diff --git a/AutoEncryptDemo.exe b/AutoEncryptDemo.exe index a955724..bac550a 100644 Binary files a/AutoEncryptDemo.exe and b/AutoEncryptDemo.exe differ diff --git a/AutoFileCryptTool.exe b/AutoFileCryptTool.exe index c8c08cf..35e0170 100644 Binary files a/AutoFileCryptTool.exe and b/AutoFileCryptTool.exe differ diff --git a/Bin/arm64/EaseFlt.sys b/Bin/arm64/EaseFlt.sys index 23b67dd..6d7d02a 100644 Binary files a/Bin/arm64/EaseFlt.sys and b/Bin/arm64/EaseFlt.sys differ diff --git a/Bin/arm64/FilterAPI.dll b/Bin/arm64/FilterAPI.dll index f4ea3d2..fe691a7 100644 Binary files a/Bin/arm64/FilterAPI.dll and b/Bin/arm64/FilterAPI.dll differ diff --git a/Bin/arm64/FilterAPI.lib b/Bin/arm64/FilterAPI.lib index e1c4187..a769ac1 100644 Binary files a/Bin/arm64/FilterAPI.lib and b/Bin/arm64/FilterAPI.lib differ diff --git a/Bin/win32/EaseFlt.sys b/Bin/win32/EaseFlt.sys index f8e709a..8e4825b 100644 Binary files a/Bin/win32/EaseFlt.sys and b/Bin/win32/EaseFlt.sys differ diff --git a/Bin/win32/FilterAPI.dll b/Bin/win32/FilterAPI.dll index 874f399..3139672 100644 Binary files a/Bin/win32/FilterAPI.dll and b/Bin/win32/FilterAPI.dll differ diff --git a/Bin/win32/FilterAPI.lib b/Bin/win32/FilterAPI.lib index e940274..5e4b922 100644 Binary files a/Bin/win32/FilterAPI.lib and b/Bin/win32/FilterAPI.lib differ diff --git a/Bin/x64/EaseFlt.sys b/Bin/x64/EaseFlt.sys index 44df7cc..f7ecbf9 100644 Binary files a/Bin/x64/EaseFlt.sys and b/Bin/x64/EaseFlt.sys differ diff --git a/Bin/x64/FilterAPI.dll b/Bin/x64/FilterAPI.dll index ab1709f..3e51cc4 100644 Binary files a/Bin/x64/FilterAPI.dll and b/Bin/x64/FilterAPI.dll differ diff --git a/Bin/x64/FilterAPI.lib b/Bin/x64/FilterAPI.lib index 311a9fc..60b4440 100644 Binary files a/Bin/x64/FilterAPI.lib and b/Bin/x64/FilterAPI.lib differ diff --git a/CommonObjects.dll b/CommonObjects.dll index ae3d999..8376558 100644 Binary files a/CommonObjects.dll and b/CommonObjects.dll differ diff --git a/Demo_Source_Code/CPlusPlusDemo/CPlusPlusDemo.cpp b/Demo_Source_Code/CPlusPlusDemo/CPlusPlusDemo.cpp new file mode 100644 index 0000000..54a01ab --- /dev/null +++ b/Demo_Source_Code/CPlusPlusDemo/CPlusPlusDemo.cpp @@ -0,0 +1,497 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +// CPlusPlusDemo.cpp : Defines the entry point for the console application. +// + +#include "stdafx.h" +#include "Tools.h" +#include "FilterAPI.h" +#include "WindowsService.h" +#include "FilterControl.h" + +#include + +#define MAX_ERROR_MESSAGE_SIZE 1024 + +#define PrintMessage wprintf //ToDebugger + +//set the include directory for this libary to folder Bin\x64 or Bin\Win32 +#pragma comment(lib, "FilterAPI.lib") + + +VOID +Usage ( + VOID + ) +/*++ + +Routine Description + + Prints usage + +Arguments + + None + +Return Value + + None + +--*/ +{ + ULONG computerId = GetComputerId(); + + wprintf(L"\nComputerId:%d\n\n\n",computerId ); + + printf( "\nUsage: EaseFltCPPDemo [command] \n" ); + printf( "\nCommands:\n" ); + printf( " i ----- Install Driver\n" ); + printf( " u ----- UnInstall Driver\n" ); + printf( " t ----- Driver UnitTest\n" ); + printf( " m ----- Start monitor filter.\n" ); + printf( " c ----- Start control filter.\n" ); + printf( " e ----- Start encryption filter driver test.\n" ); + printf( " p ----- Start process filter driver test.\n" ); + printf( " r ----- Start registry filter driver test.\n" ); + printf( "\n [FilterFolder]---- the folder mask which will be monitored.\n" ); + printf( " [IoRegistration]---- register the callback I/O requests.\n" ); + printf( " [AccessFlag]---- the I/O access control flag.\n" ); + printf( "\r\nExample: \nEaseFltCPPDemo i ----- Install Driver\r\n" ); + printf( "EaseFltCPPDemo u ----- UnInstall Driver\r\n" ); + printf( "EaseFltCPPDemo t ----- Driver UnitTest\r\n" ); + printf( "EaseFltCPPDemo p * 16128 c:\\filterTest\\* 22554420----- run process filter driver: processFilterMask controlFlag fileFilterMask accessFlag.\r\n" ); + printf( "EaseFltCPPDemo e c:\\filterTest\\* ----- encrypt filter driver with default settings.\r\n" ); + printf( "EaseFltCPPDemo m c:\\filterTest\\* ----- monitor filter driver with default settings.\r\n" ); + printf( "EaseFltCPPDemo c c:\\filterTest\\* ----- control filter driver with default settings.\r\n" ); + printf( "EaseFltCPPDemo c c:\\filterTest\\* 0 33393264 ---control filter driver, prevent files from being changed.\r\n" ); + printf( "EaseFltCPPDemo P *(processNameFilterMask) controlFlag ---process filter driver to monitor/control process activities.\r\n"); + printf( "EaseFltCPPDemo r *(processNameFilterMask) *(keyNameFilterMask) controlFlag ---registry filter driver to monitor/control registry activities.\r\n"); + +} + + +int _tmain(int argc, _TCHAR* argv[]) +{ + DWORD threadCount = 5; + DWORD connectionTimeout = 20; //SECONDS + ULONG filterType = FILE_SYSTEM_MONITOR; + BOOL ret = FALSE; + + PrintPassedMessage(L"test Install filter driver succeeded!"); + + if(argc <= 1) + { + Usage(); + return 1; + } + + TCHAR op = *argv[1]; + + EnableDebugPrivileges(); + + PrintPassedMessage(L"before Install filter driver succeeded!"); + + FilterControl* filterControl = FilterControl::GetSingleInstance(); + + // + PrintPassedMessage(L"after Install filter driver succeeded!"); + + switch(op) + { + + /*How to run as windows service, do the following steps: + 1.Create windows service: sc create filterService binpath= c:\easefilter\x64\cplusplusdemo.exe w, + replace the path with your own path,Note: binpath=(space)binarypath + 2. cplusplusdemo.exe i //install the driver manully. + 3. Sc start easefilter //start the windows service. + */ + case 'w': //start windows service for the monitor filter + { + StartWindowsService(); + break; + } + + case 'i': //install driver + { + //Install the driver only once. + //After the installation, you can use command "fltmc unload EaseFilter" to unload the driver + //or "fltmc load EaseFilter" to load the driver, or "fltmc" to check the status of the driver. + + ret = UnInstallDriver(); + Sleep(2000); + + ret = InstallDriver(); + if( !ret ) + { + PrintLastErrorMessage( L"InstallDriver failed."); + return 1; + } + + PrintPassedMessage(L"Install filter driver succeeded!"); + + break; + } + + case 'u': //uninstall driver + { + ret = UnInstallDriver(); + if( !ret ) + { + PrintLastErrorMessage( L"UnInstallDriver failed."); + break; + } + + PrintPassedMessage(L"UnInstallDriver succeeded!"); + + break; + + } + + case 'c': filterType = FILE_SYSTEM_CONTROL; //start control filter + case 'm': + { + //To monitor filter: + //you can register the file changed events to get the notification when the file was created, renamed, deleted, written and changed. + //you only can register the post I/O to get the notification after the I/O was processed by the file system. + + //To control Filter: + //You can allow or deny the file I/O by setting the access flags in the filter rule. + //You can register the pre-I/O to get the callback in user mode application before the I/O goes down to the file system, + //in your callback function you can allow or deny the I/O. + //You can register the post I/O to get the callback in user mode application after the I/O was returned from the file system, + //in your callback function you can modify the returned I/O data. + + if( !IsDriverServiceRunning()) + { + ret = InstallDriver(); + if( !ret ) + { + PrintLastErrorMessage( L"InstallDriver failed."); + return 1; + } + + PrintPassedMessage(L"Install filter driver succeeded!"); + } + + + ULONGLONG allPostIO = POST_CREATE|POST_FASTIO_READ|POST_CACHE_READ|POST_NOCACHE_READ|POST_PAGING_IO_READ; + allPostIO |= POST_FASTIO_WRITE|POST_CACHE_WRITE|POST_NOCACHE_WRITE|POST_PAGING_IO_WRITE|POST_QUERY_INFORMATION; + allPostIO |= POST_SET_INFORMATION|POST_DIRECTORY|POST_QUERY_SECURITY|POST_SET_SECURITY|POST_CLEANUP|POST_CLOSE; + + WCHAR* fileFilterMask = L"c:\\test\\*"; + ULONGLONG ioCallbackClass = allPostIO; + ULONG accessFlag = ALLOW_MAX_RIGHT_ACCESS; + + if (argc >= 3) + { + fileFilterMask = argv[2]; + } + + //To get the I/O callback registration class, you can check the IOCallbackClass for your reference. + if( argc >= 4 ) + { + ioCallbackClass = std::stoul (argv[3],nullptr,16); + } + + if( argc >= 5 ) + { + accessFlag = std::stoul (argv[4],nullptr,10); + } + + FileFilterRule fileFilterRule(fileFilterMask); + fileFilterRule.AccessFlag = accessFlag; + + //block the new file cration/rename/delete/write in the filter driver + /*fileFilterRule.AccessFlag = ALLOW_MAX_RIGHT_ACCESS & (~(ALLOW_OPEN_WITH_CREATE_OR_OVERWRITE_ACCESS|ALLOW_FILE_RENAME|ALLOW_FILE_DELETE|ALLOW_WRITE_ACCESS));*/ + + fileFilterRule.BooleanConfig = ENABLE_MONITOR_EVENT_BUFFER; + fileFilterRule.FileChangeEventFilter = FILE_WAS_CREATED|FILE_WAS_WRITTEN|FILE_WAS_RENAMED|FILE_WAS_DELETED|FILE_WAS_READ; + //fileFilterRule.MonitorFileIOEventFilter = ioCallbackClass; + + //you can filter the file I/O only opens with this option( file is going to be created.) + //fileFilterRule.FilterDisposition = FILE_CREATE | FILE_OPEN_IF | FILE_OVERWRITE | FILE_OVERWRITE_IF; + + if( filterType == FILE_SYSTEM_CONTROL) + { + //if you want to hide the files, you need to enable this flag. + //fileFilterRule.AccessFlag |= ENABLE_HIDE_FILES_IN_DIRECTORY_BROWSING; + //hide the txt files from the directory. + //fileFilterRule.AddHiddenFileFilterMask(L"*.txt"); + + //if you want to reparse the file open, you need to enable this flag. + //fileFilterRule.AccessFlag |= ENABLE_REPARSE_FILE_OPEN; + //FilterMask = c:\test\*txt + //ReparseFilterMask = d:\reparse\*doc + //If you open file c:\test\MyTest.txt, it will reparse to the file d:\reparse\MyTest.doc. + //fileFilterRule.ReparseFileFilterMask= L" d:\\reparse\*doc"; + + //get the control callback I/O request, you can block the I/O request in the pre-IO + fileFilterRule.ControlFileIOEventFilter = ioCallbackClass; + + //You can allow/block the file rename/delete in the callback handler by register PRE_RENAME_FILE|PRE_DELETE_FILE. + //ULONGLONG preIOCallbackClass = PRE_RENAME_FILE|PRE_DELETE_FILE; + //fileFilterRule.ControlFileIOEventFilter = preIOCallbackClass; + + //disable the file being renamed, deleted and written access rights. + ULONG processAccessRights = accessFlag & (~(ALLOW_FILE_RENAME|ALLOW_FILE_DELETE|ALLOW_WRITE_ACCESS)); + //set this new access rights to process cmd, cmd can't rename,delete or write to the file. + //this feature requires the process filter driver feature, it need to enable the process filter driver. + filterType |= FILE_SYSTEM_PROCESS; + fileFilterRule.AddAccessRightsToProcessName(L"cmd.exe", processAccessRights); + } + + filterControl->AddFileFilter(fileFilterRule); + + //Register the volume event notification with volume control setting. + //you can block the USB read with flag BLOCK_USB_READ or write with flag BLOCK_USB_WRITE. + //filterControl->VolumeControlSettings = BLOCK_USB_READ|BLOCK_USB_WRITE; + + //you can get the block message notification by the access flag with below setting. + //set global boolean config + ULONG globalBooleanConfig = ENABLE_SEND_DENIED_EVENT; + filterControl->globalBooleanConfig = globalBooleanConfig; + + if (!filterControl->StartFilter(filterType, threadCount, connectionTimeout, registerKey)) + { + break; + } + + if (op == 'm') + { + _tprintf(_T("Start Monitor filter, fileFilterMask=%s ioCallbackClass:0X%0X accessFlag:0X%0X \n\n Press any key to stop.\n"), fileFilterMask, ioCallbackClass, accessFlag); + } + else + { + _tprintf(_T("Start control filter, fileFilterMask=%s ioCallbackClass:0X%0X accessFlag:0X%0X \n\n Press any key to stop.\n"), fileFilterMask, ioCallbackClass, accessFlag); + } + + //prevent the current process from being terminated. + //AddProtectedProcessId(GetCurrentProcessId()); + + getchar(); + + //the process can be terminated now. + //RemoveProtectedProcessId(GetCurrentProcessId()); + + break; + + } + case 'e': //encryption filter driver test + { + + UnInstallDriver(); + Sleep(2000); + + ret = InstallDriver(); + if (!ret) + { + PrintLastErrorMessage(L"InstallDriver failed."); + break; + } + + WCHAR* fileFilterMask = L"c:\\test\\*"; + + if (argc >= 3) + { + fileFilterMask = argv[2]; + } + + //by default all users/processes will get the raw encrypted data + //it meant by default all users/processes are in blacklist + ULONG accessFlag = (ALLOW_MAX_RIGHT_ACCESS | ENABLE_FILE_ENCRYPTION_RULE) & (~ALLOW_READ_ENCRYPTED_FILES); + + //by default all users/processes will get the decrypted data + //it meant by default all users/processes are in whitelist + //ULONG accessFlag = (ALLOW_MAX_RIGHT_ACCESS | ENABLE_FILE_ENCRYPTION_RULE); + + filterType = FILE_SYSTEM_ENCRYPTION | FILE_SYSTEM_PROCESS; + + FileFilterRule fileFilterRule(fileFilterMask); + fileFilterRule.AccessFlag = accessFlag; + + //if we enable the encryption key from service, you can authorize the decryption for every file + //in the callback function OnFilterRequestEncryptKey, with this flag enabled, you don't need to set the encryption key. + //fileFilterRule.BooleanConfig |= REQUEST_ENCRYPT_KEY_IV_AND_TAGDATA_FROM_SERVICE; + + //if you have a master key, you can set it here, or if you want to get the encryption key from the callback function then don't set the key here. + //256 bit,32bytes encryption key + unsigned char key[] = { 0x60,0x3d,0xeb,0x10,0x15,0xca,0x71,0xbe,0x2b,0x73,0xae,0xf0,0x85,0x7d,0x77,0x81,0x1f,0x35,0x2c,0x07,0x3b,0x61,0x08,0xd7,0x2d,0x98,0x10,0xa3,0x09,0x14,0xdf,0xf4 }; + if (!fileFilterRule.set_EncryptionKey(key, sizeof(key))) + { + break; + } + + //set the blacklist of the process, if the default filter rule is whitelist to all users/processes. + //ULONG rawEncryptionRights = ALLOW_MAX_RIGHT_ACCESS & (~ALLOW_READ_ENCRYPTED_FILES); + //fileFilterRule.AddAccessRightsToProcessName(L"explorer.exe", rawEncryptionRights); + + //set the whitelist for the user "AzureAD\\Alice" + //fileFilterRule.AddAccessRightsToUserName(L"AzureAD\\Alice", ALLOW_MAX_RIGHT_ACCESS); + + //set the whitelist for the process "wordpad.exe" + fileFilterRule.AddAccessRightsToProcessName(L"wordpad.exe", ALLOW_MAX_RIGHT_ACCESS); + + //set the whitelist for the process "notepad.exe" + fileFilterRule.AddAccessRightsToProcessName(L"notepad.exe", ALLOW_MAX_RIGHT_ACCESS); + + filterControl->AddFileFilter(fileFilterRule); + + if (!filterControl->StartFilter(filterType, threadCount, connectionTimeout, registerKey)) + { + break; + } + + _tprintf(_T("\n\nStart Encryption for folder %ws,\r\nThe new created file will be encrypted, the encrypted file can be decrypted automatically in this folder\ + .\r\n Press any key to stop the filter driver.\n"),fileFilterMask); + + system("pause"); + getchar(); + + break; + + } + case 'p': //process filter driver test + { + + UnInstallDriver(); + Sleep(2000); + + ret = InstallDriver(); + if( !ret ) + { + PrintLastErrorMessage( L"InstallDriver failed."); + break; + } + + + WCHAR* processFilterMask = L"*"; + ULONG controlFlag = PROCESS_CREATION_NOTIFICATION|PROCESS_TERMINATION_NOTIFICATION|THREAD_CREATION_NOTIFICATION|THREAD_TERMINATION_NOTIFICATION; + + //if you want to block the application in c:\test folder to be launched, you can use below setting: + //controlFlag = DENY_NEW_PROCESS_CREATION; + //processFilterMask = L"c:\\test\\*.exe"; + + if( argc >= 3 ) + { + processFilterMask = argv[2]; + } + + if( argc >= 4 ) + { + controlFlag = std::stoul (argv[3],nullptr,10); + } + + filterType = FILE_SYSTEM_PROCESS; + + ProcessFilterRule processFilterRule(processFilterMask); + processFilterRule.ControlFlag = controlFlag; + + filterControl->AddProcessFilter(processFilterRule); + + //block the process to write,rename or delete to folder c:\test + ULONG accessFlag = ALLOW_MAX_RIGHT_ACCESS & ~(ALLOW_OPEN_WITH_CREATE_OR_OVERWRITE_ACCESS | ALLOW_WRITE_ACCESS | ALLOW_FILE_RENAME | ALLOW_FILE_DELETE); + processFilterRule.AddFileAccessRightsToProcess(L"c:\\test\\*", accessFlag); + + if (!filterControl->StartFilter(filterType, threadCount, connectionTimeout, registerKey)) + { + break; + } + + _tprintf(_T("Start Process filter, processFilterMask=%s controlFlag:0X%0X \n\n Press any key to stop.\n"), processFilterMask, controlFlag); + + getchar(); + + break; + + } + case 'r': //registry filter driver test + { + + UnInstallDriver(); + Sleep(2000); + + ret = InstallDriver(); + if( !ret ) + { + PrintLastErrorMessage( L"InstallDriver failed."); + return 1; + } + + _tprintf(_T("Start registry filter driver test. press any key to stop.\n\n")); + + filterType = FILE_SYSTEM_REGISTRY; + + WCHAR* processNameFilterMask = L"*"; + WCHAR* keyNameFilterMask = L"*"; + + if (argc >= 3) + { + processNameFilterMask = argv[2]; + } + + if (argc >= 4) + { + keyNameFilterMask = argv[3]; + } + + ULONG controlFlag = REG_MAX_ACCESS_FLAG; + if (argc >= 5) + { + controlFlag = std::stoul(argv[5], nullptr, 10); + } + + RegistryFilterRule registryFilterRule(processNameFilterMask); + + registryFilterRule.RegistryKeyNameFilterMask = keyNameFilterMask; + + //you can block the registry key being renamed/deleted/created. + //controlFlag = REG_MAX_ACCESS_FLAG & (~(REG_ALLOW_RENAME_KEY | REG_ALLOW_DELETE_KEY | REG_ALLOW_CREATE_KEY)); + + registryFilterRule.ControlFlag = controlFlag; + registryFilterRule.RegCallbackClass = Max_Reg_Callback_Class; + + filterControl->AddRegistryFilter(registryFilterRule); + + if (!filterControl->StartFilter(filterType, threadCount, connectionTimeout, registerKey)) + { + break; + } + + _tprintf(_T("Start Registry filter, processNameFilterMask=%s keyNameFilterMask=%s controlFlag:0X%0X \n\n Press any key to stop.\n") + ,processNameFilterMask, keyNameFilterMask, controlFlag); + + getchar(); + + break; + + } + default: + { + Usage(); + return 1; + } + + + } + + filterControl->StopFilter(); + delete filterControl; + + return 0; +} + diff --git a/Demo_Source_Code/CPlusPlusDemo/CPlusPlusDemo.rc b/Demo_Source_Code/CPlusPlusDemo/CPlusPlusDemo.rc new file mode 100644 index 0000000..5e6bed7 --- /dev/null +++ b/Demo_Source_Code/CPlusPlusDemo/CPlusPlusDemo.rc @@ -0,0 +1,77 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + + +///////////////////////////////////////////////////////////////////////////// +// English (Canada) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENC) +#ifdef _WIN32 +LANGUAGE LANG_NEUTRAL, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 5,2,1,1 + PRODUCTVERSION 5,2,2,1 + FILEFLAGSMASK 0x17L +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "100904b0" + BEGIN + VALUE "FileDescription", "Filter Driver SDK Demo Application" + VALUE "FileVersion", "5, 2, 2, 1" + VALUE "InternalName", "EaseFltCppDemo" + VALUE "LegalCopyright", "Copyright (C) 2022" + VALUE "OriginalFilename", "EaseFltCppDemo.exe" + VALUE "ProductName", "EaseFltCppDemo Application" + VALUE "ProductVersion", "5, 2, 2, 1" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x1009, 1200 + END +END + +#endif // English (Canada) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/Demo_Source_Code/CPlusPlusDemo/EaseFltCPPDemo.vcxproj b/Demo_Source_Code/CPlusPlusDemo/EaseFltCPPDemo.vcxproj new file mode 100644 index 0000000..b8ac2da --- /dev/null +++ b/Demo_Source_Code/CPlusPlusDemo/EaseFltCPPDemo.vcxproj @@ -0,0 +1,249 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {E9382993-43C9-4CEC-9D94-90DEF64FD214} + APIDemo + + + + + + + + + Win32Proj + 10.0 + + + + Application + Unicode + true + v142 + + + Application + Unicode + v142 + + + Application + Unicode + true + v142 + + + Application + Unicode + v142 + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.40219.1 + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + true + $(SolutionDir)release + $(Platform)\$(Configuration)\ + true + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + $(SolutionDir)$(Configuration)\ + $(Platform)\$(Configuration)\ + false + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + + + + Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + Use + Level3 + EditAndContinue + + + FilterAPI.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + ..\..\bin\win32 + true + Console + MachineX86 + + + + + + + + + X64 + + + Disabled + _WIN64;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + Use + Level3 + ProgramDatabase + + + FilterAPI.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + $(OutDir);..\..\bin\x64 + true + Console + MachineX64 + + + + + + + + + MaxSpeed + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreaded + true + Use + Level3 + ProgramDatabase + + + FilterAPI.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + $(OutDir)win32;..\..\bin\win32 + true + Console + true + true + MachineX86 + + + + + + + + + X64 + + + MaxSpeed + true + _WIN64;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreaded + true + Use + Level3 + ProgramDatabase + + + FilterAPI.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + $(OutDir)x64;..\..\bin\x64 + true + Console + true + true + MachineX64 + + + + + + + + + + + + + + Create + Create + Create + Create + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Demo_Source_Code/CPlusPlusDemo/EaseFltCPPDemo.vcxproj.filters b/Demo_Source_Code/CPlusPlusDemo/EaseFltCPPDemo.vcxproj.filters new file mode 100644 index 0000000..0b9c22d --- /dev/null +++ b/Demo_Source_Code/CPlusPlusDemo/EaseFltCPPDemo.vcxproj.filters @@ -0,0 +1,101 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Resource Files + + + + + + \ No newline at end of file diff --git a/Demo_Source_Code/CPlusPlusDemo/EaseFltCPPDemo.vcxproj.user b/Demo_Source_Code/CPlusPlusDemo/EaseFltCPPDemo.vcxproj.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/Demo_Source_Code/CPlusPlusDemo/EaseFltCPPDemo.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/Demo_Source_Code/CPlusPlusDemo/EaseFltCPPDemo.vs2019.vcxproj b/Demo_Source_Code/CPlusPlusDemo/EaseFltCPPDemo.vs2019.vcxproj new file mode 100644 index 0000000..e3fd82d --- /dev/null +++ b/Demo_Source_Code/CPlusPlusDemo/EaseFltCPPDemo.vs2019.vcxproj @@ -0,0 +1,348 @@ + + + + + Debug + ARM64 + + + Debug + Win32 + + + Debug + x64 + + + Release + ARM64 + + + Release + Win32 + + + Release + x64 + + + + {E9382993-43C9-4CEC-9D94-90DEF64FD214} + APIDemo + SAK + SAK + SAK + SAK + Win32Proj + 10.0 + EaseFltCPPDemo + + + + Application + Unicode + true + v142 + + + Application + Unicode + v142 + + + Application + Unicode + true + v142 + + + Application + Unicode + true + v142 + + + Application + Unicode + v142 + + + Application + Unicode + v142 + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.40219.1 + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + true + $(SolutionDir)release + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + true + true + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + $(SolutionDir)$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + false + false + AllRules.ruleset + + + AllRules.ruleset + AllRules.ruleset + + + + + AllRules.ruleset + + + AllRules.ruleset + AllRules.ruleset + + + + + + + EaseFltCPPDemo + + + EaseFltCPPDemo + + + EaseFltCPPDemo + + + EaseFltCPPDemo + + + EaseFltCPPDemo + + + EaseFltCPPDemo + + + + Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + Use + Level3 + EditAndContinue + + + FilterAPI.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + ..\..\bin\win32 + true + Console + MachineX86 + + + + + + + + + X64 + + + Disabled + _WIN64;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + Use + Level3 + ProgramDatabase + + + FilterAPI.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + $(SolutionDir)\$(Configuration)\$(Platform)\;$(OutDir);..\..\bin\x64 + true + Console + MachineX64 + + + + + + + + + + Disabled + _WIN64;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + Use + Level3 + ProgramDatabase + + + FilterAPI.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + $(OutDir);..\..\bin\x64 + true + Console + + + + + + + + + MaxSpeed + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreaded + true + Use + Level3 + ProgramDatabase + + + FilterAPI.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + $(OutDir)win32;..\..\bin\win32 + true + Console + true + true + MachineX86 + + + + + + + + + X64 + + + MaxSpeed + true + _WIN64;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreaded + true + Use + Level3 + ProgramDatabase + + + FilterAPI.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + $(OutDir)x64;..\..\bin\x64 + true + Console + true + true + MachineX64 + + + + + + + + + + MaxSpeed + true + _WIN64;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreaded + true + Use + Level3 + ProgramDatabase + + + FilterAPI.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + $(OutDir)x64;..\..\bin\x64 + true + Console + true + true + + + + + + + + + + + + Create + Create + Create + Create + Create + Create + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Demo_Source_Code/CPlusPlusDemo/EaseFltCPPDemo.vs2019.vcxproj.filters b/Demo_Source_Code/CPlusPlusDemo/EaseFltCPPDemo.vs2019.vcxproj.filters new file mode 100644 index 0000000..7a487f1 --- /dev/null +++ b/Demo_Source_Code/CPlusPlusDemo/EaseFltCPPDemo.vs2019.vcxproj.filters @@ -0,0 +1,92 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Resource Files + + + + + + \ No newline at end of file diff --git a/Demo_Source_Code/CPlusPlusDemo/EaseFltCPPDemo.vs2019.vcxproj.user b/Demo_Source_Code/CPlusPlusDemo/EaseFltCPPDemo.vs2019.vcxproj.user new file mode 100644 index 0000000..88a5509 --- /dev/null +++ b/Demo_Source_Code/CPlusPlusDemo/EaseFltCPPDemo.vs2019.vcxproj.user @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/Demo_Source_Code/CPlusPlusDemo/EncryptionHandler.h b/Demo_Source_Code/CPlusPlusDemo/EncryptionHandler.h new file mode 100644 index 0000000..c7c2fc8 --- /dev/null +++ b/Demo_Source_Code/CPlusPlusDemo/EncryptionHandler.h @@ -0,0 +1,117 @@ +#ifndef __ENCRYPTION_H__ +#define __ENCRYPTION_H__ + +#include "FilterAPI.h" +#include "FilterMessage.h" + +#ifndef STATUS_FILE_NOT_ENCRYPTED +#define STATUS_FILE_NOT_ENCRYPTED ((NTSTATUS)0xC0000291L) +#endif + +#ifndef STATUS_FILE_ENCRYPTED +#define STATUS_FILE_ENCRYPTED ((NTSTATUS)0xC0000293L) +#endif + +#define AES_MAX_TAG_DATA_SIZE 914 + +unsigned char testiv[] = {0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff};// Initialization vector +unsigned char testkey[] = {0x60,0x3d,0xeb,0x10,0x15,0xca,0x71,0xbe,0x2b,0x73,0xae,0xf0,0x85,0x7d,0x77,0x81,0x1f,0x35,0x2c,0x07,0x3b,0x61,0x08,0xd7,0x2d,0x98,0x10,0xa3,0x09,0x14,0xdf,0xf4};// 32bytes encrytpion key + +BOOL +EncryptionHandler( + IN PMESSAGE_SEND_DATA messageSend, + IN OUT PMESSAGE_REPLY_DATA messageReply ) +{ + BOOL retVal = FALSE; + + if ( FILTER_REQUEST_ENCRYPTION_IV_AND_KEY == messageSend->FilterCommand + || FILTER_REQUEST_ENCRYPTION_IV_AND_KEY_AND_TAGDATA == messageSend->FilterCommand ) + { + //this is encryption filter rule with boolean config "REQUEST_ENCRYPT_KEY_IV_AND_TAGDATA_FROM_SERVICE" enabled. + //the filter driver request the IV and key to open or create the encrypted file. + + //if you don't want to authorize the process to read the encrytped file,you can set the value as below: + //messageReply->ReturnStatus = STATUS_ACCESS_DENIED; + //messageReply->FilterStatus = FILTER_COMPLETE_PRE_OPERATION; + + if( FILTER_REQUEST_ENCRYPTION_IV_AND_KEY_AND_TAGDATA == messageSend->FilterCommand ) + { + //this is new created file to request the encryption key and iv, + //you can set the custom tag data to the header of the encrypted file if you set the below value. + + //if you want to block the new file creation, return STATUS_ACCESS_DENIED + //messageReply->FilterStatus = FILTER_COMPLETE_PRE_OPERATION; + //messageReply->ReturnStatus = STATUS_ACCESS_DENIED; + + //if you don't want to encrypt this new file , return STATUS_FILE_NOT_ENCRYPTED + //messageReply->ReturnStatus = STATUS_FILE_NOT_ENCRYPTED; + + //if you want to return the encryption key and iv for new created file, then return STATUS_SUCCESS + //messageReply->ReturnStatus = STATUS_SUCCESS; + + //make sure the tag data length is less than the AES_MAX_TAG_DATA_SIZE; + if( AES_MAX_TAG_DATA_SIZE > messageSend->FileNameLength ) + { + //for new created file encryption, you can append your own custom tag data to the encryption header. + //here we put the file name as the tag data for test purpose. + + messageReply->ReplyData.AESData.Data.TagDataLength = messageSend->FileNameLength; + memcpy(messageReply->ReplyData.AESData.Data.TagData,messageSend->FileName,messageSend->FileNameLength); + } + + wprintf(L"New created file :%ws is requesting encryption key, iv and tag data, return status:%0x\n",messageSend->FileName, messageReply->ReturnStatus ); + + } + else if(FILTER_REQUEST_ENCRYPTION_IV_AND_KEY == messageSend->FilterCommand) + { + //opening the existing encrypted file, request the encryption key. + //please cache the encryption key and tag data in local, since the request will be sent very often. + + //here is the custom tag data for the encrypted file which was embedded in the encryption header. + //messageSend->DataBufferLength; + //messageSend->DataBuffer; + + //if you want to block the encrypted file open, return STATUS_ACCESS_DENIED + //messageReply->FilterStatus = FILTER_COMPLETE_PRE_OPERATION; + //messageReply->ReturnStatus = STATUS_ACCESS_DENIED; + + //if you want to return the raw encrypted data, then return STATUS_FILE_ENCRYPTED, i.e., for backup software or other application requre raw encrypted data. + //messageReply->ReturnStatus = STATUS_FILE_ENCRYPTED; + + //if you want to decrypt the file, then return status success, and the encryption key and iv. + messageReply->ReturnStatus = STATUS_SUCCESS; + + } + + //Here we return the default test iv and key to the filter driver, you can replace it with your own iv and key. + messageReply->ReplyData.AESData.Data.AccessFlag = ALLOW_MAX_RIGHT_ACCESS; + + //if you want to use your own iv for the encrypted file, set the value here, + //or set the IVLength to 0, then the unique auto generated iv will be assigned to the file. + if(testiv && 16 == sizeof(testiv)) + { + messageReply->ReplyData.AESData.Data.IVLength = 16; + memcpy(messageReply->ReplyData.AESData.Data.IV,testiv,16); + } + else + { + messageReply->ReplyData.AESData.Data.IVLength = 0; + } + + //here is the encryption key for the encrypted file, you can set it with your own key. + messageReply->ReplyData.AESData.Data.EncryptionKeyLength = 32; + memcpy(messageReply->ReplyData.AESData.Data.EncryptionKey,testkey,32); + + //the total return size + messageReply->ReplyData.AESData.SizeOfData = sizeof(messageReply->ReplyData.AESData.Data) + messageReply->ReplyData.AESData.Data.TagDataLength ; + + + } + + return retVal; +} + + + + +#endif \ No newline at end of file diff --git a/Demo_Source_Code/CPlusPlusDemo/EncryptionTest.cpp b/Demo_Source_Code/CPlusPlusDemo/EncryptionTest.cpp new file mode 100644 index 0000000..285a51a --- /dev/null +++ b/Demo_Source_Code/CPlusPlusDemo/EncryptionTest.cpp @@ -0,0 +1,553 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "tools.h" +#include "FilterAPI.h" +#include "FilterControl.h" +#include "UnitTest.h" + +WCHAR* testFolder = L"c:\\filterTest"; +WCHAR* testFile = L"c:\\filterTest\\testEncryptfile1.bin"; +WCHAR* copyFile = L"c:\\filterTest\\testEncryptfile1.copy.bin"; + +//Add clear text data to the file. +unsigned char iv[] = {0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff};// Initialization vector +unsigned char clearText[] = {0x6b,0xc1,0xbe,0xe2,0x2e,0x40,0x9f,0x96,0xe9,0x3d,0x7e,0x11,0x73,0x93,0x17,0x2a};// clear text + +//256 bit test key +unsigned char key[] = {0x60,0x3d,0xeb,0x10,0x15,0xca,0x71,0xbe,0x2b,0x73,0xae,0xf0,0x85,0x7d,0x77,0x81,0x1f,0x35,0x2c,0x07,0x3b,0x61,0x08,0xd7,0x2d,0x98,0x10,0xa3,0x09,0x14,0xdf,0xf4};// 32bytes encrytpion key +unsigned char cipherText[] = {0x60,0x1e,0xc3,0x13,0x77,0x57,0x89,0xa5,0xb7,0xa7,0xf5,0x04,0xbb,0xf3,0xd2,0x28};// cipher text + + + +BOOL +CreateTestFile(BOOL bypassFilterDriver ) +{ + LARGE_INTEGER ByteOffset = {0}; + OVERLAPPED Overlapped = {0}; + DWORD dwTransferred = 0; + int nError = ERROR_SUCCESS; + BOOL ret = FALSE; + DWORD dwFlagsAndAttributes = FILE_FLAG_NO_BUFFERING; + + //Create the test folder. + ret = CreateDirectory(testFolder,NULL); + + if( ret == 0 ) + { + nError = GetLastError(); + if( nError != ERROR_ALREADY_EXISTS ) + { + PrintErrorMessage(L"Create test folder failed.", nError); + return FALSE; + } + } + + if( bypassFilterDriver ) + { + dwFlagsAndAttributes |= FILE_ATTRIBUTE_REPARSE_POINT| + FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_NO_BUFFERING|FILE_FLAG_OPEN_NO_RECALL; + } + + //Create the test file,if it exist, overwrite it. + HANDLE pFile = CreateFile(testFile,GENERIC_WRITE,NULL,NULL,CREATE_ALWAYS,dwFlagsAndAttributes,NULL); + + if( pFile == INVALID_HANDLE_VALUE ) + { + PrintErrorMessage(L"Create test file failed.", GetLastError()); + return FALSE; + } + + //since we open the file without buffering,we need to write the file with sector align length + DWORD bufferLength = 65536; + unsigned char* buffer = (unsigned char*)_aligned_malloc(bufferLength,bufferLength); + if( NULL == buffer ) + { + ret = FALSE; + PrintErrorMessage(L"Allocate memory failed with insufficient resources.",0); + goto EXIT; + } + + ZeroMemory(buffer,65536); + + RtlCopyMemory(buffer,clearText,sizeof(clearText)); + + // Write test data to the test file. + if(!WriteFile(pFile, buffer,bufferLength, &dwTransferred, NULL)) + { + nError = GetLastError(); + PrintErrorMessage(L"WriteFile failed.", nError); + ret = FALSE; + goto EXIT; + } + + SetFileSize(pFile,sizeof(clearText)); + + ret = TRUE; + +EXIT: + + CloseHandle(pFile); + + if( buffer != NULL ) + { + _aligned_free( buffer); + } + + return ret; + +} + +BOOL +VerifyRawData(WCHAR* testFile, BOOL isEncrypted) +{ + HANDLE pFile = INVALID_HANDLE_VALUE; + BOOL ret = FALSE; + + //open test file bypass the filter driver. + pFile = CreateFile( testFile, + GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_ENCRYPTED|FILE_ATTRIBUTE_REPARSE_POINT| + FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_NO_BUFFERING|FILE_FLAG_OPEN_NO_RECALL, + NULL); + + if( pFile == INVALID_HANDLE_VALUE ) + { + PrintErrorMessage(L"Open test file failed.", GetLastError()); + return FALSE; + } + + //since we open the file without buffering,we need to read the file with sector align length + DWORD bufferLength = 65536; + unsigned char* buffer = (unsigned char*)_aligned_malloc(bufferLength,bufferLength); + if( NULL == buffer ) + { + ret = FALSE; + PrintErrorMessage(L"Allocate memory failed with insufficient resources.",0); + goto EXIT; + } + + ret = ReadFile(pFile,buffer,bufferLength,&bufferLength,NULL); + if(0 == ret) + { + PrintErrorMessage(L"Read test file failed.",GetLastError()); + goto EXIT; + } + + + if( isEncrypted ) + { + UCHAR headerBuffer[1024]; + PAES_DATA pAESData = (PAES_DATA)headerBuffer; + ULONG headerSize = sizeof(headerBuffer); + + if(!GetAESHeader(testFile,&headerSize,(BYTE*)pAESData)) + { + PrintLastErrorMessage( L"Get encrypted file header failed."); + return FALSE; + } + + bufferLength = (DWORD)pAESData->FileSize; + + if( memcmp(buffer,cipherText,bufferLength) == 0) + { + ret = TRUE; + } + else + { + printf("Compare encrypted data failed.\r\nCipher data:"); + for(int i = 0; i < sizeof(cipherText); i++) + { + printf("%2x",cipherText[i]); + } + + printf("\r\nRaw data:"); + for(int i = 0; i < sizeof(cipherText); i++) + { + printf("%2x",buffer[i]); + } + + printf("\r\n"); + + ret = FALSE; + } + } + else + { + if( memcmp(buffer,clearText,bufferLength) == 0) + { + ret = TRUE; + } + else + { + printf("Compare decrypted data failed.\r\nClear data size %d: cleardata:",sizeof(clearText)); + for(int i = 0; i < sizeof(clearText); i++) + { + printf("%2x",clearText[i]); + } + + printf("\r\nRaw data size:%d: raw data:", bufferLength); + for(int i = 0; i < sizeof(clearText); i++) + { + printf("%2x",buffer[i]); + } + + printf("\r\n"); + + ret = FALSE; + } + } + +EXIT: + + if( pFile != INVALID_HANDLE_VALUE ) + { + CloseHandle(pFile); + } + + if( buffer != NULL ) + { + _aligned_free( buffer); + } + + + return ret; + +} + +BOOL +CopyEncryptedFile() +{ + HANDLE pFile = INVALID_HANDLE_VALUE; + HANDLE pFile2 = INVALID_HANDLE_VALUE; + BOOL ret = FALSE; + unsigned char* buffer = NULL; + + //Set current process to read the raw data of the encrypted file in the test folder + //set current process won't encrypt the new created file + ULONG pid = GetCurrentProcessId(); + WCHAR* filterFolder = GetFilterMask(); + ULONG accessFlag = (ALLOW_MAX_RIGHT_ACCESS|ENABLE_FILE_ENCRYPTION_RULE) + & (~ALLOW_READ_ENCRYPTED_FILES)& (~ALLOW_ENCRYPT_NEW_FILE); ; + AddProcessIdRightsToFilterRule(filterFolder,pid,accessFlag); + + + //open test encrypted file for read. + pFile = CreateFile( testFile, + GENERIC_READ,NULL,NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL); + + if( pFile == INVALID_HANDLE_VALUE ) + { + PrintErrorMessage(L"Open test file failed.", GetLastError()); + return FALSE; + } + + LARGE_INTEGER fileSize; + if( !GetFileSizeEx(pFile,&fileSize)) + { + PrintErrorMessage(L"Get test file size failed.", GetLastError()); + ret = FALSE; + goto EXIT; + } + + //Create target copy file for write. + pFile2 = CreateFile( copyFile, + GENERIC_WRITE,NULL,NULL, + CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL, + NULL); + + if( pFile2 == INVALID_HANDLE_VALUE ) + { + PrintErrorMessage(L"Create test copy file failed.", GetLastError()); + return FALSE; + } + + DWORD dwTransferred = 0; + DWORD bufferLength = 65536; + buffer = (unsigned char*)_aligned_malloc(bufferLength,bufferLength); + if( NULL == buffer ) + { + ret = FALSE; + PrintErrorMessage(L"Allocate memory failed with insufficient resources.",0); + goto EXIT; + } + + ZeroMemory(buffer,65536); + + ret = ReadFile(pFile,buffer,bufferLength,&dwTransferred,NULL); + if(0 == ret) + { + PrintErrorMessage(L"Read test file failed.",GetLastError()); + goto EXIT; + } + + // Write test data to the test file. + if(!WriteFile(pFile2, buffer, bufferLength, &dwTransferred, NULL)) + { + PrintErrorMessage(L"WriteFile failed.", GetLastError()); + ret = FALSE; + goto EXIT; + } + + //set back the correct file size + ret = SetFileSize(pFile2,fileSize.QuadPart); + if(!ret) + { + PrintLastErrorMessage( L"SetFileSize failed."); + } + + //remove the current process Id read/write encrypted file exclusion which was set in the beginning. + RemoveProcessIdRightsFromFilterRule(filterFolder,pid); + +EXIT: + + if(pFile != INVALID_HANDLE_VALUE) + { + CloseHandle(pFile); + } + + if(pFile2 != INVALID_HANDLE_VALUE) + { + CloseHandle(pFile2); + } + + if( buffer != NULL ) + { + _aligned_free( buffer); + } + + if(!VerifyRawData(copyFile,TRUE)) + { + PrintErrorMessage(L"verify copy encrypted file failed, the data is not correct.\n",0); + } + else + { + printf("Verified copy encrypted file passed.\n"); + } + + return ret; +} + +BOOL +VerifyFilterDriverDecryptData() +{ + BOOL ret = FALSE; + HANDLE pFile = INVALID_HANDLE_VALUE; + + Sleep(2000); + + pFile = CreateFile( copyFile, + GENERIC_READ,NULL,NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL); + + if( pFile == INVALID_HANDLE_VALUE ) + { + PrintErrorMessage(L"Open encrypted file failed.", GetLastError()); + return FALSE; + } + + DWORD bufferLength = 65536; + unsigned char* buffer = (unsigned char*)_aligned_malloc(bufferLength,bufferLength); + if( NULL == buffer ) + { + ret = FALSE; + PrintErrorMessage(L"Allocate memory failed with insufficient resources.",0); + goto EXIT; + } + + ZeroMemory(buffer,65536); + + ret = ReadFile(pFile,buffer,bufferLength,&bufferLength,NULL); + if(0 == ret) + { + PrintErrorMessage(L"Read test file failed.",GetLastError()); + goto EXIT; + } + + if( memcmp(buffer,clearText,bufferLength) == 0) + { + ret = TRUE; + } + else + { + printf("Verified filter driver decryption data failed.\r\nclearText data:"); + for(int i = 0; i < sizeof(clearText); i++) + { + printf("%2x",clearText[i]); + } + + printf("\r\nReturn data:"); + for(int i = 0; i < sizeof(clearText); i++) + { + printf("%2x",buffer[i]); + } + + printf("\r\n"); + + ret = FALSE; + + } + +EXIT: + + if( pFile != INVALID_HANDLE_VALUE ) + { + CloseHandle(pFile); + } + + if( buffer != NULL ) + { + _aligned_free( buffer); + } + + + return ret; + +} + +VOID +EncryptionUnitTest(FilterControl* filterControl) +{ + WCHAR* filterMask = GetFilterMask(); + + FileFilterRule fileFilter(filterMask); + //Test Remove ALLOW_OPEN_WITH_WRITE_ACCESS for current process + ULONG accessFlag = ALLOW_MAX_RIGHT_ACCESS|ENABLE_FILE_ENCRYPTION_RULE; + + fileFilter.AccessFlag = accessFlag; + + //256 bit,32bytes encrytpion key + unsigned char key[] = {0x60,0x3d,0xeb,0x10,0x15,0xca,0x71,0xbe,0x2b,0x73,0xae,0xf0,0x85,0x7d,0x77,0x81,0x1f,0x35,0x2c,0x07,0x3b,0x61,0x08,0xd7,0x2d,0x98,0x10,0xa3,0x09,0x14,0xdf,0xf4}; + + fileFilter.set_EncryptionKey(key,sizeof(key)); + + filterControl->SendFileFilterRuleToFilter(&fileFilter); + + DeleteFile(testFile); + DeleteFile(copyFile); + + //create a new test file + if(!CreateTestFile(TRUE)) + { + return; + } + else + { + PrintPassedMessage(L"Created test file passed.\n"); + } + + if(!AESEncryptFile(testFile,sizeof(key),key,sizeof(iv),iv,TRUE)) + { + PrintLastErrorMessage( L"447 AESEncryptFile failed."); + return; + } + else + { + PrintPassedMessage(L"452 Encrypted test file passed.\n"); + } + + if(!VerifyRawData(testFile,TRUE)) + { + PrintFailedMessage(L"457 Verified AESEncryptFile test failed.\n"); + return; + } + else + { + PrintPassedMessage(L"462 Verified encrypted file data passed.\n"); + } + + if(!CopyEncryptedFile()) + { + return; + } + else + { + PrintPassedMessage(L"471 Copied encrypted file passed.\n"); + } + + if(!AESDecryptFile(testFile,sizeof(key),key,sizeof(iv),iv)) + { + PrintLastErrorMessage( L"476 AESDecryptFile failed."); + return; + } + else + { + PrintPassedMessage(L"481 Decrypted file passed.\n"); + } + + if(!VerifyRawData(testFile,FALSE)) + { + PrintFailedMessage(L"486 Verified AESDecryptFile test failed.\n"); + return; + } + else + { + PrintPassedMessage(L"491 Verified decrypted file data passed.\n"); + } + + if(!VerifyFilterDriverDecryptData()) + { + PrintFailedMessage(L"496 Verified filter driver decryption test failed.\n"); + return; + } + else + { + PrintPassedMessage(L"501 Verified filter driver decryption test passed.\n"); + } + + + //create a new test file + //test the filter driver encrypt the file, the filter driver should be enabled, and didn't exclude the current process Id. + if(!CreateTestFile(FALSE)) + { + PrintFailedMessage(L"513 Created encrypted test file with filter driver failed.\n"); + return; + } + else + { + PrintPassedMessage(L"518 Created encrypted test file with filter driver passed.\n"); + } + + //decrypt the filter driver encrypted file with decryption API + if(!AESDecryptFileWithKey(testFile,sizeof(key),key)) + { + PrintLastErrorMessage( L"538 AESDecryptFile filter driver encrypted file failed."); + return; + } + + if(!VerifyRawData(testFile,FALSE)) + { + PrintFailedMessage(L"548 Verified filter driver encryption test failed.\n"); + return; + } + else + { + PrintPassedMessage(L"553 Verified filter driver encryption test passed.\n"); + } + + PrintPassedMessage(L"Encryption unit test passed.\n"); + wprintf(L"\r\n"); + +} diff --git a/Demo_Source_Code/CPlusPlusDemo/FileControlHandler.h b/Demo_Source_Code/CPlusPlusDemo/FileControlHandler.h new file mode 100644 index 0000000..1de3165 --- /dev/null +++ b/Demo_Source_Code/CPlusPlusDemo/FileControlHandler.h @@ -0,0 +1,609 @@ +#ifndef __FILECONTROL_H__ +#define __FILECONTROL_H__ + +#include "FilterAPI.h" +#include "FilterMessage.h" + +bool ichar_equals(wchar_t a, wchar_t b) +{ + return std::tolower(static_cast(a)) == + std::tolower(static_cast(b)); +} + + +bool iequals(const std::wstring& a, const std::wstring& b) +{ + return std::equal(a.begin(), a.end(), b.begin(), b.end(), ichar_equals); +} + + +BOOL +FileControlHandler( + IN PMESSAGE_SEND_DATA messageSend, + IN OUT PMESSAGE_REPLY_DATA messageReply ) +{ + BOOL retVal = TRUE; + + messageReply->ReturnStatus = STATUS_SUCCESS; + + //The filter driver will block and wait for the response. + + //you can block the PRE-IO request with below setting. + //messageReply->FilterStatus = FILTER_COMPLETE_PRE_OPERATION; + //messageReply->ReturnStatus = STATUS_ACCESS_DENIED; + + if (messageSend->MessageType == PRE_CREATE) + { + FileCreateEventArgs* fileCreateEventArgs = new FileCreateEventArgs(messageSend); + + fileCreateEventArgs->EventName = L"OnPreCreateFile"; + + //if (fileCreateEventArgs->Disposition != FILE_OPEN) + //{ + // ////It is going to create the new file here if the file doesn't exist,you can block it here. + // //messageReply->FilterStatus = FILTER_COMPLETE_PRE_OPERATION; + // //messageReply->ReturnStatus = STATUS_ACCESS_DENIED; + + // //wprintf(L"Creating file %ws was blocked in callback handler.", messageSend->FileName); + + // //return TRUE; + //} + + if (fileCreateEventArgs->isDeleteOnClose) + { + //the file will be deleted on the file close. + fileCreateEventArgs->EventName = L"OnPreCreateFile-DeleteFileOnClose"; + + //you can block the file deletion here if the file was open with delete on close, you also need to block the delete in PRE_SET_INFORMATION FileDispositionInformation class. + //messageReply->FilterStatus = FILTER_COMPLETE_PRE_OPERATION; + //messageReply->ReturnStatus = STATUS_ACCESS_DENIED; + } + + DisplayFileIOMessage(fileCreateEventArgs); + + //you can reparse the file open with below setting + //if( IsTestFile(messageSend->FileName,messageSend->FileNameLength) ) + //{ + // // + // //This is a test case for demo only + // //For reparse file/folder open test. + // // + // //the file name must be unicode string, file name length must be less than MAX_PATH. + // memcpy(messageReply->ReplyData.Data.DataBuffer,GetTestReparseFileName(),(ULONG)wcslen(GetTestReparseFileName())*sizeof(WCHAR)); + // messageReply->ReplyData.Data.DataBufferLength =(ULONG)wcslen(GetTestReparseFileName())*sizeof(WCHAR); + // + // messageReply->FilterStatus = FILTER_MESSAGE_IS_DIRTY|FILTER_COMPLETE_PRE_OPERATION|FILTER_DATA_BUFFER_IS_UPDATED; + // messageReply->ReturnStatus = STATUS_REPARSE; + //} + + //you can block the file open/create. + //messageReply->FilterStatus = FILTER_COMPLETE_PRE_OPERATION; + //messageReply->ReturnStatus = STATUS_ACCESS_DENIED; + + delete fileCreateEventArgs; + + } + else if (messageSend->MessageType == POST_CREATE ) + { + FileCreateEventArgs* fileCreateEventArgs = new FileCreateEventArgs(messageSend); + + fileCreateEventArgs->EventName = L"OnPostCreateFile"; + + if (fileCreateEventArgs->isDeleteOnClose) + { + fileCreateEventArgs->EventName = L"OnPostCreateFile-DeleteFileOnClose"; + } + + DisplayFileIOMessage(fileCreateEventArgs); + + delete fileCreateEventArgs; + + } + else if (messageSend->MessageType == PRE_CACHE_READ + || messageSend->MessageType == PRE_FASTIO_READ + || messageSend->MessageType == PRE_NOCACHE_READ + || messageSend->MessageType == PRE_PAGING_IO_READ) + { + FileReadEventArgs* fileReadEventArgs = new FileReadEventArgs(messageSend); + fileReadEventArgs->EventName = L"OnPreFileRead-" + fileReadEventArgs->readType; + + DisplayFileIOMessage(fileReadEventArgs); + + //you can block the file read request here. + //messageReply->FilterStatus = FILTER_COMPLETE_PRE_OPERATION; + //messageReply->ReturnStatus = STATUS_ACCESS_DENIED; + + delete fileReadEventArgs; + } + else if (messageSend->MessageType == POST_CACHE_READ + || messageSend->MessageType == POST_FASTIO_READ + || messageSend->MessageType == POST_NOCACHE_READ + || messageSend->MessageType == POST_PAGING_IO_READ) + { + FileReadEventArgs* fileReadEventArgs = new FileReadEventArgs(messageSend); + fileReadEventArgs->EventName = L"OnPostFileRead-" + fileReadEventArgs->readType; + + DisplayFileIOMessage(fileReadEventArgs); + + } + else if (messageSend->MessageType == PRE_CACHE_WRITE + || messageSend->MessageType == PRE_FASTIO_WRITE + || messageSend->MessageType == PRE_NOCACHE_WRITE + || messageSend->MessageType == PRE_PAGING_IO_WRITE) + { + + FileWriteEventArgs* fileWriteEventArgs = new FileWriteEventArgs(messageSend); + fileWriteEventArgs->EventName = L"OnPreFileWrite-" + fileWriteEventArgs->writeType; + + DisplayFileIOMessage(fileWriteEventArgs); + + //you can block the file write request here. + //messageReply->FilterStatus = FILTER_COMPLETE_PRE_OPERATION; + //messageReply->ReturnStatus = STATUS_ACCESS_DENIED; + + delete fileWriteEventArgs; + + } + else if (messageSend->MessageType == POST_CACHE_WRITE + || messageSend->MessageType == POST_FASTIO_WRITE + || messageSend->MessageType == POST_NOCACHE_WRITE + || messageSend->MessageType == POST_PAGING_IO_WRITE) + { + + FileWriteEventArgs* fileWriteEventArgs = new FileWriteEventArgs(messageSend); + fileWriteEventArgs->EventName = L"OnPostFileWrite-" + fileWriteEventArgs->writeType; + + DisplayFileIOMessage(fileWriteEventArgs); + + delete fileWriteEventArgs; + } + else if (messageSend->MessageType == PRE_QUERY_INFORMATION) + { + if (messageSend->InfoClass == FileBasicInformation) + { + FileSizeEventArgs* fileSizeArgs = new FileSizeEventArgs(messageSend); + fileSizeArgs->EventName = L"OnPreQueryFileBasicInfo"; + DisplayFileIOMessage(fileSizeArgs); + + //if( IsTestFile(messageSend->FileName,messageSend->FileNameLength) ) + //{ + // // + // //This is a test case for demo only + // //Change the information which returns from the file system. + // // + // PFILE_BASIC_INFORMATION basicInfo = (PFILE_BASIC_INFORMATION)messageSend->DataBuffer; + + // basicInfo->ChangeTime = basicInfo->LastWriteTime = GetTestFileTime(); + // basicInfo->FileAttributes |= FILE_ATTRIBUTE_READONLY; + + // memcpy(messageReply->ReplyData.Data.DataBuffer,basicInfo,sizeof(FILE_BASIC_INFORMATION)); + // messageReply->ReplyData.Data.DataBufferLength = sizeof(FILE_BASIC_INFORMATION); + + // messageReply->FilterStatus = FILTER_MESSAGE_IS_DIRTY|FILTER_COMPLETE_PRE_OPERATION|FILTER_DATA_BUFFER_IS_UPDATED; + // messageReply->ReturnStatus = STATUS_SUCCESS; + + //} + + //you can block FileBasicInformation query request here. + //messageReply->FilterStatus = FILTER_COMPLETE_PRE_OPERATION; + //messageReply->ReturnStatus = STATUS_ACCESS_DENIED; + + delete fileSizeArgs; + + } + else if (messageSend->InfoClass == FileEndOfFileInformation ) + { + FileSizeEventArgs* fileSizeArgs = new FileSizeEventArgs(messageSend); + fileSizeArgs->EventName = L"OnPreQueryFileSize"; + DisplayFileIOMessage(fileSizeArgs); + + //you can block file size query request here. + //messageReply->FilterStatus = FILTER_COMPLETE_PRE_OPERATION; + //messageReply->ReturnStatus = STATUS_ACCESS_DENIED; + + delete fileSizeArgs; + } + else if (messageSend->InfoClass == FileInternalInformation ) + { + FileIdEventArgs* fileIdArgs = new FileIdEventArgs(messageSend); + fileIdArgs->EventName = L"OnPreQueryFileId"; + DisplayFileIOMessage(fileIdArgs); + + //you can block file Id query request here. + //messageReply->FilterStatus = FILTER_COMPLETE_PRE_OPERATION; + //messageReply->ReturnStatus = STATUS_ACCESS_DENIED; + + delete fileIdArgs; + } + else if (messageSend->InfoClass == FileStandardInformation) + { + FileStandardInfoEventArgs* fileStandardInfoArgs = new FileStandardInfoEventArgs(messageSend); + fileStandardInfoArgs->EventName = L"OnPreQueryFileStandardInfo"; + DisplayFileIOMessage(fileStandardInfoArgs); + + //you can block FileStandardInformation query request here. + //messageReply->FilterStatus = FILTER_COMPLETE_PRE_OPERATION; + //messageReply->ReturnStatus = STATUS_ACCESS_DENIED; + + delete fileStandardInfoArgs; + } + else if (messageSend->InfoClass == FileNetworkOpenInformation) + { + FileNetworkInfoEventArgs* fileNetworkInfoArgs = new FileNetworkInfoEventArgs(messageSend); + fileNetworkInfoArgs->EventName = L"OnPreQueryFileNetworkInfo"; + DisplayFileIOMessage(fileNetworkInfoArgs); + + //you can block FileNetworkOpenInformation query request here. + //messageReply->FilterStatus = FILTER_COMPLETE_PRE_OPERATION; + //messageReply->ReturnStatus = STATUS_ACCESS_DENIED; + + delete fileNetworkInfoArgs; + } + else + { + //all other information class request + FileInfoArgs* fileInfoArgs = new FileInfoArgs(messageSend); + fileInfoArgs->EventName = L"OnPreQueryFileInfo"; + DisplayFileIOMessage(fileInfoArgs); + + //you can block all other information query request here. + //messageReply->FilterStatus = FILTER_COMPLETE_PRE_OPERATION; + //messageReply->ReturnStatus = STATUS_ACCESS_DENIED; + + delete fileInfoArgs; + } + } + else if (messageSend->MessageType == POST_QUERY_INFORMATION) + { + if (messageSend->InfoClass == FileBasicInformation) + { + FileBasicInfoEventArgs* fileBasicInfoArgs = new FileBasicInfoEventArgs(messageSend); + fileBasicInfoArgs->EventName = L"OnPostQueryFileBasicInfo"; + DisplayFileIOMessage(fileBasicInfoArgs); + + //if( IsTestFile(messageSend->FileName,messageSend->FileNameLength) ) + //{ + // // + // //This is a test case for demo only + // //Change the information after the request returned from the file system test. + // // + // + // PFILE_BASIC_INFORMATION basicInfo = (PFILE_BASIC_INFORMATION)messageSend->DataBuffer; + + // basicInfo->ChangeTime = basicInfo->LastWriteTime = GetTestFileTime(); + // basicInfo->FileAttributes = FILE_ATTRIBUTE_READONLY; + + // memcpy(messageReply->ReplyData.Data.DataBuffer,basicInfo,sizeof(FILE_BASIC_INFORMATION)); + // messageReply->ReplyData.Data.DataBufferLength = sizeof(FILE_BASIC_INFORMATION); + + // messageReply->FilterStatus = FILTER_MESSAGE_IS_DIRTY|FILTER_DATA_BUFFER_IS_UPDATED; + // messageReply->ReturnStatus = STATUS_SUCCESS; + + //} + + delete fileBasicInfoArgs; + + } + else if (messageSend->InfoClass == FileEndOfFileInformation) + { + FileSizeEventArgs* fileSizeArgs = new FileSizeEventArgs(messageSend); + fileSizeArgs->EventName = L"OnPostQueryFileSize"; + DisplayFileIOMessage(fileSizeArgs); + + delete fileSizeArgs; + } + else if (messageSend->InfoClass == FileInternalInformation) + { + FileIdEventArgs* fileIdArgs = new FileIdEventArgs(messageSend); + fileIdArgs->EventName = L"OnPostQueryFileId"; + DisplayFileIOMessage(fileIdArgs); + + delete fileIdArgs; + } + else if (messageSend->InfoClass == FileStandardInformation) + { + FileStandardInfoEventArgs* fileStandardInfoArgs = new FileStandardInfoEventArgs(messageSend); + fileStandardInfoArgs->EventName = L"OnPostQueryFileStandardInfo"; + DisplayFileIOMessage(fileStandardInfoArgs); + + delete fileStandardInfoArgs; + } + else if (messageSend->InfoClass == FileNetworkOpenInformation) + { + FileNetworkInfoEventArgs* fileNetworkInfoArgs = new FileNetworkInfoEventArgs(messageSend); + fileNetworkInfoArgs->EventName = L"OnPostQueryFileNetworkInfo"; + DisplayFileIOMessage(fileNetworkInfoArgs); + + delete fileNetworkInfoArgs; + } + else + { + //all other information class request + FileInfoArgs* fileInfoArgs = new FileInfoArgs(messageSend); + fileInfoArgs->EventName = L"OnPostQueryFileInfo"; + DisplayFileIOMessage(fileInfoArgs); + + delete fileInfoArgs; + } + } + else if (messageSend->MessageType == PRE_SET_INFORMATION) + { + if (messageSend->InfoClass == FileBasicInformation ) + { + FileBasicInfoEventArgs* fileBasicInfoArgs = new FileBasicInfoEventArgs(messageSend); + fileBasicInfoArgs->EventName = L"OnPreSetFileBasicInfo"; + DisplayFileIOMessage(fileBasicInfoArgs); + + //if( IsTestFile(messageSend->FileName,messageSend->FileNameLength) ) + //{ + // // + // //This is a test case for demo only + // //Change the information before write down to the file system test. + // // + // PFILE_BASIC_INFORMATION basicInfo = (PFILE_BASIC_INFORMATION)messageSend->DataBuffer; + // basicInfo->ChangeTime = basicInfo->LastWriteTime = GetTestFileTime(); + // basicInfo->FileAttributes = FILE_ATTRIBUTE_READONLY; + + // memcpy(messageReply->ReplyData.Data.DataBuffer,basicInfo,sizeof(FILE_BASIC_INFORMATION)); + // messageReply->ReplyData.Data.DataBufferLength = sizeof(FILE_BASIC_INFORMATION); + + // messageReply->FilterStatus = FILTER_MESSAGE_IS_DIRTY|FILTER_DATA_BUFFER_IS_UPDATED; + // messageReply->ReturnStatus = STATUS_SUCCESS; + + //} + + //you can block set FileBasicInformation request here. + //messageReply->FilterStatus = FILTER_COMPLETE_PRE_OPERATION; + //messageReply->ReturnStatus = STATUS_ACCESS_DENIED; + + delete fileBasicInfoArgs; + + } + else if (messageSend->InfoClass == FileEndOfFileInformation) + { + FileInfoArgs* fileInfoArgs = new FileInfoArgs(messageSend); + fileInfoArgs->EventName = L"OnPreSetFileSize"; + DisplayFileIOMessage(fileInfoArgs); + + //you can block set file size request here. + //messageReply->FilterStatus = FILTER_COMPLETE_PRE_OPERATION; + //messageReply->ReturnStatus = STATUS_ACCESS_DENIED; + + delete fileInfoArgs; + + } + else if (messageSend->InfoClass == FileStandardInformation ) + { + FileStandardInfoEventArgs* fileStandardInfoArgs = new FileStandardInfoEventArgs(messageSend); + fileStandardInfoArgs->EventName = L"OnPreSetFileStandardInfo"; + DisplayFileIOMessage(fileStandardInfoArgs); + + //you can block set FileStandardInformation request here. + //messageReply->FilterStatus = FILTER_COMPLETE_PRE_OPERATION; + //messageReply->ReturnStatus = STATUS_ACCESS_DENIED; + + delete fileStandardInfoArgs; + + } + else if (messageSend->InfoClass == FileNetworkOpenInformation) + { + FileNetworkInfoEventArgs* fileNetworkInfoArgs = new FileNetworkInfoEventArgs(messageSend); + fileNetworkInfoArgs->EventName = L"OnPreSetFileNetworkInfo"; + DisplayFileIOMessage(fileNetworkInfoArgs); + + //you can block set FileNetworkOpenInformation request here. + //messageReply->FilterStatus = FILTER_COMPLETE_PRE_OPERATION; + //messageReply->ReturnStatus = STATUS_ACCESS_DENIED; + + delete fileNetworkInfoArgs; + + } + else if (messageSend->InfoClass == FileRenameInformation + || messageSend->InfoClass == FileRenameInformationEx) + { + FileMoveOrRenameEventArgs* fileRenameArgs = new FileMoveOrRenameEventArgs(messageSend); + fileRenameArgs->EventName = L"OnPreMoveOrRenameFile"; + DisplayFileIOMessage(fileRenameArgs); + + //you can block file rename request here. + //messageReply->FilterStatus = FILTER_COMPLETE_PRE_OPERATION; + //messageReply->ReturnStatus = STATUS_ACCESS_DENIED; + + delete fileRenameArgs; + + } + else if (messageSend->InfoClass == FileDispositionInformation + || messageSend->InfoClass == FileDispositionInformationEx) + { + + FileDispositionEventArgs* fileDispostionArgs = new FileDispositionEventArgs(messageSend); + fileDispostionArgs->EventName = L"OnPreDeleteFile"; + DisplayFileIOMessage(fileDispostionArgs); + + //you can block the file delete request here, also check PRE_CREATE I/O if the file was opened with delete on close. + //messageReply->FilterStatus = FILTER_COMPLETE_PRE_OPERATION; + //messageReply->ReturnStatus = STATUS_ACCESS_DENIED; + + delete fileDispostionArgs; + } + else + { + //all other information class request + FileInfoArgs* fileInfoArgs = new FileInfoArgs(messageSend); + fileInfoArgs->EventName = L"OnPreSetFileInfo"; + DisplayFileIOMessage(fileInfoArgs); + + //you can block all other set information request here. + //messageReply->FilterStatus = FILTER_COMPLETE_PRE_OPERATION; + //messageReply->ReturnStatus = STATUS_ACCESS_DENIED; + + delete fileInfoArgs; + } + } + else if (messageSend->MessageType == POST_SET_INFORMATION) + { + if (messageSend->InfoClass == FileEndOfFileInformation) + { + FileSizeEventArgs* fileSizeArgs = new FileSizeEventArgs(messageSend); + fileSizeArgs->EventName = L"OnPostSetFileSize"; + DisplayFileIOMessage(fileSizeArgs); + + delete fileSizeArgs; + } + else if (messageSend->InfoClass == FileBasicInformation) + { + FileBasicInfoEventArgs* fileBasicInfoArgs = new FileBasicInfoEventArgs(messageSend); + fileBasicInfoArgs->EventName = L"OnPostSetFileBasicInfo"; + DisplayFileIOMessage(fileBasicInfoArgs); + + delete fileBasicInfoArgs; + } + else if (messageSend->InfoClass == FileStandardInformation) + { + FileStandardInfoEventArgs* fileStandardInfoArgs = new FileStandardInfoEventArgs(messageSend); + fileStandardInfoArgs->EventName = L"OnPostSetFileStandardInfo"; + DisplayFileIOMessage(fileStandardInfoArgs); + + delete fileStandardInfoArgs; + } + else if (messageSend->InfoClass == FileNetworkOpenInformation) + { + FileNetworkInfoEventArgs* fileNetworkInfoArgs = new FileNetworkInfoEventArgs(messageSend); + fileNetworkInfoArgs->EventName = L"OnPostSetFileNetworkInfo"; + DisplayFileIOMessage(fileNetworkInfoArgs); + + delete fileNetworkInfoArgs; + + } + else if (messageSend->InfoClass == FileRenameInformation + || messageSend->InfoClass == FileRenameInformationEx ) + { + FileMoveOrRenameEventArgs* fileRenameArgs = new FileMoveOrRenameEventArgs(messageSend); + fileRenameArgs->EventName = L"OnPostMoveOrRenameFile"; + DisplayFileIOMessage(fileRenameArgs); + + delete fileRenameArgs; + } + else if (messageSend->InfoClass == FileDispositionInformation + || messageSend->InfoClass == FileDispositionInformationEx) + { + FileDispositionEventArgs* fileDispostionArgs = new FileDispositionEventArgs(messageSend); + fileDispostionArgs->EventName = L"OnPostDeleteFile"; + DisplayFileIOMessage(fileDispostionArgs); + + delete fileDispostionArgs; + } + else + { + //all other information class request. + FileInfoArgs* fileInfoArgs = new FileInfoArgs(messageSend); + fileInfoArgs->EventName = L"OnPostSetFileInfo"; + DisplayFileIOMessage(fileInfoArgs); + + delete fileInfoArgs; + } + } + else if (messageSend->MessageType == PRE_QUERY_SECURITY) + { + FileSecurityEventArgs* fileSecurityArgs = new FileSecurityEventArgs(messageSend); + fileSecurityArgs->EventName = L"OnPreQueryFileSecurity"; + DisplayFileIOMessage(fileSecurityArgs); + + //you can block security query request here. + //messageReply->FilterStatus = FILTER_COMPLETE_PRE_OPERATION; + //messageReply->ReturnStatus = STATUS_ACCESS_DENIED; + + delete fileSecurityArgs; + + } + else if (messageSend->MessageType == POST_QUERY_SECURITY) + { + FileSecurityEventArgs* fileSecurityArgs = new FileSecurityEventArgs(messageSend); + fileSecurityArgs->EventName = L"OnPostQueryFileSecurity"; + DisplayFileIOMessage(fileSecurityArgs); + + delete fileSecurityArgs; + } + else if (messageSend->MessageType == PRE_SET_SECURITY) + { + FileSecurityEventArgs* fileSecurityArgs = new FileSecurityEventArgs(messageSend); + fileSecurityArgs->EventName = L"OnPreSetFileSecurity"; + DisplayFileIOMessage(fileSecurityArgs); + + //you can block set security request here. + //messageReply->FilterStatus = FILTER_COMPLETE_PRE_OPERATION; + //messageReply->ReturnStatus = STATUS_ACCESS_DENIED; + + delete fileSecurityArgs; + } + else if (messageSend->MessageType == POST_SET_SECURITY) + { + FileSecurityEventArgs* fileSecurityArgs = new FileSecurityEventArgs(messageSend); + fileSecurityArgs->EventName = L"OnPostSetFileSecurity"; + DisplayFileIOMessage(fileSecurityArgs); + + delete fileSecurityArgs; + } + else if (messageSend->MessageType == PRE_DIRECTORY) + { + FileQueryDirectoryEventArgs* directoryArgs = new FileQueryDirectoryEventArgs(messageSend); + directoryArgs->EventName = L"OnPreQueryDirectoryFile"; + DisplayFileIOMessage(directoryArgs); + + //you can block browsing directory request here. + //messageReply->FilterStatus = FILTER_COMPLETE_PRE_OPERATION; + //messageReply->ReturnStatus = STATUS_ACCESS_DENIED; + + delete directoryArgs; + } + else if (messageSend->MessageType == POST_DIRECTORY) + { + FileQueryDirectoryEventArgs* directoryArgs = new FileQueryDirectoryEventArgs(messageSend); + directoryArgs->EventName = L"OnPostQueryDirectoryFile"; + DisplayFileIOMessage(directoryArgs); + + delete directoryArgs; + } + else if (messageSend->MessageType == PRE_CLEANUP) + { + FileIOEventArgs* fileIOArgs = new FileIOEventArgs(messageSend); + fileIOArgs->EventName = L"OnPreFileHandleClose"; + fileIOArgs->Description = L"Before opened file handle is closed."; + DisplayFileIOMessage(fileIOArgs); + + delete fileIOArgs; + } + else if (messageSend->MessageType == POST_CLEANUP) + { + FileIOEventArgs* fileIOArgs = new FileIOEventArgs(messageSend); + fileIOArgs->EventName = L"OnPostFileHandleClose"; + fileIOArgs->Description = L"The opened file handle was closed."; + DisplayFileIOMessage(fileIOArgs); + + delete fileIOArgs; + } + else if (messageSend->MessageType == PRE_CLOSE) + { + FileIOEventArgs* fileIOArgs = new FileIOEventArgs(messageSend); + fileIOArgs->EventName = L"OnPreFileClose"; + fileIOArgs->Description = L"Before all system references to fileObject were closed."; + DisplayFileIOMessage(fileIOArgs); + + delete fileIOArgs; + } + else if (messageSend->MessageType == POST_CLOSE) + { + FileIOEventArgs* fileIOArgs = new FileIOEventArgs(messageSend); + fileIOArgs->EventName = L"OnPostFileClose"; + fileIOArgs->Description = L"All system references to fileObject were closed."; + DisplayFileIOMessage(fileIOArgs); + + delete fileIOArgs; + + } + + return retVal; +} + + +#endif \ No newline at end of file diff --git a/Demo_Source_Code/CPlusPlusDemo/FileMonitorHandler.h b/Demo_Source_Code/CPlusPlusDemo/FileMonitorHandler.h new file mode 100644 index 0000000..6c62660 --- /dev/null +++ b/Demo_Source_Code/CPlusPlusDemo/FileMonitorHandler.h @@ -0,0 +1,231 @@ +#ifndef __FILEMONITOR_H__ +#define __FILEMONITOR_H__ + +#include "FilterAPI.h" +#include "FilterMessage.h" + +VOID +SendFileFilterNotification(PMESSAGE_SEND_DATA messageSend) +{ + if (messageSend->FilterCommand == FILTER_SEND_ATTACHED_VOLUME_INFO) + { + VolumeInfoEventArgs* volumeArgs = new VolumeInfoEventArgs(messageSend); + volumeArgs->EventName = L"VolumeAttached"; + DisplayFileIOMessage(volumeArgs); + } + else if (messageSend->FilterCommand == FILTER_SEND_DETACHED_VOLUME_INFO) + { + VolumeInfoEventArgs* volumeArgs = new VolumeInfoEventArgs(messageSend); + volumeArgs->EventName = L"VolumeDetached"; + DisplayFileIOMessage(volumeArgs); + } + else if (messageSend->FilterCommand == FILTER_SEND_DENIED_VOLUME_DISMOUNT_EVENT) + { + VolumeInfoEventArgs* volumeArgs = new VolumeInfoEventArgs(messageSend); + volumeArgs->EventName = L"VolumeDismountWasBlocked"; + DisplayFileIOMessage(volumeArgs); + } + else if (messageSend->FilterCommand == FILTER_SEND_DENIED_FILE_IO_EVENT) + { + DeniedFileIOEventArgs* deniedIOEventArgs = new DeniedFileIOEventArgs(messageSend); + DisplayFileIOMessage(deniedIOEventArgs); + } + else if (messageSend->FilterCommand == FILTER_SEND_DENIED_USB_READ_EVENT) + { + DeniedUSBReadEventArgs* deniedIOEventArgs = new DeniedUSBReadEventArgs(messageSend); + DisplayFileIOMessage(deniedIOEventArgs); + } + else if (messageSend->FilterCommand == FILTER_SEND_DENIED_USB_WRITE_EVENT) + { + DeniedUSBWriteEventArgs* deniedIOEventArgs = new DeniedUSBWriteEventArgs(messageSend); + DisplayFileIOMessage(deniedIOEventArgs); + } + else if (messageSend->FilterCommand == FILTER_SEND_DENIED_PROCESS_TERMINATED_EVENT) + { + DeniedProcessTerminatedEventArgs* deniedProcessEventArgs = new DeniedProcessTerminatedEventArgs(messageSend); + DisplayFileIOMessage(deniedProcessEventArgs); + } + else if (messageSend->FilterCommand == FILTER_SEND_FILE_CHANGED_EVENT) + { + FileChangedEventArgs* fileChangeEventArgs = new FileChangedEventArgs(messageSend); + DisplayFileIOMessage(fileChangeEventArgs); + } + else if (messageSend->MessageType == POST_CREATE) + { + FileCreateEventArgs* fileCreateEventArgs = new FileCreateEventArgs(messageSend); + if (fileCreateEventArgs->isNewFileCreated ) + { + fileCreateEventArgs->EventName = L"OnNewFileCreated"; + } + else + { + fileCreateEventArgs->EventName = L"OnFileOpen"; + } + + if (fileCreateEventArgs->isDeleteOnClose) + { + fileCreateEventArgs->EventName = L"OnOpenFileWithDeleteOnClose"; + } + + DisplayFileIOMessage(fileCreateEventArgs); + + } + else if (messageSend->MessageType == POST_CACHE_READ + || messageSend->MessageType == POST_FASTIO_READ + || messageSend->MessageType == POST_NOCACHE_READ + || messageSend->MessageType == POST_PAGING_IO_READ) + { + FileReadEventArgs* fileReadEventArgs = new FileReadEventArgs(messageSend); + fileReadEventArgs->EventName = L"OnFileRead-" + fileReadEventArgs->readType; + DisplayFileIOMessage(fileReadEventArgs); + } + else if (messageSend->MessageType == POST_CACHE_WRITE + || messageSend->MessageType == POST_FASTIO_WRITE + || messageSend->MessageType == POST_NOCACHE_WRITE + || messageSend->MessageType == POST_PAGING_IO_WRITE) + { + FileWriteEventArgs* fileWriteEventArgs = new FileWriteEventArgs(messageSend); + fileWriteEventArgs->EventName = L"OnFileWrite-" + fileWriteEventArgs->writeType; + DisplayFileIOMessage(fileWriteEventArgs); + } + else if (messageSend->MessageType == POST_QUERY_INFORMATION) + { + if (messageSend->InfoClass == FileEndOfFileInformation) + { + FileSizeEventArgs* fileSizeArgs = new FileSizeEventArgs(messageSend); + fileSizeArgs->EventName = L"OnQueryFileSize"; + DisplayFileIOMessage(fileSizeArgs); + } + else if (messageSend->InfoClass == FileInternalInformation) + { + FileIdEventArgs* fileIdArgs = new FileIdEventArgs(messageSend); + fileIdArgs->EventName = L"OnQueryFileId"; + DisplayFileIOMessage(fileIdArgs); + + } + else if (messageSend->InfoClass == FileBasicInformation) + { + FileBasicInfoEventArgs* fileBasicInfoArgs = new FileBasicInfoEventArgs(messageSend); + fileBasicInfoArgs->EventName = L"OnQueryFileBasicInfo"; + DisplayFileIOMessage(fileBasicInfoArgs); + } + else if (messageSend->InfoClass == FileStandardInformation) + { + FileStandardInfoEventArgs* fileStandardInfoArgs = new FileStandardInfoEventArgs(messageSend); + fileStandardInfoArgs->EventName = L"OnQueryFileStandardInfo"; + DisplayFileIOMessage(fileStandardInfoArgs); + } + else if (messageSend->InfoClass == FileNetworkOpenInformation) + { + FileNetworkInfoEventArgs* fileNetworkInfoArgs = new FileNetworkInfoEventArgs(messageSend); + fileNetworkInfoArgs->EventName = L"OnQueryFileNetworkInfo"; + DisplayFileIOMessage(fileNetworkInfoArgs); + } + else + { + FileInfoArgs* fileInfoArgs = new FileInfoArgs(messageSend); + fileInfoArgs->EventName = L"OnQueryFileInfo"; + DisplayFileIOMessage(fileInfoArgs); + } + } + else if (messageSend->MessageType == POST_SET_INFORMATION) + { + if (messageSend->InfoClass == FileEndOfFileInformation) + { + FileSizeEventArgs* fileSizeArgs = new FileSizeEventArgs(messageSend); + fileSizeArgs->EventName = L"OnSetFileSize"; + DisplayFileIOMessage(fileSizeArgs); + } + else if (messageSend->InfoClass == FileBasicInformation) + { + FileBasicInfoEventArgs* fileBasicInfoArgs = new FileBasicInfoEventArgs(messageSend); + fileBasicInfoArgs->EventName = L"OnSetFileBasicInfo"; + DisplayFileIOMessage(fileBasicInfoArgs); + + } + else if (messageSend->InfoClass == FileStandardInformation) + { + FileStandardInfoEventArgs* fileStandardInfoArgs = new FileStandardInfoEventArgs(messageSend); + fileStandardInfoArgs->EventName = L"OnSetFileStandardInfo"; + DisplayFileIOMessage(fileStandardInfoArgs); + + } + else if (messageSend->InfoClass == FileNetworkOpenInformation) + { + FileNetworkInfoEventArgs* fileNetworkInfoArgs = new FileNetworkInfoEventArgs(messageSend); + fileNetworkInfoArgs->EventName = L"OnSetFileNetworkInfo"; + DisplayFileIOMessage(fileNetworkInfoArgs); + } + else if (messageSend->InfoClass == FileRenameInformation + || messageSend->InfoClass == FileRenameInformationEx) + { + FileMoveOrRenameEventArgs* fileRenameArgs = new FileMoveOrRenameEventArgs(messageSend); + fileRenameArgs->EventName = L"OnMoveOrRenameFile"; + DisplayFileIOMessage(fileRenameArgs); + } + else if (messageSend->InfoClass == FileDispositionInformation + || messageSend->InfoClass == FileDispositionInformationEx) + { + FileIOEventArgs* fileIOArgs = new FileIOEventArgs(messageSend); + fileIOArgs->EventName = L"OnDeleteFile"; + fileIOArgs->Description = L"The file was deleted."; + DisplayFileIOMessage(fileIOArgs); + + } + else + { + FileInfoArgs* fileInfoArgs = new FileInfoArgs(messageSend); + fileInfoArgs->EventName = L"OnSetFileInfo"; + DisplayFileIOMessage(fileInfoArgs); + } + + } + else if (messageSend->MessageType == POST_QUERY_SECURITY) + { + FileSecurityEventArgs* fileSecurityArgs = new FileSecurityEventArgs(messageSend); + fileSecurityArgs->EventName = L"OnQueryFileSecurity"; + DisplayFileIOMessage(fileSecurityArgs); + } + else if (messageSend->MessageType == POST_SET_SECURITY) + { + FileSecurityEventArgs* fileSecurityArgs = new FileSecurityEventArgs(messageSend); + fileSecurityArgs->EventName = L"OnSetFileSecurity"; + DisplayFileIOMessage(fileSecurityArgs); + + } + else if (messageSend->MessageType == POST_DIRECTORY) + { + FileQueryDirectoryEventArgs* directoryArgs = new FileQueryDirectoryEventArgs(messageSend); + directoryArgs->EventName = L"OnQueryDirectoryFile"; + DisplayFileIOMessage(directoryArgs); + } + else if (messageSend->MessageType == POST_CLEANUP) + { + FileIOEventArgs* fileIOArgs = new FileIOEventArgs(messageSend); + fileIOArgs->EventName = L"OnFileHandleClose"; + fileIOArgs->Description = L"The opened file handle was closed."; + DisplayFileIOMessage(fileIOArgs); + + } + else if (messageSend->MessageType == (ULONG)POST_CLOSE) + { + FileIOEventArgs* fileIOArgs = new FileIOEventArgs(messageSend); + fileIOArgs->EventName = L"OnFileClose"; + fileIOArgs->Description = L"All system references to the fileObject were closed."; + DisplayFileIOMessage(fileIOArgs); + + } + else + { + FileIOEventArgs* fileIOArgs = new FileIOEventArgs(messageSend); + fileIOArgs->EventName = L"UNKNOWN" ; + fileIOArgs->Description = L"MessageType:" + std::to_wstring(messageSend->MessageType) + L" can't be handled."; + DisplayFileIOMessage(fileIOArgs); + + } +} + + + + +#endif \ No newline at end of file diff --git a/Demo_Source_Code/CPlusPlusDemo/FilterAPI.h b/Demo_Source_Code/CPlusPlusDemo/FilterAPI.h new file mode 100644 index 0000000..edc169b --- /dev/null +++ b/Demo_Source_Code/CPlusPlusDemo/FilterAPI.h @@ -0,0 +1,2122 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2014 EaseFilter +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef __SHARE_TYPE_H__ +#define __SHARE_TYPE_H__ + +//Purchase a license key with the link: http://www.EaseFilter.com/Order.htm +//Email us to request a trial key: info@EaseFilter.com //free email is not accepted. +#define registerKey "**************************************" + +#define MESSAGE_SEND_VERIFICATION_NUMBER 0xFF000001 +#define INET_ADDR_STR_LEN 22 +#define MAX_FILE_NAME_LENGTH 1024 +#define MAX_SID_LENGTH 256 +#define MAX_EXCLUDED_PROCESS_ID 200 +#define MAX_INCLUDED_PROCESS_ID 200 +#define MAX_PROTECTED_PROCESS_ID 200 +#define MAX_BLOCK_SAVEAS_PROCESS_ID 200 +#define MAX_PATH 260 +#define MAX_ERROR_MESSAGE_SIZE 1024 +#define MAX_BUFFER_SIZE 16384 +#define BLOCK_SIZE 65536 + +#define AES_VERIFICATION_KEY 0xccb76e80 + +typedef enum _FilterType +{ + /// + /// File system control filter driver + /// + FILE_SYSTEM_CONTROL = 0x01, + /// + /// File system encryption filter driver + /// + FILE_SYSTEM_ENCRYPTION = 0x02, + /// + /// File system monitor filter driver + /// + FILE_SYSTEM_MONITOR = 0x04, + /// + /// File system registry filter driver + /// + FILE_SYSTEM_REGISTRY = 0x08, + /// + /// File system process filter driver + /// + FILE_SYSTEM_PROCESS = 0x10, + /// + /// File system hierarchical storage management filter driver + /// + FILE_SYSTEM_HSM = 0x40, + /// + /// File system cloud storage filter driver + /// + FILE_SYSTEM_CLOUD = 0x80, + +} FilterType; + + +//the structure of control meta data of the encrypted file. +#pragma pack (push,1) + +typedef struct _AES_DATA +{ + ULONG VerificationKey; + ULONG AESFlags; + ULONG Version; + UCHAR IV[16]; + ULONG EncryptionKeyLength; + UCHAR EncryptionKey[32]; + LONGLONG FileSize; + ULONG CryptoType; + ULONG PaddingSize; + //the size of this data structure + ULONG AESDataSize; + //the actual physical file size in disk including the padding and the header. + LONGLONG ShadowFileSize; + ULONG AccessFlags; + ULONG Reserve1; + ULONG Reserve2; + ULONG TagDataLength; + WCHAR TagData[1]; + +} AES_DATA, *PAES_DATA; + +//the custom data structure for tagData inside of PAES_DATA +typedef struct _AES_TAG_CONTROL_DATA +{ + ULONG VerificationKey; + ULONG AESFlags; + LONGLONG CreationTime; + LONGLONG ExpireTime; + ULONG AccessFlags; + ULONG LengthOfIncludeProcessNames; + ULONG OffsetOfIncludeProcessNames; + ULONG LengthOfExcludeProcessNames; + ULONG OffsetOfExcludeProcessNames; + ULONG LengthOfIncludeUserNames; + ULONG OffsetOfIncludeUserNames; + ULONG LengthOfExcludeUserNames; + ULONG OffsetOfExcludeUserNames; + ULONG LengthOfAccountName; + ULONG OffsetOfAccountName; + ULONG LengthOfComputerId; + ULONG OffsetOfComputerId; + ULONG LengthOfUserPassword; + ULONG OffsetOfUserPassword; + + //the data store here. + //IncludeProcessNames; + //ExcludeProcessNames; + //IncludeUserNames; + //ExcludeUserNames; + //AccountNames; + //ComputerId; + //UserPassword; + +} AES_TAG_CONTROL_DATA, *PAES_TAG_CONTROL_DATA; +#pragma pack(pop) + + +#define MAX_REQUEST_TYPE 32 + +//the commands were sent to the user mode application by filter driver. +typedef enum _FilterCommand +{ + /// + /// request the read data back with block data or whole cache file name. + /// + MESSAGE_TYPE_RESTORE_BLOCK_OR_FILE = 0x00000001, + /// + /// request to download the data to the original folder. + /// + MESSAGE_TYPE_RESTORE_FILE_TO_ORIGINAL_FOLDER = 0x00000002, + /// + /// request the directory file list. + /// + MESSAGE_TYPE_GET_FILE_LIST = 0x00000004, + /// + /// request to download whole file to the cache folder. + /// + MESSAGE_TYPE_RESTORE_FILE_TO_CACHE = 0x00000008, + /// + /// send the notification event of the file changed. + /// + MESSAGE_TYPE_SEND_EVENT_NOTIFICATION = 0x00000010, + /// + /// send the notification event of the file was deleted. + /// + MESSAGE_TYPE_DELETE_FILE = 0x00000020, + /// + /// send the notification event of the file was renamed. + /// + MESSAGE_TYPE_RENAME_FILE = 0x00000040, + /// + /// send the file name of the message was stored. + /// + MESSAGE_TYPE_SEND_MESSAGE_FILENAME = 0x00000080, + /// + /// send the notification event of the file was changed. + /// + FILTER_SEND_FILE_CHANGED_EVENT = 0x00010001, + /// + /// request the file open permission. + /// + FILTER_REQUEST_USER_PERMIT = 0x00010002, + /// + /// request the encryption key for the file open or creation. + /// + FILTER_REQUEST_ENCRYPTION_KEY = 0x00010003, + /// + /// request the encryption iv and key for the encrypted file open or to encrypt the file + /// + FILTER_REQUEST_ENCRYPTION_IV_AND_KEY = 0x00010004, + /// + /// request the encryption iv, key and access flags for the encrypted file open or to encrypt the file + /// + FILTER_REQUEST_ENCRYPTION_IV_AND_KEY_AND_ACCESSFLAG = 0x00010005, + /// + /// request the encryption iv, key and access flags and tag data for file encryption + /// + FILTER_REQUEST_ENCRYPTION_IV_AND_KEY_AND_TAGDATA = 0x00010006, + /// + /// send the registry access notification class information + /// + FILTER_SEND_REG_CALLBACK_INFO = 0x00010007, + /// + /// send the new process creation information + /// + FILTER_SEND_PROCESS_CREATION_INFO = 0x00010008, + /// + /// send the process termination information + /// + FILTER_SEND_PROCESS_TERMINATION_INFO = 0x00010009, + /// + /// send the new thread creation information + /// + FILTER_SEND_THREAD_CREATION_INFO = 0x0001000a, + /// + /// send the thread termination information + /// + FILTER_SEND_THREAD_TERMINATION_INFO = 0x0001000b, + /// + /// send the process handle operations information + /// + FILTER_SEND_PROCESS_HANDLE_INFO = 0x0001000c, + /// + /// send the thread handle operations information + /// + FILTER_SEND_THREAD_HANDLE_INFO = 0x0001000d, + /// + /// send the volume information when it was attached + /// + FILTER_SEND_ATTACHED_VOLUME_INFO = 0x0001000e, + /// + /// send the volume information when it was detached + /// + FILTER_SEND_DETACHED_VOLUME_INFO = 0x0001000f, + /// + /// send the event when the file IO was blocked by the config setting. + // if the flag ENABLE_SEND_DENIED_EVENT was enabled in global boolean setting. + /// + FILTER_SEND_DENIED_FILE_IO_EVENT = 0x00010010, + /// + /// send the event when the volume dismount was blocked by the config setting. + // if the flag ENABLE_SEND_DENIED_EVENT was enabled in global boolean setting. + /// + FILTER_SEND_DENIED_VOLUME_DISMOUNT_EVENT = 0x00010011, + /// + /// send the event when the process creation was blocked by the config setting. + // if the flag ENABLE_SEND_DENIED_EVENT was enabled in global boolean setting. + /// + FILTER_SEND_DENIED_PROCESS_CREATION_EVENT = 0x00010012, + /// + /// send the event when the registry access was blocked by the config setting. + // if the flag ENABLE_SEND_DENIED_EVENT was enabled in global boolean setting. + /// + FILTER_SEND_DENIED_REGISTRY_ACCESS_EVENT = 0x00010013, + /// + /// send the event when the protected process was terminiated ungratefully. + // if the flag ENABLE_SEND_DENIED_EVENT was enabled in global boolean setting. + /// + FILTER_SEND_DENIED_PROCESS_TERMINATED_EVENT = 0x00010014, + /// + /// send the event when the read from USB was blocked if the flag BLOCK_USB_READ was enabled in volume control flag. + // if the flag ENABLE_SEND_DENIED_EVENT was enabled in global boolean setting. + /// + FILTER_SEND_DENIED_USB_READ_EVENT = 0x00010015, + /// + /// send the event when the write to USB was blocked if the flag BLOCK_USB_WRITE was enabled in volume control flag. + // if the flag ENABLE_SEND_DENIED_EVENT was enabled in global boolean setting. + /// + FILTER_SEND_DENIED_USB_WRITE_EVENT = 0x00010016, + /// + /// send process information before the process is going to be terminated. + /// + FILTER_SEND_PRE_TERMINATE_PROCESS_INFO = 0x00010017, + +}FilterCommand; + +//the IO name of the IO operation. +typedef enum _IOName +{ + /// + /// Fires this event before the file create IO was going down to the file system. + /// + IOPreFileCreate = 0x00020001, + /// + /// Fires this event after the file create IO was returned from the file system. + /// + IOPostFileCreate, + /// + /// Fires this event before the file read IO was going down to the file system. + /// + IOPreFileRead, + /// + /// Fires this event after the file read IO was returned from the file system. + /// + IOPostFileRead, + /// + /// Fires this event before the file write IO was going down to the file system. + /// + IOPreFileWrite, + /// + /// Fires this event after the file write IO was returned from the file system. + /// + IOPostFileWrite, + /// + /// Fires this event before the query file size IO was going down to the file system. + /// + IOPreQueryFileSize, + /// + /// Fires this event after the query file size IO was returned from the file system. + /// + IOPostQueryFileSize, + /// + /// Fires this event before the query file basic info IO was going down to the file system. + /// + IOPreQueryFileBasicInfo, + /// + /// Fires this event after the query file basic info IO was returned from the file system. + /// + IOPostQueryFileBasicInfo, + /// + /// Fires this event before the query file standard info IO was going to the file system. + /// + IOPreQueryFileStandardInfo, + /// + /// Fires this event after the query file standard info IO was returned from the file system. + /// + IOPostQueryFileStandardInfo, + /// + /// Fires this event before the query file network info IO was going down to the file system. + /// + IOPreQueryFileNetworkInfo, + /// + /// Fires this event after the query file network info IO was returned from the file system. + /// + IOPostQueryFileNetworkInfo, + /// + /// Fires this event before the query file Id IO was going down to the file system. + /// + IOPreQueryFileId, + /// + /// Fires this event after the query file Id IO was returned from the file system. + /// + IOPostQueryFileId, + /// + /// Fires this event before the query file info IO was going down to the file system + /// if the query file information class is not 'QueryFileSize','QueryFileBasicInfo' + /// ,'QueryFileStandardInfo','QueryFileNetworkInfo' or 'QueryFileId'. + /// + IOPreQueryFileInfo, + /// + /// Fires this event after the query file info IO was returned from the file system. + /// + IOPostQueryFileInfo, + /// + /// Fires this event before the set file size IO was going down to the file system. + /// + IOPreSetFileSize, + /// + /// Fires this event after the set file size IO was returned from the file system. + /// + IOPostSetFileSize, + /// + /// Fires this event before the set file basic info IO was going down to the file system. + /// + IOPreSetFileBasicInfo, + /// + /// Fires this event after the set file basic info IO was returned from the file system. + /// + IOPostSetFileBasicInfo, + /// + /// Fires this event before the set file standard info IO was going down to the file system. + /// + IOPreSetFileStandardInfo, + /// + /// Fires this event after the set file standard info IO was returned from the file system. + /// + IOPostSetFileStandardInfo, + /// + /// Fires this event before the set file network info was going down to the file system. + /// + IOPreSetFileNetworkInfo, + /// + /// Fires this event after the set file network info was returned from the file system. + /// + IOPostSetFileNetworkInfo, + /// + /// Fires this event before the file move or rename IO was going down to the file system. + /// + IOPreMoveOrRenameFile, + /// + /// Fires this event after the file move or rename IO was returned from the file system. + /// + IOPostMoveOrRenameFile, + /// + /// Fires this event before the file delete IO was going down to the file system. + /// + IOPreDeleteFile, + /// + /// Fires this event after the file delete IO was returned from the file system. + /// + IOPostDeleteFile, + /// + /// Fires this event before the set file info IO was going down to the file system + /// if the information class is not 'SetFileSize','SetFileBasicInfo' + /// ,'SetFileStandardInfo','SetFileNetworkInfo'. + /// + IOPreSetFileInfo, + /// + /// Fires this event after the set file info IO was returned from the file system. + /// + IOPostSetFileInfo, + /// + /// Fires this event before the query directory file info was going down to the file system. + /// + IOPreQueryDirectoryFile, + /// + /// Fires this event after the query directory file info was returned from the file system. + /// + IOPostQueryDirectoryFile, + /// + /// Fires this event before the query file security IO was going down to the file system. + /// + IOPreQueryFileSecurity, + /// + /// Fires this event after the query file security IO was returned from the file system. + /// + IOPostQueryFileSecurity, + /// + /// Fires this event before the set file security IO was going down to the file system. + /// + IOPreSetFileSecurity, + /// + /// Fires thiis event after the set file security IO was returned from the file system. + /// + IOPostSetFileSecurity, + /// + /// Fire this event before the file handle close IO was going down to the file system. + /// + IOPreFileHandleClose, + /// + /// Fires this event after the file handle close IO was returned from the file system. + /// + IOPostFileHandleClose, + /// + /// Fires this event before the file close IO was going down to the file system. + /// + IOPreFileClose, + /// + /// Fires this event after the file close IO was returned from the file system. + /// + IOPostFileClose, + +}IOName; + + /// +/// The volume control flag. +/// +typedef enum _VolumeControlFlag +{ + /// + /// Get all the attached volumes' information. + /// + GET_ATTACHED_VOLUME_INFO = 0x00000001, + /// + /// Get a notification when the filter driver attached to a volume. + /// + VOLUME_ATTACHED_NOTIFICATION = 0x00000002, + /// + /// Get a notification when the filter driver detached from a volume. + /// + VOLUME_DETACHED_NOTIFICATION = 0x00000004, + /// + ///Prevent the attched volumes from being formatted or dismounted. + /// + BLOCK_VOLUME_DISMOUNT = 0x00000008, + /// + ///Block the read from the USB disk. + /// + BLOCK_USB_READ = 0x00000010, + /// + ///Block the write to the USB disk + /// + BLOCK_USB_WRITE = 0x00000020, + + +}VolumeControlFlag; + + +// +//the structure of the attached volume information +typedef struct _VOLUME_INFO +{ + /// + /// The length of the volume name. + /// + ULONG VolumeNameLength; + /// + /// The volume name buffer. + /// + WCHAR VolumeName[MAX_FILE_NAME_LENGTH]; + /// + /// The length of the volume dos file name. + /// + ULONG VolumeDosNameLength; + /// + /// The volume dos file name buffer. + /// + WCHAR VolumeDosName[MAX_FILE_NAME_LENGTH]; + /// + ///the volume file system type. + /// + ULONG VolumeFilesystemType; + /// + ///the Characteristics of the attached device object if existed. + /// + ULONG DeviceCharacteristics; + + +} VOLUME_INFO, *PVOLUME_INFO; + + /// +/// process filter driver control flag. +/// +typedef enum _ProcessControlFlag +{ + /// + /// deny the new process creation if the flag is on + /// + DENY_NEW_PROCESS_CREATION = 0x00000001, + /// + /// send the callback request before the process is going to be terminated. + /// you can block the process termination in the callback function. + /// + PROCESS_PRE_TERMINATION_REQUEST = 0x00000002, + /// + /// Get a notification when a new process is being created. + /// + PROCESS_CREATION_NOTIFICATION = 0x00000100, + /// + ///get a notification when a process was terminated + /// + PROCESS_TERMINATION_NOTIFICATION = 0x00000200, + /// + /// get a notification for process handle operations, when a handle for a process + /// is being created or duplicated. + /// + PROCESS_HANDLE_OP_NOTIFICATION = 0x00000400, + /// + /// get a notifcation when a new thread is being created. + /// + THREAD_CREATION_NOTIFICATION = 0x00000800, + /// + /// get a notification when a thread was terminated + /// + THREAD_TERMINATION_NOTIFICATION = 0x00001000, + /// + /// get a notification for thread handle operations, when a handle for a process + /// is being created or duplicated. + /// + THREAD_HANDLE_OP_NOTIFICATION = 0x00002000, + +}ProcessControlFlag; + +/// +/// This is for registry filter driver only, the registry access control flag +/// +typedef enum _RegControlFlag +{ + REG_ALLOW_OPEN_KEY = 0x00000001, + REG_ALLOW_CREATE_KEY = 0x00000002, + REG_ALLOW_QUERY_KEY = 0x00000004, + REG_ALLOW_RENAME_KEY = 0x00000008, + REG_ALLOW_DELETE_KEY = 0x00000010, + REG_ALLOW_SET_VALUE_KEY_INFORMATION = 0x00000020, + REG_ALLOW_SET_INFORMATION_KEY = 0x00000040, + REG_ALLOW_ENUMERATE_KEY = 0x00000080, + REG_ALLOW_QUERY_VALUE_KEY = 0x00000100, + REG_ALLOW_ENUMERATE_VALUE_KEY = 0x00000200, + REG_ALLOW_QUERY_MULTIPLE_VALUE_KEY = 0x00000400, + REG_ALLOW_DELETE_VALUE_KEY = 0x00000800, + REG_ALLOW_QUERY_KEY_SECURITY = 0x00001000, + REG_ALLOW_SET_KEY_SECRUITY = 0x00002000, + REG_ALLOW_RESTORE_KEY = 0x00004000, + REG_ALLOW_REPLACE_KEY = 0x00008000, + REG_ALLOW_SAVE_KEY = 0x00010000, + REG_ALLOW_FLUSH_KEY = 0x00020000, + REG_ALLOW_LOAD_KEY = 0x00040000, + REG_ALLOW_UNLOAD_KEY = 0x00080000, + REG_ALLOW_KEY_CLOSE = 0x00100000, + REG_ALLOW_QUERY_KEYNAME = 0x00200000, + REG_MAX_ACCESS_FLAG = 0xFFFFFFFF, + +}RegControlFlag; + +/// +/// This is for registry filter driver only, the registry callback class, you can block or modify the registry access in pre-callback +/// or monitor the registry access in post-callback +/// +typedef enum _RegCallbackClass +{ + Reg_Pre_Delete_Key = 0x00000001, + Reg_Pre_Set_Value_Key = 0x00000002, + Reg_Pre_Delete_Value_Key = 0x00000004, + Reg_Pre_SetInformation_Key = 0x00000008, + Reg_Pre_Rename_Key = 0x00000010, + Reg_Pre_Enumerate_Key = 0x00000020, + Reg_Pre_Enumerate_Value_Key = 0x00000040, + Reg_Pre_Query_Key = 0x00000080, + Reg_Pre_Query_Value_Key = 0x00000100, + Reg_Pre_Query_Multiple_Value_Key = 0x00000200, + Reg_Pre_Create_Key = 0x00000400, + Reg_Post_Create_Key = 0x00000800, + Reg_Pre_Open_Key = 0x00001000, + Reg_Post_Open_Key = 0x00002000, + Reg_Pre_Key_Handle_Close = 0x00004000, + // + // .Net only + // + Reg_Post_Delete_Key = 0x00008000, + Reg_Post_Set_Value_Key = 0x00010000, + Reg_Post_Delete_Value_Key = 0x00020000, + Reg_Post_SetInformation_Key = 0x00040000, + Reg_Post_Rename_Key = 0x00080000, + Reg_Post_Enumerate_Key = 0x00100000, + Reg_Post_Enumerate_Value_Key = 0x00200000, + Reg_Post_Query_Key = 0x00400000, + Reg_Post_Query_Value_Key = 0x00800000, + Reg_Post_Query_Multiple_Value_Key = 0x01000000, + Reg_Post_Key_Handle_Close = 0x02000000, + Reg_Pre_Create_KeyEx = 0x04000000, + Reg_Post_Create_KeyEx = 0x08000000, + Reg_Pre_Open_KeyEx = 0x10000000, + Reg_Post_Open_KeyEx = 0x20000000, + // + // new to Windows Vista + // + Reg_Pre_Flush_Key = 0x40000000, + Reg_Post_Flush_Key = 0x80000000, + + //high field for reg callback class + #define Reg_Pre_Load_Key (ULONGLONG)0x100000000 + #define Reg_Post_Load_Key (ULONGLONG)0x200000000 + #define Reg_Pre_UnLoad_Key (ULONGLONG)0x400000000 + #define Reg_Post_UnLoad_Key (ULONGLONG)0x800000000 + #define Reg_Pre_Query_Key_Security (ULONGLONG)0x1000000000 + #define Reg_Post_Query_Key_Security (ULONGLONG)0x2000000000 + #define Reg_Pre_Set_Key_Security (ULONGLONG)0x4000000000 + #define Reg_Post_Set_Key_Security (ULONGLONG)0x8000000000 + // + // per-object context cleanup + // + #define Reg_Callback_Object_Context_Cleanup (ULONGLONG)0x10000000000 + // + // new in Vista SP2 + // + #define Reg_Pre_Restore_Key (ULONGLONG)0x20000000000 + #define Reg_Post_Restore_Key (ULONGLONG)0x40000000000 + #define Reg_Pre_Save_Key (ULONGLONG)0x80000000000 + #define Reg_Post_Save_Key (ULONGLONG)0x100000000000 + #define Reg_Pre_Replace_Key (ULONGLONG)0x200000000000 + #define Reg_Post_Replace_Key (ULONGLONG)0x400000000000 + + // + //new in Windows 10 + // + #define Reg_Pre_Query_KeyName (ULONGLONG)0x800000000000 + #define Reg_Post_Query_KeyName (ULONGLONG)0x1000000000000 + + #define Max_Reg_Callback_Class (ULONGLONG)0xFFFFFFFFFFFFFFFF + + +}RegCallbackClass; + +//the I/O types of the monitor or control filter can intercept if you register the class. +//the monitor IO only can register the post IO, it meant you can get the notification after the IO was completed. +//the control IO can register both pre IO before the IO was processed by the file system and post IO after the IO +//was processed by the file system, the driver will wait for the response of the callback function. +typedef enum _IOCallbackClass +{ + //this is the IRP_MJ_CREATE which requests to open a handle + PRE_CREATE = 0x00000001, + POST_CREATE = 0x00000002, + + //this is the filter only intercept the IO when the file was created. + #define PRE_NEW_FILE_CREATED (ULONGLONG)0x0000000100000000 + #define POST_NEW_FILE_CREATED (ULONGLONG)0x0000000200000000 + + //this is the fast I/O read,return true when the data is in cache, + //if the data is not in cache, a new IRP cache read request will be generated. + PRE_FASTIO_READ = 0x00000004, + POST_FASTIO_READ = 0x00000008, + + //this is the IRP_MJ_READ cache read, the data will be read from the cache, + //if the data is not in cache, a paging read request will be generated. + PRE_CACHE_READ = 0x00000010, + POST_CACHE_READ = 0x00000020, + + //this is the IRP_MJ_READ no cache read, the data read will be bypassed the cache manager. + PRE_NOCACHE_READ = 0x00000040, + POST_NOCACHE_READ = 0x00000080, + + //this is the IRP_MJ_READ paging read, the data will be read from the disk to the cache. + PRE_PAGING_IO_READ = 0x00000100, + POST_PAGING_IO_READ = 0x00000200, + + //this is the fast I/O write,the data was written to the cache if the request is satisfied immediately, + //or a IRP cache write will be generated. + PRE_FASTIO_WRITE = 0x00000400, + POST_FASTIO_WRITE = 0x00000800, + + //this is the IRP_MJ_WRITE I/O cache write,the data was written to the cache, the IRP paging write will be gernerated after the cache write. + PRE_CACHE_WRITE = 0x00001000, + POST_CACHE_WRITE = 0x00002000, + + //this is the IRP_MJ_WRITE no cache write, the data read will be written to the disk directly and bypass the cache manager. + PRE_NOCACHE_WRITE = 0x00004000, + POST_NOCACHE_WRITE = 0x00008000, + + //this is the IRP_MJ_WRITE paging write, the data will be written from the cache to the disk. + PRE_PAGING_IO_WRITE = 0x00010000, + POST_PAGING_IO_WRITE = 0x00020000, + + //this the IRP_QUERY_INFORMATION to query the file information. + //if you register this class, the filter driver will intercept all requests to query information. + //if you want to only filter speecific query,i.e. only file size, you can register the below specific class. + PRE_QUERY_INFORMATION = 0x00040000, + POST_QUERY_INFORMATION = 0x00080000, + + //this the IRP_QUERY_INFORMATION with specific info class to query file size + #define PRE_QUERY_FILE_SIZE (ULONGLONG)0x0000000400000000 + #define POST_QUERY_FILE_SIZE (ULONGLONG)0x0000000800000000 + + //this the IRP_QUERY_INFORMATION with specific info class to query file basic information + #define PRE_QUERY_FILE_BASIC_INFO (ULONGLONG)0x0000001000000000 + #define POST_QUERY_FILE_BASIC_INFO (ULONGLONG)0x0000002000000000 + + //this the IRP_QUERY_INFORMATION with specific info class to query file standard information + #define PRE_QUERY_FILE_STANDARD_INFO (ULONGLONG)0x0000004000000000 + #define POST_QUERY_FILE_STANDARD_INFO (ULONGLONG)0x0000008000000000 + + //this the IRP_QUERY_INFORMATION with specific info class to query file network information + #define PRE_QUERY_FILE_NETWORK_INFO (ULONGLONG)0x0000010000000000 + #define POST_QUERY_FILE_NETWORK_INFO (ULONGLONG)0x0000020000000000 + + //this the IRP_QUERY_INFORMATION with specific info class to query file Id + #define PRE_QUERY_FILE_ID (ULONGLONG)0x0000040000000000 + #define POST_QUERY_FILE_ID (ULONGLONG)0x0000080000000000 + + //this the IRP_SET_INFORMATION to set the file information. + //if you register this class,the filter driver will intercept all requests to set the file information. + //if you want to only intercept specific set information, you can register below specific class. + PRE_SET_INFORMATION = 0x00100000, + POST_SET_INFORMATION = 0x00200000, + + //this the IRP_SET_INFORMATION with specific info class to set file size + #define PRE_SET_FILE_SIZE (ULONGLONG)0x0000400000000000 + #define POST_SET_FILE_SIZE (ULONGLONG)0x0000800000000000 + + //this the IRP_SET_INFORMATION with specific info class to set file basic information + #define PRE_SET_FILE_BASIC_INFO (ULONGLONG)0x0001000000000000 + #define POST_SET_FILE_BASIC_INFO (ULONGLONG)0x0002000000000000 + + //this the IRP_SET_INFORMATION with specific info class to set file standard information + #define PRE_SET_FILE_STANDARD_INFO (ULONGLONG)0x0004000000000000 + #define POST_SET_FILE_STANDARD_INFO (ULONGLONG)0x0008000000000000 + + //this the IRP_SET_INFORMATION with specific info class to set file network information + #define PRE_SET_FILE_NETWORK_INFO (ULONGLONG)0x0010000000000000 + #define POST_SET_FILE_NETWORK_INFO (ULONGLONG)0x0020000000000000 + + //this the IRP_SET_INFORMATION with specific info class to rename the file + #define PRE_RENAME_FILE (ULONGLONG)0x0040000000000000 + #define POST_RENAME_FILE (ULONGLONG)0x0080000000000000 + + //this the IRP_SET_INFORMATION with specific info class to delete the file + #define PRE_DELETE_FILE (ULONGLONG)0x0100000000000000 + #define POST_DELETE_FILE (ULONGLONG)0x0200000000000000 + + //this the IRP_MJ_DIRECTORY_CONTROL to query the file directory information. + PRE_DIRECTORY = 0x00400000, + POST_DIRECTORY = 0x00800000, + + //this the IRP_MJ_QUERY_SECURITY to query the file security information. + PRE_QUERY_SECURITY = 0x01000000, + POST_QUERY_SECURITY = 0x02000000, + + //this the IRP_MJ_SET_SECURITY to set the file security information. + PRE_SET_SECURITY = 0x04000000, + POST_SET_SECURITY = 0x08000000, + + //this the IRP_MJ_CLEANUP to close the file handle. + PRE_CLEANUP = 0x10000000, + POST_CLEANUP = 0x20000000, + + //this the IRP_MJ_CLOSE to close the file I/O. + PRE_CLOSE = 0x40000000, + POST_CLOSE = 0x80000000UL, + +}IOCallbackClass; + +//the flags of the access control to the file. +typedef enum _AccessFlag +{ + /// + /// Filter driver will skip all the IO if the file name match the include file mask. + /// + EXCLUDE_FILTER_RULE = 0X00000000, + /// + /// Block the file open. + /// + EXCLUDE_FILE_ACCESS = 0x00000001, + /// + /// Reparse the file open to the new file name if the reparse file mask was added. + /// + ENABLE_REPARSE_FILE_OPEN = 0x00000002, + /// + /// Hide the files from the folder directory list if the hide file mask was added. + /// + ENABLE_HIDE_FILES_IN_DIRECTORY_BROWSING = 0x00000004, + /// + /// Enable the transparent file encryption if the encryption key was added. + /// + ENABLE_FILE_ENCRYPTION_RULE = 0x00000008, + /// + /// Allow the file open to access the file's security information. + /// + ALLOW_OPEN_WITH_ACCESS_SYSTEM_SECURITY = 0x00000010, + /// + /// Allow the file open for read access. + /// + ALLOW_OPEN_WITH_READ_ACCESS = 0x00000020, + /// + /// Allow the file open for write access. + /// + ALLOW_OPEN_WITH_WRITE_ACCESS = 0x00000040, + /// + /// Allow the file open for create new file or overwrite access. + /// + ALLOW_OPEN_WITH_CREATE_OR_OVERWRITE_ACCESS = 0x00000080, + /// + /// Allow the file open for delete. + /// + ALLOW_OPEN_WITH_DELETE_ACCESS = 0x00000100, + /// + /// Allow to read the file data. + /// + ALLOW_READ_ACCESS = 0x00000200, + /// + /// Allow write data to the file. + /// + ALLOW_WRITE_ACCESS = 0x00000400, + /// + /// Allow to query file information. + /// + ALLOW_QUERY_INFORMATION_ACCESS = 0x00000800, + /// + /// Allow to change the file information:file attribute,file size,file name,delete file + /// + ALLOW_SET_INFORMATION = 0x00001000, + /// + /// Allow to rename the file. + /// + ALLOW_FILE_RENAME = 0x00002000, + /// + /// Allow to delete the file. + /// + ALLOW_FILE_DELETE = 0x00004000, + /// + /// Allow to change file size. + /// + ALLOW_FILE_SIZE_CHANGE = 0x00008000, + /// + /// Allow query the file security information. + /// + ALLOW_QUERY_SECURITY_ACCESS = 0x00010000, + /// + /// Allow change the file security information. + /// + ALLOW_SET_SECURITY_ACCESS = 0x00020000, + /// + /// Allow to browse the directory file list. + /// + ALLOW_DIRECTORY_LIST_ACCESS = 0x00040000, + /// + /// Allow the remote access via share folder. + /// + ALLOW_FILE_ACCESS_FROM_NETWORK = 0x00080000, + /// + /// Allow to encrypt the new file if the encryption filter rule is enabled, . + /// + ALLOW_ENCRYPT_NEW_FILE = 0x00100000, + /// + /// Allow the application to read the encrypted files, or it will return encrypted data. + /// + ALLOW_READ_ENCRYPTED_FILES = 0x00200000, + /// + /// Allow the application to create a new file after it opened the protected file. + /// + ALLOW_ALL_SAVE_AS = 0x00400000, + /// + /// Allow copy protected files out of the protected folder if ALLOW_ALL_SAVE_AS is enabled. + /// + ALLOW_COPY_PROTECTED_FILES_OUT = 0x00800000, + /// + /// Allow the file to be mapped. + /// + ALLOW_FILE_MEMORY_MAPPED = 0x01000000, + /// + /// if the encryption filter rule is enabled, it will encrypt unencrypted data on read when the flag value is 0. + /// + DISABLE_ENCRYPT_DATA_ON_READ = 0x02000000, + /// + /// prevent the protected files from being copying out to the USB when the flag value is 0. + /// + ALLOW_COPY_PROTECTED_FILES_TO_USB = 0x04000000, + /// + /// If it is not exclude filter rule,the access flag can't be 0, at least you need to include this flag + /// for filter driver with least access right to the file. + /// + LEAST_ACCESS_FLAG = 0xf0000000, + /// + /// Allow the maximum right access. + /// + ALLOW_MAX_RIGHT_ACCESS = 0xfffffff0, + +}AccessFlag; + + + +//this is the boolean data of the user mode app sending to the filter. +//this is the boolean configuration of the filter driver. +typedef enum _BooleanConfig +{ + /// + ///for easetag, if it was true, after the reparsepoint file was opened, it won't restore data back for read and write. + /// + ENABLE_NO_RECALL_FLAG = 0x00000001, + /// + /// if it is true, the filter driver can't be unloaded. + /// + DISABLE_FILTER_UNLOAD_FLAG = 0x00000002, + /// + /// for virtual file, it will set offline attribute if it is true. + /// + ENABLE_SET_OFFLINE_FLAG = 0x00000004, + /// + /// for encryption, it is true, it will use the default IV tag to encrypt the files. + /// + ENABLE_DEFAULT_IV_TAG = 0x00000008, + /// + /// if it is enabled, it will send the message data to a persistent file, or it will send the event to service right away. + /// + ENABLE_ADD_MESSAGE_TO_FILE = 0x00000010, + /// + /// the encrypted file's meta data was embedded in the reparse point tag, it is for the previous version 5.0. + /// + ENCRYPT_FILE_WITH_REPARSE_POINT_TAG = 0x00000020, + /// + /// for encryption rule, get the encryption key and IV from user mode for the encrypted files. + /// + REQUEST_ENCRYPT_KEY_AND_IV_FROM_SERVICE = 0x00000040, + /// + /// for control filter, if it is enabled, the control filter rule will be applied in boot time. + /// + ENABLE_PROTECTION_IN_BOOT_TIME = 0x00000080, + /// + /// for encryption rule, get the encryption key and IV and tag data which will attach to the file. + /// + REQUEST_ENCRYPT_KEY_IV_AND_TAGDATA_FROM_SERVICE = 0x00000100, + /// + /// if it is enabled, it will send the read/write databuffer to user mode. + /// + ENABLE_SEND_DATA_BUFFER = 0x00000200, + /// + /// if it is enabled, it will reopen the file during rehydration of the stub file. + /// + ENABLE_REOPEN_FILE_ON_REHYDRATION = 0x00000400, + /// + /// if it is true, it will enable the buffer for monitor events and send asynchronously, + /// or the monitor event will wait till the service picks up the events. + /// + ENABLE_MONITOR_EVENT_BUFFER = 0x00000800, + /// + /// if it is true, it will send the event when it was blocked by the config setting. + /// + ENABLE_SEND_DENIED_EVENT = 0x00001000, + /// + /// if it is true, and the write access is false,the write will return success + /// with zero data being written to the file, and send the write data to the user mode. + // this flag is for custom usage. + /// + ENABLE_WRITE_WITH_ZERO_DATA_AND_SEND_DATA = 0x00002000, + /// + /// if it is true, the portable massive storage will be treated as USB. + // this is for the volume control flag for BLOCK_USB_READ,BLOCK_USB_WRITE + /// + DISABLE_REMOVABLE_MEDIA_AS_USB = 0x00004000, + /// + /// if it is true, it will block the encrypted file to be renamed to different folder. + /// + DISABLE_RENAME_ENCRYPTED_FILE = 0x00008000, + /// + /// if it is true, it will disable the file synchronization for file reading for CloudTier. + /// + DISABLE_FILE_SYNCHRONIZATION = 0x00010000, + /// + /// if it is true, the data protection will continue even the service process is stopped. + /// + ENABLE_PROTECTION_IF_SERVICE_STOPPED = 0x00020000, + /// + /// if it is true and write encrypt info to cache is enabled, it will signal the system thread to write cache data to disk right away. + /// + ENABLE_SIGNAL_WRITE_ENCRYPT_INFO_EVENT = 0x00020000, + /// + ///enable this feature when accessFlag "ALLOW_SAVE_AS" or "ALLOW_COPY_PROTECTED_FILES_OUT" was disabled. + ///by default we don't enable this feature, because of the drawback of these two flags were disabled + ///which will block all new file creation of the process which was read the protected files. + /// + ENABLE_BLOCK_SAVE_AS_FLAG = 0x00040000, + +} BooleanConfig; + + +//this is the data structure of the filter driver sending data to the user mode app. +typedef struct _MESSAGE_SEND_DATA +{ + /// + ///the verification number which verifies the data structure integerity. + /// + ULONG VerificationNumber; + /// + /// This is the command Id which was sent by filter driver. + /// + ULONG FilterCommand; + /// + /// This is the sequential message Id, just for reference. + /// + ULONG MessageId; + /// + /// This the filter rule Id associated to the filter rule. + /// + ULONG FilterRuleId; + /// + /// This is the ip address of the remote computer when it accesses the file via SMB. + /// it is only effected for win 7 or later OS. + /// + WCHAR RemoteIP[INET_ADDR_STR_LEN]; + /// + ///the address of FileObject,it is equivalent to file handle,it is unique per file stream open. + /// + PVOID FileObject; + /// + ///the address of FsContext,it is unique per file. + /// + PVOID FsContext; + /// + ///the message type of the file I/O, registry class. + /// + LONGLONG MessageType; + /// + ///the process ID for the process associated with the thread that originally requested the I/O operation. + /// + ULONG ProcessId; + /// + ///the thread ID which requested the I/O operation. + /// + ULONG ThreadId; + /// + ///the read/write offset. + /// + LONGLONG Offset; + /// + ///the read/write length. + /// + ULONG Length; + /// + ///the size of the file for the I/O operation. + /// + LONGLONG FileSize; + /// + ///the transaction time in UTC of this request. + /// + LONGLONG TransactionTime; + /// + ///the creation time in UTC of the file. + /// + LONGLONG CreationTime; + /// + ///the last access time in UTC of the file. + /// + LONGLONG LastAccessTime; + /// + ///the last write time in UTC of the file. + /// + LONGLONG LastWriteTime; + /// + ///the file attributes. + /// + ULONG FileAttributes; + /// + ///the DesiredAccess for file open, please reference CreateFile windows API. + /// + ULONG DesiredAccess; + /// + ///the Disposition for file open, please reference CreateFile windows API. + /// + ULONG Disposition; + /// + ///the SharedAccess for file open, please reference CreateFile windows API. + /// + ULONG ShareAccess; + /// + ///the CreateOptions for file open, please reference CreateFile windows API. + /// + ULONG CreateOptions; + /// + ///the CreateStatus after file was openned, please reference CreateFile windows API. + /// + ULONG CreateStatus; + /// + ///this is the information class for security/directory/information IO + /// + ULONG InfoClass; + /// + ///the I/O status which returned from file system. + /// + ULONG Status; + /// + /// the return I/O (read/write) length + /// + ULONG ReturnLength; + /// + ///the file name length in byte. + /// + ULONG FileNameLength; + /// + ///the file name of the I/O operation. + /// + WCHAR FileName[MAX_FILE_NAME_LENGTH]; + /// + ///the length of the security identifier. + /// + ULONG SidLength; + /// + ///the security identifier data. + /// + UCHAR Sid[MAX_SID_LENGTH]; + /// + ///the data buffer length. + /// + ULONG DataBufferLength; + /// + ///the data buffer which contains read/write/query information/set information data. + /// + UCHAR DataBuffer[MAX_BUFFER_SIZE]; + +} MESSAGE_SEND_DATA, *PMESSAGE_SEND_DATA; + + +// +//the structure of the new creating process information +typedef struct _PROCESS_INFO +{ + + /// + ///The process ID of the parent process for the new process. Note that the parent process is not necessarily the same process as the process that created the new process. + /// + ULONG ParentProcessId; + /// + /// The process ID of the process that created the new process. + /// + ULONG CreatingProcessId; + /// + /// The thread ID of the thread that created the new process. + /// + ULONG CreatingThreadId; + /// + ///An ACCESS_MASK value that specifies the access rights to grant for the handle for OB_PRE_CREATE_HANDLE_INFORMATION. + /// + ULONG DesiredAccess; + /// + ///The type of handle operation. This member might be one of the following values:OB_OPERATION_HANDLE_CREATE,OB_OPERATION_HANDLE_DUPLICATE + /// + ULONG Operation; + /// + /// A Boolean value that specifies whether the ImageFileName member contains the exact file name that is used to open the process executable file. + /// + ULONG FileOpenNameAvailable; + /// + /// The length of the command line. + /// + ULONG CommandLineLength; + /// + /// The command that is used to execute the process. + /// + WCHAR CommandLine[MAX_FILE_NAME_LENGTH]; + +} PROCESS_INFO, *PPROCESS_INFO; + +//The status return to filter,instruct filter driver what action needs to be done. +typedef enum _FilterStatus +{ + FILTER_MESSAGE_IS_DIRTY = 0x00000001, //Set this flag if the reply message need to be processed. + FILTER_COMPLETE_PRE_OPERATION = 0x00000002, //Set this flag if complete the pre operation. + FILTER_DATA_BUFFER_IS_UPDATED = 0x00000004, //Set this flag if the databuffer was updated. + FILTER_BLOCK_DATA_WAS_RETURNED = 0x00000008, //Set this flag if return read block databuffer to filter. + FILTER_CACHE_FILE_WAS_RETURNED = 0x00000010, //Set this flag if the whole cache file was downloaded. + FILTER_REHYDRATE_FILE_VIA_CACHE_FILE = 0x00000020, //Set this flag if the whole cache file was downloaded and stub file needs to be rehydrated. + +} FilterStatus, *PFilterStatus; + +//this is the enumeration of the file I/O events. +typedef enum _FileEventType +{ + FILE_WAS_CREATED = 0x00000020, + FILE_WAS_WRITTEN = 0x00000040, + FILE_WAS_RENAMED = 0x00000080, + FILE_WAS_DELETED = 0x00000100, + FILE_SECURITY_CHANGED = 0x00000200, + FILE_INFO_CHANGED = 0x00000400, + FILE_WAS_READ = 0x00000800, + FILE_WAS_COPIED = 0x00001000, + +} FileEventType, *PFileEventType; + +//This is the enumeration of the file copy flags. +typedef enum _FILE_COPY_FLAG +{ + //this is the source file for copy in the open. + CREATE_FLAG_FILE_SOURCE_OPEN_FOR_COPY = 0x00000001, + //this is the dest file for copy in the open. + CREATE_FLAG_FILE_DEST_OPEN_FOR_COPY = 0x00000002, + //this is the source file read for file copy. + READ_FLAG_FILE_SOURCE_FOR_COPY = 0x00000004, + //this is the destination file write for file copy. + WRITE_FLAG_FILE_DEST_FOR_COPY = 0x00000008, + +} FILE_COPY_FLAG; + +// +// Define the various device characteristics flags +// +//typedef enum _File_Characteristics +//{ +// FILE_REMOVABLE_MEDIA = 0x00000001, +// FILE_READ_ONLY_DEVICE = 0x00000002, +// FILE_FLOPPY_DISKETTE = 0x00000004, +// FILE_WRITE_ONCE_MEDIA = 0x00000008, +// FILE_REMOTE_DEVICE = 0x00000010, +// FILE_DEVICE_IS_MOUNTED = 0x00000020, +// FILE_VIRTUAL_VOLUME = 0x00000040, +// FILE_AUTOGENERATED_DEVICE_NAME = 0x00000080, +// FILE_DEVICE_SECURE_OPEN = 0x00000100, +// FILE_CHARACTERISTIC_PNP_DEVICE = 0x00000800, +// FILE_CHARACTERISTIC_TS_DEVICE = 0x00001000, +// FILE_CHARACTERISTIC_WEBDAV_DEVICE = 0x00002000, +// FILE_CHARACTERISTIC_CSV = 0x00010000, +// FILE_DEVICE_ALLOW_APPCONTAINER_TRAVERSAL = 0x00020000, +// FILE_PORTABLE_DEVICE = 0x00040000, +// +//}File_Characteristics,*PFile_Characteristics; + + + +//This is the return data structure from user mode to the filter driver. +typedef struct _MESSAGE_REPLY_DATA +{ + ULONG MessageId; + ULONG MessageType; + ULONG ReturnStatus; + ULONG FilterStatus; + union { + struct { + ULONG DataBufferLength; + UCHAR DataBuffer[BLOCK_SIZE]; + } Data; + struct { + ULONG SizeOfData; + struct{ + ULONG AccessFlag; + ULONG IVLength; + UCHAR IV[16]; + ULONG EncryptionKeyLength; + UCHAR EncryptionKey[32]; + ULONG TagDataLength; + UCHAR TagData[1]; + }Data; + } AESData; + struct { + ULONG UserNameLength; + WCHAR UserName[1]; + } UserInfo; + struct { + ULONG FileNameLength; + WCHAR FileName[1]; + } FileInfo; + + }ReplyData; + +} MESSAGE_REPLY_DATA, *PMESSAGE_REPLY_DATA; + +#define STATUS_ACCESS_DENIED 0xC0000022L + +/// +/// install the filter driver service, it request the administrator privilege +/// +extern "C" __declspec(dllexport) +BOOL +InstallDriver(); + +/// +/// uninstall the filter driver service. +/// +extern "C" __declspec(dllexport) +BOOL +UnInstallDriver(); + +/// +/// set the registration key to enable the filter driver service. +/// +extern "C" __declspec(dllexport) +BOOL +SetRegistrationKey(char* key); + +typedef BOOL (__stdcall *Proto_Message_Callback)( + IN PMESSAGE_SEND_DATA pSendMessage, + IN OUT PMESSAGE_REPLY_DATA pReplyMessage); + +typedef VOID (__stdcall *Proto_Disconnect_Callback)(); + +/// +/// Create the filter driver connection with callback settings +/// +/// the number of working threads waitting for the callback message +/// the callback function +/// the disconnect callback function +extern "C" __declspec(dllexport) +BOOL +RegisterMessageCallback( + ULONG ThreadCount, + Proto_Message_Callback MessageCallback, + Proto_Disconnect_Callback DisconnectCallback ); + +extern "C" __declspec(dllexport) +VOID +Disconnect(); + +extern "C" __declspec(dllexport) +BOOL +GetLastErrorMessage(WCHAR* Buffer, PULONG BufferLength); + +extern "C" __declspec(dllexport) +BOOL +SetIntegerData(ULONG dataControlId, LONGLONG data ); + +extern "C" __declspec(dllexport) +BOOL +SetStringData(ULONG stringControlId, WCHAR* stringData); + +/// +/// reset the filter driver config settings to the default value. +/// +extern "C" __declspec(dllexport) +BOOL +ResetConfigData(); + +extern "C" __declspec(dllexport) +BOOL +ProtectCurrentProcess(); + +extern "C" __declspec(dllexport) +BOOL +StopProtectCurrentProcess(); + +extern "C" __declspec(dllexport) +BOOL +SetFilterType(ULONG FilterType); + +/// +/// set the filter driver boolean config setting based on the enum booleanConfig +/// +extern "C" __declspec(dllexport) +BOOL +SetBooleanConfig(ULONG booleanConfig); + +/// +/// set the maximum monitor event buffer size if monitorBuffer was enabled. +/// +extern "C" __declspec(dllexport) +BOOL +SetMaxMonitorEventBuffersize(ULONG maxBufferSize); + +/// +/// set the maiximun wait time of the filter driver sending message to service. +/// +extern "C" __declspec(dllexport) +BOOL +SetConnectionTimeout(ULONG TimeOutInSeconds); + +extern "C" __declspec(dllexport) +BOOL +SetVolumeControlFlag(ULONG volumeControlFlag); + +//obsolete +extern "C" __declspec(dllexport) +BOOL +AddFilterRule(ULONG AccessFlag, WCHAR* FilterMask, WCHAR* FilterMask2 = NULL,ULONG keyLength = 0,PUCHAR key = NULL); + +//obsolete +extern "C" __declspec(dllexport) +BOOL +AddNewFilterRule(ULONG accessFlag, WCHAR* filterMask,BOOL isResident = FALSE); + +/// +/// Add the new filter rule to the filter driver. +/// +/// access control rights of the file IO to the files which match the filter mask +/// the filter rule file filter mask, it must be unique. +/// if it is true, the filter rule will be added to the registry, get protection in boot time. +/// the id to identify the filter rule, it will show up in messageId field of messageSend structure if the callback is registered +extern "C" __declspec(dllexport) +BOOL +AddFileFilterRule(ULONG accessFlag, WCHAR* filterMask,BOOL isResident = FALSE, ULONG filterRuleId = 0 ); + +/// +/// Remove the filter rule from the filter driver. +/// +/// the filter rule file filter mask +extern "C" __declspec(dllexport) +BOOL +RemoveFilterRule(WCHAR* FilterMask); + +/// +///Set an encryption folder, every encrypted file has the unique iv key, +///the encrypted information will be appended to the file as an header, +///the filter driver will know if the file was encrypted by checking the header. +/// +extern "C" __declspec(dllexport) +BOOL +AddEncryptionKeyToFilterRule(WCHAR* filterMask,ULONG encryptionKeyLength,PUCHAR encryptionKey); + +/// +///Set an encryption folder, all encrypted files use the same encryption key and IV key. +/// +extern "C" __declspec(dllexport) +BOOL +AddEncryptionKeyAndIVToFilterRule(WCHAR* filterMask,ULONG encryptionKeyLength,PUCHAR encryptionKey,ULONG ivLength, PUCHAR iv); +/// +/// reparse the file open to the other file if the file matches the file filter mask. +/// +///For example: +///FilterMask = c:\test\*txt +///ReparseFilterMask = d:\reparse\*doc +///If you open file c:\test\MyTest.txt, it will reparse to the file d:\reparse\MyTest.doc. +/// +/// the filter rule file filter mask +/// reparse file filter mask +extern "C" __declspec(dllexport) +BOOL +AddReparseFileMaskToFilterRule(WCHAR* filterMask, WCHAR* reparseFilterMask); +/// +/// Hide the files from the browsing file list for the filter rule. +/// +/// the filter rule file filter mask. +/// the file filter mask for the hidden files. +extern "C" __declspec(dllexport) +BOOL +AddHiddenFileMaskToFilterRule(WCHAR* filterMask, WCHAR* hiddenFileFilterMask); + +/// +/// Exclude the file IO from this filter rule if the files match the excludeFileFilterMask. +/// +extern "C" __declspec(dllexport) +BOOL +AddExcludeFileMaskToFilterRule(WCHAR* filterMask, WCHAR* excludeFileFilterMask); + +/// +/// only manage the IO of the filter rule for the processes in the included process id list +/// +/// the file filter mask of the filter rule +/// the included process Id +extern "C" __declspec(dllexport) +BOOL +AddIncludeProcessIdToFilterRule(WCHAR* filterMask, ULONG includePID); + +/// +/// skip the IO of the filter rule for the processes in the excluded process id list +/// +/// the file filter mask of the filter rule +/// the excluded process Id +extern "C" __declspec(dllexport) +BOOL +AddExcludeProcessIdToFilterRule(WCHAR* filterMask, ULONG excludePID); + +/// +/// only manage the IO of the filter rule for the processes in the included process list +/// +/// the file filter mask of the filter rule +/// the include process name filter mask, process name format:notepad.exe +extern "C" __declspec(dllexport) +BOOL +AddIncludeProcessNameToFilterRule(WCHAR* filterMask, WCHAR* processName); + +/// +/// skip the IO of the filter rule for the processes in the excluded process list +/// +/// the file filter mask of the filter rule +/// the include process name filter mask +extern "C" __declspec(dllexport) +BOOL +AddExcludeProcessNameToFilterRule(WCHAR* filterMask, WCHAR* processName); + +/// +/// only manage the IO of the filter rule for user name in the included user name list +/// +/// the file filter mask of the filter rule +/// the included user name, format:domainName(or computerName)\userName.exe +extern "C" __declspec(dllexport) +BOOL +AddIncludeUserNameToFilterRule(WCHAR* filterMask, WCHAR* userName); + +/// +///skip the IO of the filter rule for user name in the excluded user name list +/// +/// the file filter mask of the filter rule +/// the excluded user name, format:domainName(or computerName)\userName.exe +extern "C" __declspec(dllexport) +BOOL +AddExcludeUserNameToFilterRule(WCHAR* filterMask, WCHAR* processName); + +/// +/// Filter the I/O based on the file create options,the IO will be skipped if the filter option is not 0 +/// and the file create options don't match the filter. +/// +/// the file filter mask of the filter rule +/// if it is not 0, the filter driver will check if the file creation option "DesiredAccess" matches the filter +/// if it is not 0, the filter driver will check if the file creation option "Disposition" matches the filter +/// if it is not 0, the filter driver will check if the file creation option "CreateOptions" matches the filter +extern "C" __declspec(dllexport) +BOOL +AddCreateFilterToFilterRule(WCHAR* filterMask, ULONG filterByDesiredAccess, ULONG filterByDisposition,ULONG filterByCreateOptions); + + +/// +///obsolete API,use RegisterFileChangedEventsToFilterRule instead. +/// Register the file I/O event types for the filter rule, get the notification when the I/O was triggered +/// after the file handle was closed. +/// +/// the file filter mask of the filter rule +/// the I/O event types,reference the FileEventType enumeration. +extern "C" __declspec(dllexport) +BOOL +RegisterEventTypeToFilterRule(WCHAR* filterMask, ULONG eventType); + +/// +/// Register the file changed events for the filter rule, get the notification when the I/O was triggered +/// after the file handle was closed. +/// +/// the file filter mask of the filter rule +/// the I/O event types,reference the FileEventType enumeration. +extern "C" __declspec(dllexport) +BOOL +RegisterFileChangedEventsToFilterRule(WCHAR* filterMask, ULONG eventType); + +/// +/// Register the callback I/O for monitor filter driver to the filter rule. +/// +/// the file filter mask of the filter rule +/// the specific I/Os you want to monitor +extern "C" __declspec(dllexport) +BOOL +RegisterMonitorIOToFilterRule(WCHAR* filterMask, ULONGLONG registerIO); + +/// +/// Register the callback I/O for control filter driver to the filter rule, you can change, block and pass the I/O +/// in your callback funtion. +/// +/// the file filter mask of the filter rule +/// the specific I/Os you want to monitor or control +extern "C" __declspec(dllexport) +BOOL +RegisterControlIOToFilterRule(WCHAR* filterMask, ULONGLONG registerIO); + +/// +/// Set the access rights to the specific process +/// +/// the file filter mask of the filter rule +/// the process name will be added the access rights, e.g. notepad.exe or c:\windows\*.exe +/// the access rights +extern "C" __declspec(dllexport) +BOOL +AddProcessRightsToFilterRule(WCHAR* filterMask, WCHAR* processName, ULONG accessFlags); + +/// +/// Remove the acces right setting for specific processes from filter rule +/// +/// tthe filter rule file filter mask +/// the process name filter mask +extern "C" __declspec(dllexport) +BOOL +RemoveProcessRightsFromFilterRule(WCHAR* filterMask, WCHAR* processName); + +/// +/// Set the access control flags to process with the processId +/// +/// the filter rule file filter mask +/// the process Id which will be added the access control flags +/// the access control flags +extern "C" __declspec(dllexport) +BOOL +AddProcessIdRightsToFilterRule(WCHAR* filterMask, ULONG processId, ULONG accessFlags); + +/// +/// Remove the acces right setting for specific process from filter rule +/// +/// the filter rule file filter mask +/// the process Id +extern "C" __declspec(dllexport) +BOOL +RemoveProcessIdRightsFromFilterRule(WCHAR* filterMask, ULONG processId); + +/// +/// Set the access control rights to specific users +/// +/// the filter rule file filter mask +/// the user name you want to set the access right +/// the access rights +extern "C" __declspec(dllexport) +BOOL +AddUserRightsToFilterRule(WCHAR* filterMask, WCHAR* userName, ULONG accessFlags); + +/// +/// Get sha256 hash of the file, you need to allocate the 32 bytes array to get the sha256 hash. +/// hashBytesLength is the input byte array length, and the outpout length of the hash. +/// +extern "C" __declspec(dllexport) +BOOL +Sha256HashFile( + LPCTSTR sourceFileName, + BYTE* hashBytes, + ULONG* hashBytesLength); + +/// +/// Add the access rights to the process which has the same sha256 hash as the setting. +/// +/// The filter rule file filter mask. +/// the sha256 hash of the executable binary file. +/// the length of the sha256 hash, by default is 32. +/// the access flags for the setting process. +/// return true if it is succeeded. +extern "C" __declspec(dllexport) +BOOL +AddSha256ProcessAccessRightsToFilterRule( + WCHAR* filterMask, + PUCHAR imageSha256, + ULONG hashLength, + ULONG accessFlags); + +/// +/// Add the access rights of the process which was signed with the code certificate +/// to the filter rule. +/// +/// The filter rule file filter mask. +/// the sha256 hash of the executable binary file. +/// the length of the sha256 hash, by default is 32. +/// the access flags for the setting process. +/// return true if it is succeeded. +extern "C" __declspec(dllexport) +BOOL +AddSignedProcessAccessRightsToFilterRule( + WCHAR* filterMask, + WCHAR* certificateName, + ULONG lengthOfCertificate, + ULONG accessFlags); + +/// +/// Add the boolean config setting to a filter rule. +/// Reference BooleanConfig settings +/// +/// the filter rule file filter mask +/// the boolean config setting +extern "C" __declspec(dllexport) +BOOL +AddBooleanConfigToFilterRule(WCHAR* filterMask, ULONG booleanConfig); + +extern "C" __declspec(dllexport) +BOOL +RemoveBooleanConfigFromFilterRule(WCHAR* filterMask); + +extern "C" __declspec(dllexport) +BOOL +AddExcludedProcessId(ULONG ProcessId); + +extern "C" __declspec(dllexport) +BOOL +RemoveExcludeProcessId(ULONG ProcessId); + +extern "C" __declspec(dllexport) +BOOL +AddIncludedProcessId(ULONG processId); + +extern "C" __declspec(dllexport) +BOOL +RemoveIncludeProcessId(ULONG processId); + +extern "C" __declspec(dllexport) +BOOL +AddProtectedProcessId(ULONG processId); + +extern "C" __declspec(dllexport) +BOOL +RemoveProtectedProcessId(ULONG processId); + +extern "C" __declspec(dllexport) +BOOL +AddBlockSaveAsProcessId(ULONG processId); + +extern "C" __declspec(dllexport) +BOOL +RemoveBlockSaveAsProcessId(ULONG processId); + +extern "C" __declspec(dllexport) +BOOL +RegisterIoRequest(ULONG RequestRegistration); + +extern "C" __declspec(dllexport) +BOOL +GetFileHandleInFilter(WCHAR* FileName,ULONG DesiredAccess,HANDLE* FileHandle); + +extern "C" __declspec(dllexport) +BOOL +CloseFileHandleInFilter(HANDLE hFile); + +extern "C" __declspec(dllexport) +BOOL +IsDriverServiceRunning(); + +extern "C" __declspec(dllexport) +BOOL +OpenStubFile( + LPCTSTR fileName, + DWORD dwDesiredAccess, + DWORD dwShareMode, + PHANDLE pHandle ); + +extern "C" __declspec(dllexport) +BOOL +CreateFileAPI( + LPCTSTR fileName, + DWORD dwDesiredAccess, + DWORD dwShareMode, + DWORD dwCreationDisposition, + DWORD dwFlagsAndAttributes, + PHANDLE pHandle ); + +extern "C" __declspec(dllexport) +BOOL +CreateStubFile( + LPCTSTR fileName, + LONGLONG fileSize, + ULONG fileAttributes, + ULONG tagDataLength, + BYTE* tagData, + BOOL overwriteIfExist, + PHANDLE pHandle ); + +extern "C" __declspec(dllexport) +BOOL +GetTagData( + HANDLE hFile, + PULONG tagDataLength, + BYTE* tagData); + +extern "C" __declspec(dllexport) +BOOL +RemoveTagData( + HANDLE hFile , + BOOLEAN updateTimeStamp = FALSE); + +extern "C" __declspec(dllexport) +BOOL +AddTagData( + HANDLE hFile, + ULONG tagDataLength, + BYTE* tagData ); + +extern "C" __declspec(dllexport) +BOOL +AddReparseTagData( + LPCTSTR fileName, + ULONG tagDataLength, + BYTE* tagData ); + +extern "C" __declspec(dllexport) +BOOL +QueryAllocatedRanges( + IN HANDLE hFile, + IN LONGLONG queryOffset, + IN LONGLONG queryLength, + IN OUT PFILE_ALLOCATED_RANGE_BUFFER allocatedBuffer, + IN ULONG allocatedBufferSize, + OUT ULONG *returnBufferLength ); + +extern "C" __declspec(dllexport) +BOOL +SetFileSize( + HANDLE hFile, + LONGLONG fileSize); + +extern "C" __declspec(dllexport) +BOOL +AESEncryptFile( + LPCTSTR fileName, + ULONG keyLength, + BYTE* key, + ULONG ivLength = 0, + BYTE* iv = NULL, + BOOLEAN addAESData = TRUE); + +extern "C" __declspec(dllexport) +BOOL +AESDecryptFile( + LPCTSTR fileName, + ULONG keyLength, + BYTE* key, + ULONG ivLength = 0, + BYTE* iv = NULL); + +extern "C" __declspec(dllexport) +BOOL +AESEncryptFileToFileWithTag( + LPCTSTR sourceFileName, + LPCTSTR destFileName, + ULONG keyLength, + BYTE* key, + ULONG ivLength, + BYTE* iv, + ULONG tagDataLength, + BYTE* tagData ); + +extern "C" __declspec(dllexport) +BOOL +AESEncryptFileWithTag( + LPCTSTR fileName, + ULONG keyLength, + BYTE* key, + ULONG ivLength, + BYTE* iv, + ULONG tagDataLength, + BYTE* tagData ); + +extern "C" __declspec(dllexport) +BOOL +AESEncryptFileToFile( + LPCTSTR sourceFileName, + LPCTSTR destFileName, + ULONG keyLength, + BYTE* key, + ULONG ivLength, + BYTE* iv, + BOOLEAN addAESData ); + +extern "C" __declspec(dllexport) +BOOL +AESDecryptFileWithKey( + LPCTSTR fileName, + ULONG keyLength, + BYTE* key ); + +extern "C" __declspec(dllexport) +BOOL +AESDecryptFileToFile( + LPCTSTR sourceFileName, + LPCTSTR destFileName, + ULONG keyLength, + BYTE* key, + ULONG ivLength = 0, + BYTE* iv = NULL); + +extern "C" __declspec(dllexport) +BOOL +AESEncryptDecryptBuffer( + BYTE* inputBuffer, + BYTE* outputBuffer, + ULONG bufferLength, + LONGLONG offset, + BYTE* key, + ULONG keyLength, + BYTE* ivKey, + ULONG ivLength); + +extern "C" __declspec(dllexport) +ULONG +GetComputerId(); + +extern "C" __declspec(dllexport) +BOOL +ActivateLicense( + BYTE* buffer, + ULONG bufferLength); + + +/// +/// Add registry access control filter entry with process name filter mask, user name filter mask and registry +/// key filter mask +/// +/// The length of the process name string in bytes +/// The process name to be filtered, all processes if it is '*' +/// set the processId if you want to filter by id instead of the process name +/// the user name length if you want to filter the user name +/// the user name filter mask +/// set the registry key name filter if you want to filter by the key name +/// the registry key name filter mask +/// The access control flag to the registry +/// The registered callback registry access class +/// Skip all the registry access from this process filter mask if it is true. +extern "C" __declspec(dllexport) +BOOL +AddRegistryFilterRule( + ULONG processNameLength, + WCHAR* processName, + ULONG processId, + ULONG userNameLength, + WCHAR* userName, + ULONG keyNameLength, + WCHAR* keyName, + ULONG accessFlag, + ULONGLONG regCallbackClass, + BOOL isExcludeFilter, + ULONG filterRuleId); + +/// +/// Add registry access control filter entry with process name, if process name filter mask matches the proces, +/// it will set the access flag to the process. +/// +/// The length of the process name string in bytes +/// The process name to be filtered, all processes if it is '*' +/// The access control flag to the registry +/// The registered callback registry access class +/// Skip all the registry access from this process filter mask if it is true. +extern "C" __declspec(dllexport) +BOOL +AddRegistryFilterRuleByProcessName( + ULONG processNameLength, + WCHAR* processName, + ULONG accessFlag, + ULONGLONG regCallbackClass, + BOOL isExcludeFilter ); + +extern "C" __declspec(dllexport) +BOOL +AddRegistryFilterRuleByProcessId( + ULONG processId, + ULONG accessFlag, + ULONGLONG regCallbackClass, + BOOL isExcludeFilter ); + +extern "C" __declspec(dllexport) +BOOL +RemoveRegistryFilterRuleByProcessId( + ULONG processId ); + +extern "C" __declspec(dllexport) +BOOL +RemoveRegistryFilterRuleByProcessName( + ULONG processNameLength, + WCHAR* processName ); + +/// +/// Add the process filter entry,get notification of new process/thread creation or termination. +/// prevent the unauthorized excutable binaries from running. +/// +/// the process name mask length +/// the process name mask, i.e. c:\myfolder\*.exe +/// the control flag of the process +extern "C" __declspec(dllexport) +BOOL +AddProcessFilterRule( + ULONG processNameMaskLength, + WCHAR* processNameMask, + ULONG controlFlag, + ULONG filterRuleId = 0 ); + +extern "C" __declspec(dllexport) +BOOL +RemoveProcessFilterRule( + ULONG processNameMaskLength, + WCHAR* processNameMask ); + +/// +/// Add the file control access rights to the process +/// +/// the length of the process name filter mask +/// the process name filter mask +/// the length of the file name filter mask +/// the file name filter mask +/// set the file access control flag if the control filter is enabled +extern "C" __declspec(dllexport) +BOOL +AddFileControlToProcessByName( + ULONG processNameMaskLength, + WCHAR* processNameMask, + ULONG fileNameMaskLength, + WCHAR* fileNameMask, + ULONG AccessFlag ); + +/// +/// register the file callback IO for the process with the filter option. +/// +/// the length of the process name filter mask +/// the process name filter mask +/// the length of the file name filter mask +/// the file name filter mask +/// register the monitor IO callback if the monitor filter driver is enabled +/// register the control IO callback if the control filter driver is enabled +/// if it is not 0, callback when file opens with this DesiredAccess +/// if it is not 0, callback when file opens with this Disposition +/// if it is not 0, callback when file opens with this CreateOptions +extern "C" __declspec(dllexport) +BOOL +AddFileCallbackIOToProcessByName( + ULONG processNameMaskLength, + WCHAR* processNameMask, + ULONG fileNameMaskLength, + WCHAR* fileNameMask, + ULONG monitorIOs, + ULONG controlIOs, + ULONG filterByDesiredAccess, + ULONG filterByDisposition, + ULONG filterByCreateOptions); + +extern "C" __declspec(dllexport) +BOOL +RemoveFileControlFromProcessByName( + ULONG processNameMaskLength, + WCHAR* processNameMask, + ULONG fileNameMaskLength, + WCHAR* fileNameMask); + +/// +/// This is the API to add the file access rights of the specific files to the specific processes by process Id +/// This feature requires the control filter was enabled +/// +/// the process Id it will be filtered +/// the length of the file name filter mask +/// the file name filter mask +/// the file access control flag +extern "C" __declspec(dllexport) +BOOL +AddFileControlToProcessById( + ULONG processId, + ULONG fileNameMaskLength, + WCHAR* fileNameMask, + ULONG AccessFlag ); + +extern "C" __declspec(dllexport) +BOOL +RemoveFileControlFromProcessById( + ULONG processId, + ULONG fileNameMaskLength, + WCHAR* fileNameMask); + +extern "C" __declspec(dllexport) +BOOL +SetAESVersion(ULONG version); + +extern "C" __declspec(dllexport) +BOOL +SetAESHeaderSize(ULONG headerSize); + +extern "C" __declspec(dllexport) +BOOL +EnableReparsePointTagEncryption(); + +extern "C" __declspec(dllexport) +BOOL +AddAESHeader( + LPCTSTR fileName, + ULONG headerSize, + BYTE* header); + +extern "C" __declspec(dllexport) +BOOL +GetAESHeader( + LPCTSTR fileName, + PULONG headerSize, + BYTE* header); + +extern "C" __declspec(dllexport) +BOOL +SetHeaderFlags( + LPCTSTR fileName, + ULONG aesFlags, + ULONG accessFlags ); + +extern "C" __declspec(dllexport) +BOOL +GetAESTagData( + LPCTSTR fileName, + PULONG tagDataSize, + BYTE* tagData); + +extern "C" __declspec(dllexport) +BOOL +GetAESIV( + LPCTSTR fileName, + PULONG ivSize, + BYTE* ivBuffer); + +extern "C" __declspec(dllexport) +BOOL +AddExcludeProcessNameToRegistryFilterRule(WCHAR * processNameFilterMask, WCHAR * registryKeyNameFilterMask, WCHAR * excludeProcessNameFilterMask); + +extern "C" __declspec(dllexport) +BOOL +AddExcludeUserNameToRegistryFilterRule(WCHAR * processNameFilterMask, WCHAR * registryKeyNameFilterMask, WCHAR * excludeUserName); + +extern "C" __declspec(dllexport) +BOOL +AddExcludeKeyNameToRegistryFilterRule(WCHAR * processNameFilterMask, WCHAR * registryKeyNameFilterMask, WCHAR * excludeKeyName); + + +extern "C" __declspec(dllexport) +BOOL +AddExcludeProcessNameToProcessFilterRule(WCHAR * processNameFilterMask, WCHAR * processName); + +extern "C" __declspec(dllexport) +BOOL +AddExcludeUserNameToProcessFilterRule(WCHAR * processNameFilterMask, WCHAR * userName); + +#endif//__SHARE_TYPE_H__ diff --git a/Demo_Source_Code/CPlusPlusDemo/FilterControl.cpp b/Demo_Source_Code/CPlusPlusDemo/FilterControl.cpp new file mode 100644 index 0000000..0679281 --- /dev/null +++ b/Demo_Source_Code/CPlusPlusDemo/FilterControl.cpp @@ -0,0 +1,624 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "Tools.h" + +#include "FilterAPI.h" +#include "EncryptionHandler.h" +#include "FileControlHandler.h" +#include "FilterRule.h" +#include "FileMonitorHandler.h" +#include "ProcessFilterHandler.h" +#include "RegistryFilterHandler.h" +#include "FilterControl.h" + +FilterControl* FilterControl::instance = NULL; + + +BOOL +FilterControl::StartFilter(int _filterType, int _filterConnectionThreads, int _connectionTimeout, CHAR* _licenseKey) +{ + BOOL retVal = false; + + filterType = _filterType; + filterConnectionThreads = _filterConnectionThreads; + connectionTimeout = _connectionTimeout; + licenseKey.assign(_licenseKey); + + if(isFilterStarted) + { + return true; + } + + if (!IsDriverServiceRunning()) + { + if(!InstallDriver()) + { + PrintLastErrorMessage(L"Installed driver failed."); + return false; + } + } + + if(!SetRegistrationKey(&*licenseKey.begin())) + { + PrintLastErrorMessage( L"SetRegistrationKey failed."); + return false; + } + + if(!RegisterMessageCallback(filterConnectionThreads,MessageCallback,DisconnectCallback)) + { + PrintLastErrorMessage( L"RegisterMessageCallback failed."); + return false; + } + + if(!SetConnectionTimeout(connectionTimeout)) + { + PrintLastErrorMessage( L"SetConnectionTimeout failed."); + return false; + } + + if(!SetFilterType(filterType)) + { + PrintLastErrorMessage( L"SetFilterType failed."); + return false; + } + + isFilterStarted = true; + + SendConfigSettingsToFilter(); + + return true; +} + +/// +/// Stop the filter driver service. +/// +void FilterControl::StopFilter() +{ + if (isFilterStarted) + { + printf("Stop Filter Service.\n"); + Disconnect(); + isFilterStarted = false; + } + + return; +} + +BOOL +FilterControl::ClearConfigData() +{ + if (!ResetConfigData()) + { + PrintLastErrorMessage(L"ResetConfigData failed."); + return false; + } + + return true; +} + + +BOOL +FilterControl::SendFileFilterRuleToFilter(FileFilterRule* fileFilter) +{ + //add filter rule to filter driver here, the filter rule is unique with the include file filter mask. + //you can't have the mutiple filter rules with the same file filter mask,if there are the same + //one exist, the new one with accessFlag will overwrite the old accessFlag. + //for control filter, if isResident is true, the access control will be enabled in boot time. + if (!AddFileFilterRule(fileFilter->AccessFlag, &fileFilter->FileFilterMask[0], fileFilter->IsResident, fileFilter->FilterRuleId)) + { + PrintLastErrorMessage(L"Send file filter rule failed."); + return false; + } + + if (fileFilter->FileChangeEventFilter > 0 && !RegisterFileChangedEventsToFilterRule(&fileFilter->FileFilterMask[0], fileFilter->FileChangeEventFilter)) + { + PrintLastErrorMessage(L"Register file change event failed."); + return false; + } + + if (fileFilter->MonitorFileIOEventFilter > 0 && !RegisterMonitorIOToFilterRule(&fileFilter->FileFilterMask[0], fileFilter->MonitorFileIOEventFilter)) + { + PrintLastErrorMessage(L"Register monitor IO event failed."); + return false; + } + + if (fileFilter->ControlFileIOEventFilter > 0 && !RegisterControlIOToFilterRule(&fileFilter->FileFilterMask[0], fileFilter->ControlFileIOEventFilter)) + { + PrintLastErrorMessage(L"Register control IO event failed."); + return false; + } + + if (fileFilter->FilterDesiredAccess > 0 || fileFilter->FilterDisposition > 0 || fileFilter->FilterCreateOptions > 0) + { + if (!AddCreateFilterToFilterRule(&fileFilter->FileFilterMask[0], fileFilter->FilterDesiredAccess, fileFilter->FilterDisposition, fileFilter->FilterCreateOptions)) + { + PrintLastErrorMessage(L"AddCreateFilterToFilterRule failed."); + return false; + } + } + + //every filter rule can have multiple exclude file filter masks, you can exclude the files + //which matches the exclude filter mask. + for(std::vector::iterator excludeFilterMask = fileFilter->ExcludeFileFilterMaskList.begin(); + excludeFilterMask != fileFilter->ExcludeFileFilterMaskList.end(); ++excludeFilterMask) + { + if (excludeFilterMask->length() > 0 ) + { + if (!AddExcludeFileMaskToFilterRule(&fileFilter->FileFilterMask[0], &(*excludeFilterMask)[0])) + { + PrintLastErrorMessage(L"AddExcludeFileMaskToFilterRule failed."); + return false; + } + } + } + + //only the I/O from the included processes can be managed by this filter rule, all other processes will pass through. + for(std::vector::iterator includeProcessName = fileFilter->IncludeProcessNameList.begin(); + includeProcessName != fileFilter->IncludeProcessNameList.end(); ++includeProcessName) + { + if (includeProcessName->length() > 0) + { + if (!AddIncludeProcessNameToFilterRule(&fileFilter->FileFilterMask[0], &(*includeProcessName)[0])) + { + PrintLastErrorMessage(L"AddIncludeProcessNameToFilterRule failed."); + return false; + } + } + } + + //all the I/O from the excluded processes will pass through, won't be intercepted by filter driver. + for(std::vector::iterator excludeProcessName = fileFilter->ExcludeProcessNameList.begin(); + excludeProcessName != fileFilter->ExcludeProcessNameList.end(); ++excludeProcessName) + { + if (excludeProcessName->length() > 0) + { + if (!AddExcludeProcessNameToFilterRule(&fileFilter->FileFilterMask[0], &(*excludeProcessName)[0])) + { + PrintLastErrorMessage(L"AddExcludeProcessNameToFilterRule failed."); + return false; + } + } + } + + //only the I/O from the included processes can be managed by this filter rule, all other processes will pass through. + for(std::vector::iterator includeProcessId = fileFilter->IncludeProcessIdList.begin(); + includeProcessId != fileFilter->IncludeProcessIdList.end(); ++includeProcessId) + { + if (!AddIncludeProcessIdToFilterRule(&fileFilter->FileFilterMask[0], *includeProcessId)) + { + PrintLastErrorMessage(L"AddIncludeProcessIdToFilterRule failed."); + return false; + } + } + + //all the I/O from the excluded processes will pass through, won't be intercepted by filter driver. + for(std::vector::iterator excludeProcessId = fileFilter->ExcludeProcessIdList.begin(); + excludeProcessId != fileFilter->ExcludeProcessIdList.end(); ++excludeProcessId) + { + if (!AddExcludeProcessIdToFilterRule(&fileFilter->FileFilterMask[0], *excludeProcessId)) + { + PrintLastErrorMessage(L"AddExcludeProcessIdToFilterRule failed."); + return false; + } + } + + //only the I/O from the included users can be managed by this filter rule, all other users will pass through. + for(std::vector::iterator includeUserName = fileFilter->IncludeUserNameList.begin(); + includeUserName != fileFilter->IncludeUserNameList.end(); ++includeUserName) + { + if (includeUserName->length() > 0) + { + if (!AddIncludeUserNameToFilterRule(&fileFilter->FileFilterMask[0], &(*includeUserName)[0])) + { + PrintLastErrorMessage(L"AddIncludeUserNameToFilterRule failed."); + return false; + } + } + } + + //all the I/O from the excluded user will pass through, won't be intercepted by filter driver. + for(std::vector::iterator excludeUserName = fileFilter->ExcludeUserNameList.begin(); + excludeUserName != fileFilter->ExcludeUserNameList.end(); ++excludeUserName) + { + if (excludeUserName->length() > 0) + { + if (!AddExcludeUserNameToFilterRule(&fileFilter->FileFilterMask[0], &(*excludeUserName)[0])) + { + PrintLastErrorMessage(L"AddExcludeUserNameToFilterRule failed."); + return false; + } + } + } + + //set the access rights to the specific user, you can add or remove the user access rights here. + std::map::iterator it = fileFilter->UserNameAccessRightList.begin(); + while (it != fileFilter->UserNameAccessRightList.end()) + { + std::wstring userName = it->first; + ULONG accessFlag = it->second; + + if (!AddUserRightsToFilterRule(&fileFilter->FileFilterMask[0], &userName[0], accessFlag)) + { + PrintLastErrorMessage(L"AddUserRightsToFilterRule failed."); + return false; + } + + ++it; + } + + //set the access rights to the specific process, you can add or remove the process access rights here. + it = fileFilter->ProcessNameAccessRightList.begin(); + while (it != fileFilter->ProcessNameAccessRightList.end()) + { + std::wstring processName = it->first; + ULONG accessFlag = it->second; + + if (!AddProcessRightsToFilterRule(&fileFilter->FileFilterMask[0],&processName[0], accessFlag)) + { + PrintLastErrorMessage(L"AddProcessRightsToFilterRule failed."); + return false; + } + + ++it; + } + + //set the access rights to the specific process, you can add or remove the process access rights here. + std::map::iterator pidRights = fileFilter->ProcessIdAccessRightList.begin(); + while (pidRights != fileFilter->ProcessIdAccessRightList.end()) + { + ULONG pid = pidRights->first; + ULONG accessFlag = pidRights->second; + + if (!AddProcessIdRightsToFilterRule(&fileFilter->FileFilterMask[0],pid, accessFlag)) + { + PrintLastErrorMessage(L"AddProcessRightsToFilterRule failed."); + return false; + } + + ++pidRights; + } + + //Hide the files which match the hidden file filter masks when the user browse the managed directory. + if (fileFilter->IsHiddenFileEnabled()) + { + for(std::vector::iterator hiddenFilterMask = fileFilter->HiddenFileFilterMaskList.begin(); + hiddenFilterMask != fileFilter->HiddenFileFilterMaskList.end(); ++hiddenFilterMask) + if (hiddenFilterMask->length() > 0) + { + if (!AddHiddenFileMaskToFilterRule(&fileFilter->FileFilterMask[0], &(*hiddenFilterMask)[0])) + { + PrintLastErrorMessage(L"AddHiddenFileMaskToFilterRule failed."); + return false; + } + } + } + + //reparse the file open to another file with the filter mask. + //For example: + //FilterMask = c:\test\*txt + //ReparseFilterMask = d:\reparse\*doc + //If you open file c:\test\MyTest.txt, it will reparse to the file d:\reparse\MyTest.doc. + if (fileFilter->IsReparseFileEnabled()) + { + if (!AddReparseFileMaskToFilterRule(&fileFilter->FileFilterMask[0], &fileFilter->ReparseFileFilterMask[0])) + { + PrintLastErrorMessage(L"AddReparseFileMaskToFilterRule failed."); + return false; + } + + } + + if (fileFilter->IsEncryptionEnabled()) + { + if ( fileFilter->EncryptionKey.size() > 0) + { + if (!AddEncryptionKeyToFilterRule(&fileFilter->FileFilterMask[0],(ULONG)fileFilter->EncryptionKey.size(), &fileFilter->EncryptionKey[0])) + { + PrintLastErrorMessage(L"AddEncryptionKeyToFilterRule failed."); + return false; + } + } + else + { + printf("Encryption key is not set, it will get the encryption key from callback function all the time.\n"); + + //if you didn't set the master encryption key, then require the encryption key from callback function all the time. + fileFilter->BooleanConfig |= REQUEST_ENCRYPT_KEY_IV_AND_TAGDATA_FROM_SERVICE; + } + } + + if (fileFilter->BooleanConfig > 0 && !AddBooleanConfigToFilterRule(&fileFilter->FileFilterMask[0], fileFilter->BooleanConfig)) + { + PrintLastErrorMessage(L"AddBooleanConfigToFilterRule failed."); + return false; + } + + return true; + +} + +BOOL +FilterControl::SendProcessFilterRuleToFilter(ProcessFilterRule* processFilter) +{ + if (processFilter->ProcessNameFilterMask.length() > 0) + { + //set the process control flag for the process filter mask. + if (!AddProcessFilterRule((ULONG)processFilter->ProcessNameFilterMask.length() * 2, &processFilter->ProcessNameFilterMask[0], processFilter->ControlFlag, processFilter->FilterRuleId)) + { + PrintLastErrorMessage(L"AddProcessFilterRule failed."); + return false; + } + + //set the file access rights of the file filter mask to the process + std::map::iterator it = processFilter->FileAccessList.begin(); + while (it != processFilter->FileAccessList.end()) + { + std::wstring fileFilterMask = it->first; + ULONG accessFlag = it->second; + + if(!AddFileControlToProcessByName((ULONG)processFilter->ProcessNameFilterMask.length() * 2, &processFilter->ProcessNameFilterMask[0], + (ULONG)(fileFilterMask.length()) * 2, &(fileFilterMask[0]), accessFlag)) + { + PrintLastErrorMessage(L"AddProcessRightsToFilterRule failed."); + return false; + } + + ++it; + } + + for (std::vector::iterator excludeProcessName = processFilter->ExcludeProcessNameList.begin(); + excludeProcessName != processFilter->ExcludeProcessNameList.end(); ++excludeProcessName) + { + if (excludeProcessName->length() > 0) + { + if (!AddExcludeProcessNameToProcessFilterRule(&processFilter->ProcessNameFilterMask[0], &(*excludeProcessName)[0])) + { + PrintLastErrorMessage(L"AddExcludeProcessNameToProcessFilterRule failed."); + return false; + } + } + } + + + for (std::vector::iterator excludeUserName = processFilter->ExcludeUserNameList.begin(); + excludeUserName != processFilter->ExcludeUserNameList.end(); ++excludeUserName) + { + if (excludeUserName->length() > 0) + { + if (!AddExcludeUserNameToProcessFilterRule(&processFilter->ProcessNameFilterMask[0], &(*excludeUserName)[0])) + { + PrintLastErrorMessage(L"AddExcludeUserNameToProcessFilterRule failed."); + return false; + } + } + } + + } + + return true; +} + +BOOL +FilterControl::SendRegistryFilterRuleToFilter(RegistryFilterRule* registryFilter) +{ + if (!AddRegistryFilterRule((ULONG)registryFilter->ProcessNameFilterMask.length() * 2, ®istryFilter->ProcessNameFilterMask[0], registryFilter->ProcessId, + (ULONG)registryFilter->UserName.length() * 2, ®istryFilter->UserName[0], (ULONG)registryFilter->RegistryKeyNameFilterMask.length() * 2, ®istryFilter->RegistryKeyNameFilterMask[0], + registryFilter->ControlFlag, registryFilter->RegCallbackClass,registryFilter->IsExcludeFilter, registryFilter->FilterRuleId)) + { + PrintLastErrorMessage(L"AddRegistryFilterRule failed."); + return false; + } + + for (std::vector::iterator excludeProcessName = registryFilter->ExcludeProcessNameList.begin(); + excludeProcessName != registryFilter->ExcludeProcessNameList.end(); ++excludeProcessName) + { + if (excludeProcessName->length() > 0) + { + if (!AddExcludeProcessNameToRegistryFilterRule(®istryFilter->ProcessNameFilterMask[0], ®istryFilter->RegistryKeyNameFilterMask[0], &(*excludeProcessName)[0])) + { + PrintLastErrorMessage(L"AddExcludeProcessNameToProcessFilterRule failed."); + return false; + } + } + } + + + for (std::vector::iterator excludeUserName = registryFilter->ExcludeUserNameList.begin(); + excludeUserName != registryFilter->ExcludeUserNameList.end(); ++excludeUserName) + { + if (excludeUserName->length() > 0) + { + if (!AddExcludeUserNameToRegistryFilterRule(®istryFilter->ProcessNameFilterMask[0], ®istryFilter->RegistryKeyNameFilterMask[0], &(*excludeUserName)[0])) + { + PrintLastErrorMessage(L"AddExcludeUserNameToProcessFilterRule failed."); + return false; + } + } + } + + for (std::vector::iterator excludeKeyName = registryFilter->ExcludeKeyNameList.begin(); + excludeKeyName != registryFilter->ExcludeKeyNameList.end(); ++excludeKeyName) + { + if (excludeKeyName->length() > 0) + { + if (!AddExcludeKeyNameToRegistryFilterRule(®istryFilter->ProcessNameFilterMask[0], ®istryFilter->RegistryKeyNameFilterMask[0], &(*excludeKeyName)[0])) + { + PrintLastErrorMessage(L"AddExcludeKeyNameToRegistryFilterRule failed."); + return false; + } + } + } + + + return true; +} + +BOOL +FilterControl::SendConfigSettingsToFilter() +{ + if (ProcessFilterRules.size() > 0 || RegistryFilterRules.size() > 0 || FileFilterRules.size() > 0) + { + if (!ResetConfigData()) + { + PrintLastErrorMessage(L"ResetConfigData failed."); + return false; + } + } + + if (!SetConnectionTimeout(connectionTimeout)) + { + PrintLastErrorMessage(L"SetConnectionTimeout failed."); + return false; + } + + if (!SetFilterType(filterType)) + { + PrintLastErrorMessage(L"SetFilterType failed."); + return false; + } + + if (globalBooleanConfig > 0 && !SetBooleanConfig(globalBooleanConfig)) + { + PrintLastErrorMessage(L"SetBooleanConfig failed."); + return false; + } + + if (VolumeControlSettings > 0 && !SetVolumeControlFlag(VolumeControlSettings)) + { + PrintLastErrorMessage(L"SetVolumeControlFlag failed."); + return false; + } + + for(std::vector::iterator it = ProtectedProcessIdList.begin(); it != ProtectedProcessIdList.end(); ++it) + { + // + //Send process Id to the protected list, to prevent the process from being killed ungratefully. + // + if (!AddProtectedProcessId(*it)) + { + PrintLastErrorMessage(L"AddProtectedProcessId failed."); + return false; + } + } + + // + //Send process filter rules to filter driver. + // + for(int i = 0; i < ProcessFilterRules.size(); i++) + { + SendProcessFilterRuleToFilter(&ProcessFilterRules[i]); + } + + // + //Send registry filter rules to filter driver. + // + for(int i = 0; i < RegistryFilterRules.size(); i++) + { + SendRegistryFilterRuleToFilter(&RegistryFilterRules[i]); + } + + // + //Send file filter rules to filter driver. + // + for(int i = 0; i < FileFilterRules.size(); i++) + { + SendFileFilterRuleToFilter(&FileFilterRules[i]); + } + + return true; +} + +VOID +SendNotification(PMESSAGE_SEND_DATA messageSend) +{ + if (messageSend->FilterCommand == FILTER_SEND_REG_CALLBACK_INFO || messageSend->FilterCommand == FILTER_SEND_DENIED_REGISTRY_ACCESS_EVENT) + { + SendRegistryFilterNotification(messageSend); + } + else if( ( messageSend->FilterCommand >= FILTER_SEND_PROCESS_CREATION_INFO && messageSend->FilterCommand <= FILTER_SEND_THREAD_HANDLE_INFO) + || (messageSend->FilterCommand == FILTER_SEND_DENIED_PROCESS_CREATION_EVENT) + || (messageSend->FilterCommand == FILTER_SEND_DENIED_PROCESS_TERMINATED_EVENT) ) + { + SendProcessFilterNotification(messageSend); + } + else + { + SendFileFilterNotification(messageSend); + } +} + +BOOL +FilterControl::MessageCallback( + IN PMESSAGE_SEND_DATA messageSend, + IN OUT PMESSAGE_REPLY_DATA messageReply ) +{ + + BOOL ret = true; + +__try +{ + + if (MESSAGE_SEND_VERIFICATION_NUMBER != messageSend->VerificationNumber) + { + //Received message corrupted.Please check if the MessageSendData structure is correct. + printf("\n\nmessageSend data is corrupted in MessageCallback function.\n\n"); + return false; + } + + if( NULL == messageReply) + { + SendNotification(messageSend); + } + else if(messageSend->FilterCommand == FILTER_SEND_REG_CALLBACK_INFO) + { + ret = RegistryFilterHandler(messageSend,messageReply); + } + else if( messageSend->FilterCommand == FILTER_SEND_PROCESS_CREATION_INFO + || messageSend->FilterCommand == FILTER_SEND_PRE_TERMINATE_PROCESS_INFO) + { + ret = ProcessFilterHandler(messageSend,messageReply); + } + else if( messageSend->FilterCommand == FILTER_REQUEST_ENCRYPTION_IV_AND_KEY + || messageSend->FilterCommand == FILTER_REQUEST_ENCRYPTION_IV_AND_KEY_AND_TAGDATA ) + { + ret = EncryptionHandler(messageSend,messageReply); + } + else + { + ret = FileControlHandler(messageSend,messageReply); + } +} +__except( EXCEPTION_EXECUTE_HANDLER ) +{ + printf("\n\nMessageCallback handler got exception, messageId:%d messageType:0x%I64x FilterCommand:0x%0x fileName:%ws\n\n" + ,messageSend->MessageId, messageSend->MessageType, messageSend->FilterCommand, messageSend->FileName ); + + ret = false; +} + +return ret; + +} + +VOID +FilterControl::DisconnectCallback() +{ + printf("Filter connection was disconnected.\n"); + return; +} diff --git a/Demo_Source_Code/CPlusPlusDemo/FilterControl.h b/Demo_Source_Code/CPlusPlusDemo/FilterControl.h new file mode 100644 index 0000000..51bdd04 --- /dev/null +++ b/Demo_Source_Code/CPlusPlusDemo/FilterControl.h @@ -0,0 +1,1174 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2015 EaseFilter +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef __FILTERCONTROL_H__ +#define __FILTERCONTROL_H__ + +#include "FilterAPI.h" +#include "FilterRule.h" + + +#ifndef FO_REMOTE_ORIGIN +#define FO_REMOTE_ORIGIN 0x01000000 +#endif + + class FileIOEventArgs + { + public: + + /// The Message Id. + ULONG MessageId; + /// The filter rule Id. + ULONG FilterRuleId; + ///This is the IO completion status, either STATUS_SUCCESS if the requested operation was completed successfully + ///or an informational, warning, or error STATUS_XXX value, only effect on post IO. + ULONG IoStatus; + /// the transaction time in UTC of this IO request + LONGLONG TransactionTime; + /// The fileObject is an unique Id for the file I/O from open till the close. + PVOID FileObject; + /// A pointer to the FSRTL_ADVANCED_FCB_HEADER header structure that is contained + /// within a file-system-specific structure,it is unique per file. + PVOID FsContext; + /// The process Id who initiates the IO. + ULONG ProcessId; + /// The process name who initiates the IO. + std::wstring ProcessName; + /// The thread Id who initiates the IO. + ULONG ThreadId; + /// The user name who initiates the IO. + std::wstring UserName; + /// The file name of the file IO. + std::wstring FileName; + /// The file size of the file IO. + LONGLONG FileSize; + /// The creation time in UTC of the file. + LONGLONG CreationTime; + /// The last write time in UTC of the file. + LONGLONG LastWriteTime; + /// The file attributes of the file IO. + ULONG FileAttributes; + /// The file CreateOptions of the file create API. + ULONG CreateOptions; + /// The file DesiredAccess options of the file create API. + ULONG DesiredAccess; + /// The file Disposition options of the file create API. + ULONG Disposition; + /// The ShareAccess for file open, please reference CreateFile windows API. + ULONG ShareAccess; + /// The name of the event which uses this eventargs + std::wstring EventName; + /// The file open was from the network + BOOL IsRemoteAccess; + /// The IP address of the remote computer who is opening the file. + /// This feature is enabled only for Win7 or later OS. + std::wstring RemoteIp; + /// The description of the IO. + std::wstring Description; + /// Change the return status of the IO, it is only for control filter or encryption filter + /// set the status to AccessDenied if you want to block this IO. + ULONG ReturnStatus; + /// Set it to true, if the return data was modified. + BOOL IsDataModified; + + std::wstring hex(uint32_t value) + { + WCHAR str[16]; + WCHAR* p = &str[16]; + do { + p--; + uint32_t digit = value % 16; + value /= 16; + *p = digit >= 10 ? 'a' + (digit - 10) : '0' + digit; + } while (value > 0); + p--; + *p = 'x'; + p--; + *p = '0'; + return std::wstring(p, &str[16] - p); + }; + + FileIOEventArgs(PMESSAGE_SEND_DATA messageSend) + { + if(messageSend->SidLength > 0 ) + { + WCHAR userName[MAX_PATH]; + WCHAR domainName[MAX_PATH]; + + int userNameSize = MAX_PATH; + int domainNameSize = MAX_PATH; + SID_NAME_USE snu; + + + BOOL ret = LookupAccountSid( NULL, + messageSend->Sid, + userName, + (LPDWORD)&userNameSize, + domainName, + (LPDWORD)&domainNameSize, + &snu); + + UserName.assign(domainName); + UserName.append(L"\\"); + UserName.append(userName); + + } + + if( messageSend->ProcessId > 0) + { + WCHAR processName[MAX_PATH]; + if( GetProcessNameByPid(messageSend->ProcessId,processName,MAX_PATH)) + { + ProcessName.assign(processName); + } + else + { + ProcessName.assign(L"UNKNOWN"); + } + } + + FileName.assign(messageSend->FileName); + + FileObject = messageSend->FileObject; + FsContext = messageSend->FsContext; + MessageId = messageSend->MessageId; + FilterRuleId = messageSend->FilterRuleId; + TransactionTime = messageSend->TransactionTime; + CreationTime = messageSend->CreationTime; + LastWriteTime = messageSend->LastWriteTime; + ProcessId = messageSend->ProcessId; + ThreadId = messageSend->ThreadId; + FileSize = messageSend->FileSize; + FileAttributes = messageSend->FileAttributes; + IoStatus = messageSend->Status; + + CreateOptions = messageSend->CreateOptions; + DesiredAccess = messageSend->DesiredAccess; + Disposition = messageSend->Disposition; + ShareAccess = messageSend->ShareAccess; + + IsRemoteAccess = false; + RemoteIp.assign(L""); + if ((messageSend->CreateOptions & FO_REMOTE_ORIGIN ) > 0) + { + //this is the request comes from remote server + IsRemoteAccess = true; + RemoteIp.assign(messageSend->RemoteIP); + } + + } + + }; + + /// + /// The callback parameter information of the file change event. + /// + class FileChangedEventArgs : public FileIOEventArgs + { + public: + /// The new file name of the rename IO + std::wstring newFileName; + /// The event type of the file change event. + ULONG eventType; + + FileChangedEventArgs(PMESSAGE_SEND_DATA messageSend):FileIOEventArgs(messageSend) + { + if ((messageSend->InfoClass & FILE_WAS_CREATED ) > 0) + { + eventType = FILE_WAS_CREATED; + EventName.assign(L"NotifyFileWasCreated;"); + Description.assign(L"The new file was created."); + } + + if ((messageSend->InfoClass & FILE_WAS_WRITTEN ) > 0) + { + eventType |= FILE_WAS_WRITTEN; + EventName.append(L"NotifyFileWasWritten;"); + Description.append(L" the file was written."); + } + + if ((messageSend->InfoClass & FILE_WAS_DELETED ) > 0) + { + eventType |= FILE_WAS_DELETED; + EventName.append(L"NotifyFileWasDeleted;"); + Description.append(L"The file was deleted."); + } + + if ((messageSend->InfoClass & FILE_INFO_CHANGED ) > 0) + { + eventType |= FILE_INFO_CHANGED; + EventName.append(L"NotifyFileInfoWasChanged;"); + Description.append(L"The file information was changed."); + } + + if ((messageSend->InfoClass & FILE_WAS_RENAMED ) > 0) + { + if (messageSend->DataBufferLength > 0) + { + newFileName.assign((WCHAR*)messageSend->DataBuffer); + } + + eventType |= FILE_WAS_RENAMED; + EventName.append(L"NotifyFileWasRenamed;"); + Description += L"The file was renamed to " + newFileName; + } + + if ((messageSend->InfoClass & FILE_WAS_COPIED) > 0) + { + if (messageSend->DataBufferLength > 0) + { + newFileName.assign((WCHAR*)messageSend->DataBuffer); + } + + eventType |= FILE_WAS_COPIED; + EventName.append(L"NotifyFileWasCopied;"); + Description += L"The file was copied from " + newFileName; + } + + if ((messageSend->InfoClass & FILE_SECURITY_CHANGED ) > 0) + { + eventType |= FILE_SECURITY_CHANGED; + EventName.append(L"NotifyFileSecurityWasChanged;"); + Description += L" security was changed."; + } + + if ((messageSend->InfoClass & FILE_WAS_READ ) > 0) + { + eventType |= FILE_WAS_READ; + EventName.append(L"NotifyFileWasRead;"); + Description.append(L"The file was read."); + } + + } + + }; + + class FileCreateEventArgs : public FileIOEventArgs + { + public: + /// + /// The file will be deleted on close when it was true. + /// + BOOL isDeleteOnClose; + /// + /// It indicates that the new file was created if it is true. + /// + BOOL isNewFileCreated ; + /// + /// It indicates that this is file copy source file open. + /// + BOOL isFileCopySource; + /// + /// It indicates that this is file copy dest file open. + /// + BOOL isFileCopyDest; + + FileCreateEventArgs(PMESSAGE_SEND_DATA messageSend) : FileIOEventArgs(messageSend) + { + if ((messageSend->InfoClass & CREATE_FLAG_FILE_SOURCE_OPEN_FOR_COPY) > 0) + { + isFileCopySource = true; + } + + if ((messageSend->InfoClass & CREATE_FLAG_FILE_DEST_OPEN_FOR_COPY) > 0) + { + isFileCopyDest = true; + } + + if ( messageSend->Status == 0 + && POST_CREATE == messageSend->MessageType) + { + if ( messageSend->CreateStatus == FILE_CREATED + || messageSend->CreateStatus == FILE_SUPERSEDED ) + { + Description = L"The new file was created."; + isNewFileCreated = true; + } + else + { + isNewFileCreated = false; + + if( messageSend->CreateStatus == FILE_OPENED ) + { + Description = L"The file was opened."; + } + else if( messageSend->CreateStatus == FILE_OVERWRITTEN ) + { + Description = L"The file was overwritten."; + } + else if( messageSend->CreateStatus == FILE_EXISTS ) + { + Description = L"The file already exists."; + } + else if( messageSend->CreateStatus == FILE_DOES_NOT_EXIST ) + { + Description = L"The file does not exist."; + } + + } + + } + + if ((messageSend->CreateOptions & FILE_DELETE_ON_CLOSE) > 0) + { + isDeleteOnClose = true; + Description += L",The file will be deleted on close."; + } + else + { + isDeleteOnClose = false; + } + + if (isFileCopySource) + { + Description = L"FileCopy source file open." + Description; + } + + if (isFileCopyDest) + { + Description = L"FileCopy dest file open." + Description; + } + + } + }; + + class FileReadEventArgs : public FileIOEventArgs + { + public: + + /// + /// The read offset + /// + LONGLONG offset ; + /// + /// The length of the read + /// + ULONG readLength ; + /// + /// The return length of the read + /// + ULONG returnReadLength ; + /// + /// The read data buffer + /// + std::vector buffer ; + /// + /// The read type + /// + std::wstring readType ; + + FileReadEventArgs(PMESSAGE_SEND_DATA messageSend) : FileIOEventArgs(messageSend) + { + offset = messageSend->Offset; + readLength = messageSend->Length; + returnReadLength = messageSend->ReturnLength; + + if (messageSend->DataBufferLength > 0 && messageSend->DataBufferLength <= sizeof(messageSend->DataBuffer)) + { + /*buffer.resize(messageSend->DataBufferLength); + memcpy(buffer.data(), messageSend->DataBuffer, messageSend->DataBufferLength);*/ + } + + if (messageSend->MessageType == POST_NOCACHE_READ + || messageSend->MessageType == PRE_NOCACHE_READ) + { + readType = L"NonCacheRead"; + } + else if ( messageSend->MessageType == PRE_PAGING_IO_READ + || messageSend->MessageType == POST_PAGING_IO_READ) + { + readType = L"PagingIORead"; + } + else + { + readType = L"CacheRead"; + } + + Description = L"ReadType:" + readType + L",ReadOffset:" + std::to_wstring(offset) + L",ReadLength:" + std::to_wstring((ULONGLONG)readLength) + + L",returnReadLength:" + std::to_wstring((ULONGLONG)returnReadLength); + + if ((messageSend->InfoClass & READ_FLAG_FILE_SOURCE_FOR_COPY) > 0) + { + Description = L"FileCopy source file read." + Description; + } + + } + }; + + class FileWriteEventArgs : public FileIOEventArgs + { + public: + + /// + /// The write offset + /// + LONGLONG offset ; + /// + /// The length of the write + /// + ULONG writeLength ; + /// + /// The length of the written + /// + ULONG writtenLength ; + /// + /// The data buffer length + /// + ULONG bufferLength ; + /// + /// The write data buffer + /// + std::vector buffer ; + /// + /// The read type + /// + std::wstring writeType ; + + FileWriteEventArgs(PMESSAGE_SEND_DATA messageSend) : FileIOEventArgs(messageSend) + { + offset = messageSend->Offset; + writeLength = messageSend->Length; + writtenLength = messageSend->ReturnLength; + bufferLength = messageSend->DataBufferLength; + + if (messageSend->DataBufferLength > 0 && messageSend->DataBufferLength <= sizeof(messageSend->DataBuffer)) + { + /*buffer.resize(messageSend->DataBufferLength); + memcpy(buffer.data(), messageSend->DataBuffer, messageSend->DataBufferLength);*/ + } + + if ( messageSend->MessageType == POST_NOCACHE_READ + || messageSend->MessageType == PRE_NOCACHE_READ) + { + writeType = L"NonCacheWrite"; + } + else if( messageSend->MessageType == PRE_PAGING_IO_READ + || messageSend->MessageType == POST_PAGING_IO_READ) + { + writeType = L"PagingIOWrite"; + } + else + { + writeType = L"CacheWrite"; + } + + Description = L"WriteType:" + writeType + L",WriteOffset:" + std::to_wstring(offset) + L",writeLength:" + std::to_wstring((ULONGLONG)writeLength) + + L",WrittenLength:" + std::to_wstring((ULONGLONG)writtenLength); + + if ((messageSend->InfoClass & WRITE_FLAG_FILE_DEST_FOR_COPY) > 0) + { + Description = L"FileCopy dest file write." + Description; + } + } + }; + + class FileSizeEventArgs : public FileIOEventArgs + { + public: + + /// + /// The size of the file used by FileEndOfFileInformation class + /// + LONGLONG fileSizeToQueryOrSet ; + + FileSizeEventArgs(PMESSAGE_SEND_DATA messageSend) : FileIOEventArgs(messageSend) + { + if (messageSend->DataBufferLength > 0) + { + fileSizeToQueryOrSet = *(LONGLONG*)messageSend->DataBuffer; + } + + Description = L"FileSize:" + std::to_wstring(fileSizeToQueryOrSet); + } + }; + + class FileIdEventArgs : public FileIOEventArgs + { + public: + + /// + /// The file Id used by FileInternalInformation class + /// + LONGLONG fileId ; + + FileIdEventArgs(PMESSAGE_SEND_DATA messageSend) : FileIOEventArgs(messageSend) + { + if (messageSend->DataBufferLength > 0) + { + fileId = *(LONGLONG*)messageSend->DataBuffer; + } + + Description = L"FileId:" + std::to_wstring(fileId); + } + + }; + + class FileBasicInfoEventArgs : public FileIOEventArgs + { + public: + + /// + /// The file basic information + /// + FILE_BASIC_INFORMATION basicInfo ; + + FileBasicInfoEventArgs(PMESSAGE_SEND_DATA messageSend) : FileIOEventArgs(messageSend) + { + if (messageSend->DataBufferLength > 0) + { + basicInfo = *(FILE_BASIC_INFORMATION*)messageSend->DataBuffer; + + Description = L"FileBasicInformation,creation time:" + GetFileTimeStr(basicInfo.CreationTime.QuadPart); + Description += L",last access time:" + GetFileTimeStr(basicInfo.LastAccessTime.QuadPart); + Description += L",last write time:" + GetFileTimeStr(basicInfo.LastWriteTime.QuadPart); + Description += L",file attributes:" + std::to_wstring((ULONGLONG)basicInfo.FileAttributes); + } + + } + }; + + class FileStandardInfoEventArgs : public FileIOEventArgs + { + public: + + /// + /// The file standard information + /// + FILE_STANDARD_INFORMATION standardInfo ; + + FileStandardInfoEventArgs(PMESSAGE_SEND_DATA messageSend) : FileIOEventArgs(messageSend) + { + if (messageSend->DataBufferLength > 0) + { + standardInfo = *(FILE_STANDARD_INFORMATION*)messageSend->DataBuffer; + + Description = L"FileStandardInformation,file size:" + std::to_wstring(standardInfo.EndOfFile.QuadPart); + Description += L",lallocation size:" + std::to_wstring(standardInfo.AllocationSize.QuadPart); + } + } + }; + + class FileNetworkInfoEventArgs : public FileIOEventArgs + { + public: + + /// + /// The file network information + /// + FILE_NETWORK_OPEN_INFORMATION networkInfo ; + + FileNetworkInfoEventArgs(PMESSAGE_SEND_DATA messageSend) : FileIOEventArgs(messageSend) + { + if (messageSend->DataBufferLength > 0) + { + networkInfo = *(FILE_NETWORK_OPEN_INFORMATION*)messageSend->DataBuffer; + + Description = L"FileNetworkOpenInformation,file size:" + std::to_wstring(networkInfo.EndOfFile.QuadPart); + Description += L",file attributes:" + hex((ULONG)networkInfo.FileAttributes); + } + + } + + }; + + class FileMoveOrRenameEventArgs : public FileIOEventArgs + { + public: + /// + /// The new file name of the move or rename IO + /// + std::wstring newFileName; + + FileMoveOrRenameEventArgs(PMESSAGE_SEND_DATA messageSend) : FileIOEventArgs(messageSend) + { + if (messageSend->DataBufferLength > 0) + { + newFileName.assign((WCHAR*)messageSend->DataBuffer); + + if (messageSend->MessageType == PRE_SET_INFORMATION) + { + Description = L"File is going to be renamed to " + newFileName; + } + else if(messageSend->Status == STATUS_SUCCESS ) + { + Description = L"File was renamed to " + newFileName; + } + else + { + Description = L"Rename file to " + newFileName + L" failed, status:" + hex(messageSend->Status); + } + } + } + }; + + class FileDispositionEventArgs : public FileIOEventArgs + { + public: + + FileDispositionEventArgs(PMESSAGE_SEND_DATA messageSend) : FileIOEventArgs(messageSend) + { + if (messageSend->MessageType == PRE_SET_INFORMATION) + { + Description = L"File is going to be deleted"; + } + else if (messageSend->Status == STATUS_SUCCESS) + { + Description = L"File was deleted"; + } + else + { + Description = L"Delete file failed, status:" + hex(messageSend->Status); + } + } + }; + + class FileInfoArgs : public FileIOEventArgs + { + public: + + /// + /// The information class of the IO + /// + ULONG FileInfoClass ; + /// + /// The information data of the file associated to the info class. + /// + std::vector buffer ; + + FileInfoArgs(PMESSAGE_SEND_DATA messageSend) : FileIOEventArgs(messageSend) + { + FileInfoClass = messageSend->InfoClass; + + if (messageSend->DataBufferLength > 0 && messageSend->DataBufferLength <= sizeof(messageSend->DataBuffer)) + { + /*buffer.resize(messageSend->DataBufferLength); + memcpy(buffer.data(), messageSend->DataBuffer, messageSend->DataBufferLength);*/ + } + + Description += L"FileInformationClass:" + std::to_wstring((ULONGLONG)FileInfoClass); + } + }; + + class FileSecurityEventArgs : public FileIOEventArgs + { + public: + + /// + /// The security information to be queried/set + /// + ULONG securityInformation ; + /// + /// The security data of the file associated to the info class. + /// + std::vector buffer ; + + FileSecurityEventArgs(PMESSAGE_SEND_DATA messageSend) : FileIOEventArgs(messageSend) + { + securityInformation = messageSend->InfoClass; + + if (messageSend->DataBufferLength > 0 && messageSend->DataBufferLength <= sizeof(messageSend->DataBuffer)) + { + /*buffer.resize(messageSend->DataBufferLength); + memcpy(buffer.data(), messageSend->DataBuffer, messageSend->DataBufferLength);*/ + } + + Description += L"SecurityInformation:" + std::to_wstring((ULONGLONG)securityInformation); + } + + }; + + class FileQueryDirectoryEventArgs : public FileIOEventArgs + { + public: + + /// + /// The type of information to be returned about files in the directory. + /// + ULONG fileInfomationClass ; + /// + /// The buffer that receives the desired information about the file. + /// The structure of the information returned in the buffer is defined by the FileInformationClass. + /// + std::vector buffer ; + + FileQueryDirectoryEventArgs(PMESSAGE_SEND_DATA messageSend) : FileIOEventArgs(messageSend) + { + fileInfomationClass = messageSend->InfoClass; + + if (messageSend->DataBufferLength > 0 && messageSend->DataBufferLength <= sizeof(messageSend->DataBuffer)) + { + /*buffer.resize(messageSend->DataBufferLength); + memcpy(buffer.data(), messageSend->DataBuffer, messageSend->DataBufferLength);*/ + } + + Description += L"Query directory fileInfomationClass:" + std::to_wstring((ULONGLONG)fileInfomationClass); + } + }; + + class DeniedFileIOEventArgs : public FileIOEventArgs + { + public: + + DeniedFileIOEventArgs(PMESSAGE_SEND_DATA messageSend) : FileIOEventArgs(messageSend) + { + EventName = L"The I/O request " + std::to_wstring(messageSend->MessageType) + L" was blocked."; + + if (messageSend->DataBufferLength > 0 && messageSend->InfoClass == ALLOW_FILE_RENAME) + { + std::wstring newFileName; + newFileName.assign((WCHAR*)messageSend->DataBuffer); + + Description = L"Rename file to " + newFileName + L" was blocked by the setting."; + } + else + { + Description = L"The IO request was blocked with the file access control flag " + std::to_wstring((ULONGLONG)messageSend->InfoClass); + } + } + }; + + class DeniedUSBReadEventArgs : public FileIOEventArgs + { + public: + + DeniedUSBReadEventArgs(PMESSAGE_SEND_DATA messageSend) : FileIOEventArgs(messageSend) + { + EventName = L"BlockUSBRead"; + Description = L"Reading file from USB was blocked by the setting."; + } + }; + + class DeniedUSBWriteEventArgs : public FileIOEventArgs + { + public: + + DeniedUSBWriteEventArgs(PMESSAGE_SEND_DATA messageSend) : FileIOEventArgs(messageSend) + { + EventName = L"BlockUSBWrite"; + + if (messageSend->InfoClass == ALLOW_COPY_PROTECTED_FILES_TO_USB) + { + Description = L"Copy the protected file to USB was blocked by the setting."; + } + else + { + Description = L"Writting the file to USB was blocked by the setting."; + } + } + }; + + + class DeniedProcessTerminatedEventArgs : public FileIOEventArgs + { + public: + DeniedProcessTerminatedEventArgs(PMESSAGE_SEND_DATA messageSend) : FileIOEventArgs(messageSend) + { + EventName = L"DeniedProcessTerminated"; + Description = L"Block killing process ungratefully."; + } + + }; + + class DeniedProcessCreationEventArgs : public FileIOEventArgs + { + public: + DeniedProcessCreationEventArgs(PMESSAGE_SEND_DATA messageSend) : FileIOEventArgs(messageSend) + { + EventName = L"DeniedProcessCreation"; + Description = L"Process creation was denied."; + } + + }; + + class DeniedRegistryAccessEventArgs : public FileIOEventArgs + { + public: + DeniedRegistryAccessEventArgs(PMESSAGE_SEND_DATA messageSend) : FileIOEventArgs(messageSend) + { + EventName = L"DeniedRegistryAccess"; + Description = L"Registry access was denied."; + } + + }; + + class VolumeInfoEventArgs : public FileIOEventArgs + { + public: + + /// + /// the volume name + /// + std::wstring VolumeName; + /// + /// the volume dos name + /// + std::wstring VolumeDosName; + /// + /// the volume file system type. + /// + ULONG VolumeFilesystemType; + /// + /// the Characteristics of the attached device object if existed. + /// + ULONG DeviceCharacteristics; + + VolumeInfoEventArgs(PMESSAGE_SEND_DATA messageSend) : FileIOEventArgs(messageSend) + { + if (messageSend->DataBufferLength > 0) + { + PVOLUME_INFO volumeInfo = (PVOLUME_INFO)messageSend->DataBuffer; + + VolumeName.assign(volumeInfo->VolumeName); + VolumeDosName.assign(volumeInfo->VolumeDosName); + VolumeFilesystemType = volumeInfo->VolumeFilesystemType; + DeviceCharacteristics = volumeInfo->DeviceCharacteristics; + + Description = L"VolumeName" + VolumeName + L",VolumeDosName[" + VolumeDosName; + } + + } + }; + + class ProcessEventArgs : public FileIOEventArgs + { + public: + + /// + ///The process ID of the parent process for the new process. Note that the parent process is not necessarily the same process as the process that created the new process. + /// + ULONG ParentProcessId; + /// + ///The process ID of the process that created the new process. + /// + ULONG CreatingProcessId; + /// + /// The thread ID of the thread that created the new process. + /// + ULONG CreatingThreadId; + /// + ///An ACCESS_MASK value that specifies the access rights to grant for the handle + /// + ULONG DesiredAccess; + /// + ///The type of handle operation. This member might be one of the following values:OB_OPERATION_HANDLE_CREATE,OB_OPERATION_HANDLE_DUPLICATE + /// + ULONG Operation; + /// + /// A Boolean value that specifies whether the ImageFileName member contains the exact file name that is used to open the process executable file. + /// + bool FileOpenNameAvailable; + /// + /// The file name of the executable. If the FileOpenNameAvailable member is TRUE, the string specifies the exact file name that is used to open the executable file. + /// If FileOpenNameAvailable is FALSE, the operating system might provide only a partial name. + /// + std::wstring ImageFileName; + /// + /// The command that is used to execute the process. + /// + std::wstring CommandLine; + + ProcessEventArgs(PMESSAGE_SEND_DATA messageSend) : FileIOEventArgs(messageSend) + { + ImageFileName = messageSend->FileName; + + if (messageSend->DataBufferLength > 0) + { + PROCESS_INFO* processInfo = (PROCESS_INFO*)messageSend->DataBuffer; + + ParentProcessId = processInfo->ParentProcessId; + CreatingProcessId = processInfo->CreatingProcessId; + CreatingThreadId = processInfo->CreatingThreadId; + DesiredAccess = processInfo->DesiredAccess; + Operation = processInfo->Operation; + FileOpenNameAvailable = processInfo->FileOpenNameAvailable > 0; + CommandLine = processInfo->CommandLine; + + switch (messageSend->FilterCommand) + { + case FILTER_SEND_PROCESS_CREATION_INFO: + { + Description = L"New process was created, parentPid:" + std::to_wstring((ULONGLONG)ParentProcessId) + L";CreatingPid:" + std::to_wstring((ULONGLONG)CreatingProcessId) + + L";CreatingTheadId:" + std::to_wstring((ULONGLONG)CreatingThreadId) + L";CommandLine:" + CommandLine; + + break; + } + case FILTER_SEND_PROCESS_TERMINATION_INFO: + { + Description = L"The process was terminated."; + break; + } + case FILTER_SEND_THREAD_CREATION_INFO: + { + Description = L"The new thread was created."; + break; + } + case FILTER_SEND_THREAD_TERMINATION_INFO: + { + Description = L"The thread was terminated."; + break; + } + case FILTER_SEND_PROCESS_HANDLE_INFO: + case FILTER_SEND_THREAD_HANDLE_INFO: + { + if (processInfo->Operation == 1) + { + Description = L"Create Handle"; + } + else + { + Description = L"Duplicate Handle"; + } + + Description += L"; DesiredAccess:" + std::to_wstring((ULONGLONG)processInfo->DesiredAccess); + break; + } + + } + + } + } + + }; + + class RegistryEventArgs : public FileIOEventArgs + { + public: + /// + ///The registry callback class. + /// + ULONGLONG RegCallbackClass; + /// + /// The Key Information class. + /// + ULONG InfoClass; + + RegistryEventArgs(PMESSAGE_SEND_DATA messageSend) : FileIOEventArgs(messageSend) + { + RegCallbackClass = messageSend->MessageType; + InfoClass = messageSend->InfoClass; + + if (messageSend->Status != STATUS_SUCCESS) + { + Description = L"Registry access failed, RegCallbackClass " + hex(RegCallbackClass) + L", status: " + hex(messageSend->Status); + } + else + { + switch (RegCallbackClass) + { + case Reg_Pre_Create_KeyEx: + case Reg_Post_Create_KeyEx: + case Reg_Pre_Open_KeyEx: + case Reg_Post_Open_KeyEx: + { + Description = L"Open registry key."; + break; + } + case Reg_Pre_Delete_Key: + case Reg_Post_Delete_Key: + { + Description = L"registry key is being deleted."; + break; + } + case Reg_Pre_Set_Value_Key: + case Reg_Post_Set_Value_Key: + { + Description = L"Set value key."; + break; + } + case Reg_Pre_Delete_Value_Key: + case Reg_Post_Delete_Value_Key: + { + Description = L"registry key's value is being deleted."; + break; + } + case Reg_Pre_SetInformation_Key: + case Reg_Post_SetInformation_Key: + { + Description = L"SetInformationKey"; + break; + } + case Reg_Pre_Rename_Key: + case Reg_Post_Rename_Key: + { + std::wstring newName((WCHAR*)messageSend->DataBuffer); + Description = L"registry key's name is being changed to " + newName; + break; + } + case Reg_Pre_Enumerate_Key: + case Reg_Post_Enumerate_Key: + { + Description = L"EnumberateKey"; + break; + } + case Reg_Pre_Enumerate_Value_Key: + case Reg_Post_Enumerate_Value_Key: + { + Description = L"EnumberateValueKey"; + break; + } + case Reg_Pre_Query_Key: + case Reg_Post_Query_Key: + { + Description = L"QueryKey"; + break; + } + case Reg_Pre_Query_Value_Key: + case Reg_Post_Query_Value_Key: + { + Description = L"QueryValueKey"; + break; + } + case Reg_Pre_Query_Multiple_Value_Key: + case Reg_Post_Query_Multiple_Value_Key: + { + Description = L"QueryMultipleValueKey"; + break; + } + + case Reg_Pre_Load_Key: + case Reg_Post_Load_Key: + { + Description = L"LoadKey"; + break; + } + case Reg_Pre_Replace_Key: + case Reg_Post_Replace_Key: + { + Description = L"ReplaceKey"; + break; + } + + case Reg_Pre_Query_KeyName: + case Reg_Post_Query_KeyName: + { + Description = L"QueryKeyName"; + break; + } + } + } + + } + + }; + +class FilterControl +{ +private: + + static FilterControl *instance; + + bool isFilterStarted; + int filterType; + int filterConnectionThreads; + int connectionTimeout; + std::string licenseKey; + + static BOOL + __stdcall + MessageCallback( + IN PMESSAGE_SEND_DATA pSendMessage, + IN OUT PMESSAGE_REPLY_DATA pReplyMessage); + + static VOID + __stdcall + DisconnectCallback(); + + +public: + + BOOL + SendConfigSettingsToFilter(); + + /// + /// The global boolean config setting + /// + ULONG globalBooleanConfig; + /// + /// The volume control flag, reference VolumeControlFlag + /// + ULONG VolumeControlSettings; + /// + /// Prevent the protected process from being killed ungratefully. + /// + std::vector ProtectedProcessIdList; + /// + /// The List of the File Filter Rule + /// + std::vector FileFilterRules; + /// + /// The List of the Process Filter Rule + /// + std::vector ProcessFilterRules; + /// + /// The List of the Registry Filter Rule + /// + std::vector RegistryFilterRules; + + // Private constructor so that no objects can be created. + FilterControl() + { + globalBooleanConfig = 0; + VolumeControlSettings = 0; + isFilterStarted = false; + filterType = FILE_SYSTEM_MONITOR; + filterConnectionThreads = 5; + connectionTimeout = 20; + } + + static FilterControl *GetSingleInstance() + { + if (!instance) + { + instance = new FilterControl(); + } + + return instance; + } + + BOOL StartFilter(int _filterType, int _filterConnectionThreads, int _connectionTimeout, CHAR* _licenseKey); + + void StopFilter(); + + BOOL ClearConfigData(); + + void ClearFilterRules() + { + FileFilterRules.clear(); + ProcessFilterRules.clear(); + RegistryFilterRules.clear(); + } + + VOID AddFileFilter(FileFilterRule fileFilterRule) + { + FileFilterRules.push_back(fileFilterRule); + } + + VOID AddProcessFilter(ProcessFilterRule processFilterRule) + { + ProcessFilterRules.push_back(processFilterRule); + } + + VOID AddRegistryFilter(RegistryFilterRule registryFilterRule) + { + RegistryFilterRules.push_back(registryFilterRule); + } + + BOOL + SendProcessFilterRuleToFilter(ProcessFilterRule* processFilter); + + BOOL + SendRegistryFilterRuleToFilter(RegistryFilterRule* registryFilter); + + BOOL + SendFileFilterRuleToFilter(FileFilterRule* fileFilter); + +}; + +#endif \ No newline at end of file diff --git a/Demo_Source_Code/CPlusPlusDemo/FilterMessage.cpp b/Demo_Source_Code/CPlusPlusDemo/FilterMessage.cpp new file mode 100644 index 0000000..ebf0531 --- /dev/null +++ b/Demo_Source_Code/CPlusPlusDemo/FilterMessage.cpp @@ -0,0 +1,108 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "Tools.h" +#include "FilterAPI.h" +#include "FilterMessage.h" + +#define PrintMessage wprintf //ToDebugger + +// +//Here displays the I/O information from filter driver for monitor filter driver and control filter driver +//For every I/O callback data, you always can get this information: +// +//The file related information: file name,file size, file attributes, file time. +//The user information who initiated the I/O: user name, user SID. +//The process information which initiated the I/O: process name, process Id, thread Id. +//The I/O result for post I/O requests: sucess code or the error code. + +VOID +DisplayFileIOMessage(FileIOEventArgs* fileIOEventArgs) +{ + + if( fileIOEventArgs->IoStatus >= STATUS_ERROR ) + { + ChangeColour(FOREGROUND_RED); + } + else if ( fileIOEventArgs->IoStatus >= STATUS_WARNING ) + { + ChangeColour(FOREGROUND_RED|FOREGROUND_GREEN); + } + else + { + ChangeColour(FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE); + } + + PrintMessage( L"\n\nMessageId:%d IOName:%ws, return status:0x%0x\nUserName[%ws], ProcessImagePath:%ws,ProcessId:%d, ThreadId:%d\nFileName:%ws\nFileSize:%I64d, FileAttributes:0x%0x\nDescription:%ws\n", + fileIOEventArgs->MessageId,fileIOEventArgs->EventName.c_str(),fileIOEventArgs->IoStatus,fileIOEventArgs->UserName.c_str(),fileIOEventArgs->ProcessName.c_str(), + fileIOEventArgs->ProcessId,fileIOEventArgs->ThreadId,fileIOEventArgs->FileName.c_str(), fileIOEventArgs->FileSize,fileIOEventArgs->FileAttributes,fileIOEventArgs->Description.c_str()); + + ChangeColour(FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE); + +} + +VOID +DisplayProcessMessage(ProcessEventArgs* processEventArgs) +{ + + if( processEventArgs->IoStatus >= STATUS_ERROR ) + { + ChangeColour(FOREGROUND_RED); + } + else if ( processEventArgs->IoStatus >= STATUS_WARNING ) + { + ChangeColour(FOREGROUND_RED|FOREGROUND_GREEN); + } + else + { + ChangeColour(FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE); + } + + PrintMessage( L"\n\nMessageId:%d IOName:%ws, return status:0x%0x\nUserName[%ws], ProcessImagePath:%ws,ProcessId:%d, ThreadId:%d\nDescription:%ws\n", + processEventArgs->MessageId,processEventArgs->EventName.c_str(),processEventArgs->IoStatus,processEventArgs->UserName.c_str(),processEventArgs->ProcessName.c_str(), + processEventArgs->ProcessId,processEventArgs->ThreadId,processEventArgs->Description.c_str()); + + ChangeColour(FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE); + +} + +VOID +DisplayRegistryMessage(RegistryEventArgs* registryEventArgs) +{ + + if( registryEventArgs->IoStatus >= STATUS_ERROR ) + { + ChangeColour(FOREGROUND_RED); + } + else if ( registryEventArgs->IoStatus >= STATUS_WARNING ) + { + ChangeColour(FOREGROUND_RED|FOREGROUND_GREEN); + } + else + { + ChangeColour(FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE); + } + + PrintMessage( L"\n\nMessageId:%d IOName:%ws, return status:0x%0x\nUserName[%ws], ProcessImagePath:%ws,ProcessId:%d, ThreadId:%d\nKeyName:%ws\nDescription:%ws\n", + registryEventArgs->MessageId,registryEventArgs->EventName.c_str(),registryEventArgs->IoStatus,registryEventArgs->UserName.c_str(),registryEventArgs->ProcessName.c_str(), + registryEventArgs->ProcessId,registryEventArgs->ThreadId,registryEventArgs->FileName.c_str(),registryEventArgs->Description.c_str()); + + ChangeColour(FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE); + +} + diff --git a/Demo_Source_Code/CPlusPlusDemo/FilterMessage.h b/Demo_Source_Code/CPlusPlusDemo/FilterMessage.h new file mode 100644 index 0000000..6b92579 --- /dev/null +++ b/Demo_Source_Code/CPlusPlusDemo/FilterMessage.h @@ -0,0 +1,16 @@ +#pragma once + +#include +#include +#include "FilterControl.h" +#include "WinDataStructures.h" +#include "FilterAPI.h" + +VOID +DisplayFileIOMessage(FileIOEventArgs* fileIOEventArgs); + +VOID +DisplayProcessMessage(ProcessEventArgs* processEventArgs); + +VOID +DisplayRegistryMessage(RegistryEventArgs* registryEventArgs); \ No newline at end of file diff --git a/Demo_Source_Code/CPlusPlusDemo/FilterRule.h b/Demo_Source_Code/CPlusPlusDemo/FilterRule.h new file mode 100644 index 0000000..fb48cb2 --- /dev/null +++ b/Demo_Source_Code/CPlusPlusDemo/FilterRule.h @@ -0,0 +1,486 @@ +#ifndef __FILEFILTER_H__ +#define __FILEFILTER_H__ + +#include "FilterAPI.h" +#include +#include + +static ULONG g_FilterRuleId = 0; + + class ProcessFilterRule + { + public: + + /// + /// the id to identyfy this filter rule. + /// + ULONG FilterRuleId; + /// + /// the process name filter mask, i.e. "notepad.exe","c:\\windows\\*.exe" or "*" + /// + std::wstring ProcessNameFilterMask; + /// + /// The control flag to the processes which match the processNameFilterMask + /// + ULONG ControlFlag; + /// + /// The List of the file access rights of the process. + /// + std::map FileAccessList; + + /// + /// the exclude processs name filter mask list. + /// + std::vector ExcludeProcessNameList; + /// + /// the exclude user name filter mask list. + /// + std::vector ExcludeUserNameList; + + ProcessFilterRule(WCHAR* filterMask) + { + FilterRuleId = ++g_FilterRuleId; + ProcessNameFilterMask.assign(filterMask); + ControlFlag = 0; + } + + void AddFileAccessRightsToProcess(WCHAR* _fileFilterMask, ULONG accessFlag) + { + std::wstring fileFilterMask(_fileFilterMask); + FileAccessList.insert(std::pair(fileFilterMask, accessFlag)); + + return; + } + + bool AddExcludeProcessName(WCHAR* _processName) + { + if (NULL == _processName) + { + return false; + } + + std::wstring processName(_processName); + ExcludeProcessNameList.push_back(processName); + + return true; + } + + bool AddExcludeUserName(WCHAR* _userName) + { + if (NULL == _userName) + { + return false; + } + + std::wstring userName(_userName); + ExcludeUserNameList.push_back(userName); + + return true; + } + + }; + + class RegistryFilterRule + { + public: + /// + /// the id to identyfy this filter rule. + /// + ULONG FilterRuleId; + /// + /// Control the registry access for the process with this process Id. + /// + ULONG ProcessId; + /// + /// Control the registry access for the process with this process name if the process Id is 0, or it will skip it. + /// + std::wstring ProcessNameFilterMask; + /// + /// Control the registry access for the process with this user name + /// + std::wstring UserName; + /// + /// Filter the registry access based on the key name filter mask if it was set + /// + std::wstring RegistryKeyNameFilterMask; + /// + /// The the flag to control how to access the registry for the matched process or user + /// + ULONG ControlFlag; + /// + /// Register the callback when the registry access notification was triggered + /// + ULONGLONG RegCallbackClass; + /// + /// If it is true, the registry access from the matched process or user will be excluded. + /// + BOOL IsExcludeFilter; + /// + /// the exclude processs name filter mask list. + /// + std::vector ExcludeProcessNameList; + /// + /// the exclude user name filter mask list. + /// + std::vector ExcludeUserNameList; + /// + /// the exclude key name filter mask list. + /// + std::vector ExcludeKeyNameList; + + RegistryFilterRule(WCHAR* filterMask) + { + FilterRuleId = ++g_FilterRuleId; + ProcessNameFilterMask.assign(filterMask); + ProcessId = 0; + ControlFlag = 0; + RegCallbackClass = 0; + IsExcludeFilter = FALSE; + } + + bool AddExcludeProcessName(WCHAR* _processName) + { + if (NULL == _processName) + { + return false; + } + + std::wstring processName(_processName); + ExcludeProcessNameList.push_back(processName); + + return true; + } + + bool AddExcludeUserName(WCHAR* _userName) + { + if (NULL == _userName) + { + return false; + } + + std::wstring userName(_userName); + ExcludeUserNameList.push_back(userName); + + return true; + } + + bool AddExcludeKeyName(WCHAR* _keyName) + { + if (NULL == _keyName) + { + return false; + } + + std::wstring keyName(_keyName); + ExcludeUserNameList.push_back(keyName); + + return true; + } + }; + +class FileFilterRule +{ +public: + + /// + /// the id to identyfy this filter rule. + /// + ULONG FilterRuleId; + /// + /// The file filter mask of this filter rule + /// + std::wstring FileFilterMask; + + /// + /// Skip all the file I/Os when the file open doesn't match with below options when they are not 0. + /// Please reference the CreateFile API for below options. + /// + ULONG FilterDesiredAccess; + ULONG FilterDisposition; + ULONG FilterCreateOptions; + + /// + /// if hidden file was enabled, you can add the hidden file filter mask here. + /// + std::vector HiddenFileFilterMaskList; + + /// + /// if reparse file was enabled, you can add reparse file filter mask here. + /// + std::wstring ReparseFileFilterMask; + + /// + /// Filter the file I/Os based on the filename, process name,Id, user name. + /// + std::vector ExcludeFileFilterMaskList; + std::vector IncludeProcessNameList; + std::vector ExcludeProcessNameList; + std::vector IncludeProcessIdList; + std::vector ExcludeProcessIdList; + std::vector IncludeUserNameList; + std::vector ExcludeUserNameList; + + /// + /// Enable the control file filter rule in boot time. + /// + bool IsResident; + + /// + /// the bool config setting of the filter, reference FilterAPI.BooleanConfig + /// + ULONG BooleanConfig; + + ///--------------control filter only properties start-------------------------- + /// + /// register the callback control IO based on the filter setting. + /// + ULONGLONG ControlFileIOEventFilter; + + /// + /// the control flag of the filter + /// reference FilterAPI.AccessFlag enumeration + /// + ULONG AccessFlag; + + /// + /// the access right of the process + /// + std::map ProcessNameAccessRightList; + std::map ProcessIdAccessRightList; + + /// + /// the access right of the users + /// + std::map UserNameAccessRightList; + + ///--------------control filter only properties end-------------------------- + + ///--------------monitor filter only properties start-------------------------- + /// + /// Register the file change event for monitor filter, you will get the notification if the file was changed, + /// register the file events, trigger the notifcation when the events were happened after the file was closed, + /// you can choose the events from FileEventType to register. + /// + /// + ULONG FileChangeEventFilter; + + /// + /// register the monitor notification of the IOs, this is 16 bytes integer, + /// + ULONGLONG MonitorFileIOEventFilter; + /// + /// the maximum buffer size for monitor events if it was enabled. + /// + ULONG MaxEventBufferSize;//50MB + + ///--------------monitor filter only properties end-------------------------- + + /// + /// Encryption filter only property, if the encryption was enabled, this is the encryption key that will be used for the encrypted file. + /// + std::vector EncryptionKey; + + FileFilterRule(WCHAR* filterMask) + { + FilterRuleId = ++g_FilterRuleId; + FileFilterMask.assign(filterMask); + FilterDesiredAccess = 0; + FilterDisposition = 0; + FilterCreateOptions = 0; + IsResident = false; + BooleanConfig = 0; + ControlFileIOEventFilter = 0; + AccessFlag = ALLOW_MAX_RIGHT_ACCESS; + FileChangeEventFilter = 0; + MonitorFileIOEventFilter = 0; + + MaxEventBufferSize = 1024*1024*50;//50MB + + + } + + //to check if the encryption is enabled for this filter rule. + bool IsEncryptionEnabled() + { + if( (AccessFlag & ENABLE_FILE_ENCRYPTION_RULE) > 0 ) + { + return true; + } + else + { + return false; + } + } + + //to check if the reparse file is enabled for this filter rule. + bool IsReparseFileEnabled() + { + if( (AccessFlag & ENABLE_REPARSE_FILE_OPEN) > 0 ) + { + return true; + } + else + { + return false; + } + } + + + //to check if the hidden file is enabled for this filter rule. + bool IsHiddenFileEnabled() + { + if( (AccessFlag & ENABLE_HIDE_FILES_IN_DIRECTORY_BROWSING) > 0 ) + { + return true; + } + else + { + return false; + } + } + + bool AddHiddenFileFilterMask(WCHAR* _hiddenFileFilterMask) + { + if(NULL == _hiddenFileFilterMask) + { + return false; + } + + std::wstring hiddenFileFilterMask(_hiddenFileFilterMask); + HiddenFileFilterMaskList.push_back(hiddenFileFilterMask); + + return true; + } + + bool AddExcludeFileFilterMask(WCHAR* _excludeFileFilterMask) + { + if(NULL == _excludeFileFilterMask) + { + return false; + } + + std::wstring excludeFileFilterMask(_excludeFileFilterMask); + ExcludeFileFilterMaskList.push_back(excludeFileFilterMask); + + return true; + } + + bool AddIncludeProcessName(WCHAR* _processName) + { + if(NULL == _processName) + { + return false; + } + + std::wstring processName(_processName); + IncludeProcessNameList.push_back(processName); + + return true; + } + + bool AddExcludeProcessName(WCHAR* _processName) + { + if(NULL == _processName) + { + return false; + } + + std::wstring processName(_processName); + ExcludeProcessNameList.push_back(processName); + + return true; + } + + void AddIncludeProcessId(ULONG processId) + { + IncludeProcessIdList.push_back(processId); + return ; + } + + void AddExcludeProcessId(ULONG processId) + { + ExcludeProcessIdList.push_back(processId); + return ; + } + + bool AddIncludeUserName(WCHAR* _userName) + { + if(NULL == _userName) + { + return false; + } + + std::wstring userName(_userName); + IncludeUserNameList.push_back(userName); + + return true; + } + + bool AddExcludeUserName(WCHAR* _userName) + { + if(NULL == _userName) + { + return false; + } + + std::wstring userName(_userName); + ExcludeUserNameList.push_back(userName); + + return true; + } + + bool set_EncryptionKey(UCHAR* _encryptionKey,ULONG keyLength) + { + if( NULL == _encryptionKey + || (keyLength != 16 && keyLength != 24 && keyLength != 32)) + { + //this is not valid key. + printf("The key length:%d is invalid, it has to be 16, 24 or 32 bytes\n",keyLength); + return false; + } + + EncryptionKey.clear(); + EncryptionKey.assign(_encryptionKey, _encryptionKey + keyLength); + + return true; + } + + + bool AddAccessRightsToProcessName(WCHAR* _processName, ULONG accessFlag) + { + if( NULL == _processName ) + { + return false; + } + + std::wstring processName(_processName); + ProcessNameAccessRightList.insert(std::pair(processName, accessFlag)); + + return true; + } + + void AddAccessRightsToProcessId(ULONG _processId, ULONG accessFlag) + { + ProcessIdAccessRightList.insert(std::pair(_processId, accessFlag)); + return; + } + + bool AddAccessRightsToUserName(WCHAR* _userName, ULONG accessFlag) + { + if( NULL == _userName ) + { + return false; + } + + std::wstring userName(_userName); + UserNameAccessRightList.insert(std::pair(userName, accessFlag)); + + return true; + } + +}; + + + + +#endif \ No newline at end of file diff --git a/Demo_Source_Code/CPlusPlusDemo/ProcessFilterHandler.h b/Demo_Source_Code/CPlusPlusDemo/ProcessFilterHandler.h new file mode 100644 index 0000000..af68620 --- /dev/null +++ b/Demo_Source_Code/CPlusPlusDemo/ProcessFilterHandler.h @@ -0,0 +1,77 @@ +#ifndef __PROCESSFILTER_H__ +#define __PROCESSFILTER_H__ + +#include "FilterAPI.h" +#include "FilterMessage.h" + +VOID +SendProcessFilterNotification(PMESSAGE_SEND_DATA messageSend) +{ + ProcessEventArgs* processEventArgs = new ProcessEventArgs(messageSend); + if (messageSend->FilterCommand == FILTER_SEND_DENIED_PROCESS_CREATION_EVENT) + { + processEventArgs->EventName = L"ProcessCreationWasBlocked"; + } + else if (messageSend->FilterCommand == FILTER_SEND_DENIED_PROCESS_TERMINATED_EVENT) + { + processEventArgs->EventName = L"ProcessTerminationWasBlocked"; + } + else if (messageSend->FilterCommand == FILTER_SEND_PROCESS_TERMINATION_INFO) + { + processEventArgs->EventName = L"NotifyProcessTerminated"; + } + else if (messageSend->FilterCommand == FILTER_SEND_THREAD_CREATION_INFO) + { + processEventArgs->EventName = L"NotifyThreadCreation"; + } + else if (messageSend->FilterCommand == FILTER_SEND_THREAD_TERMINATION_INFO) + { + processEventArgs->EventName = L"NotifyThreadTerminated"; + } + else if (messageSend->FilterCommand == FILTER_SEND_PROCESS_HANDLE_INFO) + { + processEventArgs->EventName = L"NotifyProcessHandleInfo"; + } + else if (messageSend->FilterCommand == FILTER_SEND_THREAD_HANDLE_INFO) + { + processEventArgs->EventName = L"NotifyThreadHandleInfo"; + } + + DisplayProcessMessage(processEventArgs); + +} + + +BOOL +ProcessFilterHandler( + IN PMESSAGE_SEND_DATA messageSend, + IN OUT PMESSAGE_REPLY_DATA messageReply ) +{ + BOOL retVal = TRUE; + + ProcessEventArgs* processEventArgs = new ProcessEventArgs(messageSend); + + if (messageSend->MessageType == FILTER_SEND_PROCESS_CREATION_INFO) + { + processEventArgs->EventName = L"OnProcessCreation"; + DisplayProcessMessage(processEventArgs); + + //you can block the process creation with below setting. + //messageReply->FilterStatus = FILTER_COMPLETE_PRE_OPERATION; + //messageReply->ReturnStatus = STATUS_ACCESS_DENIED; + } + else if (messageSend->MessageType == FILTER_SEND_PRE_TERMINATE_PROCESS_INFO) + { + processEventArgs->EventName = L"OnProcessPreTermination"; + DisplayProcessMessage(processEventArgs); + + //you can block the process termination with below setting. + //messageReply->FilterStatus = FILTER_COMPLETE_PRE_OPERATION; + //messageReply->ReturnStatus = STATUS_ACCESS_DENIED; + } + + return retVal; +} + + +#endif \ No newline at end of file diff --git a/Demo_Source_Code/CPlusPlusDemo/RegistryFilterHandler.h b/Demo_Source_Code/CPlusPlusDemo/RegistryFilterHandler.h new file mode 100644 index 0000000..118479d --- /dev/null +++ b/Demo_Source_Code/CPlusPlusDemo/RegistryFilterHandler.h @@ -0,0 +1,352 @@ +#ifndef __REGISTRYFILTER_H__ +#define __REGISTRYFILTER_H__ + +#include "FilterAPI.h" +#include "FilterMessage.h" + +VOID +SendRegistryFilterNotification(PMESSAGE_SEND_DATA messageSend) +{ + RegistryEventArgs* registryEventArgs = new RegistryEventArgs(messageSend); + + if (messageSend->FilterCommand == FILTER_SEND_DENIED_REGISTRY_ACCESS_EVENT) + { + registryEventArgs->EventName = L"NotifyRegWasBlocked"; + DisplayRegistryMessage(registryEventArgs); + + return; + } + + switch (registryEventArgs->RegCallbackClass) + { + + case Reg_Post_Delete_Key: + { + registryEventArgs->EventName = L"NotifyDeleteKey"; + break; + } + + case Reg_Post_Set_Value_Key: + { + registryEventArgs->EventName = L"NotifySetValueKey"; + break; + } + + case Reg_Post_Delete_Value_Key: + { + registryEventArgs->EventName = L"NotifyDeleteValueKey"; + + break; + } + + case Reg_Post_SetInformation_Key: + { + registryEventArgs->EventName = L"NotifySetInformationKey"; + break; + } + + case Reg_Post_Rename_Key: + { + registryEventArgs->EventName = L"NotifyRenameKey"; + break; + } + + case Reg_Post_Enumerate_Key: + { + registryEventArgs->EventName = L"NotifyEnumerateKey"; + break; + } + + case Reg_Post_Enumerate_Value_Key: + { + registryEventArgs->EventName = L"NotifyEnumerateValueKey"; + break; + } + + case Reg_Post_Query_Key: + { + registryEventArgs->EventName = L"NotifyQueryKey"; + break; + } + + case Reg_Post_Query_Value_Key: + { + registryEventArgs->EventName = L"NotifyQueryValueKey"; + break; + } + + case Reg_Post_Query_Multiple_Value_Key: + { + registryEventArgs->EventName = L"NotifyQueryMultipleValueKey"; + break; + } + + case Reg_Post_Create_Key: + { + registryEventArgs->EventName = L"NotifyCreateKey"; + break; + } + + case Reg_Post_Open_Key: + { + registryEventArgs->EventName = L"NotifyOpenKey"; + break; + } + + case Reg_Post_Key_Handle_Close: + { + registryEventArgs->EventName = L"NotifyKeyHandleClose"; + break; + } + + case Reg_Post_Create_KeyEx: + { + registryEventArgs->EventName = L"NotifyCreateKeyEx"; + break; + } + + case Reg_Post_Open_KeyEx: + { + registryEventArgs->EventName = L"NotifyOpenKeyEx"; + break; + } + + case Reg_Post_Flush_Key: + { + registryEventArgs->EventName = L"NotifyFlushKey"; + break; + } + + case Reg_Post_Load_Key: + { + registryEventArgs->EventName = L"NotifyLoadKey"; + break; + } + + case Reg_Post_UnLoad_Key: + { + registryEventArgs->EventName = L"NotifyUnLoadKey"; + break; + } + + case Reg_Post_Query_Key_Security: + { + registryEventArgs->EventName = L"NotifyQueryKeySecurity"; + break; + } + + case Reg_Post_Set_Key_Security: + { + registryEventArgs->EventName = L"NotifySetKeySecurity"; + break; + } + + case Reg_Post_Restore_Key: + { + registryEventArgs->EventName = L"NotifyRestoreKey"; + break; + } + + case Reg_Post_Save_Key: + { + registryEventArgs->EventName = L"NotifySaveKey"; + break; + } + + case Reg_Post_Replace_Key: + { + registryEventArgs->EventName = L"NotifyReplaceKey"; + break; + } + + case Reg_Post_Query_KeyName: + { + registryEventArgs->EventName = L"NotifyQueryKeyName"; + break; + } + + default: break; + } + + DisplayRegistryMessage(registryEventArgs); +} + +BOOL +RegistryFilterHandler( + IN PMESSAGE_SEND_DATA messageSend, + IN OUT PMESSAGE_REPLY_DATA messageReply ) +{ + BOOL retVal = FALSE; + + RegistryEventArgs* registryEventArgs = new RegistryEventArgs(messageSend); + + switch (registryEventArgs->RegCallbackClass) + { + case Reg_Pre_Delete_Key: + { + registryEventArgs->EventName = L"OnPreDeleteKey"; + break; + } + + case Reg_Pre_Set_Value_Key: + { + registryEventArgs->EventName = L"OnPreSetValueKey"; + break; + } + + case Reg_Pre_Delete_Value_Key: + { + registryEventArgs->EventName = L"OnPreDeleteValueKey"; + break; + } + + case Reg_Pre_SetInformation_Key: + { + registryEventArgs->EventName = L"OnPreSetInformationKey"; + break; + } + + case Reg_Pre_Rename_Key: + { + registryEventArgs->EventName = L"OnPreRenameKey"; + break; + } + + case Reg_Pre_Enumerate_Key: + { + registryEventArgs->EventName = L"OnPreEnumerateKey"; + break; + } + + case Reg_Pre_Enumerate_Value_Key: + { + registryEventArgs->EventName = L"OnPreEnumerateValueKey"; + break; + } + + case Reg_Pre_Query_Key: + { + registryEventArgs->EventName = L"OnPreQueryKey"; + break; + } + + case Reg_Pre_Query_Value_Key: + { + registryEventArgs->EventName = L"OnPreQueryValueKey"; + break; + } + + case Reg_Pre_Query_Multiple_Value_Key: + { + registryEventArgs->EventName = L"OnPreQueryMultipleValueKey"; + break; + } + + case Reg_Pre_Create_Key: + { + registryEventArgs->EventName = L"OnPreCreateKey"; + break; + } + + case Reg_Pre_Open_Key: + { + registryEventArgs->EventName = L"OnPreOpenKey"; + break; + } + + case Reg_Pre_Key_Handle_Close: + { + registryEventArgs->EventName = L"OnPreKeyHandleClose"; + break; + } + + case Reg_Pre_Create_KeyEx: + { + registryEventArgs->EventName = L"OnPreCreateKeyEx"; + break; + } + + case Reg_Pre_Open_KeyEx: + { + registryEventArgs->EventName = L"OnPreOpenKeyEx"; + break; + } + + case Reg_Pre_Flush_Key: + { + + registryEventArgs->EventName = L"OnPreFlushKey"; + break; + } + + case Reg_Pre_Load_Key: + { + registryEventArgs->EventName = L"OnPreLoadKey"; + break; + } + + case Reg_Pre_UnLoad_Key: + { + registryEventArgs->EventName = L"OnPreUnLoadKey"; + break; + } + + case Reg_Pre_Query_Key_Security: + { + registryEventArgs->EventName = L"OnPreQueryKeySecurity"; + break; + } + + case Reg_Pre_Set_Key_Security: + { + registryEventArgs->EventName = L"OnPreSetKeySecurity"; + break; + } + + case Reg_Pre_Restore_Key: + { + registryEventArgs->EventName = L"OnPreRestoreKey"; + break; + } + + case Reg_Pre_Save_Key: + { + registryEventArgs->EventName = L"OnPreSaveKey"; + break; + } + + case Reg_Pre_Replace_Key: + { + registryEventArgs->EventName = L"OnPreReplaceKey"; + break; + } + + case Reg_Pre_Query_KeyName: + { + registryEventArgs->EventName = L"OnPreQueryKeyName"; + break; + } + + default: break; + } + + messageReply->ReturnStatus = STATUS_SUCCESS; + + //you can block the process creation with below setting. + //messageReply->FilterStatus = FILTER_COMPLETE_PRE_OPERATION; + //messageReply->ReturnStatus = STATUS_ACCESS_DENIED; + + // + //You can modify the I/O data with below setting. + // + //memcpy(messageReply->ReplyData.Data.DataBuffer,your custom data, custom data length); + //messageReply->ReplyData.Data.DataBufferLength = dataLength; + //messageReply->FilterStatus = FILTER_MESSAGE_IS_DIRTY|FILTER_DATA_BUFFER_IS_UPDATED; + + DisplayRegistryMessage(registryEventArgs); + + return retVal; +} + + +#endif \ No newline at end of file diff --git a/Demo_Source_Code/CPlusPlusDemo/Tools.cpp b/Demo_Source_Code/CPlusPlusDemo/Tools.cpp new file mode 100644 index 0000000..905bd13 --- /dev/null +++ b/Demo_Source_Code/CPlusPlusDemo/Tools.cpp @@ -0,0 +1,273 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "Tools.h" + +#pragma pack(push,8) +#include +#pragma pack(pop) + +#include +#pragma comment(lib,"Psapi.lib") + + +#define MAX_ERROR_MESSAGE_SIZE 1024 + +using namespace std; + +void ChangeColour(WORD theColour) +{ + HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); // Get handle to standard output + SetConsoleTextAttribute(hConsole,theColour); // set the text attribute of the previous handle +} + +void +PrintMessage(WCHAR* message,WORD theColour) +{ + ChangeColour(theColour); + wprintf(message); + ChangeColour(FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE); +} + +void +PrintPassedMessage(WCHAR* message) +{ + PrintMessage(message,FOREGROUND_GREEN); +} + +void +PrintFailedMessage(WCHAR* message) +{ + PrintMessage(message,FOREGROUND_RED); +} + + +// +//Get the last error message returned from FilterAPI, and print it. +// +void +PrintLastErrorMessage(WCHAR* message) +{ + ULONG messageLength = 0; + WCHAR* buffer = NULL; + + if( !GetLastErrorMessage(buffer,&messageLength )) + { + buffer = (WCHAR*)malloc(messageLength); + + GetLastErrorMessage(buffer,&messageLength ); + + } + + PrintFailedMessage(message); + PrintFailedMessage(buffer); + printf("\n"); + + free(buffer); +} + +// +//To display message in WinDbg or DbgView application. +// +void +ToDebugger( + const WCHAR* pszFormat, + ...) +{ + + va_list arglist; + WCHAR pBuffer[MAX_ERROR_MESSAGE_SIZE]; + + memset( pBuffer, 0,MAX_ERROR_MESSAGE_SIZE*sizeof(WCHAR) ); + + va_start(arglist, pszFormat); + vswprintf(pBuffer,MAX_ERROR_MESSAGE_SIZE, pszFormat, arglist); + va_end(arglist); + + OutputDebugStringW(pBuffer); + OutputDebugStringW(L"\n"); + +} + +void +PrintErrorMessage( + LPWSTR message, + DWORD errorCode ) +{ + LPVOID lpMsgBuf = NULL; + WCHAR errorMessage[MAX_ERROR_MESSAGE_SIZE]; + + __try + { + + if( errorCode != 0 ) + { + FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, + NULL, errorCode, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR) &lpMsgBuf, 0, NULL ); + + swprintf_s( errorMessage, MAX_ERROR_MESSAGE_SIZE, L"%ws,errorCode:0x%0x,%ws\n", message,errorCode,lpMsgBuf); + + } + else + { + swprintf_s( errorMessage, MAX_ERROR_MESSAGE_SIZE, L"%ws\n", message); + } + + ChangeColour(FOREGROUND_RED); + wprintf(errorMessage); + OutputDebugStringW (errorMessage); + ChangeColour(FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE); + + } + __except( EXCEPTION_EXECUTE_HANDLER ) + { + OutputDebugStringW(L"PrintErrorMessage exception."); + } + + if( lpMsgBuf ) + { + LocalFree( lpMsgBuf ); + } +} + +std::wstring +GetFileTimeStr(LONGLONG fileTime ) +{ + SYSTEMTIME stUTC, stLocal; + DWORD dwRet; + + WCHAR buffer[100]; + std::wstring timeStr; + + // Convert the last-write time to local time. + FileTimeToSystemTime((FILETIME*)&fileTime, &stUTC); + SystemTimeToTzSpecificLocalTime(NULL, &stUTC, &stLocal); + + // Build a string showing the date and time. + dwRet = StringCchPrintfW(buffer, sizeof(buffer)*2, + L"%02d/%02d/%d %02d:%02d", + stLocal.wMonth, stLocal.wDay, stLocal.wYear, + stLocal.wHour, stLocal.wMinute); + + if( S_OK == dwRet ) + { + timeStr.assign(buffer); + } + + return timeStr; +} + +BOOLEAN +EnableDebugPrivileges() +{ + HANDLE Token; + HRESULT hResult = S_OK; + HANDLE procHandle = GetCurrentProcess(); + BOOL result = OpenProcessToken(procHandle, + TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, + &Token); + + //wprintf(L"OpenProcessToken pid:%p result:%d .\n", procHandle,result); + + if (result) + { + PRIVILEGE_SET privilegeSet; + privilegeSet.PrivilegeCount = 1; + privilegeSet.Control = PRIVILEGE_SET_ALL_NECESSARY; + + result = LookupPrivilegeValue(NULL, SE_DEBUG_NAME, + &privilegeSet.Privilege[0].Luid); + + // wprintf(L"LookupPrivilegeValue result:%d .\n", result); + + if (result) + { + TOKEN_PRIVILEGES tokenPrivileges; + tokenPrivileges.PrivilegeCount = 1; + tokenPrivileges.Privileges[0].Luid = privilegeSet.Privilege[0].Luid; + tokenPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; + + result = AdjustTokenPrivileges(Token, FALSE, + &tokenPrivileges, 0, NULL, NULL); + + if (result) + { + result = PrivilegeCheck(Token, &privilegeSet, &result); + + if (!result) + { + // wprintf(L"ERROR_PRIVILEGE_NOT_HELD SE_DEBUG_NAME result:%d .\n", result); + SetLastError(ERROR_PRIVILEGE_NOT_HELD); + } + + //wprintf(L"got SE_DEBUG_NAME result:%d .\n", result); + } + } + + CloseHandle(Token); + } + + if (!result) + { + } + + return result; +} + + +BOOL +GetProcessNameByPid(ULONG pid, WCHAR* processName, ULONG processNameLength ) +{ + BOOL retVal = FALSE; + HANDLE h = NULL; + +__try +{ + h = OpenProcess + ( + PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, + FALSE, + pid + ); + + if (h) + { + memset(processName,0,processNameLength); + if (GetModuleFileNameEx(h,NULL,processName, processNameLength) != 0) + { + retVal = TRUE; + } + else + { + //PrintErrorMessage(L"GetProcessImageFileNameW failed.", GetLastError()); + } + + CloseHandle(h); + + } +} +__except( EXCEPTION_EXECUTE_HANDLER ) +{ + printf("\n\nGet processName for process Id:%d exception.\n\n", pid ); +} + +return retVal; + +} diff --git a/Demo_Source_Code/CPlusPlusDemo/Tools.h b/Demo_Source_Code/CPlusPlusDemo/Tools.h new file mode 100644 index 0000000..a2cc6b8 --- /dev/null +++ b/Demo_Source_Code/CPlusPlusDemo/Tools.h @@ -0,0 +1,55 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies Inc. +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +/////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include +#include "FilterAPI.h" +#include "WinDataStructures.h" + +void ChangeColour(WORD theColour); + +void +PrintPassedMessage(WCHAR* message); + +void +PrintFailedMessage(WCHAR* message); + +void +PrintMessage(WCHAR* message,WORD theColour); + +void +PrintLastErrorMessage(WCHAR* message); + +BOOL +GetProcessNameByPid(ULONG pid, WCHAR* processName, ULONG processNameLength ); + +std::wstring +GetFileTimeStr(LONGLONG fileTime ); + +BOOLEAN +EnableDebugPrivileges(); + +// +//To display message in WinDbg or DbgView application. +// +void +ToDebugger( + const WCHAR* pszFormat, + ...); + +void +PrintErrorMessage( + LPWSTR message, + DWORD errorCode ); + + + + diff --git a/Demo_Source_Code/CPlusPlusDemo/UnitTest.cpp b/Demo_Source_Code/CPlusPlusDemo/UnitTest.cpp new file mode 100644 index 0000000..9a92010 --- /dev/null +++ b/Demo_Source_Code/CPlusPlusDemo/UnitTest.cpp @@ -0,0 +1,1363 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "Tools.h" +#include "FilterControl.h" +#include "UnitTest.h" + +#define MAX_ERROR_MESSAGE_SIZE 1024 + +static WCHAR* testFolder = L"c:\\filterTest"; +static WCHAR* filterMask = L"c:\\filterTest\\*"; +static WCHAR* testFile = L"c:\\filterTest\\myTestFile.txt"; +static WCHAR* reparseFolder = L"c:\\reparse"; +static WCHAR* reparseMask = L"c:\\reparse\\*"; +static WCHAR* reparseFile = L"c:\\reparse\\myTestFile.txt"; +static CHAR* testData = "EaseFilter Test Data for read/write,This is the original data when we setup a new test file.\n For callback filter read/write test,It will modify this data"; +static CHAR* replaceData = "This replace data test,it is not in the file.It will replace/merge the original data"; +static CHAR* reparseData = "EaseFilter Test Data for reparse open,this is the data from reparse file open."; +static LONGLONG testFileSize = 2147483648; //2 GB; + + +BOOL +IsTestFile(WCHAR* fileName,ULONG fileNameLength ) +{ + if( _wcsnicmp(testFile,fileName,wcslen(testFile)) == 0) + { + return TRUE; + } + else + { + return FALSE; + } +} + +BOOL +IsTestFolder(WCHAR* fileName ) +{ + if( _wcsnicmp(testFolder,fileName,wcslen(testFolder)) == 0) + { + return TRUE; + } + else + { + return FALSE; + } +} + +WCHAR* +GetFilterMask() +{ + return filterMask; +} + +WCHAR* +GetTestReparseFileName() +{ + return reparseFile; +} + +CHAR* +GetReplaceData() +{ + return replaceData; +} + +LONGLONG +GetTestFileSize() +{ + return testFileSize; +} + +LARGE_INTEGER +GetTestFileTime() +{ + SYSTEMTIME st; + FILETIME fileTime; + GetSystemTime(&st); + + /*printf("Current SystemTime: Year:%d Month:%d Day:%d Hour:%d Min:%d Second:% d\n" + ,st.wYear,st.wMonth,st.wDay,st.wHour,st.wMinute,st.wSecond);*/ + + //set the test file time to 2011/11/11 + st.wYear = 2011; + st.wMonth = 11; + st.wDay = 11; + st.wHour = 11; + st.wMinute = 11; + st.wSecond = 11; + st.wMilliseconds = 11; + + SystemTimeToFileTime(&st,&fileTime); + + LARGE_INTEGER large; + large.LowPart=fileTime.dwLowDateTime; + large.HighPart=fileTime.dwHighDateTime; + + return large; +} + +BOOL +CreateTestFile(WCHAR* folder,WCHAR* fileName,CHAR* data) +{ + LARGE_INTEGER ByteOffset = {0}; + OVERLAPPED Overlapped = {0}; + DWORD dwTransferred = 0; + DWORD Length = 0; + int nError = ERROR_SUCCESS; + BOOL ret = FALSE; + + //Create the test folder. + ret = CreateDirectory(folder,NULL); + + if( ret == 0 ) + { + nError = GetLastError(); + if( nError != ERROR_ALREADY_EXISTS ) + { + PrintErrorMessage(L"Create test folder failed.", nError); + return FALSE; + } + } + + //Remove readOnly attribue if it exist. + SetFileAttributes(fileName,FILE_ATTRIBUTE_NORMAL); + + //Create the test file,if it exist, overwrite it. + HANDLE pFile = CreateFile(fileName,GENERIC_WRITE,NULL,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL); + + if( pFile == INVALID_HANDLE_VALUE ) + { + PrintErrorMessage(L"Create test file failed.", GetLastError()); + return FALSE; + } + + Length = (DWORD)strlen(data); + + // Write test data to the test file. + if(!WriteFile(pFile, data, Length, &dwTransferred, NULL)) + { + nError = GetLastError(); + PrintErrorMessage(L"WriteFile failed.", nError); + ret = FALSE; + goto EXIT; + } + + ret = TRUE; + +EXIT: + + CloseHandle(pFile); + + return ret; + +} + +BOOL +SetupTestEnvironment() +{ + BOOL ret = CreateTestFile(testFolder,testFile,testData); + + if(!ret) + { + return ret; + } + + ret = CreateTestFile(reparseFolder,reparseFile,reparseData); + + return ret; +} + +BOOL +AccessFlagControlTest(FilterControl* filterControl) +{ + BOOL ret = FALSE; + CHAR buffer[4096]; + ULONG bufferLength = sizeof(buffer); + HANDLE pFile = INVALID_HANDLE_VALUE; + ULONG accessFlag = 0; + DWORD dwError = 0; + + FileFilterRule fileFilter(filterMask); + //after the processes open the managed files, it then can't create the new files till the processes terminated. + accessFlag = (~ALLOW_ALL_SAVE_AS)&ALLOW_MAX_RIGHT_ACCESS; + fileFilter.AccessFlag = accessFlag; + + filterControl->ClearConfigData(); + filterControl->SendFileFilterRuleToFilter(&fileFilter); + + pFile = CreateFile(testFile,GENERIC_WRITE,NULL,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL); + if( INVALID_HANDLE_VALUE == pFile ) + { + PrintErrorMessage(L"ALLOW_ALL_SAVE_AS test failed, it can't open the protected file.",GetLastError()); + ret = FALSE; + goto EXIT; + } + else + { + CloseHandle(pFile); + } + + pFile = CreateFile(testFile,GENERIC_WRITE,NULL,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL); + if( INVALID_HANDLE_VALUE != pFile ) + { + PrintErrorMessage(L"ALLOW_ALL_SAVE_AS test failed.",0); + ret = FALSE; + goto EXIT; + } + else + { + dwError = GetLastError(); + + if( ERROR_ACCESS_DENIED != dwError ) + { + PrintErrorMessage(L"ALLOW_ALL_SAVE_AS test failed.",dwError); + ret = FALSE; + goto EXIT; + } + + PrintPassedMessage(L"ALLOW_ALL_SAVE_AS test passed.\n"); + } + + //we need to remove the current process Id from the block save as list, or the current process can't create the new file. + if(!RemoveBlockSaveAsProcessId(GetCurrentProcessId())) + { + PrintLastErrorMessage(L"RemoveBlockSaveAsProcessId failed."); + ret = FALSE; + goto EXIT; + } + + + //Test Remove ALLOW_OPEN_WTIH_ACCESS_SYSTEM_SECURITY + accessFlag = (~ALLOW_OPEN_WTIH_ACCESS_SYSTEM_SECURITY)&ALLOW_MAX_RIGHT_ACCESS; + fileFilter.AccessFlag = accessFlag; + + filterControl->ClearConfigData(); + filterControl->SendFileFilterRuleToFilter(&fileFilter); + + pFile = CreateFile(testFile,ACCESS_SYSTEM_SECURITY,NULL,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); + if( INVALID_HANDLE_VALUE != pFile ) + { + PrintErrorMessage(L"ALLOW_OPEN_WTIH_ACCESS_SYSTEM_SECURITY test failed.",0); + ret = FALSE; + goto EXIT; + } + else + { + dwError = GetLastError(); + + if( ERROR_ACCESS_DENIED != dwError ) + { + PrintErrorMessage(L"ALLOW_OPEN_WTIH_ACCESS_SYSTEM_SECURITY test failed.",dwError); + ret = FALSE; + goto EXIT; + } + + PrintPassedMessage(L"ALLOW_OPEN_WTIH_ACCESS_SYSTEM_SECURITY test passed.\n"); + } + + + //Test Remove ALLOW_OPEN_WITH_READ_ACCESS + accessFlag = (~ALLOW_OPEN_WITH_READ_ACCESS)&ALLOW_MAX_RIGHT_ACCESS; + fileFilter.AccessFlag = accessFlag; + + filterControl->ClearConfigData(); + filterControl->SendFileFilterRuleToFilter(&fileFilter); + + + pFile = CreateFile(testFile,GENERIC_READ,NULL,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); + if( INVALID_HANDLE_VALUE != pFile ) + { + PrintErrorMessage(L"ALLOW_OPEN_WITH_READ_ACCESS test failed.",0); + ret = FALSE; + goto EXIT; + } + else + { + dwError = GetLastError(); + + if( ERROR_ACCESS_DENIED != dwError ) + { + PrintErrorMessage(L"ALLOW_OPEN_WITH_READ_ACCESS test failed.",dwError); + ret = FALSE; + goto EXIT; + } + PrintPassedMessage(L"ALLOW_OPEN_WITH_READ_ACCESS test passed.\n"); + } + + + //Test Remove ALLOW_OPEN_WITH_WRITE_ACCESS + accessFlag = (~ALLOW_OPEN_WITH_WRITE_ACCESS)&ALLOW_MAX_RIGHT_ACCESS; + fileFilter.AccessFlag = accessFlag; + + filterControl->ClearConfigData(); + filterControl->SendFileFilterRuleToFilter(&fileFilter); + + pFile = CreateFile(testFile,GENERIC_WRITE,NULL,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); + if( INVALID_HANDLE_VALUE != pFile ) + { + PrintErrorMessage(L"ALLOW_OPEN_WITH_WRITE_ACCESS test failed.",0); + ret = FALSE; + goto EXIT; + } + else + { + dwError = GetLastError(); + + if( ERROR_ACCESS_DENIED != dwError ) + { + PrintErrorMessage(L"ALLOW_OPEN_WITH_WRITE_ACCESS test failed.",dwError); + ret = FALSE; + goto EXIT; + } + + PrintPassedMessage(L"ALLOW_OPEN_WITH_WRITE_ACCESS test passed.\n"); + } + + //Not allow open file with create or overwrite option. + accessFlag = (~ALLOW_OPEN_WITH_CREATE_OR_OVERWRITE_ACCESS) & ALLOW_MAX_RIGHT_ACCESS; + fileFilter.AccessFlag = accessFlag; + + filterControl->ClearConfigData(); + filterControl->SendFileFilterRuleToFilter(&fileFilter); + + pFile = CreateFile(testFile,GENERIC_WRITE,NULL,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL); + if( INVALID_HANDLE_VALUE != pFile ) + { + PrintErrorMessage(L"ALLOW_OPEN_WITH_CREATE_OR_OVERWRITE_EXIST_FILE test failed.",0); + ret = FALSE; + goto EXIT; + } + else + { + dwError = GetLastError(); + + if( ERROR_ACCESS_DENIED != dwError ) + { + PrintErrorMessage(L"ALLOW_OPEN_WITH_CREATE_OR_OVERWRITE_EXIST_FILE test failed.",dwError); + ret = FALSE; + goto EXIT; + } + + PrintPassedMessage(L"ALLOW_OPEN_WITH_CREATE_OR_OVERWRITE_EXIST_FILE test passed.\n"); + } + + + + //Test Remove ALLOW_OPEN_WITH_DELETE_ACCESS. + accessFlag = (~ALLOW_OPEN_WITH_DELETE_ACCESS) & ALLOW_MAX_RIGHT_ACCESS; + fileFilter.AccessFlag = accessFlag; + + filterControl->ClearConfigData(); + filterControl->SendFileFilterRuleToFilter(&fileFilter); + + pFile = CreateFile(testFile,DELETE,NULL,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); + if( INVALID_HANDLE_VALUE != pFile ) + { + PrintErrorMessage(L"ALLOW_OPEN_WITH_DELETE_ACCESS test failed.",0); + ret = FALSE; + goto EXIT; + } + else + { + dwError = GetLastError(); + + if( ERROR_ACCESS_DENIED != dwError ) + { + PrintErrorMessage(L"ALLOW_OPEN_WITH_DELETE_ACCESS test failed.",dwError); + ret = FALSE; + goto EXIT; + } + + PrintPassedMessage(L"ALLOW_OPEN_WITH_DELETE_ACCESS test passed.\n"); + } + + + //Test Remove ALLOW_READ_ACCESS. + accessFlag = (~ALLOW_READ_ACCESS) & ALLOW_MAX_RIGHT_ACCESS; + fileFilter.AccessFlag = accessFlag; + + filterControl->ClearConfigData(); + filterControl->SendFileFilterRuleToFilter(&fileFilter); + + pFile = CreateFile(testFile,GENERIC_READ,NULL,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); + if( INVALID_HANDLE_VALUE == pFile ) + { + PrintErrorMessage(L"Open test file for read access failed.",GetLastError()); + ret = FALSE; + goto EXIT; + } + + ret = ReadFile(pFile,buffer,bufferLength,&bufferLength,NULL); + if(0 != ret) + { + PrintErrorMessage(L"ALLOW_READ_ACCESS test failed.",0); + goto EXIT; + } + else + { + dwError = GetLastError(); + + if( ERROR_ACCESS_DENIED != dwError ) + { + PrintErrorMessage(L"ALLOW_READ_ACCESS test failed.",dwError); + ret = FALSE; + goto EXIT; + } + + PrintPassedMessage(L"ALLOW_READ_ACCESS test passed.\n"); + CloseHandle(pFile); + } + + //Test Remove ALLOW_WRITE_ACCESS. + accessFlag = (~ALLOW_WRITE_ACCESS) & ALLOW_MAX_RIGHT_ACCESS; + fileFilter.AccessFlag = accessFlag; + + filterControl->ClearConfigData(); + filterControl->SendFileFilterRuleToFilter(&fileFilter); + + pFile = CreateFile(testFile,GENERIC_WRITE,NULL,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); + if( INVALID_HANDLE_VALUE == pFile ) + { + PrintErrorMessage(L"Open test file for write access failed.",GetLastError()); + ret = FALSE; + goto EXIT; + } + + + ret = WriteFile(pFile,buffer,bufferLength,&bufferLength,NULL); + if(0 != ret) + { + PrintErrorMessage(L"ALLOW_WRITE_ACCESS test failed.",0); + goto EXIT; + } + else + { + dwError = GetLastError(); + + if( ERROR_ACCESS_DENIED != dwError ) + { + PrintErrorMessage(L"ALLOW_WRITE_ACCESS test failed.",dwError); + ret = FALSE; + goto EXIT; + } + PrintPassedMessage(L"ALLOW_WRITE_ACCESS test passed.\n"); + CloseHandle(pFile); + } + + + //Test Remove ALLOW_QUERY_INFORMATION_ACCESS. + accessFlag = (~ALLOW_QUERY_INFORMATION_ACCESS) & ALLOW_MAX_RIGHT_ACCESS; + fileFilter.AccessFlag = accessFlag; + + filterControl->ClearConfigData(); + filterControl->SendFileFilterRuleToFilter(&fileFilter); + + pFile = CreateFile(testFile,GENERIC_READ,NULL,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); + if( INVALID_HANDLE_VALUE == pFile ) + { + PrintErrorMessage(L"Open test file for query information failed.",GetLastError()); + ret = FALSE; + goto EXIT; + } + + BY_HANDLE_FILE_INFORMATION fileInfo; + ret = GetFileInformationByHandle(pFile,&fileInfo); + if(0 != ret) + { + PrintErrorMessage(L"ALLOW_QUERY_INFORMATION_ACCESS test failed.",0); + goto EXIT; + } + else + { + dwError = GetLastError(); + + if( ERROR_ACCESS_DENIED != dwError ) + { + PrintErrorMessage(L"ALLOW_QUERY_INFORMATION_ACCESS test failed.",dwError); + ret = FALSE; + goto EXIT; + } + + PrintPassedMessage(L"ALLOW_QUERY_INFORMATION_ACCESS test passed.\n"); + CloseHandle(pFile); + } + + + + //Test Remove ALLOW_SET_INFORMATION. + accessFlag = (~ALLOW_SET_INFORMATION) & ALLOW_MAX_RIGHT_ACCESS; + fileFilter.AccessFlag = accessFlag; + + filterControl->ClearConfigData(); + filterControl->SendFileFilterRuleToFilter(&fileFilter); + + pFile = CreateFile(testFile,GENERIC_ALL,NULL,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); + if( INVALID_HANDLE_VALUE == pFile ) + { + PrintErrorMessage(L"Open test file for set information failed.",GetLastError()); + ret = FALSE; + goto EXIT; + } + + //this API only support in windows vista or later version. + //ret = SetFileInformationByHandle(pFile,FileBasicInfo,&fileInfo,sizeof(BY_HANDLE_FILE_INFORMATION)); + + //we will test with this API + ret = SetFileAttributes(testFile,FILE_ATTRIBUTE_READONLY); + if(0 != ret) + { + PrintErrorMessage(L"ALLOW_SET_INFORMATION test failed.",0); + goto EXIT; + } + else + { + dwError = GetLastError(); + + if( ERROR_ACCESS_DENIED != dwError ) + { + PrintErrorMessage(L"ALLOW_SET_INFORMATION test failed.",dwError); + ret = FALSE; + goto EXIT; + } + + PrintPassedMessage(L"ALLOW_SET_INFORMATION test passed.\n"); + CloseHandle(pFile); + } + + //Test Remove ALLOW_FILE_RENAME. + accessFlag = (~ALLOW_FILE_RENAME) & ALLOW_MAX_RIGHT_ACCESS; + fileFilter.AccessFlag = accessFlag; + + filterControl->ClearConfigData(); + filterControl->SendFileFilterRuleToFilter(&fileFilter); + + ret = MoveFile (testFile,L"c:\\TestMoveFileNameFile.txt"); + if(0 != ret) + { + PrintErrorMessage(L"ALLOW_FILE_RENAME test failed.",0); + goto EXIT; + } + else + { + dwError = GetLastError(); + + if( ERROR_ACCESS_DENIED != dwError ) + { + PrintErrorMessage(L"ALLOW_FILE_RENAME test failed.",dwError); + ret = FALSE; + goto EXIT; + } + + PrintPassedMessage(L"ALLOW_FILE_RENAME test passed.\n"); + } + + //Test Remove ALLOW_FILE_DELETE. + accessFlag = (~ALLOW_FILE_DELETE) & ALLOW_MAX_RIGHT_ACCESS; + fileFilter.AccessFlag = accessFlag; + + filterControl->ClearConfigData(); + filterControl->SendFileFilterRuleToFilter(&fileFilter); + + ret = DeleteFile(testFile); + if(0 != ret) + { + PrintErrorMessage(L"ALLOW_FILE_DELETE test failed.",0); + goto EXIT; + } + else + { + dwError = GetLastError(); + + if( ERROR_ACCESS_DENIED != dwError ) + { + PrintErrorMessage(L"ALLOW_FILE_DELETE test failed.",dwError); + ret = FALSE; + goto EXIT; + } + + PrintPassedMessage(L"ALLOW_FILE_DELETE test passed.\n"); + } + + //Test Remove ALLOW_FILE_SIZE_CHANGE. + accessFlag = (~ALLOW_FILE_SIZE_CHANGE) & ALLOW_MAX_RIGHT_ACCESS; + fileFilter.AccessFlag = accessFlag; + + filterControl->ClearConfigData(); + filterControl->SendFileFilterRuleToFilter(&fileFilter); + + pFile = CreateFile(testFile,GENERIC_ALL,NULL,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); + if( INVALID_HANDLE_VALUE == pFile ) + { + PrintErrorMessage(L"Open test file for file size change failed.",GetLastError()); + ret = FALSE; + goto EXIT; + } + + DWORD newPointer = SetFilePointer(pFile,65536,NULL,FILE_BEGIN);//set file pointer to 65536 from the beginning. + + if( INVALID_SET_FILE_POINTER == newPointer) + { + PrintErrorMessage(L"SetFilePointer failed.",GetLastError()); + goto EXIT; + } + + ret = SetEndOfFile(pFile); + if(0 != ret) + { + PrintErrorMessage(L"ALLOW_FILE_SIZE_CHANGE test failed.",0); + ret = FALSE; + goto EXIT; + } + else + { + dwError = GetLastError(); + + if( ERROR_ACCESS_DENIED != dwError ) + { + PrintErrorMessage(L"ALLOW_FILE_SIZE_CHANGE test failed.",dwError); + ret = FALSE; + goto EXIT; + } + + PrintPassedMessage(L"ALLOW_FILE_SIZE_CHANGE test passed.\n"); + CloseHandle(pFile); + } + + + + //Test Remove ALLOW_QUERY_SECURITY_ACCESS. + accessFlag = (~ALLOW_QUERY_SECURITY_ACCESS) & ALLOW_MAX_RIGHT_ACCESS; + fileFilter.AccessFlag = accessFlag; + + filterControl->ClearConfigData(); + filterControl->SendFileFilterRuleToFilter(&fileFilter); + + BYTE SecDescBuff[0x4000]; + DWORD cbSD = sizeof(SecDescBuff); + + ret = GetFileSecurity(testFile, DACL_SECURITY_INFORMATION, SecDescBuff, cbSD, &cbSD); + if(0 != ret) + { + PrintErrorMessage(L"ALLOW_QUERY_SECURITY_ACCESS test failed.",0); + goto EXIT; + } + else + { + dwError = GetLastError(); + + if( ERROR_ACCESS_DENIED != dwError ) + { + PrintErrorMessage(L"ALLOW_QUERY_SECURITY_ACCESS test failed.",dwError); + ret = FALSE; + goto EXIT; + } + + + PrintPassedMessage(L"ALLOW_QUERY_SECURITY_ACCESS test passed.\n"); + } + + + //Test Remove ALLOW_SET_SECURITY_ACCESS. + accessFlag = (~ALLOW_SET_SECURITY_ACCESS) & ALLOW_MAX_RIGHT_ACCESS; + fileFilter.AccessFlag = accessFlag; + + filterControl->ClearConfigData(); + filterControl->SendFileFilterRuleToFilter(&fileFilter); + + cbSD = sizeof(SecDescBuff); + + ret = GetFileSecurity(testFile, GROUP_SECURITY_INFORMATION, SecDescBuff, cbSD, &cbSD); + if(0 == ret) + { + PrintErrorMessage(L"ALLOW_SET_SECURITY_ACCESS GetFileSecurity failed.",GetLastError()); + goto EXIT; + } + + ret = SetFileSecurity(testFile, GROUP_SECURITY_INFORMATION, SecDescBuff); + + if(0 != ret) + { + PrintErrorMessage(L"ALLOW_SET_SECURITY_ACCESS test failed.",0); + goto EXIT; + } + else + { + dwError = GetLastError(); + + if( ERROR_ACCESS_DENIED != dwError ) + { + PrintErrorMessage(L"ALLOW_SET_SECURITY_ACCESS test failed.",dwError); + ret = FALSE; + goto EXIT; + } + + + PrintPassedMessage(L"ALLOW_SET_SECURITY_ACCESS test passed.\n"); + } + + + //Test Remove ALLOW_DIRECTORY_LIST_ACCESS. + accessFlag = (~ALLOW_DIRECTORY_LIST_ACCESS) & ALLOW_MAX_RIGHT_ACCESS; + fileFilter.AccessFlag = accessFlag; + + filterControl->ClearConfigData(); + filterControl->SendFileFilterRuleToFilter(&fileFilter); + + WIN32_FIND_DATA findFileData; + pFile = FindFirstFile(filterMask, &findFileData); + + if(INVALID_HANDLE_VALUE != pFile) + { + PrintErrorMessage(L"ALLOW_DIRECTORY_LIST_ACCESS test failed.",0); + + printf("handle:%p file:%d ",pFile,findFileData.dwFileAttributes); + FindClose(pFile); + pFile = INVALID_HANDLE_VALUE; + goto EXIT; + } + else + { + dwError = GetLastError(); + + if( ERROR_ACCESS_DENIED != dwError ) + { + PrintErrorMessage(L"ALLOW_DIRECTORY_LIST_ACCESS test failed.",dwError); + ret = FALSE; + goto EXIT; + } + + PrintPassedMessage(L"ALLOW_DIRECTORY_LIST_ACCESS test passed.\n"); + } + + // + //add exclude filter mask test + //you can add multiply exclude filter masks with the same accessFlag and same filter mask. + // + //Here we do the same test as above test, but we add the exclude filter mask, + //the above test, it can't open the file with security access, now we add the exclude to our test file, + //now we should be fine to open the file. + // + // + accessFlag = (~ALLOW_SET_INFORMATION) & ALLOW_MAX_RIGHT_ACCESS; + fileFilter.AccessFlag = accessFlag; + fileFilter.AddExcludeFileFilterMask(L"*mytestFile.txt"); + + filterControl->ClearConfigData(); + filterControl->SendFileFilterRuleToFilter(&fileFilter); + + pFile = CreateFile(testFile,GENERIC_ALL,NULL,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); + if( INVALID_HANDLE_VALUE == pFile ) + { + PrintErrorMessage(L"Open test file for set information failed.",GetLastError()); + ret = FALSE; + goto EXIT; + } + + //we will test with this API + ret = SetFileAttributes(testFile,FILE_ATTRIBUTE_READONLY); + if(0 == ret) + { + PrintErrorMessage(L"exclude filter mask test failed.",0); + ret = FALSE; + goto EXIT; + } + else + { + PrintPassedMessage(L"exclude filter mask test passed.\n"); + CloseHandle(pFile); + pFile = INVALID_HANDLE_VALUE; + } + + + + ret = TRUE; + +EXIT: + + if(!ret ) + { + PrintFailedMessage(L"\nAccess Flag Test failed.\n\n"); + } + else + { + PrintPassedMessage(L"\nAccess Flag Test Passed.\n\n"); + } + + if( INVALID_HANDLE_VALUE != pFile ) + { + CloseHandle(pFile); + } + + return ret; +} + +BOOL +ReparseFilterRuleTest(FilterControl* filterControl) +{ + BOOL ret = FALSE; + + FileFilterRule fileFilter(filterMask); + ULONG accessFlag = ENABLE_REPARSE_FILE_OPEN|ALLOW_MAX_RIGHT_ACCESS; + fileFilter.AccessFlag = accessFlag; + fileFilter.ReparseFileFilterMask = reparseMask; + + filterControl->ClearConfigData(); + filterControl->SendFileFilterRuleToFilter(&fileFilter); + + HANDLE pFile = CreateFile(testFile,GENERIC_READ,NULL,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); + if( NULL == pFile ) + { + PrintErrorMessage(L"Open test file failed.",GetLastError()); + goto EXIT; + } + else + { + ULONG bufferLength =(ULONG)strlen(reparseData); + CHAR* buffer = (CHAR*)malloc( bufferLength ); + + if(NULL == buffer) + { + PrintErrorMessage(L"Reparse filter rule test failed.Can't allocate memory for test.",0); + goto EXIT; + } + + ret = ReadFile(pFile,buffer,bufferLength,&bufferLength,NULL); + + if(0 == ret) + { + PrintErrorMessage(L"Read test file failed.",GetLastError()); + goto EXIT; + } + + if( memcmp(buffer,reparseData,bufferLength) == 0) + { + ret = TRUE; + } + else + { + PrintErrorMessage(L"The file open didnt reparse to the new file.",GetLastError()); + printf("ReparseData:%s\n\n",reparseData); + printf("DataReturn:%s\n\n",buffer); + ret = FALSE; + } + + } + +EXIT: + + if( ret ) + { + PrintPassedMessage(L"\nReparse filter rule test passed.\n\n"); + } + else + { + PrintFailedMessage(L"\nReparse filter rule test failed.\n\n"); + } + + if(pFile) + { + CloseHandle(pFile); + } + + return ret; + +} + +BOOL +ReadControlFilterTest(FilterControl* filterControl) +{ + BOOL ret = FALSE; + + FileFilterRule fileFilter(filterMask); + ULONG accessFlag = ALLOW_OPEN_WITH_READ_ACCESS |ALLOW_READ_ACCESS; + fileFilter.AccessFlag = accessFlag; + fileFilter.BooleanConfig = ENABLE_SEND_DATA_BUFFER; + fileFilter.ControlFileIOEventFilter = PRE_FASTIO_READ|PRE_CACHE_READ|PRE_NOCACHE_READ|PRE_PAGING_IO_READ; + + filterControl->ClearConfigData(); + filterControl->SendFileFilterRuleToFilter(&fileFilter); + + + HANDLE pFile = CreateFile(testFile,GENERIC_READ,NULL,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); + if( INVALID_HANDLE_VALUE == pFile ) + { + PrintErrorMessage(L"Open file for read test failed.",GetLastError()); + goto EXIT; + } + else + { + ULONG bufferLength = (ULONG)strlen(replaceData); + CHAR* buffer = (CHAR*)malloc( bufferLength ); + + if(NULL == buffer) + { + PrintErrorMessage(L"Can't allocate memory for test.",0); + goto EXIT; + } + + ret = ReadFile(pFile,buffer,bufferLength,&bufferLength,NULL); + + if(0 == ret) + { + PrintErrorMessage(L"Read test file failed.",GetLastError()); + goto EXIT; + } + + if( memcmp(buffer,replaceData,bufferLength) == 0) + { + + // + //in pre-read call back fucntion test, it will return replace data instead of the test data. + // + ret = TRUE; + } + else + { + PrintErrorMessage(L"Read data wasn't replaced by replace data.",0); + + printf("Read return data:\r\n%s\r\n\r\n",buffer); + printf("Replace data:\r\n%s\r\n\r\n",replaceData); + + + ret = FALSE; + } + + } + +EXIT: + + if( ret ) + { + PrintPassedMessage(L"\nRead Control Filter Test Passed.\n\n"); + } + else + { + PrintFailedMessage(L"\nRead Control Filter Test Failed.\n\n"); + } + + if(pFile) + { + CloseHandle(pFile); + } + + return ret; + +} + +BOOL +WriteControlFilterTest(FilterControl* filterControl) +{ + BOOL ret = FALSE; + + FileFilterRule fileFilter(filterMask); + ULONG accessFlag = ALLOW_MAX_RIGHT_ACCESS; + fileFilter.AccessFlag = accessFlag; + fileFilter.BooleanConfig = ENABLE_SEND_DATA_BUFFER; + fileFilter.ControlFileIOEventFilter = PRE_FASTIO_WRITE|PRE_CACHE_WRITE|PRE_NOCACHE_WRITE|PRE_PAGING_IO_WRITE; + + filterControl->ClearConfigData(); + filterControl->SendFileFilterRuleToFilter(&fileFilter); + + HANDLE pFile = CreateFile(testFile,GENERIC_ALL,NULL,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); + if( INVALID_HANDLE_VALUE == pFile ) + { + PrintErrorMessage(L"Open file for write test failed.",GetLastError()); + goto EXIT; + } + else + { + CHAR* buffer ="Test write data to my file,it will replace the test data in pre-write call back test function."; + ULONG bufferLength = (ULONG)strlen(buffer); + + ret = WriteFile(pFile,buffer,bufferLength,&bufferLength,NULL); + + if(0 == ret) + { + PrintErrorMessage(L"WriteFile failed.",GetLastError()); + goto EXIT; + } + + ULONG replaceDataLength = (ULONG)strlen(replaceData); + CHAR* replaceDataBuffer = (CHAR*)malloc( replaceDataLength ); + + if(NULL == replaceDataBuffer) + { + ret = FALSE; + PrintErrorMessage(L"Can't allocate memory for test.",0); + goto EXIT; + } + + //set file pointer the begining. + SetFilePointer(pFile,0,NULL,FILE_BEGIN); + ret = ReadFile(pFile,replaceDataBuffer,replaceDataLength,&replaceDataLength,NULL); + + if(0 == ret) + { + PrintErrorMessage(L"WriteControlFilterTest ReadFile failed.",GetLastError()); + goto EXIT; + } + + if( memcmp(replaceDataBuffer,replaceData,replaceDataLength) == 0) + { + + // + //in pre-write call back fucntion test, it will return replace data instead of the test data. + // + + ret = TRUE; + } + else + { + printf("Write Test Failed.\nDataFromFile:%s \n CorrectData:%s\n",replaceDataBuffer,replaceData); + ret = FALSE; + } + + } + +EXIT: + + if( ret ) + { + PrintPassedMessage(L"\nWrite Control Filter Test Passed.\n\n"); + } + else + { + PrintFailedMessage(L"\nWrite Control Filter Test Failed.\n\n"); + } + + if(pFile) + { + CloseHandle(pFile); + } + + return ret; + +} + +BOOL +QueryInformationControlTest(FilterControl* filterControl) +{ + BOOL ret = FALSE; + + FileFilterRule fileFilter(filterMask); + ULONG accessFlag = ALLOW_OPEN_WITH_READ_ACCESS|ALLOW_QUERY_INFORMATION_ACCESS; + fileFilter.AccessFlag = accessFlag; + fileFilter.ControlFileIOEventFilter = PRE_QUERY_INFORMATION; + + filterControl->ClearConfigData(); + filterControl->SendFileFilterRuleToFilter(&fileFilter); + + HANDLE pFile = CreateFile(testFile,GENERIC_READ,NULL,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); + if( INVALID_HANDLE_VALUE == pFile ) + { + PrintErrorMessage(L"Open test file failed.",GetLastError()); + goto EXIT; + } + else + { + FILETIME creationTime; + FILETIME lastAccessTime; + FILETIME lastWriteTime; + + ret = GetFileTime(pFile,&creationTime,&lastAccessTime,&lastWriteTime ); + + if(0 == ret) + { + PrintErrorMessage(L"QueryInformationControlTest GetFileInformationByHandle failed.",GetLastError()); + goto EXIT; + } + else + { + LARGE_INTEGER writeTime = GetTestFileTime(); + + if( writeTime.HighPart != lastWriteTime.dwHighDateTime || writeTime.LowPart != lastWriteTime.dwLowDateTime ) + { + ret = FALSE; + PrintErrorMessage(L"QueryInformationControlTest failed. Return last write time is not correct", 0 ); + } + + } + + + } + +EXIT: + + if( ret ) + { + PrintPassedMessage(L"\nQueryInformationControlTest passed.\n\n"); + } + else + { + PrintFailedMessage(L"\nQueryInformationControlTest failed.\n\n"); + } + + if(pFile) + { + CloseHandle(pFile); + } + + return ret; +} + +BOOL +SetInformationControlTest(FilterControl* filterControl) +{ + BOOL ret = FALSE; + + FileFilterRule fileFilter(filterMask); + ULONG accessFlag = ALLOW_MAX_RIGHT_ACCESS; + fileFilter.AccessFlag = accessFlag; + fileFilter.ControlFileIOEventFilter = PRE_SET_INFORMATION; + + + filterControl->ClearConfigData(); + filterControl->SendFileFilterRuleToFilter(&fileFilter); + + // + //In PRE_SET_INFORMATION call back test function,we add the readonly attribute to the file. + // + + ret = SetFileAttributes(testFile,FILE_ATTRIBUTE_NORMAL); + + if( 0 == ret) + { + PrintErrorMessage(L"SetInformationControlTest SetFileAttributes failed.",GetLastError()); + return FALSE; + } + + ULONG attributes = GetFileAttributes(testFile); + + if( INVALID_FILE_ATTRIBUTES == attributes ) + { + PrintErrorMessage(L"SetInformationControlTest GetFileAttributes failed.",GetLastError()); + return FALSE; + } + + if( attributes & FILE_ATTRIBUTE_READONLY ) + { + ret = TRUE; + PrintPassedMessage(L"\nSetInformationControlTest passed.\n\n"); + } + else + { + PrintFailedMessage(L"\nSetInformationControlTest failed.\n\n"); + } + + + return ret; +} + +BOOL +BrowseDirectoryControlTest(FilterControl* filterControl) +{ + BOOL ret = FALSE; + + FileFilterRule fileFilter(filterMask); + ULONG accessFlag = ALLOW_OPEN_WITH_READ_ACCESS|ALLOW_DIRECTORY_LIST_ACCESS; + fileFilter.AccessFlag = accessFlag; + fileFilter.ControlFileIOEventFilter = POST_DIRECTORY; + + + filterControl->ClearConfigData(); + filterControl->SendFileFilterRuleToFilter(&fileFilter); + + WIN32_FIND_DATA ffd; + HANDLE pFile = FindFirstFile(filterMask, &ffd); + + do + { + if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + { + printf(" %ws \n", ffd.cFileName); + } + else + { + LARGE_INTEGER filesize; + filesize.LowPart = ffd.nFileSizeLow; + filesize.HighPart = ffd.nFileSizeHigh; + printf(" %ws %I64d bytes\n", ffd.cFileName, filesize.QuadPart); + + if( filesize.QuadPart != GetTestFileSize()) + { + PrintErrorMessage(L"Browse directory failed.Return file size is not the same as test file size.",0); + ret = FALSE; + break; + } + } + } + while (FindNextFile(pFile, &ffd) != 0); + + if( INVALID_HANDLE_VALUE != pFile ) + { + FindClose(pFile); + } + + DWORD dwError = GetLastError(); + if (dwError != ERROR_NO_MORE_FILES) + { + PrintErrorMessage(L"Browse directory test failed. Return error:",dwError); + ret = FALSE; + } + else + { + PrintPassedMessage(L"\nBrowseDirectoryControlTest passed.\n\n"); + ret = TRUE; + } + + return ret; +} + + +BOOL +IncludeExcludeProcessNameTest(FilterControl* filterControl) +{ + BOOL ret = FALSE; + + FileFilterRule fileFilter(filterMask); + //Test Remove ALLOW_OPEN_WITH_WRITE_ACCESS for current process + ULONG accessFlag = (~ALLOW_OPEN_WITH_WRITE_ACCESS)&ALLOW_MAX_RIGHT_ACCESS; + ULONG currentPid = GetCurrentProcessId(); + + fileFilter.AccessFlag = accessFlag; + fileFilter.AddIncludeProcessId(currentPid); + + + filterControl->ClearConfigData(); + filterControl->SendFileFilterRuleToFilter(&fileFilter); + + HANDLE pFile = CreateFile(testFile,GENERIC_WRITE,NULL,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); + if( INVALID_HANDLE_VALUE != pFile ) + { + PrintErrorMessage(L"IncludeExcludeProcessNameTest test failed.",0); + return FALSE; + } + else + { + DWORD dwError = GetLastError(); + + if( ERROR_ACCESS_DENIED != dwError ) + { + PrintErrorMessage(L"IncludeExcludeProcessNameTest test failed.",dwError); + return FALSE; + } + PrintPassedMessage(L"IncludeExcludeProcessNameTest test passed.\n"); + } + + return ret; +} + + + +BOOLEAN +IncludeExcludeUserNameTest(FilterControl* filterControl) +{ + BOOLEAN ret = FALSE; + + FileFilterRule fileFilter(filterMask); + //Test Remove ALLOW_OPEN_WITH_WRITE_ACCESS for current process + ULONG accessFlag = (~ALLOW_OPEN_WITH_WRITE_ACCESS)&ALLOW_MAX_RIGHT_ACCESS; + + ULONG userNameSize = MAX_PATH; + WCHAR userName[MAX_PATH]; + + if( 0 == GetUserName(userName,&userNameSize) ) + { + PrintErrorMessage(L"GetUserName test failed.",GetLastError()); + return FALSE; + } + + fileFilter.AccessFlag = accessFlag; + fileFilter.AddIncludeUserName(userName); + + + filterControl->ClearConfigData(); + filterControl->SendFileFilterRuleToFilter(&fileFilter); + + HANDLE pFile = CreateFile(testFile,GENERIC_WRITE,NULL,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); + if( INVALID_HANDLE_VALUE != pFile ) + { + PrintErrorMessage(L"IncludeExcludeUserNameTest test failed.",0); + return FALSE; + + } + else + { + DWORD dwError = GetLastError(); + + if( ERROR_ACCESS_DENIED != dwError ) + { + PrintErrorMessage(L"IncludeExcludeUserNameTest test failed.",dwError); + return FALSE; + + } + + PrintPassedMessage(L"IncludeExcludeUserNameTest test passed.\n"); + } + + + return ret; +} + +void +FilterUnitTest() +{ + + if( !SetupTestEnvironment()) + { + PrintErrorMessage(L"Failed to setup test environment.",0); + return; + } + + FilterControl* filterControl = FilterControl::GetSingleInstance(); + + ULONG filterType = FILE_SYSTEM_CONTROL|FILE_SYSTEM_MONITOR|FILE_SYSTEM_ENCRYPTION|FILE_SYSTEM_PROCESS; + ULONG threadCount = 5; + ULONG connectionTimeout = 20; + + filterControl->StartFilter(filterType,threadCount,connectionTimeout,registerKey); + + Sleep(5000); + + IncludeExcludeProcessNameTest(filterControl); + + IncludeExcludeUserNameTest(filterControl); + + ReparseFilterRuleTest(filterControl); + + WriteControlFilterTest(filterControl); + + AccessFlagControlTest(filterControl); + + ReadControlFilterTest(filterControl); + + QueryInformationControlTest(filterControl); + + SetInformationControlTest(filterControl); + + BrowseDirectoryControlTest(filterControl); + + ////this the demo how to use the encryption filter. + EncryptionUnitTest(filterControl); + + system("pause"); + + filterControl->StopFilter(); + delete filterControl; +} \ No newline at end of file diff --git a/Demo_Source_Code/CPlusPlusDemo/UnitTest.h b/Demo_Source_Code/CPlusPlusDemo/UnitTest.h new file mode 100644 index 0000000..d1ba2c2 --- /dev/null +++ b/Demo_Source_Code/CPlusPlusDemo/UnitTest.h @@ -0,0 +1,44 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies Inc. +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +/////////////////////////////////////////////////////////////////////////////// + +#pragma once + +// Defines for NTSTATUS +typedef long NTSTATUS; + +#include "FilterControl.h" + +VOID +EncryptionUnitTest(FilterControl* filterControl); + +void +FilterUnitTest(); + +LARGE_INTEGER +GetTestFileTime(); + +WCHAR* +GetTestReparseFileName(); + +WCHAR* +GetFilterMask(); + +CHAR* +GetReplaceData(); + +LONGLONG +GetTestFileSize(); + +BOOL +IsTestFolder(WCHAR* fileName ); + +BOOL +IsTestFile(WCHAR* fileName,ULONG fileNameLength ); + diff --git a/Demo_Source_Code/CPlusPlusDemo/WinDataStructures.h b/Demo_Source_Code/CPlusPlusDemo/WinDataStructures.h new file mode 100644 index 0000000..da97a23 --- /dev/null +++ b/Demo_Source_Code/CPlusPlusDemo/WinDataStructures.h @@ -0,0 +1,336 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// This is the Windows data structure. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef __WinDataStructures_H__ +#define __WinDataStructures_H__ + +#define STATUS_SUCCESS 0 +#define STATUS_ACCESS_DENIED 0xC0000022L +#define STATUS_REPARSE 0x00000104L +#define STATUS_NO_MORE_FILES 0x80000006L +#define STATUS_WARNING (ULONG)0x80000000 +#define STATUS_ERROR (ULONG)0xc0000000 + +//for Disposition,ShareAccess,DesiredAccess,CreateOptions Please reference Winddows API CreateFile +//http://msdn.microsoft.com/en-us/library/aa363858%28v=vs.85%29.aspx + +typedef enum Disposition +{ + FILE_SUPERSEDE = 0, + FILE_OPEN, + FILE_CREATE, + FILE_OPEN_IF, + FILE_OVERWRITE, + FILE_OVERWRITE_IF, +}; + +typedef enum ShareAccess +{ + SHARE_READ = 1, + SHARE_WRITE = 2, + SHARE_READ_WRITE = 3, + SHARE_DELETE = 4, + SHARE_READ_DELETE = 5, + SHARE_WRITE_DELETE = 6, + SHARE_READ_WRITE_DELETE = 7, +}; + +typedef enum CreateOptions +{ + FILE_DIRECTORY_FILE = 0x00000001, + FILE_WRITE_THROUGH = 0x00000002, + FILE_SEQUENTIAL_ONLY = 0x00000004, + FILE_NO_INTERMEDIATE_BUFFERING = 0x00000008, + FILE_SYNCHRONOUS_IO_ALERT = 0x00000010, + FILE_SYNCHRONOUS_IO_NONALERT = 0x00000020, + FILE_NON_DIRECTORY_FILE = 0x00000040, + FILE_CREATE_TREE_CONNECTION = 0x00000080, + FILE_COMPLETE_IF_OPLOCKED = 0x00000100, + FILE_NO_EA_KNOWLEDGE = 0x00000200, + FILE_OPEN_REMOTE_INSTANCE = 0x00000400, + FILE_RANDOM_ACCESS = 0x00000800, + FILE_DELETE_ON_CLOSE = 0x00001000, + FILE_OPEN_BY_FILE_ID = 0x00002000, + FILE_OPEN_FOR_BACKUP_INTENT = 0x00004000, + FILE_NO_COMPRESSION = 0x00008000, + FILE_OPEN_REQUIRING_OPLOCK = 0x00010000, + FILE_DISALLOW_EXCLUSIVE = 0x00020000, + FILE_RESERVE_OPFILTER = 0x00100000, + FILE_OPEN_REPARSE_POINT = 0x00200000, + FILE_OPEN_NO_RECALL = 0x00400000, + FILE_OPEN_FOR_FREE_SPACE_QUERY = 0x00800000, +}; + +//this is the status for post create request. +typedef enum CreateStatus +{ + FILE_SUPERSEDED = 0x00000000, + FILE_OPENED = 0x00000001, + FILE_CREATED = 0x00000002, + FILE_OVERWRITTEN = 0x00000003, + FILE_EXISTS = 0x00000004, + FILE_DOES_NOT_EXIST = 0x00000005, +}; + +// +// Define the file information class values +// +// WARNING: The order of the following values are assumed by the I/O system. +// Any changes made here should be reflected there as well. +// + +typedef enum _FILE_INFORMATION_CLASS { + FileDirectoryInformation = 1, + FileFullDirectoryInformation, // 2 + FileBothDirectoryInformation, // 3 + FileBasicInformation, // 4 + FileStandardInformation, // 5 + FileInternalInformation, // 6 + FileEaInformation, // 7 + FileAccessInformation, // 8 + FileNameInformation, // 9 + FileRenameInformation, // 10 + FileLinkInformation, // 11 + FileNamesInformation, // 12 + FileDispositionInformation, // 13 + FilePositionInformation, // 14 + FileFullEaInformation, // 15 + FileModeInformation, // 16 + FileAlignmentInformation, // 17 + FileAllInformation, // 18 + FileAllocationInformation, // 19 + FileEndOfFileInformation, // 20 + FileAlternateNameInformation, // 21 + FileStreamInformation, // 22 + FilePipeInformation, // 23 + FilePipeLocalInformation, // 24 + FilePipeRemoteInformation, // 25 + FileMailslotQueryInformation, // 26 + FileMailslotSetInformation, // 27 + FileCompressionInformation, // 28 + FileObjectIdInformation, // 29 + FileCompletionInformation, // 30 + FileMoveClusterInformation, // 31 + FileQuotaInformation, // 32 + FileReparsePointInformation, // 33 + FileNetworkOpenInformation, // 34 + FileAttributeTagInformation, // 35 + FileTrackingInformation, // 36 + FileIdBothDirectoryInformation, // 37 + FileIdFullDirectoryInformation, // 38 + FileValidDataLengthInformation, // 39 + FileShortNameInformation, // 40 + FileIoCompletionNotificationInformation, // 41 + FileIoStatusBlockRangeInformation, // 42 + FileIoPriorityHintInformation, // 43 + FileSfioReserveInformation, // 44 + FileSfioVolumeInformation, // 45 + FileHardLinkInformation, // 46 + FileProcessIdsUsingFileInformation, // 47 + FileNormalizedNameInformation, // 48 + FileNetworkPhysicalNameInformation, // 49 + FileIdGlobalTxDirectoryInformation, // 50 + FileIsRemoteDeviceInformation, // 51 + FileUnusedInformation, // 52 + FileNumaNodeInformation, // 53 + FileStandardLinkInformation, // 54 + FileRemoteProtocolInformation, // 55 + + // + // These are special versions of these operations (defined earlier) + // which can be used by kernel mode drivers only to bypass security + // access checks for Rename and HardLink operations. These operations + // are only recognized by the IOManager, a file system should never + // receive these. + // + + FileRenameInformationBypassAccessCheck, // 56 + FileLinkInformationBypassAccessCheck, // 57 + + // + // End of special information classes reserved for IOManager. + // + + FileVolumeNameInformation, // 58 + FileIdInformation, // 59 + FileIdExtdDirectoryInformation, // 60 + FileReplaceCompletionInformation, // 61 + FileHardLinkFullIdInformation, // 62 + FileIdExtdBothDirectoryInformation, // 63 + FileDispositionInformationEx, // 64 + FileRenameInformationEx, // 65 + FileRenameInformationExBypassAccessCheck, // 66 + FileDesiredStorageClassInformation, // 67 + FileStatInformation, // 68 + FileMemoryPartitionInformation, // 69 + FileStatLxInformation, // 70 + FileCaseSensitiveInformation, // 71 + FileLinkInformationEx, // 72 + FileLinkInformationExBypassAccessCheck, // 73 + FileStorageReserveIdInformation, // 74 + FileCaseSensitiveInformationForceAccessCheck, // 75 + FileKnownFolderInformation, // 76 + + FileMaximumInformation +} FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS; + +// +// Define the various structures which are returned on query operations +// + +typedef struct _FILE_BASIC_INFORMATION { + LARGE_INTEGER CreationTime; + LARGE_INTEGER LastAccessTime; + LARGE_INTEGER LastWriteTime; + LARGE_INTEGER ChangeTime; + ULONG FileAttributes; +} FILE_BASIC_INFORMATION, *PFILE_BASIC_INFORMATION; + +typedef struct _FILE_STANDARD_INFORMATION { + LARGE_INTEGER AllocationSize; + LARGE_INTEGER EndOfFile; + ULONG NumberOfLinks; + BOOLEAN DeletePending; + BOOLEAN Directory; +} FILE_STANDARD_INFORMATION, *PFILE_STANDARD_INFORMATION; + + +typedef struct _FILE_POSITION_INFORMATION { + LARGE_INTEGER CurrentByteOffset; +} FILE_POSITION_INFORMATION, *PFILE_POSITION_INFORMATION; + + +typedef struct _FILE_NETWORK_OPEN_INFORMATION { + LARGE_INTEGER CreationTime; + LARGE_INTEGER LastAccessTime; + LARGE_INTEGER LastWriteTime; + LARGE_INTEGER ChangeTime; + LARGE_INTEGER AllocationSize; + LARGE_INTEGER EndOfFile; + ULONG FileAttributes; +} FILE_NETWORK_OPEN_INFORMATION, *PFILE_NETWORK_OPEN_INFORMATION; + + + +// +// NtQueryDirectoryFile return types: +// +// FILE_DIRECTORY_INFORMATION +// FILE_FULL_DIR_INFORMATION +// FILE_ID_FULL_DIR_INFORMATION +// FILE_BOTH_DIR_INFORMATION +// FILE_ID_BOTH_DIR_INFORMATION +// FILE_NAMES_INFORMATION +// FILE_OBJECTID_INFORMATION +// + +typedef struct _FILE_DIRECTORY_INFORMATION { + ULONG NextEntryOffset; + ULONG FileIndex; + LARGE_INTEGER CreationTime; + LARGE_INTEGER LastAccessTime; + LARGE_INTEGER LastWriteTime; + LARGE_INTEGER ChangeTime; + LARGE_INTEGER EndOfFile; + LARGE_INTEGER AllocationSize; + ULONG FileAttributes; + ULONG FileNameLength; + WCHAR FileName[1]; +} FILE_DIRECTORY_INFORMATION, *PFILE_DIRECTORY_INFORMATION; + +typedef struct _FILE_FULL_DIR_INFORMATION { + ULONG NextEntryOffset; + ULONG FileIndex; + LARGE_INTEGER CreationTime; + LARGE_INTEGER LastAccessTime; + LARGE_INTEGER LastWriteTime; + LARGE_INTEGER ChangeTime; + LARGE_INTEGER EndOfFile; + LARGE_INTEGER AllocationSize; + ULONG FileAttributes; + ULONG FileNameLength; + ULONG EaSize; + WCHAR FileName[1]; +} FILE_FULL_DIR_INFORMATION, *PFILE_FULL_DIR_INFORMATION; + +typedef struct _FILE_ID_FULL_DIR_INFORMATION { + ULONG NextEntryOffset; + ULONG FileIndex; + LARGE_INTEGER CreationTime; + LARGE_INTEGER LastAccessTime; + LARGE_INTEGER LastWriteTime; + LARGE_INTEGER ChangeTime; + LARGE_INTEGER EndOfFile; + LARGE_INTEGER AllocationSize; + ULONG FileAttributes; + ULONG FileNameLength; + ULONG EaSize; + LARGE_INTEGER FileId; + WCHAR FileName[1]; +} FILE_ID_FULL_DIR_INFORMATION, *PFILE_ID_FULL_DIR_INFORMATION; + +typedef struct _FILE_BOTH_DIR_INFORMATION { + ULONG NextEntryOffset; + ULONG FileIndex; + LARGE_INTEGER CreationTime; + LARGE_INTEGER LastAccessTime; + LARGE_INTEGER LastWriteTime; + LARGE_INTEGER ChangeTime; + LARGE_INTEGER EndOfFile; + LARGE_INTEGER AllocationSize; + ULONG FileAttributes; + ULONG FileNameLength; + ULONG EaSize; + CCHAR ShortNameLength; + WCHAR ShortName[12]; + WCHAR FileName[1]; +} FILE_BOTH_DIR_INFORMATION, *PFILE_BOTH_DIR_INFORMATION; + +typedef struct _FILE_ID_BOTH_DIR_INFORMATION { + ULONG NextEntryOffset; + ULONG FileIndex; + LARGE_INTEGER CreationTime; + LARGE_INTEGER LastAccessTime; + LARGE_INTEGER LastWriteTime; + LARGE_INTEGER ChangeTime; + LARGE_INTEGER EndOfFile; + LARGE_INTEGER AllocationSize; + ULONG FileAttributes; + ULONG FileNameLength; + ULONG EaSize; + CCHAR ShortNameLength; + WCHAR ShortName[12]; + LARGE_INTEGER FileId; + WCHAR FileName[1]; +} FILE_ID_BOTH_DIR_INFORMATION, *PFILE_ID_BOTH_DIR_INFORMATION; + +typedef struct _FILE_NAMES_INFORMATION { + ULONG NextEntryOffset; + ULONG FileIndex; + ULONG FileNameLength; + WCHAR FileName[1]; +} FILE_NAMES_INFORMATION, *PFILE_NAMES_INFORMATION; + +typedef struct _FILE_ID_GLOBAL_TX_DIR_INFORMATION { + ULONG NextEntryOffset; + ULONG FileIndex; + LARGE_INTEGER CreationTime; + LARGE_INTEGER LastAccessTime; + LARGE_INTEGER LastWriteTime; + LARGE_INTEGER ChangeTime; + LARGE_INTEGER EndOfFile; + LARGE_INTEGER AllocationSize; + ULONG FileAttributes; + ULONG FileNameLength; + LARGE_INTEGER FileId; + GUID LockingTransactionId; + ULONG TxInfoFlags; + WCHAR FileName[1]; +} FILE_ID_GLOBAL_TX_DIR_INFORMATION, *PFILE_ID_GLOBAL_TX_DIR_INFORMATION; + + + +#endif \ No newline at end of file diff --git a/Demo_Source_Code/CPlusPlusDemo/WindowsService.cpp b/Demo_Source_Code/CPlusPlusDemo/WindowsService.cpp new file mode 100644 index 0000000..555c732 --- /dev/null +++ b/Demo_Source_Code/CPlusPlusDemo/WindowsService.cpp @@ -0,0 +1,238 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +// + +#include "stdafx.h" +#include "Tools.h" +#include "FilterAPI.h" +#include "WindowsService.h" +#include "FilterControl.h" +#include "FilterRule.h" + +#define SERVICE_NAME _T("EaseFilter Service") + +SERVICE_STATUS g_ServiceStatus = {0}; +SERVICE_STATUS_HANDLE g_StatusHandle = NULL; +HANDLE g_ServiceStopEvent = INVALID_HANDLE_VALUE; + + +int StartWindowsService() +{ + OutputDebugString(_T("EaseFilter Service: Main: Entry")); + + SERVICE_TABLE_ENTRY ServiceTable[] = + { + {SERVICE_NAME, (LPSERVICE_MAIN_FUNCTION) ServiceMain}, + {NULL, NULL} + }; + + if (StartServiceCtrlDispatcher (ServiceTable) == FALSE) + { + OutputDebugString(_T("EaseFilter Service: Main: StartServiceCtrlDispatcher returned error")); + return GetLastError (); + } + + OutputDebugString(_T("EaseFilter Service: Main: Exit")); + return 0; +} + + +VOID WINAPI ServiceMain (DWORD argc, LPTSTR *argv) +{ + DWORD Status = E_FAIL; + + OutputDebugString(_T("EaseFilter Service: ServiceMain: Entry")); + + g_StatusHandle = RegisterServiceCtrlHandler (SERVICE_NAME, ServiceCtrlHandler); + + if (g_StatusHandle == NULL) + { + OutputDebugString(_T("EaseFilter Service: ServiceMain: RegisterServiceCtrlHandler returned error")); + goto EXIT; + } + + // Tell the service controller we are starting + ZeroMemory (&g_ServiceStatus, sizeof (g_ServiceStatus)); + g_ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; + g_ServiceStatus.dwControlsAccepted = 0; + g_ServiceStatus.dwCurrentState = SERVICE_START_PENDING; + g_ServiceStatus.dwWin32ExitCode = 0; + g_ServiceStatus.dwServiceSpecificExitCode = 0; + g_ServiceStatus.dwCheckPoint = 0; + + if (SetServiceStatus (g_StatusHandle, &g_ServiceStatus) == FALSE) + { + OutputDebugString(_T("EaseFilter Service: ServiceMain: SetServiceStatus returned error")); + } + + /* + * Perform tasks neccesary to start the service here + */ + OutputDebugString(_T("EaseFilter Service: ServiceMain: Performing Service Start Operations")); + + // Create stop event to wait on later. + g_ServiceStopEvent = CreateEvent (NULL, TRUE, FALSE, NULL); + if (g_ServiceStopEvent == NULL) + { + OutputDebugString(_T("EaseFilter Service: ServiceMain: CreateEvent(g_ServiceStopEvent) returned error")); + + g_ServiceStatus.dwControlsAccepted = 0; + g_ServiceStatus.dwCurrentState = SERVICE_STOPPED; + g_ServiceStatus.dwWin32ExitCode = GetLastError(); + g_ServiceStatus.dwCheckPoint = 1; + + if (SetServiceStatus (g_StatusHandle, &g_ServiceStatus) == FALSE) + { + OutputDebugString(_T("EaseFilter Service: ServiceMain: SetServiceStatus returned error")); + } + goto EXIT; + } + + // Tell the service controller we are started + g_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP; + g_ServiceStatus.dwCurrentState = SERVICE_RUNNING; + g_ServiceStatus.dwWin32ExitCode = 0; + g_ServiceStatus.dwCheckPoint = 0; + + if (SetServiceStatus (g_StatusHandle, &g_ServiceStatus) == FALSE) + { + OutputDebugString(_T("EaseFilter Service: ServiceMain: SetServiceStatus returned error")); + } + + // Start the thread that will perform the main task of the service + HANDLE hThread = CreateThread (NULL, 0, ServiceWorkerThread, NULL, 0, NULL); + + OutputDebugString(_T("EaseFilter Service: ServiceMain: Waiting for Worker Thread to complete")); + + // Wait until our worker thread exits effectively signaling that the service needs to stop + WaitForSingleObject (hThread, INFINITE); + + OutputDebugString(_T("EaseFilter Service: ServiceMain: Worker Thread Stop Event signaled")); + + + /* + * Perform any cleanup tasks + */ + OutputDebugString(_T("EaseFilter Service: ServiceMain: Performing Cleanup Operations")); + + CloseHandle (g_ServiceStopEvent); + + g_ServiceStatus.dwControlsAccepted = 0; + g_ServiceStatus.dwCurrentState = SERVICE_STOPPED; + g_ServiceStatus.dwWin32ExitCode = 0; + g_ServiceStatus.dwCheckPoint = 3; + + if (SetServiceStatus (g_StatusHandle, &g_ServiceStatus) == FALSE) + { + OutputDebugString(_T("EaseFilter Service: ServiceMain: SetServiceStatus returned error")); + } + + EXIT: + OutputDebugString(_T("EaseFilter Service: ServiceMain: Exit")); + + return; +} + + +VOID WINAPI ServiceCtrlHandler (DWORD CtrlCode) +{ + OutputDebugString(_T("EaseFilter Service: ServiceCtrlHandler: Entry")); + + switch (CtrlCode) + { + case SERVICE_CONTROL_STOP : + + OutputDebugString(_T("EaseFilter Service: ServiceCtrlHandler: SERVICE_CONTROL_STOP Request")); + + if (g_ServiceStatus.dwCurrentState != SERVICE_RUNNING) + break; + + /* + * Perform tasks neccesary to stop the service here + */ + + g_ServiceStatus.dwControlsAccepted = 0; + g_ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING; + g_ServiceStatus.dwWin32ExitCode = 0; + g_ServiceStatus.dwCheckPoint = 4; + + if (SetServiceStatus (g_StatusHandle, &g_ServiceStatus) == FALSE) + { + OutputDebugString(_T("EaseFilter Service: ServiceCtrlHandler: SetServiceStatus returned error")); + } + + // This will signal the worker thread to start shutting down + SetEvent (g_ServiceStopEvent); + + break; + + default: + break; + } + + OutputDebugString(_T("EaseFilter Service: ServiceCtrlHandler: Exit")); +} + + +DWORD WINAPI ServiceWorkerThread (LPVOID lpParam) +{ + OutputDebugString(_T("EaseFilter Service: ServiceWorkerThread: Entry")); + + FilterControl* filterControl = FilterControl::GetSingleInstance(); + + // Periodically check if the service has been requested to stop + while (WaitForSingleObject(g_ServiceStopEvent, 0) != WAIT_OBJECT_0) + { + BOOL ret = FALSE; + DWORD threadCount = 5; + DWORD connectionTimeout = 20; + ULONG filterType = FILE_SYSTEM_MONITOR; + + ULONG allPostIO = POST_CREATE|POST_FASTIO_READ|POST_CACHE_READ|POST_NOCACHE_READ|POST_PAGING_IO_READ; + allPostIO |= POST_FASTIO_WRITE|POST_CACHE_WRITE|POST_NOCACHE_WRITE|POST_PAGING_IO_WRITE|POST_QUERY_INFORMATION; + allPostIO |= POST_SET_INFORMATION|POST_DIRECTORY|POST_QUERY_SECURITY|POST_SET_SECURITY|POST_CLEANUP|POST_CLOSE; + + WCHAR* fileFilterMask = L"c:\\test\\*"; + ULONG ioCallbackClass = allPostIO; + ULONG accessFlag = ALLOW_MAX_RIGHT_ACCESS; + + FileFilterRule fileFilterRule(fileFilterMask); + fileFilterRule.AccessFlag = accessFlag; + fileFilterRule.FileChangeEventFilter = FILE_WAS_CREATED|FILE_WAS_WRITTEN|FILE_WAS_RENAMED|FILE_WAS_DELETED; + fileFilterRule.MonitorFileIOEventFilter = ioCallbackClass; + + filterControl->AddFileFilter(fileFilterRule); + filterControl->StartFilter(filterType,threadCount,connectionTimeout,registerKey); + + //prevent the current process from being terminated. + //AddProtectedProcessId(GetCurrentProcessId()); + + system("pause"); + + //the process can be termiated now. + //RemoveProtectedProcessId(GetCurrentProcessId()); + + } + + filterControl->StopFilter(); + delete filterControl; + + OutputDebugString(_T("EaseFilter Service: ServiceWorkerThread: Exit")); + + return ERROR_SUCCESS; +} \ No newline at end of file diff --git a/Demo_Source_Code/CPlusPlusDemo/WindowsService.h b/Demo_Source_Code/CPlusPlusDemo/WindowsService.h new file mode 100644 index 0000000..695a974 --- /dev/null +++ b/Demo_Source_Code/CPlusPlusDemo/WindowsService.h @@ -0,0 +1,4 @@ +int StartWindowsService(); +VOID WINAPI ServiceMain (DWORD argc, LPTSTR *argv); +VOID WINAPI ServiceCtrlHandler (DWORD); +DWORD WINAPI ServiceWorkerThread (LPVOID lpParam); \ No newline at end of file diff --git a/Demo_Source_Code/CPlusPlusDemo/resource.h b/Demo_Source_Code/CPlusPlusDemo/resource.h new file mode 100644 index 0000000..b273dd9 --- /dev/null +++ b/Demo_Source_Code/CPlusPlusDemo/resource.h @@ -0,0 +1,14 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by CPlusPlusDemo.rc + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 101 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/Demo_Source_Code/CPlusPlusDemo/stdafx.cpp b/Demo_Source_Code/CPlusPlusDemo/stdafx.cpp new file mode 100644 index 0000000..66f9cae --- /dev/null +++ b/Demo_Source_Code/CPlusPlusDemo/stdafx.cpp @@ -0,0 +1,8 @@ +// stdafx.cpp : source file that includes just the standard includes +// CPlusPlusDemo.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file diff --git a/Demo_Source_Code/CPlusPlusDemo/stdafx.h b/Demo_Source_Code/CPlusPlusDemo/stdafx.h new file mode 100644 index 0000000..13f7c57 --- /dev/null +++ b/Demo_Source_Code/CPlusPlusDemo/stdafx.h @@ -0,0 +1,19 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#pragma once + +#include "targetver.h" +#include +#include +#include +#include +#include +#include +#include + + + +// TODO: reference additional headers your program requires here diff --git a/Demo_Source_Code/CPlusPlusDemo/targetver.h b/Demo_Source_Code/CPlusPlusDemo/targetver.h new file mode 100644 index 0000000..6fe8eb7 --- /dev/null +++ b/Demo_Source_Code/CPlusPlusDemo/targetver.h @@ -0,0 +1,13 @@ +#pragma once + +// The following macros define the minimum required platform. The minimum required platform +// is the earliest version of Windows, Internet Explorer etc. that has the necessary features to run +// your application. The macros work by enabling all features available on platform versions up to and +// including the version specified. + +// Modify the following defines if you have to target a platform prior to the ones specified below. +// Refer to MSDN for the latest info on corresponding values for different platforms. +#ifndef _WIN32_WINNT // Specifies that the minimum required platform is Windows Vista. +#define _WIN32_WINNT 0x0600 // Change this to the appropriate value to target other versions of Windows. +#endif + diff --git a/Demo_Source_Code/CSharpDemo/AutoEncryptDemo/AutoEncryptDemo.csproj b/Demo_Source_Code/CSharpDemo/AutoEncryptDemo/AutoEncryptDemo.csproj new file mode 100644 index 0000000..92bfb98 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/AutoEncryptDemo/AutoEncryptDemo.csproj @@ -0,0 +1,157 @@ + + + + Debug + x86 + 8.0.30703 + 2.0 + {89B88C2F-1FF5-4D84-A010-6BF74436576B} + WinExe + Properties + AutoEncryptDemo + AutoEncryptDemo + v4.5 + + + 512 + SAK + SAK + SAK + SAK + + + AnyCPU + true + full + false + ..\..\Release\ + DEBUG;TRACE + prompt + 4 + false + + + AnyCPU + pdbonly + true + ..\..\Release\ + TRACE + prompt + 4 + false + + + app.manifest + + + true + ..\..\Release\ + DEBUG;TRACE + full + AnyCPU + ..\..\Release\AutoEncryptDemo.exe.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + false + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false + false + + + ..\..\Release\ + TRACE + true + pdbonly + AnyCPU + ..\..\Release\AutoEncryptDemo.exe.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + false + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false + false + false + + + + + + + + + + + + + + + + Form + + + AutoEncryptForm.cs + + + + + + Form + + + DRMForm.cs + + + AutoEncryptForm.cs + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + True + Resources.resx + True + + + DRMForm.cs + + + + Designer + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + + + {34CB783E-DDA2-4CE3-80BC-37B25AA33E5F} + CommonObjects + + + {21540012-A296-45CE-8D35-3EA5A07B32A6} + FilterControl + + + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/AutoEncryptDemo/AutoEncryptDemo.csproj.user b/Demo_Source_Code/CSharpDemo/AutoEncryptDemo/AutoEncryptDemo.csproj.user new file mode 100644 index 0000000..857d784 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/AutoEncryptDemo/AutoEncryptDemo.csproj.user @@ -0,0 +1,6 @@ + + + + true + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/AutoEncryptDemo/AutoEncryptDemo.vs2019.csproj b/Demo_Source_Code/CSharpDemo/AutoEncryptDemo/AutoEncryptDemo.vs2019.csproj new file mode 100644 index 0000000..c9a1371 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/AutoEncryptDemo/AutoEncryptDemo.vs2019.csproj @@ -0,0 +1,171 @@ + + + + Debug + x86 + 8.0.30703 + 2.0 + {89B88C2F-1FF5-4D84-A010-6BF74436576B} + WinExe + Properties + AutoEncryptDemo + AutoEncryptDemo + v4.5 + + + 512 + SAK + SAK + SAK + SAK + + + AnyCPU + true + full + false + ..\..\Release\ + DEBUG;TRACE + prompt + 4 + false + + + AnyCPU + pdbonly + true + ..\..\Release\ + TRACE + prompt + 4 + false + + + app.manifest + + + true + bin\Debug\ + DEBUG;TRACE + full + AnyCPU + ..\..\Release\AutoEncryptDemo.exe.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + false + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false + false + + + ..\..\Release\ + TRACE + true + pdbonly + AnyCPU + ..\..\Release\AutoEncryptDemo.exe.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + false + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false + false + false + + + true + bin\ARM64\Debug\ + DEBUG;TRACE + full + ARM64 + 7.3 + prompt + MinimumRecommendedRules.ruleset + false + false + + + bin\ARM64\Release\ + TRACE + true + pdbonly + ARM64 + 7.3 + prompt + MinimumRecommendedRules.ruleset + false + false + + + + + + + + + + + + + + + + Form + + + AutoEncryptForm.cs + + + + + AutoEncryptForm.cs + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + True + Resources.resx + True + + + + Designer + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + + + {34cb783e-dda2-4ce3-80bc-37b25aa33e5f} + CommonObjects.vs2019 + + + {21540012-A296-45CE-8D35-3EA5A07B32A6} + FilterControl.vs2019 + + + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/AutoEncryptDemo/AutoEncryptForm.Designer.cs b/Demo_Source_Code/CSharpDemo/AutoEncryptDemo/AutoEncryptForm.Designer.cs new file mode 100644 index 0000000..4ef084d --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/AutoEncryptDemo/AutoEncryptForm.Designer.cs @@ -0,0 +1,292 @@ +namespace AutoEncryptDemo +{ + partial class AutoEncryptForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(AutoEncryptForm)); + this.button_Start = new System.Windows.Forms.Button(); + this.textBox_EncrptFolder = new System.Windows.Forms.TextBox(); + this.label1 = new System.Windows.Forms.Label(); + this.textBox_AuthorizedProcessesForEncryptFolder = new System.Windows.Forms.TextBox(); + this.button_Stop = new System.Windows.Forms.Button(); + this.textBox_AuthorizedProcessesForDecryptFolder = new System.Windows.Forms.TextBox(); + this.label4 = new System.Windows.Forms.Label(); + this.textBox_DecryptFolder = new System.Windows.Forms.TextBox(); + this.label2 = new System.Windows.Forms.Label(); + this.label3 = new System.Windows.Forms.Label(); + this.label5 = new System.Windows.Forms.Label(); + this.textBox_PassPhrase = new System.Windows.Forms.TextBox(); + this.label6 = new System.Windows.Forms.Label(); + this.textBox_AuthorizedUsersForEncryptFolder = new System.Windows.Forms.TextBox(); + this.checkBox_EnableEncryptionWithDRM = new System.Windows.Forms.CheckBox(); + this.button_EncryptFolder = new System.Windows.Forms.Button(); + this.button_DRMSetting = new System.Windows.Forms.Button(); + this.menuStrip1 = new System.Windows.Forms.MenuStrip(); + this.getTagDataOfEncryptedFileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.helpToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.menuStrip1.SuspendLayout(); + this.SuspendLayout(); + // + // button_Start + // + this.button_Start.Location = new System.Drawing.Point(31, 372); + this.button_Start.Name = "button_Start"; + this.button_Start.Size = new System.Drawing.Size(86, 23); + this.button_Start.TabIndex = 0; + this.button_Start.Text = "Start Service"; + this.button_Start.UseVisualStyleBackColor = true; + this.button_Start.Click += new System.EventHandler(this.button_Start_Click); + // + // textBox_EncrptFolder + // + this.textBox_EncrptFolder.Location = new System.Drawing.Point(34, 51); + this.textBox_EncrptFolder.Name = "textBox_EncrptFolder"; + this.textBox_EncrptFolder.Size = new System.Drawing.Size(320, 20); + this.textBox_EncrptFolder.TabIndex = 1; + this.textBox_EncrptFolder.Text = "c:\\AutoEncryptFolder\\*"; + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(34, 35); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(184, 13); + this.label1.TabIndex = 2; + this.label1.Text = "Auto Encryption Folder In Computer A"; + // + // textBox_AuthorizedProcessesForEncryptFolder + // + this.textBox_AuthorizedProcessesForEncryptFolder.Location = new System.Drawing.Point(34, 97); + this.textBox_AuthorizedProcessesForEncryptFolder.Name = "textBox_AuthorizedProcessesForEncryptFolder"; + this.textBox_AuthorizedProcessesForEncryptFolder.Size = new System.Drawing.Size(320, 20); + this.textBox_AuthorizedProcessesForEncryptFolder.TabIndex = 3; + this.textBox_AuthorizedProcessesForEncryptFolder.Text = "notepad.exe;wordpad.exe"; + // + // button_Stop + // + this.button_Stop.Location = new System.Drawing.Point(267, 372); + this.button_Stop.Name = "button_Stop"; + this.button_Stop.Size = new System.Drawing.Size(87, 23); + this.button_Stop.TabIndex = 5; + this.button_Stop.Text = "Stop Service"; + this.button_Stop.UseVisualStyleBackColor = true; + this.button_Stop.Click += new System.EventHandler(this.button_Stop_Click); + // + // textBox_AuthorizedProcessesForDecryptFolder + // + this.textBox_AuthorizedProcessesForDecryptFolder.Location = new System.Drawing.Point(34, 336); + this.textBox_AuthorizedProcessesForDecryptFolder.Name = "textBox_AuthorizedProcessesForDecryptFolder"; + this.textBox_AuthorizedProcessesForDecryptFolder.Size = new System.Drawing.Size(320, 20); + this.textBox_AuthorizedProcessesForDecryptFolder.TabIndex = 6; + this.textBox_AuthorizedProcessesForDecryptFolder.Text = "notepad.exe;wordpad.exe"; + // + // label4 + // + this.label4.AutoSize = true; + this.label4.Location = new System.Drawing.Point(34, 81); + this.label4.Name = "label4"; + this.label4.Size = new System.Drawing.Size(324, 13); + this.label4.TabIndex = 9; + this.label4.Text = "Authorized Processes To Decrypt Files (* or empty for all processes)"; + // + // textBox_DecryptFolder + // + this.textBox_DecryptFolder.Location = new System.Drawing.Point(34, 285); + this.textBox_DecryptFolder.Name = "textBox_DecryptFolder"; + this.textBox_DecryptFolder.Size = new System.Drawing.Size(320, 20); + this.textBox_DecryptFolder.TabIndex = 8; + this.textBox_DecryptFolder.Text = "c:\\EncryptedFolder\\*"; + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(28, 269); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(335, 13); + this.label2.TabIndex = 10; + this.label2.Text = "Encryption Folder In Computer B ( Use Explorer to copy encrypted file)"; + // + // label3 + // + this.label3.AutoSize = true; + this.label3.Location = new System.Drawing.Point(28, 320); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(189, 13); + this.label3.TabIndex = 11; + this.label3.Text = "Authorized Processes To Decrypt Files"; + // + // label5 + // + this.label5.AutoSize = true; + this.label5.Location = new System.Drawing.Point(34, 205); + this.label5.Name = "label5"; + this.label5.Size = new System.Drawing.Size(258, 13); + this.label5.TabIndex = 13; + this.label5.Text = "PassPhrase (must be the same for computer A and B)"; + // + // textBox_PassPhrase + // + this.textBox_PassPhrase.Location = new System.Drawing.Point(34, 221); + this.textBox_PassPhrase.Name = "textBox_PassPhrase"; + this.textBox_PassPhrase.Size = new System.Drawing.Size(320, 20); + this.textBox_PassPhrase.TabIndex = 12; + this.textBox_PassPhrase.Text = "your password"; + // + // label6 + // + this.label6.AutoSize = true; + this.label6.Location = new System.Drawing.Point(34, 125); + this.label6.Name = "label6"; + this.label6.Size = new System.Drawing.Size(267, 13); + this.label6.TabIndex = 15; + this.label6.Text = "Authorized Users To Decrypt Files (domain\\usename1)"; + // + // textBox_AuthorizedUsersForEncryptFolder + // + this.textBox_AuthorizedUsersForEncryptFolder.Location = new System.Drawing.Point(34, 141); + this.textBox_AuthorizedUsersForEncryptFolder.Name = "textBox_AuthorizedUsersForEncryptFolder"; + this.textBox_AuthorizedUsersForEncryptFolder.Size = new System.Drawing.Size(320, 20); + this.textBox_AuthorizedUsersForEncryptFolder.TabIndex = 14; + // + // checkBox_EnableEncryptionWithDRM + // + this.checkBox_EnableEncryptionWithDRM.AutoSize = true; + this.checkBox_EnableEncryptionWithDRM.Location = new System.Drawing.Point(34, 176); + this.checkBox_EnableEncryptionWithDRM.Name = "checkBox_EnableEncryptionWithDRM"; + this.checkBox_EnableEncryptionWithDRM.Size = new System.Drawing.Size(15, 14); + this.checkBox_EnableEncryptionWithDRM.TabIndex = 16; + this.checkBox_EnableEncryptionWithDRM.UseVisualStyleBackColor = true; + this.checkBox_EnableEncryptionWithDRM.CheckedChanged += new System.EventHandler(this.checkBox_EnableEncryptionWithDRM_CheckedChanged); + // + // button_EncryptFolder + // + this.button_EncryptFolder.Location = new System.Drawing.Point(364, 49); + this.button_EncryptFolder.Name = "button_EncryptFolder"; + this.button_EncryptFolder.Size = new System.Drawing.Size(26, 23); + this.button_EncryptFolder.TabIndex = 17; + this.button_EncryptFolder.Text = "..."; + this.button_EncryptFolder.UseVisualStyleBackColor = true; + this.button_EncryptFolder.Click += new System.EventHandler(this.button_EncryptFolder_Click); + // + // button_DRMSetting + // + this.button_DRMSetting.Enabled = false; + this.button_DRMSetting.Location = new System.Drawing.Point(55, 171); + this.button_DRMSetting.Name = "button_DRMSetting"; + this.button_DRMSetting.Size = new System.Drawing.Size(299, 23); + this.button_DRMSetting.TabIndex = 18; + this.button_DRMSetting.Text = "Enable DRM For Encrypted File Settings"; + this.button_DRMSetting.TextAlign = System.Drawing.ContentAlignment.TopLeft; + this.button_DRMSetting.UseVisualStyleBackColor = true; + this.button_DRMSetting.Click += new System.EventHandler(this.button_DRMSetting_Click); + // + // menuStrip1 + // + this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.getTagDataOfEncryptedFileToolStripMenuItem, + this.helpToolStripMenuItem}); + this.menuStrip1.Location = new System.Drawing.Point(0, 0); + this.menuStrip1.Name = "menuStrip1"; + this.menuStrip1.Size = new System.Drawing.Size(402, 24); + this.menuStrip1.TabIndex = 21; + this.menuStrip1.Text = "menuStrip1"; + // + // getTagDataOfEncryptedFileToolStripMenuItem + // + this.getTagDataOfEncryptedFileToolStripMenuItem.Name = "getTagDataOfEncryptedFileToolStripMenuItem"; + this.getTagDataOfEncryptedFileToolStripMenuItem.Size = new System.Drawing.Size(158, 20); + this.getTagDataOfEncryptedFileToolStripMenuItem.Text = "Get encrypted file tag data"; + this.getTagDataOfEncryptedFileToolStripMenuItem.Click += new System.EventHandler(this.getTagDataOfEncryptedFileToolStripMenuItem_Click); + // + // helpToolStripMenuItem + // + this.helpToolStripMenuItem.Name = "helpToolStripMenuItem"; + this.helpToolStripMenuItem.Size = new System.Drawing.Size(44, 20); + this.helpToolStripMenuItem.Text = "Help"; + this.helpToolStripMenuItem.Click += new System.EventHandler(this.helpToolStripMenuItem_Click); + // + // AutoEncryptForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(402, 410); + this.Controls.Add(this.button_DRMSetting); + this.Controls.Add(this.button_EncryptFolder); + this.Controls.Add(this.checkBox_EnableEncryptionWithDRM); + this.Controls.Add(this.label6); + this.Controls.Add(this.textBox_AuthorizedUsersForEncryptFolder); + this.Controls.Add(this.label5); + this.Controls.Add(this.textBox_PassPhrase); + this.Controls.Add(this.label3); + this.Controls.Add(this.label2); + this.Controls.Add(this.label4); + this.Controls.Add(this.textBox_DecryptFolder); + this.Controls.Add(this.textBox_AuthorizedProcessesForDecryptFolder); + this.Controls.Add(this.button_Stop); + this.Controls.Add(this.textBox_AuthorizedProcessesForEncryptFolder); + this.Controls.Add(this.label1); + this.Controls.Add(this.textBox_EncrptFolder); + this.Controls.Add(this.button_Start); + this.Controls.Add(this.menuStrip1); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.MainMenuStrip = this.menuStrip1; + this.Name = "AutoEncryptForm"; + this.Text = "Auto File DRM Encryption Tool"; + this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.AutoEncryptForm_FormClosing); + this.menuStrip1.ResumeLayout(false); + this.menuStrip1.PerformLayout(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Button button_Start; + private System.Windows.Forms.TextBox textBox_EncrptFolder; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.TextBox textBox_AuthorizedProcessesForEncryptFolder; + private System.Windows.Forms.Button button_Stop; + private System.Windows.Forms.TextBox textBox_AuthorizedProcessesForDecryptFolder; + private System.Windows.Forms.Label label4; + private System.Windows.Forms.TextBox textBox_DecryptFolder; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.Label label5; + private System.Windows.Forms.TextBox textBox_PassPhrase; + private System.Windows.Forms.Label label6; + private System.Windows.Forms.TextBox textBox_AuthorizedUsersForEncryptFolder; + private System.Windows.Forms.CheckBox checkBox_EnableEncryptionWithDRM; + private System.Windows.Forms.Button button_EncryptFolder; + private System.Windows.Forms.Button button_DRMSetting; + private System.Windows.Forms.MenuStrip menuStrip1; + private System.Windows.Forms.ToolStripMenuItem helpToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem getTagDataOfEncryptedFileToolStripMenuItem; + } +} + diff --git a/Demo_Source_Code/CSharpDemo/AutoEncryptDemo/AutoEncryptForm.cs b/Demo_Source_Code/CSharpDemo/AutoEncryptDemo/AutoEncryptForm.cs new file mode 100644 index 0000000..a9d5276 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/AutoEncryptDemo/AutoEncryptForm.cs @@ -0,0 +1,388 @@ +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; + +using EaseFilter.CommonObjects; +using EaseFilter.FilterControl; + +namespace AutoEncryptDemo +{ + public partial class AutoEncryptForm : Form + { + + static FilterControl filterControl = new FilterControl(); + + public AutoEncryptForm() + { + InitializeComponent(); + } + + ~AutoEncryptForm() + { + GlobalConfig.Stop(); + filterControl.StopFilter(); + } + + private void button_Start_Click(object sender, EventArgs e) + { + + //Purchase a license key with the link: http://www.easefilter.com/Order.htm + //Email us to request a trial key: info@easefilter.com //free email is not accepted. + string licenseKey = GlobalConfig.LicenseKey; + + GlobalConfig.filterType = FilterAPI.FilterType.CONTROL_FILTER | FilterAPI.FilterType.ENCRYPTION_FILTER | FilterAPI.FilterType.PROCESS_FILTER; + + bool ret = false; + + string lastError = string.Empty; + + try + { + ret = filterControl.StartFilter(GlobalConfig.filterType, GlobalConfig.FilterConnectionThreads, GlobalConfig.ConnectionTimeOut, licenseKey, ref lastError); + if (!ret) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("StartFilter failed with error:" + lastError, "StartFilter", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + EventManager.WriteMessage(102, "StartFilter", EventLevel.Information, "Start filter service succeeded."); + + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("Start filter service succeeded.", "StartFilter", MessageBoxButtons.OK, MessageBoxIcon.Information); + + SendConfigToFilter(); + + button_Stop.Enabled = true; + button_Start.Enabled = false; + + } + catch (Exception ex) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("Start filter service failed with error " + ex.Message, "StartFilter", MessageBoxButtons.OK, MessageBoxIcon.Error); + EventManager.WriteMessage(104, "StartFilter", EventLevel.Error, "Start filter service failed with error " + ex.Message); + } + } + + private bool SendConfigToFilter() + { + string lastError = string.Empty; + + string encryptFolder = textBox_EncrptFolder.Text.Trim(); + string authorizedProcessesForEncryptFolder = textBox_AuthorizedProcessesForEncryptFolder.Text; + string authorizedUsersForEncryptFolder = textBox_AuthorizedUsersForEncryptFolder.Text; + + string decryptFolder = textBox_DecryptFolder.Text.Trim(); + string authorizedProcessesForDecryptFolder = textBox_AuthorizedProcessesForDecryptFolder.Text; + + string passPhrase = textBox_PassPhrase.Text.Trim(); + + filterControl.ClearFilters(); + + //setup a file filter rule for folder encryptFolder + if (encryptFolder.IndexOf("*") < 0) + { + //set the file filter mask + encryptFolder += "\\*"; + } + + FileFilter fileFilter = new FileFilter(encryptFolder); + + //enable the encryption for the filter rule. + fileFilter.EnableEncryption = true; + + //if we enable the encryption key from service, you can authorize the encryption or decryption for every file + //in the callback function OnFilterRequestEncryptKey. + fileFilter.EnableEncryptionKeyFromService = checkBox_EnableEncryptionWithDRM.Checked; + fileFilter.OnFilterRequestEncryptKey += OnFilterRequestEncryptKey; + + //get the 256bits encryption key with the passphrase + fileFilter.EncryptionKey = Utils.GetKeyByPassPhrase(passPhrase, 32); + + //disable the decryption right, read the raw encrypted data for all except the authorized processes or users. + fileFilter.EnableReadEncryptedData = false; + + if (textBox_AuthorizedProcessesForEncryptFolder.Text.Trim().Length == 0 || textBox_AuthorizedProcessesForEncryptFolder.Text.Trim().Equals("*")) + { + authorizedProcessesForEncryptFolder = "*"; + + //allow everyone to read the encrypted data by default, except you remove it from the process access right. + fileFilter.EnableReadEncryptedData = true; + } + else + { + string[] processNames = authorizedProcessesForEncryptFolder.Split(new char[] { ';' }); + + if (processNames.Length > 0) + { + foreach (string processName in processNames) + { + if (processName.Trim().Length > 0) + { + //authorized the process with the read encrypted data right. + fileFilter.ProcessNameAccessRightList.Add(processName, FilterAPI.ALLOW_MAX_RIGHT_ACCESS); + } + } + } + + if (!string.IsNullOrEmpty(authorizedUsersForEncryptFolder) && !authorizedUsersForEncryptFolder.Equals("*")) + { + string[] userNames = authorizedUsersForEncryptFolder.Split(new char[] { ';' }); + if (userNames.Length > 0) + { + foreach (string userName in userNames) + { + if (userName.Trim().Length > 0) + { + //authorized the user with the read encrypted data right. + fileFilter.userAccessRightList.Add(userName, FilterAPI.ALLOW_MAX_RIGHT_ACCESS); + } + } + } + + if (fileFilter.userAccessRightList.Count > 0) + { + //set black list for all other users except the white list users. + uint accessFlag = FilterAPI.ALLOW_MAX_RIGHT_ACCESS & ~(uint)FilterAPI.AccessFlag.ALLOW_READ_ENCRYPTED_FILES; + //disable the decryption right, read the raw encrypted data for all except the authorized users. + fileFilter.userAccessRightList.Add("*", accessFlag); + } + } + } + + //add the encryption file filter rule to the filter control + filterControl.AddFilter(fileFilter); + + //setup a file filter rule for folder decryptFolder + if (decryptFolder.IndexOf("*") < 0) + { + //set the file filter mask + decryptFolder += "\\*"; + } + + FileFilter decryptFileFilter = new FileFilter(decryptFolder); + + //enable the encryption for the filter rule. + decryptFileFilter.EnableEncryption = true; + + //if we enable the encryption key from service, you can authorize the decryption for every file + //in the callback function OnFilterRequestEncryptKey. + decryptFileFilter.EnableEncryptionKeyFromService = checkBox_EnableEncryptionWithDRM.Checked; + decryptFileFilter.OnFilterRequestEncryptKey += OnFilterRequestEncryptKey; + + //get the 256bits encryption key with the passphrase + decryptFileFilter.EncryptionKey = Utils.GetKeyByPassPhrase(passPhrase, 32); + + //encrypt the new created file or modification in the folder. + decryptFileFilter.EnableEncryptNewFile = true; + + //this is important if your process will copy the encrypted file to decryption folder, you need to exclude them. + //Exclude Windows explorer.exe process, copy the encrypted file decryption folder with explorer will be excluded, + //so the encrypted file won't be encrypted again. + decryptFileFilter.ExcludeProcessNameList.Add("explorer.exe"); + + //disable the decyrption right, read the raw encrypted data for all except the authorized processes or users. + decryptFileFilter.EnableReadEncryptedData = false; + + string[] processNamesToDecrypt = authorizedProcessesForDecryptFolder.Split(new char[] { ';' }); + if (processNamesToDecrypt.Length > 0) + { + foreach (string processName in processNamesToDecrypt) + { + if (processName.Trim().Length > 0) + { + //authorized the process with the read encrypted data right. + decryptFileFilter.ProcessNameAccessRightList.Add(processName, FilterAPI.ALLOW_MAX_RIGHT_ACCESS); + } + } + } + + filterControl.AddFilter(decryptFileFilter); + + if (!filterControl.SendConfigSettingsToFilter(ref lastError)) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("SendConfigSettingsToFilter failed." + lastError, "SendConfigSettingsToFilter", MessageBoxButtons.OK, MessageBoxIcon.Error); + return false; + } + + return true; + } + + /// + /// Fires this event when the encrypted file requests the encryption key. + /// + public void OnFilterRequestEncryptKey(object sender, EncryptEventArgs e) + { + e.ReturnStatus = NtStatus.Status.Success; + + try + { + if (e.IsNewCreatedFile) + { + byte[] iv = Guid.NewGuid().ToByteArray(); + //for the new created file, you can add your custom tag data to the header of the encyrpted file here. + //here we add the iv to the tag data. + e.EncryptionTag = iv; + + //if you don't set the iv data, the filter driver will generate the new GUID as iv + e.IV = iv; + + //here is the encryption key for the new encrypted file, you can set it with your own custom key. + e.EncryptionKey = Utils.GetKeyByPassPhrase(GlobalConfig.MasterPassword, 32); + + //if you want to block the new file creation, you can return access denied status. + //e.ReturnStatus = NtStatus.Status.AccessDenied; + + //if you want to the file being created without encryption, return below status. + //e.ReturnStatus = NtStatus.Status.FileIsNoEncrypted; + + EventManager.WriteMessage(200, "EncryptNewFile", EventLevel.Information, "embedDRMToFile = " + + DRMServer.embedDRMToFile.ToString() + " for file:" + e.FileName + ",return status:" + e.ReturnStatus.ToString()); + } + else + { + //this is the encrypted file open request, request the encryption key and iv. + //here is the tag data if you set custom tag data when the new created file requested the key. + byte[] tagData = e.EncryptionTag; + + if (!DRMServer.GetEncryptedFileAccessPermission(e)) + { + //here didn't get the permission for the encrypted file open, it will return the raw encrypted data. + e.ReturnStatus = NtStatus.Status.FileIsEncrypted; + } + + //The encryption key must be the same one which you created the new encrypted file. + e.EncryptionKey = Utils.GetKeyByPassPhrase(GlobalConfig.MasterPassword, 32); + + //here is the iv key we saved in tag data. + e.IV = tagData; + + //if you want to block encrypted file being opened, you can return accessdenied status. + //e.ReturnStatus = NtStatus.Status.AccessDenied; + + //if you want to return the raw encrypted data for this encrypted file, return below status. + //e.ReturnStatus = NtStatus.Status.FileIsEncrypted; + + EventManager.WriteMessage(250, "OpenEncryptedFile", EventLevel.Information, + "OpenEncryptedFile:" + e.FileName + ",userName:" + e.UserName + ",processName:" + e.ProcessName + ",return status:" + e.ReturnStatus.ToString()); + + } + + } + catch( Exception ex) + { + EventManager.WriteMessage(500, "OnFilterRequestEncryptKey", EventLevel.Error, "OnFilterRequestEncryptKey:" + e.FileName + ",got exeception:" + ex.Message); + e.ReturnStatus = NtStatus.Status.AccessDenied; + } + + } + + private void button_Stop_Click(object sender, EventArgs e) + { + button_Stop.Enabled = false; + button_Start.Enabled = true; + + GlobalConfig.Stop(); + filterControl.StopFilter(); + + EventManager.WriteMessage(102, "StopFilter", EventLevel.Information, "Stopped filter service succeeded."); + + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("Stop filter service succeeded.", "StopFilter", MessageBoxButtons.OK, MessageBoxIcon.Information); + + return; + } + + private void AutoEncryptForm_FormClosing(object sender, FormClosingEventArgs e) + { + GlobalConfig.Stop(); + filterControl.StopFilter(); + } + + private void checkBox_EnableEncryptionWithDRM_CheckedChanged(object sender, EventArgs e) + { + if (checkBox_EnableEncryptionWithDRM.Checked) + { + //To enable DRM encryption, the filter driver will always go to service callback function to get the encryption key, + //so you can setup your own unique encryption key for every new encrypted file. + + textBox_PassPhrase.Enabled = false; + textBox_AuthorizedProcessesForEncryptFolder.Enabled = false; + textBox_AuthorizedUsersForEncryptFolder.Enabled = false; + textBox_AuthorizedProcessesForDecryptFolder.Enabled = false; + button_DRMSetting.Enabled = true; + } + else + { + button_DRMSetting.Enabled = false; + textBox_PassPhrase.Enabled = true; + textBox_AuthorizedProcessesForEncryptFolder.Enabled = true; + textBox_AuthorizedUsersForEncryptFolder.Enabled = true; + textBox_AuthorizedProcessesForDecryptFolder.Enabled = true; + } + } + + private void button_EncryptFolder_Click(object sender, EventArgs e) + { + FolderBrowserDialog folderDialog = new FolderBrowserDialog(); + if (folderDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + textBox_EncrptFolder.Text = folderDialog.SelectedPath + "\\*"; + } + } + + private void button_DRMSetting_Click(object sender, EventArgs e) + { + DRMForm dRMForm = new DRMForm(); + if (dRMForm.ShowDialog() == System.Windows.Forms.DialogResult.OK && filterControl.IsFilterStarted ) + { + SendConfigToFilter(); + } + } + + + private void helpToolStripMenuItem_Click(object sender, EventArgs e) + { + System.Diagnostics.Process.Start("https://www.easefilter.com/kb/auto-file-drm-encryption-tool.htm"); + } + + private void applyTrialKeyToolStripMenuItem_Click(object sender, EventArgs e) + { + WebFormServices webForm = new WebFormServices(); + webForm.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + + System.Threading.Tasks.Task.Factory.StartNew(() => { webForm.ShowDialog(); }); + } + + private void getTagDataOfEncryptedFileToolStripMenuItem_Click(object sender, EventArgs e) + { + InputForm inputForm = new InputForm("Input file name", "Plase input file name", ""); + + if (inputForm.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + string fileName = inputForm.InputText; + + byte[] tagData = new Byte[FilterAPI.MAX_AES_TAG_SIZE]; + uint tagDataLength = (uint)tagData.Length; + bool retVal = FilterAPI.GetAESTagData(fileName, ref tagDataLength, tagData); + + if (!retVal) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("GetAESTagData failed with error:" + FilterAPI.GetLastErrorMessage(), "GetAESTagData", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("Get encrypted file " + fileName + " tag data succeeded. return tag data length:" + tagDataLength, "tagData", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + } + } +} diff --git a/Demo_Source_Code/CSharpDemo/AutoEncryptDemo/AutoEncryptForm.resx b/Demo_Source_Code/CSharpDemo/AutoEncryptDemo/AutoEncryptForm.resx new file mode 100644 index 0000000..b528ed5 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/AutoEncryptDemo/AutoEncryptForm.resx @@ -0,0 +1,411 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + + + + AAABAAEAQEAAAAEAIAAoQgAAFgAAACgAAABAAAAAgAAAAAEAIAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AABqRDYQaEM0T2lDNIVtRjasc0k5xnlOPtR/U0LUhVlIxoxgT6ySaVaEmXNfT6B+ag8AAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAf1VGA3pQQVV5TT64eUw8+nxNPf9/Tz7/g1NA/4lXRP+QXUr/lmRQ/51sWP+ldmD/rIFp/7GK + c/+0knz6uJuIt7qhkFS9ppcDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + 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 + BP+YRwH/ql4V/76HUP+1czD/smAF/7RgAf+0YAH/tF8B/7NfAf+yXgH/sl0B/7FdAf+xXQH/sl0B/7Je + Af+zXwH/tF8B/7RgAf+zXwH/t3o8/7dzKv+5ejj/t3Qw/6FPAf+KQAP/yrKg/9zArf/Qsp7/uZqGlAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAyLSkKt/M + vPv05NX/7d7R/4JGHf+sc0b/o08C/6tXAv+3eTv/xppt/8KPW/+1YQL/tGAC/7NfAv+wXQL/rVoC/6tX + Av+rVwL/rFkC/65aAv+vXAL/sF0C/7JfAv+0YAL/vHUl/9Kuh//CjFP/tWkV/69bAv+pVgL/rm4y/45P + Hv/Psp7/y6mS/7iVfvuohG4pAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAMixoKXl0L//793N/6aHc/+RQAH/ok4C/6xYAv+yXgL/zaN0/8CMVP/CfzH/tWIC/7Nf + Av+tWQL/pFAB/5ZEAf+DPQb/hUQS/4pKFv+MSAv/nE0B/6lWAv+uWgL/sl4C/7RhAv+5bhj/yZNT/7ps + Ef+0YQL/sFwC/6pWAv+cSwL/poFm/8OdhP+4kHf/onpkpQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAALicihbLsJ354ci3/9nEtf+IRBT/r3I+/6pWAv+yXwL/tmMC/7tt + Df/AeCD/t2QC/7NhAv+sWAL/l0UB/45WL/+YbVP/n29Y/6BvWP+tgWr/wZ2I/72gi/+ld1L/mkwF/6xZ + Av+zYAL/tmMC/7hlAv+5ZgL/uGUC/7ViAv+wXQL/sWwo/5JME/+7ln//tYlv/6F1XvmVa1YWAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACyk35ty6yY/9e7qP+ifWb/mUQC/6hT + Av+xXgP/t2QD/7poA/+6aAP/uWcD/7ZkA/+vXAL/mUwL/7qYgf/MrZn/tY11/6FyWv+dbVX/rYFq/8Wk + j//exrX/8ODR/9fCr/+dVxf/r1sD/7VjA/+4ZgP/umgD/7ppA/+5ZwP/tWID/69cA/+hTgL/n3VX/7GD + af+kdV7/kWVRbQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAArIlzucSi + i//QsZz/lFs1/7F0P/+wXgn/tmMD/7ppA/+8awP/vGoD/7loA/+1YwP/pFMF/9S7pf/u3M7/28Kw/8Gd + h/+meGH/nGtU/66DbP/NrZr/6NPE//jq3P/77uH/28Wx/6NWDP+0YQP/uWcD/7tqA/+8awP/vGoD/7ln + A/+0YQP/tnQy/5leMP+1iXD/p3df/5JlUboAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAlnBcA6V9Z/O7k3v/uJaA/5A+Af+sVQL/tWED/7toA/++bQP/vm0D/71sA/+6aAP/tWED/76R + Zv/77uH/+eve/+3ay//TtqT/sYdw/5xrVP+yiHH/2L2r//Pk1v/67eD/8N3O/+DGtP+zhV//s18D/7ln + A/+8awP/vm0D/75tA/+8awP/uWYD/7JeA/+YRwL/sIdv/619ZP+YalXzjmNQBAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAI5lUiifc17/sIRr/6B0W/+sbDv/tGwl/7llBP++bAT/wHAF/8Bv + Bf++bQT/vGkE/69eB//bwq//7tzN//fp2//67N//69jJ/8Wjjv+fb1j/uJF7/+jUxf/5697/69bF/9W4 + o//Goov/u5R7/6tfDv+6ZwT/vmwE/8BvBf/AcAX/wG4F/71qBP+4ahP/s3Q6/6p/Yv+2iW3/pXde/5Rr + VikAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACJYE5KmGpV/6V1Xv+WX0H/q08D/7Zf + A/+9aQT/wG8E/8JyBP/CcQT/wG8E/71qBP+xbCf/yqmT/9K0oP/exLL/7NnJ//jp3P/n08P/q4Bp/8ak + kP/15tj/4Me0/8aii/+5kHb/tYpv/7WKcP+vbi//vGgE/8BuBP/AcAf/xIpB/791Fv/AbgT/u2cE/7Ja + A/+kcU7/wZl+/7OJbv+feGFLAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkWtaX5Fh + Tf+calT/lF0//65mKv+2cSv/vHUd/8iZYf/KoG3/wnUM/8JxBP+/bAT/r24w/66Baf+whWz/tYtz/72W + f//LqpX/4cq5/9K2o//XvKr/y6mT/7uSef+7k3r/v5iA/8Sehv/HpI3/vYdU/75pBP/CcAT/yYMl/9Gr + fP/Qm1T/v3YV/7p3K/+zbir/p3lX/8+slP/CnYT/qYZvXgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAIFbSmaLW0b/lWNN/5ddPP/Eejv/y4Y7/8uEKv/KmFr/07CG/8Z1Bf/FcwX/wm8F/69s + Lv+dbFT/nGtT/5trVP+cbFX/nm5Y/6R5ZP/CpZj/7NrM//Hi1f/v3s//7trK/+vXx//p1MP/6NLB/9Gi + cv/BbAX/xHIF/8Z8GP/JmV7/y5FC/8uCH//OjDz/yII7/7KCX//dwKv/0bGa/7KVgGYAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACUc2NhhldD/5BfSv+SUi7/t1YD/8BnBP/GcgX/z5ZJ/9Ki + Yf/JeAX/yHYF/8ZyBf+5cyn/nm9a/59yXf+jd2P/qYJw/7aWif/Ou7f/4c/F/+zXxv/99/L//fbx//32 + 7v/99er//PPn//zw4//Yo2r/xG8F/8d1Bf/JeAX/y34O/8p7Cv/IdgX/xG4F/7xgBP+velT/6tTA/93E + r//BqJVgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAk3JiUYNWQ/+PXkr/kVc6/7p0 + PP/CdB//yHMF/8t6Bv/MfAb/zHsG/8t5Bf/JdgX/xnUS/62Gcv+tiHf/tZWH/8KooP/TwsD/4dfW/+DH + tv/ixKz/+/Tu//338v/99/L//ffx//338P/99u7/zIIw/8hzBf/KeAX/zHsG/8x8Bv/Mewb/yngF/8V0 + EP++ezz/vJN3//Xj0v/m0r//xrCeUgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJZz + ZDGCVUT/kF9N/45WPv+4UwT/xGcF/8p0Bv/Newb/z38H/89+B//OfAb/zHkG/8p1Bv/GlGf/vqKX/8iy + rP/VxcT/4NbX/+PW0f/fwqz/3ruf//To3v/89/L//ffy//338v/99/L/7tO4/8dtBf/Ldwb/zXsG/85+ + B//Pfwf/zn0H/8x4Bv/IbwX/vV0E/8ikjf/77N3/6tnI/7+rmzQAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACSbmAIhVpK+5FiUP+XZVL/pEcG/8J8OP/Lcwb/z3wG/9GAB//RgQf/0X8G/9B8 + Bv/OeQb/znwZ/9K5q//Wx8b/39XV/+LZ2P/i0cb/3r6n/9y4m//s18f/+/Xw//338v/99/L/+vHo/9CC + LP/NdgX/z3sG/9B/Bv/RgAf/0YEH/9B/Bv/OeQb/xoAw/6teIP/k0cL/+u/g/+DRwf6rmIkQAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIZfT82SY1P/nnBf/6RdM//JZwz/zXIF/9F8 + Bv/TgQf/1IMH/9OCB//TgAb/0n4G/9B5Bv/ShS7/4dDG/+LZ2f/j2NP/4su9/928pP/ct5r/5cq1//fu + 5v/89/L/+vDm/9iSRf/Pdgb/0XwG/9J/Bv/Tggb/1IMH/9SCB//Sfwb/0HkG/8tsBf+wZzL//fXq//fu + 4f/Ar6HjAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDYlOSkGNU/5xv + X/+ZWjz/wVkF/8h9Lv/Segb/1YEH/9aECP/WhQj/1oQH/9WBB//Ufwf/0noG/9J7G//htpH/59nQ/+HI + t//du6L/3Lea/+HCqf/z5dr/7s2r/9aFJ//SeQb/1H4H/9SBB//Vgwf/1oUI/9aFCP/WhAf/1IAH/82D + J//Bahf/wZR4//z17P/x6d7/pJGErwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAbE9BT5x0Zv+gdmX/qH5r/65jM//QbhD/03YG/9Z/B//XhAf/1YQH/82aVP/Vgwn/14MH/9aB + B//Wfgf/03cG/9R7Gv/dmVP/36Jo/96iZ//enFb/14Qi/9R6Bv/Wfgf/1oAH/9eCB//Uhxb/0ZpN/9iG + B//Yhgf/2IQH/9Z/B//Tdgb/uXAz/+/j2//68+z/6d3T/31lWHIAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAGRIOwuMbmD0oXpq/62Jev+iZkj/x1sE/8qBNv/Wegb/2YIG/9ee + TP/atYP/zpxX/9iEBv/ahAf/2YIH/9mBB//YgAf/134H/9d8Bv/XfQf/134H/9iAB//ZgQf/2YIH/9mE + B//ahQf/3JIh/9exff/XlDD/2ocH/9mEB//SizD/yG8S/8OUdv/89e//9O3m/7Whlv9yWEosAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcFNHpa2Nf/+xkYX/upyQ/6dj + P//UbBT/1nIG/9J9FP/Yn1P/3q1q/9yoX//ciAj/3YcI/9yGCP/chAj/3IMI/9uCCP/bggj/24II/9uC + CP/bgwj/3IQI/9yFCP/chwj/3YgI/92JCP/ejhX/2pQs/9SOLP/bgQf/2HkH/7h7TP/37uf/+vLs/+vg + 1/97X1HYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGxP + Qz6eg3f/spWL/76lnf+9nZP/s00O/85qFf/drHn/234M/92DCf/ehgj/3ogI/96ICP/eiAj/3ocI/96G + CP/ehQj/24MH/9uDB//dhQj/3oYI/96HCP/eiAj/3okI/9+JCP/fiQj/3ogI/92FCP/hrWr/0oUr/7xi + Ef/m08f/+/Pt//Do4f+9o5b/d1RHegAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAfV1Sx7+mnP+/qKP/y7e0/8Gglf++elX/2GcK/9pxBv/YeAf/3oEH/9+F + B//fhgj/4IcI/+CHCP/ghwj/4IcI/9qRK//dljP/4IcI/+CHCP/giAj/4IgI/+CICP/ghwj/34YH/9qA + Cf/efwf/3HgG/8aKV//dxLX/+/Pt//Ts5f/i0cb/lWla94NaTBYAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIhnW0Kgf3T+yrWu/8u5t//Vxsb/yayl/7NP + F//RZxX/2Yc7/952Bv/dewf/4IAH/+GDB//hhAf/4YUI/+GFCP/fn0v/4JQt/+GFCP/hhgj/4YUI/+GF + B//hgwf/3X8H/999B//bkD//1XIS/7pfGv/gybv/+/Tt//bt5//p3NP/vJmH/5tvXpIAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAmHVqqpeF + fP/RwLv/08bG/9zR0v/Yx8X/s3Zc/8lTBP/WahL/2oIy/990B//beAv/4HwH/+F+CP/hfwj/3IQY/96W + P//hgAj/4X8I/+F+CP/bfA//4HkH/9yJN//YcBD/zFwF/7uEZv/u4Nf/+/Tt//Xt5v/p3tX/uKOW/6SC + b++lfmsVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAIdqXxZvVUnnnYqA/9rMx//Xzc3/4NfX/+Tb2v/Ip53/s25N/8lRBP/WZRD/3YE2/99s + Bv/YeyP/4HIG/9x8Hv/il0z/4HMH/9eAKv/fcAb/3oU2/9dqEP/LVgX/uHdU/9i6rP/89e//+vPt//Lq + 4//o3dT/wq+h/6+KYf+vjHRkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYEY5mnhZSf+Vgnn/4tTO/9nPzf/f1dX/4tnY/+Ta + 1v/KrJ//uH9l/7RPGv++SQT/03M2/9pcBf/Zaxz/34lL/9teBf/Udjf/v0wE/7VSG/+/iG3/17yu//rz + 7v/79fD/+PHr/+zk3f/q3dP/vKeZ/7SUcv/SqXPiAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFhANJiSdGP/k3Jg/4ly + aP/bzcf/5NjS/9vRzf/f1M7/4dLJ/9/Kvv/dwK7/0KmS/72McP+3fV7/t3ZU/7l8XP+3e1n/vIdm/9Ko + i//lyLH/69fG//Hj2P/z6+P/7+nj/+vh2f/p2M3/n4d3/7eScv/k0L7/0ql03AAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AABdQDWXmHlp/6+SgP+lgm7/jW5e/7qnof/t3dL/6dvR/+HQxv/axLf/17qn/9SxmP/UrZD/1KmJ/8CY + eP+gfWP/0qWB/9Kkgf/VrIz/27ui/+DItv/j0sX/697U/+vb0P/FsaT/jWdR/7B+XP/Xu6P/6tnL/9Kt + fdoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAaz40lqN9bP+9opD/y7Oi/8GjkP+Ubl3/nIyA/97Iuv/jzb//6dXH/+nU + xv/lzbz/38Kt/9y8pP/Sspn/xaaP/9e0mf/ZuJ7/3sCq/+fQv//v3tH/79/U/97Iu/+okIL/ZTwr/6Fo + TP/Cm4H/3MKu/+3e0v/VtI7YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHY/M5aqg2//yrCh/9jBs//Vvq//nnpp/9vI + vPneybz/2MCx/9K2pf/Kq5f/xaOO/8ajjf/IpI//yaaT/8+vnP/gybr/7N3S/+ze0//p29H/59nO/+TU + yf/Zw7f/y6+g/2dEN/+ue1z/zauV/+bRwP/w5Nn/2Lic2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB9RjSWroZ0/9O7 + rv/hzsL/3su//6SCc/+zmo4w2MK0htW8rebRtaT/yquX/8KeiP+4j3b/rn9m/6VzW/+re2P/yKiV/+LP + w//m1sv/5tbK/+TTx//i0MP/1L6w2bKWh29mPjHcv5N0/9e8qf/u3c//8+je/9y9pNgAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAgk46lrKNfP/Yw7n/6drQ/+PTyf+jhHb/kXZqFgAAAADRt6cCzbCeO8amkn67lX20q35j3J1o + TviUWEL/mmFH/7qSev/Wv7D53Mq93NvJvbHZx7p61MK2MgAAAAAAAAAAbkUz1cqih//hy7v/8+bb//Xr + 4v/fwarYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + 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 + vP/nzbX/48at/+PFq//nya7/48Kl/9m1mv/Us5vA1LijGwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACndlk+q3RSw7R4VP++iWT/xpVz/8qb + ef/Mn3z/z6J//9Glg//TqYf/1a2N/9iwkv/WrY3/z6B9/8qcet7Lo4ZhzKqQAQAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACmb0w2qGxEkqxuRti1eFD+uoBZ/72GYf/AimX/wYpm/8KKZP++hmDnvYVfpb6NaE7Bk3IEAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAArXVPDbN9Vyq2f1k6uIJcOrmFYTG6hWEVAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA///////////////AA////////gAAf//////4AAAf//////AAAA//////4AAAB//////AAAAD + /////4AAAAH/////AAAAAP////4AAAAAf////gAAAAB////8AAAAAD////wAAAAAP///+AAAAAAf///4 + AAAAAB////gAAAAAH///8AAAAAAP///wAAAAAA////AAAAAAD///8AAAAAAP///wAAAAAA////AAAAAA + D///8AAAAAAP///wAAAAAA////AAAAAAD///+AAAAAAf///4AAAAAB////gAAAAAH///+AAAAAAf///8 + AAAAAD////wAAAAAP////gAAAAA////+AAAAAH////8AAAAAf////wAAAAD/////gAAAAf////+AAAAB + /////4AAAAH/////gAAAAf////+AAAAB/////4AAAAH/////gIABgf////+A/j+B/////4D//4H///// + gP//gf////+A//+B/////4D//4H/////gP//gf////+A//+B/////4D//wH/////gP//Af////+Af/8B + /////8B//gH/////wD/8A//////AH/gD/////+AH4Af/////8AAAB//////wAAAP//////gAAB////// + /AAAP///////AAB////////AAf////////gf//////////////8= + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/AutoEncryptDemo/DRMForm.Designer.cs b/Demo_Source_Code/CSharpDemo/AutoEncryptDemo/DRMForm.Designer.cs new file mode 100644 index 0000000..c19cc73 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/AutoEncryptDemo/DRMForm.Designer.cs @@ -0,0 +1,309 @@ +namespace AutoEncryptDemo +{ + partial class DRMForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(DRMForm)); + this.button_ApplySettings = new System.Windows.Forms.Button(); + this.label2 = new System.Windows.Forms.Label(); + this.label10 = new System.Windows.Forms.Label(); + this.textBox_authorizedProcessNames = new System.Windows.Forms.TextBox(); + this.label12 = new System.Windows.Forms.Label(); + this.dateTimePicker_ExpireTime = new System.Windows.Forms.DateTimePicker(); + this.dateTimePicker_ExpireDate = new System.Windows.Forms.DateTimePicker(); + this.label11 = new System.Windows.Forms.Label(); + this.textBox_UnauthorizedProcessNames = new System.Windows.Forms.TextBox(); + this.label5 = new System.Windows.Forms.Label(); + this.textBox_AuthorizedUserNames = new System.Windows.Forms.TextBox(); + this.label4 = new System.Windows.Forms.Label(); + this.textBox_UnauthorizedUserNames = new System.Windows.Forms.TextBox(); + this.label3 = new System.Windows.Forms.Label(); + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.button_GetComputerId = new System.Windows.Forms.Button(); + this.textBox_ComputerId = new System.Windows.Forms.TextBox(); + this.label6 = new System.Windows.Forms.Label(); + this.groupBox2 = new System.Windows.Forms.GroupBox(); + this.radioButton_StoreDRMToServer = new System.Windows.Forms.RadioButton(); + this.radioButton_EmbedDRM = new System.Windows.Forms.RadioButton(); + this.groupBox1.SuspendLayout(); + this.groupBox2.SuspendLayout(); + this.SuspendLayout(); + // + // button_ApplySettings + // + this.button_ApplySettings.DialogResult = System.Windows.Forms.DialogResult.OK; + this.button_ApplySettings.Location = new System.Drawing.Point(353, 336); + this.button_ApplySettings.Name = "button_ApplySettings"; + this.button_ApplySettings.Size = new System.Drawing.Size(114, 23); + this.button_ApplySettings.TabIndex = 15; + this.button_ApplySettings.Text = "Apply Settings"; + this.button_ApplySettings.UseVisualStyleBackColor = true; + this.button_ApplySettings.Click += new System.EventHandler(this.button_ApplySettings_Click); + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(16, 97); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(104, 13); + this.label2.TabIndex = 2; + this.label2.Text = "Share file expire time"; + // + // label10 + // + this.label10.AutoSize = true; + this.label10.Location = new System.Drawing.Point(16, 137); + this.label10.Name = "label10"; + this.label10.Size = new System.Drawing.Size(131, 13); + this.label10.TabIndex = 53; + this.label10.Text = "Authorized process names"; + // + // textBox_authorizedProcessNames + // + this.textBox_authorizedProcessNames.Location = new System.Drawing.Point(213, 134); + this.textBox_authorizedProcessNames.Name = "textBox_authorizedProcessNames"; + this.textBox_authorizedProcessNames.Size = new System.Drawing.Size(242, 20); + this.textBox_authorizedProcessNames.TabIndex = 6; + // + // label12 + // + this.label12.AutoSize = true; + this.label12.Font = new System.Drawing.Font("Microsoft Sans Serif", 6.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.label12.Location = new System.Drawing.Point(211, 158); + this.label12.Name = "label12"; + this.label12.Size = new System.Drawing.Size(244, 12); + this.label12.TabIndex = 57; + this.label12.Text = "( split with \';\' , process format \"notepad.exe;wordpad.exe\")"; + // + // dateTimePicker_ExpireTime + // + this.dateTimePicker_ExpireTime.CustomFormat = " HH:mm:ss"; + this.dateTimePicker_ExpireTime.Format = System.Windows.Forms.DateTimePickerFormat.Time; + this.dateTimePicker_ExpireTime.Location = new System.Drawing.Point(335, 97); + this.dateTimePicker_ExpireTime.Name = "dateTimePicker_ExpireTime"; + this.dateTimePicker_ExpireTime.ShowUpDown = true; + this.dateTimePicker_ExpireTime.Size = new System.Drawing.Size(120, 20); + this.dateTimePicker_ExpireTime.TabIndex = 5; + // + // dateTimePicker_ExpireDate + // + this.dateTimePicker_ExpireDate.CustomFormat = "yyyy-MM-dd"; + this.dateTimePicker_ExpireDate.Format = System.Windows.Forms.DateTimePickerFormat.Custom; + this.dateTimePicker_ExpireDate.Location = new System.Drawing.Point(212, 97); + this.dateTimePicker_ExpireDate.Name = "dateTimePicker_ExpireDate"; + this.dateTimePicker_ExpireDate.Size = new System.Drawing.Size(120, 20); + this.dateTimePicker_ExpireDate.TabIndex = 71; + // + // label11 + // + this.label11.AutoSize = true; + this.label11.Location = new System.Drawing.Point(17, 180); + this.label11.Name = "label11"; + this.label11.Size = new System.Drawing.Size(147, 13); + this.label11.TabIndex = 77; + this.label11.Text = "Unauthorized process names"; + // + // textBox_UnauthorizedProcessNames + // + this.textBox_UnauthorizedProcessNames.Location = new System.Drawing.Point(214, 180); + this.textBox_UnauthorizedProcessNames.Name = "textBox_UnauthorizedProcessNames"; + this.textBox_UnauthorizedProcessNames.Size = new System.Drawing.Size(242, 20); + this.textBox_UnauthorizedProcessNames.TabIndex = 74; + this.textBox_UnauthorizedProcessNames.Text = "explorer.exe;"; + // + // label5 + // + this.label5.AutoSize = true; + this.label5.Location = new System.Drawing.Point(17, 220); + this.label5.Name = "label5"; + this.label5.Size = new System.Drawing.Size(114, 13); + this.label5.TabIndex = 78; + this.label5.Text = "Authorized user names"; + // + // textBox_AuthorizedUserNames + // + this.textBox_AuthorizedUserNames.Location = new System.Drawing.Point(214, 217); + this.textBox_AuthorizedUserNames.Name = "textBox_AuthorizedUserNames"; + this.textBox_AuthorizedUserNames.Size = new System.Drawing.Size(242, 20); + this.textBox_AuthorizedUserNames.TabIndex = 75; + // + // label4 + // + this.label4.AutoSize = true; + this.label4.Location = new System.Drawing.Point(17, 260); + this.label4.Name = "label4"; + this.label4.Size = new System.Drawing.Size(127, 13); + this.label4.TabIndex = 79; + this.label4.Text = "Unauthorized user names"; + // + // textBox_UnauthorizedUserNames + // + this.textBox_UnauthorizedUserNames.Location = new System.Drawing.Point(214, 260); + this.textBox_UnauthorizedUserNames.Name = "textBox_UnauthorizedUserNames"; + this.textBox_UnauthorizedUserNames.Size = new System.Drawing.Size(242, 20); + this.textBox_UnauthorizedUserNames.TabIndex = 76; + // + // label3 + // + this.label3.AutoSize = true; + this.label3.Font = new System.Drawing.Font("Microsoft Sans Serif", 6.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.label3.Location = new System.Drawing.Point(209, 237); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(195, 12); + this.label3.TabIndex = 80; + this.label3.Text = "(split with \';\' ,user name format \"domain\\user\" )"; + // + // groupBox1 + // + this.groupBox1.Controls.Add(this.button_GetComputerId); + this.groupBox1.Controls.Add(this.textBox_ComputerId); + this.groupBox1.Controls.Add(this.label6); + this.groupBox1.Controls.Add(this.groupBox2); + this.groupBox1.Controls.Add(this.label3); + this.groupBox1.Controls.Add(this.textBox_UnauthorizedUserNames); + this.groupBox1.Controls.Add(this.label4); + this.groupBox1.Controls.Add(this.textBox_AuthorizedUserNames); + this.groupBox1.Controls.Add(this.label5); + this.groupBox1.Controls.Add(this.textBox_UnauthorizedProcessNames); + this.groupBox1.Controls.Add(this.label11); + this.groupBox1.Controls.Add(this.dateTimePicker_ExpireDate); + this.groupBox1.Controls.Add(this.dateTimePicker_ExpireTime); + this.groupBox1.Controls.Add(this.label12); + this.groupBox1.Controls.Add(this.textBox_authorizedProcessNames); + this.groupBox1.Controls.Add(this.label10); + this.groupBox1.Controls.Add(this.label2); + this.groupBox1.Location = new System.Drawing.Point(12, 2); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size(488, 309); + this.groupBox1.TabIndex = 11; + this.groupBox1.TabStop = false; + // + // button_GetComputerId + // + this.button_GetComputerId.Location = new System.Drawing.Point(457, 61); + this.button_GetComputerId.Name = "button_GetComputerId"; + this.button_GetComputerId.Size = new System.Drawing.Size(25, 23); + this.button_GetComputerId.TabIndex = 16; + this.button_GetComputerId.Text = "..."; + this.button_GetComputerId.UseVisualStyleBackColor = true; + this.button_GetComputerId.Click += new System.EventHandler(this.button_GetComputerId_Click); + // + // textBox_ComputerId + // + this.textBox_ComputerId.Location = new System.Drawing.Point(212, 61); + this.textBox_ComputerId.Name = "textBox_ComputerId"; + this.textBox_ComputerId.Size = new System.Drawing.Size(242, 20); + this.textBox_ComputerId.TabIndex = 82; + // + // label6 + // + this.label6.AutoSize = true; + this.label6.Location = new System.Drawing.Point(15, 64); + this.label6.Name = "label6"; + this.label6.Size = new System.Drawing.Size(116, 13); + this.label6.TabIndex = 83; + this.label6.Text = "Authorized computer Id"; + // + // groupBox2 + // + this.groupBox2.Controls.Add(this.radioButton_StoreDRMToServer); + this.groupBox2.Controls.Add(this.radioButton_EmbedDRM); + this.groupBox2.Location = new System.Drawing.Point(19, 19); + this.groupBox2.Name = "groupBox2"; + this.groupBox2.Size = new System.Drawing.Size(436, 36); + this.groupBox2.TabIndex = 81; + this.groupBox2.TabStop = false; + // + // radioButton_StoreDRMToServer + // + this.radioButton_StoreDRMToServer.AutoSize = true; + this.radioButton_StoreDRMToServer.Location = new System.Drawing.Point(194, 13); + this.radioButton_StoreDRMToServer.Name = "radioButton_StoreDRMToServer"; + this.radioButton_StoreDRMToServer.Size = new System.Drawing.Size(146, 17); + this.radioButton_StoreDRMToServer.TabIndex = 1; + this.radioButton_StoreDRMToServer.Text = "Store DRM data to server"; + this.radioButton_StoreDRMToServer.UseVisualStyleBackColor = true; + // + // radioButton_EmbedDRM + // + this.radioButton_EmbedDRM.AutoSize = true; + this.radioButton_EmbedDRM.Checked = true; + this.radioButton_EmbedDRM.Location = new System.Drawing.Point(7, 13); + this.radioButton_EmbedDRM.Name = "radioButton_EmbedDRM"; + this.radioButton_EmbedDRM.Size = new System.Drawing.Size(164, 17); + this.radioButton_EmbedDRM.TabIndex = 0; + this.radioButton_EmbedDRM.TabStop = true; + this.radioButton_EmbedDRM.Text = "Embed DRM to encrypted file"; + this.radioButton_EmbedDRM.UseVisualStyleBackColor = true; + // + // DRMForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(522, 394); + this.Controls.Add(this.button_ApplySettings); + this.Controls.Add(this.groupBox1); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "DRMForm"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "Embed DRM data to the encrypted file"; + this.groupBox1.ResumeLayout(false); + this.groupBox1.PerformLayout(); + this.groupBox2.ResumeLayout(false); + this.groupBox2.PerformLayout(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.Button button_ApplySettings; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.Label label10; + private System.Windows.Forms.TextBox textBox_authorizedProcessNames; + private System.Windows.Forms.Label label12; + private System.Windows.Forms.DateTimePicker dateTimePicker_ExpireTime; + private System.Windows.Forms.DateTimePicker dateTimePicker_ExpireDate; + private System.Windows.Forms.Label label11; + private System.Windows.Forms.TextBox textBox_UnauthorizedProcessNames; + private System.Windows.Forms.Label label5; + private System.Windows.Forms.TextBox textBox_AuthorizedUserNames; + private System.Windows.Forms.Label label4; + private System.Windows.Forms.TextBox textBox_UnauthorizedUserNames; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.GroupBox groupBox1; + private System.Windows.Forms.TextBox textBox_ComputerId; + private System.Windows.Forms.Label label6; + private System.Windows.Forms.GroupBox groupBox2; + private System.Windows.Forms.RadioButton radioButton_StoreDRMToServer; + private System.Windows.Forms.RadioButton radioButton_EmbedDRM; + private System.Windows.Forms.Button button_GetComputerId; + } +} \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/AutoEncryptDemo/DRMForm.cs b/Demo_Source_Code/CSharpDemo/AutoEncryptDemo/DRMForm.cs new file mode 100644 index 0000000..d91027f --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/AutoEncryptDemo/DRMForm.cs @@ -0,0 +1,92 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.IO; +using System.Windows.Forms; +using System.Runtime.InteropServices; + +using EaseFilter.FilterControl; +using EaseFilter.CommonObjects; + +namespace AutoEncryptDemo +{ + + public partial class DRMForm : Form + { + + public DRMForm() + { + InitializeComponent(); + + dateTimePicker_ExpireDate.Value = DateTime.Now.AddDays(1); + + if (null != DRMServer.dRMInfo) + { + dateTimePicker_ExpireDate.Value = DateTime.FromFileTime(DRMServer.dRMInfo.ExpireTime); + dateTimePicker_ExpireTime.Value = DateTime.FromFileTime(DRMServer.dRMInfo.ExpireTime); + textBox_authorizedProcessNames.Text = DRMServer.dRMInfo.AuthorizedProcessNames; + textBox_UnauthorizedProcessNames.Text = DRMServer.dRMInfo.UnauthorizedProcessNames; + textBox_AuthorizedUserNames.Text = DRMServer.dRMInfo.AuthorizedUserNames; + textBox_UnauthorizedUserNames.Text = DRMServer.dRMInfo.UnauthorizedUserNames; + textBox_ComputerId.Text = DRMServer.dRMInfo.AuthorizedComputerIds; + + radioButton_EmbedDRM.Checked = DRMServer.embedDRMToFile; + radioButton_StoreDRMToServer.Checked = !DRMServer.embedDRMToFile; + } + + } + + private void button_ApplySettings_Click(object sender, EventArgs e) + { + try + { + DRMInfo dRMInfo = new DRMInfo(); + DRMServer.embedDRMToFile = radioButton_EmbedDRM.Checked; + dRMInfo.AuthorizedProcessNames = textBox_authorizedProcessNames.Text.Trim().ToLower(); + dRMInfo.UnauthorizedProcessNames = textBox_UnauthorizedProcessNames.Text.Trim().ToLower(); + dRMInfo.AuthorizedUserNames = textBox_AuthorizedUserNames.Text.Trim().ToLower(); + dRMInfo.UnauthorizedUserNames = textBox_UnauthorizedUserNames.Text.Trim().ToLower(); + dRMInfo.AuthorizedComputerIds = textBox_ComputerId.Text; + DateTime expireDate = dateTimePicker_ExpireDate.Value.Date + dateTimePicker_ExpireTime.Value.TimeOfDay; + dRMInfo.ExpireTime = expireDate.ToFileTime(); + dRMInfo.AuthorizedComputerIds = textBox_ComputerId.Text; + + DRMServer.SetDRMInfo(dRMInfo); + } + catch (Exception ex) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("Apply setting got exception:" + ex.Message, "apply settings", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + } + + private void button_GetComputerId_Click(object sender, EventArgs e) + { + textBox_ComputerId.Text = DRMServer.GetComputerId(); + } + } +} diff --git a/Demo_Source_Code/CSharpDemo/AutoEncryptDemo/DRMForm.resx b/Demo_Source_Code/CSharpDemo/AutoEncryptDemo/DRMForm.resx new file mode 100644 index 0000000..6cb06c8 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/AutoEncryptDemo/DRMForm.resx @@ -0,0 +1,1253 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + AAABAAEAgIAAAAEAIAAoCAEAFgAAACgAAACAAAAAAAEAAAEAIAAAAAAAAAABABMLAAATCwAAAAAAAAAA + AAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAIAAAADAAAAAwAA + AAQAAAAEAAAABAAAAAMAAAADAAAAAgAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAEAAAABAAAAAgAAAAQAAAAFAAAACAAAAAkAAAAKAAAACwAAAAsAAAALAAAACgAAAAkAAAAHAAAABQAA + AAMAAAACAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAACAAAAAwAAAAUAAAAIAAAADAAAAA4AAAASAAAAFQAA + ABgAAAAaAAAAGgAAABoAAAAXAAAAFQAAABEAAAAOAAAACgAAAAcAAAAFAAAAAgAAAAEAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABAAAABAAA + AAYAAAAKAAAADgAAABQAAAAZAAAAHQAAACIAAAAmAAAAKgAAAC0AAAAuAAAALgAAACwAAAAoAAAAJAAA + AB4AAAAXAAAAEgAAAA0AAAAJAAAABQAAAAIAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAABAAAAAgAAAAUAAAAJAAAADwAAABQAAAAYAAAAGgAAACUAAQE3AQEBRAEB + AU0BAQFQAAEBTAAAAEYAAAA+AAAAPQAAAD0AAAA6AAAAMwAAACsAAAAjAAAAGwAAABMAAAANAAAACQAA + AAUAAAACAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAQAAAAIAAAADQAA + ABIAAAATAAAAIRAREUkuLi6DTk1NsHBsbNN9eHjqhoGB9oN+fvN3c3PiYV9fzD08PK0fHx+EAAEBXAAA + AEoAAABGAAAAQgAAADkAAAAvAAAAJAAAABsAAAASAAAACwAAAAcAAAADAAAAAgAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAQAAAAIAAAAFAAAACwAAAA8AAAAPAgICJicoKG1cWlq9iYOD9qaenv+zqan/taqq/7es + rP+4ra3/ua2t/7itrf+3rq7/tKur/56YmP93c3PpPT09sg4ODnUAAABRAAAASwAAAEUAAAA6AAAALQAA + ACEAAAAXAAAADwAAAAgAAAAEAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAADAAAABwAAAAwAAAAMAQEBGygo + KG1oZmbUnpaW/7OoqP+2qqr/sqam/7asrP+/trb/x8C//83Gxf/LxMP/x7++/7+1tf+4ra3/uq+v/72y + sv+0q6v/jIeH90ZFRb0MDAx1AAAAUwAAAE4AAABDAAAANQAAACgAAAAcAAAAEgAAAAsAAAAGAAAAAwAA + AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAABAAAABAAAAAgAAAALAAAADBscHEtgXl7DnZWV/7Spqf+zqKj/s6io/8S8vP/Y0tH/2dLN/8nC + vf+zqqv/p5ye/6qfof+5sK//0MnD/9rU0f/Tzc3/wbi4/7mvr/+/tbX/t6+v/4WBgfQ2NjatAgICZQAA + AFIAAABLAAAAPQAAAC4AAAAhAAAAFQAAAAwAAAAHAAAAAwAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAQAAAAJAAAACQYHBxs/Pz+KioaG9rKo + qP+zp6f/s6en/8vEw//g29f/xr67/5KGj/9uY3//YVeD/2Zelf9qZJ7/aGKc/2BYjP9hV33/eGp8/6OX + mP/TzMf/3tnX/8W9vf+7sbH/wrm5/62np/9mZWXeFBQUhAAAAFcAAABRAAAAQwAAADMAAAAlAAAAGAAA + AA8AAAAIAAAAAwAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAEAAAAFAAAACQAAAAYTFBQ1Y2JiwaScnP+1qqr/sKSk/8O6uv/i3Nr/xby5/4B0hf9gWIf/bGqw/4KC + z/+Ki93/kJHh/5CR4f+QkeP/jY/k/4aI3f96ecj/YVub/2FVdv+Wio7/1c7J/9vW1f/AuLj/wLe3/8C4 + uP+Nior5Li4uqAAAAF4AAABUAAAASAAAADgAAAAoAAAAGgAAAA8AAAAIAAAAAwAAAAEAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAABQAAAAkAAAAGHyAgVXp3d+ewpqb/s6io/7Wq + qv/a1dP/1s/K/4h8iP9dVYn/dHO+/4qL2/+Oj97/jIzc/4yM2/+MjNz/jIzc/4uM3f+Ljd//jI3g/42O + 5P+PkOj/hYXb/2Zhpf9dUHH/opWV/+Ld2v/Qysr/vrW1/8a9vf+ooqL/SEhIxwICAmkAAABWAAAASwAA + ADsAAAAqAAAAHAAAABAAAAAIAAAAAwAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAA + AAUAAAAHAAAACTc4OHSOiYn4tqur/7Glpf/BuLj/5eDd/7KoqP9hV37/ZGOv/3x+1P+Agtb/f4DU/4CA + 1f+Bgdf/goLZ/4WF2v+Ghtv/h4jd/4mJ3v+KiuD/i4vh/4uL4f+NjeP/kJHo/4KE2f9dVpH/cGJ0/8zD + v//f29r/wrm5/8e9vf+4sbH/YF9f2gsLC3cAAABWAAAATgAAADwAAAArAAAAHAAAABAAAAAIAAAAAwAA + AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAEAAAABgAAAAxBQUGJmZOT/7arq/+wpKT/zcbG/+Pe + 2P+Kfoz/U02O/2hpxf9zdNH/cXLO/3Fyz/9zdND/dHTS/3Z11P93d9X/eHjX/3t72P99fdv/f3/c/4CA + 3f+Dg+D/hobg/4iH4P+JieH/jI7l/46Q6P9wb7z/V0tw/6mdnP/n4t//ycHB/8a9vf/Curr/cW9v5g4O + Dn8AAABYAAAATwAAAD0AAAAsAAAAHAAAABAAAAAIAAAABAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAABQAA + AAUAAAAMR0ZGmp+YmP+3q6v/saam/9jS0f/X0Mv/bmOB/05MoP9jZcn/ZWbJ/2RlyP9lZsr/ZmfL/2do + zv9pac//amrR/2tr0v9ubtX/cHDX/3Jy2P90dNn/dXXb/3h43f97e93/fX3e/4CB3/+Dg+D/hofi/42O + 6f+Cg9n/Vk2C/4t+hP/k4Nz/0MrK/8W8vP/Gvr7/fXt77xISEoYAAABYAAAAUAAAAD4AAAArAAAAGwAA + AA8AAAAIAAAAAwAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAQAAAAFAAAAC0hHR5qmnp7/t6ur/7Opqf/g29n/y8K+/1xT + fv9JSaz/WlvE/1hZwv9YWcP/WFnF/1pbxv9bXMn/W1zK/11czP9eXs7/YGDQ/2Fh0f9kZNT/ZWXV/2ho + 1/9qatn/bW3Z/29v2v9yctz/dXXd/3h43f97fN//f4Dg/4WH5f+GiOT/W1aX/3dodP/e2dT/1tDQ/8a9 + vv/Mw8P/gX5+7xESEoYAAABYAAAATwAAADwAAAArAAAAGgAAAA8AAAAHAAAAAwAAAAEAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAABQAA + AAtISEiZpp6e/7esrP+zqar/497b/8K5tf9PR3//QUOv/01Pvv9MTbz/S02+/0xNv/9NTsL/Tk/E/09Q + xv9QUMf/UVHJ/1NTy/9UVM3/V1bQ/1lZ0f9aWtP/XFzV/19f1v9hYdf/ZGTY/2dn2f9qatn/bW7b/3Bx + 3P9zdd3/d3nf/3x+4v+Chuj/Xlyn/2tcbP/b1M//2tTU/8i/v//NxcX/gX9/7xISEoYAAABYAAAATgAA + ADsAAAApAAAAGQAAAA0AAAAGAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAABAAAAAwAAAAUAAAAFQ0NDj6Sdnf+4rKz/tKqq/+Pf3P++trb/RD2A/zo7 + rf9BQ7f/QUK2/0FBuP9AQbv/QUG8/0JDvv9DQ8D/REPC/0VExf9GRsf/R0fJ/0lJy/9KSsz/TU3P/05O + 0f9RUdP/U1PT/1ZW1P9ZWNX/W1vW/15f2P9hY9j/ZWba/2lq2/9sbt3/cHLe/3V34f99gej/XVyu/2BR + av/UzMf/29bW/8nBwf/Oxsb/e3l57QwMDH0AAABYAAAATQAAADkAAAAmAAAAFwAAAAwAAAAFAAAAAgAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAFAAAAAkA/ + P3ufmJj/uK2t/7Sqqv/k393/wbm4/0A7gv8tMKr/Njey/zU2sf81NrL/NTW1/zU1tv82Nrn/Nja7/zg4 + vf84OL//OjrB/zs7xP88PMb/PT7J/0A/yv9CQsz/Q0PP/0VF0P9ISND/S0rR/01N0/9RUdT/VFXV/1ZY + 1v9aXNj/XWDZ/2Fk2/9maN3/aWzd/25y4P91euj/XF20/19Qaf/Vzsj/29fX/8vDw//LxMT/cnBw5QkK + CnYAAABXAAAASgAAADYAAAAkAAAAFQAAAAsAAAAEAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAEAAAACAAAABQAAAAA2NjZjl5KS/biurv+0qqr/49/c/8W9uv88NoD/IyWk/ysr + q/8qKqv/Kiqt/ykqsP8pKrL/Kiq0/yortf8rK7j/LCy6/y0tvf8uLr7/MDDB/zAxw/8xMsX/NDPI/zU1 + y/84OMz/OjrN/z09zv8/QM//QkLQ/0VF0f9IStL/S07U/05R1f9SVdf/V1na/1te2/9fYtz/Y2fe/2ds + 4f9wduj/VVey/19Raf/e2NH/29bW/87Hx//Jw8P/YmBg2gMEBG0AAABWAAAARwAAADIAAAAhAAAAEwAA + AAkAAAAEAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAUAAAAAIiIiSY2J + ifG5r6//s6mp/97Z1//QyMX/Qjt8/xcZnP8fIKX/HyCl/x4fqP8eH6r/Hh+s/x4frf8eH7D/Hh+y/x8h + tP8gIbf/IiG5/yMjvP8jJL7/JCXB/ycnwv8pKcX/KirJ/ywsyf8vL8n/MTLL/zQ1zP83OM3/OzvO/z0/ + 0P9AQ9L/REfU/0hL1f9LT9b/T1TZ/1RZ2/9YXt3/XGPf/2Fo4v9ocOn/T1Cq/2pbbP/h3Nf/2tTU/9HK + yv/Dvr7/Tk5OyAAAAGMAAABUAAAAQwAAAC8AAAAeAAAAEAAAAAcAAAADAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAEAAAADAAAAABQVFSt8eXniua+v/7Opqf/Y0tH/3NXP/0lCf/8MDpX/FBWf/xMU + n/8TFKH/ExSk/xMUpv8SE6f/EhOq/xITrP8SE6//FBSx/xQUtP8VFbb/Fxe5/xcYu/8YGb7/GxvB/x0c + w/8eHsX/ISHG/yMjx/8mJ8j/KSrJ/ywty/8vMMz/MjTO/zY40P85PNH/PEHU/0BG1v9FStj/Sk/Z/05U + 3P9TWd7/Vl7g/1xk5P9jbev/SEih/3Zncv/n49//1tHR/9XOzv+4tLT/OTk5tAAAAF0AAABSAAAAPwAA + ACsAAAAaAAAADgAAAAYAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAELCwsSamhoxras + rP+1qqr/z8jH/+nj3P9cU4T/BQeM/wsNmv8MDZr/DA2d/wwNn/8MDaH/DA2j/wsMpf8LDKj/Cwyr/wsM + rf8LC6//Cwuy/wwMtP8MDbf/DA25/w0Ou/8PD77/ERHA/xMTw/8VFcP/FxjE/xobxv8dHsf/ISLI/yQm + yv8nKcz/Ky3N/y8z0P8yN9L/NjvU/zpA1v8/Rdn/REvb/0hQ3f9NVeD/UVvi/1hh5v9daOn/QT+S/4h5 + fv/s6eX/083N/9jR0f+ppaX/IyMjnAAAAFgAAABPAAAAOgAAACcAAAAXAAAACwAAAAUAAAABAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAIAAAADAAAAA0tKSpuupaX/uK2t/8S8vP/w7OT/d26P/wgJh/8LDZf/DQ+Z/w0O + m/8NDp3/DQ6g/w0Oov8NDqT/DA2n/wwNqf8MDar/DA2t/wwNr/8MDLL/Cwu1/wsLtv8KC7n/Cgu7/woK + vf8KCr//CgrA/wsLwP8MDcH/DxDD/xITxP8WF8X/GBvI/xwfyv8gIsv/JCjO/ygt0P8rMdL/LzfU/zQ8 + 1/85Qdr/PUfc/0JN3v9HUuH/TVjj/1Nf6v9UYeb/Pjl//6GTkf/v6+r/08zM/9rT0/+MiorzDxAQgwAA + AFcAAABKAAAANQAAACIAAAATAAAACQAAAAMAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAABAAAAAA8PT1uoZub/7uw + sP+9s7P/8u3o/5iQof8QEIL/CQyV/w0Pl/8ND5n/DQ6c/w0Onv8OD6H/Dg+j/w0Opf8NDqj/DQ6p/wwN + rP8MDa7/DA2x/wwMs/8MDLX/DAy3/wsMuv8LC73/Cwu//wsLwf8LC8H/CgrB/woLwf8KC8H/CwzD/wwN + w/8NEMX/EBTH/xUZyv8ZHcv/HSLO/yEo0f8kLdP/KTLW/y442P8zPtv/OUPe/z1K4f9CUOP/SFXm/09e + 7f9MWd3/Qjhv/7uxrf/q5+b/1M3N/9XQ0P9tbGzgAwQEbQAAAFQAAABEAAAALwAAAB0AAAAPAAAABwAA + AAIAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAMAAAAAISIiO46JifC9srL/t66u/+rm4v+6srf/IB1//wgKk/8OEJb/DhCY/w4Q + mv8OD5z/Dg+e/w4PoP8OD6P/Dg+m/w0OqP8NDqv/DQ6t/w0OsP8NDbH/DQ2z/w0Ntv8MDbj/Cw27/wwM + vf8MDMD/CwvB/wsLwf8LDML/CwzC/wsNwv8MDcL/Cw3D/wsOxf8LD8b/DBHI/w4Uyf8SGMz/Fh3P/xsi + 0f8fKdX/Iy/Y/yg02/8uO93/NEHh/zhH5P89Tub/RFTp/0te8/9CTs//T0Fm/9bOx//k4OD/2NLS/8nF + xf9HR0fCAAAAXwAAAFIAAAA/AAAAKgAAABkAAAAMAAAABQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAA8QEBRwbm7Mua+v/7es + rf/b1tX/29TQ/zs2gP8GCI//DxCU/w4Qlv8OEJj/DxCb/w8Qnf8PEJ//DxCi/w8QpP8OD6b/Dg+p/w4P + q/8OD63/Dg+w/w4Osf8NDbT/DQ22/wwNuf8MDbv/DAy9/wwMwP8MDMH/DAzB/wwNwv8MDcL/DA3C/wwN + w/8MD8T/DBDF/w0Rx/8NEcj/DBLK/w0Uy/8NFc7/ERnR/xUf0/8aJtf/Hiva/yQy3f8pOOD/Lz/j/zRG + 5/85TOn/QFPt/0dd9v84QLP/aFhr/+jj3v/d2Nj/3dfX/7Ovr/8nJyefAAAAVwAAAE4AAAA4AAAAJAAA + ABUAAAAKAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAMpKSkATExMlbCnp/+6sLD/y8XE/+/r4/9iW4z/BwmK/w8Qkv8PEZP/DxGW/w8R + mf8PEZv/DxCe/w8QoP8PEKP/DxCk/w4Ppv8OD6n/Dg+r/w4Prf8OD7D/Dg6z/w4Otf8ODrf/DQ65/w0N + u/8MDL7/DQ3A/w0Nwf8MDMH/DAzC/wwNw/8NDsP/DQ7E/w0Pxf8NEMb/DRHI/w0Syf8NFMr/DhXN/w4W + zv8OF9H/DhnT/xAd1v8UItn/GSnc/x4v4P8lN+P/Kz7m/zBF6v82S+7/PFPy/0FZ9/8yNJP/i3yA//Dt + 6v/a1NT/4NnZ/4yKivINDQ1+AAAAVgAAAEcAAAAxAAAAHwAAABEAAAAHAAAAAgAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAACkpKVGclpb/vbOz/761 + tf/08ev/koui/w4PhP8ND5D/EBGR/w8RlP8PEpf/EBKZ/xARm/8QEJ3/DxCg/w8Qo/8PEKX/Dg+n/w4P + qv8OD6v/Dg+u/w8PsP8PD7P/Dw+1/w4PuP8NDrr/DQ27/w0Nvv8NDcH/DQ3B/w0Nwf8NDcL/DA3C/w0P + xP8ND8T/DRDG/w0Rx/8OEsj/DhPJ/w4Vyv8OFs3/DxbQ/w8Z0f8PGtT/DxvW/w8e2P8RIdz/FSff/xou + 4/8gNef/Jz3q/y1E7v8yS/H/OVX5/zpS7/83MHT/t6um/+7r6v/b1dX/2NPT/19fX9UAAABkAAAAUwAA + AEAAAAArAAAAGQAAAA0AAAAFAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAgAAAAATExMeenh42b60tP+5r6//6OTh/8W+wv8jIYH/Cg2N/xETkP8REpP/EBKV/xAS + mP8QEpn/EBKb/xARnv8QEaD/EBGj/xARpf8PEKf/DxCq/w8QrP8PEK7/DxCx/w8Ps/8PD7b/Dw+4/w4P + uv8OD73/Dg6//w0Nwf8ODsH/Dg7B/w0Owv8NDsL/Dg/E/w4QxP8OEcb/DhLH/w4TyP8OFMn/DxXM/w8W + zv8QF8//EBnS/xAb1f8QHtf/ESDZ/xEh3P8RI9//Eifj/xct5v8cNOr/Izzu/ylE8v8wTPX/N1b//zBD + 1P9OQGb/29PM/+bj4//h29v/wL29/zExMasAAABZAAAATgAAADgAAAAkAAAAFAAAAAkAAAADAAAAAQAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAACKisrAFBPT5y1rq7/u7Cw/9PO + zf/q5d//S0WI/wcJif8RE47/EROQ/xESkv8RE5X/EROY/xETmv8QEZz/ERGf/xESoP8REqP/ERKl/xAR + qP8QEar/EBGs/xARr/8QELH/Dw+z/xAPtf8QELj/DxC7/w4Pvf8ODr//Dg7B/w4Owf8ODsH/Dg/C/w4P + wv8PD8T/DxDE/w4Rxv8OEsf/DxPJ/w8Vy/8PFsz/EBbN/w8Y0P8QGtL/ER3V/xEf2P8RINr/EiPc/xIl + 4P8SJ+P/Eyrn/xQt6/8YNO7/Hzzy/yZE9/8tS/r/MlL//ycxq/91ZXH/7+vn/9/b2//k39//lpOT9Q4O + DoEAAABVAAAARwAAADEAAAAeAAAAEAAAAAcAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAwAAAAAqKytRoJqa/7+1tf/Cubn/9/Tu/4N8nv8JC4X/EBKN/xIUjv8SFJH/EhOS/xET + lf8RE5j/EROa/xESnf8REp//ERKh/xESo/8REqX/EBGo/xARqv8QEaz/EBGv/xARsf8QELP/EBC1/xAQ + uP8PELv/DxC9/w8PwP8PD8L/Dg7C/w8Pwv8PD8L/Dg/C/w8QxP8PEcT/DxLG/w8Tx/8QFMn/DxXL/w8W + zP8QF83/EBnQ/xEb0v8RHNX/ER7Y/xIh2/8SJN3/EyXg/xMo4/8UK+f/FC7r/xQw7/8XNPP/HDz3/yND + +f8pSfz/LEn2/yspgv+qnZr/8vDv/9/a2v/d2Nj/YWBg1wAAAGMAAABSAAAAPwAAACkAAAAYAAAADAAA + AAQAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAEBERFnh1ddS/tbX/u7Gx/+vo + 5f/Cu8L/HRuE/w0Pjf8SFIz/EhSO/xIUkP8TFJP/EhSW/xETmP8RE5r/EhOd/xITn/8SE6L/EhOk/xIT + pv8REqj/ERKq/xESrP8REq//ERKy/xERtP8QELb/EBC4/xARuv8QEL3/EA/A/w8Pwv8PD8L/Dw/D/w8Q + w/8PEMP/DxHD/xASxP8PEsb/DxPH/xAUyf8QFsr/ERfN/xEYzv8QGc//ERzS/xIe1f8SINj/EiHb/xIk + 3f8UJuD/FCnj/xQr5/8VLuv/FTHv/xYz8v8WNvb/GTv4/x9A+f8mSP//Ijrd/0I2Z//Y0Mj/6+jo/+Xg + 4P/Cvr7/LS0tpQAAAFgAAABMAAAANgAAACIAAAATAAAACAAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAiIjIwBKSUmKs6ur/72zs//Uzs7/7Ojj/0pFi/8IC43/EhWN/xIUjP8TFY7/ExWR/xMU + lP8SFJb/EhSY/xIUmv8SE53/EhOf/xITof8TFKT/ExSm/xITqP8SE6v/EhOs/xESr/8RErL/ERG0/xER + tv8REbj/EBG6/xARvf8QEL//EBDC/xAQwv8QEML/EBHD/w8Qw/8PEcP/EBLE/xATxv8QFMf/ERXJ/xAV + yv8QF83/ERjP/xIZ0P8SHNL/Eh7V/xIg1/8TIdv/EyTd/xQn4P8UKeP/FSvn/xUu6v8WMO7/FjPy/xY2 + 9f8XOPj/Fzn4/xw++f8iRf//HCeu/3Zmcv/w7un/49/g/+jk5P+OjIzxCQoKeQAAAFQAAABEAAAALgAA + ABsAAAANAAAABgAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAIiMjOZWRkffCuLj/wbm5//bz + 7f+Oh6T/DQ6J/xEUkf8TFY3/ExWM/xMVjv8UFpH/ExSU/xIUlv8TFZn/ExWb/xMVnf8TFJ//ExSh/xMU + o/8TFKb/EhOp/xITq/8SE63/EhOu/xITsf8SErT/EhK2/xESuP8QEbv/ERG9/xERv/8QEML/EBDC/xAQ + wv8QEcP/EBHE/xESxP8RE8X/EBPG/xAUx/8RFcj/ERbL/xIXzf8SGM//ERnQ/xIc0f8THtT/EyDX/xMh + 2v8TJN3/FCfg/xUo4/8VK+b/Fi3p/xYv7f8WM/H/Fjb0/xc4+P8XOPj/Fzj4/xo8+/8cO/T/JyR9/7Kl + n//z8fD/5eDg/9vX1/9PTk7FAAAAXQAAAFAAAAA7AAAAJgAAABQAAAAJAAAAAwAAAAEAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAABAAAAAQMDAwVmZma5vbS0/72zs//l4d//z8jK/yYkh/8ND5P/FBaR/xQWjv8UFo3/FBaP/xQW + kf8UFZP/ExWW/xMVmP8TFZv/FBWd/xQVn/8UFaL/FBWj/xQVpv8TFKn/ExSr/xMUrf8TFK//ExSx/xMT + s/8SErb/EhK5/xESu/8REr3/ERG//xERwf8REcL/EBDC/xERw/8REsT/EBLE/xESxf8RFMf/ERXH/xIV + yP8SF8r/ERfL/xIYzv8SGtD/ExzR/xMd1P8TINf/FCLZ/xQj3P8UJt//FSji/xUq5P8WLOj/Fi/r/xYx + 7/8WNPL/Fzf1/xc5+P8XOfj/Fzj4/xg8//8TKtP/TT9n/+Lb1P/r6Oj/7Ofn/7Gvr/8ZGRmQAAAAVQAA + AEgAAAAxAAAAHgAAAA8AAAAGAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAOTk5XqagoP/BuLj/zcbG//Pv + 6P9gWpP/CAuR/xMVlP8UFpH/FBaO/xQWjf8VF4//FBaR/xQVlP8UFpb/FBaY/xQWm/8UFp3/FBWg/xQV + ov8UFaP/FBWm/xMUqP8TFKv/ExSt/xMUr/8TFLL/ExOz/xMTtv8TE7j/EhO7/xESvf8REb//EhLB/xIS + wv8REcL/ERLD/xESw/8REsT/EhPF/xIUxv8RFMf/ERbI/xIXyf8SF8z/ExnO/xIaz/8TG9L/Ex7U/xQg + 1v8UItj/FCTb/xQl3v8VKOH/FSrj/xYs5v8WLur/FjDt/xYy8P8XNfP/Fzf1/xc5+P8XOfj/Fzj5/xU4 + /v8UHZ3/i3yA//b08f/n4+P/6OTk/29ubtwAAABnAAAAUgAAAD8AAAApAAAAFwAAAAoAAAAEAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAABAAAAABISEhR+e3vTw7q6/7+3t//w7Oj/q6S1/xUViv8QEpj/FRaU/xUXkf8VF4//FReM/xUX + j/8VF5H/FRaU/xQWlv8UF5j/FReb/xUWnP8VFZ//FBWi/xQVo/8UFab/FBWo/xMUqv8TFK3/ExSv/xMU + sv8UFLT/FBS1/xQUuP8SE7r/EhO9/xISv/8SEsH/EhLC/xISwv8SE8L/EhPD/xESxP8SFMX/EhTG/xIV + x/8SFsj/EhfK/xIXy/8TGcz/ExrO/xMc0f8THdT/FB/U/xQi1/8UI9r/FSXd/xUo4P8WKeL/Firl/xYt + 6P8WL+r/FjHt/xYz8P8WNPP/Fjb0/xc39f8XN/b/Fjj6/w8s5/8wKGz/zMO7//Lw8P/s6Oj/ycbG/ywr + K6QAAABXAAAASwAAADQAAAAfAAAAEAAAAAcAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEUFRUARkZGe7Krq//BuLj/19HQ/+bh + 3P9DP43/Cw6Y/xQWmP8VFpX/FRaS/xUXj/8WGI3/FReP/xUXkf8WF5T/FheW/xUXmP8VF5v/FRec/xUW + n/8VFqH/FRaj/xUWpv8VFqj/FBWq/xQVrf8UFa//FBWx/xQUtP8UFLb/FBS3/xQUuv8TFLz/EhK//xIS + wf8TE8L/EhLC/xISwv8SE8P/EhPD/xMUxP8TFMb/EhXH/xIWyP8TF8r/ExfL/xMYzP8TGs//FBzR/xQd + 0/8UH9T/FCDW/xUj2f8VJdv/FSfe/xYp4f8WKeP/Fivm/xYu6P8WL+r/FjDt/xYy7/8WM/H/FjTy/xY0 + 8/8WNPP/FTT5/wwatf9sXXD/8e7p/+vn6P/u6ur/iYiI6wQEBHEAAABTAAAAQAAAACsAAAAYAAAACwAA + AAQAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAABAAAAABQVFR+Jhobmxby8/8S8vP/z8Or/kImm/w4Pkf8TFZz/FReY/xUXlf8WF5P/FhiP/xYY + jv8WGI//FhiR/xYXk/8WF5X/FhiY/xYYm/8VF5z/Fhef/xYXof8WF6P/Fhel/xYXqP8VFqv/FRat/xUW + r/8VFrD/FBSz/xQUtv8VFbj/FBW5/xMUvP8TE77/ExPB/xMTw/8TE8P/ExPD/xMUxP8SFMT/EhTE/xMV + xv8TFcb/ExfI/xMXyf8TGMv/ExnM/xQazf8UG8//FB3S/xQf1P8VINb/FSLX/xUj2v8VJtz/Fijf/xYo + 4v8WKeP/Fivl/xYt6P8WLur/FjDs/xYx7f8WMe7/FjHv/xYw7/8WMfH/ECvs/x8dff+3qqX/9/b1/+3p + 6f/Z1dX/PDw8tQAAAFkAAABMAAAANgAAACEAAAARAAAABwAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEWFhYATUxMjLqxsf/CuLj/39rZ/9fR + z/8wLo3/Dg+e/xUXnP8VF5n/FReW/xYXk/8XGJD/FxmO/xcZjv8XGZH/FxiU/xcYlv8WGJf/Fhia/xYY + nf8WF5//Fheh/xYXo/8WF6X/Fhen/xUWqv8VFq3/FRau/xUWsP8VFrL/FRW1/xUVuP8VFbr/FBW7/xQV + vf8UE8D/FBTC/xQUw/8TE8P/ExTE/xMUxP8TFMT/FBXF/xQWxv8TFsf/FBjJ/xQYyv8UGMz/FBnM/xQb + zv8UHdD/FR7T/xUf1f8VIdf/FSLY/xUk2v8WJt3/Fifg/xYo4v8WKeP/Fivl/xYs5v8WLef/Fi7q/xYu + 6v8WLuv/Fi7r/xUu6v8UL/D/CxvC/1dJav/s5uD/8O3t//Lv7/+ZmJjyCgoKeAAAAFMAAABCAAAAKwAA + ABkAAAALAAAABAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAABAAAAABYWFimQjIzxyL6+/8nBwf/08Or/fnig/wwOl/8VFqD/FRec/xYYmv8WGJf/FxiU/xcZ + kf8XGY7/FxmO/xcZkf8YGZT/GBmV/xYYmP8WGJr/Fxmc/xcYnv8XGKD/Fxij/xcYpv8XGKj/Fhep/xYX + rP8WF67/Fhew/xYXsv8VFbT/FRW3/xYWuv8VFrv/FBW8/xQUv/8UFML/FBTD/xQUw/8UFMT/FBXE/xMV + xP8UFcT/FBbG/xQWxv8UF8j/FBjJ/xQYy/8UGcz/FBvN/xQcz/8VHdH/FR/U/xUg1f8VItf/FSPY/xYk + 2v8WJ93/Fiff/xYo4f8WKeL/Firk/xYr5f8WK+b/Fizn/xYr5/8VK+f/FSvn/xQr5/8QJuj/GBmI/6ib + mP/5+Pb/7+zs/+He3v9GRka+AAAAWQAAAEwAAAA2AAAAIQAAABEAAAAHAAAAAgAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEWFhYATk1Nk7y1tf/Durr/49/d/8zF + yf8oJo//EBKj/xYXoP8WF53/Fhia/xYYl/8XGJX/GBmS/xgaj/8YGo7/GBqQ/xgakv8YGZX/FxmY/xcZ + mv8XGZz/Fxie/xcYof8YGaL/GBml/xgZp/8XGKn/Fxis/xcYrf8WF7D/Fhez/xYWtP8WFrX/Fha4/xYW + u/8VFr3/FRW//xUVwf8VFcP/FBTD/xQUw/8UFcT/FBXF/xQWxf8UFsX/FBbG/xQXx/8VGMj/FRnK/xQZ + zP8VGs3/FRzO/xUcz/8VHtL/FR/U/xUh1f8VItf/FSPY/xYl2v8WJtz/Fife/xYo4P8WKOH/Fini/xYp + 4/8WKuP/FSrj/xUq4/8UKeP/FCji/xQo5v8KGcf/Sj5r/+bg2P/z8fH/9fLy/56dnfcLCwt8AAAAUgAA + AEEAAAAqAAAAGAAAAAsAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAABYWFimRjY3xycDA/8vDw//x7eb/dG+d/wwOnP8WF6T/Fheh/xYYnv8XGZv/FxmY/xgZ + lf8YGpP/GBqP/xgajv8ZG5D/GRuT/xgZlf8YGZf/GBqZ/xgam/8YGp7/GBmg/xgZof8YGaT/GBmm/xgZ + qf8XGKv/Fxit/xcYr/8XGLH/Fxi0/xcXtv8WFrf/Fhe6/xUXvP8VFb7/FRW//xUVwv8VFcP/FRXD/xUV + xP8UFcT/FBXF/xUWxf8VF8f/FRjH/xQYx/8VGcn/FRnK/xUazP8VG87/FRzO/xUd0P8VHtL/FR/U/xYh + 1f8WItf/FSPY/xYk2f8WJdv/Fibd/xYn3v8WJ9//FSjg/xUo4P8VKOD/FSjh/xQm4P8TJuD/EyXf/w8i + 4v8UFYz/oJOU//z6+P/y7+//4+Dg/0ZGRr8AAABZAAAASwAAADUAAAAgAAAAEAAAAAcAAAABAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wAVFRUAFRUVABUVFQAVFRUAFRUVABUVFQAVFRUATk1Nkr22tv/FvLz/497c/8rD + xv8pKJP/EBKn/xcYpP8XGKH/Fxie/xcZm/8XGZn/GBmX/xkalP8ZG5H/GRuO/xkbkP8ZG5P/GRqV/xka + lv8YGpn/GRuc/xkanv8ZGZ//GRqi/xkapP8ZGqb/GBmp/xcYq/8YGa3/GBmu/xgZsf8XGLP/Fxe2/xcX + t/8XF7j/Fxe7/xYXvv8WFcD/FhbC/xYWw/8VFcP/FRXE/xUWxP8VFsT/FRbF/xUXxv8VGMf/FRjH/xUZ + yP8VGcr/FRnL/xUbzf8VG87/FRzO/xUd0P8WH9L/FSDU/xYh1f8WIdf/FSPX/xYk2f8WJNr/FSTb/xUl + 3P8VJtz/FSbe/xQm3v8UJt7/FCXe/xMj3f8SI9z/EiPf/wkWxv9KP27/5uHZ//b09P/49vb/n56e9wsL + C3sAAABRAAAAQAAAACkAAAAWAAAACgAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////ABUVFQAVFRUAFRUVABUV + FQAVFRUAFRUVABUVFSCRjY3rysHB/8zFxf/x7eb/dnGf/w0OoP8WF6n/Fxil/xcYov8XGJ//GBqd/xga + mv8YGpf/GRqV/xkbkv8ZG4//GhuP/xobkv8aG5T/GhuW/xkbmf8ZG5v/GRuc/xkbn/8ZGqL/GRqk/xka + pv8ZGqf/GBmq/xgZrf8YGa//GBmw/xgZsf8YGLT/GBi3/xgYuf8XGLv/Fhe8/xYWv/8WFsL/FhbD/xYW + w/8WFsP/FhbE/xUWxP8VF8X/FhfF/xYYx/8VGMf/FRnH/xUZyf8WGcr/FRrL/xUbzf8WHM7/FRzP/xUe + 0P8WH9H/FSDT/xUh1f8WIdb/FSHX/xUi1/8VI9n/FSPZ/xUk2f8VJNv/FCTa/xQj2v8UItr/EyLa/xMh + 2v8SINn/Dh3d/xUVjv+hlJX//fz6//Xy8v/k4uL/QEBAtwAAAFgAAABKAAAAMwAAAB0AAAAOAAAABQAA + AAEAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8AERISABESEgAREhIAERISABESEgAREhIASEhIfLu0tP/Gvr7/497d/83G + yP8rKZT/ERKr/xYYqP8XGab/GBmj/xgZoP8YGp7/GBqb/xgbmP8aG5b/GhuS/xobkP8aG4//GhuR/xob + lP8aG5b/GhyZ/xocm/8aHJ3/GRue/xkaof8ZGqP/GRql/xkaqP8ZGqn/GBmr/xgZrv8ZGrD/GRqx/xgZ + s/8YGLb/GBi5/xgYuv8XGLv/Fxe9/xcWwP8XF8L/FhbD/xYWw/8WFsP/FhfE/xYXxf8WF8X/FhjG/xYY + x/8WGcf/FRnI/xYZyf8WGsr/FRrL/xUbzf8WHM7/FRzP/xUe0P8WHtD/Fh/T/xUg1P8VINX/FSHW/xUh + 1v8VItf/FSLX/xQi1/8UIdj/EyDY/xMg2P8TINf/Eh/X/xIe1v8RHdn/CBK//01Bbf/o4tr/9/b2//r4 + +P+Uk5PvBAQEcQAAAFAAAAA8AAAAJQAAABQAAAAIAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAA////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wAREhIAERISABES + EgAREhIAERISABESEhCFgoLbysLC/8zExP/w6+X/gXuj/w4Qof8WF63/Fxmp/xgZpv8YGaT/GRmh/xka + nv8ZG5z/GRua/xobl/8aG5T/GxyR/xsckP8aG5H/GxyU/xsclf8bHJj/Ghya/xocnf8aHJ7/Ghug/xob + o/8aG6X/Ghuo/xobqf8ZGqr/GRqt/xkar/8ZGrL/GRqz/xkZtf8YGLf/GBi5/xgZu/8XGLz/Fxe+/xcX + wf8XF8P/FxfE/xcWw/8WFsP/FhfE/xYXxP8WF8X/FhjG/xYYx/8WGcj/FhnI/xYZyf8WGcr/FRrL/xUb + zf8WG87/Fh3O/xUdz/8VHtD/FR7R/xUf0v8VH9P/FR/U/xUf1f8UH9X/FCDV/xQg1f8UH9X/Ex/V/xIe + 1P8SHdT/EhzT/xEb0/8MF9b/GReH/6ygnf/+/Pv/+ff3/9vY2P8wMDCnAAAAUwAAAEUAAAAuAAAAGgAA + AAwAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AAIDAwACAwMAAgMDAAIDAwACAwMAMzMzW7Ourv/KwcH/3trZ/9fR + z/82NJb/EBKv/xcYrP8XGKr/GBqo/xkapf8ZGqL/GRqf/xkbnP8aHJr/GhyX/xsclf8bHJP/GxyQ/xsc + kf8bHJT/HB2W/xsdmP8aHJr/Gh2b/xsdnv8bHKD/Gxyi/xscpP8bHKX/Gxyo/xobq/8ZGqz/GRqu/xob + sf8aG7L/GRq0/xkZtv8ZGbj/GRm7/xgZvP8YGb7/GBe//xcXwv8XF8T/FxfE/xcXxP8XF8T/FhfE/xYY + xP8XGMX/FxjG/xYZx/8WGcj/FhnJ/xYZyf8WGcr/FhrL/xUbzP8WG87/FhzO/xYdz/8VHc//FR3P/xUd + 0f8VHdL/FR7S/xQe0/8UHtP/FB7T/xMe0/8THdP/ExzS/xIc0f8SGtH/EBrQ/xAZ1P8HDrT/XFBz//Ht + 5//59/f/+vj4/3x7e98AAABkAAAATQAAADcAAAAhAAAAEAAAAAcAAAACAAAAAAAAAAAAAAAAAAAAAP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAgMDAAID + AwACAwMAAgMDAAIDAwFvbW25ycLC/8vDw//u6+X/l5Cr/xMUov8WF7L/GBmt/xgZq/8YGqj/GRqm/xoa + o/8aG6D/Ghye/xocm/8aHJn/GxyW/xwdk/8cHZD/HB2Q/xwdkv8cHZX/HB2Y/xwdmf8bHZv/Gx2d/xsd + oP8bHKL/Gxyk/xscpv8bHKj/Gxyp/xobrP8aG63/Ghuv/xobsv8aG7T/Ghq2/xoat/8aGrn/GRq8/xgZ + vf8YGb7/GBjB/xgYw/8YGMT/FxfE/xcXxP8XGMX/FxjF/xYXxf8XGMX/FxnG/xcZx/8WGcj/FhrJ/xYa + yf8WGcn/FhrK/xUbzP8VG83/FhvN/xUczv8VHM//FRzP/xUcz/8UHND/FBzQ/xQc0P8THNH/ExzR/xMb + 0f8TG9H/ERrQ/xEZz/8RGM7/EBfO/woSzv8jHnz/vrSu//79/P/7+Pj/xcTE/x4eHpEAAABQAAAAPwAA + ACgAAAAVAAAACQAAAAMAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wAmJycAJicnACYnJwAmJycAJicnM6KenvrNxsb/2NPS/+Tf + 2f9OS5r/Dg+v/xgZsv8YGa//GBms/xkaqf8aG6f/Ghuk/xobof8aHJ//Gx2c/xsdmf8cHZf/HB2V/xwd + kv8cHZD/HR6R/x0elP8dHpb/HR6Z/xwem/8cHp3/HB6f/xwdoP8cHaP/HB2l/xwdp/8cHan/Gxyq/xsc + rf8bHK//Gxyx/xscs/8aG7X/Ghq2/xoauP8aGrn/GRq8/xkavv8ZGMD/GBjB/xgYw/8YGMT/GBjE/xcX + xf8XGMX/FxjF/xcYxf8XGMX/FxnG/xcZx/8WGcj/FhrJ/xYayf8WGcn/FhnK/xYay/8VGsz/FRvN/xUb + zf8VG83/FRvO/xQbzv8UG87/FBvO/xMbzv8TGs7/ExrO/xIZz/8SGM7/ERfO/xEWzf8QFsz/DhbQ/woN + pv96bn//+fby//bz8//v7e3/WFhYyAAAAFgAAABGAAAAMAAAABsAAAANAAAABQAAAAEAAAAAAAAAAAAA + AAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAME + BAADBAQAAwQEAAMEBABLS0uGwru7/8vDw//o5OH/tq+6/x4en/8VFrf/GBmy/xkasP8ZGq3/GRuq/xkb + qP8bHKX/Gxyi/xscoP8bHZ7/Gx2b/xwemP8dHpb/HR6U/x0ekP8dHpH/HR6U/x0elv8dHpf/HB6a/xwe + nf8cHp7/HB6f/xwdof8cHaT/HB2n/xwdqP8cHan/Gxyr/xscrv8bHLH/Gxyy/xscs/8bG7b/Gxu3/xsb + uf8aGrr/GRq9/xkav/8ZGMD/GRjB/xgYxP8YGMT/GBjE/xgYxf8XGMX/FxjF/xcYxf8XGMX/FxjG/xcZ + x/8XGcj/FhrI/xYayf8WGcn/FhnJ/xYZyv8WGcr/FRrL/xUazP8UGs3/FBrN/xQazf8UGcz/ExnM/xMY + zP8SGM3/EhjN/xIXy/8RF8z/EBbM/xAWy/8PFcz/CA7F/zgwdP/a08v/+fj3//n29v+enZ31BgYGcQAA + AEsAAAA3AAAAIQAAABAAAAAGAAAAAgAAAAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8AAwQEAAMEBAADBAQAAwQECIJ/f9HPx8f/0crK/+3o + 4f9xbKH/Dg+t/xgYt/8ZGbP/GRqx/xkarv8aG6v/Ghyp/xscpf8bHKT/HByi/xwdn/8cHpz/HB6a/x0e + l/8dHpX/HR6S/x0ekP8dHpP/HR6V/x0el/8dHpn/HB6b/xwenf8cHp//HB2i/xwdo/8cHaX/HB2n/x0e + qf8cHar/Gxyt/xscr/8bHLD/Gxyy/xsctf8bG7f/Gxu5/xsbuv8aG7v/GRu9/xkav/8ZGcD/GRnC/xkZ + xP8YGMT/GBjE/xgYxf8YGMX/FxjF/xcYxf8XGMX/FxjF/xcZx/8XGcf/FhnI/xYZyP8WGcj/FhnI/xYZ + yf8VGcr/FRnK/xUZyv8UGMv/FBjL/xMYy/8TGMv/ExjL/xIXyv8SF8r/ERfK/xEWyf8RFsn/EBTJ/xAU + yf8MEcz/EhGQ/6CVlv/8+/n/9fLy/9bU1P8rKyufAAAATQAAAD8AAAAnAAAAFQAAAAkAAAADAAAAAAAA + AAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wAqKioAKioqACoqKgAqKio+q6am/c/Hx//f2tj/19DO/zg2nf8QErn/GRm3/xkZtP8aG7L/Ghuv/xob + rP8aHKr/Gx2n/xwdpf8cHaL/HB6f/xwenv8cHpv/HR6Y/x0elv8dHpP/Hh6R/x4fkv8eH5T/Hh+W/x4e + mf8eHpv/HR6c/x0en/8dHqH/HR6j/x0epf8eH6f/Hh+o/x0eqv8cHaz/HB2t/xwdsP8bHLL/Gxyz/xsc + tP8bG7b/Gxu5/xsbuv8bG7v/Ghu+/xoav/8ZGcD/GRnC/xkZxP8ZGcT/GBjE/xgYxf8YGMX/FxjF/xcY + xf8XGMX/FxjF/xcZxv8XGcf/FhnH/xYZyP8WGcj/FRnI/xUZyP8VGcn/FRnJ/xUZyf8UGMn/FBjK/xMX + yv8TF8r/ExfJ/xIXyP8SFsj/ERXI/xEVyP8QFMj/DxPH/w4Syv8HCrH/X1V5//Hu5//z8fH/8O3t/2Vl + Zc8AAABZAAAARQAAAC4AAAAZAAAACwAAAAQAAAABAAAAAAAAAAD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AAMDAwADAwMAAwMDAE5OToXHwMD/zsbG/+zo + 5P+moLT/GBim/xYXvf8ZGbj/Ghq1/xobs/8aG7D/Gxyt/xscq/8cHan/HB2m/xwdpP8cHqH/HB6e/xwe + nP8dHpr/Hh6X/x4flP8eH5H/HyCR/x8glP8fIJb/Hx+Y/x8fm/8fIJz/HyCd/x8gn/8fIKL/HyCl/x8g + pv8eH6f/Hh+q/x4frP8dHq3/HB2u/xwdsf8cHbP/HB20/xwctf8bG7f/Gxu5/xsbuv8aG7z/Ghu+/xoa + v/8aGcH/GRnC/xkZxP8ZGcT/GRnE/xgYxP8YGMX/GBjF/xcYxf8XGMX/FxjF/xcYxf8XGMb/FxjH/xYY + x/8WGMf/FRjH/xUYx/8UGMj/FBjI/xQYyP8TF8j/ExfI/xMXyP8SFsj/EhbI/xEVx/8QFcf/EBPG/xAT + xv8PEsb/DxHG/wgLxP8sJnn/z8fB//f19f/28vL/oqCg9QYGBnAAAABKAAAANQAAAB8AAAAPAAAABQAA + AAEAAAAAAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8AAwMDAAMDAwADAwMFfnx8y9DJyf/Uzc3/7Off/21oov8OELP/GRq8/xkauP8aGrf/Gxu0/xsc + sf8bHK//Gxys/xsdqv8cHaf/HB2l/x0eo/8dHqD/HR6d/x0fm/8fH5j/HyCW/yAhlP8gIZL/ICGT/yEi + lf8hIZj/ISGa/yAhm/8gIZ7/ICGg/yAhov8gIaT/ICGl/yAhp/8fIKr/HyCq/x4frP8eH67/Hh+v/x0e + sf8dHrP/HR61/xwctv8cHLf/HBu5/xwbu/8aG7z/Ghu+/xobv/8aGsH/GhnC/xkZw/8ZGcT/GRnE/xgY + xP8YGMX/GBjF/xcYxf8XGMX/FxjF/xcYxf8XGMX/FhjG/xYYx/8WGMf/FRfH/xUXx/8UF8f/FBfH/xQX + x/8TFsf/ExbH/xIVx/8SFcf/ERTH/xEUxv8RE8b/EBLF/xASxf8PEMT/DQ7I/xAPk/+flJf/+vj2//Lv + 7//Ny8v/KSkpmgAAAEsAAAA7AAAAIwAAABIAAAAHAAAAAgAAAAAAAAAA////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wAkJSUAJCUlACQlJSein5/208zM/97Z + 2P/Y08//Pz2f/xESvf8ZGr3/GRq6/xobt/8bHLX/Gxyy/xscsP8bHK7/Gx2r/x0eqP8dHqb/Hh+j/x4f + ov8fIJ//HyCd/yAgm/8hIZj/ISKW/yIik/8iI5P/IiSV/yIkmP8iIpr/ISKc/yEinf8iI5//ISKh/yEi + ov8hIqX/ISKn/yEiqP8hIqr/ICKs/x8grf8fIK7/HyCw/x4fsv8eH7P/HR61/x0ct/8cHLj/HBy5/xwc + u/8aG73/Ghu+/xobwP8aGsH/GhrC/xkZw/8ZGcT/GRnE/xkYxP8YGMX/GBjF/xcYxf8XGMX/FxjF/xYX + xf8WF8X/FhfG/xYXxv8WF8b/FRfG/xUWxv8VFsb/FBbF/xQWxf8TFcX/ExXF/xIUxv8SFMb/EhLF/xES + xf8QEsT/EBHD/w8Qw/8ND8b/CAms/2lefv/y8On/8O3t/+nl5f9RUFC/AAAAUQAAAEAAAAAoAAAAFQAA + AAkAAAADAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////ADY2NgA2NjYANjY2Zb65uf/Rycn/6OPh/7mzu/8mJqn/GRnD/xkavv8aG7v/Ghu5/xsb + tv8bHLP/Gxyx/xwdrv8cHqz/HB+q/x8fp/8fIKX/ICGj/yAhof8gIZ//ISKc/yIimv8iJJn/IyWW/yMk + lP8kJZX/JCaY/yQlmf8kJZv/JCWd/yQln/8kJaH/JCWi/yMjpP8jJKb/IySn/yIjqf8jI6z/ISKs/yAh + rv8gIbD/ICGx/x8gs/8fILT/Hh+1/x0et/8cHLj/HBy5/xwcu/8bHL3/Ghu+/xoav/8aGsH/GhrC/xoa + w/8ZGcT/GRnE/xkZxP8YGMT/GBjF/xgYxf8XGMX/FxjF/xYXxP8WF8T/FhfF/xUWxf8VFsX/FRbF/xQW + xv8UFcT/FBXE/xMUxP8SFMT/EhTF/xITxf8RE8T/EBLE/xARxP8PEMP/DxDD/w4PxP8HCb7/PTR4/+Da + 0v/y8PD/7+zs/4aFheYAAABgAAAARAAAAC4AAAAZAAAACwAAAAQAAAAAAAAAAP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAAEBAAABAQBlZGSbzcbG/9PN + zf/t6eL/jIas/x8ft/8jI8b/Hh/A/xkavP8aG7n/Gxu3/xwctf8cHbP/HR6w/x0erv8eH6v/HyGp/yAh + p/8gIqX/ISKj/yIjoP8iI53/IySc/yQkmv8kJpf/JSeV/yUnlf8mKJf/Jiia/yYnnP8mJ53/Jief/yYn + oP8mJ6P/Jiek/yYmpv8lJaf/JSSo/yQkqv8kJKz/IyOt/yEir/8hIrD/ICGy/yAhs/8gILX/Hx+1/x4e + t/8dHbj/HRy6/xwcu/8cHLz/Ghy9/xobvv8aGsD/GhrC/xoaw/8ZGcP/GRnE/xkZxP8YGMT/GBjE/xgX + xP8XF8X/FxfF/xYXxP8WF8T/FRfE/xUWxP8VFsX/FBXF/xQVxf8TFMT/ExTE/xIUxP8SE8P/EhPE/xES + xP8REsP/EBHD/xARw/8PEMP/Dw/D/woLxP8fGof/u7Kv//b08//x7e3/raur+xESEnoAAABHAAAAMwAA + AB0AAAAOAAAABQAAAAEAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wAAAQEAAAEBB4KAgM/Uzc3/2dTT/+fi2/9jX6P/HBzB/ycnx/8mJsP/ISK//xoc + u/8aG7j/HB22/x0ftP8eH7H/Hh+v/yAhrf8gIqv/IiOp/yMjp/8kJKX/JCWi/yUmof8mJ5//Jied/yYn + m/8oKpj/KCqW/ygql/8pKpr/KSqc/ykqnf8pKp//KSqg/ykqo/8pKqT/KCim/ygop/8oKKn/Jyeq/ycm + rP8mJq3/JCWu/yIkr/8iI7H/ISKy/yAitP8gIbT/HyC2/x8et/8eHrj/HR25/x0cu/8cHLz/Gxy9/xob + vv8aGr//GhrB/xoZwf8ZGcP/GRnE/xkZxP8YGMT/GBjE/xgXxP8XF8T/FxfE/xYWw/8WFsP/FhbE/xUW + xP8VFcT/FBXE/xQVxP8TFMT/ExTE/xITw/8SE8P/EhLD/xERwv8REcL/EBDC/xAPwv8PD8L/DQ3G/woJ + m/+TiJL/+Pbz/+3o6P/Qzc3/LS0tmwAAAEcAAAA3AAAAIQAAAA8AAAAGAAAAAQAAAAD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////ABQVFQAUFRUgn5yc9NjR + 0f/f29n/083L/0VEp/8jI8n/JyfH/ygoxf8oKML/JSa//x0euv8cHbf/Hh+1/x8gs/8gIbH/ICKv/yIj + rf8kJKv/JSSp/yUlp/8mJ6T/Jyij/ygpof8pKp//Kiuc/yosm/8qLZn/Ky2X/ysumf8rLpz/LC2d/ywt + n/8sLaD/Kyyj/ysspP8rLKX/Kyun/yoqqP8qKqr/KSmr/ygorP8nJ67/Jiav/yQmsP8kJbH/IySy/yIj + s/8hIrX/ICG2/yAgt/8eHrj/Hh25/x0duv8cHLz/Gxy8/xocvv8aG77/GhrA/xoZwf8aGcH/GRnC/xkZ + w/8YGMT/GBjE/xgYxP8XF8T/FxfE/xYWw/8WFsP/FRXD/xUVw/8VFcP/FBTE/xQUxP8TE8T/ExPD/xIS + wv8SEcL/ERHC/xERwv8QEML/EBDC/w8Pwv8ODsT/CQmt/2Zcgf/w7Ob/6+jo/+bi4v9KSkq6AAAATAAA + ADsAAAAkAAAAEgAAAAcAAAACAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8AMzMzADMzM1O5tbX/1s/P/+fj4P+8t73/LS2v/yYmzv8pKMn/KSnG/ykp + xP8qK8L/KSq//yMku/8fILf/ICG1/yIjs/8jJLH/JCSv/yUlrf8mJ6v/KCep/ykpp/8qK6X/Kyyj/ywt + ov8sLaD/LS+e/y4wm/8uMJr/LjCa/y8xm/8vMZ7/LzCf/y8woP8uMKP/LS+k/y4vpf8tLqf/LC2o/yws + qv8sLKv/Kyqs/yoqrf8pKa7/Jyiv/yUnsP8lJrH/JCWz/yMktP8hI7X/ICK2/yAgt/8fH7j/Hh65/x4d + uv8dHLv/HBy8/xobvf8aG73/Ghu//xobwP8aGcH/GRnB/xkZwf8YGML/GBjD/xgYxP8XF8T/FxfE/xYW + w/8WFsP/FRXD/xUVw/8UFMP/FBTD/xQTw/8TE8P/ExLD/xISwv8SEsL/ERHC/xERwv8QEML/EBDB/w8P + wf8HCLv/QTl6/+Te1v/t6ur/6OTk/3d2dtoAAABZAAAAPgAAACcAAAAVAAAACQAAAAMAAAAA////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wA6OTkAOjk5eM3H + x//W0ND/6+fi/5yWsv8pKbv/KSrP/ysryv8rK8j/KyvG/yssw/8sLcH/LS6//yoqu/8kJLf/IyS0/yQl + sv8mJ7H/Jyiw/ykprv8rK6z/LCuq/y0tqP8tL6X/LjCk/y8xov8xMaH/MTOf/zI0nP8yNJv/MjSc/zM1 + nv8zNKD/MzOh/zEzo/8xM6T/MTOm/zAyp/8vMaj/Ly+q/y4uq/8tLqv/LC2t/ywrrv8qK6//KCmw/yco + sf8mJ7H/JSaz/yQltP8iI7T/ISK2/yAgt/8fH7j/Hh64/x0duf8dHLv/HBy7/xscvP8aG73/Ghu+/xob + v/8ZGr//GRnA/xkYwP8YGMH/GBjC/xcXwv8XF8P/FxfD/xYWw/8WFsP/FRXD/xUVw/8UFMP/FBTD/xMT + w/8TE8P/EhLB/xISwf8REcH/ERHA/xEQv/8QEL7/EA++/wkLvv8qJYP/ysK///Hu7f/s6Oj/lZSU8QAA + AGMAAABBAAAAKwAAABcAAAAJAAAAAwAAAAD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AAEBAQBtbGyh083N/9nU1P/q5d3/f3ur/yMkxP8tLc//LS7M/y4u + yf8uLsf/Ly/F/y8ww/8wMMH/MTK//zExvP8rLLj/Jyi0/ycosv8qK7D/Kyyv/y0trf8uLqz/Ly+q/y8x + qP8xM6f/MjSl/zM0o/80NqL/NTeg/zY4nv82OJ3/Njie/zY4oP82OKL/Njej/zU3pP80Nqb/NDan/zM1 + qP8yNKr/MTKr/zAxq/8uL63/Li+u/y0ur/8sLK//Kiuw/ykpsv8mKLL/Jiez/yUmtP8jJLT/ISO1/yEi + tv8gILf/Hh64/x4euP8dHLr/HBy7/xwcu/8aG7v/Ghu8/xobvv8ZGr7/GRq//xgZv/8YGL//GBi//xcX + wP8XF8H/FhbB/xYWwf8WFcH/FRXB/xUUwf8UFMD/FBTA/xMTwP8TE8D/EhK//xISvv8REb3/EBG9/xAR + vf8PEbz/DA69/xYTj/+wpqf/8/Hw/+vm5v+zsLD8FxgYewAAAEIAAAAuAAAAGQAAAAsAAAADAAAAAP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAQEBBIB/ + f8bX0dH/3djY/+Te1/9pZaj/JCXN/y8v0P8vMM3/MDDL/zExyv8xMcj/MTPG/zIzxP80NcL/NjXA/zc3 + vv80Nbv/Li+2/ywss/8tLbH/LzCw/zEyr/8yM63/MzSr/zQ2qv82OKj/Njmm/zg5pf85OqP/Ojuh/zo8 + n/86PJ//Ojyh/zo8o/86O6T/Ojul/zg6p/84Oqf/Nzmo/zY3qv81Nqv/MzSs/zIzrf8xMq3/MDGu/y4v + r/8tLbD/Kyyw/yorsf8oKbL/Jiez/yUmtP8jJbT/IiS1/yEitv8gILb/Hx+3/x4et/8dHLj/HBy5/xwc + uv8bG7v/Gxu7/xobu/8aGrz/GRq9/xgavf8YGb7/GBi+/xcYvv8XF7//Fhe//xYXv/8VFr//FRW//xQV + vv8UFL3/ExS9/xMTvf8SE73/EhO9/xESvP8RErv/EBK6/xARuf8OD7z/DQyZ/5WKlv/18u//5+Li/8bD + w/8qKiqUAAAAQgAAADEAAAAbAAAADAAAAAQAAAAA////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wAAAQENj4yM59zW1v/h3dz/1tHO/1RSrf8qK9P/MDDS/zAx + 0P8yMs3/MzPL/zMzyf81Ncf/NjfF/zY3wv84OcH/OjvA/zw9v/88PLz/ODi5/zMztf8yMrL/MzSx/zY3 + sP83OK7/ODms/zk7q/87Par/Oz2o/z0+pv8+P6X/PkCj/z9Bof8/QaH/P0Gj/z5Apf8+P6X/Pj+n/zw+ + qP86Pan/Ojyq/zg6q/83Oav/Njet/zU1rf8yNK7/MTKv/y8wr/8uL7D/LC2w/yorsf8pKrL/Jyiz/yUm + s/8kJbT/IiO0/yEitf8gIbb/Hx+2/x4etv8dHbf/HBy4/xwcuf8bG7n/Gxu6/xsbuv8aGrv/Ghq8/xkZ + vP8YGbz/Fxm7/xcYu/8XGLz/Fhe8/xYXvf8VFr3/FRa8/xQVu/8UFbz/ExS7/xMUuv8TE7r/EhO6/xIS + uf8SErj/ERG3/xAQuf8LC6L/d2yL//Hu6f/l4eH/19PT/zU1NakAAABCAAAAMwAAAB4AAAAOAAAABAAA + AAH///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////ACUl + JSCppaX03tfX/+Tg3//MxcX/RUSy/y4u1v8yMtP/MzTR/zQ1z/82Nsz/NzfL/zg4yf85Ocf/OjvF/zs9 + xP89PsH/Pz/A/0BAv/9CQr3/QkK7/z4+uP85ObT/ODmy/zo7sf89PbD/Pj+u/z9BrP8/Qqv/QUOq/0JE + qP9DRKf/Q0Wl/0RFo/9DRaT/Q0Sl/0JEp/9CQ6j/QUKo/z9Bqv89QKr/PD6r/zs9rP86O63/ODit/zY3 + rf81Nq//MzSv/zEyr/8uL7D/LS6w/ywssP8pKrL/KCmy/yYns/8kJbP/IiOz/yEis/8gIbT/HyC1/x4e + tv8dHbb/HBy3/xwbuP8bG7j/Gxu5/xsbuP8aGrj/Ghq5/xkZuv8YGbr/GBi6/xgYuv8XF7r/Fxe6/xYW + uv8WFrr/FRa6/xUVuv8UFbn/FBS4/xQUuP8TE7f/ExO3/xIStv8SEbb/ERG3/woKqf9eVoX/7enh/+Xh + 4f/g29v/TExMuQAAAEYAAAA1AAAAHwAAAA4AAAAFAAAAAf///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8ALy8vPLezs/zc19f/5uLg/8K7vv85OLb/MzPY/zU1 + 1f82NtL/NzjQ/zg5z/87Osz/OzvL/zw8yv8+P8f/P0DG/0BBxf9DQ8P/RETC/0ZGwP9ISL7/SUm9/0lJ + u/9ERbf/QEG1/z9Asv9CQrH/Q0Ww/0RGr/9FR63/Rkis/0hIqv9ISaj/SEmn/0hJpv9HSKb/R0io/0ZH + qf9GR6n/REWq/0NEq/9BQ6v/P0Gt/z5Arf88Pa3/Ojqu/zc4rv82N6//NDWv/zIzr/8vMK//LS+w/yws + sP8qK7H/Jyqx/yYnsf8kJbL/IiOy/yEis/8gIbT/HiC0/x0etP8dHbT/HB21/xsbtf8bG7b/Gxu3/xsa + t/8aGrj/Ghm4/xkZt/8ZGbj/GBi4/xgYuP8XF7j/Fxe4/xYWuP8WFrj/FRW3/xUUt/8UFLb/FBS2/xMT + tf8TE7T/EhK0/xISs/8RErP/Bwqu/0pBfv/q5Nv/5uLi/+Hc3P9oZ2fLAAAATQAAADYAAAAgAAAADwAA + AAUAAAAB////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wAxMTFPwLy8/93W1v/r5+T/sKq3/zc3vP82Ntn/ODjV/zk51P86OtL/OzvQ/z09z/8/P83/QEDM/0JC + yv9DRMj/REbH/0dHxv9JSMT/SkrD/0xMwv9OTcD/UE+//1FSvv9QUbz/TE25/0hJtf9HSLL/SUuy/0pN + sf9LTa//TE6u/01Orf9NTqv/TU6p/01OqP9MTaj/S0yq/0pLqv9JSqv/R0ms/0VHrP9ERq3/QkSt/0BC + rv8+P67/PDyu/zk6r/83OK//NTav/zM0r/8wMq//Ly+w/y0tsP8rK7D/KCqw/yUnsP8kJbH/IySx/yEi + sv8gIbL/Hh+y/x0fs/8cHrP/HBy0/xsctP8bHLT/Gxy2/xoatv8aGrb/GRm1/xkZtf8YGLb/GBi2/xgX + tv8XF7b/Fxa2/xYWtf8WFbX/FRW0/xUVtP8UFLT/FBSz/xMUsv8TE7H/EhOw/xESsP8JC67/PDWA/9/Z + 0v/n4+P/4dzc/3h2dtgAAABSAAAANgAAACEAAAAPAAAABQAAAAH///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////ADU1NWLLxsb/3tjY/+vo5P+inLP/OzvC/zg4 + 2f86Otb/PDvW/z091P89PtL/QEDS/0JCz/9DQ87/RUTN/0ZHy/9JSsn/S0vI/01Nxv9PT8b/UFHE/1JS + w/9TU8L/VVXB/1dYwP9ZWr//WVq9/1VWuv9QUbb/T1C0/1BRs/9RUrL/UlKw/1NSrv9SVK3/UlOr/1JT + qv9RUqv/T1Cs/05PrP9NTq3/Skyt/0hLrf9FSa3/REau/0JDrv9AQa7/PT+u/zs7r/84Oa//Njev/zM0 + r/8wMa//Li+v/y0tr/8rK6//KCqv/yYor/8kJrD/IiOw/yEisP8fILH/Hh+x/x0esf8dHrL/Gxyy/xsc + sv8bHLP/Gxyz/xobtP8aG7T/GRq0/xkZs/8YGbP/GBi0/xcYtP8XF7T/Fhez/xYXs/8VFrL/FRax/xQV + sf8UFbH/ExSx/xITsP8SE67/ERKu/wsNrf80LoP/1c3J/+nl5P/j3t7/hoSE4wAAAFYAAAA3AAAAIQAA + AA8AAAAFAAAAAf///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8ANjY2bNDLy//f2tr/6ubg/5aRsf85Ocb/OzvZ/z091/8+Ptf/QD/X/0FB1f9DQ9P/RUXR/0dH + 0P9ISM//S0vN/01Oy/9PUMr/UVLJ/1NTyP9VVcf/V1jG/1hZxf9aW8T/W1zD/15fwv9gYcH/YWLA/2Fi + v/9dXrz/WVq4/1ZXtf9WV7T/WFiz/1hZsf9YWbD/V1iu/1ZXrP9VVqz/VFWt/1JTrv9QUa7/Tk+u/0tN + rv9IS67/RUiu/0NFr/9BQ6//PkCu/zw8rv85Oq7/Njev/zQ1rv8xMq//Li+u/y0trv8rLK//KCmv/yYm + rv8kJK//IiOv/yAhr/8fILD/Hh+w/x0esP8cHbD/HB2x/xscsf8bHLH/Ghux/xobsf8aG7L/GRqy/xka + sv8YGbH/GBmx/xcYsf8XGLH/Fhex/xYXr/8VFq//FBWv/xQVr/8TFK7/ExSu/xITrP8SE6z/DA6r/ysn + hv/Lw8L/6ubl/+Pd3f+LiYnqAAAAWAAAADcAAAAhAAAADwAAAAUAAAAB////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wA5OTmA29bW/+Db2//p5N//npi1/z4+ + x/89Pdn/Pz/X/0FB2P9CQtj/RUXW/0ZH1P9ISdP/SkvS/01M0P9PT8//UVHO/1NUzf9VVsz/VlfK/1lZ + yv9cXcn/Xl/H/19gx/9hYcb/Y2TG/2Rnxf9nZ8T/aGjC/2lqwv9qa8H/Z2i+/2Njuv9fYLf/XV21/11d + tP9dXrH/XF2w/1tcrv9ZWq7/V1iv/1VWr/9TU6//UFCv/01Pr/9KTK//R0mv/0VHr/9CRK7/P0Gu/zw9 + rv85Oq7/Nzet/zQ1rf8xMq3/Li+t/y0trf8rK63/KCit/yYmrf8kJa7/IiOu/yAhrv8eH67/HR6u/xwd + rv8cHa//Gxyv/xscsP8bHK//Ghuu/xobr/8ZGrD/GRqw/xgZr/8YGa//Fxiu/xYXrv8WF67/Fheu/xUW + rv8VFqz/FBWs/xQVq/8TFKv/ExSr/xITqv8MDqn/LSmG/8zFw//p5eT/5N7e/5mWlvYAAABcAAAANgAA + ACEAAAAPAAAABQAAAAH///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////ADk5OYDc19f/4t3d/+bh3P+Yk7X/PT3K/0BA2f9CQtf/RETY/0VG2f9IR9j/SUnX/0tL + 1f9OTtT/UVHT/1NS0v9UVdD/V1jO/1lZzv9cXM3/Xl7N/2Bhy/9jZMv/ZWbK/2dnyv9pasj/amzI/2xt + x/9vb8b/b3DG/3Bwxf9xcsT/cXLC/3Bxwf9sbb3/Z2e6/2Njtv9hYrT/X2Gy/15fsP9dXrD/Wluw/1hZ + sP9WVbD/U1Kw/09Qr/9MTa//SEuv/0ZIrv9DRa7/QEGu/z0+rv86Oq3/Nzet/zM0rf8wMa3/LjCs/y0s + rP8qKqz/KCis/yUlrP8kJKz/ISOs/yAhrP8eH6z/HR6s/xwdrP8bHKz/Gxys/xscrf8aG63/Ghut/xka + rf8ZGq3/GBmt/xgZrf8XGK3/Fxis/xYXrP8WF6z/FRas/xUWq/8UFar/ExSq/xMUqf8TFKj/ExSn/w4Q + qP8jIIf/wLe4/+zo5v/j3Nz/mZaW9gAAAFwAAAA2AAAAIQAAAA8AAAAFAAAAAf///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AOTk5gN3Y2P/j39//5uHb/5aS + tf8+P8v/Q0La/0VF2P9HR9n/SUnZ/0pK2f9MTNn/T0/Y/1BS1v9UVNX/V1bU/1lZ0/9cW9H/Xl7Q/2Fh + 0P9kZM//ZmbO/2hpzf9ra83/bG7M/29wzP9xcsv/cnPK/3R1yv92dsn/d3fI/3d3x/94eMb/eHjF/3d4 + xP93d8L/dHTA/25vvP9oarj/ZGW0/2Fjsv9fYLH/XV6x/1pbsf9XV7H/VFSw/1FRr/9NTq//SUuv/0ZI + rv9DRa3/QEKt/zw+rf85Oq3/Njes/zMzrP8vMKv/LS6r/ywsq/8qKqv/Jyeq/yQkqv8jI6r/IiKq/yAh + qv8eH6r/HR6q/xwdq/8cHar/HB2q/xscq/8aG6z/GRqr/xkaqv8ZGqv/GBmr/xgZq/8XGKr/Fxip/xYX + qf8WF6n/Fhep/xUWqP8VFqj/FBWm/xQVpf8TFKb/DxGm/yMfhv++tbb/6+jm/+Lc3P+YlZX2AAAAXAAA + ADYAAAAhAAAADwAAAAUAAAAB////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wA5OTmA3tnZ/+Xg4P/k39r/oZy1/0ZGyv9FRdv/R0fa/0pK2v9MTNn/TU3a/1BQ + 2/9SUtn/VFXY/1dY1/9aWtb/XV3U/2Bg1P9iYtP/ZmbS/2ho0f9ra9H/bW3R/3Bx0P9ydND/dXXP/3d4 + zv94ec7/enrN/3x8zf9+fsz/fn7L/35/yv9+f8n/fX/I/31+xv98fcX/e3zD/3l6wf90dr7/bnC6/2hp + tf9jZLP/X2Cy/1tdsf9ZWbH/VVWw/1JSsP9OT6//Skyu/0ZIrf9CRa3/P0Gt/zw+rP84Oqv/Njar/zI0 + q/8vMKr/LS2q/ysrqf8oKKn/Jiao/yQkqP8iI6n/ISKp/x8gqf8eH6n/HR6p/xwdqf8cHan/HB2p/xsc + qf8bHKn/Ghup/xkaqf8ZGqj/GRqo/xgZqP8YGaj/Fxin/xcYpv8WF6b/Fhem/xUWpf8VFqT/FBWk/xQU + o/8OD6P/LiqF/8jBv//p5uX/4dra/5iVlfYAAABbAAAANQAAACEAAAAQAAAABQAAAAH///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////ADk5OYDf2tr/49/f/+rl + 4P+hnLb/SEjL/0hI2/9KStr/TU3a/05O2/9RUdr/U1Pb/1VV2/9YWdr/WlzZ/15f2P9iYtf/ZGTW/2dn + 1f9qatX/bW3U/3Bw0/9zc9P/dnbT/3h50/97fNL/fX7S/3+A0v+AgtH/goPR/4SE0P+Fhc//hoXO/4aG + zf+Fhsz/hIXL/4ODyf+Bgsf/gIDG/31/w/96fcH/d3m+/3N0u/9sbrf/ZWe0/19gsv9aW7H/VVaw/1FR + r/9OT67/Skut/0ZHrf9CRKz/PkGs/zs9qv83Oqr/NDap/zIyqf8vMKj/LSyo/yoqqP8nKKf/JiWn/yMj + pv8hIqb/ICGn/x8gp/8dHqf/HR6n/xwdp/8cHaf/HB2m/xscpv8bHKf/Ghun/xobp/8ZGqb/GRqm/xgZ + pv8XGKb/Fxil/xYXo/8WF6P/FRaj/xUWo/8UFaL/FBWi/w4PoP8vKob/0MnI/+bh4P/g2dn/l5SU9gAA + AFsAAAA1AAAAIQAAAA8AAAAFAAAAAf///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8AOTk5gODc3P/l4OD/6ubh/6KeuP9MTM3/Skrb/05O2v9QUNv/UVHb/1RU + 3P9WVtz/WVnc/1xc3P9eXtv/YmLa/2Vm2f9oaNj/bGzX/29v1/9yctf/dXXW/3h41v97e9b/fn7W/4GC + 1v+DhNX/hYbV/4iJ1f+JitT/i4vU/4yM0/+MjNL/jI3R/4yM0P+LjM//iovN/4iJzP+Gh8r/g4TH/4CB + xP99fsL/enzA/3d5vf9zdbr/b3C5/2hptv9hYrT/Wluy/1NTr/9OT63/SUqs/0VGq/9BQ6r/PT+q/zk8 + qf83Oaj/Mzao/zAyp/8tL6f/Kyym/ykppv8nJ6b/JCSl/yIjpf8hIqX/HyCl/x4fpf8dHqX/HB2k/xwd + pP8cHaX/Gxyl/xscpP8aG6X/Ghul/xkapP8YGaT/GBmj/xgZo/8XGKP/Fxii/xYXov8WFqH/FRag/xQV + n/8UFZ//Dg+f/y8rh//Qysj/5N/e/9/Y2P+XlJT2AAAAWgAAADQAAAAgAAAADwAAAAUAAAAB////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wA6OTmA4d3d/+Xh + 4f/q5eH/o5+4/1FSz/9MTNz/UFDa/1JS2/9VVdz/V1fc/1pa3f9cXN3/X1/d/2Ji3f9lZtz/aWnc/21s + 2/9wcNr/dHTZ/3Z22f96etn/fn7Z/4CA2P+EhNj/iIfZ/4qL2P+Mjdj/jo/Y/5CR2P+Sktf/k5TX/5OU + 1v+TlNX/k5TU/5KT0v+RktH/j5DQ/42Nzv+Ki8v/h4jJ/4SExv+AgMT/fH3B/3h6vv90drz/cHK5/21u + uP9pabf/Y2S1/1xdsv9UVrD/TU6u/0dHq/9AQqn/PD6o/zc5p/81N6f/MTOm/y4wpf8sLqX/Kiuk/yco + pP8mJqP/IyOj/yEio/8gIaP/Hh+j/x4fo/8cHaP/HB2j/xwdo/8cHKP/Gxyj/xobov8aG6L/GRqi/xka + ov8YGaH/GBih/xcYoP8WGKD/Fheg/xYXnv8VFp3/FRad/xQWnf8OEJ3/MCyG/9HKyf/j3t3/3tfX/5eU + lPYAAABaAAAANAAAACAAAAAPAAAABQAAAAH///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////ADc3N3LZ1dX/6OPj/+rn4v+embb/UlLP/09P3f9SUtz/VVXc/1dX + 3P9aWtz/XFze/19f3v9jY97/Zmbf/2lp3v9sbd7/cHHd/3R03P94eNv/fHzc/39/3P+Dg9v/hobb/4qK + 2/+Ojdz/kJDc/5OS2/+Vldv/l5fb/5mZ2v+amtr/m5vZ/5uc2P+am9j/mZrW/5iY1f+WltT/k5TS/5GR + 0P+Ojs3/i4vK/4eHyP+Cg8X/fn/D/3l7wP91d7z/cHK6/21tt/9oabb/ZGW1/2Bhs/9bXLL/Vlex/1BR + r/9JSqz/QUOq/zs+qP81N6X/MDKk/y0vo/8qK6P/Jyii/yYnof8jJKH/IiOh/yAhoP8fIKD/Hh+g/x0e + of8cHqD/HB6g/xwdoP8bHKD/Gxug/xoboP8aGqD/GRqf/xkan/8YGp//Fxme/xcYnf8WGJ3/Fhid/xUX + nP8UF5v/FBaa/w4Rmf8wLYb/0svK/+Pe3f/b1NT/jYqK7wAAAFcAAAA0AAAAIAAAAA8AAAAFAAAAAf// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8ANTU1Y9TQ + 0P/q5ub/7Ofi/5iTs/9RUs7/UVHd/1VV3P9XV93/Wlrd/11d3f9fX97/Y2Pf/2Zm4P9qauD/bW3g/3Bw + 4P90dN//eHjf/3x83v+AgN7/hITd/4iI3v+MjN7/kJDe/5OT3v+Wlt7/mZne/5yc3v+ent7/oKDe/6Ki + 3v+jo93/o6Pc/6Kj2/+gotr/n6DZ/52e1/+am9b/l5jU/5OV0f+Qkc7/jI3M/4iJyf+DhMf/fn/E/3p7 + wf91d73/cXK6/21tt/9nabX/Y2Sz/15fsv9aW7H/Vlew/1JTr/9OT63/SUqs/0RGqv8/Qan/OTum/zU2 + pf8wMaT/Kyyi/ycooP8jJJ//ISKf/x8gnv8dHp7/HB2e/xsdnv8bHp7/HB6e/xsdnv8aHJ7/Ghye/xoc + nv8ZG53/GRuc/xganP8YGpz/Fxmb/xYYmv8WGJr/FRea/xUXmf8UFpf/DhGY/y4rhf/SzMv/4t7c/9nS + 0v+DgYHjAAAAVAAAADQAAAAfAAAADgAAAAUAAAAB////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wA1NTVk1tLS/+vn5//s6OL/mJOz/1RVz/9UVN3/V1fc/1pa + 3f9dXd3/X1/e/2Ji3v9mZuD/aWnh/21t4f9wcOH/dHTh/3h44f98fOH/gIHh/4WF4P+JieD/jY3g/5GR + 4f+VleH/mJng/5ud4P+goOH/pKPh/6am4f+oqOH/qqrh/6qq4f+qquD/qqrf/6iq3v+nqN3/pKXa/6Ch + 2f+en9j/mpvV/5WW0v+QkdD/jo7N/4mKyv+DhMf/f3/E/3l7wf91dr7/cHG7/2xst/9maLT/YmOy/11e + sf9ZWrD/VFau/1BSrf9MTqv/SUmq/0VGqf9BQqj/Pj+o/zs8p/83OKX/NDWl/zEypP8tLqL/KSqh/yYn + oP8jJZ//ISOe/x8hnv8eIJ3/HR+c/xwdnP8aHJz/Ghyb/xkbm/8ZG5r/GBqa/xcZmf8WGJn/FhiY/xUX + l/8VF5f/FReX/xQWlv8PEpb/Mi6G/9LMzP/h3dz/2NHR/4SBgeQAAABUAAAANAAAAB8AAAAOAAAABQAA + AAH///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////ADY1 + NWTW09P/6+jo/+zn4v+Yk7P/VlbQ/1ZX3v9aWtz/XFzd/19f3v9iYt//ZWXf/2lp4P9sbOH/cHDh/3R0 + 4v93d+P/fHzj/4CA4/+EheP/iYnj/46O4/+SkuP/lZbj/5ma4/+en+P/oqPk/6an5P+qquX/rK3l/6+v + 5P+xseX/srLk/7Ky5P+ysuP/sLDi/66v4f+srN//qKnd/6Sl2/+hotn/m53W/5aX0/+Sk9D/jo7N/4iJ + y/+DhMj/fn/E/3l6wf90db7/b3C7/2prt/9lZrT/YWKy/1tcr/9XWK7/U1Ws/09Rq/9LTKr/R0mo/0NF + p/9AQab/PT6l/zo7pf83OKP/NDWj/zM0o/8yMaL/MDCi/y0uof8sLaH/Kyyg/ykrn/8oKp//Jiif/yUm + nv8jJZ3/IiSc/yAinP8fIZv/HR+Z/xwemf8bHZj/GhyX/xoblv8ZGpb/GBmV/xYXl/87N4r/0s3N/+Dc + 2v/Xz8//hIGB5AAAAFQAAAA0AAAAHwAAAA4AAAAFAAAAAf///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8ANjY2ZNfU1P/s6en/7Ojj/5iTs/9YWND/WVnf/11d + 3f9fX93/YWHe/2Vl4P9nZ+D/a2vg/29v4f9zc+L/d3fi/3t74/9/f+T/g4Pl/4iI5f+MjeX/kpLk/5aW + 5P+amuX/n5/l/6Sk5v+oqeb/q63n/7Cw5/+ztOf/trfn/7m55/+6uuf/urrn/7q65v+4uOX/tbXl/7Oz + 4/+vsOH/q6ze/6eo2/+iotr/nJ3X/5eX0/+SktH/jY7O/4eIyv+Cg8j/fX3F/3d4wf9zc77/bm67/2hp + uP9kZbX/Xl+x/1pbr/9WV6z/UVOq/01Pqf9JS6j/RUin/0JEpv8/QKX/PD2k/zk7o/82OKL/NDWh/zMz + of8xMaD/MDCg/y4voP8tLp//LS6e/yssnv8qK57/KSqe/ykpnf8oKZ3/Jyic/yYnm/8lJpr/JCWa/yMk + mv8iI5n/ICKY/yAhlv8eH5b/Gx2X/z06i//Tzc3/4NrZ/9bPz/+DgYHkAAAAVAAAADQAAAAfAAAADgAA + AAUAAAAB////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wA2NTVk2NXV/+7q6v/s6eT/l5Kz/1pZ0f9bW9//Xl7e/2Fh3v9kZN//Z2fg/2tr4P9ubuH/cnLh/3Z2 + 4/96euT/fn7k/4KC5f+Hh+f/jIvm/5CR5v+Vlub/mprn/5+f5/+kpOf/qano/66u6f+ys+n/trfq/7q7 + 6v++v+v/wMDr/8LC6//Cwuv/wsLq/8DA6f++vef/urrl/7a25P+ysuL/ra3f/6eo3f+hotr/nJ3W/5aX + 1P+RktH/jIzN/4aGy/+Agcj/enzE/3V1wf9wcb7/a2y7/2dnuP9hY7X/XV2y/1hZr/9UVqz/UFGp/0tO + p/9ISqb/REal/0JDo/8+QKP/Oz2i/zk7of82OKD/MzWf/zIzn/8xMZ7/MDCe/y8wnf8uL53/LS6d/ywt + nf8rLJ3/Kiuc/ykpm/8oKZr/Jyia/yYomf8lJpj/JCaX/yMll/8iJJb/ISOV/yAik/8cIJX/PjuL/9PN + zv/f2tn/1c3N/4OAgOQAAABUAAAANAAAAB8AAAAOAAAABQAAAAH///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////ADY2NmTZ1tb/7+vr/+rm4v+nobj/YGDQ/1xc + 3/9hYd7/Y2Pf/2Zm3/9qauD/bW3h/3Bw4v90dOL/eHjj/3x85P+BgeX/hYXm/4qK5/+Pj+j/lJTo/5mZ + 5/+enuj/o6Pp/6mp6v+urur/s7Pr/7i57P+9vuz/wcLt/8TG7f/IyO7/ysru/8rK7v/Jyu3/yMjs/8XF + 6//Bwen/vb3m/7i45f+zsuL/ra3f/6eo3P+hotn/mpzW/5WW1P+Pj9D/iorN/4OEyv9+fsf/eXnE/3N0 + wf9tbr7/aWm6/2Rkt/9fYLX/W1yy/1ZYr/9SVK3/TlCq/0pMp/9HSaX/Q0Wj/0BCov88PqH/Ojuf/zg6 + nv83OJ7/NDae/zEznf8xMpz/MDGc/y8wnP8vMJz/Li+b/y0um/8sLZv/KiuZ/ykqmf8oKpj/KCmY/yYp + lv8mJ5b/JSaW/yQmlf8jJZP/IiST/x0glP9HQ4v/1tDP/97Y2P/UzMz/g4CA5AAAAFMAAAAzAAAAHwAA + AA8AAAAFAAAAAf///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8ANjY2ZNrX1//w7e3/6OTh/6ymtv9mZ9H/Xl7g/2Nj3v9lZd//aGjg/2xs4P9vb+H/c3Pi/3d3 + 4v97e+P/f3/l/4OD5v+IiOb/jY3n/5KS6P+Xl+n/nZ3q/6Ki6v+np+v/ra3r/7Kz7P+5uO3/vr7u/8PD + 7//IyPD/zMzw/8/P8f/R0fH/0tLx/9HS8P/P0PD/zMzu/8jI7P/Dw+r/vr7n/7i45f+xsuL/q6zf/6Sm + 3P+fn9n/mJnW/5OS0/+NjdD/hofN/4CByf97fMb/dXfE/3Bwwf9rbL3/Zme7/2FjuP9cXrX/WFmy/1RV + r/9QUa3/TE6r/0hKqf9FR6b/QkOl/z9Bo/87PqD/OTue/zg5nv83N53/NDWb/zIzm/8xMpv/MDGa/zAx + mv8vMJr/Li+Z/y0umf8sLZj/KyyX/yorl/8oK5b/JyqW/yYolv8mJ5X/JSeV/yQmlf8jJZX/HiGW/1NO + jv/f2tf/29bV/9LLy/+CgIDkAAAAUgAAADMAAAAfAAAADgAAAAUAAAAB////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wA2NjZk29jY/+/t7f/w7er/q6W2/2dn + 0f9gYOD/ZGTf/2ho3/9qauD/bm7h/3Fx4f91deL/eXnj/3195P+BgeX/hobm/4qK5/+QkOj/lJTp/5qa + 6v+fn+v/pqbs/6ur7f+xse3/trbu/7297//Dw+//ycnx/87O8v/T0/P/19f0/9nZ9P/a2vT/2drz/9fX + 8v/T1PH/zc7u/8nJ7P/Dw+r/vLzn/7a25f+vsOL/qKnf/6Kj3P+bnNn/lZbV/5CQ0v+KidD/hIPM/31+ + yf94ecb/c3PD/21uwP9oab7/YmW6/15guP9ZW7X/VVez/1JTsP9OT67/Skyr/0dIqv9DRaj/QUKl/z0/ + pP87PKP/Ojqh/zg5n/82OJ7/NDWd/zI0nP8xMpz/MTGc/zAxm/8wMJr/LzCa/y4vmv8tLpn/LC2Z/yot + mf8pK5n/KCqY/ycpmP8mKJj/JieY/yUmmP8fIZr/VE+R/+Xh3v/X0ND/0svL/4J/f+QAAABSAAAAMgAA + AB4AAAANAAAABQAAAAH///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////ADY2NmTb2dn/8O3t//Hu6/+sprb/amzT/2Fh4f9mZuD/aWng/2tr4P9wcOL/c3Pi/3d3 + 4v97e+T/f3/k/4SE5f+IiOf/jY3n/5KS6P+Xl+r/nZ3q/6Ki7P+np+3/ra3t/7S07v+7u+//wMDw/8fH + 8f/NzfL/1NT0/9nZ9f/e3vb/4uL3/+Pj9//i4vb/3t71/9nZ9P/U1PH/zs7v/8fH7P/AwOn/urrn/7Ky + 5P+sq+H/paXe/56f2/+Xmdj/kpLV/4yL0v+Fhs7/gH/M/3p6yf91dcb/b3DC/2prwP9lZr3/YGK7/1te + uP9XWbb/U1Wz/09RsP9MTa7/SEqs/0VHq/9CQqj/QECn/z0+pf86O6T/OTmi/zg4ov83N6D/NTWg/zQ0 + n/8zNJ//MjOe/zExnv8wMJ7/LzCd/y4wnP8tL5z/LC6c/yssnP8qK5z/KSqc/ycpnP8mJ5z/JSac/yIj + nf9ZVJT/5eDd/9TOzv/Rycn/gX5+5AAAAFIAAAAyAAAAHgAAAA0AAAAFAAAAAf///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8ANjY2Zt3a2v/y7u7/8e7r/62n + t/9tb9T/Y2Ph/2ho3/9qauH/bW3h/3Fx4f90dOL/eHjj/3195P+BgeX/hYXm/4qK5/+Ojuj/lJTp/5mZ + 6v+enuv/paXs/6ur7v+wsO7/t7fv/7298P/ExPH/y8vy/9HR9P/Y2PX/39/2/+Xl+f/p6fn/6+v5/+rq + +f/m5vj/39/1/9nZ8//R0vH/ysvu/8TE6/+8vOj/tbXl/66u4v+np+D/oaHd/5qZ2f+TlNf/jo7U/4eH + 0f+Cgs7/fXzL/3Z3yP9xcsX/a2zD/2ZnwP9iY73/XV+7/1lauP9UVrX/UFK0/01Psv9JS6//R0it/0RF + q/9BQqr/Pz+p/zw9p/86Oqb/ODik/zc4o/82NqP/NTaj/zQ1ov8zNKL/MjOh/zEyoP8wMaD/MDCg/y4w + oP8tL5//LC6f/yssn/8qK5//KSqf/ycpn/8mKJ//JCah/19amP/l4N7/1M3N/9DJyf+Cf3/kAAAAUgAA + ADEAAAAdAAAADQAAAAQAAAAB////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wAzMzNX1NLS//Tx8f/y7+z/rKa3/2pr0v9lZeL/aWng/2xs4f9vb+H/cnLh/3Z2 + 4/96euP/fn7k/4KC5f+Ghub/i4vn/5CQ6P+Vlen/mprq/6Cg6/+lpez/rKzu/7Ky7/+4uPD/v7/y/8bG + 8v/NzfP/1dX1/9zc9v/j4/j/6ur6//Hx/P/09Pz/8fH8/+vr+v/k5Pf/3Nz0/9TU8v/Nze//xsbs/76+ + 6f+3t+f/sLDk/6mp4f+jot7/m5vb/5SW2P+Pj9b/iYnT/4KD0P99fs3/eHjK/3JzyP9tbsT/aGnC/2Nk + wP9eYL3/Wlu6/1ZXuP9TVLb/T1C1/0tMs/9ISbD/Rkev/0JDrf9AQaz/Pj6q/zo8qf84Oqj/ODin/zc4 + pv82N6X/NTel/zQ2pf8zNaT/MTSj/zAyo/8wMaP/LzCj/y8wo/8tMKP/LC6j/ystov8qLKL/KSyj/ycq + o/8iJaP/V1KV/+bi3v/TzMz/zsbG/3l2dtwAAABOAAAAMAAAABwAAAANAAAABAAAAAD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AEpKSkbKyMj/9vPz//Pw + 7f+qpLb/YmPO/2dn4v9ra+D/bW3g/3Bw4v90dOL/eHjj/3t75P9/f+X/g4Pl/4iI5/+Njef/kZHo/5eX + 6f+cnOr/oaHs/6io7f+tre7/s7Pv/7q68P/AwPL/yMjz/87O9f/W1vb/3t74/+bm+f/u7vr/9vb9//z8 + /v/39/3/7+/7/+bm+P/e3vX/1tbz/87O8P/Hx+7/wMDr/7m56P+xseX/qqri/6Oj3/+cnNz/lpba/4+Q + 1/+Ki9X/hITS/31/z/94ecz/c3XK/25vx/9pasT/ZWXC/2Bhv/9cXL3/V1i7/1NUuf9QUbf/TE21/0lK + s/9HR7L/RESw/0BBrv8/P63/PT6s/zs8q/85Oqr/ODmp/zc5qf83OKn/NTin/zQ3p/8zNqf/MjWn/zEz + pv8xMqb/MDGm/y8xpv8uMKb/LS+l/ystpv8rLKb/KSum/yMlpv9UUJX/5+Pf/9PLy//LxMT/bmxs0AAA + AEgAAAAuAAAAGwAAAAsAAAAEAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8AZ2dnSMjGxv/39PT/8/Ht/6qktv9iY87/aWni/2xs4f9ubuH/cXHh/3V1 + 4/95eeP/fHzk/4CA5f+FheX/iYnn/42N6P+Skun/l5fq/52d6v+iouz/p6ft/66u7v+zs/D/urrx/8HB + 8v/Hx/T/z8/1/9bW9v/d3fj/5eX5/+3t+v/09P3/+fn9//b2/f/u7vv/5ub4/97e9v/W1vP/zs7x/8bH + 7v/AwOz/ubjp/7Ky5v+qquP/pKTh/52d3v+Wl9v/kZLY/4uM1f+EhdP/f4DR/3l6zv90dcv/b3DK/2ps + x/9lZ8T/YWLC/11ev/9ZWr7/VVa7/1FSuf9NTrj/Sku2/0hIs/9FRbL/QkOx/0BAsP8/P67/PT6t/zo8 + rf85Oq3/ODms/zg5q/84OKv/Nzir/zU3qv80Nqr/MzSq/zIzqf8xMqn/MDGo/zAwqP8vMKn/LS+p/ywt + qP8rLKj/JCWp/1RQlv/o5OD/0crK/8rCwv9vbW3QAAAARAAAACsAAAAYAAAACgAAAAMAAAAA////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wBjY2NIycfH//f1 + 9f/z8e3/rKa3/2do0P9paeL/a2vg/25u4v9ycuL/dnbi/3p65P99feT/gYHl/4WF5v+Jieb/jo7o/5OT + 6P+YmOr/nZ3r/6Ki7P+np+3/rq7u/7Oz7/+6uvH/wcHy/8fH8//OzvT/1dX2/9vb+P/i4vn/6en6/+7u + +//x8fz/7+/8/+rq+v/j4/f/3Nz1/9XV8//OzvD/xsfv/76/7P+4uer/sbLn/6uq5P+kpOL/nZ3f/5aX + 3P+Qktr/i4vX/4WG1f9/gNP/envQ/3V1zf9vccz/amvJ/2Znxv9hY8T/Xl/C/1pbwP9WV77/UlO7/09Q + uv9MTLn/SUm3/0ZGtf9ERLT/QUKz/z9Asv8+PrD/PD2w/zs8r/85Oq//OTqv/zk4rv84OK7/Nzit/zU3 + rP81Nq3/MzSt/zIzrP8xMqz/MDCs/y8wq/8tLqv/Kyyq/ygpqv8nKaz/Xlma/+fj3//Qycn/ycHB/3Bu + bs0AAAA8AAAAJQAAABQAAAAJAAAAAgAAAAD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AGNjY0jKyMj/+ff3//Tx7v+po7f/d3jU/3195v96euP/eHjj/3V1 + 4v92duP/eXnk/3195P+BgeX/hYXm/4qK5/+Ojuj/k5Pp/5iY6v+dnev/oqLs/6en7f+uru7/s7Pv/7i4 + 8f+/v/L/xsbz/8zM9f/S0vb/2dn3/97e+P/j4/n/5+f6/+np+v/o6Pn/5OT4/9/f9//Y2PX/0dHz/8vL + 8P/Fxe//vb7s/7a36v+vsOf/qqrl/6Oj4/+dneD/l5fe/5CS2/+Li9n/hYbW/4CA1P96e9H/dXbP/3Bx + zv9sbMv/ZmjI/2Jjx/9fX8X/W1vD/1dXwf9TVL7/UFG9/01Nu/9KSrr/R0e4/0VFt/9DRLb/QUK1/0BA + tP8+P7P/PD2y/zs8sv87PLL/Ojux/zk5sf84ObH/ODiw/zY3sP81Na//MzSv/zAxrv8uMK7/MjOv/zo6 + sv9HSLj/UFG9/11fw/9pZKD/5N/e/9DJyP/IwMD/cW5uygAAADIAAAAdAAAAEAAAAAYAAAABAAAAAP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AY2NjScvK + yv/6+Pj/9PLv/7SuvP9rbM3/g4Pq/4mI6f+MjOn/j4/o/4yM5/+IiOb/hITm/4KC5f+Fheb/iYnn/46O + 5/+Skun/mJjp/52d6/+hoez/p6ft/6ys7v+xse//uLjw/7298v/Dw/P/yMj0/8/P9f/U1Pf/2dn3/97e + 9//g4Pj/4eH5/+Dg+P/d3ff/2dn2/9TU9P/OzvL/yMjx/8LB7/+7vOz/tbbq/66v6P+oqeX/oaPj/5uc + 4f+Wlt//kZHc/4qL2v+Fhtf/gIDW/3p70/92dtH/cHLP/2xszP9naMv/Y2TJ/2Bgx/9cW8T/WFfC/1RU + wP9RUb//Tk++/0tMvf9ISbv/Rka6/0RFuP9BQ7f/QEG3/z9Atv89P7b/PD60/zw9tP87PLT/OTuz/zk6 + s/83OLP/MzWx/zQ2sf87PbT/S0y7/1xdwv9tbcj/cnPL/3Fyzf9ub83/T1HB/1lTlP/r5+L/zsbG/8e/ + v/9zcXHHAAAAJQAAABQAAAALAAAABAAAAAEAAAAA////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wBeXl4vvLq6+f37+//39fX/1c/N/4uJvP9lZsj/bm/S/3Fy + 2P93eOD/iYnn/5OT6/+YmOv/mJjq/5OT6f+Pj+j/jo7o/5GR6P+Wlun/nJzq/6Gh6/+lpez/q6vu/7Cw + 7/+2tvD/u7vx/8DA8v/FxfP/ysr0/8/P9f/U1Pb/19f3/9nZ9//a2vf/2dn3/9fX9v/U1PT/z8/z/8rK + 8v/ExPH/v7/v/7m57P+zs+r/razp/6en5/+goeT/m5vi/5aW4P+QkN7/iorb/4WF2f+Af9f/envU/3Z2 + 0v9wcdD/bG3O/2dpzf9jZMv/YGDJ/1xcx/9YWMT/VlbD/1JSwv9PT8D/TEy+/0lKvv9GR7z/RUa7/0JE + uv9BQbr/QEC5/z4/uP89P7j/PD63/zs8t/84OrX/Nji0/z4+t/9QUL7/ZGXG/3N0zP90dc7/Z2jK/1FT + wv8+QLj/MzSq/ysrof8wLZD/opuu//Dt6f/Hv7//xb29/2BfX6wAAAASAAAADQAAAAYAAAACAAAAAQAA + AAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AF1d + XQWOjo7L+PX1//b09P/y8O//1tDP/8O9wv+no7f/npu+/42Lv/94d8T/dXbR/31+3P+Mjef/nJzt/6Gh + 7f+goOv/m5vq/5iY6v+amur/np7r/6Sk7P+pqe3/rq7v/7Oz7/+4uPD/vb3y/8HB8v/GxvP/ysr0/87O + 9f/R0fb/09P2/9PT9v/S0vb/0ND1/87O8//KyvP/xcXx/8DA8P+7u+7/trbs/6+v6v+qqun/paXn/5+f + 5P+amuL/lJTg/4+P3v+Kitz/hYXa/39/2P96etb/dnXT/3Fx0v9sbdD/aGjO/2VkzP9hYcv/XV3I/1lZ + x/9WVsb/U1PE/1BRw/9NTsD/SkvA/0hJv/9GR77/REW9/0JDvP9AQbv/QEC7/z8/u/87PLn/PD25/0lK + vv9gYcb/dHTN/3V1z/9jZMr/SUu+/zc4rf8zMp7/S0eX/2ljmv+Lhaj/saq4/83HyP/v7On/0MrK/8e+ + vv+zrKz/MTIyaQAAAAIAAAAIAAAAAwAAAAEAAAAAAAAAAP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8AXV1dAGFhYVvCwMD//Pr6//Ty8v/08vL/8O7s//Du + 6v/p5N7/3NbR/8vFxv+wq7r/mZa8/4GAwP99ftH/h4jf/5qa6/+np+//qanu/6Wl7f+goOv/oaHr/6am + 7P+rq+7/sLDv/7W17/+5ufH/vb3y/8HB8v/FxfP/yMjz/8rK9P/MzPT/zMz0/8zM9P/KyvT/x8f0/8TE + 8v/AwPD/vLzv/7e37f+ysuz/ra3r/6io6f+iouf/nZ3l/5iY4/+Tk+L/jo7g/4mJ3f+EhNv/f3/a/3p6 + 1/91ddX/cXHU/2xs0f9oaND/ZWXP/2FhzP9dXcv/WlrJ/1dXyP9UVMf/UVHF/05PxP9LTML/SUrB/0ZH + wf9FRsD/REW+/0FCvv8+P7z/QEC9/1NUxP9rbM3/eHjS/2xsz/9PUML/OTqv/zo5nv9dWJj/j4mp/8C5 + wP/e2db/8Ozk/+3o4//n4uD/3tnY/8nCwv/FvLz/xr6+/3Z0dMsNDQ0SAAAABAAAAAMAAAABAAAAAAAA + AAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wBdXV0AYWFhAGlpaYi9vLz/8/Dw//n29v/39PT/9PHx//Tx8f/18vL/8e7t/+/s6f/l4Nv/0cvL/7ex + vf+YlLv/hoXG/4iJ2f+amun/q6vw/7Cw8P+srO3/p6ft/6io7f+srO3/sbHv/7W18P+5ufH/vLzx/8DA + 8v/CwvP/xMTz/8bG8//GxvP/xcXz/8XF8//CwvP/v7/y/7u78f+3t+//s7Pu/6+v7P+qqur/paXp/6Cg + 6P+bm+b/l5fk/5KS4v+NjeD/h4ff/4OD3f9+ftr/eXnZ/3V11/9xcdb/bGzT/2hp0v9kZdH/YGHO/15e + zP9aWsz/V1fK/1RUyf9RUcj/T0/G/0xMxf9KS8T/SEnD/0ZGwv9CQ8D/Q0TB/1VWxv9wcM//eHnU/2Rl + zv9FRrv/Ozuk/1lVm/+Ri6n/ycPG/+rl4P/u6+X/49/d/9TOzv/KwsL/xr6+/8S7u//Hvb3/yb+//7+3 + t/+Afn7eGBkZMQ0NDQAAAAADAAAAAQAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AF1dXQBhYWEAaWlpAGFhYU+HhobErays98G/ + v/7Z1tb/6OXl//Hu7v/08fH/8O3t//Hu7//y7+//7uvo/+Pd2P/KxMX/qaO5/5COwv+Li9T/m5vm/7Cw + 8f+1tfD/sbHv/6ys7v+tre7/sbHv/7W18P+4uPD/u7vx/7298f++vvL/v7/y/7+/8v+/v/L/vr7y/7y8 + 8f+6uvH/trbw/7Oz7/+vr+7/q6vs/6am6/+ioun/nZ7o/5ma5v+UleX/kJDj/4uL4f+Ght//goLe/319 + 3P95edr/dXXZ/3Bw1v9sbNX/aGjU/2Rl0v9hYtH/Xl7P/1pbzv9XWMz/VFTL/1JSyv9PUMj/TU3H/0tL + xv9GR8T/R0fE/1dXyf9xcdH/eHjW/19gzf9CQ7f/RkOg/3ZxoP+4sbv/5eDa/+/r5f/h3Nr/z8nJ/8e/ + v//Hvb3/ycDA/8W9vf/Aubn/s62t/6OenvyIhYXoUlJSkRMTExwYGRkAAAAAAQAAAAEAAAAAAAAAAAAA + AAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8AXV1dAGFhYQBpaWkAYWFhAF5eXgNcXFwdYWFhQmdnZ2x3dnaclZSU1LSysvvW09P/6+jo//Ht + 7f/t6ur/7+zs/+/s7P/q5+L/1c/M/7Otu/+Rj73/kZHU/6Gh6P+1tfL/uLjx/7Oz7/+uru7/sLDu/7Oz + 7/+2tvD/uLjw/7m58f+6uvH/urrx/7m58f+4uPH/t7fw/7S08P+xse//rq7v/6ur7v+np+z/o6Pr/5+f + 6v+am+j/lpbm/5KS5P+NjuP/iYrj/4WF4P+AgN//fHze/3h42/90dNr/cHDY/2xs1v9oaNX/ZWXU/2Fi + 0/9dXtH/WlvP/1dYzv9VVs3/UlPM/1BQy/9MTcn/SErI/1NVy/9vcNP/envZ/2Fi0P9ERLn/UE2h/4aA + pf/Mxsf/7enj/+fi4P/Uzs3/yMDA/8e/v//JwcH/w7u7/7Krq/+Sjo7td3R0uUxMTIUwMDBYKisrMgME + BA5SUlIAExMTABgZGQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wBdXV0AYWFhAGlpaQBhYWEAXl5eAFxc + XABhYWEAZ2dnAHd2dgBcXFwGXV1dMWhoaHSGhYW9rqys+dbT0//r5+f/7enp/+rn5//u6+v/6+jl/9nT + z/+5s73/mZbA/5CR1f+oqev/ubnz/7m58f+xse//rq7u/7Cw7v+zs+//tLTv/7W17/+0tO//tLTv/7Oz + 7/+ysu//r6/v/62t7v+qqu7/p6fs/6Oj7P+goOv/nJzq/5iX6f+Tk+f/j4/m/4qL5f+Hh+P/g4Ph/35/ + 4P97e9//d3fd/3Nz3P9vb9v/a2vY/2dn1/9kZNb/YWHV/15e0/9bW9L/WFjR/1VWz/9SU87/Tk7M/1FS + zf9patT/fH3b/2lq1f9HSb3/T0yj/5KLqf/V0M3/7enj/+Hd2//NxsX/x76+/8rBwf/Fvb3/sKqq/4uH + h+JhYGCbNDQ0VBQUFBkAAAABTExMADAwMAAqKysAAwQEAFJSUgATExMAGBkZAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AF1dXQBhYWEAaWlpAGFhYQBeXl4AXFxcAGFhYQBnZ2cAd3Z2AFxcXABdXV0AaGhoAIaF + hQBcXFwqamlpf42MjNe/vb3/5ODg/+vn5//o5OT/6+no/+zo5v/Y0s//ta+8/5KQwP+XmNv/r6/u/7u7 + 8/+1tfD/rq7u/6ys7v+uru7/r6/v/6+v7/+vr+//rq7u/62t7v+rq+7/qKjt/6Wl7f+jo+z/oKDr/5yc + 6v+YmOr/lZXp/5GR6P+Njef/iIjm/4WF5f+BgeL/fX7h/3l64P92dt3/cnLd/25v3P9ra9r/Z2fY/2Vl + 2P9hYdf/Xl7V/1tb1P9YWNL/VFXR/1FS0P9hYtT/enrc/3Z23P9SU8f/TEqo/4iCp//Qysr/7enk/97Z + 2f/Kw8P/yL+//8rCwv++t7f/m5eX9WhmZq8zMzNXEBAQEGFgYAA0NDQAFBQUAAAAAABMTEwAMDAwACor + KwADBAQAUlJSABMTEwAYGRkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AXV1dAGFhYQBpaWkAYWFhAF5e + XgBcXFwAYWFhAGdnZwB3dnYAXFxcAF1dXQBoaGgAhoWFAFxcXABqaWkAXV1dCGBgYFB9fHy3sa6u+9zY + 2P/p5eX/5eHh/+rn5//r5+T/083L/6ynuv+Ojsb/n5/j/7W18v+5ufH/r6/u/6mp7f+qqu3/qqrt/6qq + 7f+pqe3/p6fs/6am7P+kpOz/oaHs/5+f6/+cnOr/mZnq/5aW6v+Skun/jo7o/4uL5v+Hh+b/g4Pl/39/ + 5P98e+L/eHjh/3R04P9wcd7/bW7d/2pq3P9naNr/ZGXZ/2Fh2P9eXtf/W1vV/1dX1P9aWtX/c3Pb/39/ + 4P9iYtP/Skmz/3Nvo//Gv8L/7enj/+Dc2//Kw8P/yMDA/8rBwf+3sbH/jImJ5kxLS4chIiIpaGZmADMz + MwAQEBAAYWBgADQ0NAAUFBQAAAAAAExMTAAwMDAAKisrAAMEBABSUlIAExMTABgZGQAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wBdXV0AYWFhAGlpaQBhYWEAXl5eAFxcXABhYWEAZ2dnAHd2dgBcXFwAXV1dAGho + aACGhYUAXFxcAGppaQBdXV0AYGBgAH18fABdXl43dXR0rKuoqPzb19f/5+Li/+Pe3v/q5+b/5+Pf/8rD + xf+dmbv/kpLS/6ip6/+4uPL/sbHv/6en7P+kpOz/paXs/6Sk7P+jo+z/oqLs/6Cg7P+enuv/m5vq/5iY + 6v+Vlen/kpLo/4+P6P+MjOf/iYnn/4WF5v+BgeX/fn7k/3p64/93d+P/c3Ph/3Bv4P9tbN//aWrd/2Zn + 3P9jZNv/YGHa/11e2P9ZWdf/Zmba/35/4f92d+D/UlLE/15bpf+spbT/6OTe/+bh3//Nxsb/x7+//8vC + wv+3sbH/hYOD4EVGRnQQEREVTEtLACEiIgBoZmYAMzMzABAQEABhYGAANDQ0ABQUFAAAAAAATExMADAw + MAAqKysAAwQEAFJSUgATExMAGBkZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AF1dXQBhYWEAaWlpAGFh + YQBeXl4AXFxcAGFhYQBnZ2cAd3Z2AFxcXABdXV0AaGhoAIaFhQBcXFwAamlpAF1dXQBgYGAAfXx8AF1e + XgB1dHQAXFxcNnd2drCxrq7+39vb/+Pe3v/i3t7/6+fm/9/a1f+2sbz/jozA/5eX3v+xsfH/srLv/6Wl + 7P+goOv/oKDs/5+f6/+dnev/nJzr/5qa6v+Xl+n/lZXp/5KS6f+Pj+j/jIzo/4mJ5/+Ghub/g4Pl/39/ + 5f98fOT/eXnj/3V14/9ycuL/b2/g/2xs4P9pad//Zmbe/2Nj3f9eX9v/Xl7a/3Jy3/+Dg+X/ZWfY/09P + s/+Hgaf/19HO/+vo5P/Uzs7/x76+/8vCwv+8trb/i4iI5UVERHYQEBAURUZGABAREQAAAAABAAAAAQAA + AAAAAAAAEBAQAGFgYAA0NDQAFBQUAAAAAABMTEwAMDAwACorKwADBAQAUlJSABMTEwAYGRkAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8AXV1dAGFhYQBpaWkAYWFhAF5eXgBcXFwAYWFhAGdnZwB3dnYAXFxcAF1d + XQBoaGgAhoWFAFxcXABqaWkAXV1dAGBgYAB9fHwAXV5eAHV0dABcXFwAd3Z2AF5eXkWAf3/MwLy8/+Ld + 3f/f2tr/5ODg/+rm4//OyMf/n5u6/5CQ0v+lpuz/sbDx/6Wl7P+bm+r/mprq/5mZ6v+YmOr/lpbp/5SU + 6f+Skuj/j4/n/42N5/+Kiuf/h4fm/4SE5v+BgeX/fn7k/3t74/93d+P/dXXi/3Jy4f9vb+H/bGzh/2lp + 4P9mZt//YWHe/2Rk3v99feT/f37m/1lazP9jYKj/s624/+vm4f/e2dn/yMDA/8rBwf/Fvb3/mpaW901N + TY0REREcRUREABAQEAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAQEBAAYWBgADQ0NAAUFBQAAAAAAExM + TAAwMDAAKisrAAMEBABSUlIAExMTABgZGQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wBdXV0AYWFhAGlp + aQBhYWEAXl5eAFxcXABhYWEAZ2dnAHd2dgBcXFwAXV1dAGhoaACGhYUAXFxcAGppaQBdXV0AYGBgAH18 + fABdXl4AdXR0AFxcXAB3dnYAXl5eAF5fXwdjY2NtlZKS69LNzf/h29v/3djY/+jk4//g29b/tK67/4+N + xf+ZmuP/ra3w/6Wl7f+Xl+n/lZXp/5WV6f+Tk+j/kZHo/4+P6P+MjOf/iorm/4eH5v+Fheb/goLl/39/ + 5P98fOT/eXnj/3Z24/9zc+L/cHDi/25u4P9ra+D/aGjf/2Nj3/9tbeH/hITn/3V24/9YWcD/hH+p/9XO + zP/q5uL/0MrK/8e+vv/Lw8P/raen/2lnZ7ojIyM0TU1NABEREQAAAAABAAAAAQAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAABAQEABhYGAANDQ0ABQUFAAAAAAATExMADAwMAAqKysAAwQEAFJSUgATExMAGBkZAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AF1dXQBhYWEAaWlpAGFhYQBeXl4AXFxcAGFhYQBnZ2cAd3Z2AFxc + XABdXV0AaGhoAIaFhQBcXFwAamlpAF1dXQBgYGAAfXx8AF1eXgB1dHQAXFxcAHd2dgBeXl4AXl9fAGNj + YwBdXV0hcXFxqbKurv/e2Nj/29XV/+Hd3f/o4+D/xr/B/5SSvP+Njtn/pqfu/6Sk7f+Vlen/kJDo/4+P + 6P+Ojuj/jIzn/4qK5v+Hh+b/hITm/4OD5f+AgOT/fX3k/3t75P94eOP/dXXj/3Jy4f9wcOH/bW3h/2pq + 4P9mZt//dHTi/4eH6f9sbdv/X1+0/6Odsf/l4Nv/4dzb/8jAwP/KwcH/wbq6/4iFhec4ODhnAQEBBiMj + IwAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQAGFgYAA0NDQAFBQUAAAA + AABMTEwAMDAwACorKwADBAQAUlJSABMTEwAYGRkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AXV1dAGFh + YQBpaWkAYWFhAF5eXgBcXFwAYWFhAGdnZwB3dnYAXFxcAF1dXQBoaGgAhoWFAFxcXABqaWkAXV1dAGBg + YAB9fHwAXV5eAHV0dABcXFwAd3Z2AF5eXgBeX18AY2NjAF1dXQBxcXEAYGBgWJCOjufRy8v/3dbW/9vV + 1f/o5OP/19HN/6GcuP+EhM3/nZ3q/6Sj7f+Skuj/i4vn/4uL5/+Jief/h4fm/4WF5v+Dg+b/gIDl/35+ + 5P98fOP/eXnj/3Z24/90dOL/cXHh/29v4f9ra+D/aWng/3t75P+Ghun/ZGXS/2tprP+/uL7/6ubh/9bQ + z//Gvb3/y8PD/6ynp/9fX1+wExQUIzg4OAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAQEBAAYWBgADQ0NAAUFBQAAAAAAExMTAAwMDAAKisrAAMEBABSUlIAExMTABgZ + GQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wBdXV0AYWFhAGlpaQBhYWEAXl5eAFxcXABhYWEAZ2dnAHd2 + dgBcXFwAXV1dAGhoaACGhYUAXFxcAGppaQBdXV0AYGBgAH18fABdXl4AdXR0AFxcXAB3dnYAXl5eAF5f + XwBjY2MAXV1dAHFxcQBgYGAAXV1dIXR0dLa6tbX/3NXV/9fR0f/j39//4NrV/6+puv+Dg8X/lJTl/6Gh + 7v+QkOj/hobm/4aG5v+Fheb/g4Pl/4GB5f9+fuT/fHzk/3p65P94eOP/dXXj/3Jy4v9xceH/bW3g/2xs + 4P+AgOb/hITo/2Bhyf99eqv/0cvJ/+fj4P/Nxsb/yL+//8a9vf+QjY3wPT09cAAAAAYTFBQAAAAAAgAA + AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEABhYGAANDQ0ABQU + FAAAAAAATExMADAwMAAqKysAAwQEAFJSUgATExMAGBkZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AF1d + XQBhYWEAaWlpAGFhYQBeXl4AXFxcAGFhYQBnZ2cAd3Z2AFxcXABdXV0AaGhoAIaFhQBcXFwAamlpAF1d + XQBgYGAAfXx8AF1eXgB1dHQAXFxcAHd2dgBeXl4AXl9fAGNjYwBdXV0AcXFxAGBgYABdXV0AX2BgAWRk + ZHignZ3519HR/9bPz//e2dn/5eHd/763vv+FhL//iovg/56e7f+Rken/hITl/4GB5f+AgOX/fn7k/319 + 5P97e+T/eXnj/3Z24/90dOL/cXHi/21t4f9zc+L/hobn/4GB5v9hYcL/kYyu/97Y0//i3t3/x7+//8rB + wf+6tLT/dXNzzxYWFjY9PT0AAAAAAgAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAEBAQAGFgYAA0NDQAFBQUAAAAAABMTEwAMDAwACorKwADBAQAUlJSABMT + EwAYGRkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8AXV1dAGFhYQBpaWkAYWFhAF5eXgBcXFwAYWFhAGdn + ZwB3dnYAXFxcAF1dXQBoaGgAhoWFAFxcXABqaWkAXV1dAGBgYAB9fHwAXV5eAHV0dABcXFwAd3Z2AF5e + XgBeX18AY2NjAF1dXQBxcXEAYGBgAF1dXQBfYGAAZGRkAF5eXkWLiYnjzsjI/9XPz//Y09P/5+Pg/8jB + w/+Jh7v/g4Pb/5qa7P+Wlun/h4fm/39/5P97e+T/eXnk/3h44/92duP/c3Pi/3Fx4v90dOL/f3/l/4yM + 6f97e+L/ZGS+/6Casf/l4Nr/29bV/8W9vf/KwcH/raen/1pZWaQREhIYFhYWAAAAAAMAAAABAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAAYWBgADQ0 + NAAUFBQAAAAAAExMTAAwMDAAKisrAAMEBABSUlIAExMTABgZGQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wBdXV0AYWFhAGlpaQBhYWEAXl5eAFxcXABhYWEAZ2dnAHd2dgBcXFwAXV1dAGhoaACGhYUAXFxcAGpp + aQBdXV0AYGBgAH18fABdXl4AdXR0AFxcXAB3dnYAXl5eAF5fXwBjY2MAXV1dAHFxcQBgYGAAXV1dAF9g + YABkZGQAXl5eAF5eXiF5eHjFwby8/9bOzv/Uzc3/5uLf/9DJyP+Sj7j/eXrQ/46O6P+YmOz/kpLp/4iI + 5v+CguX/f3/k/35+5P9/f+T/hYXm/42N6f+Jier/b2/a/2tquP+uqLf/6OPd/9XQ0P/EvLz/ycDA/52Y + mPpAQEB6AAAABRESEgAAAAADAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEABhYGAANDQ0ABQUFAAAAAAATExMADAwMAAqKysAAwQEAFJS + UgATExMAGBkZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AF1dXQBhYWEAaWlpAGFhYQBeXl4AXFxcAGFh + YQBnZ2cAd3Z2AFxcXABdXV0AaGhoAIaFhQBcXFwAamlpAF1dXQBgYGAAfXx8AF1eXgB1dHQAXFxcAHd2 + dgBeXl4AXl9fAGNjYwBdXV0AcXFxAGBgYABdXV0AX2BgAGRkZABeXl4AXl5eAF5fXw5ubm6itbCw/9TN + zf/Ry8v/49/e/9rU0P+oo7r/eHfB/3d32P+IiOj/kZHr/5GR6/+QkOn/j4/p/46O6v+IiOn/dHXe/2Rk + x/+BfrP/xb/C/+fi3v/Qysr/xby8/8e+vv+LiIjrMTIyVkBAQAAAAAADAAAAAwAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQAGFg + YAA0NDQAFBQUAAAAAABMTEwAMDAwACorKwADBAQAUlJSABMTEwAYGRkAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8AXV1dAGFhYQBpaWkAYWFhAF5eXgBcXFwAYWFhAGdnZwB3dnYAXFxcAF1dXQBoaGgAhoWFAFxc + XABqaWkAXV1dAGBgYAB9fHwAXV5eAHV0dABcXFwAd3Z2AF5eXgBeX18AY2NjAF1dXQBxcXEAYGBgAF1d + XQBfYGAAZGRkAF5eXgBeXl4AXl9fAG5ubgBmZmaGqqWl/9TNzf/Ox8f/3NfW/+Tf2v/Fv8L/lpO3/3t6 + v/9ycs7/d3fX/3Nz2v90dNn/b2/S/2xsxP9/fbT/q6a4/9zX0//i3tv/ysPD/8e9vf/Curr/fnx83RYX + FzkxMjIAAAAABAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAAYWBgADQ0NAAUFBQAAAAAAExMTAAwMDAAKisrAAME + BABSUlIAExMTABgZGQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wBdXV0AYWFhAGlpaQBhYWEAXl5eAFxc + XABhYWEAZ2dnAHd2dgBcXFwAXV1dAGhoaACGhYUAXFxcAGppaQBdXV0AYGBgAH18fABdXl4AdXR0AFxc + XAB3dnYAXl5eAF5fXwBjY2MAXV1dAHFxcQBgYGAAXV1dAF9gYABkZGQAXl5eAF5eXgBeX18Abm5uAGZm + ZgBjY2NrmpeX+c/Hx//Px8f/0crK/9/b2f/f2tX/zsjH/7Suu/+fmrf/mJS5/5uXuP+knrX/xL7B/9nT + z//j39v/1M3N/8W8vP/JwMD/urOz/3RycscWFhYkFhcXAAAAAAMAAAABAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQ + EABhYGAANDQ0ABQUFAAAAAAATExMADAwMAAqKysAAwQEAFJSUgATExMAGBkZAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AF1dXQBhYWEAaWlpAGFhYQBeXl4AXFxcAGFhYQBnZ2cAd3Z2AFxcXABdXV0AaGhoAIaF + hQBcXFwAamlpAF1dXQBgYGAAfXx8AF1eXgB1dHQAXFxcAHd2dgBeXl4AXl9fAGNjYwBdXV0AcXFxAGBg + YABdXV0AX2BgAGRkZABeXl4AXl5eAF5fXwBubm4AZmZmAGNjYwBfYGA+gX9/17iysv/PyMj/zMTE/9DI + yP/X0dH/3tnW/9/a1v/c1tH/3dfS/+Db1//a1NP/0MrJ/8e+vv/Iv7//xb29/6Oenv1PTk6SDxAQDhYW + FgAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQAGFgYAA0NDQAFBQUAAAAAABMTEwAMDAwACor + KwADBAQAUlJSABMTEwAYGRkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AXV1dAGFhYQBpaWkAYWFhAF5e + XgBcXFwAYWFhAGdnZwB3dnYAXFxcAF1dXQBoaGgAhoWFAFxcXABqaWkAXV1dAGBgYAB9fHwAXV5eAHV0 + dABcXFwAd3Z2AF5eXgBeX18AY2NjAF1dXQBxcXEAYGBgAF1dXQBfYGAAZGRkAF5eXgBeXl4AXl9fAG5u + bgBmZmYAY2NjAF9gYABfX18OZ2dnf5CNjeu5s7P/ysLC/83ExP/KwcH/ysLC/8zExP/Kw8P/x7+//8e/ + v//JwMD/w7u7/6ulpf9vbW3DKysrQE9OTgAPEBAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAQEBAAYWBgADQ0NAAUFBQAAAAAAExMTAAwMDAAKisrAAMEBABSUlIAExMTABgZGQAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wBdXV0AYWFhAGlpaQBhYWEAXl5eAFxcXABhYWEAZ2dnAHd2dgBcXFwAXV1dAGho + aACGhYUAXFxcAGppaQBdXV0AYGBgAH18fABdXl4AdXR0AFxcXAB3dnYAXl5eAF5fXwBjY2MAXV1dAHFx + cQBgYGAAXV1dAF9gYABkZGQAXl5eAF5eXgBeX18Abm5uAGZmZgBjY2MAX2BgAF9fXwBnZ2cAX19fGWdn + Z3iBf3/RnZmZ+rGrq/+9tbX/wLi4/7+3t/+2r6//pqGh/42Jie1pZ2epLi4uSgMEBAUrKysAT05OAA8Q + EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEABhYGAANDQ0ABQUFAAAAAAATExMADAw + MAAqKysAAwQEAFJSUgATExMAGBkZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AF1dXQBhYWEAaWlpAGFh + YQBeXl4AXFxcAGFhYQBnZ2cAd3Z2AFxcXABdXV0AaGhoAIaFhQBcXFwAamlpAF1dXQBgYGAAfXx8AF1e + XgB1dHQAXFxcAHd2dgBeXl4AXl9fAGNjYwBdXV0AcXFxAGBgYABdXV0AX2BgAGRkZABeXl4AXl5eAF5f + XwBubm4AZmZmAGNjYwBfYGAAX19fAGdnZwBfX18AZ2dnAF5fXyhlZGRgcnBwlHp4eLh8enrBfHp6wHZ1 + dalwb298Ojo6RA0ODg8uLi4AAwQEACsrKwBPTk4ADxAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAEBAQAGFgYAA0NDQAFBQUAAAAAABMTEwAMDAwACorKwADBAQAUlJSABMTEwAYGRkAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A/////////////////////////////////////////////////////4// + //////////////////gA//////////////////+AAB/////////////////+AAAH//////////////// + +AAAAf////////////////AAAAB////////////////AAAAAP///////////////gAAAAB////////// + /////wAAAAAH//////////////4AAAAAA//////////////8AAAAAAH/////////////+AAAAAAA//// + //////////AAAAAAAH/////////////gAAAAAAA/////////////wAAAAAAAH////////////4AAAAAA + AA////////////8AAAAAAAAH////////////AAAAAAAAB////////////AAAAAAAAAP///////////wA + AAAAAAAB///////////xAAAAAAAAAP//////////8gAAAAAAAAD//////////+QAAAAAAAAAf/////// + ///gAAAAAAAAAD//////////wAAAAAAAAAAf/////////5AAAAAAAAAAD/////////+gAAAAAAAAAA// + ////////QAAAAAAAAAAP/////////0AAAAAAAAAAB/////////6AAAAAAAAAAAP////////9AAAAAAAA + AAAB////////+QAAAAAAAAAAAf////////oAAAAAAAAAAAD////////0AAAAAAAAAAAA////////9AAA + AAAAAAAAAH///////+gAAAAAAAAAAAA////////AAAAAAAAAAAAAP///////0AAAAAAAAAAAAD////// + /6AAAAAAAAAAAAAf//////+gAAAAAAAAAAAAD///////QAAAAAAAAAAAAA///////0AAAAAAAAAAAAAH + //////6AAAAAAAAAAAAAB//////+gAAAAAAAAAAAAAf//////wAAAAAAAAAAAAAD//////8AAAAAAAAA + AAAAA//////+AAAAAAAAAAAAAAH//////gAAAAAAAAAAAAAB//////wAAAAAAAAAAAAAAf/////8AAAA + AAAAAAAAAAD/////+AAAAAAAAAAAAAAA//////gAAAAAAAAAAAAAAH/////4AAAAAAAAAAAAAAB///// + 8AAAAAAAAAAAAAAAf/////AAAAAAAAAAAAAAAD/////wAAAAAAAAAAAAAAA/////4AAAAAAAAAAAAAAA + P////+AAAAAAAAAAAAAAAD/////gAAAAAAAAAAAAAAA/////4AAAAAAAAAAAAAAAH////8AAAAAAAAAA + AAAAAB/////AAAAAAAAAAAAAAAAf////wAAAAAAAAAAAAAAAH////8AAAAAAAAAAAAAAAB/////AAAAA + AAAAAAAAAAAf////gAAAAAAAAAAAAAAAH////4AAAAAAAAAAAAAAAA////+AAAAAAAAAAAAAAAAP//// + gAAAAAAAAAAAAAAAD////4AAAAAAAAAAAAAAAA////+AAAAAAAAAAAAAAAAP////gAAAAAAAAAAAAAAA + D////4AAAAAAAAAAAAAAAA////+AAAAAAAAAAAAAAAAP////gAAAAAAAAAAAAAAAD////4AAAAAAAAAA + AAAAAA////+AAAAAAAAAAAAAAAAP////gAAAAAAAAAAAAAAAD////4AAAAAAAAAAAAAAAA////+AAAAA + AAAAAAAAAAAP////gAAAAAAAAAAAAAAAD////4AAAAAAAAAAAAAAAA////+AAAAAAAAAAAAAAAAP//// + gAAAAAAAAAAAAAAAD////4AAAAAAAAAAAAAAAA////+AAAAAAAAAAAAAAAAP////gAAAAAAAAAAAAAAA + D////4AAAAAAAAAAAAAAAA////+AAAAAAAAAAAAAAAAP////gAAAAAAAAAAAAAAAD////4AAAAAAAAAA + AAAAAB////+AAAAAAAAAAAAAAAAf////gAAAAAAAAAAAAAAAH////4AAAAAAAAAAAAAAAB////+AAAAA + AAAAAAAAAAAf////gAAAAAAAAAAAAAAAH////4AAAAAAAAAAAAAAAB////+AAAAAAAAAAAAAAAA///// + wAAAAAAAAAAAAAAAf////+AAAAAAAAAAAAAABP/////wAAAAAAAAAAAAAAn/////+AAAAAAAAAAAAAA/ + ///////AAAAAAAAAAAAD/////////AAAAAAAAAAAP/////////8AAAAAAAAAAf//////////4AAAAAAA + AAf///////////gAAAAAAAAZ///////////+AAAAAAAAZ////////////wAAAAAAAZ/////////////A + AAAAAAJ/////////////8AAAAAAJ//////////////gAAAAAE//////////////8AAAAAE////////// + /////wAAAACf//////////////+AAAABP///////////////wAAABP////////////////AAAAn///// + ///////////4AAAT/////////////////AAAL/////////////////4AAN//////////////////gAH/ + /////////////////+AH//////////////////////////////////////////////////////////// + //////////////////////////////////8= + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/AutoEncryptDemo/DRMServer.cs b/Demo_Source_Code/CSharpDemo/AutoEncryptDemo/DRMServer.cs new file mode 100644 index 0000000..dda7dc1 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/AutoEncryptDemo/DRMServer.cs @@ -0,0 +1,495 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; +using System.Runtime.InteropServices; + +using EaseFilter.FilterControl; +using EaseFilter.CommonObjects; + +namespace AutoEncryptDemo +{ + /// + /// This is the DRM information to control the encrypted file access. + /// + public class DRMInfo + { + /// + /// If it is not empty, only the processes in the process list can access the files. + /// + public string AuthorizedProcessNames = string.Empty; + /// + /// If it is not empty, all the processes in the process list can not access the files. + /// + public string UnauthorizedProcessNames = string.Empty; + /// + /// If it is not empty, only the users in the user name list can access the files. + /// + public string AuthorizedUserNames = string.Empty; + /// + /// If it is not empty, all the useres in the user name list can not access the files. + /// + public string UnauthorizedUserNames = string.Empty; + /// + /// It is an account name information. + /// + public string AccountName = string.Empty; + /// + /// If it is not empty, only the computer in the computer id list can access the files. + /// + public string AuthorizedComputerIds = string.Empty; + /// + /// The password of the user account. + /// + public string UserPassword = string.Empty; + /// + /// + /// the access flags of the shared file. + /// + public uint AccessFlags; + /// + /// The file will be expired after the expire time in UTC format, and it can't be accessed. + /// + public long ExpireTime; + /// + /// The time in UTC format of the encrypted file was created. + /// + public long CreationTime; + /// + /// the file name which was applied with policy. + /// + public string FileName = string.Empty; + /// + /// The encryption key hex string. + /// + public string EncryptionKey = string.Empty; + /// + /// the iv hex string. + /// + public string EncryptionIV = string.Empty; + /// + /// The AES control flag + /// + public AESFlags AESFlags = 0; + } + + public enum AESFlags : uint + { + Flags_Enabled_Expire_Time = 0x00000010, + Flags_Enabled_Check_ProcessName = 0x00000020, + Flags_Enabled_Check_UserName = 0x00000040, + Flags_Enabled_Check_AccessFlags = 0x00000080, + Flags_Enabled_Check_User_Permit = 0x00000100, + Flags_AES_Key_Was_Embedded = 0x00000200, + Flags_Request_AccessFlags_From_User = 0x00000400, + Flags_Request_IV_And_Key_From_User = 0x00000800, + Flags_Enabled_Check_Computer_Id = 0x00001000, + Flags_Enabled_Check_User_Password = 0x00002000, + + } + + + /// + /// This is the build in DRM data format which can be embedded into the encrypted file as a header. + /// + public class DRMData + { + public uint AESVerificationKey; + public AESFlags AESFlags; + public long CreationTime; + public long ExpireTime; + public uint AccessFlags; + public uint LengthOfIncludeProcessNames; + public uint OffsetOfIncludeProcessNames; + public uint LengthOfExcludeProcessNames; + public uint OffsetOfExcludeProcessNames; + public uint LengthOfIncludeUserNames; + public uint OffsetOfIncludeUserNames; + public uint LengthOfExcludeUserNames; + public uint OffsetOfExcludeUserNames; + public uint LengthOfAccountName; + public uint OffsetOfAccountName; + public uint LengthOfComputerId; + public uint OffsetOfComputerId; + public uint LengthOfUserPassword; + public uint OffsetOfUserPassword; + public string AuthorizedProcessNames = string.Empty; + public string UnauthorizedProcessNames = string.Empty; + public string AuthorizedUserNames = string.Empty; + public string UnauthorizedUserNames = string.Empty; + public string AccountName = string.Empty; + public string ComputerIds = string.Empty; + public string UserPassword = string.Empty; + + } + + public class DRMServer + { + /// + /// if it is true, the DRM data will be embedded to the header of the encrypted file. + /// if the encrypted file was opened, the filter driver will check if the access was authorized by the embedded data + /// if it is not authorized, the encrypted file access will be blocked, or it will go to user mode service to get the encryption key. + /// + public static bool embedDRMToFile = true; + /// + /// The defined DRM data, you can store the DRM data to your own remote server to control the encrypted file. + /// + public static DRMInfo dRMInfo = null; + + static DRMData dRMData = new DRMData(); + + //define for build in DRM data verification code. + const uint AES_VERIFICATION_KEY = 0xccb76e80; + + public static string GetComputerId() + { + + string myComputerId = FilterAPI.GetComputerId().ToString(); + + if (string.IsNullOrEmpty(myComputerId.Trim())) + { + string lastError = FilterAPI.GetLastErrorMessage(); + return ""; + } + + return myComputerId; + + } + + private static byte[] ConvertDRMDataToByteArray(DRMData dRMData) + { + try + { + MemoryStream ms = new MemoryStream(); + BinaryWriter bw = new BinaryWriter(ms); + bw.Write(AES_VERIFICATION_KEY); + bw.Write((uint)(dRMData.AESFlags)); + bw.Write(dRMData.CreationTime); + bw.Write(dRMData.ExpireTime); + bw.Write(dRMData.AccessFlags); + bw.Write(dRMData.LengthOfIncludeProcessNames); + bw.Write(dRMData.OffsetOfIncludeProcessNames); + bw.Write(dRMData.LengthOfExcludeProcessNames); + bw.Write(dRMData.OffsetOfExcludeProcessNames); + bw.Write(dRMData.LengthOfIncludeUserNames); + bw.Write(dRMData.OffsetOfIncludeUserNames); + bw.Write(dRMData.LengthOfExcludeUserNames); + bw.Write(dRMData.OffsetOfExcludeUserNames); + bw.Write(dRMData.LengthOfAccountName); + bw.Write(dRMData.OffsetOfAccountName); + bw.Write(dRMData.LengthOfComputerId); + bw.Write(dRMData.OffsetOfComputerId); + bw.Write(dRMData.LengthOfUserPassword); + bw.Write(dRMData.OffsetOfUserPassword); + + byte[] strBuffer; + if (dRMData.LengthOfIncludeProcessNames > 0) + { + strBuffer = UnicodeEncoding.Unicode.GetBytes(dRMData.AuthorizedProcessNames); + bw.Write(strBuffer); + } + + if (dRMData.LengthOfExcludeProcessNames > 0) + { + strBuffer = UnicodeEncoding.Unicode.GetBytes(dRMData.UnauthorizedProcessNames); + bw.Write(strBuffer); + } + + if (dRMData.LengthOfIncludeUserNames > 0) + { + strBuffer = UnicodeEncoding.Unicode.GetBytes(dRMData.AuthorizedUserNames); + bw.Write(strBuffer); + } + + if (dRMData.LengthOfExcludeUserNames > 0) + { + strBuffer = UnicodeEncoding.Unicode.GetBytes(dRMData.UnauthorizedUserNames); + bw.Write(strBuffer); + } + + if (dRMData.LengthOfAccountName > 0) + { + strBuffer = UnicodeEncoding.Unicode.GetBytes(dRMData.AccountName); + bw.Write(strBuffer); + } + + if (dRMData.LengthOfComputerId > 0) + { + strBuffer = UnicodeEncoding.Unicode.GetBytes(dRMData.ComputerIds); + bw.Write(strBuffer); + } + + if (dRMData.LengthOfUserPassword > 0) + { + strBuffer = UnicodeEncoding.Unicode.GetBytes(dRMData.UserPassword); + bw.Write(strBuffer); + } + + byte[] dRMDataArray = ms.ToArray(); + + return dRMDataArray; + } + catch( Exception ex) + { + EventManager.WriteMessage(200, "ConverDRMDataToByteArray", EventLevel.Error, "ConverDRMDataToByteArray got exception:" + ex.Message); + } + + return null; + } + + public static bool SetDRMInfo(DRMInfo drmInfo) + { + AESFlags aesFlag = 0; + dRMInfo = drmInfo; + + try + { + int nextOffset = Marshal.SizeOf(dRMData.AESVerificationKey) + Marshal.SizeOf((uint)dRMData.AESFlags) + Marshal.SizeOf(dRMData.CreationTime) + Marshal.SizeOf(dRMData.ExpireTime) + + Marshal.SizeOf(dRMData.AccessFlags) + Marshal.SizeOf(dRMData.LengthOfIncludeProcessNames) + Marshal.SizeOf(dRMData.OffsetOfIncludeProcessNames) + + Marshal.SizeOf(dRMData.LengthOfExcludeProcessNames) + Marshal.SizeOf(dRMData.OffsetOfExcludeProcessNames) + Marshal.SizeOf(dRMData.LengthOfIncludeUserNames) + Marshal.SizeOf(dRMData.OffsetOfIncludeUserNames) + + Marshal.SizeOf(dRMData.LengthOfExcludeUserNames) + Marshal.SizeOf(dRMData.OffsetOfExcludeUserNames) + Marshal.SizeOf(dRMData.LengthOfAccountName) + Marshal.SizeOf(dRMData.OffsetOfAccountName) + + Marshal.SizeOf(dRMData.LengthOfComputerId) + Marshal.SizeOf(dRMData.OffsetOfComputerId) + Marshal.SizeOf(dRMData.LengthOfUserPassword) + Marshal.SizeOf(dRMData.OffsetOfUserPassword); + + if (dRMInfo.AuthorizedProcessNames.Length > 0) + { + dRMData.AuthorizedProcessNames = dRMInfo.AuthorizedProcessNames; + dRMData.LengthOfIncludeProcessNames = (uint)dRMInfo.AuthorizedProcessNames.Length * 2; + dRMData.OffsetOfIncludeProcessNames = (uint)nextOffset; + nextOffset += dRMInfo.AuthorizedProcessNames.Length * 2; + aesFlag |= AESFlags.Flags_Enabled_Check_ProcessName; + } + + if (dRMInfo.UnauthorizedProcessNames.Length > 0) + { + dRMData.UnauthorizedProcessNames = dRMInfo.UnauthorizedProcessNames; + dRMData.LengthOfExcludeProcessNames = (uint)dRMInfo.UnauthorizedProcessNames.Length * 2; + dRMData.OffsetOfExcludeProcessNames = (uint)nextOffset; + nextOffset += dRMInfo.UnauthorizedProcessNames.Length * 2; + aesFlag |= AESFlags.Flags_Enabled_Check_ProcessName; + } + + if (dRMInfo.AuthorizedUserNames.Length > 0) + { + dRMData.AuthorizedUserNames = dRMInfo.AuthorizedUserNames; + dRMData.LengthOfIncludeUserNames = (uint)dRMInfo.AuthorizedUserNames.Length * 2; + dRMData.OffsetOfIncludeUserNames = (uint)nextOffset; + nextOffset += dRMInfo.AuthorizedUserNames.Length * 2; + aesFlag |= AESFlags.Flags_Enabled_Check_UserName; + } + + if (dRMInfo.UnauthorizedUserNames.Length > 0) + { + dRMData.UnauthorizedUserNames = dRMInfo.UnauthorizedUserNames; + dRMData.LengthOfExcludeUserNames = (uint)dRMInfo.UnauthorizedUserNames.Length * 2; + dRMData.OffsetOfExcludeUserNames = (uint)nextOffset; + nextOffset += dRMInfo.UnauthorizedUserNames.Length * 2; + aesFlag |= AESFlags.Flags_Enabled_Check_UserName; + } + + if (dRMInfo.AccountName.Length > 0) + { + dRMData.AccountName = dRMInfo.AccountName; + dRMData.LengthOfAccountName = (uint)dRMInfo.AccountName.Length * 2; + dRMData.OffsetOfAccountName = (uint)nextOffset; + nextOffset += dRMInfo.AccountName.Length * 2; + aesFlag |= AESFlags.Flags_Enabled_Check_User_Permit; + } + + if (dRMInfo.AuthorizedComputerIds.Length > 0) + { + dRMData.ComputerIds = dRMInfo.AuthorizedComputerIds; + dRMData.LengthOfComputerId = (uint)dRMInfo.AuthorizedComputerIds.Length * 2; + dRMData.OffsetOfComputerId = (uint)nextOffset; + nextOffset += dRMInfo.AuthorizedComputerIds.Length * 2; + aesFlag |= AESFlags.Flags_Enabled_Check_Computer_Id; + } + + if (dRMInfo.UserPassword.Length > 0) + { + dRMData.UserPassword = dRMInfo.UserPassword; + dRMData.LengthOfUserPassword = (uint)dRMInfo.UserPassword.Length * 2; + dRMData.OffsetOfUserPassword = (uint)nextOffset; + nextOffset += dRMInfo.UserPassword.Length * 2; + aesFlag |= AESFlags.Flags_Enabled_Check_User_Permit; + } + + if(dRMInfo.ExpireTime > 0 ) + { + dRMData.ExpireTime = dRMInfo.ExpireTime; + aesFlag |= AESFlags.Flags_Enabled_Expire_Time; + } + + dRMData.CreationTime = DateTime.Now.ToFileTime(); + + dRMData.AESFlags = aesFlag; + dRMData.AccessFlags = FilterAPI.ALLOW_MAX_RIGHT_ACCESS; + + return true; + } + catch (Exception ex) + { + EventManager.WriteMessage(300, "SetDRMInfo", EventLevel.Error, "SetDRMInfo got exception:" + ex.Message); + } + + return false; + } + + /// + /// Get the DRM data for the new encrypted file + /// + /// + public static byte[] GetDRMTagData(string fileName) + { + byte[] dRMDataArray = null; + + try + { + if (null == dRMInfo) + { + EventManager.WriteMessage(50, "GetDRMTagData", EventLevel.Error, "No DRM data for file:" + fileName); + + //the DRM data was not set. + return null; + } + + if (embedDRMToFile) + { + dRMDataArray = ConvertDRMDataToByteArray(dRMData); + } + else + { + //the DRM data was managed by yourself, you can store it in your own server, here we just put it in the memory for demo. + dRMDataArray = UnicodeEncoding.Unicode.GetBytes("embedDRMToServer"); + } + + return dRMDataArray; + } + catch( Exception ex) + { + EventManager.WriteMessage(600, "GetDRMTagData", EventLevel.Error, "GetDRMTagData for file:" + fileName + " got exception:" + ex.Message); + return null; + } + } + + public static bool GetEncryptedFileAccessPermission(EncryptEventArgs encryptArgs) + { + Boolean retVal = false; + string fileName = encryptArgs.FileName; + string lastError = string.Empty; + string processName = encryptArgs.ProcessName; + string userName = encryptArgs.UserName; + string encryptKey = string.Empty; + + try + { + + if (null == encryptArgs.EncryptionTag || encryptArgs.EncryptionTag.Length == 0) + { + lastError = "There are no encryption tag data."; + return false; + } + + string tagStr = UnicodeEncoding.Unicode.GetString(encryptArgs.EncryptionTag); + + if (string.Compare(tagStr, "embedDRMToServer") != 0) + { + //the DRM data is not in the server. + retVal = true; + + EventManager.WriteMessage(250, "GetEncryptedFileAccessPermission", EventLevel.Information, + "GetEncryptedFileAccessPermission:" + encryptArgs.FileName + ",userName:" + encryptArgs.UserName + + ",processName:" + encryptArgs.ProcessName + ", DRM is embedded to encrypted file, return success."); + + return true; + } + else + { + //you can store your DRM info to server, here we just demo the DRM info in local + if (null == dRMInfo) + { + lastError = "No DRM Info"; + return false; + } + + if (dRMInfo.ExpireTime > 0) + { + DateTime exTime = DateTime.FromFileTime(dRMInfo.ExpireTime); + + if (DateTime.Now > exTime) + { + lastError = "the file is expired,current time:" + DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss") + ",expire time:" + exTime.ToString("yyyy-MM-dd-HH-mm-ss"); + return false; + } + } + + if (!string.IsNullOrEmpty(dRMInfo.AuthorizedProcessNames)) + { + if (dRMInfo.AuthorizedProcessNames.IndexOf(processName.ToLower().Trim()) < 0) + { + lastError = "the process " + processName + " is not in authorized process list."; + return false; + } + } + + if (!string.IsNullOrEmpty(dRMInfo.UnauthorizedProcessNames)) + { + if (dRMInfo.UnauthorizedProcessNames.IndexOf(processName.ToLower().Trim()) >= 0) + { + lastError = "the process " + processName + " is in unauthorized process list."; + return false; + } + } + + if (!string.IsNullOrEmpty(dRMInfo.AuthorizedUserNames)) + { + if (dRMInfo.AuthorizedUserNames.IndexOf(userName.ToLower().Trim()) < 0) + { + lastError = "the user " + userName + " is not in authorized user list."; + return false; + } + } + + if (!string.IsNullOrEmpty(dRMInfo.UnauthorizedUserNames)) + { + if (dRMInfo.UnauthorizedUserNames.IndexOf(userName.ToLower().Trim()) >= 0) + { + lastError = "the user " + userName + " is in unauthorized user list."; + return false; + } + } + + if (!string.IsNullOrEmpty(dRMInfo.AuthorizedComputerIds)) + { + string currentComputerId = GetComputerId(); + if (dRMInfo.AuthorizedComputerIds.IndexOf(currentComputerId.Trim()) < 0) + { + lastError = "the current computer " + currentComputerId + " is unauthorized to access encrypted file."; + return false; + } + } + } + + retVal = true; + } + catch (Exception ex) + { + lastError = "GetFileAccessPermission exception." + ex.Message; + retVal = false; + } + finally + { + if (!retVal) + { + lastError += ",userName:" + encryptArgs.UserName + ",processName:" + encryptArgs.ProcessName; + EventManager.WriteMessage(100, "GetEncryptedFileAccessPermission", EventLevel.Error + , "Access denied for file:" + encryptArgs.FileName + "," + lastError ); + } + } + + return retVal; + + } + + } + +} diff --git a/Demo_Source_Code/CSharpDemo/AutoEncryptDemo/Program.cs b/Demo_Source_Code/CSharpDemo/AutoEncryptDemo/Program.cs new file mode 100644 index 0000000..8cce98b --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/AutoEncryptDemo/Program.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Windows.Forms; + +namespace AutoEncryptDemo +{ + static class Program + { + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main() + { + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + Application.Run(new AutoEncryptForm()); + } + } +} diff --git a/Demo_Source_Code/CSharpDemo/AutoEncryptDemo/Properties/AssemblyInfo.cs b/Demo_Source_Code/CSharpDemo/AutoEncryptDemo/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..b70f8ee --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/AutoEncryptDemo/Properties/AssemblyInfo.cs @@ -0,0 +1,37 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("AutoEncryptDemo")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("AutoEncryptDemo")] +[assembly: AssemblyCopyright("Copyright © 2021")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("c83dc675-a745-4b7e-83ca-30ef314755a7")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("5.2.3.2001")] +//[assembly: AssemblyFileVersion("1.0.0.0")] + diff --git a/Demo_Source_Code/CSharpDemo/AutoEncryptDemo/Properties/Resources.Designer.cs b/Demo_Source_Code/CSharpDemo/AutoEncryptDemo/Properties/Resources.Designer.cs new file mode 100644 index 0000000..a21f29b --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/AutoEncryptDemo/Properties/Resources.Designer.cs @@ -0,0 +1,63 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace AutoEncryptDemo.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // 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", "16.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + 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() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [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("AutoEncryptDemo.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + } +} diff --git a/Demo_Source_Code/CSharpDemo/AutoEncryptDemo/Properties/Resources.resx b/Demo_Source_Code/CSharpDemo/AutoEncryptDemo/Properties/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/AutoEncryptDemo/Properties/Resources.resx @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/AutoEncryptDemo/Properties/Settings.Designer.cs b/Demo_Source_Code/CSharpDemo/AutoEncryptDemo/Properties/Settings.Designer.cs new file mode 100644 index 0000000..b244375 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/AutoEncryptDemo/Properties/Settings.Designer.cs @@ -0,0 +1,26 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace AutoEncryptDemo.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.10.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default { + get { + return defaultInstance; + } + } + } +} diff --git a/Demo_Source_Code/CSharpDemo/AutoEncryptDemo/Properties/Settings.settings b/Demo_Source_Code/CSharpDemo/AutoEncryptDemo/Properties/Settings.settings new file mode 100644 index 0000000..3964565 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/AutoEncryptDemo/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + diff --git a/Demo_Source_Code/CSharpDemo/AutoEncryptDemo/app.config b/Demo_Source_Code/CSharpDemo/AutoEncryptDemo/app.config new file mode 100644 index 0000000..c5e1dae --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/AutoEncryptDemo/app.config @@ -0,0 +1,3 @@ + + + diff --git a/Demo_Source_Code/CSharpDemo/AutoEncryptDemo/app.manifest b/Demo_Source_Code/CSharpDemo/AutoEncryptDemo/app.manifest new file mode 100644 index 0000000..aee0ba0 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/AutoEncryptDemo/app.manifest @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/AutoFileCryptTool.csproj b/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/AutoFileCryptTool.csproj new file mode 100644 index 0000000..4eb6281 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/AutoFileCryptTool.csproj @@ -0,0 +1,229 @@ + + + + Debug + x86 + 8.0.30703 + 2.0 + {BCEBE26C-6C20-4086-AF65-76113DE08189} + WinExe + Properties + AutoFileCryptTool + AutoFileCryptTool + v4.5 + + + 512 + SAK + SAK + SAK + SAK + + + x86 + true + full + false + ..\..\Release\ + DEBUG;TRACE + prompt + 4 + false + + + AnyCPU + pdbonly + true + ..\..\Release\ + TRACE + prompt + 4 + false + false + + + encrypt.ico + + + true + ..\..\Release\ + DEBUG;TRACE + full + AnyCPU + bin\Debug\AutoFileCryptTool.exe.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false + false + + + ..\..\Release\ + TRACE + true + pdbonly + AnyCPU + ..\..\..\Release\AutoFileCryptTool.exe.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + false + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + true + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + true + false + + + app.manifest + + + true + ..\..\Release\ + DEBUG;TRACE + full + x64 + bin\Debug\AutoFileCryptTool.exe.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + false + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + true + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + true + false + + + ..\..\Release\ + TRACE + true + pdbonly + x64 + ..\..\..\Release\AutoFileCryptTool.exe.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + false + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + true + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + true + false + + + + + + + + + + + + + + + + + Form + + + DropFolderForm.cs + + + Form + + + PasswordForm.cs + + + Form + + + FormFileCrypt.cs + + + Form + + + BlackListForm.cs + + + + + Form + + + TrayForm.cs + + + DropFolderForm.cs + + + PasswordForm.cs + + + FormFileCrypt.cs + + + BlackListForm.cs + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + True + Resources.resx + True + + + TrayForm.cs + + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + + + + + + + {34CB783E-DDA2-4CE3-80BC-37B25AA33E5F} + CommonObjects + + + {21540012-A296-45CE-8D35-3EA5A07B32A6} + FilterControl + + + + + + + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/AutoFileCryptTool.csproj.user b/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/AutoFileCryptTool.csproj.user new file mode 100644 index 0000000..a5a4054 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/AutoFileCryptTool.csproj.user @@ -0,0 +1,6 @@ + + + + true + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/AutoFileCryptTool.vs2019.csproj b/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/AutoFileCryptTool.vs2019.csproj new file mode 100644 index 0000000..fc3e62e --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/AutoFileCryptTool.vs2019.csproj @@ -0,0 +1,251 @@ + + + + Debug + x86 + 8.0.30703 + 2.0 + {BCEBE26C-6C20-4086-AF65-76113DE08189} + WinExe + Properties + AutoFileCryptTool + AutoFileCryptTool + v4.5 + + + 512 + SAK + SAK + SAK + SAK + + + x86 + true + full + false + ..\..\Release\ + DEBUG;TRACE + prompt + 4 + false + + + AnyCPU + pdbonly + true + ..\..\Release\ + TRACE + prompt + 4 + false + false + + + encrypt.ico + + + true + ..\..\Release\ + DEBUG;TRACE + full + AnyCPU + bin\Debug\AutoFileCryptTool.exe.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false + false + + + ..\..\Release\ + TRACE + true + pdbonly + AnyCPU + ..\..\..\Release\AutoFileCryptTool.exe.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + false + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + true + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + true + false + + + app.manifest + + + true + bin\x64\Debug\ + DEBUG;TRACE + full + x64 + bin\Debug\AutoFileCryptTool.exe.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + false + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + true + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + true + false + + + bin\x64\Release\ + TRACE + true + pdbonly + x64 + ..\..\..\Release\AutoFileCryptTool.exe.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + false + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + true + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + true + false + + + true + bin\ARM64\Debug\ + DEBUG;TRACE + full + ARM64 + false + 7.3 + prompt + MinimumRecommendedRules.ruleset + + + bin\ARM64\Release\ + TRACE + true + pdbonly + ARM64 + false + 7.3 + prompt + MinimumRecommendedRules.ruleset + + + + + + + + + + + + + + + + + Form + + + DropFolderForm.cs + + + Form + + + PasswordForm.cs + + + Form + + + FormFileCrypt.cs + + + Form + + + BlackListForm.cs + + + + + Form + + + TrayForm.cs + + + DropFolderForm.cs + + + PasswordForm.cs + + + FormFileCrypt.cs + + + BlackListForm.cs + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + True + Resources.resx + True + + + TrayForm.cs + + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + + + + + + + {34cb783e-dda2-4ce3-80bc-37b25aa33e5f} + CommonObjects.vs2019 + + + {21540012-A296-45CE-8D35-3EA5A07B32A6} + FilterControl.vs2019 + + + + + + + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/BlackListForm.Designer.cs b/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/BlackListForm.Designer.cs new file mode 100644 index 0000000..3670412 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/BlackListForm.Designer.cs @@ -0,0 +1,110 @@ +namespace AutoFileCryptTool +{ + partial class BlackListForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(BlackListForm)); + this.label_InputPrompt = new System.Windows.Forms.Label(); + this.textBox_BlackList = new System.Windows.Forms.TextBox(); + this.button_Apply = new System.Windows.Forms.Button(); + this.openFileDialog1 = new System.Windows.Forms.OpenFileDialog(); + this.folderBrowserDialog1 = new System.Windows.Forms.FolderBrowserDialog(); + this.label1 = new System.Windows.Forms.Label(); + this.SuspendLayout(); + // + // label_InputPrompt + // + this.label_InputPrompt.AutoSize = true; + this.label_InputPrompt.Location = new System.Drawing.Point(20, 8); + this.label_InputPrompt.Name = "label_InputPrompt"; + this.label_InputPrompt.Size = new System.Drawing.Size(262, 13); + this.label_InputPrompt.TabIndex = 0; + this.label_InputPrompt.Text = "Black Process List, seperate multiple processes with \';\'"; + // + // textBox_BlackList + // + this.textBox_BlackList.Location = new System.Drawing.Point(23, 33); + this.textBox_BlackList.Name = "textBox_BlackList"; + this.textBox_BlackList.ScrollBars = System.Windows.Forms.ScrollBars.Horizontal; + this.textBox_BlackList.Size = new System.Drawing.Size(446, 20); + this.textBox_BlackList.TabIndex = 1; + this.textBox_BlackList.Text = "explorer.exe;cmd.exe"; + // + // button_Apply + // + this.button_Apply.DialogResult = System.Windows.Forms.DialogResult.OK; + this.button_Apply.Location = new System.Drawing.Point(394, 81); + this.button_Apply.Name = "button_Apply"; + this.button_Apply.Size = new System.Drawing.Size(75, 20); + this.button_Apply.TabIndex = 2; + this.button_Apply.Text = "Apply"; + this.button_Apply.UseVisualStyleBackColor = true; + this.button_Apply.Click += new System.EventHandler(this.button_Ok_Click); + // + // openFileDialog1 + // + this.openFileDialog1.FileName = "openFileDialog1"; + // + // label1 + // + this.label1.AutoSize = true; + this.label1.ForeColor = System.Drawing.SystemColors.MenuHighlight; + this.label1.Location = new System.Drawing.Point(20, 63); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(332, 13); + this.label1.TabIndex = 3; + this.label1.Text = "The process in the black list will get the raw data of the encrypted file"; + // + // BlackListForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(514, 113); + this.Controls.Add(this.label1); + this.Controls.Add(this.button_Apply); + this.Controls.Add(this.textBox_BlackList); + this.Controls.Add(this.label_InputPrompt); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Name = "BlackListForm"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "Add Black List Processes To Selected Folder"; + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Label label_InputPrompt; + private System.Windows.Forms.TextBox textBox_BlackList; + private System.Windows.Forms.Button button_Apply; + private System.Windows.Forms.OpenFileDialog openFileDialog1; + private System.Windows.Forms.FolderBrowserDialog folderBrowserDialog1; + private System.Windows.Forms.Label label1; + } +} \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/BlackListForm.cs b/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/BlackListForm.cs new file mode 100644 index 0000000..270323b --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/BlackListForm.cs @@ -0,0 +1,43 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; + +namespace AutoFileCryptTool +{ + public partial class BlackListForm : Form + { + public string BlackList = string.Empty; + + public BlackListForm() + { + InitializeComponent(); + } + + private void button_Ok_Click(object sender, EventArgs e) + { + BlackList = textBox_BlackList.Text; + } + + } +} diff --git a/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/BlackListForm.resx b/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/BlackListForm.resx new file mode 100644 index 0000000..c749c4f --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/BlackListForm.resx @@ -0,0 +1,576 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + + 147, 17 + + + + + AAABAAgAEBAAAAEACABoBQAAhgAAABAQAAABACAAaAQAAO4FAAAYGAAAAQAIAMgGAABWCgAAGBgAAAEA + IACICQAAHhEAACAgAAABAAgAqAgAAKYaAAAgIAAAAQAgAKgQAABOIwAAMDAAAAEACACoDgAA9jMAADAw + AAABACAAqCUAAJ5CAAAoAAAAEAAAACAAAAABAAgAAAAAAEABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP// + /wAAzf8AmXtrAImb/gDdu6kAOljoAGP4/wDH0f0App6/AEme/wD14tkAocD+ANTG0AA87P8AfpjYAE5x + /wCrnpgA4+j/AGaN/wC1r9cAHeX/ALCOfQBfs/8AOoL/AMCoowD69OkAbeL/AE1m4wBbmvEAlpPIANvE + vAC1t8QAptH/AKadqQDx8vsA4c/KAKeCcABX7f8AV2fuAKez/wBdm/8AYOH/APz59ACtvf4Ag5H+APjt + 2gBDe/8A8OjgALKbnwDbv7MAnpfDAFSX/wCph3gA9/j/AEua+ABar/oA+vHiANvHwwCdf28A18zPAJt3 + ZgDcuqMA+vj6APz27gDcvq4Aon9vAP37+ACXeWcA28G3APT1+wBb7f8Aps3/AJx9bADewbQA+fTuAPry + 5gDevqsA3sS6AKuJegDauKUArIh3ANq6qAD39vsAmXtoAPnv4AD79ewA27ytANzCtQD9+vYA/PfwAK+O + fwDcuaUA3LunANu6qgDcv7EA28K5ANvFvgDbxsEA+vHkAN6+rQCafGoAnX5tAKOAcAD79eoA272vAJh5 + aACZemoAm3xrAJx8bQD79OgA+vPoALGOfgDcvKkA2ruqANvAtADbw7oA/fv5AJp8awCbfGwA/PnzAJx9 + bQCcfm0A/PbtAPrz5wD68+YA3LqlANy7qQDbuqkA3cK1ANu/sgDbv7QA28fCANvCuADbw7sAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAGxmenp6eUlsbGVUbAAAAAA9ARoaGm98TGNVLkQAAAAAQgGBgVhfQX9+Pjlq + AAAAAGcBhnSFMmlyUFx9awAAAAA1AYRiH0WCV1JdbgMAAAAATwE6hGFgc2mAcWh2AAAAAFs2DTwkYINp + XgVWbAAAAAAiKC0hCFNDWXhae3cAAAAADzQ4NycUTkpkTUBtAAAAAAYqFUcXDEZDK0swOwAAAAAdJgIO + GAQjdSUlJSUAAAAAHAoHGy8sP3UlC3ARAAAAAB4TKRBIEgEBJXARAAAAAAAZIDMJMRZRUSURAAAAAAAA + AAAAAAAAAAAAAAAAAAD//wAAwAMAAMADAADAAwAAwAMAAMADAADAAwAAwAMAAMADAADAAwAAwAMAAMAD + AADAAwAAwAcAAMAPAAD//wAAKAAAABAAAAAgAAAAAQAgAAAAAABABAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAJt8a/+dfm3/nH5t/5x+bf+cfm3/nH1t/5x9bP+bfGv/m3xr/5p8av+Ze2j/m3xr/wAA + AAAAAAAAAAAAAAAAAACbd2b///////r06f/69On/+vTp//rz6P/68+f/+vLm//rx5P/57+D/+O3a/5d5 + Z/8AAAAAAAAAAAAAAAAAAAAAon9v///////dwrX/3cK1/9zCtf/cv7H/3L6u/9y7qf/cuqX/3Lqj//rx + 4v+YeWj/AAAAAAAAAAAAAAAAAAAAAKOAcP//////28O7/9vDuv/bwrj/27+z/9u9r//au6r/2ril/9y5 + pf/68+b/mXpq/wAAAAAAAAAAAAAAAAAAAACph3j//////9vHwv/bxsH/28S8/9vBt//bv7L/27yt/9q6 + qP/cu6f/+/To/5l7a/8AAAAAAAAAAAAAAAAAAAAAq4l6///////bx8P/28fC/9vFvv/bwrn/28C0/9u9 + r//buqn/3Lyp//v16v+afGv/AAAAAAAAAAAAAAAAAAAAAK+Of//3+P//1MbQ/9fMz//hz8r/28K5/9u/ + tP/bva//27qq/927qf/79ez/m3xr/wAAAAAAAAAAAAAAAAAA/wGmnan/p7P//4OR/v+m0f//x9H9//f2 + +//9+/j//fr2//z58//89/D//Pbt/5t8bP8AAAAAAAAAAAAAAAAAKf8XfpjY/1SX//9ar/r/S5r4/1dn + 7v+1r9f/3sS6/97BtP/evq3/3r6r//z27v+cfG3/AAAAAAAAAAAAAAAAACz/NzpY6P9g4f//HeX//1vt + //9fs///ocD+//T1+//9+/j//Pn0//n07v/w6OD/n4Bw/gAAAAAAAAAAAAAAAAAu/0FbmvH/V+3//wDN + //887P//OoL//4mb/v/x8vv//fv5/6eCcP+ngnD/p4Jw/6eCcP8AAAAAAAAAAAAAAAA3fv8zTWbj/0me + //9j+P//beL//0N7//+tvf7/+vj6//37+f+ngnD/9eLZ/7GOfv+ngnBYAAAAAAAAAAAAAAAAABf/CJaT + yP9mjf//XZv//05x//+mzf//4+j/////////////p4Jw/7GOfv+ngnBYAAAAAAAAAAAAAAAAAAAAAAAA + AADAqKP/tbfE/56Xw/+mnr//spuf/7COff+siHf/rIh3/6eCcP+ngnBYAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAD//wAAwAMAAMADAADAAwAAwAMAAMADAADAAwAAwAMAAMADAADAAwAAwAMAAMADAADAAwAAwAcAAMAP + AAD//wAAKAAAABgAAAAwAAAAAQAIAAAAAACgAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8AKF31AKJ6 + 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 + ///9+/n/3MjD/9zIxP/cx8L/28W//9vEvf/bwbn/28C2/9u/sv/bva//27ur/9u5p//evar/+/bt//zz + 5/+Uc2D/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAApYRz//j5///p7Pv/xLbJ/8S5yf/Pwcb/2sO//9zE + vP/bwrn/28G1/9u+s//bva//27ur/9u5qP/evar//ffu//716P+Wc2L/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAP8BmH2C/8bR//+wv/7/mKDq/6PK8P+qr+f/wsLj/+LY3f/t39n/7N7X/+zd1f/s29L/7NrP/+vZ + zf/t2cz//Pfv//306f+Vc2H/AAAAAAAAAAAAAAAAAAAAAAAAAAAANf8di56x/4GR//9OdP//P17//37M + //9edv//mKz+/8bR/f/z9Pv//vz6//37+P/9+vb//fn0//z48v/8+PH//Pjw//326/+XdGP/AAAAAAAA + AAAAAAAAAAAAAAAx/wsALf8/WG3G/33U//88hv//UaT6/2PY/f8ravb/PV/w/4iO3P+5rc3/3sa+/9/F + uv/fw7b/38Cy/9+/rv/gwa///fjw//326/+WdGP/AAAAAAAAAAAAAAAAAAAAAAAx/x8AMP9dLEbc/0Oc + //9g6v//VOz//0fd/v9gwPv/KF31/2WK6/+lrtP/07u7/9zAtP/bvbD/3Lys/9y5qf/fvqv//fry//31 + 7P+YdWP/AAAAAAAAAAAAAAAAAAAAAAAz/y0AMf94JVXl/2vO//8s2///AMr//wTQ//9X6P//c9///12V + //+ruP//6ez8///9+//6+PX/9vLt//Ps5//s5N//4dbQ/8m1qf+NaFftAAAAAAAAAAAAAAAAAAAAAAAs + /y8AJv97QYDr/1TW//8o3f//AMr//wLP//9u7P//PY///0Ro//+puv//6Oz8/////v/Ktar/nHpp/6qL + eP+ohGr/onpc/4ZgT/OQZ1ZBAAAAAAAAAAAAAAAAAAAAACBb/ytkt/+NUYzp/0SW//909f//Ld///z7j + //9Qxv//LWz//1d4//+2xP7/8PH7/////f/Vx77/zLWj//zpxf/wzJL/m3Rc85ZpXDoAAAAAAAAAAAAA + AAAAAAAAAAAAAAAv/xAALP9GR1HI/0SC//9Mof//Ucr//2PC//9oyf//WJT//4uf/v/L1f3//Pr6///+ + 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 + AA/gAAAfwAAAP+AAAH/wAAD/8AAB//AAA//wAAf/8AAP//////8oAAAAIAAAAEAAAAABACAAAAAAAIAQ + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAhGFQ/4ZhUP+EYE//hGBP/4Rg + T/+EYE//hGBP/4NgT/+DYE//g2BP/4NfTv+CX07/gl9O/4FfTv+BXk3/gF5N/4BdTv9/XUz/f11N/35c + S/9+XEz/fVtL/35dTf97W0v/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACFYVD/+OTT//Le + zP/y3sz/8t7M//LezP/y3sz/8t7M//LezP/y38z/8t3M//Ldy//y3cv/8t7K//Lcyv/y3Mf/89vH//Ha + xP/x2cL/8tjA//DXvv/x1r3/9dm9/3xbS/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIZh + UP///fL/+vTo//rz6f/68+n/+vPp//rz6f/68+n/+vPo//r06P/68uj/+vLn//ry5//68+b/+vHm//ry + 5f/68uT/+fHi//nw4P/5797/+Ozb//nt2f/03MT/e1pJ/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAhmFQ///+9f/79ur/+/Xs//v16//79ev/+/Xr//v17P/79er/+/bq//v06//79On/+/Tq//v1 + 6P/78+n/+/Pn//z05v/68uX/+vHl//nw4f/57+D/+vDe//Texv99W0r/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACHY1H///73//v17P/89uz/3sS3/97Ft//exbf/3sS3/93Dtf/dw7X/3cKz/93B + sv/dwbD/3b+u/92+q//dvar/3byo/926pf/duqX/376p//rx4v/68OH/89/J/3xbSv8AAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAIhiUf////f//Pbt//z27v/bwLT/28C0/9vAtP/bwLT/28Cz/9u/ + sv/bvrH/272u/9q7rP/auqr/2rmo/9q3pf/atqL/2rWg/9q1oP/duqT/+vLl//vz5P/14Mz/fVxL/wAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAiWNS////+v/89+///Pfv/9vCuP/bwrj/28K4/9vC + t//bwrb/28C1/9u/sv/bvrH/272v/9u8rP/auqr/2rmm/9q3pP/atqH/2rah/927pf/78+b/+/Tn//Ti + zv9+W0z/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACKZFP////6//z48P/8+PH/28O7/9vE + u//bxLv/28O7/9vDuf/bwrj/28C2/9u/s//bvrH/272u/9u8rP/auaj/2ril/9q3o//at6P/3bun//vz + 5//89ej/9uPS/4BdS/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAItlU/////v//Pjy//z4 + 8v/bxr7/28a//9vGv//bxL7/28S8/9vDuv/bwbf/28C1/9u+s//bva//27ys/9u7qv/buqj/2rek/9q3 + pP/dvaj/+/To//z06f/15NP/f1xN/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjGdU//// + /v/9+fP//fn0/9vHwv/bx8P/28fD/9vGwv/bxb//28S8/9vDuv/bwbf/27+z/9u+sf/bvK//27ur/9u6 + qP/buKX/27il/929qv/79On//Pbq//Xk0v+AXkz/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACPZlX///////369f/9+vX/28jD/9vIxP/byMT/28jC/9vGwP/bxL3/28O6/9vCuP/bwLX/276y/9u9 + r//bu6z/27qp/9u5p//buaf/3r6q//v16v/89ev/9eTT/4JdTP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAI9nVP///////fr2//379//bx8P/28fE/9vHxP/bx8P/28bA/9vFvv/bxLv/28K4/9vA + tf/bv7P/272v/9u8rP/buqr/27im/9u4pv/evqv/+/Xr//z17P/15NT/gV9O/wAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAkWhV///////9+/j//fv4/9zHwv/bxsP/28bD/9vGwf/bxcD/28S9/9vD + u//bwbn/28C1/9u/sv/bvrD/27yt/9u6qv/buKf/27in/969q//79ez//Pft//Xl1v+DXk3/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACSaVf///////78+f/+/Pr/2sTA/9rEwP/cxsD/3MbA/9zF + v//cxL3/28O6/9vCt//bwLX/276y/9u9r//bvK3/27qq/9u5p//buaf/3r2r//z27f/89u3/9eXV/4Ng + Tf8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJNqVv/4+f//6Ov7/9rh/P+4r8r/uK3K/7/B + zv/Ht8T/1b/A/9zEu//cw7r/28G3/9vAtP/bvrL/272v/9u8rf/bu6r/27mn/9u5p//evar//Pbt//z2 + 7v/15df/hF9P/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8BiGhk/9Ha//++yf3/ssH+/6u7 + /v+qs/7/vvP+/73F/v/O1/3/5+v7//37+//+/Pr//fv5//379//9+vb//fr1//359P/8+PL//Pjx//z3 + 7//89u7//fjv//fm1v+EX07/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACh4/yB7c4r/rbf//4ue + /v9phP//V3H//1l9//+a4///iJX+/6q6/v/Dzv3/4eb8//37+//+/Pn//fv4//379//9+vb//fn0//35 + 8//8+PH//Pfw//z37//99+//9ubY/4VhTv8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANv8RACT/OIms + t/98q///P1f//0WD//8qVPb/Yrj6/1+m+f81TvL/Wm/q/46T3P+rptL/zbzH/9/Hvf/fxbv/38O4/9/B + tP/fwLH/37+s/9+/rP/hwrD//Pfv//338P/25tj/hWBQ/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AwA1 + /ysAMP9QQj63/5z7//9SpP//RZf//1ix+v9j8P7/O4v4/zR69v8wVvP/Wm3n/5SV1f+zqMj/2L+6/9zA + tf/bvrL/272v/9u6qv/buaf/27mn/96+q//89+///ffw//bm1/+GYE//AAAAAAAAAAAAAAAAAAAAAAAA + AAAAQv8PADb/PAAw/2wnPNX/K2f//2b///995///ZfT//0jt//9w1/z/bcn7/ylS9P81SfD/d3vd/6eo + z//Mtr7/3MC1/9u+sv/bva//27qq/9u5p//buaf/3r6r//348f/9+PH/9+fZ/4ZhUP8AAAAAAAAAAAAA + AAAAAAAAAAAAAAA2/xsAM/9HAC7/iiNQ3v9XrP//etT//yjg//8Azv//As///1bw//9bxf//Zdv//6D9 + //+V2P//s8n+/9/l/P/+/Pr///35//79+f///fn///33//779//9+PP/+fXt//Xw6P/p1sj/h2JQ/AAA + AAAAAAAAAAAAAAAAAAAAAAAAADX/IQAy/0wALv+aHz/e/zyP//9h6///AM7//wDL//8Ayv//DdT//0ri + //9Mqv//MVz//1tv//+uvP7/2eD8//78+v///fv/5tzX/9nLwv/g08z/2szF/9XFvv/Itq3/u6Sa/5d1 + Zf+GYlG2AAAAAAAAAAAAAAAAAAAAAAAAAAAAMv8gACb/TAAY/5k9euf/XN7//0jw//8K0v//AMv//wDK + //8Z2P//gf3//0+o//8yY///XXv//66//v/Z4Pz//vz6//////+7opX/oYBy/6eJeP+lg2//o39n/7CI + Zv+TbFT/imRTxIZfSw4AAAAAAAAAAAAAAAAAAAAAAAAAAABD/xllvP9qiun/vHTA7v9Uqf//bMX//0Ps + //8Q1P//FdX//z/q//9Nq///NIf//zRl//9xi///tcP+/+Ln/P/+/Pr//////8u3rf/FrZ////Xg//nh + u//41pz/xZ5u/4ljU8GMXV8MAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC//DAAm/zkAH/9lLTfQ/zBd + //+L7v//c8z//0rl//9/////Xcf//4D///8uZP//Q2P//5Oo/v/Czv3/7/L7//78+v////z/zLqw/76h + i//237j/88+W/8CYav+IYlTPi2RODgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8BADP/JgAw + /0pNUK7/QGv//zBa//9Yvv//VcD//3XP//8pav//WKT//5Tq//92gv//sL7+/9Xd/P/8+vr//vz5///+ + /P/XycH/so1y//bTmv/In27/iWRVzJ1uXhIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAOv8LADf/MmtdkP9/lv//Sl7+/4/o//88dP//M2r//zZn//9HX///hbD//7Xi/v/J0f3/8PD7//78 + +v/9+/j////7/9PCuf+3kGr/y6Fv/4tkVM2VYlIRAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAOv8QfWR7/7bE//+bpP3/q/b+/2x5/v9shf7/fZX+/5ms/v+yvf3/ydn9/+rt + +//+/Pr//fv5//379////vv/zrqx/6J5Wv+PaVbWnXFZGQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACVb2T/2uL//8jQ///B7f//tb7//7XD//+7yP//xtL//9jf + ///y9P////////////////////////////+zl4n/j2dV1KFtYhcAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJpxXf+ccmD/lHBm/5B0cf+IanD/h2px/4pr + a/+QbWT/l25b/5dtW/+Wbln/lWxa/5RrWf+Talj/k2xZ/45nVbmTblUWAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/////wAAAP8AAAD/AAAA/wAAAP8AAAD/AA + AA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/gAAAP4AAAD+AA + AA/gAAAP4AAAH8AAAD/gAAB/8AAA//AAAf/wAAP/8AAH//AAD///////KAAAADAAAABgAAAAAQAIAAAA + AACACgAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8AMFz/ALCIZgBm7/8AqKXUAADL/wD41pwAZlyPAHaC + /wCt3/0AellJAEI+twDn3tgAvaSZAFCv/gBzg8kAVm7WAHq46ACbpP0AIETcADHe/wDbwbYAg2V1AIms + twAsg/8AltnhAN/l/ADNomwAt7vvAJX6/wBScv4Av8HOAPnhuwCNktwA/fLeAGHH/QCTbFQARun/AID+ + /wAvaeQAeq39AImRmwBw1f8AydP+AI7E3QBnec8A2rWfAISV+ACa4/8AR1//ADVJ8ABETLQARlTeALKW + igBwf+QAyretABPS/wCWem0ALTfQAFZ76wB76f8ApX5dAPDy/QA3d/8AX6b5AFKV9QCoinsA+OTTAF3i + /wC+8/4A3c7GALmwzwAfV+EAKnH+AESG+wDMtr4AZMP7AHpgeQD79/IA6dXFAKv2/gCE8P8Ap7P3AGW4 + /wBm//8AhmFPACdT7gDDmGcAxKWJAJBtZAClf2cAxK6gAN++qQDqz7sAwcn4AGx5/gAyev0ANmb+APbw + 5wCyjXIAVun/ANPb/QD14sMASeX/AFuw/QBYgP4Ak87+AEBf4QCacV0A1MHDAGeD/gAL0f8A8+reAD9X + /wAzkv8AoYByALTQ/gB8k/wAz8DJAIHX/QDmzLoA8MqNAN/QygBylP8Ahbz/AOjo9wC4j2UAccz7AEBo + /wBm2f8Ah6D/AIhoXQCbdWUAWJ3/AJaX1wCQdHEAJ0HUAPn5/QCU6v8Alaj8ALOoyACLZVQA+vHrAP78 + +ADmyLIAzbqxADRc8gA7i/gAq7r8AMva/QDTwrkAyLjGACxl+gBVwP8AgV1MANu5pwDbva4A9+3jAKCv + +QBZr/8AkXNnAMGceADL6v4A+ufJAMTN+wDZ4f4A28W/AP37+QBI7/8AaXXNAJZtWQBSpP8A4Ma3ALXE + /gDx2cIApYNxANLa/gDcyr8A8ufbAO7ezwBtyfsAQWL9AIppbABd6f8ABM//ADlV7AD19fsAlm5iAI/o + /wDVxb4AuJ+TAKCd0wD58+0A28O7ABDS/wDcyMMA2L+6AK+//wD//vsAH9j/APXZvQD02rAA0NT1AJFo + VQCUc2UAafP/AN/EtACtt/8A/Pn1AD3j/wBbb/8Aof//AFx7/gCEX00A9ezfADFp/wCPeW4A27urAFSp + /wC7xPsANWD/APrw6ADz050A3rylAODArgB/W0sAiWNSAJxyYADa4fwAxdD/ALvH/gAoZvsAjXBjAOru + /QDj5vkAWm3nAE+o/wDbuKQAW7r/ANu/sgB30P8AssH+AJNqVwD89uwASl7+APDk1gDz38oA89zHANng + /wBqh/8A//3yAMifbgDv4tMA37+sAN28qAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + 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 + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAhWFQ/4RhUf+DYE//g19P/4Nf + T/+DX0//g19P/4NfT/+CX0//gl9P/4JfT/+CYE//gl5O/4JeTv+CXk7/gV5O/4FeTv+BXk7/gV9O/4Bd + Tf+AXU3/gF1N/39eTf9/XE3/f1xM/35cTP9+XUz/fltM/31bS/99XEv/fFpK/3xbSv97W0r/e1tL/3tb + S/97W0z/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgFxL/+7R + u//rzrn/6s25/+rNuf/qzbn/6s25/+rNuv/qzbr/6s26/+rNuf/qzbn/6s25/+rNuf/qzrn/6865/+nO + uP/pzbj/6c24/+nNt//qzbf/6s23/+rMt//qzLb/6cy2/+nLtf/py7T/6cu0/+nLs//oy7P/6Mqz/+jK + sv/oyrH/58mx/+vLsv92Vkj/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAf1xL/+rUwv/m0L//5tC//+bQv//n0L//59C//+fQwP/n0MD/59DA/+fQv//m0L//5tC//+bQ + v//m0L//5tC//+bQvv/mz77/5s++/+bPvf/mz73/5c+9/+XPvP/lzrz/5c67/+XOu//lzbr/5M26/+TN + uf/kzLn/5My4/+TMt//ky7f/5My3/+XIsP93VUb/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAgFpJ//Dez//s2sv/7NrM/+zazP/s28z/7NvM/+zbzP/s28z/7NvM/+zb + zP/s2sz/7NrM/+zay//s2sv/69rL/+vay//r2sr/69nK/+vZyv/r2cn/69nJ/+vYyP/q2Mj/6tjH/+rX + x//q18b/6tfG/+nWxf/p1sT/6dbE/+nVw//o1sP/5tC8/+bJsf92V0f/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgVxK//Tl2P/z6d3/8uje//Lo3v/y6N7/8ujd//Lo + 3f/y6N3/8ujd//Lo3f/y6N7/8uje//Lo3v/y6Nz/8ujd//Lp3f/y59z/8ufc//Pn3P/x6Nv/8ebb//Hm + 2v/x59r/8uXZ//Dl2P/w5tj/8OTX//Hl1f/v49b/7+PV//Dk1P/t3s3/59C8/+XIsf94Vkf/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgltK//Xn2v/38Oj/9u/n//bx + 5v/28ej/38e4/9/Huf/fx7n/38e4/9/HuP/fxrj/38a4/9/Gt//fxbf/38S1/9/EtP/fxLP/38O0/9/D + sf/fw7H/38Gu/9/Arv/fwK3/38Cr/96+q//ev6n/3r2m/967pf/hxKv/8+re//Tr3v/t4ND/5tC9/+XK + s/95WEf/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAglxL//Tm + 2v/38ej/9/Do//fw6P/38Oj/2r6x/9q+sf/avrH/2r6x/9q+sP/avrD/2r6w/9q9r//ava7/2r2t/9q8 + rf/avKz/2rqr/9q6qf/auaj/2rmm/9q4pP/at6P/2rei/9q2oP/atp//2bSd/9mzm//evKX/9Ove//Pr + 3v/t39D/5tG+/+fJsv95V0j/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAg15L//Tn2//48un/9/Hp//fx6f/38en/28Cz/9vAs//bwLP/28Cz/9vAs//bwLL/27+y/9u/ + sf/avrD/2r2v/9q9rv/avK3/2ryr/9q7q//auqr/2rmn/9q4pv/auKT/2rej/9q3ov/atqD/2rWe/9m0 + nf/evab/9Ovf//Xs3//v4dL/5tG//+bLs/96V0j/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAhF1K//bo3P/48uz/+PLq//jy6v/48ur/28G1/9vBtv/bwbb/28G1/9vB + tf/bwLX/28C0/9vAs//bv7P/27+x/9u+sP/bvq//2ryt/9q7q//au6r/2rqp/9q5qP/auKb/2rek/9q3 + ov/atqL/2raf/9q1nf/fvqj/9Ozg//Ts4P/u4NH/59LA/+bKtP96WUj/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAhV9M//Xq3//48+z/+PPr//jz7P/48+z/28K3/9vC + uP/bw7j/28K4/9vCt//bwrb/28K1/9vAtP/bwLT/27+z/9u/sf/bvrD/272u/9u9rf/au6z/2ruq/9q6 + qf/auaf/2rim/9q3pP/atqL/2rah/9q1n//fvqn/9ezh//Tt4f/u4tL/59LA/+bMtv97WEn/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAh15L//fp3//59O3/+PPt//nz + 7f/59O3/28O6/9vDuv/bw7r/28O6/9vDuf/bw7j/28K3/9vCt//bwLb/28C0/9u/sv/bvrH/276w/9u9 + r//bvK3/27yr/9q6qv/auqj/2rmm/9q4pf/at6P/2rah/9q1oP/fvqn/9e3i//bt4v/w4dP/59PB/+jL + tf97Wkj/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAhmBN//bq + 4P/59e7/+fTu//n07v/59O7/28S7/9vEvP/bxLz/28S8/9vEu//bw7r/28O6/9vCuf/bwrf/28C2/9u/ + tP/bv7P/276x/9u9r//bva7/27yt/9u8q//bu6n/2rmn/9q5pv/auKT/2rai/9q2oP/fv6r/9e3j//Xu + 4//v49X/6NPC/+fLtv98WUj/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAhmBN//br4f/69fH/+fXv//n17//59fD/28S+/9vFvv/bxb7/28W+/9vEvf/bxLz/28O7/9vD + uf/bwrj/28G3/9vBtv/bv7T/276y/9u+sf/bva7/27yt/9u8rP/bu6v/27qo/9q5p//auKX/2rej/9q2 + ov/fv6v/9e7k//Xu5P/v4tT/6NPC/+fLuP98WUj/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAh19M//fs4v/69vH/+vbw//r28f/69vH/28bA/9vGwP/bxsH/28bA/9vG + v//bxb7/28W8/9vDu//bwrr/28K4/9vBtv/bwLX/28Cz/9u+sv/bvbD/272u/9u8rP/bu6v/27up/9u6 + p//auKb/2rik/9q3ov/fv6z/9u7k//Xv5f/v5NX/6NTD/+fNt/98WUr/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAiGFO//fs4//69/L/+vby//r28v/69/L/28bC/9vH + w//bx8P/28fC/9vGwf/bxsD/28W+/9vEvf/bxLv/28O6/9vBt//bwLb/28C0/9u/sv/bvrH/272v/9u8 + rf/bu6v/27uq/9u6qP/buaf/2rik/9q3o//fwKz/9u/l//fv5f/x49b/6NTE/+fMuf99W0n/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAiWBN//jt5P/7+PP//Pfz//v3 + 8//79/P/28jC/9vIxP/bycT/28jD/9vIwv/bx8H/28a+/9vFvf/bxLv/28O6/9vCuf/bwrf/28G1/9u/ + s//bvrH/276w/9u8rv/bu6z/27ur/9u6qP/buaf/27ml/9q3o//fwKz/9u/m//bw5v/w49j/6dTE/+fO + uv99Wkn/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAi2FP//ju + 5f/7+PT/+/j0//v49P/7+PX/28jD/9vIxP/bycX/28jE/9vHw//bx8H/28a//9vFvv/bxbz/28S6/9vC + uf/bwrf/28G2/9vAtP/bvrL/276w/9u9rv/bvK3/27ur/9u6qf/buaj/27ml/9u4o//fwK3/9/Dn//bw + 5//w5df/6dXF/+jNuf9+Wkn/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAimNO//ju6P/8+ff/+/n1//v59v/8+fb/28fE/9vIxP/byMX/28jE/9vHw//bxsL/28bA/9vF + vv/bxb3/28S7/9vCuf/bwbj/28G2/9vAtP/bv7P/276w/9u9r//bvK3/27ys/9u6qf/buaj/27mm/9u4 + pP/gwK3/9/Do//bx6P/w5Nj/6dXG/+jNuf9+Wkv/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAi2JQ//nv6P/8+vf//Pn2//z69//8+vf/28fC/9vHw//bx8P/28fD/9vH + wv/bxsH/28bA/9vFvv/bxL3/28S7/9vCuv/bwbj/28C2/9vAtP/bv7P/27+x/9u+r//bvK7/27ur/9u7 + qv/buaj/27im/9u4pf/gwK7/9/Ho//jx6P/y5Nr/6dXG/+jPu/9/XEr/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjGRP//nw6f/8+/j//Pr4//z6+P/8+/j/3MfC/9zH + w//cyMP/3MfD/9zHwv/cx8H/3MbA/9vEvv/bxL3/28O7/9vDuv/bwbj/28C3/9vAtf/bv7L/276x/9u+ + sP/bva3/27us/9u7q//buaj/27im/9u4pf/gwK//9/Hp//fx6f/x5Nn/6dbH/+jOuv9/W0r/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjmNR//nx6v/9+/n//vv5//37 + +f/9+/r/3MbB/9zHwf/cx8H/3MfB/9zGwf/cxsD/3Ma//9zFvv/cxb3/28O7/9vCuv/bwrj/28G2/9u/ + tf/bv7P/276x/9u9r//bva7/27ys/9u7qv/buqn/27in/9u4pP/gwa7/9/Hq//fy6f/x5tv/6tbH/+jO + vP+AW0r/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAj2RQ//rx + 6//9/Pr//fz6//38+//9/Pv/3MfB/9zHwf/cx8H/3MfB/9zHwP/cxsD/3Ma//9zFvf/cxLz/3MO7/9zD + uv/bwbj/28G2/9vAtP/bvrP/276x/9u9r//bva7/27ys/9u6qv/buqn/27mm/9u3pP/gwa7/+PLq//fy + 6v/x5dr/6tbI/+jOu/+AXUz/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAj2ZQ//ry7P/+/fv//fz7//79/P/+/fz/3MbA/9zGwf/cxsH/3MbB/9zGwP/cxsD/3MS//9zE + vf/cxLz/3MO6/9zCuf/cwrj/28C2/9vAtP/bv7P/276y/9u9r//bvK7/27ys/9u7q//buaj/27mn/9u3 + pP/gwa7/+PLr//fy6//x5dz/6tbI/+nQvf+AXEv/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAkGVS//vy7f/6+f7/8vP8/+zu/f/p7f3/yrnE/8y7xP/RwcP/2cPA/9zF + v//cxb7/3MS+/9zDvf/cw7v/3MO6/9zCuP/cwrf/3MG2/9u/tP/bv7L/276x/9u9sP/bvK3/27us/9u7 + qv/buqj/27mm/9u4pP/gwa7/+PLr//nz6//x59v/6tfJ/+nPvP+BXEv/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjmZV/+Th8P/Z4f7/0Nn9/8rU/v/I0v7/yNL+/8jT + /v/L6v7/2eD+/+fr/v/4+f7//v79//7+/f/+/fz//v38//79+//+/Pr//vz6//78+f/9+/j//fv3//36 + 9v/9+vX//fr0//359P/9+fP//Pjy//z48f/89/D/+PPs//jz6//y5t3/6tfJ/+nPvP+BXEv/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMv8QfF5s/8fK8v++y///s8P+/629 + //+qu///qrn//63Z//+x0P//vsr//8rU///Z4P//7vH+//7+/v/+/v3//v38//79/P/+/fv//vz6//78 + +f/+/Pj//fv4//379//9+vb//fr1//359P/9+fP//fny//z48f/8+PD/+PPs//jz7P/y5tz/6tfJ/+nP + vv+BXkv/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADZ//xwSSf8ybll9/624 + 9P+esf//iJ///3WQ//9qh///aoD//5zy//+FoP//nrD//7DA///AzP//0tv//+rv/v/+/v7//v79//79 + /P/+/fz//v37//78+v/+/Pn//fv4//379//9+vb//fr1//369P/9+fP//fny//z48v/8+PH/+PPs//jz + 7P/y5tz/6tfJ/+nPvf+CXUv/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC3/EgAo + /y6C4f+MY2GZ/4SV+P9bev//Qmn//zhm//83Y///NGT2/6P+/v86VPP/UWvv/3eG5v+UmuD/p6fb/7mz + 1v/SxM7/4c7J/+HNyP/hzcb/4cvD/+HKwf/hysD/4cm+/+DHvP/gx7r/4MW4/+DEtv/gxLT/4MKy/+DC + r//kyrj/+PPt//j07P/y5tz/6tfJ/+nPvf+CXU3/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAIf8IADP/KQAy/0EKQP9ilujn/1WF/P82YP//Mmb//2W4//8uZ///X7D6/3bm/f8rWfX/L1n0/z5d + 8P9peuT/kJTZ/6Wi0/+6sMz/1sHC/9zFvf/cxLz/3MK6/9zBuP/cwLX/3MC0/9u+sf/bvbD/27ut/9u7 + qv/buqn/27mm/9u3pP/gwa7/+fPt//j07f/z6N7/6tfK/+nPvv+CXUz/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAMv8bADL/OAAx/1IALf9+PGPZ/57///9Vov//K2n//5T2//8xif//YeP+/2DQ + /P8lYvb/OX32/y5f9P88XPD/cH7i/5aX1/+sps//xrfH/9zFvv/cxLz/3MK6/9zBuP/cwLX/3MC0/9u+ + sf/bvbD/27ut/9u7qv/buqn/27mm/9y4pP/gwa7/+PTu//n07f/y5tz/6NXH/+TJuP+CXUz/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAs/wYAMf8qADT/RgAx/2cAMf+rH0Db/16u/f9e9///YcL//2Hg + //9/7P//NeD//2PJ/P9kw/v/ccz7/yli9f8uWfP/SWHs/4SI3P+gndP/ua3L/9jCv//cxLz/3MK6/9zB + t//cwLX/3MC0/9u+sf/bvbD/27yt/9u7qv/cu6n/27mn/9u4pf/gwK7/+fXu//bw6f/z7OT/6dnO/9/E + tP+GYlD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAw/xAAM/8zADT/UAAz/4IANv/CHUze/ylq + /P9s1///H9n//2nu//8t2///ENL//3Lz//9m8P//IoH//ypx//83d///VZD//5LM//+w2///ytf//+/y + /v/+/v3//v38//38+//9+/n//Pr4//37+P///vr////8///9+v/9/Pf/+fXy//Xw6v/x6eT/7OXe/+jf + 2f/l3Nb/3Mq//7GPf/+EY1X0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAq/xgAMP86ADH/WAAy + /5kAOf/JT5nq/3DS/v9n0///Ze///wDK//8AzP//AMz//wvR//+C8v//XOD//2r1//+e////es3//2+Y + //+ntf//xdD//+fr/v/+/v3//v38//38+//9+/n//Pr4//37+f/azcX/wKqf/76mm/+8o5j/uKCU/7ee + kv+zm5D/spiP/6iNgP+Uc2X/h2JR/4hjUvyKbF1PAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAt + /xwAM/89ADH/XQAz/6UAP//KG1Ph/1Ct/f9Y5///BM///wDM//8AzP//AMz//wDM//8c1///W+T//1u8 + //8tdP//NWD//1p5//+itP//ws7//+Po/v/+/f3//v38//38+v/9+/n//Pr4///++//DrqP/pINz/8y7 + sv/Is6X/xq2a/8Wojv/DooP/wZx4/8qicv+4j2X/iWRW+5RzYkUAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAt/xwAM/89ADH/XQAu/6UANv/KJGXl/2DB/v9W5P//E9L//wDM//8AzP//AMz//wDL + //894///Z9P//ySB//8tcf//NWj//1p7//+itP//ws7//+Po/v/+/f3//fz7//38+v/9+/n//Pr4///8 + +v/NubD/vKSY////+v/78N7/+ObJ//Xcs//y05//88yL/9Opb/+HZVf5j3NjOgAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAp/xgAKv87ACr/Wjd8/7N72v/tkP7+/170//9c5v//W+v//wDK + //8AzP//AMz//wvQ//9w7P//Zd7//4Tj//8/h///NmX//2OC//+mt///w87+/+fr/f/+/fz//fz7//37 + +v/8+/n//Pr3//77+P/d0Mj/p4Z1//3y3v/14sP/8tiv/+7Om//vyIj/y6Br/4dlV/mPcmcxAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAs/xBEkf9NedX/l2i9/7o4gf/VL2nk/ydy + /f9QsP//Run//1rq//8h1///D9L//1bq//9J5f//M5L//ypw//8xa///O2X//3qU//+tvv7/ytT+/+/x + /f/9/Pz//fz6//37+f/8+vj//Pr3///7+f/e0sr/poJu//voyf/y167/7s2b/+/Ihv/Fmmn/h2RX+ZBz + ZToAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAr/wYAK/8rACr/RwAr + /2oALv+vIEfc/yxv/P+Z/f//U7L//1fo//9s6v//VOr//3PS//9i6f//dO3//yxu//81Z///UHP//5Sp + /v+3xf7/09r9//j5/P/9/Pv//fv6//z7+f/8+vj//Pn3//389//e0sr/pYBp//bcsf/uzpj/78eF/8yg + av+GZlj3k3ZqMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAMP8cADD/OgAw/1QAMv+EJ0HU/0WC/P8yeP//KHf//2P2//9at///dNb//1Wx//8sev//he3//37S + //9BXv//e5T//6q6/v/Ezv3/4ub8//38+//9/Pr//fv5//z6+P/8+vf//Pn2//36+P/e0sv/pH1k//TS + m//wxoP/xppo/4hnW/WVeWooAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAHf8JADD/KwAx/0MAMf9dREy0/0Fl+v81ZP//Q4b//5L///8wd///N4L//12t + //8xZ///M2L//4XZ//+FvP//obD+/7vH/v/T2/3/9fX7//38+v/9+/n//Pv4//z69//8+fb/+/n1//36 + 9v/f08v/o3xe//PLhf+/lGX/h2da9pV8dCEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADn/FAAv/zAANP9GYVWS/3qQ9f9TcP7/W5j//4Xb + //81X///NWX//zlp//89Zv//U3P+/32P/v+p4f//ttD9/83V/f/q7fv//f36//77+f/8/Pj//Pr5//z5 + 9//7+vb/+/j1//779//bzcT/p39b/8ygaP+KaFz1k3hxKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AQAx/xcAMP8wb12C/6mz + 8v+Wpvv/k9D9/3qt/f9eev3/Xn79/2mG/f9+lv3/lqn8/6q5+/+7xPv/zN37/+Tn+f/7+vj/+/n3//z5 + 9v/6+PX/+vj1//r39P/79/P/+fby///69v/DraD/mG9W/4ttX/KMc2shAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAALP8TgGJx/8XH7v+3ue7/ruj3/6Ot8f+irPH/oqzy/6aw8f+ttfH/trzw/8PG7//S0u3/6ePr//vx + 6P/78On/+/Dp//rv6P/67+f/+u/o//ru5v/57eX/+e3l//vv5f+bdWX/jW1g75N+choAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAlm5i/4tqbf+DZXX/iZGb/3lgfv92YID/dmCA/3hhfv98Y3v/gGRz/4ln + av+TbF//l2xY/5ZtWP+Va1n/lWxX/5RqV/+Ta1j/k2lW/5JqV/+RaFX/kWlW/5BpV/+LcGPVf3JlFQAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJ/8GNID/FQAr/xUANP8ZADT/GQAw + /xUAN/8OADb/BQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////AAD///////8AAPwAAAAAPwAA/AAAAAA/ + AAD8AAAAAD8AAPwAAAAAPwAA/AAAAAA/AAD8AAAAAD8AAPwAAAAAPwAA/AAAAAA/AAD8AAAAAD8AAPwA + AAAAPwAA/AAAAAA/AAD8AAAAAD8AAPwAAAAAPwAA/AAAAAA/AAD8AAAAAD8AAPwAAAAAPwAA/AAAAAA/ + AAD8AAAAAD8AAPwAAAAAPwAA/AAAAAA/AAD8AAAAAD8AAPwAAAAAPwAA/AAAAAA/AAD8AAAAAD8AAPwA + AAAAPwAA/AAAAAA/AAD8AAAAAD8AAPgAAAAAPwAA+AAAAAA/AADwAAAAAD8AAPAAAAAAPwAA4AAAAAA/ + AADgAAAAAH8AAOAAAAAA/wAA4AAAAAH/AADgAAAAA/8AAOAAAAAH/wAA8AAAAA//AADwAAAAH/8AAPgA + AAA//wAA/AAAAH//AAD8AAAA//8AAPwAAAH//wAA/AAAA///AAD///////8AAP///////wAA + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/DropFolderForm.Designer.cs b/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/DropFolderForm.Designer.cs new file mode 100644 index 0000000..bfc08a7 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/DropFolderForm.Designer.cs @@ -0,0 +1,110 @@ +namespace AutoFileCryptTool +{ + partial class DropFolderForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(BlackListForm)); + this.label_InputPrompt = new System.Windows.Forms.Label(); + this.textBox_DropFolder = new System.Windows.Forms.TextBox(); + this.button_Apply = new System.Windows.Forms.Button(); + this.openFileDialog1 = new System.Windows.Forms.OpenFileDialog(); + this.folderBrowserDialog1 = new System.Windows.Forms.FolderBrowserDialog(); + this.label1 = new System.Windows.Forms.Label(); + this.SuspendLayout(); + // + // label_InputPrompt + // + this.label_InputPrompt.AutoSize = true; + this.label_InputPrompt.Location = new System.Drawing.Point(20, 8); + this.label_InputPrompt.Name = "label_InputPrompt"; + this.label_InputPrompt.Size = new System.Drawing.Size(154, 13); + this.label_InputPrompt.TabIndex = 0; + this.label_InputPrompt.Text = "Copy the encrypted file to here "; + // + // textBox_DropFolder + // + this.textBox_DropFolder.Location = new System.Drawing.Point(23, 33); + this.textBox_DropFolder.Name = "textBox_DropFolder"; + this.textBox_DropFolder.ScrollBars = System.Windows.Forms.ScrollBars.Horizontal; + this.textBox_DropFolder.Size = new System.Drawing.Size(446, 20); + this.textBox_DropFolder.TabIndex = 1; + this.textBox_DropFolder.Text = "c:\\EaseFilter\\dropFolder"; + // + // button_Apply + // + this.button_Apply.DialogResult = System.Windows.Forms.DialogResult.OK; + this.button_Apply.Location = new System.Drawing.Point(394, 81); + this.button_Apply.Name = "button_Apply"; + this.button_Apply.Size = new System.Drawing.Size(75, 20); + this.button_Apply.TabIndex = 2; + this.button_Apply.Text = "Apply"; + this.button_Apply.UseVisualStyleBackColor = true; + this.button_Apply.Click += new System.EventHandler(this.button_Ok_Click); + // + // openFileDialog1 + // + this.openFileDialog1.FileName = "openFileDialog1"; + // + // label1 + // + this.label1.AutoSize = true; + this.label1.ForeColor = System.Drawing.SystemColors.MenuHighlight; + this.label1.Location = new System.Drawing.Point(20, 63); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(302, 13); + this.label1.TabIndex = 3; + this.label1.Text = "The encrypted files in this folder will be decrypted automatically"; + // + // BlackListForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(514, 113); + this.Controls.Add(this.label1); + this.Controls.Add(this.button_Apply); + this.Controls.Add(this.textBox_DropFolder); + this.Controls.Add(this.label_InputPrompt); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Name = "BlackListForm"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "Setup the drop folder "; + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Label label_InputPrompt; + private System.Windows.Forms.TextBox textBox_DropFolder; + private System.Windows.Forms.Button button_Apply; + private System.Windows.Forms.OpenFileDialog openFileDialog1; + private System.Windows.Forms.FolderBrowserDialog folderBrowserDialog1; + private System.Windows.Forms.Label label1; + } +} \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/DropFolderForm.cs b/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/DropFolderForm.cs new file mode 100644 index 0000000..a049425 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/DropFolderForm.cs @@ -0,0 +1,46 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; + +using EaseFilter.CommonObjects; + +namespace AutoFileCryptTool +{ + public partial class DropFolderForm : Form + { + public string dropFolder = string.Empty; + + public DropFolderForm() + { + InitializeComponent(); + textBox_DropFolder.Text = GlobalConfig.DropFolder; + } + + private void button_Ok_Click(object sender, EventArgs e) + { + dropFolder = textBox_DropFolder.Text; + } + + } +} diff --git a/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/DropFolderForm.resx b/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/DropFolderForm.resx new file mode 100644 index 0000000..c749c4f --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/DropFolderForm.resx @@ -0,0 +1,576 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + + 147, 17 + + + + + AAABAAgAEBAAAAEACABoBQAAhgAAABAQAAABACAAaAQAAO4FAAAYGAAAAQAIAMgGAABWCgAAGBgAAAEA + IACICQAAHhEAACAgAAABAAgAqAgAAKYaAAAgIAAAAQAgAKgQAABOIwAAMDAAAAEACACoDgAA9jMAADAw + AAABACAAqCUAAJ5CAAAoAAAAEAAAACAAAAABAAgAAAAAAEABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP// + /wAAzf8AmXtrAImb/gDdu6kAOljoAGP4/wDH0f0App6/AEme/wD14tkAocD+ANTG0AA87P8AfpjYAE5x + /wCrnpgA4+j/AGaN/wC1r9cAHeX/ALCOfQBfs/8AOoL/AMCoowD69OkAbeL/AE1m4wBbmvEAlpPIANvE + vAC1t8QAptH/AKadqQDx8vsA4c/KAKeCcABX7f8AV2fuAKez/wBdm/8AYOH/APz59ACtvf4Ag5H+APjt + 2gBDe/8A8OjgALKbnwDbv7MAnpfDAFSX/wCph3gA9/j/AEua+ABar/oA+vHiANvHwwCdf28A18zPAJt3 + ZgDcuqMA+vj6APz27gDcvq4Aon9vAP37+ACXeWcA28G3APT1+wBb7f8Aps3/AJx9bADewbQA+fTuAPry + 5gDevqsA3sS6AKuJegDauKUArIh3ANq6qAD39vsAmXtoAPnv4AD79ewA27ytANzCtQD9+vYA/PfwAK+O + fwDcuaUA3LunANu6qgDcv7EA28K5ANvFvgDbxsEA+vHkAN6+rQCafGoAnX5tAKOAcAD79eoA272vAJh5 + aACZemoAm3xrAJx8bQD79OgA+vPoALGOfgDcvKkA2ruqANvAtADbw7oA/fv5AJp8awCbfGwA/PnzAJx9 + bQCcfm0A/PbtAPrz5wD68+YA3LqlANy7qQDbuqkA3cK1ANu/sgDbv7QA28fCANvCuADbw7sAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAGxmenp6eUlsbGVUbAAAAAA9ARoaGm98TGNVLkQAAAAAQgGBgVhfQX9+Pjlq + AAAAAGcBhnSFMmlyUFx9awAAAAA1AYRiH0WCV1JdbgMAAAAATwE6hGFgc2mAcWh2AAAAAFs2DTwkYINp + XgVWbAAAAAAiKC0hCFNDWXhae3cAAAAADzQ4NycUTkpkTUBtAAAAAAYqFUcXDEZDK0swOwAAAAAdJgIO + GAQjdSUlJSUAAAAAHAoHGy8sP3UlC3ARAAAAAB4TKRBIEgEBJXARAAAAAAAZIDMJMRZRUSURAAAAAAAA + AAAAAAAAAAAAAAAAAAD//wAAwAMAAMADAADAAwAAwAMAAMADAADAAwAAwAMAAMADAADAAwAAwAMAAMAD + AADAAwAAwAcAAMAPAAD//wAAKAAAABAAAAAgAAAAAQAgAAAAAABABAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAJt8a/+dfm3/nH5t/5x+bf+cfm3/nH1t/5x9bP+bfGv/m3xr/5p8av+Ze2j/m3xr/wAA + AAAAAAAAAAAAAAAAAACbd2b///////r06f/69On/+vTp//rz6P/68+f/+vLm//rx5P/57+D/+O3a/5d5 + Z/8AAAAAAAAAAAAAAAAAAAAAon9v///////dwrX/3cK1/9zCtf/cv7H/3L6u/9y7qf/cuqX/3Lqj//rx + 4v+YeWj/AAAAAAAAAAAAAAAAAAAAAKOAcP//////28O7/9vDuv/bwrj/27+z/9u9r//au6r/2ril/9y5 + pf/68+b/mXpq/wAAAAAAAAAAAAAAAAAAAACph3j//////9vHwv/bxsH/28S8/9vBt//bv7L/27yt/9q6 + qP/cu6f/+/To/5l7a/8AAAAAAAAAAAAAAAAAAAAAq4l6///////bx8P/28fC/9vFvv/bwrn/28C0/9u9 + r//buqn/3Lyp//v16v+afGv/AAAAAAAAAAAAAAAAAAAAAK+Of//3+P//1MbQ/9fMz//hz8r/28K5/9u/ + tP/bva//27qq/927qf/79ez/m3xr/wAAAAAAAAAAAAAAAAAA/wGmnan/p7P//4OR/v+m0f//x9H9//f2 + +//9+/j//fr2//z58//89/D//Pbt/5t8bP8AAAAAAAAAAAAAAAAAKf8XfpjY/1SX//9ar/r/S5r4/1dn + 7v+1r9f/3sS6/97BtP/evq3/3r6r//z27v+cfG3/AAAAAAAAAAAAAAAAACz/NzpY6P9g4f//HeX//1vt + //9fs///ocD+//T1+//9+/j//Pn0//n07v/w6OD/n4Bw/gAAAAAAAAAAAAAAAAAu/0FbmvH/V+3//wDN + //887P//OoL//4mb/v/x8vv//fv5/6eCcP+ngnD/p4Jw/6eCcP8AAAAAAAAAAAAAAAA3fv8zTWbj/0me + //9j+P//beL//0N7//+tvf7/+vj6//37+f+ngnD/9eLZ/7GOfv+ngnBYAAAAAAAAAAAAAAAAABf/CJaT + yP9mjf//XZv//05x//+mzf//4+j/////////////p4Jw/7GOfv+ngnBYAAAAAAAAAAAAAAAAAAAAAAAA + AADAqKP/tbfE/56Xw/+mnr//spuf/7COff+siHf/rIh3/6eCcP+ngnBYAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAD//wAAwAMAAMADAADAAwAAwAMAAMADAADAAwAAwAMAAMADAADAAwAAwAMAAMADAADAAwAAwAcAAMAP + AAD//wAAKAAAABgAAAAwAAAAAQAIAAAAAACgAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8AKF31AKJ6 + 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 + ///9+/n/3MjD/9zIxP/cx8L/28W//9vEvf/bwbn/28C2/9u/sv/bva//27ur/9u5p//evar/+/bt//zz + 5/+Uc2D/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAApYRz//j5///p7Pv/xLbJ/8S5yf/Pwcb/2sO//9zE + vP/bwrn/28G1/9u+s//bva//27ur/9u5qP/evar//ffu//716P+Wc2L/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAP8BmH2C/8bR//+wv/7/mKDq/6PK8P+qr+f/wsLj/+LY3f/t39n/7N7X/+zd1f/s29L/7NrP/+vZ + zf/t2cz//Pfv//306f+Vc2H/AAAAAAAAAAAAAAAAAAAAAAAAAAAANf8di56x/4GR//9OdP//P17//37M + //9edv//mKz+/8bR/f/z9Pv//vz6//37+P/9+vb//fn0//z48v/8+PH//Pjw//326/+XdGP/AAAAAAAA + AAAAAAAAAAAAAAAx/wsALf8/WG3G/33U//88hv//UaT6/2PY/f8ravb/PV/w/4iO3P+5rc3/3sa+/9/F + uv/fw7b/38Cy/9+/rv/gwa///fjw//326/+WdGP/AAAAAAAAAAAAAAAAAAAAAAAx/x8AMP9dLEbc/0Oc + //9g6v//VOz//0fd/v9gwPv/KF31/2WK6/+lrtP/07u7/9zAtP/bvbD/3Lys/9y5qf/fvqv//fry//31 + 7P+YdWP/AAAAAAAAAAAAAAAAAAAAAAAz/y0AMf94JVXl/2vO//8s2///AMr//wTQ//9X6P//c9///12V + //+ruP//6ez8///9+//6+PX/9vLt//Ps5//s5N//4dbQ/8m1qf+NaFftAAAAAAAAAAAAAAAAAAAAAAAs + /y8AJv97QYDr/1TW//8o3f//AMr//wLP//9u7P//PY///0Ro//+puv//6Oz8/////v/Ktar/nHpp/6qL + eP+ohGr/onpc/4ZgT/OQZ1ZBAAAAAAAAAAAAAAAAAAAAACBb/ytkt/+NUYzp/0SW//909f//Ld///z7j + //9Qxv//LWz//1d4//+2xP7/8PH7/////f/Vx77/zLWj//zpxf/wzJL/m3Rc85ZpXDoAAAAAAAAAAAAA + AAAAAAAAAAAAAAAv/xAALP9GR1HI/0SC//9Mof//Ucr//2PC//9oyf//WJT//4uf/v/L1f3//Pr6///+ + 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 + AA/gAAAfwAAAP+AAAH/wAAD/8AAB//AAA//wAAf/8AAP//////8oAAAAIAAAAEAAAAABACAAAAAAAIAQ + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAhGFQ/4ZhUP+EYE//hGBP/4Rg + T/+EYE//hGBP/4NgT/+DYE//g2BP/4NfTv+CX07/gl9O/4FfTv+BXk3/gF5N/4BdTv9/XUz/f11N/35c + S/9+XEz/fVtL/35dTf97W0v/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACFYVD/+OTT//Le + zP/y3sz/8t7M//LezP/y3sz/8t7M//LezP/y38z/8t3M//Ldy//y3cv/8t7K//Lcyv/y3Mf/89vH//Ha + xP/x2cL/8tjA//DXvv/x1r3/9dm9/3xbS/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIZh + UP///fL/+vTo//rz6f/68+n/+vPp//rz6f/68+n/+vPo//r06P/68uj/+vLn//ry5//68+b/+vHm//ry + 5f/68uT/+fHi//nw4P/5797/+Ozb//nt2f/03MT/e1pJ/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAhmFQ///+9f/79ur/+/Xs//v16//79ev/+/Xr//v17P/79er/+/bq//v06//79On/+/Tq//v1 + 6P/78+n/+/Pn//z05v/68uX/+vHl//nw4f/57+D/+vDe//Texv99W0r/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACHY1H///73//v17P/89uz/3sS3/97Ft//exbf/3sS3/93Dtf/dw7X/3cKz/93B + sv/dwbD/3b+u/92+q//dvar/3byo/926pf/duqX/376p//rx4v/68OH/89/J/3xbSv8AAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAIhiUf////f//Pbt//z27v/bwLT/28C0/9vAtP/bwLT/28Cz/9u/ + sv/bvrH/272u/9q7rP/auqr/2rmo/9q3pf/atqL/2rWg/9q1oP/duqT/+vLl//vz5P/14Mz/fVxL/wAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAiWNS////+v/89+///Pfv/9vCuP/bwrj/28K4/9vC + t//bwrb/28C1/9u/sv/bvrH/272v/9u8rP/auqr/2rmm/9q3pP/atqH/2rah/927pf/78+b/+/Tn//Ti + zv9+W0z/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACKZFP////6//z48P/8+PH/28O7/9vE + u//bxLv/28O7/9vDuf/bwrj/28C2/9u/s//bvrH/272u/9u8rP/auaj/2ril/9q3o//at6P/3bun//vz + 5//89ej/9uPS/4BdS/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAItlU/////v//Pjy//z4 + 8v/bxr7/28a//9vGv//bxL7/28S8/9vDuv/bwbf/28C1/9u+s//bva//27ys/9u7qv/buqj/2rek/9q3 + pP/dvaj/+/To//z06f/15NP/f1xN/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjGdU//// + /v/9+fP//fn0/9vHwv/bx8P/28fD/9vGwv/bxb//28S8/9vDuv/bwbf/27+z/9u+sf/bvK//27ur/9u6 + qP/buKX/27il/929qv/79On//Pbq//Xk0v+AXkz/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACPZlX///////369f/9+vX/28jD/9vIxP/byMT/28jC/9vGwP/bxL3/28O6/9vCuP/bwLX/276y/9u9 + r//bu6z/27qp/9u5p//buaf/3r6q//v16v/89ev/9eTT/4JdTP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAI9nVP///////fr2//379//bx8P/28fE/9vHxP/bx8P/28bA/9vFvv/bxLv/28K4/9vA + tf/bv7P/272v/9u8rP/buqr/27im/9u4pv/evqv/+/Xr//z17P/15NT/gV9O/wAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAkWhV///////9+/j//fv4/9zHwv/bxsP/28bD/9vGwf/bxcD/28S9/9vD + u//bwbn/28C1/9u/sv/bvrD/27yt/9u6qv/buKf/27in/969q//79ez//Pft//Xl1v+DXk3/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACSaVf///////78+f/+/Pr/2sTA/9rEwP/cxsD/3MbA/9zF + v//cxL3/28O6/9vCt//bwLX/276y/9u9r//bvK3/27qq/9u5p//buaf/3r2r//z27f/89u3/9eXV/4Ng + Tf8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJNqVv/4+f//6Ov7/9rh/P+4r8r/uK3K/7/B + zv/Ht8T/1b/A/9zEu//cw7r/28G3/9vAtP/bvrL/272v/9u8rf/bu6r/27mn/9u5p//evar//Pbt//z2 + 7v/15df/hF9P/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8BiGhk/9Ha//++yf3/ssH+/6u7 + /v+qs/7/vvP+/73F/v/O1/3/5+v7//37+//+/Pr//fv5//379//9+vb//fr1//359P/8+PL//Pjx//z3 + 7//89u7//fjv//fm1v+EX07/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACh4/yB7c4r/rbf//4ue + /v9phP//V3H//1l9//+a4///iJX+/6q6/v/Dzv3/4eb8//37+//+/Pn//fv4//379//9+vb//fn0//35 + 8//8+PH//Pfw//z37//99+//9ubY/4VhTv8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANv8RACT/OIms + t/98q///P1f//0WD//8qVPb/Yrj6/1+m+f81TvL/Wm/q/46T3P+rptL/zbzH/9/Hvf/fxbv/38O4/9/B + tP/fwLH/37+s/9+/rP/hwrD//Pfv//338P/25tj/hWBQ/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AwA1 + /ysAMP9QQj63/5z7//9SpP//RZf//1ix+v9j8P7/O4v4/zR69v8wVvP/Wm3n/5SV1f+zqMj/2L+6/9zA + tf/bvrL/272v/9u6qv/buaf/27mn/96+q//89+///ffw//bm1/+GYE//AAAAAAAAAAAAAAAAAAAAAAAA + AAAAQv8PADb/PAAw/2wnPNX/K2f//2b///995///ZfT//0jt//9w1/z/bcn7/ylS9P81SfD/d3vd/6eo + z//Mtr7/3MC1/9u+sv/bva//27qq/9u5p//buaf/3r6r//348f/9+PH/9+fZ/4ZhUP8AAAAAAAAAAAAA + AAAAAAAAAAAAAAA2/xsAM/9HAC7/iiNQ3v9XrP//etT//yjg//8Azv//As///1bw//9bxf//Zdv//6D9 + //+V2P//s8n+/9/l/P/+/Pr///35//79+f///fn///33//779//9+PP/+fXt//Xw6P/p1sj/h2JQ/AAA + AAAAAAAAAAAAAAAAAAAAAAAAADX/IQAy/0wALv+aHz/e/zyP//9h6///AM7//wDL//8Ayv//DdT//0ri + //9Mqv//MVz//1tv//+uvP7/2eD8//78+v///fv/5tzX/9nLwv/g08z/2szF/9XFvv/Itq3/u6Sa/5d1 + Zf+GYlG2AAAAAAAAAAAAAAAAAAAAAAAAAAAAMv8gACb/TAAY/5k9euf/XN7//0jw//8K0v//AMv//wDK + //8Z2P//gf3//0+o//8yY///XXv//66//v/Z4Pz//vz6//////+7opX/oYBy/6eJeP+lg2//o39n/7CI + Zv+TbFT/imRTxIZfSw4AAAAAAAAAAAAAAAAAAAAAAAAAAABD/xllvP9qiun/vHTA7v9Uqf//bMX//0Ps + //8Q1P//FdX//z/q//9Nq///NIf//zRl//9xi///tcP+/+Ln/P/+/Pr//////8u3rf/FrZ////Xg//nh + u//41pz/xZ5u/4ljU8GMXV8MAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC//DAAm/zkAH/9lLTfQ/zBd + //+L7v//c8z//0rl//9/////Xcf//4D///8uZP//Q2P//5Oo/v/Czv3/7/L7//78+v////z/zLqw/76h + i//237j/88+W/8CYav+IYlTPi2RODgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8BADP/JgAw + /0pNUK7/QGv//zBa//9Yvv//VcD//3XP//8pav//WKT//5Tq//92gv//sL7+/9Xd/P/8+vr//vz5///+ + /P/XycH/so1y//bTmv/In27/iWRVzJ1uXhIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAOv8LADf/MmtdkP9/lv//Sl7+/4/o//88dP//M2r//zZn//9HX///hbD//7Xi/v/J0f3/8PD7//78 + +v/9+/j////7/9PCuf+3kGr/y6Fv/4tkVM2VYlIRAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAOv8QfWR7/7bE//+bpP3/q/b+/2x5/v9shf7/fZX+/5ms/v+yvf3/ydn9/+rt + +//+/Pr//fv5//379////vv/zrqx/6J5Wv+PaVbWnXFZGQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACVb2T/2uL//8jQ///B7f//tb7//7XD//+7yP//xtL//9jf + ///y9P////////////////////////////+zl4n/j2dV1KFtYhcAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJpxXf+ccmD/lHBm/5B0cf+IanD/h2px/4pr + a/+QbWT/l25b/5dtW/+Wbln/lWxa/5RrWf+Talj/k2xZ/45nVbmTblUWAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/////wAAAP8AAAD/AAAA/wAAAP8AAAD/AA + AA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/gAAAP4AAAD+AA + AA/gAAAP4AAAH8AAAD/gAAB/8AAA//AAAf/wAAP/8AAH//AAD///////KAAAADAAAABgAAAAAQAIAAAA + AACACgAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8AMFz/ALCIZgBm7/8AqKXUAADL/wD41pwAZlyPAHaC + /wCt3/0AellJAEI+twDn3tgAvaSZAFCv/gBzg8kAVm7WAHq46ACbpP0AIETcADHe/wDbwbYAg2V1AIms + twAsg/8AltnhAN/l/ADNomwAt7vvAJX6/wBScv4Av8HOAPnhuwCNktwA/fLeAGHH/QCTbFQARun/AID+ + /wAvaeQAeq39AImRmwBw1f8AydP+AI7E3QBnec8A2rWfAISV+ACa4/8AR1//ADVJ8ABETLQARlTeALKW + igBwf+QAyretABPS/wCWem0ALTfQAFZ76wB76f8ApX5dAPDy/QA3d/8AX6b5AFKV9QCoinsA+OTTAF3i + /wC+8/4A3c7GALmwzwAfV+EAKnH+AESG+wDMtr4AZMP7AHpgeQD79/IA6dXFAKv2/gCE8P8Ap7P3AGW4 + /wBm//8AhmFPACdT7gDDmGcAxKWJAJBtZAClf2cAxK6gAN++qQDqz7sAwcn4AGx5/gAyev0ANmb+APbw + 5wCyjXIAVun/ANPb/QD14sMASeX/AFuw/QBYgP4Ak87+AEBf4QCacV0A1MHDAGeD/gAL0f8A8+reAD9X + /wAzkv8AoYByALTQ/gB8k/wAz8DJAIHX/QDmzLoA8MqNAN/QygBylP8Ahbz/AOjo9wC4j2UAccz7AEBo + /wBm2f8Ah6D/AIhoXQCbdWUAWJ3/AJaX1wCQdHEAJ0HUAPn5/QCU6v8Alaj8ALOoyACLZVQA+vHrAP78 + +ADmyLIAzbqxADRc8gA7i/gAq7r8AMva/QDTwrkAyLjGACxl+gBVwP8AgV1MANu5pwDbva4A9+3jAKCv + +QBZr/8AkXNnAMGceADL6v4A+ufJAMTN+wDZ4f4A28W/AP37+QBI7/8AaXXNAJZtWQBSpP8A4Ma3ALXE + /gDx2cIApYNxANLa/gDcyr8A8ufbAO7ezwBtyfsAQWL9AIppbABd6f8ABM//ADlV7AD19fsAlm5iAI/o + /wDVxb4AuJ+TAKCd0wD58+0A28O7ABDS/wDcyMMA2L+6AK+//wD//vsAH9j/APXZvQD02rAA0NT1AJFo + VQCUc2UAafP/AN/EtACtt/8A/Pn1AD3j/wBbb/8Aof//AFx7/gCEX00A9ezfADFp/wCPeW4A27urAFSp + /wC7xPsANWD/APrw6ADz050A3rylAODArgB/W0sAiWNSAJxyYADa4fwAxdD/ALvH/gAoZvsAjXBjAOru + /QDj5vkAWm3nAE+o/wDbuKQAW7r/ANu/sgB30P8AssH+AJNqVwD89uwASl7+APDk1gDz38oA89zHANng + /wBqh/8A//3yAMifbgDv4tMA37+sAN28qAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + 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 + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAhWFQ/4RhUf+DYE//g19P/4Nf + T/+DX0//g19P/4NfT/+CX0//gl9P/4JfT/+CYE//gl5O/4JeTv+CXk7/gV5O/4FeTv+BXk7/gV9O/4Bd + Tf+AXU3/gF1N/39eTf9/XE3/f1xM/35cTP9+XUz/fltM/31bS/99XEv/fFpK/3xbSv97W0r/e1tL/3tb + S/97W0z/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgFxL/+7R + u//rzrn/6s25/+rNuf/qzbn/6s25/+rNuv/qzbr/6s26/+rNuf/qzbn/6s25/+rNuf/qzrn/6865/+nO + uP/pzbj/6c24/+nNt//qzbf/6s23/+rMt//qzLb/6cy2/+nLtf/py7T/6cu0/+nLs//oy7P/6Mqz/+jK + sv/oyrH/58mx/+vLsv92Vkj/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAf1xL/+rUwv/m0L//5tC//+bQv//n0L//59C//+fQwP/n0MD/59DA/+fQv//m0L//5tC//+bQ + v//m0L//5tC//+bQvv/mz77/5s++/+bPvf/mz73/5c+9/+XPvP/lzrz/5c67/+XOu//lzbr/5M26/+TN + uf/kzLn/5My4/+TMt//ky7f/5My3/+XIsP93VUb/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAgFpJ//Dez//s2sv/7NrM/+zazP/s28z/7NvM/+zbzP/s28z/7NvM/+zb + zP/s2sz/7NrM/+zay//s2sv/69rL/+vay//r2sr/69nK/+vZyv/r2cn/69nJ/+vYyP/q2Mj/6tjH/+rX + x//q18b/6tfG/+nWxf/p1sT/6dbE/+nVw//o1sP/5tC8/+bJsf92V0f/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgVxK//Tl2P/z6d3/8uje//Lo3v/y6N7/8ujd//Lo + 3f/y6N3/8ujd//Lo3f/y6N7/8uje//Lo3v/y6Nz/8ujd//Lp3f/y59z/8ufc//Pn3P/x6Nv/8ebb//Hm + 2v/x59r/8uXZ//Dl2P/w5tj/8OTX//Hl1f/v49b/7+PV//Dk1P/t3s3/59C8/+XIsf94Vkf/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgltK//Xn2v/38Oj/9u/n//bx + 5v/28ej/38e4/9/Huf/fx7n/38e4/9/HuP/fxrj/38a4/9/Gt//fxbf/38S1/9/EtP/fxLP/38O0/9/D + sf/fw7H/38Gu/9/Arv/fwK3/38Cr/96+q//ev6n/3r2m/967pf/hxKv/8+re//Tr3v/t4ND/5tC9/+XK + s/95WEf/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAglxL//Tm + 2v/38ej/9/Do//fw6P/38Oj/2r6x/9q+sf/avrH/2r6x/9q+sP/avrD/2r6w/9q9r//ava7/2r2t/9q8 + rf/avKz/2rqr/9q6qf/auaj/2rmm/9q4pP/at6P/2rei/9q2oP/atp//2bSd/9mzm//evKX/9Ove//Pr + 3v/t39D/5tG+/+fJsv95V0j/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAg15L//Tn2//48un/9/Hp//fx6f/38en/28Cz/9vAs//bwLP/28Cz/9vAs//bwLL/27+y/9u/ + sf/avrD/2r2v/9q9rv/avK3/2ryr/9q7q//auqr/2rmn/9q4pv/auKT/2rej/9q3ov/atqD/2rWe/9m0 + nf/evab/9Ovf//Xs3//v4dL/5tG//+bLs/96V0j/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAhF1K//bo3P/48uz/+PLq//jy6v/48ur/28G1/9vBtv/bwbb/28G1/9vB + tf/bwLX/28C0/9vAs//bv7P/27+x/9u+sP/bvq//2ryt/9q7q//au6r/2rqp/9q5qP/auKb/2rek/9q3 + ov/atqL/2raf/9q1nf/fvqj/9Ozg//Ts4P/u4NH/59LA/+bKtP96WUj/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAhV9M//Xq3//48+z/+PPr//jz7P/48+z/28K3/9vC + uP/bw7j/28K4/9vCt//bwrb/28K1/9vAtP/bwLT/27+z/9u/sf/bvrD/272u/9u9rf/au6z/2ruq/9q6 + qf/auaf/2rim/9q3pP/atqL/2rah/9q1n//fvqn/9ezh//Tt4f/u4tL/59LA/+bMtv97WEn/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAh15L//fp3//59O3/+PPt//nz + 7f/59O3/28O6/9vDuv/bw7r/28O6/9vDuf/bw7j/28K3/9vCt//bwLb/28C0/9u/sv/bvrH/276w/9u9 + r//bvK3/27yr/9q6qv/auqj/2rmm/9q4pf/at6P/2rah/9q1oP/fvqn/9e3i//bt4v/w4dP/59PB/+jL + tf97Wkj/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAhmBN//bq + 4P/59e7/+fTu//n07v/59O7/28S7/9vEvP/bxLz/28S8/9vEu//bw7r/28O6/9vCuf/bwrf/28C2/9u/ + tP/bv7P/276x/9u9r//bva7/27yt/9u8q//bu6n/2rmn/9q5pv/auKT/2rai/9q2oP/fv6r/9e3j//Xu + 4//v49X/6NPC/+fLtv98WUj/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAhmBN//br4f/69fH/+fXv//n17//59fD/28S+/9vFvv/bxb7/28W+/9vEvf/bxLz/28O7/9vD + uf/bwrj/28G3/9vBtv/bv7T/276y/9u+sf/bva7/27yt/9u8rP/bu6v/27qo/9q5p//auKX/2rej/9q2 + ov/fv6v/9e7k//Xu5P/v4tT/6NPC/+fLuP98WUj/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAh19M//fs4v/69vH/+vbw//r28f/69vH/28bA/9vGwP/bxsH/28bA/9vG + v//bxb7/28W8/9vDu//bwrr/28K4/9vBtv/bwLX/28Cz/9u+sv/bvbD/272u/9u8rP/bu6v/27up/9u6 + p//auKb/2rik/9q3ov/fv6z/9u7k//Xv5f/v5NX/6NTD/+fNt/98WUr/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAiGFO//fs4//69/L/+vby//r28v/69/L/28bC/9vH + w//bx8P/28fC/9vGwf/bxsD/28W+/9vEvf/bxLv/28O6/9vBt//bwLb/28C0/9u/sv/bvrH/272v/9u8 + rf/bu6v/27uq/9u6qP/buaf/2rik/9q3o//fwKz/9u/l//fv5f/x49b/6NTE/+fMuf99W0n/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAiWBN//jt5P/7+PP//Pfz//v3 + 8//79/P/28jC/9vIxP/bycT/28jD/9vIwv/bx8H/28a+/9vFvf/bxLv/28O6/9vCuf/bwrf/28G1/9u/ + s//bvrH/276w/9u8rv/bu6z/27ur/9u6qP/buaf/27ml/9q3o//fwKz/9u/m//bw5v/w49j/6dTE/+fO + uv99Wkn/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAi2FP//ju + 5f/7+PT/+/j0//v49P/7+PX/28jD/9vIxP/bycX/28jE/9vHw//bx8H/28a//9vFvv/bxbz/28S6/9vC + uf/bwrf/28G2/9vAtP/bvrL/276w/9u9rv/bvK3/27ur/9u6qf/buaj/27ml/9u4o//fwK3/9/Dn//bw + 5//w5df/6dXF/+jNuf9+Wkn/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAimNO//ju6P/8+ff/+/n1//v59v/8+fb/28fE/9vIxP/byMX/28jE/9vHw//bxsL/28bA/9vF + vv/bxb3/28S7/9vCuf/bwbj/28G2/9vAtP/bv7P/276w/9u9r//bvK3/27ys/9u6qf/buaj/27mm/9u4 + pP/gwK3/9/Do//bx6P/w5Nj/6dXG/+jNuf9+Wkv/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAi2JQ//nv6P/8+vf//Pn2//z69//8+vf/28fC/9vHw//bx8P/28fD/9vH + wv/bxsH/28bA/9vFvv/bxL3/28S7/9vCuv/bwbj/28C2/9vAtP/bv7P/27+x/9u+r//bvK7/27ur/9u7 + qv/buaj/27im/9u4pf/gwK7/9/Ho//jx6P/y5Nr/6dXG/+jPu/9/XEr/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjGRP//nw6f/8+/j//Pr4//z6+P/8+/j/3MfC/9zH + w//cyMP/3MfD/9zHwv/cx8H/3MbA/9vEvv/bxL3/28O7/9vDuv/bwbj/28C3/9vAtf/bv7L/276x/9u+ + sP/bva3/27us/9u7q//buaj/27im/9u4pf/gwK//9/Hp//fx6f/x5Nn/6dbH/+jOuv9/W0r/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjmNR//nx6v/9+/n//vv5//37 + +f/9+/r/3MbB/9zHwf/cx8H/3MfB/9zGwf/cxsD/3Ma//9zFvv/cxb3/28O7/9vCuv/bwrj/28G2/9u/ + tf/bv7P/276x/9u9r//bva7/27ys/9u7qv/buqn/27in/9u4pP/gwa7/9/Hq//fy6f/x5tv/6tbH/+jO + vP+AW0r/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAj2RQ//rx + 6//9/Pr//fz6//38+//9/Pv/3MfB/9zHwf/cx8H/3MfB/9zHwP/cxsD/3Ma//9zFvf/cxLz/3MO7/9zD + uv/bwbj/28G2/9vAtP/bvrP/276x/9u9r//bva7/27ys/9u6qv/buqn/27mm/9u3pP/gwa7/+PLq//fy + 6v/x5dr/6tbI/+jOu/+AXUz/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAj2ZQ//ry7P/+/fv//fz7//79/P/+/fz/3MbA/9zGwf/cxsH/3MbB/9zGwP/cxsD/3MS//9zE + vf/cxLz/3MO6/9zCuf/cwrj/28C2/9vAtP/bv7P/276y/9u9r//bvK7/27ys/9u7q//buaj/27mn/9u3 + pP/gwa7/+PLr//fy6//x5dz/6tbI/+nQvf+AXEv/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAkGVS//vy7f/6+f7/8vP8/+zu/f/p7f3/yrnE/8y7xP/RwcP/2cPA/9zF + v//cxb7/3MS+/9zDvf/cw7v/3MO6/9zCuP/cwrf/3MG2/9u/tP/bv7L/276x/9u9sP/bvK3/27us/9u7 + qv/buqj/27mm/9u4pP/gwa7/+PLr//nz6//x59v/6tfJ/+nPvP+BXEv/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjmZV/+Th8P/Z4f7/0Nn9/8rU/v/I0v7/yNL+/8jT + /v/L6v7/2eD+/+fr/v/4+f7//v79//7+/f/+/fz//v38//79+//+/Pr//vz6//78+f/9+/j//fv3//36 + 9v/9+vX//fr0//359P/9+fP//Pjy//z48f/89/D/+PPs//jz6//y5t3/6tfJ/+nPvP+BXEv/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMv8QfF5s/8fK8v++y///s8P+/629 + //+qu///qrn//63Z//+x0P//vsr//8rU///Z4P//7vH+//7+/v/+/v3//v38//79/P/+/fv//vz6//78 + +f/+/Pj//fv4//379//9+vb//fr1//359P/9+fP//fny//z48f/8+PD/+PPs//jz7P/y5tz/6tfJ/+nP + vv+BXkv/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADZ//xwSSf8ybll9/624 + 9P+esf//iJ///3WQ//9qh///aoD//5zy//+FoP//nrD//7DA///AzP//0tv//+rv/v/+/v7//v79//79 + /P/+/fz//v37//78+v/+/Pn//fv4//379//9+vb//fr1//369P/9+fP//fny//z48v/8+PH/+PPs//jz + 7P/y5tz/6tfJ/+nPvf+CXUv/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC3/EgAo + /y6C4f+MY2GZ/4SV+P9bev//Qmn//zhm//83Y///NGT2/6P+/v86VPP/UWvv/3eG5v+UmuD/p6fb/7mz + 1v/SxM7/4c7J/+HNyP/hzcb/4cvD/+HKwf/hysD/4cm+/+DHvP/gx7r/4MW4/+DEtv/gxLT/4MKy/+DC + r//kyrj/+PPt//j07P/y5tz/6tfJ/+nPvf+CXU3/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAIf8IADP/KQAy/0EKQP9ilujn/1WF/P82YP//Mmb//2W4//8uZ///X7D6/3bm/f8rWfX/L1n0/z5d + 8P9peuT/kJTZ/6Wi0/+6sMz/1sHC/9zFvf/cxLz/3MK6/9zBuP/cwLX/3MC0/9u+sf/bvbD/27ut/9u7 + qv/buqn/27mm/9u3pP/gwa7/+fPt//j07f/z6N7/6tfK/+nPvv+CXUz/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAMv8bADL/OAAx/1IALf9+PGPZ/57///9Vov//K2n//5T2//8xif//YeP+/2DQ + /P8lYvb/OX32/y5f9P88XPD/cH7i/5aX1/+sps//xrfH/9zFvv/cxLz/3MK6/9zBuP/cwLX/3MC0/9u+ + sf/bvbD/27ut/9u7qv/buqn/27mm/9y4pP/gwa7/+PTu//n07f/y5tz/6NXH/+TJuP+CXUz/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAs/wYAMf8qADT/RgAx/2cAMf+rH0Db/16u/f9e9///YcL//2Hg + //9/7P//NeD//2PJ/P9kw/v/ccz7/yli9f8uWfP/SWHs/4SI3P+gndP/ua3L/9jCv//cxLz/3MK6/9zB + t//cwLX/3MC0/9u+sf/bvbD/27yt/9u7qv/cu6n/27mn/9u4pf/gwK7/+fXu//bw6f/z7OT/6dnO/9/E + tP+GYlD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAw/xAAM/8zADT/UAAz/4IANv/CHUze/ylq + /P9s1///H9n//2nu//8t2///ENL//3Lz//9m8P//IoH//ypx//83d///VZD//5LM//+w2///ytf//+/y + /v/+/v3//v38//38+//9+/n//Pr4//37+P///vr////8///9+v/9/Pf/+fXy//Xw6v/x6eT/7OXe/+jf + 2f/l3Nb/3Mq//7GPf/+EY1X0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAq/xgAMP86ADH/WAAy + /5kAOf/JT5nq/3DS/v9n0///Ze///wDK//8AzP//AMz//wvR//+C8v//XOD//2r1//+e////es3//2+Y + //+ntf//xdD//+fr/v/+/v3//v38//38+//9+/n//Pr4//37+f/azcX/wKqf/76mm/+8o5j/uKCU/7ee + kv+zm5D/spiP/6iNgP+Uc2X/h2JR/4hjUvyKbF1PAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAt + /xwAM/89ADH/XQAz/6UAP//KG1Ph/1Ct/f9Y5///BM///wDM//8AzP//AMz//wDM//8c1///W+T//1u8 + //8tdP//NWD//1p5//+itP//ws7//+Po/v/+/f3//v38//38+v/9+/n//Pr4///++//DrqP/pINz/8y7 + sv/Is6X/xq2a/8Wojv/DooP/wZx4/8qicv+4j2X/iWRW+5RzYkUAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAt/xwAM/89ADH/XQAu/6UANv/KJGXl/2DB/v9W5P//E9L//wDM//8AzP//AMz//wDL + //894///Z9P//ySB//8tcf//NWj//1p7//+itP//ws7//+Po/v/+/f3//fz7//38+v/9+/n//Pr4///8 + +v/NubD/vKSY////+v/78N7/+ObJ//Xcs//y05//88yL/9Opb/+HZVf5j3NjOgAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAp/xgAKv87ACr/Wjd8/7N72v/tkP7+/170//9c5v//W+v//wDK + //8AzP//AMz//wvQ//9w7P//Zd7//4Tj//8/h///NmX//2OC//+mt///w87+/+fr/f/+/fz//fz7//37 + +v/8+/n//Pr3//77+P/d0Mj/p4Z1//3y3v/14sP/8tiv/+7Om//vyIj/y6Br/4dlV/mPcmcxAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAs/xBEkf9NedX/l2i9/7o4gf/VL2nk/ydy + /f9QsP//Run//1rq//8h1///D9L//1bq//9J5f//M5L//ypw//8xa///O2X//3qU//+tvv7/ytT+/+/x + /f/9/Pz//fz6//37+f/8+vj//Pr3///7+f/e0sr/poJu//voyf/y167/7s2b/+/Ihv/Fmmn/h2RX+ZBz + ZToAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAr/wYAK/8rACr/RwAr + /2oALv+vIEfc/yxv/P+Z/f//U7L//1fo//9s6v//VOr//3PS//9i6f//dO3//yxu//81Z///UHP//5Sp + /v+3xf7/09r9//j5/P/9/Pv//fv6//z7+f/8+vj//Pn3//389//e0sr/pYBp//bcsf/uzpj/78eF/8yg + av+GZlj3k3ZqMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAMP8cADD/OgAw/1QAMv+EJ0HU/0WC/P8yeP//KHf//2P2//9at///dNb//1Wx//8sev//he3//37S + //9BXv//e5T//6q6/v/Ezv3/4ub8//38+//9/Pr//fv5//z6+P/8+vf//Pn2//36+P/e0sv/pH1k//TS + m//wxoP/xppo/4hnW/WVeWooAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAHf8JADD/KwAx/0MAMf9dREy0/0Fl+v81ZP//Q4b//5L///8wd///N4L//12t + //8xZ///M2L//4XZ//+FvP//obD+/7vH/v/T2/3/9fX7//38+v/9+/n//Pv4//z69//8+fb/+/n1//36 + 9v/f08v/o3xe//PLhf+/lGX/h2da9pV8dCEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADn/FAAv/zAANP9GYVWS/3qQ9f9TcP7/W5j//4Xb + //81X///NWX//zlp//89Zv//U3P+/32P/v+p4f//ttD9/83V/f/q7fv//f36//77+f/8/Pj//Pr5//z5 + 9//7+vb/+/j1//779//bzcT/p39b/8ygaP+KaFz1k3hxKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AQAx/xcAMP8wb12C/6mz + 8v+Wpvv/k9D9/3qt/f9eev3/Xn79/2mG/f9+lv3/lqn8/6q5+/+7xPv/zN37/+Tn+f/7+vj/+/n3//z5 + 9v/6+PX/+vj1//r39P/79/P/+fby///69v/DraD/mG9W/4ttX/KMc2shAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAALP8TgGJx/8XH7v+3ue7/ruj3/6Ot8f+irPH/oqzy/6aw8f+ttfH/trzw/8PG7//S0u3/6ePr//vx + 6P/78On/+/Dp//rv6P/67+f/+u/o//ru5v/57eX/+e3l//vv5f+bdWX/jW1g75N+choAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAlm5i/4tqbf+DZXX/iZGb/3lgfv92YID/dmCA/3hhfv98Y3v/gGRz/4ln + av+TbF//l2xY/5ZtWP+Va1n/lWxX/5RqV/+Ta1j/k2lW/5JqV/+RaFX/kWlW/5BpV/+LcGPVf3JlFQAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJ/8GNID/FQAr/xUANP8ZADT/GQAw + /xUAN/8OADb/BQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////AAD///////8AAPwAAAAAPwAA/AAAAAA/ + AAD8AAAAAD8AAPwAAAAAPwAA/AAAAAA/AAD8AAAAAD8AAPwAAAAAPwAA/AAAAAA/AAD8AAAAAD8AAPwA + AAAAPwAA/AAAAAA/AAD8AAAAAD8AAPwAAAAAPwAA/AAAAAA/AAD8AAAAAD8AAPwAAAAAPwAA/AAAAAA/ + AAD8AAAAAD8AAPwAAAAAPwAA/AAAAAA/AAD8AAAAAD8AAPwAAAAAPwAA/AAAAAA/AAD8AAAAAD8AAPwA + AAAAPwAA/AAAAAA/AAD8AAAAAD8AAPgAAAAAPwAA+AAAAAA/AADwAAAAAD8AAPAAAAAAPwAA4AAAAAA/ + AADgAAAAAH8AAOAAAAAA/wAA4AAAAAH/AADgAAAAA/8AAOAAAAAH/wAA8AAAAA//AADwAAAAH/8AAPgA + AAA//wAA/AAAAH//AAD8AAAA//8AAPwAAAH//wAA/AAAA///AAD///////8AAP///////wAA + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/FilterDriverService.cs b/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/FilterDriverService.cs new file mode 100644 index 0000000..77a732a --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/FilterDriverService.cs @@ -0,0 +1,95 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Runtime.InteropServices; + +using EaseFilter.FilterControl; +using EaseFilter.CommonObjects; + +namespace AutoFileCryptTool +{ + public class FilterDriverService + { + + static FilterControl filterControl = new FilterControl(); + + public static bool SendConfigSettingsToFilter(ref string lastError) + { + filterControl.ClearFilters(); + foreach (FileFilterRule filterRule in GlobalConfig.FilterRules.Values) + { + FileFilter fileFilter = filterRule.ToFileFilter(); + filterControl.AddFilter(fileFilter); + } + + if (!filterControl.SendConfigSettingsToFilter(ref lastError)) + { + return false; + } + + return true; + } + + public static bool StartFilterService(out string lastError) + { + //Purchase a license key with the link: http://www.easefilter.com/Order.htm + //Email us to request a trial key: info@easefilter.com //free email is not accepted. + string licenseKey = GlobalConfig.licenseKey; + GlobalConfig.filterType = FilterAPI.FilterType.ENCRYPTION_FILTER; + + bool ret = false; + + lastError = string.Empty; + + try + { + ret = filterControl.StartFilter(GlobalConfig.filterType, GlobalConfig.FilterConnectionThreads, GlobalConfig.ConnectionTimeOut, licenseKey, ref lastError); + if (!ret) + { + return ret; + } + + ret = SendConfigSettingsToFilter(ref lastError); + + EventManager.WriteMessage(102, "StartFilter", EventLevel.Information, "Start filter service succeeded."); + } + catch (Exception ex) + { + EventManager.WriteMessage(104, "StartFilter", EventLevel.Error, "Start filter service failed with error " + ex.Message); + ret = false; + } + + return ret; + } + + public static bool StopService() + { + GlobalConfig.Stop(); + filterControl.StopFilter(); + + EventManager.WriteMessage(102, "StopFilter", EventLevel.Information, "Stopped filter service succeeded."); + + return true; + } + + } +} diff --git a/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/FormFileCrypt.Designer.cs b/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/FormFileCrypt.Designer.cs new file mode 100644 index 0000000..66c191f --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/FormFileCrypt.Designer.cs @@ -0,0 +1,755 @@ +namespace AutoFileCryptTool +{ + partial class Form_FileCrypt + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + private void AddDefaultItemsToAutoFolderList() + { + System.Windows.Forms.ListViewItem listViewItem1 = new System.Windows.Forms.ListViewItem(""); + System.Windows.Forms.ListViewItem listViewItem2 = new System.Windows.Forms.ListViewItem(new string[] { + "Add auto encryption folder here"}, -1, System.Drawing.Color.RoyalBlue, System.Drawing.Color.Empty, new System.Drawing.Font("Arial Rounded MT Bold", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)))); + System.Windows.Forms.ListViewItem listViewItem3 = new System.Windows.Forms.ListViewItem(new string[] { + "The new created files in the folder will be encrypted automatically"}, -1, System.Drawing.Color.Orange, System.Drawing.Color.Empty, new System.Drawing.Font("Arial Rounded MT Bold", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)))); + System.Windows.Forms.ListViewItem listViewItem4 = new System.Windows.Forms.ListViewItem(new string[] { + "The files will be encrypted with 256 bit key and unique IV"}, -1, System.Drawing.Color.Orange, System.Drawing.Color.Empty, new System.Drawing.Font("Arial Rounded MT Bold", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)))); + System.Windows.Forms.ListViewItem listViewItem5 = new System.Windows.Forms.ListViewItem(new string[] { + "If the process wants to get the raw data of the encrypted file"}, -1, System.Drawing.Color.Orange, System.Drawing.Color.Empty, new System.Drawing.Font("Arial Rounded MT Bold", 9F)); + System.Windows.Forms.ListViewItem listViewItem6 = new System.Windows.Forms.ListViewItem(new string[] { + "Then add the process to the black list"}, -1, System.Drawing.Color.Orange, System.Drawing.Color.Empty, new System.Drawing.Font("Arial Rounded MT Bold", 9F)); + + this.listView_AutoEncryptFolders.Items.AddRange(new System.Windows.Forms.ListViewItem[] { + listViewItem1, + listViewItem2, + listViewItem3, + listViewItem4, + listViewItem5, + listViewItem6}); + } + + private void AddDefaultItemsToEncryptOnReadList() + { + System.Windows.Forms.ListViewItem listViewItem7 = new System.Windows.Forms.ListViewItem(""); + System.Windows.Forms.ListViewItem listViewItem8 = new System.Windows.Forms.ListViewItem(new string[] { + "Encrypt Files On The Go"}, -1, System.Drawing.Color.DodgerBlue, System.Drawing.Color.Empty, new System.Drawing.Font("Arial Rounded MT Bold", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)))); + System.Windows.Forms.ListViewItem listViewItem9 = new System.Windows.Forms.ListViewItem(new string[] { + "The file is not encrypted in the local disk"}, -1, System.Drawing.Color.Orange, System.Drawing.Color.Empty, new System.Drawing.Font("Arial Rounded MT Bold", 9F)); + System.Windows.Forms.ListViewItem listViewItem10 = new System.Windows.Forms.ListViewItem(new string[] { + "The file will be encrypted automatically when it was read"}, -1, System.Drawing.Color.Orange, System.Drawing.Color.Empty, new System.Drawing.Font("Arial Rounded MT Bold", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)))); + System.Windows.Forms.ListViewItem listViewItem11 = new System.Windows.Forms.ListViewItem(new string[] { + ""}, -1, System.Drawing.Color.Orange, System.Drawing.Color.Empty, new System.Drawing.Font("Arial Rounded MT Bold", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)))); + System.Windows.Forms.ListViewItem listViewItem12 = new System.Windows.Forms.ListViewItem(new string[] { + "To decrypt file, go to decrypt file manually and check Decrypt File On The Go"}, -1, System.Drawing.Color.Orange, System.Drawing.Color.Empty, new System.Drawing.Font("Arial Rounded MT Bold", 9F)); + this.listView_EncryptOnReadFolders.Items.AddRange(new System.Windows.Forms.ListViewItem[] { + listViewItem7, + listViewItem8, + listViewItem9, + listViewItem10, + listViewItem11, + listViewItem12}); + } + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form_FileCrypt)); + this.imageList1 = new System.Windows.Forms.ImageList(this.components); + this.tabPage_EncryptFile = new System.Windows.Forms.TabPage(); + this.groupBox2 = new System.Windows.Forms.GroupBox(); + this.label12 = new System.Windows.Forms.Label(); + this.textBox_PassPhraseEncrypt = new System.Windows.Forms.TextBox(); + this.label3 = new System.Windows.Forms.Label(); + this.textBox_EncryptTargetName = new System.Windows.Forms.TextBox(); + this.label5 = new System.Windows.Forms.Label(); + this.textBox_EncryptSourceName = new System.Windows.Forms.TextBox(); + this.label6 = new System.Windows.Forms.Label(); + this.button_BrowseEncryptFile = new System.Windows.Forms.Button(); + this.button_StartToEncrypt = new System.Windows.Forms.Button(); + this.tabPage_Folder = new System.Windows.Forms.TabPage(); + this.splitContainer1 = new System.Windows.Forms.SplitContainer(); + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.button_Help = new System.Windows.Forms.Button(); + this.button_Stop = new System.Windows.Forms.Button(); + this.button_Start = new System.Windows.Forms.Button(); + this.button_RemoveFolder = new System.Windows.Forms.Button(); + this.button_AddFolder = new System.Windows.Forms.Button(); + this.listView_AutoEncryptFolders = new System.Windows.Forms.ListView(); + this.tabControl1 = new System.Windows.Forms.TabControl(); + this.tabPage_EncryptOnRead = new System.Windows.Forms.TabPage(); + this.splitContainer2 = new System.Windows.Forms.SplitContainer(); + this.groupBox4 = new System.Windows.Forms.GroupBox(); + this.button_StopService = new System.Windows.Forms.Button(); + this.button_StartService = new System.Windows.Forms.Button(); + this.button_RemoveProtectFolder = new System.Windows.Forms.Button(); + this.button_AddProtectFolder = new System.Windows.Forms.Button(); + this.listView_EncryptOnReadFolders = new System.Windows.Forms.ListView(); + this.tabPage_DecryptFile = new System.Windows.Forms.TabPage(); + this.groupBox3 = new System.Windows.Forms.GroupBox(); + this.label17 = new System.Windows.Forms.Label(); + this.textBox_PassPhraseDecrypt = new System.Windows.Forms.TextBox(); + this.label14 = new System.Windows.Forms.Label(); + this.textBox_DecryptTargetName = new System.Windows.Forms.TextBox(); + this.label15 = new System.Windows.Forms.Label(); + this.textBox_DecryptSourceName = new System.Windows.Forms.TextBox(); + this.label16 = new System.Windows.Forms.Label(); + this.button_BrowseFileToDecrypt = new System.Windows.Forms.Button(); + this.button_StartToDecrypt = new System.Windows.Forms.Button(); + this.label13 = new System.Windows.Forms.Label(); + this.textBox1 = new System.Windows.Forms.TextBox(); + this.label7 = new System.Windows.Forms.Label(); + this.textBox2 = new System.Windows.Forms.TextBox(); + this.label8 = new System.Windows.Forms.Label(); + this.label11 = new System.Windows.Forms.Label(); + this.label2 = new System.Windows.Forms.Label(); + this.label1 = new System.Windows.Forms.Label(); + this.label4 = new System.Windows.Forms.Label(); + this.checkBox_DecryptFileOnTheGo = new System.Windows.Forms.CheckBox(); + this.tabPage_EncryptFile.SuspendLayout(); + this.groupBox2.SuspendLayout(); + this.tabPage_Folder.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit(); + this.splitContainer1.Panel1.SuspendLayout(); + this.splitContainer1.Panel2.SuspendLayout(); + this.splitContainer1.SuspendLayout(); + this.groupBox1.SuspendLayout(); + this.tabControl1.SuspendLayout(); + this.tabPage_EncryptOnRead.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.splitContainer2)).BeginInit(); + this.splitContainer2.Panel1.SuspendLayout(); + this.splitContainer2.Panel2.SuspendLayout(); + this.splitContainer2.SuspendLayout(); + this.groupBox4.SuspendLayout(); + this.tabPage_DecryptFile.SuspendLayout(); + this.groupBox3.SuspendLayout(); + this.SuspendLayout(); + // + // imageList1 + // + this.imageList1.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imageList1.ImageStream"))); + this.imageList1.TransparentColor = System.Drawing.Color.Transparent; + this.imageList1.Images.SetKeyName(0, "folder_ok.png"); + // + // tabPage_EncryptFile + // + this.tabPage_EncryptFile.Controls.Add(this.groupBox2); + this.tabPage_EncryptFile.Controls.Add(this.button_StartToEncrypt); + this.tabPage_EncryptFile.Location = new System.Drawing.Point(4, 22); + this.tabPage_EncryptFile.Name = "tabPage_EncryptFile"; + this.tabPage_EncryptFile.Padding = new System.Windows.Forms.Padding(3); + this.tabPage_EncryptFile.Size = new System.Drawing.Size(548, 255); + this.tabPage_EncryptFile.TabIndex = 1; + this.tabPage_EncryptFile.Text = "Encrypt File Manually"; + this.tabPage_EncryptFile.UseVisualStyleBackColor = true; + // + // groupBox2 + // + this.groupBox2.Controls.Add(this.label12); + this.groupBox2.Controls.Add(this.textBox_PassPhraseEncrypt); + this.groupBox2.Controls.Add(this.label3); + this.groupBox2.Controls.Add(this.textBox_EncryptTargetName); + this.groupBox2.Controls.Add(this.label5); + this.groupBox2.Controls.Add(this.textBox_EncryptSourceName); + this.groupBox2.Controls.Add(this.label6); + this.groupBox2.Controls.Add(this.button_BrowseEncryptFile); + this.groupBox2.Location = new System.Drawing.Point(12, 21); + this.groupBox2.Name = "groupBox2"; + this.groupBox2.Size = new System.Drawing.Size(506, 184); + this.groupBox2.TabIndex = 5; + this.groupBox2.TabStop = false; + this.groupBox2.Text = "Encrypt file manually "; + // + // label12 + // + this.label12.AutoSize = true; + this.label12.Location = new System.Drawing.Point(16, 143); + this.label12.Name = "label12"; + this.label12.Size = new System.Drawing.Size(66, 13); + this.label12.TabIndex = 16; + this.label12.Text = "Pass Phrase"; + // + // textBox_PassPhraseEncrypt + // + this.textBox_PassPhraseEncrypt.Location = new System.Drawing.Point(138, 143); + this.textBox_PassPhraseEncrypt.Name = "textBox_PassPhraseEncrypt"; + this.textBox_PassPhraseEncrypt.Size = new System.Drawing.Size(260, 20); + this.textBox_PassPhraseEncrypt.TabIndex = 15; + // + // label3 + // + this.label3.AutoSize = true; + this.label3.Location = new System.Drawing.Point(137, 70); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(257, 13); + this.label3.TabIndex = 14; + this.label3.Text = "target file name can be the same as the source name"; + // + // textBox_EncryptTargetName + // + this.textBox_EncryptTargetName.Location = new System.Drawing.Point(140, 95); + this.textBox_EncryptTargetName.Name = "textBox_EncryptTargetName"; + this.textBox_EncryptTargetName.Size = new System.Drawing.Size(258, 20); + this.textBox_EncryptTargetName.TabIndex = 13; + // + // label5 + // + this.label5.AutoSize = true; + this.label5.Location = new System.Drawing.Point(16, 95); + this.label5.Name = "label5"; + this.label5.Size = new System.Drawing.Size(86, 13); + this.label5.TabIndex = 12; + this.label5.Text = "Target File name"; + // + // textBox_EncryptSourceName + // + this.textBox_EncryptSourceName.Location = new System.Drawing.Point(140, 38); + this.textBox_EncryptSourceName.Name = "textBox_EncryptSourceName"; + this.textBox_EncryptSourceName.Size = new System.Drawing.Size(258, 20); + this.textBox_EncryptSourceName.TabIndex = 11; + // + // label6 + // + this.label6.AutoSize = true; + this.label6.Location = new System.Drawing.Point(16, 46); + this.label6.Name = "label6"; + this.label6.Size = new System.Drawing.Size(89, 13); + this.label6.TabIndex = 10; + this.label6.Text = "Source File name"; + // + // button_BrowseEncryptFile + // + this.button_BrowseEncryptFile.Location = new System.Drawing.Point(404, 36); + this.button_BrowseEncryptFile.Name = "button_BrowseEncryptFile"; + this.button_BrowseEncryptFile.Size = new System.Drawing.Size(44, 23); + this.button_BrowseEncryptFile.TabIndex = 6; + this.button_BrowseEncryptFile.Text = "..."; + this.button_BrowseEncryptFile.UseVisualStyleBackColor = true; + this.button_BrowseEncryptFile.Click += new System.EventHandler(this.button_BrowseEncryptFile_Click); + // + // button_StartToEncrypt + // + this.button_StartToEncrypt.Location = new System.Drawing.Point(443, 211); + this.button_StartToEncrypt.Name = "button_StartToEncrypt"; + this.button_StartToEncrypt.Size = new System.Drawing.Size(75, 23); + this.button_StartToEncrypt.TabIndex = 4; + this.button_StartToEncrypt.Text = "Start"; + this.button_StartToEncrypt.UseVisualStyleBackColor = true; + this.button_StartToEncrypt.Click += new System.EventHandler(this.button_StartToEncrypt_Click); + // + // tabPage_Folder + // + this.tabPage_Folder.Controls.Add(this.splitContainer1); + this.tabPage_Folder.Location = new System.Drawing.Point(4, 22); + this.tabPage_Folder.Name = "tabPage_Folder"; + this.tabPage_Folder.Padding = new System.Windows.Forms.Padding(3); + this.tabPage_Folder.Size = new System.Drawing.Size(548, 255); + this.tabPage_Folder.TabIndex = 0; + this.tabPage_Folder.Text = "Auto Folder Encrption"; + this.tabPage_Folder.UseVisualStyleBackColor = true; + // + // splitContainer1 + // + this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill; + this.splitContainer1.Location = new System.Drawing.Point(3, 3); + this.splitContainer1.Name = "splitContainer1"; + // + // splitContainer1.Panel1 + // + this.splitContainer1.Panel1.Controls.Add(this.groupBox1); + // + // splitContainer1.Panel2 + // + this.splitContainer1.Panel2.Controls.Add(this.listView_AutoEncryptFolders); + this.splitContainer1.Size = new System.Drawing.Size(542, 249); + this.splitContainer1.SplitterDistance = 114; + this.splitContainer1.TabIndex = 0; + // + // groupBox1 + // + this.groupBox1.Controls.Add(this.button_Help); + this.groupBox1.Controls.Add(this.button_Stop); + this.groupBox1.Controls.Add(this.button_Start); + this.groupBox1.Controls.Add(this.button_RemoveFolder); + this.groupBox1.Controls.Add(this.button_AddFolder); + this.groupBox1.Dock = System.Windows.Forms.DockStyle.Fill; + this.groupBox1.Location = new System.Drawing.Point(0, 0); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size(114, 249); + this.groupBox1.TabIndex = 2; + this.groupBox1.TabStop = false; + // + // button_Help + // + this.button_Help.Location = new System.Drawing.Point(6, 206); + this.button_Help.Name = "button_Help"; + this.button_Help.Size = new System.Drawing.Size(94, 23); + this.button_Help.TabIndex = 4; + this.button_Help.Text = "Help Info"; + this.button_Help.UseVisualStyleBackColor = true; + this.button_Help.Click += new System.EventHandler(this.button_Help_Click); + // + // button_Stop + // + this.button_Stop.Location = new System.Drawing.Point(6, 153); + this.button_Stop.Name = "button_Stop"; + this.button_Stop.Size = new System.Drawing.Size(94, 23); + this.button_Stop.TabIndex = 3; + this.button_Stop.Text = "Stop Service"; + this.button_Stop.UseVisualStyleBackColor = true; + this.button_Stop.Click += new System.EventHandler(this.button_Stop_Click); + // + // button_Start + // + this.button_Start.Location = new System.Drawing.Point(6, 124); + this.button_Start.Name = "button_Start"; + this.button_Start.Size = new System.Drawing.Size(94, 23); + this.button_Start.TabIndex = 2; + this.button_Start.Text = "Start Service"; + this.button_Start.UseVisualStyleBackColor = true; + this.button_Start.Click += new System.EventHandler(this.button_Start_Click); + // + // button_RemoveFolder + // + this.button_RemoveFolder.Location = new System.Drawing.Point(6, 72); + this.button_RemoveFolder.Name = "button_RemoveFolder"; + this.button_RemoveFolder.Size = new System.Drawing.Size(94, 23); + this.button_RemoveFolder.TabIndex = 1; + this.button_RemoveFolder.Text = "Remove folder"; + this.button_RemoveFolder.UseVisualStyleBackColor = true; + this.button_RemoveFolder.Click += new System.EventHandler(this.button_RemoveFolder_Click); + // + // button_AddFolder + // + this.button_AddFolder.Location = new System.Drawing.Point(6, 34); + this.button_AddFolder.Name = "button_AddFolder"; + this.button_AddFolder.Size = new System.Drawing.Size(94, 23); + this.button_AddFolder.TabIndex = 0; + this.button_AddFolder.Text = "Add folder"; + this.button_AddFolder.UseVisualStyleBackColor = true; + this.button_AddFolder.Click += new System.EventHandler(this.button_AddFolder_Click); + // + // listView_AutoEncryptFolders + // + this.listView_AutoEncryptFolders.AllowDrop = true; + this.listView_AutoEncryptFolders.Dock = System.Windows.Forms.DockStyle.Fill; + this.listView_AutoEncryptFolders.FullRowSelect = true; + this.listView_AutoEncryptFolders.HideSelection = false; + this.listView_AutoEncryptFolders.Location = new System.Drawing.Point(0, 0); + this.listView_AutoEncryptFolders.Name = "listView_AutoEncryptFolders"; + this.listView_AutoEncryptFolders.Size = new System.Drawing.Size(424, 249); + this.listView_AutoEncryptFolders.SmallImageList = this.imageList1; + this.listView_AutoEncryptFolders.TabIndex = 0; + this.listView_AutoEncryptFolders.UseCompatibleStateImageBehavior = false; + this.listView_AutoEncryptFolders.View = System.Windows.Forms.View.List; + // + // tabControl1 + // + this.tabControl1.Controls.Add(this.tabPage_Folder); + this.tabControl1.Controls.Add(this.tabPage_EncryptOnRead); + this.tabControl1.Controls.Add(this.tabPage_EncryptFile); + this.tabControl1.Controls.Add(this.tabPage_DecryptFile); + this.tabControl1.Dock = System.Windows.Forms.DockStyle.Fill; + this.tabControl1.Location = new System.Drawing.Point(0, 0); + this.tabControl1.Name = "tabControl1"; + this.tabControl1.SelectedIndex = 0; + this.tabControl1.Size = new System.Drawing.Size(556, 281); + this.tabControl1.TabIndex = 0; + // + // tabPage_EncryptOnRead + // + this.tabPage_EncryptOnRead.Controls.Add(this.splitContainer2); + this.tabPage_EncryptOnRead.Location = new System.Drawing.Point(4, 22); + this.tabPage_EncryptOnRead.Name = "tabPage_EncryptOnRead"; + this.tabPage_EncryptOnRead.Padding = new System.Windows.Forms.Padding(3); + this.tabPage_EncryptOnRead.Size = new System.Drawing.Size(548, 255); + this.tabPage_EncryptOnRead.TabIndex = 4; + this.tabPage_EncryptOnRead.Text = "Encrypt File On The Go"; + this.tabPage_EncryptOnRead.UseVisualStyleBackColor = true; + // + // splitContainer2 + // + this.splitContainer2.Dock = System.Windows.Forms.DockStyle.Fill; + this.splitContainer2.Location = new System.Drawing.Point(3, 3); + this.splitContainer2.Name = "splitContainer2"; + // + // splitContainer2.Panel1 + // + this.splitContainer2.Panel1.Controls.Add(this.groupBox4); + // + // splitContainer2.Panel2 + // + this.splitContainer2.Panel2.Controls.Add(this.listView_EncryptOnReadFolders); + this.splitContainer2.Size = new System.Drawing.Size(542, 249); + this.splitContainer2.SplitterDistance = 114; + this.splitContainer2.TabIndex = 1; + // + // groupBox4 + // + this.groupBox4.Controls.Add(this.button_StopService); + this.groupBox4.Controls.Add(this.button_StartService); + this.groupBox4.Controls.Add(this.button_RemoveProtectFolder); + this.groupBox4.Controls.Add(this.button_AddProtectFolder); + this.groupBox4.Dock = System.Windows.Forms.DockStyle.Fill; + this.groupBox4.Location = new System.Drawing.Point(0, 0); + this.groupBox4.Name = "groupBox4"; + this.groupBox4.Size = new System.Drawing.Size(114, 249); + this.groupBox4.TabIndex = 2; + this.groupBox4.TabStop = false; + // + // button_StopService + // + this.button_StopService.Location = new System.Drawing.Point(5, 192); + this.button_StopService.Name = "button_StopService"; + this.button_StopService.Size = new System.Drawing.Size(103, 23); + this.button_StopService.TabIndex = 3; + this.button_StopService.Text = "Stop Service"; + this.button_StopService.UseVisualStyleBackColor = true; + this.button_StopService.Click += new System.EventHandler(this.button_StopService_Click); + // + // button_StartService + // + this.button_StartService.Location = new System.Drawing.Point(6, 163); + this.button_StartService.Name = "button_StartService"; + this.button_StartService.Size = new System.Drawing.Size(102, 23); + this.button_StartService.TabIndex = 2; + this.button_StartService.Text = "Start Service"; + this.button_StartService.UseVisualStyleBackColor = true; + this.button_StartService.Click += new System.EventHandler(this.button_StartService_Click); + // + // button_RemoveProtectFolder + // + this.button_RemoveProtectFolder.Location = new System.Drawing.Point(5, 48); + this.button_RemoveProtectFolder.Name = "button_RemoveProtectFolder"; + this.button_RemoveProtectFolder.Size = new System.Drawing.Size(103, 23); + this.button_RemoveProtectFolder.TabIndex = 1; + this.button_RemoveProtectFolder.Text = "Remove folder"; + this.button_RemoveProtectFolder.UseVisualStyleBackColor = true; + this.button_RemoveProtectFolder.Click += new System.EventHandler(this.button_RemoveEncryptOnReadFolder_Click); + // + // button_AddProtectFolder + // + this.button_AddProtectFolder.Location = new System.Drawing.Point(6, 19); + this.button_AddProtectFolder.Name = "button_AddProtectFolder"; + this.button_AddProtectFolder.Size = new System.Drawing.Size(102, 23); + this.button_AddProtectFolder.TabIndex = 0; + this.button_AddProtectFolder.Text = "Add folder"; + this.button_AddProtectFolder.UseVisualStyleBackColor = true; + this.button_AddProtectFolder.Click += new System.EventHandler(this.button_AddEncryptOnReadFolder_Click); + // + // listView_EncryptOnReadFolders + // + this.listView_EncryptOnReadFolders.AllowDrop = true; + this.listView_EncryptOnReadFolders.Dock = System.Windows.Forms.DockStyle.Fill; + this.listView_EncryptOnReadFolders.FullRowSelect = true; + this.listView_EncryptOnReadFolders.HideSelection = false; + this.listView_EncryptOnReadFolders.Location = new System.Drawing.Point(0, 0); + this.listView_EncryptOnReadFolders.Name = "listView_EncryptOnReadFolders"; + this.listView_EncryptOnReadFolders.Size = new System.Drawing.Size(424, 249); + this.listView_EncryptOnReadFolders.SmallImageList = this.imageList1; + this.listView_EncryptOnReadFolders.TabIndex = 0; + this.listView_EncryptOnReadFolders.UseCompatibleStateImageBehavior = false; + this.listView_EncryptOnReadFolders.View = System.Windows.Forms.View.List; + // + // tabPage_DecryptFile + // + this.tabPage_DecryptFile.Controls.Add(this.groupBox3); + this.tabPage_DecryptFile.Controls.Add(this.button_StartToDecrypt); + this.tabPage_DecryptFile.Location = new System.Drawing.Point(4, 22); + this.tabPage_DecryptFile.Name = "tabPage_DecryptFile"; + this.tabPage_DecryptFile.Padding = new System.Windows.Forms.Padding(3); + this.tabPage_DecryptFile.Size = new System.Drawing.Size(548, 255); + this.tabPage_DecryptFile.TabIndex = 2; + this.tabPage_DecryptFile.Text = "Decrypt File Manually"; + this.tabPage_DecryptFile.UseVisualStyleBackColor = true; + // + // groupBox3 + // + this.groupBox3.Controls.Add(this.checkBox_DecryptFileOnTheGo); + this.groupBox3.Controls.Add(this.label17); + this.groupBox3.Controls.Add(this.textBox_PassPhraseDecrypt); + this.groupBox3.Controls.Add(this.label14); + this.groupBox3.Controls.Add(this.textBox_DecryptTargetName); + this.groupBox3.Controls.Add(this.label15); + this.groupBox3.Controls.Add(this.textBox_DecryptSourceName); + this.groupBox3.Controls.Add(this.label16); + this.groupBox3.Controls.Add(this.button_BrowseFileToDecrypt); + this.groupBox3.Location = new System.Drawing.Point(17, 21); + this.groupBox3.Name = "groupBox3"; + this.groupBox3.Size = new System.Drawing.Size(498, 188); + this.groupBox3.TabIndex = 7; + this.groupBox3.TabStop = false; + this.groupBox3.Text = "Decrypt file manually"; + // + // label17 + // + this.label17.AutoSize = true; + this.label17.Location = new System.Drawing.Point(16, 134); + this.label17.Name = "label17"; + this.label17.Size = new System.Drawing.Size(66, 13); + this.label17.TabIndex = 19; + this.label17.Text = "Pass Phrase"; + // + // textBox_PassPhraseDecrypt + // + this.textBox_PassPhraseDecrypt.Location = new System.Drawing.Point(140, 134); + this.textBox_PassPhraseDecrypt.Name = "textBox_PassPhraseDecrypt"; + this.textBox_PassPhraseDecrypt.Size = new System.Drawing.Size(258, 20); + this.textBox_PassPhraseDecrypt.TabIndex = 18; + // + // label14 + // + this.label14.AutoSize = true; + this.label14.Location = new System.Drawing.Point(137, 64); + this.label14.Name = "label14"; + this.label14.Size = new System.Drawing.Size(257, 13); + this.label14.TabIndex = 14; + this.label14.Text = "target file name can be the same as the source name"; + // + // textBox_DecryptTargetName + // + this.textBox_DecryptTargetName.Location = new System.Drawing.Point(140, 89); + this.textBox_DecryptTargetName.Name = "textBox_DecryptTargetName"; + this.textBox_DecryptTargetName.Size = new System.Drawing.Size(258, 20); + this.textBox_DecryptTargetName.TabIndex = 13; + // + // label15 + // + this.label15.AutoSize = true; + this.label15.Location = new System.Drawing.Point(16, 89); + this.label15.Name = "label15"; + this.label15.Size = new System.Drawing.Size(86, 13); + this.label15.TabIndex = 12; + this.label15.Text = "Target File name"; + // + // textBox_DecryptSourceName + // + this.textBox_DecryptSourceName.Location = new System.Drawing.Point(140, 32); + this.textBox_DecryptSourceName.Name = "textBox_DecryptSourceName"; + this.textBox_DecryptSourceName.Size = new System.Drawing.Size(258, 20); + this.textBox_DecryptSourceName.TabIndex = 11; + // + // label16 + // + this.label16.AutoSize = true; + this.label16.Location = new System.Drawing.Point(16, 40); + this.label16.Name = "label16"; + this.label16.Size = new System.Drawing.Size(89, 13); + this.label16.TabIndex = 10; + this.label16.Text = "Source File name"; + // + // button_BrowseFileToDecrypt + // + this.button_BrowseFileToDecrypt.Location = new System.Drawing.Point(404, 30); + this.button_BrowseFileToDecrypt.Name = "button_BrowseFileToDecrypt"; + this.button_BrowseFileToDecrypt.Size = new System.Drawing.Size(44, 23); + this.button_BrowseFileToDecrypt.TabIndex = 6; + this.button_BrowseFileToDecrypt.Text = "..."; + this.button_BrowseFileToDecrypt.UseVisualStyleBackColor = true; + this.button_BrowseFileToDecrypt.Click += new System.EventHandler(this.button_BrowseFileToDecrypt_Click); + // + // button_StartToDecrypt + // + this.button_StartToDecrypt.Location = new System.Drawing.Point(440, 215); + this.button_StartToDecrypt.Name = "button_StartToDecrypt"; + this.button_StartToDecrypt.Size = new System.Drawing.Size(75, 23); + this.button_StartToDecrypt.TabIndex = 6; + this.button_StartToDecrypt.Text = "Start"; + this.button_StartToDecrypt.UseVisualStyleBackColor = true; + this.button_StartToDecrypt.Click += new System.EventHandler(this.button_StartToDecrypt_Click); + // + // label13 + // + this.label13.AutoSize = true; + this.label13.Location = new System.Drawing.Point(148, 48); + this.label13.Name = "label13"; + this.label13.Size = new System.Drawing.Size(190, 13); + this.label13.TabIndex = 52; + this.label13.Text = "(split with \';\' for multiple process names)"; + // + // textBox1 + // + this.textBox1.Location = new System.Drawing.Point(151, 80); + this.textBox1.Name = "textBox1"; + this.textBox1.Size = new System.Drawing.Size(287, 20); + this.textBox1.TabIndex = 51; + this.textBox1.Text = "explorer.exe"; + // + // label7 + // + this.label7.AutoSize = true; + this.label7.Location = new System.Drawing.Point(15, 83); + this.label7.Name = "label7"; + this.label7.Size = new System.Drawing.Size(105, 13); + this.label7.TabIndex = 50; + this.label7.Text = "Black List Processes"; + // + // textBox2 + // + this.textBox2.Location = new System.Drawing.Point(151, 25); + this.textBox2.Name = "textBox2"; + this.textBox2.Size = new System.Drawing.Size(287, 20); + this.textBox2.TabIndex = 49; + this.textBox2.Text = "*"; + // + // label8 + // + this.label8.AutoSize = true; + this.label8.Location = new System.Drawing.Point(15, 25); + this.label8.Name = "label8"; + this.label8.Size = new System.Drawing.Size(106, 13); + this.label8.TabIndex = 48; + this.label8.Text = "White List Processes"; + // + // label11 + // + this.label11.AutoSize = true; + this.label11.Location = new System.Drawing.Point(148, 103); + this.label11.Name = "label11"; + this.label11.Size = new System.Drawing.Size(190, 13); + this.label11.TabIndex = 47; + this.label11.Text = "(split with \';\' for multiple process names)"; + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(23, 44); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(89, 13); + this.label2.TabIndex = 3; + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(23, 101); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(86, 13); + this.label1.TabIndex = 7; + // + // label4 + // + this.label4.AutoSize = true; + this.label4.Location = new System.Drawing.Point(144, 73); + this.label4.Name = "label4"; + this.label4.Size = new System.Drawing.Size(257, 13); + this.label4.TabIndex = 9; + // + // checkBox_DecryptFileOnTheGo + // + this.checkBox_DecryptFileOnTheGo.AutoSize = true; + this.checkBox_DecryptFileOnTheGo.Location = new System.Drawing.Point(140, 165); + this.checkBox_DecryptFileOnTheGo.Name = "checkBox_DecryptFileOnTheGo"; + this.checkBox_DecryptFileOnTheGo.Size = new System.Drawing.Size(138, 17); + this.checkBox_DecryptFileOnTheGo.TabIndex = 20; + this.checkBox_DecryptFileOnTheGo.Text = "Decrypt File On The Go"; + this.checkBox_DecryptFileOnTheGo.UseVisualStyleBackColor = true; + // + // Form_FileCrypt + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(556, 281); + this.Controls.Add(this.tabControl1); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Name = "Form_FileCrypt"; + this.Text = "Auto FileCrypt Tool"; + this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.Form_FileCrypt_FormClosed); + this.tabPage_EncryptFile.ResumeLayout(false); + this.groupBox2.ResumeLayout(false); + this.groupBox2.PerformLayout(); + this.tabPage_Folder.ResumeLayout(false); + this.splitContainer1.Panel1.ResumeLayout(false); + this.splitContainer1.Panel2.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit(); + this.splitContainer1.ResumeLayout(false); + this.groupBox1.ResumeLayout(false); + this.tabControl1.ResumeLayout(false); + this.tabPage_EncryptOnRead.ResumeLayout(false); + this.splitContainer2.Panel1.ResumeLayout(false); + this.splitContainer2.Panel2.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.splitContainer2)).EndInit(); + this.splitContainer2.ResumeLayout(false); + this.groupBox4.ResumeLayout(false); + this.tabPage_DecryptFile.ResumeLayout(false); + this.groupBox3.ResumeLayout(false); + this.groupBox3.PerformLayout(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.ImageList imageList1; + private System.Windows.Forms.TabPage tabPage_EncryptFile; + private System.Windows.Forms.GroupBox groupBox2; + private System.Windows.Forms.Button button_BrowseEncryptFile; + private System.Windows.Forms.Button button_StartToEncrypt; + private System.Windows.Forms.TabPage tabPage_Folder; + private System.Windows.Forms.SplitContainer splitContainer1; + private System.Windows.Forms.GroupBox groupBox1; + private System.Windows.Forms.Button button_RemoveFolder; + private System.Windows.Forms.Button button_AddFolder; + private System.Windows.Forms.ListView listView_AutoEncryptFolders; + private System.Windows.Forms.TabControl tabControl1; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.TextBox textBox_EncryptTargetName; + private System.Windows.Forms.Label label5; + private System.Windows.Forms.TextBox textBox_EncryptSourceName; + private System.Windows.Forms.Label label6; + private System.Windows.Forms.Button button_Stop; + private System.Windows.Forms.Button button_Start; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Label label4; + private System.Windows.Forms.TextBox textBox1; + private System.Windows.Forms.Label label7; + private System.Windows.Forms.TextBox textBox2; + private System.Windows.Forms.Label label8; + private System.Windows.Forms.Label label11; + private System.Windows.Forms.Label label13; + private System.Windows.Forms.TabPage tabPage_DecryptFile; + private System.Windows.Forms.GroupBox groupBox3; + private System.Windows.Forms.Label label14; + private System.Windows.Forms.TextBox textBox_DecryptTargetName; + private System.Windows.Forms.Label label15; + private System.Windows.Forms.TextBox textBox_DecryptSourceName; + private System.Windows.Forms.Label label16; + private System.Windows.Forms.Button button_BrowseFileToDecrypt; + private System.Windows.Forms.Button button_StartToDecrypt; + private System.Windows.Forms.TabPage tabPage_EncryptOnRead; + private System.Windows.Forms.SplitContainer splitContainer2; + private System.Windows.Forms.GroupBox groupBox4; + private System.Windows.Forms.Button button_StopService; + private System.Windows.Forms.Button button_StartService; + private System.Windows.Forms.Button button_RemoveProtectFolder; + private System.Windows.Forms.Button button_AddProtectFolder; + private System.Windows.Forms.ListView listView_EncryptOnReadFolders; + private System.Windows.Forms.Label label12; + private System.Windows.Forms.TextBox textBox_PassPhraseEncrypt; + private System.Windows.Forms.Label label17; + private System.Windows.Forms.TextBox textBox_PassPhraseDecrypt; + private System.Windows.Forms.Button button_Help; + private System.Windows.Forms.CheckBox checkBox_DecryptFileOnTheGo; + } +} + diff --git a/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/FormFileCrypt.cs b/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/FormFileCrypt.cs new file mode 100644 index 0000000..f44d196 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/FormFileCrypt.cs @@ -0,0 +1,547 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.IO; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; +using System.Configuration; + +using EaseFilter.FilterControl; +using EaseFilter.CommonObjects; + +namespace AutoFileCryptTool +{ + public partial class Form_FileCrypt : Form + { + + FilterControl filterControl = new FilterControl(); + + public enum FilterRuleType : int + { + AutoEncryption = 0, + EncryptionOnRead, + } + + public Form_FileCrypt() + { + GlobalConfig.filterType = FilterAPI.FilterType.ENCRYPTION_FILTER|FilterAPI.FilterType.CONTROL_FILTER|FilterAPI.FilterType.PROCESS_FILTER; + + InitializeComponent(); + + StartPosition = FormStartPosition.CenterScreen; + + InitializeFileCrypt(); + + } + + + private void InitializeFileCrypt() + { + int numberOfAutoEncryptFolders = 0; + int numberOfEncryptOnReadFolders = 0; + + foreach (FileFilterRule filterRule in GlobalConfig.FilterRules.Values) + { + if (filterRule.Type == (int)FilterRuleType.AutoEncryption) + { + numberOfAutoEncryptFolders++; + } + else if (filterRule.Type == (int)FilterRuleType.EncryptionOnRead) + { + numberOfEncryptOnReadFolders++; + } + } + + listView_AutoEncryptFolders.Items.Clear(); + listView_EncryptOnReadFolders.Items.Clear(); + + if (numberOfAutoEncryptFolders == 0) + { + AddDefaultItemsToAutoFolderList(); + + } + + if (numberOfEncryptOnReadFolders == 0) + { + AddDefaultItemsToEncryptOnReadList(); + } + + foreach (FileFilterRule filterRule in GlobalConfig.FilterRules.Values) + { + if (filterRule.Type == (int)FilterRuleType.AutoEncryption) + { + + string folderName = filterRule.IncludeFileFilterMask; + if (folderName.EndsWith("\\*")) + { + folderName = folderName.Substring(0, folderName.Length - 2); + } + + ListViewItem item = new ListViewItem(folderName); + item.ImageIndex = 0; + listView_AutoEncryptFolders.Items.Add(item); + } + else if (filterRule.Type == (int)FilterRuleType.EncryptionOnRead) + { + + string folderName = filterRule.IncludeFileFilterMask; + if (folderName.EndsWith("\\*")) + { + folderName = folderName.Substring(0, folderName.Length - 2); + } + + ListViewItem item = new ListViewItem(folderName); + item.ImageIndex = 0; + listView_EncryptOnReadFolders.Items.Add(item); + } + } + + GlobalConfig.SaveConfigSetting(); + } + + public void SendConfigSettingsToFilter() + { + filterControl.ClearFilters(); + foreach (FileFilterRule filterRule in GlobalConfig.FilterRules.Values) + { + FileFilter fileFilter = filterRule.ToFileFilter(); + filterControl.AddFilter(fileFilter); + } + + FileFilter dropFolderFileFilter = new FileFilter(GlobalConfig.DropFolder + "\\*"); + //enable the encryption, it is for decryption, disable encrypt new file since the file was encrypted in this folder. + dropFolderFileFilter.AccessFlags = (FilterAPI.AccessFlag)((FilterAPI.ALLOW_MAX_RIGHT_ACCESS | (uint)FilterAPI.AccessFlag.ENABLE_FILE_ENCRYPTION_RULE) & (~(uint)FilterAPI.AccessFlag.ALLOW_ENCRYPT_NEW_FILE)); + dropFolderFileFilter.EncryptionPassPhrase = GlobalConfig.MasterPassword; + dropFolderFileFilter.EncryptionIV = Utils.GetIVByPassPhrase(GlobalConfig.MasterPassword); + + filterControl.AddFilter(dropFolderFileFilter); + + string lastError = string.Empty; + if (!filterControl.SendConfigSettingsToFilter(ref lastError)) + { + MessageBox.Show(lastError, "StartFilter", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + + + return; + } + + /// + /// The new file will be automatically encrypted when it was added to the auto encrypt folders. + /// The while list process will automatically get the decrypted data when it reads the encrypted file. + /// The black list process will get the raw data ( encrypted ) data when it reads the encrypted file. + /// + /// + /// + private bool AddAutoEncyrptFolder(string folderName) + { + + string includeFilterMask = folderName + "\\*"; + string blackProcessList = string.Empty; + string passPhrase = string.Empty; + + BlackListForm blackListForm = new BlackListForm(); + + if (blackListForm.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + blackProcessList = blackListForm.BlackList; + } + + //for blacklist process for autoencryption, it has maximum acess rights. + string blackListProcessRights = ""; + string[] blacklist = blackProcessList.Split(new char[] { ';' }); + if (blacklist.Length > 0) + { + foreach (string unAuthorizedUser in blacklist) + { + if (unAuthorizedUser.Trim().Length > 0) + { + //can't read the encrypted files + uint accessFlag = FilterAPI.ALLOW_MAX_RIGHT_ACCESS & (uint)(~FilterAPI.AccessFlag.ALLOW_READ_ENCRYPTED_FILES); + blackListProcessRights += ";" + unAuthorizedUser + "!" + accessFlag.ToString(); + } + } + } + + PasswordForm passwordForm = new PasswordForm(); + + if (passwordForm.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + passPhrase = passwordForm.PassPhrase; + } + + if (passPhrase.Trim().Length == 0) + { + MessageBox.Show("The passphrase was empty,it will use the default passPhrase 'test'", "PassPhrase", MessageBoxButtons.OK, MessageBoxIcon.Warning); + passPhrase = "test"; + } + + FileFilterRule autoEncrytFilterRule = new FileFilterRule(); + autoEncrytFilterRule.Type = (int)FilterRuleType.AutoEncryption; + autoEncrytFilterRule.IncludeFileFilterMask = folderName + "\\*"; + autoEncrytFilterRule.EncryptionPassPhrase = passPhrase; + autoEncrytFilterRule.AccessFlag = (uint)FilterAPI.ALLOW_MAX_RIGHT_ACCESS | (uint)FilterAPI.AccessFlag.ENABLE_FILE_ENCRYPTION_RULE; + autoEncrytFilterRule.EncryptMethod = (int)FilterAPI.EncryptionMethod.ENCRYPT_FILE_WITH_SAME_KEY_AND_UNIQUE_IV; + autoEncrytFilterRule.ProcessNameRights = blackListProcessRights; + + GlobalConfig.AddFileFilterRule(autoEncrytFilterRule); + + InitializeFileCrypt(); + + return true; + } + + private void button_AddFolder_Click(object sender, EventArgs e) + { + FolderBrowserDialog fdDiaglog = new FolderBrowserDialog(); + if (fdDiaglog.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + string folderName = fdDiaglog.SelectedPath; + AddAutoEncyrptFolder(folderName); + } + + string lastError = string.Empty; + + SendConfigSettingsToFilter(); + } + + + private void button_RemoveFolder_Click(object sender, EventArgs e) + { + foreach (ListViewItem item in listView_AutoEncryptFolders.SelectedItems) + { + string folderName = item.Text + "\\*"; + GlobalConfig.RemoveFilterRule(folderName); + } + + InitializeFileCrypt(); + + string lastError = string.Empty; + + SendConfigSettingsToFilter(); + } + + private void button_StartToEncrypt_Click(object sender, EventArgs e) + { + try + { + string fileName = textBox_EncryptSourceName.Text; + string targetFileName = textBox_EncryptTargetName.Text; + + string passPhrase = textBox_PassPhraseEncrypt.Text.Trim(); + byte[] key = Utils.GetKeyByPassPhrase(passPhrase, 32); + byte[] iv = Utils.GetIVByPassPhrase(passPhrase); + + //test if the file was encrypted already, then we don't need to encrypt it again. + byte[] ivBuffer = new byte[16]; + uint ivSize = 16; + if (FilterAPI.GetAESIV(fileName, ref ivSize, ivBuffer)) + { + string lastError = "The file " + fileName + " was encrypted already, you can't encrypt it again."; + ShowMessage(lastError, MessageBoxIcon.Warning); + + return; + } + + bool retVal = false; + + if (fileName.Equals(targetFileName, StringComparison.CurrentCulture)) + { + retVal = FilterAPI.AESEncryptFileWithTag(fileName, (uint)key.Length, key, (uint)iv.Length, iv, (uint)iv.Length, iv); + } + else + { + retVal = FilterAPI.AESEncryptFileToFileWithTag(fileName, targetFileName, (uint)key.Length, key, (uint)iv.Length, iv, (uint)iv.Length, iv); + } + + if (!retVal) + { + string lastError = "Encrypt file " + targetFileName + " failed with error:" + FilterAPI.GetLastErrorMessage(); + ShowMessage(lastError, MessageBoxIcon.Error); + } + else + { + string lastError = "Encrypt file " + fileName + " to " + targetFileName + " succeeded."; + ShowMessage(lastError, MessageBoxIcon.Information); + } + } + catch (Exception ex) + { + string lastError = "Encrypt file failed with error:" + ex.Message; + ShowMessage(lastError, MessageBoxIcon.Error); + } + } + + private void button_BrowseEncryptFile_Click(object sender, EventArgs e) + { + OpenFileDialog fileDiag = new OpenFileDialog(); + if (fileDiag.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + textBox_EncryptSourceName.Text = fileDiag.FileName; + textBox_EncryptTargetName.Text = fileDiag.FileName; + } + } + + private void button_BrowseFileToDecrypt_Click(object sender, EventArgs e) + { + OpenFileDialog fileDiag = new OpenFileDialog(); + if (fileDiag.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + textBox_DecryptSourceName.Text = fileDiag.FileName; + textBox_DecryptTargetName.Text = fileDiag.FileName; + + } + } + + private void button_StartToDecrypt_Click(object sender, EventArgs e) + { + try + { + string fileName = textBox_DecryptSourceName.Text; + string targetFileName = textBox_DecryptTargetName.Text; + + string passPhrase = textBox_PassPhraseDecrypt.Text.Trim(); + byte[] key = Utils.GetKeyByPassPhrase(passPhrase, 32); + byte[] iv = new byte[16]; + uint ivSize = (uint)iv.Length; + + if(checkBox_DecryptFileOnTheGo.Checked) + { + iv = Utils.GetIVByPassPhrase(GlobalConfig.MasterPassword); + key = Utils.GetKeyByPassPhrase(GlobalConfig.MasterPassword, 32); + } + else if (!FilterAPI.GetAESIV(fileName, ref ivSize, iv)) + { + string lastError = "GetAESIV from encrypted file " + fileName + " failed with error:" + FilterAPI.GetLastErrorMessage(); + ShowMessage(lastError, MessageBoxIcon.Error); + return; + } + + bool retVal = false; + if (fileName.Equals(targetFileName, StringComparison.CurrentCulture)) + { + retVal = FilterAPI.AESDecryptFile(fileName, (uint)key.Length, key, (uint)iv.Length, iv); + } + else + { + retVal = FilterAPI.AESDecryptFileToFile(fileName, targetFileName, (uint)key.Length, key, (uint)iv.Length, iv); + } + + if (!retVal) + { + string lastError = "Decrypt file " + fileName + " failed with error:" + FilterAPI.GetLastErrorMessage(); + ShowMessage(lastError, MessageBoxIcon.Error); + } + else + { + string lastError = "Decrypt file " + fileName + " to " + targetFileName + " succeeded."; + ShowMessage(lastError, MessageBoxIcon.Information); + } + } + catch (Exception ex) + { + string lastError = "Decrypt file failed with error:" + ex.Message; + ShowMessage(lastError, MessageBoxIcon.Error); + } + } + + + private void ShowMessage(string message,MessageBoxIcon messageIcon) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show(message, "Message", MessageBoxButtons.OK, messageIcon); + } + + + private void Form_FileCrypt_FormClosed(object sender, FormClosedEventArgs e) + { + FilterAPI.ResetConfigData(); + GlobalConfig.Stop(); + filterControl.StopFilter(); + + Application.Exit(); + } + + + void StartService() + { + + //Purchase a license key with the link: http://www.easefilter.com/Order.htm + //Email us to request a trial key: info@easefilter.com //free email is not accepted. + string licenseKey = GlobalConfig.LicenseKey; + + GlobalConfig.filterType = FilterAPI.FilterType.CONTROL_FILTER | FilterAPI.FilterType.ENCRYPTION_FILTER | FilterAPI.FilterType.PROCESS_FILTER; + + bool ret = false; + string lastError = string.Empty; + + try + { + ret = filterControl.StartFilter(GlobalConfig.filterType, GlobalConfig.FilterConnectionThreads, GlobalConfig.ConnectionTimeOut, licenseKey, ref lastError); + if (!ret) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("Start encryption service failed with error:" + lastError + ", auto folder encryption service will stop.", "Auto FileCrypt Service", MessageBoxButtons.OK, MessageBoxIcon.Error); + + return ; + } + + SendConfigSettingsToFilter(); + + } + catch (Exception ex) + { + EventManager.WriteMessage(104, "StartFilter", EventLevel.Error, "Start filter service failed with error " + ex.Message); + ret = false; + } + + button_Start.Enabled = false; + button_Stop.Enabled = true; + button_StartService.Enabled = false; + button_StopService.Enabled = true; + + } + + void StopService() + { + button_Start.Enabled = true; + button_Stop.Enabled = false; + button_StartService.Enabled = true; + button_StopService.Enabled = false; + + + filterControl.StopFilter(); + } + + private void button_Start_Click(object sender, EventArgs e) + { + StartService(); + } + + private void button_Stop_Click(object sender, EventArgs e) + { + StopService(); + } + + /// + /// The files in protected folder will be automatically encrypted when it was uploaded or copied out + /// by the blacklist processes, the files were not encrypted in the local disk. + /// + /// + /// + private bool AddEncryptOnReadFolder(string folderName) + { + + string includeFilterMask = folderName + "\\*"; + + FileFilterRule EncryptOnReadFilterRule = new FileFilterRule(); + EncryptOnReadFilterRule.Type = (int)FilterRuleType.EncryptionOnRead; + EncryptOnReadFilterRule.IncludeFileFilterMask = folderName + "\\*"; + EncryptOnReadFilterRule.EncryptionPassPhrase = GlobalConfig.MasterPassword; + EncryptOnReadFilterRule.AccessFlag = (uint)FilterAPI.ALLOW_MAX_RIGHT_ACCESS | (uint)FilterAPI.AccessFlag.ENABLE_FILE_ENCRYPTION_RULE; + EncryptOnReadFilterRule.AccessFlag &= (uint)(~FilterAPI.AccessFlag.ALLOW_ENCRYPT_NEW_FILE); //disable new created file encryption + EncryptOnReadFilterRule.EncryptMethod = (int)FilterAPI.EncryptionMethod.ENCRYPT_FILE_WITH_SAME_KEY_AND_IV; + + GlobalConfig.AddFileFilterRule(EncryptOnReadFilterRule); + + GlobalConfig.SaveConfigSetting(); + + return true; + } + + + private void button_AddEncryptOnReadFolder_Click(object sender, EventArgs e) + { + FolderBrowserDialog fdDiaglog = new FolderBrowserDialog(); + if (fdDiaglog.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + string folderName = fdDiaglog.SelectedPath; + AddEncryptOnReadFolder(folderName); + } + + InitializeFileCrypt(); + + string lastError = string.Empty; + + SendConfigSettingsToFilter(); + } + + + private void button_RemoveEncryptOnReadFolder_Click(object sender, EventArgs e) + { + foreach (ListViewItem item in listView_EncryptOnReadFolders.SelectedItems) + { + string folderName = item.Text + "\\*"; + GlobalConfig.RemoveFilterRule(folderName); + } + + InitializeFileCrypt(); + + string lastError = string.Empty; + + SendConfigSettingsToFilter(); + } + + private void button_SetupDropFolder_Click(object sender, EventArgs e) + { + DropFolderForm dropFolderForm = new DropFolderForm(); + if (dropFolderForm.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + GlobalConfig.DropFolder = dropFolderForm.dropFolder; + GlobalConfig.SaveConfigSetting(); + + SendConfigSettingsToFilter(); + } + } + + + private void button_StartService_Click(object sender, EventArgs e) + { + StartService(); + } + + private void button_StopService_Click(object sender, EventArgs e) + { + StopService(); + } + + private void button_Help_Click(object sender, EventArgs e) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + string helpInfo = "1.Setup auto encryption folder.\r\n"; + helpInfo += "The new created file will be encrypted automatically,the process which is not in the black list will get the decrypted data automatically when it reads the file."; + helpInfo += "Add the process to the black list if you want the process to get the raw data of the encrypted file, i.e. backup software.\r\n\r\n"; + helpInfo += "2.Setup auto encrypt file on the go folder.\r\n"; + helpInfo += "The file will be encrypted automatically when the process which is in the black list reads the file."; + helpInfo += "To decrypt the encrypted file via encrypt file on the go, you either decrypt the file manually, or copy it to the auto encryption folder without the service running,"; + helpInfo += "i.e. web browser upload the files, outlook emails the files via attachment, the files will be encrypted automatically, but the files in the local are not encrypted.\r\n\r\n"; + helpInfo += "3.Encrypt/Decrypt file manually.\r\n"; + helpInfo += "You can encrypt the file manually, or decrypt the encrypted file manually, make sure to use the same passphrase for both encryption and decryption.\r\n"; + + MessageBox.Show(helpInfo, "How to use the tool?", MessageBoxButtons.OK, MessageBoxIcon.Information); + + } + + + } +} diff --git a/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/FormFileCrypt.resx b/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/FormFileCrypt.resx new file mode 100644 index 0000000..928c4fc --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/FormFileCrypt.resx @@ -0,0 +1,468 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + + + AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w + LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 + ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAACQ + CwAAAk1TRnQBSQFMAwEBAAEYAQEBGAEBASABAAEgAQAE/wEJAQAI/wFCAU0BNgEEBgABNgEEAgABKAMA + AYADAAEgAwABAQEAAQgGAAEQGAABgAIAAYADAAKAAQABgAMAAYABAAGAAQACgAIAA8ABAAHAAdwBwAEA + AfABygGmAQABMwUAATMBAAEzAQABMwEAAjMCAAMWAQADHAEAAyIBAAMpAQADVQEAA00BAANCAQADOQEA + AYABfAH/AQACUAH/AQABkwEAAdYBAAH/AewBzAEAAcYB1gHvAQAB1gLnAQABkAGpAa0CAAH/ATMDAAFm + AwABmQMAAcwCAAEzAwACMwIAATMBZgIAATMBmQIAATMBzAIAATMB/wIAAWYDAAFmATMCAAJmAgABZgGZ + AgABZgHMAgABZgH/AgABmQMAAZkBMwIAAZkBZgIAApkCAAGZAcwCAAGZAf8CAAHMAwABzAEzAgABzAFm + AgABzAGZAgACzAIAAcwB/wIAAf8BZgIAAf8BmQIAAf8BzAEAATMB/wIAAf8BAAEzAQABMwEAAWYBAAEz + AQABmQEAATMBAAHMAQABMwEAAf8BAAH/ATMCAAMzAQACMwFmAQACMwGZAQACMwHMAQACMwH/AQABMwFm + AgABMwFmATMBAAEzAmYBAAEzAWYBmQEAATMBZgHMAQABMwFmAf8BAAEzAZkCAAEzAZkBMwEAATMBmQFm + AQABMwKZAQABMwGZAcwBAAEzAZkB/wEAATMBzAIAATMBzAEzAQABMwHMAWYBAAEzAcwBmQEAATMCzAEA + ATMBzAH/AQABMwH/ATMBAAEzAf8BZgEAATMB/wGZAQABMwH/AcwBAAEzAv8BAAFmAwABZgEAATMBAAFm + AQABZgEAAWYBAAGZAQABZgEAAcwBAAFmAQAB/wEAAWYBMwIAAWYCMwEAAWYBMwFmAQABZgEzAZkBAAFm + ATMBzAEAAWYBMwH/AQACZgIAAmYBMwEAA2YBAAJmAZkBAAJmAcwBAAFmAZkCAAFmAZkBMwEAAWYBmQFm + AQABZgKZAQABZgGZAcwBAAFmAZkB/wEAAWYBzAIAAWYBzAEzAQABZgHMAZkBAAFmAswBAAFmAcwB/wEA + AWYB/wIAAWYB/wEzAQABZgH/AZkBAAFmAf8BzAEAAcwBAAH/AQAB/wEAAcwBAAKZAgABmQEzAZkBAAGZ + AQABmQEAAZkBAAHMAQABmQMAAZkCMwEAAZkBAAFmAQABmQEzAcwBAAGZAQAB/wEAAZkBZgIAAZkBZgEz + AQABmQEzAWYBAAGZAWYBmQEAAZkBZgHMAQABmQEzAf8BAAKZATMBAAKZAWYBAAOZAQACmQHMAQACmQH/ + AQABmQHMAgABmQHMATMBAAFmAcwBZgEAAZkBzAGZAQABmQLMAQABmQHMAf8BAAGZAf8CAAGZAf8BMwEA + AZkBzAFmAQABmQH/AZkBAAGZAf8BzAEAAZkC/wEAAcwDAAGZAQABMwEAAcwBAAFmAQABzAEAAZkBAAHM + AQABzAEAAZkBMwIAAcwCMwEAAcwBMwFmAQABzAEzAZkBAAHMATMBzAEAAcwBMwH/AQABzAFmAgABzAFm + ATMBAAGZAmYBAAHMAWYBmQEAAcwBZgHMAQABmQFmAf8BAAHMAZkCAAHMAZkBMwEAAcwBmQFmAQABzAKZ + AQABzAGZAcwBAAHMAZkB/wEAAswCAALMATMBAALMAWYBAALMAZkBAAPMAQACzAH/AQABzAH/AgABzAH/ + ATMBAAGZAf8BZgEAAcwB/wGZAQABzAH/AcwBAAHMAv8BAAHMAQABMwEAAf8BAAFmAQAB/wEAAZkBAAHM + ATMCAAH/AjMBAAH/ATMBZgEAAf8BMwGZAQAB/wEzAcwBAAH/ATMB/wEAAf8BZgIAAf8BZgEzAQABzAJm + AQAB/wFmAZkBAAH/AWYBzAEAAcwBZgH/AQAB/wGZAgAB/wGZATMBAAH/AZkBZgEAAf8CmQEAAf8BmQHM + AQAB/wGZAf8BAAH/AcwCAAH/AcwBMwEAAf8BzAFmAQAB/wHMAZkBAAH/AswBAAH/AcwB/wEAAv8BMwEA + AcwB/wFmAQAC/wGZAQAC/wHMAQACZgH/AQABZgH/AWYBAAFmAv8BAAH/AmYBAAH/AWYB/wEAAv8BZgEA + ASEBAAGlAQADXwEAA3cBAAOGAQADlgEAA8sBAAOyAQAD1wEAA90BAAPjAQAD6gEAA/EBAAP4AQAB8AH7 + Af8BAAGkAqABAAOAAwAB/wIAAf8DAAL/AQAB/wMAAf8BAAH/AQAC/wIAA/8IAAP/CAAD/wT0A/9pAAL/ + AvQE/wQAAv8B8wHwAQcC7wEHAfAB8wL/aAAB/wHzAgcBvAHyAfQF/wH0AbwB7QFPAkkBTwHsAe0B9wHw + AfQB/2cAAfMCUQEcAfcBkgHvAQcB8QHzAfQB8wGYBAIDSAEnAewB7QG8AfQB/2UAAf8BmQExASoBMQIq + AXQBHAGSAfcB7wFyAQIFLQECA0gBcgHtAfAC/2QAAf8BUgFZASoDOAIxASoBHAFyAy0BVQF4ATQDLQEC + AkgB7AH3AfMB/2QAAfQBKgFeASoEWQE4AVkBeQECAS4BLQE0AfMB/wEbATQDLQECAUgBJwHtAfAB/2MA + Af8BGgExAeUBKgVZAXoBVgFPAi4B8QL0Af8BGwE0Ay0CSAHsAQcB9GMAAf8BeQFYAeUBKgVZAaABTwFW + AS0B8AH0BP8BGwE0Ai0BAgFIAU8B7wH0YwAB/wEqAuUBKwVZAaABLgGXAU8C/wGYAS4BCAL/ARsBNAIt + AUgBAgH3AfRiAAH/ARsBMQLlATEBegRZAaABLgF4AS4ClwE0AVUBLgEIAv8BGwE0AS0BSAECAfcB9GIA + Af8BmQFYAqABMQF6AeUCegFZAaABTwF4AVYCVQFWAlUBLgEIAv8BGwE0AQIBTwH3AfRiAAH/ASoDoAEx + AXoE5QGgAXgBVgF4BFYCVQEuAQgC/wGYAQIBUAH3AfRhAAH/ARsBMQOgATEBegXlAZ8BLgGYBVYCVQEu + AZgBCAFVAQIBHAH3AfRhAAH/AZkBeQOgATEBmgXlAaABeAFVAZgEVgNVAS4BLQECAZcBdAH3AfRhAAH/ + AUsDoAHDATEDoATlAaABUAFVAZgBeAJWA1UBNAEtAVABwwEqAfcB9GAAAf8BGwExAsMBoAHDATEGoALl + AcMBeAEuAVYCeAGXAVYBTwEtAZcCwwEqAfcB9GAAAf8BmQF5BMMBMQigAeUBoAEaAXgETwGXAZkDwwEq + AfcB9GAAAf8BSwXDATEBwwygAsMDoAPDASoB9wH0YAAB8gExAfYEwwExAcMKoAXlAXoEwwEqAfcB9GAA + ApkB/wH2A8MBMQLDC6AD5QGaBMMBKgH3AfRgAAFSATECUgJ5AaABMQTDCqAB5QF6BcMBKgH3AfRgAAH/ + AfQBGwIaAZkBeQExARoBmgF6A5oJoAGaBcMBKgH3AfRlAAL/AVIC9gTDAqADmgJ6AZoBegGgBcMBKgH3 + AfRnAAFSAvYFwwX2CcMBKgH3AfRnAAFSAfYB/wj2BMMB9gXDAfYBKgH3AfRnAAFYAXkCmQGaAxoBwwL2 + A/8I9gEqAfcB9GcAARsBGgOZA3kBWAJSATEBKgGZCPYBKgEHAfRpAAr/ARsBUgH/BvYBGgFRAfAB/3MA + Af8BMQf/AXQBHAHzAf90AAF5ATEDKwQqAfMC/3UACf9iAAFCAU0BPgcAAT4DAAEoAwABgAMAASADAAEB + AQABAQYAAQIWAAP/AQAB/gE/AcABDwwAAfgBBwGAAQcMAAH4AgABAwwAAfgCAAEBDAAB8A8AAfAPAAHw + DwAB4A8AAeAPAAHgDwABwA8AAcAPAAHADwABgA8AAYAPAAGAfwAB+A8AAf4PAAH+DwAB/g8AAf4PAAH/ + AYAOAAL/AeANAAL/AfANAAL/AfgBAwwACw== + + + + + + AAABAAEAQEAAAAEAIAAoQgAAFgAAACgAAABAAAAAgAAAAAEAIAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AABqRDYQaEM0T2lDNIVtRjasc0k5xnlOPtR/U0LUhVlIxoxgT6ySaVaEmXNfT6B+ag8AAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAf1VGA3pQQVV5TT64eUw8+nxNPf9/Tz7/g1NA/4lXRP+QXUr/lmRQ/51sWP+ldmD/rIFp/7GK + c/+0knz6uJuIt7qhkFS9ppcDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACTcFsBkGlUW5BjT92TYU7/k15M/5FcSv+PW0n/lGVS/6iBcf+ui3v/p4V2/62L + e/+7mor/wqCN/72Ygf/Cnof/yqmU/9G0of/Uu6r/zrmp3Mm1plnHtacBAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAClhnIgpYFrv62Ea/+tgWX/qHhf/6x/bP+ohnf/mHdj/4JX + PP+AVTj/ZCcA/3Q7Fv+OYEH/YycA/3A+Hv+SbFP/mnpm/8myof/dxLP/4ci4/+bRwf/j0MH/1cS1vtDA + sh8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC2nIlIvZ6K7sakjf/Dnob/w6CJ/66P + fP+GWTr/dzIA/55mPf+KOwD/nFsp/409AP+WTxj/q3NI/449AP+ZUx7/iz4E/4hAC/+OVzD/glIx/8Ks + nP/u3tD/8uHT//Hh0//i08Xu2Mm7RwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADFr55f0bml+9q/ + rP/XuqX/yrGg/4haOv+EOQD/pm1A/5ZEAP+fUA3/nUkA/59KAP+hSwD/plkU/7Z4QP+hTAD/oEsA/51J + AP+dTAf/l0YC/5ZOFP+XWiz/ilo4/93NwP/5697/+Orc/+rbzfvdzb9dAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AADNuqpY38u5/OrVw//o0sL/s5eF/307C/+ockf/mkgB/6BNAv+kUAH/p1IB/6pUAf+rVQH/tG4r/7Z3 + Pv+8hVT/rFYB/6tVAf+qVAH/qFIB/6RQAf+gTQH/m0kB/5xXHv+SWS7/vaSS//zv4f/46tv/6NjK/NfG + t1cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAADSwbI349LD+PPj0//049T/uKOU/4E5A/+WRQH/oVAG/6VRAf+qVQH/rVcB/69Z + Af+xWwH/slsB/8eSXf/JmWz/xZVp/7JcAf+yWwH/sVsB/7BaAf+uWAH/q1YB/6dTAf+kUgX/nEoB/4o+ + Af+9pJH/9+ja//Dfz//dybn3zbenNgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADSwrMO386/3/fo2f/67N7/rpF+/45KF/+/mHf/oE8D/6hU + Af+tWQH/sVsB/7NdAf+zXgH/tF4B/7ReAf+5ahT/vnYo/8eMSv+0XgH/tF4B/7ReAf+0XgH/s14B/7Fc + Af+vWgH/q1cB/6VSAf+1hVr/pGYz/7KSe//s18b/4su6/8yyod/ApZIOAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1MO0lfHh0v/77d//0cCz/343 + BP+YRwH/ql4V/76HUP+1czD/smAF/7RgAf+0YAH/tF8B/7NfAf+yXgH/sl0B/7FdAf+xXQH/sl0B/7Je + Af+zXwH/tF8B/7RgAf+zXwH/t3o8/7dzKv+5ejj/t3Qw/6FPAf+KQAP/yrKg/9zArf/Qsp7/uZqGlAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAyLSkKt/M + vPv05NX/7d7R/4JGHf+sc0b/o08C/6tXAv+3eTv/xppt/8KPW/+1YQL/tGAC/7NfAv+wXQL/rVoC/6tX + Av+rVwL/rFkC/65aAv+vXAL/sF0C/7JfAv+0YAL/vHUl/9Kuh//CjFP/tWkV/69bAv+pVgL/rm4y/45P + Hv/Psp7/y6mS/7iVfvuohG4pAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAMixoKXl0L//793N/6aHc/+RQAH/ok4C/6xYAv+yXgL/zaN0/8CMVP/CfzH/tWIC/7Nf + Av+tWQL/pFAB/5ZEAf+DPQb/hUQS/4pKFv+MSAv/nE0B/6lWAv+uWgL/sl4C/7RhAv+5bhj/yZNT/7ps + Ef+0YQL/sFwC/6pWAv+cSwL/poFm/8OdhP+4kHf/onpkpQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAALicihbLsJ354ci3/9nEtf+IRBT/r3I+/6pWAv+yXwL/tmMC/7tt + Df/AeCD/t2QC/7NhAv+sWAL/l0UB/45WL/+YbVP/n29Y/6BvWP+tgWr/wZ2I/72gi/+ld1L/mkwF/6xZ + Av+zYAL/tmMC/7hlAv+5ZgL/uGUC/7ViAv+wXQL/sWwo/5JME/+7ln//tYlv/6F1XvmVa1YWAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACyk35ty6yY/9e7qP+ifWb/mUQC/6hT + Av+xXgP/t2QD/7poA/+6aAP/uWcD/7ZkA/+vXAL/mUwL/7qYgf/MrZn/tY11/6FyWv+dbVX/rYFq/8Wk + j//exrX/8ODR/9fCr/+dVxf/r1sD/7VjA/+4ZgP/umgD/7ppA/+5ZwP/tWID/69cA/+hTgL/n3VX/7GD + af+kdV7/kWVRbQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAArIlzucSi + i//QsZz/lFs1/7F0P/+wXgn/tmMD/7ppA/+8awP/vGoD/7loA/+1YwP/pFMF/9S7pf/u3M7/28Kw/8Gd + h/+meGH/nGtU/66DbP/NrZr/6NPE//jq3P/77uH/28Wx/6NWDP+0YQP/uWcD/7tqA/+8awP/vGoD/7ln + A/+0YQP/tnQy/5leMP+1iXD/p3df/5JlUboAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAlnBcA6V9Z/O7k3v/uJaA/5A+Af+sVQL/tWED/7toA/++bQP/vm0D/71sA/+6aAP/tWED/76R + Zv/77uH/+eve/+3ay//TtqT/sYdw/5xrVP+yiHH/2L2r//Pk1v/67eD/8N3O/+DGtP+zhV//s18D/7ln + A/+8awP/vm0D/75tA/+8awP/uWYD/7JeA/+YRwL/sIdv/619ZP+YalXzjmNQBAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAI5lUiifc17/sIRr/6B0W/+sbDv/tGwl/7llBP++bAT/wHAF/8Bv + Bf++bQT/vGkE/69eB//bwq//7tzN//fp2//67N//69jJ/8Wjjv+fb1j/uJF7/+jUxf/5697/69bF/9W4 + o//Goov/u5R7/6tfDv+6ZwT/vmwE/8BvBf/AcAX/wG4F/71qBP+4ahP/s3Q6/6p/Yv+2iW3/pXde/5Rr + VikAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACJYE5KmGpV/6V1Xv+WX0H/q08D/7Zf + A/+9aQT/wG8E/8JyBP/CcQT/wG8E/71qBP+xbCf/yqmT/9K0oP/exLL/7NnJ//jp3P/n08P/q4Bp/8ak + kP/15tj/4Me0/8aii/+5kHb/tYpv/7WKcP+vbi//vGgE/8BuBP/AcAf/xIpB/791Fv/AbgT/u2cE/7Ja + A/+kcU7/wZl+/7OJbv+feGFLAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkWtaX5Fh + Tf+calT/lF0//65mKv+2cSv/vHUd/8iZYf/KoG3/wnUM/8JxBP+/bAT/r24w/66Baf+whWz/tYtz/72W + f//LqpX/4cq5/9K2o//XvKr/y6mT/7uSef+7k3r/v5iA/8Sehv/HpI3/vYdU/75pBP/CcAT/yYMl/9Gr + fP/Qm1T/v3YV/7p3K/+zbir/p3lX/8+slP/CnYT/qYZvXgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAIFbSmaLW0b/lWNN/5ddPP/Eejv/y4Y7/8uEKv/KmFr/07CG/8Z1Bf/FcwX/wm8F/69s + Lv+dbFT/nGtT/5trVP+cbFX/nm5Y/6R5ZP/CpZj/7NrM//Hi1f/v3s//7trK/+vXx//p1MP/6NLB/9Gi + cv/BbAX/xHIF/8Z8GP/JmV7/y5FC/8uCH//OjDz/yII7/7KCX//dwKv/0bGa/7KVgGYAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACUc2NhhldD/5BfSv+SUi7/t1YD/8BnBP/GcgX/z5ZJ/9Ki + Yf/JeAX/yHYF/8ZyBf+5cyn/nm9a/59yXf+jd2P/qYJw/7aWif/Ou7f/4c/F/+zXxv/99/L//fbx//32 + 7v/99er//PPn//zw4//Yo2r/xG8F/8d1Bf/JeAX/y34O/8p7Cv/IdgX/xG4F/7xgBP+velT/6tTA/93E + r//BqJVgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAk3JiUYNWQ/+PXkr/kVc6/7p0 + PP/CdB//yHMF/8t6Bv/MfAb/zHsG/8t5Bf/JdgX/xnUS/62Gcv+tiHf/tZWH/8KooP/TwsD/4dfW/+DH + tv/ixKz/+/Tu//338v/99/L//ffx//338P/99u7/zIIw/8hzBf/KeAX/zHsG/8x8Bv/Mewb/yngF/8V0 + EP++ezz/vJN3//Xj0v/m0r//xrCeUgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJZz + ZDGCVUT/kF9N/45WPv+4UwT/xGcF/8p0Bv/Newb/z38H/89+B//OfAb/zHkG/8p1Bv/GlGf/vqKX/8iy + rP/VxcT/4NbX/+PW0f/fwqz/3ruf//To3v/89/L//ffy//338v/99/L/7tO4/8dtBf/Ldwb/zXsG/85+ + B//Pfwf/zn0H/8x4Bv/IbwX/vV0E/8ikjf/77N3/6tnI/7+rmzQAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACSbmAIhVpK+5FiUP+XZVL/pEcG/8J8OP/Lcwb/z3wG/9GAB//RgQf/0X8G/9B8 + Bv/OeQb/znwZ/9K5q//Wx8b/39XV/+LZ2P/i0cb/3r6n/9y4m//s18f/+/Xw//338v/99/L/+vHo/9CC + LP/NdgX/z3sG/9B/Bv/RgAf/0YEH/9B/Bv/OeQb/xoAw/6teIP/k0cL/+u/g/+DRwf6rmIkQAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIZfT82SY1P/nnBf/6RdM//JZwz/zXIF/9F8 + Bv/TgQf/1IMH/9OCB//TgAb/0n4G/9B5Bv/ShS7/4dDG/+LZ2f/j2NP/4su9/928pP/ct5r/5cq1//fu + 5v/89/L/+vDm/9iSRf/Pdgb/0XwG/9J/Bv/Tggb/1IMH/9SCB//Sfwb/0HkG/8tsBf+wZzL//fXq//fu + 4f/Ar6HjAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDYlOSkGNU/5xv + X/+ZWjz/wVkF/8h9Lv/Segb/1YEH/9aECP/WhQj/1oQH/9WBB//Ufwf/0noG/9J7G//htpH/59nQ/+HI + t//du6L/3Lea/+HCqf/z5dr/7s2r/9aFJ//SeQb/1H4H/9SBB//Vgwf/1oUI/9aFCP/WhAf/1IAH/82D + J//Bahf/wZR4//z17P/x6d7/pJGErwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAbE9BT5x0Zv+gdmX/qH5r/65jM//QbhD/03YG/9Z/B//XhAf/1YQH/82aVP/Vgwn/14MH/9aB + B//Wfgf/03cG/9R7Gv/dmVP/36Jo/96iZ//enFb/14Qi/9R6Bv/Wfgf/1oAH/9eCB//Uhxb/0ZpN/9iG + B//Yhgf/2IQH/9Z/B//Tdgb/uXAz/+/j2//68+z/6d3T/31lWHIAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAGRIOwuMbmD0oXpq/62Jev+iZkj/x1sE/8qBNv/Wegb/2YIG/9ee + TP/atYP/zpxX/9iEBv/ahAf/2YIH/9mBB//YgAf/134H/9d8Bv/XfQf/134H/9iAB//ZgQf/2YIH/9mE + B//ahQf/3JIh/9exff/XlDD/2ocH/9mEB//SizD/yG8S/8OUdv/89e//9O3m/7Whlv9yWEosAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcFNHpa2Nf/+xkYX/upyQ/6dj + P//UbBT/1nIG/9J9FP/Yn1P/3q1q/9yoX//ciAj/3YcI/9yGCP/chAj/3IMI/9uCCP/bggj/24II/9uC + CP/bgwj/3IQI/9yFCP/chwj/3YgI/92JCP/ejhX/2pQs/9SOLP/bgQf/2HkH/7h7TP/37uf/+vLs/+vg + 1/97X1HYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGxP + Qz6eg3f/spWL/76lnf+9nZP/s00O/85qFf/drHn/234M/92DCf/ehgj/3ogI/96ICP/eiAj/3ocI/96G + CP/ehQj/24MH/9uDB//dhQj/3oYI/96HCP/eiAj/3okI/9+JCP/fiQj/3ogI/92FCP/hrWr/0oUr/7xi + Ef/m08f/+/Pt//Do4f+9o5b/d1RHegAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAfV1Sx7+mnP+/qKP/y7e0/8Gglf++elX/2GcK/9pxBv/YeAf/3oEH/9+F + B//fhgj/4IcI/+CHCP/ghwj/4IcI/9qRK//dljP/4IcI/+CHCP/giAj/4IgI/+CICP/ghwj/34YH/9qA + Cf/efwf/3HgG/8aKV//dxLX/+/Pt//Ts5f/i0cb/lWla94NaTBYAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIhnW0Kgf3T+yrWu/8u5t//Vxsb/yayl/7NP + F//RZxX/2Yc7/952Bv/dewf/4IAH/+GDB//hhAf/4YUI/+GFCP/fn0v/4JQt/+GFCP/hhgj/4YUI/+GF + B//hgwf/3X8H/999B//bkD//1XIS/7pfGv/gybv/+/Tt//bt5//p3NP/vJmH/5tvXpIAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAmHVqqpeF + fP/RwLv/08bG/9zR0v/Yx8X/s3Zc/8lTBP/WahL/2oIy/990B//beAv/4HwH/+F+CP/hfwj/3IQY/96W + P//hgAj/4X8I/+F+CP/bfA//4HkH/9yJN//YcBD/zFwF/7uEZv/u4Nf/+/Tt//Xt5v/p3tX/uKOW/6SC + b++lfmsVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAIdqXxZvVUnnnYqA/9rMx//Xzc3/4NfX/+Tb2v/Ip53/s25N/8lRBP/WZRD/3YE2/99s + Bv/YeyP/4HIG/9x8Hv/il0z/4HMH/9eAKv/fcAb/3oU2/9dqEP/LVgX/uHdU/9i6rP/89e//+vPt//Lq + 4//o3dT/wq+h/6+KYf+vjHRkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYEY5mnhZSf+Vgnn/4tTO/9nPzf/f1dX/4tnY/+Ta + 1v/KrJ//uH9l/7RPGv++SQT/03M2/9pcBf/Zaxz/34lL/9teBf/Udjf/v0wE/7VSG/+/iG3/17yu//rz + 7v/79fD/+PHr/+zk3f/q3dP/vKeZ/7SUcv/SqXPiAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFhANJiSdGP/k3Jg/4ly + aP/bzcf/5NjS/9vRzf/f1M7/4dLJ/9/Kvv/dwK7/0KmS/72McP+3fV7/t3ZU/7l8XP+3e1n/vIdm/9Ko + i//lyLH/69fG//Hj2P/z6+P/7+nj/+vh2f/p2M3/n4d3/7eScv/k0L7/0ql03AAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AABdQDWXmHlp/6+SgP+lgm7/jW5e/7qnof/t3dL/6dvR/+HQxv/axLf/17qn/9SxmP/UrZD/1KmJ/8CY + eP+gfWP/0qWB/9Kkgf/VrIz/27ui/+DItv/j0sX/697U/+vb0P/FsaT/jWdR/7B+XP/Xu6P/6tnL/9Kt + fdoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAaz40lqN9bP+9opD/y7Oi/8GjkP+Ubl3/nIyA/97Iuv/jzb//6dXH/+nU + xv/lzbz/38Kt/9y8pP/Sspn/xaaP/9e0mf/ZuJ7/3sCq/+fQv//v3tH/79/U/97Iu/+okIL/ZTwr/6Fo + TP/Cm4H/3MKu/+3e0v/VtI7YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHY/M5aqg2//yrCh/9jBs//Vvq//nnpp/9vI + vPneybz/2MCx/9K2pf/Kq5f/xaOO/8ajjf/IpI//yaaT/8+vnP/gybr/7N3S/+ze0//p29H/59nO/+TU + yf/Zw7f/y6+g/2dEN/+ue1z/zauV/+bRwP/w5Nn/2Lic2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB9RjSWroZ0/9O7 + rv/hzsL/3su//6SCc/+zmo4w2MK0htW8rebRtaT/yquX/8KeiP+4j3b/rn9m/6VzW/+re2P/yKiV/+LP + w//m1sv/5tbK/+TTx//i0MP/1L6w2bKWh29mPjHcv5N0/9e8qf/u3c//8+je/9y9pNgAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAgk46lrKNfP/Yw7n/6drQ/+PTyf+jhHb/kXZqFgAAAADRt6cCzbCeO8amkn67lX20q35j3J1o + TviUWEL/mmFH/7qSev/Wv7D53Mq93NvJvbHZx7p61MK2MgAAAAAAAAAAbkUz1cqih//hy7v/8+bb//Xr + 4v/fwarYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + 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 + vP/nzbX/48at/+PFq//nya7/48Kl/9m1mv/Us5vA1LijGwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACndlk+q3RSw7R4VP++iWT/xpVz/8qb + ef/Mn3z/z6J//9Glg//TqYf/1a2N/9iwkv/WrY3/z6B9/8qcet7Lo4ZhzKqQAQAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACmb0w2qGxEkqxuRti1eFD+uoBZ/72GYf/AimX/wYpm/8KKZP++hmDnvYVfpb6NaE7Bk3IEAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAArXVPDbN9Vyq2f1k6uIJcOrmFYTG6hWEVAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA///////////////AA////////gAAf//////4AAAf//////AAAA//////4AAAB//////AAAAD + /////4AAAAH/////AAAAAP////4AAAAAf////gAAAAB////8AAAAAD////wAAAAAP///+AAAAAAf///4 + AAAAAB////gAAAAAH///8AAAAAAP///wAAAAAA////AAAAAAD///8AAAAAAP///wAAAAAA////AAAAAA + D///8AAAAAAP///wAAAAAA////AAAAAAD///+AAAAAAf///4AAAAAB////gAAAAAH///+AAAAAAf///8 + AAAAAD////wAAAAAP////gAAAAA////+AAAAAH////8AAAAAf////wAAAAD/////gAAAAf////+AAAAB + /////4AAAAH/////gAAAAf////+AAAAB/////4AAAAH/////gIABgf////+A/j+B/////4D//4H///// + gP//gf////+A//+B/////4D//4H/////gP//gf////+A//+B/////4D//wH/////gP//Af////+Af/8B + /////8B//gH/////wD/8A//////AH/gD/////+AH4Af/////8AAAB//////wAAAP//////gAAB////// + /AAAP///////AAB////////AAf////////gf//////////////8= + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/PasswordForm.Designer.cs b/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/PasswordForm.Designer.cs new file mode 100644 index 0000000..aa730b3 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/PasswordForm.Designer.cs @@ -0,0 +1,97 @@ +namespace AutoFileCryptTool +{ + partial class PasswordForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(PasswordForm)); + this.label_InputPrompt = new System.Windows.Forms.Label(); + this.textBox_PassPhrase = new System.Windows.Forms.TextBox(); + this.button_Apply = new System.Windows.Forms.Button(); + this.openFileDialog1 = new System.Windows.Forms.OpenFileDialog(); + this.folderBrowserDialog1 = new System.Windows.Forms.FolderBrowserDialog(); + this.SuspendLayout(); + // + // label_InputPrompt + // + this.label_InputPrompt.AutoSize = true; + this.label_InputPrompt.Location = new System.Drawing.Point(20, 8); + this.label_InputPrompt.Name = "label_InputPrompt"; + this.label_InputPrompt.Size = new System.Drawing.Size(214, 13); + this.label_InputPrompt.TabIndex = 0; + this.label_InputPrompt.Text = "Set up the passphrase for the file encryption"; + // + // textBox_PassPhrase + // + this.textBox_PassPhrase.Location = new System.Drawing.Point(23, 33); + this.textBox_PassPhrase.Name = "textBox_PassPhrase"; + this.textBox_PassPhrase.ScrollBars = System.Windows.Forms.ScrollBars.Horizontal; + this.textBox_PassPhrase.Size = new System.Drawing.Size(446, 20); + this.textBox_PassPhrase.TabIndex = 1; + this.textBox_PassPhrase.Text = "password"; + // + // button_Apply + // + this.button_Apply.DialogResult = System.Windows.Forms.DialogResult.OK; + this.button_Apply.Location = new System.Drawing.Point(394, 81); + this.button_Apply.Name = "button_Apply"; + this.button_Apply.Size = new System.Drawing.Size(75, 20); + this.button_Apply.TabIndex = 2; + this.button_Apply.Text = "Apply"; + this.button_Apply.UseVisualStyleBackColor = true; + this.button_Apply.Click += new System.EventHandler(this.button_Ok_Click); + // + // openFileDialog1 + // + this.openFileDialog1.FileName = "openFileDialog1"; + // + // PasswordForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(514, 113); + this.Controls.Add(this.button_Apply); + this.Controls.Add(this.textBox_PassPhrase); + this.Controls.Add(this.label_InputPrompt); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Name = "PasswordForm"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "Password Setup "; + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Label label_InputPrompt; + private System.Windows.Forms.TextBox textBox_PassPhrase; + private System.Windows.Forms.Button button_Apply; + private System.Windows.Forms.OpenFileDialog openFileDialog1; + private System.Windows.Forms.FolderBrowserDialog folderBrowserDialog1; + } +} \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/PasswordForm.cs b/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/PasswordForm.cs new file mode 100644 index 0000000..a82798d --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/PasswordForm.cs @@ -0,0 +1,43 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; + +namespace AutoFileCryptTool +{ + public partial class PasswordForm : Form + { + public string PassPhrase = string.Empty; + + public PasswordForm() + { + InitializeComponent(); + } + + private void button_Ok_Click(object sender, EventArgs e) + { + PassPhrase = textBox_PassPhrase.Text; + } + + } +} diff --git a/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/PasswordForm.resx b/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/PasswordForm.resx new file mode 100644 index 0000000..c749c4f --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/PasswordForm.resx @@ -0,0 +1,576 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + + 147, 17 + + + + + AAABAAgAEBAAAAEACABoBQAAhgAAABAQAAABACAAaAQAAO4FAAAYGAAAAQAIAMgGAABWCgAAGBgAAAEA + IACICQAAHhEAACAgAAABAAgAqAgAAKYaAAAgIAAAAQAgAKgQAABOIwAAMDAAAAEACACoDgAA9jMAADAw + AAABACAAqCUAAJ5CAAAoAAAAEAAAACAAAAABAAgAAAAAAEABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP// + /wAAzf8AmXtrAImb/gDdu6kAOljoAGP4/wDH0f0App6/AEme/wD14tkAocD+ANTG0AA87P8AfpjYAE5x + /wCrnpgA4+j/AGaN/wC1r9cAHeX/ALCOfQBfs/8AOoL/AMCoowD69OkAbeL/AE1m4wBbmvEAlpPIANvE + vAC1t8QAptH/AKadqQDx8vsA4c/KAKeCcABX7f8AV2fuAKez/wBdm/8AYOH/APz59ACtvf4Ag5H+APjt + 2gBDe/8A8OjgALKbnwDbv7MAnpfDAFSX/wCph3gA9/j/AEua+ABar/oA+vHiANvHwwCdf28A18zPAJt3 + ZgDcuqMA+vj6APz27gDcvq4Aon9vAP37+ACXeWcA28G3APT1+wBb7f8Aps3/AJx9bADewbQA+fTuAPry + 5gDevqsA3sS6AKuJegDauKUArIh3ANq6qAD39vsAmXtoAPnv4AD79ewA27ytANzCtQD9+vYA/PfwAK+O + fwDcuaUA3LunANu6qgDcv7EA28K5ANvFvgDbxsEA+vHkAN6+rQCafGoAnX5tAKOAcAD79eoA272vAJh5 + aACZemoAm3xrAJx8bQD79OgA+vPoALGOfgDcvKkA2ruqANvAtADbw7oA/fv5AJp8awCbfGwA/PnzAJx9 + bQCcfm0A/PbtAPrz5wD68+YA3LqlANy7qQDbuqkA3cK1ANu/sgDbv7QA28fCANvCuADbw7sAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAGxmenp6eUlsbGVUbAAAAAA9ARoaGm98TGNVLkQAAAAAQgGBgVhfQX9+Pjlq + AAAAAGcBhnSFMmlyUFx9awAAAAA1AYRiH0WCV1JdbgMAAAAATwE6hGFgc2mAcWh2AAAAAFs2DTwkYINp + XgVWbAAAAAAiKC0hCFNDWXhae3cAAAAADzQ4NycUTkpkTUBtAAAAAAYqFUcXDEZDK0swOwAAAAAdJgIO + GAQjdSUlJSUAAAAAHAoHGy8sP3UlC3ARAAAAAB4TKRBIEgEBJXARAAAAAAAZIDMJMRZRUSURAAAAAAAA + AAAAAAAAAAAAAAAAAAD//wAAwAMAAMADAADAAwAAwAMAAMADAADAAwAAwAMAAMADAADAAwAAwAMAAMAD + AADAAwAAwAcAAMAPAAD//wAAKAAAABAAAAAgAAAAAQAgAAAAAABABAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAJt8a/+dfm3/nH5t/5x+bf+cfm3/nH1t/5x9bP+bfGv/m3xr/5p8av+Ze2j/m3xr/wAA + AAAAAAAAAAAAAAAAAACbd2b///////r06f/69On/+vTp//rz6P/68+f/+vLm//rx5P/57+D/+O3a/5d5 + Z/8AAAAAAAAAAAAAAAAAAAAAon9v///////dwrX/3cK1/9zCtf/cv7H/3L6u/9y7qf/cuqX/3Lqj//rx + 4v+YeWj/AAAAAAAAAAAAAAAAAAAAAKOAcP//////28O7/9vDuv/bwrj/27+z/9u9r//au6r/2ril/9y5 + pf/68+b/mXpq/wAAAAAAAAAAAAAAAAAAAACph3j//////9vHwv/bxsH/28S8/9vBt//bv7L/27yt/9q6 + qP/cu6f/+/To/5l7a/8AAAAAAAAAAAAAAAAAAAAAq4l6///////bx8P/28fC/9vFvv/bwrn/28C0/9u9 + r//buqn/3Lyp//v16v+afGv/AAAAAAAAAAAAAAAAAAAAAK+Of//3+P//1MbQ/9fMz//hz8r/28K5/9u/ + tP/bva//27qq/927qf/79ez/m3xr/wAAAAAAAAAAAAAAAAAA/wGmnan/p7P//4OR/v+m0f//x9H9//f2 + +//9+/j//fr2//z58//89/D//Pbt/5t8bP8AAAAAAAAAAAAAAAAAKf8XfpjY/1SX//9ar/r/S5r4/1dn + 7v+1r9f/3sS6/97BtP/evq3/3r6r//z27v+cfG3/AAAAAAAAAAAAAAAAACz/NzpY6P9g4f//HeX//1vt + //9fs///ocD+//T1+//9+/j//Pn0//n07v/w6OD/n4Bw/gAAAAAAAAAAAAAAAAAu/0FbmvH/V+3//wDN + //887P//OoL//4mb/v/x8vv//fv5/6eCcP+ngnD/p4Jw/6eCcP8AAAAAAAAAAAAAAAA3fv8zTWbj/0me + //9j+P//beL//0N7//+tvf7/+vj6//37+f+ngnD/9eLZ/7GOfv+ngnBYAAAAAAAAAAAAAAAAABf/CJaT + yP9mjf//XZv//05x//+mzf//4+j/////////////p4Jw/7GOfv+ngnBYAAAAAAAAAAAAAAAAAAAAAAAA + AADAqKP/tbfE/56Xw/+mnr//spuf/7COff+siHf/rIh3/6eCcP+ngnBYAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAD//wAAwAMAAMADAADAAwAAwAMAAMADAADAAwAAwAMAAMADAADAAwAAwAMAAMADAADAAwAAwAcAAMAP + AAD//wAAKAAAABgAAAAwAAAAAQAIAAAAAACgAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8AKF31AKJ6 + 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 + ///9+/n/3MjD/9zIxP/cx8L/28W//9vEvf/bwbn/28C2/9u/sv/bva//27ur/9u5p//evar/+/bt//zz + 5/+Uc2D/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAApYRz//j5///p7Pv/xLbJ/8S5yf/Pwcb/2sO//9zE + vP/bwrn/28G1/9u+s//bva//27ur/9u5qP/evar//ffu//716P+Wc2L/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAP8BmH2C/8bR//+wv/7/mKDq/6PK8P+qr+f/wsLj/+LY3f/t39n/7N7X/+zd1f/s29L/7NrP/+vZ + zf/t2cz//Pfv//306f+Vc2H/AAAAAAAAAAAAAAAAAAAAAAAAAAAANf8di56x/4GR//9OdP//P17//37M + //9edv//mKz+/8bR/f/z9Pv//vz6//37+P/9+vb//fn0//z48v/8+PH//Pjw//326/+XdGP/AAAAAAAA + AAAAAAAAAAAAAAAx/wsALf8/WG3G/33U//88hv//UaT6/2PY/f8ravb/PV/w/4iO3P+5rc3/3sa+/9/F + uv/fw7b/38Cy/9+/rv/gwa///fjw//326/+WdGP/AAAAAAAAAAAAAAAAAAAAAAAx/x8AMP9dLEbc/0Oc + //9g6v//VOz//0fd/v9gwPv/KF31/2WK6/+lrtP/07u7/9zAtP/bvbD/3Lys/9y5qf/fvqv//fry//31 + 7P+YdWP/AAAAAAAAAAAAAAAAAAAAAAAz/y0AMf94JVXl/2vO//8s2///AMr//wTQ//9X6P//c9///12V + //+ruP//6ez8///9+//6+PX/9vLt//Ps5//s5N//4dbQ/8m1qf+NaFftAAAAAAAAAAAAAAAAAAAAAAAs + /y8AJv97QYDr/1TW//8o3f//AMr//wLP//9u7P//PY///0Ro//+puv//6Oz8/////v/Ktar/nHpp/6qL + eP+ohGr/onpc/4ZgT/OQZ1ZBAAAAAAAAAAAAAAAAAAAAACBb/ytkt/+NUYzp/0SW//909f//Ld///z7j + //9Qxv//LWz//1d4//+2xP7/8PH7/////f/Vx77/zLWj//zpxf/wzJL/m3Rc85ZpXDoAAAAAAAAAAAAA + AAAAAAAAAAAAAAAv/xAALP9GR1HI/0SC//9Mof//Ucr//2PC//9oyf//WJT//4uf/v/L1f3//Pr6///+ + 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 + AA/gAAAfwAAAP+AAAH/wAAD/8AAB//AAA//wAAf/8AAP//////8oAAAAIAAAAEAAAAABACAAAAAAAIAQ + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAhGFQ/4ZhUP+EYE//hGBP/4Rg + T/+EYE//hGBP/4NgT/+DYE//g2BP/4NfTv+CX07/gl9O/4FfTv+BXk3/gF5N/4BdTv9/XUz/f11N/35c + S/9+XEz/fVtL/35dTf97W0v/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACFYVD/+OTT//Le + zP/y3sz/8t7M//LezP/y3sz/8t7M//LezP/y38z/8t3M//Ldy//y3cv/8t7K//Lcyv/y3Mf/89vH//Ha + xP/x2cL/8tjA//DXvv/x1r3/9dm9/3xbS/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIZh + UP///fL/+vTo//rz6f/68+n/+vPp//rz6f/68+n/+vPo//r06P/68uj/+vLn//ry5//68+b/+vHm//ry + 5f/68uT/+fHi//nw4P/5797/+Ozb//nt2f/03MT/e1pJ/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAhmFQ///+9f/79ur/+/Xs//v16//79ev/+/Xr//v17P/79er/+/bq//v06//79On/+/Tq//v1 + 6P/78+n/+/Pn//z05v/68uX/+vHl//nw4f/57+D/+vDe//Texv99W0r/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACHY1H///73//v17P/89uz/3sS3/97Ft//exbf/3sS3/93Dtf/dw7X/3cKz/93B + sv/dwbD/3b+u/92+q//dvar/3byo/926pf/duqX/376p//rx4v/68OH/89/J/3xbSv8AAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAIhiUf////f//Pbt//z27v/bwLT/28C0/9vAtP/bwLT/28Cz/9u/ + sv/bvrH/272u/9q7rP/auqr/2rmo/9q3pf/atqL/2rWg/9q1oP/duqT/+vLl//vz5P/14Mz/fVxL/wAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAiWNS////+v/89+///Pfv/9vCuP/bwrj/28K4/9vC + t//bwrb/28C1/9u/sv/bvrH/272v/9u8rP/auqr/2rmm/9q3pP/atqH/2rah/927pf/78+b/+/Tn//Ti + zv9+W0z/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACKZFP////6//z48P/8+PH/28O7/9vE + u//bxLv/28O7/9vDuf/bwrj/28C2/9u/s//bvrH/272u/9u8rP/auaj/2ril/9q3o//at6P/3bun//vz + 5//89ej/9uPS/4BdS/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAItlU/////v//Pjy//z4 + 8v/bxr7/28a//9vGv//bxL7/28S8/9vDuv/bwbf/28C1/9u+s//bva//27ys/9u7qv/buqj/2rek/9q3 + pP/dvaj/+/To//z06f/15NP/f1xN/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjGdU//// + /v/9+fP//fn0/9vHwv/bx8P/28fD/9vGwv/bxb//28S8/9vDuv/bwbf/27+z/9u+sf/bvK//27ur/9u6 + qP/buKX/27il/929qv/79On//Pbq//Xk0v+AXkz/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACPZlX///////369f/9+vX/28jD/9vIxP/byMT/28jC/9vGwP/bxL3/28O6/9vCuP/bwLX/276y/9u9 + r//bu6z/27qp/9u5p//buaf/3r6q//v16v/89ev/9eTT/4JdTP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAI9nVP///////fr2//379//bx8P/28fE/9vHxP/bx8P/28bA/9vFvv/bxLv/28K4/9vA + tf/bv7P/272v/9u8rP/buqr/27im/9u4pv/evqv/+/Xr//z17P/15NT/gV9O/wAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAkWhV///////9+/j//fv4/9zHwv/bxsP/28bD/9vGwf/bxcD/28S9/9vD + u//bwbn/28C1/9u/sv/bvrD/27yt/9u6qv/buKf/27in/969q//79ez//Pft//Xl1v+DXk3/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACSaVf///////78+f/+/Pr/2sTA/9rEwP/cxsD/3MbA/9zF + v//cxL3/28O6/9vCt//bwLX/276y/9u9r//bvK3/27qq/9u5p//buaf/3r2r//z27f/89u3/9eXV/4Ng + Tf8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJNqVv/4+f//6Ov7/9rh/P+4r8r/uK3K/7/B + zv/Ht8T/1b/A/9zEu//cw7r/28G3/9vAtP/bvrL/272v/9u8rf/bu6r/27mn/9u5p//evar//Pbt//z2 + 7v/15df/hF9P/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8BiGhk/9Ha//++yf3/ssH+/6u7 + /v+qs/7/vvP+/73F/v/O1/3/5+v7//37+//+/Pr//fv5//379//9+vb//fr1//359P/8+PL//Pjx//z3 + 7//89u7//fjv//fm1v+EX07/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACh4/yB7c4r/rbf//4ue + /v9phP//V3H//1l9//+a4///iJX+/6q6/v/Dzv3/4eb8//37+//+/Pn//fv4//379//9+vb//fn0//35 + 8//8+PH//Pfw//z37//99+//9ubY/4VhTv8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANv8RACT/OIms + t/98q///P1f//0WD//8qVPb/Yrj6/1+m+f81TvL/Wm/q/46T3P+rptL/zbzH/9/Hvf/fxbv/38O4/9/B + tP/fwLH/37+s/9+/rP/hwrD//Pfv//338P/25tj/hWBQ/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AwA1 + /ysAMP9QQj63/5z7//9SpP//RZf//1ix+v9j8P7/O4v4/zR69v8wVvP/Wm3n/5SV1f+zqMj/2L+6/9zA + tf/bvrL/272v/9u6qv/buaf/27mn/96+q//89+///ffw//bm1/+GYE//AAAAAAAAAAAAAAAAAAAAAAAA + AAAAQv8PADb/PAAw/2wnPNX/K2f//2b///995///ZfT//0jt//9w1/z/bcn7/ylS9P81SfD/d3vd/6eo + z//Mtr7/3MC1/9u+sv/bva//27qq/9u5p//buaf/3r6r//348f/9+PH/9+fZ/4ZhUP8AAAAAAAAAAAAA + AAAAAAAAAAAAAAA2/xsAM/9HAC7/iiNQ3v9XrP//etT//yjg//8Azv//As///1bw//9bxf//Zdv//6D9 + //+V2P//s8n+/9/l/P/+/Pr///35//79+f///fn///33//779//9+PP/+fXt//Xw6P/p1sj/h2JQ/AAA + AAAAAAAAAAAAAAAAAAAAAAAAADX/IQAy/0wALv+aHz/e/zyP//9h6///AM7//wDL//8Ayv//DdT//0ri + //9Mqv//MVz//1tv//+uvP7/2eD8//78+v///fv/5tzX/9nLwv/g08z/2szF/9XFvv/Itq3/u6Sa/5d1 + Zf+GYlG2AAAAAAAAAAAAAAAAAAAAAAAAAAAAMv8gACb/TAAY/5k9euf/XN7//0jw//8K0v//AMv//wDK + //8Z2P//gf3//0+o//8yY///XXv//66//v/Z4Pz//vz6//////+7opX/oYBy/6eJeP+lg2//o39n/7CI + Zv+TbFT/imRTxIZfSw4AAAAAAAAAAAAAAAAAAAAAAAAAAABD/xllvP9qiun/vHTA7v9Uqf//bMX//0Ps + //8Q1P//FdX//z/q//9Nq///NIf//zRl//9xi///tcP+/+Ln/P/+/Pr//////8u3rf/FrZ////Xg//nh + u//41pz/xZ5u/4ljU8GMXV8MAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC//DAAm/zkAH/9lLTfQ/zBd + //+L7v//c8z//0rl//9/////Xcf//4D///8uZP//Q2P//5Oo/v/Czv3/7/L7//78+v////z/zLqw/76h + i//237j/88+W/8CYav+IYlTPi2RODgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8BADP/JgAw + /0pNUK7/QGv//zBa//9Yvv//VcD//3XP//8pav//WKT//5Tq//92gv//sL7+/9Xd/P/8+vr//vz5///+ + /P/XycH/so1y//bTmv/In27/iWRVzJ1uXhIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAOv8LADf/MmtdkP9/lv//Sl7+/4/o//88dP//M2r//zZn//9HX///hbD//7Xi/v/J0f3/8PD7//78 + +v/9+/j////7/9PCuf+3kGr/y6Fv/4tkVM2VYlIRAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAOv8QfWR7/7bE//+bpP3/q/b+/2x5/v9shf7/fZX+/5ms/v+yvf3/ydn9/+rt + +//+/Pr//fv5//379////vv/zrqx/6J5Wv+PaVbWnXFZGQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACVb2T/2uL//8jQ///B7f//tb7//7XD//+7yP//xtL//9jf + ///y9P////////////////////////////+zl4n/j2dV1KFtYhcAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJpxXf+ccmD/lHBm/5B0cf+IanD/h2px/4pr + a/+QbWT/l25b/5dtW/+Wbln/lWxa/5RrWf+Talj/k2xZ/45nVbmTblUWAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/////wAAAP8AAAD/AAAA/wAAAP8AAAD/AA + AA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/gAAAP4AAAD+AA + AA/gAAAP4AAAH8AAAD/gAAB/8AAA//AAAf/wAAP/8AAH//AAD///////KAAAADAAAABgAAAAAQAIAAAA + AACACgAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8AMFz/ALCIZgBm7/8AqKXUAADL/wD41pwAZlyPAHaC + /wCt3/0AellJAEI+twDn3tgAvaSZAFCv/gBzg8kAVm7WAHq46ACbpP0AIETcADHe/wDbwbYAg2V1AIms + twAsg/8AltnhAN/l/ADNomwAt7vvAJX6/wBScv4Av8HOAPnhuwCNktwA/fLeAGHH/QCTbFQARun/AID+ + /wAvaeQAeq39AImRmwBw1f8AydP+AI7E3QBnec8A2rWfAISV+ACa4/8AR1//ADVJ8ABETLQARlTeALKW + igBwf+QAyretABPS/wCWem0ALTfQAFZ76wB76f8ApX5dAPDy/QA3d/8AX6b5AFKV9QCoinsA+OTTAF3i + /wC+8/4A3c7GALmwzwAfV+EAKnH+AESG+wDMtr4AZMP7AHpgeQD79/IA6dXFAKv2/gCE8P8Ap7P3AGW4 + /wBm//8AhmFPACdT7gDDmGcAxKWJAJBtZAClf2cAxK6gAN++qQDqz7sAwcn4AGx5/gAyev0ANmb+APbw + 5wCyjXIAVun/ANPb/QD14sMASeX/AFuw/QBYgP4Ak87+AEBf4QCacV0A1MHDAGeD/gAL0f8A8+reAD9X + /wAzkv8AoYByALTQ/gB8k/wAz8DJAIHX/QDmzLoA8MqNAN/QygBylP8Ahbz/AOjo9wC4j2UAccz7AEBo + /wBm2f8Ah6D/AIhoXQCbdWUAWJ3/AJaX1wCQdHEAJ0HUAPn5/QCU6v8Alaj8ALOoyACLZVQA+vHrAP78 + +ADmyLIAzbqxADRc8gA7i/gAq7r8AMva/QDTwrkAyLjGACxl+gBVwP8AgV1MANu5pwDbva4A9+3jAKCv + +QBZr/8AkXNnAMGceADL6v4A+ufJAMTN+wDZ4f4A28W/AP37+QBI7/8AaXXNAJZtWQBSpP8A4Ma3ALXE + /gDx2cIApYNxANLa/gDcyr8A8ufbAO7ezwBtyfsAQWL9AIppbABd6f8ABM//ADlV7AD19fsAlm5iAI/o + /wDVxb4AuJ+TAKCd0wD58+0A28O7ABDS/wDcyMMA2L+6AK+//wD//vsAH9j/APXZvQD02rAA0NT1AJFo + VQCUc2UAafP/AN/EtACtt/8A/Pn1AD3j/wBbb/8Aof//AFx7/gCEX00A9ezfADFp/wCPeW4A27urAFSp + /wC7xPsANWD/APrw6ADz050A3rylAODArgB/W0sAiWNSAJxyYADa4fwAxdD/ALvH/gAoZvsAjXBjAOru + /QDj5vkAWm3nAE+o/wDbuKQAW7r/ANu/sgB30P8AssH+AJNqVwD89uwASl7+APDk1gDz38oA89zHANng + /wBqh/8A//3yAMifbgDv4tMA37+sAN28qAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + 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 + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAhWFQ/4RhUf+DYE//g19P/4Nf + T/+DX0//g19P/4NfT/+CX0//gl9P/4JfT/+CYE//gl5O/4JeTv+CXk7/gV5O/4FeTv+BXk7/gV9O/4Bd + Tf+AXU3/gF1N/39eTf9/XE3/f1xM/35cTP9+XUz/fltM/31bS/99XEv/fFpK/3xbSv97W0r/e1tL/3tb + S/97W0z/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgFxL/+7R + u//rzrn/6s25/+rNuf/qzbn/6s25/+rNuv/qzbr/6s26/+rNuf/qzbn/6s25/+rNuf/qzrn/6865/+nO + uP/pzbj/6c24/+nNt//qzbf/6s23/+rMt//qzLb/6cy2/+nLtf/py7T/6cu0/+nLs//oy7P/6Mqz/+jK + sv/oyrH/58mx/+vLsv92Vkj/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAf1xL/+rUwv/m0L//5tC//+bQv//n0L//59C//+fQwP/n0MD/59DA/+fQv//m0L//5tC//+bQ + v//m0L//5tC//+bQvv/mz77/5s++/+bPvf/mz73/5c+9/+XPvP/lzrz/5c67/+XOu//lzbr/5M26/+TN + uf/kzLn/5My4/+TMt//ky7f/5My3/+XIsP93VUb/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAgFpJ//Dez//s2sv/7NrM/+zazP/s28z/7NvM/+zbzP/s28z/7NvM/+zb + zP/s2sz/7NrM/+zay//s2sv/69rL/+vay//r2sr/69nK/+vZyv/r2cn/69nJ/+vYyP/q2Mj/6tjH/+rX + x//q18b/6tfG/+nWxf/p1sT/6dbE/+nVw//o1sP/5tC8/+bJsf92V0f/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgVxK//Tl2P/z6d3/8uje//Lo3v/y6N7/8ujd//Lo + 3f/y6N3/8ujd//Lo3f/y6N7/8uje//Lo3v/y6Nz/8ujd//Lp3f/y59z/8ufc//Pn3P/x6Nv/8ebb//Hm + 2v/x59r/8uXZ//Dl2P/w5tj/8OTX//Hl1f/v49b/7+PV//Dk1P/t3s3/59C8/+XIsf94Vkf/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgltK//Xn2v/38Oj/9u/n//bx + 5v/28ej/38e4/9/Huf/fx7n/38e4/9/HuP/fxrj/38a4/9/Gt//fxbf/38S1/9/EtP/fxLP/38O0/9/D + sf/fw7H/38Gu/9/Arv/fwK3/38Cr/96+q//ev6n/3r2m/967pf/hxKv/8+re//Tr3v/t4ND/5tC9/+XK + s/95WEf/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAglxL//Tm + 2v/38ej/9/Do//fw6P/38Oj/2r6x/9q+sf/avrH/2r6x/9q+sP/avrD/2r6w/9q9r//ava7/2r2t/9q8 + rf/avKz/2rqr/9q6qf/auaj/2rmm/9q4pP/at6P/2rei/9q2oP/atp//2bSd/9mzm//evKX/9Ove//Pr + 3v/t39D/5tG+/+fJsv95V0j/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAg15L//Tn2//48un/9/Hp//fx6f/38en/28Cz/9vAs//bwLP/28Cz/9vAs//bwLL/27+y/9u/ + sf/avrD/2r2v/9q9rv/avK3/2ryr/9q7q//auqr/2rmn/9q4pv/auKT/2rej/9q3ov/atqD/2rWe/9m0 + nf/evab/9Ovf//Xs3//v4dL/5tG//+bLs/96V0j/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAhF1K//bo3P/48uz/+PLq//jy6v/48ur/28G1/9vBtv/bwbb/28G1/9vB + tf/bwLX/28C0/9vAs//bv7P/27+x/9u+sP/bvq//2ryt/9q7q//au6r/2rqp/9q5qP/auKb/2rek/9q3 + ov/atqL/2raf/9q1nf/fvqj/9Ozg//Ts4P/u4NH/59LA/+bKtP96WUj/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAhV9M//Xq3//48+z/+PPr//jz7P/48+z/28K3/9vC + uP/bw7j/28K4/9vCt//bwrb/28K1/9vAtP/bwLT/27+z/9u/sf/bvrD/272u/9u9rf/au6z/2ruq/9q6 + qf/auaf/2rim/9q3pP/atqL/2rah/9q1n//fvqn/9ezh//Tt4f/u4tL/59LA/+bMtv97WEn/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAh15L//fp3//59O3/+PPt//nz + 7f/59O3/28O6/9vDuv/bw7r/28O6/9vDuf/bw7j/28K3/9vCt//bwLb/28C0/9u/sv/bvrH/276w/9u9 + r//bvK3/27yr/9q6qv/auqj/2rmm/9q4pf/at6P/2rah/9q1oP/fvqn/9e3i//bt4v/w4dP/59PB/+jL + tf97Wkj/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAhmBN//bq + 4P/59e7/+fTu//n07v/59O7/28S7/9vEvP/bxLz/28S8/9vEu//bw7r/28O6/9vCuf/bwrf/28C2/9u/ + tP/bv7P/276x/9u9r//bva7/27yt/9u8q//bu6n/2rmn/9q5pv/auKT/2rai/9q2oP/fv6r/9e3j//Xu + 4//v49X/6NPC/+fLtv98WUj/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAhmBN//br4f/69fH/+fXv//n17//59fD/28S+/9vFvv/bxb7/28W+/9vEvf/bxLz/28O7/9vD + uf/bwrj/28G3/9vBtv/bv7T/276y/9u+sf/bva7/27yt/9u8rP/bu6v/27qo/9q5p//auKX/2rej/9q2 + ov/fv6v/9e7k//Xu5P/v4tT/6NPC/+fLuP98WUj/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAh19M//fs4v/69vH/+vbw//r28f/69vH/28bA/9vGwP/bxsH/28bA/9vG + v//bxb7/28W8/9vDu//bwrr/28K4/9vBtv/bwLX/28Cz/9u+sv/bvbD/272u/9u8rP/bu6v/27up/9u6 + p//auKb/2rik/9q3ov/fv6z/9u7k//Xv5f/v5NX/6NTD/+fNt/98WUr/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAiGFO//fs4//69/L/+vby//r28v/69/L/28bC/9vH + w//bx8P/28fC/9vGwf/bxsD/28W+/9vEvf/bxLv/28O6/9vBt//bwLb/28C0/9u/sv/bvrH/272v/9u8 + rf/bu6v/27uq/9u6qP/buaf/2rik/9q3o//fwKz/9u/l//fv5f/x49b/6NTE/+fMuf99W0n/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAiWBN//jt5P/7+PP//Pfz//v3 + 8//79/P/28jC/9vIxP/bycT/28jD/9vIwv/bx8H/28a+/9vFvf/bxLv/28O6/9vCuf/bwrf/28G1/9u/ + s//bvrH/276w/9u8rv/bu6z/27ur/9u6qP/buaf/27ml/9q3o//fwKz/9u/m//bw5v/w49j/6dTE/+fO + uv99Wkn/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAi2FP//ju + 5f/7+PT/+/j0//v49P/7+PX/28jD/9vIxP/bycX/28jE/9vHw//bx8H/28a//9vFvv/bxbz/28S6/9vC + uf/bwrf/28G2/9vAtP/bvrL/276w/9u9rv/bvK3/27ur/9u6qf/buaj/27ml/9u4o//fwK3/9/Dn//bw + 5//w5df/6dXF/+jNuf9+Wkn/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAimNO//ju6P/8+ff/+/n1//v59v/8+fb/28fE/9vIxP/byMX/28jE/9vHw//bxsL/28bA/9vF + vv/bxb3/28S7/9vCuf/bwbj/28G2/9vAtP/bv7P/276w/9u9r//bvK3/27ys/9u6qf/buaj/27mm/9u4 + pP/gwK3/9/Do//bx6P/w5Nj/6dXG/+jNuf9+Wkv/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAi2JQ//nv6P/8+vf//Pn2//z69//8+vf/28fC/9vHw//bx8P/28fD/9vH + wv/bxsH/28bA/9vFvv/bxL3/28S7/9vCuv/bwbj/28C2/9vAtP/bv7P/27+x/9u+r//bvK7/27ur/9u7 + qv/buaj/27im/9u4pf/gwK7/9/Ho//jx6P/y5Nr/6dXG/+jPu/9/XEr/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjGRP//nw6f/8+/j//Pr4//z6+P/8+/j/3MfC/9zH + w//cyMP/3MfD/9zHwv/cx8H/3MbA/9vEvv/bxL3/28O7/9vDuv/bwbj/28C3/9vAtf/bv7L/276x/9u+ + sP/bva3/27us/9u7q//buaj/27im/9u4pf/gwK//9/Hp//fx6f/x5Nn/6dbH/+jOuv9/W0r/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjmNR//nx6v/9+/n//vv5//37 + +f/9+/r/3MbB/9zHwf/cx8H/3MfB/9zGwf/cxsD/3Ma//9zFvv/cxb3/28O7/9vCuv/bwrj/28G2/9u/ + tf/bv7P/276x/9u9r//bva7/27ys/9u7qv/buqn/27in/9u4pP/gwa7/9/Hq//fy6f/x5tv/6tbH/+jO + vP+AW0r/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAj2RQ//rx + 6//9/Pr//fz6//38+//9/Pv/3MfB/9zHwf/cx8H/3MfB/9zHwP/cxsD/3Ma//9zFvf/cxLz/3MO7/9zD + uv/bwbj/28G2/9vAtP/bvrP/276x/9u9r//bva7/27ys/9u6qv/buqn/27mm/9u3pP/gwa7/+PLq//fy + 6v/x5dr/6tbI/+jOu/+AXUz/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAj2ZQ//ry7P/+/fv//fz7//79/P/+/fz/3MbA/9zGwf/cxsH/3MbB/9zGwP/cxsD/3MS//9zE + vf/cxLz/3MO6/9zCuf/cwrj/28C2/9vAtP/bv7P/276y/9u9r//bvK7/27ys/9u7q//buaj/27mn/9u3 + pP/gwa7/+PLr//fy6//x5dz/6tbI/+nQvf+AXEv/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAkGVS//vy7f/6+f7/8vP8/+zu/f/p7f3/yrnE/8y7xP/RwcP/2cPA/9zF + v//cxb7/3MS+/9zDvf/cw7v/3MO6/9zCuP/cwrf/3MG2/9u/tP/bv7L/276x/9u9sP/bvK3/27us/9u7 + qv/buqj/27mm/9u4pP/gwa7/+PLr//nz6//x59v/6tfJ/+nPvP+BXEv/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjmZV/+Th8P/Z4f7/0Nn9/8rU/v/I0v7/yNL+/8jT + /v/L6v7/2eD+/+fr/v/4+f7//v79//7+/f/+/fz//v38//79+//+/Pr//vz6//78+f/9+/j//fv3//36 + 9v/9+vX//fr0//359P/9+fP//Pjy//z48f/89/D/+PPs//jz6//y5t3/6tfJ/+nPvP+BXEv/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMv8QfF5s/8fK8v++y///s8P+/629 + //+qu///qrn//63Z//+x0P//vsr//8rU///Z4P//7vH+//7+/v/+/v3//v38//79/P/+/fv//vz6//78 + +f/+/Pj//fv4//379//9+vb//fr1//359P/9+fP//fny//z48f/8+PD/+PPs//jz7P/y5tz/6tfJ/+nP + vv+BXkv/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADZ//xwSSf8ybll9/624 + 9P+esf//iJ///3WQ//9qh///aoD//5zy//+FoP//nrD//7DA///AzP//0tv//+rv/v/+/v7//v79//79 + /P/+/fz//v37//78+v/+/Pn//fv4//379//9+vb//fr1//369P/9+fP//fny//z48v/8+PH/+PPs//jz + 7P/y5tz/6tfJ/+nPvf+CXUv/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC3/EgAo + /y6C4f+MY2GZ/4SV+P9bev//Qmn//zhm//83Y///NGT2/6P+/v86VPP/UWvv/3eG5v+UmuD/p6fb/7mz + 1v/SxM7/4c7J/+HNyP/hzcb/4cvD/+HKwf/hysD/4cm+/+DHvP/gx7r/4MW4/+DEtv/gxLT/4MKy/+DC + r//kyrj/+PPt//j07P/y5tz/6tfJ/+nPvf+CXU3/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAIf8IADP/KQAy/0EKQP9ilujn/1WF/P82YP//Mmb//2W4//8uZ///X7D6/3bm/f8rWfX/L1n0/z5d + 8P9peuT/kJTZ/6Wi0/+6sMz/1sHC/9zFvf/cxLz/3MK6/9zBuP/cwLX/3MC0/9u+sf/bvbD/27ut/9u7 + qv/buqn/27mm/9u3pP/gwa7/+fPt//j07f/z6N7/6tfK/+nPvv+CXUz/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAMv8bADL/OAAx/1IALf9+PGPZ/57///9Vov//K2n//5T2//8xif//YeP+/2DQ + /P8lYvb/OX32/y5f9P88XPD/cH7i/5aX1/+sps//xrfH/9zFvv/cxLz/3MK6/9zBuP/cwLX/3MC0/9u+ + sf/bvbD/27ut/9u7qv/buqn/27mm/9y4pP/gwa7/+PTu//n07f/y5tz/6NXH/+TJuP+CXUz/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAs/wYAMf8qADT/RgAx/2cAMf+rH0Db/16u/f9e9///YcL//2Hg + //9/7P//NeD//2PJ/P9kw/v/ccz7/yli9f8uWfP/SWHs/4SI3P+gndP/ua3L/9jCv//cxLz/3MK6/9zB + t//cwLX/3MC0/9u+sf/bvbD/27yt/9u7qv/cu6n/27mn/9u4pf/gwK7/+fXu//bw6f/z7OT/6dnO/9/E + tP+GYlD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAw/xAAM/8zADT/UAAz/4IANv/CHUze/ylq + /P9s1///H9n//2nu//8t2///ENL//3Lz//9m8P//IoH//ypx//83d///VZD//5LM//+w2///ytf//+/y + /v/+/v3//v38//38+//9+/n//Pr4//37+P///vr////8///9+v/9/Pf/+fXy//Xw6v/x6eT/7OXe/+jf + 2f/l3Nb/3Mq//7GPf/+EY1X0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAq/xgAMP86ADH/WAAy + /5kAOf/JT5nq/3DS/v9n0///Ze///wDK//8AzP//AMz//wvR//+C8v//XOD//2r1//+e////es3//2+Y + //+ntf//xdD//+fr/v/+/v3//v38//38+//9+/n//Pr4//37+f/azcX/wKqf/76mm/+8o5j/uKCU/7ee + kv+zm5D/spiP/6iNgP+Uc2X/h2JR/4hjUvyKbF1PAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAt + /xwAM/89ADH/XQAz/6UAP//KG1Ph/1Ct/f9Y5///BM///wDM//8AzP//AMz//wDM//8c1///W+T//1u8 + //8tdP//NWD//1p5//+itP//ws7//+Po/v/+/f3//v38//38+v/9+/n//Pr4///++//DrqP/pINz/8y7 + sv/Is6X/xq2a/8Wojv/DooP/wZx4/8qicv+4j2X/iWRW+5RzYkUAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAt/xwAM/89ADH/XQAu/6UANv/KJGXl/2DB/v9W5P//E9L//wDM//8AzP//AMz//wDL + //894///Z9P//ySB//8tcf//NWj//1p7//+itP//ws7//+Po/v/+/f3//fz7//38+v/9+/n//Pr4///8 + +v/NubD/vKSY////+v/78N7/+ObJ//Xcs//y05//88yL/9Opb/+HZVf5j3NjOgAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAp/xgAKv87ACr/Wjd8/7N72v/tkP7+/170//9c5v//W+v//wDK + //8AzP//AMz//wvQ//9w7P//Zd7//4Tj//8/h///NmX//2OC//+mt///w87+/+fr/f/+/fz//fz7//37 + +v/8+/n//Pr3//77+P/d0Mj/p4Z1//3y3v/14sP/8tiv/+7Om//vyIj/y6Br/4dlV/mPcmcxAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAs/xBEkf9NedX/l2i9/7o4gf/VL2nk/ydy + /f9QsP//Run//1rq//8h1///D9L//1bq//9J5f//M5L//ypw//8xa///O2X//3qU//+tvv7/ytT+/+/x + /f/9/Pz//fz6//37+f/8+vj//Pr3///7+f/e0sr/poJu//voyf/y167/7s2b/+/Ihv/Fmmn/h2RX+ZBz + ZToAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAr/wYAK/8rACr/RwAr + /2oALv+vIEfc/yxv/P+Z/f//U7L//1fo//9s6v//VOr//3PS//9i6f//dO3//yxu//81Z///UHP//5Sp + /v+3xf7/09r9//j5/P/9/Pv//fv6//z7+f/8+vj//Pn3//389//e0sr/pYBp//bcsf/uzpj/78eF/8yg + av+GZlj3k3ZqMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAMP8cADD/OgAw/1QAMv+EJ0HU/0WC/P8yeP//KHf//2P2//9at///dNb//1Wx//8sev//he3//37S + //9BXv//e5T//6q6/v/Ezv3/4ub8//38+//9/Pr//fv5//z6+P/8+vf//Pn2//36+P/e0sv/pH1k//TS + m//wxoP/xppo/4hnW/WVeWooAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAHf8JADD/KwAx/0MAMf9dREy0/0Fl+v81ZP//Q4b//5L///8wd///N4L//12t + //8xZ///M2L//4XZ//+FvP//obD+/7vH/v/T2/3/9fX7//38+v/9+/n//Pv4//z69//8+fb/+/n1//36 + 9v/f08v/o3xe//PLhf+/lGX/h2da9pV8dCEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADn/FAAv/zAANP9GYVWS/3qQ9f9TcP7/W5j//4Xb + //81X///NWX//zlp//89Zv//U3P+/32P/v+p4f//ttD9/83V/f/q7fv//f36//77+f/8/Pj//Pr5//z5 + 9//7+vb/+/j1//779//bzcT/p39b/8ygaP+KaFz1k3hxKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AQAx/xcAMP8wb12C/6mz + 8v+Wpvv/k9D9/3qt/f9eev3/Xn79/2mG/f9+lv3/lqn8/6q5+/+7xPv/zN37/+Tn+f/7+vj/+/n3//z5 + 9v/6+PX/+vj1//r39P/79/P/+fby///69v/DraD/mG9W/4ttX/KMc2shAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAALP8TgGJx/8XH7v+3ue7/ruj3/6Ot8f+irPH/oqzy/6aw8f+ttfH/trzw/8PG7//S0u3/6ePr//vx + 6P/78On/+/Dp//rv6P/67+f/+u/o//ru5v/57eX/+e3l//vv5f+bdWX/jW1g75N+choAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAlm5i/4tqbf+DZXX/iZGb/3lgfv92YID/dmCA/3hhfv98Y3v/gGRz/4ln + av+TbF//l2xY/5ZtWP+Va1n/lWxX/5RqV/+Ta1j/k2lW/5JqV/+RaFX/kWlW/5BpV/+LcGPVf3JlFQAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJ/8GNID/FQAr/xUANP8ZADT/GQAw + /xUAN/8OADb/BQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////AAD///////8AAPwAAAAAPwAA/AAAAAA/ + AAD8AAAAAD8AAPwAAAAAPwAA/AAAAAA/AAD8AAAAAD8AAPwAAAAAPwAA/AAAAAA/AAD8AAAAAD8AAPwA + AAAAPwAA/AAAAAA/AAD8AAAAAD8AAPwAAAAAPwAA/AAAAAA/AAD8AAAAAD8AAPwAAAAAPwAA/AAAAAA/ + AAD8AAAAAD8AAPwAAAAAPwAA/AAAAAA/AAD8AAAAAD8AAPwAAAAAPwAA/AAAAAA/AAD8AAAAAD8AAPwA + AAAAPwAA/AAAAAA/AAD8AAAAAD8AAPgAAAAAPwAA+AAAAAA/AADwAAAAAD8AAPAAAAAAPwAA4AAAAAA/ + AADgAAAAAH8AAOAAAAAA/wAA4AAAAAH/AADgAAAAA/8AAOAAAAAH/wAA8AAAAA//AADwAAAAH/8AAPgA + AAA//wAA/AAAAH//AAD8AAAA//8AAPwAAAH//wAA/AAAA///AAD///////8AAP///////wAA + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/Program.cs b/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/Program.cs new file mode 100644 index 0000000..7912907 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/Program.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Windows.Forms; + +namespace AutoFileCryptTool +{ + static class Program + { + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main() + { + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + Application.Run(new TrayForm()); + + } + } +} diff --git a/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/Properties/AssemblyInfo.cs b/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..73b7fc0 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("AutoFileCryptTool")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("EaseFilter Technologies")] +[assembly: AssemblyProduct("AutoFileCryptTool")] +[assembly: AssemblyCopyright("Copyright © 2017 EaseFilter Technologies")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("1826df94-fbbb-4180-ad6f-c1ab49726eca")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("5.2.3.2001")] +//[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/Properties/Resources.Designer.cs b/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/Properties/Resources.Designer.cs new file mode 100644 index 0000000..57116e5 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/Properties/Resources.Designer.cs @@ -0,0 +1,73 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace AutoFileCryptTool.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // 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", "16.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + 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() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [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("AutoFileCryptTool.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap about { + get { + object obj = ResourceManager.GetObject("about", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + } +} diff --git a/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/Properties/Resources.resx b/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/Properties/Resources.resx new file mode 100644 index 0000000..bf14fc6 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/Properties/Resources.resx @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + ..\Resources\about.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/Properties/Settings.Designer.cs b/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/Properties/Settings.Designer.cs new file mode 100644 index 0000000..10a337e --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/Properties/Settings.Designer.cs @@ -0,0 +1,26 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace AutoFileCryptTool.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.10.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default { + get { + return defaultInstance; + } + } + } +} diff --git a/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/Properties/Settings.settings b/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/Properties/Settings.settings new file mode 100644 index 0000000..3964565 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + diff --git a/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/Resources/about.png b/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/Resources/about.png new file mode 100644 index 0000000..4017add Binary files /dev/null and b/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/Resources/about.png differ diff --git a/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/SetupPasswordForm.Designer.cs b/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/SetupPasswordForm.Designer.cs new file mode 100644 index 0000000..ad3c0af --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/SetupPasswordForm.Designer.cs @@ -0,0 +1,122 @@ +namespace AutoFileCryptTool +{ + partial class SetupPasswordForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(SetupPasswordForm)); + this.label1 = new System.Windows.Forms.Label(); + this.label2 = new System.Windows.Forms.Label(); + this.textBox_Password1 = new System.Windows.Forms.TextBox(); + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.textBox_Password2 = new System.Windows.Forms.TextBox(); + this.button_NewPassword = new System.Windows.Forms.Button(); + this.groupBox1.SuspendLayout(); + this.SuspendLayout(); + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(20, 16); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(114, 13); + this.label1.TabIndex = 0; + this.label1.Text = "Enter master password"; + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(20, 53); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(108, 13); + this.label2.TabIndex = 1; + this.label2.Text = "Confirm the password"; + // + // textBox_Password1 + // + this.textBox_Password1.Location = new System.Drawing.Point(176, 16); + this.textBox_Password1.Name = "textBox_Password1"; + this.textBox_Password1.Size = new System.Drawing.Size(131, 20); + this.textBox_Password1.TabIndex = 2; + this.textBox_Password1.UseSystemPasswordChar = true; + // + // groupBox1 + // + this.groupBox1.Controls.Add(this.textBox_Password2); + this.groupBox1.Controls.Add(this.label1); + this.groupBox1.Controls.Add(this.textBox_Password1); + this.groupBox1.Controls.Add(this.label2); + this.groupBox1.Location = new System.Drawing.Point(12, 23); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size(359, 86); + this.groupBox1.TabIndex = 3; + this.groupBox1.TabStop = false; + // + // textBox_Password2 + // + this.textBox_Password2.Location = new System.Drawing.Point(176, 53); + this.textBox_Password2.Name = "textBox_Password2"; + this.textBox_Password2.Size = new System.Drawing.Size(131, 20); + this.textBox_Password2.TabIndex = 3; + this.textBox_Password2.UseSystemPasswordChar = true; + // + // button_NewPassword + // + this.button_NewPassword.Location = new System.Drawing.Point(296, 127); + this.button_NewPassword.Name = "button_NewPassword"; + this.button_NewPassword.Size = new System.Drawing.Size(75, 23); + this.button_NewPassword.TabIndex = 4; + this.button_NewPassword.Text = "Ok"; + this.button_NewPassword.UseVisualStyleBackColor = true; + this.button_NewPassword.Click += new System.EventHandler(this.button_NewPassword_Click); + // + // SetupPasswordForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(391, 162); + this.Controls.Add(this.button_NewPassword); + this.Controls.Add(this.groupBox1); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Name = "SetupPasswordForm"; + this.Text = "Setup Master Password For First Usage"; + this.groupBox1.ResumeLayout(false); + this.groupBox1.PerformLayout(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.TextBox textBox_Password1; + private System.Windows.Forms.GroupBox groupBox1; + private System.Windows.Forms.TextBox textBox_Password2; + private System.Windows.Forms.Button button_NewPassword; + } +} \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/SetupPasswordForm.cs b/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/SetupPasswordForm.cs new file mode 100644 index 0000000..cbb1023 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/SetupPasswordForm.cs @@ -0,0 +1,67 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +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; + +using EaseFilter.CommonObjects; + +namespace AutoFileCryptTool +{ + public partial class SetupPasswordForm : Form + { + public bool isPasswordMatched = false; + + public SetupPasswordForm() + { + InitializeComponent(); + this.StartPosition = FormStartPosition.CenterScreen; + } + + private void button_NewPassword_Click(object sender, EventArgs e) + { + if (string.IsNullOrEmpty(textBox_Password1.Text)) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("The password can't be empty.", "Password", MessageBoxButtons.OK, MessageBoxIcon.Error); + + isPasswordMatched = false; + } + else if (string.Compare(textBox_Password1.Text, textBox_Password2.Text, false) != 0) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("The password doesn't match.", "Password", MessageBoxButtons.OK, MessageBoxIcon.Error); + + isPasswordMatched = false; + } + else + { + isPasswordMatched = true; + GlobalConfig.MasterPassword = textBox_Password1.Text; + this.Close(); + } + } + + + } +} diff --git a/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/SetupPasswordForm.resx b/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/SetupPasswordForm.resx new file mode 100644 index 0000000..a4af948 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/SetupPasswordForm.resx @@ -0,0 +1,570 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + AAABAAgAEBAAAAEACABoBQAAhgAAABAQAAABACAAaAQAAO4FAAAYGAAAAQAIAMgGAABWCgAAGBgAAAEA + IACICQAAHhEAACAgAAABAAgAqAgAAKYaAAAgIAAAAQAgAKgQAABOIwAAMDAAAAEACACoDgAA9jMAADAw + AAABACAAqCUAAJ5CAAAoAAAAEAAAACAAAAABAAgAAAAAAEABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP// + /wCFe3sA1LS0AOvZ2QC3kpIAuaqqAPPFxQCXi4sA1svLAKicnADkvLwAw5ycANvX1wDlzs4Apo6OANDB + wQB8c3MAlYGBAODg4ADdxMQAxK2tALWamgD3zMwA7tLSAKOVlQDAlZUA6sjIAJ2FhQCuk5MA5NXVANzR + 0QDcvr4A2ri4AMuwsADn4uIAloaGAKWJiQDk2toA7s3NAK6OjgCumJgAvJycAJ+RkQDhysoAi319AKiS + kgC5lpYAv6qqANfT0wCzlZUA6dPTAO/JyQDbzMwAvZKSANnBwQCaiIgA4dDQAOC6ugDQsrIAqZWVAMKZ + mQDzy8sA29TUAOHNzQC8mZkAw5+fAOHX1wCjjIwA2c/PAODCwgDsy8sAvpeXAOPf3wDe2NgA4dTUAKaU + lADdwcEAuZubAL+dnQDq19cA5dfXAObT0wCik5MA5tDQALyUlADp1dUAo46OAJ+TkwDp0dEA3M/PALmY + mADr0tIA3dbWANnV1QCskpIA38/PALCXlwDm2toAqpKSAKuVlQDa0dEAvpSUAOrU1ACgkpIA59TUAOLW + 1gCnkZEA5dTUAKSUlACllZUAqJSUAN3S0gDb0tIA2svLALSZmQDju7sA27e3ANGzswCaiYkA3dfXAK6S + kgDhz88ArpeXAL6VlQDAlpYAmYiIAO3S0gCfkpIA5dXVAOHW1gDc1tYAqJGRAKmSkgCklZUAtJWVAL+V + lQC6m5sA4bq6AM+ysgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAFcua2tuhhloKyuACAAAAAApgR5RS3F4XYMNMVgAAAAAe0eHOAoTAQEBAV6A + AAAAAGFnUARQUjk1CUpFaAAAAABhRy95RCQCEGUBP1MAAAAAiX9ZXDNnVnpaI3BtAAAAACobW193Bg4s + ckkfTAAAAABBJ0ZNNxhqAQEBQ28AAAAASCdGTTcYQIJLgmA8AAAAAEg0Mg9+i2IBAQEmZAAAAAB8Pooh + diBZaVJsVIQAAAAAZhd0Czp1AzsiFRSFAAAAABoHVQUoJRwSLREwYwAAAAA2iIh9PQxCT04Wcx0AAAAA + AAAAAAAAAAAAAAAAAAD//wAAwAMAAMADAADAAwAAwAMAAMADAADAAwAAwAMAAMADAADAAwAAwAMAAMAD + AADAAwAAwAMAAMADAAD//wAAKAAAABAAAAAgAAAAAQAgAAAAAABABAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAKSPj/qpk5P9qJKS/aiSkv2mlpb8pZaW/KSWlvyhk5P9oJKS/aCSkv2gk5P9mIyM/AAA + AAAAAAAAAAAAAAAAAACwmZn95dXV/+TV1f/l19f/4dTU/9vS0v/d19f/3dbW/9zW1v/b19f/19PT/6CU + lP0AAAAAAAAAAAAAAAAAAAAAsJiY/ezLy/+0lZX/moiI/6icnP/g4OD//////////////////////9nV + 1f+gk5P9AAAAAAAAAAAAAAAAAAAAALKYmP3q1NT/6tfX/+vZ2f/q19f/5tPT/+HQ0P/bzMz/1svL/97Y + 2P/Zz8//oZOT/QAAAAAAAAAAAAAAAAAAAACymJj97MvL/7mWlv+ukpL/o4yM/5aGhv+Fe3v/0MHB/9rR + 0f//////29TU/6OUlP0AAAAAAAAAAAAAAAAAAAAAu5yc/O3S0v/p0dH/69LS/+nT0//q1NT/6dXV/+HP + z//cz8//5+Li/93S0v+llZX9AAAAAAAAAAAAAAAAAAAAAL2dnfzqyMj/uZiY/6ySkv+aiYn/uaqq/+XO + zv/hysr/2svL/+Pf3//c0dH/p5WV/QAAAAAAAAAAAAAAAAAAAAC+mpr97s3N/+DCwv/dwcH/2cHB/+7S + 0v/i1tb/////////////////4dfX/6mVlf0AAAAAAAAAAAAAAAAAAAAAwJiY/e7Nzf/gwsL/3cHB/9nB + wf/u0tL/4c3N/+HW1v/h1NT/4dbW/9/Pz/+rlpb9AAAAAAAAAAAAAAAAAAAAAMCYmP3vycn/s5WV/6aO + jv+ZiIj/z7Ky/+ba2v/////////////////k2tr/rZaW/QAAAAAAAAAAAAAAAAAAAADAlpb988vL/+G6 + uv/auLj/0bOz/9y+vv/p0dH/59TU/+bT0//l1NT/5tDQ/6mSkv0AAAAAAAAAAAAAAAAAAAAAwJWV/ffM + zP/ju7v/5Ly8/+C6uv/bt7f/1LS0/9Cysv/LsLD/xK2t/93ExP+rk5P9AAAAAAAAAAAAAAAAAAAAAMKW + lv3zxcX/vJSU/7eSkv+ujo7/pYmJ/52Fhf+VgYH/i319/3xzc/+/qqr/rJOT/QAAAAAAAAAAAAAAAAAA + AAC/k5P6wZaW/cGWlv3Cl5f9xJqa/cWdnf3FoKD9wZ6e/bucnP23m5v9tpqa/bCUlPsAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAD//wAAwAMAAMADAADAAwAAwAMAAMADAADAAwAAwAMAAMADAADAAwAAwAMAAMADAADAAwAAwAMAAMAD + AAD//wAAKAAAABgAAAAwAAAAAQAIAAAAAACgAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8AlXh4AOCx + sQBeXV0ApqKiAP/U1ADUz88AypqaAK2HhwB7bW0A5uDgAMGtrQDpxMQAnZOTAM67uwC1mJgA6tLSAPP1 + 9QCZhIQAh39/ALuMjAC/oqIAa2NjANCkpADdvb0A0cXFAN7X1wDTrq4A4czMAKmQkAD2zs4AsqSkAIt0 + dACkmpoApYKCAIJ4eADnu7sAcmhoAPXV1QCcfX0A3MTEAM20tACtm5sAyKGhAPj7+wCciooAyq6uAMGc + nADxyckA29HRANjKygC5q6sAgnBwANm4uACcm5sAuJOTAOPb2wC3oKAA1bS0AOrKygCulpYA49LSANHK + ygCvoKAA8NDQAOLCwgC6nJwAo5SUAIh4eADh4OAA6M7OAJ+PjwC2j48A0be3AHNsbADX09MAqIyMALaK + igC+qakAqZSUAMilpQC5p6cA+tPTAOXJyQDdyckAqIiIANi8vADWq6sAtJ2dAM2goACXiooApJCQAIuB + gQDtxsYA1sfHAMSfnwDs1dUA9Pj4AP7R0QD00tIA4s/PANrU1ADX0NAAm46OAOK/vwDRsrIAu5+fAPv9 + /QD50NAAmX9/APLU1ADm1NQA3s7OANDNzQCmlpYA1MPDAKuiogDHsLAA4NHRANnHxwC0oKAAxa2tAO7S + 0gDs0NAA2szMAKWgoACooKAAs5qaALiamgCwnp4AsKKiANO1tQDKo6MAw6urAOPh4QDzz88A5dDQAN3T + 0wDlzc0Aq5eXAMKhoQD5+fkA5t7eAPfS0gDn0tIA6dDQAOHKygDmxMQA0sfHANGiogDFoaEAzaSkAPrV + 1QD20NAA1cnJAKakpACroKAAt6KiAL+goADZuroAwqOjAPb6+gD+09MA+NTUAO/PzwDqzc0A2dLSAN/P + zwDZz88A3svLANjIyAC/nZ0Az6GhAMyvrwD6+/sA/NHRAPLS0gDw0tIA7NLSAOXS0gDn0NAA2NTUAOPN + zQCpoqIA1s/PAK6iogDcy8sA0s3NANrKygC6oKAAtKSkANPJyQC9oKAAyqGhANWurgDPsrIA/9LSAPvU + 1ADh398A99XVAPbU1AD01NQA+NHRAOPa2gD00dEA69PTAOvR0QC2l5cA5NPTAOrPzwDi0dEA5s/PAOHQ + 0ADc0NAA4c7OANbR0QDa0NAA4szMANTQ0ADfzc0Aw6CgAMagoADgyckAyaCgANnLywDQy8sA0qOjANrG + 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 + lv+plJT/pJCQ/5+Pj/+Xior/sJ6e//LU1P+9oqL4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA0KKi+P/S + 0v/gsbH/u4yM/7aKiv+th4f/pYKC/5x9ff+VeHj/i3R0/4JwcP97bW3/cmho/2tjY/9eXV3/h39///XV + 1f+/oqL4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1KSk+P/U1P/+0dH//tPT//7S0v/90tL//dPT//3T + 0//71NT/+9TU//rV1f/609P/+tTU//jU1P/41NT/9tLS//XU1P/CpKT4AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAzpub8dWlpfjSo6P40aOj+NCjo/jQo6P4zaOj+Myjo/jLo6P4yqOj+Mmjo/jIo6P4x6Oj+Maj + o/jFo6P4xKOj+MWlpfi6m5vxAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA////AOAABwDgAAcA4AAHAOAABwDgAAcA4AAHAOAABwDgAAcA4AAHAOAABwDgAAcA4AAHAOAA + BwDgAAcA4AAHAOAABwDgAAcA4AAHAOAABwDgAAcA4AAHAOAABwD///8AKAAAACAAAABAAAAAAQAIAAAA + AACABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8AlXR0ANO2tgBJTEwA/tTUAKuZmQBqZmYA1tLSAOjr + 6wC0hIQAx5iYAPLExAC8r68AgWtrAF5YWADSpqYAl5SUAM7ExADq09MAoYGBAOG/vwDy9vYA3uHhAH53 + dwC/jIwA4crKAMW3twC2k5MAs6ioAGBhYQD3zs4AiHJyAHZlZQCik5MAVlJSAJ55eQBrXl4A18nJAKyA + gADXvb0A7s3NAPXV1QDg0tIAwJOTAMbAwADqvb0AybGxANy4uADOvLwArYeHAJmZmQCtk5MAd2trAJV6 + egC0iooA+fv7ANzFxQDv8fEAjG1tALOYmABkXFwA+tjYAObOzgDczs4A0s3NAMStrQBxYWEA18LCAOLl + 5QCPdnYA6MnJAKeDgwCcfn4Afm9vANvd3QDx0NAAy8jIAMy1tQCclJQA/NDQAOO7uwDMwMAAZGRkAJBw + cAC4jY0Ap5aWANzCwgDdvLwA07q6AHJqagD51NQAhmxsAINxcQCYd3cA4cbGANDKygBvZmYA8szMAOXS + 0gDc0tIA28nJANi2tgC7k5MA0r29ALyKigDWqKgAinV1AOzQ0ADY1dUAoHx8ANTFxQDz8/MA9tDQAOHP + zwDXzMwA2Lq6AKiTkwDOubkAs5WVAMa0tABNTU0AaGNjAJFzcwDmzMwA08HBAJeWlgB7bW0A59XVAN7M + zADDlZUAybe3APv9/QBiWloA9tbWAO/OzgDo0NAA3dDQANnQ0ADU0NAA48jIANDHxwDYwMAAc2RkAPvV + 1QD/0dEA+tDQAOrNzQDjzc0AqX5+AOC6ugDVwMAAycHBANC1tQBKTk4A/P//APHz8wCBaWkAkHh4APPS + 0gDw0tIA5NDQAK2BgQDVzs4A2szMANTMzACZlJQA5ry8AOS9vQCflJQAzcbGAKWTkwDcv78A0cPDAM3C + wgCwk5MAz8DAALOTkwDLs7MAZGJiAPnR0QDyz88A0MzMANO4uABgWVkA9Pf3AOrs7AD719cA4OLiAPnW + 1gD709MA99LSAPTPzwDu0dEA9czMAOzS0gDo09MA7M7OAOvPzwDi0dEA4c3NALKJiQDkysoA38nJALqM + jAC9jY0A0srKAKmVlQDewMAA28LCANq7uwDUvb0A1bu7ANG7uwDWt7cA1bW1ANK0tADHuLgA+/v7AIRs + bADw9vYA8PHxAKB5eQDwzMwA5tHRAOjOzgDe0tIA39DQANjS0gDb0NAA19DQAN3OzgCrk5MA2c7OANzM + zADTzs4AuZOTAL6TkwDYyckA2MLCANXBwQByYmIAdWRkAHZqagD9/v4A8/X1AJd2dgCbfX0A/9XVAP/T + 0wD519cAooCAAPzU1AD61NQA/dHRAPfV1QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAGVqsiIiKpqampqU9PT0+mpqamERERfjMAAAAAAAAAAM+Ax+Pj44mJiYnliuWKiuaK5ovmi4ttfgAA + AAAAAAAAdWOB6oGkpKSkpHNzc6VzpaVBQUG2QQgRAAAAAAAAAAB1oYHjcuOJ44lAjeulpUFBQUFBQU22 + CBEAAAAAAAAAAHVjcllZdoMbDe7mAdra2tra2tr0CWAIpgAAAAAAAAAANODHaZX22/EjG6P13d3d3d3d + 3XC8zgimAAAAAAAAAAA0iHKhoWOAxGPHb65SUphSmJiYmC1z5KYAAAAAAAAAADSIlJShcqFycnJycuPj + iUCkqs5gqqVkTwAAAAAAAAAANIg/V1fR70SXaGgxMdkmQGUJAQG6JmRPAAAAAAAAAACvbIgZCifeAjud + ISW4eR1yZRdwcLwm4k8AAAAAAAAAAK9sP3x8P5Q/lJRylHKBcoGBUhISmKTiqQAAAAAAAAAAr8F8iD+I + iOCIiOCUyMjIgYGNc3ONpCupAAAAAAAAAACxwcbQrKwo1NV2eIjIyMiBgUUBAQllK6kAAAAAAAAAALHB + bGknJFSdQ4UEw5TIyMiBS5xwvGUrIgAAAAAAAAAAsaDFxWxsbGxswz/hlHyUlJSwra1SgcciAAAAAAAA + AAAcTClsbGzBwcHG4T856aRzc+lz6aVlxyIAAAAAAAAAAByfTBVY0nS3TlnG4WgBhISEhIT0uUTEIgAA + AAAAAAAAHJ9MLJVeXPIPGKCT0xY6Ojo6OpwJRMSrAAAAAAAAAADscYe1TJ+fKp+HxZOMRPDw8PB9fa0a + xKsAAAAAAAAAAOxx30y1TExMTEzBxV/iQEDnQEBAc8sTqwAAAAAAAAAA7L/AqJYwZtYDmUKHKJs4ODg4 + OIS50RN1AAAAAAAAAABntHGCom57Do89mkeO3Do6Ojo6nAlXE3UAAAAAAAAAAGe0H3G/v79b/ZC/wEfv + jo6XjpdEfcrDdQAAAAAAAAAAZ/7CwmLCYmLfYt8pKd+HKSkpk5OT4cPoAAAAAAAAAADt/h+Svr78/P39 + kJC9vbu7u/o+PirGwTQAAAAAAAAAAO3+khBVVckySBRJNp5rXUo1WgezU4agNAAAAAAAAAAALJFQas3M + NzJI+/c2RiBdf/Nheh4e+qA0AAAAAAAAAAAskVAMLi6np1GWljAwZmbX2JmZsi+fn68AAAAAAAAAAIL4 + kZH5+fn5+fkFBQX8/JCQkL29W5//dwAAAAAAAAAAC4IsLCzt7WdnZ2fs7OwcHBwcsbGxsXc8AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AA + AA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AA + AA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/////8oAAAAIAAAAEAAAAABACAAAAAAAIAQ + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAArJiY56iWlvCllJTwpJSU8KSU + lPCilJTwoZSU8KCUlPCglJTwn5SU8J6UlPCdlJTwnJSU8JyUlPCblJTwmpSU8JmUlPCZlJTwmJSU8JeU + lPCWlJTwlpSU8JaWlvCYmJjnAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACrlpb159XV/+LR + 0f/g0ND/39DQ/+DQ0P/e0ND/3dDQ/9zQ0P/d0ND/29DQ/9rQ0P/b0ND/2dDQ/9jQ0P/X0ND/2NDQ/9bQ + 0P/V0ND/1tDQ/9TQ0P/T0dH/2NXV/5iWlvUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKmU + lPXk0tL/3s3N/9zMzP/dzMz/28zM/9rMzP/ZzMz/2czM/9nMzP/YzMz/2MzM/9bMzP/VzMz/1szM/9TM + zP/TzMz/0szM/9LMzP/RzMz/0MzM/9HNzf/V0tL/l5SU9QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAqpSU9eTR0f/ezMz/38/P/+DPz//fz8//3tDQ/9/Q0P/e0ND/3M7O/9DHx//Tzs7/08zM/9PM + zP/SzMz/0szM/9LMzP/RzMz/0czM/9LNzf/LyMj/0MvL/9XS0v+YlJT1AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACrlJT15dHR/+HPz//Tu7v/0rq6/825uf/Jt7f/xba2/7yvr//Yycn/19HR//7/ + ///7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v//f7+/+nr6//Qycn/1tLS/5mUlPUAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAK6UlPXm0dH/49HR/7uKiv+pfn7/l3Z2/4RsbP9yYmL/VlJS/8W3 + t//Vzs7/8/X1//Dx8f/w8fH/8PHx//Dx8f/w8fH/8PHx//Dx8f/z8/P/4OHh/9LKyv/X0tL/mpSU9QAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAArpSU9efR0f/izs7/5NDQ/+TR0f/l0tL/5tTU/+fT + 0//l0tL/4tDQ/9TFxf/NwsL/y8DA/8zAwP/KwMD/y8DA/8nBwf/KwcH/yMHB/8rBwf/GwMD/1svL/9jS + 0v+blJT1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACvlJT16NHR/+TMzP/jzs7/48/P/+LP + z//jz8//4s/P/+HPz//hz8//4dDQ/+HQ0P/g0ND/4NDQ/93Pz//bzs7/28vL/83Gxv/Sysr/0MrK/8zG + xv/Vy8v/29LS/5yUlPUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALCUlPXp0dH/5s/P/9zC + wv/cwcH/28LC/9jCwv/XwcH/1b+//9K+vv/Rvb3/zry8/868vP/HuLj/18jI/9zOzv/aycn/6Ovr//7/ + ////////6uzs/9bJyf/c0tL/nZSU9QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsZSU9ezR + 0f/o0dH/v4yM/7SEhP+sf3//oHl5/5V0dP+MbW3/gGlp/3ZlZf9rXl7/YFlZ/01NTf+zqKj/4M/P/9vJ + yf/e4eH/8/T0//P09P/g4uL/18nJ/93S0v+elJT1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACylJT17NHR/+fOzv/my8v/5czM/+bOzv/kzc3/5c7O/+POzv/jzc3/4s7O/+LNzf/izs7/3szM/+DP + z//ezc3/3cvL/8zBwf/OxMT/zsTE/8nBwf/Zy8v/3tLS/5+UlPUAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAALOUlPXt0dH/58zM/+jPz//nz8//6NDQ/+fQ0P/m0ND/6NHR/+fR0f/m0dH/5M7O/+HN + zf/gzc3/4MzM/97MzP/ezMz/0MbG/9bLy//Wy8v/z8fH/9rLy//f0tL/oJSU9QAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAtJSU9e7R0f/qz8//3sDA/9y/v//bv7//1729/9W7u//Ru7v/zrm5/8a0 + tP/n0ND/4czM/+DMzP/gzMz/38zM/97Ly//i5eX//v////7////o6+v/2snJ/+DS0v+hlJT1AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC1lJT179HR/+zR0f+8ior/rICA/555ef+QcHD/gWlp/3Fh + Yf9iWlr/SUxM/+vS0v/izMz/4czM/+HMzP/gzMz/38vL/9vd3f/x8/P/8vPz/9/i4v/bycn/4dLS/6KU + lPUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALaUlPXw0dH/687O/+zNzf/s0ND/69DQ/+zQ + 0P/r0ND/7NHR/+vS0v/nzs7/6c7O/+TMzP/lzMz/48zM/+LMzP/jzMz/z8DA/9HDw//Qw8P/zMHB/9/L + y//i0tL/o5SU9QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAt5SU9fHR0f/tzMz/7c/P/+3P + z//s0ND/7tDQ/+3R0f/t0dH/6s/P/+jOzv/mzc3/3MXF/9nOzv/ZzMz/18zM/9jNzf/Zzc3/2M3N/9nN + zf/Vy8v/2snJ/+PS0v+klJT1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC4lJT19NHR//DP + z//hv7//3by8/9q7u//Yurr/07i4/8y1tf/Turr/68/P/+jNzf/Svb3///////v8/P/7/Pz/+/z8//v8 + /P/7/Pz//P7+//T39//WwsL/59PT/6WUlPUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALmU + lPX00dH/8dHR/8CSkv+pfn7/mHd3/4ZsbP91ZGT/XlhY/353d//w0tL/6c3N/9S9vf/y9vb/7/Hx/+/x + 8f/v8fH/7/Hx/+/x8f/w8/P/6Ozs/9fCwv/n09P/ppSU9QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAupSU9fXR0f/wzs7/8s7O//LR0f/z0dH/89LS//TU1P/y0tL/78/P/+zOzv/pzc3/48jI/9bC + wv/VwcH/1cHB/9TBwf/UwcH/08HB/9PBwf/RwsL/4crK/+jS0v+nlJT1AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAC7lJT19tHR//DMzP/xz8//8s/P//LQ0P/x0ND/8dDQ//LR0f/x0dH/79DQ/+3O + zv/hxsb/3tHR/9zOzv/czs7/3c7O/9vOzv/bzs7/3M/P/9jNzf/fycn/6dLS/6iUlPUAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAALyUlPX30dH/9M/P/+S9vf/gu7v/3Lm5/9m3t//Wt7f/07a2/8+0 + tP/Era3/787O/9e9vf/8////+fv7//n7+//5+/v/+fv7//n7+//7/f3/8/f3/9rCwv/q09P/qZSU9QAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAvZSU9fjR0f/20ND/w5SU/62Bgf+gfHz/kXNz/4Fr + a/9zZGT/ZFxc/0pOTv/oycn/2b+///D29v/u8fH/7/Hx/+/x8f/v8fH/7/Hx//Dz8//o7Oz/3MLC/+vT + 0/+qlJT1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC+lJT1+dHR//bOzv/3z8//99LS//jS + 0v/40tL/+dPT//nU1P/61dX/99LS//PPz//nyMj/2MLC/9fAwP/YwMD/1sDA/9fAwP/VwMD/1sHB/9LB + wf/kysr/69LS/6uUlPUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL+UlPX80dH/9czM//TM + zP/zzMz/9MzM//LMzP/xzMz/8MzM//HMzP/vzMz/7szM/+7Nzf/wzc3/783N/+3Nzf/uzc3/7c3N/+vN + zf/qzc3/683N/+jNzf/s0tL/rZSU9QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwJSU9fzR + 0f/3zc3/+c/P//vS0v/709P//NTU//vU1P/61NT/+tTU//zV1f/71dX/+tbW//nW1v/719f/+tfX//rX + 1//519f/+djY//rY2P/11dX/68/P/+3R0f+ulJT1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AADBlJT1/dHR//rQ0P/Spqb/uIyM/7iNjf+yiYn/rIeH/6eDg/+hgYH/nH5+/5V6ev+QeHj/inV1/4Nx + cf9+b2//d2tr/3Jqav9qZmb/ZGJi/2RkZP/21tb/8NHR/66UlPUAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAMKUlPX+0dH//NDQ/9aoqP+9jY3/uoyM/7SKiv+thob/p4OD/6KAgP+bfX3/lHp6/492 + dv+IcnL/gnFx/3ttbf92amr/b2Zm/2hjY/9gYGD/YGFh//jX1//w0dH/sJSU9QAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAw5SU9f/S0v/8z8//8sTE/+q9vf/pvLz/5ru7/+W8vP/ju7v/4Lq6/9+5 + uf/duLj/3Le3/9i2tv/Xtrb/1bW1/9K0tP/QtbX/z7S0/8uzs//JsbH/8tLS//LS0v+xlJT1AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADGlpb1/9XV///R0f//0tL//9PT///T0///09P//tPT///T + 0//+09P//dTU//7U1P/91NT//NTU//vU1P/81dX/+9XV//rV1f/51dX/+dXV//jU1P/00tL/99XV/7SW + lvUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMqYmO3Glpb1w5SU9cKUlPXClJT1wZSU9cCU + lPW/lJT1vpSU9b6UlPW9lJT1vJSU9buUlPW6lJT1uZSU9bmUlPW4lJT1t5SU9baUlPW1lJT1tZSU9bSU + lPW1lpb1tZiY7QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/////wAAAP8AAAD/AAAA/wAAAP8AAAD/AA + AA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AA + AA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA//////KAAAADAAAABgAAAAAQAIAAAA + AACACgAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8AlXR0ANO2tgBJTEwA/tTUAKuZmQBqZ2cA1NLSAOjr + 6wC0hIQAxJycAPHAwAC7ra0AgWtrAF5YWADNpqYAlYyMAM7ExADq09MAn4ODAOK/vwDy9vYA3+DgAIF4 + eADAjo4A4svLAMW3twC2k5MAuKOjAF9fXwD4zc0AhnR0AHZlZQChkZEAVlJSAJ55eQBrXl4A18nJAKyA + gADYvr4A7s3NAPXV1QDg0tIAwJKSAMS+vgDrv78AzK+vANy4uADOvr4ArIiIAJuYmACulJQAdm1tAJR9 + fQC0i4sA+fr6ANvFxQDu8PAAjG1tALSamgBkXFwA+tjYAObOzgDczc0A0s3NAMSpqQBxYWEA1sTEAOTm + 5gCNdnYA58fHAKaFhQCYgYEAfnBwANvb2wDw0NAAyMbGAMy1tQCdk5MA/M/PAOa1tQDLv78AZGRkAJBw + cAC4jo4ApZiYANzDwwDdvb0A07m5AHFqagD51NQAhmxsAIJycgCYd3cA4cbGANDKygBuaGgA8szMAOXS + 0gDc0tIA28nJANi2tgC7lZUA0r6+ALyKigDVra0AiHZ2AO3PzwDX19cAoHx8ANXGxgDz8/MA9dHRAOHP + zwDXzc0A2Lu7AKmRkQDPuroAs5WVAMi1tQBNTU0AamRkAJFzcwDnzMwA0sLCAJmXlwB6bm4A59XVAN7M + zADClpYAy7e3APz9/QBiWloA9tbWAO/OzgDpz88A3s/PANnQ0ADT0dEA5MfHANDHxwDYwMAAc2RkAPvV + 1QD/0dEA+s/PAOrNzQDjzc0AqX5+AOK2tgDVwMAAyMHBANC1tQBKTk4A/P//APHz8wCBaWkAjnl5APXS + 0gDw0tIA5M/PAK2BgQDVzc0A2szMANTMzACakZEA576+AOW/vwCgl5cAysXFAKaUlADcvr4A0cPDAMzD + wwCwkJAA0L+/ALSQkADPsbEAZGFhAPnR0QDyz88A0M3NANO4uABgWVkA9vf3AOzu7gD719cA4uPjAPnW + 1gD709MA99LSAPXPzwDv0NAA9czMAOzS0gDo09MA7M7OAOvPzwDi0tIA4c3NALCKigDlyckA3snJALqN + jQC9jo4A0srKAKmVlQDewMAA28LCANq8vADVvr4A1rq6ANG6ugDWt7cA1bW1ANGzswDGu7sA+/v7AIRs + bADw9vYA8PHxAKB5eQDvzMwA5tHRAOjOzgDe0tIA4NDQANjS0gDb0NAA19DQAN7OzgCrk5MA2c3NANzM + zADQz88AuZWVAL6VlQDZysoA2cPDANXCwgByYmIAdWRkAHZqagD9/v4A9PX1AJd2dgCZfX0A/9XVAP/T + 0wD519cAoYCAAPzU1AD61NQA/dHRAPfV1QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + 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 + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACrmZnaq5iY56mYmOeql5fnqJeX56mXl+eml5fnp5eX56WX + l+eml5fnpJeX56WXl+ejl5fno5eX56SXl+eil5fno5eX56GXl+eil5fnoJeX56GXl+efl5fnoJeX556X + l+efl5fnnJeX552Xl+ebl5fnnJeX55qXl+ebl5fnmZeX55mXl+eal5fnmJeX55mYmOeYmJjnmZmZ2gAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACrmJjwyLW1/9HAwP/Rv7//z7+//9C/ + v//Qv7//z7+//8+/v//Ov7//zr+//82/v//Nv7//zL+//8y/v//Lv7//y7+//8u/v//Kv7//yr+//8m/ + v//Jv7//yL+//8i/v//Hv7//x7+//8a/v//Gv7//xb+//8W/v//Ev7//xL+//8O/v//Dv7//wr+//8PA + wP+3tbX/mZiY8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACrl5fw0b+//9/O + zv/dzc3/3c3N/9zNzf/czc3/283N/9vNzf/bzc3/2s3N/9rNzf/Zzc3/2c3N/9jNzf/Yzc3/183N/9fN + zf/Xzc3/1s3N/9bNzf/Vzc3/1c3N/9TNzf/Uzc3/083N/9PNzf/Tzc3/0s3N/9LNzf/Rzc3/0c3N/9DN + zf/Qzc3/z83N/9DOzv/Bv7//mJeX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACtl5fw0b6+/97Nzf/dzMz/3MzM/9zMzP/czMz/28zM/9vMzP/azMz/2szM/9nMzP/ZzMz/2MzM/9jM + zP/YzMz/18zM/9fMzP/WzMz/1szM/9XMzP/VzMz/1MzM/9TMzP/UzMz/08zM/9PMzP/SzMz/0szM/9HM + zP/RzMz/0MzM/9DMzP/QzMz/z8zM/9DNzf/Cvr7/mZeX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACsl5fw076+/9/Nzf/ezMz/3czM/93MzP/czMz/3MzM/9vMzP/bzMz/2szM/9rM + zP/azMz/2czM/9nMzP/YzMz/2c3N/9fMzP/XzMz/2MzM/9bMzP/XzMz/1czM/9XMzP/UzMz/1MzM/9PM + zP/TzMz/08zM/9LMzP/SzMz/0czM/9HMzP/Rzc3/0MzM/9DNzf/Bvr7/m5eX8AAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACtl5fw0r6+/+DNzf/ezMz/3szM/93MzP/dzMz/3czM/9zM + zP/czMz/28zM/9vMzP/azMz/2szM/9nMzP/azc3/yL+//9TS0v/T0dH/09HR/9PR0f/U0dH/0tHR/9LR + 0f/S0dH/0tHR/9LR0f/S0dH/0tHR/9LR0f/T0dH/0dHR/9PS0v/Dv7//0s3N/9HNzf/Cvr7/mpeX8AAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACvl5fw076+/+DNzf/fzMz/4M3N/+DQ + 0P/h0ND/4NDQ/+HQ0P/g0dH/4dHR/+DS0v/h0tL/4tLS/97Pz//czc3/ycDA//39/f/5+vr/+fr6//n6 + +v/6+vr/+vr6//r6+v/6+vr/+vr6//r6+v/6+vr/+vr6//r6+v/6+vr/+vr6//3+/v/Bvb3/0s3N/9LN + zf/Dvr7/nJeX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACul5fw1L6+/+HN + zf/gzc3/2sTE/7mPj/+0kJD/rYuL/6SHh/+cg4P/lH9//4p6ev+BdXX/dW5u/6CXl//ez8//x7+///X1 + 9f/y8vL/8vLy//Ly8v/y8vL/8vLy//Ly8v/y8vL/8vLy//Ly8v/y8vL/8vLy//Ly8v/y8vL/8vLy//X2 + 9v/BvLz/083N/9PNzf/Fvr7/m5eX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACwl5fw1r6+/+LNzf/izc3/3MTE/76MjP+1i4v/rIaG/6GAgP+Ye3v/jXZ2/4Jycv93bGz/amRk/5qS + kv/g0ND/yMDA//Dw8P/u7u7/7u7u/+7u7v/u7u7/7u7u/+7u7v/u7u7/7u7u/+7u7v/u7u7/7u7u/+7u + 7v/u7u7/7u7u//Dx8f/BvLz/1M3N/9PNzf/Evr7/nJeX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACvl5fw1b6+/+PNzf/hzMz/4cvL/93Fxf/cxsb/3MXF/9rExP/YxcX/18TE/9XD + w//VwsL/0sLC/9bGxv/ezc3/y8DA/8vGxv/KxcX/ysXF/8rFxf/KxcX/ysXF/8rFxf/JxcX/ycXF/8nF + xf/JxcX/ycXF/8nFxf/IxcX/yMXF/8jGxv/HwMD/1M3N/9TNzf/Fvr7/npeX8AAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwl5fw1r6+/+PNzf/izMz/4czM/+HNzf/izc3/4M3N/+HN + zf/gzc3/4M3N/9/Nzf/fzc3/383N/97Nzf/ezMz/3c3N/93Nzf/czMz/3MzM/9vMzP/bzMz/28zM/9rM + zP/azMz/2czM/9nNzf/Zzc3/2c3N/9fNzf/Xzc3/2M3N/9bNzf/Wzc3/1MzM/9XNzf/Hvr7/nZeX8AAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACyl5fw2L6+/+TNzf/jzMz/4szM/+LM + zP/hzMz/4czM/+DMzP/gzMz/4MzM/9/MzP/fzMz/3szM/97MzP/dzMz/3czM/9zMzP/czMz/3MzM/9vM + zP/bzMz/2szM/9rMzP/ZzMz/2czM/9nLy//Evb3/yMLC/8jCwv/IwsL/yMLC/8fDw//Mw8P/1s3N/9XN + zf/Gvr7/n5eX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACxl5fw176+/+XN + zf/jzMz/5M3N/+TOzv/kzs7/5M/P/+PPz//jz8//4s/P/+PPz//hz8//4s/P/+LPz//hz8//4s/P/+HQ + 0P/h0ND/4NDQ/+DQ0P/f0ND/3s/P/9zMzP/azMz/2szM/9jJyf/f4OD//f7+//v8/P/7/Pz/+/z8//// + ///Evb3/183N/9bNzf/Hvr7/npeX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACyl5fw2L6+/+bNzf/kzMz/4cbG/8ympv/Lpqb/yaam/8Wjo//Co6P/vqCg/7uenv+4np7/tJub/6+Z + mf+tl5f/qJeX/6aUlP+hkpL/nZGR/5qPj/+VjIz/p52d/97Pz//bzMz/2szM/9jJyf/b29v/9fX1//Pz + 8//z8/P/8/Pz//b29v/Dvb3/183N/9fNzf/Ivr7/n5eX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAC0l5fw2r6+/+bNzf/mzc3/4MTE/8KPj/+/j4//uY2N/7SKiv+th4f/qIWF/6KB + gf+dfn7/lnt7/5F4eP+Ldnb/hnNz/39vb/94bGz/c2pq/21mZv9mYmL/hH19/+HQ0P/czMz/28zM/9nK + yv/X2Nj/8fHx//Dw8P/w8PD/8PDw//Lz8//FvLz/2M3N/9jNzf/Kvr7/oZeX8AAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACzl5fw2b6+/+fNzf/lzMz/5MnJ/9i1tf/XtbX/07Oz/9Cy + sv/PsbH/zLCw/8qvr//Hra3/xKys/8Krq/+/qqr/vKmp/7qoqP+3pqb/tKWl/7KkpP+uoqL/uq2t/+DO + zv/czMz/3MzM/9vKyv+/wMD/0M/P/8/Ozv/Pzs7/z87O/9DPz//EvLz/2c3N/9jNzf/Jvr7/oJeX8AAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC0l5fw2r6+/+jNzf/mzMz/583N/+bN + zf/mzs7/5c7O/+XOzv/mzs7/5M7O/+XOzv/kzs7/5M7O/+POzv/jzs7/5M7O/+LOzv/jz8//4s/P/+LP + z//hz8//4M7O/93MzP/dzMz/3czM/93Nzf/fzc3/3c3N/93Nzf/czc3/3M3N/9vNzf/bzc3/2szM/9nN + zf/Kvr7/oZeX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC2l5fw276+/+jN + zf/nzMz/5szM/+bMzP/mzMz/5czM/+XMzP/kzMz/5MzM/+PMzP/jzMz/48zM/+LMzP/izMz/4czM/+HM + zP/gzMz/4MzM/9/MzP/fzMz/38zM/97MzP/ezMz/3czM/97Nzf/Jvb3/xrq6/8W6uv/Gurr/xLq6/8S6 + uv/SxcX/2szM/9rNzf/Mvr7/o5eX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAC1l5fw3b6+/+nNzf/ozMz/6M3N/+jOzv/nzs7/6M7O/+fOzv/nzs7/6M7O/+fPz//nz8//5s/P/+bP + z//lz8//5s/P/+TOzv/hzMz/4czM/+DMzP/gzMz/38zM/9/MzP/ezMz/3szM/9/MzP/Z2Nj///////z9 + /f/8/f3//P39///////Fvb3/283N/9vNzf/Lvr7/opeX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAC2l5fw3L6+/+rNzf/ozMz/5cfH/9Ktrf/Pra3/zKys/8mqqv/FqKj/waam/72l + pf+5o6P/taGh/7Ofn/+unZ3/qZub/8u3t//kzc3/4czM/+HMzP/gzMz/4MzM/+DMzP/fzMz/38zM/9/M + zP/U09P/9vb2//T09P/09PT/9PT0//f4+P/Gvb3/3c3N/9vNzf/Mvr7/o5eX8AAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC4l5fw3b6+/+vNzf/pzc3/48TE/72MjP+4jIz/sImJ/6mF + hf+ggID/mXx8/5F5ef+IdXX/gXBw/3hsbP9vZ2f/ZGFh/66hof/mzs7/4szM/+LMzP/hzMz/4czM/+DM + zP/gzMz/38zM/+DMzP/S0dH/8fHx/+/v7//v7+//7+/v//Ly8v/HvLz/3M3N/9zNzf/Ovr7/pZeX8AAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC3l5fw376+/+vNzf/qzMz/58fH/9Ss + rP/Qq6v/zKmp/8empv/DpKT/vqKi/7mgoP+1np7/sJub/6yZmf+nl5f/oZOT/8e0tP/lzs7/48zM/+LM + zP/izMz/4czM/+HMzP/hzMz/4MzM/+LMzP/BwcH/1tfX/9XW1v/V1tb/1dbW/9bX1//Furr/3c3N/93N + zf/Pvr7/pJeX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6l5fw3r6+/+zN + zf/rzMz/683N/+vOzv/rzs7/687O/+rPz//rz8//6s/P/+rPz//qz8//6c/P/+rPz//pz8//6c/P/+bO + zv/kzMz/5czM/+TNzf/kzc3/483N/+PNzf/izc3/4s3N/+HNzf/fysr/3snJ/93Jyf/cycn/3MnJ/9vJ + yf/ezMz/3czM/93Nzf/Pvr7/ppeX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAC5l5fw376+/+3Nzf/rzMz/68zM/+vMzP/qzMz/6szM/+nMzP/pzMz/6MzM/+jMzP/nzMz/58zM/+bM + zP/mzMz/5szM/+XMzP/lzMz/5czM/9nDw//Tvr7/0r6+/9K+vv/Rvr7/0b6+/9G+vv/Qvr7/0L6+/9C+ + vv/Pvr7/z76+/8+/v//Xxsb/38zM/97Nzf/Qvr7/pZeX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAC6l5fw4L6+/+7Nzf/szMz/7c3N/+zNzf/tzs7/687O/+zOzv/rzs7/687O/+vO + zv/qzs7/687O/+rOzv/ozc3/5szM/+bMzP/lzMz/5szM/9DLy//z9fX/8fPz//Lz8//y8/P/8vPz//Lz + 8//y8/P/8vPz//Lz8//y8/P/8vPz//T29v/Lw8P/38zM/9/Nzf/Rvr7/ppeX8AAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC7l5fw4r6+/+7Nzf/tzMz/7svL/9q2tv/Ytrb/17a2/9Kz + s//Qs7P/zbCw/8mwsP/Grq7/w6ys/72pqf/cw8P/6M3N/+fMzP/mzMz/6MzM/9PNzf/4+Pj/9vb2//b2 + 9v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//j5+f/NxMT/4MzM/+DNzf/Qvr7/qZeX8AAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC9l5fw4b6+/+/Nzf/vzMz/7czM/7qM + jP+1i4v/rIeH/6KBgf+afX3/j3h4/4V0dP98bm7/cmpq/2NgYP/Er6//687O/+fMzP/nzMz/58zM/9HL + y//x8vL/7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v//Ly8v/Mw8P/4c3N/+DN + zf/Rvr7/qJeX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC8l5fw4r6+//DN + zf/uzMz/78zM/9CkpP/JoaH/w56e/7ybm/+2l5f/rpSU/6mRkf+hjY3/m4qK/5CFhf/QuLj/6s3N/+jM + zP/ozMz/6czM/8rFxf/j5eX/4uPj/+Lj4//i4+P/4uPj/+Lj4//i4+P/4uPj/+Lj4//i4+P/4uPj/+Pl + 5f/Iv7//483N/+HNzf/Tvr7/qZeX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAC+l5fw476+//HNzf/vzMz/8M3N//DOzv/xz8//8M/P//DPz//vz8//8NDQ//HQ0P/w0ND/8dDQ/+/Q + 0P/szs7/6czM/+nMzP/ozMz/6czM/93Fxf/ZwcH/18DA/9jAwP/WwMD/1sDA/9fAwP/VwMD/1cDA/9bA + wP/UwMD/1MDA/9TAwP/ax8f/4szM/+LNzf/Svr7/q5eX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAC9l5fw5b6+//HNzf/wzMz/78zM/+/MzP/vzMz/7szM/+7MzP/tzMz/7czM/+zM + zP/szMz/68zM/+vMzP/qzMz/6szM/+rMzP/pzMz/6szM/+XJyf/kyMj/48fH/+PHx//hx8f/4cfH/+LH + x//gx8f/4cfH/9/Hx//fx8f/4MfH/97IyP/iy8v/4szM/+PNzf/Tvr7/qpeX8AAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC+l5fw5L6+//LNzf/xzMz/8MzM//HNzf/wzc3/8M3N/+/N + zf/vzc3/7s3N/+7Nzf/vzc3/7c3N/+7Nzf/tzc3/7c3N/+vNzf/qzMz/6szM/8vFxf/k5+f/5OXl/+Tl + 5f/k5eX/5OXl/+Tl5f/k5eX/5OXl/+Tl5f/k5eX/5OXl/+Xn5//Kv7//5c3N/+PNzf/Vvr7/q5eX8AAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAl5fw5b6+//PNzf/xzMz/8czM/+bA + wP/lwMD/5L+//+O+vv/hv7//376+/929vf/cvLz/2ru7/9i7u//Wurr/07m5/97Bwf/tzc3/68zM/9XN + zf/4+fn/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//n5+f/PxMT/5MzM/+TN + zf/Uvr7/rZeX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC/l5fw576+//TN + zf/yzMz/8czM/7qNjf+4jIz/sImJ/6iFhf+hgID/mH19/5F5ef+IdXX/gHBw/3ltbf9waWn/ZGJi/5yQ + kP/vz8//7MzM/9HKyv/y8vL/8PDw//Dw8P/w8PD/8PDw//Dw8P/w8PD/8PDw//Dw8P/w8PD/8PDw//Lz + 8//NwsL/5czM/+XNzf/Vvr7/rJeX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AADAl5fw5r6+//TNzf/zzMz/88vL/8qbm//GmZn/vpaW/7iTk/+wkJD/qouL/6OIiP+dhYX/lYKC/49/ + f/+JfHz/fnV1/62bm//wz8//7szM/8/Jyf/u8PD/7O7u/+zu7v/s7u7/7O7u/+zu7v/s7u7/7O7u/+zu + 7v/s7u7/7O7u/+7x8f/NwsL/583N/+XNzf/Xvr7/rpeX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAADCl5fw576+//XNzf/0zMz/9M3N//XPz//1z8//9c/P//TQ0P/10ND/9NDQ//XQ + 0P/20dH/9dHR//bR0f/10tL/9dLS//HPz//uzMz/7c3N/9jAwP/Qurr/0Lq6/9G6uv/Purr/z7q6/9C6 + uv/Ourr/zrq6/8+6uv/Nurr/zbq6/826uv/ZwsL/5s3N/+bNzf/Wvr7/rZeX8AAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADBl5fw6L6+//bNzf/0zMz/9MzM//PMzP/zzMz/88zM//LM + zP/yzMz/8czM//HMzP/wzMz/8MzM/+/MzP/vzMz/7szM/+7MzP/uzMz/7czM/+7Nzf/uzc3/7s3N/+3N + zf/tzc3/683N/+zNzf/qzc3/683N/+vNzf/qzc3/6s3N/+jNzf/ozc3/5szM/+fNzf/Xvr7/rpeX8AAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADCl5fw6r6+//fNzf/1zMz/9czM//TM + zP/0zMz/88zM//PMzP/yzMz/8szM//LMzP/xzMz/8czM//DMzP/wzMz/78zM/+/MzP/uzMz/7szM/+3M + zP/tzMz/7MzM/+zMzP/szMz/68zM/+vMzP/qzMz/6szM/+nMzP/pzMz/6MzM/+jMzP/nzMz/58zM/+jN + zf/Zvr7/sJeX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADEl5fw6b6+//fN + zf/2zMz/9czM//bNzf/3zs7/9s7O//bOzv/1zs7/9c7O//TOzv/1zs7/887O//TOzv/yzs7/887O//LO + zv/yz8//8s/P//HPz//xz8//8M/P//HPz//vz8//8M/P/+7Pz//vz8//7s/P/+7Pz//uz8//7c/P/+3P + z//pzc3/6czM/+jNzf/avr7/r5eX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AADDl5fw6r6+//jNzf/3zMz/983N/+K2tv/Zrq7/2K6u/9etrf/Vra3/1Kys/9Krq//Qqqr/zqmp/8yp + qf/KqKj/yKen/8ampv/EpaX/w6Sk/8Cjo/+/oqL/vKGh/7uhof+4oKD/t5+f/7Senv+ynZ3/sJyc/66b + m/+smpr/qpqa/6WXl//gxcX/6c3N/+nNzf/Zvr7/sZeX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAADFl5fw676+//nNzf/3zMz/+c/P/86goP++kZH/vpGR/7uPj/+4jo7/tYyM/7KL + i/+tiYn/qoaG/6iEhP+jhIT/oIGB/5x/f/+ZfX3/lX19/5F6ev+OeHj/iXZ2/4d1df+Cc3P/gHFx/3tv + b/94bm7/dGxs/3Bqav9taGj/aWVl/15fX//Yvb3/6s3N/+rNzf/avr7/sJeX8AAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADEl5fw7b6+//rNzf/4zMz/+8/P/9Kjo//ElJT/wZOT/76R + kf+7kJD/t46O/7SMjP+wior/rYmJ/6mHh/+mhYX/ooOD/5+Bgf+bgID/mH5+/5R8fP+Qenr/jXl5/4l3 + d/+GdXX/gnNz/35ycv97cHD/d25u/3RsbP9wamr/bGlp/2JiYv/Zvr7/7M3N/+vNzf/cvr7/sZeX8AAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADFl5fw7L6+//rNzf/5zMz/+s7O/9Sj + o//FlJT/wpSU/7+Rkf+8j4//t42N/7SMjP+wior/rYiI/6iGhv+lhYX/oYOD/56AgP+Zfn7/l319/5J7 + e/+PeXn/ind3/4d2dv+DdHT/gHFx/3xxcf95bm7/dGxs/3Fqav9taWn/amdn/19fX//ZvLz/7c3N/+vN + zf/dvr7/s5eX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADHl5fw7b6+//vN + zf/6zMz/+czM//nMzP/6zc3/+c7O//jMzP/5zMz/98zM//jNzf/3zc3/983N//bNzf/1zc3/9s3N//XN + zf/2zc3/9c7O//XOzv/0zs7/88/P//TNzf/yzc3/887O//LOzv/yzs7/8c7O//DOzv/xzs7/8M7O/+/O + zv/tzc3/68zM/+zNzf/cvr7/speX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AADGl5fw77+///3Ozv/7zc3/+83N//rNzf/6zc3/+s3N//nNzf/6zc3/+M3N//jNzf/3zc3/983N//bN + zf/2zc3/9c3N//XNzf/2zc3/9M3N//XNzf/zzc3/9M3N//LNzf/zzc3/8c3N//LNzf/wzc3/8M3N//HN + zf/vzc3/8M3N/+7Nzf/uzc3/7c3N/+7Ozv/ev7//s5eX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAADImJjw5rW1//HAwP/wv7//77+//++/v//uv7//7r+//+2/v//tv7//7L+//+y/ + v//sv7//67+//+u/v//qv7//6r+//+m/v//pv7//6L+//+i/v//nv7//57+//+a/v//mv7//5b+//+W/ + v//kv7//5L+//+S/v//jv7//47+//+K/v//iv7//4b+//+LAwP/VtbX/tZiY8AAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADKmJjjyJiY8MiYmPDGl5fwxpeX8MeXl/DFl5fwxJeX8MSX + l/DFl5fww5eX8MSXl/DCl5fww5eX8MGXl/DCl5fwwJeX8MGXl/C/l5fwwJeX8L6Xl/C/l5fwvZeX8L6X + l/C8l5fwvZeX8LuXl/C8l5fwupeX8LmXl/C5l5fwupeX8LeXl/C2l5fwtpeX8LeYmPC2mJjwt5iY4wAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////AAD4AAAAAB8AAPgAAAAAHwAA+AAAAAAf + AAD4AAAAAB8AAPgAAAAAHwAA+AAAAAAfAAD4AAAAAB8AAPgAAAAAHwAA+AAAAAAfAAD4AAAAAB8AAPgA + AAAAHwAA+AAAAAAfAAD4AAAAAB8AAPgAAAAAHwAA+AAAAAAfAAD4AAAAAB8AAPgAAAAAHwAA+AAAAAAf + AAD4AAAAAB8AAPgAAAAAHwAA+AAAAAAfAAD4AAAAAB8AAPgAAAAAHwAA+AAAAAAfAAD4AAAAAB8AAPgA + AAAAHwAA+AAAAAAfAAD4AAAAAB8AAPgAAAAAHwAA+AAAAAAfAAD4AAAAAB8AAPgAAAAAHwAA+AAAAAAf + AAD4AAAAAB8AAPgAAAAAHwAA+AAAAAAfAAD4AAAAAB8AAPgAAAAAHwAA+AAAAAAfAAD4AAAAAB8AAPgA + AAAAHwAA+AAAAAAfAAD4AAAAAB8AAPgAAAAAHwAA+AAAAAAfAAD4AAAAAB8AAP///////wAA + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/TrayForm.Designer.cs b/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/TrayForm.Designer.cs new file mode 100644 index 0000000..ad4eed0 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/TrayForm.Designer.cs @@ -0,0 +1,155 @@ +namespace AutoFileCryptTool +{ + partial class TrayForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(TrayForm)); + this.contextMenuStrip = new System.Windows.Forms.ContextMenuStrip(this.components); + this.consoleToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripMenuItem5 = new System.Windows.Forms.ToolStripSeparator(); + this.openProtectorSourceCodeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.sdkToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripSeparator(); + this.reportBugToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripMenuItem3 = new System.Windows.Forms.ToolStripSeparator(); + this.exitToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem(); + this.notifyIcon = new System.Windows.Forms.NotifyIcon(this.components); + this.toolStripMenuItemEncryptInfo = new System.Windows.Forms.ToolStripMenuItem(); + this.contextMenuStrip.SuspendLayout(); + this.SuspendLayout(); + // + // contextMenuStrip + // + this.contextMenuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.consoleToolStripMenuItem, + this.toolStripMenuItem5, + this.openProtectorSourceCodeToolStripMenuItem, + this.toolStripMenuItemEncryptInfo, + this.sdkToolStripMenuItem, + this.toolStripMenuItem1, + this.reportBugToolStripMenuItem, + this.toolStripMenuItem3, + this.exitToolStripMenuItem1}); + this.contextMenuStrip.Name = "contextMenuStrip_fileAgent"; + this.contextMenuStrip.Size = new System.Drawing.Size(225, 176); + this.contextMenuStrip.Text = "-"; + // + // consoleToolStripMenuItem + // + this.consoleToolStripMenuItem.Name = "consoleToolStripMenuItem"; + this.consoleToolStripMenuItem.Size = new System.Drawing.Size(224, 22); + this.consoleToolStripMenuItem.Text = "Open FileCrypt Tool"; + this.consoleToolStripMenuItem.Click += new System.EventHandler(this.consoleToolStripMenuItem_Click); + // + // toolStripMenuItem5 + // + this.toolStripMenuItem5.Name = "toolStripMenuItem5"; + this.toolStripMenuItem5.Size = new System.Drawing.Size(221, 6); + // + // openProtectorSourceCodeToolStripMenuItem + // + this.openProtectorSourceCodeToolStripMenuItem.Name = "openProtectorSourceCodeToolStripMenuItem"; + this.openProtectorSourceCodeToolStripMenuItem.Size = new System.Drawing.Size(224, 22); + this.openProtectorSourceCodeToolStripMenuItem.Text = "Open SDK folder"; + this.openProtectorSourceCodeToolStripMenuItem.Click += new System.EventHandler(this.openProtectorSourceCodeToolStripMenuItem_Click); + // + // sdkToolStripMenuItem + // + this.sdkToolStripMenuItem.Name = "sdkToolStripMenuItem"; + this.sdkToolStripMenuItem.Size = new System.Drawing.Size(224, 22); + this.sdkToolStripMenuItem.Text = "SDK manual"; + this.sdkToolStripMenuItem.Click += new System.EventHandler(this.sdkToolStripMenuItem_Click); + // + // toolStripMenuItem1 + // + this.toolStripMenuItem1.Name = "toolStripMenuItem1"; + this.toolStripMenuItem1.Size = new System.Drawing.Size(221, 6); + // + // reportBugToolStripMenuItem + // + this.reportBugToolStripMenuItem.Name = "reportBugToolStripMenuItem"; + this.reportBugToolStripMenuItem.Size = new System.Drawing.Size(224, 22); + this.reportBugToolStripMenuItem.Text = "Report bug or make suggestion"; + this.reportBugToolStripMenuItem.Click += new System.EventHandler(this.reportBugToolStripMenuItem_Click); + // + // toolStripMenuItem3 + // + this.toolStripMenuItem3.Name = "toolStripMenuItem3"; + this.toolStripMenuItem3.Size = new System.Drawing.Size(221, 6); + // + // exitToolStripMenuItem1 + // + this.exitToolStripMenuItem1.Name = "exitToolStripMenuItem1"; + this.exitToolStripMenuItem1.Size = new System.Drawing.Size(224, 22); + this.exitToolStripMenuItem1.Text = "Exit"; + this.exitToolStripMenuItem1.Click += new System.EventHandler(this.exitToolStripMenuItem1_Click); + // + // notifyIcon + // + this.notifyIcon.ContextMenuStrip = this.contextMenuStrip; + this.notifyIcon.Icon = ((System.Drawing.Icon)(resources.GetObject("notifyIcon.Icon"))); + this.notifyIcon.Text = "EaseFilter File Protector"; + this.notifyIcon.Visible = true; + // + // toolStripMenuItemEncryptInfo + // + this.toolStripMenuItemEncryptInfo.Name = "toolStripMenuItemEncryptInfo"; + this.toolStripMenuItemEncryptInfo.Size = new System.Drawing.Size(224, 22); + this.toolStripMenuItemEncryptInfo.Text = "Transparent file encryption"; + this.toolStripMenuItemEncryptInfo.Click += new System.EventHandler(this.toolStripMenuItemEncryptInfo_Click); + // + // TrayForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(263, 102); + this.Name = "TrayForm"; + this.Text = "TrayForm"; + this.WindowState = System.Windows.Forms.FormWindowState.Minimized; + this.Load += new System.EventHandler(this.TrayForm_Load); + this.contextMenuStrip.ResumeLayout(false); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.ContextMenuStrip contextMenuStrip; + private System.Windows.Forms.ToolStripMenuItem consoleToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem sdkToolStripMenuItem; + private System.Windows.Forms.ToolStripSeparator toolStripMenuItem5; + private System.Windows.Forms.ToolStripSeparator toolStripMenuItem3; + private System.Windows.Forms.ToolStripMenuItem reportBugToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem exitToolStripMenuItem1; + public System.Windows.Forms.NotifyIcon notifyIcon; + private System.Windows.Forms.ToolStripMenuItem openProtectorSourceCodeToolStripMenuItem; + private System.Windows.Forms.ToolStripSeparator toolStripMenuItem1; + private System.Windows.Forms.ToolStripMenuItem toolStripMenuItemEncryptInfo; + } +} \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/TrayForm.cs b/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/TrayForm.cs new file mode 100644 index 0000000..424806f --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/TrayForm.cs @@ -0,0 +1,106 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +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; +using System.IO; + +using EaseFilter.FilterControl; +using EaseFilter.CommonObjects; + +namespace AutoFileCryptTool +{ + public partial class TrayForm: Form + { + Form_FileCrypt fileCryptForm = null; + + public TrayForm() + { + + InitializeComponent(); + this.Hide(); + + fileCryptForm = new Form_FileCrypt(); + + } + + private void TrayForm_Load(object sender, EventArgs e) + { + this.Hide(); + this.notifyIcon.Visible = true; + fileCryptForm.ShowDialog(); + } + + private void consoleToolStripMenuItem_Click(object sender, EventArgs e) + { + + if (!fileCryptForm.Visible) + { + fileCryptForm.StartPosition = FormStartPosition.CenterScreen; + fileCryptForm.ShowDialog(); + } + } + + private void settingsToolStripMenuItem_Click(object sender, EventArgs e) + { + SettingsForm settingForm = new SettingsForm(); + settingForm.StartPosition = FormStartPosition.CenterScreen; + settingForm.ShowDialog(); + } + + + private void reportBugToolStripMenuItem_Click(object sender, EventArgs e) + { + System.Diagnostics.Process.Start("http://www.easefilter.com/ReportIssue.htm"); + } + + private void exitToolStripMenuItem1_Click(object sender, EventArgs e) + { + GlobalConfig.Stop(); + fileCryptForm.Close(); + + Application.Exit(); + } + + private void sdkToolStripMenuItem_Click(object sender, EventArgs e) + { + System.Diagnostics.Process.Start("http://www.easefilter.com/info/easefilter_manual.pdf"); + } + + + private void openProtectorSourceCodeToolStripMenuItem_Click(object sender, EventArgs e) + { + System.Reflection.Assembly assembly = System.Reflection.Assembly.GetEntryAssembly(); + string AssemblyPath = Path.Combine(Path.GetDirectoryName(assembly.Location), "Demo"); + System.Diagnostics.Process.Start("explorer.exe", AssemblyPath); + } + + private void toolStripMenuItemEncryptInfo_Click(object sender, EventArgs e) + { + System.Diagnostics.Process.Start("http://easefilter.com/Forums_Files/Transparent_Encryption_Filter_Driver.htm"); + } + + + + } +} diff --git a/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/TrayForm.resx b/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/TrayForm.resx new file mode 100644 index 0000000..53ba4c7 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/TrayForm.resx @@ -0,0 +1,155 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 19, 18 + + + 214, 23 + + + + + AAABAAEAEBAAAAEACABoBQAAFgAAACgAAAAQAAAAIAAAAAEACAAAAAAAQAEAAAAAAAAAAAAAAAEAAAAA + AAAAAAAA////AAUBAAAXBwEAKhEEACgQBAAsEgUALRMFADMXBwA0GAcAOBoIADkbCQA7HQoAPx8LAEEh + CwBAIAsAQiIMAEYkDQBDIw0ASScPAE8sEgBSLhMATSsSAFUxFQBWMhYAWjYYAFk1GABdOBoAYDscAF86 + HABhPB0AYj0dAGM+HgBkPx8AZkEgAGdCIQBsRyUAa0YlAG1IJgBxTCkAdE8rAHZRLQB+WDMAhF86AIRg + OwCFYTwAh2M+AP37+QCJZT8AimZAAIxoQgCNaUMAkGxGAJFtRwCTcEoAkm9JAJRxSwCXdE4AmHVPAJx6 + VACbeVMAnn1XAJ18VgCgf1kAo4NdAKaGYQCoiGMAp4diAKmJZACqimUAqotmAK2PawCvkW0AsZNvALCS + bgCylHAAs5ZzANjFrwC2mncAuZ58ALyhfwC7oH4Aup99AL6kgwDAp4cAw6qKAMWtjgDErI0Axa6QAMix + kwDJs5UAyrSWAMu1mQDMtpoA07+lANPApgDYx7AA6d7PAPPt5QDOup4A08GoANbEqwDUwqkA39C7AN3O + uQDh1MEA7uXYAO/n3ADx6uAA8uzjAPz69wD6+PUA6eDSAPTv5wD49fAA////AAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAYGBgYGBgAAAAAAAAAAAgFADNNcDMAAw0AAAAAAA1UBzMAAAAARwdGDQAAABM4WAZM + ODg4OEsJSzgTAAAUPFoLUj0CAj9PDFs+FQAAIEVkJ11PLi5RXSllSiIAAChQaCxrWUVFWWEtZ1UqAAAr + XwEAAC9HSW4AAAFmNgAAK3EAAABDWlpCAAAAajQAI0cAYgFkZldXZF4BYgBIJx8AbGNJAE5KSEsAU11s + ACEATjY6AERcBQVgQAA4Nk4AJDEwAEFpCDc1BWFAADAwFw4sADtvOS1Wckw1bT4ALBUEChYmMjcREhAP + Mi4lGhQLAAAAABseHh4cHRsZAAAAAPgfAADgBwAAwAMAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAPAPAAA= + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/VerifyPassword.Designer.cs b/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/VerifyPassword.Designer.cs new file mode 100644 index 0000000..f6a648e --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/VerifyPassword.Designer.cs @@ -0,0 +1,99 @@ +namespace AutoFileCryptTool +{ + partial class VerifyPasswordForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(VerifyPasswordForm)); + this.button_VerifyPassword = new System.Windows.Forms.Button(); + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.label1 = new System.Windows.Forms.Label(); + this.textBox_Password1 = new System.Windows.Forms.TextBox(); + this.groupBox1.SuspendLayout(); + this.SuspendLayout(); + // + // button_VerifyPassword + // + this.button_VerifyPassword.Location = new System.Drawing.Point(281, 84); + this.button_VerifyPassword.Name = "button_VerifyPassword"; + this.button_VerifyPassword.Size = new System.Drawing.Size(75, 23); + this.button_VerifyPassword.TabIndex = 6; + this.button_VerifyPassword.Text = "Ok"; + this.button_VerifyPassword.UseVisualStyleBackColor = true; + this.button_VerifyPassword.Click += new System.EventHandler(this.button_VerifyPassword_Click); + // + // groupBox1 + // + this.groupBox1.Controls.Add(this.label1); + this.groupBox1.Controls.Add(this.textBox_Password1); + this.groupBox1.Location = new System.Drawing.Point(12, 12); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size(359, 60); + this.groupBox1.TabIndex = 5; + this.groupBox1.TabStop = false; + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(20, 16); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(114, 13); + this.label1.TabIndex = 0; + this.label1.Text = "Enter master password"; + // + // textBox_Password1 + // + this.textBox_Password1.Location = new System.Drawing.Point(140, 16); + this.textBox_Password1.Name = "textBox_Password1"; + this.textBox_Password1.Size = new System.Drawing.Size(204, 20); + this.textBox_Password1.TabIndex = 2; + this.textBox_Password1.UseSystemPasswordChar = true; + // + // VerifyPassword + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(383, 119); + this.Controls.Add(this.button_VerifyPassword); + this.Controls.Add(this.groupBox1); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Name = "VerifyPassword"; + this.Text = "Verify Password"; + this.groupBox1.ResumeLayout(false); + this.groupBox1.PerformLayout(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.Button button_VerifyPassword; + private System.Windows.Forms.GroupBox groupBox1; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.TextBox textBox_Password1; + } +} \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/VerifyPassword.cs b/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/VerifyPassword.cs new file mode 100644 index 0000000..22c97fa --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/VerifyPassword.cs @@ -0,0 +1,56 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +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; + +using EaseFilter.CommonObjects; + +namespace AutoFileCryptTool +{ + public partial class VerifyPasswordForm : Form + { + public bool isPasswordMatched = false; + + public VerifyPasswordForm() + { + InitializeComponent(); + this.StartPosition = FormStartPosition.CenterScreen; + } + + private void button_VerifyPassword_Click(object sender, EventArgs e) + { + if (string.Compare(textBox_Password1.Text, GlobalConfig.MasterPassword, false) != 0) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("The password is not correct.", "Password", MessageBoxButtons.OK, MessageBoxIcon.Error); + isPasswordMatched = false; + } + else + { + isPasswordMatched = true; + this.Close(); + } + } + } +} diff --git a/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/VerifyPassword.resx b/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/VerifyPassword.resx new file mode 100644 index 0000000..5724be6 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/VerifyPassword.resx @@ -0,0 +1,570 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + AAABAAgAEBAAAAEACABoBQAAhgAAABAQAAABACAAaAQAAO4FAAAYGAAAAQAIAMgGAABWCgAAGBgAAAEA + IACICQAAHhEAACAgAAABAAgAqAgAAKYaAAAgIAAAAQAgAKgQAABOIwAAMDAAAAEACACoDgAA9jMAADAw + AAABACAAqCUAAJ5CAAAoAAAAEAAAACAAAAABAAgAAAAAAEABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP// + /wClcmwA9cKUALS0tADu2s4AyZZ+AJqZmQDPzMoA//DhAOGuigD/3LgA5eXlALeEdQD/584A8/PzANjY + 2ADkvJgA1aKEAKZ9eQDbx8QAx8TCAMeeiQD/+fMA8+zkAK57cADBjnoA7bqQAP706gCfn58A/+vWAP/g + wAD6+voA3d3dANyphwD/5McA5eLfAOC4lQCpdm4As4BzAL2KeADFknwA+caWAPG+kgDlsowA6baOAMfH + xwCqgXoA0p+CAPv49QD//fsA//v3AP/y5QD/7t0A/+nSALqHdwDZpoYA/ejVAMSciAD/9/AAn52cAP/l + ywDPzs0A9fX1APz8/AD/7doAsX5yALWCdAD/9uwA16SEAPX08wD/9OgA/v7+APn5+QC5hnYAvot5AMKP + ewDGk30A3aqIAK16cAD7+vkAmpqaANjX1wC0s7MAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAADoGKRooSkNCTyYCEwAAABYFSUkgQEgBAQEBARQTAAAwAQlEMwEBAQEBAQEB + AgAARQEJRD5RIQEBAQEBASYAACIBCURQEAwBAQEBAQEZAAAKATVHFzIBAQEBAQEBJwAALAFBNAgHIQ8E + HQEBAQ0AAC0BHjUxUiRIPy4BAUg3AAAbAQ4eCUc7MzIBAQFASwAAKwEjNkEJRxhTPDMzIEwAAAMBHz02 + HjUcRhVERElNAAAqAQsfIw4eQTUJCQlJBgAAETkBAQEBAQEBAQEBBS8AAAAlKgMrGy0sCk44Ei8AAAAA + AAAAAAAAAAAAAAAAAAD//wAAwAMAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAIAB + AACAAQAAgAEAAMADAAD//wAAKAAAABAAAAAgAAAAAQAgAAAAAABABAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAMuYf8zJln7/xZJ8/8GOev+9inj/uYZ2/7WCdP+xfnL/rXpw/6l2bv+lcmz/pXJszAAA + AAAAAAAAAAAAAM6bgMzu2s7/+fn5//n5+f/6+vr//Pz8//7+/v///////////////////////////9vH + xP+lcmzMAAAAAAAAAADSn4L////////w4f//9uz///v3//////////////////////////////////// + ////////pXJs/wAAAAAAAAAA16SE////////8OH///bs/8/Ozf+ampr/3d3d//////////////////// + /////////////6l2bv8AAAAAAAAAANyph/////////Dh///27P/7+vn/2NjY/+Xl5f////////////// + //////////////////+ue3D/AAAAAAAAAADhror////////u3f//9Oj///nz///9+/////////////// + ////////////////////////s4Bz/wAAAAAAAAAA5bKM////////7dr///Ll/8/Myv+amZn/3d3d//Pz + 8/+0tLT/n5+f/////////////////7eEdf8AAAAAAAAAAOm2jv///////+vW///u3f/7+PX/2NfX/+Xi + 3//+/v7/9fX1/8fHx/////////////7+/v+6h3f/AAAAAAAAAADtupD////////nzv//69b///Dh///0 + 6P//9/D///v3///9+//////////////////8/Pz/vot5/wAAAAAAAAAA8b6S////////5Mf//+nS///t + 2v//8OH///To//Ps5P+0s7P/n52c///79///+/f/+vr6/8KPe/8AAAAAAAAAAPXClP///////+DA///l + y///6dL//+vW///u3f/+9Or/9fTz/8fEwv//9uz///bs//n5+f/Gk33/AAAAAAAAAAD5xpb////////c + uP//4MD//+TH///nzv//69b//+3a///u3f//8OH///Dh///w4f/5+fn/yZZ+/wAAAAAAAAAA88CTzP3o + 1f//////////////////////////////////////////////////////7trO/6p3bswAAAAAAAAAAAAA + AADuu5DM+caW//XClP/xvpL/7bqQ/+m2jv/lsoz/4a6K/92qiP/Zpob/1aKE/6p3bswAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAD//wAAwAMAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAMAD + AAD//wAAKAAAABgAAAAwAAAAAQAIAAAAAACgAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8Ao3BrAPXC + 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 + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADJln6pyZZ+/8aTfP/EkXv/wY56/7+Mef+9inj/uod2/7iF + df+2g3T/s4Bz/7F+cv+vfHH/rHlv/6p3bv+odW3/pXJs/6Nwa/+hbmr/nmtoqQAAAAAAAAAAAAAAAM6b + gKnZr5j/9eLU///27v//+vX///38//////////////////////////////////////////////////// + ///////////////////y6+r/t5GO/55raKkAAAAAAAAAANKfgv/24dD///Pn///27v/Lysn/m5qa//// + ///Ly8v/m5ub/////////////////8vLy/+bm5v/////////////////////////////////8uvq/6Fu + av8AAAAAAAAAANShg/////////Ll///17P///fz/xsXF////////////xsbG//////////////////// + ///Gxsb//////////////////////////////////////6Nwa/8AAAAAAAAAANajhP////////Ll///0 + 6v//9/H///v4//////////////////////////////////////////////////////////////////// + /////////////6VybP8AAAAAAAAAANilhf////////Dj///06v//9u7///r1///9/P////////////// + /////////////8vLy/+bm5v//////8vLy/+bm5v//////////////////////6l2bv8AAAAAAAAAANqn + hv///////+/g///z5///9ez///nz///8+v/////////////////////////////////Gxsb///////// + ///Gxsb//////////////////////6t4b/8AAAAAAAAAAN2qh////////+7e///w4///9Or///fx///6 + 9f///fz//////////////////////////////////////////////////////////////////////657 + cP8AAAAAAAAAAOCtif///////+zZ///v4P/LyMX/m5iW///58//Ly8r/m5ub//////////////////// + /////////////8vLy/+bm5v//////////////////////7B9cf8AAAAAAAAAAOKviv///////+rX///u + 3v//+/j/xsPB///27v///vz/xsXF///////////////////////////////////////Gxsb///////// + /////////////7J/cv8AAAAAAAAAAOSxi////////+nV///s2f//7+D///Ll///17P//9/H///r1///9 + /P///////////////////////////////////////////////////////////7WCdP8AAAAAAAAAAOaz + jP///////+fQ///q1///7dz//+/g///z5///9ez///fx///7+P///fz///////////////////////// + /////////////////////////////7iFdf8AAAAAAAAAAOi1jv///////+XM///o0v/LxsH/m5aS///w + 4///8+f///Xs///38f//+vX///z6/////////////////////////////////////////////////7qH + dv8AAAAAAAAAAOy5j////////+PJ///mzv//+fP/xsG9///u3v//8OP///Pn///17P//9/H///r1///8 + +v///fz//////////////////////////////////////72KeP8AAAAAAAAAAO67kP///////+HF///j + yf//5s7//+nV///s2f//7t7///Dj///z5///9ez///bu///58///+vX///z6///9/P////////////// + /////////////7+Mef8AAAAAAAAAAPC9kf///////9/A///hxf/LxL7/m5SO///p1f/Lx8L/m5aS///v + 4P//8uX///Tq///17P//9/H///nz/8vKyf+bmpn///z6///9/P///fz///38/8GOev8AAAAAAAAAAPK/ + k////////928///fwP//9/D/xr+5///mzv//+fP/xsG8///t3P//7+D///Dj///z5///9Or///Xs///9 + +v/GxMP///nz///69f//+vX///r1/8SRe/8AAAAAAAAAAPTBlP///////9u4///dvP//38D//+HF///j + yf//5s7//+jS///q1///7Nn//+7e///v4P//8OP///Pn///06v//9Or///Xs///27v//9u7///bu/8eU + ff8AAAAAAAAAAPbDlf///////9mz///buP//3bz//9/A///hxf/LxL7/m5SN///n0P//6dX//+rX/8vH + wv+blpL//+/g///w4///8uX///Ll///z5///8+f///Pn/8qXfv8AAAAAAAAAAPnGlv/+8eb//+7e///Z + s///27j//928///evv//9+//xr+4///lzP//5s7//+fQ///59P/Gwbz//+zZ///t3P//7t7//+7e///v + 4P//7+D/9uDQ/8yZf/8AAAAAAAAAAPjFlj36ypz//vHm//////////////////////////////////// + ///////////////////////////////////////////////////338z/27KZ/8yZf6kAAAAAAAAAAAAA + AAD4xZY9+caW//fElf/1wpT/88CT//G+kv/vvJH/7bqQ/+q3j//otY7/5rOM/+Sxi//ir4r/4K2J/96r + iP/ap4b/2KWF/9ajhP/UoYP/0J2BqQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA////AMAAAwCAAAEAgAABAIAAAQCAAAEAgAABAIAAAQCAAAEAgAABAIAAAQCAAAEAgAABAIAA + AQCAAAEAgAABAIAAAQCAAAEAgAABAIAAAQCAAAEAwAABAOAAAwD///8AKAAAACAAAABAAAAAAQAIAAAA + AACABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8Ao3BrAPXClACnp6cA4trTAM+cgAD/3LkA/+7eALu7 + uwCzi4kA2byhAOKvigDp6ekAtIFzALuxpwD/5cwAoHx6AMKPegD/9+8AyJ6QAKCenADy8vIA572fAO/a + zgDp4t0A2KWFAOy5jwCreG8AspaNAOLVyQCcaWcA/+nVAP/gwgC7tbAA//LnALqHdgDJln0A+8iXAP/7 + 9wDi4uIA6dnWALWRhQDntIwA4t7cAKd0bQCvfHEAvot4ANOgggDxvpIA3KmHAOnd0gD9/PwAn2xpAP/s + 2gD/59EA6eThAP/jyACgoKAAp6WjALu5twC3hHQAxZJ7AMyZfwD4xZUA//HjAOnh2QD/3b0A//n0AP/1 + 7ADv29EAoW5qAKVybACpdm4ArXpwALF+cgDAjXkAx5R8ANGegQDzwJMA1qOEAO67kADap4YA6reOAN6r + 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 + AAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPgAAAH//////////8oAAAAIAAAAEAAAAABACAAAAAAAIAQ + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALqHdrW2g3T/tYJz/7SB + c/+zgHL/sX5y/7B9cf+vfHH/rntw/616cP+seW//q3hv/6l2bv+odW3/p3Rt/6ZzbP+lcmz/pHFr/6Nw + a/+hbmr/oG1p/59saf+ea2j/nWpo/5xpZ/+caWe1AAAAAAAAAAAAAAAAAAAAAAAAAAC6h3a1yJ6Q/+/b + 0f//+PL///v3///+/f////////////////////////////////////////////////////////////// + ////////////////////////////////////////6dnW/7OLif+caWe1AAAAAAAAAAAAAAAAAAAAAL6L + eP/v2s7///Xs///48v//+/f/6ejo/6enp/+7u7v//////+np6f+np6f/u7u7//////////////////// + ///p6en/p6en/7u7u///////////////////////////////////////6dnW/59saf8AAAAAAAAAAAAA + AAAAAAAAwI15///+/v//9ez///jy///79///////8vLy/6CgoP////////////Ly8v+goKD///////// + ///////////////////y8vL/oKCg////////////////////////////////////////////oW5q/wAA + AAAAAAAAAAAAAAAAAADDkHr////////06v//9/D///r1///+/f/9/f3/4uLi/////////////f39/+Li + 4v////////////////////////////39/f/i4uL///////////////////////////////////////// + //+kcWv/AAAAAAAAAAAAAAAAAAAAAMaTfP////////Pp///27v//+fT///z5//////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////////6d0bf8AAAAAAAAAAAAAAAAAAAAAyZZ9////////8+n///bu///48v//+/f///79//// + /////////////////////////////////////////////+np6f+np6f/u7u7///////p6en/p6en/7u7 + u///////////////////////qndu/wAAAAAAAAAAAAAAAAAAAADKl37////////y5///9ez///jy///6 + 9f///fv///////////////////////////////////////////////////////Ly8v+goKD///////// + ///y8vL/oKCg//////////////////////+seW//AAAAAAAAAAAAAAAAAAAAAMyZf/////////Ll///0 + 6v//9/D///n0///8+f///////////////////////////////////////////////////////f39/+Li + 4v////////////39/f/i4uL//////////////////////698cf8AAAAAAAAAAAAAAAAAAAAAz5yA//// + ////8eP///Pp///17P//+PL///v3///+/f////////////////////////////////////////////// + ////////////////////////////////////////////////////////sn9y/wAAAAAAAAAAAAAAAAAA + AADRnoH////////w4f//8uf///Tq/+nk4f+np6b/u7m3///////p6en/p6en/7u7u/////////////// + /////////////////////////////+np6f+np6f/u7u7//////////////////////+0gXP/AAAAAAAA + AAAAAAAAAAAAANShg////////+/g///x4///8+n///79//Ly8v+goJ////79///////y8vL/oKCg//// + //////////////////////////////////////////////Ly8v+goKD//////////////////////7eE + dP8AAAAAAAAAAAAAAAAAAAAA16SE////////7dz///Dh///y5///+fT//fz8/+Le3P///Pn///7+//39 + /f/i4uL//////////////////////////////////////////////////f39/+Li4v////////////// + ////////uod2/wAAAAAAAAAAAAAAAAAAAADap4b////////s2v//7+D///Hj///z6f//9ez///jy///6 + 9f///fv///////////////////////////////////////////////////////////////////////// + //////////////////+9inf/AAAAAAAAAAAAAAAAAAAAANyph////////+rW///t3P//8OH///Ll///0 + 6v//9u7///jy///79////fv///////////////////////////////////////////////////////// + /////////////////////////////7+MeP8AAAAAAAAAAAAAAAAAAAAA3quI////////6dX//+vY///u + 3v/p4dn/p6al/7u1r///9/D///n0///79////fv///////////////////////////////////////// + ////////////////////////////////////////wo96/wAAAAAAAAAAAAAAAAAAAADhror////////n + 0f//6tb//+za///+/P/y8vL/oJ+e///17P//9/D///n0///79////fv///////////////////////// + ///////////////////////////////////////////////////Fknv/AAAAAAAAAAAAAAAAAAAAAOOw + i////////+bP///o0///6tb///bt//38+v/i29T///Pp///17P//9/D///n0///79////fv///////// + /////////////////////////////////////////////////////////////8eUfP8AAAAAAAAAAAAA + AAAAAAAA5rOM////////5cz//+bP///p1f//69j//+3c///w4f//8uX///Pp///17P//9/D///n0///7 + 9////fv///79////////////////////////////////////////////////////////////ypd+/wAA + AAAAAAAAAAAAAAAAAADpto3////////jyP//5cz//+fR/+nd0v+npaP/u7Gn///w4f/p4tv/p6al/7u1 + sP//9/D///jy///69f///Pn///79/////////////////+np6f+np6f/u7u7//////////////////// + ///MmX//AAAAAAAAAAAAAAAAAAAAAOu4jv///////+HE///kyv//5c3///37//Ly8v+gnpz//+3c///+ + /P/y8vL/oJ+e///06v//9u7///jy///59P//+/f///z5///+/f////////////Ly8v+goKD///////// + /////////////82af/8AAAAAAAAAAAAAAAAAAAAA7bqQ////////38H//+LG///kyv//8ub//fv5/+LW + y///69j///bt//38+v/i2tP///Ln///06v//9ez///fw///48v//+vX///v3///8+f///v3//f39/+Li + 4v//////////////////////0J2B/wAAAAAAAAAAAAAAAAAAAADwvZH////////dvf//4ML//+LG///k + yv//5c3//+fR///p1f//69j//+3c///v4P//8OH///Ll///z6f//9Or///bu///38P//+PL///n0///6 + 9f//+/f///z5///9+////fv///79///+/f/ToIL/AAAAAAAAAAAAAAAAAAAAAPPAk////////9y5///e + v///4ML//+LG///kyv//5c3//+fR/+nd0v+npaP/u7Cm///u3v//8OH///Hj///y5//p4t3/p6al/7u1 + sP//9/D///jy///48v//+fT///r1///79///+/f///v3/9ajhP8AAAAAAAAAAAAAAAAAAAAA9cKU//// + ////5s3//9y5///ev///4ML//+LG///kyv//5cz///37//Ly8v+gnpz//+vY///t3P//7+D///Dh///+ + /P/y8vL/oJ+e///06v//9ez///bu///27v//9/D///jy///48v//+PL/2KWF/wAAAAAAAAAAAAAAAAAA + AAD4xZX////////48v//5s3//9y5///dvf//38H//+HE///jyP//8uX//fv5/+LVyf//6dX//+rW///s + 2v//7dz///fv//38+v/i2tP///Ll///y5///8+n///Pp///06v//9ez///Xs/+7a0f/bqIb/AAAAAAAA + AAAAAAAAAAAAAPvIl4/6x5b///////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////9+//u2s3/572f/7aD + dI8AAAAAAAAAAAAAAAAAAAAAAAAAAPvIl4/7yJf/+seW//nGlv/4xZX/98SV//XClP/0wZP/88CT//K/ + kv/xvpL/8L2R/+67kP/tupD/7LmP/+y5j//ruI7/6reO/+m2jf/ntIz/5rOM/+Wyi//ksYv/47CL/+Kv + iv+2g3SPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////4AAAB8AAAAPAAAADwAAAA8AA + AAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AA + AAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAAD4AAAB///////////KAAAADAAAABgAAAAAQAIAAAA + AACACgAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8Ao3BrAPbDlACpqagA19bUAM+cgAD/3LkA/fDdAL+/ + vwCzi4kA376fAOKvigDq6ekAtIFzALuxpwD/5cwApYB9AMKPegD/+O8AxqKOAJmXlQDy8vIA7MOcAO/a + zgDp4t0A2KWFAOy5jwCreG8AspaNANPOygCcaWcA+OjWAP/gwgC7tbAA+vLnALqHdgDJln0A/MmXAP/7 + 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 + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADPnICj0J2B/9Cd + gf/QnYH/0J2B/9Cdgf/QnYH/0J2B/8+cgP/PnID/z5yA/86bgP/Om4D/zpuA/82af//Nmn//zJl//8yZ + f//MmX//yZZ9/8iVff/Gk3z/xJF7/8KPev/Bjnn/vot4/72KeP+7iHb/uYZ1/7aDdP+0gXP/s4By/7B9 + cf+ue3D/q3hv/6l2bv+ndGz/n2xoowAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANKf + gszQnYH/7tS////04///9OT///Xl///15///9ej///bp///26v//9+v///fs///47f//+O7///nv///5 + 8P//+fL///rz///69P//+/X///v2///89////Pj///z5///9+v///fz///79///+/v////////////// + ///////////////////////////////////ey8n/p3Rs/6Rxa8wAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA06CCo9Gegf/24s7///Pi///04///9OT///Xl///15///9ej///bp///26v//9+v///fs///4 + 7f//+O7///nv///58P//+fL///rz///69P//+/X///v2///89////Pj///z5///9+v///fz///79///+ + /v//////////////////////////////////////////////////////7eLh/6d0bP+fbGijAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA1KGD//Xl2P//+O3///Pi///04///9OT//PPl/9fV0f+pqKj/m5iV/+ri + 1///9+v///fs//z27P/X1tP/qamo/5uZl//q5d////rz///69P//+/X///v2///89////Pj//Pn3/9fX + 1v+pqan/m5qa/+rp6P///////////////////////////////////////////////////////////97L + yf+ndGz/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1aKD////////8+H///Pi///04///9OT///z4//v7 + +//p6en/v7+//5eVkv//9+v///fs///9+v/7+/v/6enp/7+/v/+XlZP///ry///68///+/X///v2///7 + 9////Pj///79//v7+//p6en/v7+//5eXl////v7///////////////////////////////////////// + //////////////////+pdm7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1qOE////////8+H///Pi///0 + 4///9OT////+////////////6Ojo/6Wko///9+v///fs/////////////////+jo6P+lpKT///ry///6 + 8///+/X///v2///79v///Pf/////////////////6Ojo/6Wlpf///v7///////////////////////// + //////////////////////////////////+reG//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA16SE//// + ////8+H///Pi///04///9OT///z4////////////9/f3/9HPzP//9+v///fs///9+v////////////f3 + 9//R0M7///ry///68///+vT///v1///79v///Pf///79////////////9/f3/9HR0f///v3///////// + //////////////////////////////////////////////////+ue3D/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA2KWF////////8+H///Pi///z4v//9OT///Xo///8+f////7/+ffz//ry5///9ur///fr///4 + 7v///fv///////n49f/69e3///ny///68///+vT///v1///79v//+/f///z5///+/f//////+fn4//r4 + 9////v3///7+//////////////////////////////////////////////////////+wfXH/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA2aaG////////8+D///Ph///z4v//9OT///Tl///15v//9ef///Xo///2 + 6f//9ur///fr///37P//+O3///ju///57///+fD///nx///68v//+vP///v1///79f//+/b///z3///8 + +P///Pn///36///9+////vz///79///+/v////////////////////////////////////////////// + //+zgHL/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA26iG////////8uD///Ph///z4v//9OP///Tk///1 + 5f//9ef///Xo///26f//9un///fr///37P//+O3///ju///47///+fD///nx///68v//+vP///r0///7 + 9f//+/b//Pj1/9fX1v+pqan/m5qZ/+ro5v///fz///78//z7+v/X19f/qamp/5ubm//q6ur///////// + //////////////////+0gXP/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3KmH////////8uD///Ph///z + 4v//9OP///Tk///05f//9eb///Xn///26P//9un///bq///36///9+z///ju///47v//+e////nw///5 + 8v//+vL///rz///79f//+/X///79//v7+//p6en/v7+//5eXlv///fv///38/////v/7+/v/6enp/7+/ + v/+Xl5f///////////////////////////+2g3T/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3aqH//// + ////8uD///Ph///z4v//8+L///Tk///05f//9eb///Xn///26P//9un///bq///36///9+z///jt///4 + 7v//+O////nw///58f//+vL///rz///69P//+/X/////////////////6Ojo/6WkpP///fr///37//// + /////////////+jo6P+lpaX///7+//////////////////////+5hnX/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA3quI////////8t////Pg///z4f//8+L///Tj///05P//9eX///Xn///16P//9uj///bp///3 + 6///9+z///fs///47v//+O////nv///58P//+fL///ry///68///+vT///78////////////9/f3/9HR + 0P///Pn///36///+/v////////////f39//R0dH///79///+/f///v7///7+///+/v+7iHb/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA36yI////////8t////Lg///z4f//8+L///Tj///05P//9OX///Xm///1 + 5///9uj///bp///26v//9+v///fs///47f//+O7///jv///58P//+fH///ny///68///+vP///v2///+ + /P//////+fj3//r38////Pj///z5///9+////v7///////n5+P/6+Pf///78///+/P///v3///79///+ + /f+9inj/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4K2J////////8t7///Lg///z4f//8+H///Pi///0 + 5P//9OX///Xl///15///9ej///bp///26f//9+v///fs///37P//+O7///ju///57///+fD///nx///6 + 8v//+vP///r0///79f//+/X///v2///79////Pf///z4///8+f///Pn///36///9+v///fv///37///9 + /P///fz///38///9/P++i3j/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4a6K////////8t7///Lf///y + 4P//8+H//PHi/9fV0P+pqKj/m5iU/+rh1P//9ef///bo//z06P/X1dL/qamo/5uZlv/q5Nr///ju///4 + 7///+e////nw///58f//+vL///rz///69P//+/X///v1///79v//+/f///z3//z59v/X19b/qamp/5ua + mf/q6Ob///36///9+v///fr///36///9+v/Bjnn/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4q+K//// + ////8t7///Lf///y4P//8+H///z4//v7+//p6en/v7+//5eUkP//9ef///Xo///9+f/7+/v/6enp/7+/ + v/+XlZL///jt///47v//+O////nw///58P//+fH///ry///68///+vT///v1///79f//+/b///v2///+ + /f/7+/v/6enp/7+/v/+XlpX///z5///8+f///Pn///z5///8+f/Cj3r/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA5LGL////////8d3///Le///y3///8+D////+////////////6Ojo/6Wko///9eb///Xn//// + /v///////////+jo6P+lpKT///fs///47f//+O7///jv///58P//+fD///nx///68v//+vP///rz///6 + 9P//+/X///v1/////////////////+jo6P+lpKT///z4///8+P///Pj///z4///8+P/EkXv/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA5bKL////////8d3///Le///y3///8uD///z3////////////9/f3/9HO + yv//9eX///Xn///8+f////////////f39//Rz8z///fs///47f//+O7///ju///47///+fD///nw///5 + 8f//+vL///rz///68///+vT///v1///+/P////////////f39//R0M////v3///89////Pf///z3///8 + 9//Gk3z/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA5rOM////////8dz///Hd///y3v//8t////Tk///8 + 9/////7/+fby//rw4v//9OX///Xm///26v///Pn////+//n38//68uf///fr///37P//+O3///ju///4 + 7v//+O////nw///58P//+fH///ny///68v//+vP///rz///79f///vz///////n49v/69/L///v2///7 + 9v//+/b///v2///79v/IlX3/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA57SM////////8dz///Hd///y + 3v//8t////Lg///z4f//8+H///Pi///04///9OT///Tl///15v//9ef///Xo///26f//9un///bq///3 + 6///9+z///jt///47v//+O7///jv///57///+fD///nx///58v//+vL///ry///68///+vP///r0///6 + 9P//+/X///v1///79f//+/X///v1///79f/Jln3/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA6LWN//// + ////8dv///Hc///x3f//8t7///Lf///y4P//8+H///Pi///04///9OT///Tk///15f//9eb///Xn///2 + 6P//9un///bp///26v//9+v///fs///47f//+O3///ju///47///+e////nw///58P//+fH///ny///6 + 8v//+vL///rz///68///+vP///rz///69P//+vT///r0///69P/MmX//AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA6baO////////8Nv///Hb///x3f//8d3//PDf/9fU0P+pqKf/m5iT/+rf0P//9OP///Tk///0 + 5f//9eX///Xn///15///9uj///bp///26f//9ur///fr///37P//9+z///jt///47v//+O7///jv///5 + 7///+fD///nw///58f//+fH///ny///68v//+vL///ry///68///+vP///rz///68//MmX//AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA6reO////////8Nr///Hb///x3P//8d3///z3//v7+//p6en/v7+//5eU + j///8+L///Tj///05P//9OX///Xm///15///9ef///bo///26f//9un///bq///36///9+z///fs///4 + 7f//+O7///ju///47///+O////nv///58P//+fD///nw///58f//+fH///nx///58v//+fL///ny///5 + 8v/MmX//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA67iP////////8Nr///Da///x2///8dz////+//// + ////////6Ojo/6Wko///8+L///Pi///04///9OT///Tl///15v//9ef///Xn///26P//9un///bp///2 + 6v//9+v///fr///37P//9+z///jt///47v//+O7///ju///47///+e////nv///58P//+fD///nw///5 + 8P//+fD///nw///58P/Nmn//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA7bqP////////8Nn///Da///w + 2///8dv///v2////////////9/f3/9HOyf//8+H///Pi///z4v//9OP///Tk///05f//9eb///Xn///1 + 5///9ej///bo///26f//9ur///bq///36///9+z///fs///37P//+O3///ju///47v//+O7///jv///4 + 7///+O////nv///57///+e////nv///57//Nmn//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA7ruQ//// + ////79f///DZ///w2v//8dv///Pg///79v////7/+fbw//rv3v//8+D///Ph///z4v//8+L///Tj///0 + 5P//9OX///Xl///15v//9ef///Xo///26P//9un///bp///26v//9+v///fr///37P//9+z///fs///4 + 7f//+O3///ju///47v//+O7///ju///47v//+O7///ju///47v/Om4D/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA77yQ////////79b///DZ///w2f//8Nr///Hb///x3P//8d3///Le///y3v//8uD///Pg///z + 4f//8+L///Pi///04///9OT///Tl///15f//9eb///Xn///15///9uj///bo///26f//9un///bq///3 + 6///9+v///fr///37P//9+z///fs///47f//+O3///jt///47f//+O3///jt///47f/Om4D/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA8L2R////////7tT//+/W///w2f//8Nr//O/b/9fUzv+pqKf/m5eS/+rf + zf//8t////Lg//zx4P/X1ND/qain/5uYk//q4NH///Tk///05P//9OX///Xm///15///9ef///Xo///2 + 6P//9un///bp///26f//9ur///bq//z16v/X1dL/qamo/5uZlv/q49n///fs///37P//9+z///fs///3 + 7P/Om4D/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8b6S////////7dL//+7U///v1///8Nn///v2//v7 + +//p6en/v7+//5eTjv//8t7///Lf///89//7+/v/6enp/7+/v/+XlI////Tj///05P//9OT///Tl///1 + 5f//9eb///Xn///15///9ej///bo///26P//9un///bp///9+f/7+/v/6enp/7+/v/+XlZL///fr///3 + 6///9+v///fr///36//PnID/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8r+S////////7ND//+7T///u + 1f//79f////+////////////6Ojo/6Wko///8d3///Le/////v///////////+jo6P+lpKP///Pi///0 + 4///9OP///Tk///05f//9OX///Xl///15v//9ef///Xn///16P//9uj///bo/////v///////////+jo + 6P+lpKP///bq///26v//9ur///bq///26v/PnID/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA88CT//// + ////7M7//+3R///u0///7tX///v1////////////9/f3/9HOyP//8dz///Hd///89/////////////f3 + 9//Rzsn///Ph///z4v//8+L///Tj///05P//9OT///Tl///05f//9eX///Xm///15///9ef///Xn///8 + +f////////////f39//Rz8v///bp///26f//9un///bp///26f/PnID/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA9MGT////////68z//+zP///t0f//7tP///Da///79f////7/+fXv//rt2v//8dv///Hc///z + 4f///Pf////+//n28f/679////Pg///z4f//8+H///Pi///z4v//9OP///Tk///05P//9OX///Tl///1 + 5f//9eb///Xm///26v///Pn////+//n28//68eX///Xo///16P//9ej///Xo///16P/QnYH/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA9sOU////////6sv//+vN///sz///7dH//+7T///u1f//8Nn///DZ///w + 2v//8Nv///Hb///x3P//8d3///Hd///y3v//8t////Lg///y4P//8+H///Ph///z4v//8+L///Pi///0 + 4///9OT///Tk///05P//9OX///Tl///15f//9eb///Xm///15v//9eb///Xn///15///9ef///Xn///1 + 5//QnYH/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA98SU////////6sn//+rL///rzf//7M///+3R///u + 0///7tX//+/X///w2f//8Nr///Da//zw3P/X1M//qain/5uXkv/q383///Le///y3///8uD///Pg///z + 4f//8+H//PHi/9fU0P+pqKf/m5iT/+rg0f//9OT///Tk///05P//9OX///Tl///05f//9OX///Xl///1 + 5f//9eX///Xl///15f/QnYH/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+MWV////////6cf//+rJ///q + y///683//+zP///t0f//7tP//+7V///v1///8Nn///Da///79v/7+/v/6enp/7+/v/+Xk47///Hd///y + 3v//8t////Lf///y4P//8+D///z3//v7+//p6en/v7+//5eUj///8+L///Tj///04///9OT///Tk///0 + 5P//9OT///Tk///05P//9OT///Tk///05P/QnYH/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+caW//// + ////6MP//+nH///qyf//6sv//+vN///sz///7dH//+7T///u1f//79f///DZ/////v///////////+jo + 6P+lpKP///Hd///x3f//8t7///Le///y3///8t/////+////////////6Ojo/6Wko///8+L///Pi///z + 4v//8+L///Pi///04///9OP///Tj///04///9OP///Tj///04//QnYH/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA+seW////////58H//+jE///px///6sn//+rL///rzf//7M///+3R///u0///7tT//+/W///7 + 9f////////////f39//Rzsj///Hb///x3P//8d3///Hd///y3v//8t7///z3////////////9/f3/9HO + yf//8+H///Ph///z4f//8+H///Pi///z4v//8+L///Pi///z4v//8+L///Pi///z4v/QnYH/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA+8iX//7y4v//8Nn//+fB///ow///6cf//+rJ///qy///68z//+zO///s + 0P//7dL//+7U///x2///+/X////+//n17//67dn///Db///x2///8dz///Hc///x3f//8d3///Pi///8 + 9/////7/+fbx//rv3v//8uD///Lg///y4P//8+D///Ph///z4f//8+H///Ph///z4f//8+H///Ph/+7U + v//QnYH/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/MmXo/zJl//+9OX///DZ///nwf//6MP//+jF///p + yP//6sr//+vM///szv//7ND//+3R///u0///7tX//+/X///w2f//8Nn///Da///w2v//8Nv///Hb///x + 3P//8dz///Hd///x3f//8d3///Le///y3v//8t7///Lf///y3///8t////Lg///y4P//8uD///Lg///y + 4P//9+z/9uHN/9Kfgv/PnICjAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP3KmMz8yZf//vLi//// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////15df/0Z6B/9KfgswAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAD8yZej+8iX//rHlv/5xpb/+MWV//fElP/2w5T/9MGT//PAk//yv5L/8b6S//C9kf/vvJD/7ruQ/+26 + j//ruI//6reO/+m2jv/otY3/57SM/+azjP/lsov/5LGL/+Kviv/hror/4K2J/9+siP/eq4j/3aqH/9yp + h//bqIb/2aaG/9ilhf/XpIT/1qOE/9Wig//UoYP/06CCowAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////AAD///////8AAP///////wAA+AAAAAAf + AADwAAAAAA8AAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAA + AAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAH + AADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAA + AAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAH + AADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAA + AAAABwAA4AAAAAAHAADwAAAAAA8AAPgAAAAAHwAA////////AAD///////8AAP///////wAA + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/app.config b/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/app.config new file mode 100644 index 0000000..c5e1dae --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/app.config @@ -0,0 +1,3 @@ + + + diff --git a/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/app.manifest b/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/app.manifest new file mode 100644 index 0000000..d49604f --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/app.manifest @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/encrypt.ico b/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/encrypt.ico new file mode 100644 index 0000000..fe1e884 Binary files /dev/null and b/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/encrypt.ico differ diff --git a/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/protector.ico b/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/protector.ico new file mode 100644 index 0000000..86009bf Binary files /dev/null and b/Demo_Source_Code/CSharpDemo/AutoFileCryptTool/protector.ico differ diff --git a/Demo_Source_Code/CSharpDemo/CommonObjects/AccessRightsForm.Designer.cs b/Demo_Source_Code/CSharpDemo/CommonObjects/AccessRightsForm.Designer.cs new file mode 100644 index 0000000..85a0ebf --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/CommonObjects/AccessRightsForm.Designer.cs @@ -0,0 +1,621 @@ +namespace EaseFilter.CommonObjects +{ + partial class Form_AccessRights + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.button_Add = new System.Windows.Forms.Button(); + this.groupBox_ProcessName = new System.Windows.Forms.GroupBox(); + this.button_InfoProcessName = new System.Windows.Forms.Button(); + this.textBox_ProcessName = new System.Windows.Forms.TextBox(); + this.label_AccessFlags = new System.Windows.Forms.Label(); + this.groupBox_AccessRights = new System.Windows.Forms.GroupBox(); + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.button_InfoEncryptOnRead = new System.Windows.Forms.Button(); + this.button_InfoDecryptFile = new System.Windows.Forms.Button(); + this.button_InfoEncryptNewFile = new System.Windows.Forms.Button(); + this.button_InfoCopyout = new System.Windows.Forms.Button(); + this.checkBox_AllowReadEncryptedFiles = new System.Windows.Forms.CheckBox(); + this.checkBox_AllowCopyout = new System.Windows.Forms.CheckBox(); + this.checkBox_AllowEncryptNewFile = new System.Windows.Forms.CheckBox(); + this.checkBox_SetSecurity = new System.Windows.Forms.CheckBox(); + this.checkBox_QueryInfo = new System.Windows.Forms.CheckBox(); + this.checkBox_Read = new System.Windows.Forms.CheckBox(); + this.checkBox_EnableEncryptionOnRead = new System.Windows.Forms.CheckBox(); + this.checkBox_SetInfo = new System.Windows.Forms.CheckBox(); + this.checkBox_Write = new System.Windows.Forms.CheckBox(); + this.checkBox_AllowDelete = new System.Windows.Forms.CheckBox(); + this.checkBox_AllowRename = new System.Windows.Forms.CheckBox(); + this.checkBox_Creation = new System.Windows.Forms.CheckBox(); + this.label2 = new System.Windows.Forms.Label(); + this.textBox_FileAccessFlags = new System.Windows.Forms.TextBox(); + this.button_FileAccessFlags = new System.Windows.Forms.Button(); + this.groupBox_UserName = new System.Windows.Forms.GroupBox(); + this.button_InfoUserName = new System.Windows.Forms.Button(); + this.textBox_UserName = new System.Windows.Forms.TextBox(); + this.label1 = new System.Windows.Forms.Label(); + this.groupBox_ProcessId = new System.Windows.Forms.GroupBox(); + this.button_ProcessId = new System.Windows.Forms.Button(); + this.textBox_ProcessId = new System.Windows.Forms.TextBox(); + this.label3 = new System.Windows.Forms.Label(); + this.groupBox_ProcessSha256 = new System.Windows.Forms.GroupBox(); + this.button_GetProcessSha256 = new System.Windows.Forms.Button(); + this.textBox_ProcessSha256Hash = new System.Windows.Forms.TextBox(); + this.label4 = new System.Windows.Forms.Label(); + this.groupBox_SignedProcess = new System.Windows.Forms.GroupBox(); + this.button_GetCertificateName = new System.Windows.Forms.Button(); + this.textBox_ProcessCertificateName = new System.Windows.Forms.TextBox(); + this.label5 = new System.Windows.Forms.Label(); + this.groupBox_ProcessName.SuspendLayout(); + this.groupBox_AccessRights.SuspendLayout(); + this.groupBox_UserName.SuspendLayout(); + this.groupBox_ProcessId.SuspendLayout(); + this.groupBox_ProcessSha256.SuspendLayout(); + this.groupBox_SignedProcess.SuspendLayout(); + this.SuspendLayout(); + // + // button_Add + // + this.button_Add.DialogResult = System.Windows.Forms.DialogResult.OK; + this.button_Add.Location = new System.Drawing.Point(450, 186); + this.button_Add.Name = "button_Add"; + this.button_Add.Size = new System.Drawing.Size(75, 23); + this.button_Add.TabIndex = 25; + this.button_Add.Text = "Add"; + this.button_Add.UseVisualStyleBackColor = true; + this.button_Add.Click += new System.EventHandler(this.button_Add_Click); + // + // groupBox_ProcessName + // + this.groupBox_ProcessName.Controls.Add(this.button_InfoProcessName); + this.groupBox_ProcessName.Controls.Add(this.textBox_ProcessName); + this.groupBox_ProcessName.Controls.Add(this.label_AccessFlags); + this.groupBox_ProcessName.Location = new System.Drawing.Point(25, 19); + this.groupBox_ProcessName.Name = "groupBox_ProcessName"; + this.groupBox_ProcessName.Size = new System.Drawing.Size(535, 48); + this.groupBox_ProcessName.TabIndex = 26; + this.groupBox_ProcessName.TabStop = false; + this.groupBox_ProcessName.Visible = false; + // + // button_InfoProcessName + // + this.button_InfoProcessName.Image = global::EaseFilter.CommonObjects.Properties.Resources.about; + this.button_InfoProcessName.Location = new System.Drawing.Point(461, 16); + this.button_InfoProcessName.Name = "button_InfoProcessName"; + this.button_InfoProcessName.Size = new System.Drawing.Size(41, 20); + this.button_InfoProcessName.TabIndex = 114; + this.button_InfoProcessName.UseVisualStyleBackColor = true; + this.button_InfoProcessName.Click += new System.EventHandler(this.button_InfoProcessName_Click); + // + // textBox_ProcessName + // + this.textBox_ProcessName.Location = new System.Drawing.Point(149, 16); + this.textBox_ProcessName.Name = "textBox_ProcessName"; + this.textBox_ProcessName.Size = new System.Drawing.Size(298, 20); + this.textBox_ProcessName.TabIndex = 27; + this.textBox_ProcessName.Text = "notepad.exe; cmd.exe;"; + // + // label_AccessFlags + // + this.label_AccessFlags.AutoSize = true; + this.label_AccessFlags.Location = new System.Drawing.Point(9, 19); + this.label_AccessFlags.Name = "label_AccessFlags"; + this.label_AccessFlags.Size = new System.Drawing.Size(77, 13); + this.label_AccessFlags.TabIndex = 28; + this.label_AccessFlags.Text = "Process name "; + // + // groupBox_AccessRights + // + this.groupBox_AccessRights.Controls.Add(this.groupBox1); + this.groupBox_AccessRights.Controls.Add(this.button_InfoEncryptOnRead); + this.groupBox_AccessRights.Controls.Add(this.button_InfoDecryptFile); + this.groupBox_AccessRights.Controls.Add(this.button_InfoEncryptNewFile); + this.groupBox_AccessRights.Controls.Add(this.button_InfoCopyout); + this.groupBox_AccessRights.Controls.Add(this.button_Add); + this.groupBox_AccessRights.Controls.Add(this.checkBox_AllowReadEncryptedFiles); + this.groupBox_AccessRights.Controls.Add(this.checkBox_AllowCopyout); + this.groupBox_AccessRights.Controls.Add(this.checkBox_AllowEncryptNewFile); + this.groupBox_AccessRights.Controls.Add(this.checkBox_SetSecurity); + this.groupBox_AccessRights.Controls.Add(this.checkBox_QueryInfo); + this.groupBox_AccessRights.Controls.Add(this.checkBox_Read); + this.groupBox_AccessRights.Controls.Add(this.checkBox_EnableEncryptionOnRead); + this.groupBox_AccessRights.Controls.Add(this.checkBox_SetInfo); + this.groupBox_AccessRights.Controls.Add(this.checkBox_Write); + this.groupBox_AccessRights.Controls.Add(this.checkBox_AllowDelete); + this.groupBox_AccessRights.Controls.Add(this.checkBox_AllowRename); + this.groupBox_AccessRights.Controls.Add(this.checkBox_Creation); + this.groupBox_AccessRights.Controls.Add(this.label2); + this.groupBox_AccessRights.Controls.Add(this.textBox_FileAccessFlags); + this.groupBox_AccessRights.Controls.Add(this.button_FileAccessFlags); + this.groupBox_AccessRights.Location = new System.Drawing.Point(25, 231); + this.groupBox_AccessRights.Name = "groupBox_AccessRights"; + this.groupBox_AccessRights.Size = new System.Drawing.Size(535, 214); + this.groupBox_AccessRights.TabIndex = 76; + this.groupBox_AccessRights.TabStop = false; + this.groupBox_AccessRights.Text = "File Acess Rights"; + // + // groupBox1 + // + this.groupBox1.Location = new System.Drawing.Point(9, 170); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size(516, 10); + this.groupBox1.TabIndex = 124; + this.groupBox1.TabStop = false; + // + // button_InfoEncryptOnRead + // + this.button_InfoEncryptOnRead.Image = global::EaseFilter.CommonObjects.Properties.Resources.about; + this.button_InfoEncryptOnRead.Location = new System.Drawing.Point(501, 147); + this.button_InfoEncryptOnRead.Name = "button_InfoEncryptOnRead"; + this.button_InfoEncryptOnRead.Size = new System.Drawing.Size(28, 20); + this.button_InfoEncryptOnRead.TabIndex = 120; + this.button_InfoEncryptOnRead.UseVisualStyleBackColor = true; + this.button_InfoEncryptOnRead.Click += new System.EventHandler(this.button_InfoEncryptOnRead_Click); + // + // button_InfoDecryptFile + // + this.button_InfoDecryptFile.Image = global::EaseFilter.CommonObjects.Properties.Resources.about; + this.button_InfoDecryptFile.Location = new System.Drawing.Point(501, 124); + this.button_InfoDecryptFile.Name = "button_InfoDecryptFile"; + this.button_InfoDecryptFile.Size = new System.Drawing.Size(28, 20); + this.button_InfoDecryptFile.TabIndex = 121; + this.button_InfoDecryptFile.UseVisualStyleBackColor = true; + this.button_InfoDecryptFile.Click += new System.EventHandler(this.button_InfoDecryptFile_Click); + // + // button_InfoEncryptNewFile + // + this.button_InfoEncryptNewFile.Image = global::EaseFilter.CommonObjects.Properties.Resources.about; + this.button_InfoEncryptNewFile.Location = new System.Drawing.Point(501, 98); + this.button_InfoEncryptNewFile.Name = "button_InfoEncryptNewFile"; + this.button_InfoEncryptNewFile.Size = new System.Drawing.Size(28, 20); + this.button_InfoEncryptNewFile.TabIndex = 122; + this.button_InfoEncryptNewFile.UseVisualStyleBackColor = true; + this.button_InfoEncryptNewFile.Click += new System.EventHandler(this.button_InfoEncryptNewFile_Click); + // + // button_InfoCopyout + // + this.button_InfoCopyout.Image = global::EaseFilter.CommonObjects.Properties.Resources.about; + this.button_InfoCopyout.Location = new System.Drawing.Point(501, 75); + this.button_InfoCopyout.Name = "button_InfoCopyout"; + this.button_InfoCopyout.Size = new System.Drawing.Size(28, 20); + this.button_InfoCopyout.TabIndex = 123; + this.button_InfoCopyout.UseVisualStyleBackColor = true; + this.button_InfoCopyout.Click += new System.EventHandler(this.button_InfoCopyout_Click); + // + // checkBox_AllowReadEncryptedFiles + // + this.checkBox_AllowReadEncryptedFiles.AutoSize = true; + this.checkBox_AllowReadEncryptedFiles.Checked = true; + this.checkBox_AllowReadEncryptedFiles.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBox_AllowReadEncryptedFiles.Location = new System.Drawing.Point(320, 124); + this.checkBox_AllowReadEncryptedFiles.Name = "checkBox_AllowReadEncryptedFiles"; + this.checkBox_AllowReadEncryptedFiles.Size = new System.Drawing.Size(177, 17); + this.checkBox_AllowReadEncryptedFiles.TabIndex = 49; + this.checkBox_AllowReadEncryptedFiles.Text = "Enable encrypted file decryption"; + this.checkBox_AllowReadEncryptedFiles.UseVisualStyleBackColor = true; + this.checkBox_AllowReadEncryptedFiles.CheckedChanged += new System.EventHandler(this.checkBox_AllowReadEncryptedFiles_CheckedChanged); + // + // checkBox_AllowCopyout + // + this.checkBox_AllowCopyout.AutoSize = true; + this.checkBox_AllowCopyout.Checked = true; + this.checkBox_AllowCopyout.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBox_AllowCopyout.Location = new System.Drawing.Point(320, 78); + this.checkBox_AllowCopyout.Name = "checkBox_AllowCopyout"; + this.checkBox_AllowCopyout.Size = new System.Drawing.Size(154, 17); + this.checkBox_AllowCopyout.TabIndex = 48; + this.checkBox_AllowCopyout.Text = "Allow files being copied out"; + this.checkBox_AllowCopyout.UseVisualStyleBackColor = true; + this.checkBox_AllowCopyout.CheckedChanged += new System.EventHandler(this.checkBox_AllowCopyout_CheckedChanged); + // + // checkBox_AllowEncryptNewFile + // + this.checkBox_AllowEncryptNewFile.AutoSize = true; + this.checkBox_AllowEncryptNewFile.Checked = true; + this.checkBox_AllowEncryptNewFile.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBox_AllowEncryptNewFile.Location = new System.Drawing.Point(320, 101); + this.checkBox_AllowEncryptNewFile.Name = "checkBox_AllowEncryptNewFile"; + this.checkBox_AllowEncryptNewFile.Size = new System.Drawing.Size(150, 17); + this.checkBox_AllowEncryptNewFile.TabIndex = 47; + this.checkBox_AllowEncryptNewFile.Text = "Enable new file encryption"; + this.checkBox_AllowEncryptNewFile.UseVisualStyleBackColor = true; + this.checkBox_AllowEncryptNewFile.CheckedChanged += new System.EventHandler(this.checkBox_AllowEncryptNewFile_CheckedChanged); + // + // checkBox_SetSecurity + // + this.checkBox_SetSecurity.AutoSize = true; + this.checkBox_SetSecurity.Checked = true; + this.checkBox_SetSecurity.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBox_SetSecurity.Location = new System.Drawing.Point(149, 146); + this.checkBox_SetSecurity.Name = "checkBox_SetSecurity"; + this.checkBox_SetSecurity.Size = new System.Drawing.Size(137, 17); + this.checkBox_SetSecurity.TabIndex = 46; + this.checkBox_SetSecurity.Text = "Allow security changing"; + this.checkBox_SetSecurity.UseVisualStyleBackColor = true; + this.checkBox_SetSecurity.CheckedChanged += new System.EventHandler(this.checkBox_SetSecurity_CheckedChanged); + // + // checkBox_QueryInfo + // + this.checkBox_QueryInfo.AutoSize = true; + this.checkBox_QueryInfo.Checked = true; + this.checkBox_QueryInfo.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBox_QueryInfo.Location = new System.Drawing.Point(149, 100); + this.checkBox_QueryInfo.Name = "checkBox_QueryInfo"; + this.checkBox_QueryInfo.Size = new System.Drawing.Size(130, 17); + this.checkBox_QueryInfo.TabIndex = 42; + this.checkBox_QueryInfo.Text = "Allow file info querying"; + this.checkBox_QueryInfo.UseVisualStyleBackColor = true; + this.checkBox_QueryInfo.CheckedChanged += new System.EventHandler(this.checkBox_QueryInfo_CheckedChanged); + // + // checkBox_Read + // + this.checkBox_Read.AutoSize = true; + this.checkBox_Read.Checked = true; + this.checkBox_Read.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBox_Read.Location = new System.Drawing.Point(9, 78); + this.checkBox_Read.Name = "checkBox_Read"; + this.checkBox_Read.Size = new System.Drawing.Size(105, 17); + this.checkBox_Read.TabIndex = 44; + this.checkBox_Read.Text = "Allow file reading"; + this.checkBox_Read.UseVisualStyleBackColor = true; + this.checkBox_Read.CheckedChanged += new System.EventHandler(this.checkBox_Read_CheckedChanged); + // + // checkBox_EnableEncryptionOnRead + // + this.checkBox_EnableEncryptionOnRead.AutoSize = true; + this.checkBox_EnableEncryptionOnRead.Checked = true; + this.checkBox_EnableEncryptionOnRead.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBox_EnableEncryptionOnRead.Location = new System.Drawing.Point(320, 147); + this.checkBox_EnableEncryptionOnRead.Name = "checkBox_EnableEncryptionOnRead"; + this.checkBox_EnableEncryptionOnRead.Size = new System.Drawing.Size(159, 17); + this.checkBox_EnableEncryptionOnRead.TabIndex = 43; + this.checkBox_EnableEncryptionOnRead.Text = "Enable encryption on the go"; + this.checkBox_EnableEncryptionOnRead.UseVisualStyleBackColor = true; + this.checkBox_EnableEncryptionOnRead.CheckedChanged += new System.EventHandler(this.checkBox_EncryptionOnRead_CheckedChanged); + // + // checkBox_SetInfo + // + this.checkBox_SetInfo.AutoSize = true; + this.checkBox_SetInfo.Checked = true; + this.checkBox_SetInfo.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBox_SetInfo.Location = new System.Drawing.Point(149, 123); + this.checkBox_SetInfo.Name = "checkBox_SetInfo"; + this.checkBox_SetInfo.Size = new System.Drawing.Size(134, 17); + this.checkBox_SetInfo.TabIndex = 45; + this.checkBox_SetInfo.Text = "Allow file info changing"; + this.checkBox_SetInfo.UseVisualStyleBackColor = true; + this.checkBox_SetInfo.CheckedChanged += new System.EventHandler(this.checkBox_SetInfo_CheckedChanged); + // + // checkBox_Write + // + this.checkBox_Write.AutoSize = true; + this.checkBox_Write.Checked = true; + this.checkBox_Write.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBox_Write.Location = new System.Drawing.Point(9, 101); + this.checkBox_Write.Name = "checkBox_Write"; + this.checkBox_Write.Size = new System.Drawing.Size(100, 17); + this.checkBox_Write.TabIndex = 38; + this.checkBox_Write.Text = "Allow file writing"; + this.checkBox_Write.UseVisualStyleBackColor = true; + this.checkBox_Write.CheckedChanged += new System.EventHandler(this.checkBox_Write_CheckedChanged); + // + // checkBox_AllowDelete + // + this.checkBox_AllowDelete.AutoSize = true; + this.checkBox_AllowDelete.Checked = true; + this.checkBox_AllowDelete.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBox_AllowDelete.Location = new System.Drawing.Point(9, 123); + this.checkBox_AllowDelete.Name = "checkBox_AllowDelete"; + this.checkBox_AllowDelete.Size = new System.Drawing.Size(107, 17); + this.checkBox_AllowDelete.TabIndex = 40; + this.checkBox_AllowDelete.Text = "Allow file deletion"; + this.checkBox_AllowDelete.UseVisualStyleBackColor = true; + this.checkBox_AllowDelete.CheckedChanged += new System.EventHandler(this.checkBox_AllowDelete_CheckedChanged); + // + // checkBox_AllowRename + // + this.checkBox_AllowRename.AutoSize = true; + this.checkBox_AllowRename.Checked = true; + this.checkBox_AllowRename.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBox_AllowRename.Location = new System.Drawing.Point(149, 77); + this.checkBox_AllowRename.Name = "checkBox_AllowRename"; + this.checkBox_AllowRename.Size = new System.Drawing.Size(113, 17); + this.checkBox_AllowRename.TabIndex = 39; + this.checkBox_AllowRename.Text = "Allow file renaming"; + this.checkBox_AllowRename.UseVisualStyleBackColor = true; + this.checkBox_AllowRename.CheckedChanged += new System.EventHandler(this.checkBox_AllowRename_CheckedChanged); + // + // checkBox_Creation + // + this.checkBox_Creation.AutoSize = true; + this.checkBox_Creation.Checked = true; + this.checkBox_Creation.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBox_Creation.Location = new System.Drawing.Point(9, 146); + this.checkBox_Creation.Name = "checkBox_Creation"; + this.checkBox_Creation.Size = new System.Drawing.Size(131, 17); + this.checkBox_Creation.TabIndex = 41; + this.checkBox_Creation.Text = "Allow new file creation"; + this.checkBox_Creation.UseVisualStyleBackColor = true; + this.checkBox_Creation.CheckedChanged += new System.EventHandler(this.checkBox_Creation_CheckedChanged); + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(9, 35); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(106, 13); + this.label2.TabIndex = 32; + this.label2.Text = "Access Control Flags"; + // + // textBox_FileAccessFlags + // + this.textBox_FileAccessFlags.Location = new System.Drawing.Point(149, 35); + this.textBox_FileAccessFlags.Name = "textBox_FileAccessFlags"; + this.textBox_FileAccessFlags.Size = new System.Drawing.Size(298, 20); + this.textBox_FileAccessFlags.TabIndex = 31; + this.textBox_FileAccessFlags.Text = "0"; + // + // button_FileAccessFlags + // + this.button_FileAccessFlags.Location = new System.Drawing.Point(461, 35); + this.button_FileAccessFlags.Name = "button_FileAccessFlags"; + this.button_FileAccessFlags.Size = new System.Drawing.Size(50, 20); + this.button_FileAccessFlags.TabIndex = 33; + this.button_FileAccessFlags.Text = "..."; + this.button_FileAccessFlags.UseVisualStyleBackColor = true; + this.button_FileAccessFlags.Click += new System.EventHandler(this.button_FileAccessFlags_Click); + // + // groupBox_UserName + // + this.groupBox_UserName.Controls.Add(this.button_InfoUserName); + this.groupBox_UserName.Controls.Add(this.textBox_UserName); + this.groupBox_UserName.Controls.Add(this.label1); + this.groupBox_UserName.Location = new System.Drawing.Point(25, 171); + this.groupBox_UserName.Name = "groupBox_UserName"; + this.groupBox_UserName.Size = new System.Drawing.Size(535, 46); + this.groupBox_UserName.TabIndex = 30; + this.groupBox_UserName.TabStop = false; + this.groupBox_UserName.Visible = false; + // + // button_InfoUserName + // + this.button_InfoUserName.Image = global::EaseFilter.CommonObjects.Properties.Resources.about; + this.button_InfoUserName.Location = new System.Drawing.Point(461, 16); + this.button_InfoUserName.Name = "button_InfoUserName"; + this.button_InfoUserName.Size = new System.Drawing.Size(41, 20); + this.button_InfoUserName.TabIndex = 115; + this.button_InfoUserName.UseVisualStyleBackColor = true; + this.button_InfoUserName.Click += new System.EventHandler(this.button_InfoUserName_Click); + // + // textBox_UserName + // + this.textBox_UserName.Location = new System.Drawing.Point(149, 16); + this.textBox_UserName.Name = "textBox_UserName"; + this.textBox_UserName.Size = new System.Drawing.Size(298, 20); + this.textBox_UserName.TabIndex = 27; + this.textBox_UserName.Text = "domain1\\user1; domain2\\user2;"; + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(9, 18); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(61, 13); + this.label1.TabIndex = 28; + this.label1.Text = "User name "; + // + // groupBox_ProcessId + // + this.groupBox_ProcessId.Controls.Add(this.button_ProcessId); + this.groupBox_ProcessId.Controls.Add(this.textBox_ProcessId); + this.groupBox_ProcessId.Controls.Add(this.label3); + this.groupBox_ProcessId.Location = new System.Drawing.Point(25, 136); + this.groupBox_ProcessId.Name = "groupBox_ProcessId"; + this.groupBox_ProcessId.Size = new System.Drawing.Size(535, 48); + this.groupBox_ProcessId.TabIndex = 29; + this.groupBox_ProcessId.TabStop = false; + this.groupBox_ProcessId.Visible = false; + // + // button_ProcessId + // + this.button_ProcessId.Location = new System.Drawing.Point(461, 15); + this.button_ProcessId.Name = "button_ProcessId"; + this.button_ProcessId.Size = new System.Drawing.Size(50, 20); + this.button_ProcessId.TabIndex = 38; + this.button_ProcessId.Text = "..."; + this.button_ProcessId.UseVisualStyleBackColor = true; + this.button_ProcessId.Click += new System.EventHandler(this.button_ProcessId_Click); + // + // textBox_ProcessId + // + this.textBox_ProcessId.Location = new System.Drawing.Point(149, 16); + this.textBox_ProcessId.Name = "textBox_ProcessId"; + this.textBox_ProcessId.Size = new System.Drawing.Size(298, 20); + this.textBox_ProcessId.TabIndex = 27; + // + // label3 + // + this.label3.AutoSize = true; + this.label3.Location = new System.Drawing.Point(9, 19); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(57, 13); + this.label3.TabIndex = 28; + this.label3.Text = "Process Id"; + // + // groupBox_ProcessSha256 + // + this.groupBox_ProcessSha256.Controls.Add(this.button_GetProcessSha256); + this.groupBox_ProcessSha256.Controls.Add(this.textBox_ProcessSha256Hash); + this.groupBox_ProcessSha256.Controls.Add(this.label4); + this.groupBox_ProcessSha256.Location = new System.Drawing.Point(25, 55); + this.groupBox_ProcessSha256.Name = "groupBox_ProcessSha256"; + this.groupBox_ProcessSha256.Size = new System.Drawing.Size(535, 48); + this.groupBox_ProcessSha256.TabIndex = 39; + this.groupBox_ProcessSha256.TabStop = false; + this.groupBox_ProcessSha256.Visible = false; + // + // button_GetProcessSha256 + // + this.button_GetProcessSha256.Location = new System.Drawing.Point(461, 15); + this.button_GetProcessSha256.Name = "button_GetProcessSha256"; + this.button_GetProcessSha256.Size = new System.Drawing.Size(50, 20); + this.button_GetProcessSha256.TabIndex = 38; + this.button_GetProcessSha256.Text = "..."; + this.button_GetProcessSha256.UseVisualStyleBackColor = true; + this.button_GetProcessSha256.Click += new System.EventHandler(this.button_GetProcessSha256_Click); + // + // textBox_ProcessSha256 + // + this.textBox_ProcessSha256Hash.Location = new System.Drawing.Point(149, 16); + this.textBox_ProcessSha256Hash.Name = "textBox_ProcessSha256"; + this.textBox_ProcessSha256Hash.Size = new System.Drawing.Size(298, 20); + this.textBox_ProcessSha256Hash.TabIndex = 27; + // + // label4 + // + this.label4.AutoSize = true; + this.label4.Location = new System.Drawing.Point(9, 19); + this.label4.Name = "label4"; + this.label4.Size = new System.Drawing.Size(135, 13); + this.label4.TabIndex = 28; + this.label4.Text = "Executable binrary sha256 "; + // + // groupBox_SignedProcess + // + this.groupBox_SignedProcess.Controls.Add(this.button_GetCertificateName); + this.groupBox_SignedProcess.Controls.Add(this.textBox_ProcessCertificateName); + this.groupBox_SignedProcess.Controls.Add(this.label5); + this.groupBox_SignedProcess.Location = new System.Drawing.Point(25, 97); + this.groupBox_SignedProcess.Name = "groupBox_SignedProcess"; + this.groupBox_SignedProcess.Size = new System.Drawing.Size(535, 48); + this.groupBox_SignedProcess.TabIndex = 125; + this.groupBox_SignedProcess.TabStop = false; + this.groupBox_SignedProcess.Visible = false; + // + // button_GetCertificateName + // + this.button_GetCertificateName.Location = new System.Drawing.Point(461, 12); + this.button_GetCertificateName.Name = "button_GetCertificateName"; + this.button_GetCertificateName.Size = new System.Drawing.Size(50, 20); + this.button_GetCertificateName.TabIndex = 40; + this.button_GetCertificateName.Text = "..."; + this.button_GetCertificateName.UseVisualStyleBackColor = true; + this.button_GetCertificateName.Click += new System.EventHandler(this.button_GetCertificateName_Click); + // + // textBox_ProcessCertificateName + // + this.textBox_ProcessCertificateName.Location = new System.Drawing.Point(149, 12); + this.textBox_ProcessCertificateName.Name = "textBox_ProcessCertificateName"; + this.textBox_ProcessCertificateName.Size = new System.Drawing.Size(298, 20); + this.textBox_ProcessCertificateName.TabIndex = 39; + // + // label5 + // + this.label5.AutoSize = true; + this.label5.Location = new System.Drawing.Point(9, 16); + this.label5.Name = "label5"; + this.label5.Size = new System.Drawing.Size(130, 13); + this.label5.TabIndex = 29; + this.label5.Text = "Certificate\'s subject name "; + // + // Form_AccessRights + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(590, 461); + this.Controls.Add(this.groupBox_SignedProcess); + this.Controls.Add(this.groupBox_ProcessSha256); + this.Controls.Add(this.groupBox_ProcessId); + this.Controls.Add(this.groupBox_UserName); + this.Controls.Add(this.groupBox_AccessRights); + this.Controls.Add(this.groupBox_ProcessName); + this.Margin = new System.Windows.Forms.Padding(2); + this.Name = "Form_AccessRights"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "Add Access Rights"; + this.groupBox_ProcessName.ResumeLayout(false); + this.groupBox_ProcessName.PerformLayout(); + this.groupBox_AccessRights.ResumeLayout(false); + this.groupBox_AccessRights.PerformLayout(); + this.groupBox_UserName.ResumeLayout(false); + this.groupBox_UserName.PerformLayout(); + this.groupBox_ProcessId.ResumeLayout(false); + this.groupBox_ProcessId.PerformLayout(); + this.groupBox_ProcessSha256.ResumeLayout(false); + this.groupBox_ProcessSha256.PerformLayout(); + this.groupBox_SignedProcess.ResumeLayout(false); + this.groupBox_SignedProcess.PerformLayout(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.Button button_Add; + private System.Windows.Forms.GroupBox groupBox_ProcessName; + private System.Windows.Forms.TextBox textBox_ProcessName; + private System.Windows.Forms.Label label_AccessFlags; + private System.Windows.Forms.GroupBox groupBox_AccessRights; + private System.Windows.Forms.GroupBox groupBox_UserName; + private System.Windows.Forms.TextBox textBox_UserName; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.TextBox textBox_FileAccessFlags; + private System.Windows.Forms.Button button_FileAccessFlags; + private System.Windows.Forms.GroupBox groupBox_ProcessId; + private System.Windows.Forms.Button button_ProcessId; + private System.Windows.Forms.TextBox textBox_ProcessId; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.CheckBox checkBox_AllowReadEncryptedFiles; + private System.Windows.Forms.CheckBox checkBox_AllowCopyout; + private System.Windows.Forms.CheckBox checkBox_AllowEncryptNewFile; + private System.Windows.Forms.CheckBox checkBox_SetSecurity; + private System.Windows.Forms.CheckBox checkBox_QueryInfo; + private System.Windows.Forms.CheckBox checkBox_Read; + private System.Windows.Forms.CheckBox checkBox_EnableEncryptionOnRead; + private System.Windows.Forms.CheckBox checkBox_SetInfo; + private System.Windows.Forms.CheckBox checkBox_Write; + private System.Windows.Forms.CheckBox checkBox_AllowDelete; + private System.Windows.Forms.CheckBox checkBox_AllowRename; + private System.Windows.Forms.CheckBox checkBox_Creation; + private System.Windows.Forms.Button button_InfoEncryptOnRead; + private System.Windows.Forms.Button button_InfoDecryptFile; + private System.Windows.Forms.Button button_InfoEncryptNewFile; + private System.Windows.Forms.Button button_InfoCopyout; + private System.Windows.Forms.Button button_InfoProcessName; + private System.Windows.Forms.Button button_InfoUserName; + private System.Windows.Forms.GroupBox groupBox_ProcessSha256; + private System.Windows.Forms.Button button_GetProcessSha256; + private System.Windows.Forms.TextBox textBox_ProcessSha256Hash; + private System.Windows.Forms.Label label4; + private System.Windows.Forms.GroupBox groupBox1; + private System.Windows.Forms.GroupBox groupBox_SignedProcess; + private System.Windows.Forms.Button button_GetCertificateName; + private System.Windows.Forms.TextBox textBox_ProcessCertificateName; + private System.Windows.Forms.Label label5; + } +} \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/CommonObjects/AccessRightsForm.cs b/Demo_Source_Code/CSharpDemo/CommonObjects/AccessRightsForm.cs new file mode 100644 index 0000000..0ab7fe1 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/CommonObjects/AccessRightsForm.cs @@ -0,0 +1,619 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +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; + +using EaseFilter.FilterControl; + +namespace EaseFilter.CommonObjects +{ + + public partial class Form_AccessRights : Form + { + public enum AccessRightType + { + ProcessNameRight = 0, + Sha256Process, + SignedProcess, + ProccessIdRight, + UserNameRight, + } + + AccessRightType type = AccessRightType.ProccessIdRight; + + public string accessRightText = string.Empty; + + public Form_AccessRights(AccessRightType _type) + { + InitializeComponent(); + + type = _type; + groupBox_AccessRights.Location = groupBox_ProcessSha256.Location; + groupBox_ProcessId.Location = groupBox_ProcessName.Location; + groupBox_ProcessSha256.Location = groupBox_ProcessName.Location; + groupBox_SignedProcess.Location = groupBox_ProcessName.Location; + groupBox_UserName.Location = groupBox_ProcessName.Location; + + textBox_FileAccessFlags.Text = FilterAPI.ALLOW_MAX_RIGHT_ACCESS.ToString(); + SetCheckBoxValue(); + + switch (type) + { + case AccessRightType.ProcessNameRight: groupBox_ProcessName.Visible = true; break; + case AccessRightType.Sha256Process: groupBox_ProcessSha256.Visible = true; break; + case AccessRightType.SignedProcess: groupBox_SignedProcess.Visible = true; break; + case AccessRightType.ProccessIdRight: groupBox_ProcessId.Visible = true; break; + case AccessRightType.UserNameRight: groupBox_UserName.Visible = true; break; + } + + } + + private void button_Add_Click(object sender, EventArgs e) + { + + switch (type) + { + case AccessRightType.ProcessNameRight: + { + if (textBox_ProcessName.Text.Trim().Length > 0) + { + string[] processNames = textBox_ProcessName.Text.Trim().Split(new char[] { ';' }); + if (processNames.Length > 0) + { + foreach (string processName in processNames) + { + if (processName.Trim().Length > 0) + { + if (accessRightText.Length > 0) + { + accessRightText += ";"; + } + + accessRightText += processName.Trim() + "!" + textBox_FileAccessFlags.Text; + } + } + } + } + break; + } + + case AccessRightType.Sha256Process: + { + if (textBox_ProcessSha256Hash.Text.Trim().Length > 0) + { + string[] processShaList = textBox_ProcessSha256Hash.Text.Trim().Split(new char[] { ';' }); + if (processShaList.Length > 0) + { + foreach (string processSha in processShaList) + { + if (processSha.Trim().Length > 0) + { + if (accessRightText.Length > 0) + { + accessRightText += ";"; + } + + accessRightText += processSha.Trim() + "!" + textBox_FileAccessFlags.Text; + } + } + } + } + break; + } + + case AccessRightType.SignedProcess: + { + if (textBox_ProcessCertificateName.Text.Trim().Length > 0) + { + string[] certificateNameList = textBox_ProcessCertificateName.Text.Trim().Split(new char[] { ';' }); + if (certificateNameList.Length > 0) + { + foreach (string certificateName in certificateNameList) + { + if (certificateName.Trim().Length > 0) + { + if (accessRightText.Length > 0) + { + accessRightText += ";"; + } + + accessRightText += certificateName.Trim() + "!" + textBox_FileAccessFlags.Text; + } + } + } + } + break; + } + + case AccessRightType.UserNameRight: + { + if (textBox_UserName.Text.Trim().Length > 0) + { + string[] userNames = textBox_UserName.Text.Trim().Split(new char[] { ';' }); + if (userNames.Length > 0) + { + foreach (string userName in userNames) + { + if (userName.Trim().Length > 0) + { + if (accessRightText.Length > 0) + { + accessRightText += ";"; + } + + accessRightText += userName.Trim() + "!" + textBox_FileAccessFlags.Text; + } + } + } + } + + break; + } + + case AccessRightType.ProccessIdRight: + { + if (textBox_ProcessId.Text.Trim().Length > 0) + { + string[] processIds = textBox_ProcessId.Text.Trim().Split(new char[] { ';' }); + if (processIds.Length > 0) + { + foreach (string processId in processIds) + { + if (processId.Trim().Length > 0) + { + if (accessRightText.Length > 0) + { + accessRightText += ";"; + } + + accessRightText += processId.Trim() + "!" + textBox_FileAccessFlags.Text; + } + } + } + } + + break; + } + } + + } + + + private void SetCheckBoxValue() + { + + uint accessFlags = uint.Parse(textBox_FileAccessFlags.Text); + + if ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_FILE_DELETE) > 0) + { + checkBox_AllowDelete.Checked = true; + } + else + { + checkBox_AllowDelete.Checked = false; + } + + if ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_FILE_RENAME) > 0) + { + checkBox_AllowRename.Checked = true; + } + else + { + checkBox_AllowRename.Checked = false; + } + + if ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_WRITE_ACCESS) > 0 ) + { + checkBox_Write.Checked = true; + } + else + { + checkBox_Write.Checked = false; + } + + if ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_READ_ACCESS) > 0) + { + checkBox_Read.Checked = true; + } + else + { + checkBox_Read.Checked = false; + } + + if ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_QUERY_INFORMATION_ACCESS) > 0) + { + checkBox_QueryInfo.Checked = true; + } + else + { + checkBox_QueryInfo.Checked = false; + } + + if ( (accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_SET_INFORMATION) > 0 ) + { + checkBox_SetInfo.Checked = true; + } + else + { + checkBox_SetInfo.Checked = false; + } + + if ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_OPEN_WITH_CREATE_OR_OVERWRITE_ACCESS) > 0) + { + checkBox_Creation.Checked = true; + } + else + { + checkBox_Creation.Checked = false; + } + + if ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_QUERY_SECURITY_ACCESS) > 0) + { + checkBox_EnableEncryptionOnRead.Checked = true; + } + else + { + checkBox_EnableEncryptionOnRead.Checked = false; + } + + if ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_SET_SECURITY_ACCESS) > 0) + { + checkBox_SetSecurity.Checked = true; + } + else + { + checkBox_SetSecurity.Checked = false; + } + + if ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_ALL_SAVE_AS) > 0) + { + checkBox_AllowEncryptNewFile.Checked = true; + } + else + { + checkBox_AllowEncryptNewFile.Checked = false; + } + + if ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_COPY_PROTECTED_FILES_OUT) > 0) + { + checkBox_AllowCopyout.Checked = true; + } + else + { + checkBox_AllowCopyout.Checked = false; + } + + if ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_READ_ENCRYPTED_FILES) > 0) + { + checkBox_AllowReadEncryptedFiles.Checked = true; + } + else + { + checkBox_AllowReadEncryptedFiles.Checked = false; + } + + + if ((accessFlags & (uint)FilterAPI.AccessFlag.DISABLE_ENCRYPT_DATA_ON_READ) > 0) + { + checkBox_EnableEncryptionOnRead.Checked = false; + } + else + { + checkBox_EnableEncryptionOnRead.Checked = true; + } + } + + private void button_FileAccessFlags_Click(object sender, EventArgs e) + { + OptionForm optionForm = new OptionForm(OptionForm.OptionType.Access_Flag, textBox_FileAccessFlags.Text); + + if (optionForm.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + if (optionForm.AccessFlags > 0) + { + textBox_FileAccessFlags.Text = optionForm.AccessFlags.ToString(); + } + else + { + //if the accessFlag is 0, it is exclude filter rule,this is not what we want, so we need to include this flag. + textBox_FileAccessFlags.Text = ((uint)FilterAPI.AccessFlag.LEAST_ACCESS_FLAG).ToString(); + } + + SetCheckBoxValue(); + } + } + + private void checkBox_Read_CheckedChanged(object sender, EventArgs e) + { + uint accessFlags = uint.Parse(textBox_FileAccessFlags.Text.Trim()); + if (checkBox_Read.Checked) + { + accessFlags |= (uint)FilterAPI.AccessFlag.ALLOW_READ_ACCESS; + } + else + { + accessFlags &= ~(uint)FilterAPI.AccessFlag.ALLOW_READ_ACCESS; + } + + textBox_FileAccessFlags.Text = accessFlags.ToString(); + } + + private void checkBox_Write_CheckedChanged(object sender, EventArgs e) + { + uint accessFlags = uint.Parse(textBox_FileAccessFlags.Text.Trim()); + if (checkBox_Write.Checked) + { + accessFlags |= (uint)FilterAPI.AccessFlag.ALLOW_WRITE_ACCESS; + } + else + { + accessFlags &= ~(uint)FilterAPI.AccessFlag.ALLOW_WRITE_ACCESS; + } + + textBox_FileAccessFlags.Text = accessFlags.ToString(); + } + + private void checkBox_Creation_CheckedChanged(object sender, EventArgs e) + { + uint accessFlags = uint.Parse(textBox_FileAccessFlags.Text.Trim()); + if (checkBox_Creation.Checked) + { + accessFlags |= (uint)FilterAPI.AccessFlag.ALLOW_OPEN_WITH_CREATE_OR_OVERWRITE_ACCESS; + } + else + { + accessFlags &= ~(uint)FilterAPI.AccessFlag.ALLOW_OPEN_WITH_CREATE_OR_OVERWRITE_ACCESS; + } + + textBox_FileAccessFlags.Text = accessFlags.ToString(); + } + + + + private void checkBox_QueryInfo_CheckedChanged(object sender, EventArgs e) + { + uint accessFlags = uint.Parse(textBox_FileAccessFlags.Text.Trim()); + if (checkBox_QueryInfo.Checked) + { + accessFlags |= (uint)FilterAPI.AccessFlag.ALLOW_QUERY_INFORMATION_ACCESS; + } + else + { + accessFlags &= ~(uint)FilterAPI.AccessFlag.ALLOW_QUERY_INFORMATION_ACCESS; + } + + textBox_FileAccessFlags.Text = accessFlags.ToString(); + } + + private void checkBox_SetInfo_CheckedChanged(object sender, EventArgs e) + { + uint accessFlags = uint.Parse(textBox_FileAccessFlags.Text.Trim()); + if (checkBox_SetInfo.Checked) + { + accessFlags |= (uint)FilterAPI.AccessFlag.ALLOW_SET_INFORMATION; + } + else + { + accessFlags &= ~(uint)FilterAPI.AccessFlag.ALLOW_SET_INFORMATION; + } + + textBox_FileAccessFlags.Text = accessFlags.ToString(); + } + + private void checkBox_AllowRename_CheckedChanged(object sender, EventArgs e) + { + uint accessFlags = uint.Parse(textBox_FileAccessFlags.Text.Trim()); + if (checkBox_AllowRename.Checked) + { + accessFlags |= (uint)FilterAPI.AccessFlag.ALLOW_FILE_RENAME; + } + else + { + accessFlags &= ~(uint)FilterAPI.AccessFlag.ALLOW_FILE_RENAME; + } + + textBox_FileAccessFlags.Text = accessFlags.ToString(); + } + + private void checkBox_AllowDelete_CheckedChanged(object sender, EventArgs e) + { + uint accessFlags = uint.Parse(textBox_FileAccessFlags.Text.Trim()); + if (checkBox_AllowDelete.Checked) + { + accessFlags |= (uint)FilterAPI.AccessFlag.ALLOW_FILE_DELETE; + } + else + { + accessFlags &= ~(uint)FilterAPI.AccessFlag.ALLOW_FILE_DELETE; + } + + textBox_FileAccessFlags.Text = accessFlags.ToString(); + } + + private void checkBox_EncryptionOnRead_CheckedChanged(object sender, EventArgs e) + { + uint accessFlags = uint.Parse(textBox_FileAccessFlags.Text.Trim()); + if (checkBox_EnableEncryptionOnRead.Checked) + { + accessFlags &= ~(uint)FilterAPI.AccessFlag.DISABLE_ENCRYPT_DATA_ON_READ; + } + else + { + accessFlags |= (uint)FilterAPI.AccessFlag.DISABLE_ENCRYPT_DATA_ON_READ; + } + + textBox_FileAccessFlags.Text = accessFlags.ToString(); + } + + private void checkBox_SetSecurity_CheckedChanged(object sender, EventArgs e) + { + uint accessFlags = uint.Parse(textBox_FileAccessFlags.Text.Trim()); + if (checkBox_SetSecurity.Checked) + { + accessFlags |= (uint)FilterAPI.AccessFlag.ALLOW_SET_SECURITY_ACCESS; + } + else + { + accessFlags &= ~(uint)FilterAPI.AccessFlag.ALLOW_SET_SECURITY_ACCESS; + } + + textBox_FileAccessFlags.Text = accessFlags.ToString(); + } + + private void checkBox_AllowEncryptNewFile_CheckedChanged(object sender, EventArgs e) + { + uint accessFlags = uint.Parse(textBox_FileAccessFlags.Text.Trim()); + if (checkBox_AllowEncryptNewFile.Checked) + { + accessFlags |= (uint)FilterAPI.AccessFlag.ALLOW_ENCRYPT_NEW_FILE; + } + else + { + accessFlags &= ~(uint)FilterAPI.AccessFlag.ALLOW_ENCRYPT_NEW_FILE; + } + + textBox_FileAccessFlags.Text = accessFlags.ToString(); + } + + private void checkBox_AllowCopyout_CheckedChanged(object sender, EventArgs e) + { + uint accessFlags = uint.Parse(textBox_FileAccessFlags.Text.Trim()); + if (checkBox_AllowCopyout.Checked) + { + accessFlags |= (uint)FilterAPI.AccessFlag.ALLOW_COPY_PROTECTED_FILES_OUT; + } + else + { + accessFlags &= ~(uint)FilterAPI.AccessFlag.ALLOW_COPY_PROTECTED_FILES_OUT; + } + + textBox_FileAccessFlags.Text = accessFlags.ToString(); + } + + private void checkBox_AllowReadEncryptedFiles_CheckedChanged(object sender, EventArgs e) + { + uint accessFlags = uint.Parse(textBox_FileAccessFlags.Text.Trim()); + if (checkBox_AllowReadEncryptedFiles.Checked) + { + accessFlags |= (uint)FilterAPI.AccessFlag.ALLOW_READ_ENCRYPTED_FILES; + } + else + { + accessFlags &= ~(uint)FilterAPI.AccessFlag.ALLOW_READ_ENCRYPTED_FILES; + } + + textBox_FileAccessFlags.Text = accessFlags.ToString(); + } + + private void button_ProcessId_Click(object sender, EventArgs e) + { + OptionForm optionForm = new OptionForm(OptionForm.OptionType.ProccessId, textBox_ProcessId.Text); + + if (optionForm.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + if (optionForm.ProcessId.Length > 0) + { + textBox_ProcessId.Text = optionForm.ProcessId; + } + } + } + + private void button_GetProcessSha256_Click(object sender, EventArgs e) + { + OpenFileDialog fileDialog = new OpenFileDialog(); + if (fileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + string fileName = fileDialog.FileName; + byte[] hashBytes = new byte[32]; + uint hashBytesLength = 32; + + if (FilterAPI.Sha256HashFile(fileName, hashBytes, ref hashBytesLength)) + { + textBox_ProcessSha256Hash.Text += Utils.ByteArrayToHex(hashBytes); + } + else + { + string lastError = "Get file sha256 hash failed with error:" + FilterAPI.GetLastErrorMessage(); + MessageBox.Show(lastError, "Get sha256 hash", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + + } + + private void button_GetCertificateName_Click(object sender, EventArgs e) + { + OpenFileDialog fileDialog = new OpenFileDialog(); + if (fileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + string fileName = fileDialog.FileName; + uint len = 1024; + long signedTime = 0; + string subjectName = new string((char)0, (int)len); + + if (FilterAPI.GetSignerInfo(fileName, subjectName, ref len, ref signedTime)) + { + subjectName = subjectName.Substring(0, (int)len / 2); + textBox_ProcessCertificateName.Text = subjectName; + } + else + { + string lastError = "Get process's certificate name failed with error:" + FilterAPI.GetLastErrorMessage(); + MessageBox.Show(lastError, "Get process's certificate name", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + } + + + private void button_InfoProcessName_Click(object sender, EventArgs e) + { + MessageBox.Show("Set the specific access rights to the process name list, seperate the process name with ';'."); + } + + private void button_InfoUserName_Click(object sender, EventArgs e) + { + MessageBox.Show("Set the specific access rights to the user name list, seperate the user name with ';'."); + } + + private void button_InfoCopyout_Click(object sender, EventArgs e) + { + MessageBox.Show("Prevent the files from being copied out of the folder when it was disabled."); + } + + private void button_InfoEncryptNewFile_Click(object sender, EventArgs e) + { + MessageBox.Show("Automatically encrypt the new created file when it was enabled, or it won't encrypt the new created file, a use case: copy the encrypted file to the folder, it won't encrypt the file again. To enable this feature it requires the encryption was enabled in the filter rule."); + } + + private void button_InfoDecryptFile_Click(object sender, EventArgs e) + { + MessageBox.Show("Automatically decrypt the created file when it was enabled, or the process will read the raw data of the encrypted file, a use case: the backup software. To enable this feature it requires the encryption was enabled in the filter rule."); + } + + private void button_InfoEncryptOnRead_Click(object sender, EventArgs e) + { + MessageBox.Show("If you want to encrypt the file only when it was read by the process, you can enable the encryption feature, disable the new file encryption, enable the encryption on the go. To enable this feature it requires the encryption was enabled in the filter rule."); + } + + } +} diff --git a/Demo_Source_Code/CSharpDemo/CommonObjects/AccessRightsForm.resx b/Demo_Source_Code/CSharpDemo/CommonObjects/AccessRightsForm.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/CommonObjects/AccessRightsForm.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/CommonObjects/CommonObjects.csproj b/Demo_Source_Code/CSharpDemo/CommonObjects/CommonObjects.csproj new file mode 100644 index 0000000..8de862e --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/CommonObjects/CommonObjects.csproj @@ -0,0 +1,176 @@ + + + + Debug + AnyCPU + 8.0.30703 + 2.0 + {34CB783E-DDA2-4CE3-80BC-37B25AA33E5F} + Library + Properties + EaseFilter.CommonObjects + CommonObjects + v4.5 + 512 + SAK + SAK + SAK + SAK + + + + true + full + false + ..\..\Release\ + DEBUG;TRACE + prompt + 4 + false + + + pdbonly + true + ..\..\Release\ + TRACE + prompt + 4 + false + false + + + + + + + + + + + + + + + + + + + + Form + + + InputForm.cs + + + + Form + + + ProcessFilterSetting.cs + + + True + True + Resources.resx + + + Form + + + AccessRightsForm.cs + + + Form + + + FilterRuleForm.cs + + + + Form + + + EventForm.cs + + + + + + Form + + + ControlFilterRuleSettigs.cs + + + Form + + + OptionForm.cs + + + + + Form + + + SettingsForm.cs + + + + + EventForm.cs + + + AccessRightsForm.cs + + + FilterRuleForm.cs + + + ControlFilterRuleSettigs.cs + + + InputForm.cs + + + OptionForm.cs + + + ProcessFilterSetting.cs + + + ResXFileCodeGenerator + Resources.Designer.cs + + + SettingsForm.cs + + + + + + + + + + + + + + {21540012-A296-45CE-8D35-3EA5A07B32A6} + FilterControl + + + + + + + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/CommonObjects/ConfigSetting.cs b/Demo_Source_Code/CSharpDemo/CommonObjects/ConfigSetting.cs new file mode 100644 index 0000000..be8e453 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/CommonObjects/ConfigSetting.cs @@ -0,0 +1,369 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Inc. +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + + +using System; +using System.Configuration; +using System.Collections; +using System.Collections.Generic; + +using EaseFilter.FilterControl; + +namespace EaseFilter.CommonObjects +{ + + public class ConfigSetting + { + static private string configPath = string.Empty; + static private System.Configuration.Configuration config = null; + static private FilterRuleSection filterRuleSection = new FilterRuleSection(); + static private RegistryFilterRuleSection registryFilterRuleSection = new RegistryFilterRuleSection(); + static private ProcessFilterRuleSection processFilterRuleSection = new ProcessFilterRuleSection(); + + static ConfigSetting() + { + try + { + config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); + configPath = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None).FilePath; + + filterRuleSection = (FilterRuleSection)config.Sections["FilterRuleSection"]; + registryFilterRuleSection = (RegistryFilterRuleSection)config.Sections["RegistryFilterRuleSection"]; + processFilterRuleSection = (ProcessFilterRuleSection)config.Sections["ProcessFilterRuleSection"]; + + if (filterRuleSection == null) + { + filterRuleSection = new FilterRuleSection(); + config.Sections.Add("FilterRuleSection", filterRuleSection); + + } + + if (registryFilterRuleSection == null) + { + registryFilterRuleSection = new RegistryFilterRuleSection(); + config.Sections.Add("RegistryFilterRuleSection", registryFilterRuleSection); + + } + + if (processFilterRuleSection == null) + { + processFilterRuleSection = new ProcessFilterRuleSection(); + config.Sections.Add("ProcessFilterRuleSection", processFilterRuleSection); + + } + } + catch + { + } + } + + public static void Save() + { + config.Save(ConfigurationSaveMode.Full); + } + + public static Dictionary GetFilterRules() + { + Dictionary filterRules = new Dictionary(); + + foreach (FileFilterRule filterRule in filterRuleSection.Instances) + { + filterRules.Add(filterRule.IncludeFileFilterMask, filterRule); + } + + return filterRules; + } + + public static void AddFilterRule(FileFilterRule filterRule) + { + + filterRuleSection.Instances.Add(filterRule); + + return ; + } + + public static void RemoveFilterRule(string includeFilterMask) + { + filterRuleSection.Instances.Remove(includeFilterMask); + FilterAPI.RemoveFilterRule(includeFilterMask); + + return; + } + + public static Dictionary GetProcessFilterRules() + { + Dictionary filterRules = new Dictionary(); + + foreach (ProcessFilterRule filterRule in processFilterRuleSection.Instances) + { + filterRules.Add(filterRule.ProcessNameFilterMask + filterRule.ProcessId, filterRule); + } + + return filterRules; + } + + public static void AddProcessFilterRule(ProcessFilterRule filterRule) + { + processFilterRuleSection.Instances.Add(filterRule); + return; + } + + public static void RemoveProcessFilterRule(ProcessFilterRule filterRule) + { + processFilterRuleSection.Instances.Remove(filterRule.ProcessNameFilterMask + filterRule.ProcessId); + + if (filterRule.ProcessNameFilterMask.Length > 0) + { + FilterAPI.RemoveProcessFilterRule((uint)filterRule.ProcessNameFilterMask.Length * 2, filterRule.ProcessNameFilterMask); + } + + return; + } + + public static Dictionary GetRegistryFilterRules() + { + Dictionary registryFilterRules = new Dictionary(); + + foreach (RegistryFilterRule registryFilterRule in registryFilterRuleSection.Instances) + { + registryFilterRules.Add(registryFilterRule.ProcessId + registryFilterRule.ProcessNameFilterMask, registryFilterRule); + } + + return registryFilterRules; + } + + public static void AddRegistryFilterRule(RegistryFilterRule registryFilterRule) + { + + registryFilterRuleSection.Instances.Add(registryFilterRule); + + return; + } + + public static void RemoveRegistryFilterRule(string processId,string processName) + { + registryFilterRuleSection.Instances.Remove(processId + processName ); + + return; + } + + public static string GetFilePath() + { + return configPath; + } + + public static bool Get(string name, bool value) + { + try + { + return bool.Parse(config.AppSettings.Settings[name].Value); + } + catch + { + return value; + } + } + + + public static byte Get(string name, byte value) + { + try + { + return byte.Parse(config.AppSettings.Settings[name].Value); + } + catch + { + return value; + } + } + + + public static sbyte Get(string name, sbyte value) + { + try + { + return sbyte.Parse(config.AppSettings.Settings[name].Value); + } + catch + { + return value; + } + } + + + public static char Get(string name, char value) + { + try + { + return char.Parse(config.AppSettings.Settings[name].Value); + } + catch + { + return value; + } + } + + + public static decimal Get(string name, decimal value) + { + try + { + return decimal.Parse(config.AppSettings.Settings[name].Value); + } + catch + { + return value; + } + } + + + public static double Get(string name, double value) + { + try + { + return double.Parse(config.AppSettings.Settings[name].Value); + } + catch + { + return value; + } + } + + public static float Get(string name, float value) + { + try + { + return float.Parse(config.AppSettings.Settings[name].Value); + } + catch + { + return value; + } + } + + + public static int Get(string name, int value) + { + try + { + return int.Parse(config.AppSettings.Settings[name].Value); + } + catch + { + return value; + } + } + + public static uint Get(string name, uint value) + { + try + { + return uint.Parse(config.AppSettings.Settings[name].Value); + } + catch + { + return value; + } + } + + + public static long Get(string name, long value) + { + try + { + return long.Parse(config.AppSettings.Settings[name].Value); + } + catch + { + return value; + } + } + + + public static ulong Get(string name, ulong value) + { + try + { + return ulong.Parse(config.AppSettings.Settings[name].Value); + } + catch + { + return value; + } + } + + + public static short Get(string name, short value) + { + try + { + return short.Parse(config.AppSettings.Settings[name].Value); + } + catch + { + return value; + } + } + + + public static ushort Get(string name, ushort value) + { + try + { + return ushort.Parse(config.AppSettings.Settings[name].Value); + } + catch + { + return value; + } + } + + public static string Get(string name, string value) + { + string str = string.Empty; + try + { + str = config.AppSettings.Settings[name].Value; + } + catch + { + return value; + } + + if (str == null) + str = value; + + return str; + } + + public static void Set(string name, string value) + { + try + { + config.AppSettings.Settings.Remove(name); + config.AppSettings.Settings.Add(name, value); + config.Save(ConfigurationSaveMode.Modified); + ConfigurationManager.RefreshSection("appSettings"); + + } + catch + { + } + } + + } +} diff --git a/Demo_Source_Code/CSharpDemo/CommonObjects/ControlFilterRuleSettigs.Designer.cs b/Demo_Source_Code/CSharpDemo/CommonObjects/ControlFilterRuleSettigs.Designer.cs new file mode 100644 index 0000000..c930d54 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/CommonObjects/ControlFilterRuleSettigs.Designer.cs @@ -0,0 +1,888 @@ +namespace EaseFilter.CommonObjects +{ + partial class ControlFilterRuleSettigs + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.groupBox_AccessControl = new System.Windows.Forms.GroupBox(); + this.button_InfoControlFlag = new System.Windows.Forms.Button(); + this.groupBox4 = new System.Windows.Forms.GroupBox(); + this.button_InfoControlEvents = new System.Windows.Forms.Button(); + this.label17 = new System.Windows.Forms.Label(); + this.textBox_ControlIO = new System.Windows.Forms.TextBox(); + this.button_RegisterControlIO = new System.Windows.Forms.Button(); + this.groupBox3 = new System.Windows.Forms.GroupBox(); + this.button_InfoSignedProcessRights = new System.Windows.Forms.Button(); + this.button_AddSignedProcessAccessRights = new System.Windows.Forms.Button(); + this.textBox_SignedProcessAccessRights = new System.Windows.Forms.TextBox(); + this.label4 = new System.Windows.Forms.Label(); + this.button_InfoTrustedProcessRights = new System.Windows.Forms.Button(); + this.button_AddTrustedProcessRights = new System.Windows.Forms.Button(); + this.textBox_Sha256ProcessAccessRights = new System.Windows.Forms.TextBox(); + this.label3 = new System.Windows.Forms.Label(); + this.button_InfoProcessNameRights = new System.Windows.Forms.Button(); + this.button_InfoProcessIdRights = new System.Windows.Forms.Button(); + this.button_InfoUserRights = new System.Windows.Forms.Button(); + this.textBox_UserRights = new System.Windows.Forms.TextBox(); + this.label1 = new System.Windows.Forms.Label(); + this.button_AddProcessRights = new System.Windows.Forms.Button(); + this.textBox_ProcessIdRights = new System.Windows.Forms.TextBox(); + this.textBox_ProcessRights = new System.Windows.Forms.TextBox(); + this.button_AddProcessIdRights = new System.Windows.Forms.Button(); + this.label22 = new System.Windows.Forms.Label(); + this.button_AddUserRights = new System.Windows.Forms.Button(); + this.label23 = new System.Windows.Forms.Label(); + this.button_SaveControlSettings = new System.Windows.Forms.Button(); + this.groupBox2 = new System.Windows.Forms.GroupBox(); + this.checkBox_EnableSendDeniedEvent = new System.Windows.Forms.CheckBox(); + this.button_InfoEncryptKeyLenght = new System.Windows.Forms.Button(); + this.button_InfoEncryptNewFile = new System.Windows.Forms.Button(); + this.button_InfoCopyout = new System.Windows.Forms.Button(); + this.button_InfoDecryption = new System.Windows.Forms.Button(); + this.button_InfoEncryptOnRead = new System.Windows.Forms.Button(); + this.button_InfoPassPhrase = new System.Windows.Forms.Button(); + this.button_HideFileFilterMask = new System.Windows.Forms.Button(); + this.button_InfoReparseFile = new System.Windows.Forms.Button(); + this.radioButton_EncryptFileWithTagData = new System.Windows.Forms.RadioButton(); + this.radioButton_EncryptFileWithSameKey = new System.Windows.Forms.RadioButton(); + this.checkBox_EnableReparseFile = new System.Windows.Forms.CheckBox(); + this.checkBox_EnableHidenFile = new System.Windows.Forms.CheckBox(); + this.checkBox_AllowReadEncryptedFiles = new System.Windows.Forms.CheckBox(); + this.checkBox_AllowEncryptNewFile = new System.Windows.Forms.CheckBox(); + this.checkBox_AllowCopyOut = new System.Windows.Forms.CheckBox(); + this.checkBox_AllowSetSecurity = new System.Windows.Forms.CheckBox(); + this.checkBox_AllowFileWriting = new System.Windows.Forms.CheckBox(); + this.checkBox_EnableProtectionInBootTime = new System.Windows.Forms.CheckBox(); + this.checkBox_AllowChange = new System.Windows.Forms.CheckBox(); + this.checkBox_AllowDelete = new System.Windows.Forms.CheckBox(); + this.checkBox_AllowRename = new System.Windows.Forms.CheckBox(); + this.checkBox_AllowRemoteAccess = new System.Windows.Forms.CheckBox(); + this.textBox_ReparseFileFilterMask = new System.Windows.Forms.TextBox(); + this.checkBox_AllowNewFileCreation = new System.Windows.Forms.CheckBox(); + this.checkBox_Encryption = new System.Windows.Forms.CheckBox(); + this.textBox_PassPhrase = new System.Windows.Forms.TextBox(); + this.textBox_HiddenFilterMask = new System.Windows.Forms.TextBox(); + this.label_AccessFlags = new System.Windows.Forms.Label(); + this.textBox_FileAccessFlags = new System.Windows.Forms.TextBox(); + this.button_FileAccessFlags = new System.Windows.Forms.Button(); + this.textBox_EncryptWriteBufferSize = new System.Windows.Forms.TextBox(); + this.label2 = new System.Windows.Forms.Label(); + this.button_EncryptWriteBufferSize = new System.Windows.Forms.Button(); + this.groupBox1.SuspendLayout(); + this.groupBox_AccessControl.SuspendLayout(); + this.groupBox4.SuspendLayout(); + this.groupBox3.SuspendLayout(); + this.groupBox2.SuspendLayout(); + this.SuspendLayout(); + // + // groupBox1 + // + this.groupBox1.Controls.Add(this.groupBox_AccessControl); + this.groupBox1.Dock = System.Windows.Forms.DockStyle.Fill; + this.groupBox1.Location = new System.Drawing.Point(0, 0); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size(573, 660); + this.groupBox1.TabIndex = 12; + this.groupBox1.TabStop = false; + // + // groupBox_AccessControl + // + this.groupBox_AccessControl.Controls.Add(this.button_InfoControlFlag); + this.groupBox_AccessControl.Controls.Add(this.groupBox4); + this.groupBox_AccessControl.Controls.Add(this.groupBox3); + this.groupBox_AccessControl.Controls.Add(this.button_SaveControlSettings); + this.groupBox_AccessControl.Controls.Add(this.groupBox2); + this.groupBox_AccessControl.Controls.Add(this.label_AccessFlags); + this.groupBox_AccessControl.Controls.Add(this.textBox_FileAccessFlags); + this.groupBox_AccessControl.Controls.Add(this.button_FileAccessFlags); + this.groupBox_AccessControl.Dock = System.Windows.Forms.DockStyle.Fill; + this.groupBox_AccessControl.Location = new System.Drawing.Point(3, 16); + this.groupBox_AccessControl.Name = "groupBox_AccessControl"; + this.groupBox_AccessControl.Size = new System.Drawing.Size(567, 641); + this.groupBox_AccessControl.TabIndex = 24; + this.groupBox_AccessControl.TabStop = false; + // + // button_InfoControlFlag + // + this.button_InfoControlFlag.Image = global::EaseFilter.CommonObjects.Properties.Resources.about; + this.button_InfoControlFlag.Location = new System.Drawing.Point(530, 8); + this.button_InfoControlFlag.Name = "button_InfoControlFlag"; + this.button_InfoControlFlag.Size = new System.Drawing.Size(28, 20); + this.button_InfoControlFlag.TabIndex = 118; + this.button_InfoControlFlag.UseVisualStyleBackColor = true; + this.button_InfoControlFlag.Click += new System.EventHandler(this.button_InfoControlFlag_Click); + // + // groupBox4 + // + this.groupBox4.Controls.Add(this.button_InfoControlEvents); + this.groupBox4.Controls.Add(this.label17); + this.groupBox4.Controls.Add(this.textBox_ControlIO); + this.groupBox4.Controls.Add(this.button_RegisterControlIO); + this.groupBox4.Location = new System.Drawing.Point(6, 512); + this.groupBox4.Name = "groupBox4"; + this.groupBox4.Size = new System.Drawing.Size(561, 71); + this.groupBox4.TabIndex = 91; + this.groupBox4.TabStop = false; + this.groupBox4.Text = "Register File I/O Callback Notification Settings"; + // + // button_InfoControlEvents + // + this.button_InfoControlEvents.Image = global::EaseFilter.CommonObjects.Properties.Resources.about; + this.button_InfoControlEvents.Location = new System.Drawing.Point(524, 31); + this.button_InfoControlEvents.Name = "button_InfoControlEvents"; + this.button_InfoControlEvents.Size = new System.Drawing.Size(28, 20); + this.button_InfoControlEvents.TabIndex = 127; + this.button_InfoControlEvents.UseVisualStyleBackColor = true; + this.button_InfoControlEvents.Click += new System.EventHandler(this.button_InfoControlEvents_Click); + // + // label17 + // + this.label17.AutoSize = true; + this.label17.Location = new System.Drawing.Point(12, 34); + this.label17.Name = "label17"; + this.label17.Size = new System.Drawing.Size(130, 13); + this.label17.TabIndex = 72; + this.label17.Text = "Register control IO events"; + // + // textBox_ControlIO + // + this.textBox_ControlIO.Location = new System.Drawing.Point(215, 32); + this.textBox_ControlIO.Name = "textBox_ControlIO"; + this.textBox_ControlIO.ReadOnly = true; + this.textBox_ControlIO.Size = new System.Drawing.Size(242, 20); + this.textBox_ControlIO.TabIndex = 73; + this.textBox_ControlIO.Text = "0"; + // + // button_RegisterControlIO + // + this.button_RegisterControlIO.Location = new System.Drawing.Point(473, 31); + this.button_RegisterControlIO.Name = "button_RegisterControlIO"; + this.button_RegisterControlIO.Size = new System.Drawing.Size(41, 20); + this.button_RegisterControlIO.TabIndex = 74; + this.button_RegisterControlIO.Text = "..."; + this.button_RegisterControlIO.UseVisualStyleBackColor = true; + this.button_RegisterControlIO.Click += new System.EventHandler(this.button_RegisterControlIO_Click); + // + // groupBox3 + // + this.groupBox3.Controls.Add(this.button_InfoSignedProcessRights); + this.groupBox3.Controls.Add(this.button_AddSignedProcessAccessRights); + this.groupBox3.Controls.Add(this.textBox_SignedProcessAccessRights); + this.groupBox3.Controls.Add(this.label4); + this.groupBox3.Controls.Add(this.button_InfoTrustedProcessRights); + this.groupBox3.Controls.Add(this.button_AddTrustedProcessRights); + this.groupBox3.Controls.Add(this.textBox_Sha256ProcessAccessRights); + this.groupBox3.Controls.Add(this.label3); + this.groupBox3.Controls.Add(this.button_InfoProcessNameRights); + this.groupBox3.Controls.Add(this.button_InfoProcessIdRights); + this.groupBox3.Controls.Add(this.button_InfoUserRights); + this.groupBox3.Controls.Add(this.textBox_UserRights); + this.groupBox3.Controls.Add(this.label1); + this.groupBox3.Controls.Add(this.button_AddProcessRights); + this.groupBox3.Controls.Add(this.textBox_ProcessIdRights); + this.groupBox3.Controls.Add(this.textBox_ProcessRights); + this.groupBox3.Controls.Add(this.button_AddProcessIdRights); + this.groupBox3.Controls.Add(this.label22); + this.groupBox3.Controls.Add(this.button_AddUserRights); + this.groupBox3.Controls.Add(this.label23); + this.groupBox3.Location = new System.Drawing.Point(9, 326); + this.groupBox3.Name = "groupBox3"; + this.groupBox3.Size = new System.Drawing.Size(555, 180); + this.groupBox3.TabIndex = 90; + this.groupBox3.TabStop = false; + this.groupBox3.Text = "Add or Remove Access Rights to Processes or Users (create whiltelist or blacklist" + + ")"; + // + // button_InfoSignedProcessRights + // + this.button_InfoSignedProcessRights.Image = global::EaseFilter.CommonObjects.Properties.Resources.about; + this.button_InfoSignedProcessRights.Location = new System.Drawing.Point(518, 88); + this.button_InfoSignedProcessRights.Name = "button_InfoSignedProcessRights"; + this.button_InfoSignedProcessRights.Size = new System.Drawing.Size(28, 20); + this.button_InfoSignedProcessRights.TabIndex = 134; + this.button_InfoSignedProcessRights.UseVisualStyleBackColor = true; + this.button_InfoSignedProcessRights.Click += new System.EventHandler(this.button_InfoSignedProcessRights_Click); + // + // button_AddSignedProcessAccessRights + // + this.button_AddSignedProcessAccessRights.Location = new System.Drawing.Point(470, 87); + this.button_AddSignedProcessAccessRights.Name = "button_AddSignedProcessAccessRights"; + this.button_AddSignedProcessAccessRights.Size = new System.Drawing.Size(41, 20); + this.button_AddSignedProcessAccessRights.TabIndex = 133; + this.button_AddSignedProcessAccessRights.Text = "Add"; + this.button_AddSignedProcessAccessRights.UseVisualStyleBackColor = true; + this.button_AddSignedProcessAccessRights.Click += new System.EventHandler(this.button_AddSignedProcessAccessRights_Click); + // + // textBox_SignedProcessAccessRights + // + this.textBox_SignedProcessAccessRights.Location = new System.Drawing.Point(212, 88); + this.textBox_SignedProcessAccessRights.Name = "textBox_SignedProcessAccessRights"; + this.textBox_SignedProcessAccessRights.Size = new System.Drawing.Size(242, 20); + this.textBox_SignedProcessAccessRights.TabIndex = 131; + // + // label4 + // + this.label4.AutoSize = true; + this.label4.Location = new System.Drawing.Point(9, 87); + this.label4.Name = "label4"; + this.label4.Size = new System.Drawing.Size(108, 13); + this.label4.TabIndex = 132; + this.label4.Text = "Signed process rights"; + // + // button_InfoTrustedProcessRights + // + this.button_InfoTrustedProcessRights.Image = global::EaseFilter.CommonObjects.Properties.Resources.about; + this.button_InfoTrustedProcessRights.Location = new System.Drawing.Point(521, 55); + this.button_InfoTrustedProcessRights.Name = "button_InfoTrustedProcessRights"; + this.button_InfoTrustedProcessRights.Size = new System.Drawing.Size(28, 20); + this.button_InfoTrustedProcessRights.TabIndex = 130; + this.button_InfoTrustedProcessRights.UseVisualStyleBackColor = true; + this.button_InfoTrustedProcessRights.Click += new System.EventHandler(this.button_InfoSha256ProcessRights_Click); + // + // button_AddTrustedProcessRights + // + this.button_AddTrustedProcessRights.Location = new System.Drawing.Point(473, 54); + this.button_AddTrustedProcessRights.Name = "button_AddTrustedProcessRights"; + this.button_AddTrustedProcessRights.Size = new System.Drawing.Size(41, 20); + this.button_AddTrustedProcessRights.TabIndex = 129; + this.button_AddTrustedProcessRights.Text = "Add"; + this.button_AddTrustedProcessRights.UseVisualStyleBackColor = true; + this.button_AddTrustedProcessRights.Click += new System.EventHandler(this.button_AddSha256ProcessAccessRights_Click); + // + // textBox_Sha256ProcessAccessRights + // + this.textBox_Sha256ProcessAccessRights.Location = new System.Drawing.Point(212, 55); + this.textBox_Sha256ProcessAccessRights.Name = "textBox_Sha256ProcessAccessRights"; + this.textBox_Sha256ProcessAccessRights.Size = new System.Drawing.Size(242, 20); + this.textBox_Sha256ProcessAccessRights.TabIndex = 127; + // + // label3 + // + this.label3.AutoSize = true; + this.label3.Location = new System.Drawing.Point(12, 54); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(112, 13); + this.label3.TabIndex = 128; + this.label3.Text = "Sha256 process rights"; + // + // button_InfoProcessNameRights + // + this.button_InfoProcessNameRights.Image = global::EaseFilter.CommonObjects.Properties.Resources.about; + this.button_InfoProcessNameRights.Location = new System.Drawing.Point(521, 22); + this.button_InfoProcessNameRights.Name = "button_InfoProcessNameRights"; + this.button_InfoProcessNameRights.Size = new System.Drawing.Size(28, 20); + this.button_InfoProcessNameRights.TabIndex = 124; + this.button_InfoProcessNameRights.UseVisualStyleBackColor = true; + this.button_InfoProcessNameRights.Click += new System.EventHandler(this.button_InfoProcessNameRights_Click); + // + // button_InfoProcessIdRights + // + this.button_InfoProcessIdRights.Image = global::EaseFilter.CommonObjects.Properties.Resources.about; + this.button_InfoProcessIdRights.Location = new System.Drawing.Point(521, 121); + this.button_InfoProcessIdRights.Name = "button_InfoProcessIdRights"; + this.button_InfoProcessIdRights.Size = new System.Drawing.Size(28, 20); + this.button_InfoProcessIdRights.TabIndex = 125; + this.button_InfoProcessIdRights.UseVisualStyleBackColor = true; + this.button_InfoProcessIdRights.Click += new System.EventHandler(this.button_InfoProcessIdRights_Click); + // + // button_InfoUserRights + // + this.button_InfoUserRights.Image = global::EaseFilter.CommonObjects.Properties.Resources.about; + this.button_InfoUserRights.Location = new System.Drawing.Point(521, 153); + this.button_InfoUserRights.Name = "button_InfoUserRights"; + this.button_InfoUserRights.Size = new System.Drawing.Size(28, 20); + this.button_InfoUserRights.TabIndex = 126; + this.button_InfoUserRights.UseVisualStyleBackColor = true; + this.button_InfoUserRights.Click += new System.EventHandler(this.button_InfoUserRights_Click); + // + // textBox_UserRights + // + this.textBox_UserRights.Location = new System.Drawing.Point(212, 153); + this.textBox_UserRights.Name = "textBox_UserRights"; + this.textBox_UserRights.Size = new System.Drawing.Size(242, 20); + this.textBox_UserRights.TabIndex = 80; + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(12, 123); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(96, 13); + this.label1.TabIndex = 88; + this.label1.Text = "Processes Id rights"; + // + // button_AddProcessRights + // + this.button_AddProcessRights.Location = new System.Drawing.Point(473, 21); + this.button_AddProcessRights.Name = "button_AddProcessRights"; + this.button_AddProcessRights.Size = new System.Drawing.Size(41, 20); + this.button_AddProcessRights.TabIndex = 79; + this.button_AddProcessRights.Text = "Add"; + this.button_AddProcessRights.UseVisualStyleBackColor = true; + this.button_AddProcessRights.Click += new System.EventHandler(this.button_AddProcessRights_Click); + // + // textBox_ProcessIdRights + // + this.textBox_ProcessIdRights.Location = new System.Drawing.Point(212, 124); + this.textBox_ProcessIdRights.Name = "textBox_ProcessIdRights"; + this.textBox_ProcessIdRights.Size = new System.Drawing.Size(242, 20); + this.textBox_ProcessIdRights.TabIndex = 87; + // + // textBox_ProcessRights + // + this.textBox_ProcessRights.Location = new System.Drawing.Point(212, 22); + this.textBox_ProcessRights.Name = "textBox_ProcessRights"; + this.textBox_ProcessRights.Size = new System.Drawing.Size(242, 20); + this.textBox_ProcessRights.TabIndex = 77; + // + // button_AddProcessIdRights + // + this.button_AddProcessIdRights.Location = new System.Drawing.Point(473, 123); + this.button_AddProcessIdRights.Name = "button_AddProcessIdRights"; + this.button_AddProcessIdRights.Size = new System.Drawing.Size(41, 20); + this.button_AddProcessIdRights.TabIndex = 89; + this.button_AddProcessIdRights.Text = "Add"; + this.button_AddProcessIdRights.UseVisualStyleBackColor = true; + this.button_AddProcessIdRights.Click += new System.EventHandler(this.button_AddProcessIdRights_Click); + // + // label22 + // + this.label22.AutoSize = true; + this.label22.Location = new System.Drawing.Point(12, 21); + this.label22.Name = "label22"; + this.label22.Size = new System.Drawing.Size(113, 13); + this.label22.TabIndex = 78; + this.label22.Text = "Processes name rights"; + // + // button_AddUserRights + // + this.button_AddUserRights.Location = new System.Drawing.Point(473, 153); + this.button_AddUserRights.Name = "button_AddUserRights"; + this.button_AddUserRights.Size = new System.Drawing.Size(41, 20); + this.button_AddUserRights.TabIndex = 82; + this.button_AddUserRights.Text = "Add"; + this.button_AddUserRights.UseVisualStyleBackColor = true; + this.button_AddUserRights.Click += new System.EventHandler(this.button_AddUserRights_Click); + // + // label23 + // + this.label23.AutoSize = true; + this.label23.Location = new System.Drawing.Point(12, 157); + this.label23.Name = "label23"; + this.label23.Size = new System.Drawing.Size(62, 13); + this.label23.TabIndex = 81; + this.label23.Text = "Users rights"; + // + // button_SaveControlSettings + // + this.button_SaveControlSettings.DialogResult = System.Windows.Forms.DialogResult.OK; + this.button_SaveControlSettings.Location = new System.Drawing.Point(390, 588); + this.button_SaveControlSettings.Margin = new System.Windows.Forms.Padding(2); + this.button_SaveControlSettings.Name = "button_SaveControlSettings"; + this.button_SaveControlSettings.Size = new System.Drawing.Size(130, 22); + this.button_SaveControlSettings.TabIndex = 85; + this.button_SaveControlSettings.Text = "Save Control Settings"; + this.button_SaveControlSettings.UseVisualStyleBackColor = true; + this.button_SaveControlSettings.Click += new System.EventHandler(this.button_SaveControlSettings_Click); + // + // groupBox2 + // + this.groupBox2.Controls.Add(this.button_EncryptWriteBufferSize); + this.groupBox2.Controls.Add(this.label2); + this.groupBox2.Controls.Add(this.textBox_EncryptWriteBufferSize); + this.groupBox2.Controls.Add(this.checkBox_EnableSendDeniedEvent); + this.groupBox2.Controls.Add(this.button_InfoEncryptKeyLenght); + this.groupBox2.Controls.Add(this.button_InfoEncryptNewFile); + this.groupBox2.Controls.Add(this.button_InfoCopyout); + this.groupBox2.Controls.Add(this.button_InfoDecryption); + this.groupBox2.Controls.Add(this.button_InfoEncryptOnRead); + this.groupBox2.Controls.Add(this.button_InfoPassPhrase); + this.groupBox2.Controls.Add(this.button_HideFileFilterMask); + this.groupBox2.Controls.Add(this.button_InfoReparseFile); + this.groupBox2.Controls.Add(this.radioButton_EncryptFileWithTagData); + this.groupBox2.Controls.Add(this.radioButton_EncryptFileWithSameKey); + this.groupBox2.Controls.Add(this.checkBox_EnableReparseFile); + this.groupBox2.Controls.Add(this.checkBox_EnableHidenFile); + this.groupBox2.Controls.Add(this.checkBox_AllowReadEncryptedFiles); + this.groupBox2.Controls.Add(this.checkBox_AllowEncryptNewFile); + this.groupBox2.Controls.Add(this.checkBox_AllowCopyOut); + this.groupBox2.Controls.Add(this.checkBox_AllowSetSecurity); + this.groupBox2.Controls.Add(this.checkBox_AllowFileWriting); + this.groupBox2.Controls.Add(this.checkBox_EnableProtectionInBootTime); + this.groupBox2.Controls.Add(this.checkBox_AllowChange); + this.groupBox2.Controls.Add(this.checkBox_AllowDelete); + this.groupBox2.Controls.Add(this.checkBox_AllowRename); + this.groupBox2.Controls.Add(this.checkBox_AllowRemoteAccess); + this.groupBox2.Controls.Add(this.textBox_ReparseFileFilterMask); + this.groupBox2.Controls.Add(this.checkBox_AllowNewFileCreation); + this.groupBox2.Controls.Add(this.checkBox_Encryption); + this.groupBox2.Controls.Add(this.textBox_PassPhrase); + this.groupBox2.Controls.Add(this.textBox_HiddenFilterMask); + this.groupBox2.Location = new System.Drawing.Point(9, 38); + this.groupBox2.Name = "groupBox2"; + this.groupBox2.Size = new System.Drawing.Size(555, 282); + this.groupBox2.TabIndex = 76; + this.groupBox2.TabStop = false; + this.groupBox2.Text = "Quick Access Control Flags Settings"; + // + // checkBox_EnableSendDeniedEvent + // + this.checkBox_EnableSendDeniedEvent.AutoSize = true; + this.checkBox_EnableSendDeniedEvent.Location = new System.Drawing.Point(11, 256); + this.checkBox_EnableSendDeniedEvent.Name = "checkBox_EnableSendDeniedEvent"; + this.checkBox_EnableSendDeniedEvent.Size = new System.Drawing.Size(414, 17); + this.checkBox_EnableSendDeniedEvent.TabIndex = 126; + this.checkBox_EnableSendDeniedEvent.Text = "Enable send denied file IO event which was blocked by the file access control fla" + + "g"; + this.checkBox_EnableSendDeniedEvent.UseVisualStyleBackColor = true; + // + // button_InfoEncryptKeyLenght + // + this.button_InfoEncryptKeyLenght.Image = global::EaseFilter.CommonObjects.Properties.Resources.about; + this.button_InfoEncryptKeyLenght.Location = new System.Drawing.Point(521, 139); + this.button_InfoEncryptKeyLenght.Name = "button_InfoEncryptKeyLenght"; + this.button_InfoEncryptKeyLenght.Size = new System.Drawing.Size(28, 20); + this.button_InfoEncryptKeyLenght.TabIndex = 119; + this.button_InfoEncryptKeyLenght.UseVisualStyleBackColor = true; + this.button_InfoEncryptKeyLenght.Click += new System.EventHandler(this.button_EnableEncryptionKeyFromService_Click); + // + // button_InfoEncryptNewFile + // + this.button_InfoEncryptNewFile.Image = global::EaseFilter.CommonObjects.Properties.Resources.about; + this.button_InfoEncryptNewFile.Location = new System.Drawing.Point(521, 40); + this.button_InfoEncryptNewFile.Name = "button_InfoEncryptNewFile"; + this.button_InfoEncryptNewFile.Size = new System.Drawing.Size(28, 20); + this.button_InfoEncryptNewFile.TabIndex = 125; + this.button_InfoEncryptNewFile.UseVisualStyleBackColor = true; + this.button_InfoEncryptNewFile.Click += new System.EventHandler(this.button_InfoEncryptNewFile_Click); + // + // button_InfoCopyout + // + this.button_InfoCopyout.Image = global::EaseFilter.CommonObjects.Properties.Resources.about; + this.button_InfoCopyout.Location = new System.Drawing.Point(521, 19); + this.button_InfoCopyout.Name = "button_InfoCopyout"; + this.button_InfoCopyout.Size = new System.Drawing.Size(28, 20); + this.button_InfoCopyout.TabIndex = 124; + this.button_InfoCopyout.UseVisualStyleBackColor = true; + this.button_InfoCopyout.Click += new System.EventHandler(this.button_InfoCopyout_Click); + // + // button_InfoDecryption + // + this.button_InfoDecryption.Image = global::EaseFilter.CommonObjects.Properties.Resources.about; + this.button_InfoDecryption.Location = new System.Drawing.Point(521, 66); + this.button_InfoDecryption.Name = "button_InfoDecryption"; + this.button_InfoDecryption.Size = new System.Drawing.Size(28, 20); + this.button_InfoDecryption.TabIndex = 119; + this.button_InfoDecryption.UseVisualStyleBackColor = true; + this.button_InfoDecryption.Click += new System.EventHandler(this.button_InfoDecryption_Click); + // + // button_InfoEncryptOnRead + // + this.button_InfoEncryptOnRead.Image = global::EaseFilter.CommonObjects.Properties.Resources.about; + this.button_InfoEncryptOnRead.Location = new System.Drawing.Point(521, 92); + this.button_InfoEncryptOnRead.Name = "button_InfoEncryptOnRead"; + this.button_InfoEncryptOnRead.Size = new System.Drawing.Size(28, 20); + this.button_InfoEncryptOnRead.TabIndex = 120; + this.button_InfoEncryptOnRead.UseVisualStyleBackColor = true; + this.button_InfoEncryptOnRead.Click += new System.EventHandler(this.button_InfoEncryptOnRead_Click); + // + // button_InfoPassPhrase + // + this.button_InfoPassPhrase.Image = global::EaseFilter.CommonObjects.Properties.Resources.about; + this.button_InfoPassPhrase.Location = new System.Drawing.Point(521, 118); + this.button_InfoPassPhrase.Name = "button_InfoPassPhrase"; + this.button_InfoPassPhrase.Size = new System.Drawing.Size(28, 20); + this.button_InfoPassPhrase.TabIndex = 121; + this.button_InfoPassPhrase.UseVisualStyleBackColor = true; + this.button_InfoPassPhrase.Click += new System.EventHandler(this.button_InfoPassPhrase_Click); + // + // button_HideFileFilterMask + // + this.button_HideFileFilterMask.Image = global::EaseFilter.CommonObjects.Properties.Resources.about; + this.button_HideFileFilterMask.Location = new System.Drawing.Point(521, 196); + this.button_HideFileFilterMask.Name = "button_HideFileFilterMask"; + this.button_HideFileFilterMask.Size = new System.Drawing.Size(28, 20); + this.button_HideFileFilterMask.TabIndex = 122; + this.button_HideFileFilterMask.UseVisualStyleBackColor = true; + this.button_HideFileFilterMask.Click += new System.EventHandler(this.button_HideFileFilterMask_Click); + // + // button_InfoReparseFile + // + this.button_InfoReparseFile.Image = global::EaseFilter.CommonObjects.Properties.Resources.about; + this.button_InfoReparseFile.Location = new System.Drawing.Point(521, 225); + this.button_InfoReparseFile.Name = "button_InfoReparseFile"; + this.button_InfoReparseFile.Size = new System.Drawing.Size(28, 20); + this.button_InfoReparseFile.TabIndex = 123; + this.button_InfoReparseFile.UseVisualStyleBackColor = true; + this.button_InfoReparseFile.Click += new System.EventHandler(this.button_InfoReparseFile_Click); + // + // radioButton_EncryptFileWithTagData + // + this.radioButton_EncryptFileWithTagData.AutoSize = true; + this.radioButton_EncryptFileWithTagData.Location = new System.Drawing.Point(158, 138); + this.radioButton_EncryptFileWithTagData.Name = "radioButton_EncryptFileWithTagData"; + this.radioButton_EncryptFileWithTagData.Size = new System.Drawing.Size(343, 17); + this.radioButton_EncryptFileWithTagData.TabIndex = 93; + this.radioButton_EncryptFileWithTagData.Text = "Encrypt file with unique encryption key, iv and tag data from service"; + this.radioButton_EncryptFileWithTagData.UseVisualStyleBackColor = true; + // + // radioButton_EncryptFileWithSameKey + // + this.radioButton_EncryptFileWithSameKey.AutoSize = true; + this.radioButton_EncryptFileWithSameKey.Checked = true; + this.radioButton_EncryptFileWithSameKey.Location = new System.Drawing.Point(158, 117); + this.radioButton_EncryptFileWithSameKey.Name = "radioButton_EncryptFileWithSameKey"; + this.radioButton_EncryptFileWithSameKey.Size = new System.Drawing.Size(248, 17); + this.radioButton_EncryptFileWithSameKey.TabIndex = 91; + this.radioButton_EncryptFileWithSameKey.TabStop = true; + this.radioButton_EncryptFileWithSameKey.Text = "Encrypt file with same root key from passphrase"; + this.radioButton_EncryptFileWithSameKey.UseVisualStyleBackColor = true; + // + // checkBox_EnableReparseFile + // + this.checkBox_EnableReparseFile.AutoSize = true; + this.checkBox_EnableReparseFile.Location = new System.Drawing.Point(12, 225); + this.checkBox_EnableReparseFile.Name = "checkBox_EnableReparseFile"; + this.checkBox_EnableReparseFile.Size = new System.Drawing.Size(190, 17); + this.checkBox_EnableReparseFile.TabIndex = 31; + this.checkBox_EnableReparseFile.Text = "Enable reparse files with filter mask"; + this.checkBox_EnableReparseFile.UseVisualStyleBackColor = true; + this.checkBox_EnableReparseFile.CheckedChanged += new System.EventHandler(this.checkBox_EnableReparseFile_CheckedChanged); + // + // checkBox_EnableHidenFile + // + this.checkBox_EnableHidenFile.AutoSize = true; + this.checkBox_EnableHidenFile.Location = new System.Drawing.Point(12, 190); + this.checkBox_EnableHidenFile.Name = "checkBox_EnableHidenFile"; + this.checkBox_EnableHidenFile.Size = new System.Drawing.Size(175, 17); + this.checkBox_EnableHidenFile.TabIndex = 30; + this.checkBox_EnableHidenFile.Text = "Enable hide files with filter mask"; + this.checkBox_EnableHidenFile.UseVisualStyleBackColor = true; + this.checkBox_EnableHidenFile.CheckedChanged += new System.EventHandler(this.checkBox_EnableHidenFile_CheckedChanged); + // + // checkBox_AllowReadEncryptedFiles + // + this.checkBox_AllowReadEncryptedFiles.AutoSize = true; + this.checkBox_AllowReadEncryptedFiles.Location = new System.Drawing.Point(349, 69); + this.checkBox_AllowReadEncryptedFiles.Name = "checkBox_AllowReadEncryptedFiles"; + this.checkBox_AllowReadEncryptedFiles.Size = new System.Drawing.Size(141, 17); + this.checkBox_AllowReadEncryptedFiles.TabIndex = 28; + this.checkBox_AllowReadEncryptedFiles.Text = "Allow read encrypted file"; + this.checkBox_AllowReadEncryptedFiles.UseVisualStyleBackColor = true; + this.checkBox_AllowReadEncryptedFiles.CheckedChanged += new System.EventHandler(this.checkBox_AllowReadEncryptedFiles_CheckedChanged); + // + // checkBox_AllowEncryptNewFile + // + this.checkBox_AllowEncryptNewFile.AutoSize = true; + this.checkBox_AllowEncryptNewFile.Location = new System.Drawing.Point(349, 46); + this.checkBox_AllowEncryptNewFile.Name = "checkBox_AllowEncryptNewFile"; + this.checkBox_AllowEncryptNewFile.Size = new System.Drawing.Size(142, 17); + this.checkBox_AllowEncryptNewFile.TabIndex = 26; + this.checkBox_AllowEncryptNewFile.Text = "Allow new file encryption"; + this.checkBox_AllowEncryptNewFile.UseVisualStyleBackColor = true; + this.checkBox_AllowEncryptNewFile.CheckedChanged += new System.EventHandler(this.checkBox_AllowEncryptNewFile_CheckedChanged); + // + // checkBox_AllowCopyOut + // + this.checkBox_AllowCopyOut.AutoSize = true; + this.checkBox_AllowCopyOut.Location = new System.Drawing.Point(349, 23); + this.checkBox_AllowCopyOut.Name = "checkBox_AllowCopyOut"; + this.checkBox_AllowCopyOut.Size = new System.Drawing.Size(154, 17); + this.checkBox_AllowCopyOut.TabIndex = 27; + this.checkBox_AllowCopyOut.Text = "Allow files being copied out"; + this.checkBox_AllowCopyOut.UseVisualStyleBackColor = true; + this.checkBox_AllowCopyOut.CheckedChanged += new System.EventHandler(this.checkBox_AllowCopyOut_CheckedChanged); + // + // checkBox_AllowSetSecurity + // + this.checkBox_AllowSetSecurity.AutoSize = true; + this.checkBox_AllowSetSecurity.Location = new System.Drawing.Point(158, 46); + this.checkBox_AllowSetSecurity.Name = "checkBox_AllowSetSecurity"; + this.checkBox_AllowSetSecurity.Size = new System.Drawing.Size(137, 17); + this.checkBox_AllowSetSecurity.TabIndex = 25; + this.checkBox_AllowSetSecurity.Text = "Allow security changing"; + this.checkBox_AllowSetSecurity.UseVisualStyleBackColor = true; + this.checkBox_AllowSetSecurity.CheckedChanged += new System.EventHandler(this.checkBox_AllowSetSecurity_CheckedChanged); + // + // checkBox_AllowFileWriting + // + this.checkBox_AllowFileWriting.AutoSize = true; + this.checkBox_AllowFileWriting.Location = new System.Drawing.Point(12, 46); + this.checkBox_AllowFileWriting.Name = "checkBox_AllowFileWriting"; + this.checkBox_AllowFileWriting.Size = new System.Drawing.Size(100, 17); + this.checkBox_AllowFileWriting.TabIndex = 24; + this.checkBox_AllowFileWriting.Text = "Allow file writing"; + this.checkBox_AllowFileWriting.UseVisualStyleBackColor = true; + this.checkBox_AllowFileWriting.CheckedChanged += new System.EventHandler(this.checkBox_AllowFileWriting_CheckedChanged); + // + // checkBox_EnableProtectionInBootTime + // + this.checkBox_EnableProtectionInBootTime.AutoSize = true; + this.checkBox_EnableProtectionInBootTime.Location = new System.Drawing.Point(158, 92); + this.checkBox_EnableProtectionInBootTime.Name = "checkBox_EnableProtectionInBootTime"; + this.checkBox_EnableProtectionInBootTime.Size = new System.Drawing.Size(166, 17); + this.checkBox_EnableProtectionInBootTime.TabIndex = 23; + this.checkBox_EnableProtectionInBootTime.Text = "Enable protection in boot time"; + this.checkBox_EnableProtectionInBootTime.UseVisualStyleBackColor = true; + // + // checkBox_AllowChange + // + this.checkBox_AllowChange.AutoSize = true; + this.checkBox_AllowChange.Location = new System.Drawing.Point(12, 92); + this.checkBox_AllowChange.Name = "checkBox_AllowChange"; + this.checkBox_AllowChange.Size = new System.Drawing.Size(134, 17); + this.checkBox_AllowChange.TabIndex = 15; + this.checkBox_AllowChange.Text = "Allow file info changing"; + this.checkBox_AllowChange.UseVisualStyleBackColor = true; + this.checkBox_AllowChange.CheckedChanged += new System.EventHandler(this.checkBox_AllowChange_CheckedChanged); + // + // checkBox_AllowDelete + // + this.checkBox_AllowDelete.AutoSize = true; + this.checkBox_AllowDelete.Location = new System.Drawing.Point(12, 23); + this.checkBox_AllowDelete.Name = "checkBox_AllowDelete"; + this.checkBox_AllowDelete.Size = new System.Drawing.Size(107, 17); + this.checkBox_AllowDelete.TabIndex = 17; + this.checkBox_AllowDelete.Text = "Allow file deletion"; + this.checkBox_AllowDelete.UseVisualStyleBackColor = true; + this.checkBox_AllowDelete.CheckedChanged += new System.EventHandler(this.checkBox_AllowDelete_CheckedChanged); + // + // checkBox_AllowRename + // + this.checkBox_AllowRename.AutoSize = true; + this.checkBox_AllowRename.Location = new System.Drawing.Point(12, 69); + this.checkBox_AllowRename.Name = "checkBox_AllowRename"; + this.checkBox_AllowRename.Size = new System.Drawing.Size(113, 17); + this.checkBox_AllowRename.TabIndex = 16; + this.checkBox_AllowRename.Text = "Allow file renaming"; + this.checkBox_AllowRename.UseVisualStyleBackColor = true; + this.checkBox_AllowRename.CheckedChanged += new System.EventHandler(this.checkBox_AllowRename_CheckedChanged); + // + // checkBox_AllowRemoteAccess + // + this.checkBox_AllowRemoteAccess.AutoSize = true; + this.checkBox_AllowRemoteAccess.Location = new System.Drawing.Point(158, 69); + this.checkBox_AllowRemoteAccess.Name = "checkBox_AllowRemoteAccess"; + this.checkBox_AllowRemoteAccess.Size = new System.Drawing.Size(176, 17); + this.checkBox_AllowRemoteAccess.TabIndex = 21; + this.checkBox_AllowRemoteAccess.Text = "Allow file accessing via network"; + this.checkBox_AllowRemoteAccess.UseVisualStyleBackColor = true; + this.checkBox_AllowRemoteAccess.CheckedChanged += new System.EventHandler(this.checkBox_AllowRemoteAccess_CheckedChanged); + // + // textBox_ReparseFileFilterMask + // + this.textBox_ReparseFileFilterMask.Location = new System.Drawing.Point(212, 225); + this.textBox_ReparseFileFilterMask.Name = "textBox_ReparseFileFilterMask"; + this.textBox_ReparseFileFilterMask.ReadOnly = true; + this.textBox_ReparseFileFilterMask.Size = new System.Drawing.Size(302, 20); + this.textBox_ReparseFileFilterMask.TabIndex = 83; + // + // checkBox_AllowNewFileCreation + // + this.checkBox_AllowNewFileCreation.AutoSize = true; + this.checkBox_AllowNewFileCreation.Location = new System.Drawing.Point(158, 23); + this.checkBox_AllowNewFileCreation.Name = "checkBox_AllowNewFileCreation"; + this.checkBox_AllowNewFileCreation.Size = new System.Drawing.Size(131, 17); + this.checkBox_AllowNewFileCreation.TabIndex = 22; + this.checkBox_AllowNewFileCreation.Text = "Allow new file creation"; + this.checkBox_AllowNewFileCreation.UseVisualStyleBackColor = true; + this.checkBox_AllowNewFileCreation.CheckedChanged += new System.EventHandler(this.checkBox_AllowNewFileCreation_CheckedChanged); + // + // checkBox_Encryption + // + this.checkBox_Encryption.AutoSize = true; + this.checkBox_Encryption.Location = new System.Drawing.Point(12, 118); + this.checkBox_Encryption.Name = "checkBox_Encryption"; + this.checkBox_Encryption.Size = new System.Drawing.Size(111, 17); + this.checkBox_Encryption.TabIndex = 18; + this.checkBox_Encryption.Text = "Enable encryption"; + this.checkBox_Encryption.UseVisualStyleBackColor = true; + this.checkBox_Encryption.CheckedChanged += new System.EventHandler(this.checkBox_Encryption_CheckedChanged); + // + // textBox_PassPhrase + // + this.textBox_PassPhrase.Location = new System.Drawing.Point(412, 114); + this.textBox_PassPhrase.Name = "textBox_PassPhrase"; + this.textBox_PassPhrase.ReadOnly = true; + this.textBox_PassPhrase.Size = new System.Drawing.Size(91, 20); + this.textBox_PassPhrase.TabIndex = 19; + this.textBox_PassPhrase.UseSystemPasswordChar = true; + // + // textBox_HiddenFilterMask + // + this.textBox_HiddenFilterMask.Location = new System.Drawing.Point(212, 195); + this.textBox_HiddenFilterMask.Name = "textBox_HiddenFilterMask"; + this.textBox_HiddenFilterMask.ReadOnly = true; + this.textBox_HiddenFilterMask.Size = new System.Drawing.Size(302, 20); + this.textBox_HiddenFilterMask.TabIndex = 24; + // + // label_AccessFlags + // + this.label_AccessFlags.AutoSize = true; + this.label_AccessFlags.Location = new System.Drawing.Point(17, 12); + this.label_AccessFlags.Name = "label_AccessFlags"; + this.label_AccessFlags.Size = new System.Drawing.Size(139, 13); + this.label_AccessFlags.TabIndex = 12; + this.label_AccessFlags.Text = "The file access control flags"; + // + // textBox_FileAccessFlags + // + this.textBox_FileAccessFlags.Location = new System.Drawing.Point(221, 9); + this.textBox_FileAccessFlags.Name = "textBox_FileAccessFlags"; + this.textBox_FileAccessFlags.Size = new System.Drawing.Size(242, 20); + this.textBox_FileAccessFlags.TabIndex = 11; + this.textBox_FileAccessFlags.Text = "0"; + // + // button_FileAccessFlags + // + this.button_FileAccessFlags.Location = new System.Drawing.Point(482, 9); + this.button_FileAccessFlags.Name = "button_FileAccessFlags"; + this.button_FileAccessFlags.Size = new System.Drawing.Size(41, 20); + this.button_FileAccessFlags.TabIndex = 14; + this.button_FileAccessFlags.Text = "..."; + this.button_FileAccessFlags.UseVisualStyleBackColor = true; + this.button_FileAccessFlags.Click += new System.EventHandler(this.button_FileAccessFlags_Click); + // + // textBox_EncryptWriteBufferSize + // + this.textBox_EncryptWriteBufferSize.Location = new System.Drawing.Point(212, 164); + this.textBox_EncryptWriteBufferSize.Name = "textBox_EncryptWriteBufferSize"; + this.textBox_EncryptWriteBufferSize.Size = new System.Drawing.Size(302, 20); + this.textBox_EncryptWriteBufferSize.TabIndex = 127; + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(12, 164); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(166, 13); + this.label2.TabIndex = 135; + this.label2.Text = "Encryption write buffer cache size"; + // + // button_EncryptWriteBufferSize + // + this.button_EncryptWriteBufferSize.Image = global::EaseFilter.CommonObjects.Properties.Resources.about; + this.button_EncryptWriteBufferSize.Location = new System.Drawing.Point(521, 164); + this.button_EncryptWriteBufferSize.Name = "button_EncryptWriteBufferSize"; + this.button_EncryptWriteBufferSize.Size = new System.Drawing.Size(28, 20); + this.button_EncryptWriteBufferSize.TabIndex = 136; + this.button_EncryptWriteBufferSize.UseVisualStyleBackColor = true; + this.button_EncryptWriteBufferSize.Click += new System.EventHandler(this.button_EncryptWriteBufferSize_Click); + // + // ControlFilterRuleSettigs + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(573, 660); + this.Controls.Add(this.groupBox1); + this.Margin = new System.Windows.Forms.Padding(2); + this.Name = "ControlFilterRuleSettigs"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "Access Control Settings of The Filter Rule"; + this.groupBox1.ResumeLayout(false); + this.groupBox_AccessControl.ResumeLayout(false); + this.groupBox_AccessControl.PerformLayout(); + this.groupBox4.ResumeLayout(false); + this.groupBox4.PerformLayout(); + this.groupBox3.ResumeLayout(false); + this.groupBox3.PerformLayout(); + this.groupBox2.ResumeLayout(false); + this.groupBox2.PerformLayout(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.GroupBox groupBox1; + private System.Windows.Forms.GroupBox groupBox_AccessControl; + private System.Windows.Forms.TextBox textBox_ReparseFileFilterMask; + private System.Windows.Forms.Label label23; + private System.Windows.Forms.TextBox textBox_UserRights; + private System.Windows.Forms.Button button_AddUserRights; + private System.Windows.Forms.Label label22; + private System.Windows.Forms.TextBox textBox_ProcessRights; + private System.Windows.Forms.Button button_AddProcessRights; + private System.Windows.Forms.GroupBox groupBox2; + private System.Windows.Forms.CheckBox checkBox_AllowSetSecurity; + private System.Windows.Forms.CheckBox checkBox_AllowFileWriting; + private System.Windows.Forms.CheckBox checkBox_EnableProtectionInBootTime; + private System.Windows.Forms.CheckBox checkBox_AllowChange; + private System.Windows.Forms.CheckBox checkBox_AllowDelete; + private System.Windows.Forms.CheckBox checkBox_AllowRename; + private System.Windows.Forms.CheckBox checkBox_AllowRemoteAccess; + private System.Windows.Forms.CheckBox checkBox_AllowNewFileCreation; + private System.Windows.Forms.Button button_RegisterControlIO; + private System.Windows.Forms.TextBox textBox_ControlIO; + private System.Windows.Forms.Label label17; + private System.Windows.Forms.TextBox textBox_HiddenFilterMask; + private System.Windows.Forms.Label label_AccessFlags; + private System.Windows.Forms.TextBox textBox_FileAccessFlags; + private System.Windows.Forms.Button button_FileAccessFlags; + private System.Windows.Forms.TextBox textBox_PassPhrase; + private System.Windows.Forms.CheckBox checkBox_Encryption; + private System.Windows.Forms.Button button_SaveControlSettings; + private System.Windows.Forms.CheckBox checkBox_AllowEncryptNewFile; + private System.Windows.Forms.CheckBox checkBox_AllowCopyOut; + private System.Windows.Forms.CheckBox checkBox_AllowReadEncryptedFiles; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.TextBox textBox_ProcessIdRights; + private System.Windows.Forms.Button button_AddProcessIdRights; + private System.Windows.Forms.CheckBox checkBox_EnableReparseFile; + private System.Windows.Forms.CheckBox checkBox_EnableHidenFile; + private System.Windows.Forms.GroupBox groupBox4; + private System.Windows.Forms.GroupBox groupBox3; + private System.Windows.Forms.RadioButton radioButton_EncryptFileWithTagData; + private System.Windows.Forms.RadioButton radioButton_EncryptFileWithSameKey; + private System.Windows.Forms.Button button_InfoControlFlag; + private System.Windows.Forms.Button button_InfoControlEvents; + private System.Windows.Forms.Button button_InfoProcessNameRights; + private System.Windows.Forms.Button button_InfoProcessIdRights; + private System.Windows.Forms.Button button_InfoUserRights; + private System.Windows.Forms.Button button_InfoEncryptKeyLenght; + private System.Windows.Forms.Button button_InfoEncryptNewFile; + private System.Windows.Forms.Button button_InfoCopyout; + private System.Windows.Forms.Button button_InfoDecryption; + private System.Windows.Forms.Button button_InfoEncryptOnRead; + private System.Windows.Forms.Button button_InfoPassPhrase; + private System.Windows.Forms.Button button_HideFileFilterMask; + private System.Windows.Forms.Button button_InfoReparseFile; + private System.Windows.Forms.CheckBox checkBox_EnableSendDeniedEvent; + private System.Windows.Forms.Button button_InfoTrustedProcessRights; + private System.Windows.Forms.Button button_AddTrustedProcessRights; + private System.Windows.Forms.TextBox textBox_Sha256ProcessAccessRights; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.Button button_InfoSignedProcessRights; + private System.Windows.Forms.Button button_AddSignedProcessAccessRights; + private System.Windows.Forms.TextBox textBox_SignedProcessAccessRights; + private System.Windows.Forms.Label label4; + private System.Windows.Forms.Button button_EncryptWriteBufferSize; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.TextBox textBox_EncryptWriteBufferSize; + } +} \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/CommonObjects/ControlFilterRuleSettigs.cs b/Demo_Source_Code/CSharpDemo/CommonObjects/ControlFilterRuleSettigs.cs new file mode 100644 index 0000000..8603f9b --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/CommonObjects/ControlFilterRuleSettigs.cs @@ -0,0 +1,687 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +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; + +using EaseFilter.FilterControl; + +namespace EaseFilter.CommonObjects +{ + public partial class ControlFilterRuleSettigs : Form + { + public FileFilterRule filterRule = new FileFilterRule(); + + public ControlFilterRuleSettigs() + { + } + + public ControlFilterRuleSettigs(FileFilterRule _filterRule) + { + InitializeComponent(); + filterRule = _filterRule; + + textBox_FileAccessFlags.Text = filterRule.AccessFlag.ToString(); + textBox_ControlIO.Text = filterRule.RegisterControlFileIOEvents.ToString(); + checkBox_EnableProtectionInBootTime.Checked = filterRule.IsResident; + textBox_ProcessRights.Text = filterRule.ProcessNameRights; + textBox_ProcessIdRights.Text = filterRule.ProcessIdRights; + textBox_SignedProcessAccessRights.Text = filterRule.SignedProcessAccessRights; + textBox_UserRights.Text = filterRule.UserRights; + + textBox_PassPhrase.Text = filterRule.EncryptionPassPhrase; + textBox_HiddenFilterMask.Text = filterRule.HiddenFileFilterMasks; + textBox_ReparseFileFilterMask.Text = filterRule.ReparseFileFilterMask; + textBox_EncryptWriteBufferSize.Text = filterRule.EncryptWriteBufferSize.ToString(); + + SetCheckBoxValue(); + + if (filterRule.EncryptMethod == (int)FilterAPI.EncryptionMethod.ENCRYPT_FILE_WITH_SAME_KEY_AND_UNIQUE_IV ) + { + radioButton_EncryptFileWithSameKey.Checked = true; + radioButton_EncryptFileWithTagData.Checked = false; + } + else + { + radioButton_EncryptFileWithSameKey.Checked = false; + radioButton_EncryptFileWithTagData.Checked = true; + } + } + + private void SetCheckBoxValue() + { + + uint accessFlags = uint.Parse(textBox_FileAccessFlags.Text); + + if ((accessFlags & (uint)FilterAPI.AccessFlag.ENABLE_FILE_ENCRYPTION_RULE) > 0 ) + { + checkBox_Encryption.Checked = true; + textBox_PassPhrase.ReadOnly = false; + } + else + { + checkBox_Encryption.Checked = false; + textBox_PassPhrase.ReadOnly = true; + } + + if ((accessFlags & (uint)FilterAPI.AccessFlag.ENABLE_HIDE_FILES_IN_DIRECTORY_BROWSING) > 0) + { + checkBox_EnableHidenFile.Checked = true; + textBox_HiddenFilterMask.ReadOnly = false; + } + else + { + checkBox_EnableHidenFile.Checked = false; + textBox_HiddenFilterMask.ReadOnly = true; + } + + if ((accessFlags & (uint)FilterAPI.AccessFlag.ENABLE_REPARSE_FILE_OPEN) > 0) + { + checkBox_EnableReparseFile.Checked = true; + textBox_ReparseFileFilterMask.ReadOnly = false; + } + else + { + checkBox_EnableReparseFile.Checked = false; + textBox_ReparseFileFilterMask.ReadOnly = true; + } + + if ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_FILE_ACCESS_FROM_NETWORK) > 0) + { + checkBox_AllowRemoteAccess.Checked = true; + } + else + { + checkBox_AllowRemoteAccess.Checked = false; + } + + if ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_FILE_DELETE) > 0) + { + checkBox_AllowDelete.Checked = true; + } + else + { + checkBox_AllowDelete.Checked = false; + } + + if ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_FILE_RENAME) > 0) + { + checkBox_AllowRename.Checked = true; + } + else + { + checkBox_AllowRename.Checked = false; + } + + if ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_WRITE_ACCESS) > 0) + { + checkBox_AllowFileWriting.Checked = true; + } + else + { + checkBox_AllowFileWriting.Checked = false; + } + + if ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_SET_INFORMATION) > 0) + { + checkBox_AllowChange.Checked = true; + } + else + { + checkBox_AllowChange.Checked = false; + } + + if ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_OPEN_WITH_CREATE_OR_OVERWRITE_ACCESS) > 0) + { + checkBox_AllowNewFileCreation.Checked = true; + } + else + { + checkBox_AllowNewFileCreation.Checked = false; + } + + + if ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_SET_SECURITY_ACCESS) > 0) + { + checkBox_AllowSetSecurity.Checked = true; + } + else + { + checkBox_AllowSetSecurity.Checked = false; + } + + + if ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_ENCRYPT_NEW_FILE) > 0) + { + checkBox_AllowEncryptNewFile.Checked = true; + } + else + { + checkBox_AllowEncryptNewFile.Checked = false; + } + + if ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_COPY_PROTECTED_FILES_OUT) > 0) + { + checkBox_AllowCopyOut.Checked = true; + } + else + { + checkBox_AllowCopyOut.Checked = false; + } + + if ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_READ_ENCRYPTED_FILES) > 0) + { + checkBox_AllowReadEncryptedFiles.Checked = true; + } + else + { + checkBox_AllowReadEncryptedFiles.Checked = false; + } + + if (GlobalConfig.EnableSendDeniedEvent) + { + checkBox_EnableSendDeniedEvent.Checked = true; + } + else + { + checkBox_EnableSendDeniedEvent.Checked = false; + } + } + + private void button_SaveControlSettings_Click(object sender, EventArgs e) + { + string encryptionPassPhrase = string.Empty; + uint accessFlags = uint.Parse(textBox_FileAccessFlags.Text); + + if (checkBox_Encryption.Checked) + { + encryptionPassPhrase = textBox_PassPhrase.Text; + + //enable encryption for this filter rule. + accessFlags = accessFlags | (uint)FilterAPI.AccessFlag.ENABLE_FILE_ENCRYPTION_RULE; + + if (radioButton_EncryptFileWithSameKey.Checked) + { + filterRule.EncryptMethod = (int)FilterAPI.EncryptionMethod.ENCRYPT_FILE_WITH_SAME_KEY_AND_UNIQUE_IV; + } + else + { + filterRule.EncryptMethod = (int)FilterAPI.EncryptionMethod.ENCRYPT_FILE_WITH_KEY_IV_AND_TAGDATA_FROM_SERVICE; + } + + filterRule.EncryptWriteBufferSize = uint.Parse(textBox_EncryptWriteBufferSize.Text); + } + + if (textBox_HiddenFilterMask.Text.Trim().Length > 0) + { + //enable hidden filter mask for this filter rule. + accessFlags = accessFlags | (uint)FilterAPI.AccessFlag.ENABLE_HIDE_FILES_IN_DIRECTORY_BROWSING; + } + + if (checkBox_EnableSendDeniedEvent.Checked) + { + GlobalConfig.EnableSendDeniedEvent = true; + } + else + { + GlobalConfig.EnableSendDeniedEvent = false; + } + + filterRule.EncryptionPassPhrase = encryptionPassPhrase; + filterRule.HiddenFileFilterMasks = textBox_HiddenFilterMask.Text; + filterRule.ReparseFileFilterMask = textBox_ReparseFileFilterMask.Text; + filterRule.AccessFlag = accessFlags; + filterRule.RegisterControlFileIOEvents = ulong.Parse(textBox_ControlIO.Text); + filterRule.IsResident = checkBox_EnableProtectionInBootTime.Checked; + filterRule.UserRights = textBox_UserRights.Text; + filterRule.ProcessNameRights = textBox_ProcessRights.Text; + filterRule.Sha256ProcessAccessRights = textBox_Sha256ProcessAccessRights.Text; + filterRule.SignedProcessAccessRights = textBox_SignedProcessAccessRights.Text; + filterRule.ProcessIdRights = textBox_ProcessIdRights.Text; + + } + + + private void button_FileAccessFlags_Click(object sender, EventArgs e) + { + OptionForm optionForm = new OptionForm(OptionForm.OptionType.Access_Flag, textBox_FileAccessFlags.Text); + + if (optionForm.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + if (optionForm.AccessFlags > 0) + { + textBox_FileAccessFlags.Text = optionForm.AccessFlags.ToString(); + } + else + { + //if the accessFlag is 0, it is exclude filter rule,this is not what we want, so we need to include this flag. + textBox_FileAccessFlags.Text = ((uint)FilterAPI.AccessFlag.LEAST_ACCESS_FLAG).ToString(); + } + + SetCheckBoxValue(); + } + } + + + private void button_RegisterControlIO_Click(object sender, EventArgs e) + { + OptionForm optionForm = new OptionForm(OptionForm.OptionType.ControlFileIOEvents, textBox_ControlIO.Text); + + if (optionForm.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + textBox_ControlIO.Text = optionForm.ControlIOEvents.ToString(); + } + } + + private void button_AddProcessRights_Click(object sender, EventArgs e) + { + Form_AccessRights accessRightsForm = new Form_AccessRights(Form_AccessRights.AccessRightType.ProcessNameRight); + + if (accessRightsForm.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + if (textBox_ProcessRights.Text.Trim().Length > 0) + { + textBox_ProcessRights.Text += ";" + accessRightsForm.accessRightText; + } + else + { + textBox_ProcessRights.Text = accessRightsForm.accessRightText; + } + } + } + + private void button_AddSha256ProcessAccessRights_Click(object sender, EventArgs e) + { + Form_AccessRights accessRightsForm = new Form_AccessRights(Form_AccessRights.AccessRightType.Sha256Process); + + if (accessRightsForm.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + if (textBox_ProcessRights.Text.Trim().Length > 0) + { + textBox_Sha256ProcessAccessRights.Text += ";" + accessRightsForm.accessRightText; + } + else + { + textBox_Sha256ProcessAccessRights.Text = accessRightsForm.accessRightText; + } + } + } + + private void button_AddSignedProcessAccessRights_Click(object sender, EventArgs e) + { + Form_AccessRights accessRightsForm = new Form_AccessRights(Form_AccessRights.AccessRightType.SignedProcess); + + if (accessRightsForm.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + if (textBox_ProcessRights.Text.Trim().Length > 0) + { + textBox_SignedProcessAccessRights.Text += ";" + accessRightsForm.accessRightText; + } + else + { + textBox_SignedProcessAccessRights.Text = accessRightsForm.accessRightText; + } + } + } + + + private void button_AddProcessIdRights_Click(object sender, EventArgs e) + { + Form_AccessRights accessRightsForm = new Form_AccessRights(Form_AccessRights.AccessRightType.ProccessIdRight); + + if (accessRightsForm.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + if (textBox_ProcessIdRights.Text.Trim().Length > 0) + { + textBox_ProcessIdRights.Text += ";" + accessRightsForm.accessRightText; + } + else + { + textBox_ProcessIdRights.Text = accessRightsForm.accessRightText; + } + } + + } + + + private void button_AddUserRights_Click(object sender, EventArgs e) + { + Form_AccessRights accessRightsForm = new Form_AccessRights(Form_AccessRights.AccessRightType.UserNameRight); + + if (accessRightsForm.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + if (textBox_UserRights.Text.Trim().Length > 0) + { + textBox_UserRights.Text += ";" + accessRightsForm.accessRightText; + } + else + { + textBox_UserRights.Text = accessRightsForm.accessRightText; + } + } + } + + + private void checkBox_Encryption_CheckedChanged(object sender, EventArgs e) + { + uint accessFlags = uint.Parse(textBox_FileAccessFlags.Text); + + if (checkBox_Encryption.Checked) + { + textBox_PassPhrase.ReadOnly = false; + accessFlags = accessFlags | ((uint)FilterAPI.AccessFlag.ENABLE_FILE_ENCRYPTION_RULE); + } + else + { + textBox_PassPhrase.ReadOnly = true; + accessFlags = accessFlags & ((uint)~FilterAPI.AccessFlag.ENABLE_FILE_ENCRYPTION_RULE); + } + + textBox_FileAccessFlags.Text = accessFlags.ToString(); + } + + private void checkBox_AllowDelete_CheckedChanged(object sender, EventArgs e) + { + + uint accessFlags = uint.Parse(textBox_FileAccessFlags.Text); + + if (!checkBox_AllowDelete.Checked) + { + accessFlags = accessFlags & ((uint)~FilterAPI.AccessFlag.ALLOW_FILE_DELETE); + } + else + { + accessFlags = accessFlags | ((uint)FilterAPI.AccessFlag.ALLOW_FILE_DELETE); + } + + textBox_FileAccessFlags.Text = accessFlags.ToString(); + } + + private void checkBox_AllowChange_CheckedChanged(object sender, EventArgs e) + { + uint accessFlags = uint.Parse(textBox_FileAccessFlags.Text); + if (!checkBox_AllowChange.Checked) + { + accessFlags = accessFlags & ((uint)~FilterAPI.AccessFlag.ALLOW_SET_INFORMATION); + } + else + { + accessFlags = accessFlags | ((uint)FilterAPI.AccessFlag.ALLOW_SET_INFORMATION); + } + + textBox_FileAccessFlags.Text = accessFlags.ToString(); + } + + private void checkBox_AllowRename_CheckedChanged(object sender, EventArgs e) + { + uint accessFlags = uint.Parse(textBox_FileAccessFlags.Text); + + if (!checkBox_AllowRename.Checked) + { + accessFlags = accessFlags & ((uint)~FilterAPI.AccessFlag.ALLOW_FILE_RENAME); + } + else + { + accessFlags = accessFlags | ((uint)FilterAPI.AccessFlag.ALLOW_FILE_RENAME); + } + + textBox_FileAccessFlags.Text = accessFlags.ToString(); + } + + private void checkBox_AllowRemoteAccess_CheckedChanged(object sender, EventArgs e) + { + uint accessFlags = uint.Parse(textBox_FileAccessFlags.Text); + + if (!checkBox_AllowRemoteAccess.Checked) + { + accessFlags = accessFlags & ((uint)~FilterAPI.AccessFlag.ALLOW_FILE_ACCESS_FROM_NETWORK); + } + else + { + accessFlags = accessFlags | ((uint)FilterAPI.AccessFlag.ALLOW_FILE_ACCESS_FROM_NETWORK); + } + + textBox_FileAccessFlags.Text = accessFlags.ToString(); + } + + private void checkBox_AllowNewFileCreation_CheckedChanged(object sender, EventArgs e) + { + uint accessFlags = uint.Parse(textBox_FileAccessFlags.Text); + + if (!checkBox_AllowNewFileCreation.Checked) + { + accessFlags = accessFlags & ((uint)~FilterAPI.AccessFlag.ALLOW_OPEN_WITH_CREATE_OR_OVERWRITE_ACCESS); + } + else + { + accessFlags = accessFlags | ((uint)FilterAPI.AccessFlag.ALLOW_OPEN_WITH_CREATE_OR_OVERWRITE_ACCESS); + } + + textBox_FileAccessFlags.Text = accessFlags.ToString(); + } + + private void checkBox_AllowFileWriting_CheckedChanged(object sender, EventArgs e) + { + uint accessFlags = uint.Parse(textBox_FileAccessFlags.Text); + + if (!checkBox_AllowFileWriting.Checked) + { + accessFlags = accessFlags & ((uint)~FilterAPI.AccessFlag.ALLOW_WRITE_ACCESS); + } + else + { + accessFlags = accessFlags | ((uint)FilterAPI.AccessFlag.ALLOW_WRITE_ACCESS); + } + + textBox_FileAccessFlags.Text = accessFlags.ToString(); + } + + private void checkBox_AllowSetSecurity_CheckedChanged(object sender, EventArgs e) + { + uint accessFlags = uint.Parse(textBox_FileAccessFlags.Text); + + if (!checkBox_AllowSetSecurity.Checked) + { + accessFlags = accessFlags & ((uint)~FilterAPI.AccessFlag.ALLOW_SET_SECURITY_ACCESS); + } + else + { + accessFlags = accessFlags | ((uint)FilterAPI.AccessFlag.ALLOW_SET_SECURITY_ACCESS); + } + + textBox_FileAccessFlags.Text = accessFlags.ToString(); + } + + + private void checkBox_AllowEncryptNewFile_CheckedChanged(object sender, EventArgs e) + { + uint accessFlags = uint.Parse(textBox_FileAccessFlags.Text); + + if (!checkBox_AllowEncryptNewFile.Checked) + { + accessFlags = accessFlags & ((uint)~FilterAPI.AccessFlag.ALLOW_ENCRYPT_NEW_FILE); + } + else + { + accessFlags = accessFlags | ((uint)FilterAPI.AccessFlag.ALLOW_ENCRYPT_NEW_FILE); + } + + textBox_FileAccessFlags.Text = accessFlags.ToString(); + } + + private void checkBox_AllowCopyOut_CheckedChanged(object sender, EventArgs e) + { + uint accessFlags = uint.Parse(textBox_FileAccessFlags.Text); + + if (!checkBox_AllowCopyOut.Checked) + { + accessFlags = accessFlags & ((uint)~FilterAPI.AccessFlag.ALLOW_COPY_PROTECTED_FILES_OUT); + } + else + { + accessFlags = accessFlags | ((uint)FilterAPI.AccessFlag.ALLOW_COPY_PROTECTED_FILES_OUT); + } + + textBox_FileAccessFlags.Text = accessFlags.ToString(); + } + + private void checkBox_AllowReadEncryptedFiles_CheckedChanged(object sender, EventArgs e) + { + uint accessFlags = uint.Parse(textBox_FileAccessFlags.Text.Trim()); + if (checkBox_AllowReadEncryptedFiles.Checked) + { + accessFlags |= (uint)FilterAPI.AccessFlag.ALLOW_READ_ENCRYPTED_FILES; + } + else + { + accessFlags &= ~(uint)FilterAPI.AccessFlag.ALLOW_READ_ENCRYPTED_FILES; + } + + textBox_FileAccessFlags.Text = accessFlags.ToString(); + } + + + private void checkBox_EnableHidenFile_CheckedChanged(object sender, EventArgs e) + { + uint accessFlags = uint.Parse(textBox_FileAccessFlags.Text); + + if (checkBox_EnableHidenFile.Checked) + { + textBox_HiddenFilterMask.ReadOnly = false; + accessFlags = accessFlags | ((uint)FilterAPI.AccessFlag.ENABLE_HIDE_FILES_IN_DIRECTORY_BROWSING); + } + else + { + textBox_HiddenFilterMask.ReadOnly = true; + accessFlags = accessFlags & ((uint)~FilterAPI.AccessFlag.ENABLE_HIDE_FILES_IN_DIRECTORY_BROWSING); + } + + textBox_FileAccessFlags.Text = accessFlags.ToString(); + } + + private void checkBox_EnableReparseFile_CheckedChanged(object sender, EventArgs e) + { + uint accessFlags = uint.Parse(textBox_FileAccessFlags.Text); + + if (checkBox_EnableReparseFile.Checked) + { + textBox_ReparseFileFilterMask.ReadOnly = false; + accessFlags = accessFlags | ((uint)FilterAPI.AccessFlag.ENABLE_REPARSE_FILE_OPEN); + } + else + { + textBox_ReparseFileFilterMask.ReadOnly = true; + accessFlags = accessFlags & ((uint)~FilterAPI.AccessFlag.ENABLE_REPARSE_FILE_OPEN); + } + + textBox_FileAccessFlags.Text = accessFlags.ToString(); + } + + + private void button_InfoControlFlag_Click(object sender, EventArgs e) + { + MessageBox.Show("This is the file access control flags of the filter rule, enable or disable the specific access right by checking or unchecking the selected box."); + } + + private void button_InfoCopyout_Click(object sender, EventArgs e) + { + MessageBox.Show("Prevent the files from being copied out of the folder when it was disabled."); + } + + private void button_InfoEncryptNewFile_Click(object sender, EventArgs e) + { + MessageBox.Show("Automatically encrypt the new created file when it was enabled, or it won't encrypt the new created file, a use case: copy the encrypted file to the folder, it won't encrypt the file again."); + } + + private void button_InfoDecryption_Click(object sender, EventArgs e) + { + MessageBox.Show("Automatically decrypt the created file when it was enabled, or the process will read the raw data of the encrypted file, a use case: the backup software."); + } + + private void button_InfoEncryptOnRead_Click(object sender, EventArgs e) + { + MessageBox.Show("If you want to encrypt the file only when it was read by the process, you can enable the encryption feature, disable the new file encryption, enable the encryption on the go."); + } + + private void button_InfoPassPhrase_Click(object sender, EventArgs e) + { + MessageBox.Show("Enable the encryption feature and set the encryption key phrase for generating the encryption key."); + } + + private void button_EnableEncryptionKeyFromService_Click(object sender, EventArgs e) + { + MessageBox.Show("If this is enabled, all encryption/decryption will get the encryption key from the callback service, you also can embed the custom tag data to the new created encrypted file."); + } + + private void button_HideFileFilterMask_Click(object sender, EventArgs e) + { + MessageBox.Show("Enable the hiden file feature, hide the file when the file name matches the filter mask, seperate the multiple filter mask with ';' character. i.e. *.txt;*.exe, this will hide .txt and .exe files"); + } + + private void button_InfoReparseFile_Click(object sender, EventArgs e) + { + string info = "Enable the reparse file feature,reparse the file open to the new file which the file name will be replaced with the reparse filter mask.\r\n\r\n"; + info += "i.e. FilterMask = c:\\test\\*txt, ReparseFilterMask = d:\\reparse\\*doc, If you open file c:\\test\\MyTest.txt, it will reparse to the file d:\\reparse\\MyTest.doc."; + + MessageBox.Show(info); + } + + private void button_InfoProcessNameRights_Click(object sender, EventArgs e) + { + MessageBox.Show("Add or remove the file access right of the process via the process name."); + } + + private void button_InfoSha256ProcessRights_Click(object sender, EventArgs e) + { + MessageBox.Show("Add the trusted process with the sha256 hash of the executable binary to filter rule, only the process has the same sha256 hash can access the files. "); + } + + private void button_InfoProcessIdRights_Click(object sender, EventArgs e) + { + MessageBox.Show("Add or remove the file access right of the process via the process Id."); + } + + private void button_InfoUserRights_Click(object sender, EventArgs e) + { + MessageBox.Show("Add or remove the file access right of the user via the user name."); + } + + private void button_InfoControlEvents_Click(object sender, EventArgs e) + { + MessageBox.Show("Register the control events, you can allow, modify or deny the file I/O."); + } + + private void button_InfoSignedProcessRights_Click(object sender, EventArgs e) + { + MessageBox.Show("Add the trusted process which was signed with the certificate to filter rule, only the authenticated process can access the files. "); + } + + private void button_EncryptWriteBufferSize_Click(object sender, EventArgs e) + { + MessageBox.Show("If the encrypt write buffer size is greater than 0, then the small buffer encryption write will be combined together to a bigger buffer, and write it to the disk."); + } + + + + } +} diff --git a/Demo_Source_Code/CSharpDemo/CommonObjects/ControlFilterRuleSettigs.resx b/Demo_Source_Code/CSharpDemo/CommonObjects/ControlFilterRuleSettigs.resx new file mode 100644 index 0000000..0284069 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/CommonObjects/ControlFilterRuleSettigs.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 25 + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/CommonObjects/DigitalRightControl.cs b/Demo_Source_Code/CSharpDemo/CommonObjects/DigitalRightControl.cs new file mode 100644 index 0000000..813ac04 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/CommonObjects/DigitalRightControl.cs @@ -0,0 +1,470 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.Text; +using System.IO; +using System.Collections; +using System.Collections.Generic; +using Microsoft.Win32.SafeHandles; +using System.Runtime.InteropServices; +using System.Security.Principal; +using System.Security.Cryptography; +using System.Xml.Serialization; + +namespace EaseFilter.CommonObjects +{ + public enum AESFlags : uint + { + Flags_Enabled_Expire_Time = 0x00000010, + Flags_Enabled_Check_ProcessName = 0x00000020, + Flags_Enabled_Check_UserName = 0x00000040, + Flags_Enabled_Check_AccessFlags = 0x00000080, + Flags_Enabled_Check_User_Permit = 0x00000100, + Flags_AES_Key_Was_Embedded = 0x00000200, + Flags_Request_AccessFlags_From_User = 0x00000400, + Flags_Request_IV_And_Key_From_User = 0x00000800, + Flags_Enabled_Check_Computer_Id = 0x00001000, + Flags_Enabled_Check_User_Password = 0x00002000, + + } + + /// + /// this is the return data structure for encryption to filter driver. + /// when the filter command is FILTER_REQUEST_ENCRYPTION_IV_AND_KEY, + /// FILTER_REQUEST_ENCRYPTION_IV_AND_KEY_AND_ACCESSFLAG or FILTER_REQUEST_ENCRYPTION_IV_AND_KEY_AND_TAGDATA + /// + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + public struct AESDataBuffer + { + public uint AccessFlags; + public uint IVLength; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] + public byte[] IV; + public uint EncryptionKeyLength; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] + public byte[] EncryptionKey; + public uint TagDataLength; + public byte[] TagData; + } + + /// + /// This is the DR info meta data which will be stored in server if revoke access control is enabled. + /// + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + public class DRPolicy + { + /// + /// If it is not empty, only the processes in the process list can access the files. + /// + public string AuthorizedProcessNames; + /// + /// If it is not empty, all the processes in the process list can not access the files. + /// + public string UnauthorizedProcessNames; + /// + /// If it is not empty, only the users in the user name list can access the files. + /// + public string AuthorizedUserNames; + /// + /// If it is not empty, all the useres in the user name list can not access the files. + /// + public string UnauthorizedUserNames; + /// + /// If it is not empty, only the computer in the computer id list can access the files. + /// + public string AuthorizedComputerIds; + /// + /// the password of the shared file. + /// + public string UserPassword; + /// + /// the access flags of the shared file. + /// + public uint AccessFlags; + /// + /// The file will be expired after the expire time in UTC format, and it can't be accessed. + /// + public long ExpireTime; + /// + /// The time in UTC format of the encrypted file was created. + /// + public long CreationTime; + /// + /// the file name which was applied with policy. + /// + public string FileName; + /// + /// The encryption key hex string. + /// + public string EncryptionKey; + /// + /// the iv hex string. + /// + public string EncryptionIV; + } + + + /// + /// This the DR data which will be embedded to the encyrpted file + /// + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + public struct DRPolicyData + { + + public uint AESVerificationKey; + public AESFlags AESFlags; + public uint IVLength; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] + public byte[] IV; + public uint EncryptionKeyLength; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] + public byte[] EncryptionKey; + public long CreationTime; + public long ExpireTime; + public uint AccessFlags; + public long FileSize; + public uint LengthOfAuthorizedProcessNames; + public uint LengthOfUnauthorizedProcessNames; + public uint LengthOfAuthorizedUserNames; + public uint LengthOfUnauthorizedUserNames; + public uint LengthOfAccountName; + public uint LengthOfComputerIds; + public uint LengthOfUserPassword; + public string AuthorizedProcessNames; + public string UnauthorizedProcessNames; + public string AuthorizedUserNames; + public string UnauthorizedUserNames; + public string AccountName; + public string ComputerIds; + public string UserPassword; + public uint SizeOfAESData; + + } + + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + public struct UserInfo + { + /// + /// the owner account name + /// + public string AccountName; + /// + /// the password of the account + /// + public string AccountPassword; + /// + /// the process name which access the file. + /// + public string ProcessName; + /// + /// the user name who access the file. + /// + public string UserName; + /// + /// the computer information which access the file. + /// + public string ComputerId; + /// + /// the encrypted file which was accessed. + /// + public string FileName; + /// + /// the creation time of the file which was accessed. + /// + public long CreationTime; + /// + /// the password of the user input. + /// + public string UserPassword; + /// the encryption iv hex string; + /// + public string EncryptionIV; + } + + + public class DigitalRightControl + { + public const uint AES_VERIFICATION_KEY = 0xccb76e80; + public static string PassPhrase = "PassPhrase"; + + private static byte[] ConvertDRPolicyDataToByteArray(DRPolicyData policy) + { + MemoryStream ms = new MemoryStream(); + BinaryWriter bw = new BinaryWriter(ms); + bw.Write(AES_VERIFICATION_KEY); + bw.Write((uint)(policy.AESFlags)); + bw.Write(policy.IVLength); + bw.Write(policy.IV); + bw.Write(policy.EncryptionKeyLength); + bw.Write(policy.EncryptionKey); + bw.Write(policy.CreationTime); + bw.Write(policy.ExpireTime); + bw.Write((uint)policy.AccessFlags); + bw.Write(policy.FileSize); + bw.Write(policy.LengthOfAuthorizedProcessNames); + bw.Write(policy.LengthOfUnauthorizedProcessNames); + bw.Write(policy.LengthOfAuthorizedUserNames); + bw.Write(policy.LengthOfUnauthorizedUserNames); + bw.Write(policy.LengthOfAccountName); + bw.Write(policy.LengthOfComputerIds); + bw.Write(policy.LengthOfUserPassword); + + byte[] strBuffer; + if (policy.LengthOfAuthorizedProcessNames > 0) + { + strBuffer = UnicodeEncoding.Unicode.GetBytes(policy.AuthorizedProcessNames); + bw.Write(strBuffer); + } + + if (policy.LengthOfUnauthorizedProcessNames > 0) + { + strBuffer = UnicodeEncoding.Unicode.GetBytes(policy.UnauthorizedProcessNames); + bw.Write(strBuffer); + } + + if (policy.LengthOfAuthorizedUserNames > 0) + { + strBuffer = UnicodeEncoding.Unicode.GetBytes(policy.AuthorizedUserNames); + bw.Write(strBuffer); + } + + if (policy.LengthOfUnauthorizedUserNames > 0) + { + strBuffer = UnicodeEncoding.Unicode.GetBytes(policy.UnauthorizedUserNames); + bw.Write(strBuffer); + } + + if (policy.LengthOfAccountName > 0) + { + strBuffer = UnicodeEncoding.Unicode.GetBytes(policy.AccountName); + bw.Write(strBuffer); + } + + if (policy.LengthOfComputerIds > 0) + { + strBuffer = UnicodeEncoding.Unicode.GetBytes(policy.ComputerIds); + bw.Write(strBuffer); + } + + if (policy.LengthOfUserPassword > 0) + { + strBuffer = UnicodeEncoding.Unicode.GetBytes(policy.UserPassword); + bw.Write(strBuffer); + } + + //append the sizeof the DR policy + int sizeofDRDataArray = (int)ms.Length + 4;// the size of sizeofDRDataArray takes 4 bytes memory as a int data + bw.Write(sizeofDRDataArray); + + byte[] AESBuffer = ms.ToArray(); + + return AESBuffer; + } + + /// + /// Create an encrypted file with embedded digital right policy, distribute the encrypted file via internet, + /// only the authorized users and processes can access the encrypted file. + /// + /// + /// + /// + /// + /// + public static bool EncryptFileWithEmbeddedDRPolicy(string sourceFileName, string destFileName, byte[] encryptIV, byte[] encryptKey,DRPolicyData policy, out string lastError) + { + bool ret = false; + FileStream fs = null; + lastError = string.Empty; + + try + { + if (!File.Exists(sourceFileName)) + { + lastError = sourceFileName + " doesn't exist."; + return false; + } + + byte[] AESBuffer = ConvertDRPolicyDataToByteArray(policy); + + //encrypt the file with encryption key and a iv key. + ret = FilterAPI.AESEncryptFileToFile(sourceFileName, destFileName, (uint)encryptKey.Length, encryptKey, (uint)encryptIV.Length, encryptIV, false); + if (!ret) + { + lastError = "Create encrypt file " + destFileName + " failed with error:" + FilterAPI.GetLastErrorMessage(); + return ret; + } + + fs = new FileStream(destFileName, FileMode.Append, FileAccess.Write, FileShare.Read); + + //append the DR policy to the encrypted file. + fs.Write(AESBuffer, 0, AESBuffer.Length); + + + } + catch (Exception ex) + { + ret = false; + lastError = "Encrypt file " + sourceFileName + " failed with error:" + ex.Message; + } + finally + { + if (null != fs) + { + fs.Close(); + } + } + + return ret; + } + + /// + /// Process the encrypted file's embedded access policy, remove embedded information, add AESTagData to encrypted file, + /// Create a filter driver aware encrypted file. Then you can read the encrypted file transparently via filter driver encryption engine. + /// + /// + /// + /// + /// + public static bool ProcessSecureShareFile(string fileName, out string lastError) + { + bool ret = false; + lastError = string.Empty; + + try + { + if (!File.Exists(fileName)) + { + lastError = fileName + " doesn't exist."; + return false; + } + + if (!fileName.EndsWith(GlobalConfig.ShareFileExt)) + { + lastError = fileName + " extension is not correct."; + return false; + } + + FileAttributes attributes = File.GetAttributes(fileName); + attributes = (~FileAttributes.ReadOnly) & attributes; + File.SetAttributes(fileName, attributes); + + FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.ReadWrite, FileShare.Read); + long fileSize = fs.Length; + + //read the last 4 bytes data, it is the total size of the embedded data. + + fs.Position = fileSize - 4; + BinaryReader br = new BinaryReader(fs); + uint sizeOfAESData = br.ReadUInt32(); + + if (sizeOfAESData >= fileSize) + { + lastError = fileName + " is not valid share encrypted file, the sizeOfAESData:" + sizeOfAESData + " >= file size:" + fileSize; + return false; + } + + fs.Position = fileSize - sizeOfAESData; + + //Read the embedded data + byte[] AESBuffer = new byte[sizeOfAESData]; + fs.Read(AESBuffer, 0, (int)sizeOfAESData); + + //since the last 4 bytes for sizeOfAESData is not encrypted, we need to put back the clear value back. + MemoryStream ms = new MemoryStream(AESBuffer); + ms.Position = 0; + br = new BinaryReader(ms); + uint verificationKey = br.ReadUInt32(); + + //verify if this is the valid embedded data. + if (verificationKey != AES_VERIFICATION_KEY) + { + lastError = fileName + " is not valid share encrypted file, the encryption key:" + verificationKey + " is not valid."; + return false; + } + + + //Remove the embedded data, this is the original file size without the embedded information. + fs.SetLength(fileSize - sizeOfAESData); + + fs.Close(); + fs = null; + + if (fileName.EndsWith(GlobalConfig.ShareFileExt)) + { + string newFileName = fileName.Remove(fileName.Length - GlobalConfig.ShareFileExt.Length); + File.Move(fileName, newFileName); + fileName = newFileName; + } + + //add the DR data to the encrypted file as a tag data. + ret = FilterAPI.EmbedDRPolicyDataToFile(fileName, AESBuffer, out lastError); + + } + catch (Exception ex) + { + ret = false; + lastError = "ProcessSecureShareFile " + fileName + " failed with error:" + ex.Message; + } + + + return ret; + } + + + public static T DecryptStrToObject( string toDeserialize) + { + string decryptedStr = FilterAPI.AESEncryptDecryptStr(toDeserialize, FilterAPI.EncryptType.Decryption); + + XmlSerializer xmlSerializer = new XmlSerializer(typeof(T)); + StringReader textReader = new StringReader(decryptedStr); + return (T)xmlSerializer.Deserialize(textReader); + } + + public static string EncryptObjectToStr( T toSerialize) + { + XmlSerializer xmlSerializer = new XmlSerializer(typeof(T)); + StringWriter textWriter = new StringWriter(); + xmlSerializer.Serialize(textWriter, toSerialize); + + string encryptedText = FilterAPI.AESEncryptDecryptStr(textWriter.ToString(), FilterAPI.EncryptType.Encryption); + + return encryptedText; + } + + public static byte[] ConvertAESDataToByteArray(AESDataBuffer aesData) + { + MemoryStream ms = new MemoryStream(); + BinaryWriter bw = new BinaryWriter(ms); + + bw.Write(aesData.AccessFlags); + bw.Write(aesData.IVLength); + bw.Write(aesData.IV); + bw.Write(aesData.EncryptionKeyLength); + bw.Write(aesData.EncryptionKey); + bw.Write(aesData.TagDataLength); + + if (aesData.TagDataLength > 0 && aesData.TagData != null) + { + bw.Write(aesData.TagData); + } + + return ms.ToArray(); + } + } +} diff --git a/Demo_Source_Code/CSharpDemo/CommonObjects/EventForm.Designer.cs b/Demo_Source_Code/CSharpDemo/CommonObjects/EventForm.Designer.cs new file mode 100644 index 0000000..b706189 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/CommonObjects/EventForm.Designer.cs @@ -0,0 +1,169 @@ +namespace EaseFilter.CommonObjects +{ + partial class EventForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(EventForm)); + this.menuStrip1 = new System.Windows.Forms.MenuStrip(); + this.messageToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.errorToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.warningToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.informationToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.verboseToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.traceToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.RefreshToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.clearToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.listView_EventView = new System.Windows.Forms.ListView(); + this.menuStrip1.SuspendLayout(); + this.SuspendLayout(); + // + // menuStrip1 + // + this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.messageToolStripMenuItem, + this.RefreshToolStripMenuItem, + this.clearToolStripMenuItem}); + this.menuStrip1.Location = new System.Drawing.Point(0, 0); + this.menuStrip1.Name = "menuStrip1"; + this.menuStrip1.Size = new System.Drawing.Size(1012, 24); + this.menuStrip1.TabIndex = 1; + this.menuStrip1.Text = "menuStrip1"; + // + // messageToolStripMenuItem + // + this.messageToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.errorToolStripMenuItem, + this.warningToolStripMenuItem, + this.informationToolStripMenuItem, + this.verboseToolStripMenuItem, + this.traceToolStripMenuItem}); + this.messageToolStripMenuItem.Name = "messageToolStripMenuItem"; + this.messageToolStripMenuItem.Size = new System.Drawing.Size(65, 20); + this.messageToolStripMenuItem.Text = "Message"; + // + // errorToolStripMenuItem + // + this.errorToolStripMenuItem.Checked = true; + this.errorToolStripMenuItem.CheckState = System.Windows.Forms.CheckState.Checked; + this.errorToolStripMenuItem.Name = "errorToolStripMenuItem"; + this.errorToolStripMenuItem.Size = new System.Drawing.Size(137, 22); + this.errorToolStripMenuItem.Text = "Error"; + this.errorToolStripMenuItem.Click += new System.EventHandler(this.errorToolStripMenuItem_Click); + // + // warningToolStripMenuItem + // + this.warningToolStripMenuItem.Checked = true; + this.warningToolStripMenuItem.CheckState = System.Windows.Forms.CheckState.Checked; + this.warningToolStripMenuItem.Name = "warningToolStripMenuItem"; + this.warningToolStripMenuItem.Size = new System.Drawing.Size(137, 22); + this.warningToolStripMenuItem.Text = "Warning"; + this.warningToolStripMenuItem.Click += new System.EventHandler(this.warningToolStripMenuItem_Click); + // + // informationToolStripMenuItem + // + this.informationToolStripMenuItem.Checked = true; + this.informationToolStripMenuItem.CheckState = System.Windows.Forms.CheckState.Checked; + this.informationToolStripMenuItem.Name = "informationToolStripMenuItem"; + this.informationToolStripMenuItem.Size = new System.Drawing.Size(137, 22); + this.informationToolStripMenuItem.Text = "Information"; + this.informationToolStripMenuItem.Click += new System.EventHandler(this.informationToolStripMenuItem_Click); + // + // verboseToolStripMenuItem + // + this.verboseToolStripMenuItem.Name = "verboseToolStripMenuItem"; + this.verboseToolStripMenuItem.Size = new System.Drawing.Size(137, 22); + this.verboseToolStripMenuItem.Text = "Verbose"; + this.verboseToolStripMenuItem.Click += new System.EventHandler(this.verboseToolStripMenuItem_Click); + // + // traceToolStripMenuItem + // + this.traceToolStripMenuItem.Name = "traceToolStripMenuItem"; + this.traceToolStripMenuItem.Size = new System.Drawing.Size(137, 22); + this.traceToolStripMenuItem.Text = "Trace"; + this.traceToolStripMenuItem.Click += new System.EventHandler(this.traceToolStripMenuItem_Click); + // + // RefreshToolStripMenuItem + // + this.RefreshToolStripMenuItem.Name = "RefreshToolStripMenuItem"; + this.RefreshToolStripMenuItem.Size = new System.Drawing.Size(58, 20); + this.RefreshToolStripMenuItem.Text = "Refresh"; + this.RefreshToolStripMenuItem.Click += new System.EventHandler(this.clearTasksToolStripMenuItem_Click); + // + // clearToolStripMenuItem + // + this.clearToolStripMenuItem.Name = "clearToolStripMenuItem"; + this.clearToolStripMenuItem.Size = new System.Drawing.Size(46, 20); + this.clearToolStripMenuItem.Text = "Clear"; + this.clearToolStripMenuItem.Click += new System.EventHandler(this.clearToolStripMenuItem_Click); + // + // listView_EventView + // + this.listView_EventView.BackColor = System.Drawing.SystemColors.Window; + this.listView_EventView.Dock = System.Windows.Forms.DockStyle.Fill; + this.listView_EventView.FullRowSelect = true; + this.listView_EventView.Location = new System.Drawing.Point(0, 24); + this.listView_EventView.Name = "listView_EventView"; + this.listView_EventView.ShowItemToolTips = true; + this.listView_EventView.Size = new System.Drawing.Size(1012, 694); + this.listView_EventView.TabIndex = 2; + this.listView_EventView.UseCompatibleStateImageBehavior = false; + this.listView_EventView.View = System.Windows.Forms.View.Details; + this.listView_EventView.DoubleClick += new System.EventHandler(this.listView_EventView_DoubleClick); + // + // EventForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(1012, 718); + this.Controls.Add(this.listView_EventView); + this.Controls.Add(this.menuStrip1); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Name = "EventForm"; + this.Text = "Event Message Log"; + this.Load += new System.EventHandler(this.EventForm_Load); + this.menuStrip1.ResumeLayout(false); + this.menuStrip1.PerformLayout(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.MenuStrip menuStrip1; + private System.Windows.Forms.ToolStripMenuItem messageToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem verboseToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem informationToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem warningToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem errorToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem RefreshToolStripMenuItem; + private System.Windows.Forms.ListView listView_EventView; + private System.Windows.Forms.ToolStripMenuItem traceToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem clearToolStripMenuItem; + } +} \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/CommonObjects/EventForm.cs b/Demo_Source_Code/CSharpDemo/CommonObjects/EventForm.cs new file mode 100644 index 0000000..90b6db4 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/CommonObjects/EventForm.cs @@ -0,0 +1,328 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.IO; +using System.Windows.Forms; +using System.Diagnostics; +using System.Threading; + + +namespace EaseFilter.CommonObjects +{ + public partial class EventForm : Form + { + static DateTime currentLogDateModified = DateTime.MinValue; + static string logFileName = Path.Combine(GlobalConfig.AssemblyPath, GlobalConfig.EventLogFileName); + static bool[] selectedDisplayEvents = GlobalConfig.SelectedDisplayEvents; + + static EventForm eventForm = new EventForm(); + public delegate void ShowMessageFormDlgt(); + + public EventForm() + { + InitializeComponent(); + ResetEventView(); + } + + public static void DisplayEventForm() + { + Thread messageThread = new Thread(new ThreadStart(ShowEventForm)); + messageThread.Name = "ShowEventFormThread"; + messageThread.IsBackground = true; + messageThread.Start(); + } + + private static void ShowEventForm() + { + var handle = eventForm.Handle; + + if (eventForm.InvokeRequired) + { + eventForm.Invoke(new ShowMessageFormDlgt(ShowEventForm)); + } + else + { + if (!eventForm.Visible) + { + eventForm.ShowDialog(); + } + else + { + eventForm.Activate(); + } + } + } + + + + public void ResetEventView() + { + listView_EventView.Clear(); //clear control + //create column header for ListView + //Level Date and Time Source Event ID Message + listView_EventView.Columns.Add("Id",50, System.Windows.Forms.HorizontalAlignment.Left); + listView_EventView.Columns.Add("Level", 70, System.Windows.Forms.HorizontalAlignment.Left); + listView_EventView.Columns.Add("Date and Time", 170, System.Windows.Forms.HorizontalAlignment.Left); + listView_EventView.Columns.Add("Source", 150, System.Windows.Forms.HorizontalAlignment.Left); + listView_EventView.Columns.Add("EventId",40, System.Windows.Forms.HorizontalAlignment.Left); + listView_EventView.Columns.Add("Message", 900, System.Windows.Forms.HorizontalAlignment.Left); + + errorToolStripMenuItem.Checked = GlobalConfig.SelectedDisplayEvents[(int)EventLevel.Error]; + warningToolStripMenuItem.Checked = GlobalConfig.SelectedDisplayEvents[(int)EventLevel.Warning]; + informationToolStripMenuItem.Checked = GlobalConfig.SelectedDisplayEvents[(int)EventLevel.Information]; + verboseToolStripMenuItem.Checked = GlobalConfig.SelectedDisplayEvents[(int)EventLevel.Verbose]; + traceToolStripMenuItem.Checked = GlobalConfig.SelectedDisplayEvents[(int)EventLevel.Trace]; + + } + + public void LoadEventLog() + { + + try + { + if (!File.Exists(logFileName)) + { + return; + } + + FileInfo fileInfo = new FileInfo(logFileName); + + ResetEventView(); + + string[] logs = null; + + EventManager.logFileSyncEvent.WaitOne(); + + logs = File.ReadAllLines(logFileName); + + EventManager.logFileSyncEvent.Set(); + + List items = new List(); + + for (int id = 0; id < logs.Length; id++) + { + + try + { + + string log = logs[id]; + + if (string.IsNullOrEmpty(log)) + { + break; + } + + + MessageEventArgs arg = EventManager.ConvertSringToEventArg(log); + + if (arg == null) + { + continue; + } + + string[] itemStr = new string[listView_EventView.Columns.Count]; + + int itemNum = 0; + + itemStr[itemNum++] = id.ToString(); + + switch (arg.Type) + { + case EventLevel.Error: if (!errorToolStripMenuItem.Checked) continue; break; + case EventLevel.Warning: if (!warningToolStripMenuItem.Checked) continue; break; + case EventLevel.Information: if (!informationToolStripMenuItem.Checked) continue; break; + case EventLevel.Verbose: if (!verboseToolStripMenuItem.Checked) continue; break; + case EventLevel.Trace: if (!traceToolStripMenuItem.Checked) continue; break; + } + + itemStr[itemNum++] = arg.Type.ToString(); + itemStr[itemNum++] = EventManager.FormatDateTime(arg.Time); + itemStr[itemNum++] = arg.CallerName; + itemStr[itemNum++] = arg.EventID.ToString(); + itemStr[itemNum++] = arg.Message; + + ListViewItem listItem = new ListViewItem(itemStr, 0); + + if (arg.Type == EventLevel.Error) + { + // item.BackColor = Color.Red; + listItem.ForeColor = Color.Red; + // item.Font = new Font(item.Font,FontStyle.Bold); + } + else if (arg.Type == EventLevel.Warning) + { + listItem.BackColor = Color.LightGray; + listItem.ForeColor = Color.Yellow; + // item.Font = new Font(item.Font, FontStyle.Bold); + } + + items.Add(listItem); + } + catch (Exception ex) + { + Debugger.Log(0, "EaseFilter", "ConvertSringToEventArg failed with error:" + ex.Message ); + } + } + + currentLogDateModified = fileInfo.LastWriteTime; + + if (items.Count > 0) + { + var listItems = new ListViewItem[items.Count]; + for (int i = 0; i < items.Count; i++) + { + listItems[i] = (ListViewItem)items[i]; + } + + listView_EventView.Items.AddRange(listItems); + listView_EventView.EnsureVisible(listView_EventView.Items.Count - 1); + } + + } + catch (Exception ex) + { + EventManager.WriteMessage(124, "LoadEventLog", EventLevel.Error, "LoadEventLog failed with error:" + ex.Message); + } + + } + + private void clearTasksToolStripMenuItem_Click(object sender, EventArgs e) + { + LoadEventLog(); + } + + private void errorToolStripMenuItem_Click(object sender, EventArgs e) + { + if (errorToolStripMenuItem.Checked) + { + errorToolStripMenuItem.Checked = false; + selectedDisplayEvents[(int)EventLevel.Error] = false; + } + else + { + errorToolStripMenuItem.Checked = true; + selectedDisplayEvents[(int)EventLevel.Error] = true; + } + + LoadEventLog(); + } + + private void warningToolStripMenuItem_Click(object sender, EventArgs e) + { + if (warningToolStripMenuItem.Checked) + { + warningToolStripMenuItem.Checked = false; + selectedDisplayEvents[(int)EventLevel.Warning] = false; + } + else + { + warningToolStripMenuItem.Checked = true; + selectedDisplayEvents[(int)EventLevel.Warning] = true; + } + + LoadEventLog(); + } + + private void informationToolStripMenuItem_Click(object sender, EventArgs e) + { + if (informationToolStripMenuItem.Checked) + { + informationToolStripMenuItem.Checked = false; + selectedDisplayEvents[(int)EventLevel.Information] = false; + } + else + { + informationToolStripMenuItem.Checked = true; + selectedDisplayEvents[(int)EventLevel.Information] = true; + } + + LoadEventLog(); + } + + private void verboseToolStripMenuItem_Click(object sender, EventArgs e) + { + if (verboseToolStripMenuItem.Checked) + { + verboseToolStripMenuItem.Checked = false; + selectedDisplayEvents[(int)EventLevel.Verbose] = false; + } + else + { + verboseToolStripMenuItem.Checked = true; + selectedDisplayEvents[(int)EventLevel.Verbose] = true; + } + + LoadEventLog(); + } + + private void traceToolStripMenuItem_Click(object sender, EventArgs e) + { + if (traceToolStripMenuItem.Checked) + { + traceToolStripMenuItem.Checked = false; + selectedDisplayEvents[(int)EventLevel.Trace] = false; + } + else + { + traceToolStripMenuItem.Checked = true; + selectedDisplayEvents[(int)EventLevel.Trace] = true; + } + + LoadEventLog(); + } + + private void clearToolStripMenuItem_Click(object sender, EventArgs e) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + + if (MessageBox.Show("Do you really want to delete all the event messages?", "Delete Message", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == System.Windows.Forms.DialogResult.Yes) + { + + File.Delete(logFileName); + ResetEventView(); + + } + } + + private void EventForm_Activated(object sender, EventArgs e) + { + // LoadEventLog(); + } + + private void listView_EventView_DoubleClick(object sender, EventArgs e) + { + ListViewItem item = listView_EventView.SelectedItems[0]; + string message = (string)item.SubItems[listView_EventView.Columns.Count -1 ].Text; + + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this);MessageBox.Show(message, "Event Message"); + } + + private void EventForm_Load(object sender, EventArgs e) + { + LoadEventLog(); + } + + } +} diff --git a/Demo_Source_Code/CSharpDemo/CommonObjects/EventForm.resx b/Demo_Source_Code/CSharpDemo/CommonObjects/EventForm.resx new file mode 100644 index 0000000..19ecae5 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/CommonObjects/EventForm.resx @@ -0,0 +1,573 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + + + + AAABAAgAEBAAAAEACABoBQAAhgAAABAQAAABACAAaAQAAO4FAAAYGAAAAQAIAMgGAABWCgAAGBgAAAEA + IACICQAAHhEAACAgAAABAAgAqAgAAKYaAAAgIAAAAQAgAKgQAABOIwAAMDAAAAEACACoDgAA9jMAADAw + AAABACAAqCUAAJ5CAAAoAAAAEAAAACAAAAABAAgAAAAAAEABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP// + /wAygPwAvYp4AH/e/wD/3ZcAwMDAAHyX4QB2dXQA7trOAKCgoADhrooAjMXWAKHB/wCZhnMAvaySAP/3 + ywDxyIIA0tLSAJGQjQDMrqoA/9y4AK16cAD/8OEA0p+CAIqo3gD5xpYAhIJ9AOS8mACrq6sA3trEAPTd + qQD//+oA/+THAP/RhADEnIgA8tWYAP/npgD96NUAceH/APjouwA4jP8AxpN9AJmOgwCZl5QAqoF6AO26 + kAC1gnQA782QAIaHhwD/+vUAtKiXANmmhgD/1ZAAmLz/AMjBugD22qAAmpSLAP/uvQDQtLAA//bsAIuf + 3QDRzssA/+DAAPntwgCZiXoAfn5/AP/t2gD/584AOoX/APn5+QD+2Z0AnJycAHt5dQDguJUAsX5yAIam + 4gC5hnYAwY56APXClADxvpIA6baOAOWyjADdqogA///yAP7WmAD8/PwAqKioAJaPhwDw0JQA1tPPAJmM + fgDVooQAz8/PAMTBvgA2iP8A//jwAMmWfgD/69YA/+nSAJuSiADHnokAgYB/AI+OiwDCwsIA//37AP/+ + 7wD/7t0A/9qWAJmUjgCrqqgAd3d2ALOAcwC3hHUAmZCHANekhACFhYYA//v3AHt4cwCZi3wA/v7+APr6 + +gD+0IUAuod3AL6LeQDCj3sAxZJ8AJ2dnQDcqYcAw8C9AP/37wCAgIAAgoB+AK57cADV0s8AkpCNAMfB + ugAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAACNhfk4DTS9LFhQ9WIcAAGUJRkZ5VngBAQENRQRkAAAYAXJtLGhdARIZAicp + BwAAcwEXPGlXQgiDEwxfNjsAAIABcl5/DyJ6VTlnTAGFAAALAWsyhAUkMBFHMQEBcAAAUgErWnY6KB9Z + NW8SAXEAAFEBYmAbIGpAOGx0AXh7AAAuAXc3Ch5UECUzSAZWfAAAUAEhY4JuhElmHWl1eX0AAE8BDkFb + iGCGPoFtbUYqAAAaARU/IURiQ2sXFxdGYQAAHCYBAQEBAQEBAQEBCS0AAABKGk9QLlFSC1M0XC0AAAAA + AAAAAAAAAAAAAAAAAAD//wAAwAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAIAB + AACAAQAAgAEAAMADAAD//wAAKAAAABAAAAAgAAAAAQAgAAAAAABABAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAMuYf8zJln7/xZJ8/8GOev+9inj/uYZ2/7WCdP+xfnL/rXpw/8yuqv+Ln93/l5CI/Xdz + bH4AAAAAAAAAAM6bgMzu2s7/+fn5//n5+f/6+vr//Pz8//7+/v////////////////+hwf//OoX//3/e + //+dlIr+AAAAAAAAAADSn4L//////5mQh/+ZlI7/mZeU/8LCwv/Pz8///////9LS0v+KqN7/MoD8/3Hh + //84jP//fJfh/wAAAAAAAAAA16SE////////8OH///bs///9+/+oqKj/fn5//3Z1dP+AgID/kZCN/4zF + 1v82iP//mLz//9C0sP8AAAAAAAAAANyph///////mZCH/8TBvv+dnZ3/vayS///RhP/+0IX//taY/5qU + i/+Pjov/hqbi//////+ue3D/AAAAAAAAAADhror////////u3f//+vX/goB+///dl//y1Zj/782Q//HI + gv/+2Z3/hoeH////////////s4Bz/wAAAAAAAAAA5bKM//////+ZjoP/1tPP/3t4c///7r3/+Oi7//Td + qf/w0JT//9WQ/3d3dv/S0tL//////7eEdf8AAAAAAAAAAOm2jv///////+vW///48P+Egn3////q///+ + 7//57cL/9tqg///alv+FhYb///////7+/v+6h3f/AAAAAAAAAADtupD//////5mLfP/Iwbr/oKCg/97a + xP////L///fL///npv+0qJf/nJyc/8DAwP/8/Pz/vot5/wAAAAAAAAAA8b6S////////5Mf//+nS///3 + 7/+rqqj/goB+/3t5df+BgH//q6ur///9+///+/f/+vr6/8KPe/8AAAAAAAAAAPXClP//////mYZz/5mJ + ev+ZjH7/x8G6///48P/V0s//0c7L/8PAvf+ZlI7/mZSO//n5+f/Gk33/AAAAAAAAAAD5xpb////////c + uP//4MD//+TH///nzv//69b//+3a///u3f//8OH///Dh///w4f/5+fn/yZZ+/wAAAAAAAAAA88CTzP3o + 1f//////////////////////////////////////////////////////7trO/6p3bswAAAAAAAAAAAAA + AADuu5DM+caW//XClP/xvpL/7bqQ/+m2jv/lsoz/4a6K/92qiP/Zpob/1aKE/6p3bswAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAD//wAAwAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAMAD + AAD//wAAKAAAABgAAAAwAAAAAQAIAAAAAACgAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8AGVv/AK98 + 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 + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADJln6pyZZ+/8aTfP/EkXv/wY56/7+Mef+9inj/uod2/7iF + df+2g3T/s4Bz/7F+cv+vfHH/rHlv/6p3bv+odW3/qnp0/9TEyP+Jg3j/hICA+GNjYzgAAAAAAAAAAM6b + gKnZr5j/9eLU///27v//+vX///38//////////////////////////////////////////////////// + ////////9vf//wZF//9Oheb/5drP/357evkAAAAAAAAAANKfgv/24dD///Pn///27v//+vX///38//// + ///////////////////////////////////////////////////z9f//DEr//0ac//9k1///ZZ3p/4yH + gf8AAAAAAAAAANShg/////////Ll///17P+ZlZL/mZeW/5mZmf+ZmZn/mZmZ//////////////////// + //////////////Hz//8LSf//SaL//2/Z//9Xt///D1r//7+zv/8AAAAAAAAAANajhP////////Ll///0 + 6v//9/H///v4////////////////////////////+vr6//n5+f//////8fHw/4SCh/87jOH/bt3//1a0 + //8ZW///4+f//7KGgf8AAAAAAAAAANilhf////////Dj///06v+ZlI//mZaT/5mYl/+ZmZn/y8vL/7Oz + tf+ChYj/fXx5/358ev+ChIj/jo+Q/62qpf/Ax8L/QZrp/xRW///m6////////6l2bv8AAAAAAAAAANqn + hv///////+/g///z5///9ez///nz///8+v//////o6Wn/7Wrl//10JT/+9KT//vTmv/8153/wrWh/4CD + if/EwLv/goKQ/+nt/////////////6t4b/8AAAAAAAAAAN2qh////////+7e///w4/+Zkoz/mZSR/5yZ + lv/b29z/rKSS//zXmv/x0Zv/79CZ/+7Nkf/wz5f/+tef/7+znf+Ki4z/ysrI/////////////////657 + cP8AAAAAAAAAAOCtif///////+zZ///v4P//8+f///Xs///59f+UlJf/9Nii//Xdqv/x26r/8dup//DU + ov/v0Jf/8M6a//7ao/+PkZT//////////////////////7B9cf8AAAAAAAAAAOKviv///////+rX///u + 3v+ZkIj/mZKM/62ppf+AgH7//+i1//blvv/358D/9eK4//Pdsf/x1qX/8NCV//3apP+FhIL/2NjY//// + /////////////7J/cv8AAAAAAAAAAOSxi////////+nV///s2f//7+D///Ll///38P+Eg4L///PI//z1 + 3P/689b/9+zI//bnvf/z3K3/8NOe//7Zof+EhIP//////////////////////7WCdP8AAAAAAAAAAOaz + jP///////+fQ///q1/+ZjoT/mY+G/62nof+enp3/7+bF////8P/+/vz//Pbb//fsx//24bP/89ek//TY + pP+Rk5b//////////////////////7iFdf8AAAAAAAAAAOi1jv///////+XM///o0v//6tf//+7e///y + 5//z7OX/paOc////7P////f//fnl//nuzP/347b//+Gm/6Sdkv/b29z//////////////////////7qH + dv8AAAAAAAAAAOy5j////////+PJ///mzv+Zi37/mY6C/52Tif+tpp//vru5/6Khm//j3sL///zT///y + wv/p1av/oJuS/7Kztv+/v7//mZmZ/////////////////72KeP8AAAAAAAAAAO67kP///////+HF///j + yf//5s7//+nV///s2f//7+D///Pp//Lr5P+lpKT/gICD/4CCgv+ampz/5OPj///9/f////////////// + /////////////7+Mef8AAAAAAAAAAPC9kf///////9/A///hxf+ZiHn/mYt9///p1f+ZjoL/nZOJ/6ae + lv+tp6H/r6mk/62npP+jn53///nz/5mWk/+Zl5X/mZeW///9/P///fz///38/8GOev8AAAAAAAAAAPK/ + k////////928///fwP//4cX//+PJ///mzv//6NL//+rX///t3P//7+D///Dj///z5///9Or///Xs///2 + 7v//9/H///nz///69f//+vX///r1/8SRe/8AAAAAAAAAAPTBlP///////9u4///dvP+ZhnP/mYd2/5mI + ef+Zinz/mYt+///q1/+ZjoL/mY+F/5mPhv+ZkIj/mZKL/5mSjP+Zkoz/mZOO///27v//9u7///bu/8eU + ff8AAAAAAAAAAPbDlf///////9mz///buP//3bz//9/A///hxf//48n//+XM///n0P//6dX//+rX///s + 2f//7t7//+/g///w4///8uX///Ll///z5///8+f///Pn/8qXfv8AAAAAAAAAAPnGlv/+8eb//+7e///Z + s///27j//928///evv//4MP//+LH///lzP//5s7//+fQ///p1f//6tf//+zZ///t3P//7t7//+7e///v + 4P//7+D/9uDQ/8yZf/8AAAAAAAAAAPjFlj36ypz//vHm//////////////////////////////////// + ///////////////////////////////////////////////////338z/27KZ/8yZf6kAAAAAAAAAAAAA + AAD4xZY9+caW//fElf/1wpT/88CT//G+kv/vvJH/7bqQ/+q3j//otY7/5rOM/+Sxi//ir4r/4K2J/96r + iP/ap4b/2KWF/9ajhP/UoYP/0J2BqQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA////AMAAAwCAAAEAgAABAIAAAQCAAAEAgAABAIAAAQCAAAEAgAABAIAAAQCAAAEAgAABAIAA + AQCAAAEAgAABAIAAAQCAAAEAgAABAIAAAQCAAAEAwAABAOAAAwD///8AKAAAACAAAABAAAAAAQAIAAAA + AACABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8ANF/oAMCNeQBt2f8ATVNaAPvboQB5pLUAxsjQAEtw + qgBfiP8AeX6EAK6ppADksYsA+O/PAKBuagBNsfgAmZONADqL/wBkZ20A2cmkAN3d3QDi270AUG7oAMie + kADNtLUA8sqLAIqTpAA8b/8A7u3sAJmGdAD/3r4AW3KXAF/A/wC1t7gArqKNALB9cQD//N8A79vRAJ2d + nQDXpIQA69GeAIiKjgDu8f8AKnb/AOe9nwDEwr8A7tuwAL2yogD/9+8A4cKQALWRhQDx5cEAzZp/APvI + lwDW1NIA/+3cAPG+kgCJh4EAkZOXAP3rvAD/5MoAOmfxAOLRqgCZjIAA2byhAM/LxwDi2dIApKWpAMa2 + wwDhyZoAsKmYAPLVpwCodW0AVrT/AODm5ACysK8A9dKaAPb29gD39+cA99+rAIGEiQBYgP8A6uHYALeE + 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 + AAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPgAAAH//////////8oAAAAIAAAAEAAAAABACAAAAAAAIAQ + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAHVvWSSGhH3maWhndGJiYl6EhIQCAAAAAAAAAAAAAAAAAAAAALqHdrW2g3T/tYJz/7SB + c/+zgHL/sX5y/7B9cf+vfHH/rntw/616cP+seW//q3hv/6l2bv+odW3/p3Rt/6ZzbP+lcmz/pHFr/6Nw + a/+hbmr/oG1p/6Bua//NtLX/UG7o/4qTpP/Nx8L/iIiH/2NjY2kAAAAAAAAAAAAAAAC6h3a1yJ6Q/+/b + 0f//+PL///v3///+/f////////////////////////////////////////////////////////////// + /////////////////////////Pz//1+I//8qdv//S63//+Dm5P/Py8f/aGhoeQAAAAAAAAAAAAAAAL6L + eP/v2s7///Xs///48v//+/f///79//////////////////////////////////////////////////// + //////////////////////////////v7//9bhv//Lnn//1a0//9o1f//W73//66urv+MioTTAAAAAAAA + AAAAAAAAwI15///+/v//9ez///jy///79////fv///////////////////////////////////////// + ///////////////////////////////////6+///WID//y97//9Zt///bNb//1/A//87j///Omfx/4V/ + clcAAAAAAAAAAAAAAADDkHr////////06v//9/D/mZaT/5mYl/+ZmZn/mZmZ//////+ZmZn/mZmZ/5mZ + mf+ZmZn/mZmZ/5mZmf+ZmZn/mZmZ////////////7u3s/1Bw8f8wevz/Wrn//2zW//9ev///Po7//zxv + ///GtsP/AAAAAAAAAAAAAAAAAAAAAMaTfP////////Pp///27v+ZlZL/mZeV/5mZmf+ZmZn//////5mZ + mf+ZmZn/nZ2d/7W1tf/FxcX/zMzM/8vLy//ExMT///////r6+v+Xk4r/W3KX/0qr9P9t2f//Xb7//z2N + //9AcP//7vH//65/ef8AAAAAAAAAAAAAAAAAAAAAyZZ9////////8+n///bu///48v//+/f///79//// + ///////////////////29vb/tbe4/4qMkf+EiJD/hIiP/4GEif+vsLH/6Ojo/46Ojf/i2dL/eaS1/02x + +P86i///RHP///Dz////////qndu/wAAAAAAAAAAAAAAAAAAAADKl37////////y5///9ez/mZWR/5mW + k/+ZmJf/mZmZ/5mZmf+0tLT/vL29/3Z7gv+yp5L/5ceW//HJjP/1zJH/8c+f/72yov9NU1n/kJCS/+7t + 7P/q4dj/S3Cq/zRf6P/y9P////////////+seW//AAAAAAAAAAAAAAAAAAAAAMyZf/////////Ll///0 + 6v+ZlJD/mZWS/5mXlf+ZmZn/qqqq/7+/wP+Agob/4cKQ//LKiv/syI7/6saP//DQnf/v06P/8MeK/+/O + mv9kZ23/mpuc/5OSkf+emYz/xsjQ/////////////////698cf8AAAAAAAAAAAAAAAAAAAAAz5yA//// + ////8eP///Pp///17P//+PL///v3///+/f/5+fn/h4uP/+bJmv/105n/79Ca/+/Qmf/vz5j/7s2Q/+7I + i//y06T/9NWg//LQn/9NUlr/3d3d/+jo6P//////////////////////sn9y/wAAAAAAAAAAAAAAAAAA + AADRnoH////////w4f//8uf/mZKM/5mUkP+ZlpP/srCv/8nKy/+uoo3/9NOc/+vQnv/q0p7/8dam//HV + ov/w057/79CY/+7Kjf/y1Kf/9dCR/7Ornf/CwsP///////////////////////////+0gXP/AAAAAAAA + AAAAAAAAAAAAANShg////////+/g///x4/+Zkoz/mZSP/5mVkf/DwsD/o6Wp/9nFmv/u16X/7Nep/+zX + qv/z3bD/89yt//Hbqf/w1KH/79Ca/+7Mj//227H/79Gj/5CSlv///////////////////////////7eE + dP8AAAAAAAAAAAAAAAAAAAAA16SE////////7dz///Dh///y5///9Or///fw///8+v+Qk5f/99+r//fm + vf/25r7/9unF//bnwP/35Ln/89+x//Hbqf/w1KH/78+V//LWqP/205r/jJCV//////////////////// + ////////uod2/wAAAAAAAAAAAAAAAAAAAADap4b////////s2v//7+D/mZGI/5mSjP+Zk47/zMrI/46Q + lv/13a7/+e7M//Xrz//06cr/8ufF//Divf/v3LP/7Niq//Hbqf/pzJb/7dGg//XRm/+EiI3/yMjI/5mZ + mf////////////////+9inf/AAAAAAAAAAAAAAAAAAAAANyph////////+rW///t3P+ZkIf/mZGJ/5mS + jP/Ewb7/pKWo/9nJpP//9tz/9/HY//f25//38Nv/9OnH//Hlwf/u27D/8tus/+nOmv/v0qD/582g/4mK + jv+/v7//mZmZ/////////////////7+MeP8AAAAAAAAAAAAAAAAAAAAA3quI////////6dX//+vY///u + 3v//8OH///Ln///37//a2dj/sKmY///83//+/fH//v36//7+8//89Nb/+O/P//bku//z3a//8dak//vb + of+roZL/x8jJ////////////////////////////wo96/wAAAAAAAAAAAAAAAAAAAADhror////////n + 0f//6tb/mY6D/5mPhv+ZkYj///Lo/9DNy/+hoKP/4tu9//r65f/7+/L/9/fn//Xw1//47sz/7961/+zX + qf/w157/4cma/3l+hP/7+/v////////////////////////////Fknv/AAAAAAAAAAAAAAAAAAAAAOOw + i////////+bP///o0/+ZjID/mY6E/5mPhv//8uX/q6ah/9bU0v+bm5r/5d7D//n54//69+P/9vDV//ru + yf/z4LL/992o/+DInf+AgYT/wMDA/////////////////////////////////8eUfP8AAAAAAAAAAAAA + AAAAAAAA5rOM////////5cz//+bP///p1f//69j//+3c///w4f//8uX///bv//Pw7v+jo6b/sq2e/+PY + uP//8MP//eu8/+LRqv+wqJf/hYiM/+Dg4f//////////////////////////////////////ypd+/wAA + AAAAAAAAAAAAAAAAAADpto3////////jyP//5cz/mYt9/5mMgP+ZjYL/mY6E/5mQh/+ZkYn/rqmk/9DO + zP/T0dH/np6i/4iKjv+Ehoz/kpSY/6ipqv/Nzc3//////5mZmf+ZmZn/mZmZ/5mZmf////////////// + ///MmX//AAAAAAAAAAAAAAAAAAAAAOu4jv///////+HE///kyv+ZiXv/mYt9/5mMgP+ZjYL/mY6E/5mQ + h/+ZkYn/npaQ///38P/JxsT/0c/N/9HPzf/Ix8X/tbSz/52cnP//////mZmZ/5mZmf+ZmZn/mZmZ//// + /////////////82af/8AAAAAAAAAAAAAAAAAAAAA7bqQ////////38H//+LG///kyv//5c3//+fR///p + 1f//69j//+3c///v4P//8eP///Ln///06v//9ez///fw///48v//+vX///v3///8+f///fv///79//// + ////////////////////////0J2B/wAAAAAAAAAAAAAAAAAAAADwvZH////////dvf//4ML/mYh3/5mJ + ef+ZiXv/mYt9/5mMgP//69j/mY6E/5mPhv+ZkIf/mZGJ/5mSjP//9Or/mZSP/5mUkP+ZlZH/mZWS/5mW + k/+Zl5T/mZeV/5mYl////fv///79///+/f/ToIL/AAAAAAAAAAAAAAAAAAAAAPPAk////////9y5///e + v/+ZhnT/mYh3/5mJef+ZiXv/mYt9///p1f+ZjID/mY6D/5mPhf+ZkIf/mZGI///y5/+Zkoz/mZKM/5mT + jv+ZlJD/mZWR/5mVkf+ZlZL/mZaT///79///+/f///v3/9ajhP8AAAAAAAAAAAAAAAAAAAAA9cKU//// + ////5s3//9y5///ev///4ML//+LG///kyv//5cz//+bP///o0///6tb//+vY///t3P//7+D///Dh///x + 4///8uf///Pp///06v//9ez///bu///27v//9/D///jy///48v//+PL/2KWF/wAAAAAAAAAAAAAAAAAA + AAD4xZX////////48v//5s3//9y5///dvf//38H//+HE///jyP//5cz//+bP///n0f//6dX//+rW///s + 2v//7dz//+/g///w4f//8eP///Ll///y5///8+n///Pp///06v//9ez///Xs/+7a0f/bqIb/AAAAAAAA + AAAAAAAAAAAAAPvIl4/6x5b///////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////9+//u2s3/572f/7aD + dI8AAAAAAAAAAAAAAAAAAAAAAAAAAPvIl4/7yJf/+seW//nGlv/4xZX/98SV//XClP/0wZP/88CT//K/ + kv/xvpL/8L2R/+67kP/tupD/7LmP/+y5j//ruI7/6reO/+m2jf/ntIz/5rOM/+Wyi//ksYv/47CL/+Kv + iv+2g3SPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/////////j4AAAAcAAAAHAAAABwAAAAcAA + AAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AA + AAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAAD4AAAB///////////KAAAADAAAABgAAAAAQAIAAAA + AACACgAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8AIVXwAMGOeQBt2f8ATE1PAPvboQCLldIArb3/ADhm + uQBfiP8AeX6EAK2qpwDlsosA+/DSAKBuagBNsfgAmZWLADmJ/wBnaGkA2cmkAOLe2gDi270ATInRAMai + kQDNtLUA8sqLAHWCtQA8b/8A7+3rAIV7awD/3r4AW3KXAGHE/wCytL8AqaCNALB9cQD//eMA79vRAJ2d + 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 + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI6MgwJycm/BcnJyu2Rk + ZChmZmY0V1dXAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQ3 + +CN7e4P+sK+t/4CAgP6CgoL/bW1twmxsbAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADPnICj0J2B/9Cd + gf/QnYH/0J2B/9Cdgf/QnYH/0J2B/8+cgP/PnID/z5yA/86bgP/Om4D/zpuA/82af//Nmn//zJl//8yZ + f//MmX//yZZ9/8iVff/Gk3z/xJF7/8KPev/Bjnn/vot4/72KeP+7iHb/uYZ1/7aDdP+0gXP/s4By/7B9 + cf+4i4H/vKu//yJR9f80cer/q6in/+Hg3/+UlJT/hISE/2VlZUsAAAAAAAAAAAAAAAAAAAAAAAAAANKf + gszQnYH/7tS////04///9OT///Xl///15///9ej///bp///26v//9+v///fs///47f//+O7///nv///5 + 8P//+fL///rz///69P//+/X///v2///89////Pj///z5///9+v///fz///79///+/v////////////// + ///////////////////d4///KFn//ytz//9CmP//aLTo/+bh3//m5eT/goKC/mVlZUAAAAAAAAAAAAAA + AAAAAAAA06CCo9Gegf/24s7///Pi///04///9OT///Xl///15///9ej///bp///26v//9+v///fs///4 + 7f//+O7///nv///58P//+fL///rz///69P//+/X///v2///89////Pj///z5///9+v///fz///79///+ + /v///////////////////////////9vi//8nWv//LHX//0OZ//9dv///ZM7//3/G7v/Hwr7/s7Kx/nR0 + dHsAAAAAAAAAAAAAAAAAAAAA1KGD//Xl2P//+O3///Pi///04///9OT///Xl///15///9ej///bp///2 + 6v//9+v///fs///47f//+O7///nv///58P//+fL///rz///69P//+/X///v2///89////Pj///z5///9 + +v///fz///78///+/f//////////////////////2N///ydY//8tdv//RJn//17A//9nzv//Y8j//0yq + //9XitP/npmS/3l5edwAAAAAAAAAAAAAAAAAAAAA1aKD////////8+H///Pi/4V/dv+Ff3f/hYB3/4WA + eP+FgHn/hYB6/4WAev+FgXv/hYF7/4WBfP//+O7///nv/4WCff+Fgn7/hYJ+/4WCf/+Fg4D/hYOA/4WD + gf+Fg4H/hYOC/4WEgv+FhIP/hYSD/4WEhP+FhIT/hYWF/5iYmP+jq8z/H1P5/y53//9GnP//X8H//2fO + //9ix///T6n//zqL//8XW/7/QFi8g3Fway4AAAAAAAAAAAAAAAAAAAAA1qOE////////8+H///Pi/4V/ + dv+Ff3f/hX93/4WAeP+FgHj/hYB5/4WAev+FgXv/hYF7/4WBfP//+O7///jv/4WCff+Fgn7/hYJ+/4WC + f/+Fg4D/hYOA/4WDgP+Fg4H/hYOC/4WEgv+FhIP/hYSD/4WEhP+Lior/sbGx/6GozP8cS+f/Lnn+/0ed + //9fwv//Z87//2LG//9OqP//OYr//x1c//+Hi9H/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA16SE//// + ////8+H///Pi/4V/dv+Ff3f/hX93/4WAeP+FgHj/hYB5/4WAev+FgXv/hYF7/4WBfP//+O7///jv/4WC + ff+Fgn7/hYJ+/4WCf/+Fgn//hYOA/4WDgP+Fg4H/hYOB/4WDgv+FhIL/hYSD/4uKif+vrq7/kpCM/yxM + sf8nauD/R5z8/2DE//9nzv//YcX//06n//85if//HVr//6e5///Gopr/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA2KWF////////8+H///Pi///z4v//9OT///Tl///15v//9ef///bo///26f//9ur///fr///3 + 7P//+O7///jv///57///+fD///ny///68///+/b///z4///9+v///fv///37///9+////vv///37///9 + /f/Nzcz/mZiX/5GQjf9Df8H/Wrny/2jP//9hxf//Tab//ziI//8cW///rb3///////+wfXH/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA2aaG////////8+D///Ph///z4v//9OT///Tl///15v//9ef///Xo///2 + 6f//9ur///fr///37P//+O3///ju///57///+fD///rz//369v/U0tD/np6c/3l6ev9naGn/Zmdo/3Z2 + dv+amZn/19bU///+/f/v7u3/g4OD/83My/+rrKr/WqjP/1m79P9Lpf//OIb//xxZ//+ywf////////// + //+zgHL/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA26iG////////8uD///Ph/4V/dv+Ff3b/hX93/4WA + d/+FgHj/hYB5/4WAev+FgHr/hYF7/4WBe/+FgXz/hYF8/4WBff+npaL/r66s/3R0df9wcnT/mpqZ/7+z + o//OvqT/0b+n/8G4qP+dnqH/YmVn/2VlZv9nZ2f/lJSU/7m5uf/+/f3/pKiq/0GIz/8weOj/GVHy/4ua + 0/////////////////+0gXP/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3KmH////////8uD///Ph/4V/ + dv+Ff3b/hX93/4V/d/+FgHj/hYB4/4WAef+FgHr/hYB6/4WBe/+FgXv/hYF8/66rqP+goJ//bm9y/6Gd + lf/YvI//8MaF/+/Iiv/nw4b/5sCF/+e9fv/mu3X/6cyi/7Gvrf9KS03/jIyM/+3t7f/MzMz/2NbV/4OJ + j/8YRsr/j5vS/6Kiov////////////////+2g3T/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3aqH//// + ////8uD///Ph/4V/dv+Ff3b/hX93/4V/d/+FgHj/hYB4/4WAef+FgHr/hYB6/4WBe/+FgXv/pqOf/6Wk + o/92eHv/u6yU/+nChf/nxIj/7syU/+7LlP/nxo//6cmU/+vPoP/rzqD/58KJ/+a6d//Wy7v/TlFT/5SU + lP+goKD/kZGR/6Skof+TlJb/r66u/4WFhf////////////////+5hnX/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA3quI////////8t////Pg///z4f//8+L///Tj///05P//9eX///Xn///16P//9uj///bp///3 + 6///+O7/5uPf/3l6fP+8rpb/9NCR/+/OlP/vzpX/7s6U/+7NlP/uy5L/7sqP/+3Hi//tzJf/8deu//DS + ov/swHv/1829/0tMTv9jY2P/0dHR/7GxsP/o5+f///79///+/f///v7///7+///+/v+7iHb/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA36yI////////8t////Lg///z4f//8+L///Tj///05P//9OX///Xm///1 + 5///9uj///bp///26v//+vP/oJ+f/5uWjv/21Jn/8NGc//DSnf/w0p3/8NKd//DRnP/v0Jn/79CY/+7N + kv/uyo//7cmP//HXrv/x06L/7sJ//6iopv+GhYb///79///+/f///fz///78///+/P///v3///79///+ + /f+9inj/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4K2J////////8t7///Lg/4V/df+Ff3X/hX92/4V/ + d/+Ff3f/hYB3/4WAeP+FgHn/hYB6/5GNiP+3tbP/f4GE/9W9kv/ozJj/8daj//HYpP/nz5z/58+d/+fN + nP/nzJn/58qV/+bIkv/vz5j/7suQ/+7JkP/y27H/7sqT/+zSq/9cXmH/7ezq///9+v///fv///37///9 + /P///fz///38///9/P++i3j/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4a6K////////8t7///Lf/4V+ + df+Ff3X/hX92/4V/dv+Ff3f/hX93/4WAeP+FgHj/hYB5/6WhnP+joqH/kI2J/+7RnP/o0J//8tus//Pc + rP/q06P/6tOj/+nSov/o0KD/58+c/+fMmf/w0p3/78+X/+7Lkf/w0KD/8NWr/+7Eg/+QkZX/urm4///9 + +v///fr///36///9+v///fr///36///9+v/Bjnn/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4q+K//// + ////8t7///Lf/4V+df+Ff3X/hX92/4V/dv+Ff3f/hX93/4WAd/+FgHj/hYB5/7Guqv+ampn/qaCN/+7T + o//s1aj/9eCz//Xgs//r16z/69is/+vXqf/q1af/6tOj/+jQn//x1qT/8NKd/+/Pl//vzJL/8tmz/+/I + iv+zrKL/lZSU///9+v///Pn///z5///8+f///Pn///z5///8+f/Cj3r/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA5LGL////////8d3///Le///y3///8+D///Ph///z4v//9OP///Tk///05f//9eb///Xn///6 + 8v+jo6P/uq+V//fhsf/25bz/9uW8//bpxf/368f/+OrE//blvv/247f/9eCy//Pdrv/x2aj/8dah//DR + nP/uzpL/8ter//DMlP/HuaX/hYSF///9+v///Pf///z4///8+P///Pj///z4///8+P/EkXv/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA5bKL////////8d3///Le///y3///8uD///Ph///z4v//8+L///Tk///0 + 5f//9eX///Xn///58f+mpqX/ua6W//jktv/36cT/++/S//vuzv/47s3/+O3K//fqxf/36b//9uO4//Xg + s//z3K//8dim//DTnv/vz5f/8dWn//DNlf/EtqL/hoaG///8+f//+/b///v3///89////Pf///z3///8 + 9//Gk3z/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA5rOM////////8dz///Hd/4V+dP+FfnT/hX91/4V/ + df+Ff3b/hX92/4V/d/+Ff3f/hYB4/7Kvqv+mpqX/rKOT//rpuv/x58n/9OvV//Tqzf/y68//8+jL//Dn + xP/u4r7/7d+5/+vYrv/q1af/8tqp//HWpP/nyZP/686f/+rHjf+vp5r/mZmY/6upp/+Fg4D/hYOA/4WD + gP//+/b///v2///79v/IlX3/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA57SM////////8dz///Hd/4V+ + dP+FfnT/hX51/4V/df+Ff3X/hX92/4V/dv+Ff3f/hX93/6ainP+ysa//k5GN//3twP/07NH/9fHd//Xx + 3v/49+z/+PXp//Przv/w5sb/7uTB/+3dtP/r2Kz/89ys//HXpf/nypX/6tCf/+nEif+Ki43/u7q4/5+c + mv+Fg4D/hYOA/4WDgP//+/X///v1///79f/Jln3/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA6LWN//// + ////8dv///Hc/4V+c/+FfnT/hX50/4V+df+Ff3X/hX92/4V/dv+Ff3f/hX93/5KOhv++vbr/k5SX/9/U + sv/07dH/9/Pg//n47v/6+vL/+fnw//Tv2P/x6cz/8ufH/+7et//r2Kz/892v//Hap//nypb/6c2a/9fA + mf9rbG//7Onn/42Kh/+Fgn//hYJ//4WCf///+vT///r0///69P/MmX//AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA6baO////////8Nv///Hb///x3f//8d3///Le///y4P//8+D///Ph///z4v//9OP///Tk///0 + 5f//+fD/x8bF/5mVi///+Nf//Pjh//387v///vf//f3v//z33f/79df/+vDR//jov//247j/892v//HZ + p//w1aD/9NKa/5qWkv+Xlpb///v3///68v//+vL///ry///68///+vP///rz///68//MmX//AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA6reO////////8Nr///Hb///x3P//8d3///Le///y3///8uD///Ph///z + 4f//8+L///Tj///05P//9ej/8u7p/6Wlp/+6tKD///3j//365f/9/Ov//Prp//354//79dv/++/O//fo + wv/25Lj/892u//Lap//216D/u7Cc/3Bxc//p5+P///nx///58f//+fH///nx///58v//+fL///ny///5 + 8v/MmX//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA67iP////////8Nr///Da/4V+cv+FfnP/hX5z/4V+ + dP+FfnT///Lg///z4f+Ff3b/hX92/4V/dv+Ff3f/qaWg/8XEwv+cnZ//tbGd//b01//389z/9vLc//v2 + 3v/y6cv/7uK8/+3cs//s2Kv/69Sm/+3TnP+3q5b/dHV4/6empP+hnpv///nv///58P//+fD///nw///5 + 8P//+fD///nw///58P/Nmn//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA7bqP////////8Nn///Da/4V9 + cv+FfnL/hX5z/4V+c/+FfnT///Lf///y4P+Ff3X/hX92/4V/dv+Ff3b/hX93/7Guqf/FxMP/o6Sl/5eV + i//a0rP/9OrE//3xyv/w5Lz/8OC2//HcsP/w2qr/1cKd/5mVj/95enz/p6Wk/6uopf+FgXz///jv///4 + 7///+O////nv///57///+e////nv///57//Nmn//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA7ruQ//// + ////79f///DZ/4V9cv+FfnL/hX5z/4V+c/+FfnT///Le///y3/+Ff3X/hX91/4V/dv+Ff3b/hX92/4V/ + d/+sqKL/xMK//7Oys/+Sk5P/k5GN/7CqnP+5sJv/urGZ/6yllf+Qjor/gIGD/4qJif+0s7D/pqOe/4WB + fP+FgXz///ju///47v//+O7///ju///47v//+O7///ju///47v/Om4D/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA77yQ////////79b///DZ///w2f//8Nr///Hb///x3P//8d3///Le///y3v//8uD///Pg///z + 4f//8+L///Pi///04///9OT///bp//347//i3tr/wsG+/6uqqv+bm5z/mJiY/52dnP+0srD/2tfT//75 + 8///+O3///fr///37P//9+z///fs///47f//+O3///jt///47f//+O3///jt///47f/Om4D/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA8L2R////////7tT//+/W///w2f//8Nr///Da///x2///8dz///Hd///y + 3v//8t////Lg///z4P//8+H///Pi///z4v//9OP///Tk///05P//9un///ju///58f//+vL///rz///6 + 8v//+fD///fs///26f//9ur///bq///36///9+v///fr///37P//9+z///fs///37P//9+z///fs///3 + 7P/Om4D/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8b6S////////7dL//+7U/4V9cP+FfXH/hX1y/4V9 + cv+FfnL/hX5z/4V+c/+FfnT/hX50/4V+df+Ff3X///Ph///z4v+Ff3b/hX92/4V/d/+Ff3f/hX93/4WA + d/+FgHj/hYB4/4WAeP+FgHn/hYB5/4WAef+FgHr///bp///26f+FgHr/hYB6/4WBe/+FgXv/hYF7/4WB + e///9+v///fr///36//PnID/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8r+S////////7ND//+7T/4V8 + b/+FfXD/hX1x/4V9cv+FfXL/hX5y/4V+c/+FfnP/hX50/4V+dP+FfnT///Lg///z4f+Ff3X/hX92/4V/ + dv+Ff3b/hX93/4V/d/+Ff3f/hYB3/4WAeP+FgHj/hYB4/4WAef+FgHn///bo///26f+FgHr/hYB6/4WA + ev+FgHr/hYB6/4WAev//9ur///bq///26v/PnID/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA88CT//// + ////7M7//+3R/4V8bv+FfG//hX1w/4V9cf+FfXL/hX1y/4V+cv+FfnP/hX5z/4V+dP+FfnT///Lf///y + 4P+Ff3X/hX91/4V/dv+Ff3b/hX92/4V/d/+Ff3f/hX93/4V/d/+FgHf/hYB4/4WAeP+FgHj///Xn///1 + 6P+FgHn/hYB5/4WAef+FgHn/hYB6/4WAev//9un///bp///26f/PnID/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA9MGT////////68z//+zP///t0f//7tP//+7V///w2f//8Nn///Da///w2///8dv///Hc///x + 3f//8t7///Le///y3///8uD///Pg///z4f//8+H///Pi///z4v//9OP///Tk///05P//9OX///Tl///1 + 5f//9eb///Xm///15///9ef///Xn///15///9ef///Xo///16P//9ej///Xo///16P/QnYH/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA9sOU////////6sv//+vN///sz///7dH//+7T///u1f//8Nn///DZ///w + 2v//8Nv///Hb///x3P//8d3///Hd///y3v//8t////Lg///y4P//8+H///Ph///z4v//8+L///Pi///0 + 4///9OT///Tk///05P//9OX///Tl///15f//9eb///Xm///15v//9eb///Xn///15///9ef///Xn///1 + 5//QnYH/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA98SU////////6sn//+rL/4V7a/+Fe2z/hXxt/4V8 + bv+FfG//hX1w/4V9cf+FfXL/hX1y/4V+cv+FfnP/hX5z/4V+c/+FfnT/hX50/4V+dP+FfnX/hX91///z + 4f//8+H/hX92/4V/dv+Ff3b/hX92/4V/dv+Ff3f/hX93/4V/d/+Ff3f/hX93/4V/d/+Ff3f/hYB3/4WA + d///9eX///Xl///15f/QnYH/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+MWV////////6cf//+rJ/4V6 + av+Fe2v/hXts/4V8bf+FfG7/hXxv/4V9cP+FfXH/hX1y/4V9cv+FfnL/hX5y/4V+c/+FfnP/hX5z/4V+ + dP+FfnT/hX50///y4P//8+D/hX91/4V/df+Ff3X/hX92/4V/dv+Ff3b/hX92/4V/dv+Ff3f/hX93/4V/ + d/+Ff3f/hX93/4V/d///9OT///Tk///05P/QnYH/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+caW//// + ////6MP//+nH/4V6af+Femr/hXtr/4V7bP+FfG3/hXxu/4V8b/+FfXD/hX1x/4V9cf+FfXL/hX1y/4V+ + cv+FfnP/hX5z/4V+c/+FfnT/hX50///y3///8t//hX51/4V+df+Ff3X/hX91/4V/df+Ff3b/hX92/4V/ + dv+Ff3b/hX92/4V/dv+Ff3b/hX92/4V/dv//9OP///Tj///04//QnYH/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA+seW////////58H//+jE///px///6sn//+rL///rzf//7M///+3R///u0///7tT//+/W///w + 2f//8Nn///Da///w2v//8dv///Hb///x3P//8d3///Hd///y3v//8t7///Lf///y3///8uD///Lg///z + 4P//8+H///Ph///z4f//8+H///Pi///z4v//8+L///Pi///z4v//8+L///Pi///z4v/QnYH/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA+8iX//7y4v//8Nn//+fB///ow///6cf//+rJ///qy///68z//+zO///s + 0P//7dL//+7U///v1v//79f///DZ///w2v//8Nr///Db///x2///8dz///Hc///x3f//8d3///Le///y + 3v//8t7///Lf///y3///8uD///Lg///y4P//8+D///Ph///z4f//8+H///Ph///z4f//8+H///Ph/+7U + v//QnYH/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/MmXo/zJl//+9OX///DZ///nwf//6MP//+jF///p + yP//6sr//+vM///szv//7ND//+3R///u0///7tX//+/X///w2f//8Nn///Da///w2v//8Nv///Hb///x + 3P//8dz///Hd///x3f//8d3///Le///y3v//8t7///Lf///y3///8t////Lg///y4P//8uD///Lg///y + 4P//9+z/9uHN/9Kfgv/PnICjAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP3KmMz8yZf//vLi//// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////15df/0Z6B/9KfgswAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAD8yZej+8iX//rHlv/5xpb/+MWV//fElP/2w5T/9MGT//PAk//yv5L/8b6S//C9kf/vvJD/7ruQ/+26 + j//ruI//6reO/+m2jv/otY3/57SM/+azjP/lsov/5LGL/+Kviv/hror/4K2J/9+siP/eq4j/3aqH/9yp + h//bqIb/2aaG/9ilhf/XpIT/1qOE/9Wig//UoYP/06CCowAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////AAD//////58AAP//////gwAA+AAAAAAD + AADwAAAAAAMAAOAAAAAAAQAA4AAAAAABAADgAAAAAAMAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAA + AAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAH + AADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAA + AAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAH + AADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAA + AAAABwAA4AAAAAAHAADwAAAAAA8AAPgAAAAAHwAA////////AAD///////8AAP///////wAA + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/CommonObjects/EventManager.cs b/Demo_Source_Code/CSharpDemo/CommonObjects/EventManager.cs new file mode 100644 index 0000000..45f8178 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/CommonObjects/EventManager.cs @@ -0,0 +1,440 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Text; +using System.Threading; +using System.IO; +using System.Diagnostics; +using System.Globalization; + + +namespace EaseFilter.CommonObjects +{ + public enum EventLevel + { + Off = 0, + Error = 1, + Warning = 2, + Information = 3, + Verbose = 4, + Trace = 5, + } + + public enum EventOutputType + { + EventView = 0, + File, + Console, + CallbackDelegate, + NamedPipe, + DbgView, + } + + + public class MessageEventArgs : EventArgs + { + EventLevel eventType = EventLevel.Verbose; + string message = string.Empty; + string callerName = string.Empty; + int eventId = 0; + DateTime time = DateTime.MinValue; + + public MessageEventArgs(int eventId, string callerName, EventLevel eventType, string message,DateTime messageTime) + { + this.eventType = eventType; + this.message = message; + this.callerName = callerName; + this.eventId = eventId; + this.time = messageTime; + } + + public DateTime Time + { + get { return time; } + set { time = value; } + } + + public EventLevel Type + { + get { return eventType; } + set { eventType = value; } + } + + public string Message + { + get { return message; } + set { message = value; } + } + + public string CallerName + { + get { return callerName; } + set { callerName = value; } + } + + public int EventID + { + get { return eventId; } + set { eventId = value; } + } + + } + + + public static class EventManager + { + public delegate void ShowNotificationDlgt(string message, bool isErrorMessage); + public static ShowNotificationDlgt showNotificationDlgt = null; + + public delegate void MessageEventDlgt(MessageEventArgs messageEventArg); + + static event MessageEventDlgt messageEventHandler; + static EventLevel level = GlobalConfig.EventLevel; + static EventOutputType output = GlobalConfig.EventOutputType; + static string logFileName = GlobalConfig.EventLogFileName; + static string eventSource = GlobalConfig.EventSource; + static string eventLogName = GlobalConfig.EventLogName; + static EventLog eventLog = null; + // static string PipeName = "MessagePipe"; + + static AutoResetEvent autoEvent = new AutoResetEvent(false); + static Queue messageQueue = new Queue(); + static Thread eventThread = null; + + public static AutoResetEvent logFileSyncEvent = new AutoResetEvent(true); + + static System.Reflection.Assembly assembly = System.Reflection.Assembly.GetEntryAssembly(); + public static string locallAssemblyPath = Path.GetDirectoryName(assembly.Location); + + static char taskStringSeperator = '|'; + + public static string FormatDateTime(DateTime date) + { + return date.ToString("yyyy-MM-ddTHH:mm:ss.fff"); + } + + static EventManager() + { + if (eventThread == null) + { + eventThread = new Thread(new ThreadStart(ProcessMessage)); + eventThread.Name = "EventManagerProcessThread"; + eventThread.Start(); + } + } + + public static void WriteMessage(int eventId, string callerName, EventLevel evnetType, string message) + { + if (evnetType > level) + { + return; + } + + MessageEventArgs messageEventArgs = new MessageEventArgs(eventId, callerName, evnetType, message,DateTime.Now); + + lock(messageQueue) + { + messageQueue.Enqueue(messageEventArgs); + } + + autoEvent.Set(); + + } + + public static string EventSource + { + get { return eventSource; } + set { eventSource = value; } + } + + public static string EventLogName + { + get { return eventLogName; } + set { eventLogName = value; } + } + + public static void Stop() + { + logFileSyncEvent.Set(); + autoEvent.Set(); + + } + + public static MessageEventDlgt MessageEventHandler + { + get { return messageEventHandler; } + set { messageEventHandler = value; } + } + + public static EventLevel Level + { + get { return level; } + set { level = value; } + } + + public static EventOutputType Output + { + get { return output; } + set { output = value; } + } + + public static string LogFileName + { + get { return logFileName; } + set { logFileName = value; } + } + + private static void SendMessageToNamedpipe(MessageEventArgs messageEventArg) + { + try + { + + + } + catch + { + + } + } + + private static string ConvertEventArgToSring(MessageEventArgs messageEventArg) + { + string text = FormatDateTime(messageEventArg.Time) + + taskStringSeperator + messageEventArg.Type + + taskStringSeperator + messageEventArg.EventID + + taskStringSeperator + messageEventArg.CallerName + + taskStringSeperator + messageEventArg.Message; + + return text; + } + + + public static MessageEventArgs ConvertSringToEventArg(string message) + { + string[] strs = message.Split(new char[] { taskStringSeperator }); + + if (strs.Length < 5) + { + //the log message didn't log complete message, skip + return null; + } + + DateTime time = DateTime.ParseExact(strs[0], "yyyy-MM-ddTHH:mm:ss.fff", CultureInfo.InvariantCulture); + EventLevel type = (EventLevel)Enum.Parse(typeof(EventLevel), strs[1]); + int id = int.Parse(strs[2]); + string callerName = strs[3]; + string txt = strs[4]; + + MessageEventArgs messageArg = new MessageEventArgs(id,callerName,type,txt,time); + + return messageArg; + } + + private static void SendMessageToFile(MessageEventArgs messageEventArg) + { + try + { + string logFileFullPath = Path.Combine(locallAssemblyPath, logFileName); + + if (File.Exists(logFileFullPath)) + { + FileInfo fileInfo = new FileInfo(logFileFullPath); + + if (fileInfo.Length > GlobalConfig.MaxEventLogFileSize) + { + if (File.Exists(logFileFullPath + ".1")) + { + File.Delete(logFileFullPath + ".1"); + } + + File.Move(logFileFullPath, logFileFullPath + ".1"); + } + } + + + EventManager.logFileSyncEvent.WaitOne(); + + string text = ConvertEventArgToSring(messageEventArg).Replace("\n", "") + Environment.NewLine; + File.AppendAllText(logFileFullPath, text); + + EventManager.logFileSyncEvent.Set(); + + } + catch (Exception ex) + { + throw (ex); + } + } + + private static void SendMessageToEventView(MessageEventArgs messageEventArg) + { + + try + { + string text = DateTime.Now.ToString("G") + + ":" + messageEventArg.Type + + ":" + messageEventArg.CallerName + + ":" + messageEventArg.Message; + + if (null == eventLog) + { + if (!EventLog.SourceExists(eventSource)) + { + EventLog.CreateEventSource(eventSource, eventLogName); + } + + eventLog = new EventLog(eventLogName, ".", eventSource); + } + + switch (messageEventArg.Type) + { + case EventLevel.Error: + case EventLevel.Warning: + eventLog.WriteEntry(messageEventArg.Message + "\n\n Caller:" + messageEventArg.CallerName + , (EventLogEntryType)messageEventArg.Type, messageEventArg.EventID); + break; + + case EventLevel.Information: + case EventLevel.Verbose: + eventLog.WriteEntry(messageEventArg.Message + "\n\n Caller:" + messageEventArg.CallerName + , EventLogEntryType.Information, messageEventArg.EventID); + break; + } + } + + catch (Exception ex) + { + throw (ex); + } + } + + + static void PrintWarning(string info) + { + ConsoleColor oldColor = Console.ForegroundColor; + Console.ForegroundColor = ConsoleColor.Yellow; + Console.WriteLine(info); + Console.ForegroundColor = oldColor; + } + + static void PrintError(string info) + { + ConsoleColor oldColor = Console.ForegroundColor; + Console.ForegroundColor = ConsoleColor.Red; + Console.WriteLine(info); + Console.ForegroundColor = oldColor; + } + + private static void SendMessageToConsole(MessageEventArgs messageEventArg) + { + try + { + string text = "Id:" + messageEventArg.EventID + + ":" + messageEventArg.CallerName + Environment.NewLine + + messageEventArg.Message + Environment.NewLine; + + if (messageEventArg.Type == EventLevel.Error) + { + PrintError(text); + } + else if (messageEventArg.Type == EventLevel.Warning) + { + PrintWarning(text); + } + else + { + Console.WriteLine(text); + } + } + catch (Exception ex) + { + throw (ex); + } + } + + private static void ProcessMessage() + { + WaitHandle[] waitHandles = new WaitHandle[] { autoEvent , GlobalConfig.StopEvent }; + + while (GlobalConfig.IsRunning) + { + if (messageQueue.Count == 0) + { + int result = WaitHandle.WaitAny(waitHandles); + + if (!GlobalConfig.IsRunning) + { + return; + } + } + + MessageEventArgs message = null; + + lock( messageQueue) + { + if( messageQueue.Count > 0) + { + message = messageQueue.Dequeue(); + } + } + + if (message == null) + { + continue; + } + + try + { + switch (output) + { + case EventOutputType.EventView: SendMessageToEventView(message); break; + case EventOutputType.File: SendMessageToFile(message); break; + case EventOutputType.Console: SendMessageToConsole(message); break; + case EventOutputType.CallbackDelegate: messageEventHandler(message); break; + case EventOutputType.NamedPipe: SendMessageToNamedpipe(message); break; + // case EventOutputType.MessageView: messageForm.AddMessageToEventView(message); break; + case EventOutputType.DbgView: System.Diagnostics.Debug.WriteLine(ConvertEventArgToSring(message)); break; + } + + if (GlobalConfig.EnableNotification && null != showNotificationDlgt && message.Type == EventLevel.Error) + { + showNotificationDlgt(message.Message, true); + } + } + catch (Exception ex) + { + Console.WriteLine("Log message exception:" + ex.Message + ".\r\nMessage:" + message); + } + + if (GlobalConfig.EnableLogTransaction) + { + try + { + SendMessageToFile(message); + } + catch (Exception ex) + { + Console.WriteLine("Write message exception:" + ex.Message + ".\r\nMessage:" + message); + } + } + } + } + } +} diff --git a/Demo_Source_Code/CSharpDemo/CommonObjects/FileIOControlService.cs b/Demo_Source_Code/CSharpDemo/CommonObjects/FileIOControlService.cs new file mode 100644 index 0000000..d93f75f --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/CommonObjects/FileIOControlService.cs @@ -0,0 +1,250 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.IO; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Runtime.InteropServices; +using Microsoft.Win32.SafeHandles; + + +namespace EaseFilter.CommonObjects +{ + public class FilterService + { + public static bool AuthorizeFileAccess(FilterAPI.MessageSendData messageSend, ref FilterAPI.MessageReplyData messageReply) + { + bool ret = true; + + try + { + messageReply.MessageId = messageSend.MessageId; + messageReply.MessageType = messageSend.MessageType; + messageReply.ReturnStatus = (uint)FilterAPI.NTSTATUS.STATUS_SUCCESS; + + messageReply.MessageId = messageSend.MessageId; + messageReply.MessageType = messageSend.MessageType; + + // + //here you can control all the registered IO requests,block the access or modify the I/O data base on the file IO information from MessageSend struture + // + // + + //if you don't want to change anything to this IO request, just let it pass through as below setting: + //messageReply.FilterStatus = 0; + //messageReply.ReturnStatus = (uint)NtStatus.Status.Success; + + //if you want to block the access this IO request before it goes down to the file system, you can return the status as below, + //it is only for pre IO requests, it means the user IO reuqests will be completed here instead of going down to the file system. + //messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION; + //messageReply.ReturnStatus = (uint)NtStatus.Status.AccessDenied; + + //if you want to modify the IO data and complete the pre IO with your own data, you can return status as below: + // messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION | (uint)FilterAPI.FilterStatus.FILTER_DATA_BUFFER_IS_UPDATED; + // messageReply.DataBufferLength = the return data buffer length. + // messageReply.DataBuffer = the data you want to return. + // messageReply.ReturnStatus = (uint)NtStatus.Status.Success; + + FilterAPI.MessageType messageType = (FilterAPI.MessageType)messageSend.MessageType; + WinData.FileInfomationClass infoClass = (WinData.FileInfomationClass)messageSend.InfoClass; + + uint dataLength = messageSend.DataBufferLength; + byte[] data = messageSend.DataBuffer; + + //here is some IO information for your reference: + if ((messageSend.CreateOptions & (uint)WinData.CreateOptions.FO_REMOTE_ORIGIN) > 0) + { + //this is file access request comes from remote network server + } + + //you can check the file create option with this data: + //"DesiredAccess: messageSend.DesiredAccess + //"Disposition:" + ((WinData.Disposition)messageSend.Disposition).ToString(); + //"ShareAccess:" + ((WinData.ShareAccess)messageSend.SharedAccess).ToString(); + //"CreateOptions:"messageSend.CreateOptions + + + //Here is the demo to copy file content before it was deleted.----------------------------------------------- + bool isFileDeleting = false; + if (messageSend.Status == (uint)NtStatus.Status.Success) + { + if (messageType == FilterAPI.MessageType.POST_CREATE) + { + if ((messageSend.CreateOptions & (uint)WinData.CreateOptions.FILE_DELETE_ON_CLOSE) > 0) + { + isFileDeleting = true; + } + } + else if (messageType == FilterAPI.MessageType.PRE_SET_INFORMATION) + { + if (infoClass == WinData.FileInfomationClass.FileDispositionInformation) + { + isFileDeleting = true; + } + } + + if (isFileDeleting) + { + + //IntPtr fileHandle = IntPtr.Zero; + //bool retVal = FilterAPI.GetFileHandleInFilter(messageSend.FileName,(uint)FileAccess.Read, ref fileHandle); + //if (retVal) + //{ + // SafeFileHandle sHandle = new SafeFileHandle(fileHandle, true); + // FileStream fileStream = new FileStream(sHandle, FileAccess.Read); + + // //copy your data here... + + // fileStream.Close(); + //} + + } + } + //End ----------------------------------------------- + + + + switch (messageType) + { + case FilterAPI.MessageType.PRE_CREATE: + { + + //here you reparse the file open to another new file name + + //string newReparseFileName = "\\??\\c:\\myNewFile.txt"; + //byte[] returnData = Encoding.Unicode.GetBytes(newReparseFileName); + //Array.Copy(returnData, messageReply.DataBuffer, returnData.Length); + //messageReply.DataBufferLength = (uint)returnData.Length; + //messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION; + //messageReply.ReturnStatus = (uint)NtStatus.Status.Reparse; + + break; + } + + + case FilterAPI.MessageType.PRE_CACHE_READ: + case FilterAPI.MessageType.POST_CACHE_READ: + case FilterAPI.MessageType.PRE_NOCACHE_READ: + case FilterAPI.MessageType.POST_NOCACHE_READ: + case FilterAPI.MessageType.PRE_PAGING_IO_READ: + case FilterAPI.MessageType.POST_PAGING_IO_READ: + case FilterAPI.MessageType.PRE_CACHE_WRITE: + case FilterAPI.MessageType.POST_CACHE_WRITE: + case FilterAPI.MessageType.PRE_NOCACHE_WRITE: + case FilterAPI.MessageType.POST_NOCACHE_WRITE: + case FilterAPI.MessageType.PRE_PAGING_IO_WRITE: + case FilterAPI.MessageType.POST_PAGING_IO_WRITE: + { + + + //byte[] returnData = //new data you want to modify the read/write data; + //Array.Copy(returnData, messageReply.DataBuffer, returnData.Length); + //messageReply.DataBufferLength = (uint)returnData.Length; + + ////for pre IO,use this one + //// messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION | (uint)FilterAPI.FilterStatus.FILTER_DATA_BUFFER_IS_UPDATED; + + // messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_DATA_BUFFER_IS_UPDATED; + // messageReply.ReturnStatus = (uint)NtStatus.Status.Success; + + + break; + } + case FilterAPI.MessageType.PRE_SET_INFORMATION: + case FilterAPI.MessageType.POST_SET_INFORMATION: + case FilterAPI.MessageType.PRE_QUERY_INFORMATION: + case FilterAPI.MessageType.POST_QUERY_INFORMATION: + { + switch (infoClass) + { + case WinData.FileInfomationClass.FileRenameInformation: + { + if (FilterAPI.MessageType.PRE_SET_INFORMATION == messageType) + { + string blockFileName = @"c:\filterTest\blockRename.txt"; + //test block rename to blockFileName, it needs to register PRE_SET_INFORMATION; + if (string.Compare(messageSend.FileName, blockFileName, true) == 0) + { + EventManager.WriteMessage(179, "IOAccessControl", EventLevel.Warning, "Block rename for file:" + messageSend.FileName); + ret = false; + break; + } + } + + //you can block file rename as below + //messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION; + //messageReply.ReturnStatus = (uint)NtStatus.Status.AccessDenied; + break; + } + case WinData.FileInfomationClass.FileDispositionInformation: + { + //you can block file delete as below + //messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION; + //messageReply.ReturnStatus = (uint)NtStatus.Status.AccessDenied; + break; + } + case WinData.FileInfomationClass.FileEndOfFileInformation: + { + //change file size + break; + } + case WinData.FileInfomationClass.FileBasicInformation: + { + //file basic information + break; + } + + case WinData.FileInfomationClass.FileStandardInformation: + { + //file standard information + break; + } + case WinData.FileInfomationClass.FileNetworkOpenInformation: + { + //file network information + break; + } + + case WinData.FileInfomationClass.FileInternalInformation: + { + //file internal inofrmation + break; + } + default: + { + break; + } + } + + break; + } + } + + + } + catch (Exception ex) + { + EventManager.WriteMessage(174, "IOAccessControl", EventLevel.Error, "IOAccessControl failed." + ex.Message); + } + + return ret; + } + + } +} diff --git a/Demo_Source_Code/CSharpDemo/CommonObjects/FilterAPI.cs b/Demo_Source_Code/CSharpDemo/CommonObjects/FilterAPI.cs new file mode 100644 index 0000000..013e666 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/CommonObjects/FilterAPI.cs @@ -0,0 +1,2275 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.Text; +using System.IO; +using System.Collections; +using System.Collections.Generic; +using Microsoft.Win32.SafeHandles; +using System.Runtime.InteropServices; +using System.Security.Principal; +using System.Security.Cryptography; + + +namespace EaseFilter.CommonObjects +{ + + static public class FilterAPI + { + public delegate Boolean FilterDelegate(IntPtr sendData, IntPtr replyData); + public delegate void DisconnectDelegate(); + static GCHandle gchFilter; + static GCHandle gchDisconnect; + static bool isFilterStarted = false; + public const int MAX_FILE_NAME_LENGTH = 1024; + public const int MAX_SID_LENGTH = 256; + public const int MAX_MESSAGE_LENGTH = 65536; + public const int MAX_PATH = 260; + public const int MAX_ERROR_MESSAGE_SIZE = 1024; + public const uint MESSAGE_SEND_VERIFICATION_NUMBER = 0xFF000001; + public const uint GENERIC_WRITE = 0x40000000; + public const uint AES_TAG_KEY = 0xccb76e80; + + public const uint FILE_FLAG_OPEN_REPARSE_POINT = 0x00200000; + public const uint FILE_FLAG_OPEN_NO_RECALL = 0x00100000; + public const uint FILE_FLAG_NO_BUFFERING = 0x20000000; + public const uint FILE_ATTRIBUTE_REPARSE_POINT = (uint)FileAttributes.ReparsePoint; + + static Dictionary userNameTable = new Dictionary(); + static Dictionary processNameTable = new Dictionary(); + + //for encryption default IV key + public static byte[] DEFAULT_IV_TAG = { 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff }; + + public enum FilterType : byte + { + /// + /// File system control filter driver + /// + FILE_SYSTEM_CONTROL = 0x01, + /// + /// File system encryption filter driver + /// + FILE_SYSTEM_ENCRYPTION = 0x02, + /// + /// File system monitor filter driver + /// + FILE_SYSTEM_MONITOR = 0x04, + /// + /// File system registry filter driver + /// + FILE_SYSTEM_REGISTRY = 0x08, + /// + /// File system process filter driver + /// + FILE_SYSTEM_PROCESS = 0x10, + /// + /// File system hierarchical storage management filter driver + /// + FILE_SYSTEM_HSM = 0x40, + /// + /// File system cloud storage filter driver + /// + FILE_SYSTEM_CLOUD = 0x80, + } + + public enum EncryptionMethod : uint + { + /// + /// Use the same encryption key and iv from the filter rule for all files, there are no reparse point tag data added to encrypted file, + /// it supports all file systems. You can't identify if the file is encrypted or not by API. + /// + ENCRYPT_FILE_WITH_SAME_KEY_AND_IV = 0, + /// + /// Use the same encryption key from the filter rule for all files, use unique iv key per file, a meta data header will be appended to the + /// end of the encyrpted file. You can identify if the file is encrypted by checking the header. + /// + ENCRYPT_FILE_WITH_SAME_KEY_AND_UNIQUE_IV, + /// + ///Use the encryption key and iv from the user mode service,you can control how to use encryption key and iv per file. + /// + ENCRYPT_FILE_WITH_KEY_AND_IV_FROM_SERVICE, + /// + ///Use the same encryption key from the filter rule for all files, use unique iv key per file, a meta data tag will be embeded to the + /// the encyrpted file in the reparse point tag extended attribute. You can identify if the file is encrypted by checking the reparse point tag. + /// + ENCRYPT_FILE_WITH_REPARSE_POINT_DATA, + } + + public enum BooleanConfig : uint + { + /// + ///for easetag, if it was true, after the reparsepoint file was opened, it won't restore data back for read and write. + /// + ENABLE_NO_RECALL_FLAG = 0x00000001, + /// + /// if it is true, the filter driver can't be unloaded. + /// + DISABLE_FILTER_UNLOAD_FLAG = 0x00000002, + /// + /// for virtual file, it will set offline attribute if it is true. + /// + ENABLE_SET_OFFLINE_FLAG = 0x00000004, + /// + /// for encryption, it is true, it will use the default IV tag to encrypt the files. + /// + ENABLE_DEFAULT_IV_TAG = 0x00000008, + /// + /// if it is enabled, it will send the message data to a persistent file, or it will send the event to service right away. + /// + ENABLE_ADD_MESSAGE_TO_FILE = 0x00000010, + /// + /// the encrypted file's meta data was embeded in the reparse point tag. + /// + ENCRYPT_FILE_WITH_REPARSE_POINT_TAG = 0x00000020, + /// + /// for encryption rule, get the encryption key and IV from user mode for the encrypted files. + /// + REQUEST_ENCRYPT_KEY_AND_IV_FROM_SERVICE = 0x00000040, + /// + /// for control filter, if it is enabled, the control filte rulle will be applied in boot time. + /// + ENABLE_PROTECTION_IN_BOOT_TIME = 0x00000080, + /// + /// for encryption rule, get the encryption key and IV and tag data which will attach to the file. + /// + REQUEST_ENCRYPT_KEY_IV_AND_TAGDATA_FROM_SERVICE = 0x00000100, + /// + /// if it is enabled, it will send the read/write databuffer to user mode. + /// + ENABLE_SEND_DATA_BUFFER = 0x00000200, + /// + /// if it is enabled, it will reopen the file when rehydration of the stub file. + /// + ENABLE_REOPEN_FILE_ON_REHYDRATION = 0x00000400, + + } + + /// + /// The command sent by filter driver + /// + public enum FilterCommand + { + /// + /// send the notification event of the file was changed. + /// + FILTER_SEND_FILE_CHANGED_EVENT = 0x00010001, + /// + /// request the file open permission. + /// + FILTER_REQUEST_USER_PERMIT = 0x00010002, + /// + /// request the encryption key for the file open or creation. + /// + FILTER_REQUEST_ENCRYPTION_KEY = 0x00010003, + /// + /// request the encryption iv and key for the encrypted file open or to encrypt the file + /// + FILTER_REQUEST_ENCRYPTION_IV_AND_KEY = 0x00010004, + /// + /// request the encryption iv, key and access flags for the encrypted file open or to encrypt the file + /// + FILTER_REQUEST_ENCRYPTION_IV_AND_KEY_AND_ACCESSFLAG = 0x00010005, + /// + /// request the encryption iv, key and access flags and tag data for file encryption + /// + FILTER_REQUEST_ENCRYPTION_IV_AND_KEY_AND_TAGDATA = 0x00010006, + /// + /// send the registry access notification class information + /// + FILTER_SEND_REG_CALLBACK_INFO = 0x00010007, + /// + /// send the new process creation information + /// + FILTER_SEND_PROCESS_CREATION_INFO = 0x00010008, + /// + /// send the process termination ifnormation + /// + FILTER_SEND_PROCESS_TERMINATION_INFO = 0x00010009, + /// + /// send the new thread creation information + /// + FILTER_SEND_THREAD_CREATION_INFO = 0x0001000a, + /// + /// send the thread termination ifnormation + /// + FILTER_SEND_THREAD_TERMINATION_INFO = 0x0001000b, + /// + /// send the process handle operations information + /// + FILTER_SEND_PROCESS_HANDLE_INFO = 0x0001000c, + /// + /// send the thread handle operations ifnormation + /// + FILTER_SEND_THREAD_HANDLE_INFO = 0x0001000d, + /// + /// send the volume information when it was attached + /// + FILTER_SEND_ATTACHED_VOLUME_INFO = 0x0001000e, + /// + /// send the volume information when it was detached + /// + FILTER_SEND_DETACHED_VOLUME_INFO = 0x0001000f, + + } + + + /// + /// the message type of the filter driver send the file IO request + /// + public enum MessageType : uint + { + PRE_CREATE = 0x00000001, + POST_CREATE = 0x00000002, + PRE_FASTIO_READ = 0x00000004, + POST_FASTIO_READ = 0x00000008, + PRE_CACHE_READ = 0x00000010, + POST_CACHE_READ = 0x00000020, + PRE_NOCACHE_READ = 0x00000040, + POST_NOCACHE_READ = 0x00000080, + PRE_PAGING_IO_READ = 0x00000100, + POST_PAGING_IO_READ = 0x00000200, + PRE_FASTIO_WRITE = 0x00000400, + POST_FASTIO_WRITE = 0x00000800, + PRE_CACHE_WRITE = 0x00001000, + POST_CACHE_WRITE = 0x00002000, + PRE_NOCACHE_WRITE = 0x00004000, + POST_NOCACHE_WRITE = 0x00008000, + PRE_PAGING_IO_WRITE = 0x00010000, + POST_PAGING_IO_WRITE = 0x00020000, + PRE_QUERY_INFORMATION = 0x00040000, + POST_QUERY_INFORMATION = 0x00080000, + PRE_SET_INFORMATION = 0x00100000, + POST_SET_INFORMATION = 0x00200000, + PRE_DIRECTORY = 0x00400000, + POST_DIRECTORY = 0x00800000, + PRE_QUERY_SECURITY = 0x01000000, + POST_QUERY_SECURITY = 0x02000000, + PRE_SET_SECURITY = 0x04000000, + POST_SET_SECURITY = 0x08000000, + PRE_CLEANUP = 0x10000000, + POST_CLEANUP = 0x20000000, + PRE_CLOSE = 0x40000000, + POST_CLOSE = 0x80000000, + + } + + /// + /// the file IO event type will be sent by the filter driver if the IO was happened. + /// + public enum EVENTTYPE : uint + { + NONE = 0, + CREATED = 0x00000020, + WRITTEN = 0x00000040, + RENAMED = 0x00000080, + DELETED = 0x00000100, + SECURITY_CHANGED = 0x00000200, + INFO_CHANGED = 0x00000400, + READ = 0x00000800, + } + + public enum NTSTATUS : uint + { + STATUS_SUCCESS = 0, + STATUS_UNSUCCESSFUL = 0xc0000001, + STATUS_ACCESS_DENIED = 0xC0000022, + } + + /// + /// The maximum file access right + /// + public const uint ALLOW_MAX_RIGHT_ACCESS = 0xfffffff0; + + /// + /// The change file access right + /// + public const uint ALLOW_FILE_CHANGE_ACCESS = (uint)(AccessFlag.ALLOW_WRITE_ACCESS + | AccessFlag.ALLOW_FILE_DELETE + | AccessFlag.ALLOW_FILE_SIZE_CHANGE + | AccessFlag.ALLOW_OPEN_WITH_CREATE_OR_OVERWRITE_ACCESS + | AccessFlag.ALLOW_OPEN_WITH_DELETE_ACCESS + | AccessFlag.ALLOW_SET_INFORMATION + | AccessFlag.ALLOW_SET_SECURITY_ACCESS + | AccessFlag.ALLOW_FILE_RENAME); + + /// + /// The read file access right + /// + public const uint ALLOW_FILE_READ_ACCESS = (uint)(AccessFlag.ALLOW_OPEN_WITH_READ_ACCESS + |AccessFlag.ALLOW_READ_ACCESS + |AccessFlag.ALLOW_QUERY_INFORMATION_ACCESS + |AccessFlag.ALLOW_QUERY_SECURITY_ACCESS + |AccessFlag.ALLOW_FILE_MEMORY_MAPPED + |AccessFlag.ALLOW_DIRECTORY_LIST_ACCESS + |AccessFlag.ALLOW_READ_ENCRYPTED_FILES ); + + /// + /// control the access rights of the file IO,set the accessFlag to LEAST_ACCESS_FLAG if you want to least access rights to the files. + /// + public enum AccessFlag : uint + { + /// + /// Filter driver will skip all the IO when the accessFlag equal 0 if the file name match the include file mask. + /// + EXCLUDE_FILTER_RULE = 0X00000000, + /// + /// Block the file open. + /// + EXCLUDE_FILE_ACCESS = 0x00000001, + /// + /// Reparse the file open to the new file name if the reparse file mask was added. + /// + ENABLE_REPARSE_FILE_OPEN = 0x00000002, + /// + /// Hide the files from the folder directory list if the hide file mask was added. + /// + ENABLE_HIDE_FILES_IN_DIRECTORY_BROWSING = 0x00000004, + /// + /// Enable the transparent file encryption if the encryption key was added. + /// + ENABLE_FILE_ENCRYPTION_RULE = 0x00000008, + /// + /// Allow the file open to access the file's security information. + /// + ALLOW_OPEN_WTIH_ACCESS_SYSTEM_SECURITY = 0x00000010, + /// + /// Allow the file open for read access. + /// + ALLOW_OPEN_WITH_READ_ACCESS = 0x00000020, + /// + /// Allow the file open for write access. + /// + ALLOW_OPEN_WITH_WRITE_ACCESS = 0x00000040, + /// + /// Allow the file open for create new file or overwrite access. + /// + ALLOW_OPEN_WITH_CREATE_OR_OVERWRITE_ACCESS = 0x00000080, + /// + /// Allow the file open for delete. + /// + ALLOW_OPEN_WITH_DELETE_ACCESS = 0x00000100, + /// + /// Allow to read the file data. + /// + ALLOW_READ_ACCESS = 0x00000200, + /// + /// Allow write data to the file. + /// + ALLOW_WRITE_ACCESS = 0x00000400, + /// + /// Allow to query file information. + /// + ALLOW_QUERY_INFORMATION_ACCESS = 0x00000800, + /// + /// Allow to change the file information:file attribute,file size,file name,delete file + /// + ALLOW_SET_INFORMATION = 0x00001000, + /// + /// Allow to rename the file. + /// + ALLOW_FILE_RENAME = 0x00002000, + /// + /// Allow to delete the file. + /// + ALLOW_FILE_DELETE = 0x00004000, + /// + /// Allow to change file size. + /// + ALLOW_FILE_SIZE_CHANGE = 0x00008000, + /// + /// Allow query the file security information. + /// + ALLOW_QUERY_SECURITY_ACCESS = 0x00010000, + /// + /// Allow change the file security information. + /// + ALLOW_SET_SECURITY_ACCESS = 0x00020000, + /// + /// Allow to browse the directory file list. + /// + ALLOW_DIRECTORY_LIST_ACCESS = 0x00040000, + /// + /// Allow the remote access via share folder. + /// + ALLOW_FILE_ACCESS_FROM_NETWORK = 0x00080000, + /// + /// Allow to encrypt the new file if the encryption filter rule is enabled, . + /// + ALLOW_ENCRYPT_NEW_FILE = 0x00100000, + /// + /// Allow the application to read the encrypted files, or it will return encrypted data. + /// + ALLOW_READ_ENCRYPTED_FILES = 0x00200000, + /// + /// Allow the application to create a new file after it opened the protected file. + /// + ALLOW_ALL_SAVE_AS = 0x00400000, + /// + /// Allow copy protected files out of the protected folder if ALLOW_ALL_SAVE_AS is enabled. + /// + ALLOW_COPY_PROTECTED_FILES_OUT = 0x00800000, + /// + /// Allow the file to be mapped into memory access. + /// + ALLOW_FILE_MEMORY_MAPPED = 0x01000000, + /// + /// if the encryption filter rule is enabled, it will encrypt unencrypted data on read when the flag value is 0. + /// + DISABLE_ENCRYPT_DATA_ON_READ = 0x02000000, + /// + /// If it is not exclude filter rule,the access flag can't be 0, at least you need to include this flag + /// for filter driver to process this filter rule. + /// + LEAST_ACCESS_FLAG = 0xf0000000, + // ALLOW_MAX_RIGHT_ACCESS = 0xfffffff0, + } + + const uint AES_VERIFICATION_KEY = 0xccb76e80; + const int default_header_size = 1024; + + /// + /// this is the header structure of the encrypted file + /// + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + public struct AES_HEADER + { + public uint VerificationKey; + public uint AESFlags; + public uint Version; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] + public byte[] IV; + public uint EncryptionKeyLength; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] + public byte[] EncryptionKey; + public long FileSize; + public uint CryptoType; + public uint PaddingSize; + //the size of this data structure + public uint AESDataSize; + //the actual physical file size in disk including the padding and the header. + public long ShadowFileSize; + public uint AccessFlags; + public uint Reserve1; + public uint Reserve2; + public uint TagDataLength; + /// + /// the maximum tag data size if the header size - sizeof(AES_HEADER); + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = default_header_size)] + public byte[] TagData; + + }; + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + public struct MessageSendData + { + public uint MessageId; //this is the request sequential number. + public IntPtr FileObject; //the address of FileObject,it is equivalent to file handle,it is unique per file stream open. + public IntPtr FsContext; //the address of FsContext,it is unique per file. + public uint MessageType; //the I/O request type. + public uint ProcessId; //the process ID for the process associated with the thread that originally requested the I/O operation. + public uint ThreadId; //the thread ID which requested the I/O operation. + public long Offset; //the read/write offset. + public uint Length; //the read/write length. + public long FileSize; //the size of the file for the I/O operation. + public long TransactionTime; //the transaction time in UTC of this request. + public long CreationTime; //the creation time in UTC of the file. + public long LastAccessTime; //the last access time in UTC of the file. + public long LastWriteTime; //the last write time in UTC of the file. + public uint FileAttributes; //the file attributes. + public uint DesiredAccess; //the DesiredAccess for file open, please reference CreateFile windows API. + public uint Disposition; //the Disposition for file open, please reference CreateFile windows API. + public uint SharedAccess; //the SharedAccess for file open, please reference CreateFile windows API. + public uint CreateOptions; //the CreateOptions for file open, please reference CreateFile windows API. + public uint CreateStatus; //the CreateStatus after file was openned, please reference CreateFile windows API. + public uint InfoClass; //the information class or security information + public uint Status; //the I/O status which returned from file system. + public uint FileNameLength; //the file name length in byte. + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_FILE_NAME_LENGTH)] + public string FileName; //the file name of the I/O operation. + public uint SidLength; //the length of the security identifier. + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_SID_LENGTH)] + public byte[] Sid; //the security identifier data. + public uint DataBufferLength; //the data buffer length. + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_MESSAGE_LENGTH)] + public byte[] DataBuffer; //the data buffer which contains read/write/query information/set information data. + public uint VerificationNumber; //the verification number which verifiys the data structure integerity. + } + + + /// + /// The attached volume control flag. + /// + public enum VolumeControlFlag : uint + { + /// + /// Get all the attached volumes' information. + /// + GET_ATTACHED_VOLUME_INFO = 0x00000001, + /// + /// Get a notification when the filter driver attached to a volume. + /// + VOLUME_ATTACHED_NOTIFICATION = 0x00000002, + /// + /// Get a notification when the filter driver detached from a volume. + /// + VOLUME_DETACHED_NOTIFICATION = 0x00000004, + /// + /// Prevent the attched volumes from being formatted or dismounted. + /// + BLOCK_VOLUME_DISMOUNT = 0x00000008, + + } + + /// + /// the structure of the attached volume information + /// + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + public struct VOLUME_INFO + { + /// + /// The length of the volume name. + /// + public uint VolumeNameLength; + /// + /// The volume name buffer. + /// + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_FILE_NAME_LENGTH)] + public string VolumeName; + /// + /// The length of the volume dos file name. + /// + public uint VolumeDosNameLength; + /// + /// The volume dos file name buffer. + /// + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_FILE_NAME_LENGTH)] + public string VolumeDosName; + /// + ///the volume file system type. + /// + public uint VolumeFilesystemType; + /// + ///the Characteristics of the attached device object if existed. + /// + public uint DeviceCharacteristics; + + } + + /// + /// Set the volume control to get the notification of the attached volume information. + /// + /// + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool SetVolumeControlFlag(uint volumeControlFlag); + + /// + /// the data structuct sent by the process filter driver + /// + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + public struct PROCESS_INFO + { + /// + ///this is the request sequential number. + /// + public uint MessageId; + /// + /// reserve data + /// + public IntPtr reserve1; + /// + /// reserve data + /// + public IntPtr reserve2; + /// + ///the process message type. + /// + public uint MessageType; + /// + ///the transaction time in UTC of this message. + /// + public long TransactionTime; + /// + //the current process ID of the process. + /// + public uint ProcessId; + /// + ///the thread ID of the current operation thread. + /// + public uint ThreadId; + /// + ///The process ID of the parent process for the new process. Note that the parent process is not necessarily the same process as the process that created the new process. + /// + public uint ParentProcessId; + /// + /// The process ID of the process that created the new process. + /// + public uint CreatingProcessId; + /// + /// The thread ID of the thread that created the new process. + /// + public uint CreatingThreadId; + /// + ///An ACCESS_MASK value that specifies the access rights to grant for the handle + /// + public uint DesiredAccess; + /// + ///The type of handle operation. This member might be one of the following values:OB_OPERATION_HANDLE_CREATE,OB_OPERATION_HANDLE_DUPLICATE + /// + public uint Operation; + /// + /// A Boolean value that specifies whether the ImageFileName member contains the exact file name that is used to open the process executable file. + /// + public bool FileOpenNameAvailable; + /// + ///the length of the security identifier. + /// + public uint SidLength; + /// + ///the security identifier data. + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_SID_LENGTH)] + public byte[] Sid; + /// + /// The length of the image file name. + /// + public uint ImageFileNameLength; + /// + /// The file name of the executable. If the FileOpenNameAvailable member is TRUE, the string specifies the exact file name that is used to open the executable file. + /// If FileOpenNameAvailable is FALSE, the operating system might provide only a partial name. + /// + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_FILE_NAME_LENGTH)] + public string ImageFileName; + /// + /// The length of the command line. + /// + public uint CommandLineLength; + /// + /// The command that is used to execute the process. + /// + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_FILE_NAME_LENGTH)] + public string CommandLine; + /// + ///the status which returned from file system. + /// + public uint Status; + /// + ///the verification number which verifiys the data structure integerity. + /// + public uint VerificationNumber; + } + + /// + /// the filter status which will be returned to the filter driver, + /// the filter driver will process the IO based the return status. + /// + public enum FilterStatus : uint + { + FILTER_MESSAGE_IS_DIRTY = 0x00000001, //the data buffer was updated. + FILTER_COMPLETE_PRE_OPERATION = 0x00000002, //ONLY FOR PRE CALL OPERATION,the IO won't pass down to the lower drivers and file system. + FILTER_DATA_BUFFER_IS_UPDATED = 0x00000004, //only for pre create,to reparse the file open to the new file name. + BLOCK_DATA_WAS_RETURNED = 0x00000008, //Set this flag if return read block databuffer to filter. + CACHE_FILE_WAS_RETURNED = 0x00000010, //Set this flag if the stub file was restored. + } + + /// + /// this is the data structure which will be returned back to the filter driver. + /// + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + public struct MessageReplyData + { + public uint MessageId; + public uint MessageType; + public uint ReturnStatus; + public uint FilterStatus; + public uint DataBufferLength; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 65536)] + public byte[] DataBuffer; + } + + /// + /// set the filter driver boolean config setting based on the enum booleanConfig + /// + /// + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool SetBooleanConfig(uint booleanConfig); + + /// + /// install the filter driver service, it request the administrator privilege + /// + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool InstallDriver(); + + /// + /// uninstall the filter driver service. + /// + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool UnInstallDriver(); + + /// + /// to check if the filter driver service is running. + /// + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool IsDriverServiceRunning(); + + /// + /// set the registration key to enable the filter driver service. + /// + /// + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool SetRegistrationKey([MarshalAs(UnmanagedType.LPStr)]string key); + + /// + /// disconnect the communication channel of the filter driver. + /// + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool Disconnect(); + + /// + /// get the last error message if the filter driver API return false. + /// + /// + /// + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool GetLastErrorMessage( + [MarshalAs(UnmanagedType.LPWStr)] + string lastError, + ref int messageLength); + + /// + /// start the filter driver service with callback settings + /// + /// the number of working threads waitting for the callback message + /// the callback function + /// the disconnect callback function + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool RegisterMessageCallback( + int threadCount, + IntPtr filterCallback, + IntPtr disconnectCallback); + + /// + /// reset the filter driver config settings to the default value. + /// + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool ResetConfigData(); + + /// + /// set the filter driver type. + /// + /// + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool SetFilterType(uint filterType); + + /// + /// set the maiximun wait time of the filter driver sending message to service. + /// + /// + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool SetConnectionTimeout(uint timeOutInSeconds); + + /// + /// Add the new filter rule to the filter driver. + /// + /// access control rights of the file IO to the files which match the filter mask + /// the filter rule file filter mask, it must be unique. + /// if it is true, the filter rule will be added to the registry, get protection in boot time. + /// the id to identify the filter rule, it will show up in messageId field of messageSend structure if the callback is registered + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AddFileFilterRule( + uint accessFlag, + [MarshalAs(UnmanagedType.LPWStr)]string filterMask, + bool isResident, + uint filterRuleId ); + + + /// + ///Set an encryption folder, every encrypted file has the unique iv key, + ///the encrypted information was embedded into to the file as an extended attribute called reparse point, + ///it only can be supported in NTFS. The same folder can mix encrypted files and unencrypted files, + ///the filter driver will know if the file was encrypted by checking the file reparse point attribute. + ///Since the reparse point attribute can’t be transferred, the encrypted file can’t be shared or copied outside of your computer with normal method, + ///you need to append the reparse point data to the end of the file, and recreate the new reparse point data to the new file after you copied it to the new computer. + /// + /// + /// + /// + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AddEncryptionKeyToFilterRule( + [MarshalAs(UnmanagedType.LPWStr)]string filterMask, + uint encryptionKeyLength, + byte[] encryptionKey); + + /// + ///Set an encryption folder, assume all files inside the folder were encrypted, all encrypted files use the same encryption key and IV key. + ///The encryption file doesn’t embed any encryption information, you can’t tell if the file was encrypted or not by checking the file information, + ///you can share or transfer the encrypted file without limitation. To check if the file was encrypted, you need to stop the encryption filter driver service, + ///then open the encrypted file, you will get cipher data instead of the clear data. + /// + /// + /// + /// + /// + /// + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AddEncryptionKeyAndIVToFilterRule( + [MarshalAs(UnmanagedType.LPWStr)]string filterMask, + uint encryptionKeyLength, + byte[] encryptionKey, + uint ivLength, + byte[] iv); + + /// + /// Exclude the file IO from this filter rule if the files match the excludeFileFilterMask. + /// + /// the filter rule file filter mask + /// the file filter mask for the excluded files + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AddExcludeFileMaskToFilterRule( + [MarshalAs(UnmanagedType.LPWStr)]string filterMask, + [MarshalAs(UnmanagedType.LPWStr)]string excludeFileFilterMask); + + /// + /// Hide the files from the browsing file list for the filter rule. + /// + /// the filter rule file filter mask. + /// the file filter mask for the hidden files. + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AddHiddenFileMaskToFilterRule( + [MarshalAs(UnmanagedType.LPWStr)]string filterMask, + [MarshalAs(UnmanagedType.LPWStr)]string hiddenFileFilterMask); + + /// + /// reparse the file open to the other file if the file matches the file filter mask. + /// + ///For example: + ///FilterMask = c:\test\*txt + ///ReparseFilterMask = d:\reparse\*doc + ///If you open file c:\test\MyTest.txt, it will reparse to the file d:\reparse\MyTest.doc. + /// + /// the filter rule file filter mask + /// reparse file filter mask + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AddReparseFileMaskToFilterRule( + [MarshalAs(UnmanagedType.LPWStr)]string filterMask, + [MarshalAs(UnmanagedType.LPWStr)]string reparseFileFilterMask); + + /// + /// only manage the IO of the filter rule for the processes in the included process list + /// + /// the file filter mask of the filter rule + /// the include process name filter mask, process name format:notepad.exe + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AddIncludeProcessNameToFilterRule( + [MarshalAs(UnmanagedType.LPWStr)]string filterMask, + [MarshalAs(UnmanagedType.LPWStr)]string processName); + + /// + /// skip the IO of the filter rule for the processes in the excluded process list + /// + /// the file filter mask of the filter rule + /// the include process name filter mask + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AddExcludeProcessNameToFilterRule( + [MarshalAs(UnmanagedType.LPWStr)]string filterMask, + [MarshalAs(UnmanagedType.LPWStr)]string processName); + + /// + /// only manage the IO of the filter rule for the processes in the included process id list + /// + /// the file filter mask of the filter rule + /// the included process Id + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AddIncludeProcessIdToFilterRule( + [MarshalAs(UnmanagedType.LPWStr)]string filterMask, + uint includeProcessId); + + /// + /// skip the IO of the filter rule for the processes in the excluded process id list + /// + /// the file filter mask of the filter rule + /// the excluded process Id + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AddExcludeProcessIdToFilterRule( + [MarshalAs(UnmanagedType.LPWStr)]string filterMask, + uint excludeProcessId); + + /// + /// only manage the IO of the filter rule for user name in the included user name list + /// + /// the file filter mask of the filter rule + /// the included user name, format:domainName(or computerName)\userName.exe + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AddIncludeUserNameToFilterRule( + [MarshalAs(UnmanagedType.LPWStr)]string filterMask, + [MarshalAs(UnmanagedType.LPWStr)]string userName); + + /// + ///skip the IO of the filter rule for user name in the excluded user name list + /// + /// the file filter mask of the filter rule + /// the excluded user name, format:domainName(or computerName)\userName.exe + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AddExcludeUserNameToFilterRule( + [MarshalAs(UnmanagedType.LPWStr)]string filterMask, + [MarshalAs(UnmanagedType.LPWStr)]string userName); + + /// + /// Register the I/O event types for the filter rule, get the notification when the I/O was triggered. + /// + /// the file filter mask of the filter rule + /// the I/O event types,reference the FileEventType enumeration. + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool RegisterEventTypeToFilterRule( + [MarshalAs(UnmanagedType.LPWStr)]string filterMask, + uint eventType); + + /// + /// Register the callback I/O for monitor filter driver to the filter rule. + /// + /// the file filter mask of the filter rule + /// the specific I/Os you want to monitor + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool RegisterMoinitorIOToFilterRule( + [MarshalAs(UnmanagedType.LPWStr)]string filterMask, + uint registerIO); + + /// + /// Register the callback I/O for control filter driver to the filter rule, you can change, block and pass the I/O + /// in your callback funtion. + /// + /// the file filter mask of the filter rule + /// the specific I/Os you want to monitor or control + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool RegisterControlIOToFilterRule( + [MarshalAs(UnmanagedType.LPWStr)]string filterMask, + uint registerIO); + + /// + /// Filter the register I/O, only when the file I/Os open with the filter options,the callback I/O will be triggerred + /// and send to the user mode service, for example you only want to get callback for the file open with write access. + /// + /// the file filter mask of the filter rule + /// if it is not 0, callback when file opens with this DesiredAccess + /// if it is not 0, callback when file opens with this Disposition + /// if it is not 0, callback when file opens with this CreateOptions + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AddRegisterIOFilterToFilterRule( + [MarshalAs(UnmanagedType.LPWStr)]string filterMask, + uint filterByDesiredAccess, + uint filterByDisposition, + uint filterByCreateOptions); + + /// + /// Set the access rigths to the specific process + /// + /// the file filter mask of the filter rule + /// the process name will be added the access rights, e.g. notepad.exe or c:\windows\*.exe + /// the access rights + /// return true if it succeeds + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AddProcessRightsToFilterRule( + [MarshalAs(UnmanagedType.LPWStr)]string filterMask, + [MarshalAs(UnmanagedType.LPWStr)]string processName, + uint accessFlags); + + /// + /// Remove the acces right setting for specific processes from filter rule + /// + /// tthe filter rule file filter mask + /// the process name filter mask + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool RemoveProcessRightsFromFilterRule( + [MarshalAs(UnmanagedType.LPWStr)]string filterMask, + [MarshalAs(UnmanagedType.LPWStr)]string processName); + + /// + /// Set the access control flags to process with the processId + /// + /// the filter rule file filter mask + /// the process Id which will be added the access control flags + /// the access control flags + /// return true if it succeeds + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AddProcessIdRightsToFilterRule( + [MarshalAs(UnmanagedType.LPWStr)]string filterMask, + uint processId, + uint accessFlags); + + /// + /// Remove the acces right setting for specific process from filter rule + /// + /// the filter rule file filter mask + /// the process Id + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool RemoveProcessIdRightsFromFilterRule( + [MarshalAs(UnmanagedType.LPWStr)]string filterMask, + uint processId); + + /// + /// Set the access control rights to specific users + /// + /// the filter rule file filter mask + /// the user name you want to set the access right + /// the access rights + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AddUserRightsToFilterRule( + [MarshalAs(UnmanagedType.LPWStr)]string filterMask, + [MarshalAs(UnmanagedType.LPWStr)]string userName, + uint accessFlags); + + /// + /// Add the boolean config setting to a filter rule. + /// Reference BooleanConfig settings + /// + /// the filter rule file filter mask + /// the boolean config setting + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AddBooleanConfigToFilterRule( + [MarshalAs(UnmanagedType.LPWStr)]string filterMask, + uint booleanConfig); + + /// + /// Remove the filter rule from the filter driver. + /// + /// the filter rule file filter mask + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool RemoveFilterRule( + [MarshalAs(UnmanagedType.LPWStr)] string filterMask); + + /// + /// Add the process Id to include process list, only the process Id in the list will be managed by the filter driver, + /// or all the file IO from the process Id which is not in the list will be skipped. This is the global settings, it will affect all filter rules. + /// + /// + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AddIncludedProcessId(uint processId); + + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool RemoveIncludeProcessId(uint processId); + + /// + ///Add the process Id to the exclude process list, all the file IO from the process Id which is in the excluded list will be skipped. + ///This is the global settings, it will affect all filter rules. + /// + /// + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AddExcludedProcessId(uint processId); + + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool RemoveExcludeProcessId(uint processId); + + + //---------------Registry access control APIs----------------------------------- + /// + /// The maximum registry access right flag + /// + public const uint MAX_REGITRY_ACCESS_FLAG = 0xFFFFFFFF; + + /// + /// Allow read registry access right + /// + public const uint ALLOW_READ_REGITRY_ACCESS_FLAG = (uint)(RegControlFlag.REG_ALLOW_OPEN_KEY + | RegControlFlag.REG_ALLOW_QUERY_KEY | RegControlFlag.REG_ALLOW_ENUMERATE_KEY | RegControlFlag.REG_ALLOW_QUERY_VALUE_KEY + | RegControlFlag.REG_ALLOW_QUERY_KEY_SECURITY | RegControlFlag.REG_ALLOW_QUERY_KEYNAME); + + /// + /// Allow change registry access right + /// + public const uint ALLOW_CHANGE_REGITRY_ACCESS_FLAG = (uint)(RegControlFlag.REG_ALLOW_CREATE_KEY + | RegControlFlag.REG_ALLOW_RENAME_KEY | RegControlFlag.REG_ALLOW_DELETE_KEY | RegControlFlag.REG_ALLOW_SET_VALUE_KEY_INFORMATION + | RegControlFlag.REG_ALLOW_DELETE_VALUE_KEY | RegControlFlag.REG_ALLOW_SET_KEY_SECRUITY | RegControlFlag.REG_ALLOW_RESTORE_KEY + | RegControlFlag.REG_ALLOW_REPLACE_KEY | RegControlFlag.REG_ALLOW_LOAD_KEY); + + /// + /// the registry access control flag, allow or deny the registry access based on the registry filter rule. + /// + public enum RegControlFlag : uint + { + REG_ALLOW_OPEN_KEY = 0x00000001, + REG_ALLOW_CREATE_KEY = 0x00000002, + REG_ALLOW_QUERY_KEY = 0x00000004, + REG_ALLOW_RENAME_KEY = 0x00000008, + REG_ALLOW_DELETE_KEY = 0x00000010, + REG_ALLOW_SET_VALUE_KEY_INFORMATION = 0x00000020, + REG_ALLOW_SET_INFORMATION_KEY = 0x00000040, + REG_ALLOW_ENUMERATE_KEY = 0x00000080, + REG_ALLOW_QUERY_VALUE_KEY = 0x00000100, + REG_ALLOW_ENUMERATE_VALUE_KEY = 0x00000200, + REG_ALLOW_QUERY_MULTIPLE_VALUE_KEY = 0x00000400, + REG_ALLOW_DELETE_VALUE_KEY = 0x00000800, + REG_ALLOW_QUERY_KEY_SECURITY = 0x00001000, + REG_ALLOW_SET_KEY_SECRUITY = 0x00002000, + REG_ALLOW_RESTORE_KEY = 0x00004000, + REG_ALLOW_REPLACE_KEY = 0x00008000, + REG_ALLOW_SAVE_KEY = 0x00010000, + REG_ALLOW_FLUSH_KEY = 0x00020000, + REG_ALLOW_LOAD_KEY = 0x00040000, + REG_ALLOW_UNLOAD_KEY = 0x00080000, + REG_ALLOW_KEY_CLOSE = 0x00100000, + REG_ALLOW_QUERY_KEYNAME = 0x00200000, + } + + /// + /// this is the value which will register all the registry notification callback class. + /// + public const ulong MAX_REG_CALLBACK_CLASS = 0xFFFFFFFFFFFFFFFF; + + /// + /// the registry callback class, you can block or modify the registry access in pre-callback + /// or monitor the registry access in post-callback + /// + public enum RegCallbackClass : ulong + { + Reg_Pre_Delete_Key = 0x00000001, + Reg_Pre_Set_Value_Key = 0x00000002, + Reg_Pre_Delete_Value_Key = 0x00000004, + Reg_Pre_SetInformation_Key = 0x00000008, + Reg_Pre_Rename_Key = 0x00000010, + Reg_Pre_Enumerate_Key = 0x00000020, + Reg_Pre_Enumerate_Value_Key = 0x00000040, + Reg_Pre_Query_Key = 0x00000080, + Reg_Pre_Query_Value_Key = 0x00000100, + Reg_Pre_Query_Multiple_Value_Key = 0x00000200, + Reg_Pre_Create_Key = 0x00000400, + Reg_Post_Create_Key = 0x00000800, + Reg_Pre_Open_Key = 0x00001000, + Reg_Post_Open_Key = 0x00002000, + Reg_Pre_Key_Handle_Close = 0x00004000, + // + // .Net only + // + Reg_Post_Delete_Key = 0x00008000, + Reg_Post_Set_Value_Key = 0x00010000, + Reg_Post_Delete_Value_Key = 0x00020000, + Reg_Post_SetInformation_Key = 0x00040000, + Reg_Post_Rename_Key = 0x00080000, + Reg_Post_Enumerate_Key = 0x00100000, + Reg_Post_Enumerate_Value_Key = 0x00200000, + Reg_Post_Query_Key = 0x00400000, + Reg_Post_Query_Value_Key = 0x00800000, + Reg_Post_Query_Multiple_Value_Key = 0x01000000, + Reg_Post_Key_Handle_Close = 0x02000000, + Reg_Pre_Create_KeyEx = 0x04000000, + Reg_Post_Create_KeyEx = 0x08000000, + Reg_Pre_Open_KeyEx = 0x10000000, + Reg_Post_Open_KeyEx = 0x20000000, + // + // new to Windows Vista + // + Reg_Pre_Flush_Key = 0x40000000, + Reg_Post_Flush_Key = 0x80000000, + Reg_Pre_Load_Key = 0x100000000, + Reg_Post_Load_Key = 0x200000000, + Reg_Pre_UnLoad_Key = 0x400000000, + Reg_Post_UnLoad_Key = 0x800000000, + Reg_Pre_Query_Key_Security = 0x1000000000, + Reg_Post_Query_Key_Security = 0x2000000000, + Reg_Pre_Set_Key_Security = 0x4000000000, + Reg_Post_Set_Key_Security = 0x8000000000, + // + // per-object context cleanup + // + Reg_Callback_Object_Context_Cleanup = 0x10000000000, + // + // new in Vista SP2 + // + Reg_Pre_Restore_Key = 0x20000000000, + Reg_Post_Restore_Key = 0x40000000000, + Reg_Pre_Save_Key = 0x80000000000, + Reg_Post_Save_Key = 0x100000000000, + Reg_Pre_Replace_Key = 0x200000000000, + Reg_Post_Replace_Key = 0x400000000000, + + // + // new in Windows 10 + // + Reg_Pre_Query_KeyName = 0x800000000000, + Reg_Post_Query_KeyName = 0x1000000000000, + + } + + /// + /// Add registry access control filter entry with process name filter mask, user name filter mask and registry + /// key filter mask + /// + /// The length of the process name string in bytes + /// The process name to be filtered, all processes if it is '*' + /// set the processId if you want filter with id instead of the process name + /// the user name length if you want to filter the user name + /// the user name filter mask + /// set the registry key name filter if you want to filter by the key name + /// the registry key name filter mask + /// The access control flag to the registry + /// The registered callback registry access class + /// Skip all the registry access from this process filter mask if it is true. + /// return true if the entry was added successfully + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AddRegistryFilterRule( + uint processNameLength, + [MarshalAs(UnmanagedType.LPWStr)]string processName, + uint processId, + uint userNameLength, + [MarshalAs(UnmanagedType.LPWStr)]string userName, + uint registryKeyNameLength, + [MarshalAs(UnmanagedType.LPWStr)]string registryKeyNameFilterMask, + uint accessFlag, + ulong regCallbackClass, + bool isExcludeFilter); + + /// + /// Add registry access control filter entry with process name, if process name filter mask matches the proces, + /// it will set the access flag to the process. + /// + /// The length of the process name string in bytes + /// The process name to be filtered, all processes if it is '*' + /// The access control flag to the registry + /// The registered callback registry access class + /// Skip all the registry access from this process filter mask if it is true. + /// return true if the entry was added successfully + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AddRegistryFilterRuleByProcessName( + uint processNameLength, + [MarshalAs(UnmanagedType.LPWStr)]string processName, + uint accessFlag, + ulong regCallbackClass, + bool isExcludeFilter); + + /// + /// Add registry access control filter entry with processId, if processId matches the proces, + /// it will set the access flag to the process. + /// + /// The process Id to be filtered + /// The access control flag to the registry + /// The registered callback registry access class + /// Skip all the registry access from this process filter mask if it is true. + /// return true if the entry was added successfully + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AddRegistryFilterRuleByProcessId( + uint processId, + uint accessFlag, + ulong regCallbackClass, + bool isExcludeFilter); + + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool RemoveRegistryFilterRuleByProcessId( + uint processId); + + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool RemoveRegistryFilterRuleByProcessName( + uint processNameLength, + [MarshalAs(UnmanagedType.LPWStr)]string processName); + + //---------------Registry access control APIs END----------------------------------- + + //---------------Process filter APIs----------------------------------------------- + /// + /// process control flag. + /// + public enum ProcessControlFlag : uint + { + /// + /// deny the new process creation if the flag is on + /// + DENY_NEW_PROCESS_CREATION = 0x00000001, + /// + /// Get a notification when a new process is being created. + /// + PROCESS_CREATION_NOTIFICATION = 0x00000100, + /// + ///get a notification when a process was termiated + /// + PROCESS_TERMINATION_NOTIFICATION = 0x00000200, + /// + /// get a notification for process handle operations, when a handle for a process + /// is being created or duplicated. + /// + PROCESS_HANDLE_OP_NOTIFICATION = 0x00000400, + /// + /// get a notifcation when a new thread is being created. + /// + THREAD_CREATION_NOTIFICATION = 0x00000800, + /// + /// get a notification when a thread was termiated + /// + THREAD_TERMINIATION_NOTIFICATION = 0x00001000, + /// + /// get a notification for thread handle operations, when a handle for a thread + /// is being created or duplicated. + /// + THREAD_HANDLE_OP_NOTIFICATION = 0x00002000, + } + + /// + /// Add the process filter entry,get notification of new process/thread creation or termination. + /// prevent the unauthorized excutable binaries from running. + /// + /// the process name mask length + /// the process name mask, i.e. c:\myfolder\*.exe + /// the control flag of the process + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AddProcessFilterRule( + uint processNameMaskLength, + [MarshalAs(UnmanagedType.LPWStr)]string processNameMask, + uint controlFlag, + uint filterRuleId ); + + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool RemoveProcessFilterRule( + uint processNameMaskLength, + [MarshalAs(UnmanagedType.LPWStr)]string processNameMask); + + /// + /// Add the file control access rights to the process + /// + /// the length of the process name filter mask + /// the process name filter mask + /// the length of the file name filter mask + /// the file name filter mask + /// set the file access control flag if the control filter is enabled + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AddFileControlToProcessByName( + uint processNameMaskLength, + [MarshalAs(UnmanagedType.LPWStr)]string processNameMask, + uint fileNameMaskLength, + [MarshalAs(UnmanagedType.LPWStr)]string fileNameMask, + uint AccessFlag); + + /// + /// Remove the file access rights from the process name + /// + /// + /// + /// + /// + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool RemoveFileControlFromProcessByName( + uint processNameMaskLength, + [MarshalAs(UnmanagedType.LPWStr)]string processNameMask, + uint fileNameMaskLength, + [MarshalAs(UnmanagedType.LPWStr)]string fileNameMask); + + /// + /// register the file callback IO for the process with the filter option. + /// + /// the length of the process name filter mask + /// the process name filter mask + /// the length of the file name filter mask + /// the file name filter mask + /// register the monitor IO callback if the monitor filter driver is enabled + /// register the control IO callback if the control filter driver is enabled + /// if it is not 0, callback when file opens with this DesiredAccess + /// if it is not 0, callback when file opens with this Disposition + /// if it is not 0, callback when file opens with this CreateOptions + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AddFileCallbackIOToProcessByName( + uint processNameMaskLength, + [MarshalAs(UnmanagedType.LPWStr)]string processNameMask, + uint fileNameMaskLength, + [MarshalAs(UnmanagedType.LPWStr)]string fileNameMask, + uint monitorIO, + uint controlIO, + uint filterByDesiredAccess, + uint filterByDisposition, + uint filterByCreateOptions); + + /// + /// This is the API to add the file access rights of the specific files to the specific processes by process Id + /// This feature requires the control filter was enabled + /// + /// the process Id it will be filtered + /// the length of the file name filter mask + /// the file name filter mask + /// the file access control flag + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AddFileControlToProcessById( + uint processId, + uint fileNameMaskLength, + [MarshalAs(UnmanagedType.LPWStr)]string fileNameMask, + uint AccessFlag ); + + /// + /// Remove the file access entry by process Id + /// + /// + /// + /// + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool RemoveFileControlFromProcessById( + uint processId, + uint fileNameMaskLength, + [MarshalAs(UnmanagedType.LPWStr)]string fileNameMask); + + /// + /// prevent the process being terminated, only support OS vista or later version. + /// + /// + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AddProtectedProcessId(uint processId); + + /// + /// prevent the process from creating the new file after it opened the protected file. + /// the process can't save the protected file to the other file name. + /// + /// + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AddBlockSaveAsProcessId(uint processId); + + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool RemoveBlockSaveAsProcessId(uint processId); + + //---------------Process filter APIs END----------------------------------------------- + + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool RegisterIoRequest(uint requestRegistration); + + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool GetFileHandleInFilter( + [MarshalAs(UnmanagedType.LPWStr)]string fileName, + uint dwDesiredAccess, + ref IntPtr fileHandle); + + [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)] + public static extern bool ConvertSidToStringSid( + [In] IntPtr sid, + [Out] out IntPtr sidString); + + [DllImport("kernel32.dll", SetLastError = true)] + public static extern IntPtr LocalFree(IntPtr hMem); + + [DllImport("kernel32", SetLastError = true)] + public static extern uint GetCurrentProcessId(); + + [DllImport("Kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)] + public static extern int QueryDosDeviceW( + [MarshalAs(UnmanagedType.LPWStr)]string dosName, + [MarshalAs(UnmanagedType.LPWStr)]ref string volumeName, + int volumeNameLength); + + [DllImport("FilterAPI.dll", SetLastError = true)] + private static extern bool CreateFileAPI( + [MarshalAs(UnmanagedType.LPWStr)]string fileName, + uint dwDesiredAccess, + uint dwShareMode, + uint dwCreationDisposition, + uint dwFlagsAndAttributes, + ref IntPtr fileHandle); + + [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] + private static extern bool SetFileTime(SafeFileHandle hFile, + [In] ref long lpCreationTime, + [In] ref long lpLastAccessTime, + [In] ref long lpLastWriteTime); + + [DllImport("FilterAPI.dll", SetLastError = true)] + private static extern bool CreateStubFile( + [MarshalAs(UnmanagedType.LPWStr)]string fileName, + long fileSize, //if it is 0 and the file exist,it will use the current file size. + uint fileAttributes, //if it is 0 and the file exist, it will use the current file attributes. + uint tagDataLength, //if it is 0, then no reparsepoint will be created. + IntPtr tagData, + bool overwriteIfExist, + ref IntPtr fileHandle); + + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool OpenStubFile( + [MarshalAs(UnmanagedType.LPWStr)]string fileName, + FileAccess access, + FileShare share, + ref IntPtr fileHandle); + + [DllImport("FilterAPI.dll", SetLastError = true)] + private static extern bool QueryAllocatedRanges( + IntPtr fileHandle, + long queryOffset, + long queryLength, + IntPtr allocatedRangesBuffer, + int allocatedRangesBufferSize, + ref uint returnedLength); + + [DllImport("FilterAPI.dll", SetLastError = true)] + private static extern bool AESEncryptDecryptBuffer( + IntPtr inputBuffer, + IntPtr outputBuffer, + uint bufferLength, + long offset, + byte[] encryptionKey, + uint keyLength, + byte[] iv, + uint ivLength); + + /// + /// Encrypt the file, if addHeader is true then the iv data will be embedded to the encrypted file, + /// or there are no meta data attached. + /// + /// + /// + /// + /// + /// + /// + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AESEncryptFile( + [MarshalAs(UnmanagedType.LPWStr)]string fileName, + uint keyLength, + byte[] encryptionKey, + uint ivLength, + byte[] iv, + bool addHeader); + + /// + /// Encrypt the file, the iv data and the tag data will be embedded to the encrypted file. + /// + /// + /// + /// + /// + /// + /// + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AESEncryptFileWithTag( + [MarshalAs(UnmanagedType.LPWStr)]string fileName, + uint keyLength, + byte[] encryptionKey, + uint ivLength, + byte[] iv, + uint tagDataLength, + byte[] tagData); + + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AESDecryptFile( + [MarshalAs(UnmanagedType.LPWStr)]string fileName, + uint keyLength, + byte[] encryptionKey, + uint ivLength, + byte[] iv); + + /// + /// Encrypt the source file to the dest file, if addIVTag is true then the iv data will be embedded to the encrypted file, + /// or there are no meta data attached. + /// + /// + /// + /// + /// + /// + /// + /// + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AESEncryptFileToFile( + [MarshalAs(UnmanagedType.LPWStr)]string sourceFileName, + [MarshalAs(UnmanagedType.LPWStr)]string destFileName, + uint keyLength, + byte[] encryptionKey, + uint ivLength, + byte[] iv, + bool addIVTag); + + /// + /// Encrypt the source file to the dest file, the iv data and the tag data will be embedded to the encrypted file. + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AESEncryptFileToFileWithTag( + [MarshalAs(UnmanagedType.LPWStr)]string sourceFileName, + [MarshalAs(UnmanagedType.LPWStr)]string destFileName, + uint keyLength, + byte[] encryptionKey, + uint ivLength, + byte[] iv, + uint tagDataLength, + byte[] tagData); + + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AESDecryptFileToFile( + [MarshalAs(UnmanagedType.LPWStr)]string sourceFileName, + [MarshalAs(UnmanagedType.LPWStr)]string destFileName, + uint keyLength, + byte[] encryptionKey, + uint ivLength, + byte[] iv); + + /// + /// Set the AES Data to the encrypted file + /// + /// the encrypted file name + /// the size of the AESData + /// the AESData structure + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AddAESHeader( + [MarshalAs(UnmanagedType.LPWStr)]string fileName, + uint headerSize, + byte[] header); + + /// + /// get the AES Data from the encrypted file + /// + /// the encrypted file name + /// the size of the AESData + /// the byte array to store the AESData structure + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool GetAESHeader( + [MarshalAs(UnmanagedType.LPWStr)]string fileName, + ref uint headerSize, + byte[] header); + + /// + /// Set the AESFlags and AccessFlags in the AES header + /// + /// + /// + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool SetHeaderFlags( + [MarshalAs(UnmanagedType.LPWStr)]string fileName, + uint aesFlags, + uint accessFlags ); + + /// + /// Get the tag data which was set in the AES header + /// + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool GetAESTagData( + [MarshalAs(UnmanagedType.LPWStr)]string fileName, + ref uint tagDataSize, + byte[] tagData); + + /// + /// Get the IV data from an encrypted file's header + /// + /// the encrypted file name + /// the pass in/out iv buffer size + /// the iv buffer + /// return true if it gets the right iv data + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool GetAESIV( + [MarshalAs(UnmanagedType.LPWStr)]string fileName, + ref uint ivSize, + byte[] ivBuffer); + + + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AddReparseTagData( + [MarshalAs(UnmanagedType.LPWStr)]string fileName, + int tagDataLength, + IntPtr tagData); + + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool RemoveTagData( + IntPtr fileHandle); + + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AddTagData( + IntPtr fileHandle, + int tagDataLength, + IntPtr tagData); + + public static bool EmbedDRPolicyDataToFile( + string fileName, + byte[] drPolicyData, + out string lastError ) + { + + bool ret = false; + lastError = string.Empty; + + try + { + GCHandle pinnedArray = GCHandle.Alloc(drPolicyData, GCHandleType.Pinned); + IntPtr pointer = pinnedArray.AddrOfPinnedObject(); + + ret = AddReparseTagData(fileName, drPolicyData.Length, pointer); + + pinnedArray.Free(); + + if (!ret) + { + lastError = GetLastErrorMessage(); + } + } + catch (Exception ex) + { + ret = false; + lastError = ex.Message; + } + + return ret; + + } + + [DllImport("kernel32.dll", SetLastError = true)] + public static extern bool CloseHandle(IntPtr handle); + + /// + /// Return true if it succeeds to check the iv tag, if ivLenght > 0, it returns ivTag, or there are no ivTag data. + /// + /// + /// + /// + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + private static extern bool GetIVTag( + [MarshalAs(UnmanagedType.LPWStr)]string fileName, + ref uint ivLength, + IntPtr iv, + ref uint aesFlag); + + /// + /// the buffer length has to be 36 or more. + /// + /// + /// + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool GetUniqueComputerId( + IntPtr outputBuffer, + ref uint outputBufferLength); + + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool ActivateLicense( + IntPtr outputBuffer, + uint outputBufferLength); + + public enum EncryptType + { + Decryption = 0, + Encryption , + } + + public static bool GetUniqueComputerId(ref string myComputerId,ref string lastError) + { + bool retVal = false; + byte[] computerId = new byte[52]; + GCHandle gcHandle = GCHandle.Alloc(computerId, GCHandleType.Pinned); + + try + { + uint computerIdLength = (uint)computerId.Length; + IntPtr computerIdPtr = Marshal.UnsafeAddrOfPinnedArrayElement(computerId, 0); + retVal = FilterAPI.GetUniqueComputerId(computerIdPtr, ref computerIdLength); + + if (!retVal || computerIdLength <= 0) + { + lastError = GetLastErrorMessage(); + return false; + } + + Array.Resize(ref computerId, (int)computerIdLength); + myComputerId = UnicodeEncoding.Unicode.GetString(computerId); + + return true; + } + catch (Exception ex) + { + lastError = "Get computerId got exception,system return error:" + ex.Message; + return false; + } + finally + { + gcHandle.Free(); + } + + } + + /// + /// To open encrypted file without the filter driver interception, read the raw data with the return file handle. + /// The caller is reponsible to close the file handle. + /// + /// + /// + /// + /// + public static bool OpenRawEnCyptedFile(string fileName, out IntPtr fileHandle, out string lastError) + { + fileHandle = IntPtr.Zero; + lastError = string.Empty; + uint bypassFilterFileAttributes = FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_OPEN_NO_RECALL|FILE_FLAG_NO_BUFFERING|FILE_ATTRIBUTE_REPARSE_POINT; + + try + { + if (!CreateFileAPI(fileName, (uint)FileAccess.Read, (uint)FileShare.None, (uint)FileMode.Open, bypassFilterFileAttributes, ref fileHandle)) + { + lastError = FilterAPI.GetLastErrorMessage(); + return false; + } + } + catch (Exception ex) + { + lastError = "OpenRawEnCyptedFile " + fileName + " got exception,system return error:" + ex.Message; + return false; + } + + return true; + } + + + //public static bool GetIVTag(string fileName, ref byte[] iv,ref uint aesFlag, out string lastError) + //{ + // bool ret = false; + // IntPtr tagPtr = IntPtr.Zero; + // uint ivLength = 16; + + // lastError = string.Empty; + + // tagPtr = Marshal.AllocHGlobal((int)ivLength); + // ret = GetIVTag(fileName, ref ivLength, tagPtr, ref aesFlag); + + // if (!ret) + // { + // lastError = GetLastErrorMessage(); + // } + // else if (ivLength > 0) + // { + // iv = new byte[ivLength]; + // Marshal.Copy(tagPtr, iv, 0, (int)ivLength); + // } + // else + // { + // iv = new byte[0]; ; + // } + + // if (tagPtr != IntPtr.Zero) + // { + // Marshal.FreeHGlobal(tagPtr); + // } + + // return ret; + //} + + + + public static string AESEncryptDecryptStr(string inStr, EncryptType encryptType) + { + + if (string.IsNullOrEmpty(inStr)) + { + return string.Empty; + } + + byte[] inbuffer = null; + + if (encryptType == EncryptType.Encryption) + { + inbuffer = ASCIIEncoding.UTF8.GetBytes(inStr); + } + else if (encryptType == EncryptType.Decryption) + { + inbuffer = Convert.FromBase64String(inStr); + } + else + { + throw new Exception("Failed to encrypt decrypt string, the encryptType " + encryptType.ToString() + " doesn't know."); + } + + byte[] outBuffer = new byte[inbuffer.Length]; + + GCHandle gcHandleIn = GCHandle.Alloc(inbuffer, GCHandleType.Pinned); + GCHandle gcHandleOut = GCHandle.Alloc(outBuffer, GCHandleType.Pinned); + + IntPtr inBufferPtr = Marshal.UnsafeAddrOfPinnedArrayElement(inbuffer, 0); + IntPtr outBufferPtr = Marshal.UnsafeAddrOfPinnedArrayElement(outBuffer, 0); + + try + { + bool retVal = AESEncryptDecryptBuffer(inBufferPtr, outBufferPtr, (uint)inbuffer.Length, 0, null, 0, null, 0); + + if (encryptType == EncryptType.Encryption) + { + return Convert.ToBase64String(outBuffer); + } + else //if (encryptType == EncryptType.Decryption) + { + return ASCIIEncoding.UTF8.GetString(outBuffer); + } + } + finally + { + gcHandleIn.Free(); + gcHandleOut.Free(); + } + + } + + + public static void AESEncryptDecryptBuffer(byte[] inbuffer, long offset, byte[] key, byte[] IV) + { + if (null == inbuffer || inbuffer.Length == 0) + { + throw new Exception("Failed to encrypt decrypt buffer, the input buffer can't be null"); + } + + GCHandle gcHandle = GCHandle.Alloc(inbuffer, GCHandleType.Pinned); + + try + { + IntPtr inBufferPtr = Marshal.UnsafeAddrOfPinnedArrayElement(inbuffer, 0); + + uint keyLength = 0; + uint IVLength = 0; + + if (key != null) + { + keyLength = (uint)key.Length; + } + + if (IV != null) + { + IVLength = (uint)IV.Length; + } + + + bool retVal = AESEncryptDecryptBuffer(inBufferPtr, inBufferPtr, (uint)inbuffer.Length, offset, key, keyLength, IV, IVLength); + + if (!retVal) + { + throw new Exception("Failed to encrypt buffer, return error:" + GetLastErrorMessage()); + } + } + finally + { + gcHandle.Free(); + } + + return ; + } + + public static bool DecodeUserName(byte[]sid, out string userName) + { + bool ret = true; + + IntPtr sidStringPtr = IntPtr.Zero; + string sidString = string.Empty; + + userName = string.Empty; + + try + { + + IntPtr sidBuffer = Marshal.UnsafeAddrOfPinnedArrayElement(sid, 0); + + if (FilterAPI.ConvertSidToStringSid(sidBuffer, out sidStringPtr)) + { + + sidString = Marshal.PtrToStringAuto(sidStringPtr); + + lock (userNameTable) + { + //check the user name cache table + if (userNameTable.ContainsKey(sidString)) + { + userName = userNameTable[sidString]; + return ret; + } + } + + try + { + SecurityIdentifier secIdentifier = new SecurityIdentifier(sidString); + IdentityReference reference = secIdentifier.Translate(typeof(NTAccount)); + userName = reference.Value; + } + catch + { + } + + lock (userNameTable) + { + //check the user name cache table + if (!userNameTable.ContainsKey(sidString)) + { + userNameTable.Add(sidString, userName); + } + } + } + else + { + string errorMessage = "Convert sid to sid string failed with error " + Marshal.GetLastWin32Error(); + Console.WriteLine(errorMessage); + } + } + catch (Exception ex) + { + Console.WriteLine(string.Format("Convert sid to user name got exception:{0}", ex.Message)); + ret = false; + + } + finally + { + if (sidStringPtr != null && sidStringPtr != IntPtr.Zero) + { + FilterAPI.LocalFree(sidStringPtr); + } + } + + return ret; + } + + public static bool DecodeProcessName(uint processId, out string processName) + { + bool ret = true; + processName = string.Empty; + + + //this is the optimization of the process to get the process name from the process Id + //it is not reliable for this process, since the process Id is reuasble when the process was ternmiated. + lock (processNameTable) + { + if (processNameTable.ContainsKey(processId)) + { + processName = processNameTable[processId]; + return true; + } + } + + try + { + System.Diagnostics.Process requestProcess = System.Diagnostics.Process.GetProcessById((int)processId); + processName = requestProcess.ProcessName; + } + catch (Exception ex) + { + Console.WriteLine(string.Format("Convert pid to process name got exception:{0}", ex.Message)); + ret = false; + } + + lock (processNameTable) + { + if (!processNameTable.ContainsKey(processId)) + { + processNameTable.Add(processId,processName); + } + } + + return ret; + } + + + public static string GetLastErrorMessage() + { + int len = 1024; + string lastError = new string((char)0, len); + + if (!GetLastErrorMessage(lastError, ref len)) + { + lastError = new string((char)0, len); + if (!GetLastErrorMessage(lastError, ref len)) + { + return "failed to get last error message."; + } + } + + if (lastError.IndexOf((char)0) >= 0) + { + lastError = lastError.Substring(0, lastError.IndexOf((char)0)); + } + + return lastError; + } + + static bool IsDriverChanged() + { + bool ret = false; + + try + { + System.Reflection.Assembly assembly = System.Reflection.Assembly.GetEntryAssembly(); + string localPath = Path.GetDirectoryName(assembly.Location); + string driverName = Path.Combine(localPath, "EaseFlt.sys"); + + if (File.Exists(driverName)) + { + string driverInstalledPath = Path.Combine(Environment.SystemDirectory, "drivers\\easeflt.sys"); + + if (File.Exists(driverInstalledPath)) + { + FileInfo fsInstalled = new FileInfo(driverInstalledPath); + FileInfo fsToInstall = new FileInfo(driverName); + + if (fsInstalled.LastWriteTime < fsToInstall.LastWriteTime) + { + //it needs to install new the driver. + return true; + } + } + else + { + return true; + } + } + + } + catch (Exception ex) + { + ret = false; + + EventManager.WriteMessage(630, "IsDriverChanged", EventLevel.Error, "Check IsDriverChanged failed with error:" + ex.Message); + } + + return ret; + } + + static public bool StartFilter(int threadCount, string registerKey,FilterDelegate filterCallback, DisconnectDelegate disconnectCallback,ref string lastError) + { + + bool ret = true; + + try + { + if (IsDriverChanged() || !FilterAPI.IsDriverServiceRunning()) + { + //uninstall or install driver needs the Admin permission. + + FilterAPI.UnInstallDriver(); + + //wait for 3 seconds for the uninstallation completed. + System.Threading.Thread.Sleep(3000); + + ret = FilterAPI.InstallDriver(); + if (!ret) + { + lastError = "Installed driver failed with error:" + FilterAPI.GetLastErrorMessage(); + return false; + } + else + { + isFilterStarted = false; + EventManager.WriteMessage(59, "InstallDriver", EventLevel.Information, "Install filter driver succeeded."); + } + } + + + if (!isFilterStarted) + { + + if (!SetRegistrationKey(registerKey)) + { + lastError = "Set registration key failed with error:" + GetLastErrorMessage(); + return false; + } + + gchFilter = GCHandle.Alloc(filterCallback); + IntPtr filterCallbackPtr = Marshal.GetFunctionPointerForDelegate(filterCallback); + + gchDisconnect = GCHandle.Alloc(disconnectCallback); + IntPtr disconnectCallbackPtr = Marshal.GetFunctionPointerForDelegate(disconnectCallback); + + isFilterStarted = RegisterMessageCallback(threadCount, filterCallbackPtr, disconnectCallbackPtr); + if (!isFilterStarted) + { + lastError = "RegisterMessageCallback failed with error:" + GetLastErrorMessage(); + return false; + } + + ret = true; + + } + } + catch (Exception ex) + { + ret = false; + lastError = "Start filter failed with error " + ex.Message; + } + finally + { + if (!ret) + { + lastError = lastError + " Make sure you run this application as administrator."; + } + } + + return ret; + } + + static public void StopFilter() + { + if (isFilterStarted) + { + Disconnect(); + gchFilter.Free(); + gchDisconnect.Free(); + isFilterStarted = false; + } + + return; + } + + static public bool IsFilterStarted + { + get { return isFilterStarted; } + } + + } +} diff --git a/Demo_Source_Code/CSharpDemo/CommonObjects/FilterMessage.cs b/Demo_Source_Code/CSharpDemo/CommonObjects/FilterMessage.cs new file mode 100644 index 0000000..295772c --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/CommonObjects/FilterMessage.cs @@ -0,0 +1,903 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; +using System.Runtime.InteropServices; +using System.Security.Principal; +using System.IO; +using System.Threading; +using System.Reflection; + +namespace EaseFilter.CommonObjects +{ + public class ByteArrayComparer : IEqualityComparer + { + public bool Equals(byte[] left, byte[] right) + { + if (left == null || right == null) + { + return left == right; + } + if (left.Length != right.Length) + { + return false; + } + for (int i = 0; i < left.Length; i++) + { + if (left[i] != right[i]) + { + return false; + } + } + return true; + } + + public int GetHashCode(byte[] key) + { + if (key == null) + throw new ArgumentNullException("key"); + int sum = 0; + foreach (byte cur in key) + { + sum += cur; + } + return sum; + } + } + + public class FilterMessage : IDisposable + { + + ListView listView_Message = null; + Thread messageThread = null; + Queue messageQueue = new Queue(); + + AutoResetEvent autoEvent = new AutoResetEvent(false); + bool disposed = false; + + + public FilterMessage(ListView lvMessage) + { + this.listView_Message = lvMessage; + InitListView(); + messageThread = new Thread(new ThreadStart(ProcessMessage)); + messageThread.Name = "ProcessMessage"; + messageThread.Start(); + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + private void Dispose(bool disposing) + { + if (!this.disposed) + { + } + + autoEvent.Set(); + messageThread.Abort(); + disposed = true; + } + + ~FilterMessage() + { + Dispose(false); + } + + public void InitListView() + { + messageQueue.Clear(); + //init ListView control + listView_Message.Clear(); //clear control + //create column header for ListView + listView_Message.Columns.Add("#", 40, System.Windows.Forms.HorizontalAlignment.Left); + listView_Message.Columns.Add("Time", 120, System.Windows.Forms.HorizontalAlignment.Left); + listView_Message.Columns.Add("UserName", 150, System.Windows.Forms.HorizontalAlignment.Left); + listView_Message.Columns.Add("ProcessName(PID)", 100, System.Windows.Forms.HorizontalAlignment.Left); + listView_Message.Columns.Add("ThreadId", 60, System.Windows.Forms.HorizontalAlignment.Left); + listView_Message.Columns.Add("I/O Name", 160, System.Windows.Forms.HorizontalAlignment.Left); + listView_Message.Columns.Add("FileObject", 100, System.Windows.Forms.HorizontalAlignment.Left); + listView_Message.Columns.Add("FileName", 350, System.Windows.Forms.HorizontalAlignment.Left); + listView_Message.Columns.Add("FileSize", 70, System.Windows.Forms.HorizontalAlignment.Left); + listView_Message.Columns.Add("FileAttributes", 70, System.Windows.Forms.HorizontalAlignment.Left); + listView_Message.Columns.Add("LastWriteTime", 120, System.Windows.Forms.HorizontalAlignment.Left); + listView_Message.Columns.Add("Return Status", 100, System.Windows.Forms.HorizontalAlignment.Left); + listView_Message.Columns.Add("Description", 500, System.Windows.Forms.HorizontalAlignment.Left); + } + + public void AddMessage(FilterAPI.MessageSendData messageSend) + { + lock (messageQueue) + { + if (messageQueue.Count > GlobalConfig.MaximumFilterMessages) + { + messageQueue.Clear(); + } + + + if (messageSend.MessageType == (uint)FilterAPI.FilterCommand.FILTER_SEND_PROCESS_CREATION_INFO + || messageSend.MessageType == (uint)FilterAPI.FilterCommand.FILTER_SEND_PROCESS_TERMINATION_INFO + || messageSend.MessageType == (uint)FilterAPI.FilterCommand.FILTER_SEND_THREAD_CREATION_INFO + || messageSend.MessageType == (uint)FilterAPI.FilterCommand.FILTER_SEND_THREAD_TERMINATION_INFO) + { + //this is the process filter command, we don't display the message. + return; + } + + messageQueue.Enqueue(messageSend); + } + + autoEvent.Set(); + + } + + + void ProcessMessage() + { + int waitTimeout = 2000; //2seconds + List itemList = new List(); + + WaitHandle[] waitHandles = new WaitHandle[] { autoEvent, GlobalConfig.stopEvent }; + + while (GlobalConfig.isRunning) + { + if (messageQueue.Count == 0) + { + int result = WaitHandle.WaitAny(waitHandles, waitTimeout); + if (!GlobalConfig.isRunning) + { + return; + } + } + + System.Diagnostics.Stopwatch stopWatch = new System.Diagnostics.Stopwatch(); + stopWatch.Start(); + + while (messageQueue.Count > 0 ) + { + FilterAPI.MessageSendData messageSend; + + lock (messageQueue) + { + messageSend = (FilterAPI.MessageSendData)messageQueue.Dequeue(); + } + + if (GlobalConfig.DisableDirIO && (messageSend.FileAttributes & (uint)FileAttributes.Directory) == (uint)FileAttributes.Directory) + { + //don't display the directory IO + continue; + } + + string[] filterMessages = new string[0]; + ListViewItem lvItem = GetFilterMessage(messageSend, ref filterMessages); + + if (null == lvItem) + { + //no display message. + continue; + } + + if (GlobalConfig.EnableLogTransaction) + { + LogTrasaction(filterMessages); + } + + if (GlobalConfig.OutputMessageToConsole) + { + itemList.Add(lvItem); + + if (itemList.Count > GlobalConfig.MaximumFilterMessages) + { + AddItemToList(itemList); + itemList.Clear(); + + Thread.Sleep(1000); + } + } + + } + + if (itemList.Count > 0) + { + AddItemToList(itemList); + itemList.Clear(); + } + + } + + + } + + public void LoadMessageFromLogToConsole() + { + if (listView_Message == null) + { + return; + } + + try + { + Assembly assembly = System.Reflection.Assembly.GetEntryAssembly(); + string assemblyPath = Path.GetDirectoryName(assembly.Location); + + string filterMessageLogName = GlobalConfig.FilterMessageLogName; + string logFileName = Path.Combine(assemblyPath, filterMessageLogName); + + if (!File.Exists(logFileName)) + { + return; + } + + string[] logMessage = File.ReadAllLines(logFileName); + List itemList = new List(); + + foreach(string itemStr in logMessage) + { + if (itemStr.Trim().Length > 0) + { + string[] listData = itemStr.Split(new char[] { '|' }); + if (listData.Length >= listView_Message.Columns.Count) + { + ListViewItem lvItem = new ListViewItem(listData, 0); + + uint status = 0; + string statusStr = listData[listView_Message.Columns.Count - 2]; + int index1 = statusStr.IndexOf('('); + int index2 = statusStr.IndexOf(')'); + + if (index1 >= 0 && index2 > 2) + { + statusStr = statusStr.Substring(index1 + 3, index2 - index1 -3 ); + uint.TryParse(statusStr, System.Globalization.NumberStyles.HexNumber,null, out status); + + if (status >= (uint)NtStatus.Status.Error) + { + lvItem.BackColor = Color.LightGray; + lvItem.ForeColor = Color.Red; + } + else if (status > (uint)NtStatus.Status.Warning) + { + lvItem.BackColor = Color.LightGray; + lvItem.ForeColor = Color.Yellow; + } + } + + itemList.Add(lvItem); + } + } + } + + if (itemList.Count > 0) + { + listView_Message.Items.Clear(); + AddItemToList(itemList); + } + + } + catch (Exception ex) + { + EventManager.WriteMessage(265, "LoadLogMessage", EventLevel.Error, "Load log message failed with error " + ex.Message); + } + } + + public static void LogTrasaction(string[] filterMessages) + { + try + { + Assembly assembly = System.Reflection.Assembly.GetEntryAssembly(); + string assemblyPath = Path.GetDirectoryName(assembly.Location); + + string filterMessageLogName = GlobalConfig.FilterMessageLogName; + + string logFileName = Path.Combine(assemblyPath, filterMessageLogName); + string logFolder = Path.GetDirectoryName(logFileName); + + if (!Directory.Exists(logFolder)) + { + Directory.CreateDirectory(logFolder); + } + + string logMessage = string.Empty; + + for (int i = 0; i < filterMessages.Length; i++) + { + logMessage += filterMessages[i].Trim() + "|"; + } + + if (logMessage.Length > 0) + { + File.AppendAllText(logFileName, logMessage + "\r\n"); + + FileInfo fileInfo = new FileInfo(logFileName); + + if (fileInfo.Length > GlobalConfig.FilterMessageLogFileSize) + { + File.Delete(logFileName + ".bak"); + File.Move(logFileName, logFileName + ".bak"); + } + } + } + catch (Exception ex) + { + EventManager.WriteMessage(172, "LogTrasaction", EventLevel.Error, "Log filter message failed with error " + ex.Message); + } + + } + + + void AddItemToList(List itemList) + { + if (itemList.Count < 1) + { + return; + } + + if (listView_Message.InvokeRequired) + { + listView_Message.Invoke(new MethodInvoker(delegate { AddItemToList(itemList); })); + } + else + { + + while (listView_Message.Items.Count > 0 && listView_Message.Items.Count + itemList.Count > GlobalConfig.MaximumFilterMessages) + { + //the message records in the list view reached to the maximum value, remove the first one till the record less than the maximum value. + listView_Message.Items.RemoveAt(0); + } + + + if (itemList.Count > 0) + { + listView_Message.Items.AddRange(itemList.ToArray()); + // listView_Message.EnsureVisible(listView_Message.Items.Count - 1); + + itemList.Clear(); + + } + } + } + + + public static string FormatDescription(FilterAPI.MessageSendData messageSend) + { + + string message = string.Empty; + try + { + if (messageSend.Status == (uint)NtStatus.Status.Success) + { + + if (messageSend.MessageType == (uint)FilterAPI.FilterCommand.FILTER_SEND_FILE_CHANGED_EVENT + && messageSend.InfoClass == (uint)FilterAPI.EVENTTYPE.RENAMED) + { + string newFileName = string.Empty; + + if (messageSend.DataBufferLength > 0) + { + byte[] buffer = new byte[messageSend.DataBufferLength]; + Array.Copy(messageSend.DataBuffer, buffer, buffer.Length); + newFileName = Encoding.Unicode.GetString(buffer); + if (newFileName.IndexOf((char)0) > 0) + { + newFileName = newFileName.Remove(newFileName.IndexOf((char)0)); + } + } + + message = "File " + messageSend.FileName + " was renamed to " + newFileName; + return message; + } + else if( messageSend.MessageType == (uint)FilterAPI.FilterCommand.FILTER_SEND_ATTACHED_VOLUME_INFO + || messageSend.MessageType ==(uint)FilterAPI.FilterCommand.FILTER_SEND_DETACHED_VOLUME_INFO) + { + FilterAPI.VOLUME_INFO volumeInfo = new FilterAPI.VOLUME_INFO(); + GCHandle pinnedPacket = GCHandle.Alloc(messageSend.DataBuffer, GCHandleType.Pinned); + volumeInfo = (FilterAPI.VOLUME_INFO)Marshal.PtrToStructure( + pinnedPacket.AddrOfPinnedObject(), typeof(FilterAPI.VOLUME_INFO)); + + message += "VolumeName[" + volumeInfo.VolumeName + "] "; + message += "VolumeDosName[" + volumeInfo.VolumeDosName + "] "; + message += "VolumeFilesystemType[" + ((WinData.FLT_FILESYSTEM_TYPE)volumeInfo.VolumeFilesystemType).ToString() + "] "; + + uint deviceCharacteristics = volumeInfo.DeviceCharacteristics; + string charaterMessage = string.Empty; + foreach (WinData.DeviceObject_Characteristics character in Enum.GetValues(typeof(WinData.DeviceObject_Characteristics))) + { + if ((deviceCharacteristics & (uint)character) > 0) + { + charaterMessage += character.ToString() + ";"; + } + } + + message += "DeviceCharacteristics[" + charaterMessage + "]"; + + pinnedPacket.Free(); + + return message; + } + } + else + { + if (messageSend.MessageType == (uint)FilterAPI.FilterCommand.FILTER_REQUEST_ENCRYPTION_IV_AND_KEY_AND_ACCESSFLAG + || messageSend.MessageType == (uint)FilterAPI.FilterCommand.FILTER_REQUEST_ENCRYPTION_IV_AND_KEY) + { + //this is the error message to read the shared secure file + byte[] errorBuffer = new byte[messageSend.DataBufferLength]; + Array.Copy(messageSend.DataBuffer, errorBuffer, errorBuffer.Length); + message = UnicodeEncoding.Unicode.GetString(errorBuffer); + return message; + + } + + return message; + } + + switch ((FilterAPI.MessageType)messageSend.MessageType) + { + case FilterAPI.MessageType.POST_CREATE: + { + if ((messageSend.CreateOptions & (uint)WinData.CreateOptions.FILE_DELETE_ON_CLOSE) > 0) + { + message = "file was marked as deleted."; + } + + if (messageSend.Status == (uint)NtStatus.Status.Success) + { + //the create status is meaningful only when the status is succeeded. + message += "CreateStatus:" + ((WinData.CreateStatus)messageSend.CreateStatus).ToString(); + } + + message += " DesiredAccess:" + FormatDesiredAccess(messageSend.DesiredAccess); + message += " Disposition:" + ((WinData.Disposition)messageSend.Disposition).ToString(); + message += " ShareAccess:" + ((WinData.ShareAccess)messageSend.SharedAccess).ToString(); + message += " CreateOptions:" + FormatCreateOptions(messageSend.CreateOptions); + + break; + + } + + case FilterAPI.MessageType.POST_CACHE_READ: + case FilterAPI.MessageType.POST_FASTIO_READ: + case FilterAPI.MessageType.POST_NOCACHE_READ: + case FilterAPI.MessageType.POST_PAGING_IO_READ: + { + message = "read offset:" + messageSend.Offset + " read length:" + messageSend.Length + ",returnLength:" + messageSend.DataBufferLength; + + if ((GlobalConfig.BooleanConfig & (uint)FilterAPI.BooleanConfig.ENABLE_SEND_DATA_BUFFER) > 0) + { + message += ",return data:"; + //read data is here + message += Encoding.ASCII.GetString(messageSend.DataBuffer); + } + + break; + } + + case FilterAPI.MessageType.POST_CACHE_WRITE: + case FilterAPI.MessageType.POST_FASTIO_WRITE: + case FilterAPI.MessageType.POST_NOCACHE_WRITE: + case FilterAPI.MessageType.POST_PAGING_IO_WRITE: + { + message = "write offset:" + messageSend.Offset + " length:" + messageSend.Length + ",writtenLength:" + messageSend.DataBufferLength; + + if ((GlobalConfig.BooleanConfig & (uint)FilterAPI.BooleanConfig.ENABLE_SEND_DATA_BUFFER) > 0) + { + message += ",writing data:"; + //written data is here + message += Encoding.ASCII.GetString(messageSend.DataBuffer); + } + + break; + } + case FilterAPI.MessageType.POST_SET_INFORMATION: + { + message = FormatInformationDataBuffer((WinData.FileInfomationClass)messageSend.InfoClass, messageSend.DataBufferLength, messageSend.DataBuffer); + + break; + } + case FilterAPI.MessageType.POST_QUERY_INFORMATION: + { + message = FormatInformationDataBuffer((WinData.FileInfomationClass)messageSend.InfoClass, messageSend.DataBufferLength, messageSend.DataBuffer); + + break; + } + case FilterAPI.MessageType.POST_SET_SECURITY: + { + message = "set security with information class:" + FormatSecurityInfoClass(messageSend.InfoClass); + break; + } + case FilterAPI.MessageType.POST_QUERY_SECURITY: + { + message = "query security with information class:" + FormatSecurityInfoClass(messageSend.InfoClass); + break; + } + case FilterAPI.MessageType.POST_DIRECTORY: + { + message = "browse directory with information class:" + ((WinData.FileInfomationClass)messageSend.InfoClass).ToString(); + break; + } + case FilterAPI.MessageType.POST_CLEANUP: + { + message = "all file handles to fileObject " + messageSend.FileObject.ToString("X") + " were closed."; + break; + } + case FilterAPI.MessageType.POST_CLOSE: + { + message = "all system references to fileObject " + messageSend.FileObject.ToString("X") + " were closed."; + break; + } + } + } + catch (Exception ex) + { + EventManager.WriteMessage(318, "FormatDescription", EventLevel.Error, "Format description failed with error " + ex.Message); + } + + + return message; + } + + + public static string FormatIOName(FilterAPI.MessageSendData messageSend) + { + string ioName = string.Empty; + + try + { + if (messageSend.MessageType == (uint)FilterAPI.FilterCommand.FILTER_SEND_FILE_CHANGED_EVENT) + { + foreach (FilterAPI.EVENTTYPE eventType in Enum.GetValues(typeof(FilterAPI.EVENTTYPE))) + { + if (eventType != FilterAPI.EVENTTYPE.NONE && ((messageSend.InfoClass & (uint)eventType) > 0)) + { + if (ioName.Length > 0) + { + ioName = ioName + " ," + eventType.ToString(); + } + else + { + ioName = eventType.ToString(); + } + } + } + + } + else if ( messageSend.MessageType >= (uint)FilterAPI.FilterCommand.FILTER_REQUEST_ENCRYPTION_IV_AND_KEY_AND_TAGDATA + && messageSend.MessageType <= (uint)FilterAPI.FilterCommand.FILTER_SEND_DETACHED_VOLUME_INFO ) + { + ioName = ((FilterAPI.FilterCommand)messageSend.MessageType).ToString(); + + } + else if (messageSend.MessageType == (uint)FilterAPI.MessageType.PRE_QUERY_INFORMATION) + { + if (messageSend.FsContext.ToInt64() == 0) + { + ioName = "PRE_FASTIO_NETWORK_QUERY_OPEN"; + } + else + { + ioName = "PRE_QUERY_INFORMATION"; + } + } + else if (messageSend.MessageType == (uint)FilterAPI.MessageType.POST_QUERY_INFORMATION) + { + if (messageSend.FsContext.ToInt64() == 0) + { + ioName = "POST_FASTIO_NETWORK_QUERY_OPEN"; + } + else + { + ioName = "POST_QUERY_INFORMATION"; + } + } + else + { + ioName = ((FilterAPI.MessageType)messageSend.MessageType).ToString(); + } + } + catch (Exception ex) + { + EventManager.WriteMessage(592, "FormatIOName", EventLevel.Error, "Get IO name from " + messageSend.MessageType.ToString("X") + " exception:" + ex.Message); + } + + if (ioName.Trim().Length == 0) + { + ioName = "UnKnown IO Type (0x" + messageSend.MessageType.ToString("X") + ")"; + } + + return ioName; + } + + ListViewItem GetFilterMessage(FilterAPI.MessageSendData messageSend, ref string[] filterMessages) + { + ListViewItem lvItem = new ListViewItem(); + + try + { + + string userName = string.Empty; + string processName = string.Empty; + + FilterAPI.DecodeUserName(messageSend.Sid, out userName); + FilterAPI.DecodeProcessName(messageSend.ProcessId, out processName); + + if ((messageSend.CreateOptions & (uint)WinData.CreateOptions.FO_REMOTE_ORIGIN) > 0) + { + //this is the request comes from remote server + string remoteIp = string.Empty; + if (messageSend.DataBufferLength > 0 && ((uint)FilterAPI.MessageType.POST_CREATE == messageSend.MessageType) ) + { + byte[] buffer = new byte[messageSend.DataBufferLength]; + Array.Copy(messageSend.DataBuffer, buffer, buffer.Length); + remoteIp = Encoding.Unicode.GetString(buffer); + userName += ",RemoteIP:" + remoteIp; + } + else + { + userName += ",Accessed from remote computer."; + } + } + + string[] listData = new string[listView_Message.Columns.Count]; + int col = 0; + listData[col++] = messageSend.MessageId.ToString(); + listData[col++] = FormatDateTime(messageSend.TransactionTime); + listData[col++] = userName; + listData[col++] = processName + " (" + messageSend.ProcessId + ")"; + listData[col++] = messageSend.ThreadId.ToString(); + listData[col++] = FormatIOName(messageSend); + listData[col++] = messageSend.FileObject.ToString("X"); + listData[col++] = messageSend.FileName; + listData[col++] = messageSend.FileSize.ToString(); + listData[col++] = ((FileAttributes)messageSend.FileAttributes).ToString(); + listData[col++] = FormatDateTime(messageSend.LastWriteTime); + listData[col++] = FormatStatus(messageSend.Status); + listData[col++] = FormatDescription(messageSend); + + filterMessages = listData; + + lvItem = new ListViewItem(listData, 0); + + if (messageSend.Status >= (uint)NtStatus.Status.Error) + { + lvItem.BackColor = Color.LightGray; + lvItem.ForeColor = Color.Red; + } + else if (messageSend.Status > (uint)NtStatus.Status.Warning) + { + lvItem.BackColor = Color.LightGray; + lvItem.ForeColor = Color.Yellow; + } + + + } + catch (Exception ex) + { + EventManager.WriteMessage(445, "GetFilterMessage", EventLevel.Error, "Add callback message failed." + ex.Message); + lvItem = null; + } + + return lvItem; + } + + + public static string FormatDesiredAccess(uint desiredAccess) + { + string ret = string.Empty; + + foreach (WinData.DisiredAccess access in Enum.GetValues(typeof(WinData.DisiredAccess))) + { + if (access == (WinData.DisiredAccess)((uint)access & desiredAccess)) + { + ret += access.ToString() + "; "; + } + } + + return ret; + } + + public static string FormatCreateOptions(uint createOptions) + { + string ret = string.Empty; + + foreach (WinData.CreateOptions option in Enum.GetValues(typeof(WinData.CreateOptions))) + { + if (option == (WinData.CreateOptions)((uint)option & createOptions)) + { + ret += option.ToString() + "; "; + } + } + + if (string.IsNullOrEmpty(ret)) + { + ret = "(0x)" + createOptions.ToString("X"); + } + + return ret; + } + + public static string FormatDateTime(long lDateTime) + { + try + { + if (0 == lDateTime) + { + return "0"; + } + + DateTime dateTime = DateTime.FromFileTime(lDateTime); + string ret = dateTime.ToString("yyyy-MM-ddTHH:mm"); + return ret; + } + catch (Exception ex) + { + EventManager.WriteMessage(502, "FormatDateTime", EventLevel.Error, "FormatDateTime :" + lDateTime.ToString() + " failed." + ex.Message); + return ex.Message; + } + } + + static string FormatInformationDataBuffer(WinData.FileInfomationClass infoClass, uint dataLength, byte[] data) + { + string retValue = string.Empty; + + try + { + switch (infoClass) + { + case WinData.FileInfomationClass.FileRenameInformation: + { + //destination name + string newFileName = Encoding.Unicode.GetString(data); + if (newFileName.IndexOf((char)0) > 0) + { + newFileName = newFileName.Remove(newFileName.IndexOf((char)0)); + } + + retValue = "file was renamed to " + newFileName; + break; + } + case WinData.FileInfomationClass.FileDispositionInformation: + { + //the deletion only complete in the post_cleanup I/O + retValue = "file was marked as deleted."; + break; + } + case WinData.FileInfomationClass.FileEndOfFileInformation: + { + long newFileSize = BitConverter.ToInt64(data, 0); + retValue = "file size was changed to:" + newFileSize.ToString(); + break; + } + case WinData.FileInfomationClass.FileBasicInformation: + { + WinData.FileBasicInformation basiInfo = new WinData.FileBasicInformation(); + GCHandle pinnedPacket = GCHandle.Alloc(data, GCHandleType.Pinned); + basiInfo = (WinData.FileBasicInformation)Marshal.PtrToStructure( + pinnedPacket.AddrOfPinnedObject(), typeof(WinData.FileBasicInformation)); + pinnedPacket.Free(); + + retValue = "FileBasicInformation result,creation time:" + FormatDateTime(basiInfo.CreationTime) + " "; + retValue += "last access time:" + FormatDateTime(basiInfo.LastAccessTime) + " "; + retValue += "last write time:" + FormatDateTime(basiInfo.LastWriteTime) + " "; + retValue += "file attributes:" + ((FileAttributes)basiInfo.FileAttributes).ToString(); + break; + } + + case WinData.FileInfomationClass.FileStandardInformation: + { + WinData.FileStandardInformation standardInfo = new WinData.FileStandardInformation(); + GCHandle pinnedPacket = GCHandle.Alloc(data, GCHandleType.Pinned); + standardInfo = (WinData.FileStandardInformation)Marshal.PtrToStructure( + pinnedPacket.AddrOfPinnedObject(), typeof(WinData.FileStandardInformation)); + pinnedPacket.Free(); + + retValue = "FileStandardInformation result, file size:" + standardInfo.EndOfFile.ToString() + " "; + retValue += "allocation size:" + standardInfo.AllocationSize.ToString() + " "; + retValue += "isDirectory:" + standardInfo.Directory.ToString(); + break; + } + case WinData.FileInfomationClass.FileNetworkOpenInformation: + { + WinData.FileNetworkInformation networkInfo = new WinData.FileNetworkInformation(); + GCHandle pinnedPacket = GCHandle.Alloc(data, GCHandleType.Pinned); + networkInfo = (WinData.FileNetworkInformation)Marshal.PtrToStructure( + pinnedPacket.AddrOfPinnedObject(), typeof(WinData.FileNetworkInformation)); + pinnedPacket.Free(); + + retValue = "FileNetworkOpenInformation result,creation time:" + FormatDateTime(networkInfo.CreationTime) + " "; + retValue += "last access time:" + FormatDateTime(networkInfo.LastAccessTime) + " "; + retValue += "last write time:" + FormatDateTime(networkInfo.LastWriteTime) + " "; + retValue += "file size:" + networkInfo.FileSize.ToString() + " "; + retValue += "file attributes:" + ((FileAttributes)networkInfo.FileAttributes).ToString(); + break; + } + + case WinData.FileInfomationClass.FileInternalInformation: + { + long fileId = BitConverter.ToInt64(data, 0); + retValue = "FileInternalInformation result, fileId: (0x)" + fileId.ToString("X"); + break; + } + + default: + { + retValue = infoClass.ToString() + "(" + ((uint)infoClass).ToString("X") + ")"; + break; + } + } + + } + catch (Exception ex) + { + EventManager.WriteMessage(594, "FormatInformationDataBuffer", EventLevel.Error, "Format data failed." + ex.Message); + retValue = ex.Message; + } + + return retValue; + } + + public static string FormatStatus(uint status) + { + string ret = string.Empty; + + foreach (NtStatus.Status ntStatus in Enum.GetValues(typeof(NtStatus.Status))) + { + if (status == (uint)ntStatus) + { + ret = ntStatus.ToString() + "(0x" + status.ToString("X") + ")"; + } + } + + if (string.IsNullOrEmpty(ret)) + { + ret = "(0x" + status.ToString("X") + ")"; + } + + return ret; + } + + public static string FormatSecurityInfoClass(uint infoClass) + { + string ret = string.Empty; + + foreach (WinData.SecurityInformation security in Enum.GetValues(typeof(WinData.SecurityInformation))) + { + if ((infoClass & (int)security) > 0) + { + if (ret.Length > 0) + { + ret += ";"; + } + + ret += security.ToString(); + } + } + + return ret; + } + + + } +} \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/CommonObjects/FilterRuleForm.Designer.cs b/Demo_Source_Code/CSharpDemo/CommonObjects/FilterRuleForm.Designer.cs new file mode 100644 index 0000000..41b2589 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/CommonObjects/FilterRuleForm.Designer.cs @@ -0,0 +1,773 @@ +namespace EaseFilter.CommonObjects +{ + partial class FilterRuleForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FilterRuleForm)); + this.label3 = new System.Windows.Forms.Label(); + this.button_SaveFilterRule = new System.Windows.Forms.Button(); + this.textBox_ExcludeFilterMask = new System.Windows.Forms.TextBox(); + this.label2 = new System.Windows.Forms.Label(); + this.label1 = new System.Windows.Forms.Label(); + this.textBox_IncludeFilterMask = new System.Windows.Forms.TextBox(); + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.button_ControlSettings = new System.Windows.Forms.Button(); + this.groupBox_AccessControl = new System.Windows.Forms.GroupBox(); + this.button_MonitorBufferInfo = new System.Windows.Forms.Button(); + this.checkBox_MonitorEventBuffer = new System.Windows.Forms.CheckBox(); + this.button_InfoMonitorIO = new System.Windows.Forms.Button(); + this.button_InfoFileEvents = new System.Windows.Forms.Button(); + this.textBox_SelectedEvents = new System.Windows.Forms.TextBox(); + this.label9 = new System.Windows.Forms.Label(); + this.label18 = new System.Windows.Forms.Label(); + this.button_SelectedEvents = new System.Windows.Forms.Button(); + this.button_RegisterMonitorIO = new System.Windows.Forms.Button(); + this.label16 = new System.Windows.Forms.Label(); + this.textBox_MonitorIO = new System.Windows.Forms.TextBox(); + this.label20 = new System.Windows.Forms.Label(); + this.label13 = new System.Windows.Forms.Label(); + this.textBox_ExcludeUserNames = new System.Windows.Forms.TextBox(); + this.label14 = new System.Windows.Forms.Label(); + this.textBox_IncludeUserNames = new System.Windows.Forms.TextBox(); + this.label15 = new System.Windows.Forms.Label(); + this.label12 = new System.Windows.Forms.Label(); + this.textBox_ExcludeProcessNames = new System.Windows.Forms.TextBox(); + this.label11 = new System.Windows.Forms.Label(); + this.textBox_IncludeProcessNames = new System.Windows.Forms.TextBox(); + this.label10 = new System.Windows.Forms.Label(); + this.button_SelectExcludePID = new System.Windows.Forms.Button(); + this.textBox_ExcludePID = new System.Windows.Forms.TextBox(); + this.label5 = new System.Windows.Forms.Label(); + this.button_SelectIncludePID = new System.Windows.Forms.Button(); + this.textBox_IncludePID = new System.Windows.Forms.TextBox(); + this.label6 = new System.Windows.Forms.Label(); + this.button_FilterCreateOptions = new System.Windows.Forms.Button(); + this.textBox_FilterCreateOptions = new System.Windows.Forms.TextBox(); + this.label7 = new System.Windows.Forms.Label(); + this.button_FilterDisposition = new System.Windows.Forms.Button(); + this.textBox_FilterDisposition = new System.Windows.Forms.TextBox(); + this.label8 = new System.Windows.Forms.Label(); + this.button_FilterDesiredAccess = new System.Windows.Forms.Button(); + this.textBox_FilterDesiredAccess = new System.Windows.Forms.TextBox(); + this.label17 = new System.Windows.Forms.Label(); + this.groupBox2 = new System.Windows.Forms.GroupBox(); + this.button_InfoExcludeUserName = new System.Windows.Forms.Button(); + this.groupBox3 = new System.Windows.Forms.GroupBox(); + this.button_InfoCreatOptions = new System.Windows.Forms.Button(); + this.button_InfoDisposition = new System.Windows.Forms.Button(); + this.button_InfoDesiredAccess = new System.Windows.Forms.Button(); + this.button_InfoIncludeUserName = new System.Windows.Forms.Button(); + this.button_InfoExcludeFileFilterMask = new System.Windows.Forms.Button(); + this.button_InfoIncludeProcessName = new System.Windows.Forms.Button(); + this.button_InfoExcludeProcessName = new System.Windows.Forms.Button(); + this.button_InfoFilterMask = new System.Windows.Forms.Button(); + this.button_ProcessFilterRule = new System.Windows.Forms.Button(); + this.groupBox1.SuspendLayout(); + this.groupBox_AccessControl.SuspendLayout(); + this.groupBox2.SuspendLayout(); + this.groupBox3.SuspendLayout(); + this.SuspendLayout(); + // + // label3 + // + this.label3.AutoSize = true; + this.label3.Font = new System.Drawing.Font("Microsoft Sans Serif", 6.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.label3.Location = new System.Drawing.Point(198, 69); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(131, 12); + this.label3.TabIndex = 9; + this.label3.Text = "( split with \';\' for multiple items)"; + // + // button_SaveFilterRule + // + this.button_SaveFilterRule.DialogResult = System.Windows.Forms.DialogResult.OK; + this.button_SaveFilterRule.Location = new System.Drawing.Point(438, 592); + this.button_SaveFilterRule.Name = "button_SaveFilterRule"; + this.button_SaveFilterRule.Size = new System.Drawing.Size(75, 23); + this.button_SaveFilterRule.TabIndex = 8; + this.button_SaveFilterRule.Text = "Save"; + this.button_SaveFilterRule.UseVisualStyleBackColor = true; + this.button_SaveFilterRule.Click += new System.EventHandler(this.button_SaveFilter_Click); + // + // textBox_ExcludeFilterMask + // + this.textBox_ExcludeFilterMask.Location = new System.Drawing.Point(200, 46); + this.textBox_ExcludeFilterMask.Name = "textBox_ExcludeFilterMask"; + this.textBox_ExcludeFilterMask.Size = new System.Drawing.Size(242, 20); + this.textBox_ExcludeFilterMask.TabIndex = 4; + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(14, 53); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(111, 13); + this.label2.TabIndex = 2; + this.label2.Text = "Exclude file filter mask"; + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(15, 23); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(112, 13); + this.label1.TabIndex = 1; + this.label1.Text = "Manage file filter mask"; + // + // textBox_IncludeFilterMask + // + this.textBox_IncludeFilterMask.Location = new System.Drawing.Point(200, 16); + this.textBox_IncludeFilterMask.Name = "textBox_IncludeFilterMask"; + this.textBox_IncludeFilterMask.Size = new System.Drawing.Size(242, 20); + this.textBox_IncludeFilterMask.TabIndex = 0; + this.textBox_IncludeFilterMask.Text = "c:\\test\\*"; + // + // groupBox1 + // + this.groupBox1.Controls.Add(this.button_ProcessFilterRule); + this.groupBox1.Controls.Add(this.button_ControlSettings); + this.groupBox1.Location = new System.Drawing.Point(12, 2); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size(547, 584); + this.groupBox1.TabIndex = 11; + this.groupBox1.TabStop = false; + // + // button_ControlSettings + // + this.button_ControlSettings.BackColor = System.Drawing.SystemColors.GradientActiveCaption; + this.button_ControlSettings.Location = new System.Drawing.Point(12, 523); + this.button_ControlSettings.Name = "button_ControlSettings"; + this.button_ControlSettings.Size = new System.Drawing.Size(489, 23); + this.button_ControlSettings.TabIndex = 12; + this.button_ControlSettings.Text = "Configure the control filter rule settings"; + this.button_ControlSettings.UseVisualStyleBackColor = false; + this.button_ControlSettings.Click += new System.EventHandler(this.button_ControlSettings_Click); + // + // groupBox_AccessControl + // + this.groupBox_AccessControl.Controls.Add(this.button_MonitorBufferInfo); + this.groupBox_AccessControl.Controls.Add(this.checkBox_MonitorEventBuffer); + this.groupBox_AccessControl.Controls.Add(this.button_InfoMonitorIO); + this.groupBox_AccessControl.Controls.Add(this.button_InfoFileEvents); + this.groupBox_AccessControl.Controls.Add(this.textBox_SelectedEvents); + this.groupBox_AccessControl.Controls.Add(this.label9); + this.groupBox_AccessControl.Controls.Add(this.label18); + this.groupBox_AccessControl.Controls.Add(this.button_SelectedEvents); + this.groupBox_AccessControl.Controls.Add(this.button_RegisterMonitorIO); + this.groupBox_AccessControl.Controls.Add(this.label16); + this.groupBox_AccessControl.Controls.Add(this.textBox_MonitorIO); + this.groupBox_AccessControl.Location = new System.Drawing.Point(12, 403); + this.groupBox_AccessControl.Name = "groupBox_AccessControl"; + this.groupBox_AccessControl.Size = new System.Drawing.Size(547, 116); + this.groupBox_AccessControl.TabIndex = 24; + this.groupBox_AccessControl.TabStop = false; + this.groupBox_AccessControl.Text = "Monitor Filter Only Settings"; + // + // button_MonitorBufferInfo + // + this.button_MonitorBufferInfo.Image = global::EaseFilter.CommonObjects.Properties.Resources.about; + this.button_MonitorBufferInfo.Location = new System.Drawing.Point(364, 84); + this.button_MonitorBufferInfo.Name = "button_MonitorBufferInfo"; + this.button_MonitorBufferInfo.Size = new System.Drawing.Size(28, 20); + this.button_MonitorBufferInfo.TabIndex = 121; + this.button_MonitorBufferInfo.UseVisualStyleBackColor = true; + this.button_MonitorBufferInfo.Click += new System.EventHandler(this.button_MonitorBufferInfo_Click); + // + // checkBox_MonitorEventBuffer + // + this.checkBox_MonitorEventBuffer.AutoSize = true; + this.checkBox_MonitorEventBuffer.Location = new System.Drawing.Point(199, 87); + this.checkBox_MonitorEventBuffer.Name = "checkBox_MonitorEventBuffer"; + this.checkBox_MonitorEventBuffer.Size = new System.Drawing.Size(159, 17); + this.checkBox_MonitorEventBuffer.TabIndex = 120; + this.checkBox_MonitorEventBuffer.Text = "Enable Monitor Event Buffer"; + this.checkBox_MonitorEventBuffer.UseVisualStyleBackColor = true; + // + // button_InfoMonitorIO + // + this.button_InfoMonitorIO.Image = global::EaseFilter.CommonObjects.Properties.Resources.about; + this.button_InfoMonitorIO.Location = new System.Drawing.Point(513, 56); + this.button_InfoMonitorIO.Name = "button_InfoMonitorIO"; + this.button_InfoMonitorIO.Size = new System.Drawing.Size(28, 20); + this.button_InfoMonitorIO.TabIndex = 118; + this.button_InfoMonitorIO.UseVisualStyleBackColor = true; + this.button_InfoMonitorIO.Click += new System.EventHandler(this.button_InfoMonitorIO_Click); + // + // button_InfoFileEvents + // + this.button_InfoFileEvents.Image = global::EaseFilter.CommonObjects.Properties.Resources.about; + this.button_InfoFileEvents.Location = new System.Drawing.Point(513, 16); + this.button_InfoFileEvents.Name = "button_InfoFileEvents"; + this.button_InfoFileEvents.Size = new System.Drawing.Size(28, 20); + this.button_InfoFileEvents.TabIndex = 119; + this.button_InfoFileEvents.UseVisualStyleBackColor = true; + this.button_InfoFileEvents.Click += new System.EventHandler(this.button_InfoFileEvents_Click); + // + // textBox_SelectedEvents + // + this.textBox_SelectedEvents.Location = new System.Drawing.Point(200, 16); + this.textBox_SelectedEvents.Name = "textBox_SelectedEvents"; + this.textBox_SelectedEvents.ReadOnly = true; + this.textBox_SelectedEvents.Size = new System.Drawing.Size(242, 20); + this.textBox_SelectedEvents.TabIndex = 51; + this.textBox_SelectedEvents.Text = "0"; + // + // label9 + // + this.label9.AutoSize = true; + this.label9.Location = new System.Drawing.Point(10, 23); + this.label9.Name = "label9"; + this.label9.Size = new System.Drawing.Size(97, 13); + this.label9.TabIndex = 50; + this.label9.Text = "Register file events"; + // + // label18 + // + this.label18.AutoSize = true; + this.label18.Font = new System.Drawing.Font("Microsoft Sans Serif", 6.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.label18.Location = new System.Drawing.Point(197, 39); + this.label18.Name = "label18"; + this.label18.Size = new System.Drawing.Size(237, 12); + this.label18.TabIndex = 72; + this.label18.Text = "(Receive file event notification after file handle is closed )"; + // + // button_SelectedEvents + // + this.button_SelectedEvents.Location = new System.Drawing.Point(460, 16); + this.button_SelectedEvents.Name = "button_SelectedEvents"; + this.button_SelectedEvents.Size = new System.Drawing.Size(41, 20); + this.button_SelectedEvents.TabIndex = 52; + this.button_SelectedEvents.Text = "..."; + this.button_SelectedEvents.UseVisualStyleBackColor = true; + this.button_SelectedEvents.Click += new System.EventHandler(this.button_SelectedEvents_Click); + // + // button_RegisterMonitorIO + // + this.button_RegisterMonitorIO.Location = new System.Drawing.Point(460, 56); + this.button_RegisterMonitorIO.Name = "button_RegisterMonitorIO"; + this.button_RegisterMonitorIO.Size = new System.Drawing.Size(41, 20); + this.button_RegisterMonitorIO.TabIndex = 71; + this.button_RegisterMonitorIO.Text = "..."; + this.button_RegisterMonitorIO.UseVisualStyleBackColor = true; + this.button_RegisterMonitorIO.Click += new System.EventHandler(this.button_RegisterMonitorIO_Click); + // + // label16 + // + this.label16.AutoSize = true; + this.label16.Location = new System.Drawing.Point(10, 56); + this.label16.Name = "label16"; + this.label16.Size = new System.Drawing.Size(97, 13); + this.label16.TabIndex = 69; + this.label16.Text = "Register monitor IO"; + // + // textBox_MonitorIO + // + this.textBox_MonitorIO.Location = new System.Drawing.Point(198, 56); + this.textBox_MonitorIO.Name = "textBox_MonitorIO"; + this.textBox_MonitorIO.ReadOnly = true; + this.textBox_MonitorIO.Size = new System.Drawing.Size(242, 20); + this.textBox_MonitorIO.TabIndex = 70; + this.textBox_MonitorIO.Text = "0"; + // + // label20 + // + this.label20.AutoSize = true; + this.label20.Font = new System.Drawing.Font("Microsoft Sans Serif", 6.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.label20.Location = new System.Drawing.Point(198, 179); + this.label20.Name = "label20"; + this.label20.Size = new System.Drawing.Size(222, 12); + this.label20.TabIndex = 74; + this.label20.Text = "( split with \';\' for multiple items, format \"notepad.exe\")"; + // + // label13 + // + this.label13.AutoSize = true; + this.label13.Font = new System.Drawing.Font("Microsoft Sans Serif", 6.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.label13.Location = new System.Drawing.Point(197, 246); + this.label13.Name = "label13"; + this.label13.Size = new System.Drawing.Size(245, 12); + this.label13.TabIndex = 68; + this.label13.Text = "(split with \';\' for multiple items, format \"domain\\username\" )"; + // + // textBox_ExcludeUserNames + // + this.textBox_ExcludeUserNames.Location = new System.Drawing.Point(200, 261); + this.textBox_ExcludeUserNames.Name = "textBox_ExcludeUserNames"; + this.textBox_ExcludeUserNames.Size = new System.Drawing.Size(242, 20); + this.textBox_ExcludeUserNames.TabIndex = 67; + // + // label14 + // + this.label14.AutoSize = true; + this.label14.Location = new System.Drawing.Point(14, 261); + this.label14.Name = "label14"; + this.label14.Size = new System.Drawing.Size(102, 13); + this.label14.TabIndex = 66; + this.label14.Text = "Exclude user names"; + // + // textBox_IncludeUserNames + // + this.textBox_IncludeUserNames.Location = new System.Drawing.Point(200, 223); + this.textBox_IncludeUserNames.Name = "textBox_IncludeUserNames"; + this.textBox_IncludeUserNames.Size = new System.Drawing.Size(242, 20); + this.textBox_IncludeUserNames.TabIndex = 65; + // + // label15 + // + this.label15.AutoSize = true; + this.label15.Location = new System.Drawing.Point(14, 230); + this.label15.Name = "label15"; + this.label15.Size = new System.Drawing.Size(99, 13); + this.label15.TabIndex = 64; + this.label15.Text = "Include user names"; + // + // label12 + // + this.label12.AutoSize = true; + this.label12.Font = new System.Drawing.Font("Microsoft Sans Serif", 6.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.label12.Location = new System.Drawing.Point(198, 108); + this.label12.Name = "label12"; + this.label12.Size = new System.Drawing.Size(222, 12); + this.label12.TabIndex = 57; + this.label12.Text = "( split with \';\' for multiple items, format \"notepad.exe\")"; + // + // textBox_ExcludeProcessNames + // + this.textBox_ExcludeProcessNames.Location = new System.Drawing.Point(200, 158); + this.textBox_ExcludeProcessNames.Name = "textBox_ExcludeProcessNames"; + this.textBox_ExcludeProcessNames.Size = new System.Drawing.Size(242, 20); + this.textBox_ExcludeProcessNames.TabIndex = 56; + // + // label11 + // + this.label11.AutoSize = true; + this.label11.Location = new System.Drawing.Point(14, 158); + this.label11.Name = "label11"; + this.label11.Size = new System.Drawing.Size(119, 13); + this.label11.TabIndex = 55; + this.label11.Text = "Exclude process names"; + // + // textBox_IncludeProcessNames + // + this.textBox_IncludeProcessNames.Location = new System.Drawing.Point(200, 85); + this.textBox_IncludeProcessNames.Name = "textBox_IncludeProcessNames"; + this.textBox_IncludeProcessNames.Size = new System.Drawing.Size(242, 20); + this.textBox_IncludeProcessNames.TabIndex = 54; + // + // label10 + // + this.label10.AutoSize = true; + this.label10.Location = new System.Drawing.Point(15, 92); + this.label10.Name = "label10"; + this.label10.Size = new System.Drawing.Size(116, 13); + this.label10.TabIndex = 53; + this.label10.Text = "Include process names"; + // + // button_SelectExcludePID + // + this.button_SelectExcludePID.Location = new System.Drawing.Point(460, 195); + this.button_SelectExcludePID.Name = "button_SelectExcludePID"; + this.button_SelectExcludePID.Size = new System.Drawing.Size(41, 20); + this.button_SelectExcludePID.TabIndex = 44; + this.button_SelectExcludePID.Text = "..."; + this.button_SelectExcludePID.UseVisualStyleBackColor = true; + this.button_SelectExcludePID.Click += new System.EventHandler(this.button_SelectExcludePID_Click); + // + // textBox_ExcludePID + // + this.textBox_ExcludePID.Location = new System.Drawing.Point(200, 195); + this.textBox_ExcludePID.Name = "textBox_ExcludePID"; + this.textBox_ExcludePID.ReadOnly = true; + this.textBox_ExcludePID.Size = new System.Drawing.Size(242, 20); + this.textBox_ExcludePID.TabIndex = 43; + // + // label5 + // + this.label5.AutoSize = true; + this.label5.Location = new System.Drawing.Point(14, 197); + this.label5.Name = "label5"; + this.label5.Size = new System.Drawing.Size(102, 13); + this.label5.TabIndex = 42; + this.label5.Text = "Exclude process Ids"; + // + // button_SelectIncludePID + // + this.button_SelectIncludePID.Location = new System.Drawing.Point(460, 128); + this.button_SelectIncludePID.Name = "button_SelectIncludePID"; + this.button_SelectIncludePID.Size = new System.Drawing.Size(41, 20); + this.button_SelectIncludePID.TabIndex = 41; + this.button_SelectIncludePID.Text = "..."; + this.button_SelectIncludePID.UseVisualStyleBackColor = true; + this.button_SelectIncludePID.Click += new System.EventHandler(this.button_SelectIncludePID_Click); + // + // textBox_IncludePID + // + this.textBox_IncludePID.Location = new System.Drawing.Point(200, 128); + this.textBox_IncludePID.Name = "textBox_IncludePID"; + this.textBox_IncludePID.ReadOnly = true; + this.textBox_IncludePID.Size = new System.Drawing.Size(242, 20); + this.textBox_IncludePID.TabIndex = 40; + // + // label6 + // + this.label6.AutoSize = true; + this.label6.Location = new System.Drawing.Point(15, 127); + this.label6.Name = "label6"; + this.label6.Size = new System.Drawing.Size(99, 13); + this.label6.TabIndex = 39; + this.label6.Text = "Include process Ids"; + // + // button_FilterCreateOptions + // + this.button_FilterCreateOptions.Location = new System.Drawing.Point(460, 72); + this.button_FilterCreateOptions.Name = "button_FilterCreateOptions"; + this.button_FilterCreateOptions.Size = new System.Drawing.Size(41, 20); + this.button_FilterCreateOptions.TabIndex = 111; + this.button_FilterCreateOptions.Text = "..."; + this.button_FilterCreateOptions.UseVisualStyleBackColor = true; + this.button_FilterCreateOptions.Click += new System.EventHandler(this.button_FilterCreateOptions_Click); + // + // textBox_FilterCreateOptions + // + this.textBox_FilterCreateOptions.Location = new System.Drawing.Point(200, 72); + this.textBox_FilterCreateOptions.Name = "textBox_FilterCreateOptions"; + this.textBox_FilterCreateOptions.ReadOnly = true; + this.textBox_FilterCreateOptions.Size = new System.Drawing.Size(242, 20); + this.textBox_FilterCreateOptions.TabIndex = 110; + this.textBox_FilterCreateOptions.Text = "0"; + // + // label7 + // + this.label7.AutoSize = true; + this.label7.Location = new System.Drawing.Point(10, 77); + this.label7.Name = "label7"; + this.label7.Size = new System.Drawing.Size(152, 13); + this.label7.TabIndex = 109; + this.label7.Text = "Create File With CreateOptions"; + // + // button_FilterDisposition + // + this.button_FilterDisposition.Location = new System.Drawing.Point(460, 46); + this.button_FilterDisposition.Name = "button_FilterDisposition"; + this.button_FilterDisposition.Size = new System.Drawing.Size(41, 20); + this.button_FilterDisposition.TabIndex = 108; + this.button_FilterDisposition.Text = "..."; + this.button_FilterDisposition.UseVisualStyleBackColor = true; + this.button_FilterDisposition.Click += new System.EventHandler(this.button_FilterDisposition_Click); + // + // textBox_FilterDisposition + // + this.textBox_FilterDisposition.Location = new System.Drawing.Point(200, 46); + this.textBox_FilterDisposition.Name = "textBox_FilterDisposition"; + this.textBox_FilterDisposition.ReadOnly = true; + this.textBox_FilterDisposition.Size = new System.Drawing.Size(242, 20); + this.textBox_FilterDisposition.TabIndex = 107; + this.textBox_FilterDisposition.Text = "0"; + // + // label8 + // + this.label8.AutoSize = true; + this.label8.Location = new System.Drawing.Point(10, 51); + this.label8.Name = "label8"; + this.label8.Size = new System.Drawing.Size(136, 13); + this.label8.TabIndex = 106; + this.label8.Text = "Create File With Disposition"; + // + // button_FilterDesiredAccess + // + this.button_FilterDesiredAccess.Location = new System.Drawing.Point(460, 20); + this.button_FilterDesiredAccess.Name = "button_FilterDesiredAccess"; + this.button_FilterDesiredAccess.Size = new System.Drawing.Size(41, 20); + this.button_FilterDesiredAccess.TabIndex = 105; + this.button_FilterDesiredAccess.Text = "..."; + this.button_FilterDesiredAccess.UseVisualStyleBackColor = true; + this.button_FilterDesiredAccess.Click += new System.EventHandler(this.button_FilterDesiredAccess_Click); + // + // textBox_FilterDesiredAccess + // + this.textBox_FilterDesiredAccess.Location = new System.Drawing.Point(200, 20); + this.textBox_FilterDesiredAccess.Name = "textBox_FilterDesiredAccess"; + this.textBox_FilterDesiredAccess.ReadOnly = true; + this.textBox_FilterDesiredAccess.Size = new System.Drawing.Size(242, 20); + this.textBox_FilterDesiredAccess.TabIndex = 104; + this.textBox_FilterDesiredAccess.Text = "0"; + // + // label17 + // + this.label17.AutoSize = true; + this.label17.Location = new System.Drawing.Point(10, 25); + this.label17.Name = "label17"; + this.label17.Size = new System.Drawing.Size(156, 13); + this.label17.TabIndex = 103; + this.label17.Text = "Create File With DesiredAccess"; + // + // groupBox2 + // + this.groupBox2.Controls.Add(this.button_InfoExcludeUserName); + this.groupBox2.Controls.Add(this.groupBox3); + this.groupBox2.Controls.Add(this.button_InfoIncludeUserName); + this.groupBox2.Controls.Add(this.button_InfoExcludeFileFilterMask); + this.groupBox2.Controls.Add(this.button_InfoIncludeProcessName); + this.groupBox2.Controls.Add(this.button_InfoExcludeProcessName); + this.groupBox2.Controls.Add(this.button_InfoFilterMask); + this.groupBox2.Controls.Add(this.label10); + this.groupBox2.Controls.Add(this.label20); + this.groupBox2.Controls.Add(this.label1); + this.groupBox2.Controls.Add(this.label13); + this.groupBox2.Controls.Add(this.label3); + this.groupBox2.Controls.Add(this.textBox_ExcludeUserNames); + this.groupBox2.Controls.Add(this.textBox_IncludeFilterMask); + this.groupBox2.Controls.Add(this.label14); + this.groupBox2.Controls.Add(this.textBox_IncludeUserNames); + this.groupBox2.Controls.Add(this.label2); + this.groupBox2.Controls.Add(this.label15); + this.groupBox2.Controls.Add(this.textBox_ExcludeFilterMask); + this.groupBox2.Controls.Add(this.label12); + this.groupBox2.Controls.Add(this.label6); + this.groupBox2.Controls.Add(this.textBox_ExcludeProcessNames); + this.groupBox2.Controls.Add(this.textBox_IncludePID); + this.groupBox2.Controls.Add(this.label11); + this.groupBox2.Controls.Add(this.button_SelectIncludePID); + this.groupBox2.Controls.Add(this.textBox_IncludeProcessNames); + this.groupBox2.Controls.Add(this.label5); + this.groupBox2.Controls.Add(this.textBox_ExcludePID); + this.groupBox2.Controls.Add(this.button_SelectExcludePID); + this.groupBox2.Location = new System.Drawing.Point(12, 10); + this.groupBox2.Name = "groupBox2"; + this.groupBox2.Size = new System.Drawing.Size(547, 390); + this.groupBox2.TabIndex = 75; + this.groupBox2.TabStop = false; + // + // button_InfoExcludeUserName + // + this.button_InfoExcludeUserName.Image = global::EaseFilter.CommonObjects.Properties.Resources.about; + this.button_InfoExcludeUserName.Location = new System.Drawing.Point(460, 261); + this.button_InfoExcludeUserName.Name = "button_InfoExcludeUserName"; + this.button_InfoExcludeUserName.Size = new System.Drawing.Size(41, 20); + this.button_InfoExcludeUserName.TabIndex = 117; + this.button_InfoExcludeUserName.UseVisualStyleBackColor = true; + this.button_InfoExcludeUserName.Click += new System.EventHandler(this.button_InfoExcludeUserName_Click); + // + // groupBox3 + // + this.groupBox3.Controls.Add(this.button_InfoCreatOptions); + this.groupBox3.Controls.Add(this.button_InfoDisposition); + this.groupBox3.Controls.Add(this.button_InfoDesiredAccess); + this.groupBox3.Controls.Add(this.textBox_FilterDisposition); + this.groupBox3.Controls.Add(this.label17); + this.groupBox3.Controls.Add(this.textBox_FilterDesiredAccess); + this.groupBox3.Controls.Add(this.button_FilterDesiredAccess); + this.groupBox3.Controls.Add(this.label8); + this.groupBox3.Controls.Add(this.button_FilterDisposition); + this.groupBox3.Controls.Add(this.button_FilterCreateOptions); + this.groupBox3.Controls.Add(this.label7); + this.groupBox3.Controls.Add(this.textBox_FilterCreateOptions); + this.groupBox3.Location = new System.Drawing.Point(0, 287); + this.groupBox3.Name = "groupBox3"; + this.groupBox3.Size = new System.Drawing.Size(547, 100); + this.groupBox3.TabIndex = 116; + this.groupBox3.TabStop = false; + this.groupBox3.Text = "Filter I/O by the Open Options"; + // + // button_InfoCreatOptions + // + this.button_InfoCreatOptions.Image = global::EaseFilter.CommonObjects.Properties.Resources.about; + this.button_InfoCreatOptions.Location = new System.Drawing.Point(513, 72); + this.button_InfoCreatOptions.Name = "button_InfoCreatOptions"; + this.button_InfoCreatOptions.Size = new System.Drawing.Size(28, 20); + this.button_InfoCreatOptions.TabIndex = 119; + this.button_InfoCreatOptions.UseVisualStyleBackColor = true; + this.button_InfoCreatOptions.Click += new System.EventHandler(this.button_InfoCreatOptions_Click); + // + // button_InfoDisposition + // + this.button_InfoDisposition.Image = global::EaseFilter.CommonObjects.Properties.Resources.about; + this.button_InfoDisposition.Location = new System.Drawing.Point(513, 46); + this.button_InfoDisposition.Name = "button_InfoDisposition"; + this.button_InfoDisposition.Size = new System.Drawing.Size(28, 20); + this.button_InfoDisposition.TabIndex = 118; + this.button_InfoDisposition.UseVisualStyleBackColor = true; + this.button_InfoDisposition.Click += new System.EventHandler(this.button_InfoDisposition_Click); + // + // button_InfoDesiredAccess + // + this.button_InfoDesiredAccess.Image = global::EaseFilter.CommonObjects.Properties.Resources.about; + this.button_InfoDesiredAccess.Location = new System.Drawing.Point(513, 20); + this.button_InfoDesiredAccess.Name = "button_InfoDesiredAccess"; + this.button_InfoDesiredAccess.Size = new System.Drawing.Size(28, 20); + this.button_InfoDesiredAccess.TabIndex = 117; + this.button_InfoDesiredAccess.UseVisualStyleBackColor = true; + this.button_InfoDesiredAccess.Click += new System.EventHandler(this.button_InfoDesiredAccess_Click); + // + // button_InfoIncludeUserName + // + this.button_InfoIncludeUserName.Image = global::EaseFilter.CommonObjects.Properties.Resources.about; + this.button_InfoIncludeUserName.Location = new System.Drawing.Point(460, 230); + this.button_InfoIncludeUserName.Name = "button_InfoIncludeUserName"; + this.button_InfoIncludeUserName.Size = new System.Drawing.Size(41, 20); + this.button_InfoIncludeUserName.TabIndex = 113; + this.button_InfoIncludeUserName.UseVisualStyleBackColor = true; + this.button_InfoIncludeUserName.Click += new System.EventHandler(this.button_InfoIncludeUserName_Click); + // + // button_InfoExcludeFileFilterMask + // + this.button_InfoExcludeFileFilterMask.Image = global::EaseFilter.CommonObjects.Properties.Resources.about; + this.button_InfoExcludeFileFilterMask.Location = new System.Drawing.Point(460, 46); + this.button_InfoExcludeFileFilterMask.Name = "button_InfoExcludeFileFilterMask"; + this.button_InfoExcludeFileFilterMask.Size = new System.Drawing.Size(41, 20); + this.button_InfoExcludeFileFilterMask.TabIndex = 115; + this.button_InfoExcludeFileFilterMask.UseVisualStyleBackColor = true; + this.button_InfoExcludeFileFilterMask.Click += new System.EventHandler(this.button_InfoExcludeFileFilterMask_Click); + // + // button_InfoIncludeProcessName + // + this.button_InfoIncludeProcessName.Image = global::EaseFilter.CommonObjects.Properties.Resources.about; + this.button_InfoIncludeProcessName.Location = new System.Drawing.Point(460, 85); + this.button_InfoIncludeProcessName.Name = "button_InfoIncludeProcessName"; + this.button_InfoIncludeProcessName.Size = new System.Drawing.Size(41, 20); + this.button_InfoIncludeProcessName.TabIndex = 114; + this.button_InfoIncludeProcessName.UseVisualStyleBackColor = true; + this.button_InfoIncludeProcessName.Click += new System.EventHandler(this.button_InfoIncludeProcessName_Click); + // + // button_InfoExcludeProcessName + // + this.button_InfoExcludeProcessName.Image = global::EaseFilter.CommonObjects.Properties.Resources.about; + this.button_InfoExcludeProcessName.Location = new System.Drawing.Point(460, 158); + this.button_InfoExcludeProcessName.Name = "button_InfoExcludeProcessName"; + this.button_InfoExcludeProcessName.Size = new System.Drawing.Size(41, 20); + this.button_InfoExcludeProcessName.TabIndex = 113; + this.button_InfoExcludeProcessName.UseVisualStyleBackColor = true; + this.button_InfoExcludeProcessName.Click += new System.EventHandler(this.button_InfoExcludeProcessName_Click); + // + // button_InfoFilterMask + // + this.button_InfoFilterMask.Image = global::EaseFilter.CommonObjects.Properties.Resources.about; + this.button_InfoFilterMask.Location = new System.Drawing.Point(460, 16); + this.button_InfoFilterMask.Name = "button_InfoFilterMask"; + this.button_InfoFilterMask.Size = new System.Drawing.Size(41, 20); + this.button_InfoFilterMask.TabIndex = 112; + this.button_InfoFilterMask.UseVisualStyleBackColor = true; + this.button_InfoFilterMask.Click += new System.EventHandler(this.button_InfoFilterMask_Click); + // + // button_ProcessFilterRule + // + this.button_ProcessFilterRule.BackColor = System.Drawing.SystemColors.GradientActiveCaption; + this.button_ProcessFilterRule.Location = new System.Drawing.Point(12, 552); + this.button_ProcessFilterRule.Name = "button_ProcessFilterRule"; + this.button_ProcessFilterRule.Size = new System.Drawing.Size(489, 23); + this.button_ProcessFilterRule.TabIndex = 76; + this.button_ProcessFilterRule.Text = "Configure the process filter rule settings"; + this.button_ProcessFilterRule.UseVisualStyleBackColor = false; + this.button_ProcessFilterRule.Click += new System.EventHandler(this.button_ProcessFilterRule_Click); + // + // FilterRuleForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.AutoScroll = true; + this.ClientSize = new System.Drawing.Size(571, 622); + this.Controls.Add(this.groupBox2); + this.Controls.Add(this.groupBox_AccessControl); + this.Controls.Add(this.groupBox1); + this.Controls.Add(this.button_SaveFilterRule); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Name = "FilterRuleForm"; + this.Text = "Filter rule settings"; + this.groupBox1.ResumeLayout(false); + this.groupBox_AccessControl.ResumeLayout(false); + this.groupBox_AccessControl.PerformLayout(); + this.groupBox2.ResumeLayout(false); + this.groupBox2.PerformLayout(); + this.groupBox3.ResumeLayout(false); + this.groupBox3.PerformLayout(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.TextBox textBox_ExcludeFilterMask; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.TextBox textBox_IncludeFilterMask; + private System.Windows.Forms.Button button_SaveFilterRule; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.GroupBox groupBox1; + private System.Windows.Forms.GroupBox groupBox_AccessControl; + private System.Windows.Forms.Button button_SelectExcludePID; + private System.Windows.Forms.TextBox textBox_ExcludePID; + private System.Windows.Forms.Label label5; + private System.Windows.Forms.Button button_SelectIncludePID; + private System.Windows.Forms.TextBox textBox_IncludePID; + private System.Windows.Forms.Label label6; + private System.Windows.Forms.Label label9; + private System.Windows.Forms.TextBox textBox_ExcludeProcessNames; + private System.Windows.Forms.Label label11; + private System.Windows.Forms.TextBox textBox_IncludeProcessNames; + private System.Windows.Forms.Label label10; + private System.Windows.Forms.Label label12; + private System.Windows.Forms.Label label13; + private System.Windows.Forms.TextBox textBox_ExcludeUserNames; + private System.Windows.Forms.Label label14; + private System.Windows.Forms.TextBox textBox_IncludeUserNames; + private System.Windows.Forms.Label label15; + private System.Windows.Forms.Button button_SelectedEvents; + private System.Windows.Forms.TextBox textBox_SelectedEvents; + private System.Windows.Forms.Button button_RegisterMonitorIO; + private System.Windows.Forms.TextBox textBox_MonitorIO; + private System.Windows.Forms.Label label16; + private System.Windows.Forms.Label label18; + private System.Windows.Forms.Label label20; + private System.Windows.Forms.Button button_ControlSettings; + private System.Windows.Forms.Button button_FilterCreateOptions; + private System.Windows.Forms.TextBox textBox_FilterCreateOptions; + private System.Windows.Forms.Label label7; + private System.Windows.Forms.Button button_FilterDisposition; + private System.Windows.Forms.TextBox textBox_FilterDisposition; + private System.Windows.Forms.Label label8; + private System.Windows.Forms.Button button_FilterDesiredAccess; + private System.Windows.Forms.TextBox textBox_FilterDesiredAccess; + private System.Windows.Forms.Label label17; + private System.Windows.Forms.GroupBox groupBox2; + private System.Windows.Forms.Button button_InfoIncludeUserName; + private System.Windows.Forms.Button button_InfoExcludeFileFilterMask; + private System.Windows.Forms.Button button_InfoIncludeProcessName; + private System.Windows.Forms.Button button_InfoExcludeProcessName; + private System.Windows.Forms.Button button_InfoFilterMask; + private System.Windows.Forms.GroupBox groupBox3; + private System.Windows.Forms.Button button_InfoMonitorIO; + private System.Windows.Forms.Button button_InfoFileEvents; + private System.Windows.Forms.Button button_InfoExcludeUserName; + private System.Windows.Forms.Button button_InfoCreatOptions; + private System.Windows.Forms.Button button_InfoDisposition; + private System.Windows.Forms.Button button_InfoDesiredAccess; + private System.Windows.Forms.Button button_MonitorBufferInfo; + private System.Windows.Forms.CheckBox checkBox_MonitorEventBuffer; + private System.Windows.Forms.Button button_ProcessFilterRule; + } +} \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/CommonObjects/FilterRuleForm.cs b/Demo_Source_Code/CSharpDemo/CommonObjects/FilterRuleForm.cs new file mode 100644 index 0000000..fb130f8 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/CommonObjects/FilterRuleForm.cs @@ -0,0 +1,281 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +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; + +using EaseFilter.FilterControl; + +namespace EaseFilter.CommonObjects +{ + public partial class FilterRuleForm : Form + { + FileFilterRule filterRule = new FileFilterRule(); + FileFilterRule passInFilterRule = null; + + public FilterRuleForm() + { + //set the default value for the new filter rule. + filterRule.IncludeFileFilterMask = "c:\\test\\*"; + filterRule.EncryptMethod = (int)FilterAPI.EncryptionMethod.ENCRYPT_FILE_WITH_SAME_KEY_AND_UNIQUE_IV; + filterRule.EncryptWriteBufferSize = 1048576; + filterRule.RegisterMonitorFileEvents = (uint)(FilterAPI.FileChangedEvents.NotifyFileWasCreated | FilterAPI.FileChangedEvents.NotifyFileWasDeleted | FilterAPI.FileChangedEvents.NotifyFileInfoWasChanged + | FilterAPI.FileChangedEvents.NotifyFileWasRenamed | FilterAPI.FileChangedEvents.NotifyFileWasWritten | FilterAPI.FileChangedEvents.NotifyFileSecurityWasChanged | FilterAPI.FileChangedEvents.NotifyFileWasRead); + + filterRule.RegisterMonitorFileIOEvents = 0x0; + filterRule.RegisterControlFileIOEvents = 0x0; + filterRule.AccessFlag = (uint)FilterAPI.ALLOW_MAX_RIGHT_ACCESS; + filterRule.EnableMonitorEventBuffer = true; + + InitializeFilterRuleForm(); + } + + public FilterRuleForm(FileFilterRule _filterRule) + { + passInFilterRule = _filterRule; + filterRule = _filterRule.Copy(); + + InitializeFilterRuleForm(); + } + + private void InitializeFilterRuleForm() + { + InitializeComponent(); + + textBox_IncludeFilterMask.Text = filterRule.IncludeFileFilterMask; + textBox_ExcludeFilterMask.Text = filterRule.ExcludeFileFilterMasks; + textBox_SelectedEvents.Text = filterRule.RegisterMonitorFileEvents.ToString(); + textBox_IncludePID.Text = filterRule.IncludeProcessIds; + textBox_ExcludePID.Text = filterRule.ExcludeProcessIds; + textBox_ExcludeProcessNames.Text = filterRule.ExcludeProcessNames; + textBox_IncludeProcessNames.Text = filterRule.IncludeProcessNames; + textBox_ExcludeUserNames.Text = filterRule.ExcludeUserNames; + textBox_IncludeUserNames.Text = filterRule.IncludeUserNames; + textBox_MonitorIO.Text = filterRule.RegisterMonitorFileIOEvents.ToString(); + textBox_FilterDesiredAccess.Text = filterRule.FilterDesiredAccess.ToString(); + textBox_FilterDisposition.Text = filterRule.FilterDisposition.ToString(); + textBox_FilterCreateOptions.Text = filterRule.FilterCreateOptions.ToString(); + checkBox_MonitorEventBuffer.Checked = filterRule.EnableMonitorEventBuffer; + + if (GlobalConfig.filterType == FilterAPI.FilterType.MONITOR_FILTER) + { + button_ControlSettings.Visible = false; + button_ProcessFilterRule.Visible = false; + } + } + + private void button_SaveFilter_Click(object sender, EventArgs e) + { + if (textBox_IncludeFilterMask.Text.Trim().Length == 0) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("The include filter mask can't be empty.", "Add Filter Rule", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + //include filter mask must be unique, but it can have multiple exclude filter masks associate to the same include filter mask. + filterRule.IncludeFileFilterMask = textBox_IncludeFilterMask.Text; + filterRule.ExcludeFileFilterMasks = textBox_ExcludeFilterMask.Text; + filterRule.IncludeProcessNames = textBox_IncludeProcessNames.Text; + filterRule.ExcludeProcessNames = textBox_ExcludeProcessNames.Text; + filterRule.IncludeUserNames = textBox_IncludeUserNames.Text; + filterRule.ExcludeUserNames = textBox_ExcludeUserNames.Text; + filterRule.IncludeProcessIds = textBox_IncludePID.Text; + filterRule.ExcludeProcessIds = textBox_ExcludePID.Text; + filterRule.RegisterMonitorFileEvents = uint.Parse(textBox_SelectedEvents.Text); + filterRule.RegisterMonitorFileIOEvents = ulong.Parse(textBox_MonitorIO.Text); + + filterRule.FilterDesiredAccess = uint.Parse(textBox_FilterDesiredAccess.Text); + filterRule.FilterDisposition = uint.Parse(textBox_FilterDisposition.Text); + filterRule.FilterCreateOptions = uint.Parse(textBox_FilterCreateOptions.Text); + + filterRule.EnableMonitorEventBuffer = checkBox_MonitorEventBuffer.Checked; + + if (null != passInFilterRule) + { + GlobalConfig.RemoveFilterRule(passInFilterRule.IncludeFileFilterMask); + } + + GlobalConfig.AddFileFilterRule(filterRule); + + this.Close(); + } + + + private void button_SelectIncludePID_Click(object sender, EventArgs e) + { + + OptionForm optionForm = new OptionForm(OptionForm.OptionType.ProccessId, textBox_IncludePID.Text); + + if (optionForm.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + textBox_IncludePID.Text = optionForm.ProcessId; + } + } + + private void button_SelectExcludePID_Click(object sender, EventArgs e) + { + + OptionForm optionForm = new OptionForm(OptionForm.OptionType.ProccessId, textBox_ExcludePID.Text); + + if (optionForm.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + textBox_ExcludePID.Text = optionForm.ProcessId; + } + } + + private void button_SelectedEvents_Click(object sender, EventArgs e) + { + OptionForm optionForm = new OptionForm(OptionForm.OptionType.MonitorFileEvents, textBox_SelectedEvents.Text); + + if (optionForm.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + textBox_SelectedEvents.Text = optionForm.MonitorFileEvents.ToString(); + } + } + + private void button_RegisterMonitorIO_Click(object sender, EventArgs e) + { + OptionForm optionForm = new OptionForm(OptionForm.OptionType.MonitorFileIOEvents, textBox_MonitorIO.Text,true); + + if (optionForm.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + textBox_MonitorIO.Text = optionForm.MonitorIOEvents.ToString(); + } + } + + private void button_FilterDesiredAccess_Click(object sender, EventArgs e) + { + OptionForm optionForm = new OptionForm(OptionForm.OptionType.FilterDesiredAccess, textBox_FilterDesiredAccess.Text); + + if (optionForm.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + textBox_FilterDesiredAccess.Text = optionForm.FilterDesiredAccess.ToString(); + } + } + + private void button_FilterDisposition_Click(object sender, EventArgs e) + { + OptionForm optionForm = new OptionForm(OptionForm.OptionType.FilterDisposition, textBox_FilterDisposition.Text); + + if (optionForm.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + textBox_FilterDisposition.Text = optionForm.FilterDisposition.ToString(); + } + } + + private void button_FilterCreateOptions_Click(object sender, EventArgs e) + { + OptionForm optionForm = new OptionForm(OptionForm.OptionType.FilterCreateOptions, textBox_FilterCreateOptions.Text); + + if (optionForm.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + textBox_FilterCreateOptions.Text = optionForm.FilterCreateOptions.ToString(); + } + } + + + private void button_ControlSettings_Click(object sender, EventArgs e) + { + ControlFilterRuleSettigs controlSettingForm = new ControlFilterRuleSettigs(filterRule); + + if (controlSettingForm.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + filterRule = controlSettingForm.filterRule; + } + } + + private void button_ProcessFilterRule_Click(object sender, EventArgs e) + { + ProcessFilterSetting processSettingForm = new ProcessFilterSetting(); + + if (processSettingForm.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + ProcessFilterRule processFilterRule = processSettingForm.selectedFilterRule; + } + } + + private void button_InfoFilterMask_Click(object sender, EventArgs e) + { + MessageBox.Show("Input managed file filter mask with wild card character '*', it is unique index of the filter rule, to filter map drive file, you can use the filter mask like this: '*\\192.168.1.1\\shareName\\foldername\\*'"); + } + + private void button_InfoExcludeFileFilterMask_Click(object sender, EventArgs e) + { + MessageBox.Show("Skip all the I/Os which the file name matches the exclude file filter mask, seperated with ';' for multiple exclude file filter masks."); + } + + private void button_InfoIncludeProcessName_Click(object sender, EventArgs e) + { + MessageBox.Show("Only the IOs which were initiated by the process of the include process name list will be monitored or controlled by the filter driver for this filter rule."); + } + + private void button_InfoExcludeProcessName_Click(object sender, EventArgs e) + { + MessageBox.Show("All the IOs which were initiated by the process of the exclude process name list will be skipped by the filter driver for this filter rule."); + } + + private void button_InfoIncludeUserName_Click(object sender, EventArgs e) + { + MessageBox.Show("Only the IOs which were initiated by the user of the include user name list will be monitored or controlled by the filter driver for this filter rule."); + } + + private void button_InfoExcludeUserName_Click(object sender, EventArgs e) + { + MessageBox.Show("All the IOs which were initiated by the process of the exclude user name list will be skipped by the filter driver for this filter rule."); + } + + private void button_InfoDesiredAccess_Click(object sender, EventArgs e) + { + MessageBox.Show("Skip the IOs when the CreateFile DesiredAccess doesn't match any bit of the value if the DesiredAccess is not zero."); + } + + private void button_InfoDisposition_Click(object sender, EventArgs e) + { + MessageBox.Show("Skip the IOs when the CreateFile's Disposition doesn't match any bit of the value if the Disposition is not zero."); + } + + private void button_InfoCreatOptions_Click(object sender, EventArgs e) + { + MessageBox.Show("Skip the IOs when the CreateFile's CreatOptions doesn't match any bit of the value if the CreatOptions is not zero."); + } + + private void button_InfoFileEvents_Click(object sender, EventArgs e) + { + MessageBox.Show("Get the notification after the registered file event was fired and the file handle was closed, you will get only one event even the file was read/written many times before it was closed."); + } + + private void button_InfoMonitorIO_Click(object sender, EventArgs e) + { + MessageBox.Show("Get the notfication right after the registered IO was fired, the file handle is not closed, you will get as many events as the times of the file was read/written if it was registered."); + } + + private void button_MonitorBufferInfo_Click(object sender, EventArgs e) + { + string info = "Enable the filter driver to send the monitor events to the user mode service asynchronously," + + "or the filter driver will send the monitor events synchronously, block and wait till the events being picked up."; + MessageBox.Show(info); + } + + } +} diff --git a/Demo_Source_Code/CSharpDemo/CommonObjects/FilterRuleForm.resx b/Demo_Source_Code/CSharpDemo/CommonObjects/FilterRuleForm.resx new file mode 100644 index 0000000..b5a6f9c --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/CommonObjects/FilterRuleForm.resx @@ -0,0 +1,570 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + AAABAAgAEBAAAAEACABoBQAAhgAAABAQAAABACAAaAQAAO4FAAAYGAAAAQAIAMgGAABWCgAAGBgAAAEA + IACICQAAHhEAACAgAAABAAgAqAgAAKYaAAAgIAAAAQAgAKgQAABOIwAAMDAAAAEACACoDgAA9jMAADAw + AAABACAAqCUAAJ5CAAAoAAAAEAAAACAAAAABAAgAAAAAAEABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP// + /wCec3MA4LS0AIBOTgC9lJQA7NnZAJ+MjADFq6sAkmBgAOPHxwD38fEArYGBAJZ/fwDz5eUA7b29AMef + nwC3n58Ai2pqAIhXVwCxi4sA0qenANK0tADbvb0A6NDQALCWlgCRc3MApHp6AL+MjACig4MAiF5eAKiI + iACteXkAvqOjAMKamgDKpaUAm4aGAPv29gCAVlYA58LCAN/CwgDv3t4A5MzMANawsACGUFAA7dPTAOC6 + ugCbfHwAk3t7ALOSkgCkcnIA/fv7AMSjowC5m5sA3LGxAItmZgDw4uIAzaioAMeZmQCMYGAAlXFxAL6Y + mADq1tYA4b+/AKSGhgCziIgA0KSkAMGdnQCIW1sApImJAL6goADnysoA6dPTAIpZWQDmzs4A5cXFAOHF + xQCDT08A3MHBAKd7ewDBl5cAiVVVAPHg4ADjysoA5sjIAODHxwDev78A2ru7AJyIiAClg4MAzaWlAKR0 + dACkeHgA3r29AOzX1wCJZ2cA5tHRAMmgoADFoKAA7d7eANy/vwB/T08A8ubmAOnR0QDiyckA4sbGAKN5 + eQDewcEA38DAAN++vgCsgoIAzKenAMGZmQDp1NQA5s3NAOPIyADhxMQA3MLCAM2kpADKpqYAyqSkAPHi + 4gDr19cA6NHRAOfQ0ADlzMwA5MrKAOPJyQDiyMgA4cfHAOPGxgDhxsYAqYiIANu7uwDCnZ0AAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + 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 + tQByQ0MA7NraAL+SkgCDX18AnImJANWhoQDiyMgA9u3tALJ/fwCyn58AgU5OAJJ5eQDru7sAlWVlAKmS + kgDEnp4Az6ysALSKigDgrKwA8uPjAOfR0QDevr4AildXAKt4eADns7MAnnl5AIpoaADJlpYAk21tALSU + lAB2SkoAmH9/AKKDgwCqi4sAu5ycAI9gYADIp6cA+fPzAPHV1QDWp6cA47m5AKqBgQDNn58AnGhoAJtv + bwDUsLAAeU9PALmOjgDy3d0A4MPDAN6xsQDAl5cA3Lm5ALqIiADNpKQAuZeXAPPp6QDq1dUAh2RkAOXM + zACgbGwAtYODAHxLSwDbq6sAlWBgAO7g4ACXd3cAx6OjAKN0dADOqKgAhFFRAIphYQDjwMAAjWtrAOa8 + vADZvb0A1bi4AKh1dQCjeHgA0bOzAJ+GhgCnjo4AmWxsANikpACyh4cAspGRAPfw8ACxfHwAyJmZANGv + rwC0jY0Aw5OTAMCamgDkz88AjWZmAOXGxgDjrq4ArX9/AMuqqgC8kJAA7t3dAHdNTQDq2NgAjFlZAIhf + XwDat7cAnHd3ANqzswCce3sAqXp6ALCdnQC0nZ0Af0xMAOfOzgDixcUA3Ly8AN+6ugDUtLQAyqCgALib + mwD26ekA8ufnAIBQUADp09MAhmJiAOrR0QCJZmYA5MrKAJtmZgCZaGgAlGtrAN/BwQDivr4AonJyAKZ4 + eADPqqoA1KOjAMunpwC1iIgAq42NALiMjADFnJwA8uXlAPLh4QCVY2MAqn9/ANqpqQB4S0sA7NzcAN7E + xADgv78AtIaGAM2mpgCnkZEAqY+PALaLiwCCUFAA8OHhAItmZgDiysoA5bm5ANa1tQDNqqoAt46OALuO + jgC+kJAA9+7uAPXs7AB+S0sA9OrqAPHk5ADv398A7d7eAO3b2wDr2dkAlF9fAOvW1gDo1NQA6NLSAOjQ + 0ACVbGwA5s3NAOPJyQDhx8cA48bGAJZ4eADhxMQA3729ANu4uADZtrYA2bS0ANCrqwC/mZkA8ODgAOrX + 1wDq1NQAoG1tAOTLywDhxsYAmH5+AODCwgDfwMAA3r+/AOC+vgCfhYUAooSEANy7uwDcuroAuY2NANCu + rgDOqakAe0tLAH9LSwDz6uoA9OnpAIlXVwDz5+cAi1lZAO/h4QCJYWEA7+DgAO7e3gDv3d0A7dzcAO3a + 2gDr2toA69jYAJpsbADp1dUA6dTUAOjR0QDn0NAA5s7OAOTMzADlysoA4snJAOPIyADix8cA4sbGAOHF + xQDixMQA4MTEAOHDwwDfwsIA37+/AN++vgDevb0A3bm5ANu5uQDauLgAu5CQAMCSkgAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaSKCAAAAAAAAAAAAAAAAAAAAAAAAAAAjURusAAAAAA8AAAAA + AAAAAAAAAL0AAABNLpGUogAAMsgEAAAAAAAAAAAAbInbYstCTs/+Sn7XFkMvPgAAAAAAAABUO6UCL0Fk + iHf9QAwcLMJnHgAAAAAAAAC4T+7xN6RMzRn6A3pvwvsnAAAAAAAAAAAAUoG6g/G7Cu+6yTX8bXh0AAAA + AAAAAAAAIGZ18Mrxyr7Mzb7t0jGEaxoOCAAAADCFRCi3vrk/7ckK9YfNP7+fCRAfBwAAcFeMqT3zGOu2 + SVyWNr6Hh/L7wMEGlwAA5xeY42q+6LRgjwAAAEO+zbrS08+RgAAASHyvsenw5uIRAAAAAI359crN1Vbf + AAAALRVTaAXwsZOgAAAAAKh28/LzlUsAAAAAAABVWNr4RaFe2EbRSHk/CvV2jrOGAAAAAAByW6vyBeDF + i18rKrbJ7/f2mgbdAAAAAADUNNncON7eReGyters97q89GMnAAAAAA1QKQsLPNLrRbDlxuzOuabEFKfQ + AAAAAACQ2WHDmaq2v/jNzr5/R26dJB0AAAAAAAAA/yYAIdatrn3eBWrHExIAAAAAAAAAAAAAAAAAAJyr + kjmbcaPkXSUAAAAAAAAAAAAAAAAAADpaXXMAAGUUigAAAAAAAAAAAAAAAAAAAHszWQAAAACeAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A/8f/AP+HvwD7gx8A8AAPAOAADwDgAB8A8AAfAPAA + AQDAAAEAgAABAIAcAQCAPAMAgDwHAOAAAwDgAAMA4AADAMAAAwDgAAcA8gA/AP8APwD/DH8A/x7/AP// + /wAoAAAAGAAAADAAAAABACAAAAAAAGAJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcjc3E28+ + PtpuOjradT4+owAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfEJCb6h1df+reHj/f0xM/oNERD4AAAAAAAAAAGYy + MgtxOTlzbjY2GgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH89PQmCS0uMiFBQTgAA + AAAAAAAAe0REns2fn//FnJz/lWNj/3pDQ6oAAAAAfEZGIG45Oc+gbW3/bjs77Hk+PkUAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAhFlZDX9JScWicnL/i1hY/oNOTr+DTEx9eEJC6ea8vP/gvr7/u5CQ/4ZS + Uv59SEjneUVF7uCsrP/aq6v/nGho/3I6OqEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAi09Pa7mX + l//WtbX/o3Bw/5xoaP+1g4P/466u/+K+vv/cvLz/2ri4/6BsbP+yf3//57Oz/+O5uf/ZtLT/vJCQ/3Q8 + PJwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjVNTtdm9vf/lysr/4sfH/8CXl//lubn/48DA/9/A + wP/evr7/3r29/9i1tf/KoKD/2rOz/9m0tP/dubn/kWFh/nhAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAklpaTqV5ef7q0dH/48nJ/+TKyv/ix8f/4cfH/+LIyP/iycn/48nJ/+TLy//gw8P/27m5/9q3 + t//furr/gExM/XVFRUl6ODgJQEhIBAAAAAAAAAAAAAAAAAAAAAAAAAAAhD4+BItXV73Lqqr/587O/+PI + yP/hxsb/4sfH/+HGxv/hxMT/4MLC/9/AwP/hxMT/5MzM/9y7u//UsLD/m2Zm/4xZWf+MWFj+gk1N+nlC + QlUAAAAAAAAAAJ5nZzKZZGTUmmdn95VgYP/Ip6f/6NDQ/+HExP/mzc3/5czM/+TMzP/ky8v/4sjI/+DE + xP/fwcH/38DA/+XMzP/fvb3/touL/9Whof/ru7v/yZaW/287O60AAAAAAAAAAJJdXaDYpKT/1KOj/76Q + kP/q1dX/4cXF/+fR0f/n0ND/6NLS/86oqP/KmZn236qq7OCzs/7hxMT/38HB/9/Bwf/ixsb/3bm5/9u4 + uP/Ztrb/v5KS/3NAQOQAAAAAAAAAAJllZePy4+P/7Nzc/+3c3P/q2Nj/4cTE/+nV1f/r1tb/wJqa/6p0 + dI6+oaEJAAAAAPO6ukffrKzz4cTE/9/AwP/jycn/3Lu7/9y6uv/gvr7/xZyc/3RAQK8AAAAAAAAAAKNx + ce/26en/79/f/+3b2//p1NT/48jI/+vY2P/v3d3/lWNj9oI8PAQAAAAAAAAAAAAAAADdpKSf376+/+DE + xP/hxsb/38DA/9Curv+bbW3+fUhIv4FNTS4AAAAAAAAAAKpycr+2jIz+0bOz/+7d3f/s2tr/48jI/+3b + 2//y4eH/hFFR/o9ZWTcAAAAAAAAAALGPjwjAiYnR4sXF/+HFxf/ixsb/4cXF/6p/f/+BTEzFdTg4CQAA + AAAAAAAAAAAAAAAAAAC9f38mom5ufrSIiP306en/37+//+7g4P/w4eH/tI2N/35HR/OKU1OYl19fhqJr + a9fUtLT/5czM/+LIyP/gxMT/4sXF/7WIiP+UX1//jVZWwAAAAAAAAAAAAAAAAAAAAAAAAAAAtnt7UbJ8 + fPn17Oz/4sbG/+za2v/v4OD/8ODg/8+qqv/Dk5P/1qen//HV1f/o0tL/5MvL/+LJyf/fwsL/4cPD/+C/ + v/+/kpL/jFlZ/HpUVA0AAAAAAAAAAAAAAADGh4cmu46O+/Ld3f/z6ur/8+fn/9y5uf/v4eH/7+Hh/+7g + 4P/u3t7/69nZ/+jU1P/o0dH/5s7O/9/Cwv/jycn/48bG/+LExP/lxsb/jltb7ZdISAsAAAAAAAAAAAAA + AAC+g4NS1bi4//nz8//27e3/9u3t//Pp6f/cu7v/59DQ/+7g4P/t3t7/69ra/+rX1//mzs7/3r+//+bN + zf/Nqqr/v5mZ/8+srP+3jo7/kFlZfAAAAAAAAAAAAAAAAAAAAADHlZUdu4qK6vPq6v/kz8//0Kur/97E + xP/37u7/6NLS/9+9vf/fv7//38DA/96/v//hxMT/6dPT/8ejo/+WYGCxnWVlZJpiYpCWX1+pkVFRDgAA + AAAAAAAAAAAAAAAAAAAAAAAA1pmZQMeMjMfJjo6HyY2NQrqDg5bOqan/9Orq//Hk5P/y5+f/7+Hh/+za + 2v/q2Nj/6tTU/8Senv+ibW1sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAMqSkiPNpqb/9ezs//Ll5f+8iYn4t35+zqt3d+jiysr/7dra/9Cvr/+ocHCOAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMuTkyPNpKT/9/Dw/9Gv + r/+8iIhtAAAAAMGEhCuvfX3uzqys/6Zzc+a2d3dGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAMSengfAjo6UvYmJ0bWHh7z/iIgCAAAAAAAAAACze3s7pXBwf650 + dA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA////AP/H/wD/h78A+4MfAPAADwDgAA8A4AAfAPAAHwDwAAEAwAABAIAAAQCAHAEAgDwDAIA8 + BwDgAAMA4AADAOAAAwDAAAMA4AAHAPIAPwD/AD8A/wx/AP8e/wD///8AKAAAACAAAABAAAAAAQAIAAAA + AACABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8Aom9vAN+zswBuQEAAq5iYAOva2gCIV1cAzpycAJeF + hQC3hIQA4sjIAPXt7QCJa2sAuqWlAL+RkQB9SkoAzaysAO67uwCseXkAlmNjAJB2dgDsz88ApoaGANq+ + vgDap6cAnXp6ALqbmwDz4uIAsIyMAIdiYgCdjY0AfFRUAMijowDUtLQAvIqKAOS7uwDEnJwAj1xcAJR9 + fQCmkJAAq4CAAJtrawCRb28A1KGhAIBaWgDHlJQAg1BQAK6engDWrq4A59TUAKd0dAC1lpYA5M3NAOXB + wQB1SEgAmXFxAM+mpgDbubkA6be3AI9lZQDz6ekA8dfXAOGurgC4oKAArpGRAKWVlQB4UFAAm4GBAMCX + lwCxfn4A7t/fAIReXgDfwsIA5bKyAKCHhwDCpKQAuZCQAJZ5eQCzhoYAjmBgAI5paQCVaWkAim9vANus + rAClgoIAsIKCALuVlQC4jIwA1Li4AMSfnwCrhIQAgE1NAOfQ0ADdxsYA37y8AJlmZgDasrIAn2xsAJNz + cwDQr68A0qmpAKR3dwCnenoAyqenAJ5+fgCxm5sAg1dXAOS3twDEkZEAeUZGAKGLiwDx5eUAhVNTAIZa + WgDhwMAAhWVlANi7uwCgcnIAs56eAOrX1wB9V1cA5MrKANm1tQCVgIAAqn19AMCOjgDv29sAkl9fAJJi + YgCNbGwAj3JyANSxsQCYfHwAwJSUAItnZwCSZ2cAnW5uAJp4eADMpKQAqXh4AKOSkgC4mJgApHJyAObS + 0gDhxMQAjVtbAOK5uQCbaGgA2KWlANajowCgfHwAzJ6eALSBgQC6iIgAsJOTAOrT0wDcwcEA3Lu7AIxx + cQCda2sA17OzANOtrQDIpqYAt5ycALySkgC0jY0A9OvrAPDj4wDt3d0AgFBQAIdVVQDmzs4AiVpaAOXI + yADhyckA3r+/AJhpaQDgtbUA17m5AJ9vbwDXsLAA2ampAM6qqgCahYUA0aGhAK19fQCgjY0AsYSEAMCZ + mQC6j48Aqnt7AMihoQCrlpYAuZKSAOnV1QDo0tIA5czMAN29vQCcbGwAnXBwANKwsACnd3cAl4GBANCo + qACtgYEAvouLALWMjAC+j48Ae0pKAODIyACUYmIA2ru7ANe1tQCpmJgA9u7uAPLn5wDv4OAAfktLAOzc + 3ADr2NgAiVZWAIlYWADn0dEAiFlZAIRfXwDjyckAhmNjAOLGxgDhw8MAl2RkAO26ugDfwMAAjmtrAOW4 + uADZvLwA3Lq6AJtvbwChbm4A2re3AKBwcADZtrYAo3FxANm0tADYsrIApXNzANOysgCVfn4AqHV1AJiE + hACtenoAz6urAKx8fACqf38Ay6amALGBgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAANNyB0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC/6oBD5AAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAD5jJnuJnkAAAAACQRTAAAAAAAAAAAAAAAAAB/jAAAAAIN+zIvwbgAAAJ9xzi9D + AAAAAAAAAAAAAAC4B6AvhwAAa7k676WS0eEtlBIIM1wAAAAAAAAAAAAAAFCEjPLmcdMjbOw6ofL6+Jrn + 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 + t//curr/27m5/9azs/+jcXH/rXp6/6h1df+6iIj/7bq6/+W4uP/Wrq7/wJOT/4NRUf9uOTlMAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAg1BQn8KkpP/jyMj/0rCw/7CCgv+kcXH/vIqK/9qn + p//lsrL/5Lu7/929vf/cvLz/3Lq6/7qOjv+ndHT/sX5+/9ilpf/gtbX/2LKy/9ewsP/Vrq7/glFR/nA9 + PTIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACGUlLn1rm5/+HFxf/hxcX/4cTE/86q + qv/Mnp7/4rm5/+G/v//fwMD/3r+//96+vv/dvb3/3Lu7/9e1tf/MpKT/17Cw/9m1tf/ZtLT/2LKy/7eM + jP90QUG6AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIpWVoGrgID/4sjI/+LH + x//ix8f/4sbG/+HFxf/hxMT/4MTE/+HGxv/iyMj/48rK/+PKyv/ix8f/38HB/9y6uv/bubn/2re3/9m2 + tv/ZtLT/mmtr/3dDQ48AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfz8/CI5b + W9fNrKz/48rK/+PJyf/jycn/4sjI/+HGxv/iyMj/4sfH/+HExP/gw8P/38LC/+DExP/jycn/5c3N/9/B + wf/bubn/2re3/9i0tP+lc3P/fktL/HZFRYV2QkJwcz8/aHI8PEwAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACZZmYKkFxcbJ1ubv/jycn/5MzM/+PKyv/gxMT/4sjI/+PIyP/ix8f/4cbG/+HExP/gw8P/38LC/9/A + wP/ev7//48rK/+LHx//bubn/17Oz/6Rycv+ib2//rXp6/616ev+tenr/gU5O/m4+PiUAAAAAAAAAAH9f + XwiSX1+rk2Bg3pViYvqZZmb/oHBw/+XOzv/lzc3/38LC/+TLy//kzMz/5MrK/+PJyf/iyMj/4sfH/+HF + xf/gxMT/4MLC/9/AwP/ev7//4sjI/+HGxv/bubn/yKGh/7F+fv/Wo6P/4a6u/+m3t/+WY2P/dD8/cAAA + AAAAAAAAk2JiU6x5ef/UoaH/x5SU/7SBgf/Enp7/59HR/+HFxf/kysr/5s/P/+XOzv/lzc3/5MvL/9y8 + vP/WsLD/2rKy/9+7u//hw8P/4MLC/9/AwP/ev7//48rK/96/v//bubn/062t/9iysv/YsrL/z6am/59s + bP92QkK8AAAAAAAAAACWY2Ow0qmp/+XBwf/evLz/2ru7/+TNzf/o09P/3sDA/+jS0v/n0dH/59DQ/+TM + zP/Al5f/uIWFzcWRkXfMmZlq16Ojot6trfnhwMD/4MLC/9/AwP/fwMD/48nJ/9y6uv/buLj/2ra2/9m0 + tP/YsrL/p3Z2/3lFRbUAAAAAAAAAAJpmZt3jzc3/69jY/+rY2P/q19f/6tfX/+XNzf/ix8f/6dXV/+jU + 1P/o0tL/v5mZ/6Jvb6B/f38CAAAAAAAAAAAAAAAA16SkQdyrq/vgw8P/4MLC/9/AwP/jycn/3b29/9y6 + uv/buLj/2ra2/9awsP+fcHD/eUZGbQAAAAAAAAAAnGlp6OfU1P/s2tr/7Nra/+za2v/r2dn/4sjI/+XO + zv/q19f/6tbW/+nV1f+ba2v/lWBgHQAAAAAAAAAAAAAAAAAAAAAAAAAA05+ftt+8vP/gxMT/38LC/+HF + xf/fwcH/3Lu7/9i2tv+1i4v/ilhY+3xJSaR4PDwRAAAAAAAAAACfbGzw1Li4/+vZ2f/t3d3/7dzc/+3c + 3P/iyMj/5tDQ/+vZ2f/r2Nj/5tHR/4lWVv+HUlIiAAAAAAAAAAAAAAAAAAAAAAAAAADHk5O83bu7/+HF + xf/gw8P/4cTE/+DCwv/dvb3/mGlp/4NQULh8Tk4nAAAAAAAAAAAAAAAAAAAAAKJtbU2icHCxqHd397+Z + mf/dxsb/7t7e/+XOzv/ky8v/7Nzc/+za2v/o1dX/jVtb/4BNTa5/Pz8IAAAAAAAAAAAAAAAAr319U8GS + kv3ix8f/4sfH/+HExP/hxMT/38LC/96+vv+cbGz/h1RU7INQUEYAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACfb28QpnNzX659fffs3Nz/7Nvb/929vf/u3t7/7dzc/+zb2/+7lZX/jVpa/4FNTdyHVFSLkl5efJtp + aba1h4f94cbG/+TKyv/iyMj/4cbG/+DExP/fwsL/3r+//6Bubv+baGj/iFVV+4ROTksAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACqdHQYq3h44+HJyf/w4uL/3b29/+vZ2f/u39//7d3d/+rY2P/DnJz/t4SE/7aD + g//EkZH/37Oz//HX1//lzs7/5MvL/+PJyf/ix8f/38LC/+DCwv/fwMD/z6ur/619ff+ZZmb/g1BQjwAA + AAAAAAAAAAAAAAAAAAAAAAAAqnh4JK57e93SqKj/79vb//Hl5f/s29v/27q6/+/g4P/u39//7d3d/+zb + 2//mz8//5cjI/+zPz//q09P/59HR/+bPz//lzc3/5MrK/9/Cwv/gxMT/4MPD/9/Bwf/ev7//27q6/7GE + hP+EUlKtAAAAAAAAAAAAAAAAAAAAAAAAAACue3uP1LS0//Pi4v/z6Oj/8ufn//Lm5v/mz8//3r6+/+/g + 4P/u39//7d3d/+zb2//r2dn/6tfX/+nU1P/o0tL/59DQ/+XOzv/hxMT/38HB/+LHx//hxMT/4MLC/97A + wP/dvb3/oHJy/4dTU1wAAAAAAAAAAAAAAAAAAAAAAAAAALJ+frPl0tL/9Ovr//Tq6v/z6en/8+jo//Lm + 5v/n0ND/27i4/+rX1//u3t7/7dzc/+za2v/r2Nj/6dbW/+jT0//mz8//3sDA/9/Bwf/jysr/2Lu7/8il + pf/TsrL/3L29/8umpv+KV1fUVVVVAwAAAAAAAAAAAAAAAAAAAAAAAAAAs4GBlNCvr//27u7/9e3t//Tr + 6//r2tr/8OPj//Lm5v/t3d3/3r+//9u4uP/hxcX/5czM/+XNzf/ix8f/3b29/9y7u//jycn/5c3N/8Sf + n/+da2vpl2RkopRhYcmTYGDyk2Bg/Y1ZWVMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC/f38IuISEyte5 + uf/Us7P/wpWV/bqHh9TAkJD42r6+//Dj4//w4+P/7t/f/+fR0f/jyMj/4sbG/+TKyv/n0dH/6NPT/+fQ + 0P/mzs7/qnt7/5tnZzYAAAAAAAAAAKpVVQOQWFgXAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAC2iIgcu4eHnL2IiGW8jY0bAAAAALuHhyK9iYnK4MjI//Hk5P/w4uL/7+Dg/+3d3f/s29v/6dXV/+rW + 1v/o1NT/59HR/+bPz/+peHj/nGhoTgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL+Kipzgx8f/8eXl//Dj4//n09P/vpGR/7OC + gvqtenrvxJ6e/+nU1P/n0tL/5s/P/7KGhv+da2twAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwI6OnOHIyP/y5ub/8OPj/8ad + nf62gIBptm1tB6pxcQmreHjDyqen/+jS0v/ZvLz/qXt7/p1qam4AAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADDkJCa1LCw/+bS + 0v/cwcH/uISEwv8AAAEAAAAAAAAAAKFraxOqd3fWuo+P/6Rxcd6hbGxSAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL+N + jSTBjY2FvoqKvbuIiOG3goIrAAAAAAAAAAAAAAAAAAAAAKp3dx6nc3NmjXFxCQAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////+H////g////wPH/88Dg/+DAAP/gA + AD/wAAA/8AAAP/AAAD/4AAAH+AAAA8AAAAGAAAABgAAAAYAD4AGAB+ADgAfgD8ADwA/wAAAH+AAAA/AA + AAPgAAAD4AAAB+AAAAfwAAH/+cAB///AAP//wMD//8Hh///j9///////KAAAADAAAABgAAAAAQAIAAAA + AACACgAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8Aom9vAN6zswBvPT0Aq5iYAOva2gCJV1cAzZycAJeF + hQC4hIQA4sfHAPXt7QCJa2sAuaWlAL+RkQB9SkoAzK6uAPG/vwCreXkAl2NjAJJ3dwD3ysoApoWFANnA + wADZp6cAnXx8ALqbmwDz4eEArY2NAIhiYgCdjY0AfFRUAMijowDUtbUAvIqKAOO7uwDEnJwAj1xcAJR9 + fQCmkpIAqYGBAJlsbACRcHAA06KiAIFbWwDIlpYAg1BQAK6engDWra0A6NTUAKd0dAC1lpYA5M3NAObB + wQB1SEgAm3R0ANGlpQDbubkA6re3AI9lZQD16OgA+tbWAN+trQC+oaEArY+PAKWVlQB3T08Am4ODAMCY + mACyfn4A79/fAIleXgDfwsIA5bKyAJ+IiADDp6cAt5GRAJR5eQCyh4cAjmBgAI5paQCUamoAjG9vANys + rACigoIAsIKCALyVlQC5i4sA07m5AMSfnwCshYUAgE1NAOfQ0ADdxcUA4Ly8AJlmZgDbsrIAoGtrAJd1 + dQDPsLAA06mpAJ92dgCoenoAyKioAJ5+fgC0mZkAg1hYAOW3twDEkJAAd0REAKaMjADx5eUAhFNTAIZa + WgDhv78AhWVlANm6ugCfdHQAs56eAOrX1wB9V1cA5MrKANq1tQCVgIAAqn19AMGNjQDu2toAk19fAJNh + YQCMa2sAj3JyANWwsACYfHwAwZWVAItnZwCSZ2cAnW5uAJx3dwDLo6MAq3h4AKSSkgC4mJgApXJyAOfS + 0gDhxMQAjVtbAOK5uQCcaWkA2KWlANajowChfHwAzJ+fALWBgQC6h4cAs5SUAOvT0wDcwsIA3Ly8AIxx + cQCeamoA2LOzANSsrADFqakAtZycALySkgC0jo4A9evrAPDj4wDt3d0Af1BQAIVVVQDmzs4AiVpaAOzH + xwDiysoA3r+/AJhpaQDgtbUA17m5AJ5vbwDXsLAA2qmpAMypqQCaiYkA0aGhAK98fACgjo4As4SEAMGZ + mQC7jo4Aq3t7AMqgoACslJQAtpOTAOnV1QDo0tIA5czMAN29vQCbbW0AnXBwANKwsACnd3cAl4GBANCo + qACtgYEAv4uLALWMjAC+kJAAekpKAODIyACVYWEA2ru7ANe2tgCpmJgA+fDwAPLn5wDv4OAAfkxMAO3c + 3ADs2NgAiVZWAIlYWADn0dEAiVlZAIRfXwDkyckAh2NjAOLGxgDhw8MAlmVlAOy6ugDfwMAAjmtrAOa4 + uADZvb0A3bq6AJtvbwChbm4A27e3AKFwcADZtrYAo3FxANm0tADYsrIApnJyANCysgCVfn4AqXZ2AJiE + hACte3sAz6urAKx8fACpf38Ay6amALGBgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + 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 + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB3Pj6sajc3+Wo3N+JqNzfIbDk5qng6 + OioAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIJHR0p2Q0P+t4WF/6Nw + cP+XZGT/fktL/3U+PqsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHlB + QaqzhIT/wY2N/6t4eP+kcXH/mWZm/3A7O/iEQEAbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAG02 + NhB3OzsZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAHhBQdjRpKT/vouL/6RwcP+caWn/m2ho/3xJSf96Q0N9AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAdz4+M2g0NOFpNTX1dDw8bAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJBLSx+ETU1RdDg4BQAA + AAAAAAAAAAAAAAAAAAAAAAAAfjw8DnE8PPjsvLz/y56e/76Rkf+7jo7/nGlp/45bW/90Pz/glUlJBAAA + AAAAAAAAAAAAAAAAAAB8Q0NYZTIy9LmGhv+odnb/cDw8/m83N7N9Pj4YAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjlJSMXpG + RuV/TU3/fEhI0oxUVEkAAAAAAAAAAAAAAAAAAAAAgU9PNXZERP76yMj/27m5/925uf/fvr7/tIiI/5ll + Zf94RUX/dkVFWlsAAAMAAAAAXgAAA3lFRYVtOTn90Jyc///W1v+pdnb/r3x8/4FOTv9yOjrZAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACOU1NBeEND76t8fP+0gYH/lWFh/39NTf6HTk64kFFRLwAAAACSUVEuekZGooxbW//0w8P/2rm5/9u4 + uP/bubn/1rGx/5VgYP+OW1v/dUJC/nZDQ+t6RES8c0BAv3pISP7ls7P//MjI//vIyP+fa2v/p3R0/6h1 + df9wODj2AAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAJNYWDJ9R0f2vZWV/+K8vP+kcHD/pHFx/6d0dP+RX1//gExM+4BMTN98SUn+lWVl/9Gh + of/pu7v/3Lq6/9u5uf/burr/37+//6h5ef+mcnL/t4SE/616ev+hbm7/onFx//C9vf/0wMD/8b+//9uy + sv/Sqqr/rXt7/6Btbf9uNDT4nqOjAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAIlOTpenf3//7dfX/+HFxf+ib2//nWho/6NwcP+ndHT/pHJy/7mJ + if/Xp6f/5LGx/+u3t//jurr/3L29/9y7u//curr/3bu7/8ujo/+famr/q3d3/7F+fv+5hob/2aen/++8 + vP/qubn/2bKy/9ewsP/Xr6//2rS0/7mMjP9xOjr1AAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAk0ZGCH5JSerbxcX/69fX/+LFxf/kyMj/wpyc/59r + a/+ibm7/pXFx/92rq//dqan/5LCw/+64uP/hvLz/3b29/929vf/cvLz/3Ly8/9/AwP+icXH/nWpq/6h1 + df+xfX3/2aen/+W3t//Ys7P/2LKy/9exsf/YsLD/3La2/6p9ff94Pz/FAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkVpaTY1bW//z4OD/4cXF/+HF + xf/ixcX/5MjI/+HFxf+9k5P/om1t/+axsf/ks7P/5Ly8/+DBwf/ewcH/3r+//96+vv/dvb3/3by8/928 + vP/hwMD/2La2/8ienv+7jIz/2ays/9q2tv/ZtLT/2LOz/9iysv/YsrL/27W1/3ZCQv6CR0dIAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAnF5eNYdS + UvvbvLz/5MrK/+LGxv/ixsb/4cfH/+LGxv/lysr/3L6+/+TCwv/gxcX/4MTE/+DCwv/fwcH/38DA/97A + wP/evr7/3r29/928vP/dvLz/3by8/969vf/dvLz/3Lq6/9q4uP/atrb/2bW1/9izs//ct7f/q39//3ZA + QMcAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAJJZWZacbGz/6tLS/+TJyf/iyMj/4sfH/+LHx//ixsb/48fH/+HFxf/hxcX/4cTE/+HF + xf/iycn/5M3N/+fPz//m0dH/5tLS/+fR0f/kzMz/4MPD/927u//cubn/27m5/9u4uP/at7f/2ra2/9m2 + tv/eubn/lWFh/3dCQt+APj4SAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAJ1paRGJU1PlxqKi/+fQ0P/jycn/48nJ/+PJyf/jyMj/4sjI/+LH + x//hxsb/4snJ/+LKyv/ix8f/4cbG/+DExP/gwcH/4MHB/+DExP/ix8f/5tHR/+nV1f/jyMj/3Lu7/9u5 + uf/buLj/2re3/9u3t//Vr6//pnJy/4VSUv96Rkaqb0VFDI4tLQaVAAACAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACXXl5Xj1tb/ufOzv/lzc3/5MvL/+TK + yv/jy8v/48rK/+HFxf/hxsb/4sfH/+LGxv/hxsb/4cXF/+HExP/gw8P/4MLC/9/Bwf/fwMD/3r6+/9/B + wf/lzs7/6NTU/96/v//burr/27i4/9y5uf/FnJz/oW1t/6NwcP93RET+bz09+249PfhtPj70cz4+7Xk/ + P+OMTExHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI9CQgSPYmIbjlhY066F + hf/p09P/5czM/+TNzf/jy8v/38LC/+HGxv/jysr/48nJ/+PIyP/ix8f/4sbG/+HFxf/hxcX/4MTE/+DD + w//fwsL/38DA/96/v//evb3/4cTE/+nX1//gw8P/27q6/925uf/Rqqr/m2ho/6Ftbf/FlJT/3qys/96q + qv/frKz/5rOz/6NwcP92Pz+rAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAApWhoFJ5mZnmeZGSinGVlyZJh + YeyTYGD9k2Bg/7KIiP/q1NT/587O/+bPz//dv7//4sfH/+TNzf/ky8v/5MrK/+PKyv/jycn/4sjI/+LH + x//ixsb/4cXF/+HExP/gw8P/4MLC/9/Bwf/ewMD/3r6+/9/AwP/p1tb/38HB/9u6uv/fvLz/wpiY/5di + Yv/KmJj/2qam/+Ctrf/qtrb/+8fH/6x5ef9yPj7vejs7CQAAAAAAAAAAAAAAAAAAAAAAAAAAnWVlmKFw + cP+3hYX/u4mJ/7qIiP+xf3//n2pq/8inp//q1NT/59LS/+DCwv/gw8P/58/P/+XNzf/lzc3/5MzM/+TL + y//kysr/5MrK/+TKyv/jysr/48nJ/+LHx//hxcX/4MPD/+DCwv/fwcH/3sDA/96+vv/gw8P/6NTU/928 + vP/bubn/376+/7CCgv/Pn5//1aen/9utrf/fs7P/3bGx/6Rxcf99Skr/cD8/SAAAAAAAAAAAAAAAAAAA + AACmb28Kklxc7d+trf/lsLD/0p6e/8SQkP+2gYH/qHJy/+nT0//o1NT/5s/P/9u5uf/n0dH/5tHR/+bP + z//mzs7/5c3N/+bOzv/n0ND/4sfH/9WwsP/Uqan/16ys/9yzs//hvb3/4sbG/+DExP/gwsL/38HB/97A + wP/evb3/4snJ/+TMzP/cubn/3Lq6/9y6uv/cubn/2be3/9m1tf/Ys7P/0amp/55qav+OW1v/c0BAkQAA + AAAAAAAAAAAAAAAAAACVYGBYoG5u//rIyP/muLj/3bKy/9ewsP/UsLD/2bq6/+zY2P/p1dX/3r+//+LH + x//o09P/59HR/+fQ0P/m0ND/59DQ/+rV1f/KpKT/t4KC+82Tk7jcoaF64Kioa+Wvr4/eqqrd4LCw/uLC + wv/gxMT/4MLC/9/Bwf/ewMD/3r6+/+fS0v/ev7//3Lq6/9u5uf/at7f/2ra2/9m1tf/Ys7P/27i4/6t6 + ev+NWlr/dUBAfwAAAAAAAAAAAAAAAAAAAACXYmKgwJ2d/+7e3v/q2tr/69ra/+zZ2f/s2dn/7NnZ/+nX + 1//r19f/2LGx/+jV1f/o09P/6NPT/+jS0v/n0dH/7NfX/7+Zmf+oc3PazJGRMgAAAAAAAAAAAAAAAAAA + AAD3jY0G7Lm5feKurv3iwsL/4MTE/+DCwv/fwcH/3r+//+LIyP/jyMj/3Lu7/9y6uv/buLj/2re3/9m2 + tv/ZtLT/27a2/8yiov+BTU3/eUREOwAAAAAAAAAAAAAAAAAAAACVYGCuyKio/+7d3f/r2Nj/69jY/+vY + 2P/r2Nj/6tjY/+rY2P/n0ND/2bW1/+vZ2f/p1dX/6dTU/+jU1P/q1tb/3cTE/5hhYfS4eXkmAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAO22to3fsLD/4sbG/+DDw//fwsL/38DA/9/Bwf/lz8//3bu7/9y7 + u//bubn/27i4/9u4uP/dubn/4b6+/7SJif97RkbudE5OBwAAAAAAAAAAAAAAAAAAAACYY2O4zK6u/+/e + 3v/s2tr/7Nra/+za2v/r2tr/69nZ/+za2v/ky8v/3Lu7/+va2v/q19f/6tbW/+nV1f/u2tr/uZWV/5ti + YqQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOKurhXWo6P64cXF/+LExP/gw8P/38HB/9+/ + v//lzs7/3r6+/928vP/du7v/3r29/+K/v/+7kpL/hlRU/nxGRtqLUlJRAAAAAAAAAAAAAAAAAAAAAAAA + AACYZWXD07m5//Pk5P/u3d3/7dzc/+zc3P/s29v/7Nvb/+3d3f/jycn/3b6+/+zc3P/r2Nj/6tfX/+rX + 1//x4OD/mGlp/5ZeXogAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANCGhgTOm5vu4MHB/+HG + xv/gxMT/4MLC/9/Bwf/jy8v/38HB/929vf/gwMD/vJWV/4lZWf9+S0vailRUYHM3NwUAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACfa2vCtImJ/9nAwP/x5OT/8uTk/+/g4P/u3t7/7d3d/+7d3f/kzMz/3bu7/+3d + 3f/s2tr/69nZ/+zY2P/w4OD/ilRU/41UVLsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAM+c + nCnFkZH948nJ/+PGxv/hxcX/4MPD/+DCwv/jyMj/38HB/92/v//evr7/e0ZG/4NRUamGJCQGAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACteXklrHd3h5pwcN2gcHD+vpeX/9vDw//y5eX/8ODg/+/f + 3//p09P/2LGx/+/g4P/s29v/7Nra/+vb2//x4+P/mWZm/39JSf2UVlZRAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA3pKSBLiEhLjMoaH/5c3N/+LHx//hxsb/4cTE/+DDw//hx8f/38HB/9+/v//dvLz/jltb/4ZV + VfyIWlqCkQAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAGtf381sXd3i6Zu + bt+seXn+8+fn/+/i4v/v4OD/0aWl/+7g4P/t3t7/7dzc/+zb2//x4eH/uJGR/45ZWf96SEj3iVNTd6Fb + Ww0AAAAAAAAAAAAAAAC5fX0sqXFxuruNjf/n0dH/48vL/+PIyP/ix8f/4cXF/+DExP/ixsb/38HB/9/A + wP/UsLD/lmFh/5xpaf+JV1f/hFVVrqFcXA0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAJdzcwemb2/g28TE//Hk5P/x5eX/2bOz/+bNzf/v4OD/7d3d/+3c3P/t3d3/6tjY/55q + av+gbGz/hVJS/35LS/KNVVXClV1dtJhiYtWYY2P9x52d//vr6//lzMz/5MvL/+PJyf/iyMj/4sbG/+HE + xP/gw8P/38LC/+HCwv/Rra3/lV9f/6Btbf+lcnL/jVtb/49XV48AAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAALmMjAaocnLAxZ2d//Pp6f/x5OT/6NHR/9Wrq//w5eX/7uDg/+7e + 3v/t3t7/7+Dg/+LMzP+xfn7/v4qK/8OPj/++i4v/xpKS/9+trf//2tr//+fn/+fQ0P/lzc3/5MvL/+PK + yv/jyMj/48jI/+DDw//gw8P/4MLC/9/Cwv/hw8P/0K2t/6d0dP+mcnL/m2ho/45WVrwAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAuXp6Dq54eLi1goL+57+///Po6P/y5eX/8unp/9as + rP/kysr/8ePj/+7f3//u3t7/7d3d/+7f3//u3t7/17a2/9arq//ks7P/88XF//rS0v/w1tb/5tHR/+bP + z//lzs7/5czM/+TLy//jycn/4cfH/96/v//ixMT/4MPD/9/Bwf/gwMD/4MHB/+DBwf++kpL/om5u/4xV + Vd8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADGlZUMrnp6y72Rkf/x0dH/79PT//Po + 6P/x5eX/8ufn/+3d3f/QoaH/7Nvb//Di4v/u39//7t7e/+3d3f/t3d3/7t3d/+3d3f/r2tr/6tjY/+nW + 1v/o09P/59LS/+fQ0P/mz8//5c3N/+TNzf/kzMz/3b6+/+DDw//hxcX/4MTE/+DCwv/fwcH/3r+//96+ + vv/jxMT/wJiY/4ZVVeKcAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC+hoZItYSE//zt + 7f/14uL/9Orq//Pp6f/y5+f/8ubm//Lo6P/nz8//0aKi/+7d3f/w5OT/7t/f/+7e3v/t3d3/7Nvb/+za + 2v/r2Nj/6tfX/+nV1f/p1NT/6NPT/+fR0f/mz8//5c/P/+XOzv/evr7/3sDA/+PJyf/jxsb/4cTE/+DD + w//fwcH/3sDA/9+/v//kxsb/l2Vl/49ZWXQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AADAhoZuxJyc//329v/06+v/9Ovr//Pp6f/z6Oj/8+fn//Lm5v/z6en/5czM/86fn//o1NT/8eXl/+/g + 4P/v3t7/7dzc/+zb2//r2dn/69jY/+rW1v/p1dX/6NPT/+fT0//o0dH/58/P/927u//dvb3/5MvL/+TJ + yf/ly8v/5cvL/+PHx//hxcX/4MHB/+HCwv/JpKT/hk9P6JJjYwwAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAADEiIiU0LCw//r19f/17Oz/9evr//Tr6//06ur/8+np//Po6P/y6Oj/9Ojo/+rZ + 2f/QoqL/2re3/+za2v/w5eX/7uDg/+7e3v/t29v/69ra/+vY2P/q2Nj/69bW/+nU1P/hxcX/2LOz/9+/ + v//mz8//587O/+bNzf+8lJT/tIqK/8Kdnf/QsLD/38HB/+rMzP+YaGj/lVxcdAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADPkpJauIWF/vTq6v/48fH/9e3t//bu7v/27+//+PHx//fx + 8f/27e3/8+np//Ln5//y5+f/4cTE/8+goP/Wra3/4MLC/+fQ0P/q19f/69fX/+fS0v/iyMj/3Lu7/9at + rf/bt7f/5czM/+fQ0P/o0dH/0LCw/51sbP6ZZ2fBoWlplJxlZb6RYWHni1hY/ZJgYP+MWVnokmJiDAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAxIqKlL+Rkf/89/f//Pn5//Tq + 6v/excX/yqGh/7qHh//Wtrb/9ezs//Xq6v/y5+f/8ebm//Lm5v/o0dH/3by8/9avr//UqKj/06en/9Wt + rf/btrb/4MPD/+fS0v/q1dX/6NHR/+bQ0P/r1dX/pHFx/55tbYSMAAACAAAAAAAAAACSAAACmGJiGJ1k + ZECpaGglAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAxJOTBrqE + hMHIn5//xJiY/7yDg/rJj4/EzpSUetCVlU7Hjo7Av4qK/t3Bwf/16ur/8eTk//Hk5P/w4+P/7+Pj//Di + 4v/v4OD/7t/f/+3d3f/r2tr/69jY/+nV1f/o1NT/59HR/+bQ0P/nzs7/oGpq/6p0dHEAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAANGTkxjOlpaL0JaWWc6SkhQAAAAAAAAAAAAAAAAAAAAAyZOTV7V+fv706+v/8eXl//Dj + 4//w4uL/8ODg/+/h4f/v4eH/7+Dg/+/g4P/v3t7/7NnZ/+nW1v/o09P/59HR/+bR0f/n0ND/nWlp/6xy + cpMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1ZCQGbqF + hf317Oz/8+fn//Hk5P/w4uL/8OPj/+vb2//UtbX/zKmp/8ScnP+7jo7/3cPD/+zZ2f/o09P/59LS/+jQ + 0P/r1tb/pXJy/6x0dLUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA1Z2dGbyFhf306+v/8ubm//Hl5f/w5OT/9enp/76QkP+zfX3HvYODmMGFhXu5f3+KrXd3/uTN + zf/q19f/6dLS/+fQ0P/t2Nj/sYaG/6xzc9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA1ZycGb2IiP307e3/8ujo//Hl5f/z5+f/2b29/7WAgNvMkZEKAAAAAAAA + AAAAAAAAuoaGhq58fP7p09P/69bW/+zX1//fxMT/p3d3/693d8YAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1JycGb+Kiv358vL/9e3t//Tq6v/x5OT/u4aG/dGW + lksAAAAAAAAAAAAAAAAAAAAAjQAAAq19faOxgoL/59LS/72Vlf+hamr1rHNzgbV4eAoAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA6qqqDsSQkO3GmZn/0q2t/9/G + xv/LpKT/xo6OrQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANR+fgepd3e8p3Jy/q93d7G6fn4jAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANKO + jhXAjIxOvYiIh7qHh8C7hYXXxY+PHwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC4cXEMs3x8MQAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////AAD///////8AAP//8H///wAA///wP/// + AAD//+A///8AAP//4B/H/wAA/+/gHwP/AAD/x+AOAf8AAP+BwAAB/wAA/wAAAAH/AAD+AAAAAf8AAP4A + AAAB/wAA/gAAAAP/AAD+AAAAA/8AAP4AAAAD/wAA/wAAAAH/AAD/AAAAAA8AAP+AAAAABwAA8AAAAAAH + AADgAAAAAAcAAOAAAAAAAwAAwAAAAAADAADAAAfgAAcAAMAAD/AABwAAwAAP+AAHAADAAA/4AB8AAMAA + D/gAfwAA4AAH8AA/AAD8AAPgAB8AAP8AAAAADwAA/wAAAAAPAAD+AAAAAA8AAPwAAAAADwAA/AAAAAAP + AAD4AAAAAB8AAPgAAAAAHwAA+AAAAAA/AAD8AAAAH/8AAP4EAAAf/wAA/z4AAB//AAD//wAAH/8AAP// + AAAf/wAA//8B4B//AAD//wPwP/8AAP//A/j//wAA///H////AAD///////8AAP///////wAA + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/CommonObjects/FilterRuleSection.cs b/Demo_Source_Code/CSharpDemo/CommonObjects/FilterRuleSection.cs new file mode 100644 index 0000000..dd9ccb7 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/CommonObjects/FilterRuleSection.cs @@ -0,0 +1,703 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Configuration; + +using EaseFilter.FilterControl; + +namespace EaseFilter.CommonObjects +{ + public class FilterRuleSection : ConfigurationSection + { + [ConfigurationProperty("", IsRequired = true, IsDefaultCollection = true)] + public FilterRuleCollection Instances + { + get { return (FilterRuleCollection)this[""]; } + set { this[""] = value; } + } + } + + public class FilterRuleCollection : ConfigurationElementCollection + { + public FileFilterRule this[int index] + { + get { return (FileFilterRule)BaseGet(index); } + set + { + if (BaseGet(index) != null) + { + BaseRemoveAt(index); + } + BaseAdd(index, value); + } + } + + public void Add(FileFilterRule filterRule) + { + BaseAdd(filterRule); + } + + public void Clear() + { + BaseClear(); + } + + public void Remove(FileFilterRule filterRule) + { + BaseRemove(filterRule.IncludeFileFilterMask); + } + + public void RemoveAt(int index) + { + BaseRemoveAt(index); + } + + public void Remove(string name) + { + BaseRemove(name); + } + + protected override ConfigurationElement CreateNewElement() + { + return new FileFilterRule(); + } + + protected override object GetElementKey(ConfigurationElement element) + { + //set to whatever Element Property you want to use for a key + return ((FileFilterRule)element).IncludeFileFilterMask; + } + } + + public class FileFilterRule : ConfigurationElement + { + //A filter rule must have a unique include file filter mask, + //A filter rule can have multiple exclude file filter masks. + //Make sure to set IsKey=true for property exposed as the GetElementKey above + /// + /// if the file path matches the includeFileFilterMask, the filter driver will process the registered IOs, or it will skip the IOs for this file. + /// + [ConfigurationProperty("includeFileFilterMask", IsKey = true, IsRequired = true)] + public string IncludeFileFilterMask + { + get { return (string)base["includeFileFilterMask"]; } + set { base["includeFileFilterMask"] = value; } + } + + /// + /// If the file path matches the excludeFileFilterMasks, the filter driver will skip the IOs for this file. + /// seperate the multiple items with ';' + /// + [ConfigurationProperty("excludeFileFilterMasks", IsRequired = false)] + public string ExcludeFileFilterMasks + { + get { return (string)base["excludeFileFilterMasks"]; } + set { base["excludeFileFilterMasks"] = value; } + } + + /// + /// if the file path matches the includeFileFilterMask and the includeProcessNames is not empty, + /// only the IOs from the process name which matches the includeProcessNames will be managed by filter driver. + /// seperate the multiple items with ';' + /// + [ConfigurationProperty("includeProcessNames", IsRequired = false)] + public string IncludeProcessNames + { + get { return (string)base["includeProcessNames"]; } + set { base["includeProcessNames"] = value; } + } + + /// + /// if the file path matches the includeFileFilterMask and the excludeProcessNames is not empty, + /// the IOs from the process name which matches the excludeProcessNames will be skipped by filter driver. + /// seperate the multiple items with ';' + /// + [ConfigurationProperty("excludeProcessNames", IsRequired = false)] + public string ExcludeProcessNames + { + get { return (string)base["excludeProcessNames"]; } + set { base["excludeProcessNames"] = value; } + } + + /// + /// if the file path matches the includeFileFilterMask and the includeUserNames is not empty, + /// only the IOs from the user name which matches the includeUserNames will be managed by filter driver. + /// seperate the multiple items with ';' + /// + [ConfigurationProperty("includeUserNames", IsRequired = false)] + public string IncludeUserNames + { + get { return (string)base["includeUserNames"]; } + set { base["includeUserNames"] = value; } + } + + /// + /// if the file path matches the includeFileFilterMask and the excludeUserNames is not empty, + /// the IOs from the user name which matches the excludeUserNames will be skipped by filter driver. + /// seperate the multiple items with ';' + /// + [ConfigurationProperty("excludeUserNames", IsRequired = false)] + public string ExcludeUserNames + { + get { return (string)base["excludeUserNames"]; } + set { base["excludeUserNames"] = value; } + } + + /// + /// if the file path matches the includeFileFilterMask and the includeProcessIds is not empty, + /// only the IOs from the process Id which matches the includeProcessIds will be managed by filter driver. + /// seperate the multiple items with ';' + /// + [ConfigurationProperty("includeProcessIds", IsRequired = false)] + public string IncludeProcessIds + { + get { return (string)base["includeProcessIds"]; } + set { base["includeProcessIds"] = value; } + } + + /// + /// if the file path matches the includeFileFilterMask and the excludeProcessIds is not empty, + /// the IOs from the process Id which matches the excludeProcessIds will be skipped by filter driver. + /// seperate the multiple items with ';' + /// + [ConfigurationProperty("excludeProcessIds", IsRequired = false)] + public string ExcludeProcessIds + { + get { return (string)base["excludeProcessIds"]; } + set { base["excludeProcessIds"] = value; } + } + + /// + /// if the file path matches hiddenFileFilterMasks, the file will be hidden + /// seperate the multiple items with ';' + /// + [ConfigurationProperty("hiddenFileFilterMasks", IsRequired = false)] + public string HiddenFileFilterMasks + { + get { return (string)base["hiddenFileFilterMasks"]; } + set { base["hiddenFileFilterMasks"] = value; } + } + + /// + /// if the reparse file was enabled, the open to the file path will be reparsed to the new path replaced by reparseFileFilterMasks + /// + [ConfigurationProperty("reparseFileFilterMask", IsRequired = false)] + public string ReparseFileFilterMask + { + get { return (string)base["reparseFileFilterMask"]; } + set { base["reparseFileFilterMask"] = value; } + } + + /// + /// The file access rights for the user name list, seperated with ";" for multiple users + /// the format is "userName!accessFlags;", e.g. "mydomain\user1!123456;" + /// seperate the multiple items with ';' + /// + [ConfigurationProperty("userRights", IsRequired = false)] + public string UserRights + { + get { return (string)base["userRights"]; } + set { base["userRights"] = value; } + } + + /// + /// The file access rights inside the filter rule for the process name list, seperated with ";" for multiple processes + /// the format is "processName!accessFlags;", e.g. "notepad.exe!123456;" + /// seperate the multiple items with ';' + /// + [ConfigurationProperty("processNameRights", IsRequired = false)] + public string ProcessNameRights + { + get { return (string)base["processNameRights"]; } + set { base["processNameRights"] = value; } + } + + /// + /// The file access rights for the process which has the specific sha256 hash. Seperated with ";" for multiple processes + /// the format is "sha256hash!accessFlags;", e.g. "A10B....BC!123456;" + /// seperate the multiple items with ';' + /// + [ConfigurationProperty("sha256ProcessAccessRights", IsRequired = false)] + public string Sha256ProcessAccessRights + { + get { return (string)base["sha256ProcessAccessRights"]; } + set { base["sha256ProcessAccessRights"] = value; } + } + + /// + /// The file access rights for the process which was signed with the specific certificate. Seperated with ";" for multiple processes + /// the format is "certificatename!accessFlags;", e.g. "A10B....BC!123456;" + /// seperate the multiple items with ';' + /// + [ConfigurationProperty("signedProcessAccessRights", IsRequired = false)] + public string SignedProcessAccessRights + { + get { return (string)base["signedProcessAccessRights"]; } + set { base["signedProcessAccessRights"] = value; } + } + + /// + /// The file access rights inside the filter rule for the process Id list, seperated with ";" for multiple processes + /// the format is "processId!accessFlags;", e.g. "1234!123456;" + /// seperate the multiple items with ';' + /// + [ConfigurationProperty("processIdRights", IsRequired = false)] + public string ProcessIdRights + { + get { return (string)base["processIdRights"]; } + set { base["processIdRights"] = value; } + } + + + [ConfigurationProperty("encryptionPassPhrase", IsRequired = false)] + public string EncryptionPassPhrase + { + get + { + string key = (string)base["encryptionPassPhrase"]; + if (Utils.IsBase64String(key)) + { + key = Utils.AESEncryptDecryptStr(key, Utils.EncryptType.Decryption); + } + + return key; + } + set + { + string key = value.Trim(); + + if (key.Length > 0) + { + key = Utils.AESEncryptDecryptStr(key, Utils.EncryptType.Encryption); + } + + base["encryptionPassPhrase"] = key; + } + } + + /// + /// the AES encryption key size, it could be 8bytes(128bit), 24bytes(196bits), 32bytes(256bits). + /// + [ConfigurationProperty("encryptionKeySize", IsRequired = false)] + public int EncryptionKeySize + { + get { return (int)base["encryptionKeySize"]; } + set { base["encryptionKeySize"] = value; } + } + + /// + /// If the encrypt write buffer size is greater than 0, then the small buffer encryption write will be combined together to a bigger buffer, + /// and write it to the disk. + /// + [ConfigurationProperty("encryptWriteBufferSize", IsRequired = false)] + public uint EncryptWriteBufferSize + { + get { return (uint)base["encryptWriteBufferSize"]; } + set { base["encryptWriteBufferSize"] = value; } + } + + + /// + /// the file access control flags for the filter rule. + /// + [ConfigurationProperty("accessFlag", IsRequired = true)] + public uint AccessFlag + { + get { return (uint)base["accessFlag"]; } + set { base["accessFlag"] = value; } + } + + /// + /// The register the file events + /// + [ConfigurationProperty("registerMonitorFileEvents", IsRequired = false)] + public uint RegisterMonitorFileEvents + { + get { return (uint)base["registerMonitorFileEvents"]; } + set { base["registerMonitorFileEvents"] = value; } + } + + /// + /// register monitor I/O requests + /// + [ConfigurationProperty("registerMonitorFileIOEvents", IsRequired = false)] + public ulong RegisterMonitorFileIOEvents + { + get { return (ulong)base["registerMonitorFileIOEvents"]; } + set { base["registerMonitorFileIOEvents"] = value; } + } + + /// + /// If it is true, the filter driver will send the monitor events asynchronously, the monitor event buffer will be used. + /// if it is false, the filter driver will send the monitor events synchronously, block and wait till the events being picked up. + /// + [ConfigurationProperty("enableMonitorEventBuffer", IsRequired = false)] + public bool EnableMonitorEventBuffer + { + get { return (bool)base["enableMonitorEventBuffer"]; } + set { base["enableMonitorEventBuffer"] = value; } + } + + /// + /// register control I/O requests, the filter driver will block and wait for the response. + /// + [ConfigurationProperty("registerControlFileIOEvents", IsRequired = false)] + public ulong RegisterControlFileIOEvents + { + get { return (ulong)base["registerControlFileIOEvents"]; } + set { base["registerControlFileIOEvents"] = value; } + } + + [ConfigurationProperty("filterDesiredAccess", IsRequired = false)] + public uint FilterDesiredAccess + { + get { return (uint)base["filterDesiredAccess"]; } + set { base["filterDesiredAccess"] = value; } + } + + [ConfigurationProperty("filterDisposition", IsRequired = false)] + public uint FilterDisposition + { + get { return (uint)base["filterDisposition"]; } + set { base["filterDisposition"] = value; } + } + + [ConfigurationProperty("filterCreateOptions", IsRequired = false)] + public uint FilterCreateOptions + { + get { return (uint)base["filterCreateOptions"]; } + set { base["filterCreateOptions"] = value; } + } + /// + /// Enable the filter rule in boot time for control filter if it is true. + /// + [ConfigurationProperty("isResident", IsRequired = false)] + public bool IsResident + { + get { return (bool)base["isResident"]; } + set { base["isResident"] = value; } + } + + /// + /// the encryption method for filter driver based on the filter rule, reference EncryptMethod enumeration definition + /// + [ConfigurationProperty("encryptMethod", IsRequired = false)] + public int EncryptMethod + { + get { return (int)base["encryptMethod"]; } + set { base["encryptMethod"] = value; } + } + + /// + /// The filter rule type to categorize the filter rules. + /// + [ConfigurationProperty("type", IsRequired = false)] + public int Type + { + get { return (int)base["type"]; } + set { base["type"] = value; } + } + + + public FileFilterRule Copy() + { + FileFilterRule dest = new FileFilterRule(); + dest.AccessFlag = AccessFlag; + dest.RegisterControlFileIOEvents = RegisterControlFileIOEvents; + dest.EncryptionPassPhrase = EncryptionPassPhrase; + dest.EncryptionKeySize = EncryptionKeySize; + dest.EncryptMethod = EncryptMethod; + dest.RegisterMonitorFileEvents = RegisterMonitorFileEvents; + dest.ExcludeFileFilterMasks = ExcludeFileFilterMasks; + dest.ExcludeProcessIds = ExcludeProcessIds; + dest.ExcludeProcessNames = ExcludeProcessNames; + dest.ExcludeUserNames = ExcludeUserNames; + dest.HiddenFileFilterMasks = HiddenFileFilterMasks; + dest.IncludeFileFilterMask = IncludeFileFilterMask; + dest.IncludeProcessIds = IncludeProcessIds; + dest.IncludeProcessNames = IncludeProcessNames; + dest.IncludeUserNames = IncludeUserNames; + dest.IsResident = IsResident; + dest.RegisterMonitorFileIOEvents = RegisterMonitorFileIOEvents; + dest.ProcessIdRights = ProcessIdRights; + dest.ProcessNameRights = ProcessNameRights; + dest.Sha256ProcessAccessRights = Sha256ProcessAccessRights; + dest.SignedProcessAccessRights = SignedProcessAccessRights; + dest.ReparseFileFilterMask = ReparseFileFilterMask; + dest.Type = Type; + dest.UserRights = UserRights; + dest.FilterCreateOptions = FilterCreateOptions; + dest.FilterDesiredAccess = FilterDesiredAccess; + dest.FilterDisposition = FilterDisposition; + dest.EnableMonitorEventBuffer = EnableMonitorEventBuffer; + dest.EncryptWriteBufferSize = EncryptWriteBufferSize; + + return dest; + } + + public FileFilter ToFileFilter() + { + try + { + FileFilter fileFilter = new FileFilter(IncludeFileFilterMask); + fileFilter.AccessFlags = (FilterAPI.AccessFlag)AccessFlag; + fileFilter.FileChangeEventFilter = (FilterAPI.FileChangedEvents)RegisterMonitorFileEvents; + fileFilter.ControlFileIOEventFilter = RegisterControlFileIOEvents; + fileFilter.MonitorFileIOEventFilter = RegisterMonitorFileIOEvents; + fileFilter.IsResident = IsResident; + fileFilter.FilterCreateOptions = FilterCreateOptions; + fileFilter.FilterDesiredAccess = FilterDesiredAccess; + fileFilter.FilterDisposition = FilterDisposition; + fileFilter.EnableMonitorEventBuffer = EnableMonitorEventBuffer; + fileFilter.EncryptWriteBufferSize = EncryptWriteBufferSize; + + if ((fileFilter.AccessFlags & FilterAPI.AccessFlag.ALLOW_COPY_PROTECTED_FILES_OUT) > 0) + { + fileFilter.EnableBlockSaveAs = true; + } + + string[] excludeFileFilterMasks = ExcludeFileFilterMasks.Split(new char[] { ';' }); + if (excludeFileFilterMasks.Length > 0) + { + foreach (string excludeFileFilterMask in excludeFileFilterMasks) + { + if (excludeFileFilterMask.Trim().Length > 0) + { + fileFilter.ExcludeFileFilterMaskList.Add(excludeFileFilterMask); + } + } + } + + string[] excludeProcessIds = ExcludeProcessIds.Split(new char[] { ';' }); + if (excludeProcessIds.Length > 0) + { + foreach (string excludeProcessId in excludeProcessIds) + { + if (excludeProcessId.Trim().Length > 0) + { + uint exPid = 0; + if (uint.TryParse(excludeProcessId, out exPid)) + { + fileFilter.ExcludeProcessIdList.Add(exPid); + } + } + } + } + + string[] excludeProcessNames = ExcludeProcessNames.Split(new char[] { ';' }); + if (excludeProcessNames.Length > 0) + { + foreach (string excludeProcessName in excludeProcessNames) + { + if (excludeProcessName.Trim().Length > 0) + { + fileFilter.ExcludeProcessNameList.Add(excludeProcessName); + } + } + } + + string[] excludeUserNames = ExcludeUserNames.Split(new char[] { ';' }); + if (excludeUserNames.Length > 0) + { + foreach (string excludeUserName in excludeUserNames) + { + if (excludeUserName.Trim().Length > 0) + { + fileFilter.ExcludeUserNameList.Add(excludeUserName); + } + } + } + + string[] includeProcessIds = IncludeProcessIds.Split(new char[] { ';' }); + if (includeProcessIds.Length > 0) + { + foreach (string includeProcessId in includeProcessIds) + { + if (includeProcessId.Trim().Length > 0) + { + uint exPid = 0; + if (uint.TryParse(includeProcessId, out exPid)) + { + fileFilter.IncludeProcessIdList.Add(exPid); + } + } + } + } + + string[] includeProcessNames = IncludeProcessNames.Split(new char[] { ';' }); + if (includeProcessNames.Length > 0) + { + foreach (string includeProcessName in includeProcessNames) + { + if (includeProcessName.Trim().Length > 0) + { + fileFilter.IncludeProcessNameList.Add(includeProcessName); + } + } + } + + string[] includeUserNames = IncludeUserNames.Split(new char[] { ';' }); + if (includeUserNames.Length > 0) + { + foreach (string includeUserName in includeUserNames) + { + if (includeUserName.Trim().Length > 0) + { + fileFilter.IncludeUserNameList.Add(includeUserName); + } + } + } + + string[] processIdRights = ProcessIdRights.Split(new char[] { ';' }); + if (processIdRights.Length > 0) + { + foreach (string processIdRight in processIdRights) + { + if (processIdRight.Trim().Length > 0) + { + uint processId = uint.Parse(processIdRight.Substring(0, processIdRight.IndexOf('!'))); + uint accessFlags = uint.Parse(processIdRight.Substring(processIdRight.IndexOf('!') + 1)); + fileFilter.ProcessIdAccessRightList.Add(processId, accessFlags); + } + } + } + + string[] processNameRights = ProcessNameRights.Split(new char[] { ';' }); + if (processNameRights.Length > 0) + { + foreach (string processRight in processNameRights) + { + if (processRight.Trim().Length > 0) + { + string processName = processRight.Substring(0, processRight.IndexOf('!')); + uint accessFlags = uint.Parse(processRight.Substring(processRight.IndexOf('!') + 1)); + fileFilter.ProcessNameAccessRightList.Add(processName, accessFlags); + } + } + } + + string[] processSha256Rights = Sha256ProcessAccessRights.Split(new char[] { ';' }); + if (processSha256Rights.Length > 0) + { + foreach (string processRight in processSha256Rights) + { + if (processRight.Trim().Length > 0) + { + string processSha256Hex = processRight.Substring(0, processRight.IndexOf('!')); + byte[] processSha256 = Utils.HexToByteArray(processSha256Hex); + uint accessFlags = uint.Parse(processRight.Substring(processRight.IndexOf('!') + 1)); + fileFilter.Sha256ProcessAccessRightList.Add(processSha256, accessFlags); + } + } + } + + string[] signedProcessAccessRights = SignedProcessAccessRights.Split(new char[] { ';' }); + if (signedProcessAccessRights.Length > 0) + { + foreach (string processRight in signedProcessAccessRights) + { + if (processRight.Trim().Length > 0) + { + string certificateName = processRight.Substring(0, processRight.IndexOf('!')); + uint accessFlags = uint.Parse(processRight.Substring(processRight.IndexOf('!') + 1)); + fileFilter.SignedProcessAccessRightList.Add(certificateName, accessFlags); + } + } + } + + string[] userRights = UserRights.Split(new char[] { ';' }); + if (userRights.Length > 0) + { + foreach (string userRight in userRights) + { + if (userRight.Trim().Length > 0) + { + string userName = userRight.Substring(0, userRight.IndexOf('!')); + uint accessFlags = uint.Parse(userRight.Substring(userRight.IndexOf('!') + 1)); + fileFilter.userAccessRightList.Add(userName, accessFlags); + } + } + } + + if ((AccessFlag & (uint)FilterAPI.AccessFlag.ENABLE_HIDE_FILES_IN_DIRECTORY_BROWSING) > 0) + { + fileFilter.EnableHiddenFile = true; + string[] hiddenFileFilterMasks = HiddenFileFilterMasks.Split(new char[] { ';' }); + if (hiddenFileFilterMasks.Length > 0) + { + foreach (string hiddenFileFilterMask in hiddenFileFilterMasks) + { + if (hiddenFileFilterMask.Trim().Length > 0) + { + fileFilter.HiddenFileFilterMaskList.Add(hiddenFileFilterMask); + } + } + } + } + + fileFilter.ReparseFileFilterMask = ReparseFileFilterMask; + + if ((AccessFlag & (uint)FilterAPI.AccessFlag.ENABLE_FILE_ENCRYPTION_RULE) > 0) + { + fileFilter.EnableEncryption = true; + + switch ((FilterAPI.EncryptionMethod)EncryptMethod) + { + case FilterAPI.EncryptionMethod.ENCRYPT_FILE_WITH_SAME_KEY_AND_IV: + { + fileFilter.EncryptionKey = Utils.GetKeyByPassPhrase(EncryptionPassPhrase, EncryptionKeySize); + fileFilter.EncryptionIV = Utils.GetIVByPassPhrase(EncryptionPassPhrase); + break; + } + + case FilterAPI.EncryptionMethod.ENCRYPT_FILE_WITH_SAME_KEY_AND_UNIQUE_IV: + { + //it will generate the unique iv key for every encrypted file + fileFilter.EncryptionKey = Utils.GetKeyByPassPhrase(EncryptionPassPhrase, EncryptionKeySize); + break; + } + case FilterAPI.EncryptionMethod.ENCRYPT_FILE_WITH_KEY_IV_AND_TAGDATA_FROM_SERVICE: + { + //with this setting, to open or create encrypted file, it will request the encryption key and iv from the user mode callback service. + fileFilter.EnableEncryptionKeyFromService = true; + break; + } + } + + if( Type == 1)// (FilterRuleType.EncryptionOnRead ) + { + //encrypt file on the read + AccessFlag &= ~(uint)FilterAPI.AccessFlag.DISABLE_ENCRYPT_DATA_ON_READ; + } + } + + return fileFilter; + } + catch (Exception ex) + { + throw new Exception("Convert filter rule to FileFilter failed," + ex.Message); + } + } + + } + + +} diff --git a/Demo_Source_Code/CSharpDemo/CommonObjects/GlobalConfig.cs b/Demo_Source_Code/CSharpDemo/CommonObjects/GlobalConfig.cs new file mode 100644 index 0000000..5f634c1 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/CommonObjects/GlobalConfig.cs @@ -0,0 +1,883 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// +/// + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Text; +using System.Runtime.InteropServices; +using System.Security.Principal; +using System.IO; +using System.Configuration; +using System.Collections; +using System.Xml; +using System.Text.RegularExpressions; +using System.Threading; +using System.Reflection; +using System.Diagnostics; + +using EaseFilter.FilterControl; + +namespace EaseFilter.CommonObjects +{ + + public class GlobalConfig + { + static Assembly assembly = System.Reflection.Assembly.GetEntryAssembly(); + public static string AssemblyPath = Path.GetDirectoryName(assembly.Location); + public static string AssemblyName = assembly.Location; + + //the message output level. It will output the messages which less than this level. + static EventLevel eventLevel = EventLevel.Information; + static bool[] selectedDisplayEvents = new bool[] { false, true, true, true, false, false }; + static EventOutputType eventOutputType = EventOutputType.File; + //The log file name if outputType is ToFile. + static string eventLogFileName = "EventLog.txt"; + static int maxEventLogFileSize = 4 * 1024 * 1024; //4MB + static string eventSource = "EaseFilter"; + static string eventLogName = "EaseFilter"; + + static uint volumeControlFlag = (uint)(FilterAPI.VolumeControlFlag.VOLUME_ATTACHED_NOTIFICATION | FilterAPI.VolumeControlFlag.VOLUME_DETACHED_NOTIFICATION); + + static int filterConnectionThreads = 5; + static int connectionTimeOut = 10; //seconds + static private Dictionary filterRules = new Dictionary(); + static List includePidList = new List(); + static List excludePidList = new List(); + static List protectPidList = new List(); + static string includedUsers = string.Empty; + static string excludedUsers = string.Empty; + + static uint requestIORegistration = 0; + static uint displayEvents = 0; + + static string accountName = ""; + static string masterPassword = "testpassword"; + static string licenseKey = ""; + static long expireTime = 0; + + static int maximumFilterMessages = 1000; + static string filterMessageLogName = "filterMessage.log"; + static long filterMessageLogFileSize = 10 * 1024 * 1024; + static bool enableLogTransaction = false; + static bool outputMessageToConsole = true; + static bool enableNotification = false; + + static string protectFolder = "c:\\EaseFilter\\protectFolder"; + static string protectFolderWhiteList = "*"; + static string protectFolderBlackList = "explorer.exe"; + static string shareFolder = "c:\\EaseFilter\\shareFolder"; + static string shareFolderWhiteList = "notepad.exe;wordpad.exe"; + static string shareFolderBlackList = "explorer.exe"; + static string drInfoFolder = "c:\\EaseFilter\\DRInfoFolder"; + static string dropFolder = "c:\\EaseFilter\\dropFolder"; + static bool storeSharedFileMetaDataInServer = false; + static string shareFileExt = ".psf"; + + static string configFileName = ConfigSetting.GetFilePath(); + + //the filter driver will use the default IV to encrypt the new file if it is true. + static bool enableDefaultIVKey = false; + + static uint currentPid = (uint)System.Diagnostics.Process.GetCurrentProcess().Id; + + //dont display the directory IO request if it is true. + static bool disableDirIO = false; + + static uint booleanConfig = (uint)FilterAPI.BooleanConfig.ENABLE_SEND_DENIED_EVENT; + + public static bool isRunning = true; + public static ManualResetEvent stopEvent = new ManualResetEvent(false); + + public static FilterAPI.FilterType filterType = FilterAPI.FilterType.MONITOR_FILTER; + + public static Stopwatch stopWatch = new Stopwatch(); + + //the process filter rule collection + static private Dictionary processFilterRules = new Dictionary(); + + //the registry filter rule collection + static private Dictionary registryFilterRules = new Dictionary(); + + static GlobalConfig() + { + string lastError = string.Empty; + + stopWatch.Start(); + Load(); + + Utils.CopyOSPlatformDependentFiles(ref lastError); + + } + + public static void Load() + { + filterRules.Clear(); + processFilterRules.Clear(); + registryFilterRules.Clear(); + + try + { + + filterRules = ConfigSetting.GetFilterRules(); + processFilterRules = ConfigSetting.GetProcessFilterRules(); + registryFilterRules = ConfigSetting.GetRegistryFilterRules(); + + booleanConfig = ConfigSetting.Get("booleanConfig", booleanConfig); + filterConnectionThreads = ConfigSetting.Get("filterConnectionThreads", filterConnectionThreads); + requestIORegistration = ConfigSetting.Get("requestIORegistration", requestIORegistration); + displayEvents = ConfigSetting.Get("displayEvents", displayEvents); + filterMessageLogName = ConfigSetting.Get("filterMessageLogName", filterMessageLogName); + filterMessageLogFileSize = ConfigSetting.Get("filterMessageLogFileSize", filterMessageLogFileSize); + maximumFilterMessages = ConfigSetting.Get("maximumFilterMessages", maximumFilterMessages); + enableLogTransaction = ConfigSetting.Get("enableLogTransaction", enableLogTransaction); + enableDefaultIVKey = ConfigSetting.Get("enableDefaultIVKey", enableDefaultIVKey); + accountName = ConfigSetting.Get("accountName", accountName); + + outputMessageToConsole = ConfigSetting.Get("outputMessageToConsole", outputMessageToConsole); + enableNotification = ConfigSetting.Get("enableNotification", enableNotification); + eventLevel = (EventLevel)ConfigSetting.Get("eventLevel", (uint)eventLevel); + + string savedMasterPassword = ConfigSetting.Get("masterPassword", ""); + if (savedMasterPassword.Length > 0) + { + masterPassword = Utils.AESEncryptDecryptStr(savedMasterPassword, Utils.EncryptType.Decryption); + } + + includedUsers = ConfigSetting.Get("includedUsers", includedUsers); + excludedUsers = ConfigSetting.Get("excludedUsers", excludedUsers); + + //setting for secure file sharing + protectFolder = ConfigSetting.Get("protectFolder", protectFolder); + protectFolderWhiteList = ConfigSetting.Get("protectFolderWhiteList", protectFolderWhiteList); + protectFolderBlackList = ConfigSetting.Get("protectFolderBlackList", protectFolderBlackList); + drInfoFolder = ConfigSetting.Get("drInfoFolder", drInfoFolder); + shareFolder = ConfigSetting.Get("shareFolder", shareFolder); + dropFolder = ConfigSetting.Get("dropFolder", dropFolder); + shareFolderWhiteList = ConfigSetting.Get("shareFolderWhiteList", shareFolderWhiteList); + shareFolderBlackList = ConfigSetting.Get("shareFolderBlackList", shareFolderBlackList); + storeSharedFileMetaDataInServer = ConfigSetting.Get("storeSharedFileMetaDataInServer", storeSharedFileMetaDataInServer); + shareFileExt = ConfigSetting.Get("shareFileExt", shareFileExt); + + volumeControlFlag = ConfigSetting.Get("volumeControlFlag", volumeControlFlag); + + licenseKey = ConfigSetting.Get("licenseKey", licenseKey); + expireTime = ConfigSetting.Get("expireTime", expireTime); + + } + catch (Exception ex) + { + EventManager.WriteMessage(176, "LoadConfigSetting", EventLevel.Error, "Load config file " + configFileName + " failed with error:" + ex.Message); + } + } + + public static string GetVersionInfo() + { + string version = Assembly.GetExecutingAssembly().GetName().Version.ToString(); + + try + { + string filterDllPath = Path.Combine(GlobalConfig.AssemblyPath, "FilterAPI.Dll"); + version = FileVersionInfo.GetVersionInfo(filterDllPath).ProductVersion; + + string computerId = FilterAPI.GetComputerId().ToString(); + + version =" Version:" + version; + } + catch (Exception ex) + { + EventManager.WriteMessage(43, "LoadFilterAPI Dll", EventLevel.Error, "FilterAPI.dll can't be found." + ex.Message); + } + + return version; + } + + public static void Stop() + { + isRunning = false; + stopEvent.Set(); + EventManager.Stop(); + } + + public static bool SaveConfigSetting() + { + bool ret = true; + + try + { + ConfigSetting.Save(); + } + catch (Exception ex) + { + EventManager.WriteMessage(235, "SaveConfigSetting", EventLevel.Error, "Save config file " + configFileName + " failed with error:" + ex.Message); + ret = false; + } + + return ret; + } + + + static public string ConfigFilePath + { + get { return configFileName; } + set { configFileName = value; } + } + + /// + /// The volume control flag setting + /// + static public uint VolumeControlFlag + { + get { return volumeControlFlag; } + set + { + volumeControlFlag = value; + ConfigSetting.Set("volumeControlFlag", value.ToString()); + } + } + + /// + /// the globalboolean config setting, please reference the enumeration of FilterAPI.BooleanConfig + /// + static public uint BooleanConfig + { + get { return booleanConfig; } + set + { + booleanConfig = value; + ConfigSetting.Set("booleanConfig", value.ToString()); + } + } + + static public bool EnableSendDeniedEvent + { + get { return (booleanConfig & (uint)FilterAPI.BooleanConfig.ENABLE_SEND_DENIED_EVENT) > 0; } + set + { + if (value) + { + booleanConfig |= (uint)FilterAPI.BooleanConfig.ENABLE_SEND_DENIED_EVENT; + } + else + { + booleanConfig &= (~(uint)FilterAPI.BooleanConfig.ENABLE_SEND_DENIED_EVENT); + } + } + } + + /// + /// don't display the directory IO request if it is true. + /// + static public bool DisableDirIO + { + get { return disableDirIO; } + set { disableDirIO = value; } + } + + static public bool IsRunning + { + get { return isRunning; } + } + + static public ManualResetEvent StopEvent + { + get { return stopEvent; } + } + + static public bool[] SelectedDisplayEvents + { + get + { + return selectedDisplayEvents; + } + set + { + selectedDisplayEvents = value; + } + } + + static public EventLevel EventLevel + { + get + { + return eventLevel; + } + set + { + eventLevel = value; + EventManager.Level = value; + ConfigSetting.Set("eventLevel", ((uint)value).ToString()); + } + } + + static public EventOutputType EventOutputType + { + get + { + return eventOutputType; + } + set + { + eventOutputType = value; + } + } + + static public string EventLogFileName + { + get + { + return eventLogFileName; + } + set + { + eventLogFileName = value; + } + } + + static public int MaxEventLogFileSize + { + get + { + return maxEventLogFileSize; + } + set + { + maxEventLogFileSize = value; + } + } + + static public string EventSource + { + get + { + return eventSource; + } + set + { + eventSource = value; + } + } + + + static public string EventLogName + { + get + { + return eventLogName; + } + set + { + eventLogName = value; + } + } + + + public static int FilterConnectionThreads + { + get { return filterConnectionThreads; } + set + { + filterConnectionThreads = value; + ConfigSetting.Set("filterConnectionThreads", value.ToString()); + } + } + + public static uint RequestIORegistration + { + get { return requestIORegistration; } + set + { + requestIORegistration = value; + ConfigSetting.Set("requestIORegistration", value.ToString()); + } + } + + public static uint DisplayEvents + { + get { return displayEvents; } + set + { + displayEvents = value; + ConfigSetting.Set("displayEvents", value.ToString()); + } + } + + public static string FilterMessageLogName + { + get { return filterMessageLogName; } + set + { + filterMessageLogName = value; + ConfigSetting.Set("filterMessageLogName", value.ToString()); + } + } + + public static long FilterMessageLogFileSize + { + get { return filterMessageLogFileSize; } + set + { + filterMessageLogFileSize = value; + ConfigSetting.Set("filterMessageLogFileSize", value.ToString()); + } + } + + public static int MaximumFilterMessages + { + get { return maximumFilterMessages; } + set + { + maximumFilterMessages = value; + ConfigSetting.Set("maximumFilterMessages", value.ToString()); + } + } + + public static bool EnableLogTransaction + { + get { return enableLogTransaction; } + set + { + enableLogTransaction = value; + ConfigSetting.Set("enableLogTransaction", value.ToString()); + } + } + + public static bool OutputMessageToConsole + { + get { return outputMessageToConsole; } + set + { + outputMessageToConsole = value; + ConfigSetting.Set("outputMessageToConsole", value.ToString()); + } + } + + public static bool EnableNotification + { + get { return enableNotification; } + set + { + enableNotification = value; + ConfigSetting.Set("enableNotification", value.ToString()); + } + } + + public static List IncludePidList + { + get { return includePidList; } + set { includePidList = value; } + } + + public static List ExcludePidList + { + get { return excludePidList; } + set { excludePidList = value; } + } + + public static List ProtectPidList + { + get { return protectPidList; } + set { protectPidList = value; } + } + + + public static int ConnectionTimeOut + { + get { return connectionTimeOut; } + set + { + connectionTimeOut = value; + ConfigSetting.Set("connectionTimeOut", value.ToString()); + } + } + + public static bool EnableDefaultIVKey + { + get { return enableDefaultIVKey; } + set + { + enableDefaultIVKey = value; + ConfigSetting.Set("enableDefaultIVKey", value.ToString()); + } + } + + public static string AccountName + { + get { return accountName; } + set + { + accountName = value; + ConfigSetting.Set("accountName", value.ToString()); + } + } + + public static string LicenseKey + { + get + { + //Purchase a license key with the link: http://www.easefilter.com/Order.htm + //Email us to request a trial key: info@easefilter.com //free email is not accepted. + + if (string.IsNullOrEmpty(licenseKey)) + { + System.Windows.Forms.MessageBox.Show("You don't have a valid license key, Please contact support@easefilter.com to get a trial key.", "LicenseKey", + System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error); + } + + + return licenseKey; + } + set + { + licenseKey = value; + ConfigSetting.Set("licenseKey", value.ToString()); + } + } + + public static long ExpireTime + { + get { return expireTime; } + set + { + expireTime = value; + ConfigSetting.Set("expireTime", value.ToString()); + } + } + + public static string MasterPassword + { + get + { + return masterPassword; + } + set + { + masterPassword = value; + string encryptedPassword = Utils.AESEncryptDecryptStr(value.ToString(), Utils.EncryptType.Encryption); + ConfigSetting.Set("masterPassword", encryptedPassword); + } + } + + public static string IncludedUsers + { + get { return includedUsers; } + set + { + includedUsers = value; + ConfigSetting.Set("includedUsers", value.ToString()); + } + } + + public static string ExcludedUsers + { + get { return excludedUsers; } + set + { + excludedUsers = value; + ConfigSetting.Set("excludedUsers", value.ToString()); + } + } + + public static string ProtectFolder + { + get { return protectFolder; } + set + { + protectFolder = value; + ConfigSetting.Set("protectFolder", value.ToString()); + } + } + + public static string ProtectFolderWhiteList + { + get { return protectFolderWhiteList; } + set + { + protectFolderWhiteList = value; + ConfigSetting.Set("protectFolderWhiteList", value.ToString()); + } + } + + public static string ProtectFolderBlackList + { + get { return protectFolderBlackList; } + set + { + protectFolderBlackList = value; + ConfigSetting.Set("protectFolderBlackList", value.ToString()); + } + } + + public static string DRInfoFolder + { + get { return drInfoFolder; } + set + { + drInfoFolder = value; + ConfigSetting.Set("drInfoFolder", value.ToString()); + } + } + + public static string ShareFolder + { + get { return shareFolder; } + set + { + shareFolder = value; + ConfigSetting.Set("shareFolder", value.ToString()); + } + } + + /// + /// The folder to drop the share file which was encrypted. + /// the file will be automatially decrypted + /// + public static string DropFolder + { + get { return dropFolder; } + set + { + dropFolder = value; + ConfigSetting.Set("dropFolder", value.ToString()); + } + } + + public static string ShareFolderWhiteList + { + get { return shareFolderWhiteList; } + set + { + shareFolderWhiteList = value; + ConfigSetting.Set("shareFolderWhiteList", value.ToString()); + } + } + + public static string ShareFolderBlackList + { + get { return shareFolderBlackList; } + set + { + shareFolderBlackList = value; + ConfigSetting.Set("shareFolderBlackList", value.ToString()); + } + } + + public static bool StoreSharedFileMetaDataInServer + { + get { return storeSharedFileMetaDataInServer; } + set + { + storeSharedFileMetaDataInServer = value; + ConfigSetting.Set("storeSharedFileMetaDataInServer", value.ToString()); + } + } + + public static string ShareFileExt + { + get { return shareFileExt; } + set + { + shareFileExt = value; + ConfigSetting.Set("shareFileExt", value.ToString()); + } + } + + public static bool AddFileFilterRule( FileFilterRule newRule) + { + if (filterRules.ContainsKey(newRule.IncludeFileFilterMask)) + { + //the exist filter rule already there,remove it + filterRules.Remove(newRule.IncludeFileFilterMask); + ConfigSetting.RemoveFilterRule(newRule.IncludeFileFilterMask); + } + + filterRules.Add(newRule.IncludeFileFilterMask, newRule); + + ConfigSetting.AddFilterRule(newRule); + + return true; + } + + public static void RemoveFilterRule(string includeFilterMask) + { + if (filterRules.ContainsKey(includeFilterMask)) + { + filterRules.Remove(includeFilterMask); + ConfigSetting.RemoveFilterRule(includeFilterMask); + } + + } + + public static void RemoveAllFilterRules() + { + foreach (FileFilterRule filterRule in filterRules.Values) + { + ConfigSetting.RemoveFilterRule(filterRule.IncludeFileFilterMask); + } + + filterRules.Clear(); + } + + public static bool IsFilterRuleExist(string includeFilterMask) + { + if (filterRules.ContainsKey(includeFilterMask)) + { + return true; + } + + return false; + } + + public static Dictionary FilterRules + { + get { return filterRules; } + } + + public static bool AddProcessFilterRule(ProcessFilterRule filterRule) + { + string key = filterRule.ProcessNameFilterMask; + + if (key.Trim().Length == 0) + { + key = filterRule.ProcessId; + } + + if (processFilterRules.ContainsKey(key)) + { + processFilterRules.Remove(key); + ConfigSetting.RemoveProcessFilterRule(filterRule); + } + + processFilterRules.Add(key, filterRule); + ConfigSetting.AddProcessFilterRule(filterRule); + + return true; + } + + public static void RemoveProcessFilterRule(ProcessFilterRule filterRule) + { + string key = filterRule.ProcessNameFilterMask; + + if (key.Trim().Length == 0) + { + key = filterRule.ProcessId; + } + + if (processFilterRules.ContainsKey(key)) + { + processFilterRules.Remove(key); + ConfigSetting.RemoveProcessFilterRule(filterRule); + } + } + + public static void ClearProcessFilterRule() + { + string[] filterKeys = new string[processFilterRules.Count]; + processFilterRules.Keys.CopyTo( filterKeys,0); + + foreach(string key in filterKeys) + { + ProcessFilterRule processFilterRule = processFilterRules[key]; + processFilterRules.Remove(key); + ConfigSetting.RemoveProcessFilterRule(processFilterRule); + } + } + + public static ProcessFilterRule GetProcessFilterRule(string processId, string processNameFilterMask) + { + string key = processNameFilterMask; + + if (key.Trim().Length == 0) + { + key = processId; + } + + if (processFilterRules.ContainsKey(key)) + { + return processFilterRules[key]; + } + + return null; + } + + public static Dictionary ProcessFilterRules + { + get { return processFilterRules; } + } + + public static bool AddRegistryFilterRule(RegistryFilterRule filterRule) + { + string key = filterRule.ProcessNameFilterMask; + + if (key.Trim().Length == 0) + { + key = filterRule.ProcessId; + } + + if (registryFilterRules.ContainsKey(key)) + { + registryFilterRules.Remove(key); + ConfigSetting.RemoveRegistryFilterRule(filterRule.ProcessId, filterRule.ProcessNameFilterMask); + } + + registryFilterRules.Add(key, filterRule); + ConfigSetting.AddRegistryFilterRule(filterRule); + + return true; + } + + public static void RemoveRegistryFilterRule(RegistryFilterRule filterRule) + { + string key = filterRule.ProcessNameFilterMask; + + if (key.Trim().Length == 0) + { + key = filterRule.ProcessId; + } + + if (registryFilterRules.ContainsKey(key)) + { + registryFilterRules.Remove(key); + ConfigSetting.RemoveRegistryFilterRule(filterRule.ProcessId, filterRule.ProcessNameFilterMask); + } + } + + public static RegistryFilterRule GetRegistryFilterRule(string processId, string processNameFilterMask) + { + string key = processNameFilterMask; + + if (key.Trim().Length == 0) + { + key = processId; + } + + if (registryFilterRules.ContainsKey(key)) + { + return registryFilterRules[key]; + } + + return null; + } + + public static Dictionary RegistryFilterRules + { + get { return registryFilterRules; } + } + } +} diff --git a/Demo_Source_Code/CSharpDemo/CommonObjects/InputForm.Designer.cs b/Demo_Source_Code/CSharpDemo/CommonObjects/InputForm.Designer.cs new file mode 100644 index 0000000..f3d96c6 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/CommonObjects/InputForm.Designer.cs @@ -0,0 +1,107 @@ +namespace EaseFilter.CommonObjects +{ + partial class InputForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(InputForm)); + this.label_InputPrompt = new System.Windows.Forms.Label(); + this.textBox_Input = new System.Windows.Forms.TextBox(); + this.button_Ok = new System.Windows.Forms.Button(); + this.openFileDialog1 = new System.Windows.Forms.OpenFileDialog(); + this.button_GetFilePath = new System.Windows.Forms.Button(); + this.SuspendLayout(); + // + // label_InputPrompt + // + this.label_InputPrompt.AutoSize = true; + this.label_InputPrompt.Location = new System.Drawing.Point(20, 8); + this.label_InputPrompt.Name = "label_InputPrompt"; + this.label_InputPrompt.Size = new System.Drawing.Size(117, 13); + this.label_InputPrompt.TabIndex = 0; + this.label_InputPrompt.Text = "Input the new file name"; + // + // textBox_Input + // + this.textBox_Input.Location = new System.Drawing.Point(23, 33); + this.textBox_Input.Name = "textBox_Input"; + this.textBox_Input.ScrollBars = System.Windows.Forms.ScrollBars.Horizontal; + this.textBox_Input.Size = new System.Drawing.Size(446, 20); + this.textBox_Input.TabIndex = 1; + // + // button_Ok + // + this.button_Ok.DialogResult = System.Windows.Forms.DialogResult.OK; + this.button_Ok.Location = new System.Drawing.Point(394, 59); + this.button_Ok.Name = "button_Ok"; + this.button_Ok.Size = new System.Drawing.Size(75, 20); + this.button_Ok.TabIndex = 2; + this.button_Ok.Text = "Ok"; + this.button_Ok.UseVisualStyleBackColor = true; + this.button_Ok.Click += new System.EventHandler(this.button_Ok_Click); + // + // openFileDialog1 + // + this.openFileDialog1.FileName = "openFileDialog1"; + // + // button_GetFilePath + // + this.button_GetFilePath.Location = new System.Drawing.Point(475, 33); + this.button_GetFilePath.Name = "button_GetFilePath"; + this.button_GetFilePath.Size = new System.Drawing.Size(27, 20); + this.button_GetFilePath.TabIndex = 3; + this.button_GetFilePath.Text = "..."; + this.button_GetFilePath.UseVisualStyleBackColor = true; + this.button_GetFilePath.Click += new System.EventHandler(this.button_GetFilePath_Click); + // + // InputForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(514, 91); + this.Controls.Add(this.button_GetFilePath); + this.Controls.Add(this.button_Ok); + this.Controls.Add(this.textBox_Input); + this.Controls.Add(this.label_InputPrompt); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Name = "InputForm"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "Rename"; + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Label label_InputPrompt; + private System.Windows.Forms.TextBox textBox_Input; + private System.Windows.Forms.Button button_Ok; + private System.Windows.Forms.OpenFileDialog openFileDialog1; + private System.Windows.Forms.Button button_GetFilePath; + } +} \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/CommonObjects/InputForm.cs b/Demo_Source_Code/CSharpDemo/CommonObjects/InputForm.cs new file mode 100644 index 0000000..3c1296b --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/CommonObjects/InputForm.cs @@ -0,0 +1,53 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; + +namespace EaseFilter.CommonObjects +{ + public partial class InputForm : Form + { + public string InputText = string.Empty; + + public InputForm(string caption, string promptText,string inputText) + { + InitializeComponent(); + this.Text = caption; + label_InputPrompt.Text = promptText; + textBox_Input.Text = inputText; + } + + private void button_Ok_Click(object sender, EventArgs e) + { + InputText = textBox_Input.Text; + } + + private void button_GetFilePath_Click(object sender, EventArgs e) + { + if (openFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + textBox_Input.Text = openFileDialog1.FileName; + } + } + } +} diff --git a/Demo_Source_Code/CSharpDemo/CommonObjects/InputForm.resx b/Demo_Source_Code/CSharpDemo/CommonObjects/InputForm.resx new file mode 100644 index 0000000..6b70ea8 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/CommonObjects/InputForm.resx @@ -0,0 +1,573 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + + + + AAABAAgAEBAAAAEACABoBQAAhgAAABAQAAABACAAaAQAAO4FAAAYGAAAAQAIAMgGAABWCgAAGBgAAAEA + IACICQAAHhEAACAgAAABAAgAqAgAAKYaAAAgIAAAAQAgAKgQAABOIwAAMDAAAAEACACoDgAA9jMAADAw + AAABACAAqCUAAJ5CAAAoAAAAEAAAACAAAAABAAgAAAAAAEABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP// + /wAAzf8AmXtrAImb/gDdu6kAOljoAGP4/wDH0f0App6/AEme/wD14tkAocD+ANTG0AA87P8AfpjYAE5x + /wCrnpgA4+j/AGaN/wC1r9cAHeX/ALCOfQBfs/8AOoL/AMCoowD69OkAbeL/AE1m4wBbmvEAlpPIANvE + vAC1t8QAptH/AKadqQDx8vsA4c/KAKeCcABX7f8AV2fuAKez/wBdm/8AYOH/APz59ACtvf4Ag5H+APjt + 2gBDe/8A8OjgALKbnwDbv7MAnpfDAFSX/wCph3gA9/j/AEua+ABar/oA+vHiANvHwwCdf28A18zPAJt3 + ZgDcuqMA+vj6APz27gDcvq4Aon9vAP37+ACXeWcA28G3APT1+wBb7f8Aps3/AJx9bADewbQA+fTuAPry + 5gDevqsA3sS6AKuJegDauKUArIh3ANq6qAD39vsAmXtoAPnv4AD79ewA27ytANzCtQD9+vYA/PfwAK+O + fwDcuaUA3LunANu6qgDcv7EA28K5ANvFvgDbxsEA+vHkAN6+rQCafGoAnX5tAKOAcAD79eoA272vAJh5 + aACZemoAm3xrAJx8bQD79OgA+vPoALGOfgDcvKkA2ruqANvAtADbw7oA/fv5AJp8awCbfGwA/PnzAJx9 + bQCcfm0A/PbtAPrz5wD68+YA3LqlANy7qQDbuqkA3cK1ANu/sgDbv7QA28fCANvCuADbw7sAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAGxmenp6eUlsbGVUbAAAAAA9ARoaGm98TGNVLkQAAAAAQgGBgVhfQX9+Pjlq + AAAAAGcBhnSFMmlyUFx9awAAAAA1AYRiH0WCV1JdbgMAAAAATwE6hGFgc2mAcWh2AAAAAFs2DTwkYINp + XgVWbAAAAAAiKC0hCFNDWXhae3cAAAAADzQ4NycUTkpkTUBtAAAAAAYqFUcXDEZDK0swOwAAAAAdJgIO + GAQjdSUlJSUAAAAAHAoHGy8sP3UlC3ARAAAAAB4TKRBIEgEBJXARAAAAAAAZIDMJMRZRUSURAAAAAAAA + AAAAAAAAAAAAAAAAAAD//wAAwAMAAMADAADAAwAAwAMAAMADAADAAwAAwAMAAMADAADAAwAAwAMAAMAD + AADAAwAAwAcAAMAPAAD//wAAKAAAABAAAAAgAAAAAQAgAAAAAABABAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAJt8a/+dfm3/nH5t/5x+bf+cfm3/nH1t/5x9bP+bfGv/m3xr/5p8av+Ze2j/m3xr/wAA + AAAAAAAAAAAAAAAAAACbd2b///////r06f/69On/+vTp//rz6P/68+f/+vLm//rx5P/57+D/+O3a/5d5 + Z/8AAAAAAAAAAAAAAAAAAAAAon9v///////dwrX/3cK1/9zCtf/cv7H/3L6u/9y7qf/cuqX/3Lqj//rx + 4v+YeWj/AAAAAAAAAAAAAAAAAAAAAKOAcP//////28O7/9vDuv/bwrj/27+z/9u9r//au6r/2ril/9y5 + pf/68+b/mXpq/wAAAAAAAAAAAAAAAAAAAACph3j//////9vHwv/bxsH/28S8/9vBt//bv7L/27yt/9q6 + qP/cu6f/+/To/5l7a/8AAAAAAAAAAAAAAAAAAAAAq4l6///////bx8P/28fC/9vFvv/bwrn/28C0/9u9 + r//buqn/3Lyp//v16v+afGv/AAAAAAAAAAAAAAAAAAAAAK+Of//3+P//1MbQ/9fMz//hz8r/28K5/9u/ + tP/bva//27qq/927qf/79ez/m3xr/wAAAAAAAAAAAAAAAAAA/wGmnan/p7P//4OR/v+m0f//x9H9//f2 + +//9+/j//fr2//z58//89/D//Pbt/5t8bP8AAAAAAAAAAAAAAAAAKf8XfpjY/1SX//9ar/r/S5r4/1dn + 7v+1r9f/3sS6/97BtP/evq3/3r6r//z27v+cfG3/AAAAAAAAAAAAAAAAACz/NzpY6P9g4f//HeX//1vt + //9fs///ocD+//T1+//9+/j//Pn0//n07v/w6OD/n4Bw/gAAAAAAAAAAAAAAAAAu/0FbmvH/V+3//wDN + //887P//OoL//4mb/v/x8vv//fv5/6eCcP+ngnD/p4Jw/6eCcP8AAAAAAAAAAAAAAAA3fv8zTWbj/0me + //9j+P//beL//0N7//+tvf7/+vj6//37+f+ngnD/9eLZ/7GOfv+ngnBYAAAAAAAAAAAAAAAAABf/CJaT + yP9mjf//XZv//05x//+mzf//4+j/////////////p4Jw/7GOfv+ngnBYAAAAAAAAAAAAAAAAAAAAAAAA + AADAqKP/tbfE/56Xw/+mnr//spuf/7COff+siHf/rIh3/6eCcP+ngnBYAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAD//wAAwAMAAMADAADAAwAAwAMAAMADAADAAwAAwAMAAMADAADAAwAAwAMAAMADAADAAwAAwAcAAMAP + AAD//wAAKAAAABgAAAAwAAAAAQAIAAAAAACgAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8AKF31AKJ6 + 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 + ///9+/n/3MjD/9zIxP/cx8L/28W//9vEvf/bwbn/28C2/9u/sv/bva//27ur/9u5p//evar/+/bt//zz + 5/+Uc2D/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAApYRz//j5///p7Pv/xLbJ/8S5yf/Pwcb/2sO//9zE + vP/bwrn/28G1/9u+s//bva//27ur/9u5qP/evar//ffu//716P+Wc2L/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAP8BmH2C/8bR//+wv/7/mKDq/6PK8P+qr+f/wsLj/+LY3f/t39n/7N7X/+zd1f/s29L/7NrP/+vZ + zf/t2cz//Pfv//306f+Vc2H/AAAAAAAAAAAAAAAAAAAAAAAAAAAANf8di56x/4GR//9OdP//P17//37M + //9edv//mKz+/8bR/f/z9Pv//vz6//37+P/9+vb//fn0//z48v/8+PH//Pjw//326/+XdGP/AAAAAAAA + AAAAAAAAAAAAAAAx/wsALf8/WG3G/33U//88hv//UaT6/2PY/f8ravb/PV/w/4iO3P+5rc3/3sa+/9/F + uv/fw7b/38Cy/9+/rv/gwa///fjw//326/+WdGP/AAAAAAAAAAAAAAAAAAAAAAAx/x8AMP9dLEbc/0Oc + //9g6v//VOz//0fd/v9gwPv/KF31/2WK6/+lrtP/07u7/9zAtP/bvbD/3Lys/9y5qf/fvqv//fry//31 + 7P+YdWP/AAAAAAAAAAAAAAAAAAAAAAAz/y0AMf94JVXl/2vO//8s2///AMr//wTQ//9X6P//c9///12V + //+ruP//6ez8///9+//6+PX/9vLt//Ps5//s5N//4dbQ/8m1qf+NaFftAAAAAAAAAAAAAAAAAAAAAAAs + /y8AJv97QYDr/1TW//8o3f//AMr//wLP//9u7P//PY///0Ro//+puv//6Oz8/////v/Ktar/nHpp/6qL + eP+ohGr/onpc/4ZgT/OQZ1ZBAAAAAAAAAAAAAAAAAAAAACBb/ytkt/+NUYzp/0SW//909f//Ld///z7j + //9Qxv//LWz//1d4//+2xP7/8PH7/////f/Vx77/zLWj//zpxf/wzJL/m3Rc85ZpXDoAAAAAAAAAAAAA + AAAAAAAAAAAAAAAv/xAALP9GR1HI/0SC//9Mof//Ucr//2PC//9oyf//WJT//4uf/v/L1f3//Pr6///+ + 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 + AA/gAAAfwAAAP+AAAH/wAAD/8AAB//AAA//wAAf/8AAP//////8oAAAAIAAAAEAAAAABACAAAAAAAIAQ + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAhGFQ/4ZhUP+EYE//hGBP/4Rg + T/+EYE//hGBP/4NgT/+DYE//g2BP/4NfTv+CX07/gl9O/4FfTv+BXk3/gF5N/4BdTv9/XUz/f11N/35c + S/9+XEz/fVtL/35dTf97W0v/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACFYVD/+OTT//Le + zP/y3sz/8t7M//LezP/y3sz/8t7M//LezP/y38z/8t3M//Ldy//y3cv/8t7K//Lcyv/y3Mf/89vH//Ha + xP/x2cL/8tjA//DXvv/x1r3/9dm9/3xbS/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIZh + UP///fL/+vTo//rz6f/68+n/+vPp//rz6f/68+n/+vPo//r06P/68uj/+vLn//ry5//68+b/+vHm//ry + 5f/68uT/+fHi//nw4P/5797/+Ozb//nt2f/03MT/e1pJ/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAhmFQ///+9f/79ur/+/Xs//v16//79ev/+/Xr//v17P/79er/+/bq//v06//79On/+/Tq//v1 + 6P/78+n/+/Pn//z05v/68uX/+vHl//nw4f/57+D/+vDe//Texv99W0r/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACHY1H///73//v17P/89uz/3sS3/97Ft//exbf/3sS3/93Dtf/dw7X/3cKz/93B + sv/dwbD/3b+u/92+q//dvar/3byo/926pf/duqX/376p//rx4v/68OH/89/J/3xbSv8AAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAIhiUf////f//Pbt//z27v/bwLT/28C0/9vAtP/bwLT/28Cz/9u/ + sv/bvrH/272u/9q7rP/auqr/2rmo/9q3pf/atqL/2rWg/9q1oP/duqT/+vLl//vz5P/14Mz/fVxL/wAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAiWNS////+v/89+///Pfv/9vCuP/bwrj/28K4/9vC + t//bwrb/28C1/9u/sv/bvrH/272v/9u8rP/auqr/2rmm/9q3pP/atqH/2rah/927pf/78+b/+/Tn//Ti + zv9+W0z/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACKZFP////6//z48P/8+PH/28O7/9vE + u//bxLv/28O7/9vDuf/bwrj/28C2/9u/s//bvrH/272u/9u8rP/auaj/2ril/9q3o//at6P/3bun//vz + 5//89ej/9uPS/4BdS/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAItlU/////v//Pjy//z4 + 8v/bxr7/28a//9vGv//bxL7/28S8/9vDuv/bwbf/28C1/9u+s//bva//27ys/9u7qv/buqj/2rek/9q3 + pP/dvaj/+/To//z06f/15NP/f1xN/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjGdU//// + /v/9+fP//fn0/9vHwv/bx8P/28fD/9vGwv/bxb//28S8/9vDuv/bwbf/27+z/9u+sf/bvK//27ur/9u6 + qP/buKX/27il/929qv/79On//Pbq//Xk0v+AXkz/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACPZlX///////369f/9+vX/28jD/9vIxP/byMT/28jC/9vGwP/bxL3/28O6/9vCuP/bwLX/276y/9u9 + r//bu6z/27qp/9u5p//buaf/3r6q//v16v/89ev/9eTT/4JdTP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAI9nVP///////fr2//379//bx8P/28fE/9vHxP/bx8P/28bA/9vFvv/bxLv/28K4/9vA + tf/bv7P/272v/9u8rP/buqr/27im/9u4pv/evqv/+/Xr//z17P/15NT/gV9O/wAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAkWhV///////9+/j//fv4/9zHwv/bxsP/28bD/9vGwf/bxcD/28S9/9vD + u//bwbn/28C1/9u/sv/bvrD/27yt/9u6qv/buKf/27in/969q//79ez//Pft//Xl1v+DXk3/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACSaVf///////78+f/+/Pr/2sTA/9rEwP/cxsD/3MbA/9zF + v//cxL3/28O6/9vCt//bwLX/276y/9u9r//bvK3/27qq/9u5p//buaf/3r2r//z27f/89u3/9eXV/4Ng + Tf8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJNqVv/4+f//6Ov7/9rh/P+4r8r/uK3K/7/B + zv/Ht8T/1b/A/9zEu//cw7r/28G3/9vAtP/bvrL/272v/9u8rf/bu6r/27mn/9u5p//evar//Pbt//z2 + 7v/15df/hF9P/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8BiGhk/9Ha//++yf3/ssH+/6u7 + /v+qs/7/vvP+/73F/v/O1/3/5+v7//37+//+/Pr//fv5//379//9+vb//fr1//359P/8+PL//Pjx//z3 + 7//89u7//fjv//fm1v+EX07/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACh4/yB7c4r/rbf//4ue + /v9phP//V3H//1l9//+a4///iJX+/6q6/v/Dzv3/4eb8//37+//+/Pn//fv4//379//9+vb//fn0//35 + 8//8+PH//Pfw//z37//99+//9ubY/4VhTv8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANv8RACT/OIms + t/98q///P1f//0WD//8qVPb/Yrj6/1+m+f81TvL/Wm/q/46T3P+rptL/zbzH/9/Hvf/fxbv/38O4/9/B + tP/fwLH/37+s/9+/rP/hwrD//Pfv//338P/25tj/hWBQ/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AwA1 + /ysAMP9QQj63/5z7//9SpP//RZf//1ix+v9j8P7/O4v4/zR69v8wVvP/Wm3n/5SV1f+zqMj/2L+6/9zA + tf/bvrL/272v/9u6qv/buaf/27mn/96+q//89+///ffw//bm1/+GYE//AAAAAAAAAAAAAAAAAAAAAAAA + AAAAQv8PADb/PAAw/2wnPNX/K2f//2b///995///ZfT//0jt//9w1/z/bcn7/ylS9P81SfD/d3vd/6eo + z//Mtr7/3MC1/9u+sv/bva//27qq/9u5p//buaf/3r6r//348f/9+PH/9+fZ/4ZhUP8AAAAAAAAAAAAA + AAAAAAAAAAAAAAA2/xsAM/9HAC7/iiNQ3v9XrP//etT//yjg//8Azv//As///1bw//9bxf//Zdv//6D9 + //+V2P//s8n+/9/l/P/+/Pr///35//79+f///fn///33//779//9+PP/+fXt//Xw6P/p1sj/h2JQ/AAA + AAAAAAAAAAAAAAAAAAAAAAAAADX/IQAy/0wALv+aHz/e/zyP//9h6///AM7//wDL//8Ayv//DdT//0ri + //9Mqv//MVz//1tv//+uvP7/2eD8//78+v///fv/5tzX/9nLwv/g08z/2szF/9XFvv/Itq3/u6Sa/5d1 + Zf+GYlG2AAAAAAAAAAAAAAAAAAAAAAAAAAAAMv8gACb/TAAY/5k9euf/XN7//0jw//8K0v//AMv//wDK + //8Z2P//gf3//0+o//8yY///XXv//66//v/Z4Pz//vz6//////+7opX/oYBy/6eJeP+lg2//o39n/7CI + Zv+TbFT/imRTxIZfSw4AAAAAAAAAAAAAAAAAAAAAAAAAAABD/xllvP9qiun/vHTA7v9Uqf//bMX//0Ps + //8Q1P//FdX//z/q//9Nq///NIf//zRl//9xi///tcP+/+Ln/P/+/Pr//////8u3rf/FrZ////Xg//nh + u//41pz/xZ5u/4ljU8GMXV8MAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC//DAAm/zkAH/9lLTfQ/zBd + //+L7v//c8z//0rl//9/////Xcf//4D///8uZP//Q2P//5Oo/v/Czv3/7/L7//78+v////z/zLqw/76h + i//237j/88+W/8CYav+IYlTPi2RODgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8BADP/JgAw + /0pNUK7/QGv//zBa//9Yvv//VcD//3XP//8pav//WKT//5Tq//92gv//sL7+/9Xd/P/8+vr//vz5///+ + /P/XycH/so1y//bTmv/In27/iWRVzJ1uXhIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAOv8LADf/MmtdkP9/lv//Sl7+/4/o//88dP//M2r//zZn//9HX///hbD//7Xi/v/J0f3/8PD7//78 + +v/9+/j////7/9PCuf+3kGr/y6Fv/4tkVM2VYlIRAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAOv8QfWR7/7bE//+bpP3/q/b+/2x5/v9shf7/fZX+/5ms/v+yvf3/ydn9/+rt + +//+/Pr//fv5//379////vv/zrqx/6J5Wv+PaVbWnXFZGQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACVb2T/2uL//8jQ///B7f//tb7//7XD//+7yP//xtL//9jf + ///y9P////////////////////////////+zl4n/j2dV1KFtYhcAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJpxXf+ccmD/lHBm/5B0cf+IanD/h2px/4pr + a/+QbWT/l25b/5dtW/+Wbln/lWxa/5RrWf+Talj/k2xZ/45nVbmTblUWAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/////wAAAP8AAAD/AAAA/wAAAP8AAAD/AA + AA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/gAAAP4AAAD+AA + AA/gAAAP4AAAH8AAAD/gAAB/8AAA//AAAf/wAAP/8AAH//AAD///////KAAAADAAAABgAAAAAQAIAAAA + AACACgAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8AMFz/ALCIZgBm7/8AqKXUAADL/wD41pwAZlyPAHaC + /wCt3/0AellJAEI+twDn3tgAvaSZAFCv/gBzg8kAVm7WAHq46ACbpP0AIETcADHe/wDbwbYAg2V1AIms + twAsg/8AltnhAN/l/ADNomwAt7vvAJX6/wBScv4Av8HOAPnhuwCNktwA/fLeAGHH/QCTbFQARun/AID+ + /wAvaeQAeq39AImRmwBw1f8AydP+AI7E3QBnec8A2rWfAISV+ACa4/8AR1//ADVJ8ABETLQARlTeALKW + igBwf+QAyretABPS/wCWem0ALTfQAFZ76wB76f8ApX5dAPDy/QA3d/8AX6b5AFKV9QCoinsA+OTTAF3i + /wC+8/4A3c7GALmwzwAfV+EAKnH+AESG+wDMtr4AZMP7AHpgeQD79/IA6dXFAKv2/gCE8P8Ap7P3AGW4 + /wBm//8AhmFPACdT7gDDmGcAxKWJAJBtZAClf2cAxK6gAN++qQDqz7sAwcn4AGx5/gAyev0ANmb+APbw + 5wCyjXIAVun/ANPb/QD14sMASeX/AFuw/QBYgP4Ak87+AEBf4QCacV0A1MHDAGeD/gAL0f8A8+reAD9X + /wAzkv8AoYByALTQ/gB8k/wAz8DJAIHX/QDmzLoA8MqNAN/QygBylP8Ahbz/AOjo9wC4j2UAccz7AEBo + /wBm2f8Ah6D/AIhoXQCbdWUAWJ3/AJaX1wCQdHEAJ0HUAPn5/QCU6v8Alaj8ALOoyACLZVQA+vHrAP78 + +ADmyLIAzbqxADRc8gA7i/gAq7r8AMva/QDTwrkAyLjGACxl+gBVwP8AgV1MANu5pwDbva4A9+3jAKCv + +QBZr/8AkXNnAMGceADL6v4A+ufJAMTN+wDZ4f4A28W/AP37+QBI7/8AaXXNAJZtWQBSpP8A4Ma3ALXE + /gDx2cIApYNxANLa/gDcyr8A8ufbAO7ezwBtyfsAQWL9AIppbABd6f8ABM//ADlV7AD19fsAlm5iAI/o + /wDVxb4AuJ+TAKCd0wD58+0A28O7ABDS/wDcyMMA2L+6AK+//wD//vsAH9j/APXZvQD02rAA0NT1AJFo + VQCUc2UAafP/AN/EtACtt/8A/Pn1AD3j/wBbb/8Aof//AFx7/gCEX00A9ezfADFp/wCPeW4A27urAFSp + /wC7xPsANWD/APrw6ADz050A3rylAODArgB/W0sAiWNSAJxyYADa4fwAxdD/ALvH/gAoZvsAjXBjAOru + /QDj5vkAWm3nAE+o/wDbuKQAW7r/ANu/sgB30P8AssH+AJNqVwD89uwASl7+APDk1gDz38oA89zHANng + /wBqh/8A//3yAMifbgDv4tMA37+sAN28qAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + 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 + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAhWFQ/4RhUf+DYE//g19P/4Nf + T/+DX0//g19P/4NfT/+CX0//gl9P/4JfT/+CYE//gl5O/4JeTv+CXk7/gV5O/4FeTv+BXk7/gV9O/4Bd + Tf+AXU3/gF1N/39eTf9/XE3/f1xM/35cTP9+XUz/fltM/31bS/99XEv/fFpK/3xbSv97W0r/e1tL/3tb + S/97W0z/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgFxL/+7R + u//rzrn/6s25/+rNuf/qzbn/6s25/+rNuv/qzbr/6s26/+rNuf/qzbn/6s25/+rNuf/qzrn/6865/+nO + uP/pzbj/6c24/+nNt//qzbf/6s23/+rMt//qzLb/6cy2/+nLtf/py7T/6cu0/+nLs//oy7P/6Mqz/+jK + sv/oyrH/58mx/+vLsv92Vkj/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAf1xL/+rUwv/m0L//5tC//+bQv//n0L//59C//+fQwP/n0MD/59DA/+fQv//m0L//5tC//+bQ + v//m0L//5tC//+bQvv/mz77/5s++/+bPvf/mz73/5c+9/+XPvP/lzrz/5c67/+XOu//lzbr/5M26/+TN + uf/kzLn/5My4/+TMt//ky7f/5My3/+XIsP93VUb/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAgFpJ//Dez//s2sv/7NrM/+zazP/s28z/7NvM/+zbzP/s28z/7NvM/+zb + zP/s2sz/7NrM/+zay//s2sv/69rL/+vay//r2sr/69nK/+vZyv/r2cn/69nJ/+vYyP/q2Mj/6tjH/+rX + x//q18b/6tfG/+nWxf/p1sT/6dbE/+nVw//o1sP/5tC8/+bJsf92V0f/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgVxK//Tl2P/z6d3/8uje//Lo3v/y6N7/8ujd//Lo + 3f/y6N3/8ujd//Lo3f/y6N7/8uje//Lo3v/y6Nz/8ujd//Lp3f/y59z/8ufc//Pn3P/x6Nv/8ebb//Hm + 2v/x59r/8uXZ//Dl2P/w5tj/8OTX//Hl1f/v49b/7+PV//Dk1P/t3s3/59C8/+XIsf94Vkf/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgltK//Xn2v/38Oj/9u/n//bx + 5v/28ej/38e4/9/Huf/fx7n/38e4/9/HuP/fxrj/38a4/9/Gt//fxbf/38S1/9/EtP/fxLP/38O0/9/D + sf/fw7H/38Gu/9/Arv/fwK3/38Cr/96+q//ev6n/3r2m/967pf/hxKv/8+re//Tr3v/t4ND/5tC9/+XK + s/95WEf/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAglxL//Tm + 2v/38ej/9/Do//fw6P/38Oj/2r6x/9q+sf/avrH/2r6x/9q+sP/avrD/2r6w/9q9r//ava7/2r2t/9q8 + rf/avKz/2rqr/9q6qf/auaj/2rmm/9q4pP/at6P/2rei/9q2oP/atp//2bSd/9mzm//evKX/9Ove//Pr + 3v/t39D/5tG+/+fJsv95V0j/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAg15L//Tn2//48un/9/Hp//fx6f/38en/28Cz/9vAs//bwLP/28Cz/9vAs//bwLL/27+y/9u/ + sf/avrD/2r2v/9q9rv/avK3/2ryr/9q7q//auqr/2rmn/9q4pv/auKT/2rej/9q3ov/atqD/2rWe/9m0 + nf/evab/9Ovf//Xs3//v4dL/5tG//+bLs/96V0j/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAhF1K//bo3P/48uz/+PLq//jy6v/48ur/28G1/9vBtv/bwbb/28G1/9vB + tf/bwLX/28C0/9vAs//bv7P/27+x/9u+sP/bvq//2ryt/9q7q//au6r/2rqp/9q5qP/auKb/2rek/9q3 + ov/atqL/2raf/9q1nf/fvqj/9Ozg//Ts4P/u4NH/59LA/+bKtP96WUj/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAhV9M//Xq3//48+z/+PPr//jz7P/48+z/28K3/9vC + uP/bw7j/28K4/9vCt//bwrb/28K1/9vAtP/bwLT/27+z/9u/sf/bvrD/272u/9u9rf/au6z/2ruq/9q6 + qf/auaf/2rim/9q3pP/atqL/2rah/9q1n//fvqn/9ezh//Tt4f/u4tL/59LA/+bMtv97WEn/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAh15L//fp3//59O3/+PPt//nz + 7f/59O3/28O6/9vDuv/bw7r/28O6/9vDuf/bw7j/28K3/9vCt//bwLb/28C0/9u/sv/bvrH/276w/9u9 + r//bvK3/27yr/9q6qv/auqj/2rmm/9q4pf/at6P/2rah/9q1oP/fvqn/9e3i//bt4v/w4dP/59PB/+jL + tf97Wkj/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAhmBN//bq + 4P/59e7/+fTu//n07v/59O7/28S7/9vEvP/bxLz/28S8/9vEu//bw7r/28O6/9vCuf/bwrf/28C2/9u/ + tP/bv7P/276x/9u9r//bva7/27yt/9u8q//bu6n/2rmn/9q5pv/auKT/2rai/9q2oP/fv6r/9e3j//Xu + 4//v49X/6NPC/+fLtv98WUj/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAhmBN//br4f/69fH/+fXv//n17//59fD/28S+/9vFvv/bxb7/28W+/9vEvf/bxLz/28O7/9vD + uf/bwrj/28G3/9vBtv/bv7T/276y/9u+sf/bva7/27yt/9u8rP/bu6v/27qo/9q5p//auKX/2rej/9q2 + ov/fv6v/9e7k//Xu5P/v4tT/6NPC/+fLuP98WUj/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAh19M//fs4v/69vH/+vbw//r28f/69vH/28bA/9vGwP/bxsH/28bA/9vG + v//bxb7/28W8/9vDu//bwrr/28K4/9vBtv/bwLX/28Cz/9u+sv/bvbD/272u/9u8rP/bu6v/27up/9u6 + p//auKb/2rik/9q3ov/fv6z/9u7k//Xv5f/v5NX/6NTD/+fNt/98WUr/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAiGFO//fs4//69/L/+vby//r28v/69/L/28bC/9vH + w//bx8P/28fC/9vGwf/bxsD/28W+/9vEvf/bxLv/28O6/9vBt//bwLb/28C0/9u/sv/bvrH/272v/9u8 + rf/bu6v/27uq/9u6qP/buaf/2rik/9q3o//fwKz/9u/l//fv5f/x49b/6NTE/+fMuf99W0n/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAiWBN//jt5P/7+PP//Pfz//v3 + 8//79/P/28jC/9vIxP/bycT/28jD/9vIwv/bx8H/28a+/9vFvf/bxLv/28O6/9vCuf/bwrf/28G1/9u/ + s//bvrH/276w/9u8rv/bu6z/27ur/9u6qP/buaf/27ml/9q3o//fwKz/9u/m//bw5v/w49j/6dTE/+fO + uv99Wkn/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAi2FP//ju + 5f/7+PT/+/j0//v49P/7+PX/28jD/9vIxP/bycX/28jE/9vHw//bx8H/28a//9vFvv/bxbz/28S6/9vC + uf/bwrf/28G2/9vAtP/bvrL/276w/9u9rv/bvK3/27ur/9u6qf/buaj/27ml/9u4o//fwK3/9/Dn//bw + 5//w5df/6dXF/+jNuf9+Wkn/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAimNO//ju6P/8+ff/+/n1//v59v/8+fb/28fE/9vIxP/byMX/28jE/9vHw//bxsL/28bA/9vF + vv/bxb3/28S7/9vCuf/bwbj/28G2/9vAtP/bv7P/276w/9u9r//bvK3/27ys/9u6qf/buaj/27mm/9u4 + pP/gwK3/9/Do//bx6P/w5Nj/6dXG/+jNuf9+Wkv/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAi2JQ//nv6P/8+vf//Pn2//z69//8+vf/28fC/9vHw//bx8P/28fD/9vH + wv/bxsH/28bA/9vFvv/bxL3/28S7/9vCuv/bwbj/28C2/9vAtP/bv7P/27+x/9u+r//bvK7/27ur/9u7 + qv/buaj/27im/9u4pf/gwK7/9/Ho//jx6P/y5Nr/6dXG/+jPu/9/XEr/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjGRP//nw6f/8+/j//Pr4//z6+P/8+/j/3MfC/9zH + w//cyMP/3MfD/9zHwv/cx8H/3MbA/9vEvv/bxL3/28O7/9vDuv/bwbj/28C3/9vAtf/bv7L/276x/9u+ + sP/bva3/27us/9u7q//buaj/27im/9u4pf/gwK//9/Hp//fx6f/x5Nn/6dbH/+jOuv9/W0r/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjmNR//nx6v/9+/n//vv5//37 + +f/9+/r/3MbB/9zHwf/cx8H/3MfB/9zGwf/cxsD/3Ma//9zFvv/cxb3/28O7/9vCuv/bwrj/28G2/9u/ + tf/bv7P/276x/9u9r//bva7/27ys/9u7qv/buqn/27in/9u4pP/gwa7/9/Hq//fy6f/x5tv/6tbH/+jO + vP+AW0r/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAj2RQ//rx + 6//9/Pr//fz6//38+//9/Pv/3MfB/9zHwf/cx8H/3MfB/9zHwP/cxsD/3Ma//9zFvf/cxLz/3MO7/9zD + uv/bwbj/28G2/9vAtP/bvrP/276x/9u9r//bva7/27ys/9u6qv/buqn/27mm/9u3pP/gwa7/+PLq//fy + 6v/x5dr/6tbI/+jOu/+AXUz/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAj2ZQ//ry7P/+/fv//fz7//79/P/+/fz/3MbA/9zGwf/cxsH/3MbB/9zGwP/cxsD/3MS//9zE + vf/cxLz/3MO6/9zCuf/cwrj/28C2/9vAtP/bv7P/276y/9u9r//bvK7/27ys/9u7q//buaj/27mn/9u3 + pP/gwa7/+PLr//fy6//x5dz/6tbI/+nQvf+AXEv/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAkGVS//vy7f/6+f7/8vP8/+zu/f/p7f3/yrnE/8y7xP/RwcP/2cPA/9zF + v//cxb7/3MS+/9zDvf/cw7v/3MO6/9zCuP/cwrf/3MG2/9u/tP/bv7L/276x/9u9sP/bvK3/27us/9u7 + qv/buqj/27mm/9u4pP/gwa7/+PLr//nz6//x59v/6tfJ/+nPvP+BXEv/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjmZV/+Th8P/Z4f7/0Nn9/8rU/v/I0v7/yNL+/8jT + /v/L6v7/2eD+/+fr/v/4+f7//v79//7+/f/+/fz//v38//79+//+/Pr//vz6//78+f/9+/j//fv3//36 + 9v/9+vX//fr0//359P/9+fP//Pjy//z48f/89/D/+PPs//jz6//y5t3/6tfJ/+nPvP+BXEv/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMv8QfF5s/8fK8v++y///s8P+/629 + //+qu///qrn//63Z//+x0P//vsr//8rU///Z4P//7vH+//7+/v/+/v3//v38//79/P/+/fv//vz6//78 + +f/+/Pj//fv4//379//9+vb//fr1//359P/9+fP//fny//z48f/8+PD/+PPs//jz7P/y5tz/6tfJ/+nP + vv+BXkv/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADZ//xwSSf8ybll9/624 + 9P+esf//iJ///3WQ//9qh///aoD//5zy//+FoP//nrD//7DA///AzP//0tv//+rv/v/+/v7//v79//79 + /P/+/fz//v37//78+v/+/Pn//fv4//379//9+vb//fr1//369P/9+fP//fny//z48v/8+PH/+PPs//jz + 7P/y5tz/6tfJ/+nPvf+CXUv/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC3/EgAo + /y6C4f+MY2GZ/4SV+P9bev//Qmn//zhm//83Y///NGT2/6P+/v86VPP/UWvv/3eG5v+UmuD/p6fb/7mz + 1v/SxM7/4c7J/+HNyP/hzcb/4cvD/+HKwf/hysD/4cm+/+DHvP/gx7r/4MW4/+DEtv/gxLT/4MKy/+DC + r//kyrj/+PPt//j07P/y5tz/6tfJ/+nPvf+CXU3/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAIf8IADP/KQAy/0EKQP9ilujn/1WF/P82YP//Mmb//2W4//8uZ///X7D6/3bm/f8rWfX/L1n0/z5d + 8P9peuT/kJTZ/6Wi0/+6sMz/1sHC/9zFvf/cxLz/3MK6/9zBuP/cwLX/3MC0/9u+sf/bvbD/27ut/9u7 + qv/buqn/27mm/9u3pP/gwa7/+fPt//j07f/z6N7/6tfK/+nPvv+CXUz/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAMv8bADL/OAAx/1IALf9+PGPZ/57///9Vov//K2n//5T2//8xif//YeP+/2DQ + /P8lYvb/OX32/y5f9P88XPD/cH7i/5aX1/+sps//xrfH/9zFvv/cxLz/3MK6/9zBuP/cwLX/3MC0/9u+ + sf/bvbD/27ut/9u7qv/buqn/27mm/9y4pP/gwa7/+PTu//n07f/y5tz/6NXH/+TJuP+CXUz/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAs/wYAMf8qADT/RgAx/2cAMf+rH0Db/16u/f9e9///YcL//2Hg + //9/7P//NeD//2PJ/P9kw/v/ccz7/yli9f8uWfP/SWHs/4SI3P+gndP/ua3L/9jCv//cxLz/3MK6/9zB + t//cwLX/3MC0/9u+sf/bvbD/27yt/9u7qv/cu6n/27mn/9u4pf/gwK7/+fXu//bw6f/z7OT/6dnO/9/E + tP+GYlD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAw/xAAM/8zADT/UAAz/4IANv/CHUze/ylq + /P9s1///H9n//2nu//8t2///ENL//3Lz//9m8P//IoH//ypx//83d///VZD//5LM//+w2///ytf//+/y + /v/+/v3//v38//38+//9+/n//Pr4//37+P///vr////8///9+v/9/Pf/+fXy//Xw6v/x6eT/7OXe/+jf + 2f/l3Nb/3Mq//7GPf/+EY1X0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAq/xgAMP86ADH/WAAy + /5kAOf/JT5nq/3DS/v9n0///Ze///wDK//8AzP//AMz//wvR//+C8v//XOD//2r1//+e////es3//2+Y + //+ntf//xdD//+fr/v/+/v3//v38//38+//9+/n//Pr4//37+f/azcX/wKqf/76mm/+8o5j/uKCU/7ee + kv+zm5D/spiP/6iNgP+Uc2X/h2JR/4hjUvyKbF1PAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAt + /xwAM/89ADH/XQAz/6UAP//KG1Ph/1Ct/f9Y5///BM///wDM//8AzP//AMz//wDM//8c1///W+T//1u8 + //8tdP//NWD//1p5//+itP//ws7//+Po/v/+/f3//v38//38+v/9+/n//Pr4///++//DrqP/pINz/8y7 + sv/Is6X/xq2a/8Wojv/DooP/wZx4/8qicv+4j2X/iWRW+5RzYkUAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAt/xwAM/89ADH/XQAu/6UANv/KJGXl/2DB/v9W5P//E9L//wDM//8AzP//AMz//wDL + //894///Z9P//ySB//8tcf//NWj//1p7//+itP//ws7//+Po/v/+/f3//fz7//38+v/9+/n//Pr4///8 + +v/NubD/vKSY////+v/78N7/+ObJ//Xcs//y05//88yL/9Opb/+HZVf5j3NjOgAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAp/xgAKv87ACr/Wjd8/7N72v/tkP7+/170//9c5v//W+v//wDK + //8AzP//AMz//wvQ//9w7P//Zd7//4Tj//8/h///NmX//2OC//+mt///w87+/+fr/f/+/fz//fz7//37 + +v/8+/n//Pr3//77+P/d0Mj/p4Z1//3y3v/14sP/8tiv/+7Om//vyIj/y6Br/4dlV/mPcmcxAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAs/xBEkf9NedX/l2i9/7o4gf/VL2nk/ydy + /f9QsP//Run//1rq//8h1///D9L//1bq//9J5f//M5L//ypw//8xa///O2X//3qU//+tvv7/ytT+/+/x + /f/9/Pz//fz6//37+f/8+vj//Pr3///7+f/e0sr/poJu//voyf/y167/7s2b/+/Ihv/Fmmn/h2RX+ZBz + ZToAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAr/wYAK/8rACr/RwAr + /2oALv+vIEfc/yxv/P+Z/f//U7L//1fo//9s6v//VOr//3PS//9i6f//dO3//yxu//81Z///UHP//5Sp + /v+3xf7/09r9//j5/P/9/Pv//fv6//z7+f/8+vj//Pn3//389//e0sr/pYBp//bcsf/uzpj/78eF/8yg + av+GZlj3k3ZqMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAMP8cADD/OgAw/1QAMv+EJ0HU/0WC/P8yeP//KHf//2P2//9at///dNb//1Wx//8sev//he3//37S + //9BXv//e5T//6q6/v/Ezv3/4ub8//38+//9/Pr//fv5//z6+P/8+vf//Pn2//36+P/e0sv/pH1k//TS + m//wxoP/xppo/4hnW/WVeWooAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAHf8JADD/KwAx/0MAMf9dREy0/0Fl+v81ZP//Q4b//5L///8wd///N4L//12t + //8xZ///M2L//4XZ//+FvP//obD+/7vH/v/T2/3/9fX7//38+v/9+/n//Pv4//z69//8+fb/+/n1//36 + 9v/f08v/o3xe//PLhf+/lGX/h2da9pV8dCEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADn/FAAv/zAANP9GYVWS/3qQ9f9TcP7/W5j//4Xb + //81X///NWX//zlp//89Zv//U3P+/32P/v+p4f//ttD9/83V/f/q7fv//f36//77+f/8/Pj//Pr5//z5 + 9//7+vb/+/j1//779//bzcT/p39b/8ygaP+KaFz1k3hxKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AQAx/xcAMP8wb12C/6mz + 8v+Wpvv/k9D9/3qt/f9eev3/Xn79/2mG/f9+lv3/lqn8/6q5+/+7xPv/zN37/+Tn+f/7+vj/+/n3//z5 + 9v/6+PX/+vj1//r39P/79/P/+fby///69v/DraD/mG9W/4ttX/KMc2shAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAALP8TgGJx/8XH7v+3ue7/ruj3/6Ot8f+irPH/oqzy/6aw8f+ttfH/trzw/8PG7//S0u3/6ePr//vx + 6P/78On/+/Dp//rv6P/67+f/+u/o//ru5v/57eX/+e3l//vv5f+bdWX/jW1g75N+choAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAlm5i/4tqbf+DZXX/iZGb/3lgfv92YID/dmCA/3hhfv98Y3v/gGRz/4ln + av+TbF//l2xY/5ZtWP+Va1n/lWxX/5RqV/+Ta1j/k2lW/5JqV/+RaFX/kWlW/5BpV/+LcGPVf3JlFQAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJ/8GNID/FQAr/xUANP8ZADT/GQAw + /xUAN/8OADb/BQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////AAD///////8AAPwAAAAAPwAA/AAAAAA/ + AAD8AAAAAD8AAPwAAAAAPwAA/AAAAAA/AAD8AAAAAD8AAPwAAAAAPwAA/AAAAAA/AAD8AAAAAD8AAPwA + AAAAPwAA/AAAAAA/AAD8AAAAAD8AAPwAAAAAPwAA/AAAAAA/AAD8AAAAAD8AAPwAAAAAPwAA/AAAAAA/ + AAD8AAAAAD8AAPwAAAAAPwAA/AAAAAA/AAD8AAAAAD8AAPwAAAAAPwAA/AAAAAA/AAD8AAAAAD8AAPwA + AAAAPwAA/AAAAAA/AAD8AAAAAD8AAPgAAAAAPwAA+AAAAAA/AADwAAAAAD8AAPAAAAAAPwAA4AAAAAA/ + AADgAAAAAH8AAOAAAAAA/wAA4AAAAAH/AADgAAAAA/8AAOAAAAAH/wAA8AAAAA//AADwAAAAH/8AAPgA + AAA//wAA/AAAAH//AAD8AAAA//8AAPwAAAH//wAA/AAAA///AAD///////8AAP///////wAA + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/CommonObjects/MessageBoxHelper.cs b/Demo_Source_Code/CSharpDemo/CommonObjects/MessageBoxHelper.cs new file mode 100644 index 0000000..588dab1 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/CommonObjects/MessageBoxHelper.cs @@ -0,0 +1,106 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.Runtime.InteropServices; +using System.Windows.Forms; + +namespace EaseFilter.CommonObjects +{ + public static class MessageBoxHelper + { + // use example + // MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + + public static void PrepToCenterMessageBoxOnForm(Form form) + { + MessageBoxCenterHelper helper = new MessageBoxCenterHelper(); + helper.Prep(form); + } + + private class MessageBoxCenterHelper + { + private int messageHook; + private IntPtr parentFormHandle; + + public void Prep(Form form) + { + NativeMethods.CenterMessageCallBackDelegate callBackDelegate = new NativeMethods.CenterMessageCallBackDelegate(CenterMessageCallBack); + GCHandle.Alloc(callBackDelegate); + + parentFormHandle = form.Handle; + messageHook = NativeMethods.SetWindowsHookEx(5, callBackDelegate, new IntPtr(NativeMethods.GetWindowLong(parentFormHandle, -6)), NativeMethods.GetCurrentThreadId()).ToInt32(); + } + + private int CenterMessageCallBack(int message, int wParam, int lParam) + { + NativeMethods.RECT formRect; + NativeMethods.RECT messageBoxRect; + int xPos; + int yPos; + + if (message == 5) + { + NativeMethods.GetWindowRect(parentFormHandle, out formRect); + NativeMethods.GetWindowRect(new IntPtr(wParam), out messageBoxRect); + + xPos = (int)((formRect.Left + (formRect.Right - formRect.Left) / 2) - ((messageBoxRect.Right - messageBoxRect.Left) / 2)); + yPos = (int)((formRect.Top + (formRect.Bottom - formRect.Top) / 2) - ((messageBoxRect.Bottom - messageBoxRect.Top) / 2)); + + NativeMethods.SetWindowPos(wParam, 0, xPos, yPos, 0, 0, 0x1 | 0x4 | 0x10); + NativeMethods.UnhookWindowsHookEx(messageHook); + } + + return 0; + } + } + + public static class NativeMethods + { + internal struct RECT + { + public int Left; + public int Top; + public int Right; + public int Bottom; + } + + internal delegate int CenterMessageCallBackDelegate(int message, int wParam, int lParam); + + [DllImport("user32.dll")] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool UnhookWindowsHookEx(int hhk); + + [DllImport("user32.dll", SetLastError = true)] + internal static extern int GetWindowLong(IntPtr hWnd, int nIndex); + + [DllImport("kernel32.dll")] + internal static extern int GetCurrentThreadId(); + + [DllImport("user32.dll", SetLastError = true)] + internal static extern IntPtr SetWindowsHookEx(int hook, CenterMessageCallBackDelegate callback, IntPtr hMod, int dwThreadId); + + [DllImport("user32.dll")] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool SetWindowPos(int hWnd, int hWndInsertAfter, int X, int Y, int cx, int cy, int uFlags); + + [DllImport("user32.dll")] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect); + } + } +} \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/CommonObjects/NtStatus.cs b/Demo_Source_Code/CSharpDemo/CommonObjects/NtStatus.cs new file mode 100644 index 0000000..eb95ee5 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/CommonObjects/NtStatus.cs @@ -0,0 +1,370 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.Collections.Generic; +using System.Text; + +namespace EaseFilter.CommonObjects +{ + public class NtStatus + { + /// + /// A NT status value. + /// + public enum Status : uint + { + // Success + Success = 0x00000000, + Wait1 = 0x00000001, + Wait2 = 0x00000002, + Wait3 = 0x00000003, + Wait63 = 0x0000003f, + Abandoned = 0x00000080, + AbandonedWait0 = 0x00000080, + AbandonedWait1 = 0x00000081, + AbandonedWait2 = 0x00000082, + AbandonedWait3 = 0x00000083, + AbandonedWait63 = 0x000000bf, + UserApc = 0x000000c0, + KernelApc = 0x00000100, + Alerted = 0x00000101, + Timeout = 0x00000102, + Pending = 0x00000103, + Reparse = 0x00000104, + MoreEntries = 0x00000105, + NotAllAssigned = 0x00000106, + SomeNotMapped = 0x00000107, + OpLockBreakInProgress = 0x00000108, + VolumeMounted = 0x00000109, + RxActCommitted = 0x0000010a, + NotifyCleanup = 0x0000010b, + NotifyEnumDir = 0x0000010c, + NoQuotasForAccount = 0x0000010d, + PrimaryTransportConnectFailed = 0x0000010e, + PageFaultTransition = 0x00000110, + PageFaultDemandZero = 0x00000111, + PageFaultCopyOnWrite = 0x00000112, + PageFaultGuardPage = 0x00000113, + PageFaultPagingFile = 0x00000114, + CrashDump = 0x00000116, + ReparseObject = 0x00000118, + NothingToTerminate = 0x00000122, + ProcessNotInJob = 0x00000123, + ProcessInJob = 0x00000124, + ProcessCloned = 0x00000129, + FileLockedWithOnlyReaders = 0x0000012a, + FileLockedWithWriters = 0x0000012b, + + // Informational + Informational = 0x40000000, + ObjectNameExists = 0x40000000, + ThreadWasSuspended = 0x40000001, + WorkingSetLimitRange = 0x40000002, + ImageNotAtBase = 0x40000003, + RegistryRecovered = 0x40000009, + + // Warning + Warning = 0x80000000, + GuardPageViolation = 0x80000001, + DatatypeMisalignment = 0x80000002, + Breakpoint = 0x80000003, + SingleStep = 0x80000004, + BufferOverflow = 0x80000005, + NoMoreFiles = 0x80000006, + HandlesClosed = 0x8000000a, + PartialCopy = 0x8000000d, + DeviceBusy = 0x80000011, + InvalidEaName = 0x80000013, + EaListInconsistent = 0x80000014, + NoMoreEntries = 0x8000001a, + LongJump = 0x80000026, + DllMightBeInsecure = 0x8000002b, + + // Error + Error = 0xc0000000, + Unsuccessful = 0xc0000001, + NotImplemented = 0xc0000002, + InvalidInfoClass = 0xc0000003, + InfoLengthMismatch = 0xc0000004, + AccessViolation = 0xc0000005, + InPageError = 0xc0000006, + PagefileQuota = 0xc0000007, + InvalidHandle = 0xc0000008, + BadInitialStack = 0xc0000009, + BadInitialPc = 0xc000000a, + InvalidCid = 0xc000000b, + TimerNotCanceled = 0xc000000c, + InvalidParameter = 0xc000000d, + NoSuchDevice = 0xc000000e, + NoSuchFile = 0xc000000f, + InvalidDeviceRequest = 0xc0000010, + EndOfFile = 0xc0000011, + WrongVolume = 0xc0000012, + NoMediaInDevice = 0xc0000013, + NoMemory = 0xc0000017, + NotMappedView = 0xc0000019, + UnableToFreeVm = 0xc000001a, + UnableToDeleteSection = 0xc000001b, + IllegalInstruction = 0xc000001d, + AlreadyCommitted = 0xc0000021, + AccessDenied = 0xc0000022, + BufferTooSmall = 0xc0000023, + ObjectTypeMismatch = 0xc0000024, + NonContinuableException = 0xc0000025, + BadStack = 0xc0000028, + NotLocked = 0xc000002a, + NotCommitted = 0xc000002d, + InvalidParameterMix = 0xc0000030, + ObjectNameInvalid = 0xc0000033, + ObjectNameNotFound = 0xc0000034, + ObjectNameCollision = 0xc0000035, + ObjectPathInvalid = 0xc0000039, + ObjectPathNotFound = 0xc000003a, + ObjectPathSyntaxBad = 0xc000003b, + DataOverrun = 0xc000003c, + DataLate = 0xc000003d, + DataError = 0xc000003e, + CrcError = 0xc000003f, + SectionTooBig = 0xc0000040, + PortConnectionRefused = 0xc0000041, + InvalidPortHandle = 0xc0000042, + SharingViolation = 0xc0000043, + QuotaExceeded = 0xc0000044, + InvalidPageProtection = 0xc0000045, + MutantNotOwned = 0xc0000046, + SemaphoreLimitExceeded = 0xc0000047, + PortAlreadySet = 0xc0000048, + SectionNotImage = 0xc0000049, + SuspendCountExceeded = 0xc000004a, + ThreadIsTerminating = 0xc000004b, + BadWorkingSetLimit = 0xc000004c, + IncompatibleFileMap = 0xc000004d, + SectionProtection = 0xc000004e, + EasNotSupported = 0xc000004f, + EaTooLarge = 0xc0000050, + NonExistentEaEntry = 0xc0000051, + NoEasOnFile = 0xc0000052, + EaCorruptError = 0xc0000053, + FileLockConflict = 0xc0000054, + LockNotGranted = 0xc0000055, + DeletePending = 0xc0000056, + CtlFileNotSupported = 0xc0000057, + UnknownRevision = 0xc0000058, + RevisionMismatch = 0xc0000059, + InvalidOwner = 0xc000005a, + InvalidPrimaryGroup = 0xc000005b, + NoImpersonationToken = 0xc000005c, + CantDisableMandatory = 0xc000005d, + NoLogonServers = 0xc000005e, + NoSuchLogonSession = 0xc000005f, + NoSuchPrivilege = 0xc0000060, + PrivilegeNotHeld = 0xc0000061, + InvalidAccountName = 0xc0000062, + UserExists = 0xc0000063, + NoSuchUser = 0xc0000064, + GroupExists = 0xc0000065, + NoSuchGroup = 0xc0000066, + MemberInGroup = 0xc0000067, + MemberNotInGroup = 0xc0000068, + LastAdmin = 0xc0000069, + WrongPassword = 0xc000006a, + IllFormedPassword = 0xc000006b, + PasswordRestriction = 0xc000006c, + LogonFailure = 0xc000006d, + AccountRestriction = 0xc000006e, + InvalidLogonHours = 0xc000006f, + InvalidWorkstation = 0xc0000070, + PasswordExpired = 0xc0000071, + AccountDisabled = 0xc0000072, + NoneMapped = 0xc0000073, + TooManyLuidsRequested = 0xc0000074, + LuidsExhausted = 0xc0000075, + InvalidSubAuthority = 0xc0000076, + InvalidAcl = 0xc0000077, + InvalidSid = 0xc0000078, + InvalidSecurityDescr = 0xc0000079, + ProcedureNotFound = 0xc000007a, + InvalidImageFormat = 0xc000007b, + NoToken = 0xc000007c, + BadInheritanceAcl = 0xc000007d, + RangeNotLocked = 0xc000007e, + DiskFull = 0xc000007f, + ServerDisabled = 0xc0000080, + ServerNotDisabled = 0xc0000081, + TooManyGuidsRequested = 0xc0000082, + GuidsExhausted = 0xc0000083, + InvalidIdAuthority = 0xc0000084, + AgentsExhausted = 0xc0000085, + InvalidVolumeLabel = 0xc0000086, + SectionNotExtended = 0xc0000087, + NotMappedData = 0xc0000088, + ResourceDataNotFound = 0xc0000089, + ResourceTypeNotFound = 0xc000008a, + ResourceNameNotFound = 0xc000008b, + ArrayBoundsExceeded = 0xc000008c, + FloatDenormalOperand = 0xc000008d, + FloatDivideByZero = 0xc000008e, + FloatInexactResult = 0xc000008f, + FloatInvalidOperation = 0xc0000090, + FloatOverflow = 0xc0000091, + FloatStackCheck = 0xc0000092, + FloatUnderflow = 0xc0000093, + IntegerDivideByZero = 0xc0000094, + IntegerOverflow = 0xc0000095, + PrivilegedInstruction = 0xc0000096, + TooManyPagingFiles = 0xc0000097, + FileInvalid = 0xc0000098, + InstanceNotAvailable = 0xc00000ab, + PipeNotAvailable = 0xc00000ac, + InvalidPipeState = 0xc00000ad, + PipeBusy = 0xc00000ae, + IllegalFunction = 0xc00000af, + PipeDisconnected = 0xc00000b0, + PipeClosing = 0xc00000b1, + PipeConnected = 0xc00000b2, + PipeListening = 0xc00000b3, + InvalidReadMode = 0xc00000b4, + IoTimeout = 0xc00000b5, + FileForcedClosed = 0xc00000b6, + ProfilingNotStarted = 0xc00000b7, + ProfilingNotStopped = 0xc00000b8, + NotSameDevice = 0xc00000d4, + FileRenamed = 0xc00000d5, + CantWait = 0xc00000d8, + PipeEmpty = 0xc00000d9, + CantTerminateSelf = 0xc00000db, + InternalError = 0xc00000e5, + InvalidParameter1 = 0xc00000ef, + InvalidParameter2 = 0xc00000f0, + InvalidParameter3 = 0xc00000f1, + InvalidParameter4 = 0xc00000f2, + InvalidParameter5 = 0xc00000f3, + InvalidParameter6 = 0xc00000f4, + InvalidParameter7 = 0xc00000f5, + InvalidParameter8 = 0xc00000f6, + InvalidParameter9 = 0xc00000f7, + InvalidParameter10 = 0xc00000f8, + InvalidParameter11 = 0xc00000f9, + InvalidParameter12 = 0xc00000fa, + MappedFileSizeZero = 0xc000011e, + TooManyOpenedFiles = 0xc000011f, + Cancelled = 0xc0000120, + CannotDelete = 0xc0000121, + InvalidComputerName = 0xc0000122, + FileDeleted = 0xc0000123, + SpecialAccount = 0xc0000124, + SpecialGroup = 0xc0000125, + SpecialUser = 0xc0000126, + MembersPrimaryGroup = 0xc0000127, + FileClosed = 0xc0000128, + TooManyThreads = 0xc0000129, + ThreadNotInProcess = 0xc000012a, + TokenAlreadyInUse = 0xc000012b, + PagefileQuotaExceeded = 0xc000012c, + CommitmentLimit = 0xc000012d, + InvalidImageLeFormat = 0xc000012e, + InvalidImageNotMz = 0xc000012f, + InvalidImageProtect = 0xc0000130, + InvalidImageWin16 = 0xc0000131, + LogonServer = 0xc0000132, + DifferenceAtDc = 0xc0000133, + SynchronizationRequired = 0xc0000134, + DllNotFound = 0xc0000135, + IoPrivilegeFailed = 0xc0000137, + OrdinalNotFound = 0xc0000138, + EntryPointNotFound = 0xc0000139, + ControlCExit = 0xc000013a, + PortNotSet = 0xc0000353, + DebuggerInactive = 0xc0000354, + CallbackBypass = 0xc0000503, + PortClosed = 0xc0000700, + MessageLost = 0xc0000701, + InvalidMessage = 0xc0000702, + RequestCanceled = 0xc0000703, + RecursiveDispatch = 0xc0000704, + LpcReceiveBufferExpected = 0xc0000705, + LpcInvalidConnectionUsage = 0xc0000706, + LpcRequestsNotAllowed = 0xc0000707, + ResourceInUse = 0xc0000708, + ProcessIsProtected = 0xc0000712, + VolumeDirty = 0xc0000806, + FileCheckedOut = 0xc0000901, + CheckOutRequired = 0xc0000902, + BadFileType = 0xc0000903, + FileTooLarge = 0xc0000904, + FormsAuthRequired = 0xc0000905, + VirusInfected = 0xc0000906, + VirusDeleted = 0xc0000907, + TransactionalConflict = 0xc0190001, + InvalidTransaction = 0xc0190002, + TransactionNotActive = 0xc0190003, + TmInitializationFailed = 0xc0190004, + RmNotActive = 0xc0190005, + RmMetadataCorrupt = 0xc0190006, + TransactionNotJoined = 0xc0190007, + DirectoryNotRm = 0xc0190008, + CouldNotResizeLog = 0xc0190009, + TransactionsUnsupportedRemote = 0xc019000a, + LogResizeInvalidSize = 0xc019000b, + RemoteFileVersionMismatch = 0xc019000c, + CrmProtocolAlreadyExists = 0xc019000f, + TransactionPropagationFailed = 0xc0190010, + CrmProtocolNotFound = 0xc0190011, + TransactionSuperiorExists = 0xc0190012, + TransactionRequestNotValid = 0xc0190013, + TransactionNotRequested = 0xc0190014, + TransactionAlreadyAborted = 0xc0190015, + TransactionAlreadyCommitted = 0xc0190016, + TransactionInvalidMarshallBuffer = 0xc0190017, + CurrentTransactionNotValid = 0xc0190018, + LogGrowthFailed = 0xc0190019, + ObjectNoLongerExists = 0xc0190021, + StreamMiniversionNotFound = 0xc0190022, + StreamMiniversionNotValid = 0xc0190023, + MiniversionInaccessibleFromSpecifiedTransaction = 0xc0190024, + CantOpenMiniversionWithModifyIntent = 0xc0190025, + CantCreateMoreStreamMiniversions = 0xc0190026, + HandleNoLongerValid = 0xc0190028, + NoTxfMetadata = 0xc0190029, + LogCorruptionDetected = 0xc0190030, + CantRecoverWithHandleOpen = 0xc0190031, + RmDisconnected = 0xc0190032, + EnlistmentNotSuperior = 0xc0190033, + RecoveryNotNeeded = 0xc0190034, + RmAlreadyStarted = 0xc0190035, + FileIdentityNotPersistent = 0xc0190036, + CantBreakTransactionalDependency = 0xc0190037, + CantCrossRmBoundary = 0xc0190038, + TxfDirNotEmpty = 0xc0190039, + IndoubtTransactionsExist = 0xc019003a, + TmVolatile = 0xc019003b, + RollbackTimerExpired = 0xc019003c, + TxfAttributeCorrupt = 0xc019003d, + EfsNotAllowedInTransaction = 0xc019003e, + TransactionalOpenNotAllowed = 0xc019003f, + TransactedMappingUnsupportedRemote = 0xc0190040, + TxfMetadataAlreadyPresent = 0xc0190041, + TransactionScopeCallbacksNotSet = 0xc0190042, + TransactionRequiredPromotion = 0xc0190043, + CannotExecuteFileInTransaction = 0xc0190044, + TransactionsNotFrozen = 0xc0190045, + + MaximumNtStatus = 0xffffffff + } + } +} diff --git a/Demo_Source_Code/CSharpDemo/CommonObjects/OptionForm.cs b/Demo_Source_Code/CSharpDemo/CommonObjects/OptionForm.cs new file mode 100644 index 0000000..a0e7c25 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/CommonObjects/OptionForm.cs @@ -0,0 +1,714 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; +using System.Diagnostics; +using System.Globalization; + +using EaseFilter.FilterControl; + +namespace EaseFilter.CommonObjects +{ + public partial class OptionForm : Form + { + OptionType optionType = OptionType.MonitorFileIOEvents; + string value = string.Empty; + + uint monitorFileEvents = 0; + ulong monitorIOEvents = 0; + ulong controlIOEvents = 0; + string processId = "0"; + uint accessFlags = 0; + uint debugModules = 0xffff; + uint filterStatus = 0; + uint returnStatus = 0; + uint registryAccessFlags = 0; + ulong registryCallbackClass = 0; + byte filterType = 0; + uint processControlFlag = 0; + uint filterDesiredAccess = 0; + uint filterDisposition = 0; + uint filterCreateOptions = 0; + + public bool isMonitorFilter = false; + + public enum OptionType + { + MonitorFileEvents = 0, + MonitorFileIOEvents, + ControlFileIOEvents, + ProccessId, + Access_Flag, + Filter_Status, + Return_Status, + ShareFileAccessFlag, + RegistryAccessFlag, + RegistryCallbackClass, + FilterType, + ProcessControlFlag, + FilterDesiredAccess, + FilterDisposition, + FilterCreateOptions + } + + public OptionForm(OptionType formType, string defaultValue, bool _isMoitorFilter) + { + this.optionType = formType; + this.value = defaultValue; + this.isMonitorFilter = _isMoitorFilter; + + InitializeComponent(); + InitForm(); + } + + public OptionForm(OptionType formType, string defaultValue) + { + this.optionType = formType; + this.value = defaultValue; + + InitializeComponent(); + InitForm(); + } + + public uint FilterCreateOptions + { + get { return filterCreateOptions; } + } + + public uint FilterDisposition + { + get { return filterDisposition; } + } + + public uint FilterDesiredAccess + { + get { return filterDesiredAccess; } + } + + public uint ProcessControlFlag + { + get { return processControlFlag; } + } + + public byte FilterType + { + get { return filterType; } + } + + public uint MonitorFileEvents + { + get { return monitorFileEvents; } + } + + public uint FilterStatus + { + get { return filterStatus; } + } + public uint ReturnStatus + { + get { return returnStatus; } + } + + public ulong MonitorIOEvents + { + get { return monitorIOEvents; } + } + + public ulong ControlIOEvents + { + get { return controlIOEvents; } + } + + public string ProcessId + { + get { return processId; } + } + + + public uint AccessFlags + { + get { return accessFlags; } + } + + public uint DebugModules + { + get { return debugModules; } + } + + public uint RegAccessFlags + { + get { return registryAccessFlags; } + } + + public ulong RegCallbackClass + { + get { return registryCallbackClass; } + } + + + void InitForm() + { + this.Text = optionType.ToString(); + + switch (optionType) + { + case OptionType.MonitorFileEvents: + { + listView1.Clear(); + //create column header for ListView + listView1.Columns.Add("Select monitor file event type", 200, System.Windows.Forms.HorizontalAlignment.Left); + + monitorFileEvents = uint.Parse(value); + + foreach (FilterAPI.FileChangedEvents monitorFileEvent in Enum.GetValues(typeof(FilterAPI.FileChangedEvents))) + { + + string item = monitorFileEvent.ToString(); + + ListViewItem lvItem = new ListViewItem(item, 0); + lvItem.Tag = (uint)monitorFileEvent; + + if ((monitorFileEvents & (uint)monitorFileEvent) > 0) + { + lvItem.Checked = true; + } + + listView1.Items.Add(lvItem); + } + + break; + } + + case OptionType.MonitorFileIOEvents: + { + listView1.Clear(); //clear control + //create column header for ListView + listView1.Columns.Add("Select monitor I/O events", 400, System.Windows.Forms.HorizontalAlignment.Left); + + monitorIOEvents = ulong.Parse(value); + + foreach (MonitorFileIOEvents monitorFileIOevent in Enum.GetValues(typeof(MonitorFileIOEvents))) + { + string item = monitorFileIOevent.ToString(); + + ListViewItem lvItem = new ListViewItem(item, 0); + lvItem.Tag = (ulong)monitorFileIOevent; + + if ((monitorIOEvents & (ulong)monitorFileIOevent) > 0) + { + lvItem.Checked = true; + } + + listView1.Items.Add(lvItem); + } + + break; + } + case OptionType.ControlFileIOEvents: + { + listView1.Clear(); //clear control + //create column header for ListView + listView1.Columns.Add("Select control I/O events", 400, System.Windows.Forms.HorizontalAlignment.Left); + + controlIOEvents = ulong.Parse(value); + + foreach (ControlFileIOEvents controlFileIOevent in Enum.GetValues(typeof(ControlFileIOEvents))) + { + string item = controlFileIOevent.ToString(); + + ListViewItem lvItem = new ListViewItem(item, 0); + lvItem.Tag = (ulong)controlFileIOevent; + + if ((controlIOEvents & (ulong)controlFileIOevent) > 0) + { + lvItem.Checked = true; + } + + listView1.Items.Add(lvItem); + } + + break; + } + + case OptionType.RegistryAccessFlag: + { + listView1.Clear(); //clear control + //create column header for ListView + listView1.Columns.Add("Select Registry Access Control Flag", 400, System.Windows.Forms.HorizontalAlignment.Left); + + registryAccessFlags = uint.Parse(value); + + foreach (FilterAPI.RegControlFlag regAccessFlag in Enum.GetValues(typeof(FilterAPI.RegControlFlag))) + { + string item = regAccessFlag.ToString(); + + ListViewItem lvItem = new ListViewItem(item, 0); + lvItem.Tag = regAccessFlag; + + if ((registryAccessFlags & (uint)regAccessFlag) > 0) + { + lvItem.Checked = true; + } + + listView1.Items.Add(lvItem); + } + + break; + } + + case OptionType.RegistryCallbackClass: + { + listView1.Clear(); //clear control + //create column header for ListView + listView1.Columns.Add("Select Registry Callback Class", 400, System.Windows.Forms.HorizontalAlignment.Left); + + registryCallbackClass = ulong.Parse(value); + + foreach (FilterAPI.RegCallbackClass regCallbackClass in Enum.GetValues(typeof(FilterAPI.RegCallbackClass))) + { + string item = regCallbackClass.ToString(); + + ListViewItem lvItem = new ListViewItem(item, 0); + lvItem.Tag = regCallbackClass; + + if ((registryCallbackClass & (ulong)regCallbackClass) > 0) + { + lvItem.Checked = true; + } + + listView1.Items.Add(lvItem); + } + + break; + } + case OptionType.ProccessId: + { + Process[] processlist = Process.GetProcesses(); + + listView1.Clear(); //clear control + //create column header for ListView + listView1.Columns.Add("Process Id", 100, System.Windows.Forms.HorizontalAlignment.Left); + listView1.Columns.Add("Process Name", 300, System.Windows.Forms.HorizontalAlignment.Left); + + List pidList = new List(); + + string[] pids = value.Split(';'); + foreach (string pid in pids) + { + if (!string.IsNullOrEmpty(pid)) + { + pidList.Add(uint.Parse(pid)); + } + } + + + for (int i = 0; i < processlist.Length; i++) + { + string[] item = new string[2]; + item[0] = processlist[i].Id.ToString(); + item[1] = processlist[i].ProcessName; + + if (processlist[i].Id == 0) + { + //this is idle process, skip it. + continue; + } + + ListViewItem lvItem = new ListViewItem(item, 0); + + lvItem.Tag = processlist[i].Id; + + if (pidList.Contains((uint)(processlist[i].Id))) + { + lvItem.Checked = true; + } + + if (i > 0 ) + { + for (int k = 0; k < i; k++) + { + if ((int)listView1.Items[k].Tag > processlist[i].Id) + { + listView1.Items.Insert(k, lvItem); + break; + } + } + + if (listView1.Items.Count == i ) + { + listView1.Items.Insert(i, lvItem); + } + + } + else + { + listView1.Items.Insert(i, lvItem); + } + + } + + break; + } + + case OptionType.Access_Flag: + { + listView1.Clear(); //clear control + //create column header for ListView + listView1.Columns.Add("Select AccessFlag", 400, System.Windows.Forms.HorizontalAlignment.Left); + + accessFlags = uint.Parse(value); + + foreach (FilterAPI.AccessFlag accessFlag in Enum.GetValues(typeof(FilterAPI.AccessFlag))) + { + if (accessFlag <= FilterAPI.AccessFlag.EXCLUDE_FILE_ACCESS || accessFlag == FilterAPI.AccessFlag.LEAST_ACCESS_FLAG) + { + //this is special usage for the filter + continue; + } + + string item = accessFlag.ToString(); + ListViewItem lvItem = new ListViewItem(item, 0); + lvItem.Tag = accessFlag; + + if (((uint)accessFlag & accessFlags) > 0) + { + lvItem.Checked = true; + } + + listView1.Items.Add(lvItem); + } + + break; + } + + case OptionType.ShareFileAccessFlag: + { + listView1.Clear(); //clear control + //create column header for ListView + listView1.Columns.Add("Select AccessFlag", 400, System.Windows.Forms.HorizontalAlignment.Left); + + accessFlags = uint.Parse(value); + + foreach (FilterAPI.AccessFlag accessFlag in Enum.GetValues(typeof(FilterAPI.AccessFlag))) + { + if (accessFlag < FilterAPI.AccessFlag.ALLOW_OPEN_WITH_ACCESS_SYSTEM_SECURITY || accessFlag == FilterAPI.AccessFlag.LEAST_ACCESS_FLAG) + { + //this is special usage for the filter + continue; + } + + string item = accessFlag.ToString(); + ListViewItem lvItem = new ListViewItem(item, 0); + lvItem.Tag = accessFlag; + + if (((uint)accessFlag & accessFlags) > 0) + { + lvItem.Checked = true; + } + + listView1.Items.Add(lvItem); + } + + break; + } + + + case OptionType.Filter_Status: + { + listView1.Clear(); //clear control + //create column header for ListView + listView1.Columns.Add("Select Filter Status", 400, System.Windows.Forms.HorizontalAlignment.Left); + + filterStatus = uint.Parse(value); + + foreach (FilterAPI.FilterStatus status in Enum.GetValues(typeof(FilterAPI.FilterStatus))) + { + string item = status.ToString(); + ListViewItem lvItem = new ListViewItem(item, 0); + lvItem.Tag = status; + + if (((uint)status & filterStatus) > 0) + { + lvItem.Checked = true; + } + + listView1.Items.Add(lvItem); + } + + break; + } + + case OptionType.Return_Status: + { + listView1.Clear(); //clear control + //create column header for ListView + listView1.Columns.Add("Select Only One Status", 400, System.Windows.Forms.HorizontalAlignment.Left); + + returnStatus = uint.Parse(value); + + foreach (NtStatus.Status status in Enum.GetValues(typeof(NtStatus.Status))) + { + string item = status.ToString(); + ListViewItem lvItem = new ListViewItem(item, 0); + lvItem.Tag = status; + + if (((uint)status & filterStatus) > 0) + { + lvItem.Checked = true; + } + + listView1.Items.Add(lvItem); + } + + break; + } + + case OptionType.FilterType: + { + listView1.Clear(); //clear control + //create column header for ListView + listView1.Columns.Add("Select Filter Driver Type", 400, System.Windows.Forms.HorizontalAlignment.Left); + + filterType = byte.Parse(value); + + foreach (FilterAPI.FilterType fltType in Enum.GetValues(typeof(FilterAPI.FilterType))) + { + string item = fltType.ToString(); + + ListViewItem lvItem = new ListViewItem(item, 0); + lvItem.Tag = fltType; + + if ((filterType & (byte)fltType) > 0) + { + lvItem.Checked = true; + } + + listView1.Items.Add(lvItem); + } + + break; + } + + case OptionType.ProcessControlFlag: + { + listView1.Clear(); //clear control + //create column header for ListView + listView1.Columns.Add("Select Process Control Flag", 400, System.Windows.Forms.HorizontalAlignment.Left); + + processControlFlag = uint.Parse(value); + + foreach (FilterAPI.ProcessControlFlag controlFlag in Enum.GetValues(typeof(FilterAPI.ProcessControlFlag))) + { + string item = controlFlag.ToString(); + + ListViewItem lvItem = new ListViewItem(item, 0); + lvItem.Tag = controlFlag; + + if ((processControlFlag & (uint)controlFlag) > 0) + { + lvItem.Checked = true; + } + + listView1.Items.Add(lvItem); + } + + break; + } + case OptionType.FilterDesiredAccess: + { + listView1.Clear(); //clear control + //create column header for ListView + listView1.Columns.Add("Select Filter DesiredAccess Flag", 400, System.Windows.Forms.HorizontalAlignment.Left); + + filterDesiredAccess = uint.Parse(value); + + foreach (WinData.DisiredAccess desiredAccess in Enum.GetValues(typeof(WinData.DisiredAccess))) + { + string item = "(0x" + ((uint)desiredAccess).ToString("X") + ")" + desiredAccess.ToString(); + + ListViewItem lvItem = new ListViewItem(item, 0); + lvItem.Tag = desiredAccess; + + if ((filterDesiredAccess & (uint)desiredAccess) > 0) + { + lvItem.Checked = true; + } + + listView1.Items.Add(lvItem); + } + + break; + } + case OptionType.FilterDisposition: + { + listView1.Clear(); //clear control + //create column header for ListView + listView1.Columns.Add("Select Filter Disposition Flag", 400, System.Windows.Forms.HorizontalAlignment.Left); + + filterDisposition = uint.Parse(value); + + foreach (WinData.Disposition dispostion in Enum.GetValues(typeof(WinData.Disposition))) + { + string item = "(0x" + ((uint)dispostion).ToString("X") + ")" + dispostion.ToString(); + + ListViewItem lvItem = new ListViewItem(item, 0); + lvItem.Tag = dispostion; + + if ((filterDisposition & (uint)dispostion) > 0) + { + lvItem.Checked = true; + } + + listView1.Items.Add(lvItem); + } + + break; + } + case OptionType.FilterCreateOptions: + { + listView1.Clear(); //clear control + //create column header for ListView + listView1.Columns.Add("Select Filter CreateOptions Flag", 400, System.Windows.Forms.HorizontalAlignment.Left); + + filterCreateOptions = uint.Parse(value); + + foreach (WinData.CreateOptions createOptions in Enum.GetValues(typeof(WinData.CreateOptions))) + { + string item = "(0x" + ((uint)createOptions).ToString("X") + ")" + createOptions.ToString(); + + ListViewItem lvItem = new ListViewItem(item, 0); + lvItem.Tag = createOptions; + + if ((filterCreateOptions & (uint)createOptions) > 0) + { + lvItem.Checked = true; + } + + listView1.Items.Add(lvItem); + } + + break; + } + + } + } + + private void button_Ok_Click(object sender, EventArgs e) + { + monitorFileEvents = 0; + monitorIOEvents = 0; + controlIOEvents = 0; + + processId = string.Empty; + accessFlags = 0; + debugModules = 0; + registryAccessFlags = 0; + registryCallbackClass = 0; + filterType = 0; + processControlFlag = 0; + filterDesiredAccess = 0; + filterDisposition = 0; + filterCreateOptions = 0; + + foreach (ListViewItem item in listView1.CheckedItems) + { + switch (optionType) + { + case OptionType.MonitorFileEvents: + monitorFileEvents |= (uint)item.Tag; + break; + case OptionType.MonitorFileIOEvents: + monitorIOEvents |= (ulong)item.Tag; + break; + case OptionType.ControlFileIOEvents: + controlIOEvents |= (ulong)item.Tag; + break; + case OptionType.ProccessId: + int pid = (int)item.Tag; + processId += pid.ToString() + ";"; + break; + + case OptionType.Access_Flag: + accessFlags |= (uint)item.Tag; + break; + + case OptionType.RegistryAccessFlag: + registryAccessFlags |= (uint)item.Tag; + break; + + case OptionType.RegistryCallbackClass: + registryCallbackClass |= (ulong)item.Tag; + break; + + case OptionType.ShareFileAccessFlag: + accessFlags |= (uint)item.Tag; + break; + + case OptionType.Filter_Status: + filterStatus |= (uint)item.Tag; + break; + + case OptionType.Return_Status: + returnStatus |= (uint)item.Tag; + return; + + case OptionType.FilterType: + filterType |= (byte)item.Tag; + break; + + case OptionType.ProcessControlFlag: + processControlFlag |= (uint)item.Tag; + break; + case OptionType.FilterDesiredAccess: + filterDesiredAccess |= (uint)item.Tag; + break; + case OptionType.FilterDisposition: + filterDisposition |= (uint)item.Tag; + break; + case OptionType.FilterCreateOptions: + filterCreateOptions |= (uint)item.Tag; + break; + } + } + + } + + private void button_SelectAll_Click(object sender, EventArgs e) + { + foreach (ListViewItem item in listView1.Items) + { + item.Checked = true; + } + } + + private void button_ClearAll_Click(object sender, EventArgs e) + { + foreach (ListViewItem item in listView1.Items) + { + item.Checked = false; + } + } + + + } +} diff --git a/Demo_Source_Code/CSharpDemo/CommonObjects/OptionForm.designer.cs b/Demo_Source_Code/CSharpDemo/CommonObjects/OptionForm.designer.cs new file mode 100644 index 0000000..5159ec4 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/CommonObjects/OptionForm.designer.cs @@ -0,0 +1,117 @@ +namespace EaseFilter.CommonObjects +{ + partial class OptionForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(OptionForm)); + this.button_SelectAll = new System.Windows.Forms.Button(); + this.button_ClearAll = new System.Windows.Forms.Button(); + this.button_Ok = new System.Windows.Forms.Button(); + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.listView1 = new System.Windows.Forms.ListView(); + this.groupBox1.SuspendLayout(); + this.SuspendLayout(); + // + // button_SelectAll + // + this.button_SelectAll.Location = new System.Drawing.Point(12, 452); + this.button_SelectAll.Name = "button_SelectAll"; + this.button_SelectAll.Size = new System.Drawing.Size(75, 23); + this.button_SelectAll.TabIndex = 34; + this.button_SelectAll.Text = "Select All"; + this.button_SelectAll.UseVisualStyleBackColor = true; + this.button_SelectAll.Click += new System.EventHandler(this.button_SelectAll_Click); + // + // button_ClearAll + // + this.button_ClearAll.Location = new System.Drawing.Point(93, 452); + this.button_ClearAll.Name = "button_ClearAll"; + this.button_ClearAll.Size = new System.Drawing.Size(75, 23); + this.button_ClearAll.TabIndex = 35; + this.button_ClearAll.Text = "Clear All"; + this.button_ClearAll.UseVisualStyleBackColor = true; + this.button_ClearAll.Click += new System.EventHandler(this.button_ClearAll_Click); + // + // button_Ok + // + this.button_Ok.DialogResult = System.Windows.Forms.DialogResult.OK; + this.button_Ok.Location = new System.Drawing.Point(293, 452); + this.button_Ok.Name = "button_Ok"; + this.button_Ok.Size = new System.Drawing.Size(75, 23); + this.button_Ok.TabIndex = 36; + this.button_Ok.Text = "Ok"; + this.button_Ok.UseVisualStyleBackColor = true; + this.button_Ok.Click += new System.EventHandler(this.button_Ok_Click); + // + // groupBox1 + // + this.groupBox1.Controls.Add(this.listView1); + this.groupBox1.Location = new System.Drawing.Point(12, 12); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size(356, 424); + this.groupBox1.TabIndex = 37; + this.groupBox1.TabStop = false; + // + // listView1 + // + this.listView1.CheckBoxes = true; + this.listView1.Dock = System.Windows.Forms.DockStyle.Fill; + this.listView1.Location = new System.Drawing.Point(3, 16); + this.listView1.Name = "listView1"; + this.listView1.Size = new System.Drawing.Size(350, 405); + this.listView1.TabIndex = 0; + this.listView1.UseCompatibleStateImageBehavior = false; + this.listView1.View = System.Windows.Forms.View.Details; + // + // OptionForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(389, 491); + this.Controls.Add(this.groupBox1); + this.Controls.Add(this.button_Ok); + this.Controls.Add(this.button_ClearAll); + this.Controls.Add(this.button_SelectAll); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Name = "OptionForm"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "OptionForm"; + this.groupBox1.ResumeLayout(false); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.Button button_SelectAll; + private System.Windows.Forms.Button button_ClearAll; + private System.Windows.Forms.Button button_Ok; + private System.Windows.Forms.GroupBox groupBox1; + private System.Windows.Forms.ListView listView1; + } +} \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/CommonObjects/OptionForm.resx b/Demo_Source_Code/CSharpDemo/CommonObjects/OptionForm.resx new file mode 100644 index 0000000..beb4cc5 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/CommonObjects/OptionForm.resx @@ -0,0 +1,570 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + AAABAAgAEBAAAAEACABoBQAAhgAAABAQAAABACAAaAQAAO4FAAAYGAAAAQAIAMgGAABWCgAAGBgAAAEA + IACICQAAHhEAACAgAAABAAgAqAgAAKYaAAAgIAAAAQAgAKgQAABOIwAAMDAAAAEACACoDgAA9jMAADAw + AAABACAAqCUAAJ5CAAAoAAAAEAAAACAAAAABAAgAAAAAAEABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP// + /wDTix4AAAnjAIOIvgDUx7MAOUmzALmVcAC0uvUAAACeAKinpQDb3ukAYm7eAGFoqgAaKcYAzmoCAJOd + 2wDo3cgA46ItAPLv6gC7u7kAAAbIAHN3rwDHcBcA1c/IAL6lfgDOuqMA//3jAJGWyAApNsIA1Zc2AF1w + ywDAk18A1dbZADpGxQDP1PEAr7CyANB9EQDc2r0AR1GzAObh3gDFpnEA/fnxANiYKAC4t6oA5OjsAODb + 0wBaYrMAVGrRAOrv9ADQdQYAh5TOALGuogD09fcA7erfAAARygC0uOoAymoMAMG/sQDQ2eIA040oANSE + FwDZnS8A3t7dANjV0QD5+f8A4OLkAK2tqQDOdg4A6+zrAPf17wACB54As7KrAMhwDwDLcQgA//32AGRw + 2ADo5+cAAAXeANSTJgDW2+EA/fvrALm4tADYnDUAHSzKANGAGgD89ewA297iAM5vAADNawcA0oYdAPv6 + 9wDPfRYA3NjSANOPIQDu7/EA4uboAKmrqwD7/PwA1ZArANGBFQDbnCsA///6AP//8gDUiCEA6+jkANLX + 3AD29OsA1Zw4ANB5EgDY1tUA3NnBAKyusACnqKkA1ZcqANeaKwDq6ugAPEuzANXZ3ADY2NgA3NbPANjT + zgDKbAgAyWsPANbQywDWzsUA0ocaAPz47QDl6OkA4uXrAMxrBAD79/IA+PftALi3rQCzsq4A/f3/AP39 + +gDs7OgA0X4VAP7+/ADZmSoA2pstAKyspwDObAEAymoJAPj18QDc1tEA2NbTAK2tqwDZnTQA2JoqAOrs + 6gDm6OgA2t7jANfY2QDd2dIA3dfSANbNxgD///4A///5ANmZKQDXmioA3NfSANzX0QDBv7IAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAACAyWI8PglmQOXsXBwAAAABcGCGabpN5fJ19GkkAAAAAJUBXJJRxYXB2O6J6 + AAAAAGQuQo5BCVEKd2qSSgAAAAA9KJgsDiInND9QkkQAAAAAfmmJTHUmNw02mZJtAAAAAAITRTiEhAsD + BICjigAAAABeRl8UUkOkMzCXolUAAAAAT5E1hodHZ0hNYJxaAAAAAHKDYjpUHS+FdIFdaAAAAABzW54M + Bm8VFmstmzwAAAAAoYgBCGafI04cMXhjAAAAAJVWi0sqfxsQHxEFHgAAAAApPqArloxlElONbBkAAAAA + AAAAAAAAAAAAAAAAAAD//wAAwAMAAMADAADAAwAAwAMAAMADAADAAwAAwAMAAMADAADAAwAAwAMAAMAD + AADAAwAAwAMAAMADAAD//wAAKAAAABAAAAAgAAAAAQAgAAAAAABABAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAANJ7FIPSdQX80HAA/tBtAP3RawD7z2sA+NBpAPTOaADxzmYA7c1mAOnNaADdzWoEXQAA + AAAAAAAAAAAAAAAAAADTewvt1c/I/9XW2f/X2Nn/2NbV/9jW0//Y087/1tDL/9bNxv/WzsX/zrqj/81s + AOgAAAAAAAAAAAAAAAAAAAAA1HwJ8djV0f/b3uL/r7Cy/62tq/+nqKn/qaur/6yusP/V2dz/0Nni/9zX + 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 + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADggRRN0XoUudF5E9zReRPU0XkSv9B4 + EqrReBGS0HcQftF2D2XPdQ9Qz3QMO9NwECLNbgARAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOmLGHzTfRf+0nwX/9J7 + Ff/RehT/0XoU/9F5E//ReRP/0XgS/9F3Ef/QdxH/0HYQ/892D/7RdhD93HsP9d97Dt/deg3K3HoNstx5 + DJ3eeQyF3nYJcNp4CFvaeAdC2nIFLeF3ABfuXAAGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3YQYN9V/ + GfzSfhj/0n0X/9J8Ff/SfBX/0nsU/9F6FP/RehT/0XkT/9F5E//ReBL/0XcR/9B3Ef/QdhD/0HUP/9B1 + D//QdA7/z3MN/89zDf/Pcgz/z3IM/89xC//OcAr/znAL/s5uCv3OcAn42XUH6tt0CNDccwa823QHpdpy + BozbcAJX/GkACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA038ZntN/Gf/Tfxn/030U/9KNOf/Rizb/0YMj/9F8Ff/ReAz/0XYK/9F3DP/Rdgv/0XcN/9J2 + DP/QdQ3/0HYO/9B1Dv/QdQ7/0HUP/9B0Dv/Pcw3/z3MN/89yDP/PcQv/z3EL/85wCv/OcAr/zm8J/85u + CP/Obgj/zm0H/81sBv/NbQf+zm0E3eF0BjEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA04EbztOBG//TgBn/04ku/9La4//P1Nr/zNDW/8zP0//My8r/zMS6/828 + qP/Ns5X/zquE/86jcP/Om1//z5JM/8+KOv/PgSb/z3kV/890Cf/PcQT/0XAE/89wBP/PcAb/z3AG/89v + Bf/PcAf/zm8H/85wCf/Obwj/zm4I/85uCP/ObQf/zWwG/89sBejYbAAZAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1IId09SCHP/TgBn/1JA6/9TZ3//R0dH/zs7O/8zM + zP/MzM3/zMzN/8zNzv/Mzc//zM7R/8zO0v/Mz9P/zM/U/8zQ1v/Mz9b/zNHV/8zOz//MxsL/zL+v/821 + nP/NrYj/zaR3/82bYv/NklH/zog8/85/Kf/OdhX/znAH/85rAf/Obgb/zm4I/85tB//ObQaTAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1IMe09SDHf/Ugxz/1JA7/9ba + 4f/V1dX/19fX/9XV1f/U1NT/09PT/9TU1P/T09P/0tLS/9HR0f/Q0ND/z8/P/8/Pz//Nzc3/zMzM/8zM + zP/MzM3/zM3O/8zNz//MztD/zM7S/8zP0//M0NT/zNDV/8zS1//M0df/zNDU/8zAtP/OdBH/zm8I/85u + CP/ObgfgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1IQf09SE + Hv/Ugxz/1ZM8/9re5P/X19f/19fX/9fX1//X19f/19fX/9jY2P/Z2dn/x8fH/8HBwf/Gxsb/ycnJ/87O + zv/T09P/1dXV/9bW1v/W1tb/1dXV/9PT0//R0dH/z8/P/87Ozv/Ozs7/zc3N/83Nzf/MzMz/zM3N/8zS + 1//NklH/zm8H/85vCf/Obwn8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA1IYg09WGIP/VhB3/1pM+/9zg5v/Z2dn/2NjY/9jY2P/Y2Nj/2NjY/9ra2v++vr7/k5OT/5KS + kv+SkpL/kpKS/5KSkv+Tk5P/lJSU/5aWlv+ampr/n5+f/7Gxsf/U1NT/09PT/9HR0f/S0tL/0NDQ/8/P + z//Q0ND/zc3N/8zQ1P/NlFP/0G8H/89xC//Obwr9AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA1Ych09WHIf/VhR7/15Y//97i6P/a2tr/2dnZ/9nZ2f/Z2dn/2dnZ/9zc + 3P+tra3/pKSk//f39//r6+v/5OTj/9/f3v/CwsL/t7e2/8nJyf/AwMD/t7e3/5OTk/++vr7/1NTU/9LS + 0v/S0tL/0dHR/9DQ0P/Pz8//zs7O/8zP1P/OlVT/z3IJ/89yDP/OcAv9AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1Ygj09WIIv/Vhh//15ZB/+Hm6//c3Nz/29vb/9vb + 2//a2tr/2tra/93d3f+vr6//o6Oj///////6+vr////9/5aW1v9dXaj/u7q2//7+/v/9/f3//Pz8/5OT + k/+5ubn/1tbW/9PT0//T09P/0tLS/9HR0f/Q0ND/zs7O/8zP1P/OlFX/0XIK/89zDf/Ocgz9AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1Ykk09aJI//WiSH/2JlC/+Pn + 7f/d3d3/3Nzc/9zc3P/c3Nz/29vb/97e3v+urq7/o6Oj//v7+//4+Pf/9vf2/wIHpP8AAqP/pqaq/9PT + 0f/5+fn/+Pj4/5OTk/+7u7v/19fX/9TU1P/T09P/09PT/9LS0v/R0dH/z8/P/8zP1P/OlVX/0HML/9B0 + Dv/Pcw79AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA14ol09aK + JP/WiSL/2ZlD/+Xp7//f39//3d3d/93d3f/d3d3/3d3d/9/f3/+wsLD/o6Oj//v7+/////n/W2DG/wAA + p/8AA6n/Oj+q/7Gwqf/v7+7/9/f3/5OTk/+6urr/2NjY/9XV1f/U1NT/1NTU/9PT0//S0tL/z8/P/8zP + 1P/Pllb/0HQM/9B2EP/PdA/9AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA14wm1NaMJv/WiiP/2ptG/+fr8f/h4eH/3t7e/97e3v/e3t7/3t7e/+Hh4f+vr6//pKSk//7+ + +v/CxOX/AACt/wAJr/8ACq//AAGv/4eIq/+9vLn/+fn5/5OTk/+8vLz/2dnZ/9bW1v/V1dX/1dXV/9TU + 1P/T09P/0NDQ/8zP1P/Pl1f/0ncO/9B3Ef/QdRD9AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA1o0m2NeNJ//XiyT/26BO/+vv9P/i4uL/39/f/9/f3//f39//39/f/+Li + 4v+xsbH/pKSj//n59/8RHrr/AAm1/wwatP8ADrT/AAq1/xIfs/+tq6X/2NjX/5WVlf+7u7v/2tra/9fX + 1//W1tb/1dXV/9XV1f/U1NT/0NDQ/8zP1P/PmVf/0XgP/9F4Ev/QdxH9AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA2I4o2NeOKP/XjCX/3KJQ/+zx9v/k5OT/4eHh/+Dg + 4P/g4OD/4ODg/+Pj4/+xsbD/rq6k/1hj0v8ACbr/AAe7/3+Dtv9/h9b/AAe6/wAKvP9UXbH/sLCp/5OT + k/+9vb3/29vb/9jY2P/X19f/1tbW/9bW1v/V1dX/0dHR/8zP1P/Pl1P/0XkQ/9F5E//QeBL6AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA2JAq2NiPKf/Xjif/3aJQ//D0 + +v/l5eX/4uLi/+Li4v/h4eH/4eHh/+Tk5P+2ta//X2ep/wALwv8AD8L/Jja4/+7t4v/7+/P/FifG/wAQ + wf8AD8L/kJOq/3V1cf+/v7//3d3d/9nZ2f/Y2Nj/19fX/9bW1v/X19f/0dHR/8zP1P/PllL/03oS/9F7 + Ff/RehP4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA2JEr2NiR + K//Yjyj/3qVT//L2+//n5+f/4+Pj/+Pj4//j4+P/4uLi/+jn5P+UmL3/AA/G/wAVyP8AFMP/tre//+jo + 5v/q6ub/uL3g/wANyP8AFMj/FirE/2ppYv+qqqn/3t7e/9ra2v/Z2dn/2NjY/9fX1//W1tb/0tLS/8zP + 1P/Ql1L/0nsT/9J8Fv/RexX4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA2ZIs2NiSLP/YkCj/3qVT//X5///p6en/5OTk/+Tk5P/k5OT/5OTk/+rq5P9seNj/ABLM/wAR + zv9WXY3/mJiS/5KSkv+SkpL/m5mR/z5Ms/8AFM3/ABbP/y07oP+Tkon/1NTT/9zc3P/a2tr/2dnZ/9jY + 2P/X19f/0tLS/8zP1P/QmFP/0n0V/9J9F//RfBb4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA2ZMu2NmTLf/YkSn/36hW//f7///r6+v/5eXl/+Xl5f/l5eX/5eXl/+vq + 5v+fp9//AAvS/1FgwP/Z2M7/z8/O/8rKyv/IyMj/xsbF/8jHwv8ULNT/ABnS/wAW1f9yeqr/pqWg/9zc + 3P/c3Nz/2tra/9nZ2f/Y2Nj/09PT/8zP1P/QmVT/1H4W/9R+GP/SfRf4AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA2ZQv2NmULv/Zkyz/4KhW//n9///s7Oz/5ubm/+bm + 5v/m5ub/5ubm/+jo5v/M0eT/N07b/+ro3//n5+b/5OTk/+Xl5f/k5OT/5OTk/+jn4/+4vt//ABXY/wAc + 2f8AHtf/jY+e/66uq//f397/2tra/9ra2v/a2tr/09PT/8zP0//SmlX/038X/9OAGv/Sfxj4AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA2pUw2NmVL//ZlCz/4KtY//3/ + ///u7u7/6Ojo/+jo6P/n5+f/5+fn/+fn5//o5+b/5ubn/+jo5//l5eX/5eXl/+Tk5P/j4+P/4+Pj/+Li + 4v/s6uH/cYHf/wAZ3f8AH97/EC/X/5mYmf+ysrD/3d3d/9ra2v/Z2dn/1dXV/8zP0//Rmlf/1YEZ/9OB + G//SgBn4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA2pcx2NqX + Mf/alS3/4qtb///////v7+//6enp/+np6f/p6en/6Ojo/+jo6P/p6en/6Ojo/+jo6P/n5+f/5+fn/+bm + 5v/l5eX/5eXl/+Tk5P/k4+P/7ezh/yxK4v8AIOT/ACHl/xo51/+ampX/2NjY/9vb2//a2tr/1NTU/8zP + 0//Rm1b/1IIa/9SCHP/TgRv4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA2pgy2NqYMv/ali7/4axc///////x8fH/6urq/+rq6v/q6ur/6urq/+np6f/s7Oz/4+Pj/+Dg + 4P/e3t7/39/f/93d3f/f39//4ODg/9/f3//g4OD/5OTh/9zf5v8GLer/ACXq/wAg7v+VlZr/2NjX/93d + 3f/c3Nz/1NTU/8zO0//RnFf/1IMb/9SDHf/Tghz4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA2pkz2NqZM//amDH/4a1b///////z8/P/6+vr/+vr6//r6+v/6+vr/+zs + 7P/Ly8v/kpKS/5GRkf+RkZH/kZGR/5KSkv+SkpH/kpKS/5GRkf+RkZH/kpKS/6ioo/+5weT/ACTw/wAj + 9f+SlJz/19bV/93d3f/b29v/1tbW/8zO0//RnVj/1oQc/9SFH//UhB34AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA2po12NuaNP/bmTL/465c///////z8/P/7e3t/+zs + 7P/s7Oz/7Ozs//Dw8P+qqqr/qamp/+bm5v/e3t7/39/e/9nZ3P/AwL7/x8fH/9vb2//W1tb/zMzM/5OT + kv/X1c3/kKHp/wAc+v+eorD/1NTS/97e3v/c3Nz/1dXV/8zO0//Rn1n/1YUd/9WGIP/UhR74AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA25s22NucNv/bmjP/4q9d//// + ///09PT/7u7u/+7u7v/t7e3/7e3t//Hx8f+qqqr/sbGx///////+/v3//////25vyv9zdKv/vr67//// + ///+/v7/8fHx/5GRkf/Pzs7/7+zj/2yF7v/CyeT/3d3b/9/f3//e3t7/1dXV/8zO0//Tnlv/1Ycf/9WH + If/Uhh/4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA25432Nud + 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 + 7v/Gy+j/ABfa/wAe2f8AGtz/dn6x/6emn//e3d3/5OTk/+Hh4f/g4OD/29vb/83Q1f/VpVz/2pMr/9qT + Lf/YkyzxAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3qM96N6k + Pv/eozv/57ps///////8/Pz/+/v7//r6+v/5+fn/+Pj4//n49//j5vT/6u30//f39f/09PT/8fHx//Dw + 8P/v7+//7u7u/+zs7P/19Oz/hpTl/wAZ4P8AIuH/AB/h/3uDr/+op6P/5eXl/+Li4v/g4OD/2tra/8/S + 1//Wpl7/2ZQs/9mULv/YlC3xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA3qM96N6kPv/eozv/57ps///////9/f3//Pz8//v7+//6+vr/+fn5//j4+P/39/b/9vb1//T0 + 9P/z8/P/8vLy//Dw8P/v7+//7u7u/+3t7f/s7Ov/9vbq/0hi5v8AIOX/ACXm/wEn5f+mpZ3/5eXl/+Li + 4v/h4eH/3Nzc/9PW2//XqF//25Ut/9mWMP/YlS7xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA3qM96N6kPv/eozv/57ps///////+/v7//f39//z8/P/7+/v/+vr6//r6 + +v/5+fn/+Pj4//j4+P/4+Pj/+Pj4//j4+P/5+fn/9vb2//b29v/y8vL/8vLw//X07v8fQ+z/ACXr/wAn + 7P+kopz/4+Pj/97e3//b29z/2NjZ/9XY3//YqmL/2pYv/9qXMf/ZljDxAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3qM96N6kPv/eozv/57tu//////////////////// + //////////////////////////////////////////////////////////////z+///5/P//9/n9//f5 + +//i6fj/CTb5/wAp9/+jpqb/5efs/+Hi5f/d3dz/2tjT/9jMvP/amzj/2pkz/9qYMv/amDHYAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3qM92d6kPv/epD3/47FY//// + ///////////////////////////////////++/j//Pbu//nx4f/369b/9uXL//Thv//y2rL/79ao/+zO + mv/pyI3/5sGA/+S7dP/nuGX/w5to/wAs/P/Klj7/2p45/9ydNf/bmi7/25kt/9uZLv/bmzT/25o0/9qZ + M//ZmDOJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3qI9o96k + Pv/epD7/3qM6/+W2Zf/lt2f/47FZ/+GtTv/fp0P/3qQ8/92gNf/dnzL/3aAz/92gNP/doDX/3aE2/92h + Nv/doTf/3qI4/96iOP/doTj/3aI5/92hOf/doTj/46M1/7aOXf/Ynj7/3Z85/9yeOP/cnjj/3J03/9uc + Nv/bnDb/25s1/9ucNuLxpSwSAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA7Ko/P+CmPv3epD7/3qQ+/96kPP/eozz/3qQ8/96kPf/epD3/3qQ+/96kPv/epD7/3qQ+/96k + Pv/epD7/3qQ+/96kPv/epD7/3qQ+/96kPv/epD7/3qQ//92jPf/doz3/3aI8/9+iOv/eojv/3KA6/9yg + Ov/cnzn/3J44/92fOP/cnjj+3p850fasPCYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAPi3RIHfpD7+3qQ//96kPv/epD7/3qQ+/96kPv/epD7/3qQ+/96k + Pv/epD7/3qQ+/96kPv/epD7/3qQ+/96kPv/epD7/3qQ+/92jPf7eoz3+36U+/OuuQffsrkHt7K9B3Oyt + QM/srj/E66w+suytPqftrD6Z6qk9ieqoOnvrpz5F04sABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADtrT5R3qI9wt2jPe/doz3k3aQ91d6k + PcrdpD653aM9rd2jPaLeoz2O3qI9hdyiPHfepj5m3aM8XN2jPUvaoTw/3KY8M+GiPiHSnzUY9aE1CgAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////AAD/gD////8AAP4AAAf//wAA/gAAAAH/ + AAD8AAAAAP8AAPwAAAAAfwAA/AAAAAA/AAD8AAAAAD8AAPwAAAAAPwAA/AAAAAA/AAD8AAAAAD8AAPwA + AAAAPwAA/AAAAAA/AAD8AAAAAD8AAPwAAAAAPwAA/AAAAAA/AAD8AAAAAD8AAPwAAAAAPwAA/AAAAAA/ + AAD8AAAAAD8AAPwAAAAAPwAA/AAAAAA/AAD8AAAAAD8AAPwAAAAAPwAA/AAAAAA/AAD8AAAAAD8AAPwA + AAAAPwAA/AAAAAA/AAD8AAAAAD8AAPwAAAAAPwAA/AAAAAA/AAD8AAAAAD8AAPwAAAAAPwAA/AAAAAA/ + AAD8AAAAAD8AAPwAAAAAPwAA/AAAAAA/AAD8AAAAAD8AAPwAAAAAPwAA/AAAAAA/AAD8AAAAAD8AAPwA + AAAAPwAA/AAAAAA/AAD8AAAAAH8AAP4AAAAA/wAA/gAAAAP/AAD/AAP///8AAP///////wAA + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/CommonObjects/ProcessFilterRuleSection.cs b/Demo_Source_Code/CSharpDemo/CommonObjects/ProcessFilterRuleSection.cs new file mode 100644 index 0000000..bafa3a4 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/CommonObjects/ProcessFilterRuleSection.cs @@ -0,0 +1,233 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Inc. +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Configuration; + +using EaseFilter.FilterControl; + +namespace EaseFilter.CommonObjects +{ + public class ProcessFilterRuleSection : ConfigurationSection + { + [ConfigurationProperty("", IsRequired = true, IsDefaultCollection = true)] + public ProcessFilterRuleCollection Instances + { + get { return (ProcessFilterRuleCollection)this[""]; } + set { this[""] = value; } + } + } + + public class ProcessFilterRuleCollection : ConfigurationElementCollection + { + public ProcessFilterRule this[int index] + { + get { return (ProcessFilterRule)BaseGet(index); } + set + { + if (BaseGet(index) != null) + { + BaseRemoveAt(index); + } + BaseAdd(index, value); + } + } + + public void Add(ProcessFilterRule ProcessFilterRule) + { + BaseAdd(ProcessFilterRule); + } + + public void Clear() + { + BaseClear(); + } + + public void Remove(ProcessFilterRule ProcessFilterRule) + { + BaseRemove(ProcessFilterRule.ProcessNameFilterMask + ProcessFilterRule.ProcessId); + } + + public void RemoveAt(int index) + { + BaseRemoveAt(index); + } + + public void Remove(string name) + { + BaseRemove(name); + } + + protected override ConfigurationElement CreateNewElement() + { + return new ProcessFilterRule(); + } + + protected override object GetElementKey(ConfigurationElement element) + { + return ((ProcessFilterRule)element).ProcessNameFilterMask + ((ProcessFilterRule)element).ProcessId; + } + } + + public class ProcessFilterRule : ConfigurationElement + { + + /// + /// the process name filter mask, i.e. "notepad.exe","c:\\windows\\*.exe" + /// + [ConfigurationProperty("processNameFilterMask", IsKey = true, IsRequired = true)] + public string ProcessNameFilterMask + { + get { return (string)base["processNameFilterMask"]; } + set { base["processNameFilterMask"] = value; } + } + + /// + /// The process Id here is to control the file access. + /// + [ConfigurationProperty("processId",IsRequired = false)] + public string ProcessId + { + get { return (string)base["processId"]; } + set { base["processId"] = value; } + } + + + /// + /// if the file path matches the includeFileFilterMask and the excludeProcessNames is not empty, + /// the IOs from the process name which matches the excludeProcessNames will be skipped by filter driver. + /// seperate the multiple items with ';' + /// + [ConfigurationProperty("excludeProcessNames", IsRequired = false)] + public string ExcludeProcessNames + { + get { return (string)base["excludeProcessNames"]; } + set { base["excludeProcessNames"] = value; } + } + + /// + /// if the file path matches the includeFileFilterMask and the excludeUserNames is not empty, + /// the IOs from the user name which matches the excludeUserNames will be skipped by filter driver. + /// seperate the multiple items with ';' + /// + [ConfigurationProperty("excludeUserNames", IsRequired = false)] + public string ExcludeUserNames + { + get { return (string)base["excludeUserNames"]; } + set { base["excludeUserNames"] = value; } + } + + /// + /// The file access rights to the processes which match the processNameFilterMask + /// the format is "FileMask!accessFalg;" e.g. "c:\sandbox\*!12356;" + /// + [ConfigurationProperty("fileAccessRights", IsRequired = false)] + public string FileAccessRights + { + get { return (string)base["fileAccessRights"]; } + set { base["fileAccessRights"] = value; } + } + + /// + /// The control flag to to the processes which match the processNameFilterMask + /// + [ConfigurationProperty("controlFlag", IsRequired = false)] + public uint ControlFlag + { + get { return (uint)base["controlFlag"]; } + set { base["controlFlag"] = value; } + } + + public ProcessFilterRule Copy() + { + ProcessFilterRule dest = new ProcessFilterRule(); + dest.ProcessId = ProcessId; + dest.ProcessNameFilterMask = ProcessNameFilterMask; + dest.ExcludeProcessNames = ExcludeProcessNames; + dest.ExcludeUserNames = ExcludeUserNames; + dest.FileAccessRights = FileAccessRights; + dest.ControlFlag = ControlFlag; + + return dest; + } + + public ProcessFilter ToProcessFilter() + { + ProcessFilter processFilter = new ProcessFilter(ProcessNameFilterMask); + + processFilter.FilterType = FilterAPI.FilterType.PROCESS_FILTER; + + if (ProcessId.Trim().Length > 0) + { + processFilter.ProcessId = uint.Parse(ProcessId); + } + else + { + processFilter.ProcessId = 0; + } + + string[] excludeProcessNames = ExcludeProcessNames.Split(new char[] { ';' }); + if (excludeProcessNames.Length > 0) + { + foreach (string excludeProcessName in excludeProcessNames) + { + if (excludeProcessName.Trim().Length > 0) + { + processFilter.ExcludeProcessNameList.Add(excludeProcessName); + } + } + } + + string[] excludeUserNames = ExcludeUserNames.Split(new char[] { ';' }); + if (excludeUserNames.Length > 0) + { + foreach (string excludeUserName in excludeUserNames) + { + if (excludeUserName.Trim().Length > 0) + { + processFilter.ExcludeUserNameList.Add(excludeUserName); + } + } + } + + processFilter.ProcessNameFilterMask = ProcessNameFilterMask; + processFilter.ControlFlag = ControlFlag; + + string[] fileAccessRights = FileAccessRights.Split(new char[] { ';' }); + if (fileAccessRights.Length > 0) + { + foreach (string fileAccessRight in fileAccessRights) + { + if (fileAccessRight.Trim().Length > 0) + { + string fileNamFilterMask = fileAccessRight.Substring(0, fileAccessRight.IndexOf('!')); + uint accessFlags = uint.Parse(fileAccessRight.Substring(fileAccessRight.IndexOf('!') + 1)); + processFilter.FileAccessRights.Add(fileNamFilterMask, accessFlags); + } + } + } + + return processFilter; + } + + } + + +} diff --git a/Demo_Source_Code/CSharpDemo/CommonObjects/ProcessFilterSetting.Designer.cs b/Demo_Source_Code/CSharpDemo/CommonObjects/ProcessFilterSetting.Designer.cs new file mode 100644 index 0000000..2f3abac --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/CommonObjects/ProcessFilterSetting.Designer.cs @@ -0,0 +1,207 @@ +namespace EaseFilter.CommonObjects +{ + partial class ProcessFilterSetting + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ProcessFilterSetting)); + this.groupBox_AccessControl = new System.Windows.Forms.GroupBox(); + this.button_Save = new System.Windows.Forms.Button(); + this.groupBox2 = new System.Windows.Forms.GroupBox(); + this.button_SelectPid = new System.Windows.Forms.Button(); + this.textBox_ProcessId = new System.Windows.Forms.TextBox(); + this.radioButton_Name = new System.Windows.Forms.RadioButton(); + this.radioButton_Pid = new System.Windows.Forms.RadioButton(); + this.label2 = new System.Windows.Forms.Label(); + this.textBox_ControlFlag = new System.Windows.Forms.TextBox(); + this.label17 = new System.Windows.Forms.Label(); + this.button_SelectControlFlag = new System.Windows.Forms.Button(); + this.textBox_ProcessName = new System.Windows.Forms.TextBox(); + this.groupBox_AccessControl.SuspendLayout(); + this.groupBox2.SuspendLayout(); + this.SuspendLayout(); + // + // groupBox_AccessControl + // + this.groupBox_AccessControl.Controls.Add(this.button_Save); + this.groupBox_AccessControl.Controls.Add(this.groupBox2); + this.groupBox_AccessControl.Dock = System.Windows.Forms.DockStyle.Fill; + this.groupBox_AccessControl.Location = new System.Drawing.Point(0, 0); + this.groupBox_AccessControl.Name = "groupBox_AccessControl"; + this.groupBox_AccessControl.Size = new System.Drawing.Size(537, 246); + this.groupBox_AccessControl.TabIndex = 26; + this.groupBox_AccessControl.TabStop = false; + // + // button_Save + // + this.button_Save.BackColor = System.Drawing.SystemColors.GradientActiveCaption; + this.button_Save.DialogResult = System.Windows.Forms.DialogResult.OK; + this.button_Save.Location = new System.Drawing.Point(376, 195); + this.button_Save.Name = "button_Save"; + this.button_Save.Size = new System.Drawing.Size(147, 23); + this.button_Save.TabIndex = 85; + this.button_Save.Text = "Save Process Filter Rule"; + this.button_Save.UseVisualStyleBackColor = false; + this.button_Save.Click += new System.EventHandler(this.button_Save_Click); + // + // groupBox2 + // + this.groupBox2.Controls.Add(this.button_SelectPid); + this.groupBox2.Controls.Add(this.textBox_ProcessId); + this.groupBox2.Controls.Add(this.radioButton_Name); + this.groupBox2.Controls.Add(this.radioButton_Pid); + this.groupBox2.Controls.Add(this.label2); + this.groupBox2.Controls.Add(this.textBox_ControlFlag); + this.groupBox2.Controls.Add(this.label17); + this.groupBox2.Controls.Add(this.button_SelectControlFlag); + this.groupBox2.Controls.Add(this.textBox_ProcessName); + this.groupBox2.Location = new System.Drawing.Point(6, 12); + this.groupBox2.Name = "groupBox2"; + this.groupBox2.Size = new System.Drawing.Size(517, 161); + this.groupBox2.TabIndex = 76; + this.groupBox2.TabStop = false; + // + // button_SelectPid + // + this.button_SelectPid.Location = new System.Drawing.Point(463, 19); + this.button_SelectPid.Name = "button_SelectPid"; + this.button_SelectPid.Size = new System.Drawing.Size(41, 20); + this.button_SelectPid.TabIndex = 102; + this.button_SelectPid.Text = "..."; + this.button_SelectPid.UseVisualStyleBackColor = true; + this.button_SelectPid.Click += new System.EventHandler(this.button_SelectPid_Click); + // + // textBox_ProcessId + // + this.textBox_ProcessId.Location = new System.Drawing.Point(202, 19); + this.textBox_ProcessId.Name = "textBox_ProcessId"; + this.textBox_ProcessId.Size = new System.Drawing.Size(242, 20); + this.textBox_ProcessId.TabIndex = 101; + this.textBox_ProcessId.Text = "0"; + // + // radioButton_Name + // + this.radioButton_Name.AutoSize = true; + this.radioButton_Name.Location = new System.Drawing.Point(8, 51); + this.radioButton_Name.Name = "radioButton_Name"; + this.radioButton_Name.Size = new System.Drawing.Size(134, 17); + this.radioButton_Name.TabIndex = 100; + this.radioButton_Name.Text = "Filter By Process Name"; + this.radioButton_Name.UseVisualStyleBackColor = true; + this.radioButton_Name.Click += new System.EventHandler(this.radioButton_Name_Click); + // + // radioButton_Pid + // + this.radioButton_Pid.AutoSize = true; + this.radioButton_Pid.Checked = true; + this.radioButton_Pid.Location = new System.Drawing.Point(8, 19); + this.radioButton_Pid.Name = "radioButton_Pid"; + this.radioButton_Pid.Size = new System.Drawing.Size(114, 17); + this.radioButton_Pid.TabIndex = 99; + this.radioButton_Pid.TabStop = true; + this.radioButton_Pid.Text = "Filter by Process Id"; + this.radioButton_Pid.UseVisualStyleBackColor = true; + this.radioButton_Pid.Click += new System.EventHandler(this.radioButton_Pid_Click); + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(199, 72); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(209, 13); + this.label2.TabIndex = 90; + this.label2.Text = "( i.e. c:\\testfolder\\*.exe or \'notepad.exe\' )"; + // + // textBox_ControlFlag + // + this.textBox_ControlFlag.Location = new System.Drawing.Point(201, 95); + this.textBox_ControlFlag.Name = "textBox_ControlFlag"; + this.textBox_ControlFlag.ReadOnly = true; + this.textBox_ControlFlag.Size = new System.Drawing.Size(242, 20); + this.textBox_ControlFlag.TabIndex = 73; + this.textBox_ControlFlag.Text = "0"; + // + // label17 + // + this.label17.AutoSize = true; + this.label17.Location = new System.Drawing.Point(6, 95); + this.label17.Name = "label17"; + this.label17.Size = new System.Drawing.Size(142, 13); + this.label17.TabIndex = 72; + this.label17.Text = "Process Access Control Flag"; + // + // button_SelectControlFlag + // + this.button_SelectControlFlag.Location = new System.Drawing.Point(463, 95); + this.button_SelectControlFlag.Name = "button_SelectControlFlag"; + this.button_SelectControlFlag.Size = new System.Drawing.Size(41, 20); + this.button_SelectControlFlag.TabIndex = 74; + this.button_SelectControlFlag.Text = "..."; + this.button_SelectControlFlag.UseVisualStyleBackColor = true; + this.button_SelectControlFlag.Click += new System.EventHandler(this.button_SelectControlFlag_Click); + // + // textBox_ProcessName + // + this.textBox_ProcessName.Location = new System.Drawing.Point(201, 49); + this.textBox_ProcessName.Name = "textBox_ProcessName"; + this.textBox_ProcessName.ReadOnly = true; + this.textBox_ProcessName.Size = new System.Drawing.Size(242, 20); + this.textBox_ProcessName.TabIndex = 77; + this.textBox_ProcessName.Text = "notepad.exe"; + // + // ProcessFilterSetting + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(537, 246); + this.Controls.Add(this.groupBox_AccessControl); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Name = "ProcessFilterSetting"; + this.Text = "Process Filter Rule Setting"; + this.groupBox_AccessControl.ResumeLayout(false); + this.groupBox2.ResumeLayout(false); + this.groupBox2.PerformLayout(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.GroupBox groupBox_AccessControl; + private System.Windows.Forms.GroupBox groupBox2; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.TextBox textBox_ControlFlag; + private System.Windows.Forms.Label label17; + private System.Windows.Forms.Button button_SelectControlFlag; + private System.Windows.Forms.TextBox textBox_ProcessName; + private System.Windows.Forms.Button button_SelectPid; + private System.Windows.Forms.TextBox textBox_ProcessId; + private System.Windows.Forms.RadioButton radioButton_Name; + private System.Windows.Forms.RadioButton radioButton_Pid; + private System.Windows.Forms.Button button_Save; + } +} \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/CommonObjects/ProcessFilterSetting.cs b/Demo_Source_Code/CSharpDemo/CommonObjects/ProcessFilterSetting.cs new file mode 100644 index 0000000..593d6a3 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/CommonObjects/ProcessFilterSetting.cs @@ -0,0 +1,131 @@ +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; + +using EaseFilter.FilterControl; + +namespace EaseFilter.CommonObjects +{ + public partial class ProcessFilterSetting : Form + { + public ProcessFilterRule selectedFilterRule = null; + + public ProcessFilterSetting() + { + StartPosition = FormStartPosition.CenterParent; + InitializeComponent(); + + InitSelectedFilterRule(); + } + + private void InitSelectedFilterRule() + { + if (GlobalConfig.ProcessFilterRules.Count > 0) + { + foreach (ProcessFilterRule processRule in GlobalConfig.ProcessFilterRules.Values) + { + selectedFilterRule = processRule; + break; + } + } + + if (null == selectedFilterRule) + { + selectedFilterRule = new ProcessFilterRule(); + selectedFilterRule.ProcessNameFilterMask = "*"; + selectedFilterRule.ControlFlag = 770; + } + + if (selectedFilterRule.ProcessId.Length > 0 && selectedFilterRule.ProcessId != "0" ) + { + textBox_ProcessId.Text = selectedFilterRule.ProcessId; + radioButton_Pid_Click(null,null); + } + else + { + radioButton_Name_Click(null, null); + textBox_ProcessName.Text = selectedFilterRule.ProcessNameFilterMask; + textBox_ControlFlag.Text = selectedFilterRule.ControlFlag.ToString(); + } + } + + private void button_SelectControlFlag_Click(object sender, EventArgs e) + { + OptionForm optionForm = new OptionForm(OptionForm.OptionType.ProcessControlFlag, textBox_ControlFlag.Text); + + if (optionForm.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + textBox_ControlFlag.Text = optionForm.ProcessControlFlag.ToString(); + } + } + + private void radioButton_Pid_Click(object sender, EventArgs e) + { + radioButton_Pid.Checked = true; + textBox_ProcessName.ReadOnly = true; + textBox_ProcessId.ReadOnly = false; + button_SelectPid.Enabled = true; + } + + private void radioButton_Name_Click(object sender, EventArgs e) + { + radioButton_Name.Checked = true; + textBox_ProcessName.ReadOnly = false; + textBox_ProcessId.ReadOnly = true; + textBox_ProcessId.Text = "0"; + button_SelectPid.Enabled = false; + } + + private void button_SelectPid_Click(object sender, EventArgs e) + { + OptionForm optionForm = new OptionForm(OptionForm.OptionType.ProccessId, textBox_ProcessId.Text); + + if (optionForm.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + if (optionForm.ProcessId.Length > 0) + { + textBox_ProcessId.Text = optionForm.ProcessId; + + //we choose to use process Id instead of the process name + textBox_ProcessName.Text = ""; + } + } + } + + + + private void button_Save_Click(object sender, EventArgs e) + { + if (textBox_ProcessId.Text.Trim().Length > 0 && textBox_ProcessId.Text != "0") + { + //please note that the process Id will be changed when the process launch every time. + selectedFilterRule.ProcessId = textBox_ProcessId.Text; + selectedFilterRule.ProcessNameFilterMask = ""; + } + else if (textBox_ProcessName.Text.Trim().Length > 0) + { + selectedFilterRule.ProcessId = ""; + selectedFilterRule.ProcessNameFilterMask = textBox_ProcessName.Text; + } + else + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("The process name mask and Pid can't be null.", "Add Filter Rule", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + uint controlFlag = 0; + uint.TryParse(textBox_ControlFlag.Text, out controlFlag); + selectedFilterRule.ControlFlag = controlFlag; + + GlobalConfig.AddProcessFilterRule(selectedFilterRule); + + } + + } +} diff --git a/Demo_Source_Code/CSharpDemo/CommonObjects/ProcessFilterSetting.resx b/Demo_Source_Code/CSharpDemo/CommonObjects/ProcessFilterSetting.resx new file mode 100644 index 0000000..acfec18 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/CommonObjects/ProcessFilterSetting.resx @@ -0,0 +1,408 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + AAABAAEAQEAAAAEAIAAoQgAAFgAAACgAAABAAAAAgAAAAAEAIAAAAAAAAEAAABMLAAATCwAAAAAAAAAA + AAAaEmMAFxFfAxkSYQ0cEmY4HRJngh0SZ7kcEmfYHBJn7hwSZ/ocEmf/HBJn/xwSZ/8cEmf/HBJn/xwS + Z/8cEmf/HBJn/xwSZ/8cEmf/HBJn/xwSZ/8cEmf/HBJn/xwSZ/8cEmf/HBJn/xwSZ/8cEmf/HBJn/xwS + Z/8cEmj/GxJk/xkRXv8XD1j/Fg5U/xYOUv8XDlP/Fw5T/xcPVP8XD1T/Fw9U/xcPVP8XD1b/Fw9W/xcP + Vv8XD1b/GA9X/xgPV/8YD1j/GA9Y/xgQWf8YEFn/GBBa/xgQWv8ZEFr/GRBa+hgPXO8YD1zcGRBcvhoQ + XIgZEFs8GBBYDxcQVwQYEFkAEg9bAh0SZhQeE2c4HhNnaR4SZ6IdEmfLHRJn4h0SZ/IdEmf7HRJn/x0S + Z/8dEmf/HRJn/x0SZ/8dEmf/HRJn/x0SZ/8dEmf/HRJn/x0SZ/8dEmf/HRJn/x0SZ/8dEmf/HRJn/x0S + Z/8dEmf/HRJn/x0SZ/8dEmf/HBJl/xsRYf8ZEFv/GA9W/xcPU/8XDlL/Fw5T/xcOU/8XD1T/Fw9U/xcP + VP8XD1T/Fw9V/xcPVv8YD1b/GA9W/xgPV/8YD1f/GA9Y/xkPWP8ZEFn/GRBZ/xkQWv8ZEFr/GRBa/xkQ + W/wZEFvzGRBc5RoQXM8aEFymGxFcbBsRXDoaEFsVFA9UAxcRYA0eE2c4HxNojR8TaMcfE2jfHhNo7h4T + aPYeE2j7HhNo/h4TaP8eE2j/HhNo/x4TaP8eE2j/HhNo/x4TaP8eE2j/HhNo/x4TaP8eE2j/HhNo/x4T + aP8eE2j/HhNo/x4TaP8eE2j/HhNo/x4TaP8eE2j/HhJm/xwRYP8aEFv/GRBW/xgPU/8YD1L/GA9S/xgP + U/8YD1P/GA9U/xgPVP8YD1T/GA9U/xgQVf8ZEFX/GRBW/xkQVv8ZEFf/GRBX/xkQWP8aEFj/GhBZ/xoQ + Wf8aEFr/GhBa/xoRW/8aEVv+GhFb+xoRW/cbEVzvGxFc4RwRXcocEV2PGxFcOhcPVw8fE2g4HxNoaR8T + aMcfE2j9HxNo/x8TaP8gE2j/IBNo/yATaP8gE2j/IBNo/yATaP8gE2j/IBNo/yATaP8gE2j/IBNo/yAT + aP8gE2j/IBNo/yATaP8gE2j/IBNo/yATaP8gE2j/IBNp/yATaf8fE2j/HxNm/x0SYv8bEFr/Gg9V/xkO + Uv8YD1H/GA9S/xkPU/8ZD1P/GQ9T/xkPVP8ZD1T/GQ9U/xoPVP8ZEFX/GhBV/xoQVv8aEFb/GhBX/xoQ + V/8aEFj/GxBY/xsQWf8bEFn/GxBa/xsQWv8bEVv/GxFb/xsRW/8cEVv/GxFc/xwRXP8cEV3+HBFdyhwR + XWwbEF08IRRqgiEUaqIhFGrfIBRp/yAUaf8gFGn/IRRp/yEUaf8hFGn/IRRp/yEUaf8hFGn/IRRp/yEU + af8hFGn/IRRp/yEUaf8hFGn/IRRp/yEUaf8hFGn/IRRp/yEUaf8hFGn/IRRp/yEUav8hFGr/IBNn/x4S + Yf8cEVv/Gg9V/xkOUf8ZDlH/GQ5R/xkPUv8aEFP/GhBU/xoQVP8aEFT/GhBU/xoQVf8bEFX/GxBV/xsQ + Vv8bEFb/GxBX/xsRV/8bEVj/GxFY/xwRWf8cEVn/HBFa/xwRW/8cEVv/HBFb/xwRW/8cEVz/HRFc/x0S + XP8dEl3/HRJe/x0SXuEdEV6mHRFfiCIUa7kiFGvLIRRr7iEUa/8hFGv/IRRr/yEUa/8hFGv/IRRr/yEU + a/8hFGv/IRRr/yEUa/8hFGv/IRRr/yEUa/8hFGv/IRRr/yEUa/8hFGv/IRRr/yEUa/8hFGv/IhRr/yIU + a/8hFGr/IRNn/x8SYv8cEFr/GxFY/xsWWv8bGVz/Gxld/xoWWv8aEVT/Gg9S/xoPU/8aEFT/GhBU/xsQ + VP8bEFX/GxBW/xsQVv8bEFf/GxBX/xsQWP8bEVj/HBFZ/xwRWf8cEVr/HBFa/xwRWv8cEVv/HBFb/xwR + W/8dEVv/HRFc/x0RXf8dEl3/HRJe/x0SXv8eEl/vHhJfzx4SX74jFWzZIxVs4yIVbPYiFWz/IhVs/yIV + bP8iFWz/IhVs/yIVbP8iFWz/IhVs/yIVbP8iFWz/IhVs/yIVbP8iFWz/IhVs/yIVbP8iFWz/IhVs/yIV + bP8iFWz/IhVs/yMVbP8jFWz/IhRp/yASYv8dEFr/Gw5T/xsWWf8dJmz/HjB3/x4weP8dJm3/GxZa/xoN + UP8bDlL/GxBU/xsQVP8cEVX/HBFW/xwRVv8cEVf/HBFX/xwRWP8cEVj/HBFZ/x0RWf8dEVr/HRFa/x0S + W/8dElv/HRJb/x4SW/8dElz/HhJc/x4SXf8eEl3/HhJe/x4SXv8eEl//HxJf9h8SYOUfE2DcJBVs7yQV + bPMkFWz7JBVs/yQVbP8kFWz/JBVs/yQVbP8kFWz/JBVs/yQVbP8kFWz/JBVs/yQVbP8kFWz/JBVs/yQV + bP8kFWz/JBVs/yQVbP8kFWz/JBVs/yQVbP8jFGv/IxNo/yEUZf8gGGP/Hhxj/x0jZ/8eMnb/IUeP/yJT + nf8iU53/IUeQ/x8yd/8dImb/HRpf/xwVWv8cEVX/HBBU/xwQVf8cEVb/HBFX/x0RV/8dEVj/HRFY/x0R + Wf8eEVn/HhFa/x4RWv8eElv/HhJb/x4SW/8fElv/HxJc/x4SXP8eEl3/HxJd/x8SXv8fEl7/HxJf/yAS + X/sgE2DzIBNg7yUWbfolFm37JRZt/iUWbf8lFm3/JRZt/yUWbf8lFm3/JRZt/yUWbf8lFm3/JRZt/yUW + bf8lFm3/JRZt/yUWbf8lFm3/JRZt/yUWbf8lFm3/JRZt/yUWbf8lFm3/JBRp/yIRYP8hFmH/ISRs/yE3 + fv8iT5X/I2Sr/yZ2wP8nf8v/J3/L/yZ2wP8kZKv/Ik6T/yA0e/8fIWf/HhRZ/x0PU/8dEFT/HRFW/x0R + V/8eElf/HhJY/x4SWP8eElj/HxJY/x4SWf8fElr/HxJb/x8SW/8fElv/IBJb/yATXP8fE1z/HxNd/yAT + Xf8gE17/IBNe/yATX/8hE1/+IRNg/CETYPonFm3/JxZt/ycWbf8nFm3/JxZt/ycWbf8nFm3/JxZt/ycW + bf8nFm3/JxZt/ycWbf8nFm3/JxZt/ycWbf8nFm3/JxZt/ycWbf8nFm3/JxZt/ycWbf8mFm3/Jhds/yQb + bf8iI27/IjB4/yNEi/8lW6T/JnbA/yiK1f8qluT/K53r/yud6/8qluT/KYnU/yd0vv8kWaL/IkGJ/yEu + dP8fIWb/Hxhe/x8UWf8eElf/HxFW/x8SV/8fElj/HxJY/x8SWP8fEln/IBJa/yASW/8gElv/IBJb/yAS + W/8gE1z/IRNc/yATXf8hE13/IRNe/yETXv8hE1//IhNg/yETYP8hE2D/KBdv/ygXb/8oF2//KBdv/ygX + b/8oF2//KBdv/ygXb/8oF2//KBdv/ygXb/8oF2//KBdv/ygXb/8oF2//KBdv/ygXb/8oF2//KBdv/ygW + bv8oFW7/Jxdt/yUbbP8kLHn/JUiR/yZgqP8ndL3/KIXR/yuU4/8tnu//LqT3/y6n+/8up/v/LqT3/y2e + 7/8rk+L/KIXQ/yZzvP8lX6f/I0aO/yEscv8gG2H/IBNZ/x8RVv8gEVf/IBJY/yASWf8gEln/IBNZ/yAT + Wv8hE1v/IRNb/yETXP8hE1z/IRNd/yITXf8iE17/IhNe/yIUX/8iFF//IhRg/yMUYP8jFGH/IxRh/ygX + b/8oF2//KBdv/ygXb/8oF2//KBdv/ygXb/8oF2//KBdv/ygXb/8oF2//KBdv/ygXb/8oF2//KBdv/ygX + b/8oF2//KRdv/ykWbv8oGXH/KCB2/ycqff8mN4T/Jk6Y/yhtt/8qhtH/K5bi/yyf7f8uoPL/Lpzv/y2S + 5f8tjeD/LY3g/y2S5f8um+//LqDy/yyf7f8qluL/KYXQ/ydtt/8kT5f/IzZ9/yIlbP8hGmD/IBNZ/yAR + V/8gElj/IBJZ/yATWv8hE1r/IRNb/yETW/8hE1z/IRNc/yITXf8iE13/IhNe/yITXv8iFF//IxRf/yMU + YP8jFGD/IxRh/yMUYf8pGHD/KRhw/ykYcP8pGHD/KRhw/ykYcP8pGHD/KRhw/ykYcP8pGHD/KRhw/ykY + cP8pGHD/KRhw/ykYcP8pGHD/KRhw/yoXb/8qFm7/KSB3/yg2iP8oT5z/KGiy/yp+yP8skd7/Lp7t/y6l + 9v8vpPb/L5ns/y2D1f8qY7L/KFGe/yhRnf8pYbD/LYLU/y+Z7P8vpPb/LqX2/y2e7f8skd7/KX/I/ydm + rv8lSJD/Iy51/yEZX/8hEFX/IRFX/yETWf8hE1r/IhNa/yITW/8iE1v/IhRc/yIUXP8iFF3/IxRd/yMU + Xv8jFF7/IxRf/yQUX/8kFWD/JBVg/yQVYf8kFWH/Kxhw/ysYcP8rGHD/Kxhw/ysYcP8rGHD/Kxhw/ysY + cP8rGHD/Kxhw/ysYcP8rGHD/Kxhw/ysYcP8rGHD/Kxhw/ysYcf8qHXX/Kid9/yo7jv8pV6b/KnO//yuN + 1/8tnOn/L6Ly/y+g8v8vluj/LYjZ/yx1xf8pW6j/JjuE/yQpcf8kKXD/JTmD/ylap/8sdcT/LojZ/y+X + 6f8voPL/L6Ly/y2d6f8ri9X/KG23/yZQmf8kNHv/IyJo/yIYXv8iFFr/IhNa/yITWv8iE1v/IxNb/yMU + XP8jFFz/IxRd/yMUXf8jFF7/JBRe/yQUX/8lFF//JRVg/yQVYP8kFWH/JBVh/ywZcf8sGXH/LBlx/ywZ + cf8sGXH/LBlx/ywZcf8sGXH/LBlx/ywZcf8sGXH/LBlx/ywZcf8sGXH/LBhx/ywZcv8sG3P/KyyB/ypL + m/8qaLX/K4HO/yyV4v8uovD/L6X1/zCe8P8vitz/K2u6/yhPm/8lOX//Iyhs/yIeYf8iGVz/Ihhc/yIe + Yv8jKG3/JjmB/ylQnP8sbLv/L4vd/zCe8P8vpfX/LqHw/yyT4P8qfsn/KGOs/yZFjf8lJ23/JBZc/yQU + W/8jE1v/IxRb/yQUXP8kFF3/JBRd/yQUXf8kFF3/JBVe/yUVX/8lFWD/JhVg/yYVYf8mFWH/JRVh/yUV + Yf8vG3T/Lxtz/y4ac/8tGXL/LRly/y0Zcv8tGXL/LRly/y0Zcv8tGXL/LRly/y0Zcv8uGXL/Lhly/y0Z + cv8tIHj/LC+F/yxKnP8rb73/K4vY/y2d6/8vo/L/L5zt/y+P4P8tfMv/K2Kv/ydDjP8kKW//IRdY/yAP + Tv8hEFD/IRFS/yERU/8hEVL/IRBR/yIYW/8lKnH/KEOP/yxjsf8ufc3/L5Di/y+d7v8vo/P/LZ3q/yyJ + 1f8qa7b/KEeP/yYscv8lHGP/JRRb/yQUW/8kFFz/JRRd/yUUXf8lFF3/JRRe/yUVX/8mFV//JhVg/yYV + YP8mFWH/JhVh/yYVYf8nFWH/NSF4/zMfd/8wHHX/Lxpz/y4Zc/8uGXP/Lhlz/y4Zc/8uGXP/Lhlz/y4a + c/8uGnP/Lxlz/y4Zc/8uG3X/LS+F/yxVpf8sdsT/LpHg/y+i8f8wp/j/MJvs/y5+zv8rX6z/J0CH/yUr + bv8jIGP/Ihha/yETU/8hEFD/IRJS/yISU/8iElP/IhJT/yERU/8iFFb/Ixle/yUiZ/8mLXP/KUKL/yxh + sP8vgNH/L53t/y+o+P8vofH/LZDd/yt1wP8pU5v/Jytz/yYWXv8lFVz/JRVc/yYVXf8mFV3/JhVe/yYV + Xv8mFV//JxVf/ycWYP8nFmD/JxZh/ycWYf8nFmL/KBZi/0EugP9ALH//PSl9/zome/85JHr/NyN5/zYh + eP80IHj/Mx53/zIddv8xG3X/MBp0/y8adP8uIXr/Li+H/y1Nof8teMb/LpXi/zCh8P8wn+//Lo/f/yx2 + xP8oVaH/JTV9/yEaXP8fDUz/Hg1M/x4OTv8eD0//Hw9Q/x8QUf8fEFH/HxBS/yAQUv8gEFP/IBBT/yAP + U/8hD1L/IQ5S/yMcYv8nOIP/Klim/y15yf8vkuL/MKDx/zCh8f8uleL/K3fC/ylLlP8nLHT/Jhxk/yYV + XP8mFVz/JhVd/yYVXv8mFV7/JxVf/ycVX/8nFmD/JxZg/ycWYf8oFmH/KBZi/ygWYv9UQoz/VEGM/1JA + i/9QPYr/TTmH/0k1hf9EMYL/QC1//z0off85JHr/NR94/zEcdv8wHHb/LjCG/y1WqP8tecj/L5bl/zCi + 8f8xm+z/LoLR/ylZo/8lOoD/Iidr/yAZW/8eEFD/HQxM/x0NTP8dDU3/HQ5O/x0OT/8eDk//Hg5Q/x4O + UP8fD1H/Hw9S/yAPUv8fD1L/Hw5S/yAOUv8hElj/Ixxj/yUqc/8oPon/K12r/y+F1v8xne//MKPy/y6W + 5P8secT/KlWe/ycsdP8mF17/JxVd/ycVXf8nFl7/JxZe/ycWX/8oFl//KBZg/ygWYP8oFmH/KRZh/ykX + Yv8pF2L/X02T/19Nk/9eTZP/XUuS/1pHkP9WQ43/UT+L/047iP9KNob/RjGD/0IsgP8+LYH/OzaJ/zhR + of81fMj/M5jk/zKh8P8wl+b/LHrJ/yxcpP8xPnz/NjBm/zswYv9BNGT/Rjtq/0tAcP9PRHP/UUZ1/1NI + d/9USXn/VUl5/1NIeP9RRXb/T0R1/09DdP9PRHX/UkZ3/1JGd/9PQ3b/Sz9x/0Y4bP89MGn/MSpr/yw5 + gf8tXqz/L3/P/zGZ6v8xovH/L5fk/yx5xP8qSZL/KClx/ygaYv8nFFz/JxVd/ygWX/8oFl//KBZf/ygW + YP8pFmH/KRZh/yoWYv8qF2L/KRdi/2BPlf9gT5X/YE6V/2BOlP9fTZT/XkuT/1xKkv9bSZH/WkeQ/1lF + j/9XQ43/VU2X/1Fmrf9Mgsj/RZ/l/z6n8P83mOX/LnbC/yVEi/8uM2//SEVw/2BZeP90bYX/hYCU/5aT + pP+iobH/rKq5/7Oxv/+4t8X/vLrI/726yf+6t8b/s7HA/62ru/+pprb/qqe3/7GtvP+wrbz/qaa1/52a + qv+MiJv/cGmH/0tAcP8zLGr/LDB3/ytLl/8wesn/Mpjo/zGj8f8wleL/LnG8/yxKlP8pJW7/KBNb/ygV + Xf8pFl//KRdg/yoXYP8qF2H/Khdh/yoXYv8rF2L/Kxdj/ysXY/9iUJb/YlCW/2JQlv9iUJb/YlCW/2JQ + lv9iUJb/Y1CW/2NQlv9jUZb/Y1OY/2Fnqv9ei8r/WaTj/1Ow8f9Mpun/RIjL/0Jop/9GS3//V010/3Vv + hv+KiJX/lpSd/6Cgp/+rrLL/tLW7/7q7wf++vsX/wMDI/8jIz//U1tj/3N/e/9/i4P/W2dn/w8bI/7m6 + wP+5uMH/t7W//7Kxuf+rrLP/o6Sq/5GQnf92b4z/Wk56/z8xaP8wM3X/MFag/zB5x/8ymef/MqHu/zGP + 3P8uarX/LDaA/yoaYv8qF1//KhZf/yoXYP8qF2D/Khdh/ysXYf8rF2L/Kxdi/ysXY/8rF2P/ZFGX/2RR + l/9kUZf/ZFGX/2RRl/9kUZf/ZFKX/2RRl/9kUZf/ZFWa/2Rdov9jeLn/YaLf/1+18f9drer/WpbQ/1l0 + p/9qcZf/jI2k/6WlsP+ytbr/r7O2/52fpf+PkJn/hYWS/358jf94dIv/cWuH/2pjgv94c43/m5qm/7m8 + vv/P1NP/xcrL/52fqP9/fpD/bmiG/2hhgv9sZoT/eHWL/4qKl/+dn6f/rrC4/5uaq/9mX4L/QTtu/zEy + c/8sSJP/MHrI/zKa6P8yoe7/MIbT/y5NmP8sKHL/Kxxk/ysWX/8rF1//Kxdg/ysXYP8rF2D/LBhh/ywY + Yv8sGGP/LBhj/2ZTmf9mU5n/ZlOZ/2ZTmf9mU5n/ZlOZ/2ZTmf9mUpj/ZlKY/2ZboP9lcLL/ZI7N/2Sx + 7f9itu//YJvU/2SDtf9uc5b/iYWZ/7O1uv/DyMn/ur3C/6eosv+NjZz/d3WJ/2Vhe/9WT2//SUBn/0E2 + Yf8/NV//WFJy/4qLmf+prbL/sba7/6mttf+SlqH/fX6Q/2tohv9lYYL/bGmH/3p5kP+Nj5z/oqes/7e9 + v/+us7n/iImb/2BZff87KmT/Kilw/y5Wov8xgM7/MqHu/zKa5v8wa7f/LkKN/ywkbf8rFV3/KxZf/ysX + YP8rF2D/LBdg/ywYYf8sGGL/LBhj/ywYY/9pVZr/aVWa/2lVmv9pVZr/aVWa/2lVmv9pVZr/aVSZ/2lT + mP9oZqn/Z4vK/2ao5P9muPP/Y6jg/158sP9pb5j/hIWc/5+gqv+4vL7/sbO6/4uHn/9zaoz/aWCE/19V + fP9SR3L/RDdn/zYnXP83KVv/SD9l/29thP+orLT/sLe8/4uMnP+HiJn/qK61/7e/w/+yucH/sLfB/7K6 + wv+yusD/rra5/6Oqrv+RlZ//kZaf/6Gpr/+Ki5//TT9y/ywfZP8tMHn/L1ij/zKP3P8zovD/M43b/zFl + sf8tL3j/LBRc/ywWXv8sGGD/LBhh/y0YYf8tGGH/LRhi/y0YY/8uGGT/a1ec/2tXnP9rV5z/a1ec/2tX + nP9rV5z/a1ec/2tXm/9rWJz/anCy/2if3P9ntvD/Z7Lq/2OVy/9dZ5f/bGWI/4+Qn/+prrL/tbq8/6Gi + rv9wZ4r/V0l4/1dKeP9WSnf/UkZ0/0s/bv9ENmf/TEFs/2Ziff+Iipj/rbS5/6Sqsf9xb4b/dHSJ/663 + vP/G0dH/uMDH/7G3wf+0u8P/uMHF/7vHxv+iqbD/b2+H/3JyiP+mr7P/oKew/15Wfv82JmL/Lx5j/y47 + hP8xdsL/NJnn/zSf7f8yfsv/LzyG/y0ZYf8tF2D/LRhg/y0YYf8uGGL/LRhi/y4YY/8uGGT/Lxhk/21Z + nf9tWZ3/bVmd/21Znf9tWZ3/bVmd/21Znf9tW5//bWCj/2x8vP9qrOb/aLjv/2ee1f9jf7L/Xl6M/25k + hv+Rkp//p66w/620tf+Zm6f/bmaJ/1lLef9aTnr/X1R+/2Vegv9rZYX/cGmG/357kf+VmKT/nqWr/5if + pf+EhpP/ZGJ6/3Bwhv+kr7T/qLO5/3p6lP9mYIL/b2yH/4qOnv+xvsD/n6ez/1hPe/9VTHf/lp2p/6Cq + r/9ubIb/SDxq/zQiYP8tK3T/MVek/zOAzv8zoO3/Mo3Z/zFLlv8vI27/Lhtk/y4YYP8uGGH/Lxhi/y8Z + Y/8vGWP/Lxlk/zAZZP9vW5//b1uf/29bn/9vW5//b1uf/29anv9vWp7/b2Cj/29srv9tisj/a7Tt/2m1 + 6v9mjMD/Ymuc/19YhP9vZYb/kZKf/6atsP+rsrT/naGr/397lf9ybI3/enSU/4J/m/+Li6D/kpOk/5ia + p/+lqrH/tsDC/6+5u/+Qlp7/dXaH/2Jgef9ydIn/oK2y/5unrv9iYH7/SEBn/1NObv93eo3/rbu9/52m + tP9NQHX/RTdt/4aLnf+Zpaj/eHyM/1ZPc/85J2L/LCFp/zA8iP8yaLT/M5zn/zOZ4/8yXqn/MTR//y8g + av8uF2D/Lxhh/y8YYv8vGWP/MBlj/zAZZP8wGWT/cVyg/3FcoP9xXKD/cVyg/3FcoP9xXKD/cVuf/3Bm + qf9vfLz/bpnV/2y58P9pr+L/ZX2s/2Fdif9fVH7/b2eG/5CSoP+mrrH/r7e5/6uzt/+eo63/oKSw/7C4 + wP+6xMr/vMbK/7vEyP+3wcP/vMfI/8jV1P+7x8j/l5ym/3t7jf9raYH/en2Q/6Oytv+hsbT/c3mK/15f + df9laHv/gouW/66+v/+bpLP/TUF1/0Ezaf94fJD/jpqe/3uEj/9eXXv/PC1m/ywaYf8uJ3D/MVKb/zOU + 3v80oOr/NHO+/zNJlP8wJ3H/Lxdg/y8YYf8wGWL/MBlj/zAZY/8xGmT/MRpk/3Neov9zXqL/c16i/3Ne + ov9zXqL/c12h/3Ndof9ybK3/cInH/2+k3v9uuO//aqfZ/2Vzn/9hVX7/YFN8/3BoiP+PkqD/p7C0/7bB + wv+4w8P/rre5/664uv+4xMf/vMjL/7nByP+zusP/rbO9/7O7wv/D0dH/u8jJ/5uhq/+Cg5T/c3GJ/4GE + mP+pt7z/rL6+/4uXnf97hI7/gIuU/5KgpP+pvbv/kJqq/0o+cv9AMmj/dHiN/4mWm/95hI7/X2B8/z0u + Z/8sFl3/LRth/zBDiv8ziNL/NZ/p/zWCzv80W6b/MS53/y8XX/8wGGD/MBli/zAZY/8wGWP/MRpk/zEa + ZP92YKP/dmCj/3Zgo/92YKP/dmCj/3Zfov92XqL/dXGx/3KV0P9wrOP/cLPp/2ydz/9mbpn/YlR9/2JU + ff9xaYn/j5Kg/6q1t//Azs3/wM7N/6u2uf+bo6v/kpel/4uLoP+Ef5v/fneX/3x0lf+LiqL/qrW8/7C+ + v/+dpaz/iYub/3l2kP+Hh57/r7vC/7nLyv+ktbX/m6ut/6Cxsv+itrX/n7Sy/32Imf9DN2z/QjVq/3mA + kv+Lmp7/c32K/1dXdv86K2T/LRVb/y4WXP8xOYD/NHnE/zaW4v82jNj/NGm0/zEye/8wFl//MBdg/zEZ + Yv8xGmP/MRpj/zEaZP8yGmX/eGKl/3hipf94YqX/eGKl/3hipf94YaT/eGCj/3Z1tf9zn9f/cbPo/3Gu + 4/9ulcb/aGuW/2RVff9kVn7/c2uK/4+SoP+otLb/vMvK/7fFx/+coq3/hoaa/3h0jv9tZYf/Z1qD/2NU + gP9jU4D/dW2P/5adqv+ms7b/oq2x/5KXpP98d5T/hYKd/6y2vv+7y8r/r8HA/6u+vf+wxcP/qLy7/4+i + pP9rdIf/Qjho/0tCcP+Dj53/j6Cl/2pxhf9LR23/NyZi/y4VW/8uFVr/MTN6/zVtuP82j9v/NpTf/zV1 + v/8yNn//MRZe/zEYYP8xGmL/MRpj/zIaY/8yGmT/Mxpl/3pkpf96ZKX/emSl/3pkpf96ZKX/emOk/3pi + pP94ebf/dKbd/3K36/9yqt7/b4/A/2prlP9mV37/Zld+/3Rsi/+Pk6D/oq6x/6q5uv+fqbH/goCY/3Fn + if9tYYb/al2E/2dZg/9mVoL/ZVaC/3JojP+Ljp//n6qv/6u5uv+eprH/fHaV/3x2lf+fprH/sL6//6u6 + u/+svb3/scbE/6G0tv98iJP/XGB3/0dCaP9aW3r/kaSr/5Onrf9fYH//PjFk/zMfXv8vF1v/LxZb/zEx + d/81ZK7/N4nU/zaa5P81fsf/MzqC/zEXXv8yGGD/Mhti/zIbY/8zG2P/Mxtk/zQbZP98Zqf/fGan/3xm + p/98Zqf/fGan/3xlpv98Zab/en27/3Wt4/9zu+7/c6XY/3CJuP9rapP/aFl//2dZf/91bov/jpSh/56r + rv+grrD/kpml/3Zvjf9qXYP/b2SH/3Nri/92bo7/d3CP/3hwkf+AfZf/kJak/6OwtP+2yMb/rLvA/4qL + ov+Bfpn/lJmm/6Grsf+ls7b/qrq7/62/v/+bqq//dn2N/2Bkev9eYnr/bnqL/46kqP+ElaH/Ukx2/zUi + Xv8xG13/MBhc/zAYXP8yLnT/NVqk/zeCzP82n+j/NYfP/zM+hf8yGF//Mhlg/zIbYv8zG2P/NBtj/zQb + ZP80G2T/fmio/35oqP9+aKj/fmio/35oqP9+Z6j/fmip/3uCv/92s+j/c77v/3Oh0f9xg7D/bGmR/2lb + gP9pW4H/dm+M/46Uof+cqq3/n62v/5KZpP94co//cWiJ/359k/+JjJz/j5Wh/5Obpv+Wn6n/nKav/6Sz + t/+ww8T/wNbT/7zRz/+lsrn/lJuo/42QoP+RlqP/n62x/6a3uP+ktLX/lqKp/36Dk/94f5D/hZee/4ad + oP96j5X/Y2uC/0I2af8xGlz/MBlc/zEZXP8xGFz/Mitw/zZQmv83ecT/NqLq/zWO1v8zQor/Mxpi/zMa + Yf8zG2L/Mxxj/zQcY/81HGT/NRxl/4Bqqv+Aaqr/gGqq/4Bqqv+Aaqr/gGqq/39srP99h8P/d7fr/3W/ + 7/90ncz/cn+r/25pkP9rXYL/a12C/3dwjf+OlKH/nayv/6O0tf+dqbD/jI+i/4iKnv+Sm6X/mqeq/52s + rf+gr7D/orGy/6S0tf+nt7n/rb/A/7bKyv+2ysr/rb/A/6KwtP+Wn6r/l6Cr/6Ozt/+pvLv/pre4/56s + sP+TnKj/laOs/6S9u/+XsLD/bnqK/05Lb/84KGH/Lxdb/zAYXP8xGVz/MRlc/zMobv82SJL/N3O+/zai + 6v81k9r/NEiP/zQeZv8zG2L/Mxti/zQcY/81HGT/NRxl/zUcZf+CbKv/gmyr/4Jsq/+CbKv/gmyr/4Jt + rP+Bca//f4zG/3m57P92v+3/dpzJ/3N+qf9vao//bV+D/21fg/94cY7/jZWh/5+wsv+swcD/sMbG/63A + w/+qvL//p7q6/6S1tf+gr7D/nKqt/5qmq/+Yo6n/l6Kp/5eiqv+ZpKz/nKmw/6KxtP+oubv/rsLD/7HG + x/+wxcX/sMXE/7HHxP+xxsX/sMTG/7PJyf+40s7/n7K4/2tpiv9HOGv/NyJf/zAYW/8wGVv/MRlc/zEZ + XP8zJ2z/NkSN/zdvuP82ouj/Npbb/zVOlf81JGv/NB1k/zQbYv80HGL/NRxk/zYcZf82HGX/hG6t/4Ru + rf+Ebq3/hG6t/4Rurf+Eb67/g3Wy/4CPyP97u+z/eL/s/3ebyP91faf/cWuQ/25hhP9uYYX/eXKP/46V + of+gsrP/r8bE/7XNy/+wxsb/qry//6Kwtv+bpq7/lZyn/5CVov+MkJ//ioyd/4iJm/+Ghpn/hISY/4eK + nP+Rl6X/naix/6q7wP+uwcX/qry//6m7vf+rvr//rcDC/7DBxf+1ysz/vNXT/6W1v/9yapH/UTxz/0Mu + af86JGP/NB1e/zEZXP8yGVz/NCdr/zdCiv84bbX/N6Hm/zaY3P82Upn/Nihv/zUfZf81HGL/NRxj/zYc + ZP82HGX/Nxxl/4Zvrv+Gb67/hm+u/4Zvrv+Gb67/hnGw/4V3tf+Ckcr/fbzt/3rA7P95m8f/dn6n/3Js + kf9wYob/cGKG/3p0j/+OlaH/n7Gy/6zDwf+pvb//lqCs/4qMn/+EgZr/gHqW/353lP99dZP/fHOS/3ty + kf97cZH/enCR/3lvkf96cZL/fXaV/4N9mv+KiKH/j5Km/5GYp/+TnKj/lJyo/5OZp/+RlKf/nKW0/7LI + yv+pusP/gnud/2hVhv9dSn7/Tztz/zwmZP8zGlz/Mxlc/zUma/84QYn/OGy0/zeh5v82md3/N1Sb/zcq + cf82H2b/Nhti/zYcY/83HGT/Nx1l/zgdZf+IcbD/iHGw/4hxsP+Ica//iHCv/4hzsf+Hebf/hJPM/36+ + 7f97wOz/epvG/3h+p/90bZL/cWSH/3Jkh/97dZD/jpah/52vsP+mu7r/na2z/4WGmv93bYz/dGaK/3Jj + iv9zY4r/c2SL/3Nki/90Zoz/dmiN/3dqjv93ao//dmmP/3Vnjv91aI7/eGuQ/3xzk/+BfZf/g4GZ/4OA + mf+BfZf/f3qW/46Rpv+swcX/q73E/4qFpP91ZJH/b12M/2JPgv9NOHL/Pydm/zceYP81Jmv/OECI/zhr + s/83oeX/N5rd/zhVnP84K3P/NyBn/zYcY/83HGP/Nxxk/zgdZf84HWX/inKx/4pysf+KcrH/inKw/4py + sP+KdbP/iXy5/4WWzf+Av+7/fMHs/3ubxv95fqf/dm6S/3NmiP9zZYn/fXaS/4+Xov+aq63/nrKx/5Wh + qf+Ae5X/dWeL/3Rli/90ZYv/dGWL/3RljP90Zoz/dmmN/3pvj/98c5H/fXWS/3t0kv94bpH/d2qQ/3dp + kP94apH/em6S/3tvk/98b5T/fHGU/312lf+Nkqb/q8HE/6q9w/+KhqT/eWiT/3dmkv9yYI7/ZlSF/1ZB + eP9BKGf/Nydr/zg/hv85abH/N6Hl/zea3v85V57/OSx1/zchaP83HGP/Nxxj/zgdZP84HWX/OB1m/4x0 + sf+MdLH/jHSx/4xzsf+Mc7H/i3e0/4p+uv+HmM//gcDu/37B6/98m8b/en+n/3dvk/91Z4n/dWeK/354 + kv+Pl6L/mKqr/5qtrf+Snqb/g4GX/3x0kv9/eZX/gn6Z/4SBnP+Fg57/hoWe/4eJoP+LjaH/jZGj/42S + o/+MkaP/io2j/4iJo/+HhqL/h4Og/4WBn/+Efpz/gnqa/4B5mP+AfJj/j5an/6rCw/+ovML/ioak/3pq + lf97a5b/e2qV/3dlkv9pVob/Uz11/0Q2df8+Q4n/Ommw/zih5P84m9//OVig/zkudv84IWj/Nxxj/zgd + Y/84HWT/OB1l/zgdZv+NdbL/jXWy/411sv+NdbL/jXWy/414tf+Lgbz/iJrQ/4LB7/9/wuv/fZzE/3t/ + pv94cJP/dmiK/3Zoiv9+eZP/jpii/5eqq/+Zrq7/laWq/4yUoP+LkZ//kp2o/5qpsf+gsrn/pLm+/6a8 + wP+mvsD/p73A/6a9v/+lvL7/pr2+/6a+wP+mvsH/pbzB/6O4vv+gsrr/mqqz/5Ofqf+NlKL/iIyd/5Kd + qf+pw8P/przB/4qHpP97a5X/fGyW/31tl/99bJb/d2WR/2xZif9dUYj/S06P/z5qr/85oeT/N5zf/zla + ov86MHj/OCJp/zgcYv84HWP/OB1l/zkdZv86Hmb/j3e0/493tP+Pd7T/j3e0/493tP+Perf/jYO9/4mc + 0f+Ew+//gMPr/3+cxP98gKX/eXGT/3hqi/94aov/gHqT/46Yov+Zra7/nra1/520tP+WqKv/laWq/5qu + sP+ftbb/o7u9/6a+wf+ov8L/qL7B/6e7wP+mub7/pbm9/6W6vv+nvcD/qL/C/6e/wv+mvsD/pLy9/6C3 + t/+ar7D/lqer/5Oiqf+brrP/qsjF/6W7wf+LiKX/fW2W/35ul/9/b5j/gG+Z/39umP98a5X/cWWV/15f + mf9NdrX/P6bl/zmd3/86XKP/OjF6/zkjaf84HGL/OB1j/zoeZ/8+H2v/PyBu/5J5tv+Sebb/knm2/5J5 + tv+Sebb/kXy5/4+Gv/+LntP/hsTw/4LD6/+BnMP/foGl/3tzlP96bIz/emyN/4F7lP+OmKL/nLGy/6jF + wv+pyMT/oLq5/5musP+Vp6r/kqCn/4+Zpv+Nk6X/jIyj/4yJov+MiKL/jIii/4uIof+LiKL/jImj/42L + pP+OjqX/j5Sm/5KdqP+Uo6r/lqis/5qvsv+hurv/qMbD/67Qyv+ku8D/jIml/4Bvl/+AcJj/gXGa/4Fx + mv+BcZr/gXCZ/35xnf93dab/ZovB/0yu6f89nt//PF6k/zszfP85I2r/ORxi/zodZP8+IGv/RSN3/0gl + ff+Ue7f/lHu3/5R7t/+Ue7f/lHu3/5N/uv+RiMH/jaDU/4fF8P+Ew+r/gpzD/4CBpf99dZX/e26O/3xu + jv+CfJX/jpii/5uysv+pycT/qcjG/52xtv+ToKn/jZWh/4eLm/+DgZj/gHiV/35wkv9+bZH/fm6S/35u + k/9+bpP/fm6T/35ulP9/cJX/gHOW/4J6mP+GhJv/io6f/4+Wpf+WpK7/oLe6/6jHw/+sz8n/o7q//42J + pf+CcJn/gnGa/4Nzm/+Dc5v/g3Ob/4Rym/+Ed6H/hYGt/3iYyP9etuv/TKTg/0Jipv88Nn3/OiRq/zsd + ZP8+IGr/RCN0/0smgP9OKIb/lX24/5V9uP+Vfbj/lX24/5V9t/+Ugbv/korC/4+j1f+JxvH/hcPq/4Oc + wv+BgaX/fnWW/31vj/99b4//gn2W/42Yof+Yr67/ob+8/561uP+OkaT/hH6Y/4N7lv+CeZX/gXaU/4Bz + lP+AcZP/f3CT/4BwlP+AcZT/gHGU/4Bxlf+AcJX/gHGW/4Fyl/+CdZj/g3iZ/4V7mv+GfZz/ioig/5Gc + p/+asrP/psfC/6G5vf+Niqb/g3Ka/4Rzm/+EdJz/hHSc/4R0nP+FdJz/hnmi/4eDrv+CnMj/d7/s/2Wu + 4v9Oaan/QDqA/zwmbP8+H2n/RiN2/0wngf9PKYf/USmK/5d/uf+Xf7n/l3+5/5d+uP+Xfrj/loO8/5SN + xP+Qpdf/isfx/4bE6v+FncL/g4Gl/4B1lv9+cI//fnCQ/4J7lf+KkJ3/k6Wp/5y3tf+asbT/jZKk/4WB + mv+Ef5n/hH6Y/4N8l/+Depb/gnmW/4J3lv+CdpX/gnWW/4J1lv+DdZf/g3aY/4N4mP+EeZn/hHua/4V9 + mv+Gf5z/h4Ge/4qLof+QnKf/l66v/5+9uv+bsLb/jIik/4Rzm/+FdJv/hnWc/4Z1nP+GdZz/hnSc/4d5 + ov+Iha//iJ/J/4XF7f93uOX/YHqz/09KjP9FLnb/RCNy/0wmgP9RKYn/UiqL/1MqjP+YgLr/mIC6/5iA + uv+YgLr/mIC6/5eEvf+Vj8X/kabY/4vI8f+Ixuv/h6DE/4SEp/+Bd5f/gHGP/4BxkP+Bd5P/hYGX/42V + ov+ZsbL/nry5/5u0tf+Wqq//kKCo/4uXov+KkJ7/iIqb/4aGmf+Egpj/hH6X/4N7l/+Depj/hHuZ/4V/ + mv+Hgpv/iIad/4mLnv+LkqD/jpmk/5Ghqv+WrLH/nbq6/568uv+YsbH/kZ2o/4mDoP+Gdpz/h3ad/4d3 + nf+Hdp3/h3ac/4d1nP+Ie6P/ioex/4uiy/+Jx+3/g8Lr/3mSw/9qZKH/Vj2J/04pgf9RKYj/UyqM/1Mr + jP9UK43/moK8/5qCvP+agrz/moK8/5qCu/+Zhb7/mI7F/5Ol1v+NyPD/icvw/4mw1P+Hmr3/hoyt/4SD + pP+EgKH/hH6e/4V/nP+KiqD/k6Cq/5qwsf+ct7X/mrez/5Wvrf+SqKn/kaOn/5Cfpv+OnKX/jpmk/42W + pP+NlKT/jZOl/46Upf+Ol6b/j5qn/5Ccp/+RoKj/kqWo/5Oqqv+Wr67/mrW0/5+5uv+csbb/kp2o/4uM + oP+Jfp7/iHie/4l7ov+KfqX/ioGo/4qEq/+Kh67/i4+2/4ycxP+Msdn/i8zx/4vG7f+Kn83/gHex/21S + nf9fOpL/WC+O/1Qrjf9VK43/VSuO/5yEvf+chL3/nIS9/5yEvf+chL3/nIa//5qMw/+WodP/j8Xt/4vT + 9/+LzO//jMDk/4yz1/+Mp8z/i5zB/4qTt/+Ji63/iYem/4uHoP+Nj6D/kJyk/5KlqP+Uqqr/la6t/5ez + sv+Zt7X/m7m4/527uv+evLv/n728/5+9vf+evLz/nby7/527uv+cubn/mre2/5izsf+Wr67/lKur/5Sk + qf+Tmaj/kY+l/42FoP+Lfp7/i3ue/4t9o/+NhKz/joy1/4+Vvv+Pn8f/jqnR/4602/+Nweb/jMzw/4zU + +P+Pxez/lKDQ/5KCu/+Hba//dlSj/2E4lf9WK47/ViuO/1Ysj/+ehr//noa//56Gv/+ehr7/noa+/56H + v/+dicH/mpnM/5S14f+Rx+7/kM3z/5DN8v+Rxu3/kL/l/4+33f+OrtP/jaXJ/4ucvv+Jk7T/iZSw/4uf + sv+Pp7b/kq65/5a0vf+ZusH/m77F/57Bx/+gxMn/ocbK/6LHyv+ixsr/ocbJ/6DEx/+fwsb/nsDF/5y8 + wv+Ytr7/lbG6/5Ortv+RorP/jpax/42Qsf+MjrL/jI+0/42Stv+Nl7z/jp7F/4+nzv+QsNf/kLjf/5DA + 5/+Qx+7/kM3z/5DO8/+Rx+7/lbbh/5uazf+ciMD/mH67/4lpsP9vSZ//XzWU/1kukP9XK4//oIfA/6CH + wP+gh8D/oIe//6CHv/+gh8D/oIjA/56OxP+cms3/mabW/5ez4P+Vvef/k8Pr/5HJ7v+QzPD/j83v/47K + 7P+Oxuj/jcLk/43A4f+PwN//kL/c/5K92v+Tu9j/lLjV/5W20/+WtdL/l7XR/5e00P+Xs87/l7HN/5ew + zP+XsMv/lrDM/5awzf+VsM3/lLDO/5Owzv+Ssc7/kbHQ/5Gx0/+Qs9f/j7fb/4+73/+PwOP/j8Tm/4/H + 6v+Pyu3/j83w/5DN8f+RyvD/ksXt/5S+6P+WtOD/mafX/5yazf+fj8X/oIjA/5+Gv/+Vebj/gmGs/3BK + n/9fNZT/VyuP/6KJwf+iicH/oonB/6KJwf+iicH/oonA/6KIwP+iicH/oYzC/5+Sx/+dntD/m6nY/5iz + 3/+WvOb/lcXs/5TK8P+TzfL/k8/z/5PQ9f+Tz/T/k83y/5PK7/+Sxu3/ksPp/5K/5v+SvOP/kbrg/5G5 + 3/+Rt97/kbbc/5G02v+Rs9r/kbPa/5G02/+Rttz/kbje/5G54P+Su+H/kr3j/5LA5v+TxOn/k8ft/5PK + 7/+TzfL/k8/0/5PQ9P+Sz/P/k83y/5PK8P+Uxez/lr3n/5e14f+aq9n/nZ/R/5+TyP+hi8P/oonB/6KJ + wf+jisH/noO+/5N2t/+BX6v/akKb/14zk/+jisL/o4rC/6OKwv+jisL/o4rC/6OKwf+jisH/o4rB/6OL + wv+jjcP/opHG/6GUyf+gmMv/n5zO/56h0v+dp9f/m6/c/5q14f+ZuuX/mL7o/5fC6v+Vxez/lMnv/5TL + 8P+TzPH/k83x/5LO8f+Rz/L/kdDy/5HQ8v+Rz/L/kc/x/5HP8f+Rz/L/kdDy/5HQ8v+Rz/L/ks/y/5PO + 8v+TzPH/lMvw/5XJ7v+Wxuz/l8Lp/5i+5/+ZueT/mrXg/5uv3P+cp9f/nqHS/5+cz/+gmMz/oZXJ/6KR + xv+jjcP/o4vC/6OKwv+jisL/pIvC/6OJwf+ghr//kXO1/3lUpv9tRJ7/pIvC/KSLwv2ljML+pYzC/6WM + wv+ljML/pYzC/6WMwv+ljML/pYvC/6WLwv+li8L/pYrB/6WLwv+kjsT/o5PH/6Gazf+goNH/n6XV/56q + 2f+cr9z/m7Xg/5q65P+Zvuf/mcHp/5jD6/+Xxez/l8ft/5fI7v+Xye//l8nv/5fK8P+XyvD/l8rv/5fJ + 7/+XyO7/l8ft/5fF7P+Yw+v/mcHp/5m95v+aueP/nLXf/52v3P+eqtj/n6XV/6Cg0f+hms3/o5PH/6SO + xP+li8L/pYrB/6WLwv+li8L/pYvC/6WMwv+ljML/pYzC/6WMwv+ljcP/po3D/5yBvf6KarH9gV2r/KSK + wvWli8L4po3D/aaNxP+mjcP/po3D/6aNw/+mjcP/po3D/6aNw/+mjcP/po3D/6aMw/+mjcP/po3E/6aP + xf+lkcb/pZPI/6SVyf+kl8r/pJjL/6Oazf+jnM7/o53P/6Ke0P+in9H/oqDR/6Kg0f+iodL/oqLT/6Gj + 1P+hpNT/oaTU/6Gj1P+iotL/oqHS/6Kg0f+ioNH/op/R/6Ke0P+jnc//o5zO/6Oazf+kmMv/pJbK/6SV + yf+lk8j/pZHG/6aPxf+mjcT/po3D/6aMw/+mjcP/po3D/6aNw/+mjcP/po3D/6aNw/+mjcP/p47E/6eO + xP+jisL9nYG++Jl8u/WjicLnpYrD7qeNxPmoj8X/qI/F/6iPxf+oj8X/qI/F/6iPxf+oj8X/qI/F/6iP + xf+oj8X/qI/F/6iPxf+ojsX/qI7E/6iOxP+ojsT/qI7E/6iOxP+ojcT/qI3E/6iNxP+ojcT/qI3D/6iN + w/+ojcT/qI3E/6iNxf+oj8X/qJDG/6iQxv+oj8X/qI7E/6iNw/+ojcP/qI3D/6iNxP+ojcT/qI3E/6iN + xP+ojcT/qI7E/6iOxP+ojsT/qI7E/6iOxP+ojsX/qI/F/6iPxf+oj8X/qI/F/6iPxf+oj8X/qI/F/6iP + xf+oj8X/qI/F/6iPxf+oj8X/qI7F+aeOxO6njcTooobB0aSJw92ojsX0qpDG/6qQxv+qkMb/qpDG/6qQ + xv+qkMb/qpDG/6qQxv+qkMb/qpDG/6qQxv+qkMb/qpDG/6qQxv+qkMb/qpDG/6qQxv+qkMb/qo/G/6qP + xv+qj8b/qo/G/6qPxf+qj8X/qo/G/6qPxv+qj8b/qpDG/6qQxv+qkMb/qpDG/6qPxv+qj8X/qo/F/6qP + xf+qj8X/qo/G/6qPxv+qj8b/qo/G/6qQxv+qkMb/qpDG/6qQxv+qkMb/qpDG/6qQxv+qkMb/qpDG/6qQ + xv+qkMb/qpDG/6qQxv+qkMb/qpDG/6qQxv+qkMb/qpDG/6mQxvSoj8Xep47F0qCEwJukiMO1qY/G56uS + x/+sksj/rJLI/6ySyP+sksj/rJLI/6ySyP+sksj/rJLI/6ySyP+sksj/rJLI/6ySyP+sksj/rJLI/6yS + yP+sksj/rJLI/6ySyP+sksj/rJLI/6ySyP+sksj/rJLI/6ySyP+sksj/rJLH/6ySx/+sksf/rJLH/6yS + x/+sksj/rJLI/6ySyP+sksj/rJLI/6ySyP+sksj/rJLI/6ySyP+sksj/rJLI/6ySyP+sksj/rJLI/6yS + yP+sksj/rJLI/6ySyP+sksj/rJLI/6ySyP+sksj/rJLI/6ySyP+sksj/rJLI/6ySyP+rksfoqZDGuKiP + xp+af75Jo4nDeKqQxtCsksj/rZPI/62Uyf+tk8n/rZPJ/62Tyf+tk8n/rZPJ/62Tyf+tk8n/rZPJ/62T + yf+tk8n/rZPJ/62Tyf+tk8n/rZPJ/62Tyf+tk8n/rZPJ/62Tyf+tk8n/rZPJ/62Tyf+tk8n/rZPJ/62T + yP+tk8j/rZPI/62TyP+tk8j/rZPJ/62Tyf+tk8n/rZPJ/62Tyf+tk8n/rZPJ/62Tyf+tk8n/rZPJ/62T + yf+tk8n/rZPJ/62Tyf+tk8n/rZPJ/62Tyf+tk8n/rZPJ/62Tyf+tk8n/rZPJ/62TyP+tk8n/rZPJ/66U + yf+ulMn/rpXJ062UyX2sk8hRjXW3FqKJwkKpj8aWq5DH0KyRyOetksj0rpTJ+q6Uyf2vlcn+r5XK/6+V + yv+vlcr/r5XK/6+Vyv+vlcr/r5XK/6+Vyv+vlcr/r5XK/6+Vyv+vlcr/r5XK/6+Vyv+vlcr/r5XK/6+V + yv+vlcr/r5XK/6+Vyv+vlcr/r5XK/6+Vyv+vlcr/r5XK/6+Vyv+vlcr/r5XK/6+Vyv+vlcr/r5XK/6+V + yv+vlcr/r5XK/6+Vyv+vlcr/r5XK/6+Vyv+vlcr/r5XK/6+Vyv+vlcr/r5XK/6+Vyv+vlcr/r5XK/6+V + yv6vlcr9r5XK+q6UyfWulMnpr5XK07CWypuxmMtItpvNHYZvswWehcAZoonCQqaKxHiojMa2q47H3q6S + yO6vlcn4sJbK/bCWy/+wlsv/sJbL/7CWy/+wlsv/sJbL/7CWy/+wlsv/sJbL/7CWy/+wlsv/sJbL/7CW + y/+wlsv/sJbL/7CWy/+wlsv/sJbL/7CWy/+wlsv/sJbL/7CWy/+wlsv/sJbL/7CWy/+wlsv/sJbL/7CW + y/+wlsv/sJbL/7CWy/+wlsv/sJbL/7CWy/+wlsv/sJbL/7CWy/+wlsv/sJbL/7CWy/+wlsv/sJbL/7CW + y/+wlsv/sJbL/7CWy/+wl8v9sJfL+bCWy/CvlMngrpTJurCVyn+yl8xIs5jMHbmfzweQd7gAhW+yBox0 + thaegsBKpYfEnKmMxtKtksjosJXK9rGXy/yxl8v/sZfL/7GXy/+xl8v/sZfL/7GXy/+xl8v/sZfL/7GX + y/+xl8v/sZfL/7GXy/+xl8v/sZfL/7GXy/+xl8v/sZfL/7GXy/+xl8v/sZfL/7GXy/+xl8v/sZfL/7GX + y/+xl8v/sZfL/7GXy/+xl8v/sZfL/7GXy/+xl8v/sZfL/7GXy/+xl8v/sZfL/7GXy/+xl8v/sZfL/7GX + y/+xl8v/sZfL/7GXy/+xl8v/sZfL/7GXy/+xl8v/sZfL/bGYzPewl8vqr5TJ1a6TyKKxlMpTtpbOHreX + zwi1ls4AgAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAE= + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/CommonObjects/ProcessFilterSettingForm.Designer.cs b/Demo_Source_Code/CSharpDemo/CommonObjects/ProcessFilterSettingForm.Designer.cs new file mode 100644 index 0000000..d28f6bf --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/CommonObjects/ProcessFilterSettingForm.Designer.cs @@ -0,0 +1,232 @@ +namespace EaseFilter.CommonObjects +{ + partial class ProcessFilterSettingForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ProcessFilterSettingForm)); + this.groupBox_AccessControl = new System.Windows.Forms.GroupBox(); + this.button_Apply = new System.Windows.Forms.Button(); + this.button_DeleteFilter = new System.Windows.Forms.Button(); + this.button_AddFilter = new System.Windows.Forms.Button(); + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.listView_FilterRules = new System.Windows.Forms.ListView(); + this.groupBox2 = new System.Windows.Forms.GroupBox(); + this.button_ProcessInfo = new System.Windows.Forms.Button(); + this.label2 = new System.Windows.Forms.Label(); + this.textBox_ControlFlag = new System.Windows.Forms.TextBox(); + this.label17 = new System.Windows.Forms.Label(); + this.button_SelectControlFlag = new System.Windows.Forms.Button(); + this.label22 = new System.Windows.Forms.Label(); + this.textBox_ProcessName = new System.Windows.Forms.TextBox(); + this.groupBox_AccessControl.SuspendLayout(); + this.groupBox1.SuspendLayout(); + this.groupBox2.SuspendLayout(); + this.SuspendLayout(); + // + // groupBox_AccessControl + // + this.groupBox_AccessControl.Controls.Add(this.button_Apply); + this.groupBox_AccessControl.Controls.Add(this.button_DeleteFilter); + this.groupBox_AccessControl.Controls.Add(this.button_AddFilter); + this.groupBox_AccessControl.Controls.Add(this.groupBox1); + this.groupBox_AccessControl.Controls.Add(this.groupBox2); + this.groupBox_AccessControl.Dock = System.Windows.Forms.DockStyle.Fill; + this.groupBox_AccessControl.Location = new System.Drawing.Point(0, 0); + this.groupBox_AccessControl.Name = "groupBox_AccessControl"; + this.groupBox_AccessControl.Size = new System.Drawing.Size(537, 331); + this.groupBox_AccessControl.TabIndex = 26; + this.groupBox_AccessControl.TabStop = false; + // + // button_Apply + // + this.button_Apply.DialogResult = System.Windows.Forms.DialogResult.OK; + this.button_Apply.Location = new System.Drawing.Point(382, 263); + this.button_Apply.Name = "button_Apply"; + this.button_Apply.Size = new System.Drawing.Size(138, 23); + this.button_Apply.TabIndex = 84; + this.button_Apply.Text = "Apply Filter Rule Settings"; + this.button_Apply.UseVisualStyleBackColor = true; + this.button_Apply.Click += new System.EventHandler(this.button_Apply_Click_1); + // + // button_DeleteFilter + // + this.button_DeleteFilter.Location = new System.Drawing.Point(197, 263); + this.button_DeleteFilter.Name = "button_DeleteFilter"; + this.button_DeleteFilter.Size = new System.Drawing.Size(103, 23); + this.button_DeleteFilter.TabIndex = 83; + this.button_DeleteFilter.Text = "Delete Filter Rule"; + this.button_DeleteFilter.UseVisualStyleBackColor = true; + this.button_DeleteFilter.Click += new System.EventHandler(this.button_DeleteFilter_Click); + // + // button_AddFilter + // + this.button_AddFilter.Location = new System.Drawing.Point(6, 263); + this.button_AddFilter.Name = "button_AddFilter"; + this.button_AddFilter.Size = new System.Drawing.Size(116, 23); + this.button_AddFilter.TabIndex = 82; + this.button_AddFilter.Text = "Add New Filter Rule"; + this.button_AddFilter.UseVisualStyleBackColor = true; + this.button_AddFilter.Click += new System.EventHandler(this.button_AddFilter_Click); + // + // groupBox1 + // + this.groupBox1.Controls.Add(this.listView_FilterRules); + this.groupBox1.Location = new System.Drawing.Point(6, 158); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size(517, 93); + this.groupBox1.TabIndex = 81; + this.groupBox1.TabStop = false; + this.groupBox1.Text = "Process Filter Rule Collection"; + // + // listView_FilterRules + // + this.listView_FilterRules.Dock = System.Windows.Forms.DockStyle.Fill; + this.listView_FilterRules.FullRowSelect = true; + this.listView_FilterRules.Location = new System.Drawing.Point(3, 16); + this.listView_FilterRules.Name = "listView_FilterRules"; + this.listView_FilterRules.Size = new System.Drawing.Size(511, 74); + this.listView_FilterRules.TabIndex = 1; + this.listView_FilterRules.UseCompatibleStateImageBehavior = false; + this.listView_FilterRules.View = System.Windows.Forms.View.Details; + this.listView_FilterRules.SelectedIndexChanged += new System.EventHandler(this.listView_FilterRules_SelectedIndexChanged); + // + // groupBox2 + // + this.groupBox2.Controls.Add(this.button_ProcessInfo); + this.groupBox2.Controls.Add(this.label2); + this.groupBox2.Controls.Add(this.textBox_ControlFlag); + this.groupBox2.Controls.Add(this.label17); + this.groupBox2.Controls.Add(this.button_SelectControlFlag); + this.groupBox2.Controls.Add(this.label22); + this.groupBox2.Controls.Add(this.textBox_ProcessName); + this.groupBox2.Location = new System.Drawing.Point(6, 19); + this.groupBox2.Name = "groupBox2"; + this.groupBox2.Size = new System.Drawing.Size(517, 124); + this.groupBox2.TabIndex = 76; + this.groupBox2.TabStop = false; + // + // button_ProcessInfo + // + this.button_ProcessInfo.BackColor = System.Drawing.Color.AntiqueWhite; + this.button_ProcessInfo.Image = global::EaseFilter.CommonObjects.Properties.Resources.about; + this.button_ProcessInfo.Location = new System.Drawing.Point(465, 27); + this.button_ProcessInfo.Name = "button_ProcessInfo"; + this.button_ProcessInfo.Size = new System.Drawing.Size(33, 20); + this.button_ProcessInfo.TabIndex = 97; + this.button_ProcessInfo.UseVisualStyleBackColor = false; + this.button_ProcessInfo.Click += new System.EventHandler(this.button_ProcessInfo_Click); + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(201, 50); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(209, 13); + this.label2.TabIndex = 90; + this.label2.Text = "( i.e. c:\\testfolder\\*.exe or \'notepad.exe\' )"; + // + // textBox_ControlFlag + // + this.textBox_ControlFlag.Location = new System.Drawing.Point(203, 78); + this.textBox_ControlFlag.Name = "textBox_ControlFlag"; + this.textBox_ControlFlag.ReadOnly = true; + this.textBox_ControlFlag.Size = new System.Drawing.Size(242, 20); + this.textBox_ControlFlag.TabIndex = 73; + this.textBox_ControlFlag.Text = "0"; + // + // label17 + // + this.label17.AutoSize = true; + this.label17.Location = new System.Drawing.Point(6, 83); + this.label17.Name = "label17"; + this.label17.Size = new System.Drawing.Size(142, 13); + this.label17.TabIndex = 72; + this.label17.Text = "Process Access Control Flag"; + // + // button_SelectControlFlag + // + this.button_SelectControlFlag.Location = new System.Drawing.Point(465, 78); + this.button_SelectControlFlag.Name = "button_SelectControlFlag"; + this.button_SelectControlFlag.Size = new System.Drawing.Size(41, 20); + this.button_SelectControlFlag.TabIndex = 74; + this.button_SelectControlFlag.Text = "..."; + this.button_SelectControlFlag.UseVisualStyleBackColor = true; + this.button_SelectControlFlag.Click += new System.EventHandler(this.button_SelectControlFlag_Click); + // + // label22 + // + this.label22.AutoSize = true; + this.label22.Location = new System.Drawing.Point(7, 27); + this.label22.Name = "label22"; + this.label22.Size = new System.Drawing.Size(116, 13); + this.label22.TabIndex = 78; + this.label22.Text = "Processes Name Mask"; + // + // textBox_ProcessName + // + this.textBox_ProcessName.Location = new System.Drawing.Point(203, 27); + this.textBox_ProcessName.Name = "textBox_ProcessName"; + this.textBox_ProcessName.Size = new System.Drawing.Size(242, 20); + this.textBox_ProcessName.TabIndex = 77; + this.textBox_ProcessName.Text = "*"; + // + // ProcessFilterSettingForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(537, 331); + this.Controls.Add(this.groupBox_AccessControl); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Name = "ProcessFilterSettingForm"; + this.Text = "Process Filter Rule Settings"; + this.groupBox_AccessControl.ResumeLayout(false); + this.groupBox1.ResumeLayout(false); + this.groupBox2.ResumeLayout(false); + this.groupBox2.PerformLayout(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.GroupBox groupBox_AccessControl; + private System.Windows.Forms.GroupBox groupBox2; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.TextBox textBox_ControlFlag; + private System.Windows.Forms.Label label17; + private System.Windows.Forms.Button button_SelectControlFlag; + private System.Windows.Forms.Label label22; + private System.Windows.Forms.TextBox textBox_ProcessName; + private System.Windows.Forms.Button button_Apply; + private System.Windows.Forms.Button button_DeleteFilter; + private System.Windows.Forms.Button button_AddFilter; + private System.Windows.Forms.GroupBox groupBox1; + private System.Windows.Forms.ListView listView_FilterRules; + private System.Windows.Forms.Button button_ProcessInfo; + } +} \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/CommonObjects/ProcessFilterSettingForm.cs b/Demo_Source_Code/CSharpDemo/CommonObjects/ProcessFilterSettingForm.cs new file mode 100644 index 0000000..7823c9e --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/CommonObjects/ProcessFilterSettingForm.cs @@ -0,0 +1,164 @@ +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 EaseFilter.CommonObjects +{ + public partial class ProcessFilterSettingForm : Form + { + List filterRuleList = new List(); + + public ProcessFilterSettingForm() + { + InitializeComponent(); + filterRuleList.AddRange(GlobalConfig.FilterRules.Values); + InitListView(); + } + + public void InitListView() + { + //init ListView control + listView_FilterRules.Clear(); //clear control + //create column header for ListView + listView_FilterRules.Columns.Add("#", 20, System.Windows.Forms.HorizontalAlignment.Left); + listView_FilterRules.Columns.Add("ProcessNameMask", 200, System.Windows.Forms.HorizontalAlignment.Left); + listView_FilterRules.Columns.Add("ControlFlag", 100, System.Windows.Forms.HorizontalAlignment.Left); + + foreach (FilterRule rule in filterRuleList) + { + AddItem(rule); + } + + } + + private void AddItem(FilterRule newRule) + { + if (newRule.Type == (uint)FilterAPI.FilterType.FILE_SYSTEM_PROCESS && newRule.ProcessControlFlag > 0 ) + { + string[] itemStr = new string[listView_FilterRules.Columns.Count]; + itemStr[0] = listView_FilterRules.Items.Count.ToString(); + itemStr[1] = newRule.IncludeFileFilterMask; + itemStr[2] = newRule.ProcessControlFlag.ToString(); + ListViewItem item = new ListViewItem(itemStr, 0); + item.Tag = newRule; + listView_FilterRules.Items.Add(item); + } + } + + + private void button_SelectControlFlag_Click(object sender, EventArgs e) + { + OptionForm optionForm = new OptionForm(OptionForm.OptionType.ProcessControlFlag, textBox_ControlFlag.Text); + + if (optionForm.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + textBox_ControlFlag.Text = optionForm.ProcessControlFlag.ToString(); + } + } + + + private void button_AddFilter_Click(object sender, EventArgs e) + { + try + { + FilterRule filterRule = new FilterRule(); + + filterRule.Type = (int)FilterAPI.FilterType.FILE_SYSTEM_PROCESS; + + if (textBox_ProcessName.Text.Trim().Length > 0) + { + filterRule.IncludeFileFilterMask = textBox_ProcessName.Text; + } + else + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("The process name mask can't be null.", "Add Filter Rule", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + try + { + filterRule.ProcessControlFlag = uint.Parse(textBox_ControlFlag.Text); + } + catch + { + } + + if (filterRule.ProcessControlFlag == 0) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("The process control flag is empty, the entry won't be added.", "Add Filter Rule", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + filterRuleList.Add(filterRule); + InitListView(); + + } + catch (Exception ex) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("Add registry filter rule failed." + ex.Message, "Add Filter Rule", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + } + + private void button_DeleteFilter_Click(object sender, EventArgs e) + { + if (listView_FilterRules.SelectedItems.Count == 0) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("There are no filter rule selected.", "Delete Filter Rule", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + foreach (System.Windows.Forms.ListViewItem item in listView_FilterRules.SelectedItems) + { + FilterRule filterRule = (FilterRule)item.Tag; + filterRuleList.Remove(filterRule); + + GlobalConfig.RemoveFilterRule(filterRule.IncludeFileFilterMask); + } + + InitListView(); + } + + private void button_Apply_Click_1(object sender, EventArgs e) + { + foreach (FilterRule filterRule in filterRuleList) + { + GlobalConfig.AddFilterRule(filterRule); + } + + GlobalConfig.SaveConfigSetting(); + } + + private void button_ProcessInfo_Click(object sender, EventArgs e) + { + string information = "Process Control: allow/deny the binaries executing, prevent the suspicious binaries(malware) from executing.\r\n\r\n"; + information += "Get notification for process/thread creation and termination.\r\n\r\n"; + + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show(information, "Process Filter Setting", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + + private void listView_FilterRules_SelectedIndexChanged(object sender, EventArgs e) + { + if (listView_FilterRules.SelectedItems.Count > 0) + { + FilterRule filterRule = (FilterRule)listView_FilterRules.SelectedItems[0].Tag; + textBox_ProcessName.Text = filterRule.IncludeFileFilterMask; + textBox_ControlFlag.Text = filterRule.ProcessControlFlag.ToString(); + + } + } + + + } +} diff --git a/Demo_Source_Code/CSharpDemo/CommonObjects/ProcessFilterSettingForm.resx b/Demo_Source_Code/CSharpDemo/CommonObjects/ProcessFilterSettingForm.resx new file mode 100644 index 0000000..acfec18 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/CommonObjects/ProcessFilterSettingForm.resx @@ -0,0 +1,408 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + AAABAAEAQEAAAAEAIAAoQgAAFgAAACgAAABAAAAAgAAAAAEAIAAAAAAAAEAAABMLAAATCwAAAAAAAAAA + AAAaEmMAFxFfAxkSYQ0cEmY4HRJngh0SZ7kcEmfYHBJn7hwSZ/ocEmf/HBJn/xwSZ/8cEmf/HBJn/xwS + Z/8cEmf/HBJn/xwSZ/8cEmf/HBJn/xwSZ/8cEmf/HBJn/xwSZ/8cEmf/HBJn/xwSZ/8cEmf/HBJn/xwS + Z/8cEmj/GxJk/xkRXv8XD1j/Fg5U/xYOUv8XDlP/Fw5T/xcPVP8XD1T/Fw9U/xcPVP8XD1b/Fw9W/xcP + Vv8XD1b/GA9X/xgPV/8YD1j/GA9Y/xgQWf8YEFn/GBBa/xgQWv8ZEFr/GRBa+hgPXO8YD1zcGRBcvhoQ + XIgZEFs8GBBYDxcQVwQYEFkAEg9bAh0SZhQeE2c4HhNnaR4SZ6IdEmfLHRJn4h0SZ/IdEmf7HRJn/x0S + Z/8dEmf/HRJn/x0SZ/8dEmf/HRJn/x0SZ/8dEmf/HRJn/x0SZ/8dEmf/HRJn/x0SZ/8dEmf/HRJn/x0S + Z/8dEmf/HRJn/x0SZ/8dEmf/HBJl/xsRYf8ZEFv/GA9W/xcPU/8XDlL/Fw5T/xcOU/8XD1T/Fw9U/xcP + VP8XD1T/Fw9V/xcPVv8YD1b/GA9W/xgPV/8YD1f/GA9Y/xkPWP8ZEFn/GRBZ/xkQWv8ZEFr/GRBa/xkQ + W/wZEFvzGRBc5RoQXM8aEFymGxFcbBsRXDoaEFsVFA9UAxcRYA0eE2c4HxNojR8TaMcfE2jfHhNo7h4T + aPYeE2j7HhNo/h4TaP8eE2j/HhNo/x4TaP8eE2j/HhNo/x4TaP8eE2j/HhNo/x4TaP8eE2j/HhNo/x4T + aP8eE2j/HhNo/x4TaP8eE2j/HhNo/x4TaP8eE2j/HhJm/xwRYP8aEFv/GRBW/xgPU/8YD1L/GA9S/xgP + U/8YD1P/GA9U/xgPVP8YD1T/GA9U/xgQVf8ZEFX/GRBW/xkQVv8ZEFf/GRBX/xkQWP8aEFj/GhBZ/xoQ + Wf8aEFr/GhBa/xoRW/8aEVv+GhFb+xoRW/cbEVzvGxFc4RwRXcocEV2PGxFcOhcPVw8fE2g4HxNoaR8T + aMcfE2j9HxNo/x8TaP8gE2j/IBNo/yATaP8gE2j/IBNo/yATaP8gE2j/IBNo/yATaP8gE2j/IBNo/yAT + aP8gE2j/IBNo/yATaP8gE2j/IBNo/yATaP8gE2j/IBNp/yATaf8fE2j/HxNm/x0SYv8bEFr/Gg9V/xkO + Uv8YD1H/GA9S/xkPU/8ZD1P/GQ9T/xkPVP8ZD1T/GQ9U/xoPVP8ZEFX/GhBV/xoQVv8aEFb/GhBX/xoQ + V/8aEFj/GxBY/xsQWf8bEFn/GxBa/xsQWv8bEVv/GxFb/xsRW/8cEVv/GxFc/xwRXP8cEV3+HBFdyhwR + XWwbEF08IRRqgiEUaqIhFGrfIBRp/yAUaf8gFGn/IRRp/yEUaf8hFGn/IRRp/yEUaf8hFGn/IRRp/yEU + af8hFGn/IRRp/yEUaf8hFGn/IRRp/yEUaf8hFGn/IRRp/yEUaf8hFGn/IRRp/yEUav8hFGr/IBNn/x4S + Yf8cEVv/Gg9V/xkOUf8ZDlH/GQ5R/xkPUv8aEFP/GhBU/xoQVP8aEFT/GhBU/xoQVf8bEFX/GxBV/xsQ + Vv8bEFb/GxBX/xsRV/8bEVj/GxFY/xwRWf8cEVn/HBFa/xwRW/8cEVv/HBFb/xwRW/8cEVz/HRFc/x0S + XP8dEl3/HRJe/x0SXuEdEV6mHRFfiCIUa7kiFGvLIRRr7iEUa/8hFGv/IRRr/yEUa/8hFGv/IRRr/yEU + a/8hFGv/IRRr/yEUa/8hFGv/IRRr/yEUa/8hFGv/IRRr/yEUa/8hFGv/IRRr/yEUa/8hFGv/IhRr/yIU + a/8hFGr/IRNn/x8SYv8cEFr/GxFY/xsWWv8bGVz/Gxld/xoWWv8aEVT/Gg9S/xoPU/8aEFT/GhBU/xsQ + VP8bEFX/GxBW/xsQVv8bEFf/GxBX/xsQWP8bEVj/HBFZ/xwRWf8cEVr/HBFa/xwRWv8cEVv/HBFb/xwR + W/8dEVv/HRFc/x0RXf8dEl3/HRJe/x0SXv8eEl/vHhJfzx4SX74jFWzZIxVs4yIVbPYiFWz/IhVs/yIV + bP8iFWz/IhVs/yIVbP8iFWz/IhVs/yIVbP8iFWz/IhVs/yIVbP8iFWz/IhVs/yIVbP8iFWz/IhVs/yIV + bP8iFWz/IhVs/yMVbP8jFWz/IhRp/yASYv8dEFr/Gw5T/xsWWf8dJmz/HjB3/x4weP8dJm3/GxZa/xoN + UP8bDlL/GxBU/xsQVP8cEVX/HBFW/xwRVv8cEVf/HBFX/xwRWP8cEVj/HBFZ/x0RWf8dEVr/HRFa/x0S + W/8dElv/HRJb/x4SW/8dElz/HhJc/x4SXf8eEl3/HhJe/x4SXv8eEl//HxJf9h8SYOUfE2DcJBVs7yQV + bPMkFWz7JBVs/yQVbP8kFWz/JBVs/yQVbP8kFWz/JBVs/yQVbP8kFWz/JBVs/yQVbP8kFWz/JBVs/yQV + bP8kFWz/JBVs/yQVbP8kFWz/JBVs/yQVbP8jFGv/IxNo/yEUZf8gGGP/Hhxj/x0jZ/8eMnb/IUeP/yJT + nf8iU53/IUeQ/x8yd/8dImb/HRpf/xwVWv8cEVX/HBBU/xwQVf8cEVb/HBFX/x0RV/8dEVj/HRFY/x0R + Wf8eEVn/HhFa/x4RWv8eElv/HhJb/x4SW/8fElv/HxJc/x4SXP8eEl3/HxJd/x8SXv8fEl7/HxJf/yAS + X/sgE2DzIBNg7yUWbfolFm37JRZt/iUWbf8lFm3/JRZt/yUWbf8lFm3/JRZt/yUWbf8lFm3/JRZt/yUW + bf8lFm3/JRZt/yUWbf8lFm3/JRZt/yUWbf8lFm3/JRZt/yUWbf8lFm3/JBRp/yIRYP8hFmH/ISRs/yE3 + fv8iT5X/I2Sr/yZ2wP8nf8v/J3/L/yZ2wP8kZKv/Ik6T/yA0e/8fIWf/HhRZ/x0PU/8dEFT/HRFW/x0R + V/8eElf/HhJY/x4SWP8eElj/HxJY/x4SWf8fElr/HxJb/x8SW/8fElv/IBJb/yATXP8fE1z/HxNd/yAT + Xf8gE17/IBNe/yATX/8hE1/+IRNg/CETYPonFm3/JxZt/ycWbf8nFm3/JxZt/ycWbf8nFm3/JxZt/ycW + bf8nFm3/JxZt/ycWbf8nFm3/JxZt/ycWbf8nFm3/JxZt/ycWbf8nFm3/JxZt/ycWbf8mFm3/Jhds/yQb + bf8iI27/IjB4/yNEi/8lW6T/JnbA/yiK1f8qluT/K53r/yud6/8qluT/KYnU/yd0vv8kWaL/IkGJ/yEu + dP8fIWb/Hxhe/x8UWf8eElf/HxFW/x8SV/8fElj/HxJY/x8SWP8fEln/IBJa/yASW/8gElv/IBJb/yAS + W/8gE1z/IRNc/yATXf8hE13/IRNe/yETXv8hE1//IhNg/yETYP8hE2D/KBdv/ygXb/8oF2//KBdv/ygX + b/8oF2//KBdv/ygXb/8oF2//KBdv/ygXb/8oF2//KBdv/ygXb/8oF2//KBdv/ygXb/8oF2//KBdv/ygW + bv8oFW7/Jxdt/yUbbP8kLHn/JUiR/yZgqP8ndL3/KIXR/yuU4/8tnu//LqT3/y6n+/8up/v/LqT3/y2e + 7/8rk+L/KIXQ/yZzvP8lX6f/I0aO/yEscv8gG2H/IBNZ/x8RVv8gEVf/IBJY/yASWf8gEln/IBNZ/yAT + Wv8hE1v/IRNb/yETXP8hE1z/IRNd/yITXf8iE17/IhNe/yIUX/8iFF//IhRg/yMUYP8jFGH/IxRh/ygX + b/8oF2//KBdv/ygXb/8oF2//KBdv/ygXb/8oF2//KBdv/ygXb/8oF2//KBdv/ygXb/8oF2//KBdv/ygX + b/8oF2//KRdv/ykWbv8oGXH/KCB2/ycqff8mN4T/Jk6Y/yhtt/8qhtH/K5bi/yyf7f8uoPL/Lpzv/y2S + 5f8tjeD/LY3g/y2S5f8um+//LqDy/yyf7f8qluL/KYXQ/ydtt/8kT5f/IzZ9/yIlbP8hGmD/IBNZ/yAR + V/8gElj/IBJZ/yATWv8hE1r/IRNb/yETW/8hE1z/IRNc/yITXf8iE13/IhNe/yITXv8iFF//IxRf/yMU + YP8jFGD/IxRh/yMUYf8pGHD/KRhw/ykYcP8pGHD/KRhw/ykYcP8pGHD/KRhw/ykYcP8pGHD/KRhw/ykY + cP8pGHD/KRhw/ykYcP8pGHD/KRhw/yoXb/8qFm7/KSB3/yg2iP8oT5z/KGiy/yp+yP8skd7/Lp7t/y6l + 9v8vpPb/L5ns/y2D1f8qY7L/KFGe/yhRnf8pYbD/LYLU/y+Z7P8vpPb/LqX2/y2e7f8skd7/KX/I/ydm + rv8lSJD/Iy51/yEZX/8hEFX/IRFX/yETWf8hE1r/IhNa/yITW/8iE1v/IhRc/yIUXP8iFF3/IxRd/yMU + Xv8jFF7/IxRf/yQUX/8kFWD/JBVg/yQVYf8kFWH/Kxhw/ysYcP8rGHD/Kxhw/ysYcP8rGHD/Kxhw/ysY + cP8rGHD/Kxhw/ysYcP8rGHD/Kxhw/ysYcP8rGHD/Kxhw/ysYcf8qHXX/Kid9/yo7jv8pV6b/KnO//yuN + 1/8tnOn/L6Ly/y+g8v8vluj/LYjZ/yx1xf8pW6j/JjuE/yQpcf8kKXD/JTmD/ylap/8sdcT/LojZ/y+X + 6f8voPL/L6Ly/y2d6f8ri9X/KG23/yZQmf8kNHv/IyJo/yIYXv8iFFr/IhNa/yITWv8iE1v/IxNb/yMU + XP8jFFz/IxRd/yMUXf8jFF7/JBRe/yQUX/8lFF//JRVg/yQVYP8kFWH/JBVh/ywZcf8sGXH/LBlx/ywZ + cf8sGXH/LBlx/ywZcf8sGXH/LBlx/ywZcf8sGXH/LBlx/ywZcf8sGXH/LBhx/ywZcv8sG3P/KyyB/ypL + m/8qaLX/K4HO/yyV4v8uovD/L6X1/zCe8P8vitz/K2u6/yhPm/8lOX//Iyhs/yIeYf8iGVz/Ihhc/yIe + Yv8jKG3/JjmB/ylQnP8sbLv/L4vd/zCe8P8vpfX/LqHw/yyT4P8qfsn/KGOs/yZFjf8lJ23/JBZc/yQU + W/8jE1v/IxRb/yQUXP8kFF3/JBRd/yQUXf8kFF3/JBVe/yUVX/8lFWD/JhVg/yYVYf8mFWH/JRVh/yUV + Yf8vG3T/Lxtz/y4ac/8tGXL/LRly/y0Zcv8tGXL/LRly/y0Zcv8tGXL/LRly/y0Zcv8uGXL/Lhly/y0Z + cv8tIHj/LC+F/yxKnP8rb73/K4vY/y2d6/8vo/L/L5zt/y+P4P8tfMv/K2Kv/ydDjP8kKW//IRdY/yAP + Tv8hEFD/IRFS/yERU/8hEVL/IRBR/yIYW/8lKnH/KEOP/yxjsf8ufc3/L5Di/y+d7v8vo/P/LZ3q/yyJ + 1f8qa7b/KEeP/yYscv8lHGP/JRRb/yQUW/8kFFz/JRRd/yUUXf8lFF3/JRRe/yUVX/8mFV//JhVg/yYV + YP8mFWH/JhVh/yYVYf8nFWH/NSF4/zMfd/8wHHX/Lxpz/y4Zc/8uGXP/Lhlz/y4Zc/8uGXP/Lhlz/y4a + c/8uGnP/Lxlz/y4Zc/8uG3X/LS+F/yxVpf8sdsT/LpHg/y+i8f8wp/j/MJvs/y5+zv8rX6z/J0CH/yUr + bv8jIGP/Ihha/yETU/8hEFD/IRJS/yISU/8iElP/IhJT/yERU/8iFFb/Ixle/yUiZ/8mLXP/KUKL/yxh + sP8vgNH/L53t/y+o+P8vofH/LZDd/yt1wP8pU5v/Jytz/yYWXv8lFVz/JRVc/yYVXf8mFV3/JhVe/yYV + Xv8mFV//JxVf/ycWYP8nFmD/JxZh/ycWYf8nFmL/KBZi/0EugP9ALH//PSl9/zome/85JHr/NyN5/zYh + eP80IHj/Mx53/zIddv8xG3X/MBp0/y8adP8uIXr/Li+H/y1Nof8teMb/LpXi/zCh8P8wn+//Lo/f/yx2 + xP8oVaH/JTV9/yEaXP8fDUz/Hg1M/x4OTv8eD0//Hw9Q/x8QUf8fEFH/HxBS/yAQUv8gEFP/IBBT/yAP + U/8hD1L/IQ5S/yMcYv8nOIP/Klim/y15yf8vkuL/MKDx/zCh8f8uleL/K3fC/ylLlP8nLHT/Jhxk/yYV + XP8mFVz/JhVd/yYVXv8mFV7/JxVf/ycVX/8nFmD/JxZg/ycWYf8oFmH/KBZi/ygWYv9UQoz/VEGM/1JA + i/9QPYr/TTmH/0k1hf9EMYL/QC1//z0off85JHr/NR94/zEcdv8wHHb/LjCG/y1WqP8tecj/L5bl/zCi + 8f8xm+z/LoLR/ylZo/8lOoD/Iidr/yAZW/8eEFD/HQxM/x0NTP8dDU3/HQ5O/x0OT/8eDk//Hg5Q/x4O + UP8fD1H/Hw9S/yAPUv8fD1L/Hw5S/yAOUv8hElj/Ixxj/yUqc/8oPon/K12r/y+F1v8xne//MKPy/y6W + 5P8secT/KlWe/ycsdP8mF17/JxVd/ycVXf8nFl7/JxZe/ycWX/8oFl//KBZg/ygWYP8oFmH/KRZh/ykX + Yv8pF2L/X02T/19Nk/9eTZP/XUuS/1pHkP9WQ43/UT+L/047iP9KNob/RjGD/0IsgP8+LYH/OzaJ/zhR + of81fMj/M5jk/zKh8P8wl+b/LHrJ/yxcpP8xPnz/NjBm/zswYv9BNGT/Rjtq/0tAcP9PRHP/UUZ1/1NI + d/9USXn/VUl5/1NIeP9RRXb/T0R1/09DdP9PRHX/UkZ3/1JGd/9PQ3b/Sz9x/0Y4bP89MGn/MSpr/yw5 + gf8tXqz/L3/P/zGZ6v8xovH/L5fk/yx5xP8qSZL/KClx/ygaYv8nFFz/JxVd/ygWX/8oFl//KBZf/ygW + YP8pFmH/KRZh/yoWYv8qF2L/KRdi/2BPlf9gT5X/YE6V/2BOlP9fTZT/XkuT/1xKkv9bSZH/WkeQ/1lF + j/9XQ43/VU2X/1Fmrf9Mgsj/RZ/l/z6n8P83mOX/LnbC/yVEi/8uM2//SEVw/2BZeP90bYX/hYCU/5aT + pP+iobH/rKq5/7Oxv/+4t8X/vLrI/726yf+6t8b/s7HA/62ru/+pprb/qqe3/7GtvP+wrbz/qaa1/52a + qv+MiJv/cGmH/0tAcP8zLGr/LDB3/ytLl/8wesn/Mpjo/zGj8f8wleL/LnG8/yxKlP8pJW7/KBNb/ygV + Xf8pFl//KRdg/yoXYP8qF2H/Khdh/yoXYv8rF2L/Kxdj/ysXY/9iUJb/YlCW/2JQlv9iUJb/YlCW/2JQ + lv9iUJb/Y1CW/2NQlv9jUZb/Y1OY/2Fnqv9ei8r/WaTj/1Ow8f9Mpun/RIjL/0Jop/9GS3//V010/3Vv + hv+KiJX/lpSd/6Cgp/+rrLL/tLW7/7q7wf++vsX/wMDI/8jIz//U1tj/3N/e/9/i4P/W2dn/w8bI/7m6 + wP+5uMH/t7W//7Kxuf+rrLP/o6Sq/5GQnf92b4z/Wk56/z8xaP8wM3X/MFag/zB5x/8ymef/MqHu/zGP + 3P8uarX/LDaA/yoaYv8qF1//KhZf/yoXYP8qF2D/Khdh/ysXYf8rF2L/Kxdi/ysXY/8rF2P/ZFGX/2RR + l/9kUZf/ZFGX/2RRl/9kUZf/ZFKX/2RRl/9kUZf/ZFWa/2Rdov9jeLn/YaLf/1+18f9drer/WpbQ/1l0 + p/9qcZf/jI2k/6WlsP+ytbr/r7O2/52fpf+PkJn/hYWS/358jf94dIv/cWuH/2pjgv94c43/m5qm/7m8 + vv/P1NP/xcrL/52fqP9/fpD/bmiG/2hhgv9sZoT/eHWL/4qKl/+dn6f/rrC4/5uaq/9mX4L/QTtu/zEy + c/8sSJP/MHrI/zKa6P8yoe7/MIbT/y5NmP8sKHL/Kxxk/ysWX/8rF1//Kxdg/ysXYP8rF2D/LBhh/ywY + Yv8sGGP/LBhj/2ZTmf9mU5n/ZlOZ/2ZTmf9mU5n/ZlOZ/2ZTmf9mUpj/ZlKY/2ZboP9lcLL/ZI7N/2Sx + 7f9itu//YJvU/2SDtf9uc5b/iYWZ/7O1uv/DyMn/ur3C/6eosv+NjZz/d3WJ/2Vhe/9WT2//SUBn/0E2 + Yf8/NV//WFJy/4qLmf+prbL/sba7/6mttf+SlqH/fX6Q/2tohv9lYYL/bGmH/3p5kP+Nj5z/oqes/7e9 + v/+us7n/iImb/2BZff87KmT/Kilw/y5Wov8xgM7/MqHu/zKa5v8wa7f/LkKN/ywkbf8rFV3/KxZf/ysX + YP8rF2D/LBdg/ywYYf8sGGL/LBhj/ywYY/9pVZr/aVWa/2lVmv9pVZr/aVWa/2lVmv9pVZr/aVSZ/2lT + mP9oZqn/Z4vK/2ao5P9muPP/Y6jg/158sP9pb5j/hIWc/5+gqv+4vL7/sbO6/4uHn/9zaoz/aWCE/19V + fP9SR3L/RDdn/zYnXP83KVv/SD9l/29thP+orLT/sLe8/4uMnP+HiJn/qK61/7e/w/+yucH/sLfB/7K6 + wv+yusD/rra5/6Oqrv+RlZ//kZaf/6Gpr/+Ki5//TT9y/ywfZP8tMHn/L1ij/zKP3P8zovD/M43b/zFl + sf8tL3j/LBRc/ywWXv8sGGD/LBhh/y0YYf8tGGH/LRhi/y0YY/8uGGT/a1ec/2tXnP9rV5z/a1ec/2tX + nP9rV5z/a1ec/2tXm/9rWJz/anCy/2if3P9ntvD/Z7Lq/2OVy/9dZ5f/bGWI/4+Qn/+prrL/tbq8/6Gi + rv9wZ4r/V0l4/1dKeP9WSnf/UkZ0/0s/bv9ENmf/TEFs/2Ziff+Iipj/rbS5/6Sqsf9xb4b/dHSJ/663 + vP/G0dH/uMDH/7G3wf+0u8P/uMHF/7vHxv+iqbD/b2+H/3JyiP+mr7P/oKew/15Wfv82JmL/Lx5j/y47 + hP8xdsL/NJnn/zSf7f8yfsv/LzyG/y0ZYf8tF2D/LRhg/y0YYf8uGGL/LRhi/y4YY/8uGGT/Lxhk/21Z + nf9tWZ3/bVmd/21Znf9tWZ3/bVmd/21Znf9tW5//bWCj/2x8vP9qrOb/aLjv/2ee1f9jf7L/Xl6M/25k + hv+Rkp//p66w/620tf+Zm6f/bmaJ/1lLef9aTnr/X1R+/2Vegv9rZYX/cGmG/357kf+VmKT/nqWr/5if + pf+EhpP/ZGJ6/3Bwhv+kr7T/qLO5/3p6lP9mYIL/b2yH/4qOnv+xvsD/n6ez/1hPe/9VTHf/lp2p/6Cq + r/9ubIb/SDxq/zQiYP8tK3T/MVek/zOAzv8zoO3/Mo3Z/zFLlv8vI27/Lhtk/y4YYP8uGGH/Lxhi/y8Z + Y/8vGWP/Lxlk/zAZZP9vW5//b1uf/29bn/9vW5//b1uf/29anv9vWp7/b2Cj/29srv9tisj/a7Tt/2m1 + 6v9mjMD/Ymuc/19YhP9vZYb/kZKf/6atsP+rsrT/naGr/397lf9ybI3/enSU/4J/m/+Li6D/kpOk/5ia + p/+lqrH/tsDC/6+5u/+Qlp7/dXaH/2Jgef9ydIn/oK2y/5unrv9iYH7/SEBn/1NObv93eo3/rbu9/52m + tP9NQHX/RTdt/4aLnf+Zpaj/eHyM/1ZPc/85J2L/LCFp/zA8iP8yaLT/M5zn/zOZ4/8yXqn/MTR//y8g + av8uF2D/Lxhh/y8YYv8vGWP/MBlj/zAZZP8wGWT/cVyg/3FcoP9xXKD/cVyg/3FcoP9xXKD/cVuf/3Bm + qf9vfLz/bpnV/2y58P9pr+L/ZX2s/2Fdif9fVH7/b2eG/5CSoP+mrrH/r7e5/6uzt/+eo63/oKSw/7C4 + wP+6xMr/vMbK/7vEyP+3wcP/vMfI/8jV1P+7x8j/l5ym/3t7jf9raYH/en2Q/6Oytv+hsbT/c3mK/15f + df9laHv/gouW/66+v/+bpLP/TUF1/0Ezaf94fJD/jpqe/3uEj/9eXXv/PC1m/ywaYf8uJ3D/MVKb/zOU + 3v80oOr/NHO+/zNJlP8wJ3H/Lxdg/y8YYf8wGWL/MBlj/zAZY/8xGmT/MRpk/3Neov9zXqL/c16i/3Ne + ov9zXqL/c12h/3Ndof9ybK3/cInH/2+k3v9uuO//aqfZ/2Vzn/9hVX7/YFN8/3BoiP+PkqD/p7C0/7bB + wv+4w8P/rre5/664uv+4xMf/vMjL/7nByP+zusP/rbO9/7O7wv/D0dH/u8jJ/5uhq/+Cg5T/c3GJ/4GE + mP+pt7z/rL6+/4uXnf97hI7/gIuU/5KgpP+pvbv/kJqq/0o+cv9AMmj/dHiN/4mWm/95hI7/X2B8/z0u + Z/8sFl3/LRth/zBDiv8ziNL/NZ/p/zWCzv80W6b/MS53/y8XX/8wGGD/MBli/zAZY/8wGWP/MRpk/zEa + ZP92YKP/dmCj/3Zgo/92YKP/dmCj/3Zfov92XqL/dXGx/3KV0P9wrOP/cLPp/2ydz/9mbpn/YlR9/2JU + ff9xaYn/j5Kg/6q1t//Azs3/wM7N/6u2uf+bo6v/kpel/4uLoP+Ef5v/fneX/3x0lf+LiqL/qrW8/7C+ + v/+dpaz/iYub/3l2kP+Hh57/r7vC/7nLyv+ktbX/m6ut/6Cxsv+itrX/n7Sy/32Imf9DN2z/QjVq/3mA + kv+Lmp7/c32K/1dXdv86K2T/LRVb/y4WXP8xOYD/NHnE/zaW4v82jNj/NGm0/zEye/8wFl//MBdg/zEZ + Yv8xGmP/MRpj/zEaZP8yGmX/eGKl/3hipf94YqX/eGKl/3hipf94YaT/eGCj/3Z1tf9zn9f/cbPo/3Gu + 4/9ulcb/aGuW/2RVff9kVn7/c2uK/4+SoP+otLb/vMvK/7fFx/+coq3/hoaa/3h0jv9tZYf/Z1qD/2NU + gP9jU4D/dW2P/5adqv+ms7b/oq2x/5KXpP98d5T/hYKd/6y2vv+7y8r/r8HA/6u+vf+wxcP/qLy7/4+i + pP9rdIf/Qjho/0tCcP+Dj53/j6Cl/2pxhf9LR23/NyZi/y4VW/8uFVr/MTN6/zVtuP82j9v/NpTf/zV1 + v/8yNn//MRZe/zEYYP8xGmL/MRpj/zIaY/8yGmT/Mxpl/3pkpf96ZKX/emSl/3pkpf96ZKX/emOk/3pi + pP94ebf/dKbd/3K36/9yqt7/b4/A/2prlP9mV37/Zld+/3Rsi/+Pk6D/oq6x/6q5uv+fqbH/goCY/3Fn + if9tYYb/al2E/2dZg/9mVoL/ZVaC/3JojP+Ljp//n6qv/6u5uv+eprH/fHaV/3x2lf+fprH/sL6//6u6 + u/+svb3/scbE/6G0tv98iJP/XGB3/0dCaP9aW3r/kaSr/5Onrf9fYH//PjFk/zMfXv8vF1v/LxZb/zEx + d/81ZK7/N4nU/zaa5P81fsf/MzqC/zEXXv8yGGD/Mhti/zIbY/8zG2P/Mxtk/zQbZP98Zqf/fGan/3xm + p/98Zqf/fGan/3xlpv98Zab/en27/3Wt4/9zu+7/c6XY/3CJuP9rapP/aFl//2dZf/91bov/jpSh/56r + rv+grrD/kpml/3Zvjf9qXYP/b2SH/3Nri/92bo7/d3CP/3hwkf+AfZf/kJak/6OwtP+2yMb/rLvA/4qL + ov+Bfpn/lJmm/6Grsf+ls7b/qrq7/62/v/+bqq//dn2N/2Bkev9eYnr/bnqL/46kqP+ElaH/Ukx2/zUi + Xv8xG13/MBhc/zAYXP8yLnT/NVqk/zeCzP82n+j/NYfP/zM+hf8yGF//Mhlg/zIbYv8zG2P/NBtj/zQb + ZP80G2T/fmio/35oqP9+aKj/fmio/35oqP9+Z6j/fmip/3uCv/92s+j/c77v/3Oh0f9xg7D/bGmR/2lb + gP9pW4H/dm+M/46Uof+cqq3/n62v/5KZpP94co//cWiJ/359k/+JjJz/j5Wh/5Obpv+Wn6n/nKav/6Sz + t/+ww8T/wNbT/7zRz/+lsrn/lJuo/42QoP+RlqP/n62x/6a3uP+ktLX/lqKp/36Dk/94f5D/hZee/4ad + oP96j5X/Y2uC/0I2af8xGlz/MBlc/zEZXP8xGFz/Mitw/zZQmv83ecT/NqLq/zWO1v8zQor/Mxpi/zMa + Yf8zG2L/Mxxj/zQcY/81HGT/NRxl/4Bqqv+Aaqr/gGqq/4Bqqv+Aaqr/gGqq/39srP99h8P/d7fr/3W/ + 7/90ncz/cn+r/25pkP9rXYL/a12C/3dwjf+OlKH/nayv/6O0tf+dqbD/jI+i/4iKnv+Sm6X/mqeq/52s + rf+gr7D/orGy/6S0tf+nt7n/rb/A/7bKyv+2ysr/rb/A/6KwtP+Wn6r/l6Cr/6Ozt/+pvLv/pre4/56s + sP+TnKj/laOs/6S9u/+XsLD/bnqK/05Lb/84KGH/Lxdb/zAYXP8xGVz/MRlc/zMobv82SJL/N3O+/zai + 6v81k9r/NEiP/zQeZv8zG2L/Mxti/zQcY/81HGT/NRxl/zUcZf+CbKv/gmyr/4Jsq/+CbKv/gmyr/4Jt + rP+Bca//f4zG/3m57P92v+3/dpzJ/3N+qf9vao//bV+D/21fg/94cY7/jZWh/5+wsv+swcD/sMbG/63A + w/+qvL//p7q6/6S1tf+gr7D/nKqt/5qmq/+Yo6n/l6Kp/5eiqv+ZpKz/nKmw/6KxtP+oubv/rsLD/7HG + x/+wxcX/sMXE/7HHxP+xxsX/sMTG/7PJyf+40s7/n7K4/2tpiv9HOGv/NyJf/zAYW/8wGVv/MRlc/zEZ + XP8zJ2z/NkSN/zdvuP82ouj/Npbb/zVOlf81JGv/NB1k/zQbYv80HGL/NRxk/zYcZf82HGX/hG6t/4Ru + rf+Ebq3/hG6t/4Rurf+Eb67/g3Wy/4CPyP97u+z/eL/s/3ebyP91faf/cWuQ/25hhP9uYYX/eXKP/46V + of+gsrP/r8bE/7XNy/+wxsb/qry//6Kwtv+bpq7/lZyn/5CVov+MkJ//ioyd/4iJm/+Ghpn/hISY/4eK + nP+Rl6X/naix/6q7wP+uwcX/qry//6m7vf+rvr//rcDC/7DBxf+1ysz/vNXT/6W1v/9yapH/UTxz/0Mu + af86JGP/NB1e/zEZXP8yGVz/NCdr/zdCiv84bbX/N6Hm/zaY3P82Upn/Nihv/zUfZf81HGL/NRxj/zYc + ZP82HGX/Nxxl/4Zvrv+Gb67/hm+u/4Zvrv+Gb67/hnGw/4V3tf+Ckcr/fbzt/3rA7P95m8f/dn6n/3Js + kf9wYob/cGKG/3p0j/+OlaH/n7Gy/6zDwf+pvb//lqCs/4qMn/+EgZr/gHqW/353lP99dZP/fHOS/3ty + kf97cZH/enCR/3lvkf96cZL/fXaV/4N9mv+KiKH/j5Km/5GYp/+TnKj/lJyo/5OZp/+RlKf/nKW0/7LI + yv+pusP/gnud/2hVhv9dSn7/Tztz/zwmZP8zGlz/Mxlc/zUma/84QYn/OGy0/zeh5v82md3/N1Sb/zcq + cf82H2b/Nhti/zYcY/83HGT/Nx1l/zgdZf+IcbD/iHGw/4hxsP+Ica//iHCv/4hzsf+Hebf/hJPM/36+ + 7f97wOz/epvG/3h+p/90bZL/cWSH/3Jkh/97dZD/jpah/52vsP+mu7r/na2z/4WGmv93bYz/dGaK/3Jj + iv9zY4r/c2SL/3Nki/90Zoz/dmiN/3dqjv93ao//dmmP/3Vnjv91aI7/eGuQ/3xzk/+BfZf/g4GZ/4OA + mf+BfZf/f3qW/46Rpv+swcX/q73E/4qFpP91ZJH/b12M/2JPgv9NOHL/Pydm/zceYP81Jmv/OECI/zhr + s/83oeX/N5rd/zhVnP84K3P/NyBn/zYcY/83HGP/Nxxk/zgdZf84HWX/inKx/4pysf+KcrH/inKw/4py + sP+KdbP/iXy5/4WWzf+Av+7/fMHs/3ubxv95fqf/dm6S/3NmiP9zZYn/fXaS/4+Xov+aq63/nrKx/5Wh + qf+Ae5X/dWeL/3Rli/90ZYv/dGWL/3RljP90Zoz/dmmN/3pvj/98c5H/fXWS/3t0kv94bpH/d2qQ/3dp + kP94apH/em6S/3tvk/98b5T/fHGU/312lf+Nkqb/q8HE/6q9w/+KhqT/eWiT/3dmkv9yYI7/ZlSF/1ZB + eP9BKGf/Nydr/zg/hv85abH/N6Hl/zea3v85V57/OSx1/zchaP83HGP/Nxxj/zgdZP84HWX/OB1m/4x0 + sf+MdLH/jHSx/4xzsf+Mc7H/i3e0/4p+uv+HmM//gcDu/37B6/98m8b/en+n/3dvk/91Z4n/dWeK/354 + kv+Pl6L/mKqr/5qtrf+Snqb/g4GX/3x0kv9/eZX/gn6Z/4SBnP+Fg57/hoWe/4eJoP+LjaH/jZGj/42S + o/+MkaP/io2j/4iJo/+HhqL/h4Og/4WBn/+Efpz/gnqa/4B5mP+AfJj/j5an/6rCw/+ovML/ioak/3pq + lf97a5b/e2qV/3dlkv9pVob/Uz11/0Q2df8+Q4n/Ommw/zih5P84m9//OVig/zkudv84IWj/Nxxj/zgd + Y/84HWT/OB1l/zgdZv+NdbL/jXWy/411sv+NdbL/jXWy/414tf+Lgbz/iJrQ/4LB7/9/wuv/fZzE/3t/ + pv94cJP/dmiK/3Zoiv9+eZP/jpii/5eqq/+Zrq7/laWq/4yUoP+LkZ//kp2o/5qpsf+gsrn/pLm+/6a8 + wP+mvsD/p73A/6a9v/+lvL7/pr2+/6a+wP+mvsH/pbzB/6O4vv+gsrr/mqqz/5Ofqf+NlKL/iIyd/5Kd + qf+pw8P/przB/4qHpP97a5X/fGyW/31tl/99bJb/d2WR/2xZif9dUYj/S06P/z5qr/85oeT/N5zf/zla + ov86MHj/OCJp/zgcYv84HWP/OB1l/zkdZv86Hmb/j3e0/493tP+Pd7T/j3e0/493tP+Perf/jYO9/4mc + 0f+Ew+//gMPr/3+cxP98gKX/eXGT/3hqi/94aov/gHqT/46Yov+Zra7/nra1/520tP+WqKv/laWq/5qu + sP+ftbb/o7u9/6a+wf+ov8L/qL7B/6e7wP+mub7/pbm9/6W6vv+nvcD/qL/C/6e/wv+mvsD/pLy9/6C3 + t/+ar7D/lqer/5Oiqf+brrP/qsjF/6W7wf+LiKX/fW2W/35ul/9/b5j/gG+Z/39umP98a5X/cWWV/15f + mf9NdrX/P6bl/zmd3/86XKP/OjF6/zkjaf84HGL/OB1j/zoeZ/8+H2v/PyBu/5J5tv+Sebb/knm2/5J5 + tv+Sebb/kXy5/4+Gv/+LntP/hsTw/4LD6/+BnMP/foGl/3tzlP96bIz/emyN/4F7lP+OmKL/nLGy/6jF + wv+pyMT/oLq5/5musP+Vp6r/kqCn/4+Zpv+Nk6X/jIyj/4yJov+MiKL/jIii/4uIof+LiKL/jImj/42L + pP+OjqX/j5Sm/5KdqP+Uo6r/lqis/5qvsv+hurv/qMbD/67Qyv+ku8D/jIml/4Bvl/+AcJj/gXGa/4Fx + mv+BcZr/gXCZ/35xnf93dab/ZovB/0yu6f89nt//PF6k/zszfP85I2r/ORxi/zodZP8+IGv/RSN3/0gl + ff+Ue7f/lHu3/5R7t/+Ue7f/lHu3/5N/uv+RiMH/jaDU/4fF8P+Ew+r/gpzD/4CBpf99dZX/e26O/3xu + jv+CfJX/jpii/5uysv+pycT/qcjG/52xtv+ToKn/jZWh/4eLm/+DgZj/gHiV/35wkv9+bZH/fm6S/35u + k/9+bpP/fm6T/35ulP9/cJX/gHOW/4J6mP+GhJv/io6f/4+Wpf+WpK7/oLe6/6jHw/+sz8n/o7q//42J + pf+CcJn/gnGa/4Nzm/+Dc5v/g3Ob/4Rym/+Ed6H/hYGt/3iYyP9etuv/TKTg/0Jipv88Nn3/OiRq/zsd + ZP8+IGr/RCN0/0smgP9OKIb/lX24/5V9uP+Vfbj/lX24/5V9t/+Ugbv/korC/4+j1f+JxvH/hcPq/4Oc + wv+BgaX/fnWW/31vj/99b4//gn2W/42Yof+Yr67/ob+8/561uP+OkaT/hH6Y/4N7lv+CeZX/gXaU/4Bz + lP+AcZP/f3CT/4BwlP+AcZT/gHGU/4Bxlf+AcJX/gHGW/4Fyl/+CdZj/g3iZ/4V7mv+GfZz/ioig/5Gc + p/+asrP/psfC/6G5vf+Niqb/g3Ka/4Rzm/+EdJz/hHSc/4R0nP+FdJz/hnmi/4eDrv+CnMj/d7/s/2Wu + 4v9Oaan/QDqA/zwmbP8+H2n/RiN2/0wngf9PKYf/USmK/5d/uf+Xf7n/l3+5/5d+uP+Xfrj/loO8/5SN + xP+Qpdf/isfx/4bE6v+FncL/g4Gl/4B1lv9+cI//fnCQ/4J7lf+KkJ3/k6Wp/5y3tf+asbT/jZKk/4WB + mv+Ef5n/hH6Y/4N8l/+Depb/gnmW/4J3lv+CdpX/gnWW/4J1lv+DdZf/g3aY/4N4mP+EeZn/hHua/4V9 + mv+Gf5z/h4Ge/4qLof+QnKf/l66v/5+9uv+bsLb/jIik/4Rzm/+FdJv/hnWc/4Z1nP+GdZz/hnSc/4d5 + ov+Iha//iJ/J/4XF7f93uOX/YHqz/09KjP9FLnb/RCNy/0wmgP9RKYn/UiqL/1MqjP+YgLr/mIC6/5iA + uv+YgLr/mIC6/5eEvf+Vj8X/kabY/4vI8f+Ixuv/h6DE/4SEp/+Bd5f/gHGP/4BxkP+Bd5P/hYGX/42V + ov+ZsbL/nry5/5u0tf+Wqq//kKCo/4uXov+KkJ7/iIqb/4aGmf+Egpj/hH6X/4N7l/+Depj/hHuZ/4V/ + mv+Hgpv/iIad/4mLnv+LkqD/jpmk/5Ghqv+WrLH/nbq6/568uv+YsbH/kZ2o/4mDoP+Gdpz/h3ad/4d3 + nf+Hdp3/h3ac/4d1nP+Ie6P/ioex/4uiy/+Jx+3/g8Lr/3mSw/9qZKH/Vj2J/04pgf9RKYj/UyqM/1Mr + jP9UK43/moK8/5qCvP+agrz/moK8/5qCu/+Zhb7/mI7F/5Ol1v+NyPD/icvw/4mw1P+Hmr3/hoyt/4SD + pP+EgKH/hH6e/4V/nP+KiqD/k6Cq/5qwsf+ct7X/mrez/5Wvrf+SqKn/kaOn/5Cfpv+OnKX/jpmk/42W + pP+NlKT/jZOl/46Upf+Ol6b/j5qn/5Ccp/+RoKj/kqWo/5Oqqv+Wr67/mrW0/5+5uv+csbb/kp2o/4uM + oP+Jfp7/iHie/4l7ov+KfqX/ioGo/4qEq/+Kh67/i4+2/4ycxP+Msdn/i8zx/4vG7f+Kn83/gHex/21S + nf9fOpL/WC+O/1Qrjf9VK43/VSuO/5yEvf+chL3/nIS9/5yEvf+chL3/nIa//5qMw/+WodP/j8Xt/4vT + 9/+LzO//jMDk/4yz1/+Mp8z/i5zB/4qTt/+Ji63/iYem/4uHoP+Nj6D/kJyk/5KlqP+Uqqr/la6t/5ez + sv+Zt7X/m7m4/527uv+evLv/n728/5+9vf+evLz/nby7/527uv+cubn/mre2/5izsf+Wr67/lKur/5Sk + qf+Tmaj/kY+l/42FoP+Lfp7/i3ue/4t9o/+NhKz/joy1/4+Vvv+Pn8f/jqnR/4602/+Nweb/jMzw/4zU + +P+Pxez/lKDQ/5KCu/+Hba//dlSj/2E4lf9WK47/ViuO/1Ysj/+ehr//noa//56Gv/+ehr7/noa+/56H + v/+dicH/mpnM/5S14f+Rx+7/kM3z/5DN8v+Rxu3/kL/l/4+33f+OrtP/jaXJ/4ucvv+Jk7T/iZSw/4uf + sv+Pp7b/kq65/5a0vf+ZusH/m77F/57Bx/+gxMn/ocbK/6LHyv+ixsr/ocbJ/6DEx/+fwsb/nsDF/5y8 + wv+Ytr7/lbG6/5Ortv+RorP/jpax/42Qsf+MjrL/jI+0/42Stv+Nl7z/jp7F/4+nzv+QsNf/kLjf/5DA + 5/+Qx+7/kM3z/5DO8/+Rx+7/lbbh/5uazf+ciMD/mH67/4lpsP9vSZ//XzWU/1kukP9XK4//oIfA/6CH + wP+gh8D/oIe//6CHv/+gh8D/oIjA/56OxP+cms3/mabW/5ez4P+Vvef/k8Pr/5HJ7v+QzPD/j83v/47K + 7P+Oxuj/jcLk/43A4f+PwN//kL/c/5K92v+Tu9j/lLjV/5W20/+WtdL/l7XR/5e00P+Xs87/l7HN/5ew + zP+XsMv/lrDM/5awzf+VsM3/lLDO/5Owzv+Ssc7/kbHQ/5Gx0/+Qs9f/j7fb/4+73/+PwOP/j8Tm/4/H + 6v+Pyu3/j83w/5DN8f+RyvD/ksXt/5S+6P+WtOD/mafX/5yazf+fj8X/oIjA/5+Gv/+Vebj/gmGs/3BK + n/9fNZT/VyuP/6KJwf+iicH/oonB/6KJwf+iicH/oonA/6KIwP+iicH/oYzC/5+Sx/+dntD/m6nY/5iz + 3/+WvOb/lcXs/5TK8P+TzfL/k8/z/5PQ9f+Tz/T/k83y/5PK7/+Sxu3/ksPp/5K/5v+SvOP/kbrg/5G5 + 3/+Rt97/kbbc/5G02v+Rs9r/kbPa/5G02/+Rttz/kbje/5G54P+Su+H/kr3j/5LA5v+TxOn/k8ft/5PK + 7/+TzfL/k8/0/5PQ9P+Sz/P/k83y/5PK8P+Uxez/lr3n/5e14f+aq9n/nZ/R/5+TyP+hi8P/oonB/6KJ + wf+jisH/noO+/5N2t/+BX6v/akKb/14zk/+jisL/o4rC/6OKwv+jisL/o4rC/6OKwf+jisH/o4rB/6OL + wv+jjcP/opHG/6GUyf+gmMv/n5zO/56h0v+dp9f/m6/c/5q14f+ZuuX/mL7o/5fC6v+Vxez/lMnv/5TL + 8P+TzPH/k83x/5LO8f+Rz/L/kdDy/5HQ8v+Rz/L/kc/x/5HP8f+Rz/L/kdDy/5HQ8v+Rz/L/ks/y/5PO + 8v+TzPH/lMvw/5XJ7v+Wxuz/l8Lp/5i+5/+ZueT/mrXg/5uv3P+cp9f/nqHS/5+cz/+gmMz/oZXJ/6KR + xv+jjcP/o4vC/6OKwv+jisL/pIvC/6OJwf+ghr//kXO1/3lUpv9tRJ7/pIvC/KSLwv2ljML+pYzC/6WM + wv+ljML/pYzC/6WMwv+ljML/pYvC/6WLwv+li8L/pYrB/6WLwv+kjsT/o5PH/6Gazf+goNH/n6XV/56q + 2f+cr9z/m7Xg/5q65P+Zvuf/mcHp/5jD6/+Xxez/l8ft/5fI7v+Xye//l8nv/5fK8P+XyvD/l8rv/5fJ + 7/+XyO7/l8ft/5fF7P+Yw+v/mcHp/5m95v+aueP/nLXf/52v3P+eqtj/n6XV/6Cg0f+hms3/o5PH/6SO + xP+li8L/pYrB/6WLwv+li8L/pYvC/6WMwv+ljML/pYzC/6WMwv+ljcP/po3D/5yBvf6KarH9gV2r/KSK + wvWli8L4po3D/aaNxP+mjcP/po3D/6aNw/+mjcP/po3D/6aNw/+mjcP/po3D/6aMw/+mjcP/po3E/6aP + xf+lkcb/pZPI/6SVyf+kl8r/pJjL/6Oazf+jnM7/o53P/6Ke0P+in9H/oqDR/6Kg0f+iodL/oqLT/6Gj + 1P+hpNT/oaTU/6Gj1P+iotL/oqHS/6Kg0f+ioNH/op/R/6Ke0P+jnc//o5zO/6Oazf+kmMv/pJbK/6SV + yf+lk8j/pZHG/6aPxf+mjcT/po3D/6aMw/+mjcP/po3D/6aNw/+mjcP/po3D/6aNw/+mjcP/p47E/6eO + xP+jisL9nYG++Jl8u/WjicLnpYrD7qeNxPmoj8X/qI/F/6iPxf+oj8X/qI/F/6iPxf+oj8X/qI/F/6iP + xf+oj8X/qI/F/6iPxf+ojsX/qI7E/6iOxP+ojsT/qI7E/6iOxP+ojcT/qI3E/6iNxP+ojcT/qI3D/6iN + w/+ojcT/qI3E/6iNxf+oj8X/qJDG/6iQxv+oj8X/qI7E/6iNw/+ojcP/qI3D/6iNxP+ojcT/qI3E/6iN + xP+ojcT/qI7E/6iOxP+ojsT/qI7E/6iOxP+ojsX/qI/F/6iPxf+oj8X/qI/F/6iPxf+oj8X/qI/F/6iP + xf+oj8X/qI/F/6iPxf+oj8X/qI7F+aeOxO6njcTooobB0aSJw92ojsX0qpDG/6qQxv+qkMb/qpDG/6qQ + xv+qkMb/qpDG/6qQxv+qkMb/qpDG/6qQxv+qkMb/qpDG/6qQxv+qkMb/qpDG/6qQxv+qkMb/qo/G/6qP + xv+qj8b/qo/G/6qPxf+qj8X/qo/G/6qPxv+qj8b/qpDG/6qQxv+qkMb/qpDG/6qPxv+qj8X/qo/F/6qP + xf+qj8X/qo/G/6qPxv+qj8b/qo/G/6qQxv+qkMb/qpDG/6qQxv+qkMb/qpDG/6qQxv+qkMb/qpDG/6qQ + xv+qkMb/qpDG/6qQxv+qkMb/qpDG/6qQxv+qkMb/qpDG/6mQxvSoj8Xep47F0qCEwJukiMO1qY/G56uS + x/+sksj/rJLI/6ySyP+sksj/rJLI/6ySyP+sksj/rJLI/6ySyP+sksj/rJLI/6ySyP+sksj/rJLI/6yS + yP+sksj/rJLI/6ySyP+sksj/rJLI/6ySyP+sksj/rJLI/6ySyP+sksj/rJLH/6ySx/+sksf/rJLH/6yS + x/+sksj/rJLI/6ySyP+sksj/rJLI/6ySyP+sksj/rJLI/6ySyP+sksj/rJLI/6ySyP+sksj/rJLI/6yS + yP+sksj/rJLI/6ySyP+sksj/rJLI/6ySyP+sksj/rJLI/6ySyP+sksj/rJLI/6ySyP+rksfoqZDGuKiP + xp+af75Jo4nDeKqQxtCsksj/rZPI/62Uyf+tk8n/rZPJ/62Tyf+tk8n/rZPJ/62Tyf+tk8n/rZPJ/62T + yf+tk8n/rZPJ/62Tyf+tk8n/rZPJ/62Tyf+tk8n/rZPJ/62Tyf+tk8n/rZPJ/62Tyf+tk8n/rZPJ/62T + yP+tk8j/rZPI/62TyP+tk8j/rZPJ/62Tyf+tk8n/rZPJ/62Tyf+tk8n/rZPJ/62Tyf+tk8n/rZPJ/62T + yf+tk8n/rZPJ/62Tyf+tk8n/rZPJ/62Tyf+tk8n/rZPJ/62Tyf+tk8n/rZPJ/62TyP+tk8n/rZPJ/66U + yf+ulMn/rpXJ062UyX2sk8hRjXW3FqKJwkKpj8aWq5DH0KyRyOetksj0rpTJ+q6Uyf2vlcn+r5XK/6+V + yv+vlcr/r5XK/6+Vyv+vlcr/r5XK/6+Vyv+vlcr/r5XK/6+Vyv+vlcr/r5XK/6+Vyv+vlcr/r5XK/6+V + yv+vlcr/r5XK/6+Vyv+vlcr/r5XK/6+Vyv+vlcr/r5XK/6+Vyv+vlcr/r5XK/6+Vyv+vlcr/r5XK/6+V + yv+vlcr/r5XK/6+Vyv+vlcr/r5XK/6+Vyv+vlcr/r5XK/6+Vyv+vlcr/r5XK/6+Vyv+vlcr/r5XK/6+V + yv6vlcr9r5XK+q6UyfWulMnpr5XK07CWypuxmMtItpvNHYZvswWehcAZoonCQqaKxHiojMa2q47H3q6S + yO6vlcn4sJbK/bCWy/+wlsv/sJbL/7CWy/+wlsv/sJbL/7CWy/+wlsv/sJbL/7CWy/+wlsv/sJbL/7CW + y/+wlsv/sJbL/7CWy/+wlsv/sJbL/7CWy/+wlsv/sJbL/7CWy/+wlsv/sJbL/7CWy/+wlsv/sJbL/7CW + y/+wlsv/sJbL/7CWy/+wlsv/sJbL/7CWy/+wlsv/sJbL/7CWy/+wlsv/sJbL/7CWy/+wlsv/sJbL/7CW + y/+wlsv/sJbL/7CWy/+wl8v9sJfL+bCWy/CvlMngrpTJurCVyn+yl8xIs5jMHbmfzweQd7gAhW+yBox0 + thaegsBKpYfEnKmMxtKtksjosJXK9rGXy/yxl8v/sZfL/7GXy/+xl8v/sZfL/7GXy/+xl8v/sZfL/7GX + y/+xl8v/sZfL/7GXy/+xl8v/sZfL/7GXy/+xl8v/sZfL/7GXy/+xl8v/sZfL/7GXy/+xl8v/sZfL/7GX + y/+xl8v/sZfL/7GXy/+xl8v/sZfL/7GXy/+xl8v/sZfL/7GXy/+xl8v/sZfL/7GXy/+xl8v/sZfL/7GX + y/+xl8v/sZfL/7GXy/+xl8v/sZfL/7GXy/+xl8v/sZfL/bGYzPewl8vqr5TJ1a6TyKKxlMpTtpbOHreX + zwi1ls4AgAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAE= + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/CommonObjects/Properties/AssemblyInfo.cs b/Demo_Source_Code/CSharpDemo/CommonObjects/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..03344cb --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/CommonObjects/Properties/AssemblyInfo.cs @@ -0,0 +1,37 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("CommonObjects")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("EaseFilter Technologies")] +[assembly: AssemblyProduct("EaseFilter CommonObjects")] +[assembly: AssemblyCopyright("Copyright © 2024 EaseFilter Technologies")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("a9fd3093-71e2-49d4-9093-b4300674e1e3")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +[assembly: AssemblyVersion("5.4.4.3001")] +//[assembly: AssemblyVersion("2.1.1.*")] +////[assembly: AssemblyFileVersion("2.1.1.*")] + diff --git a/Demo_Source_Code/CSharpDemo/CommonObjects/Properties/Resources.Designer.cs b/Demo_Source_Code/CSharpDemo/CommonObjects/Properties/Resources.Designer.cs new file mode 100644 index 0000000..6cb2118 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/CommonObjects/Properties/Resources.Designer.cs @@ -0,0 +1,73 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace EaseFilter.CommonObjects.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // 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", "16.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + 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() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [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("EaseFilter.CommonObjects.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap about { + get { + object obj = ResourceManager.GetObject("about", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + } +} diff --git a/Demo_Source_Code/CSharpDemo/CommonObjects/Properties/Resources.resx b/Demo_Source_Code/CSharpDemo/CommonObjects/Properties/Resources.resx new file mode 100644 index 0000000..bf14fc6 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/CommonObjects/Properties/Resources.resx @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + ..\Resources\about.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/CommonObjects/RegistryAccessControlForm.Designer.cs b/Demo_Source_Code/CSharpDemo/CommonObjects/RegistryAccessControlForm.Designer.cs new file mode 100644 index 0000000..3e0f9d7 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/CommonObjects/RegistryAccessControlForm.Designer.cs @@ -0,0 +1,329 @@ +namespace EaseFilter.CommonObjects +{ + partial class RegistryAccessControlForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.groupBox_AccessControl = new System.Windows.Forms.GroupBox(); + this.button_Apply = new System.Windows.Forms.Button(); + this.button_DeleteFilter = new System.Windows.Forms.Button(); + this.button_AddFilter = new System.Windows.Forms.Button(); + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.listView_FilterRules = new System.Windows.Forms.ListView(); + this.groupBox2 = new System.Windows.Forms.GroupBox(); + this.label4 = new System.Windows.Forms.Label(); + this.button_Info = new System.Windows.Forms.Button(); + this.label2 = new System.Windows.Forms.Label(); + this.checkBox_isExcludeFilter = new System.Windows.Forms.CheckBox(); + this.button_SelectRegistryCallbackClass = new System.Windows.Forms.Button(); + this.textBox_AccessFlags = new System.Windows.Forms.TextBox(); + this.textBox_RegistryCallbackClass = new System.Windows.Forms.TextBox(); + this.button_SelectProcessId = new System.Windows.Forms.Button(); + this.label1 = new System.Windows.Forms.Label(); + this.textBox_ProcessId = new System.Windows.Forms.TextBox(); + this.label_AccessFlags = new System.Windows.Forms.Label(); + this.label17 = new System.Windows.Forms.Label(); + this.button_SelectRegistryAccessFlags = new System.Windows.Forms.Button(); + this.label22 = new System.Windows.Forms.Label(); + this.textBox_ProcessName = new System.Windows.Forms.TextBox(); + this.groupBox_AccessControl.SuspendLayout(); + this.groupBox1.SuspendLayout(); + this.groupBox2.SuspendLayout(); + this.SuspendLayout(); + // + // groupBox_AccessControl + // + this.groupBox_AccessControl.Controls.Add(this.button_Apply); + this.groupBox_AccessControl.Controls.Add(this.button_DeleteFilter); + this.groupBox_AccessControl.Controls.Add(this.button_AddFilter); + this.groupBox_AccessControl.Controls.Add(this.groupBox1); + this.groupBox_AccessControl.Controls.Add(this.groupBox2); + this.groupBox_AccessControl.Dock = System.Windows.Forms.DockStyle.Fill; + this.groupBox_AccessControl.Location = new System.Drawing.Point(0, 0); + this.groupBox_AccessControl.Name = "groupBox_AccessControl"; + this.groupBox_AccessControl.Size = new System.Drawing.Size(546, 459); + this.groupBox_AccessControl.TabIndex = 25; + this.groupBox_AccessControl.TabStop = false; + // + // button_Apply + // + this.button_Apply.DialogResult = System.Windows.Forms.DialogResult.OK; + this.button_Apply.Location = new System.Drawing.Point(375, 375); + this.button_Apply.Name = "button_Apply"; + this.button_Apply.Size = new System.Drawing.Size(138, 23); + this.button_Apply.TabIndex = 80; + this.button_Apply.Text = "Apply Filter Rule Settings"; + this.button_Apply.UseVisualStyleBackColor = true; + this.button_Apply.Click += new System.EventHandler(this.button_Apply_Click); + // + // button_DeleteFilter + // + this.button_DeleteFilter.Location = new System.Drawing.Point(190, 375); + this.button_DeleteFilter.Name = "button_DeleteFilter"; + this.button_DeleteFilter.Size = new System.Drawing.Size(103, 23); + this.button_DeleteFilter.TabIndex = 79; + this.button_DeleteFilter.Text = "Delete Filter Rule"; + this.button_DeleteFilter.UseVisualStyleBackColor = true; + this.button_DeleteFilter.Click += new System.EventHandler(this.button_DeleteFilter_Click); + // + // button_AddFilter + // + this.button_AddFilter.Location = new System.Drawing.Point(6, 375); + this.button_AddFilter.Name = "button_AddFilter"; + this.button_AddFilter.Size = new System.Drawing.Size(116, 23); + this.button_AddFilter.TabIndex = 78; + this.button_AddFilter.Text = "Add New Filter Rule"; + this.button_AddFilter.UseVisualStyleBackColor = true; + this.button_AddFilter.Click += new System.EventHandler(this.button_AddFilter_Click); + // + // groupBox1 + // + this.groupBox1.Controls.Add(this.listView_FilterRules); + this.groupBox1.Location = new System.Drawing.Point(6, 270); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size(517, 93); + this.groupBox1.TabIndex = 77; + this.groupBox1.TabStop = false; + this.groupBox1.Text = "Registry Filter Rule Collection"; + // + // listView_FilterRules + // + this.listView_FilterRules.Dock = System.Windows.Forms.DockStyle.Fill; + this.listView_FilterRules.FullRowSelect = true; + this.listView_FilterRules.Location = new System.Drawing.Point(3, 16); + this.listView_FilterRules.Name = "listView_FilterRules"; + this.listView_FilterRules.Size = new System.Drawing.Size(511, 74); + this.listView_FilterRules.TabIndex = 1; + this.listView_FilterRules.UseCompatibleStateImageBehavior = false; + this.listView_FilterRules.View = System.Windows.Forms.View.Details; + // + // groupBox2 + // + this.groupBox2.Controls.Add(this.label4); + this.groupBox2.Controls.Add(this.button_Info); + this.groupBox2.Controls.Add(this.label2); + this.groupBox2.Controls.Add(this.checkBox_isExcludeFilter); + this.groupBox2.Controls.Add(this.button_SelectRegistryCallbackClass); + this.groupBox2.Controls.Add(this.textBox_AccessFlags); + this.groupBox2.Controls.Add(this.textBox_RegistryCallbackClass); + this.groupBox2.Controls.Add(this.button_SelectProcessId); + this.groupBox2.Controls.Add(this.label1); + this.groupBox2.Controls.Add(this.textBox_ProcessId); + this.groupBox2.Controls.Add(this.label_AccessFlags); + this.groupBox2.Controls.Add(this.label17); + this.groupBox2.Controls.Add(this.button_SelectRegistryAccessFlags); + this.groupBox2.Controls.Add(this.label22); + this.groupBox2.Controls.Add(this.textBox_ProcessName); + this.groupBox2.Location = new System.Drawing.Point(6, 19); + this.groupBox2.Name = "groupBox2"; + this.groupBox2.Size = new System.Drawing.Size(517, 245); + this.groupBox2.TabIndex = 76; + this.groupBox2.TabStop = false; + this.groupBox2.Text = "Add or Edit The Registry Filter Rule Entry"; + // + // label4 + // + this.label4.AutoSize = true; + this.label4.Location = new System.Drawing.Point(201, 40); + this.label4.Name = "label4"; + this.label4.Size = new System.Drawing.Size(152, 13); + this.label4.TabIndex = 93; + this.label4.Text = "(skip processId check if it is 0 )"; + // + // button_Info + // + this.button_Info.Image = global::EaseFilter.CommonObjects.Properties.Resources.about; + this.button_Info.Location = new System.Drawing.Point(465, 176); + this.button_Info.Name = "button_Info"; + this.button_Info.Size = new System.Drawing.Size(41, 20); + this.button_Info.TabIndex = 92; + this.button_Info.UseVisualStyleBackColor = true; + this.button_Info.Click += new System.EventHandler(this.button_Info_Click); + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(201, 83); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(153, 13); + this.label2.TabIndex = 90; + this.label2.Text = "(use * to include all processes )"; + // + // checkBox_isExcludeFilter + // + this.checkBox_isExcludeFilter.AutoSize = true; + this.checkBox_isExcludeFilter.Location = new System.Drawing.Point(203, 176); + this.checkBox_isExcludeFilter.Margin = new System.Windows.Forms.Padding(1); + this.checkBox_isExcludeFilter.Name = "checkBox_isExcludeFilter"; + this.checkBox_isExcludeFilter.Size = new System.Drawing.Size(172, 17); + this.checkBox_isExcludeFilter.TabIndex = 89; + this.checkBox_isExcludeFilter.Text = "Is Excluded Registry Filter Rule"; + this.checkBox_isExcludeFilter.UseVisualStyleBackColor = true; + // + // button_SelectRegistryCallbackClass + // + this.button_SelectRegistryCallbackClass.Location = new System.Drawing.Point(465, 146); + this.button_SelectRegistryCallbackClass.Name = "button_SelectRegistryCallbackClass"; + this.button_SelectRegistryCallbackClass.Size = new System.Drawing.Size(41, 20); + this.button_SelectRegistryCallbackClass.TabIndex = 88; + this.button_SelectRegistryCallbackClass.Text = "..."; + this.button_SelectRegistryCallbackClass.UseVisualStyleBackColor = true; + this.button_SelectRegistryCallbackClass.Click += new System.EventHandler(this.button_SelectRegistryCallbackClass_Click); + // + // textBox_AccessFlags + // + this.textBox_AccessFlags.Location = new System.Drawing.Point(203, 110); + this.textBox_AccessFlags.Name = "textBox_AccessFlags"; + this.textBox_AccessFlags.ReadOnly = true; + this.textBox_AccessFlags.Size = new System.Drawing.Size(242, 20); + this.textBox_AccessFlags.TabIndex = 73; + this.textBox_AccessFlags.Text = "0"; + // + // textBox_RegistryCallbackClass + // + this.textBox_RegistryCallbackClass.Location = new System.Drawing.Point(203, 146); + this.textBox_RegistryCallbackClass.Name = "textBox_RegistryCallbackClass"; + this.textBox_RegistryCallbackClass.ReadOnly = true; + this.textBox_RegistryCallbackClass.Size = new System.Drawing.Size(242, 20); + this.textBox_RegistryCallbackClass.TabIndex = 87; + this.textBox_RegistryCallbackClass.Text = "0"; + // + // button_SelectProcessId + // + this.button_SelectProcessId.Location = new System.Drawing.Point(466, 17); + this.button_SelectProcessId.Name = "button_SelectProcessId"; + this.button_SelectProcessId.Size = new System.Drawing.Size(41, 20); + this.button_SelectProcessId.TabIndex = 14; + this.button_SelectProcessId.Text = "..."; + this.button_SelectProcessId.UseVisualStyleBackColor = true; + this.button_SelectProcessId.Click += new System.EventHandler(this.button_SelectProcessId_Click); + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(6, 151); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(159, 13); + this.label1.TabIndex = 86; + this.label1.Text = "Register Registry Callback Class"; + // + // textBox_ProcessId + // + this.textBox_ProcessId.Location = new System.Drawing.Point(203, 17); + this.textBox_ProcessId.Name = "textBox_ProcessId"; + this.textBox_ProcessId.Size = new System.Drawing.Size(242, 20); + this.textBox_ProcessId.TabIndex = 11; + this.textBox_ProcessId.Text = "0"; + // + // label_AccessFlags + // + this.label_AccessFlags.AutoSize = true; + this.label_AccessFlags.Location = new System.Drawing.Point(7, 24); + this.label_AccessFlags.Name = "label_AccessFlags"; + this.label_AccessFlags.Size = new System.Drawing.Size(97, 13); + this.label_AccessFlags.TabIndex = 12; + this.label_AccessFlags.Text = "Filter By Process Id"; + // + // label17 + // + this.label17.AutoSize = true; + this.label17.Location = new System.Drawing.Point(6, 115); + this.label17.Name = "label17"; + this.label17.Size = new System.Drawing.Size(147, 13); + this.label17.TabIndex = 72; + this.label17.Text = "Registry Access Control Flags"; + // + // button_SelectRegistryAccessFlags + // + this.button_SelectRegistryAccessFlags.Location = new System.Drawing.Point(465, 110); + this.button_SelectRegistryAccessFlags.Name = "button_SelectRegistryAccessFlags"; + this.button_SelectRegistryAccessFlags.Size = new System.Drawing.Size(41, 20); + this.button_SelectRegistryAccessFlags.TabIndex = 74; + this.button_SelectRegistryAccessFlags.Text = "..."; + this.button_SelectRegistryAccessFlags.UseVisualStyleBackColor = true; + this.button_SelectRegistryAccessFlags.Click += new System.EventHandler(this.button_SelectRegistryAccessFlags_Click); + // + // label22 + // + this.label22.AutoSize = true; + this.label22.Location = new System.Drawing.Point(7, 59); + this.label22.Name = "label22"; + this.label22.Size = new System.Drawing.Size(130, 13); + this.label22.TabIndex = 78; + this.label22.Text = "Filter By Processes Name "; + // + // textBox_ProcessName + // + this.textBox_ProcessName.Location = new System.Drawing.Point(203, 59); + this.textBox_ProcessName.Name = "textBox_ProcessName"; + this.textBox_ProcessName.Size = new System.Drawing.Size(242, 20); + this.textBox_ProcessName.TabIndex = 77; + this.textBox_ProcessName.Text = "*"; + // + // RegistryAccessControlForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(546, 459); + this.Controls.Add(this.groupBox_AccessControl); + this.Name = "RegistryAccessControlForm"; + this.Text = "Registry Access Control Settings"; + this.groupBox_AccessControl.ResumeLayout(false); + this.groupBox1.ResumeLayout(false); + this.groupBox2.ResumeLayout(false); + this.groupBox2.PerformLayout(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.GroupBox groupBox_AccessControl; + private System.Windows.Forms.Label label22; + private System.Windows.Forms.TextBox textBox_ProcessName; + private System.Windows.Forms.GroupBox groupBox2; + private System.Windows.Forms.Button button_SelectRegistryAccessFlags; + private System.Windows.Forms.TextBox textBox_AccessFlags; + private System.Windows.Forms.Label label17; + private System.Windows.Forms.Label label_AccessFlags; + private System.Windows.Forms.TextBox textBox_ProcessId; + private System.Windows.Forms.Button button_SelectProcessId; + private System.Windows.Forms.Button button_SelectRegistryCallbackClass; + private System.Windows.Forms.TextBox textBox_RegistryCallbackClass; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Button button_DeleteFilter; + private System.Windows.Forms.Button button_AddFilter; + private System.Windows.Forms.GroupBox groupBox1; + private System.Windows.Forms.ListView listView_FilterRules; + private System.Windows.Forms.CheckBox checkBox_isExcludeFilter; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.Button button_Apply; + private System.Windows.Forms.Button button_Info; + private System.Windows.Forms.Label label4; + + } +} \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/CommonObjects/RegistryAccessControlForm.cs b/Demo_Source_Code/CSharpDemo/CommonObjects/RegistryAccessControlForm.cs new file mode 100644 index 0000000..63ab6c5 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/CommonObjects/RegistryAccessControlForm.cs @@ -0,0 +1,198 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.IO; +using System.Windows.Forms; + +namespace EaseFilter.CommonObjects +{ + public partial class RegistryAccessControlForm : Form + { + List regFilterRuleList = new List(); + + public RegistryAccessControlForm() + { + InitializeComponent(); + + regFilterRuleList.AddRange(GlobalConfig.FilterRules.Values); + + InitListView(); + + textBox_AccessFlags.Text = FilterAPI.MAX_REGITRY_ACCESS_FLAG.ToString(); + textBox_RegistryCallbackClass.Text = "93092006832128"; //by default only register post callback class + textBox_ProcessName.Text = Path.GetFileName(GlobalConfig.AssemblyName); + + + } + + public void InitListView() + { + //init ListView control + listView_FilterRules.Clear(); //clear control + //create column header for ListView + listView_FilterRules.Columns.Add("#", 20, System.Windows.Forms.HorizontalAlignment.Left); + listView_FilterRules.Columns.Add("ProcessId", 50, System.Windows.Forms.HorizontalAlignment.Left); + listView_FilterRules.Columns.Add("ProcessName", 100, System.Windows.Forms.HorizontalAlignment.Left); + listView_FilterRules.Columns.Add("AccessFlags", 100, System.Windows.Forms.HorizontalAlignment.Left); + listView_FilterRules.Columns.Add("CallbackClass", 100, System.Windows.Forms.HorizontalAlignment.Left); + + foreach (FilterRule rule in regFilterRuleList) + { + AddItem(rule); + } + + } + + private void AddItem(FilterRule newRule) + { + string[] itemStr = new string[listView_FilterRules.Columns.Count]; + itemStr[0] = listView_FilterRules.Items.Count.ToString(); + itemStr[1] = newRule.IncludeProcessIds; + itemStr[2] = newRule.IncludeProcessNames; + itemStr[3] = newRule.RegistryControlFlag.ToString(); + itemStr[4] = newRule.RegistryCallbackClass.ToString(); + ListViewItem item = new ListViewItem(itemStr, 0); + item.Tag = newRule; + listView_FilterRules.Items.Add(item); + } + + + private void button_AddFilter_Click(object sender, EventArgs e) + { + try + { + FilterRule regFilterRule = new FilterRule(); + if (textBox_ProcessId.Text.Trim().Length > 0 ) + { + //please note that the process Id will be changed when the process launch every time. + regFilterRule.IncludeProcessIds = textBox_ProcessId.Text; + } + else + { + regFilterRule.IncludeProcessIds = ""; + } + + if (textBox_ProcessName.Text.Trim().Length > 0) + { + regFilterRule.IncludeProcessNames = textBox_ProcessName.Text; + } + else + { + regFilterRule.IncludeProcessNames = ""; + } + + //this is the key of the filter rule for registry filter rule + regFilterRule.IncludeFileFilterMask = regFilterRule.IncludeProcessIds + regFilterRule.IncludeProcessNames; + regFilterRule.Type = (int)FilterAPI.FilterType.FILE_SYSTEM_REGISTRY; + regFilterRule.IsExcludeFilter = checkBox_isExcludeFilter.Checked; + regFilterRule.RegistryControlFlag = uint.Parse(textBox_AccessFlags.Text); + regFilterRule.RegistryCallbackClass = ulong.Parse(textBox_RegistryCallbackClass.Text); + + + regFilterRuleList.Add(regFilterRule); + InitListView(); + + } + catch (Exception ex) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("Add registry filter rule failed." + ex.Message, "Add Filter Rule", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + } + + private void button_DeleteFilter_Click(object sender, EventArgs e) + { + if (listView_FilterRules.SelectedItems.Count == 0) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("There are no filter rule selected.", "Delete Filter Rule", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + foreach (System.Windows.Forms.ListViewItem item in listView_FilterRules.SelectedItems) + { + FilterRule filterRule = (FilterRule)item.Tag; + regFilterRuleList.Remove(filterRule); + GlobalConfig.RemoveFilterRule(filterRule.IncludeFileFilterMask); + } + + InitListView(); + } + + private void button_SelectProcessId_Click(object sender, EventArgs e) + { + OptionForm optionForm = new OptionForm(OptionForm.OptionType.ProccessId, textBox_ProcessId.Text); + + if (optionForm.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + textBox_ProcessId.Text = optionForm.ProcessId.ToString(); + } + } + + private void button_SelectRegistryAccessFlags_Click(object sender, EventArgs e) + { + OptionForm optionForm = new OptionForm(OptionForm.OptionType.RegistryAccessFlag, textBox_AccessFlags.Text); + + if (optionForm.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + textBox_AccessFlags.Text = optionForm.RegAccessFlags.ToString(); + } + } + + private void button_SelectRegistryCallbackClass_Click(object sender, EventArgs e) + { + OptionForm optionForm = new OptionForm(OptionForm.OptionType.RegistryCallbackClass, textBox_RegistryCallbackClass.Text); + + if (optionForm.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + textBox_RegistryCallbackClass.Text = optionForm.RegCallbackClass.ToString(); + } + } + + private void button_Apply_Click(object sender, EventArgs e) + { + foreach (FilterRule regFilterRule in regFilterRuleList) + { + GlobalConfig.AddFilterRule(regFilterRule); + } + + GlobalConfig.SaveConfigSetting(); + } + + private void button_Info_Click(object sender, EventArgs e) + { + string information = "Filter by process Id: Filter the registry access by process Id, skip the process Id check if it is 0.\r\n\r\n"; + information += "Filter by process name: Filter the registry access by process name filter mask, use '*' to include all processes, use ';' to seperate multiple process names.\r\n\r\n"; + information += "Filter by user name: Filter the registry access by user name with format 'domain name\\user name', use '*' to include all users.\r\n\r\n"; + information += "Registry access control: Set the registry access control flags to allow or deny the registry access.\r\n\r\n"; + information += "Registry callback setting: Set the registry access notification callback class, monitor the registry access by registering post-notification class, control the registry access by registering pre-notification class in user mode service.\r\n\r\n"; + information += "Exclude the registry filter rule: Skip the registry access for this filter rule if it is enabled.\r\n\r\n"; + + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show(information, "Registry Filter Setting", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + } +} diff --git a/Demo_Source_Code/CSharpDemo/CommonObjects/RegistryAccessControlForm.resx b/Demo_Source_Code/CSharpDemo/CommonObjects/RegistryAccessControlForm.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/CommonObjects/RegistryAccessControlForm.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/CommonObjects/RegistryAccessControlHandler.cs b/Demo_Source_Code/CSharpDemo/CommonObjects/RegistryAccessControlHandler.cs new file mode 100644 index 0000000..2b5de0a --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/CommonObjects/RegistryAccessControlHandler.cs @@ -0,0 +1,852 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.IO; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Drawing; +using System.Windows.Forms; +using System.Runtime.InteropServices; +using Microsoft.Win32.SafeHandles; + + +namespace EaseFilter.CommonObjects +{ + public enum VALUE_DATA_TYPE : uint + { + REG_NONE = 0, + REG_SZ = 1, + REG_EXPAND_SZ = 2, + REG_BINARY = 3, + REG_DWORD = 4, + REG_DWORD_BIG_ENDIAN = 5, + REG_LINK = 6, + REG_MULTI_SZ = 7, + REG_RESOURCE_LIST = 8, + REG_FULL_RESOURCE_DESCRIPTOR = 9, + REG_RESOURCE_REQUIREMENTS_LIST = 10, + REG_QWORD = 11 + } + + public enum KEY_VALUE_INFORMATION_CLASS : uint + { + KeyValueBasicInformation = 0, + KeyValueFullInformation = 1, + KeyValuePartialInformation = 2, + KeyValueFullInformationAlign64 = 3, + KeyValuePartialInformationAlign64 = 4, + MaxKeyValueInfoClass = 5 + } + + public struct KEY_VALUE_BASIC_INFORMATION + { + public uint TitleIndex; + public uint Type; + public uint NameLength; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 65536 - 12)] + public byte[] Name; + } + public struct KEY_VALUE_FULL_INFORMATION + { + public uint TitleIndex; + public uint Type; + public uint DataOffset; + public uint DataLength; + public uint NameLength; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 65536 - 20)] + public byte[] Name; + } + + public struct KEY_VALUE_PARTIAL_INFORMATION + { + public uint TitleIndex; + public uint Type; + public uint DataLength; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 65536 - 12 )] + public byte[] Data; + } + + public struct KEY_VALUE_ENTRY + { + public uint NextEntryOffset; + public uint ValueNameLength; + public uint DataType; + public uint DataLength; + public byte[] ValueName; + //public byte[] Data; + } + + public enum KEY_SET_INFORMATION_CLASS : uint + { + KeyWriteTimeInformation = 0, + KeyWow64FlagsInformation, + KeyControlFlagsInformation, + KeySetVirtualizationInformation, + KeySetDebugInformation, + KeySetHandleTagsInformation, + MaxKeySetInfoClass // MaxKeySetInfoClass should always be the last enum + } + public enum KEY_INFORMATION_CLASS : uint + { + KeyBasicInformation = 0, + KeyNodeInformation, + KeyFullInformation, + KeyNameInformation, + KeyCachedInformation, + KeyFlagsInformation, + KeyVirtualizationInformation, + KeyHandleTagsInformation, + KeyTrustInformation, + KeyLayerInformation, + MaxKeyInfoClass + } + + public struct KEY_BASIC_INFORMATION + { + public long LastWriteTime; + public uint TitleIndex; + public uint NameLength; + public byte[] Name; + } + + public struct KEY_NODE_INFORMATION + { + public long LastWriteTime; + public uint TitleIndex; + public uint ClassOffset; + public uint ClassLength; + public uint NameLength; + public byte[] Name; + } + + public struct KEY_FULL_INFORMATION + { + public long LastWriteTime; + public uint TitleIndex; + public uint ClassOffset; + public uint ClassLength; + public uint SubKeys; + public uint MaxNameLen; + public uint MaxClassLen; + public uint Values; + public uint MaxValueNameLen; + public uint MaxValueDataLen; + public byte[] Class; + } + + public struct KEY_NAME_INFORMATION + { + public uint NameLength; + public byte[] Name; + } + + public struct KEY_CACHED_INFORMATION + { + public long LastWriteTime; + public uint TitleIndex; + public uint SubKeys; + public uint MaxNameLen; + public uint MaxClassLen; + public uint Values; + public uint MaxValueNameLen; + public uint MaxValueDataLen; + public uint NameLength; + } + + public struct KEY_VIRTUALIZATION_INFORMATION + { + public bool VirtualizationCandidate; + public bool VirtualizationEnabled; + public bool VirtualTarget; + public bool VirtualStore; + public bool VirtualSource; + } + + public enum REG_ACCESS_MASK : uint + { + KEY_QUERY_VALUE = 1, + KEY_SET_VALUE = 2, + KEY_CREATE_SUB_KEY = 4, + KEY_ENUMERATE_SUB_KEYS = 8, + KEY_NOTIFY = 16, + KEY_CREATE_LINK = 32, + KEY_WRITE = 131078, + KEY_EXECUTE = 131097, + KEY_READ = 131097, + KEY_ALL_ACCESS = 983103, + } + + public enum REG_CREATE_OPTIONS : uint + { + REG_OPTION_VOLATILE = 0x00000001, // Key is not preserved when system is rebooted + REG_OPTION_CREATE_LINK = 0x00000002, // Created key is a symbolic link + REG_OPTION_BACKUP_RESTORE = 0x00000004, // open for backup or restore special access rules privilege required + REG_OPTION_OPEN_LINK = 0x00000008, // Open symbolic link + } + + public enum REG_DISPOSITION + { + REG_CREATED_NEW_KEY = 0x00000001, // New Registry Key created + REG_OPENED_EXISTING_KEY =0x00000002, // Existing Key opened + } + + public class RegistryHandler + { + + public static string FormatDescription(FilterAPI.MessageSendData messageSend) + { + string descrption = string.Empty; + FilterAPI.RegCallbackClass regCallbackClass = (FilterAPI.RegCallbackClass)messageSend.Offset; + + try + { + + if (messageSend.Status != (uint)FilterAPI.NTSTATUS.STATUS_SUCCESS) + { + return ""; + } + + switch (regCallbackClass) + { + case FilterAPI.RegCallbackClass.Reg_Pre_Delete_Key: + case FilterAPI.RegCallbackClass.Reg_Post_Delete_Key: + { + descrption = "registry key is being deleted."; + break; + } + case FilterAPI.RegCallbackClass.Reg_Pre_Set_Value_Key: + case FilterAPI.RegCallbackClass.Reg_Post_Set_Value_Key: + { + VALUE_DATA_TYPE valueType = (VALUE_DATA_TYPE)messageSend.InfoClass; + descrption = "Type:" + valueType.ToString(); + descrption += " Data:" + ValueTypeData(valueType, (int)messageSend.DataBufferLength, messageSend.DataBuffer); + break; + } + case FilterAPI.RegCallbackClass.Reg_Pre_Delete_Value_Key: + case FilterAPI.RegCallbackClass.Reg_Post_Delete_Value_Key: + { + descrption = "registry key's value is being deleted."; + break; + } + case FilterAPI.RegCallbackClass.Reg_Pre_SetInformation_Key: + case FilterAPI.RegCallbackClass.Reg_Post_SetInformation_Key: + { + KEY_SET_INFORMATION_CLASS keySetInformationClass = (KEY_SET_INFORMATION_CLASS)messageSend.InfoClass; + descrption = keySetInformationClass.ToString(); + break; + } + case FilterAPI.RegCallbackClass.Reg_Pre_Rename_Key: + case FilterAPI.RegCallbackClass.Reg_Post_Rename_Key: + { + string newName = Encoding.Unicode.GetString(messageSend.DataBuffer); + descrption = "registry key's name is being changed to " + newName; + break; + } + case FilterAPI.RegCallbackClass.Reg_Pre_Enumerate_Key: + { + KEY_INFORMATION_CLASS keyInformationClass = (KEY_INFORMATION_CLASS)messageSend.InfoClass; + descrption = keyInformationClass.ToString(); + + break; + } + case FilterAPI.RegCallbackClass.Reg_Post_Enumerate_Key: + { + KEY_INFORMATION_CLASS keyInformationClass = (KEY_INFORMATION_CLASS)messageSend.InfoClass; + descrption += KeyInformation(keyInformationClass, messageSend.DataBuffer); + + break; + } + case FilterAPI.RegCallbackClass.Reg_Pre_Enumerate_Value_Key: + { + KEY_VALUE_INFORMATION_CLASS keyValuseInformationClass = (KEY_VALUE_INFORMATION_CLASS)messageSend.InfoClass; + descrption = keyValuseInformationClass.ToString(); + + break; + } + case FilterAPI.RegCallbackClass.Reg_Post_Enumerate_Value_Key: + { + KEY_VALUE_INFORMATION_CLASS keyValuseInformationClass = (KEY_VALUE_INFORMATION_CLASS)messageSend.InfoClass; + descrption += KeyValueInformation(keyValuseInformationClass, messageSend.DataBuffer); + + break; + } + case FilterAPI.RegCallbackClass.Reg_Pre_Query_Key: + { + KEY_INFORMATION_CLASS keyInformationClass = (KEY_INFORMATION_CLASS)messageSend.InfoClass; + descrption = keyInformationClass.ToString(); + + break; + } + case FilterAPI.RegCallbackClass.Reg_Post_Query_Key: + { + KEY_INFORMATION_CLASS keyInformationClass = (KEY_INFORMATION_CLASS)messageSend.InfoClass; + descrption += KeyInformation(keyInformationClass, messageSend.DataBuffer); + + break; + } + case FilterAPI.RegCallbackClass.Reg_Pre_Query_Value_Key: + { + KEY_VALUE_INFORMATION_CLASS keyValuseInformationClass = (KEY_VALUE_INFORMATION_CLASS)messageSend.InfoClass; + descrption = keyValuseInformationClass.ToString(); + + break; + } + case FilterAPI.RegCallbackClass.Reg_Post_Query_Value_Key: + { + //for unit test + if (messageSend.FileName.IndexOf("EaseFilter") > 0) + { + //this is our test key. + RegistryUnitTest.postQueryValueKeyPassed = true; + } + + KEY_VALUE_INFORMATION_CLASS keyValuseInformationClass = (KEY_VALUE_INFORMATION_CLASS)messageSend.InfoClass; + descrption += KeyValueInformation(keyValuseInformationClass, messageSend.DataBuffer); + + break; + } + case FilterAPI.RegCallbackClass.Reg_Pre_Query_Multiple_Value_Key: + { + break; + } + case FilterAPI.RegCallbackClass.Reg_Post_Query_Multiple_Value_Key: + { + uint entryCount = messageSend.InfoClass; + + MemoryStream ms = new MemoryStream(messageSend.DataBuffer); + BinaryReader br = new BinaryReader(ms); + + for (int i = 0; i < entryCount&&ms.Position < ms.Length; i++) + { + long currentOffset = ms.Position; + int nextEntryOffset = br.ReadInt32(); + int valueNameLength = br.ReadInt32(); + int dataType = br.ReadInt32(); + int dataLength = br.ReadInt32(); + byte[] valueName = br.ReadBytes(valueNameLength); + byte[] data = br.ReadBytes(dataLength); + + VALUE_DATA_TYPE type = (VALUE_DATA_TYPE)dataType; + descrption += "Name:" + Encoding.Unicode.GetString(valueName, 0, valueNameLength); + descrption += " Type:" + type.ToString(); + descrption += " Data:" + ValueTypeData(type,dataLength, data) + Environment.NewLine; + + ms.Position = currentOffset + nextEntryOffset; + + } + + break; + } + case FilterAPI.RegCallbackClass.Reg_Pre_Create_KeyEx: + case FilterAPI.RegCallbackClass.Reg_Post_Create_KeyEx: + case FilterAPI.RegCallbackClass.Reg_Pre_Open_KeyEx: + case FilterAPI.RegCallbackClass.Reg_Post_Open_KeyEx: + { + descrption += FormatCreateDescription(messageSend); + break; + } + case FilterAPI.RegCallbackClass.Reg_Pre_Load_Key: + case FilterAPI.RegCallbackClass.Reg_Post_Load_Key: + { + descrption += "SourceFile:" + Encoding.Unicode.GetString(messageSend.DataBuffer, 0, (int)messageSend.DataBufferLength); + break; + } + case FilterAPI.RegCallbackClass.Reg_Pre_Replace_Key: + case FilterAPI.RegCallbackClass.Reg_Post_Replace_Key: + { + descrption += "NewFileName:" + Encoding.Unicode.GetString(messageSend.DataBuffer, 0, (int)messageSend.DataBufferLength); + break; + } + + case FilterAPI.RegCallbackClass.Reg_Pre_Query_KeyName: + case FilterAPI.RegCallbackClass.Reg_Post_Query_KeyName: + { + break; + } + + default: descrption = "unsupported registry callback class:" + regCallbackClass.ToString(); break; + } + } + catch (Exception ex) + { + descrption = "Format description failed, return error:" + ex.Message; + } + + return descrption; + } + + + public static bool AuthorizeRegistryAccess(FilterAPI.MessageSendData messageSend, ref FilterAPI.MessageReplyData messageReply) + { + bool ret = true; + + try + { + + messageReply.MessageId = messageSend.MessageId; + messageReply.MessageType = messageSend.MessageType; + messageReply.ReturnStatus = (uint)FilterAPI.NTSTATUS.STATUS_SUCCESS; + + + // + //here you can control registry request,block the access or modify the registry data. + // + // + + //if you don't want to change anything to this registry request, just let it pass through as below setting: + //messageReply.FilterStatus = 0; + //messageReply.ReturnStatus = (uint)NtStatus.Status.Success; + + //if you want to block the access this registry request, you can return the status as below, + //it is only for pre callback requests. + //messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION; + //messageReply.ReturnStatus = (uint)NtStatus.Status.AccessDenied; + + //if you want to modify the registry data and complete the pre IO with your own data, you can return status as below: + // messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION | (uint)FilterAPI.FilterStatus.FILTER_DATA_BUFFER_IS_UPDATED; + // messageReply.DataBufferLength = the return data buffer length. + // messageReply.DataBuffer = the data you want to return. + // messageReply.ReturnStatus = (uint)NtStatus.Status.Success; + + FilterAPI.RegCallbackClass regCallbackClass = (FilterAPI.RegCallbackClass)messageSend.Offset; + + uint dataLength = messageSend.DataBufferLength; + byte[] data = messageSend.DataBuffer; + + switch (regCallbackClass) + { + + case FilterAPI.RegCallbackClass.Reg_Pre_Query_Value_Key: + { + KEY_VALUE_INFORMATION_CLASS keyValuseInformationClass = (KEY_VALUE_INFORMATION_CLASS)messageSend.InfoClass; + IntPtr keyValueInfoPtr = Marshal.UnsafeAddrOfPinnedArrayElement(data, 0); + + + if (messageSend.FileName.IndexOf("EaseFilter") <= 0) + { + //this is not our unit test key + break; + } + + //below code is for unit test to demo how to complete pre-callback registry call with our own data. + EventManager.WriteMessage(400, "AuthorizeRegistryAccess", EventLevel.Error, "Reg_Pre_Query_Value_Key keyValuseInformationClass:" + keyValuseInformationClass.ToString()); + + switch (keyValuseInformationClass) + { + case KEY_VALUE_INFORMATION_CLASS.KeyValueBasicInformation: + { + //public struct KEY_VALUE_BASIC_INFORMATION + // { + // public uint TitleIndex; + // public uint Type; + // public uint NameLength; + // public byte[] Name; + // } + + uint titleIndex = 0; + uint type = (uint)VALUE_DATA_TYPE.REG_DWORD; + byte[] valueName = Encoding.Unicode.GetBytes("value1"); + uint valueNameLength = (uint)valueName.Length; + + MemoryStream ms = new MemoryStream(messageReply.DataBuffer); + BinaryWriter bw = new BinaryWriter(ms); + bw.Write(titleIndex); + bw.Write(type); + bw.Write(valueNameLength); + bw.Write(valueName); + + messageReply.DataBufferLength = (uint)ms.Position; + messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION | (uint)FilterAPI.FilterStatus.FILTER_DATA_BUFFER_IS_UPDATED; + + + break; + } + case KEY_VALUE_INFORMATION_CLASS.KeyValueFullInformation: + { + //KeyValueFullInformation class structure + //public uint TitleIndex; + //public uint Type; + //public uint DataOffset; + //public uint DataLength; + //public uint NameLength; + //public byte[] Name; + + uint titleIndex = 0; + uint type = (uint)VALUE_DATA_TYPE.REG_DWORD; + uint testData = 12345; + uint testDataLength = sizeof(uint); + byte[] valueName = Encoding.Unicode.GetBytes("value1"); + uint valueNameLength =(uint)valueName.Length; + uint dataOffset = 5 * sizeof(uint) + valueNameLength; + + MemoryStream ms = new MemoryStream(messageReply.DataBuffer); + BinaryWriter bw = new BinaryWriter(ms); + bw.Write(titleIndex); + bw.Write(type); + bw.Write(dataOffset); + bw.Write(testDataLength); + bw.Write(valueNameLength); + bw.Write(valueName); + bw.Write(testData); + + messageReply.DataBufferLength = (uint)ms.Position; + messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION | (uint)FilterAPI.FilterStatus.FILTER_DATA_BUFFER_IS_UPDATED; + + + break; + } + case KEY_VALUE_INFORMATION_CLASS.KeyValuePartialInformation: + { + // public struct KEY_VALUE_PARTIAL_INFORMATION + //{ + // public uint TitleIndex; + // public uint Type; + // public uint DataLength; + // public byte[] Data; + //} + + uint titleIndex = 0; + uint type = (uint)VALUE_DATA_TYPE.REG_DWORD; + uint testData = 12345; + uint testDataLength = sizeof(uint); + + MemoryStream ms = new MemoryStream(messageReply.DataBuffer); + BinaryWriter bw = new BinaryWriter(ms); + + bw.Write(titleIndex); + bw.Write(type); + bw.Write(testDataLength); + bw.Write(testData); + + messageReply.DataBufferLength = (uint)ms.Position; + + messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION | (uint)FilterAPI.FilterStatus.FILTER_DATA_BUFFER_IS_UPDATED; + messageReply.ReturnStatus = (uint)FilterAPI.NTSTATUS.STATUS_SUCCESS; + + break; + } + + + default: break; + } + break; + } + + case FilterAPI.RegCallbackClass.Reg_Pre_Create_KeyEx: + case FilterAPI.RegCallbackClass.Reg_Pre_Open_KeyEx: + { + //this is our unit test key + if (messageSend.FileName.IndexOf("EaseFilter") > 0 ) + { + //NOT allow to create new registry key. + + messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION; + messageReply.ReturnStatus = (uint)NtStatus.Status.AccessDenied; + } + + break; + } + + default: break; + } + } + catch (Exception ex) + { + EventManager.WriteMessage(400, "AuthorizeRegistryAccess", EventLevel.Error, "AuthorizeRegistryAccess exception:" + ex.Message); + } + + return ret; + } + + private static string ValueTypeData(VALUE_DATA_TYPE type, int dataSize, byte[] data) + { + string dataStr = string.Empty; + + try + { + switch (type) + { + case VALUE_DATA_TYPE.REG_BINARY: + { + //maximum data size to 256; + for (int i = 0; i < 256; i++) + { + if (i >= dataSize) + { + break; + } + + dataStr += string.Format("0x{0:x2}", data[i]); + + } + + break; + } + case VALUE_DATA_TYPE.REG_DWORD: + { + uint value = BitConverter.ToUInt32(data, 0); + dataStr = string.Format("0x{0:x8}({1})", value, value); + break; + } + case VALUE_DATA_TYPE.REG_DWORD_BIG_ENDIAN: + { + //A 4-byte numerical value whose least significant byte is at the highest address + byte leastByte = data[3]; + byte secondByte = data[2]; + data[3] = data[0]; + data[2] = data[1]; + data[1] = secondByte; + data[0] = leastByte; + + uint value = BitConverter.ToUInt32(data, 0); + dataStr = string.Format("0x{0:x8}({1})", value, value); + + break; + } + case VALUE_DATA_TYPE.REG_EXPAND_SZ: + { + //A null-terminated Unicode string, containing unexpanded references to environment variables, such as "%PATH%" + dataStr = Encoding.Unicode.GetString(data, 0, dataSize).Replace("\0", ""); + break; + } + case VALUE_DATA_TYPE.REG_MULTI_SZ: + { + //An array of null-terminated strings, terminated by another zero + dataStr = Encoding.Unicode.GetString(data, 0, dataSize).Replace("\0", ""); + break; + } + case VALUE_DATA_TYPE.REG_SZ: + { + //A null-terminated Unicode string + dataStr = Encoding.Unicode.GetString(data, 0, dataSize).Replace("\0", ""); + break; + } + case VALUE_DATA_TYPE.REG_QWORD: + { + UInt64 value = BitConverter.ToUInt64(data, 0); + dataStr = string.Format("0x{0:x16}({1})", value, value); + break; + } + + default: break; + } + } + catch (Exception ex) + { + dataStr = "get data failed:" + ex.Message; + } + + + return dataStr; + } + + private static string KeyInformation(KEY_INFORMATION_CLASS keyInfoClass, byte[] keyInformation) + { + string keyInfoStr = "(" + keyInfoClass.ToString() + ") "; + + try + { + MemoryStream ms = new MemoryStream(keyInformation); + BinaryReader br = new BinaryReader(ms); + + switch (keyInfoClass) + { + case KEY_INFORMATION_CLASS.KeyBasicInformation: + { + long lastWriteTime = br.ReadInt64(); + uint titleIndex = br.ReadUInt32(); + uint nameLength = br.ReadUInt32(); + string name = Encoding.Unicode.GetString(keyInformation, (int)ms.Position, (int)nameLength); + + keyInfoStr += "LastWriteTime:" + DateTime.FromFileTime(lastWriteTime).ToShortDateString(); + keyInfoStr += " Name:" + name; + + break; + } + case KEY_INFORMATION_CLASS.KeyNodeInformation: + { + long lastWriteTime = br.ReadInt64(); + uint titleIndex = br.ReadUInt32(); + uint classOffset = br.ReadUInt32(); + uint classLength = br.ReadUInt32(); + uint nameLength = br.ReadUInt32(); + string name = Encoding.Unicode.GetString(keyInformation, (int)ms.Position, (int)nameLength); + string className = Encoding.Unicode.GetString(keyInformation, (int)classOffset, (int)classLength); + + keyInfoStr += "LastWriteTime:" + DateTime.FromFileTime(lastWriteTime).ToShortDateString(); + keyInfoStr += " Name:" + name + " ClassName:" + className; + + break; + } + case KEY_INFORMATION_CLASS.KeyFullInformation: + { + long lastWriteTime = br.ReadInt64(); + uint titleIndex = br.ReadUInt32(); + uint classOffset = br.ReadUInt32(); + uint classLength = br.ReadUInt32(); + uint subKeys = br.ReadUInt32(); + uint maxNameLen = br.ReadUInt32(); + uint maxClassLen = br.ReadUInt32(); + uint values = br.ReadUInt32(); + uint maxValueNameLen = br.ReadUInt32(); + uint maxValueDataLen = br.ReadUInt32(); + uint nameLength = br.ReadUInt32(); + string className = Encoding.Unicode.GetString(keyInformation, (int)classOffset, (int)classLength); + + keyInfoStr += "LastWriteTime:" + DateTime.FromFileTime(lastWriteTime).ToShortDateString(); + keyInfoStr += " subKeys:" + subKeys + " valueEntries:" + values + " ClassName:" + className; + + break; + } + case KEY_INFORMATION_CLASS.KeyNameInformation: + { + uint nameLength = br.ReadUInt32(); + string name = Encoding.Unicode.GetString(keyInformation, (int)ms.Position, (int)nameLength); + keyInfoStr += " Name:" + name; + + break; + } + + + default: break; + } + } + catch (Exception ex) + { + keyInfoStr = "get data failed:" + ex.Message; + } + + + return keyInfoStr; + } + + private static string KeyValueInformation(KEY_VALUE_INFORMATION_CLASS keyValueInfoClass, byte[] keyValueInformation) + { + string keyValueInfoStr = string.Empty; + + try + { + MemoryStream ms = new MemoryStream(keyValueInformation); + BinaryReader br = new BinaryReader(ms); + + switch (keyValueInfoClass) + { + case KEY_VALUE_INFORMATION_CLASS.KeyValueBasicInformation: + { + int titleIndex = br.ReadInt32(); + int type = br.ReadInt32(); + int nameLength = br.ReadInt32(); + keyValueInfoStr = "(" + keyValueInfoClass.ToString() + ") Name:" + Encoding.Unicode.GetString(keyValueInformation, (int)ms.Position, nameLength); + + break; + } + case KEY_VALUE_INFORMATION_CLASS.KeyValueFullInformation: + { + int titleIndex = br.ReadInt32(); + int type = br.ReadInt32(); + int dataOffset = br.ReadInt32(); + int dataLength = br.ReadInt32(); + int nameLength = br.ReadInt32(); + keyValueInfoStr = "(" + keyValueInfoClass.ToString() + ") Name:" + Encoding.Unicode.GetString(keyValueInformation, (int)ms.Position, nameLength); + keyValueInfoStr += " Type:" + ((VALUE_DATA_TYPE)type).ToString(); + + byte[] dataBuffer = new byte[dataLength]; + Array.Copy(keyValueInformation, dataOffset, dataBuffer, 0, dataBuffer.Length); + + keyValueInfoStr += " Data:" + ValueTypeData((VALUE_DATA_TYPE)type, dataBuffer.Length, dataBuffer); + + break; + } + case KEY_VALUE_INFORMATION_CLASS.KeyValuePartialInformation: + { + int titleIndex = br.ReadInt32(); + int type = br.ReadInt32(); + int dataLength = br.ReadInt32(); + keyValueInfoStr += "(" + keyValueInfoClass.ToString() + ") Type:" + ((VALUE_DATA_TYPE)type).ToString(); + + byte[] dataBuffer = new byte[dataLength]; + Array.Copy(keyValueInformation, ms.Position, dataBuffer, 0, dataBuffer.Length); + keyValueInfoStr += " Data:" + ValueTypeData((VALUE_DATA_TYPE)type, dataBuffer.Length, dataBuffer); + + break; + } + + + default: break; + } + } + catch (Exception ex) + { + keyValueInfoStr = "get data failed:" + ex.Message; + } + + + return keyValueInfoStr; + } + + private static string FormatCreateDescription(FilterAPI.MessageSendData messageSend) + { + + uint createOptions = messageSend.CreateOptions; + uint desiredAccess = messageSend.DesiredAccess; + uint dispositions = messageSend.Disposition; + + string message = string.Empty; + + message += "createOptions:"; + foreach (REG_CREATE_OPTIONS createOption in Enum.GetValues(typeof(REG_CREATE_OPTIONS))) + { + if (createOption == (REG_CREATE_OPTIONS)((uint)createOption & createOptions)) + { + message += createOption.ToString() + "; "; + } + } + + message += "(0x" + createOptions.ToString("X") + ");\r\n"; + + message += "desiredAccess:"; + foreach (REG_ACCESS_MASK accessMask in Enum.GetValues(typeof(REG_ACCESS_MASK))) + { + if (accessMask == (REG_ACCESS_MASK)((uint)accessMask & desiredAccess)) + { + message += accessMask.ToString() + "; "; + } + } + + message += "(0x" + desiredAccess.ToString("X") + ");\r\n"; + + if (dispositions > 0) + { + message += "dispositions:"; + foreach (REG_DISPOSITION disposition in Enum.GetValues(typeof(REG_DISPOSITION))) + { + if (disposition == (REG_DISPOSITION)((uint)disposition & dispositions)) + { + message += disposition.ToString() + "; "; + } + } + + message += "(0x" + desiredAccess.ToString("X") + ");"; + } + + return message; + } + + } +} diff --git a/Demo_Source_Code/CSharpDemo/CommonObjects/RegistryFilterRuleSection.cs b/Demo_Source_Code/CSharpDemo/CommonObjects/RegistryFilterRuleSection.cs new file mode 100644 index 0000000..57c2a65 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/CommonObjects/RegistryFilterRuleSection.cs @@ -0,0 +1,275 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Inc. +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Configuration; + +using EaseFilter.FilterControl; + +namespace EaseFilter.CommonObjects +{ + public class RegistryFilterRuleSection : ConfigurationSection + { + [ConfigurationProperty("", IsRequired = true, IsDefaultCollection = true)] + public RegistryFilterRuleCollection Instances + { + get { return (RegistryFilterRuleCollection)this[""]; } + set { this[""] = value; } + } + } + + public class RegistryFilterRuleCollection : ConfigurationElementCollection + { + public RegistryFilterRule this[int index] + { + get { return (RegistryFilterRule)BaseGet(index); } + set + { + if (BaseGet(index) != null) + { + BaseRemoveAt(index); + } + BaseAdd(index, value); + } + } + + public void Add(RegistryFilterRule RegistryFilterRule) + { + BaseAdd(RegistryFilterRule); + } + + public void Clear() + { + BaseClear(); + } + + public void Remove(RegistryFilterRule RegistryFilterRule) + { + BaseRemove(RegistryFilterRule.ProcessId.ToString() + RegistryFilterRule.ProcessNameFilterMask); + } + + public void RemoveAt(int index) + { + BaseRemoveAt(index); + } + + public void Remove(string name) + { + BaseRemove(name); + } + + protected override ConfigurationElement CreateNewElement() + { + return new RegistryFilterRule(); + } + + protected override object GetElementKey(ConfigurationElement element) + { + //The key is the process name + user name + return ((RegistryFilterRule)element).ProcessId.ToString() + ((RegistryFilterRule)element).ProcessNameFilterMask; + } + } + + public class RegistryFilterRule : ConfigurationElement + { + /// + /// Control the registry access for the process with this process Id. + /// + [ConfigurationProperty("processId", IsRequired = false)] + public string ProcessId + { + get { return (string)base["processId"]; } + set { base["processId"] = value; } + } + + /// + /// Control the registry access for the process with this process name if the process Id is 0, or it will skip it. + /// + [ConfigurationProperty("processNameFilterMask", IsKey = false, IsRequired = false)] + public string ProcessNameFilterMask + { + get { return (string)base["processNameFilterMask"]; } + set { base["processNameFilterMask"] = value; } + } + + /// + /// Control the registry access for the process with this user name + /// + [ConfigurationProperty("userName", IsRequired = false)] + public string UserName + { + get { return (string)base["userName"]; } + set { base["userName"] = value; } + } + + /// + /// Filter the registry access based on the key name filter mask if it was set + /// + [ConfigurationProperty("registryKeyNameFilterMask", IsRequired = false)] + public string RegistryKeyNameFilterMask + { + get { return (string)base["registryKeyNameFilterMask"]; } + set { base["registryKeyNameFilterMask"] = value; } + } + + /// + /// if the process name matches the excludeProcessNames, the registry I/O will be skipped by filter driver. + /// seperate the multiple items with ';' + /// + [ConfigurationProperty("excludeProcessNames", IsRequired = false)] + public string ExcludeProcessNames + { + get { return (string)base["excludeProcessNames"]; } + set { base["excludeProcessNames"] = value; } + } + + /// + /// if the user name matches the excludeUserNames, the registry I/O will be skipped by filter driver. + /// seperate the multiple items with ';' + /// + [ConfigurationProperty("excludeUserNames", IsRequired = false)] + public string ExcludeUserNames + { + get { return (string)base["excludeUserNames"]; } + set { base["excludeUserNames"] = value; } + } + + /// + /// if the key name matches the excludeKeyNames, the registry I/O will be skipped by filter driver. + /// seperate the multiple items with ';' + /// + [ConfigurationProperty("excludeKeyNames", IsRequired = false)] + public string ExcludeKeyNames + { + get { return (string)base["excludeKeyNames"]; } + set { base["excludeKeyNames"] = value; } + } + + /// + /// The the flag to control how to access the registry for the matched process or user + /// + [ConfigurationProperty("accessFlag", IsRequired = true)] + public uint AccessFlag + { + get { return (uint)base["accessFlag"]; } + set { base["accessFlag"] = value; } + } + + /// + /// Register the callback when the registry access notification was triggered + /// + [ConfigurationProperty("regCallbackClass", IsRequired = true)] + public ulong RegCallbackClass + { + get { return (ulong)base["regCallbackClass"]; } + set { base["regCallbackClass"] = value; } + } + + + /// + /// If it is true, the registry access from the matched process or user will be excluded. + /// + [ConfigurationProperty("isExcludeFilter", IsRequired = true)] + public bool IsExcludeFilter + { + get { return (bool)base["isExcludeFilter"]; } + set { base["isExcludeFilter"] = value; } + } + + public RegistryFilterRule Copy() + { + RegistryFilterRule dest = new RegistryFilterRule(); + dest.ProcessId = ProcessId; + dest.ProcessNameFilterMask = ProcessNameFilterMask; + dest.RegistryKeyNameFilterMask = RegistryKeyNameFilterMask; + dest.UserName = UserName; + dest.ExcludeProcessNames = ExcludeProcessNames; + dest.ExcludeUserNames = ExcludeUserNames; + dest.ExcludeKeyNames = ExcludeKeyNames; + dest.AccessFlag = AccessFlag; + dest.RegCallbackClass = RegCallbackClass; + dest.IsExcludeFilter = IsExcludeFilter; + + return dest; + } + + public RegistryFilter ToRegistryFilter() + { + RegistryFilter registryFilter = new RegistryFilter(); + + if (ProcessId.Trim().Length > 0) + { + registryFilter.ProcessId = uint.Parse(ProcessId); + } + else + { + registryFilter.ProcessId = 0; + } + + string[] excludeProcessNames = ExcludeProcessNames.Split(new char[] { ';' }); + if (excludeProcessNames.Length > 0) + { + foreach (string excludeProcessName in excludeProcessNames) + { + if (excludeProcessName.Trim().Length > 0) + { + registryFilter.ExcludeProcessNameList.Add(excludeProcessName); + } + } + } + + string[] excludeUserNames = ExcludeUserNames.Split(new char[] { ';' }); + if (excludeUserNames.Length > 0) + { + foreach (string excludeUserName in excludeUserNames) + { + if (excludeUserName.Trim().Length > 0) + { + registryFilter.ExcludeUserNameList.Add(excludeUserName); + } + } + } + + string[] excludeKeyNames = ExcludeKeyNames.Split(new char[] { ';' }); + if (excludeKeyNames.Length > 0) + { + foreach (string excludeKeyName in excludeKeyNames) + { + if (excludeKeyName.Trim().Length > 0) + { + registryFilter.ExcludeKeyNameList.Add(excludeKeyName); + } + } + } + + registryFilter.ProcessNameFilterMask = ProcessNameFilterMask; + registryFilter.RegistryKeyNameFilterMask = RegistryKeyNameFilterMask; + registryFilter.UserName = UserName; + registryFilter.ControlFlag = AccessFlag; + registryFilter.RegCallbackClass = RegCallbackClass; + registryFilter.IsExcludeFilter = IsExcludeFilter; + + return registryFilter; + } + + } + + +} diff --git a/Demo_Source_Code/CSharpDemo/CommonObjects/RegistryUnitTest.cs b/Demo_Source_Code/CSharpDemo/CommonObjects/RegistryUnitTest.cs new file mode 100644 index 0000000..a5f6144 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/CommonObjects/RegistryUnitTest.cs @@ -0,0 +1,204 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.IO; +using System.Collections.Generic; +using System.Threading; +using System.Text; +using System.Drawing; +using System.Windows.Forms; +using System.Runtime.InteropServices; +using Microsoft.Win32.SafeHandles; + +namespace EaseFilter.CommonObjects +{ + static public class RegistryUnitTest + { + public static RichTextBox unitTestResult = new RichTextBox(); + public static bool postQueryValueKeyPassed = false; + + static private void AppendUnitTestResult(string text, Color color) + { + if (color == Color.Black) + { + unitTestResult.AppendText(Environment.NewLine); + unitTestResult.SelectionFont = new Font("Arial", 12, FontStyle.Bold); + } + + unitTestResult.SelectionStart = unitTestResult.TextLength; + unitTestResult.SelectionLength = 0; + + unitTestResult.SelectionColor = color; + unitTestResult.AppendText(text + Environment.NewLine); + unitTestResult.SelectionColor = unitTestResult.ForeColor; + + if (color == Color.Black) + { + unitTestResult.AppendText(Environment.NewLine); + } + + + } + + public static void RegistryFilterUnitTest(RichTextBox richTextBox_TestResult) + { + + string lastError = string.Empty; + string userName = Environment.UserDomainName + "\\" + Environment.UserName; + string testRegistryKey = "SYSTEM\\CurrentControlSet\\Services\\EaseFilter"; + string testValueKey = "DisplayName"; + + //full registry access rights + uint accessFlag = FilterAPI.MAX_REGITRY_ACCESS_FLAG; + ulong regCallbackClass = 0; + + bool testPassed = true; + + unitTestResult = richTextBox_TestResult; + + try + { + string message = "Registry Filter Driver Unit Test."; + AppendUnitTestResult(message, Color.Black); + + // + //registry access flag test,set full registry access rights for current process. + // + if (!FilterAPI.AddRegFilterEntryById(FilterAPI.GetCurrentProcessId(), accessFlag, regCallbackClass, false)) + { + AppendUnitTestResult("AddRegFilterEntryById failed:" + FilterAPI.GetLastErrorMessage(), Color.Red); + return; + + } + + using (Microsoft.Win32.RegistryKey regkey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(testRegistryKey)) + { + string valueName = (string)regkey.GetValue(testValueKey); + AppendUnitTestResult("1.Test full registry access rights in accessFlag passed, return valueName:" + valueName, Color.Gray); + } + } + catch (Exception ex) + { + AppendUnitTestResult("1.Test registry access flag failed with error:" + ex.Message, Color.Red); + testPassed = false; + } + + if (testPassed) + { + //disable registry open key right test + accessFlag = FilterAPI.MAX_REGITRY_ACCESS_FLAG & (uint)(~FilterAPI.RegControlFlag.REG_ALLOW_OPEN_KEY); + + try + { + if (!FilterAPI.AddRegFilterEntryById(FilterAPI.GetCurrentProcessId(), accessFlag, regCallbackClass, false)) + { + AppendUnitTestResult("AddRegFilterEntryById failed:" + FilterAPI.GetLastErrorMessage(), Color.Red); + return; + } + + using (Microsoft.Win32.RegistryKey regkey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(testRegistryKey)) + { + string valueName = (string)regkey.GetValue(testValueKey); + AppendUnitTestResult("2.Test disable open registry key right in accessFlag failed, get valueName " + valueName + " succedded.", Color.Red); + } + } + catch + { + AppendUnitTestResult("2.Test disable open registry key right in accessFlag passed.", Color.Green); + } + } + + //test query value key callback, we will receive the callback registry query value key. + accessFlag = FilterAPI.MAX_REGITRY_ACCESS_FLAG; + regCallbackClass = (uint)FilterAPI.RegCallbackClass.Reg_Post_Query_Value_Key; + + try + { + if (!FilterAPI.AddRegFilterEntryById(FilterAPI.GetCurrentProcessId(), accessFlag, regCallbackClass, false)) + { + AppendUnitTestResult("AddRegFilterEntryById failed:" + FilterAPI.GetLastErrorMessage(), Color.Red); + return; + } + + using (Microsoft.Win32.RegistryKey regkey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(testRegistryKey)) + { + string valueName = (string)regkey.GetValue(testValueKey); + Thread.Sleep(2000); + + if (postQueryValueKeyPassed) + { + AppendUnitTestResult("3.Test registry query value key Reg_Post_Query_Value_Key callback passed, return valueName:" + valueName, Color.Green); + } + else + { + AppendUnitTestResult("3.Test registry query value key Reg_Post_Query_Value_Key callback failed, didn't receive callback message.", Color.Red); + } + } + } + catch( Exception ex) + { + AppendUnitTestResult("3.Test registry query value key Reg_Post_Query_Value_Key callback failed:" + ex.Message, Color.Red); + } + + + //test registry access callback control, in callback function we will block the setting of the value name if it succeeds. + regCallbackClass = (uint)FilterAPI.RegCallbackClass.Reg_Pre_Create_Key | (uint)FilterAPI.RegCallbackClass.Reg_Pre_Create_KeyEx; + + try + { + if (!FilterAPI.AddRegFilterEntryById(FilterAPI.GetCurrentProcessId(), accessFlag, regCallbackClass, false)) + { + AppendUnitTestResult("AddRegFilterEntryById failed:" + FilterAPI.GetLastErrorMessage(), Color.Red); + return; + } + + using (Microsoft.Win32.RegistryKey regkey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(testRegistryKey)) + { + regkey.CreateSubKey("newSubkey"); + AppendUnitTestResult("4.Test block creating new registry sub key in callback failed, the new subkey was created in callback.", Color.Red); + } + } + catch (Exception ex) + { + AppendUnitTestResult("4.Test block creating new registry sub key in callback passed." + ex.Message, Color.Green); + } + + //test registry access callback control, in callback function we will replace our virutal value back to user if it succeeds. + regCallbackClass = (uint)FilterAPI.RegCallbackClass.Reg_Pre_Query_Value_Key; + + try + { + if (!FilterAPI.AddRegFilterEntryById(FilterAPI.GetCurrentProcessId(), accessFlag, regCallbackClass, false)) + { + AppendUnitTestResult("AddRegFilterEntryById failed:" + FilterAPI.GetLastErrorMessage(), Color.Red); + return; + } + + using (Microsoft.Win32.RegistryKey regkey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(testRegistryKey)) + { + object value = regkey.GetValue("value1"); + AppendUnitTestResult("5.Test modify registry return data in callback passed, return value " + value + ",type:" + value.GetType().ToString(), Color.Green); + } + } + catch (Exception ex) + { + AppendUnitTestResult("5.Test modify registry return data in callback failed: " + ex.Message, Color.Red); + } + } + } +} diff --git a/Demo_Source_Code/CSharpDemo/CommonObjects/RemotingService.cs b/Demo_Source_Code/CSharpDemo/CommonObjects/RemotingService.cs new file mode 100644 index 0000000..6e66663 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/CommonObjects/RemotingService.cs @@ -0,0 +1,263 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System.Runtime.Remoting; +using System.Runtime.Remoting.Channels; +using System.Runtime.Remoting.Channels.Tcp; +using System; + + +namespace EaseFilter.CommonObjects +{ + public enum OutputMessage : uint + { + IO_Name = 0x00000000, + Process_Name, + File_Name, + File_Size, + Attributes, + Last_Write_Time, + IO_Status, + Description, + + } + + public interface IFilterService + { + void Notify(string text); + bool AddFilterRule(string includeFileFilterMask, uint eventType, uint monitorIO, uint accessFlags); + bool DeleteFilterRule(string includeFileFilterMask); + } + + public class Cache + { + private static Cache myInstance; + public static IFilterService iFilterService; + + private Cache() + { + + } + + public static void Attach(IFilterService observer) + { + iFilterService = observer; + } + public static Cache GetInstance() + { + if (myInstance == null) + { + myInstance = new Cache(); + } + return myInstance; + } + + public string MessageString + { + set + { + iFilterService.Notify(value); + } + } + + public bool AddFilterRule(string includeFileFilterMask, uint eventType, uint monitorIO, uint accessFlags) + { + return iFilterService.AddFilterRule(includeFileFilterMask, eventType, monitorIO, accessFlags); + } + + public bool DeleteFilterRule(string includeFileFilterMask) + { + return iFilterService.DeleteFilterRule(includeFileFilterMask); + } + } + + public class FilterRemoteObject : MarshalByRefObject + { + + public FilterRemoteObject() + { + + } + + public void Notify(string text) + { + Cache.GetInstance().MessageString = text; + } + + public bool AddFilterRule(string includeFileFilterMask, uint eventType, uint monitorIO, uint accessFlags) + { + return Cache.GetInstance().AddFilterRule(includeFileFilterMask, eventType, monitorIO, accessFlags); + } + + public bool DeleteFilterRule(string includeFileFilterMask) + { + return Cache.GetInstance().DeleteFilterRule(includeFileFilterMask); + } + + } + + public class RemoteServer : IFilterService + { + private FilterRemoteObject remoteObject; + TcpChannel channel = new TcpChannel(65118); + + public RemoteServer() + { + } + + public void Start() + { + try + { + remoteObject = new FilterRemoteObject(); + ChannelServices.RegisterChannel(channel,false); + RemotingConfiguration.RegisterWellKnownServiceType(typeof(FilterRemoteObject), "filterAPIs", WellKnownObjectMode.Singleton); + Cache.Attach(this); + } + catch (Exception ex) + { + throw new Exception("Create remote server failed." + ex.Message); + } + } + + public void Stop() + { + try + { + ChannelServices.UnregisterChannel(channel); + } + catch { } + } + + public void Notify(string text) + { + Console.WriteLine("Receive txt:" + text); + } + + public bool AddFilterRule(string includeFileFilterMask, uint eventType, uint monitorIO, uint accessFlags) + { + bool retVal = false; + try + { + + FilterRule filterRule = new FilterRule(); + + filterRule.IncludeFileFilterMask = includeFileFilterMask; + filterRule.EventType = eventType; + filterRule.MonitorIO = monitorIO; + filterRule.AccessFlag = accessFlags; + filterRule.ExcludeProcessNames = "explorer.exe"; + filterRule.Id = GlobalConfig.GetFilterRuleId(); + + if ((filterRule.AccessFlag & (uint)FilterAPI.AccessFlag.ENABLE_HIDE_FILES_IN_DIRECTORY_BROWSING) == (uint)FilterAPI.AccessFlag.ENABLE_HIDE_FILES_IN_DIRECTORY_BROWSING) + { + filterRule.HiddenFileFilterMasks = "*"; + } + + if ((filterRule.AccessFlag & (uint)FilterAPI.AccessFlag.ENABLE_FILE_ENCRYPTION_RULE) == (uint)FilterAPI.AccessFlag.ENABLE_FILE_ENCRYPTION_RULE) + { + filterRule.EncryptMethod = (int)FilterAPI.EncryptionMethod.ENCRYPT_FILE_WITH_SAME_KEY_AND_IV; + filterRule.EncryptionPassPhrase = "easefilter"; + } + + Console.WriteLine("Receive AddFilterRule command,includeFileFilterMask:" + includeFileFilterMask + ",eventType:(0x)" + eventType.ToString("x") + + ",monitorIO:(0x)" + monitorIO.ToString("x") + ",accessFlags:(0x)" + accessFlags.ToString("x")); + + retVal = GlobalConfig.AddFilterRule(filterRule); + + if (!retVal) + { + FilterAPI.GetLastErrorMessage(); + EventManager.WriteMessage(43, "AddFilterRule", EventLevel.Error, "AddFilterRule " + filterRule.IncludeFileFilterMask + " failed,filter returned:" + FilterAPI.GetLastErrorMessage()); + return false; + } + + GlobalConfig.SendConfigSettingsToFilter(); + EventManager.WriteMessage(43, "AddFilterRule", EventLevel.Verbose, "AddFilterRule " + filterRule.IncludeFileFilterMask + " succeeded."); + + } + catch (Exception ex) + { + EventManager.WriteMessage(43, "AddFilterRule", EventLevel.Error, "AddFilterRule " + includeFileFilterMask + " failed,system reported:" + ex.Message); + return false; + } + + return true; + } + + public bool DeleteFilterRule(string includeFileFilterMask) + { + try + { + GlobalConfig.RemoveFilterRule(includeFileFilterMask); + GlobalConfig.SendConfigSettingsToFilter(); + + Console.WriteLine("Receive DeleteFilterRule command,includeFileFilterMask:" + includeFileFilterMask); + + EventManager.WriteMessage(43, "RemoveFilterRule", EventLevel.Verbose, "RemoveFilterRule " + includeFileFilterMask + " succeeded."); + + } + catch (Exception ex) + { + EventManager.WriteMessage(43, "RemoveFilterRule", EventLevel.Error, "RemoveFilterRule " + includeFileFilterMask + " failed,system reported:" + ex.Message); + return false; + } + + return true; + } + } + + + public class RemoteClient + { + + FilterRemoteObject remoteObject = null; + TcpChannel chan = new TcpChannel(); + + public RemoteClient() + { + try + { + ChannelServices.RegisterChannel(chan,false); + remoteObject = (FilterRemoteObject)Activator.GetObject(typeof(FilterRemoteObject), "tcp://localhost:65118/filterAPIs"); + } + catch (Exception ex) + { + throw new Exception("Create remoteClient object failed." + ex.Message); + } + } + + public void Stop() + { + try + { + ChannelServices.UnregisterChannel(chan); + } + catch { } + } + + public FilterRemoteObject IRemoteServer + { + get + { + return remoteObject; + } + } + } + + +} diff --git a/Demo_Source_Code/CSharpDemo/CommonObjects/Resources/about.png b/Demo_Source_Code/CSharpDemo/CommonObjects/Resources/about.png new file mode 100644 index 0000000..4017add Binary files /dev/null and b/Demo_Source_Code/CSharpDemo/CommonObjects/Resources/about.png differ diff --git a/Demo_Source_Code/CSharpDemo/CommonObjects/SettingsForm.Designer.cs b/Demo_Source_Code/CSharpDemo/CommonObjects/SettingsForm.Designer.cs new file mode 100644 index 0000000..7d9a1a5 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/CommonObjects/SettingsForm.Designer.cs @@ -0,0 +1,584 @@ +namespace EaseFilter.CommonObjects +{ + partial class SettingsForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(SettingsForm)); + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.button_InfoBlockUSBRead = new System.Windows.Forms.Button(); + this.button_InfoBlockUSBWrite = new System.Windows.Forms.Button(); + this.checkBox_BlockUSBWrite = new System.Windows.Forms.CheckBox(); + this.checkBox_BlockUSBRead = new System.Windows.Forms.CheckBox(); + this.button_InfoGetVolumeInfo = new System.Windows.Forms.Button(); + this.button_InfoNewVolumeInfo = new System.Windows.Forms.Button(); + this.button_InfoHideDirIO = new System.Windows.Forms.Button(); + this.button_InfoBlockVolumeFormatting = new System.Windows.Forms.Button(); + this.button_InfoVolumeDetach = new System.Windows.Forms.Button(); + this.button_InfoConnectionThreads = new System.Windows.Forms.Button(); + this.button_InfoConnectionTimeout = new System.Windows.Forms.Button(); + this.button_InfoMessageOutput = new System.Windows.Forms.Button(); + this.button_InfoLogMessage = new System.Windows.Forms.Button(); + this.button_InfoProtectPid = new System.Windows.Forms.Button(); + this.button_InfoSendBuffer = new System.Windows.Forms.Button(); + this.checkBox_CallbackVolumeDetached = new System.Windows.Forms.CheckBox(); + this.checkBox_CallbackVolumeAttached = new System.Windows.Forms.CheckBox(); + this.checkBox_BlockFormatting = new System.Windows.Forms.CheckBox(); + this.checkBox_GetVolumeInfo = new System.Windows.Forms.CheckBox(); + this.checkBox_SendBuffer = new System.Windows.Forms.CheckBox(); + this.checkBox_DisableDir = new System.Windows.Forms.CheckBox(); + this.checkBox_OutputMessageToConsole = new System.Windows.Forms.CheckBox(); + this.label12 = new System.Windows.Forms.Label(); + this.button_SelectProtectPID = new System.Windows.Forms.Button(); + this.textBox_ProtectedPID = new System.Windows.Forms.TextBox(); + this.label_protector1 = new System.Windows.Forms.Label(); + this.button_EditFilterRule = new System.Windows.Forms.Button(); + this.button_DeleteFilter = new System.Windows.Forms.Button(); + this.button_AddFilter = new System.Windows.Forms.Button(); + this.groupBox2 = new System.Windows.Forms.GroupBox(); + this.listView_FilterRules = new System.Windows.Forms.ListView(); + this.checkBox_TransactionLog = new System.Windows.Forms.CheckBox(); + this.textBox_TransactionLog = new System.Windows.Forms.TextBox(); + this.label7 = new System.Windows.Forms.Label(); + this.textBox_MaximumFilterMessage = new System.Windows.Forms.TextBox(); + this.label6 = new System.Windows.Forms.Label(); + this.textBox_ConnectionTimeout = new System.Windows.Forms.TextBox(); + this.label5 = new System.Windows.Forms.Label(); + this.textBox_ConnectionThreads = new System.Windows.Forms.TextBox(); + this.label1 = new System.Windows.Forms.Label(); + this.button_ApplyOptions = new System.Windows.Forms.Button(); + this.groupBox1.SuspendLayout(); + this.groupBox2.SuspendLayout(); + this.SuspendLayout(); + // + // groupBox1 + // + this.groupBox1.Controls.Add(this.button_InfoBlockUSBRead); + this.groupBox1.Controls.Add(this.button_InfoBlockUSBWrite); + this.groupBox1.Controls.Add(this.checkBox_BlockUSBWrite); + this.groupBox1.Controls.Add(this.checkBox_BlockUSBRead); + this.groupBox1.Controls.Add(this.button_InfoGetVolumeInfo); + this.groupBox1.Controls.Add(this.button_InfoNewVolumeInfo); + this.groupBox1.Controls.Add(this.button_InfoHideDirIO); + this.groupBox1.Controls.Add(this.button_InfoBlockVolumeFormatting); + this.groupBox1.Controls.Add(this.button_InfoVolumeDetach); + this.groupBox1.Controls.Add(this.button_InfoConnectionThreads); + this.groupBox1.Controls.Add(this.button_InfoConnectionTimeout); + this.groupBox1.Controls.Add(this.button_InfoMessageOutput); + this.groupBox1.Controls.Add(this.button_InfoLogMessage); + this.groupBox1.Controls.Add(this.button_InfoProtectPid); + this.groupBox1.Controls.Add(this.button_InfoSendBuffer); + this.groupBox1.Controls.Add(this.checkBox_CallbackVolumeDetached); + this.groupBox1.Controls.Add(this.checkBox_CallbackVolumeAttached); + this.groupBox1.Controls.Add(this.checkBox_BlockFormatting); + this.groupBox1.Controls.Add(this.checkBox_GetVolumeInfo); + this.groupBox1.Controls.Add(this.checkBox_SendBuffer); + this.groupBox1.Controls.Add(this.checkBox_DisableDir); + this.groupBox1.Controls.Add(this.checkBox_OutputMessageToConsole); + this.groupBox1.Controls.Add(this.label12); + this.groupBox1.Controls.Add(this.button_SelectProtectPID); + this.groupBox1.Controls.Add(this.textBox_ProtectedPID); + this.groupBox1.Controls.Add(this.label_protector1); + this.groupBox1.Controls.Add(this.button_EditFilterRule); + this.groupBox1.Controls.Add(this.button_DeleteFilter); + this.groupBox1.Controls.Add(this.button_AddFilter); + this.groupBox1.Controls.Add(this.groupBox2); + this.groupBox1.Controls.Add(this.checkBox_TransactionLog); + this.groupBox1.Controls.Add(this.textBox_TransactionLog); + this.groupBox1.Controls.Add(this.label7); + this.groupBox1.Controls.Add(this.textBox_MaximumFilterMessage); + this.groupBox1.Controls.Add(this.label6); + this.groupBox1.Controls.Add(this.textBox_ConnectionTimeout); + this.groupBox1.Controls.Add(this.label5); + this.groupBox1.Controls.Add(this.textBox_ConnectionThreads); + this.groupBox1.Controls.Add(this.label1); + this.groupBox1.Location = new System.Drawing.Point(3, 12); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size(632, 552); + this.groupBox1.TabIndex = 0; + this.groupBox1.TabStop = false; + // + // button_InfoBlockUSBRead + // + this.button_InfoBlockUSBRead.Image = global::EaseFilter.CommonObjects.Properties.Resources.about; + this.button_InfoBlockUSBRead.Location = new System.Drawing.Point(206, 300); + this.button_InfoBlockUSBRead.Name = "button_InfoBlockUSBRead"; + this.button_InfoBlockUSBRead.Size = new System.Drawing.Size(26, 20); + this.button_InfoBlockUSBRead.TabIndex = 131; + this.button_InfoBlockUSBRead.UseVisualStyleBackColor = true; + this.button_InfoBlockUSBRead.Click += new System.EventHandler(this.button_InfoBlockUSBRead_Click); + // + // button_InfoBlockUSBWrite + // + this.button_InfoBlockUSBWrite.Image = global::EaseFilter.CommonObjects.Properties.Resources.about; + this.button_InfoBlockUSBWrite.Location = new System.Drawing.Point(550, 300); + this.button_InfoBlockUSBWrite.Name = "button_InfoBlockUSBWrite"; + this.button_InfoBlockUSBWrite.Size = new System.Drawing.Size(26, 20); + this.button_InfoBlockUSBWrite.TabIndex = 130; + this.button_InfoBlockUSBWrite.UseVisualStyleBackColor = true; + this.button_InfoBlockUSBWrite.Click += new System.EventHandler(this.button_InfoBlockUSBWrite_Click); + // + // checkBox_BlockUSBWrite + // + this.checkBox_BlockUSBWrite.AutoSize = true; + this.checkBox_BlockUSBWrite.Location = new System.Drawing.Point(341, 300); + this.checkBox_BlockUSBWrite.Name = "checkBox_BlockUSBWrite"; + this.checkBox_BlockUSBWrite.Size = new System.Drawing.Size(115, 17); + this.checkBox_BlockUSBWrite.TabIndex = 129; + this.checkBox_BlockUSBWrite.Text = "Block write to USB"; + this.checkBox_BlockUSBWrite.UseVisualStyleBackColor = true; + // + // checkBox_BlockUSBRead + // + this.checkBox_BlockUSBRead.AutoSize = true; + this.checkBox_BlockUSBRead.Location = new System.Drawing.Point(13, 300); + this.checkBox_BlockUSBRead.Name = "checkBox_BlockUSBRead"; + this.checkBox_BlockUSBRead.Size = new System.Drawing.Size(125, 17); + this.checkBox_BlockUSBRead.TabIndex = 128; + this.checkBox_BlockUSBRead.Text = "Block read from USB"; + this.checkBox_BlockUSBRead.UseVisualStyleBackColor = true; + // + // button_InfoGetVolumeInfo + // + this.button_InfoGetVolumeInfo.Image = global::EaseFilter.CommonObjects.Properties.Resources.about; + this.button_InfoGetVolumeInfo.Location = new System.Drawing.Point(206, 248); + this.button_InfoGetVolumeInfo.Name = "button_InfoGetVolumeInfo"; + this.button_InfoGetVolumeInfo.Size = new System.Drawing.Size(26, 20); + this.button_InfoGetVolumeInfo.TabIndex = 127; + this.button_InfoGetVolumeInfo.UseVisualStyleBackColor = true; + this.button_InfoGetVolumeInfo.Click += new System.EventHandler(this.button_InfoGetVolumeInfo_Click); + // + // button_InfoNewVolumeInfo + // + this.button_InfoNewVolumeInfo.Image = global::EaseFilter.CommonObjects.Properties.Resources.about; + this.button_InfoNewVolumeInfo.Location = new System.Drawing.Point(206, 274); + this.button_InfoNewVolumeInfo.Name = "button_InfoNewVolumeInfo"; + this.button_InfoNewVolumeInfo.Size = new System.Drawing.Size(26, 20); + this.button_InfoNewVolumeInfo.TabIndex = 126; + this.button_InfoNewVolumeInfo.UseVisualStyleBackColor = true; + this.button_InfoNewVolumeInfo.Click += new System.EventHandler(this.button_InfoNewVolumeInfo_Click); + // + // button_InfoHideDirIO + // + this.button_InfoHideDirIO.Image = global::EaseFilter.CommonObjects.Properties.Resources.about; + this.button_InfoHideDirIO.Location = new System.Drawing.Point(207, 219); + this.button_InfoHideDirIO.Name = "button_InfoHideDirIO"; + this.button_InfoHideDirIO.Size = new System.Drawing.Size(26, 20); + this.button_InfoHideDirIO.TabIndex = 125; + this.button_InfoHideDirIO.UseVisualStyleBackColor = true; + this.button_InfoHideDirIO.Click += new System.EventHandler(this.button_InfoHideDirIO_Click); + // + // button_InfoBlockVolumeFormatting + // + this.button_InfoBlockVolumeFormatting.Image = global::EaseFilter.CommonObjects.Properties.Resources.about; + this.button_InfoBlockVolumeFormatting.Location = new System.Drawing.Point(550, 275); + this.button_InfoBlockVolumeFormatting.Name = "button_InfoBlockVolumeFormatting"; + this.button_InfoBlockVolumeFormatting.Size = new System.Drawing.Size(26, 20); + this.button_InfoBlockVolumeFormatting.TabIndex = 124; + this.button_InfoBlockVolumeFormatting.UseVisualStyleBackColor = true; + this.button_InfoBlockVolumeFormatting.Click += new System.EventHandler(this.button_InfoBlockVolumeFormatting_Click); + // + // button_InfoVolumeDetach + // + this.button_InfoVolumeDetach.Image = global::EaseFilter.CommonObjects.Properties.Resources.about; + this.button_InfoVolumeDetach.Location = new System.Drawing.Point(550, 247); + this.button_InfoVolumeDetach.Name = "button_InfoVolumeDetach"; + this.button_InfoVolumeDetach.Size = new System.Drawing.Size(26, 20); + this.button_InfoVolumeDetach.TabIndex = 123; + this.button_InfoVolumeDetach.UseVisualStyleBackColor = true; + this.button_InfoVolumeDetach.Click += new System.EventHandler(this.button_InfoVolumeDetach_Click); + // + // button_InfoConnectionThreads + // + this.button_InfoConnectionThreads.Image = global::EaseFilter.CommonObjects.Properties.Resources.about; + this.button_InfoConnectionThreads.Location = new System.Drawing.Point(550, 60); + this.button_InfoConnectionThreads.Name = "button_InfoConnectionThreads"; + this.button_InfoConnectionThreads.Size = new System.Drawing.Size(28, 20); + this.button_InfoConnectionThreads.TabIndex = 122; + this.button_InfoConnectionThreads.UseVisualStyleBackColor = true; + this.button_InfoConnectionThreads.Click += new System.EventHandler(this.button_InfoConnectionThreads_Click); + // + // button_InfoConnectionTimeout + // + this.button_InfoConnectionTimeout.Image = global::EaseFilter.CommonObjects.Properties.Resources.about; + this.button_InfoConnectionTimeout.Location = new System.Drawing.Point(550, 99); + this.button_InfoConnectionTimeout.Name = "button_InfoConnectionTimeout"; + this.button_InfoConnectionTimeout.Size = new System.Drawing.Size(28, 20); + this.button_InfoConnectionTimeout.TabIndex = 121; + this.button_InfoConnectionTimeout.UseVisualStyleBackColor = true; + this.button_InfoConnectionTimeout.Click += new System.EventHandler(this.button_InfoConnectionTimeout_Click); + // + // button_InfoMessageOutput + // + this.button_InfoMessageOutput.Image = global::EaseFilter.CommonObjects.Properties.Resources.about; + this.button_InfoMessageOutput.Location = new System.Drawing.Point(550, 135); + this.button_InfoMessageOutput.Name = "button_InfoMessageOutput"; + this.button_InfoMessageOutput.Size = new System.Drawing.Size(28, 20); + this.button_InfoMessageOutput.TabIndex = 120; + this.button_InfoMessageOutput.UseVisualStyleBackColor = true; + this.button_InfoMessageOutput.Click += new System.EventHandler(this.button_InfoMessageOutput_Click); + // + // button_InfoLogMessage + // + this.button_InfoLogMessage.Image = global::EaseFilter.CommonObjects.Properties.Resources.about; + this.button_InfoLogMessage.Location = new System.Drawing.Point(550, 187); + this.button_InfoLogMessage.Name = "button_InfoLogMessage"; + this.button_InfoLogMessage.Size = new System.Drawing.Size(28, 20); + this.button_InfoLogMessage.TabIndex = 119; + this.button_InfoLogMessage.UseVisualStyleBackColor = true; + this.button_InfoLogMessage.Click += new System.EventHandler(this.button_InfoLogMessage_Click); + // + // button_InfoProtectPid + // + this.button_InfoProtectPid.Image = global::EaseFilter.CommonObjects.Properties.Resources.about; + this.button_InfoProtectPid.Location = new System.Drawing.Point(587, 21); + this.button_InfoProtectPid.Name = "button_InfoProtectPid"; + this.button_InfoProtectPid.Size = new System.Drawing.Size(28, 20); + this.button_InfoProtectPid.TabIndex = 118; + this.button_InfoProtectPid.UseVisualStyleBackColor = true; + this.button_InfoProtectPid.Click += new System.EventHandler(this.button_InfoProtectPid_Click); + // + // button_InfoSendBuffer + // + this.button_InfoSendBuffer.Image = global::EaseFilter.CommonObjects.Properties.Resources.about; + this.button_InfoSendBuffer.Location = new System.Drawing.Point(548, 219); + this.button_InfoSendBuffer.Name = "button_InfoSendBuffer"; + this.button_InfoSendBuffer.Size = new System.Drawing.Size(26, 20); + this.button_InfoSendBuffer.TabIndex = 73; + this.button_InfoSendBuffer.UseVisualStyleBackColor = true; + this.button_InfoSendBuffer.Click += new System.EventHandler(this.button_InfoSendBuffer_Click); + // + // checkBox_CallbackVolumeDetached + // + this.checkBox_CallbackVolumeDetached.AutoSize = true; + this.checkBox_CallbackVolumeDetached.Location = new System.Drawing.Point(341, 247); + this.checkBox_CallbackVolumeDetached.Name = "checkBox_CallbackVolumeDetached"; + this.checkBox_CallbackVolumeDetached.Size = new System.Drawing.Size(189, 17); + this.checkBox_CallbackVolumeDetached.TabIndex = 72; + this.checkBox_CallbackVolumeDetached.Text = "Notify when volume was detached"; + this.checkBox_CallbackVolumeDetached.UseVisualStyleBackColor = true; + // + // checkBox_CallbackVolumeAttached + // + this.checkBox_CallbackVolumeAttached.AutoSize = true; + this.checkBox_CallbackVolumeAttached.Location = new System.Drawing.Point(13, 274); + this.checkBox_CallbackVolumeAttached.Name = "checkBox_CallbackVolumeAttached"; + this.checkBox_CallbackVolumeAttached.Size = new System.Drawing.Size(187, 17); + this.checkBox_CallbackVolumeAttached.TabIndex = 71; + this.checkBox_CallbackVolumeAttached.Text = "Notify when new volume attached"; + this.checkBox_CallbackVolumeAttached.UseVisualStyleBackColor = true; + // + // checkBox_BlockFormatting + // + this.checkBox_BlockFormatting.AutoSize = true; + this.checkBox_BlockFormatting.Location = new System.Drawing.Point(341, 275); + this.checkBox_BlockFormatting.Name = "checkBox_BlockFormatting"; + this.checkBox_BlockFormatting.Size = new System.Drawing.Size(167, 17); + this.checkBox_BlockFormatting.TabIndex = 70; + this.checkBox_BlockFormatting.Text = "Block volumes from formatting"; + this.checkBox_BlockFormatting.UseVisualStyleBackColor = true; + // + // checkBox_GetVolumeInfo + // + this.checkBox_GetVolumeInfo.AutoSize = true; + this.checkBox_GetVolumeInfo.Location = new System.Drawing.Point(13, 248); + this.checkBox_GetVolumeInfo.Name = "checkBox_GetVolumeInfo"; + this.checkBox_GetVolumeInfo.Size = new System.Drawing.Size(179, 17); + this.checkBox_GetVolumeInfo.TabIndex = 69; + this.checkBox_GetVolumeInfo.Text = "Get attached volume information"; + this.checkBox_GetVolumeInfo.UseVisualStyleBackColor = true; + // + // checkBox_SendBuffer + // + this.checkBox_SendBuffer.AutoSize = true; + this.checkBox_SendBuffer.Location = new System.Drawing.Point(341, 219); + this.checkBox_SendBuffer.Name = "checkBox_SendBuffer"; + this.checkBox_SendBuffer.Size = new System.Drawing.Size(166, 17); + this.checkBox_SendBuffer.TabIndex = 68; + this.checkBox_SendBuffer.Text = "Enable send read/write buffer"; + this.checkBox_SendBuffer.UseVisualStyleBackColor = true; + // + // checkBox_DisableDir + // + this.checkBox_DisableDir.AutoSize = true; + this.checkBox_DisableDir.Location = new System.Drawing.Point(13, 219); + this.checkBox_DisableDir.Name = "checkBox_DisableDir"; + this.checkBox_DisableDir.Size = new System.Drawing.Size(155, 17); + this.checkBox_DisableDir.TabIndex = 67; + this.checkBox_DisableDir.Text = "Hide directory IO messages"; + this.checkBox_DisableDir.UseVisualStyleBackColor = true; + // + // checkBox_OutputMessageToConsole + // + this.checkBox_OutputMessageToConsole.AutoSize = true; + this.checkBox_OutputMessageToConsole.Checked = true; + this.checkBox_OutputMessageToConsole.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBox_OutputMessageToConsole.Location = new System.Drawing.Point(398, 135); + this.checkBox_OutputMessageToConsole.Name = "checkBox_OutputMessageToConsole"; + this.checkBox_OutputMessageToConsole.Size = new System.Drawing.Size(155, 17); + this.checkBox_OutputMessageToConsole.TabIndex = 63; + this.checkBox_OutputMessageToConsole.Text = "Output message to console"; + this.checkBox_OutputMessageToConsole.UseVisualStyleBackColor = true; + // + // label12 + // + this.label12.AutoSize = true; + this.label12.Font = new System.Drawing.Font("Microsoft Sans Serif", 6.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.label12.Location = new System.Drawing.Point(204, 155); + this.label12.Name = "label12"; + this.label12.Size = new System.Drawing.Size(233, 12); + this.label12.TabIndex = 61; + this.label12.Text = "(The maximum message items to display in the console)"; + // + // button_SelectProtectPID + // + this.button_SelectProtectPID.Location = new System.Drawing.Point(548, 20); + this.button_SelectProtectPID.Name = "button_SelectProtectPID"; + this.button_SelectProtectPID.Size = new System.Drawing.Size(30, 20); + this.button_SelectProtectPID.TabIndex = 56; + this.button_SelectProtectPID.Text = "..."; + this.button_SelectProtectPID.UseVisualStyleBackColor = true; + this.button_SelectProtectPID.Click += new System.EventHandler(this.button_SelectProtectPID_Click); + // + // textBox_ProtectedPID + // + this.textBox_ProtectedPID.Location = new System.Drawing.Point(207, 21); + this.textBox_ProtectedPID.Name = "textBox_ProtectedPID"; + this.textBox_ProtectedPID.ReadOnly = true; + this.textBox_ProtectedPID.Size = new System.Drawing.Size(324, 20); + this.textBox_ProtectedPID.TabIndex = 55; + // + // label_protector1 + // + this.label_protector1.AutoSize = true; + this.label_protector1.Location = new System.Drawing.Point(10, 20); + this.label_protector1.Name = "label_protector1"; + this.label_protector1.Size = new System.Drawing.Size(114, 13); + this.label_protector1.TabIndex = 54; + this.label_protector1.Text = "Add protect process Id"; + // + // button_EditFilterRule + // + this.button_EditFilterRule.Location = new System.Drawing.Point(236, 513); + this.button_EditFilterRule.Name = "button_EditFilterRule"; + this.button_EditFilterRule.Size = new System.Drawing.Size(92, 23); + this.button_EditFilterRule.TabIndex = 53; + this.button_EditFilterRule.Text = "Edit Filter Rule"; + this.button_EditFilterRule.UseVisualStyleBackColor = true; + this.button_EditFilterRule.Click += new System.EventHandler(this.button_EditFilterRule_Click); + // + // button_DeleteFilter + // + this.button_DeleteFilter.Location = new System.Drawing.Point(461, 513); + this.button_DeleteFilter.Name = "button_DeleteFilter"; + this.button_DeleteFilter.Size = new System.Drawing.Size(114, 23); + this.button_DeleteFilter.TabIndex = 52; + this.button_DeleteFilter.Text = "Delete Filter Rule"; + this.button_DeleteFilter.UseVisualStyleBackColor = true; + this.button_DeleteFilter.Click += new System.EventHandler(this.button_DeleteFilter_Click); + // + // button_AddFilter + // + this.button_AddFilter.Location = new System.Drawing.Point(9, 513); + this.button_AddFilter.Name = "button_AddFilter"; + this.button_AddFilter.Size = new System.Drawing.Size(127, 23); + this.button_AddFilter.TabIndex = 51; + this.button_AddFilter.Text = "Add New Filter Rule"; + this.button_AddFilter.UseVisualStyleBackColor = true; + this.button_AddFilter.Click += new System.EventHandler(this.button_AddFilter_Click); + // + // groupBox2 + // + this.groupBox2.Controls.Add(this.listView_FilterRules); + this.groupBox2.Location = new System.Drawing.Point(6, 340); + this.groupBox2.Name = "groupBox2"; + this.groupBox2.Size = new System.Drawing.Size(572, 167); + this.groupBox2.TabIndex = 50; + this.groupBox2.TabStop = false; + this.groupBox2.Text = "Filter Rule Settings Collection"; + // + // listView_FilterRules + // + this.listView_FilterRules.Dock = System.Windows.Forms.DockStyle.Fill; + this.listView_FilterRules.FullRowSelect = true; + this.listView_FilterRules.Location = new System.Drawing.Point(3, 16); + this.listView_FilterRules.Name = "listView_FilterRules"; + this.listView_FilterRules.Size = new System.Drawing.Size(566, 148); + this.listView_FilterRules.TabIndex = 1; + this.listView_FilterRules.UseCompatibleStateImageBehavior = false; + this.listView_FilterRules.View = System.Windows.Forms.View.Details; + // + // checkBox_TransactionLog + // + this.checkBox_TransactionLog.AutoSize = true; + this.checkBox_TransactionLog.Location = new System.Drawing.Point(398, 187); + this.checkBox_TransactionLog.Name = "checkBox_TransactionLog"; + this.checkBox_TransactionLog.Size = new System.Drawing.Size(143, 17); + this.checkBox_TransactionLog.TabIndex = 44; + this.checkBox_TransactionLog.Text = "Enable log filter message"; + this.checkBox_TransactionLog.UseVisualStyleBackColor = true; + // + // textBox_TransactionLog + // + this.textBox_TransactionLog.Location = new System.Drawing.Point(206, 185); + this.textBox_TransactionLog.Name = "textBox_TransactionLog"; + this.textBox_TransactionLog.Size = new System.Drawing.Size(164, 20); + this.textBox_TransactionLog.TabIndex = 43; + this.textBox_TransactionLog.Text = "filterMessage.log"; + // + // label7 + // + this.label7.AutoSize = true; + this.label7.Location = new System.Drawing.Point(10, 185); + this.label7.Name = "label7"; + this.label7.Size = new System.Drawing.Size(148, 13); + this.label7.TabIndex = 42; + this.label7.Text = "File name to log filter message"; + // + // textBox_MaximumFilterMessage + // + this.textBox_MaximumFilterMessage.Location = new System.Drawing.Point(206, 133); + this.textBox_MaximumFilterMessage.Name = "textBox_MaximumFilterMessage"; + this.textBox_MaximumFilterMessage.Size = new System.Drawing.Size(164, 20); + this.textBox_MaximumFilterMessage.TabIndex = 41; + this.textBox_MaximumFilterMessage.Text = "500"; + // + // label6 + // + this.label6.AutoSize = true; + this.label6.Location = new System.Drawing.Point(10, 133); + this.label6.Name = "label6"; + this.label6.Size = new System.Drawing.Size(89, 13); + this.label6.TabIndex = 40; + this.label6.Text = "Maximum records"; + // + // textBox_ConnectionTimeout + // + this.textBox_ConnectionTimeout.Location = new System.Drawing.Point(206, 100); + this.textBox_ConnectionTimeout.Name = "textBox_ConnectionTimeout"; + this.textBox_ConnectionTimeout.Size = new System.Drawing.Size(325, 20); + this.textBox_ConnectionTimeout.TabIndex = 37; + // + // label5 + // + this.label5.AutoSize = true; + this.label5.Location = new System.Drawing.Point(10, 100); + this.label5.Name = "label5"; + this.label5.Size = new System.Drawing.Size(151, 13); + this.label5.TabIndex = 36; + this.label5.Text = "Filter driver connection timeout"; + // + // textBox_ConnectionThreads + // + this.textBox_ConnectionThreads.Location = new System.Drawing.Point(207, 61); + this.textBox_ConnectionThreads.Name = "textBox_ConnectionThreads"; + this.textBox_ConnectionThreads.Size = new System.Drawing.Size(324, 20); + this.textBox_ConnectionThreads.TabIndex = 33; + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(10, 60); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(145, 13); + this.label1.TabIndex = 32; + this.label1.Text = "Maximum connection threads"; + // + // button_ApplyOptions + // + this.button_ApplyOptions.DialogResult = System.Windows.Forms.DialogResult.OK; + this.button_ApplyOptions.Location = new System.Drawing.Point(464, 570); + this.button_ApplyOptions.Name = "button_ApplyOptions"; + this.button_ApplyOptions.Size = new System.Drawing.Size(114, 23); + this.button_ApplyOptions.TabIndex = 1; + this.button_ApplyOptions.Text = "Apply Settings"; + this.button_ApplyOptions.UseVisualStyleBackColor = true; + this.button_ApplyOptions.Click += new System.EventHandler(this.button_ApplyOptions_Click); + // + // SettingsForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(634, 612); + this.Controls.Add(this.button_ApplyOptions); + this.Controls.Add(this.groupBox1); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Name = "SettingsForm"; + this.Text = "Filter Driver Global Settings"; + this.groupBox1.ResumeLayout(false); + this.groupBox1.PerformLayout(); + this.groupBox2.ResumeLayout(false); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.GroupBox groupBox1; + private System.Windows.Forms.TextBox textBox_ConnectionTimeout; + private System.Windows.Forms.Label label5; + private System.Windows.Forms.TextBox textBox_ConnectionThreads; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Button button_ApplyOptions; + private System.Windows.Forms.CheckBox checkBox_TransactionLog; + private System.Windows.Forms.TextBox textBox_TransactionLog; + private System.Windows.Forms.Label label7; + private System.Windows.Forms.TextBox textBox_MaximumFilterMessage; + private System.Windows.Forms.Label label6; + private System.Windows.Forms.GroupBox groupBox2; + private System.Windows.Forms.ListView listView_FilterRules; + private System.Windows.Forms.Button button_DeleteFilter; + private System.Windows.Forms.Button button_AddFilter; + private System.Windows.Forms.Button button_EditFilterRule; + private System.Windows.Forms.Button button_SelectProtectPID; + private System.Windows.Forms.TextBox textBox_ProtectedPID; + private System.Windows.Forms.Label label_protector1; + private System.Windows.Forms.Label label12; + private System.Windows.Forms.CheckBox checkBox_OutputMessageToConsole; + private System.Windows.Forms.CheckBox checkBox_DisableDir; + private System.Windows.Forms.CheckBox checkBox_SendBuffer; + private System.Windows.Forms.CheckBox checkBox_CallbackVolumeDetached; + private System.Windows.Forms.CheckBox checkBox_CallbackVolumeAttached; + private System.Windows.Forms.CheckBox checkBox_BlockFormatting; + private System.Windows.Forms.CheckBox checkBox_GetVolumeInfo; + private System.Windows.Forms.Button button_InfoSendBuffer; + private System.Windows.Forms.Button button_InfoGetVolumeInfo; + private System.Windows.Forms.Button button_InfoNewVolumeInfo; + private System.Windows.Forms.Button button_InfoHideDirIO; + private System.Windows.Forms.Button button_InfoBlockVolumeFormatting; + private System.Windows.Forms.Button button_InfoVolumeDetach; + private System.Windows.Forms.Button button_InfoConnectionThreads; + private System.Windows.Forms.Button button_InfoConnectionTimeout; + private System.Windows.Forms.Button button_InfoMessageOutput; + private System.Windows.Forms.Button button_InfoLogMessage; + private System.Windows.Forms.Button button_InfoProtectPid; + private System.Windows.Forms.Button button_InfoBlockUSBRead; + private System.Windows.Forms.Button button_InfoBlockUSBWrite; + private System.Windows.Forms.CheckBox checkBox_BlockUSBWrite; + private System.Windows.Forms.CheckBox checkBox_BlockUSBRead; + } +} \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/CommonObjects/SettingsForm.cs b/Demo_Source_Code/CSharpDemo/CommonObjects/SettingsForm.cs new file mode 100644 index 0000000..6fa09dd --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/CommonObjects/SettingsForm.cs @@ -0,0 +1,464 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +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; + +using EaseFilter.FilterControl; + +namespace EaseFilter.CommonObjects +{ + public partial class SettingsForm : Form + { + public SettingsForm() + { + InitializeComponent(); + InitOptionForm(); + } + + private void InitOptionForm() + { + try + { + if (GlobalConfig.filterType == FilterAPI.FilterType.MONITOR_FILTER) + { + //disable some non monitor settings + label_protector1.Visible = false; + textBox_ProtectedPID.Visible = false; + button_InfoProtectPid.Visible = false; + button_SelectProtectPID.Visible = false; + + checkBox_BlockFormatting.Visible = false; + checkBox_BlockUSBRead.Visible = false; + checkBox_BlockUSBWrite.Visible = false; + button_InfoBlockVolumeFormatting.Visible = false; + button_InfoBlockUSBWrite.Visible = false; + button_InfoBlockUSBRead.Visible = false; + } + + textBox_MaximumFilterMessage.Text = GlobalConfig.MaximumFilterMessages.ToString(); + textBox_TransactionLog.Text = GlobalConfig.FilterMessageLogName; + checkBox_TransactionLog.Checked = GlobalConfig.EnableLogTransaction; + checkBox_OutputMessageToConsole.Checked = GlobalConfig.OutputMessageToConsole; + checkBox_DisableDir.Checked = GlobalConfig.DisableDirIO; + + textBox_ConnectionThreads.Text = GlobalConfig.FilterConnectionThreads.ToString(); + textBox_ConnectionTimeout.Text = GlobalConfig.ConnectionTimeOut.ToString(); + + if ((GlobalConfig.BooleanConfig & (uint)FilterAPI.BooleanConfig.ENABLE_SEND_DATA_BUFFER) > 0) + { + checkBox_SendBuffer.Checked = true; + } + else + { + checkBox_SendBuffer.Checked = false; + } + + if ((GlobalConfig.VolumeControlFlag & (uint)FilterAPI.VolumeControlFlag.GET_ATTACHED_VOLUME_INFO) > 0) + { + checkBox_GetVolumeInfo.Checked = true; + } + else + { + checkBox_GetVolumeInfo.Checked = false; + } + + if ((GlobalConfig.VolumeControlFlag & (uint)FilterAPI.VolumeControlFlag.VOLUME_ATTACHED_NOTIFICATION) > 0) + { + checkBox_CallbackVolumeAttached.Checked = true; + } + else + { + checkBox_CallbackVolumeAttached.Checked = false; + } + + if ((GlobalConfig.VolumeControlFlag & (uint)FilterAPI.VolumeControlFlag.VOLUME_DETACHED_NOTIFICATION) > 0) + { + checkBox_CallbackVolumeDetached.Checked = true; + } + else + { + checkBox_CallbackVolumeDetached.Checked = false; + } + + if ((GlobalConfig.VolumeControlFlag & (uint)FilterAPI.VolumeControlFlag.BLOCK_VOLUME_DISMOUNT) > 0) + { + checkBox_BlockFormatting.Checked = true; + } + else + { + checkBox_BlockFormatting.Checked = false; + } + + if ((GlobalConfig.VolumeControlFlag & (uint)FilterAPI.VolumeControlFlag.BLOCK_USB_READ) > 0) + { + checkBox_BlockUSBRead.Checked = true; + } + else + { + checkBox_BlockUSBRead.Checked = false; + } + + if ((GlobalConfig.VolumeControlFlag & (uint)FilterAPI.VolumeControlFlag.BLOCK_USB_WRITE) > 0) + { + checkBox_BlockUSBWrite.Checked = true; + } + else + { + checkBox_BlockUSBWrite.Checked = false; + } + + + foreach (uint pid in GlobalConfig.IncludePidList) + { + if (textBox_ConnectionThreads.Text.Length > 0) + { + textBox_ConnectionThreads.Text += ";"; + } + + textBox_ConnectionThreads.Text += pid.ToString(); + } + + foreach (uint pid in GlobalConfig.ExcludePidList) + { + if (textBox_ConnectionTimeout.Text.Length > 0) + { + textBox_ConnectionTimeout.Text += ";"; + } + + textBox_ConnectionTimeout.Text += pid.ToString(); + } + + foreach (uint pid in GlobalConfig.ProtectPidList) + { + if (textBox_ProtectedPID.Text.Length > 0) + { + textBox_ProtectedPID.Text += ";"; + } + + textBox_ProtectedPID.Text += pid.ToString(); + } + + InitListView(); + + } + catch (Exception ex) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("Initialize the option form failed with error " + ex.Message, "Init options.", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + + public void InitListView() + { + //init ListView control + listView_FilterRules.Clear(); //clear control + //create column header for ListView + listView_FilterRules.Columns.Add("#", 20, System.Windows.Forms.HorizontalAlignment.Left); + listView_FilterRules.Columns.Add("InlcudeFilterMask", 150, System.Windows.Forms.HorizontalAlignment.Left); + listView_FilterRules.Columns.Add("ExcludeFilterMask", 200, System.Windows.Forms.HorizontalAlignment.Left); + listView_FilterRules.Columns.Add("AccessFlags", 100, System.Windows.Forms.HorizontalAlignment.Left); + + foreach (FileFilterRule rule in GlobalConfig.FilterRules.Values) + { + AddItem(rule); + } + + } + + private void AddItem(FileFilterRule newRule) + { + string[] itemStr = new string[listView_FilterRules.Columns.Count]; + itemStr[0] = listView_FilterRules.Items.Count.ToString(); + itemStr[1] = newRule.IncludeFileFilterMask; + itemStr[2] = newRule.ExcludeFileFilterMasks; + itemStr[3] = newRule.AccessFlag.ToString(); + ListViewItem item = new ListViewItem(itemStr, 0); + item.Tag = newRule; + listView_FilterRules.Items.Add(item); + } + + private void button_AddFilter_Click(object sender, EventArgs e) + { + string defaultAccessFlags = ((uint)FilterAPI.ALLOW_MAX_RIGHT_ACCESS ).ToString(); + + FilterRuleForm filterRuleForm = new FilterRuleForm(); + filterRuleForm.StartPosition = FormStartPosition.CenterParent; + filterRuleForm.ShowDialog(); + + InitListView(); + } + + private void button_EditFilterRule_Click(object sender, EventArgs e) + { + if (listView_FilterRules.SelectedItems.Count != 1) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("Please select one filter rule to edit.", "Edit Filter Rule", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + System.Windows.Forms.ListViewItem item = listView_FilterRules.SelectedItems[0]; + FileFilterRule filterRule = ((FileFilterRule)item.Tag).Copy(); + + FilterRuleForm filterRuleForm = new FilterRuleForm(filterRule); + filterRuleForm.StartPosition = FormStartPosition.CenterParent; + filterRuleForm.ShowDialog(); + + InitListView(); + } + + private void button_DeleteFilter_Click(object sender, EventArgs e) + { + if (listView_FilterRules.SelectedItems.Count == 0) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("There are no filter rule selected.", "Delete Filter Rule", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + foreach (System.Windows.Forms.ListViewItem item in listView_FilterRules.SelectedItems) + { + FileFilterRule filterRule = (FileFilterRule)item.Tag; + GlobalConfig.RemoveFilterRule(filterRule.IncludeFileFilterMask); + } + + InitListView(); + } + + + private void button_ApplyOptions_Click(object sender, EventArgs e) + { + try + { + + GlobalConfig.MaximumFilterMessages = int.Parse(textBox_MaximumFilterMessage.Text); + GlobalConfig.EnableLogTransaction = checkBox_TransactionLog.Checked; + GlobalConfig.OutputMessageToConsole = checkBox_OutputMessageToConsole.Checked; + GlobalConfig.FilterMessageLogName = textBox_TransactionLog.Text; + GlobalConfig.DisableDirIO = checkBox_DisableDir.Checked; + + if (checkBox_BlockFormatting.Checked) + { + GlobalConfig.VolumeControlFlag |= (uint)FilterAPI.VolumeControlFlag.BLOCK_VOLUME_DISMOUNT; + } + else + { + GlobalConfig.VolumeControlFlag &= (uint)(~FilterAPI.VolumeControlFlag.BLOCK_VOLUME_DISMOUNT); + } + + if (checkBox_CallbackVolumeAttached.Checked) + { + GlobalConfig.VolumeControlFlag |= (uint)FilterAPI.VolumeControlFlag.VOLUME_ATTACHED_NOTIFICATION; + } + else + { + GlobalConfig.VolumeControlFlag &= (uint)(~FilterAPI.VolumeControlFlag.VOLUME_ATTACHED_NOTIFICATION); + } + + if (checkBox_CallbackVolumeDetached.Checked) + { + GlobalConfig.VolumeControlFlag |= (uint)FilterAPI.VolumeControlFlag.VOLUME_DETACHED_NOTIFICATION; + } + else + { + GlobalConfig.VolumeControlFlag &= (uint)(~FilterAPI.VolumeControlFlag.VOLUME_DETACHED_NOTIFICATION); + } + + if (checkBox_GetVolumeInfo.Checked) + { + GlobalConfig.VolumeControlFlag |= (uint)FilterAPI.VolumeControlFlag.GET_ATTACHED_VOLUME_INFO; + } + else + { + GlobalConfig.VolumeControlFlag &= (uint)(~FilterAPI.VolumeControlFlag.GET_ATTACHED_VOLUME_INFO); + } + + if (checkBox_BlockUSBRead.Checked) + { + GlobalConfig.VolumeControlFlag |= (uint)FilterAPI.VolumeControlFlag.BLOCK_USB_READ; + } + else + { + GlobalConfig.VolumeControlFlag &= (uint)(~FilterAPI.VolumeControlFlag.BLOCK_USB_READ); + } + + if (checkBox_BlockUSBWrite.Checked) + { + GlobalConfig.VolumeControlFlag |= (uint)FilterAPI.VolumeControlFlag.BLOCK_USB_WRITE; + } + else + { + GlobalConfig.VolumeControlFlag &= (uint)(~FilterAPI.VolumeControlFlag.BLOCK_USB_WRITE); + } + + + if (checkBox_SendBuffer.Checked) + { + GlobalConfig.BooleanConfig |= (uint)FilterAPI.BooleanConfig.ENABLE_SEND_DATA_BUFFER; + } + else + { + GlobalConfig.BooleanConfig &= (uint)(~FilterAPI.BooleanConfig.ENABLE_SEND_DATA_BUFFER); + } + + GlobalConfig.FilterConnectionThreads = int.Parse(textBox_ConnectionThreads.Text); + GlobalConfig.ConnectionTimeOut = int.Parse(textBox_ConnectionTimeout.Text); + + List protectPids = new List(); + if (textBox_ProtectedPID.Text.Trim().Length > 0) + { + if (textBox_ProtectedPID.Text.EndsWith(";")) + { + textBox_ProtectedPID.Text = textBox_ProtectedPID.Text.Remove(textBox_ProtectedPID.Text.Length - 1); + } + + string[] pids = textBox_ProtectedPID.Text.Split(new char[] { ';' }); + for (int i = 0; i < pids.Length; i++) + { + protectPids.Add(uint.Parse(pids[i].Trim())); + } + } + + GlobalConfig.ProtectPidList = protectPids; + + if (GlobalConfig.FilterRules.Count == 0) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("There are no one filter rule added, the filter driver won't monitor any file.", "Filter Rule", MessageBoxButtons.OK, MessageBoxIcon.Warning); + } + + GlobalConfig.SaveConfigSetting(); + + this.Close(); + + } + catch (Exception ex) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("Save options failed with error " + ex.Message, "Save options.", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + + private void button_SelectIncludePID_Click(object sender, EventArgs e) + { + + OptionForm optionForm = new OptionForm(OptionForm.OptionType.ProccessId, textBox_ConnectionThreads.Text); + + if (optionForm.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + textBox_ConnectionThreads.Text = optionForm.ProcessId; + } + } + + private void button_SelectExcludePID_Click(object sender, EventArgs e) + { + + OptionForm optionForm = new OptionForm(OptionForm.OptionType.ProccessId, textBox_ConnectionTimeout.Text); + + if (optionForm.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + textBox_ConnectionTimeout.Text = optionForm.ProcessId; + } + } + + + private void button_SelectProtectPID_Click(object sender, EventArgs e) + { + OptionForm optionForm = new OptionForm(OptionForm.OptionType.ProccessId, textBox_ProtectedPID.Text); + + if (optionForm.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + textBox_ProtectedPID.Text = optionForm.ProcessId; + } + } + + private void button_InfoProtectPid_Click(object sender, EventArgs e) + { + MessageBox.Show("Prevent the processes from being terminated when the process Id list is not empty, multiple process Ids are supported."); + } + + private void button_InfoConnectionThreads_Click(object sender, EventArgs e) + { + MessageBox.Show("The number of the threads to communicate with the filter driver to get the events."); + } + + private void button_InfoConnectionTimeout_Click(object sender, EventArgs e) + { + MessageBox.Show("The maximum timeout the filter driver wait for the IO event return in seconds."); + } + + private void button_InfoMessageOutput_Click(object sender, EventArgs e) + { + MessageBox.Show("Enable or disable the message displaying in console when there are notfication events were fired."); + } + + private void button_InfoLogMessage_Click(object sender, EventArgs e) + { + MessageBox.Show("Enable or disable logging the message to a file when there are notfication events were fired."); + } + + private void button_InfoHideDirIO_Click(object sender, EventArgs e) + { + MessageBox.Show("Enable or disable the directory IO message displaying in console when there are notfication events were fired."); + } + + private void button_InfoGetVolumeInfo_Click(object sender, EventArgs e) + { + MessageBox.Show("Get all the attached volume information from the filter driver when the service is started if it was enabled."); + } + + private void button_InfoNewVolumeInfo_Click(object sender, EventArgs e) + { + MessageBox.Show("Get the notification when the filter driver attached to a new volume if it was enabled."); + } + + private void button_InfoSendBuffer_Click(object sender, EventArgs e) + { + MessageBox.Show("In order to reduce the stress of the events, it will send the read/write data when the read/write events were fired only when it was enabled."); + } + + private void button_InfoBlockVolumeFormatting_Click(object sender, EventArgs e) + { + MessageBox.Show("Prevent all the attached volumes from being formatting when it was enabled."); + } + + private void button_InfoVolumeDetach_Click(object sender, EventArgs e) + { + MessageBox.Show("Get the notification when a attached volume was detached if it was enabled."); + } + + private void button_InfoBlockUSBWrite_Click(object sender, EventArgs e) + { + MessageBox.Show("Block the write data to the USB disk."); + } + + private void button_InfoBlockUSBRead_Click(object sender, EventArgs e) + { + MessageBox.Show("Block the read data from the USB disk."); + } + + + + } +} diff --git a/Demo_Source_Code/CSharpDemo/CommonObjects/SettingsForm.resx b/Demo_Source_Code/CSharpDemo/CommonObjects/SettingsForm.resx new file mode 100644 index 0000000..b5a6f9c --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/CommonObjects/SettingsForm.resx @@ -0,0 +1,570 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + AAABAAgAEBAAAAEACABoBQAAhgAAABAQAAABACAAaAQAAO4FAAAYGAAAAQAIAMgGAABWCgAAGBgAAAEA + IACICQAAHhEAACAgAAABAAgAqAgAAKYaAAAgIAAAAQAgAKgQAABOIwAAMDAAAAEACACoDgAA9jMAADAw + AAABACAAqCUAAJ5CAAAoAAAAEAAAACAAAAABAAgAAAAAAEABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP// + /wCec3MA4LS0AIBOTgC9lJQA7NnZAJ+MjADFq6sAkmBgAOPHxwD38fEArYGBAJZ/fwDz5eUA7b29AMef + nwC3n58Ai2pqAIhXVwCxi4sA0qenANK0tADbvb0A6NDQALCWlgCRc3MApHp6AL+MjACig4MAiF5eAKiI + iACteXkAvqOjAMKamgDKpaUAm4aGAPv29gCAVlYA58LCAN/CwgDv3t4A5MzMANawsACGUFAA7dPTAOC6 + ugCbfHwAk3t7ALOSkgCkcnIA/fv7AMSjowC5m5sA3LGxAItmZgDw4uIAzaioAMeZmQCMYGAAlXFxAL6Y + mADq1tYA4b+/AKSGhgCziIgA0KSkAMGdnQCIW1sApImJAL6goADnysoA6dPTAIpZWQDmzs4A5cXFAOHF + xQCDT08A3MHBAKd7ewDBl5cAiVVVAPHg4ADjysoA5sjIAODHxwDev78A2ru7AJyIiAClg4MAzaWlAKR0 + dACkeHgA3r29AOzX1wCJZ2cA5tHRAMmgoADFoKAA7d7eANy/vwB/T08A8ubmAOnR0QDiyckA4sbGAKN5 + eQDewcEA38DAAN++vgCsgoIAzKenAMGZmQDp1NQA5s3NAOPIyADhxMQA3MLCAM2kpADKpqYAyqSkAPHi + 4gDr19cA6NHRAOfQ0ADlzMwA5MrKAOPJyQDiyMgA4cfHAOPGxgDhxsYAqYiIANu7uwDCnZ0AAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAANBBIAAAAAAAAAAAAAAAcAX0JNADAsGgAAAAAAABsJHiBLQVEcA0kA + AAAAAC91FxUnbIVhLis3AAAAAAAAT3t/gApoc1ZaZRJYAABFMltnKnxrbSiDXToPJgAAbi1gU16GNQg2 + KExdP0QAAAxjOH1SAgAANHSBOTsAAAAAWRZyDmo8QCJ9gSMTAAAAADFkPgZ5V1R6fmlHUCQAAAB2MwtI + SikGfoJDPVwAAAAARngFb2YYSnFOHQAAAAAAAAAAAHAlYhR3VYQAAAAAAAAAAAAhEBEAGR8AAAAAAAAA + AAAAAAAAAAAAAAAAAAD//wAA/H8AAPRHAADgBwAAwAcAAOABAACAAQAAgAEAAIGDAADAAwAAwAEAAMAD + AADADwAA+A8AAPifAAD//wAAKAAAABAAAAAgAAAAAQAgAAAAAABABAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB3Pz9rgE1N+nY/P5sAAAAAAAAAAGU8PA4AAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAh01NRYRQUFyHAAACe0tLtNCkpP+DTk75c0JCK3A7O3CGT0/5dz09ggAA + AAAAAAAAAAAAAAAAAAAAAAAAjlFROqV6evqSYGD/hFVV4a96evvlxcX/s4iI/4tWVv7Bjo7+4LS0/4dQ + UOMAAAAAAAAAAAAAAAAAAAAAAAAAAI1SUojcwsL/2729/9Knp//nwsL/38DA/9u7u//JoKD/4Lq6/9aw + sP96QkKoAAAAAAAAAAAAAAAAAAAAAAAAAACQWFgjqHt79+jR0f/jycn/4sjI/+PHx//iycn/48jI/96/ + v//NpaX/ekRE43dCQp95Pz9XAAAAAAAAAACcZGR+pG9v76R0dP/p0dH/5MzM/+fQ0P/ewcH/376+/9/C + wv/hxsb/3r29/8eZmf/tvb3/eUdH2QAAAAAAAAAArX9/6e3T0//m0dH/48rK/+zX1//Enp78xIqKhOOn + p2/hsrLs38LC/+HFxf/evb3/4b+//4NQUN8AAAAAAAAAAK+Cgvrt3t7/8OLi/+XMzP/x4OD/m2ZmzwAA + AAAAAAAA1ZycluHExP/hx8f/zaio/4ZSUtZ7SEhBAAAAAAAAAACqcnI/omxsodK0tP/mzc3/8+Xl/6V6 + ev6GTU2fnGZmisWbm/TlzMz/4cfH/8qlpf+HU1Pxgk1NMQAAAAAAAAAAAAAAALh/f5Tcv7//6tbW/+zZ + 2f/x4uL/2ru7/+bIyP/r19f/5MrK/+LGxv/nysr/wZeX/4JPT2wAAAAAAAAAAAAAAADRpqby/fv7//fx + 8f/p09P/5s7O/+/e3v/s2dn/5MrK/+PGxv/BnZ3/vpiY/6V3d/aLWVkbAAAAAAAAAAAAAAAA0JSUgs6m + pvLEi4u5z6mp9fLm5v/o0ND/5s7O/+nU1P/cwcH/mWNjkJ5iYjOiY2M5AAAAAAAAAAAAAAAAAAAAAAAA + AADml5cEAAAAAMuQkK379vb/yKGh8rN8fLDMqKj+4MfH/6ZtbZEAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAADRmZl+yqCg88OLi2wAAAAAs3t7dKZwcJqgb28WAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAD//wAA/H8AAPRHAADgBwAAwAcAAOABAACAAQAAgAEAAIGDAADAAwAAwAEAAMADAADADwAA+A8AAPif + AAD//wAAKAAAABgAAAAwAAAAAQAIAAAAAACgAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8Ao3BwANi1 + tQByQ0MA7NraAL+SkgCDX18AnImJANWhoQDiyMgA9u3tALJ/fwCyn58AgU5OAJJ5eQDru7sAlWVlAKmS + kgDEnp4Az6ysALSKigDgrKwA8uPjAOfR0QDevr4AildXAKt4eADns7MAnnl5AIpoaADJlpYAk21tALSU + lAB2SkoAmH9/AKKDgwCqi4sAu5ycAI9gYADIp6cA+fPzAPHV1QDWp6cA47m5AKqBgQDNn58AnGhoAJtv + bwDUsLAAeU9PALmOjgDy3d0A4MPDAN6xsQDAl5cA3Lm5ALqIiADNpKQAuZeXAPPp6QDq1dUAh2RkAOXM + zACgbGwAtYODAHxLSwDbq6sAlWBgAO7g4ACXd3cAx6OjAKN0dADOqKgAhFFRAIphYQDjwMAAjWtrAOa8 + vADZvb0A1bi4AKh1dQCjeHgA0bOzAJ+GhgCnjo4AmWxsANikpACyh4cAspGRAPfw8ACxfHwAyJmZANGv + rwC0jY0Aw5OTAMCamgDkz88AjWZmAOXGxgDjrq4ArX9/AMuqqgC8kJAA7t3dAHdNTQDq2NgAjFlZAIhf + XwDat7cAnHd3ANqzswCce3sAqXp6ALCdnQC0nZ0Af0xMAOfOzgDixcUA3Ly8AN+6ugDUtLQAyqCgALib + mwD26ekA8ufnAIBQUADp09MAhmJiAOrR0QCJZmYA5MrKAJtmZgCZaGgAlGtrAN/BwQDivr4AonJyAKZ4 + eADPqqoA1KOjAMunpwC1iIgAq42NALiMjADFnJwA8uXlAPLh4QCVY2MAqn9/ANqpqQB4S0sA7NzcAN7E + xADgv78AtIaGAM2mpgCnkZEAqY+PALaLiwCCUFAA8OHhAItmZgDiysoA5bm5ANa1tQDNqqoAt46OALuO + jgC+kJAA9+7uAPXs7AB+S0sA9OrqAPHk5ADv398A7d7eAO3b2wDr2dkAlF9fAOvW1gDo1NQA6NLSAOjQ + 0ACVbGwA5s3NAOPJyQDhx8cA48bGAJZ4eADhxMQA3729ANu4uADZtrYA2bS0ANCrqwC/mZkA8ODgAOrX + 1wDq1NQAoG1tAOTLywDhxsYAmH5+AODCwgDfwMAA3r+/AOC+vgCfhYUAooSEANy7uwDcuroAuY2NANCu + rgDOqakAe0tLAH9LSwDz6uoA9OnpAIlXVwDz5+cAi1lZAO/h4QCJYWEA7+DgAO7e3gDv3d0A7dzcAO3a + 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 + rAClgoIAsIKCALuVlQC4jIwA1Li4AMSfnwCrhIQAgE1NAOfQ0ADdxsYA37y8AJlmZgDasrIAn2xsAJNz + cwDQr68A0qmpAKR3dwCnenoAyqenAJ5+fgCxm5sAg1dXAOS3twDEkZEAeUZGAKGLiwDx5eUAhVNTAIZa + WgDhwMAAhWVlANi7uwCgcnIAs56eAOrX1wB9V1cA5MrKANm1tQCVgIAAqn19AMCOjgDv29sAkl9fAJJi + YgCNbGwAj3JyANSxsQCYfHwAwJSUAItnZwCSZ2cAnW5uAJp4eADMpKQAqXh4AKOSkgC4mJgApHJyAObS + 0gDhxMQAjVtbAOK5uQCbaGgA2KWlANajowCgfHwAzJ6eALSBgQC6iIgAsJOTAOrT0wDcwcEA3Lu7AIxx + cQCda2sA17OzANOtrQDIpqYAt5ycALySkgC0jY0A9OvrAPDj4wDt3d0AgFBQAIdVVQDmzs4AiVpaAOXI + yADhyckA3r+/AJhpaQDgtbUA17m5AJ9vbwDXsLAA2ampAM6qqgCahYUA0aGhAK19fQCgjY0AsYSEAMCZ + mQC6j48Aqnt7AMihoQCrlpYAuZKSAOnV1QDo0tIA5czMAN29vQCcbGwAnXBwANKwsACnd3cAl4GBANCo + qACtgYEAvouLALWMjAC+j48Ae0pKAODIyACUYmIA2ru7ANe1tQCpmJgA9u7uAPLn5wDv4OAAfktLAOzc + 3ADr2NgAiVZWAIlYWADn0dEAiFlZAIRfXwDjyckAhmNjAOLGxgDhw8MAl2RkAO26ugDfwMAAjmtrAOW4 + uADZvLwA3Lq6AJtvbwChbm4A2re3AKBwcADZtrYAo3FxANm0tADYsrIApXNzANOysgCVfn4AqHV1AJiE + hACtenoAz6urAKx8fACqf38Ay6amALGBgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAANNyB0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC/6oBD5AAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAD5jJnuJnkAAAAACQRTAAAAAAAAAAAAAAAAAB/jAAAAAIN+zIvwbgAAAJ9xzi9D + AAAAAAAAAAAAAAC4B6AvhwAAa7k676WS0eEtlBIIM1wAAAAAAAAAAAAAAFCEjPLmcdMjbOw6ofL6+Jrn + 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 + t//curr/27m5/9azs/+jcXH/rXp6/6h1df+6iIj/7bq6/+W4uP/Wrq7/wJOT/4NRUf9uOTlMAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAg1BQn8KkpP/jyMj/0rCw/7CCgv+kcXH/vIqK/9qn + p//lsrL/5Lu7/929vf/cvLz/3Lq6/7qOjv+ndHT/sX5+/9ilpf/gtbX/2LKy/9ewsP/Vrq7/glFR/nA9 + PTIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACGUlLn1rm5/+HFxf/hxcX/4cTE/86q + qv/Mnp7/4rm5/+G/v//fwMD/3r+//96+vv/dvb3/3Lu7/9e1tf/MpKT/17Cw/9m1tf/ZtLT/2LKy/7eM + jP90QUG6AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIpWVoGrgID/4sjI/+LH + x//ix8f/4sbG/+HFxf/hxMT/4MTE/+HGxv/iyMj/48rK/+PKyv/ix8f/38HB/9y6uv/bubn/2re3/9m2 + tv/ZtLT/mmtr/3dDQ48AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfz8/CI5b + W9fNrKz/48rK/+PJyf/jycn/4sjI/+HGxv/iyMj/4sfH/+HExP/gw8P/38LC/+DExP/jycn/5c3N/9/B + wf/bubn/2re3/9i0tP+lc3P/fktL/HZFRYV2QkJwcz8/aHI8PEwAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACZZmYKkFxcbJ1ubv/jycn/5MzM/+PKyv/gxMT/4sjI/+PIyP/ix8f/4cbG/+HExP/gw8P/38LC/9/A + wP/ev7//48rK/+LHx//bubn/17Oz/6Rycv+ib2//rXp6/616ev+tenr/gU5O/m4+PiUAAAAAAAAAAH9f + XwiSX1+rk2Bg3pViYvqZZmb/oHBw/+XOzv/lzc3/38LC/+TLy//kzMz/5MrK/+PJyf/iyMj/4sfH/+HF + xf/gxMT/4MLC/9/AwP/ev7//4sjI/+HGxv/bubn/yKGh/7F+fv/Wo6P/4a6u/+m3t/+WY2P/dD8/cAAA + AAAAAAAAk2JiU6x5ef/UoaH/x5SU/7SBgf/Enp7/59HR/+HFxf/kysr/5s/P/+XOzv/lzc3/5MvL/9y8 + vP/WsLD/2rKy/9+7u//hw8P/4MLC/9/AwP/ev7//48rK/96/v//bubn/062t/9iysv/YsrL/z6am/59s + bP92QkK8AAAAAAAAAACWY2Ow0qmp/+XBwf/evLz/2ru7/+TNzf/o09P/3sDA/+jS0v/n0dH/59DQ/+TM + zP/Al5f/uIWFzcWRkXfMmZlq16Ojot6trfnhwMD/4MLC/9/AwP/fwMD/48nJ/9y6uv/buLj/2ra2/9m0 + tP/YsrL/p3Z2/3lFRbUAAAAAAAAAAJpmZt3jzc3/69jY/+rY2P/q19f/6tfX/+XNzf/ix8f/6dXV/+jU + 1P/o0tL/v5mZ/6Jvb6B/f38CAAAAAAAAAAAAAAAA16SkQdyrq/vgw8P/4MLC/9/AwP/jycn/3b29/9y6 + uv/buLj/2ra2/9awsP+fcHD/eUZGbQAAAAAAAAAAnGlp6OfU1P/s2tr/7Nra/+za2v/r2dn/4sjI/+XO + zv/q19f/6tbW/+nV1f+ba2v/lWBgHQAAAAAAAAAAAAAAAAAAAAAAAAAA05+ftt+8vP/gxMT/38LC/+HF + xf/fwcH/3Lu7/9i2tv+1i4v/ilhY+3xJSaR4PDwRAAAAAAAAAACfbGzw1Li4/+vZ2f/t3d3/7dzc/+3c + 3P/iyMj/5tDQ/+vZ2f/r2Nj/5tHR/4lWVv+HUlIiAAAAAAAAAAAAAAAAAAAAAAAAAADHk5O83bu7/+HF + xf/gw8P/4cTE/+DCwv/dvb3/mGlp/4NQULh8Tk4nAAAAAAAAAAAAAAAAAAAAAKJtbU2icHCxqHd397+Z + mf/dxsb/7t7e/+XOzv/ky8v/7Nzc/+za2v/o1dX/jVtb/4BNTa5/Pz8IAAAAAAAAAAAAAAAAr319U8GS + kv3ix8f/4sfH/+HExP/hxMT/38LC/96+vv+cbGz/h1RU7INQUEYAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACfb28QpnNzX659fffs3Nz/7Nvb/929vf/u3t7/7dzc/+zb2/+7lZX/jVpa/4FNTdyHVFSLkl5efJtp + aba1h4f94cbG/+TKyv/iyMj/4cbG/+DExP/fwsL/3r+//6Bubv+baGj/iFVV+4ROTksAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACqdHQYq3h44+HJyf/w4uL/3b29/+vZ2f/u39//7d3d/+rY2P/DnJz/t4SE/7aD + g//EkZH/37Oz//HX1//lzs7/5MvL/+PJyf/ix8f/38LC/+DCwv/fwMD/z6ur/619ff+ZZmb/g1BQjwAA + AAAAAAAAAAAAAAAAAAAAAAAAqnh4JK57e93SqKj/79vb//Hl5f/s29v/27q6/+/g4P/u39//7d3d/+zb + 2//mz8//5cjI/+zPz//q09P/59HR/+bPz//lzc3/5MrK/9/Cwv/gxMT/4MPD/9/Bwf/ev7//27q6/7GE + hP+EUlKtAAAAAAAAAAAAAAAAAAAAAAAAAACue3uP1LS0//Pi4v/z6Oj/8ufn//Lm5v/mz8//3r6+/+/g + 4P/u39//7d3d/+zb2//r2dn/6tfX/+nU1P/o0tL/59DQ/+XOzv/hxMT/38HB/+LHx//hxMT/4MLC/97A + wP/dvb3/oHJy/4dTU1wAAAAAAAAAAAAAAAAAAAAAAAAAALJ+frPl0tL/9Ovr//Tq6v/z6en/8+jo//Lm + 5v/n0ND/27i4/+rX1//u3t7/7dzc/+za2v/r2Nj/6dbW/+jT0//mz8//3sDA/9/Bwf/jysr/2Lu7/8il + pf/TsrL/3L29/8umpv+KV1fUVVVVAwAAAAAAAAAAAAAAAAAAAAAAAAAAs4GBlNCvr//27u7/9e3t//Tr + 6//r2tr/8OPj//Lm5v/t3d3/3r+//9u4uP/hxcX/5czM/+XNzf/ix8f/3b29/9y7u//jycn/5c3N/8Sf + n/+da2vpl2RkopRhYcmTYGDyk2Bg/Y1ZWVMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC/f38IuISEyte5 + uf/Us7P/wpWV/bqHh9TAkJD42r6+//Dj4//w4+P/7t/f/+fR0f/jyMj/4sbG/+TKyv/n0dH/6NPT/+fQ + 0P/mzs7/qnt7/5tnZzYAAAAAAAAAAKpVVQOQWFgXAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAC2iIgcu4eHnL2IiGW8jY0bAAAAALuHhyK9iYnK4MjI//Hk5P/w4uL/7+Dg/+3d3f/s29v/6dXV/+rW + 1v/o1NT/59HR/+bPz/+peHj/nGhoTgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL+Kipzgx8f/8eXl//Dj4//n09P/vpGR/7OC + gvqtenrvxJ6e/+nU1P/n0tL/5s/P/7KGhv+da2twAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwI6OnOHIyP/y5ub/8OPj/8ad + nf62gIBptm1tB6pxcQmreHjDyqen/+jS0v/ZvLz/qXt7/p1qam4AAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADDkJCa1LCw/+bS + 0v/cwcH/uISEwv8AAAEAAAAAAAAAAKFraxOqd3fWuo+P/6Rxcd6hbGxSAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL+N + jSTBjY2FvoqKvbuIiOG3goIrAAAAAAAAAAAAAAAAAAAAAKp3dx6nc3NmjXFxCQAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////+H////g////wPH/88Dg/+DAAP/gA + AD/wAAA/8AAAP/AAAD/4AAAH+AAAA8AAAAGAAAABgAAAAYAD4AGAB+ADgAfgD8ADwA/wAAAH+AAAA/AA + AAPgAAAD4AAAB+AAAAfwAAH/+cAB///AAP//wMD//8Hh///j9///////KAAAADAAAABgAAAAAQAIAAAA + AACACgAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8Aom9vAN6zswBvPT0Aq5iYAOva2gCJV1cAzZycAJeF + hQC4hIQA4sfHAPXt7QCJa2sAuaWlAL+RkQB9SkoAzK6uAPG/vwCreXkAl2NjAJJ3dwD3ysoApoWFANnA + wADZp6cAnXx8ALqbmwDz4eEArY2NAIhiYgCdjY0AfFRUAMijowDUtbUAvIqKAOO7uwDEnJwAj1xcAJR9 + fQCmkpIAqYGBAJlsbACRcHAA06KiAIFbWwDIlpYAg1BQAK6engDWra0A6NTUAKd0dAC1lpYA5M3NAObB + wQB1SEgAm3R0ANGlpQDbubkA6re3AI9lZQD16OgA+tbWAN+trQC+oaEArY+PAKWVlQB3T08Am4ODAMCY + mACyfn4A79/fAIleXgDfwsIA5bKyAJ+IiADDp6cAt5GRAJR5eQCyh4cAjmBgAI5paQCUamoAjG9vANys + rACigoIAsIKCALyVlQC5i4sA07m5AMSfnwCshYUAgE1NAOfQ0ADdxcUA4Ly8AJlmZgDbsrIAoGtrAJd1 + dQDPsLAA06mpAJ92dgCoenoAyKioAJ5+fgC0mZkAg1hYAOW3twDEkJAAd0REAKaMjADx5eUAhFNTAIZa + WgDhv78AhWVlANm6ugCfdHQAs56eAOrX1wB9V1cA5MrKANq1tQCVgIAAqn19AMGNjQDu2toAk19fAJNh + YQCMa2sAj3JyANWwsACYfHwAwZWVAItnZwCSZ2cAnW5uAJx3dwDLo6MAq3h4AKSSkgC4mJgApXJyAOfS + 0gDhxMQAjVtbAOK5uQCcaWkA2KWlANajowChfHwAzJ+fALWBgQC6h4cAs5SUAOvT0wDcwsIA3Ly8AIxx + cQCeamoA2LOzANSsrADFqakAtZycALySkgC0jo4A9evrAPDj4wDt3d0Af1BQAIVVVQDmzs4AiVpaAOzH + xwDiysoA3r+/AJhpaQDgtbUA17m5AJ5vbwDXsLAA2qmpAMypqQCaiYkA0aGhAK98fACgjo4As4SEAMGZ + mQC7jo4Aq3t7AMqgoACslJQAtpOTAOnV1QDo0tIA5czMAN29vQCbbW0AnXBwANKwsACnd3cAl4GBANCo + qACtgYEAv4uLALWMjAC+kJAAekpKAODIyACVYWEA2ru7ANe2tgCpmJgA+fDwAPLn5wDv4OAAfkxMAO3c + 3ADs2NgAiVZWAIlYWADn0dEAiVlZAIRfXwDkyckAh2NjAOLGxgDhw8MAlmVlAOy6ugDfwMAAjmtrAOa4 + uADZvb0A3bq6AJtvbwChbm4A27e3AKFwcADZtrYAo3FxANm0tADYsrIApnJyANCysgCVfn4AqXZ2AJiE + hACte3sAz6urAKx8fACpf38Ay6amALGBgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + 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 + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB3Pj6sajc3+Wo3N+JqNzfIbDk5qng6 + OioAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIJHR0p2Q0P+t4WF/6Nw + cP+XZGT/fktL/3U+PqsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHlB + QaqzhIT/wY2N/6t4eP+kcXH/mWZm/3A7O/iEQEAbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAG02 + NhB3OzsZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAHhBQdjRpKT/vouL/6RwcP+caWn/m2ho/3xJSf96Q0N9AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAdz4+M2g0NOFpNTX1dDw8bAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJBLSx+ETU1RdDg4BQAA + AAAAAAAAAAAAAAAAAAAAAAAAfjw8DnE8PPjsvLz/y56e/76Rkf+7jo7/nGlp/45bW/90Pz/glUlJBAAA + AAAAAAAAAAAAAAAAAAB8Q0NYZTIy9LmGhv+odnb/cDw8/m83N7N9Pj4YAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjlJSMXpG + RuV/TU3/fEhI0oxUVEkAAAAAAAAAAAAAAAAAAAAAgU9PNXZERP76yMj/27m5/925uf/fvr7/tIiI/5ll + Zf94RUX/dkVFWlsAAAMAAAAAXgAAA3lFRYVtOTn90Jyc///W1v+pdnb/r3x8/4FOTv9yOjrZAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACOU1NBeEND76t8fP+0gYH/lWFh/39NTf6HTk64kFFRLwAAAACSUVEuekZGooxbW//0w8P/2rm5/9u4 + uP/bubn/1rGx/5VgYP+OW1v/dUJC/nZDQ+t6RES8c0BAv3pISP7ls7P//MjI//vIyP+fa2v/p3R0/6h1 + df9wODj2AAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAJNYWDJ9R0f2vZWV/+K8vP+kcHD/pHFx/6d0dP+RX1//gExM+4BMTN98SUn+lWVl/9Gh + of/pu7v/3Lq6/9u5uf/burr/37+//6h5ef+mcnL/t4SE/616ev+hbm7/onFx//C9vf/0wMD/8b+//9uy + sv/Sqqr/rXt7/6Btbf9uNDT4nqOjAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAIlOTpenf3//7dfX/+HFxf+ib2//nWho/6NwcP+ndHT/pHJy/7mJ + if/Xp6f/5LGx/+u3t//jurr/3L29/9y7u//curr/3bu7/8ujo/+famr/q3d3/7F+fv+5hob/2aen/++8 + vP/qubn/2bKy/9ewsP/Xr6//2rS0/7mMjP9xOjr1AAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAk0ZGCH5JSerbxcX/69fX/+LFxf/kyMj/wpyc/59r + a/+ibm7/pXFx/92rq//dqan/5LCw/+64uP/hvLz/3b29/929vf/cvLz/3Ly8/9/AwP+icXH/nWpq/6h1 + df+xfX3/2aen/+W3t//Ys7P/2LKy/9exsf/YsLD/3La2/6p9ff94Pz/FAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkVpaTY1bW//z4OD/4cXF/+HF + xf/ixcX/5MjI/+HFxf+9k5P/om1t/+axsf/ks7P/5Ly8/+DBwf/ewcH/3r+//96+vv/dvb3/3by8/928 + vP/hwMD/2La2/8ienv+7jIz/2ays/9q2tv/ZtLT/2LOz/9iysv/YsrL/27W1/3ZCQv6CR0dIAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAnF5eNYdS + UvvbvLz/5MrK/+LGxv/ixsb/4cfH/+LGxv/lysr/3L6+/+TCwv/gxcX/4MTE/+DCwv/fwcH/38DA/97A + wP/evr7/3r29/928vP/dvLz/3by8/969vf/dvLz/3Lq6/9q4uP/atrb/2bW1/9izs//ct7f/q39//3ZA + QMcAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAJJZWZacbGz/6tLS/+TJyf/iyMj/4sfH/+LHx//ixsb/48fH/+HFxf/hxcX/4cTE/+HF + xf/iycn/5M3N/+fPz//m0dH/5tLS/+fR0f/kzMz/4MPD/927u//cubn/27m5/9u4uP/at7f/2ra2/9m2 + tv/eubn/lWFh/3dCQt+APj4SAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAJ1paRGJU1PlxqKi/+fQ0P/jycn/48nJ/+PJyf/jyMj/4sjI/+LH + x//hxsb/4snJ/+LKyv/ix8f/4cbG/+DExP/gwcH/4MHB/+DExP/ix8f/5tHR/+nV1f/jyMj/3Lu7/9u5 + uf/buLj/2re3/9u3t//Vr6//pnJy/4VSUv96Rkaqb0VFDI4tLQaVAAACAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACXXl5Xj1tb/ufOzv/lzc3/5MvL/+TK + yv/jy8v/48rK/+HFxf/hxsb/4sfH/+LGxv/hxsb/4cXF/+HExP/gw8P/4MLC/9/Bwf/fwMD/3r6+/9/B + wf/lzs7/6NTU/96/v//burr/27i4/9y5uf/FnJz/oW1t/6NwcP93RET+bz09+249PfhtPj70cz4+7Xk/ + P+OMTExHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI9CQgSPYmIbjlhY066F + hf/p09P/5czM/+TNzf/jy8v/38LC/+HGxv/jysr/48nJ/+PIyP/ix8f/4sbG/+HFxf/hxcX/4MTE/+DD + w//fwsL/38DA/96/v//evb3/4cTE/+nX1//gw8P/27q6/925uf/Rqqr/m2ho/6Ftbf/FlJT/3qys/96q + qv/frKz/5rOz/6NwcP92Pz+rAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAApWhoFJ5mZnmeZGSinGVlyZJh + YeyTYGD9k2Bg/7KIiP/q1NT/587O/+bPz//dv7//4sfH/+TNzf/ky8v/5MrK/+PKyv/jycn/4sjI/+LH + x//ixsb/4cXF/+HExP/gw8P/4MLC/9/Bwf/ewMD/3r6+/9/AwP/p1tb/38HB/9u6uv/fvLz/wpiY/5di + Yv/KmJj/2qam/+Ctrf/qtrb/+8fH/6x5ef9yPj7vejs7CQAAAAAAAAAAAAAAAAAAAAAAAAAAnWVlmKFw + cP+3hYX/u4mJ/7qIiP+xf3//n2pq/8inp//q1NT/59LS/+DCwv/gw8P/58/P/+XNzf/lzc3/5MzM/+TL + y//kysr/5MrK/+TKyv/jysr/48nJ/+LHx//hxcX/4MPD/+DCwv/fwcH/3sDA/96+vv/gw8P/6NTU/928 + vP/bubn/376+/7CCgv/Pn5//1aen/9utrf/fs7P/3bGx/6Rxcf99Skr/cD8/SAAAAAAAAAAAAAAAAAAA + AACmb28Kklxc7d+trf/lsLD/0p6e/8SQkP+2gYH/qHJy/+nT0//o1NT/5s/P/9u5uf/n0dH/5tHR/+bP + z//mzs7/5c3N/+bOzv/n0ND/4sfH/9WwsP/Uqan/16ys/9yzs//hvb3/4sbG/+DExP/gwsL/38HB/97A + wP/evb3/4snJ/+TMzP/cubn/3Lq6/9y6uv/cubn/2be3/9m1tf/Ys7P/0amp/55qav+OW1v/c0BAkQAA + AAAAAAAAAAAAAAAAAACVYGBYoG5u//rIyP/muLj/3bKy/9ewsP/UsLD/2bq6/+zY2P/p1dX/3r+//+LH + x//o09P/59HR/+fQ0P/m0ND/59DQ/+rV1f/KpKT/t4KC+82Tk7jcoaF64Kioa+Wvr4/eqqrd4LCw/uLC + wv/gxMT/4MLC/9/Bwf/ewMD/3r6+/+fS0v/ev7//3Lq6/9u5uf/at7f/2ra2/9m1tf/Ys7P/27i4/6t6 + ev+NWlr/dUBAfwAAAAAAAAAAAAAAAAAAAACXYmKgwJ2d/+7e3v/q2tr/69ra/+zZ2f/s2dn/7NnZ/+nX + 1//r19f/2LGx/+jV1f/o09P/6NPT/+jS0v/n0dH/7NfX/7+Zmf+oc3PazJGRMgAAAAAAAAAAAAAAAAAA + AAD3jY0G7Lm5feKurv3iwsL/4MTE/+DCwv/fwcH/3r+//+LIyP/jyMj/3Lu7/9y6uv/buLj/2re3/9m2 + tv/ZtLT/27a2/8yiov+BTU3/eUREOwAAAAAAAAAAAAAAAAAAAACVYGCuyKio/+7d3f/r2Nj/69jY/+vY + 2P/r2Nj/6tjY/+rY2P/n0ND/2bW1/+vZ2f/p1dX/6dTU/+jU1P/q1tb/3cTE/5hhYfS4eXkmAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAO22to3fsLD/4sbG/+DDw//fwsL/38DA/9/Bwf/lz8//3bu7/9y7 + u//bubn/27i4/9u4uP/dubn/4b6+/7SJif97RkbudE5OBwAAAAAAAAAAAAAAAAAAAACYY2O4zK6u/+/e + 3v/s2tr/7Nra/+za2v/r2tr/69nZ/+za2v/ky8v/3Lu7/+va2v/q19f/6tbW/+nV1f/u2tr/uZWV/5ti + YqQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOKurhXWo6P64cXF/+LExP/gw8P/38HB/9+/ + v//lzs7/3r6+/928vP/du7v/3r29/+K/v/+7kpL/hlRU/nxGRtqLUlJRAAAAAAAAAAAAAAAAAAAAAAAA + AACYZWXD07m5//Pk5P/u3d3/7dzc/+zc3P/s29v/7Nvb/+3d3f/jycn/3b6+/+zc3P/r2Nj/6tfX/+rX + 1//x4OD/mGlp/5ZeXogAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANCGhgTOm5vu4MHB/+HG + xv/gxMT/4MLC/9/Bwf/jy8v/38HB/929vf/gwMD/vJWV/4lZWf9+S0vailRUYHM3NwUAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACfa2vCtImJ/9nAwP/x5OT/8uTk/+/g4P/u3t7/7d3d/+7d3f/kzMz/3bu7/+3d + 3f/s2tr/69nZ/+zY2P/w4OD/ilRU/41UVLsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAM+c + nCnFkZH948nJ/+PGxv/hxcX/4MPD/+DCwv/jyMj/38HB/92/v//evr7/e0ZG/4NRUamGJCQGAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACteXklrHd3h5pwcN2gcHD+vpeX/9vDw//y5eX/8ODg/+/f + 3//p09P/2LGx/+/g4P/s29v/7Nra/+vb2//x4+P/mWZm/39JSf2UVlZRAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA3pKSBLiEhLjMoaH/5c3N/+LHx//hxsb/4cTE/+DDw//hx8f/38HB/9+/v//dvLz/jltb/4ZV + VfyIWlqCkQAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAGtf381sXd3i6Zu + bt+seXn+8+fn/+/i4v/v4OD/0aWl/+7g4P/t3t7/7dzc/+zb2//x4eH/uJGR/45ZWf96SEj3iVNTd6Fb + Ww0AAAAAAAAAAAAAAAC5fX0sqXFxuruNjf/n0dH/48vL/+PIyP/ix8f/4cXF/+DExP/ixsb/38HB/9/A + wP/UsLD/lmFh/5xpaf+JV1f/hFVVrqFcXA0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAJdzcwemb2/g28TE//Hk5P/x5eX/2bOz/+bNzf/v4OD/7d3d/+3c3P/t3d3/6tjY/55q + av+gbGz/hVJS/35LS/KNVVXClV1dtJhiYtWYY2P9x52d//vr6//lzMz/5MvL/+PJyf/iyMj/4sbG/+HE + xP/gw8P/38LC/+HCwv/Rra3/lV9f/6Btbf+lcnL/jVtb/49XV48AAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAALmMjAaocnLAxZ2d//Pp6f/x5OT/6NHR/9Wrq//w5eX/7uDg/+7e + 3v/t3t7/7+Dg/+LMzP+xfn7/v4qK/8OPj/++i4v/xpKS/9+trf//2tr//+fn/+fQ0P/lzc3/5MvL/+PK + yv/jyMj/48jI/+DDw//gw8P/4MLC/9/Cwv/hw8P/0K2t/6d0dP+mcnL/m2ho/45WVrwAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAuXp6Dq54eLi1goL+57+///Po6P/y5eX/8unp/9as + rP/kysr/8ePj/+7f3//u3t7/7d3d/+7f3//u3t7/17a2/9arq//ks7P/88XF//rS0v/w1tb/5tHR/+bP + z//lzs7/5czM/+TLy//jycn/4cfH/96/v//ixMT/4MPD/9/Bwf/gwMD/4MHB/+DBwf++kpL/om5u/4xV + Vd8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADGlZUMrnp6y72Rkf/x0dH/79PT//Po + 6P/x5eX/8ufn/+3d3f/QoaH/7Nvb//Di4v/u39//7t7e/+3d3f/t3d3/7t3d/+3d3f/r2tr/6tjY/+nW + 1v/o09P/59LS/+fQ0P/mz8//5c3N/+TNzf/kzMz/3b6+/+DDw//hxcX/4MTE/+DCwv/fwcH/3r+//96+ + vv/jxMT/wJiY/4ZVVeKcAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC+hoZItYSE//zt + 7f/14uL/9Orq//Pp6f/y5+f/8ubm//Lo6P/nz8//0aKi/+7d3f/w5OT/7t/f/+7e3v/t3d3/7Nvb/+za + 2v/r2Nj/6tfX/+nV1f/p1NT/6NPT/+fR0f/mz8//5c/P/+XOzv/evr7/3sDA/+PJyf/jxsb/4cTE/+DD + w//fwcH/3sDA/9+/v//kxsb/l2Vl/49ZWXQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AADAhoZuxJyc//329v/06+v/9Ovr//Pp6f/z6Oj/8+fn//Lm5v/z6en/5czM/86fn//o1NT/8eXl/+/g + 4P/v3t7/7dzc/+zb2//r2dn/69jY/+rW1v/p1dX/6NPT/+fT0//o0dH/58/P/927u//dvb3/5MvL/+TJ + yf/ly8v/5cvL/+PHx//hxcX/4MHB/+HCwv/JpKT/hk9P6JJjYwwAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAADEiIiU0LCw//r19f/17Oz/9evr//Tr6//06ur/8+np//Po6P/y6Oj/9Ojo/+rZ + 2f/QoqL/2re3/+za2v/w5eX/7uDg/+7e3v/t29v/69ra/+vY2P/q2Nj/69bW/+nU1P/hxcX/2LOz/9+/ + v//mz8//587O/+bNzf+8lJT/tIqK/8Kdnf/QsLD/38HB/+rMzP+YaGj/lVxcdAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADPkpJauIWF/vTq6v/48fH/9e3t//bu7v/27+//+PHx//fx + 8f/27e3/8+np//Ln5//y5+f/4cTE/8+goP/Wra3/4MLC/+fQ0P/q19f/69fX/+fS0v/iyMj/3Lu7/9at + rf/bt7f/5czM/+fQ0P/o0dH/0LCw/51sbP6ZZ2fBoWlplJxlZb6RYWHni1hY/ZJgYP+MWVnokmJiDAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAxIqKlL+Rkf/89/f//Pn5//Tq + 6v/excX/yqGh/7qHh//Wtrb/9ezs//Xq6v/y5+f/8ebm//Lm5v/o0dH/3by8/9avr//UqKj/06en/9Wt + rf/btrb/4MPD/+fS0v/q1dX/6NHR/+bQ0P/r1dX/pHFx/55tbYSMAAACAAAAAAAAAACSAAACmGJiGJ1k + ZECpaGglAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAxJOTBrqE + hMHIn5//xJiY/7yDg/rJj4/EzpSUetCVlU7Hjo7Av4qK/t3Bwf/16ur/8eTk//Hk5P/w4+P/7+Pj//Di + 4v/v4OD/7t/f/+3d3f/r2tr/69jY/+nV1f/o1NT/59HR/+bQ0P/nzs7/oGpq/6p0dHEAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAANGTkxjOlpaL0JaWWc6SkhQAAAAAAAAAAAAAAAAAAAAAyZOTV7V+fv706+v/8eXl//Dj + 4//w4uL/8ODg/+/h4f/v4eH/7+Dg/+/g4P/v3t7/7NnZ/+nW1v/o09P/59HR/+bR0f/n0ND/nWlp/6xy + cpMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1ZCQGbqF + hf317Oz/8+fn//Hk5P/w4uL/8OPj/+vb2//UtbX/zKmp/8ScnP+7jo7/3cPD/+zZ2f/o09P/59LS/+jQ + 0P/r1tb/pXJy/6x0dLUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA1Z2dGbyFhf306+v/8ubm//Hl5f/w5OT/9enp/76QkP+zfX3HvYODmMGFhXu5f3+KrXd3/uTN + zf/q19f/6dLS/+fQ0P/t2Nj/sYaG/6xzc9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA1ZycGb2IiP307e3/8ujo//Hl5f/z5+f/2b29/7WAgNvMkZEKAAAAAAAA + AAAAAAAAuoaGhq58fP7p09P/69bW/+zX1//fxMT/p3d3/693d8YAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1JycGb+Kiv358vL/9e3t//Tq6v/x5OT/u4aG/dGW + lksAAAAAAAAAAAAAAAAAAAAAjQAAAq19faOxgoL/59LS/72Vlf+hamr1rHNzgbV4eAoAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA6qqqDsSQkO3GmZn/0q2t/9/G + xv/LpKT/xo6OrQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANR+fgepd3e8p3Jy/q93d7G6fn4jAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANKO + jhXAjIxOvYiIh7qHh8C7hYXXxY+PHwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC4cXEMs3x8MQAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////AAD///////8AAP//8H///wAA///wP/// + AAD//+A///8AAP//4B/H/wAA/+/gHwP/AAD/x+AOAf8AAP+BwAAB/wAA/wAAAAH/AAD+AAAAAf8AAP4A + AAAB/wAA/gAAAAP/AAD+AAAAA/8AAP4AAAAD/wAA/wAAAAH/AAD/AAAAAA8AAP+AAAAABwAA8AAAAAAH + AADgAAAAAAcAAOAAAAAAAwAAwAAAAAADAADAAAfgAAcAAMAAD/AABwAAwAAP+AAHAADAAA/4AB8AAMAA + D/gAfwAA4AAH8AA/AAD8AAPgAB8AAP8AAAAADwAA/wAAAAAPAAD+AAAAAA8AAPwAAAAADwAA/AAAAAAP + AAD4AAAAAB8AAPgAAAAAHwAA+AAAAAA/AAD8AAAAH/8AAP4EAAAf/wAA/z4AAB//AAD//wAAH/8AAP// + AAAf/wAA//8B4B//AAD//wPwP/8AAP//A/j//wAA///H////AAD///////8AAP///////wAA + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/CommonObjects/Utils.cs b/Demo_Source_Code/CSharpDemo/CommonObjects/Utils.cs new file mode 100644 index 0000000..056b7ed --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/CommonObjects/Utils.cs @@ -0,0 +1,330 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Globalization; +using System.Security.Cryptography; +using System.Windows.Forms; +using System.Reflection; +using System.IO; +using System.Text.RegularExpressions; +using System.Configuration; + +namespace EaseFilter.CommonObjects +{ + + public class Utils + { + public static uint WinMajorVersion() + { + dynamic major; + // The 'CurrentMajorVersionNumber' string value in the CurrentVersion key is new for Windows 10, + // and will most likely (hopefully) be there for some time before MS decides to change this - again... + if (TryGeRegistryKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion", "CurrentMajorVersionNumber", out major)) + { + return (uint)major; + } + + // When the 'CurrentMajorVersionNumber' value is not present we fallback to reading the previous key used for this: 'CurrentVersion' + dynamic version; + if (!TryGeRegistryKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion", "CurrentVersion", out version)) + return 0; + + var versionParts = ((string)version).Split('.'); + if (versionParts.Length != 2) return 0; + + uint majorAsUInt; + return uint.TryParse(versionParts[0], out majorAsUInt) ? majorAsUInt : 0; + } + + /// + /// Returns the Windows minor version number for this computer. + /// + public static uint WinMinorVersion() + { + dynamic minor; + // The 'CurrentMinorVersionNumber' string value in the CurrentVersion key is new for Windows 10, + // and will most likely (hopefully) be there for some time before MS decides to change this - again... + if (TryGeRegistryKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion", "CurrentMinorVersionNumber", + out minor)) + { + return (uint)minor; + } + + // When the 'CurrentMinorVersionNumber' value is not present we fallback to reading the previous key used for this: 'CurrentVersion' + dynamic version; + if (!TryGeRegistryKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion", "CurrentVersion", out version)) + return 0; + + var versionParts = ((string)version).Split('.'); + if (versionParts.Length != 2) return 0; + uint minorAsUInt; + return uint.TryParse(versionParts[1], out minorAsUInt) ? minorAsUInt : 0; + } + + + private static bool TryGeRegistryKey(string path, string key, out dynamic value) + { + value = null; + try + { + var rk = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(path); + if (rk == null) return false; + value = rk.GetValue(key); + return value != null; + } + catch + { + return false; + } + } + + public static void CopyOSPlatformDependentFiles() + { + Assembly assembly = System.Reflection.Assembly.GetEntryAssembly(); + string localPath = Path.GetDirectoryName(assembly.Location); + string targetName = Path.Combine(localPath, "FilterAPI.DLL"); + + bool is64BitOperatingSystem = Environment.Is64BitOperatingSystem; + uint winMajorVersion = WinMajorVersion(); + uint winMinorVersion = WinMinorVersion(); + + string sourceFolder = localPath; + + try + { + + if (is64BitOperatingSystem) + { + if( (winMajorVersion >= 10 ) + || (winMajorVersion >= 6 && winMinorVersion >=3) ) + { + sourceFolder = Path.Combine(localPath, "Bin\\Win10X64"); + } + else + { + sourceFolder = Path.Combine(localPath, "Bin\\x64"); + } + } + else + { + if ((winMajorVersion >= 10) + || (winMajorVersion >= 6 && winMinorVersion >= 3)) + { + sourceFolder = Path.Combine(localPath, "Bin\\Win10X86"); + } + else + { + sourceFolder = Path.Combine(localPath, "Bin\\win32"); + } + } + + string sourceFile = Path.Combine(sourceFolder, "FilterAPI.DLL"); + + //only copy files for x86 platform, by default for x64, the files were there already. + + bool skipCopy = false; + if (File.Exists(targetName)) + { + FileInfo sourceFileInfo = new FileInfo(sourceFile); + FileInfo targetFileInfo = new FileInfo(targetName); + + if (sourceFileInfo.LastWriteTime.ToFileTime() == targetFileInfo.LastWriteTime.ToFileTime()) + { + skipCopy = true; + } + } + + if (!skipCopy) + { + File.Copy(sourceFile, targetName, true); + } + + + sourceFile = Path.Combine(sourceFolder, "EaseFlt.sys"); + targetName = Path.Combine(localPath, "EaseFlt.sys"); + + + skipCopy = false; + if (File.Exists(targetName)) + { + FileInfo sourceFileInfo = new FileInfo(sourceFile); + FileInfo targetFileInfo = new FileInfo(targetName); + + if (sourceFileInfo.LastWriteTime.ToFileTime() == targetFileInfo.LastWriteTime.ToFileTime()) + { + skipCopy = true; + } + } + + if (!skipCopy) + { + File.Copy(sourceFile, targetName, true); + } + + } + catch (Exception ex) + { + string lastError = "Copy platform dependent files 'FilterAPI.DLL' and 'EaseFlt.sys' to folder " + localPath + " got exception:" + ex.Message; + EventManager.WriteMessage(80, "CopyOSPlatformDependentFiles", EventLevel.Error, lastError); + } + } + + + public static string ByteArrayToHexStr(byte[] ba) + { + StringBuilder hex = new StringBuilder(ba.Length * 2); + foreach (byte b in ba) + { + hex.AppendFormat("{0:x2}", b); + } + + return hex.ToString().ToUpper(); + } + + public static byte[] ConvertHexStrToByteArray(string hexString) + { + if (hexString.Length % 2 != 0) + { + throw new ArgumentException(String.Format("The binary key cannot have an odd number of digits: {0}", hexString)); + } + + byte[] HexAsBytes = new byte[hexString.Length / 2]; + for (int index = 0; index < HexAsBytes.Length; index++) + { + string byteValue = hexString.Substring(index * 2, 2); + HexAsBytes[index] = byte.Parse(byteValue, NumberStyles.HexNumber, CultureInfo.InvariantCulture); + } + + return HexAsBytes; + } + + /// + /// Generate 32 bytes key array by pass phrase string + /// + /// + /// + public static byte[] GetKeyByPassPhrase(string pwStr,int keySize) + { + byte[] saltBytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 }; + byte[] passwordBytes = Encoding.UTF8.GetBytes(pwStr); + + var rfckey = new Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000); + byte[] key = rfckey.GetBytes(keySize); + + return key; + + + } + + /// + /// Generate 16 bytes iv array by pass phrase string + /// + /// + /// + public static byte[] GetIVByPassPhrase(string pwStr) + { + byte[] saltBytes = new byte[] { 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8 }; + byte[] passwordBytes = Encoding.UTF8.GetBytes(pwStr); + + var rfckey = new Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000); + byte[] key = rfckey.GetBytes(16); + + return key; + + + } + + public static byte[] GetRandomKey() + { + AesManaged aesManaged = new AesManaged(); + aesManaged.KeySize = 256; + byte[] key = aesManaged.Key; + + return key; + } + + public static byte[] GetRandomIV() + { + AesManaged aesManaged = new AesManaged(); + Guid guid = Guid.NewGuid(); + + byte[] IV = guid.ToByteArray(); + + return IV; + } + + public static bool IsBase64String(string s) + { + s = s.Trim(); + + if ((s.Length % 4 == 0) && Regex.IsMatch(s, @"^[a-zA-Z0-9\+/]*={0,3}$", RegexOptions.None)) + { + return true; + } + else + { + return false; + } + + } + + public static void SaveAppSetting(string fileName, Dictionary keyValues) + { + ExeConfigurationFileMap configFileMap = new ExeConfigurationFileMap(); + configFileMap.ExeConfigFilename = fileName; + Configuration configuration = ConfigurationManager.OpenMappedExeConfiguration(configFileMap, ConfigurationUserLevel.None); + KeyValueConfigurationCollection settings = configuration.AppSettings.Settings; + + settings.Clear(); + + foreach (KeyValuePair item in keyValues) + { + settings.Add(item.Key, item.Value); + } + + configuration.Save(); + } + + public static void LoadAppSetting(string fileName, ref Dictionary keyValues) + { + ExeConfigurationFileMap configFileMap = new ExeConfigurationFileMap(); + configFileMap.ExeConfigFilename = fileName; + Configuration configuration = ConfigurationManager.OpenMappedExeConfiguration(configFileMap, ConfigurationUserLevel.None); + KeyValueConfigurationCollection settings = configuration.AppSettings.Settings; + + foreach (KeyValueConfigurationElement item in settings) + { + keyValues.Add(item.Key, item.Value); + } + + } + + + public static void ToDebugger(string message) + { + System.Diagnostics.StackTrace st = new System.Diagnostics.StackTrace(false); + string caller = st.GetFrame(1).GetMethod().Name; + System.Diagnostics.Debug.WriteLine(caller + " Time:" + DateTime.Now.ToLongTimeString() + ": " + message); + } + + + } +} diff --git a/Demo_Source_Code/CSharpDemo/CommonObjects/WinDataStructures.cs b/Demo_Source_Code/CSharpDemo/CommonObjects/WinDataStructures.cs new file mode 100644 index 0000000..92eee8e --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/CommonObjects/WinDataStructures.cs @@ -0,0 +1,273 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.Collections.Generic; +using System.Text; + +namespace EaseFilter.CommonObjects +{ + static public class WinData + { + //for Disposition,ShareAccess,DesiredAccess,CreateOptions Please reference Winddows API CreateFile + //http://msdn.microsoft.com/en-us/library/aa363858%28v=vs.85%29.aspx + + public enum Disposition : uint + { + FILE_SUPERSEDE = 0, + FILE_OPEN, + FILE_CREATE, + FILE_OPEN_IF, + FILE_OVERWRITE, + FILE_OVERWRITE_IF, + } + + public enum ShareAccess : uint + { + SHARE_READ = 1, + SHARE_WRITE = 2, + SHARE_READ_WRITE = 3, + SHARE_DELETE = 4, + SHARE_READ_DELETE = 5, + SHARE_WRITE_DELETE = 6, + SHARE_READ_WRITE_DELETE = 7, + } + + public enum DisiredAccess : uint + { + DELETE = 0x00010000, + READ_CONTROL = 0x00020000, + WRITE_DAC = 0x00040000, + WRITE_OWNER = 0x00080000, + SYNCHRONIZE = 0x00100000, + STANDARD_RIGHTS_REQUIRED = 0x000F0000, + STANDARD_RIGHTS_ALL = 0x001F0000, + SPECIFIC_RIGHTS_ALL = 0x0000FFFF, + ACCESS_SYSTEM_SECURITY = 0x01000000, + MAXIMUM_ALLOWED = 0x02000000, + GENERIC_READ = 0x80000000, + GENERIC_WRITE = 0x40000000, + GENERIC_EXECUTE = 0x20000000, + GENERIC_ALL = 0x10000000, + FILE_READ_DATA = 1, + FILE_WRITE_DATA = 2, + FILE_APPEND_DATA = 0x0004, // file + FILE_READ_EA = 0x0008, // file & directory + FILE_WRITE_EA = 0x0010, // file & directory + FILE_EXECUTE = 0x0020, // file + FILE_DELETE_CHILD = 0x0040, // directory + FILE_READ_ATTRIBUTES = 0x0080, // all + FILE_WRITE_ATTRIBUTES = 0x0100, // all + + } + + public enum CreateOptions : uint + { + FILE_DIRECTORY_FILE = 0x00000001, + FILE_WRITE_THROUGH = 0x00000002, + FILE_SEQUENTIAL_ONLY = 0x00000004, + FILE_NO_INTERMEDIATE_BUFFERING = 0x00000008, + FILE_SYNCHRONOUS_IO_ALERT = 0x00000010, + FILE_SYNCHRONOUS_IO_NONALERT = 0x00000020, + FILE_NON_DIRECTORY_FILE = 0x00000040, + FILE_CREATE_TREE_CONNECTION = 0x00000080, + FILE_COMPLETE_IF_OPLOCKED = 0x00000100, + FILE_NO_EA_KNOWLEDGE = 0x00000200, + FILE_OPEN_REMOTE_INSTANCE = 0x00000400, + FILE_RANDOM_ACCESS = 0x00000800, + FILE_DELETE_ON_CLOSE = 0x00001000, + FILE_OPEN_BY_FILE_ID = 0x00002000, + FILE_OPEN_FOR_BACKUP_INTENT = 0x00004000, + FILE_NO_COMPRESSION = 0x00008000, + FILE_OPEN_REQUIRING_OPLOCK = 0x00010000, + FILE_DISALLOW_EXCLUSIVE = 0x00020000, + FILE_RESERVE_OPFILTER = 0x00100000, + FILE_OPEN_REPARSE_POINT = 0x00200000, + FILE_OPEN_NO_RECALL = 0x00400000, + FILE_OPEN_FOR_FREE_SPACE_QUERY = 0x00800000, + FO_REMOTE_ORIGIN = 0x01000000, + } + + //this is the status for post create request. + public enum CreateStatus : uint + { + FILE_SUPERSEDED = 0x00000000, + FILE_OPENED = 0x00000001, + FILE_CREATED = 0x00000002, + FILE_OVERWRITTEN = 0x00000003, + FILE_EXISTS = 0x00000004, + FILE_DOES_NOT_EXIST = 0x00000005, + } + + ////end of create structure------------------------------------------------------------------------------------------------- + + // + // Define the file information class values,for more information please reference + // http://msdn.microsoft.com/en-us/library/ff543439%28v=vs.85%29.aspx + // + public enum FileInfomationClass : uint + { + FileDirectoryInformation = 1, + FileFullDirectoryInformation, // 2 + FileBothDirectoryInformation, // 3 + FileBasicInformation, // 4 + FileStandardInformation, // 5 + FileInternalInformation, // 6 + FileEaInformation, // 7 + FileAccessInformation, // 8 + FileNameInformation, // 9 + FileRenameInformation, // 10 + FileLinkInformation, // 11 + FileNamesInformation, // 12 + FileDispositionInformation, // 13 + FilePositionInformation, // 14 + FileFullEaInformation, // 15 + FileModeInformation, // 16 + FileAlignmentInformation, // 17 + FileAllInformation, // 18 + FileAllocationInformation, // 19 + FileEndOfFileInformation, // 20 + FileAlternateNameInformation, // 21 + FileStreamInformation, // 22 + FilePipeInformation, // 23 + FilePipeLocalInformation, // 24 + FilePipeRemoteInformation, // 25 + FileMailslotQueryInformation, // 26 + FileMailslotSetInformation, // 27 + FileCompressionInformation, // 28 + FileObjectIdInformation, // 29 + FileCompletionInformation, // 30 + FileMoveClusterInformation, // 31 + FileQuotaInformation, // 32 + FileReparsePointInformation, // 33 + FileNetworkOpenInformation, // 34 + FileAttributeTagInformation, // 35 + FileTrackingInformation, // 36 + FileIdBothDirectoryInformation, // 37 + FileIdFullDirectoryInformation, // 38 + FileValidDataLengthInformation, // 39 + FileShortNameInformation, // 40 + FileIoCompletionNotificationInformation, // 41 + FileIoStatusBlockRangeInformation, // 42 + FileIoPriorityHintInformation, // 43 + FileSfioReserveInformation, // 44 + FileSfioVolumeInformation, // 45 + FileHardLinkInformation, // 46 + FileProcessIdsUsingFileInformation, // 47 + FileNormalizedNameInformation, // 48 + FileNetworkPhysicalNameInformation, // 49 + FileIdGlobalTxDirectoryInformation, // 50 + FileIsRemoteDeviceInformation, // 51 + FileAttributeCacheInformation, // 52 + FileNumaNodeInformation, // 53 + FileStandardLinkInformation, // 54 + FileRemoteProtocolInformation, // 55 + FileMaximumInformation + } + + public enum SecurityInformation : uint + { + OWNER_SECURITY_INFORMATION = 0x00000001, + GROUP_SECURITY_INFORMATION = 0x00000002, + DACL_SECURITY_INFORMATION = 0x00000004, + SACL_SECURITY_INFORMATION = 0x00000008, + LABEL_SECURITY_INFORMATION = 0x00000010, + } + + public struct FileBasicInformation + { + public long CreationTime; + public long LastAccessTime; + public long LastWriteTime; + public long ChangeTime; + public uint FileAttributes; + } + + public struct FileStandardInformation + { + public long AllocationSize; + public long EndOfFile; + public uint NumberOfLinks; + public bool DeletePending; + public bool Directory; + } + + public struct FileNetworkInformation + { + public long CreationTime; + public long LastAccessTime; + public long LastWriteTime; + public long ChangeTime; + public long AllocationSize; + public long FileSize; + public uint FileAttributes; + } + + //end of information structure----------------------------------------------------------------------------------- + + public enum FLT_FILESYSTEM_TYPE : uint + { + + FLT_FSTYPE_UNKNOWN, //an UNKNOWN file system type + FLT_FSTYPE_RAW, //Microsoft's RAW file system (\FileSystem\RAW) + FLT_FSTYPE_NTFS, //Microsoft's NTFS file system (\FileSystem\Ntfs) + FLT_FSTYPE_FAT, //Microsoft's FAT file system (\FileSystem\Fastfat) + FLT_FSTYPE_CDFS, //Microsoft's CDFS file system (\FileSystem\Cdfs) + FLT_FSTYPE_UDFS, //Microsoft's UDFS file system (\FileSystem\Udfs) + FLT_FSTYPE_LANMAN, //Microsoft's LanMan Redirector (\FileSystem\MRxSmb) + FLT_FSTYPE_WEBDAV, //Microsoft's WebDav redirector (\FileSystem\MRxDav) + FLT_FSTYPE_RDPDR, //Microsoft's Terminal Server redirector (\Driver\rdpdr) + FLT_FSTYPE_NFS, //Microsoft's NFS file system (\FileSystem\NfsRdr) + FLT_FSTYPE_MS_NETWARE, //Microsoft's NetWare redirector (\FileSystem\nwrdr) + FLT_FSTYPE_NETWARE, //Novell's NetWare redirector + FLT_FSTYPE_BSUDF, //The BsUDF CD-ROM driver (\FileSystem\BsUDF) + FLT_FSTYPE_MUP, //Microsoft's Mup redirector (\FileSystem\Mup) + FLT_FSTYPE_RSFX, //Microsoft's WinFS redirector (\FileSystem\RsFxDrv) + FLT_FSTYPE_ROXIO_UDF1, //Roxio's UDF writeable file system (\FileSystem\cdudf_xp) + FLT_FSTYPE_ROXIO_UDF2, //Roxio's UDF readable file system (\FileSystem\UdfReadr_xp) + FLT_FSTYPE_ROXIO_UDF3, //Roxio's DVD file system (\FileSystem\DVDVRRdr_xp) + FLT_FSTYPE_TACIT, //Tacit FileSystem (\Device\TCFSPSE) + FLT_FSTYPE_FS_REC, //Microsoft's File system recognizer (\FileSystem\Fs_rec) + FLT_FSTYPE_INCD, //Nero's InCD file system (\FileSystem\InCDfs) + FLT_FSTYPE_INCD_FAT, //Nero's InCD FAT file system (\FileSystem\InCDFat) + FLT_FSTYPE_EXFAT, //Microsoft's EXFat FILE SYSTEM (\FileSystem\exfat) + FLT_FSTYPE_PSFS, //PolyServ's file system (\FileSystem\psfs) + FLT_FSTYPE_GPFS //IBM General Parallel File System (\FileSystem\gpfs) + + } + + public enum DeviceObject_Characteristics:uint + { + FILE_REMOVABLE_MEDIA = 0x00000001, + FILE_READ_ONLY_DEVICE = 0x00000002, + FILE_FLOPPY_DISKETTE = 0x00000004, + FILE_WRITE_ONCE_MEDIA = 0x00000008, + FILE_REMOTE_DEVICE = 0x00000010, + FILE_DEVICE_IS_MOUNTED = 0x00000020, + FILE_VIRTUAL_VOLUME = 0x00000040, + FILE_AUTOGENERATED_DEVICE_NAME = 0x00000080, + FILE_DEVICE_SECURE_OPEN = 0x00000100, + FILE_CHARACTERISTIC_PNP_DEVICE = 0x00000800, + FILE_CHARACTERISTIC_TS_DEVICE = 0x00001000, + FILE_CHARACTERISTIC_WEBDAV_DEVICE = 0x00002000, + FILE_CHARACTERISTIC_CSV = 0x00010000, + FILE_DEVICE_ALLOW_APPCONTAINER_TRAVERSAL = 0x00020000, + FILE_PORTABLE_DEVICE = 0x00040000, + + } + } +} diff --git a/Demo_Source_Code/CSharpDemo/CommonObjects/app.config b/Demo_Source_Code/CSharpDemo/CommonObjects/app.config new file mode 100644 index 0000000..2198e51 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/CommonObjects/app.config @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/Demo_Source_Code/CSharpDemo/EaseFltCSConsoleDemo/ControlEventHandler.cs b/Demo_Source_Code/CSharpDemo/EaseFltCSConsoleDemo/ControlEventHandler.cs new file mode 100644 index 0000000..3514c71 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/EaseFltCSConsoleDemo/ControlEventHandler.cs @@ -0,0 +1,726 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Text; +using System.Runtime.InteropServices; +using System.Security.Principal; +using System.IO; +using System.Threading; +using System.Reflection; + +using EaseFilter.FilterControl; +using EaseFilter.CommonObjects; + +namespace EaseFltCSConsoleDemo +{ + + public class ControlEventHandler : IDisposable + { + bool disposed = false; + + public ControlEventHandler() + { + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + private void Dispose(bool disposing) + { + disposed = true; + } + + ~ControlEventHandler() + { + Dispose(false); + } + + public void DisplayEventMessage(FileIOEventArgs fileIOEventArgs) + { + try + { + string message = string.Empty; + message += "ControlFilter-MessageId:" + fileIOEventArgs.MessageId.ToString() + "\r\n"; + message += "UserName:" + fileIOEventArgs.UserName + "\r\n"; + message += "ProcessName:" + fileIOEventArgs.ProcessName + " (" + fileIOEventArgs.ProcessId + ")" + "\r\n"; + message += "ThreadId:" + fileIOEventArgs.ThreadId.ToString() + "\r\n"; + message += "EventName:" + fileIOEventArgs.EventName + "\r\n"; + message += "FileName:" + fileIOEventArgs.FileName + "\r\n"; + message += "FileSize:" + fileIOEventArgs.FileSize.ToString() + "\r\n"; + message += "FileAttributes:" + ((FileAttributes)fileIOEventArgs.FileAttributes).ToString() + "\r\n"; + message += "LastWriteTime:" + DateTime.FromFileTime(fileIOEventArgs.LastWriteTime).ToString("yyyy-MM-ddTHH:mm") + "\r\n"; + message += "IOStatus:" + fileIOEventArgs.IOStatusToString() + "\r\n"; + message += "Description:" + fileIOEventArgs.Description + "\r\n"; + + if ((uint)fileIOEventArgs.IoStatus >= (uint)NtStatus.Status.Error) + { + Console.BackgroundColor = ConsoleColor.Black; + Console.ForegroundColor = ConsoleColor.Red; + } + else if ((uint)fileIOEventArgs.IoStatus > (uint)NtStatus.Status.Warning) + { + Console.BackgroundColor = ConsoleColor.Black; + Console.ForegroundColor = ConsoleColor.Yellow; + } + else + { + Console.BackgroundColor = ConsoleColor.Black; + Console.ForegroundColor = ConsoleColor.White; + } + + Console.WriteLine(message); + + } + catch (Exception ex) + { + Console.WriteLine("DisplayEventMessage failed." + ex.Message); + } + + } + + + /// + /// Fires this event after the new file was created, the handle is not closed. + /// + public void OnPreCreateFile(object sender, FileCreateEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + //if (string.Compare(YourTestFileName, e.FileName, true) == 0) + //{ + // //test block the file open here. + // e.ReturnStatus = NtStatus.Status.AccessDenied; + //} + //else if (string.Compare(unitTestCallbackTestReparseFile, e.FileName, true) == 0) + //{ + // //test reparse file open to other file. + // e.reparseFileName = unitTestCallbackReparseTargetFile; + // e.ReturnStatus = NtStatus.Status.Reparse; + // e.IsDataModified = true; + //} + + + } + + /// + /// Fires this event after the new file was created, the handle is not closed. + /// + public void OnPostCreateFile(object sender, FileCreateEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + + /// + /// Fires this event after the read IO was returned. + /// + public void OnPreFileRead(object sender, FileReadEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + //if (string.Compare(YourTestFileName, e.FileName, true) == 0) + //{ + // //test block the file read here. + // e.ReturnStatus = NtStatus.Status.AccessDenied; + //} + } + + /// + /// Fires this event after the read IO was returned. + /// + public void OnPostFileRead(object sender, FileReadEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + + /// + /// Fires this event after the write IO was returned. + /// + public void OnPreFileWrite(object sender, FileWriteEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + //if (string.Compare(YourTestFileName, e.FileName, true) == 0) + //{ + // //test block the file write here. + // e.ReturnStatus = NtStatus.Status.AccessDenied; + //} + } + + /// + /// Fires this event after the write IO was returned. + /// + public void OnPostFileWrite(object sender, FileWriteEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + + /// + /// Fires this event after the query file size IO was returned. + /// + public void OnPreQueryFileSize(object sender, FileSizeEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + //if (string.Compare(YourTestFileName, e.FileName, true) == 0) + //{ + // //test block the file size query here. + // e.ReturnStatus = NtStatus.Status.AccessDenied; + //} + //else if (string.Compare(YourTestFileName, e.FileName, true) == 0) + //{ + // //test replace the file size with your own, complete the pre-query IO. + // e.fileSizeToQueryOrSet = 1000;//change the file size with your own + // e.ReturnStatus = NtStatus.Status.Success; + // e.IsDataModified = true; + //} + } + + /// + /// Fires this event after the query file size IO was returned. + /// + public void OnPostQueryFileSize(object sender, FileSizeEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + //if (string.Compare(YourTestFileName, e.FileName, true) == 0) + //{ + // //test replace the file size with your own. + // e.fileSizeToQueryOrSet = 1000;//change the file size with your own + // e.ReturnStatus = NtStatus.Status.Success; + // e.IsDataModified = true; + //} + } + + /// + /// Fires this event after the query file basic information IO was returned. + /// + public void OnPreQueryFileBasicInfo(object sender, FileBasicInfoEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + //if (string.Compare(YourTestFileName, e.FileName, true) == 0) + //{ + // //test block the file basic info query here. + // e.ReturnStatus = NtStatus.Status.AccessDenied; + //} + //else if (string.Compare(YourTestFileName, e.FileName, true) == 0) + //{ + // //test replace the basic file info with your own, complete the pre-query IO. + //WinData.FileBasicInformation basicInfo = new WinData.FileBasicInformation(); + //basicInfo.CreationTime = basicInfo.LastWriteTime = DateTime.Now.ToFileTime(); + //e.basicInfo = basicInfo;//change the file basic info with your own + //e.ReturnStatus = NtStatus.Status.Success; + // e.IsDataModified = true; + //} + } + + /// + /// Fires this event after the query file basic information IO was returned. + /// + public void OnPostQueryFileBasicInfo(object sender, FileBasicInfoEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + // //test replace the basic file info with your own, complete the pre-query IO. + //WinData.FileBasicInformation basicInfo = new WinData.FileBasicInformation(); + //basicInfo.CreationTime = basicInfo.LastWriteTime = DateTime.Now.ToFileTime(); + //e.basicInfo = basicInfo;//change the file basic info with your own + //e.ReturnStatus = NtStatus.Status.Success; + // e.IsDataModified = true; + } + + /// + /// Fires this event after the query file standard information IO was returned. + /// + public void OnPreQueryFileStandardInfo(object sender, FileStandardInfoEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + //if (string.Compare(YourTestFileName, e.FileName, true) == 0) + //{ + // //test block the file standard info query here. + // e.ReturnStatus = NtStatus.Status.AccessDenied; + //} + //else if (string.Compare(YourTestFileName, e.FileName, true) == 0) + //{ + // //test replace the file standard info with your own, complete the pre-query IO. + //WinData.FileStandardInformation standardInfo = new WinData.FileStandardInformation(); + //standardInfo.EndOfFile = 1000; //new file size + //e.standardInfo = standardInfo;//change the file basic info with your own + //e.ReturnStatus = NtStatus.Status.Success; + //e.IsDataModified = true; + //} + } + + /// + /// Fires this event after the query file standard information IO was returned. + /// + public void OnPostQueryFileStandardInfo(object sender, FileStandardInfoEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + // //test replace the file standard info with your own + //WinData.FileStandardInformation standardInfo = new WinData.FileStandardInformation(); + //standardInfo.EndOfFile = 1000; //new file size + //e.standardInfo = standardInfo;//change the file basic info with your own + //e.ReturnStatus = NtStatus.Status.Success; + //e.IsDataModified = true; + } + + /// + /// Fires this event after the query file network information IO was returned. + /// + public void OnPreQueryFileNetworkInfo(object sender, FileNetworkInfoEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + //if (string.Compare(YourTestFileName, e.FileName, true) == 0) + //{ + // //test block the file network info query here. + // e.ReturnStatus = NtStatus.Status.AccessDenied; + //} + //else if (string.Compare(YourTestFileName, e.FileName, true) == 0) + //{ + // //test replace the file standard info with your own, complete the pre-query IO. + //WinData.FileNetworkInformation networkInfo = new WinData.FileNetworkInformation(); + //networkInfo.CreationTime = networkInfo.LastWriteTime = networkInfo.ChangeTime = DateTime.Now.ToFileTime(); //new file time + //e.networkInfo = networkInfo;//change the file networkInfo with your own + //e.ReturnStatus = NtStatus.Status.Success; + //e.IsDataModified = true; + //} + } + + /// + /// Fires this event after the query file network information IO was returned. + /// + public void OnPostQueryFileNetworkInfo(object sender, FileNetworkInfoEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + // //test replace the file standard info with your own, complete the pre-query IO. + //WinData.FileNetworkInformation networkInfo = new WinData.FileNetworkInformation(); + //networkInfo.CreationTime = networkInfo.LastWriteTime = networkInfo.ChangeTime = DateTime.Now.ToFileTime(); //new file time + //e.networkInfo = networkInfo;//change the file networkInfo with your own + //e.ReturnStatus = NtStatus.Status.Success; + //e.IsDataModified = true; + + } + + /// + /// Fires this event after the query file Id IO was returned. + /// + public void OnPreQueryFileId(object sender, FileIdEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + //if (string.Compare(YourTestFileName, e.FileName, true) == 0) + //{ + // //test block the file Id query here. + // e.ReturnStatus = NtStatus.Status.AccessDenied; + //} + } + + /// + /// Fires this event after the query file Id IO was returned. + /// + public void OnPostQueryFileId(object sender, FileIdEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + + /// + /// Fires this event after the query file info IO was returned. + /// + /// + /// + public void OnPreQueryFileInfo(object sender, FileInfoArgs e) + { + DisplayEventMessage(e); + //do your job here. + + //the QueryFileInfo includes all the information class as "WinData.FileInfomationClass" + //we already handled some common query information class as above "Query file size, file basic info, file standard info, file network info, file Id." + //all other classes were handled here, for more information please reference "FltQueryInformationFile". + + //if (string.Compare(YourTestFileName, e.FileName, true) == 0) + //{ + // //test block the file info query here. + // e.ReturnStatus = NtStatus.Status.AccessDenied; + //} + } + + /// + /// Fires this event after the query file info IO was returned. + /// + /// + /// + public void OnPostQueryFileInfo(object sender, FileInfoArgs e) + { + DisplayEventMessage(e); + //do your job here. + + //to get the query file info result, first you need to get the information class: + //e.FileInfoClass, then get the structure of the class + //e.DataBuffer has the information data of the file associated to the info class. + + } + + /// + /// Fires this event after the set file size IO was returned. + /// + public void OnPreSetFileSize(object sender, FileSizeEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + //if (string.Compare(YourTestFileName, e.FileName, true) == 0) + //{ + // //test block the set file size IO. + // e.fileSizeToQueryOrSet is the file size will be set + // e.ReturnStatus = NtStatus.Status.AccessDenied; + //} + } + + /// + /// Fires this event after the set file size IO was returned. + /// + public void OnPostSetFileSize(object sender, FileSizeEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + + /// + /// Fires this event after the set file basic information was returned. + /// + public void OnPreSetFileBasicInfo(object sender, FileBasicInfoEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + //if (string.Compare(YourTestFileName, e.FileName, true) == 0) + //{ + // //test block the set file basic info IO. + // e.basicInfo is the file basic info will be set + // e.ReturnStatus = NtStatus.Status.AccessDenied; + //} + } + + /// + /// Fires this event after the set file basic information was returned. + /// + public void OnPostSetFileBasicInfo(object sender, FileBasicInfoEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + + /// + /// Fires this event after the set file standard information IO was returned. + /// + public void OnPreSetFileStandardInfo(object sender, FileStandardInfoEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + //if (string.Compare(YourTestFileName, e.FileName, true) == 0) + //{ + // //test block the set file standard info IO. + // e.standardInfo is the file standard info will be set + // e.ReturnStatus = NtStatus.Status.AccessDenied; + //} + } + + /// + /// Fires this event after the set file standard information IO was returned. + /// + public void OnPostSetFileStandardInfo(object sender, FileStandardInfoEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + + + /// + /// Fires this event after the set file network information IO was returned. + /// + public void OnPreSetFileNetworkInfo(object sender, FileNetworkInfoEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + + //if (string.Compare(YourTestFileName, e.FileName, true) == 0) + //{ + // //test block the set file standard info IO. + // e.networkInfo is the file standard info will be set + // e.ReturnStatus = NtStatus.Status.AccessDenied; + //} + } + + /// + /// Fires this event after the set file network information IO was returned. + /// + public void OnPostSetFileNetworkInfo(object sender, FileNetworkInfoEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + + /// + /// Fires this event after the file was moved or renamed. + /// + public void OnPreMoveOrRenameFile(object sender, FileMoveOrRenameEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + //if (string.Compare(YourTestFileName, e.FileName, true) == 0) + //{ + // //test block the file rename here. + // e.newFileName is the new file name will be changed + // e.ReturnStatus = NtStatus.Status.AccessDenied; + //} + } + + /// + /// Fires this event after the file was moved or renamed. + /// + public void OnPostMoveOrRenameFile(object sender, FileMoveOrRenameEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + + /// + /// Fires this event after the delete IO was returned. + /// + public void OnPreDeleteFile(object sender, FileIOEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + //if (string.Compare(YourTestFileName, e.FileName, true) == 0) + //{ + // //test block the file delete here. + // e.ReturnStatus = NtStatus.Status.AccessDenied; + //} + } + + /// + /// Fires this event after the delete IO was returned. + /// + public void OnPostDeleteFile(object sender, FileIOEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + + /// + /// Fires this event after the set file info IO was returned. + /// + /// + /// + public void OnPreSetFileInfo(object sender, FileInfoArgs e) + { + DisplayEventMessage(e); + //do your job here. + + //the SetFileInfo includes all the information class as "WinData.FileInfomationClass" + //we already handled some common set information class as above "Set file size, file basic info, file standard info, file network info, rename, delete." + //all other classes were handled here, for more information please reference "FltSetInformationFile". + + //if (string.Compare(YourTestFileName, e.FileName, true) == 0) + //{ + // //test block the set file info here. + // e.ReturnStatus = NtStatus.Status.AccessDenied; + //} + } + + /// + /// Fires this event after the set file info IO was returned. + /// + /// + /// + public void OnPostSetFileInfo(object sender, FileInfoArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + + /// + /// Fires this event after the query file security IO was returned. + /// + public void OnPreQueryFileSecurity(object sender, FileSecurityEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + //if (string.Compare(YourTestFileName, e.FileName, true) == 0) + //{ + // //test block the query file security IO here. + // e.ReturnStatus = NtStatus.Status.AccessDenied; + //} + } + + /// + /// Fires this event after the query file security IO was returned. + /// + public void OnPostQueryFileSecurity(object sender, FileSecurityEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + //you can get the security data return from the file system. + //e.securityBuffer + } + + /// + /// Fires this event after the set file security IO was returned. + /// + public void OnPreSetFileSecurity(object sender, FileSecurityEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + //if (string.Compare(YourTestFileName, e.FileName, true) == 0) + //{ + // //test block the set file security IO here. + // e.ReturnStatus = NtStatus.Status.AccessDenied; + //} + } + + /// + /// Fires this event after the set file security IO was returned. + /// + public void OnPostSetFileSecurity(object sender, FileSecurityEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + + + /// + /// Fires this event after the directory enumeration query IO was returned. + /// + public void OnPreQueryDirectoryFile(object sender, FileQueryDirectoryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + + //if (string.Compare(YourTestFileName, e.FileName, true) == 0) + //{ + // //test block the query directory file IO here if you block the file browsing. + // e.ReturnStatus = NtStatus.Status.AccessDenied; + //} + } + + /// + /// Fires this event after the directory enumeration query IO was returned. + /// + public void OnPostQueryDirectoryFile(object sender, FileQueryDirectoryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + //get the data of the directory file list based on the information class. + //e.fileInfomationClass; + //e.directoryBuffer; + + } + + + /// + /// Fires this event after the file was cleanuped. + /// + public void OnPreFileHandleClose(object sender, FileIOEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + + /// + /// Fires this event after the file was cleanuped. + /// + public void OnPostFileHandleClose(object sender, FileIOEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + + /// + /// Fires this event after the last file handle of the file was closed. + /// + public void OnPreFileClose(object sender, FileIOEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + + /// + /// Fires this event after the last file handle of the file was closed. + /// + public void OnPostFileClose(object sender, FileIOEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + + /// + /// Fires this event when the filter driver attached to a volume. + /// + public void NotifyFilterAttachToVolume(object sender, VolumeInfoEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + + /// + /// Fires this event when a volume was detached from the filter driver. + /// + public void NotifyFilterDetachFromVolume(object sender, VolumeInfoEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + + } +} \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/EaseFltCSConsoleDemo/EaseFilterService.Designer.cs b/Demo_Source_Code/CSharpDemo/EaseFltCSConsoleDemo/EaseFilterService.Designer.cs new file mode 100644 index 0000000..5861bbf --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/EaseFltCSConsoleDemo/EaseFilterService.Designer.cs @@ -0,0 +1,38 @@ +namespace EaseFltCSConsoleDemo +{ + partial class EaseFilterService + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + components = new System.ComponentModel.Container(); + this.ServiceName = "EaseFilter Service"; + + } + + #endregion + } +} diff --git a/Demo_Source_Code/CSharpDemo/EaseFltCSConsoleDemo/EaseFilterService.cs b/Demo_Source_Code/CSharpDemo/EaseFltCSConsoleDemo/EaseFilterService.cs new file mode 100644 index 0000000..1aa682d --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/EaseFltCSConsoleDemo/EaseFilterService.cs @@ -0,0 +1,53 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Diagnostics; +using System.Linq; +using System.ServiceProcess; +using System.Text; + +using EaseFilter.CommonObjects; + +namespace EaseFltCSConsoleDemo +{ + public partial class EaseFilterService : ServiceBase + { + public EaseFilterService() + { + InitializeComponent(); + } + + protected override void OnStart(string[] args) + { + string lastError = string.Empty; + + if (!FilterWorker.StartService(out lastError)) + { + EventManager.WriteMessage(100, "StartFilter", EventLevel.Error, "Start filter service failed with error " + lastError); + } + } + + protected override void OnStop() + { + FilterWorker.StopService(); + } + } +} diff --git a/Demo_Source_Code/CSharpDemo/EaseFltCSConsoleDemo/EaseFltCSConsoleDemo.csproj b/Demo_Source_Code/CSharpDemo/EaseFltCSConsoleDemo/EaseFltCSConsoleDemo.csproj new file mode 100644 index 0000000..60364d1 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/EaseFltCSConsoleDemo/EaseFltCSConsoleDemo.csproj @@ -0,0 +1,96 @@ + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {B2571F4D-C611-409C-A885-53FDDA045269} + Exe + Properties + EaseFltCSConsoleDemo + EaseFltCSConsoleDemo + v4.5 + 512 + SAK + SAK + SAK + SAK + + + 3.5 + + + + + true + full + false + ..\..\Release\ + DEBUG;TRACE + prompt + 4 + AllRules.ruleset + false + + + pdbonly + true + ..\..\Release\ + TRACE + prompt + 4 + AllRules.ruleset + false + + + true + + + + + + + + + + + + + Component + + + EaseFilterService.cs + + + + + + + + + Component + + + + + + + + {34CB783E-DDA2-4CE3-80BC-37B25AA33E5F} + CommonObjects + + + {21540012-A296-45CE-8D35-3EA5A07B32A6} + FilterControl + + + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/EaseFltCSConsoleDemo/FileIOControlService.cs b/Demo_Source_Code/CSharpDemo/EaseFltCSConsoleDemo/FileIOControlService.cs new file mode 100644 index 0000000..cc1f780 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/EaseFltCSConsoleDemo/FileIOControlService.cs @@ -0,0 +1,195 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Runtime.InteropServices; + +using EaseFilter.CommonObjects; + +namespace EaseFltCSConsoleDemo +{ + class FilterService + { + public static bool IOAccessControl(FilterAPI.MessageSendData messageSend, ref FilterAPI.MessageReplyData messageReply) + { + bool ret = true; + + try + { + + messageReply.MessageId = messageSend.MessageId; + messageReply.MessageType = messageSend.MessageType; + + // + //here you can control all the registered IO requests,block the access or modify the I/O data base on the file IO information from MessageSend struture + // + // + + //if you don't want to change anything to this IO request, just let it pass through as below setting: + //messageReply.FilterStatus = 0; + //messageReply.ReturnStatus = (uint)NtStatus.Status.Success; + + //if you want to block the access this IO request before it goes down to the file system, you can return the status as below, + //it is only for pre IO requests, it means the user IO reuqests will be completed here instead of going down to the file system. + //messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION; + //messageReply.ReturnStatus = (uint)NtStatus.Status.AccessDenied; + + //if you want to modify the IO data and complete the pre IO with your own data, you can return status as below: + // messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION | (uint)FilterAPI.FilterStatus.FILTER_DATA_BUFFER_IS_UPDATED; + // messageReply.DataBufferLength = the return data buffer length. + // messageReply.DataBuffer = the data you want to return. + // messageReply.ReturnStatus = (uint)NtStatus.Status.Success; + + FilterAPI.MessageType messageType = (FilterAPI.MessageType)messageSend.MessageType; + WinData.FileInfomationClass infoClass = (WinData.FileInfomationClass)messageSend.InfoClass; + + uint dataLength = messageSend.DataBufferLength; + byte[] data = messageSend.DataBuffer; + + //here is some IO information for your reference: + if ((messageSend.CreateOptions & (uint)WinData.CreateOptions.FO_REMOTE_ORIGIN) > 0) + { + //this is file access request comes from remote network server + } + + //you can check the file create option with this data: + //"DesiredAccess: messageSend.DesiredAccess + //"Disposition:" + ((WinData.Disposition)messageSend.Disposition).ToString(); + //"ShareAccess:" + ((WinData.ShareAccess)messageSend.SharedAccess).ToString(); + //"CreateOptions:"messageSend.CreateOptions + + switch (messageType) + { + case FilterAPI.MessageType.PRE_CREATE: + { + + //here you reparse the file open to another new file name + + //string newReparseFileName = "\\??\\c:\\myNewFile.txt"; + //byte[] returnData = Encoding.Unicode.GetBytes(newReparseFileName); + //Array.Copy(returnData, messageReply.DataBuffer, returnData.Length); + //messageReply.DataBufferLength = (uint)returnData.Length; + //messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION; + //messageReply.ReturnStatus = (uint)NtStatus.Status.Reparse; + + break; + } + + + case FilterAPI.MessageType.PRE_CACHE_READ: + case FilterAPI.MessageType.POST_CACHE_READ: + case FilterAPI.MessageType.PRE_NOCACHE_READ: + case FilterAPI.MessageType.POST_NOCACHE_READ: + case FilterAPI.MessageType.PRE_PAGING_IO_READ: + case FilterAPI.MessageType.POST_PAGING_IO_READ: + case FilterAPI.MessageType.PRE_CACHE_WRITE: + case FilterAPI.MessageType.POST_CACHE_WRITE: + case FilterAPI.MessageType.PRE_NOCACHE_WRITE: + case FilterAPI.MessageType.POST_NOCACHE_WRITE: + case FilterAPI.MessageType.PRE_PAGING_IO_WRITE: + case FilterAPI.MessageType.POST_PAGING_IO_WRITE: + { + + + //byte[] returnData = //new data you want to modify the read/write data; + //Array.Copy(returnData, messageReply.DataBuffer, returnData.Length); + //messageReply.DataBufferLength = (uint)returnData.Length; + + ////for pre IO,use this one + //// messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION | (uint)FilterAPI.FilterStatus.FILTER_DATA_BUFFER_IS_UPDATED; + + // messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_DATA_BUFFER_IS_UPDATED; + // messageReply.ReturnStatus = (uint)NtStatus.Status.Success; + + + break; + } + case FilterAPI.MessageType.PRE_SET_INFORMATION: + case FilterAPI.MessageType.POST_SET_INFORMATION: + case FilterAPI.MessageType.PRE_QUERY_INFORMATION: + case FilterAPI.MessageType.POST_QUERY_INFORMATION: + { + ret = true; + switch (infoClass) + { + case WinData.FileInfomationClass.FileRenameInformation: + { + //you can block file rename as below + //messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION; + //messageReply.ReturnStatus = (uint)NtStatus.Status.AccessDenied; + break; + } + case WinData.FileInfomationClass.FileDispositionInformation: + { + //you can block file delete as below + //messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION; + //messageReply.ReturnStatus = (uint)NtStatus.Status.AccessDenied; + break; + } + case WinData.FileInfomationClass.FileEndOfFileInformation: + { + //change file size + break; + } + case WinData.FileInfomationClass.FileBasicInformation: + { + //file basic information + break; + } + + case WinData.FileInfomationClass.FileStandardInformation: + { + //file standard information + break; + } + case WinData.FileInfomationClass.FileNetworkOpenInformation: + { + //file network information + break; + } + + case WinData.FileInfomationClass.FileInternalInformation: + { + //file internal inofrmation + break; + } + default: + { + ret = false; + break; + } + } + + break; + } + } + + + } + catch (Exception ex) + { + EventManager.WriteMessage(174, "IOAccessControl", EventLevel.Error, "IOAccessControl failed." + ex.Message); + } + + return ret; + } + + } +} diff --git a/Demo_Source_Code/CSharpDemo/EaseFltCSConsoleDemo/FilterWorker.cs b/Demo_Source_Code/CSharpDemo/EaseFltCSConsoleDemo/FilterWorker.cs new file mode 100644 index 0000000..80eece3 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/EaseFltCSConsoleDemo/FilterWorker.cs @@ -0,0 +1,288 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.Runtime.InteropServices; + +using EaseFilter.FilterControl; +using EaseFilter.CommonObjects; + +namespace EaseFltCSConsoleDemo +{ + public class FilterWorker + { + static MonitorEventHandler monitorEventHandler = new MonitorEventHandler(); + static ControlEventHandler controlEventHandler = new ControlEventHandler(); + static ProcessHandler processHandler = new ProcessHandler(); + static RegistryHandler registryHandler = new RegistryHandler(); + static FilterControl filterControl = new FilterControl(); + + public static bool SendConfigSettingsToFilter(ref string lastError) + { + try + { + filterControl.ClearFilters(); + + if (GlobalConfig.ProcessFilterRules.Count == 0) + { + //there are no process filter rule in config file, here is the example to create a process filter rule. + //ProcessFilterRule processFilterRule = new ProcessFilterRule(); + //processFilterRule.ProcessNameFilterMask = "*"; + //processFilterRule.ControlFlag = (uint)(FilterAPI.ProcessControlFlag.PROCESS_CREATION_NOTIFICATION | FilterAPI.ProcessControlFlag.PROCESS_TERMINATION_NOTIFICATION); + + //GlobalConfig.AddProcessFilterRule(processFilterRule); + } + + foreach (ProcessFilterRule filterRule in GlobalConfig.ProcessFilterRules.Values) + { + ProcessFilter processFilter = filterRule.ToProcessFilter(); + + processFilter.OnProcessCreation += processHandler.OnProcessCreation; + processFilter.NotifyProcessTerminated += processHandler.NotifyProcessTerminated; + processFilter.NotifyThreadCreation += processHandler.NotifyThreadCreation; + processFilter.NotifyProcessTerminated += processHandler.NotifyProcessTerminated; + processFilter.NotifyProcessHandleInfo += processHandler.NotifyProcessHandleInfo; + processFilter.NotifyThreadHandleInfo += processHandler.NotifyThreadHandleInfo; + + filterControl.AddFilter(processFilter); + } + + if (GlobalConfig.FilterRules.Count == 0) + { + //there are no filter rule in config file, here is the example filter rule to create. + + //FileFilterRule fileFilterRule = new FileFilterRule(); + //fileFilterRule.IncludeFileFilterMask = "*"; + //fileFilterRule.EnableMonitorEventBuffer = true; + //fileFilterRule.RegisterMonitorFileIOEvents = 0x28A8AAAAAAAAAAA; + //fileFilterRule.RegisterControlFileIOEvents = 0x0; + //fileFilterRule.AccessFlag = (uint)FilterAPI.ALLOW_MAX_RIGHT_ACCESS; + + //GlobalConfig.AddFileFilterRule(fileFilterRule); + } + + foreach (FileFilterRule filterRule in GlobalConfig.FilterRules.Values) + { + FileFilter fileFilter = filterRule.ToFileFilter(); + + //add the monitor event handler for the file filter. + fileFilter.OnFileOpen += monitorEventHandler.OnFileOpen; + fileFilter.OnNewFileCreate += monitorEventHandler.OnFileCreate; + fileFilter.OnDeleteFile += monitorEventHandler.OnDeleteFile; + fileFilter.OnFileRead += monitorEventHandler.OnFileRead; + fileFilter.OnFileWrite += monitorEventHandler.OnFileWrite; + fileFilter.OnQueryFileBasicInfo += monitorEventHandler.OnQueryFileBasicInfo; + fileFilter.OnQueryFileId += monitorEventHandler.OnQueryFileId; + fileFilter.OnQueryFileNetworkInfo += monitorEventHandler.OnQueryFileNetworkInfo; + fileFilter.OnQueryFileSize += monitorEventHandler.OnQueryFileSize; + fileFilter.OnQueryFileStandardInfo += monitorEventHandler.OnQueryFileStandardInfo; + fileFilter.OnQueryFileInfo += monitorEventHandler.OnQueryFileInfo; + fileFilter.OnSetFileBasicInfo += monitorEventHandler.OnSetFileBasicInfo; + fileFilter.OnSetFileNetworkInfo += monitorEventHandler.OnSetFileNetworkInfo; + fileFilter.OnSetFileSize += monitorEventHandler.OnSetFileSize; + fileFilter.OnSetFileStandardInfo += monitorEventHandler.OnSetFileStandardInfo; + fileFilter.OnMoveOrRenameFile += monitorEventHandler.OnMoveOrRenameFile; + fileFilter.OnSetFileInfo += monitorEventHandler.OnSetFileInfo; + fileFilter.OnQueryFileSecurity += monitorEventHandler.OnQueryFileSecurity; + fileFilter.OnQueryDirectoryFile += monitorEventHandler.OnQueryDirectoryFile; + fileFilter.OnFileHandleClose += monitorEventHandler.OnFileHandleClose; + fileFilter.OnFileClose += monitorEventHandler.OnFileClose; + + fileFilter.NotifyFileWasChanged += monitorEventHandler.NotifyFileWasChanged; + + //add the control pre-event handler for the control file filter. + fileFilter.OnPreCreateFile += controlEventHandler.OnPreCreateFile; + fileFilter.OnPreDeleteFile += controlEventHandler.OnPreDeleteFile; + fileFilter.OnPreFileRead += controlEventHandler.OnPreFileRead; + fileFilter.OnPreFileWrite += controlEventHandler.OnPreFileWrite; + fileFilter.OnPreQueryFileBasicInfo += controlEventHandler.OnPreQueryFileBasicInfo; + fileFilter.OnPreQueryFileId += controlEventHandler.OnPreQueryFileId; + fileFilter.OnPreQueryFileNetworkInfo += controlEventHandler.OnPreQueryFileNetworkInfo; + fileFilter.OnPreQueryFileSize += controlEventHandler.OnPreQueryFileSize; + fileFilter.OnPreQueryFileStandardInfo += controlEventHandler.OnPreQueryFileStandardInfo; + fileFilter.OnPreQueryFileInfo += controlEventHandler.OnPreQueryFileInfo; + fileFilter.OnPreSetFileBasicInfo += controlEventHandler.OnPreSetFileBasicInfo; + fileFilter.OnPreSetFileNetworkInfo += controlEventHandler.OnPreSetFileNetworkInfo; + fileFilter.OnPreSetFileSize += controlEventHandler.OnPreSetFileSize; + fileFilter.OnPreSetFileStandardInfo += controlEventHandler.OnPreSetFileStandardInfo; + fileFilter.OnPreMoveOrRenameFile += controlEventHandler.OnPreMoveOrRenameFile; + fileFilter.OnPreSetFileInfo += controlEventHandler.OnPreSetFileInfo; + fileFilter.OnPreQueryFileSecurity += controlEventHandler.OnPreQueryFileSecurity; + fileFilter.OnPreQueryDirectoryFile += controlEventHandler.OnPreQueryDirectoryFile; + fileFilter.OnPreFileHandleClose += controlEventHandler.OnPreFileHandleClose; + fileFilter.OnPreFileClose += controlEventHandler.OnPreFileClose; + //add the control post-event handler for the control file filter. + fileFilter.OnPostCreateFile += controlEventHandler.OnPostCreateFile; + fileFilter.OnPostDeleteFile += controlEventHandler.OnPostDeleteFile; + fileFilter.OnPostFileRead += controlEventHandler.OnPostFileRead; + fileFilter.OnPostFileWrite += controlEventHandler.OnPostFileWrite; + fileFilter.OnPostQueryFileBasicInfo += controlEventHandler.OnPostQueryFileBasicInfo; + fileFilter.OnPostQueryFileId += controlEventHandler.OnPostQueryFileId; + fileFilter.OnPostQueryFileNetworkInfo += controlEventHandler.OnPostQueryFileNetworkInfo; + fileFilter.OnPostQueryFileSize += controlEventHandler.OnPostQueryFileSize; + fileFilter.OnPostQueryFileStandardInfo += controlEventHandler.OnPostQueryFileStandardInfo; + fileFilter.OnPostQueryFileInfo += controlEventHandler.OnPostQueryFileInfo; + fileFilter.OnPostSetFileBasicInfo += controlEventHandler.OnPostSetFileBasicInfo; + fileFilter.OnPostSetFileNetworkInfo += controlEventHandler.OnPostSetFileNetworkInfo; + fileFilter.OnPostSetFileSize += controlEventHandler.OnPostSetFileSize; + fileFilter.OnPostSetFileStandardInfo += controlEventHandler.OnPostSetFileStandardInfo; + fileFilter.OnPostMoveOrRenameFile += controlEventHandler.OnPostMoveOrRenameFile; + fileFilter.OnPostSetFileInfo += controlEventHandler.OnPostSetFileInfo; + fileFilter.OnPostQueryFileSecurity += controlEventHandler.OnPostQueryFileSecurity; + fileFilter.OnPostQueryDirectoryFile += controlEventHandler.OnPostQueryDirectoryFile; + fileFilter.OnPostFileHandleClose += controlEventHandler.OnPostFileHandleClose; + fileFilter.OnPostFileClose += controlEventHandler.OnPostFileClose; + + filterControl.AddFilter(fileFilter); + } + + if (GlobalConfig.RegistryFilterRules.Count == 0) + { + //there are no registry filter rule in config file, here is the example to create a registry filter rule. + //RegistryFilterRule registryFilterRule = new RegistryFilterRule(); + //registryFilterRule.AccessFlag = FilterAPI.MAX_REGITRY_ACCESS_FLAG; + //registryFilterRule.RegCallbackClass = 93092006832128; //by default only register post callback class + //registryFilterRule.ProcessNameFilterMask = "*"; + //registryFilterRule.RegistryKeyNameFilterMask = "*Windows*"; //only display the key name includs 'Windows'. + + //GlobalConfig.AddRegistryFilterRule(registryFilterRule); + } + + foreach (RegistryFilterRule filterRule in GlobalConfig.RegistryFilterRules.Values) + { + RegistryFilter registryFilter = filterRule.ToRegistryFilter(); + + registryFilter.OnPreDeleteKey += registryHandler.OnPreDeleteKey; + registryFilter.OnPreSetValueKey += registryHandler.OnPreSetValueKey; + registryFilter.OnPreDeleteValueKey += registryHandler.OnPreDeleteValueKey; + registryFilter.OnPreSetInformationKey += registryHandler.OnPreSetInformationKey; + registryFilter.OnPreRenameKey += registryHandler.OnPreRenameKey; + registryFilter.OnPreEnumerateKey += registryHandler.OnPreEnumerateKey; + registryFilter.OnPreEnumerateValueKey += registryHandler.OnPreEnumerateValueKey; + registryFilter.OnPreQueryKey += registryHandler.OnPreQueryKey; + registryFilter.OnPreQueryValueKey += registryHandler.OnPreQueryValueKey; + registryFilter.OnPreQueryMultipleValueKey += registryHandler.OnPreQueryMultipleValueKey; + registryFilter.OnPreCreateKey += registryHandler.OnPreCreateKey; + registryFilter.OnPreOpenKey += registryHandler.OnPreOpenKey; + registryFilter.OnPreKeyHandleClose += registryHandler.OnPreKeyHandleClose; + registryFilter.OnPreCreateKeyEx += registryHandler.OnPreCreateKeyEx; + registryFilter.OnPreOpenKeyEx += registryHandler.OnPreOpenKeyEx; + registryFilter.OnPreFlushKey += registryHandler.OnPreFlushKey; + registryFilter.OnPreLoadKey += registryHandler.OnPreLoadKey; + registryFilter.OnPreUnLoadKey += registryHandler.OnPreUnLoadKey; + registryFilter.OnPreQueryKeySecurity += registryHandler.OnPreQueryKeySecurity; + registryFilter.OnPreSetKeySecurity += registryHandler.OnPreSetKeySecurity; + registryFilter.OnPreRestoreKey += registryHandler.OnPreRestoreKey; + registryFilter.OnPreSaveKey += registryHandler.OnPreSaveKey; + registryFilter.OnPreReplaceKey += registryHandler.OnPreReplaceKey; + registryFilter.OnPreQueryKeyName += registryHandler.OnPreQueryKeyName; + + registryFilter.NotifyDeleteKey += registryHandler.NotifyDeleteKey; + registryFilter.NotifySetValueKey += registryHandler.NotifySetValueKey; + registryFilter.NotifyDeleteValueKey += registryHandler.NotifyDeleteValueKey; + registryFilter.NotifySetInformationKey += registryHandler.NotifySetInformationKey; + registryFilter.NotifyRenameKey += registryHandler.NotifyRenameKey; + registryFilter.NotifyEnumerateKey += registryHandler.NotifyEnumerateKey; + registryFilter.NotifyEnumerateValueKey += registryHandler.NotifyEnumerateValueKey; + registryFilter.NotifyQueryKey += registryHandler.NotifyQueryKey; + registryFilter.NotifyQueryValueKey += registryHandler.NotifyQueryValueKey; + registryFilter.NotifyQueryMultipleValueKey += registryHandler.NotifyQueryMultipleValueKey; + registryFilter.NotifyCreateKey += registryHandler.NotifyCreateKey; + registryFilter.NotifyOpenKey += registryHandler.NotifyOpenKey; + registryFilter.NotifyKeyHandleClose += registryHandler.NotifyKeyHandleClose; + registryFilter.NotifyCreateKeyEx += registryHandler.NotifyCreateKeyEx; + registryFilter.NotifyOpenKeyEx += registryHandler.NotifyOpenKeyEx; + registryFilter.NotifyFlushKey += registryHandler.NotifyFlushKey; + registryFilter.NotifyLoadKey += registryHandler.NotifyLoadKey; + registryFilter.NotifyUnLoadKey += registryHandler.NotifyUnLoadKey; + registryFilter.NotifyQueryKeySecurity += registryHandler.NotifyQueryKeySecurity; + registryFilter.NotifySetKeySecurity += registryHandler.NotifySetKeySecurity; + registryFilter.NotifyRestoreKey += registryHandler.NotifyRestoreKey; + registryFilter.NotifySaveKey += registryHandler.NotifySaveKey; + registryFilter.NotifyReplaceKey += registryHandler.NotifyReplaceKey; + registryFilter.NotifyQueryKeyName += registryHandler.NotifyQueryKeyName; + + filterControl.AddFilter(registryFilter); + } + + //register the volume notification + //filterControl.VolumeControlFlag = (uint)(FilterAPI.VolumeControlFlag.GET_ATTACHED_VOLUME_INFO | FilterAPI.VolumeControlFlag.VOLUME_ATTACHED_NOTIFICATION | FilterAPI.VolumeControlFlag.VOLUME_DETACHED_NOTIFICATION); + filterControl.VolumeControlFlag = (FilterAPI.VolumeControlFlag)GlobalConfig.VolumeControlFlag; + filterControl.NotifyFilterAttachToVolume -= controlEventHandler.NotifyFilterAttachToVolume; + filterControl.NotifyFilterAttachToVolume += controlEventHandler.NotifyFilterAttachToVolume; + filterControl.NotifyFilterDetachFromVolume -= controlEventHandler.NotifyFilterDetachFromVolume; + filterControl.NotifyFilterDetachFromVolume += controlEventHandler.NotifyFilterDetachFromVolume; + + if (!filterControl.SendConfigSettingsToFilter(ref lastError)) + { + Console.WriteLine("SendConfigSettingsToFilter failed." + lastError); + return false; + } + + return true; + } + catch (Exception ex) + { + Console.WriteLine("SendConfigSettingsToFilter failed." + ex.Message); + return false; + } + + } + + public static bool StartService(out string lastError) + { + //Purchase a license key with the link: http://www.easefilter.com/Order.htm + //Email us to request a trial key: info@easefilter.com //free email is not accepted. + string licenseKey = "A93B4-B3D73-2C533-C186E-C3EC0-5BDE3"; + bool ret = false; + + lastError = string.Empty; + + try + { + ret = filterControl.StartFilter(GlobalConfig.filterType, GlobalConfig.FilterConnectionThreads, GlobalConfig.ConnectionTimeOut, licenseKey, ref lastError); + if (!ret) + { + return ret; + } + + ret = SendConfigSettingsToFilter(ref lastError); + + EventManager.WriteMessage(102, "StartFilter", EventLevel.Information, "Start filter service succeeded."); + } + catch (Exception ex) + { + EventManager.WriteMessage(104, "StartFilter", EventLevel.Error, "Start filter service failed with error " + ex.Message); + ret = false; + } + + return ret; + } + + public static bool StopService() + { + GlobalConfig.Stop(); + filterControl.StopFilter(); + + EventManager.WriteMessage(102, "StopFilter", EventLevel.Information, "Stopped filter service succeeded."); + + return true; + } + + } + +} diff --git a/Demo_Source_Code/CSharpDemo/EaseFltCSConsoleDemo/MessageInfo.cs b/Demo_Source_Code/CSharpDemo/EaseFltCSConsoleDemo/MessageInfo.cs new file mode 100644 index 0000000..45f20e0 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/EaseFltCSConsoleDemo/MessageInfo.cs @@ -0,0 +1,367 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Runtime.InteropServices; +using System.Security.Principal; +using System.IO; +using System.Text; +using System.Threading; + +using EaseFilter.CommonObjects; + +namespace EaseFltCSConsoleDemo +{ + public static class MessageInfo + { + static object displayLock = new object(); + + public static void DisplayFilterMessage(FilterAPI.MessageSendData messageSend) + { + lock (displayLock) + { + try + { + string userName = string.Empty; + string strSid = string.Empty; + + IntPtr sidBuffer = Marshal.UnsafeAddrOfPinnedArrayElement(messageSend.Sid, 0); + ConvertSidToUserNameAndStringSid(sidBuffer, out userName, out strSid); + + string processName = string.Empty; + + try + { + System.Diagnostics.Process requestProcess = System.Diagnostics.Process.GetProcessById((int)messageSend.ProcessId); + processName = requestProcess.ProcessName; + } + catch (Exception ex) + { + Console.WriteLine("Convert process id to process name failed." + ex.Message); + } + + Console.WriteLine(string.Format("\r\n\r\nId#{0}", messageSend.MessageId.ToString())); + Console.WriteLine(string.Format("TransactionTime:{0}", FormatDateTime(messageSend.TransactionTime))); + Console.WriteLine(string.Format("UserName:{0}", userName)); + Console.WriteLine(string.Format("ProcessName:{0}", processName)); + Console.WriteLine(string.Format("ProcessId:{0}", messageSend.ProcessId.ToString())); + Console.WriteLine(string.Format("ThreadId:{0}", messageSend.ThreadId.ToString())); + Console.WriteLine(string.Format("FileObject:{0}", messageSend.FileObject.ToString("X"))); + Console.WriteLine(string.Format("FsContext:{0}", messageSend.FsContext.ToString("X"))); + Console.WriteLine(string.Format("MessageType:{0}", ((FilterAPI.MessageType)messageSend.MessageType).ToString())); + Console.WriteLine(string.Format("FileName:{0}", messageSend.FileName)); + Console.WriteLine(string.Format("FileSize:{0}", messageSend.FileSize.ToString())); + Console.WriteLine(string.Format("FileAttributes:{0}", ((FileAttributes)messageSend.FileAttributes).ToString())); + Console.WriteLine(string.Format("CreationTime:{0}", FormatDateTime(messageSend.CreationTime))); + Console.WriteLine(string.Format("LastWriteTime:{0}", FormatDateTime(messageSend.LastWriteTime))); + + if (((FilterAPI.MessageType)messageSend.MessageType == FilterAPI.MessageType.PRE_CREATE) + || ((FilterAPI.MessageType)messageSend.MessageType == FilterAPI.MessageType.POST_CREATE)) + { + Console.WriteLine("---------------Start create I/O related information ---------------"); + Console.WriteLine(string.Format("DesiredAccess:(0x{0:x}){1}", messageSend.DesiredAccess, FormatDesiredAccess(messageSend.DesiredAccess))); + Console.WriteLine(string.Format("Disposition:(0x{0:x}){1}", messageSend.Disposition, ((WinData.Disposition)messageSend.Disposition).ToString())); + Console.WriteLine(string.Format("SharedAccess:{0}", ((WinData.ShareAccess)messageSend.SharedAccess).ToString())); + Console.WriteLine(string.Format("CreateOptions:(0x{0:x}){1}", messageSend.CreateOptions, FormatCreateOptions(messageSend.CreateOptions))); + + if (messageSend.Status == (uint)NtStatus.Status.Success + && ((FilterAPI.MessageType)messageSend.MessageType == FilterAPI.MessageType.POST_CREATE)) + { + //the create status is meaningful only when the status is succeeded. + Console.WriteLine(string.Format("CreateStatus:{0}", ((WinData.CreateStatus)messageSend.CreateStatus).ToString())); + } + + Console.WriteLine("---------------End create I/O related information ---------------"); + } + + Console.WriteLine(string.Format("I/O return status:{0}", FormatStatus(messageSend.Status))); + + if (messageSend.InfoClass > 0) + { + Console.WriteLine(string.Format("InfoClass:{0}", FormatInfoClass((FilterAPI.MessageType)messageSend.MessageType, messageSend.InfoClass))); + } + + if (messageSend.Length > 0) + { + Console.WriteLine(string.Format("Read/Write Offset:{0}", messageSend.Offset.ToString())); + Console.WriteLine(string.Format("Read/Write Length:{0}", messageSend.Length.ToString())); + } + + if (messageSend.DataBufferLength > 0) + { + Console.WriteLine(string.Format("Data Buffer Length:{0}", messageSend.DataBufferLength.ToString())); + Console.WriteLine(string.Format("Data:{0}", FormatDataBuffer((FilterAPI.MessageType)messageSend.MessageType, + (WinData.FileInfomationClass)messageSend.InfoClass, + messageSend.DataBufferLength, + messageSend.DataBuffer))); + } + + } + catch (Exception ex) + { + Console.WriteLine("DisplayFilterMessage failed." + ex.Message); + } + } + + return ; + } + + + static bool ConvertSidToUserNameAndStringSid(IntPtr sidBuffer, out string userName, out string userSid) + { + bool ret = true; + + IntPtr sidStringPtr = IntPtr.Zero; + string sidString = string.Empty; + + userName = string.Empty; + userSid = string.Empty; + + try + { + if (FilterAPI.ConvertSidToStringSid(sidBuffer, out sidStringPtr)) + { + sidString = Marshal.PtrToStringAuto(sidStringPtr); + SecurityIdentifier secIdentifier = new SecurityIdentifier(sidString); + IdentityReference reference = secIdentifier.Translate(typeof(NTAccount)); + userName = reference.Value; + userSid = secIdentifier.ToString(); + } + else + { + string errorMessage = "Convert sid to sid string failed, error code:" + Marshal.GetLastWin32Error(); + Console.WriteLine(errorMessage); + } + } + catch (Exception ex) + { + string errorMessage = string.Format("Convert sid to user name got exception:{0}", ex.Message); + Console.WriteLine(errorMessage); + userName = errorMessage; + ret = false; + + } + finally + { + if (sidStringPtr != null && sidStringPtr != IntPtr.Zero) + { + IntPtr res = FilterAPI.LocalFree(sidStringPtr); + } + } + + return ret; + } + + static string FormatDesiredAccess(uint desiredAccess) + { + string ret = string.Empty; + + foreach (WinData.DisiredAccess access in Enum.GetValues(typeof(WinData.DisiredAccess))) + { + if (access == (WinData.DisiredAccess)((uint)access & desiredAccess)) + { + ret += access.ToString() + "; "; + } + } + + return ret; + } + + static string FormatCreateOptions(uint createOptions) + { + string ret = string.Empty; + + foreach (WinData.CreateOptions option in Enum.GetValues(typeof(WinData.CreateOptions))) + { + if (option == (WinData.CreateOptions)((uint)option & createOptions)) + { + ret += option.ToString() + "|"; + } + } + + if (string.IsNullOrEmpty(ret)) + { + ret = "(0x)" + createOptions.ToString("X"); + } + + return ret; + } + + static string FormatDateTime(long lDateTime) + { + try + { + if (0 == lDateTime) + { + return "0"; + } + + DateTime dateTime = DateTime.FromFileTime(lDateTime); + string ret = dateTime.ToShortDateString() + " " + dateTime.ToShortTimeString(); + return ret; + } + catch (Exception ex) + { + Console.WriteLine("FormatDateTime :" + lDateTime.ToString() + " failed." + ex.Message); + return ex.Message; + } + } + + static string FormatDataBuffer(FilterAPI.MessageType messageType, WinData.FileInfomationClass infoClass, uint dataLength, byte[] data) + { + string ret = string.Empty; + + try + { + switch (messageType) + { + case FilterAPI.MessageType.PRE_SET_INFORMATION: + case FilterAPI.MessageType.POST_SET_INFORMATION: + case FilterAPI.MessageType.PRE_QUERY_INFORMATION: + case FilterAPI.MessageType.POST_QUERY_INFORMATION: + switch (infoClass) + { + case WinData.FileInfomationClass.FileRenameInformation: + { + //destination name + ret = "Destination name:" + Encoding.Unicode.GetString(data); + break; + } + case WinData.FileInfomationClass.FileDispositionInformation: + { + ret = "Delete file."; + break; + } + case WinData.FileInfomationClass.FileEndOfFileInformation: + { + long newFileSize = BitConverter.ToInt64(data, 0); + ret = "Change file size to:" + newFileSize.ToString(); + break; + } + case WinData.FileInfomationClass.FileBasicInformation: + { + WinData.FileBasicInformation basiInfo = new WinData.FileBasicInformation(); + GCHandle pinnedPacket = GCHandle.Alloc(data, GCHandleType.Pinned); + basiInfo = (WinData.FileBasicInformation)Marshal.PtrToStructure( + pinnedPacket.AddrOfPinnedObject(), typeof(WinData.FileBasicInformation)); + pinnedPacket.Free(); + + ret = "creation time:" + FormatDateTime(basiInfo.CreationTime) + " "; + ret += "last access time:" + FormatDateTime(basiInfo.LastAccessTime) + " "; + ret += "last write time:" + FormatDateTime(basiInfo.LastWriteTime) + " "; + ret += "file attributes:" + ((FileAttributes)basiInfo.FileAttributes).ToString(); + break; + } + + case WinData.FileInfomationClass.FileStandardInformation: + { + WinData.FileStandardInformation standardInfo = new WinData.FileStandardInformation(); + GCHandle pinnedPacket = GCHandle.Alloc(data, GCHandleType.Pinned); + standardInfo = (WinData.FileStandardInformation)Marshal.PtrToStructure( + pinnedPacket.AddrOfPinnedObject(), typeof(WinData.FileStandardInformation)); + pinnedPacket.Free(); + + ret = "File size:" + standardInfo.EndOfFile.ToString() + " "; + ret += "Allocation size:" + standardInfo.AllocationSize.ToString() + " "; + ret += "IsDirectory:" + standardInfo.Directory.ToString(); + break; + } + case WinData.FileInfomationClass.FileNetworkOpenInformation: + { + WinData.FileNetworkInformation networkInfo = new WinData.FileNetworkInformation(); + GCHandle pinnedPacket = GCHandle.Alloc(data, GCHandleType.Pinned); + networkInfo = (WinData.FileNetworkInformation)Marshal.PtrToStructure( + pinnedPacket.AddrOfPinnedObject(), typeof(WinData.FileNetworkInformation)); + pinnedPacket.Free(); + + ret = "creation time:" + FormatDateTime(networkInfo.CreationTime) + " "; + ret += "last access time:" + FormatDateTime(networkInfo.LastAccessTime) + " "; + ret += "last write time:" + FormatDateTime(networkInfo.LastWriteTime) + " "; + ret += "file size:" + networkInfo.FileSize.ToString() + " "; + ret += "file attributes:" + ((FileAttributes)networkInfo.FileAttributes).ToString(); + break; + } + + case WinData.FileInfomationClass.FileInternalInformation: + { + long fileId = BitConverter.ToInt64(data, 0); + ret = "FileId: (0x)" + fileId.ToString("X"); + break; + } + } + + break; + } + } + catch (Exception ex) + { + Console.WriteLine("Format data failed." + ex.Message); + ret = ex.Message; + } + + return ret; + } + + static string FormatStatus(uint status) + { + string ret = string.Empty; + + foreach (NtStatus.Status ntStatus in Enum.GetValues(typeof(NtStatus.Status))) + { + if (status == (uint)ntStatus) + { + ret = ntStatus.ToString() + "(0x" + status.ToString("X") + ")"; + } + } + + if (string.IsNullOrEmpty(ret)) + { + ret = "(0x" + status.ToString("X") + ")"; + } + + return ret; + } + + static string FormatInfoClass(FilterAPI.MessageType messageType, uint infoClass) + { + string ret = string.Empty; + + if (FilterAPI.MessageType.PRE_QUERY_SECURITY == messageType + || FilterAPI.MessageType.PRE_SET_SECURITY == messageType + || FilterAPI.MessageType.POST_QUERY_SECURITY == messageType + || FilterAPI.MessageType.POST_SET_SECURITY == messageType) + { + ret = ((WinData.SecurityInformation)(infoClass)).ToString(); + } + else if (infoClass > 0) + { + ret = ((WinData.FileInfomationClass)infoClass).ToString(); + } + else + { + ret = string.Empty; + } + + return ret; + } + + + } +} \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/EaseFltCSConsoleDemo/MonitorEventHandler.cs b/Demo_Source_Code/CSharpDemo/EaseFltCSConsoleDemo/MonitorEventHandler.cs new file mode 100644 index 0000000..4bc98af --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/EaseFltCSConsoleDemo/MonitorEventHandler.cs @@ -0,0 +1,315 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Text; +using System.Runtime.InteropServices; +using System.Security.Principal; +using System.IO; +using System.Threading; +using System.Reflection; + +using EaseFilter.FilterControl; +using EaseFilter.CommonObjects; + +namespace EaseFltCSConsoleDemo +{ + + public class MonitorEventHandler : IDisposable + { + bool disposed = false; + public MonitorEventHandler() + { + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + private void Dispose(bool disposing) + { + if (!this.disposed) + { + } + + disposed = true; + } + + ~MonitorEventHandler() + { + Dispose(false); + } + + + public void DisplayEventMessage(FileIOEventArgs fileIOEventArgs) + { + try + { + string message = string.Empty; + message +="MonitorFilter-MessageId:" + fileIOEventArgs.MessageId.ToString() + "\r\n"; + message += "UserName:" + fileIOEventArgs.UserName + "\r\n"; + message += "ProcessName:" + fileIOEventArgs.ProcessName + " (" + fileIOEventArgs.ProcessId + ")" + "\r\n"; + message += "ThreadId:" + fileIOEventArgs.ThreadId.ToString() + "\r\n"; + message += "EventName:" + fileIOEventArgs.EventName + "\r\n"; + message += "FileName:" + fileIOEventArgs.FileName + "\r\n"; + message += "FileSize:" + fileIOEventArgs.FileSize.ToString() + "\r\n"; + message += "FileAttributes:" + ((FileAttributes)fileIOEventArgs.FileAttributes).ToString() + "\r\n"; + message += "LastWriteTime:" + DateTime.FromFileTime(fileIOEventArgs.LastWriteTime).ToString("yyyy-MM-ddTHH:mm") + "\r\n"; + message += "IOStatus:" + fileIOEventArgs.IOStatusToString() + "\r\n"; + message += "Description:" + fileIOEventArgs.Description + "\r\n"; + + if ((uint)fileIOEventArgs.IoStatus >= (uint)NtStatus.Status.Error) + { + Console.BackgroundColor = ConsoleColor.Black; + Console.ForegroundColor = ConsoleColor.Red; + } + else if ((uint)fileIOEventArgs.IoStatus > (uint)NtStatus.Status.Warning) + { + Console.BackgroundColor = ConsoleColor.Black; + Console.ForegroundColor = ConsoleColor.Yellow; + } + else + { + Console.BackgroundColor = ConsoleColor.Black; + Console.ForegroundColor = ConsoleColor.White; + } + + Console.WriteLine(message); + + } + catch (Exception ex) + { + Console.WriteLine("DisplayEventMessage failed." + ex.Message); + } + + } + + /// + /// Fires this event after the file was opened, the handle is not closed. + /// + public void OnFileOpen(object sender, FileCreateEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + + /// + /// Fires this event after the new file was created, the handle is not closed. + /// + public void OnFileCreate(object sender, FileCreateEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + /// + /// Fires this event after the read IO was returned. + /// + public void OnFileRead(object sender, FileReadEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + /// + /// Fires this event after the write IO was returned. + /// + public void OnFileWrite(object sender, FileWriteEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + /// + /// Fires this event after the query file size IO was returned. + /// + public void OnQueryFileSize(object sender, FileSizeEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + /// + /// Fires this event after the query file basic information IO was returned. + /// + public void OnQueryFileBasicInfo(object sender, FileBasicInfoEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + /// + /// Fires this event after the query file standard information IO was returned. + /// + public void OnQueryFileStandardInfo(object sender, FileStandardInfoEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + /// + /// Fires this event after the query file network information IO was returned. + /// + public void OnQueryFileNetworkInfo(object sender, FileNetworkInfoEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + /// + /// Fires this event after the query file Id IO was returned. + /// + public void OnQueryFileId(object sender, FileIdEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + /// + /// Fires this event after the query file info IO was returned. + /// + /// + /// + public void OnQueryFileInfo(object sender, FileInfoArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + /// + /// Fires this event after the set file size IO was returned. + /// + public void OnSetFileSize(object sender, FileSizeEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + /// + /// Fires this event after the set file basic information was returned. + /// + public void OnSetFileBasicInfo(object sender, FileBasicInfoEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + /// + /// Fires this event after the set file standard information IO was returned. + /// + public void OnSetFileStandardInfo(object sender, FileStandardInfoEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + /// + /// Fires this event after the set file network information IO was returned. + /// + public void OnSetFileNetworkInfo(object sender, FileNetworkInfoEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + /// + /// Fires this event after the file was moved or renamed. + /// + public void OnMoveOrRenameFile(object sender, FileMoveOrRenameEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + /// + /// Fires this event after the delete IO was returned. + /// + public void OnDeleteFile(object sender, FileIOEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + /// + /// Fires this event after the set file info IO was returned. + /// + /// + /// + public void OnSetFileInfo(object sender, FileInfoArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + /// + /// Fires this event after the query file security IO was returned. + /// + public void OnQueryFileSecurity(object sender, FileSecurityEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + /// + /// Fires this event after the set file security IO was returned. + /// + public void OnSetFileSecurity(object sender, FileSecurityEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + /// + /// Fires this event after the directory enumeration query IO was returned. + /// + public void OnQueryDirectoryFile(object sender, FileQueryDirectoryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + /// + /// Fires this event after the file was cleanuped. + /// + public void OnFileHandleClose(object sender, FileIOEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + /// + /// Fires this event after the last file handle of the file was closed. + /// + public void OnFileClose(object sender, FileIOEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + + /// + /// Fires this event when a file was changed after the file handle closed + /// + public void NotifyFileWasChanged(object sender, FileChangedEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + + /// + /// Fires this event when the filter driver attached to a volume. + /// + public void OnFilterAttachToVolume(object sender, VolumeInfoEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + /// + /// Fires this event when a volume was detached from the filter driver. + /// + public void OnFilterDetachFromVolume(object sender, VolumeInfoEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + + } +} \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/EaseFltCSConsoleDemo/ProcessHandler.cs b/Demo_Source_Code/CSharpDemo/EaseFltCSConsoleDemo/ProcessHandler.cs new file mode 100644 index 0000000..dccea1c --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/EaseFltCSConsoleDemo/ProcessHandler.cs @@ -0,0 +1,168 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.IO; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Runtime.InteropServices; +using Microsoft.Win32.SafeHandles; +using System.Security.Principal; +using System.Threading; +using System.Reflection; + +using EaseFilter.FilterControl; +using EaseFilter.CommonObjects; + +namespace EaseFltCSConsoleDemo +{ + + public class ProcessHandler : IDisposable + { + + bool disposed = false; + + public ProcessHandler() + { + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + private void Dispose(bool disposing) + { + if (!this.disposed) + { + } + + disposed = true; + } + + ~ProcessHandler() + { + Dispose(false); + } + + public void DisplayEventMessage(ProcessEventArgs processArgs) + { + + try + { + string message = string.Empty; + message += "ProcessFilter-MessageId:" + processArgs.MessageId.ToString() + "\r\n"; + message += "UserName:" + processArgs.UserName + "\r\n"; + message += "ImageFileName:" + processArgs.ImageFileName + " (" + processArgs.ProcessId + ")" + "\r\n"; + message += "ThreadId:" + processArgs.ThreadId.ToString() + "\r\n"; + message += "EventName:" + processArgs.EventName + "\r\n"; + message += "IOStatus:" + processArgs.IOStatusToString() + "\r\n"; + message += "Description:" + processArgs.Description + "\r\n"; + + if ((uint)processArgs.IoStatus >= (uint)NtStatus.Status.Error) + { + Console.BackgroundColor = ConsoleColor.Black; + Console.ForegroundColor = ConsoleColor.Red; + } + else if ((uint)processArgs.IoStatus > (uint)NtStatus.Status.Warning) + { + Console.BackgroundColor = ConsoleColor.Black; + Console.ForegroundColor = ConsoleColor.Yellow; + } + else + { + Console.BackgroundColor = ConsoleColor.Black; + Console.ForegroundColor = ConsoleColor.White; + } + + Console.WriteLine(message); + + } + catch (Exception ex) + { + Console.WriteLine("DisplayEventMessage failed." + ex.Message); + } + + } + + /// + /// Fires this event when the new process was being created. + /// + public void OnProcessCreation(object sender, ProcessEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + // //test block the process creation. + // e.ReturnStatus = NtStatus.Status.AccessDenied; + } + + /// + /// Fires this event after the event was triggered. + /// + public void NotifyProcessTerminated(object sender, ProcessEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + } + + /// + /// Fires this event after the event was triggered. + /// + public void NotifyThreadCreation(object sender, ProcessEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + } + + /// + /// Fires this event after the event was triggered. + /// + public void NotifyThreadTerminated(object sender, ProcessEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + } + + /// + /// Fires this event after the event was triggered. + /// + public void NotifyProcessHandleInfo(object sender, ProcessEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + } + + /// + /// Fires this event after the event was triggered. + /// + public void NotifyThreadHandleInfo(object sender, ProcessEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + } + + } +} + diff --git a/Demo_Source_Code/CSharpDemo/EaseFltCSConsoleDemo/Program.cs b/Demo_Source_Code/CSharpDemo/EaseFltCSConsoleDemo/Program.cs new file mode 100644 index 0000000..21e7a3a --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/EaseFltCSConsoleDemo/Program.cs @@ -0,0 +1,174 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.Collections.Generic; +using System.Linq; +using System.ServiceProcess; +using System.Text; +using System.IO; +using System.Reflection; +using System.Configuration.Install; + +using EaseFilter.FilterControl; +using EaseFilter.CommonObjects; + +namespace EaseFltCSConsoleDemo +{ + static class program + { + /// + /// The main entry point for the application. + /// + static void Main(string[] args) + { + + try + { + string lastError = string.Empty; + GlobalConfig.filterType = FilterAPI.FilterType.REGISTRY_FILTER | FilterAPI.FilterType.PROCESS_FILTER | FilterAPI.FilterType.CONTROL_FILTER | FilterAPI.FilterType.MONITOR_FILTER; + + if (Environment.UserInteractive) + { + if (args.Length > 0) + { + string command = args[0]; + switch (command.ToLower()) + { + case "-installdriver": + { + bool ret = FilterAPI.InstallDriver(); + + if (!ret) + { + Console.WriteLine("Install driver failed:" + FilterAPI.GetLastErrorMessage()); + } + + break; + } + + case "-uninstalldriver": + { + FilterWorker.StopService(); + + bool ret = FilterAPI.UnInstallDriver(); + + if (!ret) + { + Console.WriteLine("UnInstall driver failed:" + FilterAPI.GetLastErrorMessage()); + } + + break; + } + + case "-installservice": + { + try + { + ManagedInstallerClass.InstallHelper(new string[] { Assembly.GetExecutingAssembly().Location }); + } + catch (Exception ex) + { + Console.WriteLine("Install service failed:" + ex.Message); + } + + break; + } + + case "-uninstallservice": + { + try + { + ManagedInstallerClass.InstallHelper(new string[] { "/u", Assembly.GetExecutingAssembly().Location }); + } + catch (Exception ex) + { + Console.WriteLine("UnInstall service failed:" + ex.Message); + } + + break; + } + + case "-console": + { + try + { + Console.WriteLine("Starting EaseFilter console application, the filter rule will be loaded from the config file EaseFltCSConsoleDemo.exe.config."); + + if(!FilterWorker.StartService(out lastError)) + { + Console.WriteLine("\n\nStart service failed." + lastError); + return; + } + + Console.WriteLine("\n\nPress any key to stop program"); + Console.Read(); + FilterWorker.StopService(); + } + catch (Exception ex) + { + Console.WriteLine("Start EaseFilter service failed:" + ex.Message); + } + + break; + } + + default: Console.WriteLine("The command " + command + " doesn't exist"); PrintUsage(); break; + + } + + } + else + { + PrintUsage(); + } + + } + else + { + Console.WriteLine("Starting EaseFilter windows service..."); + EaseFilterService service = new EaseFilterService(); + ServiceBase.Run(service); + + } + } + catch (Exception ex) + { + EventManager.WriteMessage(132, "EaseFilterService", EventLevel.Error, "EaseFilter failed with error " + ex.Message); + } + finally + { + Console.WriteLine("Exiting EaseFilter service."); + GlobalConfig.Stop(); + } + + + } + + static void PrintUsage() + { + Console.WriteLine("Usage: EaseFltCSConsoleDemo command"); + Console.WriteLine("Commands:"); + Console.WriteLine("-InstallDriver --Install EaseFilter filter driver."); + Console.WriteLine("-UninstallDriver --Uninstall EaseFilter filter driver."); + Console.WriteLine("-InstallService --Install EaseFilter Windows service."); + Console.WriteLine("-UnInstallService ---Uninstall EaseFilter Windows service."); + Console.WriteLine("-Console ----start the console application."); + } + + } +} diff --git a/Demo_Source_Code/CSharpDemo/EaseFltCSConsoleDemo/Properties/AssemblyInfo.cs b/Demo_Source_Code/CSharpDemo/EaseFltCSConsoleDemo/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..2162c02 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/EaseFltCSConsoleDemo/Properties/AssemblyInfo.cs @@ -0,0 +1,37 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("CSharpConsoleDemo")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("CSharpConsoleDemo")] +[assembly: AssemblyCopyright("Copyright © 2013")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("c7006cc7-8a58-4483-ac2c-e914fdc429a4")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("5.2.3.2001")] +//[assembly: AssemblyFileVersion("1.0.0.0")] + diff --git a/Demo_Source_Code/CSharpDemo/EaseFltCSConsoleDemo/RegistryHandler.cs b/Demo_Source_Code/CSharpDemo/EaseFltCSConsoleDemo/RegistryHandler.cs new file mode 100644 index 0000000..a9506f8 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/EaseFltCSConsoleDemo/RegistryHandler.cs @@ -0,0 +1,862 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.IO; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Runtime.InteropServices; +using Microsoft.Win32.SafeHandles; +using System.Security.Principal; +using System.Threading; + +using EaseFilter.FilterControl; +using EaseFilter.CommonObjects; + +namespace EaseFltCSConsoleDemo +{ + public enum VALUE_DATA_TYPE : uint + { + REG_NONE = 0, + REG_SZ = 1, + REG_EXPAND_SZ = 2, + REG_BINARY = 3, + REG_DWORD = 4, + REG_DWORD_BIG_ENDIAN = 5, + REG_LINK = 6, + REG_MULTI_SZ = 7, + REG_RESOURCE_LIST = 8, + REG_FULL_RESOURCE_DESCRIPTOR = 9, + REG_RESOURCE_REQUIREMENTS_LIST = 10, + REG_QWORD = 11 + } + + public enum KEY_VALUE_INFORMATION_CLASS : uint + { + KeyValueBasicInformation = 0, + KeyValueFullInformation = 1, + KeyValuePartialInformation = 2, + KeyValueFullInformationAlign64 = 3, + KeyValuePartialInformationAlign64 = 4, + MaxKeyValueInfoClass = 5 + } + + public struct KEY_VALUE_BASIC_INFORMATION + { + public uint TitleIndex; + public uint Type; + public uint NameLength; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 65536 - 12)] + public byte[] Name; + } + public struct KEY_VALUE_FULL_INFORMATION + { + public uint TitleIndex; + public uint Type; + public uint DataOffset; + public uint DataLength; + public uint NameLength; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 65536 - 20)] + public byte[] Name; + } + + public struct KEY_VALUE_PARTIAL_INFORMATION + { + public uint TitleIndex; + public uint Type; + public uint DataLength; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 65536 - 12 )] + public byte[] Data; + } + + public struct KEY_VALUE_ENTRY + { + public uint NextEntryOffset; + public uint ValueNameLength; + public uint DataType; + public uint DataLength; + public byte[] ValueName; + //public byte[] Data; + } + + public enum KEY_SET_INFORMATION_CLASS : uint + { + KeyWriteTimeInformation = 0, + KeyWow64FlagsInformation, + KeyControlFlagsInformation, + KeySetVirtualizationInformation, + KeySetDebugInformation, + KeySetHandleTagsInformation, + MaxKeySetInfoClass // MaxKeySetInfoClass should always be the last enum + } + public enum KEY_INFORMATION_CLASS : uint + { + KeyBasicInformation = 0, + KeyNodeInformation, + KeyFullInformation, + KeyNameInformation, + KeyCachedInformation, + KeyFlagsInformation, + KeyVirtualizationInformation, + KeyHandleTagsInformation, + KeyTrustInformation, + KeyLayerInformation, + MaxKeyInfoClass + } + + public struct KEY_BASIC_INFORMATION + { + public long LastWriteTime; + public uint TitleIndex; + public uint NameLength; + public byte[] Name; + } + + public struct KEY_NODE_INFORMATION + { + public long LastWriteTime; + public uint TitleIndex; + public uint ClassOffset; + public uint ClassLength; + public uint NameLength; + public byte[] Name; + } + + public struct KEY_FULL_INFORMATION + { + public long LastWriteTime; + public uint TitleIndex; + public uint ClassOffset; + public uint ClassLength; + public uint SubKeys; + public uint MaxNameLen; + public uint MaxClassLen; + public uint Values; + public uint MaxValueNameLen; + public uint MaxValueDataLen; + public byte[] Class; + } + + public struct KEY_NAME_INFORMATION + { + public uint NameLength; + public byte[] Name; + } + + public struct KEY_CACHED_INFORMATION + { + public long LastWriteTime; + public uint TitleIndex; + public uint SubKeys; + public uint MaxNameLen; + public uint MaxClassLen; + public uint Values; + public uint MaxValueNameLen; + public uint MaxValueDataLen; + public uint NameLength; + } + + public struct KEY_VIRTUALIZATION_INFORMATION + { + public bool VirtualizationCandidate; + public bool VirtualizationEnabled; + public bool VirtualTarget; + public bool VirtualStore; + public bool VirtualSource; + } + + public enum REG_ACCESS_MASK : uint + { + KEY_QUERY_VALUE = 1, + KEY_SET_VALUE = 2, + KEY_CREATE_SUB_KEY = 4, + KEY_ENUMERATE_SUB_KEYS = 8, + KEY_NOTIFY = 16, + KEY_CREATE_LINK = 32, + KEY_WRITE = 131078, + KEY_EXECUTE = 131097, + KEY_READ = 131097, + KEY_ALL_ACCESS = 983103, + } + + public enum REG_CREATE_OPTIONS : uint + { + REG_OPTION_VOLATILE = 0x00000001, // Key is not preserved when system is rebooted + REG_OPTION_CREATE_LINK = 0x00000002, // Created key is a symbolic link + REG_OPTION_BACKUP_RESTORE = 0x00000004, // open for backup or restore special access rules privilege required + REG_OPTION_OPEN_LINK = 0x00000008, // Open symbolic link + } + + public enum REG_DISPOSITION + { + REG_CREATED_NEW_KEY = 0x00000001, // New Registry Key created + REG_OPENED_EXISTING_KEY =0x00000002, // Existing Key opened + } + + public class RegistryHandler + { + bool disposed = false; + public RegistryHandler() + { + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + private void Dispose(bool disposing) + { + if (!this.disposed) + { + } + + disposed = true; + } + + ~RegistryHandler() + { + Dispose(false); + } + + public void DisplayEventMessage(RegistryEventArgs registryEventArgs) + { + try + { + string message = string.Empty; + message += "RegistryFilter-MessageId:" + registryEventArgs.MessageId.ToString() + "\r\n"; + message += "UserName:" + registryEventArgs.UserName + "\r\n"; + message += "ProcessName:" + registryEventArgs.ProcessName + " (" + registryEventArgs.ProcessId + ")" + "\r\n"; + message += "ThreadId:" + registryEventArgs.ThreadId.ToString() + "\r\n"; + message += "EventName:" + registryEventArgs.EventName + "\r\n"; + message += "FileName:" + registryEventArgs.FileName + "\r\n"; + message += "IOStatus:" + registryEventArgs.IOStatusToString() + "\r\n"; + message += "Description:" + registryEventArgs.Description + "\r\n"; + + if ((uint)registryEventArgs.IoStatus >= (uint)NtStatus.Status.Error) + { + Console.BackgroundColor = ConsoleColor.Black; + Console.ForegroundColor = ConsoleColor.Red; + } + else if ((uint)registryEventArgs.IoStatus > (uint)NtStatus.Status.Warning) + { + Console.BackgroundColor = ConsoleColor.Black; + Console.ForegroundColor = ConsoleColor.Yellow; + } + else + { + Console.BackgroundColor = ConsoleColor.Black; + Console.ForegroundColor = ConsoleColor.White; + } + + Console.WriteLine(message); + + } + catch (Exception ex) + { + Console.WriteLine("DisplayEventMessage failed." + ex.Message); + } + + } + + /// + /// Fires this event when the register registry event was triggered. + /// + public void OnPreQueryValueKey(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + // //test block the registry event. + // e.ReturnStatus = NtStatus.Status.AccessDenied; + + KEY_VALUE_INFORMATION_CLASS keyValuseInformationClass = (KEY_VALUE_INFORMATION_CLASS)e.InfoClass; + + if (e.FileName.IndexOf("EaseFilter") > 0) + { + + //below code is to demo how to complete pre-callback registry call with our own data. + switch (keyValuseInformationClass) + { + case KEY_VALUE_INFORMATION_CLASS.KeyValueBasicInformation: + { + //public struct KEY_VALUE_BASIC_INFORMATION + // { + // public uint TitleIndex; + // public uint Type; + // public uint NameLength; + // public byte[] Name; + // } + + uint titleIndex = 0; + uint type = (uint)VALUE_DATA_TYPE.REG_DWORD; + byte[] valueName = Encoding.Unicode.GetBytes("value1"); + uint valueNameLength = (uint)valueName.Length; + + MemoryStream ms = new MemoryStream(); + BinaryWriter bw = new BinaryWriter(ms); + bw.Write(titleIndex); + bw.Write(type); + bw.Write(valueNameLength); + bw.Write(valueName); + + e.ReturnDataBuffer = ms.ToArray(); + e.IsDataModified = true; + + break; + } + case KEY_VALUE_INFORMATION_CLASS.KeyValueFullInformation: + { + //KeyValueFullInformation class structure + //public uint TitleIndex; + //public uint Type; + //public uint DataOffset; + //public uint DataLength; + //public uint NameLength; + //public byte[] Name; + + uint titleIndex = 0; + uint type = (uint)VALUE_DATA_TYPE.REG_DWORD; + uint testData = 12345; + uint testDataLength = sizeof(uint); + byte[] valueName = Encoding.Unicode.GetBytes("value1"); + uint valueNameLength = (uint)valueName.Length; + uint dataOffset = 5 * sizeof(uint) + valueNameLength; + + MemoryStream ms = new MemoryStream(); + BinaryWriter bw = new BinaryWriter(ms); + bw.Write(titleIndex); + bw.Write(type); + bw.Write(dataOffset); + bw.Write(testDataLength); + bw.Write(valueNameLength); + bw.Write(valueName); + bw.Write(testData); + + e.ReturnDataBuffer = ms.ToArray(); + e.IsDataModified = true; + + break; + } + case KEY_VALUE_INFORMATION_CLASS.KeyValuePartialInformation: + { + // public struct KEY_VALUE_PARTIAL_INFORMATION + //{ + // public uint TitleIndex; + // public uint Type; + // public uint DataLength; + // public byte[] Data; + //} + + uint titleIndex = 0; + uint type = (uint)VALUE_DATA_TYPE.REG_DWORD; + uint testData = 12345; + uint testDataLength = sizeof(uint); + + MemoryStream ms = new MemoryStream(); + BinaryWriter bw = new BinaryWriter(ms); + + bw.Write(titleIndex); + bw.Write(type); + bw.Write(testDataLength); + bw.Write(testData); + + e.ReturnDataBuffer = ms.ToArray(); + e.IsDataModified = true; + + break; + } + + + default: break; + } + } + + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void OnPreDeleteKey(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + // //test block the registry event. + // e.ReturnStatus = NtStatus.Status.AccessDenied; + } + + /// + /// Fires this event when the register registry event was triggered. + /// + public void OnPreSetValueKey(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + // //test block the registry event. + // e.ReturnStatus = NtStatus.Status.AccessDenied; + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void OnPreDeleteValueKey(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + // //test block the registry event. + // e.ReturnStatus = NtStatus.Status.AccessDenied; + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void OnPreSetInformationKey(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + // //test block the registry event. + // e.ReturnStatus = NtStatus.Status.AccessDenied; + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void OnPreRenameKey(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + // //test block the registry event. + // e.ReturnStatus = NtStatus.Status.AccessDenied; + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void OnPreEnumerateKey(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + // //test block the registry event. + // e.ReturnStatus = NtStatus.Status.AccessDenied; + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void OnPreEnumerateValueKey(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + // //test block the registry event. + // e.ReturnStatus = NtStatus.Status.AccessDenied; + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void OnPreQueryKey(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + // //test block the registry event. + // e.ReturnStatus = NtStatus.Status.AccessDenied; + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void OnPreQueryMultipleValueKey(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + // //test block the registry event. + // e.ReturnStatus = NtStatus.Status.AccessDenied; + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void OnPreCreateKey(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + // //test block the registry event. + // e.ReturnStatus = NtStatus.Status.AccessDenied; + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void OnPreOpenKey(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + // //test block the registry event. + // e.ReturnStatus = NtStatus.Status.AccessDenied; + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void OnPreKeyHandleClose(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + // //test block the registry event. + // e.ReturnStatus = NtStatus.Status.AccessDenied; + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void OnPreCreateKeyEx(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + // //test block the registry event. + // e.ReturnStatus = NtStatus.Status.AccessDenied; + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void OnPreOpenKeyEx(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + // //test block the registry event. + // e.ReturnStatus = NtStatus.Status.AccessDenied; + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void OnPreFlushKey(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + // //test block the registry event. + // e.ReturnStatus = NtStatus.Status.AccessDenied; + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void OnPreLoadKey(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + // //test block the registry event. + // e.ReturnStatus = NtStatus.Status.AccessDenied; + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void OnPreUnLoadKey(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + // //test block the registry event. + // e.ReturnStatus = NtStatus.Status.AccessDenied; + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void OnPreQueryKeySecurity(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + // //test block the registry event. + // e.ReturnStatus = NtStatus.Status.AccessDenied; + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void OnPreSetKeySecurity(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + // //test block the registry event. + // e.ReturnStatus = NtStatus.Status.AccessDenied; + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void OnPreRestoreKey(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + // //test block the registry event. + // e.ReturnStatus = NtStatus.Status.AccessDenied; + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void OnPreSaveKey(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + // //test block the registry event. + // e.ReturnStatus = NtStatus.Status.AccessDenied; + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void OnPreReplaceKey(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + // //test block the registry event. + // e.ReturnStatus = NtStatus.Status.AccessDenied; + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void OnPreQueryKeyName(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + // //test block the registry event. + // e.ReturnStatus = NtStatus.Status.AccessDenied; + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void NotifyDeleteKey(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void NotifySetValueKey(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void NotifyDeleteValueKey(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void NotifySetInformationKey(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void NotifyRenameKey(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void NotifyEnumerateKey(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void NotifyEnumerateValueKey(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void NotifyQueryKey(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void NotifyQueryValueKey(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void NotifyQueryMultipleValueKey(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void NotifyCreateKey(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void NotifyOpenKey(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void NotifyKeyHandleClose(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void NotifyCreateKeyEx(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void NotifyOpenKeyEx(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void NotifyFlushKey(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void NotifyLoadKey(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void NotifyUnLoadKey(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void NotifyQueryKeySecurity(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void NotifySetKeySecurity(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void NotifyRestoreKey(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void NotifySaveKey(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void NotifyReplaceKey(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void NotifyQueryKeyName(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + } + + + + } +} diff --git a/Demo_Source_Code/CSharpDemo/EaseFltCSConsoleDemo/ServiceInstaller.cs b/Demo_Source_Code/CSharpDemo/EaseFltCSConsoleDemo/ServiceInstaller.cs new file mode 100644 index 0000000..646d2a4 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/EaseFltCSConsoleDemo/ServiceInstaller.cs @@ -0,0 +1,57 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.ComponentModel; +using System.Configuration.Install; +using System.ServiceProcess; + +using EaseFilter.CommonObjects; + +namespace EaseFltCSConsoleDemo +{ + [RunInstaller(true)] + public class WindowsServiceInstaller : Installer + { + /// + /// Public Constructor for WindowsServiceInstaller. + /// - Put all of your Initialization code here. + /// + public WindowsServiceInstaller() + { + ServiceProcessInstaller serviceProcessInstaller = new ServiceProcessInstaller(); + ServiceInstaller serviceInstaller = new ServiceInstaller(); + + //# Service Account Information + serviceProcessInstaller.Account = ServiceAccount.LocalSystem; + serviceProcessInstaller.Username = null; + serviceProcessInstaller.Password = null; + + //# Service Information + serviceInstaller.DisplayName = "EaseFilter Service"; + serviceInstaller.StartType = ServiceStartMode.Automatic; + + // This must be identical to the WindowsService.ServiceBase name + // set in the constructor of WindowsService.cs + serviceInstaller.ServiceName = "EaseFilter Service"; + serviceInstaller.Description = "EaseFilter File System Service"; + + this.Installers.Add(serviceProcessInstaller); + this.Installers.Add(serviceInstaller); + } + } +} diff --git a/Demo_Source_Code/CSharpDemo/EaseFltCSConsoleDemo/app.config b/Demo_Source_Code/CSharpDemo/EaseFltCSConsoleDemo/app.config new file mode 100644 index 0000000..a80813a --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/EaseFltCSConsoleDemo/app.config @@ -0,0 +1,3 @@ + + + diff --git a/Demo_Source_Code/CSharpDemo/FileMonitor/FileMonitor.csproj b/Demo_Source_Code/CSharpDemo/FileMonitor/FileMonitor.csproj new file mode 100644 index 0000000..ed72ae0 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FileMonitor/FileMonitor.csproj @@ -0,0 +1,176 @@ + + + + Debug + x86 + 8.0.30703 + 2.0 + {F50E9F98-5BFA-4CF2-9373-0D8E0A623E60} + WinExe + Properties + FileMonitor + FileMonitor + v4.5 + + + 512 + SAK + SAK + SAK + SAK + + + AnyCPU + true + full + false + ..\..\..\Release\ + DEBUG;TRACE + prompt + 4 + false + false + + + AnyCPU + pdbonly + true + ..\..\..\Release\ + TRACE + prompt + 4 + false + + + text_view.ico + + + true + ..\..\Release\ + DEBUG;TRACE + full + AnyCPU + ..\..\..\Release\FileMonitor.exe.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + false + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + false + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false + false + false + + + ..\..\Release\ + TRACE + true + pdbonly + AnyCPU + ..\..\..\Release\FileMonitor.exe.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + false + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false + false + false + + + app.manifest + + + + + + + + + + + + + + + + + + + + + Form + + + MonitorForm.cs + + + + + Form + + + MonitorUnitTest.cs + + + MonitorForm.cs + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + True + Resources.resx + True + + + MonitorUnitTest.cs + + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + + + + + + {34CB783E-DDA2-4CE3-80BC-37B25AA33E5F} + CommonObjects + + + {21540012-A296-45CE-8D35-3EA5A07B32A6} + FilterControl + + + + + + + + + + + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/FileMonitor/FileMonitor.csproj.user b/Demo_Source_Code/CSharpDemo/FileMonitor/FileMonitor.csproj.user new file mode 100644 index 0000000..8fbe371 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FileMonitor/FileMonitor.csproj.user @@ -0,0 +1,6 @@ + + + + true + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/FileMonitor/FileMonitor.vs2019.csproj b/Demo_Source_Code/CSharpDemo/FileMonitor/FileMonitor.vs2019.csproj new file mode 100644 index 0000000..35104a7 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FileMonitor/FileMonitor.vs2019.csproj @@ -0,0 +1,205 @@ + + + + Debug + x86 + 8.0.30703 + 2.0 + {F50E9F98-5BFA-4CF2-9373-0D8E0A623E60} + WinExe + Properties + FileMonitor + FileMonitor + v4.5 + + + 512 + SAK + SAK + SAK + SAK + + + AnyCPU + true + full + false + ..\..\..\Release\ + DEBUG;TRACE + prompt + 4 + false + false + + + AnyCPU + pdbonly + true + ..\..\..\Release\ + TRACE + prompt + 4 + false + + + text_view.ico + + + true + ..\..\Release\ + DEBUG;TRACE + full + AnyCPU + ..\..\..\Release\FileMonitor.exe.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + false + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + false + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false + false + false + + + ..\..\Release\ + TRACE + true + pdbonly + AnyCPU + ..\..\..\Release\FileMonitor.exe.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + false + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false + false + + + app.manifest + + + true + bin\ARM64\Debug\ + DEBUG;TRACE + full + ARM64 + false + 7.3 + prompt + MinimumRecommendedRules.ruleset + false + false + + + bin\ARM64\Release\ + TRACE + true + pdbonly + ARM64 + 7.3 + prompt + MinimumRecommendedRules.ruleset + false + false + + + + + + + + + + + + + + + + + + + + + Form + + + MonitorForm.cs + + + + + Form + + + MonitorUnitTest.cs + + + Form + + + TrayForm.cs + + + MonitorForm.cs + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + True + Resources.resx + True + + + MonitorUnitTest.cs + + + TrayForm.cs + + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + + + + + + {21540012-A296-45CE-8D35-3EA5A07B32A6} + FilterControl.vs2019 + + + + + + + + + + + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/FileMonitor/Monitor.ico b/Demo_Source_Code/CSharpDemo/FileMonitor/Monitor.ico new file mode 100644 index 0000000..6a4a46c Binary files /dev/null and b/Demo_Source_Code/CSharpDemo/FileMonitor/Monitor.ico differ diff --git a/Demo_Source_Code/CSharpDemo/FileMonitor/MonitorEventHandler.cs b/Demo_Source_Code/CSharpDemo/FileMonitor/MonitorEventHandler.cs new file mode 100644 index 0000000..fac0e29 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FileMonitor/MonitorEventHandler.cs @@ -0,0 +1,618 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; +using System.Runtime.InteropServices; +using System.Security.Principal; +using System.IO; +using System.Threading; +using System.Reflection; + +using EaseFilter.FilterControl; +using EaseFilter.CommonObjects; + +namespace FileMonitor +{ + + public class MonitorEventHandler : IDisposable + { + + FastListView listView_Message = null; + Thread messageThread = null; + Queue messageQueue = new Queue(); + + AutoResetEvent autoEvent = new AutoResetEvent(false); + bool disposed = false; + + + public MonitorEventHandler(FastListView lvMessage) + { + this.listView_Message = lvMessage; + InitListView(); + messageThread = new Thread(new ThreadStart(ProcessMessage)); + messageThread.Name = "ProcessMessage"; + messageThread.Start(); + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + private void Dispose(bool disposing) + { + if (!this.disposed) + { + } + + autoEvent.Set(); + messageThread.Abort(); + disposed = true; + } + + ~MonitorEventHandler() + { + Dispose(false); + } + + public void InitListView() + { + messageQueue.Clear(); + //init ListView control + listView_Message.Clear(); //clear control + //create column header for ListView + listView_Message.Columns.Add("Id#", 40, System.Windows.Forms.HorizontalAlignment.Left); + listView_Message.Columns.Add("Time", 120, System.Windows.Forms.HorizontalAlignment.Left); + listView_Message.Columns.Add("UserName", 150, System.Windows.Forms.HorizontalAlignment.Left); + listView_Message.Columns.Add("ProcessName(PID)", 100, System.Windows.Forms.HorizontalAlignment.Left); + listView_Message.Columns.Add("ThreadId", 60, System.Windows.Forms.HorizontalAlignment.Left); + listView_Message.Columns.Add("EventName", 160, System.Windows.Forms.HorizontalAlignment.Left); + listView_Message.Columns.Add("FileObject", 100, System.Windows.Forms.HorizontalAlignment.Left); + listView_Message.Columns.Add("FileName", 350, System.Windows.Forms.HorizontalAlignment.Left); + listView_Message.Columns.Add("FileSize", 70, System.Windows.Forms.HorizontalAlignment.Left); + listView_Message.Columns.Add("FileAttributes", 70, System.Windows.Forms.HorizontalAlignment.Left); + listView_Message.Columns.Add("LastWriteTime", 120, System.Windows.Forms.HorizontalAlignment.Left); + listView_Message.Columns.Add("IO Status", 100, System.Windows.Forms.HorizontalAlignment.Left); + listView_Message.Columns.Add("RemoteIP",100, System.Windows.Forms.HorizontalAlignment.Left); + listView_Message.Columns.Add("Description", 500, System.Windows.Forms.HorizontalAlignment.Left); + } + + public void DisplayEventMessage(FileIOEventArgs fileIOEventArgs) + { + if (GlobalConfig.OutputMessageToConsole) + { + lock (messageQueue) + { + if (messageQueue.Count > GlobalConfig.MaximumFilterMessages) + { + messageQueue.Clear(); + } + + messageQueue.Enqueue(fileIOEventArgs); + } + + autoEvent.Set(); + } + + } + + + void ProcessMessage() + { + int waitTimeout = 2000; //2seconds + List itemList = new List(); + + WaitHandle[] waitHandles = new WaitHandle[] { autoEvent, GlobalConfig.stopEvent }; + + while (GlobalConfig.isRunning) + { + try + { + if (messageQueue.Count == 0) + { + int result = WaitHandle.WaitAny(waitHandles, waitTimeout); + if (!GlobalConfig.isRunning) + { + return; + } + } + + System.Diagnostics.Stopwatch stopWatch = new System.Diagnostics.Stopwatch(); + stopWatch.Start(); + + while (messageQueue.Count > 0) + { + FileIOEventArgs fileIOEventArgs = null; + + lock (messageQueue) + { + fileIOEventArgs = (FileIOEventArgs)messageQueue.Dequeue(); + } + + if (GlobalConfig.DisableDirIO && (fileIOEventArgs.FileAttributes & (uint)FileAttributes.Directory) == (uint)FileAttributes.Directory) + { + //don't display the directory IO + continue; + } + + string[] filterMessages = new string[0]; + ListViewItem lvItem = GetFilterMessage(fileIOEventArgs, ref filterMessages); + + if (null == lvItem) + { + //no display message. + continue; + } + + if (GlobalConfig.EnableLogTransaction) + { + LogTrasaction(filterMessages); + } + + if (GlobalConfig.OutputMessageToConsole) + { + itemList.Add(lvItem); + + if (itemList.Count > GlobalConfig.MaximumFilterMessages) + { + AddItemToList(itemList); + itemList.Clear(); + + Thread.Sleep(1000); + } + } + + } + + if (itemList.Count > 0) + { + AddItemToList(itemList); + itemList.Clear(); + } + } + catch (Exception ex) + { + EventManager.WriteMessage(190, "ProcessMessage", EventLevel.Error, "ProcessMessage failed with error " + ex.Message); + } + + } + + + } + + public void LoadMessageFromLogToConsole() + { + if (listView_Message == null) + { + return; + } + + try + { + Assembly assembly = System.Reflection.Assembly.GetEntryAssembly(); + string assemblyPath = Path.GetDirectoryName(assembly.Location); + + string filterMessageLogName = GlobalConfig.FilterMessageLogName; + string logFileName = Path.Combine(assemblyPath, filterMessageLogName); + + if (!File.Exists(logFileName)) + { + return; + } + + string[] logMessage = File.ReadAllLines(logFileName); + List itemList = new List(); + + foreach (string itemStr in logMessage) + { + if (itemStr.Trim().Length > 0) + { + string[] listData = itemStr.Split(new char[] { '|' }); + if (listData.Length >= listView_Message.Columns.Count) + { + ListViewItem lvItem = new ListViewItem(listData, 0); + + uint status = 0; + string statusStr = listData[listView_Message.Columns.Count - 2]; + int index1 = statusStr.IndexOf('('); + int index2 = statusStr.IndexOf(')'); + + if (index1 >= 0 && index2 > 2) + { + statusStr = statusStr.Substring(index1 + 3, index2 - index1 - 3); + uint.TryParse(statusStr, System.Globalization.NumberStyles.HexNumber, null, out status); + + if (status >= (uint)NtStatus.Status.Error) + { + lvItem.BackColor = Color.LightGray; + lvItem.ForeColor = Color.Red; + } + else if (status > (uint)NtStatus.Status.Warning) + { + lvItem.BackColor = Color.LightGray; + lvItem.ForeColor = Color.Yellow; + } + } + + itemList.Add(lvItem); + } + } + } + + if (itemList.Count > 0) + { + listView_Message.Items.Clear(); + AddItemToList(itemList); + } + + } + catch (Exception ex) + { + EventManager.WriteMessage(265, "LoadLogMessage", EventLevel.Error, "Load log message failed with error " + ex.Message); + } + } + + public static void LogTrasaction(string[] filterMessages) + { + try + { + Assembly assembly = System.Reflection.Assembly.GetEntryAssembly(); + string assemblyPath = Path.GetDirectoryName(assembly.Location); + + string filterMessageLogName = GlobalConfig.FilterMessageLogName; + + string logFileName = Path.Combine(assemblyPath, filterMessageLogName); + string logFolder = Path.GetDirectoryName(logFileName); + + if (!Directory.Exists(logFolder)) + { + Directory.CreateDirectory(logFolder); + } + + string logMessage = string.Empty; + + for (int i = 0; i < filterMessages.Length; i++) + { + logMessage += filterMessages[i].Trim() + "|"; + } + + if (logMessage.Length > 0) + { + File.AppendAllText(logFileName, logMessage + "\r\n"); + + FileInfo fileInfo = new FileInfo(logFileName); + + if (fileInfo.Length > GlobalConfig.FilterMessageLogFileSize) + { + File.Delete(logFileName + ".bak"); + File.Move(logFileName, logFileName + ".bak"); + } + } + } + catch (Exception ex) + { + EventManager.WriteMessage(172, "LogTrasaction", EventLevel.Error, "Log filter message failed with error " + ex.Message); + } + + } + + void AddItemToList(List itemList) + { + if (itemList.Count < 1) + { + return; + } + + if (listView_Message.InvokeRequired) + { + listView_Message.Invoke(new MethodInvoker(delegate { AddItemToList(itemList); })); + } + else + { + + while (listView_Message.Items.Count > 0 && listView_Message.Items.Count + itemList.Count > GlobalConfig.MaximumFilterMessages) + { + //the message records in the list view reached to the maximum value, remove the first one till the record less than the maximum value. + listView_Message.Items.RemoveAt(0); + } + + + if (itemList.Count > 0) + { + listView_Message.Items.AddRange(itemList.ToArray()); + // listView_Message.EnsureVisible(listView_Message.Items.Count - 1); + + itemList.Clear(); + + } + } + } + + ListViewItem GetFilterMessage(FileIOEventArgs fileIOEventArgs, ref string[] filterMessages) + { + ListViewItem lvItem = new ListViewItem(); + + try + { + string[] listData = new string[listView_Message.Columns.Count]; + int col = 0; + listData[col++] = fileIOEventArgs.MessageId.ToString(); + listData[col++] = DateTime.FromFileTime(fileIOEventArgs.TransactionTime).ToString("yyyy-MM-ddTHH:mm"); + if (fileIOEventArgs.IsRemoteAccess) + { + listData[col++] = fileIOEventArgs.UserName + " IsRemoteAccess " + fileIOEventArgs.RemoteIp; ; + } + else + { + listData[col++] = fileIOEventArgs.UserName; + } + listData[col++] = fileIOEventArgs.ProcessName + " (" + fileIOEventArgs.ProcessId + ")"; + listData[col++] = fileIOEventArgs.ThreadId.ToString(); + listData[col++] = fileIOEventArgs.EventName; + listData[col++] = fileIOEventArgs.FileObject.ToString("X"); + listData[col++] = fileIOEventArgs.FileName; + listData[col++] = fileIOEventArgs.FileSize.ToString(); + listData[col++] = ((FileAttributes)fileIOEventArgs.FileAttributes).ToString(); + listData[col++] = DateTime.FromFileTime(fileIOEventArgs.LastWriteTime).ToString("yyyy-MM-ddTHH:mm"); + listData[col++] = fileIOEventArgs.IOStatusToString(); + listData[col++] = fileIOEventArgs.RemoteIp; + listData[col++] = fileIOEventArgs.Description; + + filterMessages = listData; + + lvItem = new ListViewItem(listData, 0); + + if ((uint)fileIOEventArgs.IoStatus >= (uint)NtStatus.Status.Error) + { + lvItem.BackColor = Color.LightGray; + lvItem.ForeColor = Color.Red; + } + else if ((uint)fileIOEventArgs.IoStatus > (uint)NtStatus.Status.Warning) + { + lvItem.BackColor = Color.LightGray; + lvItem.ForeColor = Color.Yellow; + } + + + } + catch (Exception ex) + { + EventManager.WriteMessage(445, "GetFilterMessage", EventLevel.Error, "Add callback message failed." + ex.Message); + lvItem = null; + } + + return lvItem; + } + + /// + /// Fires this event after the file was opened, the handle is not closed. + /// + public void OnFileOpen(object sender, FileCreateEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + + /// + /// Fires this event after the new file was created, the handle is not closed. + /// + public void OnFileCreate(object sender, FileCreateEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + /// + /// Fires this event after the read IO was returned. + /// + public void OnFileRead(object sender, FileReadEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + /// + /// Fires this event after the write IO was returned. + /// + public void OnFileWrite(object sender, FileWriteEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + /// + /// Fires this event after the query file size IO was returned. + /// + public void OnQueryFileSize(object sender, FileSizeEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + /// + /// Fires this event after the query file basic information IO was returned. + /// + public void OnQueryFileBasicInfo(object sender, FileBasicInfoEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + /// + /// Fires this event after the query file standard information IO was returned. + /// + public void OnQueryFileStandardInfo(object sender, FileStandardInfoEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + /// + /// Fires this event after the query file network information IO was returned. + /// + public void OnQueryFileNetworkInfo(object sender, FileNetworkInfoEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + /// + /// Fires this event after the query file Id IO was returned. + /// + public void OnQueryFileId(object sender, FileIdEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + /// + /// Fires this event after the query file info IO was returned. + /// + /// + /// + public void OnQueryFileInfo(object sender, FileInfoArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + /// + /// Fires this event after the set file size IO was returned. + /// + public void OnSetFileSize(object sender, FileSizeEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + /// + /// Fires this event after the set file basic information was returned. + /// + public void OnSetFileBasicInfo(object sender, FileBasicInfoEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + /// + /// Fires this event after the set file standard information IO was returned. + /// + public void OnSetFileStandardInfo(object sender, FileStandardInfoEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + /// + /// Fires this event after the set file network information IO was returned. + /// + public void OnSetFileNetworkInfo(object sender, FileNetworkInfoEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + /// + /// Fires this event after the file was moved or renamed. + /// + public void OnMoveOrRenameFile(object sender, FileMoveOrRenameEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + /// + /// Fires this event after the delete IO was returned. + /// + public void OnDeleteFile(object sender, FileIOEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + /// + /// Fires this event after the set file info IO was returned. + /// + /// + /// + public void OnSetFileInfo(object sender, FileInfoArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + /// + /// Fires this event after the query file security IO was returned. + /// + public void OnQueryFileSecurity(object sender, FileSecurityEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + /// + /// Fires this event after the set file security IO was returned. + /// + public void OnSetFileSecurity(object sender, FileSecurityEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + /// + /// Fires this event after the directory enumeration query IO was returned. + /// + public void OnQueryDirectoryFile(object sender, FileQueryDirectoryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + /// + /// Fires this event after the file was cleanuped. + /// + public void OnFileHandleClose(object sender, FileIOEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + /// + /// Fires this event after the last file handle of the file was closed. + /// + public void OnFileClose(object sender, FileIOEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + + /// + /// Fires this event when a file was changed after the file handle closed + /// + public void NotifyFileWasChanged(object sender, FileChangedEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + + + /// + /// Fires this event when the filter driver attached to a volume. + /// + public void NotifyFilterAttachToVolume(object sender, VolumeInfoEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + /// + /// Fires this event when a volume was detached from the filter driver. + /// + public void NotifyFilterDetachFromVolume(object sender, VolumeInfoEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + + } +} \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/FileMonitor/MonitorForm.Designer.cs b/Demo_Source_Code/CSharpDemo/FileMonitor/MonitorForm.Designer.cs new file mode 100644 index 0000000..2ecc929 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FileMonitor/MonitorForm.Designer.cs @@ -0,0 +1,266 @@ +using System; +using System.Windows.Forms; +using System.Runtime.InteropServices; +using System.IO; +using System.Threading; + +namespace FileMonitor +{ + public class FastListView : ListView + { + [StructLayout(LayoutKind.Sequential)] + private struct NMHDR + { + public IntPtr hwndFrom; + public uint idFrom; + public uint code; + } + + private const uint NM_CUSTOMDRAW = unchecked((uint)-12); + + protected override void WndProc(ref Message m) + { + if (m.Msg == 0x204E) + { + NMHDR hdr = (NMHDR)m.GetLParam(typeof(NMHDR)); + if (hdr.code == NM_CUSTOMDRAW) + { + m.Result = (IntPtr)0; + return; + } + } + + base.WndProc(ref m); + } + } + + partial class MonitorForm + { + [DllImport("user32")] + private static extern bool SendMessage(IntPtr hwnd, uint msg, IntPtr wParam, IntPtr lParam); + private uint LVM_SETTEXTBKCOLOR = 0x1026; + + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MonitorForm)); + this.menuStrip1 = new System.Windows.Forms.MenuStrip(); + this.optionsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.exitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStrip1 = new System.Windows.Forms.ToolStrip(); + this.toolStripButton_StartFilter = new System.Windows.Forms.ToolStripButton(); + this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); + this.toolStripButton_Stop = new System.Windows.Forms.ToolStripButton(); + this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator(); + this.toolStripButton_ClearMessage = new System.Windows.Forms.ToolStripButton(); + this.toolStripSeparator3 = new System.Windows.Forms.ToolStripSeparator(); + this.toolStripButton_LoadMessage = new System.Windows.Forms.ToolStripButton(); + this.toolStripSeparator4 = new System.Windows.Forms.ToolStripSeparator(); + this.toolStripButton1 = new System.Windows.Forms.ToolStripButton(); + this.toolStripSeparator5 = new System.Windows.Forms.ToolStripSeparator(); + this.toolStripButton_UnitTest = new System.Windows.Forms.ToolStripButton(); + this.toolStripButton_Help = new System.Windows.Forms.ToolStripButton(); + this.menuStrip1.SuspendLayout(); + this.toolStrip1.SuspendLayout(); + this.SuspendLayout(); + // + // menuStrip1 + // + this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.optionsToolStripMenuItem, + this.exitToolStripMenuItem}); + this.menuStrip1.Location = new System.Drawing.Point(0, 0); + this.menuStrip1.Name = "menuStrip1"; + this.menuStrip1.Size = new System.Drawing.Size(974, 24); + this.menuStrip1.TabIndex = 0; + this.menuStrip1.Text = "menuStrip1"; + // + // optionsToolStripMenuItem + // + this.optionsToolStripMenuItem.Name = "optionsToolStripMenuItem"; + this.optionsToolStripMenuItem.Size = new System.Drawing.Size(61, 20); + this.optionsToolStripMenuItem.Text = "Settings"; + this.optionsToolStripMenuItem.Click += new System.EventHandler(this.settingsToolStripMenuItem_Click); + // + // exitToolStripMenuItem + // + this.exitToolStripMenuItem.Name = "exitToolStripMenuItem"; + this.exitToolStripMenuItem.Size = new System.Drawing.Size(38, 20); + this.exitToolStripMenuItem.Text = "Exit"; + this.exitToolStripMenuItem.Click += new System.EventHandler(this.exitToolStripMenuItem_Click); + // + // toolStrip1 + // + this.toolStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.toolStripButton_StartFilter, + this.toolStripSeparator1, + this.toolStripButton_Stop, + this.toolStripSeparator2, + this.toolStripButton_ClearMessage, + this.toolStripSeparator3, + this.toolStripButton_LoadMessage, + this.toolStripSeparator4, + this.toolStripButton1, + this.toolStripSeparator5, + this.toolStripButton_UnitTest, + this.toolStripButton_Help}); + this.toolStrip1.Location = new System.Drawing.Point(0, 24); + this.toolStrip1.Name = "toolStrip1"; + this.toolStrip1.Size = new System.Drawing.Size(974, 25); + this.toolStrip1.TabIndex = 1; + this.toolStrip1.Text = "toolStrip1"; + // + // toolStripButton_StartFilter + // + this.toolStripButton_StartFilter.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton_StartFilter.Image"))); + this.toolStripButton_StartFilter.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButton_StartFilter.Name = "toolStripButton_StartFilter"; + this.toolStripButton_StartFilter.Size = new System.Drawing.Size(97, 22); + this.toolStripButton_StartFilter.Text = "Start monitor"; + this.toolStripButton_StartFilter.Click += new System.EventHandler(this.toolStripButton_StartFilter_Click); + // + // toolStripSeparator1 + // + this.toolStripSeparator1.Name = "toolStripSeparator1"; + this.toolStripSeparator1.Size = new System.Drawing.Size(6, 25); + // + // toolStripButton_Stop + // + this.toolStripButton_Stop.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton_Stop.Image"))); + this.toolStripButton_Stop.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButton_Stop.Name = "toolStripButton_Stop"; + this.toolStripButton_Stop.Size = new System.Drawing.Size(97, 22); + this.toolStripButton_Stop.Text = "Stop monitor"; + this.toolStripButton_Stop.Click += new System.EventHandler(this.toolStripButton_Stop_Click); + // + // toolStripSeparator2 + // + this.toolStripSeparator2.Name = "toolStripSeparator2"; + this.toolStripSeparator2.Size = new System.Drawing.Size(6, 25); + // + // toolStripButton_ClearMessage + // + this.toolStripButton_ClearMessage.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton_ClearMessage.Image"))); + this.toolStripButton_ClearMessage.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButton_ClearMessage.Name = "toolStripButton_ClearMessage"; + this.toolStripButton_ClearMessage.Size = new System.Drawing.Size(108, 22); + this.toolStripButton_ClearMessage.Text = "Clear messages"; + this.toolStripButton_ClearMessage.Click += new System.EventHandler(this.toolStripButton_ClearMessage_Click); + // + // toolStripSeparator3 + // + this.toolStripSeparator3.Name = "toolStripSeparator3"; + this.toolStripSeparator3.Size = new System.Drawing.Size(6, 25); + // + // toolStripButton_LoadMessage + // + this.toolStripButton_LoadMessage.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton_LoadMessage.Image"))); + this.toolStripButton_LoadMessage.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButton_LoadMessage.Name = "toolStripButton_LoadMessage"; + this.toolStripButton_LoadMessage.Size = new System.Drawing.Size(107, 22); + this.toolStripButton_LoadMessage.Text = "Load messages"; + this.toolStripButton_LoadMessage.Click += new System.EventHandler(this.toolStripButton_LoadMessage_Click); + // + // toolStripSeparator4 + // + this.toolStripSeparator4.Name = "toolStripSeparator4"; + this.toolStripSeparator4.Size = new System.Drawing.Size(6, 25); + // + // toolStripButton1 + // + this.toolStripButton1.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton1.Image"))); + this.toolStripButton1.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButton1.Name = "toolStripButton1"; + this.toolStripButton1.Size = new System.Drawing.Size(93, 22); + this.toolStripButton1.Text = "Event viewer"; + this.toolStripButton1.Click += new System.EventHandler(this.toolStripButton1_Click); + // + // toolStripSeparator5 + // + this.toolStripSeparator5.Name = "toolStripSeparator5"; + this.toolStripSeparator5.Size = new System.Drawing.Size(6, 25); + // + // toolStripButton_UnitTest + // + this.toolStripButton_UnitTest.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton_UnitTest.Image"))); + this.toolStripButton_UnitTest.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButton_UnitTest.Name = "toolStripButton_UnitTest"; + this.toolStripButton_UnitTest.Size = new System.Drawing.Size(112, 22); + this.toolStripButton_UnitTest.Text = "MonitorUnitTest"; + this.toolStripButton_UnitTest.Click += new System.EventHandler(this.toolStripButton_UnitTest_Click); + // + // toolStripButton_Help + // + this.toolStripButton_Help.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton_Help.Image"))); + this.toolStripButton_Help.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButton_Help.Name = "toolStripButton_Help"; + this.toolStripButton_Help.Size = new System.Drawing.Size(52, 22); + this.toolStripButton_Help.Text = "Help"; + this.toolStripButton_Help.Click += new System.EventHandler(this.toolStripButton_Help_Click); + // + // MonitorForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(974, 506); + this.Controls.Add(this.toolStrip1); + this.Controls.Add(this.menuStrip1); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.MainMenuStrip = this.menuStrip1; + this.Name = "MonitorForm"; + this.Text = "EaseFilter File I/O Monitor"; + this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.MonitorForm_FormClosed); + this.menuStrip1.ResumeLayout(false); + this.menuStrip1.PerformLayout(); + this.toolStrip1.ResumeLayout(false); + this.toolStrip1.PerformLayout(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.MenuStrip menuStrip1; + private System.Windows.Forms.ToolStrip toolStrip1; + private System.Windows.Forms.ToolStripButton toolStripButton_StartFilter; + private System.Windows.Forms.ToolStripButton toolStripButton_Stop; + private System.Windows.Forms.ToolStripButton toolStripButton_ClearMessage; + private FastListView listView_Info; + private System.Windows.Forms.ToolStripMenuItem optionsToolStripMenuItem; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator1; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator2; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator3; + private System.Windows.Forms.ToolStripButton toolStripButton1; + private System.Windows.Forms.ToolStripMenuItem exitToolStripMenuItem; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator4; + private System.Windows.Forms.ToolStripButton toolStripButton_LoadMessage; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator5; + private System.Windows.Forms.ToolStripButton toolStripButton_UnitTest; + private System.Windows.Forms.ToolStripButton toolStripButton_Help; + } +} + diff --git a/Demo_Source_Code/CSharpDemo/FileMonitor/MonitorForm.cs b/Demo_Source_Code/CSharpDemo/FileMonitor/MonitorForm.cs new file mode 100644 index 0000000..3611760 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FileMonitor/MonitorForm.cs @@ -0,0 +1,253 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +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; +using System.Reflection; +using System.IO; +using System.Diagnostics; +using System.Runtime.InteropServices; + +using EaseFilter.CommonObjects; +using EaseFilter.FilterControl; + +namespace FileMonitor +{ + + public partial class MonitorForm : Form + { + + MonitorEventHandler monitorEventHandler = null; + FilterControl filterControl = new FilterControl(); + + + public MonitorForm() + { + + try + { + GlobalConfig.filterType = FilterAPI.FilterType.MONITOR_FILTER; + + InitializeComponent(); + monitorEventHandler = new MonitorEventHandler(listView_Info); + + StartPosition = FormStartPosition.CenterScreen; + + this.Text += GlobalConfig.GetVersionInfo(); + + this.Load += new EventHandler(Form1_Load); + + } + catch (Exception ex) + { + MessageBox.Show("Start FileMonitor failed," + ex.Message, "Start failed.", MessageBoxButtons.OK, MessageBoxIcon.Error); + Close(); + } + + } + + void Form1_Load(object sender, EventArgs e) + { + //to improve the listview performance + SendMessage(listView_Info.Handle, LVM_SETTEXTBKCOLOR, IntPtr.Zero, unchecked((IntPtr)(int)0xFFFFFF)); + } + + + ~MonitorForm() + { + GlobalConfig.Stop(); + } + + private void MonitorForm_FormClosing(object sender, FormClosingEventArgs e) + { + GlobalConfig.Stop(); + } + + void SendSettingsToFilter() + { + filterControl.ClearFilters(); + + GlobalConfig.Load(); + + if (GlobalConfig.FilterRules.Count == 0) + { + // MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("You don't have any monitor folder setup, please set up a filter rule in the settings, or there are no IOs will be filtered.", "FilterRule", MessageBoxButtons.OK, MessageBoxIcon.Warning); + // MessageBox.Show("You don't have any monitor folder setup, please set up a filter rule in the settings, or there are no IOs will be filtered."); + } + + foreach (FileFilterRule filterRule in GlobalConfig.FilterRules.Values) + { + FileFilter fileFilter = filterRule.ToFileFilter(); + + //add the event handler for the file filter. + fileFilter.OnFileOpen += monitorEventHandler.OnFileOpen; + fileFilter.OnNewFileCreate += monitorEventHandler.OnFileCreate; + fileFilter.OnDeleteFile += monitorEventHandler.OnDeleteFile; + fileFilter.OnFileRead += monitorEventHandler.OnFileRead; + fileFilter.OnFileWrite += monitorEventHandler.OnFileWrite; + + fileFilter.OnQueryFileBasicInfo += monitorEventHandler.OnQueryFileBasicInfo; + fileFilter.OnQueryFileId += monitorEventHandler.OnQueryFileId; + fileFilter.OnQueryFileNetworkInfo += monitorEventHandler.OnQueryFileNetworkInfo; + fileFilter.OnQueryFileSize += monitorEventHandler.OnQueryFileSize; + fileFilter.OnQueryFileStandardInfo += monitorEventHandler.OnQueryFileStandardInfo; + fileFilter.OnQueryFileInfo += monitorEventHandler.OnQueryFileInfo; + + fileFilter.OnSetFileBasicInfo += monitorEventHandler.OnSetFileBasicInfo; + fileFilter.OnSetFileNetworkInfo += monitorEventHandler.OnSetFileNetworkInfo; + fileFilter.OnSetFileSize += monitorEventHandler.OnSetFileSize; + fileFilter.OnSetFileStandardInfo += monitorEventHandler.OnSetFileStandardInfo; + fileFilter.OnMoveOrRenameFile += monitorEventHandler.OnMoveOrRenameFile; + fileFilter.OnSetFileInfo += monitorEventHandler.OnSetFileInfo; + + fileFilter.OnQueryFileSecurity += monitorEventHandler.OnQueryFileSecurity; + fileFilter.OnQueryDirectoryFile += monitorEventHandler.OnQueryDirectoryFile; + fileFilter.OnFileHandleClose += monitorEventHandler.OnFileHandleClose; + fileFilter.OnFileClose += monitorEventHandler.OnFileClose; + + fileFilter.NotifyFileWasChanged += monitorEventHandler.NotifyFileWasChanged; + + filterControl.AddFilter(fileFilter); + } + + filterControl.VolumeControlFlag = (FilterAPI.VolumeControlFlag)GlobalConfig.VolumeControlFlag; + filterControl.NotifyFilterAttachToVolume -= monitorEventHandler.NotifyFilterAttachToVolume; + filterControl.NotifyFilterAttachToVolume += monitorEventHandler.NotifyFilterAttachToVolume; + filterControl.NotifyFilterDetachFromVolume -= monitorEventHandler.NotifyFilterDetachFromVolume; + filterControl.NotifyFilterDetachFromVolume += monitorEventHandler.NotifyFilterDetachFromVolume; + + string lastError = string.Empty; + if (!filterControl.SendConfigSettingsToFilter(ref lastError)) + { + MessageBox.Show(lastError, "StartFilter", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + + + } + + private void toolStripButton_StartFilter_Click(object sender, EventArgs e) + { + try + { + //Purchase a license key with the link: http://www.easefilter.com/Order.htm + //Email us to request a trial key: info@easefilter.com //free email is not accepted. + string licenseKey = GlobalConfig.LicenseKey; + + string lastError = string.Empty; + + bool ret = filterControl.StartFilter(FilterAPI.FilterType.MONITOR_FILTER, GlobalConfig.FilterConnectionThreads, GlobalConfig.ConnectionTimeOut, licenseKey, ref lastError); + if (!ret) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("Start filter failed." + lastError, "StartFilter", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + SendSettingsToFilter(); + + toolStripButton_StartFilter.Enabled = false; + toolStripButton_Stop.Enabled = true; + + EventManager.WriteMessage(102, "StartFilter", EventLevel.Information, "Start filter service succeeded."); + } + catch (Exception ex) + { + EventManager.WriteMessage(104, "StartFilter", EventLevel.Error, "Start filter service failed with error " + ex.Message); + } + + } + + private void toolStripButton_Stop_Click(object sender, EventArgs e) + { + filterControl.StopFilter(); + + toolStripButton_StartFilter.Enabled = true; + toolStripButton_Stop.Enabled = false; + } + + private void toolStripButton_ClearMessage_Click(object sender, EventArgs e) + { + monitorEventHandler.InitListView(); + } + + + private void settingsToolStripMenuItem_Click(object sender, EventArgs e) + { + SettingsForm settingForm = new SettingsForm(); + settingForm.StartPosition = FormStartPosition.CenterParent; + if (settingForm.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + SendSettingsToFilter(); + } + } + + + private void toolStripButton1_Click(object sender, EventArgs e) + { + EventForm.DisplayEventForm(); + } + + private void exitToolStripMenuItem_Click(object sender, EventArgs e) + { + Close(); + } + + + private void MonitorForm_FormClosed(object sender, FormClosedEventArgs e) + { + FilterAPI.ResetConfigData(); + GlobalConfig.Stop(); + filterControl.StopFilter(); + Application.Exit(); + } + + private void unInstallFilterDriverToolStripMenuItem_Click(object sender, EventArgs e) + { + string lastError = string.Empty; + filterControl.StopFilter(); + filterControl.UnInstallDriver(ref lastError); + } + + private void toolStripButton_LoadMessage_Click(object sender, EventArgs e) + { + monitorEventHandler.LoadMessageFromLogToConsole(); + } + + private void toolStripButton_UnitTest_Click(object sender, EventArgs e) + { + toolStripButton_Stop_Click(null, null); + MonitorUnitTest monitorDemo = new MonitorUnitTest(); + monitorDemo.licenseKey = GlobalConfig.LicenseKey; + + monitorDemo.ShowDialog(); + } + + private void toolStripButton_Help_Click(object sender, EventArgs e) + { + System.Diagnostics.Process.Start("https://blog.easefilter.com/file-monitor-demo-step-by-step/"); + } + + + } +} diff --git a/Demo_Source_Code/CSharpDemo/FileMonitor/MonitorForm.resx b/Demo_Source_Code/CSharpDemo/FileMonitor/MonitorForm.resx new file mode 100644 index 0000000..425e9f3 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FileMonitor/MonitorForm.resx @@ -0,0 +1,693 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + + 126, 17 + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAInSURBVDhPtdJdSJNhFAfwM3OFe603yrvYjZGilq4pWo2y + MKISzGpYocOZ6fzYxj78oDUdC7Wla5V6NZC6qSAKItPlFGMpTm3a0GFTiG6Skq6kyW7Kf0MeGIKYF/W7 + PM/5cw7P89C/U0ra5IakZaogH6lIxqpbx2t3L818m8Kzj48guXvoN1WSk/S0hx3/XYIxYfll4CkcIy1o + HzWj/IUcQoPwOzVSCWvZXJwhbvnxdDeah3TQvy1FrUsOlTsf6RbxKhlokG7TAda6MZFR9LN7shX17uuo + 6i9ESe9JXH59GBf7U1HwJhl8qygc2aaZHtIOFlmPa+RCdu9NaN1XUOY6jaK+TBT0JUHuTkGx5yAqJjNx + 5tV+kJk+kYWkLBbFmbiQbVyHmsELUAzIcGkgBVeH06AYSUf5hASqKSk0szmoD8qwzRIzx2JRXBMXaptQ + o3r4PBRD2bj2Lg1l3gxU+jJR48+GNnAMdfO5aPqSB4ElJsBiUZyFC93xVaPWcw5KTxaUYxJUTWdBPXME + dcFcWL+ehfx9BgStgjlqJwmLRcW3xa90+NXQjeXjhjdnbbJm9ihMn/NgXDiFfT3xK2SjW/SctrPIeryN + Dz8I6NHwoRAa34m1yebIusd7Elepg1z0hBJZ68Z4Bx92Bk2w+othnY9c5LgUsY7Yxch/LGItm9tpFy71 + Lnaia0GN1HviX3SfOiNvvosdb0ELKcXOvT/ITqPURVms+r8R/QE18vZdo+QItgAAAABJRU5ErkJggg== + + + + + iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAARRSURBVEhLxVRbTFRXFD0woIA2owgij2JVFFF81Ee1VQoy + MMyAiKLiCwqIbyxG248+vvXHxPpV/TOxEeOTqKmmESVqRIPia2R8R9SqLQItA3SiqMu159yRcRIbTJp0 + Jzvnnjtz1lpn7b2v+t/i9XAV2z5aNfw1LtjdnUHulrHMMcHupmQTM8j9e4JydMSraONYz8IAv/WyZDzw + 9ZfAms+BVVOBZZOApRMAeV+cDBQl48XMeDwYopw9JhFwVxLBiz8F1qZo4BWfAWUTNfBXY4HC0cCiJGDB + CGBhIp7b43A3tgckAt5K8K4SqhTl5SQoT+UNppOEtygladEYYIkQjNQEBcOA+cPgtsagIU7d6Ih4D4kH + PMEPfF06MwOosOj9ssmaYPEoKidBwXBgHgnyhwJzB+OfjChciVHOJn8SAW8h+AuxpYJAq7/oJvjWBnxj + J2kaCWiVh0DsSaTyBAITfM4nQF48MDsOnTMicDlSORt9Sf4coRq6iqWgtEI8X8lcM02DbrAC65liVRlv + UMjieu2hNcgfQuDBwKyPgZmxQG40OlPDcS5COQx4pZrYdqigLSunsJBUKJ0iRV3KG5XyuVhUCygtyYsj + AdXnEkyebQOA9I+AtD6ANQKwDyJRFC6aTW4DXqmnySQoZxGlQ6q24W3s+QnoaDM2jNqjwOkqY8MoJHFb + s7Fh/FgAZIQD2ZE470vwKIkEq2nLIl77yX3gj0Zg71agercmlXDUasUSNfv1uu174NEd4NpZ4CnPHfiZ + N+Ft7ANxzhzQTfAwMciN5RwisaFysz787LHuGhsVSVw4Dkw36eeaA3rdToLGW4CrVe8rt2gCWyRO+xJc + FoIyer2E7Scds3Mj8KqLJE94IEQfrjsBTDMITu7Tq9zgwW3g72fApuVAVqS2KCscp8yBPgQJtKiUXTSf + HXHzorap9lcNkhKs1/oaPhsE9Sf1unW9tubxPWBKAIvMgguBtT+q3iEYanKjhO1XwBp8NxtopvJOl7Yg + q78GOLKDh/tR9Q/8rR24c42/EbCO1knxU9lFmdxb+P/Mfv4EtKiI4y+9PY+DwzaTTpDBwVwOEYuGHL7L + Y6/b+X4GfbYwxZK0vgY4lQu4xcwb+BHUD1KOzmxOIj9cnm+LjL9MqAxRPgnmcJBkUmWYpP9zYiiA/W4n + qZCIcrHGwhuSoHVSGPaGqCsGvFIy1nUc7w4bFXum0xh/mVABFuW5/E0mNSdag9v8wNM1eMtEgvdWjkNK + RRnwOoTkzADlbM+kOrHlrWIvsKgmuKi20TJ/8AyCU/meXspR7Q/ujcYwFV1tVjdcFioU/98B9lEtnwRv + Qb3KCb67l7r+XnBvOEly3KycbWkE4YcLdqYHmKqtvn4bBWU2TwjDrsB/Ue4fQnIslCQpBMoleA6Bs0kg + HSSTLa3LTpFspucfBO6NYyQ5GKKu/hZqch31ZIDrSGig6zDzELPSyF8C1aXKDwX/70KpN929HhkRWgNw + AAAAAElFTkSuQmCC + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAJFSURBVDhPrdBbSNNxHAXwo2aKl8ZyMy/brFzWPypvyBQL + iTJCAyWIIOqlMEkjZ4VWCNYg8hIpou1BQyScmvmgwzKjBokJBiL1IoSG1JKcl9wclTZP7u/vyYd88fPy + 53vO4f/ww6aKNYe/SGuKnT1Qox2NNql6cBFFyMceUW9sd0NER82XAra67rB7qZL9rGPuS8P8auWztthI + KXSK8pDvLT9LaXHdYx9rebwn3SlafNiKnAF/xItznWoY0p7FOOqn89g4a6TFXcZuPuBhy6HPYoF3gNoa + hImBABSKSKiALrVNN3NjLJ2myVyaxs8xuzlmuctTTqlx56BYyWzBMNpU8PQF4KiIAOWj4OZroxk0fjIw + oyt6AXeRh2IUWH6VMKxeUSdmsvfbcHIkCnwVitciAlLa9jvODklMtGicqEKCHFZAgWr/SpggybcwokL5 + pB4cVMP7uGviWvXuLJuevnUoE5FsJQLSQhTur4Qh1Hv/UCNhUgvnrAQOR2BKHnlpnihtBquGqMUxEcmW + kwMbWJzIiUhcntbg0tzBwAWm+vFPAjikRpOYrTIjc2+nyrP6vSoS2e9s7RCbztN+KnLp760MMl8is0Jp + 3+UzM6yEVszWbGn3NfqZfcfRge0iwtIFaZzWIvL5FXp/xKpsOtIUjqkdMIjJOu1IQgtyxIXFmydcHKkk + 39wmuwr5NSnkm10Jnaj/j4Cf8/oRN11vybHHZH8JPQ9zuZgc8lRMNsY47JuLDzLPZIb3Ok7rP06diZt3 + pih6Rb0ZgH+vle/bCJhHDQAAAABJRU5ErkJggg== + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIQSURBVDhPrZLfT9pQFMf5n31UYzSB2GjUFAqlgsEw54+J + IUCGCqPRYKICUioFKTAoAkbc3IMPSxw3351bSTShb9tJTu5N2/M53+85df238HgSr36/yngGAipTFJWF + wyqLRFS2taWyUCjDNjfT9Pwr8/mifyZl78ELLy5e4PNlIYpprK0dQRB24HaHsbgoYX5+BTMzczg4UOH1 + HrJJ2XtIksqKxd/IZO6RzfZxetpFOt1EKlVFIqEhHi8gFssjn28T4Ms0gCsoFF6o0MLxsYlksoJcroVK + 5RHV6gNub4d0DqBpQ1K4Pw2QZZVdXf2CJCVJ/mcsLwepcxmmOcTHMM0+/P6YM6BUesb5eRdnZ23KBnT9 + GaWShVrNou5vZ7ncIYCDBUXJOQJqtd6k91vU6xapdLCwsfFtfHk5giyfkMdD2oBCEz/Bzc0A19cWCgUT + nc49zaRFgN1pwPp6ZqzrP+2h6foTDY0PbwTDeCTZXHoLvd4DvWsTYMdpBgnawg/yxxUcYXU1Co/Hj9lZ + N9nRCGzaFqrVJv0rUWcA71ivj9BoPNknX52mWSgWm2Shhru776SkQf/BthMgbiuQpBStUEEotIdut2t3 + /RiGwQGRaUAwGGeGMaAP+tR9YK9N15t0b9MmeLbo3iRVdbLgAFha+vTq9e4zUdyzUxCCY0GQKQNjLlkU + I3by7gsLK+NJ2b+Gy/UXt60c1ec0SuIAAAAASUVORK5CYII= + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHySURBVDhPrZJ/S1NRHMb3VnoPFfROegVBqDQx25reH91t + bNLYZkpbOmMlzXmvkYKkECqEYhDB+kPBgVIRbU2dbl1tuz/O0znnHhp0tX/qgQ/3wL3Ph+/5cgP/Lcn8 + KhjRiWWOlF7khJILnKA2h0GtfFN87g8r/y1MIKeXLpf8KSCEwKVYDkHXdml5EXtfzi6XJHIrotoLkzgu + k7goLmxxCZuEIWq9qNklUfNiGAZkVcPw/RH6fICybqBpdvGpfoqgkiai1ouaeSWqtKzr2KweoE3P738C + pRrwxFhBqayjee5gYLRwwQRCwMaWtBga9HxCgLfHXRSr53hcBaLRGI6poH902i9Q0p6A3XkoPIK1JvCm + 3sH8vonJyimyO0A4EsHRmY2+iwSRMYMLOnRhEr17bh/I77SR/XAC7V0LM3sEsXgcDS6Y8gvCiXkuMLsu + SnNlTLzcQOwjEK8Q5HcJHk5OIZXJ4nA5h2f6ml8QVGe5oNVxOLMv6I8jS7g7fA+SotDyOHa3UiDJ66g8 + CvsFd5TnXMCW5GHz+x5SGqaN2usCXO0q8HkQVuIa7NtXNFH1cis0zQXfTes39R8WapRvbQtfWxaaq0/h + RG8ABwqUVP5IVL2wzQ7IM5RCD6mAfgp7xyga69jORKCOjaNvKCSL6r8kEPgFDZ0dP8+MGmkAAAAASUVO + RK5CYII= + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHvSURBVDhPrY9fSFNRHMdvpqVLqLcgZhS4hwohMo2ChN5i + RJE2pKfeRg9D7CFh9SDlg02yP8iCoprRKqysDLE2rLvmSgZJmZdoXVFYWGsrW1uR2+726Yrn7UrrwQ98 + OYff93PO4UhLDrAs6ZPsMV/J2NTz9drHp1X59zfLlbBnTQt3bcuFtjjQXpJ9Jt2bU/eDJusZgN89kDxG + 4lUNgR5pEFkuFbqR9PBKR0Zt1A+G9fTB3GVIdUDcAbHDxOVqfN2m40I3khhe8Y7MkP7qFcj1QlZPqhO+ + tkC0SV+bkc9VRIRuZObx2ix/7sPsSUi7FjJ7Aj7bYXovfGsj3F2hCd3IzMDq7/w8A1/sFOKtC5nfRw9R + UHfql3Xiv1CeEroRxVv6ALUBPjWSn5rPQfKT+9Am6vTZEQqTB3h4quyJ0I3EAw2WyO2yBOoOiOxCU+pB + rUd7s13/QhPBLimteOu2Cn1xsiM1tapnVY4PW8iMmsm9tZAJbyB41ZSffrRtj9D+zfg1U6gwsZl00Myv + lxvJvrYwerZyTNTFUfs2NQ+dlgi6JF50SQy2S4Tc1UdFXZz+ftl83u0lIAfxXL9Ba1sHFy/11oq6OIqi + VLpcrlhwJIT31h2cTmfS7/evE/X/4Xa7q6xWa9Rms/1wOBy7xXipkaS/oHk/td0LlGoAAAAASUVORK5C + YII= + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAI3SURBVDhPrZFNaxpRGIUv/fgNrZu2u3ZX6Kr9A92E0nVb + ui00i3SSiFhrFIqhkIIYoovqQBhcJEqjIWCSItIgglEsURGM8WOqjB+pqdRE6hh1Tu/o7SK0Cxc5cJk7 + d97nnHnvSy5VZvPXa7u7lRd+/9F2MFho7e0VlGAwq/j931o8HwysrASee73eq6z8og4PcS8SaaYk6Tf+ + p04HSCRqcDo3kx5P6C7DxopGu3f2938es1ooCtCVhyCPVkEerqLVAk5OgFoNqFYBnv/csNmEWwwnJBAo + bwwGY1h9/t1/iR+PFvpAowFUKkChAIgiYDJ99DKckHC40VOB4RCQZaDXpYntc6TFU1i3RAxoV5IElEpA + Njve2+1umeGExOPUnqpHbc7OqAkFXjqOcGM6htuzcYC+l8tAPg9kMmMjh2NNYTghOzsZSe379BRot+mF + URNV5HUKZDpJDyhUHKenUkC9Dmi15iTDCXG7E1w+/2v0B6pJl65mWwF5WwExVCDWFYi0dzVdvUi3e1vR + 6RamGK7O33zF58sI2WxzZNKniU83z6Fxyrjp7GLK20ORpudyQCxWwvy8/gNDL8rvT78ShFA1Ginix3cZ + fTq6jjo6mp6mnah34HJ5hhaLRcOQf5VIJK7zvO/x8rLbtLho/zQ3t7C2vh7GwQFQLA5ouiHASicTxxk0 + grA1Gt3Skks2Go332afJZDK9fxMK5WCzOXt6/btn7HgyWa2OJ1qtTpqZmd3gOO4BO75MEfIHImzoqTuQ + k6kAAAAASUVORK5CYII= + + + + + AAABAAgAEBAAAAEACABoBQAAhgAAABAQAAABACAAaAQAAO4FAAAYGAAAAQAIAMgGAABWCgAAGBgAAAEA + IACICQAAHhEAACAgAAABAAgAqAgAAKYaAAAgIAAAAQAgAKgQAABOIwAAMDAAAAEACACoDgAA9jMAADAw + AAABACAAqCUAAJ5CAAAoAAAAEAAAACAAAAABAAgAAAAAAEABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP// + /wAygPwAvYp4AH/e/wD/3ZcAwMDAAHyX4QB2dXQA7trOAKCgoADhrooAjMXWAKHB/wCZhnMAvaySAP/3 + ywDxyIIA0tLSAJGQjQDMrqoA/9y4AK16cAD/8OEA0p+CAIqo3gD5xpYAhIJ9AOS8mACrq6sA3trEAPTd + qQD//+oA/+THAP/RhADEnIgA8tWYAP/npgD96NUAceH/APjouwA4jP8AxpN9AJmOgwCZl5QAqoF6AO26 + kAC1gnQA782QAIaHhwD/+vUAtKiXANmmhgD/1ZAAmLz/AMjBugD22qAAmpSLAP/uvQDQtLAA//bsAIuf + 3QDRzssA/+DAAPntwgCZiXoAfn5/AP/t2gD/584AOoX/APn5+QD+2Z0AnJycAHt5dQDguJUAsX5yAIam + 4gC5hnYAwY56APXClADxvpIA6baOAOWyjADdqogA///yAP7WmAD8/PwAqKioAJaPhwDw0JQA1tPPAJmM + fgDVooQAz8/PAMTBvgA2iP8A//jwAMmWfgD/69YA/+nSAJuSiADHnokAgYB/AI+OiwDCwsIA//37AP/+ + 7wD/7t0A/9qWAJmUjgCrqqgAd3d2ALOAcwC3hHUAmZCHANekhACFhYYA//v3AHt4cwCZi3wA/v7+APr6 + +gD+0IUAuod3AL6LeQDCj3sAxZJ8AJ2dnQDcqYcAw8C9AP/37wCAgIAAgoB+AK57cADV0s8AkpCNAMfB + ugAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAACNhfk4DTS9LFhQ9WIcAAGUJRkZ5VngBAQENRQRkAAAYAXJtLGhdARIZAicp + BwAAcwEXPGlXQgiDEwxfNjsAAIABcl5/DyJ6VTlnTAGFAAALAWsyhAUkMBFHMQEBcAAAUgErWnY6KB9Z + NW8SAXEAAFEBYmAbIGpAOGx0AXh7AAAuAXc3Ch5UECUzSAZWfAAAUAEhY4JuhElmHWl1eX0AAE8BDkFb + iGCGPoFtbUYqAAAaARU/IURiQ2sXFxdGYQAAHCYBAQEBAQEBAQEBCS0AAABKGk9QLlFSC1M0XC0AAAAA + AAAAAAAAAAAAAAAAAAD//wAAwAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAIAB + AACAAQAAgAEAAMADAAD//wAAKAAAABAAAAAgAAAAAQAgAAAAAABABAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAMuYf8zJln7/xZJ8/8GOev+9inj/uYZ2/7WCdP+xfnL/rXpw/8yuqv+Ln93/l5CI/Xdz + bH4AAAAAAAAAAM6bgMzu2s7/+fn5//n5+f/6+vr//Pz8//7+/v////////////////+hwf//OoX//3/e + //+dlIr+AAAAAAAAAADSn4L//////5mQh/+ZlI7/mZeU/8LCwv/Pz8///////9LS0v+KqN7/MoD8/3Hh + //84jP//fJfh/wAAAAAAAAAA16SE////////8OH///bs///9+/+oqKj/fn5//3Z1dP+AgID/kZCN/4zF + 1v82iP//mLz//9C0sP8AAAAAAAAAANyph///////mZCH/8TBvv+dnZ3/vayS///RhP/+0IX//taY/5qU + i/+Pjov/hqbi//////+ue3D/AAAAAAAAAADhror////////u3f//+vX/goB+///dl//y1Zj/782Q//HI + gv/+2Z3/hoeH////////////s4Bz/wAAAAAAAAAA5bKM//////+ZjoP/1tPP/3t4c///7r3/+Oi7//Td + qf/w0JT//9WQ/3d3dv/S0tL//////7eEdf8AAAAAAAAAAOm2jv///////+vW///48P+Egn3////q///+ + 7//57cL/9tqg///alv+FhYb///////7+/v+6h3f/AAAAAAAAAADtupD//////5mLfP/Iwbr/oKCg/97a + xP////L///fL///npv+0qJf/nJyc/8DAwP/8/Pz/vot5/wAAAAAAAAAA8b6S////////5Mf//+nS///3 + 7/+rqqj/goB+/3t5df+BgH//q6ur///9+///+/f/+vr6/8KPe/8AAAAAAAAAAPXClP//////mYZz/5mJ + ev+ZjH7/x8G6///48P/V0s//0c7L/8PAvf+ZlI7/mZSO//n5+f/Gk33/AAAAAAAAAAD5xpb////////c + uP//4MD//+TH///nzv//69b//+3a///u3f//8OH///Dh///w4f/5+fn/yZZ+/wAAAAAAAAAA88CTzP3o + 1f//////////////////////////////////////////////////////7trO/6p3bswAAAAAAAAAAAAA + AADuu5DM+caW//XClP/xvpL/7bqQ/+m2jv/lsoz/4a6K/92qiP/Zpob/1aKE/6p3bswAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAD//wAAwAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAMAD + AAD//wAAKAAAABgAAAAwAAAAAQAIAAAAAACgAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8AGVv/AK98 + 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 + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADJln6pyZZ+/8aTfP/EkXv/wY56/7+Mef+9inj/uod2/7iF + df+2g3T/s4Bz/7F+cv+vfHH/rHlv/6p3bv+odW3/qnp0/9TEyP+Jg3j/hICA+GNjYzgAAAAAAAAAAM6b + gKnZr5j/9eLU///27v//+vX///38//////////////////////////////////////////////////// + ////////9vf//wZF//9Oheb/5drP/357evkAAAAAAAAAANKfgv/24dD///Pn///27v//+vX///38//// + ///////////////////////////////////////////////////z9f//DEr//0ac//9k1///ZZ3p/4yH + gf8AAAAAAAAAANShg/////////Ll///17P+ZlZL/mZeW/5mZmf+ZmZn/mZmZ//////////////////// + //////////////Hz//8LSf//SaL//2/Z//9Xt///D1r//7+zv/8AAAAAAAAAANajhP////////Ll///0 + 6v//9/H///v4////////////////////////////+vr6//n5+f//////8fHw/4SCh/87jOH/bt3//1a0 + //8ZW///4+f//7KGgf8AAAAAAAAAANilhf////////Dj///06v+ZlI//mZaT/5mYl/+ZmZn/y8vL/7Oz + tf+ChYj/fXx5/358ev+ChIj/jo+Q/62qpf/Ax8L/QZrp/xRW///m6////////6l2bv8AAAAAAAAAANqn + hv///////+/g///z5///9ez///nz///8+v//////o6Wn/7Wrl//10JT/+9KT//vTmv/8153/wrWh/4CD + if/EwLv/goKQ/+nt/////////////6t4b/8AAAAAAAAAAN2qh////////+7e///w4/+Zkoz/mZSR/5yZ + lv/b29z/rKSS//zXmv/x0Zv/79CZ/+7Nkf/wz5f/+tef/7+znf+Ki4z/ysrI/////////////////657 + cP8AAAAAAAAAAOCtif///////+zZ///v4P//8+f///Xs///59f+UlJf/9Nii//Xdqv/x26r/8dup//DU + ov/v0Jf/8M6a//7ao/+PkZT//////////////////////7B9cf8AAAAAAAAAAOKviv///////+rX///u + 3v+ZkIj/mZKM/62ppf+AgH7//+i1//blvv/358D/9eK4//Pdsf/x1qX/8NCV//3apP+FhIL/2NjY//// + /////////////7J/cv8AAAAAAAAAAOSxi////////+nV///s2f//7+D///Ll///38P+Eg4L///PI//z1 + 3P/689b/9+zI//bnvf/z3K3/8NOe//7Zof+EhIP//////////////////////7WCdP8AAAAAAAAAAOaz + jP///////+fQ///q1/+ZjoT/mY+G/62nof+enp3/7+bF////8P/+/vz//Pbb//fsx//24bP/89ek//TY + pP+Rk5b//////////////////////7iFdf8AAAAAAAAAAOi1jv///////+XM///o0v//6tf//+7e///y + 5//z7OX/paOc////7P////f//fnl//nuzP/347b//+Gm/6Sdkv/b29z//////////////////////7qH + dv8AAAAAAAAAAOy5j////////+PJ///mzv+Zi37/mY6C/52Tif+tpp//vru5/6Khm//j3sL///zT///y + wv/p1av/oJuS/7Kztv+/v7//mZmZ/////////////////72KeP8AAAAAAAAAAO67kP///////+HF///j + yf//5s7//+nV///s2f//7+D///Pp//Lr5P+lpKT/gICD/4CCgv+ampz/5OPj///9/f////////////// + /////////////7+Mef8AAAAAAAAAAPC9kf///////9/A///hxf+ZiHn/mYt9///p1f+ZjoL/nZOJ/6ae + lv+tp6H/r6mk/62npP+jn53///nz/5mWk/+Zl5X/mZeW///9/P///fz///38/8GOev8AAAAAAAAAAPK/ + k////////928///fwP//4cX//+PJ///mzv//6NL//+rX///t3P//7+D///Dj///z5///9Or///Xs///2 + 7v//9/H///nz///69f//+vX///r1/8SRe/8AAAAAAAAAAPTBlP///////9u4///dvP+ZhnP/mYd2/5mI + ef+Zinz/mYt+///q1/+ZjoL/mY+F/5mPhv+ZkIj/mZKL/5mSjP+Zkoz/mZOO///27v//9u7///bu/8eU + ff8AAAAAAAAAAPbDlf///////9mz///buP//3bz//9/A///hxf//48n//+XM///n0P//6dX//+rX///s + 2f//7t7//+/g///w4///8uX///Ll///z5///8+f///Pn/8qXfv8AAAAAAAAAAPnGlv/+8eb//+7e///Z + s///27j//928///evv//4MP//+LH///lzP//5s7//+fQ///p1f//6tf//+zZ///t3P//7t7//+7e///v + 4P//7+D/9uDQ/8yZf/8AAAAAAAAAAPjFlj36ypz//vHm//////////////////////////////////// + ///////////////////////////////////////////////////338z/27KZ/8yZf6kAAAAAAAAAAAAA + AAD4xZY9+caW//fElf/1wpT/88CT//G+kv/vvJH/7bqQ/+q3j//otY7/5rOM/+Sxi//ir4r/4K2J/96r + iP/ap4b/2KWF/9ajhP/UoYP/0J2BqQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA////AMAAAwCAAAEAgAABAIAAAQCAAAEAgAABAIAAAQCAAAEAgAABAIAAAQCAAAEAgAABAIAA + AQCAAAEAgAABAIAAAQCAAAEAgAABAIAAAQCAAAEAwAABAOAAAwD///8AKAAAACAAAABAAAAAAQAIAAAA + AACABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8ANF/oAMCNeQBt2f8ATVNaAPvboQB5pLUAxsjQAEtw + qgBfiP8AeX6EAK6ppADksYsA+O/PAKBuagBNsfgAmZONADqL/wBkZ20A2cmkAN3d3QDi270AUG7oAMie + kADNtLUA8sqLAIqTpAA8b/8A7u3sAJmGdAD/3r4AW3KXAF/A/wC1t7gArqKNALB9cQD//N8A79vRAJ2d + nQDXpIQA69GeAIiKjgDu8f8AKnb/AOe9nwDEwr8A7tuwAL2yogD/9+8A4cKQALWRhQDx5cEAzZp/APvI + lwDW1NIA/+3cAPG+kgCJh4EAkZOXAP3rvAD/5MoAOmfxAOLRqgCZjIAA2byhAM/LxwDi2dIApKWpAMa2 + wwDhyZoAsKmYAPLVpwCodW0AVrT/AODm5ACysK8A9dKaAPb29gD39+cA99+rAIGEiQBYgP8A6uHYALeE + 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 + AAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPgAAAH//////////8oAAAAIAAAAEAAAAABACAAAAAAAIAQ + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAHVvWSSGhH3maWhndGJiYl6EhIQCAAAAAAAAAAAAAAAAAAAAALqHdrW2g3T/tYJz/7SB + c/+zgHL/sX5y/7B9cf+vfHH/rntw/616cP+seW//q3hv/6l2bv+odW3/p3Rt/6ZzbP+lcmz/pHFr/6Nw + a/+hbmr/oG1p/6Bua//NtLX/UG7o/4qTpP/Nx8L/iIiH/2NjY2kAAAAAAAAAAAAAAAC6h3a1yJ6Q/+/b + 0f//+PL///v3///+/f////////////////////////////////////////////////////////////// + /////////////////////////Pz//1+I//8qdv//S63//+Dm5P/Py8f/aGhoeQAAAAAAAAAAAAAAAL6L + eP/v2s7///Xs///48v//+/f///79//////////////////////////////////////////////////// + //////////////////////////////v7//9bhv//Lnn//1a0//9o1f//W73//66urv+MioTTAAAAAAAA + AAAAAAAAwI15///+/v//9ez///jy///79////fv///////////////////////////////////////// + ///////////////////////////////////6+///WID//y97//9Zt///bNb//1/A//87j///Omfx/4V/ + clcAAAAAAAAAAAAAAADDkHr////////06v//9/D/mZaT/5mYl/+ZmZn/mZmZ//////+ZmZn/mZmZ/5mZ + mf+ZmZn/mZmZ/5mZmf+ZmZn/mZmZ////////////7u3s/1Bw8f8wevz/Wrn//2zW//9ev///Po7//zxv + ///GtsP/AAAAAAAAAAAAAAAAAAAAAMaTfP////////Pp///27v+ZlZL/mZeV/5mZmf+ZmZn//////5mZ + mf+ZmZn/nZ2d/7W1tf/FxcX/zMzM/8vLy//ExMT///////r6+v+Xk4r/W3KX/0qr9P9t2f//Xb7//z2N + //9AcP//7vH//65/ef8AAAAAAAAAAAAAAAAAAAAAyZZ9////////8+n///bu///48v//+/f///79//// + ///////////////////29vb/tbe4/4qMkf+EiJD/hIiP/4GEif+vsLH/6Ojo/46Ojf/i2dL/eaS1/02x + +P86i///RHP///Dz////////qndu/wAAAAAAAAAAAAAAAAAAAADKl37////////y5///9ez/mZWR/5mW + k/+ZmJf/mZmZ/5mZmf+0tLT/vL29/3Z7gv+yp5L/5ceW//HJjP/1zJH/8c+f/72yov9NU1n/kJCS/+7t + 7P/q4dj/S3Cq/zRf6P/y9P////////////+seW//AAAAAAAAAAAAAAAAAAAAAMyZf/////////Ll///0 + 6v+ZlJD/mZWS/5mXlf+ZmZn/qqqq/7+/wP+Agob/4cKQ//LKiv/syI7/6saP//DQnf/v06P/8MeK/+/O + mv9kZ23/mpuc/5OSkf+emYz/xsjQ/////////////////698cf8AAAAAAAAAAAAAAAAAAAAAz5yA//// + ////8eP///Pp///17P//+PL///v3///+/f/5+fn/h4uP/+bJmv/105n/79Ca/+/Qmf/vz5j/7s2Q/+7I + i//y06T/9NWg//LQn/9NUlr/3d3d/+jo6P//////////////////////sn9y/wAAAAAAAAAAAAAAAAAA + AADRnoH////////w4f//8uf/mZKM/5mUkP+ZlpP/srCv/8nKy/+uoo3/9NOc/+vQnv/q0p7/8dam//HV + ov/w057/79CY/+7Kjf/y1Kf/9dCR/7Ornf/CwsP///////////////////////////+0gXP/AAAAAAAA + AAAAAAAAAAAAANShg////////+/g///x4/+Zkoz/mZSP/5mVkf/DwsD/o6Wp/9nFmv/u16X/7Nep/+zX + qv/z3bD/89yt//Hbqf/w1KH/79Ca/+7Mj//227H/79Gj/5CSlv///////////////////////////7eE + dP8AAAAAAAAAAAAAAAAAAAAA16SE////////7dz///Dh///y5///9Or///fw///8+v+Qk5f/99+r//fm + vf/25r7/9unF//bnwP/35Ln/89+x//Hbqf/w1KH/78+V//LWqP/205r/jJCV//////////////////// + ////////uod2/wAAAAAAAAAAAAAAAAAAAADap4b////////s2v//7+D/mZGI/5mSjP+Zk47/zMrI/46Q + lv/13a7/+e7M//Xrz//06cr/8ufF//Divf/v3LP/7Niq//Hbqf/pzJb/7dGg//XRm/+EiI3/yMjI/5mZ + mf////////////////+9inf/AAAAAAAAAAAAAAAAAAAAANyph////////+rW///t3P+ZkIf/mZGJ/5mS + jP/Ewb7/pKWo/9nJpP//9tz/9/HY//f25//38Nv/9OnH//Hlwf/u27D/8tus/+nOmv/v0qD/582g/4mK + jv+/v7//mZmZ/////////////////7+MeP8AAAAAAAAAAAAAAAAAAAAA3quI////////6dX//+vY///u + 3v//8OH///Ln///37//a2dj/sKmY///83//+/fH//v36//7+8//89Nb/+O/P//bku//z3a//8dak//vb + of+roZL/x8jJ////////////////////////////wo96/wAAAAAAAAAAAAAAAAAAAADhror////////n + 0f//6tb/mY6D/5mPhv+ZkYj///Lo/9DNy/+hoKP/4tu9//r65f/7+/L/9/fn//Xw1//47sz/7961/+zX + qf/w157/4cma/3l+hP/7+/v////////////////////////////Fknv/AAAAAAAAAAAAAAAAAAAAAOOw + i////////+bP///o0/+ZjID/mY6E/5mPhv//8uX/q6ah/9bU0v+bm5r/5d7D//n54//69+P/9vDV//ru + yf/z4LL/992o/+DInf+AgYT/wMDA/////////////////////////////////8eUfP8AAAAAAAAAAAAA + AAAAAAAA5rOM////////5cz//+bP///p1f//69j//+3c///w4f//8uX///bv//Pw7v+jo6b/sq2e/+PY + uP//8MP//eu8/+LRqv+wqJf/hYiM/+Dg4f//////////////////////////////////////ypd+/wAA + AAAAAAAAAAAAAAAAAADpto3////////jyP//5cz/mYt9/5mMgP+ZjYL/mY6E/5mQh/+ZkYn/rqmk/9DO + zP/T0dH/np6i/4iKjv+Ehoz/kpSY/6ipqv/Nzc3//////5mZmf+ZmZn/mZmZ/5mZmf////////////// + ///MmX//AAAAAAAAAAAAAAAAAAAAAOu4jv///////+HE///kyv+ZiXv/mYt9/5mMgP+ZjYL/mY6E/5mQ + h/+ZkYn/npaQ///38P/JxsT/0c/N/9HPzf/Ix8X/tbSz/52cnP//////mZmZ/5mZmf+ZmZn/mZmZ//// + /////////////82af/8AAAAAAAAAAAAAAAAAAAAA7bqQ////////38H//+LG///kyv//5c3//+fR///p + 1f//69j//+3c///v4P//8eP///Ln///06v//9ez///fw///48v//+vX///v3///8+f///fv///79//// + ////////////////////////0J2B/wAAAAAAAAAAAAAAAAAAAADwvZH////////dvf//4ML/mYh3/5mJ + ef+ZiXv/mYt9/5mMgP//69j/mY6E/5mPhv+ZkIf/mZGJ/5mSjP//9Or/mZSP/5mUkP+ZlZH/mZWS/5mW + k/+Zl5T/mZeV/5mYl////fv///79///+/f/ToIL/AAAAAAAAAAAAAAAAAAAAAPPAk////////9y5///e + v/+ZhnT/mYh3/5mJef+ZiXv/mYt9///p1f+ZjID/mY6D/5mPhf+ZkIf/mZGI///y5/+Zkoz/mZKM/5mT + jv+ZlJD/mZWR/5mVkf+ZlZL/mZaT///79///+/f///v3/9ajhP8AAAAAAAAAAAAAAAAAAAAA9cKU//// + ////5s3//9y5///ev///4ML//+LG///kyv//5cz//+bP///o0///6tb//+vY///t3P//7+D///Dh///x + 4///8uf///Pp///06v//9ez///bu///27v//9/D///jy///48v//+PL/2KWF/wAAAAAAAAAAAAAAAAAA + AAD4xZX////////48v//5s3//9y5///dvf//38H//+HE///jyP//5cz//+bP///n0f//6dX//+rW///s + 2v//7dz//+/g///w4f//8eP///Ll///y5///8+n///Pp///06v//9ez///Xs/+7a0f/bqIb/AAAAAAAA + AAAAAAAAAAAAAPvIl4/6x5b///////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////9+//u2s3/572f/7aD + dI8AAAAAAAAAAAAAAAAAAAAAAAAAAPvIl4/7yJf/+seW//nGlv/4xZX/98SV//XClP/0wZP/88CT//K/ + kv/xvpL/8L2R/+67kP/tupD/7LmP/+y5j//ruI7/6reO/+m2jf/ntIz/5rOM/+Wyi//ksYv/47CL/+Kv + iv+2g3SPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/////////j4AAAAcAAAAHAAAABwAAAAcAA + AAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AA + AAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAAD4AAAB///////////KAAAADAAAABgAAAAAQAIAAAA + AACACgAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8AIVXwAMGOeQBt2f8ATE1PAPvboQCLldIArb3/ADhm + uQBfiP8AeX6EAK2qpwDlsosA+/DSAKBuagBNsfgAmZWLADmJ/wBnaGkA2cmkAOLe2gDi270ATInRAMai + kQDNtLUA8sqLAHWCtQA8b/8A7+3rAIV7awD/3r4AW3KXAGHE/wCytL8AqaCNALB9cQD//eMA79vRAJ2d + nQDXpIQA6tCfAIqLjQDb4f8AImT/AOzDnADEwr4A8deuAL+0oQD/+e4A376KALiLgQDu5MEAzZp/APvI + lwDY1tQA//HbAPG+kgCFgHgAkpOWAPzrvQD/6cgANHHqAOLRqgCZjIAA1b6jAM/LxwDi2dIApaepALyr + vwDhyZoAsqmZAPHWqACodW0AVrT/AODm5ACysa4A9dOaAPb29gD49usA99+rAIGEiQBYgP8A6uHYALaD + dACYl5cA6MSKALKWjQD/7dEA9uS4AP/05AD00JEA/ffXAFBw8QDpy5YA/f3vAMeUfQDqt44A36yIAL28 + uQBEc/8AkZCNANbAmAD/8MMA6eflAPPmzACemYwArn95AMfGxQBMpv8A8NeeAPby3QAweOgAWqjPAKGh + oQD2w5QA7sySANHPzQC4r5sA9uCyAPHaqADl3sMA0Z6BAKqpqADv0JgA8NCgANrZ2AD7+/sA+/bdAP/o + wwCZj4YAu66VAOvWqwBeuO8AZs7/APvvygDz8O4AiIeHAMrLywD07dcApHFrAKx5bwDnyZMAgYGCAPbb + sQDi07cArKSUAJmJeQDk4d8AtbSzAPfowADCwsMA//bpAPfqxQCRj4oAjZCWAJSUlADu37cA7talAOjO + oACopaEA//z3AO/jvQDt06MAop+aAESa/gDx9P8A/fniAPTq0gCdmJAA9tegAHd3eQCEh4wAuod2ANuo + hgC/v8AA7cSEAPPcrQDmyZoA18y8ALCurABbhv8A//37AP/y4AD/7tUA/+vMAPHnxgCalpEAmZmZAOjN + mwDNzMwA+fnwALOAcgCDiY8Avot4AMOQewD4xZUAyZZ9ANWigwDuu5AA57iDAOKvigDT0tEA+/v/AO/a + zgDFxMMAQHD/AF2//wD/3LkA9cyRAC54/wCKjJEA8NOeAJubnACfn6AAyMjJAP/68wD9+ucA/+DCAPfd + qADx1aIApaSkAKmtvwD5+fkAjIyMAJGRkQD25b4A4MidAMzKyAA7j/8Af8buAPb01wCZi30A+u7OAJmO + gwCZkYkA8tywAO/NlQCmc2wAqnduAK57cAC0gXMAl5WLAPTBkwDPnIAA7smQAPLTpADu0qAA0M7MAP/y + 6AD06ccA9NOcAO7KjwDw27MA79GcAO/OmgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI+PAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKu0j4+rAAAAAAAAABh6enp6 + enp69PT09PT0NTU1NTXFYGDDwwPCwq2tVPHAJDNFAj57lJyPAAAAAAAAGHqRWlpamJiYmJgxMTExMdjY + 2KGhoaG2trYBAQEBAQEBASsCLKWFlGiPAAAAAAAYemlaWlpamJiYmJgxMTExMdjY2KGhoaG2trYBAQEB + AQEBKwIspc+G5i5M4QAAAADGqDFaWlpamJiYmJgxMTExMdjY2KGhoaG2tra2AQEBAQErAiylIYYhbRep + jwAAAADGAbdaOjo6Ojo6Ojo6OjExOjo6Ojo6Ojo6Ojo6j4+JvCIC0qUhhiFtEiwbAAAAAAAoAbdaOjo6 + Ojo6Ojo6OjExOjo6Ojo6Ojo6Ojo6j4ne3gLSbSGGIW0SLAcAAAAAAAAoAbdaOjo6Ojo6Ojo6OjExOjo6 + Ojo6Ojo6Ojo6ibSaCQKlIYYhbRIsCBgAAAAAAAAoAbdaWlpaWpiYmJiYMTExMTHY2KGhtra2tra2Ab5V + ZQmFhiFtEiwIASQAAAAAAACuAbe3WlpaWpiYmJiYMTExMTHYoconqxMTq7w3AR2PvntxhW0SLAgBAcAA + AAAAAACuAbe3Ojo6Ojo6Ojo6Ojo6OqC0q6u8MEFBMNYTExOcIgFEF3ACBwEBAfEAAAAAAACuAbe3Ojo6 + Ojo6Ojo6Ojo6DHITpDKwsFYyyMifTAXgHb43wQIHcgEBAVQAAAAAAABiAbe3Ojo6Ojo6Ojo6Ojqg3auD + sFbt7VZeKSlWyLMFnHLh3Tu0iQEBAa0AAAAAAABiAbe3t1paWlqYmJiYmDGUq3Zb7e3t7XT8sF4vo7Cz + BRPKTGgBAQEBAa0AAAAAAABiAbe3t1paWlpamJiYmNjWqU3+1NTU/nx8dPz1L9ywe4kBAba2tgEBAcIA + AAAAAABiAbe3Ojo6Ojo6Ojo6mpWPZl7cnr2fvb1ejnx09ex0hBMdtra2tra2tsIAAAAAAADJAbe3Ojo6 + Ojo6Ojo6pHKa/imxsaOjKZ+9vdTtdH1IsDsitra2tra2tgMAAAAAAADJAbe3Ojo6Ojo6Ojo6tLwjo4R3 + d4SEhISjKdzU7XT9sHactra2tra2tsMAAAAAAAANATi3t7e3WlpaWlqY2N2Dd1lZmZmZ4ll3sXjc/nRI + 7TCJtqGhoaGhocMAAAAAAAANATi3t7e3WlpaWlqY2N12WZkO6emHmZZZd+xI1O1I7TCJtqGhoaGhoWAA + AAAAAADIATg4Ojo6Ojo6Ojo6TN2SPGmLqKhpuqKdhIR43I4pVke8ezo6OqGhoWAAAAAAAADIATg4Ojo6 + Ojo6Ojo6pEyaPKhvb09PqLo0nYSxSF4pVipjpDo6OqGhocUAAAAAAADIATg4Ojo6Ojo6Ojo6mmM7kahv + v7+/i2m6nYTseF69ZhNoiTo6OtjY2DUAAAAAAABhATg4ODi3t7e3WlpaWjFsEVynX6FfgFwOllnseNxN + u1Wh2NjY2NjY2DUAAAAAAABhATg4ODi3t7e3t1paWpgdRDAl2THZp4DpllmxeKowE2jY2NjY2NjY2DUA + AAAAAABhATg4Ojo6Ojq3tzo6OjqgzSd2529vgGmi/YSeKUeroKQxMTExMTExMTUAAAAAAADHATg4Ojo6 + Ojq3tzo6Ojo6tM3d8pGZh6Kd7Hhmu6vdDDoxMTExMTExMTUAAAAAAADHAbg4Ojo6Ojq3tzo6Ojo6OqAu + lZyaR3YwkpqPiUygOjoxMTExMTExMfQAAAAAAADHAbg4ODg4ODi3t7e3t1paWlqYMRUue9W8J0w32DGY + MTExMTExMTExMfQAAAAAAAA5Abi4ODg4ODg4t7e3t7daWlpaWpgx2NjY2DExmJiYmJiYMTExMTExMfQA + AAAAAAA5AVi4Ojo6Ojo6Ojo6Ojq3Wjo6Ojo6Ojo6Ojo6OjqYmDo6Ojo6OpiYmPQAAAAAAAA5AVi4Ojo6 + Ojo6Ojo6Ojq3tzo6Ojo6Ojo6Ojo6OjqYmDo6Ojo6OpiYmPQAAAAAAADzAblYOjo6Ojo6Ojo6Ojq3tzo6 + Ojo6Ojo6Ojo6OjqYmDo6Ojo6OpiYmPQAAAAAAADzAblYWLi4ODg4ODg4OLe3t7e3t7daWlpaWlpaWlpa + mJiYmJiYmJiYmHoAAAAAAABzAbm5WFi4uDg4ODg4ODg4t7e3t7e3WlpaWlpaWlpaWlpaWlqYmJiYmHoA + AAAAAADEAT25Hh46Ojo6Ojo6Ojo6Ojo6Ojo6t7c6Ojo6Ojo6Ojo6Ojo6OlpaWnoAAAAAAADEAT09Hh4e + Ojo6Ojo6Ojo6Ojo6Ojo6t7c6Ojo6Ojo6Ojo6Ojo6OlpaWnoAAAAAAADEAYE9Hh4eHjo6Ojo6Ojo6Ojo6 + Ojo6t7c6Ojo6Ojo6Ojo6Ojo6OlpaWnoAAAAAAAA2AYGBPT25uVhYuLi4ODg4ODg4ODg4t7e3t7e3t7e3 + t7daWlpaWlpaWnoAAAAAAAA2WjiBgT09ubm5WFi4uLg4ODg4ODg4ODi3t7e3t7e3t7e3t7e3t7e3kXoA + AAAAAABBNlo4gYGBPbm5uVhYuLi4ODg4ODg4ODg4ODi3t7e3t7e3t7e3tzFpehgAAAAAAAAALTZaAQEB + AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAah6GAAAAAAAAAAAAEE2NsTExHPz8zk5OcfHx2Fh + YcjIyA0NycliYmJirq6uKCgoxsYYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///////8AAP// + ////nwAA//////+DAAD4AAAAAAMAAPAAAAAAAwAA4AAAAAABAADgAAAAAAEAAOAAAAAAAwAA4AAAAAAH + AADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAA + AAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAH + AADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAA + AAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAH + AADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAPAAAAAADwAA+AAAAAAfAAD///////8AAP// + /////wAA////////AAAoAAAAMAAAAGAAAAABACAAAAAAAIAlAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI6MgwJycm/BcnJyu2Rk + ZChmZmY0V1dXAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQ3 + +CN7e4P+sK+t/4CAgP6CgoL/bW1twmxsbAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADPnICj0J2B/9Cd + gf/QnYH/0J2B/9Cdgf/QnYH/0J2B/8+cgP/PnID/z5yA/86bgP/Om4D/zpuA/82af//Nmn//zJl//8yZ + f//MmX//yZZ9/8iVff/Gk3z/xJF7/8KPev/Bjnn/vot4/72KeP+7iHb/uYZ1/7aDdP+0gXP/s4By/7B9 + cf+4i4H/vKu//yJR9f80cer/q6in/+Hg3/+UlJT/hISE/2VlZUsAAAAAAAAAAAAAAAAAAAAAAAAAANKf + gszQnYH/7tS////04///9OT///Xl///15///9ej///bp///26v//9+v///fs///47f//+O7///nv///5 + 8P//+fL///rz///69P//+/X///v2///89////Pj///z5///9+v///fz///79///+/v////////////// + ///////////////////d4///KFn//ytz//9CmP//aLTo/+bh3//m5eT/goKC/mVlZUAAAAAAAAAAAAAA + AAAAAAAA06CCo9Gegf/24s7///Pi///04///9OT///Xl///15///9ej///bp///26v//9+v///fs///4 + 7f//+O7///nv///58P//+fL///rz///69P//+/X///v2///89////Pj///z5///9+v///fz///79///+ + /v///////////////////////////9vi//8nWv//LHX//0OZ//9dv///ZM7//3/G7v/Hwr7/s7Kx/nR0 + dHsAAAAAAAAAAAAAAAAAAAAA1KGD//Xl2P//+O3///Pi///04///9OT///Xl///15///9ej///bp///2 + 6v//9+v///fs///47f//+O7///nv///58P//+fL///rz///69P//+/X///v2///89////Pj///z5///9 + +v///fz///78///+/f//////////////////////2N///ydY//8tdv//RJn//17A//9nzv//Y8j//0yq + //9XitP/npmS/3l5edwAAAAAAAAAAAAAAAAAAAAA1aKD////////8+H///Pi/4V/dv+Ff3f/hYB3/4WA + eP+FgHn/hYB6/4WAev+FgXv/hYF7/4WBfP//+O7///nv/4WCff+Fgn7/hYJ+/4WCf/+Fg4D/hYOA/4WD + gf+Fg4H/hYOC/4WEgv+FhIP/hYSD/4WEhP+FhIT/hYWF/5iYmP+jq8z/H1P5/y53//9GnP//X8H//2fO + //9ix///T6n//zqL//8XW/7/QFi8g3Fway4AAAAAAAAAAAAAAAAAAAAA1qOE////////8+H///Pi/4V/ + dv+Ff3f/hX93/4WAeP+FgHj/hYB5/4WAev+FgXv/hYF7/4WBfP//+O7///jv/4WCff+Fgn7/hYJ+/4WC + f/+Fg4D/hYOA/4WDgP+Fg4H/hYOC/4WEgv+FhIP/hYSD/4WEhP+Lior/sbGx/6GozP8cS+f/Lnn+/0ed + //9fwv//Z87//2LG//9OqP//OYr//x1c//+Hi9H/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA16SE//// + ////8+H///Pi/4V/dv+Ff3f/hX93/4WAeP+FgHj/hYB5/4WAev+FgXv/hYF7/4WBfP//+O7///jv/4WC + ff+Fgn7/hYJ+/4WCf/+Fgn//hYOA/4WDgP+Fg4H/hYOB/4WDgv+FhIL/hYSD/4uKif+vrq7/kpCM/yxM + sf8nauD/R5z8/2DE//9nzv//YcX//06n//85if//HVr//6e5///Gopr/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA2KWF////////8+H///Pi///z4v//9OT///Tl///15v//9ef///bo///26f//9ur///fr///3 + 7P//+O7///jv///57///+fD///ny///68///+/b///z4///9+v///fv///37///9+////vv///37///9 + /f/Nzcz/mZiX/5GQjf9Df8H/Wrny/2jP//9hxf//Tab//ziI//8cW///rb3///////+wfXH/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA2aaG////////8+D///Ph///z4v//9OT///Tl///15v//9ef///Xo///2 + 6f//9ur///fr///37P//+O3///ju///57///+fD///rz//369v/U0tD/np6c/3l6ev9naGn/Zmdo/3Z2 + dv+amZn/19bU///+/f/v7u3/g4OD/83My/+rrKr/WqjP/1m79P9Lpf//OIb//xxZ//+ywf////////// + //+zgHL/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA26iG////////8uD///Ph/4V/dv+Ff3b/hX93/4WA + d/+FgHj/hYB5/4WAev+FgHr/hYF7/4WBe/+FgXz/hYF8/4WBff+npaL/r66s/3R0df9wcnT/mpqZ/7+z + o//OvqT/0b+n/8G4qP+dnqH/YmVn/2VlZv9nZ2f/lJSU/7m5uf/+/f3/pKiq/0GIz/8weOj/GVHy/4ua + 0/////////////////+0gXP/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3KmH////////8uD///Ph/4V/ + dv+Ff3b/hX93/4V/d/+FgHj/hYB4/4WAef+FgHr/hYB6/4WBe/+FgXv/hYF8/66rqP+goJ//bm9y/6Gd + lf/YvI//8MaF/+/Iiv/nw4b/5sCF/+e9fv/mu3X/6cyi/7Gvrf9KS03/jIyM/+3t7f/MzMz/2NbV/4OJ + j/8YRsr/j5vS/6Kiov////////////////+2g3T/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3aqH//// + ////8uD///Ph/4V/dv+Ff3b/hX93/4V/d/+FgHj/hYB4/4WAef+FgHr/hYB6/4WBe/+FgXv/pqOf/6Wk + o/92eHv/u6yU/+nChf/nxIj/7syU/+7LlP/nxo//6cmU/+vPoP/rzqD/58KJ/+a6d//Wy7v/TlFT/5SU + lP+goKD/kZGR/6Skof+TlJb/r66u/4WFhf////////////////+5hnX/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA3quI////////8t////Pg///z4f//8+L///Tj///05P//9eX///Xn///16P//9uj///bp///3 + 6///+O7/5uPf/3l6fP+8rpb/9NCR/+/OlP/vzpX/7s6U/+7NlP/uy5L/7sqP/+3Hi//tzJf/8deu//DS + ov/swHv/1829/0tMTv9jY2P/0dHR/7GxsP/o5+f///79///+/f///v7///7+///+/v+7iHb/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA36yI////////8t////Lg///z4f//8+L///Tj///05P//9OX///Xm///1 + 5///9uj///bp///26v//+vP/oJ+f/5uWjv/21Jn/8NGc//DSnf/w0p3/8NKd//DRnP/v0Jn/79CY/+7N + kv/uyo//7cmP//HXrv/x06L/7sJ//6iopv+GhYb///79///+/f///fz///78///+/P///v3///79///+ + /f+9inj/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4K2J////////8t7///Lg/4V/df+Ff3X/hX92/4V/ + d/+Ff3f/hYB3/4WAeP+FgHn/hYB6/5GNiP+3tbP/f4GE/9W9kv/ozJj/8daj//HYpP/nz5z/58+d/+fN + nP/nzJn/58qV/+bIkv/vz5j/7suQ/+7JkP/y27H/7sqT/+zSq/9cXmH/7ezq///9+v///fv///37///9 + /P///fz///38///9/P++i3j/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4a6K////////8t7///Lf/4V+ + df+Ff3X/hX92/4V/dv+Ff3f/hX93/4WAeP+FgHj/hYB5/6WhnP+joqH/kI2J/+7RnP/o0J//8tus//Pc + rP/q06P/6tOj/+nSov/o0KD/58+c/+fMmf/w0p3/78+X/+7Lkf/w0KD/8NWr/+7Eg/+QkZX/urm4///9 + +v///fr///36///9+v///fr///36///9+v/Bjnn/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4q+K//// + ////8t7///Lf/4V+df+Ff3X/hX92/4V/dv+Ff3f/hX93/4WAd/+FgHj/hYB5/7Guqv+ampn/qaCN/+7T + o//s1aj/9eCz//Xgs//r16z/69is/+vXqf/q1af/6tOj/+jQn//x1qT/8NKd/+/Pl//vzJL/8tmz/+/I + iv+zrKL/lZSU///9+v///Pn///z5///8+f///Pn///z5///8+f/Cj3r/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA5LGL////////8d3///Le///y3///8+D///Ph///z4v//9OP///Tk///05f//9eb///Xn///6 + 8v+jo6P/uq+V//fhsf/25bz/9uW8//bpxf/368f/+OrE//blvv/247f/9eCy//Pdrv/x2aj/8dah//DR + nP/uzpL/8ter//DMlP/HuaX/hYSF///9+v///Pf///z4///8+P///Pj///z4///8+P/EkXv/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA5bKL////////8d3///Le///y3///8uD///Ph///z4v//8+L///Tk///0 + 5f//9eX///Xn///58f+mpqX/ua6W//jktv/36cT/++/S//vuzv/47s3/+O3K//fqxf/36b//9uO4//Xg + s//z3K//8dim//DTnv/vz5f/8dWn//DNlf/EtqL/hoaG///8+f//+/b///v3///89////Pf///z3///8 + 9//Gk3z/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA5rOM////////8dz///Hd/4V+dP+FfnT/hX91/4V/ + df+Ff3b/hX92/4V/d/+Ff3f/hYB4/7Kvqv+mpqX/rKOT//rpuv/x58n/9OvV//Tqzf/y68//8+jL//Dn + xP/u4r7/7d+5/+vYrv/q1af/8tqp//HWpP/nyZP/686f/+rHjf+vp5r/mZmY/6upp/+Fg4D/hYOA/4WD + gP//+/b///v2///79v/IlX3/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA57SM////////8dz///Hd/4V+ + dP+FfnT/hX51/4V/df+Ff3X/hX92/4V/dv+Ff3f/hX93/6ainP+ysa//k5GN//3twP/07NH/9fHd//Xx + 3v/49+z/+PXp//Przv/w5sb/7uTB/+3dtP/r2Kz/89ys//HXpf/nypX/6tCf/+nEif+Ki43/u7q4/5+c + mv+Fg4D/hYOA/4WDgP//+/X///v1///79f/Jln3/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA6LWN//// + ////8dv///Hc/4V+c/+FfnT/hX50/4V+df+Ff3X/hX92/4V/dv+Ff3f/hX93/5KOhv++vbr/k5SX/9/U + sv/07dH/9/Pg//n47v/6+vL/+fnw//Tv2P/x6cz/8ufH/+7et//r2Kz/892v//Hap//nypb/6c2a/9fA + mf9rbG//7Onn/42Kh/+Fgn//hYJ//4WCf///+vT///r0///69P/MmX//AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA6baO////////8Nv///Hb///x3f//8d3///Le///y4P//8+D///Ph///z4v//9OP///Tk///0 + 5f//+fD/x8bF/5mVi///+Nf//Pjh//387v///vf//f3v//z33f/79df/+vDR//jov//247j/892v//HZ + p//w1aD/9NKa/5qWkv+Xlpb///v3///68v//+vL///ry///68///+vP///rz///68//MmX//AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA6reO////////8Nr///Hb///x3P//8d3///Le///y3///8uD///Ph///z + 4f//8+L///Tj///05P//9ej/8u7p/6Wlp/+6tKD///3j//365f/9/Ov//Prp//354//79dv/++/O//fo + wv/25Lj/892u//Lap//216D/u7Cc/3Bxc//p5+P///nx///58f//+fH///nx///58v//+fL///ny///5 + 8v/MmX//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA67iP////////8Nr///Da/4V+cv+FfnP/hX5z/4V+ + dP+FfnT///Lg///z4f+Ff3b/hX92/4V/dv+Ff3f/qaWg/8XEwv+cnZ//tbGd//b01//389z/9vLc//v2 + 3v/y6cv/7uK8/+3cs//s2Kv/69Sm/+3TnP+3q5b/dHV4/6empP+hnpv///nv///58P//+fD///nw///5 + 8P//+fD///nw///58P/Nmn//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA7bqP////////8Nn///Da/4V9 + cv+FfnL/hX5z/4V+c/+FfnT///Lf///y4P+Ff3X/hX92/4V/dv+Ff3b/hX93/7Guqf/FxMP/o6Sl/5eV + i//a0rP/9OrE//3xyv/w5Lz/8OC2//HcsP/w2qr/1cKd/5mVj/95enz/p6Wk/6uopf+FgXz///jv///4 + 7///+O////nv///57///+e////nv///57//Nmn//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA7ruQ//// + ////79f///DZ/4V9cv+FfnL/hX5z/4V+c/+FfnT///Le///y3/+Ff3X/hX91/4V/dv+Ff3b/hX92/4V/ + d/+sqKL/xMK//7Oys/+Sk5P/k5GN/7CqnP+5sJv/urGZ/6yllf+Qjor/gIGD/4qJif+0s7D/pqOe/4WB + fP+FgXz///ju///47v//+O7///ju///47v//+O7///ju///47v/Om4D/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA77yQ////////79b///DZ///w2f//8Nr///Hb///x3P//8d3///Le///y3v//8uD///Pg///z + 4f//8+L///Pi///04///9OT///bp//347//i3tr/wsG+/6uqqv+bm5z/mJiY/52dnP+0srD/2tfT//75 + 8///+O3///fr///37P//9+z///fs///47f//+O3///jt///47f//+O3///jt///47f/Om4D/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA8L2R////////7tT//+/W///w2f//8Nr///Da///x2///8dz///Hd///y + 3v//8t////Lg///z4P//8+H///Pi///z4v//9OP///Tk///05P//9un///ju///58f//+vL///rz///6 + 8v//+fD///fs///26f//9ur///bq///36///9+v///fr///37P//9+z///fs///37P//9+z///fs///3 + 7P/Om4D/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8b6S////////7dL//+7U/4V9cP+FfXH/hX1y/4V9 + cv+FfnL/hX5z/4V+c/+FfnT/hX50/4V+df+Ff3X///Ph///z4v+Ff3b/hX92/4V/d/+Ff3f/hX93/4WA + d/+FgHj/hYB4/4WAeP+FgHn/hYB5/4WAef+FgHr///bp///26f+FgHr/hYB6/4WBe/+FgXv/hYF7/4WB + e///9+v///fr///36//PnID/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8r+S////////7ND//+7T/4V8 + b/+FfXD/hX1x/4V9cv+FfXL/hX5y/4V+c/+FfnP/hX50/4V+dP+FfnT///Lg///z4f+Ff3X/hX92/4V/ + dv+Ff3b/hX93/4V/d/+Ff3f/hYB3/4WAeP+FgHj/hYB4/4WAef+FgHn///bo///26f+FgHr/hYB6/4WA + ev+FgHr/hYB6/4WAev//9ur///bq///26v/PnID/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA88CT//// + ////7M7//+3R/4V8bv+FfG//hX1w/4V9cf+FfXL/hX1y/4V+cv+FfnP/hX5z/4V+dP+FfnT///Lf///y + 4P+Ff3X/hX91/4V/dv+Ff3b/hX92/4V/d/+Ff3f/hX93/4V/d/+FgHf/hYB4/4WAeP+FgHj///Xn///1 + 6P+FgHn/hYB5/4WAef+FgHn/hYB6/4WAev//9un///bp///26f/PnID/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA9MGT////////68z//+zP///t0f//7tP//+7V///w2f//8Nn///Da///w2///8dv///Hc///x + 3f//8t7///Le///y3///8uD///Pg///z4f//8+H///Pi///z4v//9OP///Tk///05P//9OX///Tl///1 + 5f//9eb///Xm///15///9ef///Xn///15///9ef///Xo///16P//9ej///Xo///16P/QnYH/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA9sOU////////6sv//+vN///sz///7dH//+7T///u1f//8Nn///DZ///w + 2v//8Nv///Hb///x3P//8d3///Hd///y3v//8t////Lg///y4P//8+H///Ph///z4v//8+L///Pi///0 + 4///9OT///Tk///05P//9OX///Tl///15f//9eb///Xm///15v//9eb///Xn///15///9ef///Xn///1 + 5//QnYH/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA98SU////////6sn//+rL/4V7a/+Fe2z/hXxt/4V8 + bv+FfG//hX1w/4V9cf+FfXL/hX1y/4V+cv+FfnP/hX5z/4V+c/+FfnT/hX50/4V+dP+FfnX/hX91///z + 4f//8+H/hX92/4V/dv+Ff3b/hX92/4V/dv+Ff3f/hX93/4V/d/+Ff3f/hX93/4V/d/+Ff3f/hYB3/4WA + d///9eX///Xl///15f/QnYH/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+MWV////////6cf//+rJ/4V6 + av+Fe2v/hXts/4V8bf+FfG7/hXxv/4V9cP+FfXH/hX1y/4V9cv+FfnL/hX5y/4V+c/+FfnP/hX5z/4V+ + dP+FfnT/hX50///y4P//8+D/hX91/4V/df+Ff3X/hX92/4V/dv+Ff3b/hX92/4V/dv+Ff3f/hX93/4V/ + d/+Ff3f/hX93/4V/d///9OT///Tk///05P/QnYH/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+caW//// + ////6MP//+nH/4V6af+Femr/hXtr/4V7bP+FfG3/hXxu/4V8b/+FfXD/hX1x/4V9cf+FfXL/hX1y/4V+ + cv+FfnP/hX5z/4V+c/+FfnT/hX50///y3///8t//hX51/4V+df+Ff3X/hX91/4V/df+Ff3b/hX92/4V/ + dv+Ff3b/hX92/4V/dv+Ff3b/hX92/4V/dv//9OP///Tj///04//QnYH/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA+seW////////58H//+jE///px///6sn//+rL///rzf//7M///+3R///u0///7tT//+/W///w + 2f//8Nn///Da///w2v//8dv///Hb///x3P//8d3///Hd///y3v//8t7///Lf///y3///8uD///Lg///z + 4P//8+H///Ph///z4f//8+H///Pi///z4v//8+L///Pi///z4v//8+L///Pi///z4v/QnYH/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA+8iX//7y4v//8Nn//+fB///ow///6cf//+rJ///qy///68z//+zO///s + 0P//7dL//+7U///v1v//79f///DZ///w2v//8Nr///Db///x2///8dz///Hc///x3f//8d3///Le///y + 3v//8t7///Lf///y3///8uD///Lg///y4P//8+D///Ph///z4f//8+H///Ph///z4f//8+H///Ph/+7U + v//QnYH/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/MmXo/zJl//+9OX///DZ///nwf//6MP//+jF///p + yP//6sr//+vM///szv//7ND//+3R///u0///7tX//+/X///w2f//8Nn///Da///w2v//8Nv///Hb///x + 3P//8dz///Hd///x3f//8d3///Le///y3v//8t7///Lf///y3///8t////Lg///y4P//8uD///Lg///y + 4P//9+z/9uHN/9Kfgv/PnICjAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP3KmMz8yZf//vLi//// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////15df/0Z6B/9KfgswAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAD8yZej+8iX//rHlv/5xpb/+MWV//fElP/2w5T/9MGT//PAk//yv5L/8b6S//C9kf/vvJD/7ruQ/+26 + j//ruI//6reO/+m2jv/otY3/57SM/+azjP/lsov/5LGL/+Kviv/hror/4K2J/9+siP/eq4j/3aqH/9yp + h//bqIb/2aaG/9ilhf/XpIT/1qOE/9Wig//UoYP/06CCowAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////AAD//////58AAP//////gwAA+AAAAAAD + AADwAAAAAAMAAOAAAAAAAQAA4AAAAAABAADgAAAAAAMAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAA + AAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAH + AADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAA + AAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAH + AADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAA + AAAABwAA4AAAAAAHAADwAAAAAA8AAPgAAAAAHwAA////////AAD///////8AAP///////wAA + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/FileMonitor/MonitorUnitTest.Designer.cs b/Demo_Source_Code/CSharpDemo/FileMonitor/MonitorUnitTest.Designer.cs new file mode 100644 index 0000000..caf7603 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FileMonitor/MonitorUnitTest.Designer.cs @@ -0,0 +1,76 @@ +namespace FileMonitor +{ + partial class MonitorUnitTest + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MonitorUnitTest)); + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.richTextBox_TestResult = new System.Windows.Forms.RichTextBox(); + this.groupBox1.SuspendLayout(); + this.SuspendLayout(); + // + // groupBox1 + // + this.groupBox1.Controls.Add(this.richTextBox_TestResult); + this.groupBox1.Dock = System.Windows.Forms.DockStyle.Fill; + this.groupBox1.Location = new System.Drawing.Point(0, 0); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size(636, 408); + this.groupBox1.TabIndex = 0; + this.groupBox1.TabStop = false; + // + // richTextBox_TestResult + // + this.richTextBox_TestResult.Dock = System.Windows.Forms.DockStyle.Fill; + this.richTextBox_TestResult.Location = new System.Drawing.Point(3, 16); + this.richTextBox_TestResult.Name = "richTextBox_TestResult"; + this.richTextBox_TestResult.Size = new System.Drawing.Size(630, 389); + this.richTextBox_TestResult.TabIndex = 0; + this.richTextBox_TestResult.Text = ""; + // + // MonitorDemo + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(636, 408); + this.Controls.Add(this.groupBox1); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Name = "MonitorDemo"; + this.Text = "Monitor Feature Demo "; + this.Activated += new System.EventHandler(this.MonitorDemo_Activated); + this.groupBox1.ResumeLayout(false); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.GroupBox groupBox1; + private System.Windows.Forms.RichTextBox richTextBox_TestResult; + } +} \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/FileMonitor/MonitorUnitTest.cs b/Demo_Source_Code/CSharpDemo/FileMonitor/MonitorUnitTest.cs new file mode 100644 index 0000000..52b132c --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FileMonitor/MonitorUnitTest.cs @@ -0,0 +1,475 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.IO; +using System.Diagnostics; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; +using Microsoft.Win32.SafeHandles; +using System.Security.AccessControl; +using System.Security.Principal; + +using EaseFilter.CommonObjects; +using EaseFilter.FilterControl; + +namespace FileMonitor +{ + public partial class MonitorUnitTest : Form + { + FilterControl filterControl = new FilterControl(); + bool isUnitTestStarted = false; + + /// + /// To manage your files, you need to create at least one filter rule, you can have multiple filter rules. + /// A filter rule only can have one unique include file mask, + /// A filter rule can have multiple exclude file masks, multiple include process names and exclude process names, + /// multiple include process Ids and exclude process Ids, multiple include user names and exclude user names. + /// + + + /// + /// Test monitor feature with registering the IO events, get notification after the file was closed. + /// + private string unitTestMonitorTestFolder = "c:\\EaseFilterUnitTest\\monitorFolder"; + private string unitTestMonitorTestFile = "c:\\EaseFilterUnitTest\\monitorFolder\\unitTestMonitorTestFile.txt"; + private bool isTestMonitorFileCreated = false; + private bool isTestMonitorFileReanmed = false; + private bool isTestMonitorFileDeleted = false; + private bool isTestMonitorFileWritten = false; + private bool isTestMonitorFileRead = false; + private bool isTestMonitorFileSecurityChanged = false; + private bool isTestMonitorFileInfoChanged = false; + + /// + /// Test monitor IO registration,get notification for the registered IO. + /// + private bool isOnFileOpenEventWasCalled = false; + private bool isOnSetFileSizeEventWasCalled = false; + + /// + /// Unit test folder + /// + private string unitTestFolder = "c:\\EaseFilterUnitTest"; + + /// + /// Test Control IO feature with callback function + /// + private string unitTestCallbackFolder = "c:\\EaseFilterUnitTest\\callbackFolder"; + private string unitTestCallbackFile = "c:\\EaseFilterUnitTest\\callbackFolder\\unitTestFile.txt"; + + //Purchase a license key with the link: http://www.easefilter.com/Order.htm + //Email us to request a trial key: info@easefilter.com //free email is not accepted. + public string licenseKey = "******************************************"; + + + public MonitorUnitTest() + { + InitializeComponent(); + StartPosition = FormStartPosition.CenterParent; + } + + + private void InitializeUnitTest() + { + + if (!Directory.Exists(unitTestMonitorTestFolder)) + { + Directory.CreateDirectory(unitTestMonitorTestFolder); + } + + if (!Directory.Exists(unitTestCallbackFolder)) + { + Directory.CreateDirectory(unitTestCallbackFolder); + } + + if (!File.Exists(unitTestCallbackFile)) + { + File.AppendAllText(unitTestCallbackFile, "This is unitTestCallbackFile test file."); + } + + } + + private void CleanupTest(string folder) + { + try + { + if (Directory.Exists(folder)) + { + Directory.Delete(folder, true); + } + + } + catch (Exception ex) + { + AppendText("Clean up test folder failed:" + ex.Message, Color.Red); + } + } + + private void AppendText(string text, Color color) + { + if (color == Color.Black) + { + richTextBox_TestResult.AppendText(Environment.NewLine); + richTextBox_TestResult.SelectionFont = new Font("Arial", 12, FontStyle.Bold); + } + + richTextBox_TestResult.SelectionStart = richTextBox_TestResult.TextLength; + richTextBox_TestResult.SelectionLength = 0; + + richTextBox_TestResult.SelectionColor = color; + richTextBox_TestResult.AppendText(text + Environment.NewLine); + richTextBox_TestResult.SelectionColor = richTextBox_TestResult.ForeColor; + + if (color == Color.Black) + { + richTextBox_TestResult.AppendText(Environment.NewLine); + } + + + } + + + /// + /// Fires this event when a file's information was changed after the file handle closed + /// + public void NotifyFileWasChanged(object sender, FileChangedEventArgs e) + { + if (string.Compare(unitTestMonitorTestFile, e.FileName, true) == 0) + { + if ((e.eventType & FilterAPI.FileChangedEvents.NotifyFileWasCreated) > 0) + { + isTestMonitorFileCreated = true; + } + + if ((e.eventType & FilterAPI.FileChangedEvents.NotifyFileWasWritten) > 0) + { + isTestMonitorFileWritten = true; + } + + if ((e.eventType & FilterAPI.FileChangedEvents.NotifyFileWasRenamed) > 0) + { + isTestMonitorFileReanmed = true; + } + + if ((e.eventType & FilterAPI.FileChangedEvents.NotifyFileWasDeleted) > 0) + { + isTestMonitorFileDeleted = true; + } + + if ((e.eventType & FilterAPI.FileChangedEvents.NotifyFileInfoWasChanged) > 0) + { + isTestMonitorFileInfoChanged = true; + } + + if ((e.eventType & FilterAPI.FileChangedEvents.NotifyFileSecurityWasChanged) > 0) + { + isTestMonitorFileSecurityChanged = true; + } + + if ((e.eventType & FilterAPI.FileChangedEvents.NotifyFileWasRead) > 0) + { + isTestMonitorFileRead = true; + } + + } + } + + + private void MonitorFileEventsUnitTest() + { + string lastError = string.Empty; + + // + //Test case1: Monitor File IO ( creation,rename,delete,write,security change,file info change, file read) + //Register file events to get the notification when the registered IO was triggered. + //This test will notify the UnitTestCallbackHandler with the IO events which we did below. + // + + + FileFilter monitorFilterRule = new FileFilter(unitTestMonitorTestFolder + "\\*"); + monitorFilterRule.AccessFlags = (FilterAPI.AccessFlag)FilterAPI.ALLOW_MAX_RIGHT_ACCESS; + monitorFilterRule.FileChangeEventFilter = (FilterAPI.FileChangedEvents.NotifyFileWasCreated | FilterAPI.FileChangedEvents.NotifyFileWasDeleted | FilterAPI.FileChangedEvents.NotifyFileInfoWasChanged + | FilterAPI.FileChangedEvents.NotifyFileWasRenamed | FilterAPI.FileChangedEvents.NotifyFileWasWritten |FilterAPI.FileChangedEvents.NotifyFileSecurityWasChanged|FilterAPI.FileChangedEvents.NotifyFileWasRead); + + + //register the file changed event handler + monitorFilterRule.NotifyFileWasChanged += NotifyFileWasChanged; + + try + { + filterControl.ClearFilters(); + filterControl.AddFilter(monitorFilterRule); + + if (!filterControl.SendConfigSettingsToFilter(ref lastError)) + { + MessageBox.Show(lastError, "SendConfigToFilter", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + //create and write events + File.AppendAllText(unitTestMonitorTestFile, "This is IO events monitor test file."); + + //read event + File.ReadAllText(unitTestMonitorTestFile); + + //file info change event + File.SetAttributes(unitTestMonitorTestFile, FileAttributes.Normal); + + // Get a FileSecurity object that represents the current security settings. + DirectoryInfo dInfo = new DirectoryInfo(unitTestMonitorTestFile); + DirectorySecurity dSecurity = dInfo.GetAccessControl(); + dSecurity.AddAccessRule(new FileSystemAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null), FileSystemRights.FullControl, InheritanceFlags.ObjectInherit | InheritanceFlags.ContainerInherit, PropagationFlags.NoPropagateInherit, AccessControlType.Allow)); + //test security change event + dInfo.SetAccessControl(dSecurity); + + //test rename event. + string newMonitorFileName = unitTestMonitorTestFolder + "\\newMonitorFileName.txt"; + File.Move(unitTestMonitorTestFile, newMonitorFileName); + + //create test file for deletion. + File.AppendAllText(unitTestMonitorTestFile, "This is IO events monitor test file."); + + //test delete event. + File.Delete(unitTestMonitorTestFile); + File.Delete(newMonitorFileName); + + //wait for the test result. + System.Threading.Thread.Sleep(3000); + } + catch (Exception ex) + { + AppendText("FileEventMonitorTest failed." + ex.Message, Color.Red); + } + finally + { + filterControl.RemoveFilter(monitorFilterRule); + filterControl.SendConfigSettingsToFilter(ref lastError); + } + + } + + + public void OnFileOpen(object sender, FileCreateEventArgs e) + { + if (string.Compare(unitTestCallbackFile, e.FileName, true) == 0) + { + isOnFileOpenEventWasCalled = true; + } + } + + public void OnSetFileSize(object sender, FileSizeEventArgs e) + { + if (string.Compare(unitTestCallbackFile, e.FileName, true) == 0) + { + isOnSetFileSizeEventWasCalled = true; + } + } + + private void MonitorIOEventsUnitTest() + { + string lastError = string.Empty; + string message = "Monitor IO Registration Unit Test"; + AppendText(message, Color.Black); + + message = " 1. Register the POST_CREATE and POST_SET_INFORMATION." + Environment.NewLine; + message += " 2. The callback function will get the notification after the file was opened or file information was changed." + Environment.NewLine; + + AppendText(message, Color.Gray); + + FileFilter fileMonitorFilter = new FileFilter(unitTestCallbackFolder + "\\*"); + fileMonitorFilter.MonitorFileIOEventFilter = (ulong)(MonitorFileIOEvents.OnFileOpen | MonitorFileIOEvents.OnSetFileSize); + + fileMonitorFilter.OnFileOpen += OnFileOpen; + fileMonitorFilter.OnSetFileSize += OnSetFileSize; + + try + { + filterControl.ClearFilters(); + filterControl.AddFilter(fileMonitorFilter); + filterControl.SendConfigSettingsToFilter(ref lastError); + + FileStream fs = new FileStream(unitTestCallbackFile, FileMode.Open, FileAccess.ReadWrite); + fs.SetLength(1024); + + fs.Close(); + + //wait for the test result. + System.Threading.Thread.Sleep(3000); + + } + catch (Exception ex) + { + AppendText("Monitor IO Registration Unit Test failed." + ex.Message, Color.Red); + } + finally + { + filterControl.ClearFilters(); + filterControl.SendConfigSettingsToFilter(ref lastError); + } + + if (isOnFileOpenEventWasCalled) + { + AppendText("Test file open event passed.", Color.Green); + AppendText("The OnFileOpen event was invoked.", Color.Gray); + } + else + { + AppendText("Test file open event failed.", Color.Red); + } + + + if (isOnSetFileSizeEventWasCalled) + { + AppendText("Test file size change event passed.", Color.Green); + AppendText("The OnFileSetFileSize event was invoked.", Color.Gray); + } + else + { + AppendText("Test OnFileSetFileSize event failed.", Color.Red); + } + } + + private void ShowMonitorFileEventsUnitTestResult() + { + + /// print out the monitor IO events test result. + string message = "Monitor File IO Events Unit Test."; + AppendText(message, Color.Black); + message = "Register the monitor file IO events: create,rename,delete,written,file info changed, read, security change in the test folder." + Environment.NewLine; + AppendText(message, Color.Gray); + + if (isTestMonitorFileCreated) + { + AppendText("Test new file creation event passed.", Color.Green); + AppendText("A test file was created.", Color.Gray); + } + else + { + AppendText("Test new file creation event failed.", Color.Red); + } + + if (isTestMonitorFileInfoChanged) + { + AppendText("Test file info change event passed.", Color.Green); + AppendText("The test file's attributes were changed.", Color.Gray); + } + else + { + AppendText("Test file info change event failed.", Color.Red); + } + + if (isTestMonitorFileRead) + { + AppendText("Test file read event passed.", Color.Green); + AppendText("The test file's data was read.", Color.Gray); + } + else + { + AppendText("Test file read event failed.", Color.Red); + } + if (isTestMonitorFileReanmed) + { + AppendText("Test file rename event passed.", Color.Green); + AppendText("The test file was renamed.", Color.Gray); + } + else + { + AppendText("Test file rename event failed.", Color.Red); + } + if (isTestMonitorFileSecurityChanged) + { + AppendText("Test file security change event passed.", Color.Green); + AppendText("The test file's security was changed.", Color.Gray); + } + else + { + AppendText("Test file security change event failed.", Color.Red); + } + + if (isTestMonitorFileWritten) + { + AppendText("Test file written event passed.", Color.Green); + AppendText("The test file was written.", Color.Gray); + } + else + { + AppendText("Test file written event failed.", Color.Red); + } + + + if (isTestMonitorFileDeleted) + { + AppendText("Test file delete event passed.", Color.Green); + AppendText("The test file was deleted.", Color.Gray); + } + else + { + AppendText("Test file delete event failed.", Color.Red); + } + } + + + public void StartFilterUnitTest() + { + try + { + CleanupTest(unitTestFolder); + + InitializeUnitTest(); + + MonitorFileEventsUnitTest(); + + MonitorIOEventsUnitTest(); + + ShowMonitorFileEventsUnitTestResult(); + + + } + catch (Exception ex) + { + richTextBox_TestResult.Text = "Filter test exception:" + ex.Message; + } + } + + private void MonitorDemo_Activated(object sender, EventArgs e) + { + if (!isUnitTestStarted) + { + isUnitTestStarted = true; + + string lastError = string.Empty; + if (!filterControl.StartFilter(FilterAPI.FilterType.MONITOR_FILTER, GlobalConfig.FilterConnectionThreads, GlobalConfig.ConnectionTimeOut,licenseKey, ref lastError)) + { + MessageBox.Show(lastError, "StartFilter", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + System.Threading.Thread.Sleep(3000); + + StartFilterUnitTest(); + + filterControl.StopFilter(); + } + } + } +} diff --git a/Demo_Source_Code/CSharpDemo/FileMonitor/MonitorUnitTest.resx b/Demo_Source_Code/CSharpDemo/FileMonitor/MonitorUnitTest.resx new file mode 100644 index 0000000..60985f5 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FileMonitor/MonitorUnitTest.resx @@ -0,0 +1,570 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + AAABAAgAEBAAAAEACABoBQAAhgAAABAQAAABACAAaAQAAO4FAAAYGAAAAQAIAMgGAABWCgAAGBgAAAEA + IACICQAAHhEAACAgAAABAAgAqAgAAKYaAAAgIAAAAQAgAKgQAABOIwAAMDAAAAEACACoDgAA9jMAADAw + AAABACAAqCUAAJ5CAAAoAAAAEAAAACAAAAABAAgAAAAAAEABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP// + /wAygPwAvYp4AH/e/wD/3ZcAwMDAAHyX4QB2dXQA7trOAKCgoADhrooAjMXWAKHB/wCZhnMAvaySAP/3 + ywDxyIIA0tLSAJGQjQDMrqoA/9y4AK16cAD/8OEA0p+CAIqo3gD5xpYAhIJ9AOS8mACrq6sA3trEAPTd + qQD//+oA/+THAP/RhADEnIgA8tWYAP/npgD96NUAceH/APjouwA4jP8AxpN9AJmOgwCZl5QAqoF6AO26 + kAC1gnQA782QAIaHhwD/+vUAtKiXANmmhgD/1ZAAmLz/AMjBugD22qAAmpSLAP/uvQDQtLAA//bsAIuf + 3QDRzssA/+DAAPntwgCZiXoAfn5/AP/t2gD/584AOoX/APn5+QD+2Z0AnJycAHt5dQDguJUAsX5yAIam + 4gC5hnYAwY56APXClADxvpIA6baOAOWyjADdqogA///yAP7WmAD8/PwAqKioAJaPhwDw0JQA1tPPAJmM + fgDVooQAz8/PAMTBvgA2iP8A//jwAMmWfgD/69YA/+nSAJuSiADHnokAgYB/AI+OiwDCwsIA//37AP/+ + 7wD/7t0A/9qWAJmUjgCrqqgAd3d2ALOAcwC3hHUAmZCHANekhACFhYYA//v3AHt4cwCZi3wA/v7+APr6 + +gD+0IUAuod3AL6LeQDCj3sAxZJ8AJ2dnQDcqYcAw8C9AP/37wCAgIAAgoB+AK57cADV0s8AkpCNAMfB + ugAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAACNhfk4DTS9LFhQ9WIcAAGUJRkZ5VngBAQENRQRkAAAYAXJtLGhdARIZAicp + BwAAcwEXPGlXQgiDEwxfNjsAAIABcl5/DyJ6VTlnTAGFAAALAWsyhAUkMBFHMQEBcAAAUgErWnY6KB9Z + NW8SAXEAAFEBYmAbIGpAOGx0AXh7AAAuAXc3Ch5UECUzSAZWfAAAUAEhY4JuhElmHWl1eX0AAE8BDkFb + iGCGPoFtbUYqAAAaARU/IURiQ2sXFxdGYQAAHCYBAQEBAQEBAQEBCS0AAABKGk9QLlFSC1M0XC0AAAAA + AAAAAAAAAAAAAAAAAAD//wAAwAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAIAB + AACAAQAAgAEAAMADAAD//wAAKAAAABAAAAAgAAAAAQAgAAAAAABABAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAMuYf8zJln7/xZJ8/8GOev+9inj/uYZ2/7WCdP+xfnL/rXpw/8yuqv+Ln93/l5CI/Xdz + bH4AAAAAAAAAAM6bgMzu2s7/+fn5//n5+f/6+vr//Pz8//7+/v////////////////+hwf//OoX//3/e + //+dlIr+AAAAAAAAAADSn4L//////5mQh/+ZlI7/mZeU/8LCwv/Pz8///////9LS0v+KqN7/MoD8/3Hh + //84jP//fJfh/wAAAAAAAAAA16SE////////8OH///bs///9+/+oqKj/fn5//3Z1dP+AgID/kZCN/4zF + 1v82iP//mLz//9C0sP8AAAAAAAAAANyph///////mZCH/8TBvv+dnZ3/vayS///RhP/+0IX//taY/5qU + i/+Pjov/hqbi//////+ue3D/AAAAAAAAAADhror////////u3f//+vX/goB+///dl//y1Zj/782Q//HI + gv/+2Z3/hoeH////////////s4Bz/wAAAAAAAAAA5bKM//////+ZjoP/1tPP/3t4c///7r3/+Oi7//Td + qf/w0JT//9WQ/3d3dv/S0tL//////7eEdf8AAAAAAAAAAOm2jv///////+vW///48P+Egn3////q///+ + 7//57cL/9tqg///alv+FhYb///////7+/v+6h3f/AAAAAAAAAADtupD//////5mLfP/Iwbr/oKCg/97a + xP////L///fL///npv+0qJf/nJyc/8DAwP/8/Pz/vot5/wAAAAAAAAAA8b6S////////5Mf//+nS///3 + 7/+rqqj/goB+/3t5df+BgH//q6ur///9+///+/f/+vr6/8KPe/8AAAAAAAAAAPXClP//////mYZz/5mJ + ev+ZjH7/x8G6///48P/V0s//0c7L/8PAvf+ZlI7/mZSO//n5+f/Gk33/AAAAAAAAAAD5xpb////////c + uP//4MD//+TH///nzv//69b//+3a///u3f//8OH///Dh///w4f/5+fn/yZZ+/wAAAAAAAAAA88CTzP3o + 1f//////////////////////////////////////////////////////7trO/6p3bswAAAAAAAAAAAAA + AADuu5DM+caW//XClP/xvpL/7bqQ/+m2jv/lsoz/4a6K/92qiP/Zpob/1aKE/6p3bswAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAD//wAAwAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAMAD + AAD//wAAKAAAABgAAAAwAAAAAQAIAAAAAACgAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8AGVv/AK98 + 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 + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADJln6pyZZ+/8aTfP/EkXv/wY56/7+Mef+9inj/uod2/7iF + df+2g3T/s4Bz/7F+cv+vfHH/rHlv/6p3bv+odW3/qnp0/9TEyP+Jg3j/hICA+GNjYzgAAAAAAAAAAM6b + gKnZr5j/9eLU///27v//+vX///38//////////////////////////////////////////////////// + ////////9vf//wZF//9Oheb/5drP/357evkAAAAAAAAAANKfgv/24dD///Pn///27v//+vX///38//// + ///////////////////////////////////////////////////z9f//DEr//0ac//9k1///ZZ3p/4yH + gf8AAAAAAAAAANShg/////////Ll///17P+ZlZL/mZeW/5mZmf+ZmZn/mZmZ//////////////////// + //////////////Hz//8LSf//SaL//2/Z//9Xt///D1r//7+zv/8AAAAAAAAAANajhP////////Ll///0 + 6v//9/H///v4////////////////////////////+vr6//n5+f//////8fHw/4SCh/87jOH/bt3//1a0 + //8ZW///4+f//7KGgf8AAAAAAAAAANilhf////////Dj///06v+ZlI//mZaT/5mYl/+ZmZn/y8vL/7Oz + tf+ChYj/fXx5/358ev+ChIj/jo+Q/62qpf/Ax8L/QZrp/xRW///m6////////6l2bv8AAAAAAAAAANqn + hv///////+/g///z5///9ez///nz///8+v//////o6Wn/7Wrl//10JT/+9KT//vTmv/8153/wrWh/4CD + if/EwLv/goKQ/+nt/////////////6t4b/8AAAAAAAAAAN2qh////////+7e///w4/+Zkoz/mZSR/5yZ + lv/b29z/rKSS//zXmv/x0Zv/79CZ/+7Nkf/wz5f/+tef/7+znf+Ki4z/ysrI/////////////////657 + cP8AAAAAAAAAAOCtif///////+zZ///v4P//8+f///Xs///59f+UlJf/9Nii//Xdqv/x26r/8dup//DU + ov/v0Jf/8M6a//7ao/+PkZT//////////////////////7B9cf8AAAAAAAAAAOKviv///////+rX///u + 3v+ZkIj/mZKM/62ppf+AgH7//+i1//blvv/358D/9eK4//Pdsf/x1qX/8NCV//3apP+FhIL/2NjY//// + /////////////7J/cv8AAAAAAAAAAOSxi////////+nV///s2f//7+D///Ll///38P+Eg4L///PI//z1 + 3P/689b/9+zI//bnvf/z3K3/8NOe//7Zof+EhIP//////////////////////7WCdP8AAAAAAAAAAOaz + jP///////+fQ///q1/+ZjoT/mY+G/62nof+enp3/7+bF////8P/+/vz//Pbb//fsx//24bP/89ek//TY + pP+Rk5b//////////////////////7iFdf8AAAAAAAAAAOi1jv///////+XM///o0v//6tf//+7e///y + 5//z7OX/paOc////7P////f//fnl//nuzP/347b//+Gm/6Sdkv/b29z//////////////////////7qH + dv8AAAAAAAAAAOy5j////////+PJ///mzv+Zi37/mY6C/52Tif+tpp//vru5/6Khm//j3sL///zT///y + wv/p1av/oJuS/7Kztv+/v7//mZmZ/////////////////72KeP8AAAAAAAAAAO67kP///////+HF///j + yf//5s7//+nV///s2f//7+D///Pp//Lr5P+lpKT/gICD/4CCgv+ampz/5OPj///9/f////////////// + /////////////7+Mef8AAAAAAAAAAPC9kf///////9/A///hxf+ZiHn/mYt9///p1f+ZjoL/nZOJ/6ae + lv+tp6H/r6mk/62npP+jn53///nz/5mWk/+Zl5X/mZeW///9/P///fz///38/8GOev8AAAAAAAAAAPK/ + k////////928///fwP//4cX//+PJ///mzv//6NL//+rX///t3P//7+D///Dj///z5///9Or///Xs///2 + 7v//9/H///nz///69f//+vX///r1/8SRe/8AAAAAAAAAAPTBlP///////9u4///dvP+ZhnP/mYd2/5mI + ef+Zinz/mYt+///q1/+ZjoL/mY+F/5mPhv+ZkIj/mZKL/5mSjP+Zkoz/mZOO///27v//9u7///bu/8eU + ff8AAAAAAAAAAPbDlf///////9mz///buP//3bz//9/A///hxf//48n//+XM///n0P//6dX//+rX///s + 2f//7t7//+/g///w4///8uX///Ll///z5///8+f///Pn/8qXfv8AAAAAAAAAAPnGlv/+8eb//+7e///Z + s///27j//928///evv//4MP//+LH///lzP//5s7//+fQ///p1f//6tf//+zZ///t3P//7t7//+7e///v + 4P//7+D/9uDQ/8yZf/8AAAAAAAAAAPjFlj36ypz//vHm//////////////////////////////////// + ///////////////////////////////////////////////////338z/27KZ/8yZf6kAAAAAAAAAAAAA + AAD4xZY9+caW//fElf/1wpT/88CT//G+kv/vvJH/7bqQ/+q3j//otY7/5rOM/+Sxi//ir4r/4K2J/96r + iP/ap4b/2KWF/9ajhP/UoYP/0J2BqQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA////AMAAAwCAAAEAgAABAIAAAQCAAAEAgAABAIAAAQCAAAEAgAABAIAAAQCAAAEAgAABAIAA + AQCAAAEAgAABAIAAAQCAAAEAgAABAIAAAQCAAAEAwAABAOAAAwD///8AKAAAACAAAABAAAAAAQAIAAAA + AACABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8ANF/oAMCNeQBt2f8ATVNaAPvboQB5pLUAxsjQAEtw + qgBfiP8AeX6EAK6ppADksYsA+O/PAKBuagBNsfgAmZONADqL/wBkZ20A2cmkAN3d3QDi270AUG7oAMie + kADNtLUA8sqLAIqTpAA8b/8A7u3sAJmGdAD/3r4AW3KXAF/A/wC1t7gArqKNALB9cQD//N8A79vRAJ2d + nQDXpIQA69GeAIiKjgDu8f8AKnb/AOe9nwDEwr8A7tuwAL2yogD/9+8A4cKQALWRhQDx5cEAzZp/APvI + lwDW1NIA/+3cAPG+kgCJh4EAkZOXAP3rvAD/5MoAOmfxAOLRqgCZjIAA2byhAM/LxwDi2dIApKWpAMa2 + wwDhyZoAsKmYAPLVpwCodW0AVrT/AODm5ACysK8A9dKaAPb29gD39+cA99+rAIGEiQBYgP8A6uHYALeE + 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 + AAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPgAAAH//////////8oAAAAIAAAAEAAAAABACAAAAAAAIAQ + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAHVvWSSGhH3maWhndGJiYl6EhIQCAAAAAAAAAAAAAAAAAAAAALqHdrW2g3T/tYJz/7SB + c/+zgHL/sX5y/7B9cf+vfHH/rntw/616cP+seW//q3hv/6l2bv+odW3/p3Rt/6ZzbP+lcmz/pHFr/6Nw + a/+hbmr/oG1p/6Bua//NtLX/UG7o/4qTpP/Nx8L/iIiH/2NjY2kAAAAAAAAAAAAAAAC6h3a1yJ6Q/+/b + 0f//+PL///v3///+/f////////////////////////////////////////////////////////////// + /////////////////////////Pz//1+I//8qdv//S63//+Dm5P/Py8f/aGhoeQAAAAAAAAAAAAAAAL6L + eP/v2s7///Xs///48v//+/f///79//////////////////////////////////////////////////// + //////////////////////////////v7//9bhv//Lnn//1a0//9o1f//W73//66urv+MioTTAAAAAAAA + AAAAAAAAwI15///+/v//9ez///jy///79////fv///////////////////////////////////////// + ///////////////////////////////////6+///WID//y97//9Zt///bNb//1/A//87j///Omfx/4V/ + clcAAAAAAAAAAAAAAADDkHr////////06v//9/D/mZaT/5mYl/+ZmZn/mZmZ//////+ZmZn/mZmZ/5mZ + mf+ZmZn/mZmZ/5mZmf+ZmZn/mZmZ////////////7u3s/1Bw8f8wevz/Wrn//2zW//9ev///Po7//zxv + ///GtsP/AAAAAAAAAAAAAAAAAAAAAMaTfP////////Pp///27v+ZlZL/mZeV/5mZmf+ZmZn//////5mZ + mf+ZmZn/nZ2d/7W1tf/FxcX/zMzM/8vLy//ExMT///////r6+v+Xk4r/W3KX/0qr9P9t2f//Xb7//z2N + //9AcP//7vH//65/ef8AAAAAAAAAAAAAAAAAAAAAyZZ9////////8+n///bu///48v//+/f///79//// + ///////////////////29vb/tbe4/4qMkf+EiJD/hIiP/4GEif+vsLH/6Ojo/46Ojf/i2dL/eaS1/02x + +P86i///RHP///Dz////////qndu/wAAAAAAAAAAAAAAAAAAAADKl37////////y5///9ez/mZWR/5mW + k/+ZmJf/mZmZ/5mZmf+0tLT/vL29/3Z7gv+yp5L/5ceW//HJjP/1zJH/8c+f/72yov9NU1n/kJCS/+7t + 7P/q4dj/S3Cq/zRf6P/y9P////////////+seW//AAAAAAAAAAAAAAAAAAAAAMyZf/////////Ll///0 + 6v+ZlJD/mZWS/5mXlf+ZmZn/qqqq/7+/wP+Agob/4cKQ//LKiv/syI7/6saP//DQnf/v06P/8MeK/+/O + mv9kZ23/mpuc/5OSkf+emYz/xsjQ/////////////////698cf8AAAAAAAAAAAAAAAAAAAAAz5yA//// + ////8eP///Pp///17P//+PL///v3///+/f/5+fn/h4uP/+bJmv/105n/79Ca/+/Qmf/vz5j/7s2Q/+7I + i//y06T/9NWg//LQn/9NUlr/3d3d/+jo6P//////////////////////sn9y/wAAAAAAAAAAAAAAAAAA + AADRnoH////////w4f//8uf/mZKM/5mUkP+ZlpP/srCv/8nKy/+uoo3/9NOc/+vQnv/q0p7/8dam//HV + ov/w057/79CY/+7Kjf/y1Kf/9dCR/7Ornf/CwsP///////////////////////////+0gXP/AAAAAAAA + AAAAAAAAAAAAANShg////////+/g///x4/+Zkoz/mZSP/5mVkf/DwsD/o6Wp/9nFmv/u16X/7Nep/+zX + qv/z3bD/89yt//Hbqf/w1KH/79Ca/+7Mj//227H/79Gj/5CSlv///////////////////////////7eE + dP8AAAAAAAAAAAAAAAAAAAAA16SE////////7dz///Dh///y5///9Or///fw///8+v+Qk5f/99+r//fm + vf/25r7/9unF//bnwP/35Ln/89+x//Hbqf/w1KH/78+V//LWqP/205r/jJCV//////////////////// + ////////uod2/wAAAAAAAAAAAAAAAAAAAADap4b////////s2v//7+D/mZGI/5mSjP+Zk47/zMrI/46Q + lv/13a7/+e7M//Xrz//06cr/8ufF//Divf/v3LP/7Niq//Hbqf/pzJb/7dGg//XRm/+EiI3/yMjI/5mZ + mf////////////////+9inf/AAAAAAAAAAAAAAAAAAAAANyph////////+rW///t3P+ZkIf/mZGJ/5mS + jP/Ewb7/pKWo/9nJpP//9tz/9/HY//f25//38Nv/9OnH//Hlwf/u27D/8tus/+nOmv/v0qD/582g/4mK + jv+/v7//mZmZ/////////////////7+MeP8AAAAAAAAAAAAAAAAAAAAA3quI////////6dX//+vY///u + 3v//8OH///Ln///37//a2dj/sKmY///83//+/fH//v36//7+8//89Nb/+O/P//bku//z3a//8dak//vb + of+roZL/x8jJ////////////////////////////wo96/wAAAAAAAAAAAAAAAAAAAADhror////////n + 0f//6tb/mY6D/5mPhv+ZkYj///Lo/9DNy/+hoKP/4tu9//r65f/7+/L/9/fn//Xw1//47sz/7961/+zX + qf/w157/4cma/3l+hP/7+/v////////////////////////////Fknv/AAAAAAAAAAAAAAAAAAAAAOOw + i////////+bP///o0/+ZjID/mY6E/5mPhv//8uX/q6ah/9bU0v+bm5r/5d7D//n54//69+P/9vDV//ru + yf/z4LL/992o/+DInf+AgYT/wMDA/////////////////////////////////8eUfP8AAAAAAAAAAAAA + AAAAAAAA5rOM////////5cz//+bP///p1f//69j//+3c///w4f//8uX///bv//Pw7v+jo6b/sq2e/+PY + uP//8MP//eu8/+LRqv+wqJf/hYiM/+Dg4f//////////////////////////////////////ypd+/wAA + AAAAAAAAAAAAAAAAAADpto3////////jyP//5cz/mYt9/5mMgP+ZjYL/mY6E/5mQh/+ZkYn/rqmk/9DO + zP/T0dH/np6i/4iKjv+Ehoz/kpSY/6ipqv/Nzc3//////5mZmf+ZmZn/mZmZ/5mZmf////////////// + ///MmX//AAAAAAAAAAAAAAAAAAAAAOu4jv///////+HE///kyv+ZiXv/mYt9/5mMgP+ZjYL/mY6E/5mQ + h/+ZkYn/npaQ///38P/JxsT/0c/N/9HPzf/Ix8X/tbSz/52cnP//////mZmZ/5mZmf+ZmZn/mZmZ//// + /////////////82af/8AAAAAAAAAAAAAAAAAAAAA7bqQ////////38H//+LG///kyv//5c3//+fR///p + 1f//69j//+3c///v4P//8eP///Ln///06v//9ez///fw///48v//+vX///v3///8+f///fv///79//// + ////////////////////////0J2B/wAAAAAAAAAAAAAAAAAAAADwvZH////////dvf//4ML/mYh3/5mJ + ef+ZiXv/mYt9/5mMgP//69j/mY6E/5mPhv+ZkIf/mZGJ/5mSjP//9Or/mZSP/5mUkP+ZlZH/mZWS/5mW + k/+Zl5T/mZeV/5mYl////fv///79///+/f/ToIL/AAAAAAAAAAAAAAAAAAAAAPPAk////////9y5///e + v/+ZhnT/mYh3/5mJef+ZiXv/mYt9///p1f+ZjID/mY6D/5mPhf+ZkIf/mZGI///y5/+Zkoz/mZKM/5mT + jv+ZlJD/mZWR/5mVkf+ZlZL/mZaT///79///+/f///v3/9ajhP8AAAAAAAAAAAAAAAAAAAAA9cKU//// + ////5s3//9y5///ev///4ML//+LG///kyv//5cz//+bP///o0///6tb//+vY///t3P//7+D///Dh///x + 4///8uf///Pp///06v//9ez///bu///27v//9/D///jy///48v//+PL/2KWF/wAAAAAAAAAAAAAAAAAA + AAD4xZX////////48v//5s3//9y5///dvf//38H//+HE///jyP//5cz//+bP///n0f//6dX//+rW///s + 2v//7dz//+/g///w4f//8eP///Ll///y5///8+n///Pp///06v//9ez///Xs/+7a0f/bqIb/AAAAAAAA + AAAAAAAAAAAAAPvIl4/6x5b///////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////9+//u2s3/572f/7aD + dI8AAAAAAAAAAAAAAAAAAAAAAAAAAPvIl4/7yJf/+seW//nGlv/4xZX/98SV//XClP/0wZP/88CT//K/ + kv/xvpL/8L2R/+67kP/tupD/7LmP/+y5j//ruI7/6reO/+m2jf/ntIz/5rOM/+Wyi//ksYv/47CL/+Kv + iv+2g3SPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/////////j4AAAAcAAAAHAAAABwAAAAcAA + AAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AA + AAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAAD4AAAB///////////KAAAADAAAABgAAAAAQAIAAAA + AACACgAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8AIVXwAMGOeQBt2f8ATE1PAPvboQCLldIArb3/ADhm + uQBfiP8AeX6EAK2qpwDlsosA+/DSAKBuagBNsfgAmZWLADmJ/wBnaGkA2cmkAOLe2gDi270ATInRAMai + kQDNtLUA8sqLAHWCtQA8b/8A7+3rAIV7awD/3r4AW3KXAGHE/wCytL8AqaCNALB9cQD//eMA79vRAJ2d + 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 + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI6MgwJycm/BcnJyu2Rk + ZChmZmY0V1dXAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQ3 + +CN7e4P+sK+t/4CAgP6CgoL/bW1twmxsbAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADPnICj0J2B/9Cd + gf/QnYH/0J2B/9Cdgf/QnYH/0J2B/8+cgP/PnID/z5yA/86bgP/Om4D/zpuA/82af//Nmn//zJl//8yZ + f//MmX//yZZ9/8iVff/Gk3z/xJF7/8KPev/Bjnn/vot4/72KeP+7iHb/uYZ1/7aDdP+0gXP/s4By/7B9 + cf+4i4H/vKu//yJR9f80cer/q6in/+Hg3/+UlJT/hISE/2VlZUsAAAAAAAAAAAAAAAAAAAAAAAAAANKf + gszQnYH/7tS////04///9OT///Xl///15///9ej///bp///26v//9+v///fs///47f//+O7///nv///5 + 8P//+fL///rz///69P//+/X///v2///89////Pj///z5///9+v///fz///79///+/v////////////// + ///////////////////d4///KFn//ytz//9CmP//aLTo/+bh3//m5eT/goKC/mVlZUAAAAAAAAAAAAAA + AAAAAAAA06CCo9Gegf/24s7///Pi///04///9OT///Xl///15///9ej///bp///26v//9+v///fs///4 + 7f//+O7///nv///58P//+fL///rz///69P//+/X///v2///89////Pj///z5///9+v///fz///79///+ + /v///////////////////////////9vi//8nWv//LHX//0OZ//9dv///ZM7//3/G7v/Hwr7/s7Kx/nR0 + dHsAAAAAAAAAAAAAAAAAAAAA1KGD//Xl2P//+O3///Pi///04///9OT///Xl///15///9ej///bp///2 + 6v//9+v///fs///47f//+O7///nv///58P//+fL///rz///69P//+/X///v2///89////Pj///z5///9 + +v///fz///78///+/f//////////////////////2N///ydY//8tdv//RJn//17A//9nzv//Y8j//0yq + //9XitP/npmS/3l5edwAAAAAAAAAAAAAAAAAAAAA1aKD////////8+H///Pi/4V/dv+Ff3f/hYB3/4WA + eP+FgHn/hYB6/4WAev+FgXv/hYF7/4WBfP//+O7///nv/4WCff+Fgn7/hYJ+/4WCf/+Fg4D/hYOA/4WD + gf+Fg4H/hYOC/4WEgv+FhIP/hYSD/4WEhP+FhIT/hYWF/5iYmP+jq8z/H1P5/y53//9GnP//X8H//2fO + //9ix///T6n//zqL//8XW/7/QFi8g3Fway4AAAAAAAAAAAAAAAAAAAAA1qOE////////8+H///Pi/4V/ + dv+Ff3f/hX93/4WAeP+FgHj/hYB5/4WAev+FgXv/hYF7/4WBfP//+O7///jv/4WCff+Fgn7/hYJ+/4WC + f/+Fg4D/hYOA/4WDgP+Fg4H/hYOC/4WEgv+FhIP/hYSD/4WEhP+Lior/sbGx/6GozP8cS+f/Lnn+/0ed + //9fwv//Z87//2LG//9OqP//OYr//x1c//+Hi9H/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA16SE//// + ////8+H///Pi/4V/dv+Ff3f/hX93/4WAeP+FgHj/hYB5/4WAev+FgXv/hYF7/4WBfP//+O7///jv/4WC + ff+Fgn7/hYJ+/4WCf/+Fgn//hYOA/4WDgP+Fg4H/hYOB/4WDgv+FhIL/hYSD/4uKif+vrq7/kpCM/yxM + sf8nauD/R5z8/2DE//9nzv//YcX//06n//85if//HVr//6e5///Gopr/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA2KWF////////8+H///Pi///z4v//9OT///Tl///15v//9ef///bo///26f//9ur///fr///3 + 7P//+O7///jv///57///+fD///ny///68///+/b///z4///9+v///fv///37///9+////vv///37///9 + /f/Nzcz/mZiX/5GQjf9Df8H/Wrny/2jP//9hxf//Tab//ziI//8cW///rb3///////+wfXH/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA2aaG////////8+D///Ph///z4v//9OT///Tl///15v//9ef///Xo///2 + 6f//9ur///fr///37P//+O3///ju///57///+fD///rz//369v/U0tD/np6c/3l6ev9naGn/Zmdo/3Z2 + dv+amZn/19bU///+/f/v7u3/g4OD/83My/+rrKr/WqjP/1m79P9Lpf//OIb//xxZ//+ywf////////// + //+zgHL/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA26iG////////8uD///Ph/4V/dv+Ff3b/hX93/4WA + d/+FgHj/hYB5/4WAev+FgHr/hYF7/4WBe/+FgXz/hYF8/4WBff+npaL/r66s/3R0df9wcnT/mpqZ/7+z + o//OvqT/0b+n/8G4qP+dnqH/YmVn/2VlZv9nZ2f/lJSU/7m5uf/+/f3/pKiq/0GIz/8weOj/GVHy/4ua + 0/////////////////+0gXP/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3KmH////////8uD///Ph/4V/ + dv+Ff3b/hX93/4V/d/+FgHj/hYB4/4WAef+FgHr/hYB6/4WBe/+FgXv/hYF8/66rqP+goJ//bm9y/6Gd + lf/YvI//8MaF/+/Iiv/nw4b/5sCF/+e9fv/mu3X/6cyi/7Gvrf9KS03/jIyM/+3t7f/MzMz/2NbV/4OJ + j/8YRsr/j5vS/6Kiov////////////////+2g3T/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3aqH//// + ////8uD///Ph/4V/dv+Ff3b/hX93/4V/d/+FgHj/hYB4/4WAef+FgHr/hYB6/4WBe/+FgXv/pqOf/6Wk + o/92eHv/u6yU/+nChf/nxIj/7syU/+7LlP/nxo//6cmU/+vPoP/rzqD/58KJ/+a6d//Wy7v/TlFT/5SU + lP+goKD/kZGR/6Skof+TlJb/r66u/4WFhf////////////////+5hnX/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA3quI////////8t////Pg///z4f//8+L///Tj///05P//9eX///Xn///16P//9uj///bp///3 + 6///+O7/5uPf/3l6fP+8rpb/9NCR/+/OlP/vzpX/7s6U/+7NlP/uy5L/7sqP/+3Hi//tzJf/8deu//DS + ov/swHv/1829/0tMTv9jY2P/0dHR/7GxsP/o5+f///79///+/f///v7///7+///+/v+7iHb/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA36yI////////8t////Lg///z4f//8+L///Tj///05P//9OX///Xm///1 + 5///9uj///bp///26v//+vP/oJ+f/5uWjv/21Jn/8NGc//DSnf/w0p3/8NKd//DRnP/v0Jn/79CY/+7N + kv/uyo//7cmP//HXrv/x06L/7sJ//6iopv+GhYb///79///+/f///fz///78///+/P///v3///79///+ + /f+9inj/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4K2J////////8t7///Lg/4V/df+Ff3X/hX92/4V/ + d/+Ff3f/hYB3/4WAeP+FgHn/hYB6/5GNiP+3tbP/f4GE/9W9kv/ozJj/8daj//HYpP/nz5z/58+d/+fN + nP/nzJn/58qV/+bIkv/vz5j/7suQ/+7JkP/y27H/7sqT/+zSq/9cXmH/7ezq///9+v///fv///37///9 + /P///fz///38///9/P++i3j/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4a6K////////8t7///Lf/4V+ + df+Ff3X/hX92/4V/dv+Ff3f/hX93/4WAeP+FgHj/hYB5/6WhnP+joqH/kI2J/+7RnP/o0J//8tus//Pc + rP/q06P/6tOj/+nSov/o0KD/58+c/+fMmf/w0p3/78+X/+7Lkf/w0KD/8NWr/+7Eg/+QkZX/urm4///9 + +v///fr///36///9+v///fr///36///9+v/Bjnn/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4q+K//// + ////8t7///Lf/4V+df+Ff3X/hX92/4V/dv+Ff3f/hX93/4WAd/+FgHj/hYB5/7Guqv+ampn/qaCN/+7T + o//s1aj/9eCz//Xgs//r16z/69is/+vXqf/q1af/6tOj/+jQn//x1qT/8NKd/+/Pl//vzJL/8tmz/+/I + iv+zrKL/lZSU///9+v///Pn///z5///8+f///Pn///z5///8+f/Cj3r/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA5LGL////////8d3///Le///y3///8+D///Ph///z4v//9OP///Tk///05f//9eb///Xn///6 + 8v+jo6P/uq+V//fhsf/25bz/9uW8//bpxf/368f/+OrE//blvv/247f/9eCy//Pdrv/x2aj/8dah//DR + nP/uzpL/8ter//DMlP/HuaX/hYSF///9+v///Pf///z4///8+P///Pj///z4///8+P/EkXv/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA5bKL////////8d3///Le///y3///8uD///Ph///z4v//8+L///Tk///0 + 5f//9eX///Xn///58f+mpqX/ua6W//jktv/36cT/++/S//vuzv/47s3/+O3K//fqxf/36b//9uO4//Xg + s//z3K//8dim//DTnv/vz5f/8dWn//DNlf/EtqL/hoaG///8+f//+/b///v3///89////Pf///z3///8 + 9//Gk3z/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA5rOM////////8dz///Hd/4V+dP+FfnT/hX91/4V/ + df+Ff3b/hX92/4V/d/+Ff3f/hYB4/7Kvqv+mpqX/rKOT//rpuv/x58n/9OvV//Tqzf/y68//8+jL//Dn + xP/u4r7/7d+5/+vYrv/q1af/8tqp//HWpP/nyZP/686f/+rHjf+vp5r/mZmY/6upp/+Fg4D/hYOA/4WD + gP//+/b///v2///79v/IlX3/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA57SM////////8dz///Hd/4V+ + dP+FfnT/hX51/4V/df+Ff3X/hX92/4V/dv+Ff3f/hX93/6ainP+ysa//k5GN//3twP/07NH/9fHd//Xx + 3v/49+z/+PXp//Przv/w5sb/7uTB/+3dtP/r2Kz/89ys//HXpf/nypX/6tCf/+nEif+Ki43/u7q4/5+c + mv+Fg4D/hYOA/4WDgP//+/X///v1///79f/Jln3/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA6LWN//// + ////8dv///Hc/4V+c/+FfnT/hX50/4V+df+Ff3X/hX92/4V/dv+Ff3f/hX93/5KOhv++vbr/k5SX/9/U + sv/07dH/9/Pg//n47v/6+vL/+fnw//Tv2P/x6cz/8ufH/+7et//r2Kz/892v//Hap//nypb/6c2a/9fA + mf9rbG//7Onn/42Kh/+Fgn//hYJ//4WCf///+vT///r0///69P/MmX//AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA6baO////////8Nv///Hb///x3f//8d3///Le///y4P//8+D///Ph///z4v//9OP///Tk///0 + 5f//+fD/x8bF/5mVi///+Nf//Pjh//387v///vf//f3v//z33f/79df/+vDR//jov//247j/892v//HZ + p//w1aD/9NKa/5qWkv+Xlpb///v3///68v//+vL///ry///68///+vP///rz///68//MmX//AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA6reO////////8Nr///Hb///x3P//8d3///Le///y3///8uD///Ph///z + 4f//8+L///Tj///05P//9ej/8u7p/6Wlp/+6tKD///3j//365f/9/Ov//Prp//354//79dv/++/O//fo + wv/25Lj/892u//Lap//216D/u7Cc/3Bxc//p5+P///nx///58f//+fH///nx///58v//+fL///ny///5 + 8v/MmX//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA67iP////////8Nr///Da/4V+cv+FfnP/hX5z/4V+ + dP+FfnT///Lg///z4f+Ff3b/hX92/4V/dv+Ff3f/qaWg/8XEwv+cnZ//tbGd//b01//389z/9vLc//v2 + 3v/y6cv/7uK8/+3cs//s2Kv/69Sm/+3TnP+3q5b/dHV4/6empP+hnpv///nv///58P//+fD///nw///5 + 8P//+fD///nw///58P/Nmn//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA7bqP////////8Nn///Da/4V9 + cv+FfnL/hX5z/4V+c/+FfnT///Lf///y4P+Ff3X/hX92/4V/dv+Ff3b/hX93/7Guqf/FxMP/o6Sl/5eV + i//a0rP/9OrE//3xyv/w5Lz/8OC2//HcsP/w2qr/1cKd/5mVj/95enz/p6Wk/6uopf+FgXz///jv///4 + 7///+O////nv///57///+e////nv///57//Nmn//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA7ruQ//// + ////79f///DZ/4V9cv+FfnL/hX5z/4V+c/+FfnT///Le///y3/+Ff3X/hX91/4V/dv+Ff3b/hX92/4V/ + d/+sqKL/xMK//7Oys/+Sk5P/k5GN/7CqnP+5sJv/urGZ/6yllf+Qjor/gIGD/4qJif+0s7D/pqOe/4WB + fP+FgXz///ju///47v//+O7///ju///47v//+O7///ju///47v/Om4D/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA77yQ////////79b///DZ///w2f//8Nr///Hb///x3P//8d3///Le///y3v//8uD///Pg///z + 4f//8+L///Pi///04///9OT///bp//347//i3tr/wsG+/6uqqv+bm5z/mJiY/52dnP+0srD/2tfT//75 + 8///+O3///fr///37P//9+z///fs///47f//+O3///jt///47f//+O3///jt///47f/Om4D/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA8L2R////////7tT//+/W///w2f//8Nr///Da///x2///8dz///Hd///y + 3v//8t////Lg///z4P//8+H///Pi///z4v//9OP///Tk///05P//9un///ju///58f//+vL///rz///6 + 8v//+fD///fs///26f//9ur///bq///36///9+v///fr///37P//9+z///fs///37P//9+z///fs///3 + 7P/Om4D/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8b6S////////7dL//+7U/4V9cP+FfXH/hX1y/4V9 + cv+FfnL/hX5z/4V+c/+FfnT/hX50/4V+df+Ff3X///Ph///z4v+Ff3b/hX92/4V/d/+Ff3f/hX93/4WA + d/+FgHj/hYB4/4WAeP+FgHn/hYB5/4WAef+FgHr///bp///26f+FgHr/hYB6/4WBe/+FgXv/hYF7/4WB + e///9+v///fr///36//PnID/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8r+S////////7ND//+7T/4V8 + b/+FfXD/hX1x/4V9cv+FfXL/hX5y/4V+c/+FfnP/hX50/4V+dP+FfnT///Lg///z4f+Ff3X/hX92/4V/ + dv+Ff3b/hX93/4V/d/+Ff3f/hYB3/4WAeP+FgHj/hYB4/4WAef+FgHn///bo///26f+FgHr/hYB6/4WA + ev+FgHr/hYB6/4WAev//9ur///bq///26v/PnID/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA88CT//// + ////7M7//+3R/4V8bv+FfG//hX1w/4V9cf+FfXL/hX1y/4V+cv+FfnP/hX5z/4V+dP+FfnT///Lf///y + 4P+Ff3X/hX91/4V/dv+Ff3b/hX92/4V/d/+Ff3f/hX93/4V/d/+FgHf/hYB4/4WAeP+FgHj///Xn///1 + 6P+FgHn/hYB5/4WAef+FgHn/hYB6/4WAev//9un///bp///26f/PnID/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA9MGT////////68z//+zP///t0f//7tP//+7V///w2f//8Nn///Da///w2///8dv///Hc///x + 3f//8t7///Le///y3///8uD///Pg///z4f//8+H///Pi///z4v//9OP///Tk///05P//9OX///Tl///1 + 5f//9eb///Xm///15///9ef///Xn///15///9ef///Xo///16P//9ej///Xo///16P/QnYH/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA9sOU////////6sv//+vN///sz///7dH//+7T///u1f//8Nn///DZ///w + 2v//8Nv///Hb///x3P//8d3///Hd///y3v//8t////Lg///y4P//8+H///Ph///z4v//8+L///Pi///0 + 4///9OT///Tk///05P//9OX///Tl///15f//9eb///Xm///15v//9eb///Xn///15///9ef///Xn///1 + 5//QnYH/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA98SU////////6sn//+rL/4V7a/+Fe2z/hXxt/4V8 + bv+FfG//hX1w/4V9cf+FfXL/hX1y/4V+cv+FfnP/hX5z/4V+c/+FfnT/hX50/4V+dP+FfnX/hX91///z + 4f//8+H/hX92/4V/dv+Ff3b/hX92/4V/dv+Ff3f/hX93/4V/d/+Ff3f/hX93/4V/d/+Ff3f/hYB3/4WA + d///9eX///Xl///15f/QnYH/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+MWV////////6cf//+rJ/4V6 + av+Fe2v/hXts/4V8bf+FfG7/hXxv/4V9cP+FfXH/hX1y/4V9cv+FfnL/hX5y/4V+c/+FfnP/hX5z/4V+ + dP+FfnT/hX50///y4P//8+D/hX91/4V/df+Ff3X/hX92/4V/dv+Ff3b/hX92/4V/dv+Ff3f/hX93/4V/ + d/+Ff3f/hX93/4V/d///9OT///Tk///05P/QnYH/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+caW//// + ////6MP//+nH/4V6af+Femr/hXtr/4V7bP+FfG3/hXxu/4V8b/+FfXD/hX1x/4V9cf+FfXL/hX1y/4V+ + cv+FfnP/hX5z/4V+c/+FfnT/hX50///y3///8t//hX51/4V+df+Ff3X/hX91/4V/df+Ff3b/hX92/4V/ + dv+Ff3b/hX92/4V/dv+Ff3b/hX92/4V/dv//9OP///Tj///04//QnYH/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA+seW////////58H//+jE///px///6sn//+rL///rzf//7M///+3R///u0///7tT//+/W///w + 2f//8Nn///Da///w2v//8dv///Hb///x3P//8d3///Hd///y3v//8t7///Lf///y3///8uD///Lg///z + 4P//8+H///Ph///z4f//8+H///Pi///z4v//8+L///Pi///z4v//8+L///Pi///z4v/QnYH/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA+8iX//7y4v//8Nn//+fB///ow///6cf//+rJ///qy///68z//+zO///s + 0P//7dL//+7U///v1v//79f///DZ///w2v//8Nr///Db///x2///8dz///Hc///x3f//8d3///Le///y + 3v//8t7///Lf///y3///8uD///Lg///y4P//8+D///Ph///z4f//8+H///Ph///z4f//8+H///Ph/+7U + v//QnYH/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/MmXo/zJl//+9OX///DZ///nwf//6MP//+jF///p + yP//6sr//+vM///szv//7ND//+3R///u0///7tX//+/X///w2f//8Nn///Da///w2v//8Nv///Hb///x + 3P//8dz///Hd///x3f//8d3///Le///y3v//8t7///Lf///y3///8t////Lg///y4P//8uD///Lg///y + 4P//9+z/9uHN/9Kfgv/PnICjAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP3KmMz8yZf//vLi//// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////15df/0Z6B/9KfgswAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAD8yZej+8iX//rHlv/5xpb/+MWV//fElP/2w5T/9MGT//PAk//yv5L/8b6S//C9kf/vvJD/7ruQ/+26 + j//ruI//6reO/+m2jv/otY3/57SM/+azjP/lsov/5LGL/+Kviv/hror/4K2J/9+siP/eq4j/3aqH/9yp + h//bqIb/2aaG/9ilhf/XpIT/1qOE/9Wig//UoYP/06CCowAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////AAD//////58AAP//////gwAA+AAAAAAD + AADwAAAAAAMAAOAAAAAAAQAA4AAAAAABAADgAAAAAAMAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAA + AAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAH + AADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAA + AAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAH + AADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAA + AAAABwAA4AAAAAAHAADwAAAAAA8AAPgAAAAAHwAA////////AAD///////8AAP///////wAA + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/FileMonitor/Program.cs b/Demo_Source_Code/CSharpDemo/FileMonitor/Program.cs new file mode 100644 index 0000000..aad9e04 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FileMonitor/Program.cs @@ -0,0 +1,73 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Windows.Forms; + +using EaseFilter.FilterControl; + +namespace FileMonitor +{ + static class Program + { + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main(string[] args) + { + + if (args.Length > 0) + { + string command = args[0]; + switch (command.ToLower()) + { + case "-installdriver": + { + bool ret = FilterAPI.InstallDriver(); + if (!ret) + { + Console.WriteLine("Install driver failed:" + FilterAPI.GetLastErrorMessage()); + } + + break; + } + + case "-uninstalldriver": + { + bool ret = FilterAPI.UnInstallDriver(); + if (!ret) + { + Console.WriteLine("UnInstall driver failed:" + FilterAPI.GetLastErrorMessage()); + } + + break; + } + } + } + else + { + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + Application.Run(new MonitorForm()); + } + + } + } +} diff --git a/Demo_Source_Code/CSharpDemo/FileMonitor/Properties/AssemblyInfo.cs b/Demo_Source_Code/CSharpDemo/FileMonitor/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..ae388a1 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FileMonitor/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("FileMonitor")] +[assembly: AssemblyDescription("Monitor File I/O Demo Application")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("EaseFilter Technologies")] +[assembly: AssemblyProduct("EaseFilter_FileMonitor.exe")] +[assembly: AssemblyCopyright("Copyright © EaseFilter Technologies")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("b8ffbab5-e350-4cf3-9015-a8ff4325ddeb")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +[assembly: AssemblyVersion("5.2.4.1001")] +//[assembly: AssemblyFileVersion("1.0.0.0")] + diff --git a/Demo_Source_Code/CSharpDemo/FileMonitor/Properties/Resources.Designer.cs b/Demo_Source_Code/CSharpDemo/FileMonitor/Properties/Resources.Designer.cs new file mode 100644 index 0000000..508f11a --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FileMonitor/Properties/Resources.Designer.cs @@ -0,0 +1,63 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace FileMonitor.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // 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", "16.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + 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() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [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("FileMonitor.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + } +} diff --git a/Demo_Source_Code/CSharpDemo/FileMonitor/Properties/Resources.resx b/Demo_Source_Code/CSharpDemo/FileMonitor/Properties/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FileMonitor/Properties/Resources.resx @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/FileMonitor/Properties/Settings.Designer.cs b/Demo_Source_Code/CSharpDemo/FileMonitor/Properties/Settings.Designer.cs new file mode 100644 index 0000000..17a1547 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FileMonitor/Properties/Settings.Designer.cs @@ -0,0 +1,26 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace FileMonitor.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.10.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default { + get { + return defaultInstance; + } + } + } +} diff --git a/Demo_Source_Code/CSharpDemo/FileMonitor/Properties/Settings.settings b/Demo_Source_Code/CSharpDemo/FileMonitor/Properties/Settings.settings new file mode 100644 index 0000000..3964565 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FileMonitor/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + diff --git a/Demo_Source_Code/CSharpDemo/FileMonitor/TrayForm.Designer.cs b/Demo_Source_Code/CSharpDemo/FileMonitor/TrayForm.Designer.cs new file mode 100644 index 0000000..e6ec864 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FileMonitor/TrayForm.Designer.cs @@ -0,0 +1,187 @@ +namespace FileMonitor +{ + partial class TrayForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(TrayForm)); + this.contextMenuStrip = new System.Windows.Forms.ContextMenuStrip(this.components); + this.consoleToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripMenuItem2 = new System.Windows.Forms.ToolStripSeparator(); + this.settingsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripMenuItem5 = new System.Windows.Forms.ToolStripSeparator(); + this.helpTopicsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.helpTopicsToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem(); + this.reportAProblemToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.uninstallDriverToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.openSourceCodeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.sdkToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripMenuItem3 = new System.Windows.Forms.ToolStripSeparator(); + this.exitToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem(); + this.notifyIcon = new System.Windows.Forms.NotifyIcon(this.components); + this.contextMenuStrip.SuspendLayout(); + this.SuspendLayout(); + // + // contextMenuStrip + // + this.contextMenuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.consoleToolStripMenuItem, + this.toolStripMenuItem2, + this.settingsToolStripMenuItem, + this.toolStripMenuItem5, + this.helpTopicsToolStripMenuItem, + this.openSourceCodeToolStripMenuItem, + this.sdkToolStripMenuItem, + this.toolStripMenuItem3, + this.exitToolStripMenuItem1}); + this.contextMenuStrip.Name = "contextMenuStrip_fileAgent"; + this.contextMenuStrip.Size = new System.Drawing.Size(194, 154); + this.contextMenuStrip.Text = "-"; + // + // consoleToolStripMenuItem + // + this.consoleToolStripMenuItem.Name = "consoleToolStripMenuItem"; + this.consoleToolStripMenuItem.Size = new System.Drawing.Size(193, 22); + this.consoleToolStripMenuItem.Text = "Show monitor console"; + this.consoleToolStripMenuItem.Click += new System.EventHandler(this.consoleToolStripMenuItem_Click); + // + // toolStripMenuItem2 + // + this.toolStripMenuItem2.Name = "toolStripMenuItem2"; + this.toolStripMenuItem2.Size = new System.Drawing.Size(190, 6); + // + // settingsToolStripMenuItem + // + this.settingsToolStripMenuItem.Name = "settingsToolStripMenuItem"; + this.settingsToolStripMenuItem.Size = new System.Drawing.Size(193, 22); + this.settingsToolStripMenuItem.Text = "Settings..."; + this.settingsToolStripMenuItem.Click += new System.EventHandler(this.settingsToolStripMenuItem_Click); + // + // toolStripMenuItem5 + // + this.toolStripMenuItem5.Name = "toolStripMenuItem5"; + this.toolStripMenuItem5.Size = new System.Drawing.Size(190, 6); + // + // helpTopicsToolStripMenuItem + // + this.helpTopicsToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.helpTopicsToolStripMenuItem1, + this.reportAProblemToolStripMenuItem, + this.uninstallDriverToolStripMenuItem}); + this.helpTopicsToolStripMenuItem.Name = "helpTopicsToolStripMenuItem"; + this.helpTopicsToolStripMenuItem.Size = new System.Drawing.Size(193, 22); + this.helpTopicsToolStripMenuItem.Text = "Help"; + // + // helpTopicsToolStripMenuItem1 + // + this.helpTopicsToolStripMenuItem1.Name = "helpTopicsToolStripMenuItem1"; + this.helpTopicsToolStripMenuItem1.Size = new System.Drawing.Size(241, 22); + this.helpTopicsToolStripMenuItem1.Text = "Help topics"; + this.helpTopicsToolStripMenuItem1.Click += new System.EventHandler(this.helpTopicsToolStripMenuItem1_Click); + // + // reportAProblemToolStripMenuItem + // + this.reportAProblemToolStripMenuItem.Name = "reportAProblemToolStripMenuItem"; + this.reportAProblemToolStripMenuItem.Size = new System.Drawing.Size(241, 22); + this.reportAProblemToolStripMenuItem.Text = "Report a problem or suggestion"; + this.reportAProblemToolStripMenuItem.Click += new System.EventHandler(this.reportAProblemToolStripMenuItem_Click); + // + // uninstallDriverToolStripMenuItem + // + this.uninstallDriverToolStripMenuItem.Name = "uninstallDriverToolStripMenuItem"; + this.uninstallDriverToolStripMenuItem.Size = new System.Drawing.Size(241, 22); + this.uninstallDriverToolStripMenuItem.Text = "Uninstall driver"; + this.uninstallDriverToolStripMenuItem.Click += new System.EventHandler(this.uninstallDriverToolStripMenuItem_Click); + // + // openSourceCodeToolStripMenuItem + // + this.openSourceCodeToolStripMenuItem.Name = "openSourceCodeToolStripMenuItem"; + this.openSourceCodeToolStripMenuItem.Size = new System.Drawing.Size(193, 22); + this.openSourceCodeToolStripMenuItem.Text = "Open SDK folder"; + this.openSourceCodeToolStripMenuItem.Click += new System.EventHandler(this.openSourceCodeToolStripMenuItem_Click); + // + // sdkToolStripMenuItem + // + this.sdkToolStripMenuItem.Name = "sdkToolStripMenuItem"; + this.sdkToolStripMenuItem.Size = new System.Drawing.Size(193, 22); + this.sdkToolStripMenuItem.Text = "SDK manual"; + this.sdkToolStripMenuItem.Click += new System.EventHandler(this.sdkToolStripMenuItem_Click); + // + // toolStripMenuItem3 + // + this.toolStripMenuItem3.Name = "toolStripMenuItem3"; + this.toolStripMenuItem3.Size = new System.Drawing.Size(190, 6); + // + // exitToolStripMenuItem1 + // + this.exitToolStripMenuItem1.Name = "exitToolStripMenuItem1"; + this.exitToolStripMenuItem1.Size = new System.Drawing.Size(193, 22); + this.exitToolStripMenuItem1.Text = "Exit"; + this.exitToolStripMenuItem1.Click += new System.EventHandler(this.exitToolStripMenuItem1_Click); + // + // notifyIcon + // + this.notifyIcon.ContextMenuStrip = this.contextMenuStrip; + this.notifyIcon.Icon = ((System.Drawing.Icon)(resources.GetObject("notifyIcon.Icon"))); + this.notifyIcon.Text = "EaseFilter File Monitor"; + this.notifyIcon.Visible = true; + + // + // TrayForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(263, 102); + this.Name = "TrayForm"; + this.Text = "TrayForm"; + this.WindowState = System.Windows.Forms.FormWindowState.Minimized; + this.Load += new System.EventHandler(this.TrayForm_Load); + this.contextMenuStrip.ResumeLayout(false); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.ContextMenuStrip contextMenuStrip; + private System.Windows.Forms.ToolStripMenuItem consoleToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem sdkToolStripMenuItem; + private System.Windows.Forms.ToolStripSeparator toolStripMenuItem2; + private System.Windows.Forms.ToolStripMenuItem settingsToolStripMenuItem; + private System.Windows.Forms.ToolStripSeparator toolStripMenuItem5; + private System.Windows.Forms.ToolStripMenuItem helpTopicsToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem helpTopicsToolStripMenuItem1; + private System.Windows.Forms.ToolStripMenuItem reportAProblemToolStripMenuItem; + private System.Windows.Forms.ToolStripSeparator toolStripMenuItem3; + private System.Windows.Forms.ToolStripMenuItem exitToolStripMenuItem1; + public System.Windows.Forms.NotifyIcon notifyIcon; + private System.Windows.Forms.ToolStripMenuItem openSourceCodeToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem uninstallDriverToolStripMenuItem; + + } +} \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/FileMonitor/TrayForm.cs b/Demo_Source_Code/CSharpDemo/FileMonitor/TrayForm.cs new file mode 100644 index 0000000..a7c35a3 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FileMonitor/TrayForm.cs @@ -0,0 +1,103 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +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; +using System.IO; + +using EaseFilter.CommonObjects; +using EaseFilter.FilterControl; + +namespace FileMonitor +{ + public partial class TrayForm : Form + { + MonitorForm monitorForm = new MonitorForm(); + + public TrayForm() + { + InitializeComponent(); + + } + + private void TrayForm_Load(object sender, EventArgs e) + { + this.Hide(); + this.notifyIcon.Visible = true; + monitorForm.ShowDialog(); + } + + private void consoleToolStripMenuItem_Click(object sender, EventArgs e) + { + if (!monitorForm.Visible) + { + monitorForm.StartPosition = FormStartPosition.CenterScreen; + monitorForm.ShowDialog(); + } + } + + private void settingsToolStripMenuItem_Click(object sender, EventArgs e) + { + SettingsForm settingForm = new SettingsForm(); + settingForm.StartPosition = FormStartPosition.CenterScreen; + settingForm.ShowDialog(); + } + + private void helpTopicsToolStripMenuItem1_Click(object sender, EventArgs e) + { + System.Diagnostics.Process.Start("http://www.easefilter.com/Forums_Files/FileMonitor.htm"); + } + + private void reportAProblemToolStripMenuItem_Click(object sender, EventArgs e) + { + System.Diagnostics.Process.Start("http://www.easefilter.com/ReportIssue.htm"); + } + + private void exitToolStripMenuItem1_Click(object sender, EventArgs e) + { + GlobalConfig.Stop(); + monitorForm.Close(); + + Application.Exit(); + } + + private void sdkToolStripMenuItem_Click(object sender, EventArgs e) + { + System.Diagnostics.Process.Start("http://www.easefilter.com/info/easefilter_manual.pdf"); + } + + private void openSourceCodeToolStripMenuItem_Click(object sender, EventArgs e) + { + System.Reflection.Assembly assembly = System.Reflection.Assembly.GetEntryAssembly(); + string AssemblyPath = Path.Combine(Path.GetDirectoryName(assembly.Location), "Demo"); + System.Diagnostics.Process.Start("explorer.exe", AssemblyPath); + } + + private void uninstallDriverToolStripMenuItem_Click(object sender, EventArgs e) + { + FilterAPI.UnInstallDriver(); + } + + + } +} diff --git a/Demo_Source_Code/CSharpDemo/FileMonitor/TrayForm.resx b/Demo_Source_Code/CSharpDemo/FileMonitor/TrayForm.resx new file mode 100644 index 0000000..fd0a6bb --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FileMonitor/TrayForm.resx @@ -0,0 +1,579 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 19, 18 + + + 214, 23 + + + + + AAABAAgAEBAAAAEACABoBQAAhgAAABAQAAABACAAaAQAAO4FAAAYGAAAAQAIAMgGAABWCgAAGBgAAAEA + IACICQAAHhEAACAgAAABAAgAqAgAAKYaAAAgIAAAAQAgAKgQAABOIwAAMDAAAAEACACoDgAA9jMAADAw + AAABACAAqCUAAJ5CAAAoAAAAEAAAACAAAAABAAgAAAAAAEABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP// + /wAygPwAvYp4AH/e/wD/3ZcAwMDAAHyX4QB2dXQA7trOAKCgoADhrooAjMXWAKHB/wCZhnMAvaySAP/3 + ywDxyIIA0tLSAJGQjQDMrqoA/9y4AK16cAD/8OEA0p+CAIqo3gD5xpYAhIJ9AOS8mACrq6sA3trEAPTd + qQD//+oA/+THAP/RhADEnIgA8tWYAP/npgD96NUAceH/APjouwA4jP8AxpN9AJmOgwCZl5QAqoF6AO26 + kAC1gnQA782QAIaHhwD/+vUAtKiXANmmhgD/1ZAAmLz/AMjBugD22qAAmpSLAP/uvQDQtLAA//bsAIuf + 3QDRzssA/+DAAPntwgCZiXoAfn5/AP/t2gD/584AOoX/APn5+QD+2Z0AnJycAHt5dQDguJUAsX5yAIam + 4gC5hnYAwY56APXClADxvpIA6baOAOWyjADdqogA///yAP7WmAD8/PwAqKioAJaPhwDw0JQA1tPPAJmM + fgDVooQAz8/PAMTBvgA2iP8A//jwAMmWfgD/69YA/+nSAJuSiADHnokAgYB/AI+OiwDCwsIA//37AP/+ + 7wD/7t0A/9qWAJmUjgCrqqgAd3d2ALOAcwC3hHUAmZCHANekhACFhYYA//v3AHt4cwCZi3wA/v7+APr6 + +gD+0IUAuod3AL6LeQDCj3sAxZJ8AJ2dnQDcqYcAw8C9AP/37wCAgIAAgoB+AK57cADV0s8AkpCNAMfB + ugAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAACNhfk4DTS9LFhQ9WIcAAGUJRkZ5VngBAQENRQRkAAAYAXJtLGhdARIZAicp + BwAAcwEXPGlXQgiDEwxfNjsAAIABcl5/DyJ6VTlnTAGFAAALAWsyhAUkMBFHMQEBcAAAUgErWnY6KB9Z + NW8SAXEAAFEBYmAbIGpAOGx0AXh7AAAuAXc3Ch5UECUzSAZWfAAAUAEhY4JuhElmHWl1eX0AAE8BDkFb + iGCGPoFtbUYqAAAaARU/IURiQ2sXFxdGYQAAHCYBAQEBAQEBAQEBCS0AAABKGk9QLlFSC1M0XC0AAAAA + AAAAAAAAAAAAAAAAAAD//wAAwAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAIAB + AACAAQAAgAEAAMADAAD//wAAKAAAABAAAAAgAAAAAQAgAAAAAABABAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAMuYf8zJln7/xZJ8/8GOev+9inj/uYZ2/7WCdP+xfnL/rXpw/8yuqv+Ln93/l5CI/Xdz + bH4AAAAAAAAAAM6bgMzu2s7/+fn5//n5+f/6+vr//Pz8//7+/v////////////////+hwf//OoX//3/e + //+dlIr+AAAAAAAAAADSn4L//////5mQh/+ZlI7/mZeU/8LCwv/Pz8///////9LS0v+KqN7/MoD8/3Hh + //84jP//fJfh/wAAAAAAAAAA16SE////////8OH///bs///9+/+oqKj/fn5//3Z1dP+AgID/kZCN/4zF + 1v82iP//mLz//9C0sP8AAAAAAAAAANyph///////mZCH/8TBvv+dnZ3/vayS///RhP/+0IX//taY/5qU + i/+Pjov/hqbi//////+ue3D/AAAAAAAAAADhror////////u3f//+vX/goB+///dl//y1Zj/782Q//HI + gv/+2Z3/hoeH////////////s4Bz/wAAAAAAAAAA5bKM//////+ZjoP/1tPP/3t4c///7r3/+Oi7//Td + qf/w0JT//9WQ/3d3dv/S0tL//////7eEdf8AAAAAAAAAAOm2jv///////+vW///48P+Egn3////q///+ + 7//57cL/9tqg///alv+FhYb///////7+/v+6h3f/AAAAAAAAAADtupD//////5mLfP/Iwbr/oKCg/97a + xP////L///fL///npv+0qJf/nJyc/8DAwP/8/Pz/vot5/wAAAAAAAAAA8b6S////////5Mf//+nS///3 + 7/+rqqj/goB+/3t5df+BgH//q6ur///9+///+/f/+vr6/8KPe/8AAAAAAAAAAPXClP//////mYZz/5mJ + ev+ZjH7/x8G6///48P/V0s//0c7L/8PAvf+ZlI7/mZSO//n5+f/Gk33/AAAAAAAAAAD5xpb////////c + uP//4MD//+TH///nzv//69b//+3a///u3f//8OH///Dh///w4f/5+fn/yZZ+/wAAAAAAAAAA88CTzP3o + 1f//////////////////////////////////////////////////////7trO/6p3bswAAAAAAAAAAAAA + AADuu5DM+caW//XClP/xvpL/7bqQ/+m2jv/lsoz/4a6K/92qiP/Zpob/1aKE/6p3bswAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAD//wAAwAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAMAD + AAD//wAAKAAAABgAAAAwAAAAAQAIAAAAAACgAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8AGVv/AK98 + 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 + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADJln6pyZZ+/8aTfP/EkXv/wY56/7+Mef+9inj/uod2/7iF + df+2g3T/s4Bz/7F+cv+vfHH/rHlv/6p3bv+odW3/qnp0/9TEyP+Jg3j/hICA+GNjYzgAAAAAAAAAAM6b + gKnZr5j/9eLU///27v//+vX///38//////////////////////////////////////////////////// + ////////9vf//wZF//9Oheb/5drP/357evkAAAAAAAAAANKfgv/24dD///Pn///27v//+vX///38//// + ///////////////////////////////////////////////////z9f//DEr//0ac//9k1///ZZ3p/4yH + gf8AAAAAAAAAANShg/////////Ll///17P+ZlZL/mZeW/5mZmf+ZmZn/mZmZ//////////////////// + //////////////Hz//8LSf//SaL//2/Z//9Xt///D1r//7+zv/8AAAAAAAAAANajhP////////Ll///0 + 6v//9/H///v4////////////////////////////+vr6//n5+f//////8fHw/4SCh/87jOH/bt3//1a0 + //8ZW///4+f//7KGgf8AAAAAAAAAANilhf////////Dj///06v+ZlI//mZaT/5mYl/+ZmZn/y8vL/7Oz + tf+ChYj/fXx5/358ev+ChIj/jo+Q/62qpf/Ax8L/QZrp/xRW///m6////////6l2bv8AAAAAAAAAANqn + hv///////+/g///z5///9ez///nz///8+v//////o6Wn/7Wrl//10JT/+9KT//vTmv/8153/wrWh/4CD + if/EwLv/goKQ/+nt/////////////6t4b/8AAAAAAAAAAN2qh////////+7e///w4/+Zkoz/mZSR/5yZ + lv/b29z/rKSS//zXmv/x0Zv/79CZ/+7Nkf/wz5f/+tef/7+znf+Ki4z/ysrI/////////////////657 + cP8AAAAAAAAAAOCtif///////+zZ///v4P//8+f///Xs///59f+UlJf/9Nii//Xdqv/x26r/8dup//DU + ov/v0Jf/8M6a//7ao/+PkZT//////////////////////7B9cf8AAAAAAAAAAOKviv///////+rX///u + 3v+ZkIj/mZKM/62ppf+AgH7//+i1//blvv/358D/9eK4//Pdsf/x1qX/8NCV//3apP+FhIL/2NjY//// + /////////////7J/cv8AAAAAAAAAAOSxi////////+nV///s2f//7+D///Ll///38P+Eg4L///PI//z1 + 3P/689b/9+zI//bnvf/z3K3/8NOe//7Zof+EhIP//////////////////////7WCdP8AAAAAAAAAAOaz + jP///////+fQ///q1/+ZjoT/mY+G/62nof+enp3/7+bF////8P/+/vz//Pbb//fsx//24bP/89ek//TY + pP+Rk5b//////////////////////7iFdf8AAAAAAAAAAOi1jv///////+XM///o0v//6tf//+7e///y + 5//z7OX/paOc////7P////f//fnl//nuzP/347b//+Gm/6Sdkv/b29z//////////////////////7qH + dv8AAAAAAAAAAOy5j////////+PJ///mzv+Zi37/mY6C/52Tif+tpp//vru5/6Khm//j3sL///zT///y + wv/p1av/oJuS/7Kztv+/v7//mZmZ/////////////////72KeP8AAAAAAAAAAO67kP///////+HF///j + yf//5s7//+nV///s2f//7+D///Pp//Lr5P+lpKT/gICD/4CCgv+ampz/5OPj///9/f////////////// + /////////////7+Mef8AAAAAAAAAAPC9kf///////9/A///hxf+ZiHn/mYt9///p1f+ZjoL/nZOJ/6ae + lv+tp6H/r6mk/62npP+jn53///nz/5mWk/+Zl5X/mZeW///9/P///fz///38/8GOev8AAAAAAAAAAPK/ + k////////928///fwP//4cX//+PJ///mzv//6NL//+rX///t3P//7+D///Dj///z5///9Or///Xs///2 + 7v//9/H///nz///69f//+vX///r1/8SRe/8AAAAAAAAAAPTBlP///////9u4///dvP+ZhnP/mYd2/5mI + ef+Zinz/mYt+///q1/+ZjoL/mY+F/5mPhv+ZkIj/mZKL/5mSjP+Zkoz/mZOO///27v//9u7///bu/8eU + ff8AAAAAAAAAAPbDlf///////9mz///buP//3bz//9/A///hxf//48n//+XM///n0P//6dX//+rX///s + 2f//7t7//+/g///w4///8uX///Ll///z5///8+f///Pn/8qXfv8AAAAAAAAAAPnGlv/+8eb//+7e///Z + s///27j//928///evv//4MP//+LH///lzP//5s7//+fQ///p1f//6tf//+zZ///t3P//7t7//+7e///v + 4P//7+D/9uDQ/8yZf/8AAAAAAAAAAPjFlj36ypz//vHm//////////////////////////////////// + ///////////////////////////////////////////////////338z/27KZ/8yZf6kAAAAAAAAAAAAA + AAD4xZY9+caW//fElf/1wpT/88CT//G+kv/vvJH/7bqQ/+q3j//otY7/5rOM/+Sxi//ir4r/4K2J/96r + iP/ap4b/2KWF/9ajhP/UoYP/0J2BqQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA////AMAAAwCAAAEAgAABAIAAAQCAAAEAgAABAIAAAQCAAAEAgAABAIAAAQCAAAEAgAABAIAA + AQCAAAEAgAABAIAAAQCAAAEAgAABAIAAAQCAAAEAwAABAOAAAwD///8AKAAAACAAAABAAAAAAQAIAAAA + AACABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8ANF/oAMCNeQBt2f8ATVNaAPvboQB5pLUAxsjQAEtw + qgBfiP8AeX6EAK6ppADksYsA+O/PAKBuagBNsfgAmZONADqL/wBkZ20A2cmkAN3d3QDi270AUG7oAMie + kADNtLUA8sqLAIqTpAA8b/8A7u3sAJmGdAD/3r4AW3KXAF/A/wC1t7gArqKNALB9cQD//N8A79vRAJ2d + nQDXpIQA69GeAIiKjgDu8f8AKnb/AOe9nwDEwr8A7tuwAL2yogD/9+8A4cKQALWRhQDx5cEAzZp/APvI + lwDW1NIA/+3cAPG+kgCJh4EAkZOXAP3rvAD/5MoAOmfxAOLRqgCZjIAA2byhAM/LxwDi2dIApKWpAMa2 + wwDhyZoAsKmYAPLVpwCodW0AVrT/AODm5ACysK8A9dKaAPb29gD39+cA99+rAIGEiQBYgP8A6uHYALeE + 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 + AAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPgAAAH//////////8oAAAAIAAAAEAAAAABACAAAAAAAIAQ + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAHVvWSSGhH3maWhndGJiYl6EhIQCAAAAAAAAAAAAAAAAAAAAALqHdrW2g3T/tYJz/7SB + c/+zgHL/sX5y/7B9cf+vfHH/rntw/616cP+seW//q3hv/6l2bv+odW3/p3Rt/6ZzbP+lcmz/pHFr/6Nw + a/+hbmr/oG1p/6Bua//NtLX/UG7o/4qTpP/Nx8L/iIiH/2NjY2kAAAAAAAAAAAAAAAC6h3a1yJ6Q/+/b + 0f//+PL///v3///+/f////////////////////////////////////////////////////////////// + /////////////////////////Pz//1+I//8qdv//S63//+Dm5P/Py8f/aGhoeQAAAAAAAAAAAAAAAL6L + eP/v2s7///Xs///48v//+/f///79//////////////////////////////////////////////////// + //////////////////////////////v7//9bhv//Lnn//1a0//9o1f//W73//66urv+MioTTAAAAAAAA + AAAAAAAAwI15///+/v//9ez///jy///79////fv///////////////////////////////////////// + ///////////////////////////////////6+///WID//y97//9Zt///bNb//1/A//87j///Omfx/4V/ + clcAAAAAAAAAAAAAAADDkHr////////06v//9/D/mZaT/5mYl/+ZmZn/mZmZ//////+ZmZn/mZmZ/5mZ + mf+ZmZn/mZmZ/5mZmf+ZmZn/mZmZ////////////7u3s/1Bw8f8wevz/Wrn//2zW//9ev///Po7//zxv + ///GtsP/AAAAAAAAAAAAAAAAAAAAAMaTfP////////Pp///27v+ZlZL/mZeV/5mZmf+ZmZn//////5mZ + mf+ZmZn/nZ2d/7W1tf/FxcX/zMzM/8vLy//ExMT///////r6+v+Xk4r/W3KX/0qr9P9t2f//Xb7//z2N + //9AcP//7vH//65/ef8AAAAAAAAAAAAAAAAAAAAAyZZ9////////8+n///bu///48v//+/f///79//// + ///////////////////29vb/tbe4/4qMkf+EiJD/hIiP/4GEif+vsLH/6Ojo/46Ojf/i2dL/eaS1/02x + +P86i///RHP///Dz////////qndu/wAAAAAAAAAAAAAAAAAAAADKl37////////y5///9ez/mZWR/5mW + k/+ZmJf/mZmZ/5mZmf+0tLT/vL29/3Z7gv+yp5L/5ceW//HJjP/1zJH/8c+f/72yov9NU1n/kJCS/+7t + 7P/q4dj/S3Cq/zRf6P/y9P////////////+seW//AAAAAAAAAAAAAAAAAAAAAMyZf/////////Ll///0 + 6v+ZlJD/mZWS/5mXlf+ZmZn/qqqq/7+/wP+Agob/4cKQ//LKiv/syI7/6saP//DQnf/v06P/8MeK/+/O + mv9kZ23/mpuc/5OSkf+emYz/xsjQ/////////////////698cf8AAAAAAAAAAAAAAAAAAAAAz5yA//// + ////8eP///Pp///17P//+PL///v3///+/f/5+fn/h4uP/+bJmv/105n/79Ca/+/Qmf/vz5j/7s2Q/+7I + i//y06T/9NWg//LQn/9NUlr/3d3d/+jo6P//////////////////////sn9y/wAAAAAAAAAAAAAAAAAA + AADRnoH////////w4f//8uf/mZKM/5mUkP+ZlpP/srCv/8nKy/+uoo3/9NOc/+vQnv/q0p7/8dam//HV + ov/w057/79CY/+7Kjf/y1Kf/9dCR/7Ornf/CwsP///////////////////////////+0gXP/AAAAAAAA + AAAAAAAAAAAAANShg////////+/g///x4/+Zkoz/mZSP/5mVkf/DwsD/o6Wp/9nFmv/u16X/7Nep/+zX + qv/z3bD/89yt//Hbqf/w1KH/79Ca/+7Mj//227H/79Gj/5CSlv///////////////////////////7eE + dP8AAAAAAAAAAAAAAAAAAAAA16SE////////7dz///Dh///y5///9Or///fw///8+v+Qk5f/99+r//fm + vf/25r7/9unF//bnwP/35Ln/89+x//Hbqf/w1KH/78+V//LWqP/205r/jJCV//////////////////// + ////////uod2/wAAAAAAAAAAAAAAAAAAAADap4b////////s2v//7+D/mZGI/5mSjP+Zk47/zMrI/46Q + lv/13a7/+e7M//Xrz//06cr/8ufF//Divf/v3LP/7Niq//Hbqf/pzJb/7dGg//XRm/+EiI3/yMjI/5mZ + mf////////////////+9inf/AAAAAAAAAAAAAAAAAAAAANyph////////+rW///t3P+ZkIf/mZGJ/5mS + jP/Ewb7/pKWo/9nJpP//9tz/9/HY//f25//38Nv/9OnH//Hlwf/u27D/8tus/+nOmv/v0qD/582g/4mK + jv+/v7//mZmZ/////////////////7+MeP8AAAAAAAAAAAAAAAAAAAAA3quI////////6dX//+vY///u + 3v//8OH///Ln///37//a2dj/sKmY///83//+/fH//v36//7+8//89Nb/+O/P//bku//z3a//8dak//vb + of+roZL/x8jJ////////////////////////////wo96/wAAAAAAAAAAAAAAAAAAAADhror////////n + 0f//6tb/mY6D/5mPhv+ZkYj///Lo/9DNy/+hoKP/4tu9//r65f/7+/L/9/fn//Xw1//47sz/7961/+zX + qf/w157/4cma/3l+hP/7+/v////////////////////////////Fknv/AAAAAAAAAAAAAAAAAAAAAOOw + i////////+bP///o0/+ZjID/mY6E/5mPhv//8uX/q6ah/9bU0v+bm5r/5d7D//n54//69+P/9vDV//ru + yf/z4LL/992o/+DInf+AgYT/wMDA/////////////////////////////////8eUfP8AAAAAAAAAAAAA + AAAAAAAA5rOM////////5cz//+bP///p1f//69j//+3c///w4f//8uX///bv//Pw7v+jo6b/sq2e/+PY + uP//8MP//eu8/+LRqv+wqJf/hYiM/+Dg4f//////////////////////////////////////ypd+/wAA + AAAAAAAAAAAAAAAAAADpto3////////jyP//5cz/mYt9/5mMgP+ZjYL/mY6E/5mQh/+ZkYn/rqmk/9DO + zP/T0dH/np6i/4iKjv+Ehoz/kpSY/6ipqv/Nzc3//////5mZmf+ZmZn/mZmZ/5mZmf////////////// + ///MmX//AAAAAAAAAAAAAAAAAAAAAOu4jv///////+HE///kyv+ZiXv/mYt9/5mMgP+ZjYL/mY6E/5mQ + h/+ZkYn/npaQ///38P/JxsT/0c/N/9HPzf/Ix8X/tbSz/52cnP//////mZmZ/5mZmf+ZmZn/mZmZ//// + /////////////82af/8AAAAAAAAAAAAAAAAAAAAA7bqQ////////38H//+LG///kyv//5c3//+fR///p + 1f//69j//+3c///v4P//8eP///Ln///06v//9ez///fw///48v//+vX///v3///8+f///fv///79//// + ////////////////////////0J2B/wAAAAAAAAAAAAAAAAAAAADwvZH////////dvf//4ML/mYh3/5mJ + ef+ZiXv/mYt9/5mMgP//69j/mY6E/5mPhv+ZkIf/mZGJ/5mSjP//9Or/mZSP/5mUkP+ZlZH/mZWS/5mW + k/+Zl5T/mZeV/5mYl////fv///79///+/f/ToIL/AAAAAAAAAAAAAAAAAAAAAPPAk////////9y5///e + v/+ZhnT/mYh3/5mJef+ZiXv/mYt9///p1f+ZjID/mY6D/5mPhf+ZkIf/mZGI///y5/+Zkoz/mZKM/5mT + jv+ZlJD/mZWR/5mVkf+ZlZL/mZaT///79///+/f///v3/9ajhP8AAAAAAAAAAAAAAAAAAAAA9cKU//// + ////5s3//9y5///ev///4ML//+LG///kyv//5cz//+bP///o0///6tb//+vY///t3P//7+D///Dh///x + 4///8uf///Pp///06v//9ez///bu///27v//9/D///jy///48v//+PL/2KWF/wAAAAAAAAAAAAAAAAAA + AAD4xZX////////48v//5s3//9y5///dvf//38H//+HE///jyP//5cz//+bP///n0f//6dX//+rW///s + 2v//7dz//+/g///w4f//8eP///Ll///y5///8+n///Pp///06v//9ez///Xs/+7a0f/bqIb/AAAAAAAA + AAAAAAAAAAAAAPvIl4/6x5b///////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////9+//u2s3/572f/7aD + dI8AAAAAAAAAAAAAAAAAAAAAAAAAAPvIl4/7yJf/+seW//nGlv/4xZX/98SV//XClP/0wZP/88CT//K/ + kv/xvpL/8L2R/+67kP/tupD/7LmP/+y5j//ruI7/6reO/+m2jf/ntIz/5rOM/+Wyi//ksYv/47CL/+Kv + iv+2g3SPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/////////j4AAAAcAAAAHAAAABwAAAAcAA + AAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AA + AAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAAD4AAAB///////////KAAAADAAAABgAAAAAQAIAAAA + AACACgAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8AIVXwAMGOeQBt2f8ATE1PAPvboQCLldIArb3/ADhm + uQBfiP8AeX6EAK2qpwDlsosA+/DSAKBuagBNsfgAmZWLADmJ/wBnaGkA2cmkAOLe2gDi270ATInRAMai + kQDNtLUA8sqLAHWCtQA8b/8A7+3rAIV7awD/3r4AW3KXAGHE/wCytL8AqaCNALB9cQD//eMA79vRAJ2d + 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 + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI6MgwJycm/BcnJyu2Rk + ZChmZmY0V1dXAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQ3 + +CN7e4P+sK+t/4CAgP6CgoL/bW1twmxsbAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADPnICj0J2B/9Cd + gf/QnYH/0J2B/9Cdgf/QnYH/0J2B/8+cgP/PnID/z5yA/86bgP/Om4D/zpuA/82af//Nmn//zJl//8yZ + f//MmX//yZZ9/8iVff/Gk3z/xJF7/8KPev/Bjnn/vot4/72KeP+7iHb/uYZ1/7aDdP+0gXP/s4By/7B9 + cf+4i4H/vKu//yJR9f80cer/q6in/+Hg3/+UlJT/hISE/2VlZUsAAAAAAAAAAAAAAAAAAAAAAAAAANKf + gszQnYH/7tS////04///9OT///Xl///15///9ej///bp///26v//9+v///fs///47f//+O7///nv///5 + 8P//+fL///rz///69P//+/X///v2///89////Pj///z5///9+v///fz///79///+/v////////////// + ///////////////////d4///KFn//ytz//9CmP//aLTo/+bh3//m5eT/goKC/mVlZUAAAAAAAAAAAAAA + AAAAAAAA06CCo9Gegf/24s7///Pi///04///9OT///Xl///15///9ej///bp///26v//9+v///fs///4 + 7f//+O7///nv///58P//+fL///rz///69P//+/X///v2///89////Pj///z5///9+v///fz///79///+ + /v///////////////////////////9vi//8nWv//LHX//0OZ//9dv///ZM7//3/G7v/Hwr7/s7Kx/nR0 + dHsAAAAAAAAAAAAAAAAAAAAA1KGD//Xl2P//+O3///Pi///04///9OT///Xl///15///9ej///bp///2 + 6v//9+v///fs///47f//+O7///nv///58P//+fL///rz///69P//+/X///v2///89////Pj///z5///9 + +v///fz///78///+/f//////////////////////2N///ydY//8tdv//RJn//17A//9nzv//Y8j//0yq + //9XitP/npmS/3l5edwAAAAAAAAAAAAAAAAAAAAA1aKD////////8+H///Pi/4V/dv+Ff3f/hYB3/4WA + eP+FgHn/hYB6/4WAev+FgXv/hYF7/4WBfP//+O7///nv/4WCff+Fgn7/hYJ+/4WCf/+Fg4D/hYOA/4WD + gf+Fg4H/hYOC/4WEgv+FhIP/hYSD/4WEhP+FhIT/hYWF/5iYmP+jq8z/H1P5/y53//9GnP//X8H//2fO + //9ix///T6n//zqL//8XW/7/QFi8g3Fway4AAAAAAAAAAAAAAAAAAAAA1qOE////////8+H///Pi/4V/ + dv+Ff3f/hX93/4WAeP+FgHj/hYB5/4WAev+FgXv/hYF7/4WBfP//+O7///jv/4WCff+Fgn7/hYJ+/4WC + f/+Fg4D/hYOA/4WDgP+Fg4H/hYOC/4WEgv+FhIP/hYSD/4WEhP+Lior/sbGx/6GozP8cS+f/Lnn+/0ed + //9fwv//Z87//2LG//9OqP//OYr//x1c//+Hi9H/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA16SE//// + ////8+H///Pi/4V/dv+Ff3f/hX93/4WAeP+FgHj/hYB5/4WAev+FgXv/hYF7/4WBfP//+O7///jv/4WC + ff+Fgn7/hYJ+/4WCf/+Fgn//hYOA/4WDgP+Fg4H/hYOB/4WDgv+FhIL/hYSD/4uKif+vrq7/kpCM/yxM + sf8nauD/R5z8/2DE//9nzv//YcX//06n//85if//HVr//6e5///Gopr/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA2KWF////////8+H///Pi///z4v//9OT///Tl///15v//9ef///bo///26f//9ur///fr///3 + 7P//+O7///jv///57///+fD///ny///68///+/b///z4///9+v///fv///37///9+////vv///37///9 + /f/Nzcz/mZiX/5GQjf9Df8H/Wrny/2jP//9hxf//Tab//ziI//8cW///rb3///////+wfXH/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA2aaG////////8+D///Ph///z4v//9OT///Tl///15v//9ef///Xo///2 + 6f//9ur///fr///37P//+O3///ju///57///+fD///rz//369v/U0tD/np6c/3l6ev9naGn/Zmdo/3Z2 + dv+amZn/19bU///+/f/v7u3/g4OD/83My/+rrKr/WqjP/1m79P9Lpf//OIb//xxZ//+ywf////////// + //+zgHL/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA26iG////////8uD///Ph/4V/dv+Ff3b/hX93/4WA + d/+FgHj/hYB5/4WAev+FgHr/hYF7/4WBe/+FgXz/hYF8/4WBff+npaL/r66s/3R0df9wcnT/mpqZ/7+z + o//OvqT/0b+n/8G4qP+dnqH/YmVn/2VlZv9nZ2f/lJSU/7m5uf/+/f3/pKiq/0GIz/8weOj/GVHy/4ua + 0/////////////////+0gXP/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3KmH////////8uD///Ph/4V/ + dv+Ff3b/hX93/4V/d/+FgHj/hYB4/4WAef+FgHr/hYB6/4WBe/+FgXv/hYF8/66rqP+goJ//bm9y/6Gd + lf/YvI//8MaF/+/Iiv/nw4b/5sCF/+e9fv/mu3X/6cyi/7Gvrf9KS03/jIyM/+3t7f/MzMz/2NbV/4OJ + j/8YRsr/j5vS/6Kiov////////////////+2g3T/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3aqH//// + ////8uD///Ph/4V/dv+Ff3b/hX93/4V/d/+FgHj/hYB4/4WAef+FgHr/hYB6/4WBe/+FgXv/pqOf/6Wk + o/92eHv/u6yU/+nChf/nxIj/7syU/+7LlP/nxo//6cmU/+vPoP/rzqD/58KJ/+a6d//Wy7v/TlFT/5SU + lP+goKD/kZGR/6Skof+TlJb/r66u/4WFhf////////////////+5hnX/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA3quI////////8t////Pg///z4f//8+L///Tj///05P//9eX///Xn///16P//9uj///bp///3 + 6///+O7/5uPf/3l6fP+8rpb/9NCR/+/OlP/vzpX/7s6U/+7NlP/uy5L/7sqP/+3Hi//tzJf/8deu//DS + ov/swHv/1829/0tMTv9jY2P/0dHR/7GxsP/o5+f///79///+/f///v7///7+///+/v+7iHb/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA36yI////////8t////Lg///z4f//8+L///Tj///05P//9OX///Xm///1 + 5///9uj///bp///26v//+vP/oJ+f/5uWjv/21Jn/8NGc//DSnf/w0p3/8NKd//DRnP/v0Jn/79CY/+7N + kv/uyo//7cmP//HXrv/x06L/7sJ//6iopv+GhYb///79///+/f///fz///78///+/P///v3///79///+ + /f+9inj/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4K2J////////8t7///Lg/4V/df+Ff3X/hX92/4V/ + d/+Ff3f/hYB3/4WAeP+FgHn/hYB6/5GNiP+3tbP/f4GE/9W9kv/ozJj/8daj//HYpP/nz5z/58+d/+fN + nP/nzJn/58qV/+bIkv/vz5j/7suQ/+7JkP/y27H/7sqT/+zSq/9cXmH/7ezq///9+v///fv///37///9 + /P///fz///38///9/P++i3j/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4a6K////////8t7///Lf/4V+ + df+Ff3X/hX92/4V/dv+Ff3f/hX93/4WAeP+FgHj/hYB5/6WhnP+joqH/kI2J/+7RnP/o0J//8tus//Pc + rP/q06P/6tOj/+nSov/o0KD/58+c/+fMmf/w0p3/78+X/+7Lkf/w0KD/8NWr/+7Eg/+QkZX/urm4///9 + +v///fr///36///9+v///fr///36///9+v/Bjnn/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4q+K//// + ////8t7///Lf/4V+df+Ff3X/hX92/4V/dv+Ff3f/hX93/4WAd/+FgHj/hYB5/7Guqv+ampn/qaCN/+7T + o//s1aj/9eCz//Xgs//r16z/69is/+vXqf/q1af/6tOj/+jQn//x1qT/8NKd/+/Pl//vzJL/8tmz/+/I + iv+zrKL/lZSU///9+v///Pn///z5///8+f///Pn///z5///8+f/Cj3r/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA5LGL////////8d3///Le///y3///8+D///Ph///z4v//9OP///Tk///05f//9eb///Xn///6 + 8v+jo6P/uq+V//fhsf/25bz/9uW8//bpxf/368f/+OrE//blvv/247f/9eCy//Pdrv/x2aj/8dah//DR + nP/uzpL/8ter//DMlP/HuaX/hYSF///9+v///Pf///z4///8+P///Pj///z4///8+P/EkXv/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA5bKL////////8d3///Le///y3///8uD///Ph///z4v//8+L///Tk///0 + 5f//9eX///Xn///58f+mpqX/ua6W//jktv/36cT/++/S//vuzv/47s3/+O3K//fqxf/36b//9uO4//Xg + s//z3K//8dim//DTnv/vz5f/8dWn//DNlf/EtqL/hoaG///8+f//+/b///v3///89////Pf///z3///8 + 9//Gk3z/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA5rOM////////8dz///Hd/4V+dP+FfnT/hX91/4V/ + df+Ff3b/hX92/4V/d/+Ff3f/hYB4/7Kvqv+mpqX/rKOT//rpuv/x58n/9OvV//Tqzf/y68//8+jL//Dn + xP/u4r7/7d+5/+vYrv/q1af/8tqp//HWpP/nyZP/686f/+rHjf+vp5r/mZmY/6upp/+Fg4D/hYOA/4WD + gP//+/b///v2///79v/IlX3/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA57SM////////8dz///Hd/4V+ + dP+FfnT/hX51/4V/df+Ff3X/hX92/4V/dv+Ff3f/hX93/6ainP+ysa//k5GN//3twP/07NH/9fHd//Xx + 3v/49+z/+PXp//Przv/w5sb/7uTB/+3dtP/r2Kz/89ys//HXpf/nypX/6tCf/+nEif+Ki43/u7q4/5+c + mv+Fg4D/hYOA/4WDgP//+/X///v1///79f/Jln3/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA6LWN//// + ////8dv///Hc/4V+c/+FfnT/hX50/4V+df+Ff3X/hX92/4V/dv+Ff3f/hX93/5KOhv++vbr/k5SX/9/U + sv/07dH/9/Pg//n47v/6+vL/+fnw//Tv2P/x6cz/8ufH/+7et//r2Kz/892v//Hap//nypb/6c2a/9fA + mf9rbG//7Onn/42Kh/+Fgn//hYJ//4WCf///+vT///r0///69P/MmX//AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA6baO////////8Nv///Hb///x3f//8d3///Le///y4P//8+D///Ph///z4v//9OP///Tk///0 + 5f//+fD/x8bF/5mVi///+Nf//Pjh//387v///vf//f3v//z33f/79df/+vDR//jov//247j/892v//HZ + p//w1aD/9NKa/5qWkv+Xlpb///v3///68v//+vL///ry///68///+vP///rz///68//MmX//AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA6reO////////8Nr///Hb///x3P//8d3///Le///y3///8uD///Ph///z + 4f//8+L///Tj///05P//9ej/8u7p/6Wlp/+6tKD///3j//365f/9/Ov//Prp//354//79dv/++/O//fo + wv/25Lj/892u//Lap//216D/u7Cc/3Bxc//p5+P///nx///58f//+fH///nx///58v//+fL///ny///5 + 8v/MmX//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA67iP////////8Nr///Da/4V+cv+FfnP/hX5z/4V+ + dP+FfnT///Lg///z4f+Ff3b/hX92/4V/dv+Ff3f/qaWg/8XEwv+cnZ//tbGd//b01//389z/9vLc//v2 + 3v/y6cv/7uK8/+3cs//s2Kv/69Sm/+3TnP+3q5b/dHV4/6empP+hnpv///nv///58P//+fD///nw///5 + 8P//+fD///nw///58P/Nmn//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA7bqP////////8Nn///Da/4V9 + cv+FfnL/hX5z/4V+c/+FfnT///Lf///y4P+Ff3X/hX92/4V/dv+Ff3b/hX93/7Guqf/FxMP/o6Sl/5eV + i//a0rP/9OrE//3xyv/w5Lz/8OC2//HcsP/w2qr/1cKd/5mVj/95enz/p6Wk/6uopf+FgXz///jv///4 + 7///+O////nv///57///+e////nv///57//Nmn//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA7ruQ//// + ////79f///DZ/4V9cv+FfnL/hX5z/4V+c/+FfnT///Le///y3/+Ff3X/hX91/4V/dv+Ff3b/hX92/4V/ + d/+sqKL/xMK//7Oys/+Sk5P/k5GN/7CqnP+5sJv/urGZ/6yllf+Qjor/gIGD/4qJif+0s7D/pqOe/4WB + fP+FgXz///ju///47v//+O7///ju///47v//+O7///ju///47v/Om4D/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA77yQ////////79b///DZ///w2f//8Nr///Hb///x3P//8d3///Le///y3v//8uD///Pg///z + 4f//8+L///Pi///04///9OT///bp//347//i3tr/wsG+/6uqqv+bm5z/mJiY/52dnP+0srD/2tfT//75 + 8///+O3///fr///37P//9+z///fs///47f//+O3///jt///47f//+O3///jt///47f/Om4D/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA8L2R////////7tT//+/W///w2f//8Nr///Da///x2///8dz///Hd///y + 3v//8t////Lg///z4P//8+H///Pi///z4v//9OP///Tk///05P//9un///ju///58f//+vL///rz///6 + 8v//+fD///fs///26f//9ur///bq///36///9+v///fr///37P//9+z///fs///37P//9+z///fs///3 + 7P/Om4D/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8b6S////////7dL//+7U/4V9cP+FfXH/hX1y/4V9 + cv+FfnL/hX5z/4V+c/+FfnT/hX50/4V+df+Ff3X///Ph///z4v+Ff3b/hX92/4V/d/+Ff3f/hX93/4WA + d/+FgHj/hYB4/4WAeP+FgHn/hYB5/4WAef+FgHr///bp///26f+FgHr/hYB6/4WBe/+FgXv/hYF7/4WB + e///9+v///fr///36//PnID/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8r+S////////7ND//+7T/4V8 + b/+FfXD/hX1x/4V9cv+FfXL/hX5y/4V+c/+FfnP/hX50/4V+dP+FfnT///Lg///z4f+Ff3X/hX92/4V/ + dv+Ff3b/hX93/4V/d/+Ff3f/hYB3/4WAeP+FgHj/hYB4/4WAef+FgHn///bo///26f+FgHr/hYB6/4WA + ev+FgHr/hYB6/4WAev//9ur///bq///26v/PnID/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA88CT//// + ////7M7//+3R/4V8bv+FfG//hX1w/4V9cf+FfXL/hX1y/4V+cv+FfnP/hX5z/4V+dP+FfnT///Lf///y + 4P+Ff3X/hX91/4V/dv+Ff3b/hX92/4V/d/+Ff3f/hX93/4V/d/+FgHf/hYB4/4WAeP+FgHj///Xn///1 + 6P+FgHn/hYB5/4WAef+FgHn/hYB6/4WAev//9un///bp///26f/PnID/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA9MGT////////68z//+zP///t0f//7tP//+7V///w2f//8Nn///Da///w2///8dv///Hc///x + 3f//8t7///Le///y3///8uD///Pg///z4f//8+H///Pi///z4v//9OP///Tk///05P//9OX///Tl///1 + 5f//9eb///Xm///15///9ef///Xn///15///9ef///Xo///16P//9ej///Xo///16P/QnYH/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA9sOU////////6sv//+vN///sz///7dH//+7T///u1f//8Nn///DZ///w + 2v//8Nv///Hb///x3P//8d3///Hd///y3v//8t////Lg///y4P//8+H///Ph///z4v//8+L///Pi///0 + 4///9OT///Tk///05P//9OX///Tl///15f//9eb///Xm///15v//9eb///Xn///15///9ef///Xn///1 + 5//QnYH/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA98SU////////6sn//+rL/4V7a/+Fe2z/hXxt/4V8 + bv+FfG//hX1w/4V9cf+FfXL/hX1y/4V+cv+FfnP/hX5z/4V+c/+FfnT/hX50/4V+dP+FfnX/hX91///z + 4f//8+H/hX92/4V/dv+Ff3b/hX92/4V/dv+Ff3f/hX93/4V/d/+Ff3f/hX93/4V/d/+Ff3f/hYB3/4WA + d///9eX///Xl///15f/QnYH/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+MWV////////6cf//+rJ/4V6 + av+Fe2v/hXts/4V8bf+FfG7/hXxv/4V9cP+FfXH/hX1y/4V9cv+FfnL/hX5y/4V+c/+FfnP/hX5z/4V+ + dP+FfnT/hX50///y4P//8+D/hX91/4V/df+Ff3X/hX92/4V/dv+Ff3b/hX92/4V/dv+Ff3f/hX93/4V/ + d/+Ff3f/hX93/4V/d///9OT///Tk///05P/QnYH/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+caW//// + ////6MP//+nH/4V6af+Femr/hXtr/4V7bP+FfG3/hXxu/4V8b/+FfXD/hX1x/4V9cf+FfXL/hX1y/4V+ + cv+FfnP/hX5z/4V+c/+FfnT/hX50///y3///8t//hX51/4V+df+Ff3X/hX91/4V/df+Ff3b/hX92/4V/ + dv+Ff3b/hX92/4V/dv+Ff3b/hX92/4V/dv//9OP///Tj///04//QnYH/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA+seW////////58H//+jE///px///6sn//+rL///rzf//7M///+3R///u0///7tT//+/W///w + 2f//8Nn///Da///w2v//8dv///Hb///x3P//8d3///Hd///y3v//8t7///Lf///y3///8uD///Lg///z + 4P//8+H///Ph///z4f//8+H///Pi///z4v//8+L///Pi///z4v//8+L///Pi///z4v/QnYH/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA+8iX//7y4v//8Nn//+fB///ow///6cf//+rJ///qy///68z//+zO///s + 0P//7dL//+7U///v1v//79f///DZ///w2v//8Nr///Db///x2///8dz///Hc///x3f//8d3///Le///y + 3v//8t7///Lf///y3///8uD///Lg///y4P//8+D///Ph///z4f//8+H///Ph///z4f//8+H///Ph/+7U + v//QnYH/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/MmXo/zJl//+9OX///DZ///nwf//6MP//+jF///p + yP//6sr//+vM///szv//7ND//+3R///u0///7tX//+/X///w2f//8Nn///Da///w2v//8Nv///Hb///x + 3P//8dz///Hd///x3f//8d3///Le///y3v//8t7///Lf///y3///8t////Lg///y4P//8uD///Lg///y + 4P//9+z/9uHN/9Kfgv/PnICjAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP3KmMz8yZf//vLi//// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////15df/0Z6B/9KfgswAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAD8yZej+8iX//rHlv/5xpb/+MWV//fElP/2w5T/9MGT//PAk//yv5L/8b6S//C9kf/vvJD/7ruQ/+26 + j//ruI//6reO/+m2jv/otY3/57SM/+azjP/lsov/5LGL/+Kviv/hror/4K2J/9+siP/eq4j/3aqH/9yp + h//bqIb/2aaG/9ilhf/XpIT/1qOE/9Wig//UoYP/06CCowAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////AAD//////58AAP//////gwAA+AAAAAAD + AADwAAAAAAMAAOAAAAAAAQAA4AAAAAABAADgAAAAAAMAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAA + AAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAH + AADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAA + AAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAH + AADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAA + AAAABwAA4AAAAAAHAADwAAAAAA8AAPgAAAAAHwAA////////AAD///////8AAP///////wAA + + + + 444, 24 + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/FileMonitor/app.config b/Demo_Source_Code/CSharpDemo/FileMonitor/app.config new file mode 100644 index 0000000..a387676 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FileMonitor/app.config @@ -0,0 +1,7 @@ + + + + + + + diff --git a/Demo_Source_Code/CSharpDemo/FileMonitor/app.manifest b/Demo_Source_Code/CSharpDemo/FileMonitor/app.manifest new file mode 100644 index 0000000..d49604f --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FileMonitor/app.manifest @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Demo_Source_Code/CSharpDemo/FileMonitor/text_view.ico b/Demo_Source_Code/CSharpDemo/FileMonitor/text_view.ico new file mode 100644 index 0000000..bb5d8a8 Binary files /dev/null and b/Demo_Source_Code/CSharpDemo/FileMonitor/text_view.ico differ diff --git a/Demo_Source_Code/CSharpDemo/FileMonitorConsole/FileMonitorConsole.csproj b/Demo_Source_Code/CSharpDemo/FileMonitorConsole/FileMonitorConsole.csproj new file mode 100644 index 0000000..37a1445 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FileMonitorConsole/FileMonitorConsole.csproj @@ -0,0 +1,103 @@ + + + + Debug + x86 + 8.0.30703 + 2.0 + {D2549779-D9A0-4A92-9390-93973CC5249A} + Exe + Properties + FileMonitorConsole + FileMonitorConsole + v4.5 + + + 512 + SAK + SAK + SAK + SAK + + + AnyCPU + true + full + false + ..\..\Release\ + DEBUG;TRACE + prompt + 4 + false + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + false + + + true + bin\Debug\ + DEBUG;TRACE + full + AnyCPU + ..\..\Release\FileMonitorConsole.exe.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false + + + ..\..\Release\ + TRACE + true + pdbonly + AnyCPU + bin\Release\FileMonitorConsole.exe.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false + + + + + + + + + + + + + + + + + + + + {21540012-a296-45ce-8d35-3ea5a07b32a6} + FilterControl + + + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/FileMonitorConsole/Program.cs b/Demo_Source_Code/CSharpDemo/FileMonitorConsole/Program.cs new file mode 100644 index 0000000..33a40fc --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FileMonitorConsole/Program.cs @@ -0,0 +1,99 @@ +using System; +using EaseFilter.FilterControl; + +namespace FileMonitorConsole +{ + class Program + { + static FilterControl filterControl = new FilterControl(); + + static void Main(string[] args) + { + string lastError = string.Empty; + //Purchase a license key with the link: http://www.easefilter.com/Order.htm + //Email us to request a trial key: info@easefilter.com //free email is not accepted. + string licenseKey = "*******************************"; + + FilterAPI.FilterType filterType = FilterAPI.FilterType.MONITOR_FILTER; + int serviceThreads = 5; + int connectionTimeOut = 10; //seconds + + try + { + if (!filterControl.StartFilter(filterType, serviceThreads, connectionTimeOut, licenseKey, ref lastError)) + { + Console.WriteLine("Start Filter Service failed with error:" + lastError); + return; + } + + //the watch path can use wildcard to be the file path filter mask.i.e. '*.txt' only monitor text file. + string watchPath = "c:\\test\\*"; + + if (args.Length > 0) + { + watchPath = args[0]; + } + + //create a file monitor filter rule, every filter rule must have the unique watch path. + FileFilter fileMonitorFilter = new FileFilter(watchPath); + + //Filter the file change event to monitor all file change events. + fileMonitorFilter.FileChangeEventFilter = (FilterAPI.FileChangedEvents)FilterAPI.NotifyAllFileEvents; + + //register the file change callback events. + fileMonitorFilter.NotifyFileWasChanged += NotifyFileChanged; + + //Filter the monitor file IO events + fileMonitorFilter.MonitorFileIOEventFilter = (ulong)(MonitorFileIOEvents.OnFileOpen | MonitorFileIOEvents.OnFileRead); + fileMonitorFilter.OnFileOpen += OnFileOpen; + fileMonitorFilter.OnFileRead += OnFileRead; + + filterControl.AddFilter(fileMonitorFilter); + + if (!filterControl.SendConfigSettingsToFilter(ref lastError)) + { + Console.WriteLine("SendConfigSettingsToFilter failed." + lastError); + return; + } + + Console.WriteLine("Start filter service succeeded. Monitoring path:" + watchPath); + + // Wait for the user to quit the program. + Console.WriteLine("Press 'q' to quit the sample."); + while (Console.Read() != 'q') ; + + filterControl.StopFilter(); + + } + catch (Exception ex) + { + Console.WriteLine("Start filter service failed with error:" + ex.Message); + } + + } + + /// + /// Fires this event when the file was changed. + /// + static void NotifyFileChanged(object sender, FileChangedEventArgs e) + { + Console.WriteLine("NotifyFileChanged:" + e.FileName + ",eventType:" + e.eventType.ToString() + ",userName:" + e.UserName + ",processName:" + e.ProcessName); + } + + /// + /// Fires this event after the file was opened, the handle is not closed. + /// + static void OnFileOpen(object sender, FileCreateEventArgs e) + { + Console.WriteLine("FileOpen:" + e.FileName + ",status:" + e.IOStatusToString() + ",userName:" + e.UserName + ",processName:" + e.ProcessName); + } + + /// + /// Fires this event after the read IO was returned. + /// + static void OnFileRead(object sender, FileReadEventArgs e) + { + Console.WriteLine("FileRead:" + e.FileName + ",offset:" + e.offset + ",readLength:" + e.returnReadLength + ",userName:" + e.UserName + ",processName:" + e.ProcessName); + } + } +} diff --git a/Demo_Source_Code/CSharpDemo/FileMonitorConsole/Properties/AssemblyInfo.cs b/Demo_Source_Code/CSharpDemo/FileMonitorConsole/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..e50ee0a --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FileMonitorConsole/Properties/AssemblyInfo.cs @@ -0,0 +1,37 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("FileMonitorConsole")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("FileMonitorConsole")] +[assembly: AssemblyCopyright("Copyright © 2021")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("35260e88-ccf4-4dfc-86d9-b4930d0e5ed8")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("5.2.3.2001")] +//[assembly: AssemblyFileVersion("1.0.0.0")] + diff --git a/Demo_Source_Code/CSharpDemo/FileMonitorConsole/app.config b/Demo_Source_Code/CSharpDemo/FileMonitorConsole/app.config new file mode 100644 index 0000000..c5e1dae --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FileMonitorConsole/app.config @@ -0,0 +1,3 @@ + + + diff --git a/Demo_Source_Code/CSharpDemo/FileProtector/ControlEventHandler.cs b/Demo_Source_Code/CSharpDemo/FileProtector/ControlEventHandler.cs new file mode 100644 index 0000000..53cd093 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FileProtector/ControlEventHandler.cs @@ -0,0 +1,753 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; +using System.Runtime.InteropServices; +using System.Security.Principal; +using System.IO; +using System.Threading; +using System.Reflection; + +using EaseFilter.FilterControl; +using EaseFilter.CommonObjects; + +namespace FileProtector +{ + + public class ControlEventHandler : IDisposable + { + MessageHandler messageHandler = null; + bool disposed = false; + + + public ControlEventHandler(MessageHandler _messageHandler) + { + this.messageHandler = _messageHandler; + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + private void Dispose(bool disposing) + { + if (!this.disposed) + { + } + + disposed = true; + } + + ~ControlEventHandler() + { + Dispose(false); + } + + private void DisplayEventMessage(FileIOEventArgs fileIOEventArgs) + { + if (null != messageHandler) + { + messageHandler.DisplayEventMessage(fileIOEventArgs); + } + + } + + + /// + /// Fires this event after the new file was created, the handle is not closed. + /// + public void OnPreCreateFile(object sender, FileCreateEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + //if (string.Compare(YourTestFileName, e.FileName, true) == 0) + //{ + // //test block the file open here. + // e.ReturnStatus = NtStatus.Status.AccessDenied; + //} + //else if (string.Compare(unitTestCallbackTestReparseFile, e.FileName, true) == 0) + //{ + // //test reparse file open to other file. + // e.reparseFileName = unitTestCallbackReparseTargetFile; + // e.ReturnStatus = NtStatus.Status.Reparse; + // e.IsDataModified = true; + //} + + + } + + /// + /// Fires this event after the new file was created, the handle is not closed. + /// + public void OnPostCreateFile(object sender, FileCreateEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + + /// + /// Fires this event after the read IO was returned. + /// + public void OnPreFileRead(object sender, FileReadEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + //if (string.Compare(YourTestFileName, e.FileName, true) == 0) + //{ + // //test block the file read here. + // e.ReturnStatus = NtStatus.Status.AccessDenied; + //} + } + + /// + /// Fires this event after the read IO was returned. + /// + public void OnPostFileRead(object sender, FileReadEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + + /// + /// Fires this event after the write IO was returned. + /// + public void OnPreFileWrite(object sender, FileWriteEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + //if (string.Compare(YourTestFileName, e.FileName, true) == 0) + //{ + // //test block the file write here. + // e.ReturnStatus = NtStatus.Status.AccessDenied; + //} + } + + /// + /// Fires this event after the write IO was returned. + /// + public void OnPostFileWrite(object sender, FileWriteEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + + /// + /// Fires this event after the query file size IO was returned. + /// + public void OnPreQueryFileSize(object sender, FileSizeEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + //if (string.Compare(YourTestFileName, e.FileName, true) == 0) + //{ + // //test block the file size query here. + // e.ReturnStatus = NtStatus.Status.AccessDenied; + //} + //else if (string.Compare(YourTestFileName, e.FileName, true) == 0) + //{ + // //test replace the file size with your own, complete the pre-query IO. + // e.fileSizeToQueryOrSet = 1000;//change the file size with your own + // e.ReturnStatus = NtStatus.Status.Success; + // e.IsDataModified = true; + //} + } + + /// + /// Fires this event after the query file size IO was returned. + /// + public void OnPostQueryFileSize(object sender, FileSizeEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + //if (string.Compare(YourTestFileName, e.FileName, true) == 0) + //{ + // //test replace the file size with your own. + // e.fileSizeToQueryOrSet = 1000;//change the file size with your own + // e.ReturnStatus = NtStatus.Status.Success; + // e.IsDataModified = true; + //} + } + + /// + /// Fires this event after the query file basic information IO was returned. + /// + public void OnPreQueryFileBasicInfo(object sender, FileBasicInfoEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + //if (string.Compare(YourTestFileName, e.FileName, true) == 0) + //{ + // //test block the file basic info query here. + // e.ReturnStatus = NtStatus.Status.AccessDenied; + //} + //else if (string.Compare(YourTestFileName, e.FileName, true) == 0) + //{ + // //test replace the basic file info with your own, complete the pre-query IO. + //WinData.FileBasicInformation basicInfo = new WinData.FileBasicInformation(); + //basicInfo.CreationTime = basicInfo.LastWriteTime = DateTime.Now.ToFileTime(); + //e.basicInfo = basicInfo;//change the file basic info with your own + //e.ReturnStatus = NtStatus.Status.Success; + // e.IsDataModified = true; + //} + } + + /// + /// Fires this event after the query file basic information IO was returned. + /// + public void OnPostQueryFileBasicInfo(object sender, FileBasicInfoEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + // //test replace the basic file info with your own, complete the pre-query IO. + //WinData.FileBasicInformation basicInfo = new WinData.FileBasicInformation(); + //basicInfo.CreationTime = basicInfo.LastWriteTime = DateTime.Now.ToFileTime(); + //e.basicInfo = basicInfo;//change the file basic info with your own + //e.ReturnStatus = NtStatus.Status.Success; + // e.IsDataModified = true; + } + + /// + /// Fires this event after the query file standard information IO was returned. + /// + public void OnPreQueryFileStandardInfo(object sender, FileStandardInfoEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + //if (string.Compare(YourTestFileName, e.FileName, true) == 0) + //{ + // //test block the file standard info query here. + // e.ReturnStatus = NtStatus.Status.AccessDenied; + //} + //else if (string.Compare(YourTestFileName, e.FileName, true) == 0) + //{ + // //test replace the file standard info with your own, complete the pre-query IO. + //WinData.FileStandardInformation standardInfo = new WinData.FileStandardInformation(); + //standardInfo.EndOfFile = 1000; //new file size + //e.standardInfo = standardInfo;//change the file basic info with your own + //e.ReturnStatus = NtStatus.Status.Success; + //e.IsDataModified = true; + //} + } + + /// + /// Fires this event after the query file standard information IO was returned. + /// + public void OnPostQueryFileStandardInfo(object sender, FileStandardInfoEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + // //test replace the file standard info with your own + //WinData.FileStandardInformation standardInfo = new WinData.FileStandardInformation(); + //standardInfo.EndOfFile = 1000; //new file size + //e.standardInfo = standardInfo;//change the file basic info with your own + //e.ReturnStatus = NtStatus.Status.Success; + //e.IsDataModified = true; + } + + /// + /// Fires this event after the query file network information IO was returned. + /// + public void OnPreQueryFileNetworkInfo(object sender, FileNetworkInfoEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + //if (string.Compare(YourTestFileName, e.FileName, true) == 0) + //{ + // //test block the file network info query here. + // e.ReturnStatus = NtStatus.Status.AccessDenied; + //} + //else if (string.Compare(YourTestFileName, e.FileName, true) == 0) + //{ + // //test replace the file standard info with your own, complete the pre-query IO. + //WinData.FileNetworkInformation networkInfo = new WinData.FileNetworkInformation(); + //networkInfo.CreationTime = networkInfo.LastWriteTime = networkInfo.ChangeTime = DateTime.Now.ToFileTime(); //new file time + //e.networkInfo = networkInfo;//change the file networkInfo with your own + //e.ReturnStatus = NtStatus.Status.Success; + //e.IsDataModified = true; + //} + } + + /// + /// Fires this event after the query file network information IO was returned. + /// + public void OnPostQueryFileNetworkInfo(object sender, FileNetworkInfoEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + // //test replace the file standard info with your own, complete the pre-query IO. + //WinData.FileNetworkInformation networkInfo = new WinData.FileNetworkInformation(); + //networkInfo.CreationTime = networkInfo.LastWriteTime = networkInfo.ChangeTime = DateTime.Now.ToFileTime(); //new file time + //e.networkInfo = networkInfo;//change the file networkInfo with your own + //e.ReturnStatus = NtStatus.Status.Success; + //e.IsDataModified = true; + + } + + /// + /// Fires this event after the query file Id IO was returned. + /// + public void OnPreQueryFileId(object sender, FileIdEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + //if (string.Compare(YourTestFileName, e.FileName, true) == 0) + //{ + // //test block the file Id query here. + // e.ReturnStatus = NtStatus.Status.AccessDenied; + //} + } + + /// + /// Fires this event after the query file Id IO was returned. + /// + public void OnPostQueryFileId(object sender, FileIdEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + + /// + /// Fires this event after the query file info IO was returned. + /// + /// + /// + public void OnPreQueryFileInfo(object sender, FileInfoArgs e) + { + DisplayEventMessage(e); + //do your job here. + + //the QueryFileInfo includes all the information class as "WinData.FileInfomationClass" + //we already handled some common query information class as above "Query file size, file basic info, file standard info, file network info, file Id." + //all other classes were handled here, for more information please reference "FltQueryInformationFile". + + //if (string.Compare(YourTestFileName, e.FileName, true) == 0) + //{ + // //test block the file info query here. + // e.ReturnStatus = NtStatus.Status.AccessDenied; + //} + } + + /// + /// Fires this event after the query file info IO was returned. + /// + /// + /// + public void OnPostQueryFileInfo(object sender, FileInfoArgs e) + { + DisplayEventMessage(e); + //do your job here. + + //to get the query file info result, first you need to get the information class: + //e.FileInfoClass, then get the structure of the class + //e.DataBuffer has the information data of the file associated to the info class. + + } + + /// + /// Fires this event after the set file size IO was returned. + /// + public void OnPreSetFileSize(object sender, FileSizeEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + //if (string.Compare(YourTestFileName, e.FileName, true) == 0) + //{ + // //test block the set file size IO. + // e.fileSizeToQueryOrSet is the file size will be set + // e.ReturnStatus = NtStatus.Status.AccessDenied; + //} + } + + /// + /// Fires this event after the set file size IO was returned. + /// + public void OnPostSetFileSize(object sender, FileSizeEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + + /// + /// Fires this event after the set file basic information was returned. + /// + public void OnPreSetFileBasicInfo(object sender, FileBasicInfoEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + //if (string.Compare(YourTestFileName, e.FileName, true) == 0) + //{ + // //test block the set file basic info IO. + // e.basicInfo is the file basic info will be set + // e.ReturnStatus = NtStatus.Status.AccessDenied; + //} + } + + /// + /// Fires this event after the set file basic information was returned. + /// + public void OnPostSetFileBasicInfo(object sender, FileBasicInfoEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + + /// + /// Fires this event after the set file standard information IO was returned. + /// + public void OnPreSetFileStandardInfo(object sender, FileStandardInfoEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + //if (string.Compare(YourTestFileName, e.FileName, true) == 0) + //{ + // //test block the set file standard info IO. + // e.standardInfo is the file standard info will be set + // e.ReturnStatus = NtStatus.Status.AccessDenied; + //} + } + + /// + /// Fires this event after the set file standard information IO was returned. + /// + public void OnPostSetFileStandardInfo(object sender, FileStandardInfoEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + + + /// + /// Fires this event after the set file network information IO was returned. + /// + public void OnPreSetFileNetworkInfo(object sender, FileNetworkInfoEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + + //if (string.Compare(YourTestFileName, e.FileName, true) == 0) + //{ + // //test block the set file standard info IO. + // e.networkInfo is the file standard info will be set + // e.ReturnStatus = NtStatus.Status.AccessDenied; + //} + } + + /// + /// Fires this event after the set file network information IO was returned. + /// + public void OnPostSetFileNetworkInfo(object sender, FileNetworkInfoEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + + /// + /// Fires this event after the file was moved or renamed. + /// + public void OnPreMoveOrRenameFile(object sender, FileMoveOrRenameEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + //if (string.Compare(YourTestFileName, e.FileName, true) == 0) + //{ + // //test block the file rename here. + // e.newFileName is the new file name will be changed + // e.ReturnStatus = NtStatus.Status.AccessDenied; + //} + } + + /// + /// Fires this event after the file was moved or renamed. + /// + public void OnPostMoveOrRenameFile(object sender, FileMoveOrRenameEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + + /// + /// Fires this event after the delete IO was returned. + /// + public void OnPreDeleteFile(object sender, FileIOEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + //if (string.Compare(YourTestFileName, e.FileName, true) == 0) + //{ + //test block the file delete here. + e.ReturnStatus = NtStatus.Status.AccessDenied; + //} + } + + /// + /// Fires this event after the delete IO was returned. + /// + public void OnPostDeleteFile(object sender, FileIOEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + + /// + /// Fires this event after the set file info IO was returned. + /// + /// + /// + public void OnPreSetFileInfo(object sender, FileInfoArgs e) + { + DisplayEventMessage(e); + //do your job here. + + //the SetFileInfo includes all the information class as "WinData.FileInfomationClass" + //we already handled some common set information class as above "Set file size, file basic info, file standard info, file network info, rename, delete." + //all other classes were handled here, for more information please reference "FltSetInformationFile". + + //if (string.Compare(YourTestFileName, e.FileName, true) == 0) + //{ + // //test block the set file info here. + // e.ReturnStatus = NtStatus.Status.AccessDenied; + //} + } + + /// + /// Fires this event after the set file info IO was returned. + /// + /// + /// + public void OnPostSetFileInfo(object sender, FileInfoArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + + /// + /// Fires this event after the query file security IO was returned. + /// + public void OnPreQueryFileSecurity(object sender, FileSecurityEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + //if (string.Compare(YourTestFileName, e.FileName, true) == 0) + //{ + // //test block the query file security IO here. + // e.ReturnStatus = NtStatus.Status.AccessDenied; + //} + } + + /// + /// Fires this event after the query file security IO was returned. + /// + public void OnPostQueryFileSecurity(object sender, FileSecurityEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + //you can get the security data return from the file system. + //e.securityBuffer + } + + /// + /// Fires this event after the set file security IO was returned. + /// + public void OnPreSetFileSecurity(object sender, FileSecurityEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + //if (string.Compare(YourTestFileName, e.FileName, true) == 0) + //{ + // //test block the set file security IO here. + // e.ReturnStatus = NtStatus.Status.AccessDenied; + //} + } + + /// + /// Fires this event after the set file security IO was returned. + /// + public void OnPostSetFileSecurity(object sender, FileSecurityEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + + + /// + /// Fires this event after the directory enumeration query IO was returned. + /// + public void OnPreQueryDirectoryFile(object sender, FileQueryDirectoryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + + //if (string.Compare(YourTestFileName, e.FileName, true) == 0) + //{ + // //test block the query directory file IO here if you block the file browsing. + // e.ReturnStatus = NtStatus.Status.AccessDenied; + //} + } + + /// + /// Fires this event after the directory enumeration query IO was returned. + /// + public void OnPostQueryDirectoryFile(object sender, FileQueryDirectoryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + //get the data of the directory file list based on the information class. + //e.fileInfomationClass; + //e.directoryBuffer; + + } + + + /// + /// Fires this event after the file was cleanuped. + /// + public void OnPreFileHandleClose(object sender, FileIOEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + + /// + /// Fires this event after the file was cleanuped. + /// + public void OnPostFileHandleClose(object sender, FileIOEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + + /// + /// Fires this event after the last file handle of the file was closed. + /// + public void OnPreFileClose(object sender, FileIOEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + + /// + /// Fires this event after the last file handle of the file was closed. + /// + public void OnPostFileClose(object sender, FileIOEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + + /// + /// Fires this event when the filter driver attached to a volume. + /// + public void NotifyFilterAttachToVolume(object sender, VolumeInfoEventArgs e) + { + DisplayEventMessage(e); + + //if ((e.DeviceCharacteristics & WinData.DeviceObject_Characteristics.FILE_REMOVABLE_MEDIA) > 0) + //{ + // //this is the USB drive, here is the USB dos volume name or drive letter. + // //e.VolumeDosName + + // //you can setup the new filter rule for this USB drive here, for example you block this USB as below: + // FileFilter usbFilter = new FileFilter(e.VolumeDosName + "*"); + // usbFilter.AccessFlags = FilterAPI.AccessFlag.LEAST_ACCESS_FLAG; + + // if (!FilterAPI.AddFileFilterRule((uint)usbFilter.AccessFlags, usbFilter.IncludeFileFilterMask, usbFilter.IsResident, usbFilter.FilterId)) + // { + // string lastError = "Send filter rule failed:" + FilterAPI.GetLastErrorMessage(); + // } + //} + } + + /// + /// Fires this event when a volume was detached from the filter driver. + /// + public void NotifyFilterDetachFromVolume(object sender, VolumeInfoEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + + /// + /// Fires this event when a volume was detached from the filter driver. + /// + public void NotifiyFileIOWasBlocked(object sender, DeniedFileIOEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + + /// + /// Fires this event when a volume was detached from the filter driver. + /// + public void NotifiyProcessTerminatedWasBlocked(object sender, DeniedProcessTerminatedEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + + + /// + /// Fires this event when a volume was detached from the filter driver. + /// + public void NotifyUSBReadWasBlocked(object sender, DeniedUSBReadEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + + + /// + /// Fires this event when a volume was detached from the filter driver. + /// + public void NotifyUSBWriteWasBlocked(object sender, DeniedUSBWriteEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + + } +} \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/FileProtector/DecryptionForm.Designer.cs b/Demo_Source_Code/CSharpDemo/FileProtector/DecryptionForm.Designer.cs new file mode 100644 index 0000000..b3fe515 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FileProtector/DecryptionForm.Designer.cs @@ -0,0 +1,207 @@ +namespace FileProtector +{ + partial class DecryptedFileForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(DecryptedFileForm)); + this.label1 = new System.Windows.Forms.Label(); + this.textBox_PassPhrase = new System.Windows.Forms.TextBox(); + this.button_Start = new System.Windows.Forms.Button(); + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.textBox_DecryptionLength = new System.Windows.Forms.TextBox(); + this.label5 = new System.Windows.Forms.Label(); + this.textBox_Offset = new System.Windows.Forms.TextBox(); + this.label_targetname = new System.Windows.Forms.Label(); + this.button_OpenFile = new System.Windows.Forms.Button(); + this.checkBox_DisplayPassword = new System.Windows.Forms.CheckBox(); + this.textBox_FileName = new System.Windows.Forms.TextBox(); + this.label3 = new System.Windows.Forms.Label(); + this.label2 = new System.Windows.Forms.Label(); + this.groupBox1.SuspendLayout(); + this.SuspendLayout(); + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(23, 26); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(88, 13); + this.label1.TabIndex = 0; + this.label1.Text = "Password phrase"; + // + // textBox_PassPhrase + // + this.textBox_PassPhrase.Location = new System.Drawing.Point(172, 23); + this.textBox_PassPhrase.Name = "textBox_PassPhrase"; + this.textBox_PassPhrase.Size = new System.Drawing.Size(206, 20); + this.textBox_PassPhrase.TabIndex = 1; + this.textBox_PassPhrase.UseSystemPasswordChar = true; + // + // button_Start + // + this.button_Start.Location = new System.Drawing.Point(469, 223); + this.button_Start.Name = "button_Start"; + this.button_Start.Size = new System.Drawing.Size(75, 23); + this.button_Start.TabIndex = 2; + this.button_Start.Text = "Start"; + this.button_Start.UseVisualStyleBackColor = true; + this.button_Start.Click += new System.EventHandler(this.button_Start_Click); + // + // groupBox1 + // + this.groupBox1.Controls.Add(this.textBox_DecryptionLength); + this.groupBox1.Controls.Add(this.label5); + this.groupBox1.Controls.Add(this.textBox_Offset); + this.groupBox1.Controls.Add(this.label_targetname); + this.groupBox1.Controls.Add(this.button_OpenFile); + this.groupBox1.Controls.Add(this.checkBox_DisplayPassword); + this.groupBox1.Controls.Add(this.textBox_FileName); + this.groupBox1.Controls.Add(this.label3); + this.groupBox1.Controls.Add(this.label2); + this.groupBox1.Controls.Add(this.textBox_PassPhrase); + this.groupBox1.Controls.Add(this.label1); + this.groupBox1.Location = new System.Drawing.Point(23, 12); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size(521, 205); + this.groupBox1.TabIndex = 3; + this.groupBox1.TabStop = false; + // + // textBox_DecryptionLength + // + this.textBox_DecryptionLength.Location = new System.Drawing.Point(172, 174); + this.textBox_DecryptionLength.Name = "textBox_DecryptionLength"; + this.textBox_DecryptionLength.Size = new System.Drawing.Size(206, 20); + this.textBox_DecryptionLength.TabIndex = 12; + this.textBox_DecryptionLength.Text = "16"; + // + // label5 + // + this.label5.AutoSize = true; + this.label5.Location = new System.Drawing.Point(23, 174); + this.label5.Name = "label5"; + this.label5.Size = new System.Drawing.Size(116, 13); + this.label5.TabIndex = 11; + this.label5.Text = "The Decryption Length"; + // + // textBox_Offset + // + this.textBox_Offset.Location = new System.Drawing.Point(172, 134); + this.textBox_Offset.Name = "textBox_Offset"; + this.textBox_Offset.Size = new System.Drawing.Size(206, 20); + this.textBox_Offset.TabIndex = 10; + this.textBox_Offset.Text = "0"; + // + // label_targetname + // + this.label_targetname.AutoSize = true; + this.label_targetname.Location = new System.Drawing.Point(23, 134); + this.label_targetname.Name = "label_targetname"; + this.label_targetname.Size = new System.Drawing.Size(60, 13); + this.label_targetname.TabIndex = 9; + this.label_targetname.Text = "Start Offset"; + // + // button_OpenFile + // + this.button_OpenFile.Location = new System.Drawing.Point(407, 86); + this.button_OpenFile.Name = "button_OpenFile"; + this.button_OpenFile.Size = new System.Drawing.Size(75, 23); + this.button_OpenFile.TabIndex = 7; + this.button_OpenFile.Text = "browse"; + this.button_OpenFile.UseVisualStyleBackColor = true; + this.button_OpenFile.Click += new System.EventHandler(this.button_OpenFile_Click); + // + // checkBox_DisplayPassword + // + this.checkBox_DisplayPassword.AutoSize = true; + this.checkBox_DisplayPassword.Location = new System.Drawing.Point(393, 26); + this.checkBox_DisplayPassword.Name = "checkBox_DisplayPassword"; + this.checkBox_DisplayPassword.Size = new System.Drawing.Size(108, 17); + this.checkBox_DisplayPassword.TabIndex = 5; + this.checkBox_DisplayPassword.Text = "Display password"; + this.checkBox_DisplayPassword.UseVisualStyleBackColor = true; + this.checkBox_DisplayPassword.CheckedChanged += new System.EventHandler(this.checkBox_DisplayPassword_CheckedChanged); + // + // textBox_FileName + // + this.textBox_FileName.Location = new System.Drawing.Point(172, 88); + this.textBox_FileName.Name = "textBox_FileName"; + this.textBox_FileName.Size = new System.Drawing.Size(206, 20); + this.textBox_FileName.TabIndex = 4; + this.textBox_FileName.Text = "c:\\test\\test.txt"; + // + // label3 + // + this.label3.AutoSize = true; + this.label3.Location = new System.Drawing.Point(23, 88); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(89, 13); + this.label3.TabIndex = 3; + this.label3.Text = "Source File name"; + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(169, 44); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(170, 13); + this.label2.TabIndex = 2; + this.label2.Text = "(it must be the same as encryption)"; + // + // DecryptedFileForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(573, 272); + this.Controls.Add(this.groupBox1); + this.Controls.Add(this.button_Start); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Name = "DecryptedFileForm"; + this.Text = "DecryptionForm"; + this.groupBox1.ResumeLayout(false); + this.groupBox1.PerformLayout(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.Label label1; + private System.Windows.Forms.TextBox textBox_PassPhrase; + private System.Windows.Forms.Button button_Start; + private System.Windows.Forms.GroupBox groupBox1; + private System.Windows.Forms.TextBox textBox_FileName; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.CheckBox checkBox_DisplayPassword; + private System.Windows.Forms.Button button_OpenFile; + private System.Windows.Forms.TextBox textBox_Offset; + private System.Windows.Forms.Label label_targetname; + private System.Windows.Forms.TextBox textBox_DecryptionLength; + private System.Windows.Forms.Label label5; + } +} \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/FileProtector/DecryptionForm.cs b/Demo_Source_Code/CSharpDemo/FileProtector/DecryptionForm.cs new file mode 100644 index 0000000..5e437e3 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FileProtector/DecryptionForm.cs @@ -0,0 +1,112 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.IO; +using System.Windows.Forms; + +using EaseFilter.FilterControl; +using EaseFilter.CommonObjects; + +namespace FileProtector +{ + public partial class DecryptedFileForm : Form + { + + public DecryptedFileForm() + { + InitializeComponent(); + } + + private void button_Start_Click(object sender, EventArgs e) + { + + string passPhrase = textBox_PassPhrase.Text.Trim(); + string fileName = textBox_FileName.Text.Trim(); + long offset = long.Parse(textBox_Offset.Text.Trim()); + int decryptionLength = int.Parse(textBox_DecryptionLength.Text.Trim()); + string lastError = string.Empty; + bool retVal = false; + + if (passPhrase.Length == 0) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("Password phrase can't be empty.", "Encryption", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + if (fileName.Length == 0) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("File name can't be empty.", "Encryption", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + byte[] key = Utils.GetKeyByPassPhrase(passPhrase,32); + byte[] decryptedBuffer = new byte[decryptionLength]; + int bytesDecrypted = 0; + + retVal = FilterAPI.AESDecryptBytes(fileName, (uint)key.Length, key, 0, null, offset, decryptionLength, decryptedBuffer, ref bytesDecrypted); + if (!retVal) + { + string errorMessage = FilterAPI.GetLastErrorMessage(); + + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("Decrypt file " + fileName + " at offset " + offset.ToString() + " failed with error:" + errorMessage, "decryption offset", MessageBoxButtons.OK, MessageBoxIcon.Error); + + return; + } + else + { + Array.Resize(ref decryptedBuffer, bytesDecrypted); + + string decryptedText = Encoding.ASCII.GetString(decryptedBuffer); + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show(decryptedText, "Decrypted data", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + + } + + private void checkBox_DisplayPassword_CheckedChanged(object sender, EventArgs e) + { + if (checkBox_DisplayPassword.Checked) + { + textBox_PassPhrase.UseSystemPasswordChar = false; + } + else + { + textBox_PassPhrase.UseSystemPasswordChar = true; + } + } + + private void button_OpenFile_Click(object sender, EventArgs e) + { + OpenFileDialog openFileDialog = new OpenFileDialog(); + + if (openFileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + textBox_FileName.Text = openFileDialog.FileName; + } + } + } +} diff --git a/Demo_Source_Code/CSharpDemo/FileProtector/DecryptionForm.resx b/Demo_Source_Code/CSharpDemo/FileProtector/DecryptionForm.resx new file mode 100644 index 0000000..a614ce3 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FileProtector/DecryptionForm.resx @@ -0,0 +1,149 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + AAABAAEAEBAAAAEACABoBQAAFgAAACgAAAAQAAAAIAAAAAEACAAAAAAAQAEAAAAAAAAAAAAAAAEAAAAA + AAAAAAAA////AAUBAAAXBwEAKhEEACgQBAAsEgUALRMFADMXBwA0GAcAOBoIADkbCQA7HQoAPx8LAEEh + CwBAIAsAQiIMAEYkDQBDIw0ASScPAE8sEgBSLhMATSsSAFUxFQBWMhYAWjYYAFk1GABdOBoAYDscAF86 + HABhPB0AYj0dAGM+HgBkPx8AZkEgAGdCIQBsRyUAa0YlAG1IJgBxTCkAdE8rAHZRLQB+WDMAhF86AIRg + OwCFYTwAh2M+AP37+QCJZT8AimZAAIxoQgCNaUMAkGxGAJFtRwCTcEoAkm9JAJRxSwCXdE4AmHVPAJx6 + VACbeVMAnn1XAJ18VgCgf1kAo4NdAKaGYQCoiGMAp4diAKmJZACqimUAqotmAK2PawCvkW0AsZNvALCS + bgCylHAAs5ZzANjFrwC2mncAuZ58ALyhfwC7oH4Aup99AL6kgwDAp4cAw6qKAMWtjgDErI0Axa6QAMix + kwDJs5UAyrSWAMu1mQDMtpoA07+lANPApgDYx7AA6d7PAPPt5QDOup4A08GoANbEqwDUwqkA39C7AN3O + uQDh1MEA7uXYAO/n3ADx6uAA8uzjAPz69wD6+PUA6eDSAPTv5wD49fAA////AAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAYGBgYGBgAAAAAAAAAAAgFADNNcDMAAw0AAAAAAA1UBzMAAAAARwdGDQAAABM4WAZM + ODg4OEsJSzgTAAAUPFoLUj0CAj9PDFs+FQAAIEVkJ11PLi5RXSllSiIAAChQaCxrWUVFWWEtZ1UqAAAr + XwEAAC9HSW4AAAFmNgAAK3EAAABDWlpCAAAAajQAI0cAYgFkZldXZF4BYgBIJx8AbGNJAE5KSEsAU11s + ACEATjY6AERcBQVgQAA4Nk4AJDEwAEFpCDc1BWFAADAwFw4sADtvOS1Wckw1bT4ALBUEChYmMjcREhAP + Mi4lGhQLAAAAABseHh4cHRsZAAAAAPgfAADgBwAAwAMAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAPAPAAA= + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/FileProtector/EncryptEventHandler.cs b/Demo_Source_Code/CSharpDemo/FileProtector/EncryptEventHandler.cs new file mode 100644 index 0000000..6bd29f6 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FileProtector/EncryptEventHandler.cs @@ -0,0 +1,135 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; +using System.Runtime.InteropServices; +using System.Security.Principal; +using System.IO; +using System.Threading; +using System.Reflection; + +using EaseFilter.FilterControl; +using EaseFilter.CommonObjects; + +namespace FileProtector +{ + + public class EncryptEventHandler : IDisposable + { + bool disposed = false; + + public EncryptEventHandler() + { + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + private void Dispose(bool disposing) + { + if (!this.disposed) + { + } + + disposed = true; + } + + ~EncryptEventHandler() + { + Dispose(false); + } + + /// + /// Fires this event after the new file was created, the handle is not closed. + /// + public void OnFilterRequestEncryptKey(object sender, EncryptEventArgs e) + { + + e.ReturnStatus = NtStatus.Status.Success; + + try + { + if (e.IsNewCreatedFile) + { + byte[] iv = Guid.NewGuid().ToByteArray(); + //for the new created file, you can add your custom tag data to the header of the encyrpted file here. + //here we add the iv to the tag data. + e.EncryptionTag = iv; + + //if you don't set the iv data, the filter driver will generate the new GUID as iv + e.IV = iv; + + //here is the encryption key for the new encrypted file, you can set it with your own unique custom key. + e.EncryptionKey = Utils.GetKeyByPassPhrase(GlobalConfig.MasterPassword, 32); + + //if you want to block the new file creation, you can return access denied status. + //e.ReturnStatus = NtStatus.Status.AccessDenied; + + //if you want to the file being created without encryption, return below status. + //e.ReturnStatus = NtStatus.Status.FileIsNoEncrypted; + + } + else + { + //this is the encrypted file open request, request the encryption key and iv. + //here is the tag data if you set custom tag data when the new created file requested the key. + byte[] tagData = e.EncryptionTag; + + //if (!GetEncryptedFileAccessPermission(e)) + //{ + // //here didn't get the permission for the encrypted file open, it will return the raw encrypted data. + // e.ReturnStatus = NtStatus.Status.FileIsEncrypted; + //} + + //The encryption key must be the same one which you created the new encrypted file. + e.EncryptionKey = Utils.GetKeyByPassPhrase(GlobalConfig.MasterPassword, 32); + + //here is the iv key we saved in tag data. + //e.IV = tagData; + + //if you want to block encrypted file being opened, you can return accessdenied status. + //e.ReturnStatus = NtStatus.Status.AccessDenied; + + //if you want to return the raw encrypted data for this encrypted file, return below status. + //e.ReturnStatus = NtStatus.Status.FileIsEncrypted; + + EventManager.WriteMessage(250, "OpenEncryptedFile", EventLevel.Information, + "OpenEncryptedFile:" + e.FileName + ",userName:" + e.UserName + ",processName:" + e.ProcessName + ",return status:" + e.ReturnStatus.ToString()); + + } + + } + catch (Exception ex) + { + EventManager.WriteMessage(500, "OnFilterRequestEncryptKey", EventLevel.Error, "OnFilterRequestEncryptKey:" + e.FileName + ",got exeception:" + ex.Message); + e.ReturnStatus = NtStatus.Status.AccessDenied; + } + + + } + + } +} \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/FileProtector/EncryptionForm.Designer.cs b/Demo_Source_Code/CSharpDemo/FileProtector/EncryptionForm.Designer.cs new file mode 100644 index 0000000..7a7a382 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FileProtector/EncryptionForm.Designer.cs @@ -0,0 +1,194 @@ +namespace FileProtector +{ + partial class EncryptedFileForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(EncryptedFileForm)); + this.label1 = new System.Windows.Forms.Label(); + this.textBox_PassPhrase = new System.Windows.Forms.TextBox(); + this.button_Start = new System.Windows.Forms.Button(); + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.textBox_TargetFileName = new System.Windows.Forms.TextBox(); + this.label5 = new System.Windows.Forms.Label(); + this.label4 = new System.Windows.Forms.Label(); + this.button_OpenFile = new System.Windows.Forms.Button(); + this.checkBox_DisplayPassword = new System.Windows.Forms.CheckBox(); + this.textBox_FileName = new System.Windows.Forms.TextBox(); + this.label3 = new System.Windows.Forms.Label(); + this.label2 = new System.Windows.Forms.Label(); + this.groupBox1.SuspendLayout(); + this.SuspendLayout(); + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(23, 26); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(102, 15); + this.label1.TabIndex = 0; + this.label1.Text = "Password phrase"; + // + // textBox_PassPhrase + // + this.textBox_PassPhrase.Location = new System.Drawing.Point(172, 23); + this.textBox_PassPhrase.Name = "textBox_PassPhrase"; + this.textBox_PassPhrase.Size = new System.Drawing.Size(206, 20); + this.textBox_PassPhrase.TabIndex = 1; + this.textBox_PassPhrase.UseSystemPasswordChar = true; + // + // button_Start + // + this.button_Start.Location = new System.Drawing.Point(469, 223); + this.button_Start.Name = "button_Start"; + this.button_Start.Size = new System.Drawing.Size(75, 23); + this.button_Start.TabIndex = 2; + this.button_Start.Text = "Start"; + this.button_Start.UseVisualStyleBackColor = true; + this.button_Start.Click += new System.EventHandler(this.button_Start_Click); + // + // groupBox1 + // + this.groupBox1.Controls.Add(this.textBox_TargetFileName); + this.groupBox1.Controls.Add(this.label5); + this.groupBox1.Controls.Add(this.label4); + this.groupBox1.Controls.Add(this.button_OpenFile); + this.groupBox1.Controls.Add(this.checkBox_DisplayPassword); + this.groupBox1.Controls.Add(this.textBox_FileName); + this.groupBox1.Controls.Add(this.label3); + this.groupBox1.Controls.Add(this.label2); + this.groupBox1.Controls.Add(this.textBox_PassPhrase); + this.groupBox1.Controls.Add(this.label1); + this.groupBox1.Location = new System.Drawing.Point(23, 12); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size(521, 194); + this.groupBox1.TabIndex = 3; + this.groupBox1.TabStop = false; + // + // textBox_TargetFileName + // + this.textBox_TargetFileName.Location = new System.Drawing.Point(172, 134); + this.textBox_TargetFileName.Name = "textBox_TargetFileName"; + this.textBox_TargetFileName.Size = new System.Drawing.Size(206, 20); + this.textBox_TargetFileName.TabIndex = 10; + // + // label5 + // + this.label5.AutoSize = true; + this.label5.Location = new System.Drawing.Point(23, 134); + this.label5.Name = "label5"; + this.label5.Size = new System.Drawing.Size(100, 15); + this.label5.TabIndex = 9; + this.label5.Text = "Target File name"; + // + // label4 + // + this.label4.AutoSize = true; + this.label4.Location = new System.Drawing.Point(169, 59); + this.label4.Name = "label4"; + this.label4.Size = new System.Drawing.Size(153, 15); + this.label4.TabIndex = 8; + this.label4.Text = "(default key size is 256bits)"; + // + // button_OpenFile + // + this.button_OpenFile.Location = new System.Drawing.Point(407, 86); + this.button_OpenFile.Name = "button_OpenFile"; + this.button_OpenFile.Size = new System.Drawing.Size(75, 23); + this.button_OpenFile.TabIndex = 7; + this.button_OpenFile.Text = "browse"; + this.button_OpenFile.UseVisualStyleBackColor = true; + this.button_OpenFile.Click += new System.EventHandler(this.button_OpenFile_Click); + // + // checkBox_DisplayPassword + // + this.checkBox_DisplayPassword.AutoSize = true; + this.checkBox_DisplayPassword.Location = new System.Drawing.Point(393, 26); + this.checkBox_DisplayPassword.Name = "checkBox_DisplayPassword"; + this.checkBox_DisplayPassword.Size = new System.Drawing.Size(125, 19); + this.checkBox_DisplayPassword.TabIndex = 5; + this.checkBox_DisplayPassword.Text = "Display password"; + this.checkBox_DisplayPassword.UseVisualStyleBackColor = true; + this.checkBox_DisplayPassword.CheckedChanged += new System.EventHandler(this.checkBox_DisplayPassword_CheckedChanged); + // + // textBox_FileName + // + this.textBox_FileName.Location = new System.Drawing.Point(172, 88); + this.textBox_FileName.Name = "textBox_FileName"; + this.textBox_FileName.Size = new System.Drawing.Size(206, 20); + this.textBox_FileName.TabIndex = 4; + // + // label3 + // + this.label3.AutoSize = true; + this.label3.Location = new System.Drawing.Point(23, 88); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(104, 15); + this.label3.TabIndex = 3; + this.label3.Text = "Source File name"; + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(169, 44); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(245, 15); + this.label2.TabIndex = 2; + this.label2.Text = "(it must be the same as the one in filter rule)"; + // + // EncryptedFileForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(573, 272); + this.Controls.Add(this.groupBox1); + this.Controls.Add(this.button_Start); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Name = "EncryptedFileForm"; + this.Text = "EncryptionForm"; + this.groupBox1.ResumeLayout(false); + this.groupBox1.PerformLayout(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.Label label1; + private System.Windows.Forms.TextBox textBox_PassPhrase; + private System.Windows.Forms.Button button_Start; + private System.Windows.Forms.GroupBox groupBox1; + private System.Windows.Forms.TextBox textBox_FileName; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.CheckBox checkBox_DisplayPassword; + private System.Windows.Forms.Button button_OpenFile; + private System.Windows.Forms.Label label4; + private System.Windows.Forms.TextBox textBox_TargetFileName; + private System.Windows.Forms.Label label5; + } +} \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/FileProtector/EncryptionForm.cs b/Demo_Source_Code/CSharpDemo/FileProtector/EncryptionForm.cs new file mode 100644 index 0000000..0417e55 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FileProtector/EncryptionForm.cs @@ -0,0 +1,147 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.IO; +using System.Windows.Forms; + +using EaseFilter.FilterControl; +using EaseFilter.CommonObjects; + +namespace FileProtector +{ + public partial class EncryptedFileForm : Form + { + Utils.EncryptType encryptType = Utils.EncryptType.Encryption; + + public EncryptedFileForm(string formName, Utils.EncryptType encryptType) + { + InitializeComponent(); + this.Text = formName; + this.encryptType = encryptType; + } + + private void button_Start_Click(object sender, EventArgs e) + { + + string passPhrase = textBox_PassPhrase.Text.Trim(); + string fileName = textBox_FileName.Text.Trim(); + string targetFileName = textBox_TargetFileName.Text.Trim(); + string lastError = string.Empty; + bool retVal = false; + + if (passPhrase.Length == 0) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("Password phrase can't be empty.", "Encryption", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + if (fileName.Length == 0) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("File name can't be empty.", "Encryption", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + byte[] key = Utils.GetKeyByPassPhrase(passPhrase,32); + byte[] iv = Utils.GetRandomIV(); + + if (encryptType == Utils.EncryptType.Encryption) + { + if (fileName.Equals(targetFileName, StringComparison.CurrentCulture)) + { + retVal = FilterAPI.AESEncryptFile(fileName, (uint)key.Length, key, (uint)iv.Length,iv, true); + //retVal = FilterAPI.AESEncryptFileWithTag(fileName, (uint)key.Length, key, (uint)iv.Length, iv, (uint)iv.Length, iv); + } + else + { + retVal = FilterAPI.AESEncryptFileToFile(fileName, targetFileName, (uint)key.Length, key, (uint)iv.Length, iv, true); + //retVal = FilterAPI.AESEncryptFileToFileWithTag(fileName, targetFileName, (uint)key.Length, key, (uint)iv.Length, iv, (uint)iv.Length, iv); + } + } + else + { + uint ivLength = (uint)iv.Length; + retVal = FilterAPI.GetAESTagData(fileName, ref ivLength, iv); + + if (!retVal) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("Decrypt file failed with error " + FilterAPI.GetLastErrorMessage(), "Decryption", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + if (fileName.Equals(targetFileName, StringComparison.CurrentCulture)) + { + retVal = FilterAPI.AESDecryptFile(fileName, (uint)key.Length, key, (uint)iv.Length, iv); + } + else + { + retVal = FilterAPI.AESDecryptFileToFile(fileName, targetFileName, (uint)key.Length, key, (uint)iv.Length, iv); + } + + } + + + if (!retVal) + { + string errorMessage = FilterAPI.GetLastErrorMessage(); + + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show(encryptType.ToString() + " file " + fileName + " failed with error:" + errorMessage, encryptType.ToString(), MessageBoxButtons.OK, MessageBoxIcon.Error); + + return; + } + else + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show(encryptType.ToString() + " file " + fileName + " succeeded.", encryptType.ToString(), MessageBoxButtons.OK, MessageBoxIcon.Information); + } + + } + + private void checkBox_DisplayPassword_CheckedChanged(object sender, EventArgs e) + { + if (checkBox_DisplayPassword.Checked) + { + textBox_PassPhrase.UseSystemPasswordChar = false; + } + else + { + textBox_PassPhrase.UseSystemPasswordChar = true; + } + } + + private void button_OpenFile_Click(object sender, EventArgs e) + { + OpenFileDialog openFileDialog = new OpenFileDialog(); + + if (openFileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + textBox_FileName.Text = openFileDialog.FileName; + textBox_TargetFileName.Text = openFileDialog.FileName; + } + } + } +} diff --git a/Demo_Source_Code/CSharpDemo/FileProtector/EncryptionForm.resx b/Demo_Source_Code/CSharpDemo/FileProtector/EncryptionForm.resx new file mode 100644 index 0000000..a614ce3 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FileProtector/EncryptionForm.resx @@ -0,0 +1,149 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + AAABAAEAEBAAAAEACABoBQAAFgAAACgAAAAQAAAAIAAAAAEACAAAAAAAQAEAAAAAAAAAAAAAAAEAAAAA + AAAAAAAA////AAUBAAAXBwEAKhEEACgQBAAsEgUALRMFADMXBwA0GAcAOBoIADkbCQA7HQoAPx8LAEEh + CwBAIAsAQiIMAEYkDQBDIw0ASScPAE8sEgBSLhMATSsSAFUxFQBWMhYAWjYYAFk1GABdOBoAYDscAF86 + HABhPB0AYj0dAGM+HgBkPx8AZkEgAGdCIQBsRyUAa0YlAG1IJgBxTCkAdE8rAHZRLQB+WDMAhF86AIRg + OwCFYTwAh2M+AP37+QCJZT8AimZAAIxoQgCNaUMAkGxGAJFtRwCTcEoAkm9JAJRxSwCXdE4AmHVPAJx6 + VACbeVMAnn1XAJ18VgCgf1kAo4NdAKaGYQCoiGMAp4diAKmJZACqimUAqotmAK2PawCvkW0AsZNvALCS + bgCylHAAs5ZzANjFrwC2mncAuZ58ALyhfwC7oH4Aup99AL6kgwDAp4cAw6qKAMWtjgDErI0Axa6QAMix + kwDJs5UAyrSWAMu1mQDMtpoA07+lANPApgDYx7AA6d7PAPPt5QDOup4A08GoANbEqwDUwqkA39C7AN3O + uQDh1MEA7uXYAO/n3ADx6uAA8uzjAPz69wD6+PUA6eDSAPTv5wD49fAA////AAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAYGBgYGBgAAAAAAAAAAAgFADNNcDMAAw0AAAAAAA1UBzMAAAAARwdGDQAAABM4WAZM + ODg4OEsJSzgTAAAUPFoLUj0CAj9PDFs+FQAAIEVkJ11PLi5RXSllSiIAAChQaCxrWUVFWWEtZ1UqAAAr + XwEAAC9HSW4AAAFmNgAAK3EAAABDWlpCAAAAajQAI0cAYgFkZldXZF4BYgBIJx8AbGNJAE5KSEsAU11s + ACEATjY6AERcBQVgQAA4Nk4AJDEwAEFpCDc1BWFAADAwFw4sADtvOS1Wckw1bT4ALBUEChYmMjcREhAP + Mi4lGhQLAAAAABseHh4cHRsZAAAAAPgfAADgBwAAwAMAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAPAPAAA= + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/FileProtector/FileIOControlService.cs b/Demo_Source_Code/CSharpDemo/FileProtector/FileIOControlService.cs new file mode 100644 index 0000000..500cf4b --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FileProtector/FileIOControlService.cs @@ -0,0 +1,251 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.IO; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Runtime.InteropServices; +using Microsoft.Win32.SafeHandles; + +using EaseFilter.FilterControl; + +namespace EaseFilter.CommonObjects +{ + public class FilterService + { + public static bool AuthorizeFileAccess(FilterAPI.MessageSendData messageSend, ref FilterAPI.MessageReplyData messageReply) + { + bool ret = true; + + try + { + messageReply.MessageId = messageSend.FilterRuleId; + messageReply.MessageType = messageSend.MessageType; + messageReply.ReturnStatus = (uint)NtStatus.Status.Success; + + messageReply.MessageId = messageSend.FilterRuleId; + messageReply.MessageType = messageSend.MessageType; + + // + //here you can control all the registered IO requests,block the access or modify the I/O data base on the file IO information from MessageSend struture + // + // + + //if you don't want to change anything to this IO request, just let it pass through as below setting: + //messageReply.FilterStatus = 0; + //messageReply.ReturnStatus = (uint)NtStatus.Status.Success; + + //if you want to block the access this IO request before it goes down to the file system, you can return the status as below, + //it is only for pre IO requests, it means the user IO reuqests will be completed here instead of going down to the file system. + //messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION; + //messageReply.ReturnStatus = (uint)NtStatus.Status.AccessDenied; + + //if you want to modify the IO data and complete the pre IO with your own data, you can return status as below: + // messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION | (uint)FilterAPI.FilterStatus.FILTER_DATA_BUFFER_IS_UPDATED; + // messageReply.DataBufferLength = the return data buffer length. + // messageReply.DataBuffer = the data you want to return. + // messageReply.ReturnStatus = (uint)NtStatus.Status.Success; + + FilterAPI.MessageType messageType = (FilterAPI.MessageType)messageSend.MessageType; + WinData.FileInfomationClass infoClass = (WinData.FileInfomationClass)messageSend.InfoClass; + + uint dataLength = messageSend.DataBufferLength; + byte[] data = messageSend.DataBuffer; + + //here is some IO information for your reference: + if ((messageSend.CreateOptions & (uint)WinData.CreateOptions.FO_REMOTE_ORIGIN) > 0) + { + //this is file access request comes from remote network server + } + + //you can check the file create option with this data: + //"DesiredAccess: messageSend.DesiredAccess + //"Disposition:" + ((WinData.Disposition)messageSend.Disposition).ToString(); + //"ShareAccess:" + ((WinData.ShareAccess)messageSend.SharedAccess).ToString(); + //"CreateOptions:"messageSend.CreateOptions + + + //Here is the demo to copy file content before it was deleted.----------------------------------------------- + bool isFileDeleting = false; + if (messageSend.Status == (uint)NtStatus.Status.Success) + { + if (messageType == FilterAPI.MessageType.POST_CREATE) + { + if ((messageSend.CreateOptions & (uint)WinData.CreateOptions.FILE_DELETE_ON_CLOSE) > 0) + { + isFileDeleting = true; + } + } + else if (messageType == FilterAPI.MessageType.PRE_SET_INFORMATION) + { + if (infoClass == WinData.FileInfomationClass.FileDispositionInformation) + { + isFileDeleting = true; + } + } + + if (isFileDeleting) + { + + //IntPtr fileHandle = IntPtr.Zero; + //bool retVal = FilterAPI.GetFileHandleInFilter(messageSend.FileName,(uint)FileAccess.Read, ref fileHandle); + //if (retVal) + //{ + // SafeFileHandle sHandle = new SafeFileHandle(fileHandle, true); + // FileStream fileStream = new FileStream(sHandle, FileAccess.Read); + + // //copy your data here... + + // fileStream.Close(); + //} + + } + } + //End ----------------------------------------------- + + + + switch (messageType) + { + case FilterAPI.MessageType.PRE_CREATE: + { + + //here you reparse the file open to another new file name + + //string newReparseFileName = "\\??\\c:\\myNewFile.txt"; + //byte[] returnData = Encoding.Unicode.GetBytes(newReparseFileName); + //Array.Copy(returnData, messageReply.DataBuffer, returnData.Length); + //messageReply.DataBufferLength = (uint)returnData.Length; + //messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION; + //messageReply.ReturnStatus = (uint)NtStatus.Status.Reparse; + + break; + } + + + case FilterAPI.MessageType.PRE_CACHE_READ: + case FilterAPI.MessageType.POST_CACHE_READ: + case FilterAPI.MessageType.PRE_NOCACHE_READ: + case FilterAPI.MessageType.POST_NOCACHE_READ: + case FilterAPI.MessageType.PRE_PAGING_IO_READ: + case FilterAPI.MessageType.POST_PAGING_IO_READ: + case FilterAPI.MessageType.PRE_CACHE_WRITE: + case FilterAPI.MessageType.POST_CACHE_WRITE: + case FilterAPI.MessageType.PRE_NOCACHE_WRITE: + case FilterAPI.MessageType.POST_NOCACHE_WRITE: + case FilterAPI.MessageType.PRE_PAGING_IO_WRITE: + case FilterAPI.MessageType.POST_PAGING_IO_WRITE: + { + + + //byte[] returnData = //new data you want to modify the read/write data; + //Array.Copy(returnData, messageReply.DataBuffer, returnData.Length); + //messageReply.DataBufferLength = (uint)returnData.Length; + + ////for pre IO,use this one + //// messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION | (uint)FilterAPI.FilterStatus.FILTER_DATA_BUFFER_IS_UPDATED; + + // messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_DATA_BUFFER_IS_UPDATED; + // messageReply.ReturnStatus = (uint)NtStatus.Status.Success; + + + break; + } + case FilterAPI.MessageType.PRE_SET_INFORMATION: + case FilterAPI.MessageType.POST_SET_INFORMATION: + case FilterAPI.MessageType.PRE_QUERY_INFORMATION: + case FilterAPI.MessageType.POST_QUERY_INFORMATION: + { + switch (infoClass) + { + case WinData.FileInfomationClass.FileRenameInformation: + { + if (FilterAPI.MessageType.PRE_SET_INFORMATION == messageType) + { + string blockFileName = @"c:\filterTest\blockRename.txt"; + //test block rename to blockFileName, it needs to register PRE_SET_INFORMATION; + if (string.Compare(messageSend.FileName, blockFileName, true) == 0) + { + EventManager.WriteMessage(179, "IOAccessControl", EventLevel.Warning, "Block rename for file:" + messageSend.FileName); + ret = false; + break; + } + } + + //you can block file rename as below + //messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION; + //messageReply.ReturnStatus = (uint)NtStatus.Status.AccessDenied; + break; + } + case WinData.FileInfomationClass.FileDispositionInformation: + { + //you can block file delete as below + //messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION; + //messageReply.ReturnStatus = (uint)NtStatus.Status.AccessDenied; + break; + } + case WinData.FileInfomationClass.FileEndOfFileInformation: + { + //change file size + break; + } + case WinData.FileInfomationClass.FileBasicInformation: + { + //file basic information + break; + } + + case WinData.FileInfomationClass.FileStandardInformation: + { + //file standard information + break; + } + case WinData.FileInfomationClass.FileNetworkOpenInformation: + { + //file network information + break; + } + + case WinData.FileInfomationClass.FileInternalInformation: + { + //file internal inofrmation + break; + } + default: + { + break; + } + } + + break; + } + } + + + } + catch (Exception ex) + { + EventManager.WriteMessage(174, "IOAccessControl", EventLevel.Error, "IOAccessControl failed." + ex.Message); + } + + return ret; + } + + } +} diff --git a/Demo_Source_Code/CSharpDemo/FileProtector/FileProtector.csproj b/Demo_Source_Code/CSharpDemo/FileProtector/FileProtector.csproj new file mode 100644 index 0000000..a2e1106 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FileProtector/FileProtector.csproj @@ -0,0 +1,246 @@ + + + + Debug + x86 + 8.0.30703 + 2.0 + {5D68B347-6B7E-4B0A-9DBF-82E287A52A21} + WinExe + Properties + FileProtector + FileProtector + v4.5 + + + 512 + SAK + SAK + SAK + SAK + false + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + true + + + AnyCPU + true + full + false + ..\..\..\debug\ + DEBUG;TRACE + prompt + 4 + false + false + + + AnyCPU + pdbonly + true + ..\..\..\Release\ + TRACE + prompt + 4 + false + + + protector.ico + + + true + ..\..\Release\ + DEBUG;TRACE + full + AnyCPU + ..\..\..\debug\FileProtector.exe.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + false + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + false + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false + false + false + + + ..\..\Release\ + TRACE + true + pdbonly + AnyCPU + ..\..\..\Release\FileProtector.exe.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + true + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + true + false + false + + + app.manifest + + + + + + + + + + + + + + + + + + + + + + Form + + + DecryptionForm.cs + + + + Form + + + EncryptionForm.cs + + + + + + + Form + + + ProtectorUnitTest.cs + + + + Form + + + ProtectorForm.cs + + + + Form + + + TutorialForm.cs + + + DecryptionForm.cs + + + EncryptionForm.cs + + + ProtectorUnitTest.cs + + + ProtectorForm.cs + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + True + Resources.resx + True + + + TutorialForm.cs + Designer + + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + + + + + + False + Microsoft .NET Framework 4 %28x86 and x64%29 + true + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + false + + + False + Windows Installer 3.1 + true + + + + + + + + {34CB783E-DDA2-4CE3-80BC-37B25AA33E5F} + CommonObjects + + + {21540012-A296-45CE-8D35-3EA5A07B32A6} + FilterControl + + + + + + + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/FileProtector/FileProtector.csproj.user b/Demo_Source_Code/CSharpDemo/FileProtector/FileProtector.csproj.user new file mode 100644 index 0000000..857d784 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FileProtector/FileProtector.csproj.user @@ -0,0 +1,6 @@ + + + + true + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/FileProtector/FileProtector.vs2019.csproj b/Demo_Source_Code/CSharpDemo/FileProtector/FileProtector.vs2019.csproj new file mode 100644 index 0000000..d22064a --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FileProtector/FileProtector.vs2019.csproj @@ -0,0 +1,263 @@ + + + + Debug + x86 + 8.0.30703 + 2.0 + {5D68B347-6B7E-4B0A-9DBF-82E287A52A21} + WinExe + Properties + FileProtector + FileProtector + v4.5 + + + 512 + SAK + SAK + SAK + SAK + false + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + true + + + AnyCPU + true + full + false + ..\..\..\debug\ + DEBUG;TRACE + prompt + 4 + false + false + + + AnyCPU + pdbonly + true + ..\..\..\Release\ + TRACE + prompt + 4 + false + + + protector.ico + + + true + ..\..\Release\ + DEBUG;TRACE + full + AnyCPU + ..\..\..\debug\FileProtector.exe.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + false + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + false + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false + false + false + + + ..\..\Release\ + TRACE + true + pdbonly + AnyCPU + ..\..\..\Release\FileProtector.exe.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + true + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + true + false + false + + + app.manifest + + + + + + true + bin\ARM64\Debug\ + DEBUG;TRACE + full + ARM64 + false + 7.3 + prompt + MinimumRecommendedRules.ruleset + false + false + + + bin\ARM64\Release\ + TRACE + true + pdbonly + ARM64 + 7.3 + prompt + MinimumRecommendedRules.ruleset + + + + + + + + + + + + + + + + + + + + Form + + + EncryptionForm.cs + + + Form + + + InputForm.cs + + + + + Form + + + ProtectorUnitTest.cs + + + + Form + + + ProtectorForm.cs + + + + Form + + + TutorialForm.cs + + + EncryptionForm.cs + + + InputForm.cs + + + ProtectorUnitTest.cs + + + ProtectorForm.cs + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + True + Resources.resx + True + + + TutorialForm.cs + Designer + + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + + + + + + False + Microsoft .NET Framework 4 %28x86 and x64%29 + true + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + false + + + False + Windows Installer 3.1 + true + + + + + + + + {21540012-A296-45CE-8D35-3EA5A07B32A6} + FilterControl.vs2019 + + + + + + + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/FileProtector/InputForm.Designer.cs b/Demo_Source_Code/CSharpDemo/FileProtector/InputForm.Designer.cs new file mode 100644 index 0000000..32d68ac --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FileProtector/InputForm.Designer.cs @@ -0,0 +1,96 @@ +namespace EaseFilter.CommonObjects +{ + partial class InputForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(InputForm)); + this.label_InputPrompt = new System.Windows.Forms.Label(); + this.textBox_Input = new System.Windows.Forms.TextBox(); + this.button_Ok = new System.Windows.Forms.Button(); + this.openFileDialog1 = new System.Windows.Forms.OpenFileDialog(); + this.folderBrowserDialog1 = new System.Windows.Forms.FolderBrowserDialog(); + this.SuspendLayout(); + // + // label_InputPrompt + // + this.label_InputPrompt.AutoSize = true; + this.label_InputPrompt.Location = new System.Drawing.Point(20, 8); + this.label_InputPrompt.Name = "label_InputPrompt"; + this.label_InputPrompt.Size = new System.Drawing.Size(117, 13); + this.label_InputPrompt.TabIndex = 0; + this.label_InputPrompt.Text = "Input the new file name"; + // + // textBox_Input + // + this.textBox_Input.Location = new System.Drawing.Point(23, 33); + this.textBox_Input.Name = "textBox_Input"; + this.textBox_Input.ScrollBars = System.Windows.Forms.ScrollBars.Horizontal; + this.textBox_Input.Size = new System.Drawing.Size(446, 20); + this.textBox_Input.TabIndex = 1; + // + // button_Ok + // + this.button_Ok.DialogResult = System.Windows.Forms.DialogResult.OK; + this.button_Ok.Location = new System.Drawing.Point(394, 59); + this.button_Ok.Name = "button_Ok"; + this.button_Ok.Size = new System.Drawing.Size(75, 20); + this.button_Ok.TabIndex = 2; + this.button_Ok.Text = "Ok"; + this.button_Ok.UseVisualStyleBackColor = true; + this.button_Ok.Click += new System.EventHandler(this.button_Ok_Click); + // + // openFileDialog1 + // + this.openFileDialog1.FileName = "openFileDialog1"; + // + // InputForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(514, 91); + this.Controls.Add(this.button_Ok); + this.Controls.Add(this.textBox_Input); + this.Controls.Add(this.label_InputPrompt); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Name = "InputForm"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "Rename"; + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Label label_InputPrompt; + private System.Windows.Forms.TextBox textBox_Input; + private System.Windows.Forms.Button button_Ok; + private System.Windows.Forms.OpenFileDialog openFileDialog1; + private System.Windows.Forms.FolderBrowserDialog folderBrowserDialog1; + } +} \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/FileProtector/InputForm.cs b/Demo_Source_Code/CSharpDemo/FileProtector/InputForm.cs new file mode 100644 index 0000000..5833531 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FileProtector/InputForm.cs @@ -0,0 +1,54 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; + +namespace EaseFilter.CommonObjects +{ + public partial class InputForm : Form + { + public string InputText = string.Empty; + + public InputForm(string caption, string promptText,string inputText) + { + InitializeComponent(); + this.Text = caption; + label_InputPrompt.Text = promptText; + textBox_Input.Text = inputText; + } + + private void button_Ok_Click(object sender, EventArgs e) + { + InputText = textBox_Input.Text; + } + + private void button_FileBrowse_Click(object sender, EventArgs e) + { + if (openFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + textBox_Input.Text = folderBrowserDialog1.SelectedPath; + } + + } + } +} diff --git a/Demo_Source_Code/CSharpDemo/FileProtector/InputForm.resx b/Demo_Source_Code/CSharpDemo/FileProtector/InputForm.resx new file mode 100644 index 0000000..c749c4f --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FileProtector/InputForm.resx @@ -0,0 +1,576 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + + 147, 17 + + + + + AAABAAgAEBAAAAEACABoBQAAhgAAABAQAAABACAAaAQAAO4FAAAYGAAAAQAIAMgGAABWCgAAGBgAAAEA + IACICQAAHhEAACAgAAABAAgAqAgAAKYaAAAgIAAAAQAgAKgQAABOIwAAMDAAAAEACACoDgAA9jMAADAw + AAABACAAqCUAAJ5CAAAoAAAAEAAAACAAAAABAAgAAAAAAEABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP// + /wAAzf8AmXtrAImb/gDdu6kAOljoAGP4/wDH0f0App6/AEme/wD14tkAocD+ANTG0AA87P8AfpjYAE5x + /wCrnpgA4+j/AGaN/wC1r9cAHeX/ALCOfQBfs/8AOoL/AMCoowD69OkAbeL/AE1m4wBbmvEAlpPIANvE + vAC1t8QAptH/AKadqQDx8vsA4c/KAKeCcABX7f8AV2fuAKez/wBdm/8AYOH/APz59ACtvf4Ag5H+APjt + 2gBDe/8A8OjgALKbnwDbv7MAnpfDAFSX/wCph3gA9/j/AEua+ABar/oA+vHiANvHwwCdf28A18zPAJt3 + ZgDcuqMA+vj6APz27gDcvq4Aon9vAP37+ACXeWcA28G3APT1+wBb7f8Aps3/AJx9bADewbQA+fTuAPry + 5gDevqsA3sS6AKuJegDauKUArIh3ANq6qAD39vsAmXtoAPnv4AD79ewA27ytANzCtQD9+vYA/PfwAK+O + fwDcuaUA3LunANu6qgDcv7EA28K5ANvFvgDbxsEA+vHkAN6+rQCafGoAnX5tAKOAcAD79eoA272vAJh5 + aACZemoAm3xrAJx8bQD79OgA+vPoALGOfgDcvKkA2ruqANvAtADbw7oA/fv5AJp8awCbfGwA/PnzAJx9 + bQCcfm0A/PbtAPrz5wD68+YA3LqlANy7qQDbuqkA3cK1ANu/sgDbv7QA28fCANvCuADbw7sAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAGxmenp6eUlsbGVUbAAAAAA9ARoaGm98TGNVLkQAAAAAQgGBgVhfQX9+Pjlq + AAAAAGcBhnSFMmlyUFx9awAAAAA1AYRiH0WCV1JdbgMAAAAATwE6hGFgc2mAcWh2AAAAAFs2DTwkYINp + XgVWbAAAAAAiKC0hCFNDWXhae3cAAAAADzQ4NycUTkpkTUBtAAAAAAYqFUcXDEZDK0swOwAAAAAdJgIO + GAQjdSUlJSUAAAAAHAoHGy8sP3UlC3ARAAAAAB4TKRBIEgEBJXARAAAAAAAZIDMJMRZRUSURAAAAAAAA + AAAAAAAAAAAAAAAAAAD//wAAwAMAAMADAADAAwAAwAMAAMADAADAAwAAwAMAAMADAADAAwAAwAMAAMAD + AADAAwAAwAcAAMAPAAD//wAAKAAAABAAAAAgAAAAAQAgAAAAAABABAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAJt8a/+dfm3/nH5t/5x+bf+cfm3/nH1t/5x9bP+bfGv/m3xr/5p8av+Ze2j/m3xr/wAA + AAAAAAAAAAAAAAAAAACbd2b///////r06f/69On/+vTp//rz6P/68+f/+vLm//rx5P/57+D/+O3a/5d5 + Z/8AAAAAAAAAAAAAAAAAAAAAon9v///////dwrX/3cK1/9zCtf/cv7H/3L6u/9y7qf/cuqX/3Lqj//rx + 4v+YeWj/AAAAAAAAAAAAAAAAAAAAAKOAcP//////28O7/9vDuv/bwrj/27+z/9u9r//au6r/2ril/9y5 + pf/68+b/mXpq/wAAAAAAAAAAAAAAAAAAAACph3j//////9vHwv/bxsH/28S8/9vBt//bv7L/27yt/9q6 + qP/cu6f/+/To/5l7a/8AAAAAAAAAAAAAAAAAAAAAq4l6///////bx8P/28fC/9vFvv/bwrn/28C0/9u9 + r//buqn/3Lyp//v16v+afGv/AAAAAAAAAAAAAAAAAAAAAK+Of//3+P//1MbQ/9fMz//hz8r/28K5/9u/ + tP/bva//27qq/927qf/79ez/m3xr/wAAAAAAAAAAAAAAAAAA/wGmnan/p7P//4OR/v+m0f//x9H9//f2 + +//9+/j//fr2//z58//89/D//Pbt/5t8bP8AAAAAAAAAAAAAAAAAKf8XfpjY/1SX//9ar/r/S5r4/1dn + 7v+1r9f/3sS6/97BtP/evq3/3r6r//z27v+cfG3/AAAAAAAAAAAAAAAAACz/NzpY6P9g4f//HeX//1vt + //9fs///ocD+//T1+//9+/j//Pn0//n07v/w6OD/n4Bw/gAAAAAAAAAAAAAAAAAu/0FbmvH/V+3//wDN + //887P//OoL//4mb/v/x8vv//fv5/6eCcP+ngnD/p4Jw/6eCcP8AAAAAAAAAAAAAAAA3fv8zTWbj/0me + //9j+P//beL//0N7//+tvf7/+vj6//37+f+ngnD/9eLZ/7GOfv+ngnBYAAAAAAAAAAAAAAAAABf/CJaT + yP9mjf//XZv//05x//+mzf//4+j/////////////p4Jw/7GOfv+ngnBYAAAAAAAAAAAAAAAAAAAAAAAA + AADAqKP/tbfE/56Xw/+mnr//spuf/7COff+siHf/rIh3/6eCcP+ngnBYAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAD//wAAwAMAAMADAADAAwAAwAMAAMADAADAAwAAwAMAAMADAADAAwAAwAMAAMADAADAAwAAwAcAAMAP + AAD//wAAKAAAABgAAAAwAAAAAQAIAAAAAACgAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8AKF31AKJ6 + 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 + ///9+/n/3MjD/9zIxP/cx8L/28W//9vEvf/bwbn/28C2/9u/sv/bva//27ur/9u5p//evar/+/bt//zz + 5/+Uc2D/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAApYRz//j5///p7Pv/xLbJ/8S5yf/Pwcb/2sO//9zE + vP/bwrn/28G1/9u+s//bva//27ur/9u5qP/evar//ffu//716P+Wc2L/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAP8BmH2C/8bR//+wv/7/mKDq/6PK8P+qr+f/wsLj/+LY3f/t39n/7N7X/+zd1f/s29L/7NrP/+vZ + zf/t2cz//Pfv//306f+Vc2H/AAAAAAAAAAAAAAAAAAAAAAAAAAAANf8di56x/4GR//9OdP//P17//37M + //9edv//mKz+/8bR/f/z9Pv//vz6//37+P/9+vb//fn0//z48v/8+PH//Pjw//326/+XdGP/AAAAAAAA + AAAAAAAAAAAAAAAx/wsALf8/WG3G/33U//88hv//UaT6/2PY/f8ravb/PV/w/4iO3P+5rc3/3sa+/9/F + uv/fw7b/38Cy/9+/rv/gwa///fjw//326/+WdGP/AAAAAAAAAAAAAAAAAAAAAAAx/x8AMP9dLEbc/0Oc + //9g6v//VOz//0fd/v9gwPv/KF31/2WK6/+lrtP/07u7/9zAtP/bvbD/3Lys/9y5qf/fvqv//fry//31 + 7P+YdWP/AAAAAAAAAAAAAAAAAAAAAAAz/y0AMf94JVXl/2vO//8s2///AMr//wTQ//9X6P//c9///12V + //+ruP//6ez8///9+//6+PX/9vLt//Ps5//s5N//4dbQ/8m1qf+NaFftAAAAAAAAAAAAAAAAAAAAAAAs + /y8AJv97QYDr/1TW//8o3f//AMr//wLP//9u7P//PY///0Ro//+puv//6Oz8/////v/Ktar/nHpp/6qL + eP+ohGr/onpc/4ZgT/OQZ1ZBAAAAAAAAAAAAAAAAAAAAACBb/ytkt/+NUYzp/0SW//909f//Ld///z7j + //9Qxv//LWz//1d4//+2xP7/8PH7/////f/Vx77/zLWj//zpxf/wzJL/m3Rc85ZpXDoAAAAAAAAAAAAA + AAAAAAAAAAAAAAAv/xAALP9GR1HI/0SC//9Mof//Ucr//2PC//9oyf//WJT//4uf/v/L1f3//Pr6///+ + /f/ZysP/xKOE/+zIjv+Xb1jylm5dPwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wEAN/8ldWyl/2mB + //9ss///QHr//ztx//9IZP//mMn+/7vN/f/t7vv//vz5/////P/azMT/u5Np/5x0W/KbbV84AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8DloCN/7rF//+q2v//jJ7//5Cl//+puv//xc7//+jv + ///////////////////RvrT/i2NR8Z1zYD0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAnXZi/6eJh/+ZjJX/kXyR/5J9kf+bgoj/p4d//6uJef+piHj/qId3/6mKeP+WcmHlmmtYNgAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA////AOAABwDgAAcA4AAHAOAABwDgAAcA4AAHAOAABwDgAAcA4AAHAOAABwDgAAcA4AAHAOAA + BwDgAAcAwAAHAMAABwDAAA8AwAAfAOAAPwDgAH8A4AD/AOAB/wD///8AKAAAACAAAABAAAAAAQAIAAAA + AACABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8AMFz/ALCIZgBj8P4Aq6bSAADL/wD41pwAa12QAHaC + /wC14v4Ae1tKAEI+twDm3NcAu6SaAE2r/wB4h8cAUGjZAHTA7gCbpP0AHz/eACjg/wDbwbYAiGpxAIms + twA0h/8Ak9npAN/l/ADLoW8Atb7/AJz7/wBXcf8Av8HOAPnhuwCOk9wA//XgAFzG/wCTbFQAQ+z/AID+ + /wA9eucAfKv/AHtzigBw1/wAydH+AI+zzwBledAA2rahAIiV/gCa4/8AR1//ADVJ8ABNUK4ARlTeALOX + iQB3e90AyretABXV/wCWem0ALTfQAFpv6gB95/8AonlaAPDx+wA8dP8AX6b5AEWX/wCniXgA+OTTAFze + /wC+8/4A2szFALiuygAjUN4AKWr/AEWD/wDMtr4AbMX/AH1kewD8+PAA6dbIAKv2/gCL7v8AqrP+AGK4 + +gBm//8AhmFQACpT9QDAmGoAvqGLAJBtZACjf2cAxa2fAN69qgDx174Avsn9AGx5/gA0evYANWb/APXw + 6ACyjXIAVvD/ANXd/AD03cUASuT/AFix+gBZff8Aldj/AEVg3gCacV0A1b/AAGmE/wAK0v8A+e3aAD9X + /wA8j/8AoYByALPJ/gB+lv8AzbzHAHrU/wDfxrwA88+WAODTzABxi/8AhbD/AOjr+wC3kGoAc8z/AEBr + /wBl2/8Ai57+AIhoZACXdWUAWKT/AJSV1QCQdHEAJzzVAPj5/wCU6v8Ak6j+ALOoyACMZlQA+/ToAP/+ + 9wDhwrAAzbqxADBW8wA7i/gAq7v+AMnZ/QDTwrkAx7fEAC5k/wBVwP8AgF1NANu5pwDbva4A+fDhAJms + /gBXrP8AkXNnAMWebgDB7f8A9eHNAMPO/QDa4v8A28W/AP37+gBI7/8AaXXNAJVtWgBSpP8A3sS3ALXD + /wDx2cIApYNvANHa/wDYysIA9ubXAPLdywBtyfsAQ2P/AIprawBh6/8AAc//ADVO8gDy9P8AlXBlAI/o + /wDVxb4Au6KVAKeozwD59e0A28O7AA/U/wDbx8MA2L+6ALC+/gD//vsAGdj/APXZvQD237gAztf9AJBn + VQCScmQAZfT/AN7CtACtt/8A/fr1AD/q/wBbb/8AoP3/AF17/wCDX04A+e/fADNq/wCRd2sA27urAFSp + /wC9xf4AMmP/APry5gD205oA3bqlAN7AsAB+XEsAiWNSAJxyYADa4fwAxtL/ALvI/wArZ/8AjnBkAOrt + +wDi5/wAWm3nAE+o/wDat6QAWL7/ANu/sgB1z/8AssH+AJNqVwD89uwASl7+APXl1QDz38oA89zHANjf + /wBshf4A//3yAMifbgD15NIA3r6rAN28qAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AABWVtbW1tbW1tbW1tbWm5ubm+Kb4uLimwsAAAAAAAAAAFZEtLS0tLS0tLS0tLT3tPj4r6+vXl7J4gAA + AAAAAAAAVvuPj4+Pj4+Pj97e3t7e3t6entdxcWcLAAAAAAAAAABWkPT09PT09I/09I+Pj4+Pj97entfX + Z+IAAAAAAAAAAFaQ9PStra2tra3P4eHh/l3/4OBdnp73CwAAAAAAAAAA45D09BYWFhbw8PCd2tqc7u4v + L+De3qTiAAAAAAAAAADjx09PFhYWFhYW8PCd2tqc7i8v4N6PpOIAAAAAAAAAAOPHT0/CwsLCwhYW8PCd + 2pyc7u7/j4/94gAAAAAAAAAAjsdPT6enp6fCwhYW8J3a2pzu7v+Pj/2bAAAAAAAAAACOAdHRxMTExKfC + whbw8J3anJycXY/0/ZsAAAAAAAAAAMwB0dHExMTEp8LCFhbwndranJxdj/T9mwAAAAAAAAAAzAHR0cTE + xMSnp8IWFvCd2tqcnP709PabAAAAAAAAAADMAaioxMTEp6fCwsIW8PCd2pycXfT09tYAAAAAAAAAAPMB + qKinp6enp8LCFhbwnZ3anJxd9PT21gAAAAAAAAAA84p+5UhIIJhuwsIWFvCdndqcnF309LPWAAAAAAAA + AACEsV/ylVNG3Mt+qKio0dHR0U9PT/RPs9YAAAAAAAAAACrQg28fajEwlaXrqKio0dHR0U9PT0+zVgAA + AAAAAAAAGClyS1dUQbo8IgV3eXmtz+H+/pFPT7NWAAAAAAAAABAMHqxCaQSUYZPsh43FFvCd2pyc/k9P + s1YAAAAAAAAALonoVT3OqSu1VzM3wEwW8J3anJz+T0+zVgAAAAAAAAARSaB4Fbm5ZSSC1Gt1G6jHx8eQ + 0dHBY1BWAAAAAAAAAGwUc7i5BgbDaA8C08blqMcNsntHvjgOhdkAAAAAAAAANShFqXAGBsgn7d3VxuWo + Ab90Q7BbAyWhAAAAAAAAAC0aEttNJsM50g8ZYnyu66gBOFwjIQeioQAAAAAAAAAAAKo7AlKAaCckJ5m2 + jKU/qMeSWcp6WOkAAAAAAAAAAAAAADSBAu+a8UqGiwnGZqiox7Jk3/yhAAAAAAAAAAAAAAAACHb1vUDY + YjJ9Ciw/qKjHl38czQAAAAAAAAAAAAAAAABOrhNRYPp2n8aW6qio0ceSPs0AAAAAAAAAAAAAAAAAALym + LKMdrufm+bsBAQEBATbNAAAAAAAAAAAAAAAAAAAAbeS8iBcXt1qrq6urq/OrOgAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AA + AA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD+AAAA/gAAAP4AAAD+AA + AA/gAAAfwAAAP+AAAH/wAAD/8AAB//AAA//wAAf/8AAP//////8oAAAAIAAAAEAAAAABACAAAAAAAIAQ + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAhGFQ/4ZhUP+EYE//hGBP/4Rg + T/+EYE//hGBP/4NgT/+DYE//g2BP/4NfTv+CX07/gl9O/4FfTv+BXk3/gF5N/4BdTv9/XUz/f11N/35c + S/9+XEz/fVtL/35dTf97W0v/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACFYVD/+OTT//Le + zP/y3sz/8t7M//LezP/y3sz/8t7M//LezP/y38z/8t3M//Ldy//y3cv/8t7K//Lcyv/y3Mf/89vH//Ha + xP/x2cL/8tjA//DXvv/x1r3/9dm9/3xbS/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIZh + UP///fL/+vTo//rz6f/68+n/+vPp//rz6f/68+n/+vPo//r06P/68uj/+vLn//ry5//68+b/+vHm//ry + 5f/68uT/+fHi//nw4P/5797/+Ozb//nt2f/03MT/e1pJ/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAhmFQ///+9f/79ur/+/Xs//v16//79ev/+/Xr//v17P/79er/+/bq//v06//79On/+/Tq//v1 + 6P/78+n/+/Pn//z05v/68uX/+vHl//nw4f/57+D/+vDe//Texv99W0r/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACHY1H///73//v17P/89uz/3sS3/97Ft//exbf/3sS3/93Dtf/dw7X/3cKz/93B + sv/dwbD/3b+u/92+q//dvar/3byo/926pf/duqX/376p//rx4v/68OH/89/J/3xbSv8AAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAIhiUf////f//Pbt//z27v/bwLT/28C0/9vAtP/bwLT/28Cz/9u/ + sv/bvrH/272u/9q7rP/auqr/2rmo/9q3pf/atqL/2rWg/9q1oP/duqT/+vLl//vz5P/14Mz/fVxL/wAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAiWNS////+v/89+///Pfv/9vCuP/bwrj/28K4/9vC + t//bwrb/28C1/9u/sv/bvrH/272v/9u8rP/auqr/2rmm/9q3pP/atqH/2rah/927pf/78+b/+/Tn//Ti + zv9+W0z/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACKZFP////6//z48P/8+PH/28O7/9vE + u//bxLv/28O7/9vDuf/bwrj/28C2/9u/s//bvrH/272u/9u8rP/auaj/2ril/9q3o//at6P/3bun//vz + 5//89ej/9uPS/4BdS/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAItlU/////v//Pjy//z4 + 8v/bxr7/28a//9vGv//bxL7/28S8/9vDuv/bwbf/28C1/9u+s//bva//27ys/9u7qv/buqj/2rek/9q3 + pP/dvaj/+/To//z06f/15NP/f1xN/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjGdU//// + /v/9+fP//fn0/9vHwv/bx8P/28fD/9vGwv/bxb//28S8/9vDuv/bwbf/27+z/9u+sf/bvK//27ur/9u6 + qP/buKX/27il/929qv/79On//Pbq//Xk0v+AXkz/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACPZlX///////369f/9+vX/28jD/9vIxP/byMT/28jC/9vGwP/bxL3/28O6/9vCuP/bwLX/276y/9u9 + r//bu6z/27qp/9u5p//buaf/3r6q//v16v/89ev/9eTT/4JdTP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAI9nVP///////fr2//379//bx8P/28fE/9vHxP/bx8P/28bA/9vFvv/bxLv/28K4/9vA + tf/bv7P/272v/9u8rP/buqr/27im/9u4pv/evqv/+/Xr//z17P/15NT/gV9O/wAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAkWhV///////9+/j//fv4/9zHwv/bxsP/28bD/9vGwf/bxcD/28S9/9vD + u//bwbn/28C1/9u/sv/bvrD/27yt/9u6qv/buKf/27in/969q//79ez//Pft//Xl1v+DXk3/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACSaVf///////78+f/+/Pr/2sTA/9rEwP/cxsD/3MbA/9zF + v//cxL3/28O6/9vCt//bwLX/276y/9u9r//bvK3/27qq/9u5p//buaf/3r2r//z27f/89u3/9eXV/4Ng + Tf8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJNqVv/4+f//6Ov7/9rh/P+4r8r/uK3K/7/B + zv/Ht8T/1b/A/9zEu//cw7r/28G3/9vAtP/bvrL/272v/9u8rf/bu6r/27mn/9u5p//evar//Pbt//z2 + 7v/15df/hF9P/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8BiGhk/9Ha//++yf3/ssH+/6u7 + /v+qs/7/vvP+/73F/v/O1/3/5+v7//37+//+/Pr//fv5//379//9+vb//fr1//359P/8+PL//Pjx//z3 + 7//89u7//fjv//fm1v+EX07/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACh4/yB7c4r/rbf//4ue + /v9phP//V3H//1l9//+a4///iJX+/6q6/v/Dzv3/4eb8//37+//+/Pn//fv4//379//9+vb//fn0//35 + 8//8+PH//Pfw//z37//99+//9ubY/4VhTv8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANv8RACT/OIms + t/98q///P1f//0WD//8qVPb/Yrj6/1+m+f81TvL/Wm/q/46T3P+rptL/zbzH/9/Hvf/fxbv/38O4/9/B + tP/fwLH/37+s/9+/rP/hwrD//Pfv//338P/25tj/hWBQ/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AwA1 + /ysAMP9QQj63/5z7//9SpP//RZf//1ix+v9j8P7/O4v4/zR69v8wVvP/Wm3n/5SV1f+zqMj/2L+6/9zA + tf/bvrL/272v/9u6qv/buaf/27mn/96+q//89+///ffw//bm1/+GYE//AAAAAAAAAAAAAAAAAAAAAAAA + AAAAQv8PADb/PAAw/2wnPNX/K2f//2b///995///ZfT//0jt//9w1/z/bcn7/ylS9P81SfD/d3vd/6eo + z//Mtr7/3MC1/9u+sv/bva//27qq/9u5p//buaf/3r6r//348f/9+PH/9+fZ/4ZhUP8AAAAAAAAAAAAA + AAAAAAAAAAAAAAA2/xsAM/9HAC7/iiNQ3v9XrP//etT//yjg//8Azv//As///1bw//9bxf//Zdv//6D9 + //+V2P//s8n+/9/l/P/+/Pr///35//79+f///fn///33//779//9+PP/+fXt//Xw6P/p1sj/h2JQ/AAA + AAAAAAAAAAAAAAAAAAAAAAAAADX/IQAy/0wALv+aHz/e/zyP//9h6///AM7//wDL//8Ayv//DdT//0ri + //9Mqv//MVz//1tv//+uvP7/2eD8//78+v///fv/5tzX/9nLwv/g08z/2szF/9XFvv/Itq3/u6Sa/5d1 + Zf+GYlG2AAAAAAAAAAAAAAAAAAAAAAAAAAAAMv8gACb/TAAY/5k9euf/XN7//0jw//8K0v//AMv//wDK + //8Z2P//gf3//0+o//8yY///XXv//66//v/Z4Pz//vz6//////+7opX/oYBy/6eJeP+lg2//o39n/7CI + Zv+TbFT/imRTxIZfSw4AAAAAAAAAAAAAAAAAAAAAAAAAAABD/xllvP9qiun/vHTA7v9Uqf//bMX//0Ps + //8Q1P//FdX//z/q//9Nq///NIf//zRl//9xi///tcP+/+Ln/P/+/Pr//////8u3rf/FrZ////Xg//nh + u//41pz/xZ5u/4ljU8GMXV8MAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC//DAAm/zkAH/9lLTfQ/zBd + //+L7v//c8z//0rl//9/////Xcf//4D///8uZP//Q2P//5Oo/v/Czv3/7/L7//78+v////z/zLqw/76h + i//237j/88+W/8CYav+IYlTPi2RODgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8BADP/JgAw + /0pNUK7/QGv//zBa//9Yvv//VcD//3XP//8pav//WKT//5Tq//92gv//sL7+/9Xd/P/8+vr//vz5///+ + /P/XycH/so1y//bTmv/In27/iWRVzJ1uXhIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAOv8LADf/MmtdkP9/lv//Sl7+/4/o//88dP//M2r//zZn//9HX///hbD//7Xi/v/J0f3/8PD7//78 + +v/9+/j////7/9PCuf+3kGr/y6Fv/4tkVM2VYlIRAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAOv8QfWR7/7bE//+bpP3/q/b+/2x5/v9shf7/fZX+/5ms/v+yvf3/ydn9/+rt + +//+/Pr//fv5//379////vv/zrqx/6J5Wv+PaVbWnXFZGQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACVb2T/2uL//8jQ///B7f//tb7//7XD//+7yP//xtL//9jf + ///y9P////////////////////////////+zl4n/j2dV1KFtYhcAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJpxXf+ccmD/lHBm/5B0cf+IanD/h2px/4pr + a/+QbWT/l25b/5dtW/+Wbln/lWxa/5RrWf+Talj/k2xZ/45nVbmTblUWAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/////wAAAP8AAAD/AAAA/wAAAP8AAAD/AA + AA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/gAAAP4AAAD+AA + AA/gAAAP4AAAH8AAAD/gAAB/8AAA//AAAf/wAAP/8AAH//AAD///////KAAAADAAAABgAAAAAQAIAAAA + AACACgAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8AMFz/ALCIZgBm7/8AqKXUAADL/wD41pwAZlyPAHaC + /wCt3/0AellJAEI+twDn3tgAvaSZAFCv/gBzg8kAVm7WAHq46ACbpP0AIETcADHe/wDbwbYAg2V1AIms + twAsg/8AltnhAN/l/ADNomwAt7vvAJX6/wBScv4Av8HOAPnhuwCNktwA/fLeAGHH/QCTbFQARun/AID+ + /wAvaeQAeq39AImRmwBw1f8AydP+AI7E3QBnec8A2rWfAISV+ACa4/8AR1//ADVJ8ABETLQARlTeALKW + igBwf+QAyretABPS/wCWem0ALTfQAFZ76wB76f8ApX5dAPDy/QA3d/8AX6b5AFKV9QCoinsA+OTTAF3i + /wC+8/4A3c7GALmwzwAfV+EAKnH+AESG+wDMtr4AZMP7AHpgeQD79/IA6dXFAKv2/gCE8P8Ap7P3AGW4 + /wBm//8AhmFPACdT7gDDmGcAxKWJAJBtZAClf2cAxK6gAN++qQDqz7sAwcn4AGx5/gAyev0ANmb+APbw + 5wCyjXIAVun/ANPb/QD14sMASeX/AFuw/QBYgP4Ak87+AEBf4QCacV0A1MHDAGeD/gAL0f8A8+reAD9X + /wAzkv8AoYByALTQ/gB8k/wAz8DJAIHX/QDmzLoA8MqNAN/QygBylP8Ahbz/AOjo9wC4j2UAccz7AEBo + /wBm2f8Ah6D/AIhoXQCbdWUAWJ3/AJaX1wCQdHEAJ0HUAPn5/QCU6v8Alaj8ALOoyACLZVQA+vHrAP78 + +ADmyLIAzbqxADRc8gA7i/gAq7r8AMva/QDTwrkAyLjGACxl+gBVwP8AgV1MANu5pwDbva4A9+3jAKCv + +QBZr/8AkXNnAMGceADL6v4A+ufJAMTN+wDZ4f4A28W/AP37+QBI7/8AaXXNAJZtWQBSpP8A4Ma3ALXE + /gDx2cIApYNxANLa/gDcyr8A8ufbAO7ezwBtyfsAQWL9AIppbABd6f8ABM//ADlV7AD19fsAlm5iAI/o + /wDVxb4AuJ+TAKCd0wD58+0A28O7ABDS/wDcyMMA2L+6AK+//wD//vsAH9j/APXZvQD02rAA0NT1AJFo + VQCUc2UAafP/AN/EtACtt/8A/Pn1AD3j/wBbb/8Aof//AFx7/gCEX00A9ezfADFp/wCPeW4A27urAFSp + /wC7xPsANWD/APrw6ADz050A3rylAODArgB/W0sAiWNSAJxyYADa4fwAxdD/ALvH/gAoZvsAjXBjAOru + /QDj5vkAWm3nAE+o/wDbuKQAW7r/ANu/sgB30P8AssH+AJNqVwD89uwASl7+APDk1gDz38oA89zHANng + /wBqh/8A//3yAMifbgDv4tMA37+sAN28qAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAABWVtbW1tbW1tbW1tbW1tabm5vWm5ubm5vi4uLi4uILCwsLCwsAAAAAAAAAAAAAAADiXl5e + Xl5eXl5eXl5eXl5eeXl5eXl5eXl5kZGRkZGRkZGRkQsAAAAAAAAAAAAAAADiUFBQUFBQUFBQUFBQUFBQ + UHl5eXl5eXl5eXl5eXl5eXl5kQsAAAAAAAAAAAAAAADitFBQULS0tLS0tFBQUFBQUFBQUFBQUFBQUFBQ + UFBQUFB5kQsAAAAAAAAAAAAAAADis7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Oz9vb29vb29rRekQsAAAAA + AAAAAAAAAACbs2NjY2OteXmtra2tra2tz8/PkZHh4f7+/l3/4JFx17R5kQsAAAAAAAAAAAAAAACbs2Nj + Y2Pw8PDwnZ2dnZ2dndranJyc7u4vLy8vL+DX17RQkQsAAAAAAAAAAAAAAADWs95jY2Pw8PDw8PDw8J2d + nZ3a2tqcnO7uLy8vL//X1/1QkQsAAAAAAAAAAAAAAADWs8FjY2MWFhYWFhYW8PDwnZ2d2tqcnJzuLy8v + L13X17RQkQsAAAAAAAAAAAAAAADW18HBwcEWFhYWFhYWFhbw8J2dndranJyc7i8vL13X1/1QeQsAAAAA + AAAAAAAAAADW18HBwcHCwsLCwhYWFhYW8PCdnZ3a2pyc7u4vL12env1QrQsAAAAAAAAAAAAAAABW18HB + wcHCwsLCwsLCwhYW8PDwnZ2d2tqcnO4vL/6envZQeQsAAAAAAAAAAAAAAABW10/BwcGnp6enp8LCwhYW + FvDw8J2d2tqcnO7uL/5jY/1QeQsAAAAAAAAAAAAAAADWnk9PT0+np6enp6fCwsIWFhbw8J2d2tranJzu + L/5jY/ZQeQsAAAAAAAAAAAAAAABWnk9PT0/ExMTEp6enp8LCFhYW8PCdndranJzu7v5jY/ZQeQsAAAAA + AAAAAAAAAABWnk9PT0/ExMTExMSnp8LCwhYW8PCdndranJyc7v5jY/ZQeQsAAAAAAAAAAAAAAADjntHR + 0dHExMTExMSnp8LCwhYWFvCdnZ3anJyc7v5jY/ZQeeIAAAAAAAAAAAAAAADjY9HR0dHExMTExMSnp6fC + whYWFvCdnZ3anJyc7v5jY/ZQeeIAAAAAAAAAAAAAAADj3tHR0dHExMTExKenp6fCwhYWFvDwnZ3a2pyc + 7uFj3rNQXuIAAAAAAAAAAAAAAADj3qioqKjExMTExMSnp6fCwhYWFvDwnZ3a2pyc7uFjY7NQeeIAAAAA + AAAAAAAAAACOj6ioqKinxMTEp6enp6fCwhYWFvDwnZ3a2pyc7pFjY7NQeeIAAAAAAAAAAAAAAACOj6io + qKjExMTEp6enp8LCwhYWFvDwnZ3a2pyc7pFjY7NQeZsAAAAAAAAAAAAAAACOwceox8enp6enp6enp8LC + whYWFvDwnZ3a2pyc7pHBY7NQXuIAAAAAAAAAAAAAAADMwYo/6uqYd26np6enwsLCFhYW8PDwnZ3a2pyc + 7pHBwbNQXpsAAAAAAAAAAAAAAACO66axLCwsLKP5forHx8fHx6ioqKjR0dHR0dFPT0/BwbNQXpsAAAAA + AAAAAAAAAABOpV+ulZWVCnVfLPk/AcfHx8eoqJCo0dHR0dFPT0/BwbNQXpsAAAAAAAAAAAAAAABOlZ+D + fPpvHoOfxl+x6gHHx8fHqKio0dHR0dFPT0/BwbNQXpsAAAAAAAAAAAAAABoIMNWBYmJi1Lo8NyIFSHd7 + e0fEeXl5eXmtrc+RkXnBwbNQXpsAAAAAAAAAAAAAABAaat1iVJlpPVeTkzciBUhup8LCFhYW8J3a2pyc + 7pHBwbNQXpsAAAAAAAAAAAAAEBFs1IboHhlFJOhhk5M3hwWYp8LCFhYW8J3a2pyc7pHBwbNQeZsAAAAA + AAAAAAAALmwUac4kRT0VJE2AmZNsIsBIp8LCFhYW8J2d2v+c7uHBY2NQz1YAAAAAAAAAAAAQEVdJSivI + BBXDzgQZSkBCawqWP8fHqKioqMfHx5BPY2OzDQ2yNuMAAAAAAAAAAAAQbFdCK4IEBgYGcFJFztTxfFPm + fsfHqKioqEdcDg6/vzY2Q81W4wAAAAAAAAAAAAAQbFdJD2W5BgYGBshF70rd1VOl68fHqKiox1ywklxc + WVmiHH/jAAAAAAAAAAAAAAAQbFdJJEU5BgYGBtKCGUpialOl68eoqKioqJIOx9ekyt96HI4AAAAAAAAA + AAAAAAAQPHgeBLi4BgYGcM6CPUtib1OlfseoqKjRqEdDI2fKenocjgAAAAAAAAAAAAAAAAAtEksoSg8m + uMjDZWhzSthidsYsP6ioqKjRqHuwpMp6eliOAAAAAAAAAAAAAAAAAAAALroUSh5pZQRl8bg9SmIfjK6x + iqioqKjRkHtbynp6HI4AAAAAAAAAAAAAAAAAAAAAEBGJS2FKzu8roGFSeLZ2laXrqKioqNHRqHtb33pY + hAAAAAAAAAAAAAAAAAAAAAAAABA0tmJLHmEZoNjdeH2f52a7qKio0dHR0Xs+eliEAAAAAAAAAAAAAAAA + AAAAAAAAAAAIdh+GeN1iYoEfdgp1y+qoqKio0dHR0Uc+HIQAAAAAAAAAAAAAAAAAAAAAAAAAAAAIU4xr + KdXVb3aMldyW66jR0dHR0U9P0Vyr6QAAAAAAAAAAAAAAAAAAAAAAAAAAAABOXx0KU5+fU1MdX8t+3t7e + 3t7e3p6e3oXpAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC8txcqTk5OTk5Ot6urq6vz8/Pz88zMzNkAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///////8AAP// + /////wAA/AAAAAA/AAD8AAAAAD8AAPwAAAAAPwAA/AAAAAA/AAD8AAAAAD8AAPwAAAAAPwAA/AAAAAA/ + AAD8AAAAAD8AAPwAAAAAPwAA/AAAAAA/AAD8AAAAAD8AAPwAAAAAPwAA/AAAAAA/AAD8AAAAAD8AAPwA + AAAAPwAA/AAAAAA/AAD8AAAAAD8AAPwAAAAAPwAA/AAAAAA/AAD8AAAAAD8AAPwAAAAAPwAA/AAAAAA/ + AAD8AAAAAD8AAPwAAAAAPwAA/AAAAAA/AAD8AAAAAD8AAPwAAAAAPwAA+AAAAAA/AAD4AAAAAD8AAPAA + AAAAPwAA8AAAAAA/AADgAAAAAD8AAOAAAAAAfwAA4AAAAAD/AADgAAAAAf8AAOAAAAAD/wAA4AAAAAf/ + AADwAAAAD/8AAPAAAAAf/wAA+AAAAD//AAD8AAAAf/8AAPwAAAD//wAA/AAAAf//AAD8AAAD//8AAP// + /////wAA////////AAAoAAAAMAAAAGAAAAABACAAAAAAAIAlAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAhWFQ/4RhUf+DYE//g19P/4Nf + T/+DX0//g19P/4NfT/+CX0//gl9P/4JfT/+CYE//gl5O/4JeTv+CXk7/gV5O/4FeTv+BXk7/gV9O/4Bd + Tf+AXU3/gF1N/39eTf9/XE3/f1xM/35cTP9+XUz/fltM/31bS/99XEv/fFpK/3xbSv97W0r/e1tL/3tb + S/97W0z/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgFxL/+7R + u//rzrn/6s25/+rNuf/qzbn/6s25/+rNuv/qzbr/6s26/+rNuf/qzbn/6s25/+rNuf/qzrn/6865/+nO + uP/pzbj/6c24/+nNt//qzbf/6s23/+rMt//qzLb/6cy2/+nLtf/py7T/6cu0/+nLs//oy7P/6Mqz/+jK + sv/oyrH/58mx/+vLsv92Vkj/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAf1xL/+rUwv/m0L//5tC//+bQv//n0L//59C//+fQwP/n0MD/59DA/+fQv//m0L//5tC//+bQ + v//m0L//5tC//+bQvv/mz77/5s++/+bPvf/mz73/5c+9/+XPvP/lzrz/5c67/+XOu//lzbr/5M26/+TN + uf/kzLn/5My4/+TMt//ky7f/5My3/+XIsP93VUb/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAgFpJ//Dez//s2sv/7NrM/+zazP/s28z/7NvM/+zbzP/s28z/7NvM/+zb + zP/s2sz/7NrM/+zay//s2sv/69rL/+vay//r2sr/69nK/+vZyv/r2cn/69nJ/+vYyP/q2Mj/6tjH/+rX + x//q18b/6tfG/+nWxf/p1sT/6dbE/+nVw//o1sP/5tC8/+bJsf92V0f/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgVxK//Tl2P/z6d3/8uje//Lo3v/y6N7/8ujd//Lo + 3f/y6N3/8ujd//Lo3f/y6N7/8uje//Lo3v/y6Nz/8ujd//Lp3f/y59z/8ufc//Pn3P/x6Nv/8ebb//Hm + 2v/x59r/8uXZ//Dl2P/w5tj/8OTX//Hl1f/v49b/7+PV//Dk1P/t3s3/59C8/+XIsf94Vkf/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgltK//Xn2v/38Oj/9u/n//bx + 5v/28ej/38e4/9/Huf/fx7n/38e4/9/HuP/fxrj/38a4/9/Gt//fxbf/38S1/9/EtP/fxLP/38O0/9/D + sf/fw7H/38Gu/9/Arv/fwK3/38Cr/96+q//ev6n/3r2m/967pf/hxKv/8+re//Tr3v/t4ND/5tC9/+XK + s/95WEf/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAglxL//Tm + 2v/38ej/9/Do//fw6P/38Oj/2r6x/9q+sf/avrH/2r6x/9q+sP/avrD/2r6w/9q9r//ava7/2r2t/9q8 + rf/avKz/2rqr/9q6qf/auaj/2rmm/9q4pP/at6P/2rei/9q2oP/atp//2bSd/9mzm//evKX/9Ove//Pr + 3v/t39D/5tG+/+fJsv95V0j/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAg15L//Tn2//48un/9/Hp//fx6f/38en/28Cz/9vAs//bwLP/28Cz/9vAs//bwLL/27+y/9u/ + sf/avrD/2r2v/9q9rv/avK3/2ryr/9q7q//auqr/2rmn/9q4pv/auKT/2rej/9q3ov/atqD/2rWe/9m0 + nf/evab/9Ovf//Xs3//v4dL/5tG//+bLs/96V0j/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAhF1K//bo3P/48uz/+PLq//jy6v/48ur/28G1/9vBtv/bwbb/28G1/9vB + tf/bwLX/28C0/9vAs//bv7P/27+x/9u+sP/bvq//2ryt/9q7q//au6r/2rqp/9q5qP/auKb/2rek/9q3 + ov/atqL/2raf/9q1nf/fvqj/9Ozg//Ts4P/u4NH/59LA/+bKtP96WUj/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAhV9M//Xq3//48+z/+PPr//jz7P/48+z/28K3/9vC + uP/bw7j/28K4/9vCt//bwrb/28K1/9vAtP/bwLT/27+z/9u/sf/bvrD/272u/9u9rf/au6z/2ruq/9q6 + qf/auaf/2rim/9q3pP/atqL/2rah/9q1n//fvqn/9ezh//Tt4f/u4tL/59LA/+bMtv97WEn/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAh15L//fp3//59O3/+PPt//nz + 7f/59O3/28O6/9vDuv/bw7r/28O6/9vDuf/bw7j/28K3/9vCt//bwLb/28C0/9u/sv/bvrH/276w/9u9 + r//bvK3/27yr/9q6qv/auqj/2rmm/9q4pf/at6P/2rah/9q1oP/fvqn/9e3i//bt4v/w4dP/59PB/+jL + tf97Wkj/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAhmBN//bq + 4P/59e7/+fTu//n07v/59O7/28S7/9vEvP/bxLz/28S8/9vEu//bw7r/28O6/9vCuf/bwrf/28C2/9u/ + tP/bv7P/276x/9u9r//bva7/27yt/9u8q//bu6n/2rmn/9q5pv/auKT/2rai/9q2oP/fv6r/9e3j//Xu + 4//v49X/6NPC/+fLtv98WUj/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAhmBN//br4f/69fH/+fXv//n17//59fD/28S+/9vFvv/bxb7/28W+/9vEvf/bxLz/28O7/9vD + uf/bwrj/28G3/9vBtv/bv7T/276y/9u+sf/bva7/27yt/9u8rP/bu6v/27qo/9q5p//auKX/2rej/9q2 + ov/fv6v/9e7k//Xu5P/v4tT/6NPC/+fLuP98WUj/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAh19M//fs4v/69vH/+vbw//r28f/69vH/28bA/9vGwP/bxsH/28bA/9vG + v//bxb7/28W8/9vDu//bwrr/28K4/9vBtv/bwLX/28Cz/9u+sv/bvbD/272u/9u8rP/bu6v/27up/9u6 + p//auKb/2rik/9q3ov/fv6z/9u7k//Xv5f/v5NX/6NTD/+fNt/98WUr/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAiGFO//fs4//69/L/+vby//r28v/69/L/28bC/9vH + w//bx8P/28fC/9vGwf/bxsD/28W+/9vEvf/bxLv/28O6/9vBt//bwLb/28C0/9u/sv/bvrH/272v/9u8 + rf/bu6v/27uq/9u6qP/buaf/2rik/9q3o//fwKz/9u/l//fv5f/x49b/6NTE/+fMuf99W0n/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAiWBN//jt5P/7+PP//Pfz//v3 + 8//79/P/28jC/9vIxP/bycT/28jD/9vIwv/bx8H/28a+/9vFvf/bxLv/28O6/9vCuf/bwrf/28G1/9u/ + s//bvrH/276w/9u8rv/bu6z/27ur/9u6qP/buaf/27ml/9q3o//fwKz/9u/m//bw5v/w49j/6dTE/+fO + uv99Wkn/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAi2FP//ju + 5f/7+PT/+/j0//v49P/7+PX/28jD/9vIxP/bycX/28jE/9vHw//bx8H/28a//9vFvv/bxbz/28S6/9vC + uf/bwrf/28G2/9vAtP/bvrL/276w/9u9rv/bvK3/27ur/9u6qf/buaj/27ml/9u4o//fwK3/9/Dn//bw + 5//w5df/6dXF/+jNuf9+Wkn/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAimNO//ju6P/8+ff/+/n1//v59v/8+fb/28fE/9vIxP/byMX/28jE/9vHw//bxsL/28bA/9vF + vv/bxb3/28S7/9vCuf/bwbj/28G2/9vAtP/bv7P/276w/9u9r//bvK3/27ys/9u6qf/buaj/27mm/9u4 + pP/gwK3/9/Do//bx6P/w5Nj/6dXG/+jNuf9+Wkv/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAi2JQ//nv6P/8+vf//Pn2//z69//8+vf/28fC/9vHw//bx8P/28fD/9vH + wv/bxsH/28bA/9vFvv/bxL3/28S7/9vCuv/bwbj/28C2/9vAtP/bv7P/27+x/9u+r//bvK7/27ur/9u7 + qv/buaj/27im/9u4pf/gwK7/9/Ho//jx6P/y5Nr/6dXG/+jPu/9/XEr/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjGRP//nw6f/8+/j//Pr4//z6+P/8+/j/3MfC/9zH + w//cyMP/3MfD/9zHwv/cx8H/3MbA/9vEvv/bxL3/28O7/9vDuv/bwbj/28C3/9vAtf/bv7L/276x/9u+ + sP/bva3/27us/9u7q//buaj/27im/9u4pf/gwK//9/Hp//fx6f/x5Nn/6dbH/+jOuv9/W0r/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjmNR//nx6v/9+/n//vv5//37 + +f/9+/r/3MbB/9zHwf/cx8H/3MfB/9zGwf/cxsD/3Ma//9zFvv/cxb3/28O7/9vCuv/bwrj/28G2/9u/ + tf/bv7P/276x/9u9r//bva7/27ys/9u7qv/buqn/27in/9u4pP/gwa7/9/Hq//fy6f/x5tv/6tbH/+jO + vP+AW0r/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAj2RQ//rx + 6//9/Pr//fz6//38+//9/Pv/3MfB/9zHwf/cx8H/3MfB/9zHwP/cxsD/3Ma//9zFvf/cxLz/3MO7/9zD + uv/bwbj/28G2/9vAtP/bvrP/276x/9u9r//bva7/27ys/9u6qv/buqn/27mm/9u3pP/gwa7/+PLq//fy + 6v/x5dr/6tbI/+jOu/+AXUz/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAj2ZQ//ry7P/+/fv//fz7//79/P/+/fz/3MbA/9zGwf/cxsH/3MbB/9zGwP/cxsD/3MS//9zE + vf/cxLz/3MO6/9zCuf/cwrj/28C2/9vAtP/bv7P/276y/9u9r//bvK7/27ys/9u7q//buaj/27mn/9u3 + pP/gwa7/+PLr//fy6//x5dz/6tbI/+nQvf+AXEv/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAkGVS//vy7f/6+f7/8vP8/+zu/f/p7f3/yrnE/8y7xP/RwcP/2cPA/9zF + v//cxb7/3MS+/9zDvf/cw7v/3MO6/9zCuP/cwrf/3MG2/9u/tP/bv7L/276x/9u9sP/bvK3/27us/9u7 + qv/buqj/27mm/9u4pP/gwa7/+PLr//nz6//x59v/6tfJ/+nPvP+BXEv/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjmZV/+Th8P/Z4f7/0Nn9/8rU/v/I0v7/yNL+/8jT + /v/L6v7/2eD+/+fr/v/4+f7//v79//7+/f/+/fz//v38//79+//+/Pr//vz6//78+f/9+/j//fv3//36 + 9v/9+vX//fr0//359P/9+fP//Pjy//z48f/89/D/+PPs//jz6//y5t3/6tfJ/+nPvP+BXEv/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMv8QfF5s/8fK8v++y///s8P+/629 + //+qu///qrn//63Z//+x0P//vsr//8rU///Z4P//7vH+//7+/v/+/v3//v38//79/P/+/fv//vz6//78 + +f/+/Pj//fv4//379//9+vb//fr1//359P/9+fP//fny//z48f/8+PD/+PPs//jz7P/y5tz/6tfJ/+nP + vv+BXkv/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADZ//xwSSf8ybll9/624 + 9P+esf//iJ///3WQ//9qh///aoD//5zy//+FoP//nrD//7DA///AzP//0tv//+rv/v/+/v7//v79//79 + /P/+/fz//v37//78+v/+/Pn//fv4//379//9+vb//fr1//369P/9+fP//fny//z48v/8+PH/+PPs//jz + 7P/y5tz/6tfJ/+nPvf+CXUv/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC3/EgAo + /y6C4f+MY2GZ/4SV+P9bev//Qmn//zhm//83Y///NGT2/6P+/v86VPP/UWvv/3eG5v+UmuD/p6fb/7mz + 1v/SxM7/4c7J/+HNyP/hzcb/4cvD/+HKwf/hysD/4cm+/+DHvP/gx7r/4MW4/+DEtv/gxLT/4MKy/+DC + r//kyrj/+PPt//j07P/y5tz/6tfJ/+nPvf+CXU3/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAIf8IADP/KQAy/0EKQP9ilujn/1WF/P82YP//Mmb//2W4//8uZ///X7D6/3bm/f8rWfX/L1n0/z5d + 8P9peuT/kJTZ/6Wi0/+6sMz/1sHC/9zFvf/cxLz/3MK6/9zBuP/cwLX/3MC0/9u+sf/bvbD/27ut/9u7 + qv/buqn/27mm/9u3pP/gwa7/+fPt//j07f/z6N7/6tfK/+nPvv+CXUz/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAMv8bADL/OAAx/1IALf9+PGPZ/57///9Vov//K2n//5T2//8xif//YeP+/2DQ + /P8lYvb/OX32/y5f9P88XPD/cH7i/5aX1/+sps//xrfH/9zFvv/cxLz/3MK6/9zBuP/cwLX/3MC0/9u+ + sf/bvbD/27ut/9u7qv/buqn/27mm/9y4pP/gwa7/+PTu//n07f/y5tz/6NXH/+TJuP+CXUz/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAs/wYAMf8qADT/RgAx/2cAMf+rH0Db/16u/f9e9///YcL//2Hg + //9/7P//NeD//2PJ/P9kw/v/ccz7/yli9f8uWfP/SWHs/4SI3P+gndP/ua3L/9jCv//cxLz/3MK6/9zB + t//cwLX/3MC0/9u+sf/bvbD/27yt/9u7qv/cu6n/27mn/9u4pf/gwK7/+fXu//bw6f/z7OT/6dnO/9/E + tP+GYlD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAw/xAAM/8zADT/UAAz/4IANv/CHUze/ylq + /P9s1///H9n//2nu//8t2///ENL//3Lz//9m8P//IoH//ypx//83d///VZD//5LM//+w2///ytf//+/y + /v/+/v3//v38//38+//9+/n//Pr4//37+P///vr////8///9+v/9/Pf/+fXy//Xw6v/x6eT/7OXe/+jf + 2f/l3Nb/3Mq//7GPf/+EY1X0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAq/xgAMP86ADH/WAAy + /5kAOf/JT5nq/3DS/v9n0///Ze///wDK//8AzP//AMz//wvR//+C8v//XOD//2r1//+e////es3//2+Y + //+ntf//xdD//+fr/v/+/v3//v38//38+//9+/n//Pr4//37+f/azcX/wKqf/76mm/+8o5j/uKCU/7ee + kv+zm5D/spiP/6iNgP+Uc2X/h2JR/4hjUvyKbF1PAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAt + /xwAM/89ADH/XQAz/6UAP//KG1Ph/1Ct/f9Y5///BM///wDM//8AzP//AMz//wDM//8c1///W+T//1u8 + //8tdP//NWD//1p5//+itP//ws7//+Po/v/+/f3//v38//38+v/9+/n//Pr4///++//DrqP/pINz/8y7 + sv/Is6X/xq2a/8Wojv/DooP/wZx4/8qicv+4j2X/iWRW+5RzYkUAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAt/xwAM/89ADH/XQAu/6UANv/KJGXl/2DB/v9W5P//E9L//wDM//8AzP//AMz//wDL + //894///Z9P//ySB//8tcf//NWj//1p7//+itP//ws7//+Po/v/+/f3//fz7//38+v/9+/n//Pr4///8 + +v/NubD/vKSY////+v/78N7/+ObJ//Xcs//y05//88yL/9Opb/+HZVf5j3NjOgAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAp/xgAKv87ACr/Wjd8/7N72v/tkP7+/170//9c5v//W+v//wDK + //8AzP//AMz//wvQ//9w7P//Zd7//4Tj//8/h///NmX//2OC//+mt///w87+/+fr/f/+/fz//fz7//37 + +v/8+/n//Pr3//77+P/d0Mj/p4Z1//3y3v/14sP/8tiv/+7Om//vyIj/y6Br/4dlV/mPcmcxAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAs/xBEkf9NedX/l2i9/7o4gf/VL2nk/ydy + /f9QsP//Run//1rq//8h1///D9L//1bq//9J5f//M5L//ypw//8xa///O2X//3qU//+tvv7/ytT+/+/x + /f/9/Pz//fz6//37+f/8+vj//Pr3///7+f/e0sr/poJu//voyf/y167/7s2b/+/Ihv/Fmmn/h2RX+ZBz + ZToAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAr/wYAK/8rACr/RwAr + /2oALv+vIEfc/yxv/P+Z/f//U7L//1fo//9s6v//VOr//3PS//9i6f//dO3//yxu//81Z///UHP//5Sp + /v+3xf7/09r9//j5/P/9/Pv//fv6//z7+f/8+vj//Pn3//389//e0sr/pYBp//bcsf/uzpj/78eF/8yg + av+GZlj3k3ZqMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAMP8cADD/OgAw/1QAMv+EJ0HU/0WC/P8yeP//KHf//2P2//9at///dNb//1Wx//8sev//he3//37S + //9BXv//e5T//6q6/v/Ezv3/4ub8//38+//9/Pr//fv5//z6+P/8+vf//Pn2//36+P/e0sv/pH1k//TS + m//wxoP/xppo/4hnW/WVeWooAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAHf8JADD/KwAx/0MAMf9dREy0/0Fl+v81ZP//Q4b//5L///8wd///N4L//12t + //8xZ///M2L//4XZ//+FvP//obD+/7vH/v/T2/3/9fX7//38+v/9+/n//Pv4//z69//8+fb/+/n1//36 + 9v/f08v/o3xe//PLhf+/lGX/h2da9pV8dCEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADn/FAAv/zAANP9GYVWS/3qQ9f9TcP7/W5j//4Xb + //81X///NWX//zlp//89Zv//U3P+/32P/v+p4f//ttD9/83V/f/q7fv//f36//77+f/8/Pj//Pr5//z5 + 9//7+vb/+/j1//779//bzcT/p39b/8ygaP+KaFz1k3hxKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AQAx/xcAMP8wb12C/6mz + 8v+Wpvv/k9D9/3qt/f9eev3/Xn79/2mG/f9+lv3/lqn8/6q5+/+7xPv/zN37/+Tn+f/7+vj/+/n3//z5 + 9v/6+PX/+vj1//r39P/79/P/+fby///69v/DraD/mG9W/4ttX/KMc2shAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAALP8TgGJx/8XH7v+3ue7/ruj3/6Ot8f+irPH/oqzy/6aw8f+ttfH/trzw/8PG7//S0u3/6ePr//vx + 6P/78On/+/Dp//rv6P/67+f/+u/o//ru5v/57eX/+e3l//vv5f+bdWX/jW1g75N+choAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAlm5i/4tqbf+DZXX/iZGb/3lgfv92YID/dmCA/3hhfv98Y3v/gGRz/4ln + av+TbF//l2xY/5ZtWP+Va1n/lWxX/5RqV/+Ta1j/k2lW/5JqV/+RaFX/kWlW/5BpV/+LcGPVf3JlFQAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJ/8GNID/FQAr/xUANP8ZADT/GQAw + /xUAN/8OADb/BQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////AAD///////8AAPwAAAAAPwAA/AAAAAA/ + AAD8AAAAAD8AAPwAAAAAPwAA/AAAAAA/AAD8AAAAAD8AAPwAAAAAPwAA/AAAAAA/AAD8AAAAAD8AAPwA + AAAAPwAA/AAAAAA/AAD8AAAAAD8AAPwAAAAAPwAA/AAAAAA/AAD8AAAAAD8AAPwAAAAAPwAA/AAAAAA/ + AAD8AAAAAD8AAPwAAAAAPwAA/AAAAAA/AAD8AAAAAD8AAPwAAAAAPwAA/AAAAAA/AAD8AAAAAD8AAPwA + AAAAPwAA/AAAAAA/AAD8AAAAAD8AAPgAAAAAPwAA+AAAAAA/AADwAAAAAD8AAPAAAAAAPwAA4AAAAAA/ + AADgAAAAAH8AAOAAAAAA/wAA4AAAAAH/AADgAAAAA/8AAOAAAAAH/wAA8AAAAA//AADwAAAAH/8AAPgA + AAA//wAA/AAAAH//AAD8AAAA//8AAPwAAAH//wAA/AAAA///AAD///////8AAP///////wAA + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/FileProtector/MessageHandler.cs b/Demo_Source_Code/CSharpDemo/FileProtector/MessageHandler.cs new file mode 100644 index 0000000..683536a --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FileProtector/MessageHandler.cs @@ -0,0 +1,407 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; +using System.Runtime.InteropServices; +using System.Security.Principal; +using System.IO; +using System.Threading; +using System.Reflection; + +using EaseFilter.FilterControl; +using EaseFilter.CommonObjects; + + +namespace FileProtector +{ + + public class MessageHandler : IDisposable + { + + FastListView listView_Message = null; + Thread messageThread = null; + Queue messageQueue = new Queue(); + + AutoResetEvent autoEvent = new AutoResetEvent(false); + bool disposed = false; + + public MessageHandler(FastListView lvMessage) + { + this.listView_Message = lvMessage; + InitListView(); + messageThread = new Thread(new ThreadStart(ProcessMessage)); + messageThread.Name = "ProcessMessage"; + messageThread.Start(); + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + private void Dispose(bool disposing) + { + if (!this.disposed) + { + } + + autoEvent.Set(); + messageThread.Abort(); + disposed = true; + } + + ~MessageHandler() + { + Dispose(false); + } + + public void InitListView() + { + messageQueue.Clear(); + //init ListView control + listView_Message.Clear(); //clear control + //create column header for ListView + listView_Message.Columns.Add("MessageId#", 40, System.Windows.Forms.HorizontalAlignment.Left); + listView_Message.Columns.Add("Time", 120, System.Windows.Forms.HorizontalAlignment.Left); + listView_Message.Columns.Add("UserName", 150, System.Windows.Forms.HorizontalAlignment.Left); + listView_Message.Columns.Add("ProcessName(PID)", 100, System.Windows.Forms.HorizontalAlignment.Left); + listView_Message.Columns.Add("ThreadId", 60, System.Windows.Forms.HorizontalAlignment.Left); + listView_Message.Columns.Add("I/O Name", 160, System.Windows.Forms.HorizontalAlignment.Left); + listView_Message.Columns.Add("FileObject", 100, System.Windows.Forms.HorizontalAlignment.Left); + listView_Message.Columns.Add("FileName", 350, System.Windows.Forms.HorizontalAlignment.Left); + listView_Message.Columns.Add("FileSize", 70, System.Windows.Forms.HorizontalAlignment.Left); + listView_Message.Columns.Add("FileAttributes", 70, System.Windows.Forms.HorizontalAlignment.Left); + listView_Message.Columns.Add("LastWriteTime", 120, System.Windows.Forms.HorizontalAlignment.Left); + listView_Message.Columns.Add("Return Status", 100, System.Windows.Forms.HorizontalAlignment.Left); + listView_Message.Columns.Add("Description", 500, System.Windows.Forms.HorizontalAlignment.Left); + } + + public void DisplayEventMessage(FileIOEventArgs fileIOEventArgs) + { + if (GlobalConfig.OutputMessageToConsole) + { + lock (messageQueue) + { + if (messageQueue.Count > GlobalConfig.MaximumFilterMessages) + { + messageQueue.Clear(); + } + + messageQueue.Enqueue(fileIOEventArgs); + } + + autoEvent.Set(); + } + + } + + + void ProcessMessage() + { + int waitTimeout = 2000; //2seconds + List itemList = new List(); + + WaitHandle[] waitHandles = new WaitHandle[] { autoEvent, GlobalConfig.stopEvent }; + + while (GlobalConfig.isRunning) + { + try + { + if (messageQueue.Count == 0) + { + int result = WaitHandle.WaitAny(waitHandles, waitTimeout); + if (!GlobalConfig.isRunning) + { + return; + } + } + + System.Diagnostics.Stopwatch stopWatch = new System.Diagnostics.Stopwatch(); + stopWatch.Start(); + + while (messageQueue.Count > 0) + { + FileIOEventArgs fileIOEventArgs = null; + + lock (messageQueue) + { + fileIOEventArgs = (FileIOEventArgs)messageQueue.Dequeue(); + } + + if (GlobalConfig.DisableDirIO && (fileIOEventArgs.FileAttributes & (uint)FileAttributes.Directory) == (uint)FileAttributes.Directory) + { + //don't display the directory IO + continue; + } + + string[] filterMessages = new string[0]; + ListViewItem lvItem = GetFilterMessage(fileIOEventArgs, ref filterMessages); + + if (null == lvItem) + { + //no display message. + continue; + } + + if (GlobalConfig.EnableLogTransaction) + { + LogTrasaction(filterMessages); + } + + if (GlobalConfig.OutputMessageToConsole) + { + itemList.Add(lvItem); + + if (itemList.Count > GlobalConfig.MaximumFilterMessages) + { + AddItemToList(itemList); + itemList.Clear(); + + Thread.Sleep(1000); + } + } + + } + + if (itemList.Count > 0) + { + AddItemToList(itemList); + itemList.Clear(); + } + + } + catch (Exception ex) + { + EventManager.WriteMessage(190, "ProcessMessage", EventLevel.Error, "Process message exception:" + ex.Message); + } + } + + + } + + public void LoadMessageFromLogToConsole() + { + if (listView_Message == null) + { + return; + } + + try + { + Assembly assembly = System.Reflection.Assembly.GetEntryAssembly(); + string assemblyPath = Path.GetDirectoryName(assembly.Location); + + string filterMessageLogName = GlobalConfig.FilterMessageLogName; + string logFileName = Path.Combine(assemblyPath, filterMessageLogName); + + if (!File.Exists(logFileName)) + { + return; + } + + string[] logMessage = File.ReadAllLines(logFileName); + List itemList = new List(); + + foreach (string itemStr in logMessage) + { + if (itemStr.Trim().Length > 0) + { + string[] listData = itemStr.Split(new char[] { '|' }); + if (listData.Length >= listView_Message.Columns.Count) + { + ListViewItem lvItem = new ListViewItem(listData, 0); + + uint status = 0; + string statusStr = listData[listView_Message.Columns.Count - 2]; + int index1 = statusStr.IndexOf('('); + int index2 = statusStr.IndexOf(')'); + + if (index1 >= 0 && index2 > 2) + { + statusStr = statusStr.Substring(index1 + 3, index2 - index1 - 3); + uint.TryParse(statusStr, System.Globalization.NumberStyles.HexNumber, null, out status); + + if (status >= (uint)NtStatus.Status.Error) + { + lvItem.BackColor = Color.LightGray; + lvItem.ForeColor = Color.Red; + } + else if (status > (uint)NtStatus.Status.Warning) + { + lvItem.BackColor = Color.LightGray; + lvItem.ForeColor = Color.Yellow; + } + } + + itemList.Add(lvItem); + } + } + } + + if (itemList.Count > 0) + { + listView_Message.Items.Clear(); + AddItemToList(itemList); + } + + } + catch (Exception ex) + { + EventManager.WriteMessage(265, "LoadLogMessage", EventLevel.Error, "Load log message failed with error " + ex.Message); + } + } + + public static void LogTrasaction(string[] filterMessages) + { + try + { + Assembly assembly = System.Reflection.Assembly.GetEntryAssembly(); + string assemblyPath = Path.GetDirectoryName(assembly.Location); + + string filterMessageLogName = GlobalConfig.FilterMessageLogName; + + string logFileName = Path.Combine(assemblyPath, filterMessageLogName); + string logFolder = Path.GetDirectoryName(logFileName); + + if (!Directory.Exists(logFolder)) + { + Directory.CreateDirectory(logFolder); + } + + string logMessage = string.Empty; + + for (int i = 0; i < filterMessages.Length; i++) + { + logMessage += filterMessages[i].Trim() + "|"; + } + + if (logMessage.Length > 0) + { + File.AppendAllText(logFileName, logMessage + "\r\n"); + + FileInfo fileInfo = new FileInfo(logFileName); + + if (fileInfo.Length > GlobalConfig.FilterMessageLogFileSize) + { + File.Delete(logFileName + ".bak"); + File.Move(logFileName, logFileName + ".bak"); + } + } + } + catch (Exception ex) + { + EventManager.WriteMessage(172, "LogTrasaction", EventLevel.Error, "Log filter message failed with error " + ex.Message); + } + + } + + void AddItemToList(List itemList) + { + if (itemList.Count < 1) + { + return; + } + + if (listView_Message.InvokeRequired) + { + listView_Message.Invoke(new MethodInvoker(delegate { AddItemToList(itemList); })); + } + else + { + + while (listView_Message.Items.Count > 0 && listView_Message.Items.Count + itemList.Count > GlobalConfig.MaximumFilterMessages) + { + //the message records in the list view reached to the maximum value, remove the first one till the record less than the maximum value. + listView_Message.Items.RemoveAt(0); + } + + + if (itemList.Count > 0) + { + listView_Message.Items.AddRange(itemList.ToArray()); + // listView_Message.EnsureVisible(listView_Message.Items.Count - 1); + + itemList.Clear(); + + } + } + } + + ListViewItem GetFilterMessage(FileIOEventArgs fileIOEventArgs, ref string[] filterMessages) + { + ListViewItem lvItem = new ListViewItem(); + + try + { + string[] listData = new string[listView_Message.Columns.Count]; + int col = 0; + listData[col++] = fileIOEventArgs.MessageId.ToString(); + listData[col++] = DateTime.FromFileTime(fileIOEventArgs.TransactionTime).ToString("yyyy-MM-ddTHH:mm"); + if (fileIOEventArgs.IsRemoteAccess) + { + listData[col++] = fileIOEventArgs.UserName + " IsRemoteAccess " + fileIOEventArgs.RemoteIp; ; + } + else + { + listData[col++] = fileIOEventArgs.UserName; + } + listData[col++] = fileIOEventArgs.ProcessName + " (" + fileIOEventArgs.ProcessId + ")"; + listData[col++] = fileIOEventArgs.ThreadId.ToString(); + listData[col++] = fileIOEventArgs.EventName; + listData[col++] = fileIOEventArgs.FileObject.ToString("X"); + listData[col++] = fileIOEventArgs.FileName; + listData[col++] = fileIOEventArgs.FileSize.ToString(); + listData[col++] = ((FileAttributes)fileIOEventArgs.FileAttributes).ToString(); + listData[col++] = DateTime.FromFileTime(fileIOEventArgs.LastWriteTime).ToString("yyyy-MM-ddTHH:mm"); + listData[col++] = fileIOEventArgs.IOStatusToString(); + listData[col++] = fileIOEventArgs.Description; + + filterMessages = listData; + + lvItem = new ListViewItem(listData, 0); + + if ((uint)fileIOEventArgs.IoStatus >= (uint)NtStatus.Status.Error) + { + lvItem.BackColor = Color.LightGray; + lvItem.ForeColor = Color.Red; + } + else if ((uint)fileIOEventArgs.IoStatus > (uint)NtStatus.Status.Warning) + { + lvItem.BackColor = Color.LightGray; + lvItem.ForeColor = Color.Yellow; + } + + + } + catch (Exception ex) + { + EventManager.WriteMessage(445, "GetFilterMessage", EventLevel.Error, "Add callback message failed." + ex.Message); + lvItem = null; + } + + return lvItem; + } + + } +} diff --git a/Demo_Source_Code/CSharpDemo/FileProtector/MonitorEventHandler.cs b/Demo_Source_Code/CSharpDemo/FileProtector/MonitorEventHandler.cs new file mode 100644 index 0000000..8e82726 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FileProtector/MonitorEventHandler.cs @@ -0,0 +1,286 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; +using System.Runtime.InteropServices; +using System.Security.Principal; +using System.IO; +using System.Threading; +using System.Reflection; + +using EaseFilter.FilterControl; +using EaseFilter.CommonObjects; + +namespace FileProtector +{ + + public class MonitorEventHandler : IDisposable + { + MessageHandler messageHandler = null; + bool disposed = false; + + public MonitorEventHandler(MessageHandler _messageHandler) + { + this.messageHandler = _messageHandler; + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + private void Dispose(bool disposing) + { + if (!this.disposed) + { + } + + disposed = true; + } + + ~MonitorEventHandler() + { + Dispose(false); + } + + private void DisplayEventMessage(FileIOEventArgs fileIOEventArgs) + { + if (null != messageHandler) + { + messageHandler.DisplayEventMessage(fileIOEventArgs); + } + + } + + + /// + /// Fires this event after the file was opened, the handle is not closed. + /// + public void OnFileOpen(object sender, FileCreateEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + + /// + /// Fires this event after the new file was created, the handle is not closed. + /// + public void OnNewFileCreate(object sender, FileCreateEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + /// + /// Fires this event after the read IO was returned. + /// + public void OnFileRead(object sender, FileReadEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + /// + /// Fires this event after the write IO was returned. + /// + public void OnFileWrite(object sender, FileWriteEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + /// + /// Fires this event after the query file size IO was returned. + /// + public void OnQueryFileSize(object sender, FileSizeEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + /// + /// Fires this event after the query file basic information IO was returned. + /// + public void OnQueryFileBasicInfo(object sender, FileBasicInfoEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + /// + /// Fires this event after the query file standard information IO was returned. + /// + public void OnQueryFileStandardInfo(object sender, FileStandardInfoEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + /// + /// Fires this event after the query file network information IO was returned. + /// + public void OnQueryFileNetworkInfo(object sender, FileNetworkInfoEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + /// + /// Fires this event after the query file Id IO was returned. + /// + public void OnQueryFileId(object sender, FileIdEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + /// + /// Fires this event after the query file info IO was returned. + /// + /// + /// + public void OnQueryFileInfo(object sender, FileInfoArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + /// + /// Fires this event after the set file size IO was returned. + /// + public void OnSetFileSize(object sender, FileSizeEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + /// + /// Fires this event after the set file basic information was returned. + /// + public void OnSetFileBasicInfo(object sender, FileBasicInfoEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + /// + /// Fires this event after the set file standard information IO was returned. + /// + public void OnSetFileStandardInfo(object sender, FileStandardInfoEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + /// + /// Fires this event after the set file network information IO was returned. + /// + public void OnSetFileNetworkInfo(object sender, FileNetworkInfoEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + /// + /// Fires this event after the file was moved or renamed. + /// + public void OnMoveOrRenameFile(object sender, FileMoveOrRenameEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + /// + /// Fires this event after the delete IO was returned. + /// + public void OnDeleteFile(object sender, FileIOEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + /// + /// Fires this event after the set file info IO was returned. + /// + /// + /// + public void OnSetFileInfo(object sender, FileInfoArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + /// + /// Fires this event after the query file security IO was returned. + /// + public void OnQueryFileSecurity(object sender, FileSecurityEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + /// + /// Fires this event after the set file security IO was returned. + /// + public void OnSetFileSecurity(object sender, FileSecurityEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + /// + /// Fires this event after the directory enumeration query IO was returned. + /// + public void OnQueryDirectoryFile(object sender, FileQueryDirectoryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + /// + /// Fires this event after the file was cleanuped. + /// + public void OnFileHandleClose(object sender, FileIOEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + /// + /// Fires this event after the last file handle of the file was closed. + /// + public void OnFileClose(object sender, FileIOEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + + /// + /// Fires this event when a file was changed after the file handle closed + /// + public void NotifyFileWasChanged(object sender, FileChangedEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + + /// + /// Fires this event when the filter driver attached to a volume. + /// + public void OnFilterAttachToVolume(object sender, VolumeInfoEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + /// + /// Fires this event when a volume was detached from the filter driver. + /// + public void OnFilterDetachFromVolume(object sender, VolumeInfoEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + + } +} \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/FileProtector/ProcessEventHandler.cs b/Demo_Source_Code/CSharpDemo/FileProtector/ProcessEventHandler.cs new file mode 100644 index 0000000..eb1d9a4 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FileProtector/ProcessEventHandler.cs @@ -0,0 +1,168 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.IO; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Drawing; +using System.Windows.Forms; +using System.Runtime.InteropServices; +using Microsoft.Win32.SafeHandles; +using System.Security.Principal; +using System.Threading; +using System.Reflection; + +using EaseFilter.FilterControl; +using EaseFilter.CommonObjects; + +namespace FileProtector +{ + + public class ProcessEventHandler : IDisposable + { + MessageHandler messageHandler = null; + bool disposed = false; + + + public ProcessEventHandler(MessageHandler _messageHandler) + { + this.messageHandler = _messageHandler; + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + private void Dispose(bool disposing) + { + if (!this.disposed) + { + } + + disposed = true; + } + + ~ProcessEventHandler() + { + Dispose(false); + } + + private void DisplayEventMessage(FileIOEventArgs fileIOEventArgs) + { + if (null != messageHandler) + { + messageHandler.DisplayEventMessage(fileIOEventArgs); + } + + } + + + /// + /// Fires this event when the new process was being created. + /// + public void OnProcessCreation(object sender, ProcessEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + // //test block the process creation. + // e.ReturnStatus = NtStatus.Status.AccessDenied; + } + + /// + /// Fires this event before the processs was terminiated. + /// + public void OnProcessPreTermination(object sender, ProcessEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + //test block the process terminiation. + //if (e.ImageFileName.IndexOf("cmd.exe") >= 0) + //{ + // e.ReturnStatus = NtStatus.Status.AccessDenied; + //} + } + + /// + /// Fires this event when the process creation was blocked by the setting, + /// if the control flag 'ENABLE_SEND_PROCESS_DENIED_EVENT' was set. + /// + public void NotifyProcessWasBlocked(object sender, ProcessEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + } + + /// + /// Fires this event after the event was triggered. + /// + public void NotifyProcessTerminated(object sender, ProcessEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + } + + /// + /// Fires this event after the event was triggered. + /// + public void NotifyThreadCreation(object sender, ProcessEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + } + + /// + /// Fires this event after the event was triggered. + /// + public void NotifyThreadTerminated(object sender, ProcessEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + } + + /// + /// Fires this event after the event was triggered. + /// + public void NotifyProcessHandleInfo(object sender, ProcessEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + } + + /// + /// Fires this event after the event was triggered. + /// + public void NotifyThreadHandleInfo(object sender, ProcessEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + } + + } +} + diff --git a/Demo_Source_Code/CSharpDemo/FileProtector/Program.cs b/Demo_Source_Code/CSharpDemo/FileProtector/Program.cs new file mode 100644 index 0000000..6c5b281 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FileProtector/Program.cs @@ -0,0 +1,73 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Windows.Forms; + +using EaseFilter.FilterControl; + +namespace FileProtector +{ + static class Program + { + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main(string[] args) + { + + if (args.Length > 0) + { + string command = args[0]; + switch (command.ToLower()) + { + case "-installdriver": + { + bool ret = FilterAPI.InstallDriver(); + if (!ret) + { + Console.WriteLine("Install driver failed:" + FilterAPI.GetLastErrorMessage()); + } + + break; + } + + case "-uninstalldriver": + { + bool ret = FilterAPI.UnInstallDriver(); + if (!ret) + { + Console.WriteLine("UnInstall driver failed:" + FilterAPI.GetLastErrorMessage()); + } + + break; + } + } + } + else + { + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + Application.Run(new ProtectorForm()); + } + + } + } +} diff --git a/Demo_Source_Code/CSharpDemo/FileProtector/Properties/AssemblyInfo.cs b/Demo_Source_Code/CSharpDemo/FileProtector/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..a8f364b --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FileProtector/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("FileProtector")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("EaseFilter Technologies")] +[assembly: AssemblyProduct("FileProtector")] +[assembly: AssemblyCopyright("Copyright © 2017 EaseFilter Technologies")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("b8ffbab5-e350-4cf3-9015-a8ff4325ddeb")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +[assembly: AssemblyVersion("5.2.4.1001")] +//[assembly: AssemblyFileVersion("1.0.0.0")] + diff --git a/Demo_Source_Code/CSharpDemo/FileProtector/Properties/Resources.Designer.cs b/Demo_Source_Code/CSharpDemo/FileProtector/Properties/Resources.Designer.cs new file mode 100644 index 0000000..1a3581b --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FileProtector/Properties/Resources.Designer.cs @@ -0,0 +1,63 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace FileProtector.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // 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", "16.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + 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() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [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("FileProtector.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + } +} diff --git a/Demo_Source_Code/CSharpDemo/FileProtector/Properties/Resources.resx b/Demo_Source_Code/CSharpDemo/FileProtector/Properties/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FileProtector/Properties/Resources.resx @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/FileProtector/Properties/Settings.Designer.cs b/Demo_Source_Code/CSharpDemo/FileProtector/Properties/Settings.Designer.cs new file mode 100644 index 0000000..8f518ff --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FileProtector/Properties/Settings.Designer.cs @@ -0,0 +1,26 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace FileProtector.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.10.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default { + get { + return defaultInstance; + } + } + } +} diff --git a/Demo_Source_Code/CSharpDemo/FileProtector/Properties/Settings.settings b/Demo_Source_Code/CSharpDemo/FileProtector/Properties/Settings.settings new file mode 100644 index 0000000..3964565 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FileProtector/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + diff --git a/Demo_Source_Code/CSharpDemo/FileProtector/ProtectorForm.Designer.cs b/Demo_Source_Code/CSharpDemo/FileProtector/ProtectorForm.Designer.cs new file mode 100644 index 0000000..c848de0 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FileProtector/ProtectorForm.Designer.cs @@ -0,0 +1,330 @@ +using System; +using System.Windows.Forms; +using System.IO; +using System.Threading; +using System.Runtime.InteropServices; + +using EaseFilter.CommonObjects; + +namespace FileProtector +{ + public class FastListView : ListView + { + [StructLayout(LayoutKind.Sequential)] + private struct NMHDR + { + public IntPtr hwndFrom; + public uint idFrom; + public uint code; + } + + private const uint NM_CUSTOMDRAW = unchecked((uint)-12); + + protected override void WndProc(ref Message m) + { + if (m.Msg == 0x204E) + { + NMHDR hdr = (NMHDR)m.GetLParam(typeof(NMHDR)); + if (hdr.code == NM_CUSTOMDRAW) + { + m.Result = (IntPtr)0; + return; + } + } + + base.WndProc(ref m); + } + } + + partial class ProtectorForm + { + [DllImport("user32")] + private static extern bool SendMessage(IntPtr hwnd, uint msg, IntPtr wParam, IntPtr lParam); + private uint LVM_SETTEXTBKCOLOR = 0x1026; + + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ProtectorForm)); + this.menuStrip1 = new System.Windows.Forms.MenuStrip(); + this.optionsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.encryptFileWithToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.decryptFileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.decryptFileWithOffsetToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.getEncryptedFileIVTagToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.exitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStrip1 = new System.Windows.Forms.ToolStrip(); + this.toolStripButton_StartFilter = new System.Windows.Forms.ToolStripButton(); + this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); + this.toolStripButton_Stop = new System.Windows.Forms.ToolStripButton(); + this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator(); + this.toolStripButton_ClearMessage = new System.Windows.Forms.ToolStripButton(); + this.toolStripSeparator3 = new System.Windows.Forms.ToolStripSeparator(); + this.toolStripButton_LoadMessage = new System.Windows.Forms.ToolStripButton(); + this.toolStripSeparator4 = new System.Windows.Forms.ToolStripSeparator(); + this.toolStripButton1 = new System.Windows.Forms.ToolStripButton(); + this.toolStripButton_UnitTest = new System.Windows.Forms.ToolStripButton(); + this.toolStripButton_Help = new System.Windows.Forms.ToolStripButton(); + this.listView_Info = new FileProtector.FastListView(); + this.toolStripButton_ApplyTrialKey = new System.Windows.Forms.ToolStripButton(); + this.menuStrip1.SuspendLayout(); + this.toolStrip1.SuspendLayout(); + this.SuspendLayout(); + // + // menuStrip1 + // + this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.optionsToolStripMenuItem, + this.toolsToolStripMenuItem, + this.exitToolStripMenuItem}); + this.menuStrip1.Location = new System.Drawing.Point(0, 0); + this.menuStrip1.Name = "menuStrip1"; + this.menuStrip1.Size = new System.Drawing.Size(974, 24); + this.menuStrip1.TabIndex = 0; + this.menuStrip1.Text = "menuStrip1"; + // + // optionsToolStripMenuItem + // + this.optionsToolStripMenuItem.Name = "optionsToolStripMenuItem"; + this.optionsToolStripMenuItem.Size = new System.Drawing.Size(61, 20); + this.optionsToolStripMenuItem.Text = "Settings"; + this.optionsToolStripMenuItem.Click += new System.EventHandler(this.settingsToolStripMenuItem_Click); + // + // toolsToolStripMenuItem + // + this.toolsToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.encryptFileWithToolStripMenuItem, + this.decryptFileToolStripMenuItem, + this.decryptFileWithOffsetToolStripMenuItem, + this.getEncryptedFileIVTagToolStripMenuItem}); + this.toolsToolStripMenuItem.Name = "toolsToolStripMenuItem"; + this.toolsToolStripMenuItem.Size = new System.Drawing.Size(47, 20); + this.toolsToolStripMenuItem.Text = "Tools"; + // + // encryptFileWithToolStripMenuItem + // + this.encryptFileWithToolStripMenuItem.Name = "encryptFileWithToolStripMenuItem"; + this.encryptFileWithToolStripMenuItem.Size = new System.Drawing.Size(223, 22); + this.encryptFileWithToolStripMenuItem.Text = "Encrypt file with API"; + this.encryptFileWithToolStripMenuItem.Click += new System.EventHandler(this.encryptFileWithToolStripMenuItem_Click); + // + // decryptFileToolStripMenuItem + // + this.decryptFileToolStripMenuItem.Name = "decryptFileToolStripMenuItem"; + this.decryptFileToolStripMenuItem.Size = new System.Drawing.Size(223, 22); + this.decryptFileToolStripMenuItem.Text = "Decrypt file with API"; + this.decryptFileToolStripMenuItem.Click += new System.EventHandler(this.decryptFileToolStripMenuItem_Click); + // + // decryptFileWithOffsetToolStripMenuItem + // + this.decryptFileWithOffsetToolStripMenuItem.Name = "decryptFileWithOffsetToolStripMenuItem"; + this.decryptFileWithOffsetToolStripMenuItem.Size = new System.Drawing.Size(223, 22); + this.decryptFileWithOffsetToolStripMenuItem.Text = "Decrypt file with offset"; + this.decryptFileWithOffsetToolStripMenuItem.Click += new System.EventHandler(this.decryptFileWithOffsetToolStripMenuItem_Click); + // + // getEncryptedFileIVTagToolStripMenuItem + // + this.getEncryptedFileIVTagToolStripMenuItem.Name = "getEncryptedFileIVTagToolStripMenuItem"; + this.getEncryptedFileIVTagToolStripMenuItem.Size = new System.Drawing.Size(223, 22); + this.getEncryptedFileIVTagToolStripMenuItem.Text = "Check Encrypt File Tag Data "; + this.getEncryptedFileIVTagToolStripMenuItem.Click += new System.EventHandler(this.getEncryptedFileTagdataToolStripMenuItem_Click); + // + // exitToolStripMenuItem + // + this.exitToolStripMenuItem.Name = "exitToolStripMenuItem"; + this.exitToolStripMenuItem.Size = new System.Drawing.Size(37, 20); + this.exitToolStripMenuItem.Text = "Exit"; + this.exitToolStripMenuItem.Click += new System.EventHandler(this.exitToolStripMenuItem_Click); + // + // toolStrip1 + // + this.toolStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.toolStripButton_StartFilter, + this.toolStripSeparator1, + this.toolStripButton_Stop, + this.toolStripSeparator2, + this.toolStripButton_ClearMessage, + this.toolStripSeparator3, + this.toolStripButton_LoadMessage, + this.toolStripSeparator4, + this.toolStripButton1, + this.toolStripButton_UnitTest, + this.toolStripButton_Help, + this.toolStripButton_ApplyTrialKey}); + this.toolStrip1.Location = new System.Drawing.Point(0, 24); + this.toolStrip1.Name = "toolStrip1"; + this.toolStrip1.Size = new System.Drawing.Size(974, 25); + this.toolStrip1.TabIndex = 1; + this.toolStrip1.Text = "toolStrip1"; + // + // toolStripButton_StartFilter + // + this.toolStripButton_StartFilter.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton_StartFilter.Image"))); + this.toolStripButton_StartFilter.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButton_StartFilter.Name = "toolStripButton_StartFilter"; + this.toolStripButton_StartFilter.Size = new System.Drawing.Size(103, 22); + this.toolStripButton_StartFilter.Text = "Start protector"; + this.toolStripButton_StartFilter.Click += new System.EventHandler(this.toolStripButton_StartFilter_Click); + // + // toolStripSeparator1 + // + this.toolStripSeparator1.Name = "toolStripSeparator1"; + this.toolStripSeparator1.Size = new System.Drawing.Size(6, 25); + // + // toolStripButton_Stop + // + this.toolStripButton_Stop.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton_Stop.Image"))); + this.toolStripButton_Stop.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButton_Stop.Name = "toolStripButton_Stop"; + this.toolStripButton_Stop.Size = new System.Drawing.Size(103, 22); + this.toolStripButton_Stop.Text = "Stop protector"; + this.toolStripButton_Stop.Click += new System.EventHandler(this.toolStripButton_Stop_Click); + // + // toolStripSeparator2 + // + this.toolStripSeparator2.Name = "toolStripSeparator2"; + this.toolStripSeparator2.Size = new System.Drawing.Size(6, 25); + // + // toolStripButton_ClearMessage + // + this.toolStripButton_ClearMessage.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton_ClearMessage.Image"))); + this.toolStripButton_ClearMessage.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButton_ClearMessage.Name = "toolStripButton_ClearMessage"; + this.toolStripButton_ClearMessage.Size = new System.Drawing.Size(108, 22); + this.toolStripButton_ClearMessage.Text = "Clear messages"; + this.toolStripButton_ClearMessage.Click += new System.EventHandler(this.toolStripButton_ClearMessage_Click); + // + // toolStripSeparator3 + // + this.toolStripSeparator3.Name = "toolStripSeparator3"; + this.toolStripSeparator3.Size = new System.Drawing.Size(6, 25); + // + // toolStripButton_LoadMessage + // + this.toolStripButton_LoadMessage.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton_LoadMessage.Image"))); + this.toolStripButton_LoadMessage.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButton_LoadMessage.Name = "toolStripButton_LoadMessage"; + this.toolStripButton_LoadMessage.Size = new System.Drawing.Size(107, 22); + this.toolStripButton_LoadMessage.Text = "Load messages"; + this.toolStripButton_LoadMessage.Click += new System.EventHandler(this.toolStripButton_LoadMessage_Click); + // + // toolStripSeparator4 + // + this.toolStripSeparator4.Name = "toolStripSeparator4"; + this.toolStripSeparator4.Size = new System.Drawing.Size(6, 25); + // + // toolStripButton1 + // + this.toolStripButton1.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton1.Image"))); + this.toolStripButton1.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButton1.Name = "toolStripButton1"; + this.toolStripButton1.Size = new System.Drawing.Size(93, 22); + this.toolStripButton1.Text = "Event viewer"; + this.toolStripButton1.Click += new System.EventHandler(this.toolStripDisplayEvent_Click); + // + // toolStripButton_UnitTest + // + this.toolStripButton_UnitTest.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton_UnitTest.Image"))); + this.toolStripButton_UnitTest.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButton_UnitTest.Name = "toolStripButton_UnitTest"; + this.toolStripButton_UnitTest.Size = new System.Drawing.Size(125, 22); + this.toolStripButton_UnitTest.Text = "Protector Unit Test"; + this.toolStripButton_UnitTest.Click += new System.EventHandler(this.toolStripButton_UnitTest_Click); + // + // toolStripButton_Help + // + this.toolStripButton_Help.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton_Help.Image"))); + this.toolStripButton_Help.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButton_Help.Name = "toolStripButton_Help"; + this.toolStripButton_Help.Size = new System.Drawing.Size(52, 22); + this.toolStripButton_Help.Text = "Help"; + this.toolStripButton_Help.Click += new System.EventHandler(this.toolStripButton_Help_Click); + // + // listView_Info + // + this.listView_Info.Dock = System.Windows.Forms.DockStyle.Fill; + this.listView_Info.FullRowSelect = true; + this.listView_Info.HoverSelection = true; + this.listView_Info.LabelEdit = true; + this.listView_Info.Location = new System.Drawing.Point(0, 49); + this.listView_Info.Name = "listView_Info"; + this.listView_Info.ShowItemToolTips = true; + this.listView_Info.Size = new System.Drawing.Size(974, 457); + this.listView_Info.TabIndex = 2; + this.listView_Info.UseCompatibleStateImageBehavior = false; + this.listView_Info.View = System.Windows.Forms.View.Details; + + // + // ProtectorForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(974, 506); + this.Controls.Add(this.listView_Info); + this.Controls.Add(this.toolStrip1); + this.Controls.Add(this.menuStrip1); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.MainMenuStrip = this.menuStrip1; + this.Name = "ProtectorForm"; + this.Text = "EaseFilter File Protector"; + this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.ProtectorForm_FormClosed); + this.menuStrip1.ResumeLayout(false); + this.menuStrip1.PerformLayout(); + this.toolStrip1.ResumeLayout(false); + this.toolStrip1.PerformLayout(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.MenuStrip menuStrip1; + private System.Windows.Forms.ToolStrip toolStrip1; + private System.Windows.Forms.ToolStripButton toolStripButton_StartFilter; + private System.Windows.Forms.ToolStripButton toolStripButton_Stop; + private System.Windows.Forms.ToolStripButton toolStripButton_ClearMessage; + private FastListView listView_Info; + private System.Windows.Forms.ToolStripMenuItem optionsToolStripMenuItem; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator1; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator2; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator3; + private System.Windows.Forms.ToolStripButton toolStripButton1; + private System.Windows.Forms.ToolStripMenuItem toolsToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem encryptFileWithToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem decryptFileToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem getEncryptedFileIVTagToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem exitToolStripMenuItem; + private System.Windows.Forms.ToolStripButton toolStripButton_LoadMessage; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator4; + private System.Windows.Forms.ToolStripButton toolStripButton_UnitTest; + private System.Windows.Forms.ToolStripButton toolStripButton_Help; + private ToolStripMenuItem decryptFileWithOffsetToolStripMenuItem; + private ToolStripButton toolStripButton_ApplyTrialKey; + } +} + diff --git a/Demo_Source_Code/CSharpDemo/FileProtector/ProtectorForm.cs b/Demo_Source_Code/CSharpDemo/FileProtector/ProtectorForm.cs new file mode 100644 index 0000000..4914c48 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FileProtector/ProtectorForm.cs @@ -0,0 +1,382 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.IO; +using System.Reflection; +using System.Windows.Forms; +using System.Diagnostics; +using System.Runtime.InteropServices; + +using EaseFilter.CommonObjects; +using EaseFilter.FilterControl; + +namespace FileProtector +{ + public partial class ProtectorForm : Form + { + MessageHandler messageHandler = null; + MonitorEventHandler monitorEventHandler = null; + ControlEventHandler controlEventHandler = null; + ProcessEventHandler processEventHandler = null; + EncryptEventHandler encryptEventHandler = new EncryptEventHandler(); + + FilterControl filterControl = new FilterControl(); + + public ProtectorForm() + { + GlobalConfig.filterType = FilterAPI.FilterType.MONITOR_FILTER | FilterAPI.FilterType.CONTROL_FILTER | FilterAPI.FilterType.ENCRYPTION_FILTER + | FilterAPI.FilterType.PROCESS_FILTER | FilterAPI.FilterType.REGISTRY_FILTER; + + InitializeComponent(); + + messageHandler = new MessageHandler(listView_Info); + monitorEventHandler = new MonitorEventHandler(messageHandler); + controlEventHandler = new ControlEventHandler(messageHandler); + processEventHandler = new ProcessEventHandler(messageHandler); + + StartPosition = FormStartPosition.CenterScreen; + + this.Text += GlobalConfig.GetVersionInfo(); + + this.Load += new EventHandler(Form1_Load); + + } + + void Form1_Load(object sender, EventArgs e) + { + //to improve the listview performance + SendMessage(listView_Info.Handle, LVM_SETTEXTBKCOLOR, IntPtr.Zero, unchecked((IntPtr)(int)0xFFFFFF)); + } + + ~ProtectorForm() + { + GlobalConfig.Stop(); + } + + void SendSettingsToFilter() + { + filterControl.ClearFilters(); + + GlobalConfig.Load(); + + if (GlobalConfig.FilterRules.Count == 0) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("You don't have any filter folder setup, please go to the settings to add a new filter rule, or the filter driver won't intercept any IOs."); + } + + foreach (FileFilterRule filterRule in GlobalConfig.FilterRules.Values) + { + FileFilter fileFilter = filterRule.ToFileFilter(); + + //add the monitor event handler for the file filter. + fileFilter.OnFileOpen += monitorEventHandler.OnFileOpen; + fileFilter.OnNewFileCreate += monitorEventHandler.OnNewFileCreate; + fileFilter.OnDeleteFile += monitorEventHandler.OnDeleteFile; + fileFilter.OnFileRead += monitorEventHandler.OnFileRead; + fileFilter.OnFileWrite += monitorEventHandler.OnFileWrite; + fileFilter.OnQueryFileBasicInfo += monitorEventHandler.OnQueryFileBasicInfo; + fileFilter.OnQueryFileId += monitorEventHandler.OnQueryFileId; + fileFilter.OnQueryFileNetworkInfo += monitorEventHandler.OnQueryFileNetworkInfo; + fileFilter.OnQueryFileSize += monitorEventHandler.OnQueryFileSize; + fileFilter.OnQueryFileStandardInfo += monitorEventHandler.OnQueryFileStandardInfo; + fileFilter.OnQueryFileInfo += monitorEventHandler.OnQueryFileInfo; + fileFilter.OnSetFileBasicInfo += monitorEventHandler.OnSetFileBasicInfo; + fileFilter.OnSetFileNetworkInfo += monitorEventHandler.OnSetFileNetworkInfo; + fileFilter.OnSetFileSize += monitorEventHandler.OnSetFileSize; + fileFilter.OnSetFileStandardInfo += monitorEventHandler.OnSetFileStandardInfo; + fileFilter.OnMoveOrRenameFile += monitorEventHandler.OnMoveOrRenameFile; + fileFilter.OnSetFileInfo += monitorEventHandler.OnSetFileInfo; + fileFilter.OnQueryFileSecurity += monitorEventHandler.OnQueryFileSecurity; + fileFilter.OnQueryDirectoryFile += monitorEventHandler.OnQueryDirectoryFile; + fileFilter.OnFileHandleClose += monitorEventHandler.OnFileHandleClose; + fileFilter.OnFileClose += monitorEventHandler.OnFileClose; + + fileFilter.NotifyFileWasChanged += monitorEventHandler.NotifyFileWasChanged; + + //add the control pre-event handler for the control file filter. + fileFilter.OnPreCreateFile += controlEventHandler.OnPreCreateFile; + fileFilter.OnPreDeleteFile += controlEventHandler.OnPreDeleteFile; + fileFilter.OnPreFileRead += controlEventHandler.OnPreFileRead; + fileFilter.OnPreFileWrite += controlEventHandler.OnPreFileWrite; + fileFilter.OnPreQueryFileBasicInfo += controlEventHandler.OnPreQueryFileBasicInfo; + fileFilter.OnPreQueryFileId += controlEventHandler.OnPreQueryFileId; + fileFilter.OnPreQueryFileNetworkInfo += controlEventHandler.OnPreQueryFileNetworkInfo; + fileFilter.OnPreQueryFileSize += controlEventHandler.OnPreQueryFileSize; + fileFilter.OnPreQueryFileStandardInfo += controlEventHandler.OnPreQueryFileStandardInfo; + fileFilter.OnPreQueryFileInfo += controlEventHandler.OnPreQueryFileInfo; + fileFilter.OnPreSetFileBasicInfo += controlEventHandler.OnPreSetFileBasicInfo; + fileFilter.OnPreSetFileNetworkInfo += controlEventHandler.OnPreSetFileNetworkInfo; + fileFilter.OnPreSetFileSize += controlEventHandler.OnPreSetFileSize; + fileFilter.OnPreSetFileStandardInfo += controlEventHandler.OnPreSetFileStandardInfo; + fileFilter.OnPreMoveOrRenameFile += controlEventHandler.OnPreMoveOrRenameFile; + fileFilter.OnPreSetFileInfo += controlEventHandler.OnPreSetFileInfo; + fileFilter.OnPreQueryFileSecurity += controlEventHandler.OnPreQueryFileSecurity; + fileFilter.OnPreQueryDirectoryFile += controlEventHandler.OnPreQueryDirectoryFile; + fileFilter.OnPreFileHandleClose += controlEventHandler.OnPreFileHandleClose; + fileFilter.OnPreFileClose += controlEventHandler.OnPreFileClose; + //add the control post-event handler for the control file filter. + fileFilter.OnPostCreateFile += controlEventHandler.OnPostCreateFile; + fileFilter.OnPostDeleteFile += controlEventHandler.OnPostDeleteFile; + fileFilter.OnPostFileRead += controlEventHandler.OnPostFileRead; + fileFilter.OnPostFileWrite += controlEventHandler.OnPostFileWrite; + fileFilter.OnPostQueryFileBasicInfo += controlEventHandler.OnPostQueryFileBasicInfo; + fileFilter.OnPostQueryFileId += controlEventHandler.OnPostQueryFileId; + fileFilter.OnPostQueryFileNetworkInfo += controlEventHandler.OnPostQueryFileNetworkInfo; + fileFilter.OnPostQueryFileSize += controlEventHandler.OnPostQueryFileSize; + fileFilter.OnPostQueryFileStandardInfo += controlEventHandler.OnPostQueryFileStandardInfo; + fileFilter.OnPostQueryFileInfo += controlEventHandler.OnPostQueryFileInfo; + fileFilter.OnPostSetFileBasicInfo += controlEventHandler.OnPostSetFileBasicInfo; + fileFilter.OnPostSetFileNetworkInfo += controlEventHandler.OnPostSetFileNetworkInfo; + fileFilter.OnPostSetFileSize += controlEventHandler.OnPostSetFileSize; + fileFilter.OnPostSetFileStandardInfo += controlEventHandler.OnPostSetFileStandardInfo; + fileFilter.OnPostMoveOrRenameFile += controlEventHandler.OnPostMoveOrRenameFile; + fileFilter.OnPostSetFileInfo += controlEventHandler.OnPostSetFileInfo; + fileFilter.OnPostQueryFileSecurity += controlEventHandler.OnPostQueryFileSecurity; + fileFilter.OnPostQueryDirectoryFile += controlEventHandler.OnPostQueryDirectoryFile; + fileFilter.OnPostFileHandleClose += controlEventHandler.OnPostFileHandleClose; + fileFilter.OnPostFileClose += controlEventHandler.OnPostFileClose; + + //add encrypt event handler if needed. + fileFilter.OnFilterRequestEncryptKey += encryptEventHandler.OnFilterRequestEncryptKey; + + filterControl.AddFilter(fileFilter); + } + + foreach (ProcessFilterRule filterRule in GlobalConfig.ProcessFilterRules.Values) + { + ProcessFilter processFilter = filterRule.ToProcessFilter(); + + processFilter.OnProcessCreation += processEventHandler.OnProcessCreation; + processFilter.OnProcessPreTermination += processEventHandler.OnProcessPreTermination; + processFilter.NotifyProcessWasBlocked += processEventHandler.NotifyProcessWasBlocked; + processFilter.NotifyProcessTerminated += processEventHandler.NotifyProcessTerminated; + processFilter.NotifyThreadCreation += processEventHandler.NotifyThreadCreation; + processFilter.NotifyThreadTerminated += processEventHandler.NotifyThreadTerminated; + processFilter.NotifyProcessHandleInfo += processEventHandler.NotifyProcessHandleInfo; + processFilter.NotifyThreadHandleInfo += processEventHandler.NotifyThreadHandleInfo; + + filterControl.AddFilter(processFilter); + } + + + filterControl.ProtectedProcessIdList = GlobalConfig.ProtectPidList; + filterControl.IncludeProcessIdList = GlobalConfig.IncludePidList; + filterControl.ExcludeProcessIdList = GlobalConfig.ExcludePidList; + filterControl.BooleanConfig = GlobalConfig.BooleanConfig; + + filterControl.NotifiyFileIOWasBlocked -= controlEventHandler.NotifiyFileIOWasBlocked; + filterControl.NotifiyFileIOWasBlocked += controlEventHandler.NotifiyFileIOWasBlocked; + + filterControl.NotifiyProcessTerminatedWasBlocked -= controlEventHandler.NotifiyProcessTerminatedWasBlocked; + filterControl.NotifiyProcessTerminatedWasBlocked += controlEventHandler.NotifiyProcessTerminatedWasBlocked; + + filterControl.NotifyUSBReadWasBlocked -= controlEventHandler.NotifyUSBReadWasBlocked; + filterControl.NotifyUSBReadWasBlocked += controlEventHandler.NotifyUSBReadWasBlocked; + + filterControl.NotifyUSBWriteWasBlocked -= controlEventHandler.NotifyUSBWriteWasBlocked; + filterControl.NotifyUSBWriteWasBlocked += controlEventHandler.NotifyUSBWriteWasBlocked; + + filterControl.VolumeControlFlag = (FilterAPI.VolumeControlFlag)GlobalConfig.VolumeControlFlag; + filterControl.NotifyFilterAttachToVolume -= controlEventHandler.NotifyFilterAttachToVolume; + filterControl.NotifyFilterAttachToVolume += controlEventHandler.NotifyFilterAttachToVolume; + filterControl.NotifyFilterDetachFromVolume -= controlEventHandler.NotifyFilterDetachFromVolume; + filterControl.NotifyFilterDetachFromVolume += controlEventHandler.NotifyFilterDetachFromVolume; + + string lastError = string.Empty; + if (!filterControl.SendConfigSettingsToFilter(ref lastError)) + { + MessageBox.Show(lastError, "StartFilter", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + + + } + + + private void toolStripButton_StartFilter_Click(object sender, EventArgs e) + { + try + { + //Purchase a license key with the link: http://www.easefilter.com/Order.htm + //Email us to request a trial key: info@easefilter.com //free email is not accepted. + string licenseKey = GlobalConfig.LicenseKey; + + string lastError = string.Empty; + + bool ret = filterControl.StartFilter(GlobalConfig.filterType, GlobalConfig.FilterConnectionThreads, GlobalConfig.ConnectionTimeOut, licenseKey, ref lastError); + if (!ret) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("Start filter failed." + lastError, "StartFilter", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + EventManager.WriteMessage(102, "StartFilter", EventLevel.Information, "Start filter service succeeded."); + + SendSettingsToFilter(); + + toolStripButton_StartFilter.Enabled = false; + toolStripButton_Stop.Enabled = true; + + EventManager.WriteMessage(102, "SendSettingsToFilter", EventLevel.Information, "SendSettingsToFilter succeeded."); + } + catch (Exception ex) + { + EventManager.WriteMessage(104, "StartFilter", EventLevel.Error, "Start filter service failed with error " + ex.Message); + } + + } + + + private void toolStripButton_Stop_Click(object sender, EventArgs e) + { + filterControl.StopFilter(); + + toolStripButton_StartFilter.Enabled = true; + toolStripButton_Stop.Enabled = false; + } + + private void toolStripButton_ClearMessage_Click(object sender, EventArgs e) + { + messageHandler.InitListView(); + } + + private void settingsToolStripMenuItem_Click(object sender, EventArgs e) + { + SettingsForm settingForm = new SettingsForm(); + settingForm.StartPosition = FormStartPosition.CenterParent; + if (settingForm.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + SendSettingsToFilter(); + } + } + + + private void toolStripDisplayEvent_Click(object sender, EventArgs e) + { + EventForm.DisplayEventForm(); + } + + private void encryptFileWithToolStripMenuItem_Click(object sender, EventArgs e) + { + EncryptedFileForm encryptForm = new EncryptedFileForm("Encrypt file", Utils.EncryptType.Encryption); + encryptForm.ShowDialog(); + } + + private void decryptFileToolStripMenuItem_Click(object sender, EventArgs e) + { + EncryptedFileForm encryptForm = new EncryptedFileForm("Decrypt file", Utils.EncryptType.Decryption); + encryptForm.ShowDialog(); + } + + private void decryptFileWithOffsetToolStripMenuItem_Click(object sender, EventArgs e) + { + DecryptedFileForm decryptForm = new DecryptedFileForm(); + decryptForm.ShowDialog(); + } + + + private void getEncryptedFileTagdataToolStripMenuItem_Click(object sender, EventArgs e) + { + InputForm inputForm = new InputForm("Input file name", "Plase input file name", ""); + + if (inputForm.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + string fileName = inputForm.InputText; + + byte[] tagData = new Byte[FilterAPI.MAX_AES_TAG_SIZE]; + uint tagDataLength = (uint)tagData.Length; + bool retVal = FilterAPI.GetAESTagData(fileName, ref tagDataLength, tagData); + + if (!retVal) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("GetAESTagData failed with error:" + FilterAPI.GetLastErrorMessage(), "GetAESTagData", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("Get encrypted file " + fileName + " tag data succeeded. return tag data length:" + tagDataLength, "tagData", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + } + + private void exitToolStripMenuItem_Click(object sender, EventArgs e) + { + FilterAPI.ResetConfigData(); + GlobalConfig.Stop(); + filterControl.StopFilter(); + Close(); + } + + + private void ProtectorForm_FormClosed(object sender, FormClosedEventArgs e) + { + FilterAPI.ResetConfigData(); + GlobalConfig.Stop(); + filterControl.StopFilter(); + Application.Exit(); + } + + private void unInstallFilterDriverToolStripMenuItem_Click(object sender, EventArgs e) + { + filterControl.StopFilter(); + FilterAPI.UnInstallDriver(); + } + + private void protectorTutorialToolStripMenuItem_Click(object sender, EventArgs e) + { + TutorialForm tutorialForm = new TutorialForm(); + tutorialForm.ShowDialog(); + } + + private void toolStripButton_LoadMessage_Click(object sender, EventArgs e) + { + messageHandler.LoadMessageFromLogToConsole(); + } + + private void toolStripButton_UnitTest_Click(object sender, EventArgs e) + { + toolStripButton_Stop_Click(null, null); + FileProtectorUnitTest fileProtectorUnitTest = new FileProtectorUnitTest(); + FileProtectorUnitTest.licenseKey = GlobalConfig.LicenseKey; + + fileProtectorUnitTest.ShowDialog(); + } + + + private void toolStripButton_Help_Click(object sender, EventArgs e) + { + System.Diagnostics.Process.Start("https://blog.easefilter.com/file-protector-demo-step-by-step/"); + } + + private void toolStripButton_ApplyTrialKey_Click(object sender, EventArgs e) + { + WebFormServices webForm = new WebFormServices(); + webForm.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + + System.Threading.Tasks.Task.Factory.StartNew(() => { webForm.ShowDialog(); }); + } + + } +} diff --git a/Demo_Source_Code/CSharpDemo/FileProtector/ProtectorForm.resx b/Demo_Source_Code/CSharpDemo/FileProtector/ProtectorForm.resx new file mode 100644 index 0000000..62e0001 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FileProtector/ProtectorForm.resx @@ -0,0 +1,290 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + + 126, 17 + + + + + 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 + AAAAAElFTkSuQmCC + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAJFSURBVDhPrdBbSNNxHAXwo2aKl8ZyMy/brFzWPypvyBQL + iTJCAyWIIOqlMEkjZ4VWCNYg8hIpou1BQyScmvmgwzKjBokJBiL1IoSG1JKcl9wclTZP7u/vyYd88fPy + 53vO4f/ww6aKNYe/SGuKnT1Qox2NNql6cBFFyMceUW9sd0NER82XAra67rB7qZL9rGPuS8P8auWztthI + KXSK8pDvLT9LaXHdYx9rebwn3SlafNiKnAF/xItznWoY0p7FOOqn89g4a6TFXcZuPuBhy6HPYoF3gNoa + hImBABSKSKiALrVNN3NjLJ2myVyaxs8xuzlmuctTTqlx56BYyWzBMNpU8PQF4KiIAOWj4OZroxk0fjIw + oyt6AXeRh2IUWH6VMKxeUSdmsvfbcHIkCnwVitciAlLa9jvODklMtGicqEKCHFZAgWr/SpggybcwokL5 + pB4cVMP7uGviWvXuLJuevnUoE5FsJQLSQhTur4Qh1Hv/UCNhUgvnrAQOR2BKHnlpnihtBquGqMUxEcmW + kwMbWJzIiUhcntbg0tzBwAWm+vFPAjikRpOYrTIjc2+nyrP6vSoS2e9s7RCbztN+KnLp760MMl8is0Jp + 3+UzM6yEVszWbGn3NfqZfcfRge0iwtIFaZzWIvL5FXp/xKpsOtIUjqkdMIjJOu1IQgtyxIXFmydcHKkk + 39wmuwr5NSnkm10Jnaj/j4Cf8/oRN11vybHHZH8JPQ9zuZgc8lRMNsY47JuLDzLPZIb3Ok7rP06diZt3 + pih6Rb0ZgH+vle/bCJhHDQAAAABJRU5ErkJggg== + + + + + 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 + gg== + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAI3SURBVDhPrZFNbxJRGIVv/PgNykbd6c7Elf4BN41xrcat + iV1U2hKCSCExNC5MKE3pQpimmbCwYAukydhaQkgMCYVMUiBESimMEL4qlQglMhSY4x24LhpddNGT3Myd + O+9zzrz3JRcqiyV8ZXu79MzvP/gcDGabOzvfFEFIKuvr8SbHBYWlJeGp1+u9zMrPan8fdyKRRrJc/o3/ + qdMBRLEKpzOQ8HhCtxk2VjTavbW7+/OI1UJRgK48BHmwCnJ/Fc0mcHwMVKtApQJw3Ke63c7fYDghglDc + GAzGsPr8u/8SPxot9IF6HSiVgMNDQJIAs/m9l+GEhMP1ngoMh4AsA70uTWydIiW1YduUMKBdlctAoQBk + MuO9w+GWGU5IPE7tqXrU5uSEmlDg+fIBrk3GcHM6DtD3YhHI5YB0emy0sMArDCdkaytdVvtut4FWi14Y + NVFFXiZBJhP0gEL5cXoyCdRqgE5nSTCcELdb1OZyv0Z/oJp06Wq0FJDXJRBjCVJNgUR7V9PVi1xZCSh6 + /dwEw9X5Wy75fGk+k2mMTPo08XHgFBqnjOvOLia8PeRpejYLxGIFzM4a3jH0rPz+1AueD1WikTx+fJfR + p6PrqKOj6SnaiXoHLpdnaLVaNQz5V6IoXuU438PFRbd5ft7xYWZm7uPa2lfs7QH5/ICmGwVWej5ptUYN + z2+ORme1umSTyXSXfTqfzOa3r0KhLOx2R89gePOEHZ9PNtvyI51OX56amt7QarX32PFFipA/BfvoPB17 + 6OkAAAAASUVORK5CYII= + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAKsSURBVDhPtZFdSJNRHMZPKIQXXZVeGoFC4IVQIJF3hkJJ + sdkmiLqx5ZyOzaUOnUhOrRymkYjOaaZzfrSJLnVq5oLN0YcVK2lmWq1tKqkpfk3LtL1Pr/hClF7WD87F + OTy/5/A/h/wTVCrVSR4vuY/H49UIBIJsenH4fH50SkpKmFAoPMLEiO1EcGlHcNC6lhBzPSHHmGNC5PLq + +wpF7RCbnWRnsRLcLFail83mjnK5nFdJSUkONocjc+lqpHZWBLUhPYeh8BDQJQOMTkhlpX1p6JHVX1JU + AqkoEwKhDMXFVVAqVVT2VfVKHD92tq/v3bavugDrwjN4HnUcNYR4GZ0Qtdr+2Wq1+WdmpzFhNsDcb0ar + vgVt+g50m7qQaAtHvfUW3o67MZIvwUBYyE/j4YBYRifkxvWBMcvoR2p6G1i29MC9BXjWAfcKkO2IR5mP + iyoqFZktyRBnZVFZ+QVyRt2jsLDH/nR0itoAsDnciQW6YJnelL1JQ8HcBdTuXIHUeR7hqhAqUEXyGO03 + ublGs2XkPbXipwseGrC5A7RN1UP6KRoaKg2KDxcRqQlFUFFABaP8iUymb+8edFKeb8BXUxs89O05lkvQ + QIhCbwJON4YiMJ/o6eihPeMvJBJdnanHQS3Qb7DY1QoXXWBoSkeMMQwRDUdx6loUipTDqUx8PxkZTeX6 + tifUBgX4e3WYnlvF5fgYSLKVuN03iJdTFBQ5DxRMfD9i8d3CKu1jykWPMN9+D2MzW3j2YgK+74BrEXB4 + ALnccPD8u6Sna2UVdwYoDy3Mt9Zjcg147f0B1xKwtgnMfdmGVNq++wYHIxY38G6qTfQANEYtxidXYe51 + ok7T76O/2CaRtJbn5fWfZeL7EYm0cQpFs6+0tMcpytA1iiXNIrG4LpLL7QxgIv8LQn4BYUaaWkGxXlUA + AAAASUVORK5CYII= + + + + + AAABAAEAEBAAAAEACABoBQAAFgAAACgAAAAQAAAAIAAAAAEACAAAAAAAQAEAAAAAAAAAAAAAAAEAAAAA + AAAAAAAA////AAUBAAAXBwEAKhEEACgQBAAsEgUALRMFADMXBwA0GAcAOBoIADkbCQA7HQoAPx8LAEEh + CwBAIAsAQiIMAEYkDQBDIw0ASScPAE8sEgBSLhMATSsSAFUxFQBWMhYAWjYYAFk1GABdOBoAYDscAF86 + HABhPB0AYj0dAGM+HgBkPx8AZkEgAGdCIQBsRyUAa0YlAG1IJgBxTCkAdE8rAHZRLQB+WDMAhF86AIRg + OwCFYTwAh2M+AP37+QCJZT8AimZAAIxoQgCNaUMAkGxGAJFtRwCTcEoAkm9JAJRxSwCXdE4AmHVPAJx6 + VACbeVMAnn1XAJ18VgCgf1kAo4NdAKaGYQCoiGMAp4diAKmJZACqimUAqotmAK2PawCvkW0AsZNvALCS + bgCylHAAs5ZzANjFrwC2mncAuZ58ALyhfwC7oH4Aup99AL6kgwDAp4cAw6qKAMWtjgDErI0Axa6QAMix + kwDJs5UAyrSWAMu1mQDMtpoA07+lANPApgDYx7AA6d7PAPPt5QDOup4A08GoANbEqwDUwqkA39C7AN3O + uQDh1MEA7uXYAO/n3ADx6uAA8uzjAPz69wD6+PUA6eDSAPTv5wD49fAA////AAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAYGBgYGBgAAAAAAAAAAAgFADNNcDMAAw0AAAAAAA1UBzMAAAAARwdGDQAAABM4WAZM + ODg4OEsJSzgTAAAUPFoLUj0CAj9PDFs+FQAAIEVkJ11PLi5RXSllSiIAAChQaCxrWUVFWWEtZ1UqAAAr + XwEAAC9HSW4AAAFmNgAAK3EAAABDWlpCAAAAajQAI0cAYgFkZldXZF4BYgBIJx8AbGNJAE5KSEsAU11s + ACEATjY6AERcBQVgQAA4Nk4AJDEwAEFpCDc1BWFAADAwFw4sADtvOS1Wckw1bT4ALBUEChYmMjcREhAP + Mi4lGhQLAAAAABseHh4cHRsZAAAAAPgfAADgBwAAwAMAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAPAPAAA= + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/FileProtector/ProtectorUnitTest.Designer.cs b/Demo_Source_Code/CSharpDemo/FileProtector/ProtectorUnitTest.Designer.cs new file mode 100644 index 0000000..aa9ebc1 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FileProtector/ProtectorUnitTest.Designer.cs @@ -0,0 +1,76 @@ +namespace FileProtector +{ + partial class FileProtectorUnitTest + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FileProtectorUnitTest)); + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.richTextBox_TestResult = new System.Windows.Forms.RichTextBox(); + this.groupBox1.SuspendLayout(); + this.SuspendLayout(); + // + // groupBox1 + // + this.groupBox1.Controls.Add(this.richTextBox_TestResult); + this.groupBox1.Dock = System.Windows.Forms.DockStyle.Fill; + this.groupBox1.Location = new System.Drawing.Point(0, 0); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size(636, 408); + this.groupBox1.TabIndex = 0; + this.groupBox1.TabStop = false; + // + // richTextBox_TestResult + // + this.richTextBox_TestResult.Dock = System.Windows.Forms.DockStyle.Fill; + this.richTextBox_TestResult.Location = new System.Drawing.Point(3, 16); + this.richTextBox_TestResult.Name = "richTextBox_TestResult"; + this.richTextBox_TestResult.Size = new System.Drawing.Size(630, 389); + this.richTextBox_TestResult.TabIndex = 0; + this.richTextBox_TestResult.Text = ""; + // + // FileProtectorUnitTest + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(636, 408); + this.Controls.Add(this.groupBox1); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Name = "FileProtectorUnitTest"; + this.Text = "FileProtector Feature Demo "; + this.Activated += new System.EventHandler(this.FileProtectorUnitTest_Activated); + this.groupBox1.ResumeLayout(false); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.GroupBox groupBox1; + private System.Windows.Forms.RichTextBox richTextBox_TestResult; + } +} \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/FileProtector/ProtectorUnitTest.cs b/Demo_Source_Code/CSharpDemo/FileProtector/ProtectorUnitTest.cs new file mode 100644 index 0000000..0e44b24 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FileProtector/ProtectorUnitTest.cs @@ -0,0 +1,1314 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.IO; +using System.Diagnostics; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; +using Microsoft.Win32.SafeHandles; +using System.Security.AccessControl; +using System.Security.Principal; + +using EaseFilter.FilterControl; +using EaseFilter.CommonObjects; + +namespace FileProtector +{ + public partial class FileProtectorUnitTest : Form + { + FilterControl filterControl = new FilterControl(); + bool isUnitTestStarted = false; + static string binaryPath = GlobalConfig.AssemblyPath; + + /// + /// To manage your files, you need to create at least one filter rule, you can have multiple filter rules. + /// A filter rule only can have one unique include file mask, + /// A filter rule can have multiple exclude file masks, multiple include process names and exclude process names, + /// multiple include process Ids and exclude process Ids, multiple include user names and exclude user names. + /// + private static string unitTestFolder = Path.Combine(binaryPath, "EaseFilterUnitTest"); + private static string unitTestFile = unitTestFolder + "\\unitTestFile.txt"; + + /// + /// Test monitor feature with registering the IO events, get notification after the file was closed for the registered IO. + /// + private static string unitTestMonitorTestFolder = unitTestFolder + "\\monitorFolder"; + private static string unitTestMonitorTestFile = unitTestFolder + "\\monitorFolder\\unitTestMonitorTestFile.txt"; + private static bool isTestMonitorFileCreated = false; + private static bool isTestMonitorFileReanmed = false; + private static bool isTestMonitorFileDeleted = false; + private static bool isTestMonitorFileWritten = false; + private static bool isTestMonitorFileRead = false; + private static bool isTestMonitorFileSecurityChanged = false; + private static bool isTestMonitorFileInfoChanged = false; + + public static bool isNewProcessCreated = false; + + + /// + /// Test Control IO feature with callback function, you can allow or block the file access in the callback function based on the + /// user and file information, here we demo how to block the new file creation, file rename, file delete IO. + /// + private static string unitTestCallbackFolder = unitTestFolder + "\\callbackFolder"; + private static string unitTestCallbackFile = unitTestFolder + "\\callbackFolder\\unitTestFile.txt"; + private static string unitTestCallbackBlockNewFile = unitTestCallbackFolder + "\\blockNewFileCreationFile.txt"; + private static string unitTestCallbackTestReparseFile = unitTestCallbackFolder + "\\reparseTestFile.txt"; + private static string unitTestCallbackReparseTargetFile = unitTestCallbackFolder + "\\reparseTargetFile.txt"; + private static string unitTestCallbackDeletionPreventionFile = unitTestFolder + "\\callbackFolder\\deletionPreventionInCallbackUnitTestFile.txt"; + private static string unitTestCopyAfterDeleteCallbackFile = unitTestFolder + "\\callbackFolder\\unitTestCopyAfterDeleteCallbackFile.txt"; + + + /// + /// Set the exclude folders for a filter rule, exclude file mask must be the subset of the include file mask. + /// All IO from the file names which match both include file mask and exclude file mask won't be intercepted by filter driver, + /// it meant it will be skipped. + /// + private static string filterRuleExcludeTestFolder = unitTestFolder + "\\excludeFolder"; + private static string excludeFolderTestFile = unitTestFolder + "\\excludeFolder\\excludeFile.txt"; + + + /// + /// Set the exclude filter rule, it meant all IO from the excludeFilterRuleTestFolder won't be intercepted by filter driver. + /// Exclude filter rule is a global setting, exclude filter rule has the highest priority. + /// + private static string globalExcludeFilterRuleTestFolder = unitTestFolder + "\\excludeFilterRuleFolder"; + private static string globalExcludeFilterRuleTestFile = unitTestFolder + "\\excludeFilterRuleFolder\\excludeFilterRuleTestFile.txt"; + + //Purchase a license key with the link: http://www.easefilter.com/Order.htm + //Email us to request a trial key: info@easefilter.com //free email is not accepted. + public static string licenseKey = "******************************************"; + + public FileProtectorUnitTest() + { + InitializeComponent(); + + } + + private void InitializeUnitTest() + { + if (!Directory.Exists(unitTestFolder)) + { + Directory.CreateDirectory(unitTestFolder); + } + + if (!File.Exists(unitTestFile)) + { + File.AppendAllText(unitTestFile, "This is unit test file."); + } + + if (!Directory.Exists(unitTestMonitorTestFolder)) + { + Directory.CreateDirectory(unitTestMonitorTestFolder); + } + + + if (!Directory.Exists(globalExcludeFilterRuleTestFolder)) + { + Directory.CreateDirectory(globalExcludeFilterRuleTestFolder); + } + + if (!File.Exists(globalExcludeFilterRuleTestFile)) + { + File.AppendAllText(globalExcludeFilterRuleTestFile, "This is unit test excludeFilterRuleTestFolder file."); + } + + + if (!Directory.Exists(filterRuleExcludeTestFolder)) + { + Directory.CreateDirectory(filterRuleExcludeTestFolder); + } + + if (!File.Exists(excludeFolderTestFile)) + { + File.AppendAllText(excludeFolderTestFile, "This is excludeFolderTestFile test file."); + } + + if (!Directory.Exists(unitTestCallbackFolder)) + { + Directory.CreateDirectory(unitTestCallbackFolder); + } + + if (!File.Exists(unitTestCallbackFile)) + { + File.AppendAllText(unitTestCallbackFile, "This is unitTestCallbackFile test file."); + } + + if (!File.Exists(unitTestCallbackDeletionPreventionFile)) + { + File.AppendAllText(unitTestCallbackDeletionPreventionFile, "This is unitTestCopyBeforeDeleteCallbackFile test file."); + } + } + + private void CleanupTestFolder(string folder) + { + try + { + if (Directory.Exists(folder)) + { + Directory.Delete(folder, true); + } + + } + catch (Exception ex) + { + AppendText("Clean up test folder failed:" + ex.Message, Color.Red); + } + } + + private void AppendText(string text, Color color) + { + if (color == Color.Black) + { + richTextBox_TestResult.AppendText(Environment.NewLine); + richTextBox_TestResult.SelectionFont = new Font("Arial", 12, FontStyle.Bold); + } + + richTextBox_TestResult.SelectionStart = richTextBox_TestResult.TextLength; + richTextBox_TestResult.SelectionLength = 0; + + richTextBox_TestResult.SelectionColor = color; + richTextBox_TestResult.AppendText(text + Environment.NewLine); + richTextBox_TestResult.SelectionColor = richTextBox_TestResult.ForeColor; + + if (color == Color.Black) + { + richTextBox_TestResult.AppendText(Environment.NewLine); + } + + + } + + /// + /// Fires this event when a file's information was changed after the file handle closed + /// + public void NotifyFileWasChanged(object sender, FileChangedEventArgs e) + { + if (string.Compare(unitTestMonitorTestFile, e.FileName, true) == 0) + { + if ((e.eventType & FilterAPI.FileChangedEvents.NotifyFileWasCreated) > 0) + { + isTestMonitorFileCreated = true; + } + + if ((e.eventType & FilterAPI.FileChangedEvents.NotifyFileWasWritten) > 0) + { + isTestMonitorFileWritten = true; + } + + if ((e.eventType & FilterAPI.FileChangedEvents.NotifyFileWasRenamed) > 0) + { + isTestMonitorFileReanmed = true; + } + + if ((e.eventType & FilterAPI.FileChangedEvents.NotifyFileWasDeleted) > 0) + { + isTestMonitorFileDeleted = true; + } + + if ((e.eventType & FilterAPI.FileChangedEvents.NotifyFileInfoWasChanged) > 0) + { + isTestMonitorFileInfoChanged = true; + } + + if ((e.eventType & FilterAPI.FileChangedEvents.NotifyFileSecurityWasChanged) > 0) + { + isTestMonitorFileSecurityChanged = true; + } + + if ((e.eventType & FilterAPI.FileChangedEvents.NotifyFileWasRead) > 0) + { + isTestMonitorFileRead = true; + } + + } + } + + private void ShowMonitorFileEventsUnitTestResult() + { + + /// print out the monitor IO events test result. + string message = "File IO Events Unit Test."; + AppendText(message, Color.Black); + message = " Register the monitor file IO events: create,rename,delete,written,file info changed, read, security change in the test folder." + Environment.NewLine; + AppendText(message, Color.Gray); + + if (isTestMonitorFileCreated) + { + AppendText("Test new file creation event passed.", Color.Green); + AppendText("A test file was created.", Color.Gray); + } + else + { + AppendText("Test new file creation event failed.", Color.Red); + } + + if (isTestMonitorFileInfoChanged) + { + AppendText("Test file info change event passed.", Color.Green); + AppendText("The test file's attributes were changed.", Color.Gray); + } + else + { + AppendText("Test file info change event failed.", Color.Red); + } + + if (isTestMonitorFileRead) + { + AppendText("Test file read event passed.", Color.Green); + AppendText("The test file's data was read.", Color.Gray); + } + else + { + AppendText("Test file read event failed.", Color.Red); + } + if (isTestMonitorFileReanmed) + { + AppendText("Test file rename event passed.", Color.Green); + AppendText("The test file was renamed.", Color.Gray); + } + else + { + AppendText("Test file rename event failed.", Color.Red); + } + if (isTestMonitorFileSecurityChanged) + { + AppendText("Test file security change event passed.", Color.Green); + AppendText("The test file's security was changed.", Color.Gray); + } + else + { + AppendText("Test file security change event failed.", Color.Red); + } + + if (isTestMonitorFileWritten) + { + AppendText("Test file written event passed.", Color.Green); + AppendText("The test file was written.", Color.Gray); + } + else + { + AppendText("Test file written event failed.", Color.Red); + } + + + if (isTestMonitorFileDeleted) + { + AppendText("Test file delete event passed.", Color.Green); + AppendText("The test file was deleted.", Color.Gray); + } + else + { + AppendText("Test file delete event failed.", Color.Red); + } + } + + private void MonitorFileEventsUnitTest() + { + string lastError = string.Empty; + + // + //Test case1: Monitor File IO ( creation,rename,delete,write,security change,file info change, file read) + //Register file events to get the notification when the registered IO was triggered. + //This test will notify the UnitTestCallbackHandler with the IO events which we did below. + // + + + FileFilter monitorFilterRule = new FileFilter(unitTestMonitorTestFolder + "\\*"); + monitorFilterRule.AccessFlags = (FilterAPI.AccessFlag)FilterAPI.ALLOW_MAX_RIGHT_ACCESS; + monitorFilterRule.FileChangeEventFilter = (FilterAPI.FileChangedEvents.NotifyFileWasCreated | FilterAPI.FileChangedEvents.NotifyFileWasDeleted | FilterAPI.FileChangedEvents.NotifyFileInfoWasChanged + | FilterAPI.FileChangedEvents.NotifyFileWasRenamed | FilterAPI.FileChangedEvents.NotifyFileWasWritten | FilterAPI.FileChangedEvents.NotifyFileSecurityWasChanged | FilterAPI.FileChangedEvents.NotifyFileWasRead); + + + //register the events + monitorFilterRule.NotifyFileWasChanged += NotifyFileWasChanged; + + try + { + filterControl.ClearFilters(); + filterControl.AddFilter(monitorFilterRule); + + if (!filterControl.SendConfigSettingsToFilter(ref lastError)) + { + MessageBox.Show(lastError, "SendConfigToFilter", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + //create and write events + File.AppendAllText(unitTestMonitorTestFile, "This is IO events monitor test file."); + + //read event + File.ReadAllText(unitTestMonitorTestFile); + + //file info change event + File.SetAttributes(unitTestMonitorTestFile, FileAttributes.Normal); + + // Get a FileSecurity object that represents the current security settings. + DirectoryInfo dInfo = new DirectoryInfo(unitTestMonitorTestFile); + DirectorySecurity dSecurity = dInfo.GetAccessControl(); + dSecurity.AddAccessRule(new FileSystemAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null), FileSystemRights.FullControl, InheritanceFlags.ObjectInherit | InheritanceFlags.ContainerInherit, PropagationFlags.NoPropagateInherit, AccessControlType.Allow)); + //test security change event + dInfo.SetAccessControl(dSecurity); + + //test rename event. + string newMonitorFileName = unitTestMonitorTestFolder + "\\newMonitorFileName.txt"; + File.Move(unitTestMonitorTestFile, newMonitorFileName); + + //create test file for deletion. + File.AppendAllText(unitTestMonitorTestFile, "This is IO events monitor test file."); + + //test delete event. + File.Delete(unitTestMonitorTestFile); + File.Delete(newMonitorFileName); + + //wait for the test result. + System.Threading.Thread.Sleep(3000); + } + catch (Exception ex) + { + AppendText("FileEventMonitorTest failed." + ex.Message, Color.Red); + } + finally + { + filterControl.RemoveFilter(monitorFilterRule); + filterControl.SendConfigSettingsToFilter(ref lastError); + } + + } + + private void FolderProtectionUnitTest() + { + // + //Test case2: Folder Protection Unit Test + //All files in the test folder "c:\\EaseFilterUnitTest" will be readonly, except the current process, you can add more authorized processes here. + //All files in the test folder "c:\\EaseFilterUnitTest" can't be accessed by process "explorer.exe" and "cmd.exe", you can add more processes. + //There are exception for the sub folder "excludeFolder", no any restriction to this folder. + + //pros: it can cover all files in the protected folder. + + //cons: the blocked processes don't have permission to access the files in the protected folder. + // it only can block the listed processes. + + string lastError = string.Empty; + string message = "Folder Protection Unit Test"; + AppendText(message, Color.Black); + + message = "1. The protected folder is read only to all processes except for the authorized processes." + Environment.NewLine; + message += "2. Block the explorer to copy&paste the protected files." + Environment.NewLine; + message += "3. Block the protected files file access from remote network." + Environment.NewLine; + message += "4. Set up an exclude sub foler of the protected folder which excludes the security restrition." + Environment.NewLine; + + AppendText(message, Color.Gray); + + //Prevent copy&paste operation from explorer and dos prompt. + FileFilter blockAccessFilter = new FileFilter(unitTestFolder + "\\*"); + //exclude the folder from the filter + blockAccessFilter.ExcludeFileFilterMaskList.Add(filterRuleExcludeTestFolder + "\\*"); + //blocked application list. + blockAccessFilter.IncludeProcessNameList.Add("explorer.exe"); + blockAccessFilter.IncludeProcessNameList.Add("cmd.exe"); + blockAccessFilter.EnableReadFileData = false; + + + //set the accessFlag to readonly for all the files in the test folder except the current process. + FileFilter readonlyFilter = new FileFilter(unitTestFolder + "*"); + //exclude the folder from the filter + readonlyFilter.ExcludeFileFilterMaskList.Add(filterRuleExcludeTestFolder + "\\*"); + readonlyFilter.EnableDeleteFile = false; + readonlyFilter.EnableFileCreation = false; + readonlyFilter.EnableWriteToFile = false; + readonlyFilter.EnableChangeFileSecurity = false; + readonlyFilter.EnableChangeFileInfo = false; + readonlyFilter.EnableFileBeingAccessedViaNetwork = false; + + try + { + filterControl.ClearFilters(); + filterControl.AddFilter(blockAccessFilter); + filterControl.AddFilter(readonlyFilter); + filterControl.SendConfigSettingsToFilter(ref lastError); + + // The current process should have the read permission. + try + { + string textData = File.ReadAllText(unitTestFile); + } + catch (Exception ex) + { + AppendText("Read file " + unitTestFile + " failed." + ex.Message, Color.Red); + return; + } + + try + { + string cmdExcludeFileName = filterRuleExcludeTestFolder + "\\cmd_copy.txt"; + + //for files in the exclude folder, anyone can read and write here. + File.Copy(unitTestFile, cmdExcludeFileName); + + if (File.Exists(cmdExcludeFileName)) + { + AppendText("Test with exclude folder passed.", Color.Green); + AppendText("Copy a protected test file to the exclude sub folder succeeded.", Color.Gray); + } + else + { + AppendText("Test with excludeFolder failed.", Color.Red); + } + + } + catch (Exception ex) + { + AppendText("Test with exclude folder failed." + ex.Message, Color.Red); + return; + } + + try + { + //The current process shouldn't have the write permission. + File.AppendAllText(unitTestFile, ",new test data was added."); + + AppendText("Test with blocking write access failed.", Color.Red); + return; + + } + catch + { + AppendText("Test with blocking write access passed.", Color.Green); + AppendText("Write data to the protected file was blocked.", Color.Gray); + } + + + filterControl.RemoveFilter(readonlyFilter); + + //here you can put your exclude process name which has the full permission to the test folder. + readonlyFilter.ExcludeProcessIdList.Add(FilterAPI.GetCurrentProcessId()); + filterControl.AddFilter(readonlyFilter); + filterControl.SendConfigSettingsToFilter(ref lastError); + + try + { + //The current process should have the write permission. + File.AppendAllText(unitTestFile, ",new test data was added."); + + AppendText("Test with exclude process passed.", Color.Green); + AppendText("Write data to the protected file was passed with authorized process.", Color.Gray); + } + catch + { + AppendText("Test with exclude process failed.", Color.Red); + return; + } + + try + { + //the cmd.exe should be blocked to access here + string cmdBlockFileName = unitTestFolder + "\\cmd_copy.txt"; + Process.Start("cmd", "/C copy " + unitTestFile + " " + cmdBlockFileName); + + if (File.Exists(cmdBlockFileName)) + { + AppendText("Test with include process cmd failed.", Color.Red); + return; + } + else + { + AppendText("Test with include process cmd passed.", Color.Green); + AppendText("Copy protected file from cmd.exe in dos prompt was blocked.", Color.Gray); + } + } + catch (Exception ex) + { + AppendText("Test with include process cmd failed." + ex.Message, Color.Red); + } + + + //blockAccessFilterRule inlcude file mask is the subset of the include file mask of the readonlyFilterRule + //the filter driver will check with the filter rule blockAccessFilterRule, if it doesn't match, then check with readonlyFilterRule. + + AppendText("Test with sub folder filter rule passed.", Color.Green); + AppendText("Create two filter rules, the files inside the sub folder matched with sub folder filter rule.", Color.Gray); + + } + catch (Exception ex) + { + AppendText("Test readonly folder failed." + ex.Message, Color.Red); + } + finally + { + filterControl.ClearFilters(); + filterControl.SendConfigSettingsToFilter(ref lastError); + } + + } + + private void AddProcessRightsUnitTest() + { + // + //Test case3: Add Process Rights Unit Test + //Test folder "c:\\EaseFilterUnitTest" . + + //pros: You can set the specific access rights to different processes in the protected folder, all other processes will have the same access rights of the filter rule. + string lastError = string.Empty; + string message = "Add Process Rights Unit Test"; + AppendText(message, Color.Black); + + message = "1. Remove the access rights for process 'cmd.exe' to files in test folder." + Environment.NewLine; + AppendText(message, Color.Gray); + + //Prevent copy&paste operation from explorer and dos prompt. + FileFilter blockAccessFilter = new FileFilter(unitTestFolder + "\\*"); + + //Remove all access rights for the process "cmd". + blockAccessFilter.ProcessNameAccessRightList.Add("cmd.exe",((uint)FilterAPI.AccessFlag.LEAST_ACCESS_FLAG)); + + try + { + filterControl.ClearFilters(); + filterControl.AddFilter(blockAccessFilter); + filterControl.SendConfigSettingsToFilter(ref lastError); + + // The current process should have all permission. + File.AppendAllText(unitTestFile, ",new test data was added."); + string textData = File.ReadAllText(unitTestFile); + + //the cmd.exe should be blocked to access here + string cmdBlockFileName = unitTestFolder + "\\cmd_copy.txt"; + //delete the test file first + File.Delete(cmdBlockFileName); + Process.Start("cmd", "/C copy " + unitTestFile + " " + cmdBlockFileName); + + if (File.Exists(cmdBlockFileName)) + { + AppendText("Test add process rights failed.", Color.Red); + return; + } + else + { + AppendText("Test add process rights passed.", Color.Green); + AppendText("Remove process cmd.exe access rights succeeded.", Color.Gray); + } + } + catch (Exception ex) + { + AppendText("Test add process rights failed." + ex.Message, Color.Red); + } + finally + { + filterControl.ClearFilters(); + filterControl.SendConfigSettingsToFilter(ref lastError); + } + + } + + private void AddUserRightsUnitTest() + { + // + //Test case4: Add User Rights Unit Test + //Set current user with readonly right access to folder "c:\\EaseFilterUnitTest". + + //pros: You can set the specific access rights to different users in the protected folder, all other users will have the same access rights of the filter rule. + string lastError = string.Empty; + string message = "Add User Rights Unit Test"; + AppendText(message, Color.Black); + + string userName = Environment.UserDomainName + "\\" + Environment.UserName; + + message = "1. The protected folder can't be acccessed by the current user:" + userName + Environment.NewLine; + AppendText(message, Color.Gray); + + //Prevent copy&paste operation from explorer and dos prompt. + FileFilter blockAccessFilter = new FileFilter(unitTestFolder + "\\*"); + + //Remove all access rights to the current user. + blockAccessFilter.userAccessRightList.Add(userName,((uint)FilterAPI.AccessFlag.LEAST_ACCESS_FLAG)); + + try + { + filterControl.ClearFilters(); + filterControl.AddFilter(blockAccessFilter); + filterControl.SendConfigSettingsToFilter(ref lastError); + + try + { + // The current process doesnt have any permission. + File.AppendAllText(unitTestFile, ",new test data was added."); + AppendText("Test add user rights failed.", Color.Red); + } + catch + { + AppendText("Test add user rights passed.", Color.Green); + AppendText("Remove current user access rights succeeded.", Color.Gray); + return; + } + + } + catch (Exception ex) + { + AppendText("Test add user rights failed." + ex.Message, Color.Red); + } + finally + { + filterControl.ClearFilters(); + filterControl.SendConfigSettingsToFilter(ref lastError); + } + + } + + private void NoRenameAndCopyUnitTest() + { + + + // + //Test case5: prevent specific files in protected folder from being copied out + //All files with protected extension ".prt" only can store in protected folder "c:\\EaseFilterUnitTest". + // + //pros: the simplest way to prevent the protected files from being copied out. + //cons: it only can block the specific files. + + GlobalConfig.FilterRules.Clear(); + string lastError = string.Empty; + string message = "Protect Files With Extension '.prt'"; + AppendText(message, Color.Black); + + message = "1. Prevent the protected files from renaming and deleting." + Environment.NewLine; + message += "2. Prevent the protected files from copying out of the protected folder." + Environment.NewLine; + message += "3. Set up an exclude sub foler of the protected folder which excludes the security restrition." + Environment.NewLine; + + AppendText(message, Color.Gray); + + //not allow file rename or delete and copy out of the folder + FileFilter noRenameFilter = new FileFilter(unitTestFolder + "*.prt"); + noRenameFilter.EnableRenameOrMoveFile = false; + noRenameFilter.EnableDeleteFile = false; + noRenameFilter.EnableFileBeingCopied = false; + + FileFilter globalExcludeFilter = new FileFilter(filterRuleExcludeTestFolder + "\\*"); + + try + { + + filterControl.ClearFilters(); + filterControl.AddFilter(noRenameFilter); + filterControl.AddFilter(globalExcludeFilter); + filterControl.SendConfigSettingsToFilter(ref lastError); + + string protectedFileName = unitTestFolder + "\\protectFile.prt"; + File.AppendAllText(protectedFileName, "This is protected file with .prt extension."); + + //file rename is blocked + try + { + File.Move(protectedFileName, unitTestFolder + "\\test.txt"); + AppendText("Test with file rename prevention failed.", Color.Red); + return; + } + catch + { + AppendText("Test with file rename prevention passed.", Color.Green); + AppendText("Block the protected file being renamed.", Color.Gray); + } + + //file delete is blocked + try + { + File.Delete(protectedFileName); + AppendText("Test with file delete prevention failed.", Color.Red); + return; + } + catch + { + AppendText("Test with file delete prevention passed.", Color.Green); + AppendText("Block the protected file being deleted.", Color.Gray); + } + + //exclude folder file deletion is allowed + try + { + File.Delete(globalExcludeFilterRuleTestFile); + AppendText("Test global exclude filter rule passed.", Color.Green); + AppendText("Delete the file from the exclude folder succeeded.", Color.Gray); + } + catch (Exception ex) + { + AppendText("Test global exclude filter rule failed." + ex.Message, Color.Red); + return; + } + + //protected file copy out to the protect folder is blocked + try + { + File.Copy(protectedFileName, "c:\\test.txt"); + AppendText("Test with file copying out prevention failed.", Color.Red); + return; + } + catch + { + AppendText("Test with file copying out prevention passed.", Color.Green); + AppendText("Copy the protected file outside of the protected folder is blocked.", Color.Gray); + } + } + catch (Exception ex) + { + AppendText("NoRenameAndCopyUnitTest failed." + ex.Message, Color.Red); + return; + } + finally + { + filterControl.ClearFilters(); + filterControl.SendConfigSettingsToFilter(ref lastError); + } + } + + private void FolderLockerUnitTest() + { + + // + //Test case6: Folder Locker + //1. Transparently encrypt/decrpt files files in the test folder "c:\\EaseFilterUnitTest". + //2. All files are hidden in the test folder "c:\\EaseFilterUnitTest". + //3. Add/Remove the exception application which will be excluded from the restriction. + string lastError = string.Empty; + string message = "Folder Locker Unit Test"; + AppendText(message, Color.Black); + + message = " 1. Encrypt files transparently in the locked folder." + Environment.NewLine; + message += " 2. Hide protected files to unauthorized processes." + Environment.NewLine; + message += " 3. Allow authorized processes to read encrypted files." + Environment.NewLine; + + AppendText(message, Color.Gray); + + //the authorized processes in the include process list. + FileFilter authorizedProcessFilter = new FileFilter(unitTestFolder + "\\*"); + authorizedProcessFilter.IncludeProcessIdList.Add(FilterAPI.GetCurrentProcessId()); + authorizedProcessFilter.EnableEncryption = true; + authorizedProcessFilter.EncryptionPassPhrase = "password"; + + //all other processes can't read the files, can't see the files. + FileFilter folderLockerFilter = new FileFilter(unitTestFolder + "*"); + folderLockerFilter.EnableEncryption = true; + folderLockerFilter.EncryptionPassPhrase = "password"; + folderLockerFilter.EnableReadEncryptedData = false; + folderLockerFilter.EnableHiddenFile = true; + folderLockerFilter.HiddenFileFilterMaskList.Add("*"); + + try + { + filterControl.ResetConfigData(ref lastError); + + string folderLockerTestFileName = unitTestFolder + "\\folderLockerTestFile.txt"; + string testContent = "This is folderLockerTestFileName FileName test file."; + + File.AppendAllText(folderLockerTestFileName, testContent); + + filterControl.ClearFilters(); + filterControl.AddFilter(folderLockerFilter); + filterControl.SendConfigSettingsToFilter(ref lastError); + + string[] txtFileList = Directory.GetFiles(unitTestFolder, "*.txt"); + if (txtFileList.Length == 0) + { + //All .txt file name should be hidden, the file list should be empty. + AppendText("Test hidden file list passed.", Color.Green); + AppendText("Hide the protected files from directory browsing.", Color.Gray); + } + else + { + AppendText("Test hidden file list failed.", Color.Red); + return; + } + + try + { + string encyrptionTestFileName = unitTestFolder + "\\encryptionTestFile.txt"; + File.AppendAllText(encyrptionTestFileName, testContent); + //read the raw encrypted file without authorization. + string readContent = File.ReadAllText(encyrptionTestFileName); + + if (string.Compare(testContent, readContent, false) != 0) + { + AppendText("Test read raw encrypted data passed.", Color.Green); + AppendText("Protected file's data can't be read.", Color.Gray); + } + else + { + AppendText("Test read raw encrypted data failed.", Color.Red); + return; + } + + } + catch + { + AppendText("Test block read access passed.", Color.Green); + AppendText("Block the protected file reading from unauthorized processes.", Color.Gray); + } + + + filterControl.AddFilter(authorizedProcessFilter); + filterControl.SendConfigSettingsToFilter(ref lastError); + + //the current process was added with exception filter rule. + txtFileList = Directory.GetFiles(unitTestFolder, "*.txt"); + if (txtFileList.Length > 0) + { + //All .txt file name should be listed now for the current process. + AppendText("Test authorized processes filter rule passed.", Color.Green); + + AppendText("Add authorized processes which can get the file list.", Color.Gray); + } + else + { + AppendText("Test authorized processes filter rule failed.", Color.Red); + return; + } + + try + { + IntPtr fileHandle = IntPtr.Zero; + + if (Utils.OpenRawEnCyptedFile(folderLockerTestFileName, out fileHandle, out lastError)) + { + SafeFileHandle shFile = new SafeFileHandle(fileHandle, true); + FileStream fs = new FileStream(shFile, FileAccess.Read); + byte[] buffer = new byte[1024]; + int len = fs.Read(buffer, 0, 1024); + + string encryptedText = Encoding.Unicode.GetString(buffer); + encryptedText = encryptedText.TrimEnd((char)0); + + fs.Close(); + + if (string.Compare(testContent, encryptedText, false) != 0) + { + AppendText("Test folder locker transparent file encryption passed.", Color.Green); + AppendText("Protected file's data was encrypted.", Color.Gray); + } + else + { + AppendText("Test folder locker transparent file encryption failed.", Color.Red); + return; + } + + } + else + { + AppendText("Test folder locker transparent file encryption failed.OpenRawEnCyptedFile failed:" + lastError, Color.Red); + return; + } + + string readContent = File.ReadAllText(folderLockerTestFileName); + if (string.Compare(testContent, readContent, false) == 0) + { + AppendText("Test folder locker transparent file decryption passed.", Color.Green); + AppendText("Protected file's data was decrypted.", Color.Gray); + } + else + { + AppendText("Test folder locker transparent file decryption failed.", Color.Red); + return; + } + } + catch(Exception ex) + { + AppendText("Test folder locker transparent file decryption failed." + ex.Message, Color.Red); + return; + } + + } + catch( Exception ex) + { + AppendText("Test folder locker failed." + ex.Message, Color.Red); + } + finally + { + filterControl.ClearFilters(); + filterControl.SendConfigSettingsToFilter(ref lastError); + } + + } + + /// + /// Fires this event after the new file was created, the handle is not closed. + /// + public void OnPreCreateFile(object sender, FileCreateEventArgs e) + { + if (string.Compare(unitTestCallbackBlockNewFile, e.FileName, true) == 0) + { + //test block the file open here. + e.ReturnStatus = NtStatus.Status.AccessDenied; + } + else if (string.Compare(unitTestCallbackTestReparseFile, e.FileName, true) == 0) + { + //test reparse file open to other file. + e.reparseFileName = unitTestCallbackReparseTargetFile; + e.ReturnStatus = NtStatus.Status.Reparse; + e.IsDataModified = true; + } + + } + + /// + /// Fires the event before the file is going to be renamed. + /// + /// + /// + public void OnPreMoveOrRenameFile(object sender, FileMoveOrRenameEventArgs e) + { + if (string.Compare(unitTestCallbackFile, e.FileName, true) == 0) + { + e.ReturnStatus = NtStatus.Status.AccessDenied; + } + } + + private static bool CopyFileBeforeDeltion(string fileName) + { + try + { + IntPtr fileHandle = IntPtr.Zero; + bool retVal = FilterAPI.GetFileHandleInFilter(fileName, (uint)FileAccess.Read, ref fileHandle); + if (retVal) + { + SafeFileHandle sHandle = new SafeFileHandle(fileHandle, false); + FileStream fileStream = new FileStream(sHandle, FileAccess.Read); + + FileStream copyFileStream = new FileStream(unitTestCopyAfterDeleteCallbackFile, FileMode.Create, FileAccess.Write, FileShare.None); + + byte[] buffer = new byte[4096]; + int readLen = 0; + + do + { + readLen = fileStream.Read(buffer, 0, buffer.Length); + + if (readLen > 0) + { + copyFileStream.Write(buffer, 0, readLen); + } + } + while (readLen > 0); + + FilterAPI.CloseFileHandleInFilter(fileHandle); + copyFileStream.Close(); + + + } + + } + catch (Exception ex) + { + EventManager.WriteMessage(156, "CopyFileBeforeDeltion", EventLevel.Error, "CopyFileBeforeDeltion failed." + ex.Message); + } + + return true; + } + + + /// + /// Fires the event before the file is going to be deleted. + /// + /// + /// + public void OnPreDeleteFile(object sender, FileIOEventArgs e) + { + e.ReturnStatus = NtStatus.Status.Success; + + if (string.Compare(unitTestCallbackFile, e.FileName, true) == 0) + { + e.ReturnStatus = NtStatus.Status.AccessDenied; + } + + if (string.Compare(unitTestCallbackDeletionPreventionFile, e.FileName, true) == 0) + { + e.ReturnStatus = NtStatus.Status.AccessDenied; + } + + } + + private void FileAccessControlUnitTest() + { + + // + //Test case7: Control the file IO with callback function. + // 1. You will get the notification before the file was opened,renamed,deleted. + // 2. In callback funtion, you can decide if proceed the IO operation based on the information + // (user name,process name,file information, file content). + // 3. For the test file, it will be blocked to create new file,rename file, delete file. + string lastError = string.Empty; + string message = "File Access Control With Callback Function Unit Test"; + AppendText(message, Color.Black); + + message = " 1. Register the PRE_CREATE and PRE_SET_INFORMATION." + Environment.NewLine; + message += " 2. The callback function will get the notification before the protected file was opened or file information was changed." + Environment.NewLine; + message += " 3. Block the new file creation, file rename and file deletion in callback function." + Environment.NewLine; + + AppendText(message, Color.Gray); + + FileFilter callbackControlFilter = new FileFilter(unitTestCallbackFolder + "\\*"); + callbackControlFilter.ControlFileIOEventFilter = (ulong)(ControlFileIOEvents.OnPreFileCreate | ControlFileIOEvents.OnPreMoveOrRenameFile| ControlFileIOEvents.OnPreDeleteFile); + callbackControlFilter.OnPreCreateFile += OnPreCreateFile; + callbackControlFilter.OnPreMoveOrRenameFile += OnPreMoveOrRenameFile; + callbackControlFilter.OnPreDeleteFile += OnPreDeleteFile; + + + try + { + filterControl.ClearFilters(); + filterControl.AddFilter(callbackControlFilter); + filterControl.SendConfigSettingsToFilter(ref lastError); + + try + { + if (File.Exists(unitTestCallbackFile)) + { + File.Delete(unitTestCallbackFile); + AppendText("Test block file deletion in callback failed. file " + unitTestCallbackFile + " was deleted.", Color.Red); + return; + } + else + { + AppendText("Test block file deletion in callback failed. file " + unitTestCallbackFile + " doesn't exist.", Color.Red); + return; + } + + } + catch + { + AppendText("Test block file deletion in callback passed.", Color.Green); + AppendText("Delete protected file was blocked by callback function.", Color.Gray); + } + + try + { + string blockRenameFileName = unitTestFolder + "\\blockRenameFile.txt"; + File.Move(unitTestCallbackFile, blockRenameFileName); + AppendText("Test block file rename in callback failed.", Color.Red); + return; + } + catch + { + AppendText("Test block file rename in callback passed.", Color.Green); + AppendText("Rename protected file was blocked by callback function.", Color.Gray); + } + + try + { + FileStream fs = new FileStream(unitTestCallbackBlockNewFile, FileMode.CreateNew); + fs.Close(); + + AppendText("Test block new file creation in callback failed.", Color.Red); + return; + } + catch + { + AppendText("Test block the new file creation in callback passed.", Color.Green); + AppendText("Create new file was blocked by callback function.", Color.Gray); + } + + } + catch (Exception ex) + { + AppendText("Test File Access Control failed." + ex.Message, Color.Red); + } + finally + { + filterControl.ClearFilters(); + filterControl.SendConfigSettingsToFilter(ref lastError); + } + } + + private void DeletionCallbackUnitTest() + { + + // + //Test case8: copy file before it was deleted + //Make a copy of the file before it was deleted. + string lastError = string.Empty; + string message = "Copy Protected File Before File Deletion Unit Test"; + AppendText(message, Color.Black); + + message = " Make a copy of the file before it was deleted." + Environment.NewLine; + AppendText(message, Color.Gray); + + FileFilter deletionCallbackFilter = new FileFilter(unitTestCallbackFolder + "\\*"); + deletionCallbackFilter.ControlFileIOEventFilter = (ulong)(ControlFileIOEvents.OnPreFileCreate | ControlFileIOEvents.OnPreDeleteFile); + deletionCallbackFilter.OnPreDeleteFile += OnPreDeleteFile; + + + try + { + filterControl.ClearFilters(); + filterControl.AddFilter(deletionCallbackFilter); + filterControl.SendConfigSettingsToFilter(ref lastError); + + try + { + File.Delete(unitTestCallbackDeletionPreventionFile); + + //the deletion should be blocked in callback function. + AppendText("Test deletion prevention in callback failed.", Color.Red); + return; + + } + catch + { + } + + filterControl.ClearFilters(); + filterControl.SendConfigSettingsToFilter(ref lastError); + + try + { + File.Delete(unitTestCallbackDeletionPreventionFile); + + //Now the file can be deleted. + AppendText("Test deletion prevention in callback passed.", Color.Green); + return; + + } + catch + { + } + + + } + catch (Exception ex) + { + AppendText("Test deletion prevention in callback exception:" + ex.Message, Color.Red); + } + finally + { + filterControl.ClearFilters(); + filterControl.SendConfigSettingsToFilter(ref lastError); + } + } + + private void ReparseFileOpenUnitTest() + { + + // + //Test case9: Reparse file open to the new file path. + string lastError = string.Empty; + string message = "Reparse file open to the new file path unit test"; + AppendText(message, Color.Black); + + message = "Reparse file " + unitTestCallbackTestReparseFile + " open to " + unitTestCallbackReparseTargetFile + Environment.NewLine; + AppendText(message, Color.Gray); + + FileFilter reparseFileFilter = new FileFilter(unitTestCallbackFolder + "\\*"); + reparseFileFilter.ControlFileIOEventFilter = (ulong)(ControlFileIOEvents.OnPreFileCreate); + reparseFileFilter.OnPreCreateFile += OnPreCreateFile; + + try + { + filterControl.ClearFilters(); + filterControl.AddFilter(reparseFileFilter); + filterControl.SendConfigSettingsToFilter(ref lastError); + + string targetFileContent = "unitTestCallbackReparseTargetFile content"; + File.AppendAllText(unitTestCallbackReparseTargetFile, targetFileContent); + + string readContent = File.ReadAllText(unitTestCallbackTestReparseFile); + if (string.Compare(readContent, targetFileContent, true) == 0) + { + AppendText("Test reparse file open passed.", Color.Green); + AppendText("reparse file open to another file.", Color.Gray); + } + else + { + AppendText("Test reparse file open failed.", Color.Red); + return; + } + + + } + catch (Exception ex) + { + AppendText("Test reparse file open exception:" + ex.Message, Color.Red); + } + finally + { + filterControl.ClearFilters(); + filterControl.SendConfigSettingsToFilter(ref lastError); + } + } + + public void StartFilterUnitTest() + { + try + { + + CleanupTestFolder(unitTestFolder); + + InitializeUnitTest(); + + MonitorFileEventsUnitTest(); + + FolderProtectionUnitTest(); + + AddProcessRightsUnitTest(); + + AddUserRightsUnitTest(); + + NoRenameAndCopyUnitTest(); + + FolderLockerUnitTest(); + + FileAccessControlUnitTest(); + + DeletionCallbackUnitTest(); + + ReparseFileOpenUnitTest(); + + ShowMonitorFileEventsUnitTestResult(); + + + + } + catch (Exception ex) + { + richTextBox_TestResult.Text = "Filter test exception:" + ex.Message; + } + } + + private void FileProtectorUnitTest_Activated(object sender, EventArgs e) + { + if (!isUnitTestStarted) + { + isUnitTestStarted = true; + + string lastError = string.Empty; + if (!filterControl.StartFilter(GlobalConfig.filterType, GlobalConfig.FilterConnectionThreads, GlobalConfig.ConnectionTimeOut, licenseKey, ref lastError)) + { + MessageBox.Show(lastError, "StartFilter", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + System.Threading.Thread.Sleep(3000); + + StartFilterUnitTest(); + + filterControl.StopFilter(); + } + + } + } +} diff --git a/Demo_Source_Code/CSharpDemo/FileProtector/ProtectorUnitTest.resx b/Demo_Source_Code/CSharpDemo/FileProtector/ProtectorUnitTest.resx new file mode 100644 index 0000000..60985f5 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FileProtector/ProtectorUnitTest.resx @@ -0,0 +1,570 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + AAABAAgAEBAAAAEACABoBQAAhgAAABAQAAABACAAaAQAAO4FAAAYGAAAAQAIAMgGAABWCgAAGBgAAAEA + IACICQAAHhEAACAgAAABAAgAqAgAAKYaAAAgIAAAAQAgAKgQAABOIwAAMDAAAAEACACoDgAA9jMAADAw + AAABACAAqCUAAJ5CAAAoAAAAEAAAACAAAAABAAgAAAAAAEABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP// + /wAygPwAvYp4AH/e/wD/3ZcAwMDAAHyX4QB2dXQA7trOAKCgoADhrooAjMXWAKHB/wCZhnMAvaySAP/3 + ywDxyIIA0tLSAJGQjQDMrqoA/9y4AK16cAD/8OEA0p+CAIqo3gD5xpYAhIJ9AOS8mACrq6sA3trEAPTd + qQD//+oA/+THAP/RhADEnIgA8tWYAP/npgD96NUAceH/APjouwA4jP8AxpN9AJmOgwCZl5QAqoF6AO26 + kAC1gnQA782QAIaHhwD/+vUAtKiXANmmhgD/1ZAAmLz/AMjBugD22qAAmpSLAP/uvQDQtLAA//bsAIuf + 3QDRzssA/+DAAPntwgCZiXoAfn5/AP/t2gD/584AOoX/APn5+QD+2Z0AnJycAHt5dQDguJUAsX5yAIam + 4gC5hnYAwY56APXClADxvpIA6baOAOWyjADdqogA///yAP7WmAD8/PwAqKioAJaPhwDw0JQA1tPPAJmM + fgDVooQAz8/PAMTBvgA2iP8A//jwAMmWfgD/69YA/+nSAJuSiADHnokAgYB/AI+OiwDCwsIA//37AP/+ + 7wD/7t0A/9qWAJmUjgCrqqgAd3d2ALOAcwC3hHUAmZCHANekhACFhYYA//v3AHt4cwCZi3wA/v7+APr6 + +gD+0IUAuod3AL6LeQDCj3sAxZJ8AJ2dnQDcqYcAw8C9AP/37wCAgIAAgoB+AK57cADV0s8AkpCNAMfB + ugAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAACNhfk4DTS9LFhQ9WIcAAGUJRkZ5VngBAQENRQRkAAAYAXJtLGhdARIZAicp + BwAAcwEXPGlXQgiDEwxfNjsAAIABcl5/DyJ6VTlnTAGFAAALAWsyhAUkMBFHMQEBcAAAUgErWnY6KB9Z + NW8SAXEAAFEBYmAbIGpAOGx0AXh7AAAuAXc3Ch5UECUzSAZWfAAAUAEhY4JuhElmHWl1eX0AAE8BDkFb + iGCGPoFtbUYqAAAaARU/IURiQ2sXFxdGYQAAHCYBAQEBAQEBAQEBCS0AAABKGk9QLlFSC1M0XC0AAAAA + AAAAAAAAAAAAAAAAAAD//wAAwAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAIAB + AACAAQAAgAEAAMADAAD//wAAKAAAABAAAAAgAAAAAQAgAAAAAABABAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAMuYf8zJln7/xZJ8/8GOev+9inj/uYZ2/7WCdP+xfnL/rXpw/8yuqv+Ln93/l5CI/Xdz + bH4AAAAAAAAAAM6bgMzu2s7/+fn5//n5+f/6+vr//Pz8//7+/v////////////////+hwf//OoX//3/e + //+dlIr+AAAAAAAAAADSn4L//////5mQh/+ZlI7/mZeU/8LCwv/Pz8///////9LS0v+KqN7/MoD8/3Hh + //84jP//fJfh/wAAAAAAAAAA16SE////////8OH///bs///9+/+oqKj/fn5//3Z1dP+AgID/kZCN/4zF + 1v82iP//mLz//9C0sP8AAAAAAAAAANyph///////mZCH/8TBvv+dnZ3/vayS///RhP/+0IX//taY/5qU + i/+Pjov/hqbi//////+ue3D/AAAAAAAAAADhror////////u3f//+vX/goB+///dl//y1Zj/782Q//HI + gv/+2Z3/hoeH////////////s4Bz/wAAAAAAAAAA5bKM//////+ZjoP/1tPP/3t4c///7r3/+Oi7//Td + qf/w0JT//9WQ/3d3dv/S0tL//////7eEdf8AAAAAAAAAAOm2jv///////+vW///48P+Egn3////q///+ + 7//57cL/9tqg///alv+FhYb///////7+/v+6h3f/AAAAAAAAAADtupD//////5mLfP/Iwbr/oKCg/97a + xP////L///fL///npv+0qJf/nJyc/8DAwP/8/Pz/vot5/wAAAAAAAAAA8b6S////////5Mf//+nS///3 + 7/+rqqj/goB+/3t5df+BgH//q6ur///9+///+/f/+vr6/8KPe/8AAAAAAAAAAPXClP//////mYZz/5mJ + ev+ZjH7/x8G6///48P/V0s//0c7L/8PAvf+ZlI7/mZSO//n5+f/Gk33/AAAAAAAAAAD5xpb////////c + uP//4MD//+TH///nzv//69b//+3a///u3f//8OH///Dh///w4f/5+fn/yZZ+/wAAAAAAAAAA88CTzP3o + 1f//////////////////////////////////////////////////////7trO/6p3bswAAAAAAAAAAAAA + AADuu5DM+caW//XClP/xvpL/7bqQ/+m2jv/lsoz/4a6K/92qiP/Zpob/1aKE/6p3bswAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAD//wAAwAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAMAD + AAD//wAAKAAAABgAAAAwAAAAAQAIAAAAAACgAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8AGVv/AK98 + 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 + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADJln6pyZZ+/8aTfP/EkXv/wY56/7+Mef+9inj/uod2/7iF + df+2g3T/s4Bz/7F+cv+vfHH/rHlv/6p3bv+odW3/qnp0/9TEyP+Jg3j/hICA+GNjYzgAAAAAAAAAAM6b + gKnZr5j/9eLU///27v//+vX///38//////////////////////////////////////////////////// + ////////9vf//wZF//9Oheb/5drP/357evkAAAAAAAAAANKfgv/24dD///Pn///27v//+vX///38//// + ///////////////////////////////////////////////////z9f//DEr//0ac//9k1///ZZ3p/4yH + gf8AAAAAAAAAANShg/////////Ll///17P+ZlZL/mZeW/5mZmf+ZmZn/mZmZ//////////////////// + //////////////Hz//8LSf//SaL//2/Z//9Xt///D1r//7+zv/8AAAAAAAAAANajhP////////Ll///0 + 6v//9/H///v4////////////////////////////+vr6//n5+f//////8fHw/4SCh/87jOH/bt3//1a0 + //8ZW///4+f//7KGgf8AAAAAAAAAANilhf////////Dj///06v+ZlI//mZaT/5mYl/+ZmZn/y8vL/7Oz + tf+ChYj/fXx5/358ev+ChIj/jo+Q/62qpf/Ax8L/QZrp/xRW///m6////////6l2bv8AAAAAAAAAANqn + hv///////+/g///z5///9ez///nz///8+v//////o6Wn/7Wrl//10JT/+9KT//vTmv/8153/wrWh/4CD + if/EwLv/goKQ/+nt/////////////6t4b/8AAAAAAAAAAN2qh////////+7e///w4/+Zkoz/mZSR/5yZ + lv/b29z/rKSS//zXmv/x0Zv/79CZ/+7Nkf/wz5f/+tef/7+znf+Ki4z/ysrI/////////////////657 + cP8AAAAAAAAAAOCtif///////+zZ///v4P//8+f///Xs///59f+UlJf/9Nii//Xdqv/x26r/8dup//DU + ov/v0Jf/8M6a//7ao/+PkZT//////////////////////7B9cf8AAAAAAAAAAOKviv///////+rX///u + 3v+ZkIj/mZKM/62ppf+AgH7//+i1//blvv/358D/9eK4//Pdsf/x1qX/8NCV//3apP+FhIL/2NjY//// + /////////////7J/cv8AAAAAAAAAAOSxi////////+nV///s2f//7+D///Ll///38P+Eg4L///PI//z1 + 3P/689b/9+zI//bnvf/z3K3/8NOe//7Zof+EhIP//////////////////////7WCdP8AAAAAAAAAAOaz + jP///////+fQ///q1/+ZjoT/mY+G/62nof+enp3/7+bF////8P/+/vz//Pbb//fsx//24bP/89ek//TY + pP+Rk5b//////////////////////7iFdf8AAAAAAAAAAOi1jv///////+XM///o0v//6tf//+7e///y + 5//z7OX/paOc////7P////f//fnl//nuzP/347b//+Gm/6Sdkv/b29z//////////////////////7qH + dv8AAAAAAAAAAOy5j////////+PJ///mzv+Zi37/mY6C/52Tif+tpp//vru5/6Khm//j3sL///zT///y + wv/p1av/oJuS/7Kztv+/v7//mZmZ/////////////////72KeP8AAAAAAAAAAO67kP///////+HF///j + yf//5s7//+nV///s2f//7+D///Pp//Lr5P+lpKT/gICD/4CCgv+ampz/5OPj///9/f////////////// + /////////////7+Mef8AAAAAAAAAAPC9kf///////9/A///hxf+ZiHn/mYt9///p1f+ZjoL/nZOJ/6ae + lv+tp6H/r6mk/62npP+jn53///nz/5mWk/+Zl5X/mZeW///9/P///fz///38/8GOev8AAAAAAAAAAPK/ + k////////928///fwP//4cX//+PJ///mzv//6NL//+rX///t3P//7+D///Dj///z5///9Or///Xs///2 + 7v//9/H///nz///69f//+vX///r1/8SRe/8AAAAAAAAAAPTBlP///////9u4///dvP+ZhnP/mYd2/5mI + ef+Zinz/mYt+///q1/+ZjoL/mY+F/5mPhv+ZkIj/mZKL/5mSjP+Zkoz/mZOO///27v//9u7///bu/8eU + ff8AAAAAAAAAAPbDlf///////9mz///buP//3bz//9/A///hxf//48n//+XM///n0P//6dX//+rX///s + 2f//7t7//+/g///w4///8uX///Ll///z5///8+f///Pn/8qXfv8AAAAAAAAAAPnGlv/+8eb//+7e///Z + s///27j//928///evv//4MP//+LH///lzP//5s7//+fQ///p1f//6tf//+zZ///t3P//7t7//+7e///v + 4P//7+D/9uDQ/8yZf/8AAAAAAAAAAPjFlj36ypz//vHm//////////////////////////////////// + ///////////////////////////////////////////////////338z/27KZ/8yZf6kAAAAAAAAAAAAA + AAD4xZY9+caW//fElf/1wpT/88CT//G+kv/vvJH/7bqQ/+q3j//otY7/5rOM/+Sxi//ir4r/4K2J/96r + iP/ap4b/2KWF/9ajhP/UoYP/0J2BqQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA////AMAAAwCAAAEAgAABAIAAAQCAAAEAgAABAIAAAQCAAAEAgAABAIAAAQCAAAEAgAABAIAA + AQCAAAEAgAABAIAAAQCAAAEAgAABAIAAAQCAAAEAwAABAOAAAwD///8AKAAAACAAAABAAAAAAQAIAAAA + AACABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8ANF/oAMCNeQBt2f8ATVNaAPvboQB5pLUAxsjQAEtw + qgBfiP8AeX6EAK6ppADksYsA+O/PAKBuagBNsfgAmZONADqL/wBkZ20A2cmkAN3d3QDi270AUG7oAMie + kADNtLUA8sqLAIqTpAA8b/8A7u3sAJmGdAD/3r4AW3KXAF/A/wC1t7gArqKNALB9cQD//N8A79vRAJ2d + nQDXpIQA69GeAIiKjgDu8f8AKnb/AOe9nwDEwr8A7tuwAL2yogD/9+8A4cKQALWRhQDx5cEAzZp/APvI + lwDW1NIA/+3cAPG+kgCJh4EAkZOXAP3rvAD/5MoAOmfxAOLRqgCZjIAA2byhAM/LxwDi2dIApKWpAMa2 + wwDhyZoAsKmYAPLVpwCodW0AVrT/AODm5ACysK8A9dKaAPb29gD39+cA99+rAIGEiQBYgP8A6uHYALeE + dACZl5UA6saPALKWjQD/6NMA9+S6AP/y5AD10JEA/PTWAFBw8QDpzJYA/v7yAMaTfADqt44A3quIALy9 + vQBEc/8Aj4+PANnFmgD/8MMA6OjoAPTpygCemYwArn95AMnHxQBLrf8A8NeeAPfw2wAwevwASqv0AKGg + owD1wpQA7s2QANHPzQCzrJ4A8+CyAPHbqQDl3sMA0Z6BAKmqqgDv0JkA8tCfANrZ2AD7+/sA//bcAP/i + xQCZj4YAsqeSAOzXqgBauP8AaNX/APruyQDz8O4AiIiHAMrLywD28NYApHFrAKx5bwDlx5YAgIKFAPbb + sQDj2LgAq6GSAJmJeQDg4OEAtbS0APbnwADCwsMA//TqAPbpxQCRj4oAjZCWAJOSkQDv3rUA7telAOfN + oACrpqEA//v3APDivQDv0qMAoJ6ZAD6O/wDx9P8A+vjjAPXrzwCelpAA9NWgAHZ7ggCEh4wAuod2ANuo + hgC/v8AA78iLAPPcrQDmyZoAzcfCAK6urgBbhv8A//36AP/w4QD/69cA/+bOAPLnxQCZlZEAmZmZAOnO + mgDNzc0A+/vyALOAcgCEiJAAvot4AMOQegD4xZUAypd+ANShgwDtupAA57SMAOKvigDT0dEA+/v/AO/a + zgDFxcUAQHD/AFy+/wD/3LkA9cyRAC96/wCKjJEA8NOeAJubmwCenqIAyMjJAP/48gD6+uUA/+DCAPfd + qADx1aIAo6OmAK+wsQD5+fkAjo6NAJGRkgD35r4A4MidAMzKyAA7j/8AbNb/APfx2ACZi30A+e7MAJmO + gwCZkYkA892wAO/PlQCmc2wAqnduAK57cAC1gnMAl5OKAPPAkwDPnIAA7MiOAPLTpADu0qAA0M7MAP/y + 6AD06ccA9NOcAO7KjQDv3LMA8NCdAO/OmgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADrg4QAAAAAAM1Tx8cAkJCTw8I2N70lJ7u6MjA8PDxkXG7OJ + ZQAAADMYJtihAQEBAQEBAQEBAQEBAQEBAQHLCixtS0LgAAAAwsyY2KEBAQEBAQEBAQEBAQEBAQEBy7XS + SobPtJoAAAADAZjYobYBAQEBAQEBAQEBAQEBActS0oXmIeU+pAAAAMMBmDFVVby8Aby8vLy8vLy8AQEd + XXCF5iGlHEUAAAAAYAGYMbtVvLwBvLwnlc2+is0Bf/IgcQTPpc4rawAAAADFAZgx2KEBAQEBAU4i08HB + Ud5o4EMHEBJkpgHvAAAAAMUB+Zi7VVW8vJVjq4OOGtF9MAXhHVMJAqYBAY0AAAAANQFamLu7Vbx7r48y + GvVW/qOw/xPVnGoIAQEBJAAAAAD0AVqYmNihAd8qsk18fHx0sPaqfQUVaAEBAQHAAAAAAHoBt/kRu1VM + iiP7KSlI3NR8/EhbdpcBAQEBAfEAAAAAxgG3WhG7uy5EZp6EhOyxeNx8dJCjOwEBAQEBVAAAAAAoATi3 + +ZgxtjtQ4uKZlll3eNztSE2bAQEBAQGtAAAAAK4BOLfrERHkm7HpqGm6ov2EeF73TazXvAEBAcIAAAAA + rgG4OILrES5EFIDnT2/6NC+xvfefKq+8AQEBAwAAAABiAVi4OLf5MX5HJV+2X1wOWezcBpLXAQEBAQHD + AAAAAMkBWLjqguv5+HIW2b9Pi+mdhG5GC38BAQEBAWAAAAAADQG5WEDqglqgN9V5p6eLh3fb44+vAQEB + AQEBYAAAAADIAT25WLg4t1oxiN12kWc8P0eslAEBAQEBAQHFAAAAAGEBPT3oQOrqgusM+MrWKqw7e74B + vLy8vAEBATUAAAAAYQGBPZPoQOrqguupMWx1dWyVJwG8vLy8AQEBNQAAAADHAdqBPblYWLg4t1r5mJgx + 2KGhobYBAQEBAQF6AAAAADkBH9qTk5PoQLjqgoLrEZi7u7u7VVVVVbYBAcYAAAAA8wHQHx6Tk5PoWEDq + goLr+REREbu7u7tVoaGhKAAAAABzAbnQH9qBPT25WLi4OLe3WvmYmJgxMTHY2NgoAAAAAMQB2LnQH9qB + PT25WFi4ODi3t1pa+ZiYmJiYJq4AAAAAQTYBAQEBAQEBAQEBAQEBAQEBAQEBAQEBtswtVwAAAAAAQTY2 + xMTEc/Pz8zk5x8fHx2FhYcjIDQ0NyVcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/////////+PgAAABwAAAAcAAAAHAAAABwAAAA8AA + AAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AA + AAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPgAAAH//////////8oAAAAIAAAAEAAAAABACAAAAAAAIAQ + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAHVvWSSGhH3maWhndGJiYl6EhIQCAAAAAAAAAAAAAAAAAAAAALqHdrW2g3T/tYJz/7SB + c/+zgHL/sX5y/7B9cf+vfHH/rntw/616cP+seW//q3hv/6l2bv+odW3/p3Rt/6ZzbP+lcmz/pHFr/6Nw + a/+hbmr/oG1p/6Bua//NtLX/UG7o/4qTpP/Nx8L/iIiH/2NjY2kAAAAAAAAAAAAAAAC6h3a1yJ6Q/+/b + 0f//+PL///v3///+/f////////////////////////////////////////////////////////////// + /////////////////////////Pz//1+I//8qdv//S63//+Dm5P/Py8f/aGhoeQAAAAAAAAAAAAAAAL6L + eP/v2s7///Xs///48v//+/f///79//////////////////////////////////////////////////// + //////////////////////////////v7//9bhv//Lnn//1a0//9o1f//W73//66urv+MioTTAAAAAAAA + AAAAAAAAwI15///+/v//9ez///jy///79////fv///////////////////////////////////////// + ///////////////////////////////////6+///WID//y97//9Zt///bNb//1/A//87j///Omfx/4V/ + clcAAAAAAAAAAAAAAADDkHr////////06v//9/D/mZaT/5mYl/+ZmZn/mZmZ//////+ZmZn/mZmZ/5mZ + mf+ZmZn/mZmZ/5mZmf+ZmZn/mZmZ////////////7u3s/1Bw8f8wevz/Wrn//2zW//9ev///Po7//zxv + ///GtsP/AAAAAAAAAAAAAAAAAAAAAMaTfP////////Pp///27v+ZlZL/mZeV/5mZmf+ZmZn//////5mZ + mf+ZmZn/nZ2d/7W1tf/FxcX/zMzM/8vLy//ExMT///////r6+v+Xk4r/W3KX/0qr9P9t2f//Xb7//z2N + //9AcP//7vH//65/ef8AAAAAAAAAAAAAAAAAAAAAyZZ9////////8+n///bu///48v//+/f///79//// + ///////////////////29vb/tbe4/4qMkf+EiJD/hIiP/4GEif+vsLH/6Ojo/46Ojf/i2dL/eaS1/02x + +P86i///RHP///Dz////////qndu/wAAAAAAAAAAAAAAAAAAAADKl37////////y5///9ez/mZWR/5mW + k/+ZmJf/mZmZ/5mZmf+0tLT/vL29/3Z7gv+yp5L/5ceW//HJjP/1zJH/8c+f/72yov9NU1n/kJCS/+7t + 7P/q4dj/S3Cq/zRf6P/y9P////////////+seW//AAAAAAAAAAAAAAAAAAAAAMyZf/////////Ll///0 + 6v+ZlJD/mZWS/5mXlf+ZmZn/qqqq/7+/wP+Agob/4cKQ//LKiv/syI7/6saP//DQnf/v06P/8MeK/+/O + mv9kZ23/mpuc/5OSkf+emYz/xsjQ/////////////////698cf8AAAAAAAAAAAAAAAAAAAAAz5yA//// + ////8eP///Pp///17P//+PL///v3///+/f/5+fn/h4uP/+bJmv/105n/79Ca/+/Qmf/vz5j/7s2Q/+7I + i//y06T/9NWg//LQn/9NUlr/3d3d/+jo6P//////////////////////sn9y/wAAAAAAAAAAAAAAAAAA + AADRnoH////////w4f//8uf/mZKM/5mUkP+ZlpP/srCv/8nKy/+uoo3/9NOc/+vQnv/q0p7/8dam//HV + ov/w057/79CY/+7Kjf/y1Kf/9dCR/7Ornf/CwsP///////////////////////////+0gXP/AAAAAAAA + AAAAAAAAAAAAANShg////////+/g///x4/+Zkoz/mZSP/5mVkf/DwsD/o6Wp/9nFmv/u16X/7Nep/+zX + qv/z3bD/89yt//Hbqf/w1KH/79Ca/+7Mj//227H/79Gj/5CSlv///////////////////////////7eE + dP8AAAAAAAAAAAAAAAAAAAAA16SE////////7dz///Dh///y5///9Or///fw///8+v+Qk5f/99+r//fm + vf/25r7/9unF//bnwP/35Ln/89+x//Hbqf/w1KH/78+V//LWqP/205r/jJCV//////////////////// + ////////uod2/wAAAAAAAAAAAAAAAAAAAADap4b////////s2v//7+D/mZGI/5mSjP+Zk47/zMrI/46Q + lv/13a7/+e7M//Xrz//06cr/8ufF//Divf/v3LP/7Niq//Hbqf/pzJb/7dGg//XRm/+EiI3/yMjI/5mZ + mf////////////////+9inf/AAAAAAAAAAAAAAAAAAAAANyph////////+rW///t3P+ZkIf/mZGJ/5mS + jP/Ewb7/pKWo/9nJpP//9tz/9/HY//f25//38Nv/9OnH//Hlwf/u27D/8tus/+nOmv/v0qD/582g/4mK + jv+/v7//mZmZ/////////////////7+MeP8AAAAAAAAAAAAAAAAAAAAA3quI////////6dX//+vY///u + 3v//8OH///Ln///37//a2dj/sKmY///83//+/fH//v36//7+8//89Nb/+O/P//bku//z3a//8dak//vb + of+roZL/x8jJ////////////////////////////wo96/wAAAAAAAAAAAAAAAAAAAADhror////////n + 0f//6tb/mY6D/5mPhv+ZkYj///Lo/9DNy/+hoKP/4tu9//r65f/7+/L/9/fn//Xw1//47sz/7961/+zX + qf/w157/4cma/3l+hP/7+/v////////////////////////////Fknv/AAAAAAAAAAAAAAAAAAAAAOOw + i////////+bP///o0/+ZjID/mY6E/5mPhv//8uX/q6ah/9bU0v+bm5r/5d7D//n54//69+P/9vDV//ru + yf/z4LL/992o/+DInf+AgYT/wMDA/////////////////////////////////8eUfP8AAAAAAAAAAAAA + AAAAAAAA5rOM////////5cz//+bP///p1f//69j//+3c///w4f//8uX///bv//Pw7v+jo6b/sq2e/+PY + uP//8MP//eu8/+LRqv+wqJf/hYiM/+Dg4f//////////////////////////////////////ypd+/wAA + AAAAAAAAAAAAAAAAAADpto3////////jyP//5cz/mYt9/5mMgP+ZjYL/mY6E/5mQh/+ZkYn/rqmk/9DO + zP/T0dH/np6i/4iKjv+Ehoz/kpSY/6ipqv/Nzc3//////5mZmf+ZmZn/mZmZ/5mZmf////////////// + ///MmX//AAAAAAAAAAAAAAAAAAAAAOu4jv///////+HE///kyv+ZiXv/mYt9/5mMgP+ZjYL/mY6E/5mQ + h/+ZkYn/npaQ///38P/JxsT/0c/N/9HPzf/Ix8X/tbSz/52cnP//////mZmZ/5mZmf+ZmZn/mZmZ//// + /////////////82af/8AAAAAAAAAAAAAAAAAAAAA7bqQ////////38H//+LG///kyv//5c3//+fR///p + 1f//69j//+3c///v4P//8eP///Ln///06v//9ez///fw///48v//+vX///v3///8+f///fv///79//// + ////////////////////////0J2B/wAAAAAAAAAAAAAAAAAAAADwvZH////////dvf//4ML/mYh3/5mJ + ef+ZiXv/mYt9/5mMgP//69j/mY6E/5mPhv+ZkIf/mZGJ/5mSjP//9Or/mZSP/5mUkP+ZlZH/mZWS/5mW + k/+Zl5T/mZeV/5mYl////fv///79///+/f/ToIL/AAAAAAAAAAAAAAAAAAAAAPPAk////////9y5///e + v/+ZhnT/mYh3/5mJef+ZiXv/mYt9///p1f+ZjID/mY6D/5mPhf+ZkIf/mZGI///y5/+Zkoz/mZKM/5mT + jv+ZlJD/mZWR/5mVkf+ZlZL/mZaT///79///+/f///v3/9ajhP8AAAAAAAAAAAAAAAAAAAAA9cKU//// + ////5s3//9y5///ev///4ML//+LG///kyv//5cz//+bP///o0///6tb//+vY///t3P//7+D///Dh///x + 4///8uf///Pp///06v//9ez///bu///27v//9/D///jy///48v//+PL/2KWF/wAAAAAAAAAAAAAAAAAA + AAD4xZX////////48v//5s3//9y5///dvf//38H//+HE///jyP//5cz//+bP///n0f//6dX//+rW///s + 2v//7dz//+/g///w4f//8eP///Ll///y5///8+n///Pp///06v//9ez///Xs/+7a0f/bqIb/AAAAAAAA + AAAAAAAAAAAAAPvIl4/6x5b///////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////9+//u2s3/572f/7aD + dI8AAAAAAAAAAAAAAAAAAAAAAAAAAPvIl4/7yJf/+seW//nGlv/4xZX/98SV//XClP/0wZP/88CT//K/ + kv/xvpL/8L2R/+67kP/tupD/7LmP/+y5j//ruI7/6reO/+m2jf/ntIz/5rOM/+Wyi//ksYv/47CL/+Kv + iv+2g3SPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/////////j4AAAAcAAAAHAAAABwAAAAcAA + AAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AA + AAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAAD4AAAB///////////KAAAADAAAABgAAAAAQAIAAAA + AACACgAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8AIVXwAMGOeQBt2f8ATE1PAPvboQCLldIArb3/ADhm + uQBfiP8AeX6EAK2qpwDlsosA+/DSAKBuagBNsfgAmZWLADmJ/wBnaGkA2cmkAOLe2gDi270ATInRAMai + kQDNtLUA8sqLAHWCtQA8b/8A7+3rAIV7awD/3r4AW3KXAGHE/wCytL8AqaCNALB9cQD//eMA79vRAJ2d + nQDXpIQA6tCfAIqLjQDb4f8AImT/AOzDnADEwr4A8deuAL+0oQD/+e4A376KALiLgQDu5MEAzZp/APvI + lwDY1tQA//HbAPG+kgCFgHgAkpOWAPzrvQD/6cgANHHqAOLRqgCZjIAA1b6jAM/LxwDi2dIApaepALyr + vwDhyZoAsqmZAPHWqACodW0AVrT/AODm5ACysa4A9dOaAPb29gD49usA99+rAIGEiQBYgP8A6uHYALaD + dACYl5cA6MSKALKWjQD/7dEA9uS4AP/05AD00JEA/ffXAFBw8QDpy5YA/f3vAMeUfQDqt44A36yIAL28 + uQBEc/8AkZCNANbAmAD/8MMA6eflAPPmzACemYwArn95AMfGxQBMpv8A8NeeAPby3QAweOgAWqjPAKGh + oQD2w5QA7sySANHPzQC4r5sA9uCyAPHaqADl3sMA0Z6BAKqpqADv0JgA8NCgANrZ2AD7+/sA+/bdAP/o + wwCZj4YAu66VAOvWqwBeuO8AZs7/APvvygDz8O4AiIeHAMrLywD07dcApHFrAKx5bwDnyZMAgYGCAPbb + sQDi07cArKSUAJmJeQDk4d8AtbSzAPfowADCwsMA//bpAPfqxQCRj4oAjZCWAJSUlADu37cA7talAOjO + oACopaEA//z3AO/jvQDt06MAop+aAESa/gDx9P8A/fniAPTq0gCdmJAA9tegAHd3eQCEh4wAuod2ANuo + hgC/v8AA7cSEAPPcrQDmyZoA18y8ALCurABbhv8A//37AP/y4AD/7tUA/+vMAPHnxgCalpEAmZmZAOjN + mwDNzMwA+fnwALOAcgCDiY8Avot4AMOQewD4xZUAyZZ9ANWigwDuu5AA57iDAOKvigDT0tEA+/v/AO/a + zgDFxMMAQHD/AF2//wD/3LkA9cyRAC54/wCKjJEA8NOeAJubnACfn6AAyMjJAP/68wD9+ucA/+DCAPfd + qADx1aIApaSkAKmtvwD5+fkAjIyMAJGRkQD25b4A4MidAMzKyAA7j/8Af8buAPb01wCZi30A+u7OAJmO + gwCZkYkA8tywAO/NlQCmc2wAqnduAK57cAC0gXMAl5WLAPTBkwDPnIAA7smQAPLTpADu0qAA0M7MAP/y + 6AD06ccA9NOcAO7KjwDw27MA79GcAO/OmgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI+PAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKu0j4+rAAAAAAAAABh6enp6 + enp69PT09PT0NTU1NTXFYGDDwwPCwq2tVPHAJDNFAj57lJyPAAAAAAAAGHqRWlpamJiYmJgxMTExMdjY + 2KGhoaG2trYBAQEBAQEBASsCLKWFlGiPAAAAAAAYemlaWlpamJiYmJgxMTExMdjY2KGhoaG2trYBAQEB + AQEBKwIspc+G5i5M4QAAAADGqDFaWlpamJiYmJgxMTExMdjY2KGhoaG2tra2AQEBAQErAiylIYYhbRep + jwAAAADGAbdaOjo6Ojo6Ojo6OjExOjo6Ojo6Ojo6Ojo6j4+JvCIC0qUhhiFtEiwbAAAAAAAoAbdaOjo6 + Ojo6Ojo6OjExOjo6Ojo6Ojo6Ojo6j4ne3gLSbSGGIW0SLAcAAAAAAAAoAbdaOjo6Ojo6Ojo6OjExOjo6 + Ojo6Ojo6Ojo6ibSaCQKlIYYhbRIsCBgAAAAAAAAoAbdaWlpaWpiYmJiYMTExMTHY2KGhtra2tra2Ab5V + ZQmFhiFtEiwIASQAAAAAAACuAbe3WlpaWpiYmJiYMTExMTHYoconqxMTq7w3AR2PvntxhW0SLAgBAcAA + AAAAAACuAbe3Ojo6Ojo6Ojo6Ojo6OqC0q6u8MEFBMNYTExOcIgFEF3ACBwEBAfEAAAAAAACuAbe3Ojo6 + Ojo6Ojo6Ojo6DHITpDKwsFYyyMifTAXgHb43wQIHcgEBAVQAAAAAAABiAbe3Ojo6Ojo6Ojo6Ojqg3auD + sFbt7VZeKSlWyLMFnHLh3Tu0iQEBAa0AAAAAAABiAbe3t1paWlqYmJiYmDGUq3Zb7e3t7XT8sF4vo7Cz + BRPKTGgBAQEBAa0AAAAAAABiAbe3t1paWlpamJiYmNjWqU3+1NTU/nx8dPz1L9ywe4kBAba2tgEBAcIA + AAAAAABiAbe3Ojo6Ojo6Ojo6mpWPZl7cnr2fvb1ejnx09ex0hBMdtra2tra2tsIAAAAAAADJAbe3Ojo6 + Ojo6Ojo6pHKa/imxsaOjKZ+9vdTtdH1IsDsitra2tra2tgMAAAAAAADJAbe3Ojo6Ojo6Ojo6tLwjo4R3 + d4SEhISjKdzU7XT9sHactra2tra2tsMAAAAAAAANATi3t7e3WlpaWlqY2N2Dd1lZmZmZ4ll3sXjc/nRI + 7TCJtqGhoaGhocMAAAAAAAANATi3t7e3WlpaWlqY2N12WZkO6emHmZZZd+xI1O1I7TCJtqGhoaGhoWAA + AAAAAADIATg4Ojo6Ojo6Ojo6TN2SPGmLqKhpuqKdhIR43I4pVke8ezo6OqGhoWAAAAAAAADIATg4Ojo6 + Ojo6Ojo6pEyaPKhvb09PqLo0nYSxSF4pVipjpDo6OqGhocUAAAAAAADIATg4Ojo6Ojo6Ojo6mmM7kahv + v7+/i2m6nYTseF69ZhNoiTo6OtjY2DUAAAAAAABhATg4ODi3t7e3WlpaWjFsEVynX6FfgFwOllnseNxN + u1Wh2NjY2NjY2DUAAAAAAABhATg4ODi3t7e3t1paWpgdRDAl2THZp4DpllmxeKowE2jY2NjY2NjY2DUA + AAAAAABhATg4Ojo6Ojq3tzo6OjqgzSd2529vgGmi/YSeKUeroKQxMTExMTExMTUAAAAAAADHATg4Ojo6 + Ojq3tzo6Ojo6tM3d8pGZh6Kd7Hhmu6vdDDoxMTExMTExMTUAAAAAAADHAbg4Ojo6Ojq3tzo6Ojo6OqAu + lZyaR3YwkpqPiUygOjoxMTExMTExMfQAAAAAAADHAbg4ODg4ODi3t7e3t1paWlqYMRUue9W8J0w32DGY + MTExMTExMTExMfQAAAAAAAA5Abi4ODg4ODg4t7e3t7daWlpaWpgx2NjY2DExmJiYmJiYMTExMTExMfQA + AAAAAAA5AVi4Ojo6Ojo6Ojo6Ojq3Wjo6Ojo6Ojo6Ojo6OjqYmDo6Ojo6OpiYmPQAAAAAAAA5AVi4Ojo6 + Ojo6Ojo6Ojq3tzo6Ojo6Ojo6Ojo6OjqYmDo6Ojo6OpiYmPQAAAAAAADzAblYOjo6Ojo6Ojo6Ojq3tzo6 + Ojo6Ojo6Ojo6OjqYmDo6Ojo6OpiYmPQAAAAAAADzAblYWLi4ODg4ODg4OLe3t7e3t7daWlpaWlpaWlpa + mJiYmJiYmJiYmHoAAAAAAABzAbm5WFi4uDg4ODg4ODg4t7e3t7e3WlpaWlpaWlpaWlpaWlqYmJiYmHoA + AAAAAADEAT25Hh46Ojo6Ojo6Ojo6Ojo6Ojo6t7c6Ojo6Ojo6Ojo6Ojo6OlpaWnoAAAAAAADEAT09Hh4e + Ojo6Ojo6Ojo6Ojo6Ojo6t7c6Ojo6Ojo6Ojo6Ojo6OlpaWnoAAAAAAADEAYE9Hh4eHjo6Ojo6Ojo6Ojo6 + Ojo6t7c6Ojo6Ojo6Ojo6Ojo6OlpaWnoAAAAAAAA2AYGBPT25uVhYuLi4ODg4ODg4ODg4t7e3t7e3t7e3 + t7daWlpaWlpaWnoAAAAAAAA2WjiBgT09ubm5WFi4uLg4ODg4ODg4ODi3t7e3t7e3t7e3t7e3t7e3kXoA + AAAAAABBNlo4gYGBPbm5uVhYuLi4ODg4ODg4ODg4ODi3t7e3t7e3t7e3tzFpehgAAAAAAAAALTZaAQEB + AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAah6GAAAAAAAAAAAAEE2NsTExHPz8zk5OcfHx2Fh + YcjIyA0NycliYmJirq6uKCgoxsYYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///////8AAP// + ////nwAA//////+DAAD4AAAAAAMAAPAAAAAAAwAA4AAAAAABAADgAAAAAAEAAOAAAAAAAwAA4AAAAAAH + AADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAA + AAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAH + AADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAA + AAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAH + AADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAPAAAAAADwAA+AAAAAAfAAD///////8AAP// + /////wAA////////AAAoAAAAMAAAAGAAAAABACAAAAAAAIAlAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI6MgwJycm/BcnJyu2Rk + ZChmZmY0V1dXAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQ3 + +CN7e4P+sK+t/4CAgP6CgoL/bW1twmxsbAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADPnICj0J2B/9Cd + gf/QnYH/0J2B/9Cdgf/QnYH/0J2B/8+cgP/PnID/z5yA/86bgP/Om4D/zpuA/82af//Nmn//zJl//8yZ + f//MmX//yZZ9/8iVff/Gk3z/xJF7/8KPev/Bjnn/vot4/72KeP+7iHb/uYZ1/7aDdP+0gXP/s4By/7B9 + cf+4i4H/vKu//yJR9f80cer/q6in/+Hg3/+UlJT/hISE/2VlZUsAAAAAAAAAAAAAAAAAAAAAAAAAANKf + gszQnYH/7tS////04///9OT///Xl///15///9ej///bp///26v//9+v///fs///47f//+O7///nv///5 + 8P//+fL///rz///69P//+/X///v2///89////Pj///z5///9+v///fz///79///+/v////////////// + ///////////////////d4///KFn//ytz//9CmP//aLTo/+bh3//m5eT/goKC/mVlZUAAAAAAAAAAAAAA + AAAAAAAA06CCo9Gegf/24s7///Pi///04///9OT///Xl///15///9ej///bp///26v//9+v///fs///4 + 7f//+O7///nv///58P//+fL///rz///69P//+/X///v2///89////Pj///z5///9+v///fz///79///+ + /v///////////////////////////9vi//8nWv//LHX//0OZ//9dv///ZM7//3/G7v/Hwr7/s7Kx/nR0 + dHsAAAAAAAAAAAAAAAAAAAAA1KGD//Xl2P//+O3///Pi///04///9OT///Xl///15///9ej///bp///2 + 6v//9+v///fs///47f//+O7///nv///58P//+fL///rz///69P//+/X///v2///89////Pj///z5///9 + +v///fz///78///+/f//////////////////////2N///ydY//8tdv//RJn//17A//9nzv//Y8j//0yq + //9XitP/npmS/3l5edwAAAAAAAAAAAAAAAAAAAAA1aKD////////8+H///Pi/4V/dv+Ff3f/hYB3/4WA + eP+FgHn/hYB6/4WAev+FgXv/hYF7/4WBfP//+O7///nv/4WCff+Fgn7/hYJ+/4WCf/+Fg4D/hYOA/4WD + gf+Fg4H/hYOC/4WEgv+FhIP/hYSD/4WEhP+FhIT/hYWF/5iYmP+jq8z/H1P5/y53//9GnP//X8H//2fO + //9ix///T6n//zqL//8XW/7/QFi8g3Fway4AAAAAAAAAAAAAAAAAAAAA1qOE////////8+H///Pi/4V/ + dv+Ff3f/hX93/4WAeP+FgHj/hYB5/4WAev+FgXv/hYF7/4WBfP//+O7///jv/4WCff+Fgn7/hYJ+/4WC + f/+Fg4D/hYOA/4WDgP+Fg4H/hYOC/4WEgv+FhIP/hYSD/4WEhP+Lior/sbGx/6GozP8cS+f/Lnn+/0ed + //9fwv//Z87//2LG//9OqP//OYr//x1c//+Hi9H/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA16SE//// + ////8+H///Pi/4V/dv+Ff3f/hX93/4WAeP+FgHj/hYB5/4WAev+FgXv/hYF7/4WBfP//+O7///jv/4WC + ff+Fgn7/hYJ+/4WCf/+Fgn//hYOA/4WDgP+Fg4H/hYOB/4WDgv+FhIL/hYSD/4uKif+vrq7/kpCM/yxM + sf8nauD/R5z8/2DE//9nzv//YcX//06n//85if//HVr//6e5///Gopr/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA2KWF////////8+H///Pi///z4v//9OT///Tl///15v//9ef///bo///26f//9ur///fr///3 + 7P//+O7///jv///57///+fD///ny///68///+/b///z4///9+v///fv///37///9+////vv///37///9 + /f/Nzcz/mZiX/5GQjf9Df8H/Wrny/2jP//9hxf//Tab//ziI//8cW///rb3///////+wfXH/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA2aaG////////8+D///Ph///z4v//9OT///Tl///15v//9ef///Xo///2 + 6f//9ur///fr///37P//+O3///ju///57///+fD///rz//369v/U0tD/np6c/3l6ev9naGn/Zmdo/3Z2 + dv+amZn/19bU///+/f/v7u3/g4OD/83My/+rrKr/WqjP/1m79P9Lpf//OIb//xxZ//+ywf////////// + //+zgHL/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA26iG////////8uD///Ph/4V/dv+Ff3b/hX93/4WA + d/+FgHj/hYB5/4WAev+FgHr/hYF7/4WBe/+FgXz/hYF8/4WBff+npaL/r66s/3R0df9wcnT/mpqZ/7+z + o//OvqT/0b+n/8G4qP+dnqH/YmVn/2VlZv9nZ2f/lJSU/7m5uf/+/f3/pKiq/0GIz/8weOj/GVHy/4ua + 0/////////////////+0gXP/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3KmH////////8uD///Ph/4V/ + dv+Ff3b/hX93/4V/d/+FgHj/hYB4/4WAef+FgHr/hYB6/4WBe/+FgXv/hYF8/66rqP+goJ//bm9y/6Gd + lf/YvI//8MaF/+/Iiv/nw4b/5sCF/+e9fv/mu3X/6cyi/7Gvrf9KS03/jIyM/+3t7f/MzMz/2NbV/4OJ + j/8YRsr/j5vS/6Kiov////////////////+2g3T/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3aqH//// + ////8uD///Ph/4V/dv+Ff3b/hX93/4V/d/+FgHj/hYB4/4WAef+FgHr/hYB6/4WBe/+FgXv/pqOf/6Wk + o/92eHv/u6yU/+nChf/nxIj/7syU/+7LlP/nxo//6cmU/+vPoP/rzqD/58KJ/+a6d//Wy7v/TlFT/5SU + lP+goKD/kZGR/6Skof+TlJb/r66u/4WFhf////////////////+5hnX/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA3quI////////8t////Pg///z4f//8+L///Tj///05P//9eX///Xn///16P//9uj///bp///3 + 6///+O7/5uPf/3l6fP+8rpb/9NCR/+/OlP/vzpX/7s6U/+7NlP/uy5L/7sqP/+3Hi//tzJf/8deu//DS + ov/swHv/1829/0tMTv9jY2P/0dHR/7GxsP/o5+f///79///+/f///v7///7+///+/v+7iHb/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA36yI////////8t////Lg///z4f//8+L///Tj///05P//9OX///Xm///1 + 5///9uj///bp///26v//+vP/oJ+f/5uWjv/21Jn/8NGc//DSnf/w0p3/8NKd//DRnP/v0Jn/79CY/+7N + kv/uyo//7cmP//HXrv/x06L/7sJ//6iopv+GhYb///79///+/f///fz///78///+/P///v3///79///+ + /f+9inj/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4K2J////////8t7///Lg/4V/df+Ff3X/hX92/4V/ + d/+Ff3f/hYB3/4WAeP+FgHn/hYB6/5GNiP+3tbP/f4GE/9W9kv/ozJj/8daj//HYpP/nz5z/58+d/+fN + nP/nzJn/58qV/+bIkv/vz5j/7suQ/+7JkP/y27H/7sqT/+zSq/9cXmH/7ezq///9+v///fv///37///9 + /P///fz///38///9/P++i3j/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4a6K////////8t7///Lf/4V+ + df+Ff3X/hX92/4V/dv+Ff3f/hX93/4WAeP+FgHj/hYB5/6WhnP+joqH/kI2J/+7RnP/o0J//8tus//Pc + rP/q06P/6tOj/+nSov/o0KD/58+c/+fMmf/w0p3/78+X/+7Lkf/w0KD/8NWr/+7Eg/+QkZX/urm4///9 + +v///fr///36///9+v///fr///36///9+v/Bjnn/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4q+K//// + ////8t7///Lf/4V+df+Ff3X/hX92/4V/dv+Ff3f/hX93/4WAd/+FgHj/hYB5/7Guqv+ampn/qaCN/+7T + o//s1aj/9eCz//Xgs//r16z/69is/+vXqf/q1af/6tOj/+jQn//x1qT/8NKd/+/Pl//vzJL/8tmz/+/I + iv+zrKL/lZSU///9+v///Pn///z5///8+f///Pn///z5///8+f/Cj3r/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA5LGL////////8d3///Le///y3///8+D///Ph///z4v//9OP///Tk///05f//9eb///Xn///6 + 8v+jo6P/uq+V//fhsf/25bz/9uW8//bpxf/368f/+OrE//blvv/247f/9eCy//Pdrv/x2aj/8dah//DR + nP/uzpL/8ter//DMlP/HuaX/hYSF///9+v///Pf///z4///8+P///Pj///z4///8+P/EkXv/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA5bKL////////8d3///Le///y3///8uD///Ph///z4v//8+L///Tk///0 + 5f//9eX///Xn///58f+mpqX/ua6W//jktv/36cT/++/S//vuzv/47s3/+O3K//fqxf/36b//9uO4//Xg + s//z3K//8dim//DTnv/vz5f/8dWn//DNlf/EtqL/hoaG///8+f//+/b///v3///89////Pf///z3///8 + 9//Gk3z/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA5rOM////////8dz///Hd/4V+dP+FfnT/hX91/4V/ + df+Ff3b/hX92/4V/d/+Ff3f/hYB4/7Kvqv+mpqX/rKOT//rpuv/x58n/9OvV//Tqzf/y68//8+jL//Dn + xP/u4r7/7d+5/+vYrv/q1af/8tqp//HWpP/nyZP/686f/+rHjf+vp5r/mZmY/6upp/+Fg4D/hYOA/4WD + gP//+/b///v2///79v/IlX3/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA57SM////////8dz///Hd/4V+ + dP+FfnT/hX51/4V/df+Ff3X/hX92/4V/dv+Ff3f/hX93/6ainP+ysa//k5GN//3twP/07NH/9fHd//Xx + 3v/49+z/+PXp//Przv/w5sb/7uTB/+3dtP/r2Kz/89ys//HXpf/nypX/6tCf/+nEif+Ki43/u7q4/5+c + mv+Fg4D/hYOA/4WDgP//+/X///v1///79f/Jln3/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA6LWN//// + ////8dv///Hc/4V+c/+FfnT/hX50/4V+df+Ff3X/hX92/4V/dv+Ff3f/hX93/5KOhv++vbr/k5SX/9/U + sv/07dH/9/Pg//n47v/6+vL/+fnw//Tv2P/x6cz/8ufH/+7et//r2Kz/892v//Hap//nypb/6c2a/9fA + mf9rbG//7Onn/42Kh/+Fgn//hYJ//4WCf///+vT///r0///69P/MmX//AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA6baO////////8Nv///Hb///x3f//8d3///Le///y4P//8+D///Ph///z4v//9OP///Tk///0 + 5f//+fD/x8bF/5mVi///+Nf//Pjh//387v///vf//f3v//z33f/79df/+vDR//jov//247j/892v//HZ + p//w1aD/9NKa/5qWkv+Xlpb///v3///68v//+vL///ry///68///+vP///rz///68//MmX//AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA6reO////////8Nr///Hb///x3P//8d3///Le///y3///8uD///Ph///z + 4f//8+L///Tj///05P//9ej/8u7p/6Wlp/+6tKD///3j//365f/9/Ov//Prp//354//79dv/++/O//fo + wv/25Lj/892u//Lap//216D/u7Cc/3Bxc//p5+P///nx///58f//+fH///nx///58v//+fL///ny///5 + 8v/MmX//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA67iP////////8Nr///Da/4V+cv+FfnP/hX5z/4V+ + dP+FfnT///Lg///z4f+Ff3b/hX92/4V/dv+Ff3f/qaWg/8XEwv+cnZ//tbGd//b01//389z/9vLc//v2 + 3v/y6cv/7uK8/+3cs//s2Kv/69Sm/+3TnP+3q5b/dHV4/6empP+hnpv///nv///58P//+fD///nw///5 + 8P//+fD///nw///58P/Nmn//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA7bqP////////8Nn///Da/4V9 + cv+FfnL/hX5z/4V+c/+FfnT///Lf///y4P+Ff3X/hX92/4V/dv+Ff3b/hX93/7Guqf/FxMP/o6Sl/5eV + i//a0rP/9OrE//3xyv/w5Lz/8OC2//HcsP/w2qr/1cKd/5mVj/95enz/p6Wk/6uopf+FgXz///jv///4 + 7///+O////nv///57///+e////nv///57//Nmn//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA7ruQ//// + ////79f///DZ/4V9cv+FfnL/hX5z/4V+c/+FfnT///Le///y3/+Ff3X/hX91/4V/dv+Ff3b/hX92/4V/ + d/+sqKL/xMK//7Oys/+Sk5P/k5GN/7CqnP+5sJv/urGZ/6yllf+Qjor/gIGD/4qJif+0s7D/pqOe/4WB + fP+FgXz///ju///47v//+O7///ju///47v//+O7///ju///47v/Om4D/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA77yQ////////79b///DZ///w2f//8Nr///Hb///x3P//8d3///Le///y3v//8uD///Pg///z + 4f//8+L///Pi///04///9OT///bp//347//i3tr/wsG+/6uqqv+bm5z/mJiY/52dnP+0srD/2tfT//75 + 8///+O3///fr///37P//9+z///fs///47f//+O3///jt///47f//+O3///jt///47f/Om4D/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA8L2R////////7tT//+/W///w2f//8Nr///Da///x2///8dz///Hd///y + 3v//8t////Lg///z4P//8+H///Pi///z4v//9OP///Tk///05P//9un///ju///58f//+vL///rz///6 + 8v//+fD///fs///26f//9ur///bq///36///9+v///fr///37P//9+z///fs///37P//9+z///fs///3 + 7P/Om4D/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8b6S////////7dL//+7U/4V9cP+FfXH/hX1y/4V9 + cv+FfnL/hX5z/4V+c/+FfnT/hX50/4V+df+Ff3X///Ph///z4v+Ff3b/hX92/4V/d/+Ff3f/hX93/4WA + d/+FgHj/hYB4/4WAeP+FgHn/hYB5/4WAef+FgHr///bp///26f+FgHr/hYB6/4WBe/+FgXv/hYF7/4WB + e///9+v///fr///36//PnID/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8r+S////////7ND//+7T/4V8 + b/+FfXD/hX1x/4V9cv+FfXL/hX5y/4V+c/+FfnP/hX50/4V+dP+FfnT///Lg///z4f+Ff3X/hX92/4V/ + dv+Ff3b/hX93/4V/d/+Ff3f/hYB3/4WAeP+FgHj/hYB4/4WAef+FgHn///bo///26f+FgHr/hYB6/4WA + ev+FgHr/hYB6/4WAev//9ur///bq///26v/PnID/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA88CT//// + ////7M7//+3R/4V8bv+FfG//hX1w/4V9cf+FfXL/hX1y/4V+cv+FfnP/hX5z/4V+dP+FfnT///Lf///y + 4P+Ff3X/hX91/4V/dv+Ff3b/hX92/4V/d/+Ff3f/hX93/4V/d/+FgHf/hYB4/4WAeP+FgHj///Xn///1 + 6P+FgHn/hYB5/4WAef+FgHn/hYB6/4WAev//9un///bp///26f/PnID/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA9MGT////////68z//+zP///t0f//7tP//+7V///w2f//8Nn///Da///w2///8dv///Hc///x + 3f//8t7///Le///y3///8uD///Pg///z4f//8+H///Pi///z4v//9OP///Tk///05P//9OX///Tl///1 + 5f//9eb///Xm///15///9ef///Xn///15///9ef///Xo///16P//9ej///Xo///16P/QnYH/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA9sOU////////6sv//+vN///sz///7dH//+7T///u1f//8Nn///DZ///w + 2v//8Nv///Hb///x3P//8d3///Hd///y3v//8t////Lg///y4P//8+H///Ph///z4v//8+L///Pi///0 + 4///9OT///Tk///05P//9OX///Tl///15f//9eb///Xm///15v//9eb///Xn///15///9ef///Xn///1 + 5//QnYH/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA98SU////////6sn//+rL/4V7a/+Fe2z/hXxt/4V8 + bv+FfG//hX1w/4V9cf+FfXL/hX1y/4V+cv+FfnP/hX5z/4V+c/+FfnT/hX50/4V+dP+FfnX/hX91///z + 4f//8+H/hX92/4V/dv+Ff3b/hX92/4V/dv+Ff3f/hX93/4V/d/+Ff3f/hX93/4V/d/+Ff3f/hYB3/4WA + d///9eX///Xl///15f/QnYH/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+MWV////////6cf//+rJ/4V6 + av+Fe2v/hXts/4V8bf+FfG7/hXxv/4V9cP+FfXH/hX1y/4V9cv+FfnL/hX5y/4V+c/+FfnP/hX5z/4V+ + dP+FfnT/hX50///y4P//8+D/hX91/4V/df+Ff3X/hX92/4V/dv+Ff3b/hX92/4V/dv+Ff3f/hX93/4V/ + d/+Ff3f/hX93/4V/d///9OT///Tk///05P/QnYH/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+caW//// + ////6MP//+nH/4V6af+Femr/hXtr/4V7bP+FfG3/hXxu/4V8b/+FfXD/hX1x/4V9cf+FfXL/hX1y/4V+ + cv+FfnP/hX5z/4V+c/+FfnT/hX50///y3///8t//hX51/4V+df+Ff3X/hX91/4V/df+Ff3b/hX92/4V/ + dv+Ff3b/hX92/4V/dv+Ff3b/hX92/4V/dv//9OP///Tj///04//QnYH/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA+seW////////58H//+jE///px///6sn//+rL///rzf//7M///+3R///u0///7tT//+/W///w + 2f//8Nn///Da///w2v//8dv///Hb///x3P//8d3///Hd///y3v//8t7///Lf///y3///8uD///Lg///z + 4P//8+H///Ph///z4f//8+H///Pi///z4v//8+L///Pi///z4v//8+L///Pi///z4v/QnYH/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA+8iX//7y4v//8Nn//+fB///ow///6cf//+rJ///qy///68z//+zO///s + 0P//7dL//+7U///v1v//79f///DZ///w2v//8Nr///Db///x2///8dz///Hc///x3f//8d3///Le///y + 3v//8t7///Lf///y3///8uD///Lg///y4P//8+D///Ph///z4f//8+H///Ph///z4f//8+H///Ph/+7U + v//QnYH/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/MmXo/zJl//+9OX///DZ///nwf//6MP//+jF///p + yP//6sr//+vM///szv//7ND//+3R///u0///7tX//+/X///w2f//8Nn///Da///w2v//8Nv///Hb///x + 3P//8dz///Hd///x3f//8d3///Le///y3v//8t7///Lf///y3///8t////Lg///y4P//8uD///Lg///y + 4P//9+z/9uHN/9Kfgv/PnICjAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP3KmMz8yZf//vLi//// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////15df/0Z6B/9KfgswAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAD8yZej+8iX//rHlv/5xpb/+MWV//fElP/2w5T/9MGT//PAk//yv5L/8b6S//C9kf/vvJD/7ruQ/+26 + j//ruI//6reO/+m2jv/otY3/57SM/+azjP/lsov/5LGL/+Kviv/hror/4K2J/9+siP/eq4j/3aqH/9yp + h//bqIb/2aaG/9ilhf/XpIT/1qOE/9Wig//UoYP/06CCowAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////AAD//////58AAP//////gwAA+AAAAAAD + AADwAAAAAAMAAOAAAAAAAQAA4AAAAAABAADgAAAAAAMAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAA + AAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAH + AADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAA + AAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAH + AADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAA + AAAABwAA4AAAAAAHAADwAAAAAA8AAPgAAAAAHwAA////////AAD///////8AAP///////wAA + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/FileProtector/TrayForm.Designer.cs b/Demo_Source_Code/CSharpDemo/FileProtector/TrayForm.Designer.cs new file mode 100644 index 0000000..5b5a0ac --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FileProtector/TrayForm.Designer.cs @@ -0,0 +1,186 @@ +namespace FileProtector +{ + partial class TrayForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(TrayForm)); + this.contextMenuStrip = new System.Windows.Forms.ContextMenuStrip(this.components); + this.consoleToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripMenuItem2 = new System.Windows.Forms.ToolStripSeparator(); + this.settingsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripMenuItem5 = new System.Windows.Forms.ToolStripSeparator(); + this.helpTopicsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.helpTopicsToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem(); + this.reportAProblemToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.uninstallDriverToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.openProtectorSourceCodeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.sdkToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripMenuItem3 = new System.Windows.Forms.ToolStripSeparator(); + this.exitToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem(); + this.notifyIcon = new System.Windows.Forms.NotifyIcon(this.components); + this.contextMenuStrip.SuspendLayout(); + this.SuspendLayout(); + // + // contextMenuStrip + // + this.contextMenuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.consoleToolStripMenuItem, + this.toolStripMenuItem2, + this.settingsToolStripMenuItem, + this.toolStripMenuItem5, + this.helpTopicsToolStripMenuItem, + this.openProtectorSourceCodeToolStripMenuItem, + this.sdkToolStripMenuItem, + this.toolStripMenuItem3, + this.exitToolStripMenuItem1}); + this.contextMenuStrip.Name = "contextMenuStrip_fileAgent"; + this.contextMenuStrip.Size = new System.Drawing.Size(200, 154); + this.contextMenuStrip.Text = "-"; + // + // consoleToolStripMenuItem + // + this.consoleToolStripMenuItem.Name = "consoleToolStripMenuItem"; + this.consoleToolStripMenuItem.Size = new System.Drawing.Size(199, 22); + this.consoleToolStripMenuItem.Text = "Show protector console"; + this.consoleToolStripMenuItem.Click += new System.EventHandler(this.consoleToolStripMenuItem_Click); + // + // toolStripMenuItem2 + // + this.toolStripMenuItem2.Name = "toolStripMenuItem2"; + this.toolStripMenuItem2.Size = new System.Drawing.Size(196, 6); + // + // settingsToolStripMenuItem + // + this.settingsToolStripMenuItem.Name = "settingsToolStripMenuItem"; + this.settingsToolStripMenuItem.Size = new System.Drawing.Size(199, 22); + this.settingsToolStripMenuItem.Text = "Settings..."; + this.settingsToolStripMenuItem.Click += new System.EventHandler(this.settingsToolStripMenuItem_Click); + // + // toolStripMenuItem5 + // + this.toolStripMenuItem5.Name = "toolStripMenuItem5"; + this.toolStripMenuItem5.Size = new System.Drawing.Size(196, 6); + // + // helpTopicsToolStripMenuItem + // + this.helpTopicsToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.helpTopicsToolStripMenuItem1, + this.reportAProblemToolStripMenuItem, + this.uninstallDriverToolStripMenuItem}); + this.helpTopicsToolStripMenuItem.Name = "helpTopicsToolStripMenuItem"; + this.helpTopicsToolStripMenuItem.Size = new System.Drawing.Size(199, 22); + this.helpTopicsToolStripMenuItem.Text = "Help"; + // + // helpTopicsToolStripMenuItem1 + // + this.helpTopicsToolStripMenuItem1.Name = "helpTopicsToolStripMenuItem1"; + this.helpTopicsToolStripMenuItem1.Size = new System.Drawing.Size(241, 22); + this.helpTopicsToolStripMenuItem1.Text = "Help topics"; + this.helpTopicsToolStripMenuItem1.Click += new System.EventHandler(this.helpTopicsToolStripMenuItem1_Click); + // + // reportAProblemToolStripMenuItem + // + this.reportAProblemToolStripMenuItem.Name = "reportAProblemToolStripMenuItem"; + this.reportAProblemToolStripMenuItem.Size = new System.Drawing.Size(241, 22); + this.reportAProblemToolStripMenuItem.Text = "Report a problem or suggestion"; + this.reportAProblemToolStripMenuItem.Click += new System.EventHandler(this.reportAProblemToolStripMenuItem_Click); + // + // uninstallDriverToolStripMenuItem + // + this.uninstallDriverToolStripMenuItem.Name = "uninstallDriverToolStripMenuItem"; + this.uninstallDriverToolStripMenuItem.Size = new System.Drawing.Size(241, 22); + this.uninstallDriverToolStripMenuItem.Text = "Uninstall driver"; + this.uninstallDriverToolStripMenuItem.Click += new System.EventHandler(this.uninstallDriverToolStripMenuItem_Click); + // + // openProtectorSourceCodeToolStripMenuItem + // + this.openProtectorSourceCodeToolStripMenuItem.Name = "openProtectorSourceCodeToolStripMenuItem"; + this.openProtectorSourceCodeToolStripMenuItem.Size = new System.Drawing.Size(199, 22); + this.openProtectorSourceCodeToolStripMenuItem.Text = "Open SDK folder"; + this.openProtectorSourceCodeToolStripMenuItem.Click += new System.EventHandler(this.openProtectorSourceCodeToolStripMenuItem_Click); + // + // sdkToolStripMenuItem + // + this.sdkToolStripMenuItem.Name = "sdkToolStripMenuItem"; + this.sdkToolStripMenuItem.Size = new System.Drawing.Size(199, 22); + this.sdkToolStripMenuItem.Text = "SDK manual"; + this.sdkToolStripMenuItem.Click += new System.EventHandler(this.sdkToolStripMenuItem_Click); + // + // toolStripMenuItem3 + // + this.toolStripMenuItem3.Name = "toolStripMenuItem3"; + this.toolStripMenuItem3.Size = new System.Drawing.Size(196, 6); + // + // exitToolStripMenuItem1 + // + this.exitToolStripMenuItem1.Name = "exitToolStripMenuItem1"; + this.exitToolStripMenuItem1.Size = new System.Drawing.Size(199, 22); + this.exitToolStripMenuItem1.Text = "Exit"; + this.exitToolStripMenuItem1.Click += new System.EventHandler(this.exitToolStripMenuItem1_Click); + // + // notifyIcon + // + this.notifyIcon.ContextMenuStrip = this.contextMenuStrip; + this.notifyIcon.Icon = ((System.Drawing.Icon)(resources.GetObject("notifyIcon.Icon"))); + this.notifyIcon.Text = "EaseFilter File Protector"; + this.notifyIcon.Visible = true; + + // + // TrayForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(263, 102); + this.Name = "TrayForm"; + this.Text = "TrayForm"; + this.WindowState = System.Windows.Forms.FormWindowState.Minimized; + this.Load += new System.EventHandler(this.TrayForm_Load); + this.contextMenuStrip.ResumeLayout(false); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.ContextMenuStrip contextMenuStrip; + private System.Windows.Forms.ToolStripMenuItem consoleToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem sdkToolStripMenuItem; + private System.Windows.Forms.ToolStripSeparator toolStripMenuItem2; + private System.Windows.Forms.ToolStripMenuItem settingsToolStripMenuItem; + private System.Windows.Forms.ToolStripSeparator toolStripMenuItem5; + private System.Windows.Forms.ToolStripMenuItem helpTopicsToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem helpTopicsToolStripMenuItem1; + private System.Windows.Forms.ToolStripMenuItem reportAProblemToolStripMenuItem; + private System.Windows.Forms.ToolStripSeparator toolStripMenuItem3; + private System.Windows.Forms.ToolStripMenuItem exitToolStripMenuItem1; + public System.Windows.Forms.NotifyIcon notifyIcon; + private System.Windows.Forms.ToolStripMenuItem openProtectorSourceCodeToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem uninstallDriverToolStripMenuItem; + } +} \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/FileProtector/TrayForm.cs b/Demo_Source_Code/CSharpDemo/FileProtector/TrayForm.cs new file mode 100644 index 0000000..c157bfa --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FileProtector/TrayForm.cs @@ -0,0 +1,120 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +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; +using System.IO; + +using EaseFilter.CommonObjects; + +namespace FileProtector +{ + public partial class TrayForm: Form + { + ProtectorForm protectorForm = new ProtectorForm(); + + public TrayForm() + { + InitializeComponent(); + } + + private void TrayForm_Load(object sender, EventArgs e) + { + this.Hide(); + this.notifyIcon.Visible = true; + protectorForm.ShowDialog(); + Utils.ToDebugger("ShowDialog"); + } + + private void consoleToolStripMenuItem_Click(object sender, EventArgs e) + { + if (!protectorForm.Visible) + { + protectorForm.StartPosition = FormStartPosition.CenterScreen; + protectorForm.ShowDialog(); + } + } + + private void settingsToolStripMenuItem_Click(object sender, EventArgs e) + { + SettingsForm settingForm = new SettingsForm(); + settingForm.StartPosition = FormStartPosition.CenterScreen; + settingForm.ShowDialog(); + } + + private void helpTopicsToolStripMenuItem1_Click(object sender, EventArgs e) + { + System.Diagnostics.Process.Start("http://www.easefilter.com/Forums_Files/FileMonitor.htm"); + } + + private void reportAProblemToolStripMenuItem_Click(object sender, EventArgs e) + { + System.Diagnostics.Process.Start("http://www.easefilter.com/ReportIssue.htm"); + } + + + private void exitToolStripMenuItem1_Click(object sender, EventArgs e) + { + GlobalConfig.Stop(); + protectorForm.Close(); + + Application.Exit(); + } + + private void sdkToolStripMenuItem_Click(object sender, EventArgs e) + { + System.Diagnostics.Process.Start("http://www.easefilter.com/info/easefilter_manual.pdf"); + } + + + private void openProtectorSourceCodeToolStripMenuItem_Click(object sender, EventArgs e) + { + System.Reflection.Assembly assembly = System.Reflection.Assembly.GetEntryAssembly(); + string AssemblyPath = Path.Combine(Path.GetDirectoryName(assembly.Location), "Demo"); + System.Diagnostics.Process.Start("explorer.exe", AssemblyPath); + } + + private void uninstallDriverToolStripMenuItem_Click(object sender, EventArgs e) + { + FilterAPI.UnInstallDriver(); + } + + private void ShowNotification(string message, bool isErrorMessage) + { + if (!GlobalConfig.EnableNotification) + { + return; + } + + if (this.InvokeRequired) + { + this.Invoke(new EventManager.ShowNotificationDlgt(ShowNotification), new Object[] { message, isErrorMessage }); + } + else + { + } + + } + + } +} diff --git a/Demo_Source_Code/CSharpDemo/FileProtector/TrayForm.resx b/Demo_Source_Code/CSharpDemo/FileProtector/TrayForm.resx new file mode 100644 index 0000000..0652129 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FileProtector/TrayForm.resx @@ -0,0 +1,158 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 19, 18 + + + 214, 23 + + + + + AAABAAEAEBAAAAEACABoBQAAFgAAACgAAAAQAAAAIAAAAAEACAAAAAAAQAEAAAAAAAAAAAAAAAEAAAAA + AAAAAAAA////AAUBAAAXBwEAKhEEACgQBAAsEgUALRMFADMXBwA0GAcAOBoIADkbCQA7HQoAPx8LAEEh + CwBAIAsAQiIMAEYkDQBDIw0ASScPAE8sEgBSLhMATSsSAFUxFQBWMhYAWjYYAFk1GABdOBoAYDscAF86 + HABhPB0AYj0dAGM+HgBkPx8AZkEgAGdCIQBsRyUAa0YlAG1IJgBxTCkAdE8rAHZRLQB+WDMAhF86AIRg + OwCFYTwAh2M+AP37+QCJZT8AimZAAIxoQgCNaUMAkGxGAJFtRwCTcEoAkm9JAJRxSwCXdE4AmHVPAJx6 + VACbeVMAnn1XAJ18VgCgf1kAo4NdAKaGYQCoiGMAp4diAKmJZACqimUAqotmAK2PawCvkW0AsZNvALCS + bgCylHAAs5ZzANjFrwC2mncAuZ58ALyhfwC7oH4Aup99AL6kgwDAp4cAw6qKAMWtjgDErI0Axa6QAMix + kwDJs5UAyrSWAMu1mQDMtpoA07+lANPApgDYx7AA6d7PAPPt5QDOup4A08GoANbEqwDUwqkA39C7AN3O + uQDh1MEA7uXYAO/n3ADx6uAA8uzjAPz69wD6+PUA6eDSAPTv5wD49fAA////AAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAYGBgYGBgAAAAAAAAAAAgFADNNcDMAAw0AAAAAAA1UBzMAAAAARwdGDQAAABM4WAZM + ODg4OEsJSzgTAAAUPFoLUj0CAj9PDFs+FQAAIEVkJ11PLi5RXSllSiIAAChQaCxrWUVFWWEtZ1UqAAAr + XwEAAC9HSW4AAAFmNgAAK3EAAABDWlpCAAAAajQAI0cAYgFkZldXZF4BYgBIJx8AbGNJAE5KSEsAU11s + ACEATjY6AERcBQVgQAA4Nk4AJDEwAEFpCDc1BWFAADAwFw4sADtvOS1Wckw1bT4ALBUEChYmMjcREhAP + Mi4lGhQLAAAAABseHh4cHRsZAAAAAPgfAADgBwAAwAMAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAPAPAAA= + + + + 444, 24 + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/FileProtector/TutorialForm.Designer.cs b/Demo_Source_Code/CSharpDemo/FileProtector/TutorialForm.Designer.cs new file mode 100644 index 0000000..527bda5 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FileProtector/TutorialForm.Designer.cs @@ -0,0 +1,202 @@ +namespace FileProtector +{ + partial class TutorialForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(TutorialForm)); + this.richTextBox1 = new System.Windows.Forms.RichTextBox(); + this.tabControl1 = new System.Windows.Forms.TabControl(); + this.tabPage_FilterRule = new System.Windows.Forms.TabPage(); + this.tabPage_GlobalSettings = new System.Windows.Forms.TabPage(); + this.richTextBox2 = new System.Windows.Forms.RichTextBox(); + this.tabPage_AccessControl = new System.Windows.Forms.TabPage(); + this.richTextBox3 = new System.Windows.Forms.RichTextBox(); + this.tabPage_Encryption = new System.Windows.Forms.TabPage(); + this.richTextBox4 = new System.Windows.Forms.RichTextBox(); + this.tabPage_Example = new System.Windows.Forms.TabPage(); + this.richTextBox5 = new System.Windows.Forms.RichTextBox(); + this.tabControl1.SuspendLayout(); + this.tabPage_FilterRule.SuspendLayout(); + this.tabPage_GlobalSettings.SuspendLayout(); + this.tabPage_AccessControl.SuspendLayout(); + this.tabPage_Encryption.SuspendLayout(); + this.tabPage_Example.SuspendLayout(); + this.SuspendLayout(); + // + // richTextBox1 + // + this.richTextBox1.Dock = System.Windows.Forms.DockStyle.Fill; + this.richTextBox1.Font = new System.Drawing.Font("Arial", 9F); + this.richTextBox1.Location = new System.Drawing.Point(3, 3); + this.richTextBox1.Name = "richTextBox1"; + this.richTextBox1.Size = new System.Drawing.Size(596, 575); + this.richTextBox1.TabIndex = 0; + this.richTextBox1.Text = resources.GetString("richTextBox1.Text"); + // + // tabControl1 + // + this.tabControl1.Controls.Add(this.tabPage_FilterRule); + this.tabControl1.Controls.Add(this.tabPage_GlobalSettings); + this.tabControl1.Controls.Add(this.tabPage_AccessControl); + this.tabControl1.Controls.Add(this.tabPage_Encryption); + this.tabControl1.Controls.Add(this.tabPage_Example); + this.tabControl1.Dock = System.Windows.Forms.DockStyle.Fill; + this.tabControl1.Location = new System.Drawing.Point(0, 0); + this.tabControl1.Name = "tabControl1"; + this.tabControl1.SelectedIndex = 0; + this.tabControl1.Size = new System.Drawing.Size(610, 607); + this.tabControl1.TabIndex = 1; + // + // tabPage_FilterRule + // + this.tabPage_FilterRule.Controls.Add(this.richTextBox1); + this.tabPage_FilterRule.Location = new System.Drawing.Point(4, 22); + this.tabPage_FilterRule.Name = "tabPage_FilterRule"; + this.tabPage_FilterRule.Padding = new System.Windows.Forms.Padding(3); + this.tabPage_FilterRule.Size = new System.Drawing.Size(602, 581); + this.tabPage_FilterRule.TabIndex = 0; + this.tabPage_FilterRule.Text = "Filter rule settings"; + this.tabPage_FilterRule.UseVisualStyleBackColor = true; + // + // tabPage_GlobalSettings + // + this.tabPage_GlobalSettings.Controls.Add(this.richTextBox2); + this.tabPage_GlobalSettings.Location = new System.Drawing.Point(4, 22); + this.tabPage_GlobalSettings.Name = "tabPage_GlobalSettings"; + this.tabPage_GlobalSettings.Padding = new System.Windows.Forms.Padding(3); + this.tabPage_GlobalSettings.Size = new System.Drawing.Size(602, 581); + this.tabPage_GlobalSettings.TabIndex = 1; + this.tabPage_GlobalSettings.Text = "Global settings"; + this.tabPage_GlobalSettings.UseVisualStyleBackColor = true; + // + // richTextBox2 + // + this.richTextBox2.Dock = System.Windows.Forms.DockStyle.Fill; + this.richTextBox2.Font = new System.Drawing.Font("Arial", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.richTextBox2.Location = new System.Drawing.Point(3, 3); + this.richTextBox2.Name = "richTextBox2"; + this.richTextBox2.Size = new System.Drawing.Size(596, 575); + this.richTextBox2.TabIndex = 1; + this.richTextBox2.Text = resources.GetString("richTextBox2.Text"); + // + // tabPage_AccessControl + // + this.tabPage_AccessControl.Controls.Add(this.richTextBox3); + this.tabPage_AccessControl.Location = new System.Drawing.Point(4, 22); + this.tabPage_AccessControl.Name = "tabPage_AccessControl"; + this.tabPage_AccessControl.Padding = new System.Windows.Forms.Padding(3); + this.tabPage_AccessControl.Size = new System.Drawing.Size(602, 581); + this.tabPage_AccessControl.TabIndex = 2; + this.tabPage_AccessControl.Text = "Access control"; + this.tabPage_AccessControl.UseVisualStyleBackColor = true; + // + // richTextBox3 + // + this.richTextBox3.Dock = System.Windows.Forms.DockStyle.Fill; + this.richTextBox3.Font = new System.Drawing.Font("Arial", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.richTextBox3.Location = new System.Drawing.Point(3, 3); + this.richTextBox3.Name = "richTextBox3"; + this.richTextBox3.Size = new System.Drawing.Size(596, 575); + this.richTextBox3.TabIndex = 2; + this.richTextBox3.Text = resources.GetString("richTextBox3.Text"); + // + // tabPage_Encryption + // + this.tabPage_Encryption.Controls.Add(this.richTextBox4); + this.tabPage_Encryption.Location = new System.Drawing.Point(4, 22); + this.tabPage_Encryption.Name = "tabPage_Encryption"; + this.tabPage_Encryption.Padding = new System.Windows.Forms.Padding(3); + this.tabPage_Encryption.Size = new System.Drawing.Size(602, 581); + this.tabPage_Encryption.TabIndex = 3; + this.tabPage_Encryption.Text = "File encryption"; + this.tabPage_Encryption.UseVisualStyleBackColor = true; + // + // richTextBox4 + // + this.richTextBox4.Dock = System.Windows.Forms.DockStyle.Fill; + this.richTextBox4.Font = new System.Drawing.Font("Arial", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.richTextBox4.Location = new System.Drawing.Point(3, 3); + this.richTextBox4.Name = "richTextBox4"; + this.richTextBox4.Size = new System.Drawing.Size(596, 575); + this.richTextBox4.TabIndex = 2; + this.richTextBox4.Text = resources.GetString("richTextBox4.Text"); + // + // tabPage_Example + // + this.tabPage_Example.Controls.Add(this.richTextBox5); + this.tabPage_Example.Location = new System.Drawing.Point(4, 22); + this.tabPage_Example.Name = "tabPage_Example"; + this.tabPage_Example.Padding = new System.Windows.Forms.Padding(3); + this.tabPage_Example.Size = new System.Drawing.Size(602, 581); + this.tabPage_Example.TabIndex = 4; + this.tabPage_Example.Text = "Data protection examples"; + this.tabPage_Example.UseVisualStyleBackColor = true; + // + // richTextBox5 + // + this.richTextBox5.Dock = System.Windows.Forms.DockStyle.Fill; + this.richTextBox5.Font = new System.Drawing.Font("Arial", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.richTextBox5.Location = new System.Drawing.Point(3, 3); + this.richTextBox5.Name = "richTextBox5"; + this.richTextBox5.Size = new System.Drawing.Size(596, 575); + this.richTextBox5.TabIndex = 2; + this.richTextBox5.Text = resources.GetString("richTextBox5.Text"); + // + // TutorialForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(610, 607); + this.Controls.Add(this.tabControl1); + this.Name = "TutorialForm"; + this.Text = "File Protector Tutorial"; + this.tabControl1.ResumeLayout(false); + this.tabPage_FilterRule.ResumeLayout(false); + this.tabPage_GlobalSettings.ResumeLayout(false); + this.tabPage_AccessControl.ResumeLayout(false); + this.tabPage_Encryption.ResumeLayout(false); + this.tabPage_Example.ResumeLayout(false); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.RichTextBox richTextBox1; + private System.Windows.Forms.TabControl tabControl1; + private System.Windows.Forms.TabPage tabPage_FilterRule; + private System.Windows.Forms.TabPage tabPage_GlobalSettings; + private System.Windows.Forms.RichTextBox richTextBox2; + private System.Windows.Forms.TabPage tabPage_AccessControl; + private System.Windows.Forms.RichTextBox richTextBox3; + private System.Windows.Forms.TabPage tabPage_Encryption; + private System.Windows.Forms.RichTextBox richTextBox4; + private System.Windows.Forms.TabPage tabPage_Example; + private System.Windows.Forms.RichTextBox richTextBox5; + } +} \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/FileProtector/TutorialForm.cs b/Demo_Source_Code/CSharpDemo/FileProtector/TutorialForm.cs new file mode 100644 index 0000000..94d8123 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FileProtector/TutorialForm.cs @@ -0,0 +1,40 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +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 FileProtector +{ + public partial class TutorialForm : Form + { + public static bool isInitialized = false; + + public TutorialForm() + { + InitializeComponent(); + } + + + } +} diff --git a/Demo_Source_Code/CSharpDemo/FileProtector/TutorialForm.resx b/Demo_Source_Code/CSharpDemo/FileProtector/TutorialForm.resx new file mode 100644 index 0000000..ebea4ff --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FileProtector/TutorialForm.resx @@ -0,0 +1,194 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 1. To manage your files, you need to create at least one filter rule, you can have multiple filter rules with different policies to manage different files with your requirement. +2. A filter rule only can have one unique include file mask, when a new filter rule was added to the filter driver, if a filter rule with the same include file mask already exists, then the new filter rule will replace the older one. A filter rule can have multiple exclude file masks, multiple include process names and exclude process names, multiple include process Ids and exclude process Ids, multiple include user names and exclude user names. +3. If the exclude filter rules exist, the filter driver will look for the exclude filter rules first, if the files match the include file mask of the filter rule, then the files won't be managed by the filter driver, if no exclude filter rule matches the file ,then the filter driver will look for the include filter rules. +4.When an I/O occurs, the filter driver will check if the file name matches the filter rules. If the file name matches the include file mask of the filter rule, then it will check if the exclude file mask list is empty, if it is not empty, then it will check if the file name matches the exclude file mask, if it matches, then go to next filter rule, or it will check if the include process name and include process Id list are empty, if they are not empty, then check if the current process name or process Id is in the include list, if not then go to next filter rule, or go to check if the exclude process name and exclude process Id list are empty, if they are not empty, then check if the current process name or process Id is in the list, if yes then go to the next filter rule, or go to check if the include user names list is empty, if it is not empty, then check if the current user name is in the list, if not then go to the next filter rule, or go to check if the exclude user names list is empty, if it is not empty, then check if the current user name is in the list, if yes then go to the next filter rule, or this is the filter rule for the file. +5. If the files match multiple filter rules, the filter driver will choose the deepest one. +For example, there are filter rule1 with include file mask c:\test\*; filter rule2 with include file mask c:\test\test2\*; filter rule3 with include file mask c:\test\test2\test3\* +Filter rule3 is the subset of the filter rule2, filter rule2 is the subset of the filter rule1, filter rule3 is above of the filter rule2, filter rule2 is above of the filter rule1.File c:\test\test2\text.txt matches the filter rule1 and filter rule2, the filter driver will choose filter rule2 as the filter rule for file c:\test\test2\test.txt +6.File changed event settings. +You can register the file changed events: file created, file renamed, file deleted, file changed. If the files match this filter rule and the files were changed, the notification with this event information will send it to the service. + + + + 1. Filter type setting: it can be monitor filter, control filter, encryption filter or control + encryption filter. + 2. Protected process Id list, the processes will be protected by filter driver, they won't be terminated from task manager. + 3. Include process Id list, if it is not empty, only the files were opened from these processes the filter driver will go to look for the filter rules, or the filter driver won't manage the files. + 4. Exclude process Id list, if it is not empty, if the files were opened by the process which is in the exclude process Id list, the filter driver won't manage the files. +5. Register I/O requests, after you register the file I/O type, if the I/O occurs with the manage files, then I/O notification will be sent to user mode application. For control filter, you can change the I/O behavior to block the I/O access or modify the I/O data. +6. Set the connection timeout value, it is the timeout for filter driver wait for the response from the user mode for control filter if the I/O requests were registered. + + + The control filter driver can protect your sensitive data, prevent the files being accessed, modified, deleted, renamed and copied from unauthorized users and processes or from remote computers. You also can hide your sensitive data from the user's view. +1. Set the AccessFlags in the filter rules. +When the I/O occurs on the managed files, the filter driver will check if the I/O allows in the access flags, if it allows to access, the I/O pass, or the I/O will be blocked and return access denied. +2. Register the I/O requests. +When you register a I/O request, you have fully control to that I/O request, a callback request will send to the user mode service with the I/O type, file name, file size, file date information, user name, process name, and I/O data. With these information, you can control the I/O behavior, modify the I/O or block the I/O. +3. The major I/O types: + a. File open/create: normally most of the I/Os start with open/create I/O first. + b. File read: read the file data. + c. File write: write the data to the file. + d. File information query: query the file name, file size, creation time, last write time, last access time, file Id, file attributes. + e. Set file information: change the above file information. + f. Query file security information. + g. Set file security information. + h. Browse directory information. + + + + 1. EaseFilter File system encryption filter driver provides a comprehensive solution for transparent file level encryption. It supports AES 256-bits encryption. +2. EaseFilter encryption filter driver introduces the shadow file object technology to support private cache for per encrypted file open. With the client-defined policy, the authorized users and processes can get clear view of the encrypted data, for unauthorized user or processes can't access the encrypted files. +3. Distribute the encrypted files with the rights management policy via internet. You can embed the access right policy to the encrypted files, allow you to set the expiration time for the encrypted files, or set the authorized process names, user names to the encrypted files. + + + + 1. Set all files to be read-only in folder c:\protectFolder, you can do the following setting: +//Here is the example which you can’t modify the files, can't rename, can't delete, can’t write, can’t change security, +//can’t change file information (creation time, last write time, file attributes.) except the process cmd.exe from user testdomain\testuser + uint accessFlag = (~ALLOW_FILE_DELETE) &(~ALLOW_FILE_RENAME) &(~ALLOW_WRITE_ACCESS)& (~ALLOW_SET_INFORMATION)& (~ALLOW_SET_SECURITY_ACCESS)& ALLOW_MAX_RIGHT_ACCESS; +string filterMask = "c:\\protectFolder\\*"; +AddNewFilterRule(accessFlag,filterMask); +AddExcludeProcessNameToFilterRule(filterMask,"cmd.exe"); +AddExcludeUserNameToFilterRule(filterMask,"testdomain\\testuser"); +2. Exclude all files in folder c:\protectFolder\excludeFolder from all your filter rules: + //Here is the example show you how to exclude the folder from the filter rule. +//The filter driver will bypass all the I/O for folder c:\protectFolder\excludeFolder + uint accessFlag = EXCLUDE_FILTER_RULE; +string filterMask = "c:\\protectFolder\\excludeFolder\\*"; +AddNewFilterRule(accessFlag,filterMask); + 3.Hide all files with extension .txt from folder c:\test, when you browse the folder, all the .txt files will be hidden from the file list. + uint accessFlag = (~ALLOW_WRITE_ACCESS)& (~ALLOW_SET_INFORMATION)& (~ALLOW_SET_SECURITY_ACCESS)& ALLOW_MAX_RIGHT_ACCESS; +string filterMask = "c:\\test\\*"; +AddNewFilterRule(accessFlag,filterMask); +string hideFileMask = L"*.txt"; +AddHiddenFileMaskToFilterRule(filterMask,hideFileMask); +4.Set encryption rule to c:\\protectFolder, only process wordpad.exe can read the encrypted files. + uint accessFlag = FILE_ENCRYPTION_RULE | ALLOW_MAX_RIGHT_ACCESS; +string filterMask = "c:\\protectFolder\\*"; +AddNewFilterRule(accessFlag,filterMask); +encryptionKey = 32 bytes encryption key byte array; +encryptionKeyLength = 32; +AddEncryptionKeyToFilterRule(filterMask, encryptionKeyLength, encryptionKey) +AddIncludeProcessNameToFilterRule(filterMask,"wordpad.exe"); + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/FileProtector/app.config b/Demo_Source_Code/CSharpDemo/FileProtector/app.config new file mode 100644 index 0000000..da85653 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FileProtector/app.config @@ -0,0 +1,7 @@ + + + + + + + diff --git a/Demo_Source_Code/CSharpDemo/FileProtector/app.manifest b/Demo_Source_Code/CSharpDemo/FileProtector/app.manifest new file mode 100644 index 0000000..5e146d8 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FileProtector/app.manifest @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Demo_Source_Code/CSharpDemo/FileProtector/protector.ico b/Demo_Source_Code/CSharpDemo/FileProtector/protector.ico new file mode 100644 index 0000000..86009bf Binary files /dev/null and b/Demo_Source_Code/CSharpDemo/FileProtector/protector.ico differ diff --git a/Demo_Source_Code/CSharpDemo/FileProtectorConsole/FileProtectorConsole.csproj b/Demo_Source_Code/CSharpDemo/FileProtectorConsole/FileProtectorConsole.csproj new file mode 100644 index 0000000..a2c2f10 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FileProtectorConsole/FileProtectorConsole.csproj @@ -0,0 +1,106 @@ + + + + Debug + x86 + 8.0.30703 + 2.0 + {1A0641F2-8857-46D7-965D-B6B3BD1771BC} + Exe + Properties + FileProtectorConsole + FileProtectorConsole + v4.5 + + + 512 + SAK + SAK + SAK + SAK + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + false + + + x86 + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + false + + + true + bin\Debug\ + DEBUG;TRACE + full + AnyCPU + bin\Debug\FileProtectorConsole.exe.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + true + false + + + bin\Release\ + TRACE + true + pdbonly + AnyCPU + bin\Release\FileProtectorConsole.exe.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + false + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false + false + + + + + + + + + + + + + + + + + + + + {21540012-A296-45CE-8D35-3EA5A07B32A6} + FilterControl + + + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/FileProtectorConsole/Program.cs b/Demo_Source_Code/CSharpDemo/FileProtectorConsole/Program.cs new file mode 100644 index 0000000..505b588 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FileProtectorConsole/Program.cs @@ -0,0 +1,115 @@ +using System; +using EaseFilter.FilterControl; + +namespace FileProtectorConsole +{ + class Program + { + static FilterControl filterControl = new FilterControl(); + + static void Main(string[] args) + { + string lastError = string.Empty; + //Purchase a license key with the link: http://www.easefilter.com/Order.htm + //Email us to request a trial key: info@easefilter.com //free email is not accepted. + string licenseKey = "*************************************"; + + FilterAPI.FilterType filterType = FilterAPI.FilterType.MONITOR_FILTER|FilterAPI.FilterType.CONTROL_FILTER + |FilterAPI.FilterType.PROCESS_FILTER|FilterAPI.FilterType.REGISTRY_FILTER|FilterAPI.FilterType.ENCRYPTION_FILTER; + + int serviceThreads = 5; + int connectionTimeOut = 10; //seconds + + try + { + if (!filterControl.StartFilter(filterType, serviceThreads, connectionTimeOut, licenseKey, ref lastError)) + { + Console.WriteLine("Start Filter Service failed with error:" + lastError); + return; + } + + //the watch path can use wildcard to be the file path filter mask.i.e. '*.txt' only monitor text file. + string watchPath = "c:\\test\\*"; + + if (args.Length > 0) + { + watchPath = args[0]; + } + + //create a file protector filter rule, every filter rule must have the unique watch path. + FileFilter fileProtectorFilter = new FileFilter(watchPath); + + //configure the access right for the protected folder + + //prevent the file from being deleted. + fileProtectorFilter.EnableDeleteFile = false; + + //prevent the file from being renamed. + fileProtectorFilter.EnableRenameOrMoveFile = false; + + //prevent the file from being written. + fileProtectorFilter.EnableWriteToFile = false; + + //authorize process with full access right + fileProtectorFilter.ProcessNameAccessRightList.Add("notepad.exe", FilterAPI.ALLOW_MAX_RIGHT_ACCESS); + + //set the access rights for the specific user, here is to remove the delete and rename rights. + uint accessRights = FilterAPI.ALLOW_MAX_RIGHT_ACCESS & (uint)(~(FilterAPI.AccessFlag.ALLOW_FILE_DELETE | FilterAPI.AccessFlag.ALLOW_FILE_RENAME)); + fileProtectorFilter.userAccessRightList.Add("domainname or computer\\username", accessRights); + + //you can enable/disalbe more access right by setting the properties of the fileProtectorFilter. + + //Filter the callback file IO events, here get callback before the file was opened/created, and file was deleted. + fileProtectorFilter.ControlFileIOEventFilter = (ulong)(ControlFileIOEvents.OnPreFileCreate | ControlFileIOEvents.OnPreDeleteFile); + + fileProtectorFilter.OnPreCreateFile += OnPreCreateFile; + fileProtectorFilter.OnPreDeleteFile += OnPreDeleteFile; + + filterControl.AddFilter(fileProtectorFilter); + + if (!filterControl.SendConfigSettingsToFilter(ref lastError)) + { + Console.WriteLine("SendConfigSettingsToFilter failed." + lastError); + return; + } + + Console.WriteLine("Start filter service succeeded."); + + // Wait for the user to quit the program. + Console.WriteLine("Press 'q' to quit the sample."); + while (Console.Read() != 'q') ; + + filterControl.StopFilter(); + + } + catch (Exception ex) + { + Console.WriteLine("Start filter service failed with error:" + ex.Message); + } + + } + + /// + /// Fires this event before the file was opened. + /// + static void OnPreCreateFile(object sender, FileCreateEventArgs e) + { + Console.WriteLine("OnPreCreateFile:" + e.FileName + ",userName:" + e.UserName + ",processName:" + e.ProcessName); + + //you can block the file open here by returning below status. + e.ReturnStatus = NtStatus.Status.AccessDenied; + + } + + /// + /// Fires this event before the file was deleted. + /// + static void OnPreDeleteFile(object sender, FileIOEventArgs e) + { + Console.WriteLine("OnPreDeleteFile:" + e.FileName + ",userName:" + e.UserName + ",processName:" + e.ProcessName); + + //you can block the file being deleted here by returning below status. + e.ReturnStatus = NtStatus.Status.AccessDenied; + } + } +} diff --git a/Demo_Source_Code/CSharpDemo/FileProtectorConsole/Properties/AssemblyInfo.cs b/Demo_Source_Code/CSharpDemo/FileProtectorConsole/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..9327364 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FileProtectorConsole/Properties/AssemblyInfo.cs @@ -0,0 +1,37 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("FileProtectorConsole")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("FileProtectorConsole")] +[assembly: AssemblyCopyright("Copyright © 2021")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("5969a609-aaf4-4d84-ad5c-0365fee9a3f7")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("5.2.3.2001")] +//[assembly: AssemblyFileVersion("1.0.0.0")] + diff --git a/Demo_Source_Code/CSharpDemo/FileProtectorConsole/app.config b/Demo_Source_Code/CSharpDemo/FileProtectorConsole/app.config new file mode 100644 index 0000000..c5e1dae --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FileProtectorConsole/app.config @@ -0,0 +1,3 @@ + + + diff --git a/Demo_Source_Code/CSharpDemo/FilterControl/ControlFilter.cs b/Demo_Source_Code/CSharpDemo/FilterControl/ControlFilter.cs new file mode 100644 index 0000000..bcbc770 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FilterControl/ControlFilter.cs @@ -0,0 +1,1871 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.IO; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using System.Text; + +namespace EaseFilter.FilterControl +{ + /// + /// Fires the control events before the file IO goes down to the file system for pre-io, + /// fires the control events after the file IO was returned from the file system for post-io. + /// you can allow, modify or deny the IO with control events. + /// + public enum ControlFileIOEvents : ulong + { + /// + /// Fires this event before the file create IO was going down to the file system. + /// + OnPreFileCreate = 0x00000001, + /// + /// Fires this event after the file create IO was returned from the file system. + /// + OnPostFileCreate = 0x00000002, + /// + /// Fires this event before the file read IO was going down to the file system. + /// + OnPreFileRead = 0x00000154, + /// + /// Fires this event after the file read IO was returned from the file system. + /// + OnPostFileRead = 0x000002a8, + /// + /// Fires this event before the file write IO was going down to the file system. + /// + OnPreFileWrite = 0x00015400, + /// + /// Fires this event after the file write IO was returned from the file system. + /// + OnPostFileWrite = 0x0002a800, + /// + /// Fires this event before the query file size IO was going down to the file system. + /// + OnPreQueryFileSize = 0x0000000400000000, + /// + /// Fires this event after the query file size IO was returned from the file system. + /// + OnPostQueryFileSize = 0x0000000800000000, + /// + /// Fires this event before the query file basic info IO was going down to the file system. + /// + OnPreQueryFileBasicInfo = 0x0000001000000000, + /// + /// Fires this event after the query file basic info IO was returned from the file system. + /// + OnPostQueryFileBasicInfo = 0x0000002000000000, + /// + /// Fires this event before the query file standard info IO was going to the file system. + /// + OnPreQueryFileStandardInfo = 0x0000004000000000, + /// + /// Fires this event after the query file standard info IO was returned from the file system. + /// + OnPostQueryFileStandardInfo = 0x0000008000000000, + /// + /// Fires this event before the query file network info IO was going down to the file system. + /// + OnPreQueryFileNetworkInfo = 0x0000010000000000, + /// + /// Fires this event after the query file network info IO was returned from the file system. + /// + OnPostQueryFileNetworkInfo = 0x0000020000000000, + /// + /// Fires this event before the query file Id IO was going down to the file system. + /// + OnPreQueryFileId = 0x0000040000000000, + /// + /// Fires this event after the query file Id IO was returned from the file system. + /// + OnPostQueryFileId = 0x0000080000000000, + /// + /// Fires this event before the query file info IO was going down to the file system + /// if the query file information class is not 'QueryFileSize','QueryFileBasicInfo' + /// ,'QueryFileStandardInfo','QueryFileNetworkInfo' or 'QueryFileId'. + /// + OnPreQueryFileInfo = 0x00040000, + /// + /// Fires this event after the query file info IO was returned from the file system. + /// + OnPostQueryFileInfo = 0x00080000, + /// + /// Fires this event before the set file size IO was going down to the file system. + /// + OnPreSetFileSize = 0x0000400000000000, + /// + /// Fires this event after the set file size IO was returned from the file system. + /// + OnPostSetFileSize = 0x0000800000000000, + /// + /// Fires this event before the set file basic info IO was going down to the file system. + /// + OnPreSetFileBasicInfo = 0x0001000000000000, + /// + /// Fires this event after the set file basic info IO was returned from the file system. + /// + OnPostSetFileBasicInfo = 0x0002000000000000, + /// + /// Fires this event before the set file standard info IO was going down to the file system. + /// + OnPreSetFileStandardInfo = 0x0004000000000000, + /// + /// Fires this event after the set file standard info IO was returned from the file system. + /// + OnPostSetFileStandardInfo = 0x0008000000000000, + /// + /// Fires this event before the set file network info was going down to the file system. + /// + OnPreSetFileNetworkInfo = 0x0010000000000000, + /// + /// Fires this event after the set file network info was returned from the file system. + /// + OnPostSetFileNetworkInfo = 0x0020000000000000, + /// + /// Fires this event before the file move or rename IO was going down to the file system. + /// + OnPreMoveOrRenameFile = 0x0040000000000000, + /// + /// Fires this event after the file move or rename IO was returned from the file system. + /// + OnPostMoveOrRenameFile = 0x0080000000000000, + /// + /// Fires this event before the file delete IO was going down to the file system. + /// + OnPreDeleteFile = 0x0100000000000000, + /// + /// Fires this event after the file delete IO was returned from the file system. + /// + OnPostDeleteFile = 0x0200000000000000, + /// + /// Fires this event before the set file info IO was going down to the file system + /// if the information class is not 'SetFileSize','SetFileBasicInfo' + /// ,'SetFileStandardInfo','SetFileNetworkInfo'. + /// + OnPreSetFileInfo = 0x00100000, + /// + /// Fires this event after the set file info IO was returned from the file system. + /// + OnPostSetFileInfo = 0x00200000, + /// + /// Fires this event before the query directory file info was going down to the file system. + /// + OnPreQueryDirectoryFile = 0x00400000, + /// + /// Fires this event after the query directory file info was returned from the file system. + /// + OnPostQueryDirectoryFile = 0x00800000, + /// + /// Fires this event before the query file security IO was going down to the file system. + /// + OnPreQueryFileSecurity = 0x01000000, + /// + /// Fires this event after the query file security IO was returned from the file system. + /// + OnPostQueryFileSecurity = 0x02000000, + /// + /// Fires this event before the set file security IO was going down to the file system. + /// + OnPreSetFileSecurity = 0x04000000, + /// + /// Fires thiis event after the set file security IO was returned from the file system. + /// + OnPostSetFileSecurity = 0x08000000, + /// + /// Fire this event before the file handle close IO was going down to the file system. + /// + OnPreFileHandleClose = 0x10000000, + /// + /// Fires this event after the file handle close IO was returned from the file system. + /// + OnPostFileHandleClose = 0x20000000, + /// + /// Fires this event before the file close IO was going down to the file system. + /// + OnPreFileClose = 0x40000000, + /// + /// Fires this event after the file close IO was returned from the file system. + /// + OnPostFileClose = 0x80000000, + + } + + partial class FileFilter + { + /// + /// register the callback control IO + /// + ulong registerControlFileIOEvents = 0; + + /// + /// the control flag of the filter + /// reference FilterAPI.AccessFlag enumeration + /// + uint accessFlags = FilterAPI.ALLOW_MAX_RIGHT_ACCESS; + + /// + /// the access right of the process + /// + Dictionary processNameAccessRightList = new Dictionary(); + Dictionary sha256ProcessAccessRightList = new Dictionary(); + Dictionary signedProcessAccessRightList = new Dictionary(); + Dictionary processIdAccessRightList = new Dictionary(); + + /// + /// the access right of the users + /// + Dictionary userNameAccessRightList = new Dictionary(); + + #region control filter property + + /// + /// Enable the control file filter rule in boot time. + /// + public bool IsResident + { + get { return isResident; } + set { isResident = value; } + } + + /// + /// Below is the control filter properties to check if the associated control event was registered. + /// + public bool IsPreFileCreateRegister { get { return (registerControlFileIOEvents & (ulong)ControlFileIOEvents.OnPreFileCreate) > 0; } } + public bool IsPostFileCreateRegister { get { return (registerControlFileIOEvents & (ulong)ControlFileIOEvents.OnPostFileCreate) > 0; } } + + public bool IsPreQueryFileSizeRegister{ get { return (registerControlFileIOEvents & (ulong)ControlFileIOEvents.OnPreQueryFileSize) > 0;} } + public bool IsPostQueryFileSizeRegister { get { return (registerControlFileIOEvents & (ulong)ControlFileIOEvents.OnPostQueryFileSize) > 0; } } + + public bool IsPreQueryBasicInfoRegister{ get { return (registerControlFileIOEvents & (ulong)ControlFileIOEvents.OnPreQueryFileBasicInfo) > 0;} } + public bool IsPostQueryBasicInfoRegister { get { return (registerControlFileIOEvents & (ulong)ControlFileIOEvents.OnPostQueryFileBasicInfo) > 0; } } + + public bool IsPreQueryFileStandardInfoRegister{ get { return (registerControlFileIOEvents & (ulong)ControlFileIOEvents.OnPreQueryFileStandardInfo) > 0;} } + public bool IsPostQueryFileStandardInfoRegister { get { return (registerControlFileIOEvents & (ulong)ControlFileIOEvents.OnPostQueryFileStandardInfo) > 0; } } + + public bool IsPreQueryFileNetworkInfoRegister{ get { return (registerControlFileIOEvents & (ulong)ControlFileIOEvents.OnPreQueryFileNetworkInfo) > 0;} } + public bool IsPostQueryFileNetworkInfoRegister { get { return (registerControlFileIOEvents & (ulong)ControlFileIOEvents.OnPostQueryFileNetworkInfo) > 0; } } + + public bool IsPreQueryFileIdRegister{ get { return (registerControlFileIOEvents & (ulong)ControlFileIOEvents.OnPreQueryFileId) > 0;} } + public bool IsPostQueryFileIdRegister{ get { return (registerControlFileIOEvents & (ulong)ControlFileIOEvents.OnPostQueryFileId) > 0;} } + + public bool IsPreDeleteFileRegister{ get { return (registerControlFileIOEvents & (ulong)ControlFileIOEvents.OnPreDeleteFile) > 0;} } + public bool IsPostDeleteFileRegister { get { return (registerControlFileIOEvents & (ulong)ControlFileIOEvents.OnPostDeleteFile) > 0; } } + + public bool IsPreMoveOrRenameFileRegister{ get { return (registerControlFileIOEvents & (ulong)ControlFileIOEvents.OnPreMoveOrRenameFile) > 0;} } + public bool IsPostMoveOrRenameFileRegister { get { return (registerControlFileIOEvents & (ulong)ControlFileIOEvents.OnPostMoveOrRenameFile) > 0; } } + + public bool IsPreSetFileBasicInfoRegister{ get { return (registerControlFileIOEvents & (ulong)ControlFileIOEvents.OnPreSetFileBasicInfo) > 0;} } + public bool IsPostSetFileBasicInfoRegister { get { return (registerControlFileIOEvents & (ulong)ControlFileIOEvents.OnPostSetFileBasicInfo) > 0; } } + + public bool IsPreSetFileNetworkInfoRegister{ get { return (registerControlFileIOEvents & (ulong)ControlFileIOEvents.OnPreSetFileNetworkInfo) > 0;} } + public bool IsPostSetFileNetworkInfoRegister { get { return (registerControlFileIOEvents & (ulong)ControlFileIOEvents.OnPostSetFileNetworkInfo) > 0; } } + + public bool IsPreSetFileSizeRegister{ get { return (registerControlFileIOEvents & (ulong)ControlFileIOEvents.OnPreSetFileSize) > 0;} } + public bool IsPostSetFileSizeRegister { get { return (registerControlFileIOEvents & (ulong)ControlFileIOEvents.OnPostSetFileSize) > 0; } } + + public bool IsPreSetFileStandardInfoRegister{ get { return (registerControlFileIOEvents & (ulong)ControlFileIOEvents.OnPreSetFileStandardInfo) > 0;} } + public bool IsPostSetFileStandardInfoRegister{ get { return (registerControlFileIOEvents & (ulong)ControlFileIOEvents.OnPostSetFileStandardInfo) > 0;} } + + /// + /// Register the file control IOs callback notification for control filter + /// to allow/modify/deny the file I/O + /// + public ulong ControlFileIOEventFilter + { + get { return registerControlFileIOEvents; } + set { registerControlFileIOEvents = value;} + } + + + /// + /// set the access rights of the process based on the process name in the list + /// + public Dictionary ProcessNameAccessRightList + { + get { return processNameAccessRightList; } + set { processNameAccessRightList = value; } + } + + /// + /// Set the access rights of the processes which have the sha26 hash. + /// You can allow only the trusted process to access your files. + /// + public Dictionary Sha256ProcessAccessRightList + { + get { return sha256ProcessAccessRightList; } + set { sha256ProcessAccessRightList = value; } + } + + /// + /// set the access rights of the process which was signed with the certificate in the list + /// + public Dictionary SignedProcessAccessRightList + { + get { return signedProcessAccessRightList; } + set { signedProcessAccessRightList = value; } + } + + /// + /// set the access rights of the files for the process in the list + /// + public Dictionary ProcessIdAccessRightList + { + get { return processIdAccessRightList; } + set { processIdAccessRightList = value; } + } + + /// + /// set the access rights of the files for the users in the list + /// + public Dictionary userAccessRightList + { + get { return userNameAccessRightList; } + set { userNameAccessRightList = value; } + } + + /// + /// Control the file access rights of the filter + /// + public FilterAPI.AccessFlag AccessFlags + { + get { return (FilterAPI.AccessFlag)accessFlags; } + set { accessFlags = (uint)value; } + } + + /// + /// allow the process to read the file when it is true, or the file can't be read. + /// + public bool EnableReadFileData + { + get + { + return ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_READ_ACCESS) > 0); + } + + set + { + if (value) + { + accessFlags |= (uint)FilterAPI.AccessFlag.ALLOW_READ_ACCESS; + } + else + { + accessFlags &= ~(uint)FilterAPI.AccessFlag.ALLOW_READ_ACCESS; + } + } + } + + /// + /// allow the process to read the encrypted file when it is true, or the file can't be read. + /// + public bool EnableReadEncryptedFileData + { + get + { + return ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_READ_ENCRYPTED_FILES) > 0); + } + + set + { + if (value) + { + accessFlags |= (uint)FilterAPI.AccessFlag.ALLOW_READ_ENCRYPTED_FILES; + } + else + { + accessFlags &= ~(uint)FilterAPI.AccessFlag.ALLOW_READ_ENCRYPTED_FILES; + } + } + } + + /// + /// allow the process to write the file when it is true, or the file can't be written. + /// + public bool EnableWriteToFile + { + get + { + return ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_WRITE_ACCESS) > 0); + } + + set + { + if (value) + { + accessFlags |= (uint)FilterAPI.AccessFlag.ALLOW_WRITE_ACCESS; + } + else + { + accessFlags &= ~(uint)FilterAPI.AccessFlag.ALLOW_WRITE_ACCESS; + } + + } + } + + /// + /// allow the process to delete the file when it is true, or the file can't be deleted. + /// + public bool EnableDeleteFile + { + get + { + return ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_FILE_DELETE) > 0); + } + + set + { + if (value) + { + accessFlags |= (uint)FilterAPI.AccessFlag.ALLOW_FILE_DELETE; + } + else + { + accessFlags &= ~(uint)FilterAPI.AccessFlag.ALLOW_FILE_DELETE; + } + } + } + + /// + /// allow the process to rename or move the file when it is true, or the file can't be moved or renamed. + /// + public bool EnableRenameOrMoveFile + { + get { return ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_FILE_RENAME) > 0); } + + set + { + if (value) + { + accessFlags |= (uint)FilterAPI.AccessFlag.ALLOW_FILE_RENAME; + } + else + { + accessFlags &= ~(uint)FilterAPI.AccessFlag.ALLOW_FILE_RENAME; + } + + } + } + + + /// + /// allow the process to create the new file when it is true, or file creation will be denied. + /// + public bool EnableFileCreation + { + get + { + return ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_OPEN_WITH_CREATE_OR_OVERWRITE_ACCESS) > 0); + } + + set + { + if (value) + { + accessFlags |= (uint)FilterAPI.AccessFlag.ALLOW_OPEN_WITH_CREATE_OR_OVERWRITE_ACCESS; + } + else + { + accessFlags &= ~(uint)FilterAPI.AccessFlag.ALLOW_OPEN_WITH_CREATE_OR_OVERWRITE_ACCESS; + } + } + } + + /// + /// allow the process to browse the directory when it is true, or the directory file list can't be enumerated. + /// + public bool EnableDirectoryBrowsing + { + get + { + return ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_DIRECTORY_LIST_ACCESS) > 0); + } + + set + { + if (value) + { + accessFlags |= (uint)FilterAPI.AccessFlag.ALLOW_DIRECTORY_LIST_ACCESS; + } + else + { + accessFlags &= ~(uint)FilterAPI.AccessFlag.ALLOW_DIRECTORY_LIST_ACCESS; + } + } + } + + /// + /// allow the files being accessed by the processes from network when it is true, or the file access will be blocked. + /// + public bool EnableFileBeingAccessedViaNetwork + { + get + { + return ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_FILE_ACCESS_FROM_NETWORK) > 0); + } + + set + { + if (value) + { + accessFlags |= (uint)FilterAPI.AccessFlag.ALLOW_FILE_ACCESS_FROM_NETWORK; + } + else + { + accessFlags &= ~(uint)FilterAPI.AccessFlag.ALLOW_FILE_ACCESS_FROM_NETWORK; + } + } + } + + /// + /// allow the file's security being changed when it is true, or the file security change will be blocked. + /// + public bool EnableChangeFileSecurity + { + get + { + return ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_SET_SECURITY_ACCESS) > 0); + } + + set + { + if (value) + { + accessFlags |= (uint)FilterAPI.AccessFlag.ALLOW_SET_SECURITY_ACCESS; + } + else + { + accessFlags &= ~(uint)FilterAPI.AccessFlag.ALLOW_SET_SECURITY_ACCESS; + } + } + } + + /// + /// allow the file's information(file size,attributes,file time) being changed when it is true, or the file information change will be blocked. + /// + public bool EnableChangeFileInfo + { + get + { + return ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_SET_INFORMATION) > 0); + } + + set + { + if (value) + { + accessFlags |= (uint)FilterAPI.AccessFlag.ALLOW_SET_INFORMATION; + } + else + { + accessFlags &= ~(uint)FilterAPI.AccessFlag.ALLOW_SET_INFORMATION; + } + } + } + + /// + /// allow the file being copied when it is true, or the file copy will be blocked. + /// + public bool EnableFileBeingCopied + { + get + { + return ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_ALL_SAVE_AS) > 0); + } + + set + { + if (value) + { + accessFlags |= (uint)FilterAPI.AccessFlag.ALLOW_ALL_SAVE_AS; + } + else + { + accessFlags &= ~(uint)FilterAPI.AccessFlag.ALLOW_ALL_SAVE_AS; + } + } + } + + /// + /// allow the file being copied out from the current folder when it is true, or the file copy will be blocked. + /// + public bool EnableFileBeingCopiedOutOfFolder + { + get + { + return ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_COPY_PROTECTED_FILES_OUT) > 0); + } + + set + { + if (value) + { + accessFlags |= (uint)FilterAPI.AccessFlag.ALLOW_COPY_PROTECTED_FILES_OUT; + } + else + { + accessFlags &= ~(uint)FilterAPI.AccessFlag.ALLOW_COPY_PROTECTED_FILES_OUT; + } + + } + } + + /// + /// Enable to hide the files in directory browsing. + /// + public bool EnableHiddenFile + { + get + { + return ((accessFlags & (uint)FilterAPI.AccessFlag.ENABLE_HIDE_FILES_IN_DIRECTORY_BROWSING) > 0); + } + + set + { + if (value) + { + accessFlags |= (uint)FilterAPI.AccessFlag.ENABLE_HIDE_FILES_IN_DIRECTORY_BROWSING; + } + else + { + accessFlags &= ~(uint)FilterAPI.AccessFlag.ENABLE_HIDE_FILES_IN_DIRECTORY_BROWSING; + } + } + } + + + /// + /// Enable reparse file open to the other file. + /// + public bool EnableReparseFile + { + get + { + return ((accessFlags & (uint)FilterAPI.AccessFlag.ENABLE_REPARSE_FILE_OPEN) > 0); + } + + set + { + if (value) + { + accessFlags |= (uint)FilterAPI.AccessFlag.ENABLE_REPARSE_FILE_OPEN; + } + else + { + accessFlags &= ~(uint)FilterAPI.AccessFlag.ENABLE_REPARSE_FILE_OPEN; + } + } + } + + /// + /// Get or set the hidden file filter mask list, + /// hide the files if the file name matches the filter mask in directory browsing. + /// + public List HiddenFileFilterMaskList + { + get { return hidenFileFilterMaskList; } + set { hidenFileFilterMaskList = value; } + } + + /// + ///Get or set the reparse file filter mask list, + ///reparse the file open to the new file which the file name will be replaced with the reparse filter mask. + /// + ///For example: + ///FilterMask = c:\test\*txt + ///ReparseFilterMask = d:\reparse\*doc + ///If you open file c:\test\MyTest.txt, it will reparse to the file d:\reparse\MyTest.doc. + /// + public string ReparseFileFilterMask + { + get { return reparseFileFilterMask; } + set { reparseFileFilterMask = value; } + } + + #endregion //control property + + #region file control events you can register + + /// + /// Fires this event before the file is opened/created, + /// you can block the file open/create or reparse the file open to other file in this event. + /// + public event EventHandler OnPreCreateFile; + /// + /// Fires this event after the file is opened/created, + /// you will get the status of the create to know if the file was created or opened sucessfully. + /// + public event EventHandler OnPostCreateFile; + /// + /// Fires this event before the data of the file was read, + /// you can block the read request, or return your own read data here. + /// + public event EventHandler OnPreFileRead; + /// + /// Fires this event after the data of the file was read, + /// you can modify the return read data here. + /// + public event EventHandler OnPostFileRead; + /// + /// Fires this event before the data was written to the file, + /// you can block the write request, or modify the write data. + /// + public event EventHandler OnPreFileWrite; + /// + /// Fires this event after the data was written to the file. + /// + public event EventHandler OnPostFileWrite; + /// + /// Fires this event before the file size query goes down to the file system. + /// you can block the query request or return your own file size data here. + /// + public event EventHandler OnPreQueryFileSize; + /// + /// Fires this event after the file size query was returned from the file system. + /// you can modify the file size data here. + /// + public event EventHandler OnPostQueryFileSize; + /// + /// Fires this event before the file basic info query goes down to the file system. + /// you can block the query request or return your own file basic information. + /// + public event EventHandler OnPreQueryFileBasicInfo; + /// + /// Fires this event after the file basic info query was returned from the file system. + /// you can modify the file basic info data here. + /// + public event EventHandler OnPostQueryFileBasicInfo; + /// + /// Fires this event before the file standard info query goes down to the file system. + /// you can block the query request or return your own file standard information. + /// + public event EventHandler OnPreQueryFileStandardInfo; + /// + /// Fires this event after the file standard info query was returned from the file system. + /// you can modify the file standard info data here. + public event EventHandler OnPostQueryFileStandardInfo; + /// + /// Fires this event before the file network info query goes down to the file system. + /// you can block the query request or return your own file network information. + /// + public event EventHandler OnPreQueryFileNetworkInfo; + /// + /// Fires this event after the file network info query was returned from the file system. + /// you can modify the file network info data here. + public event EventHandler OnPostQueryFileNetworkInfo; + /// + /// Fires this event before the file Id query goes down to the file system. + /// you can block the query request. + public event EventHandler OnPreQueryFileId; + /// + /// Fires this event after the file Id query was returned from the file system. + public event EventHandler OnPostQueryFileId; + /// + /// Fires this event before the file query info goes down to the file system. + /// you can block the query request. + public event EventHandler OnPreQueryFileInfo; + /// + /// Fires this event after the file query info was returned from the file system. + public event EventHandler OnPostQueryFileInfo; + /// + /// Fires this event before the set file size request goes down to the file system. + /// you can block this event or modify the file size data here. + /// + public event EventHandler OnPreSetFileSize; + /// + /// Fires this event after the set file size request was returned from the file system. + /// + public event EventHandler OnPostSetFileSize; + /// + /// Fires this event before the set file basic info request goes down to the file system. + /// you can block this request or modify the basic info data here. + /// + public event EventHandler OnPreSetFileBasicInfo; + /// + /// Fires this event after the set file basic info request was returned from the file system. + /// + public event EventHandler OnPostSetFileBasicInfo; + /// + /// Fires this event before the set file standard info request goes down to the file system. + /// you can block this request or modify the standard info data here. + /// + public event EventHandler OnPreSetFileStandardInfo; + /// + /// Fires this event after the set file standard info request was returned from the file system. + /// + public event EventHandler OnPostSetFileStandardInfo; + /// + /// Fires this event before the set file network info request goes down to the file system. + /// you can block this request or modify the network info data here. + /// + public event EventHandler OnPreSetFileNetworkInfo; + /// + /// Fires this event after the set file network info request was returned from the file system. + /// + public event EventHandler OnPostSetFileNetworkInfo; + /// + /// Fires this event before the file was moved or renamed. + /// you can block this request here. + /// + public event EventHandler OnPreMoveOrRenameFile; + /// + /// Fires this event after the file was moved or renamed. + /// + public event EventHandler OnPostMoveOrRenameFile; + /// + /// Fires this event before the file is going to be deleted. + /// you can block this request here. + /// + public event EventHandler OnPreDeleteFile; + /// + /// Fires this event after the file was marked as deleted + /// + public event EventHandler OnPostDeleteFile; + /// + /// Fires this event before the set file info goes down to the file system. + /// you can block this request here. + /// + public event EventHandler OnPreSetFileInfo; + /// + /// Fires this event after the set file info was returned from file system. + /// + public event EventHandler OnPostSetFileInfo; + /// + /// Fires this event before the file security query goes down to the file system. + /// you can block this request or return your own security data here. + /// + public event EventHandler OnPreQueryFileSecurity; + /// + /// Fires this event after the file security query was returned from the file system. + /// you can modify the file security data here. + /// + public event EventHandler OnPostQueryFileSecurity; + /// + /// Fires this event before the set file security request goes down to the file system. + /// you can block this request or modify the file security + /// + public event EventHandler OnPreSetFileSecurity; + /// + /// Fires this event after the set file security request was returned from the file system. + /// + public event EventHandler OnPostSetFileSecurity; + /// + /// Fires this event before the directory enumeration query goes down to the file system. + /// you can block this request or return your own data here. + /// + public event EventHandler OnPreQueryDirectoryFile; + /// + /// Fires this event after the directory enumeration query was returned from the file system. + /// you can modify the return file data here, i.e. hide the file, change the file name. + /// + public event EventHandler OnPostQueryDirectoryFile; + /// + /// Fires this event before the file handle was closed. + /// + public event EventHandler OnPreFileHandleClose; + /// + /// Fires this event after the file handle was closed. + /// + public event EventHandler OnPostFileHandleClose; + /// + /// Fires this event before all system references to fileObject were closed + /// + public event EventHandler OnPreFileClose; + /// + /// Fires this event after all system references to fileObject were closed + /// + public event EventHandler OnPostFileClose; + + #endregion //file control events you can register + + public virtual bool FireControlEvents(FilterAPI.MessageSendData messageSend, ref FilterAPI.MessageReplyData messageReply) + { + bool retVal = true; + + try + { + if (messageSend.MessageType == (uint)FilterAPI.MessageType.PRE_CREATE) + { + FileCreateEventArgs fileCreateEventArgs = new FileCreateEventArgs(messageSend); + fileCreateEventArgs.Description = fileCreateEventArgs.ToString(); + + if ( messageSend.MessageType == (uint)FilterAPI.MessageType.PRE_CREATE + && null != OnPreCreateFile && IsPreFileCreateRegister ) + { + + fileCreateEventArgs.EventName = "OnPreCreateFile"; + + //invoke the create event delegate + OnPreCreateFile(this, fileCreateEventArgs); + + //you can passthrough, modify or deny the create file IO based on the return status. + messageReply.ReturnStatus = (uint)fileCreateEventArgs.ReturnStatus; + if (fileCreateEventArgs.IsDataModified || fileCreateEventArgs.ReturnStatus != NtStatus.Status.Success) + { + messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION; + + if (fileCreateEventArgs.ReturnStatus == NtStatus.Status.Reparse && fileCreateEventArgs.reparseFileName.Length > 0) + { + //reparse file open to the new file name + byte[] returnData = Encoding.Unicode.GetBytes(fileCreateEventArgs.reparseFileName); + Array.Copy(returnData, messageReply.DataBuffer, returnData.Length); + messageReply.DataBufferLength = (uint)returnData.Length; + } + } + + } + + if (fileCreateEventArgs.isDeleteOnClose && null != OnPreDeleteFile && IsPreDeleteFileRegister ) + { + fileCreateEventArgs = new FileCreateEventArgs(messageSend); + fileCreateEventArgs.EventName = "OnPreDeleteFile"; + OnPreDeleteFile(this, fileCreateEventArgs); + + //you can deny the create file IO based on the return status. + messageReply.ReturnStatus = (uint)fileCreateEventArgs.ReturnStatus; + if ( fileCreateEventArgs.ReturnStatus != NtStatus.Status.Success) + { + messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION; + } + + } + } + else if (messageSend.MessageType == (uint)FilterAPI.MessageType.POST_CREATE ) + { + FileCreateEventArgs fileCreateEventArgs = new FileCreateEventArgs(messageSend); + fileCreateEventArgs.Description = fileCreateEventArgs.ToString(); + + if (null != OnPostCreateFile && IsPostFileCreateRegister) + { + fileCreateEventArgs.EventName = "OnPostCreateFile"; + + //invoke the create event delegate + OnPostCreateFile(this, fileCreateEventArgs); + } + + if (fileCreateEventArgs.isDeleteOnClose && null != OnPostDeleteFile && IsPostDeleteFileRegister) + { + fileCreateEventArgs = new FileCreateEventArgs(messageSend); + fileCreateEventArgs.EventName = "OnPostDeleteFile"; + + OnPostDeleteFile(this, fileCreateEventArgs); + } + + messageReply.ReturnStatus = (uint)fileCreateEventArgs.ReturnStatus; + } + else if (messageSend.MessageType == (uint)FilterAPI.MessageType.PRE_CACHE_READ + || messageSend.MessageType == (uint)FilterAPI.MessageType.PRE_FASTIO_READ + || messageSend.MessageType == (uint)FilterAPI.MessageType.PRE_NOCACHE_READ + || messageSend.MessageType == (uint)FilterAPI.MessageType.PRE_PAGING_IO_READ) + { + if (null != OnPreFileRead) + { + FileReadEventArgs fileReadEventArgs = new FileReadEventArgs(messageSend); + fileReadEventArgs.EventName = "OnPreFileRead-" + fileReadEventArgs.readType; + + //invoke the event delegate + OnPreFileRead(this, fileReadEventArgs); + messageReply.ReturnStatus = (uint)fileReadEventArgs.ReturnStatus; + + if (NtStatus.Status.Success != fileReadEventArgs.ReturnStatus) + { + //block the io, and complete the pre-io. + messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION; + } + else if (fileReadEventArgs.IsDataModified) + { + //complete the pre-read IO,won't go down to the file system, replace the read data with your own data. + messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION + | (uint)FilterAPI.FilterStatus.FILTER_DATA_BUFFER_IS_UPDATED; + + Array.Copy(fileReadEventArgs.buffer, messageReply.DataBuffer, fileReadEventArgs.buffer.Length); + messageReply.DataBufferLength = (uint)fileReadEventArgs.buffer.Length; + } + + } + } + else if (messageSend.MessageType == (uint)FilterAPI.MessageType.POST_CACHE_READ + || messageSend.MessageType == (uint)FilterAPI.MessageType.POST_FASTIO_READ + || messageSend.MessageType == (uint)FilterAPI.MessageType.POST_NOCACHE_READ + || messageSend.MessageType == (uint)FilterAPI.MessageType.POST_PAGING_IO_READ) + { + if (null != OnPostFileRead) + { + FileReadEventArgs fileReadEventArgs = new FileReadEventArgs(messageSend); + fileReadEventArgs.EventName = "OnPostFileRead-" + fileReadEventArgs.readType; + + //invoke the event delegate + OnPostFileRead(this, fileReadEventArgs); + messageReply.ReturnStatus = (uint)fileReadEventArgs.ReturnStatus; + if (fileReadEventArgs.IsDataModified) + { + messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_DATA_BUFFER_IS_UPDATED; + + //replace the read data with your own data. + Array.Copy(fileReadEventArgs.buffer, messageReply.DataBuffer, fileReadEventArgs.buffer.Length); + messageReply.DataBufferLength = (uint)fileReadEventArgs.buffer.Length; + } + } + } + else if (messageSend.MessageType == (uint)FilterAPI.MessageType.PRE_CACHE_WRITE + || messageSend.MessageType == (uint)FilterAPI.MessageType.PRE_FASTIO_WRITE + || messageSend.MessageType == (uint)FilterAPI.MessageType.PRE_NOCACHE_WRITE + || messageSend.MessageType == (uint)FilterAPI.MessageType.PRE_PAGING_IO_WRITE) + { + //if the event was subscribed + if (null != OnPreFileWrite) + { + FileWriteEventArgs fileWriteEventArgs = new FileWriteEventArgs(messageSend); + fileWriteEventArgs.EventName = "OnPreFileWrite-" + fileWriteEventArgs.writeType; + + //invoke the event delegate + OnPreFileWrite(this, fileWriteEventArgs); + + //change the IO status, and modify the write data here. + messageReply.ReturnStatus = (uint)fileWriteEventArgs.ReturnStatus; + + if (NtStatus.Status.Success != fileWriteEventArgs.ReturnStatus) + { + //block the io, and complete the pre-io. + messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION; + } + else if (fileWriteEventArgs.IsDataModified) + { + //replace the write data with your own data and write it to the file. + messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_DATA_BUFFER_IS_UPDATED; + + Array.Copy(fileWriteEventArgs.buffer, messageReply.DataBuffer, fileWriteEventArgs.buffer.Length); + messageReply.DataBufferLength = (uint)fileWriteEventArgs.buffer.Length; + } + } + } + else if (messageSend.MessageType == (uint)FilterAPI.MessageType.POST_CACHE_WRITE + || messageSend.MessageType == (uint)FilterAPI.MessageType.POST_FASTIO_WRITE + || messageSend.MessageType == (uint)FilterAPI.MessageType.POST_NOCACHE_WRITE + || messageSend.MessageType == (uint)FilterAPI.MessageType.POST_PAGING_IO_WRITE) + { + //if the event was subscribed + if (null != OnPostFileWrite) + { + FileWriteEventArgs fileWriteEventArgs = new FileWriteEventArgs(messageSend); + fileWriteEventArgs.EventName = "OnPostFileWrite;" + fileWriteEventArgs.writeType; + + //invoke the event delegate + OnPostFileWrite(this, fileWriteEventArgs); + + messageReply.ReturnStatus = (uint)fileWriteEventArgs.ReturnStatus; + } + + } + else if (messageSend.MessageType == (uint)FilterAPI.MessageType.PRE_QUERY_INFORMATION) + { + if (messageSend.InfoClass == (uint)WinData.FileInfomationClass.FileEndOfFileInformation && IsPreQueryFileSizeRegister) + { + //if the event was subscribed + if (null != OnPreQueryFileSize) + { + FileSizeEventArgs fileSizeArgs = new FileSizeEventArgs(messageSend); + fileSizeArgs.EventName = "OnPreQueryFileSize"; + + //invoke the event delegate + OnPreQueryFileSize(this, fileSizeArgs); + + messageReply.ReturnStatus = (uint)fileSizeArgs.ReturnStatus; + + if (NtStatus.Status.Success != fileSizeArgs.ReturnStatus) + { + //block the io, and complete the pre-io. + messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION; + } + else if (fileSizeArgs.IsDataModified) + { + //replace the file size with your own data and complete pre-io. + messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_DATA_BUFFER_IS_UPDATED | (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION; + + byte[] buffer = BitConverter.GetBytes(fileSizeArgs.fileSizeToQueryOrSet); + Array.Copy(buffer, messageReply.DataBuffer, buffer.Length); + messageReply.DataBufferLength = (uint)buffer.Length; + } + + } + } + else if (messageSend.InfoClass == (uint)WinData.FileInfomationClass.FileInternalInformation ) + { + //if the event was subscribed + if (null != OnPreQueryFileId && IsPreQueryFileIdRegister) + { + FileIdEventArgs fileIdArgs = new FileIdEventArgs(messageSend); + fileIdArgs.EventName = "OnPreQueryFileId"; + + //invoke the event delegate + OnPreQueryFileId(this, fileIdArgs); + + messageReply.ReturnStatus = (uint)fileIdArgs.ReturnStatus; + + if (NtStatus.Status.Success != fileIdArgs.ReturnStatus) + { + //block the io, and complete the pre-io. + messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION; + } + + } + } + else if (messageSend.InfoClass == (uint)WinData.FileInfomationClass.FileBasicInformation) + { + //if the event was subscribed + if (null != OnPreQueryFileBasicInfo && IsPreQueryBasicInfoRegister) + { + FileBasicInfoEventArgs fileBasicInfoArgs = new FileBasicInfoEventArgs(messageSend); + fileBasicInfoArgs.EventName = "OnPreQueryFileBasicInfo"; + + //invoke the event delegate + OnPreQueryFileBasicInfo(this, fileBasicInfoArgs); + + messageReply.ReturnStatus = (uint)fileBasicInfoArgs.ReturnStatus; + + if (NtStatus.Status.Success != fileBasicInfoArgs.ReturnStatus) + { + //block the io, and complete the pre-io. + messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION; + } + else if (fileBasicInfoArgs.IsDataModified) + { + //replace the file basic info data with your own data,complete pre-io. + messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_DATA_BUFFER_IS_UPDATED | (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION; + + int len = Marshal.SizeOf(fileBasicInfoArgs.basicInfo); + IntPtr ptr = Marshal.AllocHGlobal(len); + Marshal.StructureToPtr(fileBasicInfoArgs.basicInfo, ptr, true); + Marshal.Copy(ptr, messageReply.DataBuffer, 0, len); + Marshal.FreeHGlobal(ptr); + messageReply.DataBufferLength = (uint)len; + + } + } + } + else if (messageSend.InfoClass == (uint)WinData.FileInfomationClass.FileStandardInformation) + { + //if the event was subscribed + if (null != OnPreQueryFileStandardInfo && IsPreQueryFileStandardInfoRegister) + { + FileStandardInfoEventArgs fileStandardInfoArgs = new FileStandardInfoEventArgs(messageSend); + fileStandardInfoArgs.EventName = "OnPreQueryFileStandardInfo"; + + //invoke the event delegate + OnPreQueryFileStandardInfo(this, fileStandardInfoArgs); + + messageReply.ReturnStatus = (uint)fileStandardInfoArgs.ReturnStatus; + + if (NtStatus.Status.Success != fileStandardInfoArgs.ReturnStatus) + { + //block the io, and complete the pre-io. + messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION; + } + else if (fileStandardInfoArgs.IsDataModified) + { + //replace the file standardInfo data with your own data. + messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_DATA_BUFFER_IS_UPDATED | (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION; + + int len = Marshal.SizeOf(fileStandardInfoArgs.standardInfo); + IntPtr ptr = Marshal.AllocHGlobal(len); + Marshal.StructureToPtr(fileStandardInfoArgs.standardInfo, ptr, true); + Marshal.Copy(ptr, messageReply.DataBuffer, 0, len); + Marshal.FreeHGlobal(ptr); + messageReply.DataBufferLength = (uint)len; + + } + } + } + else if (messageSend.InfoClass == (uint)WinData.FileInfomationClass.FileNetworkOpenInformation) + { + //if the event was subscribed + if (null != OnPreQueryFileNetworkInfo && IsPreQueryFileNetworkInfoRegister) + { + FileNetworkInfoEventArgs fileNetworkInfoArgs = new FileNetworkInfoEventArgs(messageSend); + fileNetworkInfoArgs.EventName = "OnPreQueryFileNetworkInfo"; + + //invoke the event delegate + OnPreQueryFileNetworkInfo(this, fileNetworkInfoArgs); + + messageReply.ReturnStatus = (uint)fileNetworkInfoArgs.ReturnStatus; + + if (NtStatus.Status.Success != fileNetworkInfoArgs.ReturnStatus) + { + //block the io, and complete the pre-io. + messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION; + } + else if (fileNetworkInfoArgs.IsDataModified) + { + //replace the file standardInfo data with your own data. + messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_DATA_BUFFER_IS_UPDATED | (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION; + + int len = Marshal.SizeOf(fileNetworkInfoArgs.networkInfo); + IntPtr ptr = Marshal.AllocHGlobal(len); + Marshal.StructureToPtr(fileNetworkInfoArgs.networkInfo, ptr, true); + Marshal.Copy(ptr, messageReply.DataBuffer, 0, len); + Marshal.FreeHGlobal(ptr); + messageReply.DataBufferLength = (uint)len; + + } + + } + } + else if (null != OnPreQueryFileInfo ) + { + FileInfoArgs fileInfoArgs = new FileInfoArgs(messageSend); + fileInfoArgs.EventName = "OnPreQueryFileInfo:" + fileInfoArgs.FileInfoClass.ToString(); + + //invoke the event delegate + OnPreQueryFileInfo(this, fileInfoArgs); + + messageReply.ReturnStatus = (uint)fileInfoArgs.ReturnStatus; + + if (NtStatus.Status.Success != fileInfoArgs.ReturnStatus) + { + //block the io, and complete the pre-io. + messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION; + } + else if (fileInfoArgs.IsDataModified) + { + //replace the file standardInfo data with your own data. + } + + } + } + else if (messageSend.MessageType == (uint)FilterAPI.MessageType.POST_QUERY_INFORMATION) + { + if (messageSend.InfoClass == (uint)WinData.FileInfomationClass.FileEndOfFileInformation) + { + //if the event was subscribed + if (null != OnPostQueryFileSize && IsPostQueryFileSizeRegister) + { + FileSizeEventArgs fileSizeArgs = new FileSizeEventArgs(messageSend); + fileSizeArgs.EventName = "OnPostQueryFileSize"; + + //invoke the event delegate + OnPostQueryFileSize(this, fileSizeArgs); + + messageReply.ReturnStatus = (uint)fileSizeArgs.ReturnStatus; + if (fileSizeArgs.IsDataModified) + { + //replace the file size with your own data. + messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_DATA_BUFFER_IS_UPDATED; + + byte[] buffer = BitConverter.GetBytes(fileSizeArgs.fileSizeToQueryOrSet); + Array.Copy(buffer, messageReply.DataBuffer, buffer.Length); + messageReply.DataBufferLength = (uint)buffer.Length; + } + + } + } + else if (messageSend.InfoClass == (uint)WinData.FileInfomationClass.FileInternalInformation) + { + //if the event was subscribed + if (null != OnPostQueryFileId && IsPostQueryFileIdRegister) + { + FileIdEventArgs fileIdArgs = new FileIdEventArgs(messageSend); + fileIdArgs.EventName = "OnPostQueryFileId"; + + //invoke the event delegate + OnPostQueryFileId(this, fileIdArgs); + messageReply.ReturnStatus = (uint)fileIdArgs.ReturnStatus; + + } + } + else if (messageSend.InfoClass == (uint)WinData.FileInfomationClass.FileBasicInformation) + { + //if the event was subscribed + if (null != OnPostQueryFileBasicInfo && IsPostQueryBasicInfoRegister) + { + FileBasicInfoEventArgs fileBasicInfoArgs = new FileBasicInfoEventArgs(messageSend); + fileBasicInfoArgs.EventName = "OnPostQueryFileBasicInfo"; + + //invoke the event delegate + OnPostQueryFileBasicInfo(this, fileBasicInfoArgs); + + messageReply.ReturnStatus = (uint)fileBasicInfoArgs.ReturnStatus; + if (fileBasicInfoArgs.IsDataModified) + { + //replace the file basic info data with your own data. + messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_DATA_BUFFER_IS_UPDATED; + + int len = Marshal.SizeOf(fileBasicInfoArgs.basicInfo); + IntPtr ptr = Marshal.AllocHGlobal(len); + Marshal.StructureToPtr(fileBasicInfoArgs.basicInfo, ptr, true); + Marshal.Copy(ptr, messageReply.DataBuffer, 0, len); + Marshal.FreeHGlobal(ptr); + messageReply.DataBufferLength = (uint)len; + + } + + } + } + else if (messageSend.InfoClass == (uint)WinData.FileInfomationClass.FileStandardInformation) + { + //if the event was subscribed + if (null != OnPostQueryFileStandardInfo && IsPostQueryFileStandardInfoRegister) + { + FileStandardInfoEventArgs fileStandardInfoArgs = new FileStandardInfoEventArgs(messageSend); + fileStandardInfoArgs.EventName = "OnPostQueryFileStandardInfo"; + + //invoke the event delegate + OnPostQueryFileStandardInfo(this, fileStandardInfoArgs); + + messageReply.ReturnStatus = (uint)fileStandardInfoArgs.ReturnStatus; + if (fileStandardInfoArgs.IsDataModified) + { + //replace the file standardInfo data with your own data. + messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_DATA_BUFFER_IS_UPDATED; + + int len = Marshal.SizeOf(fileStandardInfoArgs.standardInfo); + IntPtr ptr = Marshal.AllocHGlobal(len); + Marshal.StructureToPtr(fileStandardInfoArgs.standardInfo, ptr, true); + Marshal.Copy(ptr, messageReply.DataBuffer, 0, len); + Marshal.FreeHGlobal(ptr); + messageReply.DataBufferLength = (uint)len; + + } + + } + } + else if (messageSend.InfoClass == (uint)WinData.FileInfomationClass.FileNetworkOpenInformation) + { + //if the event was subscribed + if (null != OnPostQueryFileNetworkInfo && IsPostQueryFileNetworkInfoRegister ) + { + FileNetworkInfoEventArgs fileNetworkInfoArgs = new FileNetworkInfoEventArgs(messageSend); + fileNetworkInfoArgs.EventName = "OnPostQueryFileNetworkInfo"; + + //invoke the event delegate + OnPostQueryFileNetworkInfo(this, fileNetworkInfoArgs); + + messageReply.ReturnStatus = (uint)fileNetworkInfoArgs.ReturnStatus; + if (fileNetworkInfoArgs.IsDataModified) + { + //replace the file standardInfo data with your own data. + messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_DATA_BUFFER_IS_UPDATED; + + int len = Marshal.SizeOf(fileNetworkInfoArgs.networkInfo); + IntPtr ptr = Marshal.AllocHGlobal(len); + Marshal.StructureToPtr(fileNetworkInfoArgs.networkInfo, ptr, true); + Marshal.Copy(ptr, messageReply.DataBuffer, 0, len); + Marshal.FreeHGlobal(ptr); + messageReply.DataBufferLength = (uint)len; + + } + } + } + else if (null != OnPostQueryFileInfo) + { + FileInfoArgs fileInfoArgs = new FileInfoArgs(messageSend); + fileInfoArgs.EventName = "OnPostQueryFileInfo:" + fileInfoArgs.FileInfoClass.ToString(); + + //invoke the event delegate + OnPostQueryFileInfo(this, fileInfoArgs); + + messageReply.ReturnStatus = (uint)fileInfoArgs.ReturnStatus; + if (fileInfoArgs.IsDataModified) + { + //replace the file standardInfo data with your own data. + } + + } + } + else if (messageSend.MessageType == (uint)FilterAPI.MessageType.PRE_SET_INFORMATION) + { + if (messageSend.InfoClass == (uint)WinData.FileInfomationClass.FileEndOfFileInformation) + { + //if the event was subscribed + if (null != OnPreSetFileSize && IsPreSetFileSizeRegister) + { + FileSizeEventArgs fileSizeArgs = new FileSizeEventArgs(messageSend); + fileSizeArgs.EventName = "OnPreSetFileSize"; + + //invoke the event delegate + OnPreSetFileSize(this, fileSizeArgs); + + messageReply.ReturnStatus = (uint)fileSizeArgs.ReturnStatus; + + + if (NtStatus.Status.Success != fileSizeArgs.ReturnStatus) + { + //block the io, and complete the pre-io. + messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION; + } + else if (fileSizeArgs.IsDataModified) + { + //replace the file size with your own data. + messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_DATA_BUFFER_IS_UPDATED; + + byte[] buffer = BitConverter.GetBytes(fileSizeArgs.fileSizeToQueryOrSet); + Array.Copy(buffer, messageReply.DataBuffer, buffer.Length); + messageReply.DataBufferLength = (uint)buffer.Length; + } + + } + } + else if (messageSend.InfoClass == (uint)WinData.FileInfomationClass.FileBasicInformation ) + { + //if the event was subscribed + if (null != OnPreSetFileBasicInfo && IsPreSetFileBasicInfoRegister) + { + FileBasicInfoEventArgs fileBasicInfoArgs = new FileBasicInfoEventArgs(messageSend); + fileBasicInfoArgs.EventName = "OnPreSetFileBasicInfo"; + + //invoke the event delegate + OnPreSetFileBasicInfo(this, fileBasicInfoArgs); + + messageReply.ReturnStatus = (uint)fileBasicInfoArgs.ReturnStatus; + + if (NtStatus.Status.Success != fileBasicInfoArgs.ReturnStatus) + { + //block the io, and complete the pre-io. + messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION; + } + else if (fileBasicInfoArgs.IsDataModified) + { + //replace the file basic info data with your own data. + messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_DATA_BUFFER_IS_UPDATED; + + int len = Marshal.SizeOf(fileBasicInfoArgs.basicInfo); + IntPtr ptr = Marshal.AllocHGlobal(len); + Marshal.StructureToPtr(fileBasicInfoArgs.basicInfo, ptr, true); + Marshal.Copy(ptr, messageReply.DataBuffer, 0, len); + Marshal.FreeHGlobal(ptr); + messageReply.DataBufferLength = (uint)len; + + } + } + } + else if (messageSend.InfoClass == (uint)WinData.FileInfomationClass.FileStandardInformation ) + { + //if the event was subscribed + if (null != OnPreSetFileStandardInfo && IsPreSetFileStandardInfoRegister) + { + FileStandardInfoEventArgs fileStandardInfoArgs = new FileStandardInfoEventArgs(messageSend); + fileStandardInfoArgs.EventName = "OnPreSetFileStandardInfo"; + + //invoke the event delegate + OnPreSetFileStandardInfo(this, fileStandardInfoArgs); + + messageReply.ReturnStatus = (uint)fileStandardInfoArgs.ReturnStatus; + + if (NtStatus.Status.Success != fileStandardInfoArgs.ReturnStatus) + { + //block the io, and complete the pre-io. + messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION; + } + else if (fileStandardInfoArgs.IsDataModified) + { + //replace the file standardInfo data with your own data. + messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_DATA_BUFFER_IS_UPDATED; + + int len = Marshal.SizeOf(fileStandardInfoArgs.standardInfo); + IntPtr ptr = Marshal.AllocHGlobal(len); + Marshal.StructureToPtr(fileStandardInfoArgs.standardInfo, ptr, true); + Marshal.Copy(ptr, messageReply.DataBuffer, 0, len); + Marshal.FreeHGlobal(ptr); + messageReply.DataBufferLength = (uint)len; + + } + } + } + else if (messageSend.InfoClass == (uint)WinData.FileInfomationClass.FileNetworkOpenInformation) + { + //if the event was subscribed + if (null != OnPreSetFileNetworkInfo && IsPreSetFileNetworkInfoRegister) + { + FileNetworkInfoEventArgs fileNetworkInfoArgs = new FileNetworkInfoEventArgs(messageSend); + fileNetworkInfoArgs.EventName = "OnPreSetFileNetworkInfo"; + + //invoke the event delegate + OnPreSetFileNetworkInfo(this, fileNetworkInfoArgs); + + messageReply.ReturnStatus = (uint)fileNetworkInfoArgs.ReturnStatus; + + if (NtStatus.Status.Success != fileNetworkInfoArgs.ReturnStatus) + { + //block the io, and complete the pre-io. + messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION; + } + else if (fileNetworkInfoArgs.IsDataModified) + { + //replace the file standardInfo data with your own data. + messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_DATA_BUFFER_IS_UPDATED; + + int len = Marshal.SizeOf(fileNetworkInfoArgs.networkInfo); + IntPtr ptr = Marshal.AllocHGlobal(len); + Marshal.StructureToPtr(fileNetworkInfoArgs.networkInfo, ptr, true); + Marshal.Copy(ptr, messageReply.DataBuffer, 0, len); + Marshal.FreeHGlobal(ptr); + messageReply.DataBufferLength = (uint)len; + + } + + } + } + else if (messageSend.InfoClass == (uint)WinData.FileInfomationClass.FileRenameInformation + || messageSend.InfoClass == (uint)WinData.FileInfomationClass.FileRenameInformationEx) + { + //if the event was subscribed + if (null != OnPreMoveOrRenameFile && IsPreMoveOrRenameFileRegister) + { + FileMoveOrRenameEventArgs fileRenameArgs = new FileMoveOrRenameEventArgs(messageSend); + fileRenameArgs.EventName = "OnPreMoveOrRenameFile"; + + //invoke the event delegate + OnPreMoveOrRenameFile(this, fileRenameArgs); + + messageReply.ReturnStatus = (uint)fileRenameArgs.ReturnStatus; + if (NtStatus.Status.Success != fileRenameArgs.ReturnStatus) + { + //block the io, and complete the pre-io. + messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION; + } + } + } + else if (messageSend.InfoClass == (uint)WinData.FileInfomationClass.FileDispositionInformation + || messageSend.InfoClass == (uint)WinData.FileInfomationClass.FileDispositionInformationEx) + { + //if the event was subscribed + if (null != OnPreDeleteFile && IsPreDeleteFileRegister) + { + FileIOEventArgs fileIOArgs = new FileIOEventArgs(messageSend); + fileIOArgs.EventName = "OnPreDeleteFile"; + fileIOArgs.Description = "The file is going to be deleted."; + + //invoke the event delegate + OnPreDeleteFile(this, fileIOArgs); + + messageReply.ReturnStatus = (uint)fileIOArgs.ReturnStatus; + if (NtStatus.Status.Success != fileIOArgs.ReturnStatus) + { + //block the io, and complete the pre-io. + messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION; + } + } + } + else if (null != OnPreSetFileInfo) + { + FileInfoArgs fileInfoArgs = new FileInfoArgs(messageSend); + fileInfoArgs.EventName = "OnPreSetFileInfo:" + fileInfoArgs.FileInfoClass.ToString(); + + //invoke the event delegate + OnPreSetFileInfo(this, fileInfoArgs); + + messageReply.ReturnStatus = (uint)fileInfoArgs.ReturnStatus; + if (NtStatus.Status.Success != fileInfoArgs.ReturnStatus) + { + //block the io, and complete the pre-io. + messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION; + } + + } + } + else if (messageSend.MessageType == (uint)FilterAPI.MessageType.POST_SET_INFORMATION) + { + if (messageSend.InfoClass == (uint)WinData.FileInfomationClass.FileEndOfFileInformation) + { + //if the event was subscribed + if (null != OnPostSetFileSize && IsPostSetFileSizeRegister) + { + FileSizeEventArgs fileSizeArgs = new FileSizeEventArgs(messageSend); + fileSizeArgs.EventName = "OnPostSetFileSize"; + + //invoke the event delegate + OnPostSetFileSize(this, fileSizeArgs); + messageReply.ReturnStatus = (uint)fileSizeArgs.ReturnStatus; + } + } + else if (messageSend.InfoClass == (uint)WinData.FileInfomationClass.FileBasicInformation) + { + //if the event was subscribed + if (null != OnPostSetFileBasicInfo && IsPostSetFileBasicInfoRegister) + { + FileBasicInfoEventArgs fileBasicInfoArgs = new FileBasicInfoEventArgs(messageSend); + fileBasicInfoArgs.EventName = "OnPostSetFileBasicInfo"; + + //invoke the event delegate + OnPostSetFileBasicInfo(this, fileBasicInfoArgs); + messageReply.ReturnStatus = (uint)fileBasicInfoArgs.ReturnStatus; + } + } + else if (messageSend.InfoClass == (uint)WinData.FileInfomationClass.FileStandardInformation) + { + //if the event was subscribed + if (null != OnPostSetFileStandardInfo && IsPostSetFileStandardInfoRegister) + { + FileStandardInfoEventArgs fileStandardInfoArgs = new FileStandardInfoEventArgs(messageSend); + fileStandardInfoArgs.EventName = "OnPostSetFileStandardInfo"; + + //invoke the event delegate + OnPostSetFileStandardInfo(this, fileStandardInfoArgs); + messageReply.ReturnStatus = (uint)fileStandardInfoArgs.ReturnStatus; + } + } + else if (messageSend.InfoClass == (uint)WinData.FileInfomationClass.FileNetworkOpenInformation) + { + //if the event was subscribed + if (null != OnPostSetFileNetworkInfo && IsPostSetFileNetworkInfoRegister) + { + FileNetworkInfoEventArgs fileNetworkInfoArgs = new FileNetworkInfoEventArgs(messageSend); + fileNetworkInfoArgs.EventName = "OnPostSetFileNetworkInfo"; + + //invoke the event delegate + OnPostSetFileNetworkInfo(this, fileNetworkInfoArgs); + messageReply.ReturnStatus = (uint)fileNetworkInfoArgs.ReturnStatus; + } + } + else if (messageSend.InfoClass == (uint)WinData.FileInfomationClass.FileRenameInformation + || messageSend.InfoClass == (uint)WinData.FileInfomationClass.FileRenameInformationEx ) + { + //if the event was subscribed + if (null != OnPostMoveOrRenameFile&& IsPostMoveOrRenameFileRegister) + { + FileMoveOrRenameEventArgs fileRenameArgs = new FileMoveOrRenameEventArgs(messageSend); + fileRenameArgs.EventName = "OnPostMoveOrRenameFile"; + + //invoke the event delegate + OnPostMoveOrRenameFile(this, fileRenameArgs); + messageReply.ReturnStatus = (uint)fileRenameArgs.ReturnStatus; + } + } + else if (messageSend.InfoClass == (uint)WinData.FileInfomationClass.FileDispositionInformation + || messageSend.InfoClass == (uint)WinData.FileInfomationClass.FileDispositionInformationEx) + { + //if the event was subscribed + if (null != OnPostDeleteFile && IsPostDeleteFileRegister) + { + FileIOEventArgs fileIOArgs = new FileIOEventArgs(messageSend); + fileIOArgs.EventName = "OnPostDeleteFile"; + fileIOArgs.Description = "The file was deleted."; + + //invoke the event delegate + OnPostDeleteFile(this, fileIOArgs); + messageReply.ReturnStatus = (uint)fileIOArgs.ReturnStatus; + + } + } + else if (null != OnPostSetFileInfo) + { + FileInfoArgs fileInfoArgs = new FileInfoArgs(messageSend); + fileInfoArgs.EventName = "OnPostSetFileInfo:" + fileInfoArgs.FileInfoClass.ToString(); + + //invoke the event delegate + OnPostSetFileInfo(this, fileInfoArgs); + messageReply.ReturnStatus = (uint)fileInfoArgs.ReturnStatus; + } + } + else if (messageSend.MessageType == (uint)FilterAPI.MessageType.PRE_QUERY_SECURITY) + { + //if the event was subscribed + if (null != OnPreQueryFileSecurity) + { + FileSecurityEventArgs fileSecurityArgs = new FileSecurityEventArgs(messageSend); + fileSecurityArgs.EventName = "OnPreQueryFileSecurity"; + + //invoke the event delegate + OnPreQueryFileSecurity(this, fileSecurityArgs); + + messageReply.ReturnStatus = (uint)fileSecurityArgs.ReturnStatus; + + if (NtStatus.Status.Success != fileSecurityArgs.ReturnStatus) + { + //block the io, and complete the pre-io. + messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION; + } + else if (fileSecurityArgs.IsDataModified) + { + //replace the file security data with your own data. + messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_DATA_BUFFER_IS_UPDATED | (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION; + + Array.Copy(fileSecurityArgs.securityBuffer, messageReply.DataBuffer, fileSecurityArgs.securityBuffer.Length); + messageReply.DataBufferLength = (uint)fileSecurityArgs.securityBuffer.Length; + + } + } + } + else if (messageSend.MessageType == (uint)FilterAPI.MessageType.POST_QUERY_SECURITY) + { + //if the event was subscribed + if (null != OnPostQueryFileSecurity) + { + FileSecurityEventArgs fileSecurityArgs = new FileSecurityEventArgs(messageSend); + fileSecurityArgs.EventName = "OnPostQueryFileSecurity"; + + //invoke the event delegate + OnPostQueryFileSecurity(this, fileSecurityArgs); + messageReply.ReturnStatus = (uint)fileSecurityArgs.ReturnStatus; + } + } + else if (messageSend.MessageType == (uint)FilterAPI.MessageType.PRE_SET_SECURITY) + { + //if the event was subscribed + if (null != OnPreSetFileSecurity) + { + FileSecurityEventArgs fileSecurityArgs = new FileSecurityEventArgs(messageSend); + fileSecurityArgs.EventName = "OnPreSetFileSecurity"; + + //invoke the event delegate + OnPreSetFileSecurity(this, fileSecurityArgs); + if (NtStatus.Status.Success != fileSecurityArgs.ReturnStatus) + { + //block the io, and complete the pre-io. + messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION; + } + else if (fileSecurityArgs.IsDataModified) + { + //replace the file security data with your own data. + messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_DATA_BUFFER_IS_UPDATED | (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION; + + Array.Copy(fileSecurityArgs.securityBuffer, messageReply.DataBuffer, fileSecurityArgs.securityBuffer.Length); + messageReply.DataBufferLength = (uint)fileSecurityArgs.securityBuffer.Length; + + } + + } + } + else if (messageSend.MessageType == (uint)FilterAPI.MessageType.POST_SET_SECURITY) + { + //if the event was subscribed + if (null != OnPostSetFileSecurity) + { + FileSecurityEventArgs fileSecurityArgs = new FileSecurityEventArgs(messageSend); + fileSecurityArgs.EventName = "OnPostSetFileSecurity"; + + //invoke the event delegate + OnPostSetFileSecurity(this, fileSecurityArgs); + messageReply.ReturnStatus = (uint)fileSecurityArgs.ReturnStatus; + } + } + else if (messageSend.MessageType == (uint)FilterAPI.MessageType.PRE_DIRECTORY) + { + //if the event was subscribed + if (null != OnPreQueryDirectoryFile) + { + FileQueryDirectoryEventArgs directoryArgs = new FileQueryDirectoryEventArgs(messageSend); + directoryArgs.EventName = "OnPreQueryDirectoryFile"; + + //invoke the event delegate + OnPreQueryDirectoryFile(this, directoryArgs); + + messageReply.ReturnStatus = (uint)directoryArgs.ReturnStatus; + + if (NtStatus.Status.Success != directoryArgs.ReturnStatus) + { + //block the io, and complete the pre-io. + messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION; + } + else if (directoryArgs.IsDataModified) + { + //replace the directory data with your own data. + messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_DATA_BUFFER_IS_UPDATED | (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION; + + Array.Copy(directoryArgs.directoryBuffer, messageReply.DataBuffer, directoryArgs.directoryBuffer.Length); + messageReply.DataBufferLength = (uint)directoryArgs.directoryBuffer.Length; + + } + } + } + else if (messageSend.MessageType == (uint)FilterAPI.MessageType.POST_DIRECTORY) + { + //if the event was subscribed + if (null != OnPostQueryDirectoryFile) + { + FileQueryDirectoryEventArgs directoryArgs = new FileQueryDirectoryEventArgs(messageSend); + directoryArgs.EventName = "OnPostQueryDirectoryFile"; + + //invoke the event delegate + OnPostQueryDirectoryFile(this, directoryArgs); + + messageReply.ReturnStatus = (uint)directoryArgs.ReturnStatus; + + if (directoryArgs.IsDataModified) + { + //replace the directory data with your own data. + messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_DATA_BUFFER_IS_UPDATED; + + Array.Copy(directoryArgs.directoryBuffer, messageReply.DataBuffer, directoryArgs.directoryBuffer.Length); + messageReply.DataBufferLength = (uint)directoryArgs.directoryBuffer.Length; + + } + } + } + else if (messageSend.MessageType == (uint)FilterAPI.MessageType.PRE_CLEANUP) + { + //if the event was subscribed + if (null != OnPreFileHandleClose) + { + FileIOEventArgs fileIOArgs = new FileIOEventArgs(messageSend); + fileIOArgs.EventName = "OnPreFileHandleClose"; + fileIOArgs.Description = "The opened file handle is going to close."; + + //invoke the event delegate + OnPreFileHandleClose(this, fileIOArgs); + } + } + else if (messageSend.MessageType == (uint)FilterAPI.MessageType.POST_CLEANUP) + { + //if the event was subscribed + if (null != OnPostFileHandleClose) + { + FileIOEventArgs fileIOArgs = new FileIOEventArgs(messageSend); + fileIOArgs.EventName = "OnPostFileHandleClose"; + fileIOArgs.Description = "The opened file handle was closed."; + + //invoke the event delegate + OnPostFileHandleClose(this, fileIOArgs); + } + } + else if (messageSend.MessageType == (uint)FilterAPI.MessageType.PRE_CLOSE) + { + //if the event was subscribed + if (null != OnPreFileClose) + { + FileIOEventArgs fileIOArgs = new FileIOEventArgs(messageSend); + fileIOArgs.EventName = "OnPreFileClose"; + fileIOArgs.Description = "All references to the fileObject " + messageSend.FileObject.ToString("X") + " are going to close."; + + //invoke the event delegate + OnPreFileClose(this, fileIOArgs); + } + } + else if (messageSend.MessageType == (uint)FilterAPI.MessageType.POST_CLOSE) + { + //if the event was subscribed + if (null != OnPostFileClose) + { + FileIOEventArgs fileIOArgs = new FileIOEventArgs(messageSend); + fileIOArgs.EventName = "OnPostFileClose"; + fileIOArgs.Description = "All references to the fileObject " + messageSend.FileObject.ToString("X") + " were closed."; + + //invoke the event delegate + OnPostFileClose(this, fileIOArgs); + } + } + + } + catch (Exception ex) + { + Console.WriteLine("FileControlEvents exception:" + ex.Message); + } + + + return retVal; + } + } +} diff --git a/Demo_Source_Code/CSharpDemo/FilterControl/EncryptionFilter.cs b/Demo_Source_Code/CSharpDemo/FilterControl/EncryptionFilter.cs new file mode 100644 index 0000000..488c352 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FilterControl/EncryptionFilter.cs @@ -0,0 +1,372 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; + +namespace EaseFilter.FilterControl +{ + partial class FileFilter + { + /// + /// Fires this event when the encrypted file request the encryption key and iv. + /// + public event EventHandler OnFilterRequestEncryptKey; + + /// + /// if the encryption was enabled, this is the encryption key that will be used for the encrypted file. + /// + byte[] encryptionKey = null; + + /// + /// generate encryption key with this passphrase + /// + string encryptionPassPhrase = string.Empty; + + /// + /// enable the encryption with the same IV if it is not empty. + /// + byte[] encryptionIV = null; + + uint encryptWriteBufferSize = 0; + + /// + /// If the encrypt write buffer size is greater than 0, then the small buffer encryption write will be combined together to a bigger buffer, + /// and write it to the disk. + /// + public uint EncryptWriteBufferSize + { + get { return encryptWriteBufferSize; } + set { encryptWriteBufferSize = value; } + } + + /// + /// Enable the encryption feature when it is true + /// only when the license key supports the encryption filter driver. + /// + public bool EnableEncryption + { + get + { + return ((accessFlags & (uint)FilterAPI.AccessFlag.ENABLE_FILE_ENCRYPTION_RULE) > 0); + } + + set + { + if (value) + { + accessFlags |= (uint)FilterAPI.AccessFlag.ENABLE_FILE_ENCRYPTION_RULE; + } + else + { + accessFlags &= ~(uint)FilterAPI.AccessFlag.ENABLE_FILE_ENCRYPTION_RULE; + } + } + } + + /// + /// Encrypt the new created file when it is true and the encryption was enabled. + /// + public bool EnableEncryptNewFile + { + get + { + return ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_ENCRYPT_NEW_FILE) > 0); + } + + set + { + if (value) + { + accessFlags |= (uint)FilterAPI.AccessFlag.ALLOW_ENCRYPT_NEW_FILE; + } + else + { + accessFlags &= ~(uint)FilterAPI.AccessFlag.ALLOW_ENCRYPT_NEW_FILE; + } + } + } + + /// + /// Automatically decrypt the data in read when it is true, + /// or you will get thw raw data of the encrypted file. + /// + public bool EnableReadEncryptedData + { + get + { + return ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_READ_ENCRYPTED_FILES) > 0); + } + + set + { + if (value) + { + accessFlags |= (uint)FilterAPI.AccessFlag.ALLOW_READ_ENCRYPTED_FILES; + } + else + { + accessFlags &= ~(uint)FilterAPI.AccessFlag.ALLOW_READ_ENCRYPTED_FILES; + } + } + } + + /// + /// This feature is to encrypt the data on the read when the encryption was enabled, encrypt new file was disabled. + /// the file won't be encrypted in the local disk, i.e. encrypt the file before it was sent out of your folder. + /// + public bool EnableEncryptionOnTheGo + { + get + { + return ((accessFlags & (uint)FilterAPI.AccessFlag.DISABLE_ENCRYPT_DATA_ON_READ) > 0); + } + + set + { + if (value) + { + accessFlags &= ~(uint)FilterAPI.AccessFlag.DISABLE_ENCRYPT_DATA_ON_READ; + } + else + { + accessFlags |= (uint)FilterAPI.AccessFlag.DISABLE_ENCRYPT_DATA_ON_READ; + } + } + } + + /// + /// if the encryption feature was enabled and this value is true, every new encrypted file + /// requires the encryption key, iv and tag data from the user mode service. + /// + public bool EnableEncryptionKeyFromService + { + get + { + return ((booleanConfig & (uint)FilterAPI.BooleanConfig.REQUEST_ENCRYPT_KEY_IV_AND_TAGDATA_FROM_SERVICE) > 0); + } + set + { + if (value) + { + booleanConfig |= (uint)FilterAPI.BooleanConfig.REQUEST_ENCRYPT_KEY_IV_AND_TAGDATA_FROM_SERVICE; + } + else + { + booleanConfig &= ~(uint)FilterAPI.BooleanConfig.REQUEST_ENCRYPT_KEY_IV_AND_TAGDATA_FROM_SERVICE; + } + } + } + + /// + /// Set the encryption key of the filter rule, + /// the encryption key length must be 16 bytes, 24 bytes or 32 bytes + /// + public byte[] EncryptionKey + { + get { return encryptionKey; } + set { encryptionKey = value; } + } + + /// + /// Use the pass phrase to generate the 32 bytes encryption key + /// + public string EncryptionPassPhrase + { + get { return encryptionPassPhrase; } + set + { + encryptionPassPhrase = value; + encryptionKey = Utils.GetKeyByPassPhrase(value, 32); + } + } + + /// + /// use the same encryption IV for all encryption when it was set. + /// + public byte[] EncryptionIV + { + get { return encryptionIV; } + set { encryptionIV = value; } + } + + public bool RequestEncryptionKey(FilterAPI.MessageSendData messageSend, ref FilterAPI.MessageReplyData messageReply) + { + bool retVal = true; + + //if the event was subscribed + if (null != OnFilterRequestEncryptKey) + { + EncryptEventArgs fileEncryptArgs = new EncryptEventArgs(messageSend); + fileEncryptArgs.EventName = "OnFilterRequestEncryptKey"; + + OnFilterRequestEncryptKey(this, fileEncryptArgs); + + messageReply.ReturnStatus = (uint)fileEncryptArgs.ReturnStatus; + + if (fileEncryptArgs.ReturnStatus == NtStatus.Status.Success) + { + MemoryStream ms = new MemoryStream(); + BinaryWriter bw = new BinaryWriter(ms); + byte[] iv = new byte[16]; + int ivLength = 0; + + if (null != fileEncryptArgs.IV) + { + ivLength = fileEncryptArgs.IV.Length; + Array.Copy(fileEncryptArgs.IV, iv, 16); + } + + bw.Write(fileEncryptArgs.AccessFlags); + bw.Write(ivLength); + bw.Write(iv); + bw.Write(fileEncryptArgs.EncryptionKey.Length); + bw.Write(fileEncryptArgs.EncryptionKey); + + int encryptionTagDataLength = fileEncryptArgs.EncryptionTag.Length; + bw.Write(encryptionTagDataLength); + if (encryptionTagDataLength > 0) + { + bw.Write(fileEncryptArgs.EncryptionTag); + } + + byte[] dataBuffer = ms.ToArray(); + messageReply.DataBufferLength = (uint)dataBuffer.Length; + Array.Copy(dataBuffer, messageReply.DataBuffer, dataBuffer.Length); + + } + else + { + + } + } + + return retVal; + } + } + + public class EncryptEventArgs : FileIOEventArgs + { + public EncryptEventArgs(FilterAPI.MessageSendData messageSend) + : base(messageSend) + { + if (messageSend.DataBufferLength > 0) + { + EncryptionTag = new byte[messageSend.DataBufferLength]; + Array.Copy(messageSend.DataBuffer, EncryptionTag, messageSend.DataBufferLength); + } + + if (messageSend.FilterCommand == (uint)FilterAPI.FilterCommand.FILTER_REQUEST_ENCRYPTION_IV_AND_KEY_AND_TAGDATA) + { + //when a new created file, it requests the encryption key, iv and tag data. + isNewCreatedFile = true; + } + + // this is encrypted file requests the encryption key, iv + //messageSend.FilterCommand == (uint)FilterAPI.FilterCommand.FILTER_REQUEST_ENCRYPTION_IV_AND_KEY + } + + /// + /// The maximum encryption tag data length. + /// + private int AES_MAX_TAG_DATA_SIZE = 914; + + /// + /// This is new created file when the filter command is FILTER_REQUEST_ENCRYPTION_IV_AND_KEY_AND_TAGDATA + /// + private bool isNewCreatedFile = false; + + /// + /// The access control flag of the encrypted file + /// + public uint AccessFlags { get; set; } + /// + /// The encryption iv of the encrypted file + /// + public byte[] IV { get; set; } + /// + /// The encryption key of the encrypted file + /// + public byte[] EncryptionKey { get; set; } + + private byte[] encryptionTagData = null; + /// + /// The tag data which was embedded to the header of the encrypted file. + /// + public byte[] EncryptionTag + { + get + { + if (null == encryptionTagData) + { + encryptionTagData = new byte[0]; + } + + return encryptionTagData; + } + set + { + if (value.Length > AES_MAX_TAG_DATA_SIZE) + { + throw new Exception("The encryption tag data length " + value.Length + " is over the maximum length " + AES_MAX_TAG_DATA_SIZE); + } + else + { + encryptionTagData = value; + } + + } + + } + + /// + /// it means it is new created file when it is true. + /// + public bool IsNewCreatedFile + { + get { return isNewCreatedFile; } + set { isNewCreatedFile = value; } + } + + + string description = string.Empty; + /// + /// The description of the event args + /// + public override string Description + { + get + { + if( description.Length > 0) + { + return description; + } + else + { + return "Request encryption key and iv for file:" + FileName; + } + } + + set { description = value; } + + } + } + + +} diff --git a/Demo_Source_Code/CSharpDemo/FilterControl/FileFilter.cs b/Demo_Source_Code/CSharpDemo/FilterControl/FileFilter.cs new file mode 100644 index 0000000..fd618a4 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FilterControl/FileFilter.cs @@ -0,0 +1,1395 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using System.IO; +using System.Text; + +namespace EaseFilter.FilterControl +{ + public class Filter + { + public FilterAPI.FilterType FilterType; + public uint FilterId; + + public virtual void SendNotification(FilterAPI.MessageSendData messageSend) + { + } + + public virtual bool ReplyMessage(FilterAPI.MessageSendData messageSend, IntPtr replyDataPtr) + { + return true; + } + } + + /// + /// A FileFilter is the file filter rule to monitor or control the file I/O by the filter driver. + /// The file filter rule includes monitor filter rule, control filter rule and encryption filter rule. + /// A monitor filter rule allows you to monitor the file change and file I/O activities. + /// A control filter rule allows you to control the file access or modify the file I/O data. + /// A encryption filter rule allows you to encrypt or decrypt the file automatically. + /// + public partial class FileFilter : Filter + { + /// + /// The file filter mask of this filter rule, the + /// + string fileFilterMask = string.Empty; + + /// + /// when it is true, the filter is passthrough filter + /// + bool isPassthroughFilter = false; + + /// + /// Skip all the file I/Os when the file open doesn't match with below options when they are not 0. + /// + uint filterDesiredAccess = 0; + uint filterDisposition = 0; + uint filterCreateOptions = 0; + + List hidenFileFilterMaskList = new List(); + string reparseFileFilterMask = string.Empty; + + /// + /// Filter the file I/Os based on the process name,Id, user name. + /// + List excludeFileFilterMaskList = new List(); + List includeProcessNameList = new List(); + List excludeProcessNameList = new List(); + List includeProcessIdList = new List(); + List excludeProcessIdList = new List(); + List includeUserNameList = new List(); + List excludeUserNameList = new List(); + + /// + /// Enable the control file filter rule in boot time. + /// + bool isResident = false; + + /// + /// the boolean config setting of the filter, reference FilterAPI.BooleanConfig + /// + uint booleanConfig = 0; + + public FileFilter(string fileFilterMask) + { + this.fileFilterMask = fileFilterMask; + } + + /// + /// The file filter mask of the file filter, the filter driver will manage the files based on this filter mask. + /// This is unique for the file filter, only the file matches the IncludeFileFilterMask, the IO will be managed by this filter. + /// i.e. c:\test\*, only the IO for files from folder c:\test will be intercepted by the filter driver. + /// + public string IncludeFileFilterMask + { + get { return fileFilterMask; } + } + + /// + /// The boolean config setting of the file filter. + /// + public uint BooleanConfig + { + get { return booleanConfig; } + set { booleanConfig = value; } + } + + /// + /// Get or set the exclude file filter mask list, + /// skip the file I/Os which the file name matches the exclude file filter mask. + /// i.e. c:\test\exclude\*, all the IO for files from folder c:\test\exclude will be excluded from this filter. + /// + public List ExcludeFileFilterMaskList + { + get { return excludeFileFilterMaskList; } + set { excludeFileFilterMaskList = value; } + } + + /// + /// Manage the IOs only from the include process name list when it is not empty. + /// i.e. explorer.exe, only the IO from process explorer will be intercepted by this filter. + /// + public List IncludeProcessNameList + { + get { return includeProcessNameList; } + set { includeProcessNameList = value; } + } + + /// + /// Skip all the IOs which are from the exclude process name list when it is not empty. + /// i.e. explorer.exe, all the IO from process explorer will be excluded by this filter. + /// + public List ExcludeProcessNameList + { + get { return excludeProcessNameList; } + set { excludeProcessNameList = value; } + } + + /// + /// Manage the IOs only from the include process id list when it is not empty. + /// Please note that the process Id might be changed when it was reopened. + /// i.e. 1234, only the IO from process Id 1234 will be intercepted by this filter. + /// + public List IncludeProcessIdList + { + get { return includeProcessIdList; } + set { includeProcessIdList = value; } + } + + /// + /// Skip all the IOs which are from the exclude process Id list when it is not empty. + /// i.e. 1234, all the IO from the process Id 1234 will be excluded by this filter. + /// + public List ExcludeProcessIdList + { + get { return excludeProcessIdList; } + set { excludeProcessIdList = value; } + } + + /// + /// Manage the IOs only from the include user name list when it is not empty. + /// i.e. myDomainName\myUserName, only the IO from this user myDomainName\myUserName will be intercepted by this filter. + /// + public List IncludeUserNameList + { + get { return includeUserNameList; } + set { includeUserNameList = value; } + } + + /// + /// Skip all the IOs which are from the exclude user name list when it is not empty. + /// i.e. myDomainName\myUserName, all the IO from this user myDomainName\myUserName will be excluded by this filter. + /// + public List ExcludeUserNameList + { + get { return excludeUserNameList; } + set { excludeUserNameList = value; } + } + + /// + /// Skip all the file I/Os when the file open doesn't match below option when it is not 0. + /// i.e. GENERIC_READ, only file opens with read access will be intercepted by this filter. + /// + public uint FilterDesiredAccess + { + get { return filterDesiredAccess; } + set { filterDesiredAccess = value; } + } + + /// + /// Skip all the file I/Os when the file open doesn't match below option when it is not 0. + /// i.e. OPEN_EXISTING, only file opens with existing file will be intercepted by this filter. + /// + public uint FilterDisposition + { + get { return filterDisposition; } + set { filterDisposition = value; } + } + + /// + /// Skip all the file I/Os when the file open doesn't match below option when it is not 0. + /// i.e. FILE_OPEN_REPARSE_POINT, only file opens with FILE_OPEN_REPARSE_POINT will be intercepted by this filter. + /// + public uint FilterCreateOptions + { + get { return filterCreateOptions; } + set { filterCreateOptions = value; } + } + + /// + /// Set the passthrough filter when it is true. + /// skip all the file I/Os of the files in this filter when it is true + /// + public bool IsPassthroughFilter + { + get { return isPassthroughFilter; } + set { isPassthroughFilter = value; } + } + + /// + /// if it is true it will send the read or write data to callback deletegate or it won't send the data. + /// + public bool EnableSendReadOrWriteBuffer + { + get + { + return (booleanConfig & (uint)FilterAPI.BooleanConfig.ENABLE_SEND_DATA_BUFFER) > 0; + } + + set + { + if (value) + { + booleanConfig |= (uint)FilterAPI.BooleanConfig.ENABLE_SEND_DATA_BUFFER; + } + else + { + booleanConfig &= ~(uint)FilterAPI.BooleanConfig.ENABLE_SEND_DATA_BUFFER; + } + } + } + + /// + ///enable this feature when accessFlag "ALLOW_SAVE_AS" or "ALLOW_COPY_PROTECTED_FILES_OUT" was disabled. + ///by default we don't enable this feature, because of the drawback of these two flags were disabled + ///which will block all new file creation of the process which was read the protected files. + /// + public bool EnableBlockSaveAs + { + get + { + return (booleanConfig & (uint)FilterAPI.BooleanConfig.ENABLE_BLOCK_SAVE_AS_FLAG) > 0; + } + + set + { + if (value) + { + booleanConfig |= (uint)FilterAPI.BooleanConfig.ENABLE_BLOCK_SAVE_AS_FLAG; + } + else + { + booleanConfig &= ~(uint)FilterAPI.BooleanConfig.ENABLE_BLOCK_SAVE_AS_FLAG; + } + } + } + + + + public override bool ReplyMessage(FilterAPI.MessageSendData messageSend, IntPtr replyDataPtr) + { + bool retVal = true; + + try + { + FilterAPI.MessageReplyData messageReply = (FilterAPI.MessageReplyData)Marshal.PtrToStructure(replyDataPtr, typeof(FilterAPI.MessageReplyData)); + if (messageSend.FilterCommand == (uint)FilterAPI.FilterCommand.FILTER_REQUEST_ENCRYPTION_IV_AND_KEY + || messageSend.FilterCommand == (uint)FilterAPI.FilterCommand.FILTER_REQUEST_ENCRYPTION_IV_AND_KEY_AND_TAGDATA) + { + RequestEncryptionKey(messageSend, ref messageReply); + } + else + { + FireControlEvents(messageSend, ref messageReply); + } + + Marshal.StructureToPtr(messageReply, replyDataPtr, true); + } + catch + { + } + + return retVal; + } + + + + } + + #region event args definition + /// + /// This is the create options when the process opens the file, normally every file IO needs to open/create a file first, + /// the process will get a file handle which associated to the FileObject in filter driver till the process closes the handle. + /// + public class CreateFileOptions + { + public uint DesiredAccess { get; set; } + public uint Disposition { get; set; } + public uint CreateOptions { get; set; } + public uint SharedAccess { get; set; } + public override string ToString() + { + string description = string.Empty; + + description += "DesiredAccess:" + WinData.DesiredAccessToString(DesiredAccess); + description += " Disposition:" + ((WinData.Disposition)Disposition).ToString(); + description += " ShareAccess:" + ((WinData.ShareAccess)SharedAccess).ToString(); + description += " CreateOptions:" + WinData.CreateOptionsToString(CreateOptions); + + return description; + } + } + + + /// + /// This is the general information for every file IO which was sent by filter driver if you register the callback IO. + /// + public class FileIOEventArgs : EventArgs + { + public FileIOEventArgs(FilterAPI.MessageSendData messageSend) + { + string userName = string.Empty; + string processName = string.Empty; + + Utils.DecodeUserName(messageSend.Sid, out userName); + Utils.DecodeProcessName(messageSend.ProcessId, out processName); + + UserName = userName; + ProcessName = processName; + FileObject = messageSend.FileObject; + FsContext = messageSend.FsContext; + MessageId = messageSend.MessageId; + FilterRuleId = messageSend.FilterRuleId; + TransactionTime = messageSend.TransactionTime; + CreationTime = messageSend.CreationTime; + LastWriteTime = messageSend.LastWriteTime; + ProcessId = messageSend.ProcessId; + ThreadId = messageSend.ThreadId; + FileName = messageSend.FileName; + FileSize = messageSend.FileSize; + FileAttributes = messageSend.FileAttributes; + IoStatus = (NtStatus.Status)messageSend.Status; + + SharedAccess = messageSend.SharedAccess; + CreateFileOptions createOptions = new CreateFileOptions(); + createOptions.CreateOptions = messageSend.CreateOptions; + createOptions.DesiredAccess = messageSend.DesiredAccess; + createOptions.Disposition = messageSend.Disposition; + createOptions.SharedAccess = messageSend.SharedAccess; + CreateOptions = createOptions; + + IsRemoteAccess = false; + RemoteIp = "LocalHost"; + if ((messageSend.CreateOptions & (uint)WinData.CreateOptions.FO_REMOTE_ORIGIN) > 0) + { + //this is the request comes from remote server + IsRemoteAccess = true; + RemoteIp = Encoding.Unicode.GetString(messageSend.RemoteIP); + } + } + + public string IOStatusToString() + { + string ret = string.Empty; + uint status = (uint)IoStatus; + + foreach (NtStatus.Status ntStatus in Enum.GetValues(typeof(NtStatus.Status))) + { + if (status == (uint)ntStatus) + { + ret = ntStatus.ToString() + "(0x" + status.ToString("X") + ")"; + } + } + + if (string.IsNullOrEmpty(ret)) + { + ret = "(0x" + status.ToString("X") + ")"; + } + + return ret; + } + + /// + /// The Message Id. + /// + public uint MessageId { get; set; } + /// + /// The filter rule Id. + /// + public uint FilterRuleId { get; set; } + /// + ///This is the IO completion status, either STATUS_SUCCESS if the requested operation was completed successfully + ///or an informational, warning, or error STATUS_XXX value, only effect on post IO. + /// + public NtStatus.Status IoStatus { get; set; } + /// + /// the transaction time in UTC of this IO request + /// + public long TransactionTime { get; set; } + /// + /// The fileObject is an unique Id for the file I/O from open till the close. + /// + public IntPtr FileObject { get; set; } + /// + /// A pointer to the FSRTL_ADVANCED_FCB_HEADER header structure that is contained + /// within a file-system-specific structure,it is unique per file. + /// + public IntPtr FsContext { get; set; } + /// + /// The process Id who initiates the IO. + /// + public uint ProcessId { get; set; } + /// + /// The process name who initiates the IO. + /// + public string ProcessName { get; set; } + /// + /// The thread Id who initiates the IO. + /// + public uint ThreadId { get; set; } + /// + /// The user name who initiates the IO. + /// + public string UserName { get; set; } + /// + /// The file name of the file IO. + /// + public string FileName { get; set; } + /// + /// The file size of the file IO. + /// + public long FileSize { get; set; } + /// + /// The creation time in UTC of the file. + /// + public long CreationTime { get; set; } + /// + /// The last write time in UTC of the file. + /// + public long LastWriteTime { get; set; } + /// + /// The file attributes of the file IO. + /// + public uint FileAttributes { get; set; } + /// + /// The file create options of the file IO. + /// + public CreateFileOptions CreateOptions { get; set; } + /// + /// The SharedAccess for file open, please reference CreateFile windows API. + /// + public uint SharedAccess { get; set; } + /// + /// The name of the event which uses this eventargs + /// + public string EventName { get; set; } + /// + /// The file open was from the network + /// + public bool IsRemoteAccess { get; set; } + /// + /// The IP address of the remote computer who is opening the file. + /// This feature is enabled only for Win7 or later OS. + /// + public string RemoteIp { get; set; } + + string description = string.Empty; + /// + /// The description of the IO. + /// + public virtual string Description + { + get { return description; } + set { description = value; } + } + /// + /// Change the return status of the IO, it is only for control filter or encryption filter + /// set the status to AccessDenied if you want to block this IO. + /// + public NtStatus.Status ReturnStatus { get; set; } + /// + /// Set it to true, if the return data was modified. + /// + public bool IsDataModified { get; set; } + } + + /// + /// The callback information of the file change event. + /// + public class FileChangedEventArgs : FileIOEventArgs + { + public FileChangedEventArgs(FilterAPI.MessageSendData messageSend) + : base(messageSend) + { + + if ((messageSend.InfoClass & (uint)FilterAPI.FileChangedEvents.NotifyFileWasCreated) > 0) + { + eventType = FilterAPI.FileChangedEvents.NotifyFileWasCreated; + EventName = "NotifyFileWasCreated;"; + Description = "The new file " + FileName + " was created."; + } + + if ((messageSend.InfoClass & (uint)FilterAPI.FileChangedEvents.NotifyFileWasWritten) > 0) + { + eventType |= FilterAPI.FileChangedEvents.NotifyFileWasWritten; + EventName += "NotifyFileWasWritten;"; + Description += "The file " + FileName + " was written."; + } + + if ((messageSend.InfoClass & (uint)FilterAPI.FileChangedEvents.NotifyFileWasDeleted) > 0) + { + eventType |= FilterAPI.FileChangedEvents.NotifyFileWasDeleted; + EventName += "NotifyFileWasDeleted;"; + Description += "The file " + FileName + " was deleted."; + } + + if ((messageSend.InfoClass & (uint)FilterAPI.FileChangedEvents.NotifyFileInfoWasChanged) > 0) + { + eventType |= FilterAPI.FileChangedEvents.NotifyFileInfoWasChanged; + EventName += "NotifyFileInfoWasChanged;"; + Description += "The file " + FileName + " information was changed."; + } + + if ((messageSend.InfoClass & (uint)FilterAPI.FileChangedEvents.NotifyFileWasCopied) > 0) + { + if (messageSend.DataBufferLength > 0) + { + newFileName = Encoding.Unicode.GetString(messageSend.DataBuffer); + if (newFileName.IndexOf((char)0) > 0) + { + newFileName = newFileName.Remove(newFileName.IndexOf((char)0)); + } + } + + eventType |= FilterAPI.FileChangedEvents.NotifyFileWasRenamed; + EventName += "NotifyFileWasCopied;"; + Description += "The file " + FileName + " was copied from " + newFileName + "."; + } + + if ((messageSend.InfoClass & (uint)FilterAPI.FileChangedEvents.NotifyFileWasRenamed) > 0) + { + if (messageSend.DataBufferLength > 0) + { + newFileName = Encoding.Unicode.GetString(messageSend.DataBuffer); + if (newFileName.IndexOf((char)0) > 0) + { + newFileName = newFileName.Remove(newFileName.IndexOf((char)0)); + } + } + + eventType |= FilterAPI.FileChangedEvents.NotifyFileWasRenamed; + EventName += "NotifyFileWasRenamed;"; + Description += "The file " + FileName + " was renamed to " + newFileName + "."; + } + + if ((messageSend.InfoClass & (uint)FilterAPI.FileChangedEvents.NotifyFileSecurityWasChanged) > 0) + { + eventType |= FilterAPI.FileChangedEvents.NotifyFileSecurityWasChanged; + EventName += "NotifyFileSecurityWasChanged;"; + Description += "The file " + FileName + " security was changed."; + } + + if ((messageSend.InfoClass & (uint)FilterAPI.FileChangedEvents.NotifyFileWasRead) > 0) + { + eventType |= FilterAPI.FileChangedEvents.NotifyFileWasRead; + EventName += "NotifyFileWasRead;"; + Description += "The file " + FileName + " was read."; + } + + } + + /// + /// The new file name of the rename IO + /// + public string newFileName { get; set; } + /// + /// The event type of the file change event. + /// + public FilterAPI.FileChangedEvents eventType { get; set; } + + } + + public class FileCreateEventArgs : FileIOEventArgs + { + public FileCreateEventArgs(FilterAPI.MessageSendData messageSend) + : base(messageSend) + { + if ((messageSend.CreateOptions & (uint)WinData.CreateOptions.FILE_DELETE_ON_CLOSE) > 0) + { + isDeleteOnClose = true; + } + else + { + isDeleteOnClose = false; + } + + if ( messageSend.Status == 0 + && ((uint)FilterAPI.MessageType.POST_CREATE == messageSend.MessageType)) + { + if ((WinData.CreateStatus)messageSend.CreateStatus == WinData.CreateStatus.FILE_CREATED + || messageSend.CreateStatus == (uint)WinData.CreateStatus.FILE_SUPERSEDED ) + { + isNewFileCreated = true; + } + else + { + isNewFileCreated = false; + } + } + + if ((messageSend.InfoClass & (uint)FilterAPI.FILE_COPY_FLAG.CREATE_FLAG_FILE_SOURCE_OPEN_FOR_COPY) > 0) + { + isFileCopySource = true; + } + + if ((messageSend.InfoClass & (uint)FilterAPI.FILE_COPY_FLAG.CREATE_FLAG_FILE_DEST_OPEN_FOR_COPY) > 0) + { + isFileCopyDest = true; + } + } + + /// + /// The file will be deleted on close when it was true. + /// + public bool isDeleteOnClose{ get; set; } + /// + /// Reparse the file open to this new file name for control filter. + /// the file name format should like this "\\??\\c:\\mynewfolder\\myNewFile.txt"; + /// + public string reparseFileName { get; set; } + /// + /// It indicates that the new file was created if it is true. + /// + public bool isNewFileCreated { get; set; } + /// + /// It indicates that this is file copy source file open. + /// + public bool isFileCopySource { get; set; } + /// + /// It indicates that this is file copy dest file open. + /// + public bool isFileCopyDest { get; set; } + + /// + /// The description of the IO args + /// + public override string Description + { + get + { + string message = CreateOptions.ToString(); + + if (isNewFileCreated) + { + message = "The new file was created." + message; + } + + if (isDeleteOnClose) + { + message = "The file will be deleted on close." + message; + } + + if (isFileCopySource) + { + message = "FileCopy source file open." + message; + } + + if (isFileCopyDest) + { + message = "FileCopy dest file open." + message; + } + + return message; + } + } + } + + public class FileReadEventArgs : FileIOEventArgs + { + public FileReadEventArgs(FilterAPI.MessageSendData messageSend) + : base(messageSend) + { + offset = messageSend.Offset; + readLength = messageSend.Length; + returnReadLength = messageSend.ReturnLength; + + if (messageSend.DataBufferLength > 0 && messageSend.DataBufferLength <= messageSend.DataBuffer.Length) + { + buffer = new byte[messageSend.DataBufferLength]; + Array.Copy(messageSend.DataBuffer, buffer, buffer.Length); + } + + if (messageSend.MessageType == (uint)FilterAPI.MessageType.POST_NOCACHE_READ + || messageSend.MessageType == (uint)FilterAPI.MessageType.PRE_NOCACHE_READ) + { + readType = "NonCacheRead"; + } + else if ( messageSend.MessageType == (uint)FilterAPI.MessageType.PRE_PAGING_IO_READ + || messageSend.MessageType == (uint)FilterAPI.MessageType.POST_PAGING_IO_READ) + { + readType = "PagingIORead"; + } + else if ( messageSend.MessageType == (uint)FilterAPI.MessageType.PRE_FASTIO_READ + || messageSend.MessageType == (uint)FilterAPI.MessageType.POST_FASTIO_READ) + { + readType = "FastIOCacheRead"; + } + else + { + readType = "CacheRead"; + } + + if (messageSend.MessageType == (uint)FilterAPI.MessageType.POST_NOCACHE_READ + || messageSend.MessageType == (uint)FilterAPI.MessageType.POST_PAGING_IO_READ + || messageSend.MessageType == (uint)FilterAPI.MessageType.POST_FASTIO_READ + || messageSend.MessageType == (uint)FilterAPI.MessageType.POST_CACHE_READ) + { + isPostRead = true; + } + else + { + isPostRead = false; + } + + if ((messageSend.InfoClass & (uint)FilterAPI.FILE_COPY_FLAG.READ_FLAG_FILE_SOURCE_FOR_COPY) > 0) + { + isFileCopySource = true; + } + + } + + /// + /// The read offset + /// + public long offset { get; set; } + /// + /// The length of the read + /// + public uint readLength { get; set; } + /// + /// The return length of the read + /// + public uint returnReadLength { get; set; } + /// + /// The read data buffer + /// + public byte[] buffer { get; set; } + /// + /// The read type + /// + public string readType { get; set; } + /// + /// The data was read and return from file system if it is true. + /// + public bool isPostRead { get; set; } + /// + /// It indicates that this is file copy source file open. + /// + public bool isFileCopySource { get; set; } + + /// + /// The description of the IO args + /// + public override string Description + { + get + { + string message = "ReadOffset:" + offset + ";ReadLength:" + readLength; + + if (isPostRead) + { + message = "Post-" + message; + message += ";returnReadLength:" + returnReadLength; + } + else + { + message = "Pre-" + message; + } + + if (isFileCopySource) + { + message = "FileCopy source file read." + message; + } + + return message; + } + + } + } + + public class FileWriteEventArgs : FileIOEventArgs + { + public FileWriteEventArgs(FilterAPI.MessageSendData messageSend) + : base(messageSend) + { + offset = messageSend.Offset; + writeLength = messageSend.Length; + writtenLength = messageSend.ReturnLength; + bufferLength = messageSend.DataBufferLength; + + if (messageSend.DataBufferLength > 0 && messageSend.DataBufferLength <= messageSend.DataBuffer.Length ) + { + buffer = new byte[messageSend.DataBufferLength]; + Array.Copy(messageSend.DataBuffer, buffer, buffer.Length); + } + + if ( messageSend.MessageType == (uint)FilterAPI.MessageType.POST_NOCACHE_WRITE + || messageSend.MessageType == (uint)FilterAPI.MessageType.PRE_NOCACHE_WRITE) + { + writeType= "NonCacheWrite"; + } + else if (messageSend.MessageType == (uint)FilterAPI.MessageType.PRE_PAGING_IO_WRITE + ||messageSend.MessageType == (uint)FilterAPI.MessageType.POST_PAGING_IO_WRITE) + { + writeType = "PagingIOWrite"; + } + else if ( messageSend.MessageType == (uint)FilterAPI.MessageType.PRE_FASTIO_WRITE + || messageSend.MessageType == (uint)FilterAPI.MessageType.POST_FASTIO_WRITE) + { + writeType = "FastIOCacheWrite"; + } + else + { + writeType = "CacheWrite"; + } + + if (messageSend.MessageType == (uint)FilterAPI.MessageType.POST_NOCACHE_WRITE + || messageSend.MessageType == (uint)FilterAPI.MessageType.POST_PAGING_IO_WRITE + || messageSend.MessageType == (uint)FilterAPI.MessageType.POST_FASTIO_WRITE + || messageSend.MessageType == (uint)FilterAPI.MessageType.POST_CACHE_WRITE) + { + isPostWrite = true; + } + else + { + isPostWrite = false; + } + + if ((messageSend.InfoClass & (uint)FilterAPI.FILE_COPY_FLAG.WRITE_FLAG_FILE_DEST_FOR_COPY) > 0) + { + isFileCopyDest = true; + } + } + + /// + /// The write offset + /// + public long offset { get; set; } + /// + /// The length of the write + /// + public uint writeLength { get; set; } + /// + /// The length of the written + /// + public uint writtenLength { get; set; } + /// + /// The data buffer length + /// + public uint bufferLength { get; set; } + /// + /// The write data buffer + /// + public byte[] buffer { get; set; } + /// + /// The write type + /// + public string writeType { get; set; } + /// + /// The data was written and return from file system if it is true. + /// + public bool isPostWrite { get; set; } + /// + /// It indicates that this is file copy dest file write. + /// + public bool isFileCopyDest { get; set; } + + /// + /// The description of the IO args + /// + public override string Description + { + get + { + string message = "WriteOffset:" + offset + ",writeLength:" + writeLength ; + + if (isPostWrite) + { + message = "Post-" + message; + message += ",WrittenLength:" + writtenLength; + } + else + { + message = "Pre-" + message; + } + + if(isFileCopyDest) + { + message = "FileCopy dest file write." + message; + } + + return message; + } + + } + } + + public class FileSizeEventArgs : FileIOEventArgs + { + public FileSizeEventArgs(FilterAPI.MessageSendData messageSend) + : base(messageSend) + { + if (messageSend.DataBufferLength > 0) + { + fileSizeToQueryOrSet = BitConverter.ToInt64(messageSend.DataBuffer, 0); + } + } + + /// + /// The size of the file used by FileEndOfFileInformation class + /// + public long fileSizeToQueryOrSet { get; set; } + + /// + /// The description of the IO args + /// + public override string Description + { + get + { + return "FileSize:" + fileSizeToQueryOrSet; + } + + } + } + + public class FileIdEventArgs : FileIOEventArgs + { + public FileIdEventArgs(FilterAPI.MessageSendData messageSend) + : base(messageSend) + { + if (messageSend.DataBufferLength > 0) + { + fileId = BitConverter.ToInt64(messageSend.DataBuffer, 0); + } + } + /// + /// The file Id used by FileInternalInformation class + /// + public long fileId { get; set; } + /// + /// The description of the IO args + /// + public override string Description + { + get + { + if (fileId > 0) + { + return "FileId:0x" + fileId.ToString("X"); + } + else + { + return ""; + } + } + + } + } + + public class FileBasicInfoEventArgs : FileIOEventArgs + { + public FileBasicInfoEventArgs(FilterAPI.MessageSendData messageSend) + : base(messageSend) + { + if (messageSend.DataBufferLength > 0) + { + GCHandle pinnedPacket = GCHandle.Alloc(messageSend.DataBuffer, GCHandleType.Pinned); + basicInfo = (WinData.FileBasicInformation)Marshal.PtrToStructure( + pinnedPacket.AddrOfPinnedObject(), typeof(WinData.FileBasicInformation)); + pinnedPacket.Free(); + } + + } + /// + /// The file basic information + /// + public WinData.FileBasicInformation basicInfo { get; set; } + + public override string Description + { + get + { + if (basicInfo.CreationTime > 0) + { + string desc = "FileBasicInformation,creation time:" + DateTime.FromFileTime(basicInfo.CreationTime).ToString("yyyy-MM-ddTHH:mm") + " "; + desc += "last access time:" + DateTime.FromFileTime(basicInfo.LastAccessTime).ToString("yyyy-MM-ddTHH:mm") + " "; + desc += "last write time:" + DateTime.FromFileTime(basicInfo.LastWriteTime).ToString("yyyy-MM-ddTHH:mm") + " "; + desc += "file attributes:" + ((FileAttributes)basicInfo.FileAttributes).ToString(); + + return desc; + } + else return ""; + } + + } + } + + public class FileStandardInfoEventArgs : FileIOEventArgs + { + public FileStandardInfoEventArgs(FilterAPI.MessageSendData messageSend) + : base(messageSend) + { + if (messageSend.DataBufferLength > 0) + { + GCHandle pinnedPacket = GCHandle.Alloc(messageSend.DataBuffer, GCHandleType.Pinned); + standardInfo = (WinData.FileStandardInformation)Marshal.PtrToStructure( + pinnedPacket.AddrOfPinnedObject(), typeof(WinData.FileStandardInformation)); + pinnedPacket.Free(); + } + + } + /// + /// The file standard information + /// + public WinData.FileStandardInformation standardInfo { get; set; } + + public override string Description + { + get + { + if (standardInfo.EndOfFile > 0) + { + string desc = "FileStandardInformation, file size:" + standardInfo.EndOfFile.ToString() + " "; + desc += "allocation size:" + standardInfo.AllocationSize.ToString() + " "; + desc += "isDirectory:" + standardInfo.Directory.ToString(); + + return desc; + } + else return ""; + } + + } + } + + public class FileNetworkInfoEventArgs : FileIOEventArgs + { + public FileNetworkInfoEventArgs(FilterAPI.MessageSendData messageSend) + : base(messageSend) + { + if (messageSend.DataBufferLength > 0) + { + GCHandle pinnedPacket = GCHandle.Alloc(messageSend.DataBuffer, GCHandleType.Pinned); + networkInfo = (WinData.FileNetworkInformation)Marshal.PtrToStructure( + pinnedPacket.AddrOfPinnedObject(), typeof(WinData.FileNetworkInformation)); + pinnedPacket.Free(); + } + + } + /// + /// The file network information + /// + public WinData.FileNetworkInformation networkInfo { get; set; } + + public override string Description + { + get + { + if (networkInfo.CreationTime > 0) + { + string desc = "FileNetworkOpenInformation, creation time:" + DateTime.FromFileTime(networkInfo.CreationTime).ToString("yyyy-MM-ddTHH:mm") + " "; + desc += "last access time:" + DateTime.FromFileTime(networkInfo.LastAccessTime) + " "; + desc += "last write time:" + DateTime.FromFileTime(networkInfo.LastWriteTime) + " "; + desc += "file size:" + networkInfo.FileSize.ToString() + " "; + desc += "file attributes:" + ((FileAttributes)networkInfo.FileAttributes).ToString(); + + return desc; + } + else return ""; + } + + } + + } + + public class FileMoveOrRenameEventArgs : FileIOEventArgs + { + public FileMoveOrRenameEventArgs(FilterAPI.MessageSendData messageSend) + : base(messageSend) + { + if (messageSend.DataBufferLength > 0) + { + newFileName = Encoding.Unicode.GetString(messageSend.DataBuffer); + if (newFileName.IndexOf((char)0) > 0) + { + newFileName = newFileName.Remove(newFileName.IndexOf((char)0)); + } + } + } + /// + /// The new file name of the move or rename IO + /// + public string newFileName { get; set; } + + /// + /// The description of the event args + /// + public override string Description + { + get + { + if (null != newFileName && newFileName.Length > 0) + { + string desc = "The file " + FileName + " was renamed to " + newFileName; + return desc; + } + else return ""; + } + + } + + } + + public class FileInfoArgs : FileIOEventArgs + { + public FileInfoArgs(FilterAPI.MessageSendData messageSend) + : base(messageSend) + { + FileInfoClass = (WinData.FileInfomationClass)messageSend.InfoClass; + + if (messageSend.DataBufferLength > 0) + { + DataBuffer = new byte[messageSend.DataBufferLength]; + Array.Copy(messageSend.DataBuffer, DataBuffer, messageSend.DataBufferLength); + } + } + /// + /// The information class of the IO + /// + public WinData.FileInfomationClass FileInfoClass { get; set; } + /// + /// The information data of the file associated to the info class. + /// + public byte[] DataBuffer { get; set; } + + /// + /// The description of the event args + /// + public override string Description + { + get + { + return "FileInformationClass:" + FileInfoClass.ToString(); + } + + } + + } + + public class FileSecurityEventArgs : FileIOEventArgs + { + public FileSecurityEventArgs(FilterAPI.MessageSendData messageSend) + : base(messageSend) + { + securityInformation = (WinData.SecurityInformation)messageSend.InfoClass; + if (messageSend.DataBufferLength > 0) + { + securityBuffer = new byte[messageSend.DataBufferLength]; + Array.Copy(messageSend.DataBuffer, securityBuffer, messageSend.DataBufferLength); + } + + } + + /// + /// The security information to be queried/set + /// + public WinData.SecurityInformation securityInformation { get; set; } + public byte[] securityBuffer { get; set; } + + /// + /// The description of the event args + /// + public override string Description + { + get + { + string securityInfo = string.Empty; + foreach (WinData.SecurityInformation security in Enum.GetValues(typeof(WinData.SecurityInformation))) + { + if (((uint)securityInformation & (uint)security) > 0) + { + if (securityInfo.Length > 0) + { + securityInfo += ";"; + } + + securityInfo += security.ToString(); + } + } + + return securityInfo; + } + + } + } + + public class FileQueryDirectoryEventArgs : FileIOEventArgs + { + public FileQueryDirectoryEventArgs(FilterAPI.MessageSendData messageSend) + : base(messageSend) + { + fileInfomationClass = (WinData.FileInfomationClass)messageSend.InfoClass; + if (messageSend.DataBufferLength > 0) + { + directoryBuffer = new byte[messageSend.DataBufferLength]; + Array.Copy(messageSend.DataBuffer, directoryBuffer, messageSend.DataBufferLength); + } + } + + /// + /// The type of information to be returned about files in the directory. + /// + public WinData.FileInfomationClass fileInfomationClass { get; set; } + /// + /// The buffer that receives the desired information about the file. + /// The structure of the information returned in the buffer is defined by the FileInformationClass. + /// + public byte[] directoryBuffer { get; set; } + + /// + /// The description of the event args + /// + public override string Description + { + get + { + return "Query directory with information class:" + fileInfomationClass.ToString(); + } + + } + } + + public class DeniedFileIOEventArgs : FileIOEventArgs + { + public DeniedFileIOEventArgs(FilterAPI.MessageSendData messageSend) + : base(messageSend) + { + EventName = ((FilterAPI.MessageType)messageSend.MessageType).ToString() + " was blocked."; + + if (messageSend.DataBufferLength > 0 && (FilterAPI.AccessFlag)messageSend.InfoClass == FilterAPI.AccessFlag.ALLOW_FILE_RENAME) + { + string newFileName = Encoding.Unicode.GetString(messageSend.DataBuffer); + if (newFileName.IndexOf((char)0) > 0) + { + newFileName = newFileName.Remove(newFileName.IndexOf((char)0)); + } + + Description = "Rename file " + messageSend.FileName + " to " + newFileName + " was blocked by the setting."; + } + else + { + Description = "File access control flag " + ((FilterAPI.AccessFlag)messageSend.InfoClass).ToString() + " was disabled by the setting."; + } + } + + } + + public class DeniedUSBReadEventArgs : FileIOEventArgs + { + public DeniedUSBReadEventArgs(FilterAPI.MessageSendData messageSend) + : base(messageSend) + { + EventName = "BlockUSBRead"; + Description = "Reading file from USB was blocked by the setting."; + } + } + + public class DeniedUSBWriteEventArgs : FileIOEventArgs + { + public DeniedUSBWriteEventArgs(FilterAPI.MessageSendData messageSend) + : base(messageSend) + { + EventName = "BlockUSBWrite"; + + if (messageSend.InfoClass == (uint)FilterAPI.AccessFlag.ALLOW_COPY_PROTECTED_FILES_TO_USB) + { + Description = "Copy the protected file to USB was blocked by the setting."; + } + else + { + Description = "Writting the file to USB was blocked by the setting."; + } + } + } + + + public class DeniedProcessTerminatedEventArgs : FileIOEventArgs + { + public DeniedProcessTerminatedEventArgs(FilterAPI.MessageSendData messageSend) + : base(messageSend) + { + EventName = "DeniedProcessTerminated"; + Description = "Block killing process " + ProcessName + " ungratefully."; + } + + } + + public class VolumeInfoEventArgs : FileIOEventArgs + { + public VolumeInfoEventArgs(FilterAPI.MessageSendData messageSend) + : base(messageSend) + { + if (messageSend.DataBufferLength > 0) + { + GCHandle pinnedPacket = GCHandle.Alloc(messageSend.DataBuffer, GCHandleType.Pinned); + FilterAPI.VOLUME_INFO volumeInfo = (FilterAPI.VOLUME_INFO)Marshal.PtrToStructure( + pinnedPacket.AddrOfPinnedObject(), typeof(FilterAPI.VOLUME_INFO)); + pinnedPacket.Free(); + + VolumeName = volumeInfo.VolumeName; + VolumeDosName = volumeInfo.VolumeDosName; + VolumeFilesystemType = (WinData.FLT_FILESYSTEM_TYPE)volumeInfo.VolumeFilesystemType; + DeviceCharacteristics = (WinData.DeviceObject_Characteristics)volumeInfo.DeviceCharacteristics; + + FileName = Description; + } + + + } + + /// + /// the volume name + /// + public string VolumeName{ get; set;} + /// + /// the volume dos name + /// + public string VolumeDosName {get; set;} + /// + /// the volume file system type. + /// + public WinData.FLT_FILESYSTEM_TYPE VolumeFilesystemType {get;set;} + /// + /// the Characteristics of the attached device object if existed. + /// + public WinData.DeviceObject_Characteristics DeviceCharacteristics{get;set;} + + public override string Description + { + get + { + string desc = "VolumeName[" + VolumeName + "] "; + desc += "VolumeDosName[" + VolumeDosName + "] "; + desc += "VolumeFilesystemType[" + VolumeFilesystemType.ToString() + "] "; + + string charaterMessage = string.Empty; + foreach (WinData.DeviceObject_Characteristics character in Enum.GetValues(typeof(WinData.DeviceObject_Characteristics))) + { + if (((uint)DeviceCharacteristics & (uint)character) > 0) + { + charaterMessage += character.ToString() + ";"; + } + } + + desc += "DeviceCharacteristics[" + charaterMessage + "]"; + + return desc; + } + set{ Description = value;} + + } + } + + #endregion event args definition + + + +} diff --git a/Demo_Source_Code/CSharpDemo/FilterControl/FilterAPI.cs b/Demo_Source_Code/CSharpDemo/FilterControl/FilterAPI.cs new file mode 100644 index 0000000..5589e25 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FilterControl/FilterAPI.cs @@ -0,0 +1,2234 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.Text; +using System.IO; +using System.Collections; +using System.Collections.Generic; +using Microsoft.Win32.SafeHandles; +using System.Runtime.InteropServices; +using System.Security.Principal; +using System.Security.Cryptography; + + +namespace EaseFilter.FilterControl +{ + + static public class FilterAPI + { + public const int MAX_FILE_NAME_LENGTH = 1024; + public const int MAX_SID_LENGTH = 256; + public const int INET_ADDR_STR_LEN = 22; + public const int MAX_MESSAGE_LENGTH = 65536; + public const int MAX_PATH = 260; + public const int MAX_ERROR_MESSAGE_SIZE = 1024; + public const uint MESSAGE_SEND_VERIFICATION_NUMBER = 0xFF000001; + public const uint GENERIC_WRITE = 0x40000000; + public const uint AES_TAG_KEY = 0xccb76e80; + + //default AES encrypted file header size + public const uint MAX_AES_HEADER_SIZE = 1024; + public const uint MAX_AES_TAG_SIZE = 910; + + public const uint FILE_FLAG_OPEN_REPARSE_POINT = 0x00200000; + public const uint FILE_FLAG_OPEN_NO_RECALL = 0x00100000; + public const uint FILE_FLAG_NO_BUFFERING = 0x20000000; + public const uint FILE_ATTRIBUTE_REPARSE_POINT = (uint)FileAttributes.ReparsePoint; + + //for encryption default IV key + public static byte[] DEFAULT_IV_TAG = { 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff }; + + public enum FilterType : byte + { + /// + /// File system control filter driver + /// + CONTROL_FILTER = 0x01, + /// + /// File system encryption filter driver + /// + ENCRYPTION_FILTER = 0x02, + /// + /// File system monitor filter driver + /// + MONITOR_FILTER = 0x04, + /// + /// File system registry filter driver + /// + REGISTRY_FILTER = 0x08, + /// + /// File system process filter driver + /// + PROCESS_FILTER = 0x10, + /// + /// File system hierarchical storage management filter driver + /// + HSM_FILTER = 0x40, + /// + /// File system cloud storage filter driver + /// + CLOUD_FILTER = 0x80, + } + + public enum EncryptionMethod : uint + { + /// + /// Use the same encryption key and iv from the filter rule for all files, there are no reparse point tag data added to encrypted file, + /// it supports all file systems. You can't identify if the file is encrypted or not by API. + /// + ENCRYPT_FILE_WITH_SAME_KEY_AND_IV = 0, + /// + /// Use the same encryption key from the filter rule for all files, use unique iv key per file, a meta data header will be appended to the + /// end of the encyrpted file. You can identify if the file is encrypted by checking the header. + /// + ENCRYPT_FILE_WITH_SAME_KEY_AND_UNIQUE_IV, + /// + ///Use the encryption key and iv from the user mode service,you can use the custom encryption key,iv and taga data per file. + /// + ENCRYPT_FILE_WITH_KEY_IV_AND_TAGDATA_FROM_SERVICE, + } + + //This is the enumeration of the file copy flags. + public enum FILE_COPY_FLAG:uint + { + //this is the source file for copy in the open. + CREATE_FLAG_FILE_SOURCE_OPEN_FOR_COPY = 0x00000001, + //this is the dest file for copy in the open. + CREATE_FLAG_FILE_DEST_OPEN_FOR_COPY = 0x00000002, + //this is the source file read for file copy. + READ_FLAG_FILE_SOURCE_FOR_COPY = 0x00000004, + //this is the destination file write for file copy. + WRITE_FLAG_FILE_DEST_FOR_COPY = 0x00000008, + + } + + public enum BooleanConfig : uint + { + /// + ///for easetag, if it was true, after the reparsepoint file was opened, it won't restore data back for read and write. + /// + ENABLE_NO_RECALL_FLAG = 0x00000001, + /// + /// if it is true, the filter driver can't be unloaded. + /// + DISABLE_FILTER_UNLOAD_FLAG = 0x00000002, + /// + /// for virtual file, it will set offline attribute if it is true. + /// + ENABLE_SET_OFFLINE_FLAG = 0x00000004, + /// + /// for encryption, it is true, it will use the default IV tag to encrypt the files. + /// + ENABLE_DEFAULT_IV_TAG = 0x00000008, + /// + /// if it is enabled, it will send the message data to a persistent file, or it will send the event to service right away. + /// + ENABLE_ADD_MESSAGE_TO_FILE = 0x00000010, + /// + /// the encrypted file's meta data was embedded in the reparse point tag. + /// + ENCRYPT_FILE_WITH_REPARSE_POINT_TAG = 0x00000020, + /// + /// for encryption rule, get the encryption key and IV from user mode for the encrypted files. + /// + REQUEST_ENCRYPT_KEY_AND_IV_FROM_SERVICE = 0x00000040, + /// + /// for control filter, if it is enabled, the control filter rule will be applied in boot time. + /// + ENABLE_PROTECTION_IN_BOOT_TIME = 0x00000080, + /// + /// for encryption rule, get the encryption key and IV and tag data which will attach to the file. + /// + REQUEST_ENCRYPT_KEY_IV_AND_TAGDATA_FROM_SERVICE = 0x00000100, + /// + /// if it is enabled, it will send the read/write databuffer to user mode. + /// + ENABLE_SEND_DATA_BUFFER = 0x00000200, + /// + /// if it is enabled, it will reopen the file during rehydration of the stub file. + /// + ENABLE_REOPEN_FILE_ON_REHYDRATION = 0x00000400, + /// + /// if it is true, it will enable the buffer for monitor events and send asynchronously, + /// or the monitor event will wait till the service picks up the events. + /// + ENABLE_MONITOR_EVENT_BUFFER = 0x00000800, + /// + /// if it is true, it will send the event when it was blocked by the config setting. + /// + ENABLE_SEND_DENIED_EVENT = 0x00001000, + /// + /// if it is true, and the write access is false,the write will return success + /// with zero data being written to the file, and send the write data to the user mode. + /// this flag is reserved for custom feature. + /// + ENABLE_WRITE_WITH_ZERO_DATA_AND_SEND_DATA = 0x00002000, + /// + /// if it is true, the portable massive storage won't be treated as USB. + // this is for the volume control flag for BLOCK_USB_READ,BLOCK_USB_WRITE + /// + DISABLE_REMOVABLE_MEDIA_AS_USB = 0x00004000, + /// + /// if it is true, it will block the encrypted file to be renamed to different folder. + /// + DISABLE_RENAME_ENCRYPTED_FILE = 0x00008000, + /// + /// if it is true, the data protection will continue even the service process is stopped. + /// + ENABLE_PROTECTION_IF_SERVICE_STOPPED = 0x00020000, + /// + /// if it is true and write encrypt info to cache is enabled, it will signal the system thread to write cache data to disk right away. + /// + ENABLE_SIGNAL_WRITE_ENCRYPT_INFO_EVENT = 0x00020000, + /// + ///enable this feature when accessFlag "ALLOW_SAVE_AS" or "ALLOW_COPY_PROTECTED_FILES_OUT" was disabled. + ///by default we don't enable this feature, because of the drawback of these two flags were disabled + ///which will block all new file creation of the process which was read the protected files. + /// + ENABLE_BLOCK_SAVE_AS_FLAG = 0x00040000, + + } + + /// + /// The command sent by filter driver + /// + public enum FilterCommand + { + /// + /// send the notification event of the file was changed. + /// + FILTER_SEND_FILE_CHANGED_EVENT = 0x00010001, + /// + /// request the file open permission. + /// + FILTER_REQUEST_USER_PERMIT = 0x00010002, + /// + /// request the encryption key for the file open or creation. + /// + FILTER_REQUEST_ENCRYPTION_KEY = 0x00010003, + /// + /// request the encryption iv and key for the encrypted file open or to encrypt the file + /// + FILTER_REQUEST_ENCRYPTION_IV_AND_KEY = 0x00010004, + /// + /// request the encryption iv, key and access flags for the encrypted file open or to encrypt the file + /// + FILTER_REQUEST_ENCRYPTION_IV_AND_KEY_AND_ACCESSFLAG = 0x00010005, + /// + /// request the encryption iv, key and access flags and tag data for file encryption + /// + FILTER_REQUEST_ENCRYPTION_IV_AND_KEY_AND_TAGDATA = 0x00010006, + /// + /// send the registry access notification class information + /// + FILTER_SEND_REG_CALLBACK_INFO = 0x00010007, + /// + /// send the new process creation information + /// + FILTER_SEND_PROCESS_CREATION_INFO = 0x00010008, + /// + /// send the process termination information + /// + FILTER_SEND_PROCESS_TERMINATION_INFO = 0x00010009, + /// + /// send the new thread creation information + /// + FILTER_SEND_THREAD_CREATION_INFO = 0x0001000a, + /// + /// send the thread termination information + /// + FILTER_SEND_THREAD_TERMINATION_INFO = 0x0001000b, + /// + /// send the process handle operations information + /// + FILTER_SEND_PROCESS_HANDLE_INFO = 0x0001000c, + /// + /// send the thread handle operations information + /// + FILTER_SEND_THREAD_HANDLE_INFO = 0x0001000d, + /// + /// send the volume information when it was attached + /// + FILTER_SEND_ATTACHED_VOLUME_INFO = 0x0001000e, + /// + /// send the volume information when it was detached + /// + FILTER_SEND_DETACHED_VOLUME_INFO = 0x0001000f, + /// + /// send the event when the file IO was blocked by the config setting. + /// + FILTER_SEND_DENIED_FILE_IO_EVENT = 0x00010010, + /// + /// send the event when the volume dismount was blocked by the config setting. + /// + FILTER_SEND_DENIED_VOLUME_DISMOUNT_EVENT = 0x00010011, + /// + /// send the event when the process creation was blocked by the config setting. + /// + FILTER_SEND_DENIED_PROCESS_CREATION_EVENT = 0x00010012, + /// + /// send the event when the registry access was blocked by the config setting. + /// + FILTER_SEND_DENIED_REGISTRY_ACCESS_EVENT = 0x00010013, + /// + /// send the event when the protected process was terminiated ungratefully. + /// + FILTER_SEND_DENIED_PROCESS_TERMINATED_EVENT = 0x00010014, + /// + /// send the event when the read from USB was blocked. + /// + FILTER_SEND_DENIED_USB_READ_EVENT = 0x00010015, + /// + /// send the event when the write to USB was blocked. + /// + FILTER_SEND_DENIED_USB_WRITE_EVENT = 0x00010016, + /// + /// send process information before it was terminiated. + /// + FILTER_SEND_PRE_TERMINATE_PROCESS_INFO = 0x00010017, + + } + + public enum IOEventName + { + /// + /// Fires this event before the file create IO was going down to the file system. + /// + IOPreFileCreate = 0x00020001, + /// + /// Fires this event after the file create IO was returned from the file system. + /// + IOPostFileCreate, + /// + /// Fires this event before the file read IO was going down to the file system. + /// + IOPreFileRead, + /// + /// Fires this event after the file read IO was returned from the file system. + /// + IOPostFileRead, + /// + /// Fires this event before the file write IO was going down to the file system. + /// + IOPreFileWrite, + /// + /// Fires this event after the file write IO was returned from the file system. + /// + IOPostFileWrite, + /// + /// Fires this event before the query file size IO was going down to the file system. + /// + IOPreQueryFileSize, + /// + /// Fires this event after the query file size IO was returned from the file system. + /// + IOPostQueryFileSize, + /// + /// Fires this event before the query file basic info IO was going down to the file system. + /// + IOPreQueryFileBasicInfo, + /// + /// Fires this event after the query file basic info IO was returned from the file system. + /// + IOPostQueryFileBasicInfo, + /// + /// Fires this event before the query file standard info IO was going to the file system. + /// + IOPreQueryFileStandardInfo, + /// + /// Fires this event after the query file standard info IO was returned from the file system. + /// + IOPostQueryFileStandardInfo, + /// + /// Fires this event before the query file network info IO was going down to the file system. + /// + IOPreQueryFileNetworkInfo, + /// + /// Fires this event after the query file network info IO was returned from the file system. + /// + IOPostQueryFileNetworkInfo, + /// + /// Fires this event before the query file Id IO was going down to the file system. + /// + IOPreQueryFileId, + /// + /// Fires this event after the query file Id IO was returned from the file system. + /// + IOPostQueryFileId, + /// + /// Fires this event before the query file info IO was going down to the file system + /// if the query file information class is not 'QueryFileSize','QueryFileBasicInfo' + /// ,'QueryFileStandardInfo','QueryFileNetworkInfo' or 'QueryFileId'. + /// + IOPreQueryFileInfo, + /// + /// Fires this event after the query file info IO was returned from the file system. + /// + IOPostQueryFileInfo, + /// + /// Fires this event before the set file size IO was going down to the file system. + /// + IOPreSetFileSize, + /// + /// Fires this event after the set file size IO was returned from the file system. + /// + IOPostSetFileSize, + /// + /// Fires this event before the set file basic info IO was going down to the file system. + /// + IOPreSetFileBasicInfo, + /// + /// Fires this event after the set file basic info IO was returned from the file system. + /// + IOPostSetFileBasicInfo, + /// + /// Fires this event before the set file standard info IO was going down to the file system. + /// + IOPreSetFileStandardInfo, + /// + /// Fires this event after the set file standard info IO was returned from the file system. + /// + IOPostSetFileStandardInfo, + /// + /// Fires this event before the set file network info was going down to the file system. + /// + IOPreSetFileNetworkInfo, + /// + /// Fires this event after the set file network info was returned from the file system. + /// + IOPostSetFileNetworkInfo, + /// + /// Fires this event before the file move or rename IO was going down to the file system. + /// + IOPreMoveOrRenameFile, + /// + /// Fires this event after the file move or rename IO was returned from the file system. + /// + IOPostMoveOrRenameFile, + /// + /// Fires this event before the file delete IO was going down to the file system. + /// + IOPreDeleteFile, + /// + /// Fires this event after the file delete IO was returned from the file system. + /// + IOPostDeleteFile, + /// + /// Fires this event before the set file info IO was going down to the file system + /// if the information class is not 'SetFileSize','SetFileBasicInfo' + /// ,'SetFileStandardInfo','SetFileNetworkInfo'. + /// + IOPreSetFileInfo, + /// + /// Fires this event after the set file info IO was returned from the file system. + /// + IOPostSetFileInfo, + /// + /// Fires this event before the query directory file info was going down to the file system. + /// + IOPreQueryDirectoryFile, + /// + /// Fires this event after the query directory file info was returned from the file system. + /// + IOPostQueryDirectoryFile, + /// + /// Fires this event before the query file security IO was going down to the file system. + /// + IOPreQueryFileSecurity, + /// + /// Fires this event after the query file security IO was returned from the file system. + /// + IOPostQueryFileSecurity, + /// + /// Fires this event before the set file security IO was going down to the file system. + /// + IOPreSetFileSecurity, + /// + /// Fires thiis event after the set file security IO was returned from the file system. + /// + IOPostSetFileSecurity, + /// + /// Fire this event before the file handle close IO was going down to the file system. + /// + IOPreFileHandleClose, + /// + /// Fires this event after the file handle close IO was returned from the file system. + /// + IOPostFileHandleClose, + /// + /// Fires this event before the file close IO was going down to the file system. + /// + IOPreFileClose, + /// + /// Fires this event after the file close IO was returned from the file system. + /// + IOPostFileClose, + } + + /// + /// the message type of the filter driver send the file IO request + /// + public enum MessageType : uint + { + PRE_CREATE = 0x00000001, + POST_CREATE = 0x00000002, + PRE_FASTIO_READ = 0x00000004, + POST_FASTIO_READ = 0x00000008, + PRE_CACHE_READ = 0x00000010, + POST_CACHE_READ = 0x00000020, + PRE_NOCACHE_READ = 0x00000040, + POST_NOCACHE_READ = 0x00000080, + PRE_PAGING_IO_READ = 0x00000100, + POST_PAGING_IO_READ = 0x00000200, + PRE_FASTIO_WRITE = 0x00000400, + POST_FASTIO_WRITE = 0x00000800, + PRE_CACHE_WRITE = 0x00001000, + POST_CACHE_WRITE = 0x00002000, + PRE_NOCACHE_WRITE = 0x00004000, + POST_NOCACHE_WRITE = 0x00008000, + PRE_PAGING_IO_WRITE = 0x00010000, + POST_PAGING_IO_WRITE = 0x00020000, + PRE_QUERY_INFORMATION = 0x00040000, + POST_QUERY_INFORMATION = 0x00080000, + PRE_SET_INFORMATION = 0x00100000, + POST_SET_INFORMATION = 0x00200000, + PRE_DIRECTORY = 0x00400000, + POST_DIRECTORY = 0x00800000, + PRE_QUERY_SECURITY = 0x01000000, + POST_QUERY_SECURITY = 0x02000000, + PRE_SET_SECURITY = 0x04000000, + POST_SET_SECURITY = 0x08000000, + PRE_CLEANUP = 0x10000000, + POST_CLEANUP = 0x20000000, + PRE_CLOSE = 0x40000000, + POST_CLOSE = 0x80000000, + + } + + /// + /// The file changed events for monitor filter, it will be fired after the file handle was closed. + /// + public enum FileChangedEvents:uint + { + /// + /// Fires this event when the new file was created after the file handle closed + /// + NotifyFileWasCreated = 0x00000020, + /// + /// Fires this event when the file was written after the file handle closed + /// + NotifyFileWasWritten = 0x00000040, + /// + /// Fires this event when the file was moved or renamed after the file handle closed + /// + NotifyFileWasRenamed = 0x00000080, + /// + /// Fires this event when the file was deleted after the file handle closed + /// + NotifyFileWasDeleted = 0x00000100, + /// + /// Fires this event when the file's security was changed after the file handle closed + /// + NotifyFileSecurityWasChanged = 0x00000200, + /// + /// Fires this event when the file's information was changed after the file handle closed + /// + NotifyFileInfoWasChanged = 0x00000400, + /// + /// Fires this event when the file's data was read after the file handle closed + /// + NotifyFileWasRead = 0x00000800, + /// + /// This is only for Windows 11, version 22H2 or later OS. + /// Fires this event when the file was copied after the file handle closed + /// + NotifyFileWasCopied = 0x00001000, + } + + /// + /// Fires all file events it this value was set. + /// + public const uint NotifyAllFileEvents = 0xfffffff0; + + /// + /// The maximum file access right + /// + public const uint ALLOW_MAX_RIGHT_ACCESS = 0xfffffff0; + + /// + /// The change file access right + /// + public const uint ALLOW_FILE_CHANGE_ACCESS = (uint)(AccessFlag.ALLOW_WRITE_ACCESS + | AccessFlag.ALLOW_FILE_DELETE + | AccessFlag.ALLOW_FILE_SIZE_CHANGE + | AccessFlag.ALLOW_OPEN_WITH_CREATE_OR_OVERWRITE_ACCESS + | AccessFlag.ALLOW_OPEN_WITH_DELETE_ACCESS + | AccessFlag.ALLOW_SET_INFORMATION + | AccessFlag.ALLOW_SET_SECURITY_ACCESS + | AccessFlag.ALLOW_FILE_RENAME); + + /// + /// The read file access right + /// + public const uint ALLOW_FILE_READ_ACCESS = (uint)(AccessFlag.ALLOW_OPEN_WITH_READ_ACCESS + |AccessFlag.ALLOW_READ_ACCESS + |AccessFlag.ALLOW_QUERY_INFORMATION_ACCESS + |AccessFlag.ALLOW_QUERY_SECURITY_ACCESS + |AccessFlag.ALLOW_FILE_MEMORY_MAPPED + |AccessFlag.ALLOW_DIRECTORY_LIST_ACCESS + |AccessFlag.ALLOW_READ_ENCRYPTED_FILES ); + + /// + /// control the access rights of the file IO,set the accessFlag to LEAST_ACCESS_FLAG if you want to least access rights to the files. + /// + public enum AccessFlag : uint + { + /// + /// Filter driver will skip all the IO when the accessFlag equal 0 if the file name match the include file mask. + /// + EXCLUDE_FILTER_RULE = 0X00000000, + /// + /// Block the file open. + /// + EXCLUDE_FILE_ACCESS = 0x00000001, + /// + /// Reparse the file open to the new file name if the reparse file mask was added. + /// + ENABLE_REPARSE_FILE_OPEN = 0x00000002, + /// + /// Hide the files from the folder directory list if the hide file mask was added. + /// + ENABLE_HIDE_FILES_IN_DIRECTORY_BROWSING = 0x00000004, + /// + /// Enable the transparent file encryption if the encryption key was added. + /// + ENABLE_FILE_ENCRYPTION_RULE = 0x00000008, + /// + /// Allow the file open to access the file's security information. + /// + ALLOW_OPEN_WITH_ACCESS_SYSTEM_SECURITY = 0x00000010, + /// + /// Allow the file open for read access. + /// + ALLOW_OPEN_WITH_READ_ACCESS = 0x00000020, + /// + /// Allow the file open for write access. + /// + ALLOW_OPEN_WITH_WRITE_ACCESS = 0x00000040, + /// + /// Allow the file open for create new file or overwrite access. + /// + ALLOW_OPEN_WITH_CREATE_OR_OVERWRITE_ACCESS = 0x00000080, + /// + /// Allow the file open for delete. + /// + ALLOW_OPEN_WITH_DELETE_ACCESS = 0x00000100, + /// + /// Allow to read the file data. + /// + ALLOW_READ_ACCESS = 0x00000200, + /// + /// Allow write data to the file. + /// + ALLOW_WRITE_ACCESS = 0x00000400, + /// + /// Allow to query file information. + /// + ALLOW_QUERY_INFORMATION_ACCESS = 0x00000800, + /// + /// Allow to change the file information:file attribute,file size,file name,delete file + /// + ALLOW_SET_INFORMATION = 0x00001000, + /// + /// Allow to rename the file. + /// + ALLOW_FILE_RENAME = 0x00002000, + /// + /// Allow to delete the file. + /// + ALLOW_FILE_DELETE = 0x00004000, + /// + /// Allow to change file size. + /// + ALLOW_FILE_SIZE_CHANGE = 0x00008000, + /// + /// Allow query the file security information. + /// + ALLOW_QUERY_SECURITY_ACCESS = 0x00010000, + /// + /// Allow change the file security information. + /// + ALLOW_SET_SECURITY_ACCESS = 0x00020000, + /// + /// Allow to browse the directory file list. + /// + ALLOW_DIRECTORY_LIST_ACCESS = 0x00040000, + /// + /// Allow the remote access via share folder. + /// + ALLOW_FILE_ACCESS_FROM_NETWORK = 0x00080000, + /// + /// Allow to encrypt the new file if the encryption filter rule is enabled, . + /// + ALLOW_ENCRYPT_NEW_FILE = 0x00100000, + /// + /// Allow the application to read the encrypted files, or it will return encrypted data. + /// + ALLOW_READ_ENCRYPTED_FILES = 0x00200000, + /// + /// Allow the application to create a new file after it opened the protected file. + /// + ALLOW_ALL_SAVE_AS = 0x00400000, + /// + /// Allow copy protected files out of the protected folder if ALLOW_ALL_SAVE_AS is enabled. + /// + ALLOW_COPY_PROTECTED_FILES_OUT = 0x00800000, + /// + /// Allow the file to be mapped into memory access. + /// + ALLOW_FILE_MEMORY_MAPPED = 0x01000000, + /// + /// if the encryption filter rule is enabled, it will encrypt unencrypted data on read when the flag value is 0. + /// + DISABLE_ENCRYPT_DATA_ON_READ = 0x02000000, + /// + /// prevent the protected files from being copying out to the USB when the flag value is 0. + /// + ALLOW_COPY_PROTECTED_FILES_TO_USB = 0x04000000, + /// + /// If it is not exclude filter rule,the access flag can't be 0, at least you need to include this flag + /// for filter driver to process this filter rule. + /// + LEAST_ACCESS_FLAG = 0xf0000000, + // ALLOW_MAX_RIGHT_ACCESS = 0xfffffff0, + } + + const uint AES_VERIFICATION_KEY = 0xccb76e80; + const int default_header_size = 1024; + + /// + /// this is the header structure of the encrypted file + /// + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + public struct AES_HEADER + { + public uint VerificationKey; + public uint AESFlags; + public uint Version; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] + public byte[] IV; + public uint EncryptionKeyLength; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] + public byte[] EncryptionKey; + public long FileSize; + public uint CryptoType; + public uint PaddingSize; + //the size of this data structure + public uint AESDataSize; + //the actual physical file size in disk including the padding and the header. + public long ShadowFileSize; + public uint AccessFlags; + public uint Reserve1; + public uint Reserve2; + public uint TagDataLength; + /// + /// the maximum tag data size if the header size - sizeof(AES_HEADER); + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = default_header_size)] + public byte[] TagData; + + }; + + /// + /// This is the data structure the filter driver send request to the user mode service. + /// + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + public struct MessageSendData + { + /// + ///the verification number which verifies the data structure integerity. + /// + public uint VerificationNumber; + /// + /// This is the command Id which was sent by filter driver. + /// + public uint FilterCommand; + /// + /// This is the sequential message Id, just for reference. + /// + public uint MessageId; + /// + /// This the filter rule Id associated to the filter rule. + /// + public uint FilterRuleId; + /// + /// This is the ip address of the remote computer when it accesses the file via SMB. + /// it is only effected for win 7 or later OS. + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = INET_ADDR_STR_LEN*2)] + public byte[] RemoteIP; + /// + ///the address of FileObject,it is equivalent to file handle,it is unique per file stream open. + /// + public IntPtr FileObject; + /// + ///the address of FsContext,it is unique per file. + /// + public IntPtr FsContext; + /// + ///the message type of the file I/O, registry class. + /// + public ulong MessageType; + /// + ///the process ID for the process associated with the thread that originally requested the I/O operation. + /// + public uint ProcessId; + /// + ///the thread ID which requested the I/O operation. + /// + public uint ThreadId; + /// + ///the read/write offset. + /// + public long Offset; + /// + ///the read/write length. + /// + public uint Length; + /// + ///the size of the file for the I/O operation. + /// + public long FileSize; + /// + ///the transaction time in UTC of this request. + /// + public long TransactionTime; + /// + ///the creation time in UTC of the file. + /// + public long CreationTime; + /// + ///the last access time in UTC of the file. + /// + public long LastAccessTime; + /// + ///the last write time in UTC of the file. + /// + public long LastWriteTime; + /// + ///the file attributes. + /// + public uint FileAttributes; + /// + ///the DesiredAccess for file open, please reference CreateFile windows API. + /// + public uint DesiredAccess; + /// + ///the Disposition for file open, please reference CreateFile windows API. + /// + public uint Disposition; + /// + ///the SharedAccess for file open, please reference CreateFile windows API. + /// + public uint SharedAccess; + /// + ///the CreateOptions for file open, please reference CreateFile windows API. + /// + public uint CreateOptions; + /// + ///the CreateStatus after file was openned, please reference CreateFile windows API. + /// + public uint CreateStatus; + /// + ///this is the information class for security/directory/information IO + /// + public uint InfoClass; + /// + ///the I/O status which returned from file system. + /// + public uint Status; + /// + /// the return I/O (read/write) length + /// + public uint ReturnLength; + /// + ///the file name length in byte. + /// + public uint FileNameLength; + /// + ///the file name of the I/O operation. + /// + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_FILE_NAME_LENGTH)] + public string FileName; + /// + ///the length of the security identifier. + /// + public uint SidLength; + /// + ///the security identifier data. + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_SID_LENGTH)] + public byte[] Sid; + /// + ///the data buffer length. + /// + public uint DataBufferLength; + /// + ///the data buffer which contains read/write/query information/set information data. + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_MESSAGE_LENGTH)] + public byte[] DataBuffer; + + } + + + /// + /// The attached volume control flag. + /// + public enum VolumeControlFlag : uint + { + /// + /// Get all the attached volumes' information. + /// + GET_ATTACHED_VOLUME_INFO = 0x00000001, + /// + /// Get a notification when the filter driver attached to a volume. + /// + VOLUME_ATTACHED_NOTIFICATION = 0x00000002, + /// + /// Get a notification when the filter driver detached from a volume. + /// + VOLUME_DETACHED_NOTIFICATION = 0x00000004, + /// + /// Prevent the attched volumes from being formatted or dismounted. + /// + BLOCK_VOLUME_DISMOUNT = 0x00000008, + /// + ///Block the read from the USB disk. + /// + BLOCK_USB_READ = 0x00000010, + /// + ///Block the write to the USB disk + /// + BLOCK_USB_WRITE = 0x00000020, + + } + + /// + /// the structure of the attached volume information + /// + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + public struct VOLUME_INFO + { + /// + /// The length of the volume name. + /// + public uint VolumeNameLength; + /// + /// The volume name buffer. + /// + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_FILE_NAME_LENGTH)] + public string VolumeName; + /// + /// The length of the volume dos file name. + /// + public uint VolumeDosNameLength; + /// + /// The volume dos file name buffer. + /// + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_FILE_NAME_LENGTH)] + public string VolumeDosName; + /// + ///the volume file system type. + /// + public uint VolumeFilesystemType; + /// + ///the Characteristics of the attached device object if existed. + /// + public uint DeviceCharacteristics; + + } + + /// + /// Set the volume control to get the notification of the attached volume information. + /// + /// + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool SetVolumeControlFlag(uint volumeControlFlag); + + /// + /// the data structuct sent by the process filter driver + /// + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + public struct PROCESS_INFO + { + /// + ///The process ID of the parent process for the new process. Note that the parent process is not necessarily the same process as the process that created the new process. + /// + public uint ParentProcessId; + /// + /// The process ID of the process that created the new process. + /// + public uint CreatingProcessId; + /// + /// The thread ID of the thread that created the new process. + /// + public uint CreatingThreadId; + /// + ///An ACCESS_MASK value that specifies the access rights to grant for the handle + /// + public uint DesiredAccess; + /// + ///The type of handle operation. This member might be one of the following values:OB_OPERATION_HANDLE_CREATE,OB_OPERATION_HANDLE_DUPLICATE + /// + public uint Operation; + /// + /// A Boolean value that specifies whether the ImageFileName member contains the exact file name that is used to open the process executable file. + /// + public bool FileOpenNameAvailable; + /// + /// The length of the command line. + /// + public uint CommandLineLength; + /// + /// The command that is used to execute the process. + /// + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_FILE_NAME_LENGTH)] + public string CommandLine; + } + + /// + /// the filter status which will be returned to the filter driver, + /// the filter driver will process the IO based the return status. + /// + public enum FilterStatus : uint + { + FILTER_MESSAGE_IS_DIRTY = 0x00000001, //the data buffer was updated. + FILTER_COMPLETE_PRE_OPERATION = 0x00000002, //ONLY FOR PRE CALL OPERATION,the IO won't pass down to the lower drivers and file system. + FILTER_DATA_BUFFER_IS_UPDATED = 0x00000004, //only for pre create,to reparse the file open to the new file name. + BLOCK_DATA_WAS_RETURNED = 0x00000008, //Set this flag if return read block databuffer to filter. + CACHE_FILE_WAS_RETURNED = 0x00000010, //Set this flag if the stub file was restored. + } + + /// + /// this is the data structure which will be returned back to the filter driver. + /// + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + public struct MessageReplyData + { + public uint MessageId; + public uint MessageType; + public uint ReturnStatus; + public uint FilterStatus; + public uint DataBufferLength; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 65536)] + public byte[] DataBuffer; + } + + /// + /// set the filter driver boolean config setting based on the enum booleanConfig + /// + /// + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool SetBooleanConfig(uint booleanConfig); + + /// + /// install the filter driver service, it request the administrator privilege + /// + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool InstallDriver(); + + /// + /// uninstall the filter driver service. + /// + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool UnInstallDriver(); + + /// + /// to check if the filter driver service is running. + /// + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool IsDriverServiceRunning(); + + /// + /// set the registration key to enable the filter driver service. + /// + /// + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool SetRegistrationKey([MarshalAs(UnmanagedType.LPStr)]string key); + + /// + /// disconnect the communication channel of the filter driver. + /// + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool Disconnect(); + + /// + /// get the last error message if the filter driver API return false. + /// + /// + /// + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool GetLastErrorMessage( + [MarshalAs(UnmanagedType.LPWStr)] + string lastError, + ref int messageLength); + + /// + /// Create the filter driver connection with callback settings + /// + /// the number of working threads waitting for the callback message + /// the callback function + /// the disconnect callback function + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool RegisterMessageCallback( + int threadCount, + IntPtr filterCallback, + IntPtr disconnectCallback); + + /// + /// reset the filter driver config settings to the default value. + /// + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool ResetConfigData(); + + /// + /// set the filter driver type. + /// + /// + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool SetFilterType(uint filterType); + + /// + /// set the maiximun wait time of the filter driver sending message to service. + /// + /// + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool SetConnectionTimeout(uint timeOutInSeconds); + + /// + /// set the maximum monitor event buffer size if monitorBuffer was enabled. + /// + /// + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool SetMaxMonitorEventBuffersize(uint maxMonitorEventBufferSize); + + /// + /// If the encrypt write buffer size is greater than 0, then the small buffer encryption write will be combined together to a bigger buffer, + /// and write it to the disk. + /// + /// + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool SetEncryptWriteBufferSize(uint encryptWriteBufferSize); + + /// + /// Add the new filter rule to the filter driver. + /// + /// access control rights of the file IO to the files which match the filter mask + /// the filter rule file filter mask, it must be unique. + /// if it is true, the filter rule will be added to the registry, get protection in boot time. + /// the id to identify the filter rule, it will show up in messageId field of messageSend structure if the callback is registered + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AddFileFilterRule( + uint accessFlag, + [MarshalAs(UnmanagedType.LPWStr)]string filterMask, + bool isResident, + uint filterRuleId ); + + + /// + ///Set an encryption folder, every encrypted file has the unique iv key, + ///the encrypted information will be appended to the file as an header, + ///the filter driver will know if the file was encrypted by checking the header. + /// + /// + /// + /// + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AddEncryptionKeyToFilterRule( + [MarshalAs(UnmanagedType.LPWStr)]string filterMask, + uint encryptionKeyLength, + byte[] encryptionKey); + + /// + ///Set an encryption folder, all encrypted files use the same encryption key and IV key. + /// + /// + /// + /// + /// + /// + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AddEncryptionKeyAndIVToFilterRule( + [MarshalAs(UnmanagedType.LPWStr)]string filterMask, + uint encryptionKeyLength, + byte[] encryptionKey, + uint ivLength, + byte[] iv); + + /// + /// Exclude the file IO from this filter rule if the files match the excludeFileFilterMask. + /// + /// the filter rule file filter mask + /// the file filter mask for the excluded files + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AddExcludeFileMaskToFilterRule( + [MarshalAs(UnmanagedType.LPWStr)]string filterMask, + [MarshalAs(UnmanagedType.LPWStr)]string excludeFileFilterMask); + + /// + /// Hide the files from the browsing file list for the filter rule. + /// + /// the filter rule file filter mask. + /// the file filter mask for the hidden files. + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AddHiddenFileMaskToFilterRule( + [MarshalAs(UnmanagedType.LPWStr)]string filterMask, + [MarshalAs(UnmanagedType.LPWStr)]string hiddenFileFilterMask); + + /// + /// reparse the file open to the other file if the file matches the file filter mask. + /// + ///For example: + ///FilterMask = c:\test\*txt + ///ReparseFilterMask = d:\reparse\*doc + ///If you open file c:\test\MyTest.txt, it will reparse to the file d:\reparse\MyTest.doc. + /// + /// the filter rule file filter mask + /// reparse file filter mask + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AddReparseFileMaskToFilterRule( + [MarshalAs(UnmanagedType.LPWStr)]string filterMask, + [MarshalAs(UnmanagedType.LPWStr)]string reparseFileFilterMask); + + /// + ///only manage the file IO for the processes in the included process list + /// + /// the file filter mask of the filter rule + /// the include process name filter mask, process name format:notepad.exe + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AddIncludeProcessNameToFilterRule( + [MarshalAs(UnmanagedType.LPWStr)]string filterMask, + [MarshalAs(UnmanagedType.LPWStr)]string processName); + + /// + /// skip the IO of the filter rule for the processes in the excluded process list + /// + /// the file filter mask of the filter rule + /// the include process name filter mask + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AddExcludeProcessNameToFilterRule( + [MarshalAs(UnmanagedType.LPWStr)]string filterMask, + [MarshalAs(UnmanagedType.LPWStr)]string processName); + + /// + /// only manage the IO of the filter rule for the processes in the included process id list + /// + /// the file filter mask of the filter rule + /// the included process Id + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AddIncludeProcessIdToFilterRule( + [MarshalAs(UnmanagedType.LPWStr)]string filterMask, + uint includeProcessId); + + /// + /// skip the IO of the filter rule for the processes in the excluded process id list + /// + /// the file filter mask of the filter rule + /// the excluded process Id + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AddExcludeProcessIdToFilterRule( + [MarshalAs(UnmanagedType.LPWStr)]string filterMask, + uint excludeProcessId); + + /// + /// only manage the IO of the filter rule for user name in the included user name list + /// + /// the file filter mask of the filter rule + /// the included user name, format:domainName(or computerName)\userName.exe + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AddIncludeUserNameToFilterRule( + [MarshalAs(UnmanagedType.LPWStr)]string filterMask, + [MarshalAs(UnmanagedType.LPWStr)]string userName); + + /// + ///skip the IO of the filter rule for user name in the excluded user name list + /// + /// the file filter mask of the filter rule + /// the excluded user name, format:domainName(or computerName)\userName.exe + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AddExcludeUserNameToFilterRule( + [MarshalAs(UnmanagedType.LPWStr)]string filterMask, + [MarshalAs(UnmanagedType.LPWStr)]string userName); + + /// + /// Register the file changed events for the filter rule, get the notification when the I/O was triggered + /// after the file handle was closed. + /// + /// the file filter mask of the filter rule + /// the I/O event types,reference the FileEventType enumeration. + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool RegisterFileChangedEventsToFilterRule( + [MarshalAs(UnmanagedType.LPWStr)]string filterMask, + uint eventType); + + /// + /// Register the callback I/O for monitor filter driver to the filter rule. + /// + /// the file filter mask of the filter rule + /// the specific I/Os you want to monitor + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool RegisterMonitorIOToFilterRule( + [MarshalAs(UnmanagedType.LPWStr)]string filterMask, + ulong registerIO); + + /// + /// Register the callback I/O for control filter driver to the filter rule, you can change, block and pass the I/O + /// in your callback funtion. + /// + /// the file filter mask of the filter rule + /// the specific I/Os you want to monitor or control + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool RegisterControlIOToFilterRule( + [MarshalAs(UnmanagedType.LPWStr)]string filterMask, + ulong registerIO); + + /// + /// Filter the I/O based on the file create options,the IO will be skipped if the filter option is not 0 + /// and the file create options don't match the filter. + /// + /// the file filter mask of the filter rule + /// if it is not 0, the filter driver will check if the file creation option "DesiredAccess" matches the filter + /// if it is not 0, the filter driver will check if the file creation option "Disposition" matches the filter + /// if it is not 0, the filter driver will check if the file creation option "CreateOptions" matches the filter + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AddCreateFilterToFilterRule( + [MarshalAs(UnmanagedType.LPWStr)]string filterMask, + uint filterByDesiredAccess, + uint filterByDisposition, + uint filterByCreateOptions); + + /// + /// Set the access rights to the specific process + /// + /// the file filter mask of the filter rule + /// the process name will be added the access rights, e.g. notepad.exe or c:\windows\*.exe + /// the access rights + /// return true if it succeeds + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AddProcessRightsToFilterRule( + [MarshalAs(UnmanagedType.LPWStr)]string filterMask, + [MarshalAs(UnmanagedType.LPWStr)]string processName, + uint accessFlags); + + /// + /// Remove the acces right setting for specific processes from filter rule + /// + /// tthe filter rule file filter mask + /// the process name filter mask + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool RemoveProcessRightsFromFilterRule( + [MarshalAs(UnmanagedType.LPWStr)]string filterMask, + [MarshalAs(UnmanagedType.LPWStr)]string processName); + + /// + /// Get sha256 hash of the file, you need to allocate the 32 bytes array to get the sha256 hash. + /// hashBytesLength is the input byte array length, and the outpout length of the hash. + /// + /// + /// + /// + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool Sha256HashFile( + [MarshalAs(UnmanagedType.LPWStr)]string fileName, + byte[] hashBytes, + ref uint hashBytesLength); + + /// + /// Add the access rights of the process with the sha256 hash to the filter rule. + /// allows you to set the access rights to your trusted process. + /// + /// The filter rule file filter mask. + /// the sha256 hash of the executable binary file. + /// the length of the sha256 hash, by default is 32. + /// the access flags for the setting process. + /// return true if it is succeeded. + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AddSha256ProcessAccessRightsToFilterRule( + [MarshalAs(UnmanagedType.LPWStr)]string filterMask, + byte[] imageSha256, + uint hashLength, + uint accessFlags); + + /// + /// Add the access rights of the process which was signed with the certificate to the filter rule. + /// allows you to set the access rights to your trusted process. + /// + /// The filter rule file filter mask. + /// the subject name of the code certificate to sign the process. + /// the length of the certificate name + /// the access flags for the setting process. + /// return true if it is succeeded. + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AddSignedProcessAccessRightsToFilterRule( + [MarshalAs(UnmanagedType.LPWStr)]string filterMask, + [MarshalAs(UnmanagedType.LPWStr)]string certificateName, + uint lengthOfCertificate, + uint accessFlags); + + /// + /// Set the access control flags to process with the processId + /// + /// the filter rule file filter mask + /// the process Id which will be added the access control flags + /// the access control flags + /// return true if it succeeds + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AddProcessIdRightsToFilterRule( + [MarshalAs(UnmanagedType.LPWStr)]string filterMask, + uint processId, + uint accessFlags); + + /// + /// Remove the acces right setting for specific process from filter rule + /// + /// the filter rule file filter mask + /// the process Id + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool RemoveProcessIdRightsFromFilterRule( + [MarshalAs(UnmanagedType.LPWStr)]string filterMask, + uint processId); + + /// + /// Set the access control rights to specific users + /// + /// the filter rule file filter mask + /// the user name you want to set the access right + /// the access rights + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AddUserRightsToFilterRule( + [MarshalAs(UnmanagedType.LPWStr)]string filterMask, + [MarshalAs(UnmanagedType.LPWStr)]string userName, + uint accessFlags); + + /// + /// Remove the access control rights to specific users + /// + /// the filter rule file filter mask + /// the user name you want to set the access right + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool RemoveUserRightsFromFilterRule( + [MarshalAs(UnmanagedType.LPWStr)]string filterMask, + [MarshalAs(UnmanagedType.LPWStr)]string userName); + + /// + /// Add the boolean config setting to a filter rule. + /// Reference BooleanConfig settings + /// + /// the filter rule file filter mask + /// the boolean config setting + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AddBooleanConfigToFilterRule( + [MarshalAs(UnmanagedType.LPWStr)]string filterMask, + uint booleanConfig); + + + /// + /// Remove the filter rule from the filter driver. + /// + /// the filter rule file filter mask + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool RemoveFilterRule( + [MarshalAs(UnmanagedType.LPWStr)] string filterMask); + + /// + /// Add the process Id to include process list, only the process Id in the list will be managed by the filter driver, + /// or all the file IO from the process Id which is not in the list will be skipped. This is the global settings, it will affect all filter rules. + /// + /// + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AddIncludedProcessId(uint processId); + + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool RemoveIncludeProcessId(uint processId); + + /// + ///Add the process Id to the exclude process list, all the file IO from the process Id which is in the excluded list will be skipped. + ///This is the global settings, it will affect all filter rules. + /// + /// + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AddExcludedProcessId(uint processId); + + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool RemoveExcludeProcessId(uint processId); + + + //---------------Registry access control APIs----------------------------------- + /// + /// The maximum registry access right flag + /// + public const uint MAX_REGITRY_ACCESS_FLAG = 0xFFFFFFFF; + + /// + /// Allow read registry access right + /// + public const uint ALLOW_READ_REGITRY_ACCESS_FLAG = (uint)(RegControlFlag.REG_ALLOW_OPEN_KEY + | RegControlFlag.REG_ALLOW_QUERY_KEY | RegControlFlag.REG_ALLOW_ENUMERATE_KEY | RegControlFlag.REG_ALLOW_QUERY_VALUE_KEY + | RegControlFlag.REG_ALLOW_QUERY_KEY_SECURITY | RegControlFlag.REG_ALLOW_QUERY_KEYNAME); + + /// + /// Allow change registry access right + /// + public const uint ALLOW_CHANGE_REGITRY_ACCESS_FLAG = (uint)(RegControlFlag.REG_ALLOW_CREATE_KEY + | RegControlFlag.REG_ALLOW_RENAME_KEY | RegControlFlag.REG_ALLOW_DELETE_KEY | RegControlFlag.REG_ALLOW_SET_VALUE_KEY_INFORMATION + | RegControlFlag.REG_ALLOW_DELETE_VALUE_KEY | RegControlFlag.REG_ALLOW_SET_KEY_SECRUITY | RegControlFlag.REG_ALLOW_RESTORE_KEY + | RegControlFlag.REG_ALLOW_REPLACE_KEY | RegControlFlag.REG_ALLOW_LOAD_KEY); + + /// + /// the registry access control flag, allow or deny the registry access based on the registry filter rule. + /// + public enum RegControlFlag : uint + { + REG_ALLOW_OPEN_KEY = 0x00000001, + REG_ALLOW_CREATE_KEY = 0x00000002, + REG_ALLOW_QUERY_KEY = 0x00000004, + REG_ALLOW_RENAME_KEY = 0x00000008, + REG_ALLOW_DELETE_KEY = 0x00000010, + REG_ALLOW_SET_VALUE_KEY_INFORMATION = 0x00000020, + REG_ALLOW_SET_INFORMATION_KEY = 0x00000040, + REG_ALLOW_ENUMERATE_KEY = 0x00000080, + REG_ALLOW_QUERY_VALUE_KEY = 0x00000100, + REG_ALLOW_ENUMERATE_VALUE_KEY = 0x00000200, + REG_ALLOW_QUERY_MULTIPLE_VALUE_KEY = 0x00000400, + REG_ALLOW_DELETE_VALUE_KEY = 0x00000800, + REG_ALLOW_QUERY_KEY_SECURITY = 0x00001000, + REG_ALLOW_SET_KEY_SECRUITY = 0x00002000, + REG_ALLOW_RESTORE_KEY = 0x00004000, + REG_ALLOW_REPLACE_KEY = 0x00008000, + REG_ALLOW_SAVE_KEY = 0x00010000, + REG_ALLOW_FLUSH_KEY = 0x00020000, + REG_ALLOW_LOAD_KEY = 0x00040000, + REG_ALLOW_UNLOAD_KEY = 0x00080000, + REG_ALLOW_KEY_CLOSE = 0x00100000, + REG_ALLOW_QUERY_KEYNAME = 0x00200000, + /// + /// send the registry event when registry access was blocked by the above setting, + /// when it was set to true. + /// + ENABLE_FILTER_SEND_DENIED_REG_EVENT = 0x80000000, + } + + /// + /// this is the value which will register all the registry notification callback class. + /// + public const ulong MAX_REG_CALLBACK_CLASS = 0xFFFFFFFFFFFFFFFF; + + /// + /// the registry callback class, you can block or modify the registry access in pre-callback + /// or monitor the registry access in post-callback + /// + public enum RegCallbackClass : ulong + { + Reg_Pre_Delete_Key = 0x00000001, + Reg_Pre_Set_Value_Key = 0x00000002, + Reg_Pre_Delete_Value_Key = 0x00000004, + Reg_Pre_SetInformation_Key = 0x00000008, + Reg_Pre_Rename_Key = 0x00000010, + Reg_Pre_Enumerate_Key = 0x00000020, + Reg_Pre_Enumerate_Value_Key = 0x00000040, + Reg_Pre_Query_Key = 0x00000080, + Reg_Pre_Query_Value_Key = 0x00000100, + Reg_Pre_Query_Multiple_Value_Key = 0x00000200, + Reg_Pre_Create_Key = 0x00000400, + Reg_Post_Create_Key = 0x00000800, + Reg_Pre_Open_Key = 0x00001000, + Reg_Post_Open_Key = 0x00002000, + Reg_Pre_Key_Handle_Close = 0x00004000, + // + // .Net only + // + Reg_Post_Delete_Key = 0x00008000, + Reg_Post_Set_Value_Key = 0x00010000, + Reg_Post_Delete_Value_Key = 0x00020000, + Reg_Post_SetInformation_Key = 0x00040000, + Reg_Post_Rename_Key = 0x00080000, + Reg_Post_Enumerate_Key = 0x00100000, + Reg_Post_Enumerate_Value_Key = 0x00200000, + Reg_Post_Query_Key = 0x00400000, + Reg_Post_Query_Value_Key = 0x00800000, + Reg_Post_Query_Multiple_Value_Key = 0x01000000, + Reg_Post_Key_Handle_Close = 0x02000000, + Reg_Pre_Create_KeyEx = 0x04000000, + Reg_Post_Create_KeyEx = 0x08000000, + Reg_Pre_Open_KeyEx = 0x10000000, + Reg_Post_Open_KeyEx = 0x20000000, + // + // new to Windows Vista + // + Reg_Pre_Flush_Key = 0x40000000, + Reg_Post_Flush_Key = 0x80000000, + Reg_Pre_Load_Key = 0x100000000, + Reg_Post_Load_Key = 0x200000000, + Reg_Pre_UnLoad_Key = 0x400000000, + Reg_Post_UnLoad_Key = 0x800000000, + Reg_Pre_Query_Key_Security = 0x1000000000, + Reg_Post_Query_Key_Security = 0x2000000000, + Reg_Pre_Set_Key_Security = 0x4000000000, + Reg_Post_Set_Key_Security = 0x8000000000, + // + // per-object context cleanup + // + Reg_Callback_Object_Context_Cleanup = 0x10000000000, + // + // new in Vista SP2 + // + Reg_Pre_Restore_Key = 0x20000000000, + Reg_Post_Restore_Key = 0x40000000000, + Reg_Pre_Save_Key = 0x80000000000, + Reg_Post_Save_Key = 0x100000000000, + Reg_Pre_Replace_Key = 0x200000000000, + Reg_Post_Replace_Key = 0x400000000000, + + // + // new in Windows 10 + // + Reg_Pre_Query_KeyName = 0x800000000000, + Reg_Post_Query_KeyName = 0x1000000000000, + + } + + /// + /// Add registry access control filter entry with process name filter mask, user name filter mask and registry + /// key filter mask + /// + /// The length of the process name string in bytes + /// The process name to be filtered, all processes if it is '*' + /// set the processId if you want to filter by id instead of the process name + /// the user name length if you want to filter the user name + /// the user name filter mask + /// set the registry key name filter if you want to filter by the key name + /// the registry key name filter mask + /// The access control flag to the registry + /// The registered callback registry access class + /// Skip all the registry access from this process filter mask if it is true. + /// return true if the entry was added successfully + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AddRegistryFilterRule( + uint processNameLength, + [MarshalAs(UnmanagedType.LPWStr)]string processName, + uint processId, + uint userNameLength, + [MarshalAs(UnmanagedType.LPWStr)]string userName, + uint registryKeyNameLength, + [MarshalAs(UnmanagedType.LPWStr)]string registryKeyNameFilterMask, + uint accessFlag, + ulong regCallbackClass, + bool isExcludeFilter, + uint filterRuleId); + + /// + /// Add exclude process name to the registry filter rule. + /// + /// the registry filter rule process name filter mask + /// the registry filter rule registry key filter mask + /// the exclude process name mask + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AddExcludeProcessNameToRegistryFilterRule( + [MarshalAs(UnmanagedType.LPWStr)] string processNameFilterMask, + [MarshalAs(UnmanagedType.LPWStr)] string registryKeyNameFilterMask, + [MarshalAs(UnmanagedType.LPWStr)] string excludeProcessNameMask); + + /// + /// Add exclude user name to the registry filter rule. + /// + /// the registry filter rule process name filter mask + /// the registry filter rule registry key name filter mask + /// the exclude user name mask + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AddExcludeUserNameToRegistryFilterRule( + [MarshalAs(UnmanagedType.LPWStr)] string processNameFilterMask, + [MarshalAs(UnmanagedType.LPWStr)] string registryKeyNameFilterMask, + [MarshalAs(UnmanagedType.LPWStr)] string excludeUserNameMask); + + /// + /// Add exclude key name to the registry filter rule. + /// + /// the registry filter rule process name filter mask + /// the registry filter rule registry key name filter mask + /// the key user name mask + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AddExcludeKeyNameToRegistryFilterRule( + [MarshalAs(UnmanagedType.LPWStr)] string processNameFilterMask, + [MarshalAs(UnmanagedType.LPWStr)] string registryKeyNameFilterMask, + [MarshalAs(UnmanagedType.LPWStr)] string excludeKeyNameMask); + + /// + /// Add registry access control filter entry with process name, if process name filter mask matches the proces, + /// it will set the access flag to the process. + /// + /// The length of the process name string in bytes + /// The process name to be filtered, all processes if it is '*' + /// The access control flag to the registry + /// The registered callback registry access class + /// Skip all the registry access from this process filter mask if it is true. + /// return true if the entry was added successfully + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AddRegistryFilterRuleByProcessName( + uint processNameLength, + [MarshalAs(UnmanagedType.LPWStr)]string processName, + uint accessFlag, + ulong regCallbackClass, + bool isExcludeFilter); + + /// + /// Add registry access control filter entry with processId, if processId matches the proces, + /// it will set the access flag to the process. + /// + /// The process Id to be filtered + /// The access control flag to the registry + /// The registered callback registry access class + /// Skip all the registry access from this process filter mask if it is true. + /// return true if the entry was added successfully + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AddRegistryFilterRuleByProcessId( + uint processId, + uint accessFlag, + ulong regCallbackClass, + bool isExcludeFilter); + + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool RemoveRegistryFilterRuleByProcessId( + uint processId); + + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool RemoveRegistryFilterRuleByProcessName( + uint processNameLength, + [MarshalAs(UnmanagedType.LPWStr)]string processName); + + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool RemoveRegistryFilterRuleByRegKeyName( + uint registryKeyNameLength, + [MarshalAs(UnmanagedType.LPWStr)]string registryKeyName); + + //---------------Registry access control APIs END----------------------------------- + + //---------------Process filter APIs----------------------------------------------- + /// + /// process control flag. + /// + public enum ProcessControlFlag : uint + { + /// + /// deny the new process creation if the flag is on + /// + DENY_NEW_PROCESS_CREATION = 0x00000001, + /// + /// if this flag is enabled, it will send the notification when the new process creation was blocked. + /// + ENABLE_SEND_PROCESS_DENIED_EVENT = 0x00000002, + /// + /// send the callback request before the process is going to be terminated. + /// you can block the process termination in the callback function. + /// + PROCESS_PRE_TERMINATION_REQUEST = 0x00000004, + /// + /// Get a notification when a new process is being created. + /// + PROCESS_CREATION_NOTIFICATION = 0x00000100, + /// + ///get a notification when a process was terminated + /// + PROCESS_TERMINATION_NOTIFICATION = 0x00000200, + /// + /// get a notification for process handle operations, when a handle for a process + /// is being created or duplicated. + /// + PROCESS_HANDLE_OP_NOTIFICATION = 0x00000400, + /// + /// get a notifcation when a new thread is being created. + /// + THREAD_CREATION_NOTIFICATION = 0x00000800, + /// + /// get a notification when a thread was terminated + /// + THREAD_TERMINATION_NOTIFICATION = 0x00001000, + /// + /// get a notification for thread handle operations, when a handle for a thread + /// is being created or duplicated. + /// + THREAD_HANDLE_OP_NOTIFICATION = 0x00002000, + } + + /// + /// Add the process filter entry,get notification of new process/thread creation or termination. + /// prevent the unauthorized excutable binaries from running. + /// + /// the process name mask length + /// the process name mask, i.e. c:\myfolder\*.exe + /// the control flag of the process + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AddProcessFilterRule( + uint processNameMaskLength, + [MarshalAs(UnmanagedType.LPWStr)]string processNameMask, + uint controlFlag, + uint filterRuleId ); + + /// + /// Add exclude process name to the process filter rule. + /// + /// the process filter rule process name filter mask + /// the exclude process name mask + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AddExcludeProcessNameToProcessFilterRule( + [MarshalAs(UnmanagedType.LPWStr)] string processNameMask, + [MarshalAs(UnmanagedType.LPWStr)] string excludeProcessNameMask); + + /// + /// Add exclude user name to the process filter rule. + /// + /// the process filter rule process name filter mask + /// the exclude user name mask + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AddExcludeUserNameToProcessFilterRule( + [MarshalAs(UnmanagedType.LPWStr)] string processNameMask, + [MarshalAs(UnmanagedType.LPWStr)] string excludeUserNameMask); + + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool RemoveProcessFilterRule( + uint processNameMaskLength, + [MarshalAs(UnmanagedType.LPWStr)]string processNameMask); + + /// + /// Add the file control access rights to the process + /// + /// the length of the process name filter mask + /// the process name filter mask + /// the length of the file name filter mask + /// the file name filter mask + /// set the file access control flag if the control filter is enabled + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AddFileControlToProcessByName( + uint processNameMaskLength, + [MarshalAs(UnmanagedType.LPWStr)]string processNameMask, + uint fileNameMaskLength, + [MarshalAs(UnmanagedType.LPWStr)]string fileNameMask, + uint AccessFlag); + + /// + /// Remove the file access rights from the process name + /// + /// + /// + /// + /// + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool RemoveFileControlFromProcessByName( + uint processNameMaskLength, + [MarshalAs(UnmanagedType.LPWStr)]string processNameMask, + uint fileNameMaskLength, + [MarshalAs(UnmanagedType.LPWStr)]string fileNameMask); + + /// + /// register the file callback IO for the process with the filter option. + /// + /// the length of the process name filter mask + /// the process name filter mask + /// the length of the file name filter mask + /// the file name filter mask + /// register the monitor IO callback if the monitor filter driver is enabled + /// register the control IO callback if the control filter driver is enabled + /// the filterRuleId associated to the callback event + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AddFileCallbackIOToProcessByName( + uint processNameMaskLength, + [MarshalAs(UnmanagedType.LPWStr)]string processNameMask, + uint fileNameMaskLength, + [MarshalAs(UnmanagedType.LPWStr)]string fileNameMask, + ulong monitorIO, + ulong controlIO, + uint filterRuleId ); + + /// + /// This is the API to add the file access rights of the specific files to the specific processes by process Id + /// This feature requires the control filter was enabled + /// + /// the process Id it will be filtered + /// the length of the file name filter mask + /// the file name filter mask + /// the file access control flag + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AddFileControlToProcessById( + uint processId, + uint fileNameMaskLength, + [MarshalAs(UnmanagedType.LPWStr)]string fileNameMask, + uint AccessFlag ); + + /// + /// Remove the file access entry by process Id + /// + /// + /// + /// + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool RemoveFileControlFromProcessById( + uint processId, + uint fileNameMaskLength, + [MarshalAs(UnmanagedType.LPWStr)]string fileNameMask); + + /// + /// prevent the process being terminated, only support OS vista or later version. + /// + /// + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AddProtectedProcessId(uint processId); + + /// + /// prevent the process from creating the new file after it opened the protected file. + /// the process can't save the protected file to the other file name. + /// + /// + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AddBlockSaveAsProcessId(uint processId); + + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool RemoveBlockSaveAsProcessId(uint processId); + + /// + /// Get the subject name of the certificate which the process was signed + /// + /// the signed process name + /// the subject name of the certificate + /// the size of the subject name + /// the signed time + /// return true if the process was signed correctly, or return false. + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool GetSignerInfo( + [MarshalAs(UnmanagedType.LPWStr)]string processName, + [MarshalAs(UnmanagedType.LPWStr)]string certificateSubjectName, + ref uint sizeOfCertificateSubjectName, + ref long signedTime); + + //---------------Process filter APIs END----------------------------------------------- + + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool RegisterIoRequest(uint requestRegistration); + + /// + /// Open file bypass the filter driver and security check here. + /// + /// + /// + /// + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool GetFileHandleInFilter( + [MarshalAs(UnmanagedType.LPWStr)]string fileName, + uint dwDesiredAccess, + ref IntPtr fileHandle); + + /// + /// Close the file handle which was opened by GetFileHandleInFilter. + /// + /// + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool CloseFileHandleInFilter( + IntPtr fileHandle); + + [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)] + public static extern bool ConvertSidToStringSid( + [In] IntPtr sid, + [Out] out IntPtr sidString); + + [DllImport("kernel32.dll", SetLastError = true)] + public static extern IntPtr LocalFree(IntPtr hMem); + + [DllImport("kernel32", SetLastError = true)] + public static extern uint GetCurrentProcessId(); + + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool CreateFileAPI( + [MarshalAs(UnmanagedType.LPWStr)]string fileName, + uint dwDesiredAccess, + uint dwShareMode, + uint dwCreationDisposition, + uint dwFlagsAndAttributes, + ref IntPtr fileHandle); + + + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AESEncryptDecryptBuffer( + IntPtr inputBuffer, + IntPtr outputBuffer, + uint bufferLength, + long offset, + byte[] encryptionKey, + uint keyLength, + byte[] iv, + uint ivLength); + + /// + /// Encrypt the file, if addHeader is true then the iv data will be embedded to the encrypted file, + /// or there are no meta data attached. + /// + /// + /// + /// + /// + /// + /// + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AESEncryptFile( + [MarshalAs(UnmanagedType.LPWStr)]string fileName, + uint keyLength, + byte[] encryptionKey, + uint ivLength, + byte[] iv, + bool addHeader); + + /// + /// Encrypt the file, the iv data and the tag data will be embedded to the encrypted file. + /// + /// + /// + /// + /// + /// + /// + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AESEncryptFileWithTag( + [MarshalAs(UnmanagedType.LPWStr)]string fileName, + uint keyLength, + byte[] encryptionKey, + uint ivLength, + byte[] iv, + uint tagDataLength, + byte[] tagData); + + /// + /// Encrypt the source file to the dest file, if addIVTag is true then the iv data will be embedded to the encrypted file, + /// or there are no meta data attached. + /// + /// + /// + /// + /// + /// + /// + /// + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AESEncryptFileToFile( + [MarshalAs(UnmanagedType.LPWStr)]string sourceFileName, + [MarshalAs(UnmanagedType.LPWStr)]string destFileName, + uint keyLength, + byte[] encryptionKey, + uint ivLength, + byte[] iv, + bool addIVTag); + + /// + /// Encrypt the source file to the dest file, the iv data and the tag data will be embedded to the encrypted file. + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AESEncryptFileToFileWithTag( + [MarshalAs(UnmanagedType.LPWStr)]string sourceFileName, + [MarshalAs(UnmanagedType.LPWStr)]string destFileName, + uint keyLength, + byte[] encryptionKey, + uint ivLength, + byte[] iv, + uint tagDataLength, + byte[] tagData); + + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AESDecryptFile( + [MarshalAs(UnmanagedType.LPWStr)]string fileName, + uint keyLength, + byte[] encryptionKey, + uint ivLength, + byte[] iv); + + + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AESDecryptFileToFile( + [MarshalAs(UnmanagedType.LPWStr)]string sourceFileName, + [MarshalAs(UnmanagedType.LPWStr)]string destFileName, + uint keyLength, + byte[] encryptionKey, + uint ivLength, + byte[] iv); + + /// + /// Decrypt the encrypted file at offset and length to a buffer array. + /// + /// The encrypted file name + /// the number of the bytes of the encryption key + /// the encryption key byte array + /// the lenght of the iv key, set it to 0 if the AES header was embedded. + /// the iv key, set it to null if the AES header was embedded. + /// the offset which the decryption will start + /// the number of bytes to decrypt + /// the decrypted buffer array to receive the decrypted data, + /// the buffer size must be greater or equal than the bytesToDecrypt + /// the length of the return decrytped buffer + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool AESDecryptBytes( + [MarshalAs(UnmanagedType.LPWStr)]string encryptedFileName, + uint keyLength, + byte[] encryptionKey, + uint ivLength, + byte[] iv, + long offset, + int bytesToDecrypt, + byte[] decryptedBuffer, + ref int bytesDecrypted); + + + /// + /// Set the AESFlags and AccessFlags in the AES header + /// + /// + /// + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool SetHeaderFlags( + [MarshalAs(UnmanagedType.LPWStr)]string fileName, + uint aesFlags, + uint accessFlags ); + + /// + /// Get the tag data which was set in the AES header + /// + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool GetAESTagData( + [MarshalAs(UnmanagedType.LPWStr)]string fileName, + ref uint tagDataSize, + byte[] tagData); + + /// + /// Get the IV data from an encrypted file's header + /// + /// the encrypted file name + /// the pass in/out iv buffer size + /// the iv buffer + /// return true if it gets the right iv data + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern bool GetAESIV( + [MarshalAs(UnmanagedType.LPWStr)]string fileName, + ref uint ivSize, + byte[] ivBuffer); + + /// + /// Get the computerId + /// + /// + [DllImport("FilterAPI.dll", SetLastError = true)] + public static extern uint GetComputerId(); + + + public static string GetLastErrorMessage() + { + int len = 1024; + string lastError = new string((char)0, len); + + if (!GetLastErrorMessage(lastError, ref len)) + { + lastError = new string((char)0, len); + if (!GetLastErrorMessage(lastError, ref len)) + { + return "failed to get last error message."; + } + } + + if (lastError.IndexOf((char)0) >= 0) + { + lastError = lastError.Substring(0, lastError.IndexOf((char)0)); + } + + return lastError; + } + + } +} diff --git a/Demo_Source_Code/CSharpDemo/FilterControl/FilterComponent.cs b/Demo_Source_Code/CSharpDemo/FilterControl/FilterComponent.cs new file mode 100644 index 0000000..6502932 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FilterControl/FilterComponent.cs @@ -0,0 +1,936 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.Text; +using System.IO; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.Runtime.InteropServices; + +namespace EaseFilter.FilterControl +{ + + public partial class FilterControl + { + //The FilterControl is the component to communicate with the filter driver. + //With this control, you can start or stop the filter service, setup the global configuration setting, and handle the filter callback request. + //To start the file I/O, process and registry monitoring and protection, you need to add the filter rule to the FilterControl. + //To monitor or control the file I/O, you can add the file filter rule which includes the monitor filter, control filter and encryption filter to the FilterControl. + //To monitor or control the process operation, you can add the process filter rule to the FilterControl. + //To monitor or control the registry access, you can add the registry filter rule to the FilterControl. + + delegate Boolean FilterDelegate(IntPtr sendData, IntPtr replyData); + delegate void DisconnectDelegate(); + GCHandle gchFilter; + GCHandle gchDisconnect; + + public static bool IsStarted = false; + static bool isFilterStarted = false; + + uint globalFilterId = 1; + + int filterConnectionThreads = 5; + int connectionTimeout = 10; + FilterAPI.FilterType filterType = FilterAPI.FilterType.MONITOR_FILTER; + + Dictionary filterRuleList = new Dictionary(); + List protectedProcessIdList = new List(); + List includeProcessIdList = new List(); + List excludeProcessIdList = new List(); + + public static string licenseKey = string.Empty; + + public FilterControl() + { + } + + + /// + /// The global boolean config setting + /// + public uint BooleanConfig { get; set; } + /// + /// The volume control flag, reference FilterAPI.VolumeControlFlag + /// + public FilterAPI.VolumeControlFlag VolumeControlFlag { get; set; } + /// + /// The global registered callback IO + /// + public uint RegisterCallbackIo { get; set; } + /// + /// The protected process Id list, prevent the processes from being terminiated. + /// + public List ProtectedProcessIdList + { + get { return protectedProcessIdList; } + set { protectedProcessIdList = value; } + } + /// + /// The global include process Id list, only IO from the process in the list will be managed by the filter driver. + /// + public List IncludeProcessIdList + { + get { return includeProcessIdList; } + set { includeProcessIdList = value; } + } + /// + /// The global exclude process Id list, skip all the IOs from the exclude process id list. + /// + public List ExcludeProcessIdList + { + get { return excludeProcessIdList; } + set { excludeProcessIdList = value; } + } + + + /// + /// Fires this event when the filter driver attached to a new volume or you get attached volume information. + /// + public event EventHandler NotifyFilterAttachToVolume; + /// + /// fires this event when a volume detached from a filter driver. + /// + public event EventHandler NotifyFilterDetachFromVolume; + /// + /// fires this event when the file IO was blocked by the access flag control setting when the SendDeniedFileIOEvent was true. + /// + public event EventHandler NotifiyFileIOWasBlocked; + /// + /// fires this event when the read from USB was blocked. + /// + public event EventHandler NotifyUSBReadWasBlocked; + /// + /// fires this event when the write to USB was blocked. + /// + public event EventHandler NotifyUSBWriteWasBlocked; + /// + /// fires this event when the process was terminated ungratefully was blocked. + /// + public event EventHandler NotifiyProcessTerminatedWasBlocked; + + /// + /// Start the filter driver service. + /// + /// + /// + /// + /// + /// + public bool StartFilter(FilterAPI.FilterType _filterType, int _filterConnectionThreads, int _connectionTimeout, string _licenseKey, ref string lastError) + { + + bool ret = true; + FilterDelegate filterCallback = new FilterDelegate(FilterRequestHandler); + DisconnectDelegate disconnectCallback = new DisconnectDelegate(DisconnectCallback); + + try + { + filterType = _filterType; + filterConnectionThreads = _filterConnectionThreads; + connectionTimeout = _connectionTimeout; + licenseKey = _licenseKey; + + //copy the right binary(EaseFlt.sys,FilterAPI.DLL) to the local executable binary folder. + Utils.CopyOSPlatformDependentFiles(ref lastError); + + if (Utils.IsDriverChanged()) + { + //uninstall or install driver needs the Admin permission. + FilterAPI.UnInstallDriver(); + + //wait for 3 seconds for the uninstallation completed. + System.Threading.Thread.Sleep(3000); + } + + if (!FilterAPI.IsDriverServiceRunning()) + { + ret = FilterAPI.InstallDriver(); + if (!ret) + { + lastError = "Installed driver failed with error:" + FilterAPI.GetLastErrorMessage(); + return false; + } + } + + + if (!isFilterStarted) + { + + if (!FilterAPI.SetRegistrationKey(licenseKey)) + { + lastError = "Set license key failed with error:" + FilterAPI.GetLastErrorMessage(); + return false; + } + + gchFilter = GCHandle.Alloc(filterCallback); + IntPtr filterCallbackPtr = Marshal.GetFunctionPointerForDelegate(filterCallback); + + gchDisconnect = GCHandle.Alloc(disconnectCallback); + IntPtr disconnectCallbackPtr = Marshal.GetFunctionPointerForDelegate(disconnectCallback); + + isFilterStarted = FilterAPI.RegisterMessageCallback(filterConnectionThreads, filterCallbackPtr, disconnectCallbackPtr); + if (!isFilterStarted) + { + lastError = "Connect to the filter driver failed with error:" + FilterAPI.GetLastErrorMessage(); + return false; + } + + ret = true; + + IsStarted = true; + + } + } + catch (Exception ex) + { + ret = false; + lastError = "Start filter failed with error " + ex.Message; + } + finally + { + if (!ret) + { + lastError = lastError + " Make sure you run this application as administrator."; + } + + } + + return ret; + } + + /// + ///The filter driver service is started if it is true. + /// + public bool IsFilterStarted + { + get { return isFilterStarted; } + } + + /// + /// Stop the filter driver service. + /// + public void StopFilter() + { + if (isFilterStarted) + { + FilterAPI.Disconnect(); + gchFilter.Free(); + gchDisconnect.Free(); + isFilterStarted = false; + } + + return; + } + + /// + /// Add the filter rule to the filter driver. + /// + /// + public void AddFilter(Filter filter) + { + lock (filterRuleList) + { + if (filter.FilterId > 0 && filterRuleList.ContainsKey(filter.FilterId)) + { + filterRuleList.Remove(filter.FilterId); + } + + filter.FilterId = globalFilterId++; + filterRuleList.Add(filter.FilterId, filter); + } + } + + /// + ///Remove the filter rule from the filter driver. + /// + /// + public void RemoveFilter(Filter filter) + { + lock (filterRuleList) + { + if (filterRuleList.ContainsKey(filter.FilterId)) + { + filterRuleList.Remove(filter.FilterId); + } + } + } + + /// + /// Clear all registered filters + /// + public void ClearFilters() + { + lock (filterRuleList) + { + filterRuleList.Clear(); + } + } + + /// + /// Install the filter driver service. + /// + /// + /// + public bool InstallDriver(ref string lastError) + { + if (!FilterAPI.InstallDriver()) + { + lastError = "Installed driver failed with error:" + FilterAPI.GetLastErrorMessage(); + return false; + } + + return true; + } + + /// + /// Uninstall the filter driver service. + /// + /// + /// + public bool UnInstallDriver(ref string lastError) + { + if (!FilterAPI.UnInstallDriver()) + { + lastError = "UnInstallDriver failed with error:" + FilterAPI.GetLastErrorMessage(); + return false; + } + + return true; + } + + public bool ResetConfigData(ref string lastError) + { + if (!FilterAPI.ResetConfigData()) + { + lastError = "ResetConfigData failed:" + FilterAPI.GetLastErrorMessage(); + return false; + } + + return true; + } + + public bool SendConfigSettingsToFilter(ref string lastError) + { + try + { + if (!isFilterStarted) + { + lastError = "the filter driver is not started."; + return true; + } + + if (!FilterAPI.ResetConfigData()) + { + lastError = "ResetConfigData failed:" + FilterAPI.GetLastErrorMessage(); + return false; + } + + if (!FilterAPI.SetConnectionTimeout((uint)connectionTimeout)) + { + lastError = "SetConnectionTimeout failed:" + FilterAPI.GetLastErrorMessage(); + return false; + } + + if (!FilterAPI.SetFilterType((uint)filterType)) + { + lastError = "SetFilterType " + filterType.ToString() + " failed:" + FilterAPI.GetLastErrorMessage(); + return false; + } + + if (BooleanConfig > 0 && !FilterAPI.SetBooleanConfig(BooleanConfig)) + { + lastError = "SetBooleanConfig " + BooleanConfig + " failed:" + FilterAPI.GetLastErrorMessage(); + return false; + } + + if (VolumeControlFlag > 0 && !FilterAPI.SetVolumeControlFlag((uint)VolumeControlFlag)) + { + lastError = "SetVolumeControlFlag " + VolumeControlFlag + " failed:" + FilterAPI.GetLastErrorMessage(); + return false; + } + + + foreach (uint includedPid in IncludeProcessIdList) + { + if (!FilterAPI.AddIncludedProcessId(includedPid)) + { + lastError = "AddIncludedProcessId " + includedPid + " failed:" + FilterAPI.GetLastErrorMessage(); + return false; + } + } + + foreach (uint excludedPid in ExcludeProcessIdList) + { + if (!FilterAPI.AddExcludedProcessId(excludedPid)) + { + lastError = "AddExcludedProcessId " + excludedPid + " failed:" + FilterAPI.GetLastErrorMessage(); + return false; + } + } + + if (RegisterCallbackIo > 0 && !FilterAPI.RegisterIoRequest(RegisterCallbackIo)) + { + lastError = "RegisterIoRequest " + RegisterCallbackIo + " failed:" + FilterAPI.GetLastErrorMessage(); + return false; + } + + foreach (uint protectPid in ProtectedProcessIdList) + { + if (!FilterAPI.AddProtectedProcessId(protectPid)) + { + lastError = "AddProtectedProcessId " + protectPid + " failed:" + FilterAPI.GetLastErrorMessage(); + return false; + } + } + + + foreach (Filter filter in filterRuleList.Values) + { + if (filter.FilterType == FilterAPI.FilterType.PROCESS_FILTER) + { + // + //Process filter driver config settings here. + // + ProcessFilter processFilter = (ProcessFilter)filter; + + if (processFilter.ProcessNameFilterMask.Length > 0) + { + //set the process control flag for the process filter mask. + if (!FilterAPI.AddProcessFilterRule((uint)processFilter.ProcessNameFilterMask.Length * 2, processFilter.ProcessNameFilterMask, processFilter.ControlFlag, processFilter.FilterId)) + { + lastError = "AddProcessFilterRule " + processFilter.ProcessNameFilterMask + " failed:" + FilterAPI.GetLastErrorMessage(); + return false; + } + } + + foreach (string excludeProcessName in processFilter.ExcludeProcessNameList) + { + if (excludeProcessName.Trim().Length > 0) + { + if (!FilterAPI.AddExcludeProcessNameToProcessFilterRule(processFilter.ProcessNameFilterMask, excludeProcessName.Trim())) + { + lastError = "AddExcludeProcessNameToProcessFilterRule " + excludeProcessName + " failed:" + FilterAPI.GetLastErrorMessage(); + return false; + } + } + } + + foreach (string excludeUserName in processFilter.ExcludeUserNameList) + { + if (excludeUserName.Trim().Length > 0) + { + if (!FilterAPI.AddExcludeUserNameToProcessFilterRule(processFilter.ProcessNameFilterMask, excludeUserName.Trim())) + { + lastError = "AddExcludeUserNameToProcessFilterRule " + excludeUserName + " failed:" + FilterAPI.GetLastErrorMessage(); + return false; + } + } + } + + + foreach (KeyValuePair entry in processFilter.FileAccessRights) + { + string fileNameMask = entry.Key; + uint accessFlag = entry.Value; + + if (processFilter.ProcessId > 0) + { + //filter by process Id + if (!FilterAPI.AddFileControlToProcessById(processFilter.ProcessId, (uint)fileNameMask.Length * 2, fileNameMask.Trim(), accessFlag)) + { + lastError = "AddFileControlToProcessById fileNameMask:" + fileNameMask + ",accessFlags:" + accessFlag + " failed:" + FilterAPI.GetLastErrorMessage(); + return false; + } + } + else if (processFilter.ProcessNameFilterMask.Length > 0) + { + //add file access control with process name + if (!FilterAPI.AddFileControlToProcessByName((uint)processFilter.ProcessNameFilterMask.Length * 2, + processFilter.ProcessNameFilterMask, (uint)fileNameMask.Length * 2, fileNameMask.Trim(), accessFlag)) + { + lastError = "AddFileControlToProcessByName " + processFilter.ProcessNameFilterMask + ",fileNameMask:" + fileNameMask + ",accessFlags:" + accessFlag + " failed:" + FilterAPI.GetLastErrorMessage(); + return false; + } + + if (processFilter.MonitorFileIOEventFilter > 0 || processFilter.ControlFileIOEventFilter > 0) + { + ulong registerMonitorIOToFilter = processFilter.MonitorFileIOEventFilter; + ulong registerControlIOToFilter = processFilter.ControlFileIOEventFilter; + + if (!FilterAPI.AddFileCallbackIOToProcessByName((uint)processFilter.ProcessNameFilterMask.Length * 2, + processFilter.ProcessNameFilterMask, (uint)fileNameMask.Length * 2, fileNameMask.Trim(), registerMonitorIOToFilter, registerControlIOToFilter, processFilter.FilterId)) + { + lastError = "AddFileControlToProcessByName failed:" + FilterAPI.GetLastErrorMessage(); + return false; + } + } + } + } + } + else if (filter.FilterType == FilterAPI.FilterType.REGISTRY_FILTER) + { + // + //Registry filter driver config setting + // + RegistryFilter registryFilter = (RegistryFilter)filter; + + if (!FilterAPI.AddRegistryFilterRule((uint)registryFilter.ProcessNameFilterMask.Length * 2, registryFilter.ProcessNameFilterMask, registryFilter.ProcessId, + (uint)registryFilter.UserName.Length * 2, registryFilter.UserName, (uint)registryFilter.RegistryKeyNameFilterMask.Length * 2, registryFilter.RegistryKeyNameFilterMask, + registryFilter.ControlFlag, registryFilter.RegCallbackClass, registryFilter.IsExcludeFilter, registryFilter.FilterId)) + { + lastError = "AddRegistryFilterRule failed:" + FilterAPI.GetLastErrorMessage(); + return false; + } + + foreach (string excludeProcessName in registryFilter.ExcludeProcessNameList) + { + if (excludeProcessName.Trim().Length > 0) + { + if (!FilterAPI.AddExcludeProcessNameToRegistryFilterRule( + registryFilter.ProcessNameFilterMask,registryFilter.RegistryKeyNameFilterMask, excludeProcessName.Trim())) + { + lastError = "AddExcludeProcessNameToRegistryFilterRule " + excludeProcessName + " failed:" + FilterAPI.GetLastErrorMessage(); + return false; + } + } + } + + foreach (string excludeUserName in registryFilter.ExcludeUserNameList) + { + if (excludeUserName.Trim().Length > 0) + { + if (!FilterAPI.AddExcludeUserNameToRegistryFilterRule( + registryFilter.ProcessNameFilterMask, registryFilter.RegistryKeyNameFilterMask, excludeUserName.Trim())) + { + lastError = "AddExcludeUserNameToRegistryFilterRule " + excludeUserName + " failed:" + FilterAPI.GetLastErrorMessage(); + return false; + } + } + } + + foreach (string excludeKeyName in registryFilter.ExcludeKeyNameList) + { + if (excludeKeyName.Trim().Length > 0) + { + if (!FilterAPI.AddExcludeKeyNameToRegistryFilterRule( + registryFilter.ProcessNameFilterMask, registryFilter.RegistryKeyNameFilterMask, excludeKeyName.Trim())) + { + lastError = "AddExcludeKeyNameToRegistryFilterRule " + excludeKeyName + " failed:" + FilterAPI.GetLastErrorMessage(); + return false; + } + } + } + + } + else //this is file filter. + { + + FileFilter fileFilter = (FileFilter)filter; + + //add filter rule to filter driver here, the filter rule is unique with the include file filter mask. + //you can't have the mutiple filter rules with the same include file filter mask,if there are the same + //one exist, the new one with accessFlag will overwrite the old accessFlag. + //for control filter, if isResident is true, the access control will be enabled in boot time. + if (!FilterAPI.AddFileFilterRule((uint)fileFilter.AccessFlags, fileFilter.IncludeFileFilterMask, fileFilter.IsResident, fileFilter.FilterId)) + { + lastError = "Send filter rule failed:" + FilterAPI.GetLastErrorMessage(); + return false; + } + + if (fileFilter.FileChangeEventFilter > 0 && !FilterAPI.RegisterFileChangedEventsToFilterRule(fileFilter.IncludeFileFilterMask, (uint)fileFilter.FileChangeEventFilter)) + { + lastError = "Register file event type:" + fileFilter.FileChangeEventFilter + " failed:" + FilterAPI.GetLastErrorMessage(); + return false; + } + + if (fileFilter.MonitorFileIOEventFilter > 0 && !FilterAPI.RegisterMonitorIOToFilterRule(fileFilter.IncludeFileFilterMask, fileFilter.MonitorFileIOEventFilter)) + { + lastError = "Register monitor IO:" + fileFilter.MonitorFileIOEventFilter.ToString("X") + " failed:" + FilterAPI.GetLastErrorMessage(); + return false; + } + + if (fileFilter.ControlFileIOEventFilter > 0 && !FilterAPI.RegisterControlIOToFilterRule(fileFilter.IncludeFileFilterMask, fileFilter.ControlFileIOEventFilter)) + { + lastError = "Register control IO:" + fileFilter.ControlFileIOEventFilter.ToString("X") + " failed:" + FilterAPI.GetLastErrorMessage(); + return false; + } + + if (fileFilter.FilterDesiredAccess > 0 || fileFilter.FilterDisposition > 0 || fileFilter.FilterCreateOptions > 0) + { + if (!FilterAPI.AddCreateFilterToFilterRule(fileFilter.IncludeFileFilterMask, fileFilter.FilterDesiredAccess, fileFilter.FilterDisposition, fileFilter.FilterCreateOptions)) + { + lastError = "AddCreateFilterToFilterRule failed:" + FilterAPI.GetLastErrorMessage(); + return false; + } + } + + //every filter rule can have multiple exclude file filter masks, you can exclude the files + //which matches the exclude filter mask. + foreach (string excludeFilterMask in fileFilter.ExcludeFileFilterMaskList) + { + if (excludeFilterMask.Trim().Length > 0) + { + if (!FilterAPI.AddExcludeFileMaskToFilterRule(fileFilter.IncludeFileFilterMask, excludeFilterMask.Trim())) + { + lastError = "AddExcludeFileMaskToFilterRule " + excludeFilterMask + " failed:" + FilterAPI.GetLastErrorMessage(); + return false; + } + } + } + + + if (fileFilter.EnableEncryption) + { + if (null != fileFilter.EncryptionKey && fileFilter.EncryptionKey.Length > 0) + { + if (null != fileFilter.EncryptionIV && fileFilter.EncryptionIV.Length > 0) + { + if (!FilterAPI.AddEncryptionKeyAndIVToFilterRule(fileFilter.IncludeFileFilterMask, (uint)fileFilter.EncryptionKey.Length, fileFilter.EncryptionKey, (uint)fileFilter.EncryptionIV.Length, fileFilter.EncryptionIV)) + { + lastError = "AddEncryptionKeyAndIVToFilterRule " + fileFilter.IncludeFileFilterMask + " failed:" + FilterAPI.GetLastErrorMessage(); + return false; + } + } + else + { + if (!FilterAPI.AddEncryptionKeyToFilterRule(fileFilter.IncludeFileFilterMask, (uint)fileFilter.EncryptionKey.Length, fileFilter.EncryptionKey)) + { + lastError = "AddEncryptionKeyToFilterRule " + fileFilter.IncludeFileFilterMask + " failed:" + FilterAPI.GetLastErrorMessage(); + return false; + } + } + } + + if (fileFilter.EncryptWriteBufferSize > 0) + { + if (!FilterAPI.SetEncryptWriteBufferSize(fileFilter.EncryptWriteBufferSize)) + { + lastError = "SetEncryptWriteBufferSize " + fileFilter.EncryptWriteBufferSize + " failed:" + FilterAPI.GetLastErrorMessage(); + return false; + } + } + + } + + if (fileFilter.BooleanConfig > 0 && !FilterAPI.AddBooleanConfigToFilterRule(fileFilter.IncludeFileFilterMask, fileFilter.BooleanConfig)) + { + lastError = "AddBooleanConfigToFilterRule " + fileFilter.IncludeFileFilterMask + " failed:" + FilterAPI.GetLastErrorMessage(); + return false; + } + + if (fileFilter.EnableMonitorEventBuffer && (fileFilter.MaxMonitorEventBufferSize > 0) + && !FilterAPI.SetMaxMonitorEventBuffersize((uint)fileFilter.MaxMonitorEventBufferSize)) + { + lastError = "SetMaxMonitorEventBuffersize " + fileFilter.MaxMonitorEventBufferSize + " failed:" + FilterAPI.GetLastErrorMessage(); + return false; + } + + + foreach (string includeProcessName in fileFilter.IncludeProcessNameList) + { + if (includeProcessName.Trim().Length > 0) + { + if (!FilterAPI.AddIncludeProcessNameToFilterRule(fileFilter.IncludeFileFilterMask, includeProcessName.Trim())) + { + lastError = "AddIncludeProcessNameToFilterRule " + includeProcessName + " failed:" + FilterAPI.GetLastErrorMessage(); + return false; + } + } + } + + foreach (string excludeProcessName in fileFilter.ExcludeProcessNameList) + { + if (excludeProcessName.Trim().Length > 0) + { + if (!FilterAPI.AddExcludeProcessNameToFilterRule(fileFilter.IncludeFileFilterMask, excludeProcessName.Trim())) + { + lastError = "AddExcludeProcessNameToFilterRule " + excludeProcessName + " failed:" + FilterAPI.GetLastErrorMessage(); + return false; + } + } + } + + //set include process list for this filter rule. + foreach (uint pid in fileFilter.IncludeProcessIdList) + { + if (!FilterAPI.AddIncludeProcessIdToFilterRule(fileFilter.IncludeFileFilterMask, pid)) + { + lastError = "AddIncludeProcessIdToFilterRule " + fileFilter.IncludeFileFilterMask + " PID:" + pid + " failed:" + FilterAPI.GetLastErrorMessage(); + return false; + } + } + + //set exclude process list for this filter rule. + foreach (uint pid in fileFilter.ExcludeProcessIdList) + { + if (!FilterAPI.AddExcludeProcessIdToFilterRule(fileFilter.IncludeFileFilterMask, pid)) + { + lastError = "AddExcludeProcessIdToFilterRule " + fileFilter.IncludeFileFilterMask + " PID:" + pid + " failed:" + FilterAPI.GetLastErrorMessage(); + return false; + } + + } + + foreach (string includeUserName in fileFilter.IncludeUserNameList) + { + if (includeUserName.Trim().Length > 0) + { + if (!FilterAPI.AddIncludeUserNameToFilterRule(fileFilter.IncludeFileFilterMask, includeUserName.Trim())) + { + lastError = "AddIncludeUserNameToFilterRule " + includeUserName + " failed:" + FilterAPI.GetLastErrorMessage(); + return false; + } + } + } + + foreach (string excludeUserName in fileFilter.ExcludeUserNameList) + { + if (excludeUserName.Trim().Length > 0) + { + if (!FilterAPI.AddExcludeUserNameToFilterRule(fileFilter.IncludeFileFilterMask, excludeUserName.Trim())) + { + lastError = "AddExcludeUserNameToFilterRule " + excludeUserName + " failed:" + FilterAPI.GetLastErrorMessage(); + return false; + } + } + } + + foreach (KeyValuePair entry in fileFilter.ProcessNameAccessRightList) + { + string processName = entry.Key; + uint accessFlags = entry.Value; + + if (!FilterAPI.AddProcessRightsToFilterRule(fileFilter.IncludeFileFilterMask, processName.Trim(), accessFlags)) + { + lastError = "AddProcessRightsToFilterRule " + fileFilter.IncludeFileFilterMask + ",processName:" + processName + ",accessFlags:" + accessFlags + " failed:" + FilterAPI.GetLastErrorMessage(); + return false; + } + } + + foreach (KeyValuePair entry in fileFilter.Sha256ProcessAccessRightList) + { + byte[] processSha256 = entry.Key; + uint accessFlags = entry.Value; + + if (!FilterAPI.AddSha256ProcessAccessRightsToFilterRule(fileFilter.IncludeFileFilterMask, processSha256, (uint)processSha256.Length, accessFlags)) + { + lastError = "AddProcessSha256RightsToFilterRule " + fileFilter.IncludeFileFilterMask + ",accessFlags:" + accessFlags + " failed:" + FilterAPI.GetLastErrorMessage(); + return false; + } + } + + foreach (KeyValuePair entry in fileFilter.SignedProcessAccessRightList) + { + string certificateName = entry.Key; + uint accessFlags = entry.Value; + + if (!FilterAPI.AddSignedProcessAccessRightsToFilterRule(fileFilter.IncludeFileFilterMask, certificateName.Trim(),(uint)certificateName.Length*2, accessFlags)) + { + lastError = "AddSignedProcessAccessRightsToFilterRule " + fileFilter.IncludeFileFilterMask + ",certificateName:" + certificateName + ",accessFlags:" + accessFlags + " failed:" + FilterAPI.GetLastErrorMessage(); + return false; + } + } + + + foreach (KeyValuePair entry in fileFilter.ProcessIdAccessRightList) + { + uint processId = entry.Key; + uint accessFlags = entry.Value; + + if (!FilterAPI.AddProcessIdRightsToFilterRule(fileFilter.IncludeFileFilterMask, processId, accessFlags)) + { + lastError = "AddProcessIdRightsToFilterRule " + fileFilter.IncludeFileFilterMask + ",processId:" + processId + ",accessFlags:" + accessFlags + " failed:" + FilterAPI.GetLastErrorMessage(); + return false; + } + } + + foreach (KeyValuePair entry in fileFilter.userAccessRightList) + { + string userName = entry.Key; + uint accessFlags = entry.Value; + + if (!FilterAPI.AddUserRightsToFilterRule(fileFilter.IncludeFileFilterMask, userName.Trim(), accessFlags)) + { + lastError = "AddUserRightsToFilterRule " + fileFilter.IncludeFileFilterMask + ",userName:" + userName + ",accessFlags:" + accessFlags + " failed:" + FilterAPI.GetLastErrorMessage(); + return false; + } + } + + //Hide the files which match the hidden file filter masks when the user browse the managed directory. + if (fileFilter.EnableHiddenFile) + { + foreach (string hiddenFilterMask in fileFilter.HiddenFileFilterMaskList) + { + if (hiddenFilterMask.Trim().Length > 0) + { + if (!FilterAPI.AddHiddenFileMaskToFilterRule(fileFilter.IncludeFileFilterMask, hiddenFilterMask.Trim())) + { + lastError = "AddHiddenFileMaskToFilterRule " + fileFilter.IncludeFileFilterMask + " hiddenFilterMask:" + hiddenFilterMask + " failed:" + FilterAPI.GetLastErrorMessage(); + return false; + } + } + } + } + + //reparse the file open to another file with the filter mask. + //For example: + //FilterMask = c:\test\*txt + //ReparseFilterMask = d:\reparse\*doc + //If you open file c:\test\MyTest.txt, it will reparse to the file d:\reparse\MyTest.doc. + if (fileFilter.EnableReparseFile && fileFilter.ReparseFileFilterMask.Trim().Length > 0) + { + string reparseFileFilterMask = fileFilter.ReparseFileFilterMask; + if (!FilterAPI.AddReparseFileMaskToFilterRule(fileFilter.IncludeFileFilterMask, reparseFileFilterMask.Trim())) + { + lastError = "AddReparseFileMaskToFilterRule " + fileFilter.IncludeFileFilterMask + " reparseFileFilterMask:" + reparseFileFilterMask + " failed:" + FilterAPI.GetLastErrorMessage(); + return false; + } + + } + + } + } + } + catch (Exception ex) + { + lastError = "Send config settings to filter failed with error " + ex.Message; + return false; + } + + return true; + } + + /// + /// Handle the requests from the filter driver, process the notification if no return needed, + /// or reply the message back to the filter which the filter driver is wating for. + /// + /// + /// + /// + Boolean FilterRequestHandler(IntPtr sendDataPtr, IntPtr replyDataPtr) + { + Boolean ret = true; + + try + { + + FilterAPI.MessageSendData messageSend = (FilterAPI.MessageSendData)Marshal.PtrToStructure(sendDataPtr, typeof(FilterAPI.MessageSendData)); + + if (FilterAPI.MESSAGE_SEND_VERIFICATION_NUMBER != messageSend.VerificationNumber) + { + //Received message corrupted.Please check if the MessageSendData structure is correct. + return false; + } + + if (messageSend.FilterCommand == (uint)FilterAPI.FilterCommand.FILTER_SEND_ATTACHED_VOLUME_INFO) + { + if (null != NotifyFilterAttachToVolume) + { + VolumeInfoEventArgs volumeArgs = new VolumeInfoEventArgs(messageSend); + volumeArgs.EventName = "VolumeAttached"; + NotifyFilterAttachToVolume(null, volumeArgs); + } + } + else if (messageSend.FilterCommand == (uint)FilterAPI.FilterCommand.FILTER_SEND_DETACHED_VOLUME_INFO) + { + if (null != NotifyFilterDetachFromVolume) + { + VolumeInfoEventArgs volumeArgs = new VolumeInfoEventArgs(messageSend); + volumeArgs.EventName = "VolumeDetached"; + NotifyFilterDetachFromVolume(null, volumeArgs); + } + } + else if (messageSend.FilterCommand == (uint)FilterAPI.FilterCommand.FILTER_SEND_DENIED_VOLUME_DISMOUNT_EVENT) + { + if (null != NotifyFilterDetachFromVolume) + { + VolumeInfoEventArgs volumeArgs = new VolumeInfoEventArgs(messageSend); + volumeArgs.EventName = "VolumeDismountWasBlocked"; + NotifyFilterDetachFromVolume(null, volumeArgs); + } + } + else if (messageSend.FilterCommand == (uint)FilterAPI.FilterCommand.FILTER_SEND_DENIED_FILE_IO_EVENT) + { + if (null != NotifiyFileIOWasBlocked) + { + DeniedFileIOEventArgs deniedIOEventArgs = new DeniedFileIOEventArgs(messageSend); + NotifiyFileIOWasBlocked(null, deniedIOEventArgs); + } + } + else if (messageSend.FilterCommand == (uint)FilterAPI.FilterCommand.FILTER_SEND_DENIED_USB_READ_EVENT) + { + if (null != NotifyUSBReadWasBlocked) + { + DeniedUSBReadEventArgs deniedIOEventArgs = new DeniedUSBReadEventArgs(messageSend); + NotifyUSBReadWasBlocked(null, deniedIOEventArgs); + } + } + else if (messageSend.FilterCommand == (uint)FilterAPI.FilterCommand.FILTER_SEND_DENIED_USB_WRITE_EVENT) + { + if (null != NotifyUSBWriteWasBlocked) + { + DeniedUSBWriteEventArgs deniedIOEventArgs = new DeniedUSBWriteEventArgs(messageSend); + NotifyUSBWriteWasBlocked(null, deniedIOEventArgs); + } + } + else if (messageSend.FilterCommand == (uint)FilterAPI.FilterCommand.FILTER_SEND_DENIED_PROCESS_TERMINATED_EVENT) + { + if (null != NotifiyProcessTerminatedWasBlocked) + { + DeniedProcessTerminatedEventArgs deniedProcessEventArgs = new DeniedProcessTerminatedEventArgs(messageSend); + NotifiyProcessTerminatedWasBlocked(null, deniedProcessEventArgs); + } + } + else if (filterRuleList.ContainsKey(messageSend.FilterRuleId)) + { + Filter registerFilter = filterRuleList[messageSend.FilterRuleId]; + + if (replyDataPtr.ToInt64() == 0) + { + registerFilter.SendNotification(messageSend); + } + else + { + ret = registerFilter.ReplyMessage(messageSend, replyDataPtr); + } + + } + else + { + Console.WriteLine("There are no handler for the filter command." + messageSend.FilterCommand.ToString("X") + ",filterRuleId:" + messageSend.FilterRuleId + + ",messageType:" + messageSend.MessageType.ToString("X") + ",fileName:" + messageSend.FileName); + } + + return ret; + } + catch (Exception ex) + { + //EventManager.WriteMessage(134, "FilterCallback", EventLevel.Error, "filter callback exception." + ex.Message); + Utils.ToDebugger("filter callback exception." + ex.Message); + return false; + } + + } + + void DisconnectCallback() + { + return; + } + } +} diff --git a/Demo_Source_Code/CSharpDemo/FilterControl/FilterControl.csproj b/Demo_Source_Code/CSharpDemo/FilterControl/FilterControl.csproj new file mode 100644 index 0000000..6700561 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FilterControl/FilterControl.csproj @@ -0,0 +1,72 @@ + + + + Debug + AnyCPU + 8.0.30703 + 2.0 + {21540012-A296-45CE-8D35-3EA5A07B32A6} + Library + Properties + EaseFilter.FilterControl + FilterControl + v4.5 + 512 + SAK + SAK + SAK + SAK + + + + true + full + false + ..\..\Release\ + DEBUG;TRACE + prompt + 4 + false + + + pdbonly + true + ..\..\Release\ + TRACE + prompt + 4 + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/FilterControl/FilterControl.vs2019.csproj b/Demo_Source_Code/CSharpDemo/FilterControl/FilterControl.vs2019.csproj new file mode 100644 index 0000000..fae497a --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FilterControl/FilterControl.vs2019.csproj @@ -0,0 +1,90 @@ + + + + Debug + AnyCPU + 8.0.30703 + 2.0 + {21540012-A296-45CE-8D35-3EA5A07B32A6} + Library + Properties + EaseFilter.FilterControl + FilterControl + v4.5 + 512 + SAK + SAK + SAK + SAK + + + + true + full + false + ..\..\Release\ + DEBUG;TRACE + prompt + 4 + false + + + pdbonly + true + ..\..\Release\ + TRACE + prompt + 4 + false + + + true + bin\ARM64\Debug\ + DEBUG;TRACE + full + ARM64 + 7.3 + prompt + + + bin\ARM64\Release\ + TRACE + true + pdbonly + ARM64 + 7.3 + prompt + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/FilterControl/FilterControl2015.csproj b/Demo_Source_Code/CSharpDemo/FilterControl/FilterControl2015.csproj new file mode 100644 index 0000000..79bda41 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FilterControl/FilterControl2015.csproj @@ -0,0 +1,74 @@ + + + + Debug + AnyCPU + 8.0.30703 + 2.0 + {21540012-A296-45CE-8D35-3EA5A07B32A6} + Library + Properties + EaseFilter.FilterControl + FilterControl + v4.5 + 512 + SAK + SAK + SAK + SAK + + + + true + full + false + ..\..\Release\ + DEBUG;TRACE + prompt + 4 + false + + + pdbonly + true + ..\..\Release\ + TRACE + prompt + 4 + false + + + + + + + + + + + + + + + + + + Component + + + + + + + + + + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/FilterControl/MonitorFilter.cs b/Demo_Source_Code/CSharpDemo/FilterControl/MonitorFilter.cs new file mode 100644 index 0000000..6201360 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FilterControl/MonitorFilter.cs @@ -0,0 +1,644 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.IO; +using System.Runtime.InteropServices; +using System.Text; + +namespace EaseFilter.FilterControl +{ + + /// + /// Fires the monitor events after the file IO was returned from the file system. + /// + public enum MonitorFileIOEvents : ulong + { + /// + /// Fires this event after an open file IO to an existing file was returned. + /// + OnFileOpen = 0x00000002, + /// + /// Fires this event after a create file IO was returned and a new file was created. + /// + OnFileCreate = 0x0000000200000000, + /// + /// Fires this event after a read file IO was returned. + /// it includes cache-read,non-cache read, doesn't include paging read + /// + OnFileRead = 0x000002a8, + /// + /// Fires this event after a write file IO was returned. + /// + OnFileWrite = 0x0002a800, + /// + /// Fires this event after a query file size IO was returned. + /// + OnQueryFileSize = 0x0000000800000000, + /// + /// Fires this event after a query file basic information IO was returned. + /// + OnQueryFileBasicInfo = 0x0000002000000000, + /// + /// Fires this event after a query file standard information IO was returned. + /// + OnQueryFileStandardInfo = 0x0000008000000000, + /// + /// Fires this event after a query file network information IO was returned. + /// + OnQueryFileNetworkInfo = 0x0000020000000000, + /// + /// Fires this event after a query file Id IO was returned. + /// + OnQueryFileId = 0x0000080000000000, + /// + /// Fires this event after a query file info IO was returned + /// if the query file information class is not 'QueryFileSize','QueryFileBasicInfo' + /// ,'QueryFileStandardInfo','QueryFileNetworkInfo' or 'QueryFileId'. + /// + OnQueryFileInfo = 0x00080000, + /// + /// Fires this event after a set file size IO was returned. + /// + OnSetFileSize = 0x0000800000000000, + /// + /// Fires this event after set file basic info IO was returned. + /// + OnSetFileBasicInfo = 0x0002000000000000, + /// + /// Fires this event after set file standard info IO was returned. + /// + OnSetFileStandardInfo = 0x0008000000000000, + /// + /// Fires this event after set file network info IO was returned + /// + OnSetFileNetworkInfo = 0x0020000000000000, + /// + /// Fires this event after the move or rename file IO was returned. + /// + OnMoveOrRenameFile = 0x0080000000000000, + /// + /// Fires this event after the delete file IO was returned. + /// + OnDeleteFile = 0x0200000000000000, + /// + /// Fires this event after the set file info IO was returned if + /// the information class is not 'SetFileSize','SetFileBasicInfo' + /// ,'SetFileStandardInfo','SetFileNetworkInfo'. + /// + OnSetFileInfo = 0x00200000, + /// + /// Fires this event after the query directory file info IO was returned. + /// + OnQueryDirectoryFile = 0x00800000, + /// + /// Fires this event after the query file security IO was returned. + /// + OnQueryFileSecurity = 0x02000000, + /// + /// Fires this event after the set file security IO was returned. + /// + OnSetFileSecurity = 0x08000000, + /// + /// Fires this event after file handle close IO was returned. + /// + OnFileHandleClose = 0x20000000, + /// + /// Fires this event after the file close IO was returned. + /// + OnFileClose = 0x80000000, + } + + partial class FileFilter + { + /// + /// register the file events, trigger the notifcation when the events were happened after the file was closed + /// + FilterAPI.FileChangedEvents registerFileEvents = 0; + + /// + /// register the monitor notification of the IOs, this is 16bytes integer, + /// we need to convert it to 8 bytes registerCallbackMonitorIO, since all the file info query and set IOs are + /// using the same messageType. + /// + ulong registerMonitorFileIOEvents = 0; + /// + /// the maximum buffer size for monitor events if it was enabled. + /// + int maxEventBufferSize = 1024 * 1024 * 50;//50MB + + /// + ///Fires this event after the file was opened, the handle is not closed. + /// + public event EventHandler OnFileOpen; + /// + /// Fires this event after the new file was created, the handle is not closed. + /// + public event EventHandler OnNewFileCreate; + /// + /// Fires this event after the read IO was returned. + /// + public event EventHandler OnFileRead; + /// + /// Fires this event after the write IO was returned. + /// + public event EventHandler OnFileWrite; + /// + /// Fires this event after the query file size IO was returned. + /// + public event EventHandler OnQueryFileSize; + /// + /// Fires this event after the query file basic information IO was returned. + /// + public event EventHandler OnQueryFileBasicInfo; + /// + /// Fires this event after the query file standard information IO was returned. + /// + public event EventHandler OnQueryFileStandardInfo; + /// + /// Fires this event after the query file network information IO was returned. + /// + public event EventHandler OnQueryFileNetworkInfo; + /// + /// Fires this event after the query file Id IO was returned. + /// + public event EventHandler OnQueryFileId; + /// + /// Fires this event after the query file info was returned. + /// + public event EventHandler OnQueryFileInfo; + /// + /// Fires this event after the set file size IO was returned. + /// + public event EventHandler OnSetFileSize; + /// + /// Fires this event after the set file basic information was returned. + /// + public event EventHandler OnSetFileBasicInfo; + /// + /// Fires this event after the set file standard information IO was returned. + /// + public event EventHandler OnSetFileStandardInfo; + /// + /// Fires this event after the set file network information IO was returned. + /// + public event EventHandler OnSetFileNetworkInfo; + /// + /// Fires this event after the file was moved or renamed. + /// + public event EventHandler OnMoveOrRenameFile; + /// + /// Fires this event after the delete IO was returned. + /// + public event EventHandler OnDeleteFile; + /// + /// Fires this event after the set file info was returned. + /// + public event EventHandler OnSetFileInfo; + /// + /// Fires this event after the query file security IO was returned. + /// + public event EventHandler OnQueryFileSecurity; + /// + /// Fires this event after the set file security IO was returned. + /// + public event EventHandler OnSetFileSecurity; + /// + /// Fires this event after the directory enumeration query IO was returned. + /// + public event EventHandler OnQueryDirectoryFile; + /// + /// Fires this event after the file was cleanuped. + /// + public event EventHandler OnFileHandleClose; + /// + /// Fires this event after the last file handle of the file was closed. + /// + public event EventHandler OnFileClose; + + /// + /// Fires this event when the file was changed after the file handle closed + /// + public event EventHandler NotifyFileWasChanged; + + #region monitor filter property + + /// + /// Register the file events, trigger the notifcation when the events were happened after the file handle was closed. + /// it is only enabled for monitor filter driver + /// + public FilterAPI.FileChangedEvents FileChangeEventFilter + { + get { return registerFileEvents; } + set { registerFileEvents = value; } + } + + /// + /// If it is true, the filter driver will send the monitor events asynchronously, the monitor event buffer will be used. + /// if it is false, the filter driver will send the monitor events synchronously, block and wait till the events being picked up. + /// + public bool EnableMonitorEventBuffer + { + get { return (booleanConfig & (uint)FilterAPI.BooleanConfig.ENABLE_MONITOR_EVENT_BUFFER) > 0; } + set + { + if (value) + { + booleanConfig |= (uint)FilterAPI.BooleanConfig.ENABLE_MONITOR_EVENT_BUFFER; + } + else + { + booleanConfig &= ~(uint)FilterAPI.BooleanConfig.ENABLE_MONITOR_EVENT_BUFFER; + } + } + + } + + /// + /// The maximum buffer size to keep the monitor event messages. + /// + public int MaxMonitorEventBufferSize + { + get { return maxEventBufferSize; } + set { maxEventBufferSize = value; } + } + + /// + /// The monitor file IO events which will be registered to the filter driver. + /// + public ulong MonitorFileIOEventFilter + { + get { return registerMonitorFileIOEvents; } + set { registerMonitorFileIOEvents = value; } + } + + + /// + /// Below is the properties to check if the monitor file IO events were registered, if yes, the associated events will be fired. + /// + public bool IsOnFileOpenRegister { get { return (registerMonitorFileIOEvents & (ulong)MonitorFileIOEvents.OnFileOpen) > 0; } } + public bool IsOnFileCreateRegister { get { return (registerMonitorFileIOEvents & (ulong)MonitorFileIOEvents.OnFileCreate) > 0; } } + public bool IsOnQueryFileInfoRegister { get { return (registerMonitorFileIOEvents & (ulong)MonitorFileIOEvents.OnQueryFileInfo) > 0; } } + public bool IsOnQueryFileSizeRegister { get { return (registerMonitorFileIOEvents & (ulong)MonitorFileIOEvents.OnQueryFileSize) > 0; } } + public bool IsOnQueryBasicInfoRegister { get { return (registerMonitorFileIOEvents & (ulong)MonitorFileIOEvents.OnQueryFileBasicInfo) > 0; } } + public bool IsOnQueryFileStandardInfoRegister { get { return (registerMonitorFileIOEvents & (ulong)MonitorFileIOEvents.OnQueryFileStandardInfo) > 0; } } + public bool IsOnQueryFileNetworkInfoRegister { get { return (registerMonitorFileIOEvents & (ulong)MonitorFileIOEvents.OnQueryFileNetworkInfo) > 0; } } + public bool IsOnQueryFileIdRegister { get { return (registerMonitorFileIOEvents & (ulong)MonitorFileIOEvents.OnQueryFileId) > 0; } } + public bool IsOnDeleteFileRegister { get { return (registerMonitorFileIOEvents & (ulong)MonitorFileIOEvents.OnDeleteFile) > 0; } } + public bool IsOnMoveOrRenameFileRegister { get { return (registerMonitorFileIOEvents & (ulong)MonitorFileIOEvents.OnMoveOrRenameFile) > 0; } } + public bool IsOnSetFileBasicInfoRegister { get { return (registerMonitorFileIOEvents & (ulong)MonitorFileIOEvents.OnSetFileBasicInfo) > 0; } } + public bool IsOnSetFileNetworkInfoRegister { get { return (registerMonitorFileIOEvents & (ulong)MonitorFileIOEvents.OnSetFileNetworkInfo) > 0; } } + public bool IsOnSetFileSizeRegister { get { return (registerMonitorFileIOEvents & (ulong)MonitorFileIOEvents.OnSetFileSize) > 0; } } + public bool IsOnSetFileStandardInfoRegister { get { return (registerMonitorFileIOEvents & (ulong)MonitorFileIOEvents.OnSetFileStandardInfo) > 0; } } + public bool IsOnSetFileInfoRegister { get { return (registerMonitorFileIOEvents & (ulong)MonitorFileIOEvents.OnSetFileInfo) > 0; } } + + #endregion //monitor filter property + + /// + /// Process the notification events, no return needed for the filter driver. + /// + /// + public override void SendNotification(FilterAPI.MessageSendData messageSend) + { + + try + { + if (messageSend.FilterCommand == (uint)FilterAPI.FilterCommand.FILTER_SEND_FILE_CHANGED_EVENT) + { + if (null != NotifyFileWasChanged) + { + FileChangedEventArgs fileChangeEventArgs = new FileChangedEventArgs(messageSend); + NotifyFileWasChanged(this, fileChangeEventArgs); + } + } + else if (messageSend.MessageType == (uint)FilterAPI.MessageType.POST_CREATE) + { + FileCreateEventArgs fileCreateEventArgs = new FileCreateEventArgs(messageSend); + if (fileCreateEventArgs.isNewFileCreated && IsOnFileCreateRegister) + { + fileCreateEventArgs.EventName = "OnNewFileCreate"; + if (IsOnFileCreateRegister && null != OnNewFileCreate) + { + //new file was created. + OnNewFileCreate(this, fileCreateEventArgs); + } + } + else if (IsOnFileOpenRegister ) + { + fileCreateEventArgs.EventName = "OnFileOpen"; + if (null != OnFileOpen) + { + OnFileOpen(this, fileCreateEventArgs); + } + } + + if (fileCreateEventArgs.isDeleteOnClose) + { + fileCreateEventArgs = new FileCreateEventArgs(messageSend); + fileCreateEventArgs.EventName = "OnDeleteFile"; + + if (null != OnDeleteFile && IsOnDeleteFileRegister ) + { + OnDeleteFile(this, fileCreateEventArgs); + } + } + } + else if (messageSend.MessageType == (uint)FilterAPI.MessageType.PRE_CACHE_READ + || messageSend.MessageType == (uint)FilterAPI.MessageType.PRE_FASTIO_READ + || messageSend.MessageType == (uint)FilterAPI.MessageType.PRE_NOCACHE_READ + || messageSend.MessageType == (uint)FilterAPI.MessageType.PRE_PAGING_IO_READ) + { + if (null != OnFileRead) + { + FileReadEventArgs fileReadEventArgs = new FileReadEventArgs(messageSend); + fileReadEventArgs.EventName = "OnPreFileRead-" + fileReadEventArgs.readType; + + OnFileRead(this, fileReadEventArgs); + } + } + else if (messageSend.MessageType == (uint)FilterAPI.MessageType.POST_CACHE_READ + || messageSend.MessageType == (uint)FilterAPI.MessageType.POST_FASTIO_READ + || messageSend.MessageType == (uint)FilterAPI.MessageType.POST_NOCACHE_READ + || messageSend.MessageType == (uint)FilterAPI.MessageType.POST_PAGING_IO_READ) + { + if (null != OnFileRead) + { + FileReadEventArgs fileReadEventArgs = new FileReadEventArgs(messageSend); + fileReadEventArgs.EventName = "OnPostFileRead-" + fileReadEventArgs.readType; + + OnFileRead(this, fileReadEventArgs); + } + } + else if (messageSend.MessageType == (uint)FilterAPI.MessageType.PRE_CACHE_WRITE + || messageSend.MessageType == (uint)FilterAPI.MessageType.PRE_FASTIO_WRITE + || messageSend.MessageType == (uint)FilterAPI.MessageType.PRE_NOCACHE_WRITE + || messageSend.MessageType == (uint)FilterAPI.MessageType.PRE_PAGING_IO_WRITE) + { + //if the event was subscribed + if (null != OnFileWrite) + { + FileWriteEventArgs fileWriteEventArgs = new FileWriteEventArgs(messageSend); + fileWriteEventArgs.EventName = "OnPreFileWrite-" + fileWriteEventArgs.writeType; + + OnFileWrite(this, fileWriteEventArgs); + } + } + else if (messageSend.MessageType == (uint)FilterAPI.MessageType.POST_CACHE_WRITE + || messageSend.MessageType == (uint)FilterAPI.MessageType.POST_FASTIO_WRITE + || messageSend.MessageType == (uint)FilterAPI.MessageType.POST_NOCACHE_WRITE + || messageSend.MessageType == (uint)FilterAPI.MessageType.POST_PAGING_IO_WRITE) + { + //if the event was subscribed + if (null != OnFileWrite) + { + FileWriteEventArgs fileWriteEventArgs = new FileWriteEventArgs(messageSend); + fileWriteEventArgs.EventName = "OnPostFileWrite-" + fileWriteEventArgs.writeType; + + OnFileWrite(this, fileWriteEventArgs); + } + } + else if (messageSend.MessageType == (uint)FilterAPI.MessageType.POST_QUERY_INFORMATION) + { + if (messageSend.InfoClass == (uint)WinData.FileInfomationClass.FileEndOfFileInformation) + { + //if the event was subscribed + if (null != OnQueryFileSize && IsOnQueryFileSizeRegister) + { + FileSizeEventArgs fileSizeArgs = new FileSizeEventArgs(messageSend); + fileSizeArgs.EventName = "OnQueryFileSize"; + + OnQueryFileSize(this, fileSizeArgs); + } + } + else if (messageSend.InfoClass == (uint)WinData.FileInfomationClass.FileInternalInformation) + { + //if the event was subscribed + if (null != OnQueryFileId && IsOnQueryFileIdRegister) + { + FileIdEventArgs fileIdArgs = new FileIdEventArgs(messageSend); + fileIdArgs.EventName = "OnQueryFileId"; + + OnQueryFileId(this, fileIdArgs); + } + } + else if (messageSend.InfoClass == (uint)WinData.FileInfomationClass.FileBasicInformation) + { + //if the event was subscribed + if (null != OnQueryFileBasicInfo && IsOnQueryBasicInfoRegister) + { + FileBasicInfoEventArgs fileBasicInfoArgs = new FileBasicInfoEventArgs(messageSend); + fileBasicInfoArgs.EventName = "OnQueryFileBasicInfo"; + + OnQueryFileBasicInfo(this, fileBasicInfoArgs); + } + } + else if (messageSend.InfoClass == (uint)WinData.FileInfomationClass.FileStandardInformation) + { + //if the event was subscribed + if (null != OnQueryFileStandardInfo && IsOnQueryFileStandardInfoRegister) + { + FileStandardInfoEventArgs fileStandardInfoArgs = new FileStandardInfoEventArgs(messageSend); + fileStandardInfoArgs.EventName = "OnQueryFileStandardInfo"; + + OnQueryFileStandardInfo(this, fileStandardInfoArgs); + } + } + else if (messageSend.InfoClass == (uint)WinData.FileInfomationClass.FileNetworkOpenInformation) + { + //if the event was subscribed + if (null != OnQueryFileNetworkInfo && IsOnQueryFileNetworkInfoRegister) + { + FileNetworkInfoEventArgs fileNetworkInfoArgs = new FileNetworkInfoEventArgs(messageSend); + fileNetworkInfoArgs.EventName = "OnQueryFileNetworkInfo"; + + if (messageSend.FsContext.ToInt64() == 0) + { + //this is the fast-io-network-query + fileNetworkInfoArgs.EventName += ";FastIO"; + } + + OnQueryFileNetworkInfo(this, fileNetworkInfoArgs); + } + } + else if (null != OnQueryFileInfo && IsOnQueryFileInfoRegister) + { + FileInfoArgs fileInfoArgs = new FileInfoArgs(messageSend); + fileInfoArgs.EventName = "OnQueryFileInfo:" + fileInfoArgs.FileInfoClass.ToString(); + + OnQueryFileInfo(this, fileInfoArgs); + } + + //below is the different infomation class of the query file info IO + } + else if (messageSend.MessageType == (uint)FilterAPI.MessageType.POST_SET_INFORMATION) + { + + if (messageSend.InfoClass == (uint)WinData.FileInfomationClass.FileEndOfFileInformation) + { + //if the event was subscribed + if (null != OnSetFileSize && IsOnSetFileSizeRegister) + { + FileSizeEventArgs fileSizeArgs = new FileSizeEventArgs(messageSend); + fileSizeArgs.EventName = "OnSetFileSize"; + + OnSetFileSize(this, fileSizeArgs); + } + } + else if (messageSend.InfoClass == (uint)WinData.FileInfomationClass.FileBasicInformation) + { + //if the event was subscribed + if (null != OnSetFileBasicInfo && IsOnSetFileBasicInfoRegister) + { + FileBasicInfoEventArgs fileBasicInfoArgs = new FileBasicInfoEventArgs(messageSend); + fileBasicInfoArgs.EventName = "OnSetFileBasicInfo"; + + OnSetFileBasicInfo(this, fileBasicInfoArgs); + } + } + else if (messageSend.InfoClass == (uint)WinData.FileInfomationClass.FileStandardInformation) + { + //if the event was subscribed + if (null != OnSetFileStandardInfo && IsOnSetFileStandardInfoRegister) + { + FileStandardInfoEventArgs fileStandardInfoArgs = new FileStandardInfoEventArgs(messageSend); + fileStandardInfoArgs.EventName = "OnSetFileStandardInfo"; + + OnSetFileStandardInfo(this, fileStandardInfoArgs); + } + } + else if (messageSend.InfoClass == (uint)WinData.FileInfomationClass.FileNetworkOpenInformation) + { + //if the event was subscribed + if (null != OnSetFileNetworkInfo && IsOnSetFileNetworkInfoRegister) + { + FileNetworkInfoEventArgs fileNetworkInfoArgs = new FileNetworkInfoEventArgs(messageSend); + fileNetworkInfoArgs.EventName = "OnSetFileNetworkInfo"; + + OnSetFileNetworkInfo(this, fileNetworkInfoArgs); + } + } + else if (messageSend.InfoClass == (uint)WinData.FileInfomationClass.FileRenameInformation + || messageSend.InfoClass == (uint)WinData.FileInfomationClass.FileRenameInformationEx) + { + //if the event was subscribed + if (null != OnMoveOrRenameFile && IsOnMoveOrRenameFileRegister) + { + FileMoveOrRenameEventArgs fileRenameArgs = new FileMoveOrRenameEventArgs(messageSend); + fileRenameArgs.EventName = "OnMoveOrRenameFile"; + + OnMoveOrRenameFile(this, fileRenameArgs); + } + } + else if (messageSend.InfoClass == (uint)WinData.FileInfomationClass.FileDispositionInformation + || messageSend.InfoClass == (uint)WinData.FileInfomationClass.FileDispositionInformationEx) + { + //if the event was subscribed + if (null != OnDeleteFile && IsOnDeleteFileRegister) + { + FileIOEventArgs fileIOArgs = new FileIOEventArgs(messageSend); + fileIOArgs.EventName = "OnDeleteFile"; + + OnDeleteFile(this, fileIOArgs); + } + } + else if (null != OnSetFileInfo && IsOnSetFileInfoRegister) + { + //for all other information class, we will fire this event + FileInfoArgs fileInfoArgs = new FileInfoArgs(messageSend); + fileInfoArgs.EventName = "OnSetFileInfo:" + fileInfoArgs.FileInfoClass.ToString(); + + OnSetFileInfo(this, fileInfoArgs); + } + + } + else if (messageSend.MessageType == (uint)FilterAPI.MessageType.POST_QUERY_SECURITY) + { + //if the event was subscribed + if (null != OnQueryFileSecurity) + { + FileSecurityEventArgs fileSecurityArgs = new FileSecurityEventArgs(messageSend); + fileSecurityArgs.EventName = "OnQueryFileSecurity"; + + OnQueryFileSecurity(this, fileSecurityArgs); + } + } + else if (messageSend.MessageType == (uint)FilterAPI.MessageType.POST_SET_SECURITY) + { + //if the event was subscribed + if (null != OnSetFileSecurity) + { + FileSecurityEventArgs fileSecurityArgs = new FileSecurityEventArgs(messageSend); + fileSecurityArgs.EventName = "OnSetFileSecurity"; + + OnSetFileSecurity(this, fileSecurityArgs); + } + } + else if (messageSend.MessageType == (uint)FilterAPI.MessageType.POST_DIRECTORY) + { + //if the event was subscribed + if (null != OnQueryDirectoryFile) + { + FileQueryDirectoryEventArgs directoryArgs = new FileQueryDirectoryEventArgs(messageSend); + directoryArgs.EventName = "OnQueryDirectoryFile"; + + OnQueryDirectoryFile(this, directoryArgs); + } + } + else if (messageSend.MessageType == (uint)FilterAPI.MessageType.POST_CLEANUP) + { + //if the event was subscribed + if (null != OnFileHandleClose) + { + FileIOEventArgs fileIOArgs = new FileIOEventArgs(messageSend); + fileIOArgs.EventName = "OnFileHandleClose"; + + fileIOArgs.Description = "The opened file handle was closed."; + + OnFileHandleClose(this, fileIOArgs); + } + } + else if (messageSend.MessageType == (uint)FilterAPI.MessageType.POST_CLOSE) + { + //if the event was subscribed + if (null != OnFileClose) + { + FileIOEventArgs fileIOArgs = new FileIOEventArgs(messageSend); + fileIOArgs.EventName = "OnFileClose"; + + fileIOArgs.Description = "All system references to fileObject " + messageSend.FileObject.ToString("X") + " were closed."; + + OnFileClose(this, fileIOArgs); + } + } + else + { + string errorMessage = "\r\nThe messageType:" + messageSend.MessageType.ToString("X") + " can't be handled in monitor filter, messageId:" + + messageSend.MessageId + ",name:" + messageSend.FileName + "\r\n"; + Console.WriteLine(errorMessage); + Utils.ToDebugger(errorMessage); + } + + } + catch (Exception ex) + { + Console.WriteLine("SendNotification exception:" + ex.Message); + Utils.ToDebugger("\n\n\nSendNotification exception:" + ex.Message); + } + } + + } +} diff --git a/Demo_Source_Code/CSharpDemo/FilterControl/NtStatus.cs b/Demo_Source_Code/CSharpDemo/FilterControl/NtStatus.cs new file mode 100644 index 0000000..ce5fcd6 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FilterControl/NtStatus.cs @@ -0,0 +1,392 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.Collections.Generic; +using System.Text; + +namespace EaseFilter.FilterControl +{ + public class NtStatus + { + /// + /// A NT status value. + /// + public enum Status : uint + { + // Success + Success = 0x00000000, + Wait1 = 0x00000001, + Wait2 = 0x00000002, + Wait3 = 0x00000003, + Wait63 = 0x0000003f, + Abandoned = 0x00000080, + AbandonedWait0 = 0x00000080, + AbandonedWait1 = 0x00000081, + AbandonedWait2 = 0x00000082, + AbandonedWait3 = 0x00000083, + AbandonedWait63 = 0x000000bf, + UserApc = 0x000000c0, + KernelApc = 0x00000100, + Alerted = 0x00000101, + Timeout = 0x00000102, + Pending = 0x00000103, + Reparse = 0x00000104, + MoreEntries = 0x00000105, + NotAllAssigned = 0x00000106, + SomeNotMapped = 0x00000107, + OpLockBreakInProgress = 0x00000108, + VolumeMounted = 0x00000109, + RxActCommitted = 0x0000010a, + NotifyCleanup = 0x0000010b, + NotifyEnumDir = 0x0000010c, + NoQuotasForAccount = 0x0000010d, + PrimaryTransportConnectFailed = 0x0000010e, + PageFaultTransition = 0x00000110, + PageFaultDemandZero = 0x00000111, + PageFaultCopyOnWrite = 0x00000112, + PageFaultGuardPage = 0x00000113, + PageFaultPagingFile = 0x00000114, + CrashDump = 0x00000116, + ReparseObject = 0x00000118, + NothingToTerminate = 0x00000122, + ProcessNotInJob = 0x00000123, + ProcessInJob = 0x00000124, + ProcessCloned = 0x00000129, + FileLockedWithOnlyReaders = 0x0000012a, + FileLockedWithWriters = 0x0000012b, + + // Informational + Informational = 0x40000000, + ObjectNameExists = 0x40000000, + ThreadWasSuspended = 0x40000001, + WorkingSetLimitRange = 0x40000002, + ImageNotAtBase = 0x40000003, + RegistryRecovered = 0x40000009, + + // Warning + Warning = 0x80000000, + GuardPageViolation = 0x80000001, + DatatypeMisalignment = 0x80000002, + Breakpoint = 0x80000003, + SingleStep = 0x80000004, + BufferOverflow = 0x80000005, + NoMoreFiles = 0x80000006, + HandlesClosed = 0x8000000a, + PartialCopy = 0x8000000d, + DeviceBusy = 0x80000011, + InvalidEaName = 0x80000013, + EaListInconsistent = 0x80000014, + NoMoreEntries = 0x8000001a, + LongJump = 0x80000026, + DllMightBeInsecure = 0x8000002b, + + // Error + Error = 0xc0000000, + Unsuccessful = 0xc0000001, + NotImplemented = 0xc0000002, + InvalidInfoClass = 0xc0000003, + InfoLengthMismatch = 0xc0000004, + AccessViolation = 0xc0000005, + InPageError = 0xc0000006, + PagefileQuota = 0xc0000007, + InvalidHandle = 0xc0000008, + BadInitialStack = 0xc0000009, + BadInitialPc = 0xc000000a, + InvalidCid = 0xc000000b, + TimerNotCanceled = 0xc000000c, + InvalidParameter = 0xc000000d, + NoSuchDevice = 0xc000000e, + NoSuchFile = 0xc000000f, + InvalidDeviceRequest = 0xc0000010, + EndOfFile = 0xc0000011, + WrongVolume = 0xc0000012, + NoMediaInDevice = 0xc0000013, + NoMemory = 0xc0000017, + NotMappedView = 0xc0000019, + UnableToFreeVm = 0xc000001a, + UnableToDeleteSection = 0xc000001b, + IllegalInstruction = 0xc000001d, + AlreadyCommitted = 0xc0000021, + AccessDenied = 0xc0000022, + BufferTooSmall = 0xc0000023, + ObjectTypeMismatch = 0xc0000024, + NonContinuableException = 0xc0000025, + BadStack = 0xc0000028, + NotLocked = 0xc000002a, + NotCommitted = 0xc000002d, + InvalidParameterMix = 0xc0000030, + ObjectNameInvalid = 0xc0000033, + ObjectNameNotFound = 0xc0000034, + ObjectNameCollision = 0xc0000035, + ObjectPathInvalid = 0xc0000039, + ObjectPathNotFound = 0xc000003a, + ObjectPathSyntaxBad = 0xc000003b, + DataOverrun = 0xc000003c, + DataLate = 0xc000003d, + DataError = 0xc000003e, + CrcError = 0xc000003f, + SectionTooBig = 0xc0000040, + PortConnectionRefused = 0xc0000041, + InvalidPortHandle = 0xc0000042, + SharingViolation = 0xc0000043, + QuotaExceeded = 0xc0000044, + InvalidPageProtection = 0xc0000045, + MutantNotOwned = 0xc0000046, + SemaphoreLimitExceeded = 0xc0000047, + PortAlreadySet = 0xc0000048, + SectionNotImage = 0xc0000049, + SuspendCountExceeded = 0xc000004a, + ThreadIsTerminating = 0xc000004b, + BadWorkingSetLimit = 0xc000004c, + IncompatibleFileMap = 0xc000004d, + SectionProtection = 0xc000004e, + EasNotSupported = 0xc000004f, + EaTooLarge = 0xc0000050, + NonExistentEaEntry = 0xc0000051, + NoEasOnFile = 0xc0000052, + EaCorruptError = 0xc0000053, + FileLockConflict = 0xc0000054, + LockNotGranted = 0xc0000055, + DeletePending = 0xc0000056, + CtlFileNotSupported = 0xc0000057, + UnknownRevision = 0xc0000058, + RevisionMismatch = 0xc0000059, + InvalidOwner = 0xc000005a, + InvalidPrimaryGroup = 0xc000005b, + NoImpersonationToken = 0xc000005c, + CantDisableMandatory = 0xc000005d, + NoLogonServers = 0xc000005e, + NoSuchLogonSession = 0xc000005f, + NoSuchPrivilege = 0xc0000060, + PrivilegeNotHeld = 0xc0000061, + InvalidAccountName = 0xc0000062, + UserExists = 0xc0000063, + NoSuchUser = 0xc0000064, + GroupExists = 0xc0000065, + NoSuchGroup = 0xc0000066, + MemberInGroup = 0xc0000067, + MemberNotInGroup = 0xc0000068, + LastAdmin = 0xc0000069, + WrongPassword = 0xc000006a, + IllFormedPassword = 0xc000006b, + PasswordRestriction = 0xc000006c, + LogonFailure = 0xc000006d, + AccountRestriction = 0xc000006e, + InvalidLogonHours = 0xc000006f, + InvalidWorkstation = 0xc0000070, + PasswordExpired = 0xc0000071, + AccountDisabled = 0xc0000072, + NoneMapped = 0xc0000073, + TooManyLuidsRequested = 0xc0000074, + LuidsExhausted = 0xc0000075, + InvalidSubAuthority = 0xc0000076, + InvalidAcl = 0xc0000077, + InvalidSid = 0xc0000078, + InvalidSecurityDescr = 0xc0000079, + ProcedureNotFound = 0xc000007a, + InvalidImageFormat = 0xc000007b, + NoToken = 0xc000007c, + BadInheritanceAcl = 0xc000007d, + RangeNotLocked = 0xc000007e, + DiskFull = 0xc000007f, + ServerDisabled = 0xc0000080, + ServerNotDisabled = 0xc0000081, + TooManyGuidsRequested = 0xc0000082, + GuidsExhausted = 0xc0000083, + InvalidIdAuthority = 0xc0000084, + AgentsExhausted = 0xc0000085, + InvalidVolumeLabel = 0xc0000086, + SectionNotExtended = 0xc0000087, + NotMappedData = 0xc0000088, + ResourceDataNotFound = 0xc0000089, + ResourceTypeNotFound = 0xc000008a, + ResourceNameNotFound = 0xc000008b, + ArrayBoundsExceeded = 0xc000008c, + FloatDenormalOperand = 0xc000008d, + FloatDivideByZero = 0xc000008e, + FloatInexactResult = 0xc000008f, + FloatInvalidOperation = 0xc0000090, + FloatOverflow = 0xc0000091, + FloatStackCheck = 0xc0000092, + FloatUnderflow = 0xc0000093, + IntegerDivideByZero = 0xc0000094, + IntegerOverflow = 0xc0000095, + PrivilegedInstruction = 0xc0000096, + TooManyPagingFiles = 0xc0000097, + FileInvalid = 0xc0000098, + InstanceNotAvailable = 0xc00000ab, + PipeNotAvailable = 0xc00000ac, + InvalidPipeState = 0xc00000ad, + PipeBusy = 0xc00000ae, + IllegalFunction = 0xc00000af, + PipeDisconnected = 0xc00000b0, + PipeClosing = 0xc00000b1, + PipeConnected = 0xc00000b2, + PipeListening = 0xc00000b3, + InvalidReadMode = 0xc00000b4, + IoTimeout = 0xc00000b5, + FileForcedClosed = 0xc00000b6, + ProfilingNotStarted = 0xc00000b7, + ProfilingNotStopped = 0xc00000b8, + NotSameDevice = 0xc00000d4, + FileRenamed = 0xc00000d5, + CantWait = 0xc00000d8, + PipeEmpty = 0xc00000d9, + CantTerminateSelf = 0xc00000db, + InternalError = 0xc00000e5, + InvalidParameter1 = 0xc00000ef, + InvalidParameter2 = 0xc00000f0, + InvalidParameter3 = 0xc00000f1, + InvalidParameter4 = 0xc00000f2, + InvalidParameter5 = 0xc00000f3, + InvalidParameter6 = 0xc00000f4, + InvalidParameter7 = 0xc00000f5, + InvalidParameter8 = 0xc00000f6, + InvalidParameter9 = 0xc00000f7, + InvalidParameter10 = 0xc00000f8, + InvalidParameter11 = 0xc00000f9, + InvalidParameter12 = 0xc00000fa, + MappedFileSizeZero = 0xc000011e, + TooManyOpenedFiles = 0xc000011f, + Cancelled = 0xc0000120, + CannotDelete = 0xc0000121, + InvalidComputerName = 0xc0000122, + FileDeleted = 0xc0000123, + SpecialAccount = 0xc0000124, + SpecialGroup = 0xc0000125, + SpecialUser = 0xc0000126, + MembersPrimaryGroup = 0xc0000127, + FileClosed = 0xc0000128, + TooManyThreads = 0xc0000129, + ThreadNotInProcess = 0xc000012a, + TokenAlreadyInUse = 0xc000012b, + PagefileQuotaExceeded = 0xc000012c, + CommitmentLimit = 0xc000012d, + InvalidImageLeFormat = 0xc000012e, + InvalidImageNotMz = 0xc000012f, + InvalidImageProtect = 0xc0000130, + InvalidImageWin16 = 0xc0000131, + LogonServer = 0xc0000132, + DifferenceAtDc = 0xc0000133, + SynchronizationRequired = 0xc0000134, + DllNotFound = 0xc0000135, + IoPrivilegeFailed = 0xc0000137, + OrdinalNotFound = 0xc0000138, + EntryPointNotFound = 0xc0000139, + ControlCExit = 0xc000013a, + FileIsNoEncrypted = 0xC0000291, + FileIsEncrypted = 0xC0000293, + PortNotSet = 0xc0000353, + DebuggerInactive = 0xc0000354, + CallbackBypass = 0xc0000503, + PortClosed = 0xc0000700, + MessageLost = 0xc0000701, + InvalidMessage = 0xc0000702, + RequestCanceled = 0xc0000703, + RecursiveDispatch = 0xc0000704, + LpcReceiveBufferExpected = 0xc0000705, + LpcInvalidConnectionUsage = 0xc0000706, + LpcRequestsNotAllowed = 0xc0000707, + ResourceInUse = 0xc0000708, + ProcessIsProtected = 0xc0000712, + VolumeDirty = 0xc0000806, + FileCheckedOut = 0xc0000901, + CheckOutRequired = 0xc0000902, + BadFileType = 0xc0000903, + FileTooLarge = 0xc0000904, + FormsAuthRequired = 0xc0000905, + VirusInfected = 0xc0000906, + VirusDeleted = 0xc0000907, + TransactionalConflict = 0xc0190001, + InvalidTransaction = 0xc0190002, + TransactionNotActive = 0xc0190003, + TmInitializationFailed = 0xc0190004, + RmNotActive = 0xc0190005, + RmMetadataCorrupt = 0xc0190006, + TransactionNotJoined = 0xc0190007, + DirectoryNotRm = 0xc0190008, + CouldNotResizeLog = 0xc0190009, + TransactionsUnsupportedRemote = 0xc019000a, + LogResizeInvalidSize = 0xc019000b, + RemoteFileVersionMismatch = 0xc019000c, + CrmProtocolAlreadyExists = 0xc019000f, + TransactionPropagationFailed = 0xc0190010, + CrmProtocolNotFound = 0xc0190011, + TransactionSuperiorExists = 0xc0190012, + TransactionRequestNotValid = 0xc0190013, + TransactionNotRequested = 0xc0190014, + TransactionAlreadyAborted = 0xc0190015, + TransactionAlreadyCommitted = 0xc0190016, + TransactionInvalidMarshallBuffer = 0xc0190017, + CurrentTransactionNotValid = 0xc0190018, + LogGrowthFailed = 0xc0190019, + ObjectNoLongerExists = 0xc0190021, + StreamMiniversionNotFound = 0xc0190022, + StreamMiniversionNotValid = 0xc0190023, + MiniversionInaccessibleFromSpecifiedTransaction = 0xc0190024, + CantOpenMiniversionWithModifyIntent = 0xc0190025, + CantCreateMoreStreamMiniversions = 0xc0190026, + HandleNoLongerValid = 0xc0190028, + NoTxfMetadata = 0xc0190029, + LogCorruptionDetected = 0xc0190030, + CantRecoverWithHandleOpen = 0xc0190031, + RmDisconnected = 0xc0190032, + EnlistmentNotSuperior = 0xc0190033, + RecoveryNotNeeded = 0xc0190034, + RmAlreadyStarted = 0xc0190035, + FileIdentityNotPersistent = 0xc0190036, + CantBreakTransactionalDependency = 0xc0190037, + CantCrossRmBoundary = 0xc0190038, + TxfDirNotEmpty = 0xc0190039, + IndoubtTransactionsExist = 0xc019003a, + TmVolatile = 0xc019003b, + RollbackTimerExpired = 0xc019003c, + TxfAttributeCorrupt = 0xc019003d, + EfsNotAllowedInTransaction = 0xc019003e, + TransactionalOpenNotAllowed = 0xc019003f, + TransactedMappingUnsupportedRemote = 0xc0190040, + TxfMetadataAlreadyPresent = 0xc0190041, + TransactionScopeCallbacksNotSet = 0xc0190042, + TransactionRequiredPromotion = 0xc0190043, + CannotExecuteFileInTransaction = 0xc0190044, + TransactionsNotFrozen = 0xc0190045, + + MaximumNtStatus = 0xffffffff + } + + public static string StatusToString(uint status) + { + string ret = string.Empty; + + foreach (NtStatus.Status ntStatus in Enum.GetValues(typeof(NtStatus.Status))) + { + if (status == (uint)ntStatus) + { + ret = ntStatus.ToString() + "(0x" + status.ToString("X") + ")"; + } + } + + if (string.IsNullOrEmpty(ret)) + { + ret = "(0x" + status.ToString("X") + ")"; + } + + return ret; + } + } +} diff --git a/Demo_Source_Code/CSharpDemo/FilterControl/ProcessFilter.cs b/Demo_Source_Code/CSharpDemo/FilterControl/ProcessFilter.cs new file mode 100644 index 0000000..f3101ed --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FilterControl/ProcessFilter.cs @@ -0,0 +1,268 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using System.IO; + +namespace EaseFilter.FilterControl +{ + public class ProcessFilter : FileFilter + { + private string processNameFilterMask = string.Empty; + + public event EventHandler OnProcessCreation; + public event EventHandler OnProcessPreTermination; + public event EventHandler NotifyProcessWasBlocked; + public event EventHandler NotifyProcessTerminated; + public event EventHandler NotifyThreadCreation; + public event EventHandler NotifyThreadTerminated; + public event EventHandler NotifyProcessHandleInfo; + public event EventHandler NotifyThreadHandleInfo; + + Dictionary fileAccessRights = new Dictionary(); + /// + /// the process name filter mask, i.e. "notepad.exe","c:\\windows\\*.exe" + /// + public string ProcessNameFilterMask { get { return processNameFilterMask; } set { processNameFilterMask = value; } } + + /// + /// The control flag to the processes which match the processNameFilterMask + /// + public uint ControlFlag { get; set; } + + /// + /// Using the process Id to monitor or control the file access rights instead of the process name if it is not 0. + /// + public uint ProcessId { get; set; } + + /// + /// The file access rights to the processes,the key is the FileFilterMask, the value is the access flag. + /// i.e. + /// + public Dictionary FileAccessRights + { + get { return fileAccessRights; } + set { fileAccessRights = value; } + } + + public ProcessFilter(string processNameFilterMask) + : base(processNameFilterMask) + { + ProcessNameFilterMask = processNameFilterMask; + this.FilterType = FilterAPI.FilterType.PROCESS_FILTER; + } + + public override void SendNotification(FilterAPI.MessageSendData messageSend) + { + + ProcessEventArgs processEventArgs = new ProcessEventArgs(messageSend); + if (messageSend.FilterCommand == (uint)FilterAPI.FilterCommand.FILTER_SEND_DENIED_PROCESS_CREATION_EVENT) + { + if (null != NotifyProcessWasBlocked) + { + processEventArgs.EventName = "NewProcessCreationWasBlocked"; + NotifyProcessWasBlocked(this, processEventArgs); + } + } + else if (messageSend.FilterCommand == (uint)FilterAPI.FilterCommand.FILTER_SEND_DENIED_PROCESS_TERMINATED_EVENT) + { + if (null != NotifyProcessWasBlocked) + { + processEventArgs.EventName = "ProcessTerminationWasBlocked"; + NotifyProcessWasBlocked(this, processEventArgs); + } + } + else if (messageSend.FilterCommand == (uint)FilterAPI.FilterCommand.FILTER_SEND_PROCESS_TERMINATION_INFO) + { + if (null != NotifyProcessTerminated) + { + processEventArgs.EventName = "NotifyProcessTerminated"; + NotifyProcessTerminated(this, processEventArgs); + } + } + else if (messageSend.FilterCommand == (uint)FilterAPI.FilterCommand.FILTER_SEND_THREAD_CREATION_INFO) + { + if (null != NotifyThreadCreation) + { + processEventArgs.EventName = "NotifyThreadCreation"; + NotifyThreadCreation(this, processEventArgs); + } + } + else if (messageSend.FilterCommand == (uint)FilterAPI.FilterCommand.FILTER_SEND_THREAD_TERMINATION_INFO) + { + if (null != NotifyThreadTerminated) + { + processEventArgs.EventName = "NotifyThreadTerminated"; + NotifyThreadTerminated(this, processEventArgs); + } + } + else if (messageSend.FilterCommand == (uint)FilterAPI.FilterCommand.FILTER_SEND_PROCESS_HANDLE_INFO) + { + if (null != NotifyProcessHandleInfo) + { + processEventArgs.EventName = "NotifyProcessHandleInfo"; + NotifyProcessHandleInfo(this, processEventArgs); + } + } + else if (messageSend.FilterCommand == (uint)(uint)FilterAPI.FilterCommand.FILTER_SEND_THREAD_HANDLE_INFO) + { + if (null != NotifyThreadHandleInfo) + { + processEventArgs.EventName = "NotifyThreadHandleInfo"; + NotifyThreadHandleInfo(this, processEventArgs); + } + } + else + { + base.SendNotification(messageSend); + } + + } + + public override bool FireControlEvents(FilterAPI.MessageSendData messageSend, ref FilterAPI.MessageReplyData messageReply) + { + if (messageSend.MessageType == (uint)FilterAPI.FilterCommand.FILTER_SEND_PROCESS_CREATION_INFO) + { + if (null != OnProcessCreation) + { + ProcessEventArgs processEventArgs = new ProcessEventArgs(messageSend); + processEventArgs.EventName = "OnProcessCreation"; + + OnProcessCreation(this, processEventArgs); + + //you can block the process creation if return status is not success status. + messageReply.ReturnStatus = (uint)processEventArgs.ReturnStatus; + + } + } + else if (messageSend.MessageType == (uint)FilterAPI.FilterCommand.FILTER_SEND_PRE_TERMINATE_PROCESS_INFO) + { + if (null != OnProcessPreTermination) + { + ProcessEventArgs processEventArgs = new ProcessEventArgs(messageSend); + processEventArgs.EventName = "OnProcessPreTermination"; + + OnProcessPreTermination(this, processEventArgs); + + //you can block the process termination if return status is not success status. + messageReply.ReturnStatus = (uint)processEventArgs.ReturnStatus; + + } + } + else + { + base.FireControlEvents(messageSend, ref messageReply); + } + + + return true; + } + + } + public class ProcessEventArgs : FileIOEventArgs + { + public ProcessEventArgs(FilterAPI.MessageSendData messageSend) + : base(messageSend) + { + FileName = ImageFileName = messageSend.FileName; + + if (messageSend.DataBufferLength > 0) + { + GCHandle pinnedPacket = GCHandle.Alloc(messageSend.DataBuffer, GCHandleType.Pinned); + FilterAPI.PROCESS_INFO processInfo = (FilterAPI.PROCESS_INFO)Marshal.PtrToStructure( + pinnedPacket.AddrOfPinnedObject(), typeof(FilterAPI.PROCESS_INFO)); + + ParentProcessId = processInfo.ParentProcessId; + CreatingProcessId = processInfo.CreatingProcessId; + CreatingThreadId = processInfo.CreatingThreadId; + DesiredAccess = processInfo.DesiredAccess; + Operation = processInfo.Operation; + FileOpenNameAvailable = processInfo.FileOpenNameAvailable; + CommandLine = processInfo.CommandLine; + + switch (messageSend.FilterCommand) + { + case (uint)FilterAPI.FilterCommand.FILTER_SEND_PROCESS_CREATION_INFO: + { + Description = "ParentPid:" + ParentProcessId + ";CreatingPid:" + CreatingProcessId + ";CreatingThreadId:" + CreatingThreadId + + ";FileOpenNameAvailable:" + FileOpenNameAvailable + ";CommandLine:" + CommandLine; + + break; + } + case (uint)FilterAPI.FilterCommand.FILTER_SEND_PROCESS_HANDLE_INFO: + case (uint)FilterAPI.FilterCommand.FILTER_SEND_THREAD_HANDLE_INFO: + { + if (processInfo.Operation == 1) + { + Description = "Create Handle"; + } + else + { + Description = "Duplicate Handle"; + } + + Description += "; DesiredAccess:" + processInfo.DesiredAccess.ToString("X"); + break; + } + + } + + pinnedPacket.Free(); + } + } + + /// + ///The process ID of the parent process for the new process. Note that the parent process is not necessarily the same process as the process that created the new process. + /// + public uint ParentProcessId { get; set; } + /// + /// The process ID of the process that created the new process. + /// + public uint CreatingProcessId { get; set; } + /// + /// The thread ID of the thread that created the new process. + /// + public uint CreatingThreadId { get; set; } + /// + ///An ACCESS_MASK value that specifies the access rights to grant for the handle + /// + public uint DesiredAccess { get; set; } + /// + ///The type of handle operation. This member might be one of the following values:OB_OPERATION_HANDLE_CREATE,OB_OPERATION_HANDLE_DUPLICATE + /// + public uint Operation { get; set; } + /// + /// A Boolean value that specifies whether the ImageFileName member contains the exact file name that is used to open the process executable file. + /// + public bool FileOpenNameAvailable { get; set; } + /// + /// The file name of the executable. If the FileOpenNameAvailable member is TRUE, the string specifies the exact file name that is used to open the executable file. + /// If FileOpenNameAvailable is FALSE, the operating system might provide only a partial name. + /// + public string ImageFileName { get; set; } + /// + /// The command that is used to execute the process. + /// + public string CommandLine { get; set; } + + } + + + +} diff --git a/Demo_Source_Code/CSharpDemo/FilterControl/Properties/AssemblyInfo.cs b/Demo_Source_Code/CSharpDemo/FilterControl/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..91916ce --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FilterControl/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("FilterControl")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("FilterControl")] +[assembly: AssemblyCopyright("Copyright © 2024")] +[assembly: AssemblyTrademark("EaseFilter")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("47e1b264-38bb-4890-989c-645960c6e23a")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("5.4.6.2001")] +//[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Demo_Source_Code/CSharpDemo/FilterControl/RegistryFilter.cs b/Demo_Source_Code/CSharpDemo/FilterControl/RegistryFilter.cs new file mode 100644 index 0000000..cb608c4 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FilterControl/RegistryFilter.cs @@ -0,0 +1,1362 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using System.Text; +using System.IO; + +namespace EaseFilter.FilterControl +{ + public class RegistryFilter : Filter + { + + private string processNameFilterMask = string.Empty; + private string userName = string.Empty; + private string registryKeyNameFilterMask = string.Empty; + + List excludeProcessNameList = new List(); + List excludeUserNameList = new List(); + List excludeKeyNameList = new List(); + + /// + /// Exclude the process name to the registry filter rule. + /// + public List ExcludeProcessNameList + { + get { return excludeProcessNameList; } + set { excludeProcessNameList = value; } + } + + /// + /// Exclude the user name to the registry filter rule. + /// + public List ExcludeUserNameList + { + get { return excludeUserNameList; } + set { excludeUserNameList = value; } + } + + /// + /// Exclude the key name to the registry filter rule. + /// + public List ExcludeKeyNameList + { + get { return excludeKeyNameList; } + set { excludeKeyNameList = value; } + } + /// + /// Control the registry access for the process with this process Id. + /// + public uint ProcessId { get; set; } + + /// + /// Control the registry access for the process with this process name if the process Id is 0, or it will skip it. + /// + public string ProcessNameFilterMask { get { return processNameFilterMask; } set { processNameFilterMask = value; } } + + /// + /// Control the registry access for the process with this user name + /// + public string UserName { get { return userName; } set { userName = value; } } + + /// + /// Filter the registry access based on the key name filter mask if it was set + /// + public string RegistryKeyNameFilterMask { get { return registryKeyNameFilterMask; } set { registryKeyNameFilterMask = value; } } + + /// + /// The the flag to control how to access the registry for the matched process or user + /// + public uint ControlFlag { get; set; } + + /// + /// Register the callback when the registry access notification was triggered + /// + public ulong RegCallbackClass { get; set; } + + /// + /// If it is true, the registry access from the matched process or user will be excluded. + /// + public bool IsExcludeFilter { get; set; } + + + /// + ///Fires this notification event after the registry request was returned.. + /// + /// + public event EventHandler NotifyRegWasBlocked; + public event EventHandler NotifyDeleteKey; + public event EventHandler NotifySetValueKey; + public event EventHandler NotifyDeleteValueKey; + public event EventHandler NotifySetInformationKey; + public event EventHandler NotifyRenameKey; + public event EventHandler NotifyEnumerateKey; + public event EventHandler NotifyEnumerateValueKey; + public event EventHandler NotifyQueryKey; + public event EventHandler NotifyQueryValueKey; + public event EventHandler NotifyQueryMultipleValueKey; + public event EventHandler NotifyCreateKey; + public event EventHandler NotifyOpenKey; + public event EventHandler NotifyKeyHandleClose; + public event EventHandler NotifyCreateKeyEx; + public event EventHandler NotifyOpenKeyEx; + public event EventHandler NotifyFlushKey; + public event EventHandler NotifyLoadKey; + public event EventHandler NotifyUnLoadKey; + public event EventHandler NotifyQueryKeySecurity; + public event EventHandler NotifySetKeySecurity; + public event EventHandler NotifyRestoreKey; + public event EventHandler NotifySaveKey; + public event EventHandler NotifyReplaceKey; + public event EventHandler NotifyQueryKeyName; + + /// + /// Fire the control event before the registry request was going to the registry handler. + /// + public event EventHandler OnPreDeleteKey; + public event EventHandler OnPreSetValueKey; + public event EventHandler OnPreDeleteValueKey; + public event EventHandler OnPreSetInformationKey; + public event EventHandler OnPreRenameKey; + public event EventHandler OnPreEnumerateKey; + public event EventHandler OnPreEnumerateValueKey; + public event EventHandler OnPreQueryKey; + public event EventHandler OnPreQueryValueKey; + public event EventHandler OnPreQueryMultipleValueKey; + public event EventHandler OnPreCreateKey; + public event EventHandler OnPreOpenKey; + public event EventHandler OnPreKeyHandleClose; + public event EventHandler OnPreCreateKeyEx; + public event EventHandler OnPreOpenKeyEx; + public event EventHandler OnPreFlushKey; + public event EventHandler OnPreLoadKey; + public event EventHandler OnPreUnLoadKey; + public event EventHandler OnPreQueryKeySecurity; + public event EventHandler OnPreSetKeySecurity; + public event EventHandler OnPreRestoreKey; + public event EventHandler OnPreSaveKey; + public event EventHandler OnPreReplaceKey; + public event EventHandler OnPreQueryKeyName; + + public RegistryFilter() + { + this.FilterType = FilterAPI.FilterType.REGISTRY_FILTER; + } + + public override void SendNotification(FilterAPI.MessageSendData messageSend) + { + try + { + RegistryEventArgs registryEventArgs = new RegistryEventArgs(messageSend); + + if (messageSend.FilterCommand == (uint)FilterAPI.FilterCommand.FILTER_SEND_DENIED_REGISTRY_ACCESS_EVENT) + { + if (null != NotifyRegWasBlocked) + { + registryEventArgs.EventName = "NotifyRegWasBlocked"; + NotifyRegWasBlocked(this, registryEventArgs); + } + + return; + } + + switch (registryEventArgs.RegCallbackClass) + { + + case FilterAPI.RegCallbackClass.Reg_Post_Delete_Key: + { + if (null != NotifyDeleteKey) + { + registryEventArgs.EventName = "NotifyDeleteKey"; + NotifyDeleteKey(this, registryEventArgs); + } + + break; + } + + case FilterAPI.RegCallbackClass.Reg_Post_Set_Value_Key: + { + if (null != NotifySetValueKey) + { + registryEventArgs.EventName = "NotifySetValueKey"; + NotifySetValueKey(this, registryEventArgs); + } + + break; + } + + case FilterAPI.RegCallbackClass.Reg_Post_Delete_Value_Key: + { + if (null != NotifyDeleteValueKey) + { + registryEventArgs.EventName = "NotifyDeleteValueKey"; + NotifyDeleteValueKey(this, registryEventArgs); + } + + break; + } + + case FilterAPI.RegCallbackClass.Reg_Post_SetInformation_Key: + { + if (null != NotifySetInformationKey) + { + registryEventArgs.EventName = "NotifySetInformationKey"; + NotifySetInformationKey(this, registryEventArgs); + } + + break; + } + + case FilterAPI.RegCallbackClass.Reg_Post_Rename_Key: + { + if (null != NotifyRenameKey) + { + registryEventArgs.EventName = "NotifyRenameKey"; + NotifyRenameKey(this, registryEventArgs); + } + + break; + } + + case FilterAPI.RegCallbackClass.Reg_Post_Enumerate_Key: + { + if (null != NotifyEnumerateKey) + { + registryEventArgs.EventName = "NotifyEnumerateKey"; + NotifyEnumerateKey(this, registryEventArgs); + } + + break; + } + + case FilterAPI.RegCallbackClass.Reg_Post_Enumerate_Value_Key: + { + if (null != NotifyEnumerateValueKey) + { + registryEventArgs.EventName = "NotifyEnumerateValueKey"; + NotifyEnumerateValueKey(this, registryEventArgs); + } + + break; + } + + case FilterAPI.RegCallbackClass.Reg_Post_Query_Key: + { + if (null != NotifyQueryKey) + { + registryEventArgs.EventName = "NotifyQueryKey"; + NotifyQueryKey(this, registryEventArgs); + } + + break; + } + + case FilterAPI.RegCallbackClass.Reg_Post_Query_Value_Key: + { + if (null != NotifyQueryValueKey) + { + registryEventArgs.EventName = "NotifyQueryValueKey"; + NotifyQueryValueKey(this, registryEventArgs); + } + + break; + } + + case FilterAPI.RegCallbackClass.Reg_Post_Query_Multiple_Value_Key: + { + if (null != NotifyQueryMultipleValueKey) + { + registryEventArgs.EventName = "NotifyQueryMultipleValueKey"; + NotifyQueryMultipleValueKey(this, registryEventArgs); + } + + break; + } + + case FilterAPI.RegCallbackClass.Reg_Post_Create_Key: + { + if (null != NotifyCreateKey) + { + registryEventArgs.EventName = "NotifyCreateKey"; + NotifyCreateKey(this, registryEventArgs); + } + + break; + } + + case FilterAPI.RegCallbackClass.Reg_Post_Open_Key: + { + if (null != NotifyOpenKey) + { + registryEventArgs.EventName = "NotifyOpenKey"; + NotifyOpenKey(this, registryEventArgs); + } + + break; + } + + case FilterAPI.RegCallbackClass.Reg_Post_Key_Handle_Close: + { + if (null != NotifyKeyHandleClose) + { + registryEventArgs.EventName = "NotifyKeyHandleClose"; + NotifyKeyHandleClose(this, registryEventArgs); + } + + break; + } + + case FilterAPI.RegCallbackClass.Reg_Post_Create_KeyEx: + { + if (null != NotifyCreateKeyEx) + { + registryEventArgs.EventName = "NotifyCreateKeyEx"; + NotifyCreateKeyEx(this, registryEventArgs); + } + + break; + } + + case FilterAPI.RegCallbackClass.Reg_Post_Open_KeyEx: + { + if (null != NotifyOpenKeyEx) + { + registryEventArgs.EventName = "NotifyOpenKeyEx"; + NotifyOpenKeyEx(this, registryEventArgs); + } + + break; + } + + case FilterAPI.RegCallbackClass.Reg_Post_Flush_Key: + { + if (null != NotifyFlushKey) + { + registryEventArgs.EventName = "NotifyFlushKey"; + NotifyFlushKey(this, registryEventArgs); + } + + break; + } + + case FilterAPI.RegCallbackClass.Reg_Post_Load_Key: + { + if (null != NotifyLoadKey) + { + registryEventArgs.EventName = "NotifyLoadKey"; + NotifyLoadKey(this, registryEventArgs); + } + + break; + } + + case FilterAPI.RegCallbackClass.Reg_Post_UnLoad_Key: + { + if (null != NotifyUnLoadKey) + { + registryEventArgs.EventName = "NotifyUnLoadKey"; + NotifyUnLoadKey(this, registryEventArgs); + } + + break; + } + + case FilterAPI.RegCallbackClass.Reg_Post_Query_Key_Security: + { + if (null != NotifyQueryKeySecurity) + { + registryEventArgs.EventName = "NotifyQueryKeySecurity"; + NotifyQueryKeySecurity(this, registryEventArgs); + } + + break; + } + + case FilterAPI.RegCallbackClass.Reg_Post_Set_Key_Security: + { + if (null != NotifySetKeySecurity) + { + registryEventArgs.EventName = "NotifySetKeySecurity"; + NotifySetKeySecurity(this, registryEventArgs); + } + + break; + } + + + case FilterAPI.RegCallbackClass.Reg_Post_Restore_Key: + { + if (null != NotifyRestoreKey) + { + registryEventArgs.EventName = "NotifyRestoreKey"; + NotifyRestoreKey(this, registryEventArgs); + } + + break; + } + + case FilterAPI.RegCallbackClass.Reg_Post_Save_Key: + { + if (null != NotifySaveKey) + { + registryEventArgs.EventName = "NotifySaveKey"; + NotifySaveKey(this, registryEventArgs); + } + + break; + } + + case FilterAPI.RegCallbackClass.Reg_Post_Replace_Key: + { + if (null != NotifyReplaceKey) + { + registryEventArgs.EventName = "NotifyReplaceKey"; + NotifyReplaceKey(this, registryEventArgs); + } + + break; + } + + case FilterAPI.RegCallbackClass.Reg_Post_Query_KeyName: + { + if (null != NotifyQueryKeyName) + { + registryEventArgs.EventName = "NotifyQueryKeyName"; + NotifyQueryKeyName(this, registryEventArgs); + } + + break; + } + + default: break; + } + } + catch + { + } + } + + + public override bool ReplyMessage(FilterAPI.MessageSendData messageSend, IntPtr replyDataPtr) + { + bool retVal = true; + + try + { + FilterAPI.MessageReplyData messageReply = (FilterAPI.MessageReplyData)Marshal.PtrToStructure(replyDataPtr, typeof(FilterAPI.MessageReplyData)); + + RegistryEventArgs registryEventArgs = new RegistryEventArgs(messageSend); + + switch (registryEventArgs.RegCallbackClass) + { + case FilterAPI.RegCallbackClass.Reg_Pre_Delete_Key: + { + registryEventArgs.EventName = "OnPreDeleteKey"; + if (null != OnPreDeleteKey) + { + OnPreDeleteKey(this, registryEventArgs); + } + + break; + } + + case FilterAPI.RegCallbackClass.Reg_Pre_Set_Value_Key: + { + registryEventArgs.EventName = "OnPreSetValueKey"; + if (null != OnPreSetValueKey) + { + OnPreSetValueKey(this, registryEventArgs); + } + + break; + } + + case FilterAPI.RegCallbackClass.Reg_Pre_Delete_Value_Key: + { + registryEventArgs.EventName = "OnPreDeleteValueKey"; + if (null != OnPreDeleteValueKey) + { + OnPreDeleteValueKey(this, registryEventArgs); + } + + break; + } + + case FilterAPI.RegCallbackClass.Reg_Pre_SetInformation_Key: + { + registryEventArgs.EventName = "OnPreSetInformationKey"; + if (null != OnPreSetInformationKey) + { + OnPreSetInformationKey(this, registryEventArgs); + } + + break; + } + + case FilterAPI.RegCallbackClass.Reg_Pre_Rename_Key: + { + registryEventArgs.EventName = "OnPreRenameKey"; + if (null != OnPreRenameKey) + { + OnPreRenameKey(this, registryEventArgs); + } + + break; + } + + case FilterAPI.RegCallbackClass.Reg_Pre_Enumerate_Key: + { + registryEventArgs.EventName = "OnPreEnumerateKey"; + if (null != OnPreEnumerateKey) + { + OnPreEnumerateKey(this, registryEventArgs); + } + + break; + } + + case FilterAPI.RegCallbackClass.Reg_Pre_Enumerate_Value_Key: + { + registryEventArgs.EventName = "OnPreEnumerateValueKey"; + if (null != OnPreEnumerateValueKey) + { + OnPreEnumerateValueKey(this, registryEventArgs); + } + + break; + } + + case FilterAPI.RegCallbackClass.Reg_Pre_Query_Key: + { + registryEventArgs.EventName = "OnPreQueryKey"; + if (null != OnPreQueryKey) + { + OnPreQueryKey(this, registryEventArgs); + } + + break; + } + + case FilterAPI.RegCallbackClass.Reg_Pre_Query_Value_Key: + { + registryEventArgs.EventName = "OnPreQueryValueKey"; + if (null != OnPreQueryValueKey) + { + OnPreQueryValueKey(this, registryEventArgs); + } + + break; + } + + case FilterAPI.RegCallbackClass.Reg_Pre_Query_Multiple_Value_Key: + { + registryEventArgs.EventName = "OnPreQueryMultipleValueKey"; + if (null != OnPreQueryMultipleValueKey) + { + OnPreQueryMultipleValueKey(this, registryEventArgs); + } + + break; + } + + case FilterAPI.RegCallbackClass.Reg_Pre_Create_Key: + { + registryEventArgs.EventName = "OnPreCreateKey"; + if (null != OnPreCreateKey) + { + OnPreCreateKey(this, registryEventArgs); + } + + break; + } + + case FilterAPI.RegCallbackClass.Reg_Pre_Open_Key: + { + registryEventArgs.EventName = "OnPreOpenKey"; + if (null != OnPreOpenKey) + { + OnPreOpenKey(this, registryEventArgs); + } + + break; + } + + case FilterAPI.RegCallbackClass.Reg_Pre_Key_Handle_Close: + { + registryEventArgs.EventName = "OnPreKeyHandleClose"; + if (null != OnPreKeyHandleClose) + { + OnPreKeyHandleClose(this, registryEventArgs); + } + + break; + } + + case FilterAPI.RegCallbackClass.Reg_Pre_Create_KeyEx: + { + registryEventArgs.EventName = "OnPreCreateKeyEx"; + if (null != OnPreCreateKeyEx) + { + OnPreCreateKeyEx(this, registryEventArgs); + } + + break; + } + + case FilterAPI.RegCallbackClass.Reg_Pre_Open_KeyEx: + { + registryEventArgs.EventName = "OnPreOpenKeyEx"; + if (null != OnPreOpenKeyEx) + { + OnPreOpenKeyEx(this, registryEventArgs); + } + + break; + } + + case FilterAPI.RegCallbackClass.Reg_Pre_Flush_Key: + { + registryEventArgs.EventName = "OnPreFlushKey"; + if (null != OnPreFlushKey) + { + OnPreFlushKey(this, registryEventArgs); + } + + break; + } + + case FilterAPI.RegCallbackClass.Reg_Pre_Load_Key: + { + registryEventArgs.EventName = "OnPreLoadKey"; + if (null != OnPreLoadKey) + { + OnPreLoadKey(this, registryEventArgs); + } + + break; + } + + case FilterAPI.RegCallbackClass.Reg_Pre_UnLoad_Key: + { + registryEventArgs.EventName = "OnPreUnLoadKey"; + if (null != OnPreUnLoadKey) + { + OnPreLoadKey(this, registryEventArgs); + } + + break; + } + + case FilterAPI.RegCallbackClass.Reg_Pre_Query_Key_Security: + { + registryEventArgs.EventName = "OnPreQueryKeySecurity"; + if (null != OnPreQueryKeySecurity) + { + OnPreQueryKeySecurity(this, registryEventArgs); + } + + break; + } + + case FilterAPI.RegCallbackClass.Reg_Pre_Set_Key_Security: + { + registryEventArgs.EventName = "OnPreSetKeySecurity"; + if (null != OnPreSetKeySecurity) + { + OnPreSetKeySecurity(this, registryEventArgs); + } + + break; + } + + case FilterAPI.RegCallbackClass.Reg_Pre_Restore_Key: + { + registryEventArgs.EventName = "OnPreRestoreKey"; + if (null != OnPreRestoreKey) + { + OnPreRestoreKey(this, registryEventArgs); + } + + break; + } + + case FilterAPI.RegCallbackClass.Reg_Pre_Save_Key: + { + registryEventArgs.EventName = "OnPreSaveKey"; + if (null != OnPreSaveKey) + { + OnPreSaveKey(this, registryEventArgs); + } + + break; + } + + case FilterAPI.RegCallbackClass.Reg_Pre_Replace_Key: + { + registryEventArgs.EventName = "OnPreReplaceKey"; + if (null != OnPreReplaceKey) + { + OnPreReplaceKey(this, registryEventArgs); + } + + break; + + } + + case FilterAPI.RegCallbackClass.Reg_Pre_Query_KeyName: + { + registryEventArgs.EventName = "OnPreQueryKeyName"; + if (null != OnPreQueryKeyName) + { + OnPreQueryKeyName(this, registryEventArgs); + } + + break; + } + + default: break; + } + + if (registryEventArgs.ReturnStatus != NtStatus.Status.Success) + { + messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION; + messageReply.ReturnStatus = (uint)registryEventArgs.ReturnStatus; + } + else if (registryEventArgs.IsDataModified) + { + Array.Copy(registryEventArgs.ReturnDataBuffer, messageReply.DataBuffer, registryEventArgs.ReturnDataBuffer.Length); + messageReply.DataBufferLength = (uint)registryEventArgs.ReturnDataBuffer.Length; + + messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION | (uint)FilterAPI.FilterStatus.FILTER_DATA_BUFFER_IS_UPDATED; + messageReply.ReturnStatus = (uint)registryEventArgs.ReturnStatus; + } + + Marshal.StructureToPtr(messageReply, replyDataPtr, true); + } + catch + { + } + + return retVal; + } + } + + public enum VALUE_DATA_TYPE : uint + { + REG_NONE = 0, + REG_SZ = 1, + REG_EXPAND_SZ = 2, + REG_BINARY = 3, + REG_DWORD = 4, + REG_DWORD_BIG_ENDIAN = 5, + REG_LINK = 6, + REG_MULTI_SZ = 7, + REG_RESOURCE_LIST = 8, + REG_FULL_RESOURCE_DESCRIPTOR = 9, + REG_RESOURCE_REQUIREMENTS_LIST = 10, + REG_QWORD = 11 + } + + public enum KEY_VALUE_INFORMATION_CLASS : uint + { + KeyValueBasicInformation = 0, + KeyValueFullInformation = 1, + KeyValuePartialInformation = 2, + KeyValueFullInformationAlign64 = 3, + KeyValuePartialInformationAlign64 = 4, + MaxKeyValueInfoClass = 5 + } + + public struct KEY_VALUE_BASIC_INFORMATION + { + public uint TitleIndex; + public uint Type; + public uint NameLength; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 65536 - 12)] + public byte[] Name; + } + public struct KEY_VALUE_FULL_INFORMATION + { + public uint TitleIndex; + public uint Type; + public uint DataOffset; + public uint DataLength; + public uint NameLength; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 65536 - 20)] + public byte[] Name; + } + + public struct KEY_VALUE_PARTIAL_INFORMATION + { + public uint TitleIndex; + public uint Type; + public uint DataLength; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 65536 - 12)] + public byte[] Data; + } + + public struct KEY_VALUE_ENTRY + { + public uint NextEntryOffset; + public uint ValueNameLength; + public uint DataType; + public uint DataLength; + public byte[] ValueName; + //public byte[] Data; + } + + public enum KEY_SET_INFORMATION_CLASS : uint + { + KeyWriteTimeInformation = 0, + KeyWow64FlagsInformation, + KeyControlFlagsInformation, + KeySetVirtualizationInformation, + KeySetDebugInformation, + KeySetHandleTagsInformation, + MaxKeySetInfoClass // MaxKeySetInfoClass should always be the last enum + } + public enum KEY_INFORMATION_CLASS : uint + { + KeyBasicInformation = 0, + KeyNodeInformation, + KeyFullInformation, + KeyNameInformation, + KeyCachedInformation, + KeyFlagsInformation, + KeyVirtualizationInformation, + KeyHandleTagsInformation, + KeyTrustInformation, + KeyLayerInformation, + MaxKeyInfoClass + } + + public struct KEY_BASIC_INFORMATION + { + public long LastWriteTime; + public uint TitleIndex; + public uint NameLength; + public byte[] Name; + } + + public struct KEY_NODE_INFORMATION + { + public long LastWriteTime; + public uint TitleIndex; + public uint ClassOffset; + public uint ClassLength; + public uint NameLength; + public byte[] Name; + } + + public struct KEY_FULL_INFORMATION + { + public long LastWriteTime; + public uint TitleIndex; + public uint ClassOffset; + public uint ClassLength; + public uint SubKeys; + public uint MaxNameLen; + public uint MaxClassLen; + public uint Values; + public uint MaxValueNameLen; + public uint MaxValueDataLen; + public byte[] Class; + } + + public struct KEY_NAME_INFORMATION + { + public uint NameLength; + public byte[] Name; + } + + public struct KEY_CACHED_INFORMATION + { + public long LastWriteTime; + public uint TitleIndex; + public uint SubKeys; + public uint MaxNameLen; + public uint MaxClassLen; + public uint Values; + public uint MaxValueNameLen; + public uint MaxValueDataLen; + public uint NameLength; + } + + public struct KEY_VIRTUALIZATION_INFORMATION + { + public bool VirtualizationCandidate; + public bool VirtualizationEnabled; + public bool VirtualTarget; + public bool VirtualStore; + public bool VirtualSource; + } + + public enum REG_ACCESS_MASK : uint + { + KEY_QUERY_VALUE = 1, + KEY_SET_VALUE = 2, + KEY_CREATE_SUB_KEY = 4, + KEY_ENUMERATE_SUB_KEYS = 8, + KEY_NOTIFY = 16, + KEY_CREATE_LINK = 32, + KEY_WRITE = 131078, + KEY_EXECUTE = 131097, + KEY_READ = 131097, + KEY_ALL_ACCESS = 983103, + } + + public enum REG_CREATE_OPTIONS : uint + { + REG_OPTION_VOLATILE = 0x00000001, // Key is not preserved when system is rebooted + REG_OPTION_CREATE_LINK = 0x00000002, // Created key is a symbolic link + REG_OPTION_BACKUP_RESTORE = 0x00000004, // open for backup or restore special access rules privilege required + REG_OPTION_OPEN_LINK = 0x00000008, // Open symbolic link + } + + public enum REG_DISPOSITION + { + REG_CREATED_NEW_KEY = 0x00000001, // New Registry Key created + REG_OPENED_EXISTING_KEY = 0x00000002, // Existing Key opened + } + + public class RegistryEventArgs : FileIOEventArgs + { + private static string ValueTypeData(VALUE_DATA_TYPE type, int dataSize, byte[] data) + { + string dataStr = string.Empty; + + try + { + switch (type) + { + case VALUE_DATA_TYPE.REG_BINARY: + { + //maximum data size to 256; + for (int i = 0; i < 256; i++) + { + if (i >= dataSize) + { + break; + } + + dataStr += string.Format("0x{0:x2}", data[i]); + + } + + break; + } + case VALUE_DATA_TYPE.REG_DWORD: + { + uint value = BitConverter.ToUInt32(data, 0); + dataStr = string.Format("0x{0:x8}({1})", value, value); + break; + } + case VALUE_DATA_TYPE.REG_DWORD_BIG_ENDIAN: + { + //A 4-byte numerical value whose least significant byte is at the highest address + byte leastByte = data[3]; + byte secondByte = data[2]; + data[3] = data[0]; + data[2] = data[1]; + data[1] = secondByte; + data[0] = leastByte; + + uint value = BitConverter.ToUInt32(data, 0); + dataStr = string.Format("0x{0:x8}({1})", value, value); + + break; + } + case VALUE_DATA_TYPE.REG_EXPAND_SZ: + { + //A null-terminated Unicode string, containing unexpanded references to environment variables, such as "%PATH%" + dataStr = Encoding.Unicode.GetString(data, 0, dataSize).Replace("\0", ""); + break; + } + case VALUE_DATA_TYPE.REG_MULTI_SZ: + { + //An array of null-terminated strings, terminated by another zero + dataStr = Encoding.Unicode.GetString(data, 0, dataSize).Replace("\0", ""); + break; + } + case VALUE_DATA_TYPE.REG_SZ: + { + //A null-terminated Unicode string + dataStr = Encoding.Unicode.GetString(data, 0, dataSize).Replace("\0", ""); + break; + } + case VALUE_DATA_TYPE.REG_QWORD: + { + UInt64 value = BitConverter.ToUInt64(data, 0); + dataStr = string.Format("0x{0:x16}({1})", value, value); + break; + } + + default: break; + } + } + catch (Exception ex) + { + dataStr = "get data failed:" + ex.Message; + } + + + return dataStr; + } + + private static string KeyInformation(KEY_INFORMATION_CLASS keyInfoClass, byte[] keyInformation) + { + string keyInfoStr = "(" + keyInfoClass.ToString() + ") "; + + try + { + MemoryStream ms = new MemoryStream(keyInformation); + BinaryReader br = new BinaryReader(ms); + + switch (keyInfoClass) + { + case KEY_INFORMATION_CLASS.KeyBasicInformation: + { + long lastWriteTime = br.ReadInt64(); + uint titleIndex = br.ReadUInt32(); + uint nameLength = br.ReadUInt32(); + string name = Encoding.Unicode.GetString(keyInformation, (int)ms.Position, (int)nameLength); + + keyInfoStr += "LastWriteTime:" + DateTime.FromFileTime(lastWriteTime).ToShortDateString(); + keyInfoStr += " Name:" + name; + + break; + } + case KEY_INFORMATION_CLASS.KeyNodeInformation: + { + long lastWriteTime = br.ReadInt64(); + uint titleIndex = br.ReadUInt32(); + uint classOffset = br.ReadUInt32(); + uint classLength = br.ReadUInt32(); + uint nameLength = br.ReadUInt32(); + string name = Encoding.Unicode.GetString(keyInformation, (int)ms.Position, (int)nameLength); + string className = Encoding.Unicode.GetString(keyInformation, (int)classOffset, (int)classLength); + + keyInfoStr += "LastWriteTime:" + DateTime.FromFileTime(lastWriteTime).ToShortDateString(); + keyInfoStr += " Name:" + name + " ClassName:" + className; + + break; + } + case KEY_INFORMATION_CLASS.KeyFullInformation: + { + long lastWriteTime = br.ReadInt64(); + uint titleIndex = br.ReadUInt32(); + uint classOffset = br.ReadUInt32(); + uint classLength = br.ReadUInt32(); + uint subKeys = br.ReadUInt32(); + uint maxNameLen = br.ReadUInt32(); + uint maxClassLen = br.ReadUInt32(); + uint values = br.ReadUInt32(); + uint maxValueNameLen = br.ReadUInt32(); + uint maxValueDataLen = br.ReadUInt32(); + uint nameLength = br.ReadUInt32(); + string className = Encoding.Unicode.GetString(keyInformation, (int)classOffset, (int)classLength); + + keyInfoStr += "LastWriteTime:" + DateTime.FromFileTime(lastWriteTime).ToShortDateString(); + keyInfoStr += " subKeys:" + subKeys + " valueEntries:" + values + " ClassName:" + className; + + break; + } + case KEY_INFORMATION_CLASS.KeyNameInformation: + { + uint nameLength = br.ReadUInt32(); + string name = Encoding.Unicode.GetString(keyInformation, (int)ms.Position, (int)nameLength); + keyInfoStr += " Name:" + name; + + break; + } + + + default: break; + } + } + catch (Exception ex) + { + keyInfoStr = "get data failed:" + ex.Message; + } + + + return keyInfoStr; + } + + private static string KeyValueInformation(KEY_VALUE_INFORMATION_CLASS keyValueInfoClass, byte[] keyValueInformation) + { + string keyValueInfoStr = string.Empty; + + try + { + MemoryStream ms = new MemoryStream(keyValueInformation); + BinaryReader br = new BinaryReader(ms); + + switch (keyValueInfoClass) + { + case KEY_VALUE_INFORMATION_CLASS.KeyValueBasicInformation: + { + int titleIndex = br.ReadInt32(); + int type = br.ReadInt32(); + int nameLength = br.ReadInt32(); + keyValueInfoStr = "(" + keyValueInfoClass.ToString() + ") Name:" + Encoding.Unicode.GetString(keyValueInformation, (int)ms.Position, nameLength); + + break; + } + case KEY_VALUE_INFORMATION_CLASS.KeyValueFullInformation: + { + int titleIndex = br.ReadInt32(); + int type = br.ReadInt32(); + int dataOffset = br.ReadInt32(); + int dataLength = br.ReadInt32(); + int nameLength = br.ReadInt32(); + keyValueInfoStr = "(" + keyValueInfoClass.ToString() + ") Name:" + Encoding.Unicode.GetString(keyValueInformation, (int)ms.Position, nameLength); + keyValueInfoStr += " Type:" + ((VALUE_DATA_TYPE)type).ToString(); + + byte[] dataBuffer = new byte[dataLength]; + Array.Copy(keyValueInformation, dataOffset, dataBuffer, 0, dataBuffer.Length); + + keyValueInfoStr += " Data:" + ValueTypeData((VALUE_DATA_TYPE)type, dataBuffer.Length, dataBuffer); + + break; + } + case KEY_VALUE_INFORMATION_CLASS.KeyValuePartialInformation: + { + int titleIndex = br.ReadInt32(); + int type = br.ReadInt32(); + int dataLength = br.ReadInt32(); + keyValueInfoStr += "(" + keyValueInfoClass.ToString() + ") Type:" + ((VALUE_DATA_TYPE)type).ToString(); + + byte[] dataBuffer = new byte[dataLength]; + Array.Copy(keyValueInformation, ms.Position, dataBuffer, 0, dataBuffer.Length); + keyValueInfoStr += " Data:" + ValueTypeData((VALUE_DATA_TYPE)type, dataBuffer.Length, dataBuffer); + + break; + } + + + default: break; + } + } + catch (Exception ex) + { + keyValueInfoStr = "get data failed:" + ex.Message; + } + + + return keyValueInfoStr; + } + + public RegistryEventArgs(FilterAPI.MessageSendData messageSend) + : base(messageSend) + { + RegCallbackClass = (FilterAPI.RegCallbackClass)messageSend.MessageType; + InfoClass = messageSend.InfoClass; + + if (messageSend.Status != (uint)NtStatus.Status.Success) + { + NtStatus.Status status = (NtStatus.Status)messageSend.Status; + description = "Registry access notification class " + RegCallbackClass.ToString() + " failed, status: " + status.ToString(); + } + else + { + switch (RegCallbackClass) + { + case FilterAPI.RegCallbackClass.Reg_Pre_Create_KeyEx: + case FilterAPI.RegCallbackClass.Reg_Post_Create_KeyEx: + case FilterAPI.RegCallbackClass.Reg_Pre_Open_KeyEx: + case FilterAPI.RegCallbackClass.Reg_Post_Open_KeyEx: + { + description = CreateOptions.ToString(); + break; + } + case FilterAPI.RegCallbackClass.Reg_Pre_Delete_Key: + case FilterAPI.RegCallbackClass.Reg_Post_Delete_Key: + { + description = "registry key is being deleted."; + break; + } + case FilterAPI.RegCallbackClass.Reg_Pre_Set_Value_Key: + case FilterAPI.RegCallbackClass.Reg_Post_Set_Value_Key: + { + VALUE_DATA_TYPE valueType = (VALUE_DATA_TYPE)messageSend.InfoClass; + description = "Type:" + valueType.ToString(); + description += " Data:" + ValueTypeData(valueType, (int)messageSend.DataBufferLength, messageSend.DataBuffer); + break; + } + case FilterAPI.RegCallbackClass.Reg_Pre_Delete_Value_Key: + case FilterAPI.RegCallbackClass.Reg_Post_Delete_Value_Key: + { + description = "registry key's value is being deleted."; + break; + } + case FilterAPI.RegCallbackClass.Reg_Pre_SetInformation_Key: + case FilterAPI.RegCallbackClass.Reg_Post_SetInformation_Key: + { + KEY_SET_INFORMATION_CLASS keySetInformationClass = (KEY_SET_INFORMATION_CLASS)messageSend.InfoClass; + description = keySetInformationClass.ToString(); + break; + } + case FilterAPI.RegCallbackClass.Reg_Pre_Rename_Key: + case FilterAPI.RegCallbackClass.Reg_Post_Rename_Key: + { + string newName = Encoding.Unicode.GetString(messageSend.DataBuffer); + description = "registry key's name is being changed to " + newName; + break; + } + case FilterAPI.RegCallbackClass.Reg_Pre_Enumerate_Key: + { + KEY_INFORMATION_CLASS keyInformationClass = (KEY_INFORMATION_CLASS)messageSend.InfoClass; + description = keyInformationClass.ToString(); + + break; + } + case FilterAPI.RegCallbackClass.Reg_Post_Enumerate_Key: + { + KEY_INFORMATION_CLASS keyInformationClass = (KEY_INFORMATION_CLASS)messageSend.InfoClass; + description += KeyInformation(keyInformationClass, messageSend.DataBuffer); + + break; + } + case FilterAPI.RegCallbackClass.Reg_Pre_Enumerate_Value_Key: + { + KEY_VALUE_INFORMATION_CLASS keyValuseInformationClass = (KEY_VALUE_INFORMATION_CLASS)messageSend.InfoClass; + description = keyValuseInformationClass.ToString(); + + break; + } + case FilterAPI.RegCallbackClass.Reg_Post_Enumerate_Value_Key: + { + KEY_VALUE_INFORMATION_CLASS keyValuseInformationClass = (KEY_VALUE_INFORMATION_CLASS)messageSend.InfoClass; + description += KeyValueInformation(keyValuseInformationClass, messageSend.DataBuffer); + + break; + } + case FilterAPI.RegCallbackClass.Reg_Pre_Query_Key: + { + KEY_INFORMATION_CLASS keyInformationClass = (KEY_INFORMATION_CLASS)messageSend.InfoClass; + description = keyInformationClass.ToString(); + + break; + } + case FilterAPI.RegCallbackClass.Reg_Post_Query_Key: + { + KEY_INFORMATION_CLASS keyInformationClass = (KEY_INFORMATION_CLASS)messageSend.InfoClass; + description += KeyInformation(keyInformationClass, messageSend.DataBuffer); + + break; + } + case FilterAPI.RegCallbackClass.Reg_Pre_Query_Value_Key: + { + KEY_VALUE_INFORMATION_CLASS keyValuseInformationClass = (KEY_VALUE_INFORMATION_CLASS)messageSend.InfoClass; + description = keyValuseInformationClass.ToString(); + + break; + } + case FilterAPI.RegCallbackClass.Reg_Post_Query_Value_Key: + { + KEY_VALUE_INFORMATION_CLASS keyValuseInformationClass = (KEY_VALUE_INFORMATION_CLASS)messageSend.InfoClass; + description += KeyValueInformation(keyValuseInformationClass, messageSend.DataBuffer); + + break; + } + case FilterAPI.RegCallbackClass.Reg_Pre_Query_Multiple_Value_Key: + { + break; + } + case FilterAPI.RegCallbackClass.Reg_Post_Query_Multiple_Value_Key: + { + uint entryCount = messageSend.InfoClass; + + MemoryStream ms = new MemoryStream(messageSend.DataBuffer); + BinaryReader br = new BinaryReader(ms); + + for (int i = 0; i < entryCount && ms.Position < ms.Length; i++) + { + long currentOffset = ms.Position; + int nextEntryOffset = br.ReadInt32(); + int valueNameLength = br.ReadInt32(); + int dataType = br.ReadInt32(); + int dataLength = br.ReadInt32(); + byte[] valueName = br.ReadBytes(valueNameLength); + byte[] data = br.ReadBytes(dataLength); + + VALUE_DATA_TYPE type = (VALUE_DATA_TYPE)dataType; + description += "Name:" + Encoding.Unicode.GetString(valueName, 0, valueNameLength); + description += " Type:" + type.ToString(); + description += " Data:" + ValueTypeData(type, dataLength, data) + Environment.NewLine; + + ms.Position = currentOffset + nextEntryOffset; + + } + + break; + } + + case FilterAPI.RegCallbackClass.Reg_Pre_Load_Key: + case FilterAPI.RegCallbackClass.Reg_Post_Load_Key: + { + description += "SourceFile:" + Encoding.Unicode.GetString(messageSend.DataBuffer, 0, (int)messageSend.DataBufferLength); + break; + } + case FilterAPI.RegCallbackClass.Reg_Pre_Replace_Key: + case FilterAPI.RegCallbackClass.Reg_Post_Replace_Key: + { + description += "NewFileName:" + Encoding.Unicode.GetString(messageSend.DataBuffer, 0, (int)messageSend.DataBufferLength); + break; + } + + case FilterAPI.RegCallbackClass.Reg_Pre_Query_KeyName: + case FilterAPI.RegCallbackClass.Reg_Post_Query_KeyName: + { + break; + } + } + } + + } + + /// + ///The registry callback class. + /// + public FilterAPI.RegCallbackClass RegCallbackClass { get; set; } + /// + /// The Key Information class. + /// + public uint InfoClass { get; set; } + + private string description = string.Empty; + + /// + /// The description of the IO args + /// + public override string Description + { + get { return description; } + } + + /// + /// The data buffer which will return back to the driver. + /// + public byte[] ReturnDataBuffer { get; set; } + + } + + +} diff --git a/Demo_Source_Code/CSharpDemo/FilterControl/Utils.cs b/Demo_Source_Code/CSharpDemo/FilterControl/Utils.cs new file mode 100644 index 0000000..8be08c7 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FilterControl/Utils.cs @@ -0,0 +1,716 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.Collections.Generic; +using Microsoft.Win32.SafeHandles; +using System.Runtime.InteropServices; +using System.Security.Principal; +using System.Security.Cryptography; +using System.Reflection; +using System.Globalization; +using System.IO; +using System.Text; +using System.Configuration; +using System.Text.RegularExpressions; +using System.Xml.Serialization; + +namespace EaseFilter.FilterControl +{ + + public class Utils + { + static Dictionary userNameTable = new Dictionary(); + static Dictionary processNameTable = new Dictionary(); + + + [DllImport("FilterAPI.dll", SetLastError = true)] + private static extern bool CreateFileAPI( + [MarshalAs(UnmanagedType.LPWStr)]string fileName, + uint dwDesiredAccess, + uint dwShareMode, + uint dwCreationDisposition, + uint dwFlagsAndAttributes, + ref IntPtr fileHandle); + + public enum EncryptType + { + Decryption = 0, + Encryption, + } + + public static string AESEncryptDecryptStr(string inStr, EncryptType encryptType) + { + + if (string.IsNullOrEmpty(inStr)) + { + return string.Empty; + } + + byte[] inbuffer = null; + + if (encryptType == EncryptType.Encryption) + { + inbuffer = ASCIIEncoding.UTF8.GetBytes(inStr); + } + else if (encryptType == EncryptType.Decryption) + { + inbuffer = Convert.FromBase64String(inStr); + } + else + { + throw new Exception("Failed to encrypt decrypt string, the encryptType " + encryptType.ToString() + " doesn't know."); + } + + byte[] outBuffer = new byte[inbuffer.Length]; + + GCHandle gcHandleIn = GCHandle.Alloc(inbuffer, GCHandleType.Pinned); + GCHandle gcHandleOut = GCHandle.Alloc(outBuffer, GCHandleType.Pinned); + + IntPtr inBufferPtr = Marshal.UnsafeAddrOfPinnedArrayElement(inbuffer, 0); + IntPtr outBufferPtr = Marshal.UnsafeAddrOfPinnedArrayElement(outBuffer, 0); + + try + { + bool retVal = FilterAPI.AESEncryptDecryptBuffer(inBufferPtr, outBufferPtr, (uint)inbuffer.Length, 0, null, 0, null, 0); + + if (encryptType == EncryptType.Encryption) + { + return Convert.ToBase64String(outBuffer); + } + else //if (encryptType == EncryptType.Decryption) + { + return ASCIIEncoding.UTF8.GetString(outBuffer); + } + } + finally + { + gcHandleIn.Free(); + gcHandleOut.Free(); + } + + } + + + public static void AESEncryptDecryptBuffer(byte[] inbuffer, long offset, byte[] key, byte[] IV) + { + if (null == inbuffer || inbuffer.Length == 0) + { + throw new Exception("Failed to encrypt decrypt buffer, the input buffer can't be null"); + } + + GCHandle gcHandle = GCHandle.Alloc(inbuffer, GCHandleType.Pinned); + + try + { + IntPtr inBufferPtr = Marshal.UnsafeAddrOfPinnedArrayElement(inbuffer, 0); + + uint keyLength = 0; + uint IVLength = 0; + + if (key != null) + { + keyLength = (uint)key.Length; + } + + if (IV != null) + { + IVLength = (uint)IV.Length; + } + + + bool retVal = FilterAPI.AESEncryptDecryptBuffer(inBufferPtr, inBufferPtr, (uint)inbuffer.Length, offset, key, keyLength, IV, IVLength); + + if (!retVal) + { + throw new Exception("Failed to encrypt buffer, return error:" + FilterAPI.GetLastErrorMessage()); + } + } + finally + { + gcHandle.Free(); + } + + return; + } + + public static bool DecodeUserName(byte[] sid, out string userName) + { + bool ret = true; + + IntPtr sidStringPtr = IntPtr.Zero; + string sidString = string.Empty; + + userName = string.Empty; + + try + { + + IntPtr sidBuffer = Marshal.UnsafeAddrOfPinnedArrayElement(sid, 0); + + if (FilterAPI.ConvertSidToStringSid(sidBuffer, out sidStringPtr)) + { + + sidString = Marshal.PtrToStringAuto(sidStringPtr); + + lock (userNameTable) + { + //check the user name cache table + if (userNameTable.ContainsKey(sidString)) + { + userName = userNameTable[sidString]; + return ret; + } + } + + try + { + SecurityIdentifier secIdentifier = new SecurityIdentifier(sidString); + IdentityReference reference = secIdentifier.Translate(typeof(NTAccount)); + userName = reference.Value; + } + catch + { + } + + lock (userNameTable) + { + //check the user name cache table + if (!userNameTable.ContainsKey(sidString)) + { + userNameTable.Add(sidString, userName); + } + } + } + else + { + string errorMessage = "Convert sid to sid string failed with error " + Marshal.GetLastWin32Error(); + Console.WriteLine(errorMessage); + } + } + catch (Exception ex) + { + Console.WriteLine(string.Format("Convert sid to user name got exception:{0}", ex.Message)); + ret = false; + + } + finally + { + if (sidStringPtr != null && sidStringPtr != IntPtr.Zero) + { + FilterAPI.LocalFree(sidStringPtr); + } + } + + return ret; + } + + public static bool DecodeProcessName(uint processId, out string processName) + { + bool ret = true; + processName = string.Empty; + + + //this is the optimization of the process to get the process name from the process Id + //it is not reliable for this process, since the process Id is reuasble when the process was ternmiated. + lock (processNameTable) + { + if (processNameTable.ContainsKey(processId)) + { + processName = processNameTable[processId]; + return true; + } + } + + try + { + System.Diagnostics.Process requestProcess = System.Diagnostics.Process.GetProcessById((int)processId); + processName = requestProcess.ProcessName; + } + catch (Exception ex) + { + Console.WriteLine(string.Format("Convert pid to process name got exception:{0}", ex.Message)); + ret = false; + } + + lock (processNameTable) + { + if (!processNameTable.ContainsKey(processId)) + { + processNameTable.Add(processId, processName); + } + } + + return ret; + } + + public static bool IsDriverChanged() + { + bool ret = false; + + try + { + System.Reflection.Assembly assembly = System.Reflection.Assembly.GetEntryAssembly(); + string localPath = Path.GetDirectoryName(assembly.Location); + string driverName = Path.Combine(localPath, "EaseFlt.sys"); + + if (File.Exists(driverName)) + { + string driverInstalledPath = Path.Combine(Environment.SystemDirectory, "drivers\\easeflt.sys"); + + if (File.Exists(driverInstalledPath)) + { + FileInfo fsInstalled = new FileInfo(driverInstalledPath); + FileInfo fsToInstall = new FileInfo(driverName); + + if (fsInstalled.LastWriteTime != fsToInstall.LastWriteTime) + { + return true; + } + } + + } + + } + catch + { + ret = false; + } + + return ret; + } + + public static uint WinMajorVersion() + { + dynamic major; + // The 'CurrentMajorVersionNumber' string value in the CurrentVersion key is new for Windows 10, + // and will most likely (hopefully) be there for some time before MS decides to change this - again... + if (TryGeRegistryKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion", "CurrentMajorVersionNumber", out major)) + { + return (uint)major; + } + + // When the 'CurrentMajorVersionNumber' value is not present we fallback to reading the previous key used for this: 'CurrentVersion' + dynamic version; + if (!TryGeRegistryKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion", "CurrentVersion", out version)) + return 0; + + var versionParts = ((string)version).Split('.'); + if (versionParts.Length != 2) return 0; + + uint majorAsUInt; + return uint.TryParse(versionParts[0], out majorAsUInt) ? majorAsUInt : 0; + } + + /// + /// Returns the Windows minor version number for this computer. + /// + public static uint WinMinorVersion() + { + dynamic minor; + // The 'CurrentMinorVersionNumber' string value in the CurrentVersion key is new for Windows 10, + // and will most likely (hopefully) be there for some time before MS decides to change this - again... + if (TryGeRegistryKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion", "CurrentMinorVersionNumber", + out minor)) + { + return (uint)minor; + } + + // When the 'CurrentMinorVersionNumber' value is not present we fallback to reading the previous key used for this: 'CurrentVersion' + dynamic version; + if (!TryGeRegistryKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion", "CurrentVersion", out version)) + return 0; + + var versionParts = ((string)version).Split('.'); + if (versionParts.Length != 2) return 0; + uint minorAsUInt; + return uint.TryParse(versionParts[1], out minorAsUInt) ? minorAsUInt : 0; + } + + + private static bool TryGeRegistryKey(string path, string key, out dynamic value) + { + value = null; + try + { + var rk = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(path); + if (rk == null) return false; + value = rk.GetValue(key); + return value != null; + } + catch + { + return false; + } + } + + public static bool CopyOSPlatformDependentFiles(ref string lastError) + { + bool retVal = true; + + Assembly assembly = System.Reflection.Assembly.GetEntryAssembly(); + string localPath = Path.GetDirectoryName(assembly.Location); + string targetName = Path.Combine(localPath, "FilterAPI.DLL"); + + bool is64BitOperatingSystem = Environment.Is64BitOperatingSystem; + uint winMajorVersion = WinMajorVersion(); + uint winMinorVersion = WinMinorVersion(); + + string sourceFolder = localPath; + + try + { + + if (is64BitOperatingSystem) + { + sourceFolder = Path.Combine(localPath, "Bin\\x64"); + } + else + { + sourceFolder = Path.Combine(localPath, "Bin\\win32"); + } + + string sourceFile = Path.Combine(sourceFolder, "FilterAPI.DLL"); + + //only copy files for x86 platform, by default for x64, the files were there already. + + bool skipCopy = false; + if (File.Exists(targetName)) + { + FileInfo sourceFileInfo = new FileInfo(sourceFile); + FileInfo targetFileInfo = new FileInfo(targetName); + + if (sourceFileInfo.LastWriteTime.ToFileTime() == targetFileInfo.LastWriteTime.ToFileTime()) + { + skipCopy = true; + } + } + + if (!skipCopy) + { + File.Copy(sourceFile, targetName, true); + } + + + sourceFile = Path.Combine(sourceFolder, "EaseFlt.sys"); + targetName = Path.Combine(localPath, "EaseFlt.sys"); + + + skipCopy = false; + if (File.Exists(targetName)) + { + FileInfo sourceFileInfo = new FileInfo(sourceFile); + FileInfo targetFileInfo = new FileInfo(targetName); + + if (sourceFileInfo.LastWriteTime.ToFileTime() == targetFileInfo.LastWriteTime.ToFileTime()) + { + skipCopy = true; + } + } + + if (!skipCopy) + { + File.Copy(sourceFile, targetName, true); + } + + } + catch (Exception ex) + { + retVal = false; + lastError = "Copy platform dependent files 'FilterAPI.DLL' and 'EaseFlt.sys' to folder " + localPath + " got exception:" + ex.Message; + } + + return retVal; + } + + + public static string ByteArrayToHexStr(byte[] ba) + { + StringBuilder hex = new StringBuilder(ba.Length * 2); + foreach (byte b in ba) + { + hex.AppendFormat("{0:x2}", b); + } + + return hex.ToString().ToUpper(); + } + + public static byte[] ConvertHexStrToByteArray(string hexString) + { + if (hexString.Length % 2 != 0) + { + throw new ArgumentException(String.Format("The binary key cannot have an odd number of digits: {0}", hexString)); + } + + byte[] HexAsBytes = new byte[hexString.Length / 2]; + for (int index = 0; index < HexAsBytes.Length; index++) + { + string byteValue = hexString.Substring(index * 2, 2); + HexAsBytes[index] = byte.Parse(byteValue, NumberStyles.HexNumber, CultureInfo.InvariantCulture); + } + + return HexAsBytes; + } + + /// + /// Generate 32 bytes key array by pass phrase string + /// + /// + /// + public static byte[] GetKeyByPassPhrase(string pwStr,int keySize) + { + byte[] saltBytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 }; + byte[] passwordBytes = Encoding.UTF8.GetBytes(pwStr); + + if (0 == keySize) + { + keySize = 32; + } + + var rfckey = new Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000); + byte[] key = rfckey.GetBytes(keySize); + + return key; + + + } + + /// + /// Generate 16 bytes iv array by pass phrase string + /// + /// + /// + public static byte[] GetIVByPassPhrase(string pwStr) + { + byte[] saltBytes = new byte[] { 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8 }; + byte[] passwordBytes = Encoding.UTF8.GetBytes(pwStr); + + var rfckey = new Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000); + byte[] key = rfckey.GetBytes(16); + + return key; + + + } + + public static byte[] GetRandomKey() + { + AesManaged aesManaged = new AesManaged(); + aesManaged.KeySize = 256; + byte[] key = aesManaged.Key; + + return key; + } + + public static byte[] GetRandomIV() + { + AesManaged aesManaged = new AesManaged(); + Guid guid = Guid.NewGuid(); + + byte[] IV = guid.ToByteArray(); + + return IV; + } + + public static bool IsBase64String(string s) + { + s = s.Trim(); + + if ((s.Length % 4 == 0) && Regex.IsMatch(s, @"^[a-zA-Z0-9\+/]*={0,3}$", RegexOptions.None)) + { + return true; + } + else + { + return false; + } + + } + + public static void SaveAppSetting(string fileName, Dictionary keyValues) + { + ExeConfigurationFileMap configFileMap = new ExeConfigurationFileMap(); + configFileMap.ExeConfigFilename = fileName; + Configuration configuration = ConfigurationManager.OpenMappedExeConfiguration(configFileMap, ConfigurationUserLevel.None); + KeyValueConfigurationCollection settings = configuration.AppSettings.Settings; + + settings.Clear(); + + foreach (KeyValuePair item in keyValues) + { + settings.Add(item.Key, item.Value); + } + + configuration.Save(); + } + + public static void LoadAppSetting(string fileName, ref Dictionary keyValues) + { + ExeConfigurationFileMap configFileMap = new ExeConfigurationFileMap(); + configFileMap.ExeConfigFilename = fileName; + Configuration configuration = ConfigurationManager.OpenMappedExeConfiguration(configFileMap, ConfigurationUserLevel.None); + KeyValueConfigurationCollection settings = configuration.AppSettings.Settings; + + foreach (KeyValueConfigurationElement item in settings) + { + keyValues.Add(item.Key, item.Value); + } + + } + + + public static void ToDebugger(string message) + { + System.Diagnostics.StackTrace st = new System.Diagnostics.StackTrace(false); + string caller = st.GetFrame(1).GetMethod().Name; + System.Diagnostics.Debug.WriteLine(caller + " Time:" + DateTime.Now.ToLongTimeString() + ": " + message); + } + + + public class ByteArrayComparer : IEqualityComparer + { + public bool Equals(byte[] left, byte[] right) + { + if (left == null || right == null) + { + return left == right; + } + if (left.Length != right.Length) + { + return false; + } + for (int i = 0; i < left.Length; i++) + { + if (left[i] != right[i]) + { + return false; + } + } + return true; + } + + public int GetHashCode(byte[] key) + { + if (key == null) + throw new ArgumentNullException("key"); + int sum = 0; + foreach (byte cur in key) + { + sum += cur; + } + return sum; + } + } + + /// + /// To open encrypted file without the filter driver interception, read the raw data with the return file handle. + /// The caller is reponsible to close the file handle. + /// + /// + /// + /// + /// + public static bool OpenRawEnCyptedFile(string fileName, out IntPtr fileHandle, out string lastError) + { + fileHandle = IntPtr.Zero; + lastError = string.Empty; + uint bypassFilterFileAttributes = FilterAPI.FILE_FLAG_OPEN_REPARSE_POINT | FilterAPI.FILE_FLAG_OPEN_NO_RECALL | FilterAPI.FILE_FLAG_NO_BUFFERING | FilterAPI.FILE_ATTRIBUTE_REPARSE_POINT; + + try + { + if (!CreateFileAPI(fileName, (uint)FileAccess.Read, (uint)FileShare.None, (uint)FileMode.Open, bypassFilterFileAttributes, ref fileHandle)) + { + lastError = FilterAPI.GetLastErrorMessage(); + return false; + } + } + catch (Exception ex) + { + lastError = "OpenRawEnCyptedFile " + fileName + " got exception,system return error:" + ex.Message; + return false; + } + + return true; + } + + public static T DecryptStrToObject(string toDeserialize) + { + string decryptedStr = AESEncryptDecryptStr(toDeserialize, EncryptType.Decryption); + + XmlSerializer xmlSerializer = new XmlSerializer(typeof(T)); + StringReader textReader = new StringReader(decryptedStr); + return (T)xmlSerializer.Deserialize(textReader); + } + + public static string EncryptObjectToStr(T toSerialize) + { + XmlSerializer xmlSerializer = new XmlSerializer(typeof(T)); + StringWriter textWriter = new StringWriter(); + xmlSerializer.Serialize(textWriter, toSerialize); + + string encryptedText = AESEncryptDecryptStr(textWriter.ToString(), EncryptType.Encryption); + + return encryptedText; + } + + [System.Diagnostics.Contracts.Pure] + public static string ByteArrayToHex(byte[] value) + { + if (value == null) + throw new ArgumentNullException("value"); + + const string hexAlphabet = @"0123456789ABCDEF"; + + var chars = new char[checked(value.Length * 2)]; + unchecked + { + for (int i = 0; i < value.Length; i++) + { + chars[i * 2] = hexAlphabet[value[i] >> 4]; + chars[i * 2 + 1] = hexAlphabet[value[i] & 0xF]; + } + } + return new string(chars); + } + + [System.Diagnostics.Contracts.Pure] + public static byte[] HexToByteArray(string value) + { + if (value == null) + throw new ArgumentNullException("value"); + if (value.Length % 2 != 0) + throw new ArgumentException("Hexadecimal value length must be even.", "value"); + + unchecked + { + byte[] result = new byte[value.Length / 2]; + for (int i = 0; i < result.Length; i++) + { + // 0(48) - 9(57) -> 0 - 9 + // A(65) - F(70) -> 10 - 15 + int b = value[i * 2]; // High 4 bits. + int val = ((b - '0') + ((('9' - b) >> 31) & -7)) << 4; + b = value[i * 2 + 1]; // Low 4 bits. + val += (b - '0') + ((('9' - b) >> 31) & -7); + result[i] = checked((byte)val); + } + return result; + } + } + + } +} diff --git a/Demo_Source_Code/CSharpDemo/FilterControl/WinDataStructures.cs b/Demo_Source_Code/CSharpDemo/FilterControl/WinDataStructures.cs new file mode 100644 index 0000000..81f9505 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FilterControl/WinDataStructures.cs @@ -0,0 +1,347 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.Collections.Generic; +using System.Text; + +namespace EaseFilter.FilterControl +{ + static public class WinData + { + //for Disposition,ShareAccess,DesiredAccess,CreateOptions Please reference Winddows API CreateFile + //http://msdn.microsoft.com/en-us/library/aa363858%28v=vs.85%29.aspx + + public enum Disposition : uint + { + FILE_SUPERSEDE = 0, + FILE_OPEN, + FILE_CREATE, + FILE_OPEN_IF, + FILE_OVERWRITE, + FILE_OVERWRITE_IF, + } + + public enum ShareAccess : uint + { + SHARE_READ = 1, + SHARE_WRITE = 2, + SHARE_READ_WRITE = 3, + SHARE_DELETE = 4, + SHARE_READ_DELETE = 5, + SHARE_WRITE_DELETE = 6, + SHARE_READ_WRITE_DELETE = 7, + } + + public enum DisiredAccess : uint + { + DELETE = 0x00010000, + READ_CONTROL = 0x00020000, + WRITE_DAC = 0x00040000, + WRITE_OWNER = 0x00080000, + SYNCHRONIZE = 0x00100000, + STANDARD_RIGHTS_REQUIRED = 0x000F0000, + STANDARD_RIGHTS_ALL = 0x001F0000, + SPECIFIC_RIGHTS_ALL = 0x0000FFFF, + ACCESS_SYSTEM_SECURITY = 0x01000000, + MAXIMUM_ALLOWED = 0x02000000, + GENERIC_READ = 0x80000000, + GENERIC_WRITE = 0x40000000, + GENERIC_EXECUTE = 0x20000000, + GENERIC_ALL = 0x10000000, + FILE_READ_DATA = 1, + FILE_WRITE_DATA = 2, + FILE_APPEND_DATA = 0x0004, // file + FILE_READ_EA = 0x0008, // file & directory + FILE_WRITE_EA = 0x0010, // file & directory + FILE_EXECUTE = 0x0020, // file + FILE_DELETE_CHILD = 0x0040, // directory + FILE_READ_ATTRIBUTES = 0x0080, // all + FILE_WRITE_ATTRIBUTES = 0x0100, // all + + } + + public enum CreateOptions : uint + { + FILE_DIRECTORY_FILE = 0x00000001, + FILE_WRITE_THROUGH = 0x00000002, + FILE_SEQUENTIAL_ONLY = 0x00000004, + FILE_NO_INTERMEDIATE_BUFFERING = 0x00000008, + FILE_SYNCHRONOUS_IO_ALERT = 0x00000010, + FILE_SYNCHRONOUS_IO_NONALERT = 0x00000020, + FILE_NON_DIRECTORY_FILE = 0x00000040, + FILE_CREATE_TREE_CONNECTION = 0x00000080, + FILE_COMPLETE_IF_OPLOCKED = 0x00000100, + FILE_NO_EA_KNOWLEDGE = 0x00000200, + FILE_OPEN_REMOTE_INSTANCE = 0x00000400, + FILE_RANDOM_ACCESS = 0x00000800, + FILE_DELETE_ON_CLOSE = 0x00001000, + FILE_OPEN_BY_FILE_ID = 0x00002000, + FILE_OPEN_FOR_BACKUP_INTENT = 0x00004000, + FILE_NO_COMPRESSION = 0x00008000, + FILE_OPEN_REQUIRING_OPLOCK = 0x00010000, + FILE_DISALLOW_EXCLUSIVE = 0x00020000, + FILE_RESERVE_OPFILTER = 0x00100000, + FILE_OPEN_REPARSE_POINT = 0x00200000, + FILE_OPEN_NO_RECALL = 0x00400000, + FILE_OPEN_FOR_FREE_SPACE_QUERY = 0x00800000, + FO_REMOTE_ORIGIN = 0x01000000, + } + + //this is the status for post create request. + public enum CreateStatus : uint + { + FILE_SUPERSEDED = 0x00000000, + FILE_OPENED = 0x00000001, + FILE_CREATED = 0x00000002, + FILE_OVERWRITTEN = 0x00000003, + FILE_EXISTS = 0x00000004, + FILE_DOES_NOT_EXIST = 0x00000005, + } + + public static string DesiredAccessToString(uint desiredAccess) + { + string ret = string.Empty; + + foreach (DisiredAccess access in Enum.GetValues(typeof(WinData.DisiredAccess))) + { + if (access == (WinData.DisiredAccess)((uint)access & desiredAccess)) + { + ret += access.ToString() + "; "; + } + } + + if (string.IsNullOrEmpty(ret)) + { + ret = "(0x)" + desiredAccess.ToString("X"); + } + + return ret; + } + + public static string CreateOptionsToString(uint createOptions) + { + string ret = string.Empty; + + foreach (CreateOptions option in Enum.GetValues(typeof(WinData.CreateOptions))) + { + if (option == (WinData.CreateOptions)((uint)option & createOptions)) + { + ret += option.ToString() + "; "; + } + } + + if (string.IsNullOrEmpty(ret)) + { + ret = "(0x)" + createOptions.ToString("X"); + } + + return ret; + } + + ////end of create structure------------------------------------------------------------------------------------------------- + + // + // Define the file information class values,for more information please reference + // http://msdn.microsoft.com/en-us/library/ff543439%28v=vs.85%29.aspx + // + public enum FileInfomationClass : uint + { + FileDirectoryInformation = 1, + FileFullDirectoryInformation, // 2 + FileBothDirectoryInformation, // 3 + FileBasicInformation, // 4 + FileStandardInformation, // 5 + FileInternalInformation, // 6 + FileEaInformation, // 7 + FileAccessInformation, // 8 + FileNameInformation, // 9 + FileRenameInformation, // 10 + FileLinkInformation, // 11 + FileNamesInformation, // 12 + FileDispositionInformation, // 13 + FilePositionInformation, // 14 + FileFullEaInformation, // 15 + FileModeInformation, // 16 + FileAlignmentInformation, // 17 + FileAllInformation, // 18 + FileAllocationInformation, // 19 + FileEndOfFileInformation, // 20 + FileAlternateNameInformation, // 21 + FileStreamInformation, // 22 + FilePipeInformation, // 23 + FilePipeLocalInformation, // 24 + FilePipeRemoteInformation, // 25 + FileMailslotQueryInformation, // 26 + FileMailslotSetInformation, // 27 + FileCompressionInformation, // 28 + FileObjectIdInformation, // 29 + FileCompletionInformation, // 30 + FileMoveClusterInformation, // 31 + FileQuotaInformation, // 32 + FileReparsePointInformation, // 33 + FileNetworkOpenInformation, // 34 + FileAttributeTagInformation, // 35 + FileTrackingInformation, // 36 + FileIdBothDirectoryInformation, // 37 + FileIdFullDirectoryInformation, // 38 + FileValidDataLengthInformation, // 39 + FileShortNameInformation, // 40 + FileIoCompletionNotificationInformation, // 41 + FileIoStatusBlockRangeInformation, // 42 + FileIoPriorityHintInformation, // 43 + FileSfioReserveInformation, // 44 + FileSfioVolumeInformation, // 45 + FileHardLinkInformation, // 46 + FileProcessIdsUsingFileInformation, // 47 + FileNormalizedNameInformation, // 48 + FileNetworkPhysicalNameInformation, // 49 + FileIdGlobalTxDirectoryInformation, // 50 + FileIsRemoteDeviceInformation, // 51 + FileAttributeCacheInformation, // 52 + FileNumaNodeInformation, // 53 + FileStandardLinkInformation, // 54 + FileRemoteProtocolInformation, // 55 + + // + // These are special versions of these operations (defined earlier) + // which can be used by kernel mode drivers only to bypass security + // access checks for Rename and HardLink operations. These operations + // are only recognized by the IOManager, a file system should never + // receive these. + // + + FileRenameInformationBypassAccessCheck, // 56 + FileLinkInformationBypassAccessCheck, // 57 + + // + // End of special information classes reserved for IOManager. + // + + FileVolumeNameInformation, // 58 + FileIdInformation, // 59 + FileIdExtdDirectoryInformation, // 60 + FileReplaceCompletionInformation, // 61 + FileHardLinkFullIdInformation, // 62 + FileIdExtdBothDirectoryInformation, // 63 + FileDispositionInformationEx, // 64 + FileRenameInformationEx, // 65 + FileRenameInformationExBypassAccessCheck, // 66 + FileDesiredStorageClassInformation, // 67 + FileStatInformation, // 68 + FileMemoryPartitionInformation, // 69 + FileStatLxInformation, // 70 + FileCaseSensitiveInformation, // 71 + FileLinkInformationEx, // 72 + FileLinkInformationExBypassAccessCheck, // 73 + FileStorageReserveIdInformation, // 74 + FileCaseSensitiveInformationForceAccessCheck, // 75 + + } + + public enum SecurityInformation : uint + { + OWNER_SECURITY_INFORMATION = 0x00000001, + GROUP_SECURITY_INFORMATION = 0x00000002, + DACL_SECURITY_INFORMATION = 0x00000004, + SACL_SECURITY_INFORMATION = 0x00000008, + LABEL_SECURITY_INFORMATION = 0x00000010, + } + + public struct FileBasicInformation + { + public long CreationTime; + public long LastAccessTime; + public long LastWriteTime; + public long ChangeTime; + public uint FileAttributes; + } + + public struct FileStandardInformation + { + public long AllocationSize; + public long EndOfFile; + public uint NumberOfLinks; + public bool DeletePending; + public bool Directory; + } + + public struct FileNetworkInformation + { + public long CreationTime; + public long LastAccessTime; + public long LastWriteTime; + public long ChangeTime; + public long AllocationSize; + public long FileSize; + public uint FileAttributes; + } + + //end of information structure----------------------------------------------------------------------------------- + + public enum FLT_FILESYSTEM_TYPE : uint + { + + FLT_FSTYPE_UNKNOWN, //an UNKNOWN file system type + FLT_FSTYPE_RAW, //Microsoft's RAW file system (\FileSystem\RAW) + FLT_FSTYPE_NTFS, //Microsoft's NTFS file system (\FileSystem\Ntfs) + FLT_FSTYPE_FAT, //Microsoft's FAT file system (\FileSystem\Fastfat) + FLT_FSTYPE_CDFS, //Microsoft's CDFS file system (\FileSystem\Cdfs) + FLT_FSTYPE_UDFS, //Microsoft's UDFS file system (\FileSystem\Udfs) + FLT_FSTYPE_LANMAN, //Microsoft's LanMan Redirector (\FileSystem\MRxSmb) + FLT_FSTYPE_WEBDAV, //Microsoft's WebDav redirector (\FileSystem\MRxDav) + FLT_FSTYPE_RDPDR, //Microsoft's Terminal Server redirector (\Driver\rdpdr) + FLT_FSTYPE_NFS, //Microsoft's NFS file system (\FileSystem\NfsRdr) + FLT_FSTYPE_MS_NETWARE, //Microsoft's NetWare redirector (\FileSystem\nwrdr) + FLT_FSTYPE_NETWARE, //Novell's NetWare redirector + FLT_FSTYPE_BSUDF, //The BsUDF CD-ROM driver (\FileSystem\BsUDF) + FLT_FSTYPE_MUP, //Microsoft's Mup redirector (\FileSystem\Mup) + FLT_FSTYPE_RSFX, //Microsoft's WinFS redirector (\FileSystem\RsFxDrv) + FLT_FSTYPE_ROXIO_UDF1, //Roxio's UDF writeable file system (\FileSystem\cdudf_xp) + FLT_FSTYPE_ROXIO_UDF2, //Roxio's UDF readable file system (\FileSystem\UdfReadr_xp) + FLT_FSTYPE_ROXIO_UDF3, //Roxio's DVD file system (\FileSystem\DVDVRRdr_xp) + FLT_FSTYPE_TACIT, //Tacit FileSystem (\Device\TCFSPSE) + FLT_FSTYPE_FS_REC, //Microsoft's File system recognizer (\FileSystem\Fs_rec) + FLT_FSTYPE_INCD, //Nero's InCD file system (\FileSystem\InCDfs) + FLT_FSTYPE_INCD_FAT, //Nero's InCD FAT file system (\FileSystem\InCDFat) + FLT_FSTYPE_EXFAT, //Microsoft's EXFat FILE SYSTEM (\FileSystem\exfat) + FLT_FSTYPE_PSFS, //PolyServ's file system (\FileSystem\psfs) + FLT_FSTYPE_GPFS //IBM General Parallel File System (\FileSystem\gpfs) + + } + + public enum DeviceObject_Characteristics:uint + { + FILE_REMOVABLE_MEDIA = 0x00000001, + FILE_READ_ONLY_DEVICE = 0x00000002, + FILE_FLOPPY_DISKETTE = 0x00000004, + FILE_WRITE_ONCE_MEDIA = 0x00000008, + FILE_REMOTE_DEVICE = 0x00000010, + FILE_DEVICE_IS_MOUNTED = 0x00000020, + FILE_VIRTUAL_VOLUME = 0x00000040, + FILE_AUTOGENERATED_DEVICE_NAME = 0x00000080, + FILE_DEVICE_SECURE_OPEN = 0x00000100, + FILE_CHARACTERISTIC_PNP_DEVICE = 0x00000800, + FILE_CHARACTERISTIC_TS_DEVICE = 0x00001000, + FILE_CHARACTERISTIC_WEBDAV_DEVICE = 0x00002000, + FILE_CHARACTERISTIC_CSV = 0x00010000, + FILE_DEVICE_ALLOW_APPCONTAINER_TRAVERSAL = 0x00020000, + FILE_PORTABLE_DEVICE = 0x00040000, + + } + } +} diff --git a/Demo_Source_Code/CSharpDemo/FolderLocker/AccessRightsForm.Designer.cs b/Demo_Source_Code/CSharpDemo/FolderLocker/AccessRightsForm.Designer.cs new file mode 100644 index 0000000..c8db1d2 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FolderLocker/AccessRightsForm.Designer.cs @@ -0,0 +1,353 @@ +namespace EaseFilter.FolderLocker +{ + partial class Form_AccessRights + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form_AccessRights)); + this.button_Apply = new System.Windows.Forms.Button(); + this.groupBox2 = new System.Windows.Forms.GroupBox(); + this.checkBox_AllowReadEncryptedFiles = new System.Windows.Forms.CheckBox(); + this.checkBox_AllowRemoteAccess = new System.Windows.Forms.CheckBox(); + this.checkBox_AllowCopyout = new System.Windows.Forms.CheckBox(); + this.checkBox_AllowSaveAs = new System.Windows.Forms.CheckBox(); + this.checkBox_Execution = new System.Windows.Forms.CheckBox(); + this.checkBox_SetSecurity = new System.Windows.Forms.CheckBox(); + this.checkBox_QueryInfo = new System.Windows.Forms.CheckBox(); + this.checkBox_Read = new System.Windows.Forms.CheckBox(); + this.checkBox_QuerySecurity = new System.Windows.Forms.CheckBox(); + this.checkBox_SetInfo = new System.Windows.Forms.CheckBox(); + this.checkBox_Write = new System.Windows.Forms.CheckBox(); + this.checkBox_AllowDelete = new System.Windows.Forms.CheckBox(); + this.checkBox_AllowRename = new System.Windows.Forms.CheckBox(); + this.checkBox_Creation = new System.Windows.Forms.CheckBox(); + this.label_Name = new System.Windows.Forms.Label(); + this.textBox_AccessName = new System.Windows.Forms.TextBox(); + this.groupBox_UserName = new System.Windows.Forms.GroupBox(); + this.groupBox2.SuspendLayout(); + this.groupBox_UserName.SuspendLayout(); + this.SuspendLayout(); + // + // button_Apply + // + this.button_Apply.DialogResult = System.Windows.Forms.DialogResult.OK; + this.button_Apply.Location = new System.Drawing.Point(508, 331); + this.button_Apply.Name = "button_Apply"; + this.button_Apply.TabIndex = 25; + this.button_Apply.Text = "Apply"; + this.button_Apply.UseVisualStyleBackColor = true; + this.button_Apply.Click += new System.EventHandler(this.button_Apply_Click); + // + // groupBox2 + // + this.groupBox2.Controls.Add(this.checkBox_AllowReadEncryptedFiles); + this.groupBox2.Controls.Add(this.checkBox_AllowRemoteAccess); + this.groupBox2.Controls.Add(this.checkBox_AllowCopyout); + this.groupBox2.Controls.Add(this.checkBox_AllowSaveAs); + this.groupBox2.Controls.Add(this.checkBox_Execution); + this.groupBox2.Controls.Add(this.checkBox_SetSecurity); + this.groupBox2.Controls.Add(this.checkBox_QueryInfo); + this.groupBox2.Controls.Add(this.checkBox_Read); + this.groupBox2.Controls.Add(this.checkBox_QuerySecurity); + this.groupBox2.Controls.Add(this.checkBox_SetInfo); + this.groupBox2.Controls.Add(this.checkBox_Write); + this.groupBox2.Controls.Add(this.checkBox_AllowDelete); + this.groupBox2.Controls.Add(this.checkBox_AllowRename); + this.groupBox2.Controls.Add(this.checkBox_Creation); + this.groupBox2.Location = new System.Drawing.Point(28, 157); + this.groupBox2.Name = "groupBox2"; + this.groupBox2.Size = new System.Drawing.Size(555, 149); + this.groupBox2.TabIndex = 76; + this.groupBox2.TabStop = false; + this.groupBox2.Text = "Acess Rights"; + // + // checkBox_AllowReadEncryptedFiles + // + this.checkBox_AllowReadEncryptedFiles.AutoSize = true; + this.checkBox_AllowReadEncryptedFiles.Checked = true; + this.checkBox_AllowReadEncryptedFiles.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBox_AllowReadEncryptedFiles.Location = new System.Drawing.Point(358, 119); + this.checkBox_AllowReadEncryptedFiles.Name = "checkBox_AllowReadEncryptedFiles"; + this.checkBox_AllowReadEncryptedFiles.Size = new System.Drawing.Size(186, 15); + this.checkBox_AllowReadEncryptedFiles.TabIndex = 37; + this.checkBox_AllowReadEncryptedFiles.Text = "Allow encrpted files being read"; + this.checkBox_AllowReadEncryptedFiles.UseVisualStyleBackColor = true; + this.checkBox_AllowReadEncryptedFiles.CheckedChanged += new System.EventHandler(this.checkBox_AllowReadEncryptedFiles_CheckedChanged); + // + // checkBox_AllowRemoteAccess + // + this.checkBox_AllowRemoteAccess.AutoSize = true; + this.checkBox_AllowRemoteAccess.Checked = true; + this.checkBox_AllowRemoteAccess.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBox_AllowRemoteAccess.Location = new System.Drawing.Point(9, 119); + this.checkBox_AllowRemoteAccess.Name = "checkBox_AllowRemoteAccess"; + this.checkBox_AllowRemoteAccess.Size = new System.Drawing.Size(201, 15); + this.checkBox_AllowRemoteAccess.TabIndex = 36; + this.checkBox_AllowRemoteAccess.Text = "Allow file accessing from network"; + this.checkBox_AllowRemoteAccess.UseVisualStyleBackColor = true; + this.checkBox_AllowRemoteAccess.CheckedChanged += new System.EventHandler(this.checkBox_AllowRemoteAccess_CheckedChanged); + // + // checkBox_AllowCopyout + // + this.checkBox_AllowCopyout.AutoSize = true; + this.checkBox_AllowCopyout.Checked = true; + this.checkBox_AllowCopyout.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBox_AllowCopyout.Location = new System.Drawing.Point(358, 96); + this.checkBox_AllowCopyout.Name = "checkBox_AllowCopyout"; + this.checkBox_AllowCopyout.Size = new System.Drawing.Size(170, 15); + this.checkBox_AllowCopyout.TabIndex = 35; + this.checkBox_AllowCopyout.Text = "Allow files being copied out"; + this.checkBox_AllowCopyout.UseVisualStyleBackColor = true; + this.checkBox_AllowCopyout.CheckedChanged += new System.EventHandler(this.checkBox_AllowCopyout_CheckedChanged); + // + // checkBox_AllowSaveAs + // + this.checkBox_AllowSaveAs.AutoSize = true; + this.checkBox_AllowSaveAs.Checked = true; + this.checkBox_AllowSaveAs.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBox_AllowSaveAs.Location = new System.Drawing.Point(358, 74); + this.checkBox_AllowSaveAs.Name = "checkBox_AllowSaveAs"; + this.checkBox_AllowSaveAs.Size = new System.Drawing.Size(157, 15); + this.checkBox_AllowSaveAs.TabIndex = 34; + this.checkBox_AllowSaveAs.Text = "Allow files being saved as"; + this.checkBox_AllowSaveAs.UseVisualStyleBackColor = true; + this.checkBox_AllowSaveAs.CheckedChanged += new System.EventHandler(this.checkBox_AllowSaveAs_CheckedChanged); + // + // checkBox_Execution + // + this.checkBox_Execution.AutoSize = true; + this.checkBox_Execution.Checked = true; + this.checkBox_Execution.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBox_Execution.Location = new System.Drawing.Point(9, 97); + this.checkBox_Execution.Name = "checkBox_Execution"; + this.checkBox_Execution.Size = new System.Drawing.Size(126, 15); + this.checkBox_Execution.TabIndex = 30; + this.checkBox_Execution.Text = "Allow file execution"; + this.checkBox_Execution.UseVisualStyleBackColor = true; + this.checkBox_Execution.CheckedChanged += new System.EventHandler(this.checkBox_Execution_CheckedChanged); + // + // checkBox_SetSecurity + // + this.checkBox_SetSecurity.AutoSize = true; + this.checkBox_SetSecurity.Checked = true; + this.checkBox_SetSecurity.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBox_SetSecurity.Location = new System.Drawing.Point(358, 52); + this.checkBox_SetSecurity.Name = "checkBox_SetSecurity"; + this.checkBox_SetSecurity.Size = new System.Drawing.Size(169, 15); + this.checkBox_SetSecurity.TabIndex = 29; + this.checkBox_SetSecurity.Text = "Allow file security changing"; + this.checkBox_SetSecurity.UseVisualStyleBackColor = true; + this.checkBox_SetSecurity.CheckedChanged += new System.EventHandler(this.checkBox_SetSecurity_CheckedChanged); + // + // checkBox_QueryInfo + // + this.checkBox_QueryInfo.AutoSize = true; + this.checkBox_QueryInfo.Checked = true; + this.checkBox_QueryInfo.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBox_QueryInfo.Location = new System.Drawing.Point(155, 30); + this.checkBox_QueryInfo.Name = "checkBox_QueryInfo"; + this.checkBox_QueryInfo.Size = new System.Drawing.Size(188, 15); + this.checkBox_QueryInfo.TabIndex = 24; + this.checkBox_QueryInfo.Text = "Allow file information querying"; + this.checkBox_QueryInfo.UseVisualStyleBackColor = true; + this.checkBox_QueryInfo.CheckedChanged += new System.EventHandler(this.checkBox_QueryInfo_CheckedChanged); + // + // checkBox_Read + // + this.checkBox_Read.AutoSize = true; + this.checkBox_Read.Checked = true; + this.checkBox_Read.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBox_Read.Location = new System.Drawing.Point(9, 30); + this.checkBox_Read.Name = "checkBox_Read"; + this.checkBox_Read.Size = new System.Drawing.Size(115, 15); + this.checkBox_Read.TabIndex = 26; + this.checkBox_Read.Text = "Allow file reading"; + this.checkBox_Read.UseVisualStyleBackColor = true; + this.checkBox_Read.CheckedChanged += new System.EventHandler(this.checkBox_Read_CheckedChanged); + // + // checkBox_QuerySecurity + // + this.checkBox_QuerySecurity.AutoSize = true; + this.checkBox_QuerySecurity.Checked = true; + this.checkBox_QuerySecurity.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBox_QuerySecurity.Location = new System.Drawing.Point(358, 30); + this.checkBox_QuerySecurity.Name = "checkBox_QuerySecurity"; + this.checkBox_QuerySecurity.Size = new System.Drawing.Size(166, 15); + this.checkBox_QuerySecurity.TabIndex = 25; + this.checkBox_QuerySecurity.Text = "Allow file security querying"; + this.checkBox_QuerySecurity.UseVisualStyleBackColor = true; + this.checkBox_QuerySecurity.CheckedChanged += new System.EventHandler(this.checkBox_QuerySecurity_CheckedChanged); + // + // checkBox_SetInfo + // + this.checkBox_SetInfo.AutoSize = true; + this.checkBox_SetInfo.Checked = true; + this.checkBox_SetInfo.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBox_SetInfo.Location = new System.Drawing.Point(155, 52); + this.checkBox_SetInfo.Name = "checkBox_SetInfo"; + this.checkBox_SetInfo.Size = new System.Drawing.Size(191, 15); + this.checkBox_SetInfo.TabIndex = 28; + this.checkBox_SetInfo.Text = "Allow file information changing"; + this.checkBox_SetInfo.UseVisualStyleBackColor = true; + this.checkBox_SetInfo.CheckedChanged += new System.EventHandler(this.checkBox_SetInfo_CheckedChanged); + // + // checkBox_Write + // + this.checkBox_Write.AutoSize = true; + this.checkBox_Write.Checked = true; + this.checkBox_Write.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBox_Write.Location = new System.Drawing.Point(9, 53); + this.checkBox_Write.Name = "checkBox_Write"; + this.checkBox_Write.Size = new System.Drawing.Size(112, 15); + this.checkBox_Write.TabIndex = 15; + this.checkBox_Write.Text = "Allow file writing"; + this.checkBox_Write.UseVisualStyleBackColor = true; + this.checkBox_Write.CheckedChanged += new System.EventHandler(this.checkBox_Write_CheckedChanged); + // + // checkBox_AllowDelete + // + this.checkBox_AllowDelete.AutoSize = true; + this.checkBox_AllowDelete.Checked = true; + this.checkBox_AllowDelete.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBox_AllowDelete.Location = new System.Drawing.Point(155, 97); + this.checkBox_AllowDelete.Name = "checkBox_AllowDelete"; + this.checkBox_AllowDelete.Size = new System.Drawing.Size(118, 15); + this.checkBox_AllowDelete.TabIndex = 17; + this.checkBox_AllowDelete.Text = "Allow file deletion"; + this.checkBox_AllowDelete.UseVisualStyleBackColor = true; + this.checkBox_AllowDelete.CheckedChanged += new System.EventHandler(this.checkBox_AllowDelete_CheckedChanged); + // + // checkBox_AllowRename + // + this.checkBox_AllowRename.AutoSize = true; + this.checkBox_AllowRename.Checked = true; + this.checkBox_AllowRename.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBox_AllowRename.Location = new System.Drawing.Point(155, 75); + this.checkBox_AllowRename.Name = "checkBox_AllowRename"; + this.checkBox_AllowRename.Size = new System.Drawing.Size(126, 15); + this.checkBox_AllowRename.TabIndex = 16; + this.checkBox_AllowRename.Text = "Allow file renaming"; + this.checkBox_AllowRename.UseVisualStyleBackColor = true; + this.checkBox_AllowRename.CheckedChanged += new System.EventHandler(this.checkBox_AllowRename_CheckedChanged); + // + // checkBox_Creation + // + this.checkBox_Creation.AutoSize = true; + this.checkBox_Creation.Checked = true; + this.checkBox_Creation.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBox_Creation.Location = new System.Drawing.Point(9, 75); + this.checkBox_Creation.Name = "checkBox_Creation"; + this.checkBox_Creation.Size = new System.Drawing.Size(143, 15); + this.checkBox_Creation.TabIndex = 22; + this.checkBox_Creation.Text = "Allow new file creation"; + this.checkBox_Creation.UseVisualStyleBackColor = true; + this.checkBox_Creation.CheckedChanged += new System.EventHandler(this.checkBox_Creation_CheckedChanged); + // + // label_Name + // + this.label_Name.AutoSize = true; + this.label_Name.Location = new System.Drawing.Point(9, 31); + this.label_Name.Name = "label_Name"; + this.label_Name.Size = new System.Drawing.Size(75, 19); + this.label_Name.TabIndex = 28; + this.label_Name.Text = "User Name"; + // + // textBox_AccessName + // + // + // + // + + this.textBox_AccessName.Lines = new string[0]; + this.textBox_AccessName.Location = new System.Drawing.Point(149, 28); + this.textBox_AccessName.MaxLength = 32767; + this.textBox_AccessName.Name = "textBox_AccessName"; + this.textBox_AccessName.PasswordChar = '\0'; + this.textBox_AccessName.ScrollBars = System.Windows.Forms.ScrollBars.None; + this.textBox_AccessName.SelectedText = ""; + this.textBox_AccessName.SelectionLength = 0; + this.textBox_AccessName.SelectionStart = 0; + this.textBox_AccessName.ShortcutsEnabled = true; + this.textBox_AccessName.Size = new System.Drawing.Size(332, 20); + this.textBox_AccessName.TabIndex = 27; + // + // groupBox_UserName + // + this.groupBox_UserName.Controls.Add(this.textBox_AccessName); + this.groupBox_UserName.Controls.Add(this.label_Name); + this.groupBox_UserName.Location = new System.Drawing.Point(28, 74); + this.groupBox_UserName.Name = "groupBox_UserName"; + this.groupBox_UserName.Size = new System.Drawing.Size(555, 71); + this.groupBox_UserName.TabIndex = 30; + this.groupBox_UserName.TabStop = false; + // + // Form_AccessRights + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(617, 411); + this.Controls.Add(this.groupBox_UserName); + this.Controls.Add(this.groupBox2); + this.Controls.Add(this.button_Apply); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Margin = new System.Windows.Forms.Padding(2); + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "Form_AccessRights"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "Configure Access Rights"; + this.groupBox2.ResumeLayout(false); + this.groupBox2.PerformLayout(); + this.groupBox_UserName.ResumeLayout(false); + this.groupBox_UserName.PerformLayout(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.Button button_Apply; + private System.Windows.Forms.GroupBox groupBox2; + private System.Windows.Forms.CheckBox checkBox_Write; + private System.Windows.Forms.CheckBox checkBox_AllowDelete; + private System.Windows.Forms.CheckBox checkBox_AllowRename; + private System.Windows.Forms.CheckBox checkBox_Creation; + private System.Windows.Forms.CheckBox checkBox_SetSecurity; + private System.Windows.Forms.CheckBox checkBox_QueryInfo; + private System.Windows.Forms.CheckBox checkBox_Read; + private System.Windows.Forms.CheckBox checkBox_QuerySecurity; + private System.Windows.Forms.CheckBox checkBox_SetInfo; + private System.Windows.Forms.CheckBox checkBox_Execution; + private System.Windows.Forms.CheckBox checkBox_AllowCopyout; + private System.Windows.Forms.CheckBox checkBox_AllowSaveAs; + private System.Windows.Forms.CheckBox checkBox_AllowRemoteAccess; + private System.Windows.Forms.CheckBox checkBox_AllowReadEncryptedFiles; + private System.Windows.Forms.Label label_Name; + private System.Windows.Forms.TextBox textBox_AccessName; + private System.Windows.Forms.GroupBox groupBox_UserName; + } +} \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/FolderLocker/AccessRightsForm.cs b/Demo_Source_Code/CSharpDemo/FolderLocker/AccessRightsForm.cs new file mode 100644 index 0000000..f81da39 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FolderLocker/AccessRightsForm.cs @@ -0,0 +1,378 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +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; + +using EaseFilter.FilterControl; +using EaseFilter.CommonObjects; + +namespace EaseFilter.FolderLocker +{ + public partial class Form_AccessRights : Form + { + bool isProcessRights = true; + + public string accessName = string.Empty; + public uint accessFlags = FilterAPI.ALLOW_MAX_RIGHT_ACCESS; + + public Form_AccessRights(bool _isProcessRights, uint accessRights, string name) + { + InitializeComponent(); + + isProcessRights = _isProcessRights; + accessFlags = accessRights; + textBox_AccessName.Text = name; + + if (isProcessRights) + { + label_Name.Text = "Process Name"; + } + else + { + label_Name.Text = "User Name"; + } + + SetCheckBoxValue(); + } + + private void button_Apply_Click(object sender, EventArgs e) + { + accessName = textBox_AccessName.Text; + } + + + private void SetCheckBoxValue() + { + + if ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_FILE_ACCESS_FROM_NETWORK) > 0) + { + checkBox_AllowRemoteAccess.Checked = true; + } + else + { + checkBox_AllowRemoteAccess.Checked = false; + } + + if ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_FILE_DELETE) > 0) + { + checkBox_AllowDelete.Checked = true; + } + else + { + checkBox_AllowDelete.Checked = false; + } + + if ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_FILE_RENAME) > 0) + { + checkBox_AllowRename.Checked = true; + } + else + { + checkBox_AllowRename.Checked = false; + } + + if ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_WRITE_ACCESS) > 0 ) + { + checkBox_Write.Checked = true; + } + else + { + checkBox_Write.Checked = false; + } + + if ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_READ_ACCESS) > 0) + { + checkBox_Read.Checked = true; + } + else + { + checkBox_Read.Checked = false; + } + + if ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_QUERY_INFORMATION_ACCESS) > 0) + { + checkBox_QueryInfo.Checked = true; + } + else + { + checkBox_QueryInfo.Checked = false; + } + + if ( (accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_SET_INFORMATION) > 0 ) + { + checkBox_SetInfo.Checked = true; + } + else + { + checkBox_SetInfo.Checked = false; + } + + if ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_OPEN_WITH_CREATE_OR_OVERWRITE_ACCESS) > 0) + { + checkBox_Creation.Checked = true; + } + else + { + checkBox_Creation.Checked = false; + } + + if ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_FILE_MEMORY_MAPPED) > 0) + { + checkBox_Execution.Checked = true; + } + else + { + checkBox_Execution.Checked = false; + } + + if ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_QUERY_SECURITY_ACCESS) > 0) + { + checkBox_QuerySecurity.Checked = true; + } + else + { + checkBox_QuerySecurity.Checked = false; + } + + if ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_SET_SECURITY_ACCESS) > 0) + { + checkBox_SetSecurity.Checked = true; + } + else + { + checkBox_SetSecurity.Checked = false; + } + + if ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_ALL_SAVE_AS) > 0) + { + checkBox_AllowSaveAs.Checked = true; + } + else + { + checkBox_AllowSaveAs.Checked = false; + } + + if ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_COPY_PROTECTED_FILES_OUT) > 0) + { + checkBox_AllowCopyout.Checked = true; + } + else + { + checkBox_AllowCopyout.Checked = false; + } + + if ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_READ_ENCRYPTED_FILES) > 0) + { + checkBox_AllowReadEncryptedFiles.Checked = true; + } + else + { + checkBox_AllowReadEncryptedFiles.Checked = false; + } + } + + private void checkBox_Read_CheckedChanged(object sender, EventArgs e) + { + if (checkBox_Read.Checked) + { + accessFlags |= (uint)FilterAPI.AccessFlag.ALLOW_READ_ACCESS; + } + else + { + accessFlags &= ~(uint)FilterAPI.AccessFlag.ALLOW_READ_ACCESS; + } + + } + + private void checkBox_Write_CheckedChanged(object sender, EventArgs e) + { + if (checkBox_Write.Checked) + { + accessFlags |= (uint)FilterAPI.AccessFlag.ALLOW_WRITE_ACCESS; + } + else + { + accessFlags &= ~(uint)FilterAPI.AccessFlag.ALLOW_WRITE_ACCESS; + } + + } + + private void checkBox_Creation_CheckedChanged(object sender, EventArgs e) + { + if (checkBox_Creation.Checked) + { + accessFlags |= (uint)FilterAPI.AccessFlag.ALLOW_OPEN_WITH_CREATE_OR_OVERWRITE_ACCESS; + } + else + { + accessFlags &= ~(uint)FilterAPI.AccessFlag.ALLOW_OPEN_WITH_CREATE_OR_OVERWRITE_ACCESS; + } + + } + + private void checkBox_Execution_CheckedChanged(object sender, EventArgs e) + { + if (checkBox_Execution.Checked) + { + accessFlags |= (uint)FilterAPI.AccessFlag.ALLOW_FILE_MEMORY_MAPPED; + } + else + { + accessFlags &= ~(uint)FilterAPI.AccessFlag.ALLOW_FILE_MEMORY_MAPPED; + } + + } + + private void checkBox_AllowRemoteAccess_CheckedChanged(object sender, EventArgs e) + { + if (checkBox_AllowRemoteAccess.Checked) + { + accessFlags |= (uint)FilterAPI.AccessFlag.ALLOW_FILE_ACCESS_FROM_NETWORK; + } + else + { + accessFlags &= ~(uint)FilterAPI.AccessFlag.ALLOW_FILE_ACCESS_FROM_NETWORK; + } + + } + + private void checkBox_QueryInfo_CheckedChanged(object sender, EventArgs e) + { + if (checkBox_QueryInfo.Checked) + { + accessFlags |= (uint)FilterAPI.AccessFlag.ALLOW_QUERY_INFORMATION_ACCESS; + } + else + { + accessFlags &= ~(uint)FilterAPI.AccessFlag.ALLOW_QUERY_INFORMATION_ACCESS; + } + + } + + private void checkBox_SetInfo_CheckedChanged(object sender, EventArgs e) + { + if (checkBox_SetInfo.Checked) + { + accessFlags |= (uint)FilterAPI.AccessFlag.ALLOW_SET_INFORMATION; + } + else + { + accessFlags &= ~(uint)FilterAPI.AccessFlag.ALLOW_SET_INFORMATION; + } + + } + + private void checkBox_AllowRename_CheckedChanged(object sender, EventArgs e) + { + if (checkBox_AllowRename.Checked) + { + accessFlags |= (uint)FilterAPI.AccessFlag.ALLOW_FILE_RENAME; + } + else + { + accessFlags &= ~(uint)FilterAPI.AccessFlag.ALLOW_FILE_RENAME; + } + } + + private void checkBox_AllowDelete_CheckedChanged(object sender, EventArgs e) + { + if (checkBox_AllowDelete.Checked) + { + accessFlags |= (uint)FilterAPI.AccessFlag.ALLOW_FILE_DELETE; + } + else + { + accessFlags &= ~(uint)FilterAPI.AccessFlag.ALLOW_FILE_DELETE; + } + + } + + private void checkBox_QuerySecurity_CheckedChanged(object sender, EventArgs e) + { + if (checkBox_QuerySecurity.Checked) + { + accessFlags |= (uint)FilterAPI.AccessFlag.ALLOW_QUERY_SECURITY_ACCESS; + } + else + { + accessFlags &= ~(uint)FilterAPI.AccessFlag.ALLOW_QUERY_SECURITY_ACCESS; + } + + } + + private void checkBox_SetSecurity_CheckedChanged(object sender, EventArgs e) + { + if (checkBox_SetSecurity.Checked) + { + accessFlags |= (uint)FilterAPI.AccessFlag.ALLOW_SET_SECURITY_ACCESS; + } + else + { + accessFlags &= ~(uint)FilterAPI.AccessFlag.ALLOW_SET_SECURITY_ACCESS; + } + + } + + private void checkBox_AllowSaveAs_CheckedChanged(object sender, EventArgs e) + { + if (checkBox_AllowSaveAs.Checked) + { + accessFlags |= (uint)FilterAPI.AccessFlag.ALLOW_ALL_SAVE_AS; + } + else + { + accessFlags &= ~(uint)FilterAPI.AccessFlag.ALLOW_ALL_SAVE_AS; + } + + } + + private void checkBox_AllowCopyout_CheckedChanged(object sender, EventArgs e) + { + if (checkBox_AllowCopyout.Checked) + { + accessFlags |= (uint)FilterAPI.AccessFlag.ALLOW_COPY_PROTECTED_FILES_OUT; + } + else + { + accessFlags &= ~(uint)FilterAPI.AccessFlag.ALLOW_COPY_PROTECTED_FILES_OUT; + } + + } + + private void checkBox_AllowReadEncryptedFiles_CheckedChanged(object sender, EventArgs e) + { + if (checkBox_AllowReadEncryptedFiles.Checked) + { + accessFlags |= (uint)FilterAPI.AccessFlag.ALLOW_READ_ENCRYPTED_FILES; + } + else + { + accessFlags &= ~(uint)FilterAPI.AccessFlag.ALLOW_READ_ENCRYPTED_FILES; + } + + } + + + } +} diff --git a/Demo_Source_Code/CSharpDemo/FolderLocker/AccessRightsForm.resx b/Demo_Source_Code/CSharpDemo/FolderLocker/AccessRightsForm.resx new file mode 100644 index 0000000..6efe0ef --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FolderLocker/AccessRightsForm.resx @@ -0,0 +1,408 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + AAABAAEAQEAAAAEAIAAoQgAAFgAAACgAAABAAAAAgAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOTX0YDk19H/5NfR/+TX0f/k19H/5NfR/+TX + 0f/k19H/5NfR/+TX0f/k19H/5NfR/+TX0f/k19H/5NfR/+TX0f/k19H/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADRydP/RGLg/0Ri + 4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/+TX + 0f8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AADk19FARGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri + 4P9EYuD/RGLg/0Ri4P/k19H/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA5NfRQERi4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri + 4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/5NfR/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQjs4/0I7OP9COzj/Qjs4/0I7OP9COzj/Qjs4/0I7 + OP9COzj/Qjs4/0I7OP9COzj/Qjs4/0I7OP9COzj/Qjs4/0I7OP9COzj/Qjs4/0I7OP9COzj/Qjs4/0I7 + OP9COzj/Qjs4/0I7OP9COzj/Qjs4/0I7OP9COzj/Qjs4/2tiXv9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri + 4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/+TX0f8AAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEI7OP9fVVH/X1VR/19V + Uf9fVVH/X1VR/19VUf9fVVH/X1VR/19VUf9fVVH/X1VR/19VUf9fVVH/X1VR/19VUf9fVVH/X1VR/19V + Uf9fVVH/X1VR/19VUf9fVVH/X1VR/19VUf9fVVH/X1VR/19VUf9fVVH/X1VR/19VUf+AdnH/RGLg/0Ri + 4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri + 4P/k19H/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AABCOzj/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/iHx4/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri + 4P9EYuD/RGLg/0Ri4P9EYuD/5NfR/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAQjs4/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/4h8eP9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri + 4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/+TX0f8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEI7OP9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv+IfHj/RGLg/0Ri4P9EYuD/RGLg/0Ri + 4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P/k19H/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABCOzj/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/iHx4/0Ri + 4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri + 4P9EYuD/5NfR/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAQjs4/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/4h8eP9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri + 4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/+TX0f8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAEI7OP9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv+IfHj/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri + 4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P/k19H/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABCOzj/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/+TX0f+8utX/RGLg/0Ri + 4P9EYuD/vLrV/7y61f+8utX/vLrV/7y61f+8utX/vLrV/7y61f9EYuD/RGLg/0Ri4P/k19H/5NfR/wAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQjs4/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/5NfR/0Ri4P9EYuD/RGLg/+TX0f9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv/k19H/RGLg/0Ri + 4P9EYuD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAEI7OP9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/+TX0f9EYuD/RGLg/0Ri4P/k19H/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/5NfR/0Ri4P9EYuD/RGLg/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABCOzj/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv/k19H/RGLg/0Ri4P9EYuD/5NfR/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/+TX0f9EYuD/RGLg/0Ri4P8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQjs4/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/5NfR/0Ri + 4P9EYuD/RGLg/+TX0f9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv/k19H/RGLg/0Ri4P9EYuD/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEI7 + OP9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/+TX0f9EYuD/RGLg/0Ri4P/k19H/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/5NfR/0Ri + 4P9EYuD/RGLg/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAABCOzj/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv/k19H/RGLg/0Ri4P9EYuD/5NfR/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/1hx3v9EYuD/RGLg/0Ri4P8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQjs4/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/3dDK/0Ri4P9EYuD/RGLg/0Ri + 4P+XjIf/aV5a/2leWv9pXlr/aV5a/+TX0f9EYuD/RGLg/0Ri4P/k19H/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEI7OP9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv/k19H/RGLg/0Ri4P9EYuD/5NfR/9XIw/9pXlr/aV5a/+TX0f9EYuD/RGLg/0Ri4P9EYuD/5NfR/wAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AABCOzj/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/5NfR/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/vLrV/2x/3P9EYuD/RGLg/0Ri + 4P9EYuD/Tmnf/+TX0WAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAQjs4/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv/k19H/RGLg/0Ri4P9EYuD/RGLg/0Ri + 4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/+TX0f8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEI7OP9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/+TX + 0f9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/Tmnf/+TX0f8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABCOzj/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/5NfR/+TX0f+Kldn/RGLg/0Ri4P/k19H/5NfR/5eMh/8AAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAQjs4/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAEI7OP9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABCOzj/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQjs4/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAEI7OP9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABCOzj/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQjs4/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEI7 + OP+Ddm7/g3Zu/4N2bv+Ddm7/g3Zu/4N2bv+Ddm7/g3Zu/4N2bv+Ddm7/g3Zu/4N2bv+Ddm7/g3Zu/4N2 + bv+Ddm7/g3Zu/4N2bv+Ddm7/g3Zu/2tgW/9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/wAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAABCOzj/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19U + UP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP+Ddm7/bmNe/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQjs4/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19U + UP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/4N2 + bv9uY17/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEI7OP9fVFD/X1RQ/19U + UP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19U + UP9fVFD/X1RQ/19UUP9fVFD/g3Zu/4N2bv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9zZ2L/dmpk/wAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AABCOzj/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19U + UP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/T0ZD/0I7OP9COzj/Qjs4/0I7OP9COzj/Qjs4/0I7 + OP9COzj/Qjs4/0I7OP9COzj/Qjs4/0I7OP9COzj/Qjs4/0I7OP9COzj/Qjs4/0I7OP9COzj/Qjs4/wAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAQjs4/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19U + UP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/wAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEI7OP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19U + UP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19U + UP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABCOzj/X1RQ/19U + UP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19U + UP9fVFD/X1RQ/19UUP9fVFD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAQjs4/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19U + UP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/Qjs4/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABCOzigQjs4/0I7OP9COzj/Qjs4/0I7OP9COzj/Qjs4/0I7 + OP9COzj/Qjs4/0I7OP9COzj/Qjs4/0I7OP9COzj/Qjs4/0I7OP9COzj/Qjs4/wAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA//////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////+AAD///////4AAH///////AAAf/// + ///8AAB//gAAAAAAAH/+AAAAAAAAf/4AAAAAAAB//gAAAAAAAH/+AAAAAAAAf/4AAAAAAAB//gAAAAAA + AH/+AAAAAAAAf/4AAAAAAAB//gAAAAAAAf/+AAAAAAAB//4AAAAAAAH//gAAAAAAAf/+AAAAAAAB//4A + AAAAAAH//gAAAAAAAf/+AAAAAAAB//4AAAAAAAH//gAAAAAAA//+AAAAAAAH//4AAAAAAA///gAAAAAA + D//+AAAAAAAP//4AAAAAAA///gAAAAAAD//+AAAAAAAP//4AAAAAAA///gAAAAAAD//+AAAAAAAP//4A + AAAAAA///gAAAAAAD//+AAAAAAAP//4AAAAAAB///gAAB//////+AAAH//////4AAAf//////gAAB/// + ////AAAP//////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////8= + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/FolderLocker/AccountForm.Designer.cs b/Demo_Source_Code/CSharpDemo/FolderLocker/AccountForm.Designer.cs new file mode 100644 index 0000000..ada4d34 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FolderLocker/AccountForm.Designer.cs @@ -0,0 +1,159 @@ +namespace EaseFilter.FolderLocker +{ + partial class AccountForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(AccountForm)); + this.label1 = new System.Windows.Forms.Label(); + this.label2 = new System.Windows.Forms.Label(); + this.textBox_EmailAddress = new System.Windows.Forms.TextBox(); + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.textBox_Password = new System.Windows.Forms.TextBox(); + this.button_SignIn = new System.Windows.Forms.Button(); + this.button_SignUp = new System.Windows.Forms.Button(); + this.groupBox1.SuspendLayout(); + this.SuspendLayout(); + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(20, 16); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(128, 19); + this.label1.TabIndex = 0; + this.label1.Text = "Enter email address"; + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(20, 53); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(120, 19); + this.label2.TabIndex = 1; + this.label2.Text = "Enter the password"; + // + // textBox_EmailAddress + // + // + // + // + this.textBox_EmailAddress.Lines = new string[] { + "user@myemail.com"}; + this.textBox_EmailAddress.Location = new System.Drawing.Point(176, 16); + this.textBox_EmailAddress.Name = "textBox_EmailAddress"; + this.textBox_EmailAddress.PasswordChar = '\0'; + this.textBox_EmailAddress.ScrollBars = System.Windows.Forms.ScrollBars.None; + this.textBox_EmailAddress.SelectedText = ""; + this.textBox_EmailAddress.SelectionLength = 0; + this.textBox_EmailAddress.SelectionStart = 0; + this.textBox_EmailAddress.ShortcutsEnabled = true; + this.textBox_EmailAddress.Size = new System.Drawing.Size(162, 20); + this.textBox_EmailAddress.TabIndex = 2; + this.textBox_EmailAddress.Text = "user@myemail.com"; + // + // groupBox1 + // + this.groupBox1.Controls.Add(this.textBox_Password); + this.groupBox1.Controls.Add(this.label1); + this.groupBox1.Controls.Add(this.textBox_EmailAddress); + this.groupBox1.Controls.Add(this.label2); + this.groupBox1.Location = new System.Drawing.Point(12, 56); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size(359, 86); + this.groupBox1.TabIndex = 3; + this.groupBox1.TabStop = false; + // + // textBox_Password + // + // + // + // + + this.textBox_Password.Lines = new string[0]; + this.textBox_Password.Location = new System.Drawing.Point(176, 53); + this.textBox_Password.MaxLength = 32767; + this.textBox_Password.Name = "textBox_Password"; + this.textBox_Password.PasswordChar = '●'; + this.textBox_Password.ScrollBars = System.Windows.Forms.ScrollBars.None; + this.textBox_Password.SelectedText = ""; + this.textBox_Password.SelectionLength = 0; + this.textBox_Password.SelectionStart = 0; + this.textBox_Password.ShortcutsEnabled = true; + this.textBox_Password.Size = new System.Drawing.Size(162, 20); + this.textBox_Password.TabIndex = 3; + this.textBox_Password.UseSystemPasswordChar = true; + this.textBox_Password.KeyDown += new System.Windows.Forms.KeyEventHandler(this.textBox_Password_KeyDown); + // + // button_SignIn + // + this.button_SignIn.Location = new System.Drawing.Point(188, 160); + this.button_SignIn.Name = "button_SignIn"; + this.button_SignIn.TabIndex = 4; + this.button_SignIn.Text = "Sign In"; + this.button_SignIn.UseVisualStyleBackColor = true; + this.button_SignIn.Click += new System.EventHandler(this.button_SignIn_Click); + // + // button_SignUp + // + this.button_SignUp.Location = new System.Drawing.Point(296, 160); + this.button_SignUp.Name = "button_SignUp"; + this.button_SignUp.TabIndex = 5; + this.button_SignUp.Text = "Register"; + this.button_SignUp.UseVisualStyleBackColor = true; + this.button_SignUp.Click += new System.EventHandler(this.button_SignUp_Click); + // + // AccountForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(391, 197); + this.Controls.Add(this.button_SignUp); + this.Controls.Add(this.button_SignIn); + this.Controls.Add(this.groupBox1); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "AccountForm"; + this.Text = "Account Information"; + this.groupBox1.ResumeLayout(false); + this.groupBox1.PerformLayout(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.TextBox textBox_EmailAddress; + private System.Windows.Forms.GroupBox groupBox1; + private System.Windows.Forms.TextBox textBox_Password; + private System.Windows.Forms.Button button_SignIn; + private System.Windows.Forms.Button button_SignUp; + } +} \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/FolderLocker/AccountForm.cs b/Demo_Source_Code/CSharpDemo/FolderLocker/AccountForm.cs new file mode 100644 index 0000000..01d9352 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FolderLocker/AccountForm.cs @@ -0,0 +1,209 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +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; +using System.Text.RegularExpressions; + +using EaseFilter.CommonObjects; + +namespace EaseFilter.FolderLocker +{ + public partial class AccountForm : Form + { + public static string accountName = string.Empty; + public static string password = string.Empty; + public static bool isAuthorized = false; + + public AccountForm() + { + InitializeComponent(); + + textBox_EmailAddress.Text = GlobalConfig.AccountName; + + this.StartPosition = FormStartPosition.CenterScreen; + } + + private void button_SignIn_Click(object sender, EventArgs e) + { + button_SignIn.Enabled = false; + + try + { + accountName = textBox_EmailAddress.Text.ToLower().Trim(); + password = textBox_Password.Text.Trim(); + + if (string.IsNullOrEmpty(accountName)) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("The email name can't be empty.", "account", MessageBoxButtons.OK, MessageBoxIcon.Error); + + return; + + } + + if (string.IsNullOrEmpty(password.Trim())) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("The password can't be empty.", "password", MessageBoxButtons.OK, MessageBoxIcon.Error); + + return; + + } + + if (accountName.IndexOf('@') <= 0 || accountName.IndexOf('.') <=0 ) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("The email name " + accountName + " is invalid.", "account", MessageBoxButtons.OK, MessageBoxIcon.Error); + + return; + } + + + GlobalConfig.AccountName = accountName; + GlobalConfig.SaveConfigSetting(); + + string lastError = string.Empty; + + isAuthorized = WebFormServices.SignInAccount(accountName, password, ref lastError); + + if (!isAuthorized) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show(lastError, "SignIn", MessageBoxButtons.OK, MessageBoxIcon.Error); + + return; + } + else + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("Log in successfully.", "SignIn", MessageBoxButtons.OK, MessageBoxIcon.Information); + + return; + } + + + } + catch (Exception ex) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("Sign in account failed with error" + ex.Message, "SignIn", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + finally + { + button_SignIn.Enabled = true; + + if (isAuthorized) + { + this.Close(); + } + } + } + + + private void textBox_Password_KeyDown(object sender, KeyEventArgs e) + { + if (e.KeyCode == Keys.Enter) + { + button_SignIn_Click(null, null); + } + + } + + private void button_SignUp_Click(object sender, EventArgs e) + { + + button_SignUp.Enabled = false; + + try + { + accountName = textBox_EmailAddress.Text.ToLower().Trim(); + password = textBox_Password.Text.Trim(); + + if (string.IsNullOrEmpty(accountName)) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("The account name can't be empty.", "account", MessageBoxButtons.OK, MessageBoxIcon.Error); + + return; + + } + + if (accountName.IndexOf('@') <= 0 || accountName.IndexOf('.') <= 0) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("The email name " + accountName + " is invalid.", "account", MessageBoxButtons.OK, MessageBoxIcon.Error); + + return; + } + + if (string.IsNullOrEmpty(textBox_Password.Text.Trim())) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("The password can't be empty.", "password", MessageBoxButtons.OK, MessageBoxIcon.Error); + + return; + + } + + if (password.Length < 7 || !Regex.IsMatch(password, @"[\d]", RegexOptions.ECMAScript) || (!Regex.IsMatch(password, @"[a-z]", RegexOptions.ECMAScript) && !Regex.IsMatch(password, @"[A-Z]", RegexOptions.ECMAScript))) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("The input password length has to be 8 or greater with alphanumeric characters.", "password", MessageBoxButtons.OK, MessageBoxIcon.Error); + + return; + + } + + GlobalConfig.AccountName = textBox_EmailAddress.Text; + GlobalConfig.SaveConfigSetting(); + + + string lastError = string.Empty; + bool retVal = WebFormServices.SignUpAccount(accountName,password, ref lastError); + MessageBoxIcon icon = MessageBoxIcon.Information; + if (!retVal) + { + icon = MessageBoxIcon.Error; + } + + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show(lastError, "SignUp", MessageBoxButtons.OK, icon); + + return; + } + catch (Exception ex) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("Sign up account failed with error" + ex.Message, "SignUp", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + finally + { + button_SignUp.Enabled = true; + this.Close(); + } + } + + + } +} diff --git a/Demo_Source_Code/CSharpDemo/FolderLocker/AccountForm.resx b/Demo_Source_Code/CSharpDemo/FolderLocker/AccountForm.resx new file mode 100644 index 0000000..a4af948 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FolderLocker/AccountForm.resx @@ -0,0 +1,570 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + AAABAAgAEBAAAAEACABoBQAAhgAAABAQAAABACAAaAQAAO4FAAAYGAAAAQAIAMgGAABWCgAAGBgAAAEA + IACICQAAHhEAACAgAAABAAgAqAgAAKYaAAAgIAAAAQAgAKgQAABOIwAAMDAAAAEACACoDgAA9jMAADAw + AAABACAAqCUAAJ5CAAAoAAAAEAAAACAAAAABAAgAAAAAAEABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP// + /wCFe3sA1LS0AOvZ2QC3kpIAuaqqAPPFxQCXi4sA1svLAKicnADkvLwAw5ycANvX1wDlzs4Apo6OANDB + wQB8c3MAlYGBAODg4ADdxMQAxK2tALWamgD3zMwA7tLSAKOVlQDAlZUA6sjIAJ2FhQCuk5MA5NXVANzR + 0QDcvr4A2ri4AMuwsADn4uIAloaGAKWJiQDk2toA7s3NAK6OjgCumJgAvJycAJ+RkQDhysoAi319AKiS + kgC5lpYAv6qqANfT0wCzlZUA6dPTAO/JyQDbzMwAvZKSANnBwQCaiIgA4dDQAOC6ugDQsrIAqZWVAMKZ + mQDzy8sA29TUAOHNzQC8mZkAw5+fAOHX1wCjjIwA2c/PAODCwgDsy8sAvpeXAOPf3wDe2NgA4dTUAKaU + lADdwcEAuZubAL+dnQDq19cA5dfXAObT0wCik5MA5tDQALyUlADp1dUAo46OAJ+TkwDp0dEA3M/PALmY + mADr0tIA3dbWANnV1QCskpIA38/PALCXlwDm2toAqpKSAKuVlQDa0dEAvpSUAOrU1ACgkpIA59TUAOLW + 1gCnkZEA5dTUAKSUlACllZUAqJSUAN3S0gDb0tIA2svLALSZmQDju7sA27e3ANGzswCaiYkA3dfXAK6S + kgDhz88ArpeXAL6VlQDAlpYAmYiIAO3S0gCfkpIA5dXVAOHW1gDc1tYAqJGRAKmSkgCklZUAtJWVAL+V + lQC6m5sA4bq6AM+ysgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAFcua2tuhhloKyuACAAAAAApgR5RS3F4XYMNMVgAAAAAe0eHOAoTAQEBAV6A + AAAAAGFnUARQUjk1CUpFaAAAAABhRy95RCQCEGUBP1MAAAAAiX9ZXDNnVnpaI3BtAAAAACobW193Bg4s + ckkfTAAAAABBJ0ZNNxhqAQEBQ28AAAAASCdGTTcYQIJLgmA8AAAAAEg0Mg9+i2IBAQEmZAAAAAB8Pooh + diBZaVJsVIQAAAAAZhd0Czp1AzsiFRSFAAAAABoHVQUoJRwSLREwYwAAAAA2iIh9PQxCT04Wcx0AAAAA + AAAAAAAAAAAAAAAAAAD//wAAwAMAAMADAADAAwAAwAMAAMADAADAAwAAwAMAAMADAADAAwAAwAMAAMAD + AADAAwAAwAMAAMADAAD//wAAKAAAABAAAAAgAAAAAQAgAAAAAABABAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAKSPj/qpk5P9qJKS/aiSkv2mlpb8pZaW/KSWlvyhk5P9oJKS/aCSkv2gk5P9mIyM/AAA + AAAAAAAAAAAAAAAAAACwmZn95dXV/+TV1f/l19f/4dTU/9vS0v/d19f/3dbW/9zW1v/b19f/19PT/6CU + lP0AAAAAAAAAAAAAAAAAAAAAsJiY/ezLy/+0lZX/moiI/6icnP/g4OD//////////////////////9nV + 1f+gk5P9AAAAAAAAAAAAAAAAAAAAALKYmP3q1NT/6tfX/+vZ2f/q19f/5tPT/+HQ0P/bzMz/1svL/97Y + 2P/Zz8//oZOT/QAAAAAAAAAAAAAAAAAAAACymJj97MvL/7mWlv+ukpL/o4yM/5aGhv+Fe3v/0MHB/9rR + 0f//////29TU/6OUlP0AAAAAAAAAAAAAAAAAAAAAu5yc/O3S0v/p0dH/69LS/+nT0//q1NT/6dXV/+HP + z//cz8//5+Li/93S0v+llZX9AAAAAAAAAAAAAAAAAAAAAL2dnfzqyMj/uZiY/6ySkv+aiYn/uaqq/+XO + zv/hysr/2svL/+Pf3//c0dH/p5WV/QAAAAAAAAAAAAAAAAAAAAC+mpr97s3N/+DCwv/dwcH/2cHB/+7S + 0v/i1tb/////////////////4dfX/6mVlf0AAAAAAAAAAAAAAAAAAAAAwJiY/e7Nzf/gwsL/3cHB/9nB + wf/u0tL/4c3N/+HW1v/h1NT/4dbW/9/Pz/+rlpb9AAAAAAAAAAAAAAAAAAAAAMCYmP3vycn/s5WV/6aO + jv+ZiIj/z7Ky/+ba2v/////////////////k2tr/rZaW/QAAAAAAAAAAAAAAAAAAAADAlpb988vL/+G6 + uv/auLj/0bOz/9y+vv/p0dH/59TU/+bT0//l1NT/5tDQ/6mSkv0AAAAAAAAAAAAAAAAAAAAAwJWV/ffM + zP/ju7v/5Ly8/+C6uv/bt7f/1LS0/9Cysv/LsLD/xK2t/93ExP+rk5P9AAAAAAAAAAAAAAAAAAAAAMKW + lv3zxcX/vJSU/7eSkv+ujo7/pYmJ/52Fhf+VgYH/i319/3xzc/+/qqr/rJOT/QAAAAAAAAAAAAAAAAAA + AAC/k5P6wZaW/cGWlv3Cl5f9xJqa/cWdnf3FoKD9wZ6e/bucnP23m5v9tpqa/bCUlPsAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAD//wAAwAMAAMADAADAAwAAwAMAAMADAADAAwAAwAMAAMADAADAAwAAwAMAAMADAADAAwAAwAMAAMAD + AAD//wAAKAAAABgAAAAwAAAAAQAIAAAAAACgAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8AlXh4AOCx + sQBeXV0ApqKiAP/U1ADUz88AypqaAK2HhwB7bW0A5uDgAMGtrQDpxMQAnZOTAM67uwC1mJgA6tLSAPP1 + 9QCZhIQAh39/ALuMjAC/oqIAa2NjANCkpADdvb0A0cXFAN7X1wDTrq4A4czMAKmQkAD2zs4AsqSkAIt0 + dACkmpoApYKCAIJ4eADnu7sAcmhoAPXV1QCcfX0A3MTEAM20tACtm5sAyKGhAPj7+wCciooAyq6uAMGc + nADxyckA29HRANjKygC5q6sAgnBwANm4uACcm5sAuJOTAOPb2wC3oKAA1bS0AOrKygCulpYA49LSANHK + ygCvoKAA8NDQAOLCwgC6nJwAo5SUAIh4eADh4OAA6M7OAJ+PjwC2j48A0be3AHNsbADX09MAqIyMALaK + igC+qakAqZSUAMilpQC5p6cA+tPTAOXJyQDdyckAqIiIANi8vADWq6sAtJ2dAM2goACXiooApJCQAIuB + gQDtxsYA1sfHAMSfnwDs1dUA9Pj4AP7R0QD00tIA4s/PANrU1ADX0NAAm46OAOK/vwDRsrIAu5+fAPv9 + /QD50NAAmX9/APLU1ADm1NQA3s7OANDNzQCmlpYA1MPDAKuiogDHsLAA4NHRANnHxwC0oKAAxa2tAO7S + 0gDs0NAA2szMAKWgoACooKAAs5qaALiamgCwnp4AsKKiANO1tQDKo6MAw6urAOPh4QDzz88A5dDQAN3T + 0wDlzc0Aq5eXAMKhoQD5+fkA5t7eAPfS0gDn0tIA6dDQAOHKygDmxMQA0sfHANGiogDFoaEAzaSkAPrV + 1QD20NAA1cnJAKakpACroKAAt6KiAL+goADZuroAwqOjAPb6+gD+09MA+NTUAO/PzwDqzc0A2dLSAN/P + zwDZz88A3svLANjIyAC/nZ0Az6GhAMyvrwD6+/sA/NHRAPLS0gDw0tIA7NLSAOXS0gDn0NAA2NTUAOPN + zQCpoqIA1s/PAK6iogDcy8sA0s3NANrKygC6oKAAtKSkANPJyQC9oKAAyqGhANWurgDPsrIA/9LSAPvU + 1ADh398A99XVAPbU1AD01NQA+NHRAOPa2gD00dEA69PTAOvR0QC2l5cA5NPTAOrPzwDi0dEA5s/PAOHQ + 0ADc0NAA4c7OANbR0QDa0NAA4szMANTQ0ADfzc0Aw6CgAMagoADgyckAyaCgANnLywDQy8sA0qOjANrG + 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 + lv+plJT/pJCQ/5+Pj/+Xior/sJ6e//LU1P+9oqL4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA0KKi+P/S + 0v/gsbH/u4yM/7aKiv+th4f/pYKC/5x9ff+VeHj/i3R0/4JwcP97bW3/cmho/2tjY/9eXV3/h39///XV + 1f+/oqL4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1KSk+P/U1P/+0dH//tPT//7S0v/90tL//dPT//3T + 0//71NT/+9TU//rV1f/609P/+tTU//jU1P/41NT/9tLS//XU1P/CpKT4AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAzpub8dWlpfjSo6P40aOj+NCjo/jQo6P4zaOj+Myjo/jLo6P4yqOj+Mmjo/jIo6P4x6Oj+Maj + o/jFo6P4xKOj+MWlpfi6m5vxAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA////AOAABwDgAAcA4AAHAOAABwDgAAcA4AAHAOAABwDgAAcA4AAHAOAABwDgAAcA4AAHAOAA + BwDgAAcA4AAHAOAABwDgAAcA4AAHAOAABwDgAAcA4AAHAOAABwD///8AKAAAACAAAABAAAAAAQAIAAAA + AACABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8AlXR0ANO2tgBJTEwA/tTUAKuZmQBqZmYA1tLSAOjr + 6wC0hIQAx5iYAPLExAC8r68AgWtrAF5YWADSpqYAl5SUAM7ExADq09MAoYGBAOG/vwDy9vYA3uHhAH53 + dwC/jIwA4crKAMW3twC2k5MAs6ioAGBhYQD3zs4AiHJyAHZlZQCik5MAVlJSAJ55eQBrXl4A18nJAKyA + gADXvb0A7s3NAPXV1QDg0tIAwJOTAMbAwADqvb0AybGxANy4uADOvLwArYeHAJmZmQCtk5MAd2trAJV6 + egC0iooA+fv7ANzFxQDv8fEAjG1tALOYmABkXFwA+tjYAObOzgDczs4A0s3NAMStrQBxYWEA18LCAOLl + 5QCPdnYA6MnJAKeDgwCcfn4Afm9vANvd3QDx0NAAy8jIAMy1tQCclJQA/NDQAOO7uwDMwMAAZGRkAJBw + cAC4jY0Ap5aWANzCwgDdvLwA07q6AHJqagD51NQAhmxsAINxcQCYd3cA4cbGANDKygBvZmYA8szMAOXS + 0gDc0tIA28nJANi2tgC7k5MA0r29ALyKigDWqKgAinV1AOzQ0ADY1dUAoHx8ANTFxQDz8/MA9tDQAOHP + zwDXzMwA2Lq6AKiTkwDOubkAs5WVAMa0tABNTU0AaGNjAJFzcwDmzMwA08HBAJeWlgB7bW0A59XVAN7M + zADDlZUAybe3APv9/QBiWloA9tbWAO/OzgDo0NAA3dDQANnQ0ADU0NAA48jIANDHxwDYwMAAc2RkAPvV + 1QD/0dEA+tDQAOrNzQDjzc0AqX5+AOC6ugDVwMAAycHBANC1tQBKTk4A/P//APHz8wCBaWkAkHh4APPS + 0gDw0tIA5NDQAK2BgQDVzs4A2szMANTMzACZlJQA5ry8AOS9vQCflJQAzcbGAKWTkwDcv78A0cPDAM3C + wgCwk5MAz8DAALOTkwDLs7MAZGJiAPnR0QDyz88A0MzMANO4uABgWVkA9Pf3AOrs7AD719cA4OLiAPnW + 1gD709MA99LSAPTPzwDu0dEA9czMAOzS0gDo09MA7M7OAOvPzwDi0dEA4c3NALKJiQDkysoA38nJALqM + jAC9jY0A0srKAKmVlQDewMAA28LCANq7uwDUvb0A1bu7ANG7uwDWt7cA1bW1ANK0tADHuLgA+/v7AIRs + bADw9vYA8PHxAKB5eQDwzMwA5tHRAOjOzgDe0tIA39DQANjS0gDb0NAA19DQAN3OzgCrk5MA2c7OANzM + zADTzs4AuZOTAL6TkwDYyckA2MLCANXBwQByYmIAdWRkAHZqagD9/v4A8/X1AJd2dgCbfX0A/9XVAP/T + 0wD519cAooCAAPzU1AD61NQA/dHRAPfV1QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAGVqsiIiKpqampqU9PT0+mpqamERERfjMAAAAAAAAAAM+Ax+Pj44mJiYnliuWKiuaK5ovmi4ttfgAA + AAAAAAAAdWOB6oGkpKSkpHNzc6VzpaVBQUG2QQgRAAAAAAAAAAB1oYHjcuOJ44lAjeulpUFBQUFBQU22 + CBEAAAAAAAAAAHVjcllZdoMbDe7mAdra2tra2tr0CWAIpgAAAAAAAAAANODHaZX22/EjG6P13d3d3d3d + 3XC8zgimAAAAAAAAAAA0iHKhoWOAxGPHb65SUphSmJiYmC1z5KYAAAAAAAAAADSIlJShcqFycnJycuPj + iUCkqs5gqqVkTwAAAAAAAAAANIg/V1fR70SXaGgxMdkmQGUJAQG6JmRPAAAAAAAAAACvbIgZCifeAjud + ISW4eR1yZRdwcLwm4k8AAAAAAAAAAK9sP3x8P5Q/lJRylHKBcoGBUhISmKTiqQAAAAAAAAAAr8F8iD+I + iOCIiOCUyMjIgYGNc3ONpCupAAAAAAAAAACxwcbQrKwo1NV2eIjIyMiBgUUBAQllK6kAAAAAAAAAALHB + bGknJFSdQ4UEw5TIyMiBS5xwvGUrIgAAAAAAAAAAsaDFxWxsbGxswz/hlHyUlJSwra1SgcciAAAAAAAA + AAAcTClsbGzBwcHG4T856aRzc+lz6aVlxyIAAAAAAAAAAByfTBVY0nS3TlnG4WgBhISEhIT0uUTEIgAA + AAAAAAAAHJ9MLJVeXPIPGKCT0xY6Ojo6OpwJRMSrAAAAAAAAAADscYe1TJ+fKp+HxZOMRPDw8PB9fa0a + xKsAAAAAAAAAAOxx30y1TExMTEzBxV/iQEDnQEBAc8sTqwAAAAAAAAAA7L/AqJYwZtYDmUKHKJs4ODg4 + OIS50RN1AAAAAAAAAABntHGCom57Do89mkeO3Do6Ojo6nAlXE3UAAAAAAAAAAGe0H3G/v79b/ZC/wEfv + jo6XjpdEfcrDdQAAAAAAAAAAZ/7CwmLCYmLfYt8pKd+HKSkpk5OT4cPoAAAAAAAAAADt/h+Svr78/P39 + kJC9vbu7u/o+PirGwTQAAAAAAAAAAO3+khBVVckySBRJNp5rXUo1WgezU4agNAAAAAAAAAAALJFQas3M + NzJI+/c2RiBdf/Nheh4e+qA0AAAAAAAAAAAskVAMLi6np1GWljAwZmbX2JmZsi+fn68AAAAAAAAAAIL4 + kZH5+fn5+fkFBQX8/JCQkL29W5//dwAAAAAAAAAAC4IsLCzt7WdnZ2fs7OwcHBwcsbGxsXc8AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AA + AA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AA + AA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/////8oAAAAIAAAAEAAAAABACAAAAAAAIAQ + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAArJiY56iWlvCllJTwpJSU8KSU + lPCilJTwoZSU8KCUlPCglJTwn5SU8J6UlPCdlJTwnJSU8JyUlPCblJTwmpSU8JmUlPCZlJTwmJSU8JeU + lPCWlJTwlpSU8JaWlvCYmJjnAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACrlpb159XV/+LR + 0f/g0ND/39DQ/+DQ0P/e0ND/3dDQ/9zQ0P/d0ND/29DQ/9rQ0P/b0ND/2dDQ/9jQ0P/X0ND/2NDQ/9bQ + 0P/V0ND/1tDQ/9TQ0P/T0dH/2NXV/5iWlvUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKmU + lPXk0tL/3s3N/9zMzP/dzMz/28zM/9rMzP/ZzMz/2czM/9nMzP/YzMz/2MzM/9bMzP/VzMz/1szM/9TM + zP/TzMz/0szM/9LMzP/RzMz/0MzM/9HNzf/V0tL/l5SU9QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAqpSU9eTR0f/ezMz/38/P/+DPz//fz8//3tDQ/9/Q0P/e0ND/3M7O/9DHx//Tzs7/08zM/9PM + zP/SzMz/0szM/9LMzP/RzMz/0czM/9LNzf/LyMj/0MvL/9XS0v+YlJT1AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACrlJT15dHR/+HPz//Tu7v/0rq6/825uf/Jt7f/xba2/7yvr//Yycn/19HR//7/ + ///7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v//f7+/+nr6//Qycn/1tLS/5mUlPUAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAK6UlPXm0dH/49HR/7uKiv+pfn7/l3Z2/4RsbP9yYmL/VlJS/8W3 + t//Vzs7/8/X1//Dx8f/w8fH/8PHx//Dx8f/w8fH/8PHx//Dx8f/z8/P/4OHh/9LKyv/X0tL/mpSU9QAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAArpSU9efR0f/izs7/5NDQ/+TR0f/l0tL/5tTU/+fT + 0//l0tL/4tDQ/9TFxf/NwsL/y8DA/8zAwP/KwMD/y8DA/8nBwf/KwcH/yMHB/8rBwf/GwMD/1svL/9jS + 0v+blJT1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACvlJT16NHR/+TMzP/jzs7/48/P/+LP + z//jz8//4s/P/+HPz//hz8//4dDQ/+HQ0P/g0ND/4NDQ/93Pz//bzs7/28vL/83Gxv/Sysr/0MrK/8zG + xv/Vy8v/29LS/5yUlPUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALCUlPXp0dH/5s/P/9zC + wv/cwcH/28LC/9jCwv/XwcH/1b+//9K+vv/Rvb3/zry8/868vP/HuLj/18jI/9zOzv/aycn/6Ovr//7/ + ////////6uzs/9bJyf/c0tL/nZSU9QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsZSU9ezR + 0f/o0dH/v4yM/7SEhP+sf3//oHl5/5V0dP+MbW3/gGlp/3ZlZf9rXl7/YFlZ/01NTf+zqKj/4M/P/9vJ + yf/e4eH/8/T0//P09P/g4uL/18nJ/93S0v+elJT1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACylJT17NHR/+fOzv/my8v/5czM/+bOzv/kzc3/5c7O/+POzv/jzc3/4s7O/+LNzf/izs7/3szM/+DP + z//ezc3/3cvL/8zBwf/OxMT/zsTE/8nBwf/Zy8v/3tLS/5+UlPUAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAALOUlPXt0dH/58zM/+jPz//nz8//6NDQ/+fQ0P/m0ND/6NHR/+fR0f/m0dH/5M7O/+HN + zf/gzc3/4MzM/97MzP/ezMz/0MbG/9bLy//Wy8v/z8fH/9rLy//f0tL/oJSU9QAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAtJSU9e7R0f/qz8//3sDA/9y/v//bv7//1729/9W7u//Ru7v/zrm5/8a0 + tP/n0ND/4czM/+DMzP/gzMz/38zM/97Ly//i5eX//v////7////o6+v/2snJ/+DS0v+hlJT1AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC1lJT179HR/+zR0f+8ior/rICA/555ef+QcHD/gWlp/3Fh + Yf9iWlr/SUxM/+vS0v/izMz/4czM/+HMzP/gzMz/38vL/9vd3f/x8/P/8vPz/9/i4v/bycn/4dLS/6KU + lPUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALaUlPXw0dH/687O/+zNzf/s0ND/69DQ/+zQ + 0P/r0ND/7NHR/+vS0v/nzs7/6c7O/+TMzP/lzMz/48zM/+LMzP/jzMz/z8DA/9HDw//Qw8P/zMHB/9/L + y//i0tL/o5SU9QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAt5SU9fHR0f/tzMz/7c/P/+3P + z//s0ND/7tDQ/+3R0f/t0dH/6s/P/+jOzv/mzc3/3MXF/9nOzv/ZzMz/18zM/9jNzf/Zzc3/2M3N/9nN + zf/Vy8v/2snJ/+PS0v+klJT1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC4lJT19NHR//DP + z//hv7//3by8/9q7u//Yurr/07i4/8y1tf/Turr/68/P/+jNzf/Svb3///////v8/P/7/Pz/+/z8//v8 + /P/7/Pz//P7+//T39//WwsL/59PT/6WUlPUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALmU + lPX00dH/8dHR/8CSkv+pfn7/mHd3/4ZsbP91ZGT/XlhY/353d//w0tL/6c3N/9S9vf/y9vb/7/Hx/+/x + 8f/v8fH/7/Hx/+/x8f/w8/P/6Ozs/9fCwv/n09P/ppSU9QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAupSU9fXR0f/wzs7/8s7O//LR0f/z0dH/89LS//TU1P/y0tL/78/P/+zOzv/pzc3/48jI/9bC + wv/VwcH/1cHB/9TBwf/UwcH/08HB/9PBwf/RwsL/4crK/+jS0v+nlJT1AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAC7lJT19tHR//DMzP/xz8//8s/P//LQ0P/x0ND/8dDQ//LR0f/x0dH/79DQ/+3O + zv/hxsb/3tHR/9zOzv/czs7/3c7O/9vOzv/bzs7/3M/P/9jNzf/fycn/6dLS/6iUlPUAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAALyUlPX30dH/9M/P/+S9vf/gu7v/3Lm5/9m3t//Wt7f/07a2/8+0 + tP/Era3/787O/9e9vf/8////+fv7//n7+//5+/v/+fv7//n7+//7/f3/8/f3/9rCwv/q09P/qZSU9QAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAvZSU9fjR0f/20ND/w5SU/62Bgf+gfHz/kXNz/4Fr + a/9zZGT/ZFxc/0pOTv/oycn/2b+///D29v/u8fH/7/Hx/+/x8f/v8fH/7/Hx//Dz8//o7Oz/3MLC/+vT + 0/+qlJT1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC+lJT1+dHR//bOzv/3z8//99LS//jS + 0v/40tL/+dPT//nU1P/61dX/99LS//PPz//nyMj/2MLC/9fAwP/YwMD/1sDA/9fAwP/VwMD/1sHB/9LB + wf/kysr/69LS/6uUlPUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL+UlPX80dH/9czM//TM + zP/zzMz/9MzM//LMzP/xzMz/8MzM//HMzP/vzMz/7szM/+7Nzf/wzc3/783N/+3Nzf/uzc3/7c3N/+vN + zf/qzc3/683N/+jNzf/s0tL/rZSU9QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwJSU9fzR + 0f/3zc3/+c/P//vS0v/709P//NTU//vU1P/61NT/+tTU//zV1f/71dX/+tbW//nW1v/719f/+tfX//rX + 1//519f/+djY//rY2P/11dX/68/P/+3R0f+ulJT1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AADBlJT1/dHR//rQ0P/Spqb/uIyM/7iNjf+yiYn/rIeH/6eDg/+hgYH/nH5+/5V6ev+QeHj/inV1/4Nx + cf9+b2//d2tr/3Jqav9qZmb/ZGJi/2RkZP/21tb/8NHR/66UlPUAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAMKUlPX+0dH//NDQ/9aoqP+9jY3/uoyM/7SKiv+thob/p4OD/6KAgP+bfX3/lHp6/492 + dv+IcnL/gnFx/3ttbf92amr/b2Zm/2hjY/9gYGD/YGFh//jX1//w0dH/sJSU9QAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAw5SU9f/S0v/8z8//8sTE/+q9vf/pvLz/5ru7/+W8vP/ju7v/4Lq6/9+5 + uf/duLj/3Le3/9i2tv/Xtrb/1bW1/9K0tP/QtbX/z7S0/8uzs//JsbH/8tLS//LS0v+xlJT1AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADGlpb1/9XV///R0f//0tL//9PT///T0///09P//tPT///T + 0//+09P//dTU//7U1P/91NT//NTU//vU1P/81dX/+9XV//rV1f/51dX/+dXV//jU1P/00tL/99XV/7SW + lvUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMqYmO3Glpb1w5SU9cKUlPXClJT1wZSU9cCU + lPW/lJT1vpSU9b6UlPW9lJT1vJSU9buUlPW6lJT1uZSU9bmUlPW4lJT1t5SU9baUlPW1lJT1tZSU9bSU + lPW1lpb1tZiY7QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/////wAAAP8AAAD/AAAA/wAAAP8AAAD/AA + AA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AA + AA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA//////KAAAADAAAABgAAAAAQAIAAAA + AACACgAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8AlXR0ANO2tgBJTEwA/tTUAKuZmQBqZ2cA1NLSAOjr + 6wC0hIQAxJycAPHAwAC7ra0AgWtrAF5YWADNpqYAlYyMAM7ExADq09MAn4ODAOK/vwDy9vYA3+DgAIF4 + eADAjo4A4svLAMW3twC2k5MAuKOjAF9fXwD4zc0AhnR0AHZlZQChkZEAVlJSAJ55eQBrXl4A18nJAKyA + gADYvr4A7s3NAPXV1QDg0tIAwJKSAMS+vgDrv78AzK+vANy4uADOvr4ArIiIAJuYmACulJQAdm1tAJR9 + fQC0i4sA+fr6ANvFxQDu8PAAjG1tALSamgBkXFwA+tjYAObOzgDczc0A0s3NAMSpqQBxYWEA1sTEAOTm + 5gCNdnYA58fHAKaFhQCYgYEAfnBwANvb2wDw0NAAyMbGAMy1tQCdk5MA/M/PAOa1tQDLv78AZGRkAJBw + cAC4jo4ApZiYANzDwwDdvb0A07m5AHFqagD51NQAhmxsAIJycgCYd3cA4cbGANDKygBuaGgA8szMAOXS + 0gDc0tIA28nJANi2tgC7lZUA0r6+ALyKigDVra0AiHZ2AO3PzwDX19cAoHx8ANXGxgDz8/MA9dHRAOHP + zwDXzc0A2Lu7AKmRkQDPuroAs5WVAMi1tQBNTU0AamRkAJFzcwDnzMwA0sLCAJmXlwB6bm4A59XVAN7M + zADClpYAy7e3APz9/QBiWloA9tbWAO/OzgDpz88A3s/PANnQ0ADT0dEA5MfHANDHxwDYwMAAc2RkAPvV + 1QD/0dEA+s/PAOrNzQDjzc0AqX5+AOK2tgDVwMAAyMHBANC1tQBKTk4A/P//APHz8wCBaWkAjnl5APXS + 0gDw0tIA5M/PAK2BgQDVzc0A2szMANTMzACakZEA576+AOW/vwCgl5cAysXFAKaUlADcvr4A0cPDAMzD + wwCwkJAA0L+/ALSQkADPsbEAZGFhAPnR0QDyz88A0M3NANO4uABgWVkA9vf3AOzu7gD719cA4uPjAPnW + 1gD709MA99LSAPXPzwDv0NAA9czMAOzS0gDo09MA7M7OAOvPzwDi0tIA4c3NALCKigDlyckA3snJALqN + jQC9jo4A0srKAKmVlQDewMAA28LCANq8vADVvr4A1rq6ANG6ugDWt7cA1bW1ANGzswDGu7sA+/v7AIRs + bADw9vYA8PHxAKB5eQDvzMwA5tHRAOjOzgDe0tIA4NDQANjS0gDb0NAA19DQAN7OzgCrk5MA2c3NANzM + zADQz88AuZWVAL6VlQDZysoA2cPDANXCwgByYmIAdWRkAHZqagD9/v4A9PX1AJd2dgCZfX0A/9XVAP/T + 0wD519cAoYCAAPzU1AD61NQA/dHRAPfV1QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + 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 + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACrmZnaq5iY56mYmOeql5fnqJeX56mXl+eml5fnp5eX56WX + l+eml5fnpJeX56WXl+ejl5fno5eX56SXl+eil5fno5eX56GXl+eil5fnoJeX56GXl+efl5fnoJeX556X + l+efl5fnnJeX552Xl+ebl5fnnJeX55qXl+ebl5fnmZeX55mXl+eal5fnmJeX55mYmOeYmJjnmZmZ2gAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACrmJjwyLW1/9HAwP/Rv7//z7+//9C/ + v//Qv7//z7+//8+/v//Ov7//zr+//82/v//Nv7//zL+//8y/v//Lv7//y7+//8u/v//Kv7//yr+//8m/ + v//Jv7//yL+//8i/v//Hv7//x7+//8a/v//Gv7//xb+//8W/v//Ev7//xL+//8O/v//Dv7//wr+//8PA + wP+3tbX/mZiY8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACrl5fw0b+//9/O + zv/dzc3/3c3N/9zNzf/czc3/283N/9vNzf/bzc3/2s3N/9rNzf/Zzc3/2c3N/9jNzf/Yzc3/183N/9fN + zf/Xzc3/1s3N/9bNzf/Vzc3/1c3N/9TNzf/Uzc3/083N/9PNzf/Tzc3/0s3N/9LNzf/Rzc3/0c3N/9DN + zf/Qzc3/z83N/9DOzv/Bv7//mJeX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACtl5fw0b6+/97Nzf/dzMz/3MzM/9zMzP/czMz/28zM/9vMzP/azMz/2szM/9nMzP/ZzMz/2MzM/9jM + zP/YzMz/18zM/9fMzP/WzMz/1szM/9XMzP/VzMz/1MzM/9TMzP/UzMz/08zM/9PMzP/SzMz/0szM/9HM + zP/RzMz/0MzM/9DMzP/QzMz/z8zM/9DNzf/Cvr7/mZeX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACsl5fw076+/9/Nzf/ezMz/3czM/93MzP/czMz/3MzM/9vMzP/bzMz/2szM/9rM + zP/azMz/2czM/9nMzP/YzMz/2c3N/9fMzP/XzMz/2MzM/9bMzP/XzMz/1czM/9XMzP/UzMz/1MzM/9PM + zP/TzMz/08zM/9LMzP/SzMz/0czM/9HMzP/Rzc3/0MzM/9DNzf/Bvr7/m5eX8AAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACtl5fw0r6+/+DNzf/ezMz/3szM/93MzP/dzMz/3czM/9zM + zP/czMz/28zM/9vMzP/azMz/2szM/9nMzP/azc3/yL+//9TS0v/T0dH/09HR/9PR0f/U0dH/0tHR/9LR + 0f/S0dH/0tHR/9LR0f/S0dH/0tHR/9LR0f/T0dH/0dHR/9PS0v/Dv7//0s3N/9HNzf/Cvr7/mpeX8AAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACvl5fw076+/+DNzf/fzMz/4M3N/+DQ + 0P/h0ND/4NDQ/+HQ0P/g0dH/4dHR/+DS0v/h0tL/4tLS/97Pz//czc3/ycDA//39/f/5+vr/+fr6//n6 + +v/6+vr/+vr6//r6+v/6+vr/+vr6//r6+v/6+vr/+vr6//r6+v/6+vr/+vr6//3+/v/Bvb3/0s3N/9LN + zf/Dvr7/nJeX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACul5fw1L6+/+HN + zf/gzc3/2sTE/7mPj/+0kJD/rYuL/6SHh/+cg4P/lH9//4p6ev+BdXX/dW5u/6CXl//ez8//x7+///X1 + 9f/y8vL/8vLy//Ly8v/y8vL/8vLy//Ly8v/y8vL/8vLy//Ly8v/y8vL/8vLy//Ly8v/y8vL/8vLy//X2 + 9v/BvLz/083N/9PNzf/Fvr7/m5eX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACwl5fw1r6+/+LNzf/izc3/3MTE/76MjP+1i4v/rIaG/6GAgP+Ye3v/jXZ2/4Jycv93bGz/amRk/5qS + kv/g0ND/yMDA//Dw8P/u7u7/7u7u/+7u7v/u7u7/7u7u/+7u7v/u7u7/7u7u/+7u7v/u7u7/7u7u/+7u + 7v/u7u7/7u7u//Dx8f/BvLz/1M3N/9PNzf/Evr7/nJeX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACvl5fw1b6+/+PNzf/hzMz/4cvL/93Fxf/cxsb/3MXF/9rExP/YxcX/18TE/9XD + w//VwsL/0sLC/9bGxv/ezc3/y8DA/8vGxv/KxcX/ysXF/8rFxf/KxcX/ysXF/8rFxf/JxcX/ycXF/8nF + xf/JxcX/ycXF/8nFxf/IxcX/yMXF/8jGxv/HwMD/1M3N/9TNzf/Fvr7/npeX8AAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwl5fw1r6+/+PNzf/izMz/4czM/+HNzf/izc3/4M3N/+HN + zf/gzc3/4M3N/9/Nzf/fzc3/383N/97Nzf/ezMz/3c3N/93Nzf/czMz/3MzM/9vMzP/bzMz/28zM/9rM + zP/azMz/2czM/9nNzf/Zzc3/2c3N/9fNzf/Xzc3/2M3N/9bNzf/Wzc3/1MzM/9XNzf/Hvr7/nZeX8AAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACyl5fw2L6+/+TNzf/jzMz/4szM/+LM + zP/hzMz/4czM/+DMzP/gzMz/4MzM/9/MzP/fzMz/3szM/97MzP/dzMz/3czM/9zMzP/czMz/3MzM/9vM + zP/bzMz/2szM/9rMzP/ZzMz/2czM/9nLy//Evb3/yMLC/8jCwv/IwsL/yMLC/8fDw//Mw8P/1s3N/9XN + zf/Gvr7/n5eX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACxl5fw176+/+XN + zf/jzMz/5M3N/+TOzv/kzs7/5M/P/+PPz//jz8//4s/P/+PPz//hz8//4s/P/+LPz//hz8//4s/P/+HQ + 0P/h0ND/4NDQ/+DQ0P/f0ND/3s/P/9zMzP/azMz/2szM/9jJyf/f4OD//f7+//v8/P/7/Pz/+/z8//// + ///Evb3/183N/9bNzf/Hvr7/npeX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACyl5fw2L6+/+bNzf/kzMz/4cbG/8ympv/Lpqb/yaam/8Wjo//Co6P/vqCg/7uenv+4np7/tJub/6+Z + mf+tl5f/qJeX/6aUlP+hkpL/nZGR/5qPj/+VjIz/p52d/97Pz//bzMz/2szM/9jJyf/b29v/9fX1//Pz + 8//z8/P/8/Pz//b29v/Dvb3/183N/9fNzf/Ivr7/n5eX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAC0l5fw2r6+/+bNzf/mzc3/4MTE/8KPj/+/j4//uY2N/7SKiv+th4f/qIWF/6KB + gf+dfn7/lnt7/5F4eP+Ldnb/hnNz/39vb/94bGz/c2pq/21mZv9mYmL/hH19/+HQ0P/czMz/28zM/9nK + yv/X2Nj/8fHx//Dw8P/w8PD/8PDw//Lz8//FvLz/2M3N/9jNzf/Kvr7/oZeX8AAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACzl5fw2b6+/+fNzf/lzMz/5MnJ/9i1tf/XtbX/07Oz/9Cy + sv/PsbH/zLCw/8qvr//Hra3/xKys/8Krq/+/qqr/vKmp/7qoqP+3pqb/tKWl/7KkpP+uoqL/uq2t/+DO + zv/czMz/3MzM/9vKyv+/wMD/0M/P/8/Ozv/Pzs7/z87O/9DPz//EvLz/2c3N/9jNzf/Jvr7/oJeX8AAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC0l5fw2r6+/+jNzf/mzMz/583N/+bN + zf/mzs7/5c7O/+XOzv/mzs7/5M7O/+XOzv/kzs7/5M7O/+POzv/jzs7/5M7O/+LOzv/jz8//4s/P/+LP + z//hz8//4M7O/93MzP/dzMz/3czM/93Nzf/fzc3/3c3N/93Nzf/czc3/3M3N/9vNzf/bzc3/2szM/9nN + zf/Kvr7/oZeX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC2l5fw276+/+jN + zf/nzMz/5szM/+bMzP/mzMz/5czM/+XMzP/kzMz/5MzM/+PMzP/jzMz/48zM/+LMzP/izMz/4czM/+HM + zP/gzMz/4MzM/9/MzP/fzMz/38zM/97MzP/ezMz/3czM/97Nzf/Jvb3/xrq6/8W6uv/Gurr/xLq6/8S6 + uv/SxcX/2szM/9rNzf/Mvr7/o5eX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAC1l5fw3b6+/+nNzf/ozMz/6M3N/+jOzv/nzs7/6M7O/+fOzv/nzs7/6M7O/+fPz//nz8//5s/P/+bP + z//lz8//5s/P/+TOzv/hzMz/4czM/+DMzP/gzMz/38zM/9/MzP/ezMz/3szM/9/MzP/Z2Nj///////z9 + /f/8/f3//P39///////Fvb3/283N/9vNzf/Lvr7/opeX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAC2l5fw3L6+/+rNzf/ozMz/5cfH/9Ktrf/Pra3/zKys/8mqqv/FqKj/waam/72l + pf+5o6P/taGh/7Ofn/+unZ3/qZub/8u3t//kzc3/4czM/+HMzP/gzMz/4MzM/+DMzP/fzMz/38zM/9/M + zP/U09P/9vb2//T09P/09PT/9PT0//f4+P/Gvb3/3c3N/9vNzf/Mvr7/o5eX8AAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC4l5fw3b6+/+vNzf/pzc3/48TE/72MjP+4jIz/sImJ/6mF + hf+ggID/mXx8/5F5ef+IdXX/gXBw/3hsbP9vZ2f/ZGFh/66hof/mzs7/4szM/+LMzP/hzMz/4czM/+DM + zP/gzMz/38zM/+DMzP/S0dH/8fHx/+/v7//v7+//7+/v//Ly8v/HvLz/3M3N/9zNzf/Ovr7/pZeX8AAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC3l5fw376+/+vNzf/qzMz/58fH/9Ss + rP/Qq6v/zKmp/8empv/DpKT/vqKi/7mgoP+1np7/sJub/6yZmf+nl5f/oZOT/8e0tP/lzs7/48zM/+LM + zP/izMz/4czM/+HMzP/hzMz/4MzM/+LMzP/BwcH/1tfX/9XW1v/V1tb/1dbW/9bX1//Furr/3c3N/93N + zf/Pvr7/pJeX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6l5fw3r6+/+zN + zf/rzMz/683N/+vOzv/rzs7/687O/+rPz//rz8//6s/P/+rPz//qz8//6c/P/+rPz//pz8//6c/P/+bO + zv/kzMz/5czM/+TNzf/kzc3/483N/+PNzf/izc3/4s3N/+HNzf/fysr/3snJ/93Jyf/cycn/3MnJ/9vJ + yf/ezMz/3czM/93Nzf/Pvr7/ppeX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAC5l5fw376+/+3Nzf/rzMz/68zM/+vMzP/qzMz/6szM/+nMzP/pzMz/6MzM/+jMzP/nzMz/58zM/+bM + zP/mzMz/5szM/+XMzP/lzMz/5czM/9nDw//Tvr7/0r6+/9K+vv/Rvr7/0b6+/9G+vv/Qvr7/0L6+/9C+ + vv/Pvr7/z76+/8+/v//Xxsb/38zM/97Nzf/Qvr7/pZeX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAC6l5fw4L6+/+7Nzf/szMz/7c3N/+zNzf/tzs7/687O/+zOzv/rzs7/687O/+vO + zv/qzs7/687O/+rOzv/ozc3/5szM/+bMzP/lzMz/5szM/9DLy//z9fX/8fPz//Lz8//y8/P/8vPz//Lz + 8//y8/P/8vPz//Lz8//y8/P/8vPz//T29v/Lw8P/38zM/9/Nzf/Rvr7/ppeX8AAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC7l5fw4r6+/+7Nzf/tzMz/7svL/9q2tv/Ytrb/17a2/9Kz + s//Qs7P/zbCw/8mwsP/Grq7/w6ys/72pqf/cw8P/6M3N/+fMzP/mzMz/6MzM/9PNzf/4+Pj/9vb2//b2 + 9v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//j5+f/NxMT/4MzM/+DNzf/Qvr7/qZeX8AAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC9l5fw4b6+/+/Nzf/vzMz/7czM/7qM + jP+1i4v/rIeH/6KBgf+afX3/j3h4/4V0dP98bm7/cmpq/2NgYP/Er6//687O/+fMzP/nzMz/58zM/9HL + y//x8vL/7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v//Ly8v/Mw8P/4c3N/+DN + zf/Rvr7/qJeX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC8l5fw4r6+//DN + zf/uzMz/78zM/9CkpP/JoaH/w56e/7ybm/+2l5f/rpSU/6mRkf+hjY3/m4qK/5CFhf/QuLj/6s3N/+jM + zP/ozMz/6czM/8rFxf/j5eX/4uPj/+Lj4//i4+P/4uPj/+Lj4//i4+P/4uPj/+Lj4//i4+P/4uPj/+Pl + 5f/Iv7//483N/+HNzf/Tvr7/qZeX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAC+l5fw476+//HNzf/vzMz/8M3N//DOzv/xz8//8M/P//DPz//vz8//8NDQ//HQ0P/w0ND/8dDQ/+/Q + 0P/szs7/6czM/+nMzP/ozMz/6czM/93Fxf/ZwcH/18DA/9jAwP/WwMD/1sDA/9fAwP/VwMD/1cDA/9bA + wP/UwMD/1MDA/9TAwP/ax8f/4szM/+LNzf/Svr7/q5eX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAC9l5fw5b6+//HNzf/wzMz/78zM/+/MzP/vzMz/7szM/+7MzP/tzMz/7czM/+zM + zP/szMz/68zM/+vMzP/qzMz/6szM/+rMzP/pzMz/6szM/+XJyf/kyMj/48fH/+PHx//hx8f/4cfH/+LH + x//gx8f/4cfH/9/Hx//fx8f/4MfH/97IyP/iy8v/4szM/+PNzf/Tvr7/qpeX8AAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC+l5fw5L6+//LNzf/xzMz/8MzM//HNzf/wzc3/8M3N/+/N + zf/vzc3/7s3N/+7Nzf/vzc3/7c3N/+7Nzf/tzc3/7c3N/+vNzf/qzMz/6szM/8vFxf/k5+f/5OXl/+Tl + 5f/k5eX/5OXl/+Tl5f/k5eX/5OXl/+Tl5f/k5eX/5OXl/+Xn5//Kv7//5c3N/+PNzf/Vvr7/q5eX8AAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAl5fw5b6+//PNzf/xzMz/8czM/+bA + wP/lwMD/5L+//+O+vv/hv7//376+/929vf/cvLz/2ru7/9i7u//Wurr/07m5/97Bwf/tzc3/68zM/9XN + zf/4+fn/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//n5+f/PxMT/5MzM/+TN + zf/Uvr7/rZeX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC/l5fw576+//TN + zf/yzMz/8czM/7qNjf+4jIz/sImJ/6iFhf+hgID/mH19/5F5ef+IdXX/gHBw/3ltbf9waWn/ZGJi/5yQ + kP/vz8//7MzM/9HKyv/y8vL/8PDw//Dw8P/w8PD/8PDw//Dw8P/w8PD/8PDw//Dw8P/w8PD/8PDw//Lz + 8//NwsL/5czM/+XNzf/Vvr7/rJeX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AADAl5fw5r6+//TNzf/zzMz/88vL/8qbm//GmZn/vpaW/7iTk/+wkJD/qouL/6OIiP+dhYX/lYKC/49/ + f/+JfHz/fnV1/62bm//wz8//7szM/8/Jyf/u8PD/7O7u/+zu7v/s7u7/7O7u/+zu7v/s7u7/7O7u/+zu + 7v/s7u7/7O7u/+7x8f/NwsL/583N/+XNzf/Xvr7/rpeX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAADCl5fw576+//XNzf/0zMz/9M3N//XPz//1z8//9c/P//TQ0P/10ND/9NDQ//XQ + 0P/20dH/9dHR//bR0f/10tL/9dLS//HPz//uzMz/7c3N/9jAwP/Qurr/0Lq6/9G6uv/Purr/z7q6/9C6 + uv/Ourr/zrq6/8+6uv/Nurr/zbq6/826uv/ZwsL/5s3N/+bNzf/Wvr7/rZeX8AAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADBl5fw6L6+//bNzf/0zMz/9MzM//PMzP/zzMz/88zM//LM + zP/yzMz/8czM//HMzP/wzMz/8MzM/+/MzP/vzMz/7szM/+7MzP/uzMz/7czM/+7Nzf/uzc3/7s3N/+3N + zf/tzc3/683N/+zNzf/qzc3/683N/+vNzf/qzc3/6s3N/+jNzf/ozc3/5szM/+fNzf/Xvr7/rpeX8AAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADCl5fw6r6+//fNzf/1zMz/9czM//TM + zP/0zMz/88zM//PMzP/yzMz/8szM//LMzP/xzMz/8czM//DMzP/wzMz/78zM/+/MzP/uzMz/7szM/+3M + zP/tzMz/7MzM/+zMzP/szMz/68zM/+vMzP/qzMz/6szM/+nMzP/pzMz/6MzM/+jMzP/nzMz/58zM/+jN + zf/Zvr7/sJeX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADEl5fw6b6+//fN + zf/2zMz/9czM//bNzf/3zs7/9s7O//bOzv/1zs7/9c7O//TOzv/1zs7/887O//TOzv/yzs7/887O//LO + zv/yz8//8s/P//HPz//xz8//8M/P//HPz//vz8//8M/P/+7Pz//vz8//7s/P/+7Pz//uz8//7c/P/+3P + z//pzc3/6czM/+jNzf/avr7/r5eX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AADDl5fw6r6+//jNzf/3zMz/983N/+K2tv/Zrq7/2K6u/9etrf/Vra3/1Kys/9Krq//Qqqr/zqmp/8yp + qf/KqKj/yKen/8ampv/EpaX/w6Sk/8Cjo/+/oqL/vKGh/7uhof+4oKD/t5+f/7Senv+ynZ3/sJyc/66b + m/+smpr/qpqa/6WXl//gxcX/6c3N/+nNzf/Zvr7/sZeX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAADFl5fw676+//nNzf/3zMz/+c/P/86goP++kZH/vpGR/7uPj/+4jo7/tYyM/7KL + i/+tiYn/qoaG/6iEhP+jhIT/oIGB/5x/f/+ZfX3/lX19/5F6ev+OeHj/iXZ2/4d1df+Cc3P/gHFx/3tv + b/94bm7/dGxs/3Bqav9taGj/aWVl/15fX//Yvb3/6s3N/+rNzf/avr7/sJeX8AAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADEl5fw7b6+//rNzf/4zMz/+8/P/9Kjo//ElJT/wZOT/76R + kf+7kJD/t46O/7SMjP+wior/rYmJ/6mHh/+mhYX/ooOD/5+Bgf+bgID/mH5+/5R8fP+Qenr/jXl5/4l3 + d/+GdXX/gnNz/35ycv97cHD/d25u/3RsbP9wamr/bGlp/2JiYv/Zvr7/7M3N/+vNzf/cvr7/sZeX8AAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADFl5fw7L6+//rNzf/5zMz/+s7O/9Sj + o//FlJT/wpSU/7+Rkf+8j4//t42N/7SMjP+wior/rYiI/6iGhv+lhYX/oYOD/56AgP+Zfn7/l319/5J7 + e/+PeXn/ind3/4d2dv+DdHT/gHFx/3xxcf95bm7/dGxs/3Fqav9taWn/amdn/19fX//ZvLz/7c3N/+vN + zf/dvr7/s5eX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADHl5fw7b6+//vN + zf/6zMz/+czM//nMzP/6zc3/+c7O//jMzP/5zMz/98zM//jNzf/3zc3/983N//bNzf/1zc3/9s3N//XN + zf/2zc3/9c7O//XOzv/0zs7/88/P//TNzf/yzc3/887O//LOzv/yzs7/8c7O//DOzv/xzs7/8M7O/+/O + zv/tzc3/68zM/+zNzf/cvr7/speX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AADGl5fw77+///3Ozv/7zc3/+83N//rNzf/6zc3/+s3N//nNzf/6zc3/+M3N//jNzf/3zc3/983N//bN + zf/2zc3/9c3N//XNzf/2zc3/9M3N//XNzf/zzc3/9M3N//LNzf/zzc3/8c3N//LNzf/wzc3/8M3N//HN + zf/vzc3/8M3N/+7Nzf/uzc3/7c3N/+7Ozv/ev7//s5eX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAADImJjw5rW1//HAwP/wv7//77+//++/v//uv7//7r+//+2/v//tv7//7L+//+y/ + v//sv7//67+//+u/v//qv7//6r+//+m/v//pv7//6L+//+i/v//nv7//57+//+a/v//mv7//5b+//+W/ + v//kv7//5L+//+S/v//jv7//47+//+K/v//iv7//4b+//+LAwP/VtbX/tZiY8AAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADKmJjjyJiY8MiYmPDGl5fwxpeX8MeXl/DFl5fwxJeX8MSX + l/DFl5fww5eX8MSXl/DCl5fww5eX8MGXl/DCl5fwwJeX8MGXl/C/l5fwwJeX8L6Xl/C/l5fwvZeX8L6X + l/C8l5fwvZeX8LuXl/C8l5fwupeX8LmXl/C5l5fwupeX8LeXl/C2l5fwtpeX8LeYmPC2mJjwt5iY4wAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////AAD4AAAAAB8AAPgAAAAAHwAA+AAAAAAf + AAD4AAAAAB8AAPgAAAAAHwAA+AAAAAAfAAD4AAAAAB8AAPgAAAAAHwAA+AAAAAAfAAD4AAAAAB8AAPgA + AAAAHwAA+AAAAAAfAAD4AAAAAB8AAPgAAAAAHwAA+AAAAAAfAAD4AAAAAB8AAPgAAAAAHwAA+AAAAAAf + AAD4AAAAAB8AAPgAAAAAHwAA+AAAAAAfAAD4AAAAAB8AAPgAAAAAHwAA+AAAAAAfAAD4AAAAAB8AAPgA + AAAAHwAA+AAAAAAfAAD4AAAAAB8AAPgAAAAAHwAA+AAAAAAfAAD4AAAAAB8AAPgAAAAAHwAA+AAAAAAf + AAD4AAAAAB8AAPgAAAAAHwAA+AAAAAAfAAD4AAAAAB8AAPgAAAAAHwAA+AAAAAAfAAD4AAAAAB8AAPgA + AAAAHwAA+AAAAAAfAAD4AAAAAB8AAPgAAAAAHwAA+AAAAAAfAAD4AAAAAB8AAP///////wAA + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/FolderLocker/DRServer.cs b/Demo_Source_Code/CSharpDemo/FolderLocker/DRServer.cs new file mode 100644 index 0000000..2471840 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FolderLocker/DRServer.cs @@ -0,0 +1,692 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; +using Microsoft.Win32.SafeHandles; +using System.Runtime.InteropServices; +using System.Security.Principal; +using System.Threading; +using System.Diagnostics; +using System.Management; +using System.Collections; +using System.Configuration; +using System.Windows.Forms; + +using EaseFilter.FilterControl; +using EaseFilter.CommonObjects; + +namespace EaseFilter.FolderLocker +{ + + public enum AESFlags : uint + { + Flags_Enabled_Expire_Time = 0x00000010, + Flags_Enabled_Check_ProcessName = 0x00000020, + Flags_Enabled_Check_UserName = 0x00000040, + Flags_Enabled_Check_AccessFlags = 0x00000080, + Flags_Enabled_Check_User_Permit = 0x00000100, + Flags_AES_Key_Was_Embedded = 0x00000200, + Flags_Request_AccessFlags_From_User = 0x00000400, + Flags_Request_IV_And_Key_From_User = 0x00000800, + Flags_Enabled_Check_Computer_Id = 0x00001000, + Flags_Enabled_Check_User_Password = 0x00002000, + + } + + /// + /// this is the return data structure for encryption to filter driver. + /// when the filter command is FILTER_REQUEST_ENCRYPTION_IV_AND_KEY, + /// FILTER_REQUEST_ENCRYPTION_IV_AND_KEY_AND_ACCESSFLAG or FILTER_REQUEST_ENCRYPTION_IV_AND_KEY_AND_TAGDATA + /// + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + public struct AESDataBuffer + { + public uint AccessFlags; + public uint IVLength; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] + public byte[] IV; + public uint EncryptionKeyLength; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] + public byte[] EncryptionKey; + public uint TagDataLength; + public byte[] TagData; + } + + /// + /// This is the DR info meta data which will be stored in server if revoke access control is enabled. + /// + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + public class DRPolicy + { + /// + /// If it is not empty, only the processes in the process list can access the files. + /// + public string AuthorizedProcessNames; + /// + /// If it is not empty, all the processes in the process list can not access the files. + /// + public string UnauthorizedProcessNames; + /// + /// If it is not empty, only the users in the user name list can access the files. + /// + public string AuthorizedUserNames; + /// + /// If it is not empty, all the useres in the user name list can not access the files. + /// + public string UnauthorizedUserNames; + /// + /// If it is not empty, only the computer in the computer id list can access the files. + /// + public string AuthorizedComputerIds; + /// + /// the password of the shared file. + /// + public string UserPassword; + /// + /// the access flags of the shared file. + /// + public uint AccessFlags; + /// + /// The file will be expired after the expire time in UTC format, and it can't be accessed. + /// + public long ExpireTime; + /// + /// The time in UTC format of the encrypted file was created. + /// + public long CreationTime; + /// + /// the file name which was applied with policy. + /// + public string FileName; + /// + /// The encryption key hex string. + /// + public string EncryptionKey; + /// + /// the iv hex string. + /// + public string EncryptionIV; + } + + + /// + /// This the DR data which will be embedded to the encyrpted file + /// + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + public struct DRPolicyData + { + + public uint AESVerificationKey; + public AESFlags AESFlags; + public uint IVLength; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] + public byte[] IV; + public uint EncryptionKeyLength; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] + public byte[] EncryptionKey; + public long CreationTime; + public long ExpireTime; + public uint AccessFlags; + public long FileSize; + public uint LengthOfAuthorizedProcessNames; + public uint LengthOfUnauthorizedProcessNames; + public uint LengthOfAuthorizedUserNames; + public uint LengthOfUnauthorizedUserNames; + public uint LengthOfAccountName; + public uint LengthOfComputerIds; + public uint LengthOfUserPassword; + public string AuthorizedProcessNames; + public string UnauthorizedProcessNames; + public string AuthorizedUserNames; + public string UnauthorizedUserNames; + public string AccountName; + public string ComputerIds; + public string UserPassword; + public uint SizeOfAESData; + + } + + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + public struct UserInfo + { + /// + /// the owner account name + /// + public string AccountName; + /// + /// the password of the account + /// + public string AccountPassword; + /// + /// the process name which access the file. + /// + public string ProcessName; + /// + /// the user name who access the file. + /// + public string UserName; + /// + /// the computer information which access the file. + /// + public string ComputerId; + /// + /// the encrypted file which was accessed. + /// + public string FileName; + /// + /// the creation time of the file which was accessed. + /// + public long CreationTime; + /// + /// the password of the user input. + /// + public string UserPassword; + /// the encryption iv hex string; + /// + public string EncryptionIV; + } + + + public class DigitalRightControl + { + public const uint AES_VERIFICATION_KEY = 0xccb76e80; + public static string PassPhrase = "PassPhrase"; + + private static byte[] ConvertDRPolicyDataToByteArray(DRPolicyData policy) + { + MemoryStream ms = new MemoryStream(); + BinaryWriter bw = new BinaryWriter(ms); + bw.Write(AES_VERIFICATION_KEY); + bw.Write((uint)(policy.AESFlags)); + bw.Write(policy.IVLength); + bw.Write(policy.IV); + bw.Write(policy.EncryptionKeyLength); + bw.Write(policy.EncryptionKey); + bw.Write(policy.CreationTime); + bw.Write(policy.ExpireTime); + bw.Write((uint)policy.AccessFlags); + bw.Write(policy.FileSize); + bw.Write(policy.LengthOfAuthorizedProcessNames); + bw.Write(policy.LengthOfUnauthorizedProcessNames); + bw.Write(policy.LengthOfAuthorizedUserNames); + bw.Write(policy.LengthOfUnauthorizedUserNames); + bw.Write(policy.LengthOfAccountName); + bw.Write(policy.LengthOfComputerIds); + bw.Write(policy.LengthOfUserPassword); + + byte[] strBuffer; + if (policy.LengthOfAuthorizedProcessNames > 0) + { + strBuffer = UnicodeEncoding.Unicode.GetBytes(policy.AuthorizedProcessNames); + bw.Write(strBuffer); + } + + if (policy.LengthOfUnauthorizedProcessNames > 0) + { + strBuffer = UnicodeEncoding.Unicode.GetBytes(policy.UnauthorizedProcessNames); + bw.Write(strBuffer); + } + + if (policy.LengthOfAuthorizedUserNames > 0) + { + strBuffer = UnicodeEncoding.Unicode.GetBytes(policy.AuthorizedUserNames); + bw.Write(strBuffer); + } + + if (policy.LengthOfUnauthorizedUserNames > 0) + { + strBuffer = UnicodeEncoding.Unicode.GetBytes(policy.UnauthorizedUserNames); + bw.Write(strBuffer); + } + + if (policy.LengthOfAccountName > 0) + { + strBuffer = UnicodeEncoding.Unicode.GetBytes(policy.AccountName); + bw.Write(strBuffer); + } + + if (policy.LengthOfComputerIds > 0) + { + strBuffer = UnicodeEncoding.Unicode.GetBytes(policy.ComputerIds); + bw.Write(strBuffer); + } + + if (policy.LengthOfUserPassword > 0) + { + strBuffer = UnicodeEncoding.Unicode.GetBytes(policy.UserPassword); + bw.Write(strBuffer); + } + + //append the sizeof the DR policy + int sizeofDRDataArray = (int)ms.Length + 4;// the size of sizeofDRDataArray takes 4 bytes memory as a int data + bw.Write(sizeofDRDataArray); + + byte[] AESBuffer = ms.ToArray(); + + return AESBuffer; + } + } + + + public class CacheUserAccessInfo + { + public string index = string.Empty; + public bool accessStatus = false; + public bool isDownloaded = false; + public uint accessFlags = 0; + public DateTime lastAccessTime = DateTime.MinValue; + public string iv = string.Empty; + public string key = string.Empty; + public AutoResetEvent syncEvent = new AutoResetEvent(true); + public string lastError = string.Empty; + + } + + public class DRServer + { + + static Dictionary userAccessCache = new Dictionary(); + static int cacheTimeOutInSeconds = 20; + static System.Timers.Timer deleteCachedItemTimer = new System.Timers.Timer(); + + static DRServer() + { + deleteCachedItemTimer.Interval = cacheTimeOutInSeconds * 1000 ; //millisecond + deleteCachedItemTimer.Start(); + deleteCachedItemTimer.Enabled = true; + deleteCachedItemTimer.Elapsed += new System.Timers.ElapsedEventHandler(deleteCachedItemTimer_Elapsed); + } + + static public bool GetFileAccessPermission(EncryptEventArgs encryptEvebtArgs) + { + Boolean retVal = true; + string fileName = encryptEvebtArgs.FileName; + string lastError = string.Empty; + string processName = encryptEvebtArgs.ProcessName; + string userName = encryptEvebtArgs.UserName; + string encryptKey = string.Empty; + + try + { + + if (null == encryptEvebtArgs.EncryptionTag || encryptEvebtArgs.EncryptionTag.Length == 0) + { + encryptEvebtArgs.Description = "There are no encryption tag data."; + + return false; + } + + //by default the tag data format is "accountName;ivStr" + string tagStr = UnicodeEncoding.Unicode.GetString(encryptEvebtArgs.EncryptionTag); + + int index = tagStr.IndexOf(";"); + byte[] iv = encryptEvebtArgs.EncryptionTag; + + if (index > 0) + { + string serverAccount = tagStr.Substring(0, index); + string ivStr = tagStr.Substring(index + 1); + iv = Utils.ConvertHexStrToByteArray(ivStr); + } + + uint accessFlag = 0; + + retVal = IsFileAccessAuthorized(fileName, + userName, + processName, + tagStr, + ref encryptKey, + ref accessFlag, + ref lastError); + + if (retVal && !string.IsNullOrEmpty(encryptKey)) + { + byte[] keyArray = Utils.ConvertHexStrToByteArray(encryptKey); + + encryptEvebtArgs.AccessFlags = FilterAPI.ALLOW_MAX_RIGHT_ACCESS; + encryptEvebtArgs.IV = iv; + encryptEvebtArgs.EncryptionKey = keyArray; + encryptEvebtArgs.ReturnStatus = NtStatus.Status.Success; + + } + else + { + encryptEvebtArgs.IoStatus = encryptEvebtArgs.ReturnStatus = NtStatus.Status.AccessDenied; + encryptEvebtArgs.Description = lastError; + + } + } + catch (Exception ex) + { + lastError = "GetFileAccessPermission exception." + ex.Message; + encryptEvebtArgs.Description = lastError; + + EventManager.WriteMessage(340, "GetFileAccessPermission", EventLevel.Error, lastError); + retVal = false; + } + + return retVal; + + } + + + static private bool GetAccessPermissionFromServer( string fileName, + string userName, + string processName, + string tagStr, + ref string encryptKey, + ref uint accessFlag, + ref string lastError) + { + Boolean retVal = true; + + try + { + CacheUserAccessInfo cacheUserAccessInfo = new CacheUserAccessInfo(); + + string index = userName + "_" + processName + "_" + tagStr; + + //cache the same user/process/filename access. + lock (userAccessCache) + { + if (userAccessCache.ContainsKey(index)) + { + cacheUserAccessInfo = userAccessCache[index]; + EventManager.WriteMessage(446, "GetUserPermission", EventLevel.Verbose, "Thread" + Thread.CurrentThread.ManagedThreadId + ",userInfoKey " + index + " exists in the cache table."); + } + else + { + cacheUserAccessInfo.isDownloaded = false; + cacheUserAccessInfo.index = index; + cacheUserAccessInfo.lastAccessTime = DateTime.Now; + userAccessCache.Add(index, cacheUserAccessInfo); + EventManager.WriteMessage(435, "GetUserPermission", EventLevel.Verbose, "Thread" + Thread.CurrentThread.ManagedThreadId + ",add userInfoKey " + index + " to the cache table."); + } + } + + //synchronize the same file access. + if (!cacheUserAccessInfo.isDownloaded && !cacheUserAccessInfo.syncEvent.WaitOne(new TimeSpan(0, 0, cacheTimeOutInSeconds)) ) + { + string info = "User name: " + userName + ",processname:" + processName + ",file name:" + fileName + " wait for permission timeout."; + EventManager.WriteMessage(402, "GetUserPermission", EventLevel.Warning, info); + return false; + } + + TimeSpan timeSpan = DateTime.Now - cacheUserAccessInfo.lastAccessTime; + + if (cacheUserAccessInfo.isDownloaded && timeSpan.TotalSeconds < cacheTimeOutInSeconds) + { + //the access was cached, return the last access status. + retVal = cacheUserAccessInfo.accessStatus; + + if (!retVal) + { + EventManager.WriteMessage(308, "GetAccessPermissionFromServer", EventLevel.Error, cacheUserAccessInfo.lastError); + } + else + { + string info = "thread" + Thread.CurrentThread.ManagedThreadId + ", Cached userInfoKey " + index + " in the cache table,return " + retVal; + EventManager.WriteMessage(451, "GetUserPermission", EventLevel.Verbose, info); + } + + encryptKey = cacheUserAccessInfo.key; + accessFlag = cacheUserAccessInfo.accessFlags; + lastError = cacheUserAccessInfo.lastError; + + cacheUserAccessInfo.syncEvent.Set(); + + return retVal; + } + + string encryptionIV = tagStr; + + retVal = WebAPIServices.GetSharedFilePermission(fileName, processName, userName, tagStr, ref encryptionIV, ref encryptKey, ref accessFlag, ref lastError); + cacheUserAccessInfo.accessStatus = retVal; + cacheUserAccessInfo.isDownloaded = true; + cacheUserAccessInfo.syncEvent.Set(); + + if (!retVal) + { + string message = "Get file " + fileName + " permission from server return error:" + lastError; + cacheUserAccessInfo.lastError = message; + cacheUserAccessInfo.accessStatus = false; + + EventManager.WriteMessage(293, "GetAccessPermissionFromServer", EventLevel.Error, message); + + return retVal; + } + else + { + string message = "Get file " +fileName + " permission frome server return succeed."; + EventManager.WriteMessage(208, "GetAccessPermissionFromServer", EventLevel.Verbose, message); + } + + cacheUserAccessInfo.key = encryptKey; + cacheUserAccessInfo.iv = encryptionIV; + cacheUserAccessInfo.accessFlags = accessFlag; + + + } + catch (Exception ex) + { + EventManager.WriteMessage(286, "GetAccessPermissionFromServer", EventLevel.Error, "Get file " + fileName + "permission failed with exception:" + ex.Message); + retVal = false; + } + + return retVal; + + } + + static private bool IsFileAccessAuthorized(string fileName, + string userName, + string processName, + string tagStr, + ref string encryptKey, + ref uint accessFlag, + ref string lastError) + { + Boolean retVal = true; + string expireTime = string.Empty; + string authorizedProcessNames = string.Empty; + string unauthorizedProcessNames = string.Empty; + string authorizedUserNames = string.Empty; + string unauthorizedUserNames = string.Empty; + string accessFlags = string.Empty; + + lastError = string.Empty; + DateTime currentTime = DateTime.Now; + + try + { + if (GlobalConfig.StoreSharedFileMetaDataInServer) + { + return GetAccessPermissionFromServer(fileName, userName, processName, tagStr, ref encryptKey, ref accessFlag, ref lastError); + } + + string drFilePath = GlobalConfig.DRInfoFolder + "\\" + tagStr + ".xml"; + Dictionary keyValues = new Dictionary(); + + if (!File.Exists(drFilePath)) + { + lastError = "The meta data file " + drFilePath + " doesn't exist."; + return false; + } + + Utils.LoadAppSetting(drFilePath, ref keyValues); + + encryptKey = string.Empty; + keyValues.TryGetValue("key", out encryptKey); + if (string.IsNullOrEmpty(encryptKey)) + { + lastError = "The encryption key is empty."; + return false; + } + + keyValues.TryGetValue("accessFlags", out accessFlags); + uint.TryParse(accessFlags, out accessFlag); + keyValues.TryGetValue("expireTime", out expireTime); + keyValues.TryGetValue("authorizedProcessNames", out authorizedProcessNames); + keyValues.TryGetValue("unauthorizedProcessNames", out unauthorizedProcessNames); + keyValues.TryGetValue("authorizedUserNames", out authorizedUserNames); + keyValues.TryGetValue("unauthorizeUserNames", out unauthorizedUserNames); + + if (!string.IsNullOrEmpty(expireTime)) + { + DateTime exTime = DateTime.FromFileTime(long.Parse(expireTime)); + + if (currentTime > exTime) + { + lastError = "the file is expired,current time:" + currentTime.ToString("yyyy-MM-dd-HH-mm-ss") + ",expire time:" + exTime.ToString("yyyy-MM-dd-HH-mm-ss"); + return false; + } + } + + if (!string.IsNullOrEmpty(authorizedProcessNames)) + { + if (authorizedProcessNames.IndexOf(processName.ToLower().Trim()) < 0) + { + lastError = "the process " + processName + " is not in authorized process list."; + return false; + } + } + + if (!string.IsNullOrEmpty(unauthorizedProcessNames)) + { + if (unauthorizedProcessNames.IndexOf(processName.ToLower().Trim()) >= 0) + { + lastError = "the process " + processName + " is in unauthorized process list."; + return false; + } + } + + if (!string.IsNullOrEmpty(authorizedUserNames)) + { + if (authorizedUserNames.IndexOf(userName.ToLower().Trim()) < 0) + { + lastError = "the user " + userName + " is not in authorized user list."; + return false; + } + } + + if (!string.IsNullOrEmpty(unauthorizedUserNames)) + { + if (unauthorizedUserNames.IndexOf(userName.ToLower().Trim()) >= 0) + { + lastError = "the user " + userName + " is in unauthorized user list."; + return false; + } + } + + + } + catch (Exception ex) + { + EventManager.WriteMessage(286, "IsFileAccessAuthorized", EventLevel.Error, "Get file " + fileName + "permission failed with exception:" + ex.Message); + retVal = false; + } + + return retVal; + + } + + static public bool AddDRInfoToFile(string fileName, + string authorizedProcessNames, + string unauthorizedProcessNames, + string authorizedUserNames, + string unauthorizedUserNames, + DateTime expireTime, + byte[] encryptIV, + byte[] encryptKey, + string accessFlags) + { + + try + { + if (!Directory.Exists(GlobalConfig.DRInfoFolder)) + { + Directory.CreateDirectory(GlobalConfig.DRInfoFolder); + } + + string iv = Utils.ByteArrayToHexStr(encryptIV); + string key = Utils.ByteArrayToHexStr(encryptKey); + + string drFilePath = GlobalConfig.DRInfoFolder + "\\" + iv + ".xml"; + Dictionary keyValues = new Dictionary(); + + keyValues.Add("fileName", fileName); + keyValues.Add("key", key); + keyValues.Add("iv", iv); + keyValues.Add("accessFlags", accessFlags); + keyValues.Add("authorizedProcessNames", authorizedProcessNames.ToLower()); + keyValues.Add("unauthorizedProcessNames", unauthorizedProcessNames.ToLower()); + keyValues.Add("authorizedUserNames", authorizedUserNames.ToLower()); + keyValues.Add("unauthorizedUserNames", unauthorizedUserNames.ToLower()); + keyValues.Add("expireTime", expireTime.ToFileTime().ToString()); + keyValues.Add("creationTime", DateTime.Now.ToFileTime().ToString()); + + Utils.SaveAppSetting(drFilePath, keyValues); + + return true; + } + catch (Exception ex) + { + return false; + } + + } + + static private void deleteCachedItemTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) + { + + try + { + List keysToRemove = new List(); + + foreach (KeyValuePair userItem in userAccessCache) + { + + TimeSpan tsSinceLastAccess = DateTime.Now - userItem.Value.lastAccessTime; + + if (tsSinceLastAccess.TotalSeconds >= cacheTimeOutInSeconds) + { + keysToRemove.Add(userItem.Key); + } + } + + foreach (string key in keysToRemove) + { + lock (userAccessCache) + { + userAccessCache.Remove(key); + + EventManager.WriteMessage(573, "deleteCachedItemTimer_Elapsed", EventLevel.Verbose, "Delete cached item " + key); + } + } + } + catch (System.Exception ex) + { + EventManager.WriteMessage(46, "deleteCachedItemTimer_Elapsed", EventLevel.Error, "Delete cached item failed with error:" + ex.Message); + } + + } + + } +} diff --git a/Demo_Source_Code/CSharpDemo/FolderLocker/EncryptEventHandler.cs b/Demo_Source_Code/CSharpDemo/FolderLocker/EncryptEventHandler.cs new file mode 100644 index 0000000..04b9442 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FolderLocker/EncryptEventHandler.cs @@ -0,0 +1,79 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; +using System.Runtime.InteropServices; +using System.Security.Principal; +using System.IO; +using System.Threading; +using System.Reflection; + +using EaseFilter.FilterControl; +using EaseFilter.CommonObjects; + +namespace EaseFilter.FolderLocker +{ + + public class EncryptEventHandler : IDisposable + { + bool disposed = false; + + public EncryptEventHandler() + { + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + private void Dispose(bool disposing) + { + if (!this.disposed) + { + } + + disposed = true; + } + + ~EncryptEventHandler() + { + Dispose(false); + } + + /// + /// Fires this event after the new file was created, the handle is not closed. + /// + public void OnFilterRequestEncryptKey(object sender, EncryptEventArgs e) + { + + if (!DRServer.GetFileAccessPermission(e)) + { + e.IoStatus = e.ReturnStatus = NtStatus.Status.AccessDenied; + } + + } + + } +} \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/FolderLocker/FilterWorker.cs b/Demo_Source_Code/CSharpDemo/FolderLocker/FilterWorker.cs new file mode 100644 index 0000000..de900b1 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FolderLocker/FilterWorker.cs @@ -0,0 +1,184 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; +using Microsoft.Win32.SafeHandles; +using System.Runtime.InteropServices; +using System.Security.Principal; +using System.Threading; +using System.Diagnostics; +using System.Management; +using System.Collections; +using System.Windows.Forms; + +using EaseFilter.CommonObjects; + +namespace EaseFilter.FolderLocker +{ + + public class FilterWorker + { + + + public FilterWorker() + { + } + + static public bool StartService(ref string lastError) + { + //Purchase a license key with the link: http://www.easefilter.com/Order.htm + //Email us to request a trial key: info@easefilter.com //free email is not accepted. + string registerKey = GlobalConfig.registerKey; + + bool ret = false; + lastError = string.Empty; + + try + { + + ret = FilterAPI.StartFilter((int)GlobalConfig.FilterConnectionThreads + , registerKey + , new FilterAPI.FilterDelegate(FilterCallback) + , new FilterAPI.DisconnectDelegate(DisconnectCallback) + , ref lastError); + if (!ret) + { + lastError = "Start filter service failed with error " + lastError; + EventManager.WriteMessage(43, "StartFilter", EventLevel.Error, lastError); + return ret; + } + + + ApplySettingsToFilterDriver(); + + EventManager.WriteMessage(102, "StartFilter", EventLevel.Information, "Start filter service succeeded."); + } + catch (Exception ex) + { + lastError = "Start filter service failed with error " + ex.Message; + EventManager.WriteMessage(104, "StartFilter", EventLevel.Error, lastError); + } + + return ret; + } + + static public void ApplySettingsToFilterDriver() + { + FilterRule filterRuleShareFolder = new FilterRule(); + filterRuleShareFolder.Id = GlobalConfig.GetFilterRuleId(); + filterRuleShareFolder.IncludeFileFilterMask = GlobalConfig.ShareFolder + "\\*"; + filterRuleShareFolder.AccessFlag |= (uint)FilterAPI.AccessFlag.ENABLE_FILE_ENCRYPTION_RULE | FilterAPI.ALLOW_MAX_RIGHT_ACCESS; + filterRuleShareFolder.AccessFlag &= (uint)(~FilterAPI.AccessFlag.ALLOW_ENCRYPT_NEW_FILE);// this folder won't encrypt the new file. + filterRuleShareFolder.EncryptMethod = (int)FilterAPI.EncryptionMethod.ENCRYPT_FILE_WITH_SAME_KEY_AND_UNIQUE_IV; + filterRuleShareFolder.EncryptionPassPhrase = GlobalConfig.MasterPassword; + + GlobalConfig.AddFilterRule(filterRuleShareFolder); + + //send the filter rule settings to the filter driver here. + GlobalConfig.SaveConfigSetting(); + + } + + static void DisconnectCallback() + { + EventManager.WriteMessage(697, "DisconnectCallback", EventLevel.Information, "Filter Disconnected." + FilterAPI.GetLastErrorMessage()); + } + + + static public bool StopService() + { + FilterAPI.StopFilter(); + GlobalConfig.Stop(); + + return true; + } + + public void ClearMessage() + { + } + + static private Boolean FilterCallback(IntPtr sendDataPtr, IntPtr replyDataPtr) + { + bool retVal = true; + + try + { + FilterAPI.MessageSendData messageSend = new FilterAPI.MessageSendData(); + messageSend = (FilterAPI.MessageSendData)Marshal.PtrToStructure(sendDataPtr, typeof(FilterAPI.MessageSendData)); + + if (FilterAPI.MESSAGE_SEND_VERIFICATION_NUMBER != messageSend.VerificationNumber) + { + EventManager.WriteMessage(139, "FilterCallback", EventLevel.Error, "Received message corrupted.Please check if the MessageSendData structure is correct."); + return false; + } + + if (messageSend.MessageType == (uint)FilterAPI.FilterCommand.FILTER_REQUEST_ENCRYPTION_IV_AND_KEY) + { + + if ((replyDataPtr.ToInt64() != 0)) + { + + //this is the customized tag data which was attahced to the encrypted file when it was created. + uint tagDataLength = messageSend.DataBufferLength; + byte[] tagData = messageSend.DataBuffer; + + FilterAPI.MessageReplyData messageReply = (FilterAPI.MessageReplyData)Marshal.PtrToStructure(replyDataPtr, typeof(FilterAPI.MessageReplyData)); + messageReply.MessageId = messageSend.MessageId; + messageReply.MessageType = messageSend.MessageType; + + //get permission for secure shared file from server, here just demo the server in local, + //in reality, your server could be in remote computer. + retVal = DRServer.GetFileAccessPermission(ref messageSend, ref messageReply); + + if (retVal) + { + messageReply.ReturnStatus = (uint)FilterAPI.NTSTATUS.STATUS_SUCCESS; + } + else + { + //if you don't want to authorize the process to read the encrytped file,you can set the value as below: + messageReply.ReturnStatus = (uint)FilterAPI.NTSTATUS.STATUS_ACCESS_DENIED; + messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION; + } + + Marshal.StructureToPtr(messageReply, replyDataPtr, true); + + if (!retVal) + { + messageSend.Status = (uint)FilterAPI.NTSTATUS.STATUS_ACCESS_DENIED; + } + + } + } + + } + catch (Exception ex) + { + EventManager.WriteMessage(134, "FilterCallback", EventLevel.Error, "filter callback exception." + ex.Message); + return false; + } + + return retVal; + + } + + } + +} diff --git a/Demo_Source_Code/CSharpDemo/FolderLocker/FolderLocker.csproj b/Demo_Source_Code/CSharpDemo/FolderLocker/FolderLocker.csproj new file mode 100644 index 0000000..0bbd887 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FolderLocker/FolderLocker.csproj @@ -0,0 +1,180 @@ + + + + Debug + x86 + 8.0.30703 + 2.0 + {8EB7E6DC-D83A-45E7-9F09-72931F2EED66} + WinExe + Properties + EaseFilter.FolderLocker + FolderLocker + v4.5 + + + 512 + SAK + SAK + SAK + SAK + + + AnyCPU + true + full + false + ..\..\..\Release\ + DEBUG;TRACE + prompt + 4 + false + false + + + AnyCPU + pdbonly + true + ..\..\..\Release\ + TRACE + prompt + 4 + false + false + + + Lock Folder.ico + + + true + ..\..\Release\ + DEBUG;TRACE + full + AnyCPU + bin\Debug\AutoFileCryptTool.exe.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false + false + + + ..\..\Release\ + TRACE + true + pdbonly + AnyCPU + ..\..\..\Release\AutoFileCryptTool.exe.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + false + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + true + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + true + false + + + app.manifest + + + + + + + + + + + + + + + + + + + Form + + + AccessRightsForm.cs + + + Form + + + FolderLockerSettigs.cs + + + Form + + + FormFolderLocker.cs + + + + + AccessRightsForm.cs + + + FolderLockerSettigs.cs + + + FormFolderLocker.cs + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + True + Resources.resx + True + + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + + + {34CB783E-DDA2-4CE3-80BC-37B25AA33E5F} + CommonObjects + + + {21540012-A296-45CE-8D35-3EA5A07B32A6} + FilterControl + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/FolderLocker/FolderLocker2015.csproj b/Demo_Source_Code/CSharpDemo/FolderLocker/FolderLocker2015.csproj new file mode 100644 index 0000000..b0539dd --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FolderLocker/FolderLocker2015.csproj @@ -0,0 +1,214 @@ + + + + Debug + x86 + 8.0.30703 + 2.0 + {8EB7E6DC-D83A-45E7-9F09-72931F2EED66} + WinExe + Properties + EaseFilter.FolderLocker + FolderLocker + v4.5 + + + 512 + SAK + SAK + SAK + SAK + + + AnyCPU + true + full + false + ..\..\..\Release\ + DEBUG;TRACE + prompt + 4 + false + false + + + AnyCPU + pdbonly + true + ..\..\..\Release\ + TRACE + prompt + 4 + false + false + + + Lock Folder.ico + + + true + ..\..\Release\ + DEBUG;TRACE + full + AnyCPU + bin\Debug\AutoFileCryptTool.exe.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false + false + + + ..\..\Release\ + TRACE + true + pdbonly + AnyCPU + ..\..\..\Release\AutoFileCryptTool.exe.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + false + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + true + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + true + false + + + app.manifest + + + + + + + + + + + + + + + + + + + Form + + + AccessRightsForm.cs + + + + + Form + + + FolderLockerSettigs.cs + + + Form + + + FormFolderLocker.cs + + + + + True + True + Reference.svcmap + + + + SharedFileAccessLogForm.cs + + + + ShareFileForm.cs + + + + + AccessRightsForm.cs + + + FolderLockerSettigs.cs + + + FormFolderLocker.cs + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + True + Resources.resx + True + + + SharedFileAccessLogForm.cs + + + ShareFileForm.cs + + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + + + + {34CB783E-DDA2-4CE3-80BC-37B25AA33E5F} + CommonObjects %28FilterDemo\CommonObjects%29 + + + {21540012-A296-45CE-8D35-3EA5A07B32A6} + FilterControl + + + + + + WCF Proxy Generator + Reference.cs + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/FolderLocker/FolderLockerSettigs.Designer.cs b/Demo_Source_Code/CSharpDemo/FolderLocker/FolderLockerSettigs.Designer.cs new file mode 100644 index 0000000..0cafe9a --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FolderLocker/FolderLockerSettigs.Designer.cs @@ -0,0 +1,392 @@ + +namespace EaseFilter.FolderLocker +{ + partial class FolderLockerSettigs + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FolderLockerSettigs)); + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.groupBox_AccessControl = new System.Windows.Forms.GroupBox(); + this.button_RemoveRights = new System.Windows.Forms.Button(); + this.button_AddProcessRights = new System.Windows.Forms.Button(); + this.button_AddUserRights = new System.Windows.Forms.Button(); + this.groupBox3 = new System.Windows.Forms.GroupBox(); + this.listView_AccessRights = new System.Windows.Forms.ListView(); + this.button_SaveSettings = new System.Windows.Forms.Button(); + this.groupBox2 = new System.Windows.Forms.GroupBox(); + this.checkBox_AllowCopyout = new System.Windows.Forms.CheckBox(); + this.checkBox_Encryption = new System.Windows.Forms.CheckBox(); + this.checkBox_HideFiles = new System.Windows.Forms.CheckBox(); + this.checkBox_AllowRead = new System.Windows.Forms.CheckBox(); + this.checkBox_AllowSetSecurity = new System.Windows.Forms.CheckBox(); + this.checkBox_AllowWrite = new System.Windows.Forms.CheckBox(); + this.checkBox_AllowDelete = new System.Windows.Forms.CheckBox(); + this.checkBox_AllowRename = new System.Windows.Forms.CheckBox(); + this.checkBox_AllowRemoteAccess = new System.Windows.Forms.CheckBox(); + this.checkBox_AllowNewFileCreation = new System.Windows.Forms.CheckBox(); + this.textBox_PassPhrase = new System.Windows.Forms.TextBox(); + this.label_PassPhrase = new System.Windows.Forms.Label(); + this.label_FolderName = new System.Windows.Forms.Label(); + this.textBox_FolderName = new System.Windows.Forms.TextBox(); + this.button_BrowseFolder = new System.Windows.Forms.Button(); + this.toolTip1 = new System.Windows.Forms.ToolTip(this.components); + this.groupBox1.SuspendLayout(); + this.groupBox_AccessControl.SuspendLayout(); + this.groupBox3.SuspendLayout(); + this.groupBox2.SuspendLayout(); + this.SuspendLayout(); + // + // groupBox1 + // + this.groupBox1.Controls.Add(this.groupBox_AccessControl); + this.groupBox1.Dock = System.Windows.Forms.DockStyle.Fill; + this.groupBox1.Location = new System.Drawing.Point(0, 0); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size(554, 499); + this.groupBox1.TabIndex = 12; + this.groupBox1.TabStop = false; + // + // groupBox_AccessControl + // + this.groupBox_AccessControl.Controls.Add(this.button_RemoveRights); + this.groupBox_AccessControl.Controls.Add(this.button_AddProcessRights); + this.groupBox_AccessControl.Controls.Add(this.button_AddUserRights); + this.groupBox_AccessControl.Controls.Add(this.groupBox3); + this.groupBox_AccessControl.Controls.Add(this.button_SaveSettings); + this.groupBox_AccessControl.Controls.Add(this.groupBox2); + this.groupBox_AccessControl.Controls.Add(this.label_FolderName); + this.groupBox_AccessControl.Controls.Add(this.textBox_FolderName); + this.groupBox_AccessControl.Controls.Add(this.button_BrowseFolder); + this.groupBox_AccessControl.Dock = System.Windows.Forms.DockStyle.Fill; + this.groupBox_AccessControl.Location = new System.Drawing.Point(3, 16); + this.groupBox_AccessControl.Name = "groupBox_AccessControl"; + this.groupBox_AccessControl.Size = new System.Drawing.Size(548, 480); + this.groupBox_AccessControl.TabIndex = 24; + this.groupBox_AccessControl.TabStop = false; + // + // button_RemoveRights + // + this.button_RemoveRights.Location = new System.Drawing.Point(248, 422); + this.button_RemoveRights.Margin = new System.Windows.Forms.Padding(2); + this.button_RemoveRights.Name = "button_RemoveRights"; + this.button_RemoveRights.Size = new System.Drawing.Size(131, 22); + this.button_RemoveRights.TabIndex = 89; + this.button_RemoveRights.Text = "Remove Access Right"; + this.button_RemoveRights.UseVisualStyleBackColor = true; + this.button_RemoveRights.Click += new System.EventHandler(this.button_RemoveRights_Click); + // + // button_AddProcessRights + // + this.button_AddProcessRights.Location = new System.Drawing.Point(121, 422); + this.button_AddProcessRights.Margin = new System.Windows.Forms.Padding(2); + this.button_AddProcessRights.Name = "button_AddProcessRights"; + this.button_AddProcessRights.Size = new System.Drawing.Size(110, 22); + this.button_AddProcessRights.TabIndex = 88; + this.button_AddProcessRights.Text = "Add Process Rights"; + this.button_AddProcessRights.UseVisualStyleBackColor = true; + this.button_AddProcessRights.Click += new System.EventHandler(this.button_AddProcessRights_Click); + // + // button_AddUserRights + // + this.button_AddUserRights.Location = new System.Drawing.Point(9, 422); + this.button_AddUserRights.Margin = new System.Windows.Forms.Padding(2); + this.button_AddUserRights.Name = "button_AddUserRights"; + this.button_AddUserRights.Size = new System.Drawing.Size(96, 22); + this.button_AddUserRights.TabIndex = 87; + this.button_AddUserRights.Text = "Add User Rights"; + this.button_AddUserRights.UseVisualStyleBackColor = true; + this.button_AddUserRights.Click += new System.EventHandler(this.button_AddUserRights_Click_1); + // + // groupBox3 + // + this.groupBox3.Controls.Add(this.listView_AccessRights); + this.groupBox3.Location = new System.Drawing.Point(6, 213); + this.groupBox3.Name = "groupBox3"; + this.groupBox3.Size = new System.Drawing.Size(517, 196); + this.groupBox3.TabIndex = 86; + this.groupBox3.TabStop = false; + // + // listView_AccessRights + // + this.listView_AccessRights.Dock = System.Windows.Forms.DockStyle.Fill; + this.listView_AccessRights.FullRowSelect = true; + this.listView_AccessRights.HideSelection = false; + this.listView_AccessRights.HoverSelection = true; + this.listView_AccessRights.Location = new System.Drawing.Point(3, 16); + this.listView_AccessRights.MultiSelect = false; + this.listView_AccessRights.Name = "listView_AccessRights"; + this.listView_AccessRights.ShowItemToolTips = true; + this.listView_AccessRights.Size = new System.Drawing.Size(511, 177); + this.listView_AccessRights.TabIndex = 4; + this.listView_AccessRights.UseCompatibleStateImageBehavior = false; + this.listView_AccessRights.View = System.Windows.Forms.View.Details; + // + // button_SaveSettings + // + this.button_SaveSettings.DialogResult = System.Windows.Forms.DialogResult.OK; + this.button_SaveSettings.Location = new System.Drawing.Point(402, 422); + this.button_SaveSettings.Margin = new System.Windows.Forms.Padding(2); + this.button_SaveSettings.Name = "button_SaveSettings"; + this.button_SaveSettings.Size = new System.Drawing.Size(118, 22); + this.button_SaveSettings.TabIndex = 85; + this.button_SaveSettings.Text = "Save Settings"; + this.button_SaveSettings.UseVisualStyleBackColor = true; + this.button_SaveSettings.Click += new System.EventHandler(this.button_SaveControlSettings_Click); + // + // groupBox2 + // + this.groupBox2.Controls.Add(this.checkBox_AllowCopyout); + this.groupBox2.Controls.Add(this.checkBox_Encryption); + this.groupBox2.Controls.Add(this.checkBox_HideFiles); + this.groupBox2.Controls.Add(this.checkBox_AllowRead); + this.groupBox2.Controls.Add(this.checkBox_AllowSetSecurity); + this.groupBox2.Controls.Add(this.checkBox_AllowWrite); + this.groupBox2.Controls.Add(this.checkBox_AllowDelete); + this.groupBox2.Controls.Add(this.checkBox_AllowRename); + this.groupBox2.Controls.Add(this.checkBox_AllowRemoteAccess); + this.groupBox2.Controls.Add(this.checkBox_AllowNewFileCreation); + this.groupBox2.Controls.Add(this.textBox_PassPhrase); + this.groupBox2.Controls.Add(this.label_PassPhrase); + this.groupBox2.Location = new System.Drawing.Point(6, 51); + this.groupBox2.Name = "groupBox2"; + this.groupBox2.Size = new System.Drawing.Size(517, 156); + this.groupBox2.TabIndex = 76; + this.groupBox2.TabStop = false; + this.groupBox2.Text = "Folder Access Control Settings"; + // + // checkBox_AllowCopyout + // + this.checkBox_AllowCopyout.AutoSize = true; + this.checkBox_AllowCopyout.Location = new System.Drawing.Point(7, 68); + this.checkBox_AllowCopyout.Name = "checkBox_AllowCopyout"; + this.checkBox_AllowCopyout.Size = new System.Drawing.Size(154, 17); + this.checkBox_AllowCopyout.TabIndex = 36; + this.checkBox_AllowCopyout.Text = "Allow files being copied out"; + this.checkBox_AllowCopyout.UseVisualStyleBackColor = true; + this.checkBox_AllowCopyout.CheckedChanged += new System.EventHandler(this.checkBox_AllowCopyout_CheckedChanged_1); + // + // checkBox_Encryption + // + this.checkBox_Encryption.AutoSize = true; + this.checkBox_Encryption.Location = new System.Drawing.Point(346, 55); + this.checkBox_Encryption.Name = "checkBox_Encryption"; + this.checkBox_Encryption.Size = new System.Drawing.Size(127, 17); + this.checkBox_Encryption.TabIndex = 28; + this.checkBox_Encryption.Text = "Enable file encryption"; + this.checkBox_Encryption.UseVisualStyleBackColor = true; + this.checkBox_Encryption.CheckedChanged += new System.EventHandler(this.checkBox_EnableEncryption_CheckedChanged); + // + // checkBox_HideFiles + // + this.checkBox_HideFiles.AutoSize = true; + this.checkBox_HideFiles.Location = new System.Drawing.Point(346, 32); + this.checkBox_HideFiles.Name = "checkBox_HideFiles"; + this.checkBox_HideFiles.Size = new System.Drawing.Size(109, 17); + this.checkBox_HideFiles.TabIndex = 26; + this.checkBox_HideFiles.Text = "Hide files in folder"; + this.checkBox_HideFiles.UseVisualStyleBackColor = true; + this.checkBox_HideFiles.CheckedChanged += new System.EventHandler(this.checkBox_HideFiles_CheckedChanged); + // + // checkBox_AllowRead + // + this.checkBox_AllowRead.AutoSize = true; + this.checkBox_AllowRead.Location = new System.Drawing.Point(191, 88); + this.checkBox_AllowRead.Name = "checkBox_AllowRead"; + this.checkBox_AllowRead.Size = new System.Drawing.Size(110, 17); + this.checkBox_AllowRead.TabIndex = 27; + this.checkBox_AllowRead.Text = "Allow files reading"; + this.checkBox_AllowRead.UseVisualStyleBackColor = true; + this.checkBox_AllowRead.CheckedChanged += new System.EventHandler(this.checkBox_AllowRead_CheckedChanged); + // + // checkBox_AllowSetSecurity + // + this.checkBox_AllowSetSecurity.AutoSize = true; + this.checkBox_AllowSetSecurity.Location = new System.Drawing.Point(191, 68); + this.checkBox_AllowSetSecurity.Name = "checkBox_AllowSetSecurity"; + this.checkBox_AllowSetSecurity.Size = new System.Drawing.Size(129, 17); + this.checkBox_AllowSetSecurity.TabIndex = 25; + this.checkBox_AllowSetSecurity.Text = "Allow security change"; + this.checkBox_AllowSetSecurity.UseVisualStyleBackColor = true; + this.checkBox_AllowSetSecurity.CheckedChanged += new System.EventHandler(this.checkBox_AllowSetSecurity_CheckedChanged); + // + // checkBox_AllowWrite + // + this.checkBox_AllowWrite.AutoSize = true; + this.checkBox_AllowWrite.Location = new System.Drawing.Point(191, 32); + this.checkBox_AllowWrite.Name = "checkBox_AllowWrite"; + this.checkBox_AllowWrite.Size = new System.Drawing.Size(100, 17); + this.checkBox_AllowWrite.TabIndex = 15; + this.checkBox_AllowWrite.Text = "Allow file writing"; + this.checkBox_AllowWrite.UseVisualStyleBackColor = true; + this.checkBox_AllowWrite.CheckedChanged += new System.EventHandler(this.checkBox_AllowWrite_CheckedChanged); + // + // checkBox_AllowDelete + // + this.checkBox_AllowDelete.AutoSize = true; + this.checkBox_AllowDelete.Location = new System.Drawing.Point(7, 32); + this.checkBox_AllowDelete.Name = "checkBox_AllowDelete"; + this.checkBox_AllowDelete.Size = new System.Drawing.Size(107, 17); + this.checkBox_AllowDelete.TabIndex = 17; + this.checkBox_AllowDelete.Text = "Allow file deletion"; + this.checkBox_AllowDelete.UseVisualStyleBackColor = true; + this.checkBox_AllowDelete.CheckedChanged += new System.EventHandler(this.checkBox_AllowDelete_CheckedChanged); + // + // checkBox_AllowRename + // + this.checkBox_AllowRename.AutoSize = true; + this.checkBox_AllowRename.Location = new System.Drawing.Point(7, 49); + this.checkBox_AllowRename.Name = "checkBox_AllowRename"; + this.checkBox_AllowRename.Size = new System.Drawing.Size(113, 17); + this.checkBox_AllowRename.TabIndex = 16; + this.checkBox_AllowRename.Text = "Allow file renaming"; + this.checkBox_AllowRename.UseVisualStyleBackColor = true; + this.checkBox_AllowRename.CheckedChanged += new System.EventHandler(this.checkBox_AllowRename_CheckedChanged); + // + // checkBox_AllowRemoteAccess + // + this.checkBox_AllowRemoteAccess.AutoSize = true; + this.checkBox_AllowRemoteAccess.Location = new System.Drawing.Point(6, 88); + this.checkBox_AllowRemoteAccess.Name = "checkBox_AllowRemoteAccess"; + this.checkBox_AllowRemoteAccess.Size = new System.Drawing.Size(182, 17); + this.checkBox_AllowRemoteAccess.TabIndex = 21; + this.checkBox_AllowRemoteAccess.Text = "Allow file accessing from network"; + this.checkBox_AllowRemoteAccess.UseVisualStyleBackColor = true; + this.checkBox_AllowRemoteAccess.CheckedChanged += new System.EventHandler(this.checkBox_AllowRemoteAccess_CheckedChanged); + // + // checkBox_AllowNewFileCreation + // + this.checkBox_AllowNewFileCreation.AutoSize = true; + this.checkBox_AllowNewFileCreation.Location = new System.Drawing.Point(191, 49); + this.checkBox_AllowNewFileCreation.Name = "checkBox_AllowNewFileCreation"; + this.checkBox_AllowNewFileCreation.Size = new System.Drawing.Size(131, 17); + this.checkBox_AllowNewFileCreation.TabIndex = 22; + this.checkBox_AllowNewFileCreation.Text = "Allow new file creation"; + this.checkBox_AllowNewFileCreation.UseVisualStyleBackColor = true; + this.checkBox_AllowNewFileCreation.CheckedChanged += new System.EventHandler(this.checkBox_AllowNewFileCreation_CheckedChanged); + // + // textBox_PassPhrase + // + this.textBox_PassPhrase.Location = new System.Drawing.Point(346, 100); + this.textBox_PassPhrase.Name = "textBox_PassPhrase"; + this.textBox_PassPhrase.PasswordChar = '●'; + this.textBox_PassPhrase.ReadOnly = true; + this.textBox_PassPhrase.Size = new System.Drawing.Size(100, 20); + this.textBox_PassPhrase.TabIndex = 19; + this.textBox_PassPhrase.UseSystemPasswordChar = true; + // + // label_PassPhrase + // + this.label_PassPhrase.AutoSize = true; + this.label_PassPhrase.Location = new System.Drawing.Point(344, 76); + this.label_PassPhrase.Name = "label_PassPhrase"; + this.label_PassPhrase.Size = new System.Drawing.Size(88, 13); + this.label_PassPhrase.TabIndex = 20; + this.label_PassPhrase.Text = "Password phrase"; + // + // label_FolderName + // + this.label_FolderName.AutoSize = true; + this.label_FolderName.Location = new System.Drawing.Point(10, 15); + this.label_FolderName.Name = "label_FolderName"; + this.label_FolderName.Size = new System.Drawing.Size(67, 13); + this.label_FolderName.TabIndex = 12; + this.label_FolderName.Text = "Folder Name"; + // + // textBox_FolderName + // + this.textBox_FolderName.Location = new System.Drawing.Point(196, 20); + this.textBox_FolderName.Name = "textBox_FolderName"; + this.textBox_FolderName.Size = new System.Drawing.Size(265, 20); + this.textBox_FolderName.TabIndex = 11; + this.textBox_FolderName.Text = "c:\\FolderLocker"; + // + // button_BrowseFolder + // + this.button_BrowseFolder.Location = new System.Drawing.Point(482, 20); + this.button_BrowseFolder.Name = "button_BrowseFolder"; + this.button_BrowseFolder.Size = new System.Drawing.Size(41, 20); + this.button_BrowseFolder.TabIndex = 14; + this.button_BrowseFolder.Text = "..."; + this.button_BrowseFolder.UseVisualStyleBackColor = true; + this.button_BrowseFolder.Click += new System.EventHandler(this.button_BrowseFolder_Click); + // + // FolderLockerSettigs + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(554, 499); + this.Controls.Add(this.groupBox1); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Margin = new System.Windows.Forms.Padding(2); + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "FolderLockerSettigs"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "Folder Locker Settings"; + this.Load += new System.EventHandler(this.FolderLockerSettigs_Load); + this.groupBox1.ResumeLayout(false); + this.groupBox_AccessControl.ResumeLayout(false); + this.groupBox_AccessControl.PerformLayout(); + this.groupBox3.ResumeLayout(false); + this.groupBox2.ResumeLayout(false); + this.groupBox2.PerformLayout(); + this.ResumeLayout(false); + + } + + #endregion + + + private System.Windows.Forms.GroupBox groupBox1; + private System.Windows.Forms.GroupBox groupBox_AccessControl; + private System.Windows.Forms.GroupBox groupBox2; + private System.Windows.Forms.CheckBox checkBox_AllowSetSecurity; + private System.Windows.Forms.CheckBox checkBox_AllowWrite; + private System.Windows.Forms.CheckBox checkBox_AllowDelete; + private System.Windows.Forms.CheckBox checkBox_AllowRename; + private System.Windows.Forms.CheckBox checkBox_AllowRemoteAccess; + private System.Windows.Forms.CheckBox checkBox_AllowNewFileCreation; + private System.Windows.Forms.Label label_PassPhrase; + private System.Windows.Forms.Label label_FolderName; + private System.Windows.Forms.TextBox textBox_FolderName; + private System.Windows.Forms.Button button_BrowseFolder; + private System.Windows.Forms.TextBox textBox_PassPhrase; + private System.Windows.Forms.Button button_SaveSettings; + private System.Windows.Forms.CheckBox checkBox_HideFiles; + private System.Windows.Forms.CheckBox checkBox_AllowRead; + private System.Windows.Forms.ToolTip toolTip1; + private System.Windows.Forms.CheckBox checkBox_Encryption; + private System.Windows.Forms.GroupBox groupBox3; + private System.Windows.Forms.Button button_RemoveRights; + private System.Windows.Forms.Button button_AddProcessRights; + private System.Windows.Forms.Button button_AddUserRights; + private System.Windows.Forms.ListView listView_AccessRights; + private System.Windows.Forms.CheckBox checkBox_AllowCopyout; + } +} \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/FolderLocker/FolderLockerSettigs.cs b/Demo_Source_Code/CSharpDemo/FolderLocker/FolderLockerSettigs.cs new file mode 100644 index 0000000..fd6b0bf --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FolderLocker/FolderLockerSettigs.cs @@ -0,0 +1,552 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +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; + +using EaseFilter.FilterControl; +using EaseFilter.CommonObjects; + +namespace EaseFilter.FolderLocker +{ + public partial class FolderLockerSettigs : Form + { + public FileFilterRule filterRule = new FileFilterRule(); + + uint accessFlags = FilterAPI.ALLOW_MAX_RIGHT_ACCESS; + Dictionary userList = new Dictionary(); + Dictionary processList = new Dictionary(); + bool isFormInitialized = false; + + public FolderLockerSettigs(FileFilterRule _filterRule) + { + InitializeComponent(); + + + if (null != _filterRule) + { + filterRule = _filterRule; + accessFlags = filterRule.AccessFlag; + + textBox_FolderName.Enabled = false; + button_BrowseFolder.Enabled = false; + + textBox_FolderName.Text = filterRule.IncludeFileFilterMask.Replace("\\*",""); + textBox_PassPhrase.Text = filterRule.EncryptionPassPhrase; + + } + else + { + textBox_FolderName.Enabled = true; + button_BrowseFolder.Enabled = true; + } + + SetCheckBoxValue(); + + InitAccessList(); + + InitAccessRightsListView(); + + isFormInitialized = true; + } + + private void InitAccessList() + { + string[] processRights = filterRule.ProcessNameRights.Split(new char[] { ';' }); + if (processRights.Length > 0) + { + foreach (string processRight in processRights) + { + if (processRight.Trim().Length > 0) + { + string processName = processRight.Substring(0, processRight.IndexOf('!')); + uint accessFlags = uint.Parse(processRight.Substring(processRight.IndexOf('!') + 1)); + + if( processList.ContainsKey(processName.ToLower())) + { + processList.Remove(processName.ToLower()); + } + + processList.Add(processName.ToLower(), accessFlags); + } + } + + } + + string[] userRights = filterRule.UserRights.Split(new char[] { ';' }); + if (userRights.Length > 0) + { + foreach (string userRight in userRights) + { + if (userRight.Trim().Length > 0) + { + string userName = userRight.Substring(0, userRight.IndexOf('!')); + uint accessFlags = uint.Parse(userRight.Substring(userRight.IndexOf('!') + 1)); + + if (userList.ContainsKey(userName.ToLower())) + { + userList.Remove(userName.ToLower()); + } + + userList.Add(userName.ToLower(), accessFlags); + } + } + + } + + } + + private void InitAccessRightsListView() + { + //init ListView control + listView_AccessRights.Clear(); //clear control + //create column header for ListView + listView_AccessRights.Columns.Add("Type", 50, System.Windows.Forms.HorizontalAlignment.Left); + listView_AccessRights.Columns.Add("Name", 160, System.Windows.Forms.HorizontalAlignment.Left); + listView_AccessRights.Columns.Add("Readable", 70, System.Windows.Forms.HorizontalAlignment.Left); + listView_AccessRights.Columns.Add("Writable", 70, System.Windows.Forms.HorizontalAlignment.Left); + listView_AccessRights.Columns.Add("Deletable", 70, System.Windows.Forms.HorizontalAlignment.Left); + listView_AccessRights.Columns.Add("Renamable", 70, System.Windows.Forms.HorizontalAlignment.Left); + + + foreach (KeyValuePair entry in userList) + { + string userName = entry.Key; + uint accessFlags = entry.Value; + + string[] listEntry = new string[listView_AccessRights.Columns.Count]; + int index = 0; + listEntry[index++] = "user"; + listEntry[index++] = userName; + listEntry[index++] = ((accessFlags&(uint)FilterAPI.AccessFlag.ALLOW_READ_ACCESS) > 0).ToString(); + listEntry[index++] = ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_WRITE_ACCESS) > 0).ToString(); + listEntry[index++] = ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_FILE_DELETE) > 0).ToString(); + listEntry[index++] = ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_FILE_RENAME) > 0).ToString(); + + ListViewItem item = new ListViewItem(listEntry, 0); + item.Tag = entry; + listView_AccessRights.Items.Add(item); + + } + + + foreach (KeyValuePair entry in processList) + { + string processName = entry.Key; + uint accessFlags = entry.Value; + + string[] listEntry = new string[listView_AccessRights.Columns.Count]; + int index = 0; + listEntry[index++] = "process"; + listEntry[index++] = processName; + listEntry[index++] = ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_READ_ACCESS) > 0).ToString(); + listEntry[index++] = ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_WRITE_ACCESS) > 0).ToString(); + listEntry[index++] = ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_FILE_DELETE) > 0).ToString(); + listEntry[index++] = ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_FILE_RENAME) > 0).ToString(); + + ListViewItem item = new ListViewItem(listEntry, 0); + item.Tag = entry; + listView_AccessRights.Items.Add(item); + + } + + } + + private void SetCheckBoxValue() + { + + if ((accessFlags & (uint)FilterAPI.AccessFlag.ENABLE_FILE_ENCRYPTION_RULE) > 0 ) + { + checkBox_Encryption.Checked = true; + textBox_PassPhrase.ReadOnly = false; + } + else + { + checkBox_Encryption.Checked = false; + textBox_PassPhrase.ReadOnly = true; + } + + if ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_FILE_ACCESS_FROM_NETWORK) > 0) + { + checkBox_AllowRemoteAccess.Checked = true; + } + else + { + checkBox_AllowRemoteAccess.Checked = false; + } + + if ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_FILE_DELETE) > 0) + { + checkBox_AllowDelete.Checked = true; + } + else + { + checkBox_AllowDelete.Checked = false; + } + + if ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_SET_SECURITY_ACCESS) > 0) + { + checkBox_AllowSetSecurity.Checked = true; + } + else + { + checkBox_AllowSetSecurity.Checked = false; + } + + if ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_FILE_RENAME) > 0) + { + checkBox_AllowRename.Checked = true; + } + else + { + checkBox_AllowRename.Checked = false; + } + + if ( (accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_WRITE_ACCESS) > 0 ) + { + checkBox_AllowWrite.Checked = true; + } + else + { + checkBox_AllowWrite.Checked = false; + } + + if ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_OPEN_WITH_CREATE_OR_OVERWRITE_ACCESS) > 0) + { + checkBox_AllowNewFileCreation.Checked = true; + } + else + { + checkBox_AllowNewFileCreation.Checked = false; + } + + if ((accessFlags & (uint)FilterAPI.AccessFlag.ENABLE_HIDE_FILES_IN_DIRECTORY_BROWSING) > 0) + { + checkBox_HideFiles.Checked = true; + } + else + { + checkBox_HideFiles.Checked = false; + } + + if ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_READ_ACCESS) > 0) + { + checkBox_AllowRead.Checked = true; + } + else + { + checkBox_AllowRead.Checked = false; + } + + + if ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_COPY_PROTECTED_FILES_OUT) > 0) + { + checkBox_AllowCopyout.Checked = true; + } + else + { + checkBox_AllowCopyout.Checked = false; + } + + + } + + private void button_SaveControlSettings_Click(object sender, EventArgs e) + { + string encryptionPassPhrase = string.Empty; + + filterRule.IncludeFileFilterMask = textBox_FolderName.Text + "\\*"; + filterRule.EncryptionPassPhrase = textBox_PassPhrase.Text; + filterRule.AccessFlag = accessFlags; + + if ((accessFlags & (uint)FilterAPI.AccessFlag.ENABLE_FILE_ENCRYPTION_RULE) > 0 ) + { + if (textBox_PassPhrase.Text.Trim().Length == 0) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("Please enter the passphrase when encryption is enabled.", "Passphrase", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + filterRule.EncryptMethod = (int)FilterAPI.EncryptionMethod.ENCRYPT_FILE_WITH_SAME_KEY_AND_UNIQUE_IV; + } + + if ((accessFlags & (uint)FilterAPI.AccessFlag.ENABLE_HIDE_FILES_IN_DIRECTORY_BROWSING) > 0) + { + filterRule.HiddenFileFilterMasks = "*"; + } + + if (userList.Count == 0) + { + filterRule.UserRights = ""; + } + else + { + foreach (KeyValuePair entry in userList) + { + filterRule.UserRights = entry.Key + "!" + entry.Value + ";"; + } + } + + if (processList.Count == 0) + { + filterRule.ProcessNameRights = ""; + } + else + { + foreach (KeyValuePair entry in processList) + { + filterRule.ProcessNameRights = entry.Key + "!" + entry.Value + ";"; + } + } + + } + + private void checkBox_AllowDelete_CheckedChanged(object sender, EventArgs e) + { + + if (!checkBox_AllowDelete.Checked) + { + accessFlags = accessFlags & ((uint)~FilterAPI.AccessFlag.ALLOW_FILE_DELETE); + } + else + { + accessFlags = accessFlags | ((uint)FilterAPI.AccessFlag.ALLOW_FILE_DELETE); + } + + } + + private void checkBox_AllowWrite_CheckedChanged(object sender, EventArgs e) + { + if (!checkBox_AllowWrite.Checked) + { + accessFlags = accessFlags & ((uint)~FilterAPI.AccessFlag.ALLOW_WRITE_ACCESS); + } + else + { + accessFlags = accessFlags | ((uint)FilterAPI.AccessFlag.ALLOW_WRITE_ACCESS); + } + + } + + private void checkBox_AllowRename_CheckedChanged(object sender, EventArgs e) + { + + if (!checkBox_AllowRename.Checked) + { + accessFlags = accessFlags & ((uint)~FilterAPI.AccessFlag.ALLOW_FILE_RENAME); + } + else + { + accessFlags = accessFlags | ((uint)FilterAPI.AccessFlag.ALLOW_FILE_RENAME); + } + + } + + private void checkBox_AllowRemoteAccess_CheckedChanged(object sender, EventArgs e) + { + if (!checkBox_AllowRemoteAccess.Checked) + { + accessFlags = accessFlags & ((uint)~FilterAPI.AccessFlag.ALLOW_FILE_ACCESS_FROM_NETWORK); + } + else + { + accessFlags = accessFlags | ((uint)FilterAPI.AccessFlag.ALLOW_FILE_ACCESS_FROM_NETWORK); + } + + } + + private void checkBox_AllowNewFileCreation_CheckedChanged(object sender, EventArgs e) + { + + if (!checkBox_AllowNewFileCreation.Checked) + { + accessFlags = accessFlags & ((uint)~FilterAPI.AccessFlag.ALLOW_OPEN_WITH_CREATE_OR_OVERWRITE_ACCESS); + } + else + { + accessFlags = accessFlags | ((uint)FilterAPI.AccessFlag.ALLOW_OPEN_WITH_CREATE_OR_OVERWRITE_ACCESS); + } + + } + + private void checkBox_AllowSetSecurity_CheckedChanged(object sender, EventArgs e) + { + if (!checkBox_AllowSetSecurity.Checked) + { + accessFlags = accessFlags & ((uint)~FilterAPI.AccessFlag.ALLOW_SET_SECURITY_ACCESS); + } + else + { + accessFlags = accessFlags | ((uint)FilterAPI.AccessFlag.ALLOW_SET_SECURITY_ACCESS); + } + + } + + + private void checkBox_HideFiles_CheckedChanged(object sender, EventArgs e) + { + if (!checkBox_HideFiles.Checked) + { + accessFlags = accessFlags & ((uint)~FilterAPI.AccessFlag.ENABLE_HIDE_FILES_IN_DIRECTORY_BROWSING); + } + else + { + accessFlags = accessFlags | ((uint)FilterAPI.AccessFlag.ENABLE_HIDE_FILES_IN_DIRECTORY_BROWSING); + } + + } + + private void checkBox_AllowCopyout_CheckedChanged_1(object sender, EventArgs e) + { + if (!checkBox_AllowCopyout.Checked) + { + accessFlags = accessFlags & ((uint)~FilterAPI.AccessFlag.ALLOW_COPY_PROTECTED_FILES_OUT); + } + else + { + accessFlags = accessFlags | ((uint)FilterAPI.AccessFlag.ALLOW_COPY_PROTECTED_FILES_OUT); + } + } + + private void checkBox_AllowRead_CheckedChanged(object sender, EventArgs e) + { + if (!checkBox_AllowRead.Checked) + { + accessFlags = accessFlags & ((uint)~FilterAPI.AccessFlag.ALLOW_READ_ACCESS); + } + else + { + accessFlags = accessFlags | ((uint)FilterAPI.AccessFlag.ALLOW_READ_ACCESS); + } + + } + + private void checkBox_EnableEncryption_CheckedChanged(object sender, EventArgs e) + { + if (!isFormInitialized) + { + return; + } + + if (checkBox_Encryption.Checked) + { + textBox_PassPhrase.ReadOnly = false; + accessFlags = accessFlags | ((uint)FilterAPI.AccessFlag.ENABLE_FILE_ENCRYPTION_RULE); + + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("Please note that the existing files won't be encrypted.", "encryption", MessageBoxButtons.OK, MessageBoxIcon.Warning); + } + else + { + textBox_PassPhrase.ReadOnly = true; + accessFlags = accessFlags & ((uint)~FilterAPI.AccessFlag.ENABLE_FILE_ENCRYPTION_RULE); + + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("Please note that the existing encrypted files won't be decrypted.", "encryption", MessageBoxButtons.OK, MessageBoxIcon.Warning); + } + } + + + private void button_AddUserRights_Click_1(object sender, EventArgs e) + { + string defaultUserName = Environment.UserDomainName + "\\" + Environment.UserName; + Form_AccessRights accessRightsForm = new Form_AccessRights(false, FilterAPI.ALLOW_MAX_RIGHT_ACCESS, defaultUserName); + + if (accessRightsForm.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + string userName = accessRightsForm.accessName; + uint accessFlags = accessRightsForm.accessFlags; + + if( userList.ContainsKey(userName.ToLower())) + { + userList.Remove(userName.ToLower()); + } + + userList.Add(userName, accessFlags); + InitAccessRightsListView(); + } + } + + private void button_AddProcessRights_Click(object sender, EventArgs e) + { + Form_AccessRights accessRightsForm = new Form_AccessRights(true, FilterAPI.ALLOW_MAX_RIGHT_ACCESS, "explorer.exe"); + + if (accessRightsForm.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + string processName = accessRightsForm.accessName; + uint accessFlags = accessRightsForm.accessFlags; + + if (processList.ContainsKey(processName.ToLower())) + { + processList.Remove(processName.ToLower()); + } + + processList.Add(processName.ToLower(), accessFlags); + InitAccessRightsListView(); + } + } + + private void button_RemoveRights_Click(object sender, EventArgs e) + { + if (listView_AccessRights.SelectedItems.Count != 1) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("Please select one item to delete.", "Delete Access Right", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + System.Windows.Forms.ListViewItem item = listView_AccessRights.SelectedItems[0]; + string type = item.SubItems[0].Text; + string name = item.SubItems[1].Text; + + if (string.Compare(type, "user") == 0) + { + userList.Remove(name.ToLower()); + } + else + { + processList.Remove(name.ToLower()); + } + + InitAccessRightsListView(); + + } + + private void button_BrowseFolder_Click(object sender, EventArgs e) + { + FolderBrowserDialog browseFolder = new FolderBrowserDialog(); + + if (browseFolder.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + textBox_FolderName.Text = browseFolder.SelectedPath; + } + } + + private void FolderLockerSettigs_Load(object sender, EventArgs e) + { + + } + + } +} diff --git a/Demo_Source_Code/CSharpDemo/FolderLocker/FolderLockerSettigs.resx b/Demo_Source_Code/CSharpDemo/FolderLocker/FolderLockerSettigs.resx new file mode 100644 index 0000000..5db443e --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FolderLocker/FolderLockerSettigs.resx @@ -0,0 +1,414 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 1041, 95 + + + 25 + + + + + AAABAAEAQEAAAAEAIAAoQgAAFgAAACgAAABAAAAAgAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOTX0YDk19H/5NfR/+TX0f/k19H/5NfR/+TX + 0f/k19H/5NfR/+TX0f/k19H/5NfR/+TX0f/k19H/5NfR/+TX0f/k19H/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADRydP/RGLg/0Ri + 4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/+TX + 0f8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AADk19FARGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri + 4P9EYuD/RGLg/0Ri4P/k19H/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA5NfRQERi4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri + 4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/5NfR/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQjs4/0I7OP9COzj/Qjs4/0I7OP9COzj/Qjs4/0I7 + OP9COzj/Qjs4/0I7OP9COzj/Qjs4/0I7OP9COzj/Qjs4/0I7OP9COzj/Qjs4/0I7OP9COzj/Qjs4/0I7 + OP9COzj/Qjs4/0I7OP9COzj/Qjs4/0I7OP9COzj/Qjs4/2tiXv9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri + 4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/+TX0f8AAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEI7OP9fVVH/X1VR/19V + Uf9fVVH/X1VR/19VUf9fVVH/X1VR/19VUf9fVVH/X1VR/19VUf9fVVH/X1VR/19VUf9fVVH/X1VR/19V + Uf9fVVH/X1VR/19VUf9fVVH/X1VR/19VUf9fVVH/X1VR/19VUf9fVVH/X1VR/19VUf+AdnH/RGLg/0Ri + 4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri + 4P/k19H/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AABCOzj/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/iHx4/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri + 4P9EYuD/RGLg/0Ri4P9EYuD/5NfR/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAQjs4/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/4h8eP9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri + 4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/+TX0f8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEI7OP9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv+IfHj/RGLg/0Ri4P9EYuD/RGLg/0Ri + 4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P/k19H/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABCOzj/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/iHx4/0Ri + 4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri + 4P9EYuD/5NfR/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAQjs4/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/4h8eP9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri + 4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/+TX0f8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAEI7OP9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv+IfHj/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri + 4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P/k19H/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABCOzj/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/+TX0f+8utX/RGLg/0Ri + 4P9EYuD/vLrV/7y61f+8utX/vLrV/7y61f+8utX/vLrV/7y61f9EYuD/RGLg/0Ri4P/k19H/5NfR/wAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQjs4/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/5NfR/0Ri4P9EYuD/RGLg/+TX0f9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv/k19H/RGLg/0Ri + 4P9EYuD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAEI7OP9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/+TX0f9EYuD/RGLg/0Ri4P/k19H/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/5NfR/0Ri4P9EYuD/RGLg/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABCOzj/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv/k19H/RGLg/0Ri4P9EYuD/5NfR/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/+TX0f9EYuD/RGLg/0Ri4P8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQjs4/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/5NfR/0Ri + 4P9EYuD/RGLg/+TX0f9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv/k19H/RGLg/0Ri4P9EYuD/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEI7 + OP9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/+TX0f9EYuD/RGLg/0Ri4P/k19H/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/5NfR/0Ri + 4P9EYuD/RGLg/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAABCOzj/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv/k19H/RGLg/0Ri4P9EYuD/5NfR/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/1hx3v9EYuD/RGLg/0Ri4P8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQjs4/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/3dDK/0Ri4P9EYuD/RGLg/0Ri + 4P+XjIf/aV5a/2leWv9pXlr/aV5a/+TX0f9EYuD/RGLg/0Ri4P/k19H/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEI7OP9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv/k19H/RGLg/0Ri4P9EYuD/5NfR/9XIw/9pXlr/aV5a/+TX0f9EYuD/RGLg/0Ri4P9EYuD/5NfR/wAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AABCOzj/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/5NfR/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/vLrV/2x/3P9EYuD/RGLg/0Ri + 4P9EYuD/Tmnf/+TX0WAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAQjs4/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv/k19H/RGLg/0Ri4P9EYuD/RGLg/0Ri + 4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/+TX0f8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEI7OP9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/+TX + 0f9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/Tmnf/+TX0f8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABCOzj/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/5NfR/+TX0f+Kldn/RGLg/0Ri4P/k19H/5NfR/5eMh/8AAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAQjs4/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAEI7OP9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABCOzj/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQjs4/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAEI7OP9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABCOzj/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQjs4/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEI7 + OP+Ddm7/g3Zu/4N2bv+Ddm7/g3Zu/4N2bv+Ddm7/g3Zu/4N2bv+Ddm7/g3Zu/4N2bv+Ddm7/g3Zu/4N2 + bv+Ddm7/g3Zu/4N2bv+Ddm7/g3Zu/2tgW/9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/wAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAABCOzj/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19U + UP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP+Ddm7/bmNe/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQjs4/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19U + UP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/4N2 + bv9uY17/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEI7OP9fVFD/X1RQ/19U + UP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19U + UP9fVFD/X1RQ/19UUP9fVFD/g3Zu/4N2bv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9zZ2L/dmpk/wAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AABCOzj/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19U + UP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/T0ZD/0I7OP9COzj/Qjs4/0I7OP9COzj/Qjs4/0I7 + OP9COzj/Qjs4/0I7OP9COzj/Qjs4/0I7OP9COzj/Qjs4/0I7OP9COzj/Qjs4/0I7OP9COzj/Qjs4/wAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAQjs4/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19U + UP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/wAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEI7OP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19U + UP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19U + UP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABCOzj/X1RQ/19U + UP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19U + UP9fVFD/X1RQ/19UUP9fVFD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAQjs4/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19U + UP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/Qjs4/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABCOzigQjs4/0I7OP9COzj/Qjs4/0I7OP9COzj/Qjs4/0I7 + OP9COzj/Qjs4/0I7OP9COzj/Qjs4/0I7OP9COzj/Qjs4/0I7OP9COzj/Qjs4/wAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA//////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////+AAD///////4AAH///////AAAf/// + ///8AAB//gAAAAAAAH/+AAAAAAAAf/4AAAAAAAB//gAAAAAAAH/+AAAAAAAAf/4AAAAAAAB//gAAAAAA + AH/+AAAAAAAAf/4AAAAAAAB//gAAAAAAAf/+AAAAAAAB//4AAAAAAAH//gAAAAAAAf/+AAAAAAAB//4A + AAAAAAH//gAAAAAAAf/+AAAAAAAB//4AAAAAAAH//gAAAAAAA//+AAAAAAAH//4AAAAAAA///gAAAAAA + D//+AAAAAAAP//4AAAAAAA///gAAAAAAD//+AAAAAAAP//4AAAAAAA///gAAAAAAD//+AAAAAAAP//4A + AAAAAA///gAAAAAAD//+AAAAAAAP//4AAAAAAB///gAAB//////+AAAH//////4AAAf//////gAAB/// + ////AAAP//////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////8= + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/FolderLocker/FormFolderLocker.Designer.cs b/Demo_Source_Code/CSharpDemo/FolderLocker/FormFolderLocker.Designer.cs new file mode 100644 index 0000000..80b0ee3 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FolderLocker/FormFolderLocker.Designer.cs @@ -0,0 +1,350 @@ +namespace EaseFilter.FolderLocker +{ + partial class Form_FolderLocker + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form_FolderLocker)); + this.imageList1 = new System.Windows.Forms.ImageList(this.components); + this.folderBrowserDialog1 = new System.Windows.Forms.FolderBrowserDialog(); + this.tabPage_Help = new System.Windows.Forms.TabPage(); + this.linkLabel_SDK = new System.Windows.Forms.LinkLabel(); + this.linkLabel_Report = new System.Windows.Forms.LinkLabel(); + this.label_VersionInfo = new System.Windows.Forms.Label(); + this.tabPage_Folder = new System.Windows.Forms.TabPage(); + this.splitContainer1 = new System.Windows.Forms.SplitContainer(); + this.statusStrip1 = new System.Windows.Forms.StatusStrip(); + this.toolStripStatusLabel1 = new System.Windows.Forms.ToolStripStatusLabel(); + this.listView_LockFolders = new System.Windows.Forms.ListView(); + this.toolStrip1 = new System.Windows.Forms.ToolStrip(); + this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); + this.toolStripButton_StartFilter = new System.Windows.Forms.ToolStripButton(); + this.toolStripButton_Stop = new System.Windows.Forms.ToolStripButton(); + this.toolStripButton_AddFolder = new System.Windows.Forms.ToolStripButton(); + this.toolStripSeparator5 = new System.Windows.Forms.ToolStripSeparator(); + this.toolStripButton_RemoveFolder = new System.Windows.Forms.ToolStripButton(); + this.toolStripSeparator4 = new System.Windows.Forms.ToolStripSeparator(); + this.toolStripButton_ModifyFolder = new System.Windows.Forms.ToolStripButton(); + this.listView_AccessRights = new System.Windows.Forms.ListView(); + this.tabControl1 = new System.Windows.Forms.TabControl(); + this.tabPage_Help.SuspendLayout(); + this.tabPage_Folder.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit(); + this.splitContainer1.Panel1.SuspendLayout(); + this.splitContainer1.Panel2.SuspendLayout(); + this.splitContainer1.SuspendLayout(); + this.statusStrip1.SuspendLayout(); + this.toolStrip1.SuspendLayout(); + this.tabControl1.SuspendLayout(); + this.SuspendLayout(); + // + // imageList1 + // + this.imageList1.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imageList1.ImageStream"))); + this.imageList1.TransparentColor = System.Drawing.Color.Transparent; + this.imageList1.Images.SetKeyName(0, "folder_ok.png"); + // + // tabPage_Help + // + this.tabPage_Help.Controls.Add(this.linkLabel_SDK); + this.tabPage_Help.Controls.Add(this.linkLabel_Report); + this.tabPage_Help.Controls.Add(this.label_VersionInfo); + this.tabPage_Help.Location = new System.Drawing.Point(4, 32); + this.tabPage_Help.Margin = new System.Windows.Forms.Padding(2); + this.tabPage_Help.Name = "tabPage_Help"; + this.tabPage_Help.Padding = new System.Windows.Forms.Padding(2); + this.tabPage_Help.Size = new System.Drawing.Size(699, 311); + this.tabPage_Help.TabIndex = 4; + this.tabPage_Help.Text = "Help"; + this.tabPage_Help.UseVisualStyleBackColor = true; + this.tabPage_Help.Visible = false; + // + // linkLabel_SDK + // + this.linkLabel_SDK.AutoSize = true; + this.linkLabel_SDK.Location = new System.Drawing.Point(18, 63); + this.linkLabel_SDK.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0); + this.linkLabel_SDK.Name = "linkLabel_SDK"; + this.linkLabel_SDK.Size = new System.Drawing.Size(192, 13); + this.linkLabel_SDK.TabIndex = 10; + this.linkLabel_SDK.TabStop = true; + this.linkLabel_SDK.Text = "Online help for EaseFilter Folder Locker"; + this.linkLabel_SDK.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLabel_SDK_LinkClicked); + // + // linkLabel_Report + // + this.linkLabel_Report.AutoSize = true; + this.linkLabel_Report.Location = new System.Drawing.Point(18, 33); + this.linkLabel_Report.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0); + this.linkLabel_Report.Name = "linkLabel_Report"; + this.linkLabel_Report.Size = new System.Drawing.Size(173, 13); + this.linkLabel_Report.TabIndex = 9; + this.linkLabel_Report.TabStop = true; + this.linkLabel_Report.Text = "Report a bug or make a suggestion"; + this.linkLabel_Report.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLabel_Report_LinkClicked); + // + // label_VersionInfo + // + this.label_VersionInfo.AutoSize = true; + this.label_VersionInfo.Location = new System.Drawing.Point(18, 20); + this.label_VersionInfo.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0); + this.label_VersionInfo.Name = "label_VersionInfo"; + this.label_VersionInfo.Size = new System.Drawing.Size(0, 13); + this.label_VersionInfo.TabIndex = 9; + // + // tabPage_Folder + // + this.tabPage_Folder.Controls.Add(this.splitContainer1); + this.tabPage_Folder.Location = new System.Drawing.Point(4, 32); + this.tabPage_Folder.Margin = new System.Windows.Forms.Padding(2); + this.tabPage_Folder.Name = "tabPage_Folder"; + this.tabPage_Folder.Padding = new System.Windows.Forms.Padding(2); + this.tabPage_Folder.Size = new System.Drawing.Size(699, 311); + this.tabPage_Folder.TabIndex = 0; + this.tabPage_Folder.Text = "Locked Folders"; + this.tabPage_Folder.UseVisualStyleBackColor = true; + // + // splitContainer1 + // + this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill; + this.splitContainer1.Location = new System.Drawing.Point(2, 2); + this.splitContainer1.Margin = new System.Windows.Forms.Padding(2); + this.splitContainer1.Name = "splitContainer1"; + this.splitContainer1.Orientation = System.Windows.Forms.Orientation.Horizontal; + // + // splitContainer1.Panel1 + // + this.splitContainer1.Panel1.Controls.Add(this.statusStrip1); + this.splitContainer1.Panel1.Controls.Add(this.listView_LockFolders); + this.splitContainer1.Panel1.Controls.Add(this.toolStrip1); + // + // splitContainer1.Panel2 + // + this.splitContainer1.Panel2.Controls.Add(this.listView_AccessRights); + this.splitContainer1.Size = new System.Drawing.Size(695, 307); + this.splitContainer1.SplitterDistance = 198; + this.splitContainer1.SplitterWidth = 3; + this.splitContainer1.TabIndex = 0; + // + // statusStrip1 + // + this.statusStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.toolStripStatusLabel1}); + this.statusStrip1.Location = new System.Drawing.Point(0, 176); + this.statusStrip1.Name = "statusStrip1"; + this.statusStrip1.Padding = new System.Windows.Forms.Padding(1, 0, 10, 0); + this.statusStrip1.Size = new System.Drawing.Size(695, 22); + this.statusStrip1.TabIndex = 4; + this.statusStrip1.Text = "statusStrip1"; + // + // toolStripStatusLabel1 + // + this.toolStripStatusLabel1.Name = "toolStripStatusLabel1"; + this.toolStripStatusLabel1.Size = new System.Drawing.Size(417, 17); + this.toolStripStatusLabel1.Text = "Below is the access rights to the specific users and processes in selected folder" + + ""; + // + // listView_LockFolders + // + this.listView_LockFolders.Dock = System.Windows.Forms.DockStyle.Fill; + this.listView_LockFolders.FullRowSelect = true; + this.listView_LockFolders.HideSelection = false; + this.listView_LockFolders.HoverSelection = true; + this.listView_LockFolders.Location = new System.Drawing.Point(0, 25); + this.listView_LockFolders.Margin = new System.Windows.Forms.Padding(2); + this.listView_LockFolders.MultiSelect = false; + this.listView_LockFolders.Name = "listView_LockFolders"; + this.listView_LockFolders.ShowItemToolTips = true; + this.listView_LockFolders.Size = new System.Drawing.Size(695, 173); + this.listView_LockFolders.TabIndex = 3; + this.listView_LockFolders.UseCompatibleStateImageBehavior = false; + this.listView_LockFolders.View = System.Windows.Forms.View.Details; + this.listView_LockFolders.SelectedIndexChanged += new System.EventHandler(this.listView_LockFolders_SelectedIndexChanged); + // + // toolStrip1 + // + this.toolStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.toolStripSeparator1, + this.toolStripButton_StartFilter, + this.toolStripButton_Stop, + this.toolStripButton_AddFolder, + this.toolStripSeparator5, + this.toolStripButton_RemoveFolder, + this.toolStripSeparator4, + this.toolStripButton_ModifyFolder}); + this.toolStrip1.Location = new System.Drawing.Point(0, 0); + this.toolStrip1.Name = "toolStrip1"; + this.toolStrip1.Size = new System.Drawing.Size(695, 25); + this.toolStrip1.TabIndex = 2; + this.toolStrip1.Text = "toolStrip1"; + // + // toolStripSeparator1 + // + this.toolStripSeparator1.Name = "toolStripSeparator1"; + this.toolStripSeparator1.Size = new System.Drawing.Size(6, 25); + // + // toolStripButton_StartFilter + // + this.toolStripButton_StartFilter.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton_StartFilter.Image"))); + this.toolStripButton_StartFilter.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButton_StartFilter.Name = "toolStripButton_StartFilter"; + this.toolStripButton_StartFilter.Size = new System.Drawing.Size(103, 22); + this.toolStripButton_StartFilter.Text = "Start protector"; + this.toolStripButton_StartFilter.Click += new System.EventHandler(this.toolStripButton_StartFilter_Click); + // + // toolStripButton_Stop + // + this.toolStripButton_Stop.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton_Stop.Image"))); + this.toolStripButton_Stop.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButton_Stop.Name = "toolStripButton_Stop"; + this.toolStripButton_Stop.Size = new System.Drawing.Size(103, 22); + this.toolStripButton_Stop.Text = "Stop protector"; + this.toolStripButton_Stop.Click += new System.EventHandler(this.toolStripButton_Stop_Click); + // + // toolStripButton_AddFolder + // + this.toolStripButton_AddFolder.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton_AddFolder.Image"))); + this.toolStripButton_AddFolder.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButton_AddFolder.Name = "toolStripButton_AddFolder"; + this.toolStripButton_AddFolder.Size = new System.Drawing.Size(85, 22); + this.toolStripButton_AddFolder.Text = "Add Folder"; + this.toolStripButton_AddFolder.Click += new System.EventHandler(this.toolStripButton_AddFolder_Click); + // + // toolStripSeparator5 + // + this.toolStripSeparator5.Name = "toolStripSeparator5"; + this.toolStripSeparator5.Size = new System.Drawing.Size(6, 25); + // + // toolStripButton_RemoveFolder + // + this.toolStripButton_RemoveFolder.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton_RemoveFolder.Image"))); + this.toolStripButton_RemoveFolder.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButton_RemoveFolder.Name = "toolStripButton_RemoveFolder"; + this.toolStripButton_RemoveFolder.Size = new System.Drawing.Size(106, 22); + this.toolStripButton_RemoveFolder.Text = "Remove Folder"; + this.toolStripButton_RemoveFolder.Click += new System.EventHandler(this.toolStripButton_RemoveFolder_Click); + // + // toolStripSeparator4 + // + this.toolStripSeparator4.Name = "toolStripSeparator4"; + this.toolStripSeparator4.Size = new System.Drawing.Size(6, 25); + // + // toolStripButton_ModifyFolder + // + this.toolStripButton_ModifyFolder.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton_ModifyFolder.Image"))); + this.toolStripButton_ModifyFolder.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButton_ModifyFolder.Name = "toolStripButton_ModifyFolder"; + this.toolStripButton_ModifyFolder.Size = new System.Drawing.Size(110, 22); + this.toolStripButton_ModifyFolder.Text = "Modify Settings"; + this.toolStripButton_ModifyFolder.Click += new System.EventHandler(this.toolStripButton_ModifyFolder_Click); + // + // listView_AccessRights + // + this.listView_AccessRights.Dock = System.Windows.Forms.DockStyle.Fill; + this.listView_AccessRights.FullRowSelect = true; + this.listView_AccessRights.HideSelection = false; + this.listView_AccessRights.HoverSelection = true; + this.listView_AccessRights.Location = new System.Drawing.Point(0, 0); + this.listView_AccessRights.Margin = new System.Windows.Forms.Padding(2); + this.listView_AccessRights.MultiSelect = false; + this.listView_AccessRights.Name = "listView_AccessRights"; + this.listView_AccessRights.ShowItemToolTips = true; + this.listView_AccessRights.Size = new System.Drawing.Size(695, 106); + this.listView_AccessRights.TabIndex = 3; + this.listView_AccessRights.UseCompatibleStateImageBehavior = false; + this.listView_AccessRights.View = System.Windows.Forms.View.Details; + // + // tabControl1 + // + this.tabControl1.Controls.Add(this.tabPage_Folder); + this.tabControl1.Controls.Add(this.tabPage_Help); + this.tabControl1.Dock = System.Windows.Forms.DockStyle.Fill; + this.tabControl1.Location = new System.Drawing.Point(0, 0); + this.tabControl1.Margin = new System.Windows.Forms.Padding(2); + this.tabControl1.Name = "tabControl1"; + this.tabControl1.Padding = new System.Drawing.Point(6, 8); + this.tabControl1.SelectedIndex = 0; + this.tabControl1.Size = new System.Drawing.Size(707, 347); + this.tabControl1.TabIndex = 0; + // + // Form_FolderLocker + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(707, 347); + this.Controls.Add(this.tabControl1); + this.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Margin = new System.Windows.Forms.Padding(2); + this.Name = "Form_FolderLocker"; + this.Text = " EaseFilter Folder Locker"; + this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.Form_FolderLocker_FormClosed); + this.tabPage_Help.ResumeLayout(false); + this.tabPage_Help.PerformLayout(); + this.tabPage_Folder.ResumeLayout(false); + this.splitContainer1.Panel1.ResumeLayout(false); + this.splitContainer1.Panel1.PerformLayout(); + this.splitContainer1.Panel2.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit(); + this.splitContainer1.ResumeLayout(false); + this.statusStrip1.ResumeLayout(false); + this.statusStrip1.PerformLayout(); + this.toolStrip1.ResumeLayout(false); + this.toolStrip1.PerformLayout(); + this.tabControl1.ResumeLayout(false); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.ImageList imageList1; + private System.Windows.Forms.FolderBrowserDialog folderBrowserDialog1; + private System.Windows.Forms.TabPage tabPage_Help; + private System.Windows.Forms.LinkLabel linkLabel_SDK; + private System.Windows.Forms.LinkLabel linkLabel_Report; + private System.Windows.Forms.Label label_VersionInfo; + private System.Windows.Forms.TabPage tabPage_Folder; + private System.Windows.Forms.SplitContainer splitContainer1; + private System.Windows.Forms.StatusStrip statusStrip1; + private System.Windows.Forms.ToolStripStatusLabel toolStripStatusLabel1; + private System.Windows.Forms.ListView listView_LockFolders; + private System.Windows.Forms.ToolStrip toolStrip1; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator1; + private System.Windows.Forms.ToolStripButton toolStripButton_AddFolder; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator5; + private System.Windows.Forms.ToolStripButton toolStripButton_RemoveFolder; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator4; + private System.Windows.Forms.ToolStripButton toolStripButton_ModifyFolder; + private System.Windows.Forms.ListView listView_AccessRights; + private System.Windows.Forms.TabControl tabControl1; + private System.Windows.Forms.ToolStripButton toolStripButton_StartFilter; + private System.Windows.Forms.ToolStripButton toolStripButton_Stop; + } +} + diff --git a/Demo_Source_Code/CSharpDemo/FolderLocker/FormFolderLocker.cs b/Demo_Source_Code/CSharpDemo/FolderLocker/FormFolderLocker.cs new file mode 100644 index 0000000..1f61522 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FolderLocker/FormFolderLocker.cs @@ -0,0 +1,354 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.IO; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; +using System.Configuration; +using System.Diagnostics; +using System.Runtime.InteropServices; + +using EaseFilter.FilterControl; +using EaseFilter.CommonObjects; + +namespace EaseFilter.FolderLocker +{ + public partial class Form_FolderLocker: Form + { + + FilterControl.FilterControl filterControl = new FilterControl.FilterControl(); + + void SendSettingsToFilter() + { + try + { + filterControl.ClearFilters(); + + foreach (FileFilterRule filterRule in GlobalConfig.FilterRules.Values) + { + FileFilter fileFilter = filterRule.ToFileFilter(); + filterControl.AddFilter(fileFilter); + } + + + string lastError = string.Empty; + if (!filterControl.SendConfigSettingsToFilter(ref lastError)) + { + MessageBox.Show(lastError, "SendConfigSettingsToFilter", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + catch (Exception ex) + { + MessageBox.Show("SendConfigSettingsToFilter exception:" + ex.Message, "SendConfigSettingsToFilter", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + + } + + public Form_FolderLocker() + { + GlobalConfig.filterType = FilterAPI.FilterType.MONITOR_FILTER | FilterAPI.FilterType.CONTROL_FILTER | FilterAPI.FilterType.ENCRYPTION_FILTER + | FilterAPI.FilterType.PROCESS_FILTER | FilterAPI.FilterType.REGISTRY_FILTER; + + InitializeComponent(); + + StartPosition = FormStartPosition.CenterScreen; + + InitFolderLockerListView(); + InitAccessRightsListView(); + + DisplayVersion(); + + } + + private void DisplayVersion() + { + string version = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString(); + + try + { + string filterDllPath = Path.Combine(GlobalConfig.AssemblyPath, "FilterAPI.Dll"); + FileVersionInfo fileVersion = FileVersionInfo.GetVersionInfo(filterDllPath); + version = fileVersion.ProductVersion; + } + catch (Exception ex) + { + EventManager.WriteMessage(43, "LoadFilterAPI Dll", EventLevel.Error, "FilterAPI.dll can't be found." + ex.Message); + } + + this.Text += "(V" + version + ")"; + } + + private void InitFolderLockerListView() + { + //init ListView control + listView_LockFolders.Clear(); //clear control + //create column header for ListView + listView_LockFolders.Columns.Add("Folder Name", 160, System.Windows.Forms.HorizontalAlignment.Left); + listView_LockFolders.Columns.Add("Readable", 70, System.Windows.Forms.HorizontalAlignment.Left); + listView_LockFolders.Columns.Add("Writable", 70, System.Windows.Forms.HorizontalAlignment.Left); + listView_LockFolders.Columns.Add("Deletable", 70, System.Windows.Forms.HorizontalAlignment.Left); + listView_LockFolders.Columns.Add("Renamable", 70, System.Windows.Forms.HorizontalAlignment.Left); + listView_LockFolders.Columns.Add("Encrypted", 70, System.Windows.Forms.HorizontalAlignment.Left); + listView_LockFolders.Columns.Add("Copyable", 70, System.Windows.Forms.HorizontalAlignment.Left); + listView_LockFolders.Columns.Add("Visible", 70, System.Windows.Forms.HorizontalAlignment.Left); + + foreach (FileFilterRule filterRule in GlobalConfig.FilterRules.Values) + { + string folderName = filterRule.IncludeFileFilterMask.Replace("\\*",""); + uint accessFlags = filterRule.AccessFlag; + + if (!string.IsNullOrEmpty(GlobalConfig.ShareFolder) && folderName.StartsWith(GlobalConfig.ShareFolder)) + { + continue; + } + + string[] listEntry = new string[listView_LockFolders.Columns.Count]; + int index = 0; + listEntry[index++] = folderName; + listEntry[index++] = ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_READ_ACCESS) > 0).ToString(); + listEntry[index++] = ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_WRITE_ACCESS) > 0).ToString(); + listEntry[index++] = ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_FILE_DELETE) > 0).ToString(); + listEntry[index++] = ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_FILE_RENAME) > 0).ToString(); + listEntry[index++] = ((accessFlags & (uint)FilterAPI.AccessFlag.ENABLE_FILE_ENCRYPTION_RULE) >0 ).ToString(); + listEntry[index++] = ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_COPY_PROTECTED_FILES_OUT) > 0).ToString(); + listEntry[index++] = ((accessFlags & (uint)FilterAPI.AccessFlag.ENABLE_HIDE_FILES_IN_DIRECTORY_BROWSING) == 0).ToString(); + + ListViewItem item = new ListViewItem(listEntry, 0); + item.Tag = filterRule; + listView_LockFolders.Items.Add(item); + } + + if (listView_LockFolders.Items.Count > 0) + { + listView_LockFolders.Items[0].Selected = true; + listView_LockFolders.Select(); + } + + } + + private void InitAccessRightsListView() + { + //init ListView control + listView_AccessRights.Clear(); //clear control + //create column header for ListView + listView_AccessRights.Columns.Add("Type", 50, System.Windows.Forms.HorizontalAlignment.Left); + listView_AccessRights.Columns.Add("Name", 160, System.Windows.Forms.HorizontalAlignment.Left); + listView_AccessRights.Columns.Add("Readable", 70, System.Windows.Forms.HorizontalAlignment.Left); + listView_AccessRights.Columns.Add("Writable", 70, System.Windows.Forms.HorizontalAlignment.Left); + listView_AccessRights.Columns.Add("Deletable", 70, System.Windows.Forms.HorizontalAlignment.Left); + listView_AccessRights.Columns.Add("Renamable", 70, System.Windows.Forms.HorizontalAlignment.Left); + + if (listView_LockFolders.SelectedItems.Count == 1) + { + System.Windows.Forms.ListViewItem item = listView_LockFolders.SelectedItems[0]; + FileFilterRule filterRule = (FileFilterRule)item.Tag; + + string[] processRights = filterRule.ProcessNameRights.Split(new char[] { ';' }); + if (processRights.Length > 0) + { + foreach (string processRight in processRights) + { + if (processRight.Trim().Length > 0) + { + string processName = processRight.Substring(0, processRight.IndexOf('!')); + uint accessFlags = uint.Parse(processRight.Substring(processRight.IndexOf('!') + 1)); + + string[] listEntry = new string[listView_AccessRights.Columns.Count]; + int index = 0; + listEntry[index++] = "process"; + listEntry[index++] = processName; + listEntry[index++] = ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_READ_ACCESS) > 0).ToString(); + listEntry[index++] = ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_WRITE_ACCESS) > 0).ToString(); + listEntry[index++] = ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_FILE_DELETE) > 0).ToString(); + listEntry[index++] = ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_FILE_RENAME) > 0).ToString(); + + ListViewItem listItem = new ListViewItem(listEntry, 0); + item.Tag = filterRule; + listView_AccessRights.Items.Add(listItem); + + } + } + + } + + string[] userRights = filterRule.UserRights.Split(new char[] { ';' }); + if (userRights.Length > 0) + { + foreach (string userRight in userRights) + { + if (userRight.Trim().Length > 0) + { + string userName = userRight.Substring(0, userRight.IndexOf('!')); + uint accessFlags = uint.Parse(userRight.Substring(userRight.IndexOf('!') + 1)); + + string[] listEntry = new string[listView_AccessRights.Columns.Count]; + int index = 0; + listEntry[index++] = "user"; + listEntry[index++] = userName; + listEntry[index++] = ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_READ_ACCESS) > 0).ToString(); + listEntry[index++] = ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_WRITE_ACCESS) > 0).ToString(); + listEntry[index++] = ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_FILE_DELETE) > 0).ToString(); + listEntry[index++] = ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_FILE_RENAME) > 0).ToString(); + + ListViewItem listItem = new ListViewItem(listEntry, 0); + item.Tag = filterRule; + listView_AccessRights.Items.Add(listItem); + } + } + + } + + } + + } + + private void linkLabel_Report_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) + { + System.Diagnostics.Process.Start("https://easefilter.com/Company.htm"); + } + + private void linkLabel_SDK_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) + { + System.Diagnostics.Process.Start("https://easefilter.com/Forums_Files/FolderLocker.htm"); + } + + private void Form_FolderLocker_FormClosed(object sender, FormClosedEventArgs e) + { + GlobalConfig.Stop(); + filterControl.StopFilter(); + Application.Exit(); + } + + + private void toolStripButton_AddFolder_Click(object sender, EventArgs e) + { + FolderLockerSettigs folderLocker = new FolderLockerSettigs(null); + + if (folderLocker.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + FileFilterRule filterRule = folderLocker.filterRule; + + GlobalConfig.AddFileFilterRule(filterRule); + + GlobalConfig.SaveConfigSetting(); + + SendSettingsToFilter(); + + InitFolderLockerListView(); + } + } + + private void toolStripButton_RemoveFolder_Click(object sender, EventArgs e) + { + if (listView_LockFolders.SelectedItems.Count != 1) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("Please select one item to delete.", "Delete Folder", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + else + { + + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + + if (MessageBox.Show("Are you sure you want to remove a folder from locker?", "Delete Folder", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes) + { + System.Windows.Forms.ListViewItem item = listView_LockFolders.SelectedItems[0]; + GlobalConfig.RemoveFilterRule(((FileFilterRule)item.Tag).IncludeFileFilterMask); + + GlobalConfig.SaveConfigSetting(); + + SendSettingsToFilter(); + + InitFolderLockerListView(); + } + } + } + + private void toolStripButton_ModifyFolder_Click(object sender, EventArgs e) + { + if (listView_LockFolders.SelectedItems.Count != 1) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("Please select one item to delete.", "Delete Folder", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + System.Windows.Forms.ListViewItem item = listView_LockFolders.SelectedItems[0]; + FolderLockerSettigs folderLocker = new FolderLockerSettigs((FileFilterRule)item.Tag); + + if (folderLocker.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + FileFilterRule filterRule = folderLocker.filterRule; + + GlobalConfig.RemoveFilterRule(((FileFilterRule)item.Tag).IncludeFileFilterMask); + GlobalConfig.AddFileFilterRule(filterRule); + GlobalConfig.SaveConfigSetting(); + + SendSettingsToFilter(); + + InitFolderLockerListView(); + } + + + InitFolderLockerListView(); + } + + private void listView_LockFolders_SelectedIndexChanged(object sender, EventArgs e) + { + InitAccessRightsListView(); + } + + private void toolStripButton_StartFilter_Click(object sender, EventArgs e) + { + //Purchase a license key with the link: http://www.easefilter.com/Order.htm + //Email us to request a trial key: info@easefilter.com //free email is not accepted. + string licenseKey = GlobalConfig.LicenseKey; + + string lastError = string.Empty; + bool ret = filterControl.StartFilter(GlobalConfig.filterType, GlobalConfig.FilterConnectionThreads, GlobalConfig.ConnectionTimeOut, licenseKey, ref lastError); + if (!ret) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("Start filter failed." + lastError, "StartFilter", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + SendSettingsToFilter(); + + toolStripButton_StartFilter.Enabled = false; + toolStripButton_Stop.Enabled = true; + } + + private void toolStripButton_Stop_Click(object sender, EventArgs e) + { + GlobalConfig.Stop(); + filterControl.StopFilter(); + + toolStripButton_StartFilter.Enabled = true; + toolStripButton_Stop.Enabled = false; + } + + + } +} diff --git a/Demo_Source_Code/CSharpDemo/FolderLocker/FormFolderLocker.resx b/Demo_Source_Code/CSharpDemo/FolderLocker/FormFolderLocker.resx new file mode 100644 index 0000000..d9d913f --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FolderLocker/FormFolderLocker.resx @@ -0,0 +1,568 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 279, 17 + + + + AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w + LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 + ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAACQ + CwAAAk1TRnQBSQFMAwEBAAFYAQEBWAEBASABAAEgAQAE/wEJAQAI/wFCAU0BNgEEBgABNgEEAgABKAMA + AYADAAEgAwABAQEAAQgGAAEQGAABgAIAAYADAAKAAQABgAMAAYABAAGAAQACgAIAA8ABAAHAAdwBwAEA + AfABygGmAQABMwUAATMBAAEzAQABMwEAAjMCAAMWAQADHAEAAyIBAAMpAQADVQEAA00BAANCAQADOQEA + AYABfAH/AQACUAH/AQABkwEAAdYBAAH/AewBzAEAAcYB1gHvAQAB1gLnAQABkAGpAa0CAAH/ATMDAAFm + AwABmQMAAcwCAAEzAwACMwIAATMBZgIAATMBmQIAATMBzAIAATMB/wIAAWYDAAFmATMCAAJmAgABZgGZ + AgABZgHMAgABZgH/AgABmQMAAZkBMwIAAZkBZgIAApkCAAGZAcwCAAGZAf8CAAHMAwABzAEzAgABzAFm + AgABzAGZAgACzAIAAcwB/wIAAf8BZgIAAf8BmQIAAf8BzAEAATMB/wIAAf8BAAEzAQABMwEAAWYBAAEz + AQABmQEAATMBAAHMAQABMwEAAf8BAAH/ATMCAAMzAQACMwFmAQACMwGZAQACMwHMAQACMwH/AQABMwFm + AgABMwFmATMBAAEzAmYBAAEzAWYBmQEAATMBZgHMAQABMwFmAf8BAAEzAZkCAAEzAZkBMwEAATMBmQFm + AQABMwKZAQABMwGZAcwBAAEzAZkB/wEAATMBzAIAATMBzAEzAQABMwHMAWYBAAEzAcwBmQEAATMCzAEA + ATMBzAH/AQABMwH/ATMBAAEzAf8BZgEAATMB/wGZAQABMwH/AcwBAAEzAv8BAAFmAwABZgEAATMBAAFm + AQABZgEAAWYBAAGZAQABZgEAAcwBAAFmAQAB/wEAAWYBMwIAAWYCMwEAAWYBMwFmAQABZgEzAZkBAAFm + ATMBzAEAAWYBMwH/AQACZgIAAmYBMwEAA2YBAAJmAZkBAAJmAcwBAAFmAZkCAAFmAZkBMwEAAWYBmQFm + AQABZgKZAQABZgGZAcwBAAFmAZkB/wEAAWYBzAIAAWYBzAEzAQABZgHMAZkBAAFmAswBAAFmAcwB/wEA + AWYB/wIAAWYB/wEzAQABZgH/AZkBAAFmAf8BzAEAAcwBAAH/AQAB/wEAAcwBAAKZAgABmQEzAZkBAAGZ + AQABmQEAAZkBAAHMAQABmQMAAZkCMwEAAZkBAAFmAQABmQEzAcwBAAGZAQAB/wEAAZkBZgIAAZkBZgEz + AQABmQEzAWYBAAGZAWYBmQEAAZkBZgHMAQABmQEzAf8BAAKZATMBAAKZAWYBAAOZAQACmQHMAQACmQH/ + AQABmQHMAgABmQHMATMBAAFmAcwBZgEAAZkBzAGZAQABmQLMAQABmQHMAf8BAAGZAf8CAAGZAf8BMwEA + AZkBzAFmAQABmQH/AZkBAAGZAf8BzAEAAZkC/wEAAcwDAAGZAQABMwEAAcwBAAFmAQABzAEAAZkBAAHM + AQABzAEAAZkBMwIAAcwCMwEAAcwBMwFmAQABzAEzAZkBAAHMATMBzAEAAcwBMwH/AQABzAFmAgABzAFm + ATMBAAGZAmYBAAHMAWYBmQEAAcwBZgHMAQABmQFmAf8BAAHMAZkCAAHMAZkBMwEAAcwBmQFmAQABzAKZ + AQABzAGZAcwBAAHMAZkB/wEAAswCAALMATMBAALMAWYBAALMAZkBAAPMAQACzAH/AQABzAH/AgABzAH/ + ATMBAAGZAf8BZgEAAcwB/wGZAQABzAH/AcwBAAHMAv8BAAHMAQABMwEAAf8BAAFmAQAB/wEAAZkBAAHM + ATMCAAH/AjMBAAH/ATMBZgEAAf8BMwGZAQAB/wEzAcwBAAH/ATMB/wEAAf8BZgIAAf8BZgEzAQABzAJm + AQAB/wFmAZkBAAH/AWYBzAEAAcwBZgH/AQAB/wGZAgAB/wGZATMBAAH/AZkBZgEAAf8CmQEAAf8BmQHM + AQAB/wGZAf8BAAH/AcwCAAH/AcwBMwEAAf8BzAFmAQAB/wHMAZkBAAH/AswBAAH/AcwB/wEAAv8BMwEA + AcwB/wFmAQAC/wGZAQAC/wHMAQACZgH/AQABZgH/AWYBAAFmAv8BAAH/AmYBAAH/AWYB/wEAAv8BZgEA + ASEBAAGlAQADXwEAA3cBAAOGAQADlgEAA8sBAAOyAQAD1wEAA90BAAPjAQAD6gEAA/EBAAP4AQAB8AH7 + Af8BAAGkAqABAAOAAwAB/wIAAf8DAAL/AQAB/wMAAf8BAAH/AQAC/wIAA/8IAAP/CAAD/wT0A/9pAAL/ + AvQE/wQAAv8B8wHwAQcC7wEHAfAB8wL/aAAB/wHzAgcBvAHyAfQF/wH0AbwB7QFPAkkBTwHsAe0B9wHw + AfQB/2cAAfMCUQEcAfcBkgHvAQcB8QHzAfQB8wGYBAIDSAEnAewB7QG8AfQB/2UAAf8BmQExASoBMQIq + AXQBHAGSAfcB7wFyAQIFLQECA0gBcgHtAfAC/2QAAf8BUgFZASoDOAIxASoBHAFyAy0BVQF4ATQDLQEC + AkgB7AH3AfMB/2QAAfQBKgFeASoEWQE4AVkBeQECAS4BLQE0AfMB/wEbATQDLQECAUgBJwHtAfAB/2MA + Af8BGgExAeUBKgVZAXoBVgFPAi4B8QL0Af8BGwE0Ay0CSAHsAQcB9GMAAf8BeQFYAeUBKgVZAaABTwFW + AS0B8AH0BP8BGwE0Ai0BAgFIAU8B7wH0YwAB/wEqAuUBKwVZAaABLgGXAU8C/wGYAS4BCAL/ARsBNAIt + AUgBAgH3AfRiAAH/ARsBMQLlATEBegRZAaABLgF4AS4ClwE0AVUBLgEIAv8BGwE0AS0BSAECAfcB9GIA + Af8BmQFYAqABMQF6AeUCegFZAaABTwF4AVYCVQFWAlUBLgEIAv8BGwE0AQIBTwH3AfRiAAH/ASoDoAEx + AXoE5QGgAXgBVgF4BFYCVQEuAQgC/wGYAQIBUAH3AfRhAAH/ARsBMQOgATEBegXlAZ8BLgGYBVYCVQEu + AZgBCAFVAQIBHAH3AfRhAAH/AZkBeQOgATEBmgXlAaABeAFVAZgEVgNVAS4BLQECAZcBdAH3AfRhAAH/ + AUsDoAHDATEDoATlAaABUAFVAZgBeAJWA1UBNAEtAVABwwEqAfcB9GAAAf8BGwExAsMBoAHDATEGoALl + AcMBeAEuAVYCeAGXAVYBTwEtAZcCwwEqAfcB9GAAAf8BmQF5BMMBMQigAeUBoAEaAXgETwGXAZkDwwEq + AfcB9GAAAf8BSwXDATEBwwygAsMDoAPDASoB9wH0YAAB8gExAfYEwwExAcMKoAXlAXoEwwEqAfcB9GAA + ApkB/wH2A8MBMQLDC6AD5QGaBMMBKgH3AfRgAAFSATECUgJ5AaABMQTDCqAB5QF6BcMBKgH3AfRgAAH/ + AfQBGwIaAZkBeQExARoBmgF6A5oJoAGaBcMBKgH3AfRlAAL/AVIC9gTDAqADmgJ6AZoBegGgBcMBKgH3 + AfRnAAFSAvYFwwX2CcMBKgH3AfRnAAFSAfYB/wj2BMMB9gXDAfYBKgH3AfRnAAFYAXkCmQGaAxoBwwL2 + A/8I9gEqAfcB9GcAARsBGgOZA3kBWAJSATEBKgGZCPYBKgEHAfRpAAr/ARsBUgH/BvYBGgFRAfAB/3MA + Af8BMQf/AXQBHAHzAf90AAF5ATEDKwQqAfMC/3UACf9iAAFCAU0BPgcAAT4DAAEoAwABgAMAASADAAEB + AQABAQYAAQIWAAP/AQAB/gE/AcABDwwAAfgBBwGAAQcMAAH4AgABAwwAAfgCAAEBDAAB8A8AAfAPAAHw + DwAB4A8AAeAPAAHgDwABwA8AAcAPAAHADwABgA8AAYAPAAGAfwAB+A8AAf4PAAH+DwAB/g8AAf4PAAH/ + AYAOAAL/AeANAAL/AfANAAL/AfgBAwwACw== + + + + 970, 17 + + + 494, 17 + + + 389, 17 + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAImSURBVDhPtdJfSNNRFAfwo7nC/Va/KN9iL0aKWrq2odUo + CyMqwayGFSrOzP/bcJt/aE3XwtnSsUx9GkS9VBAFkelyirEUpzZt6LApRC9JSU/SZC/ltyEXhiDmQ30e + zz1fzuHeS/9OCWmTG5OWqZx8VEkKVt06Xrt7aebbFJ59fATJvUO/qYKcpKM97PjvEgwJyy8DT+EYaUX7 + qAllL5QQ6AXfqYmKWMvm4vXxy4+ne9AyVAfd2xLUupSodOci3SxeJT0N0h06wFo3JjQIf/ZMWtHgvo6q + /nwU9Z7E5deHcbE/FXlvksFbheHINi30gHawyHpcExeye29C676CUtdpFPTJkNeXBKU7BYWegyiflOHM + q/0gE30iM0lZLIozciHbeB1qBi+geECBSwMpuDqchuKRdJRNSFA5JYVmNgsNQQW2mWPnWCyKa+ZCbRNq + VA+fR/FQJq69S0OpNwMVPhlq/JnQBo6hfj4bzV9yEGOODbBYFGfmQnd91aj1nIPKI4dqTIKqaTnUM0dQ + H8yG5etZKN9nIMYaM0ftJGGxKFGbaKXDr0bdWC5ueLPWJmtmj8L4OQeGhVPY91C0Qja6Rc9pO4usx9v4 + cGdAh8YP+dD4TqxNNkXWPd6ZuEod5KInlMhaN8Y7+LAzaITFXwjLfOQix6WIc8QtRv5jAWvZ3E67YKl3 + sQvdC2qk3hb/ovvUFXnzXex4C1pJJXbu/UF2GqVukrPq/0b0Bx5i9kMRCE3+AAAAAElFTkSuQmCC + + + + + iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAARRSURBVEhLxVRbTFRXFD0woIA2owgij2JVFFF81Ee1VQoy + MMyAiKLiCwqIbyxG248+vvXHxPpV/TOxEeOTqKmmESVqRIPia2R8R9SqLQItA3SiqMu159yRcRIbTJp0 + Jzvnnjtz1lpn7b2v+t/i9XAV2z5aNfw1LtjdnUHulrHMMcHupmQTM8j9e4JydMSraONYz8IAv/WyZDzw + 9ZfAms+BVVOBZZOApRMAeV+cDBQl48XMeDwYopw9JhFwVxLBiz8F1qZo4BWfAWUTNfBXY4HC0cCiJGDB + CGBhIp7b43A3tgckAt5K8K4SqhTl5SQoT+UNppOEtygladEYYIkQjNQEBcOA+cPgtsagIU7d6Ih4D4kH + PMEPfF06MwOosOj9ssmaYPEoKidBwXBgHgnyhwJzB+OfjChciVHOJn8SAW8h+AuxpYJAq7/oJvjWBnxj + J2kaCWiVh0DsSaTyBAITfM4nQF48MDsOnTMicDlSORt9Sf4coRq6iqWgtEI8X8lcM02DbrAC65liVRlv + UMjieu2hNcgfQuDBwKyPgZmxQG40OlPDcS5COQx4pZrYdqigLSunsJBUKJ0iRV3KG5XyuVhUCygtyYsj + AdXnEkyebQOA9I+AtD6ANQKwDyJRFC6aTW4DXqmnySQoZxGlQ6q24W3s+QnoaDM2jNqjwOkqY8MoJHFb + s7Fh/FgAZIQD2ZE470vwKIkEq2nLIl77yX3gj0Zg71agercmlXDUasUSNfv1uu174NEd4NpZ4CnPHfiZ + N+Ft7ANxzhzQTfAwMciN5RwisaFysz787LHuGhsVSVw4Dkw36eeaA3rdToLGW4CrVe8rt2gCWyRO+xJc + FoIyer2E7Scds3Mj8KqLJE94IEQfrjsBTDMITu7Tq9zgwW3g72fApuVAVqS2KCscp8yBPgQJtKiUXTSf + HXHzorap9lcNkhKs1/oaPhsE9Sf1unW9tubxPWBKAIvMgguBtT+q3iEYanKjhO1XwBp8NxtopvJOl7Yg + q78GOLKDh/tR9Q/8rR24c42/EbCO1knxU9lFmdxb+P/Mfv4EtKiI4y+9PY+DwzaTTpDBwVwOEYuGHL7L + Y6/b+X4GfbYwxZK0vgY4lQu4xcwb+BHUD1KOzmxOIj9cnm+LjL9MqAxRPgnmcJBkUmWYpP9zYiiA/W4n + qZCIcrHGwhuSoHVSGPaGqCsGvFIy1nUc7w4bFXum0xh/mVABFuW5/E0mNSdag9v8wNM1eMtEgvdWjkNK + RRnwOoTkzADlbM+kOrHlrWIvsKgmuKi20TJ/8AyCU/meXspR7Q/ujcYwFV1tVjdcFioU/98B9lEtnwRv + Qb3KCb67l7r+XnBvOEly3KycbWkE4YcLdqYHmKqtvn4bBWU2TwjDrsB/Ue4fQnIslCQpBMoleA6Bs0kg + HSSTLa3LTpFspucfBO6NYyQ5GKKu/hZqch31ZIDrSGig6zDzELPSyF8C1aXKDwX/70KpN929HhkRWgNw + AAAAAElFTkSuQmCC + + + + + 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 + AAAAAElFTkSuQmCC + + + + + AAABAAEAQEAAAAEAIAAoQgAAFgAAACgAAABAAAAAgAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOTX0YDk19H/5NfR/+TX0f/k19H/5NfR/+TX + 0f/k19H/5NfR/+TX0f/k19H/5NfR/+TX0f/k19H/5NfR/+TX0f/k19H/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADRydP/RGLg/0Ri + 4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/+TX + 0f8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AADk19FARGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri + 4P9EYuD/RGLg/0Ri4P/k19H/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA5NfRQERi4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri + 4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/5NfR/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQjs4/0I7OP9COzj/Qjs4/0I7OP9COzj/Qjs4/0I7 + OP9COzj/Qjs4/0I7OP9COzj/Qjs4/0I7OP9COzj/Qjs4/0I7OP9COzj/Qjs4/0I7OP9COzj/Qjs4/0I7 + OP9COzj/Qjs4/0I7OP9COzj/Qjs4/0I7OP9COzj/Qjs4/2tiXv9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri + 4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/+TX0f8AAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEI7OP9fVVH/X1VR/19V + Uf9fVVH/X1VR/19VUf9fVVH/X1VR/19VUf9fVVH/X1VR/19VUf9fVVH/X1VR/19VUf9fVVH/X1VR/19V + Uf9fVVH/X1VR/19VUf9fVVH/X1VR/19VUf9fVVH/X1VR/19VUf9fVVH/X1VR/19VUf+AdnH/RGLg/0Ri + 4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri + 4P/k19H/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AABCOzj/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/iHx4/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri + 4P9EYuD/RGLg/0Ri4P9EYuD/5NfR/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAQjs4/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/4h8eP9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri + 4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/+TX0f8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEI7OP9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv+IfHj/RGLg/0Ri4P9EYuD/RGLg/0Ri + 4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P/k19H/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABCOzj/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/iHx4/0Ri + 4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri + 4P9EYuD/5NfR/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAQjs4/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/4h8eP9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri + 4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/+TX0f8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAEI7OP9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv+IfHj/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri + 4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P/k19H/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABCOzj/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/+TX0f+8utX/RGLg/0Ri + 4P9EYuD/vLrV/7y61f+8utX/vLrV/7y61f+8utX/vLrV/7y61f9EYuD/RGLg/0Ri4P/k19H/5NfR/wAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQjs4/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/5NfR/0Ri4P9EYuD/RGLg/+TX0f9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv/k19H/RGLg/0Ri + 4P9EYuD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAEI7OP9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/+TX0f9EYuD/RGLg/0Ri4P/k19H/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/5NfR/0Ri4P9EYuD/RGLg/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABCOzj/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv/k19H/RGLg/0Ri4P9EYuD/5NfR/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/+TX0f9EYuD/RGLg/0Ri4P8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQjs4/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/5NfR/0Ri + 4P9EYuD/RGLg/+TX0f9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv/k19H/RGLg/0Ri4P9EYuD/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEI7 + OP9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/+TX0f9EYuD/RGLg/0Ri4P/k19H/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/5NfR/0Ri + 4P9EYuD/RGLg/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAABCOzj/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv/k19H/RGLg/0Ri4P9EYuD/5NfR/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/1hx3v9EYuD/RGLg/0Ri4P8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQjs4/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/3dDK/0Ri4P9EYuD/RGLg/0Ri + 4P+XjIf/aV5a/2leWv9pXlr/aV5a/+TX0f9EYuD/RGLg/0Ri4P/k19H/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEI7OP9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv/k19H/RGLg/0Ri4P9EYuD/5NfR/9XIw/9pXlr/aV5a/+TX0f9EYuD/RGLg/0Ri4P9EYuD/5NfR/wAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AABCOzj/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/5NfR/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/vLrV/2x/3P9EYuD/RGLg/0Ri + 4P9EYuD/Tmnf/+TX0WAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAQjs4/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv/k19H/RGLg/0Ri4P9EYuD/RGLg/0Ri + 4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/+TX0f8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEI7OP9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/+TX + 0f9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/Tmnf/+TX0f8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABCOzj/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/5NfR/+TX0f+Kldn/RGLg/0Ri4P/k19H/5NfR/5eMh/8AAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAQjs4/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAEI7OP9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABCOzj/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQjs4/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAEI7OP9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABCOzj/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQjs4/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEI7 + OP+Ddm7/g3Zu/4N2bv+Ddm7/g3Zu/4N2bv+Ddm7/g3Zu/4N2bv+Ddm7/g3Zu/4N2bv+Ddm7/g3Zu/4N2 + bv+Ddm7/g3Zu/4N2bv+Ddm7/g3Zu/2tgW/9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/wAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAABCOzj/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19U + UP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP+Ddm7/bmNe/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQjs4/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19U + UP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/4N2 + bv9uY17/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEI7OP9fVFD/X1RQ/19U + UP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19U + UP9fVFD/X1RQ/19UUP9fVFD/g3Zu/4N2bv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9zZ2L/dmpk/wAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AABCOzj/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19U + UP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/T0ZD/0I7OP9COzj/Qjs4/0I7OP9COzj/Qjs4/0I7 + OP9COzj/Qjs4/0I7OP9COzj/Qjs4/0I7OP9COzj/Qjs4/0I7OP9COzj/Qjs4/0I7OP9COzj/Qjs4/wAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAQjs4/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19U + UP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/wAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEI7OP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19U + UP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19U + UP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABCOzj/X1RQ/19U + UP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19U + UP9fVFD/X1RQ/19UUP9fVFD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAQjs4/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19U + UP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/Qjs4/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABCOzigQjs4/0I7OP9COzj/Qjs4/0I7OP9COzj/Qjs4/0I7 + OP9COzj/Qjs4/0I7OP9COzj/Qjs4/0I7OP9COzj/Qjs4/0I7OP9COzj/Qjs4/wAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA//////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////+AAD///////4AAH///////AAAf/// + ///8AAB//gAAAAAAAH/+AAAAAAAAf/4AAAAAAAB//gAAAAAAAH/+AAAAAAAAf/4AAAAAAAB//gAAAAAA + AH/+AAAAAAAAf/4AAAAAAAB//gAAAAAAAf/+AAAAAAAB//4AAAAAAAH//gAAAAAAAf/+AAAAAAAB//4A + AAAAAAH//gAAAAAAAf/+AAAAAAAB//4AAAAAAAH//gAAAAAAA//+AAAAAAAH//4AAAAAAA///gAAAAAA + D//+AAAAAAAP//4AAAAAAA///gAAAAAAD//+AAAAAAAP//4AAAAAAA///gAAAAAAD//+AAAAAAAP//4A + AAAAAA///gAAAAAAD//+AAAAAAAP//4AAAAAAB///gAAB//////+AAAH//////4AAAf//////gAAB/// + ////AAAP//////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////8= + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/FolderLocker/Lock Folder.ico b/Demo_Source_Code/CSharpDemo/FolderLocker/Lock Folder.ico new file mode 100644 index 0000000..ac2a8d1 Binary files /dev/null and b/Demo_Source_Code/CSharpDemo/FolderLocker/Lock Folder.ico differ diff --git a/Demo_Source_Code/CSharpDemo/FolderLocker/Program.cs b/Demo_Source_Code/CSharpDemo/FolderLocker/Program.cs new file mode 100644 index 0000000..078a4a7 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FolderLocker/Program.cs @@ -0,0 +1,39 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Windows.Forms; + +namespace EaseFilter.FolderLocker +{ + static class Program + { + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main() + { + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + Application.Run(new Form_FolderLocker()); + + } + } +} diff --git a/Demo_Source_Code/CSharpDemo/FolderLocker/Properties/AssemblyInfo.cs b/Demo_Source_Code/CSharpDemo/FolderLocker/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..4f52dd3 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FolderLocker/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("EaseFilter Folder Locker")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("EaseFilter Technologies")] +[assembly: AssemblyProduct("AutoFileCryptTool")] +[assembly: AssemblyCopyright("Copyright © 2017 EaseFilter Technologies")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("1826df94-fbbb-4180-ad6f-c1ab49726eca")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("5.2.3.2001")] +//[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Demo_Source_Code/CSharpDemo/FolderLocker/Properties/Resources.Designer.cs b/Demo_Source_Code/CSharpDemo/FolderLocker/Properties/Resources.Designer.cs new file mode 100644 index 0000000..15964da --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FolderLocker/Properties/Resources.Designer.cs @@ -0,0 +1,63 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace EaseFilter.FolderLocker.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // 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", "16.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + 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() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [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("EaseFilter.FolderLocker.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + } +} diff --git a/Demo_Source_Code/CSharpDemo/FolderLocker/Properties/Resources.resx b/Demo_Source_Code/CSharpDemo/FolderLocker/Properties/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FolderLocker/Properties/Resources.resx @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/FolderLocker/Properties/Settings.Designer.cs b/Demo_Source_Code/CSharpDemo/FolderLocker/Properties/Settings.Designer.cs new file mode 100644 index 0000000..4175046 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FolderLocker/Properties/Settings.Designer.cs @@ -0,0 +1,26 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace EaseFilter.FolderLocker.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.10.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default { + get { + return defaultInstance; + } + } + } +} diff --git a/Demo_Source_Code/CSharpDemo/FolderLocker/Properties/Settings.settings b/Demo_Source_Code/CSharpDemo/FolderLocker/Properties/Settings.settings new file mode 100644 index 0000000..3964565 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FolderLocker/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + diff --git a/Demo_Source_Code/CSharpDemo/FolderLocker/Service References/ServiceReference1/Reference.cs b/Demo_Source_Code/CSharpDemo/FolderLocker/Service References/ServiceReference1/Reference.cs new file mode 100644 index 0000000..f3709a1 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FolderLocker/Service References/ServiceReference1/Reference.cs @@ -0,0 +1,1151 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace EaseFilter.FolderLocker.ServiceReference1 { + + + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ServiceModel.ServiceContractAttribute(ConfigurationName="ServiceReference1.ServiceSoap")] + public interface ServiceSoap { + + // CODEGEN: Generating message contract since element name accountName from namespace http://tempuri.org/ is not marked nillable + [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/SignInAccount", ReplyAction="*")] + EaseFilter.FolderLocker.ServiceReference1.SignInAccountResponse SignInAccount(EaseFilter.FolderLocker.ServiceReference1.SignInAccountRequest request); + + // CODEGEN: Generating message contract since element name accountName from namespace http://tempuri.org/ is not marked nillable + [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/SignUpAccount", ReplyAction="*")] + EaseFilter.FolderLocker.ServiceReference1.SignUpAccountResponse SignUpAccount(EaseFilter.FolderLocker.ServiceReference1.SignUpAccountRequest request); + + // CODEGEN: Generating message contract since element name accountName from namespace http://tempuri.org/ is not marked nillable + [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/GetFileList", ReplyAction="*")] + EaseFilter.FolderLocker.ServiceReference1.GetFileListResponse GetFileList(EaseFilter.FolderLocker.ServiceReference1.GetFileListRequest request); + + // CODEGEN: Generating message contract since element name accountName from namespace http://tempuri.org/ is not marked nillable + [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/AddShareFile", ReplyAction="*")] + EaseFilter.FolderLocker.ServiceReference1.AddShareFileResponse AddShareFile(EaseFilter.FolderLocker.ServiceReference1.AddShareFileRequest request); + + // CODEGEN: Generating message contract since element name accountName from namespace http://tempuri.org/ is not marked nillable + [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/DeleteSharedFile", ReplyAction="*")] + EaseFilter.FolderLocker.ServiceReference1.DeleteSharedFileResponse DeleteSharedFile(EaseFilter.FolderLocker.ServiceReference1.DeleteSharedFileRequest request); + + // CODEGEN: Generating message contract since element name accountName from namespace http://tempuri.org/ is not marked nillable + [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/GetSharedFileDRInfo", ReplyAction="*")] + EaseFilter.FolderLocker.ServiceReference1.GetSharedFileDRInfoResponse GetSharedFileDRInfo(EaseFilter.FolderLocker.ServiceReference1.GetSharedFileDRInfoRequest request); + + // CODEGEN: Generating message contract since element name accountName from namespace http://tempuri.org/ is not marked nillable + [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/ModifySharedFileDRInfo", ReplyAction="*")] + EaseFilter.FolderLocker.ServiceReference1.ModifySharedFileDRInfoResponse ModifySharedFileDRInfo(EaseFilter.FolderLocker.ServiceReference1.ModifySharedFileDRInfoRequest request); + + // CODEGEN: Generating message contract since element name accountName from namespace http://tempuri.org/ is not marked nillable + [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/GetAccessLog", ReplyAction="*")] + EaseFilter.FolderLocker.ServiceReference1.GetAccessLogResponse GetAccessLog(EaseFilter.FolderLocker.ServiceReference1.GetAccessLogRequest request); + + // CODEGEN: Generating message contract since element name accountName from namespace http://tempuri.org/ is not marked nillable + [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/ClearAccessLog", ReplyAction="*")] + EaseFilter.FolderLocker.ServiceReference1.ClearAccessLogResponse ClearAccessLog(EaseFilter.FolderLocker.ServiceReference1.ClearAccessLogRequest request); + + // CODEGEN: Generating message contract since element name userInfoStr from namespace http://tempuri.org/ is not marked nillable + [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/GetSharedFilePermission", ReplyAction="*")] + EaseFilter.FolderLocker.ServiceReference1.GetSharedFilePermissionResponse GetSharedFilePermission(EaseFilter.FolderLocker.ServiceReference1.GetSharedFilePermissionRequest request); + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.ServiceModel.MessageContractAttribute(IsWrapped=false)] + public partial class SignInAccountRequest { + + [System.ServiceModel.MessageBodyMemberAttribute(Name="SignInAccount", Namespace="http://tempuri.org/", Order=0)] + public EaseFilter.FolderLocker.ServiceReference1.SignInAccountRequestBody Body; + + public SignInAccountRequest() { + } + + public SignInAccountRequest(EaseFilter.FolderLocker.ServiceReference1.SignInAccountRequestBody Body) { + this.Body = Body; + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.Runtime.Serialization.DataContractAttribute(Namespace="http://tempuri.org/")] + public partial class SignInAccountRequestBody { + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=0)] + public string accountName; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=1)] + public string password; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=2)] + public string lastError; + + public SignInAccountRequestBody() { + } + + public SignInAccountRequestBody(string accountName, string password, string lastError) { + this.accountName = accountName; + this.password = password; + this.lastError = lastError; + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.ServiceModel.MessageContractAttribute(IsWrapped=false)] + public partial class SignInAccountResponse { + + [System.ServiceModel.MessageBodyMemberAttribute(Name="SignInAccountResponse", Namespace="http://tempuri.org/", Order=0)] + public EaseFilter.FolderLocker.ServiceReference1.SignInAccountResponseBody Body; + + public SignInAccountResponse() { + } + + public SignInAccountResponse(EaseFilter.FolderLocker.ServiceReference1.SignInAccountResponseBody Body) { + this.Body = Body; + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.Runtime.Serialization.DataContractAttribute(Namespace="http://tempuri.org/")] + public partial class SignInAccountResponseBody { + + [System.Runtime.Serialization.DataMemberAttribute(Order=0)] + public bool SignInAccountResult; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=1)] + public string lastError; + + public SignInAccountResponseBody() { + } + + public SignInAccountResponseBody(bool SignInAccountResult, string lastError) { + this.SignInAccountResult = SignInAccountResult; + this.lastError = lastError; + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.ServiceModel.MessageContractAttribute(IsWrapped=false)] + public partial class SignUpAccountRequest { + + [System.ServiceModel.MessageBodyMemberAttribute(Name="SignUpAccount", Namespace="http://tempuri.org/", Order=0)] + public EaseFilter.FolderLocker.ServiceReference1.SignUpAccountRequestBody Body; + + public SignUpAccountRequest() { + } + + public SignUpAccountRequest(EaseFilter.FolderLocker.ServiceReference1.SignUpAccountRequestBody Body) { + this.Body = Body; + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.Runtime.Serialization.DataContractAttribute(Namespace="http://tempuri.org/")] + public partial class SignUpAccountRequestBody { + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=0)] + public string accountName; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=1)] + public string password; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=2)] + public string lastError; + + public SignUpAccountRequestBody() { + } + + public SignUpAccountRequestBody(string accountName, string password, string lastError) { + this.accountName = accountName; + this.password = password; + this.lastError = lastError; + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.ServiceModel.MessageContractAttribute(IsWrapped=false)] + public partial class SignUpAccountResponse { + + [System.ServiceModel.MessageBodyMemberAttribute(Name="SignUpAccountResponse", Namespace="http://tempuri.org/", Order=0)] + public EaseFilter.FolderLocker.ServiceReference1.SignUpAccountResponseBody Body; + + public SignUpAccountResponse() { + } + + public SignUpAccountResponse(EaseFilter.FolderLocker.ServiceReference1.SignUpAccountResponseBody Body) { + this.Body = Body; + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.Runtime.Serialization.DataContractAttribute(Namespace="http://tempuri.org/")] + public partial class SignUpAccountResponseBody { + + [System.Runtime.Serialization.DataMemberAttribute(Order=0)] + public bool SignUpAccountResult; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=1)] + public string lastError; + + public SignUpAccountResponseBody() { + } + + public SignUpAccountResponseBody(bool SignUpAccountResult, string lastError) { + this.SignUpAccountResult = SignUpAccountResult; + this.lastError = lastError; + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.ServiceModel.MessageContractAttribute(IsWrapped=false)] + public partial class GetFileListRequest { + + [System.ServiceModel.MessageBodyMemberAttribute(Name="GetFileList", Namespace="http://tempuri.org/", Order=0)] + public EaseFilter.FolderLocker.ServiceReference1.GetFileListRequestBody Body; + + public GetFileListRequest() { + } + + public GetFileListRequest(EaseFilter.FolderLocker.ServiceReference1.GetFileListRequestBody Body) { + this.Body = Body; + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.Runtime.Serialization.DataContractAttribute(Namespace="http://tempuri.org/")] + public partial class GetFileListRequestBody { + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=0)] + public string accountName; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=1)] + public string password; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=2)] + public string fileList; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=3)] + public string lastError; + + public GetFileListRequestBody() { + } + + public GetFileListRequestBody(string accountName, string password, string fileList, string lastError) { + this.accountName = accountName; + this.password = password; + this.fileList = fileList; + this.lastError = lastError; + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.ServiceModel.MessageContractAttribute(IsWrapped=false)] + public partial class GetFileListResponse { + + [System.ServiceModel.MessageBodyMemberAttribute(Name="GetFileListResponse", Namespace="http://tempuri.org/", Order=0)] + public EaseFilter.FolderLocker.ServiceReference1.GetFileListResponseBody Body; + + public GetFileListResponse() { + } + + public GetFileListResponse(EaseFilter.FolderLocker.ServiceReference1.GetFileListResponseBody Body) { + this.Body = Body; + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.Runtime.Serialization.DataContractAttribute(Namespace="http://tempuri.org/")] + public partial class GetFileListResponseBody { + + [System.Runtime.Serialization.DataMemberAttribute(Order=0)] + public bool GetFileListResult; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=1)] + public string fileList; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=2)] + public string lastError; + + public GetFileListResponseBody() { + } + + public GetFileListResponseBody(bool GetFileListResult, string fileList, string lastError) { + this.GetFileListResult = GetFileListResult; + this.fileList = fileList; + this.lastError = lastError; + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.ServiceModel.MessageContractAttribute(IsWrapped=false)] + public partial class AddShareFileRequest { + + [System.ServiceModel.MessageBodyMemberAttribute(Name="AddShareFile", Namespace="http://tempuri.org/", Order=0)] + public EaseFilter.FolderLocker.ServiceReference1.AddShareFileRequestBody Body; + + public AddShareFileRequest() { + } + + public AddShareFileRequest(EaseFilter.FolderLocker.ServiceReference1.AddShareFileRequestBody Body) { + this.Body = Body; + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.Runtime.Serialization.DataContractAttribute(Namespace="http://tempuri.org/")] + public partial class AddShareFileRequestBody { + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=0)] + public string accountName; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=1)] + public string password; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=2)] + public string policy; + + [System.Runtime.Serialization.DataMemberAttribute(Order=3)] + public long creationTime; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=4)] + public string key; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=5)] + public string iv; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=6)] + public string lastError; + + public AddShareFileRequestBody() { + } + + public AddShareFileRequestBody(string accountName, string password, string policy, long creationTime, string key, string iv, string lastError) { + this.accountName = accountName; + this.password = password; + this.policy = policy; + this.creationTime = creationTime; + this.key = key; + this.iv = iv; + this.lastError = lastError; + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.ServiceModel.MessageContractAttribute(IsWrapped=false)] + public partial class AddShareFileResponse { + + [System.ServiceModel.MessageBodyMemberAttribute(Name="AddShareFileResponse", Namespace="http://tempuri.org/", Order=0)] + public EaseFilter.FolderLocker.ServiceReference1.AddShareFileResponseBody Body; + + public AddShareFileResponse() { + } + + public AddShareFileResponse(EaseFilter.FolderLocker.ServiceReference1.AddShareFileResponseBody Body) { + this.Body = Body; + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.Runtime.Serialization.DataContractAttribute(Namespace="http://tempuri.org/")] + public partial class AddShareFileResponseBody { + + [System.Runtime.Serialization.DataMemberAttribute(Order=0)] + public bool AddShareFileResult; + + [System.Runtime.Serialization.DataMemberAttribute(Order=1)] + public long creationTime; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=2)] + public string key; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=3)] + public string iv; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=4)] + public string lastError; + + public AddShareFileResponseBody() { + } + + public AddShareFileResponseBody(bool AddShareFileResult, long creationTime, string key, string iv, string lastError) { + this.AddShareFileResult = AddShareFileResult; + this.creationTime = creationTime; + this.key = key; + this.iv = iv; + this.lastError = lastError; + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.ServiceModel.MessageContractAttribute(IsWrapped=false)] + public partial class DeleteSharedFileRequest { + + [System.ServiceModel.MessageBodyMemberAttribute(Name="DeleteSharedFile", Namespace="http://tempuri.org/", Order=0)] + public EaseFilter.FolderLocker.ServiceReference1.DeleteSharedFileRequestBody Body; + + public DeleteSharedFileRequest() { + } + + public DeleteSharedFileRequest(EaseFilter.FolderLocker.ServiceReference1.DeleteSharedFileRequestBody Body) { + this.Body = Body; + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.Runtime.Serialization.DataContractAttribute(Namespace="http://tempuri.org/")] + public partial class DeleteSharedFileRequestBody { + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=0)] + public string accountName; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=1)] + public string password; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=2)] + public string encryptionIV; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=3)] + public string lastError; + + public DeleteSharedFileRequestBody() { + } + + public DeleteSharedFileRequestBody(string accountName, string password, string encryptionIV, string lastError) { + this.accountName = accountName; + this.password = password; + this.encryptionIV = encryptionIV; + this.lastError = lastError; + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.ServiceModel.MessageContractAttribute(IsWrapped=false)] + public partial class DeleteSharedFileResponse { + + [System.ServiceModel.MessageBodyMemberAttribute(Name="DeleteSharedFileResponse", Namespace="http://tempuri.org/", Order=0)] + public EaseFilter.FolderLocker.ServiceReference1.DeleteSharedFileResponseBody Body; + + public DeleteSharedFileResponse() { + } + + public DeleteSharedFileResponse(EaseFilter.FolderLocker.ServiceReference1.DeleteSharedFileResponseBody Body) { + this.Body = Body; + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.Runtime.Serialization.DataContractAttribute(Namespace="http://tempuri.org/")] + public partial class DeleteSharedFileResponseBody { + + [System.Runtime.Serialization.DataMemberAttribute(Order=0)] + public bool DeleteSharedFileResult; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=1)] + public string lastError; + + public DeleteSharedFileResponseBody() { + } + + public DeleteSharedFileResponseBody(bool DeleteSharedFileResult, string lastError) { + this.DeleteSharedFileResult = DeleteSharedFileResult; + this.lastError = lastError; + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.ServiceModel.MessageContractAttribute(IsWrapped=false)] + public partial class GetSharedFileDRInfoRequest { + + [System.ServiceModel.MessageBodyMemberAttribute(Name="GetSharedFileDRInfo", Namespace="http://tempuri.org/", Order=0)] + public EaseFilter.FolderLocker.ServiceReference1.GetSharedFileDRInfoRequestBody Body; + + public GetSharedFileDRInfoRequest() { + } + + public GetSharedFileDRInfoRequest(EaseFilter.FolderLocker.ServiceReference1.GetSharedFileDRInfoRequestBody Body) { + this.Body = Body; + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.Runtime.Serialization.DataContractAttribute(Namespace="http://tempuri.org/")] + public partial class GetSharedFileDRInfoRequestBody { + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=0)] + public string accountName; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=1)] + public string password; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=2)] + public string ivStr; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=3)] + public string encryptedDRPolicy; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=4)] + public string lastError; + + public GetSharedFileDRInfoRequestBody() { + } + + public GetSharedFileDRInfoRequestBody(string accountName, string password, string ivStr, string encryptedDRPolicy, string lastError) { + this.accountName = accountName; + this.password = password; + this.ivStr = ivStr; + this.encryptedDRPolicy = encryptedDRPolicy; + this.lastError = lastError; + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.ServiceModel.MessageContractAttribute(IsWrapped=false)] + public partial class GetSharedFileDRInfoResponse { + + [System.ServiceModel.MessageBodyMemberAttribute(Name="GetSharedFileDRInfoResponse", Namespace="http://tempuri.org/", Order=0)] + public EaseFilter.FolderLocker.ServiceReference1.GetSharedFileDRInfoResponseBody Body; + + public GetSharedFileDRInfoResponse() { + } + + public GetSharedFileDRInfoResponse(EaseFilter.FolderLocker.ServiceReference1.GetSharedFileDRInfoResponseBody Body) { + this.Body = Body; + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.Runtime.Serialization.DataContractAttribute(Namespace="http://tempuri.org/")] + public partial class GetSharedFileDRInfoResponseBody { + + [System.Runtime.Serialization.DataMemberAttribute(Order=0)] + public bool GetSharedFileDRInfoResult; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=1)] + public string encryptedDRPolicy; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=2)] + public string lastError; + + public GetSharedFileDRInfoResponseBody() { + } + + public GetSharedFileDRInfoResponseBody(bool GetSharedFileDRInfoResult, string encryptedDRPolicy, string lastError) { + this.GetSharedFileDRInfoResult = GetSharedFileDRInfoResult; + this.encryptedDRPolicy = encryptedDRPolicy; + this.lastError = lastError; + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.ServiceModel.MessageContractAttribute(IsWrapped=false)] + public partial class ModifySharedFileDRInfoRequest { + + [System.ServiceModel.MessageBodyMemberAttribute(Name="ModifySharedFileDRInfo", Namespace="http://tempuri.org/", Order=0)] + public EaseFilter.FolderLocker.ServiceReference1.ModifySharedFileDRInfoRequestBody Body; + + public ModifySharedFileDRInfoRequest() { + } + + public ModifySharedFileDRInfoRequest(EaseFilter.FolderLocker.ServiceReference1.ModifySharedFileDRInfoRequestBody Body) { + this.Body = Body; + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.Runtime.Serialization.DataContractAttribute(Namespace="http://tempuri.org/")] + public partial class ModifySharedFileDRInfoRequestBody { + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=0)] + public string accountName; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=1)] + public string password; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=2)] + public string encryptedDRPolicy; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=3)] + public string lastError; + + public ModifySharedFileDRInfoRequestBody() { + } + + public ModifySharedFileDRInfoRequestBody(string accountName, string password, string encryptedDRPolicy, string lastError) { + this.accountName = accountName; + this.password = password; + this.encryptedDRPolicy = encryptedDRPolicy; + this.lastError = lastError; + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.ServiceModel.MessageContractAttribute(IsWrapped=false)] + public partial class ModifySharedFileDRInfoResponse { + + [System.ServiceModel.MessageBodyMemberAttribute(Name="ModifySharedFileDRInfoResponse", Namespace="http://tempuri.org/", Order=0)] + public EaseFilter.FolderLocker.ServiceReference1.ModifySharedFileDRInfoResponseBody Body; + + public ModifySharedFileDRInfoResponse() { + } + + public ModifySharedFileDRInfoResponse(EaseFilter.FolderLocker.ServiceReference1.ModifySharedFileDRInfoResponseBody Body) { + this.Body = Body; + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.Runtime.Serialization.DataContractAttribute(Namespace="http://tempuri.org/")] + public partial class ModifySharedFileDRInfoResponseBody { + + [System.Runtime.Serialization.DataMemberAttribute(Order=0)] + public bool ModifySharedFileDRInfoResult; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=1)] + public string lastError; + + public ModifySharedFileDRInfoResponseBody() { + } + + public ModifySharedFileDRInfoResponseBody(bool ModifySharedFileDRInfoResult, string lastError) { + this.ModifySharedFileDRInfoResult = ModifySharedFileDRInfoResult; + this.lastError = lastError; + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.ServiceModel.MessageContractAttribute(IsWrapped=false)] + public partial class GetAccessLogRequest { + + [System.ServiceModel.MessageBodyMemberAttribute(Name="GetAccessLog", Namespace="http://tempuri.org/", Order=0)] + public EaseFilter.FolderLocker.ServiceReference1.GetAccessLogRequestBody Body; + + public GetAccessLogRequest() { + } + + public GetAccessLogRequest(EaseFilter.FolderLocker.ServiceReference1.GetAccessLogRequestBody Body) { + this.Body = Body; + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.Runtime.Serialization.DataContractAttribute(Namespace="http://tempuri.org/")] + public partial class GetAccessLogRequestBody { + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=0)] + public string accountName; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=1)] + public string password; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=2)] + public string accessLog; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=3)] + public string lastError; + + public GetAccessLogRequestBody() { + } + + public GetAccessLogRequestBody(string accountName, string password, string accessLog, string lastError) { + this.accountName = accountName; + this.password = password; + this.accessLog = accessLog; + this.lastError = lastError; + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.ServiceModel.MessageContractAttribute(IsWrapped=false)] + public partial class GetAccessLogResponse { + + [System.ServiceModel.MessageBodyMemberAttribute(Name="GetAccessLogResponse", Namespace="http://tempuri.org/", Order=0)] + public EaseFilter.FolderLocker.ServiceReference1.GetAccessLogResponseBody Body; + + public GetAccessLogResponse() { + } + + public GetAccessLogResponse(EaseFilter.FolderLocker.ServiceReference1.GetAccessLogResponseBody Body) { + this.Body = Body; + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.Runtime.Serialization.DataContractAttribute(Namespace="http://tempuri.org/")] + public partial class GetAccessLogResponseBody { + + [System.Runtime.Serialization.DataMemberAttribute(Order=0)] + public bool GetAccessLogResult; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=1)] + public string accessLog; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=2)] + public string lastError; + + public GetAccessLogResponseBody() { + } + + public GetAccessLogResponseBody(bool GetAccessLogResult, string accessLog, string lastError) { + this.GetAccessLogResult = GetAccessLogResult; + this.accessLog = accessLog; + this.lastError = lastError; + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.ServiceModel.MessageContractAttribute(IsWrapped=false)] + public partial class ClearAccessLogRequest { + + [System.ServiceModel.MessageBodyMemberAttribute(Name="ClearAccessLog", Namespace="http://tempuri.org/", Order=0)] + public EaseFilter.FolderLocker.ServiceReference1.ClearAccessLogRequestBody Body; + + public ClearAccessLogRequest() { + } + + public ClearAccessLogRequest(EaseFilter.FolderLocker.ServiceReference1.ClearAccessLogRequestBody Body) { + this.Body = Body; + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.Runtime.Serialization.DataContractAttribute(Namespace="http://tempuri.org/")] + public partial class ClearAccessLogRequestBody { + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=0)] + public string accountName; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=1)] + public string password; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=2)] + public string lastError; + + public ClearAccessLogRequestBody() { + } + + public ClearAccessLogRequestBody(string accountName, string password, string lastError) { + this.accountName = accountName; + this.password = password; + this.lastError = lastError; + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.ServiceModel.MessageContractAttribute(IsWrapped=false)] + public partial class ClearAccessLogResponse { + + [System.ServiceModel.MessageBodyMemberAttribute(Name="ClearAccessLogResponse", Namespace="http://tempuri.org/", Order=0)] + public EaseFilter.FolderLocker.ServiceReference1.ClearAccessLogResponseBody Body; + + public ClearAccessLogResponse() { + } + + public ClearAccessLogResponse(EaseFilter.FolderLocker.ServiceReference1.ClearAccessLogResponseBody Body) { + this.Body = Body; + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.Runtime.Serialization.DataContractAttribute(Namespace="http://tempuri.org/")] + public partial class ClearAccessLogResponseBody { + + [System.Runtime.Serialization.DataMemberAttribute(Order=0)] + public bool ClearAccessLogResult; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=1)] + public string lastError; + + public ClearAccessLogResponseBody() { + } + + public ClearAccessLogResponseBody(bool ClearAccessLogResult, string lastError) { + this.ClearAccessLogResult = ClearAccessLogResult; + this.lastError = lastError; + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.ServiceModel.MessageContractAttribute(IsWrapped=false)] + public partial class GetSharedFilePermissionRequest { + + [System.ServiceModel.MessageBodyMemberAttribute(Name="GetSharedFilePermission", Namespace="http://tempuri.org/", Order=0)] + public EaseFilter.FolderLocker.ServiceReference1.GetSharedFilePermissionRequestBody Body; + + public GetSharedFilePermissionRequest() { + } + + public GetSharedFilePermissionRequest(EaseFilter.FolderLocker.ServiceReference1.GetSharedFilePermissionRequestBody Body) { + this.Body = Body; + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.Runtime.Serialization.DataContractAttribute(Namespace="http://tempuri.org/")] + public partial class GetSharedFilePermissionRequestBody { + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=0)] + public string userInfoStr; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=1)] + public string key; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=2)] + public string iv; + + [System.Runtime.Serialization.DataMemberAttribute(Order=3)] + public uint accessFlags; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=4)] + public string lastError; + + public GetSharedFilePermissionRequestBody() { + } + + public GetSharedFilePermissionRequestBody(string userInfoStr, string key, string iv, uint accessFlags, string lastError) { + this.userInfoStr = userInfoStr; + this.key = key; + this.iv = iv; + this.accessFlags = accessFlags; + this.lastError = lastError; + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.ServiceModel.MessageContractAttribute(IsWrapped=false)] + public partial class GetSharedFilePermissionResponse { + + [System.ServiceModel.MessageBodyMemberAttribute(Name="GetSharedFilePermissionResponse", Namespace="http://tempuri.org/", Order=0)] + public EaseFilter.FolderLocker.ServiceReference1.GetSharedFilePermissionResponseBody Body; + + public GetSharedFilePermissionResponse() { + } + + public GetSharedFilePermissionResponse(EaseFilter.FolderLocker.ServiceReference1.GetSharedFilePermissionResponseBody Body) { + this.Body = Body; + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.Runtime.Serialization.DataContractAttribute(Namespace="http://tempuri.org/")] + public partial class GetSharedFilePermissionResponseBody { + + [System.Runtime.Serialization.DataMemberAttribute(Order=0)] + public bool GetSharedFilePermissionResult; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=1)] + public string key; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=2)] + public string iv; + + [System.Runtime.Serialization.DataMemberAttribute(Order=3)] + public uint accessFlags; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=4)] + public string lastError; + + public GetSharedFilePermissionResponseBody() { + } + + public GetSharedFilePermissionResponseBody(bool GetSharedFilePermissionResult, string key, string iv, uint accessFlags, string lastError) { + this.GetSharedFilePermissionResult = GetSharedFilePermissionResult; + this.key = key; + this.iv = iv; + this.accessFlags = accessFlags; + this.lastError = lastError; + } + } + + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + public interface ServiceSoapChannel : EaseFilter.FolderLocker.ServiceReference1.ServiceSoap, System.ServiceModel.IClientChannel { + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + public partial class ServiceSoapClient : System.ServiceModel.ClientBase, EaseFilter.FolderLocker.ServiceReference1.ServiceSoap { + + public ServiceSoapClient() { + } + + public ServiceSoapClient(string endpointConfigurationName) : + base(endpointConfigurationName) { + } + + public ServiceSoapClient(string endpointConfigurationName, string remoteAddress) : + base(endpointConfigurationName, remoteAddress) { + } + + public ServiceSoapClient(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) : + base(endpointConfigurationName, remoteAddress) { + } + + public ServiceSoapClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) : + base(binding, remoteAddress) { + } + + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + EaseFilter.FolderLocker.ServiceReference1.SignInAccountResponse EaseFilter.FolderLocker.ServiceReference1.ServiceSoap.SignInAccount(EaseFilter.FolderLocker.ServiceReference1.SignInAccountRequest request) { + return base.Channel.SignInAccount(request); + } + + public bool SignInAccount(string accountName, string password, ref string lastError) { + EaseFilter.FolderLocker.ServiceReference1.SignInAccountRequest inValue = new EaseFilter.FolderLocker.ServiceReference1.SignInAccountRequest(); + inValue.Body = new EaseFilter.FolderLocker.ServiceReference1.SignInAccountRequestBody(); + inValue.Body.accountName = accountName; + inValue.Body.password = password; + inValue.Body.lastError = lastError; + EaseFilter.FolderLocker.ServiceReference1.SignInAccountResponse retVal = ((EaseFilter.FolderLocker.ServiceReference1.ServiceSoap)(this)).SignInAccount(inValue); + lastError = retVal.Body.lastError; + return retVal.Body.SignInAccountResult; + } + + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + EaseFilter.FolderLocker.ServiceReference1.SignUpAccountResponse EaseFilter.FolderLocker.ServiceReference1.ServiceSoap.SignUpAccount(EaseFilter.FolderLocker.ServiceReference1.SignUpAccountRequest request) { + return base.Channel.SignUpAccount(request); + } + + public bool SignUpAccount(string accountName, string password, ref string lastError) { + EaseFilter.FolderLocker.ServiceReference1.SignUpAccountRequest inValue = new EaseFilter.FolderLocker.ServiceReference1.SignUpAccountRequest(); + inValue.Body = new EaseFilter.FolderLocker.ServiceReference1.SignUpAccountRequestBody(); + inValue.Body.accountName = accountName; + inValue.Body.password = password; + inValue.Body.lastError = lastError; + EaseFilter.FolderLocker.ServiceReference1.SignUpAccountResponse retVal = ((EaseFilter.FolderLocker.ServiceReference1.ServiceSoap)(this)).SignUpAccount(inValue); + lastError = retVal.Body.lastError; + return retVal.Body.SignUpAccountResult; + } + + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + EaseFilter.FolderLocker.ServiceReference1.GetFileListResponse EaseFilter.FolderLocker.ServiceReference1.ServiceSoap.GetFileList(EaseFilter.FolderLocker.ServiceReference1.GetFileListRequest request) { + return base.Channel.GetFileList(request); + } + + public bool GetFileList(string accountName, string password, ref string fileList, ref string lastError) { + EaseFilter.FolderLocker.ServiceReference1.GetFileListRequest inValue = new EaseFilter.FolderLocker.ServiceReference1.GetFileListRequest(); + inValue.Body = new EaseFilter.FolderLocker.ServiceReference1.GetFileListRequestBody(); + inValue.Body.accountName = accountName; + inValue.Body.password = password; + inValue.Body.fileList = fileList; + inValue.Body.lastError = lastError; + EaseFilter.FolderLocker.ServiceReference1.GetFileListResponse retVal = ((EaseFilter.FolderLocker.ServiceReference1.ServiceSoap)(this)).GetFileList(inValue); + fileList = retVal.Body.fileList; + lastError = retVal.Body.lastError; + return retVal.Body.GetFileListResult; + } + + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + EaseFilter.FolderLocker.ServiceReference1.AddShareFileResponse EaseFilter.FolderLocker.ServiceReference1.ServiceSoap.AddShareFile(EaseFilter.FolderLocker.ServiceReference1.AddShareFileRequest request) { + return base.Channel.AddShareFile(request); + } + + public bool AddShareFile(string accountName, string password, string policy, ref long creationTime, ref string key, ref string iv, ref string lastError) { + EaseFilter.FolderLocker.ServiceReference1.AddShareFileRequest inValue = new EaseFilter.FolderLocker.ServiceReference1.AddShareFileRequest(); + inValue.Body = new EaseFilter.FolderLocker.ServiceReference1.AddShareFileRequestBody(); + inValue.Body.accountName = accountName; + inValue.Body.password = password; + inValue.Body.policy = policy; + inValue.Body.creationTime = creationTime; + inValue.Body.key = key; + inValue.Body.iv = iv; + inValue.Body.lastError = lastError; + EaseFilter.FolderLocker.ServiceReference1.AddShareFileResponse retVal = ((EaseFilter.FolderLocker.ServiceReference1.ServiceSoap)(this)).AddShareFile(inValue); + creationTime = retVal.Body.creationTime; + key = retVal.Body.key; + iv = retVal.Body.iv; + lastError = retVal.Body.lastError; + return retVal.Body.AddShareFileResult; + } + + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + EaseFilter.FolderLocker.ServiceReference1.DeleteSharedFileResponse EaseFilter.FolderLocker.ServiceReference1.ServiceSoap.DeleteSharedFile(EaseFilter.FolderLocker.ServiceReference1.DeleteSharedFileRequest request) { + return base.Channel.DeleteSharedFile(request); + } + + public bool DeleteSharedFile(string accountName, string password, string encryptionIV, ref string lastError) { + EaseFilter.FolderLocker.ServiceReference1.DeleteSharedFileRequest inValue = new EaseFilter.FolderLocker.ServiceReference1.DeleteSharedFileRequest(); + inValue.Body = new EaseFilter.FolderLocker.ServiceReference1.DeleteSharedFileRequestBody(); + inValue.Body.accountName = accountName; + inValue.Body.password = password; + inValue.Body.encryptionIV = encryptionIV; + inValue.Body.lastError = lastError; + EaseFilter.FolderLocker.ServiceReference1.DeleteSharedFileResponse retVal = ((EaseFilter.FolderLocker.ServiceReference1.ServiceSoap)(this)).DeleteSharedFile(inValue); + lastError = retVal.Body.lastError; + return retVal.Body.DeleteSharedFileResult; + } + + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + EaseFilter.FolderLocker.ServiceReference1.GetSharedFileDRInfoResponse EaseFilter.FolderLocker.ServiceReference1.ServiceSoap.GetSharedFileDRInfo(EaseFilter.FolderLocker.ServiceReference1.GetSharedFileDRInfoRequest request) { + return base.Channel.GetSharedFileDRInfo(request); + } + + public bool GetSharedFileDRInfo(string accountName, string password, string ivStr, ref string encryptedDRPolicy, ref string lastError) { + EaseFilter.FolderLocker.ServiceReference1.GetSharedFileDRInfoRequest inValue = new EaseFilter.FolderLocker.ServiceReference1.GetSharedFileDRInfoRequest(); + inValue.Body = new EaseFilter.FolderLocker.ServiceReference1.GetSharedFileDRInfoRequestBody(); + inValue.Body.accountName = accountName; + inValue.Body.password = password; + inValue.Body.ivStr = ivStr; + inValue.Body.encryptedDRPolicy = encryptedDRPolicy; + inValue.Body.lastError = lastError; + EaseFilter.FolderLocker.ServiceReference1.GetSharedFileDRInfoResponse retVal = ((EaseFilter.FolderLocker.ServiceReference1.ServiceSoap)(this)).GetSharedFileDRInfo(inValue); + encryptedDRPolicy = retVal.Body.encryptedDRPolicy; + lastError = retVal.Body.lastError; + return retVal.Body.GetSharedFileDRInfoResult; + } + + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + EaseFilter.FolderLocker.ServiceReference1.ModifySharedFileDRInfoResponse EaseFilter.FolderLocker.ServiceReference1.ServiceSoap.ModifySharedFileDRInfo(EaseFilter.FolderLocker.ServiceReference1.ModifySharedFileDRInfoRequest request) { + return base.Channel.ModifySharedFileDRInfo(request); + } + + public bool ModifySharedFileDRInfo(string accountName, string password, string encryptedDRPolicy, ref string lastError) { + EaseFilter.FolderLocker.ServiceReference1.ModifySharedFileDRInfoRequest inValue = new EaseFilter.FolderLocker.ServiceReference1.ModifySharedFileDRInfoRequest(); + inValue.Body = new EaseFilter.FolderLocker.ServiceReference1.ModifySharedFileDRInfoRequestBody(); + inValue.Body.accountName = accountName; + inValue.Body.password = password; + inValue.Body.encryptedDRPolicy = encryptedDRPolicy; + inValue.Body.lastError = lastError; + EaseFilter.FolderLocker.ServiceReference1.ModifySharedFileDRInfoResponse retVal = ((EaseFilter.FolderLocker.ServiceReference1.ServiceSoap)(this)).ModifySharedFileDRInfo(inValue); + lastError = retVal.Body.lastError; + return retVal.Body.ModifySharedFileDRInfoResult; + } + + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + EaseFilter.FolderLocker.ServiceReference1.GetAccessLogResponse EaseFilter.FolderLocker.ServiceReference1.ServiceSoap.GetAccessLog(EaseFilter.FolderLocker.ServiceReference1.GetAccessLogRequest request) { + return base.Channel.GetAccessLog(request); + } + + public bool GetAccessLog(string accountName, string password, ref string accessLog, ref string lastError) { + EaseFilter.FolderLocker.ServiceReference1.GetAccessLogRequest inValue = new EaseFilter.FolderLocker.ServiceReference1.GetAccessLogRequest(); + inValue.Body = new EaseFilter.FolderLocker.ServiceReference1.GetAccessLogRequestBody(); + inValue.Body.accountName = accountName; + inValue.Body.password = password; + inValue.Body.accessLog = accessLog; + inValue.Body.lastError = lastError; + EaseFilter.FolderLocker.ServiceReference1.GetAccessLogResponse retVal = ((EaseFilter.FolderLocker.ServiceReference1.ServiceSoap)(this)).GetAccessLog(inValue); + accessLog = retVal.Body.accessLog; + lastError = retVal.Body.lastError; + return retVal.Body.GetAccessLogResult; + } + + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + EaseFilter.FolderLocker.ServiceReference1.ClearAccessLogResponse EaseFilter.FolderLocker.ServiceReference1.ServiceSoap.ClearAccessLog(EaseFilter.FolderLocker.ServiceReference1.ClearAccessLogRequest request) { + return base.Channel.ClearAccessLog(request); + } + + public bool ClearAccessLog(string accountName, string password, ref string lastError) { + EaseFilter.FolderLocker.ServiceReference1.ClearAccessLogRequest inValue = new EaseFilter.FolderLocker.ServiceReference1.ClearAccessLogRequest(); + inValue.Body = new EaseFilter.FolderLocker.ServiceReference1.ClearAccessLogRequestBody(); + inValue.Body.accountName = accountName; + inValue.Body.password = password; + inValue.Body.lastError = lastError; + EaseFilter.FolderLocker.ServiceReference1.ClearAccessLogResponse retVal = ((EaseFilter.FolderLocker.ServiceReference1.ServiceSoap)(this)).ClearAccessLog(inValue); + lastError = retVal.Body.lastError; + return retVal.Body.ClearAccessLogResult; + } + + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + EaseFilter.FolderLocker.ServiceReference1.GetSharedFilePermissionResponse EaseFilter.FolderLocker.ServiceReference1.ServiceSoap.GetSharedFilePermission(EaseFilter.FolderLocker.ServiceReference1.GetSharedFilePermissionRequest request) { + return base.Channel.GetSharedFilePermission(request); + } + + public bool GetSharedFilePermission(string userInfoStr, ref string key, ref string iv, ref uint accessFlags, ref string lastError) { + EaseFilter.FolderLocker.ServiceReference1.GetSharedFilePermissionRequest inValue = new EaseFilter.FolderLocker.ServiceReference1.GetSharedFilePermissionRequest(); + inValue.Body = new EaseFilter.FolderLocker.ServiceReference1.GetSharedFilePermissionRequestBody(); + inValue.Body.userInfoStr = userInfoStr; + inValue.Body.key = key; + inValue.Body.iv = iv; + inValue.Body.accessFlags = accessFlags; + inValue.Body.lastError = lastError; + EaseFilter.FolderLocker.ServiceReference1.GetSharedFilePermissionResponse retVal = ((EaseFilter.FolderLocker.ServiceReference1.ServiceSoap)(this)).GetSharedFilePermission(inValue); + key = retVal.Body.key; + iv = retVal.Body.iv; + accessFlags = retVal.Body.accessFlags; + lastError = retVal.Body.lastError; + return retVal.Body.GetSharedFilePermissionResult; + } + } +} diff --git a/Demo_Source_Code/CSharpDemo/FolderLocker/Service References/ServiceReference1/Reference.svcmap b/Demo_Source_Code/CSharpDemo/FolderLocker/Service References/ServiceReference1/Reference.svcmap new file mode 100644 index 0000000..f61e7a5 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FolderLocker/Service References/ServiceReference1/Reference.svcmap @@ -0,0 +1,31 @@ + + + + false + true + + false + false + false + + + true + Auto + true + true + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/FolderLocker/Service References/ServiceReference1/configuration.svcinfo b/Demo_Source_Code/CSharpDemo/FolderLocker/Service References/ServiceReference1/configuration.svcinfo new file mode 100644 index 0000000..f6ecac6 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FolderLocker/Service References/ServiceReference1/configuration.svcinfo @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/FolderLocker/Service References/ServiceReference1/configuration91.svcinfo b/Demo_Source_Code/CSharpDemo/FolderLocker/Service References/ServiceReference1/configuration91.svcinfo new file mode 100644 index 0000000..0bb869c --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FolderLocker/Service References/ServiceReference1/configuration91.svcinfo @@ -0,0 +1,201 @@ + + + + + + + ServiceSoap + + + + + + + + + + + + + + + + + + + + + StrongWildcard + + + + + + 65536 + + + + + + + + + System.ServiceModel.Configuration.XmlDictionaryReaderQuotasElement + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + System.Text.UTF8Encoding + + + Buffered + + + + + + Text + + + System.ServiceModel.Configuration.BasicHttpSecurityElement + + + None + + + System.ServiceModel.Configuration.HttpTransportSecurityElement + + + None + + + None + + + System.Security.Authentication.ExtendedProtection.Configuration.ExtendedProtectionPolicyElement + + + Never + + + TransportSelected + + + (Collection) + + + + + + System.ServiceModel.Configuration.BasicHttpMessageSecurityElement + + + UserName + + + Default + + + + + + + + + http://encryptme.net/webapi.asmx + + + + + + basicHttpBinding + + + ServiceSoap + + + ServiceReference1.ServiceSoap + + + System.ServiceModel.Configuration.AddressHeaderCollectionElement + + + <Header /> + + + System.ServiceModel.Configuration.IdentityElement + + + System.ServiceModel.Configuration.UserPrincipalNameElement + + + + + + System.ServiceModel.Configuration.ServicePrincipalNameElement + + + + + + System.ServiceModel.Configuration.DnsElement + + + + + + System.ServiceModel.Configuration.RsaElement + + + + + + System.ServiceModel.Configuration.CertificateElement + + + + + + System.ServiceModel.Configuration.CertificateReferenceElement + + + My + + + LocalMachine + + + FindBySubjectDistinguishedName + + + + + + False + + + ServiceSoap + + + + + + + + + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/FolderLocker/Service References/ServiceReference1/webapi.disco b/Demo_Source_Code/CSharpDemo/FolderLocker/Service References/ServiceReference1/webapi.disco new file mode 100644 index 0000000..a1c38a7 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FolderLocker/Service References/ServiceReference1/webapi.disco @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/FolderLocker/Service References/ServiceReference1/webapi.wsdl b/Demo_Source_Code/CSharpDemo/FolderLocker/Service References/ServiceReference1/webapi.wsdl new file mode 100644 index 0000000..a1d994d --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FolderLocker/Service References/ServiceReference1/webapi.wsdl @@ -0,0 +1,494 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/FolderLocker/ShareFileForm.Designer.cs b/Demo_Source_Code/CSharpDemo/FolderLocker/ShareFileForm.Designer.cs new file mode 100644 index 0000000..f1cf844 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FolderLocker/ShareFileForm.Designer.cs @@ -0,0 +1,291 @@ +namespace EaseFilter.FolderLocker +{ + partial class ShareFileForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ShareFileForm)); + this.label2 = new System.Windows.Forms.Label(); + this.label1 = new System.Windows.Forms.Label(); + this.textBox_FileName = new System.Windows.Forms.TextBox(); + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.label3 = new System.Windows.Forms.Label(); + this.textBox_UnauthorizedUserNames = new System.Windows.Forms.TextBox(); + this.label4 = new System.Windows.Forms.Label(); + this.textBox_AuthorizedUserNames = new System.Windows.Forms.TextBox(); + this.label5 = new System.Windows.Forms.Label(); + this.textBox_UnauthorizedProcessNames = new System.Windows.Forms.TextBox(); + this.label11 = new System.Windows.Forms.Label(); + this.textBox_TargetName = new System.Windows.Forms.TextBox(); + this.label6 = new System.Windows.Forms.Label(); + this.dateTimePicker_ExpireDate = new System.Windows.Forms.DateTimePicker(); + this.button_OpenFile = new System.Windows.Forms.Button(); + this.dateTimePicker_ExpireTime = new System.Windows.Forms.DateTimePicker(); + this.label12 = new System.Windows.Forms.Label(); + this.textBox_authorizedProcessNames = new System.Windows.Forms.TextBox(); + this.label10 = new System.Windows.Forms.Label(); + this.button_CreateFile = new System.Windows.Forms.Button(); + this.groupBox1.SuspendLayout(); + this.SuspendLayout(); + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(16, 90); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(104, 13); + this.label2.TabIndex = 2; + this.label2.Text = "Share file expire time"; + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(16, 20); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(114, 13); + this.label1.TabIndex = 1; + this.label1.Text = "File name to be shared"; + // + // textBox_FileName + // + this.textBox_FileName.Location = new System.Drawing.Point(213, 20); + this.textBox_FileName.Name = "textBox_FileName"; + this.textBox_FileName.Size = new System.Drawing.Size(242, 20); + this.textBox_FileName.TabIndex = 2; + this.textBox_FileName.Text = "c:\\test\\test.txt"; + // + // groupBox1 + // + this.groupBox1.Controls.Add(this.label3); + this.groupBox1.Controls.Add(this.textBox_UnauthorizedUserNames); + this.groupBox1.Controls.Add(this.label4); + this.groupBox1.Controls.Add(this.textBox_AuthorizedUserNames); + this.groupBox1.Controls.Add(this.label5); + this.groupBox1.Controls.Add(this.textBox_UnauthorizedProcessNames); + this.groupBox1.Controls.Add(this.label11); + this.groupBox1.Controls.Add(this.textBox_TargetName); + this.groupBox1.Controls.Add(this.label6); + this.groupBox1.Controls.Add(this.dateTimePicker_ExpireDate); + this.groupBox1.Controls.Add(this.button_OpenFile); + this.groupBox1.Controls.Add(this.dateTimePicker_ExpireTime); + this.groupBox1.Controls.Add(this.label12); + this.groupBox1.Controls.Add(this.textBox_authorizedProcessNames); + this.groupBox1.Controls.Add(this.label10); + this.groupBox1.Controls.Add(this.label2); + this.groupBox1.Controls.Add(this.textBox_FileName); + this.groupBox1.Controls.Add(this.label1); + this.groupBox1.Location = new System.Drawing.Point(12, 2); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size(538, 309); + this.groupBox1.TabIndex = 11; + this.groupBox1.TabStop = false; + // + // label3 + // + this.label3.AutoSize = true; + this.label3.Font = new System.Drawing.Font("Microsoft Sans Serif", 6.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.label3.Location = new System.Drawing.Point(209, 230); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(195, 12); + this.label3.TabIndex = 80; + this.label3.Text = "(split with \';\' ,user name format \"domain\\user\" )"; + // + // textBox_UnauthorizedUserNames + // + this.textBox_UnauthorizedUserNames.Location = new System.Drawing.Point(214, 253); + this.textBox_UnauthorizedUserNames.Name = "textBox_UnauthorizedUserNames"; + this.textBox_UnauthorizedUserNames.Size = new System.Drawing.Size(242, 20); + this.textBox_UnauthorizedUserNames.TabIndex = 76; + // + // label4 + // + this.label4.AutoSize = true; + this.label4.Location = new System.Drawing.Point(17, 253); + this.label4.Name = "label4"; + this.label4.Size = new System.Drawing.Size(127, 13); + this.label4.TabIndex = 79; + this.label4.Text = "Unauthorized user names"; + // + // textBox_AuthorizedUserNames + // + this.textBox_AuthorizedUserNames.Location = new System.Drawing.Point(214, 210); + this.textBox_AuthorizedUserNames.Name = "textBox_AuthorizedUserNames"; + this.textBox_AuthorizedUserNames.Size = new System.Drawing.Size(242, 20); + this.textBox_AuthorizedUserNames.TabIndex = 75; + // + // label5 + // + this.label5.AutoSize = true; + this.label5.Location = new System.Drawing.Point(17, 213); + this.label5.Name = "label5"; + this.label5.Size = new System.Drawing.Size(114, 13); + this.label5.TabIndex = 78; + this.label5.Text = "Authorized user names"; + // + // textBox_UnauthorizedProcessNames + // + this.textBox_UnauthorizedProcessNames.Location = new System.Drawing.Point(214, 173); + this.textBox_UnauthorizedProcessNames.Name = "textBox_UnauthorizedProcessNames"; + this.textBox_UnauthorizedProcessNames.Size = new System.Drawing.Size(242, 20); + this.textBox_UnauthorizedProcessNames.TabIndex = 74; + this.textBox_UnauthorizedProcessNames.Text = "explorer.exe;"; + // + // label11 + // + this.label11.AutoSize = true; + this.label11.Location = new System.Drawing.Point(17, 173); + this.label11.Name = "label11"; + this.label11.Size = new System.Drawing.Size(147, 13); + this.label11.TabIndex = 77; + this.label11.Text = "Unauthorized process names"; + // + // textBox_TargetName + // + this.textBox_TargetName.Location = new System.Drawing.Point(214, 54); + this.textBox_TargetName.Name = "textBox_TargetName"; + this.textBox_TargetName.Size = new System.Drawing.Size(242, 20); + this.textBox_TargetName.TabIndex = 72; + this.textBox_TargetName.Text = "c:\\test\\test.txt"; + // + // label6 + // + this.label6.AutoSize = true; + this.label6.Location = new System.Drawing.Point(17, 54); + this.label6.Name = "label6"; + this.label6.Size = new System.Drawing.Size(118, 13); + this.label6.TabIndex = 73; + this.label6.Text = "Target shared file name"; + // + // dateTimePicker_ExpireDate + // + this.dateTimePicker_ExpireDate.CustomFormat = "yyyy-MM-dd"; + this.dateTimePicker_ExpireDate.Format = System.Windows.Forms.DateTimePickerFormat.Custom; + this.dateTimePicker_ExpireDate.Location = new System.Drawing.Point(212, 90); + this.dateTimePicker_ExpireDate.Name = "dateTimePicker_ExpireDate"; + this.dateTimePicker_ExpireDate.Size = new System.Drawing.Size(120, 20); + this.dateTimePicker_ExpireDate.TabIndex = 71; + // + // button_OpenFile + // + this.button_OpenFile.Location = new System.Drawing.Point(470, 18); + this.button_OpenFile.Name = "button_OpenFile"; + this.button_OpenFile.Size = new System.Drawing.Size(51, 23); + this.button_OpenFile.TabIndex = 3; + this.button_OpenFile.Text = "browse"; + this.button_OpenFile.UseVisualStyleBackColor = true; + this.button_OpenFile.Click += new System.EventHandler(this.button_OpenFile_Click); + // + // dateTimePicker_ExpireTime + // + this.dateTimePicker_ExpireTime.CustomFormat = " HH:mm:ss"; + this.dateTimePicker_ExpireTime.Format = System.Windows.Forms.DateTimePickerFormat.Time; + this.dateTimePicker_ExpireTime.Location = new System.Drawing.Point(335, 90); + this.dateTimePicker_ExpireTime.Name = "dateTimePicker_ExpireTime"; + this.dateTimePicker_ExpireTime.ShowUpDown = true; + this.dateTimePicker_ExpireTime.Size = new System.Drawing.Size(120, 20); + this.dateTimePicker_ExpireTime.TabIndex = 5; + // + // label12 + // + this.label12.AutoSize = true; + this.label12.Font = new System.Drawing.Font("Microsoft Sans Serif", 6.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.label12.Location = new System.Drawing.Point(211, 151); + this.label12.Name = "label12"; + this.label12.Size = new System.Drawing.Size(246, 12); + this.label12.TabIndex = 57; + this.label12.Text = "( split with \';\' , process format \"notepad.exe;wordpad.exe\" )"; + // + // textBox_authorizedProcessNames + // + this.textBox_authorizedProcessNames.Location = new System.Drawing.Point(213, 127); + this.textBox_authorizedProcessNames.Name = "textBox_authorizedProcessNames"; + this.textBox_authorizedProcessNames.Size = new System.Drawing.Size(242, 20); + this.textBox_authorizedProcessNames.TabIndex = 6; + // + // label10 + // + this.label10.AutoSize = true; + this.label10.Location = new System.Drawing.Point(16, 130); + this.label10.Name = "label10"; + this.label10.Size = new System.Drawing.Size(131, 13); + this.label10.TabIndex = 53; + this.label10.Text = "Authorized process names"; + // + // button_CreateFile + // + this.button_CreateFile.DialogResult = System.Windows.Forms.DialogResult.OK; + this.button_CreateFile.Location = new System.Drawing.Point(419, 335); + this.button_CreateFile.Name = "button_CreateFile"; + this.button_CreateFile.Size = new System.Drawing.Size(114, 23); + this.button_CreateFile.TabIndex = 15; + this.button_CreateFile.Text = "Create Share File"; + this.button_CreateFile.UseVisualStyleBackColor = true; + this.button_CreateFile.Click += new System.EventHandler(this.button_CreateFile_Click); + // + // ShareFileForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(571, 394); + this.Controls.Add(this.button_CreateFile); + this.Controls.Add(this.groupBox1); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "ShareFileForm"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "EaseFilter Secure File Creation"; + this.groupBox1.ResumeLayout(false); + this.groupBox1.PerformLayout(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.Label label2; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.TextBox textBox_FileName; + private System.Windows.Forms.GroupBox groupBox1; + private System.Windows.Forms.TextBox textBox_authorizedProcessNames; + private System.Windows.Forms.Label label10; + private System.Windows.Forms.Label label12; + private System.Windows.Forms.DateTimePicker dateTimePicker_ExpireTime; + private System.Windows.Forms.Button button_OpenFile; + private System.Windows.Forms.Button button_CreateFile; + private System.Windows.Forms.DateTimePicker dateTimePicker_ExpireDate; + private System.Windows.Forms.TextBox textBox_TargetName; + private System.Windows.Forms.Label label6; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.TextBox textBox_UnauthorizedUserNames; + private System.Windows.Forms.Label label4; + private System.Windows.Forms.TextBox textBox_AuthorizedUserNames; + private System.Windows.Forms.Label label5; + private System.Windows.Forms.TextBox textBox_UnauthorizedProcessNames; + private System.Windows.Forms.Label label11; + } +} \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/FolderLocker/ShareFileForm.cs b/Demo_Source_Code/CSharpDemo/FolderLocker/ShareFileForm.cs new file mode 100644 index 0000000..d37ee34 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FolderLocker/ShareFileForm.cs @@ -0,0 +1,298 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.IO; +using System.Windows.Forms; +using System.Runtime.InteropServices; + +using EaseFilter.FilterControl; +using EaseFilter.CommonObjects; + +namespace EaseFilter.FolderLocker +{ + public partial class ShareFileForm : Form + { + + DRPolicy selectedDRPolicy = null; + + public ShareFileForm(DRPolicy drPolicy) + { + InitializeComponent(); + + textBox_FileName.Text = drPolicy.FileName; + + selectedDRPolicy = drPolicy; + textBox_FileName.Enabled = false; + textBox_TargetName.Enabled = false; + button_OpenFile.Enabled = false; + + dateTimePicker_ExpireDate.Value = DateTime.FromFileTime(drPolicy.ExpireTime); + dateTimePicker_ExpireTime.Value = DateTime.FromFileTime(drPolicy.ExpireTime); + textBox_authorizedProcessNames.Text = drPolicy.AuthorizedProcessNames; + textBox_UnauthorizedProcessNames.Text = drPolicy.UnauthorizedProcessNames; + textBox_AuthorizedUserNames.Text = drPolicy.AuthorizedUserNames; + textBox_UnauthorizedUserNames.Text = drPolicy.UnauthorizedUserNames; + + button_CreateFile.Text = "Apply change"; + } + + public ShareFileForm() + { + InitializeComponent(); + dateTimePicker_ExpireDate.Value = DateTime.Now.AddDays(1); + dateTimePicker_ExpireTime.Value = DateTime.Now; + + button_CreateFile.Text = "Create Share File"; + } + + private DRPolicy GetDRSetting() + { + DRPolicy drPolicy = new DRPolicy(); + + try + { + drPolicy.AuthorizedProcessNames = textBox_authorizedProcessNames.Text.Trim().ToLower(); + drPolicy.UnauthorizedProcessNames = textBox_UnauthorizedProcessNames.Text.Trim().ToLower(); + drPolicy.AuthorizedUserNames = textBox_AuthorizedUserNames.Text.Trim().ToLower(); + drPolicy.UnauthorizedUserNames = textBox_UnauthorizedUserNames.Text.Trim().ToLower(); + DateTime expireDate = dateTimePicker_ExpireDate.Value.Date + dateTimePicker_ExpireTime.Value.TimeOfDay; + drPolicy.FileName = Path.GetFileName(textBox_TargetName.Text); + drPolicy.ExpireTime = expireDate.ToFileTime(); + + if (null != selectedDRPolicy) + { + drPolicy.EncryptionIV = selectedDRPolicy.EncryptionIV; + } + } + catch (Exception ex) + { + throw new Exception("Apply digital right failed with error:" + ex.Message); + } + + return drPolicy; + } + + + private bool AddNewFileDRInfoToServer(ref string iv, ref string key, ref long creationTime) + { + bool retVal = false; + string lastError = string.Empty; + + try + { + + iv = string.Empty; + key = string.Empty; + creationTime = 0; + + DRPolicy drPolicy = GetDRSetting(); + + string encryptedDRPolicy = Utils.EncryptObjectToStr(drPolicy); + + retVal = WebAPIServices.AddShareFile( encryptedDRPolicy, ref creationTime, ref key, ref iv, ref lastError); + if (!retVal) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("Create share encrypted file failed with error:" + lastError, "Process share encrypted file", MessageBoxButtons.OK, MessageBoxIcon.Error); + return retVal; + } + } + catch (Exception ex) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("Get encryption key info failed with error:" + ex.Message, "GetEncryptionKeyAndIVFromServer", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + + return retVal; + } + + private bool CreateOrModifyShareEncryptFile() + { + string lastError = string.Empty; + + string authorizedProcessNames = textBox_authorizedProcessNames.Text.Trim(); + string unauthorizedProcessNames = textBox_UnauthorizedProcessNames.Text.Trim(); + string authorizedUserNames = textBox_AuthorizedUserNames.Text.Trim(); + string unauthorizedUserNames = textBox_UnauthorizedUserNames.Text.Trim(); + string fileName = textBox_FileName.Text.Trim(); + string targetFileName = textBox_TargetName.Text; + + try + { + if (fileName.Length == 0) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("The file name can't be empty.", "Create share encrypted file", MessageBoxButtons.OK, MessageBoxIcon.Error); + return false; + } + + DateTime expireDateTime = dateTimePicker_ExpireDate.Value.Date + dateTimePicker_ExpireTime.Value.TimeOfDay; + if (expireDateTime <= DateTime.Now) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("The expire time can't be less than current time.", "Create share encrypted file", MessageBoxButtons.OK, MessageBoxIcon.Error); + return false; + } + + if (selectedDRPolicy != null) + { + DRPolicy drPolicy = GetDRSetting(); + string encryptedDRPolicy = Utils.EncryptObjectToStr(drPolicy); + + if (WebAPIServices.ModifySharedFileDRInfo(encryptedDRPolicy, ref lastError)) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("Modify shared file " + textBox_FileName.Text + " policy succeeded.", "Modify shared file", MessageBoxButtons.OK, MessageBoxIcon.Information); + + return true; + + } + else + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("Modify shared file " + textBox_FileName.Text + " policy failed with error:" + lastError, "Modify shared file", MessageBoxButtons.OK, MessageBoxIcon.Error); + + return false; + + } + } + + //here we generate the random unique IV and key, you can use your own key and iv + byte[] encryptionIV = Utils.GetRandomIV(); + byte[] encryptionKey = Utils.GetRandomKey(); + + string keyStr = string.Empty; + string ivStr = string.Empty; + + long creationTime = DateTime.Now.ToFileTime(); + + //send the encrypted file digital right information to the server and get back the iv and key. + if (!AddNewFileDRInfoToServer(ref ivStr, ref keyStr, ref creationTime)) + { + return false; + } + + if (ivStr.Length > 0 && keyStr.Length > 0) + { + encryptionIV = Utils.ConvertHexStrToByteArray(ivStr); + encryptionKey = Utils.ConvertHexStrToByteArray(keyStr); + } + + //for this example, we add the encryptIV and account name as the tag data to the encrypted file + //you can add your own custom tag data to the encyrpted file, so when someone open the encrypted file, you will get the tag data. + string tagStr = GlobalConfig.AccountName + ";" + ivStr; + byte[] tagData = UnicodeEncoding.Unicode.GetBytes(tagStr); + + bool retVal = false; + + if (fileName.Equals(targetFileName, StringComparison.CurrentCulture)) + { + //the source file name is the same as the target file name + retVal = FilterAPI.AESEncryptFileWithTag(fileName, (uint)encryptionKey.Length, encryptionKey, (uint)encryptionIV.Length, encryptionIV, (uint)tagData.Length, tagData); + } + else + { + retVal = FilterAPI.AESEncryptFileToFileWithTag(fileName, targetFileName, (uint)encryptionKey.Length, encryptionKey, (uint)encryptionIV.Length, encryptionIV, (uint)tagData.Length, tagData); + } + + if (!retVal) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("Create encrypted file " + targetFileName + " failed with error:" + FilterAPI.GetLastErrorMessage(), "Create share encrypted file", MessageBoxButtons.OK, MessageBoxIcon.Error); + + WebAPIServices.DeleteShareFile(ivStr, ref lastError); + + if (!fileName.Equals(targetFileName, StringComparison.CurrentCulture)) + { + File.Delete(targetFileName); + } + + return false; + } + else + { + //set this flag to the encrypted file, require to get permission from user mode when the file open + if (!FilterAPI.SetHeaderFlags(targetFileName, (uint)AESFlags.Flags_Request_IV_And_Key_From_User, FilterAPI.ALLOW_MAX_RIGHT_ACCESS)) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("SetHeaderFlags for file " + targetFileName + " failed with error:" + FilterAPI.GetLastErrorMessage(), "SetHeaderFlags", MessageBoxButtons.OK, MessageBoxIcon.Error); + + return false; + } + + + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + string message = "Create encrypted file " + targetFileName + " succeeded, you can distribute this encrypted file to your client.\r\n\r\nDownload this file to the share file drop folder in the client,"; + message += " then start the filter service there, now you can open the encrypted file if the process in client has the permission."; + MessageBox.Show(message, "Share encrypted file", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + + return true; + + } + catch (Exception ex) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("Create share file failed with error " + ex.Message, "Create share encrypted file", MessageBoxButtons.OK, MessageBoxIcon.Error); + + return false; + } + } + + + private void button_OpenFile_Click(object sender, EventArgs e) + { + OpenFileDialog openFileDialog = new OpenFileDialog(); + + if (openFileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + textBox_FileName.Text = openFileDialog.FileName; + textBox_TargetName.Text = openFileDialog.FileName; + } + } + + + private void button_CreateFile_Click(object sender, EventArgs e) + { + try + { + string lastError = string.Empty; + if (CreateOrModifyShareEncryptFile()) + { + this.Close(); + } + + } + catch (Exception ex) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("Add digital right information to file " + textBox_FileName + " failed with error " + ex.Message, "Create", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + + } + + + } +} diff --git a/Demo_Source_Code/CSharpDemo/FolderLocker/ShareFileForm.resx b/Demo_Source_Code/CSharpDemo/FolderLocker/ShareFileForm.resx new file mode 100644 index 0000000..6cb06c8 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FolderLocker/ShareFileForm.resx @@ -0,0 +1,1253 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + AAABAAEAgIAAAAEAIAAoCAEAFgAAACgAAACAAAAAAAEAAAEAIAAAAAAAAAABABMLAAATCwAAAAAAAAAA + AAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAIAAAADAAAAAwAA + AAQAAAAEAAAABAAAAAMAAAADAAAAAgAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAEAAAABAAAAAgAAAAQAAAAFAAAACAAAAAkAAAAKAAAACwAAAAsAAAALAAAACgAAAAkAAAAHAAAABQAA + AAMAAAACAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAACAAAAAwAAAAUAAAAIAAAADAAAAA4AAAASAAAAFQAA + ABgAAAAaAAAAGgAAABoAAAAXAAAAFQAAABEAAAAOAAAACgAAAAcAAAAFAAAAAgAAAAEAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABAAAABAAA + AAYAAAAKAAAADgAAABQAAAAZAAAAHQAAACIAAAAmAAAAKgAAAC0AAAAuAAAALgAAACwAAAAoAAAAJAAA + AB4AAAAXAAAAEgAAAA0AAAAJAAAABQAAAAIAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAABAAAAAgAAAAUAAAAJAAAADwAAABQAAAAYAAAAGgAAACUAAQE3AQEBRAEB + AU0BAQFQAAEBTAAAAEYAAAA+AAAAPQAAAD0AAAA6AAAAMwAAACsAAAAjAAAAGwAAABMAAAANAAAACQAA + AAUAAAACAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAQAAAAIAAAADQAA + ABIAAAATAAAAIRAREUkuLi6DTk1NsHBsbNN9eHjqhoGB9oN+fvN3c3PiYV9fzD08PK0fHx+EAAEBXAAA + AEoAAABGAAAAQgAAADkAAAAvAAAAJAAAABsAAAASAAAACwAAAAcAAAADAAAAAgAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAQAAAAIAAAAFAAAACwAAAA8AAAAPAgICJicoKG1cWlq9iYOD9qaenv+zqan/taqq/7es + rP+4ra3/ua2t/7itrf+3rq7/tKur/56YmP93c3PpPT09sg4ODnUAAABRAAAASwAAAEUAAAA6AAAALQAA + ACEAAAAXAAAADwAAAAgAAAAEAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAADAAAABwAAAAwAAAAMAQEBGygo + KG1oZmbUnpaW/7OoqP+2qqr/sqam/7asrP+/trb/x8C//83Gxf/LxMP/x7++/7+1tf+4ra3/uq+v/72y + sv+0q6v/jIeH90ZFRb0MDAx1AAAAUwAAAE4AAABDAAAANQAAACgAAAAcAAAAEgAAAAsAAAAGAAAAAwAA + AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAABAAAABAAAAAgAAAALAAAADBscHEtgXl7DnZWV/7Spqf+zqKj/s6io/8S8vP/Y0tH/2dLN/8nC + vf+zqqv/p5ye/6qfof+5sK//0MnD/9rU0f/Tzc3/wbi4/7mvr/+/tbX/t6+v/4WBgfQ2NjatAgICZQAA + AFIAAABLAAAAPQAAAC4AAAAhAAAAFQAAAAwAAAAHAAAAAwAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAQAAAAJAAAACQYHBxs/Pz+KioaG9rKo + qP+zp6f/s6en/8vEw//g29f/xr67/5KGj/9uY3//YVeD/2Zelf9qZJ7/aGKc/2BYjP9hV33/eGp8/6OX + mP/TzMf/3tnX/8W9vf+7sbH/wrm5/62np/9mZWXeFBQUhAAAAFcAAABRAAAAQwAAADMAAAAlAAAAGAAA + AA8AAAAIAAAAAwAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAEAAAAFAAAACQAAAAYTFBQ1Y2JiwaScnP+1qqr/sKSk/8O6uv/i3Nr/xby5/4B0hf9gWIf/bGqw/4KC + z/+Ki93/kJHh/5CR4f+QkeP/jY/k/4aI3f96ecj/YVub/2FVdv+Wio7/1c7J/9vW1f/AuLj/wLe3/8C4 + uP+Nior5Li4uqAAAAF4AAABUAAAASAAAADgAAAAoAAAAGgAAAA8AAAAIAAAAAwAAAAEAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAABQAAAAkAAAAGHyAgVXp3d+ewpqb/s6io/7Wq + qv/a1dP/1s/K/4h8iP9dVYn/dHO+/4qL2/+Oj97/jIzc/4yM2/+MjNz/jIzc/4uM3f+Ljd//jI3g/42O + 5P+PkOj/hYXb/2Zhpf9dUHH/opWV/+Ld2v/Qysr/vrW1/8a9vf+ooqL/SEhIxwICAmkAAABWAAAASwAA + ADsAAAAqAAAAHAAAABAAAAAIAAAAAwAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAA + AAUAAAAHAAAACTc4OHSOiYn4tqur/7Glpf/BuLj/5eDd/7KoqP9hV37/ZGOv/3x+1P+Agtb/f4DU/4CA + 1f+Bgdf/goLZ/4WF2v+Ghtv/h4jd/4mJ3v+KiuD/i4vh/4uL4f+NjeP/kJHo/4KE2f9dVpH/cGJ0/8zD + v//f29r/wrm5/8e9vf+4sbH/YF9f2gsLC3cAAABWAAAATgAAADwAAAArAAAAHAAAABAAAAAIAAAAAwAA + AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAEAAAABgAAAAxBQUGJmZOT/7arq/+wpKT/zcbG/+Pe + 2P+Kfoz/U02O/2hpxf9zdNH/cXLO/3Fyz/9zdND/dHTS/3Z11P93d9X/eHjX/3t72P99fdv/f3/c/4CA + 3f+Dg+D/hobg/4iH4P+JieH/jI7l/46Q6P9wb7z/V0tw/6mdnP/n4t//ycHB/8a9vf/Curr/cW9v5g4O + Dn8AAABYAAAATwAAAD0AAAAsAAAAHAAAABAAAAAIAAAABAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAABQAA + AAUAAAAMR0ZGmp+YmP+3q6v/saam/9jS0f/X0Mv/bmOB/05MoP9jZcn/ZWbJ/2RlyP9lZsr/ZmfL/2do + zv9pac//amrR/2tr0v9ubtX/cHDX/3Jy2P90dNn/dXXb/3h43f97e93/fX3e/4CB3/+Dg+D/hofi/42O + 6f+Cg9n/Vk2C/4t+hP/k4Nz/0MrK/8W8vP/Gvr7/fXt77xISEoYAAABYAAAAUAAAAD4AAAArAAAAGwAA + AA8AAAAIAAAAAwAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAQAAAAFAAAAC0hHR5qmnp7/t6ur/7Opqf/g29n/y8K+/1xT + fv9JSaz/WlvE/1hZwv9YWcP/WFnF/1pbxv9bXMn/W1zK/11czP9eXs7/YGDQ/2Fh0f9kZNT/ZWXV/2ho + 1/9qatn/bW3Z/29v2v9yctz/dXXd/3h43f97fN//f4Dg/4WH5f+GiOT/W1aX/3dodP/e2dT/1tDQ/8a9 + vv/Mw8P/gX5+7xESEoYAAABYAAAATwAAADwAAAArAAAAGgAAAA8AAAAHAAAAAwAAAAEAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAABQAA + AAtISEiZpp6e/7esrP+zqar/497b/8K5tf9PR3//QUOv/01Pvv9MTbz/S02+/0xNv/9NTsL/Tk/E/09Q + xv9QUMf/UVHJ/1NTy/9UVM3/V1bQ/1lZ0f9aWtP/XFzV/19f1v9hYdf/ZGTY/2dn2f9qatn/bW7b/3Bx + 3P9zdd3/d3nf/3x+4v+Chuj/Xlyn/2tcbP/b1M//2tTU/8i/v//NxcX/gX9/7xISEoYAAABYAAAATgAA + ADsAAAApAAAAGQAAAA0AAAAGAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAABAAAAAwAAAAUAAAAFQ0NDj6Sdnf+4rKz/tKqq/+Pf3P++trb/RD2A/zo7 + rf9BQ7f/QUK2/0FBuP9AQbv/QUG8/0JDvv9DQ8D/REPC/0VExf9GRsf/R0fJ/0lJy/9KSsz/TU3P/05O + 0f9RUdP/U1PT/1ZW1P9ZWNX/W1vW/15f2P9hY9j/ZWba/2lq2/9sbt3/cHLe/3V34f99gej/XVyu/2BR + av/UzMf/29bW/8nBwf/Oxsb/e3l57QwMDH0AAABYAAAATQAAADkAAAAmAAAAFwAAAAwAAAAFAAAAAgAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAFAAAAAkA/ + P3ufmJj/uK2t/7Sqqv/k393/wbm4/0A7gv8tMKr/Njey/zU2sf81NrL/NTW1/zU1tv82Nrn/Nja7/zg4 + vf84OL//OjrB/zs7xP88PMb/PT7J/0A/yv9CQsz/Q0PP/0VF0P9ISND/S0rR/01N0/9RUdT/VFXV/1ZY + 1v9aXNj/XWDZ/2Fk2/9maN3/aWzd/25y4P91euj/XF20/19Qaf/Vzsj/29fX/8vDw//LxMT/cnBw5QkK + CnYAAABXAAAASgAAADYAAAAkAAAAFQAAAAsAAAAEAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAEAAAACAAAABQAAAAA2NjZjl5KS/biurv+0qqr/49/c/8W9uv88NoD/IyWk/ysr + q/8qKqv/Kiqt/ykqsP8pKrL/Kiq0/yortf8rK7j/LCy6/y0tvf8uLr7/MDDB/zAxw/8xMsX/NDPI/zU1 + y/84OMz/OjrN/z09zv8/QM//QkLQ/0VF0f9IStL/S07U/05R1f9SVdf/V1na/1te2/9fYtz/Y2fe/2ds + 4f9wduj/VVey/19Raf/e2NH/29bW/87Hx//Jw8P/YmBg2gMEBG0AAABWAAAARwAAADIAAAAhAAAAEwAA + AAkAAAAEAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAUAAAAAIiIiSY2J + ifG5r6//s6mp/97Z1//QyMX/Qjt8/xcZnP8fIKX/HyCl/x4fqP8eH6r/Hh+s/x4frf8eH7D/Hh+y/x8h + tP8gIbf/IiG5/yMjvP8jJL7/JCXB/ycnwv8pKcX/KirJ/ywsyf8vL8n/MTLL/zQ1zP83OM3/OzvO/z0/ + 0P9AQ9L/REfU/0hL1f9LT9b/T1TZ/1RZ2/9YXt3/XGPf/2Fo4v9ocOn/T1Cq/2pbbP/h3Nf/2tTU/9HK + yv/Dvr7/Tk5OyAAAAGMAAABUAAAAQwAAAC8AAAAeAAAAEAAAAAcAAAADAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAEAAAADAAAAABQVFSt8eXniua+v/7Opqf/Y0tH/3NXP/0lCf/8MDpX/FBWf/xMU + n/8TFKH/ExSk/xMUpv8SE6f/EhOq/xITrP8SE6//FBSx/xQUtP8VFbb/Fxe5/xcYu/8YGb7/GxvB/x0c + w/8eHsX/ISHG/yMjx/8mJ8j/KSrJ/ywty/8vMMz/MjTO/zY40P85PNH/PEHU/0BG1v9FStj/Sk/Z/05U + 3P9TWd7/Vl7g/1xk5P9jbev/SEih/3Zncv/n49//1tHR/9XOzv+4tLT/OTk5tAAAAF0AAABSAAAAPwAA + ACsAAAAaAAAADgAAAAYAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAELCwsSamhoxras + rP+1qqr/z8jH/+nj3P9cU4T/BQeM/wsNmv8MDZr/DA2d/wwNn/8MDaH/DA2j/wsMpf8LDKj/Cwyr/wsM + rf8LC6//Cwuy/wwMtP8MDbf/DA25/w0Ou/8PD77/ERHA/xMTw/8VFcP/FxjE/xobxv8dHsf/ISLI/yQm + yv8nKcz/Ky3N/y8z0P8yN9L/NjvU/zpA1v8/Rdn/REvb/0hQ3f9NVeD/UVvi/1hh5v9daOn/QT+S/4h5 + fv/s6eX/083N/9jR0f+ppaX/IyMjnAAAAFgAAABPAAAAOgAAACcAAAAXAAAACwAAAAUAAAABAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAIAAAADAAAAA0tKSpuupaX/uK2t/8S8vP/w7OT/d26P/wgJh/8LDZf/DQ+Z/w0O + m/8NDp3/DQ6g/w0Oov8NDqT/DA2n/wwNqf8MDar/DA2t/wwNr/8MDLL/Cwu1/wsLtv8KC7n/Cgu7/woK + vf8KCr//CgrA/wsLwP8MDcH/DxDD/xITxP8WF8X/GBvI/xwfyv8gIsv/JCjO/ygt0P8rMdL/LzfU/zQ8 + 1/85Qdr/PUfc/0JN3v9HUuH/TVjj/1Nf6v9UYeb/Pjl//6GTkf/v6+r/08zM/9rT0/+MiorzDxAQgwAA + AFcAAABKAAAANQAAACIAAAATAAAACQAAAAMAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAABAAAAAA8PT1uoZub/7uw + sP+9s7P/8u3o/5iQof8QEIL/CQyV/w0Pl/8ND5n/DQ6c/w0Onv8OD6H/Dg+j/w0Opf8NDqj/DQ6p/wwN + rP8MDa7/DA2x/wwMs/8MDLX/DAy3/wsMuv8LC73/Cwu//wsLwf8LC8H/CgrB/woLwf8KC8H/CwzD/wwN + w/8NEMX/EBTH/xUZyv8ZHcv/HSLO/yEo0f8kLdP/KTLW/y442P8zPtv/OUPe/z1K4f9CUOP/SFXm/09e + 7f9MWd3/Qjhv/7uxrf/q5+b/1M3N/9XQ0P9tbGzgAwQEbQAAAFQAAABEAAAALwAAAB0AAAAPAAAABwAA + AAIAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAMAAAAAISIiO46JifC9srL/t66u/+rm4v+6srf/IB1//wgKk/8OEJb/DhCY/w4Q + mv8OD5z/Dg+e/w4PoP8OD6P/Dg+m/w0OqP8NDqv/DQ6t/w0OsP8NDbH/DQ2z/w0Ntv8MDbj/Cw27/wwM + vf8MDMD/CwvB/wsLwf8LDML/CwzC/wsNwv8MDcL/Cw3D/wsOxf8LD8b/DBHI/w4Uyf8SGMz/Fh3P/xsi + 0f8fKdX/Iy/Y/yg02/8uO93/NEHh/zhH5P89Tub/RFTp/0te8/9CTs//T0Fm/9bOx//k4OD/2NLS/8nF + xf9HR0fCAAAAXwAAAFIAAAA/AAAAKgAAABkAAAAMAAAABQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAA8QEBRwbm7Mua+v/7es + rf/b1tX/29TQ/zs2gP8GCI//DxCU/w4Qlv8OEJj/DxCb/w8Qnf8PEJ//DxCi/w8QpP8OD6b/Dg+p/w4P + q/8OD63/Dg+w/w4Osf8NDbT/DQ22/wwNuf8MDbv/DAy9/wwMwP8MDMH/DAzB/wwNwv8MDcL/DA3C/wwN + w/8MD8T/DBDF/w0Rx/8NEcj/DBLK/w0Uy/8NFc7/ERnR/xUf0/8aJtf/Hiva/yQy3f8pOOD/Lz/j/zRG + 5/85TOn/QFPt/0dd9v84QLP/aFhr/+jj3v/d2Nj/3dfX/7Ovr/8nJyefAAAAVwAAAE4AAAA4AAAAJAAA + ABUAAAAKAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAMpKSkATExMlbCnp/+6sLD/y8XE/+/r4/9iW4z/BwmK/w8Qkv8PEZP/DxGW/w8R + mf8PEZv/DxCe/w8QoP8PEKP/DxCk/w4Ppv8OD6n/Dg+r/w4Prf8OD7D/Dg6z/w4Otf8ODrf/DQ65/w0N + u/8MDL7/DQ3A/w0Nwf8MDMH/DAzC/wwNw/8NDsP/DQ7E/w0Pxf8NEMb/DRHI/w0Syf8NFMr/DhXN/w4W + zv8OF9H/DhnT/xAd1v8UItn/GSnc/x4v4P8lN+P/Kz7m/zBF6v82S+7/PFPy/0FZ9/8yNJP/i3yA//Dt + 6v/a1NT/4NnZ/4yKivINDQ1+AAAAVgAAAEcAAAAxAAAAHwAAABEAAAAHAAAAAgAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAACkpKVGclpb/vbOz/761 + tf/08ev/koui/w4PhP8ND5D/EBGR/w8RlP8PEpf/EBKZ/xARm/8QEJ3/DxCg/w8Qo/8PEKX/Dg+n/w4P + qv8OD6v/Dg+u/w8PsP8PD7P/Dw+1/w4PuP8NDrr/DQ27/w0Nvv8NDcH/DQ3B/w0Nwf8NDcL/DA3C/w0P + xP8ND8T/DRDG/w0Rx/8OEsj/DhPJ/w4Vyv8OFs3/DxbQ/w8Z0f8PGtT/DxvW/w8e2P8RIdz/FSff/xou + 4/8gNef/Jz3q/y1E7v8yS/H/OVX5/zpS7/83MHT/t6um/+7r6v/b1dX/2NPT/19fX9UAAABkAAAAUwAA + AEAAAAArAAAAGQAAAA0AAAAFAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAgAAAAATExMeenh42b60tP+5r6//6OTh/8W+wv8jIYH/Cg2N/xETkP8REpP/EBKV/xAS + mP8QEpn/EBKb/xARnv8QEaD/EBGj/xARpf8PEKf/DxCq/w8QrP8PEK7/DxCx/w8Ps/8PD7b/Dw+4/w4P + uv8OD73/Dg6//w0Nwf8ODsH/Dg7B/w0Owv8NDsL/Dg/E/w4QxP8OEcb/DhLH/w4TyP8OFMn/DxXM/w8W + zv8QF8//EBnS/xAb1f8QHtf/ESDZ/xEh3P8RI9//Eifj/xct5v8cNOr/Izzu/ylE8v8wTPX/N1b//zBD + 1P9OQGb/29PM/+bj4//h29v/wL29/zExMasAAABZAAAATgAAADgAAAAkAAAAFAAAAAkAAAADAAAAAQAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAACKisrAFBPT5y1rq7/u7Cw/9PO + zf/q5d//S0WI/wcJif8RE47/EROQ/xESkv8RE5X/EROY/xETmv8QEZz/ERGf/xESoP8REqP/ERKl/xAR + qP8QEar/EBGs/xARr/8QELH/Dw+z/xAPtf8QELj/DxC7/w4Pvf8ODr//Dg7B/w4Owf8ODsH/Dg/C/w4P + wv8PD8T/DxDE/w4Rxv8OEsf/DxPJ/w8Vy/8PFsz/EBbN/w8Y0P8QGtL/ER3V/xEf2P8RINr/EiPc/xIl + 4P8SJ+P/Eyrn/xQt6/8YNO7/Hzzy/yZE9/8tS/r/MlL//ycxq/91ZXH/7+vn/9/b2//k39//lpOT9Q4O + DoEAAABVAAAARwAAADEAAAAeAAAAEAAAAAcAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAwAAAAAqKytRoJqa/7+1tf/Cubn/9/Tu/4N8nv8JC4X/EBKN/xIUjv8SFJH/EhOS/xET + lf8RE5j/EROa/xESnf8REp//ERKh/xESo/8REqX/EBGo/xARqv8QEaz/EBGv/xARsf8QELP/EBC1/xAQ + uP8PELv/DxC9/w8PwP8PD8L/Dg7C/w8Pwv8PD8L/Dg/C/w8QxP8PEcT/DxLG/w8Tx/8QFMn/DxXL/w8W + zP8QF83/EBnQ/xEb0v8RHNX/ER7Y/xIh2/8SJN3/EyXg/xMo4/8UK+f/FC7r/xQw7/8XNPP/HDz3/yND + +f8pSfz/LEn2/yspgv+qnZr/8vDv/9/a2v/d2Nj/YWBg1wAAAGMAAABSAAAAPwAAACkAAAAYAAAADAAA + AAQAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAEBERFnh1ddS/tbX/u7Gx/+vo + 5f/Cu8L/HRuE/w0Pjf8SFIz/EhSO/xIUkP8TFJP/EhSW/xETmP8RE5r/EhOd/xITn/8SE6L/EhOk/xIT + pv8REqj/ERKq/xESrP8REq//ERKy/xERtP8QELb/EBC4/xARuv8QEL3/EA/A/w8Pwv8PD8L/Dw/D/w8Q + w/8PEMP/DxHD/xASxP8PEsb/DxPH/xAUyf8QFsr/ERfN/xEYzv8QGc//ERzS/xIe1f8SINj/EiHb/xIk + 3f8UJuD/FCnj/xQr5/8VLuv/FTHv/xYz8v8WNvb/GTv4/x9A+f8mSP//Ijrd/0I2Z//Y0Mj/6+jo/+Xg + 4P/Cvr7/LS0tpQAAAFgAAABMAAAANgAAACIAAAATAAAACAAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAiIjIwBKSUmKs6ur/72zs//Uzs7/7Ojj/0pFi/8IC43/EhWN/xIUjP8TFY7/ExWR/xMU + lP8SFJb/EhSY/xIUmv8SE53/EhOf/xITof8TFKT/ExSm/xITqP8SE6v/EhOs/xESr/8RErL/ERG0/xER + tv8REbj/EBG6/xARvf8QEL//EBDC/xAQwv8QEML/EBHD/w8Qw/8PEcP/EBLE/xATxv8QFMf/ERXJ/xAV + yv8QF83/ERjP/xIZ0P8SHNL/Eh7V/xIg1/8TIdv/EyTd/xQn4P8UKeP/FSvn/xUu6v8WMO7/FjPy/xY2 + 9f8XOPj/Fzn4/xw++f8iRf//HCeu/3Zmcv/w7un/49/g/+jk5P+OjIzxCQoKeQAAAFQAAABEAAAALgAA + ABsAAAANAAAABgAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAIiMjOZWRkffCuLj/wbm5//bz + 7f+Oh6T/DQ6J/xEUkf8TFY3/ExWM/xMVjv8UFpH/ExSU/xIUlv8TFZn/ExWb/xMVnf8TFJ//ExSh/xMU + o/8TFKb/EhOp/xITq/8SE63/EhOu/xITsf8SErT/EhK2/xESuP8QEbv/ERG9/xERv/8QEML/EBDC/xAQ + wv8QEcP/EBHE/xESxP8RE8X/EBPG/xAUx/8RFcj/ERbL/xIXzf8SGM//ERnQ/xIc0f8THtT/EyDX/xMh + 2v8TJN3/FCfg/xUo4/8VK+b/Fi3p/xYv7f8WM/H/Fjb0/xc4+P8XOPj/Fzj4/xo8+/8cO/T/JyR9/7Kl + n//z8fD/5eDg/9vX1/9PTk7FAAAAXQAAAFAAAAA7AAAAJgAAABQAAAAJAAAAAwAAAAEAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAABAAAAAQMDAwVmZma5vbS0/72zs//l4d//z8jK/yYkh/8ND5P/FBaR/xQWjv8UFo3/FBaP/xQW + kf8UFZP/ExWW/xMVmP8TFZv/FBWd/xQVn/8UFaL/FBWj/xQVpv8TFKn/ExSr/xMUrf8TFK//ExSx/xMT + s/8SErb/EhK5/xESu/8REr3/ERG//xERwf8REcL/EBDC/xERw/8REsT/EBLE/xESxf8RFMf/ERXH/xIV + yP8SF8r/ERfL/xIYzv8SGtD/ExzR/xMd1P8TINf/FCLZ/xQj3P8UJt//FSji/xUq5P8WLOj/Fi/r/xYx + 7/8WNPL/Fzf1/xc5+P8XOfj/Fzj4/xg8//8TKtP/TT9n/+Lb1P/r6Oj/7Ofn/7Gvr/8ZGRmQAAAAVQAA + AEgAAAAxAAAAHgAAAA8AAAAGAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAOTk5XqagoP/BuLj/zcbG//Pv + 6P9gWpP/CAuR/xMVlP8UFpH/FBaO/xQWjf8VF4//FBaR/xQVlP8UFpb/FBaY/xQWm/8UFp3/FBWg/xQV + ov8UFaP/FBWm/xMUqP8TFKv/ExSt/xMUr/8TFLL/ExOz/xMTtv8TE7j/EhO7/xESvf8REb//EhLB/xIS + wv8REcL/ERLD/xESw/8REsT/EhPF/xIUxv8RFMf/ERbI/xIXyf8SF8z/ExnO/xIaz/8TG9L/Ex7U/xQg + 1v8UItj/FCTb/xQl3v8VKOH/FSrj/xYs5v8WLur/FjDt/xYy8P8XNfP/Fzf1/xc5+P8XOfj/Fzj5/xU4 + /v8UHZ3/i3yA//b08f/n4+P/6OTk/29ubtwAAABnAAAAUgAAAD8AAAApAAAAFwAAAAoAAAAEAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAABAAAAABISEhR+e3vTw7q6/7+3t//w7Oj/q6S1/xUViv8QEpj/FRaU/xUXkf8VF4//FReM/xUX + j/8VF5H/FRaU/xQWlv8UF5j/FReb/xUWnP8VFZ//FBWi/xQVo/8UFab/FBWo/xMUqv8TFK3/ExSv/xMU + sv8UFLT/FBS1/xQUuP8SE7r/EhO9/xISv/8SEsH/EhLC/xISwv8SE8L/EhPD/xESxP8SFMX/EhTG/xIV + x/8SFsj/EhfK/xIXy/8TGcz/ExrO/xMc0f8THdT/FB/U/xQi1/8UI9r/FSXd/xUo4P8WKeL/Firl/xYt + 6P8WL+r/FjHt/xYz8P8WNPP/Fjb0/xc39f8XN/b/Fjj6/w8s5/8wKGz/zMO7//Lw8P/s6Oj/ycbG/ywr + K6QAAABXAAAASwAAADQAAAAfAAAAEAAAAAcAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEUFRUARkZGe7Krq//BuLj/19HQ/+bh + 3P9DP43/Cw6Y/xQWmP8VFpX/FRaS/xUXj/8WGI3/FReP/xUXkf8WF5T/FheW/xUXmP8VF5v/FRec/xUW + n/8VFqH/FRaj/xUWpv8VFqj/FBWq/xQVrf8UFa//FBWx/xQUtP8UFLb/FBS3/xQUuv8TFLz/EhK//xIS + wf8TE8L/EhLC/xISwv8SE8P/EhPD/xMUxP8TFMb/EhXH/xIWyP8TF8r/ExfL/xMYzP8TGs//FBzR/xQd + 0/8UH9T/FCDW/xUj2f8VJdv/FSfe/xYp4f8WKeP/Fivm/xYu6P8WL+r/FjDt/xYy7/8WM/H/FjTy/xY0 + 8/8WNPP/FTT5/wwatf9sXXD/8e7p/+vn6P/u6ur/iYiI6wQEBHEAAABTAAAAQAAAACsAAAAYAAAACwAA + AAQAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAABAAAAABQVFR+Jhobmxby8/8S8vP/z8Or/kImm/w4Pkf8TFZz/FReY/xUXlf8WF5P/FhiP/xYY + jv8WGI//FhiR/xYXk/8WF5X/FhiY/xYYm/8VF5z/Fhef/xYXof8WF6P/Fhel/xYXqP8VFqv/FRat/xUW + r/8VFrD/FBSz/xQUtv8VFbj/FBW5/xMUvP8TE77/ExPB/xMTw/8TE8P/ExPD/xMUxP8SFMT/EhTE/xMV + xv8TFcb/ExfI/xMXyf8TGMv/ExnM/xQazf8UG8//FB3S/xQf1P8VINb/FSLX/xUj2v8VJtz/Fijf/xYo + 4v8WKeP/Fivl/xYt6P8WLur/FjDs/xYx7f8WMe7/FjHv/xYw7/8WMfH/ECvs/x8dff+3qqX/9/b1/+3p + 6f/Z1dX/PDw8tQAAAFkAAABMAAAANgAAACEAAAARAAAABwAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEWFhYATUxMjLqxsf/CuLj/39rZ/9fR + z/8wLo3/Dg+e/xUXnP8VF5n/FReW/xYXk/8XGJD/FxmO/xcZjv8XGZH/FxiU/xcYlv8WGJf/Fhia/xYY + nf8WF5//Fheh/xYXo/8WF6X/Fhen/xUWqv8VFq3/FRau/xUWsP8VFrL/FRW1/xUVuP8VFbr/FBW7/xQV + vf8UE8D/FBTC/xQUw/8TE8P/ExTE/xMUxP8TFMT/FBXF/xQWxv8TFsf/FBjJ/xQYyv8UGMz/FBnM/xQb + zv8UHdD/FR7T/xUf1f8VIdf/FSLY/xUk2v8WJt3/Fifg/xYo4v8WKeP/Fivl/xYs5v8WLef/Fi7q/xYu + 6v8WLuv/Fi7r/xUu6v8UL/D/CxvC/1dJav/s5uD/8O3t//Lv7/+ZmJjyCgoKeAAAAFMAAABCAAAAKwAA + ABkAAAALAAAABAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAABAAAAABYWFimQjIzxyL6+/8nBwf/08Or/fnig/wwOl/8VFqD/FRec/xYYmv8WGJf/FxiU/xcZ + kf8XGY7/FxmO/xcZkf8YGZT/GBmV/xYYmP8WGJr/Fxmc/xcYnv8XGKD/Fxij/xcYpv8XGKj/Fhep/xYX + rP8WF67/Fhew/xYXsv8VFbT/FRW3/xYWuv8VFrv/FBW8/xQUv/8UFML/FBTD/xQUw/8UFMT/FBXE/xMV + xP8UFcT/FBbG/xQWxv8UF8j/FBjJ/xQYy/8UGcz/FBvN/xQcz/8VHdH/FR/U/xUg1f8VItf/FSPY/xYk + 2v8WJ93/Fiff/xYo4f8WKeL/Firk/xYr5f8WK+b/Fizn/xYr5/8VK+f/FSvn/xQr5/8QJuj/GBmI/6ib + mP/5+Pb/7+zs/+He3v9GRka+AAAAWQAAAEwAAAA2AAAAIQAAABEAAAAHAAAAAgAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEWFhYATk1Nk7y1tf/Durr/49/d/8zF + yf8oJo//EBKj/xYXoP8WF53/Fhia/xYYl/8XGJX/GBmS/xgaj/8YGo7/GBqQ/xgakv8YGZX/FxmY/xcZ + mv8XGZz/Fxie/xcYof8YGaL/GBml/xgZp/8XGKn/Fxis/xcYrf8WF7D/Fhez/xYWtP8WFrX/Fha4/xYW + u/8VFr3/FRW//xUVwf8VFcP/FBTD/xQUw/8UFcT/FBXF/xQWxf8UFsX/FBbG/xQXx/8VGMj/FRnK/xQZ + zP8VGs3/FRzO/xUcz/8VHtL/FR/U/xUh1f8VItf/FSPY/xYl2v8WJtz/Fife/xYo4P8WKOH/Fini/xYp + 4/8WKuP/FSrj/xUq4/8UKeP/FCji/xQo5v8KGcf/Sj5r/+bg2P/z8fH/9fLy/56dnfcLCwt8AAAAUgAA + AEEAAAAqAAAAGAAAAAsAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAABYWFimRjY3xycDA/8vDw//x7eb/dG+d/wwOnP8WF6T/Fheh/xYYnv8XGZv/FxmY/xgZ + lf8YGpP/GBqP/xgajv8ZG5D/GRuT/xgZlf8YGZf/GBqZ/xgam/8YGp7/GBmg/xgZof8YGaT/GBmm/xgZ + qf8XGKv/Fxit/xcYr/8XGLH/Fxi0/xcXtv8WFrf/Fhe6/xUXvP8VFb7/FRW//xUVwv8VFcP/FRXD/xUV + xP8UFcT/FBXF/xUWxf8VF8f/FRjH/xQYx/8VGcn/FRnK/xUazP8VG87/FRzO/xUd0P8VHtL/FR/U/xYh + 1f8WItf/FSPY/xYk2f8WJdv/Fibd/xYn3v8WJ9//FSjg/xUo4P8VKOD/FSjh/xQm4P8TJuD/EyXf/w8i + 4v8UFYz/oJOU//z6+P/y7+//4+Dg/0ZGRr8AAABZAAAASwAAADUAAAAgAAAAEAAAAAcAAAABAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wAVFRUAFRUVABUVFQAVFRUAFRUVABUVFQAVFRUATk1Nkr22tv/FvLz/497c/8rD + xv8pKJP/EBKn/xcYpP8XGKH/Fxie/xcZm/8XGZn/GBmX/xkalP8ZG5H/GRuO/xkbkP8ZG5P/GRqV/xka + lv8YGpn/GRuc/xkanv8ZGZ//GRqi/xkapP8ZGqb/GBmp/xcYq/8YGa3/GBmu/xgZsf8XGLP/Fxe2/xcX + t/8XF7j/Fxe7/xYXvv8WFcD/FhbC/xYWw/8VFcP/FRXE/xUWxP8VFsT/FRbF/xUXxv8VGMf/FRjH/xUZ + yP8VGcr/FRnL/xUbzf8VG87/FRzO/xUd0P8WH9L/FSDU/xYh1f8WIdf/FSPX/xYk2f8WJNr/FSTb/xUl + 3P8VJtz/FSbe/xQm3v8UJt7/FCXe/xMj3f8SI9z/EiPf/wkWxv9KP27/5uHZ//b09P/49vb/n56e9wsL + C3sAAABRAAAAQAAAACkAAAAWAAAACgAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////ABUVFQAVFRUAFRUVABUV + FQAVFRUAFRUVABUVFSCRjY3rysHB/8zFxf/x7eb/dnGf/w0OoP8WF6n/Fxil/xcYov8XGJ//GBqd/xga + mv8YGpf/GRqV/xkbkv8ZG4//GhuP/xobkv8aG5T/GhuW/xkbmf8ZG5v/GRuc/xkbn/8ZGqL/GRqk/xka + pv8ZGqf/GBmq/xgZrf8YGa//GBmw/xgZsf8YGLT/GBi3/xgYuf8XGLv/Fhe8/xYWv/8WFsL/FhbD/xYW + w/8WFsP/FhbE/xUWxP8VF8X/FhfF/xYYx/8VGMf/FRnH/xUZyf8WGcr/FRrL/xUbzf8WHM7/FRzP/xUe + 0P8WH9H/FSDT/xUh1f8WIdb/FSHX/xUi1/8VI9n/FSPZ/xUk2f8VJNv/FCTa/xQj2v8UItr/EyLa/xMh + 2v8SINn/Dh3d/xUVjv+hlJX//fz6//Xy8v/k4uL/QEBAtwAAAFgAAABKAAAAMwAAAB0AAAAOAAAABQAA + AAEAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8AERISABESEgAREhIAERISABESEgAREhIASEhIfLu0tP/Gvr7/497d/83G + yP8rKZT/ERKr/xYYqP8XGab/GBmj/xgZoP8YGp7/GBqb/xgbmP8aG5b/GhuS/xobkP8aG4//GhuR/xob + lP8aG5b/GhyZ/xocm/8aHJ3/GRue/xkaof8ZGqP/GRql/xkaqP8ZGqn/GBmr/xgZrv8ZGrD/GRqx/xgZ + s/8YGLb/GBi5/xgYuv8XGLv/Fxe9/xcWwP8XF8L/FhbD/xYWw/8WFsP/FhfE/xYXxf8WF8X/FhjG/xYY + x/8WGcf/FRnI/xYZyf8WGsr/FRrL/xUbzf8WHM7/FRzP/xUe0P8WHtD/Fh/T/xUg1P8VINX/FSHW/xUh + 1v8VItf/FSLX/xQi1/8UIdj/EyDY/xMg2P8TINf/Eh/X/xIe1v8RHdn/CBK//01Bbf/o4tr/9/b2//r4 + +P+Uk5PvBAQEcQAAAFAAAAA8AAAAJQAAABQAAAAIAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAA////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wAREhIAERISABES + EgAREhIAERISABESEhCFgoLbysLC/8zExP/w6+X/gXuj/w4Qof8WF63/Fxmp/xgZpv8YGaT/GRmh/xka + nv8ZG5z/GRua/xobl/8aG5T/GxyR/xsckP8aG5H/GxyU/xsclf8bHJj/Ghya/xocnf8aHJ7/Ghug/xob + o/8aG6X/Ghuo/xobqf8ZGqr/GRqt/xkar/8ZGrL/GRqz/xkZtf8YGLf/GBi5/xgZu/8XGLz/Fxe+/xcX + wf8XF8P/FxfE/xcWw/8WFsP/FhfE/xYXxP8WF8X/FhjG/xYYx/8WGcj/FhnI/xYZyf8WGcr/FRrL/xUb + zf8WG87/Fh3O/xUdz/8VHtD/FR7R/xUf0v8VH9P/FR/U/xUf1f8UH9X/FCDV/xQg1f8UH9X/Ex/V/xIe + 1P8SHdT/EhzT/xEb0/8MF9b/GReH/6ygnf/+/Pv/+ff3/9vY2P8wMDCnAAAAUwAAAEUAAAAuAAAAGgAA + AAwAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AAIDAwACAwMAAgMDAAIDAwACAwMAMzMzW7Ourv/KwcH/3trZ/9fR + z/82NJb/EBKv/xcYrP8XGKr/GBqo/xkapf8ZGqL/GRqf/xkbnP8aHJr/GhyX/xsclf8bHJP/GxyQ/xsc + kf8bHJT/HB2W/xsdmP8aHJr/Gh2b/xsdnv8bHKD/Gxyi/xscpP8bHKX/Gxyo/xobq/8ZGqz/GRqu/xob + sf8aG7L/GRq0/xkZtv8ZGbj/GRm7/xgZvP8YGb7/GBe//xcXwv8XF8T/FxfE/xcXxP8XF8T/FhfE/xYY + xP8XGMX/FxjG/xYZx/8WGcj/FhnJ/xYZyf8WGcr/FhrL/xUbzP8WG87/FhzO/xYdz/8VHc//FR3P/xUd + 0f8VHdL/FR7S/xQe0/8UHtP/FB7T/xMe0/8THdP/ExzS/xIc0f8SGtH/EBrQ/xAZ1P8HDrT/XFBz//Ht + 5//59/f/+vj4/3x7e98AAABkAAAATQAAADcAAAAhAAAAEAAAAAcAAAACAAAAAAAAAAAAAAAAAAAAAP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAgMDAAID + AwACAwMAAgMDAAIDAwFvbW25ycLC/8vDw//u6+X/l5Cr/xMUov8WF7L/GBmt/xgZq/8YGqj/GRqm/xoa + o/8aG6D/Ghye/xocm/8aHJn/GxyW/xwdk/8cHZD/HB2Q/xwdkv8cHZX/HB2Y/xwdmf8bHZv/Gx2d/xsd + oP8bHKL/Gxyk/xscpv8bHKj/Gxyp/xobrP8aG63/Ghuv/xobsv8aG7T/Ghq2/xoat/8aGrn/GRq8/xgZ + vf8YGb7/GBjB/xgYw/8YGMT/FxfE/xcXxP8XGMX/FxjF/xYXxf8XGMX/FxnG/xcZx/8WGcj/FhrJ/xYa + yf8WGcn/FhrK/xUbzP8VG83/FhvN/xUczv8VHM//FRzP/xUcz/8UHND/FBzQ/xQc0P8THNH/ExzR/xMb + 0f8TG9H/ERrQ/xEZz/8RGM7/EBfO/woSzv8jHnz/vrSu//79/P/7+Pj/xcTE/x4eHpEAAABQAAAAPwAA + ACgAAAAVAAAACQAAAAMAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wAmJycAJicnACYnJwAmJycAJicnM6KenvrNxsb/2NPS/+Tf + 2f9OS5r/Dg+v/xgZsv8YGa//GBms/xkaqf8aG6f/Ghuk/xobof8aHJ//Gx2c/xsdmf8cHZf/HB2V/xwd + kv8cHZD/HR6R/x0elP8dHpb/HR6Z/xwem/8cHp3/HB6f/xwdoP8cHaP/HB2l/xwdp/8cHan/Gxyq/xsc + rf8bHK//Gxyx/xscs/8aG7X/Ghq2/xoauP8aGrn/GRq8/xkavv8ZGMD/GBjB/xgYw/8YGMT/GBjE/xcX + xf8XGMX/FxjF/xcYxf8XGMX/FxnG/xcZx/8WGcj/FhrJ/xYayf8WGcn/FhnK/xYay/8VGsz/FRvN/xUb + zf8VG83/FRvO/xQbzv8UG87/FBvO/xMbzv8TGs7/ExrO/xIZz/8SGM7/ERfO/xEWzf8QFsz/DhbQ/woN + pv96bn//+fby//bz8//v7e3/WFhYyAAAAFgAAABGAAAAMAAAABsAAAANAAAABQAAAAEAAAAAAAAAAAAA + AAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAME + BAADBAQAAwQEAAMEBABLS0uGwru7/8vDw//o5OH/tq+6/x4en/8VFrf/GBmy/xkasP8ZGq3/GRuq/xkb + qP8bHKX/Gxyi/xscoP8bHZ7/Gx2b/xwemP8dHpb/HR6U/x0ekP8dHpH/HR6U/x0elv8dHpf/HB6a/xwe + nf8cHp7/HB6f/xwdof8cHaT/HB2n/xwdqP8cHan/Gxyr/xscrv8bHLH/Gxyy/xscs/8bG7b/Gxu3/xsb + uf8aGrr/GRq9/xkav/8ZGMD/GRjB/xgYxP8YGMT/GBjE/xgYxf8XGMX/FxjF/xcYxf8XGMX/FxjG/xcZ + x/8XGcj/FhrI/xYayf8WGcn/FhnJ/xYZyv8WGcr/FRrL/xUazP8UGs3/FBrN/xQazf8UGcz/ExnM/xMY + zP8SGM3/EhjN/xIXy/8RF8z/EBbM/xAWy/8PFcz/CA7F/zgwdP/a08v/+fj3//n29v+enZ31BgYGcQAA + AEsAAAA3AAAAIQAAABAAAAAGAAAAAgAAAAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8AAwQEAAMEBAADBAQAAwQECIJ/f9HPx8f/0crK/+3o + 4f9xbKH/Dg+t/xgYt/8ZGbP/GRqx/xkarv8aG6v/Ghyp/xscpf8bHKT/HByi/xwdn/8cHpz/HB6a/x0e + l/8dHpX/HR6S/x0ekP8dHpP/HR6V/x0el/8dHpn/HB6b/xwenf8cHp//HB2i/xwdo/8cHaX/HB2n/x0e + qf8cHar/Gxyt/xscr/8bHLD/Gxyy/xsctf8bG7f/Gxu5/xsbuv8aG7v/GRu9/xkav/8ZGcD/GRnC/xkZ + xP8YGMT/GBjE/xgYxf8YGMX/FxjF/xcYxf8XGMX/FxjF/xcZx/8XGcf/FhnI/xYZyP8WGcj/FhnI/xYZ + yf8VGcr/FRnK/xUZyv8UGMv/FBjL/xMYy/8TGMv/ExjL/xIXyv8SF8r/ERfK/xEWyf8RFsn/EBTJ/xAU + yf8MEcz/EhGQ/6CVlv/8+/n/9fLy/9bU1P8rKyufAAAATQAAAD8AAAAnAAAAFQAAAAkAAAADAAAAAAAA + AAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wAqKioAKioqACoqKgAqKio+q6am/c/Hx//f2tj/19DO/zg2nf8QErn/GRm3/xkZtP8aG7L/Ghuv/xob + rP8aHKr/Gx2n/xwdpf8cHaL/HB6f/xwenv8cHpv/HR6Y/x0elv8dHpP/Hh6R/x4fkv8eH5T/Hh+W/x4e + mf8eHpv/HR6c/x0en/8dHqH/HR6j/x0epf8eH6f/Hh+o/x0eqv8cHaz/HB2t/xwdsP8bHLL/Gxyz/xsc + tP8bG7b/Gxu5/xsbuv8bG7v/Ghu+/xoav/8ZGcD/GRnC/xkZxP8ZGcT/GBjE/xgYxf8YGMX/FxjF/xcY + xf8XGMX/FxjF/xcZxv8XGcf/FhnH/xYZyP8WGcj/FRnI/xUZyP8VGcn/FRnJ/xUZyf8UGMn/FBjK/xMX + yv8TF8r/ExfJ/xIXyP8SFsj/ERXI/xEVyP8QFMj/DxPH/w4Syv8HCrH/X1V5//Hu5//z8fH/8O3t/2Vl + Zc8AAABZAAAARQAAAC4AAAAZAAAACwAAAAQAAAABAAAAAAAAAAD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AAMDAwADAwMAAwMDAE5OToXHwMD/zsbG/+zo + 5P+moLT/GBim/xYXvf8ZGbj/Ghq1/xobs/8aG7D/Gxyt/xscq/8cHan/HB2m/xwdpP8cHqH/HB6e/xwe + nP8dHpr/Hh6X/x4flP8eH5H/HyCR/x8glP8fIJb/Hx+Y/x8fm/8fIJz/HyCd/x8gn/8fIKL/HyCl/x8g + pv8eH6f/Hh+q/x4frP8dHq3/HB2u/xwdsf8cHbP/HB20/xwctf8bG7f/Gxu5/xsbuv8aG7z/Ghu+/xoa + v/8aGcH/GRnC/xkZxP8ZGcT/GRnE/xgYxP8YGMX/GBjF/xcYxf8XGMX/FxjF/xcYxf8XGMb/FxjH/xYY + x/8WGMf/FRjH/xUYx/8UGMj/FBjI/xQYyP8TF8j/ExfI/xMXyP8SFsj/EhbI/xEVx/8QFcf/EBPG/xAT + xv8PEsb/DxHG/wgLxP8sJnn/z8fB//f19f/28vL/oqCg9QYGBnAAAABKAAAANQAAAB8AAAAPAAAABQAA + AAEAAAAAAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8AAwMDAAMDAwADAwMFfnx8y9DJyf/Uzc3/7Off/21oov8OELP/GRq8/xkauP8aGrf/Gxu0/xsc + sf8bHK//Gxys/xsdqv8cHaf/HB2l/x0eo/8dHqD/HR6d/x0fm/8fH5j/HyCW/yAhlP8gIZL/ICGT/yEi + lf8hIZj/ISGa/yAhm/8gIZ7/ICGg/yAhov8gIaT/ICGl/yAhp/8fIKr/HyCq/x4frP8eH67/Hh+v/x0e + sf8dHrP/HR61/xwctv8cHLf/HBu5/xwbu/8aG7z/Ghu+/xobv/8aGsH/GhnC/xkZw/8ZGcT/GRnE/xgY + xP8YGMX/GBjF/xcYxf8XGMX/FxjF/xcYxf8XGMX/FhjG/xYYx/8WGMf/FRfH/xUXx/8UF8f/FBfH/xQX + x/8TFsf/ExbH/xIVx/8SFcf/ERTH/xEUxv8RE8b/EBLF/xASxf8PEMT/DQ7I/xAPk/+flJf/+vj2//Lv + 7//Ny8v/KSkpmgAAAEsAAAA7AAAAIwAAABIAAAAHAAAAAgAAAAAAAAAA////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wAkJSUAJCUlACQlJSein5/208zM/97Z + 2P/Y08//Pz2f/xESvf8ZGr3/GRq6/xobt/8bHLX/Gxyy/xscsP8bHK7/Gx2r/x0eqP8dHqb/Hh+j/x4f + ov8fIJ//HyCd/yAgm/8hIZj/ISKW/yIik/8iI5P/IiSV/yIkmP8iIpr/ISKc/yEinf8iI5//ISKh/yEi + ov8hIqX/ISKn/yEiqP8hIqr/ICKs/x8grf8fIK7/HyCw/x4fsv8eH7P/HR61/x0ct/8cHLj/HBy5/xwc + u/8aG73/Ghu+/xobwP8aGsH/GhrC/xkZw/8ZGcT/GRnE/xkYxP8YGMX/GBjF/xcYxf8XGMX/FxjF/xYX + xf8WF8X/FhfG/xYXxv8WF8b/FRfG/xUWxv8VFsb/FBbF/xQWxf8TFcX/ExXF/xIUxv8SFMb/EhLF/xES + xf8QEsT/EBHD/w8Qw/8ND8b/CAms/2lefv/y8On/8O3t/+nl5f9RUFC/AAAAUQAAAEAAAAAoAAAAFQAA + AAkAAAADAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////ADY2NgA2NjYANjY2Zb65uf/Rycn/6OPh/7mzu/8mJqn/GRnD/xkavv8aG7v/Ghu5/xsb + tv8bHLP/Gxyx/xwdrv8cHqz/HB+q/x8fp/8fIKX/ICGj/yAhof8gIZ//ISKc/yIimv8iJJn/IyWW/yMk + lP8kJZX/JCaY/yQlmf8kJZv/JCWd/yQln/8kJaH/JCWi/yMjpP8jJKb/IySn/yIjqf8jI6z/ISKs/yAh + rv8gIbD/ICGx/x8gs/8fILT/Hh+1/x0et/8cHLj/HBy5/xwcu/8bHL3/Ghu+/xoav/8aGsH/GhrC/xoa + w/8ZGcT/GRnE/xkZxP8YGMT/GBjF/xgYxf8XGMX/FxjF/xYXxP8WF8T/FhfF/xUWxf8VFsX/FRbF/xQW + xv8UFcT/FBXE/xMUxP8SFMT/EhTF/xITxf8RE8T/EBLE/xARxP8PEMP/DxDD/w4PxP8HCb7/PTR4/+Da + 0v/y8PD/7+zs/4aFheYAAABgAAAARAAAAC4AAAAZAAAACwAAAAQAAAAAAAAAAP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAAEBAAABAQBlZGSbzcbG/9PN + zf/t6eL/jIas/x8ft/8jI8b/Hh/A/xkavP8aG7n/Gxu3/xwctf8cHbP/HR6w/x0erv8eH6v/HyGp/yAh + p/8gIqX/ISKj/yIjoP8iI53/IySc/yQkmv8kJpf/JSeV/yUnlf8mKJf/Jiia/yYnnP8mJ53/Jief/yYn + oP8mJ6P/Jiek/yYmpv8lJaf/JSSo/yQkqv8kJKz/IyOt/yEir/8hIrD/ICGy/yAhs/8gILX/Hx+1/x4e + t/8dHbj/HRy6/xwcu/8cHLz/Ghy9/xobvv8aGsD/GhrC/xoaw/8ZGcP/GRnE/xkZxP8YGMT/GBjE/xgX + xP8XF8X/FxfF/xYXxP8WF8T/FRfE/xUWxP8VFsX/FBXF/xQVxf8TFMT/ExTE/xIUxP8SE8P/EhPE/xES + xP8REsP/EBHD/xARw/8PEMP/Dw/D/woLxP8fGof/u7Kv//b08//x7e3/raur+xESEnoAAABHAAAAMwAA + AB0AAAAOAAAABQAAAAEAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wAAAQEAAAEBB4KAgM/Uzc3/2dTT/+fi2/9jX6P/HBzB/ycnx/8mJsP/ISK//xoc + u/8aG7j/HB22/x0ftP8eH7H/Hh+v/yAhrf8gIqv/IiOp/yMjp/8kJKX/JCWi/yUmof8mJ5//Jied/yYn + m/8oKpj/KCqW/ygql/8pKpr/KSqc/ykqnf8pKp//KSqg/ykqo/8pKqT/KCim/ygop/8oKKn/Jyeq/ycm + rP8mJq3/JCWu/yIkr/8iI7H/ISKy/yAitP8gIbT/HyC2/x8et/8eHrj/HR25/x0cu/8cHLz/Gxy9/xob + vv8aGr//GhrB/xoZwf8ZGcP/GRnE/xkZxP8YGMT/GBjE/xgXxP8XF8T/FxfE/xYWw/8WFsP/FhbE/xUW + xP8VFcT/FBXE/xQVxP8TFMT/ExTE/xITw/8SE8P/EhLD/xERwv8REcL/EBDC/xAPwv8PD8L/DQ3G/woJ + m/+TiJL/+Pbz/+3o6P/Qzc3/LS0tmwAAAEcAAAA3AAAAIQAAAA8AAAAGAAAAAQAAAAD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////ABQVFQAUFRUgn5yc9NjR + 0f/f29n/083L/0VEp/8jI8n/JyfH/ygoxf8oKML/JSa//x0euv8cHbf/Hh+1/x8gs/8gIbH/ICKv/yIj + rf8kJKv/JSSp/yUlp/8mJ6T/Jyij/ygpof8pKp//Kiuc/yosm/8qLZn/Ky2X/ysumf8rLpz/LC2d/ywt + n/8sLaD/Kyyj/ysspP8rLKX/Kyun/yoqqP8qKqr/KSmr/ygorP8nJ67/Jiav/yQmsP8kJbH/IySy/yIj + s/8hIrX/ICG2/yAgt/8eHrj/Hh25/x0duv8cHLz/Gxy8/xocvv8aG77/GhrA/xoZwf8aGcH/GRnC/xkZ + w/8YGMT/GBjE/xgYxP8XF8T/FxfE/xYWw/8WFsP/FRXD/xUVw/8VFcP/FBTE/xQUxP8TE8T/ExPD/xIS + wv8SEcL/ERHC/xERwv8QEML/EBDC/w8Pwv8ODsT/CQmt/2Zcgf/w7Ob/6+jo/+bi4v9KSkq6AAAATAAA + ADsAAAAkAAAAEgAAAAcAAAACAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8AMzMzADMzM1O5tbX/1s/P/+fj4P+8t73/LS2v/yYmzv8pKMn/KSnG/ykp + xP8qK8L/KSq//yMku/8fILf/ICG1/yIjs/8jJLH/JCSv/yUlrf8mJ6v/KCep/ykpp/8qK6X/Kyyj/ywt + ov8sLaD/LS+e/y4wm/8uMJr/LjCa/y8xm/8vMZ7/LzCf/y8woP8uMKP/LS+k/y4vpf8tLqf/LC2o/yws + qv8sLKv/Kyqs/yoqrf8pKa7/Jyiv/yUnsP8lJrH/JCWz/yMktP8hI7X/ICK2/yAgt/8fH7j/Hh65/x4d + uv8dHLv/HBy8/xobvf8aG73/Ghu//xobwP8aGcH/GRnB/xkZwf8YGML/GBjD/xgYxP8XF8T/FxfE/xYW + w/8WFsP/FRXD/xUVw/8UFMP/FBTD/xQTw/8TE8P/ExLD/xISwv8SEsL/ERHC/xERwv8QEML/EBDB/w8P + wf8HCLv/QTl6/+Te1v/t6ur/6OTk/3d2dtoAAABZAAAAPgAAACcAAAAVAAAACQAAAAMAAAAA////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wA6OTkAOjk5eM3H + x//W0ND/6+fi/5yWsv8pKbv/KSrP/ysryv8rK8j/KyvG/yssw/8sLcH/LS6//yoqu/8kJLf/IyS0/yQl + sv8mJ7H/Jyiw/ykprv8rK6z/LCuq/y0tqP8tL6X/LjCk/y8xov8xMaH/MTOf/zI0nP8yNJv/MjSc/zM1 + nv8zNKD/MzOh/zEzo/8xM6T/MTOm/zAyp/8vMaj/Ly+q/y4uq/8tLqv/LC2t/ywrrv8qK6//KCmw/yco + sf8mJ7H/JSaz/yQltP8iI7T/ISK2/yAgt/8fH7j/Hh64/x0duf8dHLv/HBy7/xscvP8aG73/Ghu+/xob + v/8ZGr//GRnA/xkYwP8YGMH/GBjC/xcXwv8XF8P/FxfD/xYWw/8WFsP/FRXD/xUVw/8UFMP/FBTD/xMT + w/8TE8P/EhLB/xISwf8REcH/ERHA/xEQv/8QEL7/EA++/wkLvv8qJYP/ysK///Hu7f/s6Oj/lZSU8QAA + AGMAAABBAAAAKwAAABcAAAAJAAAAAwAAAAD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AAEBAQBtbGyh083N/9nU1P/q5d3/f3ur/yMkxP8tLc//LS7M/y4u + yf8uLsf/Ly/F/y8ww/8wMMH/MTK//zExvP8rLLj/Jyi0/ycosv8qK7D/Kyyv/y0trf8uLqz/Ly+q/y8x + qP8xM6f/MjSl/zM0o/80NqL/NTeg/zY4nv82OJ3/Njie/zY4oP82OKL/Njej/zU3pP80Nqb/NDan/zM1 + qP8yNKr/MTKr/zAxq/8uL63/Li+u/y0ur/8sLK//Kiuw/ykpsv8mKLL/Jiez/yUmtP8jJLT/ISO1/yEi + tv8gILf/Hh64/x4euP8dHLr/HBy7/xwcu/8aG7v/Ghu8/xobvv8ZGr7/GRq//xgZv/8YGL//GBi//xcX + wP8XF8H/FhbB/xYWwf8WFcH/FRXB/xUUwf8UFMD/FBTA/xMTwP8TE8D/EhK//xISvv8REb3/EBG9/xAR + vf8PEbz/DA69/xYTj/+wpqf/8/Hw/+vm5v+zsLD8FxgYewAAAEIAAAAuAAAAGQAAAAsAAAADAAAAAP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAQEBBIB/ + f8bX0dH/3djY/+Te1/9pZaj/JCXN/y8v0P8vMM3/MDDL/zExyv8xMcj/MTPG/zIzxP80NcL/NjXA/zc3 + vv80Nbv/Li+2/ywss/8tLbH/LzCw/zEyr/8yM63/MzSr/zQ2qv82OKj/Njmm/zg5pf85OqP/Ojuh/zo8 + n/86PJ//Ojyh/zo8o/86O6T/Ojul/zg6p/84Oqf/Nzmo/zY3qv81Nqv/MzSs/zIzrf8xMq3/MDGu/y4v + r/8tLbD/Kyyw/yorsf8oKbL/Jiez/yUmtP8jJbT/IiS1/yEitv8gILb/Hx+3/x4et/8dHLj/HBy5/xwc + uv8bG7v/Gxu7/xobu/8aGrz/GRq9/xgavf8YGb7/GBi+/xcYvv8XF7//Fhe//xYXv/8VFr//FRW//xQV + vv8UFL3/ExS9/xMTvf8SE73/EhO9/xESvP8RErv/EBK6/xARuf8OD7z/DQyZ/5WKlv/18u//5+Li/8bD + w/8qKiqUAAAAQgAAADEAAAAbAAAADAAAAAQAAAAA////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wAAAQENj4yM59zW1v/h3dz/1tHO/1RSrf8qK9P/MDDS/zAx + 0P8yMs3/MzPL/zMzyf81Ncf/NjfF/zY3wv84OcH/OjvA/zw9v/88PLz/ODi5/zMztf8yMrL/MzSx/zY3 + sP83OK7/ODms/zk7q/87Par/Oz2o/z0+pv8+P6X/PkCj/z9Bof8/QaH/P0Gj/z5Apf8+P6X/Pj+n/zw+ + qP86Pan/Ojyq/zg6q/83Oav/Njet/zU1rf8yNK7/MTKv/y8wr/8uL7D/LC2w/yorsf8pKrL/Jyiz/yUm + s/8kJbT/IiO0/yEitf8gIbb/Hx+2/x4etv8dHbf/HBy4/xwcuf8bG7n/Gxu6/xsbuv8aGrv/Ghq8/xkZ + vP8YGbz/Fxm7/xcYu/8XGLz/Fhe8/xYXvf8VFr3/FRa8/xQVu/8UFbz/ExS7/xMUuv8TE7r/EhO6/xIS + uf8SErj/ERG3/xAQuf8LC6L/d2yL//Hu6f/l4eH/19PT/zU1NakAAABCAAAAMwAAAB4AAAAOAAAABAAA + AAH///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////ACUl + JSCppaX03tfX/+Tg3//MxcX/RUSy/y4u1v8yMtP/MzTR/zQ1z/82Nsz/NzfL/zg4yf85Ocf/OjvF/zs9 + xP89PsH/Pz/A/0BAv/9CQr3/QkK7/z4+uP85ObT/ODmy/zo7sf89PbD/Pj+u/z9BrP8/Qqv/QUOq/0JE + qP9DRKf/Q0Wl/0RFo/9DRaT/Q0Sl/0JEp/9CQ6j/QUKo/z9Bqv89QKr/PD6r/zs9rP86O63/ODit/zY3 + rf81Nq//MzSv/zEyr/8uL7D/LS6w/ywssP8pKrL/KCmy/yYns/8kJbP/IiOz/yEis/8gIbT/HyC1/x4e + tv8dHbb/HBy3/xwbuP8bG7j/Gxu5/xsbuP8aGrj/Ghq5/xkZuv8YGbr/GBi6/xgYuv8XF7r/Fxe6/xYW + uv8WFrr/FRa6/xUVuv8UFbn/FBS4/xQUuP8TE7f/ExO3/xIStv8SEbb/ERG3/woKqf9eVoX/7enh/+Xh + 4f/g29v/TExMuQAAAEYAAAA1AAAAHwAAAA4AAAAFAAAAAf///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8ALy8vPLezs/zc19f/5uLg/8K7vv85OLb/MzPY/zU1 + 1f82NtL/NzjQ/zg5z/87Osz/OzvL/zw8yv8+P8f/P0DG/0BBxf9DQ8P/RETC/0ZGwP9ISL7/SUm9/0lJ + u/9ERbf/QEG1/z9Asv9CQrH/Q0Ww/0RGr/9FR63/Rkis/0hIqv9ISaj/SEmn/0hJpv9HSKb/R0io/0ZH + qf9GR6n/REWq/0NEq/9BQ6v/P0Gt/z5Arf88Pa3/Ojqu/zc4rv82N6//NDWv/zIzr/8vMK//LS+w/yws + sP8qK7H/Jyqx/yYnsf8kJbL/IiOy/yEis/8gIbT/HiC0/x0etP8dHbT/HB21/xsbtf8bG7b/Gxu3/xsa + t/8aGrj/Ghm4/xkZt/8ZGbj/GBi4/xgYuP8XF7j/Fxe4/xYWuP8WFrj/FRW3/xUUt/8UFLb/FBS2/xMT + tf8TE7T/EhK0/xISs/8RErP/Bwqu/0pBfv/q5Nv/5uLi/+Hc3P9oZ2fLAAAATQAAADYAAAAgAAAADwAA + AAUAAAAB////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wAxMTFPwLy8/93W1v/r5+T/sKq3/zc3vP82Ntn/ODjV/zk51P86OtL/OzvQ/z09z/8/P83/QEDM/0JC + yv9DRMj/REbH/0dHxv9JSMT/SkrD/0xMwv9OTcD/UE+//1FSvv9QUbz/TE25/0hJtf9HSLL/SUuy/0pN + sf9LTa//TE6u/01Orf9NTqv/TU6p/01OqP9MTaj/S0yq/0pLqv9JSqv/R0ms/0VHrP9ERq3/QkSt/0BC + rv8+P67/PDyu/zk6r/83OK//NTav/zM0r/8wMq//Ly+w/y0tsP8rK7D/KCqw/yUnsP8kJbH/IySx/yEi + sv8gIbL/Hh+y/x0fs/8cHrP/HBy0/xsctP8bHLT/Gxy2/xoatv8aGrb/GRm1/xkZtf8YGLb/GBi2/xgX + tv8XF7b/Fxa2/xYWtf8WFbX/FRW0/xUVtP8UFLT/FBSz/xMUsv8TE7H/EhOw/xESsP8JC67/PDWA/9/Z + 0v/n4+P/4dzc/3h2dtgAAABSAAAANgAAACEAAAAPAAAABQAAAAH///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////ADU1NWLLxsb/3tjY/+vo5P+inLP/OzvC/zg4 + 2f86Otb/PDvW/z091P89PtL/QEDS/0JCz/9DQ87/RUTN/0ZHy/9JSsn/S0vI/01Nxv9PT8b/UFHE/1JS + w/9TU8L/VVXB/1dYwP9ZWr//WVq9/1VWuv9QUbb/T1C0/1BRs/9RUrL/UlKw/1NSrv9SVK3/UlOr/1JT + qv9RUqv/T1Cs/05PrP9NTq3/Skyt/0hLrf9FSa3/REau/0JDrv9AQa7/PT+u/zs7r/84Oa//Njev/zM0 + r/8wMa//Li+v/y0tr/8rK6//KCqv/yYor/8kJrD/IiOw/yEisP8fILH/Hh+x/x0esf8dHrL/Gxyy/xsc + sv8bHLP/Gxyz/xobtP8aG7T/GRq0/xkZs/8YGbP/GBi0/xcYtP8XF7T/Fhez/xYXs/8VFrL/FRax/xQV + sf8UFbH/ExSx/xITsP8SE67/ERKu/wsNrf80LoP/1c3J/+nl5P/j3t7/hoSE4wAAAFYAAAA3AAAAIQAA + AA8AAAAFAAAAAf///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8ANjY2bNDLy//f2tr/6ubg/5aRsf85Ocb/OzvZ/z091/8+Ptf/QD/X/0FB1f9DQ9P/RUXR/0dH + 0P9ISM//S0vN/01Oy/9PUMr/UVLJ/1NTyP9VVcf/V1jG/1hZxf9aW8T/W1zD/15fwv9gYcH/YWLA/2Fi + v/9dXrz/WVq4/1ZXtf9WV7T/WFiz/1hZsf9YWbD/V1iu/1ZXrP9VVqz/VFWt/1JTrv9QUa7/Tk+u/0tN + rv9IS67/RUiu/0NFr/9BQ6//PkCu/zw8rv85Oq7/Njev/zQ1rv8xMq//Li+u/y0trv8rLK//KCmv/yYm + rv8kJK//IiOv/yAhr/8fILD/Hh+w/x0esP8cHbD/HB2x/xscsf8bHLH/Ghux/xobsf8aG7L/GRqy/xka + sv8YGbH/GBmx/xcYsf8XGLH/Fhex/xYXr/8VFq//FBWv/xQVr/8TFK7/ExSu/xITrP8SE6z/DA6r/ysn + hv/Lw8L/6ubl/+Pd3f+LiYnqAAAAWAAAADcAAAAhAAAADwAAAAUAAAAB////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wA5OTmA29bW/+Db2//p5N//npi1/z4+ + x/89Pdn/Pz/X/0FB2P9CQtj/RUXW/0ZH1P9ISdP/SkvS/01M0P9PT8//UVHO/1NUzf9VVsz/VlfK/1lZ + yv9cXcn/Xl/H/19gx/9hYcb/Y2TG/2Rnxf9nZ8T/aGjC/2lqwv9qa8H/Z2i+/2Njuv9fYLf/XV21/11d + tP9dXrH/XF2w/1tcrv9ZWq7/V1iv/1VWr/9TU6//UFCv/01Pr/9KTK//R0mv/0VHr/9CRK7/P0Gu/zw9 + rv85Oq7/Nzet/zQ1rf8xMq3/Li+t/y0trf8rK63/KCit/yYmrf8kJa7/IiOu/yAhrv8eH67/HR6u/xwd + rv8cHa//Gxyv/xscsP8bHK//Ghuu/xobr/8ZGrD/GRqw/xgZr/8YGa//Fxiu/xYXrv8WF67/Fheu/xUW + rv8VFqz/FBWs/xQVq/8TFKv/ExSr/xITqv8MDqn/LSmG/8zFw//p5eT/5N7e/5mWlvYAAABcAAAANgAA + ACEAAAAPAAAABQAAAAH///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////ADk5OYDc19f/4t3d/+bh3P+Yk7X/PT3K/0BA2f9CQtf/RETY/0VG2f9IR9j/SUnX/0tL + 1f9OTtT/UVHT/1NS0v9UVdD/V1jO/1lZzv9cXM3/Xl7N/2Bhy/9jZMv/ZWbK/2dnyv9pasj/amzI/2xt + x/9vb8b/b3DG/3Bwxf9xcsT/cXLC/3Bxwf9sbb3/Z2e6/2Njtv9hYrT/X2Gy/15fsP9dXrD/Wluw/1hZ + sP9WVbD/U1Kw/09Qr/9MTa//SEuv/0ZIrv9DRa7/QEGu/z0+rv86Oq3/Nzet/zM0rf8wMa3/LjCs/y0s + rP8qKqz/KCis/yUlrP8kJKz/ISOs/yAhrP8eH6z/HR6s/xwdrP8bHKz/Gxys/xscrf8aG63/Ghut/xka + rf8ZGq3/GBmt/xgZrf8XGK3/Fxis/xYXrP8WF6z/FRas/xUWq/8UFar/ExSq/xMUqf8TFKj/ExSn/w4Q + qP8jIIf/wLe4/+zo5v/j3Nz/mZaW9gAAAFwAAAA2AAAAIQAAAA8AAAAFAAAAAf///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AOTk5gN3Y2P/j39//5uHb/5aS + tf8+P8v/Q0La/0VF2P9HR9n/SUnZ/0pK2f9MTNn/T0/Y/1BS1v9UVNX/V1bU/1lZ0/9cW9H/Xl7Q/2Fh + 0P9kZM//ZmbO/2hpzf9ra83/bG7M/29wzP9xcsv/cnPK/3R1yv92dsn/d3fI/3d3x/94eMb/eHjF/3d4 + xP93d8L/dHTA/25vvP9oarj/ZGW0/2Fjsv9fYLH/XV6x/1pbsf9XV7H/VFSw/1FRr/9NTq//SUuv/0ZI + rv9DRa3/QEKt/zw+rf85Oq3/Njes/zMzrP8vMKv/LS6r/ywsq/8qKqv/Jyeq/yQkqv8jI6r/IiKq/yAh + qv8eH6r/HR6q/xwdq/8cHar/HB2q/xscq/8aG6z/GRqr/xkaqv8ZGqv/GBmr/xgZq/8XGKr/Fxip/xYX + qf8WF6n/Fhep/xUWqP8VFqj/FBWm/xQVpf8TFKb/DxGm/yMfhv++tbb/6+jm/+Lc3P+YlZX2AAAAXAAA + ADYAAAAhAAAADwAAAAUAAAAB////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wA5OTmA3tnZ/+Xg4P/k39r/oZy1/0ZGyv9FRdv/R0fa/0pK2v9MTNn/TU3a/1BQ + 2/9SUtn/VFXY/1dY1/9aWtb/XV3U/2Bg1P9iYtP/ZmbS/2ho0f9ra9H/bW3R/3Bx0P9ydND/dXXP/3d4 + zv94ec7/enrN/3x8zf9+fsz/fn7L/35/yv9+f8n/fX/I/31+xv98fcX/e3zD/3l6wf90dr7/bnC6/2hp + tf9jZLP/X2Cy/1tdsf9ZWbH/VVWw/1JSsP9OT6//Skyu/0ZIrf9CRa3/P0Gt/zw+rP84Oqv/Njar/zI0 + q/8vMKr/LS2q/ysrqf8oKKn/Jiao/yQkqP8iI6n/ISKp/x8gqf8eH6n/HR6p/xwdqf8cHan/HB2p/xsc + qf8bHKn/Ghup/xkaqf8ZGqj/GRqo/xgZqP8YGaj/Fxin/xcYpv8WF6b/Fhem/xUWpf8VFqT/FBWk/xQU + o/8OD6P/LiqF/8jBv//p5uX/4dra/5iVlfYAAABbAAAANQAAACEAAAAQAAAABQAAAAH///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////ADk5OYDf2tr/49/f/+rl + 4P+hnLb/SEjL/0hI2/9KStr/TU3a/05O2/9RUdr/U1Pb/1VV2/9YWdr/WlzZ/15f2P9iYtf/ZGTW/2dn + 1f9qatX/bW3U/3Bw0/9zc9P/dnbT/3h50/97fNL/fX7S/3+A0v+AgtH/goPR/4SE0P+Fhc//hoXO/4aG + zf+Fhsz/hIXL/4ODyf+Bgsf/gIDG/31/w/96fcH/d3m+/3N0u/9sbrf/ZWe0/19gsv9aW7H/VVaw/1FR + r/9OT67/Skut/0ZHrf9CRKz/PkGs/zs9qv83Oqr/NDap/zIyqf8vMKj/LSyo/yoqqP8nKKf/JiWn/yMj + pv8hIqb/ICGn/x8gp/8dHqf/HR6n/xwdp/8cHaf/HB2m/xscpv8bHKf/Ghun/xobp/8ZGqb/GRqm/xgZ + pv8XGKb/Fxil/xYXo/8WF6P/FRaj/xUWo/8UFaL/FBWi/w4PoP8vKob/0MnI/+bh4P/g2dn/l5SU9gAA + AFsAAAA1AAAAIQAAAA8AAAAFAAAAAf///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8AOTk5gODc3P/l4OD/6ubh/6KeuP9MTM3/Skrb/05O2v9QUNv/UVHb/1RU + 3P9WVtz/WVnc/1xc3P9eXtv/YmLa/2Vm2f9oaNj/bGzX/29v1/9yctf/dXXW/3h41v97e9b/fn7W/4GC + 1v+DhNX/hYbV/4iJ1f+JitT/i4vU/4yM0/+MjNL/jI3R/4yM0P+LjM//iovN/4iJzP+Gh8r/g4TH/4CB + xP99fsL/enzA/3d5vf9zdbr/b3C5/2hptv9hYrT/Wluy/1NTr/9OT63/SUqs/0VGq/9BQ6r/PT+q/zk8 + qf83Oaj/Mzao/zAyp/8tL6f/Kyym/ykppv8nJ6b/JCSl/yIjpf8hIqX/HyCl/x4fpf8dHqX/HB2k/xwd + pP8cHaX/Gxyl/xscpP8aG6X/Ghul/xkapP8YGaT/GBmj/xgZo/8XGKP/Fxii/xYXov8WFqH/FRag/xQV + n/8UFZ//Dg+f/y8rh//Qysj/5N/e/9/Y2P+XlJT2AAAAWgAAADQAAAAgAAAADwAAAAUAAAAB////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wA6OTmA4d3d/+Xh + 4f/q5eH/o5+4/1FSz/9MTNz/UFDa/1JS2/9VVdz/V1fc/1pa3f9cXN3/X1/d/2Ji3f9lZtz/aWnc/21s + 2/9wcNr/dHTZ/3Z22f96etn/fn7Z/4CA2P+EhNj/iIfZ/4qL2P+Mjdj/jo/Y/5CR2P+Sktf/k5TX/5OU + 1v+TlNX/k5TU/5KT0v+RktH/j5DQ/42Nzv+Ki8v/h4jJ/4SExv+AgMT/fH3B/3h6vv90drz/cHK5/21u + uP9pabf/Y2S1/1xdsv9UVrD/TU6u/0dHq/9AQqn/PD6o/zc5p/81N6f/MTOm/y4wpf8sLqX/Kiuk/yco + pP8mJqP/IyOj/yEio/8gIaP/Hh+j/x4fo/8cHaP/HB2j/xwdo/8cHKP/Gxyj/xobov8aG6L/GRqi/xka + ov8YGaH/GBih/xcYoP8WGKD/Fheg/xYXnv8VFp3/FRad/xQWnf8OEJ3/MCyG/9HKyf/j3t3/3tfX/5eU + lPYAAABaAAAANAAAACAAAAAPAAAABQAAAAH///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////ADc3N3LZ1dX/6OPj/+rn4v+embb/UlLP/09P3f9SUtz/VVXc/1dX + 3P9aWtz/XFze/19f3v9jY97/Zmbf/2lp3v9sbd7/cHHd/3R03P94eNv/fHzc/39/3P+Dg9v/hobb/4qK + 2/+Ojdz/kJDc/5OS2/+Vldv/l5fb/5mZ2v+amtr/m5vZ/5uc2P+am9j/mZrW/5iY1f+WltT/k5TS/5GR + 0P+Ojs3/i4vK/4eHyP+Cg8X/fn/D/3l7wP91d7z/cHK6/21tt/9oabb/ZGW1/2Bhs/9bXLL/Vlex/1BR + r/9JSqz/QUOq/zs+qP81N6X/MDKk/y0vo/8qK6P/Jyii/yYnof8jJKH/IiOh/yAhoP8fIKD/Hh+g/x0e + of8cHqD/HB6g/xwdoP8bHKD/Gxug/xoboP8aGqD/GRqf/xkan/8YGp//Fxme/xcYnf8WGJ3/Fhid/xUX + nP8UF5v/FBaa/w4Rmf8wLYb/0svK/+Pe3f/b1NT/jYqK7wAAAFcAAAA0AAAAIAAAAA8AAAAFAAAAAf// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8ANTU1Y9TQ + 0P/q5ub/7Ofi/5iTs/9RUs7/UVHd/1VV3P9XV93/Wlrd/11d3f9fX97/Y2Pf/2Zm4P9qauD/bW3g/3Bw + 4P90dN//eHjf/3x83v+AgN7/hITd/4iI3v+MjN7/kJDe/5OT3v+Wlt7/mZne/5yc3v+ent7/oKDe/6Ki + 3v+jo93/o6Pc/6Kj2/+gotr/n6DZ/52e1/+am9b/l5jU/5OV0f+Qkc7/jI3M/4iJyf+DhMf/fn/E/3p7 + wf91d73/cXK6/21tt/9nabX/Y2Sz/15fsv9aW7H/Vlew/1JTr/9OT63/SUqs/0RGqv8/Qan/OTum/zU2 + pf8wMaT/Kyyi/ycooP8jJJ//ISKf/x8gnv8dHp7/HB2e/xsdnv8bHp7/HB6e/xsdnv8aHJ7/Ghye/xoc + nv8ZG53/GRuc/xganP8YGpz/Fxmb/xYYmv8WGJr/FRea/xUXmf8UFpf/DhGY/y4rhf/SzMv/4t7c/9nS + 0v+DgYHjAAAAVAAAADQAAAAfAAAADgAAAAUAAAAB////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wA1NTVk1tLS/+vn5//s6OL/mJOz/1RVz/9UVN3/V1fc/1pa + 3f9dXd3/X1/e/2Ji3v9mZuD/aWnh/21t4f9wcOH/dHTh/3h44f98fOH/gIHh/4WF4P+JieD/jY3g/5GR + 4f+VleH/mJng/5ud4P+goOH/pKPh/6am4f+oqOH/qqrh/6qq4f+qquD/qqrf/6iq3v+nqN3/pKXa/6Ch + 2f+en9j/mpvV/5WW0v+QkdD/jo7N/4mKyv+DhMf/f3/E/3l7wf91dr7/cHG7/2xst/9maLT/YmOy/11e + sf9ZWrD/VFau/1BSrf9MTqv/SUmq/0VGqf9BQqj/Pj+o/zs8p/83OKX/NDWl/zEypP8tLqL/KSqh/yYn + oP8jJZ//ISOe/x8hnv8eIJ3/HR+c/xwdnP8aHJz/Ghyb/xkbm/8ZG5r/GBqa/xcZmf8WGJn/FhiY/xUX + l/8VF5f/FReX/xQWlv8PEpb/Mi6G/9LMzP/h3dz/2NHR/4SBgeQAAABUAAAANAAAAB8AAAAOAAAABQAA + AAH///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////ADY1 + NWTW09P/6+jo/+zn4v+Yk7P/VlbQ/1ZX3v9aWtz/XFzd/19f3v9iYt//ZWXf/2lp4P9sbOH/cHDh/3R0 + 4v93d+P/fHzj/4CA4/+EheP/iYnj/46O4/+SkuP/lZbj/5ma4/+en+P/oqPk/6an5P+qquX/rK3l/6+v + 5P+xseX/srLk/7Ky5P+ysuP/sLDi/66v4f+srN//qKnd/6Sl2/+hotn/m53W/5aX0/+Sk9D/jo7N/4iJ + y/+DhMj/fn/E/3l6wf90db7/b3C7/2prt/9lZrT/YWKy/1tcr/9XWK7/U1Ws/09Rq/9LTKr/R0mo/0NF + p/9AQab/PT6l/zo7pf83OKP/NDWj/zM0o/8yMaL/MDCi/y0uof8sLaH/Kyyg/ykrn/8oKp//Jiif/yUm + nv8jJZ3/IiSc/yAinP8fIZv/HR+Z/xwemf8bHZj/GhyX/xoblv8ZGpb/GBmV/xYXl/87N4r/0s3N/+Dc + 2v/Xz8//hIGB5AAAAFQAAAA0AAAAHwAAAA4AAAAFAAAAAf///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8ANjY2ZNfU1P/s6en/7Ojj/5iTs/9YWND/WVnf/11d + 3f9fX93/YWHe/2Vl4P9nZ+D/a2vg/29v4f9zc+L/d3fi/3t74/9/f+T/g4Pl/4iI5f+MjeX/kpLk/5aW + 5P+amuX/n5/l/6Sk5v+oqeb/q63n/7Cw5/+ztOf/trfn/7m55/+6uuf/urrn/7q65v+4uOX/tbXl/7Oz + 4/+vsOH/q6ze/6eo2/+iotr/nJ3X/5eX0/+SktH/jY7O/4eIyv+Cg8j/fX3F/3d4wf9zc77/bm67/2hp + uP9kZbX/Xl+x/1pbr/9WV6z/UVOq/01Pqf9JS6j/RUin/0JEpv8/QKX/PD2k/zk7o/82OKL/NDWh/zMz + of8xMaD/MDCg/y4voP8tLp//LS6e/yssnv8qK57/KSqe/ykpnf8oKZ3/Jyic/yYnm/8lJpr/JCWa/yMk + mv8iI5n/ICKY/yAhlv8eH5b/Gx2X/z06i//Tzc3/4NrZ/9bPz/+DgYHkAAAAVAAAADQAAAAfAAAADgAA + AAUAAAAB////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wA2NTVk2NXV/+7q6v/s6eT/l5Kz/1pZ0f9bW9//Xl7e/2Fh3v9kZN//Z2fg/2tr4P9ubuH/cnLh/3Z2 + 4/96euT/fn7k/4KC5f+Hh+f/jIvm/5CR5v+Vlub/mprn/5+f5/+kpOf/qano/66u6f+ys+n/trfq/7q7 + 6v++v+v/wMDr/8LC6//Cwuv/wsLq/8DA6f++vef/urrl/7a25P+ysuL/ra3f/6eo3f+hotr/nJ3W/5aX + 1P+RktH/jIzN/4aGy/+Agcj/enzE/3V1wf9wcb7/a2y7/2dnuP9hY7X/XV2y/1hZr/9UVqz/UFGp/0tO + p/9ISqb/REal/0JDo/8+QKP/Oz2i/zk7of82OKD/MzWf/zIzn/8xMZ7/MDCe/y8wnf8uL53/LS6d/ywt + nf8rLJ3/Kiuc/ykpm/8oKZr/Jyia/yYomf8lJpj/JCaX/yMll/8iJJb/ISOV/yAik/8cIJX/PjuL/9PN + zv/f2tn/1c3N/4OAgOQAAABUAAAANAAAAB8AAAAOAAAABQAAAAH///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////ADY2NmTZ1tb/7+vr/+rm4v+nobj/YGDQ/1xc + 3/9hYd7/Y2Pf/2Zm3/9qauD/bW3h/3Bw4v90dOL/eHjj/3x85P+BgeX/hYXm/4qK5/+Pj+j/lJTo/5mZ + 5/+enuj/o6Pp/6mp6v+urur/s7Pr/7i57P+9vuz/wcLt/8TG7f/IyO7/ysru/8rK7v/Jyu3/yMjs/8XF + 6//Bwen/vb3m/7i45f+zsuL/ra3f/6eo3P+hotn/mpzW/5WW1P+Pj9D/iorN/4OEyv9+fsf/eXnE/3N0 + wf9tbr7/aWm6/2Rkt/9fYLX/W1yy/1ZYr/9SVK3/TlCq/0pMp/9HSaX/Q0Wj/0BCov88PqH/Ojuf/zg6 + nv83OJ7/NDae/zEznf8xMpz/MDGc/y8wnP8vMJz/Li+b/y0um/8sLZv/KiuZ/ykqmf8oKpj/KCmY/yYp + lv8mJ5b/JSaW/yQmlf8jJZP/IiST/x0glP9HQ4v/1tDP/97Y2P/UzMz/g4CA5AAAAFMAAAAzAAAAHwAA + AA8AAAAFAAAAAf///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8ANjY2ZNrX1//w7e3/6OTh/6ymtv9mZ9H/Xl7g/2Nj3v9lZd//aGjg/2xs4P9vb+H/c3Pi/3d3 + 4v97e+P/f3/l/4OD5v+IiOb/jY3n/5KS6P+Xl+n/nZ3q/6Ki6v+np+v/ra3r/7Kz7P+5uO3/vr7u/8PD + 7//IyPD/zMzw/8/P8f/R0fH/0tLx/9HS8P/P0PD/zMzu/8jI7P/Dw+r/vr7n/7i45f+xsuL/q6zf/6Sm + 3P+fn9n/mJnW/5OS0/+NjdD/hofN/4CByf97fMb/dXfE/3Bwwf9rbL3/Zme7/2FjuP9cXrX/WFmy/1RV + r/9QUa3/TE6r/0hKqf9FR6b/QkOl/z9Bo/87PqD/OTue/zg5nv83N53/NDWb/zIzm/8xMpv/MDGa/zAx + mv8vMJr/Li+Z/y0umf8sLZj/KyyX/yorl/8oK5b/JyqW/yYolv8mJ5X/JSeV/yQmlf8jJZX/HiGW/1NO + jv/f2tf/29bV/9LLy/+CgIDkAAAAUgAAADMAAAAfAAAADgAAAAUAAAAB////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wA2NjZk29jY/+/t7f/w7er/q6W2/2dn + 0f9gYOD/ZGTf/2ho3/9qauD/bm7h/3Fx4f91deL/eXnj/3195P+BgeX/hobm/4qK5/+QkOj/lJTp/5qa + 6v+fn+v/pqbs/6ur7f+xse3/trbu/7297//Dw+//ycnx/87O8v/T0/P/19f0/9nZ9P/a2vT/2drz/9fX + 8v/T1PH/zc7u/8nJ7P/Dw+r/vLzn/7a25f+vsOL/qKnf/6Kj3P+bnNn/lZbV/5CQ0v+KidD/hIPM/31+ + yf94ecb/c3PD/21uwP9oab7/YmW6/15guP9ZW7X/VVez/1JTsP9OT67/Skyr/0dIqv9DRaj/QUKl/z0/ + pP87PKP/Ojqh/zg5n/82OJ7/NDWd/zI0nP8xMpz/MTGc/zAxm/8wMJr/LzCa/y4vmv8tLpn/LC2Z/yot + mf8pK5n/KCqY/ycpmP8mKJj/JieY/yUmmP8fIZr/VE+R/+Xh3v/X0ND/0svL/4J/f+QAAABSAAAAMgAA + AB4AAAANAAAABQAAAAH///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////ADY2NmTb2dn/8O3t//Hu6/+sprb/amzT/2Fh4f9mZuD/aWng/2tr4P9wcOL/c3Pi/3d3 + 4v97e+T/f3/k/4SE5f+IiOf/jY3n/5KS6P+Xl+r/nZ3q/6Ki7P+np+3/ra3t/7S07v+7u+//wMDw/8fH + 8f/NzfL/1NT0/9nZ9f/e3vb/4uL3/+Pj9//i4vb/3t71/9nZ9P/U1PH/zs7v/8fH7P/AwOn/urrn/7Ky + 5P+sq+H/paXe/56f2/+Xmdj/kpLV/4yL0v+Fhs7/gH/M/3p6yf91dcb/b3DC/2prwP9lZr3/YGK7/1te + uP9XWbb/U1Wz/09RsP9MTa7/SEqs/0VHq/9CQqj/QECn/z0+pf86O6T/OTmi/zg4ov83N6D/NTWg/zQ0 + n/8zNJ//MjOe/zExnv8wMJ7/LzCd/y4wnP8tL5z/LC6c/yssnP8qK5z/KSqc/ycpnP8mJ5z/JSac/yIj + nf9ZVJT/5eDd/9TOzv/Rycn/gX5+5AAAAFIAAAAyAAAAHgAAAA0AAAAFAAAAAf///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8ANjY2Zt3a2v/y7u7/8e7r/62n + t/9tb9T/Y2Ph/2ho3/9qauH/bW3h/3Fx4f90dOL/eHjj/3195P+BgeX/hYXm/4qK5/+Ojuj/lJTp/5mZ + 6v+enuv/paXs/6ur7v+wsO7/t7fv/7298P/ExPH/y8vy/9HR9P/Y2PX/39/2/+Xl+f/p6fn/6+v5/+rq + +f/m5vj/39/1/9nZ8//R0vH/ysvu/8TE6/+8vOj/tbXl/66u4v+np+D/oaHd/5qZ2f+TlNf/jo7U/4eH + 0f+Cgs7/fXzL/3Z3yP9xcsX/a2zD/2ZnwP9iY73/XV+7/1lauP9UVrX/UFK0/01Psv9JS6//R0it/0RF + q/9BQqr/Pz+p/zw9p/86Oqb/ODik/zc4o/82NqP/NTaj/zQ1ov8zNKL/MjOh/zEyoP8wMaD/MDCg/y4w + oP8tL5//LC6f/yssn/8qK5//KSqf/ycpn/8mKJ//JCah/19amP/l4N7/1M3N/9DJyf+Cf3/kAAAAUgAA + ADEAAAAdAAAADQAAAAQAAAAB////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wAzMzNX1NLS//Tx8f/y7+z/rKa3/2pr0v9lZeL/aWng/2xs4f9vb+H/cnLh/3Z2 + 4/96euP/fn7k/4KC5f+Ghub/i4vn/5CQ6P+Vlen/mprq/6Cg6/+lpez/rKzu/7Ky7/+4uPD/v7/y/8bG + 8v/NzfP/1dX1/9zc9v/j4/j/6ur6//Hx/P/09Pz/8fH8/+vr+v/k5Pf/3Nz0/9TU8v/Nze//xsbs/76+ + 6f+3t+f/sLDk/6mp4f+jot7/m5vb/5SW2P+Pj9b/iYnT/4KD0P99fs3/eHjK/3JzyP9tbsT/aGnC/2Nk + wP9eYL3/Wlu6/1ZXuP9TVLb/T1C1/0tMs/9ISbD/Rkev/0JDrf9AQaz/Pj6q/zo8qf84Oqj/ODin/zc4 + pv82N6X/NTel/zQ2pf8zNaT/MTSj/zAyo/8wMaP/LzCj/y8wo/8tMKP/LC6j/ystov8qLKL/KSyj/ycq + o/8iJaP/V1KV/+bi3v/TzMz/zsbG/3l2dtwAAABOAAAAMAAAABwAAAANAAAABAAAAAD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AEpKSkbKyMj/9vPz//Pw + 7f+qpLb/YmPO/2dn4v9ra+D/bW3g/3Bw4v90dOL/eHjj/3t75P9/f+X/g4Pl/4iI5/+Njef/kZHo/5eX + 6f+cnOr/oaHs/6io7f+tre7/s7Pv/7q68P/AwPL/yMjz/87O9f/W1vb/3t74/+bm+f/u7vr/9vb9//z8 + /v/39/3/7+/7/+bm+P/e3vX/1tbz/87O8P/Hx+7/wMDr/7m56P+xseX/qqri/6Oj3/+cnNz/lpba/4+Q + 1/+Ki9X/hITS/31/z/94ecz/c3XK/25vx/9pasT/ZWXC/2Bhv/9cXL3/V1i7/1NUuf9QUbf/TE21/0lK + s/9HR7L/RESw/0BBrv8/P63/PT6s/zs8q/85Oqr/ODmp/zc5qf83OKn/NTin/zQ3p/8zNqf/MjWn/zEz + pv8xMqb/MDGm/y8xpv8uMKb/LS+l/ystpv8rLKb/KSum/yMlpv9UUJX/5+Pf/9PLy//LxMT/bmxs0AAA + AEgAAAAuAAAAGwAAAAsAAAAEAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8AZ2dnSMjGxv/39PT/8/Ht/6qktv9iY87/aWni/2xs4f9ubuH/cXHh/3V1 + 4/95eeP/fHzk/4CA5f+FheX/iYnn/42N6P+Skun/l5fq/52d6v+iouz/p6ft/66u7v+zs/D/urrx/8HB + 8v/Hx/T/z8/1/9bW9v/d3fj/5eX5/+3t+v/09P3/+fn9//b2/f/u7vv/5ub4/97e9v/W1vP/zs7x/8bH + 7v/AwOz/ubjp/7Ky5v+qquP/pKTh/52d3v+Wl9v/kZLY/4uM1f+EhdP/f4DR/3l6zv90dcv/b3DK/2ps + x/9lZ8T/YWLC/11ev/9ZWr7/VVa7/1FSuf9NTrj/Sku2/0hIs/9FRbL/QkOx/0BAsP8/P67/PT6t/zo8 + rf85Oq3/ODms/zg5q/84OKv/Nzir/zU3qv80Nqr/MzSq/zIzqf8xMqn/MDGo/zAwqP8vMKn/LS+p/ywt + qP8rLKj/JCWp/1RQlv/o5OD/0crK/8rCwv9vbW3QAAAARAAAACsAAAAYAAAACgAAAAMAAAAA////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wBjY2NIycfH//f1 + 9f/z8e3/rKa3/2do0P9paeL/a2vg/25u4v9ycuL/dnbi/3p65P99feT/gYHl/4WF5v+Jieb/jo7o/5OT + 6P+YmOr/nZ3r/6Ki7P+np+3/rq7u/7Oz7/+6uvH/wcHy/8fH8//OzvT/1dX2/9vb+P/i4vn/6en6/+7u + +//x8fz/7+/8/+rq+v/j4/f/3Nz1/9XV8//OzvD/xsfv/76/7P+4uer/sbLn/6uq5P+kpOL/nZ3f/5aX + 3P+Qktr/i4vX/4WG1f9/gNP/envQ/3V1zf9vccz/amvJ/2Znxv9hY8T/Xl/C/1pbwP9WV77/UlO7/09Q + uv9MTLn/SUm3/0ZGtf9ERLT/QUKz/z9Asv8+PrD/PD2w/zs8r/85Oq//OTqv/zk4rv84OK7/Nzit/zU3 + rP81Nq3/MzSt/zIzrP8xMqz/MDCs/y8wq/8tLqv/Kyyq/ygpqv8nKaz/Xlma/+fj3//Qycn/ycHB/3Bu + bs0AAAA8AAAAJQAAABQAAAAJAAAAAgAAAAD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AGNjY0jKyMj/+ff3//Tx7v+po7f/d3jU/3195v96euP/eHjj/3V1 + 4v92duP/eXnk/3195P+BgeX/hYXm/4qK5/+Ojuj/k5Pp/5iY6v+dnev/oqLs/6en7f+uru7/s7Pv/7i4 + 8f+/v/L/xsbz/8zM9f/S0vb/2dn3/97e+P/j4/n/5+f6/+np+v/o6Pn/5OT4/9/f9//Y2PX/0dHz/8vL + 8P/Fxe//vb7s/7a36v+vsOf/qqrl/6Oj4/+dneD/l5fe/5CS2/+Li9n/hYbW/4CA1P96e9H/dXbP/3Bx + zv9sbMv/ZmjI/2Jjx/9fX8X/W1vD/1dXwf9TVL7/UFG9/01Nu/9KSrr/R0e4/0VFt/9DRLb/QUK1/0BA + tP8+P7P/PD2y/zs8sv87PLL/Ojux/zk5sf84ObH/ODiw/zY3sP81Na//MzSv/zAxrv8uMK7/MjOv/zo6 + sv9HSLj/UFG9/11fw/9pZKD/5N/e/9DJyP/IwMD/cW5uygAAADIAAAAdAAAAEAAAAAYAAAABAAAAAP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AY2NjScvK + yv/6+Pj/9PLv/7SuvP9rbM3/g4Pq/4mI6f+MjOn/j4/o/4yM5/+IiOb/hITm/4KC5f+Fheb/iYnn/46O + 5/+Skun/mJjp/52d6/+hoez/p6ft/6ys7v+xse//uLjw/7298v/Dw/P/yMj0/8/P9f/U1Pf/2dn3/97e + 9//g4Pj/4eH5/+Dg+P/d3ff/2dn2/9TU9P/OzvL/yMjx/8LB7/+7vOz/tbbq/66v6P+oqeX/oaPj/5uc + 4f+Wlt//kZHc/4qL2v+Fhtf/gIDW/3p70/92dtH/cHLP/2xszP9naMv/Y2TJ/2Bgx/9cW8T/WFfC/1RU + wP9RUb//Tk++/0tMvf9ISbv/Rka6/0RFuP9BQ7f/QEG3/z9Atv89P7b/PD60/zw9tP87PLT/OTuz/zk6 + s/83OLP/MzWx/zQ2sf87PbT/S0y7/1xdwv9tbcj/cnPL/3Fyzf9ub83/T1HB/1lTlP/r5+L/zsbG/8e/ + v/9zcXHHAAAAJQAAABQAAAALAAAABAAAAAEAAAAA////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wBeXl4vvLq6+f37+//39fX/1c/N/4uJvP9lZsj/bm/S/3Fy + 2P93eOD/iYnn/5OT6/+YmOv/mJjq/5OT6f+Pj+j/jo7o/5GR6P+Wlun/nJzq/6Gh6/+lpez/q6vu/7Cw + 7/+2tvD/u7vx/8DA8v/FxfP/ysr0/8/P9f/U1Pb/19f3/9nZ9//a2vf/2dn3/9fX9v/U1PT/z8/z/8rK + 8v/ExPH/v7/v/7m57P+zs+r/razp/6en5/+goeT/m5vi/5aW4P+QkN7/iorb/4WF2f+Af9f/envU/3Z2 + 0v9wcdD/bG3O/2dpzf9jZMv/YGDJ/1xcx/9YWMT/VlbD/1JSwv9PT8D/TEy+/0lKvv9GR7z/RUa7/0JE + uv9BQbr/QEC5/z4/uP89P7j/PD63/zs8t/84OrX/Nji0/z4+t/9QUL7/ZGXG/3N0zP90dc7/Z2jK/1FT + wv8+QLj/MzSq/ysrof8wLZD/opuu//Dt6f/Hv7//xb29/2BfX6wAAAASAAAADQAAAAYAAAACAAAAAQAA + AAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AF1d + XQWOjo7L+PX1//b09P/y8O//1tDP/8O9wv+no7f/npu+/42Lv/94d8T/dXbR/31+3P+Mjef/nJzt/6Gh + 7f+goOv/m5vq/5iY6v+amur/np7r/6Sk7P+pqe3/rq7v/7Oz7/+4uPD/vb3y/8HB8v/GxvP/ysr0/87O + 9f/R0fb/09P2/9PT9v/S0vb/0ND1/87O8//KyvP/xcXx/8DA8P+7u+7/trbs/6+v6v+qqun/paXn/5+f + 5P+amuL/lJTg/4+P3v+Kitz/hYXa/39/2P96etb/dnXT/3Fx0v9sbdD/aGjO/2VkzP9hYcv/XV3I/1lZ + x/9WVsb/U1PE/1BRw/9NTsD/SkvA/0hJv/9GR77/REW9/0JDvP9AQbv/QEC7/z8/u/87PLn/PD25/0lK + vv9gYcb/dHTN/3V1z/9jZMr/SUu+/zc4rf8zMp7/S0eX/2ljmv+Lhaj/saq4/83HyP/v7On/0MrK/8e+ + vv+zrKz/MTIyaQAAAAIAAAAIAAAAAwAAAAEAAAAAAAAAAP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8AXV1dAGFhYVvCwMD//Pr6//Ty8v/08vL/8O7s//Du + 6v/p5N7/3NbR/8vFxv+wq7r/mZa8/4GAwP99ftH/h4jf/5qa6/+np+//qanu/6Wl7f+goOv/oaHr/6am + 7P+rq+7/sLDv/7W17/+5ufH/vb3y/8HB8v/FxfP/yMjz/8rK9P/MzPT/zMz0/8zM9P/KyvT/x8f0/8TE + 8v/AwPD/vLzv/7e37f+ysuz/ra3r/6io6f+iouf/nZ3l/5iY4/+Tk+L/jo7g/4mJ3f+EhNv/f3/a/3p6 + 1/91ddX/cXHU/2xs0f9oaND/ZWXP/2FhzP9dXcv/WlrJ/1dXyP9UVMf/UVHF/05PxP9LTML/SUrB/0ZH + wf9FRsD/REW+/0FCvv8+P7z/QEC9/1NUxP9rbM3/eHjS/2xsz/9PUML/OTqv/zo5nv9dWJj/j4mp/8C5 + wP/e2db/8Ozk/+3o4//n4uD/3tnY/8nCwv/FvLz/xr6+/3Z0dMsNDQ0SAAAABAAAAAMAAAABAAAAAAAA + AAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wBdXV0AYWFhAGlpaYi9vLz/8/Dw//n29v/39PT/9PHx//Tx8f/18vL/8e7t/+/s6f/l4Nv/0cvL/7ex + vf+YlLv/hoXG/4iJ2f+amun/q6vw/7Cw8P+srO3/p6ft/6io7f+srO3/sbHv/7W18P+5ufH/vLzx/8DA + 8v/CwvP/xMTz/8bG8//GxvP/xcXz/8XF8//CwvP/v7/y/7u78f+3t+//s7Pu/6+v7P+qqur/paXp/6Cg + 6P+bm+b/l5fk/5KS4v+NjeD/h4ff/4OD3f9+ftr/eXnZ/3V11/9xcdb/bGzT/2hp0v9kZdH/YGHO/15e + zP9aWsz/V1fK/1RUyf9RUcj/T0/G/0xMxf9KS8T/SEnD/0ZGwv9CQ8D/Q0TB/1VWxv9wcM//eHnU/2Rl + zv9FRrv/Ozuk/1lVm/+Ri6n/ycPG/+rl4P/u6+X/49/d/9TOzv/KwsL/xr6+/8S7u//Hvb3/yb+//7+3 + t/+Afn7eGBkZMQ0NDQAAAAADAAAAAQAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AF1dXQBhYWEAaWlpAGFhYU+HhobErays98G/ + v/7Z1tb/6OXl//Hu7v/08fH/8O3t//Hu7//y7+//7uvo/+Pd2P/KxMX/qaO5/5COwv+Li9T/m5vm/7Cw + 8f+1tfD/sbHv/6ys7v+tre7/sbHv/7W18P+4uPD/u7vx/7298f++vvL/v7/y/7+/8v+/v/L/vr7y/7y8 + 8f+6uvH/trbw/7Oz7/+vr+7/q6vs/6am6/+ioun/nZ7o/5ma5v+UleX/kJDj/4uL4f+Ght//goLe/319 + 3P95edr/dXXZ/3Bw1v9sbNX/aGjU/2Rl0v9hYtH/Xl7P/1pbzv9XWMz/VFTL/1JSyv9PUMj/TU3H/0tL + xv9GR8T/R0fE/1dXyf9xcdH/eHjW/19gzf9CQ7f/RkOg/3ZxoP+4sbv/5eDa/+/r5f/h3Nr/z8nJ/8e/ + v//Hvb3/ycDA/8W9vf/Aubn/s62t/6OenvyIhYXoUlJSkRMTExwYGRkAAAAAAQAAAAEAAAAAAAAAAAAA + AAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8AXV1dAGFhYQBpaWkAYWFhAF5eXgNcXFwdYWFhQmdnZ2x3dnaclZSU1LSysvvW09P/6+jo//Ht + 7f/t6ur/7+zs/+/s7P/q5+L/1c/M/7Otu/+Rj73/kZHU/6Gh6P+1tfL/uLjx/7Oz7/+uru7/sLDu/7Oz + 7/+2tvD/uLjw/7m58f+6uvH/urrx/7m58f+4uPH/t7fw/7S08P+xse//rq7v/6ur7v+np+z/o6Pr/5+f + 6v+am+j/lpbm/5KS5P+NjuP/iYrj/4WF4P+AgN//fHze/3h42/90dNr/cHDY/2xs1v9oaNX/ZWXU/2Fi + 0/9dXtH/WlvP/1dYzv9VVs3/UlPM/1BQy/9MTcn/SErI/1NVy/9vcNP/envZ/2Fi0P9ERLn/UE2h/4aA + pf/Mxsf/7enj/+fi4P/Uzs3/yMDA/8e/v//JwcH/w7u7/7Krq/+Sjo7td3R0uUxMTIUwMDBYKisrMgME + BA5SUlIAExMTABgZGQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wBdXV0AYWFhAGlpaQBhYWEAXl5eAFxc + XABhYWEAZ2dnAHd2dgBcXFwGXV1dMWhoaHSGhYW9rqys+dbT0//r5+f/7enp/+rn5//u6+v/6+jl/9nT + z/+5s73/mZbA/5CR1f+oqev/ubnz/7m58f+xse//rq7u/7Cw7v+zs+//tLTv/7W17/+0tO//tLTv/7Oz + 7/+ysu//r6/v/62t7v+qqu7/p6fs/6Oj7P+goOv/nJzq/5iX6f+Tk+f/j4/m/4qL5f+Hh+P/g4Ph/35/ + 4P97e9//d3fd/3Nz3P9vb9v/a2vY/2dn1/9kZNb/YWHV/15e0/9bW9L/WFjR/1VWz/9SU87/Tk7M/1FS + zf9patT/fH3b/2lq1f9HSb3/T0yj/5KLqf/V0M3/7enj/+Hd2//NxsX/x76+/8rBwf/Fvb3/sKqq/4uH + h+JhYGCbNDQ0VBQUFBkAAAABTExMADAwMAAqKysAAwQEAFJSUgATExMAGBkZAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AF1dXQBhYWEAaWlpAGFhYQBeXl4AXFxcAGFhYQBnZ2cAd3Z2AFxcXABdXV0AaGhoAIaF + hQBcXFwqamlpf42MjNe/vb3/5ODg/+vn5//o5OT/6+no/+zo5v/Y0s//ta+8/5KQwP+XmNv/r6/u/7u7 + 8/+1tfD/rq7u/6ys7v+uru7/r6/v/6+v7/+vr+//rq7u/62t7v+rq+7/qKjt/6Wl7f+jo+z/oKDr/5yc + 6v+YmOr/lZXp/5GR6P+Njef/iIjm/4WF5f+BgeL/fX7h/3l64P92dt3/cnLd/25v3P9ra9r/Z2fY/2Vl + 2P9hYdf/Xl7V/1tb1P9YWNL/VFXR/1FS0P9hYtT/enrc/3Z23P9SU8f/TEqo/4iCp//Qysr/7enk/97Z + 2f/Kw8P/yL+//8rCwv++t7f/m5eX9WhmZq8zMzNXEBAQEGFgYAA0NDQAFBQUAAAAAABMTEwAMDAwACor + KwADBAQAUlJSABMTEwAYGRkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AXV1dAGFhYQBpaWkAYWFhAF5e + XgBcXFwAYWFhAGdnZwB3dnYAXFxcAF1dXQBoaGgAhoWFAFxcXABqaWkAXV1dCGBgYFB9fHy3sa6u+9zY + 2P/p5eX/5eHh/+rn5//r5+T/083L/6ynuv+Ojsb/n5/j/7W18v+5ufH/r6/u/6mp7f+qqu3/qqrt/6qq + 7f+pqe3/p6fs/6am7P+kpOz/oaHs/5+f6/+cnOr/mZnq/5aW6v+Skun/jo7o/4uL5v+Hh+b/g4Pl/39/ + 5P98e+L/eHjh/3R04P9wcd7/bW7d/2pq3P9naNr/ZGXZ/2Fh2P9eXtf/W1vV/1dX1P9aWtX/c3Pb/39/ + 4P9iYtP/Skmz/3Nvo//Gv8L/7enj/+Dc2//Kw8P/yMDA/8rBwf+3sbH/jImJ5kxLS4chIiIpaGZmADMz + MwAQEBAAYWBgADQ0NAAUFBQAAAAAAExMTAAwMDAAKisrAAMEBABSUlIAExMTABgZGQAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wBdXV0AYWFhAGlpaQBhYWEAXl5eAFxcXABhYWEAZ2dnAHd2dgBcXFwAXV1dAGho + aACGhYUAXFxcAGppaQBdXV0AYGBgAH18fABdXl43dXR0rKuoqPzb19f/5+Li/+Pe3v/q5+b/5+Pf/8rD + xf+dmbv/kpLS/6ip6/+4uPL/sbHv/6en7P+kpOz/paXs/6Sk7P+jo+z/oqLs/6Cg7P+enuv/m5vq/5iY + 6v+Vlen/kpLo/4+P6P+MjOf/iYnn/4WF5v+BgeX/fn7k/3p64/93d+P/c3Ph/3Bv4P9tbN//aWrd/2Zn + 3P9jZNv/YGHa/11e2P9ZWdf/Zmba/35/4f92d+D/UlLE/15bpf+spbT/6OTe/+bh3//Nxsb/x7+//8vC + wv+3sbH/hYOD4EVGRnQQEREVTEtLACEiIgBoZmYAMzMzABAQEABhYGAANDQ0ABQUFAAAAAAATExMADAw + MAAqKysAAwQEAFJSUgATExMAGBkZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AF1dXQBhYWEAaWlpAGFh + YQBeXl4AXFxcAGFhYQBnZ2cAd3Z2AFxcXABdXV0AaGhoAIaFhQBcXFwAamlpAF1dXQBgYGAAfXx8AF1e + XgB1dHQAXFxcNnd2drCxrq7+39vb/+Pe3v/i3t7/6+fm/9/a1f+2sbz/jozA/5eX3v+xsfH/srLv/6Wl + 7P+goOv/oKDs/5+f6/+dnev/nJzr/5qa6v+Xl+n/lZXp/5KS6f+Pj+j/jIzo/4mJ5/+Ghub/g4Pl/39/ + 5f98fOT/eXnj/3V14/9ycuL/b2/g/2xs4P9pad//Zmbe/2Nj3f9eX9v/Xl7a/3Jy3/+Dg+X/ZWfY/09P + s/+Hgaf/19HO/+vo5P/Uzs7/x76+/8vCwv+8trb/i4iI5UVERHYQEBAURUZGABAREQAAAAABAAAAAQAA + AAAAAAAAEBAQAGFgYAA0NDQAFBQUAAAAAABMTEwAMDAwACorKwADBAQAUlJSABMTEwAYGRkAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8AXV1dAGFhYQBpaWkAYWFhAF5eXgBcXFwAYWFhAGdnZwB3dnYAXFxcAF1d + XQBoaGgAhoWFAFxcXABqaWkAXV1dAGBgYAB9fHwAXV5eAHV0dABcXFwAd3Z2AF5eXkWAf3/MwLy8/+Ld + 3f/f2tr/5ODg/+rm4//OyMf/n5u6/5CQ0v+lpuz/sbDx/6Wl7P+bm+r/mprq/5mZ6v+YmOr/lpbp/5SU + 6f+Skuj/j4/n/42N5/+Kiuf/h4fm/4SE5v+BgeX/fn7k/3t74/93d+P/dXXi/3Jy4f9vb+H/bGzh/2lp + 4P9mZt//YWHe/2Rk3v99feT/f37m/1lazP9jYKj/s624/+vm4f/e2dn/yMDA/8rBwf/Fvb3/mpaW901N + TY0REREcRUREABAQEAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAQEBAAYWBgADQ0NAAUFBQAAAAAAExM + TAAwMDAAKisrAAMEBABSUlIAExMTABgZGQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wBdXV0AYWFhAGlp + aQBhYWEAXl5eAFxcXABhYWEAZ2dnAHd2dgBcXFwAXV1dAGhoaACGhYUAXFxcAGppaQBdXV0AYGBgAH18 + fABdXl4AdXR0AFxcXAB3dnYAXl5eAF5fXwdjY2NtlZKS69LNzf/h29v/3djY/+jk4//g29b/tK67/4+N + xf+ZmuP/ra3w/6Wl7f+Xl+n/lZXp/5WV6f+Tk+j/kZHo/4+P6P+MjOf/iorm/4eH5v+Fheb/goLl/39/ + 5P98fOT/eXnj/3Z24/9zc+L/cHDi/25u4P9ra+D/aGjf/2Nj3/9tbeH/hITn/3V24/9YWcD/hH+p/9XO + zP/q5uL/0MrK/8e+vv/Lw8P/raen/2lnZ7ojIyM0TU1NABEREQAAAAABAAAAAQAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAABAQEABhYGAANDQ0ABQUFAAAAAAATExMADAwMAAqKysAAwQEAFJSUgATExMAGBkZAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AF1dXQBhYWEAaWlpAGFhYQBeXl4AXFxcAGFhYQBnZ2cAd3Z2AFxc + XABdXV0AaGhoAIaFhQBcXFwAamlpAF1dXQBgYGAAfXx8AF1eXgB1dHQAXFxcAHd2dgBeXl4AXl9fAGNj + YwBdXV0hcXFxqbKurv/e2Nj/29XV/+Hd3f/o4+D/xr/B/5SSvP+Njtn/pqfu/6Sk7f+Vlen/kJDo/4+P + 6P+Ojuj/jIzn/4qK5v+Hh+b/hITm/4OD5f+AgOT/fX3k/3t75P94eOP/dXXj/3Jy4f9wcOH/bW3h/2pq + 4P9mZt//dHTi/4eH6f9sbdv/X1+0/6Odsf/l4Nv/4dzb/8jAwP/KwcH/wbq6/4iFhec4ODhnAQEBBiMj + IwAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQAGFgYAA0NDQAFBQUAAAA + AABMTEwAMDAwACorKwADBAQAUlJSABMTEwAYGRkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AXV1dAGFh + YQBpaWkAYWFhAF5eXgBcXFwAYWFhAGdnZwB3dnYAXFxcAF1dXQBoaGgAhoWFAFxcXABqaWkAXV1dAGBg + YAB9fHwAXV5eAHV0dABcXFwAd3Z2AF5eXgBeX18AY2NjAF1dXQBxcXEAYGBgWJCOjufRy8v/3dbW/9vV + 1f/o5OP/19HN/6GcuP+EhM3/nZ3q/6Sj7f+Skuj/i4vn/4uL5/+Jief/h4fm/4WF5v+Dg+b/gIDl/35+ + 5P98fOP/eXnj/3Z24/90dOL/cXHh/29v4f9ra+D/aWng/3t75P+Ghun/ZGXS/2tprP+/uL7/6ubh/9bQ + z//Gvb3/y8PD/6ynp/9fX1+wExQUIzg4OAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAQEBAAYWBgADQ0NAAUFBQAAAAAAExMTAAwMDAAKisrAAMEBABSUlIAExMTABgZ + GQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wBdXV0AYWFhAGlpaQBhYWEAXl5eAFxcXABhYWEAZ2dnAHd2 + dgBcXFwAXV1dAGhoaACGhYUAXFxcAGppaQBdXV0AYGBgAH18fABdXl4AdXR0AFxcXAB3dnYAXl5eAF5f + XwBjY2MAXV1dAHFxcQBgYGAAXV1dIXR0dLa6tbX/3NXV/9fR0f/j39//4NrV/6+puv+Dg8X/lJTl/6Gh + 7v+QkOj/hobm/4aG5v+Fheb/g4Pl/4GB5f9+fuT/fHzk/3p65P94eOP/dXXj/3Jy4v9xceH/bW3g/2xs + 4P+AgOb/hITo/2Bhyf99eqv/0cvJ/+fj4P/Nxsb/yL+//8a9vf+QjY3wPT09cAAAAAYTFBQAAAAAAgAA + AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEABhYGAANDQ0ABQU + FAAAAAAATExMADAwMAAqKysAAwQEAFJSUgATExMAGBkZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AF1d + XQBhYWEAaWlpAGFhYQBeXl4AXFxcAGFhYQBnZ2cAd3Z2AFxcXABdXV0AaGhoAIaFhQBcXFwAamlpAF1d + XQBgYGAAfXx8AF1eXgB1dHQAXFxcAHd2dgBeXl4AXl9fAGNjYwBdXV0AcXFxAGBgYABdXV0AX2BgAWRk + ZHignZ3519HR/9bPz//e2dn/5eHd/763vv+FhL//iovg/56e7f+Rken/hITl/4GB5f+AgOX/fn7k/319 + 5P97e+T/eXnj/3Z24/90dOL/cXHi/21t4f9zc+L/hobn/4GB5v9hYcL/kYyu/97Y0//i3t3/x7+//8rB + wf+6tLT/dXNzzxYWFjY9PT0AAAAAAgAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAEBAQAGFgYAA0NDQAFBQUAAAAAABMTEwAMDAwACorKwADBAQAUlJSABMT + EwAYGRkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8AXV1dAGFhYQBpaWkAYWFhAF5eXgBcXFwAYWFhAGdn + ZwB3dnYAXFxcAF1dXQBoaGgAhoWFAFxcXABqaWkAXV1dAGBgYAB9fHwAXV5eAHV0dABcXFwAd3Z2AF5e + XgBeX18AY2NjAF1dXQBxcXEAYGBgAF1dXQBfYGAAZGRkAF5eXkWLiYnjzsjI/9XPz//Y09P/5+Pg/8jB + w/+Jh7v/g4Pb/5qa7P+Wlun/h4fm/39/5P97e+T/eXnk/3h44/92duP/c3Pi/3Fx4v90dOL/f3/l/4yM + 6f97e+L/ZGS+/6Casf/l4Nr/29bV/8W9vf/KwcH/raen/1pZWaQREhIYFhYWAAAAAAMAAAABAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAAYWBgADQ0 + NAAUFBQAAAAAAExMTAAwMDAAKisrAAMEBABSUlIAExMTABgZGQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wBdXV0AYWFhAGlpaQBhYWEAXl5eAFxcXABhYWEAZ2dnAHd2dgBcXFwAXV1dAGhoaACGhYUAXFxcAGpp + aQBdXV0AYGBgAH18fABdXl4AdXR0AFxcXAB3dnYAXl5eAF5fXwBjY2MAXV1dAHFxcQBgYGAAXV1dAF9g + YABkZGQAXl5eAF5eXiF5eHjFwby8/9bOzv/Uzc3/5uLf/9DJyP+Sj7j/eXrQ/46O6P+YmOz/kpLp/4iI + 5v+CguX/f3/k/35+5P9/f+T/hYXm/42N6f+Jier/b2/a/2tquP+uqLf/6OPd/9XQ0P/EvLz/ycDA/52Y + mPpAQEB6AAAABRESEgAAAAADAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEABhYGAANDQ0ABQUFAAAAAAATExMADAwMAAqKysAAwQEAFJS + UgATExMAGBkZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AF1dXQBhYWEAaWlpAGFhYQBeXl4AXFxcAGFh + YQBnZ2cAd3Z2AFxcXABdXV0AaGhoAIaFhQBcXFwAamlpAF1dXQBgYGAAfXx8AF1eXgB1dHQAXFxcAHd2 + dgBeXl4AXl9fAGNjYwBdXV0AcXFxAGBgYABdXV0AX2BgAGRkZABeXl4AXl5eAF5fXw5ubm6itbCw/9TN + zf/Ry8v/49/e/9rU0P+oo7r/eHfB/3d32P+IiOj/kZHr/5GR6/+QkOn/j4/p/46O6v+IiOn/dHXe/2Rk + x/+BfrP/xb/C/+fi3v/Qysr/xby8/8e+vv+LiIjrMTIyVkBAQAAAAAADAAAAAwAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQAGFg + YAA0NDQAFBQUAAAAAABMTEwAMDAwACorKwADBAQAUlJSABMTEwAYGRkAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8AXV1dAGFhYQBpaWkAYWFhAF5eXgBcXFwAYWFhAGdnZwB3dnYAXFxcAF1dXQBoaGgAhoWFAFxc + XABqaWkAXV1dAGBgYAB9fHwAXV5eAHV0dABcXFwAd3Z2AF5eXgBeX18AY2NjAF1dXQBxcXEAYGBgAF1d + XQBfYGAAZGRkAF5eXgBeXl4AXl9fAG5ubgBmZmaGqqWl/9TNzf/Ox8f/3NfW/+Tf2v/Fv8L/lpO3/3t6 + v/9ycs7/d3fX/3Nz2v90dNn/b2/S/2xsxP9/fbT/q6a4/9zX0//i3tv/ysPD/8e9vf/Curr/fnx83RYX + FzkxMjIAAAAABAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAAYWBgADQ0NAAUFBQAAAAAAExMTAAwMDAAKisrAAME + BABSUlIAExMTABgZGQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wBdXV0AYWFhAGlpaQBhYWEAXl5eAFxc + XABhYWEAZ2dnAHd2dgBcXFwAXV1dAGhoaACGhYUAXFxcAGppaQBdXV0AYGBgAH18fABdXl4AdXR0AFxc + XAB3dnYAXl5eAF5fXwBjY2MAXV1dAHFxcQBgYGAAXV1dAF9gYABkZGQAXl5eAF5eXgBeX18Abm5uAGZm + ZgBjY2NrmpeX+c/Hx//Px8f/0crK/9/b2f/f2tX/zsjH/7Suu/+fmrf/mJS5/5uXuP+knrX/xL7B/9nT + z//j39v/1M3N/8W8vP/JwMD/urOz/3RycscWFhYkFhcXAAAAAAMAAAABAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQ + EABhYGAANDQ0ABQUFAAAAAAATExMADAwMAAqKysAAwQEAFJSUgATExMAGBkZAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AF1dXQBhYWEAaWlpAGFhYQBeXl4AXFxcAGFhYQBnZ2cAd3Z2AFxcXABdXV0AaGhoAIaF + hQBcXFwAamlpAF1dXQBgYGAAfXx8AF1eXgB1dHQAXFxcAHd2dgBeXl4AXl9fAGNjYwBdXV0AcXFxAGBg + YABdXV0AX2BgAGRkZABeXl4AXl5eAF5fXwBubm4AZmZmAGNjYwBfYGA+gX9/17iysv/PyMj/zMTE/9DI + yP/X0dH/3tnW/9/a1v/c1tH/3dfS/+Db1//a1NP/0MrJ/8e+vv/Iv7//xb29/6Oenv1PTk6SDxAQDhYW + FgAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQAGFgYAA0NDQAFBQUAAAAAABMTEwAMDAwACor + KwADBAQAUlJSABMTEwAYGRkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AXV1dAGFhYQBpaWkAYWFhAF5e + XgBcXFwAYWFhAGdnZwB3dnYAXFxcAF1dXQBoaGgAhoWFAFxcXABqaWkAXV1dAGBgYAB9fHwAXV5eAHV0 + dABcXFwAd3Z2AF5eXgBeX18AY2NjAF1dXQBxcXEAYGBgAF1dXQBfYGAAZGRkAF5eXgBeXl4AXl9fAG5u + bgBmZmYAY2NjAF9gYABfX18OZ2dnf5CNjeu5s7P/ysLC/83ExP/KwcH/ysLC/8zExP/Kw8P/x7+//8e/ + v//JwMD/w7u7/6ulpf9vbW3DKysrQE9OTgAPEBAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAQEBAAYWBgADQ0NAAUFBQAAAAAAExMTAAwMDAAKisrAAMEBABSUlIAExMTABgZGQAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wBdXV0AYWFhAGlpaQBhYWEAXl5eAFxcXABhYWEAZ2dnAHd2dgBcXFwAXV1dAGho + aACGhYUAXFxcAGppaQBdXV0AYGBgAH18fABdXl4AdXR0AFxcXAB3dnYAXl5eAF5fXwBjY2MAXV1dAHFx + cQBgYGAAXV1dAF9gYABkZGQAXl5eAF5eXgBeX18Abm5uAGZmZgBjY2MAX2BgAF9fXwBnZ2cAX19fGWdn + Z3iBf3/RnZmZ+rGrq/+9tbX/wLi4/7+3t/+2r6//pqGh/42Jie1pZ2epLi4uSgMEBAUrKysAT05OAA8Q + EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEABhYGAANDQ0ABQUFAAAAAAATExMADAw + MAAqKysAAwQEAFJSUgATExMAGBkZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AF1dXQBhYWEAaWlpAGFh + YQBeXl4AXFxcAGFhYQBnZ2cAd3Z2AFxcXABdXV0AaGhoAIaFhQBcXFwAamlpAF1dXQBgYGAAfXx8AF1e + XgB1dHQAXFxcAHd2dgBeXl4AXl9fAGNjYwBdXV0AcXFxAGBgYABdXV0AX2BgAGRkZABeXl4AXl5eAF5f + XwBubm4AZmZmAGNjYwBfYGAAX19fAGdnZwBfX18AZ2dnAF5fXyhlZGRgcnBwlHp4eLh8enrBfHp6wHZ1 + dalwb298Ojo6RA0ODg8uLi4AAwQEACsrKwBPTk4ADxAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAEBAQAGFgYAA0NDQAFBQUAAAAAABMTEwAMDAwACorKwADBAQAUlJSABMTEwAYGRkAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A/////////////////////////////////////////////////////4// + //////////////////gA//////////////////+AAB/////////////////+AAAH//////////////// + +AAAAf////////////////AAAAB////////////////AAAAAP///////////////gAAAAB////////// + /////wAAAAAH//////////////4AAAAAA//////////////8AAAAAAH/////////////+AAAAAAA//// + //////////AAAAAAAH/////////////gAAAAAAA/////////////wAAAAAAAH////////////4AAAAAA + AA////////////8AAAAAAAAH////////////AAAAAAAAB////////////AAAAAAAAAP///////////wA + AAAAAAAB///////////xAAAAAAAAAP//////////8gAAAAAAAAD//////////+QAAAAAAAAAf/////// + ///gAAAAAAAAAD//////////wAAAAAAAAAAf/////////5AAAAAAAAAAD/////////+gAAAAAAAAAA// + ////////QAAAAAAAAAAP/////////0AAAAAAAAAAB/////////6AAAAAAAAAAAP////////9AAAAAAAA + AAAB////////+QAAAAAAAAAAAf////////oAAAAAAAAAAAD////////0AAAAAAAAAAAA////////9AAA + AAAAAAAAAH///////+gAAAAAAAAAAAA////////AAAAAAAAAAAAAP///////0AAAAAAAAAAAAD////// + /6AAAAAAAAAAAAAf//////+gAAAAAAAAAAAAD///////QAAAAAAAAAAAAA///////0AAAAAAAAAAAAAH + //////6AAAAAAAAAAAAAB//////+gAAAAAAAAAAAAAf//////wAAAAAAAAAAAAAD//////8AAAAAAAAA + AAAAA//////+AAAAAAAAAAAAAAH//////gAAAAAAAAAAAAAB//////wAAAAAAAAAAAAAAf/////8AAAA + AAAAAAAAAAD/////+AAAAAAAAAAAAAAA//////gAAAAAAAAAAAAAAH/////4AAAAAAAAAAAAAAB///// + 8AAAAAAAAAAAAAAAf/////AAAAAAAAAAAAAAAD/////wAAAAAAAAAAAAAAA/////4AAAAAAAAAAAAAAA + P////+AAAAAAAAAAAAAAAD/////gAAAAAAAAAAAAAAA/////4AAAAAAAAAAAAAAAH////8AAAAAAAAAA + AAAAAB/////AAAAAAAAAAAAAAAAf////wAAAAAAAAAAAAAAAH////8AAAAAAAAAAAAAAAB/////AAAAA + AAAAAAAAAAAf////gAAAAAAAAAAAAAAAH////4AAAAAAAAAAAAAAAA////+AAAAAAAAAAAAAAAAP//// + gAAAAAAAAAAAAAAAD////4AAAAAAAAAAAAAAAA////+AAAAAAAAAAAAAAAAP////gAAAAAAAAAAAAAAA + D////4AAAAAAAAAAAAAAAA////+AAAAAAAAAAAAAAAAP////gAAAAAAAAAAAAAAAD////4AAAAAAAAAA + AAAAAA////+AAAAAAAAAAAAAAAAP////gAAAAAAAAAAAAAAAD////4AAAAAAAAAAAAAAAA////+AAAAA + AAAAAAAAAAAP////gAAAAAAAAAAAAAAAD////4AAAAAAAAAAAAAAAA////+AAAAAAAAAAAAAAAAP//// + gAAAAAAAAAAAAAAAD////4AAAAAAAAAAAAAAAA////+AAAAAAAAAAAAAAAAP////gAAAAAAAAAAAAAAA + D////4AAAAAAAAAAAAAAAA////+AAAAAAAAAAAAAAAAP////gAAAAAAAAAAAAAAAD////4AAAAAAAAAA + AAAAAB////+AAAAAAAAAAAAAAAAf////gAAAAAAAAAAAAAAAH////4AAAAAAAAAAAAAAAB////+AAAAA + AAAAAAAAAAAf////gAAAAAAAAAAAAAAAH////4AAAAAAAAAAAAAAAB////+AAAAAAAAAAAAAAAA///// + wAAAAAAAAAAAAAAAf////+AAAAAAAAAAAAAABP/////wAAAAAAAAAAAAAAn/////+AAAAAAAAAAAAAA/ + ///////AAAAAAAAAAAAD/////////AAAAAAAAAAAP/////////8AAAAAAAAAAf//////////4AAAAAAA + AAf///////////gAAAAAAAAZ///////////+AAAAAAAAZ////////////wAAAAAAAZ/////////////A + AAAAAAJ/////////////8AAAAAAJ//////////////gAAAAAE//////////////8AAAAAE////////// + /////wAAAACf//////////////+AAAABP///////////////wAAABP////////////////AAAAn///// + ///////////4AAAT/////////////////AAAL/////////////////4AAN//////////////////gAH/ + /////////////////+AH//////////////////////////////////////////////////////////// + //////////////////////////////////8= + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/FolderLocker/ShareFileManager.cs b/Demo_Source_Code/CSharpDemo/FolderLocker/ShareFileManager.cs new file mode 100644 index 0000000..b4d7868 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FolderLocker/ShareFileManager.cs @@ -0,0 +1,256 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows.Forms; +using System.IO; + +using EaseFilter.FilterControl; +using EaseFilter.CommonObjects; + +namespace EaseFilter.FolderLocker +{ + public partial class Form_FolderLocker :Form + { + DRPolicy selectedDRPolicy = new DRPolicy(); + public Dictionary sharedFileList = new Dictionary(); + + + public void InitShareFileListView() + { + textBox_SharedFileDropFolder.Text = GlobalConfig.ShareFolder; + + listView_SharedFiles.Clear(); + //create column header for ListView + listView_SharedFiles.Columns.Add("FileName", 150, System.Windows.Forms.HorizontalAlignment.Left); + listView_SharedFiles.Columns.Add("CreationTime", 100, System.Windows.Forms.HorizontalAlignment.Left); + listView_SharedFiles.Columns.Add("ExpireTime", 100, System.Windows.Forms.HorizontalAlignment.Left); + listView_SharedFiles.Columns.Add("AuthorizedProcessNames", 100, System.Windows.Forms.HorizontalAlignment.Left); + listView_SharedFiles.Columns.Add("UnauthorizedProcessNames", 100, System.Windows.Forms.HorizontalAlignment.Left); + listView_SharedFiles.Columns.Add("AuthorizedUserNames", 100, System.Windows.Forms.HorizontalAlignment.Left); + listView_SharedFiles.Columns.Add("UnauthorizedUserNames", 100, System.Windows.Forms.HorizontalAlignment.Left); + + try + { + foreach (DRPolicy sharedFile in sharedFileList.Values) + { + int index = 0; + ListViewItem lvItem = new ListViewItem(); + string[] listEntry = new string[listView_SharedFiles.Columns.Count]; + + string fileName = sharedFile.FileName; + + if (fileName.EndsWith(GlobalConfig.ShareFileExt)) + { + fileName = fileName.Replace(GlobalConfig.ShareFileExt, ""); + } + + listEntry[index++] = fileName; + long dateTimeN = sharedFile.CreationTime; + DateTime dateTimeD = DateTime.FromFileTime(dateTimeN); + listEntry[index++] = dateTimeD.ToShortDateString();// String.Format("{0:F}", dateTimeD); + dateTimeN = sharedFile.ExpireTime; + dateTimeD = DateTime.FromFileTime(dateTimeN); + listEntry[index++] = dateTimeD.ToShortDateString();//String.Format("{0:F}", dateTimeD); + listEntry[index++] = sharedFile.AuthorizedProcessNames; + listEntry[index++] = sharedFile.UnauthorizedProcessNames; + listEntry[index++] = sharedFile.AuthorizedUserNames; + listEntry[index++] = sharedFile.UnauthorizedUserNames; + + lvItem = new ListViewItem(listEntry, 0); + lvItem.Tag = sharedFile; + + int insertIndex = 0; + if (listView_SharedFiles.Items.Count > 0) + { + for (insertIndex = 0; insertIndex < listView_SharedFiles.Items.Count; insertIndex++) + { + DRPolicy sharedFileInList = (DRPolicy)(listView_SharedFiles.Items[insertIndex]).Tag; + + if (sharedFile.CreationTime < sharedFileInList.CreationTime) + { + break; + } + } + + } + + listView_SharedFiles.Items.Insert(insertIndex, lvItem); + + } + } + catch + { + } + } + + public bool GetSharedFileList() + { + string lastError = string.Empty; + string encryptFileList = string.Empty; + + sharedFileList.Clear(); + + bool retVal = WebAPIServices.GetFileList(ref encryptFileList, ref lastError); + if (!retVal) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show(lastError, "GetFileList", MessageBoxButtons.OK, MessageBoxIcon.Error); + + return false; + } + else + { + if (encryptFileList.Length > 0) + { + List decrypFileList = Utils.DecryptStrToObject>(encryptFileList); + sharedFileList.Clear(); + + foreach (DRPolicy drPolicy in decrypFileList) + { + sharedFileList.Add(drPolicy.EncryptionIV, drPolicy); + } + } + + InitShareFileListView(); + + } + + return true; + } + + + private void toolStripButton_CreateShareFile_Click(object sender, EventArgs e) + { + ShareFileForm shareFileForm = new ShareFileForm(); + + if (shareFileForm.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + GetSharedFileList(); + } + + } + + + private void toolStripButton_RemoveShareFile_Click(object sender, EventArgs e) + { + if (listView_SharedFiles.SelectedItems.Count != 1) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("Please select a file.", "Delete", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + DRPolicy drPolicy = (DRPolicy)listView_SharedFiles.SelectedItems[0].Tag; + string lastError = string.Empty; + + if (!WebAPIServices.DeleteShareFile(drPolicy.EncryptionIV, ref lastError)) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("Delete shared file " + selectedDRPolicy.FileName + " failed with error:" + lastError, "DeleteSharedFile", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + + GetSharedFileList(); + } + + private void toolStripButton_ModifyShareFile_Click(object sender, EventArgs e) + { + if (listView_SharedFiles.SelectedItems.Count != 1) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("Please select a file.", "Edit", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + DRPolicy drPolicy = (DRPolicy)listView_SharedFiles.SelectedItems[0].Tag; + + ShareFileForm shareFileForm = new ShareFileForm(drPolicy); + shareFileForm.Text = "EaseFilter Shared File Modification"; + + if (shareFileForm.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + GetSharedFileList(); + InitShareFileListView(); + } + } + + private void toolStripButton_AccessLog_Click(object sender, EventArgs e) + { + SharedFileAccessLogForm accessLog = new SharedFileAccessLogForm(); + accessLog.ShowDialog(); + + } + + + public bool RefreshSharedFilesInClient() + { + string lastError = string.Empty; + string encryptFileList = string.Empty; + + sharedFileList.Clear(); + + bool retVal = WebAPIServices.GetFileList(ref encryptFileList, ref lastError); + if (!retVal) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show(lastError, "GetFileList", MessageBoxButtons.OK, MessageBoxIcon.Error); + + return false; + } + else + { + if (encryptFileList.Length > 0) + { + List decrypFileList = Utils.DecryptStrToObject>(encryptFileList); + sharedFileList.Clear(); + + foreach (DRPolicy drPolicy in decrypFileList) + { + sharedFileList.Add(drPolicy.EncryptionIV, drPolicy); + } + } + + InitShareFileListView(); + + } + + return true; + } + + private void button_SaveDropFolder_Click(object sender, EventArgs e) + { + if (textBox_SharedFileDropFolder.Text.Length > 0) + { + GlobalConfig.ShareFolder = textBox_SharedFileDropFolder.Text; + } + } + + + private void toolStripButton_RefreshList_Click(object sender, EventArgs e) + { + RefreshSharedFilesInClient(); + } + + + + } +} diff --git a/Demo_Source_Code/CSharpDemo/FolderLocker/SharedFileAccessLogForm.Designer.cs b/Demo_Source_Code/CSharpDemo/FolderLocker/SharedFileAccessLogForm.Designer.cs new file mode 100644 index 0000000..a27b8a6 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FolderLocker/SharedFileAccessLogForm.Designer.cs @@ -0,0 +1,115 @@ +namespace EaseFilter.FolderLocker +{ + partial class SharedFileAccessLogForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(SharedFileAccessLogForm)); + this.toolStrip1 = new System.Windows.Forms.ToolStrip(); + this.toolStripButton1 = new System.Windows.Forms.ToolStripButton(); + this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); + this.listView_AccessLog = new System.Windows.Forms.ListView() ; + this.toolStripButton_ClearMessage = new System.Windows.Forms.ToolStripButton(); + this.toolStrip1.SuspendLayout(); + this.SuspendLayout(); + // + // toolStrip1 + // + this.toolStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.toolStripButton1, + this.toolStripSeparator1, + this.toolStripButton_ClearMessage}); + this.toolStrip1.Location = new System.Drawing.Point(0, 0); + this.toolStrip1.Name = "toolStrip1"; + this.toolStrip1.Size = new System.Drawing.Size(961, 25); + this.toolStrip1.TabIndex = 3; + this.toolStrip1.Text = "toolStrip1"; + // + // toolStripButton1 + // + this.toolStripButton1.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton1.Image"))); + this.toolStripButton1.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButton1.Name = "toolStripButton1"; + this.toolStripButton1.Size = new System.Drawing.Size(123, 22); + this.toolStripButton1.Text = "Refresh access log"; + this.toolStripButton1.Click += new System.EventHandler(this.toolStripButton_GetAccessLog_Click); + // + // toolStripSeparator1 + // + this.toolStripSeparator1.Name = "toolStripSeparator1"; + this.toolStripSeparator1.Size = new System.Drawing.Size(6, 25); + // + // listView_AccessLog + // + this.listView_AccessLog.Dock = System.Windows.Forms.DockStyle.Fill; + this.listView_AccessLog.FullRowSelect = true; + this.listView_AccessLog.HoverSelection = true; + this.listView_AccessLog.LabelEdit = true; + this.listView_AccessLog.Location = new System.Drawing.Point(0, 25); + this.listView_AccessLog.Name = "listView_AccessLog"; + this.listView_AccessLog.ShowItemToolTips = true; + this.listView_AccessLog.Size = new System.Drawing.Size(961, 521); + this.listView_AccessLog.TabIndex = 4; + this.listView_AccessLog.UseCompatibleStateImageBehavior = false; + this.listView_AccessLog.View = System.Windows.Forms.View.Details; + // + // toolStripButton_ClearMessage + // + this.toolStripButton_ClearMessage.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton_ClearMessage.Image"))); + this.toolStripButton_ClearMessage.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButton_ClearMessage.Name = "toolStripButton_ClearMessage"; + this.toolStripButton_ClearMessage.Size = new System.Drawing.Size(111, 22); + this.toolStripButton_ClearMessage.Text = "Clear access log"; + this.toolStripButton_ClearMessage.Click += new System.EventHandler(this.toolStripButton_ClearMessage_Click); + // + // SharedFileAccessLogForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(961, 546); + this.Controls.Add(this.listView_AccessLog); + this.Controls.Add(this.toolStrip1); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Name = "SharedFileAccessLogForm"; + this.Text = "Shared Files Access Log"; + this.Shown += new System.EventHandler(this.AccessLogForm_Shown); + this.toolStrip1.ResumeLayout(false); + this.toolStrip1.PerformLayout(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.ToolStrip toolStrip1; + private System.Windows.Forms.ToolStripButton toolStripButton1; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator1; + private System.Windows.Forms.ListView listView_AccessLog; + private System.Windows.Forms.ToolStripButton toolStripButton_ClearMessage; + } +} \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/FolderLocker/SharedFileAccessLogForm.cs b/Demo_Source_Code/CSharpDemo/FolderLocker/SharedFileAccessLogForm.cs new file mode 100644 index 0000000..6ea16d7 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FolderLocker/SharedFileAccessLogForm.cs @@ -0,0 +1,172 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.IO; +using System.Windows.Forms; + +using EaseFilter.FilterControl; +using EaseFilter.CommonObjects; + +namespace EaseFilter.FolderLocker +{ + public partial class SharedFileAccessLogForm : Form + { + public string accessLogStr = string.Empty; + + public SharedFileAccessLogForm() + { + this.StartPosition = FormStartPosition.CenterParent; + InitializeComponent(); + + toolStripButton_GetAccessLog_Click(null,null); + + InitListView(); + } + + public void InitListView() + { + + listView_AccessLog.Clear(); + //create column header for ListView + listView_AccessLog.Columns.Add("Status", 80, System.Windows.Forms.HorizontalAlignment.Left); + listView_AccessLog.Columns.Add("AccessTime",160, System.Windows.Forms.HorizontalAlignment.Left); + listView_AccessLog.Columns.Add("UserName",100, System.Windows.Forms.HorizontalAlignment.Left); + listView_AccessLog.Columns.Add("ProcessName",100, System.Windows.Forms.HorizontalAlignment.Left); + listView_AccessLog.Columns.Add("FileName",150, System.Windows.Forms.HorizontalAlignment.Left); + listView_AccessLog.Columns.Add("Location", 200, System.Windows.Forms.HorizontalAlignment.Left); + listView_AccessLog.Columns.Add("Description", 350, System.Windows.Forms.HorizontalAlignment.Left); + + try + { + if( accessLogStr.Length == 0 ) + { + return; + } + + string accessLog = Utils.AESEncryptDecryptStr(accessLogStr, Utils.EncryptType.Decryption); + StringReader sr = new StringReader(accessLog); + + while (true) + { + string accessInfo = sr.ReadLine().Trim(); + if (string.IsNullOrEmpty(accessInfo)) + { + break; + } + + try + { + + string[] infos = accessInfo.Split(new char[] { '|' }); + + if (infos.Length < 7) + { + continue; + } + + ListViewItem lvItem = new ListViewItem(); + string[] listData = new string[listView_AccessLog.Columns.Count]; + + if (infos[0].Trim() == "1") + { + listData[0] = "Authorized"; + } + else + { + listData[0] = "Denied"; + listData[6] = infos[6].Trim(); + } + + long accessTimeL = 0; + + if (long.TryParse(infos[1].Trim(), out accessTimeL)) + { + DateTime accessTime = DateTime.FromFileTime(accessTimeL); + listData[1] = accessTime.ToString("F"); + } + + listData[2] = infos[2].Trim(); + listData[3] = infos[3].Trim(); + listData[4] = infos[4].Trim(); + listData[5] = infos[5].Trim(); + + lvItem = new ListViewItem(listData, 0); + + if (infos[0].Trim() == "0") + { + lvItem.BackColor = Color.LightGray; + lvItem.ForeColor = Color.Red; + } + + + listView_AccessLog.Items.Add(lvItem); + } + catch + { + } + } + + } + catch + { + } + } + + private void AccessLogForm_Shown(object sender, EventArgs e) + { + InitListView(); + } + + + private void toolStripButton_GetAccessLog_Click(object sender, EventArgs e) + { + string logStr = string.Empty; + string lastError = string.Empty; + + bool retVal = WebAPIServices.GetAccessLog( ref logStr, ref lastError); + + if (retVal) + { + accessLogStr = logStr; + InitListView(); + } + + } + + private void toolStripButton_ClearMessage_Click(object sender, EventArgs e) + { + string lastError = string.Empty; + + bool retVal = WebAPIServices.ClearAccessLog(ref lastError); + + if (retVal) + { + accessLogStr = string.Empty; + InitListView(); + } + } + + + } +} diff --git a/Demo_Source_Code/CSharpDemo/FolderLocker/SharedFileAccessLogForm.resx b/Demo_Source_Code/CSharpDemo/FolderLocker/SharedFileAccessLogForm.resx new file mode 100644 index 0000000..d3cbfbc --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FolderLocker/SharedFileAccessLogForm.resx @@ -0,0 +1,605 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 132, 17 + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAJWSURBVDhPrZNfSFNhGMZf6CKQIvBi3QRJgUIlNbtIMqGg + pLwXoyS8a1KaElEz/wylNtdY/9Pl2kJKjUk125xQF0nidRgVRBdiS6a5cn/dzpl7+t5vxwbmXT3wci7O + 9/y+9zzve+i/yNI3Dq7uuz6021/ismUEzV1DaOkaPkk1tIkayEoGKtGO/y02rxUDOuzeHKSF2gqMG1W6 + SDcEcINmy8vcG9BsQDabRVpdkYDVok4q3v5YB72vCNRKds2Wl+mWV7PnACkBiKczmAktodnkBl2izUUu + Heq+VkJ3vzBNFtqiWXMy3Xzxx6xmskgqK4gJwOvJz7KmPn3ELs82NM1V42CgGEeu1xs1a06tPR4JCMbn + UTNWi2/RRfxazshgbdM26If1qHq3F92RWhydKMXO27ux407ZgGYnumJ+hiV1CWXe/bgWO4UDoxUIxiLg + bJQVBdXjJ2COnYYbDbAm61DiKsVgYBKanWjQP4HDvkr5kg/x4WP+43B63srOEpkEKl4dknC9uOTD99lc + Nqs6M9SE8iflsj1uk9vd83Qfqu7VSwBn8yP5U37eTDSEcDKD8239eYDHPwXrc7cMiIPiwFyjY/C9eS8B + y2IqCRFsNJWR2SwkVJxre5gHSInRbH1QmOZR8ch4dJwNK57Om8NJFaG4AFx1rAGwxJLwsvDS8PJc6ByQ + AG55Udy6IIyhmIrZiAKDsW8dAK+pWNeCVrG2Yn1tDp8EzMcVYVQwF1UQFOYv4RTOGnvXAayKfxzxA/U4 + RtDY8UiUE43tTvHd/bIMon1+aqf/RUS/AVVJ5okbVkF5AAAAAElFTkSuQmCC + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAJFSURBVDhPrdBbSNNxHAXwo2aKl8ZyMy/brFzWPypvyBQL + iTJCAyWIIOqlMEkjZ4VWCNYg8hIpou1BQyScmvmgwzKjBokJBiL1IoSG1JKcl9wclTZP7u/vyYd88fPy + 53vO4f/ww6aKNYe/SGuKnT1Qox2NNql6cBFFyMceUW9sd0NER82XAra67rB7qZL9rGPuS8P8auWztthI + KXSK8pDvLT9LaXHdYx9rebwn3SlafNiKnAF/xItznWoY0p7FOOqn89g4a6TFXcZuPuBhy6HPYoF3gNoa + hImBABSKSKiALrVNN3NjLJ2myVyaxs8xuzlmuctTTqlx56BYyWzBMNpU8PQF4KiIAOWj4OZroxk0fjIw + oyt6AXeRh2IUWH6VMKxeUSdmsvfbcHIkCnwVitciAlLa9jvODklMtGicqEKCHFZAgWr/SpggybcwokL5 + pB4cVMP7uGviWvXuLJuevnUoE5FsJQLSQhTur4Qh1Hv/UCNhUgvnrAQOR2BKHnlpnihtBquGqMUxEcmW + kwMbWJzIiUhcntbg0tzBwAWm+vFPAjikRpOYrTIjc2+nyrP6vSoS2e9s7RCbztN+KnLp760MMl8is0Jp + 3+UzM6yEVszWbGn3NfqZfcfRge0iwtIFaZzWIvL5FXp/xKpsOtIUjqkdMIjJOu1IQgtyxIXFmydcHKkk + 39wmuwr5NSnkm10Jnaj/j4Cf8/oRN11vybHHZH8JPQ9zuZgc8lRMNsY47JuLDzLPZIb3Ok7rP06diZt3 + pih6Rb0ZgH+vle/bCJhHDQAAAABJRU5ErkJggg== + + + + + AAABAAgAEBAAAAEACABoBQAAhgAAABAQAAABACAAaAQAAO4FAAAYGAAAAQAIAMgGAABWCgAAGBgAAAEA + IACICQAAHhEAACAgAAABAAgAqAgAAKYaAAAgIAAAAQAgAKgQAABOIwAAMDAAAAEACACoDgAA9jMAADAw + AAABACAAqCUAAJ5CAAAoAAAAEAAAACAAAAABAAgAAAAAAEABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP// + /wCFe3sA1LS0AOvZ2QC3kpIAuaqqAPPFxQCXi4sA1svLAKicnADkvLwAw5ycANvX1wDlzs4Apo6OANDB + wQB8c3MAlYGBAODg4ADdxMQAxK2tALWamgD3zMwA7tLSAKOVlQDAlZUA6sjIAJ2FhQCuk5MA5NXVANzR + 0QDcvr4A2ri4AMuwsADn4uIAloaGAKWJiQDk2toA7s3NAK6OjgCumJgAvJycAJ+RkQDhysoAi319AKiS + kgC5lpYAv6qqANfT0wCzlZUA6dPTAO/JyQDbzMwAvZKSANnBwQCaiIgA4dDQAOC6ugDQsrIAqZWVAMKZ + mQDzy8sA29TUAOHNzQC8mZkAw5+fAOHX1wCjjIwA2c/PAODCwgDsy8sAvpeXAOPf3wDe2NgA4dTUAKaU + lADdwcEAuZubAL+dnQDq19cA5dfXAObT0wCik5MA5tDQALyUlADp1dUAo46OAJ+TkwDp0dEA3M/PALmY + mADr0tIA3dbWANnV1QCskpIA38/PALCXlwDm2toAqpKSAKuVlQDa0dEAvpSUAOrU1ACgkpIA59TUAOLW + 1gCnkZEA5dTUAKSUlACllZUAqJSUAN3S0gDb0tIA2svLALSZmQDju7sA27e3ANGzswCaiYkA3dfXAK6S + kgDhz88ArpeXAL6VlQDAlpYAmYiIAO3S0gCfkpIA5dXVAOHW1gDc1tYAqJGRAKmSkgCklZUAtJWVAL+V + lQC6m5sA4bq6AM+ysgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAFcua2tuhhloKyuACAAAAAApgR5RS3F4XYMNMVgAAAAAe0eHOAoTAQEBAV6A + AAAAAGFnUARQUjk1CUpFaAAAAABhRy95RCQCEGUBP1MAAAAAiX9ZXDNnVnpaI3BtAAAAACobW193Bg4s + ckkfTAAAAABBJ0ZNNxhqAQEBQ28AAAAASCdGTTcYQIJLgmA8AAAAAEg0Mg9+i2IBAQEmZAAAAAB8Pooh + diBZaVJsVIQAAAAAZhd0Czp1AzsiFRSFAAAAABoHVQUoJRwSLREwYwAAAAA2iIh9PQxCT04Wcx0AAAAA + AAAAAAAAAAAAAAAAAAD//wAAwAMAAMADAADAAwAAwAMAAMADAADAAwAAwAMAAMADAADAAwAAwAMAAMAD + AADAAwAAwAMAAMADAAD//wAAKAAAABAAAAAgAAAAAQAgAAAAAABABAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAKSPj/qpk5P9qJKS/aiSkv2mlpb8pZaW/KSWlvyhk5P9oJKS/aCSkv2gk5P9mIyM/AAA + AAAAAAAAAAAAAAAAAACwmZn95dXV/+TV1f/l19f/4dTU/9vS0v/d19f/3dbW/9zW1v/b19f/19PT/6CU + lP0AAAAAAAAAAAAAAAAAAAAAsJiY/ezLy/+0lZX/moiI/6icnP/g4OD//////////////////////9nV + 1f+gk5P9AAAAAAAAAAAAAAAAAAAAALKYmP3q1NT/6tfX/+vZ2f/q19f/5tPT/+HQ0P/bzMz/1svL/97Y + 2P/Zz8//oZOT/QAAAAAAAAAAAAAAAAAAAACymJj97MvL/7mWlv+ukpL/o4yM/5aGhv+Fe3v/0MHB/9rR + 0f//////29TU/6OUlP0AAAAAAAAAAAAAAAAAAAAAu5yc/O3S0v/p0dH/69LS/+nT0//q1NT/6dXV/+HP + z//cz8//5+Li/93S0v+llZX9AAAAAAAAAAAAAAAAAAAAAL2dnfzqyMj/uZiY/6ySkv+aiYn/uaqq/+XO + zv/hysr/2svL/+Pf3//c0dH/p5WV/QAAAAAAAAAAAAAAAAAAAAC+mpr97s3N/+DCwv/dwcH/2cHB/+7S + 0v/i1tb/////////////////4dfX/6mVlf0AAAAAAAAAAAAAAAAAAAAAwJiY/e7Nzf/gwsL/3cHB/9nB + wf/u0tL/4c3N/+HW1v/h1NT/4dbW/9/Pz/+rlpb9AAAAAAAAAAAAAAAAAAAAAMCYmP3vycn/s5WV/6aO + jv+ZiIj/z7Ky/+ba2v/////////////////k2tr/rZaW/QAAAAAAAAAAAAAAAAAAAADAlpb988vL/+G6 + uv/auLj/0bOz/9y+vv/p0dH/59TU/+bT0//l1NT/5tDQ/6mSkv0AAAAAAAAAAAAAAAAAAAAAwJWV/ffM + zP/ju7v/5Ly8/+C6uv/bt7f/1LS0/9Cysv/LsLD/xK2t/93ExP+rk5P9AAAAAAAAAAAAAAAAAAAAAMKW + lv3zxcX/vJSU/7eSkv+ujo7/pYmJ/52Fhf+VgYH/i319/3xzc/+/qqr/rJOT/QAAAAAAAAAAAAAAAAAA + AAC/k5P6wZaW/cGWlv3Cl5f9xJqa/cWdnf3FoKD9wZ6e/bucnP23m5v9tpqa/bCUlPsAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAD//wAAwAMAAMADAADAAwAAwAMAAMADAADAAwAAwAMAAMADAADAAwAAwAMAAMADAADAAwAAwAMAAMAD + AAD//wAAKAAAABgAAAAwAAAAAQAIAAAAAACgAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8AlXh4AOCx + sQBeXV0ApqKiAP/U1ADUz88AypqaAK2HhwB7bW0A5uDgAMGtrQDpxMQAnZOTAM67uwC1mJgA6tLSAPP1 + 9QCZhIQAh39/ALuMjAC/oqIAa2NjANCkpADdvb0A0cXFAN7X1wDTrq4A4czMAKmQkAD2zs4AsqSkAIt0 + dACkmpoApYKCAIJ4eADnu7sAcmhoAPXV1QCcfX0A3MTEAM20tACtm5sAyKGhAPj7+wCciooAyq6uAMGc + nADxyckA29HRANjKygC5q6sAgnBwANm4uACcm5sAuJOTAOPb2wC3oKAA1bS0AOrKygCulpYA49LSANHK + ygCvoKAA8NDQAOLCwgC6nJwAo5SUAIh4eADh4OAA6M7OAJ+PjwC2j48A0be3AHNsbADX09MAqIyMALaK + igC+qakAqZSUAMilpQC5p6cA+tPTAOXJyQDdyckAqIiIANi8vADWq6sAtJ2dAM2goACXiooApJCQAIuB + gQDtxsYA1sfHAMSfnwDs1dUA9Pj4AP7R0QD00tIA4s/PANrU1ADX0NAAm46OAOK/vwDRsrIAu5+fAPv9 + /QD50NAAmX9/APLU1ADm1NQA3s7OANDNzQCmlpYA1MPDAKuiogDHsLAA4NHRANnHxwC0oKAAxa2tAO7S + 0gDs0NAA2szMAKWgoACooKAAs5qaALiamgCwnp4AsKKiANO1tQDKo6MAw6urAOPh4QDzz88A5dDQAN3T + 0wDlzc0Aq5eXAMKhoQD5+fkA5t7eAPfS0gDn0tIA6dDQAOHKygDmxMQA0sfHANGiogDFoaEAzaSkAPrV + 1QD20NAA1cnJAKakpACroKAAt6KiAL+goADZuroAwqOjAPb6+gD+09MA+NTUAO/PzwDqzc0A2dLSAN/P + zwDZz88A3svLANjIyAC/nZ0Az6GhAMyvrwD6+/sA/NHRAPLS0gDw0tIA7NLSAOXS0gDn0NAA2NTUAOPN + zQCpoqIA1s/PAK6iogDcy8sA0s3NANrKygC6oKAAtKSkANPJyQC9oKAAyqGhANWurgDPsrIA/9LSAPvU + 1ADh398A99XVAPbU1AD01NQA+NHRAOPa2gD00dEA69PTAOvR0QC2l5cA5NPTAOrPzwDi0dEA5s/PAOHQ + 0ADc0NAA4c7OANbR0QDa0NAA4szMANTQ0ADfzc0Aw6CgAMagoADgyckAyaCgANnLywDQy8sA0qOjANrG + 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 + lv+plJT/pJCQ/5+Pj/+Xior/sJ6e//LU1P+9oqL4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA0KKi+P/S + 0v/gsbH/u4yM/7aKiv+th4f/pYKC/5x9ff+VeHj/i3R0/4JwcP97bW3/cmho/2tjY/9eXV3/h39///XV + 1f+/oqL4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1KSk+P/U1P/+0dH//tPT//7S0v/90tL//dPT//3T + 0//71NT/+9TU//rV1f/609P/+tTU//jU1P/41NT/9tLS//XU1P/CpKT4AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAzpub8dWlpfjSo6P40aOj+NCjo/jQo6P4zaOj+Myjo/jLo6P4yqOj+Mmjo/jIo6P4x6Oj+Maj + o/jFo6P4xKOj+MWlpfi6m5vxAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA////AOAABwDgAAcA4AAHAOAABwDgAAcA4AAHAOAABwDgAAcA4AAHAOAABwDgAAcA4AAHAOAA + BwDgAAcA4AAHAOAABwDgAAcA4AAHAOAABwDgAAcA4AAHAOAABwD///8AKAAAACAAAABAAAAAAQAIAAAA + AACABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8AlXR0ANO2tgBJTEwA/tTUAKuZmQBqZmYA1tLSAOjr + 6wC0hIQAx5iYAPLExAC8r68AgWtrAF5YWADSpqYAl5SUAM7ExADq09MAoYGBAOG/vwDy9vYA3uHhAH53 + dwC/jIwA4crKAMW3twC2k5MAs6ioAGBhYQD3zs4AiHJyAHZlZQCik5MAVlJSAJ55eQBrXl4A18nJAKyA + gADXvb0A7s3NAPXV1QDg0tIAwJOTAMbAwADqvb0AybGxANy4uADOvLwArYeHAJmZmQCtk5MAd2trAJV6 + egC0iooA+fv7ANzFxQDv8fEAjG1tALOYmABkXFwA+tjYAObOzgDczs4A0s3NAMStrQBxYWEA18LCAOLl + 5QCPdnYA6MnJAKeDgwCcfn4Afm9vANvd3QDx0NAAy8jIAMy1tQCclJQA/NDQAOO7uwDMwMAAZGRkAJBw + cAC4jY0Ap5aWANzCwgDdvLwA07q6AHJqagD51NQAhmxsAINxcQCYd3cA4cbGANDKygBvZmYA8szMAOXS + 0gDc0tIA28nJANi2tgC7k5MA0r29ALyKigDWqKgAinV1AOzQ0ADY1dUAoHx8ANTFxQDz8/MA9tDQAOHP + zwDXzMwA2Lq6AKiTkwDOubkAs5WVAMa0tABNTU0AaGNjAJFzcwDmzMwA08HBAJeWlgB7bW0A59XVAN7M + zADDlZUAybe3APv9/QBiWloA9tbWAO/OzgDo0NAA3dDQANnQ0ADU0NAA48jIANDHxwDYwMAAc2RkAPvV + 1QD/0dEA+tDQAOrNzQDjzc0AqX5+AOC6ugDVwMAAycHBANC1tQBKTk4A/P//APHz8wCBaWkAkHh4APPS + 0gDw0tIA5NDQAK2BgQDVzs4A2szMANTMzACZlJQA5ry8AOS9vQCflJQAzcbGAKWTkwDcv78A0cPDAM3C + wgCwk5MAz8DAALOTkwDLs7MAZGJiAPnR0QDyz88A0MzMANO4uABgWVkA9Pf3AOrs7AD719cA4OLiAPnW + 1gD709MA99LSAPTPzwDu0dEA9czMAOzS0gDo09MA7M7OAOvPzwDi0dEA4c3NALKJiQDkysoA38nJALqM + jAC9jY0A0srKAKmVlQDewMAA28LCANq7uwDUvb0A1bu7ANG7uwDWt7cA1bW1ANK0tADHuLgA+/v7AIRs + bADw9vYA8PHxAKB5eQDwzMwA5tHRAOjOzgDe0tIA39DQANjS0gDb0NAA19DQAN3OzgCrk5MA2c7OANzM + zADTzs4AuZOTAL6TkwDYyckA2MLCANXBwQByYmIAdWRkAHZqagD9/v4A8/X1AJd2dgCbfX0A/9XVAP/T + 0wD519cAooCAAPzU1AD61NQA/dHRAPfV1QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAGVqsiIiKpqampqU9PT0+mpqamERERfjMAAAAAAAAAAM+Ax+Pj44mJiYnliuWKiuaK5ovmi4ttfgAA + AAAAAAAAdWOB6oGkpKSkpHNzc6VzpaVBQUG2QQgRAAAAAAAAAAB1oYHjcuOJ44lAjeulpUFBQUFBQU22 + CBEAAAAAAAAAAHVjcllZdoMbDe7mAdra2tra2tr0CWAIpgAAAAAAAAAANODHaZX22/EjG6P13d3d3d3d + 3XC8zgimAAAAAAAAAAA0iHKhoWOAxGPHb65SUphSmJiYmC1z5KYAAAAAAAAAADSIlJShcqFycnJycuPj + iUCkqs5gqqVkTwAAAAAAAAAANIg/V1fR70SXaGgxMdkmQGUJAQG6JmRPAAAAAAAAAACvbIgZCifeAjud + ISW4eR1yZRdwcLwm4k8AAAAAAAAAAK9sP3x8P5Q/lJRylHKBcoGBUhISmKTiqQAAAAAAAAAAr8F8iD+I + iOCIiOCUyMjIgYGNc3ONpCupAAAAAAAAAACxwcbQrKwo1NV2eIjIyMiBgUUBAQllK6kAAAAAAAAAALHB + bGknJFSdQ4UEw5TIyMiBS5xwvGUrIgAAAAAAAAAAsaDFxWxsbGxswz/hlHyUlJSwra1SgcciAAAAAAAA + AAAcTClsbGzBwcHG4T856aRzc+lz6aVlxyIAAAAAAAAAAByfTBVY0nS3TlnG4WgBhISEhIT0uUTEIgAA + AAAAAAAAHJ9MLJVeXPIPGKCT0xY6Ojo6OpwJRMSrAAAAAAAAAADscYe1TJ+fKp+HxZOMRPDw8PB9fa0a + xKsAAAAAAAAAAOxx30y1TExMTEzBxV/iQEDnQEBAc8sTqwAAAAAAAAAA7L/AqJYwZtYDmUKHKJs4ODg4 + OIS50RN1AAAAAAAAAABntHGCom57Do89mkeO3Do6Ojo6nAlXE3UAAAAAAAAAAGe0H3G/v79b/ZC/wEfv + jo6XjpdEfcrDdQAAAAAAAAAAZ/7CwmLCYmLfYt8pKd+HKSkpk5OT4cPoAAAAAAAAAADt/h+Svr78/P39 + kJC9vbu7u/o+PirGwTQAAAAAAAAAAO3+khBVVckySBRJNp5rXUo1WgezU4agNAAAAAAAAAAALJFQas3M + NzJI+/c2RiBdf/Nheh4e+qA0AAAAAAAAAAAskVAMLi6np1GWljAwZmbX2JmZsi+fn68AAAAAAAAAAIL4 + kZH5+fn5+fkFBQX8/JCQkL29W5//dwAAAAAAAAAAC4IsLCzt7WdnZ2fs7OwcHBwcsbGxsXc8AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AA + AA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AA + AA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/////8oAAAAIAAAAEAAAAABACAAAAAAAIAQ + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAArJiY56iWlvCllJTwpJSU8KSU + lPCilJTwoZSU8KCUlPCglJTwn5SU8J6UlPCdlJTwnJSU8JyUlPCblJTwmpSU8JmUlPCZlJTwmJSU8JeU + lPCWlJTwlpSU8JaWlvCYmJjnAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACrlpb159XV/+LR + 0f/g0ND/39DQ/+DQ0P/e0ND/3dDQ/9zQ0P/d0ND/29DQ/9rQ0P/b0ND/2dDQ/9jQ0P/X0ND/2NDQ/9bQ + 0P/V0ND/1tDQ/9TQ0P/T0dH/2NXV/5iWlvUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKmU + lPXk0tL/3s3N/9zMzP/dzMz/28zM/9rMzP/ZzMz/2czM/9nMzP/YzMz/2MzM/9bMzP/VzMz/1szM/9TM + zP/TzMz/0szM/9LMzP/RzMz/0MzM/9HNzf/V0tL/l5SU9QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAqpSU9eTR0f/ezMz/38/P/+DPz//fz8//3tDQ/9/Q0P/e0ND/3M7O/9DHx//Tzs7/08zM/9PM + zP/SzMz/0szM/9LMzP/RzMz/0czM/9LNzf/LyMj/0MvL/9XS0v+YlJT1AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACrlJT15dHR/+HPz//Tu7v/0rq6/825uf/Jt7f/xba2/7yvr//Yycn/19HR//7/ + ///7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v//f7+/+nr6//Qycn/1tLS/5mUlPUAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAK6UlPXm0dH/49HR/7uKiv+pfn7/l3Z2/4RsbP9yYmL/VlJS/8W3 + t//Vzs7/8/X1//Dx8f/w8fH/8PHx//Dx8f/w8fH/8PHx//Dx8f/z8/P/4OHh/9LKyv/X0tL/mpSU9QAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAArpSU9efR0f/izs7/5NDQ/+TR0f/l0tL/5tTU/+fT + 0//l0tL/4tDQ/9TFxf/NwsL/y8DA/8zAwP/KwMD/y8DA/8nBwf/KwcH/yMHB/8rBwf/GwMD/1svL/9jS + 0v+blJT1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACvlJT16NHR/+TMzP/jzs7/48/P/+LP + z//jz8//4s/P/+HPz//hz8//4dDQ/+HQ0P/g0ND/4NDQ/93Pz//bzs7/28vL/83Gxv/Sysr/0MrK/8zG + xv/Vy8v/29LS/5yUlPUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALCUlPXp0dH/5s/P/9zC + wv/cwcH/28LC/9jCwv/XwcH/1b+//9K+vv/Rvb3/zry8/868vP/HuLj/18jI/9zOzv/aycn/6Ovr//7/ + ////////6uzs/9bJyf/c0tL/nZSU9QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsZSU9ezR + 0f/o0dH/v4yM/7SEhP+sf3//oHl5/5V0dP+MbW3/gGlp/3ZlZf9rXl7/YFlZ/01NTf+zqKj/4M/P/9vJ + yf/e4eH/8/T0//P09P/g4uL/18nJ/93S0v+elJT1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACylJT17NHR/+fOzv/my8v/5czM/+bOzv/kzc3/5c7O/+POzv/jzc3/4s7O/+LNzf/izs7/3szM/+DP + z//ezc3/3cvL/8zBwf/OxMT/zsTE/8nBwf/Zy8v/3tLS/5+UlPUAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAALOUlPXt0dH/58zM/+jPz//nz8//6NDQ/+fQ0P/m0ND/6NHR/+fR0f/m0dH/5M7O/+HN + zf/gzc3/4MzM/97MzP/ezMz/0MbG/9bLy//Wy8v/z8fH/9rLy//f0tL/oJSU9QAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAtJSU9e7R0f/qz8//3sDA/9y/v//bv7//1729/9W7u//Ru7v/zrm5/8a0 + tP/n0ND/4czM/+DMzP/gzMz/38zM/97Ly//i5eX//v////7////o6+v/2snJ/+DS0v+hlJT1AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC1lJT179HR/+zR0f+8ior/rICA/555ef+QcHD/gWlp/3Fh + Yf9iWlr/SUxM/+vS0v/izMz/4czM/+HMzP/gzMz/38vL/9vd3f/x8/P/8vPz/9/i4v/bycn/4dLS/6KU + lPUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALaUlPXw0dH/687O/+zNzf/s0ND/69DQ/+zQ + 0P/r0ND/7NHR/+vS0v/nzs7/6c7O/+TMzP/lzMz/48zM/+LMzP/jzMz/z8DA/9HDw//Qw8P/zMHB/9/L + y//i0tL/o5SU9QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAt5SU9fHR0f/tzMz/7c/P/+3P + z//s0ND/7tDQ/+3R0f/t0dH/6s/P/+jOzv/mzc3/3MXF/9nOzv/ZzMz/18zM/9jNzf/Zzc3/2M3N/9nN + zf/Vy8v/2snJ/+PS0v+klJT1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC4lJT19NHR//DP + z//hv7//3by8/9q7u//Yurr/07i4/8y1tf/Turr/68/P/+jNzf/Svb3///////v8/P/7/Pz/+/z8//v8 + /P/7/Pz//P7+//T39//WwsL/59PT/6WUlPUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALmU + lPX00dH/8dHR/8CSkv+pfn7/mHd3/4ZsbP91ZGT/XlhY/353d//w0tL/6c3N/9S9vf/y9vb/7/Hx/+/x + 8f/v8fH/7/Hx/+/x8f/w8/P/6Ozs/9fCwv/n09P/ppSU9QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAupSU9fXR0f/wzs7/8s7O//LR0f/z0dH/89LS//TU1P/y0tL/78/P/+zOzv/pzc3/48jI/9bC + wv/VwcH/1cHB/9TBwf/UwcH/08HB/9PBwf/RwsL/4crK/+jS0v+nlJT1AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAC7lJT19tHR//DMzP/xz8//8s/P//LQ0P/x0ND/8dDQ//LR0f/x0dH/79DQ/+3O + zv/hxsb/3tHR/9zOzv/czs7/3c7O/9vOzv/bzs7/3M/P/9jNzf/fycn/6dLS/6iUlPUAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAALyUlPX30dH/9M/P/+S9vf/gu7v/3Lm5/9m3t//Wt7f/07a2/8+0 + tP/Era3/787O/9e9vf/8////+fv7//n7+//5+/v/+fv7//n7+//7/f3/8/f3/9rCwv/q09P/qZSU9QAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAvZSU9fjR0f/20ND/w5SU/62Bgf+gfHz/kXNz/4Fr + a/9zZGT/ZFxc/0pOTv/oycn/2b+///D29v/u8fH/7/Hx/+/x8f/v8fH/7/Hx//Dz8//o7Oz/3MLC/+vT + 0/+qlJT1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC+lJT1+dHR//bOzv/3z8//99LS//jS + 0v/40tL/+dPT//nU1P/61dX/99LS//PPz//nyMj/2MLC/9fAwP/YwMD/1sDA/9fAwP/VwMD/1sHB/9LB + wf/kysr/69LS/6uUlPUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL+UlPX80dH/9czM//TM + zP/zzMz/9MzM//LMzP/xzMz/8MzM//HMzP/vzMz/7szM/+7Nzf/wzc3/783N/+3Nzf/uzc3/7c3N/+vN + zf/qzc3/683N/+jNzf/s0tL/rZSU9QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwJSU9fzR + 0f/3zc3/+c/P//vS0v/709P//NTU//vU1P/61NT/+tTU//zV1f/71dX/+tbW//nW1v/719f/+tfX//rX + 1//519f/+djY//rY2P/11dX/68/P/+3R0f+ulJT1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AADBlJT1/dHR//rQ0P/Spqb/uIyM/7iNjf+yiYn/rIeH/6eDg/+hgYH/nH5+/5V6ev+QeHj/inV1/4Nx + cf9+b2//d2tr/3Jqav9qZmb/ZGJi/2RkZP/21tb/8NHR/66UlPUAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAMKUlPX+0dH//NDQ/9aoqP+9jY3/uoyM/7SKiv+thob/p4OD/6KAgP+bfX3/lHp6/492 + dv+IcnL/gnFx/3ttbf92amr/b2Zm/2hjY/9gYGD/YGFh//jX1//w0dH/sJSU9QAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAw5SU9f/S0v/8z8//8sTE/+q9vf/pvLz/5ru7/+W8vP/ju7v/4Lq6/9+5 + uf/duLj/3Le3/9i2tv/Xtrb/1bW1/9K0tP/QtbX/z7S0/8uzs//JsbH/8tLS//LS0v+xlJT1AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADGlpb1/9XV///R0f//0tL//9PT///T0///09P//tPT///T + 0//+09P//dTU//7U1P/91NT//NTU//vU1P/81dX/+9XV//rV1f/51dX/+dXV//jU1P/00tL/99XV/7SW + lvUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMqYmO3Glpb1w5SU9cKUlPXClJT1wZSU9cCU + lPW/lJT1vpSU9b6UlPW9lJT1vJSU9buUlPW6lJT1uZSU9bmUlPW4lJT1t5SU9baUlPW1lJT1tZSU9bSU + lPW1lpb1tZiY7QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/////wAAAP8AAAD/AAAA/wAAAP8AAAD/AA + AA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AA + AA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA//////KAAAADAAAABgAAAAAQAIAAAA + AACACgAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8AlXR0ANO2tgBJTEwA/tTUAKuZmQBqZ2cA1NLSAOjr + 6wC0hIQAxJycAPHAwAC7ra0AgWtrAF5YWADNpqYAlYyMAM7ExADq09MAn4ODAOK/vwDy9vYA3+DgAIF4 + eADAjo4A4svLAMW3twC2k5MAuKOjAF9fXwD4zc0AhnR0AHZlZQChkZEAVlJSAJ55eQBrXl4A18nJAKyA + gADYvr4A7s3NAPXV1QDg0tIAwJKSAMS+vgDrv78AzK+vANy4uADOvr4ArIiIAJuYmACulJQAdm1tAJR9 + fQC0i4sA+fr6ANvFxQDu8PAAjG1tALSamgBkXFwA+tjYAObOzgDczc0A0s3NAMSpqQBxYWEA1sTEAOTm + 5gCNdnYA58fHAKaFhQCYgYEAfnBwANvb2wDw0NAAyMbGAMy1tQCdk5MA/M/PAOa1tQDLv78AZGRkAJBw + cAC4jo4ApZiYANzDwwDdvb0A07m5AHFqagD51NQAhmxsAIJycgCYd3cA4cbGANDKygBuaGgA8szMAOXS + 0gDc0tIA28nJANi2tgC7lZUA0r6+ALyKigDVra0AiHZ2AO3PzwDX19cAoHx8ANXGxgDz8/MA9dHRAOHP + zwDXzc0A2Lu7AKmRkQDPuroAs5WVAMi1tQBNTU0AamRkAJFzcwDnzMwA0sLCAJmXlwB6bm4A59XVAN7M + zADClpYAy7e3APz9/QBiWloA9tbWAO/OzgDpz88A3s/PANnQ0ADT0dEA5MfHANDHxwDYwMAAc2RkAPvV + 1QD/0dEA+s/PAOrNzQDjzc0AqX5+AOK2tgDVwMAAyMHBANC1tQBKTk4A/P//APHz8wCBaWkAjnl5APXS + 0gDw0tIA5M/PAK2BgQDVzc0A2szMANTMzACakZEA576+AOW/vwCgl5cAysXFAKaUlADcvr4A0cPDAMzD + wwCwkJAA0L+/ALSQkADPsbEAZGFhAPnR0QDyz88A0M3NANO4uABgWVkA9vf3AOzu7gD719cA4uPjAPnW + 1gD709MA99LSAPXPzwDv0NAA9czMAOzS0gDo09MA7M7OAOvPzwDi0tIA4c3NALCKigDlyckA3snJALqN + jQC9jo4A0srKAKmVlQDewMAA28LCANq8vADVvr4A1rq6ANG6ugDWt7cA1bW1ANGzswDGu7sA+/v7AIRs + bADw9vYA8PHxAKB5eQDvzMwA5tHRAOjOzgDe0tIA4NDQANjS0gDb0NAA19DQAN7OzgCrk5MA2c3NANzM + zADQz88AuZWVAL6VlQDZysoA2cPDANXCwgByYmIAdWRkAHZqagD9/v4A9PX1AJd2dgCZfX0A/9XVAP/T + 0wD519cAoYCAAPzU1AD61NQA/dHRAPfV1QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + 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 + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACrmZnaq5iY56mYmOeql5fnqJeX56mXl+eml5fnp5eX56WX + l+eml5fnpJeX56WXl+ejl5fno5eX56SXl+eil5fno5eX56GXl+eil5fnoJeX56GXl+efl5fnoJeX556X + l+efl5fnnJeX552Xl+ebl5fnnJeX55qXl+ebl5fnmZeX55mXl+eal5fnmJeX55mYmOeYmJjnmZmZ2gAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACrmJjwyLW1/9HAwP/Rv7//z7+//9C/ + v//Qv7//z7+//8+/v//Ov7//zr+//82/v//Nv7//zL+//8y/v//Lv7//y7+//8u/v//Kv7//yr+//8m/ + v//Jv7//yL+//8i/v//Hv7//x7+//8a/v//Gv7//xb+//8W/v//Ev7//xL+//8O/v//Dv7//wr+//8PA + wP+3tbX/mZiY8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACrl5fw0b+//9/O + zv/dzc3/3c3N/9zNzf/czc3/283N/9vNzf/bzc3/2s3N/9rNzf/Zzc3/2c3N/9jNzf/Yzc3/183N/9fN + zf/Xzc3/1s3N/9bNzf/Vzc3/1c3N/9TNzf/Uzc3/083N/9PNzf/Tzc3/0s3N/9LNzf/Rzc3/0c3N/9DN + zf/Qzc3/z83N/9DOzv/Bv7//mJeX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACtl5fw0b6+/97Nzf/dzMz/3MzM/9zMzP/czMz/28zM/9vMzP/azMz/2szM/9nMzP/ZzMz/2MzM/9jM + zP/YzMz/18zM/9fMzP/WzMz/1szM/9XMzP/VzMz/1MzM/9TMzP/UzMz/08zM/9PMzP/SzMz/0szM/9HM + zP/RzMz/0MzM/9DMzP/QzMz/z8zM/9DNzf/Cvr7/mZeX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACsl5fw076+/9/Nzf/ezMz/3czM/93MzP/czMz/3MzM/9vMzP/bzMz/2szM/9rM + zP/azMz/2czM/9nMzP/YzMz/2c3N/9fMzP/XzMz/2MzM/9bMzP/XzMz/1czM/9XMzP/UzMz/1MzM/9PM + zP/TzMz/08zM/9LMzP/SzMz/0czM/9HMzP/Rzc3/0MzM/9DNzf/Bvr7/m5eX8AAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACtl5fw0r6+/+DNzf/ezMz/3szM/93MzP/dzMz/3czM/9zM + zP/czMz/28zM/9vMzP/azMz/2szM/9nMzP/azc3/yL+//9TS0v/T0dH/09HR/9PR0f/U0dH/0tHR/9LR + 0f/S0dH/0tHR/9LR0f/S0dH/0tHR/9LR0f/T0dH/0dHR/9PS0v/Dv7//0s3N/9HNzf/Cvr7/mpeX8AAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACvl5fw076+/+DNzf/fzMz/4M3N/+DQ + 0P/h0ND/4NDQ/+HQ0P/g0dH/4dHR/+DS0v/h0tL/4tLS/97Pz//czc3/ycDA//39/f/5+vr/+fr6//n6 + +v/6+vr/+vr6//r6+v/6+vr/+vr6//r6+v/6+vr/+vr6//r6+v/6+vr/+vr6//3+/v/Bvb3/0s3N/9LN + zf/Dvr7/nJeX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACul5fw1L6+/+HN + zf/gzc3/2sTE/7mPj/+0kJD/rYuL/6SHh/+cg4P/lH9//4p6ev+BdXX/dW5u/6CXl//ez8//x7+///X1 + 9f/y8vL/8vLy//Ly8v/y8vL/8vLy//Ly8v/y8vL/8vLy//Ly8v/y8vL/8vLy//Ly8v/y8vL/8vLy//X2 + 9v/BvLz/083N/9PNzf/Fvr7/m5eX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACwl5fw1r6+/+LNzf/izc3/3MTE/76MjP+1i4v/rIaG/6GAgP+Ye3v/jXZ2/4Jycv93bGz/amRk/5qS + kv/g0ND/yMDA//Dw8P/u7u7/7u7u/+7u7v/u7u7/7u7u/+7u7v/u7u7/7u7u/+7u7v/u7u7/7u7u/+7u + 7v/u7u7/7u7u//Dx8f/BvLz/1M3N/9PNzf/Evr7/nJeX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACvl5fw1b6+/+PNzf/hzMz/4cvL/93Fxf/cxsb/3MXF/9rExP/YxcX/18TE/9XD + w//VwsL/0sLC/9bGxv/ezc3/y8DA/8vGxv/KxcX/ysXF/8rFxf/KxcX/ysXF/8rFxf/JxcX/ycXF/8nF + xf/JxcX/ycXF/8nFxf/IxcX/yMXF/8jGxv/HwMD/1M3N/9TNzf/Fvr7/npeX8AAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwl5fw1r6+/+PNzf/izMz/4czM/+HNzf/izc3/4M3N/+HN + zf/gzc3/4M3N/9/Nzf/fzc3/383N/97Nzf/ezMz/3c3N/93Nzf/czMz/3MzM/9vMzP/bzMz/28zM/9rM + zP/azMz/2czM/9nNzf/Zzc3/2c3N/9fNzf/Xzc3/2M3N/9bNzf/Wzc3/1MzM/9XNzf/Hvr7/nZeX8AAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACyl5fw2L6+/+TNzf/jzMz/4szM/+LM + zP/hzMz/4czM/+DMzP/gzMz/4MzM/9/MzP/fzMz/3szM/97MzP/dzMz/3czM/9zMzP/czMz/3MzM/9vM + zP/bzMz/2szM/9rMzP/ZzMz/2czM/9nLy//Evb3/yMLC/8jCwv/IwsL/yMLC/8fDw//Mw8P/1s3N/9XN + zf/Gvr7/n5eX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACxl5fw176+/+XN + zf/jzMz/5M3N/+TOzv/kzs7/5M/P/+PPz//jz8//4s/P/+PPz//hz8//4s/P/+LPz//hz8//4s/P/+HQ + 0P/h0ND/4NDQ/+DQ0P/f0ND/3s/P/9zMzP/azMz/2szM/9jJyf/f4OD//f7+//v8/P/7/Pz/+/z8//// + ///Evb3/183N/9bNzf/Hvr7/npeX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACyl5fw2L6+/+bNzf/kzMz/4cbG/8ympv/Lpqb/yaam/8Wjo//Co6P/vqCg/7uenv+4np7/tJub/6+Z + mf+tl5f/qJeX/6aUlP+hkpL/nZGR/5qPj/+VjIz/p52d/97Pz//bzMz/2szM/9jJyf/b29v/9fX1//Pz + 8//z8/P/8/Pz//b29v/Dvb3/183N/9fNzf/Ivr7/n5eX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAC0l5fw2r6+/+bNzf/mzc3/4MTE/8KPj/+/j4//uY2N/7SKiv+th4f/qIWF/6KB + gf+dfn7/lnt7/5F4eP+Ldnb/hnNz/39vb/94bGz/c2pq/21mZv9mYmL/hH19/+HQ0P/czMz/28zM/9nK + yv/X2Nj/8fHx//Dw8P/w8PD/8PDw//Lz8//FvLz/2M3N/9jNzf/Kvr7/oZeX8AAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACzl5fw2b6+/+fNzf/lzMz/5MnJ/9i1tf/XtbX/07Oz/9Cy + sv/PsbH/zLCw/8qvr//Hra3/xKys/8Krq/+/qqr/vKmp/7qoqP+3pqb/tKWl/7KkpP+uoqL/uq2t/+DO + zv/czMz/3MzM/9vKyv+/wMD/0M/P/8/Ozv/Pzs7/z87O/9DPz//EvLz/2c3N/9jNzf/Jvr7/oJeX8AAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC0l5fw2r6+/+jNzf/mzMz/583N/+bN + zf/mzs7/5c7O/+XOzv/mzs7/5M7O/+XOzv/kzs7/5M7O/+POzv/jzs7/5M7O/+LOzv/jz8//4s/P/+LP + z//hz8//4M7O/93MzP/dzMz/3czM/93Nzf/fzc3/3c3N/93Nzf/czc3/3M3N/9vNzf/bzc3/2szM/9nN + zf/Kvr7/oZeX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC2l5fw276+/+jN + zf/nzMz/5szM/+bMzP/mzMz/5czM/+XMzP/kzMz/5MzM/+PMzP/jzMz/48zM/+LMzP/izMz/4czM/+HM + zP/gzMz/4MzM/9/MzP/fzMz/38zM/97MzP/ezMz/3czM/97Nzf/Jvb3/xrq6/8W6uv/Gurr/xLq6/8S6 + uv/SxcX/2szM/9rNzf/Mvr7/o5eX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAC1l5fw3b6+/+nNzf/ozMz/6M3N/+jOzv/nzs7/6M7O/+fOzv/nzs7/6M7O/+fPz//nz8//5s/P/+bP + z//lz8//5s/P/+TOzv/hzMz/4czM/+DMzP/gzMz/38zM/9/MzP/ezMz/3szM/9/MzP/Z2Nj///////z9 + /f/8/f3//P39///////Fvb3/283N/9vNzf/Lvr7/opeX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAC2l5fw3L6+/+rNzf/ozMz/5cfH/9Ktrf/Pra3/zKys/8mqqv/FqKj/waam/72l + pf+5o6P/taGh/7Ofn/+unZ3/qZub/8u3t//kzc3/4czM/+HMzP/gzMz/4MzM/+DMzP/fzMz/38zM/9/M + zP/U09P/9vb2//T09P/09PT/9PT0//f4+P/Gvb3/3c3N/9vNzf/Mvr7/o5eX8AAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC4l5fw3b6+/+vNzf/pzc3/48TE/72MjP+4jIz/sImJ/6mF + hf+ggID/mXx8/5F5ef+IdXX/gXBw/3hsbP9vZ2f/ZGFh/66hof/mzs7/4szM/+LMzP/hzMz/4czM/+DM + zP/gzMz/38zM/+DMzP/S0dH/8fHx/+/v7//v7+//7+/v//Ly8v/HvLz/3M3N/9zNzf/Ovr7/pZeX8AAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC3l5fw376+/+vNzf/qzMz/58fH/9Ss + rP/Qq6v/zKmp/8empv/DpKT/vqKi/7mgoP+1np7/sJub/6yZmf+nl5f/oZOT/8e0tP/lzs7/48zM/+LM + zP/izMz/4czM/+HMzP/hzMz/4MzM/+LMzP/BwcH/1tfX/9XW1v/V1tb/1dbW/9bX1//Furr/3c3N/93N + zf/Pvr7/pJeX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6l5fw3r6+/+zN + zf/rzMz/683N/+vOzv/rzs7/687O/+rPz//rz8//6s/P/+rPz//qz8//6c/P/+rPz//pz8//6c/P/+bO + zv/kzMz/5czM/+TNzf/kzc3/483N/+PNzf/izc3/4s3N/+HNzf/fysr/3snJ/93Jyf/cycn/3MnJ/9vJ + yf/ezMz/3czM/93Nzf/Pvr7/ppeX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAC5l5fw376+/+3Nzf/rzMz/68zM/+vMzP/qzMz/6szM/+nMzP/pzMz/6MzM/+jMzP/nzMz/58zM/+bM + zP/mzMz/5szM/+XMzP/lzMz/5czM/9nDw//Tvr7/0r6+/9K+vv/Rvr7/0b6+/9G+vv/Qvr7/0L6+/9C+ + vv/Pvr7/z76+/8+/v//Xxsb/38zM/97Nzf/Qvr7/pZeX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAC6l5fw4L6+/+7Nzf/szMz/7c3N/+zNzf/tzs7/687O/+zOzv/rzs7/687O/+vO + zv/qzs7/687O/+rOzv/ozc3/5szM/+bMzP/lzMz/5szM/9DLy//z9fX/8fPz//Lz8//y8/P/8vPz//Lz + 8//y8/P/8vPz//Lz8//y8/P/8vPz//T29v/Lw8P/38zM/9/Nzf/Rvr7/ppeX8AAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC7l5fw4r6+/+7Nzf/tzMz/7svL/9q2tv/Ytrb/17a2/9Kz + s//Qs7P/zbCw/8mwsP/Grq7/w6ys/72pqf/cw8P/6M3N/+fMzP/mzMz/6MzM/9PNzf/4+Pj/9vb2//b2 + 9v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//j5+f/NxMT/4MzM/+DNzf/Qvr7/qZeX8AAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC9l5fw4b6+/+/Nzf/vzMz/7czM/7qM + jP+1i4v/rIeH/6KBgf+afX3/j3h4/4V0dP98bm7/cmpq/2NgYP/Er6//687O/+fMzP/nzMz/58zM/9HL + y//x8vL/7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v//Ly8v/Mw8P/4c3N/+DN + zf/Rvr7/qJeX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC8l5fw4r6+//DN + zf/uzMz/78zM/9CkpP/JoaH/w56e/7ybm/+2l5f/rpSU/6mRkf+hjY3/m4qK/5CFhf/QuLj/6s3N/+jM + zP/ozMz/6czM/8rFxf/j5eX/4uPj/+Lj4//i4+P/4uPj/+Lj4//i4+P/4uPj/+Lj4//i4+P/4uPj/+Pl + 5f/Iv7//483N/+HNzf/Tvr7/qZeX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAC+l5fw476+//HNzf/vzMz/8M3N//DOzv/xz8//8M/P//DPz//vz8//8NDQ//HQ0P/w0ND/8dDQ/+/Q + 0P/szs7/6czM/+nMzP/ozMz/6czM/93Fxf/ZwcH/18DA/9jAwP/WwMD/1sDA/9fAwP/VwMD/1cDA/9bA + wP/UwMD/1MDA/9TAwP/ax8f/4szM/+LNzf/Svr7/q5eX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAC9l5fw5b6+//HNzf/wzMz/78zM/+/MzP/vzMz/7szM/+7MzP/tzMz/7czM/+zM + zP/szMz/68zM/+vMzP/qzMz/6szM/+rMzP/pzMz/6szM/+XJyf/kyMj/48fH/+PHx//hx8f/4cfH/+LH + x//gx8f/4cfH/9/Hx//fx8f/4MfH/97IyP/iy8v/4szM/+PNzf/Tvr7/qpeX8AAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC+l5fw5L6+//LNzf/xzMz/8MzM//HNzf/wzc3/8M3N/+/N + zf/vzc3/7s3N/+7Nzf/vzc3/7c3N/+7Nzf/tzc3/7c3N/+vNzf/qzMz/6szM/8vFxf/k5+f/5OXl/+Tl + 5f/k5eX/5OXl/+Tl5f/k5eX/5OXl/+Tl5f/k5eX/5OXl/+Xn5//Kv7//5c3N/+PNzf/Vvr7/q5eX8AAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAl5fw5b6+//PNzf/xzMz/8czM/+bA + wP/lwMD/5L+//+O+vv/hv7//376+/929vf/cvLz/2ru7/9i7u//Wurr/07m5/97Bwf/tzc3/68zM/9XN + zf/4+fn/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//n5+f/PxMT/5MzM/+TN + zf/Uvr7/rZeX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC/l5fw576+//TN + zf/yzMz/8czM/7qNjf+4jIz/sImJ/6iFhf+hgID/mH19/5F5ef+IdXX/gHBw/3ltbf9waWn/ZGJi/5yQ + kP/vz8//7MzM/9HKyv/y8vL/8PDw//Dw8P/w8PD/8PDw//Dw8P/w8PD/8PDw//Dw8P/w8PD/8PDw//Lz + 8//NwsL/5czM/+XNzf/Vvr7/rJeX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AADAl5fw5r6+//TNzf/zzMz/88vL/8qbm//GmZn/vpaW/7iTk/+wkJD/qouL/6OIiP+dhYX/lYKC/49/ + f/+JfHz/fnV1/62bm//wz8//7szM/8/Jyf/u8PD/7O7u/+zu7v/s7u7/7O7u/+zu7v/s7u7/7O7u/+zu + 7v/s7u7/7O7u/+7x8f/NwsL/583N/+XNzf/Xvr7/rpeX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAADCl5fw576+//XNzf/0zMz/9M3N//XPz//1z8//9c/P//TQ0P/10ND/9NDQ//XQ + 0P/20dH/9dHR//bR0f/10tL/9dLS//HPz//uzMz/7c3N/9jAwP/Qurr/0Lq6/9G6uv/Purr/z7q6/9C6 + uv/Ourr/zrq6/8+6uv/Nurr/zbq6/826uv/ZwsL/5s3N/+bNzf/Wvr7/rZeX8AAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADBl5fw6L6+//bNzf/0zMz/9MzM//PMzP/zzMz/88zM//LM + zP/yzMz/8czM//HMzP/wzMz/8MzM/+/MzP/vzMz/7szM/+7MzP/uzMz/7czM/+7Nzf/uzc3/7s3N/+3N + zf/tzc3/683N/+zNzf/qzc3/683N/+vNzf/qzc3/6s3N/+jNzf/ozc3/5szM/+fNzf/Xvr7/rpeX8AAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADCl5fw6r6+//fNzf/1zMz/9czM//TM + zP/0zMz/88zM//PMzP/yzMz/8szM//LMzP/xzMz/8czM//DMzP/wzMz/78zM/+/MzP/uzMz/7szM/+3M + zP/tzMz/7MzM/+zMzP/szMz/68zM/+vMzP/qzMz/6szM/+nMzP/pzMz/6MzM/+jMzP/nzMz/58zM/+jN + zf/Zvr7/sJeX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADEl5fw6b6+//fN + zf/2zMz/9czM//bNzf/3zs7/9s7O//bOzv/1zs7/9c7O//TOzv/1zs7/887O//TOzv/yzs7/887O//LO + zv/yz8//8s/P//HPz//xz8//8M/P//HPz//vz8//8M/P/+7Pz//vz8//7s/P/+7Pz//uz8//7c/P/+3P + z//pzc3/6czM/+jNzf/avr7/r5eX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AADDl5fw6r6+//jNzf/3zMz/983N/+K2tv/Zrq7/2K6u/9etrf/Vra3/1Kys/9Krq//Qqqr/zqmp/8yp + qf/KqKj/yKen/8ampv/EpaX/w6Sk/8Cjo/+/oqL/vKGh/7uhof+4oKD/t5+f/7Senv+ynZ3/sJyc/66b + m/+smpr/qpqa/6WXl//gxcX/6c3N/+nNzf/Zvr7/sZeX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAADFl5fw676+//nNzf/3zMz/+c/P/86goP++kZH/vpGR/7uPj/+4jo7/tYyM/7KL + i/+tiYn/qoaG/6iEhP+jhIT/oIGB/5x/f/+ZfX3/lX19/5F6ev+OeHj/iXZ2/4d1df+Cc3P/gHFx/3tv + b/94bm7/dGxs/3Bqav9taGj/aWVl/15fX//Yvb3/6s3N/+rNzf/avr7/sJeX8AAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADEl5fw7b6+//rNzf/4zMz/+8/P/9Kjo//ElJT/wZOT/76R + kf+7kJD/t46O/7SMjP+wior/rYmJ/6mHh/+mhYX/ooOD/5+Bgf+bgID/mH5+/5R8fP+Qenr/jXl5/4l3 + d/+GdXX/gnNz/35ycv97cHD/d25u/3RsbP9wamr/bGlp/2JiYv/Zvr7/7M3N/+vNzf/cvr7/sZeX8AAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADFl5fw7L6+//rNzf/5zMz/+s7O/9Sj + o//FlJT/wpSU/7+Rkf+8j4//t42N/7SMjP+wior/rYiI/6iGhv+lhYX/oYOD/56AgP+Zfn7/l319/5J7 + e/+PeXn/ind3/4d2dv+DdHT/gHFx/3xxcf95bm7/dGxs/3Fqav9taWn/amdn/19fX//ZvLz/7c3N/+vN + zf/dvr7/s5eX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADHl5fw7b6+//vN + zf/6zMz/+czM//nMzP/6zc3/+c7O//jMzP/5zMz/98zM//jNzf/3zc3/983N//bNzf/1zc3/9s3N//XN + zf/2zc3/9c7O//XOzv/0zs7/88/P//TNzf/yzc3/887O//LOzv/yzs7/8c7O//DOzv/xzs7/8M7O/+/O + zv/tzc3/68zM/+zNzf/cvr7/speX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AADGl5fw77+///3Ozv/7zc3/+83N//rNzf/6zc3/+s3N//nNzf/6zc3/+M3N//jNzf/3zc3/983N//bN + zf/2zc3/9c3N//XNzf/2zc3/9M3N//XNzf/zzc3/9M3N//LNzf/zzc3/8c3N//LNzf/wzc3/8M3N//HN + zf/vzc3/8M3N/+7Nzf/uzc3/7c3N/+7Ozv/ev7//s5eX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAADImJjw5rW1//HAwP/wv7//77+//++/v//uv7//7r+//+2/v//tv7//7L+//+y/ + v//sv7//67+//+u/v//qv7//6r+//+m/v//pv7//6L+//+i/v//nv7//57+//+a/v//mv7//5b+//+W/ + v//kv7//5L+//+S/v//jv7//47+//+K/v//iv7//4b+//+LAwP/VtbX/tZiY8AAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADKmJjjyJiY8MiYmPDGl5fwxpeX8MeXl/DFl5fwxJeX8MSX + l/DFl5fww5eX8MSXl/DCl5fww5eX8MGXl/DCl5fwwJeX8MGXl/C/l5fwwJeX8L6Xl/C/l5fwvZeX8L6X + l/C8l5fwvZeX8LuXl/C8l5fwupeX8LmXl/C5l5fwupeX8LeXl/C2l5fwtpeX8LeYmPC2mJjwt5iY4wAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////AAD4AAAAAB8AAPgAAAAAHwAA+AAAAAAf + AAD4AAAAAB8AAPgAAAAAHwAA+AAAAAAfAAD4AAAAAB8AAPgAAAAAHwAA+AAAAAAfAAD4AAAAAB8AAPgA + AAAAHwAA+AAAAAAfAAD4AAAAAB8AAPgAAAAAHwAA+AAAAAAfAAD4AAAAAB8AAPgAAAAAHwAA+AAAAAAf + AAD4AAAAAB8AAPgAAAAAHwAA+AAAAAAfAAD4AAAAAB8AAPgAAAAAHwAA+AAAAAAfAAD4AAAAAB8AAPgA + AAAAHwAA+AAAAAAfAAD4AAAAAB8AAPgAAAAAHwAA+AAAAAAfAAD4AAAAAB8AAPgAAAAAHwAA+AAAAAAf + AAD4AAAAAB8AAPgAAAAAHwAA+AAAAAAfAAD4AAAAAB8AAPgAAAAAHwAA+AAAAAAfAAD4AAAAAB8AAPgA + AAAAHwAA+AAAAAAfAAD4AAAAAB8AAPgAAAAAHwAA+AAAAAAfAAD4AAAAAB8AAP///////wAA + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/FolderLocker/TrayForm.Designer.cs b/Demo_Source_Code/CSharpDemo/FolderLocker/TrayForm.Designer.cs new file mode 100644 index 0000000..c4c9dd0 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FolderLocker/TrayForm.Designer.cs @@ -0,0 +1,128 @@ +namespace EaseFilter.FolderLocker +{ + partial class TrayForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(TrayForm)); + this.contextMenuStrip = new System.Windows.Forms.ContextMenuStrip(this.components); + this.openConsoleToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripMenuItem5 = new System.Windows.Forms.ToolStripSeparator(); + this.startLockertoolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.stopLockertoolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripMenuItem3 = new System.Windows.Forms.ToolStripSeparator(); + this.exitToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem(); + this.notifyIcon = new System.Windows.Forms.NotifyIcon(this.components); + this.contextMenuStrip.SuspendLayout(); + this.SuspendLayout(); + // + // contextMenuStrip + // + this.contextMenuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.openConsoleToolStripMenuItem, + this.toolStripMenuItem5, + this.startLockertoolStripMenuItem, + this.stopLockertoolStripMenuItem, + this.toolStripMenuItem3, + this.exitToolStripMenuItem1}); + this.contextMenuStrip.Name = "contextMenuStrip_fileAgent"; + this.contextMenuStrip.Size = new System.Drawing.Size(150, 104); + this.contextMenuStrip.Text = "-"; + // + // openConsoleToolStripMenuItem + // + this.openConsoleToolStripMenuItem.Name = "openConsoleToolStripMenuItem"; + this.openConsoleToolStripMenuItem.Size = new System.Drawing.Size(149, 22); + this.openConsoleToolStripMenuItem.Text = "Open Console"; + this.openConsoleToolStripMenuItem.Click += new System.EventHandler(this.openConsoleToolStripMenuItem_Click); + // + // toolStripMenuItem5 + // + this.toolStripMenuItem5.Name = "toolStripMenuItem5"; + this.toolStripMenuItem5.Size = new System.Drawing.Size(146, 6); + // + // startLockertoolStripMenuItem + // + this.startLockertoolStripMenuItem.Name = "startLockertoolStripMenuItem"; + this.startLockertoolStripMenuItem.Size = new System.Drawing.Size(149, 22); + this.startLockertoolStripMenuItem.Text = "Start Locker"; + this.startLockertoolStripMenuItem.Click += new System.EventHandler(this.startLockertoolStripMenuItem_Click); + // + // stopLockertoolStripMenuItem + // + this.stopLockertoolStripMenuItem.Name = "stopLockertoolStripMenuItem"; + this.stopLockertoolStripMenuItem.Size = new System.Drawing.Size(149, 22); + this.stopLockertoolStripMenuItem.Text = "Stop Locker"; + this.stopLockertoolStripMenuItem.Click += new System.EventHandler(this.stopLockertoolStripMenuItem_Click); + // + // toolStripMenuItem3 + // + this.toolStripMenuItem3.Name = "toolStripMenuItem3"; + this.toolStripMenuItem3.Size = new System.Drawing.Size(146, 6); + // + // exitToolStripMenuItem1 + // + this.exitToolStripMenuItem1.Name = "exitToolStripMenuItem1"; + this.exitToolStripMenuItem1.Size = new System.Drawing.Size(149, 22); + this.exitToolStripMenuItem1.Text = "Exit"; + this.exitToolStripMenuItem1.Click += new System.EventHandler(this.exitToolStripMenuItem1_Click); + // + // notifyIcon + // + this.notifyIcon.ContextMenuStrip = this.contextMenuStrip; + this.notifyIcon.Icon = ((System.Drawing.Icon)(resources.GetObject("notifyIcon.Icon"))); + this.notifyIcon.Text = "EaseFilter File Protector"; + this.notifyIcon.Visible = true; + + // + // TrayForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(263, 102); + this.Name = "TrayForm"; + this.Text = "TrayForm"; + this.WindowState = System.Windows.Forms.FormWindowState.Minimized; + this.Load += new System.EventHandler(this.TrayForm_Load); + this.contextMenuStrip.ResumeLayout(false); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.ContextMenuStrip contextMenuStrip; + private System.Windows.Forms.ToolStripMenuItem openConsoleToolStripMenuItem; + private System.Windows.Forms.ToolStripSeparator toolStripMenuItem5; + private System.Windows.Forms.ToolStripSeparator toolStripMenuItem3; + private System.Windows.Forms.ToolStripMenuItem exitToolStripMenuItem1; + public System.Windows.Forms.NotifyIcon notifyIcon; + private System.Windows.Forms.ToolStripMenuItem startLockertoolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem stopLockertoolStripMenuItem; + } +} \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/FolderLocker/TrayForm.cs b/Demo_Source_Code/CSharpDemo/FolderLocker/TrayForm.cs new file mode 100644 index 0000000..28a68c2 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FolderLocker/TrayForm.cs @@ -0,0 +1,97 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +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; +using System.IO; + +using EaseFilter.CommonObjects; + +namespace EaseFilter.FolderLocker +{ + public partial class TrayForm : Form + { + Form_FolderLocker folderLockerForm = null; + + public TrayForm() + { + + InitializeComponent(); + + Utils.CopyOSPlatformDependentFiles(); + + + this.Hide(); + + folderLockerForm = new Form_FolderLocker(); + + } + + private void TrayForm_Load(object sender, EventArgs e) + { + this.Hide(); + this.notifyIcon.Visible = true; + folderLockerForm.ShowDialog(); + } + + + private void openConsoleToolStripMenuItem_Click(object sender, EventArgs e) + { + if (!folderLockerForm.Visible) + { + folderLockerForm.StartPosition = FormStartPosition.CenterScreen; + folderLockerForm.ShowDialog(); + } + } + + + private void exitToolStripMenuItem1_Click(object sender, EventArgs e) + { + GlobalConfig.Stop(); + folderLockerForm.Close(); + + Application.Exit(); + } + + private void startLockertoolStripMenuItem_Click(object sender, EventArgs e) + { + string lastError = string.Empty; + if (!FilterWorker.StartService(ref lastError)) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("Start service failed with error:" + lastError + ",folder locker service will stop.", "Folder locker Service", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + + private void stopLockertoolStripMenuItem_Click(object sender, EventArgs e) + { + GlobalConfig.Stop(); + FilterAPI.StopFilter(); + } + + + + + + } +} diff --git a/Demo_Source_Code/CSharpDemo/FolderLocker/TrayForm.resx b/Demo_Source_Code/CSharpDemo/FolderLocker/TrayForm.resx new file mode 100644 index 0000000..f39138b --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FolderLocker/TrayForm.resx @@ -0,0 +1,417 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 19, 18 + + + 214, 23 + + + + + AAABAAEAQEAAAAEAIAAoQgAAFgAAACgAAABAAAAAgAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOTX0YDk19H/5NfR/+TX0f/k19H/5NfR/+TX + 0f/k19H/5NfR/+TX0f/k19H/5NfR/+TX0f/k19H/5NfR/+TX0f/k19H/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADRydP/RGLg/0Ri + 4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/+TX + 0f8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AADk19FARGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri + 4P9EYuD/RGLg/0Ri4P/k19H/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA5NfRQERi4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri + 4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/5NfR/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQjs4/0I7OP9COzj/Qjs4/0I7OP9COzj/Qjs4/0I7 + OP9COzj/Qjs4/0I7OP9COzj/Qjs4/0I7OP9COzj/Qjs4/0I7OP9COzj/Qjs4/0I7OP9COzj/Qjs4/0I7 + OP9COzj/Qjs4/0I7OP9COzj/Qjs4/0I7OP9COzj/Qjs4/2tiXv9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri + 4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/+TX0f8AAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEI7OP9fVVH/X1VR/19V + Uf9fVVH/X1VR/19VUf9fVVH/X1VR/19VUf9fVVH/X1VR/19VUf9fVVH/X1VR/19VUf9fVVH/X1VR/19V + Uf9fVVH/X1VR/19VUf9fVVH/X1VR/19VUf9fVVH/X1VR/19VUf9fVVH/X1VR/19VUf+AdnH/RGLg/0Ri + 4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri + 4P/k19H/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AABCOzj/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/iHx4/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri + 4P9EYuD/RGLg/0Ri4P9EYuD/5NfR/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAQjs4/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/4h8eP9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri + 4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/+TX0f8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEI7OP9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv+IfHj/RGLg/0Ri4P9EYuD/RGLg/0Ri + 4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P/k19H/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABCOzj/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/iHx4/0Ri + 4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri + 4P9EYuD/5NfR/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAQjs4/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/4h8eP9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri + 4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/+TX0f8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAEI7OP9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv+IfHj/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri + 4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P/k19H/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABCOzj/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/+TX0f+8utX/RGLg/0Ri + 4P9EYuD/vLrV/7y61f+8utX/vLrV/7y61f+8utX/vLrV/7y61f9EYuD/RGLg/0Ri4P/k19H/5NfR/wAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQjs4/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/5NfR/0Ri4P9EYuD/RGLg/+TX0f9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv/k19H/RGLg/0Ri + 4P9EYuD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAEI7OP9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/+TX0f9EYuD/RGLg/0Ri4P/k19H/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/5NfR/0Ri4P9EYuD/RGLg/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABCOzj/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv/k19H/RGLg/0Ri4P9EYuD/5NfR/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/+TX0f9EYuD/RGLg/0Ri4P8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQjs4/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/5NfR/0Ri + 4P9EYuD/RGLg/+TX0f9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv/k19H/RGLg/0Ri4P9EYuD/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEI7 + OP9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/+TX0f9EYuD/RGLg/0Ri4P/k19H/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/5NfR/0Ri + 4P9EYuD/RGLg/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAABCOzj/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv/k19H/RGLg/0Ri4P9EYuD/5NfR/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/1hx3v9EYuD/RGLg/0Ri4P8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQjs4/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/3dDK/0Ri4P9EYuD/RGLg/0Ri + 4P+XjIf/aV5a/2leWv9pXlr/aV5a/+TX0f9EYuD/RGLg/0Ri4P/k19H/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEI7OP9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv/k19H/RGLg/0Ri4P9EYuD/5NfR/9XIw/9pXlr/aV5a/+TX0f9EYuD/RGLg/0Ri4P9EYuD/5NfR/wAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AABCOzj/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/5NfR/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/vLrV/2x/3P9EYuD/RGLg/0Ri + 4P9EYuD/Tmnf/+TX0WAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAQjs4/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv/k19H/RGLg/0Ri4P9EYuD/RGLg/0Ri + 4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/+TX0f8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEI7OP9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/+TX + 0f9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/Tmnf/+TX0f8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABCOzj/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/5NfR/+TX0f+Kldn/RGLg/0Ri4P/k19H/5NfR/5eMh/8AAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAQjs4/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAEI7OP9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABCOzj/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQjs4/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAEI7OP9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABCOzj/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQjs4/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEI7 + OP+Ddm7/g3Zu/4N2bv+Ddm7/g3Zu/4N2bv+Ddm7/g3Zu/4N2bv+Ddm7/g3Zu/4N2bv+Ddm7/g3Zu/4N2 + bv+Ddm7/g3Zu/4N2bv+Ddm7/g3Zu/2tgW/9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/wAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAABCOzj/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19U + UP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP+Ddm7/bmNe/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQjs4/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19U + UP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/4N2 + bv9uY17/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEI7OP9fVFD/X1RQ/19U + UP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19U + UP9fVFD/X1RQ/19UUP9fVFD/g3Zu/4N2bv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9zZ2L/dmpk/wAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AABCOzj/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19U + UP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/T0ZD/0I7OP9COzj/Qjs4/0I7OP9COzj/Qjs4/0I7 + OP9COzj/Qjs4/0I7OP9COzj/Qjs4/0I7OP9COzj/Qjs4/0I7OP9COzj/Qjs4/0I7OP9COzj/Qjs4/wAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAQjs4/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19U + UP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/wAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEI7OP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19U + UP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19U + UP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABCOzj/X1RQ/19U + UP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19U + UP9fVFD/X1RQ/19UUP9fVFD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAQjs4/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19U + UP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/Qjs4/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABCOzigQjs4/0I7OP9COzj/Qjs4/0I7OP9COzj/Qjs4/0I7 + OP9COzj/Qjs4/0I7OP9COzj/Qjs4/0I7OP9COzj/Qjs4/0I7OP9COzj/Qjs4/wAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA//////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////+AAD///////4AAH///////AAAf/// + ///8AAB//gAAAAAAAH/+AAAAAAAAf/4AAAAAAAB//gAAAAAAAH/+AAAAAAAAf/4AAAAAAAB//gAAAAAA + AH/+AAAAAAAAf/4AAAAAAAB//gAAAAAAAf/+AAAAAAAB//4AAAAAAAH//gAAAAAAAf/+AAAAAAAB//4A + AAAAAAH//gAAAAAAAf/+AAAAAAAB//4AAAAAAAH//gAAAAAAA//+AAAAAAAH//4AAAAAAA///gAAAAAA + D//+AAAAAAAP//4AAAAAAA///gAAAAAAD//+AAAAAAAP//4AAAAAAA///gAAAAAAD//+AAAAAAAP//4A + AAAAAA///gAAAAAAD//+AAAAAAAP//4AAAAAAB///gAAB//////+AAAH//////4AAAf//////gAAB/// + ////AAAP//////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////8= + + + + 320, 23 + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/FolderLocker/WebAPIService.cs b/Demo_Source_Code/CSharpDemo/FolderLocker/WebAPIService.cs new file mode 100644 index 0000000..c842a43 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FolderLocker/WebAPIService.cs @@ -0,0 +1,296 @@ +using System; +using System.IO; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; +using System.Runtime.InteropServices; +using System.Configuration; +using System.ServiceModel; +using System.Diagnostics; + +using EaseFilter.FilterControl; +using EaseFilter.CommonObjects; + +namespace EaseFilter.FolderLocker +{ + public static class WebAPIServices + { + public static string serverURI = "http://www.encryptme.net/WebAPI.asmx"; + static string accountName = GlobalConfig.AccountName; + static string password = "testpassword"; + + static WebAPIServices() + { + if (accountName.Trim().Length == 0) + { + accountName = "testaccount." + Environment.MachineName + "." + Guid.NewGuid().ToString(); + GlobalConfig.AccountName = accountName; + } + + accountName = Utils.AESEncryptDecryptStr(accountName, Utils.EncryptType.Encryption); + } + + + private static ServiceReference1.ServiceSoapClient GetServiceClient(ref string lastError) + { + ServiceReference1.ServiceSoapClient client = null; + + try + { + BasicHttpBinding binding = new BasicHttpBinding(); + binding.OpenTimeout = new TimeSpan(0, 0, 10); + binding.CloseTimeout = new TimeSpan(0, 0, 10); + binding.SendTimeout = new TimeSpan(0, 0, 10); + binding.ReceiveTimeout = new TimeSpan(0, 0, 10); + + EndpointAddress endpoint = new EndpointAddress(new Uri(serverURI)); + + client = new EaseFilter.FolderLocker.ServiceReference1.ServiceSoapClient(binding, endpoint); + } + catch (Exception ex) + { + lastError = "Connecting to server failed with error " + ex.Message; + } + + return client; + } + + public static bool AddShareFile(string policy, ref long creationTime, ref string key, ref string iv, ref string lastError) + { + bool retVal = false; + + try + { + + lastError = string.Empty; + ServiceReference1.ServiceSoapClient client = GetServiceClient(ref lastError); + + if (null == client) + { + return false; + } + + retVal = client.AddShareFile(accountName, password, policy, ref creationTime, ref key, ref iv, ref lastError); + } + catch (Exception ex) + { + lastError = "Add new file to server failed with error:" + ex.Message; + retVal = false; + } + + return retVal; + } + + public static bool GetSharedFilePermission(string fileName, string processName, string userName, string tagStr, ref string iv, ref string key, ref uint accessFlags, ref string lastError) + { + bool retVal = false; + + try + { + + lastError = string.Empty; + ServiceReference1.ServiceSoapClient client = GetServiceClient(ref lastError); + + if (null == client) + { + return false; + } + + string ivStr = tagStr; + string serverAccount = GlobalConfig.AccountName; + int index = tagStr.IndexOf(";"); + if (index > 0) + { + serverAccount = tagStr.Substring(0, index); + ivStr = tagStr.Substring(index + 1); + } + + UserInfo userInfo = new UserInfo(); + string keyStr = string.Empty; + + userInfo.FileName = fileName; + userInfo.AccountName = serverAccount; + userInfo.ProcessName = processName; + userInfo.UserName = userName; + userInfo.UserPassword = password; + userInfo.CreationTime = DateTime.Now.ToFileTime(); ; + userInfo.EncryptionIV = ivStr; + + string userInfoStr = Utils.EncryptObjectToStr(userInfo); + + retVal = client.GetSharedFilePermission(userInfoStr, ref key, ref iv, ref accessFlags, ref lastError); + } + catch (Exception ex) + { + lastError = "Get file key failed with error:" + ex.Message; + retVal = false; + } + + return retVal; + } + + public static bool GetFileDRInfo(string encryptionIV, ref string encryptedDRPolicy, ref string lastError) + { + bool retVal = false; + + try + { + + lastError = string.Empty; + ServiceReference1.ServiceSoapClient client = GetServiceClient(ref lastError); + + if (null == client) + { + return false; + } + + retVal = client.GetSharedFileDRInfo(accountName, password, encryptionIV, ref encryptedDRPolicy, ref lastError); + + } + catch (Exception ex) + { + lastError = "Get file DR info failed with error:" + ex.Message; + retVal = false; + } + + return retVal; + } + + public static bool ModifySharedFileDRInfo(string encryptedDRPolicy, ref string lastError) + { + bool retVal = false; + + try + { + + lastError = string.Empty; + ServiceReference1.ServiceSoapClient client = GetServiceClient(ref lastError); + + if (null == client) + { + return false; + } + + retVal = client.ModifySharedFileDRInfo(accountName, password, encryptedDRPolicy, ref lastError); + + } + catch (Exception ex) + { + lastError = "Set file DR info failed with error:" + ex.Message; + retVal = false; + } + + return retVal; + } + + public static bool DeleteShareFile(string encryptionIV, ref string lastError) + { + bool retVal = false; + + try + { + + lastError = string.Empty; + ServiceReference1.ServiceSoapClient client = GetServiceClient(ref lastError); + + if (null == client) + { + return false; + } + + retVal = client.DeleteSharedFile(accountName, password, encryptionIV, ref lastError); + + } + catch (Exception ex) + { + lastError = "DeleteShareFile failed with error:" + ex.Message; + retVal = false; + } + + return retVal; + } + + + public static bool GetFileList(ref string fileListStr, ref string lastError) + { + bool retVal = false; + + try + { + lastError = string.Empty; + ServiceReference1.ServiceSoapClient client = GetServiceClient(ref lastError); + + if (null == client) + { + return false; + } + + retVal = client.GetFileList(accountName, password, ref fileListStr, ref lastError); + + } + catch (Exception ex) + { + lastError = "Get file list failed with error:" + ex.Message; + retVal = false; + } + + return retVal; + } + + public static bool GetAccessLog(ref string accessLog, ref string lastError) + { + bool retVal = false; + + try + { + + lastError = string.Empty; + ServiceReference1.ServiceSoapClient client = GetServiceClient(ref lastError); + + if (null == client) + { + return false; + } + + retVal = client.GetAccessLog(accountName, password, ref accessLog, ref lastError); + } + catch (Exception ex) + { + lastError = "Get access log failed with error:" + ex.Message; + retVal = false; + } + + return retVal; + } + + public static bool ClearAccessLog(ref string lastError) + { + bool retVal = false; + + try + { + + lastError = string.Empty; + ServiceReference1.ServiceSoapClient client = GetServiceClient(ref lastError); + + if (null == client) + { + return false; + } + + retVal = client.ClearAccessLog(accountName, password, ref lastError); + } + catch (Exception ex) + { + lastError = "Clear access log failed with error:" + ex.Message; + retVal = false; + } + + return retVal; + } + } +} diff --git a/Demo_Source_Code/CSharpDemo/FolderLocker/WebAPIService.designer.cs b/Demo_Source_Code/CSharpDemo/FolderLocker/WebAPIService.designer.cs new file mode 100644 index 0000000..b8600da --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FolderLocker/WebAPIService.designer.cs @@ -0,0 +1,49 @@ +namespace EaseFilter.FolderLocker +{ + partial class WebFormServices + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(WebFormServices)); + this.SuspendLayout(); + // + // WebFormServices + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(625, 287); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Name = "WebFormServices"; + this.Text = "Web API Remote Service"; + this.ResumeLayout(false); + + } + + #endregion + + } +} \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/FolderLocker/WebAPIService.resx b/Demo_Source_Code/CSharpDemo/FolderLocker/WebAPIService.resx new file mode 100644 index 0000000..4d86311 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FolderLocker/WebAPIService.resx @@ -0,0 +1,570 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + AAABAAgAEBAAAAEACABoBQAAhgAAABAQAAABACAAaAQAAO4FAAAYGAAAAQAIAMgGAABWCgAAGBgAAAEA + IACICQAAHhEAACAgAAABAAgAqAgAAKYaAAAgIAAAAQAgAKgQAABOIwAAMDAAAAEACACoDgAA9jMAADAw + AAABACAAqCUAAJ5CAAAoAAAAEAAAACAAAAABAAgAAAAAAEABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP// + /wAYTP8Ao4R3AIcwBwAyMXwA4sKvAGZ+8QAAB6kAY3GgAJ2jsQDU3/IAUVtzAAQh1gBkCwAAxKeTAC8F + AAD04dAARWO+ACU60ACJjpQAf4y6ABofmQCHdHEAxsa5AFxdjQDc2NYAopSLAK6hxADz07YA1rOgAAEr + 6wBNTYgAtqukAChZ9wDp6OEAuZmIAN/NwAAHFrIAzbquAISOqgDq18cA/fnwANSqkwCNjIUAAQeaALCQ + gACUe28Ak5iyAN/b6QD26dsAI1HtAHBwpABqbpUAs52TAJeFfACVipMACS7iAKanqgDfvKUAJCScAJ6M + ggDny7gAEkP/AK+LdwDHrZoA79W/AKmQhgCagXEA2d/5APDh1wD///cA6dC/AOfYzgChiXwA48a1APLn + 4AAAJekAkHdsAJqDdwDc2u4AbGylAO/ZyADnybMAu5yMAOC/qQD/+/QAwaSRAPLl2ACfg3UA7NTCAOvl + 4wCei34ApIh6AKqSgwDixLIAmX5yAJ6EeAATRv8A58y7AODArAChiH8A8t/PAOvRvQCvkoIA9+jZAO7Y + xgDozbkA48e3APbn2wDy0rcA5MW0AOLFtADhw7AA4cGtAJiEewCiiHsAupqJAOPFsgDjxLEA4cKuAN68 + pgDgwKsA37ymAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAABZSk43AAAAAAAAAAAAAABPRh5MGiE2dC8bAAAAAAAAXisEDhAjAQFbcwAA + AAAAACdWAQELFlABQwAAAAAAAD1Jdm8+HE0IMUQAAAAAAABgbV9LbB0TAi04AAAAAAAAXWYGX3BqRR8/ + BQAAAAAAAGhacnhxd24HCgwgAAAAAAB1a1V6ZFgqRzUiDVEAAAAAV1M7e3ljSCkXFDMmAAAAAA9CZ1IR + aTIlXBUoYjwAAABAQVQkLgNhZQAAGBI5NAAAAAAAAAAAAAAAAAA6CRkAAAAAAAAAAAAAAAAAADAsAAAA + AAAAAAAAAAAAAAAAAAD//wAA4f8AAMAPAADADwAAwB8AAIAfAACAHwAAgB8AAIAPAACABwAAgAcAAIAD + AACAYQAA//EAAP/5AAD//wAAKAAAABAAAAAgAAAAAQAgAAAAAABABAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAI5mUzmhhXb+oYZ34oNfTq9/Wkd7gVtJR4RaTBQAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACOaFSc8OHX/9azoP/y5+D/3NjW/7arpP+1n5X+oYN134hjUayRbFdmAAAAAAAA + AAAAAAAAAAAAAAAAAACEOz4Eq5GB7dSqk/+HMAf/ZAsA/y8FAP/p6OH////////////r5eP/hV9NhQAA + AAAAAAAAAAAAAAAAAAAAAAAAiWZOOs26rv//+/T////////////U3/L/Gh+Z/9za7v//////qpCF84Vi + UBEAAAAAAAAAAAAAAAAAAAAAAAAAAI1lUHbn2M7/48Wy/+TFtP/ny7j/rqHE/wAl6f8AB6n/39vp/5Bo + UKMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACQZlSn9ufb/+LEsv/jxrX/48e3//PTtv8lOtD/GEz//wEH + mv9pSmNbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAo4BuzfLfz//iwq//4sSy/+LFtP/u2Mb/2d/5/wEr + 6/8SQ///ExJxyx8fOAkAAAAAAAAAAAAAAAAAAAAAAAAAALGRgOvs1ML/4cGt/+HCrv/hw7D/48Sx//LS + t/9mfvH/naOx/1Fbc/8TE3KeAAAAAAAAAAAAAAAAAAAAAAAAAAC7m4r86M25/+C/qf/gwKv/4MCs//Ll + 2P/9+fD////3/2pulf8oWff/BSLY/gAAl2EAAAAAAAAAAAAAAAAAAAAAwaSR/+fJs//fvKX/37ym/968 + pv/nzLv/6dC//+rXx/98Y1/Bio+V+yNR7f8BELT0AACVKQAAAAAAAAAAAAAAAMSnk//v1b//69G9/+/Z + yP/04dD/9+jZ//bp2//fzcD/jGJFdFNux4KEjqr/E0b//wABmcoAAIQCAAAAAAAAAACvi3f/x62a/7yd + jfy7mIbpsot30KF2Y7iVa1eflmhWh6F1Ui8AAP8D0NC/vkVjvv8JLuL/AACRXAAAAAAAAAAAqXhhL6B3 + ZRutcDIFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKCepxSlpqrPY3Gg/zM0fqgAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACD/DHuFtoaHhn3OAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAD//wAA4f8AAMAPAADADwAAwB8AAIAfAACAHwAAgB8AAIAPAACABwAAgAcAAIADAACAYQAA//EAAP/5 + AAD//wAAKAAAABgAAAAwAAAAAQAIAAAAAACgAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8AJVr/AKp2 + XgAAAJMAgBcAAJ+u9QBNYJwA3rieADRAPwAAG9sAhZC6AI5PMgDZ19UAbW1nAC4ukgBUZt4AKEzBAJyX + iABOFQAAsrGxAGhSRwB3d5wADTn0AMeeiQD759EAy8i4AO/RugDl5PEAT2i+AIxrWgBfX4AAAQ6vADdd + 1QBERJsAFBWXAGd3tACdgXUAgnl2APry6gDHsKQASkc5AMWyvgAdTe4AlpyxAK+PfwCsqZ0AgYmjAI6I + jwBjEAAA4sOwADtFyAALLN8A3c7CAO3ZzACRdmoAOFKhABRL/wAADM8AV2atAGZiUADu5d0AK0qwALqh + lAAPC4oAvryyAFppmACAgJEAqJqSANzf4gCrhXAAHh6QANO+sQApOZoAnHRgAJ+LgQDt7+8AFSOZALOX + iQAFMe0A//zxAJeXlAC9qZ8ACAiZAKN9agDPpZAAxsXDAAs+/wAFI9QAXmi2APf3/QB1dacAGEPvAPfr + 3wDkybkA2rqoAB1R/wBtEwAAtrCcAOvUwwDJtqsA4tvXAKiUigD88+AAgYvBAAMn3wDz49QA29fMAPj2 + 8gAODpYAGUf3AKWIewCRkZEAuLi3AC1d/wCXhHoA9v//AIpvYQB4GAAAgYibAP/86QDOwboAkXJjANfL + xgARRP8A7OHWAMOahADgv6oAmHhpAOzr9QBxeKAA//34AAAh4AAJM/IA9efZAN+8pQChg3AA49DEAPDe + 0QDa0MkAmn5wAAQt6ADq0L4AoI+GAAQKqwCljYIAj3JdAP/15QDq3dAAopKLAJN6bgCbhn4AnXdlAOnM + uQCXdWIA7djGAOTHtACOeGYAoYR3APru4gDw4tkA6tTIAKeAawCkl5EArJWIABlP/wDnzb0A9OjdALug + kAD++OkA28y/AMevnwDDr6MAuqedAN65ogD9/vwA8+TYAObKtQDhwa0AmnRkAKOCcwAPPPQA/PXqAAIC + kQCTdGUAmYJ4AP789QDfvqgArJCAAPTr3gDy388A4sWzAIlrWgCpg3EAoYBwAJuAcwD///oAFk3/AB9T + /wDu3NEA5su5AOTHtwDjw60AjG1cAJN4bAD69/MA8dK5AEVFnQDez8AA38CsAKORiQD///cA//vvAN67 + owCmfmsA///9AB9R/wD69eoA372mAKN9bAD/+/QA58y6AOXJtgDjxrYA4cKvAN++qQCSd2kA//vqAP73 + 6AD89OkA9uvgAOXIuQDkyLgA48e1AOPGtADixLIA4sSvAOLDrgDhwKoA3rukAN26ogCqhW8A///+AP7/ + /wD++/QAimtaAOPGtQDjxbQA48WzAOLEsQDixLAA4sOxAOHCrgDgwKoA4MCsAN+/qQAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAwPV1cwAAAAAAAAAAAAAAAAAAAAAAAACVrAFsi1Key+KXAAAAAAAAAAAA + AAAAAAC4zVUYiQHzRQ17rcMeN48AAAAAAAAAAACI3AV2YTETFUwBAQEBecwAAAAAAAAAANJkJ19+AwwJ + MAEBAQEBegAAAAAAAAAAAIw99PIBAQF0WSOBAQFllgAAAAAAAAAAAJ3X+uqmocegOrUEHAGkAAAAAAAA + AAAAALzl+enJ6F7OM24Xt1qSAAAAAAAAAAAAoyhq+erpyeiZKgoCT0C5AAAAAAAAAAAAS6pj7Ou/6t/f + GRBcxmkPAAAAAAAAAAAAJX3e7TL56/fnAa+EcjlNHwAAAAAAAAAAgNnusvzgMvv2yBsGjS88KUMAAAAA + AAAAmlCH/f6y/OD4nDbEaBodV1MAAAAAAAAAmNTVu39//tHmg7rTNTshYIVHAAAAAAAAVKmu2rvh/+GK + p7BdKCYSB6VYIgAAAAAAopMI74eH2trV8K7dPwAkYhHFIFsAAAAA8WcIyrGOm76Gn7bETgAALHcrfG0A + AAAARnjj5L2U0EirqC3CswAAAGs42DTPAAAASsHW27RvkWZEAAAAAAAAAHFWPqWQAAAAAAAAAAAAAAAA + AAAAAAAAAAAULkJJFgAAAAAAAAAAAAAAAAAAAAAAAAAAC4JBDgAAAAAAAAAAAAAAAAAAAAAAAAAAAABR + cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A8P//AOAH/wDgAD8A4AA/AMAAfwDAAH8AwAD/AMAA + /wCAAP8AgAD/AIAAfwCAAD8AgAA/AIAAHwCAAA8AgAIHAIADBwCAA4MAgD+DAP//wQD//+EA///5AP// + /wAoAAAAGAAAADAAAAABACAAAAAAAGAJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlmFIC4hnVe2IZlTqfVdEt4FcSoOBW0tPhV5UHAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAj2dTY8Ovo///////+Pby/9rQyf+9qZ//o4Z4/opnVOaHYEyziF9OgIlkTUyIZE0ZAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjGNQwvr38//PpZD/x56J/+PQ + xP///////v///9zf4v/Z19X/18vG/7qnnf+dgnT+iWRR44VeTbCRaldyAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACZb1kcooRx/f/79P+AFwD/eBgA/20TAP9jEAD/ThUA/2hSR//t7+////////// + /////////////87Buv+HX02rAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACVaFZoybar//ry + 6v/auqj/w5qE/6p2Xv+OTzL/NEA//46Ij////////////////////////////5JyY/iPaFQeAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACSaFSv7uXd//779P////7/////////////////9v///15o + tv8UFZf/7Ov1////////////4tvX/4RdSqEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8A + AAGNdGHq///9/+LEsP/jxrT/5829/+rUyP/u3NH/8OLZ/wAMz/8PPPT/AACT/+Xk8f//////rpeK/ops + VD4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAItvVySukoL+/PTp/+LEsf/jx7X/5Me3/+TI + uP/kybn/8dK5/ztFyP8ZR/f/DTn0/wICkf/39/3/jWxV5JAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAJBmVFPHsKP/8+PU/+LEsf/jxrT/48e1/+THt//kyLj/6cy5/8Wyvv8AG9v/JVr//wUx + 7f8PC4r/jGZVmQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJFoUn3bzL//69TD/+LE + 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 + AP/Ozs7//////////////////////////////////////4prW/yPZVMwAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACQZlLX8eri//789/////////////r28f/k0sj/zLCg/7SK + df9XhZP/aX6C/9HQ1v/////////////////////////////////Pwrv/hl9MpwAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAApHNgHpZxX/7///3//vr0//379////Pj////6//// + /v/////////////////LzOL/BhWd/y8sof/+/f7//////////////////////5V2Z/6RbFY3AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACWb1hbt52P////+//ozr3/5sq6/+rT + xf/t2s7/8ODW//Po4P/37un////3/yg4zP8WSf//AR/R/w0Kkv/08/n////////////s5+P/hV5J0gAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJhrWJXVw7b//vvy/+LE + sf/jx7X/5Me3/+TItv/kyLj/5Mm4/+PIuP/tzrn/aGnE/wsv4f8eU///AiPY/wwIj//5+fv//////7yo + n/+MZFN2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlmtWye/l + 3f/16Nz/48Wx/+PGtP/jxrX/5Me3/+TIuP/kybj/5Mm6/+fLuv/exL3/ABDR/yhZ//8YTP//AB7U/xkV + kv//////lnNg/ZRpWSMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIU+ + PwSSa1f0///3/+3Zyv/ixLH/48az/+PGtP/lx7X/5Me2/+THt//kyLj/5Mq5//DSuv9gZ8z/DjTl/yda + //8USf//ABTH/zArl/+YblDUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAlGpdJKN/bP7///r/5827/+LEsP/ixLL/4sWz/+PGs//jxrX/48a2/+PHt//kx7f/5ci3/+TI + uf8AGNf/K1r7/yFU//8QRf//AA64/xILh7cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACWbFZKtpiG////+P/iwq3/4sOv/+LEsP/ixLH/4sSy/+LFs//jxrT/48a1/+PF + tP/y5t7////8/5ek7/8BJuH/MGP//x5P//8MQf//AAeo/gAAm24AAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAJZtVWvFrZ3//vjv/+C+qv/iwq7/4sOv/+LDsP/iw7H/4sSy/+LF + sv/jxbP/4sOz//z69P////r////7/x8/5v8jTvL/Kl3//xVL//8ePML/IyFY+jIyQEUAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlGpVi9O/sP/68OT/37+o/+HBrP/hwq7/4cKu/+LD + r//iw7D/4sOx/+LEsf/jxbP/6M/A/+bMu//r0bz/4OP4/wAZ5f80Yvv/Z3GN/2JfUv9VU0r/Pz016igo + QB0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACXaVeh387B//Xo2//fv6j/4MCr/+DA + rP/hwa3/4cKu/+HCrv/hwq//4cOw/+HDsf/iwq//4cGu/+vVxv////j/cIb0/3Z8of/x7+b/hYJ3/0BS + lf8VL7H/CQd6wwAAcQUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJZqV7jp287/9OTU/+C8 + pf/gv6n/4MCq/+DAq//hwKz/4cGt/+HBrf/hwq3/59DA/+zZzP/u3M//9uzj//778/////n/k5OQ/5+f + n/87Y+r/G1D//w5E//8AELf/AACSjQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAl2pVyvLm + 2f/w3s7/3rum/9++qP/gv6n/4L+q/+C/qv/gwKv/4MCs/9++qf/z593///v0//358//9+fH//fny//// + +f+3ppf/R1/H/0Njxv8pWPf/G07//ws///8ABZz+AACXUgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACXbFXX9+/h/+/by//fvKP/372m/9++p//fvqj/376p/9+/qf/fv6r/4L+p//bq3f/++/X//vvy//z5 + 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 + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACOaVVlg15O1oNc + S6eDXkxzg15OQIdmVBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJFD + RgSDYU3axbCm/8Wzp/+ojYD/jWtc/4FaR/qJYU/Wi2JQpI9lVHCMaFU8nHVMDwAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAJBsV0iKZ1b+///+////+v////3///////j28f/f0sz/wrGn/6eMf/+LaFj/f1dH+Ihh + TdSLZFKgjmdSbZFqVzmRYEYMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAI9lUq2/qp3////6//769f/+/fj//vv3//79+f///vz///////// + ////////+vj2/9nQy/+zopn/nYR4/4RjU/5/WUj4hmFO0YpgT52IZVJqjGJUN39gPQkAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAl25hFYNdSffy6+P///z3//369P/s3tP///////// + //////////////////////7//////+rr6v/e3+D/5efn/+/z9P/t6+r/29DM/76so/+ih3v/hmRU/3xX + RviEXkzOh2BOm4ZjUGaNZ1AzkVVXCgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkmtYap5/b/////3////8/8+l + jv+AFwD/gicA/5RKJP+sdVn/w5+O/+DNw//8+vf//////83Q0f/Jy8z/zc7O/9XV1f/m5ub///////// + //////////////bz8//Yz8n/vKqh/56Edv+CYVD/e1dF9YdjUsqPa1haAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkGdVw8y6 + r////vn//////5k/Ef+JKwD/hSsA/38mAP94IQD/cR0A/2kXAP9jFQD/aioN/189Lf9zXVL/nJON/8bG + x//29vb/////////////////////////////////////////////////8e3s/39dS/6QaldXAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACea2EYiF9M+/bx6f////n/27ik/4UdAP+HKQD/gyoA/38pAP96JwD/dSUA/3AkAP9rIgD/WRsA/zkO + AP8rAQD/iX98/+Lj5P//////////////////////////////////////////////////////sJqP/4Vg + TbEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACVb1lin39u////+//+/fj/3Lqn/7p/Yv+mXzz/jTsT/3khAP9wGQD/bRoA/2ga + AP9mGgD/URkA/y0mIf9JLCH/09XW//////////////////////////////////////////////////// + ///y7uz/fFdE+ZBqUiYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACUaVWvxbKl///+9v/8+fL///74/////v////////////// + ///x6OL/28a6/8Kgkf+ofmj/hltG/wCKvf94c3H/7u7t//////////////////////////////////// + //////////////////+wmo//hmFOnwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI9eYQaKY03u6t/W//778//8+fL//vrz//35 + 9P/9+/T//fv1//779//+/vr////+/////////////////8Pr9v/UzsP/PT1h/zw5i//09Pr///////// + //////////////////////////////7+/v+CW0n9kGtXLgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJxuWjmQalb+///5//36 + 8v/48Oj/+fPr//369f/+/fj//fz5//79+f/+/vr//vz6///9+v///fv///37//////9ueNr/D0X//wAP + wP8AAI3/zs3o/////////////////////////////////8i4sP+IYFDAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJht + W3WtkYL////4//368//myrn/48Sy/+PFs//lybr/6dHC/+zXy//v3tT/8uTc//bs5f/58+///fr5//// + //8AALz/Hk77/xhN//8FJNX/AACI/7m53////////////////////////////5N0Zf+MZlVfAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAJZrWbDLtqj///31//nz6//ixLL/48e1/+THtv/kyLf/5Mi4/+TJt//kyLj/5Mm4/+PJ + uf/lyLj/5Mi5//PXvf8xPcb/ETXh/yJU//8WSf//BCng/wAAhf+7ud7/////////////////8O3r/4FZ + RvOGYEwPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAjwAAAo9sV+Xn2tD///zz//Hk2P/jxbL/48e1/+PHtf/kx7b/5Mi3/+TI + uP/kybj/5Mm5/+TKuv/kyrv/5cq7/+vPvP+lm8P/AA/M/ypd//8dUP//Ekf//wQn3/8AAIL/yMfk//// + ////////wK6l/4tjUqsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAo3hjHY5kUf39+O7///nz/+vUxf/jxrL/48a0/+PG + tP/kx7X/5Me2/+THt//kyLj/5Mi4/+TJuf/kybr/5Mm6/+bLu//11rz/FCvO/xlA6v8pWf//G0z//xBE + //8BI9n/AACD/9vb7P//////l3Zm/49nVlsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAm3BfTZ96af////f//fry/+TI + tP/jxbL/48Wz/+PGtP/jxrT/5Me1/+THtv/kx7f/5Me3/+TIuP/kybn/5Mm5/+TJuv/sz7v/npXF/wAS + 1f8wYf//I1X//xhL//8NQv//ABnL/wUCi//n4+f/hl5J+pBxThIAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoHNed7OV + hf////X/+vLp/+HBrf/ixLH/4sWy/+LFs//jxrP/48a0/+THtf/kx7b/5Me2/+THt//kyLf/5Mi4/+TI + uf/lyrr/9NW6/yY61P8WO+f/LmD//yFS//8WSf//CkH//wAQvP8PCYH/kmtWxAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAnXJaosevof///PT/9Ojb/+HBrP/ixLD/4sSx/+LEsv/ixbP/4sWz/+PGtP/jxrX/48a2/+PG + tv/kx7f/5Me3/+TIuP/kx7f/58m0/7+rvf8AD9n/MF78/ypb//8fUP//E0X//wg9//8ACav/AwGLvwAA + WgMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAnHBax9jHuf//+/L/79zN/+LCrv/iw6//4sSw/+LEsf/ixLL/4sSy/+LF + s//jxrP/48a0/+PGtf/jxrb/48a2/+PGtP/27OT//vz3////9/9Ta+n/By3h/zZm//8nWf//HE///xFE + //8GOf//AASZ/wAAlokAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAABjG5b5ure0f/++vL/6tTC/+LBrf/iw6//4sOv/+LE + sP/ixLD/4sSx/+LEsv/ixbL/48Wz/+PFtP/jxbX/48a1/+LEtP/9/Pf//vv3///+9//7+ff/ABzf/yhS + 9P8xYv//Jlf//xpL//8OQf//ATH8/wAAlv0AAKFbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACGd1MQkmhU+/jy5v/8+O//5su4/+HB + rf/iwq7/4sKu/+LDr//iw6//4sOw/+LEsf/ixLL/4sSy/+PFsv/jxbP/48W0/+rUxv////3///35///+ + +f////v/mqny/wAZ4P85av//LV7//yFT//8VSf//KkWz/zg9V/8zMjz2Ojo4WgAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACbcFgrmG5a///6 + 8P/8+e7/4sOv/+HBrP/hwa3/4cKu/+LCrv/iw6//4sOv/+LDsP/iw7H/4sOx/+LEsf/ixLL/4sSz/+bM + vf/q1Mb/6dHD/+jOv//q0cH////6/ypK6v8VPOv/Nmj//zZd5f9iZWv/XlxT/1ZVU/9MTEv/ODg48zIy + MCcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACbclxFontp///98//9+Oz/37+o/+DBq//gwav/4cGs/+HBrf/hwq7/4cKu/+HCr//iw6//4sOw/+LD + sP/iw7H/4sOx/+LEsv/ixLL/4sSz/+LEsv/r1sj////3/+Tn9P8AF+b/P2Hb/6Kflf+trKn/cHBv/11c + WP9UUEb/QD9E/zg3MccAAJUCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACbcFxarIl2///88P/59Of/37yl/+DAqv/gwKr/4MCr/+HArP/hwa3/4cGt/+HC + rv/hwq7/4cKv/+HCr//hw7D/4cOw/+LDsf/iw7H/4sSw/+HBr//x4tf//vv1////9P9/kvb/hIaR/93c + 2v/u7ez/iod9/09dj/8aRur/ADT//wACmP8AAJN7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACZblpwuJeF///78P/57+P/37ul/+C/qf/gv6r/4MCq/+DA + qv/gwKv/4cCs/+HArf/hwa3/4cGt/+HCrv/hwq//4saz/+bMu//nzr3/6NHB/+nRwv/58uv//vrz///7 + 8v////f/jo6M/4qKiP+ioJz/Q2bU/x9U//8ZSv//DUD//wMu8P8AAIn6AACcRAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACZcFqFwKOR///77v/27N7/4Lyk/+C+ + p//gvqj/4L+p/+C/qv/gv6r/4L+r/+HAq//hwKz/4cCs/+HBrf/hwKz/6tTF///99//9+vT//fvz//37 + 9P/9+fL//Pjx//z48f///ff/zcrF/5CQif9QceH/M2b//yxd//8hU///Fkn//wtA//8BIdj/AACG5gAA + oBsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACbblmTxqua///5 + 7v/16Nv/3rqj/9+9pv/fvqf/376o/+C+qf/gv6n/4L+q/+C/qv/gwKv/4MCr/+DArP/gv6v/69XG//36 + 8v/89+///Pfv//z38P/8+PD//Pjw//z48P////j/xK6g/5mPif0bPNX+WmaE/z9ZrP8nWP//H1H//xRH + //8IPv//ABK2/wAAicEAALEFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACbb1mfzLOh//756//16Nj/37ui/9+9pv/fvab/376m/9++p//fvqj/376p/9++qf/fv6n/4MCq/+DA + qv/gwKr/69XF///79P/9+vH//frx//368//9+vP//frz//358v////n/tJiH/4Jyae1/fnn+nZyX/4aD + ev9GUnX/I1T+/x1P//8RQ///Bjr//wAFmv8AAJKCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACccFqt0bmn///36v/z5db/3bqh/9+8pf/fvKX/372m/9+9pv/fvaf/376n/9++ + qP/fvqn/376p/9+/qf/gv6r/5cq3/+3Yyf/r1cb/6tPC/+nQwP/ozr7/5sq5/+7bzP////v/o4Jy/4xr + WnWBhISGh4WD+aurqf+Sj4j/OkyH/yNU//8aTf//D0L//wQw9P8AAIv8AACeRQAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACbb1q21L6q//z15f/z5NT/3bmg/967o//fvKT/37yl/9+8 + pf/fvab/372m/9+9p//fvaf/372o/9++qP/fvqn/376p/9+/qP/gvqj/4L6p/+C+qf/gv6v/4L2p/+vX + xv////z/lXFf/5VrVkMAAAAAV2u7ZYaGhv6/vrz/eXhw/yZHuf8iVf//GUn//wxB//8CINX/AACJ5AAA + lxUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACbb1q+2MGu//z05f/z49L/3rid/966 + ov/eu6P/37uj/9+7pP/fvKX/37yl/9+9pv/fvab/372m/9+9p//fvaf/372o/9+8p//fvaf/372o/+C+ + p//gvab/37uk/+3ay/////n/jGZT/pVqWi4AAAAAAAAAAExgtKqopZ//wcC7/0tVdP8gS9n/IVP//xVI + //8KQP//AQ6v/wAAk6wAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACablnG28Wy//3z + 4v/y48//3LWc/925n//duqL/3rmh/9+6ov/fuqD/3rmh/966ov/euaH/3rmg/9+8pf/hwqz/5ci0/+fN + u//q08L/7NjI/+/d0P/z5Nf/9erd//r06f/9+e7/iF9O/pRpUxoAAAAAAAAAAAM1/xNzeYvf09LQ/5WS + i/8qSKr/JFLr/x9Q//8TRf//Bzn9/wAAk/4AAJ5aAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACbblrG28Sx//vx3//048//37uh/+LErf/myrT/6dG8/+zWxP/v3cz/8+LT//Xo2//57uL/+/bp//z4 + 7v/9+O3//ffu//z37f/89+z//Pfu//347v/9+O7//vnv///78P/99+3/iV9N/ZFzUBEAAAAAAAAAAAAA + AAB3hahEpaSj/d7d2v9XX3j/IEbA/yZW/P8dTv//EET//wUm3v8AAIrpAACfFgAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACZblrG2cOv//vv2//57tv/+/Hg//vx4v/68uL/+/Pk//v05f/79ef/+/Xo//73 + 6v/+9+r//vjs///57f//+u7///zx///98f///vP///ru//fv5P/r4NT/3tHE/9PBtP/EsKH/i2NS/Z9m + VRAAAAAAAAAAAAAAAAAAAAAAjY2NquHh4f+vrKf/Nk+i/yJJyP8lVv//GUz//w5E//8CD7D/AACWnAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACabVnG28Wv//7y3f/78d3//PPg//704v//9uX///jo///5 + 6v/78uT/8ufY/+fYzP/dy7z/0bus/8aunv+7no//r5F+/6SAbf+YcV7/j2dU/4xiT/2QZVDvlWlX2Zdr + V8GXa1ipm3BdhVpgYwMAAAAAAAAAAAAAAAAAAAAAn5+fJKampvX/////enx+/ydJtv8kTdX/I1X//xhJ + //8KOfj/AACP+wAAoC8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACZb1vGyq6Z/9rDrv/NtJ7/xaiU/7uZ + h/+wjXn/pH1r/5pxXP6Valb+l2pV+p1wW+ifcFvQnnJct55xXZ+fc16Gn3NgbaFzYFWddF09oXNcJKFh + Sw5ZYGIDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJeXl3rY2Nj/6urm/2Bo + gf8hRbr/JE7e/yBT//8VSf//BRnC/wAAmqoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACoe2ShpnZi3qV3 + YMWldmGtpXhhlKd6X3yleGFjqXhhS6h3YTOkblwbpX1QBwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI2N + jQSVlZW/3t7d/8nHwv9gaIL/IUW1/yFM3v8eUf//EUD5/wAAk/kAAKcaAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACenp4SlpaWzsXFxf+9vLf/eXt+/ztQl/8cRtL/GFD//wAJtf8AAKZaAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAr6+vD5qamq2joqL+srGu/5eWkP93dHD/TlZv/1BS + Vv8yMk+LAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACfoqJNfYKT4JSS + h/+Lioj/qqmm/62trP9iYmH5QUFBOwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAB//DxY44YiOkZ7ry8vK/6SkpP9oaGj/TExM5AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACtrao2nJyb+YeHh/+hoaH/W1tbuAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlJSUgpeXl+t4eHiVbW1tDgAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////AAD///////8AAP8P/////wAA/wB///// + AAD/AAP///8AAP4AAB///wAA/gAAAP//AAD8AAAAD/8AAPwAAAAP/wAA/AAAAB//AAD4AAAAP/8AAPgA + AAA//wAA+AAAAH//AAD4AAAAf/8AAPAAAAB//wAA8AAAAP//AADwAAAA//8AAPAAAAD//wAA8AAAAf// + AADgAAAB//8AAOAAAAH//wAA4AAAAP//AADgAAAAf/8AAOAAAAA//wAA4AAAAD//AADgAAAAH/8AAMAA + AAAP/wAAwAAAAA//AADAAAAAB/8AAMAAAAAD/wAAwAAAAAH/AADAAAAAAf8AAMAAAAwA/wAAwAAADgB/ + AADAAAAPAD8AAMAAAA+APwAAwAAAD4AfAADAAAAPwB8AAMAAD//ADwAAwH///+APAAD/////8AcAAP// + ///4BwAA//////4HAAD//////wMAAP//////wwAA///////HAAD///////8AAP///////wAA + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/FolderLocker/app.config b/Demo_Source_Code/CSharpDemo/FolderLocker/app.config new file mode 100644 index 0000000..193d618 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FolderLocker/app.config @@ -0,0 +1,7 @@ + + + + + + + diff --git a/Demo_Source_Code/CSharpDemo/FolderLocker/app.manifest b/Demo_Source_Code/CSharpDemo/FolderLocker/app.manifest new file mode 100644 index 0000000..d49604f --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/FolderLocker/app.manifest @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Demo_Source_Code/CSharpDemo/ProcessMon/ProcessFileAccessRights.Designer.cs b/Demo_Source_Code/CSharpDemo/ProcessMon/ProcessFileAccessRights.Designer.cs new file mode 100644 index 0000000..09d5773 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/ProcessMon/ProcessFileAccessRights.Designer.cs @@ -0,0 +1,366 @@ +using EaseFilter.CommonObjects; + +namespace ProcessMon +{ + partial class ProcessFileAccessRights + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ProcessFileAccessRights)); + this.button_ApplyAll = new System.Windows.Forms.Button(); + this.button_Add = new System.Windows.Forms.Button(); + this.button_Delete = new System.Windows.Forms.Button(); + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.listView_ProcessFileAccessRights = new System.Windows.Forms.ListView(); + this.groupBox_ProcessRights = new System.Windows.Forms.GroupBox(); + this.button_SelectFolder = new System.Windows.Forms.Button(); + this.button_Info = new System.Windows.Forms.Button(); + this.label1 = new System.Windows.Forms.Label(); + this.textBox_FileMask = new System.Windows.Forms.TextBox(); + this.label2 = new System.Windows.Forms.Label(); + this.textBox_AccessFlag = new System.Windows.Forms.TextBox(); + this.button_AccessFlag = new System.Windows.Forms.Button(); + this.checkBox_SetSecurity = new System.Windows.Forms.CheckBox(); + this.checkBox_QueryInfo = new System.Windows.Forms.CheckBox(); + this.checkBox_Read = new System.Windows.Forms.CheckBox(); + this.checkBox_QuerySecurity = new System.Windows.Forms.CheckBox(); + this.checkBox_SetInfo = new System.Windows.Forms.CheckBox(); + this.checkBox_Write = new System.Windows.Forms.CheckBox(); + this.checkBox_AllowDelete = new System.Windows.Forms.CheckBox(); + this.checkBox_AllowRename = new System.Windows.Forms.CheckBox(); + this.checkBox_Creation = new System.Windows.Forms.CheckBox(); + this.groupBox1.SuspendLayout(); + this.groupBox_ProcessRights.SuspendLayout(); + this.SuspendLayout(); + // + // button_ApplyAll + // + this.button_ApplyAll.DialogResult = System.Windows.Forms.DialogResult.OK; + this.button_ApplyAll.Location = new System.Drawing.Point(406, 381); + this.button_ApplyAll.Name = "button_ApplyAll"; + this.button_ApplyAll.Size = new System.Drawing.Size(144, 23); + this.button_ApplyAll.TabIndex = 85; + this.button_ApplyAll.Text = "Apply settings to sandbox"; + this.button_ApplyAll.UseVisualStyleBackColor = true; + this.button_ApplyAll.Click += new System.EventHandler(this.button_ApplyAll_Click); + // + // button_Add + // + this.button_Add.Location = new System.Drawing.Point(15, 381); + this.button_Add.Name = "button_Add"; + this.button_Add.Size = new System.Drawing.Size(122, 23); + this.button_Add.TabIndex = 84; + this.button_Add.Text = "Add file entry"; + this.button_Add.UseVisualStyleBackColor = true; + this.button_Add.Click += new System.EventHandler(this.button_Add_Click); + // + // button_Delete + // + this.button_Delete.Location = new System.Drawing.Point(197, 381); + this.button_Delete.Name = "button_Delete"; + this.button_Delete.Size = new System.Drawing.Size(128, 23); + this.button_Delete.TabIndex = 83; + this.button_Delete.Text = "Delete file entry"; + this.button_Delete.UseVisualStyleBackColor = true; + this.button_Delete.Click += new System.EventHandler(this.button_Delete_Click); + // + // groupBox1 + // + this.groupBox1.Controls.Add(this.listView_ProcessFileAccessRights); + this.groupBox1.Location = new System.Drawing.Point(15, 225); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size(535, 134); + this.groupBox1.TabIndex = 82; + this.groupBox1.TabStop = false; + this.groupBox1.Text = "File Access rights collection"; + // + // listView_ProcessFileAccessRights + // + this.listView_ProcessFileAccessRights.Dock = System.Windows.Forms.DockStyle.Fill; + this.listView_ProcessFileAccessRights.FullRowSelect = true; + this.listView_ProcessFileAccessRights.Location = new System.Drawing.Point(3, 16); + this.listView_ProcessFileAccessRights.Name = "listView_ProcessFileAccessRights"; + this.listView_ProcessFileAccessRights.Size = new System.Drawing.Size(529, 115); + this.listView_ProcessFileAccessRights.TabIndex = 1; + this.listView_ProcessFileAccessRights.UseCompatibleStateImageBehavior = false; + this.listView_ProcessFileAccessRights.View = System.Windows.Forms.View.Details; + this.listView_ProcessFileAccessRights.SelectedIndexChanged += new System.EventHandler(this.listView_ProcessFileAccessRights_SelectedIndexChanged); + // + // groupBox_ProcessRights + // + this.groupBox_ProcessRights.Controls.Add(this.button_SelectFolder); + this.groupBox_ProcessRights.Controls.Add(this.button_Info); + this.groupBox_ProcessRights.Controls.Add(this.label1); + this.groupBox_ProcessRights.Controls.Add(this.textBox_FileMask); + this.groupBox_ProcessRights.Controls.Add(this.label2); + this.groupBox_ProcessRights.Controls.Add(this.textBox_AccessFlag); + this.groupBox_ProcessRights.Controls.Add(this.button_AccessFlag); + this.groupBox_ProcessRights.Controls.Add(this.checkBox_SetSecurity); + this.groupBox_ProcessRights.Controls.Add(this.checkBox_QueryInfo); + this.groupBox_ProcessRights.Controls.Add(this.checkBox_Read); + this.groupBox_ProcessRights.Controls.Add(this.checkBox_QuerySecurity); + this.groupBox_ProcessRights.Controls.Add(this.checkBox_SetInfo); + this.groupBox_ProcessRights.Controls.Add(this.checkBox_Write); + this.groupBox_ProcessRights.Controls.Add(this.checkBox_AllowDelete); + this.groupBox_ProcessRights.Controls.Add(this.checkBox_AllowRename); + this.groupBox_ProcessRights.Controls.Add(this.checkBox_Creation); + this.groupBox_ProcessRights.Location = new System.Drawing.Point(21, 12); + this.groupBox_ProcessRights.Name = "groupBox_ProcessRights"; + this.groupBox_ProcessRights.Size = new System.Drawing.Size(529, 206); + this.groupBox_ProcessRights.TabIndex = 81; + this.groupBox_ProcessRights.TabStop = false; + this.groupBox_ProcessRights.Text = "File Access Rights the Process "; + // + // button_SelectFolder + // + this.button_SelectFolder.Location = new System.Drawing.Point(422, 32); + this.button_SelectFolder.Name = "button_SelectFolder"; + this.button_SelectFolder.Size = new System.Drawing.Size(60, 20); + this.button_SelectFolder.TabIndex = 92; + this.button_SelectFolder.Text = "..."; + this.button_SelectFolder.UseVisualStyleBackColor = true; + this.button_SelectFolder.Click += new System.EventHandler(this.button_SelectFolder_Click); + // + // button_Info + // + this.button_Info.BackColor = System.Drawing.Color.AntiqueWhite; + this.button_Info.Image = global::ProcessMon.Properties.Resources.about; + this.button_Info.Location = new System.Drawing.Point(484, 32); + this.button_Info.Name = "button_Info"; + this.button_Info.Size = new System.Drawing.Size(33, 20); + this.button_Info.TabIndex = 91; + this.button_Info.UseVisualStyleBackColor = false; + this.button_Info.Click += new System.EventHandler(this.button_Info_Click); + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(12, 32); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(80, 13); + this.label1.TabIndex = 39; + this.label1.Text = "File name mask"; + // + // textBox_FileMask + // + this.textBox_FileMask.Location = new System.Drawing.Point(152, 32); + this.textBox_FileMask.Name = "textBox_FileMask"; + this.textBox_FileMask.Size = new System.Drawing.Size(242, 20); + this.textBox_FileMask.TabIndex = 38; + this.textBox_FileMask.Text = "c:\\test\\*"; + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(10, 70); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(97, 13); + this.label2.TabIndex = 32; + this.label2.Text = "Access control flag"; + // + // textBox_AccessFlag + // + this.textBox_AccessFlag.Location = new System.Drawing.Point(152, 67); + this.textBox_AccessFlag.Name = "textBox_AccessFlag"; + this.textBox_AccessFlag.ReadOnly = true; + this.textBox_AccessFlag.Size = new System.Drawing.Size(242, 20); + this.textBox_AccessFlag.TabIndex = 31; + this.textBox_AccessFlag.Text = "0"; + // + // button_AccessFlag + // + this.button_AccessFlag.Location = new System.Drawing.Point(422, 69); + this.button_AccessFlag.Name = "button_AccessFlag"; + this.button_AccessFlag.Size = new System.Drawing.Size(60, 20); + this.button_AccessFlag.TabIndex = 33; + this.button_AccessFlag.Text = "..."; + this.button_AccessFlag.UseVisualStyleBackColor = true; + this.button_AccessFlag.Click += new System.EventHandler(this.button_AccessFlag_Click); + // + // checkBox_SetSecurity + // + this.checkBox_SetSecurity.AutoSize = true; + this.checkBox_SetSecurity.Checked = true; + this.checkBox_SetSecurity.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBox_SetSecurity.Location = new System.Drawing.Point(152, 152); + this.checkBox_SetSecurity.Name = "checkBox_SetSecurity"; + this.checkBox_SetSecurity.Size = new System.Drawing.Size(137, 17); + this.checkBox_SetSecurity.TabIndex = 29; + this.checkBox_SetSecurity.Text = "Allow changing security"; + this.checkBox_SetSecurity.UseVisualStyleBackColor = true; + this.checkBox_SetSecurity.CheckedChanged += new System.EventHandler(this.checkBox_SetSecurity_CheckedChanged); + // + // checkBox_QueryInfo + // + this.checkBox_QueryInfo.AutoSize = true; + this.checkBox_QueryInfo.Checked = true; + this.checkBox_QueryInfo.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBox_QueryInfo.Location = new System.Drawing.Point(334, 129); + this.checkBox_QueryInfo.Name = "checkBox_QueryInfo"; + this.checkBox_QueryInfo.Size = new System.Drawing.Size(148, 17); + this.checkBox_QueryInfo.TabIndex = 24; + this.checkBox_QueryInfo.Text = "Allow querying information"; + this.checkBox_QueryInfo.UseVisualStyleBackColor = true; + this.checkBox_QueryInfo.CheckedChanged += new System.EventHandler(this.checkBox_QueryInfo_CheckedChanged); + // + // checkBox_Read + // + this.checkBox_Read.AutoSize = true; + this.checkBox_Read.Checked = true; + this.checkBox_Read.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBox_Read.Location = new System.Drawing.Point(334, 106); + this.checkBox_Read.Name = "checkBox_Read"; + this.checkBox_Read.Size = new System.Drawing.Size(105, 17); + this.checkBox_Read.TabIndex = 26; + this.checkBox_Read.Text = "Allow reading file"; + this.checkBox_Read.UseVisualStyleBackColor = true; + this.checkBox_Read.CheckedChanged += new System.EventHandler(this.checkBox_Read_CheckedChanged); + // + // checkBox_QuerySecurity + // + this.checkBox_QuerySecurity.AutoSize = true; + this.checkBox_QuerySecurity.Checked = true; + this.checkBox_QuerySecurity.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBox_QuerySecurity.Location = new System.Drawing.Point(334, 152); + this.checkBox_QuerySecurity.Name = "checkBox_QuerySecurity"; + this.checkBox_QuerySecurity.Size = new System.Drawing.Size(133, 17); + this.checkBox_QuerySecurity.TabIndex = 25; + this.checkBox_QuerySecurity.Text = "Allow querying security"; + this.checkBox_QuerySecurity.UseVisualStyleBackColor = true; + this.checkBox_QuerySecurity.CheckedChanged += new System.EventHandler(this.checkBox_QuerySecurity_CheckedChanged); + // + // checkBox_SetInfo + // + this.checkBox_SetInfo.AutoSize = true; + this.checkBox_SetInfo.Checked = true; + this.checkBox_SetInfo.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBox_SetInfo.Location = new System.Drawing.Point(152, 128); + this.checkBox_SetInfo.Name = "checkBox_SetInfo"; + this.checkBox_SetInfo.Size = new System.Drawing.Size(152, 17); + this.checkBox_SetInfo.TabIndex = 28; + this.checkBox_SetInfo.Text = "Allow changing information"; + this.checkBox_SetInfo.UseVisualStyleBackColor = true; + this.checkBox_SetInfo.CheckedChanged += new System.EventHandler(this.checkBox_SetInfo_CheckedChanged); + // + // checkBox_Write + // + this.checkBox_Write.AutoSize = true; + this.checkBox_Write.Checked = true; + this.checkBox_Write.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBox_Write.Location = new System.Drawing.Point(12, 129); + this.checkBox_Write.Name = "checkBox_Write"; + this.checkBox_Write.Size = new System.Drawing.Size(100, 17); + this.checkBox_Write.TabIndex = 15; + this.checkBox_Write.Text = "Allow writing file"; + this.checkBox_Write.UseVisualStyleBackColor = true; + this.checkBox_Write.CheckedChanged += new System.EventHandler(this.checkBox_Write_CheckedChanged); + // + // checkBox_AllowDelete + // + this.checkBox_AllowDelete.AutoSize = true; + this.checkBox_AllowDelete.Checked = true; + this.checkBox_AllowDelete.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBox_AllowDelete.Location = new System.Drawing.Point(12, 152); + this.checkBox_AllowDelete.Name = "checkBox_AllowDelete"; + this.checkBox_AllowDelete.Size = new System.Drawing.Size(107, 17); + this.checkBox_AllowDelete.TabIndex = 17; + this.checkBox_AllowDelete.Text = "Allow deleting file"; + this.checkBox_AllowDelete.UseVisualStyleBackColor = true; + this.checkBox_AllowDelete.CheckedChanged += new System.EventHandler(this.checkBox_AllowDelete_CheckedChanged); + // + // checkBox_AllowRename + // + this.checkBox_AllowRename.AutoSize = true; + this.checkBox_AllowRename.Checked = true; + this.checkBox_AllowRename.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBox_AllowRename.Location = new System.Drawing.Point(152, 106); + this.checkBox_AllowRename.Name = "checkBox_AllowRename"; + this.checkBox_AllowRename.Size = new System.Drawing.Size(113, 17); + this.checkBox_AllowRename.TabIndex = 16; + this.checkBox_AllowRename.Text = "Allow renaming file"; + this.checkBox_AllowRename.UseVisualStyleBackColor = true; + this.checkBox_AllowRename.CheckedChanged += new System.EventHandler(this.checkBox_AllowRename_CheckedChanged); + // + // checkBox_Creation + // + this.checkBox_Creation.AutoSize = true; + this.checkBox_Creation.Checked = true; + this.checkBox_Creation.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBox_Creation.Location = new System.Drawing.Point(12, 106); + this.checkBox_Creation.Name = "checkBox_Creation"; + this.checkBox_Creation.Size = new System.Drawing.Size(131, 17); + this.checkBox_Creation.TabIndex = 22; + this.checkBox_Creation.Text = "Allow creating new file"; + this.checkBox_Creation.UseVisualStyleBackColor = true; + this.checkBox_Creation.CheckedChanged += new System.EventHandler(this.checkBox_Creation_CheckedChanged); + // + // ProcessFileAccessRights + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(562, 444); + this.Controls.Add(this.button_ApplyAll); + this.Controls.Add(this.button_Add); + this.Controls.Add(this.button_Delete); + this.Controls.Add(this.groupBox1); + this.Controls.Add(this.groupBox_ProcessRights); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Name = "ProcessFileAccessRights"; + this.Text = "Add File Access Control To The Process"; + this.groupBox1.ResumeLayout(false); + this.groupBox_ProcessRights.ResumeLayout(false); + this.groupBox_ProcessRights.PerformLayout(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.Button button_ApplyAll; + private System.Windows.Forms.Button button_Add; + private System.Windows.Forms.Button button_Delete; + private System.Windows.Forms.GroupBox groupBox1; + private System.Windows.Forms.ListView listView_ProcessFileAccessRights; + private System.Windows.Forms.GroupBox groupBox_ProcessRights; + private System.Windows.Forms.Button button_Info; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.TextBox textBox_FileMask; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.TextBox textBox_AccessFlag; + private System.Windows.Forms.Button button_AccessFlag; + private System.Windows.Forms.CheckBox checkBox_SetSecurity; + private System.Windows.Forms.CheckBox checkBox_QueryInfo; + private System.Windows.Forms.CheckBox checkBox_Read; + private System.Windows.Forms.CheckBox checkBox_QuerySecurity; + private System.Windows.Forms.CheckBox checkBox_SetInfo; + private System.Windows.Forms.CheckBox checkBox_Write; + private System.Windows.Forms.CheckBox checkBox_AllowDelete; + private System.Windows.Forms.CheckBox checkBox_AllowRename; + private System.Windows.Forms.CheckBox checkBox_Creation; + private System.Windows.Forms.Button button_SelectFolder; + } +} \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/ProcessMon/ProcessFileAccessRights.cs b/Demo_Source_Code/CSharpDemo/ProcessMon/ProcessFileAccessRights.cs new file mode 100644 index 0000000..cd66c87 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/ProcessMon/ProcessFileAccessRights.cs @@ -0,0 +1,426 @@ +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; + +using EaseFilter.FilterControl; +using EaseFilter.CommonObjects; + +namespace ProcessMon +{ + public partial class ProcessFileAccessRights : Form + { + public struct FileAccessRight + { + public string FileNameMask; + public uint AccessFlag; + } + + ProcessFilterRule currentFilterRule = null; + Dictionary processFileAccessRightsList = new Dictionary(); + FileAccessRight currentFileAccessRight = new FileAccessRight(); + + public ProcessFileAccessRights(ProcessFilterRule filterRule) + { + InitializeComponent(); + + StartPosition = FormStartPosition.CenterParent; + + currentFilterRule = filterRule; + string processFileAccessRights = filterRule.FileAccessRights; + + string[] accessRightList = processFileAccessRights.ToLower().Split(new char[] { ';' }); + if (accessRightList.Length > 0) + { + foreach (string processFileAccessRightStr in accessRightList) + { + if (processFileAccessRightStr.Trim().Length > 0) + { + string fileMask = processFileAccessRightStr.Substring(0, processFileAccessRightStr.IndexOf('!')); + uint accessFlag = uint.Parse(processFileAccessRightStr.Substring(processFileAccessRightStr.IndexOf('!') + 1)); + + if (!processFileAccessRightsList.ContainsKey(fileMask)) + { + FileAccessRight fileAccessRight = new FileAccessRight(); + fileAccessRight.FileNameMask = fileMask; + fileAccessRight.AccessFlag = accessFlag; + + processFileAccessRightsList.Add(fileMask, fileAccessRight); + + currentFileAccessRight = fileAccessRight; + } + + textBox_FileMask.Text = fileMask; + textBox_AccessFlag.Text = accessFlag.ToString(); + } + } + + } + + groupBox_ProcessRights.Text = "The file access rights for processes which match " + filterRule.ProcessNameFilterMask; + + InitListView(); + SetCheckBoxValue(); + } + + public void InitListView() + { + //init ListView control + listView_ProcessFileAccessRights.Clear(); //clear control + //create column header for ListView + listView_ProcessFileAccessRights.Columns.Add("#", 20, System.Windows.Forms.HorizontalAlignment.Left); + listView_ProcessFileAccessRights.Columns.Add("File Name Mask", 350, System.Windows.Forms.HorizontalAlignment.Left); + listView_ProcessFileAccessRights.Columns.Add("Access Flag", 150, System.Windows.Forms.HorizontalAlignment.Left); + + foreach (FileAccessRight fileAccessRight in processFileAccessRightsList.Values) + { + string[] itemStr = new string[listView_ProcessFileAccessRights.Columns.Count]; + itemStr[0] = listView_ProcessFileAccessRights.Items.Count.ToString(); + itemStr[1] = fileAccessRight.FileNameMask; + itemStr[2] = fileAccessRight.AccessFlag.ToString("X"); + + ListViewItem item = new ListViewItem(itemStr, 0); + item.Tag = fileAccessRight; + listView_ProcessFileAccessRights.Items.Add(item); + } + + } + + private void SetCheckBoxValue() + { + + if (textBox_AccessFlag.Text.Trim().Length == 0) + { + return; + } + + uint accessFlags = uint.Parse(textBox_AccessFlag.Text); + + if ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_FILE_DELETE) > 0) + { + checkBox_AllowDelete.Checked = true; + } + else + { + checkBox_AllowDelete.Checked = false; + } + + if ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_FILE_RENAME) > 0) + { + checkBox_AllowRename.Checked = true; + } + else + { + checkBox_AllowRename.Checked = false; + } + + if ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_WRITE_ACCESS) > 0) + { + checkBox_Write.Checked = true; + } + else + { + checkBox_Write.Checked = false; + } + + if ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_READ_ACCESS) > 0) + { + checkBox_Read.Checked = true; + } + else + { + checkBox_Read.Checked = false; + } + + if ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_QUERY_INFORMATION_ACCESS) > 0) + { + checkBox_QueryInfo.Checked = true; + } + else + { + checkBox_QueryInfo.Checked = false; + } + + if ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_SET_INFORMATION) > 0) + { + checkBox_SetInfo.Checked = true; + } + else + { + checkBox_SetInfo.Checked = false; + } + + if ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_OPEN_WITH_CREATE_OR_OVERWRITE_ACCESS) > 0) + { + checkBox_Creation.Checked = true; + } + else + { + checkBox_Creation.Checked = false; + } + + if ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_QUERY_SECURITY_ACCESS) > 0) + { + checkBox_QuerySecurity.Checked = true; + } + else + { + checkBox_QuerySecurity.Checked = false; + } + + if ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_SET_SECURITY_ACCESS) > 0) + { + checkBox_SetSecurity.Checked = true; + } + else + { + checkBox_SetSecurity.Checked = false; + } + + + } + + private void button_AccessFlag_Click(object sender, EventArgs e) + { + OptionForm optionForm = new OptionForm(OptionForm.OptionType.Access_Flag, textBox_AccessFlag.Text); + + if (optionForm.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + if (optionForm.AccessFlags > 0) + { + textBox_AccessFlag.Text = optionForm.AccessFlags.ToString(); + } + else + { + //if the accessFlag is 0, it is exclude filter rule,this is not what we want, so we need to include this flag. + textBox_AccessFlag.Text = ((uint)FilterAPI.AccessFlag.LEAST_ACCESS_FLAG).ToString(); + } + + SetCheckBoxValue(); + } + } + + private void checkBox_Read_CheckedChanged(object sender, EventArgs e) + { + uint accessFlags = uint.Parse(textBox_AccessFlag.Text.Trim()); + if (checkBox_Read.Checked) + { + accessFlags |= (uint)FilterAPI.ALLOW_FILE_READ_ACCESS; + } + else + { + accessFlags &= ~(uint)FilterAPI.ALLOW_FILE_READ_ACCESS; + } + + textBox_AccessFlag.Text = accessFlags.ToString(); + } + + private void checkBox_Write_CheckedChanged(object sender, EventArgs e) + { + uint accessFlags = uint.Parse(textBox_AccessFlag.Text.Trim()); + if (checkBox_Write.Checked) + { + accessFlags |= (uint)FilterAPI.AccessFlag.ALLOW_WRITE_ACCESS; + } + else + { + accessFlags &= ~(uint)FilterAPI.AccessFlag.ALLOW_WRITE_ACCESS; + } + + textBox_AccessFlag.Text = accessFlags.ToString(); + } + + private void checkBox_Creation_CheckedChanged(object sender, EventArgs e) + { + uint accessFlags = uint.Parse(textBox_AccessFlag.Text.Trim()); + if (checkBox_Creation.Checked) + { + accessFlags |= (uint)FilterAPI.AccessFlag.ALLOW_OPEN_WITH_CREATE_OR_OVERWRITE_ACCESS; + } + else + { + accessFlags &= ~(uint)FilterAPI.AccessFlag.ALLOW_OPEN_WITH_CREATE_OR_OVERWRITE_ACCESS; + } + + textBox_AccessFlag.Text = accessFlags.ToString(); + } + + + private void checkBox_QueryInfo_CheckedChanged(object sender, EventArgs e) + { + uint accessFlags = uint.Parse(textBox_AccessFlag.Text.Trim()); + if (checkBox_QueryInfo.Checked) + { + accessFlags |= (uint)FilterAPI.AccessFlag.ALLOW_QUERY_INFORMATION_ACCESS; + } + else + { + accessFlags &= ~(uint)FilterAPI.AccessFlag.ALLOW_QUERY_INFORMATION_ACCESS; + } + + textBox_AccessFlag.Text = accessFlags.ToString(); + } + + private void checkBox_SetInfo_CheckedChanged(object sender, EventArgs e) + { + uint accessFlags = uint.Parse(textBox_AccessFlag.Text.Trim()); + if (checkBox_SetInfo.Checked) + { + accessFlags |= (uint)FilterAPI.AccessFlag.ALLOW_SET_INFORMATION; + } + else + { + accessFlags &= ~(uint)FilterAPI.AccessFlag.ALLOW_SET_INFORMATION; + } + + textBox_AccessFlag.Text = accessFlags.ToString(); + } + + private void checkBox_AllowRename_CheckedChanged(object sender, EventArgs e) + { + uint accessFlags = uint.Parse(textBox_AccessFlag.Text.Trim()); + if (checkBox_AllowRename.Checked) + { + accessFlags |= (uint)FilterAPI.AccessFlag.ALLOW_FILE_RENAME; + } + else + { + accessFlags &= ~(uint)FilterAPI.AccessFlag.ALLOW_FILE_RENAME; + } + + textBox_AccessFlag.Text = accessFlags.ToString(); + } + + private void checkBox_AllowDelete_CheckedChanged(object sender, EventArgs e) + { + uint accessFlags = uint.Parse(textBox_AccessFlag.Text.Trim()); + if (checkBox_AllowDelete.Checked) + { + accessFlags |= (uint)FilterAPI.AccessFlag.ALLOW_FILE_DELETE; + } + else + { + accessFlags &= ~(uint)FilterAPI.AccessFlag.ALLOW_FILE_DELETE; + } + + textBox_AccessFlag.Text = accessFlags.ToString(); + } + + private void checkBox_QuerySecurity_CheckedChanged(object sender, EventArgs e) + { + uint accessFlags = uint.Parse(textBox_AccessFlag.Text.Trim()); + if (checkBox_QuerySecurity.Checked) + { + accessFlags |= (uint)FilterAPI.AccessFlag.ALLOW_QUERY_SECURITY_ACCESS; + } + else + { + accessFlags &= ~(uint)FilterAPI.AccessFlag.ALLOW_QUERY_SECURITY_ACCESS; + } + + textBox_AccessFlag.Text = accessFlags.ToString(); + } + + private void checkBox_SetSecurity_CheckedChanged(object sender, EventArgs e) + { + uint accessFlags = uint.Parse(textBox_AccessFlag.Text.Trim()); + if (checkBox_SetSecurity.Checked) + { + accessFlags |= (uint)FilterAPI.AccessFlag.ALLOW_SET_SECURITY_ACCESS; + } + else + { + accessFlags &= ~(uint)FilterAPI.AccessFlag.ALLOW_SET_SECURITY_ACCESS; + } + + textBox_AccessFlag.Text = accessFlags.ToString(); + } + + + private void button_Add_Click(object sender, EventArgs e) + { + if (textBox_FileMask.Text.Trim().Length == 0) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("The file name mask can't be empty.", "Add file entry", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + + FileAccessRight fileAccessRight = new FileAccessRight(); + fileAccessRight.FileNameMask = textBox_FileMask.Text; + fileAccessRight.AccessFlag = uint.Parse(textBox_AccessFlag.Text); + + if (0 == fileAccessRight.AccessFlag) + { + fileAccessRight.AccessFlag = (uint)FilterAPI.AccessFlag.LEAST_ACCESS_FLAG; + } + + processFileAccessRightsList.Remove(fileAccessRight.FileNameMask); + + processFileAccessRightsList.Add(fileAccessRight.FileNameMask, fileAccessRight); + + InitListView(); + } + + private void button_Delete_Click(object sender, EventArgs e) + { + if (listView_ProcessFileAccessRights.SelectedItems.Count == 0) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("There are no item selected.", "Delete entry", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + FileAccessRight processFileAccessRight = (FileAccessRight)listView_ProcessFileAccessRights.SelectedItems[0].Tag; + + processFileAccessRightsList.Remove(processFileAccessRight.FileNameMask); + + InitListView(); + } + + private void button_ApplyAll_Click(object sender, EventArgs e) + { + currentFilterRule.FileAccessRights = string.Empty; + + foreach (FileAccessRight fileAccessRight in processFileAccessRightsList.Values) + { + currentFilterRule.FileAccessRights += fileAccessRight.FileNameMask + "!" + fileAccessRight.AccessFlag + ";"; + } + } + + private void button_SelectFolder_Click(object sender, EventArgs e) + { + FolderBrowserDialog folderDiag = new FolderBrowserDialog(); + + if (folderDiag.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + textBox_FileMask.Text = folderDiag.SelectedPath + "\\*"; + } + } + + private void button_Info_Click(object sender, EventArgs e) + { + string information = "Set up the file access rights with the file filter mask to the processe.\r\n\r\n"; + information += "you can restrict the process's file access rights to the specific folders, prevent the files being read or changed by the processes.\r\n\r\n"; + + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show(information, "File access rights", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + + private void listView_ProcessFileAccessRights_SelectedIndexChanged(object sender, EventArgs e) + { + if (listView_ProcessFileAccessRights.SelectedItems.Count > 0) + { + currentFileAccessRight = (FileAccessRight)listView_ProcessFileAccessRights.SelectedItems[0].Tag; + textBox_FileMask.Text = currentFileAccessRight.FileNameMask; + textBox_AccessFlag.Text = currentFileAccessRight.AccessFlag.ToString(); + SetCheckBoxValue(); + } + } + } +} diff --git a/Demo_Source_Code/CSharpDemo/ProcessMon/ProcessFileAccessRights.resx b/Demo_Source_Code/CSharpDemo/ProcessMon/ProcessFileAccessRights.resx new file mode 100644 index 0000000..0c9478a --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/ProcessMon/ProcessFileAccessRights.resx @@ -0,0 +1,1847 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + 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 + qJ73+c18/Xp5VJ9fl/P5y6LcpupvP3RkTF7d3T6A8xcBAARGAACBEQBAYAQAEBgBAARGAACB/Q//xIY7 + IGrejgAAAABJRU5ErkJggigAAACAAAAAAAEAAAEAIAAAAAAAAAABABMLAAATCwAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAG2QkHBtkJBwbZCQcG2QkHB1nJqkdZyapHWcmqR1nJqkcZybnHGcm5xxnJuccZybn + HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/ + HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/ + HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/ + HGcm/xxnJv8cZyb/GFoh/xhaIf8YWiH/GFoh/xZSHv8WUh7/FlIe/xZSHv8XUx//F1Mf/xdTH/8XUx// + F1Qf/xdUH/8XVB//F1Qf/xdUH/8XVB//F1Qf/xdUH/8XViD/F1Yg/xdWIP8XViD/F1Yg/xdWIP8XViD/ + F1Yg/xhXIP8YVyD/GFcg/xhXIP8YWCD/GFgg/xhYIP8YWCD/GFkh/xhZIf8YWSH/GFkh/xhaIf8YWiH/ + GFoh/xhaIf8ZWiH/GVoh/xlaIf8ZWiH/GFwi6RhcIukYXCLpGFwi6RpcIq8aXCKvGlwirxpcIq8ZWiEf + GVohHxlaIR8ZWiEfAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbZCQcG2QkHBtkJBwbZCQc + HWcmqR1nJqkdZyapHWcmqRxnJuccZybnHGcm5xxnJuccZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/ + HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/ + HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/ + HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8YWiH/GFoh/xhaIf8YWiH/ + FlIe/xZSHv8WUh7/FlIe/xdTH/8XUx//F1Mf/xdTH/8XVB//F1Qf/xdUH/8XVB//F1Qf/xdUH/8XVB// + F1Qf/xdWIP8XViD/F1Yg/xdWIP8XViD/F1Yg/xdWIP8XViD/GFcg/xhXIP8YVyD/GFcg/xhYIP8YWCD/ + GFgg/xhYIP8YWSH/GFkh/xhZIf8YWSH/GFoh/xhaIf8YWiH/GFoh/xlaIf8ZWiH/GVoh/xlaIf8YXCLp + GFwi6RhcIukYXCLpGlwirxpcIq8aXCKvGlwirxlaIR8ZWiEfGVohHxlaIR8AAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAABtkJBwbZCQcG2QkHBtkJBwdZyapHWcmqR1nJqkdZyapHGcm5xxnJuccZybn + HGcm5xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/ + HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/ + HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/ + HGcm/xxnJv8cZyb/HGcm/xhaIf8YWiH/GFoh/xhaIf8WUh7/FlIe/xZSHv8WUh7/F1Mf/xdTH/8XUx// + F1Mf/xdUH/8XVB//F1Qf/xdUH/8XVB//F1Qf/xdUH/8XVB//F1Yg/xdWIP8XViD/F1Yg/xdWIP8XViD/ + F1Yg/xdWIP8YVyD/GFcg/xhXIP8YVyD/GFgg/xhYIP8YWCD/GFgg/xhZIf8YWSH/GFkh/xhZIf8YWiH/ + GFoh/xhaIf8YWiH/GVoh/xlaIf8ZWiH/GVoh/xhcIukYXCLpGFwi6RhcIukaXCKvGlwirxpcIq8aXCKv + GVohHxlaIR8ZWiEfGVohHwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAG2QkHBtkJBwbZCQc + G2QkHB1nJqkdZyapHWcmqR1nJqkcZybnHGcm5xxnJuccZybnHGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/ + HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/ + HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/ + HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/GFoh/xhaIf8YWiH/ + GFoh/xZSHv8WUh7/FlIe/xZSHv8XUx//F1Mf/xdTH/8XUx//F1Qf/xdUH/8XVB//F1Qf/xdUH/8XVB// + F1Qf/xdUH/8XViD/F1Yg/xdWIP8XViD/F1Yg/xdWIP8XViD/F1Yg/xhXIP8YVyD/GFcg/xhXIP8YWCD/ + GFgg/xhYIP8YWCD/GFkh/xhZIf8YWSH/GFkh/xhaIf8YWiH/GFoh/xhaIf8ZWiH/GVoh/xlaIf8ZWiH/ + GFwi6RhcIukYXCLpGFwi6RpcIq8aXCKvGlwirxpcIq8ZWiEfGVohHxlaIR8ZWiEfAAAAAAAAAAAAAAAA + AAAAABtkJBwbZCQcG2QkHBtkJBwdaCftHWgn7R1oJ+0daCftHWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/xlaIv8ZWiL/GVoi/xlaIv8XUR7/F1Ee/xdRHv8XUR7/F1If/xdSH/8XUh//F1If/xdTH/8XUx// + F1Mf/xdTH/8XVB//F1Qf/xdUH/8XVB//GFQg/xhUIP8YVCD/GFQg/xhVIP8YVSD/GFUg/xhVIP8YViD/ + GFYg/xhWIP8YViD/GFch/xhXIf8YVyH/GFch/xlYIf8ZWCH/GVgh/xlYIf8ZWSH/GVkh/xlZIf8ZWSH/ + GVoi/xlaIv8ZWiL/GVoi/xlbIv8ZWyL/GVsi/xlbIv8ZWyL/GVsi/xlbIv8ZWyL/Glwj/xpcI/8aXCP/ + Glwj/xpdIu8aXSLvGl0i7xpdIu8ZWiEfGVohHxlaIR8ZWiEfG2QkHBtkJBwbZCQcG2QkHB1oJ+0daCft + HWgn7R1oJ+0daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/GVoi/xlaIv8ZWiL/GVoi/xdRHv8XUR7/ + F1Ee/xdRHv8XUh//F1If/xdSH/8XUh//F1Mf/xdTH/8XUx//F1Mf/xdUH/8XVB//F1Qf/xdUH/8YVCD/ + GFQg/xhUIP8YVCD/GFUg/xhVIP8YVSD/GFUg/xhWIP8YViD/GFYg/xhWIP8YVyH/GFch/xhXIf8YVyH/ + GVgh/xlYIf8ZWCH/GVgh/xlZIf8ZWSH/GVkh/xlZIf8ZWiL/GVoi/xlaIv8ZWiL/GVsi/xlbIv8ZWyL/ + GVsi/xlbIv8ZWyL/GVsi/xlbIv8aXCP/Glwj/xpcI/8aXCP/Gl0i7xpdIu8aXSLvGl0i7xlaIR8ZWiEf + GVohHxlaIR8bZCQcG2QkHBtkJBwbZCQcHWgn7R1oJ+0daCftHWgn7R1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8ZWiL/GVoi/xlaIv8ZWiL/F1Ee/xdRHv8XUR7/F1Ee/xdSH/8XUh//F1If/xdSH/8XUx// + F1Mf/xdTH/8XUx//F1Qf/xdUH/8XVB//F1Qf/xhUIP8YVCD/GFQg/xhUIP8YVSD/GFUg/xhVIP8YVSD/ + GFYg/xhWIP8YViD/GFYg/xhXIf8YVyH/GFch/xhXIf8ZWCH/GVgh/xlYIf8ZWCH/GVkh/xlZIf8ZWSH/ + GVkh/xlaIv8ZWiL/GVoi/xlaIv8ZWyL/GVsi/xlbIv8ZWyL/GVsi/xlbIv8ZWyL/GVsi/xpcI/8aXCP/ + Glwj/xpcI/8aXSLvGl0i7xpdIu8aXSLvGVohHxlaIR8ZWiEfGVohHxtkJBwbZCQcG2QkHBtkJBwdaCft + HWgn7R1oJ+0daCftHWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/xlaIv8ZWiL/GVoi/xlaIv8XUR7/ + F1Ee/xdRHv8XUR7/F1If/xdSH/8XUh//F1If/xdTH/8XUx//F1Mf/xdTH/8XVB//F1Qf/xdUH/8XVB// + GFQg/xhUIP8YVCD/GFQg/xhVIP8YVSD/GFUg/xhVIP8YViD/GFYg/xhWIP8YViD/GFch/xhXIf8YVyH/ + GFch/xlYIf8ZWCH/GVgh/xlYIf8ZWSH/GVkh/xlZIf8ZWSH/GVoi/xlaIv8ZWiL/GVoi/xlbIv8ZWyL/ + GVsi/xlbIv8ZWyL/GVsi/xlbIv8ZWyL/Glwj/xpcI/8aXCP/Glwj/xpdIu8aXSLvGl0i7xpdIu8ZWiEf + GVohHxlaIR8ZWiEfHmopqR5qKakeaimpHmopqR5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8aWyL/ + Glsi/xpbIv8aWyL/F1Ef/xdRH/8XUR//F1Ef/xdSH/8XUh//F1If/xdSH/8XUx//F1Mf/xdTH/8XUx// + GFQg/xhUIP8YVCD/GFQg/xhUIP8YVCD/GFQg/xhUIP8YVSD/GFUg/xhVIP8YVSD/GFYg/xhWIP8YViD/ + GFYg/xlXIf8ZVyH/GVch/xlXIf8ZWCH/GVgh/xlYIf8ZWCH/GVki/xlZIv8ZWSL/GVki/xlaIv8ZWiL/ + GVoi/xlaIv8aWyL/Glsi/xpbIv8aWyL/Glsj/xpbI/8aWyP/Glsj/xpcI/8aXCP/Glwj/xpcI/8aXSP/ + Gl0j/xpdI/8aXSP/G14j/xteI/8bXiP/G14j/xxfJK8cXySvHF8krxxfJK8eaimpHmopqR5qKakeaimp + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/xpbIv8aWyL/Glsi/xpbIv8XUR//F1Ef/xdRH/8XUR// + F1If/xdSH/8XUh//F1If/xdTH/8XUx//F1Mf/xdTH/8YVCD/GFQg/xhUIP8YVCD/GFQg/xhUIP8YVCD/ + GFQg/xhVIP8YVSD/GFUg/xhVIP8YViD/GFYg/xhWIP8YViD/GVch/xlXIf8ZVyH/GVch/xlYIf8ZWCH/ + GVgh/xlYIf8ZWSL/GVki/xlZIv8ZWSL/GVoi/xlaIv8ZWiL/GVoi/xpbIv8aWyL/Glsi/xpbIv8aWyP/ + Glsj/xpbI/8aWyP/Glwj/xpcI/8aXCP/Glwj/xpdI/8aXSP/Gl0j/xpdI/8bXiP/G14j/xteI/8bXiP/ + HF8krxxfJK8cXySvHF8krx5qKakeaimpHmopqR5qKakeaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Glsi/xpbIv8aWyL/Glsi/xdRH/8XUR//F1Ef/xdRH/8XUh//F1If/xdSH/8XUh//F1Mf/xdTH/8XUx// + F1Mf/xhUIP8YVCD/GFQg/xhUIP8YVCD/GFQg/xhUIP8YVCD/GFUg/xhVIP8YVSD/GFUg/xhWIP8YViD/ + GFYg/xhWIP8ZVyH/GVch/xlXIf8ZVyH/GVgh/xlYIf8ZWCH/GVgh/xlZIv8ZWSL/GVki/xlZIv8ZWiL/ + GVoi/xlaIv8ZWiL/Glsi/xpbIv8aWyL/Glsi/xpbI/8aWyP/Glsj/xpbI/8aXCP/Glwj/xpcI/8aXCP/ + Gl0j/xpdI/8aXSP/Gl0j/xteI/8bXiP/G14j/xteI/8cXySvHF8krxxfJK8cXySvHmopqR5qKakeaimp + HmopqR5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8aWyL/Glsi/xpbIv8aWyL/F1Ef/xdRH/8XUR// + F1Ef/xdSH/8XUh//F1If/xdSH/8XUx//F1Mf/xdTH/8XUx//GFQg/xhUIP8YVCD/GFQg/xhUIP8YVCD/ + GFQg/xhUIP8YVSD/GFUg/xhVIP8YVSD/GFYg/xhWIP8YViD/GFYg/xlXIf8ZVyH/GVch/xlXIf8ZWCH/ + GVgh/xlYIf8ZWCH/GVki/xlZIv8ZWSL/GVki/xlaIv8ZWiL/GVoi/xlaIv8aWyL/Glsi/xpbIv8aWyL/ + Glsj/xpbI/8aWyP/Glsj/xpcI/8aXCP/Glwj/xpcI/8aXSP/Gl0j/xpdI/8aXSP/G14j/xteI/8bXiP/ + G14j/xxfJK8cXySvHF8krxxfJK8fayroH2sq6B9rKugfayroH2sq/x9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/Glsk/xpbJP8aWyT/ + Glsk/xdQH/8XUB//F1Af/xdQH/8eaWD/Hmlg/x5pYP8eaWD/Hmpg/x5qYP8eamD/Hmpg/xhTIP8YUyD/ + GFMg/xhTIP8YVCH/GFQh/xhUIf8YVCH/GFQh/xhUIf8YVCH/GFQh/xlVIf8ZVSH/GVUh/xlVIf8ZViL/ + GVYi/xlWIv8ZViL/GVci/xlXIv8ZVyL/GVci/xlYIv8ZWCL/GVgi/xlYIv8aWSP/Glkj/xpZI/8aWSP/ + Gloj/xpaI/8aWiP/Gloj/xpbJP8aWyT/Glsk/xpbJP8bWyT/G1sk/xtbJP8bWyT/G1wk/xtcJP8bXCT/ + G1wk/xtdJf8bXSX/G10l/xtdJf8bXiX/G14l/xteJf8bXiX/G18l6RtfJekbXyXpG18l6R9rKugfayro + H2sq6B9rKugfayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8aWyT/Glsk/xpbJP8aWyT/F1Af/xdQH/8XUB//F1Af/x5pYP8eaWD/ + Hmlg/x5pYP8eamD/Hmpg/x5qYP8eamD/GFMg/xhTIP8YUyD/GFMg/xhUIf8YVCH/GFQh/xhUIf8YVCH/ + GFQh/xhUIf8YVCH/GVUh/xlVIf8ZVSH/GVUh/xlWIv8ZViL/GVYi/xlWIv8ZVyL/GVci/xlXIv8ZVyL/ + GVgi/xlYIv8ZWCL/GVgi/xpZI/8aWSP/Glkj/xpZI/8aWiP/Gloj/xpaI/8aWiP/Glsk/xpbJP8aWyT/ + Glsk/xtbJP8bWyT/G1sk/xtbJP8bXCT/G1wk/xtcJP8bXCT/G10l/xtdJf8bXSX/G10l/xteJf8bXiX/ + G14l/xteJf8bXyXpG18l6RtfJekbXyXpH2sq6B9rKugfayroH2sq6B9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/xpbJP8aWyT/ + Glsk/xpbJP8XUB//F1Af/xdQH/8XUB//Hmlg/x5pYP8eaWD/Hmlg/x5qYP8eamD/Hmpg/x5qYP8YUyD/ + GFMg/xhTIP8YUyD/GFQh/xhUIf8YVCH/GFQh/xhUIf8YVCH/GFQh/xhUIf8ZVSH/GVUh/xlVIf8ZVSH/ + GVYi/xlWIv8ZViL/GVYi/xlXIv8ZVyL/GVci/xlXIv8ZWCL/GVgi/xlYIv8ZWCL/Glkj/xpZI/8aWSP/ + Glkj/xpaI/8aWiP/Gloj/xpaI/8aWyT/Glsk/xpbJP8aWyT/G1sk/xtbJP8bWyT/G1sk/xtcJP8bXCT/ + G1wk/xtcJP8bXSX/G10l/xtdJf8bXSX/G14l/xteJf8bXiX/G14l/xtfJekbXyXpG18l6RtfJekfayro + H2sq6B9rKugfayroH2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/Glsk/xpbJP8aWyT/Glsk/xdQH/8XUB//F1Af/xdQH/8eaWD/ + Hmlg/x5pYP8eaWD/Hmpg/x5qYP8eamD/Hmpg/xhTIP8YUyD/GFMg/xhTIP8YVCH/GFQh/xhUIf8YVCH/ + GFQh/xhUIf8YVCH/GFQh/xlVIf8ZVSH/GVUh/xlVIf8ZViL/GVYi/xlWIv8ZViL/GVci/xlXIv8ZVyL/ + GVci/xlYIv8ZWCL/GVgi/xlYIv8aWSP/Glkj/xpZI/8aWSP/Gloj/xpaI/8aWiP/Gloj/xpbJP8aWyT/ + Glsk/xpbJP8bWyT/G1sk/xtbJP8bWyT/G1wk/xtcJP8bXCT/G1wk/xtdJf8bXSX/G10l/xtdJf8bXiX/ + G14l/xteJf8bXiX/G18l6RtfJekbXyXpG18l6SBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/xtbJP8bWyT/G1sk/xtbJP8eaFr/ + Hmha/x5oWv8eaFr/JYKy/yWCsv8lgrL/JYKy/ymT3/8pk9//KZPf/ymT3/8pk9//KZPf/ymT3/8pk9// + JYKu/yWCrv8lgq7/JYKu/x5nVP8eZ1T/HmdU/x5nVP8ZVSL/GVUi/xlVIv8ZVSL/GVYi/xlWIv8ZViL/ + GVYi/xlXIv8ZVyL/GVci/xlXIv8aWCP/Glgj/xpYI/8aWCP/Glgj/xpYI/8aWCP/Glgj/xpZI/8aWSP/ + Glkj/xpZI/8bWyT/G1sk/xtbJP8bWyT/G1sk/xtbJP8bWyT/G1sk/xtcJP8bXCT/G1wk/xtcJP8bXSX/ + G10l/xtdJf8bXSX/HF4l/xxeJf8cXiX/HF4l/xxfJf8cXyX/HF8l/xxfJf8cYCb/HGAm/xxgJv8cYCb/ + IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/G1sk/xtbJP8bWyT/G1sk/x5oWv8eaFr/Hmha/x5oWv8lgrL/JYKy/yWCsv8lgrL/ + KZPf/ymT3/8pk9//KZPf/ymT3/8pk9//KZPf/ymT3/8lgq7/JYKu/yWCrv8lgq7/HmdU/x5nVP8eZ1T/ + HmdU/xlVIv8ZVSL/GVUi/xlVIv8ZViL/GVYi/xlWIv8ZViL/GVci/xlXIv8ZVyL/GVci/xpYI/8aWCP/ + Glgj/xpYI/8aWCP/Glgj/xpYI/8aWCP/Glkj/xpZI/8aWSP/Glkj/xtbJP8bWyT/G1sk/xtbJP8bWyT/ + G1sk/xtbJP8bWyT/G1wk/xtcJP8bXCT/G1wk/xtdJf8bXSX/G10l/xtdJf8cXiX/HF4l/xxeJf8cXiX/ + HF8l/xxfJf8cXyX/HF8l/xxgJv8cYCb/HGAm/xxgJv8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8bWyT/G1sk/xtbJP8bWyT/ + Hmha/x5oWv8eaFr/Hmha/yWCsv8lgrL/JYKy/yWCsv8pk9//KZPf/ymT3/8pk9//KZPf/ymT3/8pk9// + KZPf/yWCrv8lgq7/JYKu/yWCrv8eZ1T/HmdU/x5nVP8eZ1T/GVUi/xlVIv8ZVSL/GVUi/xlWIv8ZViL/ + GVYi/xlWIv8ZVyL/GVci/xlXIv8ZVyL/Glgj/xpYI/8aWCP/Glgj/xpYI/8aWCP/Glgj/xpYI/8aWSP/ + Glkj/xpZI/8aWSP/G1sk/xtbJP8bWyT/G1sk/xtbJP8bWyT/G1sk/xtbJP8bXCT/G1wk/xtcJP8bXCT/ + G10l/xtdJf8bXSX/G10l/xxeJf8cXiX/HF4l/xxeJf8cXyX/HF8l/xxfJf8cXyX/HGAm/xxgJv8cYCb/ + HGAm/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/IG0r/xtbJP8bWyT/G1sk/xtbJP8eaFr/Hmha/x5oWv8eaFr/JYKy/yWCsv8lgrL/ + JYKy/ymT3/8pk9//KZPf/ymT3/8pk9//KZPf/ymT3/8pk9//JYKu/yWCrv8lgq7/JYKu/x5nVP8eZ1T/ + HmdU/x5nVP8ZVSL/GVUi/xlVIv8ZVSL/GVYi/xlWIv8ZViL/GVYi/xlXIv8ZVyL/GVci/xlXIv8aWCP/ + Glgj/xpYI/8aWCP/Glgj/xpYI/8aWCP/Glgj/xpZI/8aWSP/Glkj/xpZI/8bWyT/G1sk/xtbJP8bWyT/ + G1sk/xtbJP8bWyT/G1sk/xtcJP8bXCT/G1wk/xtcJP8bXSX/G10l/xtdJf8bXSX/HF4l/xxeJf8cXiX/ + HF4l/xxfJf8cXyX/HF8l/xxfJf8cYCb/HGAm/xxgJv8cYCb/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8dZUD/HWVA/x1lQP8dZUD/JIGn/ySBp/8kgaf/ + JIGn/ymU3/8plN//KZTf/ymU3/8upPf/LqT3/y6k9/8upPf/L6j9/y+o/f8vqP3/L6j9/y+o/f8vqP3/ + L6j9/y+o/f8upPf/LqT3/y6k9/8upPf/KZTf/ymU3/8plN//KZTf/ySApf8kgKX/JICl/ySApf8cYkL/ + HGJC/xxiQv8cYkL/GVcj/xlXI/8ZVyP/GVcj/xlYJP8ZWCT/GVgk/xlYJP8aWCT/Glgk/xpYJP8aWCT/ + Glkl/xpZJf8aWSX/Glkl/xpaJf8aWiX/Glol/xpaJf8bWyX/G1sl/xtbJf8bWyX/G1wm/xtcJv8bXCb/ + G1wm/xtdJv8bXSb/G10m/xtdJv8bXib/G14m/xteJv8bXib/HF8n/xxfJ/8cXyf/HF8n/xxgJ/8cYCf/ + HGAn/xxgJ/8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/x1lQP8dZUD/HWVA/x1lQP8kgaf/JIGn/ySBp/8kgaf/KZTf/ymU3/8plN//KZTf/y6k9/8upPf/ + LqT3/y6k9/8vqP3/L6j9/y+o/f8vqP3/L6j9/y+o/f8vqP3/L6j9/y6k9/8upPf/LqT3/y6k9/8plN// + KZTf/ymU3/8plN//JICl/ySApf8kgKX/JICl/xxiQv8cYkL/HGJC/xxiQv8ZVyP/GVcj/xlXI/8ZVyP/ + GVgk/xlYJP8ZWCT/GVgk/xpYJP8aWCT/Glgk/xpYJP8aWSX/Glkl/xpZJf8aWSX/Glol/xpaJf8aWiX/ + Glol/xtbJf8bWyX/G1sl/xtbJf8bXCb/G1wm/xtcJv8bXCb/G10m/xtdJv8bXSb/G10m/xteJv8bXib/ + G14m/xteJv8cXyf/HF8n/xxfJ/8cXyf/HGAn/xxgJ/8cYCf/HGAn/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/HWVA/x1lQP8dZUD/HWVA/ySBp/8kgaf/ + JIGn/ySBp/8plN//KZTf/ymU3/8plN//LqT3/y6k9/8upPf/LqT3/y+o/f8vqP3/L6j9/y+o/f8vqP3/ + L6j9/y+o/f8vqP3/LqT3/y6k9/8upPf/LqT3/ymU3/8plN//KZTf/ymU3/8kgKX/JICl/ySApf8kgKX/ + HGJC/xxiQv8cYkL/HGJC/xlXI/8ZVyP/GVcj/xlXI/8ZWCT/GVgk/xlYJP8ZWCT/Glgk/xpYJP8aWCT/ + Glgk/xpZJf8aWSX/Glkl/xpZJf8aWiX/Glol/xpaJf8aWiX/G1sl/xtbJf8bWyX/G1sl/xtcJv8bXCb/ + G1wm/xtcJv8bXSb/G10m/xtdJv8bXSb/G14m/xteJv8bXib/G14m/xxfJ/8cXyf/HF8n/xxfJ/8cYCf/ + HGAn/xxgJ/8cYCf/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/yBuLf8dZUD/HWVA/x1lQP8dZUD/JIGn/ySBp/8kgaf/JIGn/ymU3/8plN//KZTf/ymU3/8upPf/ + LqT3/y6k9/8upPf/L6j9/y+o/f8vqP3/L6j9/y+o/f8vqP3/L6j9/y+o/f8upPf/LqT3/y6k9/8upPf/ + KZTf/ymU3/8plN//KZTf/ySApf8kgKX/JICl/ySApf8cYkL/HGJC/xxiQv8cYkL/GVcj/xlXI/8ZVyP/ + GVcj/xlYJP8ZWCT/GVgk/xlYJP8aWCT/Glgk/xpYJP8aWCT/Glkl/xpZJf8aWSX/Glkl/xpaJf8aWiX/ + Glol/xpaJf8bWyX/G1sl/xtbJf8bWyX/G1wm/xtcJv8bXCb/G1wm/xtdJv8bXSb/G10m/xtdJv8bXib/ + G14m/xteJv8bXib/HF8n/xxfJ/8cXyf/HF8n/xxgJ/8cYCf/HGAn/xxgJ/8hcC7/IXAu/yFwLv8hcC7/ + IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/ + IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/ + IXAu/yFwLv8hcS//IXEv/yFxL/8hcS//JHx+/yR8fv8kfH7/JHx+/ymR1P8pkdT/KZHU/ymR1P8vpfb/ + L6X2/y+l9v8vpfb/MKn8/zCp/P8wqfz/MKn8/yybzf8sm83/LJvN/yybzf8gblr/IG5a/yBuWv8gblr/ + IGxY/yBsWP8gbFj/IGxY/yyazP8smsz/LJrM/yyazP8wqfz/MKn8/zCp/P8wqfz/L6X2/y+l9v8vpfb/ + L6X2/yqR1P8qkdT/KpHU/yqR1P8gdHH/IHRx/yB0cf8gdHH/Glgk/xpYJP8aWCT/Glgk/xpZJf8aWSX/ + Glkl/xpZJf8bWiX/G1ol/xtaJf8bWiX/G1sl/xtbJf8bWyX/G1sl/xtcJv8bXCb/G1wm/xtcJv8bXSb/ + G10m/xtdJv8bXSb/HF4n/xxeJ/8cXif/HF4n/xxfJ/8cXyf/HF8n/xxfJ/8cYCf/HGAn/xxgJ/8cYCf/ + HGEo/xxhKP8cYSj/HGEo/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/ + IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/ + IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFxL/8hcS//IXEv/yFxL/8kfH7/ + JHx+/yR8fv8kfH7/KZHU/ymR1P8pkdT/KZHU/y+l9v8vpfb/L6X2/y+l9v8wqfz/MKn8/zCp/P8wqfz/ + LJvN/yybzf8sm83/LJvN/yBuWv8gblr/IG5a/yBuWv8gbFj/IGxY/yBsWP8gbFj/LJrM/yyazP8smsz/ + LJrM/zCp/P8wqfz/MKn8/zCp/P8vpfb/L6X2/y+l9v8vpfb/KpHU/yqR1P8qkdT/KpHU/yB0cf8gdHH/ + IHRx/yB0cf8aWCT/Glgk/xpYJP8aWCT/Glkl/xpZJf8aWSX/Glkl/xtaJf8bWiX/G1ol/xtaJf8bWyX/ + G1sl/xtbJf8bWyX/G1wm/xtcJv8bXCb/G1wm/xtdJv8bXSb/G10m/xtdJv8cXif/HF4n/xxeJ/8cXif/ + HF8n/xxfJ/8cXyf/HF8n/xxgJ/8cYCf/HGAn/xxgJ/8cYSj/HGEo/xxhKP8cYSj/IXAu/yFwLv8hcC7/ + IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/ + IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/ + IXAu/yFwLv8hcC7/IXEv/yFxL/8hcS//IXEv/yR8fv8kfH7/JHx+/yR8fv8pkdT/KZHU/ymR1P8pkdT/ + L6X2/y+l9v8vpfb/L6X2/zCp/P8wqfz/MKn8/zCp/P8sm83/LJvN/yybzf8sm83/IG5a/yBuWv8gblr/ + IG5a/yBsWP8gbFj/IGxY/yBsWP8smsz/LJrM/yyazP8smsz/MKn8/zCp/P8wqfz/MKn8/y+l9v8vpfb/ + L6X2/y+l9v8qkdT/KpHU/yqR1P8qkdT/IHRx/yB0cf8gdHH/IHRx/xpYJP8aWCT/Glgk/xpYJP8aWSX/ + Glkl/xpZJf8aWSX/G1ol/xtaJf8bWiX/G1ol/xtbJf8bWyX/G1sl/xtbJf8bXCb/G1wm/xtcJv8bXCb/ + G10m/xtdJv8bXSb/G10m/xxeJ/8cXif/HF4n/xxeJ/8cXyf/HF8n/xxfJ/8cXyf/HGAn/xxgJ/8cYCf/ + HGAn/xxhKP8cYSj/HGEo/xxhKP8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/ + IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/ + IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcS//IXEv/yFxL/8hcS// + JHx+/yR8fv8kfH7/JHx+/ymR1P8pkdT/KZHU/ymR1P8vpfb/L6X2/y+l9v8vpfb/MKn8/zCp/P8wqfz/ + MKn8/yybzf8sm83/LJvN/yybzf8gblr/IG5a/yBuWv8gblr/IGxY/yBsWP8gbFj/IGxY/yyazP8smsz/ + LJrM/yyazP8wqfz/MKn8/zCp/P8wqfz/L6X2/y+l9v8vpfb/L6X2/yqR1P8qkdT/KpHU/yqR1P8gdHH/ + IHRx/yB0cf8gdHH/Glgk/xpYJP8aWCT/Glgk/xpZJf8aWSX/Glkl/xpZJf8bWiX/G1ol/xtaJf8bWiX/ + G1sl/xtbJf8bWyX/G1sl/xtcJv8bXCb/G1wm/xtcJv8bXSb/G10m/xtdJv8bXSb/HF4n/xxeJ/8cXif/ + HF4n/xxfJ/8cXyf/HF8n/xxfJ/8cYCf/HGAn/xxgJ/8cYCf/HGEo/xxhKP8cYSj/HGEo/yJxL/8icS// + InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS// + InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS// + I3Q7/yN0O/8jdDv/I3Q7/yeHqv8nh6r/J4eq/yeHqv8tn+z/LZ/s/y2f7P8tn+z/MKr8/zCq/P8wqvz/ + MKr8/y6f2P8un9j/Lp/Y/y6f2P8hcmb/IXJm/yFyZv8hcmb/GFEi/xhRIv8YUSL/GFEi/xlSIv8ZUiL/ + GVIi/xlSIv8ZUyL/GVMi/xlTIv8ZUyL/GVQj/xlUI/8ZVCP/GVQj/yJ0Z/8idGf/InRn/yJ0Z/8un9j/ + Lp/Y/y6f2P8un9j/MKr8/zCq/P8wqvz/MKr8/y2f7P8tn+z/LZ/s/y2f7P8lhKP/JYSj/yWEo/8lhKP/ + HF4z/xxeM/8cXjP/HF4z/xtaJf8bWiX/G1ol/xtaJf8bWyb/G1sm/xtbJv8bWyb/HFwm/xxcJv8cXCb/ + HFwm/xxdJ/8cXSf/HF0n/xxdJ/8cXif/HF4n/xxeJ/8cXif/HV8n/x1fJ/8dXyf/HV8n/x1gKP8dYCj/ + HWAo/x1gKP8dYSj/HWEo/x1hKP8dYSj/InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS// + InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS// + InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8jdDv/I3Q7/yN0O/8jdDv/J4eq/yeHqv8nh6r/ + J4eq/y2f7P8tn+z/LZ/s/y2f7P8wqvz/MKr8/zCq/P8wqvz/Lp/Y/y6f2P8un9j/Lp/Y/yFyZv8hcmb/ + IXJm/yFyZv8YUSL/GFEi/xhRIv8YUSL/GVIi/xlSIv8ZUiL/GVIi/xlTIv8ZUyL/GVMi/xlTIv8ZVCP/ + GVQj/xlUI/8ZVCP/InRn/yJ0Z/8idGf/InRn/y6f2P8un9j/Lp/Y/y6f2P8wqvz/MKr8/zCq/P8wqvz/ + LZ/s/y2f7P8tn+z/LZ/s/yWEo/8lhKP/JYSj/yWEo/8cXjP/HF4z/xxeM/8cXjP/G1ol/xtaJf8bWiX/ + G1ol/xtbJv8bWyb/G1sm/xtbJv8cXCb/HFwm/xxcJv8cXCb/HF0n/xxdJ/8cXSf/HF0n/xxeJ/8cXif/ + HF4n/xxeJ/8dXyf/HV8n/x1fJ/8dXyf/HWAo/x1gKP8dYCj/HWAo/x1hKP8dYSj/HWEo/x1hKP8icS// + InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS// + InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS// + InEv/yN0O/8jdDv/I3Q7/yN0O/8nh6r/J4eq/yeHqv8nh6r/LZ/s/y2f7P8tn+z/LZ/s/zCq/P8wqvz/ + MKr8/zCq/P8un9j/Lp/Y/y6f2P8un9j/IXJm/yFyZv8hcmb/IXJm/xhRIv8YUSL/GFEi/xhRIv8ZUiL/ + GVIi/xlSIv8ZUiL/GVMi/xlTIv8ZUyL/GVMi/xlUI/8ZVCP/GVQj/xlUI/8idGf/InRn/yJ0Z/8idGf/ + Lp/Y/y6f2P8un9j/Lp/Y/zCq/P8wqvz/MKr8/zCq/P8tn+z/LZ/s/y2f7P8tn+z/JYSj/yWEo/8lhKP/ + JYSj/xxeM/8cXjP/HF4z/xxeM/8bWiX/G1ol/xtaJf8bWiX/G1sm/xtbJv8bWyb/G1sm/xxcJv8cXCb/ + HFwm/xxcJv8cXSf/HF0n/xxdJ/8cXSf/HF4n/xxeJ/8cXif/HF4n/x1fJ/8dXyf/HV8n/x1fJ/8dYCj/ + HWAo/x1gKP8dYCj/HWEo/x1hKP8dYSj/HWEo/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS// + InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS// + InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//I3Q7/yN0O/8jdDv/I3Q7/yeHqv8nh6r/ + J4eq/yeHqv8tn+z/LZ/s/y2f7P8tn+z/MKr8/zCq/P8wqvz/MKr8/y6f2P8un9j/Lp/Y/y6f2P8hcmb/ + IXJm/yFyZv8hcmb/GFEi/xhRIv8YUSL/GFEi/xlSIv8ZUiL/GVIi/xlSIv8ZUyL/GVMi/xlTIv8ZUyL/ + GVQj/xlUI/8ZVCP/GVQj/yJ0Z/8idGf/InRn/yJ0Z/8un9j/Lp/Y/y6f2P8un9j/MKr8/zCq/P8wqvz/ + MKr8/y2f7P8tn+z/LZ/s/y2f7P8lhKP/JYSj/yWEo/8lhKP/HF4z/xxeM/8cXjP/HF4z/xtaJf8bWiX/ + G1ol/xtaJf8bWyb/G1sm/xtbJv8bWyb/HFwm/xxcJv8cXCb/HFwm/xxdJ/8cXSf/HF0n/xxdJ/8cXif/ + HF4n/xxeJ/8cXif/HV8n/x1fJ/8dXyf/HV8n/x1gKP8dYCj/HWAo/x1gKP8dYSj/HWEo/x1hKP8dYSj/ + LHg6/yx4Ov8seDr/LHg6/yVzM/8lczP/JXMz/yVzM/8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/ + I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yR0PP8kdDz/ + JHQ8/yR0PP8pj73/KY+9/ymPvf8pj73/MKn5/zCp+f8wqfn/MKn5/zCo9P8wqPT/MKj0/zCo9P8mgYn/ + JoGJ/yaBif8mgYn/GVAl/xlQJf8ZUCX/GVAl/xhQIv8YUCL/GFAi/xhQIv8ZUCP/GVAj/xlQI/8ZUCP/ + GVIj/xlSI/8ZUiP/GVIj/xlTJP8ZUyT/GVMk/xlTJP8aVCT/GlQk/xpUJP8aVCT/GlQk/xpUJP8aVCT/ + GlQk/xtXKP8bVyj/G1co/xtXKP8nhY3/J4WN/yeFjf8nhY3/MKr2/zCq9v8wqvb/MKr2/zCp+f8wqfn/ + MKn5/zCp+f8pjr3/KY69/ymOvf8pjr3/HV8z/x1fM/8dXzP/HV8z/xxbJ/8cWyf/HFsn/xxbJ/8cXCf/ + HFwn/xxcJ/8cXCf/HF0o/xxdKP8cXSj/HF0o/x1dKP8dXSj/HV0o/x1dKP8dXyn/HV8p/x1fKf8dXyn/ + HWAp/x1gKf8dYCn/HWAp/x5hKv8eYSr/HmEq/x5hKv8seDr/LHg6/yx4Ov8seDr/JXMz/yVzM/8lczP/ + JXMz/yNyMf8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/ + I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/JHQ8/yR0PP8kdDz/JHQ8/ymPvf8pj73/KY+9/ymPvf8wqfn/ + MKn5/zCp+f8wqfn/MKj0/zCo9P8wqPT/MKj0/yaBif8mgYn/JoGJ/yaBif8ZUCX/GVAl/xlQJf8ZUCX/ + GFAi/xhQIv8YUCL/GFAi/xlQI/8ZUCP/GVAj/xlQI/8ZUiP/GVIj/xlSI/8ZUiP/GVMk/xlTJP8ZUyT/ + GVMk/xpUJP8aVCT/GlQk/xpUJP8aVCT/GlQk/xpUJP8aVCT/G1co/xtXKP8bVyj/G1co/yeFjf8nhY3/ + J4WN/yeFjf8wqvb/MKr2/zCq9v8wqvb/MKn5/zCp+f8wqfn/MKn5/ymOvf8pjr3/KY69/ymOvf8dXzP/ + HV8z/x1fM/8dXzP/HFsn/xxbJ/8cWyf/HFsn/xxcJ/8cXCf/HFwn/xxcJ/8cXSj/HF0o/xxdKP8cXSj/ + HV0o/x1dKP8dXSj/HV0o/x1fKf8dXyn/HV8p/x1fKf8dYCn/HWAp/x1gKf8dYCn/HmEq/x5hKv8eYSr/ + HmEq/yx4Ov8seDr/LHg6/yx4Ov8lczP/JXMz/yVzM/8lczP/I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/ + I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yNyMf8kdDz/ + JHQ8/yR0PP8kdDz/KY+9/ymPvf8pj73/KY+9/zCp+f8wqfn/MKn5/zCp+f8wqPT/MKj0/zCo9P8wqPT/ + JoGJ/yaBif8mgYn/JoGJ/xlQJf8ZUCX/GVAl/xlQJf8YUCL/GFAi/xhQIv8YUCL/GVAj/xlQI/8ZUCP/ + GVAj/xlSI/8ZUiP/GVIj/xlSI/8ZUyT/GVMk/xlTJP8ZUyT/GlQk/xpUJP8aVCT/GlQk/xpUJP8aVCT/ + GlQk/xpUJP8bVyj/G1co/xtXKP8bVyj/J4WN/yeFjf8nhY3/J4WN/zCq9v8wqvb/MKr2/zCq9v8wqfn/ + MKn5/zCp+f8wqfn/KY69/ymOvf8pjr3/KY69/x1fM/8dXzP/HV8z/x1fM/8cWyf/HFsn/xxbJ/8cWyf/ + HFwn/xxcJ/8cXCf/HFwn/xxdKP8cXSj/HF0o/xxdKP8dXSj/HV0o/x1dKP8dXSj/HV8p/x1fKf8dXyn/ + HV8p/x1gKf8dYCn/HWAp/x1gKf8eYSr/HmEq/x5hKv8eYSr/LHg6/yx4Ov8seDr/LHg6/yVzM/8lczP/ + JXMz/yVzM/8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/ + I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yR0PP8kdDz/JHQ8/yR0PP8pj73/KY+9/ymPvf8pj73/ + MKn5/zCp+f8wqfn/MKn5/zCo9P8wqPT/MKj0/zCo9P8mgYn/JoGJ/yaBif8mgYn/GVAl/xlQJf8ZUCX/ + GVAl/xhQIv8YUCL/GFAi/xhQIv8ZUCP/GVAj/xlQI/8ZUCP/GVIj/xlSI/8ZUiP/GVIj/xlTJP8ZUyT/ + GVMk/xlTJP8aVCT/GlQk/xpUJP8aVCT/GlQk/xpUJP8aVCT/GlQk/xtXKP8bVyj/G1co/xtXKP8nhY3/ + J4WN/yeFjf8nhY3/MKr2/zCq9v8wqvb/MKr2/zCp+f8wqfn/MKn5/zCp+f8pjr3/KY69/ymOvf8pjr3/ + HV8z/x1fM/8dXzP/HV8z/xxbJ/8cWyf/HFsn/xxbJ/8cXCf/HFwn/xxcJ/8cXCf/HF0o/xxdKP8cXSj/ + HF0o/x1dKP8dXSj/HV0o/x1dKP8dXyn/HV8p/x1fKf8dXyn/HWAp/x1gKf8dYCn/HWAp/x5hKv8eYSr/ + HmEq/x5hKv9SkV3/UpFd/1KRXf9SkV3/UpFd/1KRXf9SkV3/UpFd/0mLVf9Ji1X/SYtV/0mLVf8+hEr/ + PoRK/z6ESv8+hEr/M35A/zN+QP8zfkD/M35A/yh3Nv8odzb/KHc2/yh3Nv8kdjv/JHY7/yR2O/8kdjv/ + KpPA/yqTwP8qk8D/KpPA/zGr+/8xq/v/Mav7/zGr+/8unc3/Lp3N/y6dzf8unc3/HWBC/x1gQv8dYEL/ + HWBC/xhOIv8YTiL/GE4i/xhOIv8ZTyL/GU8i/xlPIv8ZTyL/GVAj/xlQI/8ZUCP/GVAj/xlRI/8ZUSP/ + GVEj/xlRI/8ZUiP/GVIj/xlSI/8ZUiP/GlMk/xpTJP8aUyT/GlMk/xpUJP8aVCT/GlQk/xpUJP8aVSX/ + GlUl/xpVJf8aVSX/G1Yl/xtWJf8bViX/G1Yl/xtXJf8bVyX/G1cl/xtXJf8gaEn/IGhJ/yBoSf8gaEn/ + LqDT/y6g0/8uoNP/LqDT/zGr+/8xq/v/Mav7/zGr+/8qk8D/KpPA/yqTwP8qk8D/HmAy/x5gMv8eYDL/ + HmAy/x1cKP8dXCj/HVwo/x1cKP8dXSj/HV0o/x1dKP8dXSj/HV4p/x1eKf8dXin/HV4p/x5fKf8eXyn/ + Hl8p/x5fKf8eYCr/HmAq/x5gKv8eYCr/HmEq/x5hKv8eYSr/HmEq/1KRXf9SkV3/UpFd/1KRXf9SkV3/ + UpFd/1KRXf9SkV3/SYtV/0mLVf9Ji1X/SYtV/z6ESv8+hEr/PoRK/z6ESv8zfkD/M35A/zN+QP8zfkD/ + KHc2/yh3Nv8odzb/KHc2/yR2O/8kdjv/JHY7/yR2O/8qk8D/KpPA/yqTwP8qk8D/Mav7/zGr+/8xq/v/ + Mav7/y6dzf8unc3/Lp3N/y6dzf8dYEL/HWBC/x1gQv8dYEL/GE4i/xhOIv8YTiL/GE4i/xlPIv8ZTyL/ + GU8i/xlPIv8ZUCP/GVAj/xlQI/8ZUCP/GVEj/xlRI/8ZUSP/GVEj/xlSI/8ZUiP/GVIj/xlSI/8aUyT/ + GlMk/xpTJP8aUyT/GlQk/xpUJP8aVCT/GlQk/xpVJf8aVSX/GlUl/xpVJf8bViX/G1Yl/xtWJf8bViX/ + G1cl/xtXJf8bVyX/G1cl/yBoSf8gaEn/IGhJ/yBoSf8uoNP/LqDT/y6g0/8uoNP/Mav7/zGr+/8xq/v/ + Mav7/yqTwP8qk8D/KpPA/yqTwP8eYDL/HmAy/x5gMv8eYDL/HVwo/x1cKP8dXCj/HVwo/x1dKP8dXSj/ + HV0o/x1dKP8dXin/HV4p/x1eKf8dXin/Hl8p/x5fKf8eXyn/Hl8p/x5gKv8eYCr/HmAq/x5gKv8eYSr/ + HmEq/x5hKv8eYSr/UpFd/1KRXf9SkV3/UpFd/1KRXf9SkV3/UpFd/1KRXf9Ji1X/SYtV/0mLVf9Ji1X/ + PoRK/z6ESv8+hEr/PoRK/zN+QP8zfkD/M35A/zN+QP8odzb/KHc2/yh3Nv8odzb/JHY7/yR2O/8kdjv/ + JHY7/yqTwP8qk8D/KpPA/yqTwP8xq/v/Mav7/zGr+/8xq/v/Lp3N/y6dzf8unc3/Lp3N/x1gQv8dYEL/ + HWBC/x1gQv8YTiL/GE4i/xhOIv8YTiL/GU8i/xlPIv8ZTyL/GU8i/xlQI/8ZUCP/GVAj/xlQI/8ZUSP/ + GVEj/xlRI/8ZUSP/GVIj/xlSI/8ZUiP/GVIj/xpTJP8aUyT/GlMk/xpTJP8aVCT/GlQk/xpUJP8aVCT/ + GlUl/xpVJf8aVSX/GlUl/xtWJf8bViX/G1Yl/xtWJf8bVyX/G1cl/xtXJf8bVyX/IGhJ/yBoSf8gaEn/ + IGhJ/y6g0/8uoNP/LqDT/y6g0/8xq/v/Mav7/zGr+/8xq/v/KpPA/yqTwP8qk8D/KpPA/x5gMv8eYDL/ + HmAy/x5gMv8dXCj/HVwo/x1cKP8dXCj/HV0o/x1dKP8dXSj/HV0o/x1eKf8dXin/HV4p/x1eKf8eXyn/ + Hl8p/x5fKf8eXyn/HmAq/x5gKv8eYCr/HmAq/x5hKv8eYSr/HmEq/x5hKv9SkV3/UpFd/1KRXf9SkV3/ + UpFd/1KRXf9SkV3/UpFd/0mLVf9Ji1X/SYtV/0mLVf8+hEr/PoRK/z6ESv8+hEr/M35A/zN+QP8zfkD/ + M35A/yh3Nv8odzb/KHc2/yh3Nv8kdjv/JHY7/yR2O/8kdjv/KpPA/yqTwP8qk8D/KpPA/zGr+/8xq/v/ + Mav7/zGr+/8unc3/Lp3N/y6dzf8unc3/HWBC/x1gQv8dYEL/HWBC/xhOIv8YTiL/GE4i/xhOIv8ZTyL/ + GU8i/xlPIv8ZTyL/GVAj/xlQI/8ZUCP/GVAj/xlRI/8ZUSP/GVEj/xlRI/8ZUiP/GVIj/xlSI/8ZUiP/ + GlMk/xpTJP8aUyT/GlMk/xpUJP8aVCT/GlQk/xpUJP8aVSX/GlUl/xpVJf8aVSX/G1Yl/xtWJf8bViX/ + G1Yl/xtXJf8bVyX/G1cl/xtXJf8gaEn/IGhJ/yBoSf8gaEn/LqDT/y6g0/8uoNP/LqDT/zGr+/8xq/v/ + Mav7/zGr+/8qk8D/KpPA/yqTwP8qk8D/HmAy/x5gMv8eYDL/HmAy/x1cKP8dXCj/HVwo/x1cKP8dXSj/ + HV0o/x1dKP8dXSj/HV4p/x1eKf8dXin/HV4p/x5fKf8eXyn/Hl8p/x5fKf8eYCr/HmAq/x5gKv8eYCr/ + HmEq/x5hKv8eYSr/HmEq/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/ + VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1Smuf9Uprn/ + VKa5/1Smuf9Jtvv/Sbb7/0m2+/9Jtvv/NZy9/zWcvf81nL3/NZy9/1l9Xf9ZfV3/WX1d/1l9Xf9ig2L/ + YoNi/2KDYv9ig2L/Y4Ni/2ODYv9jg2L/Y4Ni/2OEYv9jhGL/Y4Ri/2OEYv9jhWL/Y4Vi/2OFYv9jhWL/ + Y4Vi/2OFYv9jhWL/Y4Vi/2OGY/9jhmP/Y4Zj/2OGY/9jh2P/Y4dj/2OHY/9jh2P/ZIdk/2SHZP9kh2T/ + ZIdk/2SIZP9kiGT/ZIhk/2SIZP9kiWT/ZIlk/2SJZP9kiWT/ZIlk/2SJZP9kiWT/ZIlk/2WKZP9limT/ + ZYpk/2WKZP9ahWL/WoVi/1qFYv9ahWL/MJvC/zCbwv8wm8L/MJvC/zKt+/8yrfv/Mq37/zKt+/8qkKn/ + KpCp/yqQqf8qkKn/HVwo/x1cKP8dXCj/HVwo/x1dKf8dXSn/HV0p/x1dKf8eXin/Hl4p/x5eKf8eXin/ + Hl8p/x5fKf8eXyn/Hl8p/x5gKv8eYCr/HmAq/x5gKv8fYiv/H2Ir/x9iK/8fYiv/VpRh/1aUYf9WlGH/ + VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/ + VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VKa5/1Smuf9Uprn/VKa5/0m2+/9Jtvv/Sbb7/0m2+/81nL3/ + NZy9/zWcvf81nL3/WX1d/1l9Xf9ZfV3/WX1d/2KDYv9ig2L/YoNi/2KDYv9jg2L/Y4Ni/2ODYv9jg2L/ + Y4Ri/2OEYv9jhGL/Y4Ri/2OFYv9jhWL/Y4Vi/2OFYv9jhWL/Y4Vi/2OFYv9jhWL/Y4Zj/2OGY/9jhmP/ + Y4Zj/2OHY/9jh2P/Y4dj/2OHY/9kh2T/ZIdk/2SHZP9kh2T/ZIhk/2SIZP9kiGT/ZIhk/2SJZP9kiWT/ + ZIlk/2SJZP9kiWT/ZIlk/2SJZP9kiWT/ZYpk/2WKZP9limT/ZYpk/1qFYv9ahWL/WoVi/1qFYv8wm8L/ + MJvC/zCbwv8wm8L/Mq37/zKt+/8yrfv/Mq37/yqQqf8qkKn/KpCp/yqQqf8dXCj/HVwo/x1cKP8dXCj/ + HV0p/x1dKf8dXSn/HV0p/x5eKf8eXin/Hl4p/x5eKf8eXyn/Hl8p/x5fKf8eXyn/HmAq/x5gKv8eYCr/ + HmAq/x9iK/8fYiv/H2Ir/x9iK/9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/ + VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9Uprn/ + VKa5/1Smuf9Uprn/Sbb7/0m2+/9Jtvv/Sbb7/zWcvf81nL3/NZy9/zWcvf9ZfV3/WX1d/1l9Xf9ZfV3/ + YoNi/2KDYv9ig2L/YoNi/2ODYv9jg2L/Y4Ni/2ODYv9jhGL/Y4Ri/2OEYv9jhGL/Y4Vi/2OFYv9jhWL/ + Y4Vi/2OFYv9jhWL/Y4Vi/2OFYv9jhmP/Y4Zj/2OGY/9jhmP/Y4dj/2OHY/9jh2P/Y4dj/2SHZP9kh2T/ + ZIdk/2SHZP9kiGT/ZIhk/2SIZP9kiGT/ZIlk/2SJZP9kiWT/ZIlk/2SJZP9kiWT/ZIlk/2SJZP9limT/ + ZYpk/2WKZP9limT/WoVi/1qFYv9ahWL/WoVi/zCbwv8wm8L/MJvC/zCbwv8yrfv/Mq37/zKt+/8yrfv/ + KpCp/yqQqf8qkKn/KpCp/x1cKP8dXCj/HVwo/x1cKP8dXSn/HV0p/x1dKf8dXSn/Hl4p/x5eKf8eXin/ + Hl4p/x5fKf8eXyn/Hl8p/x5fKf8eYCr/HmAq/x5gKv8eYCr/H2Ir/x9iK/8fYiv/H2Ir/1aUYf9WlGH/ + VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/ + VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1Smuf9Uprn/VKa5/1Smuf9Jtvv/Sbb7/0m2+/9Jtvv/ + NZy9/zWcvf81nL3/NZy9/1l9Xf9ZfV3/WX1d/1l9Xf9ig2L/YoNi/2KDYv9ig2L/Y4Ni/2ODYv9jg2L/ + Y4Ni/2OEYv9jhGL/Y4Ri/2OEYv9jhWL/Y4Vi/2OFYv9jhWL/Y4Vi/2OFYv9jhWL/Y4Vi/2OGY/9jhmP/ + Y4Zj/2OGY/9jh2P/Y4dj/2OHY/9jh2P/ZIdk/2SHZP9kh2T/ZIdk/2SIZP9kiGT/ZIhk/2SIZP9kiWT/ + ZIlk/2SJZP9kiWT/ZIlk/2SJZP9kiWT/ZIlk/2WKZP9limT/ZYpk/2WKZP9ahWL/WoVi/1qFYv9ahWL/ + MJvC/zCbwv8wm8L/MJvC/zKt+/8yrfv/Mq37/zKt+/8qkKn/KpCp/yqQqf8qkKn/HVwo/x1cKP8dXCj/ + HVwo/x1dKf8dXSn/HV0p/x1dKf8eXin/Hl4p/x5eKf8eXin/Hl8p/x5fKf8eXyn/Hl8p/x5gKv8eYCr/ + HmAq/x5gKv8fYiv/H2Ir/x9iK/8fYiv/WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/ + WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/WJdl/1iXZf9bn4j/W5+I/1ufiP9bn4j/ + YsD6/2LA+v9iwPr/YsD6/16xzf9esc3/XrHN/16xzf/O1Mb/ztTG/87Uxv/O1Mb/19nN/9fZzf/X2c3/ + 19nN/8TKuv/Eyrr/xMq6/8TKuv+/xrT/v8a0/7/GtP+/xrT/v8az/7/Gs/+/xrP/v8az/7/Gs/+/xrP/ + v8az/7/Gs/+/xrP/v8az/7/Gs/+/xrP/v8e0/7/HtP+/x7T/v8e0/7/HtP+/x7T/v8e0/7/HtP+/x7T/ + v8e0/7/HtP+/x7T/v8e0/7/HtP+/x7T/v8e0/7/ItP+/yLT/v8i0/7/ItP+/yLT/v8i0/7/ItP+/yLT/ + v8i0/7/ItP+/yLT/v8i0/83Swv/N0sL/zdLC/83Swv++ybb/vsm2/77Jtv++ybb/Lp3D/y6dw/8uncP/ + Lp3D/zKt+v8yrfr/Mq36/zKt+v8jdV7/I3Ve/yN1Xv8jdV7/HV4q/x1eKv8dXir/HV4q/x1fKv8dXyr/ + HV8q/x1fKv8eYCv/HmAr/x5gK/8eYCv/HmEr/x5hK/8eYSv/HmEr/x5iLP8eYiz/HmIs/x5iLP9Yl2X/ + WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/ + WJdl/1iXZf9Yl2X/WJdl/1ufiP9bn4j/W5+I/1ufiP9iwPr/YsD6/2LA+v9iwPr/XrHN/16xzf9esc3/ + XrHN/87Uxv/O1Mb/ztTG/87Uxv/X2c3/19nN/9fZzf/X2c3/xMq6/8TKuv/Eyrr/xMq6/7/GtP+/xrT/ + v8a0/7/GtP+/xrP/v8az/7/Gs/+/xrP/v8az/7/Gs/+/xrP/v8az/7/Gs/+/xrP/v8az/7/Gs/+/x7T/ + v8e0/7/HtP+/x7T/v8e0/7/HtP+/x7T/v8e0/7/HtP+/x7T/v8e0/7/HtP+/x7T/v8e0/7/HtP+/x7T/ + v8i0/7/ItP+/yLT/v8i0/7/ItP+/yLT/v8i0/7/ItP+/yLT/v8i0/7/ItP+/yLT/zdLC/83Swv/N0sL/ + zdLC/77Jtv++ybb/vsm2/77Jtv8uncP/Lp3D/y6dw/8uncP/Mq36/zKt+v8yrfr/Mq36/yN1Xv8jdV7/ + I3Ve/yN1Xv8dXir/HV4q/x1eKv8dXir/HV8q/x1fKv8dXyr/HV8q/x5gK/8eYCv/HmAr/x5gK/8eYSv/ + HmEr/x5hK/8eYSv/HmIs/x5iLP8eYiz/HmIs/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/ + WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/W5+I/1ufiP9bn4j/ + W5+I/2LA+v9iwPr/YsD6/2LA+v9esc3/XrHN/16xzf9esc3/ztTG/87Uxv/O1Mb/ztTG/9fZzf/X2c3/ + 19nN/9fZzf/Eyrr/xMq6/8TKuv/Eyrr/v8a0/7/GtP+/xrT/v8a0/7/Gs/+/xrP/v8az/7/Gs/+/xrP/ + v8az/7/Gs/+/xrP/v8az/7/Gs/+/xrP/v8az/7/HtP+/x7T/v8e0/7/HtP+/x7T/v8e0/7/HtP+/x7T/ + v8e0/7/HtP+/x7T/v8e0/7/HtP+/x7T/v8e0/7/HtP+/yLT/v8i0/7/ItP+/yLT/v8i0/7/ItP+/yLT/ + v8i0/7/ItP+/yLT/v8i0/7/ItP/N0sL/zdLC/83Swv/N0sL/vsm2/77Jtv++ybb/vsm2/y6dw/8uncP/ + Lp3D/y6dw/8yrfr/Mq36/zKt+v8yrfr/I3Ve/yN1Xv8jdV7/I3Ve/x1eKv8dXir/HV4q/x1eKv8dXyr/ + HV8q/x1fKv8dXyr/HmAr/x5gK/8eYCv/HmAr/x5hK/8eYSv/HmEr/x5hK/8eYiz/HmIs/x5iLP8eYiz/ + WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/ + WJdl/1iXZf9Yl2X/WJdl/1iXZf9bn4j/W5+I/1ufiP9bn4j/YsD6/2LA+v9iwPr/YsD6/16xzf9esc3/ + XrHN/16xzf/O1Mb/ztTG/87Uxv/O1Mb/19nN/9fZzf/X2c3/19nN/8TKuv/Eyrr/xMq6/8TKuv+/xrT/ + v8a0/7/GtP+/xrT/v8az/7/Gs/+/xrP/v8az/7/Gs/+/xrP/v8az/7/Gs/+/xrP/v8az/7/Gs/+/xrP/ + v8e0/7/HtP+/x7T/v8e0/7/HtP+/x7T/v8e0/7/HtP+/x7T/v8e0/7/HtP+/x7T/v8e0/7/HtP+/x7T/ + v8e0/7/ItP+/yLT/v8i0/7/ItP+/yLT/v8i0/7/ItP+/yLT/v8i0/7/ItP+/yLT/v8i0/83Swv/N0sL/ + zdLC/83Swv++ybb/vsm2/77Jtv++ybb/Lp3D/y6dw/8uncP/Lp3D/zKt+v8yrfr/Mq36/zKt+v8jdV7/ + I3Ve/yN1Xv8jdV7/HV4q/x1eKv8dXir/HV4q/x1fKv8dXyr/HV8q/x1fKv8eYCv/HmAr/x5gK/8eYCv/ + HmEr/x5hK/8eYSv/HmEr/x5iLP8eYiz/HmIs/x5iLP9cmmj/XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/ + XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/XJpo/2W73/9lu9// + Zbvf/2W73/9lv+3/Zb/t/2W/7f9lv+3/VIBm/1SAZv9UgGb/VIBm//v07f/79O3/+/Tt//v07f9fgmT/ + X4Jk/1+CZP9fgmT/Unpa/1J6Wv9Selr/Unpa/1B4WP9QeFj/UHhY/1B4WP88akX/PGpF/zxqRf88akX/ + IFUr/yBVK/8gVSv/IFUr/xpRJP8aUST/GlEk/xpRJP8nWzH/J1sx/ydbMf8nWzH/J1wx/ydcMf8nXDH/ + J1wx/xtUJv8bVCb/G1Qm/xtUJv8bVSb/G1Um/xtVJv8bVSb/G1Yn/xtWJ/8bVif/G1Yn/xxXJ/8cVyf/ + HFcn/xxXJ/8cWCj/HFgo/xxYKP8cWCj/LGQ1/yxkNf8sZDX/LGQ1//nw5//58Of/+fDn//nw5/8gZT7/ + IGU+/yBlPv8gZT7/Mqrr/zKq6/8yquv/Mqrr/zGk1/8xpNf/MaTX/zGk1/8eXir/Hl4q/x5eKv8eXir/ + Hl8r/x5fK/8eXyv/Hl8r/x5gK/8eYCv/HmAr/x5gK/8fYCv/H2Ar/x9gK/8fYCv/H2Is/x9iLP8fYiz/ + H2Is/1yaaP9cmmj/XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/ + XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/Zbvf/2W73/9lu9//Zbvf/2W/7f9lv+3/Zb/t/2W/7f9UgGb/ + VIBm/1SAZv9UgGb/+/Tt//v07f/79O3/+/Tt/1+CZP9fgmT/X4Jk/1+CZP9Selr/Unpa/1J6Wv9Selr/ + UHhY/1B4WP9QeFj/UHhY/zxqRf88akX/PGpF/zxqRf8gVSv/IFUr/yBVK/8gVSv/GlEk/xpRJP8aUST/ + GlEk/ydbMf8nWzH/J1sx/ydbMf8nXDH/J1wx/ydcMf8nXDH/G1Qm/xtUJv8bVCb/G1Qm/xtVJv8bVSb/ + G1Um/xtVJv8bVif/G1Yn/xtWJ/8bVif/HFcn/xxXJ/8cVyf/HFcn/xxYKP8cWCj/HFgo/xxYKP8sZDX/ + LGQ1/yxkNf8sZDX/+fDn//nw5//58Of/+fDn/yBlPv8gZT7/IGU+/yBlPv8yquv/Mqrr/zKq6/8yquv/ + MaTX/zGk1/8xpNf/MaTX/x5eKv8eXir/Hl4q/x5eKv8eXyv/Hl8r/x5fK/8eXyv/HmAr/x5gK/8eYCv/ + HmAr/x9gK/8fYCv/H2Ar/x9gK/8fYiz/H2Is/x9iLP8fYiz/XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/ + XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/XJpo/1yaaP9lu9// + Zbvf/2W73/9lu9//Zb/t/2W/7f9lv+3/Zb/t/1SAZv9UgGb/VIBm/1SAZv/79O3/+/Tt//v07f/79O3/ + X4Jk/1+CZP9fgmT/X4Jk/1J6Wv9Selr/Unpa/1J6Wv9QeFj/UHhY/1B4WP9QeFj/PGpF/zxqRf88akX/ + PGpF/yBVK/8gVSv/IFUr/yBVK/8aUST/GlEk/xpRJP8aUST/J1sx/ydbMf8nWzH/J1sx/ydcMf8nXDH/ + J1wx/ydcMf8bVCb/G1Qm/xtUJv8bVCb/G1Um/xtVJv8bVSb/G1Um/xtWJ/8bVif/G1Yn/xtWJ/8cVyf/ + HFcn/xxXJ/8cVyf/HFgo/xxYKP8cWCj/HFgo/yxkNf8sZDX/LGQ1/yxkNf/58Of/+fDn//nw5//58Of/ + IGU+/yBlPv8gZT7/IGU+/zKq6/8yquv/Mqrr/zKq6/8xpNf/MaTX/zGk1/8xpNf/Hl4q/x5eKv8eXir/ + Hl4q/x5fK/8eXyv/Hl8r/x5fK/8eYCv/HmAr/x5gK/8eYCv/H2Ar/x9gK/8fYCv/H2Ar/x9iLP8fYiz/ + H2Is/x9iLP9cmmj/XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/ + XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/XJpo/2W73/9lu9//Zbvf/2W73/9lv+3/Zb/t/2W/7f9lv+3/ + VIBm/1SAZv9UgGb/VIBm//v07f/79O3/+/Tt//v07f9fgmT/X4Jk/1+CZP9fgmT/Unpa/1J6Wv9Selr/ + Unpa/1B4WP9QeFj/UHhY/1B4WP88akX/PGpF/zxqRf88akX/IFUr/yBVK/8gVSv/IFUr/xpRJP8aUST/ + GlEk/xpRJP8nWzH/J1sx/ydbMf8nWzH/J1wx/ydcMf8nXDH/J1wx/xtUJv8bVCb/G1Qm/xtUJv8bVSb/ + G1Um/xtVJv8bVSb/G1Yn/xtWJ/8bVif/G1Yn/xxXJ/8cVyf/HFcn/xxXJ/8cWCj/HFgo/xxYKP8cWCj/ + LGQ1/yxkNf8sZDX/LGQ1//nw5//58Of/+fDn//nw5/8gZT7/IGU+/yBlPv8gZT7/Mqrr/zKq6/8yquv/ + Mqrr/zGk1/8xpNf/MaTX/zGk1/8eXir/Hl4q/x5eKv8eXir/Hl8r/x5fK/8eXyv/Hl8r/x5gK/8eYCv/ + HmAr/x5gK/8fYCv/H2Ar/x9gK/8fYCv/H2Is/x9iLP8fYiz/H2Is/2CdbP9gnWz/YJ1s/2CdbP9gnWz/ + YJ1s/2CdbP9gnWz/YJ1s/2CdbP9gnWz/YJ1s/2CdbP9gnWz/YJ1s/2CdbP9ho4P/YaOD/2Gjg/9ho4P/ + acX8/2nF/P9pxfz/acX8/2Cgof9goKH/YKCh/2Cgof9Velz/VXpc/1V6XP9Velz/+/Xw//v18P/79fD/ + +/Xw/1+DZv9fg2b/X4Nm/1+DZv9VfV7/VX1e/1V9Xv9VfV7/VX1e/1V9Xv9VfV7/VX1e/1V9Xv9VfV7/ + VX1e/1V9Xv9UfV3/VH1d/1R9Xf9UfV3/PGtF/zxrRf88a0X/PGtF/5Cnjv+Qp47/kKeO/5Cnjv+Ppoz/ + j6aM/4+mjP+Ppoz/G1Qn/xtUJ/8bVCf/G1Qn/xtVJ/8bVSf/G1Un/xtVJ/8cVij/HFYo/xxWKP8cVij/ + HFgo/xxYKP8cWCj/HFgo/xxZKf8cWSn/HFkp/xxZKf8rYjX/K2I1/ytiNf8rYjX/+vLq//ry6v/68ur/ + +vLq/x1bKv8dWyr/HVsq/x1bKv8piIf/KYiH/ymIh/8piIf/M7D7/zOw+/8zsPv/M7D7/yNwUP8jcFD/ + I3BQ/yNwUP8eXyz/Hl8s/x5fLP8eXyz/H2As/x9gLP8fYCz/H2As/x9hLf8fYS3/H2Et/x9hLf8gYy3/ + IGMt/yBjLf8gYy3/YJ1s/2CdbP9gnWz/YJ1s/2CdbP9gnWz/YJ1s/2CdbP9gnWz/YJ1s/2CdbP9gnWz/ + YJ1s/2CdbP9gnWz/YJ1s/2Gjg/9ho4P/YaOD/2Gjg/9pxfz/acX8/2nF/P9pxfz/YKCh/2Cgof9goKH/ + YKCh/1V6XP9Velz/VXpc/1V6XP/79fD/+/Xw//v18P/79fD/X4Nm/1+DZv9fg2b/X4Nm/1V9Xv9VfV7/ + VX1e/1V9Xv9VfV7/VX1e/1V9Xv9VfV7/VX1e/1V9Xv9VfV7/VX1e/1R9Xf9UfV3/VH1d/1R9Xf88a0X/ + PGtF/zxrRf88a0X/kKeO/5Cnjv+Qp47/kKeO/4+mjP+Ppoz/j6aM/4+mjP8bVCf/G1Qn/xtUJ/8bVCf/ + G1Un/xtVJ/8bVSf/G1Un/xxWKP8cVij/HFYo/xxWKP8cWCj/HFgo/xxYKP8cWCj/HFkp/xxZKf8cWSn/ + HFkp/ytiNf8rYjX/K2I1/ytiNf/68ur/+vLq//ry6v/68ur/HVsq/x1bKv8dWyr/HVsq/ymIh/8piIf/ + KYiH/ymIh/8zsPv/M7D7/zOw+/8zsPv/I3BQ/yNwUP8jcFD/I3BQ/x5fLP8eXyz/Hl8s/x5fLP8fYCz/ + H2As/x9gLP8fYCz/H2Et/x9hLf8fYS3/H2Et/yBjLf8gYy3/IGMt/yBjLf9gnWz/YJ1s/2CdbP9gnWz/ + YJ1s/2CdbP9gnWz/YJ1s/2CdbP9gnWz/YJ1s/2CdbP9gnWz/YJ1s/2CdbP9gnWz/YaOD/2Gjg/9ho4P/ + YaOD/2nF/P9pxfz/acX8/2nF/P9goKH/YKCh/2Cgof9goKH/VXpc/1V6XP9Velz/VXpc//v18P/79fD/ + +/Xw//v18P9fg2b/X4Nm/1+DZv9fg2b/VX1e/1V9Xv9VfV7/VX1e/1V9Xv9VfV7/VX1e/1V9Xv9VfV7/ + VX1e/1V9Xv9VfV7/VH1d/1R9Xf9UfV3/VH1d/zxrRf88a0X/PGtF/zxrRf+Qp47/kKeO/5Cnjv+Qp47/ + j6aM/4+mjP+Ppoz/j6aM/xtUJ/8bVCf/G1Qn/xtUJ/8bVSf/G1Un/xtVJ/8bVSf/HFYo/xxWKP8cVij/ + HFYo/xxYKP8cWCj/HFgo/xxYKP8cWSn/HFkp/xxZKf8cWSn/K2I1/ytiNf8rYjX/K2I1//ry6v/68ur/ + +vLq//ry6v8dWyr/HVsq/x1bKv8dWyr/KYiH/ymIh/8piIf/KYiH/zOw+/8zsPv/M7D7/zOw+/8jcFD/ + I3BQ/yNwUP8jcFD/Hl8s/x5fLP8eXyz/Hl8s/x9gLP8fYCz/H2As/x9gLP8fYS3/H2Et/x9hLf8fYS3/ + IGMt/yBjLf8gYy3/IGMt/2CdbP9gnWz/YJ1s/2CdbP9gnWz/YJ1s/2CdbP9gnWz/YJ1s/2CdbP9gnWz/ + YJ1s/2CdbP9gnWz/YJ1s/2CdbP9ho4P/YaOD/2Gjg/9ho4P/acX8/2nF/P9pxfz/acX8/2Cgof9goKH/ + YKCh/2Cgof9Velz/VXpc/1V6XP9Velz/+/Xw//v18P/79fD/+/Xw/1+DZv9fg2b/X4Nm/1+DZv9VfV7/ + VX1e/1V9Xv9VfV7/VX1e/1V9Xv9VfV7/VX1e/1V9Xv9VfV7/VX1e/1V9Xv9UfV3/VH1d/1R9Xf9UfV3/ + PGtF/zxrRf88a0X/PGtF/5Cnjv+Qp47/kKeO/5Cnjv+Ppoz/j6aM/4+mjP+Ppoz/G1Qn/xtUJ/8bVCf/ + G1Qn/xtVJ/8bVSf/G1Un/xtVJ/8cVij/HFYo/xxWKP8cVij/HFgo/xxYKP8cWCj/HFgo/xxZKf8cWSn/ + HFkp/xxZKf8rYjX/K2I1/ytiNf8rYjX/+vLq//ry6v/68ur/+vLq/x1bKv8dWyr/HVsq/x1bKv8piIf/ + KYiH/ymIh/8piIf/M7D7/zOw+/8zsPv/M7D7/yNwUP8jcFD/I3BQ/yNwUP8eXyz/Hl8s/x5fLP8eXyz/ + H2As/x9gLP8fYCz/H2As/x9hLf8fYS3/H2Et/x9hLf8gYy3/IGMt/yBjLf8gYy3/Y59v/2Ofb/9jn2// + Y59v/2Ofb/9jn2//Y59v/2Ofb/9jn2//Y59v/2Ofb/9jn2//Y59v/2Ofb/9jn2//Y59v/2eztP9ns7T/ + Z7O0/2eztP9rxff/a8X3/2vF9/9rxff/WYFq/1mBav9ZgWr/WYFq/1d8X/9XfF//V3xf/1d8X//89vH/ + /Pbx//z28f/89vH/YoRp/2KEaf9ihGn/YoRp/1h+YP9YfmD/WH5g/1h+YP9Yf2D/WH9g/1h/YP9Yf2D/ + WX9h/1l/Yf9Zf2H/WX9h/1mAYf9ZgGH/WYBh/1mAYf9ZgWL/WYFi/1mBYv9ZgWL/r7+t/6+/rf+vv63/ + r7+t/6G0nv+htJ7/obSe/6G0nv8eVir/HlYq/x5WKv8eVir/HFUn/xxVJ/8cVSf/HFUn/xxWKP8cVij/ + HFYo/xxWKP8cVyj/HFco/xxXKP8cVyj/HVgp/x1YKf8dWCn/HVgp/ytiNf8rYjX/K2I1/ytiNf/78+z/ + +/Ps//vz7P/78+z/Hlsq/x5bKv8eWyr/Hlsq/yBmPf8gZj3/IGY9/yBmPf80sPf/NLD3/zSw9/80sPf/ + K5CX/yuQl/8rkJf/K5CX/x9fLP8fXyz/H18s/x9fLP8fYCz/H2As/x9gLP8fYCz/IGEt/yBhLf8gYS3/ + IGEt/yBiLv8gYi7/IGIu/yBiLv9jn2//Y59v/2Ofb/9jn2//Y59v/2Ofb/9jn2//Y59v/2Ofb/9jn2// + Y59v/2Ofb/9jn2//Y59v/2Ofb/9jn2//Z7O0/2eztP9ns7T/Z7O0/2vF9/9rxff/a8X3/2vF9/9ZgWr/ + WYFq/1mBav9ZgWr/V3xf/1d8X/9XfF//V3xf//z28f/89vH//Pbx//z28f9ihGn/YoRp/2KEaf9ihGn/ + WH5g/1h+YP9YfmD/WH5g/1h/YP9Yf2D/WH9g/1h/YP9Zf2H/WX9h/1l/Yf9Zf2H/WYBh/1mAYf9ZgGH/ + WYBh/1mBYv9ZgWL/WYFi/1mBYv+vv63/r7+t/6+/rf+vv63/obSe/6G0nv+htJ7/obSe/x5WKv8eVir/ + HlYq/x5WKv8cVSf/HFUn/xxVJ/8cVSf/HFYo/xxWKP8cVij/HFYo/xxXKP8cVyj/HFco/xxXKP8dWCn/ + HVgp/x1YKf8dWCn/K2I1/ytiNf8rYjX/K2I1//vz7P/78+z/+/Ps//vz7P8eWyr/Hlsq/x5bKv8eWyr/ + IGY9/yBmPf8gZj3/IGY9/zSw9/80sPf/NLD3/zSw9/8rkJf/K5CX/yuQl/8rkJf/H18s/x9fLP8fXyz/ + H18s/x9gLP8fYCz/H2As/x9gLP8gYS3/IGEt/yBhLf8gYS3/IGIu/yBiLv8gYi7/IGIu/2Ofb/9jn2// + Y59v/2Ofb/9jn2//Y59v/2Ofb/9jn2//Y59v/2Ofb/9jn2//Y59v/2Ofb/9jn2//Y59v/2Ofb/9ns7T/ + Z7O0/2eztP9ns7T/a8X3/2vF9/9rxff/a8X3/1mBav9ZgWr/WYFq/1mBav9XfF//V3xf/1d8X/9XfF// + /Pbx//z28f/89vH//Pbx/2KEaf9ihGn/YoRp/2KEaf9YfmD/WH5g/1h+YP9YfmD/WH9g/1h/YP9Yf2D/ + WH9g/1l/Yf9Zf2H/WX9h/1l/Yf9ZgGH/WYBh/1mAYf9ZgGH/WYFi/1mBYv9ZgWL/WYFi/6+/rf+vv63/ + r7+t/6+/rf+htJ7/obSe/6G0nv+htJ7/HlYq/x5WKv8eVir/HlYq/xxVJ/8cVSf/HFUn/xxVJ/8cVij/ + HFYo/xxWKP8cVij/HFco/xxXKP8cVyj/HFco/x1YKf8dWCn/HVgp/x1YKf8rYjX/K2I1/ytiNf8rYjX/ + +/Ps//vz7P/78+z/+/Ps/x5bKv8eWyr/Hlsq/x5bKv8gZj3/IGY9/yBmPf8gZj3/NLD3/zSw9/80sPf/ + NLD3/yuQl/8rkJf/K5CX/yuQl/8fXyz/H18s/x9fLP8fXyz/H2As/x9gLP8fYCz/H2As/yBhLf8gYS3/ + IGEt/yBhLf8gYi7/IGIu/yBiLv8gYi7/Y59v/2Ofb/9jn2//Y59v/2Ofb/9jn2//Y59v/2Ofb/9jn2// + Y59v/2Ofb/9jn2//Y59v/2Ofb/9jn2//Y59v/2eztP9ns7T/Z7O0/2eztP9rxff/a8X3/2vF9/9rxff/ + WYFq/1mBav9ZgWr/WYFq/1d8X/9XfF//V3xf/1d8X//89vH//Pbx//z28f/89vH/YoRp/2KEaf9ihGn/ + YoRp/1h+YP9YfmD/WH5g/1h+YP9Yf2D/WH9g/1h/YP9Yf2D/WX9h/1l/Yf9Zf2H/WX9h/1mAYf9ZgGH/ + WYBh/1mAYf9ZgWL/WYFi/1mBYv9ZgWL/r7+t/6+/rf+vv63/r7+t/6G0nv+htJ7/obSe/6G0nv8eVir/ + HlYq/x5WKv8eVir/HFUn/xxVJ/8cVSf/HFUn/xxWKP8cVij/HFYo/xxWKP8cVyj/HFco/xxXKP8cVyj/ + HVgp/x1YKf8dWCn/HVgp/ytiNf8rYjX/K2I1/ytiNf/78+z/+/Ps//vz7P/78+z/Hlsq/x5bKv8eWyr/ + Hlsq/yBmPf8gZj3/IGY9/yBmPf80sPf/NLD3/zSw9/80sPf/K5CX/yuQl/8rkJf/K5CX/x9fLP8fXyz/ + H18s/x9fLP8fYCz/H2As/x9gLP8fYCz/IGEt/yBhLf8gYS3/IGEt/yBiLv8gYi7/IGIu/yBiLv9no3P/ + Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9no3P/ + bb7X/22+1/9tvtf/bb7X/2y81/9svNf/bLzX/2y81/9bfmL/W35i/1t+Yv9bfmL/W39j/1t/Y/9bf2P/ + W39j//z48//8+PP//Pjz//z48/9mh2z/Zods/2aHbP9mh2z/XIFk/1yBZP9cgWT/XIFk/1yBZP9cgWT/ + XIFk/1yBZP9miG3/Zoht/2aIbf9miG3/sMCv/7DAr/+wwK//sMCv/7LCsf+ywrH/ssKx/7LCsf/Z3tT/ + 2d7U/9ne1P/Z3tT/2d7U/9ne1P/Z3tT/2d7U/6/Arf+vwK3/r8Ct/6/Arf+bspr/m7Ka/5uymv+bspr/ + KV80/ylfNP8pXzT/KV80/x1XKP8dVyj/HVco/x1XKP8dWCn/HVgp/x1YKf8dWCn/K2M2/ytjNv8rYzb/ + K2M2//v17v/79e7/+/Xu//v17v8eXCv/Hlwr/x5cK/8eXCv/Hl0r/x5dK/8eXSv/Hl0r/zGjy/8xo8v/ + MaPL/zGjy/8wosb/MKLG/zCixv8wosb/H2As/x9gLP8fYCz/H2As/yBhLf8gYS3/IGEt/yBhLf8gYi3/ + IGIt/yBiLf8gYi3/IGMu/yBjLv8gYy7/IGMu/2ejc/9no3P/Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9no3P/ + Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9tvtf/bb7X/22+1/9tvtf/bLzX/2y81/9svNf/ + bLzX/1t+Yv9bfmL/W35i/1t+Yv9bf2P/W39j/1t/Y/9bf2P//Pjz//z48//8+PP//Pjz/2aHbP9mh2z/ + Zods/2aHbP9cgWT/XIFk/1yBZP9cgWT/XIFk/1yBZP9cgWT/XIFk/2aIbf9miG3/Zoht/2aIbf+wwK// + sMCv/7DAr/+wwK//ssKx/7LCsf+ywrH/ssKx/9ne1P/Z3tT/2d7U/9ne1P/Z3tT/2d7U/9ne1P/Z3tT/ + r8Ct/6/Arf+vwK3/r8Ct/5uymv+bspr/m7Ka/5uymv8pXzT/KV80/ylfNP8pXzT/HVco/x1XKP8dVyj/ + HVco/x1YKf8dWCn/HVgp/x1YKf8rYzb/K2M2/ytjNv8rYzb/+/Xu//v17v/79e7/+/Xu/x5cK/8eXCv/ + Hlwr/x5cK/8eXSv/Hl0r/x5dK/8eXSv/MaPL/zGjy/8xo8v/MaPL/zCixv8wosb/MKLG/zCixv8fYCz/ + H2As/x9gLP8fYCz/IGEt/yBhLf8gYS3/IGEt/yBiLf8gYi3/IGIt/yBiLf8gYy7/IGMu/yBjLv8gYy7/ + Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9no3P/ + Z6Nz/22+1/9tvtf/bb7X/22+1/9svNf/bLzX/2y81/9svNf/W35i/1t+Yv9bfmL/W35i/1t/Y/9bf2P/ + W39j/1t/Y//8+PP//Pjz//z48//8+PP/Zods/2aHbP9mh2z/Zods/1yBZP9cgWT/XIFk/1yBZP9cgWT/ + XIFk/1yBZP9cgWT/Zoht/2aIbf9miG3/Zoht/7DAr/+wwK//sMCv/7DAr/+ywrH/ssKx/7LCsf+ywrH/ + 2d7U/9ne1P/Z3tT/2d7U/9ne1P/Z3tT/2d7U/9ne1P+vwK3/r8Ct/6/Arf+vwK3/m7Ka/5uymv+bspr/ + m7Ka/ylfNP8pXzT/KV80/ylfNP8dVyj/HVco/x1XKP8dVyj/HVgp/x1YKf8dWCn/HVgp/ytjNv8rYzb/ + K2M2/ytjNv/79e7/+/Xu//v17v/79e7/Hlwr/x5cK/8eXCv/Hlwr/x5dK/8eXSv/Hl0r/x5dK/8xo8v/ + MaPL/zGjy/8xo8v/MKLG/zCixv8wosb/MKLG/x9gLP8fYCz/H2As/x9gLP8gYS3/IGEt/yBhLf8gYS3/ + IGIt/yBiLf8gYi3/IGIt/yBjLv8gYy7/IGMu/yBjLv9no3P/Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9no3P/ + Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9no3P/bb7X/22+1/9tvtf/bb7X/2y81/9svNf/ + bLzX/2y81/9bfmL/W35i/1t+Yv9bfmL/W39j/1t/Y/9bf2P/W39j//z48//8+PP//Pjz//z48/9mh2z/ + Zods/2aHbP9mh2z/XIFk/1yBZP9cgWT/XIFk/1yBZP9cgWT/XIFk/1yBZP9miG3/Zoht/2aIbf9miG3/ + sMCv/7DAr/+wwK//sMCv/7LCsf+ywrH/ssKx/7LCsf/Z3tT/2d7U/9ne1P/Z3tT/2d7U/9ne1P/Z3tT/ + 2d7U/6/Arf+vwK3/r8Ct/6/Arf+bspr/m7Ka/5uymv+bspr/KV80/ylfNP8pXzT/KV80/x1XKP8dVyj/ + HVco/x1XKP8dWCn/HVgp/x1YKf8dWCn/K2M2/ytjNv8rYzb/K2M2//v17v/79e7/+/Xu//v17v8eXCv/ + Hlwr/x5cK/8eXCv/Hl0r/x5dK/8eXSv/Hl0r/zGjy/8xo8v/MaPL/zGjy/8wosb/MKLG/zCixv8wosb/ + H2As/x9gLP8fYCz/H2As/yBhLf8gYS3/IGEt/yBhLf8gYi3/IGIt/yBiLf8gYi3/IGMu/yBjLv8gYy7/ + IGMu/2qld/9qpXf/aqV3/2qld/9qpXf/aqV3/2qld/9qpXf/aqV3/2qld/9qpXf/aqV3/2qld/9qpXf/ + aqV3/2qld/9xxuz/ccbs/3HG7P9xxuz/bLO//2yzv/9ss7//bLO//16AZf9egGX/XoBl/16AZf9egWX/ + XoFl/16BZf9egWX//fn1//359f/9+fX//fn1/2iJb/9oiW//aIlv/2iJb/9eg2f/XoNn/16DZ/9eg2f/ + XoNn/16DZ/9eg2f/XoNn/2iKcP9oinD/aIpw/2iKcP+xwbH/scGx/7HBsf+xwbH/s8Oz/7PDs/+zw7P/ + s8Oz/9vg1v/b4Nb/2+DW/9vg1v/b4Nb/2+DW/9vg1v/b4Nb/tMS0/7TEtP+0xLT/tMS0/7LDsv+yw7L/ + ssOy/7LDsv9Sflz/Un5c/1J+XP9Sflz/IFos/yBaLP8gWiz/IFos/x1YKv8dWCr/HVgq/x1YKv8rYjb/ + K2I2/ytiNv8rYjb//Pbw//z28P/89vD//Pbw/x5bLP8eWyz/Hlss/x5bLP8eXCz/Hlws/x5cLP8eXCz/ + Lpiq/y6Yqv8umKr/Lpiq/zSt5f80reX/NK3l/zSt5f8fXy3/H18t/x9fLf8fXy3/H2Au/x9gLv8fYC7/ + H2Au/yBhLv8gYS7/IGEu/yBhLv8gYy//IGMv/yBjL/8gYy//aqV3/2qld/9qpXf/aqV3/2qld/9qpXf/ + aqV3/2qld/9qpXf/aqV3/2qld/9qpXf/aqV3/2qld/9qpXf/aqV3/3HG7P9xxuz/ccbs/3HG7P9ss7// + bLO//2yzv/9ss7//XoBl/16AZf9egGX/XoBl/16BZf9egWX/XoFl/16BZf/9+fX//fn1//359f/9+fX/ + aIlv/2iJb/9oiW//aIlv/16DZ/9eg2f/XoNn/16DZ/9eg2f/XoNn/16DZ/9eg2f/aIpw/2iKcP9oinD/ + aIpw/7HBsf+xwbH/scGx/7HBsf+zw7P/s8Oz/7PDs/+zw7P/2+DW/9vg1v/b4Nb/2+DW/9vg1v/b4Nb/ + 2+DW/9vg1v+0xLT/tMS0/7TEtP+0xLT/ssOy/7LDsv+yw7L/ssOy/1J+XP9Sflz/Un5c/1J+XP8gWiz/ + IFos/yBaLP8gWiz/HVgq/x1YKv8dWCr/HVgq/ytiNv8rYjb/K2I2/ytiNv/89vD//Pbw//z28P/89vD/ + Hlss/x5bLP8eWyz/Hlss/x5cLP8eXCz/Hlws/x5cLP8umKr/Lpiq/y6Yqv8umKr/NK3l/zSt5f80reX/ + NK3l/x9fLf8fXy3/H18t/x9fLf8fYC7/H2Au/x9gLv8fYC7/IGEu/yBhLv8gYS7/IGEu/yBjL/8gYy// + IGMv/yBjL/9qpXf/aqV3/2qld/9qpXf/aqV3/2qld/9qpXf/aqV3/2qld/9qpXf/aqV3/2qld/9qpXf/ + aqV3/2qld/9qpXf/ccbs/3HG7P9xxuz/ccbs/2yzv/9ss7//bLO//2yzv/9egGX/XoBl/16AZf9egGX/ + XoFl/16BZf9egWX/XoFl//359f/9+fX//fn1//359f9oiW//aIlv/2iJb/9oiW//XoNn/16DZ/9eg2f/ + XoNn/16DZ/9eg2f/XoNn/16DZ/9oinD/aIpw/2iKcP9oinD/scGx/7HBsf+xwbH/scGx/7PDs/+zw7P/ + s8Oz/7PDs//b4Nb/2+DW/9vg1v/b4Nb/2+DW/9vg1v/b4Nb/2+DW/7TEtP+0xLT/tMS0/7TEtP+yw7L/ + ssOy/7LDsv+yw7L/Un5c/1J+XP9Sflz/Un5c/yBaLP8gWiz/IFos/yBaLP8dWCr/HVgq/x1YKv8dWCr/ + K2I2/ytiNv8rYjb/K2I2//z28P/89vD//Pbw//z28P8eWyz/Hlss/x5bLP8eWyz/Hlws/x5cLP8eXCz/ + Hlws/y6Yqv8umKr/Lpiq/y6Yqv80reX/NK3l/zSt5f80reX/H18t/x9fLf8fXy3/H18t/x9gLv8fYC7/ + H2Au/x9gLv8gYS7/IGEu/yBhLv8gYS7/IGMv/yBjL/8gYy//IGMv/2qld/9qpXf/aqV3/2qld/9qpXf/ + aqV3/2qld/9qpXf/aqV3/2qld/9qpXf/aqV3/2qld/9qpXf/aqV3/2qld/9xxuz/ccbs/3HG7P9xxuz/ + bLO//2yzv/9ss7//bLO//16AZf9egGX/XoBl/16AZf9egWX/XoFl/16BZf9egWX//fn1//359f/9+fX/ + /fn1/2iJb/9oiW//aIlv/2iJb/9eg2f/XoNn/16DZ/9eg2f/XoNn/16DZ/9eg2f/XoNn/2iKcP9oinD/ + aIpw/2iKcP+xwbH/scGx/7HBsf+xwbH/s8Oz/7PDs/+zw7P/s8Oz/9vg1v/b4Nb/2+DW/9vg1v/b4Nb/ + 2+DW/9vg1v/b4Nb/tMS0/7TEtP+0xLT/tMS0/7LDsv+yw7L/ssOy/7LDsv9Sflz/Un5c/1J+XP9Sflz/ + IFos/yBaLP8gWiz/IFos/x1YKv8dWCr/HVgq/x1YKv8rYjb/K2I2/ytiNv8rYjb//Pbw//z28P/89vD/ + /Pbw/x5bLP8eWyz/Hlss/x5bLP8eXCz/Hlws/x5cLP8eXCz/Lpiq/y6Yqv8umKr/Lpiq/zSt5f80reX/ + NK3l/zSt5f8fXy3/H18t/x9fLf8fXy3/H2Au/x9gLv8fYC7/H2Au/yBhLv8gYS7/IGEu/yBhLv8gYy// + IGMv/yBjL/8gYy//bah6/22oev9tqHr/bah6/22oev9tqHr/bah6/22oev9tqHr/bah6/22oev9tqHr/ + bal//22pf/9tqX//bal//3TM+/90zPv/dMz7/3TM+/9rqaj/a6mo/2upqP9rqaj/YIJo/2CCaP9ggmj/ + YIJo/2CDaP9gg2j/YINo/2CDaP/9+vb//fr2//369v/9+vb/a4ty/2uLcv9ri3L/a4ty/2GFaf9hhWn/ + YYVp/2GFaf9ihmn/YoZp/2KGaf9ihmn/YoZq/2KGav9ihmr/YoZq/2KHav9ih2r/Yodq/2KHav9jiGv/ + Y4hr/2OIa/9jiGv/tcW1/7XFtf+1xbX/tcW1/7XFtv+1xbb/tcW2/7XFtv9jimv/Y4pr/2OKa/9jimv/ + Y4ps/2OKbP9jimz/Y4ps/2OLbP9ji2z/Y4ts/2OLbP9ahGT/WoRk/1qEZP9ahGT/LGM4/yxjOP8sYzj/ + LGM4/ytiN/8rYjf/K2I3/ytiN//89/L//Pfy//z38v/89/L/Hlws/x5cLP8eXCz/Hlws/x5dLP8eXSz/ + Hl0s/x5dLP8rioj/K4qI/yuKiP8rioj/NbT5/zW0+f81tPn/NbT5/yFkNf8hZDX/IWQ1/yFkNf8gYS7/ + IGEu/yBhLv8gYS7/IGIv/yBiL/8gYi//IGIv/yFjL/8hYy//IWMv/yFjL/9tqHr/bah6/22oev9tqHr/ + bah6/22oev9tqHr/bah6/22oev9tqHr/bah6/22oev9tqX//bal//22pf/9tqX//dMz7/3TM+/90zPv/ + dMz7/2upqP9rqaj/a6mo/2upqP9ggmj/YIJo/2CCaP9ggmj/YINo/2CDaP9gg2j/YINo//369v/9+vb/ + /fr2//369v9ri3L/a4ty/2uLcv9ri3L/YYVp/2GFaf9hhWn/YYVp/2KGaf9ihmn/YoZp/2KGaf9ihmr/ + YoZq/2KGav9ihmr/Yodq/2KHav9ih2r/Yodq/2OIa/9jiGv/Y4hr/2OIa/+1xbX/tcW1/7XFtf+1xbX/ + tcW2/7XFtv+1xbb/tcW2/2OKa/9jimv/Y4pr/2OKa/9jimz/Y4ps/2OKbP9jimz/Y4ts/2OLbP9ji2z/ + Y4ts/1qEZP9ahGT/WoRk/1qEZP8sYzj/LGM4/yxjOP8sYzj/K2I3/ytiN/8rYjf/K2I3//z38v/89/L/ + /Pfy//z38v8eXCz/Hlws/x5cLP8eXCz/Hl0s/x5dLP8eXSz/Hl0s/yuKiP8rioj/K4qI/yuKiP81tPn/ + NbT5/zW0+f81tPn/IWQ1/yFkNf8hZDX/IWQ1/yBhLv8gYS7/IGEu/yBhLv8gYi//IGIv/yBiL/8gYi// + IWMv/yFjL/8hYy//IWMv/22oev9tqHr/bah6/22oev9tqHr/bah6/22oev9tqHr/bah6/22oev9tqHr/ + bah6/22pf/9tqX//bal//22pf/90zPv/dMz7/3TM+/90zPv/a6mo/2upqP9rqaj/a6mo/2CCaP9ggmj/ + YIJo/2CCaP9gg2j/YINo/2CDaP9gg2j//fr2//369v/9+vb//fr2/2uLcv9ri3L/a4ty/2uLcv9hhWn/ + YYVp/2GFaf9hhWn/YoZp/2KGaf9ihmn/YoZp/2KGav9ihmr/YoZq/2KGav9ih2r/Yodq/2KHav9ih2r/ + Y4hr/2OIa/9jiGv/Y4hr/7XFtf+1xbX/tcW1/7XFtf+1xbb/tcW2/7XFtv+1xbb/Y4pr/2OKa/9jimv/ + Y4pr/2OKbP9jimz/Y4ps/2OKbP9ji2z/Y4ts/2OLbP9ji2z/WoRk/1qEZP9ahGT/WoRk/yxjOP8sYzj/ + LGM4/yxjOP8rYjf/K2I3/ytiN/8rYjf//Pfy//z38v/89/L//Pfy/x5cLP8eXCz/Hlws/x5cLP8eXSz/ + Hl0s/x5dLP8eXSz/K4qI/yuKiP8rioj/K4qI/zW0+f81tPn/NbT5/zW0+f8hZDX/IWQ1/yFkNf8hZDX/ + IGEu/yBhLv8gYS7/IGEu/yBiL/8gYi//IGIv/yBiL/8hYy//IWMv/yFjL/8hYy//bah6/22oev9tqHr/ + bah6/22oev9tqHr/bah6/22oev9tqHr/bah6/22oev9tqHr/bal//22pf/9tqX//bal//3TM+/90zPv/ + dMz7/3TM+/9rqaj/a6mo/2upqP9rqaj/YIJo/2CCaP9ggmj/YIJo/2CDaP9gg2j/YINo/2CDaP/9+vb/ + /fr2//369v/9+vb/a4ty/2uLcv9ri3L/a4ty/2GFaf9hhWn/YYVp/2GFaf9ihmn/YoZp/2KGaf9ihmn/ + YoZq/2KGav9ihmr/YoZq/2KHav9ih2r/Yodq/2KHav9jiGv/Y4hr/2OIa/9jiGv/tcW1/7XFtf+1xbX/ + tcW1/7XFtv+1xbb/tcW2/7XFtv9jimv/Y4pr/2OKa/9jimv/Y4ps/2OKbP9jimz/Y4ps/2OLbP9ji2z/ + Y4ts/2OLbP9ahGT/WoRk/1qEZP9ahGT/LGM4/yxjOP8sYzj/LGM4/ytiN/8rYjf/K2I3/ytiN//89/L/ + /Pfy//z38v/89/L/Hlws/x5cLP8eXCz/Hlws/x5dLP8eXSz/Hl0s/x5dLP8rioj/K4qI/yuKiP8rioj/ + NbT5/zW0+f81tPn/NbT5/yFkNf8hZDX/IWQ1/yFkNf8gYS7/IGEu/yBhLv8gYS7/IGIv/yBiL/8gYi// + IGIv/yFjL/8hYy//IWMv/yFjL/9xq37/cat+/3Grfv9xq37/cat+/3Grfv9xq37/cat+/3Grfv9xq37/ + cat+/3Grfv9yr4z/cq+M/3KvjP9yr4z/eM37/3jN+/94zfv/eM37/22loP9tpaD/baWg/22loP9khGv/ + ZIRr/2SEa/9khGv/ZIVr/2SFa/9khWv/ZIVr//36+P/9+vj//fr4//36+P9ujnX/bo51/26Odf9ujnX/ + ZYht/2WIbf9liG3/ZYht/2WIbf9liG3/ZYht/2WIbf9liW3/ZYlt/2WJbf9liW3/Zopt/2aKbf9mim3/ + Zopt/2aKbv9mim7/Zopu/2aKbv+1xbb/tcW2/7XFtv+1xbb/tcW2/7XFtv+1xbb/tcW2/2eMb/9njG// + Z4xv/2eMb/9njW//Z41v/2eNb/9njW//Z45v/2eOb/9njm//Z45v/2eOcP9njnD/Z45w/2eOcP9mjm7/ + Zo5u/2aObv9mjm7/THtW/0x7Vv9Me1b/THtW//z49P/8+PT//Pj0//z49P8eWyz/Hlss/x5bLP8eWyz/ + H10s/x9dLP8fXSz/H10s/yqDd/8qg3f/KoN3/yqDd/82tfn/NrX5/za1+f82tfn/I21H/yNtR/8jbUf/ + I21H/yBhLv8gYS7/IGEu/yBhLv8hYi//IWIv/yFiL/8hYi//IWMw/yFjMP8hYzD/IWMw/3Grfv9xq37/ + cat+/3Grfv9xq37/cat+/3Grfv9xq37/cat+/3Grfv9xq37/cat+/3KvjP9yr4z/cq+M/3KvjP94zfv/ + eM37/3jN+/94zfv/baWg/22loP9tpaD/baWg/2SEa/9khGv/ZIRr/2SEa/9khWv/ZIVr/2SFa/9khWv/ + /fr4//36+P/9+vj//fr4/26Odf9ujnX/bo51/26Odf9liG3/ZYht/2WIbf9liG3/ZYht/2WIbf9liG3/ + ZYht/2WJbf9liW3/ZYlt/2WJbf9mim3/Zopt/2aKbf9mim3/Zopu/2aKbv9mim7/Zopu/7XFtv+1xbb/ + tcW2/7XFtv+1xbb/tcW2/7XFtv+1xbb/Z4xv/2eMb/9njG//Z4xv/2eNb/9njW//Z41v/2eNb/9njm// + Z45v/2eOb/9njm//Z45w/2eOcP9njnD/Z45w/2aObv9mjm7/Zo5u/2aObv9Me1b/THtW/0x7Vv9Me1b/ + /Pj0//z49P/8+PT//Pj0/x5bLP8eWyz/Hlss/x5bLP8fXSz/H10s/x9dLP8fXSz/KoN3/yqDd/8qg3f/ + KoN3/za1+f82tfn/NrX5/za1+f8jbUf/I21H/yNtR/8jbUf/IGEu/yBhLv8gYS7/IGEu/yFiL/8hYi// + IWIv/yFiL/8hYzD/IWMw/yFjMP8hYzD/cat+/3Grfv9xq37/cat+/3Grfv9xq37/cat+/3Grfv9xq37/ + cat+/3Grfv9xq37/cq+M/3KvjP9yr4z/cq+M/3jN+/94zfv/eM37/3jN+/9tpaD/baWg/22loP9tpaD/ + ZIRr/2SEa/9khGv/ZIRr/2SFa/9khWv/ZIVr/2SFa//9+vj//fr4//36+P/9+vj/bo51/26Odf9ujnX/ + bo51/2WIbf9liG3/ZYht/2WIbf9liG3/ZYht/2WIbf9liG3/ZYlt/2WJbf9liW3/ZYlt/2aKbf9mim3/ + Zopt/2aKbf9mim7/Zopu/2aKbv9mim7/tcW2/7XFtv+1xbb/tcW2/7XFtv+1xbb/tcW2/7XFtv9njG// + Z4xv/2eMb/9njG//Z41v/2eNb/9njW//Z41v/2eOb/9njm//Z45v/2eOb/9njnD/Z45w/2eOcP9njnD/ + Zo5u/2aObv9mjm7/Zo5u/0x7Vv9Me1b/THtW/0x7Vv/8+PT//Pj0//z49P/8+PT/Hlss/x5bLP8eWyz/ + Hlss/x9dLP8fXSz/H10s/x9dLP8qg3f/KoN3/yqDd/8qg3f/NrX5/za1+f82tfn/NrX5/yNtR/8jbUf/ + I21H/yNtR/8gYS7/IGEu/yBhLv8gYS7/IWIv/yFiL/8hYi//IWIv/yFjMP8hYzD/IWMw/yFjMP9xq37/ + cat+/3Grfv9xq37/cat+/3Grfv9xq37/cat+/3Grfv9xq37/cat+/3Grfv9yr4z/cq+M/3KvjP9yr4z/ + eM37/3jN+/94zfv/eM37/22loP9tpaD/baWg/22loP9khGv/ZIRr/2SEa/9khGv/ZIVr/2SFa/9khWv/ + ZIVr//36+P/9+vj//fr4//36+P9ujnX/bo51/26Odf9ujnX/ZYht/2WIbf9liG3/ZYht/2WIbf9liG3/ + ZYht/2WIbf9liW3/ZYlt/2WJbf9liW3/Zopt/2aKbf9mim3/Zopt/2aKbv9mim7/Zopu/2aKbv+1xbb/ + tcW2/7XFtv+1xbb/tcW2/7XFtv+1xbb/tcW2/2eMb/9njG//Z4xv/2eMb/9njW//Z41v/2eNb/9njW// + Z45v/2eOb/9njm//Z45v/2eOcP9njnD/Z45w/2eOcP9mjm7/Zo5u/2aObv9mjm7/THtW/0x7Vv9Me1b/ + THtW//z49P/8+PT//Pj0//z49P8eWyz/Hlss/x5bLP8eWyz/H10s/x9dLP8fXSz/H10s/yqDd/8qg3f/ + KoN3/yqDd/82tfn/NrX5/za1+f82tfn/I21H/yNtR/8jbUf/I21H/yBhLv8gYS7/IGEu/yBhLv8hYi// + IWIv/yFiL/8hYi//IWMw/yFjMP8hYzD/IWMw/3Stgf90rYH/dK2B/3Stgf90rYH/dK2B/3Stgf90rYH/ + dK2B/3Stgf90rYH/dK2B/3Wyk/91spP/dbKT/3Wyk/97z/v/e8/7/3vP+/97z/v/cKWe/3Clnv9wpZ7/ + cKWe/2eGbv9nhm7/Z4Zu/2eGbv9nh2//Z4dv/2eHb/9nh2///fr4//36+P/9+vj//fr4/3OSef9zknn/ + c5J5/3OSef9oim//aIpv/2iKb/9oim//aIpw/2iKcP9oinD/aIpw/2mLcf9pi3H/aYtx/2mLcf9pjHH/ + aYxx/2mMcf9pjHH/aYxx/2mMcf9pjHH/aYxx/3KUef9ylHn/cpR5/3KUef9ylHr/cpR6/3KUev9ylHr/ + aY5y/2mOcv9pjnL/aY5y/2qPc/9qj3P/ao9z/2qPc/9qkHP/apBz/2qQc/9qkHP/apBz/2qQc/9qkHP/ + apBz/2uRc/9rkXP/a5Fz/2uRc/91mX3/dZl9/3WZff91mX3//fr3//369//9+vf//fr3/yNeMP8jXjD/ + I14w/yNeMP8fXC3/H1wt/x9cLf8fXC3/KYNz/ymDc/8pg3P/KYNz/za2+f82tvn/Nrb5/za2+f8lcU3/ + JXFN/yVxTf8lcU3/IWEv/yFhL/8hYS//IWEv/yFiMP8hYjD/IWIw/yFiMP8hZDH/IWQx/yFkMf8hZDH/ + dK2B/3Stgf90rYH/dK2B/3Stgf90rYH/dK2B/3Stgf90rYH/dK2B/3Stgf90rYH/dbKT/3Wyk/91spP/ + dbKT/3vP+/97z/v/e8/7/3vP+/9wpZ7/cKWe/3Clnv9wpZ7/Z4Zu/2eGbv9nhm7/Z4Zu/2eHb/9nh2// + Z4dv/2eHb//9+vj//fr4//36+P/9+vj/c5J5/3OSef9zknn/c5J5/2iKb/9oim//aIpv/2iKb/9oinD/ + aIpw/2iKcP9oinD/aYtx/2mLcf9pi3H/aYtx/2mMcf9pjHH/aYxx/2mMcf9pjHH/aYxx/2mMcf9pjHH/ + cpR5/3KUef9ylHn/cpR5/3KUev9ylHr/cpR6/3KUev9pjnL/aY5y/2mOcv9pjnL/ao9z/2qPc/9qj3P/ + ao9z/2qQc/9qkHP/apBz/2qQc/9qkHP/apBz/2qQc/9qkHP/a5Fz/2uRc/9rkXP/a5Fz/3WZff91mX3/ + dZl9/3WZff/9+vf//fr3//369//9+vf/I14w/yNeMP8jXjD/I14w/x9cLf8fXC3/H1wt/x9cLf8pg3P/ + KYNz/ymDc/8pg3P/Nrb5/za2+f82tvn/Nrb5/yVxTf8lcU3/JXFN/yVxTf8hYS//IWEv/yFhL/8hYS// + IWIw/yFiMP8hYjD/IWIw/yFkMf8hZDH/IWQx/yFkMf90rYH/dK2B/3Stgf90rYH/dK2B/3Stgf90rYH/ + dK2B/3Stgf90rYH/dK2B/3Stgf91spP/dbKT/3Wyk/91spP/e8/7/3vP+/97z/v/e8/7/3Clnv9wpZ7/ + cKWe/3Clnv9nhm7/Z4Zu/2eGbv9nhm7/Z4dv/2eHb/9nh2//Z4dv//36+P/9+vj//fr4//36+P9zknn/ + c5J5/3OSef9zknn/aIpv/2iKb/9oim//aIpv/2iKcP9oinD/aIpw/2iKcP9pi3H/aYtx/2mLcf9pi3H/ + aYxx/2mMcf9pjHH/aYxx/2mMcf9pjHH/aYxx/2mMcf9ylHn/cpR5/3KUef9ylHn/cpR6/3KUev9ylHr/ + cpR6/2mOcv9pjnL/aY5y/2mOcv9qj3P/ao9z/2qPc/9qj3P/apBz/2qQc/9qkHP/apBz/2qQc/9qkHP/ + apBz/2qQc/9rkXP/a5Fz/2uRc/9rkXP/dZl9/3WZff91mX3/dZl9//369//9+vf//fr3//369/8jXjD/ + I14w/yNeMP8jXjD/H1wt/x9cLf8fXC3/H1wt/ymDc/8pg3P/KYNz/ymDc/82tvn/Nrb5/za2+f82tvn/ + JXFN/yVxTf8lcU3/JXFN/yFhL/8hYS//IWEv/yFhL/8hYjD/IWIw/yFiMP8hYjD/IWQx/yFkMf8hZDH/ + IWQx/3Stgf90rYH/dK2B/3Stgf90rYH/dK2B/3Stgf90rYH/dK2B/3Stgf90rYH/dK2B/3Wyk/91spP/ + dbKT/3Wyk/97z/v/e8/7/3vP+/97z/v/cKWe/3Clnv9wpZ7/cKWe/2eGbv9nhm7/Z4Zu/2eGbv9nh2// + Z4dv/2eHb/9nh2///fr4//36+P/9+vj//fr4/3OSef9zknn/c5J5/3OSef9oim//aIpv/2iKb/9oim// + aIpw/2iKcP9oinD/aIpw/2mLcf9pi3H/aYtx/2mLcf9pjHH/aYxx/2mMcf9pjHH/aYxx/2mMcf9pjHH/ + aYxx/3KUef9ylHn/cpR5/3KUef9ylHr/cpR6/3KUev9ylHr/aY5y/2mOcv9pjnL/aY5y/2qPc/9qj3P/ + ao9z/2qPc/9qkHP/apBz/2qQc/9qkHP/apBz/2qQc/9qkHP/apBz/2uRc/9rkXP/a5Fz/2uRc/91mX3/ + dZl9/3WZff91mX3//fr3//369//9+vf//fr3/yNeMP8jXjD/I14w/yNeMP8fXC3/H1wt/x9cLf8fXC3/ + KYNz/ymDc/8pg3P/KYNz/za2+f82tvn/Nrb5/za2+f8lcU3/JXFN/yVxTf8lcU3/IWEv/yFhL/8hYS// + IWEv/yFiMP8hYjD/IWIw/yFiMP8hZDH/IWQx/yFkMf8hZDH/d6+E/3evhP93r4T/d6+E/3evhP93r4T/ + d6+E/3evhP93r4T/d6+E/3evhP93r4T/eLWX/3i1l/94tZf/eLWX/37Q+/9+0Pv/ftD7/37Q+/9ypZ3/ + cqWd/3Klnf9ypZ3/aolx/2qJcf9qiXH/aolx/2qJcf9qiXH/aolx/2qJcf/Z39j/2d/Y/9nf2P/Z39j/ + 4ebg/+Hm4P/h5uD/4ebg/9je1v/Y3tb/2N7W/9je1v/Y3tb/2N7W/9je1v/Y3tb/2N/W/9jf1v/Y39b/ + 2N/W/9jf1v/Y39b/2N/W/9jf1v/Y39f/2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/ + 2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/2N/X/9jg1//Y4Nf/2ODX/9jg1//Y4Nf/ + 2ODX/9jg1//Y4Nf/2ODX/9jg1//Y4Nf/2ODX/+Hn4f/h5+H/4efh/+Hn4f/Z4tn/2eLZ/9ni2f/Z4tn/ + X4pp/1+Kaf9fimn/X4pp/yZhNP8mYTT/JmE0/yZhNP8pgG3/KYBt/ymAbf8pgG3/N7f5/ze3+f83t/n/ + N7f5/yZyUv8mclL/JnJS/yZyUv8hYTD/IWEw/yFhMP8hYTD/IWIw/yFiMP8hYjD/IWIw/yJjMf8iYzH/ + ImMx/yJjMf93r4T/d6+E/3evhP93r4T/d6+E/3evhP93r4T/d6+E/3evhP93r4T/d6+E/3evhP94tZf/ + eLWX/3i1l/94tZf/ftD7/37Q+/9+0Pv/ftD7/3Klnf9ypZ3/cqWd/3Klnf9qiXH/aolx/2qJcf9qiXH/ + aolx/2qJcf9qiXH/aolx/9nf2P/Z39j/2d/Y/9nf2P/h5uD/4ebg/+Hm4P/h5uD/2N7W/9je1v/Y3tb/ + 2N7W/9je1v/Y3tb/2N7W/9je1v/Y39b/2N/W/9jf1v/Y39b/2N/W/9jf1v/Y39b/2N/W/9jf1//Y39f/ + 2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/ + 2N/X/9jf1//Y39f/2ODX/9jg1//Y4Nf/2ODX/9jg1//Y4Nf/2ODX/9jg1//Y4Nf/2ODX/9jg1//Y4Nf/ + 4efh/+Hn4f/h5+H/4efh/9ni2f/Z4tn/2eLZ/9ni2f9fimn/X4pp/1+Kaf9fimn/JmE0/yZhNP8mYTT/ + JmE0/ymAbf8pgG3/KYBt/ymAbf83t/n/N7f5/ze3+f83t/n/JnJS/yZyUv8mclL/JnJS/yFhMP8hYTD/ + IWEw/yFhMP8hYjD/IWIw/yFiMP8hYjD/ImMx/yJjMf8iYzH/ImMx/3evhP93r4T/d6+E/3evhP93r4T/ + d6+E/3evhP93r4T/d6+E/3evhP93r4T/d6+E/3i1l/94tZf/eLWX/3i1l/9+0Pv/ftD7/37Q+/9+0Pv/ + cqWd/3Klnf9ypZ3/cqWd/2qJcf9qiXH/aolx/2qJcf9qiXH/aolx/2qJcf9qiXH/2d/Y/9nf2P/Z39j/ + 2d/Y/+Hm4P/h5uD/4ebg/+Hm4P/Y3tb/2N7W/9je1v/Y3tb/2N7W/9je1v/Y3tb/2N7W/9jf1v/Y39b/ + 2N/W/9jf1v/Y39b/2N/W/9jf1v/Y39b/2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/ + 2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/2N/X/9jf1//Y4Nf/2ODX/9jg1//Y4Nf/ + 2ODX/9jg1//Y4Nf/2ODX/9jg1//Y4Nf/2ODX/9jg1//h5+H/4efh/+Hn4f/h5+H/2eLZ/9ni2f/Z4tn/ + 2eLZ/1+Kaf9fimn/X4pp/1+Kaf8mYTT/JmE0/yZhNP8mYTT/KYBt/ymAbf8pgG3/KYBt/ze3+f83t/n/ + N7f5/ze3+f8mclL/JnJS/yZyUv8mclL/IWEw/yFhMP8hYTD/IWEw/yFiMP8hYjD/IWIw/yFiMP8iYzH/ + ImMx/yJjMf8iYzH/d6+E/3evhP93r4T/d6+E/3evhP93r4T/d6+E/3evhP93r4T/d6+E/3evhP93r4T/ + eLWX/3i1l/94tZf/eLWX/37Q+/9+0Pv/ftD7/37Q+/9ypZ3/cqWd/3Klnf9ypZ3/aolx/2qJcf9qiXH/ + aolx/2qJcf9qiXH/aolx/2qJcf/Z39j/2d/Y/9nf2P/Z39j/4ebg/+Hm4P/h5uD/4ebg/9je1v/Y3tb/ + 2N7W/9je1v/Y3tb/2N7W/9je1v/Y3tb/2N/W/9jf1v/Y39b/2N/W/9jf1v/Y39b/2N/W/9jf1v/Y39f/ + 2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/ + 2N/X/9jf1//Y39f/2N/X/9jg1//Y4Nf/2ODX/9jg1//Y4Nf/2ODX/9jg1//Y4Nf/2ODX/9jg1//Y4Nf/ + 2ODX/+Hn4f/h5+H/4efh/+Hn4f/Z4tn/2eLZ/9ni2f/Z4tn/X4pp/1+Kaf9fimn/X4pp/yZhNP8mYTT/ + JmE0/yZhNP8pgG3/KYBt/ymAbf8pgG3/N7f5/ze3+f83t/n/N7f5/yZyUv8mclL/JnJS/yZyUv8hYTD/ + IWEw/yFhMP8hYTD/IWIw/yFiMP8hYjD/IWIw/yJjMf8iYzH/ImMx/yJjMf96soj/erKI/3qyiP96soj/ + erKI/3qyiP96soj/erKI/3qyiP96soj/erKI/3qyiP97uJ3/e7id/3u4nf97uJ3/gNL7/4DS+/+A0vv/ + gNL7/3Olm/9zpZv/c6Wb/3Olm/9si3T/bIt0/2yLdP9si3T/bYt1/22Ldf9ti3X/bYt1/3KQev9ykHr/ + cpB6/3KQev+Yrp3/mK6d/5iunf+Yrp3/nbKh/52yof+dsqH/nbKh/7fGuf+3xrn/t8a5/7fGuf/r7un/ + 6+7p/+vu6f/r7un/nrSi/560ov+etKL/nrSi/560ov+etKL/nrSi/560ov+etaL/nrWi/561ov+etaL/ + nrWj/561o/+etaP/nrWj/561o/+etaP/nrWj/561o/+etqT/nrak/562pP+etqT/6+7q/+vu6v/r7ur/ + 6+7q/7fJu/+3ybv/t8m7/7fJu/+ft6T/n7ek/5+3pP+ft6T/mrSg/5q0oP+atKD/mrSg/3Wafv91mn7/ + dZp+/3Wafv9xl3r/cZd6/3GXev9xl3r/ZpBw/2aQcP9mkHD/ZpBw/zWFcP81hXD/NYVw/zWFcP83uPn/ + N7j5/ze4+f83uPn/J3ZY/yd2WP8ndlj/J3ZY/yFhMf8hYTH/IWEx/yFhMf8hYjH/IWIx/yFiMf8hYjH/ + ImYz/yJmM/8iZjP/ImYz/3qyiP96soj/erKI/3qyiP96soj/erKI/3qyiP96soj/erKI/3qyiP96soj/ + erKI/3u4nf97uJ3/e7id/3u4nf+A0vv/gNL7/4DS+/+A0vv/c6Wb/3Olm/9zpZv/c6Wb/2yLdP9si3T/ + bIt0/2yLdP9ti3X/bYt1/22Ldf9ti3X/cpB6/3KQev9ykHr/cpB6/5iunf+Yrp3/mK6d/5iunf+dsqH/ + nbKh/52yof+dsqH/t8a5/7fGuf+3xrn/t8a5/+vu6f/r7un/6+7p/+vu6f+etKL/nrSi/560ov+etKL/ + nrSi/560ov+etKL/nrSi/561ov+etaL/nrWi/561ov+etaP/nrWj/561o/+etaP/nrWj/561o/+etaP/ + nrWj/562pP+etqT/nrak/562pP/r7ur/6+7q/+vu6v/r7ur/t8m7/7fJu/+3ybv/t8m7/5+3pP+ft6T/ + n7ek/5+3pP+atKD/mrSg/5q0oP+atKD/dZp+/3Wafv91mn7/dZp+/3GXev9xl3r/cZd6/3GXev9mkHD/ + ZpBw/2aQcP9mkHD/NYVw/zWFcP81hXD/NYVw/ze4+f83uPn/N7j5/ze4+f8ndlj/J3ZY/yd2WP8ndlj/ + IWEx/yFhMf8hYTH/IWEx/yFiMf8hYjH/IWIx/yFiMf8iZjP/ImYz/yJmM/8iZjP/erKI/3qyiP96soj/ + erKI/3qyiP96soj/erKI/3qyiP96soj/erKI/3qyiP96soj/e7id/3u4nf97uJ3/e7id/4DS+/+A0vv/ + gNL7/4DS+/9zpZv/c6Wb/3Olm/9zpZv/bIt0/2yLdP9si3T/bIt0/22Ldf9ti3X/bYt1/22Ldf9ykHr/ + cpB6/3KQev9ykHr/mK6d/5iunf+Yrp3/mK6d/52yof+dsqH/nbKh/52yof+3xrn/t8a5/7fGuf+3xrn/ + 6+7p/+vu6f/r7un/6+7p/560ov+etKL/nrSi/560ov+etKL/nrSi/560ov+etKL/nrWi/561ov+etaL/ + nrWi/561o/+etaP/nrWj/561o/+etaP/nrWj/561o/+etaP/nrak/562pP+etqT/nrak/+vu6v/r7ur/ + 6+7q/+vu6v+3ybv/t8m7/7fJu/+3ybv/n7ek/5+3pP+ft6T/n7ek/5q0oP+atKD/mrSg/5q0oP91mn7/ + dZp+/3Wafv91mn7/cZd6/3GXev9xl3r/cZd6/2aQcP9mkHD/ZpBw/2aQcP81hXD/NYVw/zWFcP81hXD/ + N7j5/ze4+f83uPn/N7j5/yd2WP8ndlj/J3ZY/yd2WP8hYTH/IWEx/yFhMf8hYTH/IWIx/yFiMf8hYjH/ + IWIx/yJmM/8iZjP/ImYz/yJmM/96soj/erKI/3qyiP96soj/erKI/3qyiP96soj/erKI/3qyiP96soj/ + erKI/3qyiP97uJ3/e7id/3u4nf97uJ3/gNL7/4DS+/+A0vv/gNL7/3Olm/9zpZv/c6Wb/3Olm/9si3T/ + bIt0/2yLdP9si3T/bYt1/22Ldf9ti3X/bYt1/3KQev9ykHr/cpB6/3KQev+Yrp3/mK6d/5iunf+Yrp3/ + nbKh/52yof+dsqH/nbKh/7fGuf+3xrn/t8a5/7fGuf/r7un/6+7p/+vu6f/r7un/nrSi/560ov+etKL/ + nrSi/560ov+etKL/nrSi/560ov+etaL/nrWi/561ov+etaL/nrWj/561o/+etaP/nrWj/561o/+etaP/ + nrWj/561o/+etqT/nrak/562pP+etqT/6+7q/+vu6v/r7ur/6+7q/7fJu/+3ybv/t8m7/7fJu/+ft6T/ + n7ek/5+3pP+ft6T/mrSg/5q0oP+atKD/mrSg/3Wafv91mn7/dZp+/3Wafv9xl3r/cZd6/3GXev9xl3r/ + ZpBw/2aQcP9mkHD/ZpBw/zWFcP81hXD/NYVw/zWFcP83uPn/N7j5/ze4+f83uPn/J3ZY/yd2WP8ndlj/ + J3ZY/yFhMf8hYTH/IWEx/yFhMf8hYjH/IWIx/yFiMf8hYjH/ImYz/yJmM/8iZjP/ImYz/361i/9+tYv/ + frWL/361i/9+tYv/frWL/361i/9+tYv/frWL/361i/9+tYv/frWL/3+7o/9/u6P/f7uj/3+7o/+E0/v/ + hNP7/4TT+/+E0/v/d6Wa/3elmv93pZr/d6Wa/3CNd/9wjXf/cI13/3CNd/9wjnj/cI54/3COeP9wjnj/ + cI94/3CPeP9wj3j/cI94/3CPef9wj3n/cI95/3CPef9xkHn/cZB5/3GQef9xkHn/kamX/5Gpl/+RqZf/ + kamX/+zw7P/s8Oz/7PDs/+zw7P9yknr/cpJ6/3KSev9yknr/cpN6/3KTev9yk3r/cpN6/3KUev9ylHr/ + cpR6/3KUev9ylHv/cpR7/3KUe/9ylHv/c5V7/3OVe/9zlXv/c5V7/3OWfP9zlnz/c5Z8/3OWfP/s8Oz/ + 7PDs/+zw7P/s8Oz/k66Z/5Oumf+Trpn/k66Z/3SYfP90mHz/dJh8/3SYfP90mH3/dJh9/3SYff90mH3/ + dJl9/3SZff90mX3/dJl9/3SZfv90mX7/dJl+/3SZfv90mn7/dJp+/3Safv90mn7/c6mZ/3Opmf9zqZn/ + c6mZ/0S8+P9EvPj/RLz4/0S8+P8oeF3/KHhd/yh4Xf8oeF3/IWEx/yFhMf8hYTH/IWEx/yJlM/8iZTP/ + ImUz/yJlM/8sgEH/LIBB/yyAQf8sgEH/frWL/361i/9+tYv/frWL/361i/9+tYv/frWL/361i/9+tYv/ + frWL/361i/9+tYv/f7uj/3+7o/9/u6P/f7uj/4TT+/+E0/v/hNP7/4TT+/93pZr/d6Wa/3elmv93pZr/ + cI13/3CNd/9wjXf/cI13/3COeP9wjnj/cI54/3COeP9wj3j/cI94/3CPeP9wj3j/cI95/3CPef9wj3n/ + cI95/3GQef9xkHn/cZB5/3GQef+RqZf/kamX/5Gpl/+RqZf/7PDs/+zw7P/s8Oz/7PDs/3KSev9yknr/ + cpJ6/3KSev9yk3r/cpN6/3KTev9yk3r/cpR6/3KUev9ylHr/cpR6/3KUe/9ylHv/cpR7/3KUe/9zlXv/ + c5V7/3OVe/9zlXv/c5Z8/3OWfP9zlnz/c5Z8/+zw7P/s8Oz/7PDs/+zw7P+Trpn/k66Z/5Oumf+Trpn/ + dJh8/3SYfP90mHz/dJh8/3SYff90mH3/dJh9/3SYff90mX3/dJl9/3SZff90mX3/dJl+/3SZfv90mX7/ + dJl+/3Safv90mn7/dJp+/3Safv9zqZn/c6mZ/3Opmf9zqZn/RLz4/0S8+P9EvPj/RLz4/yh4Xf8oeF3/ + KHhd/yh4Xf8hYTH/IWEx/yFhMf8hYTH/ImUz/yJlM/8iZTP/ImUz/yyAQf8sgEH/LIBB/yyAQf9+tYv/ + frWL/361i/9+tYv/frWL/361i/9+tYv/frWL/361i/9+tYv/frWL/361i/9/u6P/f7uj/3+7o/9/u6P/ + hNP7/4TT+/+E0/v/hNP7/3elmv93pZr/d6Wa/3elmv9wjXf/cI13/3CNd/9wjXf/cI54/3COeP9wjnj/ + cI54/3CPeP9wj3j/cI94/3CPeP9wj3n/cI95/3CPef9wj3n/cZB5/3GQef9xkHn/cZB5/5Gpl/+RqZf/ + kamX/5Gpl//s8Oz/7PDs/+zw7P/s8Oz/cpJ6/3KSev9yknr/cpJ6/3KTev9yk3r/cpN6/3KTev9ylHr/ + cpR6/3KUev9ylHr/cpR7/3KUe/9ylHv/cpR7/3OVe/9zlXv/c5V7/3OVe/9zlnz/c5Z8/3OWfP9zlnz/ + 7PDs/+zw7P/s8Oz/7PDs/5Oumf+Trpn/k66Z/5Oumf90mHz/dJh8/3SYfP90mHz/dJh9/3SYff90mH3/ + dJh9/3SZff90mX3/dJl9/3SZff90mX7/dJl+/3SZfv90mX7/dJp+/3Safv90mn7/dJp+/3Opmf9zqZn/ + c6mZ/3Opmf9EvPj/RLz4/0S8+P9EvPj/KHhd/yh4Xf8oeF3/KHhd/yFhMf8hYTH/IWEx/yFhMf8iZTP/ + ImUz/yJlM/8iZTP/LIBB/yyAQf8sgEH/LIBB/361i/9+tYv/frWL/361i/9+tYv/frWL/361i/9+tYv/ + frWL/361i/9+tYv/frWL/3+7o/9/u6P/f7uj/3+7o/+E0/v/hNP7/4TT+/+E0/v/d6Wa/3elmv93pZr/ + d6Wa/3CNd/9wjXf/cI13/3CNd/9wjnj/cI54/3COeP9wjnj/cI94/3CPeP9wj3j/cI94/3CPef9wj3n/ + cI95/3CPef9xkHn/cZB5/3GQef9xkHn/kamX/5Gpl/+RqZf/kamX/+zw7P/s8Oz/7PDs/+zw7P9yknr/ + cpJ6/3KSev9yknr/cpN6/3KTev9yk3r/cpN6/3KUev9ylHr/cpR6/3KUev9ylHv/cpR7/3KUe/9ylHv/ + c5V7/3OVe/9zlXv/c5V7/3OWfP9zlnz/c5Z8/3OWfP/s8Oz/7PDs/+zw7P/s8Oz/k66Z/5Oumf+Trpn/ + k66Z/3SYfP90mHz/dJh8/3SYfP90mH3/dJh9/3SYff90mH3/dJl9/3SZff90mX3/dJl9/3SZfv90mX7/ + dJl+/3SZfv90mn7/dJp+/3Safv90mn7/c6mZ/3Opmf9zqZn/c6mZ/0S8+P9EvPj/RLz4/0S8+P8oeF3/ + KHhd/yh4Xf8oeF3/IWEx/yFhMf8hYTH/IWEx/yJlM/8iZTP/ImUz/yJlM/8sgEH/LIBB/yyAQf8sgEH/ + gbeO/4G3jv+Bt47/gbeO/4G3jv+Bt47/gbeO/4G3jv+Bt47/gbeO/4G3jv+Bt47/gr6n/4K+p/+Cvqf/ + gr6n/4fU+/+H1Pv/h9T7/4fU+/95pJj/eaSY/3mkmP95pJj/c496/3OPev9zj3r/c496/3OQev9zkHr/ + c5B6/3OQev9zkXr/c5F6/3ORev9zkXr/dJJ7/3SSe/90knv/dJJ7/3SSe/90knv/dJJ7/3SSe/94loD/ + eJaA/3iWgP94loD/7fDs/+3w7P/t8Oz/7fDs/9Te1v/U3tb/1N7W/9Te1v+/zcL/v83C/7/Nwv+/zcL/ + v83C/7/Nwv+/zcL/v83C/7/Owv+/zsL/v87C/7/Owv+/zsL/v87C/7/Owv+/zsL/1d/X/9Xf1//V39f/ + 1d/X/+3w7f/t8O3/7fDt/+3w7f96nIP/epyD/3qcg/96nIP/dpl//3aZf/92mX//dpl//3eaf/93mn// + d5p//3eaf/93m3//d5t//3ebf/93m3//d5uA/3ebgP93m4D/d5uA/3ecgf93nIH/d5yB/3ecgf98rp3/ + fK6d/3yunf98rp3/ftH6/37R+v9+0fr/ftH6/zOBaP8zgWj/M4Fo/zOBaP8iZDL/ImQy/yJkMv8iZDL/ + LYJB/y2CQf8tgkH/LYJB/y+JRf8viUX/L4lF/y+JRf+Bt47/gbeO/4G3jv+Bt47/gbeO/4G3jv+Bt47/ + gbeO/4G3jv+Bt47/gbeO/4G3jv+Cvqf/gr6n/4K+p/+Cvqf/h9T7/4fU+/+H1Pv/h9T7/3mkmP95pJj/ + eaSY/3mkmP9zj3r/c496/3OPev9zj3r/c5B6/3OQev9zkHr/c5B6/3ORev9zkXr/c5F6/3ORev90knv/ + dJJ7/3SSe/90knv/dJJ7/3SSe/90knv/dJJ7/3iWgP94loD/eJaA/3iWgP/t8Oz/7fDs/+3w7P/t8Oz/ + 1N7W/9Te1v/U3tb/1N7W/7/Nwv+/zcL/v83C/7/Nwv+/zcL/v83C/7/Nwv+/zcL/v87C/7/Owv+/zsL/ + v87C/7/Owv+/zsL/v87C/7/Owv/V39f/1d/X/9Xf1//V39f/7fDt/+3w7f/t8O3/7fDt/3qcg/96nIP/ + epyD/3qcg/92mX//dpl//3aZf/92mX//d5p//3eaf/93mn//d5p//3ebf/93m3//d5t//3ebf/93m4D/ + d5uA/3ebgP93m4D/d5yB/3ecgf93nIH/d5yB/3yunf98rp3/fK6d/3yunf9+0fr/ftH6/37R+v9+0fr/ + M4Fo/zOBaP8zgWj/M4Fo/yJkMv8iZDL/ImQy/yJkMv8tgkH/LYJB/y2CQf8tgkH/L4lF/y+JRf8viUX/ + L4lF/4G3jv+Bt47/gbeO/4G3jv+Bt47/gbeO/4G3jv+Bt47/gbeO/4G3jv+Bt47/gbeO/4K+p/+Cvqf/ + gr6n/4K+p/+H1Pv/h9T7/4fU+/+H1Pv/eaSY/3mkmP95pJj/eaSY/3OPev9zj3r/c496/3OPev9zkHr/ + c5B6/3OQev9zkHr/c5F6/3ORev9zkXr/c5F6/3SSe/90knv/dJJ7/3SSe/90knv/dJJ7/3SSe/90knv/ + eJaA/3iWgP94loD/eJaA/+3w7P/t8Oz/7fDs/+3w7P/U3tb/1N7W/9Te1v/U3tb/v83C/7/Nwv+/zcL/ + v83C/7/Nwv+/zcL/v83C/7/Nwv+/zsL/v87C/7/Owv+/zsL/v87C/7/Owv+/zsL/v87C/9Xf1//V39f/ + 1d/X/9Xf1//t8O3/7fDt/+3w7f/t8O3/epyD/3qcg/96nIP/epyD/3aZf/92mX//dpl//3aZf/93mn// + d5p//3eaf/93mn//d5t//3ebf/93m3//d5t//3ebgP93m4D/d5uA/3ebgP93nIH/d5yB/3ecgf93nIH/ + fK6d/3yunf98rp3/fK6d/37R+v9+0fr/ftH6/37R+v8zgWj/M4Fo/zOBaP8zgWj/ImQy/yJkMv8iZDL/ + ImQy/y2CQf8tgkH/LYJB/y2CQf8viUX/L4lF/y+JRf8viUX/gbeO/4G3jv+Bt47/gbeO/4G3jv+Bt47/ + gbeO/4G3jv+Bt47/gbeO/4G3jv+Bt47/gr6n/4K+p/+Cvqf/gr6n/4fU+/+H1Pv/h9T7/4fU+/95pJj/ + eaSY/3mkmP95pJj/c496/3OPev9zj3r/c496/3OQev9zkHr/c5B6/3OQev9zkXr/c5F6/3ORev9zkXr/ + dJJ7/3SSe/90knv/dJJ7/3SSe/90knv/dJJ7/3SSe/94loD/eJaA/3iWgP94loD/7fDs/+3w7P/t8Oz/ + 7fDs/9Te1v/U3tb/1N7W/9Te1v+/zcL/v83C/7/Nwv+/zcL/v83C/7/Nwv+/zcL/v83C/7/Owv+/zsL/ + v87C/7/Owv+/zsL/v87C/7/Owv+/zsL/1d/X/9Xf1//V39f/1d/X/+3w7f/t8O3/7fDt/+3w7f96nIP/ + epyD/3qcg/96nIP/dpl//3aZf/92mX//dpl//3eaf/93mn//d5p//3eaf/93m3//d5t//3ebf/93m3// + d5uA/3ebgP93m4D/d5uA/3ecgf93nIH/d5yB/3ecgf98rp3/fK6d/3yunf98rp3/ftH6/37R+v9+0fr/ + ftH6/zOBaP8zgWj/M4Fo/zOBaP8iZDL/ImQy/yJkMv8iZDL/LYJB/y2CQf8tgkH/LYJB/y+JRf8viUX/ + L4lF/y+JRf+EuZH/hLmR/4S5kf+EuZH/hLmR/4S5kf+EuZH/hLmR/4S5kf+EuZH/hLmR/4S5kf+FwKz/ + hcCs/4XArP+FwKz/idb7/4nW+/+J1vv/idb7/32qof99qqH/faqh/32qof92kXz/dpF8/3aRfP92kXz/ + dpJ9/3aSff92kn3/dpJ9/3aTfv92k37/dpN+/3aTfv92k37/dpN+/3aTfv92k37/dpR+/3aUfv92lH7/ + dpR+/3eUfv93lH7/d5R+/3eUfv+Cnor/gp6K/4Keiv+Cnor/tca5/7XGuf+1xrn/tca5/8DOw//AzsP/ + wM7D/8DOw//Az8P/wM/D/8DPw//Az8P/wM/E/8DPxP/Az8T/wM/E/8DPxP/Az8T/wM/E/8DPxP+2yLr/ + tsi6/7bIuv+2yLr/hKOL/4Sji/+Eo4v/hKOL/3mbgv95m4L/eZuC/3mbgv95m4L/eZuC/3mbgv95m4L/ + eZyC/3mcgv95nIL/eZyC/3mdgv95nYL/eZ2C/3mdgv96nYP/ep2D/3qdg/96nYP/ep6D/3qeg/96noP/ + ep6D/4Cypf+AsqX/gLKl/4Cypf+J1vv/idb7/4nW+/+J1vv/dKyc/3SsnP90rJz/dKyc/zSGSv80hkr/ + NIZK/zSGSv8wikf/MIpH/zCKR/8wikf/MIpH/zCKR/8wikf/MIpH/4S5kf+EuZH/hLmR/4S5kf+EuZH/ + hLmR/4S5kf+EuZH/hLmR/4S5kf+EuZH/hLmR/4XArP+FwKz/hcCs/4XArP+J1vv/idb7/4nW+/+J1vv/ + faqh/32qof99qqH/faqh/3aRfP92kXz/dpF8/3aRfP92kn3/dpJ9/3aSff92kn3/dpN+/3aTfv92k37/ + dpN+/3aTfv92k37/dpN+/3aTfv92lH7/dpR+/3aUfv92lH7/d5R+/3eUfv93lH7/d5R+/4Keiv+Cnor/ + gp6K/4Keiv+1xrn/tca5/7XGuf+1xrn/wM7D/8DOw//AzsP/wM7D/8DPw//Az8P/wM/D/8DPw//Az8T/ + wM/E/8DPxP/Az8T/wM/E/8DPxP/Az8T/wM/E/7bIuv+2yLr/tsi6/7bIuv+Eo4v/hKOL/4Sji/+Eo4v/ + eZuC/3mbgv95m4L/eZuC/3mbgv95m4L/eZuC/3mbgv95nIL/eZyC/3mcgv95nIL/eZ2C/3mdgv95nYL/ + eZ2C/3qdg/96nYP/ep2D/3qdg/96noP/ep6D/3qeg/96noP/gLKl/4Cypf+AsqX/gLKl/4nW+/+J1vv/ + idb7/4nW+/90rJz/dKyc/3SsnP90rJz/NIZK/zSGSv80hkr/NIZK/zCKR/8wikf/MIpH/zCKR/8wikf/ + MIpH/zCKR/8wikf/hLmR/4S5kf+EuZH/hLmR/4S5kf+EuZH/hLmR/4S5kf+EuZH/hLmR/4S5kf+EuZH/ + hcCs/4XArP+FwKz/hcCs/4nW+/+J1vv/idb7/4nW+/99qqH/faqh/32qof99qqH/dpF8/3aRfP92kXz/ + dpF8/3aSff92kn3/dpJ9/3aSff92k37/dpN+/3aTfv92k37/dpN+/3aTfv92k37/dpN+/3aUfv92lH7/ + dpR+/3aUfv93lH7/d5R+/3eUfv93lH7/gp6K/4Keiv+Cnor/gp6K/7XGuf+1xrn/tca5/7XGuf/AzsP/ + wM7D/8DOw//AzsP/wM/D/8DPw//Az8P/wM/D/8DPxP/Az8T/wM/E/8DPxP/Az8T/wM/E/8DPxP/Az8T/ + tsi6/7bIuv+2yLr/tsi6/4Sji/+Eo4v/hKOL/4Sji/95m4L/eZuC/3mbgv95m4L/eZuC/3mbgv95m4L/ + eZuC/3mcgv95nIL/eZyC/3mcgv95nYL/eZ2C/3mdgv95nYL/ep2D/3qdg/96nYP/ep2D/3qeg/96noP/ + ep6D/3qeg/+AsqX/gLKl/4Cypf+AsqX/idb7/4nW+/+J1vv/idb7/3SsnP90rJz/dKyc/3SsnP80hkr/ + NIZK/zSGSv80hkr/MIpH/zCKR/8wikf/MIpH/zCKR/8wikf/MIpH/zCKR/+EuZH/hLmR/4S5kf+EuZH/ + hLmR/4S5kf+EuZH/hLmR/4S5kf+EuZH/hLmR/4S5kf+FwKz/hcCs/4XArP+FwKz/idb7/4nW+/+J1vv/ + idb7/32qof99qqH/faqh/32qof92kXz/dpF8/3aRfP92kXz/dpJ9/3aSff92kn3/dpJ9/3aTfv92k37/ + dpN+/3aTfv92k37/dpN+/3aTfv92k37/dpR+/3aUfv92lH7/dpR+/3eUfv93lH7/d5R+/3eUfv+Cnor/ + gp6K/4Keiv+Cnor/tca5/7XGuf+1xrn/tca5/8DOw//AzsP/wM7D/8DOw//Az8P/wM/D/8DPw//Az8P/ + wM/E/8DPxP/Az8T/wM/E/8DPxP/Az8T/wM/E/8DPxP+2yLr/tsi6/7bIuv+2yLr/hKOL/4Sji/+Eo4v/ + hKOL/3mbgv95m4L/eZuC/3mbgv95m4L/eZuC/3mbgv95m4L/eZyC/3mcgv95nIL/eZyC/3mdgv95nYL/ + eZ2C/3mdgv96nYP/ep2D/3qdg/96nYP/ep6D/3qeg/96noP/ep6D/4Cypf+AsqX/gLKl/4Cypf+J1vv/ + idb7/4nW+/+J1vv/dKyc/3SsnP90rJz/dKyc/zSGSv80hkr/NIZK/zSGSv8wikf/MIpH/zCKR/8wikf/ + MIpH/zCKR/8wikf/MIpH/4e8lf+HvJX/h7yV/4e8lf+HvJX/h7yV/4e8lf+HvJX/h7yV/4e8lf+HvJX/ + h7yV/4i/oP+Iv6D/iL+g/4i/oP+M1vX/jNb1/4zW9f+M1vX/jdj6/43Y+v+N2Pr/jdj6/4rM2/+KzNv/ + iszb/4rM2/+Fu7v/hbu7/4W7u/+Fu7v/gKmc/4CpnP+AqZz/gKmc/3uYg/97mIP/e5iD/3uYg/96l4L/ + epeC/3qXgv96l4L/e5eC/3uXgv97l4L/e5eC/3uYgv97mIL/e5iC/3uYgv97mIL/e5iC/3uYgv97mIL/ + e5mD/3uZg/97mYP/e5mD/3uZg/97mYP/e5mD/3uZg/98moP/fJqD/3yag/98moP/fJuE/3ybhP98m4T/ + fJuE/3ychP98nIT/fJyE/3ychP98nIX/fJyF/3ychf98nIX/fJ2F/3ydhf98nYX/fJ2F/32dhf99nYX/ + fZ2F/32dhf9+oIf/fqCH/36gh/9+oIf/gq6g/4KuoP+CrqD/gq6g/4a/vP+Gv7z/hr+8/4a/vP+Kzdz/ + is3c/4rN3P+Kzdz/jdj6/43Y+v+N2Pr/jdj6/43W9f+N1vX/jdb1/43W9f+HvqH/h76h/4e+of+HvqH/ + drKF/3ayhf92soX/drKF/zOMSv8zjEr/M4xK/zOMSv8xi0j/MYtI/zGLSP8xi0j/h7yV/4e8lf+HvJX/ + h7yV/4e8lf+HvJX/h7yV/4e8lf+HvJX/h7yV/4e8lf+HvJX/iL+g/4i/oP+Iv6D/iL+g/4zW9f+M1vX/ + jNb1/4zW9f+N2Pr/jdj6/43Y+v+N2Pr/iszb/4rM2/+KzNv/iszb/4W7u/+Fu7v/hbu7/4W7u/+AqZz/ + gKmc/4CpnP+AqZz/e5iD/3uYg/97mIP/e5iD/3qXgv96l4L/epeC/3qXgv97l4L/e5eC/3uXgv97l4L/ + e5iC/3uYgv97mIL/e5iC/3uYgv97mIL/e5iC/3uYgv97mYP/e5mD/3uZg/97mYP/e5mD/3uZg/97mYP/ + e5mD/3yag/98moP/fJqD/3yag/98m4T/fJuE/3ybhP98m4T/fJyE/3ychP98nIT/fJyE/3ychf98nIX/ + fJyF/3ychf98nYX/fJ2F/3ydhf98nYX/fZ2F/32dhf99nYX/fZ2F/36gh/9+oIf/fqCH/36gh/+CrqD/ + gq6g/4KuoP+CrqD/hr+8/4a/vP+Gv7z/hr+8/4rN3P+Kzdz/is3c/4rN3P+N2Pr/jdj6/43Y+v+N2Pr/ + jdb1/43W9f+N1vX/jdb1/4e+of+HvqH/h76h/4e+of92soX/drKF/3ayhf92soX/M4xK/zOMSv8zjEr/ + M4xK/zGLSP8xi0j/MYtI/zGLSP+HvJX/h7yV/4e8lf+HvJX/h7yV/4e8lf+HvJX/h7yV/4e8lf+HvJX/ + h7yV/4e8lf+Iv6D/iL+g/4i/oP+Iv6D/jNb1/4zW9f+M1vX/jNb1/43Y+v+N2Pr/jdj6/43Y+v+KzNv/ + iszb/4rM2/+KzNv/hbu7/4W7u/+Fu7v/hbu7/4CpnP+AqZz/gKmc/4CpnP97mIP/e5iD/3uYg/97mIP/ + epeC/3qXgv96l4L/epeC/3uXgv97l4L/e5eC/3uXgv97mIL/e5iC/3uYgv97mIL/e5iC/3uYgv97mIL/ + e5iC/3uZg/97mYP/e5mD/3uZg/97mYP/e5mD/3uZg/97mYP/fJqD/3yag/98moP/fJqD/3ybhP98m4T/ + fJuE/3ybhP98nIT/fJyE/3ychP98nIT/fJyF/3ychf98nIX/fJyF/3ydhf98nYX/fJ2F/3ydhf99nYX/ + fZ2F/32dhf99nYX/fqCH/36gh/9+oIf/fqCH/4KuoP+CrqD/gq6g/4KuoP+Gv7z/hr+8/4a/vP+Gv7z/ + is3c/4rN3P+Kzdz/is3c/43Y+v+N2Pr/jdj6/43Y+v+N1vX/jdb1/43W9f+N1vX/h76h/4e+of+HvqH/ + h76h/3ayhf92soX/drKF/3ayhf8zjEr/M4xK/zOMSv8zjEr/MYtI/zGLSP8xi0j/MYtI/4e8lf+HvJX/ + h7yV/4e8lf+HvJX/h7yV/4e8lf+HvJX/h7yV/4e8lf+HvJX/h7yV/4i/oP+Iv6D/iL+g/4i/oP+M1vX/ + jNb1/4zW9f+M1vX/jdj6/43Y+v+N2Pr/jdj6/4rM2/+KzNv/iszb/4rM2/+Fu7v/hbu7/4W7u/+Fu7v/ + gKmc/4CpnP+AqZz/gKmc/3uYg/97mIP/e5iD/3uYg/96l4L/epeC/3qXgv96l4L/e5eC/3uXgv97l4L/ + e5eC/3uYgv97mIL/e5iC/3uYgv97mIL/e5iC/3uYgv97mIL/e5mD/3uZg/97mYP/e5mD/3uZg/97mYP/ + e5mD/3uZg/98moP/fJqD/3yag/98moP/fJuE/3ybhP98m4T/fJuE/3ychP98nIT/fJyE/3ychP98nIX/ + fJyF/3ychf98nIX/fJ2F/3ydhf98nYX/fJ2F/32dhf99nYX/fZ2F/32dhf9+oIf/fqCH/36gh/9+oIf/ + gq6g/4KuoP+CrqD/gq6g/4a/vP+Gv7z/hr+8/4a/vP+Kzdz/is3c/4rN3P+Kzdz/jdj6/43Y+v+N2Pr/ + jdj6/43W9f+N1vX/jdb1/43W9f+HvqH/h76h/4e+of+HvqH/drKF/3ayhf92soX/drKF/zOMSv8zjEr/ + M4xK/zOMSv8xi0j/MYtI/zGLSP8xi0j/ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ + ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/4rBof+KwaH/isGh/4rBof+NysX/jcrF/43Kxf+NysX/ + jtPk/47T5P+O0+T/jtPk/4/Z+v+P2fr/j9n6/4/Z+v+P2fr/j9n6/4/Z+v+P2fr/j9j4/4/Y+P+P2Pj/ + j9j4/47U7P+O1Oz/jtTs/47U7P+Nz93/jc/d/43P3f+Nz93/i8fO/4vHzv+Lx87/i8fO/4rEx/+KxMf/ + isTH/4rEx/+JwcH/icHB/4nBwf+JwcH/ib68/4m+vP+Jvrz/ib68/4m/vP+Jv7z/ib+8/4m/vP+JwsL/ + icLC/4nCwv+JwsL/isTH/4rEx/+KxMf/isTH/4vJz/+Lyc//i8nP/4vJz/+Nz93/jc/d/43P3f+Nz93/ + jtTs/47U7P+O1Oz/jtTs/4/Y+P+P2Pj/j9j4/4/Y+P+P2fr/j9n6/4/Z+v+P2fr/j9n6/4/Z+v+P2fr/ + j9n6/47T5v+O0+b/jtPm/47T5v+My8j/jMvI/4zLyP+My8j/i8Ch/4vAof+LwKH/i8Ch/4q+mP+Kvpj/ + ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/Z6t4/2ereP9nq3j/Z6t4/zKNSf8yjUn/Mo1J/zKNSf+Kvpj/ + ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ + isGh/4rBof+KwaH/isGh/43Kxf+NysX/jcrF/43Kxf+O0+T/jtPk/47T5P+O0+T/j9n6/4/Z+v+P2fr/ + j9n6/4/Z+v+P2fr/j9n6/4/Z+v+P2Pj/j9j4/4/Y+P+P2Pj/jtTs/47U7P+O1Oz/jtTs/43P3f+Nz93/ + jc/d/43P3f+Lx87/i8fO/4vHzv+Lx87/isTH/4rEx/+KxMf/isTH/4nBwf+JwcH/icHB/4nBwf+Jvrz/ + ib68/4m+vP+Jvrz/ib+8/4m/vP+Jv7z/ib+8/4nCwv+JwsL/icLC/4nCwv+KxMf/isTH/4rEx/+KxMf/ + i8nP/4vJz/+Lyc//i8nP/43P3f+Nz93/jc/d/43P3f+O1Oz/jtTs/47U7P+O1Oz/j9j4/4/Y+P+P2Pj/ + j9j4/4/Z+v+P2fr/j9n6/4/Z+v+P2fr/j9n6/4/Z+v+P2fr/jtPm/47T5v+O0+b/jtPm/4zLyP+My8j/ + jMvI/4zLyP+LwKH/i8Ch/4vAof+LwKH/ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/4q+mP9nq3j/ + Z6t4/2ereP9nq3j/Mo1J/zKNSf8yjUn/Mo1J/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ + ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+KwaH/isGh/4rBof+KwaH/jcrF/43Kxf+NysX/ + jcrF/47T5P+O0+T/jtPk/47T5P+P2fr/j9n6/4/Z+v+P2fr/j9n6/4/Z+v+P2fr/j9n6/4/Y+P+P2Pj/ + j9j4/4/Y+P+O1Oz/jtTs/47U7P+O1Oz/jc/d/43P3f+Nz93/jc/d/4vHzv+Lx87/i8fO/4vHzv+KxMf/ + isTH/4rEx/+KxMf/icHB/4nBwf+JwcH/icHB/4m+vP+Jvrz/ib68/4m+vP+Jv7z/ib+8/4m/vP+Jv7z/ + icLC/4nCwv+JwsL/icLC/4rEx/+KxMf/isTH/4rEx/+Lyc//i8nP/4vJz/+Lyc//jc/d/43P3f+Nz93/ + jc/d/47U7P+O1Oz/jtTs/47U7P+P2Pj/j9j4/4/Y+P+P2Pj/j9n6/4/Z+v+P2fr/j9n6/4/Z+v+P2fr/ + j9n6/4/Z+v+O0+b/jtPm/47T5v+O0+b/jMvI/4zLyP+My8j/jMvI/4vAof+LwKH/i8Ch/4vAof+Kvpj/ + ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/2ereP9nq3j/Z6t4/2ereP8yjUn/Mo1J/zKNSf8yjUn/ + ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ + ir6Y/4rBof+KwaH/isGh/4rBof+NysX/jcrF/43Kxf+NysX/jtPk/47T5P+O0+T/jtPk/4/Z+v+P2fr/ + j9n6/4/Z+v+P2fr/j9n6/4/Z+v+P2fr/j9j4/4/Y+P+P2Pj/j9j4/47U7P+O1Oz/jtTs/47U7P+Nz93/ + jc/d/43P3f+Nz93/i8fO/4vHzv+Lx87/i8fO/4rEx/+KxMf/isTH/4rEx/+JwcH/icHB/4nBwf+JwcH/ + ib68/4m+vP+Jvrz/ib68/4m/vP+Jv7z/ib+8/4m/vP+JwsL/icLC/4nCwv+JwsL/isTH/4rEx/+KxMf/ + isTH/4vJz/+Lyc//i8nP/4vJz/+Nz93/jc/d/43P3f+Nz93/jtTs/47U7P+O1Oz/jtTs/4/Y+P+P2Pj/ + j9j4/4/Y+P+P2fr/j9n6/4/Z+v+P2fr/j9n6/4/Z+v+P2fr/j9n6/47T5v+O0+b/jtPm/47T5v+My8j/ + jMvI/4zLyP+My8j/i8Ch/4vAof+LwKH/i8Ch/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ + Z6t4/2ereP9nq3j/Z6t4/zKNSf8yjUn/Mo1J/zKNSf+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcKj/43Co/+NwqP/jcKj/4/Iuf+PyLn/j8i5/4/Iuf+Pzcn/ + j83J/4/Nyf+Pzcn/kNHZ/5DR2f+Q0dn/kNHZ/5HV6P+R1ej/kdXo/5HV6P+R1/L/kdfy/5HX8v+R1/L/ + kdn2/5HZ9v+R2fb/kdn2/5La+v+S2vr/ktr6/5La+v+S2vv/ktr7/5La+/+S2vv/ktr7/5La+/+S2vv/ + ktr7/5La+v+S2vr/ktr6/5La+v+R2fb/kdn2/5HZ9v+R2fb/kdfy/5HX8v+R1/L/kdfy/5HV6P+R1ej/ + kdXo/5HV6P+Q0dj/kNHY/5DR2P+Q0dj/j8zI/4/MyP+PzMj/j8zI/4/Iuf+PyLn/j8i5/4/Iuf+NwqP/ + jcKj/43Co/+NwqP/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/VKFp/1Shaf9UoWn/ + VKFp/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwqP/ + jcKj/43Co/+NwqP/j8i5/4/Iuf+PyLn/j8i5/4/Nyf+Pzcn/j83J/4/Nyf+Q0dn/kNHZ/5DR2f+Q0dn/ + kdXo/5HV6P+R1ej/kdXo/5HX8v+R1/L/kdfy/5HX8v+R2fb/kdn2/5HZ9v+R2fb/ktr6/5La+v+S2vr/ + ktr6/5La+/+S2vv/ktr7/5La+/+S2vv/ktr7/5La+/+S2vv/ktr6/5La+v+S2vr/ktr6/5HZ9v+R2fb/ + kdn2/5HZ9v+R1/L/kdfy/5HX8v+R1/L/kdXo/5HV6P+R1ej/kdXo/5DR2P+Q0dj/kNHY/5DR2P+PzMj/ + j8zI/4/MyP+PzMj/j8i5/4/Iuf+PyLn/j8i5/43Co/+NwqP/jcKj/43Co/+NwJv/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwJv/jcCb/43Am/9UoWn/VKFp/1Shaf9UoWn/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Co/+NwqP/jcKj/43Co/+PyLn/j8i5/4/Iuf+PyLn/ + j83J/4/Nyf+Pzcn/j83J/5DR2f+Q0dn/kNHZ/5DR2f+R1ej/kdXo/5HV6P+R1ej/kdfy/5HX8v+R1/L/ + kdfy/5HZ9v+R2fb/kdn2/5HZ9v+S2vr/ktr6/5La+v+S2vr/ktr7/5La+/+S2vv/ktr7/5La+/+S2vv/ + ktr7/5La+/+S2vr/ktr6/5La+v+S2vr/kdn2/5HZ9v+R2fb/kdn2/5HX8v+R1/L/kdfy/5HX8v+R1ej/ + kdXo/5HV6P+R1ej/kNHY/5DR2P+Q0dj/kNHY/4/MyP+PzMj/j8zI/4/MyP+PyLn/j8i5/4/Iuf+PyLn/ + jcKj/43Co/+NwqP/jcKj/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/1Shaf9UoWn/ + VKFp/1Shaf+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/ + jcKj/43Co/+NwqP/jcKj/4/Iuf+PyLn/j8i5/4/Iuf+Pzcn/j83J/4/Nyf+Pzcn/kNHZ/5DR2f+Q0dn/ + kNHZ/5HV6P+R1ej/kdXo/5HV6P+R1/L/kdfy/5HX8v+R1/L/kdn2/5HZ9v+R2fb/kdn2/5La+v+S2vr/ + ktr6/5La+v+S2vv/ktr7/5La+/+S2vv/ktr7/5La+/+S2vv/ktr7/5La+v+S2vr/ktr6/5La+v+R2fb/ + kdn2/5HZ9v+R2fb/kdfy/5HX8v+R1/L/kdfy/5HV6P+R1ej/kdXo/5HV6P+Q0dj/kNHY/5DR2P+Q0dj/ + j8zI/4/MyP+PzMj/j8zI/4/Iuf+PyLn/j8i5/4/Iuf+NwqP/jcKj/43Co/+NwqP/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/VKFp/1Shaf9UoWn/VKFp/4zAmvGMwJrxjMCa8YzAmvGQwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKe/5DCnv+Qwp7/kMKe/5DEo/+QxKP/kMSj/5DEo/+QxKL/ + kMSi/5DEov+QxKL/kMKe/5DCnv+Qwp7/kMKe/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+NwZrx + jcGa8Y3BmvGNwZrxjMCa8YzAmvGMwJrxjMCa8ZDCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp7/ + kMKe/5DCnv+Qwp7/kMSj/5DEo/+QxKP/kMSj/5DEov+QxKL/kMSi/5DEov+Qwp7/kMKe/5DCnv+Qwp7/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/43BmvGNwZrxjcGa8Y3BmvGMwJrxjMCa8YzAmvGMwJrx + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnv+Qwp7/kMKe/5DCnv+QxKP/kMSj/5DEo/+QxKP/ + kMSi/5DEov+QxKL/kMSi/5DCnv+Qwp7/kMKe/5DCnv+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + jcGa8Y3BmvGNwZrxjcGa8YzAmvGMwJrxjMCa8YzAmvGQwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKe/5DCnv+Qwp7/kMKe/5DEo/+QxKP/kMSj/5DEo/+QxKL/kMSi/5DEov+QxKL/kMKe/5DCnv+Qwp7/ + kMKe/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+NwZrxjcGa8Y3BmvGNwZrxhr6XxIa+l8SGvpfE + hr6XxJTFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/4/CncaPwp3Gj8Kdxo/CncaGvpfEhr6XxIa+l8SGvpfElMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/j8Kdxo/CncaPwp3Gj8Kdxoa+l8SGvpfE + hr6XxIa+l8SUxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+Pwp3Gj8Kdxo/CncaPwp3Ghr6XxIa+l8SGvpfEhr6XxJTFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/4/CncaPwp3Gj8Kdxo/CncZ8u48p + fLuPKXy7jyl8u48pk8ag9ZPGoPWTxqD1k8ag9ZbHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+YyKX2 + mMil9pjIpfaYyKX2mceoMpnHqDKZx6gymceoMny7jyl8u48pfLuPKXy7jymTxqD1k8ag9ZPGoPWTxqD1 + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5jIpfaYyKX2mMil9pjIpfaZx6gymceoMpnHqDKZx6gy + fLuPKXy7jyl8u48pfLuPKZPGoPWTxqD1k8ag9ZPGoPWWx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + mMil9pjIpfaYyKX2mMil9pnHqDKZx6gymceoMpnHqDJ8u48pfLuPKXy7jyl8u48pk8ag9ZPGoPWTxqD1 + k8ag9ZbHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+YyKX2mMil9pjIpfaYyKX2mceoMpnHqDKZx6gy + mceoMgAAAAAAAAAAAAAAAAAAAAB8u48pfLuPKXy7jyl8u48pjMKbxYzCm8WMwpvFjMKbxZbHo/KWx6Py + lsej8pbHo/KZyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+ayafzmsmn85rJp/OayafzlsaiyZbGosmWxqLJ + lsaiyZvIqjObyKozm8iqM5vIqjMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHy7jyl8u48p + fLuPKXy7jymMwpvFjMKbxYzCm8WMwpvFlsej8pbHo/KWx6Pylsej8pnJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5rJp/Oayafzmsmn85rJp/OWxqLJlsaiyZbGosmWxqLJm8iqM5vIqjObyKozm8iqMwAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfLuPKXy7jyl8u48pfLuPKYzCm8WMwpvFjMKbxYzCm8WWx6Py + lsej8pbHo/KWx6Pymcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/msmn85rJp/Oayafzmsmn85bGosmWxqLJ + lsaiyZbGosmbyKozm8iqM5vIqjObyKozAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB8u48p + fLuPKXy7jyl8u48pjMKbxYzCm8WMwpvFjMKbxZbHo/KWx6Pylsej8pbHo/KZyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+ayafzmsmn85rJp/OayafzlsaiyZbGosmWxqLJlsaiyZvIqjObyKozm8iqM5vIqjMAAAAA + AAAAAAAAAAAAAAAA8AAAAAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAAAP + 8AAAAAAAAAAAAAAAAAAADwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAPAAAAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAA + AAAAD/AAAAAAAAAAAAAAAAAAAA8oAAAAQAAAAIAAAAABACAAAAAAAABAAAATCwAAEwsAAAAAAAAAAAAA + AAAAAAAAAAAbZCQcG2QkHB1nJqkdZyapHGcm5xxnJuccZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/ + HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/ + HGcm/xxnJv8YWiH/GFoh/xZSHv8WUh7/F1Mf/xdTH/8XVB//F1Qf/xdUH/8XVB//F1Yg/xdWIP8XViD/ + F1Yg/xhXIP8YVyD/GFgg/xhYIP8YWSH/GFkh/xhaIf8YWiH/GVoh/xlaIf8YXCLpGFwi6RpcIq8aXCKv + GVohHxlaIR8AAAAAAAAAAAAAAAAAAAAAG2QkHBtkJBwdZyapHWcmqRxnJuccZybnHGcm/xxnJv8cZyb/ + HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/ + HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/GFoh/xhaIf8WUh7/FlIe/xdTH/8XUx//F1Qf/xdUH/8XVB// + F1Qf/xdWIP8XViD/F1Yg/xdWIP8YVyD/GFcg/xhYIP8YWCD/GFkh/xhZIf8YWiH/GFoh/xlaIf8ZWiH/ + GFwi6RhcIukaXCKvGlwirxlaIR8ZWiEfAAAAAAAAAAAbZCQcG2QkHB1oJ+0daCftHWgn/x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8ZWiL/GVoi/xdRHv8XUR7/F1If/xdSH/8XUx// + F1Mf/xdUH/8XVB//GFQg/xhUIP8YVSD/GFUg/xhWIP8YViD/GFch/xhXIf8ZWCH/GVgh/xlZIf8ZWSH/ + GVoi/xlaIv8ZWyL/GVsi/xlbIv8ZWyL/Glwj/xpcI/8aXSLvGl0i7xlaIR8ZWiEfG2QkHBtkJBwdaCft + HWgn7R1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/GVoi/xlaIv8XUR7/ + F1Ee/xdSH/8XUh//F1Mf/xdTH/8XVB//F1Qf/xhUIP8YVCD/GFUg/xhVIP8YViD/GFYg/xhXIf8YVyH/ + GVgh/xlYIf8ZWSH/GVkh/xlaIv8ZWiL/GVsi/xlbIv8ZWyL/GVsi/xpcI/8aXCP/Gl0i7xpdIu8ZWiEf + GVohHx5qKakeaimpHmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8aWyL/ + Glsi/xdRH/8XUR//F1If/xdSH/8XUx//F1Mf/xhUIP8YVCD/GFQg/xhUIP8YVSD/GFUg/xhWIP8YViD/ + GVch/xlXIf8ZWCH/GVgh/xlZIv8ZWSL/GVoi/xlaIv8aWyL/Glsi/xpbI/8aWyP/Glwj/xpcI/8aXSP/ + Gl0j/xteI/8bXiP/HF8krxxfJK8eaimpHmopqR5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Glsi/xpbIv8XUR//F1Ef/xdSH/8XUh//F1Mf/xdTH/8YVCD/GFQg/xhUIP8YVCD/ + GFUg/xhVIP8YViD/GFYg/xlXIf8ZVyH/GVgh/xlYIf8ZWSL/GVki/xlaIv8ZWiL/Glsi/xpbIv8aWyP/ + Glsj/xpcI/8aXCP/Gl0j/xpdI/8bXiP/G14j/xxfJK8cXySvH2sq6B9rKugfayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8aWyT/Glsk/xdQH/8XUB//Hmlg/x5pYP8eamD/Hmpg/xhTIP8YUyD/ + GFQh/xhUIf8YVCH/GFQh/xlVIf8ZVSH/GVYi/xlWIv8ZVyL/GVci/xlYIv8ZWCL/Glkj/xpZI/8aWiP/ + Gloj/xpbJP8aWyT/G1sk/xtbJP8bXCT/G1wk/xtdJf8bXSX/G14l/xteJf8bXyXpG18l6R9rKugfayro + H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/Glsk/xpbJP8XUB//F1Af/x5pYP8eaWD/ + Hmpg/x5qYP8YUyD/GFMg/xhUIf8YVCH/GFQh/xhUIf8ZVSH/GVUh/xlWIv8ZViL/GVci/xlXIv8ZWCL/ + GVgi/xpZI/8aWSP/Gloj/xpaI/8aWyT/Glsk/xtbJP8bWyT/G1wk/xtcJP8bXSX/G10l/xteJf8bXiX/ + G18l6RtfJekgbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8bWyT/G1sk/x5oWv8eaFr/ + JYKy/yWCsv8pk9//KZPf/ymT3/8pk9//JYKu/yWCrv8eZ1T/HmdU/xlVIv8ZVSL/GVYi/xlWIv8ZVyL/ + GVci/xpYI/8aWCP/Glgj/xpYI/8aWSP/Glkj/xtbJP8bWyT/G1sk/xtbJP8bXCT/G1wk/xtdJf8bXSX/ + HF4l/xxeJf8cXyX/HF8l/xxgJv8cYCb/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + G1sk/xtbJP8eaFr/Hmha/yWCsv8lgrL/KZPf/ymT3/8pk9//KZPf/yWCrv8lgq7/HmdU/x5nVP8ZVSL/ + GVUi/xlWIv8ZViL/GVci/xlXIv8aWCP/Glgj/xpYI/8aWCP/Glkj/xpZI/8bWyT/G1sk/xtbJP8bWyT/ + G1wk/xtcJP8bXSX/G10l/xxeJf8cXiX/HF8l/xxfJf8cYCb/HGAm/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/yBuLf8dZUD/HWVA/ySBp/8kgaf/KZTf/ymU3/8upPf/LqT3/y+o/f8vqP3/L6j9/y+o/f8upPf/ + LqT3/ymU3/8plN//JICl/ySApf8cYkL/HGJC/xlXI/8ZVyP/GVgk/xlYJP8aWCT/Glgk/xpZJf8aWSX/ + Glol/xpaJf8bWyX/G1sl/xtcJv8bXCb/G10m/xtdJv8bXib/G14m/xxfJ/8cXyf/HGAn/xxgJ/8gbi3/ + IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/HWVA/x1lQP8kgaf/JIGn/ymU3/8plN//LqT3/y6k9/8vqP3/ + L6j9/y+o/f8vqP3/LqT3/y6k9/8plN//KZTf/ySApf8kgKX/HGJC/xxiQv8ZVyP/GVcj/xlYJP8ZWCT/ + Glgk/xpYJP8aWSX/Glkl/xpaJf8aWiX/G1sl/xtbJf8bXCb/G1wm/xtdJv8bXSb/G14m/xteJv8cXyf/ + HF8n/xxgJ/8cYCf/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/ + IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXEv/yFxL/8kfH7/JHx+/ymR1P8pkdT/L6X2/y+l9v8wqfz/ + MKn8/yybzf8sm83/IG5a/yBuWv8gbFj/IGxY/yyazP8smsz/MKn8/zCp/P8vpfb/L6X2/yqR1P8qkdT/ + IHRx/yB0cf8aWCT/Glgk/xpZJf8aWSX/G1ol/xtaJf8bWyX/G1sl/xtcJv8bXCb/G10m/xtdJv8cXif/ + HF4n/xxfJ/8cXyf/HGAn/xxgJ/8cYSj/HGEo/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/ + IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFxL/8hcS//JHx+/yR8fv8pkdT/ + KZHU/y+l9v8vpfb/MKn8/zCp/P8sm83/LJvN/yBuWv8gblr/IGxY/yBsWP8smsz/LJrM/zCp/P8wqfz/ + L6X2/y+l9v8qkdT/KpHU/yB0cf8gdHH/Glgk/xpYJP8aWSX/Glkl/xtaJf8bWiX/G1sl/xtbJf8bXCb/ + G1wm/xtdJv8bXSb/HF4n/xxeJ/8cXyf/HF8n/xxgJ/8cYCf/HGEo/xxhKP8icS//InEv/yJxL/8icS// + InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//I3Q7/yN0O/8nh6r/ + J4eq/y2f7P8tn+z/MKr8/zCq/P8un9j/Lp/Y/yFyZv8hcmb/GFEi/xhRIv8ZUiL/GVIi/xlTIv8ZUyL/ + GVQj/xlUI/8idGf/InRn/y6f2P8un9j/MKr8/zCq/P8tn+z/LZ/s/yWEo/8lhKP/HF4z/xxeM/8bWiX/ + G1ol/xtbJv8bWyb/HFwm/xxcJv8cXSf/HF0n/xxeJ/8cXif/HV8n/x1fJ/8dYCj/HWAo/x1hKP8dYSj/ + InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS// + InEv/yN0O/8jdDv/J4eq/yeHqv8tn+z/LZ/s/zCq/P8wqvz/Lp/Y/y6f2P8hcmb/IXJm/xhRIv8YUSL/ + GVIi/xlSIv8ZUyL/GVMi/xlUI/8ZVCP/InRn/yJ0Z/8un9j/Lp/Y/zCq/P8wqvz/LZ/s/y2f7P8lhKP/ + JYSj/xxeM/8cXjP/G1ol/xtaJf8bWyb/G1sm/xxcJv8cXCb/HF0n/xxdJ/8cXif/HF4n/x1fJ/8dXyf/ + HWAo/x1gKP8dYSj/HWEo/yx4Ov8seDr/JXMz/yVzM/8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/ + I3Ix/yNyMf8jcjH/JHQ8/yR0PP8pj73/KY+9/zCp+f8wqfn/MKj0/zCo9P8mgYn/JoGJ/xlQJf8ZUCX/ + GFAi/xhQIv8ZUCP/GVAj/xlSI/8ZUiP/GVMk/xlTJP8aVCT/GlQk/xpUJP8aVCT/G1co/xtXKP8nhY3/ + J4WN/zCq9v8wqvb/MKn5/zCp+f8pjr3/KY69/x1fM/8dXzP/HFsn/xxbJ/8cXCf/HFwn/xxdKP8cXSj/ + HV0o/x1dKP8dXyn/HV8p/x1gKf8dYCn/HmEq/x5hKv8seDr/LHg6/yVzM/8lczP/I3Ix/yNyMf8jcjH/ + I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yR0PP8kdDz/KY+9/ymPvf8wqfn/MKn5/zCo9P8wqPT/ + JoGJ/yaBif8ZUCX/GVAl/xhQIv8YUCL/GVAj/xlQI/8ZUiP/GVIj/xlTJP8ZUyT/GlQk/xpUJP8aVCT/ + GlQk/xtXKP8bVyj/J4WN/yeFjf8wqvb/MKr2/zCp+f8wqfn/KY69/ymOvf8dXzP/HV8z/xxbJ/8cWyf/ + HFwn/xxcJ/8cXSj/HF0o/x1dKP8dXSj/HV8p/x1fKf8dYCn/HWAp/x5hKv8eYSr/UpFd/1KRXf9SkV3/ + UpFd/0mLVf9Ji1X/PoRK/z6ESv8zfkD/M35A/yh3Nv8odzb/JHY7/yR2O/8qk8D/KpPA/zGr+/8xq/v/ + Lp3N/y6dzf8dYEL/HWBC/xhOIv8YTiL/GU8i/xlPIv8ZUCP/GVAj/xlRI/8ZUSP/GVIj/xlSI/8aUyT/ + GlMk/xpUJP8aVCT/GlUl/xpVJf8bViX/G1Yl/xtXJf8bVyX/IGhJ/yBoSf8uoNP/LqDT/zGr+/8xq/v/ + KpPA/yqTwP8eYDL/HmAy/x1cKP8dXCj/HV0o/x1dKP8dXin/HV4p/x5fKf8eXyn/HmAq/x5gKv8eYSr/ + HmEq/1KRXf9SkV3/UpFd/1KRXf9Ji1X/SYtV/z6ESv8+hEr/M35A/zN+QP8odzb/KHc2/yR2O/8kdjv/ + KpPA/yqTwP8xq/v/Mav7/y6dzf8unc3/HWBC/x1gQv8YTiL/GE4i/xlPIv8ZTyL/GVAj/xlQI/8ZUSP/ + GVEj/xlSI/8ZUiP/GlMk/xpTJP8aVCT/GlQk/xpVJf8aVSX/G1Yl/xtWJf8bVyX/G1cl/yBoSf8gaEn/ + LqDT/y6g0/8xq/v/Mav7/yqTwP8qk8D/HmAy/x5gMv8dXCj/HVwo/x1dKP8dXSj/HV4p/x1eKf8eXyn/ + Hl8p/x5gKv8eYCr/HmEq/x5hKv9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/ + VpRh/1aUYf9Uprn/VKa5/0m2+/9Jtvv/NZy9/zWcvf9ZfV3/WX1d/2KDYv9ig2L/Y4Ni/2ODYv9jhGL/ + Y4Ri/2OFYv9jhWL/Y4Vi/2OFYv9jhmP/Y4Zj/2OHY/9jh2P/ZIdk/2SHZP9kiGT/ZIhk/2SJZP9kiWT/ + ZIlk/2SJZP9limT/ZYpk/1qFYv9ahWL/MJvC/zCbwv8yrfv/Mq37/yqQqf8qkKn/HVwo/x1cKP8dXSn/ + HV0p/x5eKf8eXin/Hl8p/x5fKf8eYCr/HmAq/x9iK/8fYiv/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/ + VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VKa5/1Smuf9Jtvv/Sbb7/zWcvf81nL3/WX1d/1l9Xf9ig2L/ + YoNi/2ODYv9jg2L/Y4Ri/2OEYv9jhWL/Y4Vi/2OFYv9jhWL/Y4Zj/2OGY/9jh2P/Y4dj/2SHZP9kh2T/ + ZIhk/2SIZP9kiWT/ZIlk/2SJZP9kiWT/ZYpk/2WKZP9ahWL/WoVi/zCbwv8wm8L/Mq37/zKt+/8qkKn/ + KpCp/x1cKP8dXCj/HV0p/x1dKf8eXin/Hl4p/x5fKf8eXyn/HmAq/x5gKv8fYiv/H2Ir/1iXZf9Yl2X/ + WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/WJdl/1iXZf9bn4j/W5+I/2LA+v9iwPr/XrHN/16xzf/O1Mb/ + ztTG/9fZzf/X2c3/xMq6/8TKuv+/xrT/v8a0/7/Gs/+/xrP/v8az/7/Gs/+/xrP/v8az/7/HtP+/x7T/ + v8e0/7/HtP+/x7T/v8e0/7/HtP+/x7T/v8i0/7/ItP+/yLT/v8i0/7/ItP+/yLT/zdLC/83Swv++ybb/ + vsm2/y6dw/8uncP/Mq36/zKt+v8jdV7/I3Ve/x1eKv8dXir/HV8q/x1fKv8eYCv/HmAr/x5hK/8eYSv/ + HmIs/x5iLP9Yl2X/WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/W5+I/1ufiP9iwPr/ + YsD6/16xzf9esc3/ztTG/87Uxv/X2c3/19nN/8TKuv/Eyrr/v8a0/7/GtP+/xrP/v8az/7/Gs/+/xrP/ + v8az/7/Gs/+/x7T/v8e0/7/HtP+/x7T/v8e0/7/HtP+/x7T/v8e0/7/ItP+/yLT/v8i0/7/ItP+/yLT/ + v8i0/83Swv/N0sL/vsm2/77Jtv8uncP/Lp3D/zKt+v8yrfr/I3Ve/yN1Xv8dXir/HV4q/x1fKv8dXyr/ + HmAr/x5gK/8eYSv/HmEr/x5iLP8eYiz/XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/ + XJpo/2W73/9lu9//Zb/t/2W/7f9UgGb/VIBm//v07f/79O3/X4Jk/1+CZP9Selr/Unpa/1B4WP9QeFj/ + PGpF/zxqRf8gVSv/IFUr/xpRJP8aUST/J1sx/ydbMf8nXDH/J1wx/xtUJv8bVCb/G1Um/xtVJv8bVif/ + G1Yn/xxXJ/8cVyf/HFgo/xxYKP8sZDX/LGQ1//nw5//58Of/IGU+/yBlPv8yquv/Mqrr/zGk1/8xpNf/ + Hl4q/x5eKv8eXyv/Hl8r/x5gK/8eYCv/H2Ar/x9gK/8fYiz/H2Is/1yaaP9cmmj/XJpo/1yaaP9cmmj/ + XJpo/1yaaP9cmmj/XJpo/1yaaP9lu9//Zbvf/2W/7f9lv+3/VIBm/1SAZv/79O3/+/Tt/1+CZP9fgmT/ + Unpa/1J6Wv9QeFj/UHhY/zxqRf88akX/IFUr/yBVK/8aUST/GlEk/ydbMf8nWzH/J1wx/ydcMf8bVCb/ + G1Qm/xtVJv8bVSb/G1Yn/xtWJ/8cVyf/HFcn/xxYKP8cWCj/LGQ1/yxkNf/58Of/+fDn/yBlPv8gZT7/ + Mqrr/zKq6/8xpNf/MaTX/x5eKv8eXir/Hl8r/x5fK/8eYCv/HmAr/x9gK/8fYCv/H2Is/x9iLP9gnWz/ + YJ1s/2CdbP9gnWz/YJ1s/2CdbP9gnWz/YJ1s/2Gjg/9ho4P/acX8/2nF/P9goKH/YKCh/1V6XP9Velz/ + +/Xw//v18P9fg2b/X4Nm/1V9Xv9VfV7/VX1e/1V9Xv9VfV7/VX1e/1R9Xf9UfV3/PGtF/zxrRf+Qp47/ + kKeO/4+mjP+Ppoz/G1Qn/xtUJ/8bVSf/G1Un/xxWKP8cVij/HFgo/xxYKP8cWSn/HFkp/ytiNf8rYjX/ + +vLq//ry6v8dWyr/HVsq/ymIh/8piIf/M7D7/zOw+/8jcFD/I3BQ/x5fLP8eXyz/H2As/x9gLP8fYS3/ + H2Et/yBjLf8gYy3/YJ1s/2CdbP9gnWz/YJ1s/2CdbP9gnWz/YJ1s/2CdbP9ho4P/YaOD/2nF/P9pxfz/ + YKCh/2Cgof9Velz/VXpc//v18P/79fD/X4Nm/1+DZv9VfV7/VX1e/1V9Xv9VfV7/VX1e/1V9Xv9UfV3/ + VH1d/zxrRf88a0X/kKeO/5Cnjv+Ppoz/j6aM/xtUJ/8bVCf/G1Un/xtVJ/8cVij/HFYo/xxYKP8cWCj/ + HFkp/xxZKf8rYjX/K2I1//ry6v/68ur/HVsq/x1bKv8piIf/KYiH/zOw+/8zsPv/I3BQ/yNwUP8eXyz/ + Hl8s/x9gLP8fYCz/H2Et/x9hLf8gYy3/IGMt/2Ofb/9jn2//Y59v/2Ofb/9jn2//Y59v/2Ofb/9jn2// + Z7O0/2eztP9rxff/a8X3/1mBav9ZgWr/V3xf/1d8X//89vH//Pbx/2KEaf9ihGn/WH5g/1h+YP9Yf2D/ + WH9g/1l/Yf9Zf2H/WYBh/1mAYf9ZgWL/WYFi/6+/rf+vv63/obSe/6G0nv8eVir/HlYq/xxVJ/8cVSf/ + HFYo/xxWKP8cVyj/HFco/x1YKf8dWCn/K2I1/ytiNf/78+z/+/Ps/x5bKv8eWyr/IGY9/yBmPf80sPf/ + NLD3/yuQl/8rkJf/H18s/x9fLP8fYCz/H2As/yBhLf8gYS3/IGIu/yBiLv9jn2//Y59v/2Ofb/9jn2// + Y59v/2Ofb/9jn2//Y59v/2eztP9ns7T/a8X3/2vF9/9ZgWr/WYFq/1d8X/9XfF///Pbx//z28f9ihGn/ + YoRp/1h+YP9YfmD/WH9g/1h/YP9Zf2H/WX9h/1mAYf9ZgGH/WYFi/1mBYv+vv63/r7+t/6G0nv+htJ7/ + HlYq/x5WKv8cVSf/HFUn/xxWKP8cVij/HFco/xxXKP8dWCn/HVgp/ytiNf8rYjX/+/Ps//vz7P8eWyr/ + Hlsq/yBmPf8gZj3/NLD3/zSw9/8rkJf/K5CX/x9fLP8fXyz/H2As/x9gLP8gYS3/IGEt/yBiLv8gYi7/ + Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9tvtf/bb7X/2y81/9svNf/W35i/1t+Yv9bf2P/ + W39j//z48//8+PP/Zods/2aHbP9cgWT/XIFk/1yBZP9cgWT/Zoht/2aIbf+wwK//sMCv/7LCsf+ywrH/ + 2d7U/9ne1P/Z3tT/2d7U/6/Arf+vwK3/m7Ka/5uymv8pXzT/KV80/x1XKP8dVyj/HVgp/x1YKf8rYzb/ + K2M2//v17v/79e7/Hlwr/x5cK/8eXSv/Hl0r/zGjy/8xo8v/MKLG/zCixv8fYCz/H2As/yBhLf8gYS3/ + IGIt/yBiLf8gYy7/IGMu/2ejc/9no3P/Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9no3P/bb7X/22+1/9svNf/ + bLzX/1t+Yv9bfmL/W39j/1t/Y//8+PP//Pjz/2aHbP9mh2z/XIFk/1yBZP9cgWT/XIFk/2aIbf9miG3/ + sMCv/7DAr/+ywrH/ssKx/9ne1P/Z3tT/2d7U/9ne1P+vwK3/r8Ct/5uymv+bspr/KV80/ylfNP8dVyj/ + HVco/x1YKf8dWCn/K2M2/ytjNv/79e7/+/Xu/x5cK/8eXCv/Hl0r/x5dK/8xo8v/MaPL/zCixv8wosb/ + H2As/x9gLP8gYS3/IGEt/yBiLf8gYi3/IGMu/yBjLv9qpXf/aqV3/2qld/9qpXf/aqV3/2qld/9qpXf/ + aqV3/3HG7P9xxuz/bLO//2yzv/9egGX/XoBl/16BZf9egWX//fn1//359f9oiW//aIlv/16DZ/9eg2f/ + XoNn/16DZ/9oinD/aIpw/7HBsf+xwbH/s8Oz/7PDs//b4Nb/2+DW/9vg1v/b4Nb/tMS0/7TEtP+yw7L/ + ssOy/1J+XP9Sflz/IFos/yBaLP8dWCr/HVgq/ytiNv8rYjb//Pbw//z28P8eWyz/Hlss/x5cLP8eXCz/ + Lpiq/y6Yqv80reX/NK3l/x9fLf8fXy3/H2Au/x9gLv8gYS7/IGEu/yBjL/8gYy//aqV3/2qld/9qpXf/ + aqV3/2qld/9qpXf/aqV3/2qld/9xxuz/ccbs/2yzv/9ss7//XoBl/16AZf9egWX/XoFl//359f/9+fX/ + aIlv/2iJb/9eg2f/XoNn/16DZ/9eg2f/aIpw/2iKcP+xwbH/scGx/7PDs/+zw7P/2+DW/9vg1v/b4Nb/ + 2+DW/7TEtP+0xLT/ssOy/7LDsv9Sflz/Un5c/yBaLP8gWiz/HVgq/x1YKv8rYjb/K2I2//z28P/89vD/ + Hlss/x5bLP8eXCz/Hlws/y6Yqv8umKr/NK3l/zSt5f8fXy3/H18t/x9gLv8fYC7/IGEu/yBhLv8gYy// + IGMv/22oev9tqHr/bah6/22oev9tqHr/bah6/22pf/9tqX//dMz7/3TM+/9rqaj/a6mo/2CCaP9ggmj/ + YINo/2CDaP/9+vb//fr2/2uLcv9ri3L/YYVp/2GFaf9ihmn/YoZp/2KGav9ihmr/Yodq/2KHav9jiGv/ + Y4hr/7XFtf+1xbX/tcW2/7XFtv9jimv/Y4pr/2OKbP9jimz/Y4ts/2OLbP9ahGT/WoRk/yxjOP8sYzj/ + K2I3/ytiN//89/L//Pfy/x5cLP8eXCz/Hl0s/x5dLP8rioj/K4qI/zW0+f81tPn/IWQ1/yFkNf8gYS7/ + IGEu/yBiL/8gYi//IWMv/yFjL/9tqHr/bah6/22oev9tqHr/bah6/22oev9tqX//bal//3TM+/90zPv/ + a6mo/2upqP9ggmj/YIJo/2CDaP9gg2j//fr2//369v9ri3L/a4ty/2GFaf9hhWn/YoZp/2KGaf9ihmr/ + YoZq/2KHav9ih2r/Y4hr/2OIa/+1xbX/tcW1/7XFtv+1xbb/Y4pr/2OKa/9jimz/Y4ps/2OLbP9ji2z/ + WoRk/1qEZP8sYzj/LGM4/ytiN/8rYjf//Pfy//z38v8eXCz/Hlws/x5dLP8eXSz/K4qI/yuKiP81tPn/ + NbT5/yFkNf8hZDX/IGEu/yBhLv8gYi//IGIv/yFjL/8hYy//cat+/3Grfv9xq37/cat+/3Grfv9xq37/ + cq+M/3KvjP94zfv/eM37/22loP9tpaD/ZIRr/2SEa/9khWv/ZIVr//36+P/9+vj/bo51/26Odf9liG3/ + ZYht/2WIbf9liG3/ZYlt/2WJbf9mim3/Zopt/2aKbv9mim7/tcW2/7XFtv+1xbb/tcW2/2eMb/9njG// + Z41v/2eNb/9njm//Z45v/2eOcP9njnD/Zo5u/2aObv9Me1b/THtW//z49P/8+PT/Hlss/x5bLP8fXSz/ + H10s/yqDd/8qg3f/NrX5/za1+f8jbUf/I21H/yBhLv8gYS7/IWIv/yFiL/8hYzD/IWMw/3Grfv9xq37/ + cat+/3Grfv9xq37/cat+/3KvjP9yr4z/eM37/3jN+/9tpaD/baWg/2SEa/9khGv/ZIVr/2SFa//9+vj/ + /fr4/26Odf9ujnX/ZYht/2WIbf9liG3/ZYht/2WJbf9liW3/Zopt/2aKbf9mim7/Zopu/7XFtv+1xbb/ + tcW2/7XFtv9njG//Z4xv/2eNb/9njW//Z45v/2eOb/9njnD/Z45w/2aObv9mjm7/THtW/0x7Vv/8+PT/ + /Pj0/x5bLP8eWyz/H10s/x9dLP8qg3f/KoN3/za1+f82tfn/I21H/yNtR/8gYS7/IGEu/yFiL/8hYi// + IWMw/yFjMP90rYH/dK2B/3Stgf90rYH/dK2B/3Stgf91spP/dbKT/3vP+/97z/v/cKWe/3Clnv9nhm7/ + Z4Zu/2eHb/9nh2///fr4//36+P9zknn/c5J5/2iKb/9oim//aIpw/2iKcP9pi3H/aYtx/2mMcf9pjHH/ + aYxx/2mMcf9ylHn/cpR5/3KUev9ylHr/aY5y/2mOcv9qj3P/ao9z/2qQc/9qkHP/apBz/2qQc/9rkXP/ + a5Fz/3WZff91mX3//fr3//369/8jXjD/I14w/x9cLf8fXC3/KYNz/ymDc/82tvn/Nrb5/yVxTf8lcU3/ + IWEv/yFhL/8hYjD/IWIw/yFkMf8hZDH/dK2B/3Stgf90rYH/dK2B/3Stgf90rYH/dbKT/3Wyk/97z/v/ + e8/7/3Clnv9wpZ7/Z4Zu/2eGbv9nh2//Z4dv//36+P/9+vj/c5J5/3OSef9oim//aIpv/2iKcP9oinD/ + aYtx/2mLcf9pjHH/aYxx/2mMcf9pjHH/cpR5/3KUef9ylHr/cpR6/2mOcv9pjnL/ao9z/2qPc/9qkHP/ + apBz/2qQc/9qkHP/a5Fz/2uRc/91mX3/dZl9//369//9+vf/I14w/yNeMP8fXC3/H1wt/ymDc/8pg3P/ + Nrb5/za2+f8lcU3/JXFN/yFhL/8hYS//IWIw/yFiMP8hZDH/IWQx/3evhP93r4T/d6+E/3evhP93r4T/ + d6+E/3i1l/94tZf/ftD7/37Q+/9ypZ3/cqWd/2qJcf9qiXH/aolx/2qJcf/Z39j/2d/Y/+Hm4P/h5uD/ + 2N7W/9je1v/Y3tb/2N7W/9jf1v/Y39b/2N/W/9jf1v/Y39f/2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/ + 2N/X/9jf1//Y39f/2ODX/9jg1//Y4Nf/2ODX/9jg1//Y4Nf/4efh/+Hn4f/Z4tn/2eLZ/1+Kaf9fimn/ + JmE0/yZhNP8pgG3/KYBt/ze3+f83t/n/JnJS/yZyUv8hYTD/IWEw/yFiMP8hYjD/ImMx/yJjMf93r4T/ + d6+E/3evhP93r4T/d6+E/3evhP94tZf/eLWX/37Q+/9+0Pv/cqWd/3Klnf9qiXH/aolx/2qJcf9qiXH/ + 2d/Y/9nf2P/h5uD/4ebg/9je1v/Y3tb/2N7W/9je1v/Y39b/2N/W/9jf1v/Y39b/2N/X/9jf1//Y39f/ + 2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/2N/X/9jg1//Y4Nf/2ODX/9jg1//Y4Nf/2ODX/+Hn4f/h5+H/ + 2eLZ/9ni2f9fimn/X4pp/yZhNP8mYTT/KYBt/ymAbf83t/n/N7f5/yZyUv8mclL/IWEw/yFhMP8hYjD/ + IWIw/yJjMf8iYzH/erKI/3qyiP96soj/erKI/3qyiP96soj/e7id/3u4nf+A0vv/gNL7/3Olm/9zpZv/ + bIt0/2yLdP9ti3X/bYt1/3KQev9ykHr/mK6d/5iunf+dsqH/nbKh/7fGuf+3xrn/6+7p/+vu6f+etKL/ + nrSi/560ov+etKL/nrWi/561ov+etaP/nrWj/561o/+etaP/nrak/562pP/r7ur/6+7q/7fJu/+3ybv/ + n7ek/5+3pP+atKD/mrSg/3Wafv91mn7/cZd6/3GXev9mkHD/ZpBw/zWFcP81hXD/N7j5/ze4+f8ndlj/ + J3ZY/yFhMf8hYTH/IWIx/yFiMf8iZjP/ImYz/3qyiP96soj/erKI/3qyiP96soj/erKI/3u4nf97uJ3/ + gNL7/4DS+/9zpZv/c6Wb/2yLdP9si3T/bYt1/22Ldf9ykHr/cpB6/5iunf+Yrp3/nbKh/52yof+3xrn/ + t8a5/+vu6f/r7un/nrSi/560ov+etKL/nrSi/561ov+etaL/nrWj/561o/+etaP/nrWj/562pP+etqT/ + 6+7q/+vu6v+3ybv/t8m7/5+3pP+ft6T/mrSg/5q0oP91mn7/dZp+/3GXev9xl3r/ZpBw/2aQcP81hXD/ + NYVw/ze4+f83uPn/J3ZY/yd2WP8hYTH/IWEx/yFiMf8hYjH/ImYz/yJmM/9+tYv/frWL/361i/9+tYv/ + frWL/361i/9/u6P/f7uj/4TT+/+E0/v/d6Wa/3elmv9wjXf/cI13/3COeP9wjnj/cI94/3CPeP9wj3n/ + cI95/3GQef9xkHn/kamX/5Gpl//s8Oz/7PDs/3KSev9yknr/cpN6/3KTev9ylHr/cpR6/3KUe/9ylHv/ + c5V7/3OVe/9zlnz/c5Z8/+zw7P/s8Oz/k66Z/5Oumf90mHz/dJh8/3SYff90mH3/dJl9/3SZff90mX7/ + dJl+/3Safv90mn7/c6mZ/3Opmf9EvPj/RLz4/yh4Xf8oeF3/IWEx/yFhMf8iZTP/ImUz/yyAQf8sgEH/ + frWL/361i/9+tYv/frWL/361i/9+tYv/f7uj/3+7o/+E0/v/hNP7/3elmv93pZr/cI13/3CNd/9wjnj/ + cI54/3CPeP9wj3j/cI95/3CPef9xkHn/cZB5/5Gpl/+RqZf/7PDs/+zw7P9yknr/cpJ6/3KTev9yk3r/ + cpR6/3KUev9ylHv/cpR7/3OVe/9zlXv/c5Z8/3OWfP/s8Oz/7PDs/5Oumf+Trpn/dJh8/3SYfP90mH3/ + dJh9/3SZff90mX3/dJl+/3SZfv90mn7/dJp+/3Opmf9zqZn/RLz4/0S8+P8oeF3/KHhd/yFhMf8hYTH/ + ImUz/yJlM/8sgEH/LIBB/4G3jv+Bt47/gbeO/4G3jv+Bt47/gbeO/4K+p/+Cvqf/h9T7/4fU+/95pJj/ + eaSY/3OPev9zj3r/c5B6/3OQev9zkXr/c5F6/3SSe/90knv/dJJ7/3SSe/94loD/eJaA/+3w7P/t8Oz/ + 1N7W/9Te1v+/zcL/v83C/7/Nwv+/zcL/v87C/7/Owv+/zsL/v87C/9Xf1//V39f/7fDt/+3w7f96nIP/ + epyD/3aZf/92mX//d5p//3eaf/93m3//d5t//3ebgP93m4D/d5yB/3ecgf98rp3/fK6d/37R+v9+0fr/ + M4Fo/zOBaP8iZDL/ImQy/y2CQf8tgkH/L4lF/y+JRf+Bt47/gbeO/4G3jv+Bt47/gbeO/4G3jv+Cvqf/ + gr6n/4fU+/+H1Pv/eaSY/3mkmP9zj3r/c496/3OQev9zkHr/c5F6/3ORev90knv/dJJ7/3SSe/90knv/ + eJaA/3iWgP/t8Oz/7fDs/9Te1v/U3tb/v83C/7/Nwv+/zcL/v83C/7/Owv+/zsL/v87C/7/Owv/V39f/ + 1d/X/+3w7f/t8O3/epyD/3qcg/92mX//dpl//3eaf/93mn//d5t//3ebf/93m4D/d5uA/3ecgf93nIH/ + fK6d/3yunf9+0fr/ftH6/zOBaP8zgWj/ImQy/yJkMv8tgkH/LYJB/y+JRf8viUX/hLmR/4S5kf+EuZH/ + hLmR/4S5kf+EuZH/hcCs/4XArP+J1vv/idb7/32qof99qqH/dpF8/3aRfP92kn3/dpJ9/3aTfv92k37/ + dpN+/3aTfv92lH7/dpR+/3eUfv93lH7/gp6K/4Keiv+1xrn/tca5/8DOw//AzsP/wM/D/8DPw//Az8T/ + wM/E/8DPxP/Az8T/tsi6/7bIuv+Eo4v/hKOL/3mbgv95m4L/eZuC/3mbgv95nIL/eZyC/3mdgv95nYL/ + ep2D/3qdg/96noP/ep6D/4Cypf+AsqX/idb7/4nW+/90rJz/dKyc/zSGSv80hkr/MIpH/zCKR/8wikf/ + MIpH/4S5kf+EuZH/hLmR/4S5kf+EuZH/hLmR/4XArP+FwKz/idb7/4nW+/99qqH/faqh/3aRfP92kXz/ + dpJ9/3aSff92k37/dpN+/3aTfv92k37/dpR+/3aUfv93lH7/d5R+/4Keiv+Cnor/tca5/7XGuf/AzsP/ + wM7D/8DPw//Az8P/wM/E/8DPxP/Az8T/wM/E/7bIuv+2yLr/hKOL/4Sji/95m4L/eZuC/3mbgv95m4L/ + eZyC/3mcgv95nYL/eZ2C/3qdg/96nYP/ep6D/3qeg/+AsqX/gLKl/4nW+/+J1vv/dKyc/3SsnP80hkr/ + NIZK/zCKR/8wikf/MIpH/zCKR/+HvJX/h7yV/4e8lf+HvJX/h7yV/4e8lf+Iv6D/iL+g/4zW9f+M1vX/ + jdj6/43Y+v+KzNv/iszb/4W7u/+Fu7v/gKmc/4CpnP97mIP/e5iD/3qXgv96l4L/e5eC/3uXgv97mIL/ + e5iC/3uYgv97mIL/e5mD/3uZg/97mYP/e5mD/3yag/98moP/fJuE/3ybhP98nIT/fJyE/3ychf98nIX/ + fJ2F/3ydhf99nYX/fZ2F/36gh/9+oIf/gq6g/4KuoP+Gv7z/hr+8/4rN3P+Kzdz/jdj6/43Y+v+N1vX/ + jdb1/4e+of+HvqH/drKF/3ayhf8zjEr/M4xK/zGLSP8xi0j/h7yV/4e8lf+HvJX/h7yV/4e8lf+HvJX/ + iL+g/4i/oP+M1vX/jNb1/43Y+v+N2Pr/iszb/4rM2/+Fu7v/hbu7/4CpnP+AqZz/e5iD/3uYg/96l4L/ + epeC/3uXgv97l4L/e5iC/3uYgv97mIL/e5iC/3uZg/97mYP/e5mD/3uZg/98moP/fJqD/3ybhP98m4T/ + fJyE/3ychP98nIX/fJyF/3ydhf98nYX/fZ2F/32dhf9+oIf/fqCH/4KuoP+CrqD/hr+8/4a/vP+Kzdz/ + is3c/43Y+v+N2Pr/jdb1/43W9f+HvqH/h76h/3ayhf92soX/M4xK/zOMSv8xi0j/MYtI/4q+mP+Kvpj/ + ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/isGh/4rBof+NysX/jcrF/47T5P+O0+T/j9n6/4/Z+v+P2fr/ + j9n6/4/Y+P+P2Pj/jtTs/47U7P+Nz93/jc/d/4vHzv+Lx87/isTH/4rEx/+JwcH/icHB/4m+vP+Jvrz/ + ib+8/4m/vP+JwsL/icLC/4rEx/+KxMf/i8nP/4vJz/+Nz93/jc/d/47U7P+O1Oz/j9j4/4/Y+P+P2fr/ + j9n6/4/Z+v+P2fr/jtPm/47T5v+My8j/jMvI/4vAof+LwKH/ir6Y/4q+mP+Kvpj/ir6Y/2ereP9nq3j/ + Mo1J/zKNSf+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/4rBof+KwaH/jcrF/43Kxf+O0+T/ + jtPk/4/Z+v+P2fr/j9n6/4/Z+v+P2Pj/j9j4/47U7P+O1Oz/jc/d/43P3f+Lx87/i8fO/4rEx/+KxMf/ + icHB/4nBwf+Jvrz/ib68/4m/vP+Jv7z/icLC/4nCwv+KxMf/isTH/4vJz/+Lyc//jc/d/43P3f+O1Oz/ + jtTs/4/Y+P+P2Pj/j9n6/4/Z+v+P2fr/j9n6/47T5v+O0+b/jMvI/4zLyP+LwKH/i8Ch/4q+mP+Kvpj/ + ir6Y/4q+mP9nq3j/Z6t4/zKNSf8yjUn/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwJv/jcCb/43Am/+NwqP/jcKj/4/Iuf+PyLn/j83J/4/Nyf+Q0dn/kNHZ/5HV6P+R1ej/ + kdfy/5HX8v+R2fb/kdn2/5La+v+S2vr/ktr7/5La+/+S2vv/ktr7/5La+v+S2vr/kdn2/5HZ9v+R1/L/ + kdfy/5HV6P+R1ej/kNHY/5DR2P+PzMj/j8zI/4/Iuf+PyLn/jcKj/43Co/+NwJv/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/9UoWn/VKFp/43Am/+NwJv/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcKj/43Co/+PyLn/j8i5/4/Nyf+Pzcn/ + kNHZ/5DR2f+R1ej/kdXo/5HX8v+R1/L/kdn2/5HZ9v+S2vr/ktr6/5La+/+S2vv/ktr7/5La+/+S2vr/ + ktr6/5HZ9v+R2fb/kdfy/5HX8v+R1ej/kdXo/5DR2P+Q0dj/j8zI/4/MyP+PyLn/j8i5/43Co/+NwqP/ + jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/VKFp/1Shaf+MwJrx + jMCa8ZDCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKe/5DCnv+QxKP/ + kMSj/5DEov+QxKL/kMKe/5DCnv+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/43BmvGNwZrxjMCa8YzAmvGQwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnv+Qwp7/kMSj/5DEo/+QxKL/kMSi/5DCnv+Qwp7/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+NwZrxjcGa8Ya+l8SGvpfElMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/j8Kdxo/CncaGvpfEhr6XxJTFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/4/CncaPwp3G + fLuPKXy7jymTxqD1k8ag9ZbHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + mMil9pjIpfaZx6gymceoMny7jyl8u48pk8ag9ZPGoPWWx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5jIpfaYyKX2mceoMpnHqDIAAAAAAAAAAHy7jyl8u48pjMKbxYzCm8WWx6Py + lsej8pnJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5rJp/OayafzlsaiyZbGosmbyKozm8iqMwAAAAAAAAAAAAAAAAAAAAB8u48p + fLuPKYzCm8WMwpvFlsej8pbHo/KZyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+ayafzmsmn85bGosmWxqLJm8iqM5vIqjMAAAAA + AAAAAMAAAAAAAAADwAAAAAAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAAAAAA8AAAAAAAAADKAAAADAAAABgAAAAAQAgAAAAAAAAJAAA + EwsAABMLAAAAAAAAAAAAAAAAAAAbZCQOG2QkHB1nJqkcZybIHGcm5xxnJv8cZyb/HGcm/xxnJv8cZyb/ + HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xhaIf8XViD/ + FlIe/xdTH/8XVB//F1Qf/xdUH/8XVSD/F1Yg/xdWIP8YVyD/GFcg/xhYIP8YWSH/GFkh/xhaIf8ZWiH/ + GVoh/xhcIukZXCLMGlwirxlaIR8ZWiEQAAAAABtkJA4dZyZJHWgnhR1oJ9QdaCfkHWgn8x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8cZCX/ + G2Ek/xhWIP8XVB//F1If/xdTH/8XVB//F1Qf/xhUIP8YVSD/GFYg/xhWIP8YVyD/GFch/xlYIf8ZWSH/ + GVkh/xlaIv8ZWiL/GVsi/xlbIvQZXCLmGlwj1xpdIocaXCJLGVohEBtkJBwdaCeFHWgn7R1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8bYSX/GVoi/xdRHv8XUh//F1If/xdTH/8XVB//F1Qf/xhUIP8YVSD/GFUg/xhWIP8YVyH/ + GFch/xlYIf8ZWSH/GVkh/xlaIv8ZWyL/GVsi/xlbIv8aXCP/Glwj/xpdIu8aXSKHGVohHx5qKakeaijU + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Hmoo/xpbIv8ZViH/F1Ef/xdSH/8XUx//F1Mf/xhUIP8YVCD/GFQg/xhVIP8YViD/ + GFYg/xlXIf8ZWCH/GVgh/xlZIv8ZWiL/GVoi/xpbIv8aWyP/Glsj/xpcI/8aXSP/Gl0j/xteI/8bXiPX + HF8krx9rKskfaynkH2sp/x9rKf8fayn/H2sp/x9rKf8fayn/H2sp/x9rKf8fayn/H2sp/x9rKf8fayn/ + H2sp/x9rKf8fayn/H2sp/x9rKf8dZyj/HGMm/xlWIf8aWTD/G11A/xteQP8ZWTD/GFMg/xhUIf8YVCH/ + GFQh/xlVIf8ZViH/GVYh/xlXIv8ZWCL/GVgi/xpZI/8aWiP/Gloj/xpbI/8aWyP/G1sk/xtcJP8bXST/ + G10k/xteJP8bXiTmG18lzB9rKugfayr0H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8dYyf/Glsk/xdQH/8bXUD/Hmlg/x5qYP8bX0D/ + GFMg/xhUIf8YVCH/GFQh/xlVIf8ZViL/GVYi/xlXIv8ZWCL/GVgi/xpZI/8aWiP/Gloj/xpbJP8bWyT/ + G1sk/xtcJP8bXSX/G10l/xteJf8bXiX0G18l6SBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/xtbJP8dYj//Hmha/yWCsv8ni8n/ + KZPf/ymT3/8ni8f/JYKu/x5nVP8cXjv/GVUi/xlWIv8ZVyL/GVci/xpYI/8aWCP/Glgj/xpZI/8bWiT/ + G1sk/xtbJP8bXCT/G1wk/xtdJf8cXiX/HF4l/xxfJf8cYCb/HGAm/yBuLP8gbiz/IG4s/yBuLP8gbiz/ + IG4s/yBuLP8gbiz/IG4s/yBuLP8gbiz/IG4s/yBuLP8gbiz/IG4s/yBuLP8fazH/H2k2/yBuZv8idoH/ + JH6d/yqT1f8rmOH/LJ7u/yye7v8rmOD/KpPT/yR+mv8hdH//H2tk/xtcMv8aWir/GVcj/xpYJP8aWCT/ + Glgk/xpZJP8aWiT/G1sl/xtbJf8bXCX/G1wl/xtdJv8bXib/HF4m/xxfJv8cYCb/HGAn/yBuLf8gbi3/ + IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8fajf/ + HWVA/ySBp/8ni8P/KZTf/y6k9/8vpvr/L6j9/y+o/f8vpvr/LqT3/ymU3/8nisL/JICl/xxiQv8bXTP/ + GVcj/xlYJP8aWCT/Glgk/xpZJf8aWiX/Glol/xtbJf8bXCb/G1wm/xtdJv8bXib/G14m/xxfJ/8cYCf/ + HGAn/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcS// + IXEv/yR8fv8nh6n/KZHU/y+l9v8wp/n/MKn8/yybzf8mhZT/IG5a/yBsWP8mg5L/LJrM/zCp/P8wp/n/ + L6X2/yqR1P8lg6P/IHRx/xpYJP8aWSX/Glkl/xtaJf8bWyX/G1sl/xtcJv8bXSb/G10m/xxeJ/8cXyf/ + HF8n/xxgJ/8cYSj/HGEo/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS// + InEv/yJyNf8jd1H/JHxt/ymOtf8rls//LZ7o/y+i5/8smMz/KY6x/yJ2eP8fa1v/HWA+/x1gPf8ga1r/ + I3d4/ymPsv8smMz/L6Ln/y2e6P8qlMv/J4qv/yBuZP8dZUj/G1ws/xtaJf8bWyX/G1sm/xxcJv8cXSb/ + HF0n/xxeJ/8cXyf/HV8n/x1gKP8dYSj/HWEo/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS// + InEv/yJxL/8icS//InEv/yN0O/8lfnP/J4eq/y2f7P8vpfT/MKr8/y6f2P8oiZ//IXJm/xhRIv8ZUiL/ + GVIi/xlTIv8ZVCP/GVQj/yJ0Z/8oiqD/Lp/Y/zCq/P8vpfT/LZ/s/yWEo/8hcWv/HF4z/xtaJf8bWyb/ + G1sm/xxcJv8cXSf/HF0n/xxeJ/8dXyf/HV8n/x1gKP8dYSj/HWEo/yx4Ov8pdjf/JXMz/yNyMf8jcjH/ + I3Ix/yNyMf8jcjH/I3Ix/yNyMf8kczf/JHQ8/ymPvf8tnNv/MKn5/zCo9P8rlb//JoGJ/xlQJf8ZUCT/ + GFAi/xlQI/8ZUSP/GVIj/xlTJP8aVCT/GlQk/xpUJP8bVib/G1co/yeFjf8smML/MKr2/zCp+f8tnNv/ + KY69/x1fM/8dXS3/HFsn/xxcJ/8cXSj/HF0o/x1dKP8dXin/HV8p/x1gKf8eYSr/HmEq/z+FTP89g0r/ + PIJI/zZ/Q/8zfUD/MXs+/yt4Of8odjb/JnU0/yR0Nv8lfFr/J4R+/y2d3P8uoOD/L6Pj/yeEm/8jdnj/ + H2hW/xlQJP8ZUCP/GVAj/xlRI/8ZUSP/GVIj/xpTJP8aVCT/GlQk/xpVJf8bVib/G1cn/yFuWf8lfHz/ + KImg/y+l5v8uoeH/LZ3c/yR5ev8ga1P/HV4t/x1cKP8dXSj/HV0o/x1eKf8dXin/Hl8p/x5gKv8eYSr/ + HmEq/1KRXf9SkV3/UpFd/0mLVf9EiFD/PoRK/zN+QP8uezv/KHc2/yR2O/8nhX7/KpPA/zGr+/8wpOT/ + Lp3N/x1gQv8bVzL/GE4i/xlPIv8ZUCP/GVAj/xlRI/8ZUiP/GVIj/xpTJP8aVCT/GlQk/xpVJf8bViX/ + G1Yl/xtXJf8eYDf/IGhJ/y6g0/8wpuf/Mav7/yqTwP8kenn/HmAy/x1cKP8dXSj/HV0o/x1eKf8eXyn/ + Hl8p/x5gKv8eYSr/HmEq/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1Smuf9Prtr/ + Sbb7/zWcvf9HjY3/WX1d/2KDYv9jg2L/Y4Ni/2OEYv9jhWL/Y4Vi/2OFYv9jhmP/Y4Zj/2OHY/9kh2T/ + ZIdk/2SIZP9kiWT/ZIlk/2SJZP9limT/ZYpk/1qFYv9FkJL/MJvC/zKt+/8un9L/KpCp/x1cKP8dXSn/ + HV0p/x5eKf8eXyn/Hl8p/x5gKv8fYSv/H2Ir/1eWY/9XlmP/V5Zj/1eWY/9XlmP/V5Zj/1eWY/9YmGz/ + WZp1/1uz2v9Xs9//VLTk/4K4wv+Nsqv/mKuV/5Onjv+Spo3/kaWL/5Gli/+RpYv/kaaL/5Gmi/+Rpov/ + kaeM/5GnjP+Rp4z/kqeM/5KojP+SqIz/kqmM/5KpjP+SqYz/kqmM/5Sskv+Fr6f/d7K8/zCl3/8votj/ + Lp/S/yBpQ/8fYzb/HV4q/x5fKv8eXyr/HmAq/x5hK/8eYSv/H2Is/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/ + WJdl/1iXZf9am3f/W5+I/2LA+v9gueT/XrHN/87Uxv/T18r/19nN/8TKuv/CyLf/v8a0/7/Gs/+/xrP/ + v8az/7/Gs/+/x7T/v8e0/7/HtP+/x7T/v8e0/7/HtP+/yLT/v8i0/7/ItP+/yLT/v8i0/83Swv/Gzrz/ + vsm2/y6dw/8wpd//Mq36/yN1Xv8gakT/HV4q/x1fKv8eYCv/HmAr/x5hK/8eYiz/HmIs/1yaaP9cmmj/ + XJpo/1yaaP9cmmj/XJpo/1yaaP9hq6T/Zbvf/2W/7f9doKr/VIBm//v07f+tu6n/X4Jk/1J6Wv9ReVn/ + UHhY/zxqRf8uYDj/IFUr/xpRJP8hViv/J1sx/ydcMf8hWCz/G1Qm/xtVJv8bVif/G1Yn/xxXJ/8cWCj/ + HFgo/yxkNf+Tqo7/+fDn/yBlPv8piJX/Mqrr/zGk1/8ogYH/Hl4q/x5fK/8eYCv/HmAr/x9gK/8fYSz/ + H2Is/16cav9enGr/Xpxq/16cav9enGr/Xpxq/1+fdv9jr7L/Z8Du/2Owx/9clpT/VX1h//v17/+tvKr/ + X4Nl/1R8XP9Te1z/U3tb/0l0Uv9Bbkv/OmlE/yteNf9DcEr/XIFg/1uBX/87a0P/G1Qn/xtVJ/8bVif/ + HFYo/xxYKP8cWCj/HFkp/yxjNf+Tqo//+vHp/x9gNP8mfXf/Lpm5/zKq6f8piZP/IWc9/x5fLP8eYCz/ + H2As/x9hLP8fYiz/IGMt/2CdbP9gnWz/YJ1s/2CdbP9gnWz/YJ1s/2Gjg/9ltMD/acX8/2Cgof9bjX// + VXpc//v18P+tvKv/X4Nm/1V9Xv9VfV7/VX1e/1V9Xv9VfV7/VH1d/zxrRf9miWr/kKeO/4+mjP9VfVr/ + G1Qn/xtVJ/8cVij/HFYo/xxYKP8cWSn/HFkp/ytiNf+TqpD/+vLq/x1bKv8jcln/KYiH/zOw+/8rkKb/ + I3BQ/x5fLP8fYCz/H2As/x9hLf8gYi3/IGMt/2Ofb/9jn2//Y59v/2Ofb/9jn2//Y59v/2eztP9pvNb/ + a8X3/1mBav9Yf2X/V3xf//z28f+vva3/YoRp/1h+YP9Yf2D/WH9g/1l/Yf9ZgGH/WYBh/1mBYv+EoIj/ + r7+t/6G0nv9ghWT/HlYq/xxVJ/8cVij/HFYo/xxXKP8dWCn/HVgp/ytiNf+Tq5H/+/Ps/x5bKv8fYTT/ + IGY9/zSw9/8woMf/K5CX/x9fLP8fYCz/H2As/yBhLf8gYi7/IGIu/2Whcf9loXH/ZaFx/2Whcf9loXH/ + ZaFx/2q5xv9rvdb/bMHn/1qAZv9af2T/WX5h//z38v+wvq7/ZIZr/1qAYv9agGL/WoBi/2CEZ/9yknj/ + haCI/4aiiv+luKX/xM/B/73Juf+SqpL/Z4ts/1yEYf8/b0f/I1su/x1XKP8dWCn/HVgp/ytjNv+Tq5H/ + +/Tt/x5cK/8fXy//H2I0/zOq4f8wocj/Lpmv/x9gLP8fYCz/IGEt/yBiLf8gYi7/IGMu/2ejc/9no3P/ + Z6Nz/2ejc/9no3P/Z6Nz/22+1/9tvdf/bLzX/1t+Yv9bf2P/W39j//z48/+xwLD/Zods/1yBZP9cgWT/ + XIFk/2aIbf+LpI7/sMCv/7LCsf/G0MP/2d7U/9ne1P/Ez8H/r8Ct/5uymv9iiWf/KV80/x1XKP8dWCn/ + HVgp/ytjNv+TrJL/+/Xu/x5cK/8eXSv/Hl0r/zGjy/8xo8n/MKLG/x9gLP8gYS3/IGEt/yBiLf8gYy7/ + IGMu/2qld/9qpXf/aqV3/2qld/9qpXf/aqV3/3HG7P9vvdb/bLO//16AZf9egWX/XoFl//359f+zwbL/ + aIlv/16DZ/9eg2f/XoNn/2iKcP+NppH/scGx/7PDs//H0sX/2+DW/9vg1v/I0sX/tMS0/7LDsv+CoYf/ + Un5c/yBaLP8fWSv/HVgq/ytiNv+UrJP//Pbw/x5bLP8eXCz/Hlws/y6Yqv8xo8j/NK3l/x9fLf8fYC7/ + H2Au/yBhLv8gYi//IGMv/2ynef9sp3n/bKd5/2ynef9sp3r/bKd7/3PJ9P9vvNT/bK60/1+BZ/9fgmf/ + X4Jn//369v+zwrP/aopx/2CEaP9ghGj/YIVo/2WIbf93ln3/iqSO/4umj/+qvKr/yNPG/8jTxv+qvav/ + jKeQ/4unj/9zlnr/W4Vk/z1vSP8xZj3/JV4x/ytiN/+UrJT//Pfx/x5cLP8eXCz/Hl0s/y2Rmf8xocT/ + NbHv/yBiMf8gYTD/IGEu/yBiL/8gYi//IWMv/22oev9tqHr/bah6/22oev9tqX3/bal//3TM+/9wu9L/ + a6mo/2CCaP9gg2j/YINo//369v+0w7T/a4ty/2GFaf9ihmn/YoZp/2KGav9ih2r/Yodq/2OIa/+Mp5D/ + tcW1/7XFtv+MqJH/Y4pr/2OKbP9ji2z/Y4ts/1qEZP9DdE7/LGM4/ytiN/+UrZX//Pfy/x5cLP8eXSz/ + Hl0s/yuKiP8wn8H/NbT5/yFkNf8hYzL/IGEu/yBiL/8hYy//IWMv/3Grfv9xq37/cat+/3Grfv9yrYX/ + cq+M/3jN+/9zuc7/baWg/2SEa/9khWv/ZIVr//36+P+2xLf/bo51/2WIbf9liG3/ZYht/2WJbf9mim3/ + Zopt/2aKbv+OqJL/tcW2/7XFtv+OqZP/Z4xv/2eNb/9njm//Z45v/2eOcP9njm//Zo5u/0x7Vv+kuqX/ + /Pj0/x5bLP8fXCz/H10s/yqDd/8wnLj/NrX5/yNtR/8iZzv/IGEu/yFiL/8hYzD/IWMw/3OsgP9zrID/ + c6yA/3OsgP9zroj/dLGQ/3rO+/90us3/b6Wf/2aFbf9mhm3/ZoZt//36+P+3xbj/cZB3/2eJbv9niW7/ + Z4lv/2eKb/9ni2//aItv/2iLcP9+nIT/lK2Y/5StmP9+nYT/aI1x/2mOcf9pj3H/aY9x/2mPcv9pj3H/ + aZBx/2GKav+vwrD//fn2/yFdLv8gXS3/H10t/yqDdf8wnLf/Nrb5/yRvSv8iaDz/IWEv/yFiMP8hYzD/ + IWQx/3Stgf90rYH/dK2B/3Stgf91sIr/dbKT/3vP+/92us3/cKWe/2eGbv9nh2//Z4dv//36+P+4xrn/ + c5J5/2iKb/9oinD/aIpw/2mLcf9pjHH/aYxx/2mMcf9ukHX/cpR5/3KUev9ukXb/aY5y/2qPc/9qkHP/ + apBz/2qQc/9rkXP/a5Fz/3WZff+5yrr//fr3/yNeMP8hXS//H1wt/ymDc/8wnbb/Nrb5/yVxTf8jaT7/ + IWEv/yFiMP8hYzH/IWQx/3evhP93r4T/d6+E/3evhP94so7/eLWX/37Q+/94u8z/cqWd/2qJcf9qiXH/ + aolx/9nf2P/d49z/4ebg/9je1v/Y3tb/2N7W/9jf1v/Y39b/2N/W/9jf1//Y39f/2N/X/9jf1//Y39f/ + 2N/X/9jf1//Y4Nf/2ODX/9jg1//Y4Nf/2ODX/+Hn4f/d5d3/2eLZ/1+Kaf9Ddk//JmE0/ymAbf8wnLP/ + N7f5/yZyUv8kakH/IWEw/yFiMP8iYzH/ImMx/3mxhv95sYb/ebGG/3mxhv95tJD/erea/3/R+/95u8z/ + c6Wc/2uKc/9rinP/bIpz/6a4qf+xwbT/vcq//7vIvP/BzcL/yNLI/+Ln4P/O2M7/u8q8/7vKvf+7yr3/ + u8q9/7vKvf+7yr3/u8q9/7vLvv/O2c//4ufh/8jVyf/C0MP/vMy+/77Owf+yxrb/p76s/2iRcv9XhWL/ + RnlS/y+Db/8znbT/N7j5/yd0Vf8ka0P/IWEx/yFiMf8iYzH/ImUy/3qyiP96soj/erKI/3qyiP97tZP/ + e7id/4DS+/96vMv/c6Wb/2yLdP9ti3X/bYt1/3KQev+Fn4z/mK6d/52yof+qvK3/t8a5/+vu6f/F0cb/ + nrSi/560ov+etaL/nrWi/561o/+etaP/nrWj/562pP/F0sf/6+7q/7fJu/+rwLD/n7ek/5q0oP+Ip4// + dZp+/3GXev9slHX/ZpBw/zWFcP82n7X/N7j5/yd2WP8kbEX/IWEx/yFiMf8iZDL/ImYz/361i/9+tYv/ + frWL/361i/9/uJf/f7uj/4TT+/9+vMv/d6Wa/3CNd/9wjnj/cI54/3CPeP9wj3n/cI95/3GQef+BnYj/ + kamX/+zw7P+vwbP/cpJ6/3KTev9ylHr/cpR6/3KUe/9zlXv/c5V7/3OWfP+ww7T/7PDs/5Oumf+Eo4v/ + dJh8/3SYff90mX3/dJl9/3SZfv90mn7/dJp+/3Opmf9cs8n/RLz4/yh4Xf8lbUf/IWEx/yJlM/8nczr/ + LIBB/4C2jf+Ato3/gLaN/4C2jf+AuZn/gb2l/4bU+/9/vMr/eKWZ/3KOef9yj3n/co95/3KQef9ykHr/ + cpF6/3ORev98mIP/haCM/+3w7P/I1Mr/o7io/5mwnv+ZsJ7/mbGe/5mxn/+ZsZ//mbKf/6S7qv/I1cv/ + 7fDt/4eljv9+n4b/dZl+/3aZfv92mn7/dpp+/3aaf/92m3//dpuA/3ism/9sucr/Ycf5/y59Y/8ocEr/ + ImMy/yh0Ov8rfD//LoVD/4G3jv+Bt47/gbeO/4G3jv+Cu5v/gr6n/4fU+/+AvMr/eaSY/3OPev9zkHr/ + c5B6/3ORev90knv/dJJ7/3SSe/92lH7/eJaA/+3w7P/h5+H/1N7W/7/Nwv+/zcL/v83C/7/Owv+/zsL/ + v87C/9Xf1//h6OL/7fDt/3qcg/94m4H/dpl//3eaf/93m3//d5t//3ebgP93nIH/d5yB/3yunf99wMz/ + ftH6/zOBaP8rc03/ImQy/y2CQf8uhkP/L4lF/4S5kf+EuZH/hLmR/4S5kf+FvZ//hcCs/4nW+/+DwM7/ + faqh/3aRfP92kn3/dpJ9/3aTfv92k37/dpN+/3aUfv93lH7/d5R+/4Keiv+csqL/tca5/8DOw//Az8P/ + wM/D/8DPxP/Az8T/wM/E/7bIuv+dtqP/hKOL/3mbgv95m4L/eZuC/3mcgv95nYL/eZ2C/3qdg/96noP/ + ep6D/4Cypf+FxND/idb7/3SsnP9UmXP/NIZK/zCKR/8wikf/MIpH/4a7k/+Gu5P/hruT/4a7k/+GvZ3/ + h8Cm/4vW+P+IzOP/hcHO/4CvrP9/q6T/fqec/3uejf96mof/eZaB/3iWgP95loD/eZaA/3+bhv+LpZL/ + mK+e/560o/+etKP/nrSj/561pP+etaT/nrWk/5myn/+NqZT/gKCI/3uchP97nIT/e5yE/3yehf99oov/ + fqaR/4CuoP+Bsqj/graw/4fF0P+JzuT/i9b4/361n/9pqYP/VZxo/zKLSf8xi0j/MYtI/4e8lf+HvJX/ + h7yV/4e8lf+Ivpv/iL+g/4zW9f+N1/j/jdj6/4rM2/+IxMv/hbu7/4CpnP9+oZD/e5iD/3qXgv97l4L/ + e5eC/3uYgv97mIL/e5iC/3uZg/97mYP/e5mD/3yag/98m4T/fJuE/3ychP98nIX/fJyF/3ydhf99nYX/ + fZ2F/36gh/+Ap5T/gq6g/4a/vP+Ixsz/is3c/43Y+v+N1/j/jdb1/4e+of9/uJP/drKF/zOMSv8yjEn/ + MYtI/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/4rBof+MxrP/jcrF/47T5P+P1u//j9n6/4/Z+v+P2fn/ + j9j4/47U7P+O0uX/jc/d/4vHzv+Lxsv/isTH/4nBwf+JwL//ib68/4m/vP+Jwb//icLC/4rEx/+Lx8v/ + i8nP/43P3f+O0uX/jtTs/4/Y+P+P2fn/j9n6/4/Z+v+P1vD/jtPm/4zLyP+MxrX/i8Ch/4q+mP+Kvpj/ + ir6Y/2ereP9NnGH/Mo1J/4y/mv+Mv5r/jL+a/4y/mv+Mv5r/jL+a/4zBnv+Mw6f/jcWw/47KwP+OzMf/ + js7P/4/R2v+P0t3/j9Ph/4/T4/+P0uP/j9Lj/47P4P+Oz9//js/f/47O3v+Ozd3/jszc/47N3P+Ozd3/ + js7e/47P3/+Oz+D/jtDh/4/S4/+P0uL/j9Pi/4/S4P+P0d3/j9Ha/47Oz/+OzMj/jsrB/43Gsv+Mw6j/ + jMCe/4y/mv+Mv5r/jL+a/3q2iv9fpnH/Q5dZ/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwZ//jcKj/4/Iuf+Py8H/j83J/5DR2f+R0+H/kdXo/5HX8v+R2PT/kdn2/5La+v+S2vv/ + ktr7/5La+/+S2vv/ktr6/5HZ9v+R2PT/kdfy/5HV6P+R0+D/kNHY/4/MyP+PysH/j8i5/43Co/+NwZ// + jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/9xsYL/VKFp/4zAmvGOwZz4kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnv+Qw6H/kMSj/5DEov+Qw6D/kMKe/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Pwpz4jcGa8Ym/mduOwZzt + ksSf/5LEn/+SxJ//ksSf/5LEn/+SxJ//ksSf/5LEn/+SxJ//ksSf/5LEn/+SxJ//ksSf/5LEn/+SxJ// + ksSf/5LEn/+SxJ//ksSf/5LEoP+SxKH/ksWi/5LFov+SxKH/ksSg/5LEn/+SxJ//ksSf/5LEn/+SxJ// + ksSf/5LEn/+SxJ//ksSf/5LEn/+SxJ//ksSf/5LEn/+SxJ//ksSf/5LEn/+SxJ//ksSf/5LEn/+Qw53t + jsGb3Ia+l8SOwp3ilMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+SxJ/jj8Kdxny7jymQxJ6Pk8ag9ZbHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5jIpfaYyKaUmceoMny7jxWNw5xSkMSej5LFoOKUxqLtlsek+ZjIpf+YyKX/ + mMil/5jIpf+YyKX/mMil/5jIpf+YyKX/mMil/5jIpf+YyKX/mMil/5jIpf+YyKX/mMil/5jIpf+YyKX/ + mMil/5jIpf+YyKX/mMil/5jIpf+YyKX/mMil/5jIpf+YyKX/mMil/5jIpf+YyKX/mMil/5jIpf+YyKX/ + mMil/5jIpf+YyKX/mMil/5jIpfmXx6Tvlsej5JnIppWZyKZXmceoGQAAAAB8u48VfLuPKYzCm8WSxZ/c + lsej8pnJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5rJp/OYyKXelsaiyZvIqjObyKoaAAAAAIAAAAAAAQAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAACAAAAAAAEAACgAAAAgAAAAQAAAAAEAIAAAAAAAABAAABMLAAATCwAAAAAAAAAAAAAAAAAA + G2QkHB1nJqkcZybnHGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/ + GFoh/xZSHv8XUx//F1Qf/xdUH/8XViD/F1Yg/xhXIP8YWCD/GFkh/xhaIf8ZWiH/GFwi6RpcIq8ZWiEf + AAAAABtkJBwdaCftHWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/xlaIv8XUR7/F1If/xdTH/8XVB//GFQg/xhVIP8YViD/GFch/xlYIf8ZWSH/GVoi/xlbIv8ZWyL/ + Glwj/xpdIu8ZWiEfHmopqR5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8aWyL/F1Ef/xdSH/8XUx//GFQg/xhUIP8YVSD/GFYg/xlXIf8ZWCH/GVki/xlaIv8aWyL/ + Glsj/xpcI/8aXSP/G14j/xxfJK8fayroH2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/Glsk/xdQH/8eaWD/Hmpg/xhTIP8YVCH/GFQh/xlVIf8ZViL/GVci/xlYIv8aWSP/ + Gloj/xpbJP8bWyT/G1wk/xtdJf8bXiX/G18l6SBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/IG0r/xtbJP8eaFr/JYKy/ymT3/8pk9//JYKu/x5nVP8ZVSL/GVYi/xlXIv8aWCP/ + Glgj/xpZI/8bWyT/G1sk/xtcJP8bXSX/HF4l/xxfJf8cYCb/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/yBuLf8gbi3/IG4t/yBuLf8dZUD/JIGn/ymU3/8upPf/L6j9/y+o/f8upPf/KZTf/ySApf8cYkL/ + GVcj/xlYJP8aWCT/Glkl/xpaJf8bWyX/G1wm/xtdJv8bXib/HF8n/xxgJ/8hcC7/IXAu/yFwLv8hcC7/ + IXAu/yFwLv8hcC7/IXAu/yFwLv8hcS//JHx+/ymR1P8vpfb/MKn8/yybzf8gblr/IGxY/yyazP8wqfz/ + L6X2/yqR1P8gdHH/Glgk/xpZJf8bWiX/G1sl/xtcJv8bXSb/HF4n/xxfJ/8cYCf/HGEo/yJxL/8icS// + InEv/yJxL/8icS//InEv/yJxL/8icS//I3Q7/yeHqv8tn+z/MKr8/y6f2P8hcmb/GFEi/xlSIv8ZUyL/ + GVQj/yJ0Z/8un9j/MKr8/y2f7P8lhKP/HF4z/xtaJf8bWyb/HFwm/xxdJ/8cXif/HV8n/x1gKP8dYSj/ + LHg6/yVzM/8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yR0PP8pj73/MKn5/zCo9P8mgYn/GVAl/xhQIv8ZUCP/ + GVIj/xlTJP8aVCT/GlQk/xtXKP8nhY3/MKr2/zCp+f8pjr3/HV8z/xxbJ/8cXCf/HF0o/x1dKP8dXyn/ + HWAp/x5hKv9SkV3/UpFd/0mLVf8+hEr/M35A/yh3Nv8kdjv/KpPA/zGr+/8unc3/HWBC/xhOIv8ZTyL/ + GVAj/xlRI/8ZUiP/GlMk/xpUJP8aVSX/G1Yl/xtXJf8gaEn/LqDT/zGr+/8qk8D/HmAy/x1cKP8dXSj/ + HV4p/x5fKf8eYCr/HmEq/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1Smuf9Jtvv/NZy9/1l9Xf9ig2L/ + Y4Ni/2OEYv9jhWL/Y4Vi/2OGY/9jh2P/ZIdk/2SIZP9kiWT/ZIlk/2WKZP9ahWL/MJvC/zKt+/8qkKn/ + HVwo/x1dKf8eXin/Hl8p/x5gKv8fYiv/WJdl/1iXZf9Yl2X/WJdl/1iXZf9bn4j/YsD6/16xzf/O1Mb/ + 19nN/8TKuv+/xrT/v8az/7/Gs/+/xrP/v8e0/7/HtP+/x7T/v8e0/7/ItP+/yLT/v8i0/83Swv++ybb/ + Lp3D/zKt+v8jdV7/HV4q/x1fKv8eYCv/HmEr/x5iLP9cmmj/XJpo/1yaaP9cmmj/XJpo/2W73/9lv+3/ + VIBm//v07f9fgmT/Unpa/1B4WP88akX/IFUr/xpRJP8nWzH/J1wx/xtUJv8bVSb/G1Yn/xxXJ/8cWCj/ + LGQ1//nw5/8gZT7/Mqrr/zGk1/8eXir/Hl8r/x5gK/8fYCv/H2Is/2CdbP9gnWz/YJ1s/2CdbP9ho4P/ + acX8/2Cgof9Velz/+/Xw/1+DZv9VfV7/VX1e/1V9Xv9UfV3/PGtF/5Cnjv+Ppoz/G1Qn/xtVJ/8cVij/ + HFgo/xxZKf8rYjX/+vLq/x1bKv8piIf/M7D7/yNwUP8eXyz/H2As/x9hLf8gYy3/Y59v/2Ofb/9jn2// + Y59v/2eztP9rxff/WYFq/1d8X//89vH/YoRp/1h+YP9Yf2D/WX9h/1mAYf9ZgWL/r7+t/6G0nv8eVir/ + HFUn/xxWKP8cVyj/HVgp/ytiNf/78+z/Hlsq/yBmPf80sPf/K5CX/x9fLP8fYCz/IGEt/yBiLv9no3P/ + Z6Nz/2ejc/9no3P/bb7X/2y81/9bfmL/W39j//z48/9mh2z/XIFk/1yBZP9miG3/sMCv/7LCsf/Z3tT/ + 2d7U/6/Arf+bspr/KV80/x1XKP8dWCn/K2M2//v17v8eXCv/Hl0r/zGjy/8wosb/H2As/yBhLf8gYi3/ + IGMu/2qld/9qpXf/aqV3/2qld/9xxuz/bLO//16AZf9egWX//fn1/2iJb/9eg2f/XoNn/2iKcP+xwbH/ + s8Oz/9vg1v/b4Nb/tMS0/7LDsv9Sflz/IFos/x1YKv8rYjb//Pbw/x5bLP8eXCz/Lpiq/zSt5f8fXy3/ + H2Au/yBhLv8gYy//bah6/22oev9tqHr/bal//3TM+/9rqaj/YIJo/2CDaP/9+vb/a4ty/2GFaf9ihmn/ + YoZq/2KHav9jiGv/tcW1/7XFtv9jimv/Y4ps/2OLbP9ahGT/LGM4/ytiN//89/L/Hlws/x5dLP8rioj/ + NbT5/yFkNf8gYS7/IGIv/yFjL/9xq37/cat+/3Grfv9yr4z/eM37/22loP9khGv/ZIVr//36+P9ujnX/ + ZYht/2WIbf9liW3/Zopt/2aKbv+1xbb/tcW2/2eMb/9njW//Z45v/2eOcP9mjm7/THtW//z49P8eWyz/ + H10s/yqDd/82tfn/I21H/yBhLv8hYi//IWMw/3Stgf90rYH/dK2B/3Wyk/97z/v/cKWe/2eGbv9nh2// + /fr4/3OSef9oim//aIpw/2mLcf9pjHH/aYxx/3KUef9ylHr/aY5y/2qPc/9qkHP/apBz/2uRc/91mX3/ + /fr3/yNeMP8fXC3/KYNz/za2+f8lcU3/IWEv/yFiMP8hZDH/d6+E/3evhP93r4T/eLWX/37Q+/9ypZ3/ + aolx/2qJcf/Z39j/4ebg/9je1v/Y3tb/2N/W/9jf1v/Y39f/2N/X/9jf1//Y39f/2N/X/9jg1//Y4Nf/ + 2ODX/+Hn4f/Z4tn/X4pp/yZhNP8pgG3/N7f5/yZyUv8hYTD/IWIw/yJjMf96soj/erKI/3qyiP97uJ3/ + gNL7/3Olm/9si3T/bYt1/3KQev+Yrp3/nbKh/7fGuf/r7un/nrSi/560ov+etaL/nrWj/561o/+etqT/ + 6+7q/7fJu/+ft6T/mrSg/3Wafv9xl3r/ZpBw/zWFcP83uPn/J3ZY/yFhMf8hYjH/ImYz/361i/9+tYv/ + frWL/3+7o/+E0/v/d6Wa/3CNd/9wjnj/cI94/3CPef9xkHn/kamX/+zw7P9yknr/cpN6/3KUev9ylHv/ + c5V7/3OWfP/s8Oz/k66Z/3SYfP90mH3/dJl9/3SZfv90mn7/c6mZ/0S8+P8oeF3/IWEx/yJlM/8sgEH/ + gbeO/4G3jv+Bt47/gr6n/4fU+/95pJj/c496/3OQev9zkXr/dJJ7/3SSe/94loD/7fDs/9Te1v+/zcL/ + v83C/7/Owv+/zsL/1d/X/+3w7f96nIP/dpl//3eaf/93m3//d5uA/3ecgf98rp3/ftH6/zOBaP8iZDL/ + LYJB/y+JRf+EuZH/hLmR/4S5kf+FwKz/idb7/32qof92kXz/dpJ9/3aTfv92k37/dpR+/3eUfv+Cnor/ + tca5/8DOw//Az8P/wM/E/8DPxP+2yLr/hKOL/3mbgv95m4L/eZyC/3mdgv96nYP/ep6D/4Cypf+J1vv/ + dKyc/zSGSv8wikf/MIpH/4e8lf+HvJX/h7yV/4i/oP+M1vX/jdj6/4rM2/+Fu7v/gKmc/3uYg/96l4L/ + e5eC/3uYgv97mIL/e5mD/3uZg/98moP/fJuE/3ychP98nIX/fJ2F/32dhf9+oIf/gq6g/4a/vP+Kzdz/ + jdj6/43W9f+HvqH/drKF/zOMSv8xi0j/ir6Y/4q+mP+Kvpj/ir6Y/4rBof+NysX/jtPk/4/Z+v+P2fr/ + j9j4/47U7P+Nz93/i8fO/4rEx/+JwcH/ib68/4m/vP+JwsL/isTH/4vJz/+Nz93/jtTs/4/Y+P+P2fr/ + j9n6/47T5v+My8j/i8Ch/4q+mP+Kvpj/Z6t4/zKNSf+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/ + jcKj/4/Iuf+Pzcn/kNHZ/5HV6P+R1/L/kdn2/5La+v+S2vv/ktr7/5La+v+R2fb/kdfy/5HV6P+Q0dj/ + j8zI/4/Iuf+NwqP/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/VKFp/4zAmvGQwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKe/5DEo/+QxKL/kMKe/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+NwZrxhr6XxJTFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/4/CncZ8u48p + k8ag9ZbHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+YyKX2 + mceoMgAAAAB8u48pjMKbxZbHo/KZyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+ayafz + lsaiyZvIqjMAAAAAgAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAIAAAAEoAAAAEAAAACAAAAABACAAAAAAAAAEAAATCwAAEwsAAAAAAAAAAAAA + HWcmSR1oJ+QdaCf/HWgn/x1oJ/8daCf/HWgn/xxkJf8XVB//F1Qf/xhVIP8YVyD/GVkh/xlaIv8ZXCLm + GlwiSx9rKeQfayn/H2sp/x9rKf8fayn/H2sp/x1nKP8aWTD/GVkw/xhUIf8ZViH/GVgi/xpaI/8aWyP/ + G10k/xteJOYgbiz/IG4s/yBuLP8gbiz/IG4s/x9rMf8idoH/K5jh/yuY4P8hdH//Gloq/xpYJP8aWiT/ + G1wl/xteJv8cYCb/InEv/yJxL/8icS//InEv/yN3Uf8rls//LJjM/x9rW/8ga1r/LJjM/yqUy/8dZUj/ + G1sl/xxdJv8cXyf/HWEo/z2DSv8zfUD/KHY2/yV8Wv8uoOD/I3Z4/xlQI/8ZUSP/GlQk/xtWJv8lfHz/ + LqHh/yBrU/8dXSj/HV4p/x5hKv9XlmP/V5Zj/1iYbP9Xs9//jbKr/5Kmjf+RpYv/kaaL/5GnjP+SqIz/ + kqmM/4Wvp/8votj/H2M2/x5fKv8eYSv/Xpxq/16cav9jr7L/XJaU/628qv9Te1z/QW5L/0NwSv87a0P/ + G1Yn/xxYKP+Tqo//Jn13/ymJk/8eYCz/H2Is/2Whcf9loXH/a73W/1p/ZP+wvq7/WoBi/3KSeP+luKX/ + kqqS/z9vR/8dWCn/k6uR/x9fL/8wocj/H2As/yBiLv9sp3n/bKd6/2+81P9fgmf/s8Kz/2CEaP93ln3/ + qryq/6q9q/9zlnr/MWY9/5SslP8eXCz/MaHE/yBhMP8gYi//c6yA/3OuiP90us3/ZoZt/7fFuP9niW7/ + Z4tv/36chP9+nYT/aY9x/2mPcf+vwrD/IF0t/zCct/8iaDz/IWMw/3mxhv95tJD/ebvM/2uKc/+xwbT/ + wc3C/87Yzv+7yr3/u8q9/87Zz//C0MP/ssa2/1eFYv8znbT/JGtD/yJjMf+Ato3/gLmZ/3+8yv9yj3n/ + cpB6/3yYg//I1Mr/mbCe/5mxn//I1cv/fp+G/3aafv92m3//bLnK/yhwSv8rfD//hruT/4a9nf+IzOP/ + f6uk/3qah/95loD/i6WS/560o/+etaT/jamU/3uchP99oov/gbKo/4nO5P9pqYP/MYtI/4y/mv+Mv5r/ + jMOn/47Mx/+P0t3/j9Lj/47P3/+Ozd3/js3d/47P4P+P0uL/j9Hd/47MyP+Mw6j/jL+a/1+mcf+OwZzt + ksSf/5LEn/+SxJ//ksSf/5LEn/+SxJ//ksSh/5LEof+SxJ//ksSf/5LEn/+SxJ//ksSf/5LEn/+Qw53t + jcOcUpTGou2YyKX/mMil/5jIpf+YyKX/mMil/5jIpf+YyKX/mMil/5jIpf+YyKX/mMil/5jIpf+Xx6Tv + mcimVwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAA= + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/ProcessMon/ProcessFilterSetting.Designer.cs b/Demo_Source_Code/CSharpDemo/ProcessMon/ProcessFilterSetting.Designer.cs new file mode 100644 index 0000000..c19a3b9 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/ProcessMon/ProcessFilterSetting.Designer.cs @@ -0,0 +1,235 @@ +namespace ProcessMon +{ + partial class ProcessFilterSetting + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ProcessFilterSetting)); + this.groupBox_AccessControl = new System.Windows.Forms.GroupBox(); + this.button_Save = new System.Windows.Forms.Button(); + this.groupBox2 = new System.Windows.Forms.GroupBox(); + this.button_SelectPid = new System.Windows.Forms.Button(); + this.textBox_ProcessId = new System.Windows.Forms.TextBox(); + this.radioButton_Name = new System.Windows.Forms.RadioButton(); + this.radioButton_Pid = new System.Windows.Forms.RadioButton(); + this.button_ConfigFileAccessRights = new System.Windows.Forms.Button(); + this.button_ProcessInfo = new System.Windows.Forms.Button(); + this.label2 = new System.Windows.Forms.Label(); + this.textBox_ControlFlag = new System.Windows.Forms.TextBox(); + this.label17 = new System.Windows.Forms.Label(); + this.button_SelectControlFlag = new System.Windows.Forms.Button(); + this.textBox_ProcessName = new System.Windows.Forms.TextBox(); + this.groupBox_AccessControl.SuspendLayout(); + this.groupBox2.SuspendLayout(); + this.SuspendLayout(); + // + // groupBox_AccessControl + // + this.groupBox_AccessControl.Controls.Add(this.button_Save); + this.groupBox_AccessControl.Controls.Add(this.groupBox2); + this.groupBox_AccessControl.Dock = System.Windows.Forms.DockStyle.Fill; + this.groupBox_AccessControl.Location = new System.Drawing.Point(0, 0); + this.groupBox_AccessControl.Name = "groupBox_AccessControl"; + this.groupBox_AccessControl.Size = new System.Drawing.Size(537, 246); + this.groupBox_AccessControl.TabIndex = 26; + this.groupBox_AccessControl.TabStop = false; + // + // button_Save + // + this.button_Save.BackColor = System.Drawing.SystemColors.GradientActiveCaption; + this.button_Save.DialogResult = System.Windows.Forms.DialogResult.OK; + this.button_Save.Location = new System.Drawing.Point(407, 211); + this.button_Save.Name = "button_Save"; + this.button_Save.Size = new System.Drawing.Size(116, 23); + this.button_Save.TabIndex = 85; + this.button_Save.Text = "Save Filter Rule"; + this.button_Save.UseVisualStyleBackColor = false; + this.button_Save.Click += new System.EventHandler(this.button_Save_Click); + // + // groupBox2 + // + this.groupBox2.Controls.Add(this.button_SelectPid); + this.groupBox2.Controls.Add(this.textBox_ProcessId); + this.groupBox2.Controls.Add(this.radioButton_Name); + this.groupBox2.Controls.Add(this.radioButton_Pid); + this.groupBox2.Controls.Add(this.button_ConfigFileAccessRights); + this.groupBox2.Controls.Add(this.button_ProcessInfo); + this.groupBox2.Controls.Add(this.label2); + this.groupBox2.Controls.Add(this.textBox_ControlFlag); + this.groupBox2.Controls.Add(this.label17); + this.groupBox2.Controls.Add(this.button_SelectControlFlag); + this.groupBox2.Controls.Add(this.textBox_ProcessName); + this.groupBox2.Location = new System.Drawing.Point(6, 12); + this.groupBox2.Name = "groupBox2"; + this.groupBox2.Size = new System.Drawing.Size(517, 187); + this.groupBox2.TabIndex = 76; + this.groupBox2.TabStop = false; + // + // button_SelectPid + // + this.button_SelectPid.Location = new System.Drawing.Point(463, 19); + this.button_SelectPid.Name = "button_SelectPid"; + this.button_SelectPid.Size = new System.Drawing.Size(41, 20); + this.button_SelectPid.TabIndex = 102; + this.button_SelectPid.Text = "..."; + this.button_SelectPid.UseVisualStyleBackColor = true; + this.button_SelectPid.Click += new System.EventHandler(this.button_SelectPid_Click); + // + // textBox_ProcessId + // + this.textBox_ProcessId.Location = new System.Drawing.Point(202, 19); + this.textBox_ProcessId.Name = "textBox_ProcessId"; + this.textBox_ProcessId.Size = new System.Drawing.Size(242, 20); + this.textBox_ProcessId.TabIndex = 101; + this.textBox_ProcessId.Text = "0"; + // + // radioButton_Name + // + this.radioButton_Name.AutoSize = true; + this.radioButton_Name.Location = new System.Drawing.Point(8, 51); + this.radioButton_Name.Name = "radioButton_Name"; + this.radioButton_Name.Size = new System.Drawing.Size(134, 17); + this.radioButton_Name.TabIndex = 100; + this.radioButton_Name.Text = "Filter By Process Name"; + this.radioButton_Name.UseVisualStyleBackColor = true; + this.radioButton_Name.Click += new System.EventHandler(this.radioButton_Name_Click); + // + // radioButton_Pid + // + this.radioButton_Pid.AutoSize = true; + this.radioButton_Pid.Checked = true; + this.radioButton_Pid.Location = new System.Drawing.Point(8, 19); + this.radioButton_Pid.Name = "radioButton_Pid"; + this.radioButton_Pid.Size = new System.Drawing.Size(114, 17); + this.radioButton_Pid.TabIndex = 99; + this.radioButton_Pid.TabStop = true; + this.radioButton_Pid.Text = "Filter by Process Id"; + this.radioButton_Pid.UseVisualStyleBackColor = true; + this.radioButton_Pid.Click += new System.EventHandler(this.radioButton_Pid_Click); + // + // button_ConfigFileAccessRights + // + this.button_ConfigFileAccessRights.BackColor = System.Drawing.SystemColors.GradientActiveCaption; + this.button_ConfigFileAccessRights.Location = new System.Drawing.Point(201, 145); + this.button_ConfigFileAccessRights.Name = "button_ConfigFileAccessRights"; + this.button_ConfigFileAccessRights.Size = new System.Drawing.Size(241, 20); + this.button_ConfigFileAccessRights.TabIndex = 98; + this.button_ConfigFileAccessRights.Text = "Add File Access Control To Process"; + this.button_ConfigFileAccessRights.UseVisualStyleBackColor = false; + this.button_ConfigFileAccessRights.Click += new System.EventHandler(this.button_ConfigFileAccessRights_Click); + // + // button_ProcessInfo + // + this.button_ProcessInfo.BackColor = System.Drawing.Color.AntiqueWhite; + this.button_ProcessInfo.Image = global::ProcessMon.Properties.Resources.about; + this.button_ProcessInfo.Location = new System.Drawing.Point(463, 145); + this.button_ProcessInfo.Name = "button_ProcessInfo"; + this.button_ProcessInfo.Size = new System.Drawing.Size(41, 20); + this.button_ProcessInfo.TabIndex = 97; + this.button_ProcessInfo.UseVisualStyleBackColor = false; + this.button_ProcessInfo.Click += new System.EventHandler(this.button_ProcessInfo_Click); + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(199, 72); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(209, 13); + this.label2.TabIndex = 90; + this.label2.Text = "( i.e. c:\\testfolder\\*.exe or \'notepad.exe\' )"; + // + // textBox_ControlFlag + // + this.textBox_ControlFlag.Location = new System.Drawing.Point(201, 95); + this.textBox_ControlFlag.Name = "textBox_ControlFlag"; + this.textBox_ControlFlag.ReadOnly = true; + this.textBox_ControlFlag.Size = new System.Drawing.Size(242, 20); + this.textBox_ControlFlag.TabIndex = 73; + this.textBox_ControlFlag.Text = "0"; + // + // label17 + // + this.label17.AutoSize = true; + this.label17.Location = new System.Drawing.Point(6, 95); + this.label17.Name = "label17"; + this.label17.Size = new System.Drawing.Size(142, 13); + this.label17.TabIndex = 72; + this.label17.Text = "Process Access Control Flag"; + // + // button_SelectControlFlag + // + this.button_SelectControlFlag.Location = new System.Drawing.Point(463, 95); + this.button_SelectControlFlag.Name = "button_SelectControlFlag"; + this.button_SelectControlFlag.Size = new System.Drawing.Size(41, 20); + this.button_SelectControlFlag.TabIndex = 74; + this.button_SelectControlFlag.Text = "..."; + this.button_SelectControlFlag.UseVisualStyleBackColor = true; + this.button_SelectControlFlag.Click += new System.EventHandler(this.button_SelectControlFlag_Click); + // + // textBox_ProcessName + // + this.textBox_ProcessName.Location = new System.Drawing.Point(201, 49); + this.textBox_ProcessName.Name = "textBox_ProcessName"; + this.textBox_ProcessName.ReadOnly = true; + this.textBox_ProcessName.Size = new System.Drawing.Size(242, 20); + this.textBox_ProcessName.TabIndex = 77; + this.textBox_ProcessName.Text = "notepad.exe"; + // + // ProcessFilterSetting + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(537, 246); + this.Controls.Add(this.groupBox_AccessControl); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Name = "ProcessFilterSetting"; + this.Text = "Process Filter Rule Setting"; + this.groupBox_AccessControl.ResumeLayout(false); + this.groupBox2.ResumeLayout(false); + this.groupBox2.PerformLayout(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.GroupBox groupBox_AccessControl; + private System.Windows.Forms.GroupBox groupBox2; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.TextBox textBox_ControlFlag; + private System.Windows.Forms.Label label17; + private System.Windows.Forms.Button button_SelectControlFlag; + private System.Windows.Forms.TextBox textBox_ProcessName; + private System.Windows.Forms.Button button_ProcessInfo; + private System.Windows.Forms.Button button_SelectPid; + private System.Windows.Forms.TextBox textBox_ProcessId; + private System.Windows.Forms.RadioButton radioButton_Name; + private System.Windows.Forms.RadioButton radioButton_Pid; + private System.Windows.Forms.Button button_ConfigFileAccessRights; + private System.Windows.Forms.Button button_Save; + } +} \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/ProcessMon/ProcessFilterSetting.cs b/Demo_Source_Code/CSharpDemo/ProcessMon/ProcessFilterSetting.cs new file mode 100644 index 0000000..15032f1 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/ProcessMon/ProcessFilterSetting.cs @@ -0,0 +1,200 @@ +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; + +using EaseFilter.FilterControl; +using EaseFilter.CommonObjects; + +namespace ProcessMon +{ + public partial class ProcessFilterSetting : Form + { + public ProcessFilterRule selectedFilterRule = null; + bool isNewFilterRule = false; + + public ProcessFilterSetting(ProcessFilterRule _selectedFilterRule) + { + StartPosition = FormStartPosition.CenterParent; + InitializeComponent(); + selectedFilterRule = _selectedFilterRule; + + InitSelectedFilterRule(); + } + + private void InitSelectedFilterRule() + { + if (null == selectedFilterRule) + { + selectedFilterRule = new ProcessFilterRule(); + selectedFilterRule.ProcessNameFilterMask = "*"; + selectedFilterRule.ControlFlag = 16130; + + isNewFilterRule = true; + } + + if (selectedFilterRule.ProcessId.Length > 0 && selectedFilterRule.ProcessId != "0" ) + { + textBox_ProcessId.Text = selectedFilterRule.ProcessId; + radioButton_Pid_Click(null,null); + } + else + { + radioButton_Name_Click(null, null); + textBox_ProcessName.Text = selectedFilterRule.ProcessNameFilterMask; + textBox_ControlFlag.Text = selectedFilterRule.ControlFlag.ToString(); + } + } + + private void button_SelectControlFlag_Click(object sender, EventArgs e) + { + OptionForm optionForm = new OptionForm(OptionForm.OptionType.ProcessControlFlag, textBox_ControlFlag.Text); + + if (optionForm.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + textBox_ControlFlag.Text = optionForm.ProcessControlFlag.ToString(); + } + } + + private void button_Apply_Click_1(object sender, EventArgs e) + { + GlobalConfig.SaveConfigSetting(); + } + + private void button_ProcessInfo_Click(object sender, EventArgs e) + { + string information = "Process Control: allow/deny the binaries executing, prevent the suspicious binaries(malware) from executing.\r\n\r\n"; + information += "Get notification for process/thread creation and termination.\r\n\r\n"; + information += "Set the file access rights to the process.\r\n\r\n"; + + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show(information, "Process Filter Setting", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + + + private void radioButton_Pid_Click(object sender, EventArgs e) + { + radioButton_Pid.Checked = true; + textBox_ProcessName.ReadOnly = true; + textBox_ProcessId.ReadOnly = false; + button_SelectPid.Enabled = true; + } + + private void radioButton_Name_Click(object sender, EventArgs e) + { + radioButton_Name.Checked = true; + textBox_ProcessName.ReadOnly = false; + textBox_ProcessId.ReadOnly = true; + textBox_ProcessId.Text = "0"; + button_SelectPid.Enabled = false; + } + + private void button_SelectPid_Click(object sender, EventArgs e) + { + OptionForm optionForm = new OptionForm(OptionForm.OptionType.ProccessId, textBox_ProcessId.Text); + + if (optionForm.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + if (optionForm.ProcessId.Length > 0) + { + textBox_ProcessId.Text = optionForm.ProcessId; + + //we choose to use process Id instead of the process name + textBox_ProcessName.Text = ""; + } + } + } + + private void button_ConfigFileAccessRights_Click(object sender, EventArgs e) + { + + if (textBox_ProcessId.Text.Trim().Length > 0 && textBox_ProcessId.Text != "0" ) + { + if (selectedFilterRule.ProcessId != textBox_ProcessId.Text) + { + selectedFilterRule = new ProcessFilterRule(); + isNewFilterRule = true; + } + + selectedFilterRule.ProcessId = textBox_ProcessId.Text; + + } + else if (textBox_ProcessName.Text.Trim().Length > 0) + { + if (selectedFilterRule.ProcessNameFilterMask != textBox_ProcessName.Text) + { + isNewFilterRule = true; + selectedFilterRule = new ProcessFilterRule(); + } + + selectedFilterRule.ProcessNameFilterMask = textBox_ProcessName.Text; + + } + else + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("The process name mask and Pid can't be null.", "Add Filter Rule", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + uint controlFlag = 0; + + if (uint.TryParse(textBox_ControlFlag.Text, out controlFlag) && ((controlFlag & (uint)FilterAPI.ProcessControlFlag.DENY_NEW_PROCESS_CREATION )> 0)) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("The process was blocked to executed, no need to set the file access rights for the process.", "Add Filter Rule", MessageBoxButtons.OK, MessageBoxIcon.Information); + return; + } + + if (isNewFilterRule) + { + //default file access rights setting for new process filter rule + + //allow the windows dll or exe to be read by the process, or it can't be loaded. + selectedFilterRule.FileAccessRights = "c:\\test\\*!" + FilterAPI.ALLOW_FILE_READ_ACCESS + ";"; + + } + + ProcessFileAccessRights processFileAccessRights = new ProcessFileAccessRights(selectedFilterRule); + processFileAccessRights.ShowDialog(); + } + + private void button_Save_Click(object sender, EventArgs e) + { + if (textBox_ProcessId.Text.Trim().Length > 0 && textBox_ProcessId.Text != "0") + { + //please note that the process Id will be changed when the process launch every time. + selectedFilterRule.ProcessId = textBox_ProcessId.Text; + selectedFilterRule.ProcessNameFilterMask = ""; + } + else if (textBox_ProcessName.Text.Trim().Length > 0) + { + selectedFilterRule.ProcessId = ""; + selectedFilterRule.ProcessNameFilterMask = textBox_ProcessName.Text; + } + else + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("The process name mask and Pid can't be null.", "Add Filter Rule", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + uint controlFlag = 0; + uint.TryParse(textBox_ControlFlag.Text, out controlFlag); + selectedFilterRule.ControlFlag = controlFlag; + + GlobalConfig.AddProcessFilterRule(selectedFilterRule); + + } + + private void button_Cancel_Click(object sender, EventArgs e) + { + } + + + } +} diff --git a/Demo_Source_Code/CSharpDemo/ProcessMon/ProcessFilterSetting.resx b/Demo_Source_Code/CSharpDemo/ProcessMon/ProcessFilterSetting.resx new file mode 100644 index 0000000..acfec18 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/ProcessMon/ProcessFilterSetting.resx @@ -0,0 +1,408 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + AAABAAEAQEAAAAEAIAAoQgAAFgAAACgAAABAAAAAgAAAAAEAIAAAAAAAAEAAABMLAAATCwAAAAAAAAAA + AAAaEmMAFxFfAxkSYQ0cEmY4HRJngh0SZ7kcEmfYHBJn7hwSZ/ocEmf/HBJn/xwSZ/8cEmf/HBJn/xwS + Z/8cEmf/HBJn/xwSZ/8cEmf/HBJn/xwSZ/8cEmf/HBJn/xwSZ/8cEmf/HBJn/xwSZ/8cEmf/HBJn/xwS + Z/8cEmj/GxJk/xkRXv8XD1j/Fg5U/xYOUv8XDlP/Fw5T/xcPVP8XD1T/Fw9U/xcPVP8XD1b/Fw9W/xcP + Vv8XD1b/GA9X/xgPV/8YD1j/GA9Y/xgQWf8YEFn/GBBa/xgQWv8ZEFr/GRBa+hgPXO8YD1zcGRBcvhoQ + XIgZEFs8GBBYDxcQVwQYEFkAEg9bAh0SZhQeE2c4HhNnaR4SZ6IdEmfLHRJn4h0SZ/IdEmf7HRJn/x0S + Z/8dEmf/HRJn/x0SZ/8dEmf/HRJn/x0SZ/8dEmf/HRJn/x0SZ/8dEmf/HRJn/x0SZ/8dEmf/HRJn/x0S + Z/8dEmf/HRJn/x0SZ/8dEmf/HBJl/xsRYf8ZEFv/GA9W/xcPU/8XDlL/Fw5T/xcOU/8XD1T/Fw9U/xcP + VP8XD1T/Fw9V/xcPVv8YD1b/GA9W/xgPV/8YD1f/GA9Y/xkPWP8ZEFn/GRBZ/xkQWv8ZEFr/GRBa/xkQ + W/wZEFvzGRBc5RoQXM8aEFymGxFcbBsRXDoaEFsVFA9UAxcRYA0eE2c4HxNojR8TaMcfE2jfHhNo7h4T + aPYeE2j7HhNo/h4TaP8eE2j/HhNo/x4TaP8eE2j/HhNo/x4TaP8eE2j/HhNo/x4TaP8eE2j/HhNo/x4T + aP8eE2j/HhNo/x4TaP8eE2j/HhNo/x4TaP8eE2j/HhJm/xwRYP8aEFv/GRBW/xgPU/8YD1L/GA9S/xgP + U/8YD1P/GA9U/xgPVP8YD1T/GA9U/xgQVf8ZEFX/GRBW/xkQVv8ZEFf/GRBX/xkQWP8aEFj/GhBZ/xoQ + Wf8aEFr/GhBa/xoRW/8aEVv+GhFb+xoRW/cbEVzvGxFc4RwRXcocEV2PGxFcOhcPVw8fE2g4HxNoaR8T + aMcfE2j9HxNo/x8TaP8gE2j/IBNo/yATaP8gE2j/IBNo/yATaP8gE2j/IBNo/yATaP8gE2j/IBNo/yAT + aP8gE2j/IBNo/yATaP8gE2j/IBNo/yATaP8gE2j/IBNp/yATaf8fE2j/HxNm/x0SYv8bEFr/Gg9V/xkO + Uv8YD1H/GA9S/xkPU/8ZD1P/GQ9T/xkPVP8ZD1T/GQ9U/xoPVP8ZEFX/GhBV/xoQVv8aEFb/GhBX/xoQ + V/8aEFj/GxBY/xsQWf8bEFn/GxBa/xsQWv8bEVv/GxFb/xsRW/8cEVv/GxFc/xwRXP8cEV3+HBFdyhwR + XWwbEF08IRRqgiEUaqIhFGrfIBRp/yAUaf8gFGn/IRRp/yEUaf8hFGn/IRRp/yEUaf8hFGn/IRRp/yEU + af8hFGn/IRRp/yEUaf8hFGn/IRRp/yEUaf8hFGn/IRRp/yEUaf8hFGn/IRRp/yEUav8hFGr/IBNn/x4S + Yf8cEVv/Gg9V/xkOUf8ZDlH/GQ5R/xkPUv8aEFP/GhBU/xoQVP8aEFT/GhBU/xoQVf8bEFX/GxBV/xsQ + Vv8bEFb/GxBX/xsRV/8bEVj/GxFY/xwRWf8cEVn/HBFa/xwRW/8cEVv/HBFb/xwRW/8cEVz/HRFc/x0S + XP8dEl3/HRJe/x0SXuEdEV6mHRFfiCIUa7kiFGvLIRRr7iEUa/8hFGv/IRRr/yEUa/8hFGv/IRRr/yEU + a/8hFGv/IRRr/yEUa/8hFGv/IRRr/yEUa/8hFGv/IRRr/yEUa/8hFGv/IRRr/yEUa/8hFGv/IhRr/yIU + a/8hFGr/IRNn/x8SYv8cEFr/GxFY/xsWWv8bGVz/Gxld/xoWWv8aEVT/Gg9S/xoPU/8aEFT/GhBU/xsQ + VP8bEFX/GxBW/xsQVv8bEFf/GxBX/xsQWP8bEVj/HBFZ/xwRWf8cEVr/HBFa/xwRWv8cEVv/HBFb/xwR + W/8dEVv/HRFc/x0RXf8dEl3/HRJe/x0SXv8eEl/vHhJfzx4SX74jFWzZIxVs4yIVbPYiFWz/IhVs/yIV + bP8iFWz/IhVs/yIVbP8iFWz/IhVs/yIVbP8iFWz/IhVs/yIVbP8iFWz/IhVs/yIVbP8iFWz/IhVs/yIV + bP8iFWz/IhVs/yMVbP8jFWz/IhRp/yASYv8dEFr/Gw5T/xsWWf8dJmz/HjB3/x4weP8dJm3/GxZa/xoN + UP8bDlL/GxBU/xsQVP8cEVX/HBFW/xwRVv8cEVf/HBFX/xwRWP8cEVj/HBFZ/x0RWf8dEVr/HRFa/x0S + W/8dElv/HRJb/x4SW/8dElz/HhJc/x4SXf8eEl3/HhJe/x4SXv8eEl//HxJf9h8SYOUfE2DcJBVs7yQV + bPMkFWz7JBVs/yQVbP8kFWz/JBVs/yQVbP8kFWz/JBVs/yQVbP8kFWz/JBVs/yQVbP8kFWz/JBVs/yQV + bP8kFWz/JBVs/yQVbP8kFWz/JBVs/yQVbP8jFGv/IxNo/yEUZf8gGGP/Hhxj/x0jZ/8eMnb/IUeP/yJT + nf8iU53/IUeQ/x8yd/8dImb/HRpf/xwVWv8cEVX/HBBU/xwQVf8cEVb/HBFX/x0RV/8dEVj/HRFY/x0R + Wf8eEVn/HhFa/x4RWv8eElv/HhJb/x4SW/8fElv/HxJc/x4SXP8eEl3/HxJd/x8SXv8fEl7/HxJf/yAS + X/sgE2DzIBNg7yUWbfolFm37JRZt/iUWbf8lFm3/JRZt/yUWbf8lFm3/JRZt/yUWbf8lFm3/JRZt/yUW + bf8lFm3/JRZt/yUWbf8lFm3/JRZt/yUWbf8lFm3/JRZt/yUWbf8lFm3/JBRp/yIRYP8hFmH/ISRs/yE3 + fv8iT5X/I2Sr/yZ2wP8nf8v/J3/L/yZ2wP8kZKv/Ik6T/yA0e/8fIWf/HhRZ/x0PU/8dEFT/HRFW/x0R + V/8eElf/HhJY/x4SWP8eElj/HxJY/x4SWf8fElr/HxJb/x8SW/8fElv/IBJb/yATXP8fE1z/HxNd/yAT + Xf8gE17/IBNe/yATX/8hE1/+IRNg/CETYPonFm3/JxZt/ycWbf8nFm3/JxZt/ycWbf8nFm3/JxZt/ycW + bf8nFm3/JxZt/ycWbf8nFm3/JxZt/ycWbf8nFm3/JxZt/ycWbf8nFm3/JxZt/ycWbf8mFm3/Jhds/yQb + bf8iI27/IjB4/yNEi/8lW6T/JnbA/yiK1f8qluT/K53r/yud6/8qluT/KYnU/yd0vv8kWaL/IkGJ/yEu + dP8fIWb/Hxhe/x8UWf8eElf/HxFW/x8SV/8fElj/HxJY/x8SWP8fEln/IBJa/yASW/8gElv/IBJb/yAS + W/8gE1z/IRNc/yATXf8hE13/IRNe/yETXv8hE1//IhNg/yETYP8hE2D/KBdv/ygXb/8oF2//KBdv/ygX + b/8oF2//KBdv/ygXb/8oF2//KBdv/ygXb/8oF2//KBdv/ygXb/8oF2//KBdv/ygXb/8oF2//KBdv/ygW + bv8oFW7/Jxdt/yUbbP8kLHn/JUiR/yZgqP8ndL3/KIXR/yuU4/8tnu//LqT3/y6n+/8up/v/LqT3/y2e + 7/8rk+L/KIXQ/yZzvP8lX6f/I0aO/yEscv8gG2H/IBNZ/x8RVv8gEVf/IBJY/yASWf8gEln/IBNZ/yAT + Wv8hE1v/IRNb/yETXP8hE1z/IRNd/yITXf8iE17/IhNe/yIUX/8iFF//IhRg/yMUYP8jFGH/IxRh/ygX + b/8oF2//KBdv/ygXb/8oF2//KBdv/ygXb/8oF2//KBdv/ygXb/8oF2//KBdv/ygXb/8oF2//KBdv/ygX + b/8oF2//KRdv/ykWbv8oGXH/KCB2/ycqff8mN4T/Jk6Y/yhtt/8qhtH/K5bi/yyf7f8uoPL/Lpzv/y2S + 5f8tjeD/LY3g/y2S5f8um+//LqDy/yyf7f8qluL/KYXQ/ydtt/8kT5f/IzZ9/yIlbP8hGmD/IBNZ/yAR + V/8gElj/IBJZ/yATWv8hE1r/IRNb/yETW/8hE1z/IRNc/yITXf8iE13/IhNe/yITXv8iFF//IxRf/yMU + YP8jFGD/IxRh/yMUYf8pGHD/KRhw/ykYcP8pGHD/KRhw/ykYcP8pGHD/KRhw/ykYcP8pGHD/KRhw/ykY + cP8pGHD/KRhw/ykYcP8pGHD/KRhw/yoXb/8qFm7/KSB3/yg2iP8oT5z/KGiy/yp+yP8skd7/Lp7t/y6l + 9v8vpPb/L5ns/y2D1f8qY7L/KFGe/yhRnf8pYbD/LYLU/y+Z7P8vpPb/LqX2/y2e7f8skd7/KX/I/ydm + rv8lSJD/Iy51/yEZX/8hEFX/IRFX/yETWf8hE1r/IhNa/yITW/8iE1v/IhRc/yIUXP8iFF3/IxRd/yMU + Xv8jFF7/IxRf/yQUX/8kFWD/JBVg/yQVYf8kFWH/Kxhw/ysYcP8rGHD/Kxhw/ysYcP8rGHD/Kxhw/ysY + cP8rGHD/Kxhw/ysYcP8rGHD/Kxhw/ysYcP8rGHD/Kxhw/ysYcf8qHXX/Kid9/yo7jv8pV6b/KnO//yuN + 1/8tnOn/L6Ly/y+g8v8vluj/LYjZ/yx1xf8pW6j/JjuE/yQpcf8kKXD/JTmD/ylap/8sdcT/LojZ/y+X + 6f8voPL/L6Ly/y2d6f8ri9X/KG23/yZQmf8kNHv/IyJo/yIYXv8iFFr/IhNa/yITWv8iE1v/IxNb/yMU + XP8jFFz/IxRd/yMUXf8jFF7/JBRe/yQUX/8lFF//JRVg/yQVYP8kFWH/JBVh/ywZcf8sGXH/LBlx/ywZ + cf8sGXH/LBlx/ywZcf8sGXH/LBlx/ywZcf8sGXH/LBlx/ywZcf8sGXH/LBhx/ywZcv8sG3P/KyyB/ypL + m/8qaLX/K4HO/yyV4v8uovD/L6X1/zCe8P8vitz/K2u6/yhPm/8lOX//Iyhs/yIeYf8iGVz/Ihhc/yIe + Yv8jKG3/JjmB/ylQnP8sbLv/L4vd/zCe8P8vpfX/LqHw/yyT4P8qfsn/KGOs/yZFjf8lJ23/JBZc/yQU + W/8jE1v/IxRb/yQUXP8kFF3/JBRd/yQUXf8kFF3/JBVe/yUVX/8lFWD/JhVg/yYVYf8mFWH/JRVh/yUV + Yf8vG3T/Lxtz/y4ac/8tGXL/LRly/y0Zcv8tGXL/LRly/y0Zcv8tGXL/LRly/y0Zcv8uGXL/Lhly/y0Z + cv8tIHj/LC+F/yxKnP8rb73/K4vY/y2d6/8vo/L/L5zt/y+P4P8tfMv/K2Kv/ydDjP8kKW//IRdY/yAP + Tv8hEFD/IRFS/yERU/8hEVL/IRBR/yIYW/8lKnH/KEOP/yxjsf8ufc3/L5Di/y+d7v8vo/P/LZ3q/yyJ + 1f8qa7b/KEeP/yYscv8lHGP/JRRb/yQUW/8kFFz/JRRd/yUUXf8lFF3/JRRe/yUVX/8mFV//JhVg/yYV + YP8mFWH/JhVh/yYVYf8nFWH/NSF4/zMfd/8wHHX/Lxpz/y4Zc/8uGXP/Lhlz/y4Zc/8uGXP/Lhlz/y4a + c/8uGnP/Lxlz/y4Zc/8uG3X/LS+F/yxVpf8sdsT/LpHg/y+i8f8wp/j/MJvs/y5+zv8rX6z/J0CH/yUr + bv8jIGP/Ihha/yETU/8hEFD/IRJS/yISU/8iElP/IhJT/yERU/8iFFb/Ixle/yUiZ/8mLXP/KUKL/yxh + sP8vgNH/L53t/y+o+P8vofH/LZDd/yt1wP8pU5v/Jytz/yYWXv8lFVz/JRVc/yYVXf8mFV3/JhVe/yYV + Xv8mFV//JxVf/ycWYP8nFmD/JxZh/ycWYf8nFmL/KBZi/0EugP9ALH//PSl9/zome/85JHr/NyN5/zYh + eP80IHj/Mx53/zIddv8xG3X/MBp0/y8adP8uIXr/Li+H/y1Nof8teMb/LpXi/zCh8P8wn+//Lo/f/yx2 + xP8oVaH/JTV9/yEaXP8fDUz/Hg1M/x4OTv8eD0//Hw9Q/x8QUf8fEFH/HxBS/yAQUv8gEFP/IBBT/yAP + U/8hD1L/IQ5S/yMcYv8nOIP/Klim/y15yf8vkuL/MKDx/zCh8f8uleL/K3fC/ylLlP8nLHT/Jhxk/yYV + XP8mFVz/JhVd/yYVXv8mFV7/JxVf/ycVX/8nFmD/JxZg/ycWYf8oFmH/KBZi/ygWYv9UQoz/VEGM/1JA + i/9QPYr/TTmH/0k1hf9EMYL/QC1//z0off85JHr/NR94/zEcdv8wHHb/LjCG/y1WqP8tecj/L5bl/zCi + 8f8xm+z/LoLR/ylZo/8lOoD/Iidr/yAZW/8eEFD/HQxM/x0NTP8dDU3/HQ5O/x0OT/8eDk//Hg5Q/x4O + UP8fD1H/Hw9S/yAPUv8fD1L/Hw5S/yAOUv8hElj/Ixxj/yUqc/8oPon/K12r/y+F1v8xne//MKPy/y6W + 5P8secT/KlWe/ycsdP8mF17/JxVd/ycVXf8nFl7/JxZe/ycWX/8oFl//KBZg/ygWYP8oFmH/KRZh/ykX + Yv8pF2L/X02T/19Nk/9eTZP/XUuS/1pHkP9WQ43/UT+L/047iP9KNob/RjGD/0IsgP8+LYH/OzaJ/zhR + of81fMj/M5jk/zKh8P8wl+b/LHrJ/yxcpP8xPnz/NjBm/zswYv9BNGT/Rjtq/0tAcP9PRHP/UUZ1/1NI + d/9USXn/VUl5/1NIeP9RRXb/T0R1/09DdP9PRHX/UkZ3/1JGd/9PQ3b/Sz9x/0Y4bP89MGn/MSpr/yw5 + gf8tXqz/L3/P/zGZ6v8xovH/L5fk/yx5xP8qSZL/KClx/ygaYv8nFFz/JxVd/ygWX/8oFl//KBZf/ygW + YP8pFmH/KRZh/yoWYv8qF2L/KRdi/2BPlf9gT5X/YE6V/2BOlP9fTZT/XkuT/1xKkv9bSZH/WkeQ/1lF + j/9XQ43/VU2X/1Fmrf9Mgsj/RZ/l/z6n8P83mOX/LnbC/yVEi/8uM2//SEVw/2BZeP90bYX/hYCU/5aT + pP+iobH/rKq5/7Oxv/+4t8X/vLrI/726yf+6t8b/s7HA/62ru/+pprb/qqe3/7GtvP+wrbz/qaa1/52a + qv+MiJv/cGmH/0tAcP8zLGr/LDB3/ytLl/8wesn/Mpjo/zGj8f8wleL/LnG8/yxKlP8pJW7/KBNb/ygV + Xf8pFl//KRdg/yoXYP8qF2H/Khdh/yoXYv8rF2L/Kxdj/ysXY/9iUJb/YlCW/2JQlv9iUJb/YlCW/2JQ + lv9iUJb/Y1CW/2NQlv9jUZb/Y1OY/2Fnqv9ei8r/WaTj/1Ow8f9Mpun/RIjL/0Jop/9GS3//V010/3Vv + hv+KiJX/lpSd/6Cgp/+rrLL/tLW7/7q7wf++vsX/wMDI/8jIz//U1tj/3N/e/9/i4P/W2dn/w8bI/7m6 + wP+5uMH/t7W//7Kxuf+rrLP/o6Sq/5GQnf92b4z/Wk56/z8xaP8wM3X/MFag/zB5x/8ymef/MqHu/zGP + 3P8uarX/LDaA/yoaYv8qF1//KhZf/yoXYP8qF2D/Khdh/ysXYf8rF2L/Kxdi/ysXY/8rF2P/ZFGX/2RR + l/9kUZf/ZFGX/2RRl/9kUZf/ZFKX/2RRl/9kUZf/ZFWa/2Rdov9jeLn/YaLf/1+18f9drer/WpbQ/1l0 + p/9qcZf/jI2k/6WlsP+ytbr/r7O2/52fpf+PkJn/hYWS/358jf94dIv/cWuH/2pjgv94c43/m5qm/7m8 + vv/P1NP/xcrL/52fqP9/fpD/bmiG/2hhgv9sZoT/eHWL/4qKl/+dn6f/rrC4/5uaq/9mX4L/QTtu/zEy + c/8sSJP/MHrI/zKa6P8yoe7/MIbT/y5NmP8sKHL/Kxxk/ysWX/8rF1//Kxdg/ysXYP8rF2D/LBhh/ywY + Yv8sGGP/LBhj/2ZTmf9mU5n/ZlOZ/2ZTmf9mU5n/ZlOZ/2ZTmf9mUpj/ZlKY/2ZboP9lcLL/ZI7N/2Sx + 7f9itu//YJvU/2SDtf9uc5b/iYWZ/7O1uv/DyMn/ur3C/6eosv+NjZz/d3WJ/2Vhe/9WT2//SUBn/0E2 + Yf8/NV//WFJy/4qLmf+prbL/sba7/6mttf+SlqH/fX6Q/2tohv9lYYL/bGmH/3p5kP+Nj5z/oqes/7e9 + v/+us7n/iImb/2BZff87KmT/Kilw/y5Wov8xgM7/MqHu/zKa5v8wa7f/LkKN/ywkbf8rFV3/KxZf/ysX + YP8rF2D/LBdg/ywYYf8sGGL/LBhj/ywYY/9pVZr/aVWa/2lVmv9pVZr/aVWa/2lVmv9pVZr/aVSZ/2lT + mP9oZqn/Z4vK/2ao5P9muPP/Y6jg/158sP9pb5j/hIWc/5+gqv+4vL7/sbO6/4uHn/9zaoz/aWCE/19V + fP9SR3L/RDdn/zYnXP83KVv/SD9l/29thP+orLT/sLe8/4uMnP+HiJn/qK61/7e/w/+yucH/sLfB/7K6 + wv+yusD/rra5/6Oqrv+RlZ//kZaf/6Gpr/+Ki5//TT9y/ywfZP8tMHn/L1ij/zKP3P8zovD/M43b/zFl + sf8tL3j/LBRc/ywWXv8sGGD/LBhh/y0YYf8tGGH/LRhi/y0YY/8uGGT/a1ec/2tXnP9rV5z/a1ec/2tX + nP9rV5z/a1ec/2tXm/9rWJz/anCy/2if3P9ntvD/Z7Lq/2OVy/9dZ5f/bGWI/4+Qn/+prrL/tbq8/6Gi + rv9wZ4r/V0l4/1dKeP9WSnf/UkZ0/0s/bv9ENmf/TEFs/2Ziff+Iipj/rbS5/6Sqsf9xb4b/dHSJ/663 + vP/G0dH/uMDH/7G3wf+0u8P/uMHF/7vHxv+iqbD/b2+H/3JyiP+mr7P/oKew/15Wfv82JmL/Lx5j/y47 + hP8xdsL/NJnn/zSf7f8yfsv/LzyG/y0ZYf8tF2D/LRhg/y0YYf8uGGL/LRhi/y4YY/8uGGT/Lxhk/21Z + nf9tWZ3/bVmd/21Znf9tWZ3/bVmd/21Znf9tW5//bWCj/2x8vP9qrOb/aLjv/2ee1f9jf7L/Xl6M/25k + hv+Rkp//p66w/620tf+Zm6f/bmaJ/1lLef9aTnr/X1R+/2Vegv9rZYX/cGmG/357kf+VmKT/nqWr/5if + pf+EhpP/ZGJ6/3Bwhv+kr7T/qLO5/3p6lP9mYIL/b2yH/4qOnv+xvsD/n6ez/1hPe/9VTHf/lp2p/6Cq + r/9ubIb/SDxq/zQiYP8tK3T/MVek/zOAzv8zoO3/Mo3Z/zFLlv8vI27/Lhtk/y4YYP8uGGH/Lxhi/y8Z + Y/8vGWP/Lxlk/zAZZP9vW5//b1uf/29bn/9vW5//b1uf/29anv9vWp7/b2Cj/29srv9tisj/a7Tt/2m1 + 6v9mjMD/Ymuc/19YhP9vZYb/kZKf/6atsP+rsrT/naGr/397lf9ybI3/enSU/4J/m/+Li6D/kpOk/5ia + p/+lqrH/tsDC/6+5u/+Qlp7/dXaH/2Jgef9ydIn/oK2y/5unrv9iYH7/SEBn/1NObv93eo3/rbu9/52m + tP9NQHX/RTdt/4aLnf+Zpaj/eHyM/1ZPc/85J2L/LCFp/zA8iP8yaLT/M5zn/zOZ4/8yXqn/MTR//y8g + av8uF2D/Lxhh/y8YYv8vGWP/MBlj/zAZZP8wGWT/cVyg/3FcoP9xXKD/cVyg/3FcoP9xXKD/cVuf/3Bm + qf9vfLz/bpnV/2y58P9pr+L/ZX2s/2Fdif9fVH7/b2eG/5CSoP+mrrH/r7e5/6uzt/+eo63/oKSw/7C4 + wP+6xMr/vMbK/7vEyP+3wcP/vMfI/8jV1P+7x8j/l5ym/3t7jf9raYH/en2Q/6Oytv+hsbT/c3mK/15f + df9laHv/gouW/66+v/+bpLP/TUF1/0Ezaf94fJD/jpqe/3uEj/9eXXv/PC1m/ywaYf8uJ3D/MVKb/zOU + 3v80oOr/NHO+/zNJlP8wJ3H/Lxdg/y8YYf8wGWL/MBlj/zAZY/8xGmT/MRpk/3Neov9zXqL/c16i/3Ne + ov9zXqL/c12h/3Ndof9ybK3/cInH/2+k3v9uuO//aqfZ/2Vzn/9hVX7/YFN8/3BoiP+PkqD/p7C0/7bB + wv+4w8P/rre5/664uv+4xMf/vMjL/7nByP+zusP/rbO9/7O7wv/D0dH/u8jJ/5uhq/+Cg5T/c3GJ/4GE + mP+pt7z/rL6+/4uXnf97hI7/gIuU/5KgpP+pvbv/kJqq/0o+cv9AMmj/dHiN/4mWm/95hI7/X2B8/z0u + Z/8sFl3/LRth/zBDiv8ziNL/NZ/p/zWCzv80W6b/MS53/y8XX/8wGGD/MBli/zAZY/8wGWP/MRpk/zEa + ZP92YKP/dmCj/3Zgo/92YKP/dmCj/3Zfov92XqL/dXGx/3KV0P9wrOP/cLPp/2ydz/9mbpn/YlR9/2JU + ff9xaYn/j5Kg/6q1t//Azs3/wM7N/6u2uf+bo6v/kpel/4uLoP+Ef5v/fneX/3x0lf+LiqL/qrW8/7C+ + v/+dpaz/iYub/3l2kP+Hh57/r7vC/7nLyv+ktbX/m6ut/6Cxsv+itrX/n7Sy/32Imf9DN2z/QjVq/3mA + kv+Lmp7/c32K/1dXdv86K2T/LRVb/y4WXP8xOYD/NHnE/zaW4v82jNj/NGm0/zEye/8wFl//MBdg/zEZ + Yv8xGmP/MRpj/zEaZP8yGmX/eGKl/3hipf94YqX/eGKl/3hipf94YaT/eGCj/3Z1tf9zn9f/cbPo/3Gu + 4/9ulcb/aGuW/2RVff9kVn7/c2uK/4+SoP+otLb/vMvK/7fFx/+coq3/hoaa/3h0jv9tZYf/Z1qD/2NU + gP9jU4D/dW2P/5adqv+ms7b/oq2x/5KXpP98d5T/hYKd/6y2vv+7y8r/r8HA/6u+vf+wxcP/qLy7/4+i + pP9rdIf/Qjho/0tCcP+Dj53/j6Cl/2pxhf9LR23/NyZi/y4VW/8uFVr/MTN6/zVtuP82j9v/NpTf/zV1 + v/8yNn//MRZe/zEYYP8xGmL/MRpj/zIaY/8yGmT/Mxpl/3pkpf96ZKX/emSl/3pkpf96ZKX/emOk/3pi + pP94ebf/dKbd/3K36/9yqt7/b4/A/2prlP9mV37/Zld+/3Rsi/+Pk6D/oq6x/6q5uv+fqbH/goCY/3Fn + if9tYYb/al2E/2dZg/9mVoL/ZVaC/3JojP+Ljp//n6qv/6u5uv+eprH/fHaV/3x2lf+fprH/sL6//6u6 + u/+svb3/scbE/6G0tv98iJP/XGB3/0dCaP9aW3r/kaSr/5Onrf9fYH//PjFk/zMfXv8vF1v/LxZb/zEx + d/81ZK7/N4nU/zaa5P81fsf/MzqC/zEXXv8yGGD/Mhti/zIbY/8zG2P/Mxtk/zQbZP98Zqf/fGan/3xm + p/98Zqf/fGan/3xlpv98Zab/en27/3Wt4/9zu+7/c6XY/3CJuP9rapP/aFl//2dZf/91bov/jpSh/56r + rv+grrD/kpml/3Zvjf9qXYP/b2SH/3Nri/92bo7/d3CP/3hwkf+AfZf/kJak/6OwtP+2yMb/rLvA/4qL + ov+Bfpn/lJmm/6Grsf+ls7b/qrq7/62/v/+bqq//dn2N/2Bkev9eYnr/bnqL/46kqP+ElaH/Ukx2/zUi + Xv8xG13/MBhc/zAYXP8yLnT/NVqk/zeCzP82n+j/NYfP/zM+hf8yGF//Mhlg/zIbYv8zG2P/NBtj/zQb + ZP80G2T/fmio/35oqP9+aKj/fmio/35oqP9+Z6j/fmip/3uCv/92s+j/c77v/3Oh0f9xg7D/bGmR/2lb + gP9pW4H/dm+M/46Uof+cqq3/n62v/5KZpP94co//cWiJ/359k/+JjJz/j5Wh/5Obpv+Wn6n/nKav/6Sz + t/+ww8T/wNbT/7zRz/+lsrn/lJuo/42QoP+RlqP/n62x/6a3uP+ktLX/lqKp/36Dk/94f5D/hZee/4ad + oP96j5X/Y2uC/0I2af8xGlz/MBlc/zEZXP8xGFz/Mitw/zZQmv83ecT/NqLq/zWO1v8zQor/Mxpi/zMa + Yf8zG2L/Mxxj/zQcY/81HGT/NRxl/4Bqqv+Aaqr/gGqq/4Bqqv+Aaqr/gGqq/39srP99h8P/d7fr/3W/ + 7/90ncz/cn+r/25pkP9rXYL/a12C/3dwjf+OlKH/nayv/6O0tf+dqbD/jI+i/4iKnv+Sm6X/mqeq/52s + rf+gr7D/orGy/6S0tf+nt7n/rb/A/7bKyv+2ysr/rb/A/6KwtP+Wn6r/l6Cr/6Ozt/+pvLv/pre4/56s + sP+TnKj/laOs/6S9u/+XsLD/bnqK/05Lb/84KGH/Lxdb/zAYXP8xGVz/MRlc/zMobv82SJL/N3O+/zai + 6v81k9r/NEiP/zQeZv8zG2L/Mxti/zQcY/81HGT/NRxl/zUcZf+CbKv/gmyr/4Jsq/+CbKv/gmyr/4Jt + rP+Bca//f4zG/3m57P92v+3/dpzJ/3N+qf9vao//bV+D/21fg/94cY7/jZWh/5+wsv+swcD/sMbG/63A + w/+qvL//p7q6/6S1tf+gr7D/nKqt/5qmq/+Yo6n/l6Kp/5eiqv+ZpKz/nKmw/6KxtP+oubv/rsLD/7HG + x/+wxcX/sMXE/7HHxP+xxsX/sMTG/7PJyf+40s7/n7K4/2tpiv9HOGv/NyJf/zAYW/8wGVv/MRlc/zEZ + XP8zJ2z/NkSN/zdvuP82ouj/Npbb/zVOlf81JGv/NB1k/zQbYv80HGL/NRxk/zYcZf82HGX/hG6t/4Ru + rf+Ebq3/hG6t/4Rurf+Eb67/g3Wy/4CPyP97u+z/eL/s/3ebyP91faf/cWuQ/25hhP9uYYX/eXKP/46V + of+gsrP/r8bE/7XNy/+wxsb/qry//6Kwtv+bpq7/lZyn/5CVov+MkJ//ioyd/4iJm/+Ghpn/hISY/4eK + nP+Rl6X/naix/6q7wP+uwcX/qry//6m7vf+rvr//rcDC/7DBxf+1ysz/vNXT/6W1v/9yapH/UTxz/0Mu + af86JGP/NB1e/zEZXP8yGVz/NCdr/zdCiv84bbX/N6Hm/zaY3P82Upn/Nihv/zUfZf81HGL/NRxj/zYc + ZP82HGX/Nxxl/4Zvrv+Gb67/hm+u/4Zvrv+Gb67/hnGw/4V3tf+Ckcr/fbzt/3rA7P95m8f/dn6n/3Js + kf9wYob/cGKG/3p0j/+OlaH/n7Gy/6zDwf+pvb//lqCs/4qMn/+EgZr/gHqW/353lP99dZP/fHOS/3ty + kf97cZH/enCR/3lvkf96cZL/fXaV/4N9mv+KiKH/j5Km/5GYp/+TnKj/lJyo/5OZp/+RlKf/nKW0/7LI + yv+pusP/gnud/2hVhv9dSn7/Tztz/zwmZP8zGlz/Mxlc/zUma/84QYn/OGy0/zeh5v82md3/N1Sb/zcq + cf82H2b/Nhti/zYcY/83HGT/Nx1l/zgdZf+IcbD/iHGw/4hxsP+Ica//iHCv/4hzsf+Hebf/hJPM/36+ + 7f97wOz/epvG/3h+p/90bZL/cWSH/3Jkh/97dZD/jpah/52vsP+mu7r/na2z/4WGmv93bYz/dGaK/3Jj + iv9zY4r/c2SL/3Nki/90Zoz/dmiN/3dqjv93ao//dmmP/3Vnjv91aI7/eGuQ/3xzk/+BfZf/g4GZ/4OA + mf+BfZf/f3qW/46Rpv+swcX/q73E/4qFpP91ZJH/b12M/2JPgv9NOHL/Pydm/zceYP81Jmv/OECI/zhr + s/83oeX/N5rd/zhVnP84K3P/NyBn/zYcY/83HGP/Nxxk/zgdZf84HWX/inKx/4pysf+KcrH/inKw/4py + sP+KdbP/iXy5/4WWzf+Av+7/fMHs/3ubxv95fqf/dm6S/3NmiP9zZYn/fXaS/4+Xov+aq63/nrKx/5Wh + qf+Ae5X/dWeL/3Rli/90ZYv/dGWL/3RljP90Zoz/dmmN/3pvj/98c5H/fXWS/3t0kv94bpH/d2qQ/3dp + kP94apH/em6S/3tvk/98b5T/fHGU/312lf+Nkqb/q8HE/6q9w/+KhqT/eWiT/3dmkv9yYI7/ZlSF/1ZB + eP9BKGf/Nydr/zg/hv85abH/N6Hl/zea3v85V57/OSx1/zchaP83HGP/Nxxj/zgdZP84HWX/OB1m/4x0 + sf+MdLH/jHSx/4xzsf+Mc7H/i3e0/4p+uv+HmM//gcDu/37B6/98m8b/en+n/3dvk/91Z4n/dWeK/354 + kv+Pl6L/mKqr/5qtrf+Snqb/g4GX/3x0kv9/eZX/gn6Z/4SBnP+Fg57/hoWe/4eJoP+LjaH/jZGj/42S + o/+MkaP/io2j/4iJo/+HhqL/h4Og/4WBn/+Efpz/gnqa/4B5mP+AfJj/j5an/6rCw/+ovML/ioak/3pq + lf97a5b/e2qV/3dlkv9pVob/Uz11/0Q2df8+Q4n/Ommw/zih5P84m9//OVig/zkudv84IWj/Nxxj/zgd + Y/84HWT/OB1l/zgdZv+NdbL/jXWy/411sv+NdbL/jXWy/414tf+Lgbz/iJrQ/4LB7/9/wuv/fZzE/3t/ + pv94cJP/dmiK/3Zoiv9+eZP/jpii/5eqq/+Zrq7/laWq/4yUoP+LkZ//kp2o/5qpsf+gsrn/pLm+/6a8 + wP+mvsD/p73A/6a9v/+lvL7/pr2+/6a+wP+mvsH/pbzB/6O4vv+gsrr/mqqz/5Ofqf+NlKL/iIyd/5Kd + qf+pw8P/przB/4qHpP97a5X/fGyW/31tl/99bJb/d2WR/2xZif9dUYj/S06P/z5qr/85oeT/N5zf/zla + ov86MHj/OCJp/zgcYv84HWP/OB1l/zkdZv86Hmb/j3e0/493tP+Pd7T/j3e0/493tP+Perf/jYO9/4mc + 0f+Ew+//gMPr/3+cxP98gKX/eXGT/3hqi/94aov/gHqT/46Yov+Zra7/nra1/520tP+WqKv/laWq/5qu + sP+ftbb/o7u9/6a+wf+ov8L/qL7B/6e7wP+mub7/pbm9/6W6vv+nvcD/qL/C/6e/wv+mvsD/pLy9/6C3 + t/+ar7D/lqer/5Oiqf+brrP/qsjF/6W7wf+LiKX/fW2W/35ul/9/b5j/gG+Z/39umP98a5X/cWWV/15f + mf9NdrX/P6bl/zmd3/86XKP/OjF6/zkjaf84HGL/OB1j/zoeZ/8+H2v/PyBu/5J5tv+Sebb/knm2/5J5 + tv+Sebb/kXy5/4+Gv/+LntP/hsTw/4LD6/+BnMP/foGl/3tzlP96bIz/emyN/4F7lP+OmKL/nLGy/6jF + wv+pyMT/oLq5/5musP+Vp6r/kqCn/4+Zpv+Nk6X/jIyj/4yJov+MiKL/jIii/4uIof+LiKL/jImj/42L + pP+OjqX/j5Sm/5KdqP+Uo6r/lqis/5qvsv+hurv/qMbD/67Qyv+ku8D/jIml/4Bvl/+AcJj/gXGa/4Fx + mv+BcZr/gXCZ/35xnf93dab/ZovB/0yu6f89nt//PF6k/zszfP85I2r/ORxi/zodZP8+IGv/RSN3/0gl + ff+Ue7f/lHu3/5R7t/+Ue7f/lHu3/5N/uv+RiMH/jaDU/4fF8P+Ew+r/gpzD/4CBpf99dZX/e26O/3xu + jv+CfJX/jpii/5uysv+pycT/qcjG/52xtv+ToKn/jZWh/4eLm/+DgZj/gHiV/35wkv9+bZH/fm6S/35u + k/9+bpP/fm6T/35ulP9/cJX/gHOW/4J6mP+GhJv/io6f/4+Wpf+WpK7/oLe6/6jHw/+sz8n/o7q//42J + pf+CcJn/gnGa/4Nzm/+Dc5v/g3Ob/4Rym/+Ed6H/hYGt/3iYyP9etuv/TKTg/0Jipv88Nn3/OiRq/zsd + ZP8+IGr/RCN0/0smgP9OKIb/lX24/5V9uP+Vfbj/lX24/5V9t/+Ugbv/korC/4+j1f+JxvH/hcPq/4Oc + wv+BgaX/fnWW/31vj/99b4//gn2W/42Yof+Yr67/ob+8/561uP+OkaT/hH6Y/4N7lv+CeZX/gXaU/4Bz + lP+AcZP/f3CT/4BwlP+AcZT/gHGU/4Bxlf+AcJX/gHGW/4Fyl/+CdZj/g3iZ/4V7mv+GfZz/ioig/5Gc + p/+asrP/psfC/6G5vf+Niqb/g3Ka/4Rzm/+EdJz/hHSc/4R0nP+FdJz/hnmi/4eDrv+CnMj/d7/s/2Wu + 4v9Oaan/QDqA/zwmbP8+H2n/RiN2/0wngf9PKYf/USmK/5d/uf+Xf7n/l3+5/5d+uP+Xfrj/loO8/5SN + xP+Qpdf/isfx/4bE6v+FncL/g4Gl/4B1lv9+cI//fnCQ/4J7lf+KkJ3/k6Wp/5y3tf+asbT/jZKk/4WB + mv+Ef5n/hH6Y/4N8l/+Depb/gnmW/4J3lv+CdpX/gnWW/4J1lv+DdZf/g3aY/4N4mP+EeZn/hHua/4V9 + mv+Gf5z/h4Ge/4qLof+QnKf/l66v/5+9uv+bsLb/jIik/4Rzm/+FdJv/hnWc/4Z1nP+GdZz/hnSc/4d5 + ov+Iha//iJ/J/4XF7f93uOX/YHqz/09KjP9FLnb/RCNy/0wmgP9RKYn/UiqL/1MqjP+YgLr/mIC6/5iA + uv+YgLr/mIC6/5eEvf+Vj8X/kabY/4vI8f+Ixuv/h6DE/4SEp/+Bd5f/gHGP/4BxkP+Bd5P/hYGX/42V + ov+ZsbL/nry5/5u0tf+Wqq//kKCo/4uXov+KkJ7/iIqb/4aGmf+Egpj/hH6X/4N7l/+Depj/hHuZ/4V/ + mv+Hgpv/iIad/4mLnv+LkqD/jpmk/5Ghqv+WrLH/nbq6/568uv+YsbH/kZ2o/4mDoP+Gdpz/h3ad/4d3 + nf+Hdp3/h3ac/4d1nP+Ie6P/ioex/4uiy/+Jx+3/g8Lr/3mSw/9qZKH/Vj2J/04pgf9RKYj/UyqM/1Mr + jP9UK43/moK8/5qCvP+agrz/moK8/5qCu/+Zhb7/mI7F/5Ol1v+NyPD/icvw/4mw1P+Hmr3/hoyt/4SD + pP+EgKH/hH6e/4V/nP+KiqD/k6Cq/5qwsf+ct7X/mrez/5Wvrf+SqKn/kaOn/5Cfpv+OnKX/jpmk/42W + pP+NlKT/jZOl/46Upf+Ol6b/j5qn/5Ccp/+RoKj/kqWo/5Oqqv+Wr67/mrW0/5+5uv+csbb/kp2o/4uM + oP+Jfp7/iHie/4l7ov+KfqX/ioGo/4qEq/+Kh67/i4+2/4ycxP+Msdn/i8zx/4vG7f+Kn83/gHex/21S + nf9fOpL/WC+O/1Qrjf9VK43/VSuO/5yEvf+chL3/nIS9/5yEvf+chL3/nIa//5qMw/+WodP/j8Xt/4vT + 9/+LzO//jMDk/4yz1/+Mp8z/i5zB/4qTt/+Ji63/iYem/4uHoP+Nj6D/kJyk/5KlqP+Uqqr/la6t/5ez + sv+Zt7X/m7m4/527uv+evLv/n728/5+9vf+evLz/nby7/527uv+cubn/mre2/5izsf+Wr67/lKur/5Sk + qf+Tmaj/kY+l/42FoP+Lfp7/i3ue/4t9o/+NhKz/joy1/4+Vvv+Pn8f/jqnR/4602/+Nweb/jMzw/4zU + +P+Pxez/lKDQ/5KCu/+Hba//dlSj/2E4lf9WK47/ViuO/1Ysj/+ehr//noa//56Gv/+ehr7/noa+/56H + v/+dicH/mpnM/5S14f+Rx+7/kM3z/5DN8v+Rxu3/kL/l/4+33f+OrtP/jaXJ/4ucvv+Jk7T/iZSw/4uf + sv+Pp7b/kq65/5a0vf+ZusH/m77F/57Bx/+gxMn/ocbK/6LHyv+ixsr/ocbJ/6DEx/+fwsb/nsDF/5y8 + wv+Ytr7/lbG6/5Ortv+RorP/jpax/42Qsf+MjrL/jI+0/42Stv+Nl7z/jp7F/4+nzv+QsNf/kLjf/5DA + 5/+Qx+7/kM3z/5DO8/+Rx+7/lbbh/5uazf+ciMD/mH67/4lpsP9vSZ//XzWU/1kukP9XK4//oIfA/6CH + wP+gh8D/oIe//6CHv/+gh8D/oIjA/56OxP+cms3/mabW/5ez4P+Vvef/k8Pr/5HJ7v+QzPD/j83v/47K + 7P+Oxuj/jcLk/43A4f+PwN//kL/c/5K92v+Tu9j/lLjV/5W20/+WtdL/l7XR/5e00P+Xs87/l7HN/5ew + zP+XsMv/lrDM/5awzf+VsM3/lLDO/5Owzv+Ssc7/kbHQ/5Gx0/+Qs9f/j7fb/4+73/+PwOP/j8Tm/4/H + 6v+Pyu3/j83w/5DN8f+RyvD/ksXt/5S+6P+WtOD/mafX/5yazf+fj8X/oIjA/5+Gv/+Vebj/gmGs/3BK + n/9fNZT/VyuP/6KJwf+iicH/oonB/6KJwf+iicH/oonA/6KIwP+iicH/oYzC/5+Sx/+dntD/m6nY/5iz + 3/+WvOb/lcXs/5TK8P+TzfL/k8/z/5PQ9f+Tz/T/k83y/5PK7/+Sxu3/ksPp/5K/5v+SvOP/kbrg/5G5 + 3/+Rt97/kbbc/5G02v+Rs9r/kbPa/5G02/+Rttz/kbje/5G54P+Su+H/kr3j/5LA5v+TxOn/k8ft/5PK + 7/+TzfL/k8/0/5PQ9P+Sz/P/k83y/5PK8P+Uxez/lr3n/5e14f+aq9n/nZ/R/5+TyP+hi8P/oonB/6KJ + wf+jisH/noO+/5N2t/+BX6v/akKb/14zk/+jisL/o4rC/6OKwv+jisL/o4rC/6OKwf+jisH/o4rB/6OL + wv+jjcP/opHG/6GUyf+gmMv/n5zO/56h0v+dp9f/m6/c/5q14f+ZuuX/mL7o/5fC6v+Vxez/lMnv/5TL + 8P+TzPH/k83x/5LO8f+Rz/L/kdDy/5HQ8v+Rz/L/kc/x/5HP8f+Rz/L/kdDy/5HQ8v+Rz/L/ks/y/5PO + 8v+TzPH/lMvw/5XJ7v+Wxuz/l8Lp/5i+5/+ZueT/mrXg/5uv3P+cp9f/nqHS/5+cz/+gmMz/oZXJ/6KR + xv+jjcP/o4vC/6OKwv+jisL/pIvC/6OJwf+ghr//kXO1/3lUpv9tRJ7/pIvC/KSLwv2ljML+pYzC/6WM + wv+ljML/pYzC/6WMwv+ljML/pYvC/6WLwv+li8L/pYrB/6WLwv+kjsT/o5PH/6Gazf+goNH/n6XV/56q + 2f+cr9z/m7Xg/5q65P+Zvuf/mcHp/5jD6/+Xxez/l8ft/5fI7v+Xye//l8nv/5fK8P+XyvD/l8rv/5fJ + 7/+XyO7/l8ft/5fF7P+Yw+v/mcHp/5m95v+aueP/nLXf/52v3P+eqtj/n6XV/6Cg0f+hms3/o5PH/6SO + xP+li8L/pYrB/6WLwv+li8L/pYvC/6WMwv+ljML/pYzC/6WMwv+ljcP/po3D/5yBvf6KarH9gV2r/KSK + wvWli8L4po3D/aaNxP+mjcP/po3D/6aNw/+mjcP/po3D/6aNw/+mjcP/po3D/6aMw/+mjcP/po3E/6aP + xf+lkcb/pZPI/6SVyf+kl8r/pJjL/6Oazf+jnM7/o53P/6Ke0P+in9H/oqDR/6Kg0f+iodL/oqLT/6Gj + 1P+hpNT/oaTU/6Gj1P+iotL/oqHS/6Kg0f+ioNH/op/R/6Ke0P+jnc//o5zO/6Oazf+kmMv/pJbK/6SV + yf+lk8j/pZHG/6aPxf+mjcT/po3D/6aMw/+mjcP/po3D/6aNw/+mjcP/po3D/6aNw/+mjcP/p47E/6eO + xP+jisL9nYG++Jl8u/WjicLnpYrD7qeNxPmoj8X/qI/F/6iPxf+oj8X/qI/F/6iPxf+oj8X/qI/F/6iP + xf+oj8X/qI/F/6iPxf+ojsX/qI7E/6iOxP+ojsT/qI7E/6iOxP+ojcT/qI3E/6iNxP+ojcT/qI3D/6iN + w/+ojcT/qI3E/6iNxf+oj8X/qJDG/6iQxv+oj8X/qI7E/6iNw/+ojcP/qI3D/6iNxP+ojcT/qI3E/6iN + xP+ojcT/qI7E/6iOxP+ojsT/qI7E/6iOxP+ojsX/qI/F/6iPxf+oj8X/qI/F/6iPxf+oj8X/qI/F/6iP + xf+oj8X/qI/F/6iPxf+oj8X/qI7F+aeOxO6njcTooobB0aSJw92ojsX0qpDG/6qQxv+qkMb/qpDG/6qQ + xv+qkMb/qpDG/6qQxv+qkMb/qpDG/6qQxv+qkMb/qpDG/6qQxv+qkMb/qpDG/6qQxv+qkMb/qo/G/6qP + xv+qj8b/qo/G/6qPxf+qj8X/qo/G/6qPxv+qj8b/qpDG/6qQxv+qkMb/qpDG/6qPxv+qj8X/qo/F/6qP + xf+qj8X/qo/G/6qPxv+qj8b/qo/G/6qQxv+qkMb/qpDG/6qQxv+qkMb/qpDG/6qQxv+qkMb/qpDG/6qQ + xv+qkMb/qpDG/6qQxv+qkMb/qpDG/6qQxv+qkMb/qpDG/6mQxvSoj8Xep47F0qCEwJukiMO1qY/G56uS + x/+sksj/rJLI/6ySyP+sksj/rJLI/6ySyP+sksj/rJLI/6ySyP+sksj/rJLI/6ySyP+sksj/rJLI/6yS + yP+sksj/rJLI/6ySyP+sksj/rJLI/6ySyP+sksj/rJLI/6ySyP+sksj/rJLH/6ySx/+sksf/rJLH/6yS + x/+sksj/rJLI/6ySyP+sksj/rJLI/6ySyP+sksj/rJLI/6ySyP+sksj/rJLI/6ySyP+sksj/rJLI/6yS + yP+sksj/rJLI/6ySyP+sksj/rJLI/6ySyP+sksj/rJLI/6ySyP+sksj/rJLI/6ySyP+rksfoqZDGuKiP + xp+af75Jo4nDeKqQxtCsksj/rZPI/62Uyf+tk8n/rZPJ/62Tyf+tk8n/rZPJ/62Tyf+tk8n/rZPJ/62T + yf+tk8n/rZPJ/62Tyf+tk8n/rZPJ/62Tyf+tk8n/rZPJ/62Tyf+tk8n/rZPJ/62Tyf+tk8n/rZPJ/62T + yP+tk8j/rZPI/62TyP+tk8j/rZPJ/62Tyf+tk8n/rZPJ/62Tyf+tk8n/rZPJ/62Tyf+tk8n/rZPJ/62T + yf+tk8n/rZPJ/62Tyf+tk8n/rZPJ/62Tyf+tk8n/rZPJ/62Tyf+tk8n/rZPJ/62TyP+tk8n/rZPJ/66U + yf+ulMn/rpXJ062UyX2sk8hRjXW3FqKJwkKpj8aWq5DH0KyRyOetksj0rpTJ+q6Uyf2vlcn+r5XK/6+V + yv+vlcr/r5XK/6+Vyv+vlcr/r5XK/6+Vyv+vlcr/r5XK/6+Vyv+vlcr/r5XK/6+Vyv+vlcr/r5XK/6+V + yv+vlcr/r5XK/6+Vyv+vlcr/r5XK/6+Vyv+vlcr/r5XK/6+Vyv+vlcr/r5XK/6+Vyv+vlcr/r5XK/6+V + yv+vlcr/r5XK/6+Vyv+vlcr/r5XK/6+Vyv+vlcr/r5XK/6+Vyv+vlcr/r5XK/6+Vyv+vlcr/r5XK/6+V + yv6vlcr9r5XK+q6UyfWulMnpr5XK07CWypuxmMtItpvNHYZvswWehcAZoonCQqaKxHiojMa2q47H3q6S + yO6vlcn4sJbK/bCWy/+wlsv/sJbL/7CWy/+wlsv/sJbL/7CWy/+wlsv/sJbL/7CWy/+wlsv/sJbL/7CW + y/+wlsv/sJbL/7CWy/+wlsv/sJbL/7CWy/+wlsv/sJbL/7CWy/+wlsv/sJbL/7CWy/+wlsv/sJbL/7CW + y/+wlsv/sJbL/7CWy/+wlsv/sJbL/7CWy/+wlsv/sJbL/7CWy/+wlsv/sJbL/7CWy/+wlsv/sJbL/7CW + y/+wlsv/sJbL/7CWy/+wl8v9sJfL+bCWy/CvlMngrpTJurCVyn+yl8xIs5jMHbmfzweQd7gAhW+yBox0 + thaegsBKpYfEnKmMxtKtksjosJXK9rGXy/yxl8v/sZfL/7GXy/+xl8v/sZfL/7GXy/+xl8v/sZfL/7GX + y/+xl8v/sZfL/7GXy/+xl8v/sZfL/7GXy/+xl8v/sZfL/7GXy/+xl8v/sZfL/7GXy/+xl8v/sZfL/7GX + y/+xl8v/sZfL/7GXy/+xl8v/sZfL/7GXy/+xl8v/sZfL/7GXy/+xl8v/sZfL/7GXy/+xl8v/sZfL/7GX + y/+xl8v/sZfL/7GXy/+xl8v/sZfL/7GXy/+xl8v/sZfL/bGYzPewl8vqr5TJ1a6TyKKxlMpTtpbOHreX + zwi1ls4AgAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAE= + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/ProcessMon/ProcessFilterSettingCollection.Designer.cs b/Demo_Source_Code/CSharpDemo/ProcessMon/ProcessFilterSettingCollection.Designer.cs new file mode 100644 index 0000000..551ec61 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/ProcessMon/ProcessFilterSettingCollection.Designer.cs @@ -0,0 +1,144 @@ +namespace ProcessMon +{ + partial class ProcessFilterSettingCollection + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ProcessFilterSettingCollection)); + this.groupBox_AccessControl = new System.Windows.Forms.GroupBox(); + this.button_ModifyFilter = new System.Windows.Forms.Button(); + this.button_Apply = new System.Windows.Forms.Button(); + this.button_DeleteFilter = new System.Windows.Forms.Button(); + this.button_AddFilter = new System.Windows.Forms.Button(); + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.listView_FilterRules = new System.Windows.Forms.ListView(); + this.groupBox_AccessControl.SuspendLayout(); + this.groupBox1.SuspendLayout(); + this.SuspendLayout(); + // + // groupBox_AccessControl + // + this.groupBox_AccessControl.Controls.Add(this.button_ModifyFilter); + this.groupBox_AccessControl.Controls.Add(this.button_Apply); + this.groupBox_AccessControl.Controls.Add(this.button_DeleteFilter); + this.groupBox_AccessControl.Controls.Add(this.button_AddFilter); + this.groupBox_AccessControl.Controls.Add(this.groupBox1); + this.groupBox_AccessControl.Dock = System.Windows.Forms.DockStyle.Fill; + this.groupBox_AccessControl.Location = new System.Drawing.Point(0, 0); + this.groupBox_AccessControl.Name = "groupBox_AccessControl"; + this.groupBox_AccessControl.Size = new System.Drawing.Size(537, 445); + this.groupBox_AccessControl.TabIndex = 26; + this.groupBox_AccessControl.TabStop = false; + // + // button_ModifyFilter + // + this.button_ModifyFilter.Location = new System.Drawing.Point(139, 399); + this.button_ModifyFilter.Name = "button_ModifyFilter"; + this.button_ModifyFilter.Size = new System.Drawing.Size(103, 23); + this.button_ModifyFilter.TabIndex = 85; + this.button_ModifyFilter.Text = "Modify Filter Rule"; + this.button_ModifyFilter.UseVisualStyleBackColor = true; + this.button_ModifyFilter.Click += new System.EventHandler(this.button_ModifyFilter_Click); + // + // button_Apply + // + this.button_Apply.DialogResult = System.Windows.Forms.DialogResult.OK; + this.button_Apply.Location = new System.Drawing.Point(383, 399); + this.button_Apply.Name = "button_Apply"; + this.button_Apply.Size = new System.Drawing.Size(138, 23); + this.button_Apply.TabIndex = 84; + this.button_Apply.Text = "Apply Filter Rule Settings"; + this.button_Apply.UseVisualStyleBackColor = true; + this.button_Apply.Click += new System.EventHandler(this.button_Apply_Click_1); + // + // button_DeleteFilter + // + this.button_DeleteFilter.Location = new System.Drawing.Point(257, 399); + this.button_DeleteFilter.Name = "button_DeleteFilter"; + this.button_DeleteFilter.Size = new System.Drawing.Size(103, 23); + this.button_DeleteFilter.TabIndex = 83; + this.button_DeleteFilter.Text = "Delete Filter Rule"; + this.button_DeleteFilter.UseVisualStyleBackColor = true; + this.button_DeleteFilter.Click += new System.EventHandler(this.button_DeleteFilter_Click); + // + // button_AddFilter + // + this.button_AddFilter.Location = new System.Drawing.Point(7, 399); + this.button_AddFilter.Name = "button_AddFilter"; + this.button_AddFilter.Size = new System.Drawing.Size(116, 23); + this.button_AddFilter.TabIndex = 82; + this.button_AddFilter.Text = "Add New Filter Rule"; + this.button_AddFilter.UseVisualStyleBackColor = true; + this.button_AddFilter.Click += new System.EventHandler(this.button_AddFilter_Click); + // + // groupBox1 + // + this.groupBox1.Controls.Add(this.listView_FilterRules); + this.groupBox1.Location = new System.Drawing.Point(7, 32); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size(517, 355); + this.groupBox1.TabIndex = 81; + this.groupBox1.TabStop = false; + this.groupBox1.Text = "Process Filter Rule Collection"; + // + // listView_FilterRules + // + this.listView_FilterRules.Dock = System.Windows.Forms.DockStyle.Fill; + this.listView_FilterRules.FullRowSelect = true; + this.listView_FilterRules.Location = new System.Drawing.Point(3, 16); + this.listView_FilterRules.Name = "listView_FilterRules"; + this.listView_FilterRules.Size = new System.Drawing.Size(511, 336); + this.listView_FilterRules.TabIndex = 1; + this.listView_FilterRules.UseCompatibleStateImageBehavior = false; + this.listView_FilterRules.View = System.Windows.Forms.View.Details; + // + // ProcessFilterSettingCollection + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(537, 445); + this.Controls.Add(this.groupBox_AccessControl); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Name = "ProcessFilterSettingCollection"; + this.Text = "Process Filter Rule Settings"; + this.groupBox_AccessControl.ResumeLayout(false); + this.groupBox1.ResumeLayout(false); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.GroupBox groupBox_AccessControl; + private System.Windows.Forms.Button button_Apply; + private System.Windows.Forms.Button button_DeleteFilter; + private System.Windows.Forms.Button button_AddFilter; + private System.Windows.Forms.GroupBox groupBox1; + private System.Windows.Forms.ListView listView_FilterRules; + private System.Windows.Forms.Button button_ModifyFilter; + } +} \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/ProcessMon/ProcessFilterSettingCollection.cs b/Demo_Source_Code/CSharpDemo/ProcessMon/ProcessFilterSettingCollection.cs new file mode 100644 index 0000000..38a1cec --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/ProcessMon/ProcessFilterSettingCollection.cs @@ -0,0 +1,144 @@ +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; + +using EaseFilter.FilterControl; +using EaseFilter.CommonObjects; + +namespace ProcessMon +{ + public partial class ProcessFilterSettingCollection : Form + { + public ProcessFilterSettingCollection() + { + InitializeComponent(); + InitListView(); + } + + public void InitListView() + { + //init ListView control + listView_FilterRules.Clear(); //clear control + //create column header for ListView + listView_FilterRules.Columns.Add("#", 20, System.Windows.Forms.HorizontalAlignment.Left); + listView_FilterRules.Columns.Add("ProcessId", 100, System.Windows.Forms.HorizontalAlignment.Left); + listView_FilterRules.Columns.Add("ProcessNameMask", 200, System.Windows.Forms.HorizontalAlignment.Left); + listView_FilterRules.Columns.Add("ControlFlag", 100, System.Windows.Forms.HorizontalAlignment.Left); + listView_FilterRules.Columns.Add("FileAccessRights", 300, System.Windows.Forms.HorizontalAlignment.Left); + + foreach (ProcessFilterRule rule in GlobalConfig.ProcessFilterRules.Values) + { + AddItem(rule); + } + + } + + private void AddItem(ProcessFilterRule newRule) + { + string[] itemStr = new string[listView_FilterRules.Columns.Count]; + itemStr[0] = listView_FilterRules.Items.Count.ToString(); + itemStr[1] = newRule.ProcessId; + itemStr[2] = newRule.ProcessNameFilterMask; + itemStr[3] = newRule.ControlFlag.ToString(); + itemStr[4] = newRule.FileAccessRights; + ListViewItem item = new ListViewItem(itemStr, 0); + item.Tag = newRule; + + foreach (ListViewItem lvItem in listView_FilterRules.Items) + { + if (string.Compare(((ProcessFilterRule)(lvItem.Tag)).ProcessNameFilterMask, newRule.ProcessNameFilterMask, true) == 0) + { + listView_FilterRules.Items.Remove(lvItem); + break; + } + } + + listView_FilterRules.Items.Add(item); + } + + + private void button_AddFilter_Click(object sender, EventArgs e) + { + try + { + ProcessFilterSetting processFilterSetting = new ProcessFilterSetting(null); + if (processFilterSetting.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + ProcessFilterRule newRule = processFilterSetting.selectedFilterRule; + AddItem(newRule); + } + } + catch (Exception ex) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("Add registry filter rule failed." + ex.Message, "Add Filter Rule", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + } + + private void button_DeleteFilter_Click(object sender, EventArgs e) + { + if (listView_FilterRules.SelectedItems.Count == 0) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("There are no filter rule selected.", "Delete Filter Rule", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + listView_FilterRules.Items.Remove(listView_FilterRules.SelectedItems[0]); + } + + + private void button_ModifyFilter_Click(object sender, EventArgs e) + { + if (listView_FilterRules.SelectedItems.Count == 0) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("There are no filter rule selected.", "Delete Filter Rule", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + ProcessFilterRule processFilter = (ProcessFilterRule)listView_FilterRules.SelectedItems[0].Tag; + ProcessFilterSetting processFilterSetting = new ProcessFilterSetting(processFilter); + + if (processFilterSetting.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + listView_FilterRules.Items.Remove(listView_FilterRules.SelectedItems[0]); + + ProcessFilterRule modifiedProcessFilter = processFilterSetting.selectedFilterRule; + AddItem(modifiedProcessFilter); + } + + } + + private void button_Apply_Click_1(object sender, EventArgs e) + { + GlobalConfig.ClearProcessFilterRule(); + + foreach(ListViewItem item in listView_FilterRules.Items) + { + GlobalConfig.AddProcessFilterRule((ProcessFilterRule)item.Tag); + } + + GlobalConfig.SaveConfigSetting(); + } + + private void button_ProcessInfo_Click(object sender, EventArgs e) + { + string information = "Process Control: allow/deny the binaries executing, prevent the suspicious binaries(malware) from executing.\r\n\r\n"; + information += "Get notification for process/thread creation and termination.\r\n\r\n"; + information += "Set the file access rights to the process.\r\n\r\n"; + + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show(information, "Process Filter Setting", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + + + } +} diff --git a/Demo_Source_Code/CSharpDemo/ProcessMon/ProcessFilterSettingCollection.resx b/Demo_Source_Code/CSharpDemo/ProcessMon/ProcessFilterSettingCollection.resx new file mode 100644 index 0000000..acfec18 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/ProcessMon/ProcessFilterSettingCollection.resx @@ -0,0 +1,408 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + AAABAAEAQEAAAAEAIAAoQgAAFgAAACgAAABAAAAAgAAAAAEAIAAAAAAAAEAAABMLAAATCwAAAAAAAAAA + AAAaEmMAFxFfAxkSYQ0cEmY4HRJngh0SZ7kcEmfYHBJn7hwSZ/ocEmf/HBJn/xwSZ/8cEmf/HBJn/xwS + Z/8cEmf/HBJn/xwSZ/8cEmf/HBJn/xwSZ/8cEmf/HBJn/xwSZ/8cEmf/HBJn/xwSZ/8cEmf/HBJn/xwS + Z/8cEmj/GxJk/xkRXv8XD1j/Fg5U/xYOUv8XDlP/Fw5T/xcPVP8XD1T/Fw9U/xcPVP8XD1b/Fw9W/xcP + Vv8XD1b/GA9X/xgPV/8YD1j/GA9Y/xgQWf8YEFn/GBBa/xgQWv8ZEFr/GRBa+hgPXO8YD1zcGRBcvhoQ + XIgZEFs8GBBYDxcQVwQYEFkAEg9bAh0SZhQeE2c4HhNnaR4SZ6IdEmfLHRJn4h0SZ/IdEmf7HRJn/x0S + Z/8dEmf/HRJn/x0SZ/8dEmf/HRJn/x0SZ/8dEmf/HRJn/x0SZ/8dEmf/HRJn/x0SZ/8dEmf/HRJn/x0S + Z/8dEmf/HRJn/x0SZ/8dEmf/HBJl/xsRYf8ZEFv/GA9W/xcPU/8XDlL/Fw5T/xcOU/8XD1T/Fw9U/xcP + VP8XD1T/Fw9V/xcPVv8YD1b/GA9W/xgPV/8YD1f/GA9Y/xkPWP8ZEFn/GRBZ/xkQWv8ZEFr/GRBa/xkQ + W/wZEFvzGRBc5RoQXM8aEFymGxFcbBsRXDoaEFsVFA9UAxcRYA0eE2c4HxNojR8TaMcfE2jfHhNo7h4T + aPYeE2j7HhNo/h4TaP8eE2j/HhNo/x4TaP8eE2j/HhNo/x4TaP8eE2j/HhNo/x4TaP8eE2j/HhNo/x4T + aP8eE2j/HhNo/x4TaP8eE2j/HhNo/x4TaP8eE2j/HhJm/xwRYP8aEFv/GRBW/xgPU/8YD1L/GA9S/xgP + U/8YD1P/GA9U/xgPVP8YD1T/GA9U/xgQVf8ZEFX/GRBW/xkQVv8ZEFf/GRBX/xkQWP8aEFj/GhBZ/xoQ + Wf8aEFr/GhBa/xoRW/8aEVv+GhFb+xoRW/cbEVzvGxFc4RwRXcocEV2PGxFcOhcPVw8fE2g4HxNoaR8T + aMcfE2j9HxNo/x8TaP8gE2j/IBNo/yATaP8gE2j/IBNo/yATaP8gE2j/IBNo/yATaP8gE2j/IBNo/yAT + aP8gE2j/IBNo/yATaP8gE2j/IBNo/yATaP8gE2j/IBNp/yATaf8fE2j/HxNm/x0SYv8bEFr/Gg9V/xkO + Uv8YD1H/GA9S/xkPU/8ZD1P/GQ9T/xkPVP8ZD1T/GQ9U/xoPVP8ZEFX/GhBV/xoQVv8aEFb/GhBX/xoQ + V/8aEFj/GxBY/xsQWf8bEFn/GxBa/xsQWv8bEVv/GxFb/xsRW/8cEVv/GxFc/xwRXP8cEV3+HBFdyhwR + XWwbEF08IRRqgiEUaqIhFGrfIBRp/yAUaf8gFGn/IRRp/yEUaf8hFGn/IRRp/yEUaf8hFGn/IRRp/yEU + af8hFGn/IRRp/yEUaf8hFGn/IRRp/yEUaf8hFGn/IRRp/yEUaf8hFGn/IRRp/yEUav8hFGr/IBNn/x4S + Yf8cEVv/Gg9V/xkOUf8ZDlH/GQ5R/xkPUv8aEFP/GhBU/xoQVP8aEFT/GhBU/xoQVf8bEFX/GxBV/xsQ + Vv8bEFb/GxBX/xsRV/8bEVj/GxFY/xwRWf8cEVn/HBFa/xwRW/8cEVv/HBFb/xwRW/8cEVz/HRFc/x0S + XP8dEl3/HRJe/x0SXuEdEV6mHRFfiCIUa7kiFGvLIRRr7iEUa/8hFGv/IRRr/yEUa/8hFGv/IRRr/yEU + a/8hFGv/IRRr/yEUa/8hFGv/IRRr/yEUa/8hFGv/IRRr/yEUa/8hFGv/IRRr/yEUa/8hFGv/IhRr/yIU + a/8hFGr/IRNn/x8SYv8cEFr/GxFY/xsWWv8bGVz/Gxld/xoWWv8aEVT/Gg9S/xoPU/8aEFT/GhBU/xsQ + VP8bEFX/GxBW/xsQVv8bEFf/GxBX/xsQWP8bEVj/HBFZ/xwRWf8cEVr/HBFa/xwRWv8cEVv/HBFb/xwR + W/8dEVv/HRFc/x0RXf8dEl3/HRJe/x0SXv8eEl/vHhJfzx4SX74jFWzZIxVs4yIVbPYiFWz/IhVs/yIV + bP8iFWz/IhVs/yIVbP8iFWz/IhVs/yIVbP8iFWz/IhVs/yIVbP8iFWz/IhVs/yIVbP8iFWz/IhVs/yIV + bP8iFWz/IhVs/yMVbP8jFWz/IhRp/yASYv8dEFr/Gw5T/xsWWf8dJmz/HjB3/x4weP8dJm3/GxZa/xoN + UP8bDlL/GxBU/xsQVP8cEVX/HBFW/xwRVv8cEVf/HBFX/xwRWP8cEVj/HBFZ/x0RWf8dEVr/HRFa/x0S + W/8dElv/HRJb/x4SW/8dElz/HhJc/x4SXf8eEl3/HhJe/x4SXv8eEl//HxJf9h8SYOUfE2DcJBVs7yQV + bPMkFWz7JBVs/yQVbP8kFWz/JBVs/yQVbP8kFWz/JBVs/yQVbP8kFWz/JBVs/yQVbP8kFWz/JBVs/yQV + bP8kFWz/JBVs/yQVbP8kFWz/JBVs/yQVbP8jFGv/IxNo/yEUZf8gGGP/Hhxj/x0jZ/8eMnb/IUeP/yJT + nf8iU53/IUeQ/x8yd/8dImb/HRpf/xwVWv8cEVX/HBBU/xwQVf8cEVb/HBFX/x0RV/8dEVj/HRFY/x0R + Wf8eEVn/HhFa/x4RWv8eElv/HhJb/x4SW/8fElv/HxJc/x4SXP8eEl3/HxJd/x8SXv8fEl7/HxJf/yAS + X/sgE2DzIBNg7yUWbfolFm37JRZt/iUWbf8lFm3/JRZt/yUWbf8lFm3/JRZt/yUWbf8lFm3/JRZt/yUW + bf8lFm3/JRZt/yUWbf8lFm3/JRZt/yUWbf8lFm3/JRZt/yUWbf8lFm3/JBRp/yIRYP8hFmH/ISRs/yE3 + fv8iT5X/I2Sr/yZ2wP8nf8v/J3/L/yZ2wP8kZKv/Ik6T/yA0e/8fIWf/HhRZ/x0PU/8dEFT/HRFW/x0R + V/8eElf/HhJY/x4SWP8eElj/HxJY/x4SWf8fElr/HxJb/x8SW/8fElv/IBJb/yATXP8fE1z/HxNd/yAT + Xf8gE17/IBNe/yATX/8hE1/+IRNg/CETYPonFm3/JxZt/ycWbf8nFm3/JxZt/ycWbf8nFm3/JxZt/ycW + bf8nFm3/JxZt/ycWbf8nFm3/JxZt/ycWbf8nFm3/JxZt/ycWbf8nFm3/JxZt/ycWbf8mFm3/Jhds/yQb + bf8iI27/IjB4/yNEi/8lW6T/JnbA/yiK1f8qluT/K53r/yud6/8qluT/KYnU/yd0vv8kWaL/IkGJ/yEu + dP8fIWb/Hxhe/x8UWf8eElf/HxFW/x8SV/8fElj/HxJY/x8SWP8fEln/IBJa/yASW/8gElv/IBJb/yAS + W/8gE1z/IRNc/yATXf8hE13/IRNe/yETXv8hE1//IhNg/yETYP8hE2D/KBdv/ygXb/8oF2//KBdv/ygX + b/8oF2//KBdv/ygXb/8oF2//KBdv/ygXb/8oF2//KBdv/ygXb/8oF2//KBdv/ygXb/8oF2//KBdv/ygW + bv8oFW7/Jxdt/yUbbP8kLHn/JUiR/yZgqP8ndL3/KIXR/yuU4/8tnu//LqT3/y6n+/8up/v/LqT3/y2e + 7/8rk+L/KIXQ/yZzvP8lX6f/I0aO/yEscv8gG2H/IBNZ/x8RVv8gEVf/IBJY/yASWf8gEln/IBNZ/yAT + Wv8hE1v/IRNb/yETXP8hE1z/IRNd/yITXf8iE17/IhNe/yIUX/8iFF//IhRg/yMUYP8jFGH/IxRh/ygX + b/8oF2//KBdv/ygXb/8oF2//KBdv/ygXb/8oF2//KBdv/ygXb/8oF2//KBdv/ygXb/8oF2//KBdv/ygX + b/8oF2//KRdv/ykWbv8oGXH/KCB2/ycqff8mN4T/Jk6Y/yhtt/8qhtH/K5bi/yyf7f8uoPL/Lpzv/y2S + 5f8tjeD/LY3g/y2S5f8um+//LqDy/yyf7f8qluL/KYXQ/ydtt/8kT5f/IzZ9/yIlbP8hGmD/IBNZ/yAR + V/8gElj/IBJZ/yATWv8hE1r/IRNb/yETW/8hE1z/IRNc/yITXf8iE13/IhNe/yITXv8iFF//IxRf/yMU + YP8jFGD/IxRh/yMUYf8pGHD/KRhw/ykYcP8pGHD/KRhw/ykYcP8pGHD/KRhw/ykYcP8pGHD/KRhw/ykY + cP8pGHD/KRhw/ykYcP8pGHD/KRhw/yoXb/8qFm7/KSB3/yg2iP8oT5z/KGiy/yp+yP8skd7/Lp7t/y6l + 9v8vpPb/L5ns/y2D1f8qY7L/KFGe/yhRnf8pYbD/LYLU/y+Z7P8vpPb/LqX2/y2e7f8skd7/KX/I/ydm + rv8lSJD/Iy51/yEZX/8hEFX/IRFX/yETWf8hE1r/IhNa/yITW/8iE1v/IhRc/yIUXP8iFF3/IxRd/yMU + Xv8jFF7/IxRf/yQUX/8kFWD/JBVg/yQVYf8kFWH/Kxhw/ysYcP8rGHD/Kxhw/ysYcP8rGHD/Kxhw/ysY + cP8rGHD/Kxhw/ysYcP8rGHD/Kxhw/ysYcP8rGHD/Kxhw/ysYcf8qHXX/Kid9/yo7jv8pV6b/KnO//yuN + 1/8tnOn/L6Ly/y+g8v8vluj/LYjZ/yx1xf8pW6j/JjuE/yQpcf8kKXD/JTmD/ylap/8sdcT/LojZ/y+X + 6f8voPL/L6Ly/y2d6f8ri9X/KG23/yZQmf8kNHv/IyJo/yIYXv8iFFr/IhNa/yITWv8iE1v/IxNb/yMU + XP8jFFz/IxRd/yMUXf8jFF7/JBRe/yQUX/8lFF//JRVg/yQVYP8kFWH/JBVh/ywZcf8sGXH/LBlx/ywZ + cf8sGXH/LBlx/ywZcf8sGXH/LBlx/ywZcf8sGXH/LBlx/ywZcf8sGXH/LBhx/ywZcv8sG3P/KyyB/ypL + m/8qaLX/K4HO/yyV4v8uovD/L6X1/zCe8P8vitz/K2u6/yhPm/8lOX//Iyhs/yIeYf8iGVz/Ihhc/yIe + Yv8jKG3/JjmB/ylQnP8sbLv/L4vd/zCe8P8vpfX/LqHw/yyT4P8qfsn/KGOs/yZFjf8lJ23/JBZc/yQU + W/8jE1v/IxRb/yQUXP8kFF3/JBRd/yQUXf8kFF3/JBVe/yUVX/8lFWD/JhVg/yYVYf8mFWH/JRVh/yUV + Yf8vG3T/Lxtz/y4ac/8tGXL/LRly/y0Zcv8tGXL/LRly/y0Zcv8tGXL/LRly/y0Zcv8uGXL/Lhly/y0Z + cv8tIHj/LC+F/yxKnP8rb73/K4vY/y2d6/8vo/L/L5zt/y+P4P8tfMv/K2Kv/ydDjP8kKW//IRdY/yAP + Tv8hEFD/IRFS/yERU/8hEVL/IRBR/yIYW/8lKnH/KEOP/yxjsf8ufc3/L5Di/y+d7v8vo/P/LZ3q/yyJ + 1f8qa7b/KEeP/yYscv8lHGP/JRRb/yQUW/8kFFz/JRRd/yUUXf8lFF3/JRRe/yUVX/8mFV//JhVg/yYV + YP8mFWH/JhVh/yYVYf8nFWH/NSF4/zMfd/8wHHX/Lxpz/y4Zc/8uGXP/Lhlz/y4Zc/8uGXP/Lhlz/y4a + c/8uGnP/Lxlz/y4Zc/8uG3X/LS+F/yxVpf8sdsT/LpHg/y+i8f8wp/j/MJvs/y5+zv8rX6z/J0CH/yUr + bv8jIGP/Ihha/yETU/8hEFD/IRJS/yISU/8iElP/IhJT/yERU/8iFFb/Ixle/yUiZ/8mLXP/KUKL/yxh + sP8vgNH/L53t/y+o+P8vofH/LZDd/yt1wP8pU5v/Jytz/yYWXv8lFVz/JRVc/yYVXf8mFV3/JhVe/yYV + Xv8mFV//JxVf/ycWYP8nFmD/JxZh/ycWYf8nFmL/KBZi/0EugP9ALH//PSl9/zome/85JHr/NyN5/zYh + eP80IHj/Mx53/zIddv8xG3X/MBp0/y8adP8uIXr/Li+H/y1Nof8teMb/LpXi/zCh8P8wn+//Lo/f/yx2 + xP8oVaH/JTV9/yEaXP8fDUz/Hg1M/x4OTv8eD0//Hw9Q/x8QUf8fEFH/HxBS/yAQUv8gEFP/IBBT/yAP + U/8hD1L/IQ5S/yMcYv8nOIP/Klim/y15yf8vkuL/MKDx/zCh8f8uleL/K3fC/ylLlP8nLHT/Jhxk/yYV + XP8mFVz/JhVd/yYVXv8mFV7/JxVf/ycVX/8nFmD/JxZg/ycWYf8oFmH/KBZi/ygWYv9UQoz/VEGM/1JA + i/9QPYr/TTmH/0k1hf9EMYL/QC1//z0off85JHr/NR94/zEcdv8wHHb/LjCG/y1WqP8tecj/L5bl/zCi + 8f8xm+z/LoLR/ylZo/8lOoD/Iidr/yAZW/8eEFD/HQxM/x0NTP8dDU3/HQ5O/x0OT/8eDk//Hg5Q/x4O + UP8fD1H/Hw9S/yAPUv8fD1L/Hw5S/yAOUv8hElj/Ixxj/yUqc/8oPon/K12r/y+F1v8xne//MKPy/y6W + 5P8secT/KlWe/ycsdP8mF17/JxVd/ycVXf8nFl7/JxZe/ycWX/8oFl//KBZg/ygWYP8oFmH/KRZh/ykX + Yv8pF2L/X02T/19Nk/9eTZP/XUuS/1pHkP9WQ43/UT+L/047iP9KNob/RjGD/0IsgP8+LYH/OzaJ/zhR + of81fMj/M5jk/zKh8P8wl+b/LHrJ/yxcpP8xPnz/NjBm/zswYv9BNGT/Rjtq/0tAcP9PRHP/UUZ1/1NI + d/9USXn/VUl5/1NIeP9RRXb/T0R1/09DdP9PRHX/UkZ3/1JGd/9PQ3b/Sz9x/0Y4bP89MGn/MSpr/yw5 + gf8tXqz/L3/P/zGZ6v8xovH/L5fk/yx5xP8qSZL/KClx/ygaYv8nFFz/JxVd/ygWX/8oFl//KBZf/ygW + YP8pFmH/KRZh/yoWYv8qF2L/KRdi/2BPlf9gT5X/YE6V/2BOlP9fTZT/XkuT/1xKkv9bSZH/WkeQ/1lF + j/9XQ43/VU2X/1Fmrf9Mgsj/RZ/l/z6n8P83mOX/LnbC/yVEi/8uM2//SEVw/2BZeP90bYX/hYCU/5aT + pP+iobH/rKq5/7Oxv/+4t8X/vLrI/726yf+6t8b/s7HA/62ru/+pprb/qqe3/7GtvP+wrbz/qaa1/52a + qv+MiJv/cGmH/0tAcP8zLGr/LDB3/ytLl/8wesn/Mpjo/zGj8f8wleL/LnG8/yxKlP8pJW7/KBNb/ygV + Xf8pFl//KRdg/yoXYP8qF2H/Khdh/yoXYv8rF2L/Kxdj/ysXY/9iUJb/YlCW/2JQlv9iUJb/YlCW/2JQ + lv9iUJb/Y1CW/2NQlv9jUZb/Y1OY/2Fnqv9ei8r/WaTj/1Ow8f9Mpun/RIjL/0Jop/9GS3//V010/3Vv + hv+KiJX/lpSd/6Cgp/+rrLL/tLW7/7q7wf++vsX/wMDI/8jIz//U1tj/3N/e/9/i4P/W2dn/w8bI/7m6 + wP+5uMH/t7W//7Kxuf+rrLP/o6Sq/5GQnf92b4z/Wk56/z8xaP8wM3X/MFag/zB5x/8ymef/MqHu/zGP + 3P8uarX/LDaA/yoaYv8qF1//KhZf/yoXYP8qF2D/Khdh/ysXYf8rF2L/Kxdi/ysXY/8rF2P/ZFGX/2RR + l/9kUZf/ZFGX/2RRl/9kUZf/ZFKX/2RRl/9kUZf/ZFWa/2Rdov9jeLn/YaLf/1+18f9drer/WpbQ/1l0 + p/9qcZf/jI2k/6WlsP+ytbr/r7O2/52fpf+PkJn/hYWS/358jf94dIv/cWuH/2pjgv94c43/m5qm/7m8 + vv/P1NP/xcrL/52fqP9/fpD/bmiG/2hhgv9sZoT/eHWL/4qKl/+dn6f/rrC4/5uaq/9mX4L/QTtu/zEy + c/8sSJP/MHrI/zKa6P8yoe7/MIbT/y5NmP8sKHL/Kxxk/ysWX/8rF1//Kxdg/ysXYP8rF2D/LBhh/ywY + Yv8sGGP/LBhj/2ZTmf9mU5n/ZlOZ/2ZTmf9mU5n/ZlOZ/2ZTmf9mUpj/ZlKY/2ZboP9lcLL/ZI7N/2Sx + 7f9itu//YJvU/2SDtf9uc5b/iYWZ/7O1uv/DyMn/ur3C/6eosv+NjZz/d3WJ/2Vhe/9WT2//SUBn/0E2 + Yf8/NV//WFJy/4qLmf+prbL/sba7/6mttf+SlqH/fX6Q/2tohv9lYYL/bGmH/3p5kP+Nj5z/oqes/7e9 + v/+us7n/iImb/2BZff87KmT/Kilw/y5Wov8xgM7/MqHu/zKa5v8wa7f/LkKN/ywkbf8rFV3/KxZf/ysX + YP8rF2D/LBdg/ywYYf8sGGL/LBhj/ywYY/9pVZr/aVWa/2lVmv9pVZr/aVWa/2lVmv9pVZr/aVSZ/2lT + mP9oZqn/Z4vK/2ao5P9muPP/Y6jg/158sP9pb5j/hIWc/5+gqv+4vL7/sbO6/4uHn/9zaoz/aWCE/19V + fP9SR3L/RDdn/zYnXP83KVv/SD9l/29thP+orLT/sLe8/4uMnP+HiJn/qK61/7e/w/+yucH/sLfB/7K6 + wv+yusD/rra5/6Oqrv+RlZ//kZaf/6Gpr/+Ki5//TT9y/ywfZP8tMHn/L1ij/zKP3P8zovD/M43b/zFl + sf8tL3j/LBRc/ywWXv8sGGD/LBhh/y0YYf8tGGH/LRhi/y0YY/8uGGT/a1ec/2tXnP9rV5z/a1ec/2tX + nP9rV5z/a1ec/2tXm/9rWJz/anCy/2if3P9ntvD/Z7Lq/2OVy/9dZ5f/bGWI/4+Qn/+prrL/tbq8/6Gi + rv9wZ4r/V0l4/1dKeP9WSnf/UkZ0/0s/bv9ENmf/TEFs/2Ziff+Iipj/rbS5/6Sqsf9xb4b/dHSJ/663 + vP/G0dH/uMDH/7G3wf+0u8P/uMHF/7vHxv+iqbD/b2+H/3JyiP+mr7P/oKew/15Wfv82JmL/Lx5j/y47 + hP8xdsL/NJnn/zSf7f8yfsv/LzyG/y0ZYf8tF2D/LRhg/y0YYf8uGGL/LRhi/y4YY/8uGGT/Lxhk/21Z + nf9tWZ3/bVmd/21Znf9tWZ3/bVmd/21Znf9tW5//bWCj/2x8vP9qrOb/aLjv/2ee1f9jf7L/Xl6M/25k + hv+Rkp//p66w/620tf+Zm6f/bmaJ/1lLef9aTnr/X1R+/2Vegv9rZYX/cGmG/357kf+VmKT/nqWr/5if + pf+EhpP/ZGJ6/3Bwhv+kr7T/qLO5/3p6lP9mYIL/b2yH/4qOnv+xvsD/n6ez/1hPe/9VTHf/lp2p/6Cq + r/9ubIb/SDxq/zQiYP8tK3T/MVek/zOAzv8zoO3/Mo3Z/zFLlv8vI27/Lhtk/y4YYP8uGGH/Lxhi/y8Z + Y/8vGWP/Lxlk/zAZZP9vW5//b1uf/29bn/9vW5//b1uf/29anv9vWp7/b2Cj/29srv9tisj/a7Tt/2m1 + 6v9mjMD/Ymuc/19YhP9vZYb/kZKf/6atsP+rsrT/naGr/397lf9ybI3/enSU/4J/m/+Li6D/kpOk/5ia + p/+lqrH/tsDC/6+5u/+Qlp7/dXaH/2Jgef9ydIn/oK2y/5unrv9iYH7/SEBn/1NObv93eo3/rbu9/52m + tP9NQHX/RTdt/4aLnf+Zpaj/eHyM/1ZPc/85J2L/LCFp/zA8iP8yaLT/M5zn/zOZ4/8yXqn/MTR//y8g + av8uF2D/Lxhh/y8YYv8vGWP/MBlj/zAZZP8wGWT/cVyg/3FcoP9xXKD/cVyg/3FcoP9xXKD/cVuf/3Bm + qf9vfLz/bpnV/2y58P9pr+L/ZX2s/2Fdif9fVH7/b2eG/5CSoP+mrrH/r7e5/6uzt/+eo63/oKSw/7C4 + wP+6xMr/vMbK/7vEyP+3wcP/vMfI/8jV1P+7x8j/l5ym/3t7jf9raYH/en2Q/6Oytv+hsbT/c3mK/15f + df9laHv/gouW/66+v/+bpLP/TUF1/0Ezaf94fJD/jpqe/3uEj/9eXXv/PC1m/ywaYf8uJ3D/MVKb/zOU + 3v80oOr/NHO+/zNJlP8wJ3H/Lxdg/y8YYf8wGWL/MBlj/zAZY/8xGmT/MRpk/3Neov9zXqL/c16i/3Ne + ov9zXqL/c12h/3Ndof9ybK3/cInH/2+k3v9uuO//aqfZ/2Vzn/9hVX7/YFN8/3BoiP+PkqD/p7C0/7bB + wv+4w8P/rre5/664uv+4xMf/vMjL/7nByP+zusP/rbO9/7O7wv/D0dH/u8jJ/5uhq/+Cg5T/c3GJ/4GE + mP+pt7z/rL6+/4uXnf97hI7/gIuU/5KgpP+pvbv/kJqq/0o+cv9AMmj/dHiN/4mWm/95hI7/X2B8/z0u + Z/8sFl3/LRth/zBDiv8ziNL/NZ/p/zWCzv80W6b/MS53/y8XX/8wGGD/MBli/zAZY/8wGWP/MRpk/zEa + ZP92YKP/dmCj/3Zgo/92YKP/dmCj/3Zfov92XqL/dXGx/3KV0P9wrOP/cLPp/2ydz/9mbpn/YlR9/2JU + ff9xaYn/j5Kg/6q1t//Azs3/wM7N/6u2uf+bo6v/kpel/4uLoP+Ef5v/fneX/3x0lf+LiqL/qrW8/7C+ + v/+dpaz/iYub/3l2kP+Hh57/r7vC/7nLyv+ktbX/m6ut/6Cxsv+itrX/n7Sy/32Imf9DN2z/QjVq/3mA + kv+Lmp7/c32K/1dXdv86K2T/LRVb/y4WXP8xOYD/NHnE/zaW4v82jNj/NGm0/zEye/8wFl//MBdg/zEZ + Yv8xGmP/MRpj/zEaZP8yGmX/eGKl/3hipf94YqX/eGKl/3hipf94YaT/eGCj/3Z1tf9zn9f/cbPo/3Gu + 4/9ulcb/aGuW/2RVff9kVn7/c2uK/4+SoP+otLb/vMvK/7fFx/+coq3/hoaa/3h0jv9tZYf/Z1qD/2NU + gP9jU4D/dW2P/5adqv+ms7b/oq2x/5KXpP98d5T/hYKd/6y2vv+7y8r/r8HA/6u+vf+wxcP/qLy7/4+i + pP9rdIf/Qjho/0tCcP+Dj53/j6Cl/2pxhf9LR23/NyZi/y4VW/8uFVr/MTN6/zVtuP82j9v/NpTf/zV1 + v/8yNn//MRZe/zEYYP8xGmL/MRpj/zIaY/8yGmT/Mxpl/3pkpf96ZKX/emSl/3pkpf96ZKX/emOk/3pi + pP94ebf/dKbd/3K36/9yqt7/b4/A/2prlP9mV37/Zld+/3Rsi/+Pk6D/oq6x/6q5uv+fqbH/goCY/3Fn + if9tYYb/al2E/2dZg/9mVoL/ZVaC/3JojP+Ljp//n6qv/6u5uv+eprH/fHaV/3x2lf+fprH/sL6//6u6 + u/+svb3/scbE/6G0tv98iJP/XGB3/0dCaP9aW3r/kaSr/5Onrf9fYH//PjFk/zMfXv8vF1v/LxZb/zEx + d/81ZK7/N4nU/zaa5P81fsf/MzqC/zEXXv8yGGD/Mhti/zIbY/8zG2P/Mxtk/zQbZP98Zqf/fGan/3xm + p/98Zqf/fGan/3xlpv98Zab/en27/3Wt4/9zu+7/c6XY/3CJuP9rapP/aFl//2dZf/91bov/jpSh/56r + rv+grrD/kpml/3Zvjf9qXYP/b2SH/3Nri/92bo7/d3CP/3hwkf+AfZf/kJak/6OwtP+2yMb/rLvA/4qL + ov+Bfpn/lJmm/6Grsf+ls7b/qrq7/62/v/+bqq//dn2N/2Bkev9eYnr/bnqL/46kqP+ElaH/Ukx2/zUi + Xv8xG13/MBhc/zAYXP8yLnT/NVqk/zeCzP82n+j/NYfP/zM+hf8yGF//Mhlg/zIbYv8zG2P/NBtj/zQb + ZP80G2T/fmio/35oqP9+aKj/fmio/35oqP9+Z6j/fmip/3uCv/92s+j/c77v/3Oh0f9xg7D/bGmR/2lb + gP9pW4H/dm+M/46Uof+cqq3/n62v/5KZpP94co//cWiJ/359k/+JjJz/j5Wh/5Obpv+Wn6n/nKav/6Sz + t/+ww8T/wNbT/7zRz/+lsrn/lJuo/42QoP+RlqP/n62x/6a3uP+ktLX/lqKp/36Dk/94f5D/hZee/4ad + oP96j5X/Y2uC/0I2af8xGlz/MBlc/zEZXP8xGFz/Mitw/zZQmv83ecT/NqLq/zWO1v8zQor/Mxpi/zMa + Yf8zG2L/Mxxj/zQcY/81HGT/NRxl/4Bqqv+Aaqr/gGqq/4Bqqv+Aaqr/gGqq/39srP99h8P/d7fr/3W/ + 7/90ncz/cn+r/25pkP9rXYL/a12C/3dwjf+OlKH/nayv/6O0tf+dqbD/jI+i/4iKnv+Sm6X/mqeq/52s + rf+gr7D/orGy/6S0tf+nt7n/rb/A/7bKyv+2ysr/rb/A/6KwtP+Wn6r/l6Cr/6Ozt/+pvLv/pre4/56s + sP+TnKj/laOs/6S9u/+XsLD/bnqK/05Lb/84KGH/Lxdb/zAYXP8xGVz/MRlc/zMobv82SJL/N3O+/zai + 6v81k9r/NEiP/zQeZv8zG2L/Mxti/zQcY/81HGT/NRxl/zUcZf+CbKv/gmyr/4Jsq/+CbKv/gmyr/4Jt + rP+Bca//f4zG/3m57P92v+3/dpzJ/3N+qf9vao//bV+D/21fg/94cY7/jZWh/5+wsv+swcD/sMbG/63A + w/+qvL//p7q6/6S1tf+gr7D/nKqt/5qmq/+Yo6n/l6Kp/5eiqv+ZpKz/nKmw/6KxtP+oubv/rsLD/7HG + x/+wxcX/sMXE/7HHxP+xxsX/sMTG/7PJyf+40s7/n7K4/2tpiv9HOGv/NyJf/zAYW/8wGVv/MRlc/zEZ + XP8zJ2z/NkSN/zdvuP82ouj/Npbb/zVOlf81JGv/NB1k/zQbYv80HGL/NRxk/zYcZf82HGX/hG6t/4Ru + rf+Ebq3/hG6t/4Rurf+Eb67/g3Wy/4CPyP97u+z/eL/s/3ebyP91faf/cWuQ/25hhP9uYYX/eXKP/46V + of+gsrP/r8bE/7XNy/+wxsb/qry//6Kwtv+bpq7/lZyn/5CVov+MkJ//ioyd/4iJm/+Ghpn/hISY/4eK + nP+Rl6X/naix/6q7wP+uwcX/qry//6m7vf+rvr//rcDC/7DBxf+1ysz/vNXT/6W1v/9yapH/UTxz/0Mu + af86JGP/NB1e/zEZXP8yGVz/NCdr/zdCiv84bbX/N6Hm/zaY3P82Upn/Nihv/zUfZf81HGL/NRxj/zYc + ZP82HGX/Nxxl/4Zvrv+Gb67/hm+u/4Zvrv+Gb67/hnGw/4V3tf+Ckcr/fbzt/3rA7P95m8f/dn6n/3Js + kf9wYob/cGKG/3p0j/+OlaH/n7Gy/6zDwf+pvb//lqCs/4qMn/+EgZr/gHqW/353lP99dZP/fHOS/3ty + kf97cZH/enCR/3lvkf96cZL/fXaV/4N9mv+KiKH/j5Km/5GYp/+TnKj/lJyo/5OZp/+RlKf/nKW0/7LI + yv+pusP/gnud/2hVhv9dSn7/Tztz/zwmZP8zGlz/Mxlc/zUma/84QYn/OGy0/zeh5v82md3/N1Sb/zcq + cf82H2b/Nhti/zYcY/83HGT/Nx1l/zgdZf+IcbD/iHGw/4hxsP+Ica//iHCv/4hzsf+Hebf/hJPM/36+ + 7f97wOz/epvG/3h+p/90bZL/cWSH/3Jkh/97dZD/jpah/52vsP+mu7r/na2z/4WGmv93bYz/dGaK/3Jj + iv9zY4r/c2SL/3Nki/90Zoz/dmiN/3dqjv93ao//dmmP/3Vnjv91aI7/eGuQ/3xzk/+BfZf/g4GZ/4OA + mf+BfZf/f3qW/46Rpv+swcX/q73E/4qFpP91ZJH/b12M/2JPgv9NOHL/Pydm/zceYP81Jmv/OECI/zhr + s/83oeX/N5rd/zhVnP84K3P/NyBn/zYcY/83HGP/Nxxk/zgdZf84HWX/inKx/4pysf+KcrH/inKw/4py + sP+KdbP/iXy5/4WWzf+Av+7/fMHs/3ubxv95fqf/dm6S/3NmiP9zZYn/fXaS/4+Xov+aq63/nrKx/5Wh + qf+Ae5X/dWeL/3Rli/90ZYv/dGWL/3RljP90Zoz/dmmN/3pvj/98c5H/fXWS/3t0kv94bpH/d2qQ/3dp + kP94apH/em6S/3tvk/98b5T/fHGU/312lf+Nkqb/q8HE/6q9w/+KhqT/eWiT/3dmkv9yYI7/ZlSF/1ZB + eP9BKGf/Nydr/zg/hv85abH/N6Hl/zea3v85V57/OSx1/zchaP83HGP/Nxxj/zgdZP84HWX/OB1m/4x0 + sf+MdLH/jHSx/4xzsf+Mc7H/i3e0/4p+uv+HmM//gcDu/37B6/98m8b/en+n/3dvk/91Z4n/dWeK/354 + kv+Pl6L/mKqr/5qtrf+Snqb/g4GX/3x0kv9/eZX/gn6Z/4SBnP+Fg57/hoWe/4eJoP+LjaH/jZGj/42S + o/+MkaP/io2j/4iJo/+HhqL/h4Og/4WBn/+Efpz/gnqa/4B5mP+AfJj/j5an/6rCw/+ovML/ioak/3pq + lf97a5b/e2qV/3dlkv9pVob/Uz11/0Q2df8+Q4n/Ommw/zih5P84m9//OVig/zkudv84IWj/Nxxj/zgd + Y/84HWT/OB1l/zgdZv+NdbL/jXWy/411sv+NdbL/jXWy/414tf+Lgbz/iJrQ/4LB7/9/wuv/fZzE/3t/ + pv94cJP/dmiK/3Zoiv9+eZP/jpii/5eqq/+Zrq7/laWq/4yUoP+LkZ//kp2o/5qpsf+gsrn/pLm+/6a8 + wP+mvsD/p73A/6a9v/+lvL7/pr2+/6a+wP+mvsH/pbzB/6O4vv+gsrr/mqqz/5Ofqf+NlKL/iIyd/5Kd + qf+pw8P/przB/4qHpP97a5X/fGyW/31tl/99bJb/d2WR/2xZif9dUYj/S06P/z5qr/85oeT/N5zf/zla + ov86MHj/OCJp/zgcYv84HWP/OB1l/zkdZv86Hmb/j3e0/493tP+Pd7T/j3e0/493tP+Perf/jYO9/4mc + 0f+Ew+//gMPr/3+cxP98gKX/eXGT/3hqi/94aov/gHqT/46Yov+Zra7/nra1/520tP+WqKv/laWq/5qu + sP+ftbb/o7u9/6a+wf+ov8L/qL7B/6e7wP+mub7/pbm9/6W6vv+nvcD/qL/C/6e/wv+mvsD/pLy9/6C3 + t/+ar7D/lqer/5Oiqf+brrP/qsjF/6W7wf+LiKX/fW2W/35ul/9/b5j/gG+Z/39umP98a5X/cWWV/15f + mf9NdrX/P6bl/zmd3/86XKP/OjF6/zkjaf84HGL/OB1j/zoeZ/8+H2v/PyBu/5J5tv+Sebb/knm2/5J5 + tv+Sebb/kXy5/4+Gv/+LntP/hsTw/4LD6/+BnMP/foGl/3tzlP96bIz/emyN/4F7lP+OmKL/nLGy/6jF + wv+pyMT/oLq5/5musP+Vp6r/kqCn/4+Zpv+Nk6X/jIyj/4yJov+MiKL/jIii/4uIof+LiKL/jImj/42L + pP+OjqX/j5Sm/5KdqP+Uo6r/lqis/5qvsv+hurv/qMbD/67Qyv+ku8D/jIml/4Bvl/+AcJj/gXGa/4Fx + mv+BcZr/gXCZ/35xnf93dab/ZovB/0yu6f89nt//PF6k/zszfP85I2r/ORxi/zodZP8+IGv/RSN3/0gl + ff+Ue7f/lHu3/5R7t/+Ue7f/lHu3/5N/uv+RiMH/jaDU/4fF8P+Ew+r/gpzD/4CBpf99dZX/e26O/3xu + jv+CfJX/jpii/5uysv+pycT/qcjG/52xtv+ToKn/jZWh/4eLm/+DgZj/gHiV/35wkv9+bZH/fm6S/35u + k/9+bpP/fm6T/35ulP9/cJX/gHOW/4J6mP+GhJv/io6f/4+Wpf+WpK7/oLe6/6jHw/+sz8n/o7q//42J + pf+CcJn/gnGa/4Nzm/+Dc5v/g3Ob/4Rym/+Ed6H/hYGt/3iYyP9etuv/TKTg/0Jipv88Nn3/OiRq/zsd + ZP8+IGr/RCN0/0smgP9OKIb/lX24/5V9uP+Vfbj/lX24/5V9t/+Ugbv/korC/4+j1f+JxvH/hcPq/4Oc + wv+BgaX/fnWW/31vj/99b4//gn2W/42Yof+Yr67/ob+8/561uP+OkaT/hH6Y/4N7lv+CeZX/gXaU/4Bz + lP+AcZP/f3CT/4BwlP+AcZT/gHGU/4Bxlf+AcJX/gHGW/4Fyl/+CdZj/g3iZ/4V7mv+GfZz/ioig/5Gc + p/+asrP/psfC/6G5vf+Niqb/g3Ka/4Rzm/+EdJz/hHSc/4R0nP+FdJz/hnmi/4eDrv+CnMj/d7/s/2Wu + 4v9Oaan/QDqA/zwmbP8+H2n/RiN2/0wngf9PKYf/USmK/5d/uf+Xf7n/l3+5/5d+uP+Xfrj/loO8/5SN + xP+Qpdf/isfx/4bE6v+FncL/g4Gl/4B1lv9+cI//fnCQ/4J7lf+KkJ3/k6Wp/5y3tf+asbT/jZKk/4WB + mv+Ef5n/hH6Y/4N8l/+Depb/gnmW/4J3lv+CdpX/gnWW/4J1lv+DdZf/g3aY/4N4mP+EeZn/hHua/4V9 + mv+Gf5z/h4Ge/4qLof+QnKf/l66v/5+9uv+bsLb/jIik/4Rzm/+FdJv/hnWc/4Z1nP+GdZz/hnSc/4d5 + ov+Iha//iJ/J/4XF7f93uOX/YHqz/09KjP9FLnb/RCNy/0wmgP9RKYn/UiqL/1MqjP+YgLr/mIC6/5iA + uv+YgLr/mIC6/5eEvf+Vj8X/kabY/4vI8f+Ixuv/h6DE/4SEp/+Bd5f/gHGP/4BxkP+Bd5P/hYGX/42V + ov+ZsbL/nry5/5u0tf+Wqq//kKCo/4uXov+KkJ7/iIqb/4aGmf+Egpj/hH6X/4N7l/+Depj/hHuZ/4V/ + mv+Hgpv/iIad/4mLnv+LkqD/jpmk/5Ghqv+WrLH/nbq6/568uv+YsbH/kZ2o/4mDoP+Gdpz/h3ad/4d3 + nf+Hdp3/h3ac/4d1nP+Ie6P/ioex/4uiy/+Jx+3/g8Lr/3mSw/9qZKH/Vj2J/04pgf9RKYj/UyqM/1Mr + jP9UK43/moK8/5qCvP+agrz/moK8/5qCu/+Zhb7/mI7F/5Ol1v+NyPD/icvw/4mw1P+Hmr3/hoyt/4SD + pP+EgKH/hH6e/4V/nP+KiqD/k6Cq/5qwsf+ct7X/mrez/5Wvrf+SqKn/kaOn/5Cfpv+OnKX/jpmk/42W + pP+NlKT/jZOl/46Upf+Ol6b/j5qn/5Ccp/+RoKj/kqWo/5Oqqv+Wr67/mrW0/5+5uv+csbb/kp2o/4uM + oP+Jfp7/iHie/4l7ov+KfqX/ioGo/4qEq/+Kh67/i4+2/4ycxP+Msdn/i8zx/4vG7f+Kn83/gHex/21S + nf9fOpL/WC+O/1Qrjf9VK43/VSuO/5yEvf+chL3/nIS9/5yEvf+chL3/nIa//5qMw/+WodP/j8Xt/4vT + 9/+LzO//jMDk/4yz1/+Mp8z/i5zB/4qTt/+Ji63/iYem/4uHoP+Nj6D/kJyk/5KlqP+Uqqr/la6t/5ez + sv+Zt7X/m7m4/527uv+evLv/n728/5+9vf+evLz/nby7/527uv+cubn/mre2/5izsf+Wr67/lKur/5Sk + qf+Tmaj/kY+l/42FoP+Lfp7/i3ue/4t9o/+NhKz/joy1/4+Vvv+Pn8f/jqnR/4602/+Nweb/jMzw/4zU + +P+Pxez/lKDQ/5KCu/+Hba//dlSj/2E4lf9WK47/ViuO/1Ysj/+ehr//noa//56Gv/+ehr7/noa+/56H + v/+dicH/mpnM/5S14f+Rx+7/kM3z/5DN8v+Rxu3/kL/l/4+33f+OrtP/jaXJ/4ucvv+Jk7T/iZSw/4uf + sv+Pp7b/kq65/5a0vf+ZusH/m77F/57Bx/+gxMn/ocbK/6LHyv+ixsr/ocbJ/6DEx/+fwsb/nsDF/5y8 + wv+Ytr7/lbG6/5Ortv+RorP/jpax/42Qsf+MjrL/jI+0/42Stv+Nl7z/jp7F/4+nzv+QsNf/kLjf/5DA + 5/+Qx+7/kM3z/5DO8/+Rx+7/lbbh/5uazf+ciMD/mH67/4lpsP9vSZ//XzWU/1kukP9XK4//oIfA/6CH + wP+gh8D/oIe//6CHv/+gh8D/oIjA/56OxP+cms3/mabW/5ez4P+Vvef/k8Pr/5HJ7v+QzPD/j83v/47K + 7P+Oxuj/jcLk/43A4f+PwN//kL/c/5K92v+Tu9j/lLjV/5W20/+WtdL/l7XR/5e00P+Xs87/l7HN/5ew + zP+XsMv/lrDM/5awzf+VsM3/lLDO/5Owzv+Ssc7/kbHQ/5Gx0/+Qs9f/j7fb/4+73/+PwOP/j8Tm/4/H + 6v+Pyu3/j83w/5DN8f+RyvD/ksXt/5S+6P+WtOD/mafX/5yazf+fj8X/oIjA/5+Gv/+Vebj/gmGs/3BK + n/9fNZT/VyuP/6KJwf+iicH/oonB/6KJwf+iicH/oonA/6KIwP+iicH/oYzC/5+Sx/+dntD/m6nY/5iz + 3/+WvOb/lcXs/5TK8P+TzfL/k8/z/5PQ9f+Tz/T/k83y/5PK7/+Sxu3/ksPp/5K/5v+SvOP/kbrg/5G5 + 3/+Rt97/kbbc/5G02v+Rs9r/kbPa/5G02/+Rttz/kbje/5G54P+Su+H/kr3j/5LA5v+TxOn/k8ft/5PK + 7/+TzfL/k8/0/5PQ9P+Sz/P/k83y/5PK8P+Uxez/lr3n/5e14f+aq9n/nZ/R/5+TyP+hi8P/oonB/6KJ + wf+jisH/noO+/5N2t/+BX6v/akKb/14zk/+jisL/o4rC/6OKwv+jisL/o4rC/6OKwf+jisH/o4rB/6OL + wv+jjcP/opHG/6GUyf+gmMv/n5zO/56h0v+dp9f/m6/c/5q14f+ZuuX/mL7o/5fC6v+Vxez/lMnv/5TL + 8P+TzPH/k83x/5LO8f+Rz/L/kdDy/5HQ8v+Rz/L/kc/x/5HP8f+Rz/L/kdDy/5HQ8v+Rz/L/ks/y/5PO + 8v+TzPH/lMvw/5XJ7v+Wxuz/l8Lp/5i+5/+ZueT/mrXg/5uv3P+cp9f/nqHS/5+cz/+gmMz/oZXJ/6KR + xv+jjcP/o4vC/6OKwv+jisL/pIvC/6OJwf+ghr//kXO1/3lUpv9tRJ7/pIvC/KSLwv2ljML+pYzC/6WM + wv+ljML/pYzC/6WMwv+ljML/pYvC/6WLwv+li8L/pYrB/6WLwv+kjsT/o5PH/6Gazf+goNH/n6XV/56q + 2f+cr9z/m7Xg/5q65P+Zvuf/mcHp/5jD6/+Xxez/l8ft/5fI7v+Xye//l8nv/5fK8P+XyvD/l8rv/5fJ + 7/+XyO7/l8ft/5fF7P+Yw+v/mcHp/5m95v+aueP/nLXf/52v3P+eqtj/n6XV/6Cg0f+hms3/o5PH/6SO + xP+li8L/pYrB/6WLwv+li8L/pYvC/6WMwv+ljML/pYzC/6WMwv+ljcP/po3D/5yBvf6KarH9gV2r/KSK + wvWli8L4po3D/aaNxP+mjcP/po3D/6aNw/+mjcP/po3D/6aNw/+mjcP/po3D/6aMw/+mjcP/po3E/6aP + xf+lkcb/pZPI/6SVyf+kl8r/pJjL/6Oazf+jnM7/o53P/6Ke0P+in9H/oqDR/6Kg0f+iodL/oqLT/6Gj + 1P+hpNT/oaTU/6Gj1P+iotL/oqHS/6Kg0f+ioNH/op/R/6Ke0P+jnc//o5zO/6Oazf+kmMv/pJbK/6SV + yf+lk8j/pZHG/6aPxf+mjcT/po3D/6aMw/+mjcP/po3D/6aNw/+mjcP/po3D/6aNw/+mjcP/p47E/6eO + xP+jisL9nYG++Jl8u/WjicLnpYrD7qeNxPmoj8X/qI/F/6iPxf+oj8X/qI/F/6iPxf+oj8X/qI/F/6iP + xf+oj8X/qI/F/6iPxf+ojsX/qI7E/6iOxP+ojsT/qI7E/6iOxP+ojcT/qI3E/6iNxP+ojcT/qI3D/6iN + w/+ojcT/qI3E/6iNxf+oj8X/qJDG/6iQxv+oj8X/qI7E/6iNw/+ojcP/qI3D/6iNxP+ojcT/qI3E/6iN + xP+ojcT/qI7E/6iOxP+ojsT/qI7E/6iOxP+ojsX/qI/F/6iPxf+oj8X/qI/F/6iPxf+oj8X/qI/F/6iP + xf+oj8X/qI/F/6iPxf+oj8X/qI7F+aeOxO6njcTooobB0aSJw92ojsX0qpDG/6qQxv+qkMb/qpDG/6qQ + xv+qkMb/qpDG/6qQxv+qkMb/qpDG/6qQxv+qkMb/qpDG/6qQxv+qkMb/qpDG/6qQxv+qkMb/qo/G/6qP + xv+qj8b/qo/G/6qPxf+qj8X/qo/G/6qPxv+qj8b/qpDG/6qQxv+qkMb/qpDG/6qPxv+qj8X/qo/F/6qP + xf+qj8X/qo/G/6qPxv+qj8b/qo/G/6qQxv+qkMb/qpDG/6qQxv+qkMb/qpDG/6qQxv+qkMb/qpDG/6qQ + xv+qkMb/qpDG/6qQxv+qkMb/qpDG/6qQxv+qkMb/qpDG/6mQxvSoj8Xep47F0qCEwJukiMO1qY/G56uS + x/+sksj/rJLI/6ySyP+sksj/rJLI/6ySyP+sksj/rJLI/6ySyP+sksj/rJLI/6ySyP+sksj/rJLI/6yS + yP+sksj/rJLI/6ySyP+sksj/rJLI/6ySyP+sksj/rJLI/6ySyP+sksj/rJLH/6ySx/+sksf/rJLH/6yS + x/+sksj/rJLI/6ySyP+sksj/rJLI/6ySyP+sksj/rJLI/6ySyP+sksj/rJLI/6ySyP+sksj/rJLI/6yS + yP+sksj/rJLI/6ySyP+sksj/rJLI/6ySyP+sksj/rJLI/6ySyP+sksj/rJLI/6ySyP+rksfoqZDGuKiP + xp+af75Jo4nDeKqQxtCsksj/rZPI/62Uyf+tk8n/rZPJ/62Tyf+tk8n/rZPJ/62Tyf+tk8n/rZPJ/62T + yf+tk8n/rZPJ/62Tyf+tk8n/rZPJ/62Tyf+tk8n/rZPJ/62Tyf+tk8n/rZPJ/62Tyf+tk8n/rZPJ/62T + yP+tk8j/rZPI/62TyP+tk8j/rZPJ/62Tyf+tk8n/rZPJ/62Tyf+tk8n/rZPJ/62Tyf+tk8n/rZPJ/62T + yf+tk8n/rZPJ/62Tyf+tk8n/rZPJ/62Tyf+tk8n/rZPJ/62Tyf+tk8n/rZPJ/62TyP+tk8n/rZPJ/66U + yf+ulMn/rpXJ062UyX2sk8hRjXW3FqKJwkKpj8aWq5DH0KyRyOetksj0rpTJ+q6Uyf2vlcn+r5XK/6+V + yv+vlcr/r5XK/6+Vyv+vlcr/r5XK/6+Vyv+vlcr/r5XK/6+Vyv+vlcr/r5XK/6+Vyv+vlcr/r5XK/6+V + yv+vlcr/r5XK/6+Vyv+vlcr/r5XK/6+Vyv+vlcr/r5XK/6+Vyv+vlcr/r5XK/6+Vyv+vlcr/r5XK/6+V + yv+vlcr/r5XK/6+Vyv+vlcr/r5XK/6+Vyv+vlcr/r5XK/6+Vyv+vlcr/r5XK/6+Vyv+vlcr/r5XK/6+V + yv6vlcr9r5XK+q6UyfWulMnpr5XK07CWypuxmMtItpvNHYZvswWehcAZoonCQqaKxHiojMa2q47H3q6S + yO6vlcn4sJbK/bCWy/+wlsv/sJbL/7CWy/+wlsv/sJbL/7CWy/+wlsv/sJbL/7CWy/+wlsv/sJbL/7CW + y/+wlsv/sJbL/7CWy/+wlsv/sJbL/7CWy/+wlsv/sJbL/7CWy/+wlsv/sJbL/7CWy/+wlsv/sJbL/7CW + y/+wlsv/sJbL/7CWy/+wlsv/sJbL/7CWy/+wlsv/sJbL/7CWy/+wlsv/sJbL/7CWy/+wlsv/sJbL/7CW + y/+wlsv/sJbL/7CWy/+wl8v9sJfL+bCWy/CvlMngrpTJurCVyn+yl8xIs5jMHbmfzweQd7gAhW+yBox0 + thaegsBKpYfEnKmMxtKtksjosJXK9rGXy/yxl8v/sZfL/7GXy/+xl8v/sZfL/7GXy/+xl8v/sZfL/7GX + y/+xl8v/sZfL/7GXy/+xl8v/sZfL/7GXy/+xl8v/sZfL/7GXy/+xl8v/sZfL/7GXy/+xl8v/sZfL/7GX + y/+xl8v/sZfL/7GXy/+xl8v/sZfL/7GXy/+xl8v/sZfL/7GXy/+xl8v/sZfL/7GXy/+xl8v/sZfL/7GX + y/+xl8v/sZfL/7GXy/+xl8v/sZfL/7GXy/+xl8v/sZfL/bGYzPewl8vqr5TJ1a6TyKKxlMpTtpbOHreX + zwi1ls4AgAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAE= + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/ProcessMon/ProcessHandler.cs b/Demo_Source_Code/CSharpDemo/ProcessMon/ProcessHandler.cs new file mode 100644 index 0000000..4f3d580 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/ProcessMon/ProcessHandler.cs @@ -0,0 +1,355 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.IO; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Drawing; +using System.Windows.Forms; +using System.Runtime.InteropServices; +using Microsoft.Win32.SafeHandles; +using System.Security.Principal; +using System.Threading; +using System.Reflection; + +using EaseFilter.FilterControl; +using EaseFilter.CommonObjects; + +namespace ProcessMon +{ + + public class ProcessHandler : IDisposable + { + + ListView listView_Info = null; + Thread messageThread = null; + Queue messageQueue = new Queue(); + + AutoResetEvent autoEvent = new AutoResetEvent(false); + bool disposed = false; + + + public ProcessHandler(ListView lvMessage) + { + this.listView_Info = lvMessage; + InitListView(); + + messageThread = new Thread(new ThreadStart(ProcessMessage)); + messageThread.Name = "ProcessMessage"; + messageThread.Start(); + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + private void Dispose(bool disposing) + { + if (!this.disposed) + { + } + + autoEvent.Set(); + messageThread.Abort(); + disposed = true; + } + + ~ProcessHandler() + { + Dispose(false); + } + + public void InitListView() + { + listView_Info.Clear(); //clear control + //create column header for ListView + listView_Info.Columns.Add("#", 40, System.Windows.Forms.HorizontalAlignment.Left); + listView_Info.Columns.Add("MessageType", 160, System.Windows.Forms.HorizontalAlignment.Left); + listView_Info.Columns.Add("UserName", 150, System.Windows.Forms.HorizontalAlignment.Left); + listView_Info.Columns.Add("ImageName(PID)", 200, System.Windows.Forms.HorizontalAlignment.Left); + listView_Info.Columns.Add("ThreadId", 60, System.Windows.Forms.HorizontalAlignment.Left); + listView_Info.Columns.Add("Description", 600, System.Windows.Forms.HorizontalAlignment.Left); + } + + public void DisplayEventMessage(ProcessEventArgs processEventArgs) + { + if (GlobalConfig.OutputMessageToConsole) + { + lock (messageQueue) + { + if (messageQueue.Count > GlobalConfig.MaximumFilterMessages) + { + messageQueue.Clear(); + } + + messageQueue.Enqueue(processEventArgs); + } + + autoEvent.Set(); + } + + } + + void ProcessMessage() + { + int waitTimeout = 2000; //2seconds + List itemList = new List(); + + WaitHandle[] waitHandles = new WaitHandle[] { autoEvent, GlobalConfig.stopEvent }; + + while (GlobalConfig.isRunning) + { + try + { + if (messageQueue.Count == 0) + { + int result = WaitHandle.WaitAny(waitHandles, waitTimeout); + if (!GlobalConfig.isRunning) + { + Utils.ToDebugger("Service stopped, processMessage thread exited."); + return; + } + } + + System.Diagnostics.Stopwatch stopWatch = new System.Diagnostics.Stopwatch(); + stopWatch.Start(); + + while (messageQueue.Count > 0) + { + ProcessEventArgs processEventArgs; + + lock (messageQueue) + { + processEventArgs = (ProcessEventArgs)messageQueue.Dequeue(); + } + + string[] filterMessages = new string[0]; + ListViewItem lvItem = FormatProcessInfo(processEventArgs); + itemList.Add(lvItem); + + if (itemList.Count > GlobalConfig.MaximumFilterMessages) + { + AddItemToList(itemList); + itemList.Clear(); + + Thread.Sleep(1000); + } + } + + + if (itemList.Count > 0) + { + AddItemToList(itemList); + itemList.Clear(); + } + } + catch (Exception ex) + { + itemList.Clear(); + Utils.ToDebugger("ProcessMessage exception:" + ex.Message); + EventManager.WriteMessage(160, "ProcessMessage", EventLevel.Error, "ProcessMessage exception:" + ex.Message); + } + } + + } + + void AddItemToList(List itemList) + { + if (itemList.Count < 1) + { + return; + } + + if (listView_Info.InvokeRequired) + { + listView_Info.Invoke(new MethodInvoker(delegate { AddItemToList(itemList); })); + } + else + { + + while (listView_Info.Items.Count > 0 && listView_Info.Items.Count + itemList.Count > GlobalConfig.MaximumFilterMessages) + { + //the message records in the list view reached to the maximum value, remove the first one till the record less than the maximum value. + listView_Info.Items.Clear(); + } + + + if (itemList.Count > 0) + { + listView_Info.Items.AddRange(itemList.ToArray()); + // listView_Message.EnsureVisible(listView_Message.Items.Count - 1); + + itemList.Clear(); + + } + } + } + + + private void AddItemToList(ListViewItem lvItem) + { + if (listView_Info.InvokeRequired) + { + listView_Info.Invoke(new MethodInvoker(delegate { AddItemToList(lvItem); })); + } + else + { + + while (listView_Info.Items.Count > GlobalConfig.MaximumFilterMessages) + { + listView_Info.Items.RemoveAt(0); + } + + listView_Info.Items.Add(lvItem); + + } + } + + public ListViewItem FormatProcessInfo(ProcessEventArgs processArgs) + { + ListViewItem lvItem = new ListViewItem(); + + try + { + string[] listData = new string[listView_Info.Columns.Count]; + int col = 0; + listData[col++] = processArgs.MessageId.ToString(); + listData[col++] = processArgs.EventName; + listData[col++] = processArgs.UserName; + listData[col++] = processArgs.ImageFileName + " (" + processArgs.ProcessId + ")"; + listData[col++] = processArgs.ThreadId.ToString(); + listData[col++] = processArgs.Description; + + lvItem = new ListViewItem(listData, 0); + + if (processArgs.IoStatus >= NtStatus.Status.Error) + { + lvItem.BackColor = Color.LightGray; + lvItem.ForeColor = Color.Red; + } + else if (processArgs.IoStatus > NtStatus.Status.Warning) + { + lvItem.BackColor = Color.LightGray; + lvItem.ForeColor = Color.Yellow; + } + + } + catch (Exception ex) + { + EventManager.WriteMessage(445, "GetFilterMessage", EventLevel.Error, "Add callback message failed." + ex.Message); + lvItem = null; + } + + return lvItem; + + } + + /// + /// Fires this event when the new process was being created. + /// + public void OnProcessCreation(object sender, ProcessEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + // //test block the process creation. + // e.ReturnStatus = NtStatus.Status.AccessDenied; + } + + /// + /// Fires this event before the processs was terminiated. + /// + public void OnProcessPreTermination(object sender, ProcessEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + //test block the process terminiation. + //if (e.ImageFileName.IndexOf("cmd.exe") >= 0) + //{ + // e.ReturnStatus = NtStatus.Status.AccessDenied; + //} + } + + /// + /// Fires this event when the process creation was blocked by the setting, + /// if the control flag 'ENABLE_SEND_PROCESS_DENIED_EVENT' was set. + /// + public void NotifyProcessWasBlocked(object sender, ProcessEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + } + + /// + /// Fires this event after the event was triggered. + /// + public void NotifyProcessTerminated(object sender, ProcessEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + } + + /// + /// Fires this event after the event was triggered. + /// + public void NotifyThreadCreation(object sender, ProcessEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + } + + /// + /// Fires this event after the event was triggered. + /// + public void NotifyThreadTerminated(object sender, ProcessEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + } + + /// + /// Fires this event after the event was triggered. + /// + public void NotifyProcessHandleInfo(object sender, ProcessEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + } + + /// + /// Fires this event after the event was triggered. + /// + public void NotifyThreadHandleInfo(object sender, ProcessEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + } + + } +} + diff --git a/Demo_Source_Code/CSharpDemo/ProcessMon/ProcessMon.Designer.cs b/Demo_Source_Code/CSharpDemo/ProcessMon/ProcessMon.Designer.cs new file mode 100644 index 0000000..d0945d1 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/ProcessMon/ProcessMon.Designer.cs @@ -0,0 +1,212 @@ +namespace ProcessMon +{ + partial class ProcessMon + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ProcessMon)); + this.toolStrip1 = new System.Windows.Forms.ToolStrip(); + this.toolStripButton_StartFilter = new System.Windows.Forms.ToolStripButton(); + this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); + this.toolStripButton_Stop = new System.Windows.Forms.ToolStripButton(); + this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator(); + this.toolStripButton_ClearMessage = new System.Windows.Forms.ToolStripButton(); + this.toolStripSeparator3 = new System.Windows.Forms.ToolStripSeparator(); + this.toolStripButton_UnitTest = new System.Windows.Forms.ToolStripButton(); + this.menuStrip1 = new System.Windows.Forms.MenuStrip(); + this.settingsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.uninstallDriverToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.exitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.listView_Info = new System.Windows.Forms.ListView(); + this.toolStrip1.SuspendLayout(); + this.menuStrip1.SuspendLayout(); + this.SuspendLayout(); + // + // toolStrip1 + // + this.toolStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.toolStripButton_StartFilter, + this.toolStripSeparator1, + this.toolStripButton_Stop, + this.toolStripSeparator2, + this.toolStripButton_ClearMessage, + this.toolStripSeparator3, + this.toolStripButton_UnitTest}); + this.toolStrip1.Location = new System.Drawing.Point(0, 24); + this.toolStrip1.Name = "toolStrip1"; + this.toolStrip1.Size = new System.Drawing.Size(693, 25); + this.toolStrip1.TabIndex = 5; + this.toolStrip1.Text = "toolStrip1"; + // + // toolStripButton_StartFilter + // + this.toolStripButton_StartFilter.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton_StartFilter.Image"))); + this.toolStripButton_StartFilter.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButton_StartFilter.Name = "toolStripButton_StartFilter"; + this.toolStripButton_StartFilter.Size = new System.Drawing.Size(91, 22); + this.toolStripButton_StartFilter.Text = "Start Service"; + this.toolStripButton_StartFilter.Click += new System.EventHandler(this.toolStripButton_StartFilter_Click); + // + // toolStripSeparator1 + // + this.toolStripSeparator1.Name = "toolStripSeparator1"; + this.toolStripSeparator1.Size = new System.Drawing.Size(6, 25); + // + // toolStripButton_Stop + // + this.toolStripButton_Stop.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton_Stop.Image"))); + this.toolStripButton_Stop.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButton_Stop.Name = "toolStripButton_Stop"; + this.toolStripButton_Stop.Size = new System.Drawing.Size(91, 22); + this.toolStripButton_Stop.Text = "Stop Service"; + this.toolStripButton_Stop.Click += new System.EventHandler(this.toolStripButton_Stop_Click); + // + // toolStripSeparator2 + // + this.toolStripSeparator2.Name = "toolStripSeparator2"; + this.toolStripSeparator2.Size = new System.Drawing.Size(6, 25); + // + // toolStripButton_ClearMessage + // + this.toolStripButton_ClearMessage.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton_ClearMessage.Image"))); + this.toolStripButton_ClearMessage.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButton_ClearMessage.Name = "toolStripButton_ClearMessage"; + this.toolStripButton_ClearMessage.Size = new System.Drawing.Size(108, 22); + this.toolStripButton_ClearMessage.Text = "Clear messages"; + this.toolStripButton_ClearMessage.Click += new System.EventHandler(this.toolStripButton_ClearMessage_Click); + // + // toolStripSeparator3 + // + this.toolStripSeparator3.Name = "toolStripSeparator3"; + this.toolStripSeparator3.Size = new System.Drawing.Size(6, 25); + // + // toolStripButton_UnitTest + // + this.toolStripButton_UnitTest.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton_UnitTest.Image"))); + this.toolStripButton_UnitTest.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButton_UnitTest.Name = "toolStripButton_UnitTest"; + this.toolStripButton_UnitTest.Size = new System.Drawing.Size(115, 22); + this.toolStripButton_UnitTest.Text = "Process Unit Test"; + this.toolStripButton_UnitTest.Click += new System.EventHandler(this.toolStripButton_UnitTest_Click); + // + // menuStrip1 + // + this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.settingsToolStripMenuItem, + this.toolsToolStripMenuItem, + this.exitToolStripMenuItem}); + this.menuStrip1.Location = new System.Drawing.Point(0, 0); + this.menuStrip1.Name = "menuStrip1"; + this.menuStrip1.Size = new System.Drawing.Size(693, 24); + this.menuStrip1.TabIndex = 6; + this.menuStrip1.Text = "menuStrip1"; + // + // settingsToolStripMenuItem + // + this.settingsToolStripMenuItem.Name = "settingsToolStripMenuItem"; + this.settingsToolStripMenuItem.Size = new System.Drawing.Size(61, 20); + this.settingsToolStripMenuItem.Text = "Settings"; + this.settingsToolStripMenuItem.Click += new System.EventHandler(this.settingsToolStripMenuItem_Click); + // + // toolsToolStripMenuItem + // + this.toolsToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.uninstallDriverToolStripMenuItem}); + this.toolsToolStripMenuItem.Name = "toolsToolStripMenuItem"; + this.toolsToolStripMenuItem.Size = new System.Drawing.Size(46, 20); + this.toolsToolStripMenuItem.Text = "Tools"; + // + // uninstallDriverToolStripMenuItem + // + this.uninstallDriverToolStripMenuItem.Name = "uninstallDriverToolStripMenuItem"; + this.uninstallDriverToolStripMenuItem.Size = new System.Drawing.Size(152, 22); + this.uninstallDriverToolStripMenuItem.Text = "uninstall driver"; + this.uninstallDriverToolStripMenuItem.Click += new System.EventHandler(this.uninstallDriverToolStripMenuItem_Click); + // + // exitToolStripMenuItem + // + this.exitToolStripMenuItem.Name = "exitToolStripMenuItem"; + this.exitToolStripMenuItem.Size = new System.Drawing.Size(38, 20); + this.exitToolStripMenuItem.Text = "Exit"; + this.exitToolStripMenuItem.Click += new System.EventHandler(this.exitToolStripMenuItem_Click_1); + // + // listView_Info + // + this.listView_Info.Dock = System.Windows.Forms.DockStyle.Fill; + this.listView_Info.FullRowSelect = true; + this.listView_Info.HideSelection = false; + this.listView_Info.HoverSelection = true; + this.listView_Info.LabelEdit = true; + this.listView_Info.Location = new System.Drawing.Point(0, 49); + this.listView_Info.Name = "listView_Info"; + this.listView_Info.ShowItemToolTips = true; + this.listView_Info.Size = new System.Drawing.Size(693, 403); + this.listView_Info.TabIndex = 7; + this.listView_Info.UseCompatibleStateImageBehavior = false; + this.listView_Info.View = System.Windows.Forms.View.Details; + // + // ProcessMon + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(693, 452); + this.Controls.Add(this.listView_Info); + this.Controls.Add(this.toolStrip1); + this.Controls.Add(this.menuStrip1); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Name = "ProcessMon"; + this.Text = "Process monitoring and protection"; + this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.ProcessMon_FormClosing); + this.toolStrip1.ResumeLayout(false); + this.toolStrip1.PerformLayout(); + this.menuStrip1.ResumeLayout(false); + this.menuStrip1.PerformLayout(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.ToolStrip toolStrip1; + private System.Windows.Forms.ToolStripButton toolStripButton_StartFilter; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator1; + private System.Windows.Forms.ToolStripButton toolStripButton_Stop; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator2; + private System.Windows.Forms.ToolStripButton toolStripButton_ClearMessage; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator3; + private System.Windows.Forms.MenuStrip menuStrip1; + private System.Windows.Forms.ToolStripMenuItem settingsToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem toolsToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem exitToolStripMenuItem; + private System.Windows.Forms.ListView listView_Info; + private System.Windows.Forms.ToolStripMenuItem uninstallDriverToolStripMenuItem; + private System.Windows.Forms.ToolStripButton toolStripButton_UnitTest; + } +} + diff --git a/Demo_Source_Code/CSharpDemo/ProcessMon/ProcessMon.cs b/Demo_Source_Code/CSharpDemo/ProcessMon/ProcessMon.cs new file mode 100644 index 0000000..b75d9c0 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/ProcessMon/ProcessMon.cs @@ -0,0 +1,201 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +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; +using System.Reflection; +using System.IO; +using System.Diagnostics; +using System.Runtime.InteropServices; + +using EaseFilter.FilterControl; +using EaseFilter.CommonObjects; + +namespace ProcessMon +{ + public partial class ProcessMon : Form + { + + ProcessHandler processHandler = null; + FilterControl filterControl = new FilterControl(); + + public ProcessMon() + { + GlobalConfig.filterType = FilterAPI.FilterType.PROCESS_FILTER|FilterAPI.FilterType.CONTROL_FILTER|FilterAPI.FilterType.MONITOR_FILTER; + InitializeComponent(); + + StartPosition = FormStartPosition.CenterScreen; + DisplayVersion(); + + processHandler = new ProcessHandler(listView_Info); + + } + + ~ProcessMon() + { + GlobalConfig.Stop(); + } + + private void DisplayVersion() + { + string version = Assembly.GetExecutingAssembly().GetName().Version.ToString(); + try + { + string filterDllPath = Path.Combine(GlobalConfig.AssemblyPath, "FilterAPI.Dll"); + version = FileVersionInfo.GetVersionInfo(filterDllPath).ProductVersion; + } + catch (Exception ex) + { + EventManager.WriteMessage(43, "LoadFilterAPI Dll", EventLevel.Error, "FilterAPI.dll can't be found." + ex.Message); + } + + this.Text += " Version: " + version; + } + + + void SendSettingsToFilter() + { + filterControl.ClearFilters(); + + GlobalConfig.Load(); + + if (GlobalConfig.ProcessFilterRules.Count == 0) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("You don't have any process filter setup, please go to the settings to add a new filter rule, or the filter driver won't intercept any process or IO."); + } + + foreach (ProcessFilterRule filterRule in GlobalConfig.ProcessFilterRules.Values) + { + ProcessFilter processFilter = filterRule.ToProcessFilter(); + + processFilter.OnProcessCreation += processHandler.OnProcessCreation; + processFilter.OnProcessPreTermination += processHandler.OnProcessPreTermination; + processFilter.NotifyProcessWasBlocked += processHandler.NotifyProcessWasBlocked; + processFilter.NotifyProcessTerminated += processHandler.NotifyProcessTerminated; + processFilter.NotifyThreadCreation += processHandler.NotifyThreadCreation; + processFilter.NotifyThreadTerminated += processHandler.NotifyThreadTerminated; + processFilter.NotifyProcessHandleInfo += processHandler.NotifyProcessHandleInfo; + processFilter.NotifyThreadHandleInfo += processHandler.NotifyThreadHandleInfo; + + filterControl.AddFilter(processFilter); + } + + + string lastError = string.Empty; + if (!filterControl.SendConfigSettingsToFilter(ref lastError)) + { + MessageBox.Show(lastError, "StartFilter", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + + + } + + + private void toolStripButton_StartFilter_Click(object sender, EventArgs e) + { + try + { + //Purchase a license key with the link: http://www.easefilter.com/Order.htm + //Email us to request a trial key: info@easefilter.com //free email is not accepted. + string licenseKey = GlobalConfig.LicenseKey; + + string lastError = string.Empty; + + bool ret = filterControl.StartFilter(GlobalConfig.filterType, GlobalConfig.FilterConnectionThreads, GlobalConfig.ConnectionTimeOut, licenseKey, ref lastError); + if (!ret) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("Start filter failed." + lastError, "StartFilter", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + SendSettingsToFilter(); + + toolStripButton_StartFilter.Enabled = false; + toolStripButton_Stop.Enabled = true; + + EventManager.WriteMessage(102, "StartFilter", EventLevel.Information, "Start filter service succeeded."); + } + catch (Exception ex) + { + EventManager.WriteMessage(104, "StartFilter", EventLevel.Error, "Start filter service failed with error " + ex.Message); + } + } + + private void ProcessMon_FormClosing(object sender, FormClosingEventArgs e) + { + FilterAPI.ResetConfigData(); + GlobalConfig.Stop(); + filterControl.StopFilter(); + Application.Exit(); + } + + private void toolStripButton_Stop_Click(object sender, EventArgs e) + { + FilterAPI.ResetConfigData(); + filterControl.StopFilter(); + + toolStripButton_StartFilter.Enabled = true; + toolStripButton_Stop.Enabled = false; + } + + private void toolStripButton_ClearMessage_Click(object sender, EventArgs e) + { + processHandler.InitListView(); + } + + private void exitToolStripMenuItem_Click_1(object sender, EventArgs e) + { + FilterAPI.ResetConfigData(); + GlobalConfig.Stop(); + filterControl.StopFilter(); + Close(); + } + + private void uninstallDriverToolStripMenuItem_Click(object sender, EventArgs e) + { + GlobalConfig.Stop(); + filterControl.StopFilter(); + FilterAPI.UnInstallDriver(); + } + + private void settingsToolStripMenuItem_Click(object sender, EventArgs e) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + ProcessFilterSettingCollection settingForm = new ProcessFilterSettingCollection(); + if (settingForm.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + SendSettingsToFilter(); + } + } + + private void toolStripButton_UnitTest_Click(object sender, EventArgs e) + { + toolStripButton_Stop_Click(null, null); + ProcessUnitTestForm regUnitTest = new ProcessUnitTestForm(GlobalConfig.LicenseKey); + regUnitTest.ShowDialog(); + } + + } +} diff --git a/Demo_Source_Code/CSharpDemo/ProcessMon/ProcessMon.csproj b/Demo_Source_Code/CSharpDemo/ProcessMon/ProcessMon.csproj new file mode 100644 index 0000000..16c0d14 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/ProcessMon/ProcessMon.csproj @@ -0,0 +1,190 @@ + + + + Debug + x86 + 8.0.30703 + 2.0 + {BB797E16-A353-478D-9335-1D1B6AED38F8} + WinExe + Properties + ProcessMon + ProcessMon + v4.5 + + + 512 + SAK + SAK + SAK + SAK + + + AnyCPU + true + full + false + ..\..\Release\ + DEBUG;TRACE + prompt + 4 + false + false + + + AnyCPU + pdbonly + true + ..\..\Release\ + TRACE + prompt + 4 + false + + + processmon.ico + + + app.manifest + + + true + ..\..\Release\ + DEBUG;TRACE + full + AnyCPU + ..\..\Release\ProcessMon.exe.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + false + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false + + + ..\..\Release\ + TRACE + true + pdbonly + AnyCPU + ..\..\Release\ProcessMon.exe.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + false + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false + false + + + + + + + + + + + + + + + + + Form + + + ProcessFilterSetting.cs + + + Form + + + ProcessFileAccessRights.cs + + + Form + + + ProcessFilterSettingCollection.cs + + + Form + + + ProcessMon.cs + + + + + + + Form + + + ProcessUnitTestForm.cs + + + ProcessFilterSetting.cs + + + ProcessFileAccessRights.cs + + + ProcessFilterSettingCollection.cs + + + ProcessMon.cs + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + True + Resources.resx + True + + + ProcessUnitTestForm.cs + + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + + + + + + + {34CB783E-DDA2-4CE3-80BC-37B25AA33E5F} + CommonObjects + + + {21540012-A296-45CE-8D35-3EA5A07B32A6} + FilterControl + + + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/ProcessMon/ProcessMon.resx b/Demo_Source_Code/CSharpDemo/ProcessMon/ProcessMon.resx new file mode 100644 index 0000000..6236c05 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/ProcessMon/ProcessMon.resx @@ -0,0 +1,485 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 19, 21 + + + + + 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 + AAAAAElFTkSuQmCC + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAJFSURBVDhPrdBbSNNxHAXwo2aKl8ZyMy/brFzWPypvyBQL + iTJCAyWIIOqlMEkjZ4VWCNYg8hIpou1BQyScmvmgwzKjBokJBiL1IoSG1JKcl9wclTZP7u/vyYd88fPy + 53vO4f/ww6aKNYe/SGuKnT1Qox2NNql6cBFFyMceUW9sd0NER82XAra67rB7qZL9rGPuS8P8auWztthI + KXSK8pDvLT9LaXHdYx9rebwn3SlafNiKnAF/xItznWoY0p7FOOqn89g4a6TFXcZuPuBhy6HPYoF3gNoa + hImBABSKSKiALrVNN3NjLJ2myVyaxs8xuzlmuctTTqlx56BYyWzBMNpU8PQF4KiIAOWj4OZroxk0fjIw + oyt6AXeRh2IUWH6VMKxeUSdmsvfbcHIkCnwVitciAlLa9jvODklMtGicqEKCHFZAgWr/SpggybcwokL5 + pB4cVMP7uGviWvXuLJuevnUoE5FsJQLSQhTur4Qh1Hv/UCNhUgvnrAQOR2BKHnlpnihtBquGqMUxEcmW + kwMbWJzIiUhcntbg0tzBwAWm+vFPAjikRpOYrTIjc2+nyrP6vSoS2e9s7RCbztN+KnLp760MMl8is0Jp + 3+UzM6yEVszWbGn3NfqZfcfRge0iwtIFaZzWIvL5FXp/xKpsOtIUjqkdMIjJOu1IQgtyxIXFmydcHKkk + 39wmuwr5NSnkm10Jnaj/j4Cf8/oRN11vybHHZH8JPQ9zuZgc8lRMNsY47JuLDzLPZIb3Ok7rP06diZt3 + pih6Rb0ZgH+vle/bCJhHDQAAAABJRU5ErkJggg== + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHvSURBVDhPrY9fSFNRHMdvpqVLqLcgZhS4hwohMo2ChN5i + RJE2pKfeRg9D7CFh9SAlYZP+IguKakarsLIyxNqw7porGSSZXqRxJWFhra1sbUVuu9unK563K60HP/Dl + HH7fzzmHIy05wLKkT7LHfCWjky/Xa+PPq/KTt8uVsGdNC/dty4W2ONBekn0hPZhT94Mm6+mH392QPEbi + TQ2BbmkAWS4VupH00EpHRm3UD4b19MLcVUh1QNwBscPE5Wp8503HhW4kMbRinMyg/uo1yPVAVk+qE762 + QLRJX5uRL1REhG5k5unaLH8ewuxJSLsWMnsCPtthei98ayN8pkITupGZ/tXf+XkWvtgpxFsXMr+PHqKg + 7tQv68R/qTwldCOKt/QRagN8aiT/cT4HyU/tQ5uo02dHKEwd4PGpsmdCNxIPNFgid8sSqDsgsgtNqQe1 + Hu3ddv0LTQS7pLTirdsq9MXJDtfUqp5VOT5sITNiJjdmIRPegHzdlJ9+sm2P0P7N+xumUGFiM+mgmV+v + N5J9a2HkXOWoqIuj9m5qHjwtEXRJvOqSGGiXCLmrj4q6OH19svmi20tADuK5eYvWtg4uX+mpFXVxFEWp + dLlcseBwCO+dezidzqTf718n6v/D7XZXWa3WqM1m++FwOHaL8VIjSX8BS9c/mtQKzXcAAAAASUVORK5C + YII= + + + + 124, 21 + + + + AAABAAEAQEAAAAEAIAAoQgAAFgAAACgAAABAAAAAgAAAAAEAIAAAAAAAAEAAABMLAAATCwAAAAAAAAAA + AAAaEmMAFxFfAxkSYQ0cEmY4HRJngh0SZ7kcEmfYHBJn7hwSZ/ocEmf/HBJn/xwSZ/8cEmf/HBJn/xwS + Z/8cEmf/HBJn/xwSZ/8cEmf/HBJn/xwSZ/8cEmf/HBJn/xwSZ/8cEmf/HBJn/xwSZ/8cEmf/HBJn/xwS + Z/8cEmj/GxJk/xkRXv8XD1j/Fg5U/xYOUv8XDlP/Fw5T/xcPVP8XD1T/Fw9U/xcPVP8XD1b/Fw9W/xcP + Vv8XD1b/GA9X/xgPV/8YD1j/GA9Y/xgQWf8YEFn/GBBa/xgQWv8ZEFr/GRBa+hgPXO8YD1zcGRBcvhoQ + XIgZEFs8GBBYDxcQVwQYEFkAEg9bAh0SZhQeE2c4HhNnaR4SZ6IdEmfLHRJn4h0SZ/IdEmf7HRJn/x0S + Z/8dEmf/HRJn/x0SZ/8dEmf/HRJn/x0SZ/8dEmf/HRJn/x0SZ/8dEmf/HRJn/x0SZ/8dEmf/HRJn/x0S + Z/8dEmf/HRJn/x0SZ/8dEmf/HBJl/xsRYf8ZEFv/GA9W/xcPU/8XDlL/Fw5T/xcOU/8XD1T/Fw9U/xcP + VP8XD1T/Fw9V/xcPVv8YD1b/GA9W/xgPV/8YD1f/GA9Y/xkPWP8ZEFn/GRBZ/xkQWv8ZEFr/GRBa/xkQ + W/wZEFvzGRBc5RoQXM8aEFymGxFcbBsRXDoaEFsVFA9UAxcRYA0eE2c4HxNojR8TaMcfE2jfHhNo7h4T + aPYeE2j7HhNo/h4TaP8eE2j/HhNo/x4TaP8eE2j/HhNo/x4TaP8eE2j/HhNo/x4TaP8eE2j/HhNo/x4T + aP8eE2j/HhNo/x4TaP8eE2j/HhNo/x4TaP8eE2j/HhJm/xwRYP8aEFv/GRBW/xgPU/8YD1L/GA9S/xgP + U/8YD1P/GA9U/xgPVP8YD1T/GA9U/xgQVf8ZEFX/GRBW/xkQVv8ZEFf/GRBX/xkQWP8aEFj/GhBZ/xoQ + Wf8aEFr/GhBa/xoRW/8aEVv+GhFb+xoRW/cbEVzvGxFc4RwRXcocEV2PGxFcOhcPVw8fE2g4HxNoaR8T + aMcfE2j9HxNo/x8TaP8gE2j/IBNo/yATaP8gE2j/IBNo/yATaP8gE2j/IBNo/yATaP8gE2j/IBNo/yAT + aP8gE2j/IBNo/yATaP8gE2j/IBNo/yATaP8gE2j/IBNp/yATaf8fE2j/HxNm/x0SYv8bEFr/Gg9V/xkO + Uv8YD1H/GA9S/xkPU/8ZD1P/GQ9T/xkPVP8ZD1T/GQ9U/xoPVP8ZEFX/GhBV/xoQVv8aEFb/GhBX/xoQ + V/8aEFj/GxBY/xsQWf8bEFn/GxBa/xsQWv8bEVv/GxFb/xsRW/8cEVv/GxFc/xwRXP8cEV3+HBFdyhwR + XWwbEF08IRRqgiEUaqIhFGrfIBRp/yAUaf8gFGn/IRRp/yEUaf8hFGn/IRRp/yEUaf8hFGn/IRRp/yEU + af8hFGn/IRRp/yEUaf8hFGn/IRRp/yEUaf8hFGn/IRRp/yEUaf8hFGn/IRRp/yEUav8hFGr/IBNn/x4S + Yf8cEVv/Gg9V/xkOUf8ZDlH/GQ5R/xkPUv8aEFP/GhBU/xoQVP8aEFT/GhBU/xoQVf8bEFX/GxBV/xsQ + Vv8bEFb/GxBX/xsRV/8bEVj/GxFY/xwRWf8cEVn/HBFa/xwRW/8cEVv/HBFb/xwRW/8cEVz/HRFc/x0S + XP8dEl3/HRJe/x0SXuEdEV6mHRFfiCIUa7kiFGvLIRRr7iEUa/8hFGv/IRRr/yEUa/8hFGv/IRRr/yEU + a/8hFGv/IRRr/yEUa/8hFGv/IRRr/yEUa/8hFGv/IRRr/yEUa/8hFGv/IRRr/yEUa/8hFGv/IhRr/yIU + a/8hFGr/IRNn/x8SYv8cEFr/GxFY/xsWWv8bGVz/Gxld/xoWWv8aEVT/Gg9S/xoPU/8aEFT/GhBU/xsQ + VP8bEFX/GxBW/xsQVv8bEFf/GxBX/xsQWP8bEVj/HBFZ/xwRWf8cEVr/HBFa/xwRWv8cEVv/HBFb/xwR + W/8dEVv/HRFc/x0RXf8dEl3/HRJe/x0SXv8eEl/vHhJfzx4SX74jFWzZIxVs4yIVbPYiFWz/IhVs/yIV + bP8iFWz/IhVs/yIVbP8iFWz/IhVs/yIVbP8iFWz/IhVs/yIVbP8iFWz/IhVs/yIVbP8iFWz/IhVs/yIV + bP8iFWz/IhVs/yMVbP8jFWz/IhRp/yASYv8dEFr/Gw5T/xsWWf8dJmz/HjB3/x4weP8dJm3/GxZa/xoN + UP8bDlL/GxBU/xsQVP8cEVX/HBFW/xwRVv8cEVf/HBFX/xwRWP8cEVj/HBFZ/x0RWf8dEVr/HRFa/x0S + W/8dElv/HRJb/x4SW/8dElz/HhJc/x4SXf8eEl3/HhJe/x4SXv8eEl//HxJf9h8SYOUfE2DcJBVs7yQV + bPMkFWz7JBVs/yQVbP8kFWz/JBVs/yQVbP8kFWz/JBVs/yQVbP8kFWz/JBVs/yQVbP8kFWz/JBVs/yQV + bP8kFWz/JBVs/yQVbP8kFWz/JBVs/yQVbP8jFGv/IxNo/yEUZf8gGGP/Hhxj/x0jZ/8eMnb/IUeP/yJT + nf8iU53/IUeQ/x8yd/8dImb/HRpf/xwVWv8cEVX/HBBU/xwQVf8cEVb/HBFX/x0RV/8dEVj/HRFY/x0R + Wf8eEVn/HhFa/x4RWv8eElv/HhJb/x4SW/8fElv/HxJc/x4SXP8eEl3/HxJd/x8SXv8fEl7/HxJf/yAS + X/sgE2DzIBNg7yUWbfolFm37JRZt/iUWbf8lFm3/JRZt/yUWbf8lFm3/JRZt/yUWbf8lFm3/JRZt/yUW + bf8lFm3/JRZt/yUWbf8lFm3/JRZt/yUWbf8lFm3/JRZt/yUWbf8lFm3/JBRp/yIRYP8hFmH/ISRs/yE3 + fv8iT5X/I2Sr/yZ2wP8nf8v/J3/L/yZ2wP8kZKv/Ik6T/yA0e/8fIWf/HhRZ/x0PU/8dEFT/HRFW/x0R + V/8eElf/HhJY/x4SWP8eElj/HxJY/x4SWf8fElr/HxJb/x8SW/8fElv/IBJb/yATXP8fE1z/HxNd/yAT + Xf8gE17/IBNe/yATX/8hE1/+IRNg/CETYPonFm3/JxZt/ycWbf8nFm3/JxZt/ycWbf8nFm3/JxZt/ycW + bf8nFm3/JxZt/ycWbf8nFm3/JxZt/ycWbf8nFm3/JxZt/ycWbf8nFm3/JxZt/ycWbf8mFm3/Jhds/yQb + bf8iI27/IjB4/yNEi/8lW6T/JnbA/yiK1f8qluT/K53r/yud6/8qluT/KYnU/yd0vv8kWaL/IkGJ/yEu + dP8fIWb/Hxhe/x8UWf8eElf/HxFW/x8SV/8fElj/HxJY/x8SWP8fEln/IBJa/yASW/8gElv/IBJb/yAS + W/8gE1z/IRNc/yATXf8hE13/IRNe/yETXv8hE1//IhNg/yETYP8hE2D/KBdv/ygXb/8oF2//KBdv/ygX + b/8oF2//KBdv/ygXb/8oF2//KBdv/ygXb/8oF2//KBdv/ygXb/8oF2//KBdv/ygXb/8oF2//KBdv/ygW + bv8oFW7/Jxdt/yUbbP8kLHn/JUiR/yZgqP8ndL3/KIXR/yuU4/8tnu//LqT3/y6n+/8up/v/LqT3/y2e + 7/8rk+L/KIXQ/yZzvP8lX6f/I0aO/yEscv8gG2H/IBNZ/x8RVv8gEVf/IBJY/yASWf8gEln/IBNZ/yAT + Wv8hE1v/IRNb/yETXP8hE1z/IRNd/yITXf8iE17/IhNe/yIUX/8iFF//IhRg/yMUYP8jFGH/IxRh/ygX + b/8oF2//KBdv/ygXb/8oF2//KBdv/ygXb/8oF2//KBdv/ygXb/8oF2//KBdv/ygXb/8oF2//KBdv/ygX + b/8oF2//KRdv/ykWbv8oGXH/KCB2/ycqff8mN4T/Jk6Y/yhtt/8qhtH/K5bi/yyf7f8uoPL/Lpzv/y2S + 5f8tjeD/LY3g/y2S5f8um+//LqDy/yyf7f8qluL/KYXQ/ydtt/8kT5f/IzZ9/yIlbP8hGmD/IBNZ/yAR + V/8gElj/IBJZ/yATWv8hE1r/IRNb/yETW/8hE1z/IRNc/yITXf8iE13/IhNe/yITXv8iFF//IxRf/yMU + YP8jFGD/IxRh/yMUYf8pGHD/KRhw/ykYcP8pGHD/KRhw/ykYcP8pGHD/KRhw/ykYcP8pGHD/KRhw/ykY + cP8pGHD/KRhw/ykYcP8pGHD/KRhw/yoXb/8qFm7/KSB3/yg2iP8oT5z/KGiy/yp+yP8skd7/Lp7t/y6l + 9v8vpPb/L5ns/y2D1f8qY7L/KFGe/yhRnf8pYbD/LYLU/y+Z7P8vpPb/LqX2/y2e7f8skd7/KX/I/ydm + rv8lSJD/Iy51/yEZX/8hEFX/IRFX/yETWf8hE1r/IhNa/yITW/8iE1v/IhRc/yIUXP8iFF3/IxRd/yMU + Xv8jFF7/IxRf/yQUX/8kFWD/JBVg/yQVYf8kFWH/Kxhw/ysYcP8rGHD/Kxhw/ysYcP8rGHD/Kxhw/ysY + cP8rGHD/Kxhw/ysYcP8rGHD/Kxhw/ysYcP8rGHD/Kxhw/ysYcf8qHXX/Kid9/yo7jv8pV6b/KnO//yuN + 1/8tnOn/L6Ly/y+g8v8vluj/LYjZ/yx1xf8pW6j/JjuE/yQpcf8kKXD/JTmD/ylap/8sdcT/LojZ/y+X + 6f8voPL/L6Ly/y2d6f8ri9X/KG23/yZQmf8kNHv/IyJo/yIYXv8iFFr/IhNa/yITWv8iE1v/IxNb/yMU + XP8jFFz/IxRd/yMUXf8jFF7/JBRe/yQUX/8lFF//JRVg/yQVYP8kFWH/JBVh/ywZcf8sGXH/LBlx/ywZ + cf8sGXH/LBlx/ywZcf8sGXH/LBlx/ywZcf8sGXH/LBlx/ywZcf8sGXH/LBhx/ywZcv8sG3P/KyyB/ypL + m/8qaLX/K4HO/yyV4v8uovD/L6X1/zCe8P8vitz/K2u6/yhPm/8lOX//Iyhs/yIeYf8iGVz/Ihhc/yIe + Yv8jKG3/JjmB/ylQnP8sbLv/L4vd/zCe8P8vpfX/LqHw/yyT4P8qfsn/KGOs/yZFjf8lJ23/JBZc/yQU + W/8jE1v/IxRb/yQUXP8kFF3/JBRd/yQUXf8kFF3/JBVe/yUVX/8lFWD/JhVg/yYVYf8mFWH/JRVh/yUV + Yf8vG3T/Lxtz/y4ac/8tGXL/LRly/y0Zcv8tGXL/LRly/y0Zcv8tGXL/LRly/y0Zcv8uGXL/Lhly/y0Z + cv8tIHj/LC+F/yxKnP8rb73/K4vY/y2d6/8vo/L/L5zt/y+P4P8tfMv/K2Kv/ydDjP8kKW//IRdY/yAP + Tv8hEFD/IRFS/yERU/8hEVL/IRBR/yIYW/8lKnH/KEOP/yxjsf8ufc3/L5Di/y+d7v8vo/P/LZ3q/yyJ + 1f8qa7b/KEeP/yYscv8lHGP/JRRb/yQUW/8kFFz/JRRd/yUUXf8lFF3/JRRe/yUVX/8mFV//JhVg/yYV + YP8mFWH/JhVh/yYVYf8nFWH/NSF4/zMfd/8wHHX/Lxpz/y4Zc/8uGXP/Lhlz/y4Zc/8uGXP/Lhlz/y4a + c/8uGnP/Lxlz/y4Zc/8uG3X/LS+F/yxVpf8sdsT/LpHg/y+i8f8wp/j/MJvs/y5+zv8rX6z/J0CH/yUr + bv8jIGP/Ihha/yETU/8hEFD/IRJS/yISU/8iElP/IhJT/yERU/8iFFb/Ixle/yUiZ/8mLXP/KUKL/yxh + sP8vgNH/L53t/y+o+P8vofH/LZDd/yt1wP8pU5v/Jytz/yYWXv8lFVz/JRVc/yYVXf8mFV3/JhVe/yYV + Xv8mFV//JxVf/ycWYP8nFmD/JxZh/ycWYf8nFmL/KBZi/0EugP9ALH//PSl9/zome/85JHr/NyN5/zYh + eP80IHj/Mx53/zIddv8xG3X/MBp0/y8adP8uIXr/Li+H/y1Nof8teMb/LpXi/zCh8P8wn+//Lo/f/yx2 + xP8oVaH/JTV9/yEaXP8fDUz/Hg1M/x4OTv8eD0//Hw9Q/x8QUf8fEFH/HxBS/yAQUv8gEFP/IBBT/yAP + U/8hD1L/IQ5S/yMcYv8nOIP/Klim/y15yf8vkuL/MKDx/zCh8f8uleL/K3fC/ylLlP8nLHT/Jhxk/yYV + XP8mFVz/JhVd/yYVXv8mFV7/JxVf/ycVX/8nFmD/JxZg/ycWYf8oFmH/KBZi/ygWYv9UQoz/VEGM/1JA + i/9QPYr/TTmH/0k1hf9EMYL/QC1//z0off85JHr/NR94/zEcdv8wHHb/LjCG/y1WqP8tecj/L5bl/zCi + 8f8xm+z/LoLR/ylZo/8lOoD/Iidr/yAZW/8eEFD/HQxM/x0NTP8dDU3/HQ5O/x0OT/8eDk//Hg5Q/x4O + UP8fD1H/Hw9S/yAPUv8fD1L/Hw5S/yAOUv8hElj/Ixxj/yUqc/8oPon/K12r/y+F1v8xne//MKPy/y6W + 5P8secT/KlWe/ycsdP8mF17/JxVd/ycVXf8nFl7/JxZe/ycWX/8oFl//KBZg/ygWYP8oFmH/KRZh/ykX + Yv8pF2L/X02T/19Nk/9eTZP/XUuS/1pHkP9WQ43/UT+L/047iP9KNob/RjGD/0IsgP8+LYH/OzaJ/zhR + of81fMj/M5jk/zKh8P8wl+b/LHrJ/yxcpP8xPnz/NjBm/zswYv9BNGT/Rjtq/0tAcP9PRHP/UUZ1/1NI + d/9USXn/VUl5/1NIeP9RRXb/T0R1/09DdP9PRHX/UkZ3/1JGd/9PQ3b/Sz9x/0Y4bP89MGn/MSpr/yw5 + gf8tXqz/L3/P/zGZ6v8xovH/L5fk/yx5xP8qSZL/KClx/ygaYv8nFFz/JxVd/ygWX/8oFl//KBZf/ygW + YP8pFmH/KRZh/yoWYv8qF2L/KRdi/2BPlf9gT5X/YE6V/2BOlP9fTZT/XkuT/1xKkv9bSZH/WkeQ/1lF + j/9XQ43/VU2X/1Fmrf9Mgsj/RZ/l/z6n8P83mOX/LnbC/yVEi/8uM2//SEVw/2BZeP90bYX/hYCU/5aT + pP+iobH/rKq5/7Oxv/+4t8X/vLrI/726yf+6t8b/s7HA/62ru/+pprb/qqe3/7GtvP+wrbz/qaa1/52a + qv+MiJv/cGmH/0tAcP8zLGr/LDB3/ytLl/8wesn/Mpjo/zGj8f8wleL/LnG8/yxKlP8pJW7/KBNb/ygV + Xf8pFl//KRdg/yoXYP8qF2H/Khdh/yoXYv8rF2L/Kxdj/ysXY/9iUJb/YlCW/2JQlv9iUJb/YlCW/2JQ + lv9iUJb/Y1CW/2NQlv9jUZb/Y1OY/2Fnqv9ei8r/WaTj/1Ow8f9Mpun/RIjL/0Jop/9GS3//V010/3Vv + hv+KiJX/lpSd/6Cgp/+rrLL/tLW7/7q7wf++vsX/wMDI/8jIz//U1tj/3N/e/9/i4P/W2dn/w8bI/7m6 + wP+5uMH/t7W//7Kxuf+rrLP/o6Sq/5GQnf92b4z/Wk56/z8xaP8wM3X/MFag/zB5x/8ymef/MqHu/zGP + 3P8uarX/LDaA/yoaYv8qF1//KhZf/yoXYP8qF2D/Khdh/ysXYf8rF2L/Kxdi/ysXY/8rF2P/ZFGX/2RR + l/9kUZf/ZFGX/2RRl/9kUZf/ZFKX/2RRl/9kUZf/ZFWa/2Rdov9jeLn/YaLf/1+18f9drer/WpbQ/1l0 + p/9qcZf/jI2k/6WlsP+ytbr/r7O2/52fpf+PkJn/hYWS/358jf94dIv/cWuH/2pjgv94c43/m5qm/7m8 + vv/P1NP/xcrL/52fqP9/fpD/bmiG/2hhgv9sZoT/eHWL/4qKl/+dn6f/rrC4/5uaq/9mX4L/QTtu/zEy + c/8sSJP/MHrI/zKa6P8yoe7/MIbT/y5NmP8sKHL/Kxxk/ysWX/8rF1//Kxdg/ysXYP8rF2D/LBhh/ywY + Yv8sGGP/LBhj/2ZTmf9mU5n/ZlOZ/2ZTmf9mU5n/ZlOZ/2ZTmf9mUpj/ZlKY/2ZboP9lcLL/ZI7N/2Sx + 7f9itu//YJvU/2SDtf9uc5b/iYWZ/7O1uv/DyMn/ur3C/6eosv+NjZz/d3WJ/2Vhe/9WT2//SUBn/0E2 + Yf8/NV//WFJy/4qLmf+prbL/sba7/6mttf+SlqH/fX6Q/2tohv9lYYL/bGmH/3p5kP+Nj5z/oqes/7e9 + v/+us7n/iImb/2BZff87KmT/Kilw/y5Wov8xgM7/MqHu/zKa5v8wa7f/LkKN/ywkbf8rFV3/KxZf/ysX + YP8rF2D/LBdg/ywYYf8sGGL/LBhj/ywYY/9pVZr/aVWa/2lVmv9pVZr/aVWa/2lVmv9pVZr/aVSZ/2lT + mP9oZqn/Z4vK/2ao5P9muPP/Y6jg/158sP9pb5j/hIWc/5+gqv+4vL7/sbO6/4uHn/9zaoz/aWCE/19V + fP9SR3L/RDdn/zYnXP83KVv/SD9l/29thP+orLT/sLe8/4uMnP+HiJn/qK61/7e/w/+yucH/sLfB/7K6 + wv+yusD/rra5/6Oqrv+RlZ//kZaf/6Gpr/+Ki5//TT9y/ywfZP8tMHn/L1ij/zKP3P8zovD/M43b/zFl + sf8tL3j/LBRc/ywWXv8sGGD/LBhh/y0YYf8tGGH/LRhi/y0YY/8uGGT/a1ec/2tXnP9rV5z/a1ec/2tX + nP9rV5z/a1ec/2tXm/9rWJz/anCy/2if3P9ntvD/Z7Lq/2OVy/9dZ5f/bGWI/4+Qn/+prrL/tbq8/6Gi + rv9wZ4r/V0l4/1dKeP9WSnf/UkZ0/0s/bv9ENmf/TEFs/2Ziff+Iipj/rbS5/6Sqsf9xb4b/dHSJ/663 + vP/G0dH/uMDH/7G3wf+0u8P/uMHF/7vHxv+iqbD/b2+H/3JyiP+mr7P/oKew/15Wfv82JmL/Lx5j/y47 + hP8xdsL/NJnn/zSf7f8yfsv/LzyG/y0ZYf8tF2D/LRhg/y0YYf8uGGL/LRhi/y4YY/8uGGT/Lxhk/21Z + nf9tWZ3/bVmd/21Znf9tWZ3/bVmd/21Znf9tW5//bWCj/2x8vP9qrOb/aLjv/2ee1f9jf7L/Xl6M/25k + hv+Rkp//p66w/620tf+Zm6f/bmaJ/1lLef9aTnr/X1R+/2Vegv9rZYX/cGmG/357kf+VmKT/nqWr/5if + pf+EhpP/ZGJ6/3Bwhv+kr7T/qLO5/3p6lP9mYIL/b2yH/4qOnv+xvsD/n6ez/1hPe/9VTHf/lp2p/6Cq + r/9ubIb/SDxq/zQiYP8tK3T/MVek/zOAzv8zoO3/Mo3Z/zFLlv8vI27/Lhtk/y4YYP8uGGH/Lxhi/y8Z + Y/8vGWP/Lxlk/zAZZP9vW5//b1uf/29bn/9vW5//b1uf/29anv9vWp7/b2Cj/29srv9tisj/a7Tt/2m1 + 6v9mjMD/Ymuc/19YhP9vZYb/kZKf/6atsP+rsrT/naGr/397lf9ybI3/enSU/4J/m/+Li6D/kpOk/5ia + p/+lqrH/tsDC/6+5u/+Qlp7/dXaH/2Jgef9ydIn/oK2y/5unrv9iYH7/SEBn/1NObv93eo3/rbu9/52m + tP9NQHX/RTdt/4aLnf+Zpaj/eHyM/1ZPc/85J2L/LCFp/zA8iP8yaLT/M5zn/zOZ4/8yXqn/MTR//y8g + av8uF2D/Lxhh/y8YYv8vGWP/MBlj/zAZZP8wGWT/cVyg/3FcoP9xXKD/cVyg/3FcoP9xXKD/cVuf/3Bm + qf9vfLz/bpnV/2y58P9pr+L/ZX2s/2Fdif9fVH7/b2eG/5CSoP+mrrH/r7e5/6uzt/+eo63/oKSw/7C4 + wP+6xMr/vMbK/7vEyP+3wcP/vMfI/8jV1P+7x8j/l5ym/3t7jf9raYH/en2Q/6Oytv+hsbT/c3mK/15f + df9laHv/gouW/66+v/+bpLP/TUF1/0Ezaf94fJD/jpqe/3uEj/9eXXv/PC1m/ywaYf8uJ3D/MVKb/zOU + 3v80oOr/NHO+/zNJlP8wJ3H/Lxdg/y8YYf8wGWL/MBlj/zAZY/8xGmT/MRpk/3Neov9zXqL/c16i/3Ne + ov9zXqL/c12h/3Ndof9ybK3/cInH/2+k3v9uuO//aqfZ/2Vzn/9hVX7/YFN8/3BoiP+PkqD/p7C0/7bB + wv+4w8P/rre5/664uv+4xMf/vMjL/7nByP+zusP/rbO9/7O7wv/D0dH/u8jJ/5uhq/+Cg5T/c3GJ/4GE + mP+pt7z/rL6+/4uXnf97hI7/gIuU/5KgpP+pvbv/kJqq/0o+cv9AMmj/dHiN/4mWm/95hI7/X2B8/z0u + Z/8sFl3/LRth/zBDiv8ziNL/NZ/p/zWCzv80W6b/MS53/y8XX/8wGGD/MBli/zAZY/8wGWP/MRpk/zEa + ZP92YKP/dmCj/3Zgo/92YKP/dmCj/3Zfov92XqL/dXGx/3KV0P9wrOP/cLPp/2ydz/9mbpn/YlR9/2JU + ff9xaYn/j5Kg/6q1t//Azs3/wM7N/6u2uf+bo6v/kpel/4uLoP+Ef5v/fneX/3x0lf+LiqL/qrW8/7C+ + v/+dpaz/iYub/3l2kP+Hh57/r7vC/7nLyv+ktbX/m6ut/6Cxsv+itrX/n7Sy/32Imf9DN2z/QjVq/3mA + kv+Lmp7/c32K/1dXdv86K2T/LRVb/y4WXP8xOYD/NHnE/zaW4v82jNj/NGm0/zEye/8wFl//MBdg/zEZ + Yv8xGmP/MRpj/zEaZP8yGmX/eGKl/3hipf94YqX/eGKl/3hipf94YaT/eGCj/3Z1tf9zn9f/cbPo/3Gu + 4/9ulcb/aGuW/2RVff9kVn7/c2uK/4+SoP+otLb/vMvK/7fFx/+coq3/hoaa/3h0jv9tZYf/Z1qD/2NU + gP9jU4D/dW2P/5adqv+ms7b/oq2x/5KXpP98d5T/hYKd/6y2vv+7y8r/r8HA/6u+vf+wxcP/qLy7/4+i + pP9rdIf/Qjho/0tCcP+Dj53/j6Cl/2pxhf9LR23/NyZi/y4VW/8uFVr/MTN6/zVtuP82j9v/NpTf/zV1 + v/8yNn//MRZe/zEYYP8xGmL/MRpj/zIaY/8yGmT/Mxpl/3pkpf96ZKX/emSl/3pkpf96ZKX/emOk/3pi + pP94ebf/dKbd/3K36/9yqt7/b4/A/2prlP9mV37/Zld+/3Rsi/+Pk6D/oq6x/6q5uv+fqbH/goCY/3Fn + if9tYYb/al2E/2dZg/9mVoL/ZVaC/3JojP+Ljp//n6qv/6u5uv+eprH/fHaV/3x2lf+fprH/sL6//6u6 + u/+svb3/scbE/6G0tv98iJP/XGB3/0dCaP9aW3r/kaSr/5Onrf9fYH//PjFk/zMfXv8vF1v/LxZb/zEx + d/81ZK7/N4nU/zaa5P81fsf/MzqC/zEXXv8yGGD/Mhti/zIbY/8zG2P/Mxtk/zQbZP98Zqf/fGan/3xm + p/98Zqf/fGan/3xlpv98Zab/en27/3Wt4/9zu+7/c6XY/3CJuP9rapP/aFl//2dZf/91bov/jpSh/56r + rv+grrD/kpml/3Zvjf9qXYP/b2SH/3Nri/92bo7/d3CP/3hwkf+AfZf/kJak/6OwtP+2yMb/rLvA/4qL + ov+Bfpn/lJmm/6Grsf+ls7b/qrq7/62/v/+bqq//dn2N/2Bkev9eYnr/bnqL/46kqP+ElaH/Ukx2/zUi + Xv8xG13/MBhc/zAYXP8yLnT/NVqk/zeCzP82n+j/NYfP/zM+hf8yGF//Mhlg/zIbYv8zG2P/NBtj/zQb + ZP80G2T/fmio/35oqP9+aKj/fmio/35oqP9+Z6j/fmip/3uCv/92s+j/c77v/3Oh0f9xg7D/bGmR/2lb + gP9pW4H/dm+M/46Uof+cqq3/n62v/5KZpP94co//cWiJ/359k/+JjJz/j5Wh/5Obpv+Wn6n/nKav/6Sz + t/+ww8T/wNbT/7zRz/+lsrn/lJuo/42QoP+RlqP/n62x/6a3uP+ktLX/lqKp/36Dk/94f5D/hZee/4ad + oP96j5X/Y2uC/0I2af8xGlz/MBlc/zEZXP8xGFz/Mitw/zZQmv83ecT/NqLq/zWO1v8zQor/Mxpi/zMa + Yf8zG2L/Mxxj/zQcY/81HGT/NRxl/4Bqqv+Aaqr/gGqq/4Bqqv+Aaqr/gGqq/39srP99h8P/d7fr/3W/ + 7/90ncz/cn+r/25pkP9rXYL/a12C/3dwjf+OlKH/nayv/6O0tf+dqbD/jI+i/4iKnv+Sm6X/mqeq/52s + rf+gr7D/orGy/6S0tf+nt7n/rb/A/7bKyv+2ysr/rb/A/6KwtP+Wn6r/l6Cr/6Ozt/+pvLv/pre4/56s + sP+TnKj/laOs/6S9u/+XsLD/bnqK/05Lb/84KGH/Lxdb/zAYXP8xGVz/MRlc/zMobv82SJL/N3O+/zai + 6v81k9r/NEiP/zQeZv8zG2L/Mxti/zQcY/81HGT/NRxl/zUcZf+CbKv/gmyr/4Jsq/+CbKv/gmyr/4Jt + rP+Bca//f4zG/3m57P92v+3/dpzJ/3N+qf9vao//bV+D/21fg/94cY7/jZWh/5+wsv+swcD/sMbG/63A + w/+qvL//p7q6/6S1tf+gr7D/nKqt/5qmq/+Yo6n/l6Kp/5eiqv+ZpKz/nKmw/6KxtP+oubv/rsLD/7HG + x/+wxcX/sMXE/7HHxP+xxsX/sMTG/7PJyf+40s7/n7K4/2tpiv9HOGv/NyJf/zAYW/8wGVv/MRlc/zEZ + XP8zJ2z/NkSN/zdvuP82ouj/Npbb/zVOlf81JGv/NB1k/zQbYv80HGL/NRxk/zYcZf82HGX/hG6t/4Ru + rf+Ebq3/hG6t/4Rurf+Eb67/g3Wy/4CPyP97u+z/eL/s/3ebyP91faf/cWuQ/25hhP9uYYX/eXKP/46V + of+gsrP/r8bE/7XNy/+wxsb/qry//6Kwtv+bpq7/lZyn/5CVov+MkJ//ioyd/4iJm/+Ghpn/hISY/4eK + nP+Rl6X/naix/6q7wP+uwcX/qry//6m7vf+rvr//rcDC/7DBxf+1ysz/vNXT/6W1v/9yapH/UTxz/0Mu + af86JGP/NB1e/zEZXP8yGVz/NCdr/zdCiv84bbX/N6Hm/zaY3P82Upn/Nihv/zUfZf81HGL/NRxj/zYc + ZP82HGX/Nxxl/4Zvrv+Gb67/hm+u/4Zvrv+Gb67/hnGw/4V3tf+Ckcr/fbzt/3rA7P95m8f/dn6n/3Js + kf9wYob/cGKG/3p0j/+OlaH/n7Gy/6zDwf+pvb//lqCs/4qMn/+EgZr/gHqW/353lP99dZP/fHOS/3ty + kf97cZH/enCR/3lvkf96cZL/fXaV/4N9mv+KiKH/j5Km/5GYp/+TnKj/lJyo/5OZp/+RlKf/nKW0/7LI + yv+pusP/gnud/2hVhv9dSn7/Tztz/zwmZP8zGlz/Mxlc/zUma/84QYn/OGy0/zeh5v82md3/N1Sb/zcq + cf82H2b/Nhti/zYcY/83HGT/Nx1l/zgdZf+IcbD/iHGw/4hxsP+Ica//iHCv/4hzsf+Hebf/hJPM/36+ + 7f97wOz/epvG/3h+p/90bZL/cWSH/3Jkh/97dZD/jpah/52vsP+mu7r/na2z/4WGmv93bYz/dGaK/3Jj + iv9zY4r/c2SL/3Nki/90Zoz/dmiN/3dqjv93ao//dmmP/3Vnjv91aI7/eGuQ/3xzk/+BfZf/g4GZ/4OA + mf+BfZf/f3qW/46Rpv+swcX/q73E/4qFpP91ZJH/b12M/2JPgv9NOHL/Pydm/zceYP81Jmv/OECI/zhr + s/83oeX/N5rd/zhVnP84K3P/NyBn/zYcY/83HGP/Nxxk/zgdZf84HWX/inKx/4pysf+KcrH/inKw/4py + sP+KdbP/iXy5/4WWzf+Av+7/fMHs/3ubxv95fqf/dm6S/3NmiP9zZYn/fXaS/4+Xov+aq63/nrKx/5Wh + qf+Ae5X/dWeL/3Rli/90ZYv/dGWL/3RljP90Zoz/dmmN/3pvj/98c5H/fXWS/3t0kv94bpH/d2qQ/3dp + kP94apH/em6S/3tvk/98b5T/fHGU/312lf+Nkqb/q8HE/6q9w/+KhqT/eWiT/3dmkv9yYI7/ZlSF/1ZB + eP9BKGf/Nydr/zg/hv85abH/N6Hl/zea3v85V57/OSx1/zchaP83HGP/Nxxj/zgdZP84HWX/OB1m/4x0 + sf+MdLH/jHSx/4xzsf+Mc7H/i3e0/4p+uv+HmM//gcDu/37B6/98m8b/en+n/3dvk/91Z4n/dWeK/354 + kv+Pl6L/mKqr/5qtrf+Snqb/g4GX/3x0kv9/eZX/gn6Z/4SBnP+Fg57/hoWe/4eJoP+LjaH/jZGj/42S + o/+MkaP/io2j/4iJo/+HhqL/h4Og/4WBn/+Efpz/gnqa/4B5mP+AfJj/j5an/6rCw/+ovML/ioak/3pq + lf97a5b/e2qV/3dlkv9pVob/Uz11/0Q2df8+Q4n/Ommw/zih5P84m9//OVig/zkudv84IWj/Nxxj/zgd + Y/84HWT/OB1l/zgdZv+NdbL/jXWy/411sv+NdbL/jXWy/414tf+Lgbz/iJrQ/4LB7/9/wuv/fZzE/3t/ + pv94cJP/dmiK/3Zoiv9+eZP/jpii/5eqq/+Zrq7/laWq/4yUoP+LkZ//kp2o/5qpsf+gsrn/pLm+/6a8 + wP+mvsD/p73A/6a9v/+lvL7/pr2+/6a+wP+mvsH/pbzB/6O4vv+gsrr/mqqz/5Ofqf+NlKL/iIyd/5Kd + qf+pw8P/przB/4qHpP97a5X/fGyW/31tl/99bJb/d2WR/2xZif9dUYj/S06P/z5qr/85oeT/N5zf/zla + ov86MHj/OCJp/zgcYv84HWP/OB1l/zkdZv86Hmb/j3e0/493tP+Pd7T/j3e0/493tP+Perf/jYO9/4mc + 0f+Ew+//gMPr/3+cxP98gKX/eXGT/3hqi/94aov/gHqT/46Yov+Zra7/nra1/520tP+WqKv/laWq/5qu + sP+ftbb/o7u9/6a+wf+ov8L/qL7B/6e7wP+mub7/pbm9/6W6vv+nvcD/qL/C/6e/wv+mvsD/pLy9/6C3 + t/+ar7D/lqer/5Oiqf+brrP/qsjF/6W7wf+LiKX/fW2W/35ul/9/b5j/gG+Z/39umP98a5X/cWWV/15f + mf9NdrX/P6bl/zmd3/86XKP/OjF6/zkjaf84HGL/OB1j/zoeZ/8+H2v/PyBu/5J5tv+Sebb/knm2/5J5 + tv+Sebb/kXy5/4+Gv/+LntP/hsTw/4LD6/+BnMP/foGl/3tzlP96bIz/emyN/4F7lP+OmKL/nLGy/6jF + wv+pyMT/oLq5/5musP+Vp6r/kqCn/4+Zpv+Nk6X/jIyj/4yJov+MiKL/jIii/4uIof+LiKL/jImj/42L + pP+OjqX/j5Sm/5KdqP+Uo6r/lqis/5qvsv+hurv/qMbD/67Qyv+ku8D/jIml/4Bvl/+AcJj/gXGa/4Fx + mv+BcZr/gXCZ/35xnf93dab/ZovB/0yu6f89nt//PF6k/zszfP85I2r/ORxi/zodZP8+IGv/RSN3/0gl + ff+Ue7f/lHu3/5R7t/+Ue7f/lHu3/5N/uv+RiMH/jaDU/4fF8P+Ew+r/gpzD/4CBpf99dZX/e26O/3xu + jv+CfJX/jpii/5uysv+pycT/qcjG/52xtv+ToKn/jZWh/4eLm/+DgZj/gHiV/35wkv9+bZH/fm6S/35u + k/9+bpP/fm6T/35ulP9/cJX/gHOW/4J6mP+GhJv/io6f/4+Wpf+WpK7/oLe6/6jHw/+sz8n/o7q//42J + pf+CcJn/gnGa/4Nzm/+Dc5v/g3Ob/4Rym/+Ed6H/hYGt/3iYyP9etuv/TKTg/0Jipv88Nn3/OiRq/zsd + ZP8+IGr/RCN0/0smgP9OKIb/lX24/5V9uP+Vfbj/lX24/5V9t/+Ugbv/korC/4+j1f+JxvH/hcPq/4Oc + wv+BgaX/fnWW/31vj/99b4//gn2W/42Yof+Yr67/ob+8/561uP+OkaT/hH6Y/4N7lv+CeZX/gXaU/4Bz + lP+AcZP/f3CT/4BwlP+AcZT/gHGU/4Bxlf+AcJX/gHGW/4Fyl/+CdZj/g3iZ/4V7mv+GfZz/ioig/5Gc + p/+asrP/psfC/6G5vf+Niqb/g3Ka/4Rzm/+EdJz/hHSc/4R0nP+FdJz/hnmi/4eDrv+CnMj/d7/s/2Wu + 4v9Oaan/QDqA/zwmbP8+H2n/RiN2/0wngf9PKYf/USmK/5d/uf+Xf7n/l3+5/5d+uP+Xfrj/loO8/5SN + xP+Qpdf/isfx/4bE6v+FncL/g4Gl/4B1lv9+cI//fnCQ/4J7lf+KkJ3/k6Wp/5y3tf+asbT/jZKk/4WB + mv+Ef5n/hH6Y/4N8l/+Depb/gnmW/4J3lv+CdpX/gnWW/4J1lv+DdZf/g3aY/4N4mP+EeZn/hHua/4V9 + mv+Gf5z/h4Ge/4qLof+QnKf/l66v/5+9uv+bsLb/jIik/4Rzm/+FdJv/hnWc/4Z1nP+GdZz/hnSc/4d5 + ov+Iha//iJ/J/4XF7f93uOX/YHqz/09KjP9FLnb/RCNy/0wmgP9RKYn/UiqL/1MqjP+YgLr/mIC6/5iA + uv+YgLr/mIC6/5eEvf+Vj8X/kabY/4vI8f+Ixuv/h6DE/4SEp/+Bd5f/gHGP/4BxkP+Bd5P/hYGX/42V + ov+ZsbL/nry5/5u0tf+Wqq//kKCo/4uXov+KkJ7/iIqb/4aGmf+Egpj/hH6X/4N7l/+Depj/hHuZ/4V/ + mv+Hgpv/iIad/4mLnv+LkqD/jpmk/5Ghqv+WrLH/nbq6/568uv+YsbH/kZ2o/4mDoP+Gdpz/h3ad/4d3 + nf+Hdp3/h3ac/4d1nP+Ie6P/ioex/4uiy/+Jx+3/g8Lr/3mSw/9qZKH/Vj2J/04pgf9RKYj/UyqM/1Mr + jP9UK43/moK8/5qCvP+agrz/moK8/5qCu/+Zhb7/mI7F/5Ol1v+NyPD/icvw/4mw1P+Hmr3/hoyt/4SD + pP+EgKH/hH6e/4V/nP+KiqD/k6Cq/5qwsf+ct7X/mrez/5Wvrf+SqKn/kaOn/5Cfpv+OnKX/jpmk/42W + pP+NlKT/jZOl/46Upf+Ol6b/j5qn/5Ccp/+RoKj/kqWo/5Oqqv+Wr67/mrW0/5+5uv+csbb/kp2o/4uM + oP+Jfp7/iHie/4l7ov+KfqX/ioGo/4qEq/+Kh67/i4+2/4ycxP+Msdn/i8zx/4vG7f+Kn83/gHex/21S + nf9fOpL/WC+O/1Qrjf9VK43/VSuO/5yEvf+chL3/nIS9/5yEvf+chL3/nIa//5qMw/+WodP/j8Xt/4vT + 9/+LzO//jMDk/4yz1/+Mp8z/i5zB/4qTt/+Ji63/iYem/4uHoP+Nj6D/kJyk/5KlqP+Uqqr/la6t/5ez + sv+Zt7X/m7m4/527uv+evLv/n728/5+9vf+evLz/nby7/527uv+cubn/mre2/5izsf+Wr67/lKur/5Sk + qf+Tmaj/kY+l/42FoP+Lfp7/i3ue/4t9o/+NhKz/joy1/4+Vvv+Pn8f/jqnR/4602/+Nweb/jMzw/4zU + +P+Pxez/lKDQ/5KCu/+Hba//dlSj/2E4lf9WK47/ViuO/1Ysj/+ehr//noa//56Gv/+ehr7/noa+/56H + v/+dicH/mpnM/5S14f+Rx+7/kM3z/5DN8v+Rxu3/kL/l/4+33f+OrtP/jaXJ/4ucvv+Jk7T/iZSw/4uf + sv+Pp7b/kq65/5a0vf+ZusH/m77F/57Bx/+gxMn/ocbK/6LHyv+ixsr/ocbJ/6DEx/+fwsb/nsDF/5y8 + wv+Ytr7/lbG6/5Ortv+RorP/jpax/42Qsf+MjrL/jI+0/42Stv+Nl7z/jp7F/4+nzv+QsNf/kLjf/5DA + 5/+Qx+7/kM3z/5DO8/+Rx+7/lbbh/5uazf+ciMD/mH67/4lpsP9vSZ//XzWU/1kukP9XK4//oIfA/6CH + wP+gh8D/oIe//6CHv/+gh8D/oIjA/56OxP+cms3/mabW/5ez4P+Vvef/k8Pr/5HJ7v+QzPD/j83v/47K + 7P+Oxuj/jcLk/43A4f+PwN//kL/c/5K92v+Tu9j/lLjV/5W20/+WtdL/l7XR/5e00P+Xs87/l7HN/5ew + zP+XsMv/lrDM/5awzf+VsM3/lLDO/5Owzv+Ssc7/kbHQ/5Gx0/+Qs9f/j7fb/4+73/+PwOP/j8Tm/4/H + 6v+Pyu3/j83w/5DN8f+RyvD/ksXt/5S+6P+WtOD/mafX/5yazf+fj8X/oIjA/5+Gv/+Vebj/gmGs/3BK + n/9fNZT/VyuP/6KJwf+iicH/oonB/6KJwf+iicH/oonA/6KIwP+iicH/oYzC/5+Sx/+dntD/m6nY/5iz + 3/+WvOb/lcXs/5TK8P+TzfL/k8/z/5PQ9f+Tz/T/k83y/5PK7/+Sxu3/ksPp/5K/5v+SvOP/kbrg/5G5 + 3/+Rt97/kbbc/5G02v+Rs9r/kbPa/5G02/+Rttz/kbje/5G54P+Su+H/kr3j/5LA5v+TxOn/k8ft/5PK + 7/+TzfL/k8/0/5PQ9P+Sz/P/k83y/5PK8P+Uxez/lr3n/5e14f+aq9n/nZ/R/5+TyP+hi8P/oonB/6KJ + wf+jisH/noO+/5N2t/+BX6v/akKb/14zk/+jisL/o4rC/6OKwv+jisL/o4rC/6OKwf+jisH/o4rB/6OL + wv+jjcP/opHG/6GUyf+gmMv/n5zO/56h0v+dp9f/m6/c/5q14f+ZuuX/mL7o/5fC6v+Vxez/lMnv/5TL + 8P+TzPH/k83x/5LO8f+Rz/L/kdDy/5HQ8v+Rz/L/kc/x/5HP8f+Rz/L/kdDy/5HQ8v+Rz/L/ks/y/5PO + 8v+TzPH/lMvw/5XJ7v+Wxuz/l8Lp/5i+5/+ZueT/mrXg/5uv3P+cp9f/nqHS/5+cz/+gmMz/oZXJ/6KR + xv+jjcP/o4vC/6OKwv+jisL/pIvC/6OJwf+ghr//kXO1/3lUpv9tRJ7/pIvC/KSLwv2ljML+pYzC/6WM + wv+ljML/pYzC/6WMwv+ljML/pYvC/6WLwv+li8L/pYrB/6WLwv+kjsT/o5PH/6Gazf+goNH/n6XV/56q + 2f+cr9z/m7Xg/5q65P+Zvuf/mcHp/5jD6/+Xxez/l8ft/5fI7v+Xye//l8nv/5fK8P+XyvD/l8rv/5fJ + 7/+XyO7/l8ft/5fF7P+Yw+v/mcHp/5m95v+aueP/nLXf/52v3P+eqtj/n6XV/6Cg0f+hms3/o5PH/6SO + xP+li8L/pYrB/6WLwv+li8L/pYvC/6WMwv+ljML/pYzC/6WMwv+ljcP/po3D/5yBvf6KarH9gV2r/KSK + wvWli8L4po3D/aaNxP+mjcP/po3D/6aNw/+mjcP/po3D/6aNw/+mjcP/po3D/6aMw/+mjcP/po3E/6aP + xf+lkcb/pZPI/6SVyf+kl8r/pJjL/6Oazf+jnM7/o53P/6Ke0P+in9H/oqDR/6Kg0f+iodL/oqLT/6Gj + 1P+hpNT/oaTU/6Gj1P+iotL/oqHS/6Kg0f+ioNH/op/R/6Ke0P+jnc//o5zO/6Oazf+kmMv/pJbK/6SV + yf+lk8j/pZHG/6aPxf+mjcT/po3D/6aMw/+mjcP/po3D/6aNw/+mjcP/po3D/6aNw/+mjcP/p47E/6eO + xP+jisL9nYG++Jl8u/WjicLnpYrD7qeNxPmoj8X/qI/F/6iPxf+oj8X/qI/F/6iPxf+oj8X/qI/F/6iP + xf+oj8X/qI/F/6iPxf+ojsX/qI7E/6iOxP+ojsT/qI7E/6iOxP+ojcT/qI3E/6iNxP+ojcT/qI3D/6iN + w/+ojcT/qI3E/6iNxf+oj8X/qJDG/6iQxv+oj8X/qI7E/6iNw/+ojcP/qI3D/6iNxP+ojcT/qI3E/6iN + xP+ojcT/qI7E/6iOxP+ojsT/qI7E/6iOxP+ojsX/qI/F/6iPxf+oj8X/qI/F/6iPxf+oj8X/qI/F/6iP + xf+oj8X/qI/F/6iPxf+oj8X/qI7F+aeOxO6njcTooobB0aSJw92ojsX0qpDG/6qQxv+qkMb/qpDG/6qQ + xv+qkMb/qpDG/6qQxv+qkMb/qpDG/6qQxv+qkMb/qpDG/6qQxv+qkMb/qpDG/6qQxv+qkMb/qo/G/6qP + xv+qj8b/qo/G/6qPxf+qj8X/qo/G/6qPxv+qj8b/qpDG/6qQxv+qkMb/qpDG/6qPxv+qj8X/qo/F/6qP + xf+qj8X/qo/G/6qPxv+qj8b/qo/G/6qQxv+qkMb/qpDG/6qQxv+qkMb/qpDG/6qQxv+qkMb/qpDG/6qQ + xv+qkMb/qpDG/6qQxv+qkMb/qpDG/6qQxv+qkMb/qpDG/6mQxvSoj8Xep47F0qCEwJukiMO1qY/G56uS + x/+sksj/rJLI/6ySyP+sksj/rJLI/6ySyP+sksj/rJLI/6ySyP+sksj/rJLI/6ySyP+sksj/rJLI/6yS + yP+sksj/rJLI/6ySyP+sksj/rJLI/6ySyP+sksj/rJLI/6ySyP+sksj/rJLH/6ySx/+sksf/rJLH/6yS + x/+sksj/rJLI/6ySyP+sksj/rJLI/6ySyP+sksj/rJLI/6ySyP+sksj/rJLI/6ySyP+sksj/rJLI/6yS + yP+sksj/rJLI/6ySyP+sksj/rJLI/6ySyP+sksj/rJLI/6ySyP+sksj/rJLI/6ySyP+rksfoqZDGuKiP + xp+af75Jo4nDeKqQxtCsksj/rZPI/62Uyf+tk8n/rZPJ/62Tyf+tk8n/rZPJ/62Tyf+tk8n/rZPJ/62T + yf+tk8n/rZPJ/62Tyf+tk8n/rZPJ/62Tyf+tk8n/rZPJ/62Tyf+tk8n/rZPJ/62Tyf+tk8n/rZPJ/62T + yP+tk8j/rZPI/62TyP+tk8j/rZPJ/62Tyf+tk8n/rZPJ/62Tyf+tk8n/rZPJ/62Tyf+tk8n/rZPJ/62T + yf+tk8n/rZPJ/62Tyf+tk8n/rZPJ/62Tyf+tk8n/rZPJ/62Tyf+tk8n/rZPJ/62TyP+tk8n/rZPJ/66U + yf+ulMn/rpXJ062UyX2sk8hRjXW3FqKJwkKpj8aWq5DH0KyRyOetksj0rpTJ+q6Uyf2vlcn+r5XK/6+V + yv+vlcr/r5XK/6+Vyv+vlcr/r5XK/6+Vyv+vlcr/r5XK/6+Vyv+vlcr/r5XK/6+Vyv+vlcr/r5XK/6+V + yv+vlcr/r5XK/6+Vyv+vlcr/r5XK/6+Vyv+vlcr/r5XK/6+Vyv+vlcr/r5XK/6+Vyv+vlcr/r5XK/6+V + yv+vlcr/r5XK/6+Vyv+vlcr/r5XK/6+Vyv+vlcr/r5XK/6+Vyv+vlcr/r5XK/6+Vyv+vlcr/r5XK/6+V + yv6vlcr9r5XK+q6UyfWulMnpr5XK07CWypuxmMtItpvNHYZvswWehcAZoonCQqaKxHiojMa2q47H3q6S + yO6vlcn4sJbK/bCWy/+wlsv/sJbL/7CWy/+wlsv/sJbL/7CWy/+wlsv/sJbL/7CWy/+wlsv/sJbL/7CW + y/+wlsv/sJbL/7CWy/+wlsv/sJbL/7CWy/+wlsv/sJbL/7CWy/+wlsv/sJbL/7CWy/+wlsv/sJbL/7CW + y/+wlsv/sJbL/7CWy/+wlsv/sJbL/7CWy/+wlsv/sJbL/7CWy/+wlsv/sJbL/7CWy/+wlsv/sJbL/7CW + y/+wlsv/sJbL/7CWy/+wl8v9sJfL+bCWy/CvlMngrpTJurCVyn+yl8xIs5jMHbmfzweQd7gAhW+yBox0 + thaegsBKpYfEnKmMxtKtksjosJXK9rGXy/yxl8v/sZfL/7GXy/+xl8v/sZfL/7GXy/+xl8v/sZfL/7GX + y/+xl8v/sZfL/7GXy/+xl8v/sZfL/7GXy/+xl8v/sZfL/7GXy/+xl8v/sZfL/7GXy/+xl8v/sZfL/7GX + y/+xl8v/sZfL/7GXy/+xl8v/sZfL/7GXy/+xl8v/sZfL/7GXy/+xl8v/sZfL/7GXy/+xl8v/sZfL/7GX + y/+xl8v/sZfL/7GXy/+xl8v/sZfL/7GXy/+xl8v/sZfL/bGYzPewl8vqr5TJ1a6TyKKxlMpTtpbOHreX + zwi1ls4AgAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAE= + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/ProcessMon/ProcessUnitTest.cs b/Demo_Source_Code/CSharpDemo/ProcessMon/ProcessUnitTest.cs new file mode 100644 index 0000000..85fc9b4 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/ProcessMon/ProcessUnitTest.cs @@ -0,0 +1,363 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.IO; +using System.Collections.Generic; +using System.Threading; +using System.Text; +using System.Drawing; +using System.Windows.Forms; +using System.Runtime.InteropServices; +using Microsoft.Win32.SafeHandles; + +using EaseFilter.FilterControl; +using EaseFilter.CommonObjects; + +namespace ProcessMon +{ + static public class ProcessUnitTest + { + static FilterControl filterControl = new FilterControl(); + public static RichTextBox unitTestResult = new RichTextBox(); + public static bool newProcessCreationNotification = false; + public static bool monitorIONotification = false; + public static bool controlIONotification = false; + + static string lastError = string.Empty; + + static private void AppendUnitTestResult(string text, Color color) + { + if (color == Color.Black) + { + unitTestResult.AppendText(Environment.NewLine); + unitTestResult.SelectionFont = new Font("Arial", 12, FontStyle.Bold); + } + + unitTestResult.SelectionStart = unitTestResult.TextLength; + unitTestResult.SelectionLength = 0; + + unitTestResult.SelectionColor = color; + unitTestResult.AppendText(text + Environment.NewLine); + unitTestResult.SelectionColor = unitTestResult.ForeColor; + + if (color == Color.Black) + { + unitTestResult.AppendText(Environment.NewLine); + } + + + } + + private static void DenyNewProcessTest() + { + try + { + + // + //Process control flag test,deny new process creation. + // + uint controlFlag = (uint)FilterAPI.ProcessControlFlag.DENY_NEW_PROCESS_CREATION; + + //start new process should be fine + string processName = "cmd.exe"; + var proc = System.Diagnostics.Process.Start(processName); + proc.Kill(); + + ProcessFilter processFilter = new ProcessFilter(processName); + processFilter.ControlFlag = controlFlag; + + filterControl.ClearFilters(); + filterControl.AddFilter(processFilter); + filterControl.SendConfigSettingsToFilter(ref lastError); + + try + { + proc = System.Diagnostics.Process.Start(processName); + proc.Kill(); + AppendUnitTestResult("DENY_NEW_PROCESS_CREATION control flag test failed, denied process launch was failed.", Color.Red); + } + catch (Exception ex) + { + AppendUnitTestResult("DENY_NEW_PROCESS_CREATION control flag test passed.", Color.Green); + } + + } + catch (Exception ex) + { + AppendUnitTestResult("DENY_NEW_PROCESS_CREATION failed, return error:" + ex.Message, Color.Red); + } + finally + { + filterControl.ClearFilters(); + filterControl.SendConfigSettingsToFilter(ref lastError); + } + + } + + /// + /// Fires this event when the new process was being created. + /// + public static void OnProcessCreation(object sender, ProcessEventArgs e) + { + if (e.ImageFileName.IndexOf("cmd.exe") >= 0) + { + //this is our unit test file name. + newProcessCreationNotification = true; + } + } + + /// + /// Fires this event after the event was triggered. + /// + public static void OnProcessInfoNotification(object sender, ProcessEventArgs e) + { + //do your job here. + + } + + private static void NewProcessCallbackTest() + { + try + { + + // + //Process control flag test, new process creation notification. + // + string processName = "cmd.exe"; + ProcessFilter processFilter = new ProcessFilter(processName); + processFilter.ControlFlag = (uint)FilterAPI.ProcessControlFlag.PROCESS_CREATION_NOTIFICATION; + processFilter.OnProcessCreation += OnProcessCreation; + + filterControl.ClearFilters(); + filterControl.AddFilter(processFilter); + filterControl.SendConfigSettingsToFilter(ref lastError); + + try + { + //start new process should be fine + var proc = System.Diagnostics.Process.Start(processName); + proc.Kill(); + + } + catch (Exception ex) + { + AppendUnitTestResult("PROCESS_CREATION_NOTIFICATION failed," + ex.Message, Color.Red); + } + + } + catch (Exception ex) + { + AppendUnitTestResult("PROCESS_CREATION_NOTIFICATION failed," + ex.Message, Color.Red); + } + finally + { + filterControl.SendConfigSettingsToFilter(ref lastError); + } + + } + + + + + private static void ProcessFileControlTest() + { + + try + { + + // + //File access control test for process, to test block the new file creation for current process + // + + ProcessFilter processFilter = new ProcessFilter(""); + processFilter.ControlFlag = 0; + processFilter.ProcessId = FilterAPI.GetCurrentProcessId(); + uint accessFlag = FilterAPI.ALLOW_MAX_RIGHT_ACCESS & (uint)~FilterAPI.AccessFlag.ALLOW_OPEN_WITH_CREATE_OR_OVERWRITE_ACCESS; + processFilter.FileAccessRights.Add("*", accessFlag); + + filterControl.ClearFilters(); + filterControl.AddFilter(processFilter); + filterControl.SendConfigSettingsToFilter(ref lastError); + + string fileName = "test.txt"; + + try + { + File.AppendAllText(fileName, "This is test file content"); + AppendUnitTestResult("File access control test for current process failed, can't block the new creation.", Color.Red); + } + catch (Exception ex) + { + AppendUnitTestResult("File access control flag ALLOW_OPEN_WITH_CREATE_OR_OVERWRITE_ACCESS test for current process passed", Color.Green); + } + + } + catch (Exception ex) + { + AppendUnitTestResult("File access control test for current process failed," + ex.Message, Color.Red); + } + + + } + + /// + /// Fires this event after the new file was created, the handle is not closed. + /// + public static void OnPreCreateFile(object sender, FileCreateEventArgs e) + { + if (e.FileName.IndexOf("test.txt") > 0) + { + controlIONotification = true; + } + + } + + /// + /// Fires this event after the new file was created, the handle is not closed. + /// + public static void OnFileCreate(object sender, FileCreateEventArgs e) + { + if (e.FileName.IndexOf("test.txt") > 0) + { + monitorIONotification = true; + } + } + + + private static void ProcessFileIOCallbackTest() + { + try + { + ProcessFilter processFilter = new ProcessFilter(""); + processFilter.ControlFlag = 0; + processFilter.ProcessNameFilterMask = GlobalConfig.AssemblyName; + uint accessFlag = FilterAPI.ALLOW_MAX_RIGHT_ACCESS; + processFilter.FileAccessRights.Add("*", accessFlag); + processFilter.MonitorFileIOEventFilter = (ulong)(MonitorFileIOEvents.OnFileCreate); + processFilter.ControlFileIOEventFilter = (ulong)(ControlFileIOEvents.OnPreFileCreate); + + processFilter.OnPreCreateFile += OnPreCreateFile; + processFilter.OnNewFileCreate += OnFileCreate; + + filterControl.ClearFilters(); + filterControl.AddFilter(processFilter); + + if (!filterControl.SendConfigSettingsToFilter(ref lastError)) + { + AppendUnitTestResult("ProcessFileIOCallbackTest SendConfigSettingsToFilter failed:" + lastError, Color.Red); + return; + } + + // + //monitor and control IO callback notification test for current process + // + string fileName = GlobalConfig.AssemblyPath + "\\test.txt"; + + try + { + File.Delete(fileName); + File.AppendAllText(fileName, "This is test file content"); + + } + catch (Exception ex) + { + AppendUnitTestResult("Register monitor/control IO callback for current process failed." + ex.Message, Color.Red); + } + + } + catch (Exception ex) + { + AppendUnitTestResult("File access control test for current process failed," + ex.Message, Color.Red); + + } + finally + { + filterControl.SendConfigSettingsToFilter(ref lastError); + } + + } + + public static void GetUnitTestResult() + { + + Thread.Sleep(3000); + + if (newProcessCreationNotification) + { + AppendUnitTestResult("PROCESS_CREATION_NOTIFICATION control flag test passed.", Color.Green); + } + else + { + AppendUnitTestResult("PROCESS_CREATION_NOTIFICATION test failed, didn't receive the new process creation notification.", Color.Red); + } + + if (controlIONotification) + { + AppendUnitTestResult("Register control IO callback for current process test passed.", Color.Green); + } + else + { + AppendUnitTestResult("File control IO callback test failed, no monitor callback.", Color.Red); + } + + if (monitorIONotification) + { + AppendUnitTestResult("Register monitor IO callback for current process test passed.", Color.Green); + } + else + { + AppendUnitTestResult("File monitor IO callback test failed, no monitor callback.", Color.Red); + } + + + } + + public static void ProcessFilterUnitTest(RichTextBox richTextBox_TestResult, string licenseKey) + { + + string lastError = string.Empty; + string userName = Environment.UserDomainName + "\\" + Environment.UserName; + + unitTestResult = richTextBox_TestResult; + + + string message = "Process Filter Driver Unit Test."; + AppendUnitTestResult(message, Color.Black); + + if (!filterControl.StartFilter(GlobalConfig.filterType, GlobalConfig.FilterConnectionThreads, GlobalConfig.ConnectionTimeOut, licenseKey, ref lastError)) + { + MessageBox.Show(lastError, "StartFilter", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + Thread.Sleep(3000); + + DenyNewProcessTest(); + + NewProcessCallbackTest(); + + ProcessFileControlTest(); + + ProcessFileIOCallbackTest(); + + GetUnitTestResult(); + + filterControl.StopFilter(); + } + } +} diff --git a/Demo_Source_Code/CSharpDemo/ProcessMon/ProcessUnitTestForm.Designer.cs b/Demo_Source_Code/CSharpDemo/ProcessMon/ProcessUnitTestForm.Designer.cs new file mode 100644 index 0000000..e56152f --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/ProcessMon/ProcessUnitTestForm.Designer.cs @@ -0,0 +1,76 @@ +namespace ProcessMon +{ + partial class ProcessUnitTestForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ProcessUnitTestForm)); + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.richTextBox_TestResult = new System.Windows.Forms.RichTextBox(); + this.groupBox1.SuspendLayout(); + this.SuspendLayout(); + // + // groupBox1 + // + this.groupBox1.Controls.Add(this.richTextBox_TestResult); + this.groupBox1.Dock = System.Windows.Forms.DockStyle.Fill; + this.groupBox1.Location = new System.Drawing.Point(0, 0); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size(636, 408); + this.groupBox1.TabIndex = 0; + this.groupBox1.TabStop = false; + // + // richTextBox_TestResult + // + this.richTextBox_TestResult.Dock = System.Windows.Forms.DockStyle.Fill; + this.richTextBox_TestResult.Location = new System.Drawing.Point(3, 16); + this.richTextBox_TestResult.Name = "richTextBox_TestResult"; + this.richTextBox_TestResult.Size = new System.Drawing.Size(630, 389); + this.richTextBox_TestResult.TabIndex = 0; + this.richTextBox_TestResult.Text = ""; + // + // RegUnitTest + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(636, 408); + this.Controls.Add(this.groupBox1); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Name = "RegUnitTest"; + this.Text = "Process Filter Driver SDK Unit Test"; + this.Activated += new System.EventHandler(this.ProcessUnitTest_Activated); + this.groupBox1.ResumeLayout(false); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.GroupBox groupBox1; + private System.Windows.Forms.RichTextBox richTextBox_TestResult; + } +} \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/ProcessMon/ProcessUnitTestForm.cs b/Demo_Source_Code/CSharpDemo/ProcessMon/ProcessUnitTestForm.cs new file mode 100644 index 0000000..0a7fb52 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/ProcessMon/ProcessUnitTestForm.cs @@ -0,0 +1,69 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.IO; +using System.Diagnostics; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; +using Microsoft.Win32.SafeHandles; +using System.Security.AccessControl; +using System.Security.Principal; +using System.Threading; +using System.Threading.Tasks; + +using EaseFilter.FilterControl; +using EaseFilter.CommonObjects; + +namespace ProcessMon +{ + public partial class ProcessUnitTestForm : Form + { + + bool isUnitTestCompleted = false; + //Purchase a license key with the link: http://www.easefilter.com/Order.htm + //Email us to request a trial key: info@easefilter.com //free email is not accepted. + string licenseKey = "******************************************"; + + public ProcessUnitTestForm(string _licenseKey) + { + InitializeComponent(); + this.licenseKey = _licenseKey; + + } + + private void ProcessUnitTest_Activated(object sender, EventArgs e) + { + if (!isUnitTestCompleted) + { + isUnitTestCompleted = true; + + ProcessUnitTest.ProcessFilterUnitTest(richTextBox_TestResult,licenseKey); + GlobalConfig.Load(); + //System.Threading.Tasks.Task.Factory.StartNew(() => { ProcessUnitTest.ProcessFilterUnitTest(richTextBox_TestResult); }); + + } + + } + + } +} diff --git a/Demo_Source_Code/CSharpDemo/ProcessMon/ProcessUnitTestForm.resx b/Demo_Source_Code/CSharpDemo/ProcessMon/ProcessUnitTestForm.resx new file mode 100644 index 0000000..60985f5 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/ProcessMon/ProcessUnitTestForm.resx @@ -0,0 +1,570 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + AAABAAgAEBAAAAEACABoBQAAhgAAABAQAAABACAAaAQAAO4FAAAYGAAAAQAIAMgGAABWCgAAGBgAAAEA + IACICQAAHhEAACAgAAABAAgAqAgAAKYaAAAgIAAAAQAgAKgQAABOIwAAMDAAAAEACACoDgAA9jMAADAw + AAABACAAqCUAAJ5CAAAoAAAAEAAAACAAAAABAAgAAAAAAEABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP// + /wAygPwAvYp4AH/e/wD/3ZcAwMDAAHyX4QB2dXQA7trOAKCgoADhrooAjMXWAKHB/wCZhnMAvaySAP/3 + ywDxyIIA0tLSAJGQjQDMrqoA/9y4AK16cAD/8OEA0p+CAIqo3gD5xpYAhIJ9AOS8mACrq6sA3trEAPTd + qQD//+oA/+THAP/RhADEnIgA8tWYAP/npgD96NUAceH/APjouwA4jP8AxpN9AJmOgwCZl5QAqoF6AO26 + kAC1gnQA782QAIaHhwD/+vUAtKiXANmmhgD/1ZAAmLz/AMjBugD22qAAmpSLAP/uvQDQtLAA//bsAIuf + 3QDRzssA/+DAAPntwgCZiXoAfn5/AP/t2gD/584AOoX/APn5+QD+2Z0AnJycAHt5dQDguJUAsX5yAIam + 4gC5hnYAwY56APXClADxvpIA6baOAOWyjADdqogA///yAP7WmAD8/PwAqKioAJaPhwDw0JQA1tPPAJmM + fgDVooQAz8/PAMTBvgA2iP8A//jwAMmWfgD/69YA/+nSAJuSiADHnokAgYB/AI+OiwDCwsIA//37AP/+ + 7wD/7t0A/9qWAJmUjgCrqqgAd3d2ALOAcwC3hHUAmZCHANekhACFhYYA//v3AHt4cwCZi3wA/v7+APr6 + +gD+0IUAuod3AL6LeQDCj3sAxZJ8AJ2dnQDcqYcAw8C9AP/37wCAgIAAgoB+AK57cADV0s8AkpCNAMfB + ugAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAACNhfk4DTS9LFhQ9WIcAAGUJRkZ5VngBAQENRQRkAAAYAXJtLGhdARIZAicp + BwAAcwEXPGlXQgiDEwxfNjsAAIABcl5/DyJ6VTlnTAGFAAALAWsyhAUkMBFHMQEBcAAAUgErWnY6KB9Z + NW8SAXEAAFEBYmAbIGpAOGx0AXh7AAAuAXc3Ch5UECUzSAZWfAAAUAEhY4JuhElmHWl1eX0AAE8BDkFb + iGCGPoFtbUYqAAAaARU/IURiQ2sXFxdGYQAAHCYBAQEBAQEBAQEBCS0AAABKGk9QLlFSC1M0XC0AAAAA + AAAAAAAAAAAAAAAAAAD//wAAwAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAIAB + AACAAQAAgAEAAMADAAD//wAAKAAAABAAAAAgAAAAAQAgAAAAAABABAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAMuYf8zJln7/xZJ8/8GOev+9inj/uYZ2/7WCdP+xfnL/rXpw/8yuqv+Ln93/l5CI/Xdz + bH4AAAAAAAAAAM6bgMzu2s7/+fn5//n5+f/6+vr//Pz8//7+/v////////////////+hwf//OoX//3/e + //+dlIr+AAAAAAAAAADSn4L//////5mQh/+ZlI7/mZeU/8LCwv/Pz8///////9LS0v+KqN7/MoD8/3Hh + //84jP//fJfh/wAAAAAAAAAA16SE////////8OH///bs///9+/+oqKj/fn5//3Z1dP+AgID/kZCN/4zF + 1v82iP//mLz//9C0sP8AAAAAAAAAANyph///////mZCH/8TBvv+dnZ3/vayS///RhP/+0IX//taY/5qU + i/+Pjov/hqbi//////+ue3D/AAAAAAAAAADhror////////u3f//+vX/goB+///dl//y1Zj/782Q//HI + gv/+2Z3/hoeH////////////s4Bz/wAAAAAAAAAA5bKM//////+ZjoP/1tPP/3t4c///7r3/+Oi7//Td + qf/w0JT//9WQ/3d3dv/S0tL//////7eEdf8AAAAAAAAAAOm2jv///////+vW///48P+Egn3////q///+ + 7//57cL/9tqg///alv+FhYb///////7+/v+6h3f/AAAAAAAAAADtupD//////5mLfP/Iwbr/oKCg/97a + xP////L///fL///npv+0qJf/nJyc/8DAwP/8/Pz/vot5/wAAAAAAAAAA8b6S////////5Mf//+nS///3 + 7/+rqqj/goB+/3t5df+BgH//q6ur///9+///+/f/+vr6/8KPe/8AAAAAAAAAAPXClP//////mYZz/5mJ + ev+ZjH7/x8G6///48P/V0s//0c7L/8PAvf+ZlI7/mZSO//n5+f/Gk33/AAAAAAAAAAD5xpb////////c + uP//4MD//+TH///nzv//69b//+3a///u3f//8OH///Dh///w4f/5+fn/yZZ+/wAAAAAAAAAA88CTzP3o + 1f//////////////////////////////////////////////////////7trO/6p3bswAAAAAAAAAAAAA + AADuu5DM+caW//XClP/xvpL/7bqQ/+m2jv/lsoz/4a6K/92qiP/Zpob/1aKE/6p3bswAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAD//wAAwAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAMAD + AAD//wAAKAAAABgAAAAwAAAAAQAIAAAAAACgAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8AGVv/AK98 + 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 + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADJln6pyZZ+/8aTfP/EkXv/wY56/7+Mef+9inj/uod2/7iF + df+2g3T/s4Bz/7F+cv+vfHH/rHlv/6p3bv+odW3/qnp0/9TEyP+Jg3j/hICA+GNjYzgAAAAAAAAAAM6b + gKnZr5j/9eLU///27v//+vX///38//////////////////////////////////////////////////// + ////////9vf//wZF//9Oheb/5drP/357evkAAAAAAAAAANKfgv/24dD///Pn///27v//+vX///38//// + ///////////////////////////////////////////////////z9f//DEr//0ac//9k1///ZZ3p/4yH + gf8AAAAAAAAAANShg/////////Ll///17P+ZlZL/mZeW/5mZmf+ZmZn/mZmZ//////////////////// + //////////////Hz//8LSf//SaL//2/Z//9Xt///D1r//7+zv/8AAAAAAAAAANajhP////////Ll///0 + 6v//9/H///v4////////////////////////////+vr6//n5+f//////8fHw/4SCh/87jOH/bt3//1a0 + //8ZW///4+f//7KGgf8AAAAAAAAAANilhf////////Dj///06v+ZlI//mZaT/5mYl/+ZmZn/y8vL/7Oz + tf+ChYj/fXx5/358ev+ChIj/jo+Q/62qpf/Ax8L/QZrp/xRW///m6////////6l2bv8AAAAAAAAAANqn + hv///////+/g///z5///9ez///nz///8+v//////o6Wn/7Wrl//10JT/+9KT//vTmv/8153/wrWh/4CD + if/EwLv/goKQ/+nt/////////////6t4b/8AAAAAAAAAAN2qh////////+7e///w4/+Zkoz/mZSR/5yZ + lv/b29z/rKSS//zXmv/x0Zv/79CZ/+7Nkf/wz5f/+tef/7+znf+Ki4z/ysrI/////////////////657 + cP8AAAAAAAAAAOCtif///////+zZ///v4P//8+f///Xs///59f+UlJf/9Nii//Xdqv/x26r/8dup//DU + ov/v0Jf/8M6a//7ao/+PkZT//////////////////////7B9cf8AAAAAAAAAAOKviv///////+rX///u + 3v+ZkIj/mZKM/62ppf+AgH7//+i1//blvv/358D/9eK4//Pdsf/x1qX/8NCV//3apP+FhIL/2NjY//// + /////////////7J/cv8AAAAAAAAAAOSxi////////+nV///s2f//7+D///Ll///38P+Eg4L///PI//z1 + 3P/689b/9+zI//bnvf/z3K3/8NOe//7Zof+EhIP//////////////////////7WCdP8AAAAAAAAAAOaz + jP///////+fQ///q1/+ZjoT/mY+G/62nof+enp3/7+bF////8P/+/vz//Pbb//fsx//24bP/89ek//TY + pP+Rk5b//////////////////////7iFdf8AAAAAAAAAAOi1jv///////+XM///o0v//6tf//+7e///y + 5//z7OX/paOc////7P////f//fnl//nuzP/347b//+Gm/6Sdkv/b29z//////////////////////7qH + dv8AAAAAAAAAAOy5j////////+PJ///mzv+Zi37/mY6C/52Tif+tpp//vru5/6Khm//j3sL///zT///y + wv/p1av/oJuS/7Kztv+/v7//mZmZ/////////////////72KeP8AAAAAAAAAAO67kP///////+HF///j + yf//5s7//+nV///s2f//7+D///Pp//Lr5P+lpKT/gICD/4CCgv+ampz/5OPj///9/f////////////// + /////////////7+Mef8AAAAAAAAAAPC9kf///////9/A///hxf+ZiHn/mYt9///p1f+ZjoL/nZOJ/6ae + lv+tp6H/r6mk/62npP+jn53///nz/5mWk/+Zl5X/mZeW///9/P///fz///38/8GOev8AAAAAAAAAAPK/ + k////////928///fwP//4cX//+PJ///mzv//6NL//+rX///t3P//7+D///Dj///z5///9Or///Xs///2 + 7v//9/H///nz///69f//+vX///r1/8SRe/8AAAAAAAAAAPTBlP///////9u4///dvP+ZhnP/mYd2/5mI + ef+Zinz/mYt+///q1/+ZjoL/mY+F/5mPhv+ZkIj/mZKL/5mSjP+Zkoz/mZOO///27v//9u7///bu/8eU + ff8AAAAAAAAAAPbDlf///////9mz///buP//3bz//9/A///hxf//48n//+XM///n0P//6dX//+rX///s + 2f//7t7//+/g///w4///8uX///Ll///z5///8+f///Pn/8qXfv8AAAAAAAAAAPnGlv/+8eb//+7e///Z + s///27j//928///evv//4MP//+LH///lzP//5s7//+fQ///p1f//6tf//+zZ///t3P//7t7//+7e///v + 4P//7+D/9uDQ/8yZf/8AAAAAAAAAAPjFlj36ypz//vHm//////////////////////////////////// + ///////////////////////////////////////////////////338z/27KZ/8yZf6kAAAAAAAAAAAAA + AAD4xZY9+caW//fElf/1wpT/88CT//G+kv/vvJH/7bqQ/+q3j//otY7/5rOM/+Sxi//ir4r/4K2J/96r + iP/ap4b/2KWF/9ajhP/UoYP/0J2BqQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA////AMAAAwCAAAEAgAABAIAAAQCAAAEAgAABAIAAAQCAAAEAgAABAIAAAQCAAAEAgAABAIAA + AQCAAAEAgAABAIAAAQCAAAEAgAABAIAAAQCAAAEAwAABAOAAAwD///8AKAAAACAAAABAAAAAAQAIAAAA + AACABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8ANF/oAMCNeQBt2f8ATVNaAPvboQB5pLUAxsjQAEtw + qgBfiP8AeX6EAK6ppADksYsA+O/PAKBuagBNsfgAmZONADqL/wBkZ20A2cmkAN3d3QDi270AUG7oAMie + kADNtLUA8sqLAIqTpAA8b/8A7u3sAJmGdAD/3r4AW3KXAF/A/wC1t7gArqKNALB9cQD//N8A79vRAJ2d + nQDXpIQA69GeAIiKjgDu8f8AKnb/AOe9nwDEwr8A7tuwAL2yogD/9+8A4cKQALWRhQDx5cEAzZp/APvI + lwDW1NIA/+3cAPG+kgCJh4EAkZOXAP3rvAD/5MoAOmfxAOLRqgCZjIAA2byhAM/LxwDi2dIApKWpAMa2 + wwDhyZoAsKmYAPLVpwCodW0AVrT/AODm5ACysK8A9dKaAPb29gD39+cA99+rAIGEiQBYgP8A6uHYALeE + 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 + AAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPgAAAH//////////8oAAAAIAAAAEAAAAABACAAAAAAAIAQ + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAHVvWSSGhH3maWhndGJiYl6EhIQCAAAAAAAAAAAAAAAAAAAAALqHdrW2g3T/tYJz/7SB + c/+zgHL/sX5y/7B9cf+vfHH/rntw/616cP+seW//q3hv/6l2bv+odW3/p3Rt/6ZzbP+lcmz/pHFr/6Nw + a/+hbmr/oG1p/6Bua//NtLX/UG7o/4qTpP/Nx8L/iIiH/2NjY2kAAAAAAAAAAAAAAAC6h3a1yJ6Q/+/b + 0f//+PL///v3///+/f////////////////////////////////////////////////////////////// + /////////////////////////Pz//1+I//8qdv//S63//+Dm5P/Py8f/aGhoeQAAAAAAAAAAAAAAAL6L + eP/v2s7///Xs///48v//+/f///79//////////////////////////////////////////////////// + //////////////////////////////v7//9bhv//Lnn//1a0//9o1f//W73//66urv+MioTTAAAAAAAA + AAAAAAAAwI15///+/v//9ez///jy///79////fv///////////////////////////////////////// + ///////////////////////////////////6+///WID//y97//9Zt///bNb//1/A//87j///Omfx/4V/ + clcAAAAAAAAAAAAAAADDkHr////////06v//9/D/mZaT/5mYl/+ZmZn/mZmZ//////+ZmZn/mZmZ/5mZ + mf+ZmZn/mZmZ/5mZmf+ZmZn/mZmZ////////////7u3s/1Bw8f8wevz/Wrn//2zW//9ev///Po7//zxv + ///GtsP/AAAAAAAAAAAAAAAAAAAAAMaTfP////////Pp///27v+ZlZL/mZeV/5mZmf+ZmZn//////5mZ + mf+ZmZn/nZ2d/7W1tf/FxcX/zMzM/8vLy//ExMT///////r6+v+Xk4r/W3KX/0qr9P9t2f//Xb7//z2N + //9AcP//7vH//65/ef8AAAAAAAAAAAAAAAAAAAAAyZZ9////////8+n///bu///48v//+/f///79//// + ///////////////////29vb/tbe4/4qMkf+EiJD/hIiP/4GEif+vsLH/6Ojo/46Ojf/i2dL/eaS1/02x + +P86i///RHP///Dz////////qndu/wAAAAAAAAAAAAAAAAAAAADKl37////////y5///9ez/mZWR/5mW + k/+ZmJf/mZmZ/5mZmf+0tLT/vL29/3Z7gv+yp5L/5ceW//HJjP/1zJH/8c+f/72yov9NU1n/kJCS/+7t + 7P/q4dj/S3Cq/zRf6P/y9P////////////+seW//AAAAAAAAAAAAAAAAAAAAAMyZf/////////Ll///0 + 6v+ZlJD/mZWS/5mXlf+ZmZn/qqqq/7+/wP+Agob/4cKQ//LKiv/syI7/6saP//DQnf/v06P/8MeK/+/O + mv9kZ23/mpuc/5OSkf+emYz/xsjQ/////////////////698cf8AAAAAAAAAAAAAAAAAAAAAz5yA//// + ////8eP///Pp///17P//+PL///v3///+/f/5+fn/h4uP/+bJmv/105n/79Ca/+/Qmf/vz5j/7s2Q/+7I + i//y06T/9NWg//LQn/9NUlr/3d3d/+jo6P//////////////////////sn9y/wAAAAAAAAAAAAAAAAAA + AADRnoH////////w4f//8uf/mZKM/5mUkP+ZlpP/srCv/8nKy/+uoo3/9NOc/+vQnv/q0p7/8dam//HV + ov/w057/79CY/+7Kjf/y1Kf/9dCR/7Ornf/CwsP///////////////////////////+0gXP/AAAAAAAA + AAAAAAAAAAAAANShg////////+/g///x4/+Zkoz/mZSP/5mVkf/DwsD/o6Wp/9nFmv/u16X/7Nep/+zX + qv/z3bD/89yt//Hbqf/w1KH/79Ca/+7Mj//227H/79Gj/5CSlv///////////////////////////7eE + dP8AAAAAAAAAAAAAAAAAAAAA16SE////////7dz///Dh///y5///9Or///fw///8+v+Qk5f/99+r//fm + vf/25r7/9unF//bnwP/35Ln/89+x//Hbqf/w1KH/78+V//LWqP/205r/jJCV//////////////////// + ////////uod2/wAAAAAAAAAAAAAAAAAAAADap4b////////s2v//7+D/mZGI/5mSjP+Zk47/zMrI/46Q + lv/13a7/+e7M//Xrz//06cr/8ufF//Divf/v3LP/7Niq//Hbqf/pzJb/7dGg//XRm/+EiI3/yMjI/5mZ + mf////////////////+9inf/AAAAAAAAAAAAAAAAAAAAANyph////////+rW///t3P+ZkIf/mZGJ/5mS + jP/Ewb7/pKWo/9nJpP//9tz/9/HY//f25//38Nv/9OnH//Hlwf/u27D/8tus/+nOmv/v0qD/582g/4mK + jv+/v7//mZmZ/////////////////7+MeP8AAAAAAAAAAAAAAAAAAAAA3quI////////6dX//+vY///u + 3v//8OH///Ln///37//a2dj/sKmY///83//+/fH//v36//7+8//89Nb/+O/P//bku//z3a//8dak//vb + of+roZL/x8jJ////////////////////////////wo96/wAAAAAAAAAAAAAAAAAAAADhror////////n + 0f//6tb/mY6D/5mPhv+ZkYj///Lo/9DNy/+hoKP/4tu9//r65f/7+/L/9/fn//Xw1//47sz/7961/+zX + qf/w157/4cma/3l+hP/7+/v////////////////////////////Fknv/AAAAAAAAAAAAAAAAAAAAAOOw + i////////+bP///o0/+ZjID/mY6E/5mPhv//8uX/q6ah/9bU0v+bm5r/5d7D//n54//69+P/9vDV//ru + yf/z4LL/992o/+DInf+AgYT/wMDA/////////////////////////////////8eUfP8AAAAAAAAAAAAA + AAAAAAAA5rOM////////5cz//+bP///p1f//69j//+3c///w4f//8uX///bv//Pw7v+jo6b/sq2e/+PY + uP//8MP//eu8/+LRqv+wqJf/hYiM/+Dg4f//////////////////////////////////////ypd+/wAA + AAAAAAAAAAAAAAAAAADpto3////////jyP//5cz/mYt9/5mMgP+ZjYL/mY6E/5mQh/+ZkYn/rqmk/9DO + zP/T0dH/np6i/4iKjv+Ehoz/kpSY/6ipqv/Nzc3//////5mZmf+ZmZn/mZmZ/5mZmf////////////// + ///MmX//AAAAAAAAAAAAAAAAAAAAAOu4jv///////+HE///kyv+ZiXv/mYt9/5mMgP+ZjYL/mY6E/5mQ + h/+ZkYn/npaQ///38P/JxsT/0c/N/9HPzf/Ix8X/tbSz/52cnP//////mZmZ/5mZmf+ZmZn/mZmZ//// + /////////////82af/8AAAAAAAAAAAAAAAAAAAAA7bqQ////////38H//+LG///kyv//5c3//+fR///p + 1f//69j//+3c///v4P//8eP///Ln///06v//9ez///fw///48v//+vX///v3///8+f///fv///79//// + ////////////////////////0J2B/wAAAAAAAAAAAAAAAAAAAADwvZH////////dvf//4ML/mYh3/5mJ + ef+ZiXv/mYt9/5mMgP//69j/mY6E/5mPhv+ZkIf/mZGJ/5mSjP//9Or/mZSP/5mUkP+ZlZH/mZWS/5mW + k/+Zl5T/mZeV/5mYl////fv///79///+/f/ToIL/AAAAAAAAAAAAAAAAAAAAAPPAk////////9y5///e + v/+ZhnT/mYh3/5mJef+ZiXv/mYt9///p1f+ZjID/mY6D/5mPhf+ZkIf/mZGI///y5/+Zkoz/mZKM/5mT + jv+ZlJD/mZWR/5mVkf+ZlZL/mZaT///79///+/f///v3/9ajhP8AAAAAAAAAAAAAAAAAAAAA9cKU//// + ////5s3//9y5///ev///4ML//+LG///kyv//5cz//+bP///o0///6tb//+vY///t3P//7+D///Dh///x + 4///8uf///Pp///06v//9ez///bu///27v//9/D///jy///48v//+PL/2KWF/wAAAAAAAAAAAAAAAAAA + AAD4xZX////////48v//5s3//9y5///dvf//38H//+HE///jyP//5cz//+bP///n0f//6dX//+rW///s + 2v//7dz//+/g///w4f//8eP///Ll///y5///8+n///Pp///06v//9ez///Xs/+7a0f/bqIb/AAAAAAAA + AAAAAAAAAAAAAPvIl4/6x5b///////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////9+//u2s3/572f/7aD + dI8AAAAAAAAAAAAAAAAAAAAAAAAAAPvIl4/7yJf/+seW//nGlv/4xZX/98SV//XClP/0wZP/88CT//K/ + kv/xvpL/8L2R/+67kP/tupD/7LmP/+y5j//ruI7/6reO/+m2jf/ntIz/5rOM/+Wyi//ksYv/47CL/+Kv + iv+2g3SPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/////////j4AAAAcAAAAHAAAABwAAAAcAA + AAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AA + AAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAAD4AAAB///////////KAAAADAAAABgAAAAAQAIAAAA + AACACgAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8AIVXwAMGOeQBt2f8ATE1PAPvboQCLldIArb3/ADhm + uQBfiP8AeX6EAK2qpwDlsosA+/DSAKBuagBNsfgAmZWLADmJ/wBnaGkA2cmkAOLe2gDi270ATInRAMai + kQDNtLUA8sqLAHWCtQA8b/8A7+3rAIV7awD/3r4AW3KXAGHE/wCytL8AqaCNALB9cQD//eMA79vRAJ2d + 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 + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI6MgwJycm/BcnJyu2Rk + ZChmZmY0V1dXAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQ3 + +CN7e4P+sK+t/4CAgP6CgoL/bW1twmxsbAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADPnICj0J2B/9Cd + gf/QnYH/0J2B/9Cdgf/QnYH/0J2B/8+cgP/PnID/z5yA/86bgP/Om4D/zpuA/82af//Nmn//zJl//8yZ + f//MmX//yZZ9/8iVff/Gk3z/xJF7/8KPev/Bjnn/vot4/72KeP+7iHb/uYZ1/7aDdP+0gXP/s4By/7B9 + cf+4i4H/vKu//yJR9f80cer/q6in/+Hg3/+UlJT/hISE/2VlZUsAAAAAAAAAAAAAAAAAAAAAAAAAANKf + gszQnYH/7tS////04///9OT///Xl///15///9ej///bp///26v//9+v///fs///47f//+O7///nv///5 + 8P//+fL///rz///69P//+/X///v2///89////Pj///z5///9+v///fz///79///+/v////////////// + ///////////////////d4///KFn//ytz//9CmP//aLTo/+bh3//m5eT/goKC/mVlZUAAAAAAAAAAAAAA + AAAAAAAA06CCo9Gegf/24s7///Pi///04///9OT///Xl///15///9ej///bp///26v//9+v///fs///4 + 7f//+O7///nv///58P//+fL///rz///69P//+/X///v2///89////Pj///z5///9+v///fz///79///+ + /v///////////////////////////9vi//8nWv//LHX//0OZ//9dv///ZM7//3/G7v/Hwr7/s7Kx/nR0 + dHsAAAAAAAAAAAAAAAAAAAAA1KGD//Xl2P//+O3///Pi///04///9OT///Xl///15///9ej///bp///2 + 6v//9+v///fs///47f//+O7///nv///58P//+fL///rz///69P//+/X///v2///89////Pj///z5///9 + +v///fz///78///+/f//////////////////////2N///ydY//8tdv//RJn//17A//9nzv//Y8j//0yq + //9XitP/npmS/3l5edwAAAAAAAAAAAAAAAAAAAAA1aKD////////8+H///Pi/4V/dv+Ff3f/hYB3/4WA + eP+FgHn/hYB6/4WAev+FgXv/hYF7/4WBfP//+O7///nv/4WCff+Fgn7/hYJ+/4WCf/+Fg4D/hYOA/4WD + gf+Fg4H/hYOC/4WEgv+FhIP/hYSD/4WEhP+FhIT/hYWF/5iYmP+jq8z/H1P5/y53//9GnP//X8H//2fO + //9ix///T6n//zqL//8XW/7/QFi8g3Fway4AAAAAAAAAAAAAAAAAAAAA1qOE////////8+H///Pi/4V/ + dv+Ff3f/hX93/4WAeP+FgHj/hYB5/4WAev+FgXv/hYF7/4WBfP//+O7///jv/4WCff+Fgn7/hYJ+/4WC + f/+Fg4D/hYOA/4WDgP+Fg4H/hYOC/4WEgv+FhIP/hYSD/4WEhP+Lior/sbGx/6GozP8cS+f/Lnn+/0ed + //9fwv//Z87//2LG//9OqP//OYr//x1c//+Hi9H/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA16SE//// + ////8+H///Pi/4V/dv+Ff3f/hX93/4WAeP+FgHj/hYB5/4WAev+FgXv/hYF7/4WBfP//+O7///jv/4WC + ff+Fgn7/hYJ+/4WCf/+Fgn//hYOA/4WDgP+Fg4H/hYOB/4WDgv+FhIL/hYSD/4uKif+vrq7/kpCM/yxM + sf8nauD/R5z8/2DE//9nzv//YcX//06n//85if//HVr//6e5///Gopr/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA2KWF////////8+H///Pi///z4v//9OT///Tl///15v//9ef///bo///26f//9ur///fr///3 + 7P//+O7///jv///57///+fD///ny///68///+/b///z4///9+v///fv///37///9+////vv///37///9 + /f/Nzcz/mZiX/5GQjf9Df8H/Wrny/2jP//9hxf//Tab//ziI//8cW///rb3///////+wfXH/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA2aaG////////8+D///Ph///z4v//9OT///Tl///15v//9ef///Xo///2 + 6f//9ur///fr///37P//+O3///ju///57///+fD///rz//369v/U0tD/np6c/3l6ev9naGn/Zmdo/3Z2 + dv+amZn/19bU///+/f/v7u3/g4OD/83My/+rrKr/WqjP/1m79P9Lpf//OIb//xxZ//+ywf////////// + //+zgHL/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA26iG////////8uD///Ph/4V/dv+Ff3b/hX93/4WA + d/+FgHj/hYB5/4WAev+FgHr/hYF7/4WBe/+FgXz/hYF8/4WBff+npaL/r66s/3R0df9wcnT/mpqZ/7+z + o//OvqT/0b+n/8G4qP+dnqH/YmVn/2VlZv9nZ2f/lJSU/7m5uf/+/f3/pKiq/0GIz/8weOj/GVHy/4ua + 0/////////////////+0gXP/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3KmH////////8uD///Ph/4V/ + dv+Ff3b/hX93/4V/d/+FgHj/hYB4/4WAef+FgHr/hYB6/4WBe/+FgXv/hYF8/66rqP+goJ//bm9y/6Gd + lf/YvI//8MaF/+/Iiv/nw4b/5sCF/+e9fv/mu3X/6cyi/7Gvrf9KS03/jIyM/+3t7f/MzMz/2NbV/4OJ + j/8YRsr/j5vS/6Kiov////////////////+2g3T/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3aqH//// + ////8uD///Ph/4V/dv+Ff3b/hX93/4V/d/+FgHj/hYB4/4WAef+FgHr/hYB6/4WBe/+FgXv/pqOf/6Wk + o/92eHv/u6yU/+nChf/nxIj/7syU/+7LlP/nxo//6cmU/+vPoP/rzqD/58KJ/+a6d//Wy7v/TlFT/5SU + lP+goKD/kZGR/6Skof+TlJb/r66u/4WFhf////////////////+5hnX/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA3quI////////8t////Pg///z4f//8+L///Tj///05P//9eX///Xn///16P//9uj///bp///3 + 6///+O7/5uPf/3l6fP+8rpb/9NCR/+/OlP/vzpX/7s6U/+7NlP/uy5L/7sqP/+3Hi//tzJf/8deu//DS + ov/swHv/1829/0tMTv9jY2P/0dHR/7GxsP/o5+f///79///+/f///v7///7+///+/v+7iHb/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA36yI////////8t////Lg///z4f//8+L///Tj///05P//9OX///Xm///1 + 5///9uj///bp///26v//+vP/oJ+f/5uWjv/21Jn/8NGc//DSnf/w0p3/8NKd//DRnP/v0Jn/79CY/+7N + kv/uyo//7cmP//HXrv/x06L/7sJ//6iopv+GhYb///79///+/f///fz///78///+/P///v3///79///+ + /f+9inj/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4K2J////////8t7///Lg/4V/df+Ff3X/hX92/4V/ + d/+Ff3f/hYB3/4WAeP+FgHn/hYB6/5GNiP+3tbP/f4GE/9W9kv/ozJj/8daj//HYpP/nz5z/58+d/+fN + nP/nzJn/58qV/+bIkv/vz5j/7suQ/+7JkP/y27H/7sqT/+zSq/9cXmH/7ezq///9+v///fv///37///9 + /P///fz///38///9/P++i3j/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4a6K////////8t7///Lf/4V+ + df+Ff3X/hX92/4V/dv+Ff3f/hX93/4WAeP+FgHj/hYB5/6WhnP+joqH/kI2J/+7RnP/o0J//8tus//Pc + rP/q06P/6tOj/+nSov/o0KD/58+c/+fMmf/w0p3/78+X/+7Lkf/w0KD/8NWr/+7Eg/+QkZX/urm4///9 + +v///fr///36///9+v///fr///36///9+v/Bjnn/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4q+K//// + ////8t7///Lf/4V+df+Ff3X/hX92/4V/dv+Ff3f/hX93/4WAd/+FgHj/hYB5/7Guqv+ampn/qaCN/+7T + o//s1aj/9eCz//Xgs//r16z/69is/+vXqf/q1af/6tOj/+jQn//x1qT/8NKd/+/Pl//vzJL/8tmz/+/I + iv+zrKL/lZSU///9+v///Pn///z5///8+f///Pn///z5///8+f/Cj3r/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA5LGL////////8d3///Le///y3///8+D///Ph///z4v//9OP///Tk///05f//9eb///Xn///6 + 8v+jo6P/uq+V//fhsf/25bz/9uW8//bpxf/368f/+OrE//blvv/247f/9eCy//Pdrv/x2aj/8dah//DR + nP/uzpL/8ter//DMlP/HuaX/hYSF///9+v///Pf///z4///8+P///Pj///z4///8+P/EkXv/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA5bKL////////8d3///Le///y3///8uD///Ph///z4v//8+L///Tk///0 + 5f//9eX///Xn///58f+mpqX/ua6W//jktv/36cT/++/S//vuzv/47s3/+O3K//fqxf/36b//9uO4//Xg + s//z3K//8dim//DTnv/vz5f/8dWn//DNlf/EtqL/hoaG///8+f//+/b///v3///89////Pf///z3///8 + 9//Gk3z/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA5rOM////////8dz///Hd/4V+dP+FfnT/hX91/4V/ + df+Ff3b/hX92/4V/d/+Ff3f/hYB4/7Kvqv+mpqX/rKOT//rpuv/x58n/9OvV//Tqzf/y68//8+jL//Dn + xP/u4r7/7d+5/+vYrv/q1af/8tqp//HWpP/nyZP/686f/+rHjf+vp5r/mZmY/6upp/+Fg4D/hYOA/4WD + gP//+/b///v2///79v/IlX3/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA57SM////////8dz///Hd/4V+ + dP+FfnT/hX51/4V/df+Ff3X/hX92/4V/dv+Ff3f/hX93/6ainP+ysa//k5GN//3twP/07NH/9fHd//Xx + 3v/49+z/+PXp//Przv/w5sb/7uTB/+3dtP/r2Kz/89ys//HXpf/nypX/6tCf/+nEif+Ki43/u7q4/5+c + mv+Fg4D/hYOA/4WDgP//+/X///v1///79f/Jln3/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA6LWN//// + ////8dv///Hc/4V+c/+FfnT/hX50/4V+df+Ff3X/hX92/4V/dv+Ff3f/hX93/5KOhv++vbr/k5SX/9/U + sv/07dH/9/Pg//n47v/6+vL/+fnw//Tv2P/x6cz/8ufH/+7et//r2Kz/892v//Hap//nypb/6c2a/9fA + mf9rbG//7Onn/42Kh/+Fgn//hYJ//4WCf///+vT///r0///69P/MmX//AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA6baO////////8Nv///Hb///x3f//8d3///Le///y4P//8+D///Ph///z4v//9OP///Tk///0 + 5f//+fD/x8bF/5mVi///+Nf//Pjh//387v///vf//f3v//z33f/79df/+vDR//jov//247j/892v//HZ + p//w1aD/9NKa/5qWkv+Xlpb///v3///68v//+vL///ry///68///+vP///rz///68//MmX//AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA6reO////////8Nr///Hb///x3P//8d3///Le///y3///8uD///Ph///z + 4f//8+L///Tj///05P//9ej/8u7p/6Wlp/+6tKD///3j//365f/9/Ov//Prp//354//79dv/++/O//fo + wv/25Lj/892u//Lap//216D/u7Cc/3Bxc//p5+P///nx///58f//+fH///nx///58v//+fL///ny///5 + 8v/MmX//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA67iP////////8Nr///Da/4V+cv+FfnP/hX5z/4V+ + dP+FfnT///Lg///z4f+Ff3b/hX92/4V/dv+Ff3f/qaWg/8XEwv+cnZ//tbGd//b01//389z/9vLc//v2 + 3v/y6cv/7uK8/+3cs//s2Kv/69Sm/+3TnP+3q5b/dHV4/6empP+hnpv///nv///58P//+fD///nw///5 + 8P//+fD///nw///58P/Nmn//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA7bqP////////8Nn///Da/4V9 + cv+FfnL/hX5z/4V+c/+FfnT///Lf///y4P+Ff3X/hX92/4V/dv+Ff3b/hX93/7Guqf/FxMP/o6Sl/5eV + i//a0rP/9OrE//3xyv/w5Lz/8OC2//HcsP/w2qr/1cKd/5mVj/95enz/p6Wk/6uopf+FgXz///jv///4 + 7///+O////nv///57///+e////nv///57//Nmn//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA7ruQ//// + ////79f///DZ/4V9cv+FfnL/hX5z/4V+c/+FfnT///Le///y3/+Ff3X/hX91/4V/dv+Ff3b/hX92/4V/ + d/+sqKL/xMK//7Oys/+Sk5P/k5GN/7CqnP+5sJv/urGZ/6yllf+Qjor/gIGD/4qJif+0s7D/pqOe/4WB + fP+FgXz///ju///47v//+O7///ju///47v//+O7///ju///47v/Om4D/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA77yQ////////79b///DZ///w2f//8Nr///Hb///x3P//8d3///Le///y3v//8uD///Pg///z + 4f//8+L///Pi///04///9OT///bp//347//i3tr/wsG+/6uqqv+bm5z/mJiY/52dnP+0srD/2tfT//75 + 8///+O3///fr///37P//9+z///fs///47f//+O3///jt///47f//+O3///jt///47f/Om4D/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA8L2R////////7tT//+/W///w2f//8Nr///Da///x2///8dz///Hd///y + 3v//8t////Lg///z4P//8+H///Pi///z4v//9OP///Tk///05P//9un///ju///58f//+vL///rz///6 + 8v//+fD///fs///26f//9ur///bq///36///9+v///fr///37P//9+z///fs///37P//9+z///fs///3 + 7P/Om4D/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8b6S////////7dL//+7U/4V9cP+FfXH/hX1y/4V9 + cv+FfnL/hX5z/4V+c/+FfnT/hX50/4V+df+Ff3X///Ph///z4v+Ff3b/hX92/4V/d/+Ff3f/hX93/4WA + d/+FgHj/hYB4/4WAeP+FgHn/hYB5/4WAef+FgHr///bp///26f+FgHr/hYB6/4WBe/+FgXv/hYF7/4WB + e///9+v///fr///36//PnID/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8r+S////////7ND//+7T/4V8 + b/+FfXD/hX1x/4V9cv+FfXL/hX5y/4V+c/+FfnP/hX50/4V+dP+FfnT///Lg///z4f+Ff3X/hX92/4V/ + dv+Ff3b/hX93/4V/d/+Ff3f/hYB3/4WAeP+FgHj/hYB4/4WAef+FgHn///bo///26f+FgHr/hYB6/4WA + ev+FgHr/hYB6/4WAev//9ur///bq///26v/PnID/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA88CT//// + ////7M7//+3R/4V8bv+FfG//hX1w/4V9cf+FfXL/hX1y/4V+cv+FfnP/hX5z/4V+dP+FfnT///Lf///y + 4P+Ff3X/hX91/4V/dv+Ff3b/hX92/4V/d/+Ff3f/hX93/4V/d/+FgHf/hYB4/4WAeP+FgHj///Xn///1 + 6P+FgHn/hYB5/4WAef+FgHn/hYB6/4WAev//9un///bp///26f/PnID/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA9MGT////////68z//+zP///t0f//7tP//+7V///w2f//8Nn///Da///w2///8dv///Hc///x + 3f//8t7///Le///y3///8uD///Pg///z4f//8+H///Pi///z4v//9OP///Tk///05P//9OX///Tl///1 + 5f//9eb///Xm///15///9ef///Xn///15///9ef///Xo///16P//9ej///Xo///16P/QnYH/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA9sOU////////6sv//+vN///sz///7dH//+7T///u1f//8Nn///DZ///w + 2v//8Nv///Hb///x3P//8d3///Hd///y3v//8t////Lg///y4P//8+H///Ph///z4v//8+L///Pi///0 + 4///9OT///Tk///05P//9OX///Tl///15f//9eb///Xm///15v//9eb///Xn///15///9ef///Xn///1 + 5//QnYH/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA98SU////////6sn//+rL/4V7a/+Fe2z/hXxt/4V8 + bv+FfG//hX1w/4V9cf+FfXL/hX1y/4V+cv+FfnP/hX5z/4V+c/+FfnT/hX50/4V+dP+FfnX/hX91///z + 4f//8+H/hX92/4V/dv+Ff3b/hX92/4V/dv+Ff3f/hX93/4V/d/+Ff3f/hX93/4V/d/+Ff3f/hYB3/4WA + d///9eX///Xl///15f/QnYH/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+MWV////////6cf//+rJ/4V6 + av+Fe2v/hXts/4V8bf+FfG7/hXxv/4V9cP+FfXH/hX1y/4V9cv+FfnL/hX5y/4V+c/+FfnP/hX5z/4V+ + dP+FfnT/hX50///y4P//8+D/hX91/4V/df+Ff3X/hX92/4V/dv+Ff3b/hX92/4V/dv+Ff3f/hX93/4V/ + d/+Ff3f/hX93/4V/d///9OT///Tk///05P/QnYH/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+caW//// + ////6MP//+nH/4V6af+Femr/hXtr/4V7bP+FfG3/hXxu/4V8b/+FfXD/hX1x/4V9cf+FfXL/hX1y/4V+ + cv+FfnP/hX5z/4V+c/+FfnT/hX50///y3///8t//hX51/4V+df+Ff3X/hX91/4V/df+Ff3b/hX92/4V/ + dv+Ff3b/hX92/4V/dv+Ff3b/hX92/4V/dv//9OP///Tj///04//QnYH/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA+seW////////58H//+jE///px///6sn//+rL///rzf//7M///+3R///u0///7tT//+/W///w + 2f//8Nn///Da///w2v//8dv///Hb///x3P//8d3///Hd///y3v//8t7///Lf///y3///8uD///Lg///z + 4P//8+H///Ph///z4f//8+H///Pi///z4v//8+L///Pi///z4v//8+L///Pi///z4v/QnYH/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA+8iX//7y4v//8Nn//+fB///ow///6cf//+rJ///qy///68z//+zO///s + 0P//7dL//+7U///v1v//79f///DZ///w2v//8Nr///Db///x2///8dz///Hc///x3f//8d3///Le///y + 3v//8t7///Lf///y3///8uD///Lg///y4P//8+D///Ph///z4f//8+H///Ph///z4f//8+H///Ph/+7U + v//QnYH/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/MmXo/zJl//+9OX///DZ///nwf//6MP//+jF///p + yP//6sr//+vM///szv//7ND//+3R///u0///7tX//+/X///w2f//8Nn///Da///w2v//8Nv///Hb///x + 3P//8dz///Hd///x3f//8d3///Le///y3v//8t7///Lf///y3///8t////Lg///y4P//8uD///Lg///y + 4P//9+z/9uHN/9Kfgv/PnICjAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP3KmMz8yZf//vLi//// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////15df/0Z6B/9KfgswAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAD8yZej+8iX//rHlv/5xpb/+MWV//fElP/2w5T/9MGT//PAk//yv5L/8b6S//C9kf/vvJD/7ruQ/+26 + j//ruI//6reO/+m2jv/otY3/57SM/+azjP/lsov/5LGL/+Kviv/hror/4K2J/9+siP/eq4j/3aqH/9yp + h//bqIb/2aaG/9ilhf/XpIT/1qOE/9Wig//UoYP/06CCowAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////AAD//////58AAP//////gwAA+AAAAAAD + AADwAAAAAAMAAOAAAAAAAQAA4AAAAAABAADgAAAAAAMAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAA + AAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAH + AADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAA + AAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAH + AADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAA + AAAABwAA4AAAAAAHAADwAAAAAA8AAPgAAAAAHwAA////////AAD///////8AAP///////wAA + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/ProcessMon/Program.cs b/Demo_Source_Code/CSharpDemo/ProcessMon/Program.cs new file mode 100644 index 0000000..3e93b31 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/ProcessMon/Program.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Windows.Forms; + +namespace ProcessMon +{ + static class Program + { + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main() + { + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + Application.Run(new ProcessMon()); + } + } +} diff --git a/Demo_Source_Code/CSharpDemo/ProcessMon/Properties/AssemblyInfo.cs b/Demo_Source_Code/CSharpDemo/ProcessMon/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..71287f0 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/ProcessMon/Properties/AssemblyInfo.cs @@ -0,0 +1,38 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("ProcessMon")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("ProcessMon")] +[assembly: AssemblyCopyright("Copyright © EaseFilter 2019")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("6f3ee287-55d9-4d9a-9944-5a7500c1266d")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("5.2.3.2001")] +//[assembly: AssemblyFileVersion("1.0.0.0")] + + diff --git a/Demo_Source_Code/CSharpDemo/ProcessMon/Properties/Resources.Designer.cs b/Demo_Source_Code/CSharpDemo/ProcessMon/Properties/Resources.Designer.cs new file mode 100644 index 0000000..462ca70 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/ProcessMon/Properties/Resources.Designer.cs @@ -0,0 +1,73 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace ProcessMon.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // 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", "16.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + 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() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [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("ProcessMon.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap about { + get { + object obj = ResourceManager.GetObject("about", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + } +} diff --git a/Demo_Source_Code/CSharpDemo/ProcessMon/Properties/Resources.resx b/Demo_Source_Code/CSharpDemo/ProcessMon/Properties/Resources.resx new file mode 100644 index 0000000..3be265d --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/ProcessMon/Properties/Resources.resx @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + ..\about.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/ProcessMon/Properties/Settings.Designer.cs b/Demo_Source_Code/CSharpDemo/ProcessMon/Properties/Settings.Designer.cs new file mode 100644 index 0000000..8ebfcb0 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/ProcessMon/Properties/Settings.Designer.cs @@ -0,0 +1,26 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace ProcessMon.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.10.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default { + get { + return defaultInstance; + } + } + } +} diff --git a/Demo_Source_Code/CSharpDemo/ProcessMon/Properties/Settings.settings b/Demo_Source_Code/CSharpDemo/ProcessMon/Properties/Settings.settings new file mode 100644 index 0000000..3964565 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/ProcessMon/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + diff --git a/Demo_Source_Code/CSharpDemo/ProcessMon/about.png b/Demo_Source_Code/CSharpDemo/ProcessMon/about.png new file mode 100644 index 0000000..4017add Binary files /dev/null and b/Demo_Source_Code/CSharpDemo/ProcessMon/about.png differ diff --git a/Demo_Source_Code/CSharpDemo/ProcessMon/app.config b/Demo_Source_Code/CSharpDemo/ProcessMon/app.config new file mode 100644 index 0000000..c5e1dae --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/ProcessMon/app.config @@ -0,0 +1,3 @@ + + + diff --git a/Demo_Source_Code/CSharpDemo/ProcessMon/app.manifest b/Demo_Source_Code/CSharpDemo/ProcessMon/app.manifest new file mode 100644 index 0000000..aee0ba0 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/ProcessMon/app.manifest @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Demo_Source_Code/CSharpDemo/ProcessMon/processmon.ico b/Demo_Source_Code/CSharpDemo/ProcessMon/processmon.ico new file mode 100644 index 0000000..7d0dd69 Binary files /dev/null and b/Demo_Source_Code/CSharpDemo/ProcessMon/processmon.ico differ diff --git a/Demo_Source_Code/CSharpDemo/RegMon/Program.cs b/Demo_Source_Code/CSharpDemo/RegMon/Program.cs new file mode 100644 index 0000000..ae401bd --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/RegMon/Program.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Windows.Forms; + +namespace RegMon +{ + static class Program + { + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main() + { + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + Application.Run(new RegMonForm()); + + } + } +} diff --git a/Demo_Source_Code/CSharpDemo/RegMon/Properties/AssemblyInfo.cs b/Demo_Source_Code/CSharpDemo/RegMon/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..2bfa1f0 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/RegMon/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Registry Monitor and Protector")] +[assembly: AssemblyDescription("Registry Access Monitor and Control")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("EaseFilter")] +[assembly: AssemblyProduct("Registry Access Monitor and Protector")] +[assembly: AssemblyCopyright("Copyright © EaseFilter 2019")] +[assembly: AssemblyTrademark("EaseFilter")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("ddf4bb22-545a-481e-9d32-980e86721f6a")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("5.2.4.1")] +//[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Demo_Source_Code/CSharpDemo/RegMon/Properties/Resources.Designer.cs b/Demo_Source_Code/CSharpDemo/RegMon/Properties/Resources.Designer.cs new file mode 100644 index 0000000..241047d --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/RegMon/Properties/Resources.Designer.cs @@ -0,0 +1,63 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace RegMon.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // 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", "16.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + 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() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [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("RegMon.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + } +} diff --git a/Demo_Source_Code/CSharpDemo/RegMon/Properties/Resources.resx b/Demo_Source_Code/CSharpDemo/RegMon/Properties/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/RegMon/Properties/Resources.resx @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/RegMon/Properties/Settings.Designer.cs b/Demo_Source_Code/CSharpDemo/RegMon/Properties/Settings.Designer.cs new file mode 100644 index 0000000..573eb7c --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/RegMon/Properties/Settings.Designer.cs @@ -0,0 +1,26 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace RegMon.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.10.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default { + get { + return defaultInstance; + } + } + } +} diff --git a/Demo_Source_Code/CSharpDemo/RegMon/Properties/Settings.settings b/Demo_Source_Code/CSharpDemo/RegMon/Properties/Settings.settings new file mode 100644 index 0000000..3964565 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/RegMon/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + diff --git a/Demo_Source_Code/CSharpDemo/RegMon/RegMon.csproj b/Demo_Source_Code/CSharpDemo/RegMon/RegMon.csproj new file mode 100644 index 0000000..f516e83 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/RegMon/RegMon.csproj @@ -0,0 +1,173 @@ + + + + Debug + x86 + 8.0.30703 + 2.0 + {3159257E-F264-4B6A-B96E-F3D46ABF90A3} + WinExe + Properties + RegMon + RegMon + v4.5 + + + 512 + SAK + SAK + SAK + SAK + + + AnyCPU + true + full + false + ..\..\Release\ + DEBUG;TRACE + prompt + 4 + false + + + AnyCPU + pdbonly + true + ..\..\Release\ + TRACE + prompt + 4 + false + + + registry-icon.ico + + + app.manifest + + + true + ..\..\Release\ + DEBUG;TRACE + full + AnyCPU + ..\..\Release\RegMon.exe.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + false + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false + false + false + false + + + ..\..\Release\ + TRACE + true + pdbonly + AnyCPU + ..\..\Release\RegMon.exe.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + false + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false + false + + + + + + + + + + + + + + + + + Form + + + RegistryAccessControlForm.cs + + + + + Form + + + RegUnitTest.cs + + + Form + + + RegMonForm.cs + + + + + RegistryAccessControlForm.cs + + + RegUnitTest.cs + + + RegMonForm.cs + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + True + Resources.resx + True + + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + + + + + + {34CB783E-DDA2-4CE3-80BC-37B25AA33E5F} + CommonObjects + + + {21540012-A296-45CE-8D35-3EA5A07B32A6} + FilterControl + + + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/RegMon/RegMonForm.Designer.cs b/Demo_Source_Code/CSharpDemo/RegMon/RegMonForm.Designer.cs new file mode 100644 index 0000000..6122b38 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/RegMon/RegMonForm.Designer.cs @@ -0,0 +1,202 @@ +namespace RegMon +{ + partial class RegMonForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(RegMonForm)); + this.toolStrip1 = new System.Windows.Forms.ToolStrip(); + this.toolStripButton_StartFilter = new System.Windows.Forms.ToolStripButton(); + this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); + this.toolStripButton_Stop = new System.Windows.Forms.ToolStripButton(); + this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator(); + this.toolStripButton_ClearMessage = new System.Windows.Forms.ToolStripButton(); + this.toolStripSeparator3 = new System.Windows.Forms.ToolStripSeparator(); + this.toolStripButton_UnitTest = new System.Windows.Forms.ToolStripButton(); + this.listView_Info = new System.Windows.Forms.ListView(); + this.menuStrip1 = new System.Windows.Forms.MenuStrip(); + this.settingsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.exitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStrip1.SuspendLayout(); + this.menuStrip1.SuspendLayout(); + this.SuspendLayout(); + // + // toolStrip1 + // + this.toolStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.toolStripButton_StartFilter, + this.toolStripSeparator1, + this.toolStripButton_Stop, + this.toolStripSeparator2, + this.toolStripButton_ClearMessage, + this.toolStripSeparator3, + this.toolStripButton_UnitTest}); + this.toolStrip1.Location = new System.Drawing.Point(0, 24); + this.toolStrip1.Name = "toolStrip1"; + this.toolStrip1.Size = new System.Drawing.Size(909, 25); + this.toolStrip1.TabIndex = 2; + this.toolStrip1.Text = "toolStrip1"; + // + // toolStripButton_StartFilter + // + this.toolStripButton_StartFilter.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton_StartFilter.Image"))); + this.toolStripButton_StartFilter.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButton_StartFilter.Name = "toolStripButton_StartFilter"; + this.toolStripButton_StartFilter.Size = new System.Drawing.Size(91, 22); + this.toolStripButton_StartFilter.Text = "Start Service"; + this.toolStripButton_StartFilter.Click += new System.EventHandler(this.toolStripButton_StartFilter_Click); + // + // toolStripSeparator1 + // + this.toolStripSeparator1.Name = "toolStripSeparator1"; + this.toolStripSeparator1.Size = new System.Drawing.Size(6, 25); + // + // toolStripButton_Stop + // + this.toolStripButton_Stop.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton_Stop.Image"))); + this.toolStripButton_Stop.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButton_Stop.Name = "toolStripButton_Stop"; + this.toolStripButton_Stop.Size = new System.Drawing.Size(91, 22); + this.toolStripButton_Stop.Text = "Stop Service"; + this.toolStripButton_Stop.Click += new System.EventHandler(this.toolStripButton_Stop_Click); + // + // toolStripSeparator2 + // + this.toolStripSeparator2.Name = "toolStripSeparator2"; + this.toolStripSeparator2.Size = new System.Drawing.Size(6, 25); + // + // toolStripButton_ClearMessage + // + this.toolStripButton_ClearMessage.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton_ClearMessage.Image"))); + this.toolStripButton_ClearMessage.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButton_ClearMessage.Name = "toolStripButton_ClearMessage"; + this.toolStripButton_ClearMessage.Size = new System.Drawing.Size(108, 22); + this.toolStripButton_ClearMessage.Text = "Clear messages"; + this.toolStripButton_ClearMessage.Click += new System.EventHandler(this.toolStripButton_ClearMessage_Click); + // + // toolStripSeparator3 + // + this.toolStripSeparator3.Name = "toolStripSeparator3"; + this.toolStripSeparator3.Size = new System.Drawing.Size(6, 25); + // + // toolStripButton_UnitTest + // + this.toolStripButton_UnitTest.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton_UnitTest.Image"))); + this.toolStripButton_UnitTest.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButton_UnitTest.Name = "toolStripButton_UnitTest"; + this.toolStripButton_UnitTest.Size = new System.Drawing.Size(117, 22); + this.toolStripButton_UnitTest.Text = "Registry Unit Test"; + this.toolStripButton_UnitTest.Click += new System.EventHandler(this.toolStripButton_UnitTest_Click); + // + // listView_Info + // + this.listView_Info.Dock = System.Windows.Forms.DockStyle.Fill; + this.listView_Info.FullRowSelect = true; + this.listView_Info.HideSelection = false; + this.listView_Info.HoverSelection = true; + this.listView_Info.LabelEdit = true; + this.listView_Info.Location = new System.Drawing.Point(0, 49); + this.listView_Info.Name = "listView_Info"; + this.listView_Info.ShowItemToolTips = true; + this.listView_Info.Size = new System.Drawing.Size(909, 434); + this.listView_Info.TabIndex = 3; + this.listView_Info.UseCompatibleStateImageBehavior = false; + this.listView_Info.View = System.Windows.Forms.View.Details; + // + // menuStrip1 + // + this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.settingsToolStripMenuItem, + this.toolsToolStripMenuItem, + this.exitToolStripMenuItem}); + this.menuStrip1.Location = new System.Drawing.Point(0, 0); + this.menuStrip1.Name = "menuStrip1"; + this.menuStrip1.Size = new System.Drawing.Size(909, 24); + this.menuStrip1.TabIndex = 4; + this.menuStrip1.Text = "menuStrip1"; + // + // settingsToolStripMenuItem + // + this.settingsToolStripMenuItem.Name = "settingsToolStripMenuItem"; + this.settingsToolStripMenuItem.Size = new System.Drawing.Size(61, 20); + this.settingsToolStripMenuItem.Text = "Settings"; + this.settingsToolStripMenuItem.Click += new System.EventHandler(this.settingsToolStripMenuItem_Click); + // + // toolsToolStripMenuItem + // + this.toolsToolStripMenuItem.Name = "toolsToolStripMenuItem"; + this.toolsToolStripMenuItem.Size = new System.Drawing.Size(46, 20); + this.toolsToolStripMenuItem.Text = "Tools"; + // + // exitToolStripMenuItem + // + this.exitToolStripMenuItem.Name = "exitToolStripMenuItem"; + this.exitToolStripMenuItem.Size = new System.Drawing.Size(38, 20); + this.exitToolStripMenuItem.Text = "Exit"; + this.exitToolStripMenuItem.Click += new System.EventHandler(this.exitToolStripMenuItem_Click); + // + // RegMonForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(909, 483); + this.Controls.Add(this.listView_Info); + this.Controls.Add(this.toolStrip1); + this.Controls.Add(this.menuStrip1); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.MainMenuStrip = this.menuStrip1; + this.Name = "RegMonForm"; + this.Text = "Registry Monitoring and Protection"; + this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.RegMonForm_FormClosing); + this.toolStrip1.ResumeLayout(false); + this.toolStrip1.PerformLayout(); + this.menuStrip1.ResumeLayout(false); + this.menuStrip1.PerformLayout(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.ToolStrip toolStrip1; + private System.Windows.Forms.ToolStripButton toolStripButton_StartFilter; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator1; + private System.Windows.Forms.ToolStripButton toolStripButton_Stop; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator2; + private System.Windows.Forms.ToolStripButton toolStripButton_ClearMessage; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator3; + private System.Windows.Forms.ToolStripButton toolStripButton_UnitTest; + private System.Windows.Forms.ListView listView_Info; + private System.Windows.Forms.MenuStrip menuStrip1; + private System.Windows.Forms.ToolStripMenuItem settingsToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem toolsToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem exitToolStripMenuItem; + } +} + diff --git a/Demo_Source_Code/CSharpDemo/RegMon/RegMonForm.cs b/Demo_Source_Code/CSharpDemo/RegMon/RegMonForm.cs new file mode 100644 index 0000000..7acea9b --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/RegMon/RegMonForm.cs @@ -0,0 +1,246 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.IO; +using System.Reflection; +using System.Windows.Forms; +using System.Diagnostics; +using System.Runtime.InteropServices; + +using EaseFilter.FilterControl; +using EaseFilter.CommonObjects; + +namespace RegMon +{ + public partial class RegMonForm : Form + { + RegistryHandler registryHandler = null; + FilterControl filterControl = new FilterControl(); + + public RegMonForm() + { + GlobalConfig.filterType = FilterAPI.FilterType.REGISTRY_FILTER; + + InitializeComponent(); + + StartPosition = FormStartPosition.CenterScreen; + DisplayVersion(); + + registryHandler = new RegistryHandler(listView_Info); + + } + + ~RegMonForm() + { + GlobalConfig.Stop(); + filterControl.StopFilter(); + } + + private void DisplayVersion() + { + string version = Assembly.GetExecutingAssembly().GetName().Version.ToString(); + try + { + string filterDllPath = Path.Combine(GlobalConfig.AssemblyPath, "FilterAPI.Dll"); + version = FileVersionInfo.GetVersionInfo(filterDllPath).ProductVersion; + } + catch (Exception ex) + { + EventManager.WriteMessage(43, "LoadFilterAPI Dll", EventLevel.Error, "FilterAPI.dll can't be found." + ex.Message); + } + + this.Text += " Version: " + version; + } + + private void RegMonForm_FormClosing(object sender, FormClosingEventArgs e) + { + FilterAPI.ResetConfigData(); + GlobalConfig.Stop(); + filterControl.StopFilter(); + Application.Exit(); + } + + private void settingsToolStripMenuItem_Click(object sender, EventArgs e) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + RegistryAccessControlForm regitryAccessControlForm = new RegistryAccessControlForm(); + if (regitryAccessControlForm.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + SendSettingsToFilter(); + } + } + + void SendSettingsToFilter() + { + filterControl.ClearFilters(); + + GlobalConfig.Load(); + + if (GlobalConfig.RegistryFilterRules.Count == 0) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("You don't have any registry filter setup, please go to the settings to add a new filter rule, or the filter driver won't intercept any process or IO."); + } + + foreach (RegistryFilterRule filterRule in GlobalConfig.RegistryFilterRules.Values) + { + RegistryFilter registryFilter = filterRule.ToRegistryFilter(); + + registryFilter.NotifyRegWasBlocked += registryHandler.NotifyRegWasBlocked; + + registryFilter.OnPreDeleteKey += registryHandler.OnPreDeleteKey; + registryFilter.OnPreSetValueKey += registryHandler.OnPreSetValueKey; + registryFilter.OnPreDeleteValueKey += registryHandler.OnPreDeleteValueKey; + registryFilter.OnPreSetInformationKey += registryHandler.OnPreSetInformationKey; + registryFilter.OnPreRenameKey += registryHandler.OnPreRenameKey; + registryFilter.OnPreEnumerateKey += registryHandler.OnPreEnumerateKey; + registryFilter.OnPreEnumerateValueKey += registryHandler.OnPreEnumerateValueKey; + registryFilter.OnPreQueryKey += registryHandler.OnPreQueryKey; + registryFilter.OnPreQueryValueKey += registryHandler.OnPreQueryValueKey; + registryFilter.OnPreQueryMultipleValueKey += registryHandler.OnPreQueryMultipleValueKey; + registryFilter.OnPreCreateKey += registryHandler.OnPreCreateKey; + registryFilter.OnPreOpenKey += registryHandler.OnPreOpenKey; + registryFilter.OnPreKeyHandleClose += registryHandler.OnPreKeyHandleClose; + registryFilter.OnPreCreateKeyEx += registryHandler.OnPreCreateKeyEx; + registryFilter.OnPreOpenKeyEx += registryHandler.OnPreOpenKeyEx; + registryFilter.OnPreFlushKey += registryHandler.OnPreFlushKey; + registryFilter.OnPreLoadKey += registryHandler.OnPreLoadKey; + registryFilter.OnPreUnLoadKey += registryHandler.OnPreUnLoadKey; + registryFilter.OnPreQueryKeySecurity += registryHandler.OnPreQueryKeySecurity; + registryFilter.OnPreSetKeySecurity += registryHandler.OnPreSetKeySecurity; + registryFilter.OnPreRestoreKey += registryHandler.OnPreRestoreKey; + registryFilter.OnPreSaveKey += registryHandler.OnPreSaveKey; + registryFilter.OnPreReplaceKey += registryHandler.OnPreReplaceKey; + registryFilter.OnPreQueryKeyName += registryHandler.OnPreQueryKeyName; + + registryFilter.NotifyDeleteKey += registryHandler.NotifyDeleteKey; + registryFilter.NotifySetValueKey += registryHandler.NotifySetValueKey; + registryFilter.NotifyDeleteValueKey += registryHandler.NotifyDeleteValueKey; + registryFilter.NotifySetInformationKey += registryHandler.NotifySetInformationKey; + registryFilter.NotifyRenameKey += registryHandler.NotifyRenameKey; + registryFilter.NotifyEnumerateKey += registryHandler.NotifyEnumerateKey; + registryFilter.NotifyEnumerateValueKey += registryHandler.NotifyEnumerateValueKey; + registryFilter.NotifyQueryKey += registryHandler.NotifyQueryKey; + registryFilter.NotifyQueryValueKey += registryHandler.NotifyQueryValueKey; + registryFilter.NotifyQueryMultipleValueKey += registryHandler.NotifyQueryMultipleValueKey; + registryFilter.NotifyCreateKey += registryHandler.NotifyCreateKey; + registryFilter.NotifyOpenKey += registryHandler.NotifyOpenKey; + registryFilter.NotifyKeyHandleClose += registryHandler.NotifyKeyHandleClose; + registryFilter.NotifyCreateKeyEx += registryHandler.NotifyCreateKeyEx; + registryFilter.NotifyOpenKeyEx += registryHandler.NotifyOpenKeyEx; + registryFilter.NotifyFlushKey += registryHandler.NotifyFlushKey; + registryFilter.NotifyLoadKey += registryHandler.NotifyLoadKey; + registryFilter.NotifyUnLoadKey += registryHandler.NotifyUnLoadKey; + registryFilter.NotifyQueryKeySecurity += registryHandler.NotifyQueryKeySecurity; + registryFilter.NotifySetKeySecurity += registryHandler.NotifySetKeySecurity; + registryFilter.NotifyRestoreKey += registryHandler.NotifyRestoreKey; + registryFilter.NotifySaveKey += registryHandler.NotifySaveKey; + registryFilter.NotifyReplaceKey += registryHandler.NotifyReplaceKey; + registryFilter.NotifyQueryKeyName += registryHandler.NotifyQueryKeyName; + + filterControl.AddFilter(registryFilter); + } + + + string lastError = string.Empty; + if (!filterControl.SendConfigSettingsToFilter(ref lastError)) + { + MessageBox.Show(lastError, "SendConfigSettingsToFilter", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + + } + + + private void toolStripButton_StartFilter_Click(object sender, EventArgs e) + { + try + { + //Purchase a license key with the link: http://www.easefilter.com/Order.htm + //Email us to request a trial key: info@easefilter.com //free email is not accepted. + string licenseKey = GlobalConfig.LicenseKey; + + string lastError = string.Empty; + + bool ret = filterControl.StartFilter(GlobalConfig.filterType, GlobalConfig.FilterConnectionThreads, GlobalConfig.ConnectionTimeOut, licenseKey, ref lastError); + if (!ret) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("Start filter failed." + lastError, "StartFilter", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + EventManager.WriteMessage(102, "StartFilter", EventLevel.Information, "Start filter service succeeded."); + + SendSettingsToFilter(); + + toolStripButton_StartFilter.Enabled = false; + toolStripButton_Stop.Enabled = true; + + EventManager.WriteMessage(102, "SendSettingsToFilter", EventLevel.Information, "SendSettingsToFilter succeeded."); + } + catch (Exception ex) + { + EventManager.WriteMessage(104, "StartFilter", EventLevel.Error, "Start filter service failed with error " + ex.Message); + } + } + + + private void toolStripButton_Stop_Click(object sender, EventArgs e) + { + FilterAPI.ResetConfigData(); + filterControl.StopFilter(); + + toolStripButton_StartFilter.Enabled = true; + toolStripButton_Stop.Enabled = false; + } + + private void toolStripButton_ClearMessage_Click(object sender, EventArgs e) + { + registryHandler.InitListView(); + } + + private void toolStripButton_UnitTest_Click(object sender, EventArgs e) + { + toolStripButton_Stop_Click(null, null); + RegUnitTest regUnitTest = new RegUnitTest(GlobalConfig.LicenseKey ); + regUnitTest.ShowDialog(); + } + + private void exitToolStripMenuItem_Click(object sender, EventArgs e) + { + Close(); + } + + + private void toolStripButton_ApplyTrialKey_Click(object sender, EventArgs e) + { + WebFormServices webForm = new WebFormServices(); + webForm.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + + System.Threading.Tasks.Task.Factory.StartNew(() => { webForm.ShowDialog(); }); + } + + + } +} diff --git a/Demo_Source_Code/CSharpDemo/RegMon/RegMonForm.resx b/Demo_Source_Code/CSharpDemo/RegMon/RegMonForm.resx new file mode 100644 index 0000000..e00a261 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/RegMon/RegMonForm.resx @@ -0,0 +1,4551 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + + + + 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 + AAAAAElFTkSuQmCC + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAJFSURBVDhPrdBbSNNxHAXwo2aKl8ZyMy/brFzWPypvyBQL + iTJCAyWIIOqlMEkjZ4VWCNYg8hIpou1BQyScmvmgwzKjBokJBiL1IoSG1JKcl9wclTZP7u/vyYd88fPy + 53vO4f/ww6aKNYe/SGuKnT1Qox2NNql6cBFFyMceUW9sd0NER82XAra67rB7qZL9rGPuS8P8auWztthI + KXSK8pDvLT9LaXHdYx9rebwn3SlafNiKnAF/xItznWoY0p7FOOqn89g4a6TFXcZuPuBhy6HPYoF3gNoa + hImBABSKSKiALrVNN3NjLJ2myVyaxs8xuzlmuctTTqlx56BYyWzBMNpU8PQF4KiIAOWj4OZroxk0fjIw + oyt6AXeRh2IUWH6VMKxeUSdmsvfbcHIkCnwVitciAlLa9jvODklMtGicqEKCHFZAgWr/SpggybcwokL5 + pB4cVMP7uGviWvXuLJuevnUoE5FsJQLSQhTur4Qh1Hv/UCNhUgvnrAQOR2BKHnlpnihtBquGqMUxEcmW + kwMbWJzIiUhcntbg0tzBwAWm+vFPAjikRpOYrTIjc2+nyrP6vSoS2e9s7RCbztN+KnLp760MMl8is0Jp + 3+UzM6yEVszWbGn3NfqZfcfRge0iwtIFaZzWIvL5FXp/xKpsOtIUjqkdMIjJOu1IQgtyxIXFmydcHKkk + 39wmuwr5NSnkm10Jnaj/j4Cf8/oRN11vybHHZH8JPQ9zuZgc8lRMNsY47JuLDzLPZIb3Ok7rP06diZt3 + pih6Rb0ZgH+vle/bCJhHDQAAAABJRU5ErkJggg== + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHvSURBVDhPrY9fSFNRHMdvpqVLqLcgZhS4hwohMo2ChN5i + RJE2pKfeRg9D7CFh9SAlZJP+IguKakarsLIyxNqw7porGST92aUaVxIW1trK1lbktrt9uuJ5u9J68ANf + zuH3/ZxzONKCAyxK+SR73Fc2/v7pai3yuKbw7nqlEvasaOO2bbHQ5gc6y3JPpDsz6m7QZD2D8LsXUodI + vqgj0CsNIcvlQjeSGVnqyKrN+sGwnn6YuQjpLkg4IL6fhFyL77TpsNCNJEeWvCU7rL96CfJ9kNOT7oav + bRBr0ddW5DNVUaEbmXq4MsefuzB9FDKuuUwfgc92mNwJ3zoIn6jShG5kanD5d36ehC92ion2uczuY/so + qlv1y7rxn6tMC92I4i2/h9oEn5opfJzNXgoTu9AiDfrsAMWJPdw/VvFI6EYSgSZL9GZFEnULRLehKY2g + NqK92qx/oYVgj5RRvA0bhT4/udG6etWzLM+HDWTHzORfW8iG1yBfNhUmH2zaIbR/8+aKKVSMrCcTNPPr + +VpyLy2MnaoeF3Vp1P51rcPHJYIuiWc9EkOdEiF37UFRl2ZgQDafdXsJyEE8V6/R3tHF+Qt99aIujaIo + 1S6XKx4cDeG9cQun05ny+/2rRP1/uN3uGqvVGrPZbD8cDsd2MV5oJOkvVdA/naM/yOcAAAAASUVORK5C + YII= + + + + 122, 17 + + + + AAABAAEAAPcAAAEAIAAI+wMAFgAAACgAAAAAAQAA7gEAAAEAIAAAAAAAANwDAAAAAAAAAAAAAAAAAAAA + AAD///////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////+/v7///////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////7+/v////////////7+/v/6+vr///////// + ///+/v7///////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////7+/v////////////Lz8/+oqKn/kJCQ/9zb + 2//////////////////+/v7///////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////f39////////////9vj4/8bGxv9oYV7/SEZG/0xM + TP9JTlL/oqSm/+rp6P////////////39/f////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////+/v7//f39///////+////2Nra/4iDgP9FQkD/NE9d/6iv + sv/Pz9D/cVxJ/z44Mv9eZGn/v7+///Py8v////////////39/f////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////8/Pz////////////s7u//p6am/09JRv86R03/SX2Y/ySq + 7//b9v///////81yIP+TURb/Xko4/zg7Pf9/goX/2NfW/////////////Pz8//7+/v////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////7+/v/9/f3///////z9/f/Dxcb/bmZj/zs+P/9Can//PKLV/znC + //8htP//1Ov2///////HbyH/yFcA/7tdCP+DVCv/TEE2/0VMUv+lpqb/6ejn/////////////f39//// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////z8/P///////////+Dj5P+TkI//R0JA/zxTX/9CjrX/Nbv//zPA + //86ufn/IbL8/9bu+v//////yXAg/75VAP/EXQH/zV4A/6ZZFf9tTTH/PDo4/2puc//Jx8X//fz8//// + ///7+/v//v7+//////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////////////////////v7+//z8/P///////f7+/7i6u/9jXFj/OD1A/0N5lP86run/M8L//zW5 + /P81uPr/Orz+/yG0/v/W7vn//////8lwIP/BVgD/wlwB/8BbAv/JXQD/xV0B/5JXIv9UQzP/P0VL/5iY + mP/m5OP///////7+/v/9/f3///////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////////////////////Pz8////////////3+Hi/4yKif9HQT7/PVpp/0GZxv81vP//NL7//za3 + +f81uv3/Nbr+/zq8/v8htP7/1u75///////JcCD/wVYA/8NdAf/DXAD/wVwB/8NcAP/LXQD/sFsQ/3hP + K/8+PDr/ZGlu/8PBv////v7///////r6+v////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////////////////////Pz8////////////t7q7/2VeW/86PkH/QX6d/zqw7P80wv//Nbn8/zW4 + +/81uv7/Nbr+/zW6/v87vP7/IrT+/9bu+f//////yXAg/8FWAP/DXQH/w1wA/8NcAP/CXAD/wVwB/8dc + AP/GXQD/l1ce/1dCMP9AR03/l5aV/+vq6f//////+/v7//7+/v////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////+/v7//Pz8///////t7u//jo+P/01GQ/87VWL/QJvJ/zW8//80vv//Nbf5/zW6 + /v81uv7/Nbr+/zW6/v81uv7/Orz+/yK0/v/W7vn//////8lxIP/BVgD/w1wB/8NcAP/DXAD/w1wA/8Nc + AP/BXAH/wlsA/8pcAP+zXA7/dU0q/z8/Pv9rbnH/zcrH////////////+/v7//////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////9/f3////////////KzM3/b2xq/z06Of8/eJT/O67p/zTA//81uf3/Nbn8/zW6 + /v81uv7/Nbr+/zW6/v81uv7/Nbr+/zu8/v8itP7/1u75///////JcSD/wVcA/8NdAf/DXAD/w1wA/8Nc + AP/DXAD/w1wA/8JcAP/AWwH/xlsA/8NdAv+VVh7/TUA0/0lQVv+ppqT/+fj4///////6+vr///////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////8/Pz///////////+ho6T/WVNQ/ztIT/9AlL//N7n6/zXA//82ufr/Nbr+/zW6 + /v81uv7/Nbr+/zW6/v81uv7/Nbr+/zW6/v87vP7/IrT+/9bu+f//////yXEg/8FXAP/DXgH/w10A/8Nc + AP/DXAD/w1wA/8NcAP/DXAD/w1wA/8FbAf/EWwD/yFwA/61bEv9nSCz/QERI/4B/f//j4eD///////v7 + +//+/v7///////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////8/Pz//////+3u7v+AgIH/SEA9/z1jdv88quD/Nb///za8//82ufv/Nrv+/za7 + /v81uv7/Nbr+/zW6/v81uv7/Nbr+/zW6/v81uv7/O7z+/yK0/v/W7vn//////8lxIP/BVwD/w14B/8Nd + AP/DXQD/w1wA/8NcAP/DXAD/w1wA/8NcAP/DXAD/wVsB/8FbAf/HXAD/vl0G/4VRIv9EQT7/XF9i/8nG + xP///////v7+//39/f////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////8/Pz//////87Q0P9paGj/Pz07/z6Bov85s/H/NcH//za6/P82uv3/Nrv+/za7 + /v82u/7/Nrv+/zW6/v81uv7/Nbr+/zW6/v81uv7/Nbr+/zu8/v8itP7/1u75///////JcSD/wVcA/8Ne + Af/DXQD/w10A/8NdAP/DXAD/w1wA/8NcAP/DXAD/w1wA/8NcAP/CWwD/wFsB/8VbAP/EXAD/oFcX/1JD + Nv9ITlP/qKak///+/v///////Pz8//////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////7+/v/8/Pz//////6+wsf9YVlX/PEZK/z2XxP83uvz/Nb///za6/P82u/7/Nrv+/za7 + /v82u/7/Nrv+/za7/v82u/7/Nbr+/zW6/v81uv7/Nbr+/zW6/v87vP7/IrT+/9bu+f//////yXIg/8FX + AP/DXgH/w10A/8NdAP/DXQD/w10A/8NcAP/DXAD/w1wA/8NcAP/DXAD/w1wA/8NbAP/BWwH/w1sA/8Zc + AP+zWw3/ZEgu/0JGSv+HhoX/8/Lx///////8/Pz///////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////7+/v/+/v7//////5OVlv9MSEb/Pldj/zuo4P82vv//Nrz//za6/f82u/7/Nrv+/za7 + /v82u/7/Nrv+/za7/v82u/7/Nrv+/za7/v81uv7/Nbr+/zW6/v81uv7/O7z+/yK0/v/W7vn//////8ly + IP/BWAD/w14B/8NdAP/DXQD/w10A/8NdAP/DXQD/w1wA/8NcAP/DXAD/w1wA/8NcAP/DXAD/w1sA/8Fb + AP/CWwD/xVsA/79cBP96Tib/Q0RF/2tsbf/l5OP///////39/f////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////39/f//////8/Pz/3t9fv9FPzz/Pm+H/zmz7/83wP//N7z+/za7/f82u/7/Nrv+/za7 + /v82u/7/Nrv+/za7/v82u/7/Nrv+/za7/v82u/7/Nrv+/zW6/v81uv7/Nbr+/zu8/v8itP7/1u75//// + ///JciD/wVgA/8NeAf/DXQD/w10A/8NdAP/DXQD/w10A/8NdAP/DXAD/w1wA/8NcAP/DXAD/w1wA/8Nc + AP/CWwD/wlsA/8FbAf/EWwD/xFwA/5JTHP9JRUH/VFda/8/NzP////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////39/f//////4+Pj/25vb/9APz3/PoGj/zi49/82wP//N7z9/ze8/v83vP7/Nrv+/za7 + /v82u/7/Nrv+/za7/v82u/7/Nrv+/za7/v82u/7/Nrv+/za7/v82u/7/Nbr+/zW6/v87vP7/IrT+/9bu + +f//////yXIg/8FYAP/DXwH/w14A/8NdAP/DXQD/w10A/8NdAP/DXQD/w10A/8NcAP/DXAD/w1wA/8Nc + AP/DXAD/w1wA/8JbAP/CWwD/wVsB/8NbAP/EXAD/o1cU/1FGPP9KTlH/vLu6//////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////39/f//////09PT/2FiYv9AQkL/PZK7/zi8/v83vv//N7z9/ze8/v83vP7/N7z+/ze8 + /v82u/7/Nrv+/za7/v82u/7/Nrv+/za7/v82u/7/Nrv+/za7/v82u/7/Nrv+/za7/v81uv7/Orz+/yK0 + /v/W7vn//////8pyIP/BWAD/w18B/8NeAP/DXgD/w10A/8NdAP/DXQD/w10A/8NdAP/DXQD/w1wA/8Nc + AP/DXAD/w1wA/8NcAP/DXAD/wlsA/8JbAP/BWwD/wlsA/8RbAP+wWQz/XUk3/0RHSv+op6f///////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////39/f//////xsbG/1hYV/9ASEz/PJzL/ze+//83vf//N7z+/ze8/v83vP7/N7z+/ze8 + /v83vP7/N7z+/za7/v82u/7/Nrv+/za7/v82u/7/Nrv+/za7/v82u/7/Nrv+/za7/v82u/7/Nrv+/zu8 + /v8is/7/1u75///////KciD/wlgA/8NfAf/DXgD/w14A/8NeAP/DXQD/w10A/8NdAP/DXQD/w10A/8Nd + AP/DXAD/w1wA/8NcAP/DXAD/w1wA/8NcAP/CWwD/wlsA/8JbAP/CWwD/w1sA/7laBv9mSzP/QkRG/5eX + l//9/f3///////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////7+/v//////vr+//1VTU/9AT1b/PKPX/ze///83vP//N7z+/ze8/v83vP7/N7z+/ze8 + /v83vP7/N7z+/ze8/v83vP7/Nrv+/za7/v82u/7/Nrv+/za7/v82u/7/Nrv+/za7/v82u/7/Nrv+/za7 + /v88vf7/IrT+/9bu+f//////ynIg/8JYAP/EXwH/w14A/8NeAP/DXgD/w14A/8NdAP/DXQD/w10A/8Nd + AP/DXQD/w10A/8NcAP/DXAD/w1wA/8NcAP/DXAD/w1wA/8JbAP/CWwD/wlsA/8JbAP/CWwD/vlsD/29N + MP9CQ0T/jo+Q//n5+f////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////+/////v////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////v7+//7+/v//////r7Cw/05MS/9BVF7/PKng/zfB//83vP7/N7z+/ze8/v83vP7/N7z+/ze8 + /v83vP7/N7z+/ze8/v83vP7/N7z+/ze8/v82u/7/Nrv+/za7/v82u/7/Nrv+/za7/v82u/7/Nrv+/za7 + /v82u/7/O73+/yO1/v/W7vn//////8pyIP/CWAD/xF8B/8ReAP/DXgD/w14A/8NeAP/DXgD/w10A/8Nd + AP/DXQD/w10A/8NdAP/DXQD/w1wA/8NcAP/DXAD/w1wA/8NcAP/DXAD/wlsA/8JbAP/CWwD/wlsA/8Jb + AP/DWwD/dE4t/0RERP97fH3/9/f3//////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////+//// + ///////////////////////////////////+/v7///////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////v7+//7+/v//////sLCx/01KSP9BXGn/O6/o/zfB//84u/3/N7z+/ze8/v83vP7/N7z+/ze8 + /v83vP7/N7z+/ze8/v83vP7/N7z+/ze8/v83vP7/N7z+/za7/v82u/7/Nrv+/za7/v82u/7/Nrv+/za7 + /v82u/7/Nrv+/zu9/v8jtf7/1u75///////KciD/wlgA/8RfAf/EXgD/xF4A/8NeAP/DXgD/w14A/8Ne + AP/DXQD/w10A/8NdAP/DXQD/w10A/8NdAP/DXAD/w1wA/8NcAP/DXAD/w1wA/8NcAP/CWwD/wlsA/8Jb + AP/CWwD/wVsB/8ZcAP99UCj/RURE/3t8ff/39/f///////7+/v////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////v////////////// + //////////77///88v/49On/9PHr//z6+P///////////////////////v7+/////v////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////v7+////////////sLGx/01JSP9BXWr/O6/o/zfC//84u/z/OLz+/zi8/v83vP7/N7z+/ze8 + /v83vP7/N7z+/ze8/v83vP7/N7z+/ze8/v83vP7/N7z+/ze8/v83vP7/Nrv+/za7/v82u/7/Nrv+/za7 + /v82u/7/Nrv+/za7/v87vf7/I7X+/9bu+f//////ynIg/8JYAP/EXwH/xF4A/8ReAP/EXgD/w14A/8Ne + AP/DXgD/w14A/8NdAP/DXQD/w10A/8NdAP/DXQD/w10A/8NcAP/DXAD/w1wA/8NcAP/DXAD/w1wA/8Jb + AP/CWwD/wlsA/8JbAP/BWwH/xlwA/35RKP9ERET/e3x9//f29v///////v7+//////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////7////+///////////////////+ + +v//+/D///PU///nn//+12b/uYoW/4NdEv+4n2v/3tK8//bz7P/6+PT//////////////////v7+//7+ + /f////7///////////////////////////////////////////////////////////////////////// + /////////v7+////////////srKz/01JR/9CXmv/O6/n/zfC//84u/z/OL3+/zi8/v84vP7/OLz+/ze8 + /v83vP7/N7z+/ze8/v83vP7/N7z+/ze8/v83vP7/N7z+/ze8/v83vP7/N7z+/ze8/v82u/7/Nrv+/za7 + /v82u/7/Nrv+/za7/v82u/7/O73+/yO1/v/W7vn//////8pzIP/CWAD/xF8B/8ReAP/EXgD/xF4A/8Re + AP/DXgD/w14A/8NeAP/DXgD/w10A/8NdAP/DXQD/w10A/8NdAP/DXQD/w1wA/8NcAP/DXAD/w1wA/8Nc + AP/DXAD/wlsA/8JbAP/CWwD/wlsA/8FbAf/GXAD/flEo/0RERP97fH3/9/f3///////+/v7///////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////7////+/////v///////////////////vr///vt///0 + 0///5p///9lq///PQ///007//tJR/76TK/95TgD/gVUA/3tNAP+PaRz/tp1r/9/Tvf/z7+f/+vj0//// + //////////////7+/f/+/v3///7+//////////////////////////////////////////////////// + /////////v7+////////////uru8/1BMSv9BXmv/PK/n/zfC//84u/v/OL3+/zi9/v84vf7/OLz+/zi8 + /v84vP7/N7z+/ze8/v83vP7/N7z+/ze8/v83vP7/N7z+/ze8/v83vP7/N7z+/ze8/v83vP7/N7z+/za7 + /v82u/7/Nrv+/za7/v82u/7/Nrv+/zu9/v8jtf7/1u75///////KcyD/wlkA/8RfAf/EXgD/xF4A/8Re + AP/EXgD/xF4A/8NeAP/DXgD/w14A/8NeAP/DXQD/w10A/8NdAP/DXQD/w10A/8NdAP/DXAD/w1wA/8Nc + AP/DXAD/w1wA/8NcAP/CWwD/wlsA/8JbAP/CWwD/wVsB/8ZcAP9+USf/RERE/4SFhf/7+/v///////7+ + /v////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////////////+/////v////3///////////////////76///66v//89H//+ag///a + bf//z0P//9FM///TUf//1Fb//9RV//7SUv+9kSf/eU4A/4ZcBf+EWgX/glcA/35RAP96TAD/kWwh/7ee + bf/f073/8Ozi//r49f/////////////////+/fz//v79///+/v////////////////////////////// + /////////v7+//7+/v//////xMbH/1VQTv9AWWX/PK7l/zfD//84u/r/OL3+/zi9/v84vf7/OL3+/zi9 + /v84vP7/OLz+/zi8/v83vP7/N7z+/ze8/v83vP7/N7z+/ze8/v83vP7/N7z+/ze8/v83vP7/N7z+/ze8 + /v83vP7/Nrv+/za7/v82u/7/Nrv+/za7/v87vf7/I7X+/9bu+f//////ynMg/8JZAP/EYAH/xF4A/8Re + AP/EXgD/xF4A/8ReAP/EXgD/w14A/8NeAP/DXgD/w14A/8NdAP/DXQD/w10A/8NdAP/DXQD/w10A/8Nc + AP/DXAD/w1wA/8NcAP/DXAD/w1wA/8JbAP/CWwD/wlsA/8JbAP/BWwD/xlwA/3tPKP9CREb/kJCP//7+ + /v///////v7+//////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////////////v////7///79///////////////////++///+ej///LO///moP//23D//89D///R + Sf//01H//9RW///UVP//01P//9NS///UU//+0lH/vZEn/3hOAP+FWgL/glcA/4NYAf+EWQP/hVsF/4JX + AP99UAD/ekwA/5NvJf+4n27/3tK7/+7p3f/7+fb//////////////////fz7//79/f/+/v7///////// + //////////////7+/v//////09XW/15ZVv8/UVn/P6nd/zfC//84uvr/OL3+/zi9/v84vf7/OL3+/zi9 + /v84vf7/OL3+/zi8/v84vP7/OLz+/ze8/v83vP7/N7z+/ze8/v83vP7/N7z+/ze8/v83vP7/N7z+/ze8 + /v83vP7/N7z+/ze8/v82u/7/Nrv+/za7/v82u/7/O73+/yO1/v/W7vn//////8pzIP/CWQD/xGAB/8Rf + AP/EXgD/xF4A/8ReAP/EXgD/xF4A/8ReAP/DXgD/w14A/8NeAP/DXgD/w10A/8NdAP/DXQD/w10A/8Nd + AP/DXQD/w1wA/8NcAP/DXAD/w1wA/8NcAP/DXAD/wlsA/8JbAP/CWwD/wlsA/8JbAP/CXAH/c04s/0FF + SP+ioaD///////7+/v/+/v7///////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////7////9///+/P///////////////////vz///nm///yy///5qD//9ty///QRP//0Ef//9JQ///U + V///1FX//9NT///TUv//01L//9NS///TUv//1FP//tJR/72RJ/94TgD/hVoC/4JXAP+CVwD/glcA/4JX + AP+DWAL/hFoE/4VbBv+BVgD/e04A/3lMAP+Vcin/uJ9u/9zQt//s5tn/+/r4//////////////////38 + +v/+/f3//v7+//39/f//////4ePk/2hkYv88R0v/QaXW/zjE//85uvn/OL3+/zi9/v84vf7/OL3+/zi9 + /v84vf7/OL3+/zi9/v84vf7/OLz+/zi8/v84vP7/N7z+/ze8/v83vP7/N7z+/ze8/v83vP7/N7z+/ze8 + /v83vP7/N7z+/ze8/v83vP7/N7z+/za7/v82u/7/Nrv+/zu9/v8jtf7/1u75///////KcyD/wlkA/8Rg + Af/EXwD/xF8A/8ReAP/EXgD/xF4A/8ReAP/EXgD/xF4A/8NeAP/DXgD/w14A/8NeAP/DXQD/w10A/8Nd + AP/DXQD/w10A/8NdAP/DXAD/w1wA/8NcAP/DXAD/w1wA/8NcAP/CWwD/wlsA/8JbAP/CWwD/w1sA/8Jc + Af9pSjD/QkZK/7Wzsf///////Pz8//////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /v///vz////////////////////+///45P//8cj//+af///cdP//0Eb//9BF///ST///1Fb//9RW///T + VP//01L//9NS///TUv//01L//9NS///TUv//01L//9RT//7SUf+9kSf/eE4A/4VaAv+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/g1gC/4RaBf+FWwb/gFUA/3pNAP96TAD/l3Qs/7ifbf/ZzbL/6uPV//38 + +v////////////7+////////8PLz/3dzcv86PkD/RJ7J/zfF//85ufn/Ob3+/zm9/v84vf7/OL3+/zi9 + /v84vf7/OL3+/zi9/v84vf7/OL3+/zi9/v84vP7/OLz+/zi8/v83vP7/N7z+/ze8/v83vP7/N7z+/ze8 + /v83vP7/N7z+/ze8/v83vP7/N7z+/ze8/v83vP7/Nrv+/za7/v88vf7/I7X+/9bu+f//////ynMg/8JZ + AP/EYAH/xF8A/8RfAP/EXwD/xF4A/8ReAP/EXgD/xF4A/8ReAP/EXgD/w14A/8NeAP/DXgD/w14A/8Nd + AP/DXQD/w10A/8NdAP/DXQD/w10A/8NcAP/DXAD/w1wA/8NcAP/DXAD/w1wA/8JbAP/CWwD/wlsA/8Fb + AP/DWwD/vlwG/15IM/9GS0//ycfF///////7+/v///////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ////////////////////+OT///DG///mnv//3Hb//9FJ///PQ///0k7//9RW///UVv//01T//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///UU//+0lH/vZEn/3hOAP+FWgL/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4NZAv+EWgX/hVsG/39TAP95SwD/e04A/5h1 + L/+3nmz/18mt/+jh0v///////////4uIhv88PDz/RZK3/zjC//85u/r/Ob7+/zm9/v85vf7/Ob3+/zi9 + /v84vf7/OL3+/zi9/v84vf7/OL3+/zi9/v84vf7/OL3+/zi8/v84vP7/OLz+/ze8/v83vP7/N7z+/ze8 + /v83vP7/N7z+/ze8/v83vP7/N7z+/ze8/v83vP7/N7z+/ze8/v82u/7/O73+/yO1/v/W7vn//////8pz + IP/CWQD/xGAB/8RfAP/EXwD/xF8A/8RfAP/EXgD/xF4A/8ReAP/EXgD/xF4A/8ReAP/DXgD/w14A/8Ne + AP/DXgD/w10A/8NdAP/DXQD/w10A/8NdAP/DXQD/w1wA/8NcAP/DXAD/w1wA/8NcAP/DXAD/wlsA/8Jb + AP/CWwD/wVsA/8RbAP+zWgv/VUY4/1VZXP/d29n///////v7+/////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////9///+/P/+/fr//Pv5//79 + /f///vz///nn///ww///5p3//9x3///STf//z0H//9JN///UVf//1Fb//9NU///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//1FP//tJR/72RJ/94TgD/hVoC/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+DWQP/hVsF/4Ra + Bf9/UgD/eEoA/3xQAP+Zdi7/u6Nz/5uWj/9BPz3/RX6Z/zm///85vfz/Ob39/zm+/v85vv7/Ob3+/zm9 + /v85vf7/OL3+/zi9/v84vf7/OL3+/zi9/v84vf7/OL3+/zi9/v84vf7/OLz+/zi8/v84vP7/N7z+/ze8 + /v83vP7/N7z+/ze8/v83vP7/N7z+/ze8/v83vP7/N7z+/ze8/v83vP7/N7z+/zu9/v8jtf7/1u75//// + ///KdCD/wlkA/8RfAf/EXwD/xF8A/8RfAP/EXwD/xF8A/8ReAP/EXgD/xF4A/8ReAP/EXgD/xF4A/8Ne + AP/DXgD/w14A/8NeAP/DXQD/w10A/8NdAP/DXQD/w10A/8NdAP/DXAD/w1wA/8NcAP/DXAD/w1wA/8Nc + AP/CWwD/wlsA/8JbAP/CWwD/xVsA/6VYE/9IQz7/bG1t/+7t7P///////Pz8//////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////f///vz///78//////////////////// + /////////vnu//7jlP//0kz//89C///STf//1FT//9RW///UVP//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9RT//7SUf+9kSf/eE4A/4Va + Av+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwH/g1kD/4VbBv+EWgT/f1IA/2ZFAv9AOC//RWt9/zq49f85v///Ob38/zm+/v85vv7/Ob7+/zm+ + /v85vf7/Ob3+/zm9/v84vf7/OL3+/zi9/v84vf7/OL3+/zi9/v84vf7/OL3+/zi9/v84vP7/OLz+/zi8 + /v83vP7/N7z+/ze8/v83vP7/N7z+/ze8/v83vP7/N7z+/ze8/v83vP7/N7z+/ze8/v88vv7/I7X+/9bu + +f//////ynMg/8JaAP/EYAH/xF8A/8RfAP/EXwD/xF8A/8RfAP/EXwD/xF4A/8ReAP/EXgD/xF4A/8Re + AP/EXgD/w14A/8NeAP/DXgD/w14A/8NdAP/DXQD/w10A/8NdAP/DXQD/w10A/8NcAP/DXAD/w1wA/8Nc + AP/DXAD/w1wA/8JbAP/CWwD/wlsA/8JbAP/FXAD/k1Qd/0FCQ/+Mioj//v7+//7+/v/+/v7///////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////3///78///++///////////////////+eX//++//+XN + kv/JtpX/6+bb////8///44T//tBK///VWv//1FT//9NT///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///UU//+0lH/vZEn/3hO + AP+FWgL/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/hFgA/3tYD/9SSj7/Rltn/zyt4v84w///Obv6/zm+/v85vv7/Ob7+/zm+ + /v85vv7/Ob7+/zm9/v85vf7/Ob3+/zi9/v84vf7/OL3+/zi9/v84vf7/OL3+/zi9/v84vf7/OL3+/zi8 + /v84vP7/OLz+/ze8/v83vP7/N7z+/ze8/v83vP7/N7z+/ze8/v83vP7/N7z+/ze8/v83vP7/Pb7+/yS1 + /v/W7vn//////8p0IP/CWgD/xGEB/8RgAP/EXwD/xF8A/8RfAP/EXwD/xF8A/8RfAP/EXgD/xF4A/8Re + AP/EXgD/xF4A/8ReAP/DXgD/w14A/8NeAP/DXgD/w10A/8NdAP/DXQD/w10A/8NdAP/DXQD/w1wA/8Nc + AP/DXAD/w1wA/8NcAP/DXAD/wlsA/8JbAP/BWwH/xFsA/8RcAf96TSb/QUZL/6+sqf//////+/v7//// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////////////9///+/P///vv///////////////////jm///vv///45T//913///U + Vv/GlRr/eU4A/5t5NP+6nV7/7cdc///VUf/+0lL//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//1FP//tJR/72R + J/94TgD/hVoC/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/g1cA/39XBP9ZSS3/REtT/0Cbxv84xf//Obv5/zm+//85vv7/Ob7+/zm+ + /v85vv7/Ob7+/zm+/v85vv7/Ob3+/zm9/v85vf7/OL3+/zi9/v84vf7/OL3+/zi9/v84vf7/OL3+/zi9 + /v84vf7/OLz+/zi8/v84vP7/N7z+/ze8/v83vP7/N7z+/ze8/v83vP7/N7z+/ze8/v83vP7/N7z+/zy+ + /v8ktv7/1u75///////LdCD/wloA/8RhAf/EYAD/xGAA/8RfAP/EXwD/xF8A/8RfAP/EXwD/xF8A/8Re + AP/EXgD/xF4A/8ReAP/EXgD/xF4A/8NeAP/DXgD/w14A/8NeAP/DXQD/w10A/8NdAP/DXQD/w10A/8Nd + AP/DXAD/w1wA/8NcAP/DXAD/w1wA/8NcAP/CWwD/wlsA/8FbAf/FWwD/vFwH/2FGLv9NU1n/0c7M//// + ///7+/v///////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////////////v///vz///77///////////////////55///777//+OQ///cdf//1Vn//89C///S + Sv//01H/zKE1/3tQAP96TQD/h1kA/9uuNf//2Vf//dFQ///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9RT//7S + Uf+9kSf/eE4A/4VaAv+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/g1cA/4JXAP9nTh7/REdL/0KBnf85w///Orv5/zm+/v85vv7/Ob7+/zm+ + /v85vv7/Ob7+/zm+/v85vv7/Ob7+/zm+/v85vf7/Ob3+/zm9/v84vf7/OL3+/zi9/v84vf7/OL3+/zi9 + /v84vf7/OL3+/zi9/v84vP7/OLz+/zi8/v83vP7/N7z+/ze8/v83vP7/N7z+/ze8/v83vP7/N7z+/ze8 + /v88vv7/JLb+/9bu+f//////y3Mg/8NaAP/FYQH/xGAA/8RgAP/EYAD/xF8A/8RfAP/EXwD/xF8A/8Rf + AP/EXwD/xF4A/8ReAP/EXgD/xF4A/8ReAP/EXgD/w14A/8NeAP/DXgD/w14A/8NdAP/DXQD/w10A/8Nd + AP/DXQD/w10A/8NcAP/DXAD/w1wA/8NcAP/DXAD/w1wA/8JbAP/CWwD/wVsB/8dcAP+rWhL/S0A2/3By + c//t7Ov///////39/f////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////7///78///++///////////////////+er//+69///ijf//23L//9Va///PQ///0Un//9JQ///U + Vf//1FX//9RT/8ufMP97UQD/glgC/5NoDv/fsz7//9hV//3RUf//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///U + U//+0lH/vZEn/3hOAP+FWgL/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4NXAP92VA//SUVC/0RldP86vfr/Or79/zq9/f86vv7/Ob7+/zm+ + /v85vv7/Ob7+/zm+/v85vv7/Ob7+/zm+/v85vv7/Ob7+/zm9/v85vf7/Ob3+/zi9/v84vf7/OL3+/zi9 + /v84vf7/OL3+/zi9/v84vf7/OL3+/zi8/v84vP7/OLz+/ze8/v83vP7/N7z+/ze8/v83vP7/N7z+/ze8 + /v83vP7/PL7+/yS2/v/W7vn//////8t0IP/DWgD/xWEB/8VgAP/EYAD/xGAA/8RgAP/EXwD/xF8A/8Rf + AP/EXwD/xF8A/8RfAP/EXgD/xF4A/8ReAP/EXgD/xF4A/8ReAP/DXgD/w14A/8NeAP/DXgD/w10A/8Nd + AP/DXQD/w10A/8NdAP/DXQD/w1wA/8NcAP/DXAD/w1wA/8NcAP/DXAD/wlsA/8JbAP/CWwD/x1wA/5JV + Hv89P0D/npya///////8/Pz///////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////+///+ + /P///vv///////////////////rt///uvf//4Yv//9pv///WXP//0EX//9FJ///ST///1FX//9RU///T + U///01L//9RT///TUv/LnzD/e1AA/4BWAP+RZQn/3rI8///YVf/90VH//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//1FP//tJR/72RJ/94TgD/hVoC/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4NXAP9/VwP/U0cy/0VQWP89qdz/OcP//zq9+/86v/7/Or7+/zq+ + /v85vv7/Ob7+/zm+/v85vv7/Ob7+/zm+/v85vv7/Ob7+/zm+/v85vv7/Ob3+/zm9/v85vf7/OL3+/zi9 + /v84vf7/OL3+/zi9/v84vf7/OL3+/zi9/v84vf7/OLz+/zi8/v84vP7/N7z+/ze8/v83vP7/N7z+/ze8 + /v83vP7/N7z+/zy+/v8ktv7/1u75///////LdCD/w1sA/8VgAf/FYAD/xWAA/8RgAP/EYAD/xGAA/8Rf + AP/EXwD/xF8A/8RfAP/EXwD/xF8A/8ReAP/EXgD/xF4A/8ReAP/EXgD/xF4A/8NeAP/DXgD/w14A/8Ne + AP/DXQD/w10A/8NdAP/DXQD/w10A/8NdAP/DXAD/w1wA/8NcAP/DXAD/w1wA/8NcAP/DWwD/wVsB/8Rb + AP/BXQT/cUoo/0VNU//IxsP///////v7+/////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////v///v3///77//// + /v/////////////78P//7r7//+GK///ZbP//1lz//9BI///RSf//0k///9RU///TVP//01P//9NS///T + Uv//01L//9NS///UU///01L/y58w/3tQAP+AVgD/kWUJ/96yPP//2FX//dFR///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9RT//7SUf+9kSf/eE4A/4VaAv+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/Z04f/0RITP9Ch6f/OcX//zq9+v86v/7/Or/+/zq+ + /v86vv7/Or7+/zm+/v85vv7/Ob7+/zm+/v85vv7/Ob7+/zm+/v85vv7/Ob7+/zm+/v85vf7/Ob3+/zm9 + /v84vf7/OL3+/zi9/v84vf7/OL3+/zi9/v84vf7/OL3+/zi9/v84vP7/OLz+/zi8/v83vP7/N7z+/ze8 + /v83vP7/N7z+/ze8/v88vv7/JLb+/9bu+f//////y3Qg/8NbAP/FYQH/xWAA/8VgAP/FYAD/xGAA/8Rg + AP/EYAD/xF8A/8RfAP/EXwD/xF8A/8RfAP/EXwD/xF4A/8ReAP/EXgD/xF4A/8ReAP/EXgD/w14A/8Ne + AP/DXgD/w14A/8NdAP/DXQD/w10A/8NdAP/DXQD/w10A/8NcAP/DXAD/w1wA/8NcAP/DXAD/w1wA/8Nb + AP/AWwH/yFwA/65bEf9PPzL/cHN2/+zr6v///////f39//////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////9///+/P////7///////// + /////PP//++////hif//2Wj//9Zd///RSv//0Un//9JP///TU///01T//9NT///TUv//01L//9NS///T + Uv//01L//9NS///TUv//1FP//9NS/8ufMP97UAD/gFYA/5FlCf/esjz//9hV//3RUf//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///UU//+0lH/vZEn/3hOAP+FWgL/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/eVUM/0lGQv9EYnD/OsD//zq+/P86v/7/Or/+/zq/ + /v86v/7/Or7+/zq+/v86vv7/Ob7+/zm+/v85vv7/Ob7+/zm+/v85vv7/Ob7+/zm+/v85vv7/Ob7+/zm9 + /v85vf7/Ob3+/zi9/v84vf7/OL3+/zi9/v84vf7/OL3+/zi9/v84vf7/OL3+/zi8/v84vP7/OLz+/ze8 + /v83vP7/N7z+/ze8/v83vP7/PL7+/yS2/v/W7vn//////8t0IP/DWwD/xWIB/8VhAP/FYAD/xWAA/8Vg + AP/EYAD/xGAA/8RgAP/EXwD/xF8A/8RfAP/EXwD/xF8A/8RfAP/EXgD/xF4A/8ReAP/EXgD/xF4A/8Re + AP/DXgD/w14A/8NeAP/DXgD/w10A/8NdAP/DXQD/w10A/8NdAP/DXQD/w1wA/8NcAP/DXAD/w1wA/8Nc + AP/DXAD/wlsA/8BbAf/KXQD/kVYh/zs+QP+mpaT///////39/f////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////z2///v + wP//4Yr//9hl///WXP//0k3//9FJ///ST///01P//9NU///TU///01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9RT///TUv/LnzD/e1AA/4BWAP+RZQn/3rI8///YVf/90VH//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//1FP//tJR/72RJ/94TgD/hVoC/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/1lJL/9FTFH/PafZ/zrC//86vvz/Or/+/zq/ + /v86v/7/Or/+/zq//v86vv7/Or7+/zq+/v85vv7/Ob7+/zm+/v85vv7/Ob7+/zm+/v85vv7/Ob7+/zm+ + /v85vv7/Ob3+/zm9/v85vf7/OL3+/zi9/v84vf7/OL3+/zi9/v84vf7/OL3+/zi9/v84vf7/OLz+/zi8 + /v84vP7/N7z+/ze8/v83vP7/N7z+/zy+/v8ktv7/1u75///////LdCD/w1sA/8ViAf/FYQD/xWEA/8Vg + AP/FYAD/xWAA/8RgAP/EYAD/xGAA/8RfAP/EXwD/xF8A/8RfAP/EXwD/xF8A/8ReAP/EXgD/xF4A/8Re + AP/EXgD/xF4A/8NeAP/DXgD/w14A/8NeAP/DXQD/w10A/8NdAP/DXQD/w10A/8NdAP/DXAD/w1wA/8Nc + AP/DXAD/w1wA/8NcAP/BWwH/xFsA/8BdBf9qSSv/UFde/9jW1P///////Pz8//////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////7////+//7+/f/+/v3////////++v//8cj//+KK///X + Yv//1Vv//9JP///RSv//0k///9NS///TU///01P//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///UU///01L/y58w/3tQAP+AVgD/kWUJ/96yPP//2FX//dFR///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9RT//7SUf+9kSf/eE4A/4VaAv+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/3FSFf9GR0j/QniR/znE//86vfv/Or/+/zq/ + /v86v/7/Or/+/zq//v86v/7/Or/+/zq+/v86vv7/Or7+/zm+/v85vv7/Ob7+/zm+/v85vv7/Ob7+/zm+ + /v85vv7/Ob7+/zm+/v85vf7/Ob3+/zm9/v84vf7/OL3+/zi9/v84vf7/OL3+/zi9/v84vf7/OL3+/zi9 + /v84vP7/OLz+/zi8/v83vP7/N7z+/ze8/v88vv7/JLb+/9bu+f//////y3Qg/8NbAP/FYgH/xWEA/8Vh + AP/FYQD/xWAA/8VgAP/FYAD/xGAA/8RgAP/EYAD/xF8A/8RfAP/EXwD/xF8A/8RfAP/EXwD/xF4A/8Re + AP/EXgD/xF4A/8ReAP/EXgD/w14A/8NeAP/DXgD/w14A/8NdAP/DXQD/w10A/8NdAP/DXQD/w10A/8Nc + AP/DXAD/w1wA/8NcAP/DXAD/w1wA/8BbAf/KXAD/olkY/0U8Nf+Nj5H/+fn4///////+/v7///////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////v////7////////////////////////////++er//9lt///S + T///0kz//9JP///TUv//01P//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//1FP//9NS/8ufMP97UAD/gFYA/5FlCf/esjz//9hV//3R + Uf//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///UU//+0lH/vZEn/3hOAP+FWgL/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4FWAf9QRzf/RVFX/zy48/87v/7/Or/+/zq/ + /v86v/7/Or/+/zq//v86v/7/Or/+/zq//v86v/7/Or7+/zq+/v86vv7/Ob7+/zm+/v85vv7/Ob7+/zm+ + /v85vv7/Ob7+/zm+/v85vv7/Ob7+/zm9/v85vf7/Ob3+/zi9/v84vf7/OL3+/zi9/v84vf7/OL3+/zi9 + /v84vf7/OL3+/zi8/v84vP7/OLz+/ze8/v83vP7/PL7+/yS2/v/W7vn//////8t0IP/DWwD/xWIB/8Vh + AP/FYQD/xWEA/8VhAP/FYAD/xWAA/8VgAP/EYAD/xGAA/8RgAP/EXwD/xF8A/8RfAP/EXwD/xF8A/8Rf + AP/EXgD/xF4A/8ReAP/EXgD/xF4A/8ReAP/DXgD/w14A/8NeAP/DXgD/w10A/8NdAP/DXQD/w10A/8Nd + AP/DXQD/w1wA/8NcAP/DXAD/w1wA/8NcAP/DXAD/wVsB/8hdAP98UCr/PkVM/8nHxv///////f39//// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////00f/74pf/vJ5e/9PEpf/49/f///3v///X + Zf//01H//9RU///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9RT///TUv/LnzD/e1AA/4BWAP+RZQn/3rI8///Y + Vf/90VH//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//1FP//tJR/72RJ/94TgD/hVoC/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4NXAP9rUBv/RkdI/0GKrf87wv//O779/zu/ + /v86v/7/Or/+/zq//v86v/7/Or/+/zq//v86v/7/Or/+/zq//v86vv7/Or7+/zq+/v85vv7/Ob7+/zm+ + /v85vv7/Ob7+/zm+/v85vv7/Ob7+/zm+/v85vv7/Ob3+/zm9/v85vf7/OL3+/zi9/v84vf7/OL3+/zi9 + /v84vf7/OL3+/zi9/v84vf7/OLz+/zi8/v84vP7/N7z+/zy+/v8ktv7/1u75///////LdCD/w1sA/8Vi + Af/FYQD/xWEA/8VhAP/FYQD/xWEA/8VgAP/FYAD/xWAA/8RgAP/EYAD/xGAA/8RfAP/EXwD/xF8A/8Rf + AP/EXwD/xF8A/8ReAP/EXgD/xF4A/8ReAP/EXgD/xF4A/8NeAP/DXgD/w14A/8NeAP/DXQD/w10A/8Nd + AP/DXQD/w10A/8NdAP/DXAD/w1wA/8NcAP/DXAD/w1wA/8FcAf/IXAD/rVsR/1BAMP9/g4f/8/Hw//// + ///+/v7///////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////89P//+ab///YZf//1Vb/+89P/5twEP+DWAL/hl4O/66N + RP/50l3//tJQ///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///UU///01L/y58w/3tQAP+AVgD/kWUJ/96y + PP//2FX//dFR///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9RT//7SUf+9kSf/eE4A/4VaAv+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVgD/TUY7/0VWXv88vvr/O8D+/zu/ + /v87v/7/O7/+/zq//v86v/7/Or/+/zq//v86v/7/Or/+/zq//v86v/7/Or/+/zq+/v86vv7/Or7+/zm+ + /v85vv7/Ob7+/zm+/v85vv7/Ob7+/zm+/v85vv7/Ob7+/zm+/v85vf7/Ob3+/zm9/v84vf7/OL3+/zi9 + /v84vf7/OL3+/zi9/v84vf7/OL3+/zi9/v84vP7/OLz+/zi8/v89vv7/JLb+/9bu+f//////y3Qg/8Nb + AP/FYgH/xWEA/8VhAP/FYQD/xWEA/8VhAP/FYQD/xWAA/8VgAP/FYAD/xGAA/8RgAP/EYAD/xF8A/8Rf + AP/EXwD/xF8A/8RfAP/EXwD/xF4A/8ReAP/EXgD/xF4A/8ReAP/EXgD/w14A/8NeAP/DXgD/w14A/8Nd + AP/DXQD/w10A/8NdAP/DXQD/w10A/8NcAP/DXAD/w1wA/8NcAP/DXAD/wVwB/8xeAP+DUyj/Oz9E/8jH + xv///////f39//////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////////////f////////TV///mnP//2GT//9NS///TUf//0lD//9RR//vPT/+bcBH/gVUA/3xR + AP+QZQj/78NI///UUv/+0lH//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//1FP//9NS/8ufMP97UAD/gFYA/5Fl + Cf/esjz//9hV//3RUf//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///UU//+0lH/vZEn/3hOAP+FWgL/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+DVwD/alAc/0dGRv9AlLz/O8L//zvA + /v87wP7/O7/+/zu//v87v/7/Or/+/zq//v86v/7/Or/+/zq//v86v/7/Or/+/zq//v86v/7/Or7+/zq+ + /v86vv7/Ob7+/zm+/v85vv7/Ob7+/zm+/v85vv7/Ob7+/zm+/v85vv7/Ob7+/zm9/v85vf7/Ob3+/zi9 + /v84vf7/OL3+/zi9/v84vf7/OL3+/zi9/v84vf7/OL3+/zi8/v84vP7/Pr7+/yW2/v/W7vn//////8t0 + IP/DWwD/xWIB/8VhAP/FYQD/xWEA/8VhAP/FYQD/xWEA/8VhAP/FYAD/xWAA/8VgAP/EYAD/xGAA/8Rg + AP/EXwD/xF8A/8RfAP/EXwD/xF8A/8RfAP/EXgD/xF4A/8ReAP/EXgD/xF4A/8ReAP/DXgD/w14A/8Ne + AP/DXgD/w10A/8NdAP/DXQD/w10A/8NdAP/DXQD/w1wA/8NcAP/DXAD/w1wA/8JcAf/GXQD/tFwO/1VB + MP98gob/8/Hw///////+/v7///////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////vz////9///11///557//9hl///SUP//01D//9NR///TUf//01L//9NS///VU//7z0//m3AR/4JX + AP9+UwD/kWYK/+/DSP//1FL//tJR///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9RT///TUv/LnzD/e1AA/4BW + AP+RZQn/3rI8///YVf/90VH//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//1FP//tJR/72RJ/94TgD/hVoC/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwH/glcA/01HO/9FVV7/O7/8/zvA + //87wP7/O8D+/zvA/v87v/7/O7/+/zu//v86v/7/Or/+/zq//v86v/7/Or/+/zq//v86v/7/Or/+/zq/ + /v86vv7/Or7+/zq+/v85vv7/Ob7+/zm+/v85vv7/Ob7+/zm+/v85vv7/Ob7+/zm+/v85vv7/Ob3+/zm9 + /v85vf7/OL3+/zi9/v84vf7/OL3+/zi9/v84vf7/OL3+/zi9/v84vf7/OLz+/z2+/v8ltv7/1u75//// + ///LdSD/w1sA/8ViAf/FYQD/xWEA/8VhAP/FYQD/xWEA/8VhAP/FYQD/xWEA/8VgAP/FYAD/xWAA/8Rg + AP/EYAD/xGAA/8RfAP/EXwD/xF8A/8RfAP/EXwD/xF8A/8ReAP/EXgD/xF4A/8ReAP/EXgD/xF4A/8Ne + AP/DXgD/w14A/8NeAP/DXQD/w10A/8NdAP/DXQD/w10A/8NdAP/DXAD/w1wA/8NcAP/DXAD/wFsC/85f + AP+DVCr/Oj5C/8rKyf///////f39//////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////v////////////////////////77///+ + +v//9dr//+eg///ZZ///0k3//9JQ///TUv//01L//9NS///TUv//01L//9NS///TUv//1VP/+89P/5tw + Ef+CVwD/flMA/5FmCv/vw0j//9RS//7SUf//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///UU///01L/y58w/3tQ + AP+AVgD/kWUJ/96yPP//2FX//dFR///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9RT//7SUf+9kSf/eE4A/4Va + Av+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwH/hFcA/2tSHP9IRUP/QI60/zvB + //87wP7/O8D+/zvA/v87wP7/O8D+/zu//v87v/7/O7/+/zq//v86v/7/Or/+/zq//v86v/7/Or/+/zq/ + /v86v/7/Or/+/zq+/v86vv7/Or7+/zm+/v85vv7/Ob7+/zm+/v85vv7/Ob7+/zm+/v85vv7/Ob7+/zm+ + /v85vf7/Ob3+/zm9/v84vf7/OL3+/zi9/v84vf7/OL3+/zi9/v84vf7/OL3+/zi9/v89vv7/Jbb+/9bu + +f//////y3Ug/8NcAP/FYgH/xWEA/8VhAP/FYQD/xWEA/8VhAP/FYQD/xWEA/8VhAP/FYQD/xWAA/8Vg + AP/FYAD/xGAA/8RgAP/EYAD/xF8A/8RfAP/EXwD/xF8A/8RfAP/EXwD/xF4A/8ReAP/EXgD/xF4A/8Re + AP/EXgD/w14A/8NeAP/DXgD/w14A/8NdAP/DXQD/w10A/8NdAP/DXQD/w10A/8NcAP/DXAD/w1wA/8Jc + Af/GXAD/sFsQ/1JCM/+Bhor/9fTz///////+/v7///////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////7////+///////////////////++v///fb///bb///n + ov//2Wr//9FL///ST///01L//9NT///TU///01L//9NS///TUv//01L//9NS///TUv//01L//9VT//vP + T/+bcBH/glcA/35TAP+RZgr/78NI///UUv/+0lH//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//1FP//9NS/8uf + MP97UAD/gFYA/5FlCf/esjz//9hV//3RUf//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///UU//+0lH/vZEn/3hO + AP+FWgL/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/gVcB/4RYAP9TSzn/RVBV/zy7 + 9/87wf//O8D+/zvA/v87wP7/O8D+/zvA/v87wP7/O7/+/zu//v87v/7/Or/+/zq//v86v/7/Or/+/zq/ + /v86v/7/Or/+/zq//v86v/7/Or7+/zq+/v86vv7/Ob7+/zm+/v85vv7/Ob7+/zm+/v85vv7/Ob7+/zm+ + /v85vv7/Ob7+/zm9/v85vf7/Ob3+/zi9/v84vf7/OL3+/zi9/v84vf7/OL3+/zi9/v84vf7/Pb/+/yW2 + /v/W7vn//////8t1IP/DXAD/xWMB/8VhAP/FYQD/xWEA/8VhAP/FYQD/xWEA/8VhAP/FYQD/xWEA/8Vh + AP/FYAD/xWAA/8VgAP/EYAD/xGAA/8RgAP/EXwD/xF8A/8RfAP/EXwD/xF8A/8RfAP/EXgD/xF4A/8Re + AP/EXgD/xF4A/8ReAP/DXgD/w14A/8NeAP/DXgD/w10A/8NdAP/DXQD/w10A/8NdAP/DXQD/w1wA/8Nc + AP/DXAD/wFwC/89eAP96US7/QUZK/9jX1v///////v7+//////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////vr///zz///23P//6KP//9pt///R + Sv//0k3//9NS///UVP//01P//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///V + U//7z0//m3AR/4JXAP9+UwD/kWYK/+/DSP//1FL//tJR///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9RT///T + Uv/LnzD/e1AA/4BWAP+RZQn/3rI8///YVf/90VH//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//1FP//tJR/72R + J/94TgD/hVoC/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4NXAP9zVBP/SkQ//0CC + ov87v/3/O8H//zvA/v87wP7/O8D+/zvA/v87wP7/O8D+/zvA/v87v/7/O7/+/zu//v86v/7/Or/+/zq/ + /v86v/7/Or/+/zq//v86v/7/Or/+/zq//v86vv7/Or7+/zq+/v85vv7/Ob7+/zm+/v85vv7/Ob7+/zm+ + /v85vv7/Ob7+/zm+/v85vv7/Ob3+/zm9/v85vf7/OL3+/zi9/v84vf7/OL3+/zi9/v84vf7/OL3+/z2/ + /v8lt/7/1u/5///////MdSD/w1wA/8VjAf/FYgD/xWEA/8VhAP/FYQD/xWEA/8VhAP/FYQD/xWEA/8Vh + AP/FYQD/xWEA/8VgAP/FYAD/xWAA/8RgAP/EYAD/xGAA/8RfAP/EXwD/xF8A/8RfAP/EXwD/xF8A/8Re + AP/EXgD/xF4A/8ReAP/EXgD/xF4A/8NeAP/DXgD/w14A/8NeAP/DXQD/w10A/8NdAP/DXQD/w10A/8Nd + AP/DXAD/w1wA/8FcAf/HXQD/p1sW/0g+NP+anqH//Pv7//////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////77///77///9tv//+ik///bcP//0Un//9FM///T + Uv//1FX//9NU///TU///01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//1VP/+89P/5twEf+CVwD/flMA/5FmCv/vw0j//9RS//7SUf//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///U + U///01L/y58w/3tQAP+AVgD/kWUJ/96yPP//2FX//dFR///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9RT//7S + Uf+9kSf/eE4A/4VaAv+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4FXAf+FWAD/XE4w/0dH + R/89sef/O8L//zvA/v87wP7/O8D+/zvA/v87wP7/O8D+/zvA/v87wP7/O8D+/zu//v87v/7/O7/+/zq/ + /v86v/7/Or/+/zq//v86v/7/Or/+/zq//v86v/7/Or/+/zq+/v86vv7/Or7+/zm+/v85vv7/Ob7+/zm+ + /v85vv7/Ob7+/zm+/v85vv7/Ob7+/zm+/v85vf7/Ob3+/zm9/v84vf7/OL3+/zi9/v84vf7/OL3+/zi9 + /v89v/7/Jbf+/9bv+f//////zHUg/8RcAP/FYwH/xWIA/8ViAP/FYQD/xWEA/8VhAP/FYQD/xWEA/8Vh + AP/FYQD/xWEA/8VhAP/FYQD/xWAA/8VgAP/FYAD/xGAA/8RgAP/EYAD/xF8A/8RfAP/EXwD/xF8A/8Rf + AP/EXwD/xF4A/8ReAP/EXgD/xF4A/8ReAP/EXgD/w14A/8NeAP/DXgD/w14A/8NdAP/DXQD/w10A/8Nd + AP/DXQD/w10A/8NcAP/DXAD/wVwB/8pfAP9qTTL/Vlxh/+jn5v///////v7+//////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////76///no///3HP//9FI///RSv//01H//9RV///U + VP//01P//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9VT//vPT/+bcBH/glcA/35TAP+RZgr/78NI///UUv/+0lH//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//1FP//9NS/8ufMP97UAD/gFYA/5FlCf/esjz//9hV//3RUf//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///U + U//+0lH/vZEn/3hOAP+FWgL/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/f1cG/01H + Pv9CbIL/PL35/zzB//87wP7/O8D+/zvA/v87wP7/O8D+/zvA/v87wP7/O8D+/zvA/v87wP7/O7/+/zu/ + /v87v/7/Or/+/zq//v86v/7/Or/+/zq//v86v/7/Or/+/zq//v86v/7/Or7+/zq+/v86vv7/Ob7+/zm+ + /v85vv7/Ob7+/zm+/v85vv7/Ob7+/zm+/v85vv7/Ob7+/zm9/v85vf7/Ob3+/zi9/v84vf7/OL3+/zi9 + /v84vf7/Pb/+/yW3/v/W7/n//////8x1IP/EXAD/xmMB/8ViAP/FYgD/xWIA/8VhAP/FYQD/xWEA/8Vh + AP/FYQD/xWEA/8VhAP/FYQD/xWEA/8VhAP/FYAD/xWAA/8VgAP/EYAD/xGAA/8RgAP/EXwD/xF8A/8Rf + AP/EXwD/xF8A/8RfAP/EXgD/xF4A/8ReAP/EXgD/xF4A/8ReAP/DXgD/w14A/8NeAP/DXgD/w10A/8Nd + AP/DXQD/w10A/8NdAP/DXQD/w1wA/8FcAf/KXQD/lFgi/z87N//Bw8T///////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////88v//zkD//9NS///UVv//1FX//9NT///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///VU//7z0//m3AR/4JXAP9+UwD/kWYK/+/DSP//1FL//tJR///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9RT///TUv/LnzD/e1AA/4BWAP+RZQn/3rI8///YVf/90VH//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//1FP//tJR/72RJ/94TgD/hVoC/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+BVwH/hFgA/2lR + H/9KQjz/P5nE/zzB//88wP//PMD+/zvA/v87wP7/O8D+/zvA/v87wP7/O8D+/zvA/v87wP7/O8D+/zvA + /v87v/7/O7/+/zu//v86v/7/Or/+/zq//v86v/7/Or/+/zq//v86v/7/Or/+/zq//v86vv7/Or7+/zq+ + /v85vv7/Ob7+/zm+/v85vv7/Ob7+/zm+/v85vv7/Ob7+/zm+/v85vv7/Ob3+/zm9/v85vf7/OL3+/zi9 + /v84vf7/OL3+/z2//v8lt/7/1u/5///////MdiD/xFwA/8ZiAf/GYgD/xWIA/8ViAP/FYgD/xWEA/8Vh + AP/FYQD/xWEA/8VhAP/FYQD/xWEA/8VhAP/FYQD/xWEA/8VgAP/FYAD/xWAA/8RgAP/EYAD/xGAA/8Rf + AP/EXwD/xF8A/8RfAP/EXwD/xF8A/8ReAP/EXgD/xF4A/8ReAP/EXgD/xF4A/8NeAP/DXgD/w14A/8Ne + AP/DXQD/w10A/8NdAP/DXQD/w10A/8NdAP/CXAH/w1wA/7lcCv9WRTf/foOH//X19P///////v7+//// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////PP//9JO///UVv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//1VP/+89P/5twEf+CVwD/flMA/5FmCv/vw0j//9RS//7SUf//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///UU///01L/y58w/3tQAP+AVgD/kWUJ/96yPP//2FX//dFR///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9RT//7SUf+9kSf/eE4A/4VaAv+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/gVcB/4VY + AP9XTDT/RU9U/zy48f88w///PMD+/zzA/v88wP7/O8D+/zvA/v87wP7/O8D+/zvA/v87wP7/O8D+/zvA + /v87wP7/O8D+/zu//v87v/7/O7/+/zq//v86v/7/Or/+/zq//v86v/7/Or/+/zq//v86v/7/Or/+/zq+ + /v86vv7/Or7+/zm+/v85vv7/Ob7+/zm+/v85vv7/Ob7+/zm+/v85vv7/Ob7+/zm+/v85vf7/Ob3+/zm9 + /v84vf7/OL3+/zi9/v89v/7/Jbf+/9bv+f//////zHYg/8RdAP/GYwH/xmIA/8ZiAP/FYgD/xWIA/8Vi + AP/FYQD/xWEA/8VhAP/FYQD/xWEA/8VhAP/FYQD/xWEA/8VhAP/FYQD/xWAA/8VgAP/FYAD/xGAA/8Rg + AP/EYAD/xF8A/8RfAP/EXwD/xF8A/8RfAP/EXwD/xF4A/8ReAP/EXgD/xF4A/8ReAP/EXgD/w14A/8Ne + AP/DXgD/w14A/8NdAP/DXQD/w10A/8NdAP/DXQD/w10A/8BbAv/OXgD/dVAw/0pNUP/j4+P///////7+ + /v////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////zz///RSv//1FT//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9VT//vPT/+bcBH/glcA/35TAP+RZgr/78NI///UUv/+0lH//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//1FP//9NS/8ufMP97UAD/gFYA/5FlCf/esjz//9hV//3RUf//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///UU//+0lH/vZEn/3hOAP+FWgL/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP99Vwj/TkY8/0R4kf9Bvfj/QMP//0DB/v9Awf7/QMH+/0DB/v8/wf7/P8H+/z/B/v8/wf7/P8H+/z/B + /v8/wf7/P8H+/z/B/v8/wf7/P8D+/z/A/v8/wP7/PsD+/z7A/v8+wP7/PsD+/z7A/v8+wP7/PsD+/z7A + /v8+wP7/PsD+/z6//v8+v/7/Pr/+/z2//v89v/7/Pb/+/z2//v89v/7/Pb/+/z2//v89v/7/Pb/+/z2+ + /v89vv7/Pb7+/zy+/v88vv7/QsD+/yq4/v/X7/n//////815Jf/FYAD/x2cG/8dmBf/HZQX/x2UF/8dl + Bf/GZQX/xmUF/8ZlBf/GZAX/xmQF/8ZkBf/GZAX/xmQF/8ZkBf/GZAX/xmUF/8ZkBf/GYwX/xmMF/8Zj + Bf/FYwX/xWQF/8VjBf/FYgX/xWIF/8ViBf/FYgX/xWIF/8VjBf/FYgX/xWEF/8VhBf/FYQX/xWEF/8Vh + Bf/EYQX/xGEF/8RiBf/EYQX/xGEF/8RgBf/EYQX/xGAF/8RhBv/DYAf/yWAD/51dJP9BPDf/vL7A//// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////88///0Ur//9RU///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///VU//7z0//m3AR/4JXAP9+UwD/kWYK/+/DSP//1FL//tJR///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9RT///TUv/LnzD/e1AA/4BWAP+RZQn/3rI8///YVf/90VH//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//dFQ/72RJv96TwD/hVoC/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4FX + Af+EVwD/a1Me/0lAOf8tlsj/KLz//yi6/v8ouv7/KLr+/yi6/v8ouv7/KLr+/yi6/v8nuv7/J7r+/ye6 + /v8nuv7/J7r+/ye6/v8nuv7/J7r+/ye5/v8nuf7/J7n+/ye5/v8muf7/Jrn+/ya5/v8muf7/Jrn+/ya5 + /v8muf7/Jrn+/ya5/v8muP7/Jrf+/ya3/v8lt/7/Jbf+/yW3/v8lt/7/Jbf+/yW3/v8lt/7/Jbf+/yW4 + /v8lt/7/Jbf+/yW2/v8ltv7/JLb+/yq4/v8PsP7/0u35///////HaAr/vk0A/8BUAP/AUwD/wFMA/8BS + AP/AUgD/wFIA/79SAP+/UgD/v1EA/79RAP+/UQD/v1EA/79RAP+/UQD/v1EA/79RAP+/UQD/v1EA/79Q + AP+/UAD/v1AA/75QAP++UAD/vlAA/75PAP++TwD/vk8A/75PAP++TwD/vk8A/75OAP++TgD/vk4A/75O + AP++TgD/vk4A/71OAP+9TgD/vU4A/71OAP+9TQD/vU0A/71NAP+9TQD/vE0A/71NAP+1SwD/Uz8u/4SJ + jv/39vb///////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////PP//9FK///U + VP//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//1VP/+89P/5twEf+CVwD/flMA/5FmCv/vw0j//9RS//7S + Uf//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///UU///01L/y58w/3tQAP+AVgD/kWUJ/96yPP//2FX//dFR///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS//7SUf/90VD//9VT///WV/+7kir/ckkA/4NZAv+DWAD/hFgA/4NXAP+CVwD/glcA/4JX + AP+BVwL/h1kA/1tOMf9QTUv/i8nl/5Pd/v+R2Pf/kdj4/5HY+P+R2Pj/kdj4/5HY+P+R2Pj/kNj4/5DY + +P+Q2Pj/kNj4/5DY+P+Q2Pj/kNj4/5DY+P+Q2Pj/kNj4/5DX+P+Q1/j/kNf4/5DX+P+Q1/j/kNf4/5DX + +P+Q1/j/kNf4/5DX+P+Q1/j/kNf4/5DX+P+Q1/j/kNf4/4/X+P+P1/j/j9f4/4/X+P+P1/j/j9f4/4/X + +P+P1/j/j9f4/4/W+P+P1vj/j9b4/4/W+P+R1/j/hNL3/+j1+///////3rGD/9mja//ap3H/2qZx/9qm + cf/apnH/2qZx/9qmcf/ZpnH/2aZx/9mmcf/ZpXH/2aVx/9mlcf/ZpXH/2aVx/9mlcf/ZpXH/2aVx/9ml + cf/ZpXH/2aRx/9qlcf/ZpXH/2aRx/9mlcf/ZpHH/2aRx/9mkcf/ZpHH/2aRx/9mkcf/ZpHH/2aNx/9mj + cf/Zo3H/2aNx/9mjcf/Zo3H/2KNx/9ijcf/Yo3H/2KNx/9ijcf/Yo3H/2KNx/9ijcf/VoXD/5Kpz/3Rp + X/9QVFb/7u3t///////+/v7///////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////zz///R + Sv//1FT//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9VT//vPT/+bcBH/glcA/35TAP+RZgr/78NI///U + Uv/+0lH//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//1FP//9NS/8ufMP97UAD/gFYA/5FlCf/esjz//9hV//3R + Uf//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv/+0lH//tFQ///TUv//2Ff//9lZ//zPTv/vvDn/xY8X/5dkAP+NXwH/fVQA/3xTAP+BVgD/hFgA/4RY + AP+CVwD/gVcB/4RaAv9NRTb/foaS//////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////+/z7//////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///FvLj/REJB/9PU1P////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////////8 + 8///0Ur//9RU///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///VU//7z0//m3AR/4JXAP9+UwD/kWYK/+/D + SP//1FL//tJR///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9RT///TUv/LnzD/e1AA/4BWAP+RZQn/3rI8///Y + Vf/90VH//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//tJR//7R + UP//01L//9dX///aWv/90E//8L06/+auKf/bnxn/0I4H/86JAP/LiAD/unwA/6tyAP+daQD/i10A/3xT + AP98UwD/gVYB/4VZAP94VhH/RkQ//5d6Wv/crHT/3q93/92td//drnf/3a53/92ud//drnf/3a53/92t + d//drXf/3a13/92td//drXf/3a13/92td//crXf/3K13/9ytd//crHf/3K13/9ysd//crXf/3Kx3/9yt + d//crHf/3Kx3/9ysd//crHf/3Kx3/9ysd//cq3f/3Kt3/9yrd//cq3f/3Kt3/9yrd//cq3f/3Kt3/9yr + d//cq3f/3Kt3/9yrd//cq3f/3Kt3/9yrd//cq3f/26p3/9ytev/Yomr/9u3k//////+g3Pj/j9b3/5PY + +P+T1/j/k9f4/5PX+P+T1/j/k9f4/5PX+P+T1/j/k9f4/5LX+P+T1/j/ktf4/5LX+P+S1/j/ktf4/5LX + +P+S1/j/ktf4/5LX+P+S1/j/k9f4/5LW+P+S1vj/ktb4/5LW+P+S1vj/ktb4/5LW+P+S1vj/ktb4/5LW + +P+S1vj/ktb4/5LW+P+R1vj/kdb4/5HW+P+R1vj/kdb4/5HW+P+R1vj/kdb4/5HW+P+R1vj/kdb4/5HU + 9v+T2Pr/frvZ/0VNUf+opaT//f7+//////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////PP//9FK///UVP//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//1VP/+89P/5twEf+CVwD/flMA/5Fm + Cv/vw0j//9RS//7SUf//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///UU///01L/y58w/3tQAP+AVgD/kWUJ/96y + PP//2FX//dFR///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS//7SUf/+0VD//9JR///X + Vv//2lr//dFQ//C9Ov/krCj/254Y/9CPB//JgwD/yYMA/8uHAP/LiAD/zIgA/9CLAP/SjAD/yoYA/7t8 + AP+scwD/nWkA/4hcAf9+UwD/aU4b/0FGSv+oXAX/yF0A/8NbAP/DWwD/w1sA/8NbAP/DWwD/w1sA/8Nb + AP/DWwD/w1oA/8NZAP/DWgD/w1oA/8NaAP/DWgD/w1oA/8JaAP/CWQD/wlkA/8JYAP/CWAD/wlgA/8JY + AP/CWAD/wlgA/8JXAP/CVwD/wlcA/8JXAP/CVwD/wlcA/8FWAP/BVgD/wVYA/8FWAP/BVgD/wVYA/8FV + AP/BVQD/wVUA/8FVAP/BVQD/wVUA/8FVAP/BVQD/wVUA/8FVAP/CWQD/ukQA/+7cx///////P778/xuz + /v8ktv7/I7b+/yO2/v8jtv7/I7b+/yO2/v8jtv7/I7X+/yO1/v8jtf7/IrX+/yK1/v8itf7/IrX+/yK1 + /v8itf7/IrX+/yK1/v8itf7/IrX+/yK1/v8itf7/IbT+/yG0/v8htP7/IbT+/yG0/v8htP7/IbT+/yG0 + /v8htP7/IbT+/yG0/v8htP7/IbP+/yCz/v8gs/7/ILP+/yCz/v8gs/7/ILP+/yCz/v8gs/7/ILP+/yCz + /v8gs/3/ILH7/ya4//8/VWD/gnt4//b39/////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////zz///RSv//1FT//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9VT//vPT/+bcBH/glcA/35T + AP+RZgr/78NI///UUv/+0lH//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//1FP//9NS/8ufMP97UAD/gFYA/5Fl + Cf/esjz//9hV//3RUf//01L//9NS///TUv//01L//9NS///TUv/+0lH//tFQ//7SUf//1lX//9pa//7S + Uf/wvTr/46sm/9qdF//Rjwj/yYQA/8iDAP/LhgD/zYkB/82JAf/MiQH/zIgA/8yIAP/LhwD/y4cA/8yI + AP/QiwD/0YsA/8mGAP+5fAL/tncA/2dULP9HRkf/u2gL/9BwA//Kbgb/ym4G/8puBv/KbQb/ym0G/8pt + Bv/KbQb/ym0G/8ptBv/KbQb/ymwG/8psBv/KbAb/ymwG/8psBv/JbAb/yW0G/8lsBv/JbAb/yWsG/8lr + Bv/Jawb/yWsG/8lsBv/Jawb/yWoG/8lqBv/Jagb/yWoG/8lrBv/Jagb/yGkG/8hqBv/IaQb/yGkG/8hq + Bv/Iagb/yGkG/8hoBv/IaQb/yGkG/8hpBv/IaQb/yGkG/8hoBv/IaQb/ym0N/8JZAP/w4M7//////1TG + /P81vP7/Pb/+/z2//v89v/7/Pb/+/z2+/v89v/7/Pb/+/z2+/v89vf7/Pb7+/zy+/v87vv7/PL7+/zy+ + /v88vv7/PL7+/zy+/v88vv7/PL7+/zy+/v88vv7/PL7+/zu9/v87vf7/O73+/zu9/v87vf7/O73+/zu9 + /v87vf7/O73+/zu9/v87vf7/O73+/zu9/v86vP7/Obv+/zq8/v86vP7/Orz+/zq8/v86vP7/Orz+/zq8 + /v86vP7/Orz+/zq5+v83xf//Q2l7/1ZTUf/x8fH///////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////88///0Ur//9RU///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///VU//7z0//m3AR/4JX + AP9+UwD/kWYK/+/DSP//1FL//tJR///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9RT///TUv/LnzD/e1AA/4BW + AP+RZQn/3rI8///YVf/90VH//9NS///TUv//01L//tJR//7RUP/+0lH//9VU///aWf//01L/8L47/+Kp + JP/ZmxX/0Y8I/8qFAP/IgwD/y4YA/8yJAf/NiQH/zIkB/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/y4cA/8uHAP/NiAD/zYoC/9uQAP9kVjj/XUw7/8BoBf/ObAD/yWsA/8lrAP/JawD/yWsA/8lq + AP/JagD/yWoA/8lqAP/JagD/yWoA/8lpAP/JaQD/yWkA/8lpAP/JaQD/yWkA/8hpAP/IaQD/yGkA/8ho + AP/IaAD/yGgA/8hoAP/IaAD/yGgA/8hoAP/IZwD/yGcA/8hnAP/IZwD/yGcA/8hnAP/HZgD/x2YA/8dm + AP/HZgD/x2YA/8dmAP/HZQD/x2UA/8dlAP/HZQD/x2UA/8dlAP/HZQD/x2UA/8lpB//BVgD/8N/N//// + //9RxPz/MLr+/zm9/v84vf7/OL3+/zi9/v84vf7/OL3+/zi9/v84vf7/OLz+/zi8/v84vP7/N7z+/ze8 + /v83vP7/N7z+/ze8/v83vP7/N7z+/ze8/v83vP7/N7z+/ze8/v83vP7/N7z+/za7/v82u/7/Nrv+/za7 + /v82u/7/Nrv+/za7/v82u/7/Nrv+/za7/v82u/7/Nrv+/zW6/v81uv7/Nbr+/zW6/v81uv7/Nbr+/zW6 + /v81uv7/Nbr+/zW6/v81uPv/NL///0GDo/89QED/5+bl//////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////////////////PP//9FK///UVP//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//1VP/+89P/5tw + Ef+CVwD/flMA/5FmCv/vw0j//9RS//7SUf//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///UU///01L/y58w/3tQ + AP+AVgD/kWUJ/96yPP//2FX//dFR///SUf/+0VD//tJR///VVP//2Vn//9RT//G/PP/iqCP/2JoU/9GP + CP/KhgD/yYMA/8uGAP/MiAD/zYkB/8yJAf/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/y4cA/8uHAP/CgwX/V1A+/3ZTLv/GawL/zGwA/8prAP/KawD/yWsA/8lr + AP/JawD/yWoA/8lqAP/JagD/yWoA/8lqAP/JagD/yWkA/8lpAP/JaQD/yWkA/8lpAP/JaQD/yGkA/8hp + AP/IaQD/yGgA/8hoAP/IaAD/yGgA/8hoAP/IaAD/yGgA/8hnAP/IZwD/yGcA/8hnAP/IZwD/yGcA/8dm + AP/HZgD/x2YA/8dmAP/HZgD/x2YA/8dlAP/HZQD/x2UA/8dlAP/HZQD/x2UA/8dlAP/JaQf/wlcA//Df + zf//////UsT8/zG6/v85vf7/OL3+/zi9/v84vf7/OL3+/zi9/v84vf7/OL3+/zi9/v84vP7/OLz+/zi8 + /v83vP7/N7z+/ze8/v83vP7/N7z+/ze8/v83vP7/N7z+/ze8/v83vP7/N7z+/ze8/v83vP7/Nrv+/za7 + /v82u/7/Nrv+/za7/v82u/7/Nrv+/za7/v82u/7/Nrv+/za7/v82u/7/Nbr+/zW6/v81uv7/Nbr+/zW6 + /v81uv7/Nbr+/zW6/v81uv7/Nbn8/zS9//8+lsP/PkRI/8fEw/////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////zz///RSv//1FT//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9VT//vP + T/+bcBH/glcA/35TAP+RZgr/78NI///UUv/+0lH//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//1FP//9NS/8uf + MP97UAD/gFYA/5FlCf/esjz//9dU//zQT///1FP//9lY///VVP/ywD3/4agj/9eZEv/Rjwj/y4cA/8mD + AP/KhgD/zIgA/82JAf/MiQH/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8qHAf/PigD/sHoP/05MQ/+NWiL/ymwA/8tsAP/KawD/ymsA/8pr + AP/JawD/yWsA/8lrAP/JagD/yWoA/8lqAP/JagD/yWoA/8lqAP/JaQD/yWkA/8lpAP/JaQD/yWkA/8lp + AP/IaQD/yGkA/8hpAP/IaAD/yGgA/8hoAP/IaAD/yGgA/8hoAP/IaAD/yGcA/8hnAP/IZwD/yGcA/8hn + AP/IZwD/x2YA/8dmAP/HZgD/x2YA/8dmAP/HZgD/x2UA/8dlAP/HZQD/x2UA/8dlAP/HZQD/yWkH/8JX + AP/w383//////1HE/P8xuv7/Or3+/zi9/v84vf7/OL3+/zi9/v84vf7/OL3+/zi9/v84vf7/OL3+/zi8 + /v84vP7/OLz+/ze8/v83vP7/N7z+/ze8/v83vP7/N7z+/ze8/v83vP7/N7z+/ze8/v83vP7/N7z+/ze8 + /v82u/7/Nrv+/za7/v82u/7/Nrv+/za7/v82u/7/Nrv+/za7/v82u/7/Nrv+/za7/v81uv7/Nbr+/zW6 + /v81uv7/Nbr+/zW6/v81uv7/Nbr+/zW5/f81u///Oqjg/0BLUP+ppaP//v7+//////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////88///0Ur//9RU///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///V + U//7z0//m3AR/4JXAP9+UwD/kWYK/+/DSP//1FL//tJR///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9RT///T + Uv/LnzD/e1AA/4FWAP+QZQn/3rI9///cW///1FT/88E//+GoI//WlxH/0I8H/8uHAP/JhAD/yoYA/8yI + AP/NiQH/zIgB/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/KhwH/0osA/6FyF/9GSEj/oGAX/89tAP/KbAD/ymwA/8pr + AP/KawD/ymsA/8lrAP/JawD/yWsA/8lqAP/JagD/yWoA/8lqAP/JagD/yWoA/8lpAP/JaQD/yWkA/8lp + AP/JaQD/yWkA/8hpAP/IaQD/yGkA/8hoAP/IaAD/yGgA/8hoAP/IaAD/yGgA/8hoAP/IZwD/yGcA/8hn + AP/IZwD/yGcA/8hnAP/HZgD/x2YA/8dmAP/HZgD/x2YA/8dmAP/HZQD/x2UA/8dlAP/HZQD/x2UA/8lp + B//CVwD/8N/N//////9Rxfz/Mbr+/zq9/v85vf7/OL3+/zi9/v84vf7/OL3+/zi9/v84vf7/OL3+/zi9 + /v84vf7/OLz+/zi8/v84vP7/N7z+/ze8/v83vP7/N7z+/ze8/v83vP7/N7z+/ze8/v83vP7/N7z+/ze8 + /v83vP7/N7z+/za7/v82u/7/Nrv+/za7/v82u/7/Nrv+/za7/v82u/7/Nrv+/za7/v82u/7/Nrv+/zW6 + /v81uv7/Nbr+/zW6/v81uv7/Nbr+/zW6/v81uv3/Nbn8/ze3+f9BUFf/kIuJ//v7/P////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////PP//9FK///UVP//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//1VP/+89P/5twEf+CVwD/flMA/5FmCv/vw0j//9RS//7SUf//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//0lH/y58v/3xRAP+BVgD/kWYK/9emLf/prib/05QP/8+NB//LiAD/yoQA/8qGAP/MiAD/zIkB/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/yYcB/9SMAP+TbB7/QUZK/69kD//RbgD/yWwA/8ps + AP/KbAD/ymsA/8prAP/KawD/yWsA/8lrAP/JawD/yWoA/8lqAP/JagD/yWoA/8lqAP/JagD/yWkA/8lp + AP/JaQD/yWkA/8lpAP/JaQD/yGkA/8hpAP/IaQD/yGgA/8hoAP/IaAD/yGgA/8hoAP/IaAD/yGgA/8hn + AP/IZwD/yGcA/8hnAP/IZwD/yGcA/8dmAP/HZgD/x2YA/8dmAP/HZgD/x2YA/8dlAP/HZQD/x2UA/8dl + AP/JaQf/wlcA//Dfzf//////UcX8/zG7/v86vf7/Ob3+/zm9/v84vf7/OL3+/zi9/v84vf7/OL3+/zi9 + /v84vf7/OL3+/zi9/v84vP7/OLz+/zi8/v83vP7/N7z+/ze8/v83vP7/N7z+/ze8/v83vP7/N7z+/ze8 + /v83vP7/N7z+/ze8/v83vP7/Nrv+/za7/v82u/7/Nrv+/za7/v82u/7/Nrv+/za7/v82u/7/Nrv+/za7 + /v82u/7/Nbr+/zW6/v81uv7/Nbr+/zW6/v81uv7/Nbr+/zW4+v81wv//QlZh/3t2c//5+fn///////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////zz///RSv//1FT//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9VT//vPT/+bcBH/glcA/35TAP+RZgr/78NI///UUv/+0lH//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9JR//7S + Uf//1VT//9ZV/8ugM/93TQD/g1kB/4RZAf+XZwT/r3UA/8SBAP/QiQD/zYgA/8yIAP/LiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8mHAv/WjQD/iGYk/0hHR/+0Zgz/0W4A/8ls + AP/KbAD/ymwA/8psAP/KawD/ymsA/8prAP/JawD/yWsA/8lrAP/JagD/yWoA/8lqAP/JagD/yWoA/8lq + AP/JaQD/yWkA/8lpAP/JaQD/yWkA/8lpAP/IaQD/yGkA/8hpAP/IaAD/yGgA/8hoAP/IaAD/yGgA/8ho + AP/IaAD/yGcA/8hnAP/IZwD/yGcA/8hnAP/IZwD/x2YA/8dmAP/HZgD/x2YA/8dmAP/HZgD/x2UA/8dl + AP/HZQD/yWkH/8JXAP/w383//////1HF/P8xvP7/Or7+/zm9/v85vf7/Ob3+/zi9/v84vf7/OL3+/zi9 + /v84vf7/OL3+/zi9/v84vf7/OL3+/zi8/v84vP7/OLz+/ze8/v83vP7/N7z+/ze8/v83vP7/N7z+/ze8 + /v83vP7/N7z+/ze8/v83vP7/N7z+/ze8/v82u/7/Nrv+/za7/v82u/7/Nrv+/za7/v82u/7/Nrv+/za7 + /v82u/7/Nrv+/za7/v81uv7/Nbr+/zW6/v81uv7/Nbr+/zW6/v81uPr/NcP//0Jhcf9qZ2X/9/f3//// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////88///0Ur//9RU///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///VU//7z0//m3AR/4JXAP9+UwD/kWYK/+/DSP//1FL//tJR///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9RT///V + Vf//1VT/8L05/+ClIP/MjAf/sXYA/5ZkAP+DVwD/f1QA/4NXAP+IWwD/mGUA/691AP/IhQD/0IsA/82I + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/JhgL/2Y4A/3lfK/9SSkH/uWgJ/89t + AP/JbAD/ymwA/8psAP/KbAD/ymwA/8prAP/KawD/ymsA/8lrAP/JawD/yWsA/8lqAP/JagD/yWoA/8lq + AP/JagD/yWoA/8lpAP/JaQD/yWkA/8lpAP/JaQD/yWkA/8hpAP/IaQD/yGkA/8hoAP/IaAD/yGgA/8ho + AP/IaAD/yGgA/8hoAP/IZwD/yGcA/8hnAP/IZwD/yGcA/8hnAP/HZgD/x2YA/8dmAP/HZgD/x2YA/8dm + AP/HZQD/x2UA/8lpB//CVwD/8N/N//////9Rxfz/Mbv+/zq+/v85vv7/Ob3+/zm9/v85vf7/OL3+/zi9 + /v84vf7/OL3+/zi9/v84vf7/OL3+/zi9/v84vf7/OLz+/zi8/v84vP7/N7z+/ze8/v83vP7/N7z+/ze8 + /v83vP7/N7z+/ze8/v83vP7/N7z+/ze8/v83vP7/N7z+/za7/v82u/7/Nrv+/za7/v82u/7/Nrv+/za7 + /v82u/7/Nrv+/za7/v82u/7/Nrv+/zW6/v81uv7/Nbr+/zW6/v81uv7/Nbj7/zTA//9CcYn/VFRT//X0 + 9P////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////PP//9FK///UVP//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//1VP/+89P/5twEf+CVwD/flMA/5FmCv/vw0j//9RS//7SUf//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///UU///1FP//9VU//G+ + Ov/gpiH/0ZAI/82KAv/MiAD/zIcA/8yIAP/KhwD/xoQA/7F2AP+UYwD/glcA/4BWAP+DWAD/h1oA/5hl + AP+wdQD/yYYA/8+KAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/yIYC/9qPAP9vWzL/VUlA/7xp + CP/PbgD/yWwA/8psAP/KbAD/ymwA/8psAP/KbAD/ymsA/8prAP/KawD/yWsA/8lrAP/JawD/yWoA/8lq + AP/JagD/yWoA/8lqAP/JagD/yWkA/8lpAP/JaQD/yWkA/8lpAP/JaQD/yGkA/8hpAP/IaQD/yGgA/8ho + AP/IaAD/yGgA/8hoAP/IaAD/yGgA/8hnAP/IZwD/yGcA/8hnAP/IZwD/yGcA/8dmAP/HZgD/x2YA/8dm + AP/HZgD/x2YA/8dlAP/JaQf/wlcA//Dfzf//////UcX8/zG7/v86vv7/Ob7+/zm+/v85vf7/Ob3+/zm9 + /v84vf7/OL3+/zi9/v84vf7/OL3+/zi9/v84vf7/OL3+/zi9/v84vP7/OLz+/zi8/v83vP7/N7z+/ze8 + /v83vP7/N7z+/ze8/v83vP7/N7z+/ze8/v83vP7/N7z+/ze8/v83vP7/Nrv+/za7/v82u/7/Nrv+/za7 + /v82u/7/Nrv+/za7/v82u/7/Nrv+/za7/v82u/7/Nbr+/zW6/v81uv7/Nbr+/zW4+/80wP//QXeU/0pK + S//08/L///////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////zz///RSv//1FT//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9VT//vPT/+bcBH/glcA/35TAP+RZgr/78NI///UUv/+0lH//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///UU///1FP//9NS///UU//xvzz/4aYi/9GP + CP/NiQH/zIgA/8uHAP/LhwD/zIgA/8yIAP/MiAD/zYkA/82JAP/MiAD/y4gA/8aEAP+vdQD/k2IA/4NY + AP+BVgD/glcA/4VZAP+ZZQD/sXYA/8mGAP/NiQD/zIgA/82IAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8iGAv/bjwD/aFg1/1tM + PP+/agb/zm4A/8lsAP/KbAD/ymwA/8psAP/KbAD/ymwA/8psAP/KawD/ymsA/8prAP/JawD/yWsA/8lr + AP/JagD/yWoA/8lqAP/JagD/yWoA/8lqAP/JaQD/yWkA/8lpAP/JaQD/yWkA/8lpAP/IaQD/yGkA/8hp + AP/IaAD/yGgA/8hoAP/IaAD/yGgA/8hoAP/IaAD/yGcA/8hnAP/IZwD/yGcA/8hnAP/IZwD/x2YA/8dm + AP/HZgD/x2YA/8dmAP/HZgD/yWkH/8JWAP/w383//////1HF/P8xu/7/Or7+/zm+/v85vv7/Ob7+/zm9 + /v85vf7/Ob3+/zi9/v84vf7/OL3+/zi9/v84vf7/OL3+/zi9/v84vf7/OL3+/zi8/v84vP7/OLz+/ze8 + /v83vP7/N7z+/ze8/v83vP7/N7z+/ze8/v83vP7/N7z+/ze8/v83vP7/N7z+/ze8/v82u/7/Nrv+/za7 + /v82u/7/Nrv+/za7/v82u/7/Nrv+/za7/v82u/7/Nrv+/za7/v81uv7/Nbr+/zW6/v81uPv/NL///0GA + of8/QEH/8/Hx//////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////88///0Ur//9RU///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///VU//7z0//m3AR/4JXAP9+UwD/kWYK/+/DSP//1FL//tJR///T + Uv//01L//9NS///TUv//01L//9NS///UU///1FP//9RT//7SUf//01L/8sA9/+GnIv/Rjwj/zIgA/8yI + AP/LhwD/zIcA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/82IAP/NiQD/zIgA/82I + AP/GhAD/rnQA/5JiAP+EWAD/glcA/4FXAP+EWAD/mWYA/7F2AP/JhgD/zIgA/8yIAP/NiQD/zYkA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/IhQH/244A/2hX + Nf9cTDz/v2oG/85uAP/JbQD/ymwA/8psAP/KbAD/ymwA/8psAP/KbAD/ymwA/8prAP/KawD/ymsA/8lr + AP/JawD/yWsA/8lqAP/JagD/yWoA/8lqAP/JagD/yWoA/8lpAP/JaQD/yWkA/8lpAP/JaQD/yWkA/8hp + AP/IaQD/yGkA/8hoAP/IaAD/yGgA/8hoAP/IaAD/yGgA/8hoAP/IZwD/yGcA/8hnAP/IZwD/yGcA/8hn + AP/HZgD/x2YA/8dmAP/HZgD/x2YA/8lqB//CVwD/8N/N//////9Rxfz/Mbv+/zq+/v85vv7/Ob7+/zm+ + /v85vv7/Ob3+/zm9/v85vf7/OL3+/zi9/v84vf7/OL3+/zi9/v84vf7/OL3+/zi9/v84vf7/OLz+/zi8 + /v84vP7/N7z+/ze8/v83vP7/N7z+/ze8/v83vP7/N7z+/ze8/v83vP7/N7z+/ze8/v83vP7/N7z+/za7 + /v82u/7/Nrv+/za7/v82u/7/Nrv+/za7/v82u/7/Nrv+/za7/v82u/7/Nrv+/zW6/v81uv7/Nbj7/zS/ + //9BgKL/PkBB//Px8f////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////PP//9FK///U + VP//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//1VP/+89P/5twEf+CVwD/flMA/5FmCv/vw0j//9RS//7S + Uf//01L//9NS///TUv//1FP//9VU///UU//+0VD//tJQ//PBPv/iqCP/0ZAI/8uHAP/LhwD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/OiQD/xoQA/6xzAP+SYgD/hVkA/4JXAP+AVgD/g1cA/5pmAP+ydwD/yYYA/8qH + AP/MiAD/zokA/82JAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIcA/8uGAP/MhwD/yYcD/+GX + AP9qWjj/XEs7/79qBv/ObgD/yW0A/8ptAP/KbAD/ymwA/8psAP/KbAD/ymwA/8psAP/KbAD/ymsA/8pr + AP/KawD/yWsA/8lrAP/JawD/yWoA/8lqAP/JagD/yWoA/8lqAP/JagD/yWkA/8lpAP/JaQD/yWkA/8lp + AP/JaQD/yGkA/8hpAP/IaQD/yGgA/8hoAP/IaAD/yGgA/8hoAP/IaAD/yGgA/8hnAP/IZwD/yGcA/8hn + AP/IZwD/yGcA/8dmAP/HZgD/x2YA/8dmAP/Jagf/wlgA//Dfzf//////UcX8/zG7/v86vv7/Ob7+/zm+ + /v85vv7/Ob7+/zm+/v85vf7/Ob3+/zm9/v84vf7/OL3+/zi9/v84vf7/OL3+/zi9/v84vf7/OL3+/zi9 + /v84vP7/OLz+/zi8/v83vP7/N7z+/ze8/v83vP7/N7z+/ze8/v83vP7/N7z+/ze8/v83vP7/N7z+/ze8 + /v83vP7/Nrv+/za7/v82u/7/Nrv+/za7/v82u/7/Nrv+/za7/v82u/7/Nrv+/za7/v82u/7/Nbr+/zW4 + +/80v///QYGi/z9AQf/z8fH///////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////zz///R + Sv//1FT//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9VT//vPT/+bcBH/glcA/35TAP+RZgr/78NI///T + Uv/+0lH//9RT///VVP//1VT//tFQ//3QT//zwj//4qkk/9GQCf/KhgD/y4cA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/NiQD/z4oA/8WEAP+rcgD/k2IA/4daAP+CVwD/flUA/4JX + AP+bZwD/s3gA/8iFAP/JhgD/y4cA/8qFAP/LhwD/zIgA/82JAP/OigD/zYkA/82KAv/Qjgb/258Z/+ez + M///4lH/dm5P/2VJLv/EbAX/zW4A/8ptAP/KbQD/ym0A/8psAP/KbAD/ymwA/8psAP/KbAD/ymwA/8ps + AP/KawD/ymsA/8prAP/JawD/yWsA/8lrAP/JagD/yWoA/8lqAP/JagD/yWoA/8lqAP/JaQD/yWkA/8lp + AP/JaQD/yWkA/8lpAP/IaQD/yGkA/8hpAP/IaAD/yGgA/8hoAP/IaAD/yGgA/8hoAP/IaAD/yGcA/8hn + AP/IZwD/yGcA/8hnAP/IZwD/x2YA/8dmAP/HZgD/yWoH/8JYAP/w383//////1HF/P8xu/7/Or7+/zm+ + /v85vv7/Ob7+/zm+/v85vv7/Ob7+/zm9/v85vf7/Ob3+/zi9/v84vf7/OL3+/zi9/v84vf7/OL3+/zi9 + /v84vf7/OL3+/zi8/v84vP7/OLz+/ze8/v83vP7/N7z+/ze8/v83vP7/N7z+/ze8/v83vP7/N7z+/ze8 + /v83vP7/N7z+/ze8/v82u/7/Nrv+/za7/v82u/7/Nrv+/za7/v82u/7/Nrv+/za7/v82u/7/Nrv+/za7 + /v82ufz/NL7//z+Irf8+QUP/8/Hw//////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////////8 + 8///0Ur//9RU///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///VU//7z0//m3AR/4JXAP9+UwD/kWYK//DE + Sf//1lX//9VU//3RT//8z03/9MNA/+OqJf/SkQr/yoUA/8uGAP/MiAD/zIkB/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8uIAP/MiAD/zokA/9CKAP/FgwD/qnEA/5Rj + AP+JWwD/glcA/31UAP+BVQD/om8F/9SYFf/Qjgb/zosD/8yIAP/KhwD/xYMA/7d6Af/WoiX//9VS///a + Wv/70FP//91M/3JpSv9nSi//xGwF/81uAP/KbQD/ym0A/8ptAP/KbQD/ymwA/8psAP/KbAD/ymwA/8ps + AP/KbAD/ymwA/8prAP/KawD/ymsA/8lrAP/JawD/yWsA/8lqAP/JagD/yWoA/8lqAP/JagD/yWoA/8lp + AP/JaQD/yWkA/8lpAP/JaQD/yWkA/8hpAP/IaQD/yGkA/8hoAP/IaAD/yGgA/8hoAP/IaAD/yGgA/8ho + AP/IZwD/yGcA/8hnAP/IZwD/yGcA/8hnAP/HZgD/x2YA/8lqB//CWAD/8N/N//////9Sxfz/Mbv+/zq+ + /v85vv7/Ob7+/zm+/v85vv7/Ob7+/zm+/v85vv7/Ob3+/zm9/v85vf7/OL3+/zi9/v84vf7/OL3+/zi9 + /v84vf7/OL3+/zi9/v84vf7/OLz+/zi8/v84vP7/N7z+/ze8/v83vP7/N7z+/ze8/v83vP7/N7z+/ze8 + /v83vP7/N7z+/ze8/v83vP7/N7z+/za7/v82u/7/Nrv+/za7/v82u/7/Nrv+/za7/v82u/7/Nrv+/za7 + /v82u/7/Nrr8/zW9//8+j7f/PkJE//Px8P////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////PP//9FK///UVP//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//1VP/+89P/5xwEf+CVwD/flMA/5Jm + Cv/xw0b//c5M//PCP//jqiX/05MM/8mEAP/LhgD/zIgA/82JAf/MiQH/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8uIAP/LhwD/zIgA/86K + AP/RiwD/xIMA/6pxAf+WZAH/hFYA/5BkB//xxkv//dBO/++5NP/PlRb/nGcA/4hbAP+BWAP/1qo3///Z + U//0xEP/57M0/+umEf9oWjr/ak4z/8RsBP/NbgD/yW0A/8ptAP/KbQD/ym0A/8ptAP/KbAD/ymwA/8ps + AP/KbAD/ymwA/8psAP/KbAD/ymsA/8prAP/KawD/yWsA/8lrAP/JawD/yWoA/8lqAP/JagD/yWoA/8lq + AP/JagD/yWkA/8lpAP/JaQD/yWkA/8lpAP/JaQD/yGkA/8hpAP/IaQD/yGgA/8hoAP/IaAD/yGgA/8ho + AP/IaAD/yGgA/8hnAP/IZwD/yGcA/8hnAP/IZwD/yGcA/8dmAP/Jagf/wlgA//Dfzf//////UsX8/zK7 + /v86vv7/Ob7+/zm+/v85vv7/Ob7+/zm+/v85vv7/Ob7+/zm+/v85vf7/Ob3+/zm9/v84vf7/OL3+/zi9 + /v84vf7/OL3+/zi9/v84vf7/OL3+/zi9/v84vP7/OLz+/zi8/v83vP7/N7z+/ze8/v83vP7/N7z+/ze8 + /v83vP7/N7z+/ze8/v83vP7/N7z+/ze8/v83vP7/Nrv+/za7/v82u/7/Nrv+/za7/v82u/7/Nrv+/za7 + /v82u/7/Nrv+/za6/P82vv//P463/z5CRP/z8fD///////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////zz///RSv//1FT//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv/+0lH//9RT//zRUf+acBL/gVYA/4BV + AP+OYgb/zpoh/9CRDf/LhQD/zogA/82JAP/MiQH/zIgB/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAH/y4gB/8uHAP/NhwD/z4kA/8GCAf+6hRL/8sZI//3RUP//417/1q08/25EAP+FWgL/h1sC/8CO + HP/gpB//zYkA/8iDAP/cjwD/Zlc2/2pPNP/EawT/zm4A/8ptAP/KbQD/ym0A/8ptAP/KbQD/ym0A/8ps + AP/KbAD/ymwA/8psAP/KbAD/ymwA/8psAP/KawD/ymsA/8prAP/JawD/yWsA/8lrAP/JagD/yWoA/8lq + AP/JagD/yWoA/8lqAP/JaQD/yWkA/8lpAP/JaQD/yWkA/8lpAP/IaQD/yGkA/8hpAP/IaAD/yGgA/8ho + AP/IaAD/yGgA/8hoAP/IaAD/yGcA/8hnAP/IZwD/yGcA/8hnAP/IZwD/yGoH/8JYAP/w383//////1LF + /P8yu/7/Or7+/zm+/v85vv7/Ob7+/zm+/v85vv7/Ob7+/zm+/v85vv7/Ob7+/zm9/v85vf7/Ob3+/zi9 + /v84vf7/OL3+/zi9/v84vf7/OL3+/zi9/v84vf7/OL3+/zi8/v84vP7/OLz+/ze8/v83vP7/N7z+/ze8 + /v83vP7/N7z+/ze8/v83vP7/N7z+/ze8/v83vP7/N7z+/ze8/v82u/7/Nrv+/za7/v82u/7/Nrv+/za7 + /v82u/7/Nrv+/za7/v82uvz/Nb7//0CPt/8+QkT/8/Hw//////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////88///0Ur//9RU///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//tJR///TUv//1VT//9dX///XVv/4y0r/oXMO/4NY + AP9+VQD/flQA/4RXAP+eaQD/tnsC/8GBAf/IhgD/0IoA/9CLAP/NiQD/y4gA/8uHAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIkB/82J + Af/LhwD/yoQA/8mEAP/OiwT/0pIL/9qeGf/rtTH//c9K///aWf/+0lL//9NO/9OjK/+CVAD/hlsC/35U + AP+GVwD/m2YA/7Z6Af+/gQT/2Y4A/2ZXN/9qTzT/xGsE/85uAP/LbQD/ym0A/8ptAP/KbQD/ym0A/8pt + AP/KbQD/ymwA/8psAP/KbAD/ymwA/8psAP/KbAD/ymwA/8prAP/KawD/ymsA/8lrAP/JawD/yWsA/8lq + AP/JagD/yWoA/8lqAP/JagD/yWoA/8lpAP/JaQD/yWkA/8lpAP/JaQD/yWkA/8hpAP/IaQD/yGkA/8ho + AP/IaAD/yGgA/8hoAP/IaAD/yGgA/8hoAP/IZwD/yGcA/8hnAP/IZwD/yGcA/8lrB//CWAD/8N/N//// + //9Sxfz/Mrv+/zu+/v85vv7/Ob7+/zm+/v85vv7/Ob7+/zm+/v85vv7/Ob7+/zm+/v85vv7/Ob3+/zm9 + /v85vf7/OL3+/zi9/v84vf7/OL3+/zi9/v84vf7/OL3+/zi9/v84vf7/OLz+/zi8/v84vP7/N7z+/ze8 + /v83vP7/N7z+/ze8/v83vP7/N7z+/ze8/v83vP7/N7z+/ze8/v83vP7/N7z+/za7/v82u/7/Nrv+/za7 + /v82u/7/Nrv+/za7/v82u/7/Nrr8/zW+//9Aj7f/PkJE//Px8P////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////////////////PP//9FK///UVP//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS//7SUf//0lH//9RU///YV///1lb//M5N//XEQf/stzP/3qIc/8KB + Af+rcgD/mGUA/41eAP+FWQH/elIB/3pRAP+HWgD/oGsA/7V5AP+/fwD/yIYA/9CLAP/QiwD/zYkA/8uH + AP/LhwD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/82JAf/NiQH/y4cA/8qE + AP/JgwD/zosD/9SUDP/coBr/6rQx//rMSv//32D//9hY//nLSv/ywD7/6bMv/9qcFf/NiQH/wIAA/6dw + AP+YZQD/jF4B/4BWAf94UAD/g1gC/6xwAP9dUTb/bVI0/8RsBP/ObgD/y20A/8ttAP/KbQD/ym0A/8pt + AP/KbQD/ym0A/8ptAP/KbAD/ymwA/8psAP/KbAD/ymwA/8psAP/KbAD/ymsA/8prAP/KawD/yWsA/8lr + AP/JawD/yWoA/8lqAP/JagD/yWoA/8lqAP/JagD/yWkA/8lpAP/JaQD/yWkA/8lpAP/JaQD/yGkA/8hp + AP/IaQD/yGgA/8hoAP/IaAD/yGgA/8hoAP/IaAD/yGgA/8hnAP/IZwD/yGcA/8hnAP/Kawf/wlgA//Df + zf//////Usb8/zK8/v87vv7/Or7+/zm+/v85vv7/Ob7+/zm+/v85vv7/Ob7+/zm+/v85vv7/Ob7+/zm+ + /v85vf7/Ob3+/zm9/v84vf7/OL3+/zi9/v84vf7/OL3+/zi9/v84vf7/OL3+/zi9/v84vP7/OLz+/zi8 + /v83vP7/N7z+/ze8/v83vP7/N7z+/ze8/v83vP7/N7z+/ze8/v83vP7/N7z+/ze8/v83vP7/Nrv+/za7 + /v82u/7/Nrv+/za7/v82u/7/Nrv+/za6/P81vv//QI+3/z5CRP/z8fD///////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////zz///RSv//1FT//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv/+0lH//tJR///UU///2Ff//9dX//zOTf/0wkD/67Uy/9+jHv/PjAX/yIIA/8mD + AP/OiQD/0YsA/9CLAP+9fgD/q3IA/5tnAP+PYAD/g1gA/3lRAP96UgD/iFsA/6BrAP+0eAD/vn8A/8mG + AP/RiwD/0IsA/82IAP/LhwD/y4cA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/NiQH/zYkB/8yHAP/KhQD/yIMA/86L + A//UlQ7/3aEb/+q0MP/5ykj//+Bg///aWv/6zEv/8b06/+ixLP/anRf/zYgA/8iCAP/JhAD/zIcA/9CL + AP/RiwD/z4oA/75/AP+pcQD/m2cA/4teAv+EVQD/T0g2/3BUNP/DbAT/zm4A/8ttAP/LbQD/y20A/8pt + AP/KbQD/ym0A/8ptAP/KbQD/ym0A/8psAP/KbAD/ymwA/8psAP/KbAD/ymwA/8psAP/KawD/ymsA/8pr + AP/JawD/yWsA/8lrAP/JagD/yWoA/8lqAP/JagD/yWoA/8lqAP/JaQD/yWkA/8lpAP/JaQD/yWkA/8lp + AP/IaQD/yGkA/8hpAP/IaAD/yGgA/8hoAP/IaAD/yGgA/8hoAP/IaAD/yGcA/8hnAP/IZwD/yWsH/8NZ + AP/w4M3//////1LG/P8yvf7/O7/+/zq+/v86vv7/Ob7+/zm+/v85vv7/Ob7+/zm+/v85vv7/Ob7+/zm+ + /v85vv7/Ob7+/zm9/v85vf7/Ob3+/zi9/v84vf7/OL3+/zi9/v84vf7/OL3+/zi9/v84vf7/OL3+/zi8 + /v84vP7/OLz+/ze8/v83vP7/N7z+/ze8/v83vP7/N7z+/ze8/v83vP7/N7z+/ze8/v83vP7/N7z+/ze8 + /v82u/7/Nrv+/za7/v82u/7/Nrv+/za7/v82uvz/Nb7//0CPt/8+QkT/8/Hw//////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////88///0Ur//9RU///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//tJR//7SUf//1FP//9hX///YV//8z03/88E+/+q0MP/fox7/0I4G/8iCAP/IggD/yYQA/8qF + AP/Qjwj/xoUC/8yIAP/QiwD/0IsA/9KMAP/PigD/vX4A/6xyAP+caAD/kGAA/4JXAP94UAD/elIA/4pc + AP+hbAD/sncA/71+AP/KhwD/0owA/9CLAP/MiAD/y4cA/8uHAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zYkB/82JAv/MiAD/yoUA/8iCAP/NigL/1ZUO/96i + HP/qtDD/+MlH///fX///3Fv/+81L//C8Of/nryv/250X/82JAf/IggD/yYQA/8mEAP/JhAD/1JML/86P + C/+9fQD/zYkA/9GLAP/PigD/0owA/86JAP+6fQL/tHUA/1tPNv9tUjT/xGwE/85vAP/LbQD/y20A/8tt + AP/LbQD/ym0A/8ptAP/KbQD/ym0A/8ptAP/KbQD/ymwA/8psAP/KbAD/ymwA/8psAP/KbAD/ymwA/8pr + AP/KawD/ymsA/8lrAP/JawD/yWsA/8lqAP/JagD/yWoA/8lqAP/JagD/yWoA/8lpAP/JaQD/yWkA/8lp + AP/JaQD/yWkA/8hpAP/IaQD/yGkA/8hoAP/IaAD/yGgA/8hoAP/IaAD/yGgA/8hoAP/IZwD/yGcA/8pr + B//DWQD/8ODN//////9Sxvz/Mrz+/zu//v86vv7/Or7+/zq+/v85vv7/Ob7+/zm+/v85vv7/Ob7+/zm+ + /v85vv7/Ob7+/zm+/v85vv7/Ob3+/zm9/v85vf7/OL3+/zi9/v84vf7/OL3+/zi9/v84vf7/OL3+/zi9 + /v84vf7/OLz+/zi8/v84vP7/N7z+/ze8/v83vP7/N7z+/ze8/v83vP7/N7z+/ze8/v83vP7/N7z+/ze8 + /v83vP7/N7z+/za7/v82u/7/Nrv+/za7/v82u/7/Nrr8/zW+//9Aj7f/PkJE//Px8P////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////PP//9FK///UVP//01L//9NS///TUv//01L//9NS//7S + Uf/+0lD//9NS///XV///2Vj//dBO//PAPv/psi7/36Me/9GPCP/JgwD/yIIA/8mEAP/JhAD/0Y8I/9mb + FP/krCb/67g2/6h3Df+lbgD/tHgA/8CAAP/NiQD/0YsA/9CLAP/SjAD/zokA/7x9AP+tcwD/nWkA/5Bg + AP+AVgD/d1AA/3tSAP+LXQD/oWwA/7F2AP+8fQD/y4cA/9KMAP/QiwD/zIgA/8qHAP/LiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yJAf/NigL/zIgA/8qFAP/IggD/zIkB/9WWD//epB7/6rQx//fI + Rf//3l7//91d//vNTP/vuzj/5a0p/9ueGP/OigP/yIIA/8mDAP/JhAD/yYQA/9GQCf/ZmxT/4acj//rH + Qf/TpS//hlUA/6pyAv+2eQD/wYAA/82JAP/RiwD/zIkC/+KTAP9nWDb/alA0/8RsBP/ObwD/y24A/8tt + AP/LbQD/y20A/8ttAP/KbQD/ym0A/8ptAP/KbQD/ym0A/8ptAP/KbAD/ymwA/8psAP/KbAD/ymwA/8ps + AP/KbAD/ymsA/8prAP/KawD/yWsA/8lrAP/JawD/yWoA/8lqAP/JagD/yWoA/8lqAP/JagD/yWkA/8lp + AP/JaQD/yWkA/8lpAP/JaQD/yGkA/8hpAP/IaQD/yGgA/8hoAP/IaAD/yGgA/8hoAP/IaAD/yGgA/8hn + AP/Kawf/w1kA//Dgzf//////Usb8/zK9/v87v/7/Or/+/zq+/v86vv7/Or7+/zm+/v85vv7/Ob7+/zm+ + /v85vv7/Ob7+/zm+/v85vv7/Ob7+/zm+/v85vf7/Ob3+/zm9/v84vf7/OL3+/zi9/v84vf7/OL3+/zi9 + /v84vf7/OL3+/zi9/v84vP7/OLz+/zi8/v83vP7/N7z+/ze8/v83vP7/N7z+/ze8/v83vP7/N7z+/ze8 + /v83vP7/N7z+/ze8/v83vP7/Nrv+/za7/v82u/7/Nrv+/za6/P81vv//QI+3/z5CRP/z8fD///////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////zz///RSv//1FT//9NS///TUv/+0lH//tFQ///T + Uv//11f//9lZ//7RT//zwD3/6LEt/96jHf/SkAn/yYMA/8iCAP/JgwD/yYQA/9COB//ZnBX/5Kwn/++8 + Of/6zEr//9xc//7TVP+ZbxL/e1IA/4JXAP+SYgD/pW4A/7J3AP/BgAD/zokA/9GLAP/QiwD/0owA/8yI + AP+8fQD/rnQA/55qAP+PYAD/f1QA/3dPAP97UwD/jV4A/6FrAP+vdQD/vH0A/8yIAP/TjAD/zokA/8yI + AP/NigL/zYkB/8yIAP/LhwD/y4cA/8uHAP/LhgD/yIIA/8yIAP/Vlg//36Uf/+q1Mf/2x0T//9xc///f + X//8zk3/7ro3/+SsJ//bnRj/z4wE/8iDAP/JgwD/yYQA/8iDAP/Rjwj/2pwW/+OqJf/wvDr/+81L///X + WP//4V3/1ao3/3FHAP9/VgP/g1cA/5RjAP+lbgD/tXgA/71/Av/fkgD/aFg2/2pQNP/EbAT/zm8A/8tu + AP/LbgD/y24A/8ttAP/LbQD/y20A/8ptAP/KbQD/ym0A/8ptAP/KbQD/ym0A/8psAP/KbAD/ymwA/8ps + AP/KbAD/ymwA/8psAP/KawD/ymsA/8prAP/JawD/yWsA/8lrAP/JagD/yWoA/8lqAP/JagD/yWoA/8lq + AP/JaQD/yWkA/8lpAP/JaQD/yWkA/8lpAP/IaQD/yGkA/8hpAP/IaAD/yGgA/8hoAP/IaAD/yGgA/8ho + AP/IaAD/ymsH/8NZAP/w4M3//////1LG/P8yvf7/O7/+/zq//v86v/7/Or7+/zq+/v86vv7/Ob7+/zm+ + /v85vv7/Ob7+/zm+/v85vv7/Ob7+/zm+/v85vv7/Ob7+/zm9/v85vf7/Ob3+/zi9/v84vf7/OL3+/zi9 + /v84vf7/OL3+/zi9/v84vf7/OL3+/zi8/v84vP7/OLz+/ze8/v83vP7/N7z+/ze8/v83vP7/N7z+/ze8 + /v83vP7/N7z+/ze8/v83vP7/N7z+/ze8/v82u/7/Nrv+/za7/v82uvz/Nb7//0CPt/8+QkT/8/Hw//// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////88///0Ur//tJT//7RUP//01L//9dW///a + Wf/+0lH/88A9/+ewK//eoh3/05IK/8qEAP/IggD/yYMA/8mDAP/Qjgb/2pwW/+WtKP/wvDr/+ctJ///a + Wv//2Ff//9RT///TUf/6zk7/nHER/4NXAP+DWAD/f1UA/3xTAP+CVwD/k2IA/6RtAP+xdgD/wYEA/8+K + AP/RiwD/0IoA/9KMAP/KhwD/vH0A/690AP+fagD/j18A/31TAP92TwD/fFMA/45fAP+gawD/rnQA/8KE + BP/MiAD/x4EA/8qFAP/MiAD/z4oA/9KMAP/QiwH/05MN/+CmIP/rtjL/9sZD///bWv//4GD//dBO/+66 + N//jqiX/250X/9CNBf/JgwD/yIMA/8mEAP/IggD/0Y4H/9qdF//kqyf/8L06//rMSv//2Vn//9dX///U + U//8z0///9xY/9WpNv91SgD/h1wC/4JXAP9/VQD/fFMA/4RYAP+QYQL/snQA/15SNv9sUTT/xGwE/85v + AP/LbgD/y24A/8tuAP/LbgD/y20A/8ttAP/LbQD/ym0A/8ptAP/KbQD/ym0A/8ptAP/KbQD/ymwA/8ps + AP/KbAD/ymwA/8psAP/KbAD/ymwA/8prAP/KawD/ymsA/8lrAP/JawD/yWsA/8lqAP/JagD/yWoA/8lq + AP/JagD/yWoA/8lpAP/JaQD/yWkA/8lpAP/JaQD/yWkA/8hpAP/IaQD/yGkA/8hoAP/IaAD/yGgA/8ho + AP/IaAD/yGgA/8psB//DWQD/8ODN//////9Sxvz/Mr3+/zu//v86v/7/Or/+/zq//v86vv7/Or7+/zq+ + /v85vv7/Ob7+/zm+/v85vv7/Ob7+/zm+/v85vv7/Ob7+/zm+/v85vv7/Ob3+/zm9/v85vf7/OL3+/zi9 + /v84vf7/OL3+/zi9/v84vf7/OL3+/zi9/v84vf7/OLz+/zi8/v84vP7/N7z+/ze8/v83vP7/N7z+/ze8 + /v83vP7/N7z+/ze8/v83vP7/N7z+/ze8/v83vP7/N7z+/za7/v82u/7/Nrr8/zW+//9Aj7f/PkJE//Px + 8P////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////PP//9JN///XWP//2ln//9NS//PB + Pv/mrir/3aEb/9OSC//KhQD/yIIA/8mDAP/IgwD/z4wF/9qdFv/mrin/8L07//nKSP//2Vj//9hY///U + VP/+0VD//tJQ//7SUf//1VP/+89P/5twEf+BVgD/g1gA/4NYAP+EWAD/glcA/35VAP98UwD/g1gA/5Ni + AP+ibQD/sHYA/8KCAP/QiwD/0YwA/9CKAP/SjAD/yYYA/7x9AP+wdQD/n2oA/45fAP97UgD/dk8A/35V + Af+tfhX/8Ls2/+KpJP/XmBH/yYYA/8CAAf+qcAD/p3MH/96uNP//3Fv//99g//7RUP/vujf/4qgj/9qd + F//Qjgb/yYQA/8mDAP/JhAD/yIIA/9CNBv/bnhf/5a0p//G9O//6zEr//9hY///YV///1FP//tFQ//7S + Uf//0lH//dFR///eWf/VqTb/dEkA/4ZbAv+CVwD/g1gA/4RYAP+CVwD/fFQC/4RVAP9RSTb/cFQ0/8Ns + BP/ObwD/y24A/8tuAP/LbgD/y24A/8tuAP/LbQD/y20A/8ttAP/KbQD/ym0A/8ptAP/KbQD/ym0A/8pt + AP/KbAD/ymwA/8psAP/KbAD/ymwA/8psAP/KbAD/ymsA/8prAP/KawD/yWsA/8lrAP/JawD/yWoA/8lq + AP/JagD/yWoA/8lqAP/JagD/yWkA/8lpAP/JaQD/yWkA/8lpAP/JaQD/yGkA/8hpAP/IaQD/yGgA/8ho + AP/IaAD/yGgA/8hoAP/KbAf/w1kA//Dgzf//////Usb8/zK9/v87v/7/Or/+/zq//v86v/7/Or/+/zq+ + /v86vv7/Or7+/zm+/v85vv7/Ob7+/zm+/v85vv7/Ob7+/zm+/v85vv7/Ob7+/zm+/v85vf7/Ob3+/zm9 + /v84vf7/OL3+/zi9/v84vf7/OL3+/zi9/v84vf7/OL3+/zi9/v84vP7/OLz+/zi8/v83vP7/N7z+/ze8 + /v83vP7/N7z+/ze8/v83vP7/N7z+/ze8/v83vP7/N7z+/ze8/v83vP7/Nrv+/za6/P81vv//QI+3/z5C + RP/z8fD///////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////zz//7PRP/0xEX/57Au/92h + HP/Ukwz/y4YA/8iDAP/JgwD/yIMA/86LA//anRb/5q8q//G/PP/5ykj//9hX///ZWP//1VT//tJR//7S + UP//0lH//9NS///TUv//01L//9VT//vPT/+bcBH/gVYA/4JXAP+CVwD/glcA/4JXAP+DWAD/g1gA/4JX + AP9+VAD/fFMA/4RYAP+TYgD/oWwA/7B1AP/EgwD/0IsA/9GMAP/QigD/0YwA/8iGAP+9fgD/s3gB/6Ft + Av+MXAD/ongY///dW///1VT/8sJB/7eEFP+OXwD/f1QA/4tiCv/fsTj/98I8/96kIP/Ymxb/0Y8H/8qF + AP/JgwD/yYQA/8eBAP/PjAX/254Y/+auKv/xvjz/+stJ///YV///2Ff//9VU//7SUf/+0lH//9JR///T + Uv//01L//9NS//3RUf//3ln/1ak2/3RJAP+GWwL/glcA/4JXAP+CVwD/glcA/4FXAv+MWgD/Uko2/29T + NP/DbQT/znAA/8tuAP/LbgD/y24A/8tuAP/LbgD/y24A/8ttAP/LbQD/y20A/8ptAP/KbQD/ym0A/8pt + AP/KbQD/ym0A/8psAP/KbAD/ymwA/8psAP/KbAD/ymwA/8psAP/KawD/ymsA/8prAP/JawD/yWsA/8lr + AP/JagD/yWoA/8lqAP/JagD/yWoA/8lqAP/JaQD/yWkA/8lpAP/JaQD/yWkA/8lpAP/IaQD/yGkA/8hp + AP/IaAD/yGgA/8hoAP/IaAD/ymwH/8NaAP/w4M3//////1LG/P8yvf7/O7/+/zq//v86v/7/Or/+/zq/ + /v86v/7/Or7+/zq+/v86vv7/Ob7+/zm+/v85vv7/Ob7+/zm+/v85vv7/Ob7+/zm+/v85vv7/Ob7+/zm9 + /v85vf7/Ob3+/zi9/v84vf7/OL3+/zi9/v84vf7/OL3+/zi9/v84vf7/OL3+/zi8/v84vP7/OLz+/ze8 + /v83vP7/N7z+/ze8/v83vP7/N7z+/ze8/v83vP7/N7z+/ze8/v83vP7/N7z+/ze8/v82uvz/Nb7//0CP + t/8+QkT/8/Hw//////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////779f/ks0P/0Y0A/8d7 + AP/HfwD/yYQA/8iCAP/NiQH/2pwW/+ewK//ywD3/+cpI///WVf//2Vn//9VU//7SUf/+0lD//9JR///T + Uv//01L//9NS///TUv//01L//9NS///VU//7z0//m3AR/4FWAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/g1gA/4NYAP+BVwD/flQA/31UAP+FWQD/kmIA/6BrAP+wdQD/xYQA/9GLAP/RiwD/z4kA/82F + AP/BfAD/xIcK/9alK//+0lD//9NR//vQUv+sgyH/eVAA/4RZAP+KXgP/q3gN/8WICf/QiQD/0IgA/8qF + AP/HgQD/zooD/9ueGP/nryv/8r89//rLSf//11b//9hY///VVP/+0lH//tJR///SUf//01L//9NS///T + Uv//01L//9NS///TUv/90VH//95Z/9WpNv90SQD/hlsC/4JXAP+CVwD/glcA/4JXAP+AVwL/ilkA/1JK + Nv9wUzT/w20E/85wAP/LbwD/y24A/8tuAP/LbgD/y24A/8tuAP/LbgD/y20A/8ttAP/LbQD/ym0A/8pt + AP/KbQD/ym0A/8ptAP/KbQD/ymwA/8psAP/KbAD/ymwA/8psAP/KbAD/ymwA/8prAP/KawD/ymsA/8lr + AP/JawD/yWsA/8lqAP/JagD/yWoA/8lqAP/JagD/yWoA/8lpAP/JaQD/yWkA/8lpAP/JaQD/yWkA/8hp + AP/IaQD/yGkA/8hoAP/IaAD/yGgA/8psB//DWgD/8ODN//////9Sxvz/Mr3+/zu//v86v/7/Or/+/zq/ + /v86v/7/Or/+/zq//v86vv7/Or7+/zq+/v85vv7/Ob7+/zm+/v85vv7/Ob7+/zm+/v85vv7/Ob7+/zm+ + /v85vv7/Ob3+/zm9/v85vf7/OL3+/zi9/v84vf7/OL3+/zi9/v84vf7/OL3+/zi9/v84vf7/OLz+/zi8 + /v84vP7/N7z+/ze8/v83vP7/N7z+/ze8/v83vP7/N7z+/ze8/v83vP7/N7z+/ze8/v83vP7/N7v8/zW+ + //9Aj7f/PkJE//Px8P////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////+/vz/8+bP/+/c + uf/kxYj/16I3/9iZEP/nsS3/88E///nKSP//1VT//9lY///VVP//0lH//tJR///SUf//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//1VP/+89P/5twEf+BVgD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4NYAP+DWAD/gVYA/35UAP9+VAD/hlkA/5FhAP+eagD/sHUA/8uK + Bv/priX/9L44//nHQ///0k///9hY///aWf/ywT//u4YU/4laAP9+VAH/flQA/4FVAP+JWQD/jVsA/6tz + Af/Xmxf/6LEs//LAPv/6y0n//9ZV///YV///1VT//9JR//7SUf//0lH//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//dFR///eWf/VqTb/dEkA/4ZbAv+CVwD/glcA/4JXAP+CVwD/gFcC/4pZ + AP9SSjb/cFM0/8NtBP/OcAD/y28A/8tvAP/LbgD/y24A/8tuAP/LbgD/y24A/8tuAP/LbQD/y20A/8tt + AP/KbQD/ym0A/8ptAP/KbQD/ym0A/8ptAP/KbAD/ymwA/8psAP/KbAD/ymwA/8psAP/KbAD/ymsA/8pr + AP/KawD/yWsA/8lrAP/JawD/yWoA/8lqAP/JagD/yWoA/8lqAP/JagD/yWkA/8lpAP/JaQD/yWkA/8lp + AP/JaQD/yGkA/8hpAP/IaQD/yGgA/8hoAP/KbAf/w1oA//Dgzf//////U8b8/zK9/v87v/7/Or/+/zq/ + /v86v/7/Or/+/zq//v86v/7/Or/+/zq+/v86vv7/Or7+/zm+/v85vv7/Ob7+/zm+/v85vv7/Ob7+/zm+ + /v85vv7/Ob7+/zm+/v85vf7/Ob3+/zm9/v84vf7/OL3+/zi9/v84vf7/OL3+/zi9/v84vf7/OL3+/zi9 + /v84vP7/OLz+/zi8/v83vP7/N7z+/ze8/v83vP7/N7z+/ze8/v83vP7/N7z+/ze8/v83vP7/N7z+/ze7 + /P82v///QI+3/z5CRP/z8fD///////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////7///////// + /////eb//uei//jMVP/5ykj//9RU///ZWP//1VT//9NS//7SUf//0lH//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9VT//vPT/+bcBH/gVYA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+DWAD/g1cA/4FWAP9+VAD/flUA/4Za + AP+SYwP/rYAZ/9SpOf/70FL/+8tF/+ixLv/bnxj/05MM/8qIA//AgAD/tXkB/5xnAP+NXwH/n3YX/8GY + LP/jtz//+MpJ///VVP//2Ff//9VU///TUv/+0lH//9JR///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS//3RUf//3ln/1ak2/3RJAP+GWwL/glcA/4JXAP+CVwD/glcA/4BX + Av+KWQD/Uko2/3BTNP/DbQT/znAA/8tvAP/LbwD/y28A/8tuAP/LbgD/y24A/8tuAP/LbgD/y24A/8tt + AP/LbQD/y20A/8ptAP/KbQD/ym0A/8ptAP/KbQD/ym0A/8psAP/KbAD/ymwA/8psAP/KbAD/ymwA/8ps + AP/KawD/ymsA/8prAP/JawD/yWsA/8lrAP/JagD/yWoA/8lqAP/JagD/yWoA/8lqAP/JaQD/yWkA/8lp + AP/JaQD/yWkA/8lpAP/IaQD/yGkA/8hpAP/IaAD/ymwH/8NaAP/w4M3//////1PG/P8zvf7/O7/+/zq/ + /v86v/7/Or/+/zq//v86v/7/Or/+/zq//v86v/7/Or7+/zq+/v86vv7/Ob7+/zm+/v85vv7/Ob7+/zm+ + /v85vv7/Ob7+/zm+/v85vv7/Ob7+/zm9/v85vf7/Ob3+/zi9/v84vf7/OL3+/zi9/v84vf7/OL3+/zi9 + /v84vf7/OL3+/zi8/v84vP7/OLz+/ze8/v83vP7/N7z+/ze8/v83vP7/N7z+/ze8/v83vP7/N7z+/ze8 + /v83u/z/N7///0CPt/8+QkT/8/Hw//////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////////9 + 9v//2W3//tZi///UVP//1VD//9ZW///TUv/+0lH//9NR///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///VU//7z0//m3AR/4FWAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/g1gA/4JX + AP+BVgD/fVQA/35UAP+JXQT/l2wO/696C//QjAP/yYUA/8uGAP/NiAD/0IsB/82IAP/Liwf/4a4x//TJ + Tf//1FL//9pX///VVP//01L//tJR///SUf//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv/90VH//95Z/9WpNv90SQD/hlsC/4JXAP+CVwD/glcA/4JX + AP+AVwL/ilkA/1JKNv9vUzT/w20E/85wAP/LbwD/y28A/8tvAP/LbwD/y24A/8tuAP/LbgD/y24A/8tu + AP/LbgD/y20A/8ttAP/LbQD/ym0A/8ptAP/KbQD/ym0A/8ptAP/KbQD/ymwA/8psAP/KbAD/ymwA/8ps + AP/KbAD/ymwA/8prAP/KawD/ymsA/8lrAP/JawD/yWsA/8lqAP/JagD/yWoA/8lqAP/JagD/yWoA/8lp + AP/JaQD/yWkA/8lpAP/JaQD/yWkA/8hpAP/IaQD/yGkA/8lsB//DWgD/8ODN//////9Txvz/M73+/zy/ + /v86v/7/Or/+/zq//v86v/7/Or/+/zq//v86v/7/Or/+/zq//v86vv7/Or7+/zq+/v85vv7/Ob7+/zm+ + /v85vv7/Ob7+/zm+/v85vv7/Ob7+/zm+/v85vv7/Ob3+/zm9/v85vf7/OL3+/zi9/v84vf7/OL3+/zi9 + /v84vf7/OL3+/zi9/v84vf7/OLz+/zi8/v84vP7/N7z+/ze8/v83vP7/N7z+/ze8/v83vP7/N7z+/ze8 + /v83vP7/N7v8/ze///9AkLf/PkJE//Px8P////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////PL//85A///ST///0lD//9NS///SUf//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//1VP/+89P/5twEf+BVgD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4NYAP+CVwD/f1QA/3tQAP+UYQD/zIYA/8mEAP/NiwX/w4cJ/8iFAP/PiQD/1pQK//fF + QP//2lj//9JR//7SUf//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//dFR///eWf/VqTb/dEkA/4ZbAv+CVwD/glcA/4JX + AP+CVwD/gFcC/4pZAP9SSjb/cFQ0/8NtBP/OcAD/y28A/8tvAP/LbwD/y28A/8tvAP/LbgD/y24A/8tu + AP/LbgD/y24A/8tuAP/LbQD/y20A/8ttAP/KbQD/ym0A/8ptAP/KbQD/ym0A/8ptAP/KbAD/ymwA/8ps + AP/KbAD/ymwA/8psAP/KbAD/ymsA/8prAP/KawD/yWsA/8lrAP/JawD/yWoA/8lqAP/JagD/yWoA/8lq + AP/JagD/yWkA/8lpAP/JaQD/yWkA/8lpAP/JaQD/yGkA/8hpAP/KbQf/w1oA//Dgzf//////U8f8/zO9 + /v88v/7/O7/+/zq//v86v/7/Or/+/zq//v86v/7/Or/+/zq//v86v/7/Or/+/zq+/v86vv7/Or7+/zm+ + /v85vv7/Ob7+/zm+/v85vv7/Ob7+/zm+/v85vv7/Ob7+/zm+/v85vf7/Ob3+/zm9/v84vf7/OL3+/zi9 + /v84vf7/OL3+/zi9/v84vf7/OL3+/zi9/v84vP7/OLz+/zi8/v83vP7/N7z+/ze8/v83vP7/N7z+/ze8 + /v83vP7/N7z+/ze7/P83v///QJC3/z5CRP/z8fD///////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////zz///RTP//1FX//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9VT//vPT/+bcBH/gVYA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/nGoE/+GlHv/ywDz/88VF/7GDG/+JWgD/mmYA/7qB + Cf/vvTz//9VV//7SUf//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS//3RUf//3ln/1ak2/3RJAP+GWwL/glcA/4JX + AP+CVwD/glcA/4BXAv+KWQD/Uko2/3BUNP/EbgT/znAA/8tvAP/LbwD/y28A/8tvAP/LbwD/y28A/8tu + AP/LbgD/y24A/8tuAP/LbgD/y24A/8ttAP/LbQD/y20A/8ptAP/KbQD/ym0A/8ptAP/KbQD/ym0A/8ps + AP/KbAD/ymwA/8psAP/KbAD/ymwA/8psAP/KawD/ymsA/8prAP/JawD/yWsA/8lrAP/JagD/yWoA/8lq + AP/JagD/yWoA/8lqAP/JaQD/yWkA/8lpAP/JaQD/yWkA/8lpAP/IaQD/yW0H/8NbAP/w4M3//////1PH + /P8zvf7/PL/+/zu//v87v/7/Or/+/zq//v86v/7/Or/+/zq//v86v/7/Or/+/zq//v86v/7/Or7+/zq+ + /v86vv7/Ob7+/zm+/v85vv7/Ob7+/zm+/v85vv7/Ob7+/zm+/v85vv7/Ob7+/zm9/v85vf7/Ob3+/zi9 + /v84vf7/OL3+/zi9/v84vf7/OL3+/zi9/v84vf7/OL3+/zi8/v84vP7/OLz+/ze8/v83vP7/N7z+/ze8 + /v83vP7/N7z+/ze8/v83u/z/N7///0CQt/8+QkT/8/Hw//////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////88///0Ur//9RU///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///VU//7z0//m3AR/4FW + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/gVYA/6Z7F///01H//9ZV//rPUf+vgx7/fFIA/39U + AP+TZwn/4LM8///YVf/90VH//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv/90VH//95Z/9WpNv90SQD/hlsC/4JX + AP+CVwD/glcA/4JXAP+AVwL/ilkA/1JKNv9wVDT/xG4E/89xAP/LbwD/y28A/8tvAP/LbwD/y28A/8tv + AP/LbwD/y24A/8tuAP/LbgD/y24A/8tuAP/LbgD/y20A/8ttAP/LbQD/ym0A/8ptAP/KbQD/ym0A/8pt + AP/KbQD/ymwA/8psAP/KbAD/ymwA/8psAP/KbAD/ymwA/8prAP/KawD/ymsA/8lrAP/JawD/yWsA/8lq + AP/JagD/yWoA/8lqAP/JagD/yWoA/8lpAP/JaQD/yWkA/8lpAP/JaQD/yWkA/8ptB//DWwD/8ODN//// + //9Tx/z/M77+/zzA/v87v/7/O7/+/zu//v86v/7/Or/+/zq//v86v/7/Or/+/zq//v86v/7/Or/+/zq/ + /v86vv7/Or7+/zq+/v85vv7/Ob7+/zm+/v85vv7/Ob7+/zm+/v85vv7/Ob7+/zm+/v85vv7/Ob3+/zm9 + /v85vf7/OL3+/zi9/v84vf7/OL3+/zi9/v84vf7/OL3+/zi9/v84vf7/OLz+/zi8/v84vP7/N7z+/ze8 + /v83vP7/N7z+/ze8/v83vP7/N7v8/ze///9AkLf/PkJE//Px8P////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////////////////PP//9FK///UVP//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//1VP/+89P/5tw + Ef+BVgD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4FWAP+ofRr//9hW///VU//4zE3/r4Qd/39U + AP9/VAD/j2QJ/96yPP//2FX//dFR///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//dFR///eWf/VqTb/dEkA/4Zb + Av+CVwD/glcA/4JXAP+CVwD/gFcC/4pZAP9SSjb/cFQ0/8RuBP/PcQD/zHAA/8tvAP/LbwD/y28A/8tv + AP/LbwD/y28A/8tvAP/LbgD/y24A/8tuAP/LbgD/y24A/8tuAP/LbQD/y20A/8ttAP/KbQD/ym0A/8pt + AP/KbQD/ym0A/8ptAP/KbAD/ymwA/8psAP/KbAD/ymwA/8psAP/KbAD/ymsA/8prAP/KawD/yWsA/8lr + AP/JawD/yWoA/8lqAP/JagD/yWoA/8lqAP/JagD/yWkA/8lpAP/JaQD/yWkA/8lpAP/LbQf/w1sA//Dg + zf//////U8f8/zO+/v88wP7/O8D+/zu//v87v/7/O7/+/zq//v86v/7/Or/+/zq//v86v/7/Or/+/zq/ + /v86v/7/Or/+/zq+/v86vv7/Or7+/zm+/v85vv7/Ob7+/zm+/v85vv7/Ob7+/zm+/v85vv7/Ob7+/zm+ + /v85vf7/Ob3+/zm9/v84vf7/OL3+/zi9/v84vf7/OL3+/zi9/v84vf7/OL3+/zi9/v84vP7/OLz+/zi8 + /v83vP7/N7z+/ze8/v83vP7/N7z+/ze7/P83v///QJC3/z5CRP/z8fD///////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////zz///RSv//1FT//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9VT//vP + T/+bcBH/gVYA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+BVgD/qHwZ///WVP//1FP/+c1O/6+E + Hf9/VAD/gFUA/5FlCf/esjz//9hV//3RUf//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS//3RUf//3ln/1ak2/3RJ + AP+GWwL/glcA/4JXAP+CVwD/glcA/4BXAv+KWQD/Uko2/3BUNP/EbgT/z3EA/8xwAP/McAD/y28A/8tv + AP/LbwD/y28A/8tvAP/LbwD/y28A/8tuAP/LbgD/y24A/8tuAP/LbgD/y24A/8ttAP/LbQD/y20A/8pt + AP/KbQD/ym0A/8ptAP/KbQD/ym0A/8psAP/KbAD/ymwA/8psAP/KbAD/ymwA/8psAP/KawD/ymsA/8pr + AP/JawD/yWsA/8lrAP/JagD/yWoA/8lqAP/JagD/yWoA/8lqAP/JaQD/yWkA/8lpAP/JaQD/y20H/8Rb + AP/w4M3//////1PH/P8zvv7/PMD+/zvA/v87wP7/O7/+/zu//v87v/7/Or/+/zq//v86v/7/Or/+/zq/ + /v86v/7/Or/+/zq//v86v/7/Or7+/zq+/v86vv7/Ob7+/zm+/v85vv7/Ob7+/zm+/v85vv7/Ob7+/zm+ + /v85vv7/Ob7+/zm9/v85vf7/Ob3+/zi9/v84vf7/OL3+/zi9/v84vf7/OL3+/zi9/v84vf7/OL3+/zi8 + /v84vP7/OLz+/ze8/v83vP7/N7z+/ze8/v83u/z/N7///0CQt/8+QkT/8/Hw//////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////88///0Ur//9RU///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///V + U//7z0//m3AR/4FWAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/gVYA/6h8Gf//1lT//9RT//nN + Tv+vhB3/f1QA/4BVAP+RZQn/3rI8///YVf/90VH//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv/90VH//95Z/9Wp + Nv90SQD/hlsC/4JXAP+CVwD/glcA/4JXAP+AVwL/ilkA/1JKNv9wVDT/xG4E/89xAP/McAD/zHAA/8xw + AP/LbwD/y28A/8tvAP/LbwD/y28A/8tvAP/LbwD/y24A/8tuAP/LbgD/y24A/8tuAP/LbgD/y20A/8tt + AP/LbQD/ym0A/8ptAP/KbQD/ym0A/8ptAP/KbQD/ymwA/8psAP/KbAD/ymwA/8psAP/KbAD/ymwA/8pr + AP/KawD/ymsA/8lrAP/JawD/yWsA/8lqAP/JagD/yWoA/8lqAP/JagD/yWoA/8lpAP/JaQD/yWkA/8pt + B//EWwD/8ODN//////9Tx/z/M77+/zzA/v87wP7/O8D+/zvA/v87v/7/O7/+/zu//v86v/7/Or/+/zq/ + /v86v/7/Or/+/zq//v86v/7/Or/+/zq//v86vv7/Or7+/zq+/v85vv7/Ob7+/zm+/v85vv7/Ob7+/zm+ + /v85vv7/Ob7+/zm+/v85vv7/Ob3+/zm9/v85vf7/OL3+/zi9/v84vf7/OL3+/zi9/v84vf7/OL3+/zi9 + /v84vf7/OLz+/zi8/v84vP7/N7z+/ze8/v83vP7/N7v8/ze///9AkLf/PkJE//Px8P////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////PP//9FK///UVP//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//1VP/+89P/5twEf+BVgD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4FWAP+ofBn//9ZU///U + U//5zU7/r4Qd/39UAP+AVQD/kWUJ/96yPP//2FX//dFR///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//dFR///e + Wf/VqTb/dEkA/4ZbAv+CVwD/glcA/4JXAP+CVwD/gFcC/4pZAP9SSjb/cFQ0/8RuBP/PcQD/y3AA/8xw + AP/McAD/zHAA/8tvAP/LbwD/y28A/8tvAP/LbwD/y28A/8tvAP/LbgD/y24A/8tuAP/LbgD/y24A/8tu + AP/LbQD/y20A/8ttAP/KbQD/ym0A/8ptAP/KbQD/ym0A/8ptAP/KbAD/ymwA/8psAP/KbAD/ymwA/8ps + AP/KbAD/ymsA/8prAP/KawD/yWsA/8lrAP/JawD/yWoA/8lqAP/JagD/yWoA/8lqAP/JagD/yWkA/8lp + AP/KbQf/xFsA//Dgzf//////U8f8/zO+/v88wP7/O8D+/zvA/v87wP7/O8D+/zu//v87v/7/O7/+/zq/ + /v86v/7/Or/+/zq//v86v/7/Or/+/zq//v86v/7/Or/+/zq+/v86vv7/Or7+/zm+/v85vv7/Ob7+/zm+ + /v85vv7/Ob7+/zm+/v85vv7/Ob7+/zm+/v85vf7/Ob3+/zm9/v84vf7/OL3+/zi9/v84vf7/OL3+/zi9 + /v84vf7/OL3+/zi9/v84vP7/OLz+/zi8/v83vP7/N7z+/ze7/P83v///QJC3/z5CRP/z8fD///////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////zz///RSv//1FT//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9VT//vPT/+bcBH/gVYA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+BVgD/qHwZ///W + VP//1FP/+c1O/6+EHf9/VAD/gFUA/5FlCf/esjz//9hV//3RUf//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS//3R + Uf//3ln/1ak2/3RJAP+GWwL/glcA/4JXAP+CVwD/glcA/4BXAv+KWQD/Uko2/3FUNP/GbwP/0XIA/81w + AP/NcAD/zXAA/81wAP/McAD/y28A/8tvAP/LbwD/y28A/8tvAP/LbwD/y28A/8tuAP/LbgD/y24A/8tu + AP/LbgD/y24A/8ttAP/LbQD/y20A/8ptAP/KbQD/ym0A/8ptAP/KbQD/ym0A/8psAP/KbAD/ymwA/8ps + AP/KbAD/ymwA/8psAP/KawD/ymsA/8prAP/JawD/yWsA/8lrAP/JagD/yWoA/8lqAP/JagD/yWoA/8lq + AP/JaQD/ym0H/8RbAP/w4M3//////1PH/P8zvv7/PMD+/zvA/v87wP7/O8D+/zvA/v87wP7/O7/+/zu/ + /v87v/7/Or/+/zq//v86v/7/Or/+/zq//v86v/7/Or/+/zq//v86v/7/Or7+/zq+/v86vv7/Ob7+/zm+ + /v85vv7/Ob7+/zm+/v85vv7/Ob7+/zm+/v85vv7/Ob7+/zm9/v85vf7/Ob3+/zi9/v84vf7/OL3+/zi9 + /v84vf7/OL3+/zi9/f84vf3/OL3+/zi9/v84vf//OL3//ze9//83vP7/NsH//0CRuP8+QkT/8/Hw//// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////88///0Ur//9RU///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///VU//7z0//m3AR/4FWAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/gVYA/6h8 + Gf//1lT//9RT//nNTv+vhB3/f1QA/4BVAP+RZQn/3rI8///YVf/90VH//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv/90VH//95Z/9WpNv90SQD/hlsC/4JXAP+CVwD/glcA/4JXAP+AVwL/ilkA/1JKNv9vVDX/wW0F/8tx + AP/JbwH/y3AB/8xwAP/OcAD/0HEA/9FyAP/PcAD/znAA/81wAP/MbwD/y28A/8pvAP/KbwD/y24A/8tu + AP/LbgD/y24A/8tuAP/LbgD/y20A/8ttAP/LbQD/ym0A/8ptAP/KbQD/ym0A/8ptAP/KbQD/ymwA/8ps + AP/KbAD/ymwA/8psAP/KbAD/ymwA/8prAP/KawD/ymsA/8lrAP/JawD/yWsA/8lqAP/JagD/yWoA/8lq + AP/JagD/yWoA/8ptB//EWwD/8ODN//////9Tx/z/M77+/zzA/v87wP7/O8D+/zvA/v87wP7/O8D+/zvA + /v87v/7/O7/+/zu//v86v/7/Or/+/zq//v86v/7/Or/+/zq//v86v/7/Or/+/zq//v86vv7/Or7+/zq+ + /v85vv7/Ob7+/zm+/v85vv7/Ob7+/zm+/v85vv7/Ob7+/zm+/v85vv7/Ob3+/zm9/v85vf3/OLz9/zi9 + /v84vv//OL///zjA//84wf//OML//zjB//84v///Ob3//zm8/f85u/z/Obn4/zi9//9BjrX/P0NF//Px + 8P////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////PP//9FK///UVP//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//1VP/+89P/5twEf+BVgD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4FW + AP+ofBn//9ZU///UU//5zU7/r4Qd/39UAP+AVQD/kWUJ/96yPP//2FX//dFR///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//dFR///eWf/VqTb/dEkA/4ZbAv+CVwD/glcA/4JXAP+CVwD/gFcC/4lZAP9TSjf/UktF/3hX + Lv98WC3/gVoq/4lcJf+UXx//nmIa/61nEv+6awr/vmwI/8FsBf/FbQP/yW4B/85wAP/RcQD/z3AA/85v + AP/LbgD/ym4A/8puAP/LbgD/y24A/8tuAP/LbQD/y20A/8ttAP/KbQD/ym0A/8ptAP/KbQD/ym0A/8pt + AP/KbAD/ymwA/8psAP/KbAD/ymwA/8psAP/KbAD/ymsA/8prAP/KawD/yWsA/8lrAP/JawD/yWoA/8lq + AP/JagD/yWoA/8lqAP/Kbgf/xFsA//Dgzf//////U8f8/zO+/v88wP7/O8D+/zvA/v87wP7/O8D+/zvA + /v87wP7/O8D+/zu//v87v/7/O7/+/zq//v86v/7/Or/+/zq//v86v/7/Or/+/zq//v86v/7/Or/+/zq+ + /v86vv7/Or7+/zm+/v85vv7/Ob7+/zm+/v85vv7/Ob7+/zm+/v85vv3/Ob39/zm+/v85v///OcD//zjC + //84wv//Ob7//zq6+f86t/P/OrLt/ziu6P84pNr/OZXD/zmLs/85gKX/OXiY/zlwi/85cIv/Pl5u/zY3 + OP/y8fH///////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////zz///RSv//1FT//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9VT//vPT/+bcBH/gVYA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+BVgD/qHwZ///WVP//1FP/+c1O/6+EHf9/VAD/gFUA/5FlCf/esjz//9hV//3RUf//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS//3RUf//3ln/1ak2/3RJAP+GWwL/glcA/4JXAP+CVwD/glcA/4FXAv+HWAD/Xk0s/0tI + Qv9MSD7/TEg//0pIQf9IR0L/RkdE/0RGRv9BRUj/P0VL/09KRP9fTzz/clQy/4dbJv+hYxj/tWkM/75r + B//GbgP/znAA/9JwAP/PbwD/zG4A/8puAP/KbgH/y20A/8ttAP/LbQD/y20A/8ptAP/KbQD/ym0A/8pt + AP/KbQD/ym0A/8psAP/KbAD/ymwA/8psAP/KbAD/ymwA/8psAP/KawD/ymsA/8prAP/JawD/yWsA/8lr + AP/JagD/yWoA/8lqAP/JagD/ym4H/8RcAP/w4M3//////1TH/P80vv7/PMD+/zvA/v87wP7/O8D+/zvA + /v87wP7/O8D+/zvA/v87wP7/O7/+/zu//v87v/7/Or/+/zq//v86v/7/Or/+/zq//v86v/7/Or/+/zq/ + /v86v/7/Or7+/zq+/v86vv7/Ob7+/zm+/v85vv7/Ob39/zm9/P85vv7/OcH//zjE//85w///O7z7/zy1 + 8f87reX/OZ7Q/zmGq/85boj/Olxt/0BQWP9IRUP/T0Q//1NMSP9WUE3/W1VT/11ZVv9gXVv/YV1c/2Ng + X/9dXFz/9PX1//////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////88///0Ur//9RU///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///VU//7z0//m3AR/4FWAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/gVYA/6h8Gf//1lT//9RT//nNTv+vhB3/f1QA/4BVAP+RZQn/3rI8///YVf/90VH//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv/90VH//95Z/9WpNv90SQD/hlsC/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4RY + AP+CVwH/glcB/4NXAf9/Vgb/fFUJ/3dVD/9zUxT/blIa/2dQIv9fTi3/VEo2/01JPf9IR0L/QEVI/0JG + Sv9YTD//clIt/5NcG/+xZg7/vmsH/8ltAf/ScAD/0XAA/8xuAP/KbQH/ym0A/8ttAP/LbQD/ym0A/8pt + AP/KbQD/ym0A/8ptAP/KbQD/ymwA/8psAP/KbAD/ymwA/8psAP/KbAD/ymwA/8prAP/KawD/ymsA/8lr + AP/JawD/yWsA/8lqAP/JagD/yWoA/8puB//EXAD/8ODN//////9Ux/z/Nb7+/zzA/v87wP7/O8D+/zvA + /v87wP7/O8D+/zvA/v87wP7/O8D+/zvA/v87v/7/O7/+/zu//v86v/7/Or/+/zq//v86v/7/Or/+/zq/ + /v86v/7/Or/+/zq//v86vv7/Or7+/zq+/f85vfz/Ob79/znB//84xf//OsH//zy38/88reT/OpnG/zp4 + lv85Wmr/QUZI/09EP/9ZUk7/Yl5c/25sa/+CgoL/mpyd/7Cztf/Cxcb/z9LT/+Hj5P/s7u//+Pr6//v9 + /f/6+vv///////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////PP//9FK///U + VP//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//1VP/+89P/5twEf+BVgD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4FWAP+ofBn//9ZU///UU//5zU7/r4Qd/39UAP+AVQD/kWUJ/96yPP//2FX//dFR///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//dFR///eWf/VqTb/dEkA/4ZbAv+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+BVwH/gVcB/4FXAf+BVwH/glcA/4JXAP+DVwD/hFcA/4RYAP+FWAD/h1gA/4hZAP+DWAD/eFQM/3BS + F/9iTST/Wk42/1tXSP9NUU7/QURI/1tJOv+GWyj/p2QT/7tpCP/MbwD/03EA/85uAP/KbQH/ym0B/8tt + AP/KbQD/ym0A/8ptAP/KbQD/ym0A/8ptAP/KbAD/ymwA/8psAP/KbAD/ymwA/8psAP/KbAD/ymsA/8pr + AP/KawD/yWsA/8lrAP/JawD/yWoA/8lqAP/Kbgf/xFwA//Dgzf//////VMf8/zS+/v89wP7/O8D+/zvA + /v87wP7/O8D+/zvA/v87wP7/O8D+/zvA/v87wP7/O8D+/zu//v87v/7/O7/+/zq//v86v/7/Or/+/zq/ + /v86v/7/Or/+/zq//v86v/7/Or/9/zq9/P86v///OsT//zrE//88t/L/Pafa/zuKsP84Ynb/PUZL/1JH + Qf9fWVb/cG1s/4uMjf+vsrP/ztHS//Dx8v////////////////////////////////////////////39 + /f/9/f3//f39//v7+/////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////zz///R + Sv//1FT//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9VT//vPT/+bcBH/gVYA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+BVgD/qHwZ///WVP//1FP/+c1O/6+EHf9/VAD/gFUA/5FlCf/esjz//9hV//3R + Uf//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS//3RUf//3ln/1ak2/3RJAP+GWwL/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/gVcB/4FXAf+BVwH/gVcB/4FXAv+AVwL/gVcB/4NX + AP+FWQD/g1QA/5doBf/Rpzz/za1Q/56ITP9lXEP/QkNA/0BGTf9bTD7/h1gj/61mEf/EbQX/03AA/9Bv + AP/KbQH/ym0B/8ptAP/KbQD/ym0A/8ptAP/KbQD/ym0A/8psAP/KbAD/ymwA/8psAP/KbAD/ymwA/8ps + AP/KawD/ymsA/8prAP/JawD/yWsA/8lrAP/JagD/ym4H/8RcAP/w4M3//////1TH/P80vv7/PcD+/zzA + /v87wP7/O8D+/zvA/v87wP7/O8D+/zvA/v87wP7/O8D+/zvA/v87wP7/O7/+/zu//v87v/7/Or/+/zq/ + /v86v/7/Or/+/zq//v86vv3/Or37/zrB//85x///PL78/z+t4v89jrb/OGJ3/z0+Pv9USkT/bGdl/4iI + iP+2ubv/3d/g////////////////////////////+/v7//r6+v/7+/v//Pz8//39/f/9/f3//v7+//7+ + /v/+/v7//v7+//7+/v////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////////8 + 8///0Ur//9RU///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///VU//7z0//m3AR/4FWAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/gVYA/6h8Gf//1lT//9RT//nNTv+vhB3/f1QA/4BVAP+RZQn/3rI8///Y + Vf/90VH//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv/90VH//95Z/9WpNv90SQD/hlsC/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+BVwH/glgC/31TAP+OZAv/37I8///aVP//6lr/y54s/2hGBv9oUiX/WU83/0pOTP9CQkX/aEsv/51h + Gf+9awn/03AA/9FvAP/JbAH/yW0B/8ptAP/KbQD/ym0A/8ptAP/KbQD/ymwA/8psAP/KbAD/ymwA/8ps + AP/KbAD/ymwA/8prAP/KawD/ymsA/8lrAP/JawD/yWsA/8puB//EXAD/8ODN//////9Ux/z/NL7+/z3A + /v88wP7/PMD+/zvA/v87wP7/O8D+/zvA/v87wP7/O8D+/zvA/v87wP7/O8D+/zvA/v87v/7/O7/+/zu/ + /v86v/7/Or/+/zq//f86vfv/OsH//znI//89u/b/QKLQ/zx4lP83SVH/T0Q+/25oZf+PkJH/vsHD//L0 + 9f/////////////////8/Pz/+vr6//z8/P/9/f3//v7+//////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////PP//9FK///UVP//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//1VP/+89P/5twEf+BVgD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4FWAP+ofBn//9ZU///UU//5zU7/r4Qd/39UAP+AVQD/kWUJ/96y + PP//2FX//dFR///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//dFR///eWf/VqTb/dEkA/4ZbAv+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4NYAf9+UwD/kGUJ/92xPP/+01P//9tZ/8CVKv93SwD/iVoA/45iB/+4lj7/nIhP/2Rf + TP88QUv/Wkc2/5NeHv+4aQz/1HAA/89uAP/IbAH/yW0A/8ptAP/KbQD/ym0A/8ptAP/KbAD/ymwA/8ps + AP/KbAD/ymwA/8psAP/KbAD/ymsA/8prAP/KawD/yWsA/8lrAP/Lbwf/xFwA//Dgzf//////VMf8/zS+ + /v89wP7/PMD+/zzA/v88wP7/O8D+/zvA/v87wP7/O8D+/zvA/v87wP7/O8D+/zvA/v87wP7/O8D+/zu/ + /v87v/7/O7/+/zq9+/86v/7/Ocj//z259P9Bm8b/PG2E/zs8PP9dU07/hIGA/7a6u//t7/D///////// + ////////+vr6//z8/P/9/f3//v7+//////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////zz///RSv//1FT//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9VT//vPT/+bcBH/gVYA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+BVgD/qHwZ///WVP//1FP/+c1O/6+EHf9/VAD/gFUA/5Fl + Cf/esjz//9hV//3RUf//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS//3RUf//3ln/1ak2/3RJAP+GWwL/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+DWAH/flMA/5BlCf/esjz//9VT///eWf/Clyr/dUoA/4NZA/+JXwf/6rw////l + V//nv07/q5JK/3NqTP88RE3/VEY6/5VeHv++awj/1HAA/8ttAP/IbAH/ym0A/8ptAP/KbQD/ym0A/8ps + AP/KbAD/ymwA/8psAP/KbAD/ymwA/8psAP/KawD/ymsA/8prAP/JawD/ym8H/8RdAP/w4M3//////1TH + /P80vv7/PcD+/zzA/v88wP7/PMD+/zzA/v87wP7/O8D+/zvA/v87wP7/O8D+/zvA/v87wP7/O8D+/zvA + /v87wP7/O778/zu9+/86xf//O778/0KgzP8+an//PTs6/2VcWP+Vlpf/ztHT//////////////////r6 + +v/8/Pz//v7+//////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////88///0Ur//9RU///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///VU//7z0//m3AR/4FW + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/gVYA/6h8Gf//1lT//9RT//nNTv+vhB3/f1QA/4BV + AP+RZQn/3rI8///YVf/90VH//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv/90VH//95Z/9WpNv90SQD/hlsC/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/g1gB/35TAP+QZQn/3rI8///VU///3ln/wpcq/3VLAP+EWQH/i2AH/+C1 + P///11b//9RR///fU//yyFD/uJxM/3RsTf84P0r/YEs1/59jGv/LbgH/0W8A/8dsAf/KbQD/ym0A/8pt + AP/KbQD/ymwA/8psAP/KbAD/ymwA/8psAP/KbAD/ymwA/8prAP/KawD/ymsA/8pvB//EXQD/8ODN//// + //9UyPz/NL7+/z3A/v88wP7/PMD+/zzA/v88wP7/PMD+/zvA/v87wP7/O8D+/zvA/v87wP7/O8D+/zvA + /v87wP7/O776/zvC//86xf//QKjY/0B2j/85PT//YVhT/5+gof/a3d/////////////9/f3/+/v7//39 + /f////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////////////////PP//9FK///UVP//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//1VP/+89P/5tw + Ef+BVgD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4FWAP+ofBn//9ZU///UU//5zU7/r4Qd/39U + AP+AVQD/kWUJ/96yPP//2FX//dFR///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//dFR///eWf/VqTb/dEkA/4Zb + Av+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4NYAf9+UwD/kGUJ/96yPP//1VP//95Z/8KXKv91SwD/hFkC/4tg + Bv/itz///9pX//zQUf/70FL//9RS///fU//vxlD/sZZL/2NgTf86PEb/dlQt/7FnEP/TbwD/yW0A/8hs + Af/KbQD/ym0A/8ptAP/KbAD/ymwA/8psAP/KbAD/ymwA/8psAP/KbAD/ymsA/8prAP/Lbwf/xF0A//Dg + zf//////VMj8/zS//v89wf7/PMD+/zzA/v88wP7/PMD+/zzA/v88wP7/O8D+/zvA/v87wP7/O8D+/zvA + /v87v/z/O736/zrH//88uPL/Q4io/z9RXf9WTkz/lZOS/9fa2/////////////v7+//8/Pz//v7+//// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////zz///RSv//1FT//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9VT//vP + T/+bcBH/gVYA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+BVgD/qHwZ///WVP//1FP/+c1O/6+E + Hf9/VAD/gFUA/5FlCf/esjz//9hV//3RUf//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS//3RUf//3ln/1ak2/3RJ + AP+GWwL/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+DWAH/flMA/5BlCf/esjz//9VT///eWf/Clyr/dUsA/4RZ + Av+LYAb/4rc////aV//+0lH//9NS//7SUv/70FL//9ZS///dU//jvE//nIhM/0NJTP9SRjz/l2Ae/8tu + Af/QbwD/x2wB/8hsAf/KbQD/ym0A/8psAP/KbAD/ymwA/8psAP/KbAD/ymwA/8psAP/KawD/zG8H/8Vd + AP/w4M3//////1TI/P80v/7/PcH+/zzB/v88wP7/PMD+/zzA/v88wP7/PMD+/zzA/v87wP7/O8D+/zu/ + /P87vfn/O8L//zrH//8/pNL/Q2t+/0ZERv9YRiv/trKn/////////////Pz8//z8/P////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////88///0Ur//9RU///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///V + U//7z0//m3AR/4FWAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/gVYA/6h8Gf//1lT//9RT//nN + Tv+vhB3/f1QA/4BVAP+RZQn/3rI8///YVf/90VH//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv/90VH//95Z/9Wp + Nv90SQD/hlsC/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/g1gB/35TAP+QZQn/3rI8///VU///3ln/wpcq/3VL + AP+EWQL/i2AG/+K3P///2lf//tJR///TUv//01L//9NS//7SUv/80VL//9lS///XUv/Mq03/b2hM/zk9 + R/9yUzD/q2YU/9FvAP/PbwD/yGwB/8dsAv/JbQH/ymwA/8psAP/KbAD/ymwA/8psAP/KbAD/ymwA/8tv + B//FXQD/8ODN//////9UyPz/NL/+/z3B/v88wf7/PMH+/zzA/v88wP7/PMD+/zzA/v88v/3/PL77/zy9 + +f87wv//Osn//z2z6f9Dgp3/QlNg/0xDO/9mTyD/hmIY/+neyP//////+vr5//////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////PP//9FK///UVP//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//1VP/+89P/5twEf+BVgD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4FWAP+ofBn//9ZU///U + U//5zU7/r4Qd/39UAP+AVQD/kWUJ/96yPP//2FX//dFR///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//dFR///e + Wf/VqTb/dEkA/4ZbAv+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4NYAf9+UwD/kGUJ/96yPP//1VP//95Z/8KX + Kv91SwD/hFkC/4tgBv/itz///9pX//7SUf//01L//9NS///TUv//01L//9NS//3RUv//01L//9xT/+rC + UP+kjk3/S05M/0dBQP95Vy7/q2YU/89vAP/TcAD/y20A/8dsAv/HawH/yGsB/8lsAP/KbAD/ymwA/8ps + AP/LcAf/xV0A//Dgzf//////VMj8/zS//v89wf7/PMH+/zzB/v88wP3/PL/8/zy++/88vfn/PL/8/zvG + //87yf//PrHm/0OFov9CXm7/RUVH/1tHKf90Vhb/g1cA/41jEP/f1cL///////79/P////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////zz///RSv//1FT//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9VT//vPT/+ccRH/gVYA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+BVgD/qHwZ///W + VP//1FP/+c1O/6+EHf9/VAD/gFUA/5FlCf/esjz//9hV//3RUf//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS//3R + Uf//3Vj/1ak1/3VKAP+GWwL/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+DWAH/flMA/5BlCf/esjz//9VT///e + Wf/Clyr/dUsA/4RZAv+LYAb/4rc////aV//+0lH//9NS///TUv//01L//9NS///TUv//01L//tJS//3R + Uv//2FL//9VS/9i0Tv+QgE7/RUlL/0ZAP/9uUjL/lmEf/7xqCv/UcQD/03AA/85tAP/KbAD/x2sC/8dr + Av/HawL/yW8I/8NeAP/t3sr//////1XF+f81vfv/Pb/6/zy++v88vvn/PMD9/zzD//87xv//O8r//z2+ + +f9BmsP/RHiQ/0Jba/9ERkv/VkMq/21SGv9+Vwb/hlkA/4FWAP+KYhP/4tfD///////+/fz///////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////88///0Ur//9RU///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//tJR///TUf/7z0//mnAS/4JXAP+EWAD/g1cA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/gVYA/6h8 + Gf//1lT//9RT//nNTv+vhB3/f1QA/4BVAP+RZQn/3rI8///YVf/90VH//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NR//7S + Uf/8z0///99a/9WrOf9xRwD/h1wD/4RYAP+DVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/g1gB/35TAP+QZQn/3rI8///V + U///3ln/wpcq/3VLAP+EWQL/i2AG/+K3P///2lf//tJR///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//dJS///UUv//2lP/+89R/9i0T/+fi0//V1dM/z0+RP9TRzz/bVIy/45dI/+pZRL/wWoF/9Nv + AP/XcAD/028A/9NyA//LXwD/+enT//////9Wzv//NMX//zzJ//87y///O8z//z299v8/qtr/QpG0/0R2 + jf9DXm3/QlBc/0hEQf9dRiP/b1IW/3xXCf+EWAD/hFcA/4JYA/+BVgD/i2IS/+HXw////////v38//// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////PP//9FK///UVP//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS//7S + Uf/+0VD//9NS///WVf//2ln/+MpJ/6Z0Cv+BVgD/fVQA/4FWAP+DWAD/g1gA/4NXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4FW + AP+ofBn//9ZU///UU//5zU7/r4Qd/39UAP+AVQD/kWUJ/96yPP//2FX//dFR///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv/+0lH//tJQ///T + Uv//11f//9dX//vLR//Smx7/kF4A/4JYAf99VAD/gVYA/4NYAP+DWAD/g1cA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4NYAf9+UwD/kGUJ/96y + PP//1VP//95Z/8KXKv91SwD/hFkC/4tgBv/itz///9pX//7SUf//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv/+01L//dJS///VUv//2lP//tJR/+jAUP/Ep0//in1O/1dVSv8/P0T/SENC/1ZK + Pv9gTjr/cFIx/35XKv+PXiX/kFUS/6acjv+3tLH/Uo6o/0CJqv9Efpj/Q3KI/0Rldf9DW2j/Q1Vh/0JM + Vf9IRD//WUQo/2lNGf93VA7/flcG/4RYAP+EWAD/glcA/4JXAP+DWAL/gVYA/4piEv/h18P///////79 + /P////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////zz///RSv//1FT//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//0lH//tJR///T + Uv//1VT//9hY//vOTP/ptDD/2p0X/9KRCv/IhgH/wIAA/691AP+UYwD/gVcA/35UAP+BVwD/g1gA/4NY + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+BVgD/qHwZ///WVP//1FP/+c1O/6+EHf9/VAD/gFUA/5FlCf/esjz//9hV//3RUf//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//tJR//7SUf//01L//9ZW///Y + V//3yEb/5a0p/9iaE//RkAn/zIkC/8aEAP++fwD/rnQA/5VjAP+AVgD/flQA/4FXAP+DWAD/g1gA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+DWAH/flMA/5Bl + Cf/esjz//9VT///eWf/Clyr/dUsA/4RZAv+LYAb/4rc////aV//+0lH//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv/+0lL//dJS///UUf//2FH//9hR//nPU//uyFX/069K/6aG + N/98ZTH/YFQ3/1NOQf9LSUT/QkRJ/0BCSv9CRlD/Q0hS/0BHUv9CSVL/R0dG/01GPf9TQy7/XUcl/2dL + Gv9yUBH/eVUK/31XB/+CWAD/hVgA/4NXAP+CVwD/glcA/4JXAP+CVwD/g1gC/4FWAP+KYhL/4dfD//// + ///+/fz///////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////88///0Ur//9RU///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS//7SUf//01L//9RT///X + V//8zk3/6rUx/9qcFv/SkAn/zosD/8uHAP/KhQD/zokA/86KAP/MiAD/x4UA/8GBAP+udAD/k2IA/4FX + AP9/VQD/glcA/4NXAP+DVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/gVYA/6h8Gf//1lT//9RT//nNTv+vhB3/f1QA/4BVAP+RZQn/3rI8///YVf/90VH//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///SUf/+0lH//9NS///VVf//11f/+MlI/+Wu + Kf/XmRL/0Y8H/82JAf/KhQD/yoUA/8yHAP/OiQD/z4oA/8yIAP/HhQD/v38A/650AP+TYgD/gFUA/39V + AP+CVwD/g1gA/4NXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/g1gB/35T + AP+QZQn/3rI8///VU///3ln/wpcq/3VLAP+EWQL/i2AG/+K3P///2lf//tJR///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//tJR///TUv//1FT//9ZW//vNTP/uuDL/4qMY/9iU + B//SjwX/yYcD/8ODBP+/ggf/vIAI/7h+Cv+3fgz/t30I/7B4B/+fbAf/hFoH/3ZRB/95Uwf/fVYH/4BY + Bf+CWAL/hFgA/4VYAP+EVwD/glcA/4JXAf+CVwD/glcA/4JXAP+CVwD/glcA/4NYAv+BVgD/imIS/+HX + w////////v38//////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////PP//9FK///U + VP//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///UU///1lb//M9O/+u2 + M//anBb/0Y8I/86KA//LhwD/yoYA/8qFAP/KhgD/z40G/8SFA//PigD/zokA/86KAP/OiQD/zIgA/8iF + AP/CggD/rXQA/5JhAP+BVwD/gFUA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4FWAP+ofBn//9ZU///UU//5zU7/r4Qd/39UAP+AVQD/kWUJ/96yPP//2FX//dFR///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NR///TUv//1VT//9ZW//nKSf/mryv/15gR/9CN + Bv/NiQH/y4YA/8qGAP/LhwD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zokA/86KAP/MiAD/yIUA/8CA + AP+tdAD/kWEA/4BWAP9/VQD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4NY + Af9+UwD/kGUJ/96yPP//1VP//95Z/8KXKv91SwD/hFkC/4tgBv/itz///9pX//7SUf//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9RT///WVf/8zk3/7LYz/9ueGf/PjQX/zosD/8qG + AP/JhQD/zIcA/86JAP/PigD/0IoA/9GKAP/SiwD/0osA/9KLAP/RiwD/zYgA/8mFAP+/fwD/qXAA/41d + AP+AVQD/gVYA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+DWAL/gVYA/4pi + Ev/h18P///////79/P////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////zz///R + Sv//1FT//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9VV//zPTv/suDT/2pwW/9CO + Bv/NigL/y4cA/8qGAP/LhgD/y4YA/9COBv/fpR//9MI///jLS/+dcRD/jl4A/6ZvAP+9fwD/z4oA/82J + AP/OiQD/zokA/8yIAP/JhgD/w4IA/6xzAP+QYAD/glcA/4BWAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+BVgD/qHwZ///WVP//1FP/+c1O/6+EHf9/VAD/gFUA/5FlCf/esjz//9hV//3R + Uf//01L//9NS///TUv//01L//9NS///TUv//01L//9RT///VVf/5y0n/57As/9aXEf/PjAT/zYkB/8uG + AP/LhgD/y4cA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/86J + AP/OiQD/zIgA/8mGAP/BgQD/rHMA/5BgAP+AVgD/gFYA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+DWAH/flMA/5BlCf/esjz//9VT///eWf/Clyr/dUsA/4RZAv+LYAb/4rc////aV//+0lH//9NS///T + Uv//01L//9NS///TUv//01L//9NS///UU///1VT//c9O/+y3M//cnxn/zosD/86KA//LhwD/yoYA/8uH + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/LiAD/y4gA/8uIAP/LiAD/zIgA/8yIAP/OiQD/zYkA/8uH + AP/IhQD/vX4A/6VvAP+LXAD/gFUA/4FWAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/g1gC/4FW + AP+KYhL/4dfD///////+/fz///////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////////8 + 8///0Ur//9RU///TUv//01L//9NS///TUv//1FP//9NS///UU//90E//7bk2/9qdF//PjQX/zIkB/8uH + AP/LhgD/y4cA/8uHAP/Qjgb/3qMe//LAPf/90E///tJR///WVP/80VH/mnAS/4BVAP+DWAD/hFgA/45f + AP+mbwD/v38A/86JAP/MiAD/zokA/86JAP/MiAD/y4cA/8OCAP+qcgD/kGAA/4JXAP+BVgD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/gVYA/6h8Gf//1lT//9RT//nNTv+vhB3/f1QA/4BVAP+RZQn/3rI8///Y + Vf/90VH//9NS///TUv//01L//9RT///TUv//1FP/+ctK/+iyLf/WlxH/zosD/8yIAP/LhwD/y4cA/8yH + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/NiQD/zYkA/8yIAP/KhwD/woEA/6tzAP+PYAD/gVYA/4FXAP+BVwD/glcA/4JX + AP+CVwD/g1gB/35TAP+QZQn/3rI8///VU///3ln/wpcq/3VLAP+EWQL/i2AG/+K3P///2lf//tJR///T + Uv//01L//9NS///UU///1FP//9RT//3PTv/tuDT/3J8a/82KAv/NiQL/zIcA/8uGAP/LhwD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/NiAD/zYkA/82JAP/MiAD/yYYA/75+AP+kbgD/ilwA/4FWAP+CVwD/gVcA/4JXAP+CVwD/glcA/4NY + Av+BVgD/imIS/+HXw////////v38//////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////PP//9FK///UVP//1FP//9RT///TUv//01L//M9O/+67OP/bnhj/z4wF/8yIAP/LhwD/y4YA/8uH + AP/MiAD/0I4H/92iHf/xvz3//tFQ///TUv//1FP//9RT///UU///1VP/+89P/5twEf+BVgD/glcA/4FW + AP+BVgD/glcA/4NXAP+PXwD/p28A/8CAAP/NiQD/zIgA/86JAP/OiQD/zIgA/8yIAP/DggD/qXEA/49g + AP+DWAD/glcA/4FWAP+BVgD/gVYA/4FWAP+ofRn//9ZU///UU//5zU7/r4Qd/39UAP+AVQD/kWUJ/96y + PP//2Fb//tJS///UU///01L//9NS//rMSv/psy//1pcR/82KAv/MiAD/zIcA/8uHAP/MhwD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zYkA/82JAP/MiAD/y4gA/8KBAP+qcgD/j18A/4JX + AP+CVwD/gVYA/4JXAf9+UwD/kGUJ/96yPP//1VP//95Z/8KXKv91SwD/hFkC/4tgBv/itz///9tX//7S + Uv//1FP//9NS///TUv/8zk3/7bk1/92gG//NiQH/zIgA/8yHAP/LhwD/zIcA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/82JAP/NiAD/zIgA/8qHAP+9fgD/o20A/4pcAP+CVwD/glcA/4FW + AP+CWAL/gVYA/4tiEv/i18P///////79/P////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////zz///STP//1FX//tJR//zPTv/vvDn/258Z/86MBP/LhwD/y4cA/8uGAP/MhwD/zYkB/9CO + B//doRv/8L47//7SUf//1FP//9NS///UU///01L//9NS///TUv//01L//9VT//vPT/+bcBH/gVYA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4FXAP+CVwD/kF8A/6hwAP/BgQD/zIgA/8uIAP/OiQD/zokA/82J + AP/NiQD/woIA/6hwAP+PYAD/hFkA/4JXAP+AVQD/pnwZ///WVP//1FP/+c1O/6+EHf9/VAD/gFUA/5Fm + Cv/gtD7//9hV//zQT//6y0r/6rQx/9eYEv/NiQH/y4cA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/NiAD/zYgA/8yI + AP/CgQD/qXEA/45fAP+FWQH/f1QA/49kCf/dsTz//9VT///eWf/Clyr/dksA/4RZAv+LYAb/5LhB///b + V//80E///M5N/+66Nv/doRz/zYkB/8uHAP/MhwD/zIcA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/82JAP/LhwD/vX4A/6Fs + AP+KXAD/hFkC/4JXAP+JYBH/4dbC///////9/fz///////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////88//6ykH/7ro1/9ueF//OiwP/y4YA/8uGAP/LhgD/zIcA/82KAv/Rjwj/3KAa/++8 + Of/+0lH//9VU///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///VU//7z0//m3AR/4FW + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+BVgD/gVYA/5FgAP+pcQD/woEA/8qH + AP/LhwD/zokA/86JAP/OiQD/zokA/8GBAP+lbQD/jV0A/6p+Gf//1lT//9RT//nMTv+vhB7/f1QA/4BV + AP+QZQn/2as1//G7Nf/YmRL/zYkB/8uGAP/LiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/82JAP/NiAD/wYAA/6JqAP+cbQr/37M8///VU///31r/wpcr/3VKAP+FWQH/i2AG/96x + Ov/3wzv/3qIc/86KAv/KhQD/y4cA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yJ + Af/OiQH/y4cA/7x8AP+eZwD/kmcS/+LYxf///////v38//////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////9+vX/2qhA/86PEf/NjAv/y4cA/8uHAP/OiwP/0pAJ/9ygGv/uuzj//tJR///W + Vf//1FP//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//1VP/+89P/5tw + Ef+BVgD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/gFYA/4BW + AP+SYQD/qXEA/8KBAP/JhgD/y4cA/86JAP/PiwL/0Y4F/9ORCP/irS3//9VU///XVv/6z1D/r4Md/3xR + AP+BVwH/hFgA/5tmAP+5egD/yIUA/8qHAP/OigD/z4oA/82JAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/y4cA/8qGAP/KhQD/zIkB/86MBP/WlAz/6rEs//vNS//+1FT//+Bb/8OXKf91SgD/glgB/4Na + A/+gagD/v34A/8iFAP/LhwD/z4oA/86KAP/NiQD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAH/zIkB/8yI + AP/LhQD/yoQA/8uHAP/Pjg3/1Zoi/+K9cP/58+f////////+/f////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////7////////////89+//682P/9qhLv/bnhf/7bo3//3RUP//11f//9RT///S + Uf/+0lH//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9VT//vP + T/+bcBH/gVYA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4NX + AP+DWAD/glcA/4BVAP+AVQD/k2IA/6pyAP/BgQD/2J4c/++9Ov//2Vf//9lY//3RUP/8zkz/7708/7iE + Ev+PXwD/iVwB/4NYAP9+VQH/fFQB/4pcAP+ibAD/unwA/8eEAP/JhgD/z4oA/8+KAP/NiQD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIkB/8uH + AP/KhgD/yoQA/82JAf/PjQX/1JQN/+WsKP/2xUP//9hZ///WVv/90E//+MlJ//TAO//JkBP/mmUA/45g + Af+GWgD/gFYB/31UAf+PXwD/p3AA/8CAAP/HhQD/y4cA/8+KAP/OigD/zYgA/8uIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIkB/8yJAv/MiAD/y4UA/8qD + AP/LhwD/z48P/9SbKP/ftWD/8d+7//////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////v/+9uL///DG///nmf//22n//9dW///VVf//0lH//tJR///S + Uf//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///V + U//7z0//m3AR/4FWAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+DWAD/g1gA/4FXAP9/VQD/glkD/6N5GP/Hmy7/6r5E/+28Pf/kqyb/1JQN/8iD + AP/PiQD/z4oA/75/AP+kbQD/k2IA/4pcAP+DVwD/fFMA/3tSAP+LXQD/o20A/7p8AP/FgwD/yYYA/9CK + AP/PigD/zYkA/8uIAP/LiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/82JAf/MhwD/yoYA/8mE + AP/NiQH/0I4H/9WUDv/lrCj/9cRC///ZWf//2Vj//dBP//jIRv/vuzf/4KUg/9COB//HgQD/zIcA/9GM + AP/MiAD/tnkA/55pAP+QYAD/hloA/35UAP97UgD/kGAA/6hwAP+/gAD/xoQA/8uHAP/QiwD/zooA/82I + AP/LhwD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yJAf/MiQL/zIgA/8uFAP/JggD/y4YA/8+Q + Ef/VnCv/37Vg//Ddtv/////////////////+/fz//v38//////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////PX//9NV///QRf/+0Er//tFO//7SUf/+0lH//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//1VP/+89P/5twEf+BVgD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+DVwD/g1gA/4NXAP9/VAD/e1AA/35TAP+faAD/y4YA/8mE + AP/KhQD/zIgA/8+KAP/PigD/0YsA/8+KAP+8fgD/pG0A/5RjAP+LXQD/glcA/3tSAP97UgD/jV4A/6Nt + AP+6fAD/xIIA/8mGAP/QiwD/z4oA/82JAP/LhwD/y4gA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAf/NiQH/zIgA/8qGAP/JgwD/zIgA/9GP + CP/Vlg//5Ksn//TDQf//2Vn//9pa//3QT//3x0X/7ro3/+ClIP/Rjwn/yIIA/8qEAP/JhAD/zIgA/8yJ + Av/MiAD/0IoA/8+KAP/RiwD/y4gA/7V5AP+fagD/kWEA/4ZaAP98UwD/e1IA/5FgAP+ocAD/vn8A/8WD + AP/MiAD/0YsA/86KAP/MiAD/y4cA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiQH/zYkD/8yIAf/LhQD/yYEA/8uFAP/QkBL/1Z4w/9+1 + Yf/v27H//////////////////v37//79+v///v3///////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////zz///RS///1Vj//9RU///TU///01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9VT//vPT/+bcBH/gVYA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/g1gB/4RZAf+EWQL/mGUA/8+K + Af/Tkgv/1ZcT/8CGC/+7fAD/xIMA/8yIAP/QiwD/z4oA/9GLAP/OiQD/u30A/6RtAP+WZAD/jF0A/4FW + AP96UgD/e1IA/45fAP+kbQD/uXwA/8KBAP/KhwD/0YwA/8+KAP/NiAD/y4cA/8uIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiQH/zYkB/8yIAP/KhgD/yIIA/8yHAP/SkAn/1pcQ/+Sr + J//0wkD//9lZ///cXP/+0VD/9sZE/+25Nf/gpSD/0pEK/8eBAP/JhAD/yYQA/8uGAP/Qjgf/05IM/+ar + I//GkBj/qW4A/8KCAf/GhAD/zokA/9CKAP/PigD/0YsA/8qHAP+0eAD/oGsA/5NiAP+GWgD/e1IA/3tS + AP+SYQD/qXEA/71+AP/EggD/zIgA/9GMAP/OigD/zIgA/8uHAP/LiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIkB/82KA//MiQL/y4UA/8mBAP/KhAD/0JET/9ahNP/ftmP/7tmu//7+ + /P////////////79/P/+/Pn//v78//////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////88///0Uv//9RU///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///VU//7z0//m3AR/4FWAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/gVcA/55t + CP/nrif/98ZD//rPUP+tgyD/fVIA/5hmAf+rcgD/vH0A/8OCAP/NiAD/0IsA/8+KAP/SjAD/zYkA/7p8 + AP+lbgD/l2UA/4xeAP9/VQD/eVEA/3tSAP+PXwD/pG4A/7h7AP/BgQD/yocA/9KMAP/PigD/zYkA/82J + Af/NiQH/zIgA/8yIAP/MiAD/y4cA/8uIAf/MiAD/y4YA/8iCAP/LhwD/0pEK/9eZEv/kqyb/88E////Y + WP//3l7//tJQ//XEQv/stzT/4KUg/9OSDP/IggD/yYMA/8mDAP/KhQD/0I4H/9aWD//eoh3/7bg1//jK + Sf//52L/wpcs/25FAP+LXgL/nGgA/7F2AP++fwD/xoQA/8+KAP/QigD/0IsA/9KMAP/JhgD/s3gA/6Fs + AP+UYwD/hVkA/3lRAP97UgD/k2IA/6lxAP+8fQD/w4IA/82JAP/SjAD/zokA/8yIAf/MiQP/zYkC/8yI + AP/MiAD/zIgA/8yJAf/NigT/zYkC/8uGAP/JgAD/yoMA/9CRE//Xozn/4Lhn/+7Yq//9/Pn///////// + ///+/vz//vz5//7+/P////7///////////////////////////////////////////////////////// + //////////7+//7+/v/+/v7//v7+//7+/v/+/v7//v79//79/f/+/f3//v39//79/f/+/f3//v38//39 + +//9/fv//f37//39+//9/fz//fz6//39/P////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////PP//9FK///UVP//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//1VP/+89P/5twEf+BVgD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4FW + AP+pfxz//91b///WVf/4y0z/sIQd/39UAP+BVwH/fFMA/4NXAP+XZAD/qnIA/7p8AP/DggD/zokA/9CL + AP/QigD/0owA/8yIAP+4ewD/pm8A/5lmAP+MXgD/flQA/3hQAP98UwD/kGAA/6RuAP+3egD/wYEA/8mF + AP/HgQD/yoUA/8yIAP/LiAH/y4cA/8+KAf/OiQD/zIcA/9KRCv/YmhT/5Kom//LAPv//11f//99f///T + Uf/1xEH/67Yy/+ClH//Ukw3/yIIA/8iDAP/JgwD/yYQA/9COB//XlxH/36Me/+24Nf/6zEr//9lZ///X + Vv/80FD//95Y/8KWKf93SwD/hVoC/35VAP98UwD/iVsA/5xoAP+xdgD/vX4A/8aEAP/QiwD/0IsA/9GL + AP/RjAD/yIYA/7N3AP+jbQD/lWQA/4VZAP94UAD/fFMA/5RiAP+pcQD/unwA/8OCAf/MhwD/y4MA/8qE + AP/NiQL/zYoF/82JA//LhgD/yYAA/8mBAP/PkBL/2KU+/+G6bP/u16n//fv1//////////////79//78 + +P/+/fv////+///////////////////////////////////////+/vz//fz7//38+v/8+/n//Pv6//z7 + +v/8/Pr//Pv5//////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////zz///RSv//1FT//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9VT//vPT/+bcBH/gVYA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+BVgD/p3wZ///VUv//1FL/+MxO/6+EHf9+UwD/hVkB/4RYAP+DVwD/f1UA/3xTAP+EWAD/l2UA/6py + AP+5ewD/w4IA/8+KAP/QiwD/0IsA/9KMAP/LiAD/uHsA/6dwAP+aZwD/jF0A/31UAP93UAD/fVQA/49e + AP+sdgb/4qYe/9OTDP/NiQH/z4kA/9GMAf/CgQD/voEE/9qiIf/0wT7//9VV///fYP//1FP/9MNB/+q0 + Mf/fpB//1JQO/8mDAP/IggD/yYMA/8mDAP/QjQb/15kS/9+kH//tuDX/+ctJ///ZWf//11b//9NT//7R + UP/+0lH//NBP///gW//Clyr/dUoA/4ZaAv+DWAD/hFgA/4JXAP9+VAD/fFMA/4pcAP+caAD/sHUA/7x9 + AP/GhAD/0YsA/9CLAP/RiwD/0YsA/8eFAP+zdwD/pG4A/5ZkAP+EWAD/d1AA/35UAf+SYAD/sX0S/9Og + OP/UmSP/yYIA/8d9AP/JgQD/z48Q/9mmQf/ivXH/7tep//z58f///////////////v/+/Pj//v37///+ + /v///////////////////////////////////////////////v/+/v3///////////////////////// + ///////////////////+/v7//Pr4//z7+f/8+/n//Pv5//z7+f/08Oj/7ObZ/+3n2v/t5tr/7efa/+3n + 2v/l3cv/3NC4/97Su//d0bv/3dG6/+DVwP/RwqL/4dbA//7+/f////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////88///0Ur//9RU///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///VU//7z0//m3AR/4FWAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/gVYA/6h8Gf//1lT//9RT//nNTv+vhB3/flMA/4RZAf+CVwD/glcA/4NYAP+EWAD/glcA/39V + AP98UwD/hlkA/5dlAP+pcQD/uHoA/8OCAP/QiwD/0IsA/9GLAP/RjAD/yocA/7h6AP+pcQD/m2gA/41f + Av91TQD/kGkR///hXP/zwkH/5K0r/76DCP+ocQD/kF8A/59zEf/vxk7//9pY//HBQP/psi//36Qe/9WV + Dv/KhAD/yIIA/8mDAP/IggD/z40F/9iaE//hpiH/7bk2//nKSP//2Vj//9hX///UU//+0VD//tJR///S + Uf//01L//9NS//zQUP//4Fv/wpcq/3VKAP+FWgL/glcA/4JXAP+DVwD/g1gA/4RYAP+BVgD/fVQA/3xT + AP+LXQD/nGgA/650AP+7fAD/x4UA/9GMAP/QigD/0YsA/9GLAP/GhAD/s3gA/6ZvAf+YaAf/flIA/49w + Mf/h1sD/+OnK/+TBfP/dr1P/4r1y/+7Xq//79uz//////////////////vz4//79+v///v7///////// + ///////////////////////////////////////////////+/P/+/////////+zk0P/VyKr/zr2a/8e0 + jf/JtpD/yLaP/8i1jv/KuJP/tp1r/7KYYv+0mWX/s5lk/7SZZf+zmWT/qIpN/518OP+efTn/nn05/559 + Of+efTn/lG8l/4deC/+JYRD/iWAP/4hfDv+OZhj/dkcA/5x6Nv/z7+b///////7+/f////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////PP//9FK///U + VP//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//1VP/+89P/5twEf+BVgD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4FWAP+ofBn//9ZU///UU//5zU7/r4Qd/35TAP+EWQH/glcA/4JXAP+CVwD/glcA/4JX + AP+DWAD/hFgA/4JXAP9+VQD/fFMA/4daAP+XZQD/qHAA/7d6AP/EgwD/0YsA/9CLAP/RiwD/0YwA/8mG + AP+2dwD/oWYA/656DP//2lf//9VU//XKTv+lexr/elAA/35UAP+SZwr/0J0k/+eqH//bmQ7/zYgA/8iC + AP/JgwD/yIIA/8+MBP/ZmhT/4qgj/+65Nv/4yUf//9hY///YWP//1VT//tFQ//7SUP//0lH//9NS///T + Uv//01L//9NS///TUv/80FD//+Bb/8KXKv91SgD/hVoC/4JXAP+CVwD/glcA/4JXAP+CVwD/g1cA/4NY + AP+EWAD/gVYA/31UAP99UwD/jF0A/5toAP+tcwD/unwA/8iGAP/SjAD/0IsA/9GLAP/PiAD/wnwA/6xp + AP+4izH/7ufY//////////////////////////////////78+f/+/fr///79//////////////////// + ///////////////////////////////////////////////+/P///////f3+///0u//atFD/kGcN/3hK + AP90QwD/dEUA/3REAP90RQD/dEQA/3hJAP95SwD/eEoA/3hKAP94SgD/eUoA/3tNAP99UAD/fVAA/31Q + AP99UAD/fVAA/39TAP+CVwD/gVYA/4FWAP+BVgD/gVYA/4VbBf+EWwb/2cyy///////9/fz///////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////zz///R + Sv//1FT//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9VT//vPT/+bcBH/gVYA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+BVgD/qHwZ///WVP//1FP/+c1O/6+EHf9+UwD/hFkB/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/g1gA/4RYAP+BVwD/flQA/3xTAP+IWwD/lmQA/6dvAP+2eQD/xYMA/9GL + AP/SjQP/25sR/+SoIf/suDb//9ZW///bWf/2yk3/o3cU/3lQAP+BVwH/hVoC/5RiAP+haQD/rHAA/7p4 + AP/MiQP/2ZsU/+OpJP/uujf/+MlH///XV///2Vj//9VU//7SUP/+0lD//9JR///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//NBQ///gW//Clyr/dUoA/4VaAv+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4NXAP+DWAD/g1gA/4BWAP99UwD/flQA/4xdAP+aZwD/q3IA/7p7AP/KiAP/2Joe/9+v + T//pxXr/896z//z58////v3//vz5///+/v/+/fv//v36///+/f////////////////////////////// + ///////////////////////////////////////////////+/P////////75//7no///1FT/+sxG/6V6 + GP96UAD/iF4J/4VbB/+FXAf/hVwH/4VcB/+FWwX/hVoF/4VaBf+FWgX/hVoF/4VaBf+EWgT/hFkD/4RZ + A/+EWQP/hFkD/4RZA/+DWQP/g1gC/4NYAv+DWAL/g1gC/4NYAv+GXAj/dUUA/72meP////////////// + /v////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////////8 + 8///0Ur//9RU///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///VU//7z0//m3AR/4FWAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/gVYA/6h8Gf//1lT//9RT//nNTv+vhB3/flMA/4RZAf+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/g1cA/4NYAP+DWAD/gVYA/35UAP99UwD/iFsA/5Vk + AP+ocgT/x5Md/+y8Pv//41///+Be//bGRP/tuDT/3aMe/7+CBv+obwD/l2UB/4RYAP9xSAD/fVQB/6N3 + FP/PnSX/7bo4//jJRv//1lX//9lY///VVP/+0lH//tJQ//7SUf//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS//zQUP//4Fv/wpcq/3VKAP+FWgL/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+DVwD/g1gA/4NYAP+AVgD/fFMA/39VAP+MXQD/mmgC/7SL + N//ayab///////////////////7+//////////7///////////////////////////////////////// + ///////////////////////////////////////////+///+/P////////nr///giP//01L//dBO///d + XP/EmSz/gFUA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/g1kC/4BUAP+Xcyn/6eLS//// + ///+/f3///////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////PP//9FK///UVP//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//1VP/+89P/5twEf+BVgD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4FWAP+ofBn//9ZU///UU//5zU7/r4Qd/35TAP+EWQH/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4NXAP+DWAD/g1gA/4BW + AP99VAD/f1YD/5FoDv+jeRj/uo4k/8uXH//YmBD/zosE/8qFAP/QigD/zooB/8KBAP+8gAb/w5Mi/9mt + Ov/twUb//dNU///ZWP//1VX//tJR//7SUf/+0lH//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv/80FD//+Bb/8KXKv91SgD/hVoC/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/g1cA/4NYAP+DWAD/gFUA/3xT + AP+CWwz/lXIr/6aGR//Kt5D/9fLr///////+/v7///////////////////////////////////////// + ///////////////////////////////////////////+/////f////////XZ///bcv//0Uz//9NS//3S + U///2FX/4rc//5RpDP9+UwD/g1gB/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+FWwb/eEoA/9TF + p////////v38//////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////zz///RSv//1FT//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9VT//vPT/+bcBH/gVYA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+BVgD/qHwZ///WVP//1FP/+c1O/6+EHf9+UwD/hFkB/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+DVwD/g1gA/4NXAP9+UwD/ek8A/3hNAP+RXgD/0IkA/8eCAP/IgwD/zIcA/9ONAf/OiAD/2ZgO//zL + Rf//3lv//9dU///TUv/+0lH//9JR///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//NBQ///gW//Clyr/dUoA/4VaAv+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4NX + AP+DWAD/glYA/39SAP90RQD/lHAl/+jh0P///////f38//////////////////////////////////// + //////////////////////////////////////////79//////////////DE///XYf//0Ur//9RV///T + U///01L//dFR///YVf+ugx3/eU4A/4RZAf+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/hFoF/3pM + AP+wlV7/9/Tu///////+/v7///////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////88///0Ur//9RU///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///VU//7z0//m3AR/4FW + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/gVYA/6h8Gf//1lT//9RT//nNTv+vhB3/flMA/4RZ + Af+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/g1gB/4RZAf9/VgH/jV8A/9SPA//epB//4q0u/7F+Ef+hawD/u3sA/9eX + D//3xkL//9RU//3RUP//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS//zQUP//4Fv/wpcq/3VKAP+FWgL/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAf+FWgX/f1MA/5h1Lv/m3s3///////39/P////////////////////////////// + //////////////////////////////////////////79/////////////+ij///VXP//0Ur//9RW///T + Uv//01L//9NS//zQUP//31r/y58w/4RZAf+BVgD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JY + Af+EWQP/g1gB/+TbyP///////f38//////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////////////////PP//9FK///UVP//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//1VP/+89P/5tw + Ef+BVgD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4FWAP+ofBn//9ZU///UU//5zU7/r4Qd/35T + AP+EWQH/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+DWAD/fFIA/5ZqC//+zUf//M9N//PITP+jeRn/fVIA/4la + AP+mdg//675C///XVf/+0lH//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv/80FD//+Bb/8KXKv91SgD/hVoC/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/g1kD/31QAP+YdS3/59/O///////9/fz///////////////////////// + //////////////////////////////////////////79/////////ff//9+G///TU///0k3//9RV///T + Uv//01L//9NS///TUv/+0lH//9RT//PHSv+dchL/e1AA/4NYAf+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/hVsG/3dJAP/Gsor///////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////zz///RSv//1FT//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9VT//vP + T/+bcBH/gVYA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+BVgD/qHwZ///WVP//1FP/+c1O/6+E + Hf9+UwD/hFkB/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/g1gB/3tQAP+Ybg///+Je///VVP/yxkn/pXkW/35T + AP98UgD/lWsP/+e7Q///2FX//dFR///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//NBQ///gW//Clyr/dUoA/4Va + Av+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4NZA/99UAD/mHUt/+ffzv///////f38//////////////////// + ///////////////////////////////////////////9////////+eX//913///RTf//01H//9NT///T + Uv//01L//9NS///TUv//01L//9NS//zQUP//3lr/s4gg/3tQAP+DWAH/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4NZA/9/UwD/nnw5//Dr4P///////v7+//////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////88///0Ur//9RU///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///V + U//7z0//m3AR/4FWAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/gVYA/6h8Gf//1lT//9RT//nN + Tv+vhB3/flMA/4RZAf+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4NYAP98UQD/mG0O///cWP//01L/8sZJ/6V5 + F/9+UwD/f1QA/5luD//ovEP//9hV//7SUf//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS//zQUP//4Fv/wpcq/3VK + AP+FWgL/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+DWQP/fVAA/5h1Lf/n387///////39/P////////////// + ///////////////////////////////////////////+////////8cn//9lp///STf//01P//9NT///T + Uv//01L//9NS///TUv//01L//9NS///TUv/90VH//9lW/9qvOv+OZAj/f1QA/4NYAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/hVsG/3lLAP/e073///////7+/f////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////PP//9FK///UVP//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//1VP/+89P/5twEf+BVgD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4FWAP+ofBn//9ZU///U + U//5zU7/r4Qd/35TAP+EWQH/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+DWAD/fFEA/5htDv//3Vn//9RS//LG + Sf+leRf/flMA/39UAP+ZbQ//6LxD///YVf/+0lH//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv/80FD//+Bb/8KX + Kv91SgD/hVoC/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/g1kD/31QAP+YdS3/59/O///////9/fz///////// + ////////////////////////////////////////////////////6ar//9VZ///STv//01P//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS//3RUf//2FX/onYV/3lOAP+EWQH/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4VaBf96TAD/uKBv//v59v/////////+//////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////zz///RSv//1FT//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9VT//vPT/+bcBH/gVYA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+BVgD/qHwZ///W + VP//1FP/+c1O/6+EHf9+UwD/hFkB/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/g1gA/3xRAP+YbQ7//91Z///U + Uv/yxkn/pXkX/35TAP9/VAD/mW0P/+i8Q///2FX//tJR///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//NBQ///g + W//Clyr/dUoA/4VaAv+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4NZA/99UAD/mHUt/+ffzv///////f38//// + ///////////////////////////////////////////////++///5JX//9NU///STv//01P//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv/80FD//9xY/8OYK/+DWQH/gVYA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+DWAL/glcA/45mF//u59v///////7+/f////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////88///0Ur//9RU///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///VU//7z0//m3AR/4FWAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/gVYA/6h8 + Gf//1lT//9RT//nNTv+vhB3/flMA/4RZAf+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4NYAP98UQD/mG0O///d + Wf//1FL/8sZJ/6V5F/9+UwD/f1QA/5ltD//ovEP//9hV//7SUf//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS//zQ + UP//4Fv/wpcq/3VKAP+FWgL/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+DWQP/fVAA/5h1Lf/n387///////39 + /P/////////////////////////////////////////////55///3X///9NR///TUP//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//tJR///VU//rv0T/lGkM/31S + AP+DWAH/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4VbBv95SwD/08Sl//////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////PP//9FK///UVP//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//1VP/+89P/5twEf+BVgD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4FW + AP+ofBn//9ZU///UU//5zU7/r4Qd/35TAP+EWQH/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+DWAD/fFEA/5ht + Dv//3Vn//9RS//LGSf+leRf/flMA/39UAP+ZbQ//6LxD///YVf/+0lH//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv/80FD//+Bb/8KXKv91SgD/hVoC/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/g1kD/31QAP+YdS3/59/O//// + ///9/fz////////////////////////////////////////01P//2Gb//9JP///TUf//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv/80FD//99a/6h9 + Gf97UAD/g1gB/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+EWQP/flIA/6mLT//39O/////////+ + /v////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////zz///RSv//1FT//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9VT//vPT/+bcBH/gVYA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+BVgD/qHwZ///WVP//1FP/+c1O/6+EHf9+UwD/hFkB/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/g1gA/3xR + AP+YbQ7//91Z///UUv/yxkn/pXkX/35TAP9/VAD/mW0P/+i8Q///2FX//tJR///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//NBQ///gW//Clyr/dUoA/4VaAv+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4NZA/99UAD/mHUt/+ff + zv///////f38///////////////////////////////////vwP//1Vj//9JO///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//dFR///Z + Vv/RpTT/iV4F/39UAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4RaBf9+UgD/7OXX//// + ///+/v7///////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////88///0Ur//9RU///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///VU//7z0//m3AR/4FWAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/gVYA/6h8Gf//1lT//9RT//nNTv+vhB3/flMA/4RZAf+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4NY + AP98UQD/mG0O///dWf//1FL/8sZJ/6V5F/9+UwD/f1QA/5ltD//ovEP//9hV//7SUf//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS//zQUP//4Fv/wpcq/3VKAP+FWgL/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+DWQP/fVAA/5h1 + Lf/n387///////39/P////////////////////////35///nof//01P//9JP///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS//7S + Uv/+0lH/+s5P/5hsDv98UQD/g1gB/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+EWgT/e04A/8Ww + iP/+/v3///////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////PP//9FK///U + VP//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//1VP/+89P/5twEf+BVgD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4FWAP+ofBn//9ZU///UU//5zU7/r4Qd/35TAP+EWQH/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+DWAD/fFEA/5htDv//3Vn//9RS//LGSf+leRf/flMA/39UAP+ZbQ//6LxD///YVf/+0lH//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv/80FD//+Bb/8KXKv91SgD/hVoC/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/g1kD/31Q + AP+YdS3/59/O///////9/fz//////////////vz///33///fhf//0k3//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//NBQ///dWP+0iSH/gVYA/4JWAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/g1gC/4FW + AP+YdS3/9PHq//////////7///////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////zz///R + Sv//1FT//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9VT//vPT/+bcBH/gVYA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+BVgD/qHwZ///WVP//1FP/+c1O/6+EHf9+UwD/hFkB/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/g1gA/3xRAP+YbQ7//91Z///UUv/yxkn/pXkX/35TAP9/VAD/mW0P/+i8Q///2FX//tJR///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//NBQ///gW//Clyr/dUoA/4VaAv+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4NZ + A/99UAD/mHUt/+ffzv///////f38/////v////////zy///bcf//0Un//9NU///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS//7SUf//1VT/4bY+/4xhBv9+UwD/g1gA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+FWgX/eUsA/9zRuf////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////////8 + 8///0Ur//9RU///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///UU//7zk//m3AR/4JXAP+DWAD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/gVYA/6h8Gf//1lT//9RT//nNTv+vhB3/flMA/4RZAf+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4NYAP98UQD/mG0O///dWf//1FL/8sZJ/6V5F/9+UwD/f1QA/5ltD//ovEP//9hV//7S + Uf//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS//zQUP//4Fv/wpcq/3VKAP+FWgL/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+DWQP/fVAA/5h1Lf/n387///////39/P////7////+///++v//3HP//9FK///TU///01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//NBQ///aV/+dcRL/fVIA/4NYAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/g1kD/39TAP+ymGP//Pv4//////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////PP//9FK///UVP//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//0lH//tJR///UU///11b//tNU/5pvEf99VAD/gVYA/4JX + AP+DVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4FWAP+ofBn//9ZU///UU//5zU7/r4Qd/35TAP+EWQH/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+DWAD/fFEA/5htDv//3Vn//9RS//LGSf+leRf/flMA/39UAP+ZbQ//6LxD///Y + Vf/+0lH//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv/80FD//+Bb/8KXKv91SgD/hVoC/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/g1kD/31QAP+YdS3/59/O///////9/fz////////++////////+aa///TUP//01H//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS//3RUf//2FX/y58w/4ZbA/+AVQD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+DWQP/g1cC//Lu5f/////////+//////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////zz///RSv//1FT//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9JR//7SUf//1FP//9ZV///YWP/+0lD/+stJ//HAPv+rdwj/j18A/4hb + AP+AVQD/flQA/4BWAP+CVwD/g1gA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+BVgD/qHwZ///WVP//1FP/+c1O/6+EHf9+UwD/hFkB/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/g1gA/3xRAP+YbQ7//91Z///UUv/yxkn/pXkX/35TAP9/VAD/mW0P/+i8 + Q///2FX//tJR///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//NBQ///gW//Clyr/dUoA/4VaAv+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4NZA/99UAD/mHUt/+ffzv///////f38//////////3////////23f//12L//9FL///T + U///01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv/+0lL//9NS//DESP+QZQn/flMA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/hFkD/31QAP/QwaH///////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////88///0Ur//9RU///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///SUf/+0lH//9NS///WVf//2Vj//tJR//jJR//zwT7/5Kwn/9aXEf/JhQD/0IoA/8qH + AP+1eQD/nmkA/5FhAP+IWwD/f1UA/31UAP+AVgD/g1cA/4NYAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/gVYA/6h8Gf//1lT//9RT//nNTv+vhB3/flMA/4RZ + Af+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4NYAP98UQD/mG0O///dWf//1FL/8sZJ/6V5F/9+UwD/f1QA/5lt + D//ovEP//9hV//7SUf//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS//zQUP//4Fv/wpcq/3VKAP+FWgL/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+DWQP/fVAA/5h1Lf/n387///////39/P/////////////+/P///////916///R + S///01P//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS//zQUP//3Vn/q4Aa/4BVAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4NYAf+CVgD/mngy//38+v////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////////////////PP//9FK///UVP//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//0lH//tJQ///TUv//1lX//9lZ///TUv/4yEb/8sA9/+SsJ//XmBL/yYUA/8iDAP/LhgD/zYkC/8uH + AP/LiAD/z4oA/9KMAP/KhgD/tHgA/59qAP+SYgD/iFsA/35UAP99VAD/gVYA/4NYAP+DWAD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4FWAP+ofBn//9ZU///UU//5zU7/r4Qd/35T + AP+EWQH/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+DWAD/fFEA/5htDv//3Vn//9RS//LGSf+leRf/flMA/39U + AP+ZbQ//6LxD///YVf/+0lH//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv/80FD//+Bb/8KXKv91SgD/hVoC/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/g1kD/31QAP+YdS3/59/O///////9/fz//////////////vz////////t + t///1Vn//9JP///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv/+0lH//9VT/9mtOf+HXAP/gFUA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/g1kC/4BUAP/r5Nb///////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////zz///RSv//1FT//9NS///TUv//01L//9NS///TUv//01L//9JR//7R + UP//0lL//9VV///ZWf//1FP/98hG//G+O//krCf/15kS/8qGAP/IggD/y4YA/82JAv/NigL/zYkB/8yI + AP/MiAD/zIgA/8uHAP/KhwD/zIgA/9CKAP/SjAD/yIYA/7N4AP+gawD/lGMA/4daAP99VAD/fVQA/4FW + AP+DWAD/g1gA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+BVgD/qHwZ///WVP//1FP/+c1O/6+E + Hf9+UwD/hFkB/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/g1gA/3xRAP+YbQ7//91Z///UUv/yxkn/pXkX/35T + AP9/VAD/mW0P/+i8Q///2FX//tJR///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//NBQ///gW//Clyr/dUoA/4Va + Av+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4NZA/99UAD/mHUt/+ffzv///////f38///////////////+//// + /v///PT//9hn///RS///01P//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS//3RUf//11T/k2gL/35T + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4NYAv+AVAD/u6N0///+/v////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////88///0Ur//9RU///TUv//01L//9NS///SUf/+0VD//tJR///V + VP//2ln//9ZV//fIRv/wvTn/5Kwm/9iZE//LhwD/yIIA/8qGAP/NiQH/zYoC/82JAf/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/LhwD/yocA/8yIAP/QiwD/0owA/8eFAP+zdwD/oWsA/5Vj + AP+GWgD/fFMA/31UAP+BVwD/hFgA/4NYAP+CVwD/glcA/4JXAP+CVwD/gVYA/6h8Gf//1lT//9RT//nN + Tv+vhB3/flMA/4RZAf+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4NYAP98UQD/mG0O///dWf//1FL/8sZJ/6V5 + F/9+UwD/f1QA/5ltD//ovEP//9hV//7SUf//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS//zQUP//4Fv/wpcq/3VK + AP+FWgL/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+DWQP/fVAA/5h1Lf/n387///////39/P////////////// + /////vv////////ijf//0lD//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv/90VH//9hV/7mO + JP+EWQH/gVYA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/5JtIf/49fD///////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////PP//9FK///TVP//0lH//tFQ//7SUf//1VT//9lZ///X + Vv/3yEb/77s4/+SrJv/YmRP/zIgA/8eCAP/KhQD/zYkB/82KAv/NiQH/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/y4cA/8qHAP/MiAD/0YsA/9KM + AP/GhAD/s3cA/6JsAP+VZAD/hVkA/3xTAP99VAD/glcA/4RYAP+DWAD/glcA/4FWAP+ofBn//9ZU///U + U//5zU7/r4Qd/35TAP+EWQH/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+DWAD/fFEA/5htDv//3Vn//9RS//LG + Sf+leRf/flMA/39UAP+ZbQ//6LxD///YVf/+0lH//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv/80FD//+Bb/8KX + Kv91SgD/hVoC/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/g1kD/31QAP+YdS3/59/O///////9/fz///////// + ///////////+////////89D//9Vb///STv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv/uw0f/hVoC/39UAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4NYAv98TwD/3dG6//// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////zz//7PSf/+0lL//9VU///ZWf//2Fj/+MlG/+66 + N//jqiX/2JkT/82JAv/HgQD/yoUA/8yIAP/NigL/zYkB/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8uH + AP/KhwD/zYgA/9GLAP/RiwD/xYQA/7N3AP+kbQD/lmQA/4RYAP97UgD/flQA/4JXAP+DVwD/qH0Z///W + VP//1FP/+c1O/6+EHf9+UwD/hFkB/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/g1gA/3xRAP+YbQ7//91Z///U + Uv/yxkn/pXkX/35TAP9/VAD/mW0P/+i8Q///2FX//tJR///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//NBQ///g + W//Clyr/dUoA/4VaAv+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4NZA/99UAD/mHUt/+ffzv///////f38//// + /////////////////////v3////////acP//0k3//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv/+0lH//9dV/590E/+BVgD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/6mL + T/////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////89P//2lf//9xg//nKSf/tuTb/4qkk/9iZ + E//OiwP/yIIA/8qEAP/MiAD/zYoC/82JAf/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8uIAP/LhwD/y4cA/82JAP/RjAD/0IsA/8SDAP+0eAD/pW4A/5ZlAP+DWAH/e1MB/6Z8 + G///1lT//9RT//nNTv+vhB3/flMA/4RZAf+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4NYAP98UQD/mG0O///d + Wf//1FL/8sZJ/6V5F/9+UwD/f1QA/5ltD//ovEP//9hV//7SUf//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS//zQ + UP//4Fr/wpcq/3VKAP+FWgL/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+DWQP/fVAA/5h1Lf/n387///////39 + /P////////////////////////78////////56T//9RV///TUf//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//tJR///VU//OojL/hFkB/4FWAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+EWQP/8ezi//////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////++vD/56oT/9+jGP/XmBH/0I8M/8mE + AP/KhQD/zIcA/82KAv/NiQH/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/LiAD/y4cA/8uHAP/OiQD/0owB/9GMAv/FhAL/tHcA/6Jp + AP+zgBP//9ZU///TUv/3y0z/sIQd/4BUAP+FWQH/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+DWAD/fFEA/5ht + Dv//3Vn//9RS//LGSf+leRf/flMA/39UAP+ZbQ//6LxD///YVf/+0lH//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv/7z07//95Z/8KWKv92SwD/h1sC/4NXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/g1kD/31QAP+YdS3/59/O//// + ///9/fz//////////////////////////v////7///rq///VWv//0k7//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L/9spM/41iB/+AVQD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/gVYA/8Wxif////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////v36/+zPk//ZqU3/zYwO/8Z6 + AP/LhQD/zYkC/86MCP/NigT/zIkB/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yJAf/NiQL/zYkC/8qGAP/IgwD/yoQA/9qY + Df/jqCD/7Ls8///TUv//2Ff//NNV/6yDIf93TgD/gVcB/4NYAP+EWAD/g1gA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/g1gA/3xR + AP+YbQ7//91Z///UUv/yxkn/pXkX/35TAP9/VAD/mW0P/+i8Q///2FX//tJR///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//tJR//7R + UP//01L//9VV///kYP/FmCr/ckgA/39WAv+BVgD/hFgA/4RYAP+DVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4NZA/99UAD/mHUt/+ff + zv///////f38//////////////////////////////78////////3n3//9NQ///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//tJR///YVv+yhh//glcA/4JXAP+CVwD/glcA/4JXAP+DVwD/g1cA/4NX + AP+DVwD/g1cA/4NXAP+DWAD/g1gA/4NYAP+DWAD/g1gA/4NYAP+EWAD/hFgA/4RYAP+EWAD/hFgA/4RY + AP+EWAD/hFgA/4RYAP+ZdSv///////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////Pbr//Xm + yf/qzpX/3a5T/8+ODf/HewD/yoQA/8yJAv/Niwf/zYkD/8yIAf/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiQH/zYkB/82KAv/MhwD/yYQA/8iDAP/Tkwz/4KYh/+66 + N//1xUP//9NS///fXv//0lH/8r87/+CmIf/Chgn/qXAA/5VkAP+AVQD/fFMA/4BWAP+DWAD/hFgA/4NX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4NY + AP98UQD/mG0O///dWf//1FL/8sZJ/6V5F/9+UwD/f1QA/5ltD//ovEP//9hV//7SUf//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS//7SUf/+0VD//9NS///X + Vv//2Vn//M5N/+y3NP/hph//y4wK/7F1AP+kbgH/jV4A/31TAP99VAD/glcA/4RYAP+DWAD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+DWQP/fVAA/5h1 + Lf/n387///////39/P///////////////////////////////v///////+6+///UVf//01D//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L/5bpB/4JXAP+DVwD/hFgA/4RYAP+DWAD/gVcA/4JX + AP+CVwD/glcA/4JXAP+BVgD/f1UA/39VAP9/VQD/f1UA/39VAP9+VAD/fVMA/31TAP99UwD/fVMA/31T + AP98UwD/elIA/3pSAP96UQD/fFUG/9vPuf/////////+//////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////79//// + //////////////v16v/158z/6s+X/9yuUv/Niwj/x3wA/8uFAP/NiQP/zYsG/82JA//MiAH/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/82JAf/NigL/zIgA/8qEAP/IgwD/05IL/+GnIf/vvDj/98dF//7S + Uf//3l7//9dW//LAPf/gpiH/15kS/9GPCP/LhgD/zogA/86JAP/EggD/uXsA/6pyAP+TYgD/f1UA/3xT + AP+BVgD/g1gA/4RYAP+DVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+DWAD/fFEA/5htDv//3Vn//9RS//LGSf+leRf/flMA/39UAP+ZbQ//6LxD///YVf/+0lH//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv/+0lH//tFQ///SUf//1lX//9lY//3P + Tv/tuDX/3qId/9aWEP/QjQX/yYMA/8yHAP/RjAH/yocA/8CAAP+1eQD/pG4A/4xdAP98UwD/fVQA/4JX + AP+EWAD/g1gA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/g1kD/31Q + AP+YdS3/59/O///////9/fz////////////////////////////////////+///+/P//2Wj//9JP///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//tJR///TUv+VbBH/elEA/3pSAP96UgD/gFYA/4tc + AP+KXAD/ilwA/4pcAP+JWwD/kGAA/5toAP+ZZgD/mWcA/5lnAP+YZgD/oGsA/6hwAP+pcQD/qXEA/6lx + AP+pcQD/q3IA/7d6AP+4fAP/t3oA/7V3AP/o2rz//////////v////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////v3//v78///+/v/////////////////79ev/9unP/+vPmP/crVD/zIkC/8h+AP/LhgD/zYoE/82K + Bf/MiQL/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/NiQH/zYoC/8yIAP/KhQD/yIMA/9KRCv/hpyH/8L05//jIRv/90VD//91d///Y + V//zwT7/4aYg/9aWD//Rjwf/y4YA/8mDAP/LhgD/zIgA/8yIAP/MiAD/z4oA/9CLAP/MiAD/xIMA/7p8 + AP+qcgD/kmEA/39VAP99VAD/gVcA/4NYAP+DWAD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/g1gA/3xRAP+YbQ7//91Z///UUv/yxkn/pXkX/35TAP9/VAD/mW0P/+i8Q///2FX//tJR///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//tJR//7SUP/+0lH//9VV///ZWP/90E//7rk2/96i + HP/VlQ7/0I0G/8qFAP/JhAD/y4cA/82JAf/MiAH/y4cA/82IAP/PigD/0IsA/8qHAP/BgQD/tnkA/6Rt + AP+KXAD/fFMA/35VAP+CVwD/hFgA/4NYAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4NZ + A/99UAD/mHUt/+ffzv///////f38/////////////////////////////////////f///////+SV///T + Uv//01H//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//tJR///UU//8z07/zpMU/7p8AP+7fAD/u3wA/71+ + AP/BgAD/wIAA/8GAAP/BgAD/wIAA/8OCAP/HhQD/xoQA/8aEAP/GhAD/xoQA/8mGAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/82IAP/SjQP/0YkA/9WTEf/03Kz///76//////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////7+///+/f//////////////////////+/bs//br0//rz5j/3KxN/8uH + AP/IfwD/y4YA/82KBP/NigT/zIkC/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIkB/82JAf/MiAD/yoYA/8mDAP/Rjwj/4KYh//C9Ov/5ykj//dBP///bW///2Ff/9MJA/+Gm + IP/VlQ7/0I4H/8uHAP/JhAD/yoYA/8yIAP/NiQH/zIgA/8yIAP/MiAD/zIgA/8uIAP/LiAD/zIgA/8+K + AP/QiwD/zIgA/8WDAP+7fQD/qnIA/5BgAP9+VAD/flQA/4JXAP+DWAD/g1gA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4NYAP98UQD/mG0O///dWf//1FL/8sZJ/6V5F/9+UwD/f1QA/5ltD//ovEP//9hV//7S + Uf//01L//9NS///TUv//01L//9NS///SUf/+0lH//tJR///VVP//2Ff//tFQ/++6N//doRv/1JMM/8+N + Bf/KhgD/yYQA/8uGAP/MiAD/zYkB/8yIAP/MiAD/zIgA/8yIAP/MiAD/y4gA/8uIAP/NiQD/z4oA/8+K + AP/KhwD/woIA/7d6AP+jbQD/iVsA/31TAP9/VQD/glcA/4NYAP+DWAD/glcA/4JXAP+CVwD/glcA/4JX + AP+DWQP/fVAA/5h1Lf/n387///////39/P/////////////////////////////////////////////3 + 4f//1FX//9NQ///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//tJR///VVf/3yEX/15kT/9GMAv/RiwD/0YsA/9GL + AP/QiwD/z4oA/8+KAP/PigD/z4oA/8+KAP/PigD/zokA/86JAP/OiQD/zokA/86JAP/NiQD/zYgA/8yI + AP/NiAD/zYgA/8yIAP/NigX/yYMA/9ahN//z5cj///////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////+/v///v3///////////////////////z3 + 7v/37df/6s6X/9uqSv/LhQD/yYEA/8uHAP/NigP/zYkD/8yJAf/MiAD/zIgA/8yIAP/MiAD/zIgA/8yJ + Av/NiQH/zIgA/8uGAP/JhAD/0I4H/+CmIP/wvTr/+stK//3QTv//2Vn//9hX//XEQf/hpiH/1JMM/9CN + Bv/MiAD/yoQA/8qGAP/MiAD/zIkB/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/OigD/z4oA/8uIAP/GhAD/vH4A/6pxAP+PXwD/flQA/39VAP+CVwD/g1gA/4NX + AP+CVwD/glcA/4JXAP+DWAD/fFEA/5htDv//3Vn//9RS//LGSf+leRf/flMA/39UAP+ZbQ//6LxD///Y + Vf/+0lH//9NS///TUv//01L//tJR///SUf//1FP//9dW//7RUP/wvDn/3aEb/9OSCv/PjAX/y4YA/8qE + AP/LhgD/zIgA/8yJAf/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8uI + AP/MiAD/zYkA/8+KAP/PigD/yocA/8SDAP+4ewD/om0A/4hbAP99VAD/gFYA/4JXAP+DWAD/g1cA/4JX + AP+CVwD/g1kD/31QAP+YdS3/59/O///////9/fz///////////////////////////////////////// + /v///////9lv///TUP//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//tJQ///XVv/wvDj/0pEK/8qFAP/LhwD/y4gA/8uI + AP/LiAD/y4gA/8uIAP/LiAD/y4gA/8uIAP/LiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/NigX/yYEA/9ytUf/68+X///////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////7///7+//// + ///////////////////8+PH/+O/b/+rOlf/aqUf/yoQA/8qDAP/LhwD/zIkC/8yJAv/MiQH/zIkC/8yI + Af/LhgD/yoUA/8+NBf/gpSD/8L06//vNTP/90E///9dX///XVv/2xUP/4qgi/9OSC//PjAX/zIgA/8qF + AP/LhgD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/NiAD/zooA/8+KAP/LhwD/x4QA/71+AP+pcQD/jV4A/39V + AP+AVQD/glcA/4NXAP+CVwD/g1gA/3xRAP+YbQ7//91Z///UUv/yxkn/pXkX/35TAP9/VAD/mW0P/+i8 + Q///2FX//dFR///SUf//01L//9RT///WVf/+0lD/8L06/92hG//SkAn/zowE/8uHAP/KhQD/y4YA/8yI + AP/MiAH/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/82JAP/PigD/zokA/8qHAP/FgwD/uXsA/6FsAP+HWgD/flUA/4FW + AP+CVwD/g1cA/4RZA/99UAD/mHUt/+ffzv///////f38//////////////////////////////////// + ///////////////stv//01P//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//tJR///UVP/psy//z40G/8qFAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAf/NiQL/yoUA/+XCff/8+fH///////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////+/////v///////////////////////fr0//nw3v/qzZP/2qdE/8qEAP/LhQD/y4YA/8qE + AP/OjxL/37JV/++/Q//8z03//dFQ///WVf//1lb/9sZE/+OpJP/Tkgv/zosD/8yIAP/KhgD/y4YA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zYgA/86JAP/OiQD/y4gA/8iF + AP++fwD/qHAA/4xeAP9/VQD/gVYA/4NYAP98UQD/mG0O///dWf//1FL/8sZJ/6V5F/9+UwD/f1QA/5lt + D//ou0L//9hV//7SUf//1VT//tFQ//G+O//eohz/0Y8H/86LA//MhwD/yoYA/8uGAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/NiQD/zokA/82JAP/LhwD/xoQA/7l8 + AP+gawD/h1oA/39VAP+DWAP/fVAA/5h1Lf/n387///////39/P////////////////////////////// + /////////////////////PL//9NR///TUf//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NR///TUf/gpSD/zYkB/8uGAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yJAv/MiAD/0JAR/+zTof/+/v3//////////v////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////v////7///////////////////////78+P/58eD/6cuR/+O/ + dv/v2q7//f3+//724///2Wn//9VT//fHRv/kqyb/05IK/82KAv/MiQH/y4YA/8uGAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/82I + AP/OiQD/zYkA/8yIAP/JhgD/v38A/6dwAP+MXgD/ek8A/5dsDv//3Vn//9RS//LGSf+leRf/flMA/39U + AP+ZbQ//6b1E///WU//xvjz/36Md/9COBv/NiQL/zIgA/8uGAP/LhwD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zYkA/86J + AP/NiQD/y4cA/8eFAP+5fAD/oGwD/4FTAP+Wcyz/59/N///////9/fz///////////////////////// + ///////////////////////////////jjv//01H//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS//zPTv/ZnBb/yoYA/8yHAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yJAv/LhgD/0pUb//PkxP////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////v7////////////9+On/57VC/9ORCf/MiAD/zIcA/8uGAP/LhwD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/NiAD/zYkA/82IAP/LhwD/y4cA/7l5AP+4gw///9tZ///VU//yx0r/pXkX/31S + AP+BVgD/kGUK/8eQF//Vkgf/y4cA/82IAP/MhwD/zIcA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/82IAP/NiAD/zIcA/8yJAv/FgAD/yJg3//Do1////////v78//////////////////// + ////////////////////////////////////8Mf//9JQ///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9VU//XEQv/UlAz/yoUA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yJAv/KhAD/2aZA//nw4P////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////nx4f/oyYz/16I4/8yIAP/NigT/y4cA/8uGAP/MhwD/zIgA/8yI + Af/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/LhwD/y4cA/8uHAP/MiAD/zooC/9qbFP/uuDT//M5N///UU///1lT/8cVI/6Z6 + Fv9+UwD/g1kB/4FWAP+BVgD/kWAA/6pxAP/DggD/zIgA/8yIAP/NiQD/zYkA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/y4YA/8uGAP/MiAD/zIkC/8+PEP/esVf/8t+4//369P/////////+//////////////////// + //////////////////////////////////////////78///YZf//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9dW/+u2Mv/PjAX/y4YA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgB/8yHAP/LhwD/4bps//z48P/////////+//////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////58N7/6MiK/9ehNf/NigX/zYoF/8uG + AP/LhQD/y4cA/8yIAP/MiAH/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/y4cA/8uGAP/LhwD/zYkB/86LBP/ZmhP/7Lcz//zPTf//1lX//9NS//3RT//2xkT/5a0p/9aV + Dv/JhQD/t3sB/5pnAP+JXAD/hFgA/4FWAP9/VQD/gVYA/5NiAP+rcgD/xIMA/8uHAP/MiAD/zokA/82J + AP/NiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAf/MiAH/zIgA/8uG + AP/LhQD/zIcA/82LBf/QkBL/3a9T//DctP/9+vX///////////////////////////////////////// + /////////////////////////////////////////////////v//5p7//9JO///TU///01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9RU/+OqJf/LhwD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAH/zIgA/8yHAP/LhgD/6MuQ///////////////+//////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////v////7/////////////////+O7b/+fH + iP/WnzL/zo0K/82LBv/LhQD/yoUA/8uHAP/MiAH/zIkB/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8uH + AP/KhgD/y4YA/82KAv/PjQX/2JoT/+u2Mv/8z07//9hX///TUv/8z07/9sVD/+auKf/WlhD/yYQA/8uH + AP/MiAD/zIgA/8yIAP/PigD/y4cA/7V5AP+aZwD/ilwA/4VZAP+BVgD/flQA/4BVAP+UYgD/rHMA/8SD + AP/JhgD/zIgA/8+KAP/OiQD/zYgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAH/zIkB/8yIAP/LhgD/yoQA/8uG + AP/OjAn/0JIW/92tUf/w2rD//fv2/////////////////////v////////////////////////////// + //////////////////////////////////////////////////////////jm///STv//01P//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//1FP/+81M/92iHf/KhQD/zIgB/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiQH/zIgA/8uGAP/QkRT/8Ny1///////+/vz///////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////v7///79//// + //////////////fs1v/nxob/1p8x/8+PD//Niwb/yoMA/8qEAP/LhwD/zIkC/8yJAf/MiAH/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/LhwD/yoUA/8qG + AP/OigP/0I4H/9iaE//rtDD//M9N///ZWf//1FP/+85M//XEQv/mrir/1pcR/8mDAP/LhgD/zIgA/82J + Af/MiAD/zIgA/8yIAP/MiAD/y4gA/8uIAP/NiAD/0IoA/8uHAP+zeAD/mmcA/4tdAP+GWQD/gFYA/31T + AP9/VQD/lWMA/61zAP/DggD/yIUA/8yIAP/PigD/zokA/8yIAP/LiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgB/8yJAv/MiAD/y4YA/8qDAP/LhgD/zo4M/9GU + Gv/crU//79ms//379v/////////////+/v///v3////+//////////////////////////////////// + ///////////////////////////////////////////////////////////////++///3X3//9NQ///T + U///01L//9NS///TUv//01L//9JR///UU///1VX/9MNB/9eYEf/KhQD/zYkB/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiQL/zIcA/8qEAP/XoTX/9uvV///////+/Pr///////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////7///79//79+//////////////////26tL/5sWE/9afMv/QkhX/zYsG/8mCAP/KhAD/y4cA/8yJ + Av/MiQL/zIgB/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgB/8yJAf/MiAH/y4cA/8qFAP/KhQD/zooD/9GQ + CP/YmhP/6rMv//zOTf//21r//9VU//rMS//0w0H/5q4q/9eYEv/JgwD/yoUA/8yHAP/NiQH/zIkB/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8uHAP/LiAD/zYkA/9GLAP/KhwD/sncA/5pn + AP+NXgD/hloA/39VAP97UgD/f1UA/5ZkAP+tdAD/woEA/8eEAP/MiAD/0IsA/86JAP/MiAD/y4gA/8yJ + Af/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAf/MiQL/zIgB/8uGAP/KggD/y4UA/8+PDv/SlyD/3K1Q/+7X + qP/9+vX//////////////v3//v38///+/f////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////+6////R + TP//01T//9NS///TUv//01L//9NS///UU///1VX/7rs4/9COB//KhQD/zYkC/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiQL/y4YA/8qEAP/esVf/+/Xq///////+/fr///////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////7+//7+/P/+/fr/////////////////9ejN/+bFg//WoDT/0ZQZ/82K + Bf/JgQD/yoQA/8yHAP/NiQP/zIkC/8yIAf/MiQL/zIkC/8uHAP/KhAD/yYQA/86KAv/SkQr/2ZoU/+my + Lf/7zUz//9xb///WVf/6y0r/88E//+auKv/YmRP/yYMA/8mEAP/LhwD/zYkC/82JAf/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8uIAP/LhwD/y4gA/86J + AP/RjAD/yYYA/7F2AP+bZwD/j18A/4daAP9+VAD/elIA/4BVAP+XZQD/rnQA/8GAAP/GhAD/zYkB/8+K + AP/LhQD/zIgA/82JA//MiQH/zIkC/8yJAv/LhgD/yYIA/8qDAP/Pjw//1Jol/9ytUf/t1aT//fnz//// + //////////79//79+////v3////+//////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////////7 + 7v//1lv//9NT///TUv//01L//9NR///UU//+0lH/6bEu/86KA//LhwD/zYkB/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + Af/MiQH/y4UA/82KBP/kwn7////////////+/fv///////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////+/f/+/fv//v36//////////////////Xm + yv/mxIL/16I4/9KWHv/NiQP/yH8A/8qEAP/LhgD/yoIA/8mBAP/NigP/05MO/9mbFP/osCz/+sxK///c + XP//11f/+ctJ//LAPf/mrir/2JoU/8mEAP/IgwD/y4cA/82KAv/NiQH/zIkB/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/LhwD/yocA/8uIAP/PigD/0owA/8iGAP+wdQD/nGgA/5BhAP+HWgD/fVQA/3lRAP+BVgD/mGYA/61z + AP/DhAf/z5EV/8uFAP/IgAD/y4UA/8mCAP/KggD/z48P/9WcK//drlP/7NOh//z48P/////////////+ + /f/+/fr//v78/////v////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////vr//+WW///STf//01P//9NS///WVf/7zUz/4KYh/8yHAP/MiAD/zYkB/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAf/MiAH/zIgB/8yJ + Av/MiAH/yoMA/9GTGP/t06L///////79+v///v3///////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////v3//v36//78 + +v/////////////////05cf/5sSC/9ilPf/Slh//zowK/9SaJf/bq0//58Fw//nPWf//3Vz//9la//nL + Sf/xvzz/5q4p/9mbFf/KhQD/yIIA/8uHAP/NigL/zYoC/8yJAf/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/y4cA/8qHAP/MiAD/z4oA/9OMAP/HhQD/r3UA/51pAP+SYgD/h1oA/31V + A/9zSgD/mXYw/+nSpv/iumv/1Z4v/9KXH//VnSz/3rBX/+zSnv/89uz//////////////v7//vz5//79 + +/////7///////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////01P//0Ur//9VW///XV//3yEb/3J8a/8mEAP/OiwT/zYkD/8yJAv/MiQL/zIkC/82J + A//NigP/zYoD/82KA//NigP/zYoD/82KBP/NigT/zYoF/82KBP/NigT/zYoF/82KBP/MhwD/zIcA/8yI + AP/LhQD/yoMA/9afM//y4L3///////78+P////7///////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////v78//79+v/+/fr/////////////////8uG//+rNlP/37NT////////65P/3x0f/77o0/+av + Lf/anRn/zIcB/8eBAP/LhgD/zYkB/82KAv/NiQH/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8uHAP/KhwD/zIgA/9CLAP/TjQH/xoUD/7B3 + BP+gbAP/iVMA/553J//29PH///////z58//y4Lz/+vLi///////////////+//78+f/+/fv///7+//// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////////////////PT//9ts///UUv/xvjv/1ZQM/8iCAP/NiQD/yoQA/8qEAP/KhAD/yoQA/8qE + AP/KgwD/yYEA/8mAAP/JgQD/yYAA/8mBAP/JgAD/x30A/8d9AP/HfQD/x30A/8d9AP/IfgD/zYoF/82K + BP/NiQL/zYsF/9ytT//4793///////379/////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////////////+//7+/P/+/Pn//v36///////////////////////78tz/6MBl/9GS + Fv/EeQD/x30A/8yHAP/OjAb/zosF/8yJAv/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgB/8yJA//MiQX/yocB/8qD + AP/NggD/0owA/8mRIf/OsXT/+fbw//78+f/+/v3////////////+/Pn//v36///+/f////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////////////9//7pr//qsiz/0ZEO/8uIA//OjAb/zo4M/9KXIf/TmCP/05gj/9OY + I//TmCL/1Jwq/9ilPf/Zp0L/2aZB/9mmQf/ZpkH/2qlG/9+zXf/ftWD/37Rf/9+0X//ftF7/4LZi/+nL + kP/py47/6MmK/+vRnP/9+vP///////78+P////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////v/+/fz//v36//7+/P////7///////v2 + 7//w3LL/5b91/9uqSP/RkhX/yH8A/8iAAP/LhwD/zYoF/82KBf/MiQL/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAf/NiQP/zYoF/82JAv/KhAD/yH4A/8uF + AP/Tmij/3LJb/+bIjP/26c3//////////////v7///7+//79+////v3///////////////////////// + //////////////////////////////////////////////////////////////7+/v////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////89ur/6syR/+rOmP/r0Jn/6s2U/+zTov/y4cD/8+PD//Pj + w//z48P/8uLB//Xozv/79er//Pjx//z37//8+O///Pfv//379v////////////////////////////// + //////////////////////////////7+/P////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /v/////////////////8+PH/8Nqx/+S/d//bqkn/0JAS/8h+AP/JgAD/zIcA/82LBv/NigT/zIkB/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAH/zIkD/82LBf/NigP/y4UA/8h+AP/KhAD/1Jon/9+1 + YP/pzJH/9ObK//////////////////39/f///v7///////////////////////////////////////// + ///////////////////////////////////////////////////+/f3//fz6//z8+v////7//v39//// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////7///////////////////////////////////////// + /////////////////////////////////////////////////////////vz4//379//+/Pj//vz4//78 + +P/+/Pj//vz5//78+f/+/Pn//v36///+/v////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////7+//79+//+/Pr//////////////////Pft//Dbsf/lwnz/26tL/8+ODv/HfQD/yYEA/8yI + AP/Niwb/zYoE/8yJAf/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yJAv/NiwX/zYoE/8uFAP/IfgD/yYMA/9OaJv/gt2T/6s6W//Tm + yf///////////////////vz//vz5//7+/P////7///////////////////////////////////////// + /////////////////////////////////////////v38//z8+v/8+/j//////////////////v79//// + ///9/fv///////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////v/+/fr//v36//79+v/+/Pr//v36//79 + +//+/fv//v37//79+//+/fv//v78///+/f///v3///79///+/f///v3///7+//////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////+/f/+/fv//v36//////////////////v16v/w3LP/5sSB/9us + TP/OjAn/x30A/8mCAP/MiAH/zYsH/82KBP/MiQH/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiQL/zYsF/82KBf/LhgD/yH8A/8mCAP/TmCT/4Lhn/+vRnP/05sn///////// + //////////7+//78+f/+/vz////+//////////////////////////////////////////////////// + ///////////////////////////+//79/P/8+/r//Pv5//////////////////Hs4v/Wya3/v6d7/62S + Wf/e0rv///////38+v////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////v3//v37//79+/////////////// + ///79Oj/8d23/+fHh//brEz/zYoF/8d9AP/KgwD/zIkC/82LB//NigT/zIgB/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIkC/82KBf/Niwb/zIcA/8mAAP/JgQD/0pcg/+G5aP/s1KL/9ObL//7++/////////////// + ///+/Pr//v38/////v////////////////////////////////////////////////////////////// + ///////////////+/v/9/fz//Pv5//38+//////////////////t59r/0MCe/7igb/+ffTr/imMS/3xO + AP92RwD/nHo2//Pv5////////v79//////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////79//79 + +//+/vz/////////////////+vTn//Lfu//oyYz/26tL/82JAv/HfQD/yoQA/82KA//Niwb/zYkD/8yJ + Av/NigX/zYsG/8yIAP/JgAD/yIAA/9GVHf/huWn/7dan//Xozf/9/Pj//////////////////v36//79 + /P////7///////////////////////////////////////////////////////////////////////// + ///+/v7//f37//z7+f/9/fv/////////////////6ODQ/8i1kP+sj1b/mXYw/4dfC/95TAD/e04A/4BU + AP+EWQP/g1gC/39TAP+0m2b///////z6+P////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////+/f/+/fv///79//////////////////r05//z4cD/6cuQ/9uqSP/MhwD/yH4A/8uF + AP/MiAD/yYEA/8iAAP/Rkxj/4Lhn/+7Yq//16dD//fr1//////////////////79+//+/fz////+//// + /////////////////////////////////////////////////////////////////////////v7+//39 + +//8+vj//v79/////////////////97TvP/Aq37/pohK/5VwJv+FWwb/eEoA/3xOAP+AVQD/hFkD/4RZ + A/+DWAL/glcA/4NYAv+AVAD/hlwH/8+/nv//////+/r3//////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////v3//v38/////v/////////////////69Of/8+TF/+rM + k//aqEP/0pYe/+C3Zf/v2q//9uvU//z58//////////////////+/vz//v78/////v////////////// + //////////////////////////////////////////////////////////////7+/v/9/fv//Pv5//7+ + /v////////////v69//Vx6r/uJ9v/6GAP/+OaBr/glcB/3pMAP98TwD/gVUA/4RZBP+DWQP/g1gB/4JX + AP+CVwD/glcA/4JXAP+CVwD/g1gC/31RAP+VcCb/6eHS///////9/fz///////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////79//7+/P////////////// + ////////+vTm//ju2v/8+fP///////////////////79//7+/P////7///////////////////////// + ///////////////////////////////////////////////////+/v3//fz7//38+v////////////// + ///39O7/0MCf/7CWX/+Zdi//i2MS/4BVAP97TQD/flEA/4FWAP+DWQP/g1kC/4JYAf+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+DWAL/e04A/6qMUf///////fz7/////v////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////////+ + /f///v3////////////////////////+/v///v3////+//////////////////////////////////// + //////////////////////////////////////////////////////7/////////////////8ezj/8q4 + lP+niEv/kWsf/4lhD/9/UwD/fE8A/39TAP+CVwD/g1gC/4NYAv+CVwH/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/g1gB/4FWAP9+UgD/wayA///////7+vj///////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////////////////v7///79/////v////////////////////////////////////////////// + /////////////////////////////////////////////////////////v7//+be0f+/qXv/ooJB/41m + F/+HXgr/flIA/3xPAP+AVAD/glcA/4NYAv+DWAH/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+DWQP/flEA/4xkFP/c0bn///////z7 + +v////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////zxz/+9kyn/fVQC/4FV + AP9+UQD/gFUA/4JXAP+DWAL/glcB/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4RZA/98TwD/n347/+/q + 3////////v38//////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////56v//3G7/7L9A/5Jn + C/+BVgD/hFkC/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwH/g1gB/31Q + AP+4n27////////+/v///v7///////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////++v//4Yr//9JO///Z + WP/dsjz/g1gA/4NYAf+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4NY + Av+BVgD/g1kC/9LDo////////fz6//////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////7rz//9FM///T + U///1FP//9NS/8OXK/95TgD/hVoC/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/g1kD/31RAP+Wcij/5t7M///////9/fz///////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////9t3//9RW///T + Uv//01L//tJS///XVP/1yUv/qX0Z/3xRAP+EWQH/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+EWgX/eEoA/6+UXP/7+vf///////7+/f////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////fj//9hp///T + Uf//01L//9NS///TUv/+0lH//9tX/+W6Qf+JXwX/gVYA/4NYAf+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4RaBf95SwD/xrKK/////////v7///7+//////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////+WZ///S + UP//01L//9NS///TUv//01L//9NS//7SUf//2FX/0aY0/39UAP+DWAH/g1gA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+DWAL/gVYA/4tjEv/e0rv///////7+/f////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////v////////DD///S + Tv//01L//9NS///TUv//01L//9NS///TUv/+0lL//9RT//rPT/+0iSH/ek8A/4RZAf+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4RaBP99UAD/n348//Dq4P///////v39//// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////v////////no///U + Vv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS//3RUf//2Vb/679F/5htDv99UgD/hFkB/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/hVsG/3xPAP+6onL//v7+//// + ///+/v3///////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////77///e + e///01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//dFQ///bV//arjn/hlsC/39U + AP+DWAH/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAf+EWgX/gFUA/9fK + rv/////////+//////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////v3////////n + n///01D//9NR///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv/+0lH//9VU/7+T + KP99UgD/g1gB/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/g1kC/4FV + AP+SbCD/6+TW///////+/v3///////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////vz////////y + zP//01H//9JQ///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//tJR///V + U//3y03/p3sY/3pPAP+EWQL/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+FWwb/ek0A/62RV//7+vf///////7+/f////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////3////////5 + 5///2Gr//9NR///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv/80FD//9tY/+K3P/+PZAj/flMA/4RZAf+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4ZdCf94SgD/ybaQ//////////////7+//////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////78//// + ////4IX//9NP///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS//vPUP//21f/zaIx/4NYAf+AVQD/g1gB/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/hFoF/4dfC//g1sD///////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////76//// + ////67D//9NS///SUP//01P//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//tJR//7SUf+vhB7/fVIA/4NYAf+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4NZA/9/UwD/m3kz//Pw6P////////7+//////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////77//// + ////8s///9Va///STv//01P//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS//3RUf//2FX/7cJH/5htDv9+UwD/hFkB/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/hFoF/35RAP+2nWr///////////////7///////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////9//// + /////PL//9px///RTP//01P//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//NBQ///bV//ZrTn/iF0E/35TAP+DWAH/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+EWgT/gVUA/9fJrf////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////////+ + +////////+SU///STv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv/80FD//9hV/7yQJv+CVwD/gVYA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/g1gB/4JXAP+NZRX/8uzh//// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////////+ + +f///////+y1///TUf//0k///9NT///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//tJR///TUv/+0VH/oHUT/31S + AP+DWAH/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/g1cA/4NYAP+FWgL/flEA/6GD + Rv/8/P////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////////+ + /P////////bb///XY///0Uv//9RU///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv/90VD//9lW/+e8 + Q/+PZAj/flMA/4NYAf+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4NXAP+DWAD/hFgA/4JXAP9/VQD/e1IA/4Va + BP+QXAD/4Mqc//////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /v////////z0///fgf//0Uv//9NU///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS//zQ + UP//2lf/zKEx/4VaAv+AVQD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+DVwD/g1gA/4RYAP+CVwD/f1UA/3pSAP+IWwD/mmcA/61z + AP+7fgL/x4kN//Ln0P////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////vv////////oo///0Un//9NT///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//dFR///WVP+qfxv/gVYA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4JXAP+CVwD/g1cA/4NYAP+DWAD/gVcA/39VAP99UwD/i10A/51pAP+xdgD/v4AA/8aE + AP/PiwT/zogA//DXp/////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////79////////9NX//9hm///RS///01T//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS//7SUf//1VP/9MhL/5VqDP+AVQD/glcA/4JXAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+CVwD/glcA/4NXAP+DWAD/g1gA/4FXAP9+VAD/flUA/45fAP+hbAD/t3oA/8OCAP/HhQD/zooA/9CK + AP/PiwP/yoMA/+C4aP////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////////////////vz////////ssv//1Fb//9NQ///TU///01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//dFR///XVf/esjz/hVoC/4BVAP+CVwD/glcA/4JXAP+CVwD/glcA/4JX + AP+DVwD/g1gA/4NYAP+BVgD/flQA/4BVAP+RYQD/qHEA/7t9AP/FgwD/yYYA/8+KAP/PigD/zYkA/8yI + AP/MiAH/y4cA/9agMv/79en///////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////////////+/////////////+GJ///RS///01P//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv/90VH//9dV/7+TKP+DWAH/gVYA/4JXAP+CVwD/glcA/4NX + AP+CVwD/gVYA/35UAP+CVwD/mGYA/6xzAP+/fwD/x4QA/8uHAP/PigD/z4oA/82JAP/MiAD/y4gA/8yI + AP/MiAD/zYoE/8yIAf/z5MT///////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////3////////77///2m7//9FJ///TVP//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//1VP/m3AQ/4BVAP+CVwD/glcA/4FW + AP9/VQD/hlkA/5xoAP+vdQD/w4IA/8mGAP/MiAD/zooA/86JAP/NiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zYsG/8h/AP/qz5j///////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////+/P////////DC///WXP//0k7//9NT///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv/+0lL//9VT/+7DR/+MYQf/f1QA/4lc + AP+gawD/tHgA/8mGAP/KhgD/zIgA/86JAP/NiQD/zYgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zYoE/8qDAP/ftF3//fr0//////////7///////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////78////////5Zz//9JR///T + Uf//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS//7SUf//1lX/y5sm/7t9 + AP/KhgD/y4cA/8yIAP/OiQD/zYkA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIkC/8yHAP/SlRz/+O/c/////////v7///////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////v////7///77///d + eP//0Uz//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//1FP/+sxK/9KQ + CP/MiAD/zYkA/82IAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgB/82JA//JgwD/8d+6//////////7///////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////+//// + ////9+H//9dj///STf//01P//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9VU/9ue + GP/MhwD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/82KBf/JgAD/58iJ///////////////+//////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////vz////////ssf//1FT//9JQ///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv/+0lH//9VV/+ew + K//MiQH/y4cA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/82KBf/JggD/3K9T//v27f////////7+//////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////+/P///////+GH///STf//01H//9NS///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv/+0lH//9VU//PB + P//OiwP/y4YA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/82JA//LhgD/0JEU//boz////////v38//////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////////////+///99f//2Gb//9JN///TUv//01L//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//0lH//9RT//zP + Tv/VlQ7/y4cA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yJAv/MiAD/y4cA/+3WqP///////v78//////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////v////////HJ///UWP//01H//9NS///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//tJR///V + VP/eoh3/zIcA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/NigT/yYEA/+TAd/////7//////////v////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////79////////5p///9JO///TUv//01L//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//tJQ///X + Vv/psi7/zYoC/8uHAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/NigX/yoMA/9ikPf/58N////////7+/P////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////v3///77///dev//0k3//9NS///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//tJR///V + Vf/1xUL/z40G/8qFAP/MiQH/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/NigT/yoMA/9CSFv/z4sH///////79+v////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////+OX//9Ze///T + Uv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//tJR///U + U//7zk3/2JoT/8uHAP/MiQH/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiQH/zIgA/8uEAP/oyYz///////79+/////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////////t + uf//0k3//9RU///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS//7R + UP//1lX/4agj/8uHAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zYoE/8qDAP/ftF7//vz3/////////v3///////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////+OQ///RSv//1FT//9NS///TUv//01L//9NS///TUv//01L//9NS///TUv//01L//9NS//7R + UP//11f/7ro2/86MBP/LhgD/zIkB/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiAD/zYsF/8mBAP/UnCz/+fDe///////+/fr///////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////88v//2Gf//9NQ///TU///01L//9NS///TUv//01L//9NS///TUv//01L//9NS//7R + UP//11b/9sZD/9OSCv/KhQD/zYkB/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zIgA/8yIAP/MiQL/zYwH/8uGAP/NjAj/7tmt///////9+/f///////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////PQ///TVP//1FX//9NS///TUv//01L//9NS///TUv//01L//9NS///S + Uf//01L//tJQ/9yfGf/JhAD/zYkB/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yI + AP/MiAD/zYkD/82KBf/Niwb/zIcA/8h/AP/JgAD/5cN////////+/Pn///////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////6Kj//9FI///UVv//01L//9NS///TUv//01L//9NS///T + Uv/+0VD//9ZW/+avKv/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAP/MiAD/zIgA/82J + A//Niwb/zYsG/8uGAP/IgAD/x30A/9CRE//bq0r/58mK//v37v////////79//////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////v////////33///ghP//0Uv//9RV///TUv//01L//9NS///T + Uv/+0VD//9hY//C9Ov/OiwP/yoYA/82JAf/MiAD/zIgA/8yIAP/MiAD/zIgA/8yIAf/NiQP/zYsG/82L + Bf/LhQD/yH8A/8d9AP/TmST/3rJb/+jIiP/y37v/+/bs/////////////v79//////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////+OL//9dg///TU///01P//9NS///T + Uv/+0lH//9ZV//nKSP/WlhD/yYQA/82KAv/MiAD/zIgA/8yIAP/MiAH/zYoE/82LBv/NigT/y4UA/8h/ + AP/IgAD/1Z0t/+G5af/r0Jr/9efM//z58f///////////////////v3///79//////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////uvf//0Ur//9RX///T + Uv//01L//9NS//7RUP/gpSD/yoUA/82JAv/MiAD/zIkB/82KBP/Niwb/zYkD/8qEAP/IfgD/yoUA/9eh + N//kwHj/79uz//fs1f/+/Pj//////////////////v78//79+////v3////+//////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////+/////////v3//+ab///P + Rf//1Ff//tJQ///WVv/pszD/yoUA/8yJAv/NigT/zYsH/8yIAf/KhAD/yH4A/8yIAP/crE3/58mK//Lh + vv/48N///v78//////////////////79/P/+/vz///7+//////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////7////////6 + 6f//23D//tFN///XWP/0w0H/0pEL/8uIAv/NiQH/yoQA/8d8AP/PjxD/37Ne/+vQmv/05sn/+/Xq//// + ///////////////////+/fv///79///+/v////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /v///////vLP///XWv/6zU7/2ZsV/8iBAP/JgQD/0JQZ/+G6av/u2Kv/9+3Y//z48f////////////// + /////////v78///+/f////7///////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////7////////////95qj/4qQU/9CWI//kwHf/8uG///rz5v/9+vT////////////////////////+ + /f///v7////+//////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /////////////////v///////v36//rz4v/69On//vz5/////////////////////////v7////+//// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////7+/////v////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////+/////v////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAA= + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/RegMon/RegUnitTest.Designer.cs b/Demo_Source_Code/CSharpDemo/RegMon/RegUnitTest.Designer.cs new file mode 100644 index 0000000..710402c --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/RegMon/RegUnitTest.Designer.cs @@ -0,0 +1,76 @@ +namespace RegMon +{ + partial class RegUnitTest + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(RegUnitTest)); + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.richTextBox_TestResult = new System.Windows.Forms.RichTextBox(); + this.groupBox1.SuspendLayout(); + this.SuspendLayout(); + // + // groupBox1 + // + this.groupBox1.Controls.Add(this.richTextBox_TestResult); + this.groupBox1.Dock = System.Windows.Forms.DockStyle.Fill; + this.groupBox1.Location = new System.Drawing.Point(0, 0); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size(636, 408); + this.groupBox1.TabIndex = 0; + this.groupBox1.TabStop = false; + // + // richTextBox_TestResult + // + this.richTextBox_TestResult.Dock = System.Windows.Forms.DockStyle.Fill; + this.richTextBox_TestResult.Location = new System.Drawing.Point(3, 16); + this.richTextBox_TestResult.Name = "richTextBox_TestResult"; + this.richTextBox_TestResult.Size = new System.Drawing.Size(630, 389); + this.richTextBox_TestResult.TabIndex = 0; + this.richTextBox_TestResult.Text = ""; + // + // RegUnitTest + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(636, 408); + this.Controls.Add(this.groupBox1); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Name = "RegUnitTest"; + this.Text = "Registry Filter Driver SDK Unit Test"; + this.Activated += new System.EventHandler(this.RegUnitTest_Activated); + this.groupBox1.ResumeLayout(false); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.GroupBox groupBox1; + private System.Windows.Forms.RichTextBox richTextBox_TestResult; + } +} \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/RegMon/RegUnitTest.cs b/Demo_Source_Code/CSharpDemo/RegMon/RegUnitTest.cs new file mode 100644 index 0000000..8d01acd --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/RegMon/RegUnitTest.cs @@ -0,0 +1,90 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.IO; +using System.Diagnostics; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; +using Microsoft.Win32.SafeHandles; +using System.Security.AccessControl; +using System.Security.Principal; + +using EaseFilter.FilterControl; +using EaseFilter.CommonObjects; + +namespace RegMon +{ + public partial class RegUnitTest : Form + { + + bool isUnitTestStarted = false; + FilterControl filterControl = new FilterControl(); + + //Purchase a license key with the link: http://www.easefilter.com/Order.htm + //Email us to request a trial key: info@easefilter.com //free email is not accepted. + public static string licenseKey = "********************************************"; + + public RegUnitTest(string _licenseKey) + { + InitializeComponent(); + licenseKey = _licenseKey; + } + + + public void StartFilterUnitTest() + { + try + { + RegistryUnitTest registryUnitTest = new RegistryUnitTest(); + registryUnitTest.RegistryFilterUnitTest(filterControl, richTextBox_TestResult, licenseKey); + } + catch (Exception ex) + { + richTextBox_TestResult.Text = "Filter test exception:" + ex.Message; + } + } + + private void RegUnitTest_Activated(object sender, EventArgs e) + { + if (!isUnitTestStarted) + { + isUnitTestStarted = true; + + string lastError = string.Empty; + if (!filterControl.StartFilter(GlobalConfig.filterType, GlobalConfig.FilterConnectionThreads, GlobalConfig.ConnectionTimeOut, licenseKey, ref lastError)) + { + MessageBox.Show(lastError, "StartFilter", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + System.Threading.Thread.Sleep(3000); + + StartFilterUnitTest(); + + filterControl.StopFilter(); + } + + } + + } +} diff --git a/Demo_Source_Code/CSharpDemo/RegMon/RegUnitTest.resx b/Demo_Source_Code/CSharpDemo/RegMon/RegUnitTest.resx new file mode 100644 index 0000000..60985f5 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/RegMon/RegUnitTest.resx @@ -0,0 +1,570 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + AAABAAgAEBAAAAEACABoBQAAhgAAABAQAAABACAAaAQAAO4FAAAYGAAAAQAIAMgGAABWCgAAGBgAAAEA + IACICQAAHhEAACAgAAABAAgAqAgAAKYaAAAgIAAAAQAgAKgQAABOIwAAMDAAAAEACACoDgAA9jMAADAw + AAABACAAqCUAAJ5CAAAoAAAAEAAAACAAAAABAAgAAAAAAEABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP// + /wAygPwAvYp4AH/e/wD/3ZcAwMDAAHyX4QB2dXQA7trOAKCgoADhrooAjMXWAKHB/wCZhnMAvaySAP/3 + ywDxyIIA0tLSAJGQjQDMrqoA/9y4AK16cAD/8OEA0p+CAIqo3gD5xpYAhIJ9AOS8mACrq6sA3trEAPTd + qQD//+oA/+THAP/RhADEnIgA8tWYAP/npgD96NUAceH/APjouwA4jP8AxpN9AJmOgwCZl5QAqoF6AO26 + kAC1gnQA782QAIaHhwD/+vUAtKiXANmmhgD/1ZAAmLz/AMjBugD22qAAmpSLAP/uvQDQtLAA//bsAIuf + 3QDRzssA/+DAAPntwgCZiXoAfn5/AP/t2gD/584AOoX/APn5+QD+2Z0AnJycAHt5dQDguJUAsX5yAIam + 4gC5hnYAwY56APXClADxvpIA6baOAOWyjADdqogA///yAP7WmAD8/PwAqKioAJaPhwDw0JQA1tPPAJmM + fgDVooQAz8/PAMTBvgA2iP8A//jwAMmWfgD/69YA/+nSAJuSiADHnokAgYB/AI+OiwDCwsIA//37AP/+ + 7wD/7t0A/9qWAJmUjgCrqqgAd3d2ALOAcwC3hHUAmZCHANekhACFhYYA//v3AHt4cwCZi3wA/v7+APr6 + +gD+0IUAuod3AL6LeQDCj3sAxZJ8AJ2dnQDcqYcAw8C9AP/37wCAgIAAgoB+AK57cADV0s8AkpCNAMfB + ugAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAACNhfk4DTS9LFhQ9WIcAAGUJRkZ5VngBAQENRQRkAAAYAXJtLGhdARIZAicp + BwAAcwEXPGlXQgiDEwxfNjsAAIABcl5/DyJ6VTlnTAGFAAALAWsyhAUkMBFHMQEBcAAAUgErWnY6KB9Z + NW8SAXEAAFEBYmAbIGpAOGx0AXh7AAAuAXc3Ch5UECUzSAZWfAAAUAEhY4JuhElmHWl1eX0AAE8BDkFb + iGCGPoFtbUYqAAAaARU/IURiQ2sXFxdGYQAAHCYBAQEBAQEBAQEBCS0AAABKGk9QLlFSC1M0XC0AAAAA + AAAAAAAAAAAAAAAAAAD//wAAwAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAIAB + AACAAQAAgAEAAMADAAD//wAAKAAAABAAAAAgAAAAAQAgAAAAAABABAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAMuYf8zJln7/xZJ8/8GOev+9inj/uYZ2/7WCdP+xfnL/rXpw/8yuqv+Ln93/l5CI/Xdz + bH4AAAAAAAAAAM6bgMzu2s7/+fn5//n5+f/6+vr//Pz8//7+/v////////////////+hwf//OoX//3/e + //+dlIr+AAAAAAAAAADSn4L//////5mQh/+ZlI7/mZeU/8LCwv/Pz8///////9LS0v+KqN7/MoD8/3Hh + //84jP//fJfh/wAAAAAAAAAA16SE////////8OH///bs///9+/+oqKj/fn5//3Z1dP+AgID/kZCN/4zF + 1v82iP//mLz//9C0sP8AAAAAAAAAANyph///////mZCH/8TBvv+dnZ3/vayS///RhP/+0IX//taY/5qU + i/+Pjov/hqbi//////+ue3D/AAAAAAAAAADhror////////u3f//+vX/goB+///dl//y1Zj/782Q//HI + gv/+2Z3/hoeH////////////s4Bz/wAAAAAAAAAA5bKM//////+ZjoP/1tPP/3t4c///7r3/+Oi7//Td + qf/w0JT//9WQ/3d3dv/S0tL//////7eEdf8AAAAAAAAAAOm2jv///////+vW///48P+Egn3////q///+ + 7//57cL/9tqg///alv+FhYb///////7+/v+6h3f/AAAAAAAAAADtupD//////5mLfP/Iwbr/oKCg/97a + xP////L///fL///npv+0qJf/nJyc/8DAwP/8/Pz/vot5/wAAAAAAAAAA8b6S////////5Mf//+nS///3 + 7/+rqqj/goB+/3t5df+BgH//q6ur///9+///+/f/+vr6/8KPe/8AAAAAAAAAAPXClP//////mYZz/5mJ + ev+ZjH7/x8G6///48P/V0s//0c7L/8PAvf+ZlI7/mZSO//n5+f/Gk33/AAAAAAAAAAD5xpb////////c + uP//4MD//+TH///nzv//69b//+3a///u3f//8OH///Dh///w4f/5+fn/yZZ+/wAAAAAAAAAA88CTzP3o + 1f//////////////////////////////////////////////////////7trO/6p3bswAAAAAAAAAAAAA + AADuu5DM+caW//XClP/xvpL/7bqQ/+m2jv/lsoz/4a6K/92qiP/Zpob/1aKE/6p3bswAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAD//wAAwAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAMAD + AAD//wAAKAAAABgAAAAwAAAAAQAIAAAAAACgAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8AGVv/AK98 + cQBu3f8A+9KTALKztgBBmukA5drPANilhQCCgpAApJ2SAP/80wBXt/8A4+f/AGWd6QD/6LUAysrIAOnV + qwDEkXsA7LmPAJmLfQAGRf8Av7OdAPLr5ABOheYASaL/AH18eQDBoI4A/+XMAKOlpwCRk5YA2a+YAP/2 + 7gCyhoEA/dqkAPHz/wC/v78A7+bFADuM4QDb29wA//LCAP/t3AD2w5UA/9mzAOKvigCdk4kA8NOeAIWE + ggC1q5cA5OPjAOPewgC6h3YA8fHwAP/fwADuzZEA9eLUAK+ppACampwA892xAIqLjADMmX8Av7O/AGTX + /wDUxMgApaOcAJmGcwCJg3gA+e7MAKh1bQD2570A+sqcAKykkgD5+fkAD1r/AP/y5QD689YA///wAJmV + kgDSn4IA99/MAPTYpAD815oAwMfCAOnt/wD347YA/+nVAAxK/wCMh4EA8b6SAJmOhAD/4aYAgIOJALWC + dAC/jHkA8duqAN2qhwD9+eUAvru5AP/59QCAgH4Ajo+QAO/QlwBGnP8A/PXcAMTAuwAUVv8A9vf/APXQ + lACcmZYA///3AKp6dACtpp8A//PIAOazjAD/4scA2NjYAPfsyACenp0A/9u4APrXnwDCtaEAmZKMAICA + gwCZiHkAq3hvAMeUfQCEgocApp6WAKOfnQD/9OoA/+/gAP/n0AD/3bwAmZCIAPXdqgCgm5IAsn9yAPnG + lgD//PoA9uHQAG/Z/wD705oA8NSiAMSikAD//+wA9uGzAPPcrQDx0ZsA8dalAKWkpADbspkAg4CAAObr + /wCZl5YAj5GUAOi1jgD+2aEAlJSXAJmZmQDwzpoAy8vLAFa0/wD/9/EAmYd2AP/s2QD/4MMA9+fAAJmU + jwD+/vwAgoWIALiFdQC9ingAwY56APXiuADJln4A9MGUANShgwDvvJEA1qOEANqnhgDksYsA4K2JAKKh + mwDz9f8A//DjAPzXnQDqt48Av56OAK2npACtqqUA//v4AP/17ACAgoIA//PnAP/u3gD/6tcA/+jSAP/m + zgCZj4YA/+PJAP/hxQD/3r4A9uW+AJmYlwDw0JUAraehAP/58wCZjoIA9NiiAO/QmQD//f0Afnt6APr6 + +gCpdm4ArntwAP7x5gCzgHMA8+zlAMaTfADzwJMA7ruQAN6riADCoY8AC0n/AKp3bgCEg4IA//PpAISE + gwCseW8A/PbbALB9cQCxfnIAmYp8ALaDdACZk44A/tqjAJmUkQCZlpMAypd+APfElQDz16QA9cKUAPDP + lwDyv5MA8L2RAO26kACzs7UA//38AP/69QB+fHoA//fwAP/y5wCChIgAmYt+AJmPhQAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAALyv2xOtXqw0q+rZ6APl4UVvQEOYAAAA3yA4Ifn4AQEBAQEBAQEBAQFrFhkI + 1AAAT4zCIfn4AQEBAQEBAQEBAbhXZz8PWAAAsQFLwE6an5+fAQEBAQEBJOAajQ1KPgAAswFLgqO/AQEB + AQHVSQE1fycEogIOIgAACQG5gqjuzJ+h96ob+v1lvlMHapkB1gAAtAGDwsDPiwEeMWwFjrp5XGkKVAEB + fQAAYAHDuXrtbShIUpTSN/N4FzwRAQEB1wAAtgGlg8LAY57Rh19fj2ag7JsBAQEB5wAALQHEw4Z6vmQQ + y6euO5XNIzB0AQEBiQAAtQFWpYNL++JxaEx1RpMvneQBAQEBXQAAcgGExFrHznYmTanmdZLxUR8BAQEB + qwAAnAEdxcTD/NpBkW5hRFVbCygBAQEBNAAAFAHIxv7QLnBitzMMKRKIBiWfAQEBrAAA3QHJyMZWpYPj + GJZ7wToy0wEBAQEBXgAA9QE2yXwVVtAugM45vYHP7pqa+Pj4rQAA9AGFNsnIxsXEKoO5woLAIaPP+fn5 + EwAAsAF3hUKkfOn+xND/x4Z6enrrISEhfgAAKwEsd4U2ycgdhFbEpcODuUtLwsLC7wAAitjDLHeFyqZz + HcaEVsSlKsPDg4OMPQAAAEfYAQEBAQEBAQEBAQEBAQEBAVCXHAAAAACK8PLcWbL2u5xytS223rQJs7GQ + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8AwAADAIAAAQCAAAEAgAABAIAAAQCAAAEAgAABAIAA + AQCAAAEAgAABAIAAAQCAAAEAgAABAIAAAQCAAAEAgAABAIAAAQCAAAEAgAABAIAAAQDAAAEA4AADAP// + /wAoAAAAGAAAADAAAAABACAAAAAAAGAJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADJln6pyZZ+/8aTfP/EkXv/wY56/7+Mef+9inj/uod2/7iF + df+2g3T/s4Bz/7F+cv+vfHH/rHlv/6p3bv+odW3/qnp0/9TEyP+Jg3j/hICA+GNjYzgAAAAAAAAAAM6b + gKnZr5j/9eLU///27v//+vX///38//////////////////////////////////////////////////// + ////////9vf//wZF//9Oheb/5drP/357evkAAAAAAAAAANKfgv/24dD///Pn///27v//+vX///38//// + ///////////////////////////////////////////////////z9f//DEr//0ac//9k1///ZZ3p/4yH + gf8AAAAAAAAAANShg/////////Ll///17P+ZlZL/mZeW/5mZmf+ZmZn/mZmZ//////////////////// + //////////////Hz//8LSf//SaL//2/Z//9Xt///D1r//7+zv/8AAAAAAAAAANajhP////////Ll///0 + 6v//9/H///v4////////////////////////////+vr6//n5+f//////8fHw/4SCh/87jOH/bt3//1a0 + //8ZW///4+f//7KGgf8AAAAAAAAAANilhf////////Dj///06v+ZlI//mZaT/5mYl/+ZmZn/y8vL/7Oz + tf+ChYj/fXx5/358ev+ChIj/jo+Q/62qpf/Ax8L/QZrp/xRW///m6////////6l2bv8AAAAAAAAAANqn + hv///////+/g///z5///9ez///nz///8+v//////o6Wn/7Wrl//10JT/+9KT//vTmv/8153/wrWh/4CD + if/EwLv/goKQ/+nt/////////////6t4b/8AAAAAAAAAAN2qh////////+7e///w4/+Zkoz/mZSR/5yZ + lv/b29z/rKSS//zXmv/x0Zv/79CZ/+7Nkf/wz5f/+tef/7+znf+Ki4z/ysrI/////////////////657 + cP8AAAAAAAAAAOCtif///////+zZ///v4P//8+f///Xs///59f+UlJf/9Nii//Xdqv/x26r/8dup//DU + ov/v0Jf/8M6a//7ao/+PkZT//////////////////////7B9cf8AAAAAAAAAAOKviv///////+rX///u + 3v+ZkIj/mZKM/62ppf+AgH7//+i1//blvv/358D/9eK4//Pdsf/x1qX/8NCV//3apP+FhIL/2NjY//// + /////////////7J/cv8AAAAAAAAAAOSxi////////+nV///s2f//7+D///Ll///38P+Eg4L///PI//z1 + 3P/689b/9+zI//bnvf/z3K3/8NOe//7Zof+EhIP//////////////////////7WCdP8AAAAAAAAAAOaz + jP///////+fQ///q1/+ZjoT/mY+G/62nof+enp3/7+bF////8P/+/vz//Pbb//fsx//24bP/89ek//TY + pP+Rk5b//////////////////////7iFdf8AAAAAAAAAAOi1jv///////+XM///o0v//6tf//+7e///y + 5//z7OX/paOc////7P////f//fnl//nuzP/347b//+Gm/6Sdkv/b29z//////////////////////7qH + dv8AAAAAAAAAAOy5j////////+PJ///mzv+Zi37/mY6C/52Tif+tpp//vru5/6Khm//j3sL///zT///y + wv/p1av/oJuS/7Kztv+/v7//mZmZ/////////////////72KeP8AAAAAAAAAAO67kP///////+HF///j + yf//5s7//+nV///s2f//7+D///Pp//Lr5P+lpKT/gICD/4CCgv+ampz/5OPj///9/f////////////// + /////////////7+Mef8AAAAAAAAAAPC9kf///////9/A///hxf+ZiHn/mYt9///p1f+ZjoL/nZOJ/6ae + lv+tp6H/r6mk/62npP+jn53///nz/5mWk/+Zl5X/mZeW///9/P///fz///38/8GOev8AAAAAAAAAAPK/ + k////////928///fwP//4cX//+PJ///mzv//6NL//+rX///t3P//7+D///Dj///z5///9Or///Xs///2 + 7v//9/H///nz///69f//+vX///r1/8SRe/8AAAAAAAAAAPTBlP///////9u4///dvP+ZhnP/mYd2/5mI + ef+Zinz/mYt+///q1/+ZjoL/mY+F/5mPhv+ZkIj/mZKL/5mSjP+Zkoz/mZOO///27v//9u7///bu/8eU + ff8AAAAAAAAAAPbDlf///////9mz///buP//3bz//9/A///hxf//48n//+XM///n0P//6dX//+rX///s + 2f//7t7//+/g///w4///8uX///Ll///z5///8+f///Pn/8qXfv8AAAAAAAAAAPnGlv/+8eb//+7e///Z + s///27j//928///evv//4MP//+LH///lzP//5s7//+fQ///p1f//6tf//+zZ///t3P//7t7//+7e///v + 4P//7+D/9uDQ/8yZf/8AAAAAAAAAAPjFlj36ypz//vHm//////////////////////////////////// + ///////////////////////////////////////////////////338z/27KZ/8yZf6kAAAAAAAAAAAAA + AAD4xZY9+caW//fElf/1wpT/88CT//G+kv/vvJH/7bqQ/+q3j//otY7/5rOM/+Sxi//ir4r/4K2J/96r + iP/ap4b/2KWF/9ajhP/UoYP/0J2BqQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA////AMAAAwCAAAEAgAABAIAAAQCAAAEAgAABAIAAAQCAAAEAgAABAIAAAQCAAAEAgAABAIAA + AQCAAAEAgAABAIAAAQCAAAEAgAABAIAAAQCAAAEAwAABAOAAAwD///8AKAAAACAAAABAAAAAAQAIAAAA + AACABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8ANF/oAMCNeQBt2f8ATVNaAPvboQB5pLUAxsjQAEtw + qgBfiP8AeX6EAK6ppADksYsA+O/PAKBuagBNsfgAmZONADqL/wBkZ20A2cmkAN3d3QDi270AUG7oAMie + kADNtLUA8sqLAIqTpAA8b/8A7u3sAJmGdAD/3r4AW3KXAF/A/wC1t7gArqKNALB9cQD//N8A79vRAJ2d + nQDXpIQA69GeAIiKjgDu8f8AKnb/AOe9nwDEwr8A7tuwAL2yogD/9+8A4cKQALWRhQDx5cEAzZp/APvI + lwDW1NIA/+3cAPG+kgCJh4EAkZOXAP3rvAD/5MoAOmfxAOLRqgCZjIAA2byhAM/LxwDi2dIApKWpAMa2 + wwDhyZoAsKmYAPLVpwCodW0AVrT/AODm5ACysK8A9dKaAPb29gD39+cA99+rAIGEiQBYgP8A6uHYALeE + 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 + AAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPgAAAH//////////8oAAAAIAAAAEAAAAABACAAAAAAAIAQ + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAHVvWSSGhH3maWhndGJiYl6EhIQCAAAAAAAAAAAAAAAAAAAAALqHdrW2g3T/tYJz/7SB + c/+zgHL/sX5y/7B9cf+vfHH/rntw/616cP+seW//q3hv/6l2bv+odW3/p3Rt/6ZzbP+lcmz/pHFr/6Nw + a/+hbmr/oG1p/6Bua//NtLX/UG7o/4qTpP/Nx8L/iIiH/2NjY2kAAAAAAAAAAAAAAAC6h3a1yJ6Q/+/b + 0f//+PL///v3///+/f////////////////////////////////////////////////////////////// + /////////////////////////Pz//1+I//8qdv//S63//+Dm5P/Py8f/aGhoeQAAAAAAAAAAAAAAAL6L + eP/v2s7///Xs///48v//+/f///79//////////////////////////////////////////////////// + //////////////////////////////v7//9bhv//Lnn//1a0//9o1f//W73//66urv+MioTTAAAAAAAA + AAAAAAAAwI15///+/v//9ez///jy///79////fv///////////////////////////////////////// + ///////////////////////////////////6+///WID//y97//9Zt///bNb//1/A//87j///Omfx/4V/ + clcAAAAAAAAAAAAAAADDkHr////////06v//9/D/mZaT/5mYl/+ZmZn/mZmZ//////+ZmZn/mZmZ/5mZ + mf+ZmZn/mZmZ/5mZmf+ZmZn/mZmZ////////////7u3s/1Bw8f8wevz/Wrn//2zW//9ev///Po7//zxv + ///GtsP/AAAAAAAAAAAAAAAAAAAAAMaTfP////////Pp///27v+ZlZL/mZeV/5mZmf+ZmZn//////5mZ + mf+ZmZn/nZ2d/7W1tf/FxcX/zMzM/8vLy//ExMT///////r6+v+Xk4r/W3KX/0qr9P9t2f//Xb7//z2N + //9AcP//7vH//65/ef8AAAAAAAAAAAAAAAAAAAAAyZZ9////////8+n///bu///48v//+/f///79//// + ///////////////////29vb/tbe4/4qMkf+EiJD/hIiP/4GEif+vsLH/6Ojo/46Ojf/i2dL/eaS1/02x + +P86i///RHP///Dz////////qndu/wAAAAAAAAAAAAAAAAAAAADKl37////////y5///9ez/mZWR/5mW + k/+ZmJf/mZmZ/5mZmf+0tLT/vL29/3Z7gv+yp5L/5ceW//HJjP/1zJH/8c+f/72yov9NU1n/kJCS/+7t + 7P/q4dj/S3Cq/zRf6P/y9P////////////+seW//AAAAAAAAAAAAAAAAAAAAAMyZf/////////Ll///0 + 6v+ZlJD/mZWS/5mXlf+ZmZn/qqqq/7+/wP+Agob/4cKQ//LKiv/syI7/6saP//DQnf/v06P/8MeK/+/O + mv9kZ23/mpuc/5OSkf+emYz/xsjQ/////////////////698cf8AAAAAAAAAAAAAAAAAAAAAz5yA//// + ////8eP///Pp///17P//+PL///v3///+/f/5+fn/h4uP/+bJmv/105n/79Ca/+/Qmf/vz5j/7s2Q/+7I + i//y06T/9NWg//LQn/9NUlr/3d3d/+jo6P//////////////////////sn9y/wAAAAAAAAAAAAAAAAAA + AADRnoH////////w4f//8uf/mZKM/5mUkP+ZlpP/srCv/8nKy/+uoo3/9NOc/+vQnv/q0p7/8dam//HV + ov/w057/79CY/+7Kjf/y1Kf/9dCR/7Ornf/CwsP///////////////////////////+0gXP/AAAAAAAA + AAAAAAAAAAAAANShg////////+/g///x4/+Zkoz/mZSP/5mVkf/DwsD/o6Wp/9nFmv/u16X/7Nep/+zX + qv/z3bD/89yt//Hbqf/w1KH/79Ca/+7Mj//227H/79Gj/5CSlv///////////////////////////7eE + dP8AAAAAAAAAAAAAAAAAAAAA16SE////////7dz///Dh///y5///9Or///fw///8+v+Qk5f/99+r//fm + vf/25r7/9unF//bnwP/35Ln/89+x//Hbqf/w1KH/78+V//LWqP/205r/jJCV//////////////////// + ////////uod2/wAAAAAAAAAAAAAAAAAAAADap4b////////s2v//7+D/mZGI/5mSjP+Zk47/zMrI/46Q + lv/13a7/+e7M//Xrz//06cr/8ufF//Divf/v3LP/7Niq//Hbqf/pzJb/7dGg//XRm/+EiI3/yMjI/5mZ + mf////////////////+9inf/AAAAAAAAAAAAAAAAAAAAANyph////////+rW///t3P+ZkIf/mZGJ/5mS + jP/Ewb7/pKWo/9nJpP//9tz/9/HY//f25//38Nv/9OnH//Hlwf/u27D/8tus/+nOmv/v0qD/582g/4mK + jv+/v7//mZmZ/////////////////7+MeP8AAAAAAAAAAAAAAAAAAAAA3quI////////6dX//+vY///u + 3v//8OH///Ln///37//a2dj/sKmY///83//+/fH//v36//7+8//89Nb/+O/P//bku//z3a//8dak//vb + of+roZL/x8jJ////////////////////////////wo96/wAAAAAAAAAAAAAAAAAAAADhror////////n + 0f//6tb/mY6D/5mPhv+ZkYj///Lo/9DNy/+hoKP/4tu9//r65f/7+/L/9/fn//Xw1//47sz/7961/+zX + qf/w157/4cma/3l+hP/7+/v////////////////////////////Fknv/AAAAAAAAAAAAAAAAAAAAAOOw + i////////+bP///o0/+ZjID/mY6E/5mPhv//8uX/q6ah/9bU0v+bm5r/5d7D//n54//69+P/9vDV//ru + yf/z4LL/992o/+DInf+AgYT/wMDA/////////////////////////////////8eUfP8AAAAAAAAAAAAA + AAAAAAAA5rOM////////5cz//+bP///p1f//69j//+3c///w4f//8uX///bv//Pw7v+jo6b/sq2e/+PY + uP//8MP//eu8/+LRqv+wqJf/hYiM/+Dg4f//////////////////////////////////////ypd+/wAA + AAAAAAAAAAAAAAAAAADpto3////////jyP//5cz/mYt9/5mMgP+ZjYL/mY6E/5mQh/+ZkYn/rqmk/9DO + zP/T0dH/np6i/4iKjv+Ehoz/kpSY/6ipqv/Nzc3//////5mZmf+ZmZn/mZmZ/5mZmf////////////// + ///MmX//AAAAAAAAAAAAAAAAAAAAAOu4jv///////+HE///kyv+ZiXv/mYt9/5mMgP+ZjYL/mY6E/5mQ + h/+ZkYn/npaQ///38P/JxsT/0c/N/9HPzf/Ix8X/tbSz/52cnP//////mZmZ/5mZmf+ZmZn/mZmZ//// + /////////////82af/8AAAAAAAAAAAAAAAAAAAAA7bqQ////////38H//+LG///kyv//5c3//+fR///p + 1f//69j//+3c///v4P//8eP///Ln///06v//9ez///fw///48v//+vX///v3///8+f///fv///79//// + ////////////////////////0J2B/wAAAAAAAAAAAAAAAAAAAADwvZH////////dvf//4ML/mYh3/5mJ + ef+ZiXv/mYt9/5mMgP//69j/mY6E/5mPhv+ZkIf/mZGJ/5mSjP//9Or/mZSP/5mUkP+ZlZH/mZWS/5mW + k/+Zl5T/mZeV/5mYl////fv///79///+/f/ToIL/AAAAAAAAAAAAAAAAAAAAAPPAk////////9y5///e + v/+ZhnT/mYh3/5mJef+ZiXv/mYt9///p1f+ZjID/mY6D/5mPhf+ZkIf/mZGI///y5/+Zkoz/mZKM/5mT + jv+ZlJD/mZWR/5mVkf+ZlZL/mZaT///79///+/f///v3/9ajhP8AAAAAAAAAAAAAAAAAAAAA9cKU//// + ////5s3//9y5///ev///4ML//+LG///kyv//5cz//+bP///o0///6tb//+vY///t3P//7+D///Dh///x + 4///8uf///Pp///06v//9ez///bu///27v//9/D///jy///48v//+PL/2KWF/wAAAAAAAAAAAAAAAAAA + AAD4xZX////////48v//5s3//9y5///dvf//38H//+HE///jyP//5cz//+bP///n0f//6dX//+rW///s + 2v//7dz//+/g///w4f//8eP///Ll///y5///8+n///Pp///06v//9ez///Xs/+7a0f/bqIb/AAAAAAAA + AAAAAAAAAAAAAPvIl4/6x5b///////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////9+//u2s3/572f/7aD + dI8AAAAAAAAAAAAAAAAAAAAAAAAAAPvIl4/7yJf/+seW//nGlv/4xZX/98SV//XClP/0wZP/88CT//K/ + kv/xvpL/8L2R/+67kP/tupD/7LmP/+y5j//ruI7/6reO/+m2jf/ntIz/5rOM/+Wyi//ksYv/47CL/+Kv + iv+2g3SPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/////////j4AAAAcAAAAHAAAABwAAAAcAA + AAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AA + AAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAAD4AAAB///////////KAAAADAAAABgAAAAAQAIAAAA + AACACgAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8AIVXwAMGOeQBt2f8ATE1PAPvboQCLldIArb3/ADhm + uQBfiP8AeX6EAK2qpwDlsosA+/DSAKBuagBNsfgAmZWLADmJ/wBnaGkA2cmkAOLe2gDi270ATInRAMai + kQDNtLUA8sqLAHWCtQA8b/8A7+3rAIV7awD/3r4AW3KXAGHE/wCytL8AqaCNALB9cQD//eMA79vRAJ2d + nQDXpIQA6tCfAIqLjQDb4f8AImT/AOzDnADEwr4A8deuAL+0oQD/+e4A376KALiLgQDu5MEAzZp/APvI + lwDY1tQA//HbAPG+kgCFgHgAkpOWAPzrvQD/6cgANHHqAOLRqgCZjIAA1b6jAM/LxwDi2dIApaepALyr + vwDhyZoAsqmZAPHWqACodW0AVrT/AODm5ACysa4A9dOaAPb29gD49usA99+rAIGEiQBYgP8A6uHYALaD + dACYl5cA6MSKALKWjQD/7dEA9uS4AP/05AD00JEA/ffXAFBw8QDpy5YA/f3vAMeUfQDqt44A36yIAL28 + uQBEc/8AkZCNANbAmAD/8MMA6eflAPPmzACemYwArn95AMfGxQBMpv8A8NeeAPby3QAweOgAWqjPAKGh + oQD2w5QA7sySANHPzQC4r5sA9uCyAPHaqADl3sMA0Z6BAKqpqADv0JgA8NCgANrZ2AD7+/sA+/bdAP/o + wwCZj4YAu66VAOvWqwBeuO8AZs7/APvvygDz8O4AiIeHAMrLywD07dcApHFrAKx5bwDnyZMAgYGCAPbb + sQDi07cArKSUAJmJeQDk4d8AtbSzAPfowADCwsMA//bpAPfqxQCRj4oAjZCWAJSUlADu37cA7talAOjO + oACopaEA//z3AO/jvQDt06MAop+aAESa/gDx9P8A/fniAPTq0gCdmJAA9tegAHd3eQCEh4wAuod2ANuo + hgC/v8AA7cSEAPPcrQDmyZoA18y8ALCurABbhv8A//37AP/y4AD/7tUA/+vMAPHnxgCalpEAmZmZAOjN + mwDNzMwA+fnwALOAcgCDiY8Avot4AMOQewD4xZUAyZZ9ANWigwDuu5AA57iDAOKvigDT0tEA+/v/AO/a + zgDFxMMAQHD/AF2//wD/3LkA9cyRAC54/wCKjJEA8NOeAJubnACfn6AAyMjJAP/68wD9+ucA/+DCAPfd + qADx1aIApaSkAKmtvwD5+fkAjIyMAJGRkQD25b4A4MidAMzKyAA7j/8Af8buAPb01wCZi30A+u7OAJmO + gwCZkYkA8tywAO/NlQCmc2wAqnduAK57cAC0gXMAl5WLAPTBkwDPnIAA7smQAPLTpADu0qAA0M7MAP/y + 6AD06ccA9NOcAO7KjwDw27MA79GcAO/OmgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI+PAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKu0j4+rAAAAAAAAABh6enp6 + enp69PT09PT0NTU1NTXFYGDDwwPCwq2tVPHAJDNFAj57lJyPAAAAAAAAGHqRWlpamJiYmJgxMTExMdjY + 2KGhoaG2trYBAQEBAQEBASsCLKWFlGiPAAAAAAAYemlaWlpamJiYmJgxMTExMdjY2KGhoaG2trYBAQEB + AQEBKwIspc+G5i5M4QAAAADGqDFaWlpamJiYmJgxMTExMdjY2KGhoaG2tra2AQEBAQErAiylIYYhbRep + jwAAAADGAbdaOjo6Ojo6Ojo6OjExOjo6Ojo6Ojo6Ojo6j4+JvCIC0qUhhiFtEiwbAAAAAAAoAbdaOjo6 + Ojo6Ojo6OjExOjo6Ojo6Ojo6Ojo6j4ne3gLSbSGGIW0SLAcAAAAAAAAoAbdaOjo6Ojo6Ojo6OjExOjo6 + Ojo6Ojo6Ojo6ibSaCQKlIYYhbRIsCBgAAAAAAAAoAbdaWlpaWpiYmJiYMTExMTHY2KGhtra2tra2Ab5V + ZQmFhiFtEiwIASQAAAAAAACuAbe3WlpaWpiYmJiYMTExMTHYoconqxMTq7w3AR2PvntxhW0SLAgBAcAA + AAAAAACuAbe3Ojo6Ojo6Ojo6Ojo6OqC0q6u8MEFBMNYTExOcIgFEF3ACBwEBAfEAAAAAAACuAbe3Ojo6 + Ojo6Ojo6Ojo6DHITpDKwsFYyyMifTAXgHb43wQIHcgEBAVQAAAAAAABiAbe3Ojo6Ojo6Ojo6Ojqg3auD + sFbt7VZeKSlWyLMFnHLh3Tu0iQEBAa0AAAAAAABiAbe3t1paWlqYmJiYmDGUq3Zb7e3t7XT8sF4vo7Cz + BRPKTGgBAQEBAa0AAAAAAABiAbe3t1paWlpamJiYmNjWqU3+1NTU/nx8dPz1L9ywe4kBAba2tgEBAcIA + AAAAAABiAbe3Ojo6Ojo6Ojo6mpWPZl7cnr2fvb1ejnx09ex0hBMdtra2tra2tsIAAAAAAADJAbe3Ojo6 + Ojo6Ojo6pHKa/imxsaOjKZ+9vdTtdH1IsDsitra2tra2tgMAAAAAAADJAbe3Ojo6Ojo6Ojo6tLwjo4R3 + d4SEhISjKdzU7XT9sHactra2tra2tsMAAAAAAAANATi3t7e3WlpaWlqY2N2Dd1lZmZmZ4ll3sXjc/nRI + 7TCJtqGhoaGhocMAAAAAAAANATi3t7e3WlpaWlqY2N12WZkO6emHmZZZd+xI1O1I7TCJtqGhoaGhoWAA + AAAAAADIATg4Ojo6Ojo6Ojo6TN2SPGmLqKhpuqKdhIR43I4pVke8ezo6OqGhoWAAAAAAAADIATg4Ojo6 + Ojo6Ojo6pEyaPKhvb09PqLo0nYSxSF4pVipjpDo6OqGhocUAAAAAAADIATg4Ojo6Ojo6Ojo6mmM7kahv + v7+/i2m6nYTseF69ZhNoiTo6OtjY2DUAAAAAAABhATg4ODi3t7e3WlpaWjFsEVynX6FfgFwOllnseNxN + u1Wh2NjY2NjY2DUAAAAAAABhATg4ODi3t7e3t1paWpgdRDAl2THZp4DpllmxeKowE2jY2NjY2NjY2DUA + AAAAAABhATg4Ojo6Ojq3tzo6OjqgzSd2529vgGmi/YSeKUeroKQxMTExMTExMTUAAAAAAADHATg4Ojo6 + Ojq3tzo6Ojo6tM3d8pGZh6Kd7Hhmu6vdDDoxMTExMTExMTUAAAAAAADHAbg4Ojo6Ojq3tzo6Ojo6OqAu + lZyaR3YwkpqPiUygOjoxMTExMTExMfQAAAAAAADHAbg4ODg4ODi3t7e3t1paWlqYMRUue9W8J0w32DGY + MTExMTExMTExMfQAAAAAAAA5Abi4ODg4ODg4t7e3t7daWlpaWpgx2NjY2DExmJiYmJiYMTExMTExMfQA + AAAAAAA5AVi4Ojo6Ojo6Ojo6Ojq3Wjo6Ojo6Ojo6Ojo6OjqYmDo6Ojo6OpiYmPQAAAAAAAA5AVi4Ojo6 + Ojo6Ojo6Ojq3tzo6Ojo6Ojo6Ojo6OjqYmDo6Ojo6OpiYmPQAAAAAAADzAblYOjo6Ojo6Ojo6Ojq3tzo6 + Ojo6Ojo6Ojo6OjqYmDo6Ojo6OpiYmPQAAAAAAADzAblYWLi4ODg4ODg4OLe3t7e3t7daWlpaWlpaWlpa + mJiYmJiYmJiYmHoAAAAAAABzAbm5WFi4uDg4ODg4ODg4t7e3t7e3WlpaWlpaWlpaWlpaWlqYmJiYmHoA + AAAAAADEAT25Hh46Ojo6Ojo6Ojo6Ojo6Ojo6t7c6Ojo6Ojo6Ojo6Ojo6OlpaWnoAAAAAAADEAT09Hh4e + Ojo6Ojo6Ojo6Ojo6Ojo6t7c6Ojo6Ojo6Ojo6Ojo6OlpaWnoAAAAAAADEAYE9Hh4eHjo6Ojo6Ojo6Ojo6 + Ojo6t7c6Ojo6Ojo6Ojo6Ojo6OlpaWnoAAAAAAAA2AYGBPT25uVhYuLi4ODg4ODg4ODg4t7e3t7e3t7e3 + t7daWlpaWlpaWnoAAAAAAAA2WjiBgT09ubm5WFi4uLg4ODg4ODg4ODi3t7e3t7e3t7e3t7e3t7e3kXoA + AAAAAABBNlo4gYGBPbm5uVhYuLi4ODg4ODg4ODg4ODi3t7e3t7e3t7e3tzFpehgAAAAAAAAALTZaAQEB + AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAah6GAAAAAAAAAAAAEE2NsTExHPz8zk5OcfHx2Fh + YcjIyA0NycliYmJirq6uKCgoxsYYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///////8AAP// + ////nwAA//////+DAAD4AAAAAAMAAPAAAAAAAwAA4AAAAAABAADgAAAAAAEAAOAAAAAAAwAA4AAAAAAH + AADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAA + AAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAH + AADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAA + AAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAH + AADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAPAAAAAADwAA+AAAAAAfAAD///////8AAP// + /////wAA////////AAAoAAAAMAAAAGAAAAABACAAAAAAAIAlAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI6MgwJycm/BcnJyu2Rk + ZChmZmY0V1dXAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQ3 + +CN7e4P+sK+t/4CAgP6CgoL/bW1twmxsbAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADPnICj0J2B/9Cd + gf/QnYH/0J2B/9Cdgf/QnYH/0J2B/8+cgP/PnID/z5yA/86bgP/Om4D/zpuA/82af//Nmn//zJl//8yZ + f//MmX//yZZ9/8iVff/Gk3z/xJF7/8KPev/Bjnn/vot4/72KeP+7iHb/uYZ1/7aDdP+0gXP/s4By/7B9 + cf+4i4H/vKu//yJR9f80cer/q6in/+Hg3/+UlJT/hISE/2VlZUsAAAAAAAAAAAAAAAAAAAAAAAAAANKf + gszQnYH/7tS////04///9OT///Xl///15///9ej///bp///26v//9+v///fs///47f//+O7///nv///5 + 8P//+fL///rz///69P//+/X///v2///89////Pj///z5///9+v///fz///79///+/v////////////// + ///////////////////d4///KFn//ytz//9CmP//aLTo/+bh3//m5eT/goKC/mVlZUAAAAAAAAAAAAAA + AAAAAAAA06CCo9Gegf/24s7///Pi///04///9OT///Xl///15///9ej///bp///26v//9+v///fs///4 + 7f//+O7///nv///58P//+fL///rz///69P//+/X///v2///89////Pj///z5///9+v///fz///79///+ + /v///////////////////////////9vi//8nWv//LHX//0OZ//9dv///ZM7//3/G7v/Hwr7/s7Kx/nR0 + dHsAAAAAAAAAAAAAAAAAAAAA1KGD//Xl2P//+O3///Pi///04///9OT///Xl///15///9ej///bp///2 + 6v//9+v///fs///47f//+O7///nv///58P//+fL///rz///69P//+/X///v2///89////Pj///z5///9 + +v///fz///78///+/f//////////////////////2N///ydY//8tdv//RJn//17A//9nzv//Y8j//0yq + //9XitP/npmS/3l5edwAAAAAAAAAAAAAAAAAAAAA1aKD////////8+H///Pi/4V/dv+Ff3f/hYB3/4WA + eP+FgHn/hYB6/4WAev+FgXv/hYF7/4WBfP//+O7///nv/4WCff+Fgn7/hYJ+/4WCf/+Fg4D/hYOA/4WD + gf+Fg4H/hYOC/4WEgv+FhIP/hYSD/4WEhP+FhIT/hYWF/5iYmP+jq8z/H1P5/y53//9GnP//X8H//2fO + //9ix///T6n//zqL//8XW/7/QFi8g3Fway4AAAAAAAAAAAAAAAAAAAAA1qOE////////8+H///Pi/4V/ + dv+Ff3f/hX93/4WAeP+FgHj/hYB5/4WAev+FgXv/hYF7/4WBfP//+O7///jv/4WCff+Fgn7/hYJ+/4WC + f/+Fg4D/hYOA/4WDgP+Fg4H/hYOC/4WEgv+FhIP/hYSD/4WEhP+Lior/sbGx/6GozP8cS+f/Lnn+/0ed + //9fwv//Z87//2LG//9OqP//OYr//x1c//+Hi9H/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA16SE//// + ////8+H///Pi/4V/dv+Ff3f/hX93/4WAeP+FgHj/hYB5/4WAev+FgXv/hYF7/4WBfP//+O7///jv/4WC + ff+Fgn7/hYJ+/4WCf/+Fgn//hYOA/4WDgP+Fg4H/hYOB/4WDgv+FhIL/hYSD/4uKif+vrq7/kpCM/yxM + sf8nauD/R5z8/2DE//9nzv//YcX//06n//85if//HVr//6e5///Gopr/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA2KWF////////8+H///Pi///z4v//9OT///Tl///15v//9ef///bo///26f//9ur///fr///3 + 7P//+O7///jv///57///+fD///ny///68///+/b///z4///9+v///fv///37///9+////vv///37///9 + /f/Nzcz/mZiX/5GQjf9Df8H/Wrny/2jP//9hxf//Tab//ziI//8cW///rb3///////+wfXH/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA2aaG////////8+D///Ph///z4v//9OT///Tl///15v//9ef///Xo///2 + 6f//9ur///fr///37P//+O3///ju///57///+fD///rz//369v/U0tD/np6c/3l6ev9naGn/Zmdo/3Z2 + dv+amZn/19bU///+/f/v7u3/g4OD/83My/+rrKr/WqjP/1m79P9Lpf//OIb//xxZ//+ywf////////// + //+zgHL/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA26iG////////8uD///Ph/4V/dv+Ff3b/hX93/4WA + d/+FgHj/hYB5/4WAev+FgHr/hYF7/4WBe/+FgXz/hYF8/4WBff+npaL/r66s/3R0df9wcnT/mpqZ/7+z + o//OvqT/0b+n/8G4qP+dnqH/YmVn/2VlZv9nZ2f/lJSU/7m5uf/+/f3/pKiq/0GIz/8weOj/GVHy/4ua + 0/////////////////+0gXP/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3KmH////////8uD///Ph/4V/ + dv+Ff3b/hX93/4V/d/+FgHj/hYB4/4WAef+FgHr/hYB6/4WBe/+FgXv/hYF8/66rqP+goJ//bm9y/6Gd + lf/YvI//8MaF/+/Iiv/nw4b/5sCF/+e9fv/mu3X/6cyi/7Gvrf9KS03/jIyM/+3t7f/MzMz/2NbV/4OJ + j/8YRsr/j5vS/6Kiov////////////////+2g3T/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3aqH//// + ////8uD///Ph/4V/dv+Ff3b/hX93/4V/d/+FgHj/hYB4/4WAef+FgHr/hYB6/4WBe/+FgXv/pqOf/6Wk + o/92eHv/u6yU/+nChf/nxIj/7syU/+7LlP/nxo//6cmU/+vPoP/rzqD/58KJ/+a6d//Wy7v/TlFT/5SU + lP+goKD/kZGR/6Skof+TlJb/r66u/4WFhf////////////////+5hnX/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA3quI////////8t////Pg///z4f//8+L///Tj///05P//9eX///Xn///16P//9uj///bp///3 + 6///+O7/5uPf/3l6fP+8rpb/9NCR/+/OlP/vzpX/7s6U/+7NlP/uy5L/7sqP/+3Hi//tzJf/8deu//DS + ov/swHv/1829/0tMTv9jY2P/0dHR/7GxsP/o5+f///79///+/f///v7///7+///+/v+7iHb/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA36yI////////8t////Lg///z4f//8+L///Tj///05P//9OX///Xm///1 + 5///9uj///bp///26v//+vP/oJ+f/5uWjv/21Jn/8NGc//DSnf/w0p3/8NKd//DRnP/v0Jn/79CY/+7N + kv/uyo//7cmP//HXrv/x06L/7sJ//6iopv+GhYb///79///+/f///fz///78///+/P///v3///79///+ + /f+9inj/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4K2J////////8t7///Lg/4V/df+Ff3X/hX92/4V/ + d/+Ff3f/hYB3/4WAeP+FgHn/hYB6/5GNiP+3tbP/f4GE/9W9kv/ozJj/8daj//HYpP/nz5z/58+d/+fN + nP/nzJn/58qV/+bIkv/vz5j/7suQ/+7JkP/y27H/7sqT/+zSq/9cXmH/7ezq///9+v///fv///37///9 + /P///fz///38///9/P++i3j/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4a6K////////8t7///Lf/4V+ + df+Ff3X/hX92/4V/dv+Ff3f/hX93/4WAeP+FgHj/hYB5/6WhnP+joqH/kI2J/+7RnP/o0J//8tus//Pc + rP/q06P/6tOj/+nSov/o0KD/58+c/+fMmf/w0p3/78+X/+7Lkf/w0KD/8NWr/+7Eg/+QkZX/urm4///9 + +v///fr///36///9+v///fr///36///9+v/Bjnn/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4q+K//// + ////8t7///Lf/4V+df+Ff3X/hX92/4V/dv+Ff3f/hX93/4WAd/+FgHj/hYB5/7Guqv+ampn/qaCN/+7T + o//s1aj/9eCz//Xgs//r16z/69is/+vXqf/q1af/6tOj/+jQn//x1qT/8NKd/+/Pl//vzJL/8tmz/+/I + iv+zrKL/lZSU///9+v///Pn///z5///8+f///Pn///z5///8+f/Cj3r/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA5LGL////////8d3///Le///y3///8+D///Ph///z4v//9OP///Tk///05f//9eb///Xn///6 + 8v+jo6P/uq+V//fhsf/25bz/9uW8//bpxf/368f/+OrE//blvv/247f/9eCy//Pdrv/x2aj/8dah//DR + nP/uzpL/8ter//DMlP/HuaX/hYSF///9+v///Pf///z4///8+P///Pj///z4///8+P/EkXv/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA5bKL////////8d3///Le///y3///8uD///Ph///z4v//8+L///Tk///0 + 5f//9eX///Xn///58f+mpqX/ua6W//jktv/36cT/++/S//vuzv/47s3/+O3K//fqxf/36b//9uO4//Xg + s//z3K//8dim//DTnv/vz5f/8dWn//DNlf/EtqL/hoaG///8+f//+/b///v3///89////Pf///z3///8 + 9//Gk3z/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA5rOM////////8dz///Hd/4V+dP+FfnT/hX91/4V/ + df+Ff3b/hX92/4V/d/+Ff3f/hYB4/7Kvqv+mpqX/rKOT//rpuv/x58n/9OvV//Tqzf/y68//8+jL//Dn + xP/u4r7/7d+5/+vYrv/q1af/8tqp//HWpP/nyZP/686f/+rHjf+vp5r/mZmY/6upp/+Fg4D/hYOA/4WD + gP//+/b///v2///79v/IlX3/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA57SM////////8dz///Hd/4V+ + dP+FfnT/hX51/4V/df+Ff3X/hX92/4V/dv+Ff3f/hX93/6ainP+ysa//k5GN//3twP/07NH/9fHd//Xx + 3v/49+z/+PXp//Przv/w5sb/7uTB/+3dtP/r2Kz/89ys//HXpf/nypX/6tCf/+nEif+Ki43/u7q4/5+c + mv+Fg4D/hYOA/4WDgP//+/X///v1///79f/Jln3/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA6LWN//// + ////8dv///Hc/4V+c/+FfnT/hX50/4V+df+Ff3X/hX92/4V/dv+Ff3f/hX93/5KOhv++vbr/k5SX/9/U + sv/07dH/9/Pg//n47v/6+vL/+fnw//Tv2P/x6cz/8ufH/+7et//r2Kz/892v//Hap//nypb/6c2a/9fA + mf9rbG//7Onn/42Kh/+Fgn//hYJ//4WCf///+vT///r0///69P/MmX//AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA6baO////////8Nv///Hb///x3f//8d3///Le///y4P//8+D///Ph///z4v//9OP///Tk///0 + 5f//+fD/x8bF/5mVi///+Nf//Pjh//387v///vf//f3v//z33f/79df/+vDR//jov//247j/892v//HZ + p//w1aD/9NKa/5qWkv+Xlpb///v3///68v//+vL///ry///68///+vP///rz///68//MmX//AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA6reO////////8Nr///Hb///x3P//8d3///Le///y3///8uD///Ph///z + 4f//8+L///Tj///05P//9ej/8u7p/6Wlp/+6tKD///3j//365f/9/Ov//Prp//354//79dv/++/O//fo + wv/25Lj/892u//Lap//216D/u7Cc/3Bxc//p5+P///nx///58f//+fH///nx///58v//+fL///ny///5 + 8v/MmX//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA67iP////////8Nr///Da/4V+cv+FfnP/hX5z/4V+ + dP+FfnT///Lg///z4f+Ff3b/hX92/4V/dv+Ff3f/qaWg/8XEwv+cnZ//tbGd//b01//389z/9vLc//v2 + 3v/y6cv/7uK8/+3cs//s2Kv/69Sm/+3TnP+3q5b/dHV4/6empP+hnpv///nv///58P//+fD///nw///5 + 8P//+fD///nw///58P/Nmn//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA7bqP////////8Nn///Da/4V9 + cv+FfnL/hX5z/4V+c/+FfnT///Lf///y4P+Ff3X/hX92/4V/dv+Ff3b/hX93/7Guqf/FxMP/o6Sl/5eV + i//a0rP/9OrE//3xyv/w5Lz/8OC2//HcsP/w2qr/1cKd/5mVj/95enz/p6Wk/6uopf+FgXz///jv///4 + 7///+O////nv///57///+e////nv///57//Nmn//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA7ruQ//// + ////79f///DZ/4V9cv+FfnL/hX5z/4V+c/+FfnT///Le///y3/+Ff3X/hX91/4V/dv+Ff3b/hX92/4V/ + d/+sqKL/xMK//7Oys/+Sk5P/k5GN/7CqnP+5sJv/urGZ/6yllf+Qjor/gIGD/4qJif+0s7D/pqOe/4WB + fP+FgXz///ju///47v//+O7///ju///47v//+O7///ju///47v/Om4D/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA77yQ////////79b///DZ///w2f//8Nr///Hb///x3P//8d3///Le///y3v//8uD///Pg///z + 4f//8+L///Pi///04///9OT///bp//347//i3tr/wsG+/6uqqv+bm5z/mJiY/52dnP+0srD/2tfT//75 + 8///+O3///fr///37P//9+z///fs///47f//+O3///jt///47f//+O3///jt///47f/Om4D/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA8L2R////////7tT//+/W///w2f//8Nr///Da///x2///8dz///Hd///y + 3v//8t////Lg///z4P//8+H///Pi///z4v//9OP///Tk///05P//9un///ju///58f//+vL///rz///6 + 8v//+fD///fs///26f//9ur///bq///36///9+v///fr///37P//9+z///fs///37P//9+z///fs///3 + 7P/Om4D/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8b6S////////7dL//+7U/4V9cP+FfXH/hX1y/4V9 + cv+FfnL/hX5z/4V+c/+FfnT/hX50/4V+df+Ff3X///Ph///z4v+Ff3b/hX92/4V/d/+Ff3f/hX93/4WA + d/+FgHj/hYB4/4WAeP+FgHn/hYB5/4WAef+FgHr///bp///26f+FgHr/hYB6/4WBe/+FgXv/hYF7/4WB + e///9+v///fr///36//PnID/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8r+S////////7ND//+7T/4V8 + b/+FfXD/hX1x/4V9cv+FfXL/hX5y/4V+c/+FfnP/hX50/4V+dP+FfnT///Lg///z4f+Ff3X/hX92/4V/ + dv+Ff3b/hX93/4V/d/+Ff3f/hYB3/4WAeP+FgHj/hYB4/4WAef+FgHn///bo///26f+FgHr/hYB6/4WA + ev+FgHr/hYB6/4WAev//9ur///bq///26v/PnID/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA88CT//// + ////7M7//+3R/4V8bv+FfG//hX1w/4V9cf+FfXL/hX1y/4V+cv+FfnP/hX5z/4V+dP+FfnT///Lf///y + 4P+Ff3X/hX91/4V/dv+Ff3b/hX92/4V/d/+Ff3f/hX93/4V/d/+FgHf/hYB4/4WAeP+FgHj///Xn///1 + 6P+FgHn/hYB5/4WAef+FgHn/hYB6/4WAev//9un///bp///26f/PnID/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA9MGT////////68z//+zP///t0f//7tP//+7V///w2f//8Nn///Da///w2///8dv///Hc///x + 3f//8t7///Le///y3///8uD///Pg///z4f//8+H///Pi///z4v//9OP///Tk///05P//9OX///Tl///1 + 5f//9eb///Xm///15///9ef///Xn///15///9ef///Xo///16P//9ej///Xo///16P/QnYH/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA9sOU////////6sv//+vN///sz///7dH//+7T///u1f//8Nn///DZ///w + 2v//8Nv///Hb///x3P//8d3///Hd///y3v//8t////Lg///y4P//8+H///Ph///z4v//8+L///Pi///0 + 4///9OT///Tk///05P//9OX///Tl///15f//9eb///Xm///15v//9eb///Xn///15///9ef///Xn///1 + 5//QnYH/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA98SU////////6sn//+rL/4V7a/+Fe2z/hXxt/4V8 + bv+FfG//hX1w/4V9cf+FfXL/hX1y/4V+cv+FfnP/hX5z/4V+c/+FfnT/hX50/4V+dP+FfnX/hX91///z + 4f//8+H/hX92/4V/dv+Ff3b/hX92/4V/dv+Ff3f/hX93/4V/d/+Ff3f/hX93/4V/d/+Ff3f/hYB3/4WA + d///9eX///Xl///15f/QnYH/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+MWV////////6cf//+rJ/4V6 + av+Fe2v/hXts/4V8bf+FfG7/hXxv/4V9cP+FfXH/hX1y/4V9cv+FfnL/hX5y/4V+c/+FfnP/hX5z/4V+ + dP+FfnT/hX50///y4P//8+D/hX91/4V/df+Ff3X/hX92/4V/dv+Ff3b/hX92/4V/dv+Ff3f/hX93/4V/ + d/+Ff3f/hX93/4V/d///9OT///Tk///05P/QnYH/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+caW//// + ////6MP//+nH/4V6af+Femr/hXtr/4V7bP+FfG3/hXxu/4V8b/+FfXD/hX1x/4V9cf+FfXL/hX1y/4V+ + cv+FfnP/hX5z/4V+c/+FfnT/hX50///y3///8t//hX51/4V+df+Ff3X/hX91/4V/df+Ff3b/hX92/4V/ + dv+Ff3b/hX92/4V/dv+Ff3b/hX92/4V/dv//9OP///Tj///04//QnYH/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA+seW////////58H//+jE///px///6sn//+rL///rzf//7M///+3R///u0///7tT//+/W///w + 2f//8Nn///Da///w2v//8dv///Hb///x3P//8d3///Hd///y3v//8t7///Lf///y3///8uD///Lg///z + 4P//8+H///Ph///z4f//8+H///Pi///z4v//8+L///Pi///z4v//8+L///Pi///z4v/QnYH/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA+8iX//7y4v//8Nn//+fB///ow///6cf//+rJ///qy///68z//+zO///s + 0P//7dL//+7U///v1v//79f///DZ///w2v//8Nr///Db///x2///8dz///Hc///x3f//8d3///Le///y + 3v//8t7///Lf///y3///8uD///Lg///y4P//8+D///Ph///z4f//8+H///Ph///z4f//8+H///Ph/+7U + v//QnYH/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/MmXo/zJl//+9OX///DZ///nwf//6MP//+jF///p + yP//6sr//+vM///szv//7ND//+3R///u0///7tX//+/X///w2f//8Nn///Da///w2v//8Nv///Hb///x + 3P//8dz///Hd///x3f//8d3///Le///y3v//8t7///Lf///y3///8t////Lg///y4P//8uD///Lg///y + 4P//9+z/9uHN/9Kfgv/PnICjAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP3KmMz8yZf//vLi//// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ///////////////////15df/0Z6B/9KfgswAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAD8yZej+8iX//rHlv/5xpb/+MWV//fElP/2w5T/9MGT//PAk//yv5L/8b6S//C9kf/vvJD/7ruQ/+26 + j//ruI//6reO/+m2jv/otY3/57SM/+azjP/lsov/5LGL/+Kviv/hror/4K2J/9+siP/eq4j/3aqH/9yp + h//bqIb/2aaG/9ilhf/XpIT/1qOE/9Wig//UoYP/06CCowAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////AAD//////58AAP//////gwAA+AAAAAAD + AADwAAAAAAMAAOAAAAAAAQAA4AAAAAABAADgAAAAAAMAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAA + AAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAH + AADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAA + AAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAH + AADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAA + AAAABwAA4AAAAAAHAADwAAAAAA8AAPgAAAAAHwAA////////AAD///////8AAP///////wAA + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/RegMon/RegistryAccessControlForm.Designer.cs b/Demo_Source_Code/CSharpDemo/RegMon/RegistryAccessControlForm.Designer.cs new file mode 100644 index 0000000..62e0cba --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/RegMon/RegistryAccessControlForm.Designer.cs @@ -0,0 +1,462 @@ +namespace EaseFilter.CommonObjects +{ + partial class RegistryAccessControlForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.groupBox_AccessControl = new System.Windows.Forms.GroupBox(); + this.button_Apply = new System.Windows.Forms.Button(); + this.button_DeleteFilter = new System.Windows.Forms.Button(); + this.button_AddFilter = new System.Windows.Forms.Button(); + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.listView_FilterRules = new System.Windows.Forms.ListView(); + this.groupBox2 = new System.Windows.Forms.GroupBox(); + this.label20 = new System.Windows.Forms.Label(); + this.label13 = new System.Windows.Forms.Label(); + this.textBox_ExcludeUserNames = new System.Windows.Forms.TextBox(); + this.label14 = new System.Windows.Forms.Label(); + this.textBox_ExcludeProcessNames = new System.Windows.Forms.TextBox(); + this.label11 = new System.Windows.Forms.Label(); + this.label3 = new System.Windows.Forms.Label(); + this.label5 = new System.Windows.Forms.Label(); + this.textBox_RegistryKeyNameFilterMask = new System.Windows.Forms.TextBox(); + this.radioButton_Name = new System.Windows.Forms.RadioButton(); + this.radioButton_Pid = new System.Windows.Forms.RadioButton(); + this.label4 = new System.Windows.Forms.Label(); + this.button_Info = new System.Windows.Forms.Button(); + this.label2 = new System.Windows.Forms.Label(); + this.checkBox_isExcludeFilter = new System.Windows.Forms.CheckBox(); + this.button_SelectRegistryCallbackClass = new System.Windows.Forms.Button(); + this.textBox_AccessFlags = new System.Windows.Forms.TextBox(); + this.textBox_RegistryCallbackClass = new System.Windows.Forms.TextBox(); + this.button_SelectProcessId = new System.Windows.Forms.Button(); + this.label1 = new System.Windows.Forms.Label(); + this.textBox_ProcessId = new System.Windows.Forms.TextBox(); + this.label17 = new System.Windows.Forms.Label(); + this.button_SelectRegistryAccessFlags = new System.Windows.Forms.Button(); + this.textBox_ProcessName = new System.Windows.Forms.TextBox(); + this.textBox_ExcludeKeyNames = new System.Windows.Forms.TextBox(); + this.label6 = new System.Windows.Forms.Label(); + this.groupBox_AccessControl.SuspendLayout(); + this.groupBox1.SuspendLayout(); + this.groupBox2.SuspendLayout(); + this.SuspendLayout(); + // + // groupBox_AccessControl + // + this.groupBox_AccessControl.Controls.Add(this.button_Apply); + this.groupBox_AccessControl.Controls.Add(this.button_DeleteFilter); + this.groupBox_AccessControl.Controls.Add(this.button_AddFilter); + this.groupBox_AccessControl.Controls.Add(this.groupBox1); + this.groupBox_AccessControl.Controls.Add(this.groupBox2); + this.groupBox_AccessControl.Dock = System.Windows.Forms.DockStyle.Fill; + this.groupBox_AccessControl.Location = new System.Drawing.Point(0, 0); + this.groupBox_AccessControl.Name = "groupBox_AccessControl"; + this.groupBox_AccessControl.Size = new System.Drawing.Size(546, 541); + this.groupBox_AccessControl.TabIndex = 25; + this.groupBox_AccessControl.TabStop = false; + // + // button_Apply + // + this.button_Apply.DialogResult = System.Windows.Forms.DialogResult.OK; + this.button_Apply.Location = new System.Drawing.Point(375, 501); + this.button_Apply.Name = "button_Apply"; + this.button_Apply.Size = new System.Drawing.Size(138, 23); + this.button_Apply.TabIndex = 80; + this.button_Apply.Text = "Apply Filter Rule Settings"; + this.button_Apply.UseVisualStyleBackColor = true; + this.button_Apply.Click += new System.EventHandler(this.button_Apply_Click); + // + // button_DeleteFilter + // + this.button_DeleteFilter.Location = new System.Drawing.Point(190, 501); + this.button_DeleteFilter.Name = "button_DeleteFilter"; + this.button_DeleteFilter.Size = new System.Drawing.Size(103, 23); + this.button_DeleteFilter.TabIndex = 79; + this.button_DeleteFilter.Text = "Delete Filter Rule"; + this.button_DeleteFilter.UseVisualStyleBackColor = true; + this.button_DeleteFilter.Click += new System.EventHandler(this.button_DeleteFilter_Click); + // + // button_AddFilter + // + this.button_AddFilter.Location = new System.Drawing.Point(6, 501); + this.button_AddFilter.Name = "button_AddFilter"; + this.button_AddFilter.Size = new System.Drawing.Size(116, 23); + this.button_AddFilter.TabIndex = 78; + this.button_AddFilter.Text = "Add New Filter Rule"; + this.button_AddFilter.UseVisualStyleBackColor = true; + this.button_AddFilter.Click += new System.EventHandler(this.button_AddFilter_Click); + // + // groupBox1 + // + this.groupBox1.Controls.Add(this.listView_FilterRules); + this.groupBox1.Location = new System.Drawing.Point(6, 396); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size(517, 93); + this.groupBox1.TabIndex = 77; + this.groupBox1.TabStop = false; + this.groupBox1.Text = "Registry Filter Rule Collection"; + // + // listView_FilterRules + // + this.listView_FilterRules.Dock = System.Windows.Forms.DockStyle.Fill; + this.listView_FilterRules.FullRowSelect = true; + this.listView_FilterRules.HideSelection = false; + this.listView_FilterRules.Location = new System.Drawing.Point(3, 16); + this.listView_FilterRules.Name = "listView_FilterRules"; + this.listView_FilterRules.Size = new System.Drawing.Size(511, 74); + this.listView_FilterRules.TabIndex = 1; + this.listView_FilterRules.UseCompatibleStateImageBehavior = false; + this.listView_FilterRules.View = System.Windows.Forms.View.Details; + this.listView_FilterRules.SelectedIndexChanged += new System.EventHandler(this.listView_FilterRules_SelectedIndexChanged); + // + // groupBox2 + // + this.groupBox2.Controls.Add(this.textBox_ExcludeKeyNames); + this.groupBox2.Controls.Add(this.label6); + this.groupBox2.Controls.Add(this.label20); + this.groupBox2.Controls.Add(this.label13); + this.groupBox2.Controls.Add(this.textBox_ExcludeUserNames); + this.groupBox2.Controls.Add(this.label14); + this.groupBox2.Controls.Add(this.textBox_ExcludeProcessNames); + this.groupBox2.Controls.Add(this.label11); + this.groupBox2.Controls.Add(this.label3); + this.groupBox2.Controls.Add(this.label5); + this.groupBox2.Controls.Add(this.textBox_RegistryKeyNameFilterMask); + this.groupBox2.Controls.Add(this.radioButton_Name); + this.groupBox2.Controls.Add(this.radioButton_Pid); + this.groupBox2.Controls.Add(this.label4); + this.groupBox2.Controls.Add(this.button_Info); + this.groupBox2.Controls.Add(this.label2); + this.groupBox2.Controls.Add(this.checkBox_isExcludeFilter); + this.groupBox2.Controls.Add(this.button_SelectRegistryCallbackClass); + this.groupBox2.Controls.Add(this.textBox_AccessFlags); + this.groupBox2.Controls.Add(this.textBox_RegistryCallbackClass); + this.groupBox2.Controls.Add(this.button_SelectProcessId); + this.groupBox2.Controls.Add(this.label1); + this.groupBox2.Controls.Add(this.textBox_ProcessId); + this.groupBox2.Controls.Add(this.label17); + this.groupBox2.Controls.Add(this.button_SelectRegistryAccessFlags); + this.groupBox2.Controls.Add(this.textBox_ProcessName); + this.groupBox2.Location = new System.Drawing.Point(6, 19); + this.groupBox2.Name = "groupBox2"; + this.groupBox2.Size = new System.Drawing.Size(517, 371); + this.groupBox2.TabIndex = 76; + this.groupBox2.TabStop = false; + this.groupBox2.Text = "Add or Edit The Registry Filter Rule Entry"; + // + // label20 + // + this.label20.AutoSize = true; + this.label20.Font = new System.Drawing.Font("Microsoft Sans Serif", 6.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.label20.Location = new System.Drawing.Point(202, 213); + this.label20.Name = "label20"; + this.label20.Size = new System.Drawing.Size(168, 12); + this.label20.TabIndex = 134; + this.label20.Text = "( split with \';\' i.e \"*test1.exe;*test2.exe\")"; + // + // label13 + // + this.label13.AutoSize = true; + this.label13.Font = new System.Drawing.Font("Microsoft Sans Serif", 6.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.label13.Location = new System.Drawing.Point(202, 255); + this.label13.Name = "label13"; + this.label13.Size = new System.Drawing.Size(245, 12); + this.label13.TabIndex = 133; + this.label13.Text = "(split with \';\' for multiple items, format \"domain\\username\" )"; + // + // textBox_ExcludeUserNames + // + this.textBox_ExcludeUserNames.Location = new System.Drawing.Point(204, 232); + this.textBox_ExcludeUserNames.Name = "textBox_ExcludeUserNames"; + this.textBox_ExcludeUserNames.Size = new System.Drawing.Size(242, 20); + this.textBox_ExcludeUserNames.TabIndex = 132; + // + // label14 + // + this.label14.AutoSize = true; + this.label14.Location = new System.Drawing.Point(8, 236); + this.label14.Name = "label14"; + this.label14.Size = new System.Drawing.Size(102, 13); + this.label14.TabIndex = 131; + this.label14.Text = "Exclude user names"; + // + // textBox_ExcludeProcessNames + // + this.textBox_ExcludeProcessNames.Location = new System.Drawing.Point(203, 190); + this.textBox_ExcludeProcessNames.Name = "textBox_ExcludeProcessNames"; + this.textBox_ExcludeProcessNames.Size = new System.Drawing.Size(242, 20); + this.textBox_ExcludeProcessNames.TabIndex = 130; + // + // label11 + // + this.label11.AutoSize = true; + this.label11.Location = new System.Drawing.Point(7, 193); + this.label11.Name = "label11"; + this.label11.Size = new System.Drawing.Size(119, 13); + this.label11.TabIndex = 129; + this.label11.Text = "Exclude process names"; + // + // label3 + // + this.label3.AutoSize = true; + this.label3.Location = new System.Drawing.Point(6, 19); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(151, 13); + this.label3.TabIndex = 105; + this.label3.Text = "Registry Key Name Filter Mask"; + // + // label5 + // + this.label5.AutoSize = true; + this.label5.Location = new System.Drawing.Point(201, 40); + this.label5.Name = "label5"; + this.label5.Size = new System.Drawing.Size(181, 13); + this.label5.TabIndex = 104; + this.label5.Text = "(key name filter mask, i.e. *Windows*"; + // + // textBox_RegistryKeyNameFilterMask + // + this.textBox_RegistryKeyNameFilterMask.Location = new System.Drawing.Point(203, 19); + this.textBox_RegistryKeyNameFilterMask.Name = "textBox_RegistryKeyNameFilterMask"; + this.textBox_RegistryKeyNameFilterMask.Size = new System.Drawing.Size(242, 20); + this.textBox_RegistryKeyNameFilterMask.TabIndex = 103; + this.textBox_RegistryKeyNameFilterMask.Text = "*"; + // + // radioButton_Name + // + this.radioButton_Name.AutoSize = true; + this.radioButton_Name.Location = new System.Drawing.Point(9, 138); + this.radioButton_Name.Name = "radioButton_Name"; + this.radioButton_Name.Size = new System.Drawing.Size(134, 17); + this.radioButton_Name.TabIndex = 102; + this.radioButton_Name.Text = "Filter By Process Name"; + this.radioButton_Name.UseVisualStyleBackColor = true; + this.radioButton_Name.Click += new System.EventHandler(this.radioButton_Name_Click); + // + // radioButton_Pid + // + this.radioButton_Pid.AutoSize = true; + this.radioButton_Pid.Checked = true; + this.radioButton_Pid.Location = new System.Drawing.Point(9, 106); + this.radioButton_Pid.Name = "radioButton_Pid"; + this.radioButton_Pid.Size = new System.Drawing.Size(114, 17); + this.radioButton_Pid.TabIndex = 101; + this.radioButton_Pid.TabStop = true; + this.radioButton_Pid.Text = "Filter by Process Id"; + this.radioButton_Pid.UseVisualStyleBackColor = true; + this.radioButton_Pid.Click += new System.EventHandler(this.radioButton_Pid_Click); + // + // label4 + // + this.label4.AutoSize = true; + this.label4.Location = new System.Drawing.Point(201, 126); + this.label4.Name = "label4"; + this.label4.Size = new System.Drawing.Size(152, 13); + this.label4.TabIndex = 93; + this.label4.Text = "(skip processId check if it is 0 )"; + // + // button_Info + // + this.button_Info.Location = new System.Drawing.Point(465, 343); + this.button_Info.Name = "button_Info"; + this.button_Info.Size = new System.Drawing.Size(41, 20); + this.button_Info.TabIndex = 92; + this.button_Info.UseVisualStyleBackColor = true; + this.button_Info.Click += new System.EventHandler(this.button_Info_Click); + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(201, 168); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(153, 13); + this.label2.TabIndex = 90; + this.label2.Text = "(use * to include all processes )"; + // + // checkBox_isExcludeFilter + // + this.checkBox_isExcludeFilter.AutoSize = true; + this.checkBox_isExcludeFilter.Location = new System.Drawing.Point(203, 346); + this.checkBox_isExcludeFilter.Margin = new System.Windows.Forms.Padding(1); + this.checkBox_isExcludeFilter.Name = "checkBox_isExcludeFilter"; + this.checkBox_isExcludeFilter.Size = new System.Drawing.Size(172, 17); + this.checkBox_isExcludeFilter.TabIndex = 89; + this.checkBox_isExcludeFilter.Text = "Is Excluded Registry Filter Rule"; + this.checkBox_isExcludeFilter.UseVisualStyleBackColor = true; + // + // button_SelectRegistryCallbackClass + // + this.button_SelectRegistryCallbackClass.Location = new System.Drawing.Point(465, 314); + this.button_SelectRegistryCallbackClass.Name = "button_SelectRegistryCallbackClass"; + this.button_SelectRegistryCallbackClass.Size = new System.Drawing.Size(41, 20); + this.button_SelectRegistryCallbackClass.TabIndex = 88; + this.button_SelectRegistryCallbackClass.Text = "..."; + this.button_SelectRegistryCallbackClass.UseVisualStyleBackColor = true; + this.button_SelectRegistryCallbackClass.Click += new System.EventHandler(this.button_SelectRegistryCallbackClass_Click); + // + // textBox_AccessFlags + // + this.textBox_AccessFlags.Location = new System.Drawing.Point(203, 280); + this.textBox_AccessFlags.Name = "textBox_AccessFlags"; + this.textBox_AccessFlags.ReadOnly = true; + this.textBox_AccessFlags.Size = new System.Drawing.Size(242, 20); + this.textBox_AccessFlags.TabIndex = 73; + this.textBox_AccessFlags.Text = "0"; + // + // textBox_RegistryCallbackClass + // + this.textBox_RegistryCallbackClass.Location = new System.Drawing.Point(203, 316); + this.textBox_RegistryCallbackClass.Name = "textBox_RegistryCallbackClass"; + this.textBox_RegistryCallbackClass.ReadOnly = true; + this.textBox_RegistryCallbackClass.Size = new System.Drawing.Size(242, 20); + this.textBox_RegistryCallbackClass.TabIndex = 87; + this.textBox_RegistryCallbackClass.Text = "0"; + // + // button_SelectProcessId + // + this.button_SelectProcessId.Location = new System.Drawing.Point(466, 103); + this.button_SelectProcessId.Name = "button_SelectProcessId"; + this.button_SelectProcessId.Size = new System.Drawing.Size(41, 20); + this.button_SelectProcessId.TabIndex = 14; + this.button_SelectProcessId.Text = "..."; + this.button_SelectProcessId.UseVisualStyleBackColor = true; + this.button_SelectProcessId.Click += new System.EventHandler(this.button_SelectProcessId_Click); + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(6, 321); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(159, 13); + this.label1.TabIndex = 86; + this.label1.Text = "Register Registry Callback Class"; + // + // textBox_ProcessId + // + this.textBox_ProcessId.Location = new System.Drawing.Point(203, 103); + this.textBox_ProcessId.Name = "textBox_ProcessId"; + this.textBox_ProcessId.Size = new System.Drawing.Size(242, 20); + this.textBox_ProcessId.TabIndex = 11; + this.textBox_ProcessId.Text = "0"; + // + // label17 + // + this.label17.AutoSize = true; + this.label17.Location = new System.Drawing.Point(6, 285); + this.label17.Name = "label17"; + this.label17.Size = new System.Drawing.Size(147, 13); + this.label17.TabIndex = 72; + this.label17.Text = "Registry Access Control Flags"; + // + // button_SelectRegistryAccessFlags + // + this.button_SelectRegistryAccessFlags.Location = new System.Drawing.Point(465, 280); + this.button_SelectRegistryAccessFlags.Name = "button_SelectRegistryAccessFlags"; + this.button_SelectRegistryAccessFlags.Size = new System.Drawing.Size(41, 20); + this.button_SelectRegistryAccessFlags.TabIndex = 74; + this.button_SelectRegistryAccessFlags.Text = "..."; + this.button_SelectRegistryAccessFlags.UseVisualStyleBackColor = true; + this.button_SelectRegistryAccessFlags.Click += new System.EventHandler(this.button_SelectRegistryAccessFlags_Click); + // + // textBox_ProcessName + // + this.textBox_ProcessName.Location = new System.Drawing.Point(203, 145); + this.textBox_ProcessName.Name = "textBox_ProcessName"; + this.textBox_ProcessName.Size = new System.Drawing.Size(242, 20); + this.textBox_ProcessName.TabIndex = 77; + this.textBox_ProcessName.Text = "*"; + // + // textBox_ExcludeKeyNames + // + this.textBox_ExcludeKeyNames.Location = new System.Drawing.Point(203, 65); + this.textBox_ExcludeKeyNames.Name = "textBox_ExcludeKeyNames"; + this.textBox_ExcludeKeyNames.Size = new System.Drawing.Size(242, 20); + this.textBox_ExcludeKeyNames.TabIndex = 136; + // + // label6 + // + this.label6.AutoSize = true; + this.label6.Location = new System.Drawing.Point(6, 65); + this.label6.Name = "label6"; + this.label6.Size = new System.Drawing.Size(99, 13); + this.label6.TabIndex = 135; + this.label6.Text = "Exclude key names"; + // + // RegistryAccessControlForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(546, 541); + this.Controls.Add(this.groupBox_AccessControl); + this.Name = "RegistryAccessControlForm"; + this.Text = "Registry Access Control Settings"; + this.groupBox_AccessControl.ResumeLayout(false); + this.groupBox1.ResumeLayout(false); + this.groupBox2.ResumeLayout(false); + this.groupBox2.PerformLayout(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.GroupBox groupBox_AccessControl; + private System.Windows.Forms.TextBox textBox_ProcessName; + private System.Windows.Forms.GroupBox groupBox2; + private System.Windows.Forms.Button button_SelectRegistryAccessFlags; + private System.Windows.Forms.TextBox textBox_AccessFlags; + private System.Windows.Forms.Label label17; + private System.Windows.Forms.TextBox textBox_ProcessId; + private System.Windows.Forms.Button button_SelectProcessId; + private System.Windows.Forms.Button button_SelectRegistryCallbackClass; + private System.Windows.Forms.TextBox textBox_RegistryCallbackClass; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Button button_DeleteFilter; + private System.Windows.Forms.Button button_AddFilter; + private System.Windows.Forms.GroupBox groupBox1; + private System.Windows.Forms.ListView listView_FilterRules; + private System.Windows.Forms.CheckBox checkBox_isExcludeFilter; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.Button button_Apply; + private System.Windows.Forms.Button button_Info; + private System.Windows.Forms.Label label4; + private System.Windows.Forms.RadioButton radioButton_Name; + private System.Windows.Forms.RadioButton radioButton_Pid; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.Label label5; + private System.Windows.Forms.TextBox textBox_RegistryKeyNameFilterMask; + private System.Windows.Forms.Label label20; + private System.Windows.Forms.Label label13; + private System.Windows.Forms.TextBox textBox_ExcludeUserNames; + private System.Windows.Forms.Label label14; + private System.Windows.Forms.TextBox textBox_ExcludeProcessNames; + private System.Windows.Forms.Label label11; + private System.Windows.Forms.TextBox textBox_ExcludeKeyNames; + private System.Windows.Forms.Label label6; + } +} \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/RegMon/RegistryAccessControlForm.cs b/Demo_Source_Code/CSharpDemo/RegMon/RegistryAccessControlForm.cs new file mode 100644 index 0000000..066febe --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/RegMon/RegistryAccessControlForm.cs @@ -0,0 +1,259 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.IO; +using System.Windows.Forms; + +using EaseFilter.FilterControl; + +namespace EaseFilter.CommonObjects +{ + public partial class RegistryAccessControlForm : Form + { + RegistryFilterRule selectedFilterRule = null; + + public RegistryAccessControlForm() + { + InitializeComponent(); + + InitListView(); + + } + + public void InitListView() + { + //init ListView control + listView_FilterRules.Clear(); //clear control + //create column header for ListView + listView_FilterRules.Columns.Add("#", 20, System.Windows.Forms.HorizontalAlignment.Left); + listView_FilterRules.Columns.Add("ProcessId", 50, System.Windows.Forms.HorizontalAlignment.Left); + listView_FilterRules.Columns.Add("ProcessName", 100, System.Windows.Forms.HorizontalAlignment.Left); + listView_FilterRules.Columns.Add("KeyNameMask", 100, System.Windows.Forms.HorizontalAlignment.Left); + listView_FilterRules.Columns.Add("AccessFlags", 100, System.Windows.Forms.HorizontalAlignment.Left); + listView_FilterRules.Columns.Add("CallbackClass", 100, System.Windows.Forms.HorizontalAlignment.Left); + + foreach (RegistryFilterRule rule in GlobalConfig.RegistryFilterRules.Values) + { + AddItem(rule); + selectedFilterRule = rule; + } + + InitSelectedFilterRule(); + } + + void InitSelectedFilterRule() + { + if (null == selectedFilterRule) + { + selectedFilterRule = new RegistryFilterRule(); + + selectedFilterRule.AccessFlag = FilterAPI.MAX_REGITRY_ACCESS_FLAG; + selectedFilterRule.RegCallbackClass = 93092006832128; //by default only register post callback class + selectedFilterRule.ProcessNameFilterMask = "*"; + selectedFilterRule.RegistryKeyNameFilterMask = "*"; + } + + if (selectedFilterRule.ProcessId.Length > 0 && selectedFilterRule.ProcessId != "0") + { + textBox_ProcessId.Text = selectedFilterRule.ProcessId; + radioButton_Pid_Click(null, null); + } + else + { + radioButton_Name_Click(null, null); + textBox_ProcessName.Text = selectedFilterRule.ProcessNameFilterMask; + } + + textBox_RegistryKeyNameFilterMask.Text = selectedFilterRule.RegistryKeyNameFilterMask; + + textBox_ExcludeProcessNames.Text = selectedFilterRule.ExcludeProcessNames; + textBox_ExcludeUserNames.Text = selectedFilterRule.ExcludeUserNames; + textBox_ExcludeKeyNames.Text = selectedFilterRule.ExcludeKeyNames; + + textBox_AccessFlags.Text = selectedFilterRule.AccessFlag.ToString(); + textBox_RegistryCallbackClass.Text = selectedFilterRule.RegCallbackClass.ToString(); + checkBox_isExcludeFilter.Checked = selectedFilterRule.IsExcludeFilter; + } + + private void AddItem(RegistryFilterRule newRule) + { + string[] itemStr = new string[listView_FilterRules.Columns.Count]; + itemStr[0] = listView_FilterRules.Items.Count.ToString(); + itemStr[1] = newRule.ProcessId; + itemStr[2] = newRule.ProcessNameFilterMask; + itemStr[3] = newRule.RegistryKeyNameFilterMask; + itemStr[4] = newRule.AccessFlag.ToString(); + itemStr[5] = newRule.RegCallbackClass.ToString(); + ListViewItem item = new ListViewItem(itemStr, 0); + item.Tag = newRule; + listView_FilterRules.Items.Add(item); + } + + + private void button_AddFilter_Click(object sender, EventArgs e) + { + try + { + selectedFilterRule = new RegistryFilterRule(); + + if (textBox_ProcessId.Text.Trim().Length > 0 && textBox_ProcessId.Text != "0") + { + //please note that the process Id will be changed when the process launch every time. + selectedFilterRule.ProcessId = textBox_ProcessId.Text; + selectedFilterRule.ProcessNameFilterMask = ""; + } + else if (textBox_ProcessName.Text.Trim().Length > 0) + { + selectedFilterRule.ProcessId = ""; + selectedFilterRule.ProcessNameFilterMask = textBox_ProcessName.Text; + } + else + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("The process name mask and Pid can't be null.", "Add Filter Rule", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + selectedFilterRule.RegistryKeyNameFilterMask = textBox_RegistryKeyNameFilterMask.Text; + + selectedFilterRule.ExcludeProcessNames = textBox_ExcludeProcessNames.Text; + selectedFilterRule.ExcludeUserNames = textBox_ExcludeUserNames.Text; + selectedFilterRule.ExcludeKeyNames = textBox_ExcludeKeyNames.Text; + + //this is the key of the filter rule for registry filter rule + selectedFilterRule.IsExcludeFilter = checkBox_isExcludeFilter.Checked; + selectedFilterRule.AccessFlag = uint.Parse(textBox_AccessFlags.Text); + selectedFilterRule.RegCallbackClass = ulong.Parse(textBox_RegistryCallbackClass.Text); + + GlobalConfig.AddRegistryFilterRule(selectedFilterRule); + + InitListView(); + + } + catch (Exception ex) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("Add registry filter rule failed." + ex.Message, "Add Filter Rule", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + } + + private void button_DeleteFilter_Click(object sender, EventArgs e) + { + if (listView_FilterRules.SelectedItems.Count == 0) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("There are no filter rule selected.", "Delete Filter Rule", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + foreach (System.Windows.Forms.ListViewItem item in listView_FilterRules.SelectedItems) + { + RegistryFilterRule filterRule = (RegistryFilterRule)item.Tag; + GlobalConfig.RemoveRegistryFilterRule(filterRule); + } + + InitListView(); + } + + private void button_SelectProcessId_Click(object sender, EventArgs e) + { + OptionForm optionForm = new OptionForm(OptionForm.OptionType.ProccessId, textBox_ProcessId.Text); + + if (optionForm.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + textBox_ProcessId.Text = optionForm.ProcessId.ToString(); + } + } + + private void button_SelectRegistryAccessFlags_Click(object sender, EventArgs e) + { + OptionForm optionForm = new OptionForm(OptionForm.OptionType.RegistryAccessFlag, textBox_AccessFlags.Text); + + if (optionForm.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + textBox_AccessFlags.Text = optionForm.RegAccessFlags.ToString(); + } + } + + private void button_SelectRegistryCallbackClass_Click(object sender, EventArgs e) + { + OptionForm optionForm = new OptionForm(OptionForm.OptionType.RegistryCallbackClass, textBox_RegistryCallbackClass.Text); + + if (optionForm.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + textBox_RegistryCallbackClass.Text = optionForm.RegCallbackClass.ToString(); + } + } + + private void button_Apply_Click(object sender, EventArgs e) + { + GlobalConfig.SaveConfigSetting(); + } + + private void button_Info_Click(object sender, EventArgs e) + { + string information = "Filter by process Id: Filter the registry access by process Id, skip the process Id check if it is 0.\r\n\r\n"; + information += "Filter by process name: Filter the registry access by process name filter mask, use '*' to include all processes, use ';' to seperate multiple process names.\r\n\r\n"; + information += "Filter by user name: Filter the registry access by user name with format 'domain name\\user name', use '*' to include all users.\r\n\r\n"; + information += "Filter by registry key name: Filter the registry access by the registry key name filter mask, use '*' to include all keys.\r\n\r\n"; + information += "Registry access control: Set the registry access control flags to allow or deny the registry access.\r\n\r\n"; + information += "Registry callback setting: Set the registry access notification callback class, monitor the registry access by registering post-notification class, control the registry access by registering pre-notification class in user mode service.\r\n\r\n"; + information += "Exclude the registry filter rule: Skip the registry access for this filter rule if it is enabled.\r\n\r\n"; + + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show(information, "Registry Filter Setting", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + + private void listView_FilterRules_SelectedIndexChanged(object sender, EventArgs e) + { + if (listView_FilterRules.SelectedItems.Count > 0) + { + selectedFilterRule = (RegistryFilterRule)listView_FilterRules.SelectedItems[0].Tag; + InitSelectedFilterRule(); + } + } + + + private void radioButton_Pid_Click(object sender, EventArgs e) + { + radioButton_Pid.Checked = true; + textBox_ProcessName.ReadOnly = true; + textBox_ProcessId.ReadOnly = false; + button_SelectProcessId.Enabled = true; + } + + private void radioButton_Name_Click(object sender, EventArgs e) + { + radioButton_Name.Checked = true; + textBox_ProcessName.ReadOnly = false; + textBox_ProcessId.ReadOnly = true; + textBox_ProcessId.Text = "0"; + button_SelectProcessId.Enabled = false; + } + + + } +} diff --git a/Demo_Source_Code/CSharpDemo/RegMon/RegistryAccessControlForm.resx b/Demo_Source_Code/CSharpDemo/RegMon/RegistryAccessControlForm.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/RegMon/RegistryAccessControlForm.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/RegMon/RegistryHandler.cs b/Demo_Source_Code/CSharpDemo/RegMon/RegistryHandler.cs new file mode 100644 index 0000000..9390195 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/RegMon/RegistryHandler.cs @@ -0,0 +1,1063 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.IO; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Drawing; +using System.Windows.Forms; +using System.Runtime.InteropServices; +using Microsoft.Win32.SafeHandles; +using System.Security.Principal; +using System.Threading; + +using EaseFilter.FilterControl; +using EaseFilter.CommonObjects; + +namespace RegMon +{ + public enum VALUE_DATA_TYPE : uint + { + REG_NONE = 0, + REG_SZ = 1, + REG_EXPAND_SZ = 2, + REG_BINARY = 3, + REG_DWORD = 4, + REG_DWORD_BIG_ENDIAN = 5, + REG_LINK = 6, + REG_MULTI_SZ = 7, + REG_RESOURCE_LIST = 8, + REG_FULL_RESOURCE_DESCRIPTOR = 9, + REG_RESOURCE_REQUIREMENTS_LIST = 10, + REG_QWORD = 11 + } + + public enum KEY_VALUE_INFORMATION_CLASS : uint + { + KeyValueBasicInformation = 0, + KeyValueFullInformation = 1, + KeyValuePartialInformation = 2, + KeyValueFullInformationAlign64 = 3, + KeyValuePartialInformationAlign64 = 4, + MaxKeyValueInfoClass = 5 + } + + public struct KEY_VALUE_BASIC_INFORMATION + { + public uint TitleIndex; + public uint Type; + public uint NameLength; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 65536 - 12)] + public byte[] Name; + } + public struct KEY_VALUE_FULL_INFORMATION + { + public uint TitleIndex; + public uint Type; + public uint DataOffset; + public uint DataLength; + public uint NameLength; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 65536 - 20)] + public byte[] Name; + } + + public struct KEY_VALUE_PARTIAL_INFORMATION + { + public uint TitleIndex; + public uint Type; + public uint DataLength; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 65536 - 12 )] + public byte[] Data; + } + + public struct KEY_VALUE_ENTRY + { + public uint NextEntryOffset; + public uint ValueNameLength; + public uint DataType; + public uint DataLength; + public byte[] ValueName; + //public byte[] Data; + } + + public enum KEY_SET_INFORMATION_CLASS : uint + { + KeyWriteTimeInformation = 0, + KeyWow64FlagsInformation, + KeyControlFlagsInformation, + KeySetVirtualizationInformation, + KeySetDebugInformation, + KeySetHandleTagsInformation, + MaxKeySetInfoClass // MaxKeySetInfoClass should always be the last enum + } + public enum KEY_INFORMATION_CLASS : uint + { + KeyBasicInformation = 0, + KeyNodeInformation, + KeyFullInformation, + KeyNameInformation, + KeyCachedInformation, + KeyFlagsInformation, + KeyVirtualizationInformation, + KeyHandleTagsInformation, + KeyTrustInformation, + KeyLayerInformation, + MaxKeyInfoClass + } + + public struct KEY_BASIC_INFORMATION + { + public long LastWriteTime; + public uint TitleIndex; + public uint NameLength; + public byte[] Name; + } + + public struct KEY_NODE_INFORMATION + { + public long LastWriteTime; + public uint TitleIndex; + public uint ClassOffset; + public uint ClassLength; + public uint NameLength; + public byte[] Name; + } + + public struct KEY_FULL_INFORMATION + { + public long LastWriteTime; + public uint TitleIndex; + public uint ClassOffset; + public uint ClassLength; + public uint SubKeys; + public uint MaxNameLen; + public uint MaxClassLen; + public uint Values; + public uint MaxValueNameLen; + public uint MaxValueDataLen; + public byte[] Class; + } + + public struct KEY_NAME_INFORMATION + { + public uint NameLength; + public byte[] Name; + } + + public struct KEY_CACHED_INFORMATION + { + public long LastWriteTime; + public uint TitleIndex; + public uint SubKeys; + public uint MaxNameLen; + public uint MaxClassLen; + public uint Values; + public uint MaxValueNameLen; + public uint MaxValueDataLen; + public uint NameLength; + } + + public struct KEY_VIRTUALIZATION_INFORMATION + { + public bool VirtualizationCandidate; + public bool VirtualizationEnabled; + public bool VirtualTarget; + public bool VirtualStore; + public bool VirtualSource; + } + + public enum REG_ACCESS_MASK : uint + { + KEY_QUERY_VALUE = 1, + KEY_SET_VALUE = 2, + KEY_CREATE_SUB_KEY = 4, + KEY_ENUMERATE_SUB_KEYS = 8, + KEY_NOTIFY = 16, + KEY_CREATE_LINK = 32, + KEY_WRITE = 131078, + KEY_EXECUTE = 131097, + KEY_READ = 131097, + KEY_ALL_ACCESS = 983103, + } + + public enum REG_CREATE_OPTIONS : uint + { + REG_OPTION_VOLATILE = 0x00000001, // Key is not preserved when system is rebooted + REG_OPTION_CREATE_LINK = 0x00000002, // Created key is a symbolic link + REG_OPTION_BACKUP_RESTORE = 0x00000004, // open for backup or restore special access rules privilege required + REG_OPTION_OPEN_LINK = 0x00000008, // Open symbolic link + } + + public enum REG_DISPOSITION + { + REG_CREATED_NEW_KEY = 0x00000001, // New Registry Key created + REG_OPENED_EXISTING_KEY =0x00000002, // Existing Key opened + } + + public class RegistryHandler + { + ListView listView_Info = null; + Thread messageThread = null; + Queue messageQueue = new Queue(); + + AutoResetEvent autoEvent = new AutoResetEvent(false); + bool disposed = false; + + + public void InitListView() + { + listView_Info.Clear(); //clear control + //create column header for ListView + listView_Info.Columns.Add("#", 40, System.Windows.Forms.HorizontalAlignment.Left); + listView_Info.Columns.Add("Time", 100, System.Windows.Forms.HorizontalAlignment.Left); + listView_Info.Columns.Add("UserName", 150, System.Windows.Forms.HorizontalAlignment.Left); + listView_Info.Columns.Add("ProcessName(PID)", 100, System.Windows.Forms.HorizontalAlignment.Left); + listView_Info.Columns.Add("ThreadId", 60, System.Windows.Forms.HorizontalAlignment.Left); + listView_Info.Columns.Add("RegCallbackClassName", 160, System.Windows.Forms.HorizontalAlignment.Left); + listView_Info.Columns.Add("KeyName", 300, System.Windows.Forms.HorizontalAlignment.Left); + listView_Info.Columns.Add("Return Status", 100, System.Windows.Forms.HorizontalAlignment.Left); + listView_Info.Columns.Add("Description", 400, System.Windows.Forms.HorizontalAlignment.Left); + } + + public RegistryHandler(ListView lvMessage) + { + this.listView_Info = lvMessage; + InitListView(); + + messageThread = new Thread(new ThreadStart(ProcessMessage)); + messageThread.Name = "ProcessMessage"; + messageThread.Start(); + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + private void Dispose(bool disposing) + { + if (!this.disposed) + { + } + + autoEvent.Set(); + messageThread.Abort(); + disposed = true; + } + + ~RegistryHandler() + { + Dispose(false); + } + + public void DisplayEventMessage(RegistryEventArgs registryEventArgs) + { + if (GlobalConfig.OutputMessageToConsole) + { + lock (messageQueue) + { + if (messageQueue.Count > GlobalConfig.MaximumFilterMessages) + { + messageQueue.Clear(); + } + + messageQueue.Enqueue(registryEventArgs); + } + + autoEvent.Set(); + } + + } + + void ProcessMessage() + { + int waitTimeout = 2000; //2seconds + List itemList = new List(); + + WaitHandle[] waitHandles = new WaitHandle[] { autoEvent, GlobalConfig.stopEvent }; + + while (GlobalConfig.isRunning) + { + if (messageQueue.Count == 0) + { + int result = WaitHandle.WaitAny(waitHandles, waitTimeout); + if (!GlobalConfig.isRunning) + { + return; + } + } + + System.Diagnostics.Stopwatch stopWatch = new System.Diagnostics.Stopwatch(); + stopWatch.Start(); + + while (messageQueue.Count > 0) + { + RegistryEventArgs registryEventMessage; + + lock (messageQueue) + { + registryEventMessage = (RegistryEventArgs)messageQueue.Dequeue(); + } + + ListViewItem lvItem = FormatRegistryMessage(registryEventMessage); + itemList.Add(lvItem); + + if (itemList.Count > GlobalConfig.MaximumFilterMessages) + { + AddItemToList(itemList); + itemList.Clear(); + + Thread.Sleep(1000); + } + } + + if (itemList.Count > 0) + { + AddItemToList(itemList); + itemList.Clear(); + } + } + + } + + void AddItemToList(List itemList) + { + if (itemList.Count < 1) + { + return; + } + + if (listView_Info.InvokeRequired) + { + listView_Info.Invoke(new MethodInvoker(delegate { AddItemToList(itemList); })); + } + else + { + + while (listView_Info.Items.Count > 0 && listView_Info.Items.Count + itemList.Count > GlobalConfig.MaximumFilterMessages) + { + //the message records in the list view reached to the maximum value, remove the first one till the record less than the maximum value. + listView_Info.Items.Clear(); + } + + + if (itemList.Count > 0) + { + listView_Info.Items.AddRange(itemList.ToArray()); + // listView_Message.EnsureVisible(listView_Message.Items.Count - 1); + + itemList.Clear(); + + } + } + } + + + public string FormatDateTime(long lDateTime) + { + try + { + if (0 == lDateTime) + { + return "0"; + } + + DateTime dateTime = DateTime.FromFileTime(lDateTime); + string ret = dateTime.ToString("yyyy-MM-ddTHH:mm"); + return ret; + } + catch (Exception ex) + { + EventManager.WriteMessage(502, "FormatDateTime", EventLevel.Error, "FormatDateTime :" + lDateTime.ToString() + " failed." + ex.Message); + return ex.Message; + } + } + + + private void AddItemToList(ListViewItem lvItem) + { + if (listView_Info.InvokeRequired) + { + listView_Info.Invoke(new MethodInvoker(delegate { AddItemToList(lvItem); })); + } + else + { + + while (listView_Info.Items.Count > GlobalConfig.MaximumFilterMessages) + { + listView_Info.Items.RemoveAt(0); + } + + listView_Info.Items.Add(lvItem); + + } + } + + string GetRegCallbackClassName(FilterAPI.MessageSendData messageSend) + { + if (messageSend.MessageType == (uint)FilterAPI.FilterCommand.FILTER_SEND_REG_CALLBACK_INFO) + { + return ((FilterAPI.RegCallbackClass)messageSend.Offset).ToString(); + } + else + { + return ""; + } + } + + public ListViewItem FormatRegistryMessage(RegistryEventArgs registryEventArgs) + { + ListViewItem lvItem = new ListViewItem(); + + try + { + + string[] listData = new string[listView_Info.Columns.Count]; + int col = 0; + listData[col++] = registryEventArgs.MessageId.ToString(); + listData[col++] = FormatDateTime(registryEventArgs.TransactionTime); + listData[col++] = registryEventArgs.UserName; + listData[col++] = registryEventArgs.ProcessName + " (" + registryEventArgs.ProcessId + ")"; + listData[col++] = registryEventArgs.ThreadId.ToString(); + listData[col++] = registryEventArgs.EventName; + listData[col++] = registryEventArgs.FileName; + listData[col++] = registryEventArgs.IOStatusToString(); + listData[col++] = registryEventArgs.Description; + + lvItem = new ListViewItem(listData, 0); + + if (registryEventArgs.IoStatus >= NtStatus.Status.Error) + { + lvItem.BackColor = Color.LightGray; + lvItem.ForeColor = Color.Red; + } + else if (registryEventArgs.IoStatus > NtStatus.Status.Warning) + { + lvItem.BackColor = Color.LightGray; + lvItem.ForeColor = Color.Yellow; + } + + + + } + catch (Exception ex) + { + EventManager.WriteMessage(445, "GetFilterMessage", EventLevel.Error, "Add callback message failed." + ex.Message); + lvItem = null; + } + + return lvItem; + + } + + /// + /// Fires this event when the registry access was blocked by the setting, + /// if the control flag "ENABLE_FILTER_SEND_DENIED_REG_EVENT" was enabled. + /// + public void NotifyRegWasBlocked(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + + /// + /// Fires this event when the register registry event was triggered. + /// + public void OnPreQueryValueKey(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + // //test block the registry event. + // e.ReturnStatus = NtStatus.Status.AccessDenied; + + KEY_VALUE_INFORMATION_CLASS keyValuseInformationClass = (KEY_VALUE_INFORMATION_CLASS)e.InfoClass; + + //test to replace the query value with your own data. + if (e.FileName.IndexOf("EaseFilter") > 0) + { + + //below code is to demo how to complete pre-callback registry call with our own data. + switch (keyValuseInformationClass) + { + case KEY_VALUE_INFORMATION_CLASS.KeyValueBasicInformation: + { + //public struct KEY_VALUE_BASIC_INFORMATION + // { + // public uint TitleIndex; + // public uint Type; + // public uint NameLength; + // public byte[] Name; + // } + + uint titleIndex = 0; + uint type = (uint)VALUE_DATA_TYPE.REG_DWORD; + byte[] valueName = Encoding.Unicode.GetBytes("value1"); + uint valueNameLength = (uint)valueName.Length; + + MemoryStream ms = new MemoryStream(); + BinaryWriter bw = new BinaryWriter(ms); + bw.Write(titleIndex); + bw.Write(type); + bw.Write(valueNameLength); + bw.Write(valueName); + + e.ReturnDataBuffer = ms.ToArray(); + e.IsDataModified = true; + + break; + } + case KEY_VALUE_INFORMATION_CLASS.KeyValueFullInformation: + { + //KeyValueFullInformation class structure + //public uint TitleIndex; + //public uint Type; + //public uint DataOffset; + //public uint DataLength; + //public uint NameLength; + //public byte[] Name; + + uint titleIndex = 0; + uint type = (uint)VALUE_DATA_TYPE.REG_DWORD; + uint testData = 12345; + uint testDataLength = sizeof(uint); + byte[] valueName = Encoding.Unicode.GetBytes("value1"); + uint valueNameLength = (uint)valueName.Length; + uint dataOffset = 5 * sizeof(uint) + valueNameLength; + + MemoryStream ms = new MemoryStream(); + BinaryWriter bw = new BinaryWriter(ms); + bw.Write(titleIndex); + bw.Write(type); + bw.Write(dataOffset); + bw.Write(testDataLength); + bw.Write(valueNameLength); + bw.Write(valueName); + bw.Write(testData); + + e.ReturnDataBuffer = ms.ToArray(); + e.IsDataModified = true; + + break; + } + case KEY_VALUE_INFORMATION_CLASS.KeyValuePartialInformation: + { + // public struct KEY_VALUE_PARTIAL_INFORMATION + //{ + // public uint TitleIndex; + // public uint Type; + // public uint DataLength; + // public byte[] Data; + //} + + uint titleIndex = 0; + uint type = (uint)VALUE_DATA_TYPE.REG_DWORD; + uint testData = 12345; + uint testDataLength = sizeof(uint); + + MemoryStream ms = new MemoryStream(); + BinaryWriter bw = new BinaryWriter(ms); + + bw.Write(titleIndex); + bw.Write(type); + bw.Write(testDataLength); + bw.Write(testData); + + e.ReturnDataBuffer = ms.ToArray(); + e.IsDataModified = true; + + break; + } + + + default: break; + } + } + + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void OnPreDeleteKey(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + // //test block the registry event. + // e.ReturnStatus = NtStatus.Status.AccessDenied; + } + + /// + /// Fires this event when the register registry event was triggered. + /// + public void OnPreSetValueKey(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + // //test block the registry event. + // e.ReturnStatus = NtStatus.Status.AccessDenied; + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void OnPreDeleteValueKey(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + // //test block the registry event. + // e.ReturnStatus = NtStatus.Status.AccessDenied; + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void OnPreSetInformationKey(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + // //test block the registry event. + // e.ReturnStatus = NtStatus.Status.AccessDenied; + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void OnPreRenameKey(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + // //test block the registry event. + // e.ReturnStatus = NtStatus.Status.AccessDenied; + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void OnPreEnumerateKey(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + // //test block the registry event. + // e.ReturnStatus = NtStatus.Status.AccessDenied; + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void OnPreEnumerateValueKey(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + // //test block the registry event. + // e.ReturnStatus = NtStatus.Status.AccessDenied; + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void OnPreQueryKey(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + // //test block the registry event. + // e.ReturnStatus = NtStatus.Status.AccessDenied; + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void OnPreQueryMultipleValueKey(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + // //test block the registry event. + // e.ReturnStatus = NtStatus.Status.AccessDenied; + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void OnPreCreateKey(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + // //test block the registry event. + // e.ReturnStatus = NtStatus.Status.AccessDenied; + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void OnPreOpenKey(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + // //test block the registry event. + // e.ReturnStatus = NtStatus.Status.AccessDenied; + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void OnPreKeyHandleClose(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + // //test block the registry event. + // e.ReturnStatus = NtStatus.Status.AccessDenied; + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void OnPreCreateKeyEx(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + // //test block the registry event. + // e.ReturnStatus = NtStatus.Status.AccessDenied; + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void OnPreOpenKeyEx(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + // //test block the registry event. + // e.ReturnStatus = NtStatus.Status.AccessDenied; + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void OnPreFlushKey(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + // //test block the registry event. + // e.ReturnStatus = NtStatus.Status.AccessDenied; + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void OnPreLoadKey(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + // //test block the registry event. + // e.ReturnStatus = NtStatus.Status.AccessDenied; + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void OnPreUnLoadKey(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + // //test block the registry event. + // e.ReturnStatus = NtStatus.Status.AccessDenied; + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void OnPreQueryKeySecurity(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + // //test block the registry event. + // e.ReturnStatus = NtStatus.Status.AccessDenied; + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void OnPreSetKeySecurity(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + // //test block the registry event. + // e.ReturnStatus = NtStatus.Status.AccessDenied; + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void OnPreRestoreKey(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + // //test block the registry event. + // e.ReturnStatus = NtStatus.Status.AccessDenied; + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void OnPreSaveKey(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + // //test block the registry event. + // e.ReturnStatus = NtStatus.Status.AccessDenied; + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void OnPreReplaceKey(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + // //test block the registry event. + // e.ReturnStatus = NtStatus.Status.AccessDenied; + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void OnPreQueryKeyName(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + // //test block the registry event. + // e.ReturnStatus = NtStatus.Status.AccessDenied; + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void NotifyDeleteKey(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void NotifySetValueKey(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void NotifyDeleteValueKey(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void NotifySetInformationKey(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void NotifyRenameKey(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void NotifyEnumerateKey(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void NotifyEnumerateValueKey(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void NotifyQueryKey(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void NotifyQueryValueKey(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void NotifyQueryMultipleValueKey(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void NotifyCreateKey(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void NotifyOpenKey(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void NotifyKeyHandleClose(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void NotifyCreateKeyEx(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void NotifyOpenKeyEx(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void NotifyFlushKey(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void NotifyLoadKey(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void NotifyUnLoadKey(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void NotifyQueryKeySecurity(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void NotifySetKeySecurity(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void NotifyRestoreKey(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void NotifySaveKey(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void NotifyReplaceKey(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + } + /// + /// Fires this event when the register registry event was triggered. + /// + public void NotifyQueryKeyName(object sender, RegistryEventArgs e) + { + DisplayEventMessage(e); + //do your job here. + + } + + } +} diff --git a/Demo_Source_Code/CSharpDemo/RegMon/RegistryMessage.cs b/Demo_Source_Code/CSharpDemo/RegMon/RegistryMessage.cs new file mode 100644 index 0000000..e37a53e --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/RegMon/RegistryMessage.cs @@ -0,0 +1,326 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.IO; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Drawing; +using System.Windows.Forms; +using System.Runtime.InteropServices; +using Microsoft.Win32.SafeHandles; +using System.Security.Principal; +using System.Threading; +using System.Reflection; + +using EaseFilter.CommonObjects; + +namespace RegMon +{ + + public class RegistryMessage : IDisposable + { + + ListView listView_Message = null; + Thread messageThread = null; + Queue messageQueue = new Queue(); + + AutoResetEvent autoEvent = new AutoResetEvent(false); + bool disposed = false; + + + public RegistryMessage(ListView lvMessage) + { + this.listView_Message = lvMessage; + messageThread = new Thread(new ThreadStart(ProcessMessage)); + messageThread.Name = "ProcessMessage"; + messageThread.Start(); + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + private void Dispose(bool disposing) + { + if (!this.disposed) + { + } + + autoEvent.Set(); + messageThread.Abort(); + disposed = true; + } + + ~RegistryMessage() + { + Dispose(false); + } + + public void AddMessage(FilterAPI.MessageSendData messageSend) + { + lock (messageQueue) + { + if (messageQueue.Count > GlobalConfig.MaximumFilterMessages) + { + messageQueue.Clear(); + } + + messageQueue.Enqueue(messageSend); + } + + autoEvent.Set(); + + } + + + void ProcessMessage() + { + int waitTimeout = 2000; //2seconds + List itemList = new List(); + + WaitHandle[] waitHandles = new WaitHandle[] { autoEvent, GlobalConfig.stopEvent }; + + while (GlobalConfig.isRunning) + { + if (messageQueue.Count == 0) + { + int result = WaitHandle.WaitAny(waitHandles, waitTimeout); + if (!GlobalConfig.isRunning) + { + return; + } + } + + System.Diagnostics.Stopwatch stopWatch = new System.Diagnostics.Stopwatch(); + stopWatch.Start(); + + while (messageQueue.Count > 0) + { + FilterAPI.MessageSendData messageSend; + + lock (messageQueue) + { + messageSend = (FilterAPI.MessageSendData)messageQueue.Dequeue(); + } + + string[] filterMessages = new string[0]; + ListViewItem lvItem = FormatRegistryMessage(messageSend); + itemList.Add(lvItem); + + if (itemList.Count > GlobalConfig.MaximumFilterMessages) + { + AddItemToList(itemList); + itemList.Clear(); + + Thread.Sleep(1000); + } + } + + } + + if (itemList.Count > 0) + { + AddItemToList(itemList); + itemList.Clear(); + } + + + } + + void AddItemToList(List itemList) + { + if (itemList.Count < 1) + { + return; + } + + if (listView_Message.InvokeRequired) + { + listView_Message.Invoke(new MethodInvoker(delegate { AddItemToList(itemList); })); + } + else + { + + while (listView_Message.Items.Count > 0 && listView_Message.Items.Count + itemList.Count > GlobalConfig.MaximumFilterMessages) + { + //the message records in the list view reached to the maximum value, remove the first one till the record less than the maximum value. + listView_Message.Items.Clear(); + } + + + if (itemList.Count > 0) + { + listView_Message.Items.AddRange(itemList.ToArray()); + // listView_Message.EnsureVisible(listView_Message.Items.Count - 1); + + itemList.Clear(); + + } + } + } + + + public string FormatDateTime(long lDateTime) + { + try + { + if (0 == lDateTime) + { + return "0"; + } + + DateTime dateTime = DateTime.FromFileTime(lDateTime); + string ret = dateTime.ToString("yyyy-MM-ddTHH:mm"); + return ret; + } + catch (Exception ex) + { + EventManager.WriteMessage(502, "FormatDateTime", EventLevel.Error, "FormatDateTime :" + lDateTime.ToString() + " failed." + ex.Message); + return ex.Message; + } + } + + private string FormatDescription(FilterAPI.PROCESS_INFO processInfo) + { + string message = string.Empty; + + switch (processInfo.MessageType) + { + case (uint)FilterAPI.FilterCommand.FILTER_SEND_PROCESS_CREATION_INFO: + { + message = "ParentPid:" + processInfo.ParentProcessId + ";CreatingPid:" + processInfo.CreatingProcessId + ";CreatingTheadId:" + processInfo.CreatingThreadId + + ";FileOpenNameAvailable:" + processInfo.FileOpenNameAvailable + ";CommandLine:" + processInfo.CommandLine; + break; + } + case (uint)FilterAPI.FilterCommand.FILTER_SEND_PROCESS_HANDLE_INFO: + case (uint)FilterAPI.FilterCommand.FILTER_SEND_THREAD_HANDLE_INFO: + { + if (processInfo.Operation == 1) + { + message = "Create Handle"; + } + else + { + message = "Duplicate Handle"; + } + + message += "; DesiredAccess:" + processInfo.DesiredAccess.ToString("X"); + break; + } + + default: + break; + } + + return message; + } + + private void AddItemToList(ListViewItem lvItem) + { + if (listView_Message.InvokeRequired) + { + listView_Message.Invoke(new MethodInvoker(delegate { AddItemToList(lvItem); })); + } + else + { + + while (listView_Message.Items.Count > GlobalConfig.MaximumFilterMessages) + { + listView_Message.Items.RemoveAt(0); + } + + listView_Message.Items.Add(lvItem); + + } + } + + string GetRegCallbackClassName(FilterAPI.MessageSendData messageSend) + { + if (messageSend.MessageType == (uint)FilterAPI.FilterCommand.FILTER_SEND_REG_CALLBACK_INFO) + { + return ((FilterAPI.RegCallbackClass)messageSend.Offset).ToString(); + } + else + { + return ""; + } + } + + public ListViewItem FormatRegistryMessage(FilterAPI.MessageSendData messageSend) + { + ListViewItem lvItem = new ListViewItem(); + + try + { + + string userName = string.Empty; + string processName = string.Empty; + + FilterAPI.DecodeUserName(messageSend.Sid, out userName); + FilterAPI.DecodeProcessName(messageSend.ProcessId, out processName); + + string[] listData = new string[listView_Message.Columns.Count]; + int col = 0; + listData[col++] = messageSend.MessageId.ToString(); + listData[col++] = FormatDateTime(messageSend.TransactionTime); + listData[col++] = userName; + listData[col++] = processName + " (" + messageSend.ProcessId + ")"; + listData[col++] = messageSend.ThreadId.ToString(); + listData[col++] = GetRegCallbackClassName(messageSend); + listData[col++] = messageSend.FileName; + listData[col++] = FilterMessage.FormatStatus(messageSend.Status); + listData[col++] = RegistryHandler.FormatDescription(messageSend); + + lvItem = new ListViewItem(listData, 0); + + if (messageSend.Status >= (uint)NtStatus.Status.Error) + { + lvItem.BackColor = Color.LightGray; + lvItem.ForeColor = Color.Red; + } + else if (messageSend.Status > (uint)NtStatus.Status.Warning) + { + lvItem.BackColor = Color.LightGray; + lvItem.ForeColor = Color.Yellow; + } + + + if (GlobalConfig.EnableLogTransaction) + { + FilterMessage.LogTrasaction(listData); + } + + AddItemToList(lvItem); + + } + catch (Exception ex) + { + EventManager.WriteMessage(445, "GetFilterMessage", EventLevel.Error, "Add callback message failed." + ex.Message); + lvItem = null; + } + + return lvItem; + + } + + } +} + diff --git a/Demo_Source_Code/CSharpDemo/RegMon/RegistryUnitTest.cs b/Demo_Source_Code/CSharpDemo/RegMon/RegistryUnitTest.cs new file mode 100644 index 0000000..eaab00c --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/RegMon/RegistryUnitTest.cs @@ -0,0 +1,399 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.IO; +using System.Collections.Generic; +using System.Threading; +using System.Text; +using System.Drawing; +using System.Windows.Forms; +using System.Runtime.InteropServices; +using Microsoft.Win32.SafeHandles; + +using EaseFilter.CommonObjects; +using EaseFilter.FilterControl; + +namespace RegMon +{ + public class RegistryUnitTest + { + FilterControl filterControl = null; + + public RichTextBox unitTestResult = new RichTextBox(); + public bool postQueryValueKeyPassed = false; + + private void AppendUnitTestResult(string text, Color color) + { + if (color == Color.Black) + { + unitTestResult.AppendText(Environment.NewLine); + unitTestResult.SelectionFont = new Font("Arial", 12, FontStyle.Bold); + } + + unitTestResult.SelectionStart = unitTestResult.TextLength; + unitTestResult.SelectionLength = 0; + + unitTestResult.SelectionColor = color; + unitTestResult.AppendText(text + Environment.NewLine); + unitTestResult.SelectionColor = unitTestResult.ForeColor; + + if (color == Color.Black) + { + unitTestResult.AppendText(Environment.NewLine); + } + + + } + + /// + /// Fires this event when the register registry event was triggered. + /// + public void NotifyQueryValueKey(object sender, RegistryEventArgs e) + { + if (e.FileName.IndexOf("EaseFilter") > 0) + { + //this is our test key. + postQueryValueKeyPassed = true; + } + } + + /// + /// Fires this event when the register registry event was triggered. + /// + public void OnPreCreateKey(object sender, RegistryEventArgs e) + { + // //test block the registry event. + if (e.FileName.IndexOf("EaseFilter") > 0) + { + e.ReturnStatus = NtStatus.Status.AccessDenied; + } + } + + + /// + /// Fires this event when the register registry event was triggered. + /// + public void OnPreQueryValueKey(object sender, RegistryEventArgs e) + { + + // //test block the registry event. + // e.ReturnStatus = NtStatus.Status.AccessDenied; + KEY_VALUE_INFORMATION_CLASS keyValuseInformationClass = (KEY_VALUE_INFORMATION_CLASS)e.InfoClass; + + //test to replace the query value with your own data. + if (e.FileName.IndexOf("EaseFilter") > 0) + { + + //below code is to demo how to complete pre-callback registry call with our own data. + switch (keyValuseInformationClass) + { + case KEY_VALUE_INFORMATION_CLASS.KeyValueBasicInformation: + { + //public struct KEY_VALUE_BASIC_INFORMATION + // { + // public uint TitleIndex; + // public uint Type; + // public uint NameLength; + // public byte[] Name; + // } + + uint titleIndex = 0; + uint type = (uint)VALUE_DATA_TYPE.REG_SZ; + byte[] valueName = Encoding.Unicode.GetBytes("value1"); + uint valueNameLength = (uint)valueName.Length; + + MemoryStream ms = new MemoryStream(); + BinaryWriter bw = new BinaryWriter(ms); + bw.Write(titleIndex); + bw.Write(type); + bw.Write(valueNameLength); + bw.Write(valueName); + + e.ReturnDataBuffer = ms.ToArray(); + e.IsDataModified = true; + + break; + } + case KEY_VALUE_INFORMATION_CLASS.KeyValueFullInformation: + { + //KeyValueFullInformation class structure + //public uint TitleIndex; + //public uint Type; + //public uint DataOffset; + //public uint DataLength; + //public uint NameLength; + //public byte[] Name; + + uint titleIndex = 0; + //uint type = (uint)VALUE_DATA_TYPE.REG_DWORD; + //uint testData = 12345; + + uint type = (uint)VALUE_DATA_TYPE.REG_SZ; + byte[] testData = UnicodeEncoding.Unicode.GetBytes("S12345"); + + uint testDataLength = sizeof(uint); + byte[] valueName = Encoding.Unicode.GetBytes("value1"); + uint valueNameLength = (uint)valueName.Length; + uint dataOffset = 5 * sizeof(uint) + valueNameLength; + + MemoryStream ms = new MemoryStream(); + BinaryWriter bw = new BinaryWriter(ms); + bw.Write(titleIndex); + bw.Write(type); + bw.Write(dataOffset); + bw.Write(testDataLength); + bw.Write(valueNameLength); + bw.Write(valueName); + bw.Write(testData); + + e.ReturnDataBuffer = ms.ToArray(); + e.IsDataModified = true; + + break; + } + case KEY_VALUE_INFORMATION_CLASS.KeyValuePartialInformation: + { + // public struct KEY_VALUE_PARTIAL_INFORMATION + //{ + // public uint TitleIndex; + // public uint Type; + // public uint DataLength; + // public byte[] Data; + //} + + uint titleIndex = 0; + uint type = (uint)VALUE_DATA_TYPE.REG_SZ; + //uint testData = 12345; + byte[] testData = UnicodeEncoding.Unicode.GetBytes("S12345"); + //uint testDataLength = (uint)sizeof(uint); + uint testDataLength = (uint)testData.Length; + + MemoryStream ms = new MemoryStream(); + BinaryWriter bw = new BinaryWriter(ms); + + bw.Write(titleIndex); + bw.Write(type); + bw.Write(testDataLength); + bw.Write(testData); + + e.ReturnDataBuffer = ms.ToArray(); + e.IsDataModified = true; + + break; + } + + + default: break; + } + } + } + + public void RegistryFilterUnitTest(FilterControl _filterControl, RichTextBox richTextBox_TestResult, string licenseKey) + { + + string lastError = string.Empty; + string userName = Environment.UserDomainName + "\\" + Environment.UserName; + string testRegistryKey = "SYSTEM\\CurrentControlSet\\Services\\EaseFilter"; + string testValueKey = "DisplayName"; + + //full registry access rights + uint accessFlag = FilterAPI.MAX_REGITRY_ACCESS_FLAG; + + bool testPassed = true; + + unitTestResult = richTextBox_TestResult; + + try + { + string message = "Registry Filter Driver Unit Test."; + AppendUnitTestResult(message, Color.Black); + + filterControl = _filterControl; + + if (!filterControl.StartFilter(GlobalConfig.filterType, GlobalConfig.FilterConnectionThreads, GlobalConfig.ConnectionTimeOut, licenseKey, ref lastError)) + { + MessageBox.Show(lastError, "StartFilter", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + Thread.Sleep(3000); + + + //registry access flag test,set full registry access rights for current process. + + RegistryFilter regFilter = new RegistryFilter(); + regFilter.ControlFlag = accessFlag; + regFilter.RegCallbackClass = 0; + regFilter.ProcessId = FilterAPI.GetCurrentProcessId(); + + filterControl.AddFilter(regFilter); + + if (!filterControl.SendConfigSettingsToFilter(ref lastError)) + { + AppendUnitTestResult("SendConfigSettingsToFilter failed:" + lastError, Color.Red); + return; + } + + using (Microsoft.Win32.RegistryKey regkey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(testRegistryKey)) + { + string valueName = (string)regkey.GetValue(testValueKey); + AppendUnitTestResult("1.Test full registry access rights in accessFlag passed, return valueName:" + valueName, Color.Gray); + } + } + catch (Exception ex) + { + AppendUnitTestResult("1.Test registry access flag failed with error:" + ex.Message, Color.Red); + testPassed = false; + } + + if (testPassed) + { + //disable registry open key right test + filterControl.ClearFilters(); + RegistryFilter regFilter = new RegistryFilter(); + regFilter.ControlFlag = FilterAPI.MAX_REGITRY_ACCESS_FLAG & (uint)(~FilterAPI.RegControlFlag.REG_ALLOW_OPEN_KEY); ; + regFilter.RegCallbackClass = 0; + regFilter.ProcessId = FilterAPI.GetCurrentProcessId(); + + filterControl.AddFilter(regFilter); + + if (!filterControl.SendConfigSettingsToFilter(ref lastError)) + { + AppendUnitTestResult("SendConfigSettingsToFilter failed:" + lastError, Color.Red); + return; + } + + try + { + using (Microsoft.Win32.RegistryKey regkey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(testRegistryKey)) + { + string valueName = (string)regkey.GetValue(testValueKey); + AppendUnitTestResult("2.Test disable open registry key right in accessFlag failed, get valueName " + valueName + " succedded.", Color.Red); + } + } + catch + { + AppendUnitTestResult("2.Test disable open registry key right in accessFlag passed.", Color.Green); + } + } + + try + { + + //test query value key callback, we will receive the callback registry query value key. + filterControl.ClearFilters(); + RegistryFilter regFilter = new RegistryFilter(); + regFilter.ControlFlag = FilterAPI.MAX_REGITRY_ACCESS_FLAG; + regFilter.RegCallbackClass = (uint)FilterAPI.RegCallbackClass.Reg_Post_Query_Value_Key; + regFilter.NotifyQueryValueKey += NotifyQueryValueKey; + regFilter.ProcessId = FilterAPI.GetCurrentProcessId(); + + filterControl.AddFilter(regFilter); + + if (!filterControl.SendConfigSettingsToFilter(ref lastError)) + { + AppendUnitTestResult("SendConfigSettingsToFilter failed:" + lastError, Color.Red); + return; + } + + using (Microsoft.Win32.RegistryKey regkey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(testRegistryKey)) + { + string valueName = (string)regkey.GetValue(testValueKey); + + Thread.Sleep(3000); + + if (postQueryValueKeyPassed) + { + AppendUnitTestResult("3.Test registry query value key Reg_Post_Query_Value_Key callback passed, return valueName:" + valueName, Color.Green); + } + else + { + AppendUnitTestResult("3.Test registry query value key Reg_Post_Query_Value_Key callback failed, didn't receive callback message.", Color.Red); + } + } + } + catch (Exception ex) + { + AppendUnitTestResult("3.Test registry query value key Reg_Post_Query_Value_Key callback failed:" + ex.Message, Color.Red); + } + + + //test registry access callback control, in callback function we will block the setting of the value name if it succeeds. + + try + { + filterControl.ClearFilters(); + RegistryFilter regFilter = new RegistryFilter(); + regFilter.ControlFlag = FilterAPI.MAX_REGITRY_ACCESS_FLAG; + regFilter.RegCallbackClass = (uint)FilterAPI.RegCallbackClass.Reg_Pre_Create_Key | (uint)FilterAPI.RegCallbackClass.Reg_Pre_Create_KeyEx; + regFilter.OnPreCreateKey += OnPreCreateKey; + regFilter.OnPreCreateKeyEx += OnPreCreateKey; + + regFilter.ProcessId = FilterAPI.GetCurrentProcessId(); + + filterControl.AddFilter(regFilter); + + if (!filterControl.SendConfigSettingsToFilter(ref lastError)) + { + AppendUnitTestResult("SendConfigSettingsToFilter failed:" + lastError, Color.Red); + return; + } + + using (Microsoft.Win32.RegistryKey regkey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(testRegistryKey)) + { + regkey.CreateSubKey("newSubkey"); + AppendUnitTestResult("4.Test block creating new registry sub key in callback failed, the new subkey was created in callback.", Color.Red); + } + } + catch (Exception ex) + { + AppendUnitTestResult("4.Test block creating new registry sub key in callback passed." + ex.Message, Color.Green); + } + + //test registry access callback control, in callback function we will replace our virutal value back to user if it succeeds. + try + { + filterControl.ClearFilters(); + RegistryFilter regFilter = new RegistryFilter(); + regFilter.ControlFlag = FilterAPI.MAX_REGITRY_ACCESS_FLAG; + regFilter.RegCallbackClass = (uint)FilterAPI.RegCallbackClass.Reg_Pre_Query_Value_Key ; + regFilter.OnPreQueryValueKey += OnPreQueryValueKey; + + regFilter.ProcessId = FilterAPI.GetCurrentProcessId(); + + filterControl.AddFilter(regFilter); + + if (!filterControl.SendConfigSettingsToFilter(ref lastError)) + { + AppendUnitTestResult("SendConfigSettingsToFilter failed:" + lastError, Color.Red); + return; + } + + using (Microsoft.Win32.RegistryKey regkey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(testRegistryKey)) + { + object value = regkey.GetValue("value1"); + AppendUnitTestResult("5.Test modify registry return data in callback passed, return value " + value + ",type:" + value.GetType().ToString(), Color.Green); + } + } + catch (Exception ex) + { + AppendUnitTestResult("5.Test modify registry return data in callback failed: " + ex.Message, Color.Red); + } + } + } +} diff --git a/Demo_Source_Code/CSharpDemo/RegMon/app.config b/Demo_Source_Code/CSharpDemo/RegMon/app.config new file mode 100644 index 0000000..c5e1dae --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/RegMon/app.config @@ -0,0 +1,3 @@ + + + diff --git a/Demo_Source_Code/CSharpDemo/RegMon/app.manifest b/Demo_Source_Code/CSharpDemo/RegMon/app.manifest new file mode 100644 index 0000000..aee0ba0 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/RegMon/app.manifest @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Demo_Source_Code/CSharpDemo/RegMon/registry-icon.ico b/Demo_Source_Code/CSharpDemo/RegMon/registry-icon.ico new file mode 100644 index 0000000..bc0d04d Binary files /dev/null and b/Demo_Source_Code/CSharpDemo/RegMon/registry-icon.ico differ diff --git a/Demo_Source_Code/CSharpDemo/SecureSandbox/AuthorizedProcessForm.Designer.cs b/Demo_Source_Code/CSharpDemo/SecureSandbox/AuthorizedProcessForm.Designer.cs new file mode 100644 index 0000000..5782db7 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/SecureSandbox/AuthorizedProcessForm.Designer.cs @@ -0,0 +1,450 @@ +namespace SecureSandbox +{ + partial class Form_ProcessRights + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form_ProcessRights)); + this.groupBox2 = new System.Windows.Forms.GroupBox(); + this.button_info = new System.Windows.Forms.Button(); + this.label3 = new System.Windows.Forms.Label(); + this.textBox_ProcessId = new System.Windows.Forms.TextBox(); + this.label1 = new System.Windows.Forms.Label(); + this.textBox_ProcessName = new System.Windows.Forms.TextBox(); + this.button_AddProcessName = new System.Windows.Forms.Button(); + this.checkBox_AllowReadEncryptedFiles = new System.Windows.Forms.CheckBox(); + this.checkBox_AllowCopyout = new System.Windows.Forms.CheckBox(); + this.checkBox_AllowSaveAs = new System.Windows.Forms.CheckBox(); + this.label2 = new System.Windows.Forms.Label(); + this.textBox_AccessFlag = new System.Windows.Forms.TextBox(); + this.button_AccessFlag = new System.Windows.Forms.Button(); + this.checkBox_SetSecurity = new System.Windows.Forms.CheckBox(); + this.checkBox_QueryInfo = new System.Windows.Forms.CheckBox(); + this.checkBox_Read = new System.Windows.Forms.CheckBox(); + this.checkBox_QuerySecurity = new System.Windows.Forms.CheckBox(); + this.checkBox_SetInfo = new System.Windows.Forms.CheckBox(); + this.checkBox_Write = new System.Windows.Forms.CheckBox(); + this.checkBox_AllowDelete = new System.Windows.Forms.CheckBox(); + this.checkBox_AllowRename = new System.Windows.Forms.CheckBox(); + this.checkBox_Creation = new System.Windows.Forms.CheckBox(); + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.listView_ProcessRights = new System.Windows.Forms.ListView(); + this.button_Add = new System.Windows.Forms.Button(); + this.button_ApplyAll = new System.Windows.Forms.Button(); + this.button_Delete = new System.Windows.Forms.Button(); + this.button_SaveProcessRight = new System.Windows.Forms.Button(); + this.groupBox2.SuspendLayout(); + this.groupBox1.SuspendLayout(); + this.SuspendLayout(); + // + // groupBox2 + // + this.groupBox2.Controls.Add(this.button_info); + this.groupBox2.Controls.Add(this.label3); + this.groupBox2.Controls.Add(this.textBox_ProcessId); + this.groupBox2.Controls.Add(this.label1); + this.groupBox2.Controls.Add(this.textBox_ProcessName); + this.groupBox2.Controls.Add(this.button_AddProcessName); + this.groupBox2.Controls.Add(this.checkBox_AllowReadEncryptedFiles); + this.groupBox2.Controls.Add(this.checkBox_AllowCopyout); + this.groupBox2.Controls.Add(this.checkBox_AllowSaveAs); + this.groupBox2.Controls.Add(this.label2); + this.groupBox2.Controls.Add(this.textBox_AccessFlag); + this.groupBox2.Controls.Add(this.button_AccessFlag); + this.groupBox2.Controls.Add(this.checkBox_SetSecurity); + this.groupBox2.Controls.Add(this.checkBox_QueryInfo); + this.groupBox2.Controls.Add(this.checkBox_Read); + this.groupBox2.Controls.Add(this.checkBox_QuerySecurity); + this.groupBox2.Controls.Add(this.checkBox_SetInfo); + this.groupBox2.Controls.Add(this.checkBox_Write); + this.groupBox2.Controls.Add(this.checkBox_AllowDelete); + this.groupBox2.Controls.Add(this.checkBox_AllowRename); + this.groupBox2.Controls.Add(this.checkBox_Creation); + this.groupBox2.Location = new System.Drawing.Point(21, 12); + this.groupBox2.Name = "groupBox2"; + this.groupBox2.Size = new System.Drawing.Size(517, 232); + this.groupBox2.TabIndex = 76; + this.groupBox2.TabStop = false; + this.groupBox2.Text = "Process Rights"; + // + // button_info + // + this.button_info.Image = ((System.Drawing.Image)(resources.GetObject("button_info.Image"))); + this.button_info.Location = new System.Drawing.Point(422, 25); + this.button_info.Name = "button_info"; + this.button_info.Size = new System.Drawing.Size(60, 33); + this.button_info.TabIndex = 97; + this.button_info.UseVisualStyleBackColor = true; + this.button_info.Click += new System.EventHandler(this.button_info_Click); + // + // label3 + // + this.label3.AutoSize = true; + this.label3.Location = new System.Drawing.Point(12, 65); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(64, 15); + this.label3.TabIndex = 42; + this.label3.Text = "Process Id"; + // + // textBox_ProcessId + // + this.textBox_ProcessId.Location = new System.Drawing.Point(152, 65); + this.textBox_ProcessId.Name = "textBox_ProcessId"; + this.textBox_ProcessId.ReadOnly = true; + this.textBox_ProcessId.Size = new System.Drawing.Size(242, 20); + this.textBox_ProcessId.TabIndex = 41; + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(12, 32); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(88, 15); + this.label1.TabIndex = 39; + this.label1.Text = "Process Name"; + // + // textBox_ProcessName + // + this.textBox_ProcessName.Location = new System.Drawing.Point(152, 32); + this.textBox_ProcessName.Name = "textBox_ProcessName"; + this.textBox_ProcessName.Size = new System.Drawing.Size(242, 20); + this.textBox_ProcessName.TabIndex = 38; + // + // button_AddProcessName + // + this.button_AddProcessName.Location = new System.Drawing.Point(422, 65); + this.button_AddProcessName.Name = "button_AddProcessName"; + this.button_AddProcessName.Size = new System.Drawing.Size(60, 20); + this.button_AddProcessName.TabIndex = 40; + this.button_AddProcessName.Text = "..."; + this.button_AddProcessName.UseVisualStyleBackColor = true; + this.button_AddProcessName.Click += new System.EventHandler(this.button_AddProcessName_Click); + // + // checkBox_AllowReadEncryptedFiles + // + this.checkBox_AllowReadEncryptedFiles.AutoSize = true; + this.checkBox_AllowReadEncryptedFiles.Checked = true; + this.checkBox_AllowReadEncryptedFiles.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBox_AllowReadEncryptedFiles.Location = new System.Drawing.Point(151, 205); + this.checkBox_AllowReadEncryptedFiles.Name = "checkBox_AllowReadEncryptedFiles"; + this.checkBox_AllowReadEncryptedFiles.Size = new System.Drawing.Size(195, 19); + this.checkBox_AllowReadEncryptedFiles.TabIndex = 37; + this.checkBox_AllowReadEncryptedFiles.Text = "Allow encrypted file being read"; + this.checkBox_AllowReadEncryptedFiles.UseVisualStyleBackColor = true; + this.checkBox_AllowReadEncryptedFiles.CheckedChanged += new System.EventHandler(this.checkBox_AllowReadEncryptedFiles_CheckedChanged); + // + // checkBox_AllowCopyout + // + this.checkBox_AllowCopyout.AutoSize = true; + this.checkBox_AllowCopyout.Checked = true; + this.checkBox_AllowCopyout.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBox_AllowCopyout.Location = new System.Drawing.Point(336, 205); + this.checkBox_AllowCopyout.Name = "checkBox_AllowCopyout"; + this.checkBox_AllowCopyout.Size = new System.Drawing.Size(177, 19); + this.checkBox_AllowCopyout.TabIndex = 35; + this.checkBox_AllowCopyout.Text = "Allow files being copied out"; + this.checkBox_AllowCopyout.UseVisualStyleBackColor = true; + this.checkBox_AllowCopyout.CheckedChanged += new System.EventHandler(this.checkBox_AllowCopyout_CheckedChanged); + // + // checkBox_AllowSaveAs + // + this.checkBox_AllowSaveAs.AutoSize = true; + this.checkBox_AllowSaveAs.Checked = true; + this.checkBox_AllowSaveAs.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBox_AllowSaveAs.Location = new System.Drawing.Point(336, 182); + this.checkBox_AllowSaveAs.Name = "checkBox_AllowSaveAs"; + this.checkBox_AllowSaveAs.Size = new System.Drawing.Size(162, 19); + this.checkBox_AllowSaveAs.TabIndex = 34; + this.checkBox_AllowSaveAs.Text = "Allow file being saved as"; + this.checkBox_AllowSaveAs.UseVisualStyleBackColor = true; + this.checkBox_AllowSaveAs.CheckedChanged += new System.EventHandler(this.checkBox_AllowSaveAs_CheckedChanged); + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(10, 103); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(114, 15); + this.label2.TabIndex = 32; + this.label2.Text = "Access Control Flag"; + // + // textBox_AccessFlag + // + this.textBox_AccessFlag.Location = new System.Drawing.Point(152, 100); + this.textBox_AccessFlag.Name = "textBox_AccessFlag"; + this.textBox_AccessFlag.ReadOnly = true; + this.textBox_AccessFlag.Size = new System.Drawing.Size(242, 20); + this.textBox_AccessFlag.TabIndex = 31; + this.textBox_AccessFlag.Text = "0"; + // + // button_AccessFlag + // + this.button_AccessFlag.Location = new System.Drawing.Point(422, 102); + this.button_AccessFlag.Name = "button_AccessFlag"; + this.button_AccessFlag.Size = new System.Drawing.Size(60, 20); + this.button_AccessFlag.TabIndex = 33; + this.button_AccessFlag.Text = "..."; + this.button_AccessFlag.UseVisualStyleBackColor = true; + this.button_AccessFlag.Click += new System.EventHandler(this.button_AccessFlag_Click); + // + // checkBox_SetSecurity + // + this.checkBox_SetSecurity.AutoSize = true; + this.checkBox_SetSecurity.Checked = true; + this.checkBox_SetSecurity.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBox_SetSecurity.Location = new System.Drawing.Point(336, 159); + this.checkBox_SetSecurity.Name = "checkBox_SetSecurity"; + this.checkBox_SetSecurity.Size = new System.Drawing.Size(156, 19); + this.checkBox_SetSecurity.TabIndex = 29; + this.checkBox_SetSecurity.Text = "Allow changing security"; + this.checkBox_SetSecurity.UseVisualStyleBackColor = true; + this.checkBox_SetSecurity.CheckedChanged += new System.EventHandler(this.checkBox_SetSecurity_CheckedChanged); + // + // checkBox_QueryInfo + // + this.checkBox_QueryInfo.AutoSize = true; + this.checkBox_QueryInfo.Checked = true; + this.checkBox_QueryInfo.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBox_QueryInfo.Location = new System.Drawing.Point(152, 137); + this.checkBox_QueryInfo.Name = "checkBox_QueryInfo"; + this.checkBox_QueryInfo.Size = new System.Drawing.Size(173, 19); + this.checkBox_QueryInfo.TabIndex = 24; + this.checkBox_QueryInfo.Text = "Allow querying information"; + this.checkBox_QueryInfo.UseVisualStyleBackColor = true; + this.checkBox_QueryInfo.CheckedChanged += new System.EventHandler(this.checkBox_QueryInfo_CheckedChanged); + // + // checkBox_Read + // + this.checkBox_Read.AutoSize = true; + this.checkBox_Read.Checked = true; + this.checkBox_Read.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBox_Read.Location = new System.Drawing.Point(12, 137); + this.checkBox_Read.Name = "checkBox_Read"; + this.checkBox_Read.Size = new System.Drawing.Size(122, 19); + this.checkBox_Read.TabIndex = 26; + this.checkBox_Read.Text = "Allow reading file"; + this.checkBox_Read.UseVisualStyleBackColor = true; + this.checkBox_Read.CheckedChanged += new System.EventHandler(this.checkBox_Read_CheckedChanged); + // + // checkBox_QuerySecurity + // + this.checkBox_QuerySecurity.AutoSize = true; + this.checkBox_QuerySecurity.Checked = true; + this.checkBox_QuerySecurity.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBox_QuerySecurity.Location = new System.Drawing.Point(336, 137); + this.checkBox_QuerySecurity.Name = "checkBox_QuerySecurity"; + this.checkBox_QuerySecurity.Size = new System.Drawing.Size(152, 19); + this.checkBox_QuerySecurity.TabIndex = 25; + this.checkBox_QuerySecurity.Text = "Allow querying security"; + this.checkBox_QuerySecurity.UseVisualStyleBackColor = true; + this.checkBox_QuerySecurity.CheckedChanged += new System.EventHandler(this.checkBox_QuerySecurity_CheckedChanged); + // + // checkBox_SetInfo + // + this.checkBox_SetInfo.AutoSize = true; + this.checkBox_SetInfo.Checked = true; + this.checkBox_SetInfo.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBox_SetInfo.Location = new System.Drawing.Point(152, 159); + this.checkBox_SetInfo.Name = "checkBox_SetInfo"; + this.checkBox_SetInfo.Size = new System.Drawing.Size(177, 19); + this.checkBox_SetInfo.TabIndex = 28; + this.checkBox_SetInfo.Text = "Allow changing information"; + this.checkBox_SetInfo.UseVisualStyleBackColor = true; + this.checkBox_SetInfo.CheckedChanged += new System.EventHandler(this.checkBox_SetInfo_CheckedChanged); + // + // checkBox_Write + // + this.checkBox_Write.AutoSize = true; + this.checkBox_Write.Checked = true; + this.checkBox_Write.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBox_Write.Location = new System.Drawing.Point(12, 160); + this.checkBox_Write.Name = "checkBox_Write"; + this.checkBox_Write.Size = new System.Drawing.Size(116, 19); + this.checkBox_Write.TabIndex = 15; + this.checkBox_Write.Text = "Allow writing file"; + this.checkBox_Write.UseVisualStyleBackColor = true; + this.checkBox_Write.CheckedChanged += new System.EventHandler(this.checkBox_Write_CheckedChanged); + // + // checkBox_AllowDelete + // + this.checkBox_AllowDelete.AutoSize = true; + this.checkBox_AllowDelete.Checked = true; + this.checkBox_AllowDelete.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBox_AllowDelete.Location = new System.Drawing.Point(12, 205); + this.checkBox_AllowDelete.Name = "checkBox_AllowDelete"; + this.checkBox_AllowDelete.Size = new System.Drawing.Size(124, 19); + this.checkBox_AllowDelete.TabIndex = 17; + this.checkBox_AllowDelete.Text = "Allow deleting file"; + this.checkBox_AllowDelete.UseVisualStyleBackColor = true; + this.checkBox_AllowDelete.CheckedChanged += new System.EventHandler(this.checkBox_AllowDelete_CheckedChanged); + // + // checkBox_AllowRename + // + this.checkBox_AllowRename.AutoSize = true; + this.checkBox_AllowRename.Checked = true; + this.checkBox_AllowRename.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBox_AllowRename.Location = new System.Drawing.Point(152, 182); + this.checkBox_AllowRename.Name = "checkBox_AllowRename"; + this.checkBox_AllowRename.Size = new System.Drawing.Size(133, 19); + this.checkBox_AllowRename.TabIndex = 16; + this.checkBox_AllowRename.Text = "Allow renaming file"; + this.checkBox_AllowRename.UseVisualStyleBackColor = true; + this.checkBox_AllowRename.CheckedChanged += new System.EventHandler(this.checkBox_AllowRename_CheckedChanged); + // + // checkBox_Creation + // + this.checkBox_Creation.AutoSize = true; + this.checkBox_Creation.Checked = true; + this.checkBox_Creation.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBox_Creation.Location = new System.Drawing.Point(12, 182); + this.checkBox_Creation.Name = "checkBox_Creation"; + this.checkBox_Creation.Size = new System.Drawing.Size(150, 19); + this.checkBox_Creation.TabIndex = 22; + this.checkBox_Creation.Text = "Allow creating new file"; + this.checkBox_Creation.UseVisualStyleBackColor = true; + this.checkBox_Creation.CheckedChanged += new System.EventHandler(this.checkBox_Creation_CheckedChanged); + // + // groupBox1 + // + this.groupBox1.Controls.Add(this.listView_ProcessRights); + this.groupBox1.Location = new System.Drawing.Point(21, 279); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size(523, 105); + this.groupBox1.TabIndex = 77; + this.groupBox1.TabStop = false; + this.groupBox1.Text = "Process rights collection"; + // + // listView_ProcessRights + // + this.listView_ProcessRights.Dock = System.Windows.Forms.DockStyle.Fill; + this.listView_ProcessRights.FullRowSelect = true; + this.listView_ProcessRights.Location = new System.Drawing.Point(3, 16); + this.listView_ProcessRights.Name = "listView_ProcessRights"; + this.listView_ProcessRights.Size = new System.Drawing.Size(517, 86); + this.listView_ProcessRights.TabIndex = 1; + this.listView_ProcessRights.UseCompatibleStateImageBehavior = false; + this.listView_ProcessRights.View = System.Windows.Forms.View.Details; + this.listView_ProcessRights.SelectedIndexChanged += new System.EventHandler(this.listView_ProcessRights_SelectedIndexChanged); + // + // button_Add + // + this.button_Add.Location = new System.Drawing.Point(21, 406); + this.button_Add.Name = "button_Add"; + this.button_Add.Size = new System.Drawing.Size(122, 23); + this.button_Add.TabIndex = 79; + this.button_Add.Text = "Add Process Rights"; + this.button_Add.UseVisualStyleBackColor = true; + this.button_Add.Click += new System.EventHandler(this.button_AddProcessRights_Click); + // + // button_ApplyAll + // + this.button_ApplyAll.DialogResult = System.Windows.Forms.DialogResult.OK; + this.button_ApplyAll.Location = new System.Drawing.Point(376, 406); + this.button_ApplyAll.Name = "button_ApplyAll"; + this.button_ApplyAll.Size = new System.Drawing.Size(162, 23); + this.button_ApplyAll.TabIndex = 80; + this.button_ApplyAll.Text = "Apply Settings To Sandbox"; + this.button_ApplyAll.UseVisualStyleBackColor = true; + this.button_ApplyAll.Click += new System.EventHandler(this.button_ApplyAll_Click); + // + // button_Delete + // + this.button_Delete.Location = new System.Drawing.Point(197, 406); + this.button_Delete.Name = "button_Delete"; + this.button_Delete.Size = new System.Drawing.Size(153, 23); + this.button_Delete.TabIndex = 78; + this.button_Delete.Text = "Delete Process Rights"; + this.button_Delete.UseVisualStyleBackColor = true; + this.button_Delete.Click += new System.EventHandler(this.button_Delete_Click); + // + // button_SaveProcessRight + // + this.button_SaveProcessRight.BackColor = System.Drawing.Color.Gold; + this.button_SaveProcessRight.Location = new System.Drawing.Point(381, 250); + this.button_SaveProcessRight.Name = "button_SaveProcessRight"; + this.button_SaveProcessRight.Size = new System.Drawing.Size(153, 23); + this.button_SaveProcessRight.TabIndex = 81; + this.button_SaveProcessRight.Text = "Save Process Right"; + this.button_SaveProcessRight.UseVisualStyleBackColor = false; + this.button_SaveProcessRight.Click += new System.EventHandler(this.button_SaveProcessRight_Click); + // + // Form_ProcessRights + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(570, 465); + this.Controls.Add(this.button_SaveProcessRight); + this.Controls.Add(this.button_ApplyAll); + this.Controls.Add(this.button_Add); + this.Controls.Add(this.button_Delete); + this.Controls.Add(this.groupBox1); + this.Controls.Add(this.groupBox2); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Margin = new System.Windows.Forms.Padding(2); + this.MaximizeBox = false; + this.Name = "Form_ProcessRights"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "Set the access rights to the specific process"; + this.groupBox2.ResumeLayout(false); + this.groupBox2.PerformLayout(); + this.groupBox1.ResumeLayout(false); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.GroupBox groupBox2; + private System.Windows.Forms.CheckBox checkBox_Write; + private System.Windows.Forms.CheckBox checkBox_AllowDelete; + private System.Windows.Forms.CheckBox checkBox_AllowRename; + private System.Windows.Forms.CheckBox checkBox_Creation; + private System.Windows.Forms.CheckBox checkBox_SetSecurity; + private System.Windows.Forms.CheckBox checkBox_QueryInfo; + private System.Windows.Forms.CheckBox checkBox_Read; + private System.Windows.Forms.CheckBox checkBox_QuerySecurity; + private System.Windows.Forms.CheckBox checkBox_SetInfo; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.TextBox textBox_AccessFlag; + private System.Windows.Forms.Button button_AccessFlag; + private System.Windows.Forms.CheckBox checkBox_AllowCopyout; + private System.Windows.Forms.CheckBox checkBox_AllowSaveAs; + private System.Windows.Forms.CheckBox checkBox_AllowReadEncryptedFiles; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.TextBox textBox_ProcessName; + private System.Windows.Forms.Button button_AddProcessName; + private System.Windows.Forms.GroupBox groupBox1; + private System.Windows.Forms.ListView listView_ProcessRights; + private System.Windows.Forms.Button button_Add; + private System.Windows.Forms.Button button_ApplyAll; + private System.Windows.Forms.Button button_Delete; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.TextBox textBox_ProcessId; + private System.Windows.Forms.Button button_info; + private System.Windows.Forms.Button button_SaveProcessRight; + } +} \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/SecureSandbox/AuthorizedProcessForm.cs b/Demo_Source_Code/CSharpDemo/SecureSandbox/AuthorizedProcessForm.cs new file mode 100644 index 0000000..e2007d6 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/SecureSandbox/AuthorizedProcessForm.cs @@ -0,0 +1,611 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +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; + +using EaseFilter.FilterControl; +using EaseFilter.CommonObjects; + +namespace SecureSandbox +{ + + public partial class Form_ProcessRights : Form + { + public struct ProcessRight + { + public string ProcessName; + public uint ProcessId; + public uint AccessFlag; + } + + public FileFilterRule currentFilterRule = null; + ProcessRight selectedProcessRight; + Dictionary processRights = new Dictionary(); + + public Form_ProcessRights(ref FileFilterRule filterRule) + { + InitializeComponent(); + currentFilterRule = filterRule; + + StartPosition = FormStartPosition.CenterParent; + + string[] processRightList = filterRule.ProcessNameRights.ToLower().Split(new char[] { ';' }); + if (processRightList.Length > 0) + { + foreach (string processRightStr in processRightList) + { + if (processRightStr.Trim().Length > 0) + { + string processName = processRightStr.Substring(0, processRightStr.IndexOf('!')); + uint accessFlag = uint.Parse(processRightStr.Substring(processRightStr.IndexOf('!') + 1)); + + if (!processRights.ContainsKey(processName)) + { + ProcessRight processRight = new ProcessRight(); + processRight.ProcessName = processName; + processRight.ProcessId = 0; + processRight.AccessFlag = accessFlag; + + processRights.Add(processName, processRight); + } + + textBox_ProcessName.Text = processName; + textBox_AccessFlag.Text = accessFlag.ToString(); + } + } + + } + + string[] processIdList = filterRule.ProcessIdRights.Split(new char[] { ';' }); + if (processIdList.Length > 0) + { + foreach (string processIdRightStr in processIdList) + { + if (processIdRightStr.Trim().Length > 0) + { + string processId = processIdRightStr.Substring(0, processIdRightStr.IndexOf('!')); + uint accessFlag = uint.Parse(processIdRightStr.Substring(processIdRightStr.IndexOf('!') + 1)); + + if (!processRights.ContainsKey(processId)) + { + ProcessRight processRight = new ProcessRight(); + processRight.ProcessName = ""; + processRight.ProcessId = uint.Parse(processId); + processRight.AccessFlag = accessFlag; + + processRights.Add(processId, processRight); + } + + textBox_ProcessId.Text = processId; + textBox_AccessFlag.Text = accessFlag.ToString(); + } + } + + } + + InitListView(); + SetCheckBoxValue(); + } + + public void InitListView() + { + //init ListView control + listView_ProcessRights.Clear(); //clear control + //create column header for ListView + listView_ProcessRights.Columns.Add("#", 20, System.Windows.Forms.HorizontalAlignment.Left); + listView_ProcessRights.Columns.Add("Process Name", 350, System.Windows.Forms.HorizontalAlignment.Left); + listView_ProcessRights.Columns.Add("Process Id", 100, System.Windows.Forms.HorizontalAlignment.Left); + listView_ProcessRights.Columns.Add("Access Rights", 150, System.Windows.Forms.HorizontalAlignment.Left); + + foreach (ProcessRight processRight in processRights.Values) + { + string[] itemStr = new string[listView_ProcessRights.Columns.Count]; + itemStr[0] = listView_ProcessRights.Items.Count.ToString(); + itemStr[1] = processRight.ProcessName; + itemStr[2] = processRight.ProcessId.ToString(); + itemStr[3] = processRight.AccessFlag.ToString(); + + ListViewItem item = new ListViewItem(itemStr, 0); + item.Tag = processRight; + listView_ProcessRights.Items.Add(item); + + selectedProcessRight = processRight; + } + + } + + private void SetCheckBoxValue() + { + + if (textBox_AccessFlag.Text.Trim().Length == 0) + { + return; + } + + uint accessFlags = uint.Parse(textBox_AccessFlag.Text); + + if ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_FILE_DELETE) > 0) + { + checkBox_AllowDelete.Checked = true; + } + else + { + checkBox_AllowDelete.Checked = false; + } + + if ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_FILE_RENAME) > 0) + { + checkBox_AllowRename.Checked = true; + } + else + { + checkBox_AllowRename.Checked = false; + } + + if ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_WRITE_ACCESS) > 0 ) + { + checkBox_Write.Checked = true; + } + else + { + checkBox_Write.Checked = false; + } + + if ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_READ_ACCESS) > 0) + { + checkBox_Read.Checked = true; + } + else + { + checkBox_Read.Checked = false; + } + + if ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_QUERY_INFORMATION_ACCESS) > 0) + { + checkBox_QueryInfo.Checked = true; + } + else + { + checkBox_QueryInfo.Checked = false; + } + + if ( (accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_SET_INFORMATION) > 0 ) + { + checkBox_SetInfo.Checked = true; + } + else + { + checkBox_SetInfo.Checked = false; + } + + if ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_OPEN_WITH_CREATE_OR_OVERWRITE_ACCESS) > 0) + { + checkBox_Creation.Checked = true; + } + else + { + checkBox_Creation.Checked = false; + } + + if ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_QUERY_SECURITY_ACCESS) > 0) + { + checkBox_QuerySecurity.Checked = true; + } + else + { + checkBox_QuerySecurity.Checked = false; + } + + if ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_SET_SECURITY_ACCESS) > 0) + { + checkBox_SetSecurity.Checked = true; + } + else + { + checkBox_SetSecurity.Checked = false; + } + + if ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_ALL_SAVE_AS) > 0) + { + checkBox_AllowSaveAs.Checked = true; + } + else + { + checkBox_AllowSaveAs.Checked = false; + } + + if ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_COPY_PROTECTED_FILES_OUT) > 0) + { + checkBox_AllowCopyout.Checked = true; + } + else + { + checkBox_AllowCopyout.Checked = false; + } + + if ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_READ_ENCRYPTED_FILES) > 0) + { + checkBox_AllowReadEncryptedFiles.Checked = true; + } + else + { + checkBox_AllowReadEncryptedFiles.Checked = false; + } + } + + private void button_AccessFlag_Click(object sender, EventArgs e) + { + OptionForm optionForm = new OptionForm(OptionForm.OptionType.Access_Flag, textBox_AccessFlag.Text); + + if (optionForm.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + if (optionForm.AccessFlags > 0) + { + textBox_AccessFlag.Text = optionForm.AccessFlags.ToString(); + } + else + { + //if the accessFlag is 0, it is exclude filter rule,this is not what we want, so we need to include this flag. + textBox_AccessFlag.Text = ((uint)FilterAPI.AccessFlag.LEAST_ACCESS_FLAG).ToString(); + } + + SetCheckBoxValue(); + } + } + + private void checkBox_Read_CheckedChanged(object sender, EventArgs e) + { + uint accessFlags = uint.Parse(textBox_AccessFlag.Text.Trim()); + if (checkBox_Read.Checked) + { + accessFlags |= (uint)FilterAPI.AccessFlag.ALLOW_READ_ACCESS; + } + else + { + accessFlags &= ~(uint)FilterAPI.AccessFlag.ALLOW_READ_ACCESS; + } + + textBox_AccessFlag.Text = accessFlags.ToString(); + } + + private void checkBox_Write_CheckedChanged(object sender, EventArgs e) + { + uint accessFlags = uint.Parse(textBox_AccessFlag.Text.Trim()); + if (checkBox_Write.Checked) + { + accessFlags |= (uint)FilterAPI.AccessFlag.ALLOW_WRITE_ACCESS; + } + else + { + accessFlags &= ~(uint)FilterAPI.AccessFlag.ALLOW_WRITE_ACCESS; + } + + textBox_AccessFlag.Text = accessFlags.ToString(); + } + + private void checkBox_Creation_CheckedChanged(object sender, EventArgs e) + { + uint accessFlags = uint.Parse(textBox_AccessFlag.Text.Trim()); + if (checkBox_Creation.Checked) + { + accessFlags |= (uint)FilterAPI.AccessFlag.ALLOW_OPEN_WITH_CREATE_OR_OVERWRITE_ACCESS; + } + else + { + accessFlags &= ~(uint)FilterAPI.AccessFlag.ALLOW_OPEN_WITH_CREATE_OR_OVERWRITE_ACCESS; + } + + textBox_AccessFlag.Text = accessFlags.ToString(); + } + + + private void checkBox_QueryInfo_CheckedChanged(object sender, EventArgs e) + { + uint accessFlags = uint.Parse(textBox_AccessFlag.Text.Trim()); + if (checkBox_QueryInfo.Checked) + { + accessFlags |= (uint)FilterAPI.AccessFlag.ALLOW_QUERY_INFORMATION_ACCESS; + } + else + { + accessFlags &= ~(uint)FilterAPI.AccessFlag.ALLOW_QUERY_INFORMATION_ACCESS; + } + + textBox_AccessFlag.Text = accessFlags.ToString(); + } + + private void checkBox_SetInfo_CheckedChanged(object sender, EventArgs e) + { + uint accessFlags = uint.Parse(textBox_AccessFlag.Text.Trim()); + if (checkBox_SetInfo.Checked) + { + accessFlags |= (uint)FilterAPI.AccessFlag.ALLOW_SET_INFORMATION; + } + else + { + accessFlags &= ~(uint)FilterAPI.AccessFlag.ALLOW_SET_INFORMATION; + } + + textBox_AccessFlag.Text = accessFlags.ToString(); + } + + private void checkBox_AllowRename_CheckedChanged(object sender, EventArgs e) + { + uint accessFlags = uint.Parse(textBox_AccessFlag.Text.Trim()); + if (checkBox_AllowRename.Checked) + { + accessFlags |= (uint)FilterAPI.AccessFlag.ALLOW_FILE_RENAME; + } + else + { + accessFlags &= ~(uint)FilterAPI.AccessFlag.ALLOW_FILE_RENAME; + } + + textBox_AccessFlag.Text = accessFlags.ToString(); + } + + private void checkBox_AllowDelete_CheckedChanged(object sender, EventArgs e) + { + uint accessFlags = uint.Parse(textBox_AccessFlag.Text.Trim()); + if (checkBox_AllowDelete.Checked) + { + accessFlags |= (uint)FilterAPI.AccessFlag.ALLOW_FILE_DELETE; + } + else + { + accessFlags &= ~(uint)FilterAPI.AccessFlag.ALLOW_FILE_DELETE; + } + + textBox_AccessFlag.Text = accessFlags.ToString(); + } + + private void checkBox_QuerySecurity_CheckedChanged(object sender, EventArgs e) + { + uint accessFlags = uint.Parse(textBox_AccessFlag.Text.Trim()); + if (checkBox_QuerySecurity.Checked) + { + accessFlags |= (uint)FilterAPI.AccessFlag.ALLOW_QUERY_SECURITY_ACCESS; + } + else + { + accessFlags &= ~(uint)FilterAPI.AccessFlag.ALLOW_QUERY_SECURITY_ACCESS; + } + + textBox_AccessFlag.Text = accessFlags.ToString(); + } + + private void checkBox_SetSecurity_CheckedChanged(object sender, EventArgs e) + { + uint accessFlags = uint.Parse(textBox_AccessFlag.Text.Trim()); + if (checkBox_SetSecurity.Checked) + { + accessFlags |= (uint)FilterAPI.AccessFlag.ALLOW_SET_SECURITY_ACCESS; + } + else + { + accessFlags &= ~(uint)FilterAPI.AccessFlag.ALLOW_SET_SECURITY_ACCESS; + } + + textBox_AccessFlag.Text = accessFlags.ToString(); + } + + private void checkBox_AllowSaveAs_CheckedChanged(object sender, EventArgs e) + { + uint accessFlags = uint.Parse(textBox_AccessFlag.Text.Trim()); + if (checkBox_AllowSaveAs.Checked) + { + accessFlags |= (uint)FilterAPI.AccessFlag.ALLOW_ALL_SAVE_AS; + } + else + { + accessFlags &= ~(uint)FilterAPI.AccessFlag.ALLOW_ALL_SAVE_AS; + } + + textBox_AccessFlag.Text = accessFlags.ToString(); + } + + private void checkBox_AllowCopyout_CheckedChanged(object sender, EventArgs e) + { + uint accessFlags = uint.Parse(textBox_AccessFlag.Text.Trim()); + if (checkBox_AllowCopyout.Checked) + { + accessFlags |= (uint)FilterAPI.AccessFlag.ALLOW_COPY_PROTECTED_FILES_OUT; + } + else + { + accessFlags &= ~(uint)FilterAPI.AccessFlag.ALLOW_COPY_PROTECTED_FILES_OUT; + } + + textBox_AccessFlag.Text = accessFlags.ToString(); + } + + private void checkBox_AllowReadEncryptedFiles_CheckedChanged(object sender, EventArgs e) + { + uint accessFlags = uint.Parse(textBox_AccessFlag.Text.Trim()); + if (checkBox_AllowReadEncryptedFiles.Checked) + { + accessFlags |= (uint)FilterAPI.AccessFlag.ALLOW_READ_ENCRYPTED_FILES; + } + else + { + accessFlags &= ~(uint)FilterAPI.AccessFlag.ALLOW_READ_ENCRYPTED_FILES; + } + + textBox_AccessFlag.Text = accessFlags.ToString(); + } + + private void button_AddProcessName_Click(object sender, EventArgs e) + { + + OptionForm optionForm = new OptionForm(OptionForm.OptionType.ProccessId, textBox_ProcessId.Text); + + if (optionForm.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + if (optionForm.ProcessId.Length > 0) + { + textBox_ProcessId.Text = optionForm.ProcessId; + + //we choose to use process Id instead of the process name + textBox_ProcessName.Text = ""; + } + } + } + + private void button_Delete_Click(object sender, EventArgs e) + { + if (listView_ProcessRights.SelectedItems.Count == 0) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("There are no process selected.", "Delete process", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + ProcessRight processRight = (ProcessRight)listView_ProcessRights.SelectedItems[0].Tag; + + if (processRight.ProcessId > 0) + { + processRights.Remove(processRight.ProcessId.ToString()); + } + else + { + processRights.Remove(processRight.ProcessName.ToString()); + } + + InitListView(); + } + + private void listView_ProcessRights_SelectedIndexChanged(object sender, EventArgs e) + { + + if (listView_ProcessRights.SelectedItems.Count > 0) + { + ProcessRight processRight = (ProcessRight)listView_ProcessRights.SelectedItems[0].Tag; + + textBox_AccessFlag.Text = processRight.AccessFlag.ToString(); + textBox_ProcessName.Text = processRight.ProcessName; + textBox_ProcessId.Text = processRight.ProcessId.ToString(); + + SetCheckBoxValue(); + } + + } + + private void button_AddProcessRights_Click(object sender, EventArgs e) + { + textBox_ProcessName.Text = "newprocessname.exe"; + textBox_AccessFlag.Text = FilterAPI.ALLOW_MAX_RIGHT_ACCESS.ToString(); + SetCheckBoxValue(); + } + + private void button_ApplyAll_Click(object sender, EventArgs e) + { + currentFilterRule.ProcessNameRights = ""; + currentFilterRule.ProcessIdRights = ""; + + foreach (ProcessRight processRight in processRights.Values ) + { + if (processRight.ProcessId > 0) + { + currentFilterRule.ProcessIdRights += processRight.ProcessId.ToString() + "!" + processRight.AccessFlag + ";"; + } + else + { + currentFilterRule.ProcessNameRights += processRight.ProcessName + "!" + processRight.AccessFlag + ";"; + } + } + } + + private void button_info_Click(object sender, EventArgs e) + { + string information = "1.With the access right control to the process, you can control which process can access or change your files.\r\n\r\n"; + information += "2. The process name filter mask format can be the image path filter mask or the process name, e.g. 'c:\\test\\*.exe'. or only process name, e.g. 'notepad.exe'.\r\n\r\n"; + information += "3. To authorize all access rights to the process, set the accessFlag to the maximum access rights."; + information += "To remove some specific access rights to the process, set the accessFlag to the maximum access rights first, then remove thoese specific rights.\r\n\r\n"; + + + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show(information, "How to set the access rights to specific process?", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + + private void button_SaveProcessRight_Click(object sender, EventArgs e) + { + + if (textBox_ProcessName.Text.Trim().Length == 0 && (textBox_ProcessId.Text.Length == 0 || textBox_ProcessId.Text == "0")) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("The process name and process Id can't be empty.", "Save settings", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + string[] processList = textBox_ProcessName.Text.ToLower().Split(new char[] { ';' }); + uint accessFlag = uint.Parse(textBox_AccessFlag.Text); + + if (processList.Length > 0) + { + foreach (string processName in processList) + { + if (processName.Trim().Length > 0) + { + processRights.Remove(processName); + ProcessRight processRight = new ProcessRight(); + processRight.ProcessName = processName; + processRight.ProcessId = 0; + processRight.AccessFlag = accessFlag; + + processRights.Add(processName, processRight); + } + } + + } + + string[] processIdList = textBox_ProcessId.Text.Split(new char[] { ';' }); + if (processIdList.Length > 0) + { + foreach (string processId in processIdList) + { + uint pid = 0; + + if (uint.TryParse(processId, out pid) && pid > 0) + { + processRights.Remove(processId); + + ProcessRight processRight = new ProcessRight(); + processRight.ProcessName = ""; + processRight.ProcessId = uint.Parse(processId); + processRight.AccessFlag = accessFlag; + + processRights.Add(processId, processRight); + + } + } + + } + + InitListView(); + } + + + } +} diff --git a/Demo_Source_Code/CSharpDemo/SecureSandbox/AuthorizedProcessForm.resx b/Demo_Source_Code/CSharpDemo/SecureSandbox/AuthorizedProcessForm.resx new file mode 100644 index 0000000..d0018ab --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/SecureSandbox/AuthorizedProcessForm.resx @@ -0,0 +1,1892 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + 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 + DPgfKTU+503JE84AAAAASUVORK5CYII= + + + + + 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 + qJ73+c18/Xp5VJ9fl/P5y6LcpupvP3RkTF7d3T6A8xcBAARGAACBEQBAYAQAEBgBAARGAACB/Q//xIY7 + IGrejgAAAABJRU5ErkJggigAAACAAAAAAAEAAAEAIAAAAAAAAAABABMLAAATCwAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAG2QkHBtkJBwbZCQcG2QkHB1nJqkdZyapHWcmqR1nJqkcZybnHGcm5xxnJuccZybn + HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/ + HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/ + HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/ + HGcm/xxnJv8cZyb/GFoh/xhaIf8YWiH/GFoh/xZSHv8WUh7/FlIe/xZSHv8XUx//F1Mf/xdTH/8XUx// + F1Qf/xdUH/8XVB//F1Qf/xdUH/8XVB//F1Qf/xdUH/8XViD/F1Yg/xdWIP8XViD/F1Yg/xdWIP8XViD/ + F1Yg/xhXIP8YVyD/GFcg/xhXIP8YWCD/GFgg/xhYIP8YWCD/GFkh/xhZIf8YWSH/GFkh/xhaIf8YWiH/ + GFoh/xhaIf8ZWiH/GVoh/xlaIf8ZWiH/GFwi6RhcIukYXCLpGFwi6RpcIq8aXCKvGlwirxpcIq8ZWiEf + GVohHxlaIR8ZWiEfAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbZCQcG2QkHBtkJBwbZCQc + HWcmqR1nJqkdZyapHWcmqRxnJuccZybnHGcm5xxnJuccZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/ + HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/ + HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/ + HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8YWiH/GFoh/xhaIf8YWiH/ + FlIe/xZSHv8WUh7/FlIe/xdTH/8XUx//F1Mf/xdTH/8XVB//F1Qf/xdUH/8XVB//F1Qf/xdUH/8XVB// + F1Qf/xdWIP8XViD/F1Yg/xdWIP8XViD/F1Yg/xdWIP8XViD/GFcg/xhXIP8YVyD/GFcg/xhYIP8YWCD/ + GFgg/xhYIP8YWSH/GFkh/xhZIf8YWSH/GFoh/xhaIf8YWiH/GFoh/xlaIf8ZWiH/GVoh/xlaIf8YXCLp + GFwi6RhcIukYXCLpGlwirxpcIq8aXCKvGlwirxlaIR8ZWiEfGVohHxlaIR8AAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAABtkJBwbZCQcG2QkHBtkJBwdZyapHWcmqR1nJqkdZyapHGcm5xxnJuccZybn + HGcm5xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/ + HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/ + HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/ + HGcm/xxnJv8cZyb/HGcm/xhaIf8YWiH/GFoh/xhaIf8WUh7/FlIe/xZSHv8WUh7/F1Mf/xdTH/8XUx// + F1Mf/xdUH/8XVB//F1Qf/xdUH/8XVB//F1Qf/xdUH/8XVB//F1Yg/xdWIP8XViD/F1Yg/xdWIP8XViD/ + F1Yg/xdWIP8YVyD/GFcg/xhXIP8YVyD/GFgg/xhYIP8YWCD/GFgg/xhZIf8YWSH/GFkh/xhZIf8YWiH/ + GFoh/xhaIf8YWiH/GVoh/xlaIf8ZWiH/GVoh/xhcIukYXCLpGFwi6RhcIukaXCKvGlwirxpcIq8aXCKv + GVohHxlaIR8ZWiEfGVohHwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAG2QkHBtkJBwbZCQc + G2QkHB1nJqkdZyapHWcmqR1nJqkcZybnHGcm5xxnJuccZybnHGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/ + HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/ + HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/ + HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/GFoh/xhaIf8YWiH/ + GFoh/xZSHv8WUh7/FlIe/xZSHv8XUx//F1Mf/xdTH/8XUx//F1Qf/xdUH/8XVB//F1Qf/xdUH/8XVB// + F1Qf/xdUH/8XViD/F1Yg/xdWIP8XViD/F1Yg/xdWIP8XViD/F1Yg/xhXIP8YVyD/GFcg/xhXIP8YWCD/ + GFgg/xhYIP8YWCD/GFkh/xhZIf8YWSH/GFkh/xhaIf8YWiH/GFoh/xhaIf8ZWiH/GVoh/xlaIf8ZWiH/ + GFwi6RhcIukYXCLpGFwi6RpcIq8aXCKvGlwirxpcIq8ZWiEfGVohHxlaIR8ZWiEfAAAAAAAAAAAAAAAA + AAAAABtkJBwbZCQcG2QkHBtkJBwdaCftHWgn7R1oJ+0daCftHWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/xlaIv8ZWiL/GVoi/xlaIv8XUR7/F1Ee/xdRHv8XUR7/F1If/xdSH/8XUh//F1If/xdTH/8XUx// + F1Mf/xdTH/8XVB//F1Qf/xdUH/8XVB//GFQg/xhUIP8YVCD/GFQg/xhVIP8YVSD/GFUg/xhVIP8YViD/ + GFYg/xhWIP8YViD/GFch/xhXIf8YVyH/GFch/xlYIf8ZWCH/GVgh/xlYIf8ZWSH/GVkh/xlZIf8ZWSH/ + GVoi/xlaIv8ZWiL/GVoi/xlbIv8ZWyL/GVsi/xlbIv8ZWyL/GVsi/xlbIv8ZWyL/Glwj/xpcI/8aXCP/ + Glwj/xpdIu8aXSLvGl0i7xpdIu8ZWiEfGVohHxlaIR8ZWiEfG2QkHBtkJBwbZCQcG2QkHB1oJ+0daCft + HWgn7R1oJ+0daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/GVoi/xlaIv8ZWiL/GVoi/xdRHv8XUR7/ + F1Ee/xdRHv8XUh//F1If/xdSH/8XUh//F1Mf/xdTH/8XUx//F1Mf/xdUH/8XVB//F1Qf/xdUH/8YVCD/ + GFQg/xhUIP8YVCD/GFUg/xhVIP8YVSD/GFUg/xhWIP8YViD/GFYg/xhWIP8YVyH/GFch/xhXIf8YVyH/ + GVgh/xlYIf8ZWCH/GVgh/xlZIf8ZWSH/GVkh/xlZIf8ZWiL/GVoi/xlaIv8ZWiL/GVsi/xlbIv8ZWyL/ + GVsi/xlbIv8ZWyL/GVsi/xlbIv8aXCP/Glwj/xpcI/8aXCP/Gl0i7xpdIu8aXSLvGl0i7xlaIR8ZWiEf + GVohHxlaIR8bZCQcG2QkHBtkJBwbZCQcHWgn7R1oJ+0daCftHWgn7R1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8ZWiL/GVoi/xlaIv8ZWiL/F1Ee/xdRHv8XUR7/F1Ee/xdSH/8XUh//F1If/xdSH/8XUx// + F1Mf/xdTH/8XUx//F1Qf/xdUH/8XVB//F1Qf/xhUIP8YVCD/GFQg/xhUIP8YVSD/GFUg/xhVIP8YVSD/ + GFYg/xhWIP8YViD/GFYg/xhXIf8YVyH/GFch/xhXIf8ZWCH/GVgh/xlYIf8ZWCH/GVkh/xlZIf8ZWSH/ + GVkh/xlaIv8ZWiL/GVoi/xlaIv8ZWyL/GVsi/xlbIv8ZWyL/GVsi/xlbIv8ZWyL/GVsi/xpcI/8aXCP/ + Glwj/xpcI/8aXSLvGl0i7xpdIu8aXSLvGVohHxlaIR8ZWiEfGVohHxtkJBwbZCQcG2QkHBtkJBwdaCft + HWgn7R1oJ+0daCftHWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/xlaIv8ZWiL/GVoi/xlaIv8XUR7/ + F1Ee/xdRHv8XUR7/F1If/xdSH/8XUh//F1If/xdTH/8XUx//F1Mf/xdTH/8XVB//F1Qf/xdUH/8XVB// + GFQg/xhUIP8YVCD/GFQg/xhVIP8YVSD/GFUg/xhVIP8YViD/GFYg/xhWIP8YViD/GFch/xhXIf8YVyH/ + GFch/xlYIf8ZWCH/GVgh/xlYIf8ZWSH/GVkh/xlZIf8ZWSH/GVoi/xlaIv8ZWiL/GVoi/xlbIv8ZWyL/ + GVsi/xlbIv8ZWyL/GVsi/xlbIv8ZWyL/Glwj/xpcI/8aXCP/Glwj/xpdIu8aXSLvGl0i7xpdIu8ZWiEf + GVohHxlaIR8ZWiEfHmopqR5qKakeaimpHmopqR5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8aWyL/ + Glsi/xpbIv8aWyL/F1Ef/xdRH/8XUR//F1Ef/xdSH/8XUh//F1If/xdSH/8XUx//F1Mf/xdTH/8XUx// + GFQg/xhUIP8YVCD/GFQg/xhUIP8YVCD/GFQg/xhUIP8YVSD/GFUg/xhVIP8YVSD/GFYg/xhWIP8YViD/ + GFYg/xlXIf8ZVyH/GVch/xlXIf8ZWCH/GVgh/xlYIf8ZWCH/GVki/xlZIv8ZWSL/GVki/xlaIv8ZWiL/ + GVoi/xlaIv8aWyL/Glsi/xpbIv8aWyL/Glsj/xpbI/8aWyP/Glsj/xpcI/8aXCP/Glwj/xpcI/8aXSP/ + Gl0j/xpdI/8aXSP/G14j/xteI/8bXiP/G14j/xxfJK8cXySvHF8krxxfJK8eaimpHmopqR5qKakeaimp + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/xpbIv8aWyL/Glsi/xpbIv8XUR//F1Ef/xdRH/8XUR// + F1If/xdSH/8XUh//F1If/xdTH/8XUx//F1Mf/xdTH/8YVCD/GFQg/xhUIP8YVCD/GFQg/xhUIP8YVCD/ + GFQg/xhVIP8YVSD/GFUg/xhVIP8YViD/GFYg/xhWIP8YViD/GVch/xlXIf8ZVyH/GVch/xlYIf8ZWCH/ + GVgh/xlYIf8ZWSL/GVki/xlZIv8ZWSL/GVoi/xlaIv8ZWiL/GVoi/xpbIv8aWyL/Glsi/xpbIv8aWyP/ + Glsj/xpbI/8aWyP/Glwj/xpcI/8aXCP/Glwj/xpdI/8aXSP/Gl0j/xpdI/8bXiP/G14j/xteI/8bXiP/ + HF8krxxfJK8cXySvHF8krx5qKakeaimpHmopqR5qKakeaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Glsi/xpbIv8aWyL/Glsi/xdRH/8XUR//F1Ef/xdRH/8XUh//F1If/xdSH/8XUh//F1Mf/xdTH/8XUx// + F1Mf/xhUIP8YVCD/GFQg/xhUIP8YVCD/GFQg/xhUIP8YVCD/GFUg/xhVIP8YVSD/GFUg/xhWIP8YViD/ + GFYg/xhWIP8ZVyH/GVch/xlXIf8ZVyH/GVgh/xlYIf8ZWCH/GVgh/xlZIv8ZWSL/GVki/xlZIv8ZWiL/ + GVoi/xlaIv8ZWiL/Glsi/xpbIv8aWyL/Glsi/xpbI/8aWyP/Glsj/xpbI/8aXCP/Glwj/xpcI/8aXCP/ + Gl0j/xpdI/8aXSP/Gl0j/xteI/8bXiP/G14j/xteI/8cXySvHF8krxxfJK8cXySvHmopqR5qKakeaimp + HmopqR5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8aWyL/Glsi/xpbIv8aWyL/F1Ef/xdRH/8XUR// + F1Ef/xdSH/8XUh//F1If/xdSH/8XUx//F1Mf/xdTH/8XUx//GFQg/xhUIP8YVCD/GFQg/xhUIP8YVCD/ + GFQg/xhUIP8YVSD/GFUg/xhVIP8YVSD/GFYg/xhWIP8YViD/GFYg/xlXIf8ZVyH/GVch/xlXIf8ZWCH/ + GVgh/xlYIf8ZWCH/GVki/xlZIv8ZWSL/GVki/xlaIv8ZWiL/GVoi/xlaIv8aWyL/Glsi/xpbIv8aWyL/ + Glsj/xpbI/8aWyP/Glsj/xpcI/8aXCP/Glwj/xpcI/8aXSP/Gl0j/xpdI/8aXSP/G14j/xteI/8bXiP/ + G14j/xxfJK8cXySvHF8krxxfJK8fayroH2sq6B9rKugfayroH2sq/x9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/Glsk/xpbJP8aWyT/ + Glsk/xdQH/8XUB//F1Af/xdQH/8eaWD/Hmlg/x5pYP8eaWD/Hmpg/x5qYP8eamD/Hmpg/xhTIP8YUyD/ + GFMg/xhTIP8YVCH/GFQh/xhUIf8YVCH/GFQh/xhUIf8YVCH/GFQh/xlVIf8ZVSH/GVUh/xlVIf8ZViL/ + GVYi/xlWIv8ZViL/GVci/xlXIv8ZVyL/GVci/xlYIv8ZWCL/GVgi/xlYIv8aWSP/Glkj/xpZI/8aWSP/ + Gloj/xpaI/8aWiP/Gloj/xpbJP8aWyT/Glsk/xpbJP8bWyT/G1sk/xtbJP8bWyT/G1wk/xtcJP8bXCT/ + G1wk/xtdJf8bXSX/G10l/xtdJf8bXiX/G14l/xteJf8bXiX/G18l6RtfJekbXyXpG18l6R9rKugfayro + H2sq6B9rKugfayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8aWyT/Glsk/xpbJP8aWyT/F1Af/xdQH/8XUB//F1Af/x5pYP8eaWD/ + Hmlg/x5pYP8eamD/Hmpg/x5qYP8eamD/GFMg/xhTIP8YUyD/GFMg/xhUIf8YVCH/GFQh/xhUIf8YVCH/ + GFQh/xhUIf8YVCH/GVUh/xlVIf8ZVSH/GVUh/xlWIv8ZViL/GVYi/xlWIv8ZVyL/GVci/xlXIv8ZVyL/ + GVgi/xlYIv8ZWCL/GVgi/xpZI/8aWSP/Glkj/xpZI/8aWiP/Gloj/xpaI/8aWiP/Glsk/xpbJP8aWyT/ + Glsk/xtbJP8bWyT/G1sk/xtbJP8bXCT/G1wk/xtcJP8bXCT/G10l/xtdJf8bXSX/G10l/xteJf8bXiX/ + G14l/xteJf8bXyXpG18l6RtfJekbXyXpH2sq6B9rKugfayroH2sq6B9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/xpbJP8aWyT/ + Glsk/xpbJP8XUB//F1Af/xdQH/8XUB//Hmlg/x5pYP8eaWD/Hmlg/x5qYP8eamD/Hmpg/x5qYP8YUyD/ + GFMg/xhTIP8YUyD/GFQh/xhUIf8YVCH/GFQh/xhUIf8YVCH/GFQh/xhUIf8ZVSH/GVUh/xlVIf8ZVSH/ + GVYi/xlWIv8ZViL/GVYi/xlXIv8ZVyL/GVci/xlXIv8ZWCL/GVgi/xlYIv8ZWCL/Glkj/xpZI/8aWSP/ + Glkj/xpaI/8aWiP/Gloj/xpaI/8aWyT/Glsk/xpbJP8aWyT/G1sk/xtbJP8bWyT/G1sk/xtcJP8bXCT/ + G1wk/xtcJP8bXSX/G10l/xtdJf8bXSX/G14l/xteJf8bXiX/G14l/xtfJekbXyXpG18l6RtfJekfayro + H2sq6B9rKugfayroH2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/Glsk/xpbJP8aWyT/Glsk/xdQH/8XUB//F1Af/xdQH/8eaWD/ + Hmlg/x5pYP8eaWD/Hmpg/x5qYP8eamD/Hmpg/xhTIP8YUyD/GFMg/xhTIP8YVCH/GFQh/xhUIf8YVCH/ + GFQh/xhUIf8YVCH/GFQh/xlVIf8ZVSH/GVUh/xlVIf8ZViL/GVYi/xlWIv8ZViL/GVci/xlXIv8ZVyL/ + GVci/xlYIv8ZWCL/GVgi/xlYIv8aWSP/Glkj/xpZI/8aWSP/Gloj/xpaI/8aWiP/Gloj/xpbJP8aWyT/ + Glsk/xpbJP8bWyT/G1sk/xtbJP8bWyT/G1wk/xtcJP8bXCT/G1wk/xtdJf8bXSX/G10l/xtdJf8bXiX/ + G14l/xteJf8bXiX/G18l6RtfJekbXyXpG18l6SBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/xtbJP8bWyT/G1sk/xtbJP8eaFr/ + Hmha/x5oWv8eaFr/JYKy/yWCsv8lgrL/JYKy/ymT3/8pk9//KZPf/ymT3/8pk9//KZPf/ymT3/8pk9// + JYKu/yWCrv8lgq7/JYKu/x5nVP8eZ1T/HmdU/x5nVP8ZVSL/GVUi/xlVIv8ZVSL/GVYi/xlWIv8ZViL/ + GVYi/xlXIv8ZVyL/GVci/xlXIv8aWCP/Glgj/xpYI/8aWCP/Glgj/xpYI/8aWCP/Glgj/xpZI/8aWSP/ + Glkj/xpZI/8bWyT/G1sk/xtbJP8bWyT/G1sk/xtbJP8bWyT/G1sk/xtcJP8bXCT/G1wk/xtcJP8bXSX/ + G10l/xtdJf8bXSX/HF4l/xxeJf8cXiX/HF4l/xxfJf8cXyX/HF8l/xxfJf8cYCb/HGAm/xxgJv8cYCb/ + IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/G1sk/xtbJP8bWyT/G1sk/x5oWv8eaFr/Hmha/x5oWv8lgrL/JYKy/yWCsv8lgrL/ + KZPf/ymT3/8pk9//KZPf/ymT3/8pk9//KZPf/ymT3/8lgq7/JYKu/yWCrv8lgq7/HmdU/x5nVP8eZ1T/ + HmdU/xlVIv8ZVSL/GVUi/xlVIv8ZViL/GVYi/xlWIv8ZViL/GVci/xlXIv8ZVyL/GVci/xpYI/8aWCP/ + Glgj/xpYI/8aWCP/Glgj/xpYI/8aWCP/Glkj/xpZI/8aWSP/Glkj/xtbJP8bWyT/G1sk/xtbJP8bWyT/ + G1sk/xtbJP8bWyT/G1wk/xtcJP8bXCT/G1wk/xtdJf8bXSX/G10l/xtdJf8cXiX/HF4l/xxeJf8cXiX/ + HF8l/xxfJf8cXyX/HF8l/xxgJv8cYCb/HGAm/xxgJv8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8bWyT/G1sk/xtbJP8bWyT/ + Hmha/x5oWv8eaFr/Hmha/yWCsv8lgrL/JYKy/yWCsv8pk9//KZPf/ymT3/8pk9//KZPf/ymT3/8pk9// + KZPf/yWCrv8lgq7/JYKu/yWCrv8eZ1T/HmdU/x5nVP8eZ1T/GVUi/xlVIv8ZVSL/GVUi/xlWIv8ZViL/ + GVYi/xlWIv8ZVyL/GVci/xlXIv8ZVyL/Glgj/xpYI/8aWCP/Glgj/xpYI/8aWCP/Glgj/xpYI/8aWSP/ + Glkj/xpZI/8aWSP/G1sk/xtbJP8bWyT/G1sk/xtbJP8bWyT/G1sk/xtbJP8bXCT/G1wk/xtcJP8bXCT/ + G10l/xtdJf8bXSX/G10l/xxeJf8cXiX/HF4l/xxeJf8cXyX/HF8l/xxfJf8cXyX/HGAm/xxgJv8cYCb/ + HGAm/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/IG0r/xtbJP8bWyT/G1sk/xtbJP8eaFr/Hmha/x5oWv8eaFr/JYKy/yWCsv8lgrL/ + JYKy/ymT3/8pk9//KZPf/ymT3/8pk9//KZPf/ymT3/8pk9//JYKu/yWCrv8lgq7/JYKu/x5nVP8eZ1T/ + HmdU/x5nVP8ZVSL/GVUi/xlVIv8ZVSL/GVYi/xlWIv8ZViL/GVYi/xlXIv8ZVyL/GVci/xlXIv8aWCP/ + Glgj/xpYI/8aWCP/Glgj/xpYI/8aWCP/Glgj/xpZI/8aWSP/Glkj/xpZI/8bWyT/G1sk/xtbJP8bWyT/ + G1sk/xtbJP8bWyT/G1sk/xtcJP8bXCT/G1wk/xtcJP8bXSX/G10l/xtdJf8bXSX/HF4l/xxeJf8cXiX/ + HF4l/xxfJf8cXyX/HF8l/xxfJf8cYCb/HGAm/xxgJv8cYCb/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8dZUD/HWVA/x1lQP8dZUD/JIGn/ySBp/8kgaf/ + JIGn/ymU3/8plN//KZTf/ymU3/8upPf/LqT3/y6k9/8upPf/L6j9/y+o/f8vqP3/L6j9/y+o/f8vqP3/ + L6j9/y+o/f8upPf/LqT3/y6k9/8upPf/KZTf/ymU3/8plN//KZTf/ySApf8kgKX/JICl/ySApf8cYkL/ + HGJC/xxiQv8cYkL/GVcj/xlXI/8ZVyP/GVcj/xlYJP8ZWCT/GVgk/xlYJP8aWCT/Glgk/xpYJP8aWCT/ + Glkl/xpZJf8aWSX/Glkl/xpaJf8aWiX/Glol/xpaJf8bWyX/G1sl/xtbJf8bWyX/G1wm/xtcJv8bXCb/ + G1wm/xtdJv8bXSb/G10m/xtdJv8bXib/G14m/xteJv8bXib/HF8n/xxfJ/8cXyf/HF8n/xxgJ/8cYCf/ + HGAn/xxgJ/8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/x1lQP8dZUD/HWVA/x1lQP8kgaf/JIGn/ySBp/8kgaf/KZTf/ymU3/8plN//KZTf/y6k9/8upPf/ + LqT3/y6k9/8vqP3/L6j9/y+o/f8vqP3/L6j9/y+o/f8vqP3/L6j9/y6k9/8upPf/LqT3/y6k9/8plN// + KZTf/ymU3/8plN//JICl/ySApf8kgKX/JICl/xxiQv8cYkL/HGJC/xxiQv8ZVyP/GVcj/xlXI/8ZVyP/ + GVgk/xlYJP8ZWCT/GVgk/xpYJP8aWCT/Glgk/xpYJP8aWSX/Glkl/xpZJf8aWSX/Glol/xpaJf8aWiX/ + Glol/xtbJf8bWyX/G1sl/xtbJf8bXCb/G1wm/xtcJv8bXCb/G10m/xtdJv8bXSb/G10m/xteJv8bXib/ + G14m/xteJv8cXyf/HF8n/xxfJ/8cXyf/HGAn/xxgJ/8cYCf/HGAn/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/HWVA/x1lQP8dZUD/HWVA/ySBp/8kgaf/ + JIGn/ySBp/8plN//KZTf/ymU3/8plN//LqT3/y6k9/8upPf/LqT3/y+o/f8vqP3/L6j9/y+o/f8vqP3/ + L6j9/y+o/f8vqP3/LqT3/y6k9/8upPf/LqT3/ymU3/8plN//KZTf/ymU3/8kgKX/JICl/ySApf8kgKX/ + HGJC/xxiQv8cYkL/HGJC/xlXI/8ZVyP/GVcj/xlXI/8ZWCT/GVgk/xlYJP8ZWCT/Glgk/xpYJP8aWCT/ + Glgk/xpZJf8aWSX/Glkl/xpZJf8aWiX/Glol/xpaJf8aWiX/G1sl/xtbJf8bWyX/G1sl/xtcJv8bXCb/ + G1wm/xtcJv8bXSb/G10m/xtdJv8bXSb/G14m/xteJv8bXib/G14m/xxfJ/8cXyf/HF8n/xxfJ/8cYCf/ + HGAn/xxgJ/8cYCf/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/yBuLf8dZUD/HWVA/x1lQP8dZUD/JIGn/ySBp/8kgaf/JIGn/ymU3/8plN//KZTf/ymU3/8upPf/ + LqT3/y6k9/8upPf/L6j9/y+o/f8vqP3/L6j9/y+o/f8vqP3/L6j9/y+o/f8upPf/LqT3/y6k9/8upPf/ + KZTf/ymU3/8plN//KZTf/ySApf8kgKX/JICl/ySApf8cYkL/HGJC/xxiQv8cYkL/GVcj/xlXI/8ZVyP/ + GVcj/xlYJP8ZWCT/GVgk/xlYJP8aWCT/Glgk/xpYJP8aWCT/Glkl/xpZJf8aWSX/Glkl/xpaJf8aWiX/ + Glol/xpaJf8bWyX/G1sl/xtbJf8bWyX/G1wm/xtcJv8bXCb/G1wm/xtdJv8bXSb/G10m/xtdJv8bXib/ + G14m/xteJv8bXib/HF8n/xxfJ/8cXyf/HF8n/xxgJ/8cYCf/HGAn/xxgJ/8hcC7/IXAu/yFwLv8hcC7/ + IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/ + IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/ + IXAu/yFwLv8hcS//IXEv/yFxL/8hcS//JHx+/yR8fv8kfH7/JHx+/ymR1P8pkdT/KZHU/ymR1P8vpfb/ + L6X2/y+l9v8vpfb/MKn8/zCp/P8wqfz/MKn8/yybzf8sm83/LJvN/yybzf8gblr/IG5a/yBuWv8gblr/ + IGxY/yBsWP8gbFj/IGxY/yyazP8smsz/LJrM/yyazP8wqfz/MKn8/zCp/P8wqfz/L6X2/y+l9v8vpfb/ + L6X2/yqR1P8qkdT/KpHU/yqR1P8gdHH/IHRx/yB0cf8gdHH/Glgk/xpYJP8aWCT/Glgk/xpZJf8aWSX/ + Glkl/xpZJf8bWiX/G1ol/xtaJf8bWiX/G1sl/xtbJf8bWyX/G1sl/xtcJv8bXCb/G1wm/xtcJv8bXSb/ + G10m/xtdJv8bXSb/HF4n/xxeJ/8cXif/HF4n/xxfJ/8cXyf/HF8n/xxfJ/8cYCf/HGAn/xxgJ/8cYCf/ + HGEo/xxhKP8cYSj/HGEo/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/ + IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/ + IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFxL/8hcS//IXEv/yFxL/8kfH7/ + JHx+/yR8fv8kfH7/KZHU/ymR1P8pkdT/KZHU/y+l9v8vpfb/L6X2/y+l9v8wqfz/MKn8/zCp/P8wqfz/ + LJvN/yybzf8sm83/LJvN/yBuWv8gblr/IG5a/yBuWv8gbFj/IGxY/yBsWP8gbFj/LJrM/yyazP8smsz/ + LJrM/zCp/P8wqfz/MKn8/zCp/P8vpfb/L6X2/y+l9v8vpfb/KpHU/yqR1P8qkdT/KpHU/yB0cf8gdHH/ + IHRx/yB0cf8aWCT/Glgk/xpYJP8aWCT/Glkl/xpZJf8aWSX/Glkl/xtaJf8bWiX/G1ol/xtaJf8bWyX/ + G1sl/xtbJf8bWyX/G1wm/xtcJv8bXCb/G1wm/xtdJv8bXSb/G10m/xtdJv8cXif/HF4n/xxeJ/8cXif/ + HF8n/xxfJ/8cXyf/HF8n/xxgJ/8cYCf/HGAn/xxgJ/8cYSj/HGEo/xxhKP8cYSj/IXAu/yFwLv8hcC7/ + IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/ + IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/ + IXAu/yFwLv8hcC7/IXEv/yFxL/8hcS//IXEv/yR8fv8kfH7/JHx+/yR8fv8pkdT/KZHU/ymR1P8pkdT/ + L6X2/y+l9v8vpfb/L6X2/zCp/P8wqfz/MKn8/zCp/P8sm83/LJvN/yybzf8sm83/IG5a/yBuWv8gblr/ + IG5a/yBsWP8gbFj/IGxY/yBsWP8smsz/LJrM/yyazP8smsz/MKn8/zCp/P8wqfz/MKn8/y+l9v8vpfb/ + L6X2/y+l9v8qkdT/KpHU/yqR1P8qkdT/IHRx/yB0cf8gdHH/IHRx/xpYJP8aWCT/Glgk/xpYJP8aWSX/ + Glkl/xpZJf8aWSX/G1ol/xtaJf8bWiX/G1ol/xtbJf8bWyX/G1sl/xtbJf8bXCb/G1wm/xtcJv8bXCb/ + G10m/xtdJv8bXSb/G10m/xxeJ/8cXif/HF4n/xxeJ/8cXyf/HF8n/xxfJ/8cXyf/HGAn/xxgJ/8cYCf/ + HGAn/xxhKP8cYSj/HGEo/xxhKP8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/ + IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/ + IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcS//IXEv/yFxL/8hcS// + JHx+/yR8fv8kfH7/JHx+/ymR1P8pkdT/KZHU/ymR1P8vpfb/L6X2/y+l9v8vpfb/MKn8/zCp/P8wqfz/ + MKn8/yybzf8sm83/LJvN/yybzf8gblr/IG5a/yBuWv8gblr/IGxY/yBsWP8gbFj/IGxY/yyazP8smsz/ + LJrM/yyazP8wqfz/MKn8/zCp/P8wqfz/L6X2/y+l9v8vpfb/L6X2/yqR1P8qkdT/KpHU/yqR1P8gdHH/ + IHRx/yB0cf8gdHH/Glgk/xpYJP8aWCT/Glgk/xpZJf8aWSX/Glkl/xpZJf8bWiX/G1ol/xtaJf8bWiX/ + G1sl/xtbJf8bWyX/G1sl/xtcJv8bXCb/G1wm/xtcJv8bXSb/G10m/xtdJv8bXSb/HF4n/xxeJ/8cXif/ + HF4n/xxfJ/8cXyf/HF8n/xxfJ/8cYCf/HGAn/xxgJ/8cYCf/HGEo/xxhKP8cYSj/HGEo/yJxL/8icS// + InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS// + InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS// + I3Q7/yN0O/8jdDv/I3Q7/yeHqv8nh6r/J4eq/yeHqv8tn+z/LZ/s/y2f7P8tn+z/MKr8/zCq/P8wqvz/ + MKr8/y6f2P8un9j/Lp/Y/y6f2P8hcmb/IXJm/yFyZv8hcmb/GFEi/xhRIv8YUSL/GFEi/xlSIv8ZUiL/ + GVIi/xlSIv8ZUyL/GVMi/xlTIv8ZUyL/GVQj/xlUI/8ZVCP/GVQj/yJ0Z/8idGf/InRn/yJ0Z/8un9j/ + Lp/Y/y6f2P8un9j/MKr8/zCq/P8wqvz/MKr8/y2f7P8tn+z/LZ/s/y2f7P8lhKP/JYSj/yWEo/8lhKP/ + HF4z/xxeM/8cXjP/HF4z/xtaJf8bWiX/G1ol/xtaJf8bWyb/G1sm/xtbJv8bWyb/HFwm/xxcJv8cXCb/ + HFwm/xxdJ/8cXSf/HF0n/xxdJ/8cXif/HF4n/xxeJ/8cXif/HV8n/x1fJ/8dXyf/HV8n/x1gKP8dYCj/ + HWAo/x1gKP8dYSj/HWEo/x1hKP8dYSj/InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS// + InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS// + InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8jdDv/I3Q7/yN0O/8jdDv/J4eq/yeHqv8nh6r/ + J4eq/y2f7P8tn+z/LZ/s/y2f7P8wqvz/MKr8/zCq/P8wqvz/Lp/Y/y6f2P8un9j/Lp/Y/yFyZv8hcmb/ + IXJm/yFyZv8YUSL/GFEi/xhRIv8YUSL/GVIi/xlSIv8ZUiL/GVIi/xlTIv8ZUyL/GVMi/xlTIv8ZVCP/ + GVQj/xlUI/8ZVCP/InRn/yJ0Z/8idGf/InRn/y6f2P8un9j/Lp/Y/y6f2P8wqvz/MKr8/zCq/P8wqvz/ + LZ/s/y2f7P8tn+z/LZ/s/yWEo/8lhKP/JYSj/yWEo/8cXjP/HF4z/xxeM/8cXjP/G1ol/xtaJf8bWiX/ + G1ol/xtbJv8bWyb/G1sm/xtbJv8cXCb/HFwm/xxcJv8cXCb/HF0n/xxdJ/8cXSf/HF0n/xxeJ/8cXif/ + HF4n/xxeJ/8dXyf/HV8n/x1fJ/8dXyf/HWAo/x1gKP8dYCj/HWAo/x1hKP8dYSj/HWEo/x1hKP8icS// + InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS// + InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS// + InEv/yN0O/8jdDv/I3Q7/yN0O/8nh6r/J4eq/yeHqv8nh6r/LZ/s/y2f7P8tn+z/LZ/s/zCq/P8wqvz/ + MKr8/zCq/P8un9j/Lp/Y/y6f2P8un9j/IXJm/yFyZv8hcmb/IXJm/xhRIv8YUSL/GFEi/xhRIv8ZUiL/ + GVIi/xlSIv8ZUiL/GVMi/xlTIv8ZUyL/GVMi/xlUI/8ZVCP/GVQj/xlUI/8idGf/InRn/yJ0Z/8idGf/ + Lp/Y/y6f2P8un9j/Lp/Y/zCq/P8wqvz/MKr8/zCq/P8tn+z/LZ/s/y2f7P8tn+z/JYSj/yWEo/8lhKP/ + JYSj/xxeM/8cXjP/HF4z/xxeM/8bWiX/G1ol/xtaJf8bWiX/G1sm/xtbJv8bWyb/G1sm/xxcJv8cXCb/ + HFwm/xxcJv8cXSf/HF0n/xxdJ/8cXSf/HF4n/xxeJ/8cXif/HF4n/x1fJ/8dXyf/HV8n/x1fJ/8dYCj/ + HWAo/x1gKP8dYCj/HWEo/x1hKP8dYSj/HWEo/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS// + InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS// + InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//I3Q7/yN0O/8jdDv/I3Q7/yeHqv8nh6r/ + J4eq/yeHqv8tn+z/LZ/s/y2f7P8tn+z/MKr8/zCq/P8wqvz/MKr8/y6f2P8un9j/Lp/Y/y6f2P8hcmb/ + IXJm/yFyZv8hcmb/GFEi/xhRIv8YUSL/GFEi/xlSIv8ZUiL/GVIi/xlSIv8ZUyL/GVMi/xlTIv8ZUyL/ + GVQj/xlUI/8ZVCP/GVQj/yJ0Z/8idGf/InRn/yJ0Z/8un9j/Lp/Y/y6f2P8un9j/MKr8/zCq/P8wqvz/ + MKr8/y2f7P8tn+z/LZ/s/y2f7P8lhKP/JYSj/yWEo/8lhKP/HF4z/xxeM/8cXjP/HF4z/xtaJf8bWiX/ + G1ol/xtaJf8bWyb/G1sm/xtbJv8bWyb/HFwm/xxcJv8cXCb/HFwm/xxdJ/8cXSf/HF0n/xxdJ/8cXif/ + HF4n/xxeJ/8cXif/HV8n/x1fJ/8dXyf/HV8n/x1gKP8dYCj/HWAo/x1gKP8dYSj/HWEo/x1hKP8dYSj/ + LHg6/yx4Ov8seDr/LHg6/yVzM/8lczP/JXMz/yVzM/8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/ + I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yR0PP8kdDz/ + JHQ8/yR0PP8pj73/KY+9/ymPvf8pj73/MKn5/zCp+f8wqfn/MKn5/zCo9P8wqPT/MKj0/zCo9P8mgYn/ + JoGJ/yaBif8mgYn/GVAl/xlQJf8ZUCX/GVAl/xhQIv8YUCL/GFAi/xhQIv8ZUCP/GVAj/xlQI/8ZUCP/ + GVIj/xlSI/8ZUiP/GVIj/xlTJP8ZUyT/GVMk/xlTJP8aVCT/GlQk/xpUJP8aVCT/GlQk/xpUJP8aVCT/ + GlQk/xtXKP8bVyj/G1co/xtXKP8nhY3/J4WN/yeFjf8nhY3/MKr2/zCq9v8wqvb/MKr2/zCp+f8wqfn/ + MKn5/zCp+f8pjr3/KY69/ymOvf8pjr3/HV8z/x1fM/8dXzP/HV8z/xxbJ/8cWyf/HFsn/xxbJ/8cXCf/ + HFwn/xxcJ/8cXCf/HF0o/xxdKP8cXSj/HF0o/x1dKP8dXSj/HV0o/x1dKP8dXyn/HV8p/x1fKf8dXyn/ + HWAp/x1gKf8dYCn/HWAp/x5hKv8eYSr/HmEq/x5hKv8seDr/LHg6/yx4Ov8seDr/JXMz/yVzM/8lczP/ + JXMz/yNyMf8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/ + I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/JHQ8/yR0PP8kdDz/JHQ8/ymPvf8pj73/KY+9/ymPvf8wqfn/ + MKn5/zCp+f8wqfn/MKj0/zCo9P8wqPT/MKj0/yaBif8mgYn/JoGJ/yaBif8ZUCX/GVAl/xlQJf8ZUCX/ + GFAi/xhQIv8YUCL/GFAi/xlQI/8ZUCP/GVAj/xlQI/8ZUiP/GVIj/xlSI/8ZUiP/GVMk/xlTJP8ZUyT/ + GVMk/xpUJP8aVCT/GlQk/xpUJP8aVCT/GlQk/xpUJP8aVCT/G1co/xtXKP8bVyj/G1co/yeFjf8nhY3/ + J4WN/yeFjf8wqvb/MKr2/zCq9v8wqvb/MKn5/zCp+f8wqfn/MKn5/ymOvf8pjr3/KY69/ymOvf8dXzP/ + HV8z/x1fM/8dXzP/HFsn/xxbJ/8cWyf/HFsn/xxcJ/8cXCf/HFwn/xxcJ/8cXSj/HF0o/xxdKP8cXSj/ + HV0o/x1dKP8dXSj/HV0o/x1fKf8dXyn/HV8p/x1fKf8dYCn/HWAp/x1gKf8dYCn/HmEq/x5hKv8eYSr/ + HmEq/yx4Ov8seDr/LHg6/yx4Ov8lczP/JXMz/yVzM/8lczP/I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/ + I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yNyMf8kdDz/ + JHQ8/yR0PP8kdDz/KY+9/ymPvf8pj73/KY+9/zCp+f8wqfn/MKn5/zCp+f8wqPT/MKj0/zCo9P8wqPT/ + JoGJ/yaBif8mgYn/JoGJ/xlQJf8ZUCX/GVAl/xlQJf8YUCL/GFAi/xhQIv8YUCL/GVAj/xlQI/8ZUCP/ + GVAj/xlSI/8ZUiP/GVIj/xlSI/8ZUyT/GVMk/xlTJP8ZUyT/GlQk/xpUJP8aVCT/GlQk/xpUJP8aVCT/ + GlQk/xpUJP8bVyj/G1co/xtXKP8bVyj/J4WN/yeFjf8nhY3/J4WN/zCq9v8wqvb/MKr2/zCq9v8wqfn/ + MKn5/zCp+f8wqfn/KY69/ymOvf8pjr3/KY69/x1fM/8dXzP/HV8z/x1fM/8cWyf/HFsn/xxbJ/8cWyf/ + HFwn/xxcJ/8cXCf/HFwn/xxdKP8cXSj/HF0o/xxdKP8dXSj/HV0o/x1dKP8dXSj/HV8p/x1fKf8dXyn/ + HV8p/x1gKf8dYCn/HWAp/x1gKf8eYSr/HmEq/x5hKv8eYSr/LHg6/yx4Ov8seDr/LHg6/yVzM/8lczP/ + JXMz/yVzM/8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/ + I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yR0PP8kdDz/JHQ8/yR0PP8pj73/KY+9/ymPvf8pj73/ + MKn5/zCp+f8wqfn/MKn5/zCo9P8wqPT/MKj0/zCo9P8mgYn/JoGJ/yaBif8mgYn/GVAl/xlQJf8ZUCX/ + GVAl/xhQIv8YUCL/GFAi/xhQIv8ZUCP/GVAj/xlQI/8ZUCP/GVIj/xlSI/8ZUiP/GVIj/xlTJP8ZUyT/ + GVMk/xlTJP8aVCT/GlQk/xpUJP8aVCT/GlQk/xpUJP8aVCT/GlQk/xtXKP8bVyj/G1co/xtXKP8nhY3/ + J4WN/yeFjf8nhY3/MKr2/zCq9v8wqvb/MKr2/zCp+f8wqfn/MKn5/zCp+f8pjr3/KY69/ymOvf8pjr3/ + HV8z/x1fM/8dXzP/HV8z/xxbJ/8cWyf/HFsn/xxbJ/8cXCf/HFwn/xxcJ/8cXCf/HF0o/xxdKP8cXSj/ + HF0o/x1dKP8dXSj/HV0o/x1dKP8dXyn/HV8p/x1fKf8dXyn/HWAp/x1gKf8dYCn/HWAp/x5hKv8eYSr/ + HmEq/x5hKv9SkV3/UpFd/1KRXf9SkV3/UpFd/1KRXf9SkV3/UpFd/0mLVf9Ji1X/SYtV/0mLVf8+hEr/ + PoRK/z6ESv8+hEr/M35A/zN+QP8zfkD/M35A/yh3Nv8odzb/KHc2/yh3Nv8kdjv/JHY7/yR2O/8kdjv/ + KpPA/yqTwP8qk8D/KpPA/zGr+/8xq/v/Mav7/zGr+/8unc3/Lp3N/y6dzf8unc3/HWBC/x1gQv8dYEL/ + HWBC/xhOIv8YTiL/GE4i/xhOIv8ZTyL/GU8i/xlPIv8ZTyL/GVAj/xlQI/8ZUCP/GVAj/xlRI/8ZUSP/ + GVEj/xlRI/8ZUiP/GVIj/xlSI/8ZUiP/GlMk/xpTJP8aUyT/GlMk/xpUJP8aVCT/GlQk/xpUJP8aVSX/ + GlUl/xpVJf8aVSX/G1Yl/xtWJf8bViX/G1Yl/xtXJf8bVyX/G1cl/xtXJf8gaEn/IGhJ/yBoSf8gaEn/ + LqDT/y6g0/8uoNP/LqDT/zGr+/8xq/v/Mav7/zGr+/8qk8D/KpPA/yqTwP8qk8D/HmAy/x5gMv8eYDL/ + HmAy/x1cKP8dXCj/HVwo/x1cKP8dXSj/HV0o/x1dKP8dXSj/HV4p/x1eKf8dXin/HV4p/x5fKf8eXyn/ + Hl8p/x5fKf8eYCr/HmAq/x5gKv8eYCr/HmEq/x5hKv8eYSr/HmEq/1KRXf9SkV3/UpFd/1KRXf9SkV3/ + UpFd/1KRXf9SkV3/SYtV/0mLVf9Ji1X/SYtV/z6ESv8+hEr/PoRK/z6ESv8zfkD/M35A/zN+QP8zfkD/ + KHc2/yh3Nv8odzb/KHc2/yR2O/8kdjv/JHY7/yR2O/8qk8D/KpPA/yqTwP8qk8D/Mav7/zGr+/8xq/v/ + Mav7/y6dzf8unc3/Lp3N/y6dzf8dYEL/HWBC/x1gQv8dYEL/GE4i/xhOIv8YTiL/GE4i/xlPIv8ZTyL/ + GU8i/xlPIv8ZUCP/GVAj/xlQI/8ZUCP/GVEj/xlRI/8ZUSP/GVEj/xlSI/8ZUiP/GVIj/xlSI/8aUyT/ + GlMk/xpTJP8aUyT/GlQk/xpUJP8aVCT/GlQk/xpVJf8aVSX/GlUl/xpVJf8bViX/G1Yl/xtWJf8bViX/ + G1cl/xtXJf8bVyX/G1cl/yBoSf8gaEn/IGhJ/yBoSf8uoNP/LqDT/y6g0/8uoNP/Mav7/zGr+/8xq/v/ + Mav7/yqTwP8qk8D/KpPA/yqTwP8eYDL/HmAy/x5gMv8eYDL/HVwo/x1cKP8dXCj/HVwo/x1dKP8dXSj/ + HV0o/x1dKP8dXin/HV4p/x1eKf8dXin/Hl8p/x5fKf8eXyn/Hl8p/x5gKv8eYCr/HmAq/x5gKv8eYSr/ + HmEq/x5hKv8eYSr/UpFd/1KRXf9SkV3/UpFd/1KRXf9SkV3/UpFd/1KRXf9Ji1X/SYtV/0mLVf9Ji1X/ + PoRK/z6ESv8+hEr/PoRK/zN+QP8zfkD/M35A/zN+QP8odzb/KHc2/yh3Nv8odzb/JHY7/yR2O/8kdjv/ + JHY7/yqTwP8qk8D/KpPA/yqTwP8xq/v/Mav7/zGr+/8xq/v/Lp3N/y6dzf8unc3/Lp3N/x1gQv8dYEL/ + HWBC/x1gQv8YTiL/GE4i/xhOIv8YTiL/GU8i/xlPIv8ZTyL/GU8i/xlQI/8ZUCP/GVAj/xlQI/8ZUSP/ + GVEj/xlRI/8ZUSP/GVIj/xlSI/8ZUiP/GVIj/xpTJP8aUyT/GlMk/xpTJP8aVCT/GlQk/xpUJP8aVCT/ + GlUl/xpVJf8aVSX/GlUl/xtWJf8bViX/G1Yl/xtWJf8bVyX/G1cl/xtXJf8bVyX/IGhJ/yBoSf8gaEn/ + IGhJ/y6g0/8uoNP/LqDT/y6g0/8xq/v/Mav7/zGr+/8xq/v/KpPA/yqTwP8qk8D/KpPA/x5gMv8eYDL/ + HmAy/x5gMv8dXCj/HVwo/x1cKP8dXCj/HV0o/x1dKP8dXSj/HV0o/x1eKf8dXin/HV4p/x1eKf8eXyn/ + Hl8p/x5fKf8eXyn/HmAq/x5gKv8eYCr/HmAq/x5hKv8eYSr/HmEq/x5hKv9SkV3/UpFd/1KRXf9SkV3/ + UpFd/1KRXf9SkV3/UpFd/0mLVf9Ji1X/SYtV/0mLVf8+hEr/PoRK/z6ESv8+hEr/M35A/zN+QP8zfkD/ + M35A/yh3Nv8odzb/KHc2/yh3Nv8kdjv/JHY7/yR2O/8kdjv/KpPA/yqTwP8qk8D/KpPA/zGr+/8xq/v/ + Mav7/zGr+/8unc3/Lp3N/y6dzf8unc3/HWBC/x1gQv8dYEL/HWBC/xhOIv8YTiL/GE4i/xhOIv8ZTyL/ + GU8i/xlPIv8ZTyL/GVAj/xlQI/8ZUCP/GVAj/xlRI/8ZUSP/GVEj/xlRI/8ZUiP/GVIj/xlSI/8ZUiP/ + GlMk/xpTJP8aUyT/GlMk/xpUJP8aVCT/GlQk/xpUJP8aVSX/GlUl/xpVJf8aVSX/G1Yl/xtWJf8bViX/ + G1Yl/xtXJf8bVyX/G1cl/xtXJf8gaEn/IGhJ/yBoSf8gaEn/LqDT/y6g0/8uoNP/LqDT/zGr+/8xq/v/ + Mav7/zGr+/8qk8D/KpPA/yqTwP8qk8D/HmAy/x5gMv8eYDL/HmAy/x1cKP8dXCj/HVwo/x1cKP8dXSj/ + HV0o/x1dKP8dXSj/HV4p/x1eKf8dXin/HV4p/x5fKf8eXyn/Hl8p/x5fKf8eYCr/HmAq/x5gKv8eYCr/ + HmEq/x5hKv8eYSr/HmEq/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/ + VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1Smuf9Uprn/ + VKa5/1Smuf9Jtvv/Sbb7/0m2+/9Jtvv/NZy9/zWcvf81nL3/NZy9/1l9Xf9ZfV3/WX1d/1l9Xf9ig2L/ + YoNi/2KDYv9ig2L/Y4Ni/2ODYv9jg2L/Y4Ni/2OEYv9jhGL/Y4Ri/2OEYv9jhWL/Y4Vi/2OFYv9jhWL/ + Y4Vi/2OFYv9jhWL/Y4Vi/2OGY/9jhmP/Y4Zj/2OGY/9jh2P/Y4dj/2OHY/9jh2P/ZIdk/2SHZP9kh2T/ + ZIdk/2SIZP9kiGT/ZIhk/2SIZP9kiWT/ZIlk/2SJZP9kiWT/ZIlk/2SJZP9kiWT/ZIlk/2WKZP9limT/ + ZYpk/2WKZP9ahWL/WoVi/1qFYv9ahWL/MJvC/zCbwv8wm8L/MJvC/zKt+/8yrfv/Mq37/zKt+/8qkKn/ + KpCp/yqQqf8qkKn/HVwo/x1cKP8dXCj/HVwo/x1dKf8dXSn/HV0p/x1dKf8eXin/Hl4p/x5eKf8eXin/ + Hl8p/x5fKf8eXyn/Hl8p/x5gKv8eYCr/HmAq/x5gKv8fYiv/H2Ir/x9iK/8fYiv/VpRh/1aUYf9WlGH/ + VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/ + VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VKa5/1Smuf9Uprn/VKa5/0m2+/9Jtvv/Sbb7/0m2+/81nL3/ + NZy9/zWcvf81nL3/WX1d/1l9Xf9ZfV3/WX1d/2KDYv9ig2L/YoNi/2KDYv9jg2L/Y4Ni/2ODYv9jg2L/ + Y4Ri/2OEYv9jhGL/Y4Ri/2OFYv9jhWL/Y4Vi/2OFYv9jhWL/Y4Vi/2OFYv9jhWL/Y4Zj/2OGY/9jhmP/ + Y4Zj/2OHY/9jh2P/Y4dj/2OHY/9kh2T/ZIdk/2SHZP9kh2T/ZIhk/2SIZP9kiGT/ZIhk/2SJZP9kiWT/ + ZIlk/2SJZP9kiWT/ZIlk/2SJZP9kiWT/ZYpk/2WKZP9limT/ZYpk/1qFYv9ahWL/WoVi/1qFYv8wm8L/ + MJvC/zCbwv8wm8L/Mq37/zKt+/8yrfv/Mq37/yqQqf8qkKn/KpCp/yqQqf8dXCj/HVwo/x1cKP8dXCj/ + HV0p/x1dKf8dXSn/HV0p/x5eKf8eXin/Hl4p/x5eKf8eXyn/Hl8p/x5fKf8eXyn/HmAq/x5gKv8eYCr/ + HmAq/x9iK/8fYiv/H2Ir/x9iK/9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/ + VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9Uprn/ + VKa5/1Smuf9Uprn/Sbb7/0m2+/9Jtvv/Sbb7/zWcvf81nL3/NZy9/zWcvf9ZfV3/WX1d/1l9Xf9ZfV3/ + YoNi/2KDYv9ig2L/YoNi/2ODYv9jg2L/Y4Ni/2ODYv9jhGL/Y4Ri/2OEYv9jhGL/Y4Vi/2OFYv9jhWL/ + Y4Vi/2OFYv9jhWL/Y4Vi/2OFYv9jhmP/Y4Zj/2OGY/9jhmP/Y4dj/2OHY/9jh2P/Y4dj/2SHZP9kh2T/ + ZIdk/2SHZP9kiGT/ZIhk/2SIZP9kiGT/ZIlk/2SJZP9kiWT/ZIlk/2SJZP9kiWT/ZIlk/2SJZP9limT/ + ZYpk/2WKZP9limT/WoVi/1qFYv9ahWL/WoVi/zCbwv8wm8L/MJvC/zCbwv8yrfv/Mq37/zKt+/8yrfv/ + KpCp/yqQqf8qkKn/KpCp/x1cKP8dXCj/HVwo/x1cKP8dXSn/HV0p/x1dKf8dXSn/Hl4p/x5eKf8eXin/ + Hl4p/x5fKf8eXyn/Hl8p/x5fKf8eYCr/HmAq/x5gKv8eYCr/H2Ir/x9iK/8fYiv/H2Ir/1aUYf9WlGH/ + VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/ + VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1Smuf9Uprn/VKa5/1Smuf9Jtvv/Sbb7/0m2+/9Jtvv/ + NZy9/zWcvf81nL3/NZy9/1l9Xf9ZfV3/WX1d/1l9Xf9ig2L/YoNi/2KDYv9ig2L/Y4Ni/2ODYv9jg2L/ + Y4Ni/2OEYv9jhGL/Y4Ri/2OEYv9jhWL/Y4Vi/2OFYv9jhWL/Y4Vi/2OFYv9jhWL/Y4Vi/2OGY/9jhmP/ + Y4Zj/2OGY/9jh2P/Y4dj/2OHY/9jh2P/ZIdk/2SHZP9kh2T/ZIdk/2SIZP9kiGT/ZIhk/2SIZP9kiWT/ + ZIlk/2SJZP9kiWT/ZIlk/2SJZP9kiWT/ZIlk/2WKZP9limT/ZYpk/2WKZP9ahWL/WoVi/1qFYv9ahWL/ + MJvC/zCbwv8wm8L/MJvC/zKt+/8yrfv/Mq37/zKt+/8qkKn/KpCp/yqQqf8qkKn/HVwo/x1cKP8dXCj/ + HVwo/x1dKf8dXSn/HV0p/x1dKf8eXin/Hl4p/x5eKf8eXin/Hl8p/x5fKf8eXyn/Hl8p/x5gKv8eYCr/ + HmAq/x5gKv8fYiv/H2Ir/x9iK/8fYiv/WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/ + WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/WJdl/1iXZf9bn4j/W5+I/1ufiP9bn4j/ + YsD6/2LA+v9iwPr/YsD6/16xzf9esc3/XrHN/16xzf/O1Mb/ztTG/87Uxv/O1Mb/19nN/9fZzf/X2c3/ + 19nN/8TKuv/Eyrr/xMq6/8TKuv+/xrT/v8a0/7/GtP+/xrT/v8az/7/Gs/+/xrP/v8az/7/Gs/+/xrP/ + v8az/7/Gs/+/xrP/v8az/7/Gs/+/xrP/v8e0/7/HtP+/x7T/v8e0/7/HtP+/x7T/v8e0/7/HtP+/x7T/ + v8e0/7/HtP+/x7T/v8e0/7/HtP+/x7T/v8e0/7/ItP+/yLT/v8i0/7/ItP+/yLT/v8i0/7/ItP+/yLT/ + v8i0/7/ItP+/yLT/v8i0/83Swv/N0sL/zdLC/83Swv++ybb/vsm2/77Jtv++ybb/Lp3D/y6dw/8uncP/ + Lp3D/zKt+v8yrfr/Mq36/zKt+v8jdV7/I3Ve/yN1Xv8jdV7/HV4q/x1eKv8dXir/HV4q/x1fKv8dXyr/ + HV8q/x1fKv8eYCv/HmAr/x5gK/8eYCv/HmEr/x5hK/8eYSv/HmEr/x5iLP8eYiz/HmIs/x5iLP9Yl2X/ + WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/ + WJdl/1iXZf9Yl2X/WJdl/1ufiP9bn4j/W5+I/1ufiP9iwPr/YsD6/2LA+v9iwPr/XrHN/16xzf9esc3/ + XrHN/87Uxv/O1Mb/ztTG/87Uxv/X2c3/19nN/9fZzf/X2c3/xMq6/8TKuv/Eyrr/xMq6/7/GtP+/xrT/ + v8a0/7/GtP+/xrP/v8az/7/Gs/+/xrP/v8az/7/Gs/+/xrP/v8az/7/Gs/+/xrP/v8az/7/Gs/+/x7T/ + v8e0/7/HtP+/x7T/v8e0/7/HtP+/x7T/v8e0/7/HtP+/x7T/v8e0/7/HtP+/x7T/v8e0/7/HtP+/x7T/ + v8i0/7/ItP+/yLT/v8i0/7/ItP+/yLT/v8i0/7/ItP+/yLT/v8i0/7/ItP+/yLT/zdLC/83Swv/N0sL/ + zdLC/77Jtv++ybb/vsm2/77Jtv8uncP/Lp3D/y6dw/8uncP/Mq36/zKt+v8yrfr/Mq36/yN1Xv8jdV7/ + I3Ve/yN1Xv8dXir/HV4q/x1eKv8dXir/HV8q/x1fKv8dXyr/HV8q/x5gK/8eYCv/HmAr/x5gK/8eYSv/ + HmEr/x5hK/8eYSv/HmIs/x5iLP8eYiz/HmIs/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/ + WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/W5+I/1ufiP9bn4j/ + W5+I/2LA+v9iwPr/YsD6/2LA+v9esc3/XrHN/16xzf9esc3/ztTG/87Uxv/O1Mb/ztTG/9fZzf/X2c3/ + 19nN/9fZzf/Eyrr/xMq6/8TKuv/Eyrr/v8a0/7/GtP+/xrT/v8a0/7/Gs/+/xrP/v8az/7/Gs/+/xrP/ + v8az/7/Gs/+/xrP/v8az/7/Gs/+/xrP/v8az/7/HtP+/x7T/v8e0/7/HtP+/x7T/v8e0/7/HtP+/x7T/ + v8e0/7/HtP+/x7T/v8e0/7/HtP+/x7T/v8e0/7/HtP+/yLT/v8i0/7/ItP+/yLT/v8i0/7/ItP+/yLT/ + v8i0/7/ItP+/yLT/v8i0/7/ItP/N0sL/zdLC/83Swv/N0sL/vsm2/77Jtv++ybb/vsm2/y6dw/8uncP/ + Lp3D/y6dw/8yrfr/Mq36/zKt+v8yrfr/I3Ve/yN1Xv8jdV7/I3Ve/x1eKv8dXir/HV4q/x1eKv8dXyr/ + HV8q/x1fKv8dXyr/HmAr/x5gK/8eYCv/HmAr/x5hK/8eYSv/HmEr/x5hK/8eYiz/HmIs/x5iLP8eYiz/ + WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/ + WJdl/1iXZf9Yl2X/WJdl/1iXZf9bn4j/W5+I/1ufiP9bn4j/YsD6/2LA+v9iwPr/YsD6/16xzf9esc3/ + XrHN/16xzf/O1Mb/ztTG/87Uxv/O1Mb/19nN/9fZzf/X2c3/19nN/8TKuv/Eyrr/xMq6/8TKuv+/xrT/ + v8a0/7/GtP+/xrT/v8az/7/Gs/+/xrP/v8az/7/Gs/+/xrP/v8az/7/Gs/+/xrP/v8az/7/Gs/+/xrP/ + v8e0/7/HtP+/x7T/v8e0/7/HtP+/x7T/v8e0/7/HtP+/x7T/v8e0/7/HtP+/x7T/v8e0/7/HtP+/x7T/ + v8e0/7/ItP+/yLT/v8i0/7/ItP+/yLT/v8i0/7/ItP+/yLT/v8i0/7/ItP+/yLT/v8i0/83Swv/N0sL/ + zdLC/83Swv++ybb/vsm2/77Jtv++ybb/Lp3D/y6dw/8uncP/Lp3D/zKt+v8yrfr/Mq36/zKt+v8jdV7/ + I3Ve/yN1Xv8jdV7/HV4q/x1eKv8dXir/HV4q/x1fKv8dXyr/HV8q/x1fKv8eYCv/HmAr/x5gK/8eYCv/ + HmEr/x5hK/8eYSv/HmEr/x5iLP8eYiz/HmIs/x5iLP9cmmj/XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/ + XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/XJpo/2W73/9lu9// + Zbvf/2W73/9lv+3/Zb/t/2W/7f9lv+3/VIBm/1SAZv9UgGb/VIBm//v07f/79O3/+/Tt//v07f9fgmT/ + X4Jk/1+CZP9fgmT/Unpa/1J6Wv9Selr/Unpa/1B4WP9QeFj/UHhY/1B4WP88akX/PGpF/zxqRf88akX/ + IFUr/yBVK/8gVSv/IFUr/xpRJP8aUST/GlEk/xpRJP8nWzH/J1sx/ydbMf8nWzH/J1wx/ydcMf8nXDH/ + J1wx/xtUJv8bVCb/G1Qm/xtUJv8bVSb/G1Um/xtVJv8bVSb/G1Yn/xtWJ/8bVif/G1Yn/xxXJ/8cVyf/ + HFcn/xxXJ/8cWCj/HFgo/xxYKP8cWCj/LGQ1/yxkNf8sZDX/LGQ1//nw5//58Of/+fDn//nw5/8gZT7/ + IGU+/yBlPv8gZT7/Mqrr/zKq6/8yquv/Mqrr/zGk1/8xpNf/MaTX/zGk1/8eXir/Hl4q/x5eKv8eXir/ + Hl8r/x5fK/8eXyv/Hl8r/x5gK/8eYCv/HmAr/x5gK/8fYCv/H2Ar/x9gK/8fYCv/H2Is/x9iLP8fYiz/ + H2Is/1yaaP9cmmj/XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/ + XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/Zbvf/2W73/9lu9//Zbvf/2W/7f9lv+3/Zb/t/2W/7f9UgGb/ + VIBm/1SAZv9UgGb/+/Tt//v07f/79O3/+/Tt/1+CZP9fgmT/X4Jk/1+CZP9Selr/Unpa/1J6Wv9Selr/ + UHhY/1B4WP9QeFj/UHhY/zxqRf88akX/PGpF/zxqRf8gVSv/IFUr/yBVK/8gVSv/GlEk/xpRJP8aUST/ + GlEk/ydbMf8nWzH/J1sx/ydbMf8nXDH/J1wx/ydcMf8nXDH/G1Qm/xtUJv8bVCb/G1Qm/xtVJv8bVSb/ + G1Um/xtVJv8bVif/G1Yn/xtWJ/8bVif/HFcn/xxXJ/8cVyf/HFcn/xxYKP8cWCj/HFgo/xxYKP8sZDX/ + LGQ1/yxkNf8sZDX/+fDn//nw5//58Of/+fDn/yBlPv8gZT7/IGU+/yBlPv8yquv/Mqrr/zKq6/8yquv/ + MaTX/zGk1/8xpNf/MaTX/x5eKv8eXir/Hl4q/x5eKv8eXyv/Hl8r/x5fK/8eXyv/HmAr/x5gK/8eYCv/ + HmAr/x9gK/8fYCv/H2Ar/x9gK/8fYiz/H2Is/x9iLP8fYiz/XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/ + XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/XJpo/1yaaP9lu9// + Zbvf/2W73/9lu9//Zb/t/2W/7f9lv+3/Zb/t/1SAZv9UgGb/VIBm/1SAZv/79O3/+/Tt//v07f/79O3/ + X4Jk/1+CZP9fgmT/X4Jk/1J6Wv9Selr/Unpa/1J6Wv9QeFj/UHhY/1B4WP9QeFj/PGpF/zxqRf88akX/ + PGpF/yBVK/8gVSv/IFUr/yBVK/8aUST/GlEk/xpRJP8aUST/J1sx/ydbMf8nWzH/J1sx/ydcMf8nXDH/ + J1wx/ydcMf8bVCb/G1Qm/xtUJv8bVCb/G1Um/xtVJv8bVSb/G1Um/xtWJ/8bVif/G1Yn/xtWJ/8cVyf/ + HFcn/xxXJ/8cVyf/HFgo/xxYKP8cWCj/HFgo/yxkNf8sZDX/LGQ1/yxkNf/58Of/+fDn//nw5//58Of/ + IGU+/yBlPv8gZT7/IGU+/zKq6/8yquv/Mqrr/zKq6/8xpNf/MaTX/zGk1/8xpNf/Hl4q/x5eKv8eXir/ + Hl4q/x5fK/8eXyv/Hl8r/x5fK/8eYCv/HmAr/x5gK/8eYCv/H2Ar/x9gK/8fYCv/H2Ar/x9iLP8fYiz/ + H2Is/x9iLP9cmmj/XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/ + XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/XJpo/2W73/9lu9//Zbvf/2W73/9lv+3/Zb/t/2W/7f9lv+3/ + VIBm/1SAZv9UgGb/VIBm//v07f/79O3/+/Tt//v07f9fgmT/X4Jk/1+CZP9fgmT/Unpa/1J6Wv9Selr/ + Unpa/1B4WP9QeFj/UHhY/1B4WP88akX/PGpF/zxqRf88akX/IFUr/yBVK/8gVSv/IFUr/xpRJP8aUST/ + GlEk/xpRJP8nWzH/J1sx/ydbMf8nWzH/J1wx/ydcMf8nXDH/J1wx/xtUJv8bVCb/G1Qm/xtUJv8bVSb/ + G1Um/xtVJv8bVSb/G1Yn/xtWJ/8bVif/G1Yn/xxXJ/8cVyf/HFcn/xxXJ/8cWCj/HFgo/xxYKP8cWCj/ + LGQ1/yxkNf8sZDX/LGQ1//nw5//58Of/+fDn//nw5/8gZT7/IGU+/yBlPv8gZT7/Mqrr/zKq6/8yquv/ + Mqrr/zGk1/8xpNf/MaTX/zGk1/8eXir/Hl4q/x5eKv8eXir/Hl8r/x5fK/8eXyv/Hl8r/x5gK/8eYCv/ + HmAr/x5gK/8fYCv/H2Ar/x9gK/8fYCv/H2Is/x9iLP8fYiz/H2Is/2CdbP9gnWz/YJ1s/2CdbP9gnWz/ + YJ1s/2CdbP9gnWz/YJ1s/2CdbP9gnWz/YJ1s/2CdbP9gnWz/YJ1s/2CdbP9ho4P/YaOD/2Gjg/9ho4P/ + acX8/2nF/P9pxfz/acX8/2Cgof9goKH/YKCh/2Cgof9Velz/VXpc/1V6XP9Velz/+/Xw//v18P/79fD/ + +/Xw/1+DZv9fg2b/X4Nm/1+DZv9VfV7/VX1e/1V9Xv9VfV7/VX1e/1V9Xv9VfV7/VX1e/1V9Xv9VfV7/ + VX1e/1V9Xv9UfV3/VH1d/1R9Xf9UfV3/PGtF/zxrRf88a0X/PGtF/5Cnjv+Qp47/kKeO/5Cnjv+Ppoz/ + j6aM/4+mjP+Ppoz/G1Qn/xtUJ/8bVCf/G1Qn/xtVJ/8bVSf/G1Un/xtVJ/8cVij/HFYo/xxWKP8cVij/ + HFgo/xxYKP8cWCj/HFgo/xxZKf8cWSn/HFkp/xxZKf8rYjX/K2I1/ytiNf8rYjX/+vLq//ry6v/68ur/ + +vLq/x1bKv8dWyr/HVsq/x1bKv8piIf/KYiH/ymIh/8piIf/M7D7/zOw+/8zsPv/M7D7/yNwUP8jcFD/ + I3BQ/yNwUP8eXyz/Hl8s/x5fLP8eXyz/H2As/x9gLP8fYCz/H2As/x9hLf8fYS3/H2Et/x9hLf8gYy3/ + IGMt/yBjLf8gYy3/YJ1s/2CdbP9gnWz/YJ1s/2CdbP9gnWz/YJ1s/2CdbP9gnWz/YJ1s/2CdbP9gnWz/ + YJ1s/2CdbP9gnWz/YJ1s/2Gjg/9ho4P/YaOD/2Gjg/9pxfz/acX8/2nF/P9pxfz/YKCh/2Cgof9goKH/ + YKCh/1V6XP9Velz/VXpc/1V6XP/79fD/+/Xw//v18P/79fD/X4Nm/1+DZv9fg2b/X4Nm/1V9Xv9VfV7/ + VX1e/1V9Xv9VfV7/VX1e/1V9Xv9VfV7/VX1e/1V9Xv9VfV7/VX1e/1R9Xf9UfV3/VH1d/1R9Xf88a0X/ + PGtF/zxrRf88a0X/kKeO/5Cnjv+Qp47/kKeO/4+mjP+Ppoz/j6aM/4+mjP8bVCf/G1Qn/xtUJ/8bVCf/ + G1Un/xtVJ/8bVSf/G1Un/xxWKP8cVij/HFYo/xxWKP8cWCj/HFgo/xxYKP8cWCj/HFkp/xxZKf8cWSn/ + HFkp/ytiNf8rYjX/K2I1/ytiNf/68ur/+vLq//ry6v/68ur/HVsq/x1bKv8dWyr/HVsq/ymIh/8piIf/ + KYiH/ymIh/8zsPv/M7D7/zOw+/8zsPv/I3BQ/yNwUP8jcFD/I3BQ/x5fLP8eXyz/Hl8s/x5fLP8fYCz/ + H2As/x9gLP8fYCz/H2Et/x9hLf8fYS3/H2Et/yBjLf8gYy3/IGMt/yBjLf9gnWz/YJ1s/2CdbP9gnWz/ + YJ1s/2CdbP9gnWz/YJ1s/2CdbP9gnWz/YJ1s/2CdbP9gnWz/YJ1s/2CdbP9gnWz/YaOD/2Gjg/9ho4P/ + YaOD/2nF/P9pxfz/acX8/2nF/P9goKH/YKCh/2Cgof9goKH/VXpc/1V6XP9Velz/VXpc//v18P/79fD/ + +/Xw//v18P9fg2b/X4Nm/1+DZv9fg2b/VX1e/1V9Xv9VfV7/VX1e/1V9Xv9VfV7/VX1e/1V9Xv9VfV7/ + VX1e/1V9Xv9VfV7/VH1d/1R9Xf9UfV3/VH1d/zxrRf88a0X/PGtF/zxrRf+Qp47/kKeO/5Cnjv+Qp47/ + j6aM/4+mjP+Ppoz/j6aM/xtUJ/8bVCf/G1Qn/xtUJ/8bVSf/G1Un/xtVJ/8bVSf/HFYo/xxWKP8cVij/ + HFYo/xxYKP8cWCj/HFgo/xxYKP8cWSn/HFkp/xxZKf8cWSn/K2I1/ytiNf8rYjX/K2I1//ry6v/68ur/ + +vLq//ry6v8dWyr/HVsq/x1bKv8dWyr/KYiH/ymIh/8piIf/KYiH/zOw+/8zsPv/M7D7/zOw+/8jcFD/ + I3BQ/yNwUP8jcFD/Hl8s/x5fLP8eXyz/Hl8s/x9gLP8fYCz/H2As/x9gLP8fYS3/H2Et/x9hLf8fYS3/ + IGMt/yBjLf8gYy3/IGMt/2CdbP9gnWz/YJ1s/2CdbP9gnWz/YJ1s/2CdbP9gnWz/YJ1s/2CdbP9gnWz/ + YJ1s/2CdbP9gnWz/YJ1s/2CdbP9ho4P/YaOD/2Gjg/9ho4P/acX8/2nF/P9pxfz/acX8/2Cgof9goKH/ + YKCh/2Cgof9Velz/VXpc/1V6XP9Velz/+/Xw//v18P/79fD/+/Xw/1+DZv9fg2b/X4Nm/1+DZv9VfV7/ + VX1e/1V9Xv9VfV7/VX1e/1V9Xv9VfV7/VX1e/1V9Xv9VfV7/VX1e/1V9Xv9UfV3/VH1d/1R9Xf9UfV3/ + PGtF/zxrRf88a0X/PGtF/5Cnjv+Qp47/kKeO/5Cnjv+Ppoz/j6aM/4+mjP+Ppoz/G1Qn/xtUJ/8bVCf/ + G1Qn/xtVJ/8bVSf/G1Un/xtVJ/8cVij/HFYo/xxWKP8cVij/HFgo/xxYKP8cWCj/HFgo/xxZKf8cWSn/ + HFkp/xxZKf8rYjX/K2I1/ytiNf8rYjX/+vLq//ry6v/68ur/+vLq/x1bKv8dWyr/HVsq/x1bKv8piIf/ + KYiH/ymIh/8piIf/M7D7/zOw+/8zsPv/M7D7/yNwUP8jcFD/I3BQ/yNwUP8eXyz/Hl8s/x5fLP8eXyz/ + H2As/x9gLP8fYCz/H2As/x9hLf8fYS3/H2Et/x9hLf8gYy3/IGMt/yBjLf8gYy3/Y59v/2Ofb/9jn2// + Y59v/2Ofb/9jn2//Y59v/2Ofb/9jn2//Y59v/2Ofb/9jn2//Y59v/2Ofb/9jn2//Y59v/2eztP9ns7T/ + Z7O0/2eztP9rxff/a8X3/2vF9/9rxff/WYFq/1mBav9ZgWr/WYFq/1d8X/9XfF//V3xf/1d8X//89vH/ + /Pbx//z28f/89vH/YoRp/2KEaf9ihGn/YoRp/1h+YP9YfmD/WH5g/1h+YP9Yf2D/WH9g/1h/YP9Yf2D/ + WX9h/1l/Yf9Zf2H/WX9h/1mAYf9ZgGH/WYBh/1mAYf9ZgWL/WYFi/1mBYv9ZgWL/r7+t/6+/rf+vv63/ + r7+t/6G0nv+htJ7/obSe/6G0nv8eVir/HlYq/x5WKv8eVir/HFUn/xxVJ/8cVSf/HFUn/xxWKP8cVij/ + HFYo/xxWKP8cVyj/HFco/xxXKP8cVyj/HVgp/x1YKf8dWCn/HVgp/ytiNf8rYjX/K2I1/ytiNf/78+z/ + +/Ps//vz7P/78+z/Hlsq/x5bKv8eWyr/Hlsq/yBmPf8gZj3/IGY9/yBmPf80sPf/NLD3/zSw9/80sPf/ + K5CX/yuQl/8rkJf/K5CX/x9fLP8fXyz/H18s/x9fLP8fYCz/H2As/x9gLP8fYCz/IGEt/yBhLf8gYS3/ + IGEt/yBiLv8gYi7/IGIu/yBiLv9jn2//Y59v/2Ofb/9jn2//Y59v/2Ofb/9jn2//Y59v/2Ofb/9jn2// + Y59v/2Ofb/9jn2//Y59v/2Ofb/9jn2//Z7O0/2eztP9ns7T/Z7O0/2vF9/9rxff/a8X3/2vF9/9ZgWr/ + WYFq/1mBav9ZgWr/V3xf/1d8X/9XfF//V3xf//z28f/89vH//Pbx//z28f9ihGn/YoRp/2KEaf9ihGn/ + WH5g/1h+YP9YfmD/WH5g/1h/YP9Yf2D/WH9g/1h/YP9Zf2H/WX9h/1l/Yf9Zf2H/WYBh/1mAYf9ZgGH/ + WYBh/1mBYv9ZgWL/WYFi/1mBYv+vv63/r7+t/6+/rf+vv63/obSe/6G0nv+htJ7/obSe/x5WKv8eVir/ + HlYq/x5WKv8cVSf/HFUn/xxVJ/8cVSf/HFYo/xxWKP8cVij/HFYo/xxXKP8cVyj/HFco/xxXKP8dWCn/ + HVgp/x1YKf8dWCn/K2I1/ytiNf8rYjX/K2I1//vz7P/78+z/+/Ps//vz7P8eWyr/Hlsq/x5bKv8eWyr/ + IGY9/yBmPf8gZj3/IGY9/zSw9/80sPf/NLD3/zSw9/8rkJf/K5CX/yuQl/8rkJf/H18s/x9fLP8fXyz/ + H18s/x9gLP8fYCz/H2As/x9gLP8gYS3/IGEt/yBhLf8gYS3/IGIu/yBiLv8gYi7/IGIu/2Ofb/9jn2// + Y59v/2Ofb/9jn2//Y59v/2Ofb/9jn2//Y59v/2Ofb/9jn2//Y59v/2Ofb/9jn2//Y59v/2Ofb/9ns7T/ + Z7O0/2eztP9ns7T/a8X3/2vF9/9rxff/a8X3/1mBav9ZgWr/WYFq/1mBav9XfF//V3xf/1d8X/9XfF// + /Pbx//z28f/89vH//Pbx/2KEaf9ihGn/YoRp/2KEaf9YfmD/WH5g/1h+YP9YfmD/WH9g/1h/YP9Yf2D/ + WH9g/1l/Yf9Zf2H/WX9h/1l/Yf9ZgGH/WYBh/1mAYf9ZgGH/WYFi/1mBYv9ZgWL/WYFi/6+/rf+vv63/ + r7+t/6+/rf+htJ7/obSe/6G0nv+htJ7/HlYq/x5WKv8eVir/HlYq/xxVJ/8cVSf/HFUn/xxVJ/8cVij/ + HFYo/xxWKP8cVij/HFco/xxXKP8cVyj/HFco/x1YKf8dWCn/HVgp/x1YKf8rYjX/K2I1/ytiNf8rYjX/ + +/Ps//vz7P/78+z/+/Ps/x5bKv8eWyr/Hlsq/x5bKv8gZj3/IGY9/yBmPf8gZj3/NLD3/zSw9/80sPf/ + NLD3/yuQl/8rkJf/K5CX/yuQl/8fXyz/H18s/x9fLP8fXyz/H2As/x9gLP8fYCz/H2As/yBhLf8gYS3/ + IGEt/yBhLf8gYi7/IGIu/yBiLv8gYi7/Y59v/2Ofb/9jn2//Y59v/2Ofb/9jn2//Y59v/2Ofb/9jn2// + Y59v/2Ofb/9jn2//Y59v/2Ofb/9jn2//Y59v/2eztP9ns7T/Z7O0/2eztP9rxff/a8X3/2vF9/9rxff/ + WYFq/1mBav9ZgWr/WYFq/1d8X/9XfF//V3xf/1d8X//89vH//Pbx//z28f/89vH/YoRp/2KEaf9ihGn/ + YoRp/1h+YP9YfmD/WH5g/1h+YP9Yf2D/WH9g/1h/YP9Yf2D/WX9h/1l/Yf9Zf2H/WX9h/1mAYf9ZgGH/ + WYBh/1mAYf9ZgWL/WYFi/1mBYv9ZgWL/r7+t/6+/rf+vv63/r7+t/6G0nv+htJ7/obSe/6G0nv8eVir/ + HlYq/x5WKv8eVir/HFUn/xxVJ/8cVSf/HFUn/xxWKP8cVij/HFYo/xxWKP8cVyj/HFco/xxXKP8cVyj/ + HVgp/x1YKf8dWCn/HVgp/ytiNf8rYjX/K2I1/ytiNf/78+z/+/Ps//vz7P/78+z/Hlsq/x5bKv8eWyr/ + Hlsq/yBmPf8gZj3/IGY9/yBmPf80sPf/NLD3/zSw9/80sPf/K5CX/yuQl/8rkJf/K5CX/x9fLP8fXyz/ + H18s/x9fLP8fYCz/H2As/x9gLP8fYCz/IGEt/yBhLf8gYS3/IGEt/yBiLv8gYi7/IGIu/yBiLv9no3P/ + Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9no3P/ + bb7X/22+1/9tvtf/bb7X/2y81/9svNf/bLzX/2y81/9bfmL/W35i/1t+Yv9bfmL/W39j/1t/Y/9bf2P/ + W39j//z48//8+PP//Pjz//z48/9mh2z/Zods/2aHbP9mh2z/XIFk/1yBZP9cgWT/XIFk/1yBZP9cgWT/ + XIFk/1yBZP9miG3/Zoht/2aIbf9miG3/sMCv/7DAr/+wwK//sMCv/7LCsf+ywrH/ssKx/7LCsf/Z3tT/ + 2d7U/9ne1P/Z3tT/2d7U/9ne1P/Z3tT/2d7U/6/Arf+vwK3/r8Ct/6/Arf+bspr/m7Ka/5uymv+bspr/ + KV80/ylfNP8pXzT/KV80/x1XKP8dVyj/HVco/x1XKP8dWCn/HVgp/x1YKf8dWCn/K2M2/ytjNv8rYzb/ + K2M2//v17v/79e7/+/Xu//v17v8eXCv/Hlwr/x5cK/8eXCv/Hl0r/x5dK/8eXSv/Hl0r/zGjy/8xo8v/ + MaPL/zGjy/8wosb/MKLG/zCixv8wosb/H2As/x9gLP8fYCz/H2As/yBhLf8gYS3/IGEt/yBhLf8gYi3/ + IGIt/yBiLf8gYi3/IGMu/yBjLv8gYy7/IGMu/2ejc/9no3P/Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9no3P/ + Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9tvtf/bb7X/22+1/9tvtf/bLzX/2y81/9svNf/ + bLzX/1t+Yv9bfmL/W35i/1t+Yv9bf2P/W39j/1t/Y/9bf2P//Pjz//z48//8+PP//Pjz/2aHbP9mh2z/ + Zods/2aHbP9cgWT/XIFk/1yBZP9cgWT/XIFk/1yBZP9cgWT/XIFk/2aIbf9miG3/Zoht/2aIbf+wwK// + sMCv/7DAr/+wwK//ssKx/7LCsf+ywrH/ssKx/9ne1P/Z3tT/2d7U/9ne1P/Z3tT/2d7U/9ne1P/Z3tT/ + r8Ct/6/Arf+vwK3/r8Ct/5uymv+bspr/m7Ka/5uymv8pXzT/KV80/ylfNP8pXzT/HVco/x1XKP8dVyj/ + HVco/x1YKf8dWCn/HVgp/x1YKf8rYzb/K2M2/ytjNv8rYzb/+/Xu//v17v/79e7/+/Xu/x5cK/8eXCv/ + Hlwr/x5cK/8eXSv/Hl0r/x5dK/8eXSv/MaPL/zGjy/8xo8v/MaPL/zCixv8wosb/MKLG/zCixv8fYCz/ + H2As/x9gLP8fYCz/IGEt/yBhLf8gYS3/IGEt/yBiLf8gYi3/IGIt/yBiLf8gYy7/IGMu/yBjLv8gYy7/ + Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9no3P/ + Z6Nz/22+1/9tvtf/bb7X/22+1/9svNf/bLzX/2y81/9svNf/W35i/1t+Yv9bfmL/W35i/1t/Y/9bf2P/ + W39j/1t/Y//8+PP//Pjz//z48//8+PP/Zods/2aHbP9mh2z/Zods/1yBZP9cgWT/XIFk/1yBZP9cgWT/ + XIFk/1yBZP9cgWT/Zoht/2aIbf9miG3/Zoht/7DAr/+wwK//sMCv/7DAr/+ywrH/ssKx/7LCsf+ywrH/ + 2d7U/9ne1P/Z3tT/2d7U/9ne1P/Z3tT/2d7U/9ne1P+vwK3/r8Ct/6/Arf+vwK3/m7Ka/5uymv+bspr/ + m7Ka/ylfNP8pXzT/KV80/ylfNP8dVyj/HVco/x1XKP8dVyj/HVgp/x1YKf8dWCn/HVgp/ytjNv8rYzb/ + K2M2/ytjNv/79e7/+/Xu//v17v/79e7/Hlwr/x5cK/8eXCv/Hlwr/x5dK/8eXSv/Hl0r/x5dK/8xo8v/ + MaPL/zGjy/8xo8v/MKLG/zCixv8wosb/MKLG/x9gLP8fYCz/H2As/x9gLP8gYS3/IGEt/yBhLf8gYS3/ + IGIt/yBiLf8gYi3/IGIt/yBjLv8gYy7/IGMu/yBjLv9no3P/Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9no3P/ + Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9no3P/bb7X/22+1/9tvtf/bb7X/2y81/9svNf/ + bLzX/2y81/9bfmL/W35i/1t+Yv9bfmL/W39j/1t/Y/9bf2P/W39j//z48//8+PP//Pjz//z48/9mh2z/ + Zods/2aHbP9mh2z/XIFk/1yBZP9cgWT/XIFk/1yBZP9cgWT/XIFk/1yBZP9miG3/Zoht/2aIbf9miG3/ + sMCv/7DAr/+wwK//sMCv/7LCsf+ywrH/ssKx/7LCsf/Z3tT/2d7U/9ne1P/Z3tT/2d7U/9ne1P/Z3tT/ + 2d7U/6/Arf+vwK3/r8Ct/6/Arf+bspr/m7Ka/5uymv+bspr/KV80/ylfNP8pXzT/KV80/x1XKP8dVyj/ + HVco/x1XKP8dWCn/HVgp/x1YKf8dWCn/K2M2/ytjNv8rYzb/K2M2//v17v/79e7/+/Xu//v17v8eXCv/ + Hlwr/x5cK/8eXCv/Hl0r/x5dK/8eXSv/Hl0r/zGjy/8xo8v/MaPL/zGjy/8wosb/MKLG/zCixv8wosb/ + H2As/x9gLP8fYCz/H2As/yBhLf8gYS3/IGEt/yBhLf8gYi3/IGIt/yBiLf8gYi3/IGMu/yBjLv8gYy7/ + IGMu/2qld/9qpXf/aqV3/2qld/9qpXf/aqV3/2qld/9qpXf/aqV3/2qld/9qpXf/aqV3/2qld/9qpXf/ + aqV3/2qld/9xxuz/ccbs/3HG7P9xxuz/bLO//2yzv/9ss7//bLO//16AZf9egGX/XoBl/16AZf9egWX/ + XoFl/16BZf9egWX//fn1//359f/9+fX//fn1/2iJb/9oiW//aIlv/2iJb/9eg2f/XoNn/16DZ/9eg2f/ + XoNn/16DZ/9eg2f/XoNn/2iKcP9oinD/aIpw/2iKcP+xwbH/scGx/7HBsf+xwbH/s8Oz/7PDs/+zw7P/ + s8Oz/9vg1v/b4Nb/2+DW/9vg1v/b4Nb/2+DW/9vg1v/b4Nb/tMS0/7TEtP+0xLT/tMS0/7LDsv+yw7L/ + ssOy/7LDsv9Sflz/Un5c/1J+XP9Sflz/IFos/yBaLP8gWiz/IFos/x1YKv8dWCr/HVgq/x1YKv8rYjb/ + K2I2/ytiNv8rYjb//Pbw//z28P/89vD//Pbw/x5bLP8eWyz/Hlss/x5bLP8eXCz/Hlws/x5cLP8eXCz/ + Lpiq/y6Yqv8umKr/Lpiq/zSt5f80reX/NK3l/zSt5f8fXy3/H18t/x9fLf8fXy3/H2Au/x9gLv8fYC7/ + H2Au/yBhLv8gYS7/IGEu/yBhLv8gYy//IGMv/yBjL/8gYy//aqV3/2qld/9qpXf/aqV3/2qld/9qpXf/ + aqV3/2qld/9qpXf/aqV3/2qld/9qpXf/aqV3/2qld/9qpXf/aqV3/3HG7P9xxuz/ccbs/3HG7P9ss7// + bLO//2yzv/9ss7//XoBl/16AZf9egGX/XoBl/16BZf9egWX/XoFl/16BZf/9+fX//fn1//359f/9+fX/ + aIlv/2iJb/9oiW//aIlv/16DZ/9eg2f/XoNn/16DZ/9eg2f/XoNn/16DZ/9eg2f/aIpw/2iKcP9oinD/ + aIpw/7HBsf+xwbH/scGx/7HBsf+zw7P/s8Oz/7PDs/+zw7P/2+DW/9vg1v/b4Nb/2+DW/9vg1v/b4Nb/ + 2+DW/9vg1v+0xLT/tMS0/7TEtP+0xLT/ssOy/7LDsv+yw7L/ssOy/1J+XP9Sflz/Un5c/1J+XP8gWiz/ + IFos/yBaLP8gWiz/HVgq/x1YKv8dWCr/HVgq/ytiNv8rYjb/K2I2/ytiNv/89vD//Pbw//z28P/89vD/ + Hlss/x5bLP8eWyz/Hlss/x5cLP8eXCz/Hlws/x5cLP8umKr/Lpiq/y6Yqv8umKr/NK3l/zSt5f80reX/ + NK3l/x9fLf8fXy3/H18t/x9fLf8fYC7/H2Au/x9gLv8fYC7/IGEu/yBhLv8gYS7/IGEu/yBjL/8gYy// + IGMv/yBjL/9qpXf/aqV3/2qld/9qpXf/aqV3/2qld/9qpXf/aqV3/2qld/9qpXf/aqV3/2qld/9qpXf/ + aqV3/2qld/9qpXf/ccbs/3HG7P9xxuz/ccbs/2yzv/9ss7//bLO//2yzv/9egGX/XoBl/16AZf9egGX/ + XoFl/16BZf9egWX/XoFl//359f/9+fX//fn1//359f9oiW//aIlv/2iJb/9oiW//XoNn/16DZ/9eg2f/ + XoNn/16DZ/9eg2f/XoNn/16DZ/9oinD/aIpw/2iKcP9oinD/scGx/7HBsf+xwbH/scGx/7PDs/+zw7P/ + s8Oz/7PDs//b4Nb/2+DW/9vg1v/b4Nb/2+DW/9vg1v/b4Nb/2+DW/7TEtP+0xLT/tMS0/7TEtP+yw7L/ + ssOy/7LDsv+yw7L/Un5c/1J+XP9Sflz/Un5c/yBaLP8gWiz/IFos/yBaLP8dWCr/HVgq/x1YKv8dWCr/ + K2I2/ytiNv8rYjb/K2I2//z28P/89vD//Pbw//z28P8eWyz/Hlss/x5bLP8eWyz/Hlws/x5cLP8eXCz/ + Hlws/y6Yqv8umKr/Lpiq/y6Yqv80reX/NK3l/zSt5f80reX/H18t/x9fLf8fXy3/H18t/x9gLv8fYC7/ + H2Au/x9gLv8gYS7/IGEu/yBhLv8gYS7/IGMv/yBjL/8gYy//IGMv/2qld/9qpXf/aqV3/2qld/9qpXf/ + aqV3/2qld/9qpXf/aqV3/2qld/9qpXf/aqV3/2qld/9qpXf/aqV3/2qld/9xxuz/ccbs/3HG7P9xxuz/ + bLO//2yzv/9ss7//bLO//16AZf9egGX/XoBl/16AZf9egWX/XoFl/16BZf9egWX//fn1//359f/9+fX/ + /fn1/2iJb/9oiW//aIlv/2iJb/9eg2f/XoNn/16DZ/9eg2f/XoNn/16DZ/9eg2f/XoNn/2iKcP9oinD/ + aIpw/2iKcP+xwbH/scGx/7HBsf+xwbH/s8Oz/7PDs/+zw7P/s8Oz/9vg1v/b4Nb/2+DW/9vg1v/b4Nb/ + 2+DW/9vg1v/b4Nb/tMS0/7TEtP+0xLT/tMS0/7LDsv+yw7L/ssOy/7LDsv9Sflz/Un5c/1J+XP9Sflz/ + IFos/yBaLP8gWiz/IFos/x1YKv8dWCr/HVgq/x1YKv8rYjb/K2I2/ytiNv8rYjb//Pbw//z28P/89vD/ + /Pbw/x5bLP8eWyz/Hlss/x5bLP8eXCz/Hlws/x5cLP8eXCz/Lpiq/y6Yqv8umKr/Lpiq/zSt5f80reX/ + NK3l/zSt5f8fXy3/H18t/x9fLf8fXy3/H2Au/x9gLv8fYC7/H2Au/yBhLv8gYS7/IGEu/yBhLv8gYy// + IGMv/yBjL/8gYy//bah6/22oev9tqHr/bah6/22oev9tqHr/bah6/22oev9tqHr/bah6/22oev9tqHr/ + bal//22pf/9tqX//bal//3TM+/90zPv/dMz7/3TM+/9rqaj/a6mo/2upqP9rqaj/YIJo/2CCaP9ggmj/ + YIJo/2CDaP9gg2j/YINo/2CDaP/9+vb//fr2//369v/9+vb/a4ty/2uLcv9ri3L/a4ty/2GFaf9hhWn/ + YYVp/2GFaf9ihmn/YoZp/2KGaf9ihmn/YoZq/2KGav9ihmr/YoZq/2KHav9ih2r/Yodq/2KHav9jiGv/ + Y4hr/2OIa/9jiGv/tcW1/7XFtf+1xbX/tcW1/7XFtv+1xbb/tcW2/7XFtv9jimv/Y4pr/2OKa/9jimv/ + Y4ps/2OKbP9jimz/Y4ps/2OLbP9ji2z/Y4ts/2OLbP9ahGT/WoRk/1qEZP9ahGT/LGM4/yxjOP8sYzj/ + LGM4/ytiN/8rYjf/K2I3/ytiN//89/L//Pfy//z38v/89/L/Hlws/x5cLP8eXCz/Hlws/x5dLP8eXSz/ + Hl0s/x5dLP8rioj/K4qI/yuKiP8rioj/NbT5/zW0+f81tPn/NbT5/yFkNf8hZDX/IWQ1/yFkNf8gYS7/ + IGEu/yBhLv8gYS7/IGIv/yBiL/8gYi//IGIv/yFjL/8hYy//IWMv/yFjL/9tqHr/bah6/22oev9tqHr/ + bah6/22oev9tqHr/bah6/22oev9tqHr/bah6/22oev9tqX//bal//22pf/9tqX//dMz7/3TM+/90zPv/ + dMz7/2upqP9rqaj/a6mo/2upqP9ggmj/YIJo/2CCaP9ggmj/YINo/2CDaP9gg2j/YINo//369v/9+vb/ + /fr2//369v9ri3L/a4ty/2uLcv9ri3L/YYVp/2GFaf9hhWn/YYVp/2KGaf9ihmn/YoZp/2KGaf9ihmr/ + YoZq/2KGav9ihmr/Yodq/2KHav9ih2r/Yodq/2OIa/9jiGv/Y4hr/2OIa/+1xbX/tcW1/7XFtf+1xbX/ + tcW2/7XFtv+1xbb/tcW2/2OKa/9jimv/Y4pr/2OKa/9jimz/Y4ps/2OKbP9jimz/Y4ts/2OLbP9ji2z/ + Y4ts/1qEZP9ahGT/WoRk/1qEZP8sYzj/LGM4/yxjOP8sYzj/K2I3/ytiN/8rYjf/K2I3//z38v/89/L/ + /Pfy//z38v8eXCz/Hlws/x5cLP8eXCz/Hl0s/x5dLP8eXSz/Hl0s/yuKiP8rioj/K4qI/yuKiP81tPn/ + NbT5/zW0+f81tPn/IWQ1/yFkNf8hZDX/IWQ1/yBhLv8gYS7/IGEu/yBhLv8gYi//IGIv/yBiL/8gYi// + IWMv/yFjL/8hYy//IWMv/22oev9tqHr/bah6/22oev9tqHr/bah6/22oev9tqHr/bah6/22oev9tqHr/ + bah6/22pf/9tqX//bal//22pf/90zPv/dMz7/3TM+/90zPv/a6mo/2upqP9rqaj/a6mo/2CCaP9ggmj/ + YIJo/2CCaP9gg2j/YINo/2CDaP9gg2j//fr2//369v/9+vb//fr2/2uLcv9ri3L/a4ty/2uLcv9hhWn/ + YYVp/2GFaf9hhWn/YoZp/2KGaf9ihmn/YoZp/2KGav9ihmr/YoZq/2KGav9ih2r/Yodq/2KHav9ih2r/ + Y4hr/2OIa/9jiGv/Y4hr/7XFtf+1xbX/tcW1/7XFtf+1xbb/tcW2/7XFtv+1xbb/Y4pr/2OKa/9jimv/ + Y4pr/2OKbP9jimz/Y4ps/2OKbP9ji2z/Y4ts/2OLbP9ji2z/WoRk/1qEZP9ahGT/WoRk/yxjOP8sYzj/ + LGM4/yxjOP8rYjf/K2I3/ytiN/8rYjf//Pfy//z38v/89/L//Pfy/x5cLP8eXCz/Hlws/x5cLP8eXSz/ + Hl0s/x5dLP8eXSz/K4qI/yuKiP8rioj/K4qI/zW0+f81tPn/NbT5/zW0+f8hZDX/IWQ1/yFkNf8hZDX/ + IGEu/yBhLv8gYS7/IGEu/yBiL/8gYi//IGIv/yBiL/8hYy//IWMv/yFjL/8hYy//bah6/22oev9tqHr/ + bah6/22oev9tqHr/bah6/22oev9tqHr/bah6/22oev9tqHr/bal//22pf/9tqX//bal//3TM+/90zPv/ + dMz7/3TM+/9rqaj/a6mo/2upqP9rqaj/YIJo/2CCaP9ggmj/YIJo/2CDaP9gg2j/YINo/2CDaP/9+vb/ + /fr2//369v/9+vb/a4ty/2uLcv9ri3L/a4ty/2GFaf9hhWn/YYVp/2GFaf9ihmn/YoZp/2KGaf9ihmn/ + YoZq/2KGav9ihmr/YoZq/2KHav9ih2r/Yodq/2KHav9jiGv/Y4hr/2OIa/9jiGv/tcW1/7XFtf+1xbX/ + tcW1/7XFtv+1xbb/tcW2/7XFtv9jimv/Y4pr/2OKa/9jimv/Y4ps/2OKbP9jimz/Y4ps/2OLbP9ji2z/ + Y4ts/2OLbP9ahGT/WoRk/1qEZP9ahGT/LGM4/yxjOP8sYzj/LGM4/ytiN/8rYjf/K2I3/ytiN//89/L/ + /Pfy//z38v/89/L/Hlws/x5cLP8eXCz/Hlws/x5dLP8eXSz/Hl0s/x5dLP8rioj/K4qI/yuKiP8rioj/ + NbT5/zW0+f81tPn/NbT5/yFkNf8hZDX/IWQ1/yFkNf8gYS7/IGEu/yBhLv8gYS7/IGIv/yBiL/8gYi// + IGIv/yFjL/8hYy//IWMv/yFjL/9xq37/cat+/3Grfv9xq37/cat+/3Grfv9xq37/cat+/3Grfv9xq37/ + cat+/3Grfv9yr4z/cq+M/3KvjP9yr4z/eM37/3jN+/94zfv/eM37/22loP9tpaD/baWg/22loP9khGv/ + ZIRr/2SEa/9khGv/ZIVr/2SFa/9khWv/ZIVr//36+P/9+vj//fr4//36+P9ujnX/bo51/26Odf9ujnX/ + ZYht/2WIbf9liG3/ZYht/2WIbf9liG3/ZYht/2WIbf9liW3/ZYlt/2WJbf9liW3/Zopt/2aKbf9mim3/ + Zopt/2aKbv9mim7/Zopu/2aKbv+1xbb/tcW2/7XFtv+1xbb/tcW2/7XFtv+1xbb/tcW2/2eMb/9njG// + Z4xv/2eMb/9njW//Z41v/2eNb/9njW//Z45v/2eOb/9njm//Z45v/2eOcP9njnD/Z45w/2eOcP9mjm7/ + Zo5u/2aObv9mjm7/THtW/0x7Vv9Me1b/THtW//z49P/8+PT//Pj0//z49P8eWyz/Hlss/x5bLP8eWyz/ + H10s/x9dLP8fXSz/H10s/yqDd/8qg3f/KoN3/yqDd/82tfn/NrX5/za1+f82tfn/I21H/yNtR/8jbUf/ + I21H/yBhLv8gYS7/IGEu/yBhLv8hYi//IWIv/yFiL/8hYi//IWMw/yFjMP8hYzD/IWMw/3Grfv9xq37/ + cat+/3Grfv9xq37/cat+/3Grfv9xq37/cat+/3Grfv9xq37/cat+/3KvjP9yr4z/cq+M/3KvjP94zfv/ + eM37/3jN+/94zfv/baWg/22loP9tpaD/baWg/2SEa/9khGv/ZIRr/2SEa/9khWv/ZIVr/2SFa/9khWv/ + /fr4//36+P/9+vj//fr4/26Odf9ujnX/bo51/26Odf9liG3/ZYht/2WIbf9liG3/ZYht/2WIbf9liG3/ + ZYht/2WJbf9liW3/ZYlt/2WJbf9mim3/Zopt/2aKbf9mim3/Zopu/2aKbv9mim7/Zopu/7XFtv+1xbb/ + tcW2/7XFtv+1xbb/tcW2/7XFtv+1xbb/Z4xv/2eMb/9njG//Z4xv/2eNb/9njW//Z41v/2eNb/9njm// + Z45v/2eOb/9njm//Z45w/2eOcP9njnD/Z45w/2aObv9mjm7/Zo5u/2aObv9Me1b/THtW/0x7Vv9Me1b/ + /Pj0//z49P/8+PT//Pj0/x5bLP8eWyz/Hlss/x5bLP8fXSz/H10s/x9dLP8fXSz/KoN3/yqDd/8qg3f/ + KoN3/za1+f82tfn/NrX5/za1+f8jbUf/I21H/yNtR/8jbUf/IGEu/yBhLv8gYS7/IGEu/yFiL/8hYi// + IWIv/yFiL/8hYzD/IWMw/yFjMP8hYzD/cat+/3Grfv9xq37/cat+/3Grfv9xq37/cat+/3Grfv9xq37/ + cat+/3Grfv9xq37/cq+M/3KvjP9yr4z/cq+M/3jN+/94zfv/eM37/3jN+/9tpaD/baWg/22loP9tpaD/ + ZIRr/2SEa/9khGv/ZIRr/2SFa/9khWv/ZIVr/2SFa//9+vj//fr4//36+P/9+vj/bo51/26Odf9ujnX/ + bo51/2WIbf9liG3/ZYht/2WIbf9liG3/ZYht/2WIbf9liG3/ZYlt/2WJbf9liW3/ZYlt/2aKbf9mim3/ + Zopt/2aKbf9mim7/Zopu/2aKbv9mim7/tcW2/7XFtv+1xbb/tcW2/7XFtv+1xbb/tcW2/7XFtv9njG// + Z4xv/2eMb/9njG//Z41v/2eNb/9njW//Z41v/2eOb/9njm//Z45v/2eOb/9njnD/Z45w/2eOcP9njnD/ + Zo5u/2aObv9mjm7/Zo5u/0x7Vv9Me1b/THtW/0x7Vv/8+PT//Pj0//z49P/8+PT/Hlss/x5bLP8eWyz/ + Hlss/x9dLP8fXSz/H10s/x9dLP8qg3f/KoN3/yqDd/8qg3f/NrX5/za1+f82tfn/NrX5/yNtR/8jbUf/ + I21H/yNtR/8gYS7/IGEu/yBhLv8gYS7/IWIv/yFiL/8hYi//IWIv/yFjMP8hYzD/IWMw/yFjMP9xq37/ + cat+/3Grfv9xq37/cat+/3Grfv9xq37/cat+/3Grfv9xq37/cat+/3Grfv9yr4z/cq+M/3KvjP9yr4z/ + eM37/3jN+/94zfv/eM37/22loP9tpaD/baWg/22loP9khGv/ZIRr/2SEa/9khGv/ZIVr/2SFa/9khWv/ + ZIVr//36+P/9+vj//fr4//36+P9ujnX/bo51/26Odf9ujnX/ZYht/2WIbf9liG3/ZYht/2WIbf9liG3/ + ZYht/2WIbf9liW3/ZYlt/2WJbf9liW3/Zopt/2aKbf9mim3/Zopt/2aKbv9mim7/Zopu/2aKbv+1xbb/ + tcW2/7XFtv+1xbb/tcW2/7XFtv+1xbb/tcW2/2eMb/9njG//Z4xv/2eMb/9njW//Z41v/2eNb/9njW// + Z45v/2eOb/9njm//Z45v/2eOcP9njnD/Z45w/2eOcP9mjm7/Zo5u/2aObv9mjm7/THtW/0x7Vv9Me1b/ + THtW//z49P/8+PT//Pj0//z49P8eWyz/Hlss/x5bLP8eWyz/H10s/x9dLP8fXSz/H10s/yqDd/8qg3f/ + KoN3/yqDd/82tfn/NrX5/za1+f82tfn/I21H/yNtR/8jbUf/I21H/yBhLv8gYS7/IGEu/yBhLv8hYi// + IWIv/yFiL/8hYi//IWMw/yFjMP8hYzD/IWMw/3Stgf90rYH/dK2B/3Stgf90rYH/dK2B/3Stgf90rYH/ + dK2B/3Stgf90rYH/dK2B/3Wyk/91spP/dbKT/3Wyk/97z/v/e8/7/3vP+/97z/v/cKWe/3Clnv9wpZ7/ + cKWe/2eGbv9nhm7/Z4Zu/2eGbv9nh2//Z4dv/2eHb/9nh2///fr4//36+P/9+vj//fr4/3OSef9zknn/ + c5J5/3OSef9oim//aIpv/2iKb/9oim//aIpw/2iKcP9oinD/aIpw/2mLcf9pi3H/aYtx/2mLcf9pjHH/ + aYxx/2mMcf9pjHH/aYxx/2mMcf9pjHH/aYxx/3KUef9ylHn/cpR5/3KUef9ylHr/cpR6/3KUev9ylHr/ + aY5y/2mOcv9pjnL/aY5y/2qPc/9qj3P/ao9z/2qPc/9qkHP/apBz/2qQc/9qkHP/apBz/2qQc/9qkHP/ + apBz/2uRc/9rkXP/a5Fz/2uRc/91mX3/dZl9/3WZff91mX3//fr3//369//9+vf//fr3/yNeMP8jXjD/ + I14w/yNeMP8fXC3/H1wt/x9cLf8fXC3/KYNz/ymDc/8pg3P/KYNz/za2+f82tvn/Nrb5/za2+f8lcU3/ + JXFN/yVxTf8lcU3/IWEv/yFhL/8hYS//IWEv/yFiMP8hYjD/IWIw/yFiMP8hZDH/IWQx/yFkMf8hZDH/ + dK2B/3Stgf90rYH/dK2B/3Stgf90rYH/dK2B/3Stgf90rYH/dK2B/3Stgf90rYH/dbKT/3Wyk/91spP/ + dbKT/3vP+/97z/v/e8/7/3vP+/9wpZ7/cKWe/3Clnv9wpZ7/Z4Zu/2eGbv9nhm7/Z4Zu/2eHb/9nh2// + Z4dv/2eHb//9+vj//fr4//36+P/9+vj/c5J5/3OSef9zknn/c5J5/2iKb/9oim//aIpv/2iKb/9oinD/ + aIpw/2iKcP9oinD/aYtx/2mLcf9pi3H/aYtx/2mMcf9pjHH/aYxx/2mMcf9pjHH/aYxx/2mMcf9pjHH/ + cpR5/3KUef9ylHn/cpR5/3KUev9ylHr/cpR6/3KUev9pjnL/aY5y/2mOcv9pjnL/ao9z/2qPc/9qj3P/ + ao9z/2qQc/9qkHP/apBz/2qQc/9qkHP/apBz/2qQc/9qkHP/a5Fz/2uRc/9rkXP/a5Fz/3WZff91mX3/ + dZl9/3WZff/9+vf//fr3//369//9+vf/I14w/yNeMP8jXjD/I14w/x9cLf8fXC3/H1wt/x9cLf8pg3P/ + KYNz/ymDc/8pg3P/Nrb5/za2+f82tvn/Nrb5/yVxTf8lcU3/JXFN/yVxTf8hYS//IWEv/yFhL/8hYS// + IWIw/yFiMP8hYjD/IWIw/yFkMf8hZDH/IWQx/yFkMf90rYH/dK2B/3Stgf90rYH/dK2B/3Stgf90rYH/ + dK2B/3Stgf90rYH/dK2B/3Stgf91spP/dbKT/3Wyk/91spP/e8/7/3vP+/97z/v/e8/7/3Clnv9wpZ7/ + cKWe/3Clnv9nhm7/Z4Zu/2eGbv9nhm7/Z4dv/2eHb/9nh2//Z4dv//36+P/9+vj//fr4//36+P9zknn/ + c5J5/3OSef9zknn/aIpv/2iKb/9oim//aIpv/2iKcP9oinD/aIpw/2iKcP9pi3H/aYtx/2mLcf9pi3H/ + aYxx/2mMcf9pjHH/aYxx/2mMcf9pjHH/aYxx/2mMcf9ylHn/cpR5/3KUef9ylHn/cpR6/3KUev9ylHr/ + cpR6/2mOcv9pjnL/aY5y/2mOcv9qj3P/ao9z/2qPc/9qj3P/apBz/2qQc/9qkHP/apBz/2qQc/9qkHP/ + apBz/2qQc/9rkXP/a5Fz/2uRc/9rkXP/dZl9/3WZff91mX3/dZl9//369//9+vf//fr3//369/8jXjD/ + I14w/yNeMP8jXjD/H1wt/x9cLf8fXC3/H1wt/ymDc/8pg3P/KYNz/ymDc/82tvn/Nrb5/za2+f82tvn/ + JXFN/yVxTf8lcU3/JXFN/yFhL/8hYS//IWEv/yFhL/8hYjD/IWIw/yFiMP8hYjD/IWQx/yFkMf8hZDH/ + IWQx/3Stgf90rYH/dK2B/3Stgf90rYH/dK2B/3Stgf90rYH/dK2B/3Stgf90rYH/dK2B/3Wyk/91spP/ + dbKT/3Wyk/97z/v/e8/7/3vP+/97z/v/cKWe/3Clnv9wpZ7/cKWe/2eGbv9nhm7/Z4Zu/2eGbv9nh2// + Z4dv/2eHb/9nh2///fr4//36+P/9+vj//fr4/3OSef9zknn/c5J5/3OSef9oim//aIpv/2iKb/9oim// + aIpw/2iKcP9oinD/aIpw/2mLcf9pi3H/aYtx/2mLcf9pjHH/aYxx/2mMcf9pjHH/aYxx/2mMcf9pjHH/ + aYxx/3KUef9ylHn/cpR5/3KUef9ylHr/cpR6/3KUev9ylHr/aY5y/2mOcv9pjnL/aY5y/2qPc/9qj3P/ + ao9z/2qPc/9qkHP/apBz/2qQc/9qkHP/apBz/2qQc/9qkHP/apBz/2uRc/9rkXP/a5Fz/2uRc/91mX3/ + dZl9/3WZff91mX3//fr3//369//9+vf//fr3/yNeMP8jXjD/I14w/yNeMP8fXC3/H1wt/x9cLf8fXC3/ + KYNz/ymDc/8pg3P/KYNz/za2+f82tvn/Nrb5/za2+f8lcU3/JXFN/yVxTf8lcU3/IWEv/yFhL/8hYS// + IWEv/yFiMP8hYjD/IWIw/yFiMP8hZDH/IWQx/yFkMf8hZDH/d6+E/3evhP93r4T/d6+E/3evhP93r4T/ + d6+E/3evhP93r4T/d6+E/3evhP93r4T/eLWX/3i1l/94tZf/eLWX/37Q+/9+0Pv/ftD7/37Q+/9ypZ3/ + cqWd/3Klnf9ypZ3/aolx/2qJcf9qiXH/aolx/2qJcf9qiXH/aolx/2qJcf/Z39j/2d/Y/9nf2P/Z39j/ + 4ebg/+Hm4P/h5uD/4ebg/9je1v/Y3tb/2N7W/9je1v/Y3tb/2N7W/9je1v/Y3tb/2N/W/9jf1v/Y39b/ + 2N/W/9jf1v/Y39b/2N/W/9jf1v/Y39f/2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/ + 2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/2N/X/9jg1//Y4Nf/2ODX/9jg1//Y4Nf/ + 2ODX/9jg1//Y4Nf/2ODX/9jg1//Y4Nf/2ODX/+Hn4f/h5+H/4efh/+Hn4f/Z4tn/2eLZ/9ni2f/Z4tn/ + X4pp/1+Kaf9fimn/X4pp/yZhNP8mYTT/JmE0/yZhNP8pgG3/KYBt/ymAbf8pgG3/N7f5/ze3+f83t/n/ + N7f5/yZyUv8mclL/JnJS/yZyUv8hYTD/IWEw/yFhMP8hYTD/IWIw/yFiMP8hYjD/IWIw/yJjMf8iYzH/ + ImMx/yJjMf93r4T/d6+E/3evhP93r4T/d6+E/3evhP93r4T/d6+E/3evhP93r4T/d6+E/3evhP94tZf/ + eLWX/3i1l/94tZf/ftD7/37Q+/9+0Pv/ftD7/3Klnf9ypZ3/cqWd/3Klnf9qiXH/aolx/2qJcf9qiXH/ + aolx/2qJcf9qiXH/aolx/9nf2P/Z39j/2d/Y/9nf2P/h5uD/4ebg/+Hm4P/h5uD/2N7W/9je1v/Y3tb/ + 2N7W/9je1v/Y3tb/2N7W/9je1v/Y39b/2N/W/9jf1v/Y39b/2N/W/9jf1v/Y39b/2N/W/9jf1//Y39f/ + 2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/ + 2N/X/9jf1//Y39f/2ODX/9jg1//Y4Nf/2ODX/9jg1//Y4Nf/2ODX/9jg1//Y4Nf/2ODX/9jg1//Y4Nf/ + 4efh/+Hn4f/h5+H/4efh/9ni2f/Z4tn/2eLZ/9ni2f9fimn/X4pp/1+Kaf9fimn/JmE0/yZhNP8mYTT/ + JmE0/ymAbf8pgG3/KYBt/ymAbf83t/n/N7f5/ze3+f83t/n/JnJS/yZyUv8mclL/JnJS/yFhMP8hYTD/ + IWEw/yFhMP8hYjD/IWIw/yFiMP8hYjD/ImMx/yJjMf8iYzH/ImMx/3evhP93r4T/d6+E/3evhP93r4T/ + d6+E/3evhP93r4T/d6+E/3evhP93r4T/d6+E/3i1l/94tZf/eLWX/3i1l/9+0Pv/ftD7/37Q+/9+0Pv/ + cqWd/3Klnf9ypZ3/cqWd/2qJcf9qiXH/aolx/2qJcf9qiXH/aolx/2qJcf9qiXH/2d/Y/9nf2P/Z39j/ + 2d/Y/+Hm4P/h5uD/4ebg/+Hm4P/Y3tb/2N7W/9je1v/Y3tb/2N7W/9je1v/Y3tb/2N7W/9jf1v/Y39b/ + 2N/W/9jf1v/Y39b/2N/W/9jf1v/Y39b/2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/ + 2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/2N/X/9jf1//Y4Nf/2ODX/9jg1//Y4Nf/ + 2ODX/9jg1//Y4Nf/2ODX/9jg1//Y4Nf/2ODX/9jg1//h5+H/4efh/+Hn4f/h5+H/2eLZ/9ni2f/Z4tn/ + 2eLZ/1+Kaf9fimn/X4pp/1+Kaf8mYTT/JmE0/yZhNP8mYTT/KYBt/ymAbf8pgG3/KYBt/ze3+f83t/n/ + N7f5/ze3+f8mclL/JnJS/yZyUv8mclL/IWEw/yFhMP8hYTD/IWEw/yFiMP8hYjD/IWIw/yFiMP8iYzH/ + ImMx/yJjMf8iYzH/d6+E/3evhP93r4T/d6+E/3evhP93r4T/d6+E/3evhP93r4T/d6+E/3evhP93r4T/ + eLWX/3i1l/94tZf/eLWX/37Q+/9+0Pv/ftD7/37Q+/9ypZ3/cqWd/3Klnf9ypZ3/aolx/2qJcf9qiXH/ + aolx/2qJcf9qiXH/aolx/2qJcf/Z39j/2d/Y/9nf2P/Z39j/4ebg/+Hm4P/h5uD/4ebg/9je1v/Y3tb/ + 2N7W/9je1v/Y3tb/2N7W/9je1v/Y3tb/2N/W/9jf1v/Y39b/2N/W/9jf1v/Y39b/2N/W/9jf1v/Y39f/ + 2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/ + 2N/X/9jf1//Y39f/2N/X/9jg1//Y4Nf/2ODX/9jg1//Y4Nf/2ODX/9jg1//Y4Nf/2ODX/9jg1//Y4Nf/ + 2ODX/+Hn4f/h5+H/4efh/+Hn4f/Z4tn/2eLZ/9ni2f/Z4tn/X4pp/1+Kaf9fimn/X4pp/yZhNP8mYTT/ + JmE0/yZhNP8pgG3/KYBt/ymAbf8pgG3/N7f5/ze3+f83t/n/N7f5/yZyUv8mclL/JnJS/yZyUv8hYTD/ + IWEw/yFhMP8hYTD/IWIw/yFiMP8hYjD/IWIw/yJjMf8iYzH/ImMx/yJjMf96soj/erKI/3qyiP96soj/ + erKI/3qyiP96soj/erKI/3qyiP96soj/erKI/3qyiP97uJ3/e7id/3u4nf97uJ3/gNL7/4DS+/+A0vv/ + gNL7/3Olm/9zpZv/c6Wb/3Olm/9si3T/bIt0/2yLdP9si3T/bYt1/22Ldf9ti3X/bYt1/3KQev9ykHr/ + cpB6/3KQev+Yrp3/mK6d/5iunf+Yrp3/nbKh/52yof+dsqH/nbKh/7fGuf+3xrn/t8a5/7fGuf/r7un/ + 6+7p/+vu6f/r7un/nrSi/560ov+etKL/nrSi/560ov+etKL/nrSi/560ov+etaL/nrWi/561ov+etaL/ + nrWj/561o/+etaP/nrWj/561o/+etaP/nrWj/561o/+etqT/nrak/562pP+etqT/6+7q/+vu6v/r7ur/ + 6+7q/7fJu/+3ybv/t8m7/7fJu/+ft6T/n7ek/5+3pP+ft6T/mrSg/5q0oP+atKD/mrSg/3Wafv91mn7/ + dZp+/3Wafv9xl3r/cZd6/3GXev9xl3r/ZpBw/2aQcP9mkHD/ZpBw/zWFcP81hXD/NYVw/zWFcP83uPn/ + N7j5/ze4+f83uPn/J3ZY/yd2WP8ndlj/J3ZY/yFhMf8hYTH/IWEx/yFhMf8hYjH/IWIx/yFiMf8hYjH/ + ImYz/yJmM/8iZjP/ImYz/3qyiP96soj/erKI/3qyiP96soj/erKI/3qyiP96soj/erKI/3qyiP96soj/ + erKI/3u4nf97uJ3/e7id/3u4nf+A0vv/gNL7/4DS+/+A0vv/c6Wb/3Olm/9zpZv/c6Wb/2yLdP9si3T/ + bIt0/2yLdP9ti3X/bYt1/22Ldf9ti3X/cpB6/3KQev9ykHr/cpB6/5iunf+Yrp3/mK6d/5iunf+dsqH/ + nbKh/52yof+dsqH/t8a5/7fGuf+3xrn/t8a5/+vu6f/r7un/6+7p/+vu6f+etKL/nrSi/560ov+etKL/ + nrSi/560ov+etKL/nrSi/561ov+etaL/nrWi/561ov+etaP/nrWj/561o/+etaP/nrWj/561o/+etaP/ + nrWj/562pP+etqT/nrak/562pP/r7ur/6+7q/+vu6v/r7ur/t8m7/7fJu/+3ybv/t8m7/5+3pP+ft6T/ + n7ek/5+3pP+atKD/mrSg/5q0oP+atKD/dZp+/3Wafv91mn7/dZp+/3GXev9xl3r/cZd6/3GXev9mkHD/ + ZpBw/2aQcP9mkHD/NYVw/zWFcP81hXD/NYVw/ze4+f83uPn/N7j5/ze4+f8ndlj/J3ZY/yd2WP8ndlj/ + IWEx/yFhMf8hYTH/IWEx/yFiMf8hYjH/IWIx/yFiMf8iZjP/ImYz/yJmM/8iZjP/erKI/3qyiP96soj/ + erKI/3qyiP96soj/erKI/3qyiP96soj/erKI/3qyiP96soj/e7id/3u4nf97uJ3/e7id/4DS+/+A0vv/ + gNL7/4DS+/9zpZv/c6Wb/3Olm/9zpZv/bIt0/2yLdP9si3T/bIt0/22Ldf9ti3X/bYt1/22Ldf9ykHr/ + cpB6/3KQev9ykHr/mK6d/5iunf+Yrp3/mK6d/52yof+dsqH/nbKh/52yof+3xrn/t8a5/7fGuf+3xrn/ + 6+7p/+vu6f/r7un/6+7p/560ov+etKL/nrSi/560ov+etKL/nrSi/560ov+etKL/nrWi/561ov+etaL/ + nrWi/561o/+etaP/nrWj/561o/+etaP/nrWj/561o/+etaP/nrak/562pP+etqT/nrak/+vu6v/r7ur/ + 6+7q/+vu6v+3ybv/t8m7/7fJu/+3ybv/n7ek/5+3pP+ft6T/n7ek/5q0oP+atKD/mrSg/5q0oP91mn7/ + dZp+/3Wafv91mn7/cZd6/3GXev9xl3r/cZd6/2aQcP9mkHD/ZpBw/2aQcP81hXD/NYVw/zWFcP81hXD/ + N7j5/ze4+f83uPn/N7j5/yd2WP8ndlj/J3ZY/yd2WP8hYTH/IWEx/yFhMf8hYTH/IWIx/yFiMf8hYjH/ + IWIx/yJmM/8iZjP/ImYz/yJmM/96soj/erKI/3qyiP96soj/erKI/3qyiP96soj/erKI/3qyiP96soj/ + erKI/3qyiP97uJ3/e7id/3u4nf97uJ3/gNL7/4DS+/+A0vv/gNL7/3Olm/9zpZv/c6Wb/3Olm/9si3T/ + bIt0/2yLdP9si3T/bYt1/22Ldf9ti3X/bYt1/3KQev9ykHr/cpB6/3KQev+Yrp3/mK6d/5iunf+Yrp3/ + nbKh/52yof+dsqH/nbKh/7fGuf+3xrn/t8a5/7fGuf/r7un/6+7p/+vu6f/r7un/nrSi/560ov+etKL/ + nrSi/560ov+etKL/nrSi/560ov+etaL/nrWi/561ov+etaL/nrWj/561o/+etaP/nrWj/561o/+etaP/ + nrWj/561o/+etqT/nrak/562pP+etqT/6+7q/+vu6v/r7ur/6+7q/7fJu/+3ybv/t8m7/7fJu/+ft6T/ + n7ek/5+3pP+ft6T/mrSg/5q0oP+atKD/mrSg/3Wafv91mn7/dZp+/3Wafv9xl3r/cZd6/3GXev9xl3r/ + ZpBw/2aQcP9mkHD/ZpBw/zWFcP81hXD/NYVw/zWFcP83uPn/N7j5/ze4+f83uPn/J3ZY/yd2WP8ndlj/ + J3ZY/yFhMf8hYTH/IWEx/yFhMf8hYjH/IWIx/yFiMf8hYjH/ImYz/yJmM/8iZjP/ImYz/361i/9+tYv/ + frWL/361i/9+tYv/frWL/361i/9+tYv/frWL/361i/9+tYv/frWL/3+7o/9/u6P/f7uj/3+7o/+E0/v/ + hNP7/4TT+/+E0/v/d6Wa/3elmv93pZr/d6Wa/3CNd/9wjXf/cI13/3CNd/9wjnj/cI54/3COeP9wjnj/ + cI94/3CPeP9wj3j/cI94/3CPef9wj3n/cI95/3CPef9xkHn/cZB5/3GQef9xkHn/kamX/5Gpl/+RqZf/ + kamX/+zw7P/s8Oz/7PDs/+zw7P9yknr/cpJ6/3KSev9yknr/cpN6/3KTev9yk3r/cpN6/3KUev9ylHr/ + cpR6/3KUev9ylHv/cpR7/3KUe/9ylHv/c5V7/3OVe/9zlXv/c5V7/3OWfP9zlnz/c5Z8/3OWfP/s8Oz/ + 7PDs/+zw7P/s8Oz/k66Z/5Oumf+Trpn/k66Z/3SYfP90mHz/dJh8/3SYfP90mH3/dJh9/3SYff90mH3/ + dJl9/3SZff90mX3/dJl9/3SZfv90mX7/dJl+/3SZfv90mn7/dJp+/3Safv90mn7/c6mZ/3Opmf9zqZn/ + c6mZ/0S8+P9EvPj/RLz4/0S8+P8oeF3/KHhd/yh4Xf8oeF3/IWEx/yFhMf8hYTH/IWEx/yJlM/8iZTP/ + ImUz/yJlM/8sgEH/LIBB/yyAQf8sgEH/frWL/361i/9+tYv/frWL/361i/9+tYv/frWL/361i/9+tYv/ + frWL/361i/9+tYv/f7uj/3+7o/9/u6P/f7uj/4TT+/+E0/v/hNP7/4TT+/93pZr/d6Wa/3elmv93pZr/ + cI13/3CNd/9wjXf/cI13/3COeP9wjnj/cI54/3COeP9wj3j/cI94/3CPeP9wj3j/cI95/3CPef9wj3n/ + cI95/3GQef9xkHn/cZB5/3GQef+RqZf/kamX/5Gpl/+RqZf/7PDs/+zw7P/s8Oz/7PDs/3KSev9yknr/ + cpJ6/3KSev9yk3r/cpN6/3KTev9yk3r/cpR6/3KUev9ylHr/cpR6/3KUe/9ylHv/cpR7/3KUe/9zlXv/ + c5V7/3OVe/9zlXv/c5Z8/3OWfP9zlnz/c5Z8/+zw7P/s8Oz/7PDs/+zw7P+Trpn/k66Z/5Oumf+Trpn/ + dJh8/3SYfP90mHz/dJh8/3SYff90mH3/dJh9/3SYff90mX3/dJl9/3SZff90mX3/dJl+/3SZfv90mX7/ + dJl+/3Safv90mn7/dJp+/3Safv9zqZn/c6mZ/3Opmf9zqZn/RLz4/0S8+P9EvPj/RLz4/yh4Xf8oeF3/ + KHhd/yh4Xf8hYTH/IWEx/yFhMf8hYTH/ImUz/yJlM/8iZTP/ImUz/yyAQf8sgEH/LIBB/yyAQf9+tYv/ + frWL/361i/9+tYv/frWL/361i/9+tYv/frWL/361i/9+tYv/frWL/361i/9/u6P/f7uj/3+7o/9/u6P/ + hNP7/4TT+/+E0/v/hNP7/3elmv93pZr/d6Wa/3elmv9wjXf/cI13/3CNd/9wjXf/cI54/3COeP9wjnj/ + cI54/3CPeP9wj3j/cI94/3CPeP9wj3n/cI95/3CPef9wj3n/cZB5/3GQef9xkHn/cZB5/5Gpl/+RqZf/ + kamX/5Gpl//s8Oz/7PDs/+zw7P/s8Oz/cpJ6/3KSev9yknr/cpJ6/3KTev9yk3r/cpN6/3KTev9ylHr/ + cpR6/3KUev9ylHr/cpR7/3KUe/9ylHv/cpR7/3OVe/9zlXv/c5V7/3OVe/9zlnz/c5Z8/3OWfP9zlnz/ + 7PDs/+zw7P/s8Oz/7PDs/5Oumf+Trpn/k66Z/5Oumf90mHz/dJh8/3SYfP90mHz/dJh9/3SYff90mH3/ + dJh9/3SZff90mX3/dJl9/3SZff90mX7/dJl+/3SZfv90mX7/dJp+/3Safv90mn7/dJp+/3Opmf9zqZn/ + c6mZ/3Opmf9EvPj/RLz4/0S8+P9EvPj/KHhd/yh4Xf8oeF3/KHhd/yFhMf8hYTH/IWEx/yFhMf8iZTP/ + ImUz/yJlM/8iZTP/LIBB/yyAQf8sgEH/LIBB/361i/9+tYv/frWL/361i/9+tYv/frWL/361i/9+tYv/ + frWL/361i/9+tYv/frWL/3+7o/9/u6P/f7uj/3+7o/+E0/v/hNP7/4TT+/+E0/v/d6Wa/3elmv93pZr/ + d6Wa/3CNd/9wjXf/cI13/3CNd/9wjnj/cI54/3COeP9wjnj/cI94/3CPeP9wj3j/cI94/3CPef9wj3n/ + cI95/3CPef9xkHn/cZB5/3GQef9xkHn/kamX/5Gpl/+RqZf/kamX/+zw7P/s8Oz/7PDs/+zw7P9yknr/ + cpJ6/3KSev9yknr/cpN6/3KTev9yk3r/cpN6/3KUev9ylHr/cpR6/3KUev9ylHv/cpR7/3KUe/9ylHv/ + c5V7/3OVe/9zlXv/c5V7/3OWfP9zlnz/c5Z8/3OWfP/s8Oz/7PDs/+zw7P/s8Oz/k66Z/5Oumf+Trpn/ + k66Z/3SYfP90mHz/dJh8/3SYfP90mH3/dJh9/3SYff90mH3/dJl9/3SZff90mX3/dJl9/3SZfv90mX7/ + dJl+/3SZfv90mn7/dJp+/3Safv90mn7/c6mZ/3Opmf9zqZn/c6mZ/0S8+P9EvPj/RLz4/0S8+P8oeF3/ + KHhd/yh4Xf8oeF3/IWEx/yFhMf8hYTH/IWEx/yJlM/8iZTP/ImUz/yJlM/8sgEH/LIBB/yyAQf8sgEH/ + gbeO/4G3jv+Bt47/gbeO/4G3jv+Bt47/gbeO/4G3jv+Bt47/gbeO/4G3jv+Bt47/gr6n/4K+p/+Cvqf/ + gr6n/4fU+/+H1Pv/h9T7/4fU+/95pJj/eaSY/3mkmP95pJj/c496/3OPev9zj3r/c496/3OQev9zkHr/ + c5B6/3OQev9zkXr/c5F6/3ORev9zkXr/dJJ7/3SSe/90knv/dJJ7/3SSe/90knv/dJJ7/3SSe/94loD/ + eJaA/3iWgP94loD/7fDs/+3w7P/t8Oz/7fDs/9Te1v/U3tb/1N7W/9Te1v+/zcL/v83C/7/Nwv+/zcL/ + v83C/7/Nwv+/zcL/v83C/7/Owv+/zsL/v87C/7/Owv+/zsL/v87C/7/Owv+/zsL/1d/X/9Xf1//V39f/ + 1d/X/+3w7f/t8O3/7fDt/+3w7f96nIP/epyD/3qcg/96nIP/dpl//3aZf/92mX//dpl//3eaf/93mn// + d5p//3eaf/93m3//d5t//3ebf/93m3//d5uA/3ebgP93m4D/d5uA/3ecgf93nIH/d5yB/3ecgf98rp3/ + fK6d/3yunf98rp3/ftH6/37R+v9+0fr/ftH6/zOBaP8zgWj/M4Fo/zOBaP8iZDL/ImQy/yJkMv8iZDL/ + LYJB/y2CQf8tgkH/LYJB/y+JRf8viUX/L4lF/y+JRf+Bt47/gbeO/4G3jv+Bt47/gbeO/4G3jv+Bt47/ + gbeO/4G3jv+Bt47/gbeO/4G3jv+Cvqf/gr6n/4K+p/+Cvqf/h9T7/4fU+/+H1Pv/h9T7/3mkmP95pJj/ + eaSY/3mkmP9zj3r/c496/3OPev9zj3r/c5B6/3OQev9zkHr/c5B6/3ORev9zkXr/c5F6/3ORev90knv/ + dJJ7/3SSe/90knv/dJJ7/3SSe/90knv/dJJ7/3iWgP94loD/eJaA/3iWgP/t8Oz/7fDs/+3w7P/t8Oz/ + 1N7W/9Te1v/U3tb/1N7W/7/Nwv+/zcL/v83C/7/Nwv+/zcL/v83C/7/Nwv+/zcL/v87C/7/Owv+/zsL/ + v87C/7/Owv+/zsL/v87C/7/Owv/V39f/1d/X/9Xf1//V39f/7fDt/+3w7f/t8O3/7fDt/3qcg/96nIP/ + epyD/3qcg/92mX//dpl//3aZf/92mX//d5p//3eaf/93mn//d5p//3ebf/93m3//d5t//3ebf/93m4D/ + d5uA/3ebgP93m4D/d5yB/3ecgf93nIH/d5yB/3yunf98rp3/fK6d/3yunf9+0fr/ftH6/37R+v9+0fr/ + M4Fo/zOBaP8zgWj/M4Fo/yJkMv8iZDL/ImQy/yJkMv8tgkH/LYJB/y2CQf8tgkH/L4lF/y+JRf8viUX/ + L4lF/4G3jv+Bt47/gbeO/4G3jv+Bt47/gbeO/4G3jv+Bt47/gbeO/4G3jv+Bt47/gbeO/4K+p/+Cvqf/ + gr6n/4K+p/+H1Pv/h9T7/4fU+/+H1Pv/eaSY/3mkmP95pJj/eaSY/3OPev9zj3r/c496/3OPev9zkHr/ + c5B6/3OQev9zkHr/c5F6/3ORev9zkXr/c5F6/3SSe/90knv/dJJ7/3SSe/90knv/dJJ7/3SSe/90knv/ + eJaA/3iWgP94loD/eJaA/+3w7P/t8Oz/7fDs/+3w7P/U3tb/1N7W/9Te1v/U3tb/v83C/7/Nwv+/zcL/ + v83C/7/Nwv+/zcL/v83C/7/Nwv+/zsL/v87C/7/Owv+/zsL/v87C/7/Owv+/zsL/v87C/9Xf1//V39f/ + 1d/X/9Xf1//t8O3/7fDt/+3w7f/t8O3/epyD/3qcg/96nIP/epyD/3aZf/92mX//dpl//3aZf/93mn// + d5p//3eaf/93mn//d5t//3ebf/93m3//d5t//3ebgP93m4D/d5uA/3ebgP93nIH/d5yB/3ecgf93nIH/ + fK6d/3yunf98rp3/fK6d/37R+v9+0fr/ftH6/37R+v8zgWj/M4Fo/zOBaP8zgWj/ImQy/yJkMv8iZDL/ + ImQy/y2CQf8tgkH/LYJB/y2CQf8viUX/L4lF/y+JRf8viUX/gbeO/4G3jv+Bt47/gbeO/4G3jv+Bt47/ + gbeO/4G3jv+Bt47/gbeO/4G3jv+Bt47/gr6n/4K+p/+Cvqf/gr6n/4fU+/+H1Pv/h9T7/4fU+/95pJj/ + eaSY/3mkmP95pJj/c496/3OPev9zj3r/c496/3OQev9zkHr/c5B6/3OQev9zkXr/c5F6/3ORev9zkXr/ + dJJ7/3SSe/90knv/dJJ7/3SSe/90knv/dJJ7/3SSe/94loD/eJaA/3iWgP94loD/7fDs/+3w7P/t8Oz/ + 7fDs/9Te1v/U3tb/1N7W/9Te1v+/zcL/v83C/7/Nwv+/zcL/v83C/7/Nwv+/zcL/v83C/7/Owv+/zsL/ + v87C/7/Owv+/zsL/v87C/7/Owv+/zsL/1d/X/9Xf1//V39f/1d/X/+3w7f/t8O3/7fDt/+3w7f96nIP/ + epyD/3qcg/96nIP/dpl//3aZf/92mX//dpl//3eaf/93mn//d5p//3eaf/93m3//d5t//3ebf/93m3// + d5uA/3ebgP93m4D/d5uA/3ecgf93nIH/d5yB/3ecgf98rp3/fK6d/3yunf98rp3/ftH6/37R+v9+0fr/ + ftH6/zOBaP8zgWj/M4Fo/zOBaP8iZDL/ImQy/yJkMv8iZDL/LYJB/y2CQf8tgkH/LYJB/y+JRf8viUX/ + L4lF/y+JRf+EuZH/hLmR/4S5kf+EuZH/hLmR/4S5kf+EuZH/hLmR/4S5kf+EuZH/hLmR/4S5kf+FwKz/ + hcCs/4XArP+FwKz/idb7/4nW+/+J1vv/idb7/32qof99qqH/faqh/32qof92kXz/dpF8/3aRfP92kXz/ + dpJ9/3aSff92kn3/dpJ9/3aTfv92k37/dpN+/3aTfv92k37/dpN+/3aTfv92k37/dpR+/3aUfv92lH7/ + dpR+/3eUfv93lH7/d5R+/3eUfv+Cnor/gp6K/4Keiv+Cnor/tca5/7XGuf+1xrn/tca5/8DOw//AzsP/ + wM7D/8DOw//Az8P/wM/D/8DPw//Az8P/wM/E/8DPxP/Az8T/wM/E/8DPxP/Az8T/wM/E/8DPxP+2yLr/ + tsi6/7bIuv+2yLr/hKOL/4Sji/+Eo4v/hKOL/3mbgv95m4L/eZuC/3mbgv95m4L/eZuC/3mbgv95m4L/ + eZyC/3mcgv95nIL/eZyC/3mdgv95nYL/eZ2C/3mdgv96nYP/ep2D/3qdg/96nYP/ep6D/3qeg/96noP/ + ep6D/4Cypf+AsqX/gLKl/4Cypf+J1vv/idb7/4nW+/+J1vv/dKyc/3SsnP90rJz/dKyc/zSGSv80hkr/ + NIZK/zSGSv8wikf/MIpH/zCKR/8wikf/MIpH/zCKR/8wikf/MIpH/4S5kf+EuZH/hLmR/4S5kf+EuZH/ + hLmR/4S5kf+EuZH/hLmR/4S5kf+EuZH/hLmR/4XArP+FwKz/hcCs/4XArP+J1vv/idb7/4nW+/+J1vv/ + faqh/32qof99qqH/faqh/3aRfP92kXz/dpF8/3aRfP92kn3/dpJ9/3aSff92kn3/dpN+/3aTfv92k37/ + dpN+/3aTfv92k37/dpN+/3aTfv92lH7/dpR+/3aUfv92lH7/d5R+/3eUfv93lH7/d5R+/4Keiv+Cnor/ + gp6K/4Keiv+1xrn/tca5/7XGuf+1xrn/wM7D/8DOw//AzsP/wM7D/8DPw//Az8P/wM/D/8DPw//Az8T/ + wM/E/8DPxP/Az8T/wM/E/8DPxP/Az8T/wM/E/7bIuv+2yLr/tsi6/7bIuv+Eo4v/hKOL/4Sji/+Eo4v/ + eZuC/3mbgv95m4L/eZuC/3mbgv95m4L/eZuC/3mbgv95nIL/eZyC/3mcgv95nIL/eZ2C/3mdgv95nYL/ + eZ2C/3qdg/96nYP/ep2D/3qdg/96noP/ep6D/3qeg/96noP/gLKl/4Cypf+AsqX/gLKl/4nW+/+J1vv/ + idb7/4nW+/90rJz/dKyc/3SsnP90rJz/NIZK/zSGSv80hkr/NIZK/zCKR/8wikf/MIpH/zCKR/8wikf/ + MIpH/zCKR/8wikf/hLmR/4S5kf+EuZH/hLmR/4S5kf+EuZH/hLmR/4S5kf+EuZH/hLmR/4S5kf+EuZH/ + hcCs/4XArP+FwKz/hcCs/4nW+/+J1vv/idb7/4nW+/99qqH/faqh/32qof99qqH/dpF8/3aRfP92kXz/ + dpF8/3aSff92kn3/dpJ9/3aSff92k37/dpN+/3aTfv92k37/dpN+/3aTfv92k37/dpN+/3aUfv92lH7/ + dpR+/3aUfv93lH7/d5R+/3eUfv93lH7/gp6K/4Keiv+Cnor/gp6K/7XGuf+1xrn/tca5/7XGuf/AzsP/ + wM7D/8DOw//AzsP/wM/D/8DPw//Az8P/wM/D/8DPxP/Az8T/wM/E/8DPxP/Az8T/wM/E/8DPxP/Az8T/ + tsi6/7bIuv+2yLr/tsi6/4Sji/+Eo4v/hKOL/4Sji/95m4L/eZuC/3mbgv95m4L/eZuC/3mbgv95m4L/ + eZuC/3mcgv95nIL/eZyC/3mcgv95nYL/eZ2C/3mdgv95nYL/ep2D/3qdg/96nYP/ep2D/3qeg/96noP/ + ep6D/3qeg/+AsqX/gLKl/4Cypf+AsqX/idb7/4nW+/+J1vv/idb7/3SsnP90rJz/dKyc/3SsnP80hkr/ + NIZK/zSGSv80hkr/MIpH/zCKR/8wikf/MIpH/zCKR/8wikf/MIpH/zCKR/+EuZH/hLmR/4S5kf+EuZH/ + hLmR/4S5kf+EuZH/hLmR/4S5kf+EuZH/hLmR/4S5kf+FwKz/hcCs/4XArP+FwKz/idb7/4nW+/+J1vv/ + idb7/32qof99qqH/faqh/32qof92kXz/dpF8/3aRfP92kXz/dpJ9/3aSff92kn3/dpJ9/3aTfv92k37/ + dpN+/3aTfv92k37/dpN+/3aTfv92k37/dpR+/3aUfv92lH7/dpR+/3eUfv93lH7/d5R+/3eUfv+Cnor/ + gp6K/4Keiv+Cnor/tca5/7XGuf+1xrn/tca5/8DOw//AzsP/wM7D/8DOw//Az8P/wM/D/8DPw//Az8P/ + wM/E/8DPxP/Az8T/wM/E/8DPxP/Az8T/wM/E/8DPxP+2yLr/tsi6/7bIuv+2yLr/hKOL/4Sji/+Eo4v/ + hKOL/3mbgv95m4L/eZuC/3mbgv95m4L/eZuC/3mbgv95m4L/eZyC/3mcgv95nIL/eZyC/3mdgv95nYL/ + eZ2C/3mdgv96nYP/ep2D/3qdg/96nYP/ep6D/3qeg/96noP/ep6D/4Cypf+AsqX/gLKl/4Cypf+J1vv/ + idb7/4nW+/+J1vv/dKyc/3SsnP90rJz/dKyc/zSGSv80hkr/NIZK/zSGSv8wikf/MIpH/zCKR/8wikf/ + MIpH/zCKR/8wikf/MIpH/4e8lf+HvJX/h7yV/4e8lf+HvJX/h7yV/4e8lf+HvJX/h7yV/4e8lf+HvJX/ + h7yV/4i/oP+Iv6D/iL+g/4i/oP+M1vX/jNb1/4zW9f+M1vX/jdj6/43Y+v+N2Pr/jdj6/4rM2/+KzNv/ + iszb/4rM2/+Fu7v/hbu7/4W7u/+Fu7v/gKmc/4CpnP+AqZz/gKmc/3uYg/97mIP/e5iD/3uYg/96l4L/ + epeC/3qXgv96l4L/e5eC/3uXgv97l4L/e5eC/3uYgv97mIL/e5iC/3uYgv97mIL/e5iC/3uYgv97mIL/ + e5mD/3uZg/97mYP/e5mD/3uZg/97mYP/e5mD/3uZg/98moP/fJqD/3yag/98moP/fJuE/3ybhP98m4T/ + fJuE/3ychP98nIT/fJyE/3ychP98nIX/fJyF/3ychf98nIX/fJ2F/3ydhf98nYX/fJ2F/32dhf99nYX/ + fZ2F/32dhf9+oIf/fqCH/36gh/9+oIf/gq6g/4KuoP+CrqD/gq6g/4a/vP+Gv7z/hr+8/4a/vP+Kzdz/ + is3c/4rN3P+Kzdz/jdj6/43Y+v+N2Pr/jdj6/43W9f+N1vX/jdb1/43W9f+HvqH/h76h/4e+of+HvqH/ + drKF/3ayhf92soX/drKF/zOMSv8zjEr/M4xK/zOMSv8xi0j/MYtI/zGLSP8xi0j/h7yV/4e8lf+HvJX/ + h7yV/4e8lf+HvJX/h7yV/4e8lf+HvJX/h7yV/4e8lf+HvJX/iL+g/4i/oP+Iv6D/iL+g/4zW9f+M1vX/ + jNb1/4zW9f+N2Pr/jdj6/43Y+v+N2Pr/iszb/4rM2/+KzNv/iszb/4W7u/+Fu7v/hbu7/4W7u/+AqZz/ + gKmc/4CpnP+AqZz/e5iD/3uYg/97mIP/e5iD/3qXgv96l4L/epeC/3qXgv97l4L/e5eC/3uXgv97l4L/ + e5iC/3uYgv97mIL/e5iC/3uYgv97mIL/e5iC/3uYgv97mYP/e5mD/3uZg/97mYP/e5mD/3uZg/97mYP/ + e5mD/3yag/98moP/fJqD/3yag/98m4T/fJuE/3ybhP98m4T/fJyE/3ychP98nIT/fJyE/3ychf98nIX/ + fJyF/3ychf98nYX/fJ2F/3ydhf98nYX/fZ2F/32dhf99nYX/fZ2F/36gh/9+oIf/fqCH/36gh/+CrqD/ + gq6g/4KuoP+CrqD/hr+8/4a/vP+Gv7z/hr+8/4rN3P+Kzdz/is3c/4rN3P+N2Pr/jdj6/43Y+v+N2Pr/ + jdb1/43W9f+N1vX/jdb1/4e+of+HvqH/h76h/4e+of92soX/drKF/3ayhf92soX/M4xK/zOMSv8zjEr/ + M4xK/zGLSP8xi0j/MYtI/zGLSP+HvJX/h7yV/4e8lf+HvJX/h7yV/4e8lf+HvJX/h7yV/4e8lf+HvJX/ + h7yV/4e8lf+Iv6D/iL+g/4i/oP+Iv6D/jNb1/4zW9f+M1vX/jNb1/43Y+v+N2Pr/jdj6/43Y+v+KzNv/ + iszb/4rM2/+KzNv/hbu7/4W7u/+Fu7v/hbu7/4CpnP+AqZz/gKmc/4CpnP97mIP/e5iD/3uYg/97mIP/ + epeC/3qXgv96l4L/epeC/3uXgv97l4L/e5eC/3uXgv97mIL/e5iC/3uYgv97mIL/e5iC/3uYgv97mIL/ + e5iC/3uZg/97mYP/e5mD/3uZg/97mYP/e5mD/3uZg/97mYP/fJqD/3yag/98moP/fJqD/3ybhP98m4T/ + fJuE/3ybhP98nIT/fJyE/3ychP98nIT/fJyF/3ychf98nIX/fJyF/3ydhf98nYX/fJ2F/3ydhf99nYX/ + fZ2F/32dhf99nYX/fqCH/36gh/9+oIf/fqCH/4KuoP+CrqD/gq6g/4KuoP+Gv7z/hr+8/4a/vP+Gv7z/ + is3c/4rN3P+Kzdz/is3c/43Y+v+N2Pr/jdj6/43Y+v+N1vX/jdb1/43W9f+N1vX/h76h/4e+of+HvqH/ + h76h/3ayhf92soX/drKF/3ayhf8zjEr/M4xK/zOMSv8zjEr/MYtI/zGLSP8xi0j/MYtI/4e8lf+HvJX/ + h7yV/4e8lf+HvJX/h7yV/4e8lf+HvJX/h7yV/4e8lf+HvJX/h7yV/4i/oP+Iv6D/iL+g/4i/oP+M1vX/ + jNb1/4zW9f+M1vX/jdj6/43Y+v+N2Pr/jdj6/4rM2/+KzNv/iszb/4rM2/+Fu7v/hbu7/4W7u/+Fu7v/ + gKmc/4CpnP+AqZz/gKmc/3uYg/97mIP/e5iD/3uYg/96l4L/epeC/3qXgv96l4L/e5eC/3uXgv97l4L/ + e5eC/3uYgv97mIL/e5iC/3uYgv97mIL/e5iC/3uYgv97mIL/e5mD/3uZg/97mYP/e5mD/3uZg/97mYP/ + e5mD/3uZg/98moP/fJqD/3yag/98moP/fJuE/3ybhP98m4T/fJuE/3ychP98nIT/fJyE/3ychP98nIX/ + fJyF/3ychf98nIX/fJ2F/3ydhf98nYX/fJ2F/32dhf99nYX/fZ2F/32dhf9+oIf/fqCH/36gh/9+oIf/ + gq6g/4KuoP+CrqD/gq6g/4a/vP+Gv7z/hr+8/4a/vP+Kzdz/is3c/4rN3P+Kzdz/jdj6/43Y+v+N2Pr/ + jdj6/43W9f+N1vX/jdb1/43W9f+HvqH/h76h/4e+of+HvqH/drKF/3ayhf92soX/drKF/zOMSv8zjEr/ + M4xK/zOMSv8xi0j/MYtI/zGLSP8xi0j/ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ + ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/4rBof+KwaH/isGh/4rBof+NysX/jcrF/43Kxf+NysX/ + jtPk/47T5P+O0+T/jtPk/4/Z+v+P2fr/j9n6/4/Z+v+P2fr/j9n6/4/Z+v+P2fr/j9j4/4/Y+P+P2Pj/ + j9j4/47U7P+O1Oz/jtTs/47U7P+Nz93/jc/d/43P3f+Nz93/i8fO/4vHzv+Lx87/i8fO/4rEx/+KxMf/ + isTH/4rEx/+JwcH/icHB/4nBwf+JwcH/ib68/4m+vP+Jvrz/ib68/4m/vP+Jv7z/ib+8/4m/vP+JwsL/ + icLC/4nCwv+JwsL/isTH/4rEx/+KxMf/isTH/4vJz/+Lyc//i8nP/4vJz/+Nz93/jc/d/43P3f+Nz93/ + jtTs/47U7P+O1Oz/jtTs/4/Y+P+P2Pj/j9j4/4/Y+P+P2fr/j9n6/4/Z+v+P2fr/j9n6/4/Z+v+P2fr/ + j9n6/47T5v+O0+b/jtPm/47T5v+My8j/jMvI/4zLyP+My8j/i8Ch/4vAof+LwKH/i8Ch/4q+mP+Kvpj/ + ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/Z6t4/2ereP9nq3j/Z6t4/zKNSf8yjUn/Mo1J/zKNSf+Kvpj/ + ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ + isGh/4rBof+KwaH/isGh/43Kxf+NysX/jcrF/43Kxf+O0+T/jtPk/47T5P+O0+T/j9n6/4/Z+v+P2fr/ + j9n6/4/Z+v+P2fr/j9n6/4/Z+v+P2Pj/j9j4/4/Y+P+P2Pj/jtTs/47U7P+O1Oz/jtTs/43P3f+Nz93/ + jc/d/43P3f+Lx87/i8fO/4vHzv+Lx87/isTH/4rEx/+KxMf/isTH/4nBwf+JwcH/icHB/4nBwf+Jvrz/ + ib68/4m+vP+Jvrz/ib+8/4m/vP+Jv7z/ib+8/4nCwv+JwsL/icLC/4nCwv+KxMf/isTH/4rEx/+KxMf/ + i8nP/4vJz/+Lyc//i8nP/43P3f+Nz93/jc/d/43P3f+O1Oz/jtTs/47U7P+O1Oz/j9j4/4/Y+P+P2Pj/ + j9j4/4/Z+v+P2fr/j9n6/4/Z+v+P2fr/j9n6/4/Z+v+P2fr/jtPm/47T5v+O0+b/jtPm/4zLyP+My8j/ + jMvI/4zLyP+LwKH/i8Ch/4vAof+LwKH/ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/4q+mP9nq3j/ + Z6t4/2ereP9nq3j/Mo1J/zKNSf8yjUn/Mo1J/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ + ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+KwaH/isGh/4rBof+KwaH/jcrF/43Kxf+NysX/ + jcrF/47T5P+O0+T/jtPk/47T5P+P2fr/j9n6/4/Z+v+P2fr/j9n6/4/Z+v+P2fr/j9n6/4/Y+P+P2Pj/ + j9j4/4/Y+P+O1Oz/jtTs/47U7P+O1Oz/jc/d/43P3f+Nz93/jc/d/4vHzv+Lx87/i8fO/4vHzv+KxMf/ + isTH/4rEx/+KxMf/icHB/4nBwf+JwcH/icHB/4m+vP+Jvrz/ib68/4m+vP+Jv7z/ib+8/4m/vP+Jv7z/ + icLC/4nCwv+JwsL/icLC/4rEx/+KxMf/isTH/4rEx/+Lyc//i8nP/4vJz/+Lyc//jc/d/43P3f+Nz93/ + jc/d/47U7P+O1Oz/jtTs/47U7P+P2Pj/j9j4/4/Y+P+P2Pj/j9n6/4/Z+v+P2fr/j9n6/4/Z+v+P2fr/ + j9n6/4/Z+v+O0+b/jtPm/47T5v+O0+b/jMvI/4zLyP+My8j/jMvI/4vAof+LwKH/i8Ch/4vAof+Kvpj/ + ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/2ereP9nq3j/Z6t4/2ereP8yjUn/Mo1J/zKNSf8yjUn/ + ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ + ir6Y/4rBof+KwaH/isGh/4rBof+NysX/jcrF/43Kxf+NysX/jtPk/47T5P+O0+T/jtPk/4/Z+v+P2fr/ + j9n6/4/Z+v+P2fr/j9n6/4/Z+v+P2fr/j9j4/4/Y+P+P2Pj/j9j4/47U7P+O1Oz/jtTs/47U7P+Nz93/ + jc/d/43P3f+Nz93/i8fO/4vHzv+Lx87/i8fO/4rEx/+KxMf/isTH/4rEx/+JwcH/icHB/4nBwf+JwcH/ + ib68/4m+vP+Jvrz/ib68/4m/vP+Jv7z/ib+8/4m/vP+JwsL/icLC/4nCwv+JwsL/isTH/4rEx/+KxMf/ + isTH/4vJz/+Lyc//i8nP/4vJz/+Nz93/jc/d/43P3f+Nz93/jtTs/47U7P+O1Oz/jtTs/4/Y+P+P2Pj/ + j9j4/4/Y+P+P2fr/j9n6/4/Z+v+P2fr/j9n6/4/Z+v+P2fr/j9n6/47T5v+O0+b/jtPm/47T5v+My8j/ + jMvI/4zLyP+My8j/i8Ch/4vAof+LwKH/i8Ch/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ + Z6t4/2ereP9nq3j/Z6t4/zKNSf8yjUn/Mo1J/zKNSf+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcKj/43Co/+NwqP/jcKj/4/Iuf+PyLn/j8i5/4/Iuf+Pzcn/ + j83J/4/Nyf+Pzcn/kNHZ/5DR2f+Q0dn/kNHZ/5HV6P+R1ej/kdXo/5HV6P+R1/L/kdfy/5HX8v+R1/L/ + kdn2/5HZ9v+R2fb/kdn2/5La+v+S2vr/ktr6/5La+v+S2vv/ktr7/5La+/+S2vv/ktr7/5La+/+S2vv/ + ktr7/5La+v+S2vr/ktr6/5La+v+R2fb/kdn2/5HZ9v+R2fb/kdfy/5HX8v+R1/L/kdfy/5HV6P+R1ej/ + kdXo/5HV6P+Q0dj/kNHY/5DR2P+Q0dj/j8zI/4/MyP+PzMj/j8zI/4/Iuf+PyLn/j8i5/4/Iuf+NwqP/ + jcKj/43Co/+NwqP/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/VKFp/1Shaf9UoWn/ + VKFp/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwqP/ + jcKj/43Co/+NwqP/j8i5/4/Iuf+PyLn/j8i5/4/Nyf+Pzcn/j83J/4/Nyf+Q0dn/kNHZ/5DR2f+Q0dn/ + kdXo/5HV6P+R1ej/kdXo/5HX8v+R1/L/kdfy/5HX8v+R2fb/kdn2/5HZ9v+R2fb/ktr6/5La+v+S2vr/ + ktr6/5La+/+S2vv/ktr7/5La+/+S2vv/ktr7/5La+/+S2vv/ktr6/5La+v+S2vr/ktr6/5HZ9v+R2fb/ + kdn2/5HZ9v+R1/L/kdfy/5HX8v+R1/L/kdXo/5HV6P+R1ej/kdXo/5DR2P+Q0dj/kNHY/5DR2P+PzMj/ + j8zI/4/MyP+PzMj/j8i5/4/Iuf+PyLn/j8i5/43Co/+NwqP/jcKj/43Co/+NwJv/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwJv/jcCb/43Am/9UoWn/VKFp/1Shaf9UoWn/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Co/+NwqP/jcKj/43Co/+PyLn/j8i5/4/Iuf+PyLn/ + j83J/4/Nyf+Pzcn/j83J/5DR2f+Q0dn/kNHZ/5DR2f+R1ej/kdXo/5HV6P+R1ej/kdfy/5HX8v+R1/L/ + kdfy/5HZ9v+R2fb/kdn2/5HZ9v+S2vr/ktr6/5La+v+S2vr/ktr7/5La+/+S2vv/ktr7/5La+/+S2vv/ + ktr7/5La+/+S2vr/ktr6/5La+v+S2vr/kdn2/5HZ9v+R2fb/kdn2/5HX8v+R1/L/kdfy/5HX8v+R1ej/ + kdXo/5HV6P+R1ej/kNHY/5DR2P+Q0dj/kNHY/4/MyP+PzMj/j8zI/4/MyP+PyLn/j8i5/4/Iuf+PyLn/ + jcKj/43Co/+NwqP/jcKj/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/1Shaf9UoWn/ + VKFp/1Shaf+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/ + jcKj/43Co/+NwqP/jcKj/4/Iuf+PyLn/j8i5/4/Iuf+Pzcn/j83J/4/Nyf+Pzcn/kNHZ/5DR2f+Q0dn/ + kNHZ/5HV6P+R1ej/kdXo/5HV6P+R1/L/kdfy/5HX8v+R1/L/kdn2/5HZ9v+R2fb/kdn2/5La+v+S2vr/ + ktr6/5La+v+S2vv/ktr7/5La+/+S2vv/ktr7/5La+/+S2vv/ktr7/5La+v+S2vr/ktr6/5La+v+R2fb/ + kdn2/5HZ9v+R2fb/kdfy/5HX8v+R1/L/kdfy/5HV6P+R1ej/kdXo/5HV6P+Q0dj/kNHY/5DR2P+Q0dj/ + j8zI/4/MyP+PzMj/j8zI/4/Iuf+PyLn/j8i5/4/Iuf+NwqP/jcKj/43Co/+NwqP/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/VKFp/1Shaf9UoWn/VKFp/4zAmvGMwJrxjMCa8YzAmvGQwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKe/5DCnv+Qwp7/kMKe/5DEo/+QxKP/kMSj/5DEo/+QxKL/ + kMSi/5DEov+QxKL/kMKe/5DCnv+Qwp7/kMKe/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+NwZrx + jcGa8Y3BmvGNwZrxjMCa8YzAmvGMwJrxjMCa8ZDCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp7/ + kMKe/5DCnv+Qwp7/kMSj/5DEo/+QxKP/kMSj/5DEov+QxKL/kMSi/5DEov+Qwp7/kMKe/5DCnv+Qwp7/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/43BmvGNwZrxjcGa8Y3BmvGMwJrxjMCa8YzAmvGMwJrx + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnv+Qwp7/kMKe/5DCnv+QxKP/kMSj/5DEo/+QxKP/ + kMSi/5DEov+QxKL/kMSi/5DCnv+Qwp7/kMKe/5DCnv+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + jcGa8Y3BmvGNwZrxjcGa8YzAmvGMwJrxjMCa8YzAmvGQwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKe/5DCnv+Qwp7/kMKe/5DEo/+QxKP/kMSj/5DEo/+QxKL/kMSi/5DEov+QxKL/kMKe/5DCnv+Qwp7/ + kMKe/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+NwZrxjcGa8Y3BmvGNwZrxhr6XxIa+l8SGvpfE + hr6XxJTFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/4/CncaPwp3Gj8Kdxo/CncaGvpfEhr6XxIa+l8SGvpfElMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/j8Kdxo/CncaPwp3Gj8Kdxoa+l8SGvpfE + hr6XxIa+l8SUxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+Pwp3Gj8Kdxo/CncaPwp3Ghr6XxIa+l8SGvpfEhr6XxJTFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/4/CncaPwp3Gj8Kdxo/CncZ8u48p + fLuPKXy7jyl8u48pk8ag9ZPGoPWTxqD1k8ag9ZbHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+YyKX2 + mMil9pjIpfaYyKX2mceoMpnHqDKZx6gymceoMny7jyl8u48pfLuPKXy7jymTxqD1k8ag9ZPGoPWTxqD1 + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5jIpfaYyKX2mMil9pjIpfaZx6gymceoMpnHqDKZx6gy + fLuPKXy7jyl8u48pfLuPKZPGoPWTxqD1k8ag9ZPGoPWWx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + mMil9pjIpfaYyKX2mMil9pnHqDKZx6gymceoMpnHqDJ8u48pfLuPKXy7jyl8u48pk8ag9ZPGoPWTxqD1 + k8ag9ZbHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+YyKX2mMil9pjIpfaYyKX2mceoMpnHqDKZx6gy + mceoMgAAAAAAAAAAAAAAAAAAAAB8u48pfLuPKXy7jyl8u48pjMKbxYzCm8WMwpvFjMKbxZbHo/KWx6Py + lsej8pbHo/KZyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+ayafzmsmn85rJp/OayafzlsaiyZbGosmWxqLJ + lsaiyZvIqjObyKozm8iqM5vIqjMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHy7jyl8u48p + fLuPKXy7jymMwpvFjMKbxYzCm8WMwpvFlsej8pbHo/KWx6Pylsej8pnJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5rJp/Oayafzmsmn85rJp/OWxqLJlsaiyZbGosmWxqLJm8iqM5vIqjObyKozm8iqMwAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfLuPKXy7jyl8u48pfLuPKYzCm8WMwpvFjMKbxYzCm8WWx6Py + lsej8pbHo/KWx6Pymcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/msmn85rJp/Oayafzmsmn85bGosmWxqLJ + lsaiyZbGosmbyKozm8iqM5vIqjObyKozAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB8u48p + fLuPKXy7jyl8u48pjMKbxYzCm8WMwpvFjMKbxZbHo/KWx6Pylsej8pbHo/KZyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+ayafzmsmn85rJp/OayafzlsaiyZbGosmWxqLJlsaiyZvIqjObyKozm8iqM5vIqjMAAAAA + AAAAAAAAAAAAAAAA8AAAAAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAAAP + 8AAAAAAAAAAAAAAAAAAADwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAPAAAAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAA + AAAAD/AAAAAAAAAAAAAAAAAAAA8oAAAAQAAAAIAAAAABACAAAAAAAABAAAATCwAAEwsAAAAAAAAAAAAA + AAAAAAAAAAAbZCQcG2QkHB1nJqkdZyapHGcm5xxnJuccZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/ + HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/ + HGcm/xxnJv8YWiH/GFoh/xZSHv8WUh7/F1Mf/xdTH/8XVB//F1Qf/xdUH/8XVB//F1Yg/xdWIP8XViD/ + F1Yg/xhXIP8YVyD/GFgg/xhYIP8YWSH/GFkh/xhaIf8YWiH/GVoh/xlaIf8YXCLpGFwi6RpcIq8aXCKv + GVohHxlaIR8AAAAAAAAAAAAAAAAAAAAAG2QkHBtkJBwdZyapHWcmqRxnJuccZybnHGcm/xxnJv8cZyb/ + HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/ + HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/GFoh/xhaIf8WUh7/FlIe/xdTH/8XUx//F1Qf/xdUH/8XVB// + F1Qf/xdWIP8XViD/F1Yg/xdWIP8YVyD/GFcg/xhYIP8YWCD/GFkh/xhZIf8YWiH/GFoh/xlaIf8ZWiH/ + GFwi6RhcIukaXCKvGlwirxlaIR8ZWiEfAAAAAAAAAAAbZCQcG2QkHB1oJ+0daCftHWgn/x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8ZWiL/GVoi/xdRHv8XUR7/F1If/xdSH/8XUx// + F1Mf/xdUH/8XVB//GFQg/xhUIP8YVSD/GFUg/xhWIP8YViD/GFch/xhXIf8ZWCH/GVgh/xlZIf8ZWSH/ + GVoi/xlaIv8ZWyL/GVsi/xlbIv8ZWyL/Glwj/xpcI/8aXSLvGl0i7xlaIR8ZWiEfG2QkHBtkJBwdaCft + HWgn7R1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/GVoi/xlaIv8XUR7/ + F1Ee/xdSH/8XUh//F1Mf/xdTH/8XVB//F1Qf/xhUIP8YVCD/GFUg/xhVIP8YViD/GFYg/xhXIf8YVyH/ + GVgh/xlYIf8ZWSH/GVkh/xlaIv8ZWiL/GVsi/xlbIv8ZWyL/GVsi/xpcI/8aXCP/Gl0i7xpdIu8ZWiEf + GVohHx5qKakeaimpHmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8aWyL/ + Glsi/xdRH/8XUR//F1If/xdSH/8XUx//F1Mf/xhUIP8YVCD/GFQg/xhUIP8YVSD/GFUg/xhWIP8YViD/ + GVch/xlXIf8ZWCH/GVgh/xlZIv8ZWSL/GVoi/xlaIv8aWyL/Glsi/xpbI/8aWyP/Glwj/xpcI/8aXSP/ + Gl0j/xteI/8bXiP/HF8krxxfJK8eaimpHmopqR5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Glsi/xpbIv8XUR//F1Ef/xdSH/8XUh//F1Mf/xdTH/8YVCD/GFQg/xhUIP8YVCD/ + GFUg/xhVIP8YViD/GFYg/xlXIf8ZVyH/GVgh/xlYIf8ZWSL/GVki/xlaIv8ZWiL/Glsi/xpbIv8aWyP/ + Glsj/xpcI/8aXCP/Gl0j/xpdI/8bXiP/G14j/xxfJK8cXySvH2sq6B9rKugfayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8aWyT/Glsk/xdQH/8XUB//Hmlg/x5pYP8eamD/Hmpg/xhTIP8YUyD/ + GFQh/xhUIf8YVCH/GFQh/xlVIf8ZVSH/GVYi/xlWIv8ZVyL/GVci/xlYIv8ZWCL/Glkj/xpZI/8aWiP/ + Gloj/xpbJP8aWyT/G1sk/xtbJP8bXCT/G1wk/xtdJf8bXSX/G14l/xteJf8bXyXpG18l6R9rKugfayro + H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/Glsk/xpbJP8XUB//F1Af/x5pYP8eaWD/ + Hmpg/x5qYP8YUyD/GFMg/xhUIf8YVCH/GFQh/xhUIf8ZVSH/GVUh/xlWIv8ZViL/GVci/xlXIv8ZWCL/ + GVgi/xpZI/8aWSP/Gloj/xpaI/8aWyT/Glsk/xtbJP8bWyT/G1wk/xtcJP8bXSX/G10l/xteJf8bXiX/ + G18l6RtfJekgbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8bWyT/G1sk/x5oWv8eaFr/ + JYKy/yWCsv8pk9//KZPf/ymT3/8pk9//JYKu/yWCrv8eZ1T/HmdU/xlVIv8ZVSL/GVYi/xlWIv8ZVyL/ + GVci/xpYI/8aWCP/Glgj/xpYI/8aWSP/Glkj/xtbJP8bWyT/G1sk/xtbJP8bXCT/G1wk/xtdJf8bXSX/ + HF4l/xxeJf8cXyX/HF8l/xxgJv8cYCb/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + G1sk/xtbJP8eaFr/Hmha/yWCsv8lgrL/KZPf/ymT3/8pk9//KZPf/yWCrv8lgq7/HmdU/x5nVP8ZVSL/ + GVUi/xlWIv8ZViL/GVci/xlXIv8aWCP/Glgj/xpYI/8aWCP/Glkj/xpZI/8bWyT/G1sk/xtbJP8bWyT/ + G1wk/xtcJP8bXSX/G10l/xxeJf8cXiX/HF8l/xxfJf8cYCb/HGAm/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/yBuLf8dZUD/HWVA/ySBp/8kgaf/KZTf/ymU3/8upPf/LqT3/y+o/f8vqP3/L6j9/y+o/f8upPf/ + LqT3/ymU3/8plN//JICl/ySApf8cYkL/HGJC/xlXI/8ZVyP/GVgk/xlYJP8aWCT/Glgk/xpZJf8aWSX/ + Glol/xpaJf8bWyX/G1sl/xtcJv8bXCb/G10m/xtdJv8bXib/G14m/xxfJ/8cXyf/HGAn/xxgJ/8gbi3/ + IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/HWVA/x1lQP8kgaf/JIGn/ymU3/8plN//LqT3/y6k9/8vqP3/ + L6j9/y+o/f8vqP3/LqT3/y6k9/8plN//KZTf/ySApf8kgKX/HGJC/xxiQv8ZVyP/GVcj/xlYJP8ZWCT/ + Glgk/xpYJP8aWSX/Glkl/xpaJf8aWiX/G1sl/xtbJf8bXCb/G1wm/xtdJv8bXSb/G14m/xteJv8cXyf/ + HF8n/xxgJ/8cYCf/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/ + IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXEv/yFxL/8kfH7/JHx+/ymR1P8pkdT/L6X2/y+l9v8wqfz/ + MKn8/yybzf8sm83/IG5a/yBuWv8gbFj/IGxY/yyazP8smsz/MKn8/zCp/P8vpfb/L6X2/yqR1P8qkdT/ + IHRx/yB0cf8aWCT/Glgk/xpZJf8aWSX/G1ol/xtaJf8bWyX/G1sl/xtcJv8bXCb/G10m/xtdJv8cXif/ + HF4n/xxfJ/8cXyf/HGAn/xxgJ/8cYSj/HGEo/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/ + IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFxL/8hcS//JHx+/yR8fv8pkdT/ + KZHU/y+l9v8vpfb/MKn8/zCp/P8sm83/LJvN/yBuWv8gblr/IGxY/yBsWP8smsz/LJrM/zCp/P8wqfz/ + L6X2/y+l9v8qkdT/KpHU/yB0cf8gdHH/Glgk/xpYJP8aWSX/Glkl/xtaJf8bWiX/G1sl/xtbJf8bXCb/ + G1wm/xtdJv8bXSb/HF4n/xxeJ/8cXyf/HF8n/xxgJ/8cYCf/HGEo/xxhKP8icS//InEv/yJxL/8icS// + InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//I3Q7/yN0O/8nh6r/ + J4eq/y2f7P8tn+z/MKr8/zCq/P8un9j/Lp/Y/yFyZv8hcmb/GFEi/xhRIv8ZUiL/GVIi/xlTIv8ZUyL/ + GVQj/xlUI/8idGf/InRn/y6f2P8un9j/MKr8/zCq/P8tn+z/LZ/s/yWEo/8lhKP/HF4z/xxeM/8bWiX/ + G1ol/xtbJv8bWyb/HFwm/xxcJv8cXSf/HF0n/xxeJ/8cXif/HV8n/x1fJ/8dYCj/HWAo/x1hKP8dYSj/ + InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS// + InEv/yN0O/8jdDv/J4eq/yeHqv8tn+z/LZ/s/zCq/P8wqvz/Lp/Y/y6f2P8hcmb/IXJm/xhRIv8YUSL/ + GVIi/xlSIv8ZUyL/GVMi/xlUI/8ZVCP/InRn/yJ0Z/8un9j/Lp/Y/zCq/P8wqvz/LZ/s/y2f7P8lhKP/ + JYSj/xxeM/8cXjP/G1ol/xtaJf8bWyb/G1sm/xxcJv8cXCb/HF0n/xxdJ/8cXif/HF4n/x1fJ/8dXyf/ + HWAo/x1gKP8dYSj/HWEo/yx4Ov8seDr/JXMz/yVzM/8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/ + I3Ix/yNyMf8jcjH/JHQ8/yR0PP8pj73/KY+9/zCp+f8wqfn/MKj0/zCo9P8mgYn/JoGJ/xlQJf8ZUCX/ + GFAi/xhQIv8ZUCP/GVAj/xlSI/8ZUiP/GVMk/xlTJP8aVCT/GlQk/xpUJP8aVCT/G1co/xtXKP8nhY3/ + J4WN/zCq9v8wqvb/MKn5/zCp+f8pjr3/KY69/x1fM/8dXzP/HFsn/xxbJ/8cXCf/HFwn/xxdKP8cXSj/ + HV0o/x1dKP8dXyn/HV8p/x1gKf8dYCn/HmEq/x5hKv8seDr/LHg6/yVzM/8lczP/I3Ix/yNyMf8jcjH/ + I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yR0PP8kdDz/KY+9/ymPvf8wqfn/MKn5/zCo9P8wqPT/ + JoGJ/yaBif8ZUCX/GVAl/xhQIv8YUCL/GVAj/xlQI/8ZUiP/GVIj/xlTJP8ZUyT/GlQk/xpUJP8aVCT/ + GlQk/xtXKP8bVyj/J4WN/yeFjf8wqvb/MKr2/zCp+f8wqfn/KY69/ymOvf8dXzP/HV8z/xxbJ/8cWyf/ + HFwn/xxcJ/8cXSj/HF0o/x1dKP8dXSj/HV8p/x1fKf8dYCn/HWAp/x5hKv8eYSr/UpFd/1KRXf9SkV3/ + UpFd/0mLVf9Ji1X/PoRK/z6ESv8zfkD/M35A/yh3Nv8odzb/JHY7/yR2O/8qk8D/KpPA/zGr+/8xq/v/ + Lp3N/y6dzf8dYEL/HWBC/xhOIv8YTiL/GU8i/xlPIv8ZUCP/GVAj/xlRI/8ZUSP/GVIj/xlSI/8aUyT/ + GlMk/xpUJP8aVCT/GlUl/xpVJf8bViX/G1Yl/xtXJf8bVyX/IGhJ/yBoSf8uoNP/LqDT/zGr+/8xq/v/ + KpPA/yqTwP8eYDL/HmAy/x1cKP8dXCj/HV0o/x1dKP8dXin/HV4p/x5fKf8eXyn/HmAq/x5gKv8eYSr/ + HmEq/1KRXf9SkV3/UpFd/1KRXf9Ji1X/SYtV/z6ESv8+hEr/M35A/zN+QP8odzb/KHc2/yR2O/8kdjv/ + KpPA/yqTwP8xq/v/Mav7/y6dzf8unc3/HWBC/x1gQv8YTiL/GE4i/xlPIv8ZTyL/GVAj/xlQI/8ZUSP/ + GVEj/xlSI/8ZUiP/GlMk/xpTJP8aVCT/GlQk/xpVJf8aVSX/G1Yl/xtWJf8bVyX/G1cl/yBoSf8gaEn/ + LqDT/y6g0/8xq/v/Mav7/yqTwP8qk8D/HmAy/x5gMv8dXCj/HVwo/x1dKP8dXSj/HV4p/x1eKf8eXyn/ + Hl8p/x5gKv8eYCr/HmEq/x5hKv9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/ + VpRh/1aUYf9Uprn/VKa5/0m2+/9Jtvv/NZy9/zWcvf9ZfV3/WX1d/2KDYv9ig2L/Y4Ni/2ODYv9jhGL/ + Y4Ri/2OFYv9jhWL/Y4Vi/2OFYv9jhmP/Y4Zj/2OHY/9jh2P/ZIdk/2SHZP9kiGT/ZIhk/2SJZP9kiWT/ + ZIlk/2SJZP9limT/ZYpk/1qFYv9ahWL/MJvC/zCbwv8yrfv/Mq37/yqQqf8qkKn/HVwo/x1cKP8dXSn/ + HV0p/x5eKf8eXin/Hl8p/x5fKf8eYCr/HmAq/x9iK/8fYiv/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/ + VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VKa5/1Smuf9Jtvv/Sbb7/zWcvf81nL3/WX1d/1l9Xf9ig2L/ + YoNi/2ODYv9jg2L/Y4Ri/2OEYv9jhWL/Y4Vi/2OFYv9jhWL/Y4Zj/2OGY/9jh2P/Y4dj/2SHZP9kh2T/ + ZIhk/2SIZP9kiWT/ZIlk/2SJZP9kiWT/ZYpk/2WKZP9ahWL/WoVi/zCbwv8wm8L/Mq37/zKt+/8qkKn/ + KpCp/x1cKP8dXCj/HV0p/x1dKf8eXin/Hl4p/x5fKf8eXyn/HmAq/x5gKv8fYiv/H2Ir/1iXZf9Yl2X/ + WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/WJdl/1iXZf9bn4j/W5+I/2LA+v9iwPr/XrHN/16xzf/O1Mb/ + ztTG/9fZzf/X2c3/xMq6/8TKuv+/xrT/v8a0/7/Gs/+/xrP/v8az/7/Gs/+/xrP/v8az/7/HtP+/x7T/ + v8e0/7/HtP+/x7T/v8e0/7/HtP+/x7T/v8i0/7/ItP+/yLT/v8i0/7/ItP+/yLT/zdLC/83Swv++ybb/ + vsm2/y6dw/8uncP/Mq36/zKt+v8jdV7/I3Ve/x1eKv8dXir/HV8q/x1fKv8eYCv/HmAr/x5hK/8eYSv/ + HmIs/x5iLP9Yl2X/WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/W5+I/1ufiP9iwPr/ + YsD6/16xzf9esc3/ztTG/87Uxv/X2c3/19nN/8TKuv/Eyrr/v8a0/7/GtP+/xrP/v8az/7/Gs/+/xrP/ + v8az/7/Gs/+/x7T/v8e0/7/HtP+/x7T/v8e0/7/HtP+/x7T/v8e0/7/ItP+/yLT/v8i0/7/ItP+/yLT/ + v8i0/83Swv/N0sL/vsm2/77Jtv8uncP/Lp3D/zKt+v8yrfr/I3Ve/yN1Xv8dXir/HV4q/x1fKv8dXyr/ + HmAr/x5gK/8eYSv/HmEr/x5iLP8eYiz/XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/ + XJpo/2W73/9lu9//Zb/t/2W/7f9UgGb/VIBm//v07f/79O3/X4Jk/1+CZP9Selr/Unpa/1B4WP9QeFj/ + PGpF/zxqRf8gVSv/IFUr/xpRJP8aUST/J1sx/ydbMf8nXDH/J1wx/xtUJv8bVCb/G1Um/xtVJv8bVif/ + G1Yn/xxXJ/8cVyf/HFgo/xxYKP8sZDX/LGQ1//nw5//58Of/IGU+/yBlPv8yquv/Mqrr/zGk1/8xpNf/ + Hl4q/x5eKv8eXyv/Hl8r/x5gK/8eYCv/H2Ar/x9gK/8fYiz/H2Is/1yaaP9cmmj/XJpo/1yaaP9cmmj/ + XJpo/1yaaP9cmmj/XJpo/1yaaP9lu9//Zbvf/2W/7f9lv+3/VIBm/1SAZv/79O3/+/Tt/1+CZP9fgmT/ + Unpa/1J6Wv9QeFj/UHhY/zxqRf88akX/IFUr/yBVK/8aUST/GlEk/ydbMf8nWzH/J1wx/ydcMf8bVCb/ + G1Qm/xtVJv8bVSb/G1Yn/xtWJ/8cVyf/HFcn/xxYKP8cWCj/LGQ1/yxkNf/58Of/+fDn/yBlPv8gZT7/ + Mqrr/zKq6/8xpNf/MaTX/x5eKv8eXir/Hl8r/x5fK/8eYCv/HmAr/x9gK/8fYCv/H2Is/x9iLP9gnWz/ + YJ1s/2CdbP9gnWz/YJ1s/2CdbP9gnWz/YJ1s/2Gjg/9ho4P/acX8/2nF/P9goKH/YKCh/1V6XP9Velz/ + +/Xw//v18P9fg2b/X4Nm/1V9Xv9VfV7/VX1e/1V9Xv9VfV7/VX1e/1R9Xf9UfV3/PGtF/zxrRf+Qp47/ + kKeO/4+mjP+Ppoz/G1Qn/xtUJ/8bVSf/G1Un/xxWKP8cVij/HFgo/xxYKP8cWSn/HFkp/ytiNf8rYjX/ + +vLq//ry6v8dWyr/HVsq/ymIh/8piIf/M7D7/zOw+/8jcFD/I3BQ/x5fLP8eXyz/H2As/x9gLP8fYS3/ + H2Et/yBjLf8gYy3/YJ1s/2CdbP9gnWz/YJ1s/2CdbP9gnWz/YJ1s/2CdbP9ho4P/YaOD/2nF/P9pxfz/ + YKCh/2Cgof9Velz/VXpc//v18P/79fD/X4Nm/1+DZv9VfV7/VX1e/1V9Xv9VfV7/VX1e/1V9Xv9UfV3/ + VH1d/zxrRf88a0X/kKeO/5Cnjv+Ppoz/j6aM/xtUJ/8bVCf/G1Un/xtVJ/8cVij/HFYo/xxYKP8cWCj/ + HFkp/xxZKf8rYjX/K2I1//ry6v/68ur/HVsq/x1bKv8piIf/KYiH/zOw+/8zsPv/I3BQ/yNwUP8eXyz/ + Hl8s/x9gLP8fYCz/H2Et/x9hLf8gYy3/IGMt/2Ofb/9jn2//Y59v/2Ofb/9jn2//Y59v/2Ofb/9jn2// + Z7O0/2eztP9rxff/a8X3/1mBav9ZgWr/V3xf/1d8X//89vH//Pbx/2KEaf9ihGn/WH5g/1h+YP9Yf2D/ + WH9g/1l/Yf9Zf2H/WYBh/1mAYf9ZgWL/WYFi/6+/rf+vv63/obSe/6G0nv8eVir/HlYq/xxVJ/8cVSf/ + HFYo/xxWKP8cVyj/HFco/x1YKf8dWCn/K2I1/ytiNf/78+z/+/Ps/x5bKv8eWyr/IGY9/yBmPf80sPf/ + NLD3/yuQl/8rkJf/H18s/x9fLP8fYCz/H2As/yBhLf8gYS3/IGIu/yBiLv9jn2//Y59v/2Ofb/9jn2// + Y59v/2Ofb/9jn2//Y59v/2eztP9ns7T/a8X3/2vF9/9ZgWr/WYFq/1d8X/9XfF///Pbx//z28f9ihGn/ + YoRp/1h+YP9YfmD/WH9g/1h/YP9Zf2H/WX9h/1mAYf9ZgGH/WYFi/1mBYv+vv63/r7+t/6G0nv+htJ7/ + HlYq/x5WKv8cVSf/HFUn/xxWKP8cVij/HFco/xxXKP8dWCn/HVgp/ytiNf8rYjX/+/Ps//vz7P8eWyr/ + Hlsq/yBmPf8gZj3/NLD3/zSw9/8rkJf/K5CX/x9fLP8fXyz/H2As/x9gLP8gYS3/IGEt/yBiLv8gYi7/ + Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9tvtf/bb7X/2y81/9svNf/W35i/1t+Yv9bf2P/ + W39j//z48//8+PP/Zods/2aHbP9cgWT/XIFk/1yBZP9cgWT/Zoht/2aIbf+wwK//sMCv/7LCsf+ywrH/ + 2d7U/9ne1P/Z3tT/2d7U/6/Arf+vwK3/m7Ka/5uymv8pXzT/KV80/x1XKP8dVyj/HVgp/x1YKf8rYzb/ + K2M2//v17v/79e7/Hlwr/x5cK/8eXSv/Hl0r/zGjy/8xo8v/MKLG/zCixv8fYCz/H2As/yBhLf8gYS3/ + IGIt/yBiLf8gYy7/IGMu/2ejc/9no3P/Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9no3P/bb7X/22+1/9svNf/ + bLzX/1t+Yv9bfmL/W39j/1t/Y//8+PP//Pjz/2aHbP9mh2z/XIFk/1yBZP9cgWT/XIFk/2aIbf9miG3/ + sMCv/7DAr/+ywrH/ssKx/9ne1P/Z3tT/2d7U/9ne1P+vwK3/r8Ct/5uymv+bspr/KV80/ylfNP8dVyj/ + HVco/x1YKf8dWCn/K2M2/ytjNv/79e7/+/Xu/x5cK/8eXCv/Hl0r/x5dK/8xo8v/MaPL/zCixv8wosb/ + H2As/x9gLP8gYS3/IGEt/yBiLf8gYi3/IGMu/yBjLv9qpXf/aqV3/2qld/9qpXf/aqV3/2qld/9qpXf/ + aqV3/3HG7P9xxuz/bLO//2yzv/9egGX/XoBl/16BZf9egWX//fn1//359f9oiW//aIlv/16DZ/9eg2f/ + XoNn/16DZ/9oinD/aIpw/7HBsf+xwbH/s8Oz/7PDs//b4Nb/2+DW/9vg1v/b4Nb/tMS0/7TEtP+yw7L/ + ssOy/1J+XP9Sflz/IFos/yBaLP8dWCr/HVgq/ytiNv8rYjb//Pbw//z28P8eWyz/Hlss/x5cLP8eXCz/ + Lpiq/y6Yqv80reX/NK3l/x9fLf8fXy3/H2Au/x9gLv8gYS7/IGEu/yBjL/8gYy//aqV3/2qld/9qpXf/ + aqV3/2qld/9qpXf/aqV3/2qld/9xxuz/ccbs/2yzv/9ss7//XoBl/16AZf9egWX/XoFl//359f/9+fX/ + aIlv/2iJb/9eg2f/XoNn/16DZ/9eg2f/aIpw/2iKcP+xwbH/scGx/7PDs/+zw7P/2+DW/9vg1v/b4Nb/ + 2+DW/7TEtP+0xLT/ssOy/7LDsv9Sflz/Un5c/yBaLP8gWiz/HVgq/x1YKv8rYjb/K2I2//z28P/89vD/ + Hlss/x5bLP8eXCz/Hlws/y6Yqv8umKr/NK3l/zSt5f8fXy3/H18t/x9gLv8fYC7/IGEu/yBhLv8gYy// + IGMv/22oev9tqHr/bah6/22oev9tqHr/bah6/22pf/9tqX//dMz7/3TM+/9rqaj/a6mo/2CCaP9ggmj/ + YINo/2CDaP/9+vb//fr2/2uLcv9ri3L/YYVp/2GFaf9ihmn/YoZp/2KGav9ihmr/Yodq/2KHav9jiGv/ + Y4hr/7XFtf+1xbX/tcW2/7XFtv9jimv/Y4pr/2OKbP9jimz/Y4ts/2OLbP9ahGT/WoRk/yxjOP8sYzj/ + K2I3/ytiN//89/L//Pfy/x5cLP8eXCz/Hl0s/x5dLP8rioj/K4qI/zW0+f81tPn/IWQ1/yFkNf8gYS7/ + IGEu/yBiL/8gYi//IWMv/yFjL/9tqHr/bah6/22oev9tqHr/bah6/22oev9tqX//bal//3TM+/90zPv/ + a6mo/2upqP9ggmj/YIJo/2CDaP9gg2j//fr2//369v9ri3L/a4ty/2GFaf9hhWn/YoZp/2KGaf9ihmr/ + YoZq/2KHav9ih2r/Y4hr/2OIa/+1xbX/tcW1/7XFtv+1xbb/Y4pr/2OKa/9jimz/Y4ps/2OLbP9ji2z/ + WoRk/1qEZP8sYzj/LGM4/ytiN/8rYjf//Pfy//z38v8eXCz/Hlws/x5dLP8eXSz/K4qI/yuKiP81tPn/ + NbT5/yFkNf8hZDX/IGEu/yBhLv8gYi//IGIv/yFjL/8hYy//cat+/3Grfv9xq37/cat+/3Grfv9xq37/ + cq+M/3KvjP94zfv/eM37/22loP9tpaD/ZIRr/2SEa/9khWv/ZIVr//36+P/9+vj/bo51/26Odf9liG3/ + ZYht/2WIbf9liG3/ZYlt/2WJbf9mim3/Zopt/2aKbv9mim7/tcW2/7XFtv+1xbb/tcW2/2eMb/9njG// + Z41v/2eNb/9njm//Z45v/2eOcP9njnD/Zo5u/2aObv9Me1b/THtW//z49P/8+PT/Hlss/x5bLP8fXSz/ + H10s/yqDd/8qg3f/NrX5/za1+f8jbUf/I21H/yBhLv8gYS7/IWIv/yFiL/8hYzD/IWMw/3Grfv9xq37/ + cat+/3Grfv9xq37/cat+/3KvjP9yr4z/eM37/3jN+/9tpaD/baWg/2SEa/9khGv/ZIVr/2SFa//9+vj/ + /fr4/26Odf9ujnX/ZYht/2WIbf9liG3/ZYht/2WJbf9liW3/Zopt/2aKbf9mim7/Zopu/7XFtv+1xbb/ + tcW2/7XFtv9njG//Z4xv/2eNb/9njW//Z45v/2eOb/9njnD/Z45w/2aObv9mjm7/THtW/0x7Vv/8+PT/ + /Pj0/x5bLP8eWyz/H10s/x9dLP8qg3f/KoN3/za1+f82tfn/I21H/yNtR/8gYS7/IGEu/yFiL/8hYi// + IWMw/yFjMP90rYH/dK2B/3Stgf90rYH/dK2B/3Stgf91spP/dbKT/3vP+/97z/v/cKWe/3Clnv9nhm7/ + Z4Zu/2eHb/9nh2///fr4//36+P9zknn/c5J5/2iKb/9oim//aIpw/2iKcP9pi3H/aYtx/2mMcf9pjHH/ + aYxx/2mMcf9ylHn/cpR5/3KUev9ylHr/aY5y/2mOcv9qj3P/ao9z/2qQc/9qkHP/apBz/2qQc/9rkXP/ + a5Fz/3WZff91mX3//fr3//369/8jXjD/I14w/x9cLf8fXC3/KYNz/ymDc/82tvn/Nrb5/yVxTf8lcU3/ + IWEv/yFhL/8hYjD/IWIw/yFkMf8hZDH/dK2B/3Stgf90rYH/dK2B/3Stgf90rYH/dbKT/3Wyk/97z/v/ + e8/7/3Clnv9wpZ7/Z4Zu/2eGbv9nh2//Z4dv//36+P/9+vj/c5J5/3OSef9oim//aIpv/2iKcP9oinD/ + aYtx/2mLcf9pjHH/aYxx/2mMcf9pjHH/cpR5/3KUef9ylHr/cpR6/2mOcv9pjnL/ao9z/2qPc/9qkHP/ + apBz/2qQc/9qkHP/a5Fz/2uRc/91mX3/dZl9//369//9+vf/I14w/yNeMP8fXC3/H1wt/ymDc/8pg3P/ + Nrb5/za2+f8lcU3/JXFN/yFhL/8hYS//IWIw/yFiMP8hZDH/IWQx/3evhP93r4T/d6+E/3evhP93r4T/ + d6+E/3i1l/94tZf/ftD7/37Q+/9ypZ3/cqWd/2qJcf9qiXH/aolx/2qJcf/Z39j/2d/Y/+Hm4P/h5uD/ + 2N7W/9je1v/Y3tb/2N7W/9jf1v/Y39b/2N/W/9jf1v/Y39f/2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/ + 2N/X/9jf1//Y39f/2ODX/9jg1//Y4Nf/2ODX/9jg1//Y4Nf/4efh/+Hn4f/Z4tn/2eLZ/1+Kaf9fimn/ + JmE0/yZhNP8pgG3/KYBt/ze3+f83t/n/JnJS/yZyUv8hYTD/IWEw/yFiMP8hYjD/ImMx/yJjMf93r4T/ + d6+E/3evhP93r4T/d6+E/3evhP94tZf/eLWX/37Q+/9+0Pv/cqWd/3Klnf9qiXH/aolx/2qJcf9qiXH/ + 2d/Y/9nf2P/h5uD/4ebg/9je1v/Y3tb/2N7W/9je1v/Y39b/2N/W/9jf1v/Y39b/2N/X/9jf1//Y39f/ + 2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/2N/X/9jg1//Y4Nf/2ODX/9jg1//Y4Nf/2ODX/+Hn4f/h5+H/ + 2eLZ/9ni2f9fimn/X4pp/yZhNP8mYTT/KYBt/ymAbf83t/n/N7f5/yZyUv8mclL/IWEw/yFhMP8hYjD/ + IWIw/yJjMf8iYzH/erKI/3qyiP96soj/erKI/3qyiP96soj/e7id/3u4nf+A0vv/gNL7/3Olm/9zpZv/ + bIt0/2yLdP9ti3X/bYt1/3KQev9ykHr/mK6d/5iunf+dsqH/nbKh/7fGuf+3xrn/6+7p/+vu6f+etKL/ + nrSi/560ov+etKL/nrWi/561ov+etaP/nrWj/561o/+etaP/nrak/562pP/r7ur/6+7q/7fJu/+3ybv/ + n7ek/5+3pP+atKD/mrSg/3Wafv91mn7/cZd6/3GXev9mkHD/ZpBw/zWFcP81hXD/N7j5/ze4+f8ndlj/ + J3ZY/yFhMf8hYTH/IWIx/yFiMf8iZjP/ImYz/3qyiP96soj/erKI/3qyiP96soj/erKI/3u4nf97uJ3/ + gNL7/4DS+/9zpZv/c6Wb/2yLdP9si3T/bYt1/22Ldf9ykHr/cpB6/5iunf+Yrp3/nbKh/52yof+3xrn/ + t8a5/+vu6f/r7un/nrSi/560ov+etKL/nrSi/561ov+etaL/nrWj/561o/+etaP/nrWj/562pP+etqT/ + 6+7q/+vu6v+3ybv/t8m7/5+3pP+ft6T/mrSg/5q0oP91mn7/dZp+/3GXev9xl3r/ZpBw/2aQcP81hXD/ + NYVw/ze4+f83uPn/J3ZY/yd2WP8hYTH/IWEx/yFiMf8hYjH/ImYz/yJmM/9+tYv/frWL/361i/9+tYv/ + frWL/361i/9/u6P/f7uj/4TT+/+E0/v/d6Wa/3elmv9wjXf/cI13/3COeP9wjnj/cI94/3CPeP9wj3n/ + cI95/3GQef9xkHn/kamX/5Gpl//s8Oz/7PDs/3KSev9yknr/cpN6/3KTev9ylHr/cpR6/3KUe/9ylHv/ + c5V7/3OVe/9zlnz/c5Z8/+zw7P/s8Oz/k66Z/5Oumf90mHz/dJh8/3SYff90mH3/dJl9/3SZff90mX7/ + dJl+/3Safv90mn7/c6mZ/3Opmf9EvPj/RLz4/yh4Xf8oeF3/IWEx/yFhMf8iZTP/ImUz/yyAQf8sgEH/ + frWL/361i/9+tYv/frWL/361i/9+tYv/f7uj/3+7o/+E0/v/hNP7/3elmv93pZr/cI13/3CNd/9wjnj/ + cI54/3CPeP9wj3j/cI95/3CPef9xkHn/cZB5/5Gpl/+RqZf/7PDs/+zw7P9yknr/cpJ6/3KTev9yk3r/ + cpR6/3KUev9ylHv/cpR7/3OVe/9zlXv/c5Z8/3OWfP/s8Oz/7PDs/5Oumf+Trpn/dJh8/3SYfP90mH3/ + dJh9/3SZff90mX3/dJl+/3SZfv90mn7/dJp+/3Opmf9zqZn/RLz4/0S8+P8oeF3/KHhd/yFhMf8hYTH/ + ImUz/yJlM/8sgEH/LIBB/4G3jv+Bt47/gbeO/4G3jv+Bt47/gbeO/4K+p/+Cvqf/h9T7/4fU+/95pJj/ + eaSY/3OPev9zj3r/c5B6/3OQev9zkXr/c5F6/3SSe/90knv/dJJ7/3SSe/94loD/eJaA/+3w7P/t8Oz/ + 1N7W/9Te1v+/zcL/v83C/7/Nwv+/zcL/v87C/7/Owv+/zsL/v87C/9Xf1//V39f/7fDt/+3w7f96nIP/ + epyD/3aZf/92mX//d5p//3eaf/93m3//d5t//3ebgP93m4D/d5yB/3ecgf98rp3/fK6d/37R+v9+0fr/ + M4Fo/zOBaP8iZDL/ImQy/y2CQf8tgkH/L4lF/y+JRf+Bt47/gbeO/4G3jv+Bt47/gbeO/4G3jv+Cvqf/ + gr6n/4fU+/+H1Pv/eaSY/3mkmP9zj3r/c496/3OQev9zkHr/c5F6/3ORev90knv/dJJ7/3SSe/90knv/ + eJaA/3iWgP/t8Oz/7fDs/9Te1v/U3tb/v83C/7/Nwv+/zcL/v83C/7/Owv+/zsL/v87C/7/Owv/V39f/ + 1d/X/+3w7f/t8O3/epyD/3qcg/92mX//dpl//3eaf/93mn//d5t//3ebf/93m4D/d5uA/3ecgf93nIH/ + fK6d/3yunf9+0fr/ftH6/zOBaP8zgWj/ImQy/yJkMv8tgkH/LYJB/y+JRf8viUX/hLmR/4S5kf+EuZH/ + hLmR/4S5kf+EuZH/hcCs/4XArP+J1vv/idb7/32qof99qqH/dpF8/3aRfP92kn3/dpJ9/3aTfv92k37/ + dpN+/3aTfv92lH7/dpR+/3eUfv93lH7/gp6K/4Keiv+1xrn/tca5/8DOw//AzsP/wM/D/8DPw//Az8T/ + wM/E/8DPxP/Az8T/tsi6/7bIuv+Eo4v/hKOL/3mbgv95m4L/eZuC/3mbgv95nIL/eZyC/3mdgv95nYL/ + ep2D/3qdg/96noP/ep6D/4Cypf+AsqX/idb7/4nW+/90rJz/dKyc/zSGSv80hkr/MIpH/zCKR/8wikf/ + MIpH/4S5kf+EuZH/hLmR/4S5kf+EuZH/hLmR/4XArP+FwKz/idb7/4nW+/99qqH/faqh/3aRfP92kXz/ + dpJ9/3aSff92k37/dpN+/3aTfv92k37/dpR+/3aUfv93lH7/d5R+/4Keiv+Cnor/tca5/7XGuf/AzsP/ + wM7D/8DPw//Az8P/wM/E/8DPxP/Az8T/wM/E/7bIuv+2yLr/hKOL/4Sji/95m4L/eZuC/3mbgv95m4L/ + eZyC/3mcgv95nYL/eZ2C/3qdg/96nYP/ep6D/3qeg/+AsqX/gLKl/4nW+/+J1vv/dKyc/3SsnP80hkr/ + NIZK/zCKR/8wikf/MIpH/zCKR/+HvJX/h7yV/4e8lf+HvJX/h7yV/4e8lf+Iv6D/iL+g/4zW9f+M1vX/ + jdj6/43Y+v+KzNv/iszb/4W7u/+Fu7v/gKmc/4CpnP97mIP/e5iD/3qXgv96l4L/e5eC/3uXgv97mIL/ + e5iC/3uYgv97mIL/e5mD/3uZg/97mYP/e5mD/3yag/98moP/fJuE/3ybhP98nIT/fJyE/3ychf98nIX/ + fJ2F/3ydhf99nYX/fZ2F/36gh/9+oIf/gq6g/4KuoP+Gv7z/hr+8/4rN3P+Kzdz/jdj6/43Y+v+N1vX/ + jdb1/4e+of+HvqH/drKF/3ayhf8zjEr/M4xK/zGLSP8xi0j/h7yV/4e8lf+HvJX/h7yV/4e8lf+HvJX/ + iL+g/4i/oP+M1vX/jNb1/43Y+v+N2Pr/iszb/4rM2/+Fu7v/hbu7/4CpnP+AqZz/e5iD/3uYg/96l4L/ + epeC/3uXgv97l4L/e5iC/3uYgv97mIL/e5iC/3uZg/97mYP/e5mD/3uZg/98moP/fJqD/3ybhP98m4T/ + fJyE/3ychP98nIX/fJyF/3ydhf98nYX/fZ2F/32dhf9+oIf/fqCH/4KuoP+CrqD/hr+8/4a/vP+Kzdz/ + is3c/43Y+v+N2Pr/jdb1/43W9f+HvqH/h76h/3ayhf92soX/M4xK/zOMSv8xi0j/MYtI/4q+mP+Kvpj/ + ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/isGh/4rBof+NysX/jcrF/47T5P+O0+T/j9n6/4/Z+v+P2fr/ + j9n6/4/Y+P+P2Pj/jtTs/47U7P+Nz93/jc/d/4vHzv+Lx87/isTH/4rEx/+JwcH/icHB/4m+vP+Jvrz/ + ib+8/4m/vP+JwsL/icLC/4rEx/+KxMf/i8nP/4vJz/+Nz93/jc/d/47U7P+O1Oz/j9j4/4/Y+P+P2fr/ + j9n6/4/Z+v+P2fr/jtPm/47T5v+My8j/jMvI/4vAof+LwKH/ir6Y/4q+mP+Kvpj/ir6Y/2ereP9nq3j/ + Mo1J/zKNSf+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/4rBof+KwaH/jcrF/43Kxf+O0+T/ + jtPk/4/Z+v+P2fr/j9n6/4/Z+v+P2Pj/j9j4/47U7P+O1Oz/jc/d/43P3f+Lx87/i8fO/4rEx/+KxMf/ + icHB/4nBwf+Jvrz/ib68/4m/vP+Jv7z/icLC/4nCwv+KxMf/isTH/4vJz/+Lyc//jc/d/43P3f+O1Oz/ + jtTs/4/Y+P+P2Pj/j9n6/4/Z+v+P2fr/j9n6/47T5v+O0+b/jMvI/4zLyP+LwKH/i8Ch/4q+mP+Kvpj/ + ir6Y/4q+mP9nq3j/Z6t4/zKNSf8yjUn/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwJv/jcCb/43Am/+NwqP/jcKj/4/Iuf+PyLn/j83J/4/Nyf+Q0dn/kNHZ/5HV6P+R1ej/ + kdfy/5HX8v+R2fb/kdn2/5La+v+S2vr/ktr7/5La+/+S2vv/ktr7/5La+v+S2vr/kdn2/5HZ9v+R1/L/ + kdfy/5HV6P+R1ej/kNHY/5DR2P+PzMj/j8zI/4/Iuf+PyLn/jcKj/43Co/+NwJv/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/9UoWn/VKFp/43Am/+NwJv/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcKj/43Co/+PyLn/j8i5/4/Nyf+Pzcn/ + kNHZ/5DR2f+R1ej/kdXo/5HX8v+R1/L/kdn2/5HZ9v+S2vr/ktr6/5La+/+S2vv/ktr7/5La+/+S2vr/ + ktr6/5HZ9v+R2fb/kdfy/5HX8v+R1ej/kdXo/5DR2P+Q0dj/j8zI/4/MyP+PyLn/j8i5/43Co/+NwqP/ + jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/VKFp/1Shaf+MwJrx + jMCa8ZDCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKe/5DCnv+QxKP/ + kMSj/5DEov+QxKL/kMKe/5DCnv+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/43BmvGNwZrxjMCa8YzAmvGQwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnv+Qwp7/kMSj/5DEo/+QxKL/kMSi/5DCnv+Qwp7/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+NwZrxjcGa8Ya+l8SGvpfElMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/j8Kdxo/CncaGvpfEhr6XxJTFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/4/CncaPwp3G + fLuPKXy7jymTxqD1k8ag9ZbHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + mMil9pjIpfaZx6gymceoMny7jyl8u48pk8ag9ZPGoPWWx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5jIpfaYyKX2mceoMpnHqDIAAAAAAAAAAHy7jyl8u48pjMKbxYzCm8WWx6Py + lsej8pnJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5rJp/OayafzlsaiyZbGosmbyKozm8iqMwAAAAAAAAAAAAAAAAAAAAB8u48p + fLuPKYzCm8WMwpvFlsej8pbHo/KZyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+ayafzmsmn85bGosmWxqLJm8iqM5vIqjMAAAAA + AAAAAMAAAAAAAAADwAAAAAAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAAAAAA8AAAAAAAAADKAAAADAAAABgAAAAAQAgAAAAAAAAJAAA + EwsAABMLAAAAAAAAAAAAAAAAAAAbZCQOG2QkHB1nJqkcZybIHGcm5xxnJv8cZyb/HGcm/xxnJv8cZyb/ + HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xhaIf8XViD/ + FlIe/xdTH/8XVB//F1Qf/xdUH/8XVSD/F1Yg/xdWIP8YVyD/GFcg/xhYIP8YWSH/GFkh/xhaIf8ZWiH/ + GVoh/xhcIukZXCLMGlwirxlaIR8ZWiEQAAAAABtkJA4dZyZJHWgnhR1oJ9QdaCfkHWgn8x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8cZCX/ + G2Ek/xhWIP8XVB//F1If/xdTH/8XVB//F1Qf/xhUIP8YVSD/GFYg/xhWIP8YVyD/GFch/xlYIf8ZWSH/ + GVkh/xlaIv8ZWiL/GVsi/xlbIvQZXCLmGlwj1xpdIocaXCJLGVohEBtkJBwdaCeFHWgn7R1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8bYSX/GVoi/xdRHv8XUh//F1If/xdTH/8XVB//F1Qf/xhUIP8YVSD/GFUg/xhWIP8YVyH/ + GFch/xlYIf8ZWSH/GVkh/xlaIv8ZWyL/GVsi/xlbIv8aXCP/Glwj/xpdIu8aXSKHGVohHx5qKakeaijU + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Hmoo/xpbIv8ZViH/F1Ef/xdSH/8XUx//F1Mf/xhUIP8YVCD/GFQg/xhVIP8YViD/ + GFYg/xlXIf8ZWCH/GVgh/xlZIv8ZWiL/GVoi/xpbIv8aWyP/Glsj/xpcI/8aXSP/Gl0j/xteI/8bXiPX + HF8krx9rKskfaynkH2sp/x9rKf8fayn/H2sp/x9rKf8fayn/H2sp/x9rKf8fayn/H2sp/x9rKf8fayn/ + H2sp/x9rKf8fayn/H2sp/x9rKf8dZyj/HGMm/xlWIf8aWTD/G11A/xteQP8ZWTD/GFMg/xhUIf8YVCH/ + GFQh/xlVIf8ZViH/GVYh/xlXIv8ZWCL/GVgi/xpZI/8aWiP/Gloj/xpbI/8aWyP/G1sk/xtcJP8bXST/ + G10k/xteJP8bXiTmG18lzB9rKugfayr0H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8dYyf/Glsk/xdQH/8bXUD/Hmlg/x5qYP8bX0D/ + GFMg/xhUIf8YVCH/GFQh/xlVIf8ZViL/GVYi/xlXIv8ZWCL/GVgi/xpZI/8aWiP/Gloj/xpbJP8bWyT/ + G1sk/xtcJP8bXSX/G10l/xteJf8bXiX0G18l6SBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/xtbJP8dYj//Hmha/yWCsv8ni8n/ + KZPf/ymT3/8ni8f/JYKu/x5nVP8cXjv/GVUi/xlWIv8ZVyL/GVci/xpYI/8aWCP/Glgj/xpZI/8bWiT/ + G1sk/xtbJP8bXCT/G1wk/xtdJf8cXiX/HF4l/xxfJf8cYCb/HGAm/yBuLP8gbiz/IG4s/yBuLP8gbiz/ + IG4s/yBuLP8gbiz/IG4s/yBuLP8gbiz/IG4s/yBuLP8gbiz/IG4s/yBuLP8fazH/H2k2/yBuZv8idoH/ + JH6d/yqT1f8rmOH/LJ7u/yye7v8rmOD/KpPT/yR+mv8hdH//H2tk/xtcMv8aWir/GVcj/xpYJP8aWCT/ + Glgk/xpZJP8aWiT/G1sl/xtbJf8bXCX/G1wl/xtdJv8bXib/HF4m/xxfJv8cYCb/HGAn/yBuLf8gbi3/ + IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8fajf/ + HWVA/ySBp/8ni8P/KZTf/y6k9/8vpvr/L6j9/y+o/f8vpvr/LqT3/ymU3/8nisL/JICl/xxiQv8bXTP/ + GVcj/xlYJP8aWCT/Glgk/xpZJf8aWiX/Glol/xtbJf8bXCb/G1wm/xtdJv8bXib/G14m/xxfJ/8cYCf/ + HGAn/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcS// + IXEv/yR8fv8nh6n/KZHU/y+l9v8wp/n/MKn8/yybzf8mhZT/IG5a/yBsWP8mg5L/LJrM/zCp/P8wp/n/ + L6X2/yqR1P8lg6P/IHRx/xpYJP8aWSX/Glkl/xtaJf8bWyX/G1sl/xtcJv8bXSb/G10m/xxeJ/8cXyf/ + HF8n/xxgJ/8cYSj/HGEo/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS// + InEv/yJyNf8jd1H/JHxt/ymOtf8rls//LZ7o/y+i5/8smMz/KY6x/yJ2eP8fa1v/HWA+/x1gPf8ga1r/ + I3d4/ymPsv8smMz/L6Ln/y2e6P8qlMv/J4qv/yBuZP8dZUj/G1ws/xtaJf8bWyX/G1sm/xxcJv8cXSb/ + HF0n/xxeJ/8cXyf/HV8n/x1gKP8dYSj/HWEo/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS// + InEv/yJxL/8icS//InEv/yN0O/8lfnP/J4eq/y2f7P8vpfT/MKr8/y6f2P8oiZ//IXJm/xhRIv8ZUiL/ + GVIi/xlTIv8ZVCP/GVQj/yJ0Z/8oiqD/Lp/Y/zCq/P8vpfT/LZ/s/yWEo/8hcWv/HF4z/xtaJf8bWyb/ + G1sm/xxcJv8cXSf/HF0n/xxeJ/8dXyf/HV8n/x1gKP8dYSj/HWEo/yx4Ov8pdjf/JXMz/yNyMf8jcjH/ + I3Ix/yNyMf8jcjH/I3Ix/yNyMf8kczf/JHQ8/ymPvf8tnNv/MKn5/zCo9P8rlb//JoGJ/xlQJf8ZUCT/ + GFAi/xlQI/8ZUSP/GVIj/xlTJP8aVCT/GlQk/xpUJP8bVib/G1co/yeFjf8smML/MKr2/zCp+f8tnNv/ + KY69/x1fM/8dXS3/HFsn/xxcJ/8cXSj/HF0o/x1dKP8dXin/HV8p/x1gKf8eYSr/HmEq/z+FTP89g0r/ + PIJI/zZ/Q/8zfUD/MXs+/yt4Of8odjb/JnU0/yR0Nv8lfFr/J4R+/y2d3P8uoOD/L6Pj/yeEm/8jdnj/ + H2hW/xlQJP8ZUCP/GVAj/xlRI/8ZUSP/GVIj/xpTJP8aVCT/GlQk/xpVJf8bVib/G1cn/yFuWf8lfHz/ + KImg/y+l5v8uoeH/LZ3c/yR5ev8ga1P/HV4t/x1cKP8dXSj/HV0o/x1eKf8dXin/Hl8p/x5gKv8eYSr/ + HmEq/1KRXf9SkV3/UpFd/0mLVf9EiFD/PoRK/zN+QP8uezv/KHc2/yR2O/8nhX7/KpPA/zGr+/8wpOT/ + Lp3N/x1gQv8bVzL/GE4i/xlPIv8ZUCP/GVAj/xlRI/8ZUiP/GVIj/xpTJP8aVCT/GlQk/xpVJf8bViX/ + G1Yl/xtXJf8eYDf/IGhJ/y6g0/8wpuf/Mav7/yqTwP8kenn/HmAy/x1cKP8dXSj/HV0o/x1eKf8eXyn/ + Hl8p/x5gKv8eYSr/HmEq/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1Smuf9Prtr/ + Sbb7/zWcvf9HjY3/WX1d/2KDYv9jg2L/Y4Ni/2OEYv9jhWL/Y4Vi/2OFYv9jhmP/Y4Zj/2OHY/9kh2T/ + ZIdk/2SIZP9kiWT/ZIlk/2SJZP9limT/ZYpk/1qFYv9FkJL/MJvC/zKt+/8un9L/KpCp/x1cKP8dXSn/ + HV0p/x5eKf8eXyn/Hl8p/x5gKv8fYSv/H2Ir/1eWY/9XlmP/V5Zj/1eWY/9XlmP/V5Zj/1eWY/9YmGz/ + WZp1/1uz2v9Xs9//VLTk/4K4wv+Nsqv/mKuV/5Onjv+Spo3/kaWL/5Gli/+RpYv/kaaL/5Gmi/+Rpov/ + kaeM/5GnjP+Rp4z/kqeM/5KojP+SqIz/kqmM/5KpjP+SqYz/kqmM/5Sskv+Fr6f/d7K8/zCl3/8votj/ + Lp/S/yBpQ/8fYzb/HV4q/x5fKv8eXyr/HmAq/x5hK/8eYSv/H2Is/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/ + WJdl/1iXZf9am3f/W5+I/2LA+v9gueT/XrHN/87Uxv/T18r/19nN/8TKuv/CyLf/v8a0/7/Gs/+/xrP/ + v8az/7/Gs/+/x7T/v8e0/7/HtP+/x7T/v8e0/7/HtP+/yLT/v8i0/7/ItP+/yLT/v8i0/83Swv/Gzrz/ + vsm2/y6dw/8wpd//Mq36/yN1Xv8gakT/HV4q/x1fKv8eYCv/HmAr/x5hK/8eYiz/HmIs/1yaaP9cmmj/ + XJpo/1yaaP9cmmj/XJpo/1yaaP9hq6T/Zbvf/2W/7f9doKr/VIBm//v07f+tu6n/X4Jk/1J6Wv9ReVn/ + UHhY/zxqRf8uYDj/IFUr/xpRJP8hViv/J1sx/ydcMf8hWCz/G1Qm/xtVJv8bVif/G1Yn/xxXJ/8cWCj/ + HFgo/yxkNf+Tqo7/+fDn/yBlPv8piJX/Mqrr/zGk1/8ogYH/Hl4q/x5fK/8eYCv/HmAr/x9gK/8fYSz/ + H2Is/16cav9enGr/Xpxq/16cav9enGr/Xpxq/1+fdv9jr7L/Z8Du/2Owx/9clpT/VX1h//v17/+tvKr/ + X4Nl/1R8XP9Te1z/U3tb/0l0Uv9Bbkv/OmlE/yteNf9DcEr/XIFg/1uBX/87a0P/G1Qn/xtVJ/8bVif/ + HFYo/xxYKP8cWCj/HFkp/yxjNf+Tqo//+vHp/x9gNP8mfXf/Lpm5/zKq6f8piZP/IWc9/x5fLP8eYCz/ + H2As/x9hLP8fYiz/IGMt/2CdbP9gnWz/YJ1s/2CdbP9gnWz/YJ1s/2Gjg/9ltMD/acX8/2Cgof9bjX// + VXpc//v18P+tvKv/X4Nm/1V9Xv9VfV7/VX1e/1V9Xv9VfV7/VH1d/zxrRf9miWr/kKeO/4+mjP9VfVr/ + G1Qn/xtVJ/8cVij/HFYo/xxYKP8cWSn/HFkp/ytiNf+TqpD/+vLq/x1bKv8jcln/KYiH/zOw+/8rkKb/ + I3BQ/x5fLP8fYCz/H2As/x9hLf8gYi3/IGMt/2Ofb/9jn2//Y59v/2Ofb/9jn2//Y59v/2eztP9pvNb/ + a8X3/1mBav9Yf2X/V3xf//z28f+vva3/YoRp/1h+YP9Yf2D/WH9g/1l/Yf9ZgGH/WYBh/1mBYv+EoIj/ + r7+t/6G0nv9ghWT/HlYq/xxVJ/8cVij/HFYo/xxXKP8dWCn/HVgp/ytiNf+Tq5H/+/Ps/x5bKv8fYTT/ + IGY9/zSw9/8woMf/K5CX/x9fLP8fYCz/H2As/yBhLf8gYi7/IGIu/2Whcf9loXH/ZaFx/2Whcf9loXH/ + ZaFx/2q5xv9rvdb/bMHn/1qAZv9af2T/WX5h//z38v+wvq7/ZIZr/1qAYv9agGL/WoBi/2CEZ/9yknj/ + haCI/4aiiv+luKX/xM/B/73Juf+SqpL/Z4ts/1yEYf8/b0f/I1su/x1XKP8dWCn/HVgp/ytjNv+Tq5H/ + +/Tt/x5cK/8fXy//H2I0/zOq4f8wocj/Lpmv/x9gLP8fYCz/IGEt/yBiLf8gYi7/IGMu/2ejc/9no3P/ + Z6Nz/2ejc/9no3P/Z6Nz/22+1/9tvdf/bLzX/1t+Yv9bf2P/W39j//z48/+xwLD/Zods/1yBZP9cgWT/ + XIFk/2aIbf+LpI7/sMCv/7LCsf/G0MP/2d7U/9ne1P/Ez8H/r8Ct/5uymv9iiWf/KV80/x1XKP8dWCn/ + HVgp/ytjNv+TrJL/+/Xu/x5cK/8eXSv/Hl0r/zGjy/8xo8n/MKLG/x9gLP8gYS3/IGEt/yBiLf8gYy7/ + IGMu/2qld/9qpXf/aqV3/2qld/9qpXf/aqV3/3HG7P9vvdb/bLO//16AZf9egWX/XoFl//359f+zwbL/ + aIlv/16DZ/9eg2f/XoNn/2iKcP+NppH/scGx/7PDs//H0sX/2+DW/9vg1v/I0sX/tMS0/7LDsv+CoYf/ + Un5c/yBaLP8fWSv/HVgq/ytiNv+UrJP//Pbw/x5bLP8eXCz/Hlws/y6Yqv8xo8j/NK3l/x9fLf8fYC7/ + H2Au/yBhLv8gYi//IGMv/2ynef9sp3n/bKd5/2ynef9sp3r/bKd7/3PJ9P9vvNT/bK60/1+BZ/9fgmf/ + X4Jn//369v+zwrP/aopx/2CEaP9ghGj/YIVo/2WIbf93ln3/iqSO/4umj/+qvKr/yNPG/8jTxv+qvav/ + jKeQ/4unj/9zlnr/W4Vk/z1vSP8xZj3/JV4x/ytiN/+UrJT//Pfx/x5cLP8eXCz/Hl0s/y2Rmf8xocT/ + NbHv/yBiMf8gYTD/IGEu/yBiL/8gYi//IWMv/22oev9tqHr/bah6/22oev9tqX3/bal//3TM+/9wu9L/ + a6mo/2CCaP9gg2j/YINo//369v+0w7T/a4ty/2GFaf9ihmn/YoZp/2KGav9ih2r/Yodq/2OIa/+Mp5D/ + tcW1/7XFtv+MqJH/Y4pr/2OKbP9ji2z/Y4ts/1qEZP9DdE7/LGM4/ytiN/+UrZX//Pfy/x5cLP8eXSz/ + Hl0s/yuKiP8wn8H/NbT5/yFkNf8hYzL/IGEu/yBiL/8hYy//IWMv/3Grfv9xq37/cat+/3Grfv9yrYX/ + cq+M/3jN+/9zuc7/baWg/2SEa/9khWv/ZIVr//36+P+2xLf/bo51/2WIbf9liG3/ZYht/2WJbf9mim3/ + Zopt/2aKbv+OqJL/tcW2/7XFtv+OqZP/Z4xv/2eNb/9njm//Z45v/2eOcP9njm//Zo5u/0x7Vv+kuqX/ + /Pj0/x5bLP8fXCz/H10s/yqDd/8wnLj/NrX5/yNtR/8iZzv/IGEu/yFiL/8hYzD/IWMw/3OsgP9zrID/ + c6yA/3OsgP9zroj/dLGQ/3rO+/90us3/b6Wf/2aFbf9mhm3/ZoZt//36+P+3xbj/cZB3/2eJbv9niW7/ + Z4lv/2eKb/9ni2//aItv/2iLcP9+nIT/lK2Y/5StmP9+nYT/aI1x/2mOcf9pj3H/aY9x/2mPcv9pj3H/ + aZBx/2GKav+vwrD//fn2/yFdLv8gXS3/H10t/yqDdf8wnLf/Nrb5/yRvSv8iaDz/IWEv/yFiMP8hYzD/ + IWQx/3Stgf90rYH/dK2B/3Stgf91sIr/dbKT/3vP+/92us3/cKWe/2eGbv9nh2//Z4dv//36+P+4xrn/ + c5J5/2iKb/9oinD/aIpw/2mLcf9pjHH/aYxx/2mMcf9ukHX/cpR5/3KUev9ukXb/aY5y/2qPc/9qkHP/ + apBz/2qQc/9rkXP/a5Fz/3WZff+5yrr//fr3/yNeMP8hXS//H1wt/ymDc/8wnbb/Nrb5/yVxTf8jaT7/ + IWEv/yFiMP8hYzH/IWQx/3evhP93r4T/d6+E/3evhP94so7/eLWX/37Q+/94u8z/cqWd/2qJcf9qiXH/ + aolx/9nf2P/d49z/4ebg/9je1v/Y3tb/2N7W/9jf1v/Y39b/2N/W/9jf1//Y39f/2N/X/9jf1//Y39f/ + 2N/X/9jf1//Y4Nf/2ODX/9jg1//Y4Nf/2ODX/+Hn4f/d5d3/2eLZ/1+Kaf9Ddk//JmE0/ymAbf8wnLP/ + N7f5/yZyUv8kakH/IWEw/yFiMP8iYzH/ImMx/3mxhv95sYb/ebGG/3mxhv95tJD/erea/3/R+/95u8z/ + c6Wc/2uKc/9rinP/bIpz/6a4qf+xwbT/vcq//7vIvP/BzcL/yNLI/+Ln4P/O2M7/u8q8/7vKvf+7yr3/ + u8q9/7vKvf+7yr3/u8q9/7vLvv/O2c//4ufh/8jVyf/C0MP/vMy+/77Owf+yxrb/p76s/2iRcv9XhWL/ + RnlS/y+Db/8znbT/N7j5/yd0Vf8ka0P/IWEx/yFiMf8iYzH/ImUy/3qyiP96soj/erKI/3qyiP97tZP/ + e7id/4DS+/96vMv/c6Wb/2yLdP9ti3X/bYt1/3KQev+Fn4z/mK6d/52yof+qvK3/t8a5/+vu6f/F0cb/ + nrSi/560ov+etaL/nrWi/561o/+etaP/nrWj/562pP/F0sf/6+7q/7fJu/+rwLD/n7ek/5q0oP+Ip4// + dZp+/3GXev9slHX/ZpBw/zWFcP82n7X/N7j5/yd2WP8kbEX/IWEx/yFiMf8iZDL/ImYz/361i/9+tYv/ + frWL/361i/9/uJf/f7uj/4TT+/9+vMv/d6Wa/3CNd/9wjnj/cI54/3CPeP9wj3n/cI95/3GQef+BnYj/ + kamX/+zw7P+vwbP/cpJ6/3KTev9ylHr/cpR6/3KUe/9zlXv/c5V7/3OWfP+ww7T/7PDs/5Oumf+Eo4v/ + dJh8/3SYff90mX3/dJl9/3SZfv90mn7/dJp+/3Opmf9cs8n/RLz4/yh4Xf8lbUf/IWEx/yJlM/8nczr/ + LIBB/4C2jf+Ato3/gLaN/4C2jf+AuZn/gb2l/4bU+/9/vMr/eKWZ/3KOef9yj3n/co95/3KQef9ykHr/ + cpF6/3ORev98mIP/haCM/+3w7P/I1Mr/o7io/5mwnv+ZsJ7/mbGe/5mxn/+ZsZ//mbKf/6S7qv/I1cv/ + 7fDt/4eljv9+n4b/dZl+/3aZfv92mn7/dpp+/3aaf/92m3//dpuA/3ism/9sucr/Ycf5/y59Y/8ocEr/ + ImMy/yh0Ov8rfD//LoVD/4G3jv+Bt47/gbeO/4G3jv+Cu5v/gr6n/4fU+/+AvMr/eaSY/3OPev9zkHr/ + c5B6/3ORev90knv/dJJ7/3SSe/92lH7/eJaA/+3w7P/h5+H/1N7W/7/Nwv+/zcL/v83C/7/Owv+/zsL/ + v87C/9Xf1//h6OL/7fDt/3qcg/94m4H/dpl//3eaf/93m3//d5t//3ebgP93nIH/d5yB/3yunf99wMz/ + ftH6/zOBaP8rc03/ImQy/y2CQf8uhkP/L4lF/4S5kf+EuZH/hLmR/4S5kf+FvZ//hcCs/4nW+/+DwM7/ + faqh/3aRfP92kn3/dpJ9/3aTfv92k37/dpN+/3aUfv93lH7/d5R+/4Keiv+csqL/tca5/8DOw//Az8P/ + wM/D/8DPxP/Az8T/wM/E/7bIuv+dtqP/hKOL/3mbgv95m4L/eZuC/3mcgv95nYL/eZ2C/3qdg/96noP/ + ep6D/4Cypf+FxND/idb7/3SsnP9UmXP/NIZK/zCKR/8wikf/MIpH/4a7k/+Gu5P/hruT/4a7k/+GvZ3/ + h8Cm/4vW+P+IzOP/hcHO/4CvrP9/q6T/fqec/3uejf96mof/eZaB/3iWgP95loD/eZaA/3+bhv+LpZL/ + mK+e/560o/+etKP/nrSj/561pP+etaT/nrWk/5myn/+NqZT/gKCI/3uchP97nIT/e5yE/3yehf99oov/ + fqaR/4CuoP+Bsqj/graw/4fF0P+JzuT/i9b4/361n/9pqYP/VZxo/zKLSf8xi0j/MYtI/4e8lf+HvJX/ + h7yV/4e8lf+Ivpv/iL+g/4zW9f+N1/j/jdj6/4rM2/+IxMv/hbu7/4CpnP9+oZD/e5iD/3qXgv97l4L/ + e5eC/3uYgv97mIL/e5iC/3uZg/97mYP/e5mD/3yag/98m4T/fJuE/3ychP98nIX/fJyF/3ydhf99nYX/ + fZ2F/36gh/+Ap5T/gq6g/4a/vP+Ixsz/is3c/43Y+v+N1/j/jdb1/4e+of9/uJP/drKF/zOMSv8yjEn/ + MYtI/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/4rBof+MxrP/jcrF/47T5P+P1u//j9n6/4/Z+v+P2fn/ + j9j4/47U7P+O0uX/jc/d/4vHzv+Lxsv/isTH/4nBwf+JwL//ib68/4m/vP+Jwb//icLC/4rEx/+Lx8v/ + i8nP/43P3f+O0uX/jtTs/4/Y+P+P2fn/j9n6/4/Z+v+P1vD/jtPm/4zLyP+MxrX/i8Ch/4q+mP+Kvpj/ + ir6Y/2ereP9NnGH/Mo1J/4y/mv+Mv5r/jL+a/4y/mv+Mv5r/jL+a/4zBnv+Mw6f/jcWw/47KwP+OzMf/ + js7P/4/R2v+P0t3/j9Ph/4/T4/+P0uP/j9Lj/47P4P+Oz9//js/f/47O3v+Ozd3/jszc/47N3P+Ozd3/ + js7e/47P3/+Oz+D/jtDh/4/S4/+P0uL/j9Pi/4/S4P+P0d3/j9Ha/47Oz/+OzMj/jsrB/43Gsv+Mw6j/ + jMCe/4y/mv+Mv5r/jL+a/3q2iv9fpnH/Q5dZ/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwZ//jcKj/4/Iuf+Py8H/j83J/5DR2f+R0+H/kdXo/5HX8v+R2PT/kdn2/5La+v+S2vv/ + ktr7/5La+/+S2vv/ktr6/5HZ9v+R2PT/kdfy/5HV6P+R0+D/kNHY/4/MyP+PysH/j8i5/43Co/+NwZ// + jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/9xsYL/VKFp/4zAmvGOwZz4kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnv+Qw6H/kMSj/5DEov+Qw6D/kMKe/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Pwpz4jcGa8Ym/mduOwZzt + ksSf/5LEn/+SxJ//ksSf/5LEn/+SxJ//ksSf/5LEn/+SxJ//ksSf/5LEn/+SxJ//ksSf/5LEn/+SxJ// + ksSf/5LEn/+SxJ//ksSf/5LEoP+SxKH/ksWi/5LFov+SxKH/ksSg/5LEn/+SxJ//ksSf/5LEn/+SxJ// + ksSf/5LEn/+SxJ//ksSf/5LEn/+SxJ//ksSf/5LEn/+SxJ//ksSf/5LEn/+SxJ//ksSf/5LEn/+Qw53t + jsGb3Ia+l8SOwp3ilMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+SxJ/jj8Kdxny7jymQxJ6Pk8ag9ZbHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5jIpfaYyKaUmceoMny7jxWNw5xSkMSej5LFoOKUxqLtlsek+ZjIpf+YyKX/ + mMil/5jIpf+YyKX/mMil/5jIpf+YyKX/mMil/5jIpf+YyKX/mMil/5jIpf+YyKX/mMil/5jIpf+YyKX/ + mMil/5jIpf+YyKX/mMil/5jIpf+YyKX/mMil/5jIpf+YyKX/mMil/5jIpf+YyKX/mMil/5jIpf+YyKX/ + mMil/5jIpf+YyKX/mMil/5jIpfmXx6Tvlsej5JnIppWZyKZXmceoGQAAAAB8u48VfLuPKYzCm8WSxZ/c + lsej8pnJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5rJp/OYyKXelsaiyZvIqjObyKoaAAAAAIAAAAAAAQAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAACAAAAAAAEAACgAAAAgAAAAQAAAAAEAIAAAAAAAABAAABMLAAATCwAAAAAAAAAAAAAAAAAA + G2QkHB1nJqkcZybnHGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/ + GFoh/xZSHv8XUx//F1Qf/xdUH/8XViD/F1Yg/xhXIP8YWCD/GFkh/xhaIf8ZWiH/GFwi6RpcIq8ZWiEf + AAAAABtkJBwdaCftHWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/xlaIv8XUR7/F1If/xdTH/8XVB//GFQg/xhVIP8YViD/GFch/xlYIf8ZWSH/GVoi/xlbIv8ZWyL/ + Glwj/xpdIu8ZWiEfHmopqR5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8aWyL/F1Ef/xdSH/8XUx//GFQg/xhUIP8YVSD/GFYg/xlXIf8ZWCH/GVki/xlaIv8aWyL/ + Glsj/xpcI/8aXSP/G14j/xxfJK8fayroH2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/Glsk/xdQH/8eaWD/Hmpg/xhTIP8YVCH/GFQh/xlVIf8ZViL/GVci/xlYIv8aWSP/ + Gloj/xpbJP8bWyT/G1wk/xtdJf8bXiX/G18l6SBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/IG0r/xtbJP8eaFr/JYKy/ymT3/8pk9//JYKu/x5nVP8ZVSL/GVYi/xlXIv8aWCP/ + Glgj/xpZI/8bWyT/G1sk/xtcJP8bXSX/HF4l/xxfJf8cYCb/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/yBuLf8gbi3/IG4t/yBuLf8dZUD/JIGn/ymU3/8upPf/L6j9/y+o/f8upPf/KZTf/ySApf8cYkL/ + GVcj/xlYJP8aWCT/Glkl/xpaJf8bWyX/G1wm/xtdJv8bXib/HF8n/xxgJ/8hcC7/IXAu/yFwLv8hcC7/ + IXAu/yFwLv8hcC7/IXAu/yFwLv8hcS//JHx+/ymR1P8vpfb/MKn8/yybzf8gblr/IGxY/yyazP8wqfz/ + L6X2/yqR1P8gdHH/Glgk/xpZJf8bWiX/G1sl/xtcJv8bXSb/HF4n/xxfJ/8cYCf/HGEo/yJxL/8icS// + InEv/yJxL/8icS//InEv/yJxL/8icS//I3Q7/yeHqv8tn+z/MKr8/y6f2P8hcmb/GFEi/xlSIv8ZUyL/ + GVQj/yJ0Z/8un9j/MKr8/y2f7P8lhKP/HF4z/xtaJf8bWyb/HFwm/xxdJ/8cXif/HV8n/x1gKP8dYSj/ + LHg6/yVzM/8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yR0PP8pj73/MKn5/zCo9P8mgYn/GVAl/xhQIv8ZUCP/ + GVIj/xlTJP8aVCT/GlQk/xtXKP8nhY3/MKr2/zCp+f8pjr3/HV8z/xxbJ/8cXCf/HF0o/x1dKP8dXyn/ + HWAp/x5hKv9SkV3/UpFd/0mLVf8+hEr/M35A/yh3Nv8kdjv/KpPA/zGr+/8unc3/HWBC/xhOIv8ZTyL/ + GVAj/xlRI/8ZUiP/GlMk/xpUJP8aVSX/G1Yl/xtXJf8gaEn/LqDT/zGr+/8qk8D/HmAy/x1cKP8dXSj/ + HV4p/x5fKf8eYCr/HmEq/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1Smuf9Jtvv/NZy9/1l9Xf9ig2L/ + Y4Ni/2OEYv9jhWL/Y4Vi/2OGY/9jh2P/ZIdk/2SIZP9kiWT/ZIlk/2WKZP9ahWL/MJvC/zKt+/8qkKn/ + HVwo/x1dKf8eXin/Hl8p/x5gKv8fYiv/WJdl/1iXZf9Yl2X/WJdl/1iXZf9bn4j/YsD6/16xzf/O1Mb/ + 19nN/8TKuv+/xrT/v8az/7/Gs/+/xrP/v8e0/7/HtP+/x7T/v8e0/7/ItP+/yLT/v8i0/83Swv++ybb/ + Lp3D/zKt+v8jdV7/HV4q/x1fKv8eYCv/HmEr/x5iLP9cmmj/XJpo/1yaaP9cmmj/XJpo/2W73/9lv+3/ + VIBm//v07f9fgmT/Unpa/1B4WP88akX/IFUr/xpRJP8nWzH/J1wx/xtUJv8bVSb/G1Yn/xxXJ/8cWCj/ + LGQ1//nw5/8gZT7/Mqrr/zGk1/8eXir/Hl8r/x5gK/8fYCv/H2Is/2CdbP9gnWz/YJ1s/2CdbP9ho4P/ + acX8/2Cgof9Velz/+/Xw/1+DZv9VfV7/VX1e/1V9Xv9UfV3/PGtF/5Cnjv+Ppoz/G1Qn/xtVJ/8cVij/ + HFgo/xxZKf8rYjX/+vLq/x1bKv8piIf/M7D7/yNwUP8eXyz/H2As/x9hLf8gYy3/Y59v/2Ofb/9jn2// + Y59v/2eztP9rxff/WYFq/1d8X//89vH/YoRp/1h+YP9Yf2D/WX9h/1mAYf9ZgWL/r7+t/6G0nv8eVir/ + HFUn/xxWKP8cVyj/HVgp/ytiNf/78+z/Hlsq/yBmPf80sPf/K5CX/x9fLP8fYCz/IGEt/yBiLv9no3P/ + Z6Nz/2ejc/9no3P/bb7X/2y81/9bfmL/W39j//z48/9mh2z/XIFk/1yBZP9miG3/sMCv/7LCsf/Z3tT/ + 2d7U/6/Arf+bspr/KV80/x1XKP8dWCn/K2M2//v17v8eXCv/Hl0r/zGjy/8wosb/H2As/yBhLf8gYi3/ + IGMu/2qld/9qpXf/aqV3/2qld/9xxuz/bLO//16AZf9egWX//fn1/2iJb/9eg2f/XoNn/2iKcP+xwbH/ + s8Oz/9vg1v/b4Nb/tMS0/7LDsv9Sflz/IFos/x1YKv8rYjb//Pbw/x5bLP8eXCz/Lpiq/zSt5f8fXy3/ + H2Au/yBhLv8gYy//bah6/22oev9tqHr/bal//3TM+/9rqaj/YIJo/2CDaP/9+vb/a4ty/2GFaf9ihmn/ + YoZq/2KHav9jiGv/tcW1/7XFtv9jimv/Y4ps/2OLbP9ahGT/LGM4/ytiN//89/L/Hlws/x5dLP8rioj/ + NbT5/yFkNf8gYS7/IGIv/yFjL/9xq37/cat+/3Grfv9yr4z/eM37/22loP9khGv/ZIVr//36+P9ujnX/ + ZYht/2WIbf9liW3/Zopt/2aKbv+1xbb/tcW2/2eMb/9njW//Z45v/2eOcP9mjm7/THtW//z49P8eWyz/ + H10s/yqDd/82tfn/I21H/yBhLv8hYi//IWMw/3Stgf90rYH/dK2B/3Wyk/97z/v/cKWe/2eGbv9nh2// + /fr4/3OSef9oim//aIpw/2mLcf9pjHH/aYxx/3KUef9ylHr/aY5y/2qPc/9qkHP/apBz/2uRc/91mX3/ + /fr3/yNeMP8fXC3/KYNz/za2+f8lcU3/IWEv/yFiMP8hZDH/d6+E/3evhP93r4T/eLWX/37Q+/9ypZ3/ + aolx/2qJcf/Z39j/4ebg/9je1v/Y3tb/2N/W/9jf1v/Y39f/2N/X/9jf1//Y39f/2N/X/9jg1//Y4Nf/ + 2ODX/+Hn4f/Z4tn/X4pp/yZhNP8pgG3/N7f5/yZyUv8hYTD/IWIw/yJjMf96soj/erKI/3qyiP97uJ3/ + gNL7/3Olm/9si3T/bYt1/3KQev+Yrp3/nbKh/7fGuf/r7un/nrSi/560ov+etaL/nrWj/561o/+etqT/ + 6+7q/7fJu/+ft6T/mrSg/3Wafv9xl3r/ZpBw/zWFcP83uPn/J3ZY/yFhMf8hYjH/ImYz/361i/9+tYv/ + frWL/3+7o/+E0/v/d6Wa/3CNd/9wjnj/cI94/3CPef9xkHn/kamX/+zw7P9yknr/cpN6/3KUev9ylHv/ + c5V7/3OWfP/s8Oz/k66Z/3SYfP90mH3/dJl9/3SZfv90mn7/c6mZ/0S8+P8oeF3/IWEx/yJlM/8sgEH/ + gbeO/4G3jv+Bt47/gr6n/4fU+/95pJj/c496/3OQev9zkXr/dJJ7/3SSe/94loD/7fDs/9Te1v+/zcL/ + v83C/7/Owv+/zsL/1d/X/+3w7f96nIP/dpl//3eaf/93m3//d5uA/3ecgf98rp3/ftH6/zOBaP8iZDL/ + LYJB/y+JRf+EuZH/hLmR/4S5kf+FwKz/idb7/32qof92kXz/dpJ9/3aTfv92k37/dpR+/3eUfv+Cnor/ + tca5/8DOw//Az8P/wM/E/8DPxP+2yLr/hKOL/3mbgv95m4L/eZyC/3mdgv96nYP/ep6D/4Cypf+J1vv/ + dKyc/zSGSv8wikf/MIpH/4e8lf+HvJX/h7yV/4i/oP+M1vX/jdj6/4rM2/+Fu7v/gKmc/3uYg/96l4L/ + e5eC/3uYgv97mIL/e5mD/3uZg/98moP/fJuE/3ychP98nIX/fJ2F/32dhf9+oIf/gq6g/4a/vP+Kzdz/ + jdj6/43W9f+HvqH/drKF/zOMSv8xi0j/ir6Y/4q+mP+Kvpj/ir6Y/4rBof+NysX/jtPk/4/Z+v+P2fr/ + j9j4/47U7P+Nz93/i8fO/4rEx/+JwcH/ib68/4m/vP+JwsL/isTH/4vJz/+Nz93/jtTs/4/Y+P+P2fr/ + j9n6/47T5v+My8j/i8Ch/4q+mP+Kvpj/Z6t4/zKNSf+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/ + jcKj/4/Iuf+Pzcn/kNHZ/5HV6P+R1/L/kdn2/5La+v+S2vv/ktr7/5La+v+R2fb/kdfy/5HV6P+Q0dj/ + j8zI/4/Iuf+NwqP/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/VKFp/4zAmvGQwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKe/5DEo/+QxKL/kMKe/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+NwZrxhr6XxJTFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/4/CncZ8u48p + k8ag9ZbHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+YyKX2 + mceoMgAAAAB8u48pjMKbxZbHo/KZyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+ayafz + lsaiyZvIqjMAAAAAgAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAIAAAAEoAAAAEAAAACAAAAABACAAAAAAAAAEAAATCwAAEwsAAAAAAAAAAAAA + HWcmSR1oJ+QdaCf/HWgn/x1oJ/8daCf/HWgn/xxkJf8XVB//F1Qf/xhVIP8YVyD/GVkh/xlaIv8ZXCLm + GlwiSx9rKeQfayn/H2sp/x9rKf8fayn/H2sp/x1nKP8aWTD/GVkw/xhUIf8ZViH/GVgi/xpaI/8aWyP/ + G10k/xteJOYgbiz/IG4s/yBuLP8gbiz/IG4s/x9rMf8idoH/K5jh/yuY4P8hdH//Gloq/xpYJP8aWiT/ + G1wl/xteJv8cYCb/InEv/yJxL/8icS//InEv/yN3Uf8rls//LJjM/x9rW/8ga1r/LJjM/yqUy/8dZUj/ + G1sl/xxdJv8cXyf/HWEo/z2DSv8zfUD/KHY2/yV8Wv8uoOD/I3Z4/xlQI/8ZUSP/GlQk/xtWJv8lfHz/ + LqHh/yBrU/8dXSj/HV4p/x5hKv9XlmP/V5Zj/1iYbP9Xs9//jbKr/5Kmjf+RpYv/kaaL/5GnjP+SqIz/ + kqmM/4Wvp/8votj/H2M2/x5fKv8eYSv/Xpxq/16cav9jr7L/XJaU/628qv9Te1z/QW5L/0NwSv87a0P/ + G1Yn/xxYKP+Tqo//Jn13/ymJk/8eYCz/H2Is/2Whcf9loXH/a73W/1p/ZP+wvq7/WoBi/3KSeP+luKX/ + kqqS/z9vR/8dWCn/k6uR/x9fL/8wocj/H2As/yBiLv9sp3n/bKd6/2+81P9fgmf/s8Kz/2CEaP93ln3/ + qryq/6q9q/9zlnr/MWY9/5SslP8eXCz/MaHE/yBhMP8gYi//c6yA/3OuiP90us3/ZoZt/7fFuP9niW7/ + Z4tv/36chP9+nYT/aY9x/2mPcf+vwrD/IF0t/zCct/8iaDz/IWMw/3mxhv95tJD/ebvM/2uKc/+xwbT/ + wc3C/87Yzv+7yr3/u8q9/87Zz//C0MP/ssa2/1eFYv8znbT/JGtD/yJjMf+Ato3/gLmZ/3+8yv9yj3n/ + cpB6/3yYg//I1Mr/mbCe/5mxn//I1cv/fp+G/3aafv92m3//bLnK/yhwSv8rfD//hruT/4a9nf+IzOP/ + f6uk/3qah/95loD/i6WS/560o/+etaT/jamU/3uchP99oov/gbKo/4nO5P9pqYP/MYtI/4y/mv+Mv5r/ + jMOn/47Mx/+P0t3/j9Lj/47P3/+Ozd3/js3d/47P4P+P0uL/j9Hd/47MyP+Mw6j/jL+a/1+mcf+OwZzt + ksSf/5LEn/+SxJ//ksSf/5LEn/+SxJ//ksSh/5LEof+SxJ//ksSf/5LEn/+SxJ//ksSf/5LEn/+Qw53t + jcOcUpTGou2YyKX/mMil/5jIpf+YyKX/mMil/5jIpf+YyKX/mMil/5jIpf+YyKX/mMil/5jIpf+Xx6Tv + mcimVwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAA= + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/SecureSandbox/EncryptEventHandler.cs b/Demo_Source_Code/CSharpDemo/SecureSandbox/EncryptEventHandler.cs new file mode 100644 index 0000000..b2b8604 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/SecureSandbox/EncryptEventHandler.cs @@ -0,0 +1,79 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; +using System.Runtime.InteropServices; +using System.Security.Principal; +using System.IO; +using System.Threading; +using System.Reflection; + +using EaseFilter.FilterControl; +using EaseFilter.CommonObjects; + +namespace SecureSandbox +{ + + public class EncryptEventHandler : IDisposable + { + bool disposed = false; + + public EncryptEventHandler() + { + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + private void Dispose(bool disposing) + { + if (!this.disposed) + { + } + + disposed = true; + } + + ~EncryptEventHandler() + { + Dispose(false); + } + + /// + /// Fires this event after the new file was created, the handle is not closed. + /// + public void OnFilterRequestEncryptKey(object sender, EncryptEventArgs e) + { + //if you want to block the encryption you can return access denied + // e.ReturnStatus = NtStatus.Status.AccessDenied; + //or return the encryption key and iv here. + //e.EncryptionKey = new byte[32]; //put your own encryption key here + //e.IV = Utils.GetRandomIV(); + + } + + } +} \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/SecureSandbox/Info.png b/Demo_Source_Code/CSharpDemo/SecureSandbox/Info.png new file mode 100644 index 0000000..c0e58c8 Binary files /dev/null and b/Demo_Source_Code/CSharpDemo/SecureSandbox/Info.png differ diff --git a/Demo_Source_Code/CSharpDemo/SecureSandbox/ProcessFileAccessRights.Designer.cs b/Demo_Source_Code/CSharpDemo/SecureSandbox/ProcessFileAccessRights.Designer.cs new file mode 100644 index 0000000..2dcb266 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/SecureSandbox/ProcessFileAccessRights.Designer.cs @@ -0,0 +1,363 @@ +namespace SecureSandbox +{ + partial class ProcessFileAccessRights + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ProcessFileAccessRights)); + this.button_ApplyAll = new System.Windows.Forms.Button(); + this.button_Add = new System.Windows.Forms.Button(); + this.button_Delete = new System.Windows.Forms.Button(); + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.listView_ProcessFileAccessRights = new System.Windows.Forms.ListView(); + this.groupBox_ProcessRights = new System.Windows.Forms.GroupBox(); + this.button_SelectFolder = new System.Windows.Forms.Button(); + this.button_Info = new System.Windows.Forms.Button(); + this.label1 = new System.Windows.Forms.Label(); + this.textBox_FileMask = new System.Windows.Forms.TextBox(); + this.label2 = new System.Windows.Forms.Label(); + this.textBox_AccessFlag = new System.Windows.Forms.TextBox(); + this.button_AccessFlag = new System.Windows.Forms.Button(); + this.checkBox_SetSecurity = new System.Windows.Forms.CheckBox(); + this.checkBox_QueryInfo = new System.Windows.Forms.CheckBox(); + this.checkBox_Read = new System.Windows.Forms.CheckBox(); + this.checkBox_QuerySecurity = new System.Windows.Forms.CheckBox(); + this.checkBox_SetInfo = new System.Windows.Forms.CheckBox(); + this.checkBox_Write = new System.Windows.Forms.CheckBox(); + this.checkBox_AllowDelete = new System.Windows.Forms.CheckBox(); + this.checkBox_AllowRename = new System.Windows.Forms.CheckBox(); + this.checkBox_Creation = new System.Windows.Forms.CheckBox(); + this.groupBox1.SuspendLayout(); + this.groupBox_ProcessRights.SuspendLayout(); + this.SuspendLayout(); + // + // button_ApplyAll + // + this.button_ApplyAll.DialogResult = System.Windows.Forms.DialogResult.OK; + this.button_ApplyAll.Location = new System.Drawing.Point(406, 381); + this.button_ApplyAll.Name = "button_ApplyAll"; + this.button_ApplyAll.Size = new System.Drawing.Size(144, 23); + this.button_ApplyAll.TabIndex = 85; + this.button_ApplyAll.Text = "Apply settings to sandbox"; + this.button_ApplyAll.UseVisualStyleBackColor = true; + this.button_ApplyAll.Click += new System.EventHandler(this.button_ApplyAll_Click); + // + // button_Add + // + this.button_Add.Location = new System.Drawing.Point(15, 381); + this.button_Add.Name = "button_Add"; + this.button_Add.Size = new System.Drawing.Size(122, 23); + this.button_Add.TabIndex = 84; + this.button_Add.Text = "Add file entry"; + this.button_Add.UseVisualStyleBackColor = true; + this.button_Add.Click += new System.EventHandler(this.button_Add_Click); + // + // button_Delete + // + this.button_Delete.Location = new System.Drawing.Point(197, 381); + this.button_Delete.Name = "button_Delete"; + this.button_Delete.Size = new System.Drawing.Size(128, 23); + this.button_Delete.TabIndex = 83; + this.button_Delete.Text = "Delete file entry"; + this.button_Delete.UseVisualStyleBackColor = true; + this.button_Delete.Click += new System.EventHandler(this.button_Delete_Click); + // + // groupBox1 + // + this.groupBox1.Controls.Add(this.listView_ProcessFileAccessRights); + this.groupBox1.Location = new System.Drawing.Point(15, 225); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size(535, 134); + this.groupBox1.TabIndex = 82; + this.groupBox1.TabStop = false; + this.groupBox1.Text = "File Access rights collection"; + // + // listView_ProcessFileAccessRights + // + this.listView_ProcessFileAccessRights.Dock = System.Windows.Forms.DockStyle.Fill; + this.listView_ProcessFileAccessRights.FullRowSelect = true; + this.listView_ProcessFileAccessRights.Location = new System.Drawing.Point(3, 16); + this.listView_ProcessFileAccessRights.Name = "listView_ProcessFileAccessRights"; + this.listView_ProcessFileAccessRights.Size = new System.Drawing.Size(529, 115); + this.listView_ProcessFileAccessRights.TabIndex = 1; + this.listView_ProcessFileAccessRights.UseCompatibleStateImageBehavior = false; + this.listView_ProcessFileAccessRights.View = System.Windows.Forms.View.Details; + this.listView_ProcessFileAccessRights.SelectedIndexChanged += new System.EventHandler(this.listView_ProcessFileAccessRights_SelectedIndexChanged); + // + // groupBox_ProcessRights + // + this.groupBox_ProcessRights.Controls.Add(this.button_SelectFolder); + this.groupBox_ProcessRights.Controls.Add(this.button_Info); + this.groupBox_ProcessRights.Controls.Add(this.label1); + this.groupBox_ProcessRights.Controls.Add(this.textBox_FileMask); + this.groupBox_ProcessRights.Controls.Add(this.label2); + this.groupBox_ProcessRights.Controls.Add(this.textBox_AccessFlag); + this.groupBox_ProcessRights.Controls.Add(this.button_AccessFlag); + this.groupBox_ProcessRights.Controls.Add(this.checkBox_SetSecurity); + this.groupBox_ProcessRights.Controls.Add(this.checkBox_QueryInfo); + this.groupBox_ProcessRights.Controls.Add(this.checkBox_Read); + this.groupBox_ProcessRights.Controls.Add(this.checkBox_QuerySecurity); + this.groupBox_ProcessRights.Controls.Add(this.checkBox_SetInfo); + this.groupBox_ProcessRights.Controls.Add(this.checkBox_Write); + this.groupBox_ProcessRights.Controls.Add(this.checkBox_AllowDelete); + this.groupBox_ProcessRights.Controls.Add(this.checkBox_AllowRename); + this.groupBox_ProcessRights.Controls.Add(this.checkBox_Creation); + this.groupBox_ProcessRights.Location = new System.Drawing.Point(21, 12); + this.groupBox_ProcessRights.Name = "groupBox_ProcessRights"; + this.groupBox_ProcessRights.Size = new System.Drawing.Size(529, 206); + this.groupBox_ProcessRights.TabIndex = 81; + this.groupBox_ProcessRights.TabStop = false; + this.groupBox_ProcessRights.Text = "Process Rights"; + // + // button_SelectFolder + // + this.button_SelectFolder.Location = new System.Drawing.Point(422, 32); + this.button_SelectFolder.Name = "button_SelectFolder"; + this.button_SelectFolder.Size = new System.Drawing.Size(60, 20); + this.button_SelectFolder.TabIndex = 92; + this.button_SelectFolder.Text = "..."; + this.button_SelectFolder.UseVisualStyleBackColor = true; + this.button_SelectFolder.Click += new System.EventHandler(this.button_SelectFolder_Click); + // + // button_Info + // + this.button_Info.BackColor = System.Drawing.Color.AntiqueWhite; + this.button_Info.Image = global::SecureSandbox.Properties.Resources.about; + this.button_Info.Location = new System.Drawing.Point(484, 32); + this.button_Info.Name = "button_Info"; + this.button_Info.Size = new System.Drawing.Size(33, 20); + this.button_Info.TabIndex = 91; + this.button_Info.UseVisualStyleBackColor = false; + this.button_Info.Click += new System.EventHandler(this.button_Info_Click); + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(12, 32); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(80, 13); + this.label1.TabIndex = 39; + this.label1.Text = "File name mask"; + // + // textBox_FileMask + // + this.textBox_FileMask.Location = new System.Drawing.Point(152, 32); + this.textBox_FileMask.Name = "textBox_FileMask"; + this.textBox_FileMask.Size = new System.Drawing.Size(242, 20); + this.textBox_FileMask.TabIndex = 38; + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(10, 70); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(97, 13); + this.label2.TabIndex = 32; + this.label2.Text = "Access control flag"; + // + // textBox_AccessFlag + // + this.textBox_AccessFlag.Location = new System.Drawing.Point(152, 67); + this.textBox_AccessFlag.Name = "textBox_AccessFlag"; + this.textBox_AccessFlag.ReadOnly = true; + this.textBox_AccessFlag.Size = new System.Drawing.Size(242, 20); + this.textBox_AccessFlag.TabIndex = 31; + this.textBox_AccessFlag.Text = "0"; + // + // button_AccessFlag + // + this.button_AccessFlag.Location = new System.Drawing.Point(422, 69); + this.button_AccessFlag.Name = "button_AccessFlag"; + this.button_AccessFlag.Size = new System.Drawing.Size(60, 20); + this.button_AccessFlag.TabIndex = 33; + this.button_AccessFlag.Text = "..."; + this.button_AccessFlag.UseVisualStyleBackColor = true; + this.button_AccessFlag.Click += new System.EventHandler(this.button_AccessFlag_Click); + // + // checkBox_SetSecurity + // + this.checkBox_SetSecurity.AutoSize = true; + this.checkBox_SetSecurity.Checked = true; + this.checkBox_SetSecurity.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBox_SetSecurity.Location = new System.Drawing.Point(152, 152); + this.checkBox_SetSecurity.Name = "checkBox_SetSecurity"; + this.checkBox_SetSecurity.Size = new System.Drawing.Size(137, 17); + this.checkBox_SetSecurity.TabIndex = 29; + this.checkBox_SetSecurity.Text = "Allow changing security"; + this.checkBox_SetSecurity.UseVisualStyleBackColor = true; + this.checkBox_SetSecurity.CheckedChanged += new System.EventHandler(this.checkBox_SetSecurity_CheckedChanged); + // + // checkBox_QueryInfo + // + this.checkBox_QueryInfo.AutoSize = true; + this.checkBox_QueryInfo.Checked = true; + this.checkBox_QueryInfo.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBox_QueryInfo.Location = new System.Drawing.Point(334, 129); + this.checkBox_QueryInfo.Name = "checkBox_QueryInfo"; + this.checkBox_QueryInfo.Size = new System.Drawing.Size(148, 17); + this.checkBox_QueryInfo.TabIndex = 24; + this.checkBox_QueryInfo.Text = "Allow querying information"; + this.checkBox_QueryInfo.UseVisualStyleBackColor = true; + this.checkBox_QueryInfo.CheckedChanged += new System.EventHandler(this.checkBox_QueryInfo_CheckedChanged); + // + // checkBox_Read + // + this.checkBox_Read.AutoSize = true; + this.checkBox_Read.Checked = true; + this.checkBox_Read.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBox_Read.Location = new System.Drawing.Point(334, 106); + this.checkBox_Read.Name = "checkBox_Read"; + this.checkBox_Read.Size = new System.Drawing.Size(105, 17); + this.checkBox_Read.TabIndex = 26; + this.checkBox_Read.Text = "Allow reading file"; + this.checkBox_Read.UseVisualStyleBackColor = true; + this.checkBox_Read.CheckedChanged += new System.EventHandler(this.checkBox_Read_CheckedChanged); + // + // checkBox_QuerySecurity + // + this.checkBox_QuerySecurity.AutoSize = true; + this.checkBox_QuerySecurity.Checked = true; + this.checkBox_QuerySecurity.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBox_QuerySecurity.Location = new System.Drawing.Point(334, 152); + this.checkBox_QuerySecurity.Name = "checkBox_QuerySecurity"; + this.checkBox_QuerySecurity.Size = new System.Drawing.Size(133, 17); + this.checkBox_QuerySecurity.TabIndex = 25; + this.checkBox_QuerySecurity.Text = "Allow querying security"; + this.checkBox_QuerySecurity.UseVisualStyleBackColor = true; + this.checkBox_QuerySecurity.CheckedChanged += new System.EventHandler(this.checkBox_QuerySecurity_CheckedChanged); + // + // checkBox_SetInfo + // + this.checkBox_SetInfo.AutoSize = true; + this.checkBox_SetInfo.Checked = true; + this.checkBox_SetInfo.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBox_SetInfo.Location = new System.Drawing.Point(152, 128); + this.checkBox_SetInfo.Name = "checkBox_SetInfo"; + this.checkBox_SetInfo.Size = new System.Drawing.Size(152, 17); + this.checkBox_SetInfo.TabIndex = 28; + this.checkBox_SetInfo.Text = "Allow changing information"; + this.checkBox_SetInfo.UseVisualStyleBackColor = true; + this.checkBox_SetInfo.CheckedChanged += new System.EventHandler(this.checkBox_SetInfo_CheckedChanged); + // + // checkBox_Write + // + this.checkBox_Write.AutoSize = true; + this.checkBox_Write.Checked = true; + this.checkBox_Write.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBox_Write.Location = new System.Drawing.Point(12, 129); + this.checkBox_Write.Name = "checkBox_Write"; + this.checkBox_Write.Size = new System.Drawing.Size(100, 17); + this.checkBox_Write.TabIndex = 15; + this.checkBox_Write.Text = "Allow writing file"; + this.checkBox_Write.UseVisualStyleBackColor = true; + this.checkBox_Write.CheckedChanged += new System.EventHandler(this.checkBox_Write_CheckedChanged); + // + // checkBox_AllowDelete + // + this.checkBox_AllowDelete.AutoSize = true; + this.checkBox_AllowDelete.Checked = true; + this.checkBox_AllowDelete.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBox_AllowDelete.Location = new System.Drawing.Point(12, 152); + this.checkBox_AllowDelete.Name = "checkBox_AllowDelete"; + this.checkBox_AllowDelete.Size = new System.Drawing.Size(107, 17); + this.checkBox_AllowDelete.TabIndex = 17; + this.checkBox_AllowDelete.Text = "Allow deleting file"; + this.checkBox_AllowDelete.UseVisualStyleBackColor = true; + this.checkBox_AllowDelete.CheckedChanged += new System.EventHandler(this.checkBox_AllowDelete_CheckedChanged); + // + // checkBox_AllowRename + // + this.checkBox_AllowRename.AutoSize = true; + this.checkBox_AllowRename.Checked = true; + this.checkBox_AllowRename.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBox_AllowRename.Location = new System.Drawing.Point(152, 106); + this.checkBox_AllowRename.Name = "checkBox_AllowRename"; + this.checkBox_AllowRename.Size = new System.Drawing.Size(113, 17); + this.checkBox_AllowRename.TabIndex = 16; + this.checkBox_AllowRename.Text = "Allow renaming file"; + this.checkBox_AllowRename.UseVisualStyleBackColor = true; + this.checkBox_AllowRename.CheckedChanged += new System.EventHandler(this.checkBox_AllowRename_CheckedChanged); + // + // checkBox_Creation + // + this.checkBox_Creation.AutoSize = true; + this.checkBox_Creation.Checked = true; + this.checkBox_Creation.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBox_Creation.Location = new System.Drawing.Point(12, 106); + this.checkBox_Creation.Name = "checkBox_Creation"; + this.checkBox_Creation.Size = new System.Drawing.Size(131, 17); + this.checkBox_Creation.TabIndex = 22; + this.checkBox_Creation.Text = "Allow creating new file"; + this.checkBox_Creation.UseVisualStyleBackColor = true; + this.checkBox_Creation.CheckedChanged += new System.EventHandler(this.checkBox_Creation_CheckedChanged); + // + // ProcessFileAccessRights + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(562, 444); + this.Controls.Add(this.button_ApplyAll); + this.Controls.Add(this.button_Add); + this.Controls.Add(this.button_Delete); + this.Controls.Add(this.groupBox1); + this.Controls.Add(this.groupBox_ProcessRights); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Name = "ProcessFileAccessRights"; + this.Text = "Process File Access Rights"; + this.groupBox1.ResumeLayout(false); + this.groupBox_ProcessRights.ResumeLayout(false); + this.groupBox_ProcessRights.PerformLayout(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.Button button_ApplyAll; + private System.Windows.Forms.Button button_Add; + private System.Windows.Forms.Button button_Delete; + private System.Windows.Forms.GroupBox groupBox1; + private System.Windows.Forms.ListView listView_ProcessFileAccessRights; + private System.Windows.Forms.GroupBox groupBox_ProcessRights; + private System.Windows.Forms.Button button_Info; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.TextBox textBox_FileMask; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.TextBox textBox_AccessFlag; + private System.Windows.Forms.Button button_AccessFlag; + private System.Windows.Forms.CheckBox checkBox_SetSecurity; + private System.Windows.Forms.CheckBox checkBox_QueryInfo; + private System.Windows.Forms.CheckBox checkBox_Read; + private System.Windows.Forms.CheckBox checkBox_QuerySecurity; + private System.Windows.Forms.CheckBox checkBox_SetInfo; + private System.Windows.Forms.CheckBox checkBox_Write; + private System.Windows.Forms.CheckBox checkBox_AllowDelete; + private System.Windows.Forms.CheckBox checkBox_AllowRename; + private System.Windows.Forms.CheckBox checkBox_Creation; + private System.Windows.Forms.Button button_SelectFolder; + } +} \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/SecureSandbox/ProcessFileAccessRights.cs b/Demo_Source_Code/CSharpDemo/SecureSandbox/ProcessFileAccessRights.cs new file mode 100644 index 0000000..cdfba1f --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/SecureSandbox/ProcessFileAccessRights.cs @@ -0,0 +1,423 @@ +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; + +using EaseFilter.FilterControl; +using EaseFilter.CommonObjects; + +namespace SecureSandbox +{ + public partial class ProcessFileAccessRights : Form + { + public struct FileAccessRight + { + public string FileNameMask; + public uint AccessFlag; + } + + ProcessFilterRule currentFilterRule = null; + Dictionary processFileAccessRightsList = new Dictionary(); + FileAccessRight currentFileAccessRight = new FileAccessRight(); + + public ProcessFileAccessRights(ProcessFilterRule filterRule) + { + InitializeComponent(); + + StartPosition = FormStartPosition.CenterParent; + + currentFilterRule = filterRule; + string processFileAccessRights = filterRule.FileAccessRights; + + string[] accessRightList = processFileAccessRights.ToLower().Split(new char[] { ';' }); + if (accessRightList.Length > 0) + { + foreach (string processFileAccessRightStr in accessRightList) + { + if (processFileAccessRightStr.Trim().Length > 0) + { + string fileMask = processFileAccessRightStr.Substring(0, processFileAccessRightStr.IndexOf('!')); + uint accessFlag = uint.Parse(processFileAccessRightStr.Substring(processFileAccessRightStr.IndexOf('!') + 1)); + + if (!processFileAccessRightsList.ContainsKey(fileMask)) + { + FileAccessRight fileAccessRight = new FileAccessRight(); + fileAccessRight.FileNameMask = fileMask; + fileAccessRight.AccessFlag = accessFlag; + + processFileAccessRightsList.Add(fileMask, fileAccessRight); + currentFileAccessRight = fileAccessRight; + } + + textBox_FileMask.Text = fileMask; + textBox_AccessFlag.Text = accessFlag.ToString(); + } + } + + } + + groupBox_ProcessRights.Text = "The file access rights for processes which match " + filterRule.ProcessNameFilterMask; + + InitListView(); + SetCheckBoxValue(); + } + + public void InitListView() + { + //init ListView control + listView_ProcessFileAccessRights.Clear(); //clear control + //create column header for ListView + listView_ProcessFileAccessRights.Columns.Add("#", 20, System.Windows.Forms.HorizontalAlignment.Left); + listView_ProcessFileAccessRights.Columns.Add("File Name Mask", 350, System.Windows.Forms.HorizontalAlignment.Left); + listView_ProcessFileAccessRights.Columns.Add("Access Flag", 150, System.Windows.Forms.HorizontalAlignment.Left); + + foreach (FileAccessRight fileAccessRight in processFileAccessRightsList.Values) + { + string[] itemStr = new string[listView_ProcessFileAccessRights.Columns.Count]; + itemStr[0] = listView_ProcessFileAccessRights.Items.Count.ToString(); + itemStr[1] = fileAccessRight.FileNameMask; + itemStr[2] = fileAccessRight.AccessFlag.ToString("X"); + + ListViewItem item = new ListViewItem(itemStr, 0); + item.Tag = fileAccessRight; + listView_ProcessFileAccessRights.Items.Add(item); + } + + } + + private void SetCheckBoxValue() + { + + if (textBox_AccessFlag.Text.Trim().Length == 0) + { + return; + } + + uint accessFlags = uint.Parse(textBox_AccessFlag.Text); + + if ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_FILE_DELETE) > 0) + { + checkBox_AllowDelete.Checked = true; + } + else + { + checkBox_AllowDelete.Checked = false; + } + + if ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_FILE_RENAME) > 0) + { + checkBox_AllowRename.Checked = true; + } + else + { + checkBox_AllowRename.Checked = false; + } + + if ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_WRITE_ACCESS) > 0) + { + checkBox_Write.Checked = true; + } + else + { + checkBox_Write.Checked = false; + } + + if ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_READ_ACCESS) > 0) + { + checkBox_Read.Checked = true; + } + else + { + checkBox_Read.Checked = false; + } + + if ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_QUERY_INFORMATION_ACCESS) > 0) + { + checkBox_QueryInfo.Checked = true; + } + else + { + checkBox_QueryInfo.Checked = false; + } + + if ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_SET_INFORMATION) > 0) + { + checkBox_SetInfo.Checked = true; + } + else + { + checkBox_SetInfo.Checked = false; + } + + if ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_OPEN_WITH_CREATE_OR_OVERWRITE_ACCESS) > 0) + { + checkBox_Creation.Checked = true; + } + else + { + checkBox_Creation.Checked = false; + } + + if ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_QUERY_SECURITY_ACCESS) > 0) + { + checkBox_QuerySecurity.Checked = true; + } + else + { + checkBox_QuerySecurity.Checked = false; + } + + if ((accessFlags & (uint)FilterAPI.AccessFlag.ALLOW_SET_SECURITY_ACCESS) > 0) + { + checkBox_SetSecurity.Checked = true; + } + else + { + checkBox_SetSecurity.Checked = false; + } + + + } + + private void button_AccessFlag_Click(object sender, EventArgs e) + { + OptionForm optionForm = new OptionForm(OptionForm.OptionType.Access_Flag, textBox_AccessFlag.Text); + + if (optionForm.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + if (optionForm.AccessFlags > 0) + { + textBox_AccessFlag.Text = optionForm.AccessFlags.ToString(); + } + else + { + //if the accessFlag is 0, it is exclude filter rule,this is not what we want, so we need to include this flag. + textBox_AccessFlag.Text = ((uint)FilterAPI.AccessFlag.LEAST_ACCESS_FLAG).ToString(); + } + + SetCheckBoxValue(); + } + } + + private void checkBox_Read_CheckedChanged(object sender, EventArgs e) + { + uint accessFlags = uint.Parse(textBox_AccessFlag.Text.Trim()); + if (checkBox_Read.Checked) + { + accessFlags |= (uint)FilterAPI.ALLOW_FILE_READ_ACCESS; + } + else + { + accessFlags &= ~(uint)FilterAPI.ALLOW_FILE_READ_ACCESS; + } + + textBox_AccessFlag.Text = accessFlags.ToString(); + } + + private void checkBox_Write_CheckedChanged(object sender, EventArgs e) + { + uint accessFlags = uint.Parse(textBox_AccessFlag.Text.Trim()); + if (checkBox_Write.Checked) + { + accessFlags |= (uint)FilterAPI.AccessFlag.ALLOW_WRITE_ACCESS | (uint)FilterAPI.AccessFlag.ALLOW_OPEN_WITH_WRITE_ACCESS; + } + else + { + accessFlags &= ~((uint)FilterAPI.AccessFlag.ALLOW_WRITE_ACCESS | (uint)FilterAPI.AccessFlag.ALLOW_OPEN_WITH_WRITE_ACCESS); + } + + textBox_AccessFlag.Text = accessFlags.ToString(); + } + + private void checkBox_Creation_CheckedChanged(object sender, EventArgs e) + { + uint accessFlags = uint.Parse(textBox_AccessFlag.Text.Trim()); + if (checkBox_Creation.Checked) + { + accessFlags |= (uint)FilterAPI.AccessFlag.ALLOW_OPEN_WITH_CREATE_OR_OVERWRITE_ACCESS; + } + else + { + accessFlags &= ~(uint)FilterAPI.AccessFlag.ALLOW_OPEN_WITH_CREATE_OR_OVERWRITE_ACCESS; + } + + textBox_AccessFlag.Text = accessFlags.ToString(); + } + + + private void checkBox_QueryInfo_CheckedChanged(object sender, EventArgs e) + { + uint accessFlags = uint.Parse(textBox_AccessFlag.Text.Trim()); + if (checkBox_QueryInfo.Checked) + { + accessFlags |= (uint)FilterAPI.AccessFlag.ALLOW_QUERY_INFORMATION_ACCESS; + } + else + { + accessFlags &= ~(uint)FilterAPI.AccessFlag.ALLOW_QUERY_INFORMATION_ACCESS; + } + + textBox_AccessFlag.Text = accessFlags.ToString(); + } + + private void checkBox_SetInfo_CheckedChanged(object sender, EventArgs e) + { + uint accessFlags = uint.Parse(textBox_AccessFlag.Text.Trim()); + if (checkBox_SetInfo.Checked) + { + accessFlags |= (uint)FilterAPI.AccessFlag.ALLOW_SET_INFORMATION; + } + else + { + accessFlags &= ~(uint)FilterAPI.AccessFlag.ALLOW_SET_INFORMATION; + } + + textBox_AccessFlag.Text = accessFlags.ToString(); + } + + private void checkBox_AllowRename_CheckedChanged(object sender, EventArgs e) + { + uint accessFlags = uint.Parse(textBox_AccessFlag.Text.Trim()); + if (checkBox_AllowRename.Checked) + { + accessFlags |= (uint)FilterAPI.AccessFlag.ALLOW_FILE_RENAME; + } + else + { + accessFlags &= ~(uint)FilterAPI.AccessFlag.ALLOW_FILE_RENAME; + } + + textBox_AccessFlag.Text = accessFlags.ToString(); + } + + private void checkBox_AllowDelete_CheckedChanged(object sender, EventArgs e) + { + uint accessFlags = uint.Parse(textBox_AccessFlag.Text.Trim()); + if (checkBox_AllowDelete.Checked) + { + accessFlags |= (uint)FilterAPI.AccessFlag.ALLOW_FILE_DELETE; + } + else + { + accessFlags &= ~(uint)FilterAPI.AccessFlag.ALLOW_FILE_DELETE; + } + + textBox_AccessFlag.Text = accessFlags.ToString(); + } + + private void checkBox_QuerySecurity_CheckedChanged(object sender, EventArgs e) + { + uint accessFlags = uint.Parse(textBox_AccessFlag.Text.Trim()); + if (checkBox_QuerySecurity.Checked) + { + accessFlags |= (uint)FilterAPI.AccessFlag.ALLOW_QUERY_SECURITY_ACCESS; + } + else + { + accessFlags &= ~(uint)FilterAPI.AccessFlag.ALLOW_QUERY_SECURITY_ACCESS; + } + + textBox_AccessFlag.Text = accessFlags.ToString(); + } + + private void checkBox_SetSecurity_CheckedChanged(object sender, EventArgs e) + { + uint accessFlags = uint.Parse(textBox_AccessFlag.Text.Trim()); + if (checkBox_SetSecurity.Checked) + { + accessFlags |= (uint)FilterAPI.AccessFlag.ALLOW_SET_SECURITY_ACCESS; + } + else + { + accessFlags &= ~(uint)FilterAPI.AccessFlag.ALLOW_SET_SECURITY_ACCESS; + } + + textBox_AccessFlag.Text = accessFlags.ToString(); + } + + + private void button_Add_Click(object sender, EventArgs e) + { + if (textBox_FileMask.Text.Trim().Length == 0) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("The file name mask can't be empty.", "Add file entry", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + + FileAccessRight fileAccessRight = new FileAccessRight(); + fileAccessRight.FileNameMask = textBox_FileMask.Text; + fileAccessRight.AccessFlag = uint.Parse(textBox_AccessFlag.Text); + + processFileAccessRightsList.Remove(fileAccessRight.FileNameMask); + + processFileAccessRightsList.Add(fileAccessRight.FileNameMask, fileAccessRight); + + InitListView(); + } + + private void button_Delete_Click(object sender, EventArgs e) + { + if (listView_ProcessFileAccessRights.SelectedItems.Count == 0) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("There are no item selected.", "Delete entry", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + FileAccessRight processFileAccessRight = (FileAccessRight)listView_ProcessFileAccessRights.SelectedItems[0].Tag; + + processFileAccessRightsList.Remove(processFileAccessRight.FileNameMask); + + InitListView(); + } + + private void button_ApplyAll_Click(object sender, EventArgs e) + { + currentFilterRule.FileAccessRights = string.Empty; + + foreach (FileAccessRight fileAccessRight in processFileAccessRightsList.Values) + { + currentFilterRule.FileAccessRights += fileAccessRight.FileNameMask + "!" + fileAccessRight.AccessFlag + ";"; + } + } + + private void button_SelectFolder_Click(object sender, EventArgs e) + { + FolderBrowserDialog folderDiag = new FolderBrowserDialog(); + + if (folderDiag.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + textBox_FileMask.Text = folderDiag.SelectedPath + "\\*"; + } + } + + private void button_Info_Click(object sender, EventArgs e) + { + string information = "Set up the file access rights with the file filter mask to the processes which were launched from the sandbox.\r\n\r\n"; + information += "you can restrict the process's file access rights to the specific folders, prevent the files being read or changed by the processes inside the sandbox.\r\n\r\n"; + + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show(information, "File access rights", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + + private void listView_ProcessFileAccessRights_SelectedIndexChanged(object sender, EventArgs e) + { + if (listView_ProcessFileAccessRights.SelectedItems.Count > 0) + { + + currentFileAccessRight = (FileAccessRight)listView_ProcessFileAccessRights.SelectedItems[0].Tag; + + textBox_FileMask.Text = currentFileAccessRight.FileNameMask; + textBox_AccessFlag.Text = currentFileAccessRight.AccessFlag.ToString(); + + SetCheckBoxValue(); + } + } + } +} diff --git a/Demo_Source_Code/CSharpDemo/SecureSandbox/ProcessFileAccessRights.resx b/Demo_Source_Code/CSharpDemo/SecureSandbox/ProcessFileAccessRights.resx new file mode 100644 index 0000000..0c9478a --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/SecureSandbox/ProcessFileAccessRights.resx @@ -0,0 +1,1847 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + 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 + qJ73+c18/Xp5VJ9fl/P5y6LcpupvP3RkTF7d3T6A8xcBAARGAACBEQBAYAQAEBgBAARGAACB/Q//xIY7 + IGrejgAAAABJRU5ErkJggigAAACAAAAAAAEAAAEAIAAAAAAAAAABABMLAAATCwAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAG2QkHBtkJBwbZCQcG2QkHB1nJqkdZyapHWcmqR1nJqkcZybnHGcm5xxnJuccZybn + HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/ + HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/ + HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/ + HGcm/xxnJv8cZyb/GFoh/xhaIf8YWiH/GFoh/xZSHv8WUh7/FlIe/xZSHv8XUx//F1Mf/xdTH/8XUx// + F1Qf/xdUH/8XVB//F1Qf/xdUH/8XVB//F1Qf/xdUH/8XViD/F1Yg/xdWIP8XViD/F1Yg/xdWIP8XViD/ + F1Yg/xhXIP8YVyD/GFcg/xhXIP8YWCD/GFgg/xhYIP8YWCD/GFkh/xhZIf8YWSH/GFkh/xhaIf8YWiH/ + GFoh/xhaIf8ZWiH/GVoh/xlaIf8ZWiH/GFwi6RhcIukYXCLpGFwi6RpcIq8aXCKvGlwirxpcIq8ZWiEf + GVohHxlaIR8ZWiEfAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbZCQcG2QkHBtkJBwbZCQc + HWcmqR1nJqkdZyapHWcmqRxnJuccZybnHGcm5xxnJuccZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/ + HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/ + HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/ + HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8YWiH/GFoh/xhaIf8YWiH/ + FlIe/xZSHv8WUh7/FlIe/xdTH/8XUx//F1Mf/xdTH/8XVB//F1Qf/xdUH/8XVB//F1Qf/xdUH/8XVB// + F1Qf/xdWIP8XViD/F1Yg/xdWIP8XViD/F1Yg/xdWIP8XViD/GFcg/xhXIP8YVyD/GFcg/xhYIP8YWCD/ + GFgg/xhYIP8YWSH/GFkh/xhZIf8YWSH/GFoh/xhaIf8YWiH/GFoh/xlaIf8ZWiH/GVoh/xlaIf8YXCLp + GFwi6RhcIukYXCLpGlwirxpcIq8aXCKvGlwirxlaIR8ZWiEfGVohHxlaIR8AAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAABtkJBwbZCQcG2QkHBtkJBwdZyapHWcmqR1nJqkdZyapHGcm5xxnJuccZybn + HGcm5xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/ + HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/ + HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/ + HGcm/xxnJv8cZyb/HGcm/xhaIf8YWiH/GFoh/xhaIf8WUh7/FlIe/xZSHv8WUh7/F1Mf/xdTH/8XUx// + F1Mf/xdUH/8XVB//F1Qf/xdUH/8XVB//F1Qf/xdUH/8XVB//F1Yg/xdWIP8XViD/F1Yg/xdWIP8XViD/ + F1Yg/xdWIP8YVyD/GFcg/xhXIP8YVyD/GFgg/xhYIP8YWCD/GFgg/xhZIf8YWSH/GFkh/xhZIf8YWiH/ + GFoh/xhaIf8YWiH/GVoh/xlaIf8ZWiH/GVoh/xhcIukYXCLpGFwi6RhcIukaXCKvGlwirxpcIq8aXCKv + GVohHxlaIR8ZWiEfGVohHwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAG2QkHBtkJBwbZCQc + G2QkHB1nJqkdZyapHWcmqR1nJqkcZybnHGcm5xxnJuccZybnHGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/ + HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/ + HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/ + HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/GFoh/xhaIf8YWiH/ + GFoh/xZSHv8WUh7/FlIe/xZSHv8XUx//F1Mf/xdTH/8XUx//F1Qf/xdUH/8XVB//F1Qf/xdUH/8XVB// + F1Qf/xdUH/8XViD/F1Yg/xdWIP8XViD/F1Yg/xdWIP8XViD/F1Yg/xhXIP8YVyD/GFcg/xhXIP8YWCD/ + GFgg/xhYIP8YWCD/GFkh/xhZIf8YWSH/GFkh/xhaIf8YWiH/GFoh/xhaIf8ZWiH/GVoh/xlaIf8ZWiH/ + GFwi6RhcIukYXCLpGFwi6RpcIq8aXCKvGlwirxpcIq8ZWiEfGVohHxlaIR8ZWiEfAAAAAAAAAAAAAAAA + AAAAABtkJBwbZCQcG2QkHBtkJBwdaCftHWgn7R1oJ+0daCftHWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/xlaIv8ZWiL/GVoi/xlaIv8XUR7/F1Ee/xdRHv8XUR7/F1If/xdSH/8XUh//F1If/xdTH/8XUx// + F1Mf/xdTH/8XVB//F1Qf/xdUH/8XVB//GFQg/xhUIP8YVCD/GFQg/xhVIP8YVSD/GFUg/xhVIP8YViD/ + GFYg/xhWIP8YViD/GFch/xhXIf8YVyH/GFch/xlYIf8ZWCH/GVgh/xlYIf8ZWSH/GVkh/xlZIf8ZWSH/ + GVoi/xlaIv8ZWiL/GVoi/xlbIv8ZWyL/GVsi/xlbIv8ZWyL/GVsi/xlbIv8ZWyL/Glwj/xpcI/8aXCP/ + Glwj/xpdIu8aXSLvGl0i7xpdIu8ZWiEfGVohHxlaIR8ZWiEfG2QkHBtkJBwbZCQcG2QkHB1oJ+0daCft + HWgn7R1oJ+0daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/GVoi/xlaIv8ZWiL/GVoi/xdRHv8XUR7/ + F1Ee/xdRHv8XUh//F1If/xdSH/8XUh//F1Mf/xdTH/8XUx//F1Mf/xdUH/8XVB//F1Qf/xdUH/8YVCD/ + GFQg/xhUIP8YVCD/GFUg/xhVIP8YVSD/GFUg/xhWIP8YViD/GFYg/xhWIP8YVyH/GFch/xhXIf8YVyH/ + GVgh/xlYIf8ZWCH/GVgh/xlZIf8ZWSH/GVkh/xlZIf8ZWiL/GVoi/xlaIv8ZWiL/GVsi/xlbIv8ZWyL/ + GVsi/xlbIv8ZWyL/GVsi/xlbIv8aXCP/Glwj/xpcI/8aXCP/Gl0i7xpdIu8aXSLvGl0i7xlaIR8ZWiEf + GVohHxlaIR8bZCQcG2QkHBtkJBwbZCQcHWgn7R1oJ+0daCftHWgn7R1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8ZWiL/GVoi/xlaIv8ZWiL/F1Ee/xdRHv8XUR7/F1Ee/xdSH/8XUh//F1If/xdSH/8XUx// + F1Mf/xdTH/8XUx//F1Qf/xdUH/8XVB//F1Qf/xhUIP8YVCD/GFQg/xhUIP8YVSD/GFUg/xhVIP8YVSD/ + GFYg/xhWIP8YViD/GFYg/xhXIf8YVyH/GFch/xhXIf8ZWCH/GVgh/xlYIf8ZWCH/GVkh/xlZIf8ZWSH/ + GVkh/xlaIv8ZWiL/GVoi/xlaIv8ZWyL/GVsi/xlbIv8ZWyL/GVsi/xlbIv8ZWyL/GVsi/xpcI/8aXCP/ + Glwj/xpcI/8aXSLvGl0i7xpdIu8aXSLvGVohHxlaIR8ZWiEfGVohHxtkJBwbZCQcG2QkHBtkJBwdaCft + HWgn7R1oJ+0daCftHWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/xlaIv8ZWiL/GVoi/xlaIv8XUR7/ + F1Ee/xdRHv8XUR7/F1If/xdSH/8XUh//F1If/xdTH/8XUx//F1Mf/xdTH/8XVB//F1Qf/xdUH/8XVB// + GFQg/xhUIP8YVCD/GFQg/xhVIP8YVSD/GFUg/xhVIP8YViD/GFYg/xhWIP8YViD/GFch/xhXIf8YVyH/ + GFch/xlYIf8ZWCH/GVgh/xlYIf8ZWSH/GVkh/xlZIf8ZWSH/GVoi/xlaIv8ZWiL/GVoi/xlbIv8ZWyL/ + GVsi/xlbIv8ZWyL/GVsi/xlbIv8ZWyL/Glwj/xpcI/8aXCP/Glwj/xpdIu8aXSLvGl0i7xpdIu8ZWiEf + GVohHxlaIR8ZWiEfHmopqR5qKakeaimpHmopqR5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8aWyL/ + Glsi/xpbIv8aWyL/F1Ef/xdRH/8XUR//F1Ef/xdSH/8XUh//F1If/xdSH/8XUx//F1Mf/xdTH/8XUx// + GFQg/xhUIP8YVCD/GFQg/xhUIP8YVCD/GFQg/xhUIP8YVSD/GFUg/xhVIP8YVSD/GFYg/xhWIP8YViD/ + GFYg/xlXIf8ZVyH/GVch/xlXIf8ZWCH/GVgh/xlYIf8ZWCH/GVki/xlZIv8ZWSL/GVki/xlaIv8ZWiL/ + GVoi/xlaIv8aWyL/Glsi/xpbIv8aWyL/Glsj/xpbI/8aWyP/Glsj/xpcI/8aXCP/Glwj/xpcI/8aXSP/ + Gl0j/xpdI/8aXSP/G14j/xteI/8bXiP/G14j/xxfJK8cXySvHF8krxxfJK8eaimpHmopqR5qKakeaimp + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/xpbIv8aWyL/Glsi/xpbIv8XUR//F1Ef/xdRH/8XUR// + F1If/xdSH/8XUh//F1If/xdTH/8XUx//F1Mf/xdTH/8YVCD/GFQg/xhUIP8YVCD/GFQg/xhUIP8YVCD/ + GFQg/xhVIP8YVSD/GFUg/xhVIP8YViD/GFYg/xhWIP8YViD/GVch/xlXIf8ZVyH/GVch/xlYIf8ZWCH/ + GVgh/xlYIf8ZWSL/GVki/xlZIv8ZWSL/GVoi/xlaIv8ZWiL/GVoi/xpbIv8aWyL/Glsi/xpbIv8aWyP/ + Glsj/xpbI/8aWyP/Glwj/xpcI/8aXCP/Glwj/xpdI/8aXSP/Gl0j/xpdI/8bXiP/G14j/xteI/8bXiP/ + HF8krxxfJK8cXySvHF8krx5qKakeaimpHmopqR5qKakeaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Glsi/xpbIv8aWyL/Glsi/xdRH/8XUR//F1Ef/xdRH/8XUh//F1If/xdSH/8XUh//F1Mf/xdTH/8XUx// + F1Mf/xhUIP8YVCD/GFQg/xhUIP8YVCD/GFQg/xhUIP8YVCD/GFUg/xhVIP8YVSD/GFUg/xhWIP8YViD/ + GFYg/xhWIP8ZVyH/GVch/xlXIf8ZVyH/GVgh/xlYIf8ZWCH/GVgh/xlZIv8ZWSL/GVki/xlZIv8ZWiL/ + GVoi/xlaIv8ZWiL/Glsi/xpbIv8aWyL/Glsi/xpbI/8aWyP/Glsj/xpbI/8aXCP/Glwj/xpcI/8aXCP/ + Gl0j/xpdI/8aXSP/Gl0j/xteI/8bXiP/G14j/xteI/8cXySvHF8krxxfJK8cXySvHmopqR5qKakeaimp + HmopqR5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8aWyL/Glsi/xpbIv8aWyL/F1Ef/xdRH/8XUR// + F1Ef/xdSH/8XUh//F1If/xdSH/8XUx//F1Mf/xdTH/8XUx//GFQg/xhUIP8YVCD/GFQg/xhUIP8YVCD/ + GFQg/xhUIP8YVSD/GFUg/xhVIP8YVSD/GFYg/xhWIP8YViD/GFYg/xlXIf8ZVyH/GVch/xlXIf8ZWCH/ + GVgh/xlYIf8ZWCH/GVki/xlZIv8ZWSL/GVki/xlaIv8ZWiL/GVoi/xlaIv8aWyL/Glsi/xpbIv8aWyL/ + Glsj/xpbI/8aWyP/Glsj/xpcI/8aXCP/Glwj/xpcI/8aXSP/Gl0j/xpdI/8aXSP/G14j/xteI/8bXiP/ + G14j/xxfJK8cXySvHF8krxxfJK8fayroH2sq6B9rKugfayroH2sq/x9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/Glsk/xpbJP8aWyT/ + Glsk/xdQH/8XUB//F1Af/xdQH/8eaWD/Hmlg/x5pYP8eaWD/Hmpg/x5qYP8eamD/Hmpg/xhTIP8YUyD/ + GFMg/xhTIP8YVCH/GFQh/xhUIf8YVCH/GFQh/xhUIf8YVCH/GFQh/xlVIf8ZVSH/GVUh/xlVIf8ZViL/ + GVYi/xlWIv8ZViL/GVci/xlXIv8ZVyL/GVci/xlYIv8ZWCL/GVgi/xlYIv8aWSP/Glkj/xpZI/8aWSP/ + Gloj/xpaI/8aWiP/Gloj/xpbJP8aWyT/Glsk/xpbJP8bWyT/G1sk/xtbJP8bWyT/G1wk/xtcJP8bXCT/ + G1wk/xtdJf8bXSX/G10l/xtdJf8bXiX/G14l/xteJf8bXiX/G18l6RtfJekbXyXpG18l6R9rKugfayro + H2sq6B9rKugfayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8aWyT/Glsk/xpbJP8aWyT/F1Af/xdQH/8XUB//F1Af/x5pYP8eaWD/ + Hmlg/x5pYP8eamD/Hmpg/x5qYP8eamD/GFMg/xhTIP8YUyD/GFMg/xhUIf8YVCH/GFQh/xhUIf8YVCH/ + GFQh/xhUIf8YVCH/GVUh/xlVIf8ZVSH/GVUh/xlWIv8ZViL/GVYi/xlWIv8ZVyL/GVci/xlXIv8ZVyL/ + GVgi/xlYIv8ZWCL/GVgi/xpZI/8aWSP/Glkj/xpZI/8aWiP/Gloj/xpaI/8aWiP/Glsk/xpbJP8aWyT/ + Glsk/xtbJP8bWyT/G1sk/xtbJP8bXCT/G1wk/xtcJP8bXCT/G10l/xtdJf8bXSX/G10l/xteJf8bXiX/ + G14l/xteJf8bXyXpG18l6RtfJekbXyXpH2sq6B9rKugfayroH2sq6B9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/xpbJP8aWyT/ + Glsk/xpbJP8XUB//F1Af/xdQH/8XUB//Hmlg/x5pYP8eaWD/Hmlg/x5qYP8eamD/Hmpg/x5qYP8YUyD/ + GFMg/xhTIP8YUyD/GFQh/xhUIf8YVCH/GFQh/xhUIf8YVCH/GFQh/xhUIf8ZVSH/GVUh/xlVIf8ZVSH/ + GVYi/xlWIv8ZViL/GVYi/xlXIv8ZVyL/GVci/xlXIv8ZWCL/GVgi/xlYIv8ZWCL/Glkj/xpZI/8aWSP/ + Glkj/xpaI/8aWiP/Gloj/xpaI/8aWyT/Glsk/xpbJP8aWyT/G1sk/xtbJP8bWyT/G1sk/xtcJP8bXCT/ + G1wk/xtcJP8bXSX/G10l/xtdJf8bXSX/G14l/xteJf8bXiX/G14l/xtfJekbXyXpG18l6RtfJekfayro + H2sq6B9rKugfayroH2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/Glsk/xpbJP8aWyT/Glsk/xdQH/8XUB//F1Af/xdQH/8eaWD/ + Hmlg/x5pYP8eaWD/Hmpg/x5qYP8eamD/Hmpg/xhTIP8YUyD/GFMg/xhTIP8YVCH/GFQh/xhUIf8YVCH/ + GFQh/xhUIf8YVCH/GFQh/xlVIf8ZVSH/GVUh/xlVIf8ZViL/GVYi/xlWIv8ZViL/GVci/xlXIv8ZVyL/ + GVci/xlYIv8ZWCL/GVgi/xlYIv8aWSP/Glkj/xpZI/8aWSP/Gloj/xpaI/8aWiP/Gloj/xpbJP8aWyT/ + Glsk/xpbJP8bWyT/G1sk/xtbJP8bWyT/G1wk/xtcJP8bXCT/G1wk/xtdJf8bXSX/G10l/xtdJf8bXiX/ + G14l/xteJf8bXiX/G18l6RtfJekbXyXpG18l6SBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/xtbJP8bWyT/G1sk/xtbJP8eaFr/ + Hmha/x5oWv8eaFr/JYKy/yWCsv8lgrL/JYKy/ymT3/8pk9//KZPf/ymT3/8pk9//KZPf/ymT3/8pk9// + JYKu/yWCrv8lgq7/JYKu/x5nVP8eZ1T/HmdU/x5nVP8ZVSL/GVUi/xlVIv8ZVSL/GVYi/xlWIv8ZViL/ + GVYi/xlXIv8ZVyL/GVci/xlXIv8aWCP/Glgj/xpYI/8aWCP/Glgj/xpYI/8aWCP/Glgj/xpZI/8aWSP/ + Glkj/xpZI/8bWyT/G1sk/xtbJP8bWyT/G1sk/xtbJP8bWyT/G1sk/xtcJP8bXCT/G1wk/xtcJP8bXSX/ + G10l/xtdJf8bXSX/HF4l/xxeJf8cXiX/HF4l/xxfJf8cXyX/HF8l/xxfJf8cYCb/HGAm/xxgJv8cYCb/ + IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/G1sk/xtbJP8bWyT/G1sk/x5oWv8eaFr/Hmha/x5oWv8lgrL/JYKy/yWCsv8lgrL/ + KZPf/ymT3/8pk9//KZPf/ymT3/8pk9//KZPf/ymT3/8lgq7/JYKu/yWCrv8lgq7/HmdU/x5nVP8eZ1T/ + HmdU/xlVIv8ZVSL/GVUi/xlVIv8ZViL/GVYi/xlWIv8ZViL/GVci/xlXIv8ZVyL/GVci/xpYI/8aWCP/ + Glgj/xpYI/8aWCP/Glgj/xpYI/8aWCP/Glkj/xpZI/8aWSP/Glkj/xtbJP8bWyT/G1sk/xtbJP8bWyT/ + G1sk/xtbJP8bWyT/G1wk/xtcJP8bXCT/G1wk/xtdJf8bXSX/G10l/xtdJf8cXiX/HF4l/xxeJf8cXiX/ + HF8l/xxfJf8cXyX/HF8l/xxgJv8cYCb/HGAm/xxgJv8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8bWyT/G1sk/xtbJP8bWyT/ + Hmha/x5oWv8eaFr/Hmha/yWCsv8lgrL/JYKy/yWCsv8pk9//KZPf/ymT3/8pk9//KZPf/ymT3/8pk9// + KZPf/yWCrv8lgq7/JYKu/yWCrv8eZ1T/HmdU/x5nVP8eZ1T/GVUi/xlVIv8ZVSL/GVUi/xlWIv8ZViL/ + GVYi/xlWIv8ZVyL/GVci/xlXIv8ZVyL/Glgj/xpYI/8aWCP/Glgj/xpYI/8aWCP/Glgj/xpYI/8aWSP/ + Glkj/xpZI/8aWSP/G1sk/xtbJP8bWyT/G1sk/xtbJP8bWyT/G1sk/xtbJP8bXCT/G1wk/xtcJP8bXCT/ + G10l/xtdJf8bXSX/G10l/xxeJf8cXiX/HF4l/xxeJf8cXyX/HF8l/xxfJf8cXyX/HGAm/xxgJv8cYCb/ + HGAm/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/IG0r/xtbJP8bWyT/G1sk/xtbJP8eaFr/Hmha/x5oWv8eaFr/JYKy/yWCsv8lgrL/ + JYKy/ymT3/8pk9//KZPf/ymT3/8pk9//KZPf/ymT3/8pk9//JYKu/yWCrv8lgq7/JYKu/x5nVP8eZ1T/ + HmdU/x5nVP8ZVSL/GVUi/xlVIv8ZVSL/GVYi/xlWIv8ZViL/GVYi/xlXIv8ZVyL/GVci/xlXIv8aWCP/ + Glgj/xpYI/8aWCP/Glgj/xpYI/8aWCP/Glgj/xpZI/8aWSP/Glkj/xpZI/8bWyT/G1sk/xtbJP8bWyT/ + G1sk/xtbJP8bWyT/G1sk/xtcJP8bXCT/G1wk/xtcJP8bXSX/G10l/xtdJf8bXSX/HF4l/xxeJf8cXiX/ + HF4l/xxfJf8cXyX/HF8l/xxfJf8cYCb/HGAm/xxgJv8cYCb/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8dZUD/HWVA/x1lQP8dZUD/JIGn/ySBp/8kgaf/ + JIGn/ymU3/8plN//KZTf/ymU3/8upPf/LqT3/y6k9/8upPf/L6j9/y+o/f8vqP3/L6j9/y+o/f8vqP3/ + L6j9/y+o/f8upPf/LqT3/y6k9/8upPf/KZTf/ymU3/8plN//KZTf/ySApf8kgKX/JICl/ySApf8cYkL/ + HGJC/xxiQv8cYkL/GVcj/xlXI/8ZVyP/GVcj/xlYJP8ZWCT/GVgk/xlYJP8aWCT/Glgk/xpYJP8aWCT/ + Glkl/xpZJf8aWSX/Glkl/xpaJf8aWiX/Glol/xpaJf8bWyX/G1sl/xtbJf8bWyX/G1wm/xtcJv8bXCb/ + G1wm/xtdJv8bXSb/G10m/xtdJv8bXib/G14m/xteJv8bXib/HF8n/xxfJ/8cXyf/HF8n/xxgJ/8cYCf/ + HGAn/xxgJ/8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/x1lQP8dZUD/HWVA/x1lQP8kgaf/JIGn/ySBp/8kgaf/KZTf/ymU3/8plN//KZTf/y6k9/8upPf/ + LqT3/y6k9/8vqP3/L6j9/y+o/f8vqP3/L6j9/y+o/f8vqP3/L6j9/y6k9/8upPf/LqT3/y6k9/8plN// + KZTf/ymU3/8plN//JICl/ySApf8kgKX/JICl/xxiQv8cYkL/HGJC/xxiQv8ZVyP/GVcj/xlXI/8ZVyP/ + GVgk/xlYJP8ZWCT/GVgk/xpYJP8aWCT/Glgk/xpYJP8aWSX/Glkl/xpZJf8aWSX/Glol/xpaJf8aWiX/ + Glol/xtbJf8bWyX/G1sl/xtbJf8bXCb/G1wm/xtcJv8bXCb/G10m/xtdJv8bXSb/G10m/xteJv8bXib/ + G14m/xteJv8cXyf/HF8n/xxfJ/8cXyf/HGAn/xxgJ/8cYCf/HGAn/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/HWVA/x1lQP8dZUD/HWVA/ySBp/8kgaf/ + JIGn/ySBp/8plN//KZTf/ymU3/8plN//LqT3/y6k9/8upPf/LqT3/y+o/f8vqP3/L6j9/y+o/f8vqP3/ + L6j9/y+o/f8vqP3/LqT3/y6k9/8upPf/LqT3/ymU3/8plN//KZTf/ymU3/8kgKX/JICl/ySApf8kgKX/ + HGJC/xxiQv8cYkL/HGJC/xlXI/8ZVyP/GVcj/xlXI/8ZWCT/GVgk/xlYJP8ZWCT/Glgk/xpYJP8aWCT/ + Glgk/xpZJf8aWSX/Glkl/xpZJf8aWiX/Glol/xpaJf8aWiX/G1sl/xtbJf8bWyX/G1sl/xtcJv8bXCb/ + G1wm/xtcJv8bXSb/G10m/xtdJv8bXSb/G14m/xteJv8bXib/G14m/xxfJ/8cXyf/HF8n/xxfJ/8cYCf/ + HGAn/xxgJ/8cYCf/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/yBuLf8dZUD/HWVA/x1lQP8dZUD/JIGn/ySBp/8kgaf/JIGn/ymU3/8plN//KZTf/ymU3/8upPf/ + LqT3/y6k9/8upPf/L6j9/y+o/f8vqP3/L6j9/y+o/f8vqP3/L6j9/y+o/f8upPf/LqT3/y6k9/8upPf/ + KZTf/ymU3/8plN//KZTf/ySApf8kgKX/JICl/ySApf8cYkL/HGJC/xxiQv8cYkL/GVcj/xlXI/8ZVyP/ + GVcj/xlYJP8ZWCT/GVgk/xlYJP8aWCT/Glgk/xpYJP8aWCT/Glkl/xpZJf8aWSX/Glkl/xpaJf8aWiX/ + Glol/xpaJf8bWyX/G1sl/xtbJf8bWyX/G1wm/xtcJv8bXCb/G1wm/xtdJv8bXSb/G10m/xtdJv8bXib/ + G14m/xteJv8bXib/HF8n/xxfJ/8cXyf/HF8n/xxgJ/8cYCf/HGAn/xxgJ/8hcC7/IXAu/yFwLv8hcC7/ + IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/ + IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/ + IXAu/yFwLv8hcS//IXEv/yFxL/8hcS//JHx+/yR8fv8kfH7/JHx+/ymR1P8pkdT/KZHU/ymR1P8vpfb/ + L6X2/y+l9v8vpfb/MKn8/zCp/P8wqfz/MKn8/yybzf8sm83/LJvN/yybzf8gblr/IG5a/yBuWv8gblr/ + IGxY/yBsWP8gbFj/IGxY/yyazP8smsz/LJrM/yyazP8wqfz/MKn8/zCp/P8wqfz/L6X2/y+l9v8vpfb/ + L6X2/yqR1P8qkdT/KpHU/yqR1P8gdHH/IHRx/yB0cf8gdHH/Glgk/xpYJP8aWCT/Glgk/xpZJf8aWSX/ + Glkl/xpZJf8bWiX/G1ol/xtaJf8bWiX/G1sl/xtbJf8bWyX/G1sl/xtcJv8bXCb/G1wm/xtcJv8bXSb/ + G10m/xtdJv8bXSb/HF4n/xxeJ/8cXif/HF4n/xxfJ/8cXyf/HF8n/xxfJ/8cYCf/HGAn/xxgJ/8cYCf/ + HGEo/xxhKP8cYSj/HGEo/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/ + IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/ + IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFxL/8hcS//IXEv/yFxL/8kfH7/ + JHx+/yR8fv8kfH7/KZHU/ymR1P8pkdT/KZHU/y+l9v8vpfb/L6X2/y+l9v8wqfz/MKn8/zCp/P8wqfz/ + LJvN/yybzf8sm83/LJvN/yBuWv8gblr/IG5a/yBuWv8gbFj/IGxY/yBsWP8gbFj/LJrM/yyazP8smsz/ + LJrM/zCp/P8wqfz/MKn8/zCp/P8vpfb/L6X2/y+l9v8vpfb/KpHU/yqR1P8qkdT/KpHU/yB0cf8gdHH/ + IHRx/yB0cf8aWCT/Glgk/xpYJP8aWCT/Glkl/xpZJf8aWSX/Glkl/xtaJf8bWiX/G1ol/xtaJf8bWyX/ + G1sl/xtbJf8bWyX/G1wm/xtcJv8bXCb/G1wm/xtdJv8bXSb/G10m/xtdJv8cXif/HF4n/xxeJ/8cXif/ + HF8n/xxfJ/8cXyf/HF8n/xxgJ/8cYCf/HGAn/xxgJ/8cYSj/HGEo/xxhKP8cYSj/IXAu/yFwLv8hcC7/ + IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/ + IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/ + IXAu/yFwLv8hcC7/IXEv/yFxL/8hcS//IXEv/yR8fv8kfH7/JHx+/yR8fv8pkdT/KZHU/ymR1P8pkdT/ + L6X2/y+l9v8vpfb/L6X2/zCp/P8wqfz/MKn8/zCp/P8sm83/LJvN/yybzf8sm83/IG5a/yBuWv8gblr/ + IG5a/yBsWP8gbFj/IGxY/yBsWP8smsz/LJrM/yyazP8smsz/MKn8/zCp/P8wqfz/MKn8/y+l9v8vpfb/ + L6X2/y+l9v8qkdT/KpHU/yqR1P8qkdT/IHRx/yB0cf8gdHH/IHRx/xpYJP8aWCT/Glgk/xpYJP8aWSX/ + Glkl/xpZJf8aWSX/G1ol/xtaJf8bWiX/G1ol/xtbJf8bWyX/G1sl/xtbJf8bXCb/G1wm/xtcJv8bXCb/ + G10m/xtdJv8bXSb/G10m/xxeJ/8cXif/HF4n/xxeJ/8cXyf/HF8n/xxfJ/8cXyf/HGAn/xxgJ/8cYCf/ + HGAn/xxhKP8cYSj/HGEo/xxhKP8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/ + IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/ + IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcS//IXEv/yFxL/8hcS// + JHx+/yR8fv8kfH7/JHx+/ymR1P8pkdT/KZHU/ymR1P8vpfb/L6X2/y+l9v8vpfb/MKn8/zCp/P8wqfz/ + MKn8/yybzf8sm83/LJvN/yybzf8gblr/IG5a/yBuWv8gblr/IGxY/yBsWP8gbFj/IGxY/yyazP8smsz/ + LJrM/yyazP8wqfz/MKn8/zCp/P8wqfz/L6X2/y+l9v8vpfb/L6X2/yqR1P8qkdT/KpHU/yqR1P8gdHH/ + IHRx/yB0cf8gdHH/Glgk/xpYJP8aWCT/Glgk/xpZJf8aWSX/Glkl/xpZJf8bWiX/G1ol/xtaJf8bWiX/ + G1sl/xtbJf8bWyX/G1sl/xtcJv8bXCb/G1wm/xtcJv8bXSb/G10m/xtdJv8bXSb/HF4n/xxeJ/8cXif/ + HF4n/xxfJ/8cXyf/HF8n/xxfJ/8cYCf/HGAn/xxgJ/8cYCf/HGEo/xxhKP8cYSj/HGEo/yJxL/8icS// + InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS// + InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS// + I3Q7/yN0O/8jdDv/I3Q7/yeHqv8nh6r/J4eq/yeHqv8tn+z/LZ/s/y2f7P8tn+z/MKr8/zCq/P8wqvz/ + MKr8/y6f2P8un9j/Lp/Y/y6f2P8hcmb/IXJm/yFyZv8hcmb/GFEi/xhRIv8YUSL/GFEi/xlSIv8ZUiL/ + GVIi/xlSIv8ZUyL/GVMi/xlTIv8ZUyL/GVQj/xlUI/8ZVCP/GVQj/yJ0Z/8idGf/InRn/yJ0Z/8un9j/ + Lp/Y/y6f2P8un9j/MKr8/zCq/P8wqvz/MKr8/y2f7P8tn+z/LZ/s/y2f7P8lhKP/JYSj/yWEo/8lhKP/ + HF4z/xxeM/8cXjP/HF4z/xtaJf8bWiX/G1ol/xtaJf8bWyb/G1sm/xtbJv8bWyb/HFwm/xxcJv8cXCb/ + HFwm/xxdJ/8cXSf/HF0n/xxdJ/8cXif/HF4n/xxeJ/8cXif/HV8n/x1fJ/8dXyf/HV8n/x1gKP8dYCj/ + HWAo/x1gKP8dYSj/HWEo/x1hKP8dYSj/InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS// + InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS// + InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8jdDv/I3Q7/yN0O/8jdDv/J4eq/yeHqv8nh6r/ + J4eq/y2f7P8tn+z/LZ/s/y2f7P8wqvz/MKr8/zCq/P8wqvz/Lp/Y/y6f2P8un9j/Lp/Y/yFyZv8hcmb/ + IXJm/yFyZv8YUSL/GFEi/xhRIv8YUSL/GVIi/xlSIv8ZUiL/GVIi/xlTIv8ZUyL/GVMi/xlTIv8ZVCP/ + GVQj/xlUI/8ZVCP/InRn/yJ0Z/8idGf/InRn/y6f2P8un9j/Lp/Y/y6f2P8wqvz/MKr8/zCq/P8wqvz/ + LZ/s/y2f7P8tn+z/LZ/s/yWEo/8lhKP/JYSj/yWEo/8cXjP/HF4z/xxeM/8cXjP/G1ol/xtaJf8bWiX/ + G1ol/xtbJv8bWyb/G1sm/xtbJv8cXCb/HFwm/xxcJv8cXCb/HF0n/xxdJ/8cXSf/HF0n/xxeJ/8cXif/ + HF4n/xxeJ/8dXyf/HV8n/x1fJ/8dXyf/HWAo/x1gKP8dYCj/HWAo/x1hKP8dYSj/HWEo/x1hKP8icS// + InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS// + InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS// + InEv/yN0O/8jdDv/I3Q7/yN0O/8nh6r/J4eq/yeHqv8nh6r/LZ/s/y2f7P8tn+z/LZ/s/zCq/P8wqvz/ + MKr8/zCq/P8un9j/Lp/Y/y6f2P8un9j/IXJm/yFyZv8hcmb/IXJm/xhRIv8YUSL/GFEi/xhRIv8ZUiL/ + GVIi/xlSIv8ZUiL/GVMi/xlTIv8ZUyL/GVMi/xlUI/8ZVCP/GVQj/xlUI/8idGf/InRn/yJ0Z/8idGf/ + Lp/Y/y6f2P8un9j/Lp/Y/zCq/P8wqvz/MKr8/zCq/P8tn+z/LZ/s/y2f7P8tn+z/JYSj/yWEo/8lhKP/ + JYSj/xxeM/8cXjP/HF4z/xxeM/8bWiX/G1ol/xtaJf8bWiX/G1sm/xtbJv8bWyb/G1sm/xxcJv8cXCb/ + HFwm/xxcJv8cXSf/HF0n/xxdJ/8cXSf/HF4n/xxeJ/8cXif/HF4n/x1fJ/8dXyf/HV8n/x1fJ/8dYCj/ + HWAo/x1gKP8dYCj/HWEo/x1hKP8dYSj/HWEo/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS// + InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS// + InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//I3Q7/yN0O/8jdDv/I3Q7/yeHqv8nh6r/ + J4eq/yeHqv8tn+z/LZ/s/y2f7P8tn+z/MKr8/zCq/P8wqvz/MKr8/y6f2P8un9j/Lp/Y/y6f2P8hcmb/ + IXJm/yFyZv8hcmb/GFEi/xhRIv8YUSL/GFEi/xlSIv8ZUiL/GVIi/xlSIv8ZUyL/GVMi/xlTIv8ZUyL/ + GVQj/xlUI/8ZVCP/GVQj/yJ0Z/8idGf/InRn/yJ0Z/8un9j/Lp/Y/y6f2P8un9j/MKr8/zCq/P8wqvz/ + MKr8/y2f7P8tn+z/LZ/s/y2f7P8lhKP/JYSj/yWEo/8lhKP/HF4z/xxeM/8cXjP/HF4z/xtaJf8bWiX/ + G1ol/xtaJf8bWyb/G1sm/xtbJv8bWyb/HFwm/xxcJv8cXCb/HFwm/xxdJ/8cXSf/HF0n/xxdJ/8cXif/ + HF4n/xxeJ/8cXif/HV8n/x1fJ/8dXyf/HV8n/x1gKP8dYCj/HWAo/x1gKP8dYSj/HWEo/x1hKP8dYSj/ + LHg6/yx4Ov8seDr/LHg6/yVzM/8lczP/JXMz/yVzM/8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/ + I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yR0PP8kdDz/ + JHQ8/yR0PP8pj73/KY+9/ymPvf8pj73/MKn5/zCp+f8wqfn/MKn5/zCo9P8wqPT/MKj0/zCo9P8mgYn/ + JoGJ/yaBif8mgYn/GVAl/xlQJf8ZUCX/GVAl/xhQIv8YUCL/GFAi/xhQIv8ZUCP/GVAj/xlQI/8ZUCP/ + GVIj/xlSI/8ZUiP/GVIj/xlTJP8ZUyT/GVMk/xlTJP8aVCT/GlQk/xpUJP8aVCT/GlQk/xpUJP8aVCT/ + GlQk/xtXKP8bVyj/G1co/xtXKP8nhY3/J4WN/yeFjf8nhY3/MKr2/zCq9v8wqvb/MKr2/zCp+f8wqfn/ + MKn5/zCp+f8pjr3/KY69/ymOvf8pjr3/HV8z/x1fM/8dXzP/HV8z/xxbJ/8cWyf/HFsn/xxbJ/8cXCf/ + HFwn/xxcJ/8cXCf/HF0o/xxdKP8cXSj/HF0o/x1dKP8dXSj/HV0o/x1dKP8dXyn/HV8p/x1fKf8dXyn/ + HWAp/x1gKf8dYCn/HWAp/x5hKv8eYSr/HmEq/x5hKv8seDr/LHg6/yx4Ov8seDr/JXMz/yVzM/8lczP/ + JXMz/yNyMf8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/ + I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/JHQ8/yR0PP8kdDz/JHQ8/ymPvf8pj73/KY+9/ymPvf8wqfn/ + MKn5/zCp+f8wqfn/MKj0/zCo9P8wqPT/MKj0/yaBif8mgYn/JoGJ/yaBif8ZUCX/GVAl/xlQJf8ZUCX/ + GFAi/xhQIv8YUCL/GFAi/xlQI/8ZUCP/GVAj/xlQI/8ZUiP/GVIj/xlSI/8ZUiP/GVMk/xlTJP8ZUyT/ + GVMk/xpUJP8aVCT/GlQk/xpUJP8aVCT/GlQk/xpUJP8aVCT/G1co/xtXKP8bVyj/G1co/yeFjf8nhY3/ + J4WN/yeFjf8wqvb/MKr2/zCq9v8wqvb/MKn5/zCp+f8wqfn/MKn5/ymOvf8pjr3/KY69/ymOvf8dXzP/ + HV8z/x1fM/8dXzP/HFsn/xxbJ/8cWyf/HFsn/xxcJ/8cXCf/HFwn/xxcJ/8cXSj/HF0o/xxdKP8cXSj/ + HV0o/x1dKP8dXSj/HV0o/x1fKf8dXyn/HV8p/x1fKf8dYCn/HWAp/x1gKf8dYCn/HmEq/x5hKv8eYSr/ + HmEq/yx4Ov8seDr/LHg6/yx4Ov8lczP/JXMz/yVzM/8lczP/I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/ + I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yNyMf8kdDz/ + JHQ8/yR0PP8kdDz/KY+9/ymPvf8pj73/KY+9/zCp+f8wqfn/MKn5/zCp+f8wqPT/MKj0/zCo9P8wqPT/ + JoGJ/yaBif8mgYn/JoGJ/xlQJf8ZUCX/GVAl/xlQJf8YUCL/GFAi/xhQIv8YUCL/GVAj/xlQI/8ZUCP/ + GVAj/xlSI/8ZUiP/GVIj/xlSI/8ZUyT/GVMk/xlTJP8ZUyT/GlQk/xpUJP8aVCT/GlQk/xpUJP8aVCT/ + GlQk/xpUJP8bVyj/G1co/xtXKP8bVyj/J4WN/yeFjf8nhY3/J4WN/zCq9v8wqvb/MKr2/zCq9v8wqfn/ + MKn5/zCp+f8wqfn/KY69/ymOvf8pjr3/KY69/x1fM/8dXzP/HV8z/x1fM/8cWyf/HFsn/xxbJ/8cWyf/ + HFwn/xxcJ/8cXCf/HFwn/xxdKP8cXSj/HF0o/xxdKP8dXSj/HV0o/x1dKP8dXSj/HV8p/x1fKf8dXyn/ + HV8p/x1gKf8dYCn/HWAp/x1gKf8eYSr/HmEq/x5hKv8eYSr/LHg6/yx4Ov8seDr/LHg6/yVzM/8lczP/ + JXMz/yVzM/8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/ + I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yR0PP8kdDz/JHQ8/yR0PP8pj73/KY+9/ymPvf8pj73/ + MKn5/zCp+f8wqfn/MKn5/zCo9P8wqPT/MKj0/zCo9P8mgYn/JoGJ/yaBif8mgYn/GVAl/xlQJf8ZUCX/ + GVAl/xhQIv8YUCL/GFAi/xhQIv8ZUCP/GVAj/xlQI/8ZUCP/GVIj/xlSI/8ZUiP/GVIj/xlTJP8ZUyT/ + GVMk/xlTJP8aVCT/GlQk/xpUJP8aVCT/GlQk/xpUJP8aVCT/GlQk/xtXKP8bVyj/G1co/xtXKP8nhY3/ + J4WN/yeFjf8nhY3/MKr2/zCq9v8wqvb/MKr2/zCp+f8wqfn/MKn5/zCp+f8pjr3/KY69/ymOvf8pjr3/ + HV8z/x1fM/8dXzP/HV8z/xxbJ/8cWyf/HFsn/xxbJ/8cXCf/HFwn/xxcJ/8cXCf/HF0o/xxdKP8cXSj/ + HF0o/x1dKP8dXSj/HV0o/x1dKP8dXyn/HV8p/x1fKf8dXyn/HWAp/x1gKf8dYCn/HWAp/x5hKv8eYSr/ + HmEq/x5hKv9SkV3/UpFd/1KRXf9SkV3/UpFd/1KRXf9SkV3/UpFd/0mLVf9Ji1X/SYtV/0mLVf8+hEr/ + PoRK/z6ESv8+hEr/M35A/zN+QP8zfkD/M35A/yh3Nv8odzb/KHc2/yh3Nv8kdjv/JHY7/yR2O/8kdjv/ + KpPA/yqTwP8qk8D/KpPA/zGr+/8xq/v/Mav7/zGr+/8unc3/Lp3N/y6dzf8unc3/HWBC/x1gQv8dYEL/ + HWBC/xhOIv8YTiL/GE4i/xhOIv8ZTyL/GU8i/xlPIv8ZTyL/GVAj/xlQI/8ZUCP/GVAj/xlRI/8ZUSP/ + GVEj/xlRI/8ZUiP/GVIj/xlSI/8ZUiP/GlMk/xpTJP8aUyT/GlMk/xpUJP8aVCT/GlQk/xpUJP8aVSX/ + GlUl/xpVJf8aVSX/G1Yl/xtWJf8bViX/G1Yl/xtXJf8bVyX/G1cl/xtXJf8gaEn/IGhJ/yBoSf8gaEn/ + LqDT/y6g0/8uoNP/LqDT/zGr+/8xq/v/Mav7/zGr+/8qk8D/KpPA/yqTwP8qk8D/HmAy/x5gMv8eYDL/ + HmAy/x1cKP8dXCj/HVwo/x1cKP8dXSj/HV0o/x1dKP8dXSj/HV4p/x1eKf8dXin/HV4p/x5fKf8eXyn/ + Hl8p/x5fKf8eYCr/HmAq/x5gKv8eYCr/HmEq/x5hKv8eYSr/HmEq/1KRXf9SkV3/UpFd/1KRXf9SkV3/ + UpFd/1KRXf9SkV3/SYtV/0mLVf9Ji1X/SYtV/z6ESv8+hEr/PoRK/z6ESv8zfkD/M35A/zN+QP8zfkD/ + KHc2/yh3Nv8odzb/KHc2/yR2O/8kdjv/JHY7/yR2O/8qk8D/KpPA/yqTwP8qk8D/Mav7/zGr+/8xq/v/ + Mav7/y6dzf8unc3/Lp3N/y6dzf8dYEL/HWBC/x1gQv8dYEL/GE4i/xhOIv8YTiL/GE4i/xlPIv8ZTyL/ + GU8i/xlPIv8ZUCP/GVAj/xlQI/8ZUCP/GVEj/xlRI/8ZUSP/GVEj/xlSI/8ZUiP/GVIj/xlSI/8aUyT/ + GlMk/xpTJP8aUyT/GlQk/xpUJP8aVCT/GlQk/xpVJf8aVSX/GlUl/xpVJf8bViX/G1Yl/xtWJf8bViX/ + G1cl/xtXJf8bVyX/G1cl/yBoSf8gaEn/IGhJ/yBoSf8uoNP/LqDT/y6g0/8uoNP/Mav7/zGr+/8xq/v/ + Mav7/yqTwP8qk8D/KpPA/yqTwP8eYDL/HmAy/x5gMv8eYDL/HVwo/x1cKP8dXCj/HVwo/x1dKP8dXSj/ + HV0o/x1dKP8dXin/HV4p/x1eKf8dXin/Hl8p/x5fKf8eXyn/Hl8p/x5gKv8eYCr/HmAq/x5gKv8eYSr/ + HmEq/x5hKv8eYSr/UpFd/1KRXf9SkV3/UpFd/1KRXf9SkV3/UpFd/1KRXf9Ji1X/SYtV/0mLVf9Ji1X/ + PoRK/z6ESv8+hEr/PoRK/zN+QP8zfkD/M35A/zN+QP8odzb/KHc2/yh3Nv8odzb/JHY7/yR2O/8kdjv/ + JHY7/yqTwP8qk8D/KpPA/yqTwP8xq/v/Mav7/zGr+/8xq/v/Lp3N/y6dzf8unc3/Lp3N/x1gQv8dYEL/ + HWBC/x1gQv8YTiL/GE4i/xhOIv8YTiL/GU8i/xlPIv8ZTyL/GU8i/xlQI/8ZUCP/GVAj/xlQI/8ZUSP/ + GVEj/xlRI/8ZUSP/GVIj/xlSI/8ZUiP/GVIj/xpTJP8aUyT/GlMk/xpTJP8aVCT/GlQk/xpUJP8aVCT/ + GlUl/xpVJf8aVSX/GlUl/xtWJf8bViX/G1Yl/xtWJf8bVyX/G1cl/xtXJf8bVyX/IGhJ/yBoSf8gaEn/ + IGhJ/y6g0/8uoNP/LqDT/y6g0/8xq/v/Mav7/zGr+/8xq/v/KpPA/yqTwP8qk8D/KpPA/x5gMv8eYDL/ + HmAy/x5gMv8dXCj/HVwo/x1cKP8dXCj/HV0o/x1dKP8dXSj/HV0o/x1eKf8dXin/HV4p/x1eKf8eXyn/ + Hl8p/x5fKf8eXyn/HmAq/x5gKv8eYCr/HmAq/x5hKv8eYSr/HmEq/x5hKv9SkV3/UpFd/1KRXf9SkV3/ + UpFd/1KRXf9SkV3/UpFd/0mLVf9Ji1X/SYtV/0mLVf8+hEr/PoRK/z6ESv8+hEr/M35A/zN+QP8zfkD/ + M35A/yh3Nv8odzb/KHc2/yh3Nv8kdjv/JHY7/yR2O/8kdjv/KpPA/yqTwP8qk8D/KpPA/zGr+/8xq/v/ + Mav7/zGr+/8unc3/Lp3N/y6dzf8unc3/HWBC/x1gQv8dYEL/HWBC/xhOIv8YTiL/GE4i/xhOIv8ZTyL/ + GU8i/xlPIv8ZTyL/GVAj/xlQI/8ZUCP/GVAj/xlRI/8ZUSP/GVEj/xlRI/8ZUiP/GVIj/xlSI/8ZUiP/ + GlMk/xpTJP8aUyT/GlMk/xpUJP8aVCT/GlQk/xpUJP8aVSX/GlUl/xpVJf8aVSX/G1Yl/xtWJf8bViX/ + G1Yl/xtXJf8bVyX/G1cl/xtXJf8gaEn/IGhJ/yBoSf8gaEn/LqDT/y6g0/8uoNP/LqDT/zGr+/8xq/v/ + Mav7/zGr+/8qk8D/KpPA/yqTwP8qk8D/HmAy/x5gMv8eYDL/HmAy/x1cKP8dXCj/HVwo/x1cKP8dXSj/ + HV0o/x1dKP8dXSj/HV4p/x1eKf8dXin/HV4p/x5fKf8eXyn/Hl8p/x5fKf8eYCr/HmAq/x5gKv8eYCr/ + HmEq/x5hKv8eYSr/HmEq/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/ + VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1Smuf9Uprn/ + VKa5/1Smuf9Jtvv/Sbb7/0m2+/9Jtvv/NZy9/zWcvf81nL3/NZy9/1l9Xf9ZfV3/WX1d/1l9Xf9ig2L/ + YoNi/2KDYv9ig2L/Y4Ni/2ODYv9jg2L/Y4Ni/2OEYv9jhGL/Y4Ri/2OEYv9jhWL/Y4Vi/2OFYv9jhWL/ + Y4Vi/2OFYv9jhWL/Y4Vi/2OGY/9jhmP/Y4Zj/2OGY/9jh2P/Y4dj/2OHY/9jh2P/ZIdk/2SHZP9kh2T/ + ZIdk/2SIZP9kiGT/ZIhk/2SIZP9kiWT/ZIlk/2SJZP9kiWT/ZIlk/2SJZP9kiWT/ZIlk/2WKZP9limT/ + ZYpk/2WKZP9ahWL/WoVi/1qFYv9ahWL/MJvC/zCbwv8wm8L/MJvC/zKt+/8yrfv/Mq37/zKt+/8qkKn/ + KpCp/yqQqf8qkKn/HVwo/x1cKP8dXCj/HVwo/x1dKf8dXSn/HV0p/x1dKf8eXin/Hl4p/x5eKf8eXin/ + Hl8p/x5fKf8eXyn/Hl8p/x5gKv8eYCr/HmAq/x5gKv8fYiv/H2Ir/x9iK/8fYiv/VpRh/1aUYf9WlGH/ + VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/ + VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VKa5/1Smuf9Uprn/VKa5/0m2+/9Jtvv/Sbb7/0m2+/81nL3/ + NZy9/zWcvf81nL3/WX1d/1l9Xf9ZfV3/WX1d/2KDYv9ig2L/YoNi/2KDYv9jg2L/Y4Ni/2ODYv9jg2L/ + Y4Ri/2OEYv9jhGL/Y4Ri/2OFYv9jhWL/Y4Vi/2OFYv9jhWL/Y4Vi/2OFYv9jhWL/Y4Zj/2OGY/9jhmP/ + Y4Zj/2OHY/9jh2P/Y4dj/2OHY/9kh2T/ZIdk/2SHZP9kh2T/ZIhk/2SIZP9kiGT/ZIhk/2SJZP9kiWT/ + ZIlk/2SJZP9kiWT/ZIlk/2SJZP9kiWT/ZYpk/2WKZP9limT/ZYpk/1qFYv9ahWL/WoVi/1qFYv8wm8L/ + MJvC/zCbwv8wm8L/Mq37/zKt+/8yrfv/Mq37/yqQqf8qkKn/KpCp/yqQqf8dXCj/HVwo/x1cKP8dXCj/ + HV0p/x1dKf8dXSn/HV0p/x5eKf8eXin/Hl4p/x5eKf8eXyn/Hl8p/x5fKf8eXyn/HmAq/x5gKv8eYCr/ + HmAq/x9iK/8fYiv/H2Ir/x9iK/9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/ + VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9Uprn/ + VKa5/1Smuf9Uprn/Sbb7/0m2+/9Jtvv/Sbb7/zWcvf81nL3/NZy9/zWcvf9ZfV3/WX1d/1l9Xf9ZfV3/ + YoNi/2KDYv9ig2L/YoNi/2ODYv9jg2L/Y4Ni/2ODYv9jhGL/Y4Ri/2OEYv9jhGL/Y4Vi/2OFYv9jhWL/ + Y4Vi/2OFYv9jhWL/Y4Vi/2OFYv9jhmP/Y4Zj/2OGY/9jhmP/Y4dj/2OHY/9jh2P/Y4dj/2SHZP9kh2T/ + ZIdk/2SHZP9kiGT/ZIhk/2SIZP9kiGT/ZIlk/2SJZP9kiWT/ZIlk/2SJZP9kiWT/ZIlk/2SJZP9limT/ + ZYpk/2WKZP9limT/WoVi/1qFYv9ahWL/WoVi/zCbwv8wm8L/MJvC/zCbwv8yrfv/Mq37/zKt+/8yrfv/ + KpCp/yqQqf8qkKn/KpCp/x1cKP8dXCj/HVwo/x1cKP8dXSn/HV0p/x1dKf8dXSn/Hl4p/x5eKf8eXin/ + Hl4p/x5fKf8eXyn/Hl8p/x5fKf8eYCr/HmAq/x5gKv8eYCr/H2Ir/x9iK/8fYiv/H2Ir/1aUYf9WlGH/ + VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/ + VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1Smuf9Uprn/VKa5/1Smuf9Jtvv/Sbb7/0m2+/9Jtvv/ + NZy9/zWcvf81nL3/NZy9/1l9Xf9ZfV3/WX1d/1l9Xf9ig2L/YoNi/2KDYv9ig2L/Y4Ni/2ODYv9jg2L/ + Y4Ni/2OEYv9jhGL/Y4Ri/2OEYv9jhWL/Y4Vi/2OFYv9jhWL/Y4Vi/2OFYv9jhWL/Y4Vi/2OGY/9jhmP/ + Y4Zj/2OGY/9jh2P/Y4dj/2OHY/9jh2P/ZIdk/2SHZP9kh2T/ZIdk/2SIZP9kiGT/ZIhk/2SIZP9kiWT/ + ZIlk/2SJZP9kiWT/ZIlk/2SJZP9kiWT/ZIlk/2WKZP9limT/ZYpk/2WKZP9ahWL/WoVi/1qFYv9ahWL/ + MJvC/zCbwv8wm8L/MJvC/zKt+/8yrfv/Mq37/zKt+/8qkKn/KpCp/yqQqf8qkKn/HVwo/x1cKP8dXCj/ + HVwo/x1dKf8dXSn/HV0p/x1dKf8eXin/Hl4p/x5eKf8eXin/Hl8p/x5fKf8eXyn/Hl8p/x5gKv8eYCr/ + HmAq/x5gKv8fYiv/H2Ir/x9iK/8fYiv/WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/ + WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/WJdl/1iXZf9bn4j/W5+I/1ufiP9bn4j/ + YsD6/2LA+v9iwPr/YsD6/16xzf9esc3/XrHN/16xzf/O1Mb/ztTG/87Uxv/O1Mb/19nN/9fZzf/X2c3/ + 19nN/8TKuv/Eyrr/xMq6/8TKuv+/xrT/v8a0/7/GtP+/xrT/v8az/7/Gs/+/xrP/v8az/7/Gs/+/xrP/ + v8az/7/Gs/+/xrP/v8az/7/Gs/+/xrP/v8e0/7/HtP+/x7T/v8e0/7/HtP+/x7T/v8e0/7/HtP+/x7T/ + v8e0/7/HtP+/x7T/v8e0/7/HtP+/x7T/v8e0/7/ItP+/yLT/v8i0/7/ItP+/yLT/v8i0/7/ItP+/yLT/ + v8i0/7/ItP+/yLT/v8i0/83Swv/N0sL/zdLC/83Swv++ybb/vsm2/77Jtv++ybb/Lp3D/y6dw/8uncP/ + Lp3D/zKt+v8yrfr/Mq36/zKt+v8jdV7/I3Ve/yN1Xv8jdV7/HV4q/x1eKv8dXir/HV4q/x1fKv8dXyr/ + HV8q/x1fKv8eYCv/HmAr/x5gK/8eYCv/HmEr/x5hK/8eYSv/HmEr/x5iLP8eYiz/HmIs/x5iLP9Yl2X/ + WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/ + WJdl/1iXZf9Yl2X/WJdl/1ufiP9bn4j/W5+I/1ufiP9iwPr/YsD6/2LA+v9iwPr/XrHN/16xzf9esc3/ + XrHN/87Uxv/O1Mb/ztTG/87Uxv/X2c3/19nN/9fZzf/X2c3/xMq6/8TKuv/Eyrr/xMq6/7/GtP+/xrT/ + v8a0/7/GtP+/xrP/v8az/7/Gs/+/xrP/v8az/7/Gs/+/xrP/v8az/7/Gs/+/xrP/v8az/7/Gs/+/x7T/ + v8e0/7/HtP+/x7T/v8e0/7/HtP+/x7T/v8e0/7/HtP+/x7T/v8e0/7/HtP+/x7T/v8e0/7/HtP+/x7T/ + v8i0/7/ItP+/yLT/v8i0/7/ItP+/yLT/v8i0/7/ItP+/yLT/v8i0/7/ItP+/yLT/zdLC/83Swv/N0sL/ + zdLC/77Jtv++ybb/vsm2/77Jtv8uncP/Lp3D/y6dw/8uncP/Mq36/zKt+v8yrfr/Mq36/yN1Xv8jdV7/ + I3Ve/yN1Xv8dXir/HV4q/x1eKv8dXir/HV8q/x1fKv8dXyr/HV8q/x5gK/8eYCv/HmAr/x5gK/8eYSv/ + HmEr/x5hK/8eYSv/HmIs/x5iLP8eYiz/HmIs/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/ + WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/W5+I/1ufiP9bn4j/ + W5+I/2LA+v9iwPr/YsD6/2LA+v9esc3/XrHN/16xzf9esc3/ztTG/87Uxv/O1Mb/ztTG/9fZzf/X2c3/ + 19nN/9fZzf/Eyrr/xMq6/8TKuv/Eyrr/v8a0/7/GtP+/xrT/v8a0/7/Gs/+/xrP/v8az/7/Gs/+/xrP/ + v8az/7/Gs/+/xrP/v8az/7/Gs/+/xrP/v8az/7/HtP+/x7T/v8e0/7/HtP+/x7T/v8e0/7/HtP+/x7T/ + v8e0/7/HtP+/x7T/v8e0/7/HtP+/x7T/v8e0/7/HtP+/yLT/v8i0/7/ItP+/yLT/v8i0/7/ItP+/yLT/ + v8i0/7/ItP+/yLT/v8i0/7/ItP/N0sL/zdLC/83Swv/N0sL/vsm2/77Jtv++ybb/vsm2/y6dw/8uncP/ + Lp3D/y6dw/8yrfr/Mq36/zKt+v8yrfr/I3Ve/yN1Xv8jdV7/I3Ve/x1eKv8dXir/HV4q/x1eKv8dXyr/ + HV8q/x1fKv8dXyr/HmAr/x5gK/8eYCv/HmAr/x5hK/8eYSv/HmEr/x5hK/8eYiz/HmIs/x5iLP8eYiz/ + WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/ + WJdl/1iXZf9Yl2X/WJdl/1iXZf9bn4j/W5+I/1ufiP9bn4j/YsD6/2LA+v9iwPr/YsD6/16xzf9esc3/ + XrHN/16xzf/O1Mb/ztTG/87Uxv/O1Mb/19nN/9fZzf/X2c3/19nN/8TKuv/Eyrr/xMq6/8TKuv+/xrT/ + v8a0/7/GtP+/xrT/v8az/7/Gs/+/xrP/v8az/7/Gs/+/xrP/v8az/7/Gs/+/xrP/v8az/7/Gs/+/xrP/ + v8e0/7/HtP+/x7T/v8e0/7/HtP+/x7T/v8e0/7/HtP+/x7T/v8e0/7/HtP+/x7T/v8e0/7/HtP+/x7T/ + v8e0/7/ItP+/yLT/v8i0/7/ItP+/yLT/v8i0/7/ItP+/yLT/v8i0/7/ItP+/yLT/v8i0/83Swv/N0sL/ + zdLC/83Swv++ybb/vsm2/77Jtv++ybb/Lp3D/y6dw/8uncP/Lp3D/zKt+v8yrfr/Mq36/zKt+v8jdV7/ + I3Ve/yN1Xv8jdV7/HV4q/x1eKv8dXir/HV4q/x1fKv8dXyr/HV8q/x1fKv8eYCv/HmAr/x5gK/8eYCv/ + HmEr/x5hK/8eYSv/HmEr/x5iLP8eYiz/HmIs/x5iLP9cmmj/XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/ + XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/XJpo/2W73/9lu9// + Zbvf/2W73/9lv+3/Zb/t/2W/7f9lv+3/VIBm/1SAZv9UgGb/VIBm//v07f/79O3/+/Tt//v07f9fgmT/ + X4Jk/1+CZP9fgmT/Unpa/1J6Wv9Selr/Unpa/1B4WP9QeFj/UHhY/1B4WP88akX/PGpF/zxqRf88akX/ + IFUr/yBVK/8gVSv/IFUr/xpRJP8aUST/GlEk/xpRJP8nWzH/J1sx/ydbMf8nWzH/J1wx/ydcMf8nXDH/ + J1wx/xtUJv8bVCb/G1Qm/xtUJv8bVSb/G1Um/xtVJv8bVSb/G1Yn/xtWJ/8bVif/G1Yn/xxXJ/8cVyf/ + HFcn/xxXJ/8cWCj/HFgo/xxYKP8cWCj/LGQ1/yxkNf8sZDX/LGQ1//nw5//58Of/+fDn//nw5/8gZT7/ + IGU+/yBlPv8gZT7/Mqrr/zKq6/8yquv/Mqrr/zGk1/8xpNf/MaTX/zGk1/8eXir/Hl4q/x5eKv8eXir/ + Hl8r/x5fK/8eXyv/Hl8r/x5gK/8eYCv/HmAr/x5gK/8fYCv/H2Ar/x9gK/8fYCv/H2Is/x9iLP8fYiz/ + H2Is/1yaaP9cmmj/XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/ + XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/Zbvf/2W73/9lu9//Zbvf/2W/7f9lv+3/Zb/t/2W/7f9UgGb/ + VIBm/1SAZv9UgGb/+/Tt//v07f/79O3/+/Tt/1+CZP9fgmT/X4Jk/1+CZP9Selr/Unpa/1J6Wv9Selr/ + UHhY/1B4WP9QeFj/UHhY/zxqRf88akX/PGpF/zxqRf8gVSv/IFUr/yBVK/8gVSv/GlEk/xpRJP8aUST/ + GlEk/ydbMf8nWzH/J1sx/ydbMf8nXDH/J1wx/ydcMf8nXDH/G1Qm/xtUJv8bVCb/G1Qm/xtVJv8bVSb/ + G1Um/xtVJv8bVif/G1Yn/xtWJ/8bVif/HFcn/xxXJ/8cVyf/HFcn/xxYKP8cWCj/HFgo/xxYKP8sZDX/ + LGQ1/yxkNf8sZDX/+fDn//nw5//58Of/+fDn/yBlPv8gZT7/IGU+/yBlPv8yquv/Mqrr/zKq6/8yquv/ + MaTX/zGk1/8xpNf/MaTX/x5eKv8eXir/Hl4q/x5eKv8eXyv/Hl8r/x5fK/8eXyv/HmAr/x5gK/8eYCv/ + HmAr/x9gK/8fYCv/H2Ar/x9gK/8fYiz/H2Is/x9iLP8fYiz/XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/ + XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/XJpo/1yaaP9lu9// + Zbvf/2W73/9lu9//Zb/t/2W/7f9lv+3/Zb/t/1SAZv9UgGb/VIBm/1SAZv/79O3/+/Tt//v07f/79O3/ + X4Jk/1+CZP9fgmT/X4Jk/1J6Wv9Selr/Unpa/1J6Wv9QeFj/UHhY/1B4WP9QeFj/PGpF/zxqRf88akX/ + PGpF/yBVK/8gVSv/IFUr/yBVK/8aUST/GlEk/xpRJP8aUST/J1sx/ydbMf8nWzH/J1sx/ydcMf8nXDH/ + J1wx/ydcMf8bVCb/G1Qm/xtUJv8bVCb/G1Um/xtVJv8bVSb/G1Um/xtWJ/8bVif/G1Yn/xtWJ/8cVyf/ + HFcn/xxXJ/8cVyf/HFgo/xxYKP8cWCj/HFgo/yxkNf8sZDX/LGQ1/yxkNf/58Of/+fDn//nw5//58Of/ + IGU+/yBlPv8gZT7/IGU+/zKq6/8yquv/Mqrr/zKq6/8xpNf/MaTX/zGk1/8xpNf/Hl4q/x5eKv8eXir/ + Hl4q/x5fK/8eXyv/Hl8r/x5fK/8eYCv/HmAr/x5gK/8eYCv/H2Ar/x9gK/8fYCv/H2Ar/x9iLP8fYiz/ + H2Is/x9iLP9cmmj/XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/ + XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/XJpo/2W73/9lu9//Zbvf/2W73/9lv+3/Zb/t/2W/7f9lv+3/ + VIBm/1SAZv9UgGb/VIBm//v07f/79O3/+/Tt//v07f9fgmT/X4Jk/1+CZP9fgmT/Unpa/1J6Wv9Selr/ + Unpa/1B4WP9QeFj/UHhY/1B4WP88akX/PGpF/zxqRf88akX/IFUr/yBVK/8gVSv/IFUr/xpRJP8aUST/ + GlEk/xpRJP8nWzH/J1sx/ydbMf8nWzH/J1wx/ydcMf8nXDH/J1wx/xtUJv8bVCb/G1Qm/xtUJv8bVSb/ + G1Um/xtVJv8bVSb/G1Yn/xtWJ/8bVif/G1Yn/xxXJ/8cVyf/HFcn/xxXJ/8cWCj/HFgo/xxYKP8cWCj/ + LGQ1/yxkNf8sZDX/LGQ1//nw5//58Of/+fDn//nw5/8gZT7/IGU+/yBlPv8gZT7/Mqrr/zKq6/8yquv/ + Mqrr/zGk1/8xpNf/MaTX/zGk1/8eXir/Hl4q/x5eKv8eXir/Hl8r/x5fK/8eXyv/Hl8r/x5gK/8eYCv/ + HmAr/x5gK/8fYCv/H2Ar/x9gK/8fYCv/H2Is/x9iLP8fYiz/H2Is/2CdbP9gnWz/YJ1s/2CdbP9gnWz/ + YJ1s/2CdbP9gnWz/YJ1s/2CdbP9gnWz/YJ1s/2CdbP9gnWz/YJ1s/2CdbP9ho4P/YaOD/2Gjg/9ho4P/ + acX8/2nF/P9pxfz/acX8/2Cgof9goKH/YKCh/2Cgof9Velz/VXpc/1V6XP9Velz/+/Xw//v18P/79fD/ + +/Xw/1+DZv9fg2b/X4Nm/1+DZv9VfV7/VX1e/1V9Xv9VfV7/VX1e/1V9Xv9VfV7/VX1e/1V9Xv9VfV7/ + VX1e/1V9Xv9UfV3/VH1d/1R9Xf9UfV3/PGtF/zxrRf88a0X/PGtF/5Cnjv+Qp47/kKeO/5Cnjv+Ppoz/ + j6aM/4+mjP+Ppoz/G1Qn/xtUJ/8bVCf/G1Qn/xtVJ/8bVSf/G1Un/xtVJ/8cVij/HFYo/xxWKP8cVij/ + HFgo/xxYKP8cWCj/HFgo/xxZKf8cWSn/HFkp/xxZKf8rYjX/K2I1/ytiNf8rYjX/+vLq//ry6v/68ur/ + +vLq/x1bKv8dWyr/HVsq/x1bKv8piIf/KYiH/ymIh/8piIf/M7D7/zOw+/8zsPv/M7D7/yNwUP8jcFD/ + I3BQ/yNwUP8eXyz/Hl8s/x5fLP8eXyz/H2As/x9gLP8fYCz/H2As/x9hLf8fYS3/H2Et/x9hLf8gYy3/ + IGMt/yBjLf8gYy3/YJ1s/2CdbP9gnWz/YJ1s/2CdbP9gnWz/YJ1s/2CdbP9gnWz/YJ1s/2CdbP9gnWz/ + YJ1s/2CdbP9gnWz/YJ1s/2Gjg/9ho4P/YaOD/2Gjg/9pxfz/acX8/2nF/P9pxfz/YKCh/2Cgof9goKH/ + YKCh/1V6XP9Velz/VXpc/1V6XP/79fD/+/Xw//v18P/79fD/X4Nm/1+DZv9fg2b/X4Nm/1V9Xv9VfV7/ + VX1e/1V9Xv9VfV7/VX1e/1V9Xv9VfV7/VX1e/1V9Xv9VfV7/VX1e/1R9Xf9UfV3/VH1d/1R9Xf88a0X/ + PGtF/zxrRf88a0X/kKeO/5Cnjv+Qp47/kKeO/4+mjP+Ppoz/j6aM/4+mjP8bVCf/G1Qn/xtUJ/8bVCf/ + G1Un/xtVJ/8bVSf/G1Un/xxWKP8cVij/HFYo/xxWKP8cWCj/HFgo/xxYKP8cWCj/HFkp/xxZKf8cWSn/ + HFkp/ytiNf8rYjX/K2I1/ytiNf/68ur/+vLq//ry6v/68ur/HVsq/x1bKv8dWyr/HVsq/ymIh/8piIf/ + KYiH/ymIh/8zsPv/M7D7/zOw+/8zsPv/I3BQ/yNwUP8jcFD/I3BQ/x5fLP8eXyz/Hl8s/x5fLP8fYCz/ + H2As/x9gLP8fYCz/H2Et/x9hLf8fYS3/H2Et/yBjLf8gYy3/IGMt/yBjLf9gnWz/YJ1s/2CdbP9gnWz/ + YJ1s/2CdbP9gnWz/YJ1s/2CdbP9gnWz/YJ1s/2CdbP9gnWz/YJ1s/2CdbP9gnWz/YaOD/2Gjg/9ho4P/ + YaOD/2nF/P9pxfz/acX8/2nF/P9goKH/YKCh/2Cgof9goKH/VXpc/1V6XP9Velz/VXpc//v18P/79fD/ + +/Xw//v18P9fg2b/X4Nm/1+DZv9fg2b/VX1e/1V9Xv9VfV7/VX1e/1V9Xv9VfV7/VX1e/1V9Xv9VfV7/ + VX1e/1V9Xv9VfV7/VH1d/1R9Xf9UfV3/VH1d/zxrRf88a0X/PGtF/zxrRf+Qp47/kKeO/5Cnjv+Qp47/ + j6aM/4+mjP+Ppoz/j6aM/xtUJ/8bVCf/G1Qn/xtUJ/8bVSf/G1Un/xtVJ/8bVSf/HFYo/xxWKP8cVij/ + HFYo/xxYKP8cWCj/HFgo/xxYKP8cWSn/HFkp/xxZKf8cWSn/K2I1/ytiNf8rYjX/K2I1//ry6v/68ur/ + +vLq//ry6v8dWyr/HVsq/x1bKv8dWyr/KYiH/ymIh/8piIf/KYiH/zOw+/8zsPv/M7D7/zOw+/8jcFD/ + I3BQ/yNwUP8jcFD/Hl8s/x5fLP8eXyz/Hl8s/x9gLP8fYCz/H2As/x9gLP8fYS3/H2Et/x9hLf8fYS3/ + IGMt/yBjLf8gYy3/IGMt/2CdbP9gnWz/YJ1s/2CdbP9gnWz/YJ1s/2CdbP9gnWz/YJ1s/2CdbP9gnWz/ + YJ1s/2CdbP9gnWz/YJ1s/2CdbP9ho4P/YaOD/2Gjg/9ho4P/acX8/2nF/P9pxfz/acX8/2Cgof9goKH/ + YKCh/2Cgof9Velz/VXpc/1V6XP9Velz/+/Xw//v18P/79fD/+/Xw/1+DZv9fg2b/X4Nm/1+DZv9VfV7/ + VX1e/1V9Xv9VfV7/VX1e/1V9Xv9VfV7/VX1e/1V9Xv9VfV7/VX1e/1V9Xv9UfV3/VH1d/1R9Xf9UfV3/ + PGtF/zxrRf88a0X/PGtF/5Cnjv+Qp47/kKeO/5Cnjv+Ppoz/j6aM/4+mjP+Ppoz/G1Qn/xtUJ/8bVCf/ + G1Qn/xtVJ/8bVSf/G1Un/xtVJ/8cVij/HFYo/xxWKP8cVij/HFgo/xxYKP8cWCj/HFgo/xxZKf8cWSn/ + HFkp/xxZKf8rYjX/K2I1/ytiNf8rYjX/+vLq//ry6v/68ur/+vLq/x1bKv8dWyr/HVsq/x1bKv8piIf/ + KYiH/ymIh/8piIf/M7D7/zOw+/8zsPv/M7D7/yNwUP8jcFD/I3BQ/yNwUP8eXyz/Hl8s/x5fLP8eXyz/ + H2As/x9gLP8fYCz/H2As/x9hLf8fYS3/H2Et/x9hLf8gYy3/IGMt/yBjLf8gYy3/Y59v/2Ofb/9jn2// + Y59v/2Ofb/9jn2//Y59v/2Ofb/9jn2//Y59v/2Ofb/9jn2//Y59v/2Ofb/9jn2//Y59v/2eztP9ns7T/ + Z7O0/2eztP9rxff/a8X3/2vF9/9rxff/WYFq/1mBav9ZgWr/WYFq/1d8X/9XfF//V3xf/1d8X//89vH/ + /Pbx//z28f/89vH/YoRp/2KEaf9ihGn/YoRp/1h+YP9YfmD/WH5g/1h+YP9Yf2D/WH9g/1h/YP9Yf2D/ + WX9h/1l/Yf9Zf2H/WX9h/1mAYf9ZgGH/WYBh/1mAYf9ZgWL/WYFi/1mBYv9ZgWL/r7+t/6+/rf+vv63/ + r7+t/6G0nv+htJ7/obSe/6G0nv8eVir/HlYq/x5WKv8eVir/HFUn/xxVJ/8cVSf/HFUn/xxWKP8cVij/ + HFYo/xxWKP8cVyj/HFco/xxXKP8cVyj/HVgp/x1YKf8dWCn/HVgp/ytiNf8rYjX/K2I1/ytiNf/78+z/ + +/Ps//vz7P/78+z/Hlsq/x5bKv8eWyr/Hlsq/yBmPf8gZj3/IGY9/yBmPf80sPf/NLD3/zSw9/80sPf/ + K5CX/yuQl/8rkJf/K5CX/x9fLP8fXyz/H18s/x9fLP8fYCz/H2As/x9gLP8fYCz/IGEt/yBhLf8gYS3/ + IGEt/yBiLv8gYi7/IGIu/yBiLv9jn2//Y59v/2Ofb/9jn2//Y59v/2Ofb/9jn2//Y59v/2Ofb/9jn2// + Y59v/2Ofb/9jn2//Y59v/2Ofb/9jn2//Z7O0/2eztP9ns7T/Z7O0/2vF9/9rxff/a8X3/2vF9/9ZgWr/ + WYFq/1mBav9ZgWr/V3xf/1d8X/9XfF//V3xf//z28f/89vH//Pbx//z28f9ihGn/YoRp/2KEaf9ihGn/ + WH5g/1h+YP9YfmD/WH5g/1h/YP9Yf2D/WH9g/1h/YP9Zf2H/WX9h/1l/Yf9Zf2H/WYBh/1mAYf9ZgGH/ + WYBh/1mBYv9ZgWL/WYFi/1mBYv+vv63/r7+t/6+/rf+vv63/obSe/6G0nv+htJ7/obSe/x5WKv8eVir/ + HlYq/x5WKv8cVSf/HFUn/xxVJ/8cVSf/HFYo/xxWKP8cVij/HFYo/xxXKP8cVyj/HFco/xxXKP8dWCn/ + HVgp/x1YKf8dWCn/K2I1/ytiNf8rYjX/K2I1//vz7P/78+z/+/Ps//vz7P8eWyr/Hlsq/x5bKv8eWyr/ + IGY9/yBmPf8gZj3/IGY9/zSw9/80sPf/NLD3/zSw9/8rkJf/K5CX/yuQl/8rkJf/H18s/x9fLP8fXyz/ + H18s/x9gLP8fYCz/H2As/x9gLP8gYS3/IGEt/yBhLf8gYS3/IGIu/yBiLv8gYi7/IGIu/2Ofb/9jn2// + Y59v/2Ofb/9jn2//Y59v/2Ofb/9jn2//Y59v/2Ofb/9jn2//Y59v/2Ofb/9jn2//Y59v/2Ofb/9ns7T/ + Z7O0/2eztP9ns7T/a8X3/2vF9/9rxff/a8X3/1mBav9ZgWr/WYFq/1mBav9XfF//V3xf/1d8X/9XfF// + /Pbx//z28f/89vH//Pbx/2KEaf9ihGn/YoRp/2KEaf9YfmD/WH5g/1h+YP9YfmD/WH9g/1h/YP9Yf2D/ + WH9g/1l/Yf9Zf2H/WX9h/1l/Yf9ZgGH/WYBh/1mAYf9ZgGH/WYFi/1mBYv9ZgWL/WYFi/6+/rf+vv63/ + r7+t/6+/rf+htJ7/obSe/6G0nv+htJ7/HlYq/x5WKv8eVir/HlYq/xxVJ/8cVSf/HFUn/xxVJ/8cVij/ + HFYo/xxWKP8cVij/HFco/xxXKP8cVyj/HFco/x1YKf8dWCn/HVgp/x1YKf8rYjX/K2I1/ytiNf8rYjX/ + +/Ps//vz7P/78+z/+/Ps/x5bKv8eWyr/Hlsq/x5bKv8gZj3/IGY9/yBmPf8gZj3/NLD3/zSw9/80sPf/ + NLD3/yuQl/8rkJf/K5CX/yuQl/8fXyz/H18s/x9fLP8fXyz/H2As/x9gLP8fYCz/H2As/yBhLf8gYS3/ + IGEt/yBhLf8gYi7/IGIu/yBiLv8gYi7/Y59v/2Ofb/9jn2//Y59v/2Ofb/9jn2//Y59v/2Ofb/9jn2// + Y59v/2Ofb/9jn2//Y59v/2Ofb/9jn2//Y59v/2eztP9ns7T/Z7O0/2eztP9rxff/a8X3/2vF9/9rxff/ + WYFq/1mBav9ZgWr/WYFq/1d8X/9XfF//V3xf/1d8X//89vH//Pbx//z28f/89vH/YoRp/2KEaf9ihGn/ + YoRp/1h+YP9YfmD/WH5g/1h+YP9Yf2D/WH9g/1h/YP9Yf2D/WX9h/1l/Yf9Zf2H/WX9h/1mAYf9ZgGH/ + WYBh/1mAYf9ZgWL/WYFi/1mBYv9ZgWL/r7+t/6+/rf+vv63/r7+t/6G0nv+htJ7/obSe/6G0nv8eVir/ + HlYq/x5WKv8eVir/HFUn/xxVJ/8cVSf/HFUn/xxWKP8cVij/HFYo/xxWKP8cVyj/HFco/xxXKP8cVyj/ + HVgp/x1YKf8dWCn/HVgp/ytiNf8rYjX/K2I1/ytiNf/78+z/+/Ps//vz7P/78+z/Hlsq/x5bKv8eWyr/ + Hlsq/yBmPf8gZj3/IGY9/yBmPf80sPf/NLD3/zSw9/80sPf/K5CX/yuQl/8rkJf/K5CX/x9fLP8fXyz/ + H18s/x9fLP8fYCz/H2As/x9gLP8fYCz/IGEt/yBhLf8gYS3/IGEt/yBiLv8gYi7/IGIu/yBiLv9no3P/ + Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9no3P/ + bb7X/22+1/9tvtf/bb7X/2y81/9svNf/bLzX/2y81/9bfmL/W35i/1t+Yv9bfmL/W39j/1t/Y/9bf2P/ + W39j//z48//8+PP//Pjz//z48/9mh2z/Zods/2aHbP9mh2z/XIFk/1yBZP9cgWT/XIFk/1yBZP9cgWT/ + XIFk/1yBZP9miG3/Zoht/2aIbf9miG3/sMCv/7DAr/+wwK//sMCv/7LCsf+ywrH/ssKx/7LCsf/Z3tT/ + 2d7U/9ne1P/Z3tT/2d7U/9ne1P/Z3tT/2d7U/6/Arf+vwK3/r8Ct/6/Arf+bspr/m7Ka/5uymv+bspr/ + KV80/ylfNP8pXzT/KV80/x1XKP8dVyj/HVco/x1XKP8dWCn/HVgp/x1YKf8dWCn/K2M2/ytjNv8rYzb/ + K2M2//v17v/79e7/+/Xu//v17v8eXCv/Hlwr/x5cK/8eXCv/Hl0r/x5dK/8eXSv/Hl0r/zGjy/8xo8v/ + MaPL/zGjy/8wosb/MKLG/zCixv8wosb/H2As/x9gLP8fYCz/H2As/yBhLf8gYS3/IGEt/yBhLf8gYi3/ + IGIt/yBiLf8gYi3/IGMu/yBjLv8gYy7/IGMu/2ejc/9no3P/Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9no3P/ + Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9tvtf/bb7X/22+1/9tvtf/bLzX/2y81/9svNf/ + bLzX/1t+Yv9bfmL/W35i/1t+Yv9bf2P/W39j/1t/Y/9bf2P//Pjz//z48//8+PP//Pjz/2aHbP9mh2z/ + Zods/2aHbP9cgWT/XIFk/1yBZP9cgWT/XIFk/1yBZP9cgWT/XIFk/2aIbf9miG3/Zoht/2aIbf+wwK// + sMCv/7DAr/+wwK//ssKx/7LCsf+ywrH/ssKx/9ne1P/Z3tT/2d7U/9ne1P/Z3tT/2d7U/9ne1P/Z3tT/ + r8Ct/6/Arf+vwK3/r8Ct/5uymv+bspr/m7Ka/5uymv8pXzT/KV80/ylfNP8pXzT/HVco/x1XKP8dVyj/ + HVco/x1YKf8dWCn/HVgp/x1YKf8rYzb/K2M2/ytjNv8rYzb/+/Xu//v17v/79e7/+/Xu/x5cK/8eXCv/ + Hlwr/x5cK/8eXSv/Hl0r/x5dK/8eXSv/MaPL/zGjy/8xo8v/MaPL/zCixv8wosb/MKLG/zCixv8fYCz/ + H2As/x9gLP8fYCz/IGEt/yBhLf8gYS3/IGEt/yBiLf8gYi3/IGIt/yBiLf8gYy7/IGMu/yBjLv8gYy7/ + Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9no3P/ + Z6Nz/22+1/9tvtf/bb7X/22+1/9svNf/bLzX/2y81/9svNf/W35i/1t+Yv9bfmL/W35i/1t/Y/9bf2P/ + W39j/1t/Y//8+PP//Pjz//z48//8+PP/Zods/2aHbP9mh2z/Zods/1yBZP9cgWT/XIFk/1yBZP9cgWT/ + XIFk/1yBZP9cgWT/Zoht/2aIbf9miG3/Zoht/7DAr/+wwK//sMCv/7DAr/+ywrH/ssKx/7LCsf+ywrH/ + 2d7U/9ne1P/Z3tT/2d7U/9ne1P/Z3tT/2d7U/9ne1P+vwK3/r8Ct/6/Arf+vwK3/m7Ka/5uymv+bspr/ + m7Ka/ylfNP8pXzT/KV80/ylfNP8dVyj/HVco/x1XKP8dVyj/HVgp/x1YKf8dWCn/HVgp/ytjNv8rYzb/ + K2M2/ytjNv/79e7/+/Xu//v17v/79e7/Hlwr/x5cK/8eXCv/Hlwr/x5dK/8eXSv/Hl0r/x5dK/8xo8v/ + MaPL/zGjy/8xo8v/MKLG/zCixv8wosb/MKLG/x9gLP8fYCz/H2As/x9gLP8gYS3/IGEt/yBhLf8gYS3/ + IGIt/yBiLf8gYi3/IGIt/yBjLv8gYy7/IGMu/yBjLv9no3P/Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9no3P/ + Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9no3P/bb7X/22+1/9tvtf/bb7X/2y81/9svNf/ + bLzX/2y81/9bfmL/W35i/1t+Yv9bfmL/W39j/1t/Y/9bf2P/W39j//z48//8+PP//Pjz//z48/9mh2z/ + Zods/2aHbP9mh2z/XIFk/1yBZP9cgWT/XIFk/1yBZP9cgWT/XIFk/1yBZP9miG3/Zoht/2aIbf9miG3/ + sMCv/7DAr/+wwK//sMCv/7LCsf+ywrH/ssKx/7LCsf/Z3tT/2d7U/9ne1P/Z3tT/2d7U/9ne1P/Z3tT/ + 2d7U/6/Arf+vwK3/r8Ct/6/Arf+bspr/m7Ka/5uymv+bspr/KV80/ylfNP8pXzT/KV80/x1XKP8dVyj/ + HVco/x1XKP8dWCn/HVgp/x1YKf8dWCn/K2M2/ytjNv8rYzb/K2M2//v17v/79e7/+/Xu//v17v8eXCv/ + Hlwr/x5cK/8eXCv/Hl0r/x5dK/8eXSv/Hl0r/zGjy/8xo8v/MaPL/zGjy/8wosb/MKLG/zCixv8wosb/ + H2As/x9gLP8fYCz/H2As/yBhLf8gYS3/IGEt/yBhLf8gYi3/IGIt/yBiLf8gYi3/IGMu/yBjLv8gYy7/ + IGMu/2qld/9qpXf/aqV3/2qld/9qpXf/aqV3/2qld/9qpXf/aqV3/2qld/9qpXf/aqV3/2qld/9qpXf/ + aqV3/2qld/9xxuz/ccbs/3HG7P9xxuz/bLO//2yzv/9ss7//bLO//16AZf9egGX/XoBl/16AZf9egWX/ + XoFl/16BZf9egWX//fn1//359f/9+fX//fn1/2iJb/9oiW//aIlv/2iJb/9eg2f/XoNn/16DZ/9eg2f/ + XoNn/16DZ/9eg2f/XoNn/2iKcP9oinD/aIpw/2iKcP+xwbH/scGx/7HBsf+xwbH/s8Oz/7PDs/+zw7P/ + s8Oz/9vg1v/b4Nb/2+DW/9vg1v/b4Nb/2+DW/9vg1v/b4Nb/tMS0/7TEtP+0xLT/tMS0/7LDsv+yw7L/ + ssOy/7LDsv9Sflz/Un5c/1J+XP9Sflz/IFos/yBaLP8gWiz/IFos/x1YKv8dWCr/HVgq/x1YKv8rYjb/ + K2I2/ytiNv8rYjb//Pbw//z28P/89vD//Pbw/x5bLP8eWyz/Hlss/x5bLP8eXCz/Hlws/x5cLP8eXCz/ + Lpiq/y6Yqv8umKr/Lpiq/zSt5f80reX/NK3l/zSt5f8fXy3/H18t/x9fLf8fXy3/H2Au/x9gLv8fYC7/ + H2Au/yBhLv8gYS7/IGEu/yBhLv8gYy//IGMv/yBjL/8gYy//aqV3/2qld/9qpXf/aqV3/2qld/9qpXf/ + aqV3/2qld/9qpXf/aqV3/2qld/9qpXf/aqV3/2qld/9qpXf/aqV3/3HG7P9xxuz/ccbs/3HG7P9ss7// + bLO//2yzv/9ss7//XoBl/16AZf9egGX/XoBl/16BZf9egWX/XoFl/16BZf/9+fX//fn1//359f/9+fX/ + aIlv/2iJb/9oiW//aIlv/16DZ/9eg2f/XoNn/16DZ/9eg2f/XoNn/16DZ/9eg2f/aIpw/2iKcP9oinD/ + aIpw/7HBsf+xwbH/scGx/7HBsf+zw7P/s8Oz/7PDs/+zw7P/2+DW/9vg1v/b4Nb/2+DW/9vg1v/b4Nb/ + 2+DW/9vg1v+0xLT/tMS0/7TEtP+0xLT/ssOy/7LDsv+yw7L/ssOy/1J+XP9Sflz/Un5c/1J+XP8gWiz/ + IFos/yBaLP8gWiz/HVgq/x1YKv8dWCr/HVgq/ytiNv8rYjb/K2I2/ytiNv/89vD//Pbw//z28P/89vD/ + Hlss/x5bLP8eWyz/Hlss/x5cLP8eXCz/Hlws/x5cLP8umKr/Lpiq/y6Yqv8umKr/NK3l/zSt5f80reX/ + NK3l/x9fLf8fXy3/H18t/x9fLf8fYC7/H2Au/x9gLv8fYC7/IGEu/yBhLv8gYS7/IGEu/yBjL/8gYy// + IGMv/yBjL/9qpXf/aqV3/2qld/9qpXf/aqV3/2qld/9qpXf/aqV3/2qld/9qpXf/aqV3/2qld/9qpXf/ + aqV3/2qld/9qpXf/ccbs/3HG7P9xxuz/ccbs/2yzv/9ss7//bLO//2yzv/9egGX/XoBl/16AZf9egGX/ + XoFl/16BZf9egWX/XoFl//359f/9+fX//fn1//359f9oiW//aIlv/2iJb/9oiW//XoNn/16DZ/9eg2f/ + XoNn/16DZ/9eg2f/XoNn/16DZ/9oinD/aIpw/2iKcP9oinD/scGx/7HBsf+xwbH/scGx/7PDs/+zw7P/ + s8Oz/7PDs//b4Nb/2+DW/9vg1v/b4Nb/2+DW/9vg1v/b4Nb/2+DW/7TEtP+0xLT/tMS0/7TEtP+yw7L/ + ssOy/7LDsv+yw7L/Un5c/1J+XP9Sflz/Un5c/yBaLP8gWiz/IFos/yBaLP8dWCr/HVgq/x1YKv8dWCr/ + K2I2/ytiNv8rYjb/K2I2//z28P/89vD//Pbw//z28P8eWyz/Hlss/x5bLP8eWyz/Hlws/x5cLP8eXCz/ + Hlws/y6Yqv8umKr/Lpiq/y6Yqv80reX/NK3l/zSt5f80reX/H18t/x9fLf8fXy3/H18t/x9gLv8fYC7/ + H2Au/x9gLv8gYS7/IGEu/yBhLv8gYS7/IGMv/yBjL/8gYy//IGMv/2qld/9qpXf/aqV3/2qld/9qpXf/ + aqV3/2qld/9qpXf/aqV3/2qld/9qpXf/aqV3/2qld/9qpXf/aqV3/2qld/9xxuz/ccbs/3HG7P9xxuz/ + bLO//2yzv/9ss7//bLO//16AZf9egGX/XoBl/16AZf9egWX/XoFl/16BZf9egWX//fn1//359f/9+fX/ + /fn1/2iJb/9oiW//aIlv/2iJb/9eg2f/XoNn/16DZ/9eg2f/XoNn/16DZ/9eg2f/XoNn/2iKcP9oinD/ + aIpw/2iKcP+xwbH/scGx/7HBsf+xwbH/s8Oz/7PDs/+zw7P/s8Oz/9vg1v/b4Nb/2+DW/9vg1v/b4Nb/ + 2+DW/9vg1v/b4Nb/tMS0/7TEtP+0xLT/tMS0/7LDsv+yw7L/ssOy/7LDsv9Sflz/Un5c/1J+XP9Sflz/ + IFos/yBaLP8gWiz/IFos/x1YKv8dWCr/HVgq/x1YKv8rYjb/K2I2/ytiNv8rYjb//Pbw//z28P/89vD/ + /Pbw/x5bLP8eWyz/Hlss/x5bLP8eXCz/Hlws/x5cLP8eXCz/Lpiq/y6Yqv8umKr/Lpiq/zSt5f80reX/ + NK3l/zSt5f8fXy3/H18t/x9fLf8fXy3/H2Au/x9gLv8fYC7/H2Au/yBhLv8gYS7/IGEu/yBhLv8gYy// + IGMv/yBjL/8gYy//bah6/22oev9tqHr/bah6/22oev9tqHr/bah6/22oev9tqHr/bah6/22oev9tqHr/ + bal//22pf/9tqX//bal//3TM+/90zPv/dMz7/3TM+/9rqaj/a6mo/2upqP9rqaj/YIJo/2CCaP9ggmj/ + YIJo/2CDaP9gg2j/YINo/2CDaP/9+vb//fr2//369v/9+vb/a4ty/2uLcv9ri3L/a4ty/2GFaf9hhWn/ + YYVp/2GFaf9ihmn/YoZp/2KGaf9ihmn/YoZq/2KGav9ihmr/YoZq/2KHav9ih2r/Yodq/2KHav9jiGv/ + Y4hr/2OIa/9jiGv/tcW1/7XFtf+1xbX/tcW1/7XFtv+1xbb/tcW2/7XFtv9jimv/Y4pr/2OKa/9jimv/ + Y4ps/2OKbP9jimz/Y4ps/2OLbP9ji2z/Y4ts/2OLbP9ahGT/WoRk/1qEZP9ahGT/LGM4/yxjOP8sYzj/ + LGM4/ytiN/8rYjf/K2I3/ytiN//89/L//Pfy//z38v/89/L/Hlws/x5cLP8eXCz/Hlws/x5dLP8eXSz/ + Hl0s/x5dLP8rioj/K4qI/yuKiP8rioj/NbT5/zW0+f81tPn/NbT5/yFkNf8hZDX/IWQ1/yFkNf8gYS7/ + IGEu/yBhLv8gYS7/IGIv/yBiL/8gYi//IGIv/yFjL/8hYy//IWMv/yFjL/9tqHr/bah6/22oev9tqHr/ + bah6/22oev9tqHr/bah6/22oev9tqHr/bah6/22oev9tqX//bal//22pf/9tqX//dMz7/3TM+/90zPv/ + dMz7/2upqP9rqaj/a6mo/2upqP9ggmj/YIJo/2CCaP9ggmj/YINo/2CDaP9gg2j/YINo//369v/9+vb/ + /fr2//369v9ri3L/a4ty/2uLcv9ri3L/YYVp/2GFaf9hhWn/YYVp/2KGaf9ihmn/YoZp/2KGaf9ihmr/ + YoZq/2KGav9ihmr/Yodq/2KHav9ih2r/Yodq/2OIa/9jiGv/Y4hr/2OIa/+1xbX/tcW1/7XFtf+1xbX/ + tcW2/7XFtv+1xbb/tcW2/2OKa/9jimv/Y4pr/2OKa/9jimz/Y4ps/2OKbP9jimz/Y4ts/2OLbP9ji2z/ + Y4ts/1qEZP9ahGT/WoRk/1qEZP8sYzj/LGM4/yxjOP8sYzj/K2I3/ytiN/8rYjf/K2I3//z38v/89/L/ + /Pfy//z38v8eXCz/Hlws/x5cLP8eXCz/Hl0s/x5dLP8eXSz/Hl0s/yuKiP8rioj/K4qI/yuKiP81tPn/ + NbT5/zW0+f81tPn/IWQ1/yFkNf8hZDX/IWQ1/yBhLv8gYS7/IGEu/yBhLv8gYi//IGIv/yBiL/8gYi// + IWMv/yFjL/8hYy//IWMv/22oev9tqHr/bah6/22oev9tqHr/bah6/22oev9tqHr/bah6/22oev9tqHr/ + bah6/22pf/9tqX//bal//22pf/90zPv/dMz7/3TM+/90zPv/a6mo/2upqP9rqaj/a6mo/2CCaP9ggmj/ + YIJo/2CCaP9gg2j/YINo/2CDaP9gg2j//fr2//369v/9+vb//fr2/2uLcv9ri3L/a4ty/2uLcv9hhWn/ + YYVp/2GFaf9hhWn/YoZp/2KGaf9ihmn/YoZp/2KGav9ihmr/YoZq/2KGav9ih2r/Yodq/2KHav9ih2r/ + Y4hr/2OIa/9jiGv/Y4hr/7XFtf+1xbX/tcW1/7XFtf+1xbb/tcW2/7XFtv+1xbb/Y4pr/2OKa/9jimv/ + Y4pr/2OKbP9jimz/Y4ps/2OKbP9ji2z/Y4ts/2OLbP9ji2z/WoRk/1qEZP9ahGT/WoRk/yxjOP8sYzj/ + LGM4/yxjOP8rYjf/K2I3/ytiN/8rYjf//Pfy//z38v/89/L//Pfy/x5cLP8eXCz/Hlws/x5cLP8eXSz/ + Hl0s/x5dLP8eXSz/K4qI/yuKiP8rioj/K4qI/zW0+f81tPn/NbT5/zW0+f8hZDX/IWQ1/yFkNf8hZDX/ + IGEu/yBhLv8gYS7/IGEu/yBiL/8gYi//IGIv/yBiL/8hYy//IWMv/yFjL/8hYy//bah6/22oev9tqHr/ + bah6/22oev9tqHr/bah6/22oev9tqHr/bah6/22oev9tqHr/bal//22pf/9tqX//bal//3TM+/90zPv/ + dMz7/3TM+/9rqaj/a6mo/2upqP9rqaj/YIJo/2CCaP9ggmj/YIJo/2CDaP9gg2j/YINo/2CDaP/9+vb/ + /fr2//369v/9+vb/a4ty/2uLcv9ri3L/a4ty/2GFaf9hhWn/YYVp/2GFaf9ihmn/YoZp/2KGaf9ihmn/ + YoZq/2KGav9ihmr/YoZq/2KHav9ih2r/Yodq/2KHav9jiGv/Y4hr/2OIa/9jiGv/tcW1/7XFtf+1xbX/ + tcW1/7XFtv+1xbb/tcW2/7XFtv9jimv/Y4pr/2OKa/9jimv/Y4ps/2OKbP9jimz/Y4ps/2OLbP9ji2z/ + Y4ts/2OLbP9ahGT/WoRk/1qEZP9ahGT/LGM4/yxjOP8sYzj/LGM4/ytiN/8rYjf/K2I3/ytiN//89/L/ + /Pfy//z38v/89/L/Hlws/x5cLP8eXCz/Hlws/x5dLP8eXSz/Hl0s/x5dLP8rioj/K4qI/yuKiP8rioj/ + NbT5/zW0+f81tPn/NbT5/yFkNf8hZDX/IWQ1/yFkNf8gYS7/IGEu/yBhLv8gYS7/IGIv/yBiL/8gYi// + IGIv/yFjL/8hYy//IWMv/yFjL/9xq37/cat+/3Grfv9xq37/cat+/3Grfv9xq37/cat+/3Grfv9xq37/ + cat+/3Grfv9yr4z/cq+M/3KvjP9yr4z/eM37/3jN+/94zfv/eM37/22loP9tpaD/baWg/22loP9khGv/ + ZIRr/2SEa/9khGv/ZIVr/2SFa/9khWv/ZIVr//36+P/9+vj//fr4//36+P9ujnX/bo51/26Odf9ujnX/ + ZYht/2WIbf9liG3/ZYht/2WIbf9liG3/ZYht/2WIbf9liW3/ZYlt/2WJbf9liW3/Zopt/2aKbf9mim3/ + Zopt/2aKbv9mim7/Zopu/2aKbv+1xbb/tcW2/7XFtv+1xbb/tcW2/7XFtv+1xbb/tcW2/2eMb/9njG// + Z4xv/2eMb/9njW//Z41v/2eNb/9njW//Z45v/2eOb/9njm//Z45v/2eOcP9njnD/Z45w/2eOcP9mjm7/ + Zo5u/2aObv9mjm7/THtW/0x7Vv9Me1b/THtW//z49P/8+PT//Pj0//z49P8eWyz/Hlss/x5bLP8eWyz/ + H10s/x9dLP8fXSz/H10s/yqDd/8qg3f/KoN3/yqDd/82tfn/NrX5/za1+f82tfn/I21H/yNtR/8jbUf/ + I21H/yBhLv8gYS7/IGEu/yBhLv8hYi//IWIv/yFiL/8hYi//IWMw/yFjMP8hYzD/IWMw/3Grfv9xq37/ + cat+/3Grfv9xq37/cat+/3Grfv9xq37/cat+/3Grfv9xq37/cat+/3KvjP9yr4z/cq+M/3KvjP94zfv/ + eM37/3jN+/94zfv/baWg/22loP9tpaD/baWg/2SEa/9khGv/ZIRr/2SEa/9khWv/ZIVr/2SFa/9khWv/ + /fr4//36+P/9+vj//fr4/26Odf9ujnX/bo51/26Odf9liG3/ZYht/2WIbf9liG3/ZYht/2WIbf9liG3/ + ZYht/2WJbf9liW3/ZYlt/2WJbf9mim3/Zopt/2aKbf9mim3/Zopu/2aKbv9mim7/Zopu/7XFtv+1xbb/ + tcW2/7XFtv+1xbb/tcW2/7XFtv+1xbb/Z4xv/2eMb/9njG//Z4xv/2eNb/9njW//Z41v/2eNb/9njm// + Z45v/2eOb/9njm//Z45w/2eOcP9njnD/Z45w/2aObv9mjm7/Zo5u/2aObv9Me1b/THtW/0x7Vv9Me1b/ + /Pj0//z49P/8+PT//Pj0/x5bLP8eWyz/Hlss/x5bLP8fXSz/H10s/x9dLP8fXSz/KoN3/yqDd/8qg3f/ + KoN3/za1+f82tfn/NrX5/za1+f8jbUf/I21H/yNtR/8jbUf/IGEu/yBhLv8gYS7/IGEu/yFiL/8hYi// + IWIv/yFiL/8hYzD/IWMw/yFjMP8hYzD/cat+/3Grfv9xq37/cat+/3Grfv9xq37/cat+/3Grfv9xq37/ + cat+/3Grfv9xq37/cq+M/3KvjP9yr4z/cq+M/3jN+/94zfv/eM37/3jN+/9tpaD/baWg/22loP9tpaD/ + ZIRr/2SEa/9khGv/ZIRr/2SFa/9khWv/ZIVr/2SFa//9+vj//fr4//36+P/9+vj/bo51/26Odf9ujnX/ + bo51/2WIbf9liG3/ZYht/2WIbf9liG3/ZYht/2WIbf9liG3/ZYlt/2WJbf9liW3/ZYlt/2aKbf9mim3/ + Zopt/2aKbf9mim7/Zopu/2aKbv9mim7/tcW2/7XFtv+1xbb/tcW2/7XFtv+1xbb/tcW2/7XFtv9njG// + Z4xv/2eMb/9njG//Z41v/2eNb/9njW//Z41v/2eOb/9njm//Z45v/2eOb/9njnD/Z45w/2eOcP9njnD/ + Zo5u/2aObv9mjm7/Zo5u/0x7Vv9Me1b/THtW/0x7Vv/8+PT//Pj0//z49P/8+PT/Hlss/x5bLP8eWyz/ + Hlss/x9dLP8fXSz/H10s/x9dLP8qg3f/KoN3/yqDd/8qg3f/NrX5/za1+f82tfn/NrX5/yNtR/8jbUf/ + I21H/yNtR/8gYS7/IGEu/yBhLv8gYS7/IWIv/yFiL/8hYi//IWIv/yFjMP8hYzD/IWMw/yFjMP9xq37/ + cat+/3Grfv9xq37/cat+/3Grfv9xq37/cat+/3Grfv9xq37/cat+/3Grfv9yr4z/cq+M/3KvjP9yr4z/ + eM37/3jN+/94zfv/eM37/22loP9tpaD/baWg/22loP9khGv/ZIRr/2SEa/9khGv/ZIVr/2SFa/9khWv/ + ZIVr//36+P/9+vj//fr4//36+P9ujnX/bo51/26Odf9ujnX/ZYht/2WIbf9liG3/ZYht/2WIbf9liG3/ + ZYht/2WIbf9liW3/ZYlt/2WJbf9liW3/Zopt/2aKbf9mim3/Zopt/2aKbv9mim7/Zopu/2aKbv+1xbb/ + tcW2/7XFtv+1xbb/tcW2/7XFtv+1xbb/tcW2/2eMb/9njG//Z4xv/2eMb/9njW//Z41v/2eNb/9njW// + Z45v/2eOb/9njm//Z45v/2eOcP9njnD/Z45w/2eOcP9mjm7/Zo5u/2aObv9mjm7/THtW/0x7Vv9Me1b/ + THtW//z49P/8+PT//Pj0//z49P8eWyz/Hlss/x5bLP8eWyz/H10s/x9dLP8fXSz/H10s/yqDd/8qg3f/ + KoN3/yqDd/82tfn/NrX5/za1+f82tfn/I21H/yNtR/8jbUf/I21H/yBhLv8gYS7/IGEu/yBhLv8hYi// + IWIv/yFiL/8hYi//IWMw/yFjMP8hYzD/IWMw/3Stgf90rYH/dK2B/3Stgf90rYH/dK2B/3Stgf90rYH/ + dK2B/3Stgf90rYH/dK2B/3Wyk/91spP/dbKT/3Wyk/97z/v/e8/7/3vP+/97z/v/cKWe/3Clnv9wpZ7/ + cKWe/2eGbv9nhm7/Z4Zu/2eGbv9nh2//Z4dv/2eHb/9nh2///fr4//36+P/9+vj//fr4/3OSef9zknn/ + c5J5/3OSef9oim//aIpv/2iKb/9oim//aIpw/2iKcP9oinD/aIpw/2mLcf9pi3H/aYtx/2mLcf9pjHH/ + aYxx/2mMcf9pjHH/aYxx/2mMcf9pjHH/aYxx/3KUef9ylHn/cpR5/3KUef9ylHr/cpR6/3KUev9ylHr/ + aY5y/2mOcv9pjnL/aY5y/2qPc/9qj3P/ao9z/2qPc/9qkHP/apBz/2qQc/9qkHP/apBz/2qQc/9qkHP/ + apBz/2uRc/9rkXP/a5Fz/2uRc/91mX3/dZl9/3WZff91mX3//fr3//369//9+vf//fr3/yNeMP8jXjD/ + I14w/yNeMP8fXC3/H1wt/x9cLf8fXC3/KYNz/ymDc/8pg3P/KYNz/za2+f82tvn/Nrb5/za2+f8lcU3/ + JXFN/yVxTf8lcU3/IWEv/yFhL/8hYS//IWEv/yFiMP8hYjD/IWIw/yFiMP8hZDH/IWQx/yFkMf8hZDH/ + dK2B/3Stgf90rYH/dK2B/3Stgf90rYH/dK2B/3Stgf90rYH/dK2B/3Stgf90rYH/dbKT/3Wyk/91spP/ + dbKT/3vP+/97z/v/e8/7/3vP+/9wpZ7/cKWe/3Clnv9wpZ7/Z4Zu/2eGbv9nhm7/Z4Zu/2eHb/9nh2// + Z4dv/2eHb//9+vj//fr4//36+P/9+vj/c5J5/3OSef9zknn/c5J5/2iKb/9oim//aIpv/2iKb/9oinD/ + aIpw/2iKcP9oinD/aYtx/2mLcf9pi3H/aYtx/2mMcf9pjHH/aYxx/2mMcf9pjHH/aYxx/2mMcf9pjHH/ + cpR5/3KUef9ylHn/cpR5/3KUev9ylHr/cpR6/3KUev9pjnL/aY5y/2mOcv9pjnL/ao9z/2qPc/9qj3P/ + ao9z/2qQc/9qkHP/apBz/2qQc/9qkHP/apBz/2qQc/9qkHP/a5Fz/2uRc/9rkXP/a5Fz/3WZff91mX3/ + dZl9/3WZff/9+vf//fr3//369//9+vf/I14w/yNeMP8jXjD/I14w/x9cLf8fXC3/H1wt/x9cLf8pg3P/ + KYNz/ymDc/8pg3P/Nrb5/za2+f82tvn/Nrb5/yVxTf8lcU3/JXFN/yVxTf8hYS//IWEv/yFhL/8hYS// + IWIw/yFiMP8hYjD/IWIw/yFkMf8hZDH/IWQx/yFkMf90rYH/dK2B/3Stgf90rYH/dK2B/3Stgf90rYH/ + dK2B/3Stgf90rYH/dK2B/3Stgf91spP/dbKT/3Wyk/91spP/e8/7/3vP+/97z/v/e8/7/3Clnv9wpZ7/ + cKWe/3Clnv9nhm7/Z4Zu/2eGbv9nhm7/Z4dv/2eHb/9nh2//Z4dv//36+P/9+vj//fr4//36+P9zknn/ + c5J5/3OSef9zknn/aIpv/2iKb/9oim//aIpv/2iKcP9oinD/aIpw/2iKcP9pi3H/aYtx/2mLcf9pi3H/ + aYxx/2mMcf9pjHH/aYxx/2mMcf9pjHH/aYxx/2mMcf9ylHn/cpR5/3KUef9ylHn/cpR6/3KUev9ylHr/ + cpR6/2mOcv9pjnL/aY5y/2mOcv9qj3P/ao9z/2qPc/9qj3P/apBz/2qQc/9qkHP/apBz/2qQc/9qkHP/ + apBz/2qQc/9rkXP/a5Fz/2uRc/9rkXP/dZl9/3WZff91mX3/dZl9//369//9+vf//fr3//369/8jXjD/ + I14w/yNeMP8jXjD/H1wt/x9cLf8fXC3/H1wt/ymDc/8pg3P/KYNz/ymDc/82tvn/Nrb5/za2+f82tvn/ + JXFN/yVxTf8lcU3/JXFN/yFhL/8hYS//IWEv/yFhL/8hYjD/IWIw/yFiMP8hYjD/IWQx/yFkMf8hZDH/ + IWQx/3Stgf90rYH/dK2B/3Stgf90rYH/dK2B/3Stgf90rYH/dK2B/3Stgf90rYH/dK2B/3Wyk/91spP/ + dbKT/3Wyk/97z/v/e8/7/3vP+/97z/v/cKWe/3Clnv9wpZ7/cKWe/2eGbv9nhm7/Z4Zu/2eGbv9nh2// + Z4dv/2eHb/9nh2///fr4//36+P/9+vj//fr4/3OSef9zknn/c5J5/3OSef9oim//aIpv/2iKb/9oim// + aIpw/2iKcP9oinD/aIpw/2mLcf9pi3H/aYtx/2mLcf9pjHH/aYxx/2mMcf9pjHH/aYxx/2mMcf9pjHH/ + aYxx/3KUef9ylHn/cpR5/3KUef9ylHr/cpR6/3KUev9ylHr/aY5y/2mOcv9pjnL/aY5y/2qPc/9qj3P/ + ao9z/2qPc/9qkHP/apBz/2qQc/9qkHP/apBz/2qQc/9qkHP/apBz/2uRc/9rkXP/a5Fz/2uRc/91mX3/ + dZl9/3WZff91mX3//fr3//369//9+vf//fr3/yNeMP8jXjD/I14w/yNeMP8fXC3/H1wt/x9cLf8fXC3/ + KYNz/ymDc/8pg3P/KYNz/za2+f82tvn/Nrb5/za2+f8lcU3/JXFN/yVxTf8lcU3/IWEv/yFhL/8hYS// + IWEv/yFiMP8hYjD/IWIw/yFiMP8hZDH/IWQx/yFkMf8hZDH/d6+E/3evhP93r4T/d6+E/3evhP93r4T/ + d6+E/3evhP93r4T/d6+E/3evhP93r4T/eLWX/3i1l/94tZf/eLWX/37Q+/9+0Pv/ftD7/37Q+/9ypZ3/ + cqWd/3Klnf9ypZ3/aolx/2qJcf9qiXH/aolx/2qJcf9qiXH/aolx/2qJcf/Z39j/2d/Y/9nf2P/Z39j/ + 4ebg/+Hm4P/h5uD/4ebg/9je1v/Y3tb/2N7W/9je1v/Y3tb/2N7W/9je1v/Y3tb/2N/W/9jf1v/Y39b/ + 2N/W/9jf1v/Y39b/2N/W/9jf1v/Y39f/2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/ + 2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/2N/X/9jg1//Y4Nf/2ODX/9jg1//Y4Nf/ + 2ODX/9jg1//Y4Nf/2ODX/9jg1//Y4Nf/2ODX/+Hn4f/h5+H/4efh/+Hn4f/Z4tn/2eLZ/9ni2f/Z4tn/ + X4pp/1+Kaf9fimn/X4pp/yZhNP8mYTT/JmE0/yZhNP8pgG3/KYBt/ymAbf8pgG3/N7f5/ze3+f83t/n/ + N7f5/yZyUv8mclL/JnJS/yZyUv8hYTD/IWEw/yFhMP8hYTD/IWIw/yFiMP8hYjD/IWIw/yJjMf8iYzH/ + ImMx/yJjMf93r4T/d6+E/3evhP93r4T/d6+E/3evhP93r4T/d6+E/3evhP93r4T/d6+E/3evhP94tZf/ + eLWX/3i1l/94tZf/ftD7/37Q+/9+0Pv/ftD7/3Klnf9ypZ3/cqWd/3Klnf9qiXH/aolx/2qJcf9qiXH/ + aolx/2qJcf9qiXH/aolx/9nf2P/Z39j/2d/Y/9nf2P/h5uD/4ebg/+Hm4P/h5uD/2N7W/9je1v/Y3tb/ + 2N7W/9je1v/Y3tb/2N7W/9je1v/Y39b/2N/W/9jf1v/Y39b/2N/W/9jf1v/Y39b/2N/W/9jf1//Y39f/ + 2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/ + 2N/X/9jf1//Y39f/2ODX/9jg1//Y4Nf/2ODX/9jg1//Y4Nf/2ODX/9jg1//Y4Nf/2ODX/9jg1//Y4Nf/ + 4efh/+Hn4f/h5+H/4efh/9ni2f/Z4tn/2eLZ/9ni2f9fimn/X4pp/1+Kaf9fimn/JmE0/yZhNP8mYTT/ + JmE0/ymAbf8pgG3/KYBt/ymAbf83t/n/N7f5/ze3+f83t/n/JnJS/yZyUv8mclL/JnJS/yFhMP8hYTD/ + IWEw/yFhMP8hYjD/IWIw/yFiMP8hYjD/ImMx/yJjMf8iYzH/ImMx/3evhP93r4T/d6+E/3evhP93r4T/ + d6+E/3evhP93r4T/d6+E/3evhP93r4T/d6+E/3i1l/94tZf/eLWX/3i1l/9+0Pv/ftD7/37Q+/9+0Pv/ + cqWd/3Klnf9ypZ3/cqWd/2qJcf9qiXH/aolx/2qJcf9qiXH/aolx/2qJcf9qiXH/2d/Y/9nf2P/Z39j/ + 2d/Y/+Hm4P/h5uD/4ebg/+Hm4P/Y3tb/2N7W/9je1v/Y3tb/2N7W/9je1v/Y3tb/2N7W/9jf1v/Y39b/ + 2N/W/9jf1v/Y39b/2N/W/9jf1v/Y39b/2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/ + 2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/2N/X/9jf1//Y4Nf/2ODX/9jg1//Y4Nf/ + 2ODX/9jg1//Y4Nf/2ODX/9jg1//Y4Nf/2ODX/9jg1//h5+H/4efh/+Hn4f/h5+H/2eLZ/9ni2f/Z4tn/ + 2eLZ/1+Kaf9fimn/X4pp/1+Kaf8mYTT/JmE0/yZhNP8mYTT/KYBt/ymAbf8pgG3/KYBt/ze3+f83t/n/ + N7f5/ze3+f8mclL/JnJS/yZyUv8mclL/IWEw/yFhMP8hYTD/IWEw/yFiMP8hYjD/IWIw/yFiMP8iYzH/ + ImMx/yJjMf8iYzH/d6+E/3evhP93r4T/d6+E/3evhP93r4T/d6+E/3evhP93r4T/d6+E/3evhP93r4T/ + eLWX/3i1l/94tZf/eLWX/37Q+/9+0Pv/ftD7/37Q+/9ypZ3/cqWd/3Klnf9ypZ3/aolx/2qJcf9qiXH/ + aolx/2qJcf9qiXH/aolx/2qJcf/Z39j/2d/Y/9nf2P/Z39j/4ebg/+Hm4P/h5uD/4ebg/9je1v/Y3tb/ + 2N7W/9je1v/Y3tb/2N7W/9je1v/Y3tb/2N/W/9jf1v/Y39b/2N/W/9jf1v/Y39b/2N/W/9jf1v/Y39f/ + 2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/ + 2N/X/9jf1//Y39f/2N/X/9jg1//Y4Nf/2ODX/9jg1//Y4Nf/2ODX/9jg1//Y4Nf/2ODX/9jg1//Y4Nf/ + 2ODX/+Hn4f/h5+H/4efh/+Hn4f/Z4tn/2eLZ/9ni2f/Z4tn/X4pp/1+Kaf9fimn/X4pp/yZhNP8mYTT/ + JmE0/yZhNP8pgG3/KYBt/ymAbf8pgG3/N7f5/ze3+f83t/n/N7f5/yZyUv8mclL/JnJS/yZyUv8hYTD/ + IWEw/yFhMP8hYTD/IWIw/yFiMP8hYjD/IWIw/yJjMf8iYzH/ImMx/yJjMf96soj/erKI/3qyiP96soj/ + erKI/3qyiP96soj/erKI/3qyiP96soj/erKI/3qyiP97uJ3/e7id/3u4nf97uJ3/gNL7/4DS+/+A0vv/ + gNL7/3Olm/9zpZv/c6Wb/3Olm/9si3T/bIt0/2yLdP9si3T/bYt1/22Ldf9ti3X/bYt1/3KQev9ykHr/ + cpB6/3KQev+Yrp3/mK6d/5iunf+Yrp3/nbKh/52yof+dsqH/nbKh/7fGuf+3xrn/t8a5/7fGuf/r7un/ + 6+7p/+vu6f/r7un/nrSi/560ov+etKL/nrSi/560ov+etKL/nrSi/560ov+etaL/nrWi/561ov+etaL/ + nrWj/561o/+etaP/nrWj/561o/+etaP/nrWj/561o/+etqT/nrak/562pP+etqT/6+7q/+vu6v/r7ur/ + 6+7q/7fJu/+3ybv/t8m7/7fJu/+ft6T/n7ek/5+3pP+ft6T/mrSg/5q0oP+atKD/mrSg/3Wafv91mn7/ + dZp+/3Wafv9xl3r/cZd6/3GXev9xl3r/ZpBw/2aQcP9mkHD/ZpBw/zWFcP81hXD/NYVw/zWFcP83uPn/ + N7j5/ze4+f83uPn/J3ZY/yd2WP8ndlj/J3ZY/yFhMf8hYTH/IWEx/yFhMf8hYjH/IWIx/yFiMf8hYjH/ + ImYz/yJmM/8iZjP/ImYz/3qyiP96soj/erKI/3qyiP96soj/erKI/3qyiP96soj/erKI/3qyiP96soj/ + erKI/3u4nf97uJ3/e7id/3u4nf+A0vv/gNL7/4DS+/+A0vv/c6Wb/3Olm/9zpZv/c6Wb/2yLdP9si3T/ + bIt0/2yLdP9ti3X/bYt1/22Ldf9ti3X/cpB6/3KQev9ykHr/cpB6/5iunf+Yrp3/mK6d/5iunf+dsqH/ + nbKh/52yof+dsqH/t8a5/7fGuf+3xrn/t8a5/+vu6f/r7un/6+7p/+vu6f+etKL/nrSi/560ov+etKL/ + nrSi/560ov+etKL/nrSi/561ov+etaL/nrWi/561ov+etaP/nrWj/561o/+etaP/nrWj/561o/+etaP/ + nrWj/562pP+etqT/nrak/562pP/r7ur/6+7q/+vu6v/r7ur/t8m7/7fJu/+3ybv/t8m7/5+3pP+ft6T/ + n7ek/5+3pP+atKD/mrSg/5q0oP+atKD/dZp+/3Wafv91mn7/dZp+/3GXev9xl3r/cZd6/3GXev9mkHD/ + ZpBw/2aQcP9mkHD/NYVw/zWFcP81hXD/NYVw/ze4+f83uPn/N7j5/ze4+f8ndlj/J3ZY/yd2WP8ndlj/ + IWEx/yFhMf8hYTH/IWEx/yFiMf8hYjH/IWIx/yFiMf8iZjP/ImYz/yJmM/8iZjP/erKI/3qyiP96soj/ + erKI/3qyiP96soj/erKI/3qyiP96soj/erKI/3qyiP96soj/e7id/3u4nf97uJ3/e7id/4DS+/+A0vv/ + gNL7/4DS+/9zpZv/c6Wb/3Olm/9zpZv/bIt0/2yLdP9si3T/bIt0/22Ldf9ti3X/bYt1/22Ldf9ykHr/ + cpB6/3KQev9ykHr/mK6d/5iunf+Yrp3/mK6d/52yof+dsqH/nbKh/52yof+3xrn/t8a5/7fGuf+3xrn/ + 6+7p/+vu6f/r7un/6+7p/560ov+etKL/nrSi/560ov+etKL/nrSi/560ov+etKL/nrWi/561ov+etaL/ + nrWi/561o/+etaP/nrWj/561o/+etaP/nrWj/561o/+etaP/nrak/562pP+etqT/nrak/+vu6v/r7ur/ + 6+7q/+vu6v+3ybv/t8m7/7fJu/+3ybv/n7ek/5+3pP+ft6T/n7ek/5q0oP+atKD/mrSg/5q0oP91mn7/ + dZp+/3Wafv91mn7/cZd6/3GXev9xl3r/cZd6/2aQcP9mkHD/ZpBw/2aQcP81hXD/NYVw/zWFcP81hXD/ + N7j5/ze4+f83uPn/N7j5/yd2WP8ndlj/J3ZY/yd2WP8hYTH/IWEx/yFhMf8hYTH/IWIx/yFiMf8hYjH/ + IWIx/yJmM/8iZjP/ImYz/yJmM/96soj/erKI/3qyiP96soj/erKI/3qyiP96soj/erKI/3qyiP96soj/ + erKI/3qyiP97uJ3/e7id/3u4nf97uJ3/gNL7/4DS+/+A0vv/gNL7/3Olm/9zpZv/c6Wb/3Olm/9si3T/ + bIt0/2yLdP9si3T/bYt1/22Ldf9ti3X/bYt1/3KQev9ykHr/cpB6/3KQev+Yrp3/mK6d/5iunf+Yrp3/ + nbKh/52yof+dsqH/nbKh/7fGuf+3xrn/t8a5/7fGuf/r7un/6+7p/+vu6f/r7un/nrSi/560ov+etKL/ + nrSi/560ov+etKL/nrSi/560ov+etaL/nrWi/561ov+etaL/nrWj/561o/+etaP/nrWj/561o/+etaP/ + nrWj/561o/+etqT/nrak/562pP+etqT/6+7q/+vu6v/r7ur/6+7q/7fJu/+3ybv/t8m7/7fJu/+ft6T/ + n7ek/5+3pP+ft6T/mrSg/5q0oP+atKD/mrSg/3Wafv91mn7/dZp+/3Wafv9xl3r/cZd6/3GXev9xl3r/ + ZpBw/2aQcP9mkHD/ZpBw/zWFcP81hXD/NYVw/zWFcP83uPn/N7j5/ze4+f83uPn/J3ZY/yd2WP8ndlj/ + J3ZY/yFhMf8hYTH/IWEx/yFhMf8hYjH/IWIx/yFiMf8hYjH/ImYz/yJmM/8iZjP/ImYz/361i/9+tYv/ + frWL/361i/9+tYv/frWL/361i/9+tYv/frWL/361i/9+tYv/frWL/3+7o/9/u6P/f7uj/3+7o/+E0/v/ + hNP7/4TT+/+E0/v/d6Wa/3elmv93pZr/d6Wa/3CNd/9wjXf/cI13/3CNd/9wjnj/cI54/3COeP9wjnj/ + cI94/3CPeP9wj3j/cI94/3CPef9wj3n/cI95/3CPef9xkHn/cZB5/3GQef9xkHn/kamX/5Gpl/+RqZf/ + kamX/+zw7P/s8Oz/7PDs/+zw7P9yknr/cpJ6/3KSev9yknr/cpN6/3KTev9yk3r/cpN6/3KUev9ylHr/ + cpR6/3KUev9ylHv/cpR7/3KUe/9ylHv/c5V7/3OVe/9zlXv/c5V7/3OWfP9zlnz/c5Z8/3OWfP/s8Oz/ + 7PDs/+zw7P/s8Oz/k66Z/5Oumf+Trpn/k66Z/3SYfP90mHz/dJh8/3SYfP90mH3/dJh9/3SYff90mH3/ + dJl9/3SZff90mX3/dJl9/3SZfv90mX7/dJl+/3SZfv90mn7/dJp+/3Safv90mn7/c6mZ/3Opmf9zqZn/ + c6mZ/0S8+P9EvPj/RLz4/0S8+P8oeF3/KHhd/yh4Xf8oeF3/IWEx/yFhMf8hYTH/IWEx/yJlM/8iZTP/ + ImUz/yJlM/8sgEH/LIBB/yyAQf8sgEH/frWL/361i/9+tYv/frWL/361i/9+tYv/frWL/361i/9+tYv/ + frWL/361i/9+tYv/f7uj/3+7o/9/u6P/f7uj/4TT+/+E0/v/hNP7/4TT+/93pZr/d6Wa/3elmv93pZr/ + cI13/3CNd/9wjXf/cI13/3COeP9wjnj/cI54/3COeP9wj3j/cI94/3CPeP9wj3j/cI95/3CPef9wj3n/ + cI95/3GQef9xkHn/cZB5/3GQef+RqZf/kamX/5Gpl/+RqZf/7PDs/+zw7P/s8Oz/7PDs/3KSev9yknr/ + cpJ6/3KSev9yk3r/cpN6/3KTev9yk3r/cpR6/3KUev9ylHr/cpR6/3KUe/9ylHv/cpR7/3KUe/9zlXv/ + c5V7/3OVe/9zlXv/c5Z8/3OWfP9zlnz/c5Z8/+zw7P/s8Oz/7PDs/+zw7P+Trpn/k66Z/5Oumf+Trpn/ + dJh8/3SYfP90mHz/dJh8/3SYff90mH3/dJh9/3SYff90mX3/dJl9/3SZff90mX3/dJl+/3SZfv90mX7/ + dJl+/3Safv90mn7/dJp+/3Safv9zqZn/c6mZ/3Opmf9zqZn/RLz4/0S8+P9EvPj/RLz4/yh4Xf8oeF3/ + KHhd/yh4Xf8hYTH/IWEx/yFhMf8hYTH/ImUz/yJlM/8iZTP/ImUz/yyAQf8sgEH/LIBB/yyAQf9+tYv/ + frWL/361i/9+tYv/frWL/361i/9+tYv/frWL/361i/9+tYv/frWL/361i/9/u6P/f7uj/3+7o/9/u6P/ + hNP7/4TT+/+E0/v/hNP7/3elmv93pZr/d6Wa/3elmv9wjXf/cI13/3CNd/9wjXf/cI54/3COeP9wjnj/ + cI54/3CPeP9wj3j/cI94/3CPeP9wj3n/cI95/3CPef9wj3n/cZB5/3GQef9xkHn/cZB5/5Gpl/+RqZf/ + kamX/5Gpl//s8Oz/7PDs/+zw7P/s8Oz/cpJ6/3KSev9yknr/cpJ6/3KTev9yk3r/cpN6/3KTev9ylHr/ + cpR6/3KUev9ylHr/cpR7/3KUe/9ylHv/cpR7/3OVe/9zlXv/c5V7/3OVe/9zlnz/c5Z8/3OWfP9zlnz/ + 7PDs/+zw7P/s8Oz/7PDs/5Oumf+Trpn/k66Z/5Oumf90mHz/dJh8/3SYfP90mHz/dJh9/3SYff90mH3/ + dJh9/3SZff90mX3/dJl9/3SZff90mX7/dJl+/3SZfv90mX7/dJp+/3Safv90mn7/dJp+/3Opmf9zqZn/ + c6mZ/3Opmf9EvPj/RLz4/0S8+P9EvPj/KHhd/yh4Xf8oeF3/KHhd/yFhMf8hYTH/IWEx/yFhMf8iZTP/ + ImUz/yJlM/8iZTP/LIBB/yyAQf8sgEH/LIBB/361i/9+tYv/frWL/361i/9+tYv/frWL/361i/9+tYv/ + frWL/361i/9+tYv/frWL/3+7o/9/u6P/f7uj/3+7o/+E0/v/hNP7/4TT+/+E0/v/d6Wa/3elmv93pZr/ + d6Wa/3CNd/9wjXf/cI13/3CNd/9wjnj/cI54/3COeP9wjnj/cI94/3CPeP9wj3j/cI94/3CPef9wj3n/ + cI95/3CPef9xkHn/cZB5/3GQef9xkHn/kamX/5Gpl/+RqZf/kamX/+zw7P/s8Oz/7PDs/+zw7P9yknr/ + cpJ6/3KSev9yknr/cpN6/3KTev9yk3r/cpN6/3KUev9ylHr/cpR6/3KUev9ylHv/cpR7/3KUe/9ylHv/ + c5V7/3OVe/9zlXv/c5V7/3OWfP9zlnz/c5Z8/3OWfP/s8Oz/7PDs/+zw7P/s8Oz/k66Z/5Oumf+Trpn/ + k66Z/3SYfP90mHz/dJh8/3SYfP90mH3/dJh9/3SYff90mH3/dJl9/3SZff90mX3/dJl9/3SZfv90mX7/ + dJl+/3SZfv90mn7/dJp+/3Safv90mn7/c6mZ/3Opmf9zqZn/c6mZ/0S8+P9EvPj/RLz4/0S8+P8oeF3/ + KHhd/yh4Xf8oeF3/IWEx/yFhMf8hYTH/IWEx/yJlM/8iZTP/ImUz/yJlM/8sgEH/LIBB/yyAQf8sgEH/ + gbeO/4G3jv+Bt47/gbeO/4G3jv+Bt47/gbeO/4G3jv+Bt47/gbeO/4G3jv+Bt47/gr6n/4K+p/+Cvqf/ + gr6n/4fU+/+H1Pv/h9T7/4fU+/95pJj/eaSY/3mkmP95pJj/c496/3OPev9zj3r/c496/3OQev9zkHr/ + c5B6/3OQev9zkXr/c5F6/3ORev9zkXr/dJJ7/3SSe/90knv/dJJ7/3SSe/90knv/dJJ7/3SSe/94loD/ + eJaA/3iWgP94loD/7fDs/+3w7P/t8Oz/7fDs/9Te1v/U3tb/1N7W/9Te1v+/zcL/v83C/7/Nwv+/zcL/ + v83C/7/Nwv+/zcL/v83C/7/Owv+/zsL/v87C/7/Owv+/zsL/v87C/7/Owv+/zsL/1d/X/9Xf1//V39f/ + 1d/X/+3w7f/t8O3/7fDt/+3w7f96nIP/epyD/3qcg/96nIP/dpl//3aZf/92mX//dpl//3eaf/93mn// + d5p//3eaf/93m3//d5t//3ebf/93m3//d5uA/3ebgP93m4D/d5uA/3ecgf93nIH/d5yB/3ecgf98rp3/ + fK6d/3yunf98rp3/ftH6/37R+v9+0fr/ftH6/zOBaP8zgWj/M4Fo/zOBaP8iZDL/ImQy/yJkMv8iZDL/ + LYJB/y2CQf8tgkH/LYJB/y+JRf8viUX/L4lF/y+JRf+Bt47/gbeO/4G3jv+Bt47/gbeO/4G3jv+Bt47/ + gbeO/4G3jv+Bt47/gbeO/4G3jv+Cvqf/gr6n/4K+p/+Cvqf/h9T7/4fU+/+H1Pv/h9T7/3mkmP95pJj/ + eaSY/3mkmP9zj3r/c496/3OPev9zj3r/c5B6/3OQev9zkHr/c5B6/3ORev9zkXr/c5F6/3ORev90knv/ + dJJ7/3SSe/90knv/dJJ7/3SSe/90knv/dJJ7/3iWgP94loD/eJaA/3iWgP/t8Oz/7fDs/+3w7P/t8Oz/ + 1N7W/9Te1v/U3tb/1N7W/7/Nwv+/zcL/v83C/7/Nwv+/zcL/v83C/7/Nwv+/zcL/v87C/7/Owv+/zsL/ + v87C/7/Owv+/zsL/v87C/7/Owv/V39f/1d/X/9Xf1//V39f/7fDt/+3w7f/t8O3/7fDt/3qcg/96nIP/ + epyD/3qcg/92mX//dpl//3aZf/92mX//d5p//3eaf/93mn//d5p//3ebf/93m3//d5t//3ebf/93m4D/ + d5uA/3ebgP93m4D/d5yB/3ecgf93nIH/d5yB/3yunf98rp3/fK6d/3yunf9+0fr/ftH6/37R+v9+0fr/ + M4Fo/zOBaP8zgWj/M4Fo/yJkMv8iZDL/ImQy/yJkMv8tgkH/LYJB/y2CQf8tgkH/L4lF/y+JRf8viUX/ + L4lF/4G3jv+Bt47/gbeO/4G3jv+Bt47/gbeO/4G3jv+Bt47/gbeO/4G3jv+Bt47/gbeO/4K+p/+Cvqf/ + gr6n/4K+p/+H1Pv/h9T7/4fU+/+H1Pv/eaSY/3mkmP95pJj/eaSY/3OPev9zj3r/c496/3OPev9zkHr/ + c5B6/3OQev9zkHr/c5F6/3ORev9zkXr/c5F6/3SSe/90knv/dJJ7/3SSe/90knv/dJJ7/3SSe/90knv/ + eJaA/3iWgP94loD/eJaA/+3w7P/t8Oz/7fDs/+3w7P/U3tb/1N7W/9Te1v/U3tb/v83C/7/Nwv+/zcL/ + v83C/7/Nwv+/zcL/v83C/7/Nwv+/zsL/v87C/7/Owv+/zsL/v87C/7/Owv+/zsL/v87C/9Xf1//V39f/ + 1d/X/9Xf1//t8O3/7fDt/+3w7f/t8O3/epyD/3qcg/96nIP/epyD/3aZf/92mX//dpl//3aZf/93mn// + d5p//3eaf/93mn//d5t//3ebf/93m3//d5t//3ebgP93m4D/d5uA/3ebgP93nIH/d5yB/3ecgf93nIH/ + fK6d/3yunf98rp3/fK6d/37R+v9+0fr/ftH6/37R+v8zgWj/M4Fo/zOBaP8zgWj/ImQy/yJkMv8iZDL/ + ImQy/y2CQf8tgkH/LYJB/y2CQf8viUX/L4lF/y+JRf8viUX/gbeO/4G3jv+Bt47/gbeO/4G3jv+Bt47/ + gbeO/4G3jv+Bt47/gbeO/4G3jv+Bt47/gr6n/4K+p/+Cvqf/gr6n/4fU+/+H1Pv/h9T7/4fU+/95pJj/ + eaSY/3mkmP95pJj/c496/3OPev9zj3r/c496/3OQev9zkHr/c5B6/3OQev9zkXr/c5F6/3ORev9zkXr/ + dJJ7/3SSe/90knv/dJJ7/3SSe/90knv/dJJ7/3SSe/94loD/eJaA/3iWgP94loD/7fDs/+3w7P/t8Oz/ + 7fDs/9Te1v/U3tb/1N7W/9Te1v+/zcL/v83C/7/Nwv+/zcL/v83C/7/Nwv+/zcL/v83C/7/Owv+/zsL/ + v87C/7/Owv+/zsL/v87C/7/Owv+/zsL/1d/X/9Xf1//V39f/1d/X/+3w7f/t8O3/7fDt/+3w7f96nIP/ + epyD/3qcg/96nIP/dpl//3aZf/92mX//dpl//3eaf/93mn//d5p//3eaf/93m3//d5t//3ebf/93m3// + d5uA/3ebgP93m4D/d5uA/3ecgf93nIH/d5yB/3ecgf98rp3/fK6d/3yunf98rp3/ftH6/37R+v9+0fr/ + ftH6/zOBaP8zgWj/M4Fo/zOBaP8iZDL/ImQy/yJkMv8iZDL/LYJB/y2CQf8tgkH/LYJB/y+JRf8viUX/ + L4lF/y+JRf+EuZH/hLmR/4S5kf+EuZH/hLmR/4S5kf+EuZH/hLmR/4S5kf+EuZH/hLmR/4S5kf+FwKz/ + hcCs/4XArP+FwKz/idb7/4nW+/+J1vv/idb7/32qof99qqH/faqh/32qof92kXz/dpF8/3aRfP92kXz/ + dpJ9/3aSff92kn3/dpJ9/3aTfv92k37/dpN+/3aTfv92k37/dpN+/3aTfv92k37/dpR+/3aUfv92lH7/ + dpR+/3eUfv93lH7/d5R+/3eUfv+Cnor/gp6K/4Keiv+Cnor/tca5/7XGuf+1xrn/tca5/8DOw//AzsP/ + wM7D/8DOw//Az8P/wM/D/8DPw//Az8P/wM/E/8DPxP/Az8T/wM/E/8DPxP/Az8T/wM/E/8DPxP+2yLr/ + tsi6/7bIuv+2yLr/hKOL/4Sji/+Eo4v/hKOL/3mbgv95m4L/eZuC/3mbgv95m4L/eZuC/3mbgv95m4L/ + eZyC/3mcgv95nIL/eZyC/3mdgv95nYL/eZ2C/3mdgv96nYP/ep2D/3qdg/96nYP/ep6D/3qeg/96noP/ + ep6D/4Cypf+AsqX/gLKl/4Cypf+J1vv/idb7/4nW+/+J1vv/dKyc/3SsnP90rJz/dKyc/zSGSv80hkr/ + NIZK/zSGSv8wikf/MIpH/zCKR/8wikf/MIpH/zCKR/8wikf/MIpH/4S5kf+EuZH/hLmR/4S5kf+EuZH/ + hLmR/4S5kf+EuZH/hLmR/4S5kf+EuZH/hLmR/4XArP+FwKz/hcCs/4XArP+J1vv/idb7/4nW+/+J1vv/ + faqh/32qof99qqH/faqh/3aRfP92kXz/dpF8/3aRfP92kn3/dpJ9/3aSff92kn3/dpN+/3aTfv92k37/ + dpN+/3aTfv92k37/dpN+/3aTfv92lH7/dpR+/3aUfv92lH7/d5R+/3eUfv93lH7/d5R+/4Keiv+Cnor/ + gp6K/4Keiv+1xrn/tca5/7XGuf+1xrn/wM7D/8DOw//AzsP/wM7D/8DPw//Az8P/wM/D/8DPw//Az8T/ + wM/E/8DPxP/Az8T/wM/E/8DPxP/Az8T/wM/E/7bIuv+2yLr/tsi6/7bIuv+Eo4v/hKOL/4Sji/+Eo4v/ + eZuC/3mbgv95m4L/eZuC/3mbgv95m4L/eZuC/3mbgv95nIL/eZyC/3mcgv95nIL/eZ2C/3mdgv95nYL/ + eZ2C/3qdg/96nYP/ep2D/3qdg/96noP/ep6D/3qeg/96noP/gLKl/4Cypf+AsqX/gLKl/4nW+/+J1vv/ + idb7/4nW+/90rJz/dKyc/3SsnP90rJz/NIZK/zSGSv80hkr/NIZK/zCKR/8wikf/MIpH/zCKR/8wikf/ + MIpH/zCKR/8wikf/hLmR/4S5kf+EuZH/hLmR/4S5kf+EuZH/hLmR/4S5kf+EuZH/hLmR/4S5kf+EuZH/ + hcCs/4XArP+FwKz/hcCs/4nW+/+J1vv/idb7/4nW+/99qqH/faqh/32qof99qqH/dpF8/3aRfP92kXz/ + dpF8/3aSff92kn3/dpJ9/3aSff92k37/dpN+/3aTfv92k37/dpN+/3aTfv92k37/dpN+/3aUfv92lH7/ + dpR+/3aUfv93lH7/d5R+/3eUfv93lH7/gp6K/4Keiv+Cnor/gp6K/7XGuf+1xrn/tca5/7XGuf/AzsP/ + wM7D/8DOw//AzsP/wM/D/8DPw//Az8P/wM/D/8DPxP/Az8T/wM/E/8DPxP/Az8T/wM/E/8DPxP/Az8T/ + tsi6/7bIuv+2yLr/tsi6/4Sji/+Eo4v/hKOL/4Sji/95m4L/eZuC/3mbgv95m4L/eZuC/3mbgv95m4L/ + eZuC/3mcgv95nIL/eZyC/3mcgv95nYL/eZ2C/3mdgv95nYL/ep2D/3qdg/96nYP/ep2D/3qeg/96noP/ + ep6D/3qeg/+AsqX/gLKl/4Cypf+AsqX/idb7/4nW+/+J1vv/idb7/3SsnP90rJz/dKyc/3SsnP80hkr/ + NIZK/zSGSv80hkr/MIpH/zCKR/8wikf/MIpH/zCKR/8wikf/MIpH/zCKR/+EuZH/hLmR/4S5kf+EuZH/ + hLmR/4S5kf+EuZH/hLmR/4S5kf+EuZH/hLmR/4S5kf+FwKz/hcCs/4XArP+FwKz/idb7/4nW+/+J1vv/ + idb7/32qof99qqH/faqh/32qof92kXz/dpF8/3aRfP92kXz/dpJ9/3aSff92kn3/dpJ9/3aTfv92k37/ + dpN+/3aTfv92k37/dpN+/3aTfv92k37/dpR+/3aUfv92lH7/dpR+/3eUfv93lH7/d5R+/3eUfv+Cnor/ + gp6K/4Keiv+Cnor/tca5/7XGuf+1xrn/tca5/8DOw//AzsP/wM7D/8DOw//Az8P/wM/D/8DPw//Az8P/ + wM/E/8DPxP/Az8T/wM/E/8DPxP/Az8T/wM/E/8DPxP+2yLr/tsi6/7bIuv+2yLr/hKOL/4Sji/+Eo4v/ + hKOL/3mbgv95m4L/eZuC/3mbgv95m4L/eZuC/3mbgv95m4L/eZyC/3mcgv95nIL/eZyC/3mdgv95nYL/ + eZ2C/3mdgv96nYP/ep2D/3qdg/96nYP/ep6D/3qeg/96noP/ep6D/4Cypf+AsqX/gLKl/4Cypf+J1vv/ + idb7/4nW+/+J1vv/dKyc/3SsnP90rJz/dKyc/zSGSv80hkr/NIZK/zSGSv8wikf/MIpH/zCKR/8wikf/ + MIpH/zCKR/8wikf/MIpH/4e8lf+HvJX/h7yV/4e8lf+HvJX/h7yV/4e8lf+HvJX/h7yV/4e8lf+HvJX/ + h7yV/4i/oP+Iv6D/iL+g/4i/oP+M1vX/jNb1/4zW9f+M1vX/jdj6/43Y+v+N2Pr/jdj6/4rM2/+KzNv/ + iszb/4rM2/+Fu7v/hbu7/4W7u/+Fu7v/gKmc/4CpnP+AqZz/gKmc/3uYg/97mIP/e5iD/3uYg/96l4L/ + epeC/3qXgv96l4L/e5eC/3uXgv97l4L/e5eC/3uYgv97mIL/e5iC/3uYgv97mIL/e5iC/3uYgv97mIL/ + e5mD/3uZg/97mYP/e5mD/3uZg/97mYP/e5mD/3uZg/98moP/fJqD/3yag/98moP/fJuE/3ybhP98m4T/ + fJuE/3ychP98nIT/fJyE/3ychP98nIX/fJyF/3ychf98nIX/fJ2F/3ydhf98nYX/fJ2F/32dhf99nYX/ + fZ2F/32dhf9+oIf/fqCH/36gh/9+oIf/gq6g/4KuoP+CrqD/gq6g/4a/vP+Gv7z/hr+8/4a/vP+Kzdz/ + is3c/4rN3P+Kzdz/jdj6/43Y+v+N2Pr/jdj6/43W9f+N1vX/jdb1/43W9f+HvqH/h76h/4e+of+HvqH/ + drKF/3ayhf92soX/drKF/zOMSv8zjEr/M4xK/zOMSv8xi0j/MYtI/zGLSP8xi0j/h7yV/4e8lf+HvJX/ + h7yV/4e8lf+HvJX/h7yV/4e8lf+HvJX/h7yV/4e8lf+HvJX/iL+g/4i/oP+Iv6D/iL+g/4zW9f+M1vX/ + jNb1/4zW9f+N2Pr/jdj6/43Y+v+N2Pr/iszb/4rM2/+KzNv/iszb/4W7u/+Fu7v/hbu7/4W7u/+AqZz/ + gKmc/4CpnP+AqZz/e5iD/3uYg/97mIP/e5iD/3qXgv96l4L/epeC/3qXgv97l4L/e5eC/3uXgv97l4L/ + e5iC/3uYgv97mIL/e5iC/3uYgv97mIL/e5iC/3uYgv97mYP/e5mD/3uZg/97mYP/e5mD/3uZg/97mYP/ + e5mD/3yag/98moP/fJqD/3yag/98m4T/fJuE/3ybhP98m4T/fJyE/3ychP98nIT/fJyE/3ychf98nIX/ + fJyF/3ychf98nYX/fJ2F/3ydhf98nYX/fZ2F/32dhf99nYX/fZ2F/36gh/9+oIf/fqCH/36gh/+CrqD/ + gq6g/4KuoP+CrqD/hr+8/4a/vP+Gv7z/hr+8/4rN3P+Kzdz/is3c/4rN3P+N2Pr/jdj6/43Y+v+N2Pr/ + jdb1/43W9f+N1vX/jdb1/4e+of+HvqH/h76h/4e+of92soX/drKF/3ayhf92soX/M4xK/zOMSv8zjEr/ + M4xK/zGLSP8xi0j/MYtI/zGLSP+HvJX/h7yV/4e8lf+HvJX/h7yV/4e8lf+HvJX/h7yV/4e8lf+HvJX/ + h7yV/4e8lf+Iv6D/iL+g/4i/oP+Iv6D/jNb1/4zW9f+M1vX/jNb1/43Y+v+N2Pr/jdj6/43Y+v+KzNv/ + iszb/4rM2/+KzNv/hbu7/4W7u/+Fu7v/hbu7/4CpnP+AqZz/gKmc/4CpnP97mIP/e5iD/3uYg/97mIP/ + epeC/3qXgv96l4L/epeC/3uXgv97l4L/e5eC/3uXgv97mIL/e5iC/3uYgv97mIL/e5iC/3uYgv97mIL/ + e5iC/3uZg/97mYP/e5mD/3uZg/97mYP/e5mD/3uZg/97mYP/fJqD/3yag/98moP/fJqD/3ybhP98m4T/ + fJuE/3ybhP98nIT/fJyE/3ychP98nIT/fJyF/3ychf98nIX/fJyF/3ydhf98nYX/fJ2F/3ydhf99nYX/ + fZ2F/32dhf99nYX/fqCH/36gh/9+oIf/fqCH/4KuoP+CrqD/gq6g/4KuoP+Gv7z/hr+8/4a/vP+Gv7z/ + is3c/4rN3P+Kzdz/is3c/43Y+v+N2Pr/jdj6/43Y+v+N1vX/jdb1/43W9f+N1vX/h76h/4e+of+HvqH/ + h76h/3ayhf92soX/drKF/3ayhf8zjEr/M4xK/zOMSv8zjEr/MYtI/zGLSP8xi0j/MYtI/4e8lf+HvJX/ + h7yV/4e8lf+HvJX/h7yV/4e8lf+HvJX/h7yV/4e8lf+HvJX/h7yV/4i/oP+Iv6D/iL+g/4i/oP+M1vX/ + jNb1/4zW9f+M1vX/jdj6/43Y+v+N2Pr/jdj6/4rM2/+KzNv/iszb/4rM2/+Fu7v/hbu7/4W7u/+Fu7v/ + gKmc/4CpnP+AqZz/gKmc/3uYg/97mIP/e5iD/3uYg/96l4L/epeC/3qXgv96l4L/e5eC/3uXgv97l4L/ + e5eC/3uYgv97mIL/e5iC/3uYgv97mIL/e5iC/3uYgv97mIL/e5mD/3uZg/97mYP/e5mD/3uZg/97mYP/ + e5mD/3uZg/98moP/fJqD/3yag/98moP/fJuE/3ybhP98m4T/fJuE/3ychP98nIT/fJyE/3ychP98nIX/ + fJyF/3ychf98nIX/fJ2F/3ydhf98nYX/fJ2F/32dhf99nYX/fZ2F/32dhf9+oIf/fqCH/36gh/9+oIf/ + gq6g/4KuoP+CrqD/gq6g/4a/vP+Gv7z/hr+8/4a/vP+Kzdz/is3c/4rN3P+Kzdz/jdj6/43Y+v+N2Pr/ + jdj6/43W9f+N1vX/jdb1/43W9f+HvqH/h76h/4e+of+HvqH/drKF/3ayhf92soX/drKF/zOMSv8zjEr/ + M4xK/zOMSv8xi0j/MYtI/zGLSP8xi0j/ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ + ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/4rBof+KwaH/isGh/4rBof+NysX/jcrF/43Kxf+NysX/ + jtPk/47T5P+O0+T/jtPk/4/Z+v+P2fr/j9n6/4/Z+v+P2fr/j9n6/4/Z+v+P2fr/j9j4/4/Y+P+P2Pj/ + j9j4/47U7P+O1Oz/jtTs/47U7P+Nz93/jc/d/43P3f+Nz93/i8fO/4vHzv+Lx87/i8fO/4rEx/+KxMf/ + isTH/4rEx/+JwcH/icHB/4nBwf+JwcH/ib68/4m+vP+Jvrz/ib68/4m/vP+Jv7z/ib+8/4m/vP+JwsL/ + icLC/4nCwv+JwsL/isTH/4rEx/+KxMf/isTH/4vJz/+Lyc//i8nP/4vJz/+Nz93/jc/d/43P3f+Nz93/ + jtTs/47U7P+O1Oz/jtTs/4/Y+P+P2Pj/j9j4/4/Y+P+P2fr/j9n6/4/Z+v+P2fr/j9n6/4/Z+v+P2fr/ + j9n6/47T5v+O0+b/jtPm/47T5v+My8j/jMvI/4zLyP+My8j/i8Ch/4vAof+LwKH/i8Ch/4q+mP+Kvpj/ + ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/Z6t4/2ereP9nq3j/Z6t4/zKNSf8yjUn/Mo1J/zKNSf+Kvpj/ + ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ + isGh/4rBof+KwaH/isGh/43Kxf+NysX/jcrF/43Kxf+O0+T/jtPk/47T5P+O0+T/j9n6/4/Z+v+P2fr/ + j9n6/4/Z+v+P2fr/j9n6/4/Z+v+P2Pj/j9j4/4/Y+P+P2Pj/jtTs/47U7P+O1Oz/jtTs/43P3f+Nz93/ + jc/d/43P3f+Lx87/i8fO/4vHzv+Lx87/isTH/4rEx/+KxMf/isTH/4nBwf+JwcH/icHB/4nBwf+Jvrz/ + ib68/4m+vP+Jvrz/ib+8/4m/vP+Jv7z/ib+8/4nCwv+JwsL/icLC/4nCwv+KxMf/isTH/4rEx/+KxMf/ + i8nP/4vJz/+Lyc//i8nP/43P3f+Nz93/jc/d/43P3f+O1Oz/jtTs/47U7P+O1Oz/j9j4/4/Y+P+P2Pj/ + j9j4/4/Z+v+P2fr/j9n6/4/Z+v+P2fr/j9n6/4/Z+v+P2fr/jtPm/47T5v+O0+b/jtPm/4zLyP+My8j/ + jMvI/4zLyP+LwKH/i8Ch/4vAof+LwKH/ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/4q+mP9nq3j/ + Z6t4/2ereP9nq3j/Mo1J/zKNSf8yjUn/Mo1J/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ + ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+KwaH/isGh/4rBof+KwaH/jcrF/43Kxf+NysX/ + jcrF/47T5P+O0+T/jtPk/47T5P+P2fr/j9n6/4/Z+v+P2fr/j9n6/4/Z+v+P2fr/j9n6/4/Y+P+P2Pj/ + j9j4/4/Y+P+O1Oz/jtTs/47U7P+O1Oz/jc/d/43P3f+Nz93/jc/d/4vHzv+Lx87/i8fO/4vHzv+KxMf/ + isTH/4rEx/+KxMf/icHB/4nBwf+JwcH/icHB/4m+vP+Jvrz/ib68/4m+vP+Jv7z/ib+8/4m/vP+Jv7z/ + icLC/4nCwv+JwsL/icLC/4rEx/+KxMf/isTH/4rEx/+Lyc//i8nP/4vJz/+Lyc//jc/d/43P3f+Nz93/ + jc/d/47U7P+O1Oz/jtTs/47U7P+P2Pj/j9j4/4/Y+P+P2Pj/j9n6/4/Z+v+P2fr/j9n6/4/Z+v+P2fr/ + j9n6/4/Z+v+O0+b/jtPm/47T5v+O0+b/jMvI/4zLyP+My8j/jMvI/4vAof+LwKH/i8Ch/4vAof+Kvpj/ + ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/2ereP9nq3j/Z6t4/2ereP8yjUn/Mo1J/zKNSf8yjUn/ + ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ + ir6Y/4rBof+KwaH/isGh/4rBof+NysX/jcrF/43Kxf+NysX/jtPk/47T5P+O0+T/jtPk/4/Z+v+P2fr/ + j9n6/4/Z+v+P2fr/j9n6/4/Z+v+P2fr/j9j4/4/Y+P+P2Pj/j9j4/47U7P+O1Oz/jtTs/47U7P+Nz93/ + jc/d/43P3f+Nz93/i8fO/4vHzv+Lx87/i8fO/4rEx/+KxMf/isTH/4rEx/+JwcH/icHB/4nBwf+JwcH/ + ib68/4m+vP+Jvrz/ib68/4m/vP+Jv7z/ib+8/4m/vP+JwsL/icLC/4nCwv+JwsL/isTH/4rEx/+KxMf/ + isTH/4vJz/+Lyc//i8nP/4vJz/+Nz93/jc/d/43P3f+Nz93/jtTs/47U7P+O1Oz/jtTs/4/Y+P+P2Pj/ + j9j4/4/Y+P+P2fr/j9n6/4/Z+v+P2fr/j9n6/4/Z+v+P2fr/j9n6/47T5v+O0+b/jtPm/47T5v+My8j/ + jMvI/4zLyP+My8j/i8Ch/4vAof+LwKH/i8Ch/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ + Z6t4/2ereP9nq3j/Z6t4/zKNSf8yjUn/Mo1J/zKNSf+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcKj/43Co/+NwqP/jcKj/4/Iuf+PyLn/j8i5/4/Iuf+Pzcn/ + j83J/4/Nyf+Pzcn/kNHZ/5DR2f+Q0dn/kNHZ/5HV6P+R1ej/kdXo/5HV6P+R1/L/kdfy/5HX8v+R1/L/ + kdn2/5HZ9v+R2fb/kdn2/5La+v+S2vr/ktr6/5La+v+S2vv/ktr7/5La+/+S2vv/ktr7/5La+/+S2vv/ + ktr7/5La+v+S2vr/ktr6/5La+v+R2fb/kdn2/5HZ9v+R2fb/kdfy/5HX8v+R1/L/kdfy/5HV6P+R1ej/ + kdXo/5HV6P+Q0dj/kNHY/5DR2P+Q0dj/j8zI/4/MyP+PzMj/j8zI/4/Iuf+PyLn/j8i5/4/Iuf+NwqP/ + jcKj/43Co/+NwqP/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/VKFp/1Shaf9UoWn/ + VKFp/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwqP/ + jcKj/43Co/+NwqP/j8i5/4/Iuf+PyLn/j8i5/4/Nyf+Pzcn/j83J/4/Nyf+Q0dn/kNHZ/5DR2f+Q0dn/ + kdXo/5HV6P+R1ej/kdXo/5HX8v+R1/L/kdfy/5HX8v+R2fb/kdn2/5HZ9v+R2fb/ktr6/5La+v+S2vr/ + ktr6/5La+/+S2vv/ktr7/5La+/+S2vv/ktr7/5La+/+S2vv/ktr6/5La+v+S2vr/ktr6/5HZ9v+R2fb/ + kdn2/5HZ9v+R1/L/kdfy/5HX8v+R1/L/kdXo/5HV6P+R1ej/kdXo/5DR2P+Q0dj/kNHY/5DR2P+PzMj/ + j8zI/4/MyP+PzMj/j8i5/4/Iuf+PyLn/j8i5/43Co/+NwqP/jcKj/43Co/+NwJv/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwJv/jcCb/43Am/9UoWn/VKFp/1Shaf9UoWn/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Co/+NwqP/jcKj/43Co/+PyLn/j8i5/4/Iuf+PyLn/ + j83J/4/Nyf+Pzcn/j83J/5DR2f+Q0dn/kNHZ/5DR2f+R1ej/kdXo/5HV6P+R1ej/kdfy/5HX8v+R1/L/ + kdfy/5HZ9v+R2fb/kdn2/5HZ9v+S2vr/ktr6/5La+v+S2vr/ktr7/5La+/+S2vv/ktr7/5La+/+S2vv/ + ktr7/5La+/+S2vr/ktr6/5La+v+S2vr/kdn2/5HZ9v+R2fb/kdn2/5HX8v+R1/L/kdfy/5HX8v+R1ej/ + kdXo/5HV6P+R1ej/kNHY/5DR2P+Q0dj/kNHY/4/MyP+PzMj/j8zI/4/MyP+PyLn/j8i5/4/Iuf+PyLn/ + jcKj/43Co/+NwqP/jcKj/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/1Shaf9UoWn/ + VKFp/1Shaf+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/ + jcKj/43Co/+NwqP/jcKj/4/Iuf+PyLn/j8i5/4/Iuf+Pzcn/j83J/4/Nyf+Pzcn/kNHZ/5DR2f+Q0dn/ + kNHZ/5HV6P+R1ej/kdXo/5HV6P+R1/L/kdfy/5HX8v+R1/L/kdn2/5HZ9v+R2fb/kdn2/5La+v+S2vr/ + ktr6/5La+v+S2vv/ktr7/5La+/+S2vv/ktr7/5La+/+S2vv/ktr7/5La+v+S2vr/ktr6/5La+v+R2fb/ + kdn2/5HZ9v+R2fb/kdfy/5HX8v+R1/L/kdfy/5HV6P+R1ej/kdXo/5HV6P+Q0dj/kNHY/5DR2P+Q0dj/ + j8zI/4/MyP+PzMj/j8zI/4/Iuf+PyLn/j8i5/4/Iuf+NwqP/jcKj/43Co/+NwqP/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/VKFp/1Shaf9UoWn/VKFp/4zAmvGMwJrxjMCa8YzAmvGQwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKe/5DCnv+Qwp7/kMKe/5DEo/+QxKP/kMSj/5DEo/+QxKL/ + kMSi/5DEov+QxKL/kMKe/5DCnv+Qwp7/kMKe/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+NwZrx + jcGa8Y3BmvGNwZrxjMCa8YzAmvGMwJrxjMCa8ZDCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp7/ + kMKe/5DCnv+Qwp7/kMSj/5DEo/+QxKP/kMSj/5DEov+QxKL/kMSi/5DEov+Qwp7/kMKe/5DCnv+Qwp7/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/43BmvGNwZrxjcGa8Y3BmvGMwJrxjMCa8YzAmvGMwJrx + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnv+Qwp7/kMKe/5DCnv+QxKP/kMSj/5DEo/+QxKP/ + kMSi/5DEov+QxKL/kMSi/5DCnv+Qwp7/kMKe/5DCnv+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + jcGa8Y3BmvGNwZrxjcGa8YzAmvGMwJrxjMCa8YzAmvGQwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKe/5DCnv+Qwp7/kMKe/5DEo/+QxKP/kMSj/5DEo/+QxKL/kMSi/5DEov+QxKL/kMKe/5DCnv+Qwp7/ + kMKe/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+NwZrxjcGa8Y3BmvGNwZrxhr6XxIa+l8SGvpfE + hr6XxJTFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/4/CncaPwp3Gj8Kdxo/CncaGvpfEhr6XxIa+l8SGvpfElMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/j8Kdxo/CncaPwp3Gj8Kdxoa+l8SGvpfE + hr6XxIa+l8SUxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+Pwp3Gj8Kdxo/CncaPwp3Ghr6XxIa+l8SGvpfEhr6XxJTFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/4/CncaPwp3Gj8Kdxo/CncZ8u48p + fLuPKXy7jyl8u48pk8ag9ZPGoPWTxqD1k8ag9ZbHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+YyKX2 + mMil9pjIpfaYyKX2mceoMpnHqDKZx6gymceoMny7jyl8u48pfLuPKXy7jymTxqD1k8ag9ZPGoPWTxqD1 + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5jIpfaYyKX2mMil9pjIpfaZx6gymceoMpnHqDKZx6gy + fLuPKXy7jyl8u48pfLuPKZPGoPWTxqD1k8ag9ZPGoPWWx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + mMil9pjIpfaYyKX2mMil9pnHqDKZx6gymceoMpnHqDJ8u48pfLuPKXy7jyl8u48pk8ag9ZPGoPWTxqD1 + k8ag9ZbHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+YyKX2mMil9pjIpfaYyKX2mceoMpnHqDKZx6gy + mceoMgAAAAAAAAAAAAAAAAAAAAB8u48pfLuPKXy7jyl8u48pjMKbxYzCm8WMwpvFjMKbxZbHo/KWx6Py + lsej8pbHo/KZyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+ayafzmsmn85rJp/OayafzlsaiyZbGosmWxqLJ + lsaiyZvIqjObyKozm8iqM5vIqjMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHy7jyl8u48p + fLuPKXy7jymMwpvFjMKbxYzCm8WMwpvFlsej8pbHo/KWx6Pylsej8pnJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5rJp/Oayafzmsmn85rJp/OWxqLJlsaiyZbGosmWxqLJm8iqM5vIqjObyKozm8iqMwAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfLuPKXy7jyl8u48pfLuPKYzCm8WMwpvFjMKbxYzCm8WWx6Py + lsej8pbHo/KWx6Pymcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/msmn85rJp/Oayafzmsmn85bGosmWxqLJ + lsaiyZbGosmbyKozm8iqM5vIqjObyKozAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB8u48p + fLuPKXy7jyl8u48pjMKbxYzCm8WMwpvFjMKbxZbHo/KWx6Pylsej8pbHo/KZyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+ayafzmsmn85rJp/OayafzlsaiyZbGosmWxqLJlsaiyZvIqjObyKozm8iqM5vIqjMAAAAA + AAAAAAAAAAAAAAAA8AAAAAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAAAP + 8AAAAAAAAAAAAAAAAAAADwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAPAAAAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAA + AAAAD/AAAAAAAAAAAAAAAAAAAA8oAAAAQAAAAIAAAAABACAAAAAAAABAAAATCwAAEwsAAAAAAAAAAAAA + AAAAAAAAAAAbZCQcG2QkHB1nJqkdZyapHGcm5xxnJuccZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/ + HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/ + HGcm/xxnJv8YWiH/GFoh/xZSHv8WUh7/F1Mf/xdTH/8XVB//F1Qf/xdUH/8XVB//F1Yg/xdWIP8XViD/ + F1Yg/xhXIP8YVyD/GFgg/xhYIP8YWSH/GFkh/xhaIf8YWiH/GVoh/xlaIf8YXCLpGFwi6RpcIq8aXCKv + GVohHxlaIR8AAAAAAAAAAAAAAAAAAAAAG2QkHBtkJBwdZyapHWcmqRxnJuccZybnHGcm/xxnJv8cZyb/ + HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/ + HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/GFoh/xhaIf8WUh7/FlIe/xdTH/8XUx//F1Qf/xdUH/8XVB// + F1Qf/xdWIP8XViD/F1Yg/xdWIP8YVyD/GFcg/xhYIP8YWCD/GFkh/xhZIf8YWiH/GFoh/xlaIf8ZWiH/ + GFwi6RhcIukaXCKvGlwirxlaIR8ZWiEfAAAAAAAAAAAbZCQcG2QkHB1oJ+0daCftHWgn/x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8ZWiL/GVoi/xdRHv8XUR7/F1If/xdSH/8XUx// + F1Mf/xdUH/8XVB//GFQg/xhUIP8YVSD/GFUg/xhWIP8YViD/GFch/xhXIf8ZWCH/GVgh/xlZIf8ZWSH/ + GVoi/xlaIv8ZWyL/GVsi/xlbIv8ZWyL/Glwj/xpcI/8aXSLvGl0i7xlaIR8ZWiEfG2QkHBtkJBwdaCft + HWgn7R1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/GVoi/xlaIv8XUR7/ + F1Ee/xdSH/8XUh//F1Mf/xdTH/8XVB//F1Qf/xhUIP8YVCD/GFUg/xhVIP8YViD/GFYg/xhXIf8YVyH/ + GVgh/xlYIf8ZWSH/GVkh/xlaIv8ZWiL/GVsi/xlbIv8ZWyL/GVsi/xpcI/8aXCP/Gl0i7xpdIu8ZWiEf + GVohHx5qKakeaimpHmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8aWyL/ + Glsi/xdRH/8XUR//F1If/xdSH/8XUx//F1Mf/xhUIP8YVCD/GFQg/xhUIP8YVSD/GFUg/xhWIP8YViD/ + GVch/xlXIf8ZWCH/GVgh/xlZIv8ZWSL/GVoi/xlaIv8aWyL/Glsi/xpbI/8aWyP/Glwj/xpcI/8aXSP/ + Gl0j/xteI/8bXiP/HF8krxxfJK8eaimpHmopqR5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Glsi/xpbIv8XUR//F1Ef/xdSH/8XUh//F1Mf/xdTH/8YVCD/GFQg/xhUIP8YVCD/ + GFUg/xhVIP8YViD/GFYg/xlXIf8ZVyH/GVgh/xlYIf8ZWSL/GVki/xlaIv8ZWiL/Glsi/xpbIv8aWyP/ + Glsj/xpcI/8aXCP/Gl0j/xpdI/8bXiP/G14j/xxfJK8cXySvH2sq6B9rKugfayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8aWyT/Glsk/xdQH/8XUB//Hmlg/x5pYP8eamD/Hmpg/xhTIP8YUyD/ + GFQh/xhUIf8YVCH/GFQh/xlVIf8ZVSH/GVYi/xlWIv8ZVyL/GVci/xlYIv8ZWCL/Glkj/xpZI/8aWiP/ + Gloj/xpbJP8aWyT/G1sk/xtbJP8bXCT/G1wk/xtdJf8bXSX/G14l/xteJf8bXyXpG18l6R9rKugfayro + H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/Glsk/xpbJP8XUB//F1Af/x5pYP8eaWD/ + Hmpg/x5qYP8YUyD/GFMg/xhUIf8YVCH/GFQh/xhUIf8ZVSH/GVUh/xlWIv8ZViL/GVci/xlXIv8ZWCL/ + GVgi/xpZI/8aWSP/Gloj/xpaI/8aWyT/Glsk/xtbJP8bWyT/G1wk/xtcJP8bXSX/G10l/xteJf8bXiX/ + G18l6RtfJekgbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8bWyT/G1sk/x5oWv8eaFr/ + JYKy/yWCsv8pk9//KZPf/ymT3/8pk9//JYKu/yWCrv8eZ1T/HmdU/xlVIv8ZVSL/GVYi/xlWIv8ZVyL/ + GVci/xpYI/8aWCP/Glgj/xpYI/8aWSP/Glkj/xtbJP8bWyT/G1sk/xtbJP8bXCT/G1wk/xtdJf8bXSX/ + HF4l/xxeJf8cXyX/HF8l/xxgJv8cYCb/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + G1sk/xtbJP8eaFr/Hmha/yWCsv8lgrL/KZPf/ymT3/8pk9//KZPf/yWCrv8lgq7/HmdU/x5nVP8ZVSL/ + GVUi/xlWIv8ZViL/GVci/xlXIv8aWCP/Glgj/xpYI/8aWCP/Glkj/xpZI/8bWyT/G1sk/xtbJP8bWyT/ + G1wk/xtcJP8bXSX/G10l/xxeJf8cXiX/HF8l/xxfJf8cYCb/HGAm/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/yBuLf8dZUD/HWVA/ySBp/8kgaf/KZTf/ymU3/8upPf/LqT3/y+o/f8vqP3/L6j9/y+o/f8upPf/ + LqT3/ymU3/8plN//JICl/ySApf8cYkL/HGJC/xlXI/8ZVyP/GVgk/xlYJP8aWCT/Glgk/xpZJf8aWSX/ + Glol/xpaJf8bWyX/G1sl/xtcJv8bXCb/G10m/xtdJv8bXib/G14m/xxfJ/8cXyf/HGAn/xxgJ/8gbi3/ + IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/HWVA/x1lQP8kgaf/JIGn/ymU3/8plN//LqT3/y6k9/8vqP3/ + L6j9/y+o/f8vqP3/LqT3/y6k9/8plN//KZTf/ySApf8kgKX/HGJC/xxiQv8ZVyP/GVcj/xlYJP8ZWCT/ + Glgk/xpYJP8aWSX/Glkl/xpaJf8aWiX/G1sl/xtbJf8bXCb/G1wm/xtdJv8bXSb/G14m/xteJv8cXyf/ + HF8n/xxgJ/8cYCf/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/ + IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXEv/yFxL/8kfH7/JHx+/ymR1P8pkdT/L6X2/y+l9v8wqfz/ + MKn8/yybzf8sm83/IG5a/yBuWv8gbFj/IGxY/yyazP8smsz/MKn8/zCp/P8vpfb/L6X2/yqR1P8qkdT/ + IHRx/yB0cf8aWCT/Glgk/xpZJf8aWSX/G1ol/xtaJf8bWyX/G1sl/xtcJv8bXCb/G10m/xtdJv8cXif/ + HF4n/xxfJ/8cXyf/HGAn/xxgJ/8cYSj/HGEo/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/ + IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFxL/8hcS//JHx+/yR8fv8pkdT/ + KZHU/y+l9v8vpfb/MKn8/zCp/P8sm83/LJvN/yBuWv8gblr/IGxY/yBsWP8smsz/LJrM/zCp/P8wqfz/ + L6X2/y+l9v8qkdT/KpHU/yB0cf8gdHH/Glgk/xpYJP8aWSX/Glkl/xtaJf8bWiX/G1sl/xtbJf8bXCb/ + G1wm/xtdJv8bXSb/HF4n/xxeJ/8cXyf/HF8n/xxgJ/8cYCf/HGEo/xxhKP8icS//InEv/yJxL/8icS// + InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//I3Q7/yN0O/8nh6r/ + J4eq/y2f7P8tn+z/MKr8/zCq/P8un9j/Lp/Y/yFyZv8hcmb/GFEi/xhRIv8ZUiL/GVIi/xlTIv8ZUyL/ + GVQj/xlUI/8idGf/InRn/y6f2P8un9j/MKr8/zCq/P8tn+z/LZ/s/yWEo/8lhKP/HF4z/xxeM/8bWiX/ + G1ol/xtbJv8bWyb/HFwm/xxcJv8cXSf/HF0n/xxeJ/8cXif/HV8n/x1fJ/8dYCj/HWAo/x1hKP8dYSj/ + InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS// + InEv/yN0O/8jdDv/J4eq/yeHqv8tn+z/LZ/s/zCq/P8wqvz/Lp/Y/y6f2P8hcmb/IXJm/xhRIv8YUSL/ + GVIi/xlSIv8ZUyL/GVMi/xlUI/8ZVCP/InRn/yJ0Z/8un9j/Lp/Y/zCq/P8wqvz/LZ/s/y2f7P8lhKP/ + JYSj/xxeM/8cXjP/G1ol/xtaJf8bWyb/G1sm/xxcJv8cXCb/HF0n/xxdJ/8cXif/HF4n/x1fJ/8dXyf/ + HWAo/x1gKP8dYSj/HWEo/yx4Ov8seDr/JXMz/yVzM/8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/ + I3Ix/yNyMf8jcjH/JHQ8/yR0PP8pj73/KY+9/zCp+f8wqfn/MKj0/zCo9P8mgYn/JoGJ/xlQJf8ZUCX/ + GFAi/xhQIv8ZUCP/GVAj/xlSI/8ZUiP/GVMk/xlTJP8aVCT/GlQk/xpUJP8aVCT/G1co/xtXKP8nhY3/ + J4WN/zCq9v8wqvb/MKn5/zCp+f8pjr3/KY69/x1fM/8dXzP/HFsn/xxbJ/8cXCf/HFwn/xxdKP8cXSj/ + HV0o/x1dKP8dXyn/HV8p/x1gKf8dYCn/HmEq/x5hKv8seDr/LHg6/yVzM/8lczP/I3Ix/yNyMf8jcjH/ + I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yR0PP8kdDz/KY+9/ymPvf8wqfn/MKn5/zCo9P8wqPT/ + JoGJ/yaBif8ZUCX/GVAl/xhQIv8YUCL/GVAj/xlQI/8ZUiP/GVIj/xlTJP8ZUyT/GlQk/xpUJP8aVCT/ + GlQk/xtXKP8bVyj/J4WN/yeFjf8wqvb/MKr2/zCp+f8wqfn/KY69/ymOvf8dXzP/HV8z/xxbJ/8cWyf/ + HFwn/xxcJ/8cXSj/HF0o/x1dKP8dXSj/HV8p/x1fKf8dYCn/HWAp/x5hKv8eYSr/UpFd/1KRXf9SkV3/ + UpFd/0mLVf9Ji1X/PoRK/z6ESv8zfkD/M35A/yh3Nv8odzb/JHY7/yR2O/8qk8D/KpPA/zGr+/8xq/v/ + Lp3N/y6dzf8dYEL/HWBC/xhOIv8YTiL/GU8i/xlPIv8ZUCP/GVAj/xlRI/8ZUSP/GVIj/xlSI/8aUyT/ + GlMk/xpUJP8aVCT/GlUl/xpVJf8bViX/G1Yl/xtXJf8bVyX/IGhJ/yBoSf8uoNP/LqDT/zGr+/8xq/v/ + KpPA/yqTwP8eYDL/HmAy/x1cKP8dXCj/HV0o/x1dKP8dXin/HV4p/x5fKf8eXyn/HmAq/x5gKv8eYSr/ + HmEq/1KRXf9SkV3/UpFd/1KRXf9Ji1X/SYtV/z6ESv8+hEr/M35A/zN+QP8odzb/KHc2/yR2O/8kdjv/ + KpPA/yqTwP8xq/v/Mav7/y6dzf8unc3/HWBC/x1gQv8YTiL/GE4i/xlPIv8ZTyL/GVAj/xlQI/8ZUSP/ + GVEj/xlSI/8ZUiP/GlMk/xpTJP8aVCT/GlQk/xpVJf8aVSX/G1Yl/xtWJf8bVyX/G1cl/yBoSf8gaEn/ + LqDT/y6g0/8xq/v/Mav7/yqTwP8qk8D/HmAy/x5gMv8dXCj/HVwo/x1dKP8dXSj/HV4p/x1eKf8eXyn/ + Hl8p/x5gKv8eYCr/HmEq/x5hKv9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/ + VpRh/1aUYf9Uprn/VKa5/0m2+/9Jtvv/NZy9/zWcvf9ZfV3/WX1d/2KDYv9ig2L/Y4Ni/2ODYv9jhGL/ + Y4Ri/2OFYv9jhWL/Y4Vi/2OFYv9jhmP/Y4Zj/2OHY/9jh2P/ZIdk/2SHZP9kiGT/ZIhk/2SJZP9kiWT/ + ZIlk/2SJZP9limT/ZYpk/1qFYv9ahWL/MJvC/zCbwv8yrfv/Mq37/yqQqf8qkKn/HVwo/x1cKP8dXSn/ + HV0p/x5eKf8eXin/Hl8p/x5fKf8eYCr/HmAq/x9iK/8fYiv/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/ + VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VKa5/1Smuf9Jtvv/Sbb7/zWcvf81nL3/WX1d/1l9Xf9ig2L/ + YoNi/2ODYv9jg2L/Y4Ri/2OEYv9jhWL/Y4Vi/2OFYv9jhWL/Y4Zj/2OGY/9jh2P/Y4dj/2SHZP9kh2T/ + ZIhk/2SIZP9kiWT/ZIlk/2SJZP9kiWT/ZYpk/2WKZP9ahWL/WoVi/zCbwv8wm8L/Mq37/zKt+/8qkKn/ + KpCp/x1cKP8dXCj/HV0p/x1dKf8eXin/Hl4p/x5fKf8eXyn/HmAq/x5gKv8fYiv/H2Ir/1iXZf9Yl2X/ + WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/WJdl/1iXZf9bn4j/W5+I/2LA+v9iwPr/XrHN/16xzf/O1Mb/ + ztTG/9fZzf/X2c3/xMq6/8TKuv+/xrT/v8a0/7/Gs/+/xrP/v8az/7/Gs/+/xrP/v8az/7/HtP+/x7T/ + v8e0/7/HtP+/x7T/v8e0/7/HtP+/x7T/v8i0/7/ItP+/yLT/v8i0/7/ItP+/yLT/zdLC/83Swv++ybb/ + vsm2/y6dw/8uncP/Mq36/zKt+v8jdV7/I3Ve/x1eKv8dXir/HV8q/x1fKv8eYCv/HmAr/x5hK/8eYSv/ + HmIs/x5iLP9Yl2X/WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/W5+I/1ufiP9iwPr/ + YsD6/16xzf9esc3/ztTG/87Uxv/X2c3/19nN/8TKuv/Eyrr/v8a0/7/GtP+/xrP/v8az/7/Gs/+/xrP/ + v8az/7/Gs/+/x7T/v8e0/7/HtP+/x7T/v8e0/7/HtP+/x7T/v8e0/7/ItP+/yLT/v8i0/7/ItP+/yLT/ + v8i0/83Swv/N0sL/vsm2/77Jtv8uncP/Lp3D/zKt+v8yrfr/I3Ve/yN1Xv8dXir/HV4q/x1fKv8dXyr/ + HmAr/x5gK/8eYSv/HmEr/x5iLP8eYiz/XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/ + XJpo/2W73/9lu9//Zb/t/2W/7f9UgGb/VIBm//v07f/79O3/X4Jk/1+CZP9Selr/Unpa/1B4WP9QeFj/ + PGpF/zxqRf8gVSv/IFUr/xpRJP8aUST/J1sx/ydbMf8nXDH/J1wx/xtUJv8bVCb/G1Um/xtVJv8bVif/ + G1Yn/xxXJ/8cVyf/HFgo/xxYKP8sZDX/LGQ1//nw5//58Of/IGU+/yBlPv8yquv/Mqrr/zGk1/8xpNf/ + Hl4q/x5eKv8eXyv/Hl8r/x5gK/8eYCv/H2Ar/x9gK/8fYiz/H2Is/1yaaP9cmmj/XJpo/1yaaP9cmmj/ + XJpo/1yaaP9cmmj/XJpo/1yaaP9lu9//Zbvf/2W/7f9lv+3/VIBm/1SAZv/79O3/+/Tt/1+CZP9fgmT/ + Unpa/1J6Wv9QeFj/UHhY/zxqRf88akX/IFUr/yBVK/8aUST/GlEk/ydbMf8nWzH/J1wx/ydcMf8bVCb/ + G1Qm/xtVJv8bVSb/G1Yn/xtWJ/8cVyf/HFcn/xxYKP8cWCj/LGQ1/yxkNf/58Of/+fDn/yBlPv8gZT7/ + Mqrr/zKq6/8xpNf/MaTX/x5eKv8eXir/Hl8r/x5fK/8eYCv/HmAr/x9gK/8fYCv/H2Is/x9iLP9gnWz/ + YJ1s/2CdbP9gnWz/YJ1s/2CdbP9gnWz/YJ1s/2Gjg/9ho4P/acX8/2nF/P9goKH/YKCh/1V6XP9Velz/ + +/Xw//v18P9fg2b/X4Nm/1V9Xv9VfV7/VX1e/1V9Xv9VfV7/VX1e/1R9Xf9UfV3/PGtF/zxrRf+Qp47/ + kKeO/4+mjP+Ppoz/G1Qn/xtUJ/8bVSf/G1Un/xxWKP8cVij/HFgo/xxYKP8cWSn/HFkp/ytiNf8rYjX/ + +vLq//ry6v8dWyr/HVsq/ymIh/8piIf/M7D7/zOw+/8jcFD/I3BQ/x5fLP8eXyz/H2As/x9gLP8fYS3/ + H2Et/yBjLf8gYy3/YJ1s/2CdbP9gnWz/YJ1s/2CdbP9gnWz/YJ1s/2CdbP9ho4P/YaOD/2nF/P9pxfz/ + YKCh/2Cgof9Velz/VXpc//v18P/79fD/X4Nm/1+DZv9VfV7/VX1e/1V9Xv9VfV7/VX1e/1V9Xv9UfV3/ + VH1d/zxrRf88a0X/kKeO/5Cnjv+Ppoz/j6aM/xtUJ/8bVCf/G1Un/xtVJ/8cVij/HFYo/xxYKP8cWCj/ + HFkp/xxZKf8rYjX/K2I1//ry6v/68ur/HVsq/x1bKv8piIf/KYiH/zOw+/8zsPv/I3BQ/yNwUP8eXyz/ + Hl8s/x9gLP8fYCz/H2Et/x9hLf8gYy3/IGMt/2Ofb/9jn2//Y59v/2Ofb/9jn2//Y59v/2Ofb/9jn2// + Z7O0/2eztP9rxff/a8X3/1mBav9ZgWr/V3xf/1d8X//89vH//Pbx/2KEaf9ihGn/WH5g/1h+YP9Yf2D/ + WH9g/1l/Yf9Zf2H/WYBh/1mAYf9ZgWL/WYFi/6+/rf+vv63/obSe/6G0nv8eVir/HlYq/xxVJ/8cVSf/ + HFYo/xxWKP8cVyj/HFco/x1YKf8dWCn/K2I1/ytiNf/78+z/+/Ps/x5bKv8eWyr/IGY9/yBmPf80sPf/ + NLD3/yuQl/8rkJf/H18s/x9fLP8fYCz/H2As/yBhLf8gYS3/IGIu/yBiLv9jn2//Y59v/2Ofb/9jn2// + Y59v/2Ofb/9jn2//Y59v/2eztP9ns7T/a8X3/2vF9/9ZgWr/WYFq/1d8X/9XfF///Pbx//z28f9ihGn/ + YoRp/1h+YP9YfmD/WH9g/1h/YP9Zf2H/WX9h/1mAYf9ZgGH/WYFi/1mBYv+vv63/r7+t/6G0nv+htJ7/ + HlYq/x5WKv8cVSf/HFUn/xxWKP8cVij/HFco/xxXKP8dWCn/HVgp/ytiNf8rYjX/+/Ps//vz7P8eWyr/ + Hlsq/yBmPf8gZj3/NLD3/zSw9/8rkJf/K5CX/x9fLP8fXyz/H2As/x9gLP8gYS3/IGEt/yBiLv8gYi7/ + Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9tvtf/bb7X/2y81/9svNf/W35i/1t+Yv9bf2P/ + W39j//z48//8+PP/Zods/2aHbP9cgWT/XIFk/1yBZP9cgWT/Zoht/2aIbf+wwK//sMCv/7LCsf+ywrH/ + 2d7U/9ne1P/Z3tT/2d7U/6/Arf+vwK3/m7Ka/5uymv8pXzT/KV80/x1XKP8dVyj/HVgp/x1YKf8rYzb/ + K2M2//v17v/79e7/Hlwr/x5cK/8eXSv/Hl0r/zGjy/8xo8v/MKLG/zCixv8fYCz/H2As/yBhLf8gYS3/ + IGIt/yBiLf8gYy7/IGMu/2ejc/9no3P/Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9no3P/bb7X/22+1/9svNf/ + bLzX/1t+Yv9bfmL/W39j/1t/Y//8+PP//Pjz/2aHbP9mh2z/XIFk/1yBZP9cgWT/XIFk/2aIbf9miG3/ + sMCv/7DAr/+ywrH/ssKx/9ne1P/Z3tT/2d7U/9ne1P+vwK3/r8Ct/5uymv+bspr/KV80/ylfNP8dVyj/ + HVco/x1YKf8dWCn/K2M2/ytjNv/79e7/+/Xu/x5cK/8eXCv/Hl0r/x5dK/8xo8v/MaPL/zCixv8wosb/ + H2As/x9gLP8gYS3/IGEt/yBiLf8gYi3/IGMu/yBjLv9qpXf/aqV3/2qld/9qpXf/aqV3/2qld/9qpXf/ + aqV3/3HG7P9xxuz/bLO//2yzv/9egGX/XoBl/16BZf9egWX//fn1//359f9oiW//aIlv/16DZ/9eg2f/ + XoNn/16DZ/9oinD/aIpw/7HBsf+xwbH/s8Oz/7PDs//b4Nb/2+DW/9vg1v/b4Nb/tMS0/7TEtP+yw7L/ + ssOy/1J+XP9Sflz/IFos/yBaLP8dWCr/HVgq/ytiNv8rYjb//Pbw//z28P8eWyz/Hlss/x5cLP8eXCz/ + Lpiq/y6Yqv80reX/NK3l/x9fLf8fXy3/H2Au/x9gLv8gYS7/IGEu/yBjL/8gYy//aqV3/2qld/9qpXf/ + aqV3/2qld/9qpXf/aqV3/2qld/9xxuz/ccbs/2yzv/9ss7//XoBl/16AZf9egWX/XoFl//359f/9+fX/ + aIlv/2iJb/9eg2f/XoNn/16DZ/9eg2f/aIpw/2iKcP+xwbH/scGx/7PDs/+zw7P/2+DW/9vg1v/b4Nb/ + 2+DW/7TEtP+0xLT/ssOy/7LDsv9Sflz/Un5c/yBaLP8gWiz/HVgq/x1YKv8rYjb/K2I2//z28P/89vD/ + Hlss/x5bLP8eXCz/Hlws/y6Yqv8umKr/NK3l/zSt5f8fXy3/H18t/x9gLv8fYC7/IGEu/yBhLv8gYy// + IGMv/22oev9tqHr/bah6/22oev9tqHr/bah6/22pf/9tqX//dMz7/3TM+/9rqaj/a6mo/2CCaP9ggmj/ + YINo/2CDaP/9+vb//fr2/2uLcv9ri3L/YYVp/2GFaf9ihmn/YoZp/2KGav9ihmr/Yodq/2KHav9jiGv/ + Y4hr/7XFtf+1xbX/tcW2/7XFtv9jimv/Y4pr/2OKbP9jimz/Y4ts/2OLbP9ahGT/WoRk/yxjOP8sYzj/ + K2I3/ytiN//89/L//Pfy/x5cLP8eXCz/Hl0s/x5dLP8rioj/K4qI/zW0+f81tPn/IWQ1/yFkNf8gYS7/ + IGEu/yBiL/8gYi//IWMv/yFjL/9tqHr/bah6/22oev9tqHr/bah6/22oev9tqX//bal//3TM+/90zPv/ + a6mo/2upqP9ggmj/YIJo/2CDaP9gg2j//fr2//369v9ri3L/a4ty/2GFaf9hhWn/YoZp/2KGaf9ihmr/ + YoZq/2KHav9ih2r/Y4hr/2OIa/+1xbX/tcW1/7XFtv+1xbb/Y4pr/2OKa/9jimz/Y4ps/2OLbP9ji2z/ + WoRk/1qEZP8sYzj/LGM4/ytiN/8rYjf//Pfy//z38v8eXCz/Hlws/x5dLP8eXSz/K4qI/yuKiP81tPn/ + NbT5/yFkNf8hZDX/IGEu/yBhLv8gYi//IGIv/yFjL/8hYy//cat+/3Grfv9xq37/cat+/3Grfv9xq37/ + cq+M/3KvjP94zfv/eM37/22loP9tpaD/ZIRr/2SEa/9khWv/ZIVr//36+P/9+vj/bo51/26Odf9liG3/ + ZYht/2WIbf9liG3/ZYlt/2WJbf9mim3/Zopt/2aKbv9mim7/tcW2/7XFtv+1xbb/tcW2/2eMb/9njG// + Z41v/2eNb/9njm//Z45v/2eOcP9njnD/Zo5u/2aObv9Me1b/THtW//z49P/8+PT/Hlss/x5bLP8fXSz/ + H10s/yqDd/8qg3f/NrX5/za1+f8jbUf/I21H/yBhLv8gYS7/IWIv/yFiL/8hYzD/IWMw/3Grfv9xq37/ + cat+/3Grfv9xq37/cat+/3KvjP9yr4z/eM37/3jN+/9tpaD/baWg/2SEa/9khGv/ZIVr/2SFa//9+vj/ + /fr4/26Odf9ujnX/ZYht/2WIbf9liG3/ZYht/2WJbf9liW3/Zopt/2aKbf9mim7/Zopu/7XFtv+1xbb/ + tcW2/7XFtv9njG//Z4xv/2eNb/9njW//Z45v/2eOb/9njnD/Z45w/2aObv9mjm7/THtW/0x7Vv/8+PT/ + /Pj0/x5bLP8eWyz/H10s/x9dLP8qg3f/KoN3/za1+f82tfn/I21H/yNtR/8gYS7/IGEu/yFiL/8hYi// + IWMw/yFjMP90rYH/dK2B/3Stgf90rYH/dK2B/3Stgf91spP/dbKT/3vP+/97z/v/cKWe/3Clnv9nhm7/ + Z4Zu/2eHb/9nh2///fr4//36+P9zknn/c5J5/2iKb/9oim//aIpw/2iKcP9pi3H/aYtx/2mMcf9pjHH/ + aYxx/2mMcf9ylHn/cpR5/3KUev9ylHr/aY5y/2mOcv9qj3P/ao9z/2qQc/9qkHP/apBz/2qQc/9rkXP/ + a5Fz/3WZff91mX3//fr3//369/8jXjD/I14w/x9cLf8fXC3/KYNz/ymDc/82tvn/Nrb5/yVxTf8lcU3/ + IWEv/yFhL/8hYjD/IWIw/yFkMf8hZDH/dK2B/3Stgf90rYH/dK2B/3Stgf90rYH/dbKT/3Wyk/97z/v/ + e8/7/3Clnv9wpZ7/Z4Zu/2eGbv9nh2//Z4dv//36+P/9+vj/c5J5/3OSef9oim//aIpv/2iKcP9oinD/ + aYtx/2mLcf9pjHH/aYxx/2mMcf9pjHH/cpR5/3KUef9ylHr/cpR6/2mOcv9pjnL/ao9z/2qPc/9qkHP/ + apBz/2qQc/9qkHP/a5Fz/2uRc/91mX3/dZl9//369//9+vf/I14w/yNeMP8fXC3/H1wt/ymDc/8pg3P/ + Nrb5/za2+f8lcU3/JXFN/yFhL/8hYS//IWIw/yFiMP8hZDH/IWQx/3evhP93r4T/d6+E/3evhP93r4T/ + d6+E/3i1l/94tZf/ftD7/37Q+/9ypZ3/cqWd/2qJcf9qiXH/aolx/2qJcf/Z39j/2d/Y/+Hm4P/h5uD/ + 2N7W/9je1v/Y3tb/2N7W/9jf1v/Y39b/2N/W/9jf1v/Y39f/2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/ + 2N/X/9jf1//Y39f/2ODX/9jg1//Y4Nf/2ODX/9jg1//Y4Nf/4efh/+Hn4f/Z4tn/2eLZ/1+Kaf9fimn/ + JmE0/yZhNP8pgG3/KYBt/ze3+f83t/n/JnJS/yZyUv8hYTD/IWEw/yFiMP8hYjD/ImMx/yJjMf93r4T/ + d6+E/3evhP93r4T/d6+E/3evhP94tZf/eLWX/37Q+/9+0Pv/cqWd/3Klnf9qiXH/aolx/2qJcf9qiXH/ + 2d/Y/9nf2P/h5uD/4ebg/9je1v/Y3tb/2N7W/9je1v/Y39b/2N/W/9jf1v/Y39b/2N/X/9jf1//Y39f/ + 2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/2N/X/9jg1//Y4Nf/2ODX/9jg1//Y4Nf/2ODX/+Hn4f/h5+H/ + 2eLZ/9ni2f9fimn/X4pp/yZhNP8mYTT/KYBt/ymAbf83t/n/N7f5/yZyUv8mclL/IWEw/yFhMP8hYjD/ + IWIw/yJjMf8iYzH/erKI/3qyiP96soj/erKI/3qyiP96soj/e7id/3u4nf+A0vv/gNL7/3Olm/9zpZv/ + bIt0/2yLdP9ti3X/bYt1/3KQev9ykHr/mK6d/5iunf+dsqH/nbKh/7fGuf+3xrn/6+7p/+vu6f+etKL/ + nrSi/560ov+etKL/nrWi/561ov+etaP/nrWj/561o/+etaP/nrak/562pP/r7ur/6+7q/7fJu/+3ybv/ + n7ek/5+3pP+atKD/mrSg/3Wafv91mn7/cZd6/3GXev9mkHD/ZpBw/zWFcP81hXD/N7j5/ze4+f8ndlj/ + J3ZY/yFhMf8hYTH/IWIx/yFiMf8iZjP/ImYz/3qyiP96soj/erKI/3qyiP96soj/erKI/3u4nf97uJ3/ + gNL7/4DS+/9zpZv/c6Wb/2yLdP9si3T/bYt1/22Ldf9ykHr/cpB6/5iunf+Yrp3/nbKh/52yof+3xrn/ + t8a5/+vu6f/r7un/nrSi/560ov+etKL/nrSi/561ov+etaL/nrWj/561o/+etaP/nrWj/562pP+etqT/ + 6+7q/+vu6v+3ybv/t8m7/5+3pP+ft6T/mrSg/5q0oP91mn7/dZp+/3GXev9xl3r/ZpBw/2aQcP81hXD/ + NYVw/ze4+f83uPn/J3ZY/yd2WP8hYTH/IWEx/yFiMf8hYjH/ImYz/yJmM/9+tYv/frWL/361i/9+tYv/ + frWL/361i/9/u6P/f7uj/4TT+/+E0/v/d6Wa/3elmv9wjXf/cI13/3COeP9wjnj/cI94/3CPeP9wj3n/ + cI95/3GQef9xkHn/kamX/5Gpl//s8Oz/7PDs/3KSev9yknr/cpN6/3KTev9ylHr/cpR6/3KUe/9ylHv/ + c5V7/3OVe/9zlnz/c5Z8/+zw7P/s8Oz/k66Z/5Oumf90mHz/dJh8/3SYff90mH3/dJl9/3SZff90mX7/ + dJl+/3Safv90mn7/c6mZ/3Opmf9EvPj/RLz4/yh4Xf8oeF3/IWEx/yFhMf8iZTP/ImUz/yyAQf8sgEH/ + frWL/361i/9+tYv/frWL/361i/9+tYv/f7uj/3+7o/+E0/v/hNP7/3elmv93pZr/cI13/3CNd/9wjnj/ + cI54/3CPeP9wj3j/cI95/3CPef9xkHn/cZB5/5Gpl/+RqZf/7PDs/+zw7P9yknr/cpJ6/3KTev9yk3r/ + cpR6/3KUev9ylHv/cpR7/3OVe/9zlXv/c5Z8/3OWfP/s8Oz/7PDs/5Oumf+Trpn/dJh8/3SYfP90mH3/ + dJh9/3SZff90mX3/dJl+/3SZfv90mn7/dJp+/3Opmf9zqZn/RLz4/0S8+P8oeF3/KHhd/yFhMf8hYTH/ + ImUz/yJlM/8sgEH/LIBB/4G3jv+Bt47/gbeO/4G3jv+Bt47/gbeO/4K+p/+Cvqf/h9T7/4fU+/95pJj/ + eaSY/3OPev9zj3r/c5B6/3OQev9zkXr/c5F6/3SSe/90knv/dJJ7/3SSe/94loD/eJaA/+3w7P/t8Oz/ + 1N7W/9Te1v+/zcL/v83C/7/Nwv+/zcL/v87C/7/Owv+/zsL/v87C/9Xf1//V39f/7fDt/+3w7f96nIP/ + epyD/3aZf/92mX//d5p//3eaf/93m3//d5t//3ebgP93m4D/d5yB/3ecgf98rp3/fK6d/37R+v9+0fr/ + M4Fo/zOBaP8iZDL/ImQy/y2CQf8tgkH/L4lF/y+JRf+Bt47/gbeO/4G3jv+Bt47/gbeO/4G3jv+Cvqf/ + gr6n/4fU+/+H1Pv/eaSY/3mkmP9zj3r/c496/3OQev9zkHr/c5F6/3ORev90knv/dJJ7/3SSe/90knv/ + eJaA/3iWgP/t8Oz/7fDs/9Te1v/U3tb/v83C/7/Nwv+/zcL/v83C/7/Owv+/zsL/v87C/7/Owv/V39f/ + 1d/X/+3w7f/t8O3/epyD/3qcg/92mX//dpl//3eaf/93mn//d5t//3ebf/93m4D/d5uA/3ecgf93nIH/ + fK6d/3yunf9+0fr/ftH6/zOBaP8zgWj/ImQy/yJkMv8tgkH/LYJB/y+JRf8viUX/hLmR/4S5kf+EuZH/ + hLmR/4S5kf+EuZH/hcCs/4XArP+J1vv/idb7/32qof99qqH/dpF8/3aRfP92kn3/dpJ9/3aTfv92k37/ + dpN+/3aTfv92lH7/dpR+/3eUfv93lH7/gp6K/4Keiv+1xrn/tca5/8DOw//AzsP/wM/D/8DPw//Az8T/ + wM/E/8DPxP/Az8T/tsi6/7bIuv+Eo4v/hKOL/3mbgv95m4L/eZuC/3mbgv95nIL/eZyC/3mdgv95nYL/ + ep2D/3qdg/96noP/ep6D/4Cypf+AsqX/idb7/4nW+/90rJz/dKyc/zSGSv80hkr/MIpH/zCKR/8wikf/ + MIpH/4S5kf+EuZH/hLmR/4S5kf+EuZH/hLmR/4XArP+FwKz/idb7/4nW+/99qqH/faqh/3aRfP92kXz/ + dpJ9/3aSff92k37/dpN+/3aTfv92k37/dpR+/3aUfv93lH7/d5R+/4Keiv+Cnor/tca5/7XGuf/AzsP/ + wM7D/8DPw//Az8P/wM/E/8DPxP/Az8T/wM/E/7bIuv+2yLr/hKOL/4Sji/95m4L/eZuC/3mbgv95m4L/ + eZyC/3mcgv95nYL/eZ2C/3qdg/96nYP/ep6D/3qeg/+AsqX/gLKl/4nW+/+J1vv/dKyc/3SsnP80hkr/ + NIZK/zCKR/8wikf/MIpH/zCKR/+HvJX/h7yV/4e8lf+HvJX/h7yV/4e8lf+Iv6D/iL+g/4zW9f+M1vX/ + jdj6/43Y+v+KzNv/iszb/4W7u/+Fu7v/gKmc/4CpnP97mIP/e5iD/3qXgv96l4L/e5eC/3uXgv97mIL/ + e5iC/3uYgv97mIL/e5mD/3uZg/97mYP/e5mD/3yag/98moP/fJuE/3ybhP98nIT/fJyE/3ychf98nIX/ + fJ2F/3ydhf99nYX/fZ2F/36gh/9+oIf/gq6g/4KuoP+Gv7z/hr+8/4rN3P+Kzdz/jdj6/43Y+v+N1vX/ + jdb1/4e+of+HvqH/drKF/3ayhf8zjEr/M4xK/zGLSP8xi0j/h7yV/4e8lf+HvJX/h7yV/4e8lf+HvJX/ + iL+g/4i/oP+M1vX/jNb1/43Y+v+N2Pr/iszb/4rM2/+Fu7v/hbu7/4CpnP+AqZz/e5iD/3uYg/96l4L/ + epeC/3uXgv97l4L/e5iC/3uYgv97mIL/e5iC/3uZg/97mYP/e5mD/3uZg/98moP/fJqD/3ybhP98m4T/ + fJyE/3ychP98nIX/fJyF/3ydhf98nYX/fZ2F/32dhf9+oIf/fqCH/4KuoP+CrqD/hr+8/4a/vP+Kzdz/ + is3c/43Y+v+N2Pr/jdb1/43W9f+HvqH/h76h/3ayhf92soX/M4xK/zOMSv8xi0j/MYtI/4q+mP+Kvpj/ + ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/isGh/4rBof+NysX/jcrF/47T5P+O0+T/j9n6/4/Z+v+P2fr/ + j9n6/4/Y+P+P2Pj/jtTs/47U7P+Nz93/jc/d/4vHzv+Lx87/isTH/4rEx/+JwcH/icHB/4m+vP+Jvrz/ + ib+8/4m/vP+JwsL/icLC/4rEx/+KxMf/i8nP/4vJz/+Nz93/jc/d/47U7P+O1Oz/j9j4/4/Y+P+P2fr/ + j9n6/4/Z+v+P2fr/jtPm/47T5v+My8j/jMvI/4vAof+LwKH/ir6Y/4q+mP+Kvpj/ir6Y/2ereP9nq3j/ + Mo1J/zKNSf+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/4rBof+KwaH/jcrF/43Kxf+O0+T/ + jtPk/4/Z+v+P2fr/j9n6/4/Z+v+P2Pj/j9j4/47U7P+O1Oz/jc/d/43P3f+Lx87/i8fO/4rEx/+KxMf/ + icHB/4nBwf+Jvrz/ib68/4m/vP+Jv7z/icLC/4nCwv+KxMf/isTH/4vJz/+Lyc//jc/d/43P3f+O1Oz/ + jtTs/4/Y+P+P2Pj/j9n6/4/Z+v+P2fr/j9n6/47T5v+O0+b/jMvI/4zLyP+LwKH/i8Ch/4q+mP+Kvpj/ + ir6Y/4q+mP9nq3j/Z6t4/zKNSf8yjUn/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwJv/jcCb/43Am/+NwqP/jcKj/4/Iuf+PyLn/j83J/4/Nyf+Q0dn/kNHZ/5HV6P+R1ej/ + kdfy/5HX8v+R2fb/kdn2/5La+v+S2vr/ktr7/5La+/+S2vv/ktr7/5La+v+S2vr/kdn2/5HZ9v+R1/L/ + kdfy/5HV6P+R1ej/kNHY/5DR2P+PzMj/j8zI/4/Iuf+PyLn/jcKj/43Co/+NwJv/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/9UoWn/VKFp/43Am/+NwJv/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcKj/43Co/+PyLn/j8i5/4/Nyf+Pzcn/ + kNHZ/5DR2f+R1ej/kdXo/5HX8v+R1/L/kdn2/5HZ9v+S2vr/ktr6/5La+/+S2vv/ktr7/5La+/+S2vr/ + ktr6/5HZ9v+R2fb/kdfy/5HX8v+R1ej/kdXo/5DR2P+Q0dj/j8zI/4/MyP+PyLn/j8i5/43Co/+NwqP/ + jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/VKFp/1Shaf+MwJrx + jMCa8ZDCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKe/5DCnv+QxKP/ + kMSj/5DEov+QxKL/kMKe/5DCnv+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/43BmvGNwZrxjMCa8YzAmvGQwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnv+Qwp7/kMSj/5DEo/+QxKL/kMSi/5DCnv+Qwp7/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+NwZrxjcGa8Ya+l8SGvpfElMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/j8Kdxo/CncaGvpfEhr6XxJTFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/4/CncaPwp3G + fLuPKXy7jymTxqD1k8ag9ZbHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + mMil9pjIpfaZx6gymceoMny7jyl8u48pk8ag9ZPGoPWWx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5jIpfaYyKX2mceoMpnHqDIAAAAAAAAAAHy7jyl8u48pjMKbxYzCm8WWx6Py + lsej8pnJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5rJp/OayafzlsaiyZbGosmbyKozm8iqMwAAAAAAAAAAAAAAAAAAAAB8u48p + fLuPKYzCm8WMwpvFlsej8pbHo/KZyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+ayafzmsmn85bGosmWxqLJm8iqM5vIqjMAAAAA + AAAAAMAAAAAAAAADwAAAAAAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAAAAAA8AAAAAAAAADKAAAADAAAABgAAAAAQAgAAAAAAAAJAAA + EwsAABMLAAAAAAAAAAAAAAAAAAAbZCQOG2QkHB1nJqkcZybIHGcm5xxnJv8cZyb/HGcm/xxnJv8cZyb/ + HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xhaIf8XViD/ + FlIe/xdTH/8XVB//F1Qf/xdUH/8XVSD/F1Yg/xdWIP8YVyD/GFcg/xhYIP8YWSH/GFkh/xhaIf8ZWiH/ + GVoh/xhcIukZXCLMGlwirxlaIR8ZWiEQAAAAABtkJA4dZyZJHWgnhR1oJ9QdaCfkHWgn8x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8cZCX/ + G2Ek/xhWIP8XVB//F1If/xdTH/8XVB//F1Qf/xhUIP8YVSD/GFYg/xhWIP8YVyD/GFch/xlYIf8ZWSH/ + GVkh/xlaIv8ZWiL/GVsi/xlbIvQZXCLmGlwj1xpdIocaXCJLGVohEBtkJBwdaCeFHWgn7R1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8bYSX/GVoi/xdRHv8XUh//F1If/xdTH/8XVB//F1Qf/xhUIP8YVSD/GFUg/xhWIP8YVyH/ + GFch/xlYIf8ZWSH/GVkh/xlaIv8ZWyL/GVsi/xlbIv8aXCP/Glwj/xpdIu8aXSKHGVohHx5qKakeaijU + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Hmoo/xpbIv8ZViH/F1Ef/xdSH/8XUx//F1Mf/xhUIP8YVCD/GFQg/xhVIP8YViD/ + GFYg/xlXIf8ZWCH/GVgh/xlZIv8ZWiL/GVoi/xpbIv8aWyP/Glsj/xpcI/8aXSP/Gl0j/xteI/8bXiPX + HF8krx9rKskfaynkH2sp/x9rKf8fayn/H2sp/x9rKf8fayn/H2sp/x9rKf8fayn/H2sp/x9rKf8fayn/ + H2sp/x9rKf8fayn/H2sp/x9rKf8dZyj/HGMm/xlWIf8aWTD/G11A/xteQP8ZWTD/GFMg/xhUIf8YVCH/ + GFQh/xlVIf8ZViH/GVYh/xlXIv8ZWCL/GVgi/xpZI/8aWiP/Gloj/xpbI/8aWyP/G1sk/xtcJP8bXST/ + G10k/xteJP8bXiTmG18lzB9rKugfayr0H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8dYyf/Glsk/xdQH/8bXUD/Hmlg/x5qYP8bX0D/ + GFMg/xhUIf8YVCH/GFQh/xlVIf8ZViL/GVYi/xlXIv8ZWCL/GVgi/xpZI/8aWiP/Gloj/xpbJP8bWyT/ + G1sk/xtcJP8bXSX/G10l/xteJf8bXiX0G18l6SBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/xtbJP8dYj//Hmha/yWCsv8ni8n/ + KZPf/ymT3/8ni8f/JYKu/x5nVP8cXjv/GVUi/xlWIv8ZVyL/GVci/xpYI/8aWCP/Glgj/xpZI/8bWiT/ + G1sk/xtbJP8bXCT/G1wk/xtdJf8cXiX/HF4l/xxfJf8cYCb/HGAm/yBuLP8gbiz/IG4s/yBuLP8gbiz/ + IG4s/yBuLP8gbiz/IG4s/yBuLP8gbiz/IG4s/yBuLP8gbiz/IG4s/yBuLP8fazH/H2k2/yBuZv8idoH/ + JH6d/yqT1f8rmOH/LJ7u/yye7v8rmOD/KpPT/yR+mv8hdH//H2tk/xtcMv8aWir/GVcj/xpYJP8aWCT/ + Glgk/xpZJP8aWiT/G1sl/xtbJf8bXCX/G1wl/xtdJv8bXib/HF4m/xxfJv8cYCb/HGAn/yBuLf8gbi3/ + IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8fajf/ + HWVA/ySBp/8ni8P/KZTf/y6k9/8vpvr/L6j9/y+o/f8vpvr/LqT3/ymU3/8nisL/JICl/xxiQv8bXTP/ + GVcj/xlYJP8aWCT/Glgk/xpZJf8aWiX/Glol/xtbJf8bXCb/G1wm/xtdJv8bXib/G14m/xxfJ/8cYCf/ + HGAn/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcS// + IXEv/yR8fv8nh6n/KZHU/y+l9v8wp/n/MKn8/yybzf8mhZT/IG5a/yBsWP8mg5L/LJrM/zCp/P8wp/n/ + L6X2/yqR1P8lg6P/IHRx/xpYJP8aWSX/Glkl/xtaJf8bWyX/G1sl/xtcJv8bXSb/G10m/xxeJ/8cXyf/ + HF8n/xxgJ/8cYSj/HGEo/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS// + InEv/yJyNf8jd1H/JHxt/ymOtf8rls//LZ7o/y+i5/8smMz/KY6x/yJ2eP8fa1v/HWA+/x1gPf8ga1r/ + I3d4/ymPsv8smMz/L6Ln/y2e6P8qlMv/J4qv/yBuZP8dZUj/G1ws/xtaJf8bWyX/G1sm/xxcJv8cXSb/ + HF0n/xxeJ/8cXyf/HV8n/x1gKP8dYSj/HWEo/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS// + InEv/yJxL/8icS//InEv/yN0O/8lfnP/J4eq/y2f7P8vpfT/MKr8/y6f2P8oiZ//IXJm/xhRIv8ZUiL/ + GVIi/xlTIv8ZVCP/GVQj/yJ0Z/8oiqD/Lp/Y/zCq/P8vpfT/LZ/s/yWEo/8hcWv/HF4z/xtaJf8bWyb/ + G1sm/xxcJv8cXSf/HF0n/xxeJ/8dXyf/HV8n/x1gKP8dYSj/HWEo/yx4Ov8pdjf/JXMz/yNyMf8jcjH/ + I3Ix/yNyMf8jcjH/I3Ix/yNyMf8kczf/JHQ8/ymPvf8tnNv/MKn5/zCo9P8rlb//JoGJ/xlQJf8ZUCT/ + GFAi/xlQI/8ZUSP/GVIj/xlTJP8aVCT/GlQk/xpUJP8bVib/G1co/yeFjf8smML/MKr2/zCp+f8tnNv/ + KY69/x1fM/8dXS3/HFsn/xxcJ/8cXSj/HF0o/x1dKP8dXin/HV8p/x1gKf8eYSr/HmEq/z+FTP89g0r/ + PIJI/zZ/Q/8zfUD/MXs+/yt4Of8odjb/JnU0/yR0Nv8lfFr/J4R+/y2d3P8uoOD/L6Pj/yeEm/8jdnj/ + H2hW/xlQJP8ZUCP/GVAj/xlRI/8ZUSP/GVIj/xpTJP8aVCT/GlQk/xpVJf8bVib/G1cn/yFuWf8lfHz/ + KImg/y+l5v8uoeH/LZ3c/yR5ev8ga1P/HV4t/x1cKP8dXSj/HV0o/x1eKf8dXin/Hl8p/x5gKv8eYSr/ + HmEq/1KRXf9SkV3/UpFd/0mLVf9EiFD/PoRK/zN+QP8uezv/KHc2/yR2O/8nhX7/KpPA/zGr+/8wpOT/ + Lp3N/x1gQv8bVzL/GE4i/xlPIv8ZUCP/GVAj/xlRI/8ZUiP/GVIj/xpTJP8aVCT/GlQk/xpVJf8bViX/ + G1Yl/xtXJf8eYDf/IGhJ/y6g0/8wpuf/Mav7/yqTwP8kenn/HmAy/x1cKP8dXSj/HV0o/x1eKf8eXyn/ + Hl8p/x5gKv8eYSr/HmEq/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1Smuf9Prtr/ + Sbb7/zWcvf9HjY3/WX1d/2KDYv9jg2L/Y4Ni/2OEYv9jhWL/Y4Vi/2OFYv9jhmP/Y4Zj/2OHY/9kh2T/ + ZIdk/2SIZP9kiWT/ZIlk/2SJZP9limT/ZYpk/1qFYv9FkJL/MJvC/zKt+/8un9L/KpCp/x1cKP8dXSn/ + HV0p/x5eKf8eXyn/Hl8p/x5gKv8fYSv/H2Ir/1eWY/9XlmP/V5Zj/1eWY/9XlmP/V5Zj/1eWY/9YmGz/ + WZp1/1uz2v9Xs9//VLTk/4K4wv+Nsqv/mKuV/5Onjv+Spo3/kaWL/5Gli/+RpYv/kaaL/5Gmi/+Rpov/ + kaeM/5GnjP+Rp4z/kqeM/5KojP+SqIz/kqmM/5KpjP+SqYz/kqmM/5Sskv+Fr6f/d7K8/zCl3/8votj/ + Lp/S/yBpQ/8fYzb/HV4q/x5fKv8eXyr/HmAq/x5hK/8eYSv/H2Is/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/ + WJdl/1iXZf9am3f/W5+I/2LA+v9gueT/XrHN/87Uxv/T18r/19nN/8TKuv/CyLf/v8a0/7/Gs/+/xrP/ + v8az/7/Gs/+/x7T/v8e0/7/HtP+/x7T/v8e0/7/HtP+/yLT/v8i0/7/ItP+/yLT/v8i0/83Swv/Gzrz/ + vsm2/y6dw/8wpd//Mq36/yN1Xv8gakT/HV4q/x1fKv8eYCv/HmAr/x5hK/8eYiz/HmIs/1yaaP9cmmj/ + XJpo/1yaaP9cmmj/XJpo/1yaaP9hq6T/Zbvf/2W/7f9doKr/VIBm//v07f+tu6n/X4Jk/1J6Wv9ReVn/ + UHhY/zxqRf8uYDj/IFUr/xpRJP8hViv/J1sx/ydcMf8hWCz/G1Qm/xtVJv8bVif/G1Yn/xxXJ/8cWCj/ + HFgo/yxkNf+Tqo7/+fDn/yBlPv8piJX/Mqrr/zGk1/8ogYH/Hl4q/x5fK/8eYCv/HmAr/x9gK/8fYSz/ + H2Is/16cav9enGr/Xpxq/16cav9enGr/Xpxq/1+fdv9jr7L/Z8Du/2Owx/9clpT/VX1h//v17/+tvKr/ + X4Nl/1R8XP9Te1z/U3tb/0l0Uv9Bbkv/OmlE/yteNf9DcEr/XIFg/1uBX/87a0P/G1Qn/xtVJ/8bVif/ + HFYo/xxYKP8cWCj/HFkp/yxjNf+Tqo//+vHp/x9gNP8mfXf/Lpm5/zKq6f8piZP/IWc9/x5fLP8eYCz/ + H2As/x9hLP8fYiz/IGMt/2CdbP9gnWz/YJ1s/2CdbP9gnWz/YJ1s/2Gjg/9ltMD/acX8/2Cgof9bjX// + VXpc//v18P+tvKv/X4Nm/1V9Xv9VfV7/VX1e/1V9Xv9VfV7/VH1d/zxrRf9miWr/kKeO/4+mjP9VfVr/ + G1Qn/xtVJ/8cVij/HFYo/xxYKP8cWSn/HFkp/ytiNf+TqpD/+vLq/x1bKv8jcln/KYiH/zOw+/8rkKb/ + I3BQ/x5fLP8fYCz/H2As/x9hLf8gYi3/IGMt/2Ofb/9jn2//Y59v/2Ofb/9jn2//Y59v/2eztP9pvNb/ + a8X3/1mBav9Yf2X/V3xf//z28f+vva3/YoRp/1h+YP9Yf2D/WH9g/1l/Yf9ZgGH/WYBh/1mBYv+EoIj/ + r7+t/6G0nv9ghWT/HlYq/xxVJ/8cVij/HFYo/xxXKP8dWCn/HVgp/ytiNf+Tq5H/+/Ps/x5bKv8fYTT/ + IGY9/zSw9/8woMf/K5CX/x9fLP8fYCz/H2As/yBhLf8gYi7/IGIu/2Whcf9loXH/ZaFx/2Whcf9loXH/ + ZaFx/2q5xv9rvdb/bMHn/1qAZv9af2T/WX5h//z38v+wvq7/ZIZr/1qAYv9agGL/WoBi/2CEZ/9yknj/ + haCI/4aiiv+luKX/xM/B/73Juf+SqpL/Z4ts/1yEYf8/b0f/I1su/x1XKP8dWCn/HVgp/ytjNv+Tq5H/ + +/Tt/x5cK/8fXy//H2I0/zOq4f8wocj/Lpmv/x9gLP8fYCz/IGEt/yBiLf8gYi7/IGMu/2ejc/9no3P/ + Z6Nz/2ejc/9no3P/Z6Nz/22+1/9tvdf/bLzX/1t+Yv9bf2P/W39j//z48/+xwLD/Zods/1yBZP9cgWT/ + XIFk/2aIbf+LpI7/sMCv/7LCsf/G0MP/2d7U/9ne1P/Ez8H/r8Ct/5uymv9iiWf/KV80/x1XKP8dWCn/ + HVgp/ytjNv+TrJL/+/Xu/x5cK/8eXSv/Hl0r/zGjy/8xo8n/MKLG/x9gLP8gYS3/IGEt/yBiLf8gYy7/ + IGMu/2qld/9qpXf/aqV3/2qld/9qpXf/aqV3/3HG7P9vvdb/bLO//16AZf9egWX/XoFl//359f+zwbL/ + aIlv/16DZ/9eg2f/XoNn/2iKcP+NppH/scGx/7PDs//H0sX/2+DW/9vg1v/I0sX/tMS0/7LDsv+CoYf/ + Un5c/yBaLP8fWSv/HVgq/ytiNv+UrJP//Pbw/x5bLP8eXCz/Hlws/y6Yqv8xo8j/NK3l/x9fLf8fYC7/ + H2Au/yBhLv8gYi//IGMv/2ynef9sp3n/bKd5/2ynef9sp3r/bKd7/3PJ9P9vvNT/bK60/1+BZ/9fgmf/ + X4Jn//369v+zwrP/aopx/2CEaP9ghGj/YIVo/2WIbf93ln3/iqSO/4umj/+qvKr/yNPG/8jTxv+qvav/ + jKeQ/4unj/9zlnr/W4Vk/z1vSP8xZj3/JV4x/ytiN/+UrJT//Pfx/x5cLP8eXCz/Hl0s/y2Rmf8xocT/ + NbHv/yBiMf8gYTD/IGEu/yBiL/8gYi//IWMv/22oev9tqHr/bah6/22oev9tqX3/bal//3TM+/9wu9L/ + a6mo/2CCaP9gg2j/YINo//369v+0w7T/a4ty/2GFaf9ihmn/YoZp/2KGav9ih2r/Yodq/2OIa/+Mp5D/ + tcW1/7XFtv+MqJH/Y4pr/2OKbP9ji2z/Y4ts/1qEZP9DdE7/LGM4/ytiN/+UrZX//Pfy/x5cLP8eXSz/ + Hl0s/yuKiP8wn8H/NbT5/yFkNf8hYzL/IGEu/yBiL/8hYy//IWMv/3Grfv9xq37/cat+/3Grfv9yrYX/ + cq+M/3jN+/9zuc7/baWg/2SEa/9khWv/ZIVr//36+P+2xLf/bo51/2WIbf9liG3/ZYht/2WJbf9mim3/ + Zopt/2aKbv+OqJL/tcW2/7XFtv+OqZP/Z4xv/2eNb/9njm//Z45v/2eOcP9njm//Zo5u/0x7Vv+kuqX/ + /Pj0/x5bLP8fXCz/H10s/yqDd/8wnLj/NrX5/yNtR/8iZzv/IGEu/yFiL/8hYzD/IWMw/3OsgP9zrID/ + c6yA/3OsgP9zroj/dLGQ/3rO+/90us3/b6Wf/2aFbf9mhm3/ZoZt//36+P+3xbj/cZB3/2eJbv9niW7/ + Z4lv/2eKb/9ni2//aItv/2iLcP9+nIT/lK2Y/5StmP9+nYT/aI1x/2mOcf9pj3H/aY9x/2mPcv9pj3H/ + aZBx/2GKav+vwrD//fn2/yFdLv8gXS3/H10t/yqDdf8wnLf/Nrb5/yRvSv8iaDz/IWEv/yFiMP8hYzD/ + IWQx/3Stgf90rYH/dK2B/3Stgf91sIr/dbKT/3vP+/92us3/cKWe/2eGbv9nh2//Z4dv//36+P+4xrn/ + c5J5/2iKb/9oinD/aIpw/2mLcf9pjHH/aYxx/2mMcf9ukHX/cpR5/3KUev9ukXb/aY5y/2qPc/9qkHP/ + apBz/2qQc/9rkXP/a5Fz/3WZff+5yrr//fr3/yNeMP8hXS//H1wt/ymDc/8wnbb/Nrb5/yVxTf8jaT7/ + IWEv/yFiMP8hYzH/IWQx/3evhP93r4T/d6+E/3evhP94so7/eLWX/37Q+/94u8z/cqWd/2qJcf9qiXH/ + aolx/9nf2P/d49z/4ebg/9je1v/Y3tb/2N7W/9jf1v/Y39b/2N/W/9jf1//Y39f/2N/X/9jf1//Y39f/ + 2N/X/9jf1//Y4Nf/2ODX/9jg1//Y4Nf/2ODX/+Hn4f/d5d3/2eLZ/1+Kaf9Ddk//JmE0/ymAbf8wnLP/ + N7f5/yZyUv8kakH/IWEw/yFiMP8iYzH/ImMx/3mxhv95sYb/ebGG/3mxhv95tJD/erea/3/R+/95u8z/ + c6Wc/2uKc/9rinP/bIpz/6a4qf+xwbT/vcq//7vIvP/BzcL/yNLI/+Ln4P/O2M7/u8q8/7vKvf+7yr3/ + u8q9/7vKvf+7yr3/u8q9/7vLvv/O2c//4ufh/8jVyf/C0MP/vMy+/77Owf+yxrb/p76s/2iRcv9XhWL/ + RnlS/y+Db/8znbT/N7j5/yd0Vf8ka0P/IWEx/yFiMf8iYzH/ImUy/3qyiP96soj/erKI/3qyiP97tZP/ + e7id/4DS+/96vMv/c6Wb/2yLdP9ti3X/bYt1/3KQev+Fn4z/mK6d/52yof+qvK3/t8a5/+vu6f/F0cb/ + nrSi/560ov+etaL/nrWi/561o/+etaP/nrWj/562pP/F0sf/6+7q/7fJu/+rwLD/n7ek/5q0oP+Ip4// + dZp+/3GXev9slHX/ZpBw/zWFcP82n7X/N7j5/yd2WP8kbEX/IWEx/yFiMf8iZDL/ImYz/361i/9+tYv/ + frWL/361i/9/uJf/f7uj/4TT+/9+vMv/d6Wa/3CNd/9wjnj/cI54/3CPeP9wj3n/cI95/3GQef+BnYj/ + kamX/+zw7P+vwbP/cpJ6/3KTev9ylHr/cpR6/3KUe/9zlXv/c5V7/3OWfP+ww7T/7PDs/5Oumf+Eo4v/ + dJh8/3SYff90mX3/dJl9/3SZfv90mn7/dJp+/3Opmf9cs8n/RLz4/yh4Xf8lbUf/IWEx/yJlM/8nczr/ + LIBB/4C2jf+Ato3/gLaN/4C2jf+AuZn/gb2l/4bU+/9/vMr/eKWZ/3KOef9yj3n/co95/3KQef9ykHr/ + cpF6/3ORev98mIP/haCM/+3w7P/I1Mr/o7io/5mwnv+ZsJ7/mbGe/5mxn/+ZsZ//mbKf/6S7qv/I1cv/ + 7fDt/4eljv9+n4b/dZl+/3aZfv92mn7/dpp+/3aaf/92m3//dpuA/3ism/9sucr/Ycf5/y59Y/8ocEr/ + ImMy/yh0Ov8rfD//LoVD/4G3jv+Bt47/gbeO/4G3jv+Cu5v/gr6n/4fU+/+AvMr/eaSY/3OPev9zkHr/ + c5B6/3ORev90knv/dJJ7/3SSe/92lH7/eJaA/+3w7P/h5+H/1N7W/7/Nwv+/zcL/v83C/7/Owv+/zsL/ + v87C/9Xf1//h6OL/7fDt/3qcg/94m4H/dpl//3eaf/93m3//d5t//3ebgP93nIH/d5yB/3yunf99wMz/ + ftH6/zOBaP8rc03/ImQy/y2CQf8uhkP/L4lF/4S5kf+EuZH/hLmR/4S5kf+FvZ//hcCs/4nW+/+DwM7/ + faqh/3aRfP92kn3/dpJ9/3aTfv92k37/dpN+/3aUfv93lH7/d5R+/4Keiv+csqL/tca5/8DOw//Az8P/ + wM/D/8DPxP/Az8T/wM/E/7bIuv+dtqP/hKOL/3mbgv95m4L/eZuC/3mcgv95nYL/eZ2C/3qdg/96noP/ + ep6D/4Cypf+FxND/idb7/3SsnP9UmXP/NIZK/zCKR/8wikf/MIpH/4a7k/+Gu5P/hruT/4a7k/+GvZ3/ + h8Cm/4vW+P+IzOP/hcHO/4CvrP9/q6T/fqec/3uejf96mof/eZaB/3iWgP95loD/eZaA/3+bhv+LpZL/ + mK+e/560o/+etKP/nrSj/561pP+etaT/nrWk/5myn/+NqZT/gKCI/3uchP97nIT/e5yE/3yehf99oov/ + fqaR/4CuoP+Bsqj/graw/4fF0P+JzuT/i9b4/361n/9pqYP/VZxo/zKLSf8xi0j/MYtI/4e8lf+HvJX/ + h7yV/4e8lf+Ivpv/iL+g/4zW9f+N1/j/jdj6/4rM2/+IxMv/hbu7/4CpnP9+oZD/e5iD/3qXgv97l4L/ + e5eC/3uYgv97mIL/e5iC/3uZg/97mYP/e5mD/3yag/98m4T/fJuE/3ychP98nIX/fJyF/3ydhf99nYX/ + fZ2F/36gh/+Ap5T/gq6g/4a/vP+Ixsz/is3c/43Y+v+N1/j/jdb1/4e+of9/uJP/drKF/zOMSv8yjEn/ + MYtI/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/4rBof+MxrP/jcrF/47T5P+P1u//j9n6/4/Z+v+P2fn/ + j9j4/47U7P+O0uX/jc/d/4vHzv+Lxsv/isTH/4nBwf+JwL//ib68/4m/vP+Jwb//icLC/4rEx/+Lx8v/ + i8nP/43P3f+O0uX/jtTs/4/Y+P+P2fn/j9n6/4/Z+v+P1vD/jtPm/4zLyP+MxrX/i8Ch/4q+mP+Kvpj/ + ir6Y/2ereP9NnGH/Mo1J/4y/mv+Mv5r/jL+a/4y/mv+Mv5r/jL+a/4zBnv+Mw6f/jcWw/47KwP+OzMf/ + js7P/4/R2v+P0t3/j9Ph/4/T4/+P0uP/j9Lj/47P4P+Oz9//js/f/47O3v+Ozd3/jszc/47N3P+Ozd3/ + js7e/47P3/+Oz+D/jtDh/4/S4/+P0uL/j9Pi/4/S4P+P0d3/j9Ha/47Oz/+OzMj/jsrB/43Gsv+Mw6j/ + jMCe/4y/mv+Mv5r/jL+a/3q2iv9fpnH/Q5dZ/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwZ//jcKj/4/Iuf+Py8H/j83J/5DR2f+R0+H/kdXo/5HX8v+R2PT/kdn2/5La+v+S2vv/ + ktr7/5La+/+S2vv/ktr6/5HZ9v+R2PT/kdfy/5HV6P+R0+D/kNHY/4/MyP+PysH/j8i5/43Co/+NwZ// + jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/9xsYL/VKFp/4zAmvGOwZz4kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnv+Qw6H/kMSj/5DEov+Qw6D/kMKe/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Pwpz4jcGa8Ym/mduOwZzt + ksSf/5LEn/+SxJ//ksSf/5LEn/+SxJ//ksSf/5LEn/+SxJ//ksSf/5LEn/+SxJ//ksSf/5LEn/+SxJ// + ksSf/5LEn/+SxJ//ksSf/5LEoP+SxKH/ksWi/5LFov+SxKH/ksSg/5LEn/+SxJ//ksSf/5LEn/+SxJ// + ksSf/5LEn/+SxJ//ksSf/5LEn/+SxJ//ksSf/5LEn/+SxJ//ksSf/5LEn/+SxJ//ksSf/5LEn/+Qw53t + jsGb3Ia+l8SOwp3ilMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+SxJ/jj8Kdxny7jymQxJ6Pk8ag9ZbHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5jIpfaYyKaUmceoMny7jxWNw5xSkMSej5LFoOKUxqLtlsek+ZjIpf+YyKX/ + mMil/5jIpf+YyKX/mMil/5jIpf+YyKX/mMil/5jIpf+YyKX/mMil/5jIpf+YyKX/mMil/5jIpf+YyKX/ + mMil/5jIpf+YyKX/mMil/5jIpf+YyKX/mMil/5jIpf+YyKX/mMil/5jIpf+YyKX/mMil/5jIpf+YyKX/ + mMil/5jIpf+YyKX/mMil/5jIpfmXx6Tvlsej5JnIppWZyKZXmceoGQAAAAB8u48VfLuPKYzCm8WSxZ/c + lsej8pnJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5rJp/OYyKXelsaiyZvIqjObyKoaAAAAAIAAAAAAAQAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAACAAAAAAAEAACgAAAAgAAAAQAAAAAEAIAAAAAAAABAAABMLAAATCwAAAAAAAAAAAAAAAAAA + G2QkHB1nJqkcZybnHGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/ + GFoh/xZSHv8XUx//F1Qf/xdUH/8XViD/F1Yg/xhXIP8YWCD/GFkh/xhaIf8ZWiH/GFwi6RpcIq8ZWiEf + AAAAABtkJBwdaCftHWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/xlaIv8XUR7/F1If/xdTH/8XVB//GFQg/xhVIP8YViD/GFch/xlYIf8ZWSH/GVoi/xlbIv8ZWyL/ + Glwj/xpdIu8ZWiEfHmopqR5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8aWyL/F1Ef/xdSH/8XUx//GFQg/xhUIP8YVSD/GFYg/xlXIf8ZWCH/GVki/xlaIv8aWyL/ + Glsj/xpcI/8aXSP/G14j/xxfJK8fayroH2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/Glsk/xdQH/8eaWD/Hmpg/xhTIP8YVCH/GFQh/xlVIf8ZViL/GVci/xlYIv8aWSP/ + Gloj/xpbJP8bWyT/G1wk/xtdJf8bXiX/G18l6SBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/IG0r/xtbJP8eaFr/JYKy/ymT3/8pk9//JYKu/x5nVP8ZVSL/GVYi/xlXIv8aWCP/ + Glgj/xpZI/8bWyT/G1sk/xtcJP8bXSX/HF4l/xxfJf8cYCb/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/yBuLf8gbi3/IG4t/yBuLf8dZUD/JIGn/ymU3/8upPf/L6j9/y+o/f8upPf/KZTf/ySApf8cYkL/ + GVcj/xlYJP8aWCT/Glkl/xpaJf8bWyX/G1wm/xtdJv8bXib/HF8n/xxgJ/8hcC7/IXAu/yFwLv8hcC7/ + IXAu/yFwLv8hcC7/IXAu/yFwLv8hcS//JHx+/ymR1P8vpfb/MKn8/yybzf8gblr/IGxY/yyazP8wqfz/ + L6X2/yqR1P8gdHH/Glgk/xpZJf8bWiX/G1sl/xtcJv8bXSb/HF4n/xxfJ/8cYCf/HGEo/yJxL/8icS// + InEv/yJxL/8icS//InEv/yJxL/8icS//I3Q7/yeHqv8tn+z/MKr8/y6f2P8hcmb/GFEi/xlSIv8ZUyL/ + GVQj/yJ0Z/8un9j/MKr8/y2f7P8lhKP/HF4z/xtaJf8bWyb/HFwm/xxdJ/8cXif/HV8n/x1gKP8dYSj/ + LHg6/yVzM/8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yR0PP8pj73/MKn5/zCo9P8mgYn/GVAl/xhQIv8ZUCP/ + GVIj/xlTJP8aVCT/GlQk/xtXKP8nhY3/MKr2/zCp+f8pjr3/HV8z/xxbJ/8cXCf/HF0o/x1dKP8dXyn/ + HWAp/x5hKv9SkV3/UpFd/0mLVf8+hEr/M35A/yh3Nv8kdjv/KpPA/zGr+/8unc3/HWBC/xhOIv8ZTyL/ + GVAj/xlRI/8ZUiP/GlMk/xpUJP8aVSX/G1Yl/xtXJf8gaEn/LqDT/zGr+/8qk8D/HmAy/x1cKP8dXSj/ + HV4p/x5fKf8eYCr/HmEq/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1Smuf9Jtvv/NZy9/1l9Xf9ig2L/ + Y4Ni/2OEYv9jhWL/Y4Vi/2OGY/9jh2P/ZIdk/2SIZP9kiWT/ZIlk/2WKZP9ahWL/MJvC/zKt+/8qkKn/ + HVwo/x1dKf8eXin/Hl8p/x5gKv8fYiv/WJdl/1iXZf9Yl2X/WJdl/1iXZf9bn4j/YsD6/16xzf/O1Mb/ + 19nN/8TKuv+/xrT/v8az/7/Gs/+/xrP/v8e0/7/HtP+/x7T/v8e0/7/ItP+/yLT/v8i0/83Swv++ybb/ + Lp3D/zKt+v8jdV7/HV4q/x1fKv8eYCv/HmEr/x5iLP9cmmj/XJpo/1yaaP9cmmj/XJpo/2W73/9lv+3/ + VIBm//v07f9fgmT/Unpa/1B4WP88akX/IFUr/xpRJP8nWzH/J1wx/xtUJv8bVSb/G1Yn/xxXJ/8cWCj/ + LGQ1//nw5/8gZT7/Mqrr/zGk1/8eXir/Hl8r/x5gK/8fYCv/H2Is/2CdbP9gnWz/YJ1s/2CdbP9ho4P/ + acX8/2Cgof9Velz/+/Xw/1+DZv9VfV7/VX1e/1V9Xv9UfV3/PGtF/5Cnjv+Ppoz/G1Qn/xtVJ/8cVij/ + HFgo/xxZKf8rYjX/+vLq/x1bKv8piIf/M7D7/yNwUP8eXyz/H2As/x9hLf8gYy3/Y59v/2Ofb/9jn2// + Y59v/2eztP9rxff/WYFq/1d8X//89vH/YoRp/1h+YP9Yf2D/WX9h/1mAYf9ZgWL/r7+t/6G0nv8eVir/ + HFUn/xxWKP8cVyj/HVgp/ytiNf/78+z/Hlsq/yBmPf80sPf/K5CX/x9fLP8fYCz/IGEt/yBiLv9no3P/ + Z6Nz/2ejc/9no3P/bb7X/2y81/9bfmL/W39j//z48/9mh2z/XIFk/1yBZP9miG3/sMCv/7LCsf/Z3tT/ + 2d7U/6/Arf+bspr/KV80/x1XKP8dWCn/K2M2//v17v8eXCv/Hl0r/zGjy/8wosb/H2As/yBhLf8gYi3/ + IGMu/2qld/9qpXf/aqV3/2qld/9xxuz/bLO//16AZf9egWX//fn1/2iJb/9eg2f/XoNn/2iKcP+xwbH/ + s8Oz/9vg1v/b4Nb/tMS0/7LDsv9Sflz/IFos/x1YKv8rYjb//Pbw/x5bLP8eXCz/Lpiq/zSt5f8fXy3/ + H2Au/yBhLv8gYy//bah6/22oev9tqHr/bal//3TM+/9rqaj/YIJo/2CDaP/9+vb/a4ty/2GFaf9ihmn/ + YoZq/2KHav9jiGv/tcW1/7XFtv9jimv/Y4ps/2OLbP9ahGT/LGM4/ytiN//89/L/Hlws/x5dLP8rioj/ + NbT5/yFkNf8gYS7/IGIv/yFjL/9xq37/cat+/3Grfv9yr4z/eM37/22loP9khGv/ZIVr//36+P9ujnX/ + ZYht/2WIbf9liW3/Zopt/2aKbv+1xbb/tcW2/2eMb/9njW//Z45v/2eOcP9mjm7/THtW//z49P8eWyz/ + H10s/yqDd/82tfn/I21H/yBhLv8hYi//IWMw/3Stgf90rYH/dK2B/3Wyk/97z/v/cKWe/2eGbv9nh2// + /fr4/3OSef9oim//aIpw/2mLcf9pjHH/aYxx/3KUef9ylHr/aY5y/2qPc/9qkHP/apBz/2uRc/91mX3/ + /fr3/yNeMP8fXC3/KYNz/za2+f8lcU3/IWEv/yFiMP8hZDH/d6+E/3evhP93r4T/eLWX/37Q+/9ypZ3/ + aolx/2qJcf/Z39j/4ebg/9je1v/Y3tb/2N/W/9jf1v/Y39f/2N/X/9jf1//Y39f/2N/X/9jg1//Y4Nf/ + 2ODX/+Hn4f/Z4tn/X4pp/yZhNP8pgG3/N7f5/yZyUv8hYTD/IWIw/yJjMf96soj/erKI/3qyiP97uJ3/ + gNL7/3Olm/9si3T/bYt1/3KQev+Yrp3/nbKh/7fGuf/r7un/nrSi/560ov+etaL/nrWj/561o/+etqT/ + 6+7q/7fJu/+ft6T/mrSg/3Wafv9xl3r/ZpBw/zWFcP83uPn/J3ZY/yFhMf8hYjH/ImYz/361i/9+tYv/ + frWL/3+7o/+E0/v/d6Wa/3CNd/9wjnj/cI94/3CPef9xkHn/kamX/+zw7P9yknr/cpN6/3KUev9ylHv/ + c5V7/3OWfP/s8Oz/k66Z/3SYfP90mH3/dJl9/3SZfv90mn7/c6mZ/0S8+P8oeF3/IWEx/yJlM/8sgEH/ + gbeO/4G3jv+Bt47/gr6n/4fU+/95pJj/c496/3OQev9zkXr/dJJ7/3SSe/94loD/7fDs/9Te1v+/zcL/ + v83C/7/Owv+/zsL/1d/X/+3w7f96nIP/dpl//3eaf/93m3//d5uA/3ecgf98rp3/ftH6/zOBaP8iZDL/ + LYJB/y+JRf+EuZH/hLmR/4S5kf+FwKz/idb7/32qof92kXz/dpJ9/3aTfv92k37/dpR+/3eUfv+Cnor/ + tca5/8DOw//Az8P/wM/E/8DPxP+2yLr/hKOL/3mbgv95m4L/eZyC/3mdgv96nYP/ep6D/4Cypf+J1vv/ + dKyc/zSGSv8wikf/MIpH/4e8lf+HvJX/h7yV/4i/oP+M1vX/jdj6/4rM2/+Fu7v/gKmc/3uYg/96l4L/ + e5eC/3uYgv97mIL/e5mD/3uZg/98moP/fJuE/3ychP98nIX/fJ2F/32dhf9+oIf/gq6g/4a/vP+Kzdz/ + jdj6/43W9f+HvqH/drKF/zOMSv8xi0j/ir6Y/4q+mP+Kvpj/ir6Y/4rBof+NysX/jtPk/4/Z+v+P2fr/ + j9j4/47U7P+Nz93/i8fO/4rEx/+JwcH/ib68/4m/vP+JwsL/isTH/4vJz/+Nz93/jtTs/4/Y+P+P2fr/ + j9n6/47T5v+My8j/i8Ch/4q+mP+Kvpj/Z6t4/zKNSf+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/ + jcKj/4/Iuf+Pzcn/kNHZ/5HV6P+R1/L/kdn2/5La+v+S2vv/ktr7/5La+v+R2fb/kdfy/5HV6P+Q0dj/ + j8zI/4/Iuf+NwqP/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/VKFp/4zAmvGQwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKe/5DEo/+QxKL/kMKe/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+NwZrxhr6XxJTFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/4/CncZ8u48p + k8ag9ZbHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+YyKX2 + mceoMgAAAAB8u48pjMKbxZbHo/KZyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+ayafz + lsaiyZvIqjMAAAAAgAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAIAAAAEoAAAAEAAAACAAAAABACAAAAAAAAAEAAATCwAAEwsAAAAAAAAAAAAA + HWcmSR1oJ+QdaCf/HWgn/x1oJ/8daCf/HWgn/xxkJf8XVB//F1Qf/xhVIP8YVyD/GVkh/xlaIv8ZXCLm + GlwiSx9rKeQfayn/H2sp/x9rKf8fayn/H2sp/x1nKP8aWTD/GVkw/xhUIf8ZViH/GVgi/xpaI/8aWyP/ + G10k/xteJOYgbiz/IG4s/yBuLP8gbiz/IG4s/x9rMf8idoH/K5jh/yuY4P8hdH//Gloq/xpYJP8aWiT/ + G1wl/xteJv8cYCb/InEv/yJxL/8icS//InEv/yN3Uf8rls//LJjM/x9rW/8ga1r/LJjM/yqUy/8dZUj/ + G1sl/xxdJv8cXyf/HWEo/z2DSv8zfUD/KHY2/yV8Wv8uoOD/I3Z4/xlQI/8ZUSP/GlQk/xtWJv8lfHz/ + LqHh/yBrU/8dXSj/HV4p/x5hKv9XlmP/V5Zj/1iYbP9Xs9//jbKr/5Kmjf+RpYv/kaaL/5GnjP+SqIz/ + kqmM/4Wvp/8votj/H2M2/x5fKv8eYSv/Xpxq/16cav9jr7L/XJaU/628qv9Te1z/QW5L/0NwSv87a0P/ + G1Yn/xxYKP+Tqo//Jn13/ymJk/8eYCz/H2Is/2Whcf9loXH/a73W/1p/ZP+wvq7/WoBi/3KSeP+luKX/ + kqqS/z9vR/8dWCn/k6uR/x9fL/8wocj/H2As/yBiLv9sp3n/bKd6/2+81P9fgmf/s8Kz/2CEaP93ln3/ + qryq/6q9q/9zlnr/MWY9/5SslP8eXCz/MaHE/yBhMP8gYi//c6yA/3OuiP90us3/ZoZt/7fFuP9niW7/ + Z4tv/36chP9+nYT/aY9x/2mPcf+vwrD/IF0t/zCct/8iaDz/IWMw/3mxhv95tJD/ebvM/2uKc/+xwbT/ + wc3C/87Yzv+7yr3/u8q9/87Zz//C0MP/ssa2/1eFYv8znbT/JGtD/yJjMf+Ato3/gLmZ/3+8yv9yj3n/ + cpB6/3yYg//I1Mr/mbCe/5mxn//I1cv/fp+G/3aafv92m3//bLnK/yhwSv8rfD//hruT/4a9nf+IzOP/ + f6uk/3qah/95loD/i6WS/560o/+etaT/jamU/3uchP99oov/gbKo/4nO5P9pqYP/MYtI/4y/mv+Mv5r/ + jMOn/47Mx/+P0t3/j9Lj/47P3/+Ozd3/js3d/47P4P+P0uL/j9Hd/47MyP+Mw6j/jL+a/1+mcf+OwZzt + ksSf/5LEn/+SxJ//ksSf/5LEn/+SxJ//ksSh/5LEof+SxJ//ksSf/5LEn/+SxJ//ksSf/5LEn/+Qw53t + jcOcUpTGou2YyKX/mMil/5jIpf+YyKX/mMil/5jIpf+YyKX/mMil/5jIpf+YyKX/mMil/5jIpf+Xx6Tv + mcimVwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAA= + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/SecureSandbox/Program.cs b/Demo_Source_Code/CSharpDemo/SecureSandbox/Program.cs new file mode 100644 index 0000000..8d04c2f --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/SecureSandbox/Program.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Windows.Forms; + +namespace SecureSandbox +{ + static class Program + { + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main() + { + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + Application.Run(new TrayForm()); + } + } +} diff --git a/Demo_Source_Code/CSharpDemo/SecureSandbox/Properties/AssemblyInfo.cs b/Demo_Source_Code/CSharpDemo/SecureSandbox/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..a24e9e2 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/SecureSandbox/Properties/AssemblyInfo.cs @@ -0,0 +1,37 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("SecureSandbox")] +[assembly: AssemblyDescription("EaseFilter secure sandbox")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("EaseFilter")] +[assembly: AssemblyProduct("SecureSandbox")] +[assembly: AssemblyCopyright("Copyright © EaseFilter 2019")] +[assembly: AssemblyTrademark("EaseFilter")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("bdbc2b5e-2c6f-423b-b2a6-1a3884d67dba")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("5.2.3.2001")] +//[assembly: AssemblyFileVersion("1.0.0.0")] + diff --git a/Demo_Source_Code/CSharpDemo/SecureSandbox/Properties/Resources.Designer.cs b/Demo_Source_Code/CSharpDemo/SecureSandbox/Properties/Resources.Designer.cs new file mode 100644 index 0000000..b86c064 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/SecureSandbox/Properties/Resources.Designer.cs @@ -0,0 +1,83 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace SecureSandbox.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // 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", "16.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + 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() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [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("SecureSandbox.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap about { + get { + object obj = ResourceManager.GetObject("about", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap Info { + get { + object obj = ResourceManager.GetObject("Info", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + } +} diff --git a/Demo_Source_Code/CSharpDemo/SecureSandbox/Properties/Resources.resx b/Demo_Source_Code/CSharpDemo/SecureSandbox/Properties/Resources.resx new file mode 100644 index 0000000..c7807d3 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/SecureSandbox/Properties/Resources.resx @@ -0,0 +1,127 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + ..\Info.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\about.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/SecureSandbox/Properties/Settings.Designer.cs b/Demo_Source_Code/CSharpDemo/SecureSandbox/Properties/Settings.Designer.cs new file mode 100644 index 0000000..2c48dd1 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/SecureSandbox/Properties/Settings.Designer.cs @@ -0,0 +1,26 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace SecureSandbox.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.10.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default { + get { + return defaultInstance; + } + } + } +} diff --git a/Demo_Source_Code/CSharpDemo/SecureSandbox/Properties/Settings.settings b/Demo_Source_Code/CSharpDemo/SecureSandbox/Properties/Settings.settings new file mode 100644 index 0000000..3964565 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/SecureSandbox/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + diff --git a/Demo_Source_Code/CSharpDemo/SecureSandbox/SecureSandbox.Designer.cs b/Demo_Source_Code/CSharpDemo/SecureSandbox/SecureSandbox.Designer.cs new file mode 100644 index 0000000..20cc4be --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/SecureSandbox/SecureSandbox.Designer.cs @@ -0,0 +1,448 @@ +namespace SecureSandbox +{ + partial class SecureSandbox + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(SecureSandbox)); + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.button_help = new System.Windows.Forms.Button(); + this.toolStrip1 = new System.Windows.Forms.ToolStrip(); + this.toolStripButton_StartFilter = new System.Windows.Forms.ToolStripButton(); + this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); + this.toolStripButton_Stop = new System.Windows.Forms.ToolStripButton(); + this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator(); + this.toolStripButton_EventViewer = new System.Windows.Forms.ToolStripButton(); + this.button_AddSandbox = new System.Windows.Forms.Button(); + this.groupBox3 = new System.Windows.Forms.GroupBox(); + this.button_SaveSandBox = new System.Windows.Forms.Button(); + this.groupBox5 = new System.Windows.Forms.GroupBox(); + this.checkBox_AllowFolderBrowsing = new System.Windows.Forms.CheckBox(); + this.button_ConfigProcessRights = new System.Windows.Forms.Button(); + this.checkBox_EnableEncryption = new System.Windows.Forms.CheckBox(); + this.checkBox_AllowSandboxRead = new System.Windows.Forms.CheckBox(); + this.checkBox_AllowReadEncryptedFiles = new System.Windows.Forms.CheckBox(); + this.checkBox_AllowSandboxChange = new System.Windows.Forms.CheckBox(); + this.groupBox4 = new System.Windows.Forms.GroupBox(); + this.button_ProcessFileAccessRights = new System.Windows.Forms.Button(); + this.checkBox_AllowExecute = new System.Windows.Forms.CheckBox(); + this.checkBox_AllowChangeRegistry = new System.Windows.Forms.CheckBox(); + this.checkBox_AllowReadRegistry = new System.Windows.Forms.CheckBox(); + this.textBox_SandboxFolder = new System.Windows.Forms.TextBox(); + this.label5 = new System.Windows.Forms.Label(); + this.button_SelectFolder = new System.Windows.Forms.Button(); + this.button_DeleteSandbox = new System.Windows.Forms.Button(); + this.groupBox2 = new System.Windows.Forms.GroupBox(); + this.listView_Sandbox = new System.Windows.Forms.ListView(); + this.groupBox1.SuspendLayout(); + this.toolStrip1.SuspendLayout(); + this.groupBox3.SuspendLayout(); + this.groupBox5.SuspendLayout(); + this.groupBox4.SuspendLayout(); + this.groupBox2.SuspendLayout(); + this.SuspendLayout(); + // + // groupBox1 + // + this.groupBox1.Controls.Add(this.button_help); + this.groupBox1.Controls.Add(this.toolStrip1); + this.groupBox1.Controls.Add(this.button_AddSandbox); + this.groupBox1.Controls.Add(this.groupBox3); + this.groupBox1.Controls.Add(this.button_DeleteSandbox); + this.groupBox1.Controls.Add(this.groupBox2); + this.groupBox1.Dock = System.Windows.Forms.DockStyle.Fill; + this.groupBox1.Location = new System.Drawing.Point(0, 0); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size(544, 520); + this.groupBox1.TabIndex = 4; + this.groupBox1.TabStop = false; + // + // button_help + // + this.button_help.Image = ((System.Drawing.Image)(resources.GetObject("button_help.Image"))); + this.button_help.Location = new System.Drawing.Point(485, 471); + this.button_help.Name = "button_help"; + this.button_help.Size = new System.Drawing.Size(36, 33); + this.button_help.TabIndex = 96; + this.button_help.UseVisualStyleBackColor = true; + this.button_help.Click += new System.EventHandler(this.button_help_Click); + // + // toolStrip1 + // + this.toolStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.toolStripButton_StartFilter, + this.toolStripSeparator1, + this.toolStripButton_Stop, + this.toolStripSeparator2, + this.toolStripButton_EventViewer}); + this.toolStrip1.Location = new System.Drawing.Point(3, 16); + this.toolStrip1.Name = "toolStrip1"; + this.toolStrip1.Size = new System.Drawing.Size(538, 25); + this.toolStrip1.TabIndex = 95; + this.toolStrip1.Text = "toolStrip1"; + // + // toolStripButton_StartFilter + // + this.toolStripButton_StartFilter.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton_StartFilter.Image"))); + this.toolStripButton_StartFilter.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButton_StartFilter.Name = "toolStripButton_StartFilter"; + this.toolStripButton_StartFilter.Size = new System.Drawing.Size(91, 22); + this.toolStripButton_StartFilter.Text = "Start Service"; + this.toolStripButton_StartFilter.Click += new System.EventHandler(this.toolStripButton_StartFilter_Click); + // + // toolStripSeparator1 + // + this.toolStripSeparator1.Name = "toolStripSeparator1"; + this.toolStripSeparator1.Size = new System.Drawing.Size(6, 25); + // + // toolStripButton_Stop + // + this.toolStripButton_Stop.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton_Stop.Image"))); + this.toolStripButton_Stop.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButton_Stop.Name = "toolStripButton_Stop"; + this.toolStripButton_Stop.Size = new System.Drawing.Size(91, 22); + this.toolStripButton_Stop.Text = "Stop Service"; + this.toolStripButton_Stop.Click += new System.EventHandler(this.toolStripButton_Stop_Click); + // + // toolStripSeparator2 + // + this.toolStripSeparator2.Name = "toolStripSeparator2"; + this.toolStripSeparator2.Size = new System.Drawing.Size(6, 25); + // + // toolStripButton_EventViewer + // + this.toolStripButton_EventViewer.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton_EventViewer.Image"))); + this.toolStripButton_EventViewer.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButton_EventViewer.Name = "toolStripButton_EventViewer"; + this.toolStripButton_EventViewer.Size = new System.Drawing.Size(93, 22); + this.toolStripButton_EventViewer.Text = "Event viewer"; + this.toolStripButton_EventViewer.Click += new System.EventHandler(this.toolStripButton_EventViewer_Click); + // + // button_AddSandbox + // + this.button_AddSandbox.Location = new System.Drawing.Point(20, 476); + this.button_AddSandbox.Name = "button_AddSandbox"; + this.button_AddSandbox.Size = new System.Drawing.Size(94, 23); + this.button_AddSandbox.TabIndex = 94; + this.button_AddSandbox.Text = "Add Sandbox"; + this.button_AddSandbox.UseVisualStyleBackColor = true; + this.button_AddSandbox.Click += new System.EventHandler(this.button_AddSandbox_Click); + // + // groupBox3 + // + this.groupBox3.Controls.Add(this.button_SaveSandBox); + this.groupBox3.Controls.Add(this.groupBox5); + this.groupBox3.Controls.Add(this.groupBox4); + this.groupBox3.Controls.Add(this.textBox_SandboxFolder); + this.groupBox3.Controls.Add(this.label5); + this.groupBox3.Controls.Add(this.button_SelectFolder); + this.groupBox3.Location = new System.Drawing.Point(17, 53); + this.groupBox3.Name = "groupBox3"; + this.groupBox3.Size = new System.Drawing.Size(507, 277); + this.groupBox3.TabIndex = 57; + this.groupBox3.TabStop = false; + this.groupBox3.Text = "Sandbox Settings"; + // + // button_SaveSandBox + // + this.button_SaveSandBox.BackColor = System.Drawing.Color.Gold; + this.button_SaveSandBox.Location = new System.Drawing.Point(363, 251); + this.button_SaveSandBox.Name = "button_SaveSandBox"; + this.button_SaveSandBox.Size = new System.Drawing.Size(131, 26); + this.button_SaveSandBox.TabIndex = 97; + this.button_SaveSandBox.Text = "Save Sandbox"; + this.button_SaveSandBox.UseVisualStyleBackColor = false; + this.button_SaveSandBox.Click += new System.EventHandler(this.button_SaveSandBox_Click); + // + // groupBox5 + // + this.groupBox5.Controls.Add(this.checkBox_AllowFolderBrowsing); + this.groupBox5.Controls.Add(this.button_ConfigProcessRights); + this.groupBox5.Controls.Add(this.checkBox_EnableEncryption); + this.groupBox5.Controls.Add(this.checkBox_AllowSandboxRead); + this.groupBox5.Controls.Add(this.checkBox_AllowReadEncryptedFiles); + this.groupBox5.Controls.Add(this.checkBox_AllowSandboxChange); + this.groupBox5.Location = new System.Drawing.Point(14, 144); + this.groupBox5.Name = "groupBox5"; + this.groupBox5.Size = new System.Drawing.Size(492, 101); + this.groupBox5.TabIndex = 78; + this.groupBox5.TabStop = false; + this.groupBox5.Text = "The default file access rights of the sandbox to all processes"; + // + // checkBox_AllowFolderBrowsing + // + this.checkBox_AllowFolderBrowsing.AutoSize = true; + this.checkBox_AllowFolderBrowsing.Checked = true; + this.checkBox_AllowFolderBrowsing.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBox_AllowFolderBrowsing.Location = new System.Drawing.Point(7, 76); + this.checkBox_AllowFolderBrowsing.Name = "checkBox_AllowFolderBrowsing"; + this.checkBox_AllowFolderBrowsing.Size = new System.Drawing.Size(125, 17); + this.checkBox_AllowFolderBrowsing.TabIndex = 80; + this.checkBox_AllowFolderBrowsing.Text = "Allow browsing folder"; + this.checkBox_AllowFolderBrowsing.UseVisualStyleBackColor = true; + this.checkBox_AllowFolderBrowsing.CheckedChanged += new System.EventHandler(this.checkBox_AllowFolderBrowsing_CheckedChanged); + // + // button_ConfigProcessRights + // + this.button_ConfigProcessRights.BackColor = System.Drawing.SystemColors.GradientActiveCaption; + this.button_ConfigProcessRights.Location = new System.Drawing.Point(372, 34); + this.button_ConfigProcessRights.Name = "button_ConfigProcessRights"; + this.button_ConfigProcessRights.Size = new System.Drawing.Size(108, 23); + this.button_ConfigProcessRights.TabIndex = 58; + this.button_ConfigProcessRights.Text = "Advance Settings"; + this.button_ConfigProcessRights.UseVisualStyleBackColor = false; + this.button_ConfigProcessRights.Click += new System.EventHandler(this.button_ConfigProcessRights_Click); + // + // checkBox_EnableEncryption + // + this.checkBox_EnableEncryption.AutoSize = true; + this.checkBox_EnableEncryption.Checked = true; + this.checkBox_EnableEncryption.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBox_EnableEncryption.Location = new System.Drawing.Point(181, 34); + this.checkBox_EnableEncryption.Name = "checkBox_EnableEncryption"; + this.checkBox_EnableEncryption.Size = new System.Drawing.Size(111, 17); + this.checkBox_EnableEncryption.TabIndex = 30; + this.checkBox_EnableEncryption.Text = "Enable encryption"; + this.checkBox_EnableEncryption.UseVisualStyleBackColor = true; + this.checkBox_EnableEncryption.CheckedChanged += new System.EventHandler(this.checkBox_EnableEncryption_CheckedChanged); + // + // checkBox_AllowSandboxRead + // + this.checkBox_AllowSandboxRead.AutoSize = true; + this.checkBox_AllowSandboxRead.Checked = true; + this.checkBox_AllowSandboxRead.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBox_AllowSandboxRead.Location = new System.Drawing.Point(7, 34); + this.checkBox_AllowSandboxRead.Name = "checkBox_AllowSandboxRead"; + this.checkBox_AllowSandboxRead.Size = new System.Drawing.Size(120, 17); + this.checkBox_AllowSandboxRead.TabIndex = 29; + this.checkBox_AllowSandboxRead.Text = "Allow file being read"; + this.checkBox_AllowSandboxRead.UseVisualStyleBackColor = true; + this.checkBox_AllowSandboxRead.CheckedChanged += new System.EventHandler(this.checkBox_AllowSandboxRead_CheckedChanged); + // + // checkBox_AllowReadEncryptedFiles + // + this.checkBox_AllowReadEncryptedFiles.AutoSize = true; + this.checkBox_AllowReadEncryptedFiles.Checked = true; + this.checkBox_AllowReadEncryptedFiles.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBox_AllowReadEncryptedFiles.Location = new System.Drawing.Point(181, 59); + this.checkBox_AllowReadEncryptedFiles.Name = "checkBox_AllowReadEncryptedFiles"; + this.checkBox_AllowReadEncryptedFiles.Size = new System.Drawing.Size(170, 17); + this.checkBox_AllowReadEncryptedFiles.TabIndex = 28; + this.checkBox_AllowReadEncryptedFiles.Text = "Allow encrypted file being read"; + this.checkBox_AllowReadEncryptedFiles.UseVisualStyleBackColor = true; + this.checkBox_AllowReadEncryptedFiles.CheckedChanged += new System.EventHandler(this.checkBox_AllowReadEncryptedFiles_CheckedChanged); + // + // checkBox_AllowSandboxChange + // + this.checkBox_AllowSandboxChange.AutoSize = true; + this.checkBox_AllowSandboxChange.Checked = true; + this.checkBox_AllowSandboxChange.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBox_AllowSandboxChange.Location = new System.Drawing.Point(7, 54); + this.checkBox_AllowSandboxChange.Name = "checkBox_AllowSandboxChange"; + this.checkBox_AllowSandboxChange.Size = new System.Drawing.Size(141, 17); + this.checkBox_AllowSandboxChange.TabIndex = 15; + this.checkBox_AllowSandboxChange.Text = "Allow file being changed"; + this.checkBox_AllowSandboxChange.UseVisualStyleBackColor = true; + this.checkBox_AllowSandboxChange.CheckedChanged += new System.EventHandler(this.checkBox_AllowSandboxChange_CheckedChanged); + // + // groupBox4 + // + this.groupBox4.Controls.Add(this.button_ProcessFileAccessRights); + this.groupBox4.Controls.Add(this.checkBox_AllowExecute); + this.groupBox4.Controls.Add(this.checkBox_AllowChangeRegistry); + this.groupBox4.Controls.Add(this.checkBox_AllowReadRegistry); + this.groupBox4.Location = new System.Drawing.Point(14, 60); + this.groupBox4.Name = "groupBox4"; + this.groupBox4.Size = new System.Drawing.Size(492, 85); + this.groupBox4.TabIndex = 77; + this.groupBox4.TabStop = false; + this.groupBox4.Text = "The policy of the executable binaries inside the sandbox"; + // + // button_ProcessFileAccessRights + // + this.button_ProcessFileAccessRights.BackColor = System.Drawing.SystemColors.GradientActiveCaption; + this.button_ProcessFileAccessRights.Location = new System.Drawing.Point(177, 51); + this.button_ProcessFileAccessRights.Name = "button_ProcessFileAccessRights"; + this.button_ProcessFileAccessRights.Size = new System.Drawing.Size(303, 23); + this.button_ProcessFileAccessRights.TabIndex = 96; + this.button_ProcessFileAccessRights.Text = "Configure executable binaries file access rights"; + this.button_ProcessFileAccessRights.UseVisualStyleBackColor = false; + this.button_ProcessFileAccessRights.Click += new System.EventHandler(this.button_ProcessFileAccessRights_Click); + // + // checkBox_AllowExecute + // + this.checkBox_AllowExecute.AutoSize = true; + this.checkBox_AllowExecute.Location = new System.Drawing.Point(177, 28); + this.checkBox_AllowExecute.Name = "checkBox_AllowExecute"; + this.checkBox_AllowExecute.Size = new System.Drawing.Size(242, 17); + this.checkBox_AllowExecute.TabIndex = 17; + this.checkBox_AllowExecute.Text = "Allow binaries inside sandbox being executed"; + this.checkBox_AllowExecute.UseVisualStyleBackColor = true; + this.checkBox_AllowExecute.CheckedChanged += new System.EventHandler(this.checkBox_AllowExecute_CheckedChanged); + // + // checkBox_AllowChangeRegistry + // + this.checkBox_AllowChangeRegistry.AutoSize = true; + this.checkBox_AllowChangeRegistry.Location = new System.Drawing.Point(23, 51); + this.checkBox_AllowChangeRegistry.Name = "checkBox_AllowChangeRegistry"; + this.checkBox_AllowChangeRegistry.Size = new System.Drawing.Size(134, 17); + this.checkBox_AllowChangeRegistry.TabIndex = 16; + this.checkBox_AllowChangeRegistry.Text = "Allow registry changing"; + this.checkBox_AllowChangeRegistry.UseVisualStyleBackColor = true; + // + // checkBox_AllowReadRegistry + // + this.checkBox_AllowReadRegistry.AutoSize = true; + this.checkBox_AllowReadRegistry.Checked = true; + this.checkBox_AllowReadRegistry.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBox_AllowReadRegistry.Location = new System.Drawing.Point(23, 28); + this.checkBox_AllowReadRegistry.Name = "checkBox_AllowReadRegistry"; + this.checkBox_AllowReadRegistry.Size = new System.Drawing.Size(125, 17); + this.checkBox_AllowReadRegistry.TabIndex = 21; + this.checkBox_AllowReadRegistry.Text = "Allow registry reading"; + this.checkBox_AllowReadRegistry.UseVisualStyleBackColor = true; + // + // textBox_SandboxFolder + // + this.textBox_SandboxFolder.Location = new System.Drawing.Point(98, 21); + this.textBox_SandboxFolder.Name = "textBox_SandboxFolder"; + this.textBox_SandboxFolder.Size = new System.Drawing.Size(321, 20); + this.textBox_SandboxFolder.TabIndex = 37; + this.textBox_SandboxFolder.Text = "c:\\MySandbox"; + // + // label5 + // + this.label5.AutoSize = true; + this.label5.Location = new System.Drawing.Point(11, 24); + this.label5.Name = "label5"; + this.label5.Size = new System.Drawing.Size(81, 13); + this.label5.TabIndex = 36; + this.label5.Text = "Sandbox Folder"; + // + // button_SelectFolder + // + this.button_SelectFolder.Location = new System.Drawing.Point(434, 21); + this.button_SelectFolder.Name = "button_SelectFolder"; + this.button_SelectFolder.Size = new System.Drawing.Size(60, 20); + this.button_SelectFolder.TabIndex = 38; + this.button_SelectFolder.Text = "..."; + this.button_SelectFolder.UseVisualStyleBackColor = true; + this.button_SelectFolder.Click += new System.EventHandler(this.button_SelectFolder_Click); + // + // button_DeleteSandbox + // + this.button_DeleteSandbox.Location = new System.Drawing.Point(319, 476); + this.button_DeleteSandbox.Name = "button_DeleteSandbox"; + this.button_DeleteSandbox.Size = new System.Drawing.Size(131, 23); + this.button_DeleteSandbox.TabIndex = 52; + this.button_DeleteSandbox.Text = "Delete Sandbox"; + this.button_DeleteSandbox.UseVisualStyleBackColor = true; + this.button_DeleteSandbox.Click += new System.EventHandler(this.button_DeleteSandbox_Click); + // + // groupBox2 + // + this.groupBox2.Controls.Add(this.listView_Sandbox); + this.groupBox2.Location = new System.Drawing.Point(17, 336); + this.groupBox2.Name = "groupBox2"; + this.groupBox2.Size = new System.Drawing.Size(507, 116); + this.groupBox2.TabIndex = 50; + this.groupBox2.TabStop = false; + this.groupBox2.Text = "Sandbox Collection"; + // + // listView_Sandbox + // + this.listView_Sandbox.Dock = System.Windows.Forms.DockStyle.Fill; + this.listView_Sandbox.FullRowSelect = true; + this.listView_Sandbox.HideSelection = false; + this.listView_Sandbox.Location = new System.Drawing.Point(3, 16); + this.listView_Sandbox.Name = "listView_Sandbox"; + this.listView_Sandbox.Size = new System.Drawing.Size(501, 97); + this.listView_Sandbox.TabIndex = 1; + this.listView_Sandbox.UseCompatibleStateImageBehavior = false; + this.listView_Sandbox.View = System.Windows.Forms.View.Details; + this.listView_Sandbox.SelectedIndexChanged += new System.EventHandler(this.listView_Sandbox_SelectedIndexChanged); + // + // SecureSandbox + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(544, 520); + this.Controls.Add(this.groupBox1); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.MaximizeBox = false; + this.Name = "SecureSandbox"; + this.Text = "Easefilter Secure Sandbox"; + this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.SecureSandbox_FormClosed); + this.groupBox1.ResumeLayout(false); + this.groupBox1.PerformLayout(); + this.toolStrip1.ResumeLayout(false); + this.toolStrip1.PerformLayout(); + this.groupBox3.ResumeLayout(false); + this.groupBox3.PerformLayout(); + this.groupBox5.ResumeLayout(false); + this.groupBox5.PerformLayout(); + this.groupBox4.ResumeLayout(false); + this.groupBox4.PerformLayout(); + this.groupBox2.ResumeLayout(false); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.GroupBox groupBox1; + private System.Windows.Forms.Button button_DeleteSandbox; + private System.Windows.Forms.GroupBox groupBox2; + private System.Windows.Forms.ListView listView_Sandbox; + private System.Windows.Forms.Button button_SelectFolder; + private System.Windows.Forms.TextBox textBox_SandboxFolder; + private System.Windows.Forms.Label label5; + private System.Windows.Forms.GroupBox groupBox3; + private System.Windows.Forms.GroupBox groupBox4; + private System.Windows.Forms.CheckBox checkBox_AllowExecute; + private System.Windows.Forms.CheckBox checkBox_AllowChangeRegistry; + private System.Windows.Forms.CheckBox checkBox_AllowReadRegistry; + private System.Windows.Forms.GroupBox groupBox5; + private System.Windows.Forms.CheckBox checkBox_AllowSandboxRead; + private System.Windows.Forms.CheckBox checkBox_AllowReadEncryptedFiles; + private System.Windows.Forms.CheckBox checkBox_AllowSandboxChange; + private System.Windows.Forms.CheckBox checkBox_EnableEncryption; + private System.Windows.Forms.Button button_ConfigProcessRights; + private System.Windows.Forms.Button button_AddSandbox; + private System.Windows.Forms.CheckBox checkBox_AllowFolderBrowsing; + private System.Windows.Forms.Button button_ProcessFileAccessRights; + private System.Windows.Forms.ToolStrip toolStrip1; + private System.Windows.Forms.ToolStripButton toolStripButton_StartFilter; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator1; + private System.Windows.Forms.ToolStripButton toolStripButton_Stop; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator2; + private System.Windows.Forms.ToolStripButton toolStripButton_EventViewer; + private System.Windows.Forms.Button button_help; + private System.Windows.Forms.Button button_SaveSandBox; + } +} + diff --git a/Demo_Source_Code/CSharpDemo/SecureSandbox/SecureSandbox.cs b/Demo_Source_Code/CSharpDemo/SecureSandbox/SecureSandbox.cs new file mode 100644 index 0000000..7e7342d --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/SecureSandbox/SecureSandbox.cs @@ -0,0 +1,696 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Reflection; +using System.IO; +using System.Diagnostics; +using System.Windows.Forms; +using System.Runtime.InteropServices; + +using EaseFilter.FilterControl; +using EaseFilter.CommonObjects; + +namespace SecureSandbox +{ + public partial class SecureSandbox : Form + { + /// + /// Filter rule is the access control setting for the specific files. + /// + /// for example: set file filter mask c:\test\*, you can set the access rights to the files in c:\test. + /// you also can add the specific process or user access rights to the files in c:\test + /// + FileFilterRule selectedFilterRule = null; + + /// + /// Process filter rule is the access control of the process, set the file access rights to this process. + /// + /// for example: set the process filter mask: c:\test\*.exe, you can control the processes which were launched from c:\test, set the file access rights + /// to this process, not allow the process to change the files in c:\Windows or other sensitive files. + /// + ProcessFilterRule selectedProcessFilterRule = null; + + /// + /// Registry filter rule is the access control of the registry, allow the process to access or change the registry. + /// + RegistryFilterRule selectedRegistryFilterRule = null; + + + EncryptEventHandler encryptEventHandler = new EncryptEventHandler(); + FilterControl filterControl = new FilterControl(); + + public SecureSandbox() + { + GlobalConfig.filterType = FilterAPI.FilterType.CONTROL_FILTER | FilterAPI.FilterType.ENCRYPTION_FILTER + | FilterAPI.FilterType.PROCESS_FILTER | FilterAPI.FilterType.REGISTRY_FILTER; + + InitializeComponent(); + StartPosition = FormStartPosition.CenterScreen; + + InitListView(); + + DisplayVersion(); + } + + ~SecureSandbox() + { + GlobalConfig.Stop(); + } + + void SendSettingsToFilter() + { + try + { + filterControl.ClearFilters(); + foreach (FileFilterRule filterRule in GlobalConfig.FilterRules.Values) + { + FileFilter fileFilter = filterRule.ToFileFilter(); + fileFilter.OnFilterRequestEncryptKey += encryptEventHandler.OnFilterRequestEncryptKey; + filterControl.AddFilter(fileFilter); + } + + foreach (ProcessFilterRule filterRule in GlobalConfig.ProcessFilterRules.Values) + { + ProcessFilter processFilter = filterRule.ToProcessFilter(); + filterControl.AddFilter(processFilter); + } + + foreach (RegistryFilterRule filterRule in GlobalConfig.RegistryFilterRules.Values) + { + RegistryFilter registryFilter = filterRule.ToRegistryFilter(); + filterControl.AddFilter(registryFilter); + } + + string lastError = string.Empty; + if (!filterControl.SendConfigSettingsToFilter(ref lastError)) + { + MessageBox.Show(lastError, "SendConfigSettingsToFilter", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + catch (Exception ex) + { + MessageBox.Show("SendConfigSettingsToFilter exception:" + ex.Message, "SendConfigSettingsToFilter", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + + private void toolStripButton_StartFilter_Click(object sender, EventArgs e) + { + try + { + //Purchase a license key with the link: http://www.easefilter.com/Order.htm + //Email us to request a trial key: info@easefilter.com //free email is not accepted. + string licenseKey = GlobalConfig.LicenseKey; + + string lastError = string.Empty; + + bool ret = filterControl.StartFilter(GlobalConfig.filterType, GlobalConfig.FilterConnectionThreads, GlobalConfig.ConnectionTimeOut, licenseKey, ref lastError); + if (!ret) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("Start filter failed." + lastError, "StartFilter", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + SendSettingsToFilter(); + + toolStripButton_StartFilter.Enabled = false; + toolStripButton_Stop.Enabled = true; + + EventManager.WriteMessage(102, "StartFilter", EventLevel.Information, "Start filter service succeeded."); + } + catch (Exception ex) + { + EventManager.WriteMessage(104, "StartFilter", EventLevel.Error, "Start filter service failed with error " + ex.Message); + } + } + + private void toolStripButton_Stop_Click(object sender, EventArgs e) + { + FilterAPI.ResetConfigData(); + filterControl.StopFilter(); + + toolStripButton_StartFilter.Enabled = true; + toolStripButton_Stop.Enabled = false; + } + + private void SecureSandbox_FormClosed(object sender, FormClosedEventArgs e) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + if (MessageBox.Show("Do you want to minimize to system tray?", "Close", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes) + { + + } + else + { + FilterAPI.ResetConfigData(); + GlobalConfig.Stop(); + filterControl.StopFilter(); + Application.Exit(); + } + } + + + private void DisplayVersion() + { + string version = Assembly.GetExecutingAssembly().GetName().Version.ToString(); + try + { + string filterDllPath = Path.Combine(GlobalConfig.AssemblyPath, "FilterAPI.Dll"); + version = FileVersionInfo.GetVersionInfo(filterDllPath).ProductVersion; + } + catch (Exception ex) + { + EventManager.WriteMessage(43, "LoadFilterAPI Dll", EventLevel.Error, "FilterAPI.dll can't be found." + ex.Message); + } + + this.Text += " Version: " + version; + } + + void SetSelectedFilterRule(FileFilterRule filterRule) + { + selectedFilterRule = filterRule; + selectedProcessFilterRule = GlobalConfig.GetProcessFilterRule("", selectedFilterRule.IncludeFileFilterMask); + + if (null == selectedProcessFilterRule) + { + selectedProcessFilterRule = new ProcessFilterRule(); + } + + selectedRegistryFilterRule = GlobalConfig.GetRegistryFilterRule("", selectedFilterRule.IncludeFileFilterMask); + if (null == selectedRegistryFilterRule) + { + selectedRegistryFilterRule = new RegistryFilterRule(); + } + + } + + public void InitListView() + { + try + { + //init ListView control + listView_Sandbox.Clear(); //clear control + //create column header for ListView + listView_Sandbox.Columns.Add("#", 20, System.Windows.Forms.HorizontalAlignment.Left); + listView_Sandbox.Columns.Add("Sandbox Folder", 330, System.Windows.Forms.HorizontalAlignment.Left); + listView_Sandbox.Columns.Add("Access Flag", 100, System.Windows.Forms.HorizontalAlignment.Left); + + foreach (FileFilterRule rule in GlobalConfig.FilterRules.Values) + { + string[] itemStr = new string[listView_Sandbox.Columns.Count]; + itemStr[0] = listView_Sandbox.Items.Count.ToString(); + itemStr[1] = rule.IncludeFileFilterMask; + itemStr[2] = rule.AccessFlag.ToString(); + + ListViewItem item = new ListViewItem(itemStr, 0); + item.Tag = rule; + listView_Sandbox.Items.Add(item); + + SetSelectedFilterRule(rule); + } + + InitSandbox(); + } + catch (Exception ex) + { + EventManager.WriteMessage(127, "InitListView", EventLevel.Error, "InitListView failed with error:" + ex.Message); + } + } + + void InitNewFilterRule() + { + selectedFilterRule = new FileFilterRule(); + selectedProcessFilterRule = new ProcessFilterRule(); + selectedRegistryFilterRule = new RegistryFilterRule(); + + textBox_SandboxFolder.Text = "c:\\newSandboxFolder"; + + selectedFilterRule.IncludeFileFilterMask = textBox_SandboxFolder.Text.Trim() + "\\*"; + selectedProcessFilterRule.ProcessNameFilterMask = textBox_SandboxFolder.Text.Trim() + "\\*"; + selectedRegistryFilterRule.ProcessNameFilterMask = textBox_SandboxFolder.Text.Trim() + "\\*"; + + //by default allow the binaries inside the sandbox to read/write the registry + selectedRegistryFilterRule.AccessFlag = FilterAPI.MAX_REGITRY_ACCESS_FLAG; + + selectedProcessFilterRule.ProcessId = selectedRegistryFilterRule.ProcessId = ""; + //by default not allow the executable + selectedProcessFilterRule.ControlFlag = (uint)FilterAPI.ProcessControlFlag.DENY_NEW_PROCESS_CREATION; + //set the maximum access rights to the sandbox for all binaries inside the sandbox + selectedProcessFilterRule.FileAccessRights = textBox_SandboxFolder.Text + "!" + FilterAPI.ALLOW_MAX_RIGHT_ACCESS.ToString() + ";"; + //allow the windows dll or exe to be read by the process, or it can't be loaded. + selectedProcessFilterRule.FileAccessRights += "c:\\windows\\*!" + FilterAPI.ALLOW_FILE_READ_ACCESS + ";"; + //No access rights to all other folders by default. + selectedProcessFilterRule.FileAccessRights += "*!" + ((uint)FilterAPI.AccessFlag.LEAST_ACCESS_FLAG).ToString() + ";"; + + //by default the sandbox folder doesn't allow being read/write by processes, if the processes want to access the sandbox, it needs to add process rights. + selectedFilterRule.AccessFlag = (uint)(FilterAPI.ALLOW_MAX_RIGHT_ACCESS|(uint)FilterAPI.AccessFlag.ENABLE_FILE_ENCRYPTION_RULE); + //Not allow the explorer.exe to read the encrypted files, when you copy the encrypted files from exploer, the file can stay encrypted. + selectedFilterRule.ProcessNameRights = "explorer.exe!" + ((uint)FilterAPI.ALLOW_MAX_RIGHT_ACCESS &~(uint)(FilterAPI.AccessFlag.ALLOW_READ_ENCRYPTED_FILES)).ToString() + ";"; + } + + private void InitSandbox() + { + try + { + if (selectedFilterRule == null) + { + InitNewFilterRule(); + } + else + { + textBox_SandboxFolder.Text = selectedFilterRule.IncludeFileFilterMask.Replace("\\*",""); + } + + uint fileAccessFlag = selectedFilterRule.AccessFlag; + uint processControlFlag = selectedProcessFilterRule.ControlFlag; + uint processRegistryControlFlag = selectedRegistryFilterRule.AccessFlag; + + if ((processRegistryControlFlag & (uint)FilterAPI.ALLOW_READ_REGITRY_ACCESS_FLAG) != 0) + { + checkBox_AllowReadRegistry.Checked = true; + } + else + { + checkBox_AllowReadRegistry.Checked = false; + } + + if ((processRegistryControlFlag & (uint)FilterAPI.ALLOW_CHANGE_REGITRY_ACCESS_FLAG) != 0) + { + checkBox_AllowChangeRegistry.Checked = true; + } + else + { + checkBox_AllowChangeRegistry.Checked = false; + } + + if ((processControlFlag & (uint)FilterAPI.ProcessControlFlag.DENY_NEW_PROCESS_CREATION) != 0) + { + checkBox_AllowExecute.Checked = false; + } + else + { + checkBox_AllowExecute.Checked = true; + } + + if ((fileAccessFlag & (uint)FilterAPI.ALLOW_FILE_READ_ACCESS) != 0) + { + checkBox_AllowSandboxRead.Checked = true; + } + else + { + checkBox_AllowSandboxRead.Checked = false; + } + + if ((fileAccessFlag & (uint)FilterAPI.ALLOW_FILE_CHANGE_ACCESS) != 0) + { + checkBox_AllowSandboxChange.Checked = true; + } + else + { + checkBox_AllowSandboxChange.Checked = false; + } + + if ((fileAccessFlag & (uint)FilterAPI.AccessFlag.ALLOW_DIRECTORY_LIST_ACCESS) != 0) + { + checkBox_AllowFolderBrowsing.Checked = true; + } + else + { + checkBox_AllowFolderBrowsing.Checked = false; + } + + + if ((fileAccessFlag & (uint)FilterAPI.AccessFlag.ALLOW_READ_ENCRYPTED_FILES) != 0) + { + checkBox_AllowReadEncryptedFiles.Checked = true; + } + else + { + checkBox_AllowReadEncryptedFiles.Checked = false; + } + + if ((fileAccessFlag & (uint)FilterAPI.AccessFlag.ENABLE_FILE_ENCRYPTION_RULE) != 0) + { + checkBox_EnableEncryption.Checked = true; + } + else + { + checkBox_EnableEncryption.Checked = false; + } + + SendSettingsToFilter(); + + } + catch (Exception ex) + { + EventManager.WriteMessage(254, "InitSandbox", EventLevel.Error, "InitSandbox failed with error:" + ex.Message); + } + + } + + private bool GetSandboxSetting() + { + try + { + uint fileAccessFlag = selectedFilterRule.AccessFlag; + uint processRegistryControlFlag = FilterAPI.MAX_REGITRY_ACCESS_FLAG; + + if (textBox_SandboxFolder.Text.Trim().Length == 0) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("The sandbox folder can't be empty.", "Add Filter Rule", MessageBoxButtons.OK, MessageBoxIcon.Error); + return false; + } + + //copy the current filter instance. + selectedFilterRule = selectedFilterRule.Copy(); + + selectedFilterRule.IncludeFileFilterMask = textBox_SandboxFolder.Text.Trim() + "\\*"; + selectedProcessFilterRule.ProcessNameFilterMask = textBox_SandboxFolder.Text.Trim() + "\\*"; + selectedRegistryFilterRule.ProcessNameFilterMask = textBox_SandboxFolder.Text.Trim() + "\\*"; + + if (checkBox_AllowReadRegistry.Checked) + { + processRegistryControlFlag |= (uint)FilterAPI.ALLOW_READ_REGITRY_ACCESS_FLAG; + } + else + { + processRegistryControlFlag &= ~(uint)FilterAPI.ALLOW_READ_REGITRY_ACCESS_FLAG; + } + + if (checkBox_AllowChangeRegistry.Checked) + { + processRegistryControlFlag |= (uint)FilterAPI.ALLOW_CHANGE_REGITRY_ACCESS_FLAG; + } + else + { + processRegistryControlFlag &= ~(uint)FilterAPI.ALLOW_CHANGE_REGITRY_ACCESS_FLAG; + } + + selectedRegistryFilterRule.AccessFlag = processRegistryControlFlag; + + if (checkBox_EnableEncryption.Checked) + { + fileAccessFlag |= (uint)FilterAPI.AccessFlag.ENABLE_FILE_ENCRYPTION_RULE; + + selectedFilterRule.EncryptMethod = (int)FilterAPI.EncryptionMethod.ENCRYPT_FILE_WITH_SAME_KEY_AND_UNIQUE_IV; + //use the default encryption password to generate encryption key, you can change with your own password, + selectedFilterRule.EncryptionPassPhrase = GlobalConfig.MasterPassword; + + } + + selectedFilterRule.AccessFlag = fileAccessFlag; + + return true; + } + catch (Exception ex) + { + EventManager.WriteMessage(326, "GetSandboxSetting", EventLevel.Error, "GetSandboxSetting failed with error:" + ex.Message); + return false; + } + + } + + private void button_AccessFlag_Click(object sender, EventArgs e) + { + if (selectedProcessFilterRule.ProcessNameFilterMask != textBox_SandboxFolder.Text) + { + InitNewFilterRule(); + } + + OptionForm optionForm = new OptionForm(OptionForm.OptionType.Access_Flag, selectedFilterRule.AccessFlag.ToString()); + + if (optionForm.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + if (optionForm.AccessFlags > 0) + { + selectedFilterRule.AccessFlag = optionForm.AccessFlags; + } + } + + InitSandbox(); + } + + + private void button_SelectFolder_Click(object sender, EventArgs e) + { + FolderBrowserDialog folderBrowserDialog = new FolderBrowserDialog(); + + if (folderBrowserDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + textBox_SandboxFolder.Text = folderBrowserDialog.SelectedPath ; + } + } + + private void button_ProcessFileAccessRights_Click(object sender, EventArgs e) + { + if (textBox_SandboxFolder.Text.Trim().Length == 0) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("Sandbox folder can't be empty.", "config file access", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + if (!checkBox_AllowExecute.Checked) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("Allow the binaries being executed checkbox is not check, there are no access rights to the binaries.", "config file access", MessageBoxButtons.OK, MessageBoxIcon.Information); + return; + } + + if (selectedProcessFilterRule.ProcessNameFilterMask != textBox_SandboxFolder.Text) + { + InitNewFilterRule(); + } + + selectedProcessFilterRule.ProcessNameFilterMask = textBox_SandboxFolder.Text; + + ProcessFileAccessRights processFileAccessRights = new ProcessFileAccessRights(selectedProcessFilterRule); + processFileAccessRights.ShowDialog(); + } + + private void button_ConfigProcessRights_Click(object sender, EventArgs e) + { + if (textBox_SandboxFolder.Text.Trim().Length == 0) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("Sandbox folder can't be empty.", "config sendbox", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + if (selectedFilterRule.IncludeFileFilterMask != textBox_SandboxFolder.Text) + { + GetSandboxSetting(); + } + + Form_ProcessRights processRights = new Form_ProcessRights(ref selectedFilterRule); + if (processRights.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + selectedFilterRule = processRights.currentFilterRule; + GlobalConfig.AddFileFilterRule(selectedFilterRule); + InitListView(); + } + + } + + private void listView_Sandbox_SelectedIndexChanged(object sender, EventArgs e) + { + if (listView_Sandbox.SelectedItems.Count == 0) + { + return; + } + + SetSelectedFilterRule(((FileFilterRule)listView_Sandbox.SelectedItems[0].Tag).Copy()); + + InitSandbox(); + } + + + private void button_AddSandbox_Click(object sender, EventArgs e) + { + InitNewFilterRule(); + InitSandbox(); + } + + + private void button_DeleteSandbox_Click(object sender, EventArgs e) + { + if (listView_Sandbox.SelectedItems.Count == 0) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("There are no sandbox selected.", "Delete sendbox", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + foreach (System.Windows.Forms.ListViewItem item in listView_Sandbox.SelectedItems) + { + FileFilterRule filterRule = (FileFilterRule)item.Tag; + + GlobalConfig.RemoveFilterRule(filterRule.IncludeFileFilterMask); + + ProcessFilterRule processFilterRule = GlobalConfig.GetProcessFilterRule("", filterRule.IncludeFileFilterMask); + if (null != processFilterRule) + { + GlobalConfig.RemoveProcessFilterRule(processFilterRule); + } + + RegistryFilterRule registryFilterRule = GlobalConfig.GetRegistryFilterRule("", filterRule.IncludeFileFilterMask); + if (null != registryFilterRule) + { + GlobalConfig.RemoveRegistryFilterRule(registryFilterRule); + } + + GlobalConfig.SaveConfigSetting(); + + SendSettingsToFilter(); + } + + if (GlobalConfig.FilterRules.Count > 0) + { + SetSelectedFilterRule(GlobalConfig.FilterRules.Values.ElementAt(0).Copy()); + } + else + { + selectedFilterRule = null; + } + + InitListView(); + } + + + + private void checkBox_AllowSandboxRead_CheckedChanged(object sender, EventArgs e) + { + if (checkBox_AllowSandboxRead.Checked) + { + selectedFilterRule.AccessFlag |= FilterAPI.ALLOW_FILE_READ_ACCESS; + } + else + { + selectedFilterRule.AccessFlag &= ~FilterAPI.ALLOW_FILE_READ_ACCESS; + } + } + + private void checkBox_AllowSandboxChange_CheckedChanged(object sender, EventArgs e) + { + if (checkBox_AllowSandboxChange.Checked) + { + selectedFilterRule.AccessFlag |= FilterAPI.ALLOW_FILE_CHANGE_ACCESS; + } + else + { + selectedFilterRule.AccessFlag &= ~FilterAPI.ALLOW_FILE_CHANGE_ACCESS; + } + } + + private void checkBox_AllowFolderBrowsing_CheckedChanged(object sender, EventArgs e) + { + if (checkBox_AllowFolderBrowsing.Checked) + { + selectedFilterRule.AccessFlag |= (uint)FilterAPI.AccessFlag.ALLOW_DIRECTORY_LIST_ACCESS; + } + else + { + selectedFilterRule.AccessFlag &= ~(uint)FilterAPI.AccessFlag.ALLOW_DIRECTORY_LIST_ACCESS; + } + } + + + private void checkBox_AllowReadEncryptedFiles_CheckedChanged(object sender, EventArgs e) + { + if (checkBox_AllowReadEncryptedFiles.Checked) + { + selectedFilterRule.AccessFlag |= (uint)FilterAPI.AccessFlag.ALLOW_READ_ENCRYPTED_FILES; + } + else + { + selectedFilterRule.AccessFlag &= ~(uint)FilterAPI.AccessFlag.ALLOW_READ_ENCRYPTED_FILES; + } + } + + private void checkBox_EnableEncryption_CheckedChanged(object sender, EventArgs e) + { + if (checkBox_EnableEncryption.Checked) + { + selectedFilterRule.AccessFlag |= (uint)FilterAPI.AccessFlag.ENABLE_FILE_ENCRYPTION_RULE; + } + else + { + selectedFilterRule.AccessFlag &= ~(uint)FilterAPI.AccessFlag.ENABLE_FILE_ENCRYPTION_RULE; + } + } + + private void checkBox_AllowExecute_CheckedChanged(object sender, EventArgs e) + { + if (checkBox_AllowExecute.Checked) + { + selectedProcessFilterRule.ControlFlag &= ~(uint)FilterAPI.ProcessControlFlag.DENY_NEW_PROCESS_CREATION; + } + else + { + selectedProcessFilterRule.ControlFlag |= (uint)FilterAPI.ProcessControlFlag.DENY_NEW_PROCESS_CREATION; + } + } + + + private void button_SaveSandBox_Click(object sender, EventArgs e) + { + if (GetSandboxSetting()) + { + GlobalConfig.AddFileFilterRule(selectedFilterRule); + GlobalConfig.AddProcessFilterRule(selectedProcessFilterRule); + GlobalConfig.AddRegistryFilterRule(selectedRegistryFilterRule); + GlobalConfig.SaveConfigSetting(); + + SendSettingsToFilter(); + } + + InitListView(); + } + + + private void toolStripButton_EventViewer_Click(object sender, EventArgs e) + { + EventForm.DisplayEventForm(); + } + + + private void button_help_Click(object sender, EventArgs e) + { + string information = "The sandbox can be used in below two purposes:\r\n\r\n"; + information += "1. Restrict the binary access rights inside the sandbox, prevent the registries"; + information += "from being accessed or changed, prevent your important files from being accessed, changed or deleted by the untrusted processes inside the sandbox.\r\n\r\n"; + information += "i.e. you can create a sandbox for your document setting folder,prevent the untrusted downloaded binaries from being launched there,"; + information += "or you can create a sandbox for your test software, only can read/write the files in the sandbox or other specific folder.\r\n\r\n"; + information += "2. Protect sensitive files inside the sandbox, encrypt the sensitive files, add the white list processes who can access the encrypted files, black list processes who can't access the encrypted files.\r\n"; + information += "set the specific access rights to the specific process, allow the process to read, write, rename, delete or change security of the files inside the sandbox.\r\n\r\n"; + information += "i.e. you create a sandbox for your confidential files,"; + information += "only allow authorized user/process to read or change the files there.\r\n\r\n"; + + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show(information, "How to use sandbox?", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + + } +} diff --git a/Demo_Source_Code/CSharpDemo/SecureSandbox/SecureSandbox.csproj b/Demo_Source_Code/CSharpDemo/SecureSandbox/SecureSandbox.csproj new file mode 100644 index 0000000..4edc03f --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/SecureSandbox/SecureSandbox.csproj @@ -0,0 +1,184 @@ + + + + Debug + x86 + 8.0.30703 + 2.0 + {E6D17F25-C5AA-4C56-906C-0B9B35E600BC} + WinExe + Properties + SecureSandbox + SecureSandbox + v4.5 + + + 512 + SAK + SAK + SAK + SAK + + + AnyCPU + true + full + false + ..\..\Release\ + DEBUG;TRACE + prompt + 4 + false + false + + + AnyCPU + pdbonly + true + ..\..\Release\ + TRACE + prompt + 4 + false + + + SecureSandbox.ico + + + true + bin\Debug\ + DEBUG;TRACE + full + AnyCPU + ..\..\Release\SecureSandbox.exe.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + false + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + false + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false + false + false + + + ..\..\Release\ + TRACE + true + pdbonly + AnyCPU + ..\..\Release\SecureSandbox.exe.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + false + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false + false + + + app.manifest + + + + + + + + + + + + + + + + + + Form + + + ProcessFileAccessRights.cs + + + Form + + + AuthorizedProcessForm.cs + + + Form + + + SecureSandbox.cs + + + + + Form + + + TrayForm.cs + + + ProcessFileAccessRights.cs + + + AuthorizedProcessForm.cs + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + True + Resources.resx + True + + + SecureSandbox.cs + + + TrayForm.cs + + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + + + + + + + + {34CB783E-DDA2-4CE3-80BC-37B25AA33E5F} + CommonObjects + + + {21540012-A296-45CE-8D35-3EA5A07B32A6} + FilterControl + + + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/SecureSandbox/SecureSandbox.ico b/Demo_Source_Code/CSharpDemo/SecureSandbox/SecureSandbox.ico new file mode 100644 index 0000000..7d42950 Binary files /dev/null and b/Demo_Source_Code/CSharpDemo/SecureSandbox/SecureSandbox.ico differ diff --git a/Demo_Source_Code/CSharpDemo/SecureSandbox/SecureSandbox.resx b/Demo_Source_Code/CSharpDemo/SecureSandbox/SecureSandbox.resx new file mode 100644 index 0000000..ab1efbd --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/SecureSandbox/SecureSandbox.resx @@ -0,0 +1,1950 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAS + dAAAEnQB3mYfeAAACRlJREFUWEedV3dUlfcZ9v+eND1pGjUaxKCgIIpwWe6JNk7cC2UPRVGjgCaN5ljj + SJ2J0cTjSDTnNCapaWMTzalSbVUEGZfLkIuADNnrDuAy9Onz/r4ruKN9D+/5fnzc+z3P886PHnhJM5mt + uJ5ZhvP/LcbZi7dx7nIRLqfcQVlFvf0TL2cvRKCyuhFHzmRjXsJVjIlJwYQ4PfyiM+ATmQnvyAx11oUl + Q7fiEjbsS0FyZqn9m79uzyVgtTZj65E0BMTdhG9UFtxXZGB4qOaeYfRwegR/j8jkVY/h4VkYGqqH+/JU + BMRehj6vzP6kZ9szCfx8pRCB8alUqcewEAFMhxcBvQimo2ovqvfk2Yt/14lH8X6UXPXwIlmPCAOcFqQg + 4cANPu2+9tCn2FMJHPw6A+9sEMUEpVKvcAEnGNUOXp6GfvNT0XdOKgYvS4fjgpvoO/8mnJczEkIkJqvL + vWIMcA3OQsDqy3xqq/bwx+wJAgI+5V2DAteJYrqOSt1D0gmago++LEV59aMPa21px3cXq6k+C65heniv + Mtg9W7l7ZA7GxV7hJ9u0LzxkjxD4+crtLuUPg7sEpWH6xhx+4kEo76G9vQM2m3g72tva+acO3r+P0B0F + cGMt+MRmw2e1eI5y14hcBG+7pn39IesiIAUXmJCKIcsl3Fq+BXxoaDpCtxvVZ+7f14Db2gh2v5M/HVTf + huZmG79vQ7NVItOJUXE50MXmwJdXv7jcLu+/Igs//EuEdFsXAal2b+ZQFRtzrWPOdbxK0TkwxyUVzfzU + Pf6I0ns4f60O56/X8dyBFhIwm1tgMrWgw9aK75Oq4RpF8LV58FvX7b5rb2FwSDLJWwRSmSJQVdOkWm1o + sIBL+LvBdax2Ka6BS9P5yXsoKrOyEDPhRH97hVR8NjrbbLCQQFNTM6zmZhSXmuDMkPtvuIURG/KV+9vd + bVU+jnybKbDKFIHDZ5gnto+ol7ArcKl61V5aW7mH6zFrUx5cVrD9Vhrgu4YhXpOLwZHZ2PtNuVLe2GiF + 2WRF+V0TBgiBjQTdaMSIeCNGJRgxOtEI//gCjFmfQlSbQGsE5iVeU7kXYCHwANyLve0VzXaiexPUk1cp + LH/m04cEPFbmwDHYgA+Ol6CjtQUNDRY0W6z4JbkGfYJzMCT21hM+dE0++gQZUFRcohGQ2T465gY8WGxK + PYtPppqAe1K5zg7uG2uAji0lFe7E0Ev4nUKy8OrcTDTUW9BE9fW8oqMFIXuKMYih9lhnxPD14gV2N2IY + 7zlHG3HsrF4jkMzFMn6NngSk8ARcU+/J3Au4AHswDU7LMuCwOAP9mfsBBHYON+CVOZlI1tej1WpFXZ0F + FpMFOcYG9A65Ba+Nt6GLt3tCoeY8e9GHrC1E4iGpKRKQreYXTbVq4pEAgUW9NyeZZ7QejovT0HdBGhyX + ZuBtgg8kuAvBfztfj78lVaHT1qzAG+rNsJnNcIs1wjO+ED6biuC7mf4en293Ocu9YfHFiNwtBDrQ44dL + hWqjqeUixUf1PjF6OAeloxfH7VsL7eBB3cp7B2Xhw5PMIcNdW2tGHZ1hwJjEQnjEF8Hv/WL4/+kORmwp + wUjxrXbnWe55bi5ByK4MEmhDD9nnQmC4RECFXY++81Lt4DfRb0k6+jP8TsEkFWrAgDBOtzV5/LKAmxSB + zhYLYj8rhduGIoz44I4CG/VhKcZsK8OYP5dj7HbN5Sz3fLaUI2a/ncDl1BL4c58PV5WfiZ6zbxA8RS0Y + h0VcNir0nAOhEvpsvLnCgH9cqYKV+a6pMaO+zoTikka8tfK2UqeACTTuo3KM33kXE3ZVYMJuu/M8jvdG + ba/Epi9kFnSih7zJeIfdUAT+MCMZvUigzzxuOG65fos19QNEfZgBgznd3lhqQF2NCa1mFl2TCfeo/ug/ + qzAs8Q5GU50oHU+giR9XYvJfqhCwtxoB++zO8yTem7ynBp+c0YaRmgPewUl4bdoN9JyZjN4MfR+mQOWe + 4Rf1knuXiGy4xuTCMTQXR3+8i1MXKnHsp0qcvFCF0INl8NtaRtVUvFsDnrK/GlMP1uKPn9TinU/rlMs5 + 4ADvHahG0tXsbgJxH1/HK1Ouo+esFBJg+KneYZEUH0cu+905LAuDuFLdVuapQTJwZT6cVxfAhe3knsDK + 3lKqQq7A91Rh6oEaBTj9cD1mHGnAzM81l/PUQ42Ys7cQNlNFN4FUQylef+c/eIMElHq2nYOEP0jCz8qX + 8Edzsq3Kw7C4fPYxwVcVYNJWDpz1xRjNnEvYu8AP1WEGAWcdbUTgsSbMOWFSPpvn+V9ZsP2UFCBXOE0R + EBsbeRGvTU/Bm3O1/Dsu4dBh6w0M0TP8fLOJyYF7bB5cV+dj9rYitp20nhlVFY3w21Km1EvYRbkoFbC5 + J82Yf8qCBaetygO/tGLR8VoY86SLNOsikJ1fjlcnX0EvEnBYxALk9nOS/LP1BkUw/Mz/0NW34BiVj/Ts + WjTWNaGyshEtTU349Fw1Ru6k+oM1KuyiXMAFdNFfW7DkTCsWftOK8B87sOO0DKDuN6MuAmLx+5Pxu2ms + gYVsPylAyT8JuJCAa4yWfyGQlVeH+lo7AZMJx36pw8hdVarIJPSBx01KuYAv+96GoLPtCP3pPqJOlMBc + 8+gr+yME5JVqQnQSXp/9EAHJPwtwCAtQ8u8WZ0Tovjt8NbByo4o3YyKrf9LeGkw7VIuZX7DITlD911Ys + /bZVgYddAFadNUGfYbDjdNtjBMRsGBnxb/yeJLoIsP8fEPB8l+98625j5GbO88N3OVZLMZYFOGWfRmAW + CcwlgYUksIhhF+UCfvWaFN6T9hQCYu1YvuUqfjMjjSv30RQIAW9uNG8uFp/3S9gBZZi4q1INGlWAnzeq + Agz8qhnh5zoQxZ3xNOUP7BkENPv7pVzWw1X0XJoN56g8uJOAx7oCrtVCtdVk9MrYHb+zApPYglM4ZKZ+ + 1shWs2Ixq33H6QxYap//b9pzCWhmwZHvZD1zTC/lTIgxqn3uwZXq9V6pWiwy2yfvqVYTLnBvEfs8095q + 2mvX8+wFCDwwm3qNOnY2Cwl8mYjgPg/mSo3Zl4lELhaZ7UnXsmFrkgmnDZkXsZcg8LjJ67n0s3in3Pg/ + DPgfKTU+503JE84AAAAASUVORK5CYII= + + + + 17, 17 + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAImSURBVDhPtdJfSNNRFAfwM3OF+61+Ub7FXowUtXRtQ6tR + FkZUglkNK3Q4M51/tuE2/5BNx8LZmrJKfRKiXiqIgsh0OcVYilObJjpsCtFLUtLTaLKX8tuQC0MQ86E+ + j+eeL+dw76V/p4QMKQ3JISonP2lJyapbxxt2L89+m8Kzj48gvXvoN1VQDxlpDzv+u0RzYuhl4ClcI61w + jlpQ9kIFoUn4nRqpmLVsLsGUEHo83Y2WoVoY35agxq2C1pOHDKtklUw0SLfpAGvdmMgs+tk9aUe95zoq + +wtQ3HsSl18fxsX+NOS/SQFvF0Wi27TQA9rBIutxjVy4w3cTBs8VlLpPo7BPjvy+ZKg8qSjyHkT5pBxn + Xu0HWegTWUnGYjFcExd2jNeievAC1ANKXBpIxdXhdKhHMlA2IYV2Sgb9XDbqg0pss8bNs1gM18yF2yZ0 + qBo+D/VQFq69S0epLxMVfjmqZ7JgCBxD3UIOmr/kQmCNC7BYDGflwnf8VajxnoPGq4BmTIrKaQV0s0dQ + F8yB7etZqN5nQmAXzJOTpCwWI24Tr7TP6FA7locbvuy1yfq5o2j6nAvz4inseyheIQfdoue0nUXW4x18 + 5H7AiIYPBdD7T6xNtkTXPe5MWqV2ctMTSmKtG+NdfKQn2ATbTBFsC9GLHJch3hW/FP2Phaxlczs7hMu9 + S53oWtQhzSr5RfeoM/rmu9jxFrSSRtKz9wd10Ch1kYJV/zeiPxbj9jyzHFQiAAAAAElFTkSuQmCC + + + + + iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAARRSURBVEhLxVRbTFRXFD0woIA2owgij2JVFFF81Ee1VQoy + MMyAiKLiCwqIbyxG248+vvXHxPpV/TOxEeOTqKmmESVqRIPia2R8R9SqLQItA3SiqMu159yRcRIbTJp0 + Jzvnnjtz1lpn7b2v+t/i9XAV2z5aNfw1LtjdnUHulrHMMcHupmQTM8j9e4JydMSraONYz8IAv/WyZDzw + 9ZfAms+BVVOBZZOApRMAeV+cDBQl48XMeDwYopw9JhFwVxLBiz8F1qZo4BWfAWUTNfBXY4HC0cCiJGDB + CGBhIp7b43A3tgckAt5K8K4SqhTl5SQoT+UNppOEtygladEYYIkQjNQEBcOA+cPgtsagIU7d6Ih4D4kH + PMEPfF06MwOosOj9ssmaYPEoKidBwXBgHgnyhwJzB+OfjChciVHOJn8SAW8h+AuxpYJAq7/oJvjWBnxj + J2kaCWiVh0DsSaTyBAITfM4nQF48MDsOnTMicDlSORt9Sf4coRq6iqWgtEI8X8lcM02DbrAC65liVRlv + UMjieu2hNcgfQuDBwKyPgZmxQG40OlPDcS5COQx4pZrYdqigLSunsJBUKJ0iRV3KG5XyuVhUCygtyYsj + AdXnEkyebQOA9I+AtD6ANQKwDyJRFC6aTW4DXqmnySQoZxGlQ6q24W3s+QnoaDM2jNqjwOkqY8MoJHFb + s7Fh/FgAZIQD2ZE470vwKIkEq2nLIl77yX3gj0Zg71agercmlXDUasUSNfv1uu174NEd4NpZ4CnPHfiZ + N+Ft7ANxzhzQTfAwMciN5RwisaFysz787LHuGhsVSVw4Dkw36eeaA3rdToLGW4CrVe8rt2gCWyRO+xJc + FoIyer2E7Scds3Mj8KqLJE94IEQfrjsBTDMITu7Tq9zgwW3g72fApuVAVqS2KCscp8yBPgQJtKiUXTSf + HXHzorap9lcNkhKs1/oaPhsE9Sf1unW9tubxPWBKAIvMgguBtT+q3iEYanKjhO1XwBp8NxtopvJOl7Yg + q78GOLKDh/tR9Q/8rR24c42/EbCO1knxU9lFmdxb+P/Mfv4EtKiI4y+9PY+DwzaTTpDBwVwOEYuGHL7L + Y6/b+X4GfbYwxZK0vgY4lQu4xcwb+BHUD1KOzmxOIj9cnm+LjL9MqAxRPgnmcJBkUmWYpP9zYiiA/W4n + qZCIcrHGwhuSoHVSGPaGqCsGvFIy1nUc7w4bFXum0xh/mVABFuW5/E0mNSdag9v8wNM1eMtEgvdWjkNK + RRnwOoTkzADlbM+kOrHlrWIvsKgmuKi20TJ/8AyCU/meXspR7Q/ujcYwFV1tVjdcFioU/98B9lEtnwRv + Qb3KCb67l7r+XnBvOEly3KycbWkE4YcLdqYHmKqtvn4bBWU2TwjDrsB/Ue4fQnIslCQpBMoleA6Bs0kg + HSSTLa3LTpFspucfBO6NYyQ5GKKu/hZqch31ZIDrSGig6zDzELPSyF8C1aXKDwX/70KpN929HhkRWgNw + AAAAAElFTkSuQmCC + + + + + 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 + HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/ + HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/ + HGcm/xxnJv8cZyb/GFoh/xhaIf8YWiH/GFoh/xZSHv8WUh7/FlIe/xZSHv8XUx//F1Mf/xdTH/8XUx// + F1Qf/xdUH/8XVB//F1Qf/xdUH/8XVB//F1Qf/xdUH/8XViD/F1Yg/xdWIP8XViD/F1Yg/xdWIP8XViD/ + F1Yg/xhXIP8YVyD/GFcg/xhXIP8YWCD/GFgg/xhYIP8YWCD/GFkh/xhZIf8YWSH/GFkh/xhaIf8YWiH/ + GFoh/xhaIf8ZWiH/GVoh/xlaIf8ZWiH/GFwi6RhcIukYXCLpGFwi6RpcIq8aXCKvGlwirxpcIq8ZWiEf + GVohHxlaIR8ZWiEfAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbZCQcG2QkHBtkJBwbZCQc + HWcmqR1nJqkdZyapHWcmqRxnJuccZybnHGcm5xxnJuccZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/ + HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/ + HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/ + HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8YWiH/GFoh/xhaIf8YWiH/ + FlIe/xZSHv8WUh7/FlIe/xdTH/8XUx//F1Mf/xdTH/8XVB//F1Qf/xdUH/8XVB//F1Qf/xdUH/8XVB// + F1Qf/xdWIP8XViD/F1Yg/xdWIP8XViD/F1Yg/xdWIP8XViD/GFcg/xhXIP8YVyD/GFcg/xhYIP8YWCD/ + GFgg/xhYIP8YWSH/GFkh/xhZIf8YWSH/GFoh/xhaIf8YWiH/GFoh/xlaIf8ZWiH/GVoh/xlaIf8YXCLp + GFwi6RhcIukYXCLpGlwirxpcIq8aXCKvGlwirxlaIR8ZWiEfGVohHxlaIR8AAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAABtkJBwbZCQcG2QkHBtkJBwdZyapHWcmqR1nJqkdZyapHGcm5xxnJuccZybn + HGcm5xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/ + HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/ + HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/ + HGcm/xxnJv8cZyb/HGcm/xhaIf8YWiH/GFoh/xhaIf8WUh7/FlIe/xZSHv8WUh7/F1Mf/xdTH/8XUx// + F1Mf/xdUH/8XVB//F1Qf/xdUH/8XVB//F1Qf/xdUH/8XVB//F1Yg/xdWIP8XViD/F1Yg/xdWIP8XViD/ + F1Yg/xdWIP8YVyD/GFcg/xhXIP8YVyD/GFgg/xhYIP8YWCD/GFgg/xhZIf8YWSH/GFkh/xhZIf8YWiH/ + GFoh/xhaIf8YWiH/GVoh/xlaIf8ZWiH/GVoh/xhcIukYXCLpGFwi6RhcIukaXCKvGlwirxpcIq8aXCKv + GVohHxlaIR8ZWiEfGVohHwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAG2QkHBtkJBwbZCQc + G2QkHB1nJqkdZyapHWcmqR1nJqkcZybnHGcm5xxnJuccZybnHGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/ + HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/ + HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/ + HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/GFoh/xhaIf8YWiH/ + GFoh/xZSHv8WUh7/FlIe/xZSHv8XUx//F1Mf/xdTH/8XUx//F1Qf/xdUH/8XVB//F1Qf/xdUH/8XVB// + F1Qf/xdUH/8XViD/F1Yg/xdWIP8XViD/F1Yg/xdWIP8XViD/F1Yg/xhXIP8YVyD/GFcg/xhXIP8YWCD/ + GFgg/xhYIP8YWCD/GFkh/xhZIf8YWSH/GFkh/xhaIf8YWiH/GFoh/xhaIf8ZWiH/GVoh/xlaIf8ZWiH/ + GFwi6RhcIukYXCLpGFwi6RpcIq8aXCKvGlwirxpcIq8ZWiEfGVohHxlaIR8ZWiEfAAAAAAAAAAAAAAAA + AAAAABtkJBwbZCQcG2QkHBtkJBwdaCftHWgn7R1oJ+0daCftHWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/xlaIv8ZWiL/GVoi/xlaIv8XUR7/F1Ee/xdRHv8XUR7/F1If/xdSH/8XUh//F1If/xdTH/8XUx// + F1Mf/xdTH/8XVB//F1Qf/xdUH/8XVB//GFQg/xhUIP8YVCD/GFQg/xhVIP8YVSD/GFUg/xhVIP8YViD/ + GFYg/xhWIP8YViD/GFch/xhXIf8YVyH/GFch/xlYIf8ZWCH/GVgh/xlYIf8ZWSH/GVkh/xlZIf8ZWSH/ + GVoi/xlaIv8ZWiL/GVoi/xlbIv8ZWyL/GVsi/xlbIv8ZWyL/GVsi/xlbIv8ZWyL/Glwj/xpcI/8aXCP/ + Glwj/xpdIu8aXSLvGl0i7xpdIu8ZWiEfGVohHxlaIR8ZWiEfG2QkHBtkJBwbZCQcG2QkHB1oJ+0daCft + HWgn7R1oJ+0daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/GVoi/xlaIv8ZWiL/GVoi/xdRHv8XUR7/ + F1Ee/xdRHv8XUh//F1If/xdSH/8XUh//F1Mf/xdTH/8XUx//F1Mf/xdUH/8XVB//F1Qf/xdUH/8YVCD/ + GFQg/xhUIP8YVCD/GFUg/xhVIP8YVSD/GFUg/xhWIP8YViD/GFYg/xhWIP8YVyH/GFch/xhXIf8YVyH/ + GVgh/xlYIf8ZWCH/GVgh/xlZIf8ZWSH/GVkh/xlZIf8ZWiL/GVoi/xlaIv8ZWiL/GVsi/xlbIv8ZWyL/ + GVsi/xlbIv8ZWyL/GVsi/xlbIv8aXCP/Glwj/xpcI/8aXCP/Gl0i7xpdIu8aXSLvGl0i7xlaIR8ZWiEf + GVohHxlaIR8bZCQcG2QkHBtkJBwbZCQcHWgn7R1oJ+0daCftHWgn7R1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8ZWiL/GVoi/xlaIv8ZWiL/F1Ee/xdRHv8XUR7/F1Ee/xdSH/8XUh//F1If/xdSH/8XUx// + F1Mf/xdTH/8XUx//F1Qf/xdUH/8XVB//F1Qf/xhUIP8YVCD/GFQg/xhUIP8YVSD/GFUg/xhVIP8YVSD/ + GFYg/xhWIP8YViD/GFYg/xhXIf8YVyH/GFch/xhXIf8ZWCH/GVgh/xlYIf8ZWCH/GVkh/xlZIf8ZWSH/ + GVkh/xlaIv8ZWiL/GVoi/xlaIv8ZWyL/GVsi/xlbIv8ZWyL/GVsi/xlbIv8ZWyL/GVsi/xpcI/8aXCP/ + Glwj/xpcI/8aXSLvGl0i7xpdIu8aXSLvGVohHxlaIR8ZWiEfGVohHxtkJBwbZCQcG2QkHBtkJBwdaCft + HWgn7R1oJ+0daCftHWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/xlaIv8ZWiL/GVoi/xlaIv8XUR7/ + F1Ee/xdRHv8XUR7/F1If/xdSH/8XUh//F1If/xdTH/8XUx//F1Mf/xdTH/8XVB//F1Qf/xdUH/8XVB// + GFQg/xhUIP8YVCD/GFQg/xhVIP8YVSD/GFUg/xhVIP8YViD/GFYg/xhWIP8YViD/GFch/xhXIf8YVyH/ + GFch/xlYIf8ZWCH/GVgh/xlYIf8ZWSH/GVkh/xlZIf8ZWSH/GVoi/xlaIv8ZWiL/GVoi/xlbIv8ZWyL/ + GVsi/xlbIv8ZWyL/GVsi/xlbIv8ZWyL/Glwj/xpcI/8aXCP/Glwj/xpdIu8aXSLvGl0i7xpdIu8ZWiEf + GVohHxlaIR8ZWiEfHmopqR5qKakeaimpHmopqR5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8aWyL/ + Glsi/xpbIv8aWyL/F1Ef/xdRH/8XUR//F1Ef/xdSH/8XUh//F1If/xdSH/8XUx//F1Mf/xdTH/8XUx// + GFQg/xhUIP8YVCD/GFQg/xhUIP8YVCD/GFQg/xhUIP8YVSD/GFUg/xhVIP8YVSD/GFYg/xhWIP8YViD/ + GFYg/xlXIf8ZVyH/GVch/xlXIf8ZWCH/GVgh/xlYIf8ZWCH/GVki/xlZIv8ZWSL/GVki/xlaIv8ZWiL/ + GVoi/xlaIv8aWyL/Glsi/xpbIv8aWyL/Glsj/xpbI/8aWyP/Glsj/xpcI/8aXCP/Glwj/xpcI/8aXSP/ + Gl0j/xpdI/8aXSP/G14j/xteI/8bXiP/G14j/xxfJK8cXySvHF8krxxfJK8eaimpHmopqR5qKakeaimp + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/xpbIv8aWyL/Glsi/xpbIv8XUR//F1Ef/xdRH/8XUR// + F1If/xdSH/8XUh//F1If/xdTH/8XUx//F1Mf/xdTH/8YVCD/GFQg/xhUIP8YVCD/GFQg/xhUIP8YVCD/ + GFQg/xhVIP8YVSD/GFUg/xhVIP8YViD/GFYg/xhWIP8YViD/GVch/xlXIf8ZVyH/GVch/xlYIf8ZWCH/ + GVgh/xlYIf8ZWSL/GVki/xlZIv8ZWSL/GVoi/xlaIv8ZWiL/GVoi/xpbIv8aWyL/Glsi/xpbIv8aWyP/ + Glsj/xpbI/8aWyP/Glwj/xpcI/8aXCP/Glwj/xpdI/8aXSP/Gl0j/xpdI/8bXiP/G14j/xteI/8bXiP/ + HF8krxxfJK8cXySvHF8krx5qKakeaimpHmopqR5qKakeaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Glsi/xpbIv8aWyL/Glsi/xdRH/8XUR//F1Ef/xdRH/8XUh//F1If/xdSH/8XUh//F1Mf/xdTH/8XUx// + F1Mf/xhUIP8YVCD/GFQg/xhUIP8YVCD/GFQg/xhUIP8YVCD/GFUg/xhVIP8YVSD/GFUg/xhWIP8YViD/ + GFYg/xhWIP8ZVyH/GVch/xlXIf8ZVyH/GVgh/xlYIf8ZWCH/GVgh/xlZIv8ZWSL/GVki/xlZIv8ZWiL/ + GVoi/xlaIv8ZWiL/Glsi/xpbIv8aWyL/Glsi/xpbI/8aWyP/Glsj/xpbI/8aXCP/Glwj/xpcI/8aXCP/ + Gl0j/xpdI/8aXSP/Gl0j/xteI/8bXiP/G14j/xteI/8cXySvHF8krxxfJK8cXySvHmopqR5qKakeaimp + HmopqR5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8aWyL/Glsi/xpbIv8aWyL/F1Ef/xdRH/8XUR// + F1Ef/xdSH/8XUh//F1If/xdSH/8XUx//F1Mf/xdTH/8XUx//GFQg/xhUIP8YVCD/GFQg/xhUIP8YVCD/ + GFQg/xhUIP8YVSD/GFUg/xhVIP8YVSD/GFYg/xhWIP8YViD/GFYg/xlXIf8ZVyH/GVch/xlXIf8ZWCH/ + GVgh/xlYIf8ZWCH/GVki/xlZIv8ZWSL/GVki/xlaIv8ZWiL/GVoi/xlaIv8aWyL/Glsi/xpbIv8aWyL/ + Glsj/xpbI/8aWyP/Glsj/xpcI/8aXCP/Glwj/xpcI/8aXSP/Gl0j/xpdI/8aXSP/G14j/xteI/8bXiP/ + G14j/xxfJK8cXySvHF8krxxfJK8fayroH2sq6B9rKugfayroH2sq/x9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/Glsk/xpbJP8aWyT/ + Glsk/xdQH/8XUB//F1Af/xdQH/8eaWD/Hmlg/x5pYP8eaWD/Hmpg/x5qYP8eamD/Hmpg/xhTIP8YUyD/ + GFMg/xhTIP8YVCH/GFQh/xhUIf8YVCH/GFQh/xhUIf8YVCH/GFQh/xlVIf8ZVSH/GVUh/xlVIf8ZViL/ + GVYi/xlWIv8ZViL/GVci/xlXIv8ZVyL/GVci/xlYIv8ZWCL/GVgi/xlYIv8aWSP/Glkj/xpZI/8aWSP/ + Gloj/xpaI/8aWiP/Gloj/xpbJP8aWyT/Glsk/xpbJP8bWyT/G1sk/xtbJP8bWyT/G1wk/xtcJP8bXCT/ + G1wk/xtdJf8bXSX/G10l/xtdJf8bXiX/G14l/xteJf8bXiX/G18l6RtfJekbXyXpG18l6R9rKugfayro + H2sq6B9rKugfayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8aWyT/Glsk/xpbJP8aWyT/F1Af/xdQH/8XUB//F1Af/x5pYP8eaWD/ + Hmlg/x5pYP8eamD/Hmpg/x5qYP8eamD/GFMg/xhTIP8YUyD/GFMg/xhUIf8YVCH/GFQh/xhUIf8YVCH/ + GFQh/xhUIf8YVCH/GVUh/xlVIf8ZVSH/GVUh/xlWIv8ZViL/GVYi/xlWIv8ZVyL/GVci/xlXIv8ZVyL/ + GVgi/xlYIv8ZWCL/GVgi/xpZI/8aWSP/Glkj/xpZI/8aWiP/Gloj/xpaI/8aWiP/Glsk/xpbJP8aWyT/ + Glsk/xtbJP8bWyT/G1sk/xtbJP8bXCT/G1wk/xtcJP8bXCT/G10l/xtdJf8bXSX/G10l/xteJf8bXiX/ + G14l/xteJf8bXyXpG18l6RtfJekbXyXpH2sq6B9rKugfayroH2sq6B9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/xpbJP8aWyT/ + Glsk/xpbJP8XUB//F1Af/xdQH/8XUB//Hmlg/x5pYP8eaWD/Hmlg/x5qYP8eamD/Hmpg/x5qYP8YUyD/ + GFMg/xhTIP8YUyD/GFQh/xhUIf8YVCH/GFQh/xhUIf8YVCH/GFQh/xhUIf8ZVSH/GVUh/xlVIf8ZVSH/ + GVYi/xlWIv8ZViL/GVYi/xlXIv8ZVyL/GVci/xlXIv8ZWCL/GVgi/xlYIv8ZWCL/Glkj/xpZI/8aWSP/ + Glkj/xpaI/8aWiP/Gloj/xpaI/8aWyT/Glsk/xpbJP8aWyT/G1sk/xtbJP8bWyT/G1sk/xtcJP8bXCT/ + G1wk/xtcJP8bXSX/G10l/xtdJf8bXSX/G14l/xteJf8bXiX/G14l/xtfJekbXyXpG18l6RtfJekfayro + H2sq6B9rKugfayroH2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/Glsk/xpbJP8aWyT/Glsk/xdQH/8XUB//F1Af/xdQH/8eaWD/ + Hmlg/x5pYP8eaWD/Hmpg/x5qYP8eamD/Hmpg/xhTIP8YUyD/GFMg/xhTIP8YVCH/GFQh/xhUIf8YVCH/ + GFQh/xhUIf8YVCH/GFQh/xlVIf8ZVSH/GVUh/xlVIf8ZViL/GVYi/xlWIv8ZViL/GVci/xlXIv8ZVyL/ + GVci/xlYIv8ZWCL/GVgi/xlYIv8aWSP/Glkj/xpZI/8aWSP/Gloj/xpaI/8aWiP/Gloj/xpbJP8aWyT/ + Glsk/xpbJP8bWyT/G1sk/xtbJP8bWyT/G1wk/xtcJP8bXCT/G1wk/xtdJf8bXSX/G10l/xtdJf8bXiX/ + G14l/xteJf8bXiX/G18l6RtfJekbXyXpG18l6SBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/xtbJP8bWyT/G1sk/xtbJP8eaFr/ + Hmha/x5oWv8eaFr/JYKy/yWCsv8lgrL/JYKy/ymT3/8pk9//KZPf/ymT3/8pk9//KZPf/ymT3/8pk9// + JYKu/yWCrv8lgq7/JYKu/x5nVP8eZ1T/HmdU/x5nVP8ZVSL/GVUi/xlVIv8ZVSL/GVYi/xlWIv8ZViL/ + GVYi/xlXIv8ZVyL/GVci/xlXIv8aWCP/Glgj/xpYI/8aWCP/Glgj/xpYI/8aWCP/Glgj/xpZI/8aWSP/ + Glkj/xpZI/8bWyT/G1sk/xtbJP8bWyT/G1sk/xtbJP8bWyT/G1sk/xtcJP8bXCT/G1wk/xtcJP8bXSX/ + G10l/xtdJf8bXSX/HF4l/xxeJf8cXiX/HF4l/xxfJf8cXyX/HF8l/xxfJf8cYCb/HGAm/xxgJv8cYCb/ + IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/G1sk/xtbJP8bWyT/G1sk/x5oWv8eaFr/Hmha/x5oWv8lgrL/JYKy/yWCsv8lgrL/ + KZPf/ymT3/8pk9//KZPf/ymT3/8pk9//KZPf/ymT3/8lgq7/JYKu/yWCrv8lgq7/HmdU/x5nVP8eZ1T/ + HmdU/xlVIv8ZVSL/GVUi/xlVIv8ZViL/GVYi/xlWIv8ZViL/GVci/xlXIv8ZVyL/GVci/xpYI/8aWCP/ + Glgj/xpYI/8aWCP/Glgj/xpYI/8aWCP/Glkj/xpZI/8aWSP/Glkj/xtbJP8bWyT/G1sk/xtbJP8bWyT/ + G1sk/xtbJP8bWyT/G1wk/xtcJP8bXCT/G1wk/xtdJf8bXSX/G10l/xtdJf8cXiX/HF4l/xxeJf8cXiX/ + HF8l/xxfJf8cXyX/HF8l/xxgJv8cYCb/HGAm/xxgJv8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8bWyT/G1sk/xtbJP8bWyT/ + Hmha/x5oWv8eaFr/Hmha/yWCsv8lgrL/JYKy/yWCsv8pk9//KZPf/ymT3/8pk9//KZPf/ymT3/8pk9// + KZPf/yWCrv8lgq7/JYKu/yWCrv8eZ1T/HmdU/x5nVP8eZ1T/GVUi/xlVIv8ZVSL/GVUi/xlWIv8ZViL/ + GVYi/xlWIv8ZVyL/GVci/xlXIv8ZVyL/Glgj/xpYI/8aWCP/Glgj/xpYI/8aWCP/Glgj/xpYI/8aWSP/ + Glkj/xpZI/8aWSP/G1sk/xtbJP8bWyT/G1sk/xtbJP8bWyT/G1sk/xtbJP8bXCT/G1wk/xtcJP8bXCT/ + G10l/xtdJf8bXSX/G10l/xxeJf8cXiX/HF4l/xxeJf8cXyX/HF8l/xxfJf8cXyX/HGAm/xxgJv8cYCb/ + HGAm/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/IG0r/xtbJP8bWyT/G1sk/xtbJP8eaFr/Hmha/x5oWv8eaFr/JYKy/yWCsv8lgrL/ + JYKy/ymT3/8pk9//KZPf/ymT3/8pk9//KZPf/ymT3/8pk9//JYKu/yWCrv8lgq7/JYKu/x5nVP8eZ1T/ + HmdU/x5nVP8ZVSL/GVUi/xlVIv8ZVSL/GVYi/xlWIv8ZViL/GVYi/xlXIv8ZVyL/GVci/xlXIv8aWCP/ + Glgj/xpYI/8aWCP/Glgj/xpYI/8aWCP/Glgj/xpZI/8aWSP/Glkj/xpZI/8bWyT/G1sk/xtbJP8bWyT/ + G1sk/xtbJP8bWyT/G1sk/xtcJP8bXCT/G1wk/xtcJP8bXSX/G10l/xtdJf8bXSX/HF4l/xxeJf8cXiX/ + HF4l/xxfJf8cXyX/HF8l/xxfJf8cYCb/HGAm/xxgJv8cYCb/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8dZUD/HWVA/x1lQP8dZUD/JIGn/ySBp/8kgaf/ + JIGn/ymU3/8plN//KZTf/ymU3/8upPf/LqT3/y6k9/8upPf/L6j9/y+o/f8vqP3/L6j9/y+o/f8vqP3/ + L6j9/y+o/f8upPf/LqT3/y6k9/8upPf/KZTf/ymU3/8plN//KZTf/ySApf8kgKX/JICl/ySApf8cYkL/ + HGJC/xxiQv8cYkL/GVcj/xlXI/8ZVyP/GVcj/xlYJP8ZWCT/GVgk/xlYJP8aWCT/Glgk/xpYJP8aWCT/ + Glkl/xpZJf8aWSX/Glkl/xpaJf8aWiX/Glol/xpaJf8bWyX/G1sl/xtbJf8bWyX/G1wm/xtcJv8bXCb/ + G1wm/xtdJv8bXSb/G10m/xtdJv8bXib/G14m/xteJv8bXib/HF8n/xxfJ/8cXyf/HF8n/xxgJ/8cYCf/ + HGAn/xxgJ/8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/x1lQP8dZUD/HWVA/x1lQP8kgaf/JIGn/ySBp/8kgaf/KZTf/ymU3/8plN//KZTf/y6k9/8upPf/ + LqT3/y6k9/8vqP3/L6j9/y+o/f8vqP3/L6j9/y+o/f8vqP3/L6j9/y6k9/8upPf/LqT3/y6k9/8plN// + KZTf/ymU3/8plN//JICl/ySApf8kgKX/JICl/xxiQv8cYkL/HGJC/xxiQv8ZVyP/GVcj/xlXI/8ZVyP/ + GVgk/xlYJP8ZWCT/GVgk/xpYJP8aWCT/Glgk/xpYJP8aWSX/Glkl/xpZJf8aWSX/Glol/xpaJf8aWiX/ + Glol/xtbJf8bWyX/G1sl/xtbJf8bXCb/G1wm/xtcJv8bXCb/G10m/xtdJv8bXSb/G10m/xteJv8bXib/ + G14m/xteJv8cXyf/HF8n/xxfJ/8cXyf/HGAn/xxgJ/8cYCf/HGAn/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/HWVA/x1lQP8dZUD/HWVA/ySBp/8kgaf/ + JIGn/ySBp/8plN//KZTf/ymU3/8plN//LqT3/y6k9/8upPf/LqT3/y+o/f8vqP3/L6j9/y+o/f8vqP3/ + L6j9/y+o/f8vqP3/LqT3/y6k9/8upPf/LqT3/ymU3/8plN//KZTf/ymU3/8kgKX/JICl/ySApf8kgKX/ + HGJC/xxiQv8cYkL/HGJC/xlXI/8ZVyP/GVcj/xlXI/8ZWCT/GVgk/xlYJP8ZWCT/Glgk/xpYJP8aWCT/ + Glgk/xpZJf8aWSX/Glkl/xpZJf8aWiX/Glol/xpaJf8aWiX/G1sl/xtbJf8bWyX/G1sl/xtcJv8bXCb/ + G1wm/xtcJv8bXSb/G10m/xtdJv8bXSb/G14m/xteJv8bXib/G14m/xxfJ/8cXyf/HF8n/xxfJ/8cYCf/ + HGAn/xxgJ/8cYCf/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/yBuLf8dZUD/HWVA/x1lQP8dZUD/JIGn/ySBp/8kgaf/JIGn/ymU3/8plN//KZTf/ymU3/8upPf/ + LqT3/y6k9/8upPf/L6j9/y+o/f8vqP3/L6j9/y+o/f8vqP3/L6j9/y+o/f8upPf/LqT3/y6k9/8upPf/ + KZTf/ymU3/8plN//KZTf/ySApf8kgKX/JICl/ySApf8cYkL/HGJC/xxiQv8cYkL/GVcj/xlXI/8ZVyP/ + GVcj/xlYJP8ZWCT/GVgk/xlYJP8aWCT/Glgk/xpYJP8aWCT/Glkl/xpZJf8aWSX/Glkl/xpaJf8aWiX/ + Glol/xpaJf8bWyX/G1sl/xtbJf8bWyX/G1wm/xtcJv8bXCb/G1wm/xtdJv8bXSb/G10m/xtdJv8bXib/ + G14m/xteJv8bXib/HF8n/xxfJ/8cXyf/HF8n/xxgJ/8cYCf/HGAn/xxgJ/8hcC7/IXAu/yFwLv8hcC7/ + IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/ + IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/ + IXAu/yFwLv8hcS//IXEv/yFxL/8hcS//JHx+/yR8fv8kfH7/JHx+/ymR1P8pkdT/KZHU/ymR1P8vpfb/ + L6X2/y+l9v8vpfb/MKn8/zCp/P8wqfz/MKn8/yybzf8sm83/LJvN/yybzf8gblr/IG5a/yBuWv8gblr/ + IGxY/yBsWP8gbFj/IGxY/yyazP8smsz/LJrM/yyazP8wqfz/MKn8/zCp/P8wqfz/L6X2/y+l9v8vpfb/ + L6X2/yqR1P8qkdT/KpHU/yqR1P8gdHH/IHRx/yB0cf8gdHH/Glgk/xpYJP8aWCT/Glgk/xpZJf8aWSX/ + Glkl/xpZJf8bWiX/G1ol/xtaJf8bWiX/G1sl/xtbJf8bWyX/G1sl/xtcJv8bXCb/G1wm/xtcJv8bXSb/ + G10m/xtdJv8bXSb/HF4n/xxeJ/8cXif/HF4n/xxfJ/8cXyf/HF8n/xxfJ/8cYCf/HGAn/xxgJ/8cYCf/ + HGEo/xxhKP8cYSj/HGEo/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/ + IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/ + IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFxL/8hcS//IXEv/yFxL/8kfH7/ + JHx+/yR8fv8kfH7/KZHU/ymR1P8pkdT/KZHU/y+l9v8vpfb/L6X2/y+l9v8wqfz/MKn8/zCp/P8wqfz/ + LJvN/yybzf8sm83/LJvN/yBuWv8gblr/IG5a/yBuWv8gbFj/IGxY/yBsWP8gbFj/LJrM/yyazP8smsz/ + LJrM/zCp/P8wqfz/MKn8/zCp/P8vpfb/L6X2/y+l9v8vpfb/KpHU/yqR1P8qkdT/KpHU/yB0cf8gdHH/ + IHRx/yB0cf8aWCT/Glgk/xpYJP8aWCT/Glkl/xpZJf8aWSX/Glkl/xtaJf8bWiX/G1ol/xtaJf8bWyX/ + G1sl/xtbJf8bWyX/G1wm/xtcJv8bXCb/G1wm/xtdJv8bXSb/G10m/xtdJv8cXif/HF4n/xxeJ/8cXif/ + HF8n/xxfJ/8cXyf/HF8n/xxgJ/8cYCf/HGAn/xxgJ/8cYSj/HGEo/xxhKP8cYSj/IXAu/yFwLv8hcC7/ + IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/ + IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/ + IXAu/yFwLv8hcC7/IXEv/yFxL/8hcS//IXEv/yR8fv8kfH7/JHx+/yR8fv8pkdT/KZHU/ymR1P8pkdT/ + L6X2/y+l9v8vpfb/L6X2/zCp/P8wqfz/MKn8/zCp/P8sm83/LJvN/yybzf8sm83/IG5a/yBuWv8gblr/ + IG5a/yBsWP8gbFj/IGxY/yBsWP8smsz/LJrM/yyazP8smsz/MKn8/zCp/P8wqfz/MKn8/y+l9v8vpfb/ + L6X2/y+l9v8qkdT/KpHU/yqR1P8qkdT/IHRx/yB0cf8gdHH/IHRx/xpYJP8aWCT/Glgk/xpYJP8aWSX/ + Glkl/xpZJf8aWSX/G1ol/xtaJf8bWiX/G1ol/xtbJf8bWyX/G1sl/xtbJf8bXCb/G1wm/xtcJv8bXCb/ + G10m/xtdJv8bXSb/G10m/xxeJ/8cXif/HF4n/xxeJ/8cXyf/HF8n/xxfJ/8cXyf/HGAn/xxgJ/8cYCf/ + HGAn/xxhKP8cYSj/HGEo/xxhKP8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/ + IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/ + IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcS//IXEv/yFxL/8hcS// + JHx+/yR8fv8kfH7/JHx+/ymR1P8pkdT/KZHU/ymR1P8vpfb/L6X2/y+l9v8vpfb/MKn8/zCp/P8wqfz/ + MKn8/yybzf8sm83/LJvN/yybzf8gblr/IG5a/yBuWv8gblr/IGxY/yBsWP8gbFj/IGxY/yyazP8smsz/ + LJrM/yyazP8wqfz/MKn8/zCp/P8wqfz/L6X2/y+l9v8vpfb/L6X2/yqR1P8qkdT/KpHU/yqR1P8gdHH/ + IHRx/yB0cf8gdHH/Glgk/xpYJP8aWCT/Glgk/xpZJf8aWSX/Glkl/xpZJf8bWiX/G1ol/xtaJf8bWiX/ + G1sl/xtbJf8bWyX/G1sl/xtcJv8bXCb/G1wm/xtcJv8bXSb/G10m/xtdJv8bXSb/HF4n/xxeJ/8cXif/ + HF4n/xxfJ/8cXyf/HF8n/xxfJ/8cYCf/HGAn/xxgJ/8cYCf/HGEo/xxhKP8cYSj/HGEo/yJxL/8icS// + InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS// + InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS// + I3Q7/yN0O/8jdDv/I3Q7/yeHqv8nh6r/J4eq/yeHqv8tn+z/LZ/s/y2f7P8tn+z/MKr8/zCq/P8wqvz/ + MKr8/y6f2P8un9j/Lp/Y/y6f2P8hcmb/IXJm/yFyZv8hcmb/GFEi/xhRIv8YUSL/GFEi/xlSIv8ZUiL/ + GVIi/xlSIv8ZUyL/GVMi/xlTIv8ZUyL/GVQj/xlUI/8ZVCP/GVQj/yJ0Z/8idGf/InRn/yJ0Z/8un9j/ + Lp/Y/y6f2P8un9j/MKr8/zCq/P8wqvz/MKr8/y2f7P8tn+z/LZ/s/y2f7P8lhKP/JYSj/yWEo/8lhKP/ + HF4z/xxeM/8cXjP/HF4z/xtaJf8bWiX/G1ol/xtaJf8bWyb/G1sm/xtbJv8bWyb/HFwm/xxcJv8cXCb/ + HFwm/xxdJ/8cXSf/HF0n/xxdJ/8cXif/HF4n/xxeJ/8cXif/HV8n/x1fJ/8dXyf/HV8n/x1gKP8dYCj/ + HWAo/x1gKP8dYSj/HWEo/x1hKP8dYSj/InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS// + InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS// + InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8jdDv/I3Q7/yN0O/8jdDv/J4eq/yeHqv8nh6r/ + J4eq/y2f7P8tn+z/LZ/s/y2f7P8wqvz/MKr8/zCq/P8wqvz/Lp/Y/y6f2P8un9j/Lp/Y/yFyZv8hcmb/ + IXJm/yFyZv8YUSL/GFEi/xhRIv8YUSL/GVIi/xlSIv8ZUiL/GVIi/xlTIv8ZUyL/GVMi/xlTIv8ZVCP/ + GVQj/xlUI/8ZVCP/InRn/yJ0Z/8idGf/InRn/y6f2P8un9j/Lp/Y/y6f2P8wqvz/MKr8/zCq/P8wqvz/ + LZ/s/y2f7P8tn+z/LZ/s/yWEo/8lhKP/JYSj/yWEo/8cXjP/HF4z/xxeM/8cXjP/G1ol/xtaJf8bWiX/ + G1ol/xtbJv8bWyb/G1sm/xtbJv8cXCb/HFwm/xxcJv8cXCb/HF0n/xxdJ/8cXSf/HF0n/xxeJ/8cXif/ + HF4n/xxeJ/8dXyf/HV8n/x1fJ/8dXyf/HWAo/x1gKP8dYCj/HWAo/x1hKP8dYSj/HWEo/x1hKP8icS// + InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS// + InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS// + InEv/yN0O/8jdDv/I3Q7/yN0O/8nh6r/J4eq/yeHqv8nh6r/LZ/s/y2f7P8tn+z/LZ/s/zCq/P8wqvz/ + MKr8/zCq/P8un9j/Lp/Y/y6f2P8un9j/IXJm/yFyZv8hcmb/IXJm/xhRIv8YUSL/GFEi/xhRIv8ZUiL/ + GVIi/xlSIv8ZUiL/GVMi/xlTIv8ZUyL/GVMi/xlUI/8ZVCP/GVQj/xlUI/8idGf/InRn/yJ0Z/8idGf/ + Lp/Y/y6f2P8un9j/Lp/Y/zCq/P8wqvz/MKr8/zCq/P8tn+z/LZ/s/y2f7P8tn+z/JYSj/yWEo/8lhKP/ + JYSj/xxeM/8cXjP/HF4z/xxeM/8bWiX/G1ol/xtaJf8bWiX/G1sm/xtbJv8bWyb/G1sm/xxcJv8cXCb/ + HFwm/xxcJv8cXSf/HF0n/xxdJ/8cXSf/HF4n/xxeJ/8cXif/HF4n/x1fJ/8dXyf/HV8n/x1fJ/8dYCj/ + HWAo/x1gKP8dYCj/HWEo/x1hKP8dYSj/HWEo/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS// + InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS// + InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//I3Q7/yN0O/8jdDv/I3Q7/yeHqv8nh6r/ + J4eq/yeHqv8tn+z/LZ/s/y2f7P8tn+z/MKr8/zCq/P8wqvz/MKr8/y6f2P8un9j/Lp/Y/y6f2P8hcmb/ + IXJm/yFyZv8hcmb/GFEi/xhRIv8YUSL/GFEi/xlSIv8ZUiL/GVIi/xlSIv8ZUyL/GVMi/xlTIv8ZUyL/ + GVQj/xlUI/8ZVCP/GVQj/yJ0Z/8idGf/InRn/yJ0Z/8un9j/Lp/Y/y6f2P8un9j/MKr8/zCq/P8wqvz/ + MKr8/y2f7P8tn+z/LZ/s/y2f7P8lhKP/JYSj/yWEo/8lhKP/HF4z/xxeM/8cXjP/HF4z/xtaJf8bWiX/ + G1ol/xtaJf8bWyb/G1sm/xtbJv8bWyb/HFwm/xxcJv8cXCb/HFwm/xxdJ/8cXSf/HF0n/xxdJ/8cXif/ + HF4n/xxeJ/8cXif/HV8n/x1fJ/8dXyf/HV8n/x1gKP8dYCj/HWAo/x1gKP8dYSj/HWEo/x1hKP8dYSj/ + LHg6/yx4Ov8seDr/LHg6/yVzM/8lczP/JXMz/yVzM/8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/ + I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yR0PP8kdDz/ + JHQ8/yR0PP8pj73/KY+9/ymPvf8pj73/MKn5/zCp+f8wqfn/MKn5/zCo9P8wqPT/MKj0/zCo9P8mgYn/ + JoGJ/yaBif8mgYn/GVAl/xlQJf8ZUCX/GVAl/xhQIv8YUCL/GFAi/xhQIv8ZUCP/GVAj/xlQI/8ZUCP/ + GVIj/xlSI/8ZUiP/GVIj/xlTJP8ZUyT/GVMk/xlTJP8aVCT/GlQk/xpUJP8aVCT/GlQk/xpUJP8aVCT/ + GlQk/xtXKP8bVyj/G1co/xtXKP8nhY3/J4WN/yeFjf8nhY3/MKr2/zCq9v8wqvb/MKr2/zCp+f8wqfn/ + MKn5/zCp+f8pjr3/KY69/ymOvf8pjr3/HV8z/x1fM/8dXzP/HV8z/xxbJ/8cWyf/HFsn/xxbJ/8cXCf/ + HFwn/xxcJ/8cXCf/HF0o/xxdKP8cXSj/HF0o/x1dKP8dXSj/HV0o/x1dKP8dXyn/HV8p/x1fKf8dXyn/ + HWAp/x1gKf8dYCn/HWAp/x5hKv8eYSr/HmEq/x5hKv8seDr/LHg6/yx4Ov8seDr/JXMz/yVzM/8lczP/ + JXMz/yNyMf8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/ + I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/JHQ8/yR0PP8kdDz/JHQ8/ymPvf8pj73/KY+9/ymPvf8wqfn/ + MKn5/zCp+f8wqfn/MKj0/zCo9P8wqPT/MKj0/yaBif8mgYn/JoGJ/yaBif8ZUCX/GVAl/xlQJf8ZUCX/ + GFAi/xhQIv8YUCL/GFAi/xlQI/8ZUCP/GVAj/xlQI/8ZUiP/GVIj/xlSI/8ZUiP/GVMk/xlTJP8ZUyT/ + GVMk/xpUJP8aVCT/GlQk/xpUJP8aVCT/GlQk/xpUJP8aVCT/G1co/xtXKP8bVyj/G1co/yeFjf8nhY3/ + J4WN/yeFjf8wqvb/MKr2/zCq9v8wqvb/MKn5/zCp+f8wqfn/MKn5/ymOvf8pjr3/KY69/ymOvf8dXzP/ + HV8z/x1fM/8dXzP/HFsn/xxbJ/8cWyf/HFsn/xxcJ/8cXCf/HFwn/xxcJ/8cXSj/HF0o/xxdKP8cXSj/ + HV0o/x1dKP8dXSj/HV0o/x1fKf8dXyn/HV8p/x1fKf8dYCn/HWAp/x1gKf8dYCn/HmEq/x5hKv8eYSr/ + HmEq/yx4Ov8seDr/LHg6/yx4Ov8lczP/JXMz/yVzM/8lczP/I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/ + I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yNyMf8kdDz/ + JHQ8/yR0PP8kdDz/KY+9/ymPvf8pj73/KY+9/zCp+f8wqfn/MKn5/zCp+f8wqPT/MKj0/zCo9P8wqPT/ + JoGJ/yaBif8mgYn/JoGJ/xlQJf8ZUCX/GVAl/xlQJf8YUCL/GFAi/xhQIv8YUCL/GVAj/xlQI/8ZUCP/ + GVAj/xlSI/8ZUiP/GVIj/xlSI/8ZUyT/GVMk/xlTJP8ZUyT/GlQk/xpUJP8aVCT/GlQk/xpUJP8aVCT/ + GlQk/xpUJP8bVyj/G1co/xtXKP8bVyj/J4WN/yeFjf8nhY3/J4WN/zCq9v8wqvb/MKr2/zCq9v8wqfn/ + MKn5/zCp+f8wqfn/KY69/ymOvf8pjr3/KY69/x1fM/8dXzP/HV8z/x1fM/8cWyf/HFsn/xxbJ/8cWyf/ + HFwn/xxcJ/8cXCf/HFwn/xxdKP8cXSj/HF0o/xxdKP8dXSj/HV0o/x1dKP8dXSj/HV8p/x1fKf8dXyn/ + HV8p/x1gKf8dYCn/HWAp/x1gKf8eYSr/HmEq/x5hKv8eYSr/LHg6/yx4Ov8seDr/LHg6/yVzM/8lczP/ + JXMz/yVzM/8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/ + I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yR0PP8kdDz/JHQ8/yR0PP8pj73/KY+9/ymPvf8pj73/ + MKn5/zCp+f8wqfn/MKn5/zCo9P8wqPT/MKj0/zCo9P8mgYn/JoGJ/yaBif8mgYn/GVAl/xlQJf8ZUCX/ + GVAl/xhQIv8YUCL/GFAi/xhQIv8ZUCP/GVAj/xlQI/8ZUCP/GVIj/xlSI/8ZUiP/GVIj/xlTJP8ZUyT/ + GVMk/xlTJP8aVCT/GlQk/xpUJP8aVCT/GlQk/xpUJP8aVCT/GlQk/xtXKP8bVyj/G1co/xtXKP8nhY3/ + J4WN/yeFjf8nhY3/MKr2/zCq9v8wqvb/MKr2/zCp+f8wqfn/MKn5/zCp+f8pjr3/KY69/ymOvf8pjr3/ + HV8z/x1fM/8dXzP/HV8z/xxbJ/8cWyf/HFsn/xxbJ/8cXCf/HFwn/xxcJ/8cXCf/HF0o/xxdKP8cXSj/ + HF0o/x1dKP8dXSj/HV0o/x1dKP8dXyn/HV8p/x1fKf8dXyn/HWAp/x1gKf8dYCn/HWAp/x5hKv8eYSr/ + HmEq/x5hKv9SkV3/UpFd/1KRXf9SkV3/UpFd/1KRXf9SkV3/UpFd/0mLVf9Ji1X/SYtV/0mLVf8+hEr/ + PoRK/z6ESv8+hEr/M35A/zN+QP8zfkD/M35A/yh3Nv8odzb/KHc2/yh3Nv8kdjv/JHY7/yR2O/8kdjv/ + KpPA/yqTwP8qk8D/KpPA/zGr+/8xq/v/Mav7/zGr+/8unc3/Lp3N/y6dzf8unc3/HWBC/x1gQv8dYEL/ + HWBC/xhOIv8YTiL/GE4i/xhOIv8ZTyL/GU8i/xlPIv8ZTyL/GVAj/xlQI/8ZUCP/GVAj/xlRI/8ZUSP/ + GVEj/xlRI/8ZUiP/GVIj/xlSI/8ZUiP/GlMk/xpTJP8aUyT/GlMk/xpUJP8aVCT/GlQk/xpUJP8aVSX/ + GlUl/xpVJf8aVSX/G1Yl/xtWJf8bViX/G1Yl/xtXJf8bVyX/G1cl/xtXJf8gaEn/IGhJ/yBoSf8gaEn/ + LqDT/y6g0/8uoNP/LqDT/zGr+/8xq/v/Mav7/zGr+/8qk8D/KpPA/yqTwP8qk8D/HmAy/x5gMv8eYDL/ + HmAy/x1cKP8dXCj/HVwo/x1cKP8dXSj/HV0o/x1dKP8dXSj/HV4p/x1eKf8dXin/HV4p/x5fKf8eXyn/ + Hl8p/x5fKf8eYCr/HmAq/x5gKv8eYCr/HmEq/x5hKv8eYSr/HmEq/1KRXf9SkV3/UpFd/1KRXf9SkV3/ + UpFd/1KRXf9SkV3/SYtV/0mLVf9Ji1X/SYtV/z6ESv8+hEr/PoRK/z6ESv8zfkD/M35A/zN+QP8zfkD/ + KHc2/yh3Nv8odzb/KHc2/yR2O/8kdjv/JHY7/yR2O/8qk8D/KpPA/yqTwP8qk8D/Mav7/zGr+/8xq/v/ + Mav7/y6dzf8unc3/Lp3N/y6dzf8dYEL/HWBC/x1gQv8dYEL/GE4i/xhOIv8YTiL/GE4i/xlPIv8ZTyL/ + GU8i/xlPIv8ZUCP/GVAj/xlQI/8ZUCP/GVEj/xlRI/8ZUSP/GVEj/xlSI/8ZUiP/GVIj/xlSI/8aUyT/ + GlMk/xpTJP8aUyT/GlQk/xpUJP8aVCT/GlQk/xpVJf8aVSX/GlUl/xpVJf8bViX/G1Yl/xtWJf8bViX/ + G1cl/xtXJf8bVyX/G1cl/yBoSf8gaEn/IGhJ/yBoSf8uoNP/LqDT/y6g0/8uoNP/Mav7/zGr+/8xq/v/ + Mav7/yqTwP8qk8D/KpPA/yqTwP8eYDL/HmAy/x5gMv8eYDL/HVwo/x1cKP8dXCj/HVwo/x1dKP8dXSj/ + HV0o/x1dKP8dXin/HV4p/x1eKf8dXin/Hl8p/x5fKf8eXyn/Hl8p/x5gKv8eYCr/HmAq/x5gKv8eYSr/ + HmEq/x5hKv8eYSr/UpFd/1KRXf9SkV3/UpFd/1KRXf9SkV3/UpFd/1KRXf9Ji1X/SYtV/0mLVf9Ji1X/ + PoRK/z6ESv8+hEr/PoRK/zN+QP8zfkD/M35A/zN+QP8odzb/KHc2/yh3Nv8odzb/JHY7/yR2O/8kdjv/ + JHY7/yqTwP8qk8D/KpPA/yqTwP8xq/v/Mav7/zGr+/8xq/v/Lp3N/y6dzf8unc3/Lp3N/x1gQv8dYEL/ + HWBC/x1gQv8YTiL/GE4i/xhOIv8YTiL/GU8i/xlPIv8ZTyL/GU8i/xlQI/8ZUCP/GVAj/xlQI/8ZUSP/ + GVEj/xlRI/8ZUSP/GVIj/xlSI/8ZUiP/GVIj/xpTJP8aUyT/GlMk/xpTJP8aVCT/GlQk/xpUJP8aVCT/ + GlUl/xpVJf8aVSX/GlUl/xtWJf8bViX/G1Yl/xtWJf8bVyX/G1cl/xtXJf8bVyX/IGhJ/yBoSf8gaEn/ + IGhJ/y6g0/8uoNP/LqDT/y6g0/8xq/v/Mav7/zGr+/8xq/v/KpPA/yqTwP8qk8D/KpPA/x5gMv8eYDL/ + HmAy/x5gMv8dXCj/HVwo/x1cKP8dXCj/HV0o/x1dKP8dXSj/HV0o/x1eKf8dXin/HV4p/x1eKf8eXyn/ + Hl8p/x5fKf8eXyn/HmAq/x5gKv8eYCr/HmAq/x5hKv8eYSr/HmEq/x5hKv9SkV3/UpFd/1KRXf9SkV3/ + UpFd/1KRXf9SkV3/UpFd/0mLVf9Ji1X/SYtV/0mLVf8+hEr/PoRK/z6ESv8+hEr/M35A/zN+QP8zfkD/ + M35A/yh3Nv8odzb/KHc2/yh3Nv8kdjv/JHY7/yR2O/8kdjv/KpPA/yqTwP8qk8D/KpPA/zGr+/8xq/v/ + Mav7/zGr+/8unc3/Lp3N/y6dzf8unc3/HWBC/x1gQv8dYEL/HWBC/xhOIv8YTiL/GE4i/xhOIv8ZTyL/ + GU8i/xlPIv8ZTyL/GVAj/xlQI/8ZUCP/GVAj/xlRI/8ZUSP/GVEj/xlRI/8ZUiP/GVIj/xlSI/8ZUiP/ + GlMk/xpTJP8aUyT/GlMk/xpUJP8aVCT/GlQk/xpUJP8aVSX/GlUl/xpVJf8aVSX/G1Yl/xtWJf8bViX/ + G1Yl/xtXJf8bVyX/G1cl/xtXJf8gaEn/IGhJ/yBoSf8gaEn/LqDT/y6g0/8uoNP/LqDT/zGr+/8xq/v/ + Mav7/zGr+/8qk8D/KpPA/yqTwP8qk8D/HmAy/x5gMv8eYDL/HmAy/x1cKP8dXCj/HVwo/x1cKP8dXSj/ + HV0o/x1dKP8dXSj/HV4p/x1eKf8dXin/HV4p/x5fKf8eXyn/Hl8p/x5fKf8eYCr/HmAq/x5gKv8eYCr/ + HmEq/x5hKv8eYSr/HmEq/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/ + VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1Smuf9Uprn/ + VKa5/1Smuf9Jtvv/Sbb7/0m2+/9Jtvv/NZy9/zWcvf81nL3/NZy9/1l9Xf9ZfV3/WX1d/1l9Xf9ig2L/ + YoNi/2KDYv9ig2L/Y4Ni/2ODYv9jg2L/Y4Ni/2OEYv9jhGL/Y4Ri/2OEYv9jhWL/Y4Vi/2OFYv9jhWL/ + Y4Vi/2OFYv9jhWL/Y4Vi/2OGY/9jhmP/Y4Zj/2OGY/9jh2P/Y4dj/2OHY/9jh2P/ZIdk/2SHZP9kh2T/ + ZIdk/2SIZP9kiGT/ZIhk/2SIZP9kiWT/ZIlk/2SJZP9kiWT/ZIlk/2SJZP9kiWT/ZIlk/2WKZP9limT/ + ZYpk/2WKZP9ahWL/WoVi/1qFYv9ahWL/MJvC/zCbwv8wm8L/MJvC/zKt+/8yrfv/Mq37/zKt+/8qkKn/ + KpCp/yqQqf8qkKn/HVwo/x1cKP8dXCj/HVwo/x1dKf8dXSn/HV0p/x1dKf8eXin/Hl4p/x5eKf8eXin/ + Hl8p/x5fKf8eXyn/Hl8p/x5gKv8eYCr/HmAq/x5gKv8fYiv/H2Ir/x9iK/8fYiv/VpRh/1aUYf9WlGH/ + VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/ + VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VKa5/1Smuf9Uprn/VKa5/0m2+/9Jtvv/Sbb7/0m2+/81nL3/ + NZy9/zWcvf81nL3/WX1d/1l9Xf9ZfV3/WX1d/2KDYv9ig2L/YoNi/2KDYv9jg2L/Y4Ni/2ODYv9jg2L/ + Y4Ri/2OEYv9jhGL/Y4Ri/2OFYv9jhWL/Y4Vi/2OFYv9jhWL/Y4Vi/2OFYv9jhWL/Y4Zj/2OGY/9jhmP/ + Y4Zj/2OHY/9jh2P/Y4dj/2OHY/9kh2T/ZIdk/2SHZP9kh2T/ZIhk/2SIZP9kiGT/ZIhk/2SJZP9kiWT/ + ZIlk/2SJZP9kiWT/ZIlk/2SJZP9kiWT/ZYpk/2WKZP9limT/ZYpk/1qFYv9ahWL/WoVi/1qFYv8wm8L/ + MJvC/zCbwv8wm8L/Mq37/zKt+/8yrfv/Mq37/yqQqf8qkKn/KpCp/yqQqf8dXCj/HVwo/x1cKP8dXCj/ + HV0p/x1dKf8dXSn/HV0p/x5eKf8eXin/Hl4p/x5eKf8eXyn/Hl8p/x5fKf8eXyn/HmAq/x5gKv8eYCr/ + HmAq/x9iK/8fYiv/H2Ir/x9iK/9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/ + VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9Uprn/ + VKa5/1Smuf9Uprn/Sbb7/0m2+/9Jtvv/Sbb7/zWcvf81nL3/NZy9/zWcvf9ZfV3/WX1d/1l9Xf9ZfV3/ + YoNi/2KDYv9ig2L/YoNi/2ODYv9jg2L/Y4Ni/2ODYv9jhGL/Y4Ri/2OEYv9jhGL/Y4Vi/2OFYv9jhWL/ + Y4Vi/2OFYv9jhWL/Y4Vi/2OFYv9jhmP/Y4Zj/2OGY/9jhmP/Y4dj/2OHY/9jh2P/Y4dj/2SHZP9kh2T/ + ZIdk/2SHZP9kiGT/ZIhk/2SIZP9kiGT/ZIlk/2SJZP9kiWT/ZIlk/2SJZP9kiWT/ZIlk/2SJZP9limT/ + ZYpk/2WKZP9limT/WoVi/1qFYv9ahWL/WoVi/zCbwv8wm8L/MJvC/zCbwv8yrfv/Mq37/zKt+/8yrfv/ + KpCp/yqQqf8qkKn/KpCp/x1cKP8dXCj/HVwo/x1cKP8dXSn/HV0p/x1dKf8dXSn/Hl4p/x5eKf8eXin/ + Hl4p/x5fKf8eXyn/Hl8p/x5fKf8eYCr/HmAq/x5gKv8eYCr/H2Ir/x9iK/8fYiv/H2Ir/1aUYf9WlGH/ + VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/ + VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1Smuf9Uprn/VKa5/1Smuf9Jtvv/Sbb7/0m2+/9Jtvv/ + NZy9/zWcvf81nL3/NZy9/1l9Xf9ZfV3/WX1d/1l9Xf9ig2L/YoNi/2KDYv9ig2L/Y4Ni/2ODYv9jg2L/ + Y4Ni/2OEYv9jhGL/Y4Ri/2OEYv9jhWL/Y4Vi/2OFYv9jhWL/Y4Vi/2OFYv9jhWL/Y4Vi/2OGY/9jhmP/ + Y4Zj/2OGY/9jh2P/Y4dj/2OHY/9jh2P/ZIdk/2SHZP9kh2T/ZIdk/2SIZP9kiGT/ZIhk/2SIZP9kiWT/ + ZIlk/2SJZP9kiWT/ZIlk/2SJZP9kiWT/ZIlk/2WKZP9limT/ZYpk/2WKZP9ahWL/WoVi/1qFYv9ahWL/ + MJvC/zCbwv8wm8L/MJvC/zKt+/8yrfv/Mq37/zKt+/8qkKn/KpCp/yqQqf8qkKn/HVwo/x1cKP8dXCj/ + HVwo/x1dKf8dXSn/HV0p/x1dKf8eXin/Hl4p/x5eKf8eXin/Hl8p/x5fKf8eXyn/Hl8p/x5gKv8eYCr/ + HmAq/x5gKv8fYiv/H2Ir/x9iK/8fYiv/WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/ + WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/WJdl/1iXZf9bn4j/W5+I/1ufiP9bn4j/ + YsD6/2LA+v9iwPr/YsD6/16xzf9esc3/XrHN/16xzf/O1Mb/ztTG/87Uxv/O1Mb/19nN/9fZzf/X2c3/ + 19nN/8TKuv/Eyrr/xMq6/8TKuv+/xrT/v8a0/7/GtP+/xrT/v8az/7/Gs/+/xrP/v8az/7/Gs/+/xrP/ + v8az/7/Gs/+/xrP/v8az/7/Gs/+/xrP/v8e0/7/HtP+/x7T/v8e0/7/HtP+/x7T/v8e0/7/HtP+/x7T/ + v8e0/7/HtP+/x7T/v8e0/7/HtP+/x7T/v8e0/7/ItP+/yLT/v8i0/7/ItP+/yLT/v8i0/7/ItP+/yLT/ + v8i0/7/ItP+/yLT/v8i0/83Swv/N0sL/zdLC/83Swv++ybb/vsm2/77Jtv++ybb/Lp3D/y6dw/8uncP/ + Lp3D/zKt+v8yrfr/Mq36/zKt+v8jdV7/I3Ve/yN1Xv8jdV7/HV4q/x1eKv8dXir/HV4q/x1fKv8dXyr/ + HV8q/x1fKv8eYCv/HmAr/x5gK/8eYCv/HmEr/x5hK/8eYSv/HmEr/x5iLP8eYiz/HmIs/x5iLP9Yl2X/ + WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/ + WJdl/1iXZf9Yl2X/WJdl/1ufiP9bn4j/W5+I/1ufiP9iwPr/YsD6/2LA+v9iwPr/XrHN/16xzf9esc3/ + XrHN/87Uxv/O1Mb/ztTG/87Uxv/X2c3/19nN/9fZzf/X2c3/xMq6/8TKuv/Eyrr/xMq6/7/GtP+/xrT/ + v8a0/7/GtP+/xrP/v8az/7/Gs/+/xrP/v8az/7/Gs/+/xrP/v8az/7/Gs/+/xrP/v8az/7/Gs/+/x7T/ + v8e0/7/HtP+/x7T/v8e0/7/HtP+/x7T/v8e0/7/HtP+/x7T/v8e0/7/HtP+/x7T/v8e0/7/HtP+/x7T/ + v8i0/7/ItP+/yLT/v8i0/7/ItP+/yLT/v8i0/7/ItP+/yLT/v8i0/7/ItP+/yLT/zdLC/83Swv/N0sL/ + zdLC/77Jtv++ybb/vsm2/77Jtv8uncP/Lp3D/y6dw/8uncP/Mq36/zKt+v8yrfr/Mq36/yN1Xv8jdV7/ + I3Ve/yN1Xv8dXir/HV4q/x1eKv8dXir/HV8q/x1fKv8dXyr/HV8q/x5gK/8eYCv/HmAr/x5gK/8eYSv/ + HmEr/x5hK/8eYSv/HmIs/x5iLP8eYiz/HmIs/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/ + WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/W5+I/1ufiP9bn4j/ + W5+I/2LA+v9iwPr/YsD6/2LA+v9esc3/XrHN/16xzf9esc3/ztTG/87Uxv/O1Mb/ztTG/9fZzf/X2c3/ + 19nN/9fZzf/Eyrr/xMq6/8TKuv/Eyrr/v8a0/7/GtP+/xrT/v8a0/7/Gs/+/xrP/v8az/7/Gs/+/xrP/ + v8az/7/Gs/+/xrP/v8az/7/Gs/+/xrP/v8az/7/HtP+/x7T/v8e0/7/HtP+/x7T/v8e0/7/HtP+/x7T/ + v8e0/7/HtP+/x7T/v8e0/7/HtP+/x7T/v8e0/7/HtP+/yLT/v8i0/7/ItP+/yLT/v8i0/7/ItP+/yLT/ + v8i0/7/ItP+/yLT/v8i0/7/ItP/N0sL/zdLC/83Swv/N0sL/vsm2/77Jtv++ybb/vsm2/y6dw/8uncP/ + Lp3D/y6dw/8yrfr/Mq36/zKt+v8yrfr/I3Ve/yN1Xv8jdV7/I3Ve/x1eKv8dXir/HV4q/x1eKv8dXyr/ + HV8q/x1fKv8dXyr/HmAr/x5gK/8eYCv/HmAr/x5hK/8eYSv/HmEr/x5hK/8eYiz/HmIs/x5iLP8eYiz/ + WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/ + WJdl/1iXZf9Yl2X/WJdl/1iXZf9bn4j/W5+I/1ufiP9bn4j/YsD6/2LA+v9iwPr/YsD6/16xzf9esc3/ + XrHN/16xzf/O1Mb/ztTG/87Uxv/O1Mb/19nN/9fZzf/X2c3/19nN/8TKuv/Eyrr/xMq6/8TKuv+/xrT/ + v8a0/7/GtP+/xrT/v8az/7/Gs/+/xrP/v8az/7/Gs/+/xrP/v8az/7/Gs/+/xrP/v8az/7/Gs/+/xrP/ + v8e0/7/HtP+/x7T/v8e0/7/HtP+/x7T/v8e0/7/HtP+/x7T/v8e0/7/HtP+/x7T/v8e0/7/HtP+/x7T/ + v8e0/7/ItP+/yLT/v8i0/7/ItP+/yLT/v8i0/7/ItP+/yLT/v8i0/7/ItP+/yLT/v8i0/83Swv/N0sL/ + zdLC/83Swv++ybb/vsm2/77Jtv++ybb/Lp3D/y6dw/8uncP/Lp3D/zKt+v8yrfr/Mq36/zKt+v8jdV7/ + I3Ve/yN1Xv8jdV7/HV4q/x1eKv8dXir/HV4q/x1fKv8dXyr/HV8q/x1fKv8eYCv/HmAr/x5gK/8eYCv/ + HmEr/x5hK/8eYSv/HmEr/x5iLP8eYiz/HmIs/x5iLP9cmmj/XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/ + XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/XJpo/2W73/9lu9// + Zbvf/2W73/9lv+3/Zb/t/2W/7f9lv+3/VIBm/1SAZv9UgGb/VIBm//v07f/79O3/+/Tt//v07f9fgmT/ + X4Jk/1+CZP9fgmT/Unpa/1J6Wv9Selr/Unpa/1B4WP9QeFj/UHhY/1B4WP88akX/PGpF/zxqRf88akX/ + IFUr/yBVK/8gVSv/IFUr/xpRJP8aUST/GlEk/xpRJP8nWzH/J1sx/ydbMf8nWzH/J1wx/ydcMf8nXDH/ + J1wx/xtUJv8bVCb/G1Qm/xtUJv8bVSb/G1Um/xtVJv8bVSb/G1Yn/xtWJ/8bVif/G1Yn/xxXJ/8cVyf/ + HFcn/xxXJ/8cWCj/HFgo/xxYKP8cWCj/LGQ1/yxkNf8sZDX/LGQ1//nw5//58Of/+fDn//nw5/8gZT7/ + IGU+/yBlPv8gZT7/Mqrr/zKq6/8yquv/Mqrr/zGk1/8xpNf/MaTX/zGk1/8eXir/Hl4q/x5eKv8eXir/ + Hl8r/x5fK/8eXyv/Hl8r/x5gK/8eYCv/HmAr/x5gK/8fYCv/H2Ar/x9gK/8fYCv/H2Is/x9iLP8fYiz/ + H2Is/1yaaP9cmmj/XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/ + XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/Zbvf/2W73/9lu9//Zbvf/2W/7f9lv+3/Zb/t/2W/7f9UgGb/ + VIBm/1SAZv9UgGb/+/Tt//v07f/79O3/+/Tt/1+CZP9fgmT/X4Jk/1+CZP9Selr/Unpa/1J6Wv9Selr/ + UHhY/1B4WP9QeFj/UHhY/zxqRf88akX/PGpF/zxqRf8gVSv/IFUr/yBVK/8gVSv/GlEk/xpRJP8aUST/ + GlEk/ydbMf8nWzH/J1sx/ydbMf8nXDH/J1wx/ydcMf8nXDH/G1Qm/xtUJv8bVCb/G1Qm/xtVJv8bVSb/ + G1Um/xtVJv8bVif/G1Yn/xtWJ/8bVif/HFcn/xxXJ/8cVyf/HFcn/xxYKP8cWCj/HFgo/xxYKP8sZDX/ + LGQ1/yxkNf8sZDX/+fDn//nw5//58Of/+fDn/yBlPv8gZT7/IGU+/yBlPv8yquv/Mqrr/zKq6/8yquv/ + MaTX/zGk1/8xpNf/MaTX/x5eKv8eXir/Hl4q/x5eKv8eXyv/Hl8r/x5fK/8eXyv/HmAr/x5gK/8eYCv/ + HmAr/x9gK/8fYCv/H2Ar/x9gK/8fYiz/H2Is/x9iLP8fYiz/XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/ + XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/XJpo/1yaaP9lu9// + Zbvf/2W73/9lu9//Zb/t/2W/7f9lv+3/Zb/t/1SAZv9UgGb/VIBm/1SAZv/79O3/+/Tt//v07f/79O3/ + X4Jk/1+CZP9fgmT/X4Jk/1J6Wv9Selr/Unpa/1J6Wv9QeFj/UHhY/1B4WP9QeFj/PGpF/zxqRf88akX/ + PGpF/yBVK/8gVSv/IFUr/yBVK/8aUST/GlEk/xpRJP8aUST/J1sx/ydbMf8nWzH/J1sx/ydcMf8nXDH/ + J1wx/ydcMf8bVCb/G1Qm/xtUJv8bVCb/G1Um/xtVJv8bVSb/G1Um/xtWJ/8bVif/G1Yn/xtWJ/8cVyf/ + HFcn/xxXJ/8cVyf/HFgo/xxYKP8cWCj/HFgo/yxkNf8sZDX/LGQ1/yxkNf/58Of/+fDn//nw5//58Of/ + IGU+/yBlPv8gZT7/IGU+/zKq6/8yquv/Mqrr/zKq6/8xpNf/MaTX/zGk1/8xpNf/Hl4q/x5eKv8eXir/ + Hl4q/x5fK/8eXyv/Hl8r/x5fK/8eYCv/HmAr/x5gK/8eYCv/H2Ar/x9gK/8fYCv/H2Ar/x9iLP8fYiz/ + H2Is/x9iLP9cmmj/XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/ + XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/XJpo/2W73/9lu9//Zbvf/2W73/9lv+3/Zb/t/2W/7f9lv+3/ + VIBm/1SAZv9UgGb/VIBm//v07f/79O3/+/Tt//v07f9fgmT/X4Jk/1+CZP9fgmT/Unpa/1J6Wv9Selr/ + Unpa/1B4WP9QeFj/UHhY/1B4WP88akX/PGpF/zxqRf88akX/IFUr/yBVK/8gVSv/IFUr/xpRJP8aUST/ + GlEk/xpRJP8nWzH/J1sx/ydbMf8nWzH/J1wx/ydcMf8nXDH/J1wx/xtUJv8bVCb/G1Qm/xtUJv8bVSb/ + G1Um/xtVJv8bVSb/G1Yn/xtWJ/8bVif/G1Yn/xxXJ/8cVyf/HFcn/xxXJ/8cWCj/HFgo/xxYKP8cWCj/ + LGQ1/yxkNf8sZDX/LGQ1//nw5//58Of/+fDn//nw5/8gZT7/IGU+/yBlPv8gZT7/Mqrr/zKq6/8yquv/ + Mqrr/zGk1/8xpNf/MaTX/zGk1/8eXir/Hl4q/x5eKv8eXir/Hl8r/x5fK/8eXyv/Hl8r/x5gK/8eYCv/ + HmAr/x5gK/8fYCv/H2Ar/x9gK/8fYCv/H2Is/x9iLP8fYiz/H2Is/2CdbP9gnWz/YJ1s/2CdbP9gnWz/ + YJ1s/2CdbP9gnWz/YJ1s/2CdbP9gnWz/YJ1s/2CdbP9gnWz/YJ1s/2CdbP9ho4P/YaOD/2Gjg/9ho4P/ + acX8/2nF/P9pxfz/acX8/2Cgof9goKH/YKCh/2Cgof9Velz/VXpc/1V6XP9Velz/+/Xw//v18P/79fD/ + +/Xw/1+DZv9fg2b/X4Nm/1+DZv9VfV7/VX1e/1V9Xv9VfV7/VX1e/1V9Xv9VfV7/VX1e/1V9Xv9VfV7/ + VX1e/1V9Xv9UfV3/VH1d/1R9Xf9UfV3/PGtF/zxrRf88a0X/PGtF/5Cnjv+Qp47/kKeO/5Cnjv+Ppoz/ + j6aM/4+mjP+Ppoz/G1Qn/xtUJ/8bVCf/G1Qn/xtVJ/8bVSf/G1Un/xtVJ/8cVij/HFYo/xxWKP8cVij/ + HFgo/xxYKP8cWCj/HFgo/xxZKf8cWSn/HFkp/xxZKf8rYjX/K2I1/ytiNf8rYjX/+vLq//ry6v/68ur/ + +vLq/x1bKv8dWyr/HVsq/x1bKv8piIf/KYiH/ymIh/8piIf/M7D7/zOw+/8zsPv/M7D7/yNwUP8jcFD/ + I3BQ/yNwUP8eXyz/Hl8s/x5fLP8eXyz/H2As/x9gLP8fYCz/H2As/x9hLf8fYS3/H2Et/x9hLf8gYy3/ + IGMt/yBjLf8gYy3/YJ1s/2CdbP9gnWz/YJ1s/2CdbP9gnWz/YJ1s/2CdbP9gnWz/YJ1s/2CdbP9gnWz/ + YJ1s/2CdbP9gnWz/YJ1s/2Gjg/9ho4P/YaOD/2Gjg/9pxfz/acX8/2nF/P9pxfz/YKCh/2Cgof9goKH/ + YKCh/1V6XP9Velz/VXpc/1V6XP/79fD/+/Xw//v18P/79fD/X4Nm/1+DZv9fg2b/X4Nm/1V9Xv9VfV7/ + VX1e/1V9Xv9VfV7/VX1e/1V9Xv9VfV7/VX1e/1V9Xv9VfV7/VX1e/1R9Xf9UfV3/VH1d/1R9Xf88a0X/ + PGtF/zxrRf88a0X/kKeO/5Cnjv+Qp47/kKeO/4+mjP+Ppoz/j6aM/4+mjP8bVCf/G1Qn/xtUJ/8bVCf/ + G1Un/xtVJ/8bVSf/G1Un/xxWKP8cVij/HFYo/xxWKP8cWCj/HFgo/xxYKP8cWCj/HFkp/xxZKf8cWSn/ + HFkp/ytiNf8rYjX/K2I1/ytiNf/68ur/+vLq//ry6v/68ur/HVsq/x1bKv8dWyr/HVsq/ymIh/8piIf/ + KYiH/ymIh/8zsPv/M7D7/zOw+/8zsPv/I3BQ/yNwUP8jcFD/I3BQ/x5fLP8eXyz/Hl8s/x5fLP8fYCz/ + H2As/x9gLP8fYCz/H2Et/x9hLf8fYS3/H2Et/yBjLf8gYy3/IGMt/yBjLf9gnWz/YJ1s/2CdbP9gnWz/ + YJ1s/2CdbP9gnWz/YJ1s/2CdbP9gnWz/YJ1s/2CdbP9gnWz/YJ1s/2CdbP9gnWz/YaOD/2Gjg/9ho4P/ + YaOD/2nF/P9pxfz/acX8/2nF/P9goKH/YKCh/2Cgof9goKH/VXpc/1V6XP9Velz/VXpc//v18P/79fD/ + +/Xw//v18P9fg2b/X4Nm/1+DZv9fg2b/VX1e/1V9Xv9VfV7/VX1e/1V9Xv9VfV7/VX1e/1V9Xv9VfV7/ + VX1e/1V9Xv9VfV7/VH1d/1R9Xf9UfV3/VH1d/zxrRf88a0X/PGtF/zxrRf+Qp47/kKeO/5Cnjv+Qp47/ + j6aM/4+mjP+Ppoz/j6aM/xtUJ/8bVCf/G1Qn/xtUJ/8bVSf/G1Un/xtVJ/8bVSf/HFYo/xxWKP8cVij/ + HFYo/xxYKP8cWCj/HFgo/xxYKP8cWSn/HFkp/xxZKf8cWSn/K2I1/ytiNf8rYjX/K2I1//ry6v/68ur/ + +vLq//ry6v8dWyr/HVsq/x1bKv8dWyr/KYiH/ymIh/8piIf/KYiH/zOw+/8zsPv/M7D7/zOw+/8jcFD/ + I3BQ/yNwUP8jcFD/Hl8s/x5fLP8eXyz/Hl8s/x9gLP8fYCz/H2As/x9gLP8fYS3/H2Et/x9hLf8fYS3/ + IGMt/yBjLf8gYy3/IGMt/2CdbP9gnWz/YJ1s/2CdbP9gnWz/YJ1s/2CdbP9gnWz/YJ1s/2CdbP9gnWz/ + YJ1s/2CdbP9gnWz/YJ1s/2CdbP9ho4P/YaOD/2Gjg/9ho4P/acX8/2nF/P9pxfz/acX8/2Cgof9goKH/ + YKCh/2Cgof9Velz/VXpc/1V6XP9Velz/+/Xw//v18P/79fD/+/Xw/1+DZv9fg2b/X4Nm/1+DZv9VfV7/ + VX1e/1V9Xv9VfV7/VX1e/1V9Xv9VfV7/VX1e/1V9Xv9VfV7/VX1e/1V9Xv9UfV3/VH1d/1R9Xf9UfV3/ + PGtF/zxrRf88a0X/PGtF/5Cnjv+Qp47/kKeO/5Cnjv+Ppoz/j6aM/4+mjP+Ppoz/G1Qn/xtUJ/8bVCf/ + G1Qn/xtVJ/8bVSf/G1Un/xtVJ/8cVij/HFYo/xxWKP8cVij/HFgo/xxYKP8cWCj/HFgo/xxZKf8cWSn/ + HFkp/xxZKf8rYjX/K2I1/ytiNf8rYjX/+vLq//ry6v/68ur/+vLq/x1bKv8dWyr/HVsq/x1bKv8piIf/ + KYiH/ymIh/8piIf/M7D7/zOw+/8zsPv/M7D7/yNwUP8jcFD/I3BQ/yNwUP8eXyz/Hl8s/x5fLP8eXyz/ + H2As/x9gLP8fYCz/H2As/x9hLf8fYS3/H2Et/x9hLf8gYy3/IGMt/yBjLf8gYy3/Y59v/2Ofb/9jn2// + Y59v/2Ofb/9jn2//Y59v/2Ofb/9jn2//Y59v/2Ofb/9jn2//Y59v/2Ofb/9jn2//Y59v/2eztP9ns7T/ + Z7O0/2eztP9rxff/a8X3/2vF9/9rxff/WYFq/1mBav9ZgWr/WYFq/1d8X/9XfF//V3xf/1d8X//89vH/ + /Pbx//z28f/89vH/YoRp/2KEaf9ihGn/YoRp/1h+YP9YfmD/WH5g/1h+YP9Yf2D/WH9g/1h/YP9Yf2D/ + WX9h/1l/Yf9Zf2H/WX9h/1mAYf9ZgGH/WYBh/1mAYf9ZgWL/WYFi/1mBYv9ZgWL/r7+t/6+/rf+vv63/ + r7+t/6G0nv+htJ7/obSe/6G0nv8eVir/HlYq/x5WKv8eVir/HFUn/xxVJ/8cVSf/HFUn/xxWKP8cVij/ + HFYo/xxWKP8cVyj/HFco/xxXKP8cVyj/HVgp/x1YKf8dWCn/HVgp/ytiNf8rYjX/K2I1/ytiNf/78+z/ + +/Ps//vz7P/78+z/Hlsq/x5bKv8eWyr/Hlsq/yBmPf8gZj3/IGY9/yBmPf80sPf/NLD3/zSw9/80sPf/ + K5CX/yuQl/8rkJf/K5CX/x9fLP8fXyz/H18s/x9fLP8fYCz/H2As/x9gLP8fYCz/IGEt/yBhLf8gYS3/ + IGEt/yBiLv8gYi7/IGIu/yBiLv9jn2//Y59v/2Ofb/9jn2//Y59v/2Ofb/9jn2//Y59v/2Ofb/9jn2// + Y59v/2Ofb/9jn2//Y59v/2Ofb/9jn2//Z7O0/2eztP9ns7T/Z7O0/2vF9/9rxff/a8X3/2vF9/9ZgWr/ + WYFq/1mBav9ZgWr/V3xf/1d8X/9XfF//V3xf//z28f/89vH//Pbx//z28f9ihGn/YoRp/2KEaf9ihGn/ + WH5g/1h+YP9YfmD/WH5g/1h/YP9Yf2D/WH9g/1h/YP9Zf2H/WX9h/1l/Yf9Zf2H/WYBh/1mAYf9ZgGH/ + WYBh/1mBYv9ZgWL/WYFi/1mBYv+vv63/r7+t/6+/rf+vv63/obSe/6G0nv+htJ7/obSe/x5WKv8eVir/ + HlYq/x5WKv8cVSf/HFUn/xxVJ/8cVSf/HFYo/xxWKP8cVij/HFYo/xxXKP8cVyj/HFco/xxXKP8dWCn/ + HVgp/x1YKf8dWCn/K2I1/ytiNf8rYjX/K2I1//vz7P/78+z/+/Ps//vz7P8eWyr/Hlsq/x5bKv8eWyr/ + IGY9/yBmPf8gZj3/IGY9/zSw9/80sPf/NLD3/zSw9/8rkJf/K5CX/yuQl/8rkJf/H18s/x9fLP8fXyz/ + H18s/x9gLP8fYCz/H2As/x9gLP8gYS3/IGEt/yBhLf8gYS3/IGIu/yBiLv8gYi7/IGIu/2Ofb/9jn2// + Y59v/2Ofb/9jn2//Y59v/2Ofb/9jn2//Y59v/2Ofb/9jn2//Y59v/2Ofb/9jn2//Y59v/2Ofb/9ns7T/ + Z7O0/2eztP9ns7T/a8X3/2vF9/9rxff/a8X3/1mBav9ZgWr/WYFq/1mBav9XfF//V3xf/1d8X/9XfF// + /Pbx//z28f/89vH//Pbx/2KEaf9ihGn/YoRp/2KEaf9YfmD/WH5g/1h+YP9YfmD/WH9g/1h/YP9Yf2D/ + WH9g/1l/Yf9Zf2H/WX9h/1l/Yf9ZgGH/WYBh/1mAYf9ZgGH/WYFi/1mBYv9ZgWL/WYFi/6+/rf+vv63/ + r7+t/6+/rf+htJ7/obSe/6G0nv+htJ7/HlYq/x5WKv8eVir/HlYq/xxVJ/8cVSf/HFUn/xxVJ/8cVij/ + HFYo/xxWKP8cVij/HFco/xxXKP8cVyj/HFco/x1YKf8dWCn/HVgp/x1YKf8rYjX/K2I1/ytiNf8rYjX/ + +/Ps//vz7P/78+z/+/Ps/x5bKv8eWyr/Hlsq/x5bKv8gZj3/IGY9/yBmPf8gZj3/NLD3/zSw9/80sPf/ + NLD3/yuQl/8rkJf/K5CX/yuQl/8fXyz/H18s/x9fLP8fXyz/H2As/x9gLP8fYCz/H2As/yBhLf8gYS3/ + IGEt/yBhLf8gYi7/IGIu/yBiLv8gYi7/Y59v/2Ofb/9jn2//Y59v/2Ofb/9jn2//Y59v/2Ofb/9jn2// + Y59v/2Ofb/9jn2//Y59v/2Ofb/9jn2//Y59v/2eztP9ns7T/Z7O0/2eztP9rxff/a8X3/2vF9/9rxff/ + WYFq/1mBav9ZgWr/WYFq/1d8X/9XfF//V3xf/1d8X//89vH//Pbx//z28f/89vH/YoRp/2KEaf9ihGn/ + YoRp/1h+YP9YfmD/WH5g/1h+YP9Yf2D/WH9g/1h/YP9Yf2D/WX9h/1l/Yf9Zf2H/WX9h/1mAYf9ZgGH/ + WYBh/1mAYf9ZgWL/WYFi/1mBYv9ZgWL/r7+t/6+/rf+vv63/r7+t/6G0nv+htJ7/obSe/6G0nv8eVir/ + HlYq/x5WKv8eVir/HFUn/xxVJ/8cVSf/HFUn/xxWKP8cVij/HFYo/xxWKP8cVyj/HFco/xxXKP8cVyj/ + HVgp/x1YKf8dWCn/HVgp/ytiNf8rYjX/K2I1/ytiNf/78+z/+/Ps//vz7P/78+z/Hlsq/x5bKv8eWyr/ + Hlsq/yBmPf8gZj3/IGY9/yBmPf80sPf/NLD3/zSw9/80sPf/K5CX/yuQl/8rkJf/K5CX/x9fLP8fXyz/ + H18s/x9fLP8fYCz/H2As/x9gLP8fYCz/IGEt/yBhLf8gYS3/IGEt/yBiLv8gYi7/IGIu/yBiLv9no3P/ + Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9no3P/ + bb7X/22+1/9tvtf/bb7X/2y81/9svNf/bLzX/2y81/9bfmL/W35i/1t+Yv9bfmL/W39j/1t/Y/9bf2P/ + W39j//z48//8+PP//Pjz//z48/9mh2z/Zods/2aHbP9mh2z/XIFk/1yBZP9cgWT/XIFk/1yBZP9cgWT/ + XIFk/1yBZP9miG3/Zoht/2aIbf9miG3/sMCv/7DAr/+wwK//sMCv/7LCsf+ywrH/ssKx/7LCsf/Z3tT/ + 2d7U/9ne1P/Z3tT/2d7U/9ne1P/Z3tT/2d7U/6/Arf+vwK3/r8Ct/6/Arf+bspr/m7Ka/5uymv+bspr/ + KV80/ylfNP8pXzT/KV80/x1XKP8dVyj/HVco/x1XKP8dWCn/HVgp/x1YKf8dWCn/K2M2/ytjNv8rYzb/ + K2M2//v17v/79e7/+/Xu//v17v8eXCv/Hlwr/x5cK/8eXCv/Hl0r/x5dK/8eXSv/Hl0r/zGjy/8xo8v/ + MaPL/zGjy/8wosb/MKLG/zCixv8wosb/H2As/x9gLP8fYCz/H2As/yBhLf8gYS3/IGEt/yBhLf8gYi3/ + IGIt/yBiLf8gYi3/IGMu/yBjLv8gYy7/IGMu/2ejc/9no3P/Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9no3P/ + Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9tvtf/bb7X/22+1/9tvtf/bLzX/2y81/9svNf/ + bLzX/1t+Yv9bfmL/W35i/1t+Yv9bf2P/W39j/1t/Y/9bf2P//Pjz//z48//8+PP//Pjz/2aHbP9mh2z/ + Zods/2aHbP9cgWT/XIFk/1yBZP9cgWT/XIFk/1yBZP9cgWT/XIFk/2aIbf9miG3/Zoht/2aIbf+wwK// + sMCv/7DAr/+wwK//ssKx/7LCsf+ywrH/ssKx/9ne1P/Z3tT/2d7U/9ne1P/Z3tT/2d7U/9ne1P/Z3tT/ + r8Ct/6/Arf+vwK3/r8Ct/5uymv+bspr/m7Ka/5uymv8pXzT/KV80/ylfNP8pXzT/HVco/x1XKP8dVyj/ + HVco/x1YKf8dWCn/HVgp/x1YKf8rYzb/K2M2/ytjNv8rYzb/+/Xu//v17v/79e7/+/Xu/x5cK/8eXCv/ + Hlwr/x5cK/8eXSv/Hl0r/x5dK/8eXSv/MaPL/zGjy/8xo8v/MaPL/zCixv8wosb/MKLG/zCixv8fYCz/ + H2As/x9gLP8fYCz/IGEt/yBhLf8gYS3/IGEt/yBiLf8gYi3/IGIt/yBiLf8gYy7/IGMu/yBjLv8gYy7/ + Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9no3P/ + Z6Nz/22+1/9tvtf/bb7X/22+1/9svNf/bLzX/2y81/9svNf/W35i/1t+Yv9bfmL/W35i/1t/Y/9bf2P/ + W39j/1t/Y//8+PP//Pjz//z48//8+PP/Zods/2aHbP9mh2z/Zods/1yBZP9cgWT/XIFk/1yBZP9cgWT/ + XIFk/1yBZP9cgWT/Zoht/2aIbf9miG3/Zoht/7DAr/+wwK//sMCv/7DAr/+ywrH/ssKx/7LCsf+ywrH/ + 2d7U/9ne1P/Z3tT/2d7U/9ne1P/Z3tT/2d7U/9ne1P+vwK3/r8Ct/6/Arf+vwK3/m7Ka/5uymv+bspr/ + m7Ka/ylfNP8pXzT/KV80/ylfNP8dVyj/HVco/x1XKP8dVyj/HVgp/x1YKf8dWCn/HVgp/ytjNv8rYzb/ + K2M2/ytjNv/79e7/+/Xu//v17v/79e7/Hlwr/x5cK/8eXCv/Hlwr/x5dK/8eXSv/Hl0r/x5dK/8xo8v/ + MaPL/zGjy/8xo8v/MKLG/zCixv8wosb/MKLG/x9gLP8fYCz/H2As/x9gLP8gYS3/IGEt/yBhLf8gYS3/ + IGIt/yBiLf8gYi3/IGIt/yBjLv8gYy7/IGMu/yBjLv9no3P/Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9no3P/ + Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9no3P/bb7X/22+1/9tvtf/bb7X/2y81/9svNf/ + bLzX/2y81/9bfmL/W35i/1t+Yv9bfmL/W39j/1t/Y/9bf2P/W39j//z48//8+PP//Pjz//z48/9mh2z/ + Zods/2aHbP9mh2z/XIFk/1yBZP9cgWT/XIFk/1yBZP9cgWT/XIFk/1yBZP9miG3/Zoht/2aIbf9miG3/ + sMCv/7DAr/+wwK//sMCv/7LCsf+ywrH/ssKx/7LCsf/Z3tT/2d7U/9ne1P/Z3tT/2d7U/9ne1P/Z3tT/ + 2d7U/6/Arf+vwK3/r8Ct/6/Arf+bspr/m7Ka/5uymv+bspr/KV80/ylfNP8pXzT/KV80/x1XKP8dVyj/ + HVco/x1XKP8dWCn/HVgp/x1YKf8dWCn/K2M2/ytjNv8rYzb/K2M2//v17v/79e7/+/Xu//v17v8eXCv/ + Hlwr/x5cK/8eXCv/Hl0r/x5dK/8eXSv/Hl0r/zGjy/8xo8v/MaPL/zGjy/8wosb/MKLG/zCixv8wosb/ + H2As/x9gLP8fYCz/H2As/yBhLf8gYS3/IGEt/yBhLf8gYi3/IGIt/yBiLf8gYi3/IGMu/yBjLv8gYy7/ + IGMu/2qld/9qpXf/aqV3/2qld/9qpXf/aqV3/2qld/9qpXf/aqV3/2qld/9qpXf/aqV3/2qld/9qpXf/ + aqV3/2qld/9xxuz/ccbs/3HG7P9xxuz/bLO//2yzv/9ss7//bLO//16AZf9egGX/XoBl/16AZf9egWX/ + XoFl/16BZf9egWX//fn1//359f/9+fX//fn1/2iJb/9oiW//aIlv/2iJb/9eg2f/XoNn/16DZ/9eg2f/ + XoNn/16DZ/9eg2f/XoNn/2iKcP9oinD/aIpw/2iKcP+xwbH/scGx/7HBsf+xwbH/s8Oz/7PDs/+zw7P/ + s8Oz/9vg1v/b4Nb/2+DW/9vg1v/b4Nb/2+DW/9vg1v/b4Nb/tMS0/7TEtP+0xLT/tMS0/7LDsv+yw7L/ + ssOy/7LDsv9Sflz/Un5c/1J+XP9Sflz/IFos/yBaLP8gWiz/IFos/x1YKv8dWCr/HVgq/x1YKv8rYjb/ + K2I2/ytiNv8rYjb//Pbw//z28P/89vD//Pbw/x5bLP8eWyz/Hlss/x5bLP8eXCz/Hlws/x5cLP8eXCz/ + Lpiq/y6Yqv8umKr/Lpiq/zSt5f80reX/NK3l/zSt5f8fXy3/H18t/x9fLf8fXy3/H2Au/x9gLv8fYC7/ + H2Au/yBhLv8gYS7/IGEu/yBhLv8gYy//IGMv/yBjL/8gYy//aqV3/2qld/9qpXf/aqV3/2qld/9qpXf/ + aqV3/2qld/9qpXf/aqV3/2qld/9qpXf/aqV3/2qld/9qpXf/aqV3/3HG7P9xxuz/ccbs/3HG7P9ss7// + bLO//2yzv/9ss7//XoBl/16AZf9egGX/XoBl/16BZf9egWX/XoFl/16BZf/9+fX//fn1//359f/9+fX/ + aIlv/2iJb/9oiW//aIlv/16DZ/9eg2f/XoNn/16DZ/9eg2f/XoNn/16DZ/9eg2f/aIpw/2iKcP9oinD/ + aIpw/7HBsf+xwbH/scGx/7HBsf+zw7P/s8Oz/7PDs/+zw7P/2+DW/9vg1v/b4Nb/2+DW/9vg1v/b4Nb/ + 2+DW/9vg1v+0xLT/tMS0/7TEtP+0xLT/ssOy/7LDsv+yw7L/ssOy/1J+XP9Sflz/Un5c/1J+XP8gWiz/ + IFos/yBaLP8gWiz/HVgq/x1YKv8dWCr/HVgq/ytiNv8rYjb/K2I2/ytiNv/89vD//Pbw//z28P/89vD/ + Hlss/x5bLP8eWyz/Hlss/x5cLP8eXCz/Hlws/x5cLP8umKr/Lpiq/y6Yqv8umKr/NK3l/zSt5f80reX/ + NK3l/x9fLf8fXy3/H18t/x9fLf8fYC7/H2Au/x9gLv8fYC7/IGEu/yBhLv8gYS7/IGEu/yBjL/8gYy// + IGMv/yBjL/9qpXf/aqV3/2qld/9qpXf/aqV3/2qld/9qpXf/aqV3/2qld/9qpXf/aqV3/2qld/9qpXf/ + aqV3/2qld/9qpXf/ccbs/3HG7P9xxuz/ccbs/2yzv/9ss7//bLO//2yzv/9egGX/XoBl/16AZf9egGX/ + XoFl/16BZf9egWX/XoFl//359f/9+fX//fn1//359f9oiW//aIlv/2iJb/9oiW//XoNn/16DZ/9eg2f/ + XoNn/16DZ/9eg2f/XoNn/16DZ/9oinD/aIpw/2iKcP9oinD/scGx/7HBsf+xwbH/scGx/7PDs/+zw7P/ + s8Oz/7PDs//b4Nb/2+DW/9vg1v/b4Nb/2+DW/9vg1v/b4Nb/2+DW/7TEtP+0xLT/tMS0/7TEtP+yw7L/ + ssOy/7LDsv+yw7L/Un5c/1J+XP9Sflz/Un5c/yBaLP8gWiz/IFos/yBaLP8dWCr/HVgq/x1YKv8dWCr/ + K2I2/ytiNv8rYjb/K2I2//z28P/89vD//Pbw//z28P8eWyz/Hlss/x5bLP8eWyz/Hlws/x5cLP8eXCz/ + Hlws/y6Yqv8umKr/Lpiq/y6Yqv80reX/NK3l/zSt5f80reX/H18t/x9fLf8fXy3/H18t/x9gLv8fYC7/ + H2Au/x9gLv8gYS7/IGEu/yBhLv8gYS7/IGMv/yBjL/8gYy//IGMv/2qld/9qpXf/aqV3/2qld/9qpXf/ + aqV3/2qld/9qpXf/aqV3/2qld/9qpXf/aqV3/2qld/9qpXf/aqV3/2qld/9xxuz/ccbs/3HG7P9xxuz/ + bLO//2yzv/9ss7//bLO//16AZf9egGX/XoBl/16AZf9egWX/XoFl/16BZf9egWX//fn1//359f/9+fX/ + /fn1/2iJb/9oiW//aIlv/2iJb/9eg2f/XoNn/16DZ/9eg2f/XoNn/16DZ/9eg2f/XoNn/2iKcP9oinD/ + aIpw/2iKcP+xwbH/scGx/7HBsf+xwbH/s8Oz/7PDs/+zw7P/s8Oz/9vg1v/b4Nb/2+DW/9vg1v/b4Nb/ + 2+DW/9vg1v/b4Nb/tMS0/7TEtP+0xLT/tMS0/7LDsv+yw7L/ssOy/7LDsv9Sflz/Un5c/1J+XP9Sflz/ + IFos/yBaLP8gWiz/IFos/x1YKv8dWCr/HVgq/x1YKv8rYjb/K2I2/ytiNv8rYjb//Pbw//z28P/89vD/ + /Pbw/x5bLP8eWyz/Hlss/x5bLP8eXCz/Hlws/x5cLP8eXCz/Lpiq/y6Yqv8umKr/Lpiq/zSt5f80reX/ + NK3l/zSt5f8fXy3/H18t/x9fLf8fXy3/H2Au/x9gLv8fYC7/H2Au/yBhLv8gYS7/IGEu/yBhLv8gYy// + IGMv/yBjL/8gYy//bah6/22oev9tqHr/bah6/22oev9tqHr/bah6/22oev9tqHr/bah6/22oev9tqHr/ + bal//22pf/9tqX//bal//3TM+/90zPv/dMz7/3TM+/9rqaj/a6mo/2upqP9rqaj/YIJo/2CCaP9ggmj/ + YIJo/2CDaP9gg2j/YINo/2CDaP/9+vb//fr2//369v/9+vb/a4ty/2uLcv9ri3L/a4ty/2GFaf9hhWn/ + YYVp/2GFaf9ihmn/YoZp/2KGaf9ihmn/YoZq/2KGav9ihmr/YoZq/2KHav9ih2r/Yodq/2KHav9jiGv/ + Y4hr/2OIa/9jiGv/tcW1/7XFtf+1xbX/tcW1/7XFtv+1xbb/tcW2/7XFtv9jimv/Y4pr/2OKa/9jimv/ + Y4ps/2OKbP9jimz/Y4ps/2OLbP9ji2z/Y4ts/2OLbP9ahGT/WoRk/1qEZP9ahGT/LGM4/yxjOP8sYzj/ + LGM4/ytiN/8rYjf/K2I3/ytiN//89/L//Pfy//z38v/89/L/Hlws/x5cLP8eXCz/Hlws/x5dLP8eXSz/ + Hl0s/x5dLP8rioj/K4qI/yuKiP8rioj/NbT5/zW0+f81tPn/NbT5/yFkNf8hZDX/IWQ1/yFkNf8gYS7/ + IGEu/yBhLv8gYS7/IGIv/yBiL/8gYi//IGIv/yFjL/8hYy//IWMv/yFjL/9tqHr/bah6/22oev9tqHr/ + bah6/22oev9tqHr/bah6/22oev9tqHr/bah6/22oev9tqX//bal//22pf/9tqX//dMz7/3TM+/90zPv/ + dMz7/2upqP9rqaj/a6mo/2upqP9ggmj/YIJo/2CCaP9ggmj/YINo/2CDaP9gg2j/YINo//369v/9+vb/ + /fr2//369v9ri3L/a4ty/2uLcv9ri3L/YYVp/2GFaf9hhWn/YYVp/2KGaf9ihmn/YoZp/2KGaf9ihmr/ + YoZq/2KGav9ihmr/Yodq/2KHav9ih2r/Yodq/2OIa/9jiGv/Y4hr/2OIa/+1xbX/tcW1/7XFtf+1xbX/ + tcW2/7XFtv+1xbb/tcW2/2OKa/9jimv/Y4pr/2OKa/9jimz/Y4ps/2OKbP9jimz/Y4ts/2OLbP9ji2z/ + Y4ts/1qEZP9ahGT/WoRk/1qEZP8sYzj/LGM4/yxjOP8sYzj/K2I3/ytiN/8rYjf/K2I3//z38v/89/L/ + /Pfy//z38v8eXCz/Hlws/x5cLP8eXCz/Hl0s/x5dLP8eXSz/Hl0s/yuKiP8rioj/K4qI/yuKiP81tPn/ + NbT5/zW0+f81tPn/IWQ1/yFkNf8hZDX/IWQ1/yBhLv8gYS7/IGEu/yBhLv8gYi//IGIv/yBiL/8gYi// + IWMv/yFjL/8hYy//IWMv/22oev9tqHr/bah6/22oev9tqHr/bah6/22oev9tqHr/bah6/22oev9tqHr/ + bah6/22pf/9tqX//bal//22pf/90zPv/dMz7/3TM+/90zPv/a6mo/2upqP9rqaj/a6mo/2CCaP9ggmj/ + YIJo/2CCaP9gg2j/YINo/2CDaP9gg2j//fr2//369v/9+vb//fr2/2uLcv9ri3L/a4ty/2uLcv9hhWn/ + YYVp/2GFaf9hhWn/YoZp/2KGaf9ihmn/YoZp/2KGav9ihmr/YoZq/2KGav9ih2r/Yodq/2KHav9ih2r/ + Y4hr/2OIa/9jiGv/Y4hr/7XFtf+1xbX/tcW1/7XFtf+1xbb/tcW2/7XFtv+1xbb/Y4pr/2OKa/9jimv/ + Y4pr/2OKbP9jimz/Y4ps/2OKbP9ji2z/Y4ts/2OLbP9ji2z/WoRk/1qEZP9ahGT/WoRk/yxjOP8sYzj/ + LGM4/yxjOP8rYjf/K2I3/ytiN/8rYjf//Pfy//z38v/89/L//Pfy/x5cLP8eXCz/Hlws/x5cLP8eXSz/ + Hl0s/x5dLP8eXSz/K4qI/yuKiP8rioj/K4qI/zW0+f81tPn/NbT5/zW0+f8hZDX/IWQ1/yFkNf8hZDX/ + IGEu/yBhLv8gYS7/IGEu/yBiL/8gYi//IGIv/yBiL/8hYy//IWMv/yFjL/8hYy//bah6/22oev9tqHr/ + bah6/22oev9tqHr/bah6/22oev9tqHr/bah6/22oev9tqHr/bal//22pf/9tqX//bal//3TM+/90zPv/ + dMz7/3TM+/9rqaj/a6mo/2upqP9rqaj/YIJo/2CCaP9ggmj/YIJo/2CDaP9gg2j/YINo/2CDaP/9+vb/ + /fr2//369v/9+vb/a4ty/2uLcv9ri3L/a4ty/2GFaf9hhWn/YYVp/2GFaf9ihmn/YoZp/2KGaf9ihmn/ + YoZq/2KGav9ihmr/YoZq/2KHav9ih2r/Yodq/2KHav9jiGv/Y4hr/2OIa/9jiGv/tcW1/7XFtf+1xbX/ + tcW1/7XFtv+1xbb/tcW2/7XFtv9jimv/Y4pr/2OKa/9jimv/Y4ps/2OKbP9jimz/Y4ps/2OLbP9ji2z/ + Y4ts/2OLbP9ahGT/WoRk/1qEZP9ahGT/LGM4/yxjOP8sYzj/LGM4/ytiN/8rYjf/K2I3/ytiN//89/L/ + /Pfy//z38v/89/L/Hlws/x5cLP8eXCz/Hlws/x5dLP8eXSz/Hl0s/x5dLP8rioj/K4qI/yuKiP8rioj/ + NbT5/zW0+f81tPn/NbT5/yFkNf8hZDX/IWQ1/yFkNf8gYS7/IGEu/yBhLv8gYS7/IGIv/yBiL/8gYi// + IGIv/yFjL/8hYy//IWMv/yFjL/9xq37/cat+/3Grfv9xq37/cat+/3Grfv9xq37/cat+/3Grfv9xq37/ + cat+/3Grfv9yr4z/cq+M/3KvjP9yr4z/eM37/3jN+/94zfv/eM37/22loP9tpaD/baWg/22loP9khGv/ + ZIRr/2SEa/9khGv/ZIVr/2SFa/9khWv/ZIVr//36+P/9+vj//fr4//36+P9ujnX/bo51/26Odf9ujnX/ + ZYht/2WIbf9liG3/ZYht/2WIbf9liG3/ZYht/2WIbf9liW3/ZYlt/2WJbf9liW3/Zopt/2aKbf9mim3/ + Zopt/2aKbv9mim7/Zopu/2aKbv+1xbb/tcW2/7XFtv+1xbb/tcW2/7XFtv+1xbb/tcW2/2eMb/9njG// + Z4xv/2eMb/9njW//Z41v/2eNb/9njW//Z45v/2eOb/9njm//Z45v/2eOcP9njnD/Z45w/2eOcP9mjm7/ + Zo5u/2aObv9mjm7/THtW/0x7Vv9Me1b/THtW//z49P/8+PT//Pj0//z49P8eWyz/Hlss/x5bLP8eWyz/ + H10s/x9dLP8fXSz/H10s/yqDd/8qg3f/KoN3/yqDd/82tfn/NrX5/za1+f82tfn/I21H/yNtR/8jbUf/ + I21H/yBhLv8gYS7/IGEu/yBhLv8hYi//IWIv/yFiL/8hYi//IWMw/yFjMP8hYzD/IWMw/3Grfv9xq37/ + cat+/3Grfv9xq37/cat+/3Grfv9xq37/cat+/3Grfv9xq37/cat+/3KvjP9yr4z/cq+M/3KvjP94zfv/ + eM37/3jN+/94zfv/baWg/22loP9tpaD/baWg/2SEa/9khGv/ZIRr/2SEa/9khWv/ZIVr/2SFa/9khWv/ + /fr4//36+P/9+vj//fr4/26Odf9ujnX/bo51/26Odf9liG3/ZYht/2WIbf9liG3/ZYht/2WIbf9liG3/ + ZYht/2WJbf9liW3/ZYlt/2WJbf9mim3/Zopt/2aKbf9mim3/Zopu/2aKbv9mim7/Zopu/7XFtv+1xbb/ + tcW2/7XFtv+1xbb/tcW2/7XFtv+1xbb/Z4xv/2eMb/9njG//Z4xv/2eNb/9njW//Z41v/2eNb/9njm// + Z45v/2eOb/9njm//Z45w/2eOcP9njnD/Z45w/2aObv9mjm7/Zo5u/2aObv9Me1b/THtW/0x7Vv9Me1b/ + /Pj0//z49P/8+PT//Pj0/x5bLP8eWyz/Hlss/x5bLP8fXSz/H10s/x9dLP8fXSz/KoN3/yqDd/8qg3f/ + KoN3/za1+f82tfn/NrX5/za1+f8jbUf/I21H/yNtR/8jbUf/IGEu/yBhLv8gYS7/IGEu/yFiL/8hYi// + IWIv/yFiL/8hYzD/IWMw/yFjMP8hYzD/cat+/3Grfv9xq37/cat+/3Grfv9xq37/cat+/3Grfv9xq37/ + cat+/3Grfv9xq37/cq+M/3KvjP9yr4z/cq+M/3jN+/94zfv/eM37/3jN+/9tpaD/baWg/22loP9tpaD/ + ZIRr/2SEa/9khGv/ZIRr/2SFa/9khWv/ZIVr/2SFa//9+vj//fr4//36+P/9+vj/bo51/26Odf9ujnX/ + bo51/2WIbf9liG3/ZYht/2WIbf9liG3/ZYht/2WIbf9liG3/ZYlt/2WJbf9liW3/ZYlt/2aKbf9mim3/ + Zopt/2aKbf9mim7/Zopu/2aKbv9mim7/tcW2/7XFtv+1xbb/tcW2/7XFtv+1xbb/tcW2/7XFtv9njG// + Z4xv/2eMb/9njG//Z41v/2eNb/9njW//Z41v/2eOb/9njm//Z45v/2eOb/9njnD/Z45w/2eOcP9njnD/ + Zo5u/2aObv9mjm7/Zo5u/0x7Vv9Me1b/THtW/0x7Vv/8+PT//Pj0//z49P/8+PT/Hlss/x5bLP8eWyz/ + Hlss/x9dLP8fXSz/H10s/x9dLP8qg3f/KoN3/yqDd/8qg3f/NrX5/za1+f82tfn/NrX5/yNtR/8jbUf/ + I21H/yNtR/8gYS7/IGEu/yBhLv8gYS7/IWIv/yFiL/8hYi//IWIv/yFjMP8hYzD/IWMw/yFjMP9xq37/ + cat+/3Grfv9xq37/cat+/3Grfv9xq37/cat+/3Grfv9xq37/cat+/3Grfv9yr4z/cq+M/3KvjP9yr4z/ + eM37/3jN+/94zfv/eM37/22loP9tpaD/baWg/22loP9khGv/ZIRr/2SEa/9khGv/ZIVr/2SFa/9khWv/ + ZIVr//36+P/9+vj//fr4//36+P9ujnX/bo51/26Odf9ujnX/ZYht/2WIbf9liG3/ZYht/2WIbf9liG3/ + ZYht/2WIbf9liW3/ZYlt/2WJbf9liW3/Zopt/2aKbf9mim3/Zopt/2aKbv9mim7/Zopu/2aKbv+1xbb/ + tcW2/7XFtv+1xbb/tcW2/7XFtv+1xbb/tcW2/2eMb/9njG//Z4xv/2eMb/9njW//Z41v/2eNb/9njW// + Z45v/2eOb/9njm//Z45v/2eOcP9njnD/Z45w/2eOcP9mjm7/Zo5u/2aObv9mjm7/THtW/0x7Vv9Me1b/ + THtW//z49P/8+PT//Pj0//z49P8eWyz/Hlss/x5bLP8eWyz/H10s/x9dLP8fXSz/H10s/yqDd/8qg3f/ + KoN3/yqDd/82tfn/NrX5/za1+f82tfn/I21H/yNtR/8jbUf/I21H/yBhLv8gYS7/IGEu/yBhLv8hYi// + IWIv/yFiL/8hYi//IWMw/yFjMP8hYzD/IWMw/3Stgf90rYH/dK2B/3Stgf90rYH/dK2B/3Stgf90rYH/ + dK2B/3Stgf90rYH/dK2B/3Wyk/91spP/dbKT/3Wyk/97z/v/e8/7/3vP+/97z/v/cKWe/3Clnv9wpZ7/ + cKWe/2eGbv9nhm7/Z4Zu/2eGbv9nh2//Z4dv/2eHb/9nh2///fr4//36+P/9+vj//fr4/3OSef9zknn/ + c5J5/3OSef9oim//aIpv/2iKb/9oim//aIpw/2iKcP9oinD/aIpw/2mLcf9pi3H/aYtx/2mLcf9pjHH/ + aYxx/2mMcf9pjHH/aYxx/2mMcf9pjHH/aYxx/3KUef9ylHn/cpR5/3KUef9ylHr/cpR6/3KUev9ylHr/ + aY5y/2mOcv9pjnL/aY5y/2qPc/9qj3P/ao9z/2qPc/9qkHP/apBz/2qQc/9qkHP/apBz/2qQc/9qkHP/ + apBz/2uRc/9rkXP/a5Fz/2uRc/91mX3/dZl9/3WZff91mX3//fr3//369//9+vf//fr3/yNeMP8jXjD/ + I14w/yNeMP8fXC3/H1wt/x9cLf8fXC3/KYNz/ymDc/8pg3P/KYNz/za2+f82tvn/Nrb5/za2+f8lcU3/ + JXFN/yVxTf8lcU3/IWEv/yFhL/8hYS//IWEv/yFiMP8hYjD/IWIw/yFiMP8hZDH/IWQx/yFkMf8hZDH/ + dK2B/3Stgf90rYH/dK2B/3Stgf90rYH/dK2B/3Stgf90rYH/dK2B/3Stgf90rYH/dbKT/3Wyk/91spP/ + dbKT/3vP+/97z/v/e8/7/3vP+/9wpZ7/cKWe/3Clnv9wpZ7/Z4Zu/2eGbv9nhm7/Z4Zu/2eHb/9nh2// + Z4dv/2eHb//9+vj//fr4//36+P/9+vj/c5J5/3OSef9zknn/c5J5/2iKb/9oim//aIpv/2iKb/9oinD/ + aIpw/2iKcP9oinD/aYtx/2mLcf9pi3H/aYtx/2mMcf9pjHH/aYxx/2mMcf9pjHH/aYxx/2mMcf9pjHH/ + cpR5/3KUef9ylHn/cpR5/3KUev9ylHr/cpR6/3KUev9pjnL/aY5y/2mOcv9pjnL/ao9z/2qPc/9qj3P/ + ao9z/2qQc/9qkHP/apBz/2qQc/9qkHP/apBz/2qQc/9qkHP/a5Fz/2uRc/9rkXP/a5Fz/3WZff91mX3/ + dZl9/3WZff/9+vf//fr3//369//9+vf/I14w/yNeMP8jXjD/I14w/x9cLf8fXC3/H1wt/x9cLf8pg3P/ + KYNz/ymDc/8pg3P/Nrb5/za2+f82tvn/Nrb5/yVxTf8lcU3/JXFN/yVxTf8hYS//IWEv/yFhL/8hYS// + IWIw/yFiMP8hYjD/IWIw/yFkMf8hZDH/IWQx/yFkMf90rYH/dK2B/3Stgf90rYH/dK2B/3Stgf90rYH/ + dK2B/3Stgf90rYH/dK2B/3Stgf91spP/dbKT/3Wyk/91spP/e8/7/3vP+/97z/v/e8/7/3Clnv9wpZ7/ + cKWe/3Clnv9nhm7/Z4Zu/2eGbv9nhm7/Z4dv/2eHb/9nh2//Z4dv//36+P/9+vj//fr4//36+P9zknn/ + c5J5/3OSef9zknn/aIpv/2iKb/9oim//aIpv/2iKcP9oinD/aIpw/2iKcP9pi3H/aYtx/2mLcf9pi3H/ + aYxx/2mMcf9pjHH/aYxx/2mMcf9pjHH/aYxx/2mMcf9ylHn/cpR5/3KUef9ylHn/cpR6/3KUev9ylHr/ + cpR6/2mOcv9pjnL/aY5y/2mOcv9qj3P/ao9z/2qPc/9qj3P/apBz/2qQc/9qkHP/apBz/2qQc/9qkHP/ + apBz/2qQc/9rkXP/a5Fz/2uRc/9rkXP/dZl9/3WZff91mX3/dZl9//369//9+vf//fr3//369/8jXjD/ + I14w/yNeMP8jXjD/H1wt/x9cLf8fXC3/H1wt/ymDc/8pg3P/KYNz/ymDc/82tvn/Nrb5/za2+f82tvn/ + JXFN/yVxTf8lcU3/JXFN/yFhL/8hYS//IWEv/yFhL/8hYjD/IWIw/yFiMP8hYjD/IWQx/yFkMf8hZDH/ + IWQx/3Stgf90rYH/dK2B/3Stgf90rYH/dK2B/3Stgf90rYH/dK2B/3Stgf90rYH/dK2B/3Wyk/91spP/ + dbKT/3Wyk/97z/v/e8/7/3vP+/97z/v/cKWe/3Clnv9wpZ7/cKWe/2eGbv9nhm7/Z4Zu/2eGbv9nh2// + Z4dv/2eHb/9nh2///fr4//36+P/9+vj//fr4/3OSef9zknn/c5J5/3OSef9oim//aIpv/2iKb/9oim// + aIpw/2iKcP9oinD/aIpw/2mLcf9pi3H/aYtx/2mLcf9pjHH/aYxx/2mMcf9pjHH/aYxx/2mMcf9pjHH/ + aYxx/3KUef9ylHn/cpR5/3KUef9ylHr/cpR6/3KUev9ylHr/aY5y/2mOcv9pjnL/aY5y/2qPc/9qj3P/ + ao9z/2qPc/9qkHP/apBz/2qQc/9qkHP/apBz/2qQc/9qkHP/apBz/2uRc/9rkXP/a5Fz/2uRc/91mX3/ + dZl9/3WZff91mX3//fr3//369//9+vf//fr3/yNeMP8jXjD/I14w/yNeMP8fXC3/H1wt/x9cLf8fXC3/ + KYNz/ymDc/8pg3P/KYNz/za2+f82tvn/Nrb5/za2+f8lcU3/JXFN/yVxTf8lcU3/IWEv/yFhL/8hYS// + IWEv/yFiMP8hYjD/IWIw/yFiMP8hZDH/IWQx/yFkMf8hZDH/d6+E/3evhP93r4T/d6+E/3evhP93r4T/ + d6+E/3evhP93r4T/d6+E/3evhP93r4T/eLWX/3i1l/94tZf/eLWX/37Q+/9+0Pv/ftD7/37Q+/9ypZ3/ + cqWd/3Klnf9ypZ3/aolx/2qJcf9qiXH/aolx/2qJcf9qiXH/aolx/2qJcf/Z39j/2d/Y/9nf2P/Z39j/ + 4ebg/+Hm4P/h5uD/4ebg/9je1v/Y3tb/2N7W/9je1v/Y3tb/2N7W/9je1v/Y3tb/2N/W/9jf1v/Y39b/ + 2N/W/9jf1v/Y39b/2N/W/9jf1v/Y39f/2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/ + 2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/2N/X/9jg1//Y4Nf/2ODX/9jg1//Y4Nf/ + 2ODX/9jg1//Y4Nf/2ODX/9jg1//Y4Nf/2ODX/+Hn4f/h5+H/4efh/+Hn4f/Z4tn/2eLZ/9ni2f/Z4tn/ + X4pp/1+Kaf9fimn/X4pp/yZhNP8mYTT/JmE0/yZhNP8pgG3/KYBt/ymAbf8pgG3/N7f5/ze3+f83t/n/ + N7f5/yZyUv8mclL/JnJS/yZyUv8hYTD/IWEw/yFhMP8hYTD/IWIw/yFiMP8hYjD/IWIw/yJjMf8iYzH/ + ImMx/yJjMf93r4T/d6+E/3evhP93r4T/d6+E/3evhP93r4T/d6+E/3evhP93r4T/d6+E/3evhP94tZf/ + eLWX/3i1l/94tZf/ftD7/37Q+/9+0Pv/ftD7/3Klnf9ypZ3/cqWd/3Klnf9qiXH/aolx/2qJcf9qiXH/ + aolx/2qJcf9qiXH/aolx/9nf2P/Z39j/2d/Y/9nf2P/h5uD/4ebg/+Hm4P/h5uD/2N7W/9je1v/Y3tb/ + 2N7W/9je1v/Y3tb/2N7W/9je1v/Y39b/2N/W/9jf1v/Y39b/2N/W/9jf1v/Y39b/2N/W/9jf1//Y39f/ + 2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/ + 2N/X/9jf1//Y39f/2ODX/9jg1//Y4Nf/2ODX/9jg1//Y4Nf/2ODX/9jg1//Y4Nf/2ODX/9jg1//Y4Nf/ + 4efh/+Hn4f/h5+H/4efh/9ni2f/Z4tn/2eLZ/9ni2f9fimn/X4pp/1+Kaf9fimn/JmE0/yZhNP8mYTT/ + JmE0/ymAbf8pgG3/KYBt/ymAbf83t/n/N7f5/ze3+f83t/n/JnJS/yZyUv8mclL/JnJS/yFhMP8hYTD/ + IWEw/yFhMP8hYjD/IWIw/yFiMP8hYjD/ImMx/yJjMf8iYzH/ImMx/3evhP93r4T/d6+E/3evhP93r4T/ + d6+E/3evhP93r4T/d6+E/3evhP93r4T/d6+E/3i1l/94tZf/eLWX/3i1l/9+0Pv/ftD7/37Q+/9+0Pv/ + cqWd/3Klnf9ypZ3/cqWd/2qJcf9qiXH/aolx/2qJcf9qiXH/aolx/2qJcf9qiXH/2d/Y/9nf2P/Z39j/ + 2d/Y/+Hm4P/h5uD/4ebg/+Hm4P/Y3tb/2N7W/9je1v/Y3tb/2N7W/9je1v/Y3tb/2N7W/9jf1v/Y39b/ + 2N/W/9jf1v/Y39b/2N/W/9jf1v/Y39b/2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/ + 2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/2N/X/9jf1//Y4Nf/2ODX/9jg1//Y4Nf/ + 2ODX/9jg1//Y4Nf/2ODX/9jg1//Y4Nf/2ODX/9jg1//h5+H/4efh/+Hn4f/h5+H/2eLZ/9ni2f/Z4tn/ + 2eLZ/1+Kaf9fimn/X4pp/1+Kaf8mYTT/JmE0/yZhNP8mYTT/KYBt/ymAbf8pgG3/KYBt/ze3+f83t/n/ + N7f5/ze3+f8mclL/JnJS/yZyUv8mclL/IWEw/yFhMP8hYTD/IWEw/yFiMP8hYjD/IWIw/yFiMP8iYzH/ + ImMx/yJjMf8iYzH/d6+E/3evhP93r4T/d6+E/3evhP93r4T/d6+E/3evhP93r4T/d6+E/3evhP93r4T/ + eLWX/3i1l/94tZf/eLWX/37Q+/9+0Pv/ftD7/37Q+/9ypZ3/cqWd/3Klnf9ypZ3/aolx/2qJcf9qiXH/ + aolx/2qJcf9qiXH/aolx/2qJcf/Z39j/2d/Y/9nf2P/Z39j/4ebg/+Hm4P/h5uD/4ebg/9je1v/Y3tb/ + 2N7W/9je1v/Y3tb/2N7W/9je1v/Y3tb/2N/W/9jf1v/Y39b/2N/W/9jf1v/Y39b/2N/W/9jf1v/Y39f/ + 2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/ + 2N/X/9jf1//Y39f/2N/X/9jg1//Y4Nf/2ODX/9jg1//Y4Nf/2ODX/9jg1//Y4Nf/2ODX/9jg1//Y4Nf/ + 2ODX/+Hn4f/h5+H/4efh/+Hn4f/Z4tn/2eLZ/9ni2f/Z4tn/X4pp/1+Kaf9fimn/X4pp/yZhNP8mYTT/ + JmE0/yZhNP8pgG3/KYBt/ymAbf8pgG3/N7f5/ze3+f83t/n/N7f5/yZyUv8mclL/JnJS/yZyUv8hYTD/ + IWEw/yFhMP8hYTD/IWIw/yFiMP8hYjD/IWIw/yJjMf8iYzH/ImMx/yJjMf96soj/erKI/3qyiP96soj/ + erKI/3qyiP96soj/erKI/3qyiP96soj/erKI/3qyiP97uJ3/e7id/3u4nf97uJ3/gNL7/4DS+/+A0vv/ + gNL7/3Olm/9zpZv/c6Wb/3Olm/9si3T/bIt0/2yLdP9si3T/bYt1/22Ldf9ti3X/bYt1/3KQev9ykHr/ + cpB6/3KQev+Yrp3/mK6d/5iunf+Yrp3/nbKh/52yof+dsqH/nbKh/7fGuf+3xrn/t8a5/7fGuf/r7un/ + 6+7p/+vu6f/r7un/nrSi/560ov+etKL/nrSi/560ov+etKL/nrSi/560ov+etaL/nrWi/561ov+etaL/ + nrWj/561o/+etaP/nrWj/561o/+etaP/nrWj/561o/+etqT/nrak/562pP+etqT/6+7q/+vu6v/r7ur/ + 6+7q/7fJu/+3ybv/t8m7/7fJu/+ft6T/n7ek/5+3pP+ft6T/mrSg/5q0oP+atKD/mrSg/3Wafv91mn7/ + dZp+/3Wafv9xl3r/cZd6/3GXev9xl3r/ZpBw/2aQcP9mkHD/ZpBw/zWFcP81hXD/NYVw/zWFcP83uPn/ + N7j5/ze4+f83uPn/J3ZY/yd2WP8ndlj/J3ZY/yFhMf8hYTH/IWEx/yFhMf8hYjH/IWIx/yFiMf8hYjH/ + ImYz/yJmM/8iZjP/ImYz/3qyiP96soj/erKI/3qyiP96soj/erKI/3qyiP96soj/erKI/3qyiP96soj/ + erKI/3u4nf97uJ3/e7id/3u4nf+A0vv/gNL7/4DS+/+A0vv/c6Wb/3Olm/9zpZv/c6Wb/2yLdP9si3T/ + bIt0/2yLdP9ti3X/bYt1/22Ldf9ti3X/cpB6/3KQev9ykHr/cpB6/5iunf+Yrp3/mK6d/5iunf+dsqH/ + nbKh/52yof+dsqH/t8a5/7fGuf+3xrn/t8a5/+vu6f/r7un/6+7p/+vu6f+etKL/nrSi/560ov+etKL/ + nrSi/560ov+etKL/nrSi/561ov+etaL/nrWi/561ov+etaP/nrWj/561o/+etaP/nrWj/561o/+etaP/ + nrWj/562pP+etqT/nrak/562pP/r7ur/6+7q/+vu6v/r7ur/t8m7/7fJu/+3ybv/t8m7/5+3pP+ft6T/ + n7ek/5+3pP+atKD/mrSg/5q0oP+atKD/dZp+/3Wafv91mn7/dZp+/3GXev9xl3r/cZd6/3GXev9mkHD/ + ZpBw/2aQcP9mkHD/NYVw/zWFcP81hXD/NYVw/ze4+f83uPn/N7j5/ze4+f8ndlj/J3ZY/yd2WP8ndlj/ + IWEx/yFhMf8hYTH/IWEx/yFiMf8hYjH/IWIx/yFiMf8iZjP/ImYz/yJmM/8iZjP/erKI/3qyiP96soj/ + erKI/3qyiP96soj/erKI/3qyiP96soj/erKI/3qyiP96soj/e7id/3u4nf97uJ3/e7id/4DS+/+A0vv/ + gNL7/4DS+/9zpZv/c6Wb/3Olm/9zpZv/bIt0/2yLdP9si3T/bIt0/22Ldf9ti3X/bYt1/22Ldf9ykHr/ + cpB6/3KQev9ykHr/mK6d/5iunf+Yrp3/mK6d/52yof+dsqH/nbKh/52yof+3xrn/t8a5/7fGuf+3xrn/ + 6+7p/+vu6f/r7un/6+7p/560ov+etKL/nrSi/560ov+etKL/nrSi/560ov+etKL/nrWi/561ov+etaL/ + nrWi/561o/+etaP/nrWj/561o/+etaP/nrWj/561o/+etaP/nrak/562pP+etqT/nrak/+vu6v/r7ur/ + 6+7q/+vu6v+3ybv/t8m7/7fJu/+3ybv/n7ek/5+3pP+ft6T/n7ek/5q0oP+atKD/mrSg/5q0oP91mn7/ + dZp+/3Wafv91mn7/cZd6/3GXev9xl3r/cZd6/2aQcP9mkHD/ZpBw/2aQcP81hXD/NYVw/zWFcP81hXD/ + N7j5/ze4+f83uPn/N7j5/yd2WP8ndlj/J3ZY/yd2WP8hYTH/IWEx/yFhMf8hYTH/IWIx/yFiMf8hYjH/ + IWIx/yJmM/8iZjP/ImYz/yJmM/96soj/erKI/3qyiP96soj/erKI/3qyiP96soj/erKI/3qyiP96soj/ + erKI/3qyiP97uJ3/e7id/3u4nf97uJ3/gNL7/4DS+/+A0vv/gNL7/3Olm/9zpZv/c6Wb/3Olm/9si3T/ + bIt0/2yLdP9si3T/bYt1/22Ldf9ti3X/bYt1/3KQev9ykHr/cpB6/3KQev+Yrp3/mK6d/5iunf+Yrp3/ + nbKh/52yof+dsqH/nbKh/7fGuf+3xrn/t8a5/7fGuf/r7un/6+7p/+vu6f/r7un/nrSi/560ov+etKL/ + nrSi/560ov+etKL/nrSi/560ov+etaL/nrWi/561ov+etaL/nrWj/561o/+etaP/nrWj/561o/+etaP/ + nrWj/561o/+etqT/nrak/562pP+etqT/6+7q/+vu6v/r7ur/6+7q/7fJu/+3ybv/t8m7/7fJu/+ft6T/ + n7ek/5+3pP+ft6T/mrSg/5q0oP+atKD/mrSg/3Wafv91mn7/dZp+/3Wafv9xl3r/cZd6/3GXev9xl3r/ + ZpBw/2aQcP9mkHD/ZpBw/zWFcP81hXD/NYVw/zWFcP83uPn/N7j5/ze4+f83uPn/J3ZY/yd2WP8ndlj/ + J3ZY/yFhMf8hYTH/IWEx/yFhMf8hYjH/IWIx/yFiMf8hYjH/ImYz/yJmM/8iZjP/ImYz/361i/9+tYv/ + frWL/361i/9+tYv/frWL/361i/9+tYv/frWL/361i/9+tYv/frWL/3+7o/9/u6P/f7uj/3+7o/+E0/v/ + hNP7/4TT+/+E0/v/d6Wa/3elmv93pZr/d6Wa/3CNd/9wjXf/cI13/3CNd/9wjnj/cI54/3COeP9wjnj/ + cI94/3CPeP9wj3j/cI94/3CPef9wj3n/cI95/3CPef9xkHn/cZB5/3GQef9xkHn/kamX/5Gpl/+RqZf/ + kamX/+zw7P/s8Oz/7PDs/+zw7P9yknr/cpJ6/3KSev9yknr/cpN6/3KTev9yk3r/cpN6/3KUev9ylHr/ + cpR6/3KUev9ylHv/cpR7/3KUe/9ylHv/c5V7/3OVe/9zlXv/c5V7/3OWfP9zlnz/c5Z8/3OWfP/s8Oz/ + 7PDs/+zw7P/s8Oz/k66Z/5Oumf+Trpn/k66Z/3SYfP90mHz/dJh8/3SYfP90mH3/dJh9/3SYff90mH3/ + dJl9/3SZff90mX3/dJl9/3SZfv90mX7/dJl+/3SZfv90mn7/dJp+/3Safv90mn7/c6mZ/3Opmf9zqZn/ + c6mZ/0S8+P9EvPj/RLz4/0S8+P8oeF3/KHhd/yh4Xf8oeF3/IWEx/yFhMf8hYTH/IWEx/yJlM/8iZTP/ + ImUz/yJlM/8sgEH/LIBB/yyAQf8sgEH/frWL/361i/9+tYv/frWL/361i/9+tYv/frWL/361i/9+tYv/ + frWL/361i/9+tYv/f7uj/3+7o/9/u6P/f7uj/4TT+/+E0/v/hNP7/4TT+/93pZr/d6Wa/3elmv93pZr/ + cI13/3CNd/9wjXf/cI13/3COeP9wjnj/cI54/3COeP9wj3j/cI94/3CPeP9wj3j/cI95/3CPef9wj3n/ + cI95/3GQef9xkHn/cZB5/3GQef+RqZf/kamX/5Gpl/+RqZf/7PDs/+zw7P/s8Oz/7PDs/3KSev9yknr/ + cpJ6/3KSev9yk3r/cpN6/3KTev9yk3r/cpR6/3KUev9ylHr/cpR6/3KUe/9ylHv/cpR7/3KUe/9zlXv/ + c5V7/3OVe/9zlXv/c5Z8/3OWfP9zlnz/c5Z8/+zw7P/s8Oz/7PDs/+zw7P+Trpn/k66Z/5Oumf+Trpn/ + dJh8/3SYfP90mHz/dJh8/3SYff90mH3/dJh9/3SYff90mX3/dJl9/3SZff90mX3/dJl+/3SZfv90mX7/ + dJl+/3Safv90mn7/dJp+/3Safv9zqZn/c6mZ/3Opmf9zqZn/RLz4/0S8+P9EvPj/RLz4/yh4Xf8oeF3/ + KHhd/yh4Xf8hYTH/IWEx/yFhMf8hYTH/ImUz/yJlM/8iZTP/ImUz/yyAQf8sgEH/LIBB/yyAQf9+tYv/ + frWL/361i/9+tYv/frWL/361i/9+tYv/frWL/361i/9+tYv/frWL/361i/9/u6P/f7uj/3+7o/9/u6P/ + hNP7/4TT+/+E0/v/hNP7/3elmv93pZr/d6Wa/3elmv9wjXf/cI13/3CNd/9wjXf/cI54/3COeP9wjnj/ + cI54/3CPeP9wj3j/cI94/3CPeP9wj3n/cI95/3CPef9wj3n/cZB5/3GQef9xkHn/cZB5/5Gpl/+RqZf/ + kamX/5Gpl//s8Oz/7PDs/+zw7P/s8Oz/cpJ6/3KSev9yknr/cpJ6/3KTev9yk3r/cpN6/3KTev9ylHr/ + cpR6/3KUev9ylHr/cpR7/3KUe/9ylHv/cpR7/3OVe/9zlXv/c5V7/3OVe/9zlnz/c5Z8/3OWfP9zlnz/ + 7PDs/+zw7P/s8Oz/7PDs/5Oumf+Trpn/k66Z/5Oumf90mHz/dJh8/3SYfP90mHz/dJh9/3SYff90mH3/ + dJh9/3SZff90mX3/dJl9/3SZff90mX7/dJl+/3SZfv90mX7/dJp+/3Safv90mn7/dJp+/3Opmf9zqZn/ + c6mZ/3Opmf9EvPj/RLz4/0S8+P9EvPj/KHhd/yh4Xf8oeF3/KHhd/yFhMf8hYTH/IWEx/yFhMf8iZTP/ + ImUz/yJlM/8iZTP/LIBB/yyAQf8sgEH/LIBB/361i/9+tYv/frWL/361i/9+tYv/frWL/361i/9+tYv/ + frWL/361i/9+tYv/frWL/3+7o/9/u6P/f7uj/3+7o/+E0/v/hNP7/4TT+/+E0/v/d6Wa/3elmv93pZr/ + d6Wa/3CNd/9wjXf/cI13/3CNd/9wjnj/cI54/3COeP9wjnj/cI94/3CPeP9wj3j/cI94/3CPef9wj3n/ + cI95/3CPef9xkHn/cZB5/3GQef9xkHn/kamX/5Gpl/+RqZf/kamX/+zw7P/s8Oz/7PDs/+zw7P9yknr/ + cpJ6/3KSev9yknr/cpN6/3KTev9yk3r/cpN6/3KUev9ylHr/cpR6/3KUev9ylHv/cpR7/3KUe/9ylHv/ + c5V7/3OVe/9zlXv/c5V7/3OWfP9zlnz/c5Z8/3OWfP/s8Oz/7PDs/+zw7P/s8Oz/k66Z/5Oumf+Trpn/ + k66Z/3SYfP90mHz/dJh8/3SYfP90mH3/dJh9/3SYff90mH3/dJl9/3SZff90mX3/dJl9/3SZfv90mX7/ + dJl+/3SZfv90mn7/dJp+/3Safv90mn7/c6mZ/3Opmf9zqZn/c6mZ/0S8+P9EvPj/RLz4/0S8+P8oeF3/ + KHhd/yh4Xf8oeF3/IWEx/yFhMf8hYTH/IWEx/yJlM/8iZTP/ImUz/yJlM/8sgEH/LIBB/yyAQf8sgEH/ + gbeO/4G3jv+Bt47/gbeO/4G3jv+Bt47/gbeO/4G3jv+Bt47/gbeO/4G3jv+Bt47/gr6n/4K+p/+Cvqf/ + gr6n/4fU+/+H1Pv/h9T7/4fU+/95pJj/eaSY/3mkmP95pJj/c496/3OPev9zj3r/c496/3OQev9zkHr/ + c5B6/3OQev9zkXr/c5F6/3ORev9zkXr/dJJ7/3SSe/90knv/dJJ7/3SSe/90knv/dJJ7/3SSe/94loD/ + eJaA/3iWgP94loD/7fDs/+3w7P/t8Oz/7fDs/9Te1v/U3tb/1N7W/9Te1v+/zcL/v83C/7/Nwv+/zcL/ + v83C/7/Nwv+/zcL/v83C/7/Owv+/zsL/v87C/7/Owv+/zsL/v87C/7/Owv+/zsL/1d/X/9Xf1//V39f/ + 1d/X/+3w7f/t8O3/7fDt/+3w7f96nIP/epyD/3qcg/96nIP/dpl//3aZf/92mX//dpl//3eaf/93mn// + d5p//3eaf/93m3//d5t//3ebf/93m3//d5uA/3ebgP93m4D/d5uA/3ecgf93nIH/d5yB/3ecgf98rp3/ + fK6d/3yunf98rp3/ftH6/37R+v9+0fr/ftH6/zOBaP8zgWj/M4Fo/zOBaP8iZDL/ImQy/yJkMv8iZDL/ + LYJB/y2CQf8tgkH/LYJB/y+JRf8viUX/L4lF/y+JRf+Bt47/gbeO/4G3jv+Bt47/gbeO/4G3jv+Bt47/ + gbeO/4G3jv+Bt47/gbeO/4G3jv+Cvqf/gr6n/4K+p/+Cvqf/h9T7/4fU+/+H1Pv/h9T7/3mkmP95pJj/ + eaSY/3mkmP9zj3r/c496/3OPev9zj3r/c5B6/3OQev9zkHr/c5B6/3ORev9zkXr/c5F6/3ORev90knv/ + dJJ7/3SSe/90knv/dJJ7/3SSe/90knv/dJJ7/3iWgP94loD/eJaA/3iWgP/t8Oz/7fDs/+3w7P/t8Oz/ + 1N7W/9Te1v/U3tb/1N7W/7/Nwv+/zcL/v83C/7/Nwv+/zcL/v83C/7/Nwv+/zcL/v87C/7/Owv+/zsL/ + v87C/7/Owv+/zsL/v87C/7/Owv/V39f/1d/X/9Xf1//V39f/7fDt/+3w7f/t8O3/7fDt/3qcg/96nIP/ + epyD/3qcg/92mX//dpl//3aZf/92mX//d5p//3eaf/93mn//d5p//3ebf/93m3//d5t//3ebf/93m4D/ + d5uA/3ebgP93m4D/d5yB/3ecgf93nIH/d5yB/3yunf98rp3/fK6d/3yunf9+0fr/ftH6/37R+v9+0fr/ + M4Fo/zOBaP8zgWj/M4Fo/yJkMv8iZDL/ImQy/yJkMv8tgkH/LYJB/y2CQf8tgkH/L4lF/y+JRf8viUX/ + L4lF/4G3jv+Bt47/gbeO/4G3jv+Bt47/gbeO/4G3jv+Bt47/gbeO/4G3jv+Bt47/gbeO/4K+p/+Cvqf/ + gr6n/4K+p/+H1Pv/h9T7/4fU+/+H1Pv/eaSY/3mkmP95pJj/eaSY/3OPev9zj3r/c496/3OPev9zkHr/ + c5B6/3OQev9zkHr/c5F6/3ORev9zkXr/c5F6/3SSe/90knv/dJJ7/3SSe/90knv/dJJ7/3SSe/90knv/ + eJaA/3iWgP94loD/eJaA/+3w7P/t8Oz/7fDs/+3w7P/U3tb/1N7W/9Te1v/U3tb/v83C/7/Nwv+/zcL/ + v83C/7/Nwv+/zcL/v83C/7/Nwv+/zsL/v87C/7/Owv+/zsL/v87C/7/Owv+/zsL/v87C/9Xf1//V39f/ + 1d/X/9Xf1//t8O3/7fDt/+3w7f/t8O3/epyD/3qcg/96nIP/epyD/3aZf/92mX//dpl//3aZf/93mn// + d5p//3eaf/93mn//d5t//3ebf/93m3//d5t//3ebgP93m4D/d5uA/3ebgP93nIH/d5yB/3ecgf93nIH/ + fK6d/3yunf98rp3/fK6d/37R+v9+0fr/ftH6/37R+v8zgWj/M4Fo/zOBaP8zgWj/ImQy/yJkMv8iZDL/ + ImQy/y2CQf8tgkH/LYJB/y2CQf8viUX/L4lF/y+JRf8viUX/gbeO/4G3jv+Bt47/gbeO/4G3jv+Bt47/ + gbeO/4G3jv+Bt47/gbeO/4G3jv+Bt47/gr6n/4K+p/+Cvqf/gr6n/4fU+/+H1Pv/h9T7/4fU+/95pJj/ + eaSY/3mkmP95pJj/c496/3OPev9zj3r/c496/3OQev9zkHr/c5B6/3OQev9zkXr/c5F6/3ORev9zkXr/ + dJJ7/3SSe/90knv/dJJ7/3SSe/90knv/dJJ7/3SSe/94loD/eJaA/3iWgP94loD/7fDs/+3w7P/t8Oz/ + 7fDs/9Te1v/U3tb/1N7W/9Te1v+/zcL/v83C/7/Nwv+/zcL/v83C/7/Nwv+/zcL/v83C/7/Owv+/zsL/ + v87C/7/Owv+/zsL/v87C/7/Owv+/zsL/1d/X/9Xf1//V39f/1d/X/+3w7f/t8O3/7fDt/+3w7f96nIP/ + epyD/3qcg/96nIP/dpl//3aZf/92mX//dpl//3eaf/93mn//d5p//3eaf/93m3//d5t//3ebf/93m3// + d5uA/3ebgP93m4D/d5uA/3ecgf93nIH/d5yB/3ecgf98rp3/fK6d/3yunf98rp3/ftH6/37R+v9+0fr/ + ftH6/zOBaP8zgWj/M4Fo/zOBaP8iZDL/ImQy/yJkMv8iZDL/LYJB/y2CQf8tgkH/LYJB/y+JRf8viUX/ + L4lF/y+JRf+EuZH/hLmR/4S5kf+EuZH/hLmR/4S5kf+EuZH/hLmR/4S5kf+EuZH/hLmR/4S5kf+FwKz/ + hcCs/4XArP+FwKz/idb7/4nW+/+J1vv/idb7/32qof99qqH/faqh/32qof92kXz/dpF8/3aRfP92kXz/ + dpJ9/3aSff92kn3/dpJ9/3aTfv92k37/dpN+/3aTfv92k37/dpN+/3aTfv92k37/dpR+/3aUfv92lH7/ + dpR+/3eUfv93lH7/d5R+/3eUfv+Cnor/gp6K/4Keiv+Cnor/tca5/7XGuf+1xrn/tca5/8DOw//AzsP/ + wM7D/8DOw//Az8P/wM/D/8DPw//Az8P/wM/E/8DPxP/Az8T/wM/E/8DPxP/Az8T/wM/E/8DPxP+2yLr/ + tsi6/7bIuv+2yLr/hKOL/4Sji/+Eo4v/hKOL/3mbgv95m4L/eZuC/3mbgv95m4L/eZuC/3mbgv95m4L/ + eZyC/3mcgv95nIL/eZyC/3mdgv95nYL/eZ2C/3mdgv96nYP/ep2D/3qdg/96nYP/ep6D/3qeg/96noP/ + ep6D/4Cypf+AsqX/gLKl/4Cypf+J1vv/idb7/4nW+/+J1vv/dKyc/3SsnP90rJz/dKyc/zSGSv80hkr/ + NIZK/zSGSv8wikf/MIpH/zCKR/8wikf/MIpH/zCKR/8wikf/MIpH/4S5kf+EuZH/hLmR/4S5kf+EuZH/ + hLmR/4S5kf+EuZH/hLmR/4S5kf+EuZH/hLmR/4XArP+FwKz/hcCs/4XArP+J1vv/idb7/4nW+/+J1vv/ + faqh/32qof99qqH/faqh/3aRfP92kXz/dpF8/3aRfP92kn3/dpJ9/3aSff92kn3/dpN+/3aTfv92k37/ + dpN+/3aTfv92k37/dpN+/3aTfv92lH7/dpR+/3aUfv92lH7/d5R+/3eUfv93lH7/d5R+/4Keiv+Cnor/ + gp6K/4Keiv+1xrn/tca5/7XGuf+1xrn/wM7D/8DOw//AzsP/wM7D/8DPw//Az8P/wM/D/8DPw//Az8T/ + wM/E/8DPxP/Az8T/wM/E/8DPxP/Az8T/wM/E/7bIuv+2yLr/tsi6/7bIuv+Eo4v/hKOL/4Sji/+Eo4v/ + eZuC/3mbgv95m4L/eZuC/3mbgv95m4L/eZuC/3mbgv95nIL/eZyC/3mcgv95nIL/eZ2C/3mdgv95nYL/ + eZ2C/3qdg/96nYP/ep2D/3qdg/96noP/ep6D/3qeg/96noP/gLKl/4Cypf+AsqX/gLKl/4nW+/+J1vv/ + idb7/4nW+/90rJz/dKyc/3SsnP90rJz/NIZK/zSGSv80hkr/NIZK/zCKR/8wikf/MIpH/zCKR/8wikf/ + MIpH/zCKR/8wikf/hLmR/4S5kf+EuZH/hLmR/4S5kf+EuZH/hLmR/4S5kf+EuZH/hLmR/4S5kf+EuZH/ + hcCs/4XArP+FwKz/hcCs/4nW+/+J1vv/idb7/4nW+/99qqH/faqh/32qof99qqH/dpF8/3aRfP92kXz/ + dpF8/3aSff92kn3/dpJ9/3aSff92k37/dpN+/3aTfv92k37/dpN+/3aTfv92k37/dpN+/3aUfv92lH7/ + dpR+/3aUfv93lH7/d5R+/3eUfv93lH7/gp6K/4Keiv+Cnor/gp6K/7XGuf+1xrn/tca5/7XGuf/AzsP/ + wM7D/8DOw//AzsP/wM/D/8DPw//Az8P/wM/D/8DPxP/Az8T/wM/E/8DPxP/Az8T/wM/E/8DPxP/Az8T/ + tsi6/7bIuv+2yLr/tsi6/4Sji/+Eo4v/hKOL/4Sji/95m4L/eZuC/3mbgv95m4L/eZuC/3mbgv95m4L/ + eZuC/3mcgv95nIL/eZyC/3mcgv95nYL/eZ2C/3mdgv95nYL/ep2D/3qdg/96nYP/ep2D/3qeg/96noP/ + ep6D/3qeg/+AsqX/gLKl/4Cypf+AsqX/idb7/4nW+/+J1vv/idb7/3SsnP90rJz/dKyc/3SsnP80hkr/ + NIZK/zSGSv80hkr/MIpH/zCKR/8wikf/MIpH/zCKR/8wikf/MIpH/zCKR/+EuZH/hLmR/4S5kf+EuZH/ + hLmR/4S5kf+EuZH/hLmR/4S5kf+EuZH/hLmR/4S5kf+FwKz/hcCs/4XArP+FwKz/idb7/4nW+/+J1vv/ + idb7/32qof99qqH/faqh/32qof92kXz/dpF8/3aRfP92kXz/dpJ9/3aSff92kn3/dpJ9/3aTfv92k37/ + dpN+/3aTfv92k37/dpN+/3aTfv92k37/dpR+/3aUfv92lH7/dpR+/3eUfv93lH7/d5R+/3eUfv+Cnor/ + gp6K/4Keiv+Cnor/tca5/7XGuf+1xrn/tca5/8DOw//AzsP/wM7D/8DOw//Az8P/wM/D/8DPw//Az8P/ + wM/E/8DPxP/Az8T/wM/E/8DPxP/Az8T/wM/E/8DPxP+2yLr/tsi6/7bIuv+2yLr/hKOL/4Sji/+Eo4v/ + hKOL/3mbgv95m4L/eZuC/3mbgv95m4L/eZuC/3mbgv95m4L/eZyC/3mcgv95nIL/eZyC/3mdgv95nYL/ + eZ2C/3mdgv96nYP/ep2D/3qdg/96nYP/ep6D/3qeg/96noP/ep6D/4Cypf+AsqX/gLKl/4Cypf+J1vv/ + idb7/4nW+/+J1vv/dKyc/3SsnP90rJz/dKyc/zSGSv80hkr/NIZK/zSGSv8wikf/MIpH/zCKR/8wikf/ + MIpH/zCKR/8wikf/MIpH/4e8lf+HvJX/h7yV/4e8lf+HvJX/h7yV/4e8lf+HvJX/h7yV/4e8lf+HvJX/ + h7yV/4i/oP+Iv6D/iL+g/4i/oP+M1vX/jNb1/4zW9f+M1vX/jdj6/43Y+v+N2Pr/jdj6/4rM2/+KzNv/ + iszb/4rM2/+Fu7v/hbu7/4W7u/+Fu7v/gKmc/4CpnP+AqZz/gKmc/3uYg/97mIP/e5iD/3uYg/96l4L/ + epeC/3qXgv96l4L/e5eC/3uXgv97l4L/e5eC/3uYgv97mIL/e5iC/3uYgv97mIL/e5iC/3uYgv97mIL/ + e5mD/3uZg/97mYP/e5mD/3uZg/97mYP/e5mD/3uZg/98moP/fJqD/3yag/98moP/fJuE/3ybhP98m4T/ + fJuE/3ychP98nIT/fJyE/3ychP98nIX/fJyF/3ychf98nIX/fJ2F/3ydhf98nYX/fJ2F/32dhf99nYX/ + fZ2F/32dhf9+oIf/fqCH/36gh/9+oIf/gq6g/4KuoP+CrqD/gq6g/4a/vP+Gv7z/hr+8/4a/vP+Kzdz/ + is3c/4rN3P+Kzdz/jdj6/43Y+v+N2Pr/jdj6/43W9f+N1vX/jdb1/43W9f+HvqH/h76h/4e+of+HvqH/ + drKF/3ayhf92soX/drKF/zOMSv8zjEr/M4xK/zOMSv8xi0j/MYtI/zGLSP8xi0j/h7yV/4e8lf+HvJX/ + h7yV/4e8lf+HvJX/h7yV/4e8lf+HvJX/h7yV/4e8lf+HvJX/iL+g/4i/oP+Iv6D/iL+g/4zW9f+M1vX/ + jNb1/4zW9f+N2Pr/jdj6/43Y+v+N2Pr/iszb/4rM2/+KzNv/iszb/4W7u/+Fu7v/hbu7/4W7u/+AqZz/ + gKmc/4CpnP+AqZz/e5iD/3uYg/97mIP/e5iD/3qXgv96l4L/epeC/3qXgv97l4L/e5eC/3uXgv97l4L/ + e5iC/3uYgv97mIL/e5iC/3uYgv97mIL/e5iC/3uYgv97mYP/e5mD/3uZg/97mYP/e5mD/3uZg/97mYP/ + e5mD/3yag/98moP/fJqD/3yag/98m4T/fJuE/3ybhP98m4T/fJyE/3ychP98nIT/fJyE/3ychf98nIX/ + fJyF/3ychf98nYX/fJ2F/3ydhf98nYX/fZ2F/32dhf99nYX/fZ2F/36gh/9+oIf/fqCH/36gh/+CrqD/ + gq6g/4KuoP+CrqD/hr+8/4a/vP+Gv7z/hr+8/4rN3P+Kzdz/is3c/4rN3P+N2Pr/jdj6/43Y+v+N2Pr/ + jdb1/43W9f+N1vX/jdb1/4e+of+HvqH/h76h/4e+of92soX/drKF/3ayhf92soX/M4xK/zOMSv8zjEr/ + M4xK/zGLSP8xi0j/MYtI/zGLSP+HvJX/h7yV/4e8lf+HvJX/h7yV/4e8lf+HvJX/h7yV/4e8lf+HvJX/ + h7yV/4e8lf+Iv6D/iL+g/4i/oP+Iv6D/jNb1/4zW9f+M1vX/jNb1/43Y+v+N2Pr/jdj6/43Y+v+KzNv/ + iszb/4rM2/+KzNv/hbu7/4W7u/+Fu7v/hbu7/4CpnP+AqZz/gKmc/4CpnP97mIP/e5iD/3uYg/97mIP/ + epeC/3qXgv96l4L/epeC/3uXgv97l4L/e5eC/3uXgv97mIL/e5iC/3uYgv97mIL/e5iC/3uYgv97mIL/ + e5iC/3uZg/97mYP/e5mD/3uZg/97mYP/e5mD/3uZg/97mYP/fJqD/3yag/98moP/fJqD/3ybhP98m4T/ + fJuE/3ybhP98nIT/fJyE/3ychP98nIT/fJyF/3ychf98nIX/fJyF/3ydhf98nYX/fJ2F/3ydhf99nYX/ + fZ2F/32dhf99nYX/fqCH/36gh/9+oIf/fqCH/4KuoP+CrqD/gq6g/4KuoP+Gv7z/hr+8/4a/vP+Gv7z/ + is3c/4rN3P+Kzdz/is3c/43Y+v+N2Pr/jdj6/43Y+v+N1vX/jdb1/43W9f+N1vX/h76h/4e+of+HvqH/ + h76h/3ayhf92soX/drKF/3ayhf8zjEr/M4xK/zOMSv8zjEr/MYtI/zGLSP8xi0j/MYtI/4e8lf+HvJX/ + h7yV/4e8lf+HvJX/h7yV/4e8lf+HvJX/h7yV/4e8lf+HvJX/h7yV/4i/oP+Iv6D/iL+g/4i/oP+M1vX/ + jNb1/4zW9f+M1vX/jdj6/43Y+v+N2Pr/jdj6/4rM2/+KzNv/iszb/4rM2/+Fu7v/hbu7/4W7u/+Fu7v/ + gKmc/4CpnP+AqZz/gKmc/3uYg/97mIP/e5iD/3uYg/96l4L/epeC/3qXgv96l4L/e5eC/3uXgv97l4L/ + e5eC/3uYgv97mIL/e5iC/3uYgv97mIL/e5iC/3uYgv97mIL/e5mD/3uZg/97mYP/e5mD/3uZg/97mYP/ + e5mD/3uZg/98moP/fJqD/3yag/98moP/fJuE/3ybhP98m4T/fJuE/3ychP98nIT/fJyE/3ychP98nIX/ + fJyF/3ychf98nIX/fJ2F/3ydhf98nYX/fJ2F/32dhf99nYX/fZ2F/32dhf9+oIf/fqCH/36gh/9+oIf/ + gq6g/4KuoP+CrqD/gq6g/4a/vP+Gv7z/hr+8/4a/vP+Kzdz/is3c/4rN3P+Kzdz/jdj6/43Y+v+N2Pr/ + jdj6/43W9f+N1vX/jdb1/43W9f+HvqH/h76h/4e+of+HvqH/drKF/3ayhf92soX/drKF/zOMSv8zjEr/ + M4xK/zOMSv8xi0j/MYtI/zGLSP8xi0j/ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ + ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/4rBof+KwaH/isGh/4rBof+NysX/jcrF/43Kxf+NysX/ + jtPk/47T5P+O0+T/jtPk/4/Z+v+P2fr/j9n6/4/Z+v+P2fr/j9n6/4/Z+v+P2fr/j9j4/4/Y+P+P2Pj/ + j9j4/47U7P+O1Oz/jtTs/47U7P+Nz93/jc/d/43P3f+Nz93/i8fO/4vHzv+Lx87/i8fO/4rEx/+KxMf/ + isTH/4rEx/+JwcH/icHB/4nBwf+JwcH/ib68/4m+vP+Jvrz/ib68/4m/vP+Jv7z/ib+8/4m/vP+JwsL/ + icLC/4nCwv+JwsL/isTH/4rEx/+KxMf/isTH/4vJz/+Lyc//i8nP/4vJz/+Nz93/jc/d/43P3f+Nz93/ + jtTs/47U7P+O1Oz/jtTs/4/Y+P+P2Pj/j9j4/4/Y+P+P2fr/j9n6/4/Z+v+P2fr/j9n6/4/Z+v+P2fr/ + j9n6/47T5v+O0+b/jtPm/47T5v+My8j/jMvI/4zLyP+My8j/i8Ch/4vAof+LwKH/i8Ch/4q+mP+Kvpj/ + ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/Z6t4/2ereP9nq3j/Z6t4/zKNSf8yjUn/Mo1J/zKNSf+Kvpj/ + ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ + isGh/4rBof+KwaH/isGh/43Kxf+NysX/jcrF/43Kxf+O0+T/jtPk/47T5P+O0+T/j9n6/4/Z+v+P2fr/ + j9n6/4/Z+v+P2fr/j9n6/4/Z+v+P2Pj/j9j4/4/Y+P+P2Pj/jtTs/47U7P+O1Oz/jtTs/43P3f+Nz93/ + jc/d/43P3f+Lx87/i8fO/4vHzv+Lx87/isTH/4rEx/+KxMf/isTH/4nBwf+JwcH/icHB/4nBwf+Jvrz/ + ib68/4m+vP+Jvrz/ib+8/4m/vP+Jv7z/ib+8/4nCwv+JwsL/icLC/4nCwv+KxMf/isTH/4rEx/+KxMf/ + i8nP/4vJz/+Lyc//i8nP/43P3f+Nz93/jc/d/43P3f+O1Oz/jtTs/47U7P+O1Oz/j9j4/4/Y+P+P2Pj/ + j9j4/4/Z+v+P2fr/j9n6/4/Z+v+P2fr/j9n6/4/Z+v+P2fr/jtPm/47T5v+O0+b/jtPm/4zLyP+My8j/ + jMvI/4zLyP+LwKH/i8Ch/4vAof+LwKH/ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/4q+mP9nq3j/ + Z6t4/2ereP9nq3j/Mo1J/zKNSf8yjUn/Mo1J/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ + ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+KwaH/isGh/4rBof+KwaH/jcrF/43Kxf+NysX/ + jcrF/47T5P+O0+T/jtPk/47T5P+P2fr/j9n6/4/Z+v+P2fr/j9n6/4/Z+v+P2fr/j9n6/4/Y+P+P2Pj/ + j9j4/4/Y+P+O1Oz/jtTs/47U7P+O1Oz/jc/d/43P3f+Nz93/jc/d/4vHzv+Lx87/i8fO/4vHzv+KxMf/ + isTH/4rEx/+KxMf/icHB/4nBwf+JwcH/icHB/4m+vP+Jvrz/ib68/4m+vP+Jv7z/ib+8/4m/vP+Jv7z/ + icLC/4nCwv+JwsL/icLC/4rEx/+KxMf/isTH/4rEx/+Lyc//i8nP/4vJz/+Lyc//jc/d/43P3f+Nz93/ + jc/d/47U7P+O1Oz/jtTs/47U7P+P2Pj/j9j4/4/Y+P+P2Pj/j9n6/4/Z+v+P2fr/j9n6/4/Z+v+P2fr/ + j9n6/4/Z+v+O0+b/jtPm/47T5v+O0+b/jMvI/4zLyP+My8j/jMvI/4vAof+LwKH/i8Ch/4vAof+Kvpj/ + ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/2ereP9nq3j/Z6t4/2ereP8yjUn/Mo1J/zKNSf8yjUn/ + ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ + ir6Y/4rBof+KwaH/isGh/4rBof+NysX/jcrF/43Kxf+NysX/jtPk/47T5P+O0+T/jtPk/4/Z+v+P2fr/ + j9n6/4/Z+v+P2fr/j9n6/4/Z+v+P2fr/j9j4/4/Y+P+P2Pj/j9j4/47U7P+O1Oz/jtTs/47U7P+Nz93/ + jc/d/43P3f+Nz93/i8fO/4vHzv+Lx87/i8fO/4rEx/+KxMf/isTH/4rEx/+JwcH/icHB/4nBwf+JwcH/ + ib68/4m+vP+Jvrz/ib68/4m/vP+Jv7z/ib+8/4m/vP+JwsL/icLC/4nCwv+JwsL/isTH/4rEx/+KxMf/ + isTH/4vJz/+Lyc//i8nP/4vJz/+Nz93/jc/d/43P3f+Nz93/jtTs/47U7P+O1Oz/jtTs/4/Y+P+P2Pj/ + j9j4/4/Y+P+P2fr/j9n6/4/Z+v+P2fr/j9n6/4/Z+v+P2fr/j9n6/47T5v+O0+b/jtPm/47T5v+My8j/ + jMvI/4zLyP+My8j/i8Ch/4vAof+LwKH/i8Ch/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ + Z6t4/2ereP9nq3j/Z6t4/zKNSf8yjUn/Mo1J/zKNSf+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcKj/43Co/+NwqP/jcKj/4/Iuf+PyLn/j8i5/4/Iuf+Pzcn/ + j83J/4/Nyf+Pzcn/kNHZ/5DR2f+Q0dn/kNHZ/5HV6P+R1ej/kdXo/5HV6P+R1/L/kdfy/5HX8v+R1/L/ + kdn2/5HZ9v+R2fb/kdn2/5La+v+S2vr/ktr6/5La+v+S2vv/ktr7/5La+/+S2vv/ktr7/5La+/+S2vv/ + ktr7/5La+v+S2vr/ktr6/5La+v+R2fb/kdn2/5HZ9v+R2fb/kdfy/5HX8v+R1/L/kdfy/5HV6P+R1ej/ + kdXo/5HV6P+Q0dj/kNHY/5DR2P+Q0dj/j8zI/4/MyP+PzMj/j8zI/4/Iuf+PyLn/j8i5/4/Iuf+NwqP/ + jcKj/43Co/+NwqP/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/VKFp/1Shaf9UoWn/ + VKFp/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwqP/ + jcKj/43Co/+NwqP/j8i5/4/Iuf+PyLn/j8i5/4/Nyf+Pzcn/j83J/4/Nyf+Q0dn/kNHZ/5DR2f+Q0dn/ + kdXo/5HV6P+R1ej/kdXo/5HX8v+R1/L/kdfy/5HX8v+R2fb/kdn2/5HZ9v+R2fb/ktr6/5La+v+S2vr/ + ktr6/5La+/+S2vv/ktr7/5La+/+S2vv/ktr7/5La+/+S2vv/ktr6/5La+v+S2vr/ktr6/5HZ9v+R2fb/ + kdn2/5HZ9v+R1/L/kdfy/5HX8v+R1/L/kdXo/5HV6P+R1ej/kdXo/5DR2P+Q0dj/kNHY/5DR2P+PzMj/ + j8zI/4/MyP+PzMj/j8i5/4/Iuf+PyLn/j8i5/43Co/+NwqP/jcKj/43Co/+NwJv/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwJv/jcCb/43Am/9UoWn/VKFp/1Shaf9UoWn/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Co/+NwqP/jcKj/43Co/+PyLn/j8i5/4/Iuf+PyLn/ + j83J/4/Nyf+Pzcn/j83J/5DR2f+Q0dn/kNHZ/5DR2f+R1ej/kdXo/5HV6P+R1ej/kdfy/5HX8v+R1/L/ + kdfy/5HZ9v+R2fb/kdn2/5HZ9v+S2vr/ktr6/5La+v+S2vr/ktr7/5La+/+S2vv/ktr7/5La+/+S2vv/ + ktr7/5La+/+S2vr/ktr6/5La+v+S2vr/kdn2/5HZ9v+R2fb/kdn2/5HX8v+R1/L/kdfy/5HX8v+R1ej/ + kdXo/5HV6P+R1ej/kNHY/5DR2P+Q0dj/kNHY/4/MyP+PzMj/j8zI/4/MyP+PyLn/j8i5/4/Iuf+PyLn/ + jcKj/43Co/+NwqP/jcKj/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/1Shaf9UoWn/ + VKFp/1Shaf+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/ + jcKj/43Co/+NwqP/jcKj/4/Iuf+PyLn/j8i5/4/Iuf+Pzcn/j83J/4/Nyf+Pzcn/kNHZ/5DR2f+Q0dn/ + kNHZ/5HV6P+R1ej/kdXo/5HV6P+R1/L/kdfy/5HX8v+R1/L/kdn2/5HZ9v+R2fb/kdn2/5La+v+S2vr/ + ktr6/5La+v+S2vv/ktr7/5La+/+S2vv/ktr7/5La+/+S2vv/ktr7/5La+v+S2vr/ktr6/5La+v+R2fb/ + kdn2/5HZ9v+R2fb/kdfy/5HX8v+R1/L/kdfy/5HV6P+R1ej/kdXo/5HV6P+Q0dj/kNHY/5DR2P+Q0dj/ + j8zI/4/MyP+PzMj/j8zI/4/Iuf+PyLn/j8i5/4/Iuf+NwqP/jcKj/43Co/+NwqP/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/VKFp/1Shaf9UoWn/VKFp/4zAmvGMwJrxjMCa8YzAmvGQwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKe/5DCnv+Qwp7/kMKe/5DEo/+QxKP/kMSj/5DEo/+QxKL/ + kMSi/5DEov+QxKL/kMKe/5DCnv+Qwp7/kMKe/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+NwZrx + jcGa8Y3BmvGNwZrxjMCa8YzAmvGMwJrxjMCa8ZDCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp7/ + kMKe/5DCnv+Qwp7/kMSj/5DEo/+QxKP/kMSj/5DEov+QxKL/kMSi/5DEov+Qwp7/kMKe/5DCnv+Qwp7/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/43BmvGNwZrxjcGa8Y3BmvGMwJrxjMCa8YzAmvGMwJrx + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnv+Qwp7/kMKe/5DCnv+QxKP/kMSj/5DEo/+QxKP/ + kMSi/5DEov+QxKL/kMSi/5DCnv+Qwp7/kMKe/5DCnv+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + jcGa8Y3BmvGNwZrxjcGa8YzAmvGMwJrxjMCa8YzAmvGQwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKe/5DCnv+Qwp7/kMKe/5DEo/+QxKP/kMSj/5DEo/+QxKL/kMSi/5DEov+QxKL/kMKe/5DCnv+Qwp7/ + kMKe/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+NwZrxjcGa8Y3BmvGNwZrxhr6XxIa+l8SGvpfE + hr6XxJTFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/4/CncaPwp3Gj8Kdxo/CncaGvpfEhr6XxIa+l8SGvpfElMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/j8Kdxo/CncaPwp3Gj8Kdxoa+l8SGvpfE + hr6XxIa+l8SUxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+Pwp3Gj8Kdxo/CncaPwp3Ghr6XxIa+l8SGvpfEhr6XxJTFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/4/CncaPwp3Gj8Kdxo/CncZ8u48p + fLuPKXy7jyl8u48pk8ag9ZPGoPWTxqD1k8ag9ZbHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+YyKX2 + mMil9pjIpfaYyKX2mceoMpnHqDKZx6gymceoMny7jyl8u48pfLuPKXy7jymTxqD1k8ag9ZPGoPWTxqD1 + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5jIpfaYyKX2mMil9pjIpfaZx6gymceoMpnHqDKZx6gy + fLuPKXy7jyl8u48pfLuPKZPGoPWTxqD1k8ag9ZPGoPWWx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + mMil9pjIpfaYyKX2mMil9pnHqDKZx6gymceoMpnHqDJ8u48pfLuPKXy7jyl8u48pk8ag9ZPGoPWTxqD1 + k8ag9ZbHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+YyKX2mMil9pjIpfaYyKX2mceoMpnHqDKZx6gy + mceoMgAAAAAAAAAAAAAAAAAAAAB8u48pfLuPKXy7jyl8u48pjMKbxYzCm8WMwpvFjMKbxZbHo/KWx6Py + lsej8pbHo/KZyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+ayafzmsmn85rJp/OayafzlsaiyZbGosmWxqLJ + lsaiyZvIqjObyKozm8iqM5vIqjMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHy7jyl8u48p + fLuPKXy7jymMwpvFjMKbxYzCm8WMwpvFlsej8pbHo/KWx6Pylsej8pnJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5rJp/Oayafzmsmn85rJp/OWxqLJlsaiyZbGosmWxqLJm8iqM5vIqjObyKozm8iqMwAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfLuPKXy7jyl8u48pfLuPKYzCm8WMwpvFjMKbxYzCm8WWx6Py + lsej8pbHo/KWx6Pymcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/msmn85rJp/Oayafzmsmn85bGosmWxqLJ + lsaiyZbGosmbyKozm8iqM5vIqjObyKozAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB8u48p + fLuPKXy7jyl8u48pjMKbxYzCm8WMwpvFjMKbxZbHo/KWx6Pylsej8pbHo/KZyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+ayafzmsmn85rJp/OayafzlsaiyZbGosmWxqLJlsaiyZvIqjObyKozm8iqM5vIqjMAAAAA + AAAAAAAAAAAAAAAA8AAAAAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAAAP + 8AAAAAAAAAAAAAAAAAAADwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAPAAAAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAA + AAAAD/AAAAAAAAAAAAAAAAAAAA8oAAAAQAAAAIAAAAABACAAAAAAAABAAAATCwAAEwsAAAAAAAAAAAAA + AAAAAAAAAAAbZCQcG2QkHB1nJqkdZyapHGcm5xxnJuccZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/ + HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/ + HGcm/xxnJv8YWiH/GFoh/xZSHv8WUh7/F1Mf/xdTH/8XVB//F1Qf/xdUH/8XVB//F1Yg/xdWIP8XViD/ + F1Yg/xhXIP8YVyD/GFgg/xhYIP8YWSH/GFkh/xhaIf8YWiH/GVoh/xlaIf8YXCLpGFwi6RpcIq8aXCKv + GVohHxlaIR8AAAAAAAAAAAAAAAAAAAAAG2QkHBtkJBwdZyapHWcmqRxnJuccZybnHGcm/xxnJv8cZyb/ + HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/ + HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/GFoh/xhaIf8WUh7/FlIe/xdTH/8XUx//F1Qf/xdUH/8XVB// + F1Qf/xdWIP8XViD/F1Yg/xdWIP8YVyD/GFcg/xhYIP8YWCD/GFkh/xhZIf8YWiH/GFoh/xlaIf8ZWiH/ + GFwi6RhcIukaXCKvGlwirxlaIR8ZWiEfAAAAAAAAAAAbZCQcG2QkHB1oJ+0daCftHWgn/x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8ZWiL/GVoi/xdRHv8XUR7/F1If/xdSH/8XUx// + F1Mf/xdUH/8XVB//GFQg/xhUIP8YVSD/GFUg/xhWIP8YViD/GFch/xhXIf8ZWCH/GVgh/xlZIf8ZWSH/ + GVoi/xlaIv8ZWyL/GVsi/xlbIv8ZWyL/Glwj/xpcI/8aXSLvGl0i7xlaIR8ZWiEfG2QkHBtkJBwdaCft + HWgn7R1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/GVoi/xlaIv8XUR7/ + F1Ee/xdSH/8XUh//F1Mf/xdTH/8XVB//F1Qf/xhUIP8YVCD/GFUg/xhVIP8YViD/GFYg/xhXIf8YVyH/ + GVgh/xlYIf8ZWSH/GVkh/xlaIv8ZWiL/GVsi/xlbIv8ZWyL/GVsi/xpcI/8aXCP/Gl0i7xpdIu8ZWiEf + GVohHx5qKakeaimpHmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8aWyL/ + Glsi/xdRH/8XUR//F1If/xdSH/8XUx//F1Mf/xhUIP8YVCD/GFQg/xhUIP8YVSD/GFUg/xhWIP8YViD/ + GVch/xlXIf8ZWCH/GVgh/xlZIv8ZWSL/GVoi/xlaIv8aWyL/Glsi/xpbI/8aWyP/Glwj/xpcI/8aXSP/ + Gl0j/xteI/8bXiP/HF8krxxfJK8eaimpHmopqR5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Glsi/xpbIv8XUR//F1Ef/xdSH/8XUh//F1Mf/xdTH/8YVCD/GFQg/xhUIP8YVCD/ + GFUg/xhVIP8YViD/GFYg/xlXIf8ZVyH/GVgh/xlYIf8ZWSL/GVki/xlaIv8ZWiL/Glsi/xpbIv8aWyP/ + Glsj/xpcI/8aXCP/Gl0j/xpdI/8bXiP/G14j/xxfJK8cXySvH2sq6B9rKugfayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8aWyT/Glsk/xdQH/8XUB//Hmlg/x5pYP8eamD/Hmpg/xhTIP8YUyD/ + GFQh/xhUIf8YVCH/GFQh/xlVIf8ZVSH/GVYi/xlWIv8ZVyL/GVci/xlYIv8ZWCL/Glkj/xpZI/8aWiP/ + Gloj/xpbJP8aWyT/G1sk/xtbJP8bXCT/G1wk/xtdJf8bXSX/G14l/xteJf8bXyXpG18l6R9rKugfayro + H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/Glsk/xpbJP8XUB//F1Af/x5pYP8eaWD/ + Hmpg/x5qYP8YUyD/GFMg/xhUIf8YVCH/GFQh/xhUIf8ZVSH/GVUh/xlWIv8ZViL/GVci/xlXIv8ZWCL/ + GVgi/xpZI/8aWSP/Gloj/xpaI/8aWyT/Glsk/xtbJP8bWyT/G1wk/xtcJP8bXSX/G10l/xteJf8bXiX/ + G18l6RtfJekgbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8bWyT/G1sk/x5oWv8eaFr/ + JYKy/yWCsv8pk9//KZPf/ymT3/8pk9//JYKu/yWCrv8eZ1T/HmdU/xlVIv8ZVSL/GVYi/xlWIv8ZVyL/ + GVci/xpYI/8aWCP/Glgj/xpYI/8aWSP/Glkj/xtbJP8bWyT/G1sk/xtbJP8bXCT/G1wk/xtdJf8bXSX/ + HF4l/xxeJf8cXyX/HF8l/xxgJv8cYCb/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + G1sk/xtbJP8eaFr/Hmha/yWCsv8lgrL/KZPf/ymT3/8pk9//KZPf/yWCrv8lgq7/HmdU/x5nVP8ZVSL/ + GVUi/xlWIv8ZViL/GVci/xlXIv8aWCP/Glgj/xpYI/8aWCP/Glkj/xpZI/8bWyT/G1sk/xtbJP8bWyT/ + G1wk/xtcJP8bXSX/G10l/xxeJf8cXiX/HF8l/xxfJf8cYCb/HGAm/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/yBuLf8dZUD/HWVA/ySBp/8kgaf/KZTf/ymU3/8upPf/LqT3/y+o/f8vqP3/L6j9/y+o/f8upPf/ + LqT3/ymU3/8plN//JICl/ySApf8cYkL/HGJC/xlXI/8ZVyP/GVgk/xlYJP8aWCT/Glgk/xpZJf8aWSX/ + Glol/xpaJf8bWyX/G1sl/xtcJv8bXCb/G10m/xtdJv8bXib/G14m/xxfJ/8cXyf/HGAn/xxgJ/8gbi3/ + IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/HWVA/x1lQP8kgaf/JIGn/ymU3/8plN//LqT3/y6k9/8vqP3/ + L6j9/y+o/f8vqP3/LqT3/y6k9/8plN//KZTf/ySApf8kgKX/HGJC/xxiQv8ZVyP/GVcj/xlYJP8ZWCT/ + Glgk/xpYJP8aWSX/Glkl/xpaJf8aWiX/G1sl/xtbJf8bXCb/G1wm/xtdJv8bXSb/G14m/xteJv8cXyf/ + HF8n/xxgJ/8cYCf/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/ + IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXEv/yFxL/8kfH7/JHx+/ymR1P8pkdT/L6X2/y+l9v8wqfz/ + MKn8/yybzf8sm83/IG5a/yBuWv8gbFj/IGxY/yyazP8smsz/MKn8/zCp/P8vpfb/L6X2/yqR1P8qkdT/ + IHRx/yB0cf8aWCT/Glgk/xpZJf8aWSX/G1ol/xtaJf8bWyX/G1sl/xtcJv8bXCb/G10m/xtdJv8cXif/ + HF4n/xxfJ/8cXyf/HGAn/xxgJ/8cYSj/HGEo/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/ + IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFxL/8hcS//JHx+/yR8fv8pkdT/ + KZHU/y+l9v8vpfb/MKn8/zCp/P8sm83/LJvN/yBuWv8gblr/IGxY/yBsWP8smsz/LJrM/zCp/P8wqfz/ + L6X2/y+l9v8qkdT/KpHU/yB0cf8gdHH/Glgk/xpYJP8aWSX/Glkl/xtaJf8bWiX/G1sl/xtbJf8bXCb/ + G1wm/xtdJv8bXSb/HF4n/xxeJ/8cXyf/HF8n/xxgJ/8cYCf/HGEo/xxhKP8icS//InEv/yJxL/8icS// + InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//I3Q7/yN0O/8nh6r/ + J4eq/y2f7P8tn+z/MKr8/zCq/P8un9j/Lp/Y/yFyZv8hcmb/GFEi/xhRIv8ZUiL/GVIi/xlTIv8ZUyL/ + GVQj/xlUI/8idGf/InRn/y6f2P8un9j/MKr8/zCq/P8tn+z/LZ/s/yWEo/8lhKP/HF4z/xxeM/8bWiX/ + G1ol/xtbJv8bWyb/HFwm/xxcJv8cXSf/HF0n/xxeJ/8cXif/HV8n/x1fJ/8dYCj/HWAo/x1hKP8dYSj/ + InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS// + InEv/yN0O/8jdDv/J4eq/yeHqv8tn+z/LZ/s/zCq/P8wqvz/Lp/Y/y6f2P8hcmb/IXJm/xhRIv8YUSL/ + GVIi/xlSIv8ZUyL/GVMi/xlUI/8ZVCP/InRn/yJ0Z/8un9j/Lp/Y/zCq/P8wqvz/LZ/s/y2f7P8lhKP/ + JYSj/xxeM/8cXjP/G1ol/xtaJf8bWyb/G1sm/xxcJv8cXCb/HF0n/xxdJ/8cXif/HF4n/x1fJ/8dXyf/ + HWAo/x1gKP8dYSj/HWEo/yx4Ov8seDr/JXMz/yVzM/8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/ + I3Ix/yNyMf8jcjH/JHQ8/yR0PP8pj73/KY+9/zCp+f8wqfn/MKj0/zCo9P8mgYn/JoGJ/xlQJf8ZUCX/ + GFAi/xhQIv8ZUCP/GVAj/xlSI/8ZUiP/GVMk/xlTJP8aVCT/GlQk/xpUJP8aVCT/G1co/xtXKP8nhY3/ + J4WN/zCq9v8wqvb/MKn5/zCp+f8pjr3/KY69/x1fM/8dXzP/HFsn/xxbJ/8cXCf/HFwn/xxdKP8cXSj/ + HV0o/x1dKP8dXyn/HV8p/x1gKf8dYCn/HmEq/x5hKv8seDr/LHg6/yVzM/8lczP/I3Ix/yNyMf8jcjH/ + I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yR0PP8kdDz/KY+9/ymPvf8wqfn/MKn5/zCo9P8wqPT/ + JoGJ/yaBif8ZUCX/GVAl/xhQIv8YUCL/GVAj/xlQI/8ZUiP/GVIj/xlTJP8ZUyT/GlQk/xpUJP8aVCT/ + GlQk/xtXKP8bVyj/J4WN/yeFjf8wqvb/MKr2/zCp+f8wqfn/KY69/ymOvf8dXzP/HV8z/xxbJ/8cWyf/ + HFwn/xxcJ/8cXSj/HF0o/x1dKP8dXSj/HV8p/x1fKf8dYCn/HWAp/x5hKv8eYSr/UpFd/1KRXf9SkV3/ + UpFd/0mLVf9Ji1X/PoRK/z6ESv8zfkD/M35A/yh3Nv8odzb/JHY7/yR2O/8qk8D/KpPA/zGr+/8xq/v/ + Lp3N/y6dzf8dYEL/HWBC/xhOIv8YTiL/GU8i/xlPIv8ZUCP/GVAj/xlRI/8ZUSP/GVIj/xlSI/8aUyT/ + GlMk/xpUJP8aVCT/GlUl/xpVJf8bViX/G1Yl/xtXJf8bVyX/IGhJ/yBoSf8uoNP/LqDT/zGr+/8xq/v/ + KpPA/yqTwP8eYDL/HmAy/x1cKP8dXCj/HV0o/x1dKP8dXin/HV4p/x5fKf8eXyn/HmAq/x5gKv8eYSr/ + HmEq/1KRXf9SkV3/UpFd/1KRXf9Ji1X/SYtV/z6ESv8+hEr/M35A/zN+QP8odzb/KHc2/yR2O/8kdjv/ + KpPA/yqTwP8xq/v/Mav7/y6dzf8unc3/HWBC/x1gQv8YTiL/GE4i/xlPIv8ZTyL/GVAj/xlQI/8ZUSP/ + GVEj/xlSI/8ZUiP/GlMk/xpTJP8aVCT/GlQk/xpVJf8aVSX/G1Yl/xtWJf8bVyX/G1cl/yBoSf8gaEn/ + LqDT/y6g0/8xq/v/Mav7/yqTwP8qk8D/HmAy/x5gMv8dXCj/HVwo/x1dKP8dXSj/HV4p/x1eKf8eXyn/ + Hl8p/x5gKv8eYCr/HmEq/x5hKv9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/ + VpRh/1aUYf9Uprn/VKa5/0m2+/9Jtvv/NZy9/zWcvf9ZfV3/WX1d/2KDYv9ig2L/Y4Ni/2ODYv9jhGL/ + Y4Ri/2OFYv9jhWL/Y4Vi/2OFYv9jhmP/Y4Zj/2OHY/9jh2P/ZIdk/2SHZP9kiGT/ZIhk/2SJZP9kiWT/ + ZIlk/2SJZP9limT/ZYpk/1qFYv9ahWL/MJvC/zCbwv8yrfv/Mq37/yqQqf8qkKn/HVwo/x1cKP8dXSn/ + HV0p/x5eKf8eXin/Hl8p/x5fKf8eYCr/HmAq/x9iK/8fYiv/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/ + VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VKa5/1Smuf9Jtvv/Sbb7/zWcvf81nL3/WX1d/1l9Xf9ig2L/ + YoNi/2ODYv9jg2L/Y4Ri/2OEYv9jhWL/Y4Vi/2OFYv9jhWL/Y4Zj/2OGY/9jh2P/Y4dj/2SHZP9kh2T/ + ZIhk/2SIZP9kiWT/ZIlk/2SJZP9kiWT/ZYpk/2WKZP9ahWL/WoVi/zCbwv8wm8L/Mq37/zKt+/8qkKn/ + KpCp/x1cKP8dXCj/HV0p/x1dKf8eXin/Hl4p/x5fKf8eXyn/HmAq/x5gKv8fYiv/H2Ir/1iXZf9Yl2X/ + WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/WJdl/1iXZf9bn4j/W5+I/2LA+v9iwPr/XrHN/16xzf/O1Mb/ + ztTG/9fZzf/X2c3/xMq6/8TKuv+/xrT/v8a0/7/Gs/+/xrP/v8az/7/Gs/+/xrP/v8az/7/HtP+/x7T/ + v8e0/7/HtP+/x7T/v8e0/7/HtP+/x7T/v8i0/7/ItP+/yLT/v8i0/7/ItP+/yLT/zdLC/83Swv++ybb/ + vsm2/y6dw/8uncP/Mq36/zKt+v8jdV7/I3Ve/x1eKv8dXir/HV8q/x1fKv8eYCv/HmAr/x5hK/8eYSv/ + HmIs/x5iLP9Yl2X/WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/W5+I/1ufiP9iwPr/ + YsD6/16xzf9esc3/ztTG/87Uxv/X2c3/19nN/8TKuv/Eyrr/v8a0/7/GtP+/xrP/v8az/7/Gs/+/xrP/ + v8az/7/Gs/+/x7T/v8e0/7/HtP+/x7T/v8e0/7/HtP+/x7T/v8e0/7/ItP+/yLT/v8i0/7/ItP+/yLT/ + v8i0/83Swv/N0sL/vsm2/77Jtv8uncP/Lp3D/zKt+v8yrfr/I3Ve/yN1Xv8dXir/HV4q/x1fKv8dXyr/ + HmAr/x5gK/8eYSv/HmEr/x5iLP8eYiz/XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/ + XJpo/2W73/9lu9//Zb/t/2W/7f9UgGb/VIBm//v07f/79O3/X4Jk/1+CZP9Selr/Unpa/1B4WP9QeFj/ + PGpF/zxqRf8gVSv/IFUr/xpRJP8aUST/J1sx/ydbMf8nXDH/J1wx/xtUJv8bVCb/G1Um/xtVJv8bVif/ + G1Yn/xxXJ/8cVyf/HFgo/xxYKP8sZDX/LGQ1//nw5//58Of/IGU+/yBlPv8yquv/Mqrr/zGk1/8xpNf/ + Hl4q/x5eKv8eXyv/Hl8r/x5gK/8eYCv/H2Ar/x9gK/8fYiz/H2Is/1yaaP9cmmj/XJpo/1yaaP9cmmj/ + XJpo/1yaaP9cmmj/XJpo/1yaaP9lu9//Zbvf/2W/7f9lv+3/VIBm/1SAZv/79O3/+/Tt/1+CZP9fgmT/ + Unpa/1J6Wv9QeFj/UHhY/zxqRf88akX/IFUr/yBVK/8aUST/GlEk/ydbMf8nWzH/J1wx/ydcMf8bVCb/ + G1Qm/xtVJv8bVSb/G1Yn/xtWJ/8cVyf/HFcn/xxYKP8cWCj/LGQ1/yxkNf/58Of/+fDn/yBlPv8gZT7/ + Mqrr/zKq6/8xpNf/MaTX/x5eKv8eXir/Hl8r/x5fK/8eYCv/HmAr/x9gK/8fYCv/H2Is/x9iLP9gnWz/ + YJ1s/2CdbP9gnWz/YJ1s/2CdbP9gnWz/YJ1s/2Gjg/9ho4P/acX8/2nF/P9goKH/YKCh/1V6XP9Velz/ + +/Xw//v18P9fg2b/X4Nm/1V9Xv9VfV7/VX1e/1V9Xv9VfV7/VX1e/1R9Xf9UfV3/PGtF/zxrRf+Qp47/ + kKeO/4+mjP+Ppoz/G1Qn/xtUJ/8bVSf/G1Un/xxWKP8cVij/HFgo/xxYKP8cWSn/HFkp/ytiNf8rYjX/ + +vLq//ry6v8dWyr/HVsq/ymIh/8piIf/M7D7/zOw+/8jcFD/I3BQ/x5fLP8eXyz/H2As/x9gLP8fYS3/ + H2Et/yBjLf8gYy3/YJ1s/2CdbP9gnWz/YJ1s/2CdbP9gnWz/YJ1s/2CdbP9ho4P/YaOD/2nF/P9pxfz/ + YKCh/2Cgof9Velz/VXpc//v18P/79fD/X4Nm/1+DZv9VfV7/VX1e/1V9Xv9VfV7/VX1e/1V9Xv9UfV3/ + VH1d/zxrRf88a0X/kKeO/5Cnjv+Ppoz/j6aM/xtUJ/8bVCf/G1Un/xtVJ/8cVij/HFYo/xxYKP8cWCj/ + HFkp/xxZKf8rYjX/K2I1//ry6v/68ur/HVsq/x1bKv8piIf/KYiH/zOw+/8zsPv/I3BQ/yNwUP8eXyz/ + Hl8s/x9gLP8fYCz/H2Et/x9hLf8gYy3/IGMt/2Ofb/9jn2//Y59v/2Ofb/9jn2//Y59v/2Ofb/9jn2// + Z7O0/2eztP9rxff/a8X3/1mBav9ZgWr/V3xf/1d8X//89vH//Pbx/2KEaf9ihGn/WH5g/1h+YP9Yf2D/ + WH9g/1l/Yf9Zf2H/WYBh/1mAYf9ZgWL/WYFi/6+/rf+vv63/obSe/6G0nv8eVir/HlYq/xxVJ/8cVSf/ + HFYo/xxWKP8cVyj/HFco/x1YKf8dWCn/K2I1/ytiNf/78+z/+/Ps/x5bKv8eWyr/IGY9/yBmPf80sPf/ + NLD3/yuQl/8rkJf/H18s/x9fLP8fYCz/H2As/yBhLf8gYS3/IGIu/yBiLv9jn2//Y59v/2Ofb/9jn2// + Y59v/2Ofb/9jn2//Y59v/2eztP9ns7T/a8X3/2vF9/9ZgWr/WYFq/1d8X/9XfF///Pbx//z28f9ihGn/ + YoRp/1h+YP9YfmD/WH9g/1h/YP9Zf2H/WX9h/1mAYf9ZgGH/WYFi/1mBYv+vv63/r7+t/6G0nv+htJ7/ + HlYq/x5WKv8cVSf/HFUn/xxWKP8cVij/HFco/xxXKP8dWCn/HVgp/ytiNf8rYjX/+/Ps//vz7P8eWyr/ + Hlsq/yBmPf8gZj3/NLD3/zSw9/8rkJf/K5CX/x9fLP8fXyz/H2As/x9gLP8gYS3/IGEt/yBiLv8gYi7/ + Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9tvtf/bb7X/2y81/9svNf/W35i/1t+Yv9bf2P/ + W39j//z48//8+PP/Zods/2aHbP9cgWT/XIFk/1yBZP9cgWT/Zoht/2aIbf+wwK//sMCv/7LCsf+ywrH/ + 2d7U/9ne1P/Z3tT/2d7U/6/Arf+vwK3/m7Ka/5uymv8pXzT/KV80/x1XKP8dVyj/HVgp/x1YKf8rYzb/ + K2M2//v17v/79e7/Hlwr/x5cK/8eXSv/Hl0r/zGjy/8xo8v/MKLG/zCixv8fYCz/H2As/yBhLf8gYS3/ + IGIt/yBiLf8gYy7/IGMu/2ejc/9no3P/Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9no3P/bb7X/22+1/9svNf/ + bLzX/1t+Yv9bfmL/W39j/1t/Y//8+PP//Pjz/2aHbP9mh2z/XIFk/1yBZP9cgWT/XIFk/2aIbf9miG3/ + sMCv/7DAr/+ywrH/ssKx/9ne1P/Z3tT/2d7U/9ne1P+vwK3/r8Ct/5uymv+bspr/KV80/ylfNP8dVyj/ + HVco/x1YKf8dWCn/K2M2/ytjNv/79e7/+/Xu/x5cK/8eXCv/Hl0r/x5dK/8xo8v/MaPL/zCixv8wosb/ + H2As/x9gLP8gYS3/IGEt/yBiLf8gYi3/IGMu/yBjLv9qpXf/aqV3/2qld/9qpXf/aqV3/2qld/9qpXf/ + aqV3/3HG7P9xxuz/bLO//2yzv/9egGX/XoBl/16BZf9egWX//fn1//359f9oiW//aIlv/16DZ/9eg2f/ + XoNn/16DZ/9oinD/aIpw/7HBsf+xwbH/s8Oz/7PDs//b4Nb/2+DW/9vg1v/b4Nb/tMS0/7TEtP+yw7L/ + ssOy/1J+XP9Sflz/IFos/yBaLP8dWCr/HVgq/ytiNv8rYjb//Pbw//z28P8eWyz/Hlss/x5cLP8eXCz/ + Lpiq/y6Yqv80reX/NK3l/x9fLf8fXy3/H2Au/x9gLv8gYS7/IGEu/yBjL/8gYy//aqV3/2qld/9qpXf/ + aqV3/2qld/9qpXf/aqV3/2qld/9xxuz/ccbs/2yzv/9ss7//XoBl/16AZf9egWX/XoFl//359f/9+fX/ + aIlv/2iJb/9eg2f/XoNn/16DZ/9eg2f/aIpw/2iKcP+xwbH/scGx/7PDs/+zw7P/2+DW/9vg1v/b4Nb/ + 2+DW/7TEtP+0xLT/ssOy/7LDsv9Sflz/Un5c/yBaLP8gWiz/HVgq/x1YKv8rYjb/K2I2//z28P/89vD/ + Hlss/x5bLP8eXCz/Hlws/y6Yqv8umKr/NK3l/zSt5f8fXy3/H18t/x9gLv8fYC7/IGEu/yBhLv8gYy// + IGMv/22oev9tqHr/bah6/22oev9tqHr/bah6/22pf/9tqX//dMz7/3TM+/9rqaj/a6mo/2CCaP9ggmj/ + YINo/2CDaP/9+vb//fr2/2uLcv9ri3L/YYVp/2GFaf9ihmn/YoZp/2KGav9ihmr/Yodq/2KHav9jiGv/ + Y4hr/7XFtf+1xbX/tcW2/7XFtv9jimv/Y4pr/2OKbP9jimz/Y4ts/2OLbP9ahGT/WoRk/yxjOP8sYzj/ + K2I3/ytiN//89/L//Pfy/x5cLP8eXCz/Hl0s/x5dLP8rioj/K4qI/zW0+f81tPn/IWQ1/yFkNf8gYS7/ + IGEu/yBiL/8gYi//IWMv/yFjL/9tqHr/bah6/22oev9tqHr/bah6/22oev9tqX//bal//3TM+/90zPv/ + a6mo/2upqP9ggmj/YIJo/2CDaP9gg2j//fr2//369v9ri3L/a4ty/2GFaf9hhWn/YoZp/2KGaf9ihmr/ + YoZq/2KHav9ih2r/Y4hr/2OIa/+1xbX/tcW1/7XFtv+1xbb/Y4pr/2OKa/9jimz/Y4ps/2OLbP9ji2z/ + WoRk/1qEZP8sYzj/LGM4/ytiN/8rYjf//Pfy//z38v8eXCz/Hlws/x5dLP8eXSz/K4qI/yuKiP81tPn/ + NbT5/yFkNf8hZDX/IGEu/yBhLv8gYi//IGIv/yFjL/8hYy//cat+/3Grfv9xq37/cat+/3Grfv9xq37/ + cq+M/3KvjP94zfv/eM37/22loP9tpaD/ZIRr/2SEa/9khWv/ZIVr//36+P/9+vj/bo51/26Odf9liG3/ + ZYht/2WIbf9liG3/ZYlt/2WJbf9mim3/Zopt/2aKbv9mim7/tcW2/7XFtv+1xbb/tcW2/2eMb/9njG// + Z41v/2eNb/9njm//Z45v/2eOcP9njnD/Zo5u/2aObv9Me1b/THtW//z49P/8+PT/Hlss/x5bLP8fXSz/ + H10s/yqDd/8qg3f/NrX5/za1+f8jbUf/I21H/yBhLv8gYS7/IWIv/yFiL/8hYzD/IWMw/3Grfv9xq37/ + cat+/3Grfv9xq37/cat+/3KvjP9yr4z/eM37/3jN+/9tpaD/baWg/2SEa/9khGv/ZIVr/2SFa//9+vj/ + /fr4/26Odf9ujnX/ZYht/2WIbf9liG3/ZYht/2WJbf9liW3/Zopt/2aKbf9mim7/Zopu/7XFtv+1xbb/ + tcW2/7XFtv9njG//Z4xv/2eNb/9njW//Z45v/2eOb/9njnD/Z45w/2aObv9mjm7/THtW/0x7Vv/8+PT/ + /Pj0/x5bLP8eWyz/H10s/x9dLP8qg3f/KoN3/za1+f82tfn/I21H/yNtR/8gYS7/IGEu/yFiL/8hYi// + IWMw/yFjMP90rYH/dK2B/3Stgf90rYH/dK2B/3Stgf91spP/dbKT/3vP+/97z/v/cKWe/3Clnv9nhm7/ + Z4Zu/2eHb/9nh2///fr4//36+P9zknn/c5J5/2iKb/9oim//aIpw/2iKcP9pi3H/aYtx/2mMcf9pjHH/ + aYxx/2mMcf9ylHn/cpR5/3KUev9ylHr/aY5y/2mOcv9qj3P/ao9z/2qQc/9qkHP/apBz/2qQc/9rkXP/ + a5Fz/3WZff91mX3//fr3//369/8jXjD/I14w/x9cLf8fXC3/KYNz/ymDc/82tvn/Nrb5/yVxTf8lcU3/ + IWEv/yFhL/8hYjD/IWIw/yFkMf8hZDH/dK2B/3Stgf90rYH/dK2B/3Stgf90rYH/dbKT/3Wyk/97z/v/ + e8/7/3Clnv9wpZ7/Z4Zu/2eGbv9nh2//Z4dv//36+P/9+vj/c5J5/3OSef9oim//aIpv/2iKcP9oinD/ + aYtx/2mLcf9pjHH/aYxx/2mMcf9pjHH/cpR5/3KUef9ylHr/cpR6/2mOcv9pjnL/ao9z/2qPc/9qkHP/ + apBz/2qQc/9qkHP/a5Fz/2uRc/91mX3/dZl9//369//9+vf/I14w/yNeMP8fXC3/H1wt/ymDc/8pg3P/ + Nrb5/za2+f8lcU3/JXFN/yFhL/8hYS//IWIw/yFiMP8hZDH/IWQx/3evhP93r4T/d6+E/3evhP93r4T/ + d6+E/3i1l/94tZf/ftD7/37Q+/9ypZ3/cqWd/2qJcf9qiXH/aolx/2qJcf/Z39j/2d/Y/+Hm4P/h5uD/ + 2N7W/9je1v/Y3tb/2N7W/9jf1v/Y39b/2N/W/9jf1v/Y39f/2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/ + 2N/X/9jf1//Y39f/2ODX/9jg1//Y4Nf/2ODX/9jg1//Y4Nf/4efh/+Hn4f/Z4tn/2eLZ/1+Kaf9fimn/ + JmE0/yZhNP8pgG3/KYBt/ze3+f83t/n/JnJS/yZyUv8hYTD/IWEw/yFiMP8hYjD/ImMx/yJjMf93r4T/ + d6+E/3evhP93r4T/d6+E/3evhP94tZf/eLWX/37Q+/9+0Pv/cqWd/3Klnf9qiXH/aolx/2qJcf9qiXH/ + 2d/Y/9nf2P/h5uD/4ebg/9je1v/Y3tb/2N7W/9je1v/Y39b/2N/W/9jf1v/Y39b/2N/X/9jf1//Y39f/ + 2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/2N/X/9jg1//Y4Nf/2ODX/9jg1//Y4Nf/2ODX/+Hn4f/h5+H/ + 2eLZ/9ni2f9fimn/X4pp/yZhNP8mYTT/KYBt/ymAbf83t/n/N7f5/yZyUv8mclL/IWEw/yFhMP8hYjD/ + IWIw/yJjMf8iYzH/erKI/3qyiP96soj/erKI/3qyiP96soj/e7id/3u4nf+A0vv/gNL7/3Olm/9zpZv/ + bIt0/2yLdP9ti3X/bYt1/3KQev9ykHr/mK6d/5iunf+dsqH/nbKh/7fGuf+3xrn/6+7p/+vu6f+etKL/ + nrSi/560ov+etKL/nrWi/561ov+etaP/nrWj/561o/+etaP/nrak/562pP/r7ur/6+7q/7fJu/+3ybv/ + n7ek/5+3pP+atKD/mrSg/3Wafv91mn7/cZd6/3GXev9mkHD/ZpBw/zWFcP81hXD/N7j5/ze4+f8ndlj/ + J3ZY/yFhMf8hYTH/IWIx/yFiMf8iZjP/ImYz/3qyiP96soj/erKI/3qyiP96soj/erKI/3u4nf97uJ3/ + gNL7/4DS+/9zpZv/c6Wb/2yLdP9si3T/bYt1/22Ldf9ykHr/cpB6/5iunf+Yrp3/nbKh/52yof+3xrn/ + t8a5/+vu6f/r7un/nrSi/560ov+etKL/nrSi/561ov+etaL/nrWj/561o/+etaP/nrWj/562pP+etqT/ + 6+7q/+vu6v+3ybv/t8m7/5+3pP+ft6T/mrSg/5q0oP91mn7/dZp+/3GXev9xl3r/ZpBw/2aQcP81hXD/ + NYVw/ze4+f83uPn/J3ZY/yd2WP8hYTH/IWEx/yFiMf8hYjH/ImYz/yJmM/9+tYv/frWL/361i/9+tYv/ + frWL/361i/9/u6P/f7uj/4TT+/+E0/v/d6Wa/3elmv9wjXf/cI13/3COeP9wjnj/cI94/3CPeP9wj3n/ + cI95/3GQef9xkHn/kamX/5Gpl//s8Oz/7PDs/3KSev9yknr/cpN6/3KTev9ylHr/cpR6/3KUe/9ylHv/ + c5V7/3OVe/9zlnz/c5Z8/+zw7P/s8Oz/k66Z/5Oumf90mHz/dJh8/3SYff90mH3/dJl9/3SZff90mX7/ + dJl+/3Safv90mn7/c6mZ/3Opmf9EvPj/RLz4/yh4Xf8oeF3/IWEx/yFhMf8iZTP/ImUz/yyAQf8sgEH/ + frWL/361i/9+tYv/frWL/361i/9+tYv/f7uj/3+7o/+E0/v/hNP7/3elmv93pZr/cI13/3CNd/9wjnj/ + cI54/3CPeP9wj3j/cI95/3CPef9xkHn/cZB5/5Gpl/+RqZf/7PDs/+zw7P9yknr/cpJ6/3KTev9yk3r/ + cpR6/3KUev9ylHv/cpR7/3OVe/9zlXv/c5Z8/3OWfP/s8Oz/7PDs/5Oumf+Trpn/dJh8/3SYfP90mH3/ + dJh9/3SZff90mX3/dJl+/3SZfv90mn7/dJp+/3Opmf9zqZn/RLz4/0S8+P8oeF3/KHhd/yFhMf8hYTH/ + ImUz/yJlM/8sgEH/LIBB/4G3jv+Bt47/gbeO/4G3jv+Bt47/gbeO/4K+p/+Cvqf/h9T7/4fU+/95pJj/ + eaSY/3OPev9zj3r/c5B6/3OQev9zkXr/c5F6/3SSe/90knv/dJJ7/3SSe/94loD/eJaA/+3w7P/t8Oz/ + 1N7W/9Te1v+/zcL/v83C/7/Nwv+/zcL/v87C/7/Owv+/zsL/v87C/9Xf1//V39f/7fDt/+3w7f96nIP/ + epyD/3aZf/92mX//d5p//3eaf/93m3//d5t//3ebgP93m4D/d5yB/3ecgf98rp3/fK6d/37R+v9+0fr/ + M4Fo/zOBaP8iZDL/ImQy/y2CQf8tgkH/L4lF/y+JRf+Bt47/gbeO/4G3jv+Bt47/gbeO/4G3jv+Cvqf/ + gr6n/4fU+/+H1Pv/eaSY/3mkmP9zj3r/c496/3OQev9zkHr/c5F6/3ORev90knv/dJJ7/3SSe/90knv/ + eJaA/3iWgP/t8Oz/7fDs/9Te1v/U3tb/v83C/7/Nwv+/zcL/v83C/7/Owv+/zsL/v87C/7/Owv/V39f/ + 1d/X/+3w7f/t8O3/epyD/3qcg/92mX//dpl//3eaf/93mn//d5t//3ebf/93m4D/d5uA/3ecgf93nIH/ + fK6d/3yunf9+0fr/ftH6/zOBaP8zgWj/ImQy/yJkMv8tgkH/LYJB/y+JRf8viUX/hLmR/4S5kf+EuZH/ + hLmR/4S5kf+EuZH/hcCs/4XArP+J1vv/idb7/32qof99qqH/dpF8/3aRfP92kn3/dpJ9/3aTfv92k37/ + dpN+/3aTfv92lH7/dpR+/3eUfv93lH7/gp6K/4Keiv+1xrn/tca5/8DOw//AzsP/wM/D/8DPw//Az8T/ + wM/E/8DPxP/Az8T/tsi6/7bIuv+Eo4v/hKOL/3mbgv95m4L/eZuC/3mbgv95nIL/eZyC/3mdgv95nYL/ + ep2D/3qdg/96noP/ep6D/4Cypf+AsqX/idb7/4nW+/90rJz/dKyc/zSGSv80hkr/MIpH/zCKR/8wikf/ + MIpH/4S5kf+EuZH/hLmR/4S5kf+EuZH/hLmR/4XArP+FwKz/idb7/4nW+/99qqH/faqh/3aRfP92kXz/ + dpJ9/3aSff92k37/dpN+/3aTfv92k37/dpR+/3aUfv93lH7/d5R+/4Keiv+Cnor/tca5/7XGuf/AzsP/ + wM7D/8DPw//Az8P/wM/E/8DPxP/Az8T/wM/E/7bIuv+2yLr/hKOL/4Sji/95m4L/eZuC/3mbgv95m4L/ + eZyC/3mcgv95nYL/eZ2C/3qdg/96nYP/ep6D/3qeg/+AsqX/gLKl/4nW+/+J1vv/dKyc/3SsnP80hkr/ + NIZK/zCKR/8wikf/MIpH/zCKR/+HvJX/h7yV/4e8lf+HvJX/h7yV/4e8lf+Iv6D/iL+g/4zW9f+M1vX/ + jdj6/43Y+v+KzNv/iszb/4W7u/+Fu7v/gKmc/4CpnP97mIP/e5iD/3qXgv96l4L/e5eC/3uXgv97mIL/ + e5iC/3uYgv97mIL/e5mD/3uZg/97mYP/e5mD/3yag/98moP/fJuE/3ybhP98nIT/fJyE/3ychf98nIX/ + fJ2F/3ydhf99nYX/fZ2F/36gh/9+oIf/gq6g/4KuoP+Gv7z/hr+8/4rN3P+Kzdz/jdj6/43Y+v+N1vX/ + jdb1/4e+of+HvqH/drKF/3ayhf8zjEr/M4xK/zGLSP8xi0j/h7yV/4e8lf+HvJX/h7yV/4e8lf+HvJX/ + iL+g/4i/oP+M1vX/jNb1/43Y+v+N2Pr/iszb/4rM2/+Fu7v/hbu7/4CpnP+AqZz/e5iD/3uYg/96l4L/ + epeC/3uXgv97l4L/e5iC/3uYgv97mIL/e5iC/3uZg/97mYP/e5mD/3uZg/98moP/fJqD/3ybhP98m4T/ + fJyE/3ychP98nIX/fJyF/3ydhf98nYX/fZ2F/32dhf9+oIf/fqCH/4KuoP+CrqD/hr+8/4a/vP+Kzdz/ + is3c/43Y+v+N2Pr/jdb1/43W9f+HvqH/h76h/3ayhf92soX/M4xK/zOMSv8xi0j/MYtI/4q+mP+Kvpj/ + ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/isGh/4rBof+NysX/jcrF/47T5P+O0+T/j9n6/4/Z+v+P2fr/ + j9n6/4/Y+P+P2Pj/jtTs/47U7P+Nz93/jc/d/4vHzv+Lx87/isTH/4rEx/+JwcH/icHB/4m+vP+Jvrz/ + ib+8/4m/vP+JwsL/icLC/4rEx/+KxMf/i8nP/4vJz/+Nz93/jc/d/47U7P+O1Oz/j9j4/4/Y+P+P2fr/ + j9n6/4/Z+v+P2fr/jtPm/47T5v+My8j/jMvI/4vAof+LwKH/ir6Y/4q+mP+Kvpj/ir6Y/2ereP9nq3j/ + Mo1J/zKNSf+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/4rBof+KwaH/jcrF/43Kxf+O0+T/ + jtPk/4/Z+v+P2fr/j9n6/4/Z+v+P2Pj/j9j4/47U7P+O1Oz/jc/d/43P3f+Lx87/i8fO/4rEx/+KxMf/ + icHB/4nBwf+Jvrz/ib68/4m/vP+Jv7z/icLC/4nCwv+KxMf/isTH/4vJz/+Lyc//jc/d/43P3f+O1Oz/ + jtTs/4/Y+P+P2Pj/j9n6/4/Z+v+P2fr/j9n6/47T5v+O0+b/jMvI/4zLyP+LwKH/i8Ch/4q+mP+Kvpj/ + ir6Y/4q+mP9nq3j/Z6t4/zKNSf8yjUn/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwJv/jcCb/43Am/+NwqP/jcKj/4/Iuf+PyLn/j83J/4/Nyf+Q0dn/kNHZ/5HV6P+R1ej/ + kdfy/5HX8v+R2fb/kdn2/5La+v+S2vr/ktr7/5La+/+S2vv/ktr7/5La+v+S2vr/kdn2/5HZ9v+R1/L/ + kdfy/5HV6P+R1ej/kNHY/5DR2P+PzMj/j8zI/4/Iuf+PyLn/jcKj/43Co/+NwJv/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/9UoWn/VKFp/43Am/+NwJv/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcKj/43Co/+PyLn/j8i5/4/Nyf+Pzcn/ + kNHZ/5DR2f+R1ej/kdXo/5HX8v+R1/L/kdn2/5HZ9v+S2vr/ktr6/5La+/+S2vv/ktr7/5La+/+S2vr/ + ktr6/5HZ9v+R2fb/kdfy/5HX8v+R1ej/kdXo/5DR2P+Q0dj/j8zI/4/MyP+PyLn/j8i5/43Co/+NwqP/ + jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/VKFp/1Shaf+MwJrx + jMCa8ZDCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKe/5DCnv+QxKP/ + kMSj/5DEov+QxKL/kMKe/5DCnv+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/43BmvGNwZrxjMCa8YzAmvGQwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnv+Qwp7/kMSj/5DEo/+QxKL/kMSi/5DCnv+Qwp7/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+NwZrxjcGa8Ya+l8SGvpfElMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/j8Kdxo/CncaGvpfEhr6XxJTFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/4/CncaPwp3G + fLuPKXy7jymTxqD1k8ag9ZbHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + mMil9pjIpfaZx6gymceoMny7jyl8u48pk8ag9ZPGoPWWx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5jIpfaYyKX2mceoMpnHqDIAAAAAAAAAAHy7jyl8u48pjMKbxYzCm8WWx6Py + lsej8pnJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5rJp/OayafzlsaiyZbGosmbyKozm8iqMwAAAAAAAAAAAAAAAAAAAAB8u48p + fLuPKYzCm8WMwpvFlsej8pbHo/KZyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+ayafzmsmn85bGosmWxqLJm8iqM5vIqjMAAAAA + AAAAAMAAAAAAAAADwAAAAAAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAAAAAA8AAAAAAAAADKAAAADAAAABgAAAAAQAgAAAAAAAAJAAA + EwsAABMLAAAAAAAAAAAAAAAAAAAbZCQOG2QkHB1nJqkcZybIHGcm5xxnJv8cZyb/HGcm/xxnJv8cZyb/ + HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xhaIf8XViD/ + FlIe/xdTH/8XVB//F1Qf/xdUH/8XVSD/F1Yg/xdWIP8YVyD/GFcg/xhYIP8YWSH/GFkh/xhaIf8ZWiH/ + GVoh/xhcIukZXCLMGlwirxlaIR8ZWiEQAAAAABtkJA4dZyZJHWgnhR1oJ9QdaCfkHWgn8x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8cZCX/ + G2Ek/xhWIP8XVB//F1If/xdTH/8XVB//F1Qf/xhUIP8YVSD/GFYg/xhWIP8YVyD/GFch/xlYIf8ZWSH/ + GVkh/xlaIv8ZWiL/GVsi/xlbIvQZXCLmGlwj1xpdIocaXCJLGVohEBtkJBwdaCeFHWgn7R1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8bYSX/GVoi/xdRHv8XUh//F1If/xdTH/8XVB//F1Qf/xhUIP8YVSD/GFUg/xhWIP8YVyH/ + GFch/xlYIf8ZWSH/GVkh/xlaIv8ZWyL/GVsi/xlbIv8aXCP/Glwj/xpdIu8aXSKHGVohHx5qKakeaijU + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Hmoo/xpbIv8ZViH/F1Ef/xdSH/8XUx//F1Mf/xhUIP8YVCD/GFQg/xhVIP8YViD/ + GFYg/xlXIf8ZWCH/GVgh/xlZIv8ZWiL/GVoi/xpbIv8aWyP/Glsj/xpcI/8aXSP/Gl0j/xteI/8bXiPX + HF8krx9rKskfaynkH2sp/x9rKf8fayn/H2sp/x9rKf8fayn/H2sp/x9rKf8fayn/H2sp/x9rKf8fayn/ + H2sp/x9rKf8fayn/H2sp/x9rKf8dZyj/HGMm/xlWIf8aWTD/G11A/xteQP8ZWTD/GFMg/xhUIf8YVCH/ + GFQh/xlVIf8ZViH/GVYh/xlXIv8ZWCL/GVgi/xpZI/8aWiP/Gloj/xpbI/8aWyP/G1sk/xtcJP8bXST/ + G10k/xteJP8bXiTmG18lzB9rKugfayr0H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8dYyf/Glsk/xdQH/8bXUD/Hmlg/x5qYP8bX0D/ + GFMg/xhUIf8YVCH/GFQh/xlVIf8ZViL/GVYi/xlXIv8ZWCL/GVgi/xpZI/8aWiP/Gloj/xpbJP8bWyT/ + G1sk/xtcJP8bXSX/G10l/xteJf8bXiX0G18l6SBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/xtbJP8dYj//Hmha/yWCsv8ni8n/ + KZPf/ymT3/8ni8f/JYKu/x5nVP8cXjv/GVUi/xlWIv8ZVyL/GVci/xpYI/8aWCP/Glgj/xpZI/8bWiT/ + G1sk/xtbJP8bXCT/G1wk/xtdJf8cXiX/HF4l/xxfJf8cYCb/HGAm/yBuLP8gbiz/IG4s/yBuLP8gbiz/ + IG4s/yBuLP8gbiz/IG4s/yBuLP8gbiz/IG4s/yBuLP8gbiz/IG4s/yBuLP8fazH/H2k2/yBuZv8idoH/ + JH6d/yqT1f8rmOH/LJ7u/yye7v8rmOD/KpPT/yR+mv8hdH//H2tk/xtcMv8aWir/GVcj/xpYJP8aWCT/ + Glgk/xpZJP8aWiT/G1sl/xtbJf8bXCX/G1wl/xtdJv8bXib/HF4m/xxfJv8cYCb/HGAn/yBuLf8gbi3/ + IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8fajf/ + HWVA/ySBp/8ni8P/KZTf/y6k9/8vpvr/L6j9/y+o/f8vpvr/LqT3/ymU3/8nisL/JICl/xxiQv8bXTP/ + GVcj/xlYJP8aWCT/Glgk/xpZJf8aWiX/Glol/xtbJf8bXCb/G1wm/xtdJv8bXib/G14m/xxfJ/8cYCf/ + HGAn/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcS// + IXEv/yR8fv8nh6n/KZHU/y+l9v8wp/n/MKn8/yybzf8mhZT/IG5a/yBsWP8mg5L/LJrM/zCp/P8wp/n/ + L6X2/yqR1P8lg6P/IHRx/xpYJP8aWSX/Glkl/xtaJf8bWyX/G1sl/xtcJv8bXSb/G10m/xxeJ/8cXyf/ + HF8n/xxgJ/8cYSj/HGEo/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS// + InEv/yJyNf8jd1H/JHxt/ymOtf8rls//LZ7o/y+i5/8smMz/KY6x/yJ2eP8fa1v/HWA+/x1gPf8ga1r/ + I3d4/ymPsv8smMz/L6Ln/y2e6P8qlMv/J4qv/yBuZP8dZUj/G1ws/xtaJf8bWyX/G1sm/xxcJv8cXSb/ + HF0n/xxeJ/8cXyf/HV8n/x1gKP8dYSj/HWEo/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS// + InEv/yJxL/8icS//InEv/yN0O/8lfnP/J4eq/y2f7P8vpfT/MKr8/y6f2P8oiZ//IXJm/xhRIv8ZUiL/ + GVIi/xlTIv8ZVCP/GVQj/yJ0Z/8oiqD/Lp/Y/zCq/P8vpfT/LZ/s/yWEo/8hcWv/HF4z/xtaJf8bWyb/ + G1sm/xxcJv8cXSf/HF0n/xxeJ/8dXyf/HV8n/x1gKP8dYSj/HWEo/yx4Ov8pdjf/JXMz/yNyMf8jcjH/ + I3Ix/yNyMf8jcjH/I3Ix/yNyMf8kczf/JHQ8/ymPvf8tnNv/MKn5/zCo9P8rlb//JoGJ/xlQJf8ZUCT/ + GFAi/xlQI/8ZUSP/GVIj/xlTJP8aVCT/GlQk/xpUJP8bVib/G1co/yeFjf8smML/MKr2/zCp+f8tnNv/ + KY69/x1fM/8dXS3/HFsn/xxcJ/8cXSj/HF0o/x1dKP8dXin/HV8p/x1gKf8eYSr/HmEq/z+FTP89g0r/ + PIJI/zZ/Q/8zfUD/MXs+/yt4Of8odjb/JnU0/yR0Nv8lfFr/J4R+/y2d3P8uoOD/L6Pj/yeEm/8jdnj/ + H2hW/xlQJP8ZUCP/GVAj/xlRI/8ZUSP/GVIj/xpTJP8aVCT/GlQk/xpVJf8bVib/G1cn/yFuWf8lfHz/ + KImg/y+l5v8uoeH/LZ3c/yR5ev8ga1P/HV4t/x1cKP8dXSj/HV0o/x1eKf8dXin/Hl8p/x5gKv8eYSr/ + HmEq/1KRXf9SkV3/UpFd/0mLVf9EiFD/PoRK/zN+QP8uezv/KHc2/yR2O/8nhX7/KpPA/zGr+/8wpOT/ + Lp3N/x1gQv8bVzL/GE4i/xlPIv8ZUCP/GVAj/xlRI/8ZUiP/GVIj/xpTJP8aVCT/GlQk/xpVJf8bViX/ + G1Yl/xtXJf8eYDf/IGhJ/y6g0/8wpuf/Mav7/yqTwP8kenn/HmAy/x1cKP8dXSj/HV0o/x1eKf8eXyn/ + Hl8p/x5gKv8eYSr/HmEq/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1Smuf9Prtr/ + Sbb7/zWcvf9HjY3/WX1d/2KDYv9jg2L/Y4Ni/2OEYv9jhWL/Y4Vi/2OFYv9jhmP/Y4Zj/2OHY/9kh2T/ + ZIdk/2SIZP9kiWT/ZIlk/2SJZP9limT/ZYpk/1qFYv9FkJL/MJvC/zKt+/8un9L/KpCp/x1cKP8dXSn/ + HV0p/x5eKf8eXyn/Hl8p/x5gKv8fYSv/H2Ir/1eWY/9XlmP/V5Zj/1eWY/9XlmP/V5Zj/1eWY/9YmGz/ + WZp1/1uz2v9Xs9//VLTk/4K4wv+Nsqv/mKuV/5Onjv+Spo3/kaWL/5Gli/+RpYv/kaaL/5Gmi/+Rpov/ + kaeM/5GnjP+Rp4z/kqeM/5KojP+SqIz/kqmM/5KpjP+SqYz/kqmM/5Sskv+Fr6f/d7K8/zCl3/8votj/ + Lp/S/yBpQ/8fYzb/HV4q/x5fKv8eXyr/HmAq/x5hK/8eYSv/H2Is/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/ + WJdl/1iXZf9am3f/W5+I/2LA+v9gueT/XrHN/87Uxv/T18r/19nN/8TKuv/CyLf/v8a0/7/Gs/+/xrP/ + v8az/7/Gs/+/x7T/v8e0/7/HtP+/x7T/v8e0/7/HtP+/yLT/v8i0/7/ItP+/yLT/v8i0/83Swv/Gzrz/ + vsm2/y6dw/8wpd//Mq36/yN1Xv8gakT/HV4q/x1fKv8eYCv/HmAr/x5hK/8eYiz/HmIs/1yaaP9cmmj/ + XJpo/1yaaP9cmmj/XJpo/1yaaP9hq6T/Zbvf/2W/7f9doKr/VIBm//v07f+tu6n/X4Jk/1J6Wv9ReVn/ + UHhY/zxqRf8uYDj/IFUr/xpRJP8hViv/J1sx/ydcMf8hWCz/G1Qm/xtVJv8bVif/G1Yn/xxXJ/8cWCj/ + HFgo/yxkNf+Tqo7/+fDn/yBlPv8piJX/Mqrr/zGk1/8ogYH/Hl4q/x5fK/8eYCv/HmAr/x9gK/8fYSz/ + H2Is/16cav9enGr/Xpxq/16cav9enGr/Xpxq/1+fdv9jr7L/Z8Du/2Owx/9clpT/VX1h//v17/+tvKr/ + X4Nl/1R8XP9Te1z/U3tb/0l0Uv9Bbkv/OmlE/yteNf9DcEr/XIFg/1uBX/87a0P/G1Qn/xtVJ/8bVif/ + HFYo/xxYKP8cWCj/HFkp/yxjNf+Tqo//+vHp/x9gNP8mfXf/Lpm5/zKq6f8piZP/IWc9/x5fLP8eYCz/ + H2As/x9hLP8fYiz/IGMt/2CdbP9gnWz/YJ1s/2CdbP9gnWz/YJ1s/2Gjg/9ltMD/acX8/2Cgof9bjX// + VXpc//v18P+tvKv/X4Nm/1V9Xv9VfV7/VX1e/1V9Xv9VfV7/VH1d/zxrRf9miWr/kKeO/4+mjP9VfVr/ + G1Qn/xtVJ/8cVij/HFYo/xxYKP8cWSn/HFkp/ytiNf+TqpD/+vLq/x1bKv8jcln/KYiH/zOw+/8rkKb/ + I3BQ/x5fLP8fYCz/H2As/x9hLf8gYi3/IGMt/2Ofb/9jn2//Y59v/2Ofb/9jn2//Y59v/2eztP9pvNb/ + a8X3/1mBav9Yf2X/V3xf//z28f+vva3/YoRp/1h+YP9Yf2D/WH9g/1l/Yf9ZgGH/WYBh/1mBYv+EoIj/ + r7+t/6G0nv9ghWT/HlYq/xxVJ/8cVij/HFYo/xxXKP8dWCn/HVgp/ytiNf+Tq5H/+/Ps/x5bKv8fYTT/ + IGY9/zSw9/8woMf/K5CX/x9fLP8fYCz/H2As/yBhLf8gYi7/IGIu/2Whcf9loXH/ZaFx/2Whcf9loXH/ + ZaFx/2q5xv9rvdb/bMHn/1qAZv9af2T/WX5h//z38v+wvq7/ZIZr/1qAYv9agGL/WoBi/2CEZ/9yknj/ + haCI/4aiiv+luKX/xM/B/73Juf+SqpL/Z4ts/1yEYf8/b0f/I1su/x1XKP8dWCn/HVgp/ytjNv+Tq5H/ + +/Tt/x5cK/8fXy//H2I0/zOq4f8wocj/Lpmv/x9gLP8fYCz/IGEt/yBiLf8gYi7/IGMu/2ejc/9no3P/ + Z6Nz/2ejc/9no3P/Z6Nz/22+1/9tvdf/bLzX/1t+Yv9bf2P/W39j//z48/+xwLD/Zods/1yBZP9cgWT/ + XIFk/2aIbf+LpI7/sMCv/7LCsf/G0MP/2d7U/9ne1P/Ez8H/r8Ct/5uymv9iiWf/KV80/x1XKP8dWCn/ + HVgp/ytjNv+TrJL/+/Xu/x5cK/8eXSv/Hl0r/zGjy/8xo8n/MKLG/x9gLP8gYS3/IGEt/yBiLf8gYy7/ + IGMu/2qld/9qpXf/aqV3/2qld/9qpXf/aqV3/3HG7P9vvdb/bLO//16AZf9egWX/XoFl//359f+zwbL/ + aIlv/16DZ/9eg2f/XoNn/2iKcP+NppH/scGx/7PDs//H0sX/2+DW/9vg1v/I0sX/tMS0/7LDsv+CoYf/ + Un5c/yBaLP8fWSv/HVgq/ytiNv+UrJP//Pbw/x5bLP8eXCz/Hlws/y6Yqv8xo8j/NK3l/x9fLf8fYC7/ + H2Au/yBhLv8gYi//IGMv/2ynef9sp3n/bKd5/2ynef9sp3r/bKd7/3PJ9P9vvNT/bK60/1+BZ/9fgmf/ + X4Jn//369v+zwrP/aopx/2CEaP9ghGj/YIVo/2WIbf93ln3/iqSO/4umj/+qvKr/yNPG/8jTxv+qvav/ + jKeQ/4unj/9zlnr/W4Vk/z1vSP8xZj3/JV4x/ytiN/+UrJT//Pfx/x5cLP8eXCz/Hl0s/y2Rmf8xocT/ + NbHv/yBiMf8gYTD/IGEu/yBiL/8gYi//IWMv/22oev9tqHr/bah6/22oev9tqX3/bal//3TM+/9wu9L/ + a6mo/2CCaP9gg2j/YINo//369v+0w7T/a4ty/2GFaf9ihmn/YoZp/2KGav9ih2r/Yodq/2OIa/+Mp5D/ + tcW1/7XFtv+MqJH/Y4pr/2OKbP9ji2z/Y4ts/1qEZP9DdE7/LGM4/ytiN/+UrZX//Pfy/x5cLP8eXSz/ + Hl0s/yuKiP8wn8H/NbT5/yFkNf8hYzL/IGEu/yBiL/8hYy//IWMv/3Grfv9xq37/cat+/3Grfv9yrYX/ + cq+M/3jN+/9zuc7/baWg/2SEa/9khWv/ZIVr//36+P+2xLf/bo51/2WIbf9liG3/ZYht/2WJbf9mim3/ + Zopt/2aKbv+OqJL/tcW2/7XFtv+OqZP/Z4xv/2eNb/9njm//Z45v/2eOcP9njm//Zo5u/0x7Vv+kuqX/ + /Pj0/x5bLP8fXCz/H10s/yqDd/8wnLj/NrX5/yNtR/8iZzv/IGEu/yFiL/8hYzD/IWMw/3OsgP9zrID/ + c6yA/3OsgP9zroj/dLGQ/3rO+/90us3/b6Wf/2aFbf9mhm3/ZoZt//36+P+3xbj/cZB3/2eJbv9niW7/ + Z4lv/2eKb/9ni2//aItv/2iLcP9+nIT/lK2Y/5StmP9+nYT/aI1x/2mOcf9pj3H/aY9x/2mPcv9pj3H/ + aZBx/2GKav+vwrD//fn2/yFdLv8gXS3/H10t/yqDdf8wnLf/Nrb5/yRvSv8iaDz/IWEv/yFiMP8hYzD/ + IWQx/3Stgf90rYH/dK2B/3Stgf91sIr/dbKT/3vP+/92us3/cKWe/2eGbv9nh2//Z4dv//36+P+4xrn/ + c5J5/2iKb/9oinD/aIpw/2mLcf9pjHH/aYxx/2mMcf9ukHX/cpR5/3KUev9ukXb/aY5y/2qPc/9qkHP/ + apBz/2qQc/9rkXP/a5Fz/3WZff+5yrr//fr3/yNeMP8hXS//H1wt/ymDc/8wnbb/Nrb5/yVxTf8jaT7/ + IWEv/yFiMP8hYzH/IWQx/3evhP93r4T/d6+E/3evhP94so7/eLWX/37Q+/94u8z/cqWd/2qJcf9qiXH/ + aolx/9nf2P/d49z/4ebg/9je1v/Y3tb/2N7W/9jf1v/Y39b/2N/W/9jf1//Y39f/2N/X/9jf1//Y39f/ + 2N/X/9jf1//Y4Nf/2ODX/9jg1//Y4Nf/2ODX/+Hn4f/d5d3/2eLZ/1+Kaf9Ddk//JmE0/ymAbf8wnLP/ + N7f5/yZyUv8kakH/IWEw/yFiMP8iYzH/ImMx/3mxhv95sYb/ebGG/3mxhv95tJD/erea/3/R+/95u8z/ + c6Wc/2uKc/9rinP/bIpz/6a4qf+xwbT/vcq//7vIvP/BzcL/yNLI/+Ln4P/O2M7/u8q8/7vKvf+7yr3/ + u8q9/7vKvf+7yr3/u8q9/7vLvv/O2c//4ufh/8jVyf/C0MP/vMy+/77Owf+yxrb/p76s/2iRcv9XhWL/ + RnlS/y+Db/8znbT/N7j5/yd0Vf8ka0P/IWEx/yFiMf8iYzH/ImUy/3qyiP96soj/erKI/3qyiP97tZP/ + e7id/4DS+/96vMv/c6Wb/2yLdP9ti3X/bYt1/3KQev+Fn4z/mK6d/52yof+qvK3/t8a5/+vu6f/F0cb/ + nrSi/560ov+etaL/nrWi/561o/+etaP/nrWj/562pP/F0sf/6+7q/7fJu/+rwLD/n7ek/5q0oP+Ip4// + dZp+/3GXev9slHX/ZpBw/zWFcP82n7X/N7j5/yd2WP8kbEX/IWEx/yFiMf8iZDL/ImYz/361i/9+tYv/ + frWL/361i/9/uJf/f7uj/4TT+/9+vMv/d6Wa/3CNd/9wjnj/cI54/3CPeP9wj3n/cI95/3GQef+BnYj/ + kamX/+zw7P+vwbP/cpJ6/3KTev9ylHr/cpR6/3KUe/9zlXv/c5V7/3OWfP+ww7T/7PDs/5Oumf+Eo4v/ + dJh8/3SYff90mX3/dJl9/3SZfv90mn7/dJp+/3Opmf9cs8n/RLz4/yh4Xf8lbUf/IWEx/yJlM/8nczr/ + LIBB/4C2jf+Ato3/gLaN/4C2jf+AuZn/gb2l/4bU+/9/vMr/eKWZ/3KOef9yj3n/co95/3KQef9ykHr/ + cpF6/3ORev98mIP/haCM/+3w7P/I1Mr/o7io/5mwnv+ZsJ7/mbGe/5mxn/+ZsZ//mbKf/6S7qv/I1cv/ + 7fDt/4eljv9+n4b/dZl+/3aZfv92mn7/dpp+/3aaf/92m3//dpuA/3ism/9sucr/Ycf5/y59Y/8ocEr/ + ImMy/yh0Ov8rfD//LoVD/4G3jv+Bt47/gbeO/4G3jv+Cu5v/gr6n/4fU+/+AvMr/eaSY/3OPev9zkHr/ + c5B6/3ORev90knv/dJJ7/3SSe/92lH7/eJaA/+3w7P/h5+H/1N7W/7/Nwv+/zcL/v83C/7/Owv+/zsL/ + v87C/9Xf1//h6OL/7fDt/3qcg/94m4H/dpl//3eaf/93m3//d5t//3ebgP93nIH/d5yB/3yunf99wMz/ + ftH6/zOBaP8rc03/ImQy/y2CQf8uhkP/L4lF/4S5kf+EuZH/hLmR/4S5kf+FvZ//hcCs/4nW+/+DwM7/ + faqh/3aRfP92kn3/dpJ9/3aTfv92k37/dpN+/3aUfv93lH7/d5R+/4Keiv+csqL/tca5/8DOw//Az8P/ + wM/D/8DPxP/Az8T/wM/E/7bIuv+dtqP/hKOL/3mbgv95m4L/eZuC/3mcgv95nYL/eZ2C/3qdg/96noP/ + ep6D/4Cypf+FxND/idb7/3SsnP9UmXP/NIZK/zCKR/8wikf/MIpH/4a7k/+Gu5P/hruT/4a7k/+GvZ3/ + h8Cm/4vW+P+IzOP/hcHO/4CvrP9/q6T/fqec/3uejf96mof/eZaB/3iWgP95loD/eZaA/3+bhv+LpZL/ + mK+e/560o/+etKP/nrSj/561pP+etaT/nrWk/5myn/+NqZT/gKCI/3uchP97nIT/e5yE/3yehf99oov/ + fqaR/4CuoP+Bsqj/graw/4fF0P+JzuT/i9b4/361n/9pqYP/VZxo/zKLSf8xi0j/MYtI/4e8lf+HvJX/ + h7yV/4e8lf+Ivpv/iL+g/4zW9f+N1/j/jdj6/4rM2/+IxMv/hbu7/4CpnP9+oZD/e5iD/3qXgv97l4L/ + e5eC/3uYgv97mIL/e5iC/3uZg/97mYP/e5mD/3yag/98m4T/fJuE/3ychP98nIX/fJyF/3ydhf99nYX/ + fZ2F/36gh/+Ap5T/gq6g/4a/vP+Ixsz/is3c/43Y+v+N1/j/jdb1/4e+of9/uJP/drKF/zOMSv8yjEn/ + MYtI/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/4rBof+MxrP/jcrF/47T5P+P1u//j9n6/4/Z+v+P2fn/ + j9j4/47U7P+O0uX/jc/d/4vHzv+Lxsv/isTH/4nBwf+JwL//ib68/4m/vP+Jwb//icLC/4rEx/+Lx8v/ + i8nP/43P3f+O0uX/jtTs/4/Y+P+P2fn/j9n6/4/Z+v+P1vD/jtPm/4zLyP+MxrX/i8Ch/4q+mP+Kvpj/ + ir6Y/2ereP9NnGH/Mo1J/4y/mv+Mv5r/jL+a/4y/mv+Mv5r/jL+a/4zBnv+Mw6f/jcWw/47KwP+OzMf/ + js7P/4/R2v+P0t3/j9Ph/4/T4/+P0uP/j9Lj/47P4P+Oz9//js/f/47O3v+Ozd3/jszc/47N3P+Ozd3/ + js7e/47P3/+Oz+D/jtDh/4/S4/+P0uL/j9Pi/4/S4P+P0d3/j9Ha/47Oz/+OzMj/jsrB/43Gsv+Mw6j/ + jMCe/4y/mv+Mv5r/jL+a/3q2iv9fpnH/Q5dZ/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwZ//jcKj/4/Iuf+Py8H/j83J/5DR2f+R0+H/kdXo/5HX8v+R2PT/kdn2/5La+v+S2vv/ + ktr7/5La+/+S2vv/ktr6/5HZ9v+R2PT/kdfy/5HV6P+R0+D/kNHY/4/MyP+PysH/j8i5/43Co/+NwZ// + jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/9xsYL/VKFp/4zAmvGOwZz4kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnv+Qw6H/kMSj/5DEov+Qw6D/kMKe/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Pwpz4jcGa8Ym/mduOwZzt + ksSf/5LEn/+SxJ//ksSf/5LEn/+SxJ//ksSf/5LEn/+SxJ//ksSf/5LEn/+SxJ//ksSf/5LEn/+SxJ// + ksSf/5LEn/+SxJ//ksSf/5LEoP+SxKH/ksWi/5LFov+SxKH/ksSg/5LEn/+SxJ//ksSf/5LEn/+SxJ// + ksSf/5LEn/+SxJ//ksSf/5LEn/+SxJ//ksSf/5LEn/+SxJ//ksSf/5LEn/+SxJ//ksSf/5LEn/+Qw53t + jsGb3Ia+l8SOwp3ilMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+SxJ/jj8Kdxny7jymQxJ6Pk8ag9ZbHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5jIpfaYyKaUmceoMny7jxWNw5xSkMSej5LFoOKUxqLtlsek+ZjIpf+YyKX/ + mMil/5jIpf+YyKX/mMil/5jIpf+YyKX/mMil/5jIpf+YyKX/mMil/5jIpf+YyKX/mMil/5jIpf+YyKX/ + mMil/5jIpf+YyKX/mMil/5jIpf+YyKX/mMil/5jIpf+YyKX/mMil/5jIpf+YyKX/mMil/5jIpf+YyKX/ + mMil/5jIpf+YyKX/mMil/5jIpfmXx6Tvlsej5JnIppWZyKZXmceoGQAAAAB8u48VfLuPKYzCm8WSxZ/c + lsej8pnJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5rJp/OYyKXelsaiyZvIqjObyKoaAAAAAIAAAAAAAQAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAACAAAAAAAEAACgAAAAgAAAAQAAAAAEAIAAAAAAAABAAABMLAAATCwAAAAAAAAAAAAAAAAAA + G2QkHB1nJqkcZybnHGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/ + GFoh/xZSHv8XUx//F1Qf/xdUH/8XViD/F1Yg/xhXIP8YWCD/GFkh/xhaIf8ZWiH/GFwi6RpcIq8ZWiEf + AAAAABtkJBwdaCftHWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/xlaIv8XUR7/F1If/xdTH/8XVB//GFQg/xhVIP8YViD/GFch/xlYIf8ZWSH/GVoi/xlbIv8ZWyL/ + Glwj/xpdIu8ZWiEfHmopqR5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8aWyL/F1Ef/xdSH/8XUx//GFQg/xhUIP8YVSD/GFYg/xlXIf8ZWCH/GVki/xlaIv8aWyL/ + Glsj/xpcI/8aXSP/G14j/xxfJK8fayroH2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/Glsk/xdQH/8eaWD/Hmpg/xhTIP8YVCH/GFQh/xlVIf8ZViL/GVci/xlYIv8aWSP/ + Gloj/xpbJP8bWyT/G1wk/xtdJf8bXiX/G18l6SBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/IG0r/xtbJP8eaFr/JYKy/ymT3/8pk9//JYKu/x5nVP8ZVSL/GVYi/xlXIv8aWCP/ + Glgj/xpZI/8bWyT/G1sk/xtcJP8bXSX/HF4l/xxfJf8cYCb/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/yBuLf8gbi3/IG4t/yBuLf8dZUD/JIGn/ymU3/8upPf/L6j9/y+o/f8upPf/KZTf/ySApf8cYkL/ + GVcj/xlYJP8aWCT/Glkl/xpaJf8bWyX/G1wm/xtdJv8bXib/HF8n/xxgJ/8hcC7/IXAu/yFwLv8hcC7/ + IXAu/yFwLv8hcC7/IXAu/yFwLv8hcS//JHx+/ymR1P8vpfb/MKn8/yybzf8gblr/IGxY/yyazP8wqfz/ + L6X2/yqR1P8gdHH/Glgk/xpZJf8bWiX/G1sl/xtcJv8bXSb/HF4n/xxfJ/8cYCf/HGEo/yJxL/8icS// + InEv/yJxL/8icS//InEv/yJxL/8icS//I3Q7/yeHqv8tn+z/MKr8/y6f2P8hcmb/GFEi/xlSIv8ZUyL/ + GVQj/yJ0Z/8un9j/MKr8/y2f7P8lhKP/HF4z/xtaJf8bWyb/HFwm/xxdJ/8cXif/HV8n/x1gKP8dYSj/ + LHg6/yVzM/8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yR0PP8pj73/MKn5/zCo9P8mgYn/GVAl/xhQIv8ZUCP/ + GVIj/xlTJP8aVCT/GlQk/xtXKP8nhY3/MKr2/zCp+f8pjr3/HV8z/xxbJ/8cXCf/HF0o/x1dKP8dXyn/ + HWAp/x5hKv9SkV3/UpFd/0mLVf8+hEr/M35A/yh3Nv8kdjv/KpPA/zGr+/8unc3/HWBC/xhOIv8ZTyL/ + GVAj/xlRI/8ZUiP/GlMk/xpUJP8aVSX/G1Yl/xtXJf8gaEn/LqDT/zGr+/8qk8D/HmAy/x1cKP8dXSj/ + HV4p/x5fKf8eYCr/HmEq/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1Smuf9Jtvv/NZy9/1l9Xf9ig2L/ + Y4Ni/2OEYv9jhWL/Y4Vi/2OGY/9jh2P/ZIdk/2SIZP9kiWT/ZIlk/2WKZP9ahWL/MJvC/zKt+/8qkKn/ + HVwo/x1dKf8eXin/Hl8p/x5gKv8fYiv/WJdl/1iXZf9Yl2X/WJdl/1iXZf9bn4j/YsD6/16xzf/O1Mb/ + 19nN/8TKuv+/xrT/v8az/7/Gs/+/xrP/v8e0/7/HtP+/x7T/v8e0/7/ItP+/yLT/v8i0/83Swv++ybb/ + Lp3D/zKt+v8jdV7/HV4q/x1fKv8eYCv/HmEr/x5iLP9cmmj/XJpo/1yaaP9cmmj/XJpo/2W73/9lv+3/ + VIBm//v07f9fgmT/Unpa/1B4WP88akX/IFUr/xpRJP8nWzH/J1wx/xtUJv8bVSb/G1Yn/xxXJ/8cWCj/ + LGQ1//nw5/8gZT7/Mqrr/zGk1/8eXir/Hl8r/x5gK/8fYCv/H2Is/2CdbP9gnWz/YJ1s/2CdbP9ho4P/ + acX8/2Cgof9Velz/+/Xw/1+DZv9VfV7/VX1e/1V9Xv9UfV3/PGtF/5Cnjv+Ppoz/G1Qn/xtVJ/8cVij/ + HFgo/xxZKf8rYjX/+vLq/x1bKv8piIf/M7D7/yNwUP8eXyz/H2As/x9hLf8gYy3/Y59v/2Ofb/9jn2// + Y59v/2eztP9rxff/WYFq/1d8X//89vH/YoRp/1h+YP9Yf2D/WX9h/1mAYf9ZgWL/r7+t/6G0nv8eVir/ + HFUn/xxWKP8cVyj/HVgp/ytiNf/78+z/Hlsq/yBmPf80sPf/K5CX/x9fLP8fYCz/IGEt/yBiLv9no3P/ + Z6Nz/2ejc/9no3P/bb7X/2y81/9bfmL/W39j//z48/9mh2z/XIFk/1yBZP9miG3/sMCv/7LCsf/Z3tT/ + 2d7U/6/Arf+bspr/KV80/x1XKP8dWCn/K2M2//v17v8eXCv/Hl0r/zGjy/8wosb/H2As/yBhLf8gYi3/ + IGMu/2qld/9qpXf/aqV3/2qld/9xxuz/bLO//16AZf9egWX//fn1/2iJb/9eg2f/XoNn/2iKcP+xwbH/ + s8Oz/9vg1v/b4Nb/tMS0/7LDsv9Sflz/IFos/x1YKv8rYjb//Pbw/x5bLP8eXCz/Lpiq/zSt5f8fXy3/ + H2Au/yBhLv8gYy//bah6/22oev9tqHr/bal//3TM+/9rqaj/YIJo/2CDaP/9+vb/a4ty/2GFaf9ihmn/ + YoZq/2KHav9jiGv/tcW1/7XFtv9jimv/Y4ps/2OLbP9ahGT/LGM4/ytiN//89/L/Hlws/x5dLP8rioj/ + NbT5/yFkNf8gYS7/IGIv/yFjL/9xq37/cat+/3Grfv9yr4z/eM37/22loP9khGv/ZIVr//36+P9ujnX/ + ZYht/2WIbf9liW3/Zopt/2aKbv+1xbb/tcW2/2eMb/9njW//Z45v/2eOcP9mjm7/THtW//z49P8eWyz/ + H10s/yqDd/82tfn/I21H/yBhLv8hYi//IWMw/3Stgf90rYH/dK2B/3Wyk/97z/v/cKWe/2eGbv9nh2// + /fr4/3OSef9oim//aIpw/2mLcf9pjHH/aYxx/3KUef9ylHr/aY5y/2qPc/9qkHP/apBz/2uRc/91mX3/ + /fr3/yNeMP8fXC3/KYNz/za2+f8lcU3/IWEv/yFiMP8hZDH/d6+E/3evhP93r4T/eLWX/37Q+/9ypZ3/ + aolx/2qJcf/Z39j/4ebg/9je1v/Y3tb/2N/W/9jf1v/Y39f/2N/X/9jf1//Y39f/2N/X/9jg1//Y4Nf/ + 2ODX/+Hn4f/Z4tn/X4pp/yZhNP8pgG3/N7f5/yZyUv8hYTD/IWIw/yJjMf96soj/erKI/3qyiP97uJ3/ + gNL7/3Olm/9si3T/bYt1/3KQev+Yrp3/nbKh/7fGuf/r7un/nrSi/560ov+etaL/nrWj/561o/+etqT/ + 6+7q/7fJu/+ft6T/mrSg/3Wafv9xl3r/ZpBw/zWFcP83uPn/J3ZY/yFhMf8hYjH/ImYz/361i/9+tYv/ + frWL/3+7o/+E0/v/d6Wa/3CNd/9wjnj/cI94/3CPef9xkHn/kamX/+zw7P9yknr/cpN6/3KUev9ylHv/ + c5V7/3OWfP/s8Oz/k66Z/3SYfP90mH3/dJl9/3SZfv90mn7/c6mZ/0S8+P8oeF3/IWEx/yJlM/8sgEH/ + gbeO/4G3jv+Bt47/gr6n/4fU+/95pJj/c496/3OQev9zkXr/dJJ7/3SSe/94loD/7fDs/9Te1v+/zcL/ + v83C/7/Owv+/zsL/1d/X/+3w7f96nIP/dpl//3eaf/93m3//d5uA/3ecgf98rp3/ftH6/zOBaP8iZDL/ + LYJB/y+JRf+EuZH/hLmR/4S5kf+FwKz/idb7/32qof92kXz/dpJ9/3aTfv92k37/dpR+/3eUfv+Cnor/ + tca5/8DOw//Az8P/wM/E/8DPxP+2yLr/hKOL/3mbgv95m4L/eZyC/3mdgv96nYP/ep6D/4Cypf+J1vv/ + dKyc/zSGSv8wikf/MIpH/4e8lf+HvJX/h7yV/4i/oP+M1vX/jdj6/4rM2/+Fu7v/gKmc/3uYg/96l4L/ + e5eC/3uYgv97mIL/e5mD/3uZg/98moP/fJuE/3ychP98nIX/fJ2F/32dhf9+oIf/gq6g/4a/vP+Kzdz/ + jdj6/43W9f+HvqH/drKF/zOMSv8xi0j/ir6Y/4q+mP+Kvpj/ir6Y/4rBof+NysX/jtPk/4/Z+v+P2fr/ + j9j4/47U7P+Nz93/i8fO/4rEx/+JwcH/ib68/4m/vP+JwsL/isTH/4vJz/+Nz93/jtTs/4/Y+P+P2fr/ + j9n6/47T5v+My8j/i8Ch/4q+mP+Kvpj/Z6t4/zKNSf+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/ + jcKj/4/Iuf+Pzcn/kNHZ/5HV6P+R1/L/kdn2/5La+v+S2vv/ktr7/5La+v+R2fb/kdfy/5HV6P+Q0dj/ + j8zI/4/Iuf+NwqP/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/VKFp/4zAmvGQwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKe/5DEo/+QxKL/kMKe/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+NwZrxhr6XxJTFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/4/CncZ8u48p + k8ag9ZbHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+YyKX2 + mceoMgAAAAB8u48pjMKbxZbHo/KZyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+ayafz + lsaiyZvIqjMAAAAAgAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAIAAAAEoAAAAEAAAACAAAAABACAAAAAAAAAEAAATCwAAEwsAAAAAAAAAAAAA + HWcmSR1oJ+QdaCf/HWgn/x1oJ/8daCf/HWgn/xxkJf8XVB//F1Qf/xhVIP8YVyD/GVkh/xlaIv8ZXCLm + GlwiSx9rKeQfayn/H2sp/x9rKf8fayn/H2sp/x1nKP8aWTD/GVkw/xhUIf8ZViH/GVgi/xpaI/8aWyP/ + G10k/xteJOYgbiz/IG4s/yBuLP8gbiz/IG4s/x9rMf8idoH/K5jh/yuY4P8hdH//Gloq/xpYJP8aWiT/ + G1wl/xteJv8cYCb/InEv/yJxL/8icS//InEv/yN3Uf8rls//LJjM/x9rW/8ga1r/LJjM/yqUy/8dZUj/ + G1sl/xxdJv8cXyf/HWEo/z2DSv8zfUD/KHY2/yV8Wv8uoOD/I3Z4/xlQI/8ZUSP/GlQk/xtWJv8lfHz/ + LqHh/yBrU/8dXSj/HV4p/x5hKv9XlmP/V5Zj/1iYbP9Xs9//jbKr/5Kmjf+RpYv/kaaL/5GnjP+SqIz/ + kqmM/4Wvp/8votj/H2M2/x5fKv8eYSv/Xpxq/16cav9jr7L/XJaU/628qv9Te1z/QW5L/0NwSv87a0P/ + G1Yn/xxYKP+Tqo//Jn13/ymJk/8eYCz/H2Is/2Whcf9loXH/a73W/1p/ZP+wvq7/WoBi/3KSeP+luKX/ + kqqS/z9vR/8dWCn/k6uR/x9fL/8wocj/H2As/yBiLv9sp3n/bKd6/2+81P9fgmf/s8Kz/2CEaP93ln3/ + qryq/6q9q/9zlnr/MWY9/5SslP8eXCz/MaHE/yBhMP8gYi//c6yA/3OuiP90us3/ZoZt/7fFuP9niW7/ + Z4tv/36chP9+nYT/aY9x/2mPcf+vwrD/IF0t/zCct/8iaDz/IWMw/3mxhv95tJD/ebvM/2uKc/+xwbT/ + wc3C/87Yzv+7yr3/u8q9/87Zz//C0MP/ssa2/1eFYv8znbT/JGtD/yJjMf+Ato3/gLmZ/3+8yv9yj3n/ + cpB6/3yYg//I1Mr/mbCe/5mxn//I1cv/fp+G/3aafv92m3//bLnK/yhwSv8rfD//hruT/4a9nf+IzOP/ + f6uk/3qah/95loD/i6WS/560o/+etaT/jamU/3uchP99oov/gbKo/4nO5P9pqYP/MYtI/4y/mv+Mv5r/ + jMOn/47Mx/+P0t3/j9Lj/47P3/+Ozd3/js3d/47P4P+P0uL/j9Hd/47MyP+Mw6j/jL+a/1+mcf+OwZzt + ksSf/5LEn/+SxJ//ksSf/5LEn/+SxJ//ksSh/5LEof+SxJ//ksSf/5LEn/+SxJ//ksSf/5LEn/+Qw53t + jcOcUpTGou2YyKX/mMil/5jIpf+YyKX/mMil/5jIpf+YyKX/mMil/5jIpf+YyKX/mMil/5jIpf+Xx6Tv + mcimVwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAA= + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/SecureSandbox/TrayForm.Designer.cs b/Demo_Source_Code/CSharpDemo/SecureSandbox/TrayForm.Designer.cs new file mode 100644 index 0000000..a86c096 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/SecureSandbox/TrayForm.Designer.cs @@ -0,0 +1,99 @@ +namespace SecureSandbox +{ + partial class TrayForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(TrayForm)); + this.contextMenuStrip = new System.Windows.Forms.ContextMenuStrip(this.components); + this.consoleToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripMenuItem3 = new System.Windows.Forms.ToolStripSeparator(); + this.exitToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem(); + this.notifyIcon = new System.Windows.Forms.NotifyIcon(this.components); + this.contextMenuStrip.SuspendLayout(); + this.SuspendLayout(); + // + // contextMenuStrip + // + this.contextMenuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.consoleToolStripMenuItem, + this.toolStripMenuItem3, + this.exitToolStripMenuItem1}); + this.contextMenuStrip.Name = "contextMenuStrip_fileAgent"; + this.contextMenuStrip.Size = new System.Drawing.Size(150, 54); + this.contextMenuStrip.Text = "-"; + // + // consoleToolStripMenuItem + // + this.consoleToolStripMenuItem.Name = "consoleToolStripMenuItem"; + this.consoleToolStripMenuItem.Size = new System.Drawing.Size(149, 22); + this.consoleToolStripMenuItem.Text = "Open Console"; + this.consoleToolStripMenuItem.Click += new System.EventHandler(this.consoleToolStripMenuItem_Click); + // + // toolStripMenuItem3 + // + this.toolStripMenuItem3.Name = "toolStripMenuItem3"; + this.toolStripMenuItem3.Size = new System.Drawing.Size(146, 6); + // + // exitToolStripMenuItem1 + // + this.exitToolStripMenuItem1.Name = "exitToolStripMenuItem1"; + this.exitToolStripMenuItem1.Size = new System.Drawing.Size(149, 22); + this.exitToolStripMenuItem1.Text = "Exit"; + this.exitToolStripMenuItem1.Click += new System.EventHandler(this.exitToolStripMenuItem1_Click); + // + // notifyIcon + // + this.notifyIcon.ContextMenuStrip = this.contextMenuStrip; + this.notifyIcon.Icon = ((System.Drawing.Icon)(resources.GetObject("notifyIcon.Icon"))); + this.notifyIcon.Text = "Secure Sandbox"; + this.notifyIcon.Visible = true; + // + // TrayForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(263, 102); + this.Name = "TrayForm"; + this.Text = "TrayForm"; + this.WindowState = System.Windows.Forms.FormWindowState.Minimized; + this.Load += new System.EventHandler(this.TrayForm_Load); + this.contextMenuStrip.ResumeLayout(false); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.ContextMenuStrip contextMenuStrip; + private System.Windows.Forms.ToolStripMenuItem consoleToolStripMenuItem; + private System.Windows.Forms.ToolStripSeparator toolStripMenuItem3; + private System.Windows.Forms.ToolStripMenuItem exitToolStripMenuItem1; + public System.Windows.Forms.NotifyIcon notifyIcon; + } +} \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/SecureSandbox/TrayForm.cs b/Demo_Source_Code/CSharpDemo/SecureSandbox/TrayForm.cs new file mode 100644 index 0000000..c3a6e08 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/SecureSandbox/TrayForm.cs @@ -0,0 +1,83 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +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; +using System.IO; + +using EaseFilter.CommonObjects; + +namespace SecureSandbox +{ + public partial class TrayForm: Form + { + SecureSandbox secureSandbox = null; + + public TrayForm() + { + + InitializeComponent(); + + this.Hide(); + + secureSandbox = new SecureSandbox(); + + } + + private void TrayForm_Load(object sender, EventArgs e) + { + this.Hide(); + this.notifyIcon.Visible = true; + secureSandbox.ShowDialog(); + } + + + private void consoleToolStripMenuItem_Click(object sender, EventArgs e) + { + if (!secureSandbox.Visible) + { + secureSandbox.StartPosition = FormStartPosition.CenterScreen; + secureSandbox.ShowDialog(); + } + } + + private void settingsToolStripMenuItem_Click(object sender, EventArgs e) + { + SettingsForm settingForm = new SettingsForm(); + settingForm.StartPosition = FormStartPosition.CenterScreen; + settingForm.ShowDialog(); + } + + + + private void exitToolStripMenuItem1_Click(object sender, EventArgs e) + { + GlobalConfig.Stop(); + secureSandbox.Close(); + + Application.Exit(); + } + + + } +} diff --git a/Demo_Source_Code/CSharpDemo/SecureSandbox/TrayForm.resx b/Demo_Source_Code/CSharpDemo/SecureSandbox/TrayForm.resx new file mode 100644 index 0000000..e17a672 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/SecureSandbox/TrayForm.resx @@ -0,0 +1,1853 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 19, 18 + + + 214, 23 + + + + + AAABAAYAAAAAAAEAIAD2DQAAZgAAAICAAAABACAAKAgBAFwOAABAQAAAAQAgAChCAACEFgEAMDAAAAEA + IACoJQAArFgBACAgAAABACAAqBAAAFR+AQAQEAAAAQAgAGgEAAD8jgEAiVBORw0KGgoAAAANSUhEUgAA + AQAAAAEACAYAAABccqhmAAANvUlEQVR42u3d249ddRnG8b32XjOzO9NOpwfaQgtth0pqoIBibCWIAbwQ + NSEa0xCvPECIh2gxStTIBV4YNaJcqJiIhqghSogXSGIIJoBSSrC2lKMtp05L26Hnmc5xH9byL+jzkPyy + smvf7+f2XWvttdeePl3J+ztkNeMXT/zg/aq+cGDkAVVv9g1uUvVGvbHI3QNwvspq2ZSqt7udV1W9We/7 + qqpv3XL7f1S93usHAKB3CAAgMAIACIwAAAIjAIDACAAgMAIACCxzff4lQyt3qnqeNQZ7/SWAqLKsPqvq + jTK7TtV5AwACIwCAwAgAIDACAAiMAAACIwCAwAgAILC82Rj8rTogKzPZ5++WRa+/AxBYsUBV57rtX6o6 + bwBAYAQAEBgBAARGAACBEQBAYAQAEBgBAASWN+r9ct3+TrfT63uEkJl6n4n40pzfKdLOR291y+JyVecN + AAiMAAACIwCAwAgAIDACAAiMAAACIwCAwPKslg2rA4qi2+t7TNI0EbeiXx8w0qfPH8l1J36xqQ+a+8td + PdPXd+MEHDtOoNRHuHEEM6Z+uqOvf7qt6xNmGMvRlr6Buf/z5S52j+2Q/755AwACIwCAwAgAIDACAAiM + AAACIwCAwAgAILC82+M+/4KGrm8wB6xdoDvdK/rTOuGFaYRPmUb3REtf4LBpNM939fktU2+7n9c8nn7z + +/TV9QWafbo+bMZhLDfnrxvQ9br9+fXnHze/3wHz++2d1ufPuj8wY/+JN3X9+FsJ3x7AeY0AAAIjAIDA + CAAgMAIACIwAAAIjAIDAKh8HMNTQjdjPXZDLulvXfmxKT/h+erytzz+p60dO6XpZuj5ullR2stQJ/249 + AXf91K+XeEDd/H1dOKz/vtYs0fV15vwPLtIDJTYN6ft7ZLwl6+9MnZL1F8d2yrr7++QNAAiMAAACIwCA + wAgAIDACAAiMAAACIwCAwPJOt9pxAAvNuvj9ps/70ItTsv76kXlZd33s9D562gELB4dk/aqN18j6YFOf + X/EwhNrM/Iys73l9l6zPzk0nfb5ZDqF2wIzjOHhKP4Ed5gGNLu+X9a0bFsh6++QJWd++7yn9/fO0f7+8 + AQCBEQBAYAQAEBgBAARGAACBEQBAYAQAEFjl6wG0C9NILXQGzbb0fP/C3X/qfHY3UMD0oftyPZ/8S5/9 + mqwfPXlE1o+fOpZ0f2XiQICLV66V9Ws2bpb1Xz9yr6x3uvr39wM9ksr28nMdfX9lW49z2PnKk7I+flCv + B7D4Ej0OJB/Q/754AwACIwCAwAgAIDACAAiMAAACIwCAwAgAILDKxwF0uq6PbvqUmd5/3d1/9eva6yNW + LrvYXEA36v/02O/TbrDi7+ee77bPf0/WVyy9UNYPHh3Tn1/1tgzmgE7bjFM5tkfWp2f1OIHSLHgweVCf + P7x6UNZ5AwACIwCAwAgAIDACAAiMAAACIwCAwAgAILC86+ZbJ2rZcQCmz1zT99ctOuZ8ff2+vj5Zv/SS + y2Q9z/X5q5ZfZO5f93k3jl5RS1LxvgBuHEBhvt/o6g2yPrRgoax3unrd/7cOv27O138/M/O6zz55bLd+ + Pov1/7Htwg1k0Ao3TuCw3reBNwAgMAIACIwAAAIjAIDACAAgMAIACIwAAALLO91q1wOw4wCKhizXzXz5 + bqHXC3C+fMvXZb050JT1mbnZpM8/MaH3h//Q5dfKemofv2onJvX3W7NyfVJ9cGCBrH/kyo/J+n1//pGs + //u1Hfr6a/Xfb60cluVWR/99p40SqNXcch+8AQCBEQBAYAQAEBgBAARGAACBEQBAYAQAENg5sC+AWde/ + ZvYF6KbtC7DOzEe/5zd3yfrMnJ4v7vefr3bCfrOp++Tu8nMtPc6h6vt3P+BgU697//0v/ljWd7z8jKy7 + 9Sb6G/rza6Xu5LfLtHEAfl8DfQXeAIDACAAgMAIACIwAAAIjAIDACAAgMAIACKzycQDzdj0A/fn1mq7b + +0/sQ3c6et35IvX5+YECSad/9AM3Jd3e4zseTbz/tNML0wnfe+A1WXf7Lrh9BWp1fYe5+wamkd/qFOb0 + xJEA5nTeAIDACAAgMAIACIwAAAIjAIDACAAgMAIACCx3+6OnOuOW7S91BjVzsx6Ama/t2qTu9tx6A/b5 + JfbxbR/dXD91PnnHPN/U+5+b1+sNvPz2i/r7mfn0RfKEen2BJQOuD6/PPzmbtq+Fu7/SfEHeAIDACAAg + MAIACIwAAAIjAIDACAAgMAIACCx3fe5U7uoTLX3EykHdx+wWpo+a1qa16w2krgewYECvK3/D5ptlvV7X + Gb5+9WVJ93fztZ/R37/Uz//hJx6U9Rfe2KWvb57vwsFhc3/mC7q6MTrckPXj8/oD5tr6+bltF1yfP2Nf + AABnQwAAgREAQGAEABAYAQAERgAAgREAQGB5p+J9AZxjc3q++Sq9vb3t07s+amEGArhxBnYcguHOd/fn + BjIUifc3b/ZFODF5XNb/O6bX7e90034/u96DeT5l4vXXD+lxAGPT+u/bf37ixgoGbwBAYAQAEBgBAARG + AACBEQBAYAQAEBgBAASWdzrV7gvgvDmt6zctzWW92dB97mkz39q1ybtm3X+/L4AuT82ekfVHn/qLvry5 + /qeu3yrrE9OTsv6zP9ytn0+ZNp89dWMBN0zC/b7u/GWD+v/IKxbpcQAP7tf7Hrj1CEpzQJY4EIA3ACAw + AgAIjAAAAiMAgMAIACAwAgAIjAAAAsvdfPqq7T6tG7WfWKozavPaAVl/Yp8eaOD2l++WZl8AU09dd971 + gcdPjsv62PiYuX+3HoL5fol9fHt+lvYA7XoK5vl+clQvSJGb8x/fP5f0+f4BufUO9Pm8AQCBEQBAYAQA + EBgBAARGAACBEQBAYAQAEFhu57NX7JCZLn1wRq8H8Om1fbK+fb/r8+vPd/vLu3Xt3br8bl39w8fekfX5 + TkvW//jY/foL2P3nU7kJ76kL2+vzu+YHXD6o5/PfZsYBvDGlf999J/W+Cna9BNfnN88vM+MgeAMAAiMA + gMAIACAwAgAIjAAAAiMAgMAIACCw7Pb7b01v9Vbo0qbu035rvV4P4KUJPc5h/tJtsj7Qp/vAJyZOyHqr + o/vAVT9832eu+gaqvfzw4LCsT81OyPqil7fJ+uYRPQ7ltuf09Xe+q8dp2OUS3A9oz9d13gCAwAgAIDAC + AAiMAAACIwCAwAgAIDACAAgs73SL9KtUaO+0vr8nD8/L+o0jel+Afz53h6zfP7ZB1vv69TiB9HXx39Nj + Ovvpide3+89XfP/uCxRt/ft+YcWrsr5lqe7z//WgXtf/+SO6z+/HYegDUncNcDfAGwAQGAEABEYAAIER + AEBgBAAQGAEABEYAAIEl7wsw19IL+0/P6z7tTMvUzfk/PKDvf+Diflm/fpVeT2Bk3Suy/p1/nZL1/WZd + eNenTe3j93q+uT3AlDcs0fs+/HSLXg9g45BeT2L7Yd3n/8kLU7UUvo+f3OnXn8++AADOhgAAAiMAgMAI + ACAwAgAIjAAAAiMAgMCya797hWwUzrf1fPuiPLfXExgy+8ffs1r3ma+7SI8TaJs27q/2zsj6A7vPyHrX + 9IntfH0T8cl9fCNv6PNvv3KhrH/lfXq9hYZ5/s8c0n+/d+3Rff6pjvmA1HES5gKZ+y86cZwHbwBAYAQA + EBgBAARGAACBEQBAYAQAEBgBAASWXXXnaNVb1J/TFpo+9TeX6XXjb1yl1xsYMfPR3zD7Hvz8JT1O4B9v + 6/UYUufju9M/vk736e+8XPf5Nwzp/4NOT3dl/e+H9Hz++/bp5zNp+vyp4yTS13Oo9vq8AQCBEQBAYAQA + EBgBAARGAACBEQBAYAQAEFh25bb1occBOK7Peovp82+9QK83MLpcjyPoz/UN7JnU+yLc+5Ke716Y5Ry+ + bebrX71Yj5NomT77W8f1vgm/O6jXU/jbOy1Zr3rfgtQ+fOq+DKn3xxsAEBgBAARGAACBEQBAYAQAEBgB + AARGAACBZZu+sY5xABVaNqvns9+xRu87sGWZHkewakTX3TgCx/Xxx0/rPv6zrs9/QM/nHzPrASSvu3+O + z9evehwBbwBAYAQAEBgBAARGAACBEQBAYAQAEBgBAASWF4wCqNSxpl4v4G6zbv2HF+n57rdepMcRbFqi + 5+s7u0/p9QYeOjQv67tO6nEAqX3w93CA5P78bZ899fr2CvqI1OvzBgAERgAAgREAQGAEABAYAQAERgAA + gREAQGB5WZTvmmNW9vomz2f9I7pP/7yZb799l+7D33ChHifgGsVPvZu47r6VJVRrtdJ1wu10edNnL/X1 + 7fcvU/v4aQN1ylrtqKrzBgAERgAAgREAQGAEABAYAQAERgAAgREAQGB5WZZPqwPKWm1rr28ysnyxHidQ + mPOfHNfjBHo9H991wn2fvNrP92e7cQzJfXz7BHQ1e1bVeQMAAiMAgMAIACAwAgAIjAAAAiMAgMAIACCw + bMNtq9eoAxp5fY+5xtJefwmcXXtSr+vfmdUjCSrf394fkHZ9e37a5yc/H3t7Zj2BrHZa1rvl1arOGwAQ + GAEABEYAAIERAEBgBAAQGAEABEYAAIHZLqUbJ1Bv1O/VVyivNx+xqtcPIbL2GT1OoDvnxgkk9vGNLPW/ + qJ73+c18/Xp5VJ9fl/P5y6LcpupvP3RkTF7d3T6A8xcBAARGAACBEQBAYAQAEBgBAARGAACB/Q//xIY7 + IGrejgAAAABJRU5ErkJggigAAACAAAAAAAEAAAEAIAAAAAAAAAABABMLAAATCwAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAG2QkHBtkJBwbZCQcG2QkHB1nJqkdZyapHWcmqR1nJqkcZybnHGcm5xxnJuccZybn + HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/ + HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/ + HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/ + HGcm/xxnJv8cZyb/GFoh/xhaIf8YWiH/GFoh/xZSHv8WUh7/FlIe/xZSHv8XUx//F1Mf/xdTH/8XUx// + F1Qf/xdUH/8XVB//F1Qf/xdUH/8XVB//F1Qf/xdUH/8XViD/F1Yg/xdWIP8XViD/F1Yg/xdWIP8XViD/ + F1Yg/xhXIP8YVyD/GFcg/xhXIP8YWCD/GFgg/xhYIP8YWCD/GFkh/xhZIf8YWSH/GFkh/xhaIf8YWiH/ + GFoh/xhaIf8ZWiH/GVoh/xlaIf8ZWiH/GFwi6RhcIukYXCLpGFwi6RpcIq8aXCKvGlwirxpcIq8ZWiEf + GVohHxlaIR8ZWiEfAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbZCQcG2QkHBtkJBwbZCQc + HWcmqR1nJqkdZyapHWcmqRxnJuccZybnHGcm5xxnJuccZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/ + HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/ + HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/ + HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8YWiH/GFoh/xhaIf8YWiH/ + FlIe/xZSHv8WUh7/FlIe/xdTH/8XUx//F1Mf/xdTH/8XVB//F1Qf/xdUH/8XVB//F1Qf/xdUH/8XVB// + F1Qf/xdWIP8XViD/F1Yg/xdWIP8XViD/F1Yg/xdWIP8XViD/GFcg/xhXIP8YVyD/GFcg/xhYIP8YWCD/ + GFgg/xhYIP8YWSH/GFkh/xhZIf8YWSH/GFoh/xhaIf8YWiH/GFoh/xlaIf8ZWiH/GVoh/xlaIf8YXCLp + GFwi6RhcIukYXCLpGlwirxpcIq8aXCKvGlwirxlaIR8ZWiEfGVohHxlaIR8AAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAABtkJBwbZCQcG2QkHBtkJBwdZyapHWcmqR1nJqkdZyapHGcm5xxnJuccZybn + HGcm5xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/ + HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/ + HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/ + HGcm/xxnJv8cZyb/HGcm/xhaIf8YWiH/GFoh/xhaIf8WUh7/FlIe/xZSHv8WUh7/F1Mf/xdTH/8XUx// + F1Mf/xdUH/8XVB//F1Qf/xdUH/8XVB//F1Qf/xdUH/8XVB//F1Yg/xdWIP8XViD/F1Yg/xdWIP8XViD/ + F1Yg/xdWIP8YVyD/GFcg/xhXIP8YVyD/GFgg/xhYIP8YWCD/GFgg/xhZIf8YWSH/GFkh/xhZIf8YWiH/ + GFoh/xhaIf8YWiH/GVoh/xlaIf8ZWiH/GVoh/xhcIukYXCLpGFwi6RhcIukaXCKvGlwirxpcIq8aXCKv + GVohHxlaIR8ZWiEfGVohHwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAG2QkHBtkJBwbZCQc + G2QkHB1nJqkdZyapHWcmqR1nJqkcZybnHGcm5xxnJuccZybnHGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/ + HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/ + HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/ + HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/GFoh/xhaIf8YWiH/ + GFoh/xZSHv8WUh7/FlIe/xZSHv8XUx//F1Mf/xdTH/8XUx//F1Qf/xdUH/8XVB//F1Qf/xdUH/8XVB// + F1Qf/xdUH/8XViD/F1Yg/xdWIP8XViD/F1Yg/xdWIP8XViD/F1Yg/xhXIP8YVyD/GFcg/xhXIP8YWCD/ + GFgg/xhYIP8YWCD/GFkh/xhZIf8YWSH/GFkh/xhaIf8YWiH/GFoh/xhaIf8ZWiH/GVoh/xlaIf8ZWiH/ + GFwi6RhcIukYXCLpGFwi6RpcIq8aXCKvGlwirxpcIq8ZWiEfGVohHxlaIR8ZWiEfAAAAAAAAAAAAAAAA + AAAAABtkJBwbZCQcG2QkHBtkJBwdaCftHWgn7R1oJ+0daCftHWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/xlaIv8ZWiL/GVoi/xlaIv8XUR7/F1Ee/xdRHv8XUR7/F1If/xdSH/8XUh//F1If/xdTH/8XUx// + F1Mf/xdTH/8XVB//F1Qf/xdUH/8XVB//GFQg/xhUIP8YVCD/GFQg/xhVIP8YVSD/GFUg/xhVIP8YViD/ + GFYg/xhWIP8YViD/GFch/xhXIf8YVyH/GFch/xlYIf8ZWCH/GVgh/xlYIf8ZWSH/GVkh/xlZIf8ZWSH/ + GVoi/xlaIv8ZWiL/GVoi/xlbIv8ZWyL/GVsi/xlbIv8ZWyL/GVsi/xlbIv8ZWyL/Glwj/xpcI/8aXCP/ + Glwj/xpdIu8aXSLvGl0i7xpdIu8ZWiEfGVohHxlaIR8ZWiEfG2QkHBtkJBwbZCQcG2QkHB1oJ+0daCft + HWgn7R1oJ+0daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/GVoi/xlaIv8ZWiL/GVoi/xdRHv8XUR7/ + F1Ee/xdRHv8XUh//F1If/xdSH/8XUh//F1Mf/xdTH/8XUx//F1Mf/xdUH/8XVB//F1Qf/xdUH/8YVCD/ + GFQg/xhUIP8YVCD/GFUg/xhVIP8YVSD/GFUg/xhWIP8YViD/GFYg/xhWIP8YVyH/GFch/xhXIf8YVyH/ + GVgh/xlYIf8ZWCH/GVgh/xlZIf8ZWSH/GVkh/xlZIf8ZWiL/GVoi/xlaIv8ZWiL/GVsi/xlbIv8ZWyL/ + GVsi/xlbIv8ZWyL/GVsi/xlbIv8aXCP/Glwj/xpcI/8aXCP/Gl0i7xpdIu8aXSLvGl0i7xlaIR8ZWiEf + GVohHxlaIR8bZCQcG2QkHBtkJBwbZCQcHWgn7R1oJ+0daCftHWgn7R1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8ZWiL/GVoi/xlaIv8ZWiL/F1Ee/xdRHv8XUR7/F1Ee/xdSH/8XUh//F1If/xdSH/8XUx// + F1Mf/xdTH/8XUx//F1Qf/xdUH/8XVB//F1Qf/xhUIP8YVCD/GFQg/xhUIP8YVSD/GFUg/xhVIP8YVSD/ + GFYg/xhWIP8YViD/GFYg/xhXIf8YVyH/GFch/xhXIf8ZWCH/GVgh/xlYIf8ZWCH/GVkh/xlZIf8ZWSH/ + GVkh/xlaIv8ZWiL/GVoi/xlaIv8ZWyL/GVsi/xlbIv8ZWyL/GVsi/xlbIv8ZWyL/GVsi/xpcI/8aXCP/ + Glwj/xpcI/8aXSLvGl0i7xpdIu8aXSLvGVohHxlaIR8ZWiEfGVohHxtkJBwbZCQcG2QkHBtkJBwdaCft + HWgn7R1oJ+0daCftHWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/xlaIv8ZWiL/GVoi/xlaIv8XUR7/ + F1Ee/xdRHv8XUR7/F1If/xdSH/8XUh//F1If/xdTH/8XUx//F1Mf/xdTH/8XVB//F1Qf/xdUH/8XVB// + GFQg/xhUIP8YVCD/GFQg/xhVIP8YVSD/GFUg/xhVIP8YViD/GFYg/xhWIP8YViD/GFch/xhXIf8YVyH/ + GFch/xlYIf8ZWCH/GVgh/xlYIf8ZWSH/GVkh/xlZIf8ZWSH/GVoi/xlaIv8ZWiL/GVoi/xlbIv8ZWyL/ + GVsi/xlbIv8ZWyL/GVsi/xlbIv8ZWyL/Glwj/xpcI/8aXCP/Glwj/xpdIu8aXSLvGl0i7xpdIu8ZWiEf + GVohHxlaIR8ZWiEfHmopqR5qKakeaimpHmopqR5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8aWyL/ + Glsi/xpbIv8aWyL/F1Ef/xdRH/8XUR//F1Ef/xdSH/8XUh//F1If/xdSH/8XUx//F1Mf/xdTH/8XUx// + GFQg/xhUIP8YVCD/GFQg/xhUIP8YVCD/GFQg/xhUIP8YVSD/GFUg/xhVIP8YVSD/GFYg/xhWIP8YViD/ + GFYg/xlXIf8ZVyH/GVch/xlXIf8ZWCH/GVgh/xlYIf8ZWCH/GVki/xlZIv8ZWSL/GVki/xlaIv8ZWiL/ + GVoi/xlaIv8aWyL/Glsi/xpbIv8aWyL/Glsj/xpbI/8aWyP/Glsj/xpcI/8aXCP/Glwj/xpcI/8aXSP/ + Gl0j/xpdI/8aXSP/G14j/xteI/8bXiP/G14j/xxfJK8cXySvHF8krxxfJK8eaimpHmopqR5qKakeaimp + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/xpbIv8aWyL/Glsi/xpbIv8XUR//F1Ef/xdRH/8XUR// + F1If/xdSH/8XUh//F1If/xdTH/8XUx//F1Mf/xdTH/8YVCD/GFQg/xhUIP8YVCD/GFQg/xhUIP8YVCD/ + GFQg/xhVIP8YVSD/GFUg/xhVIP8YViD/GFYg/xhWIP8YViD/GVch/xlXIf8ZVyH/GVch/xlYIf8ZWCH/ + GVgh/xlYIf8ZWSL/GVki/xlZIv8ZWSL/GVoi/xlaIv8ZWiL/GVoi/xpbIv8aWyL/Glsi/xpbIv8aWyP/ + Glsj/xpbI/8aWyP/Glwj/xpcI/8aXCP/Glwj/xpdI/8aXSP/Gl0j/xpdI/8bXiP/G14j/xteI/8bXiP/ + HF8krxxfJK8cXySvHF8krx5qKakeaimpHmopqR5qKakeaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Glsi/xpbIv8aWyL/Glsi/xdRH/8XUR//F1Ef/xdRH/8XUh//F1If/xdSH/8XUh//F1Mf/xdTH/8XUx// + F1Mf/xhUIP8YVCD/GFQg/xhUIP8YVCD/GFQg/xhUIP8YVCD/GFUg/xhVIP8YVSD/GFUg/xhWIP8YViD/ + GFYg/xhWIP8ZVyH/GVch/xlXIf8ZVyH/GVgh/xlYIf8ZWCH/GVgh/xlZIv8ZWSL/GVki/xlZIv8ZWiL/ + GVoi/xlaIv8ZWiL/Glsi/xpbIv8aWyL/Glsi/xpbI/8aWyP/Glsj/xpbI/8aXCP/Glwj/xpcI/8aXCP/ + Gl0j/xpdI/8aXSP/Gl0j/xteI/8bXiP/G14j/xteI/8cXySvHF8krxxfJK8cXySvHmopqR5qKakeaimp + HmopqR5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8aWyL/Glsi/xpbIv8aWyL/F1Ef/xdRH/8XUR// + F1Ef/xdSH/8XUh//F1If/xdSH/8XUx//F1Mf/xdTH/8XUx//GFQg/xhUIP8YVCD/GFQg/xhUIP8YVCD/ + GFQg/xhUIP8YVSD/GFUg/xhVIP8YVSD/GFYg/xhWIP8YViD/GFYg/xlXIf8ZVyH/GVch/xlXIf8ZWCH/ + GVgh/xlYIf8ZWCH/GVki/xlZIv8ZWSL/GVki/xlaIv8ZWiL/GVoi/xlaIv8aWyL/Glsi/xpbIv8aWyL/ + Glsj/xpbI/8aWyP/Glsj/xpcI/8aXCP/Glwj/xpcI/8aXSP/Gl0j/xpdI/8aXSP/G14j/xteI/8bXiP/ + G14j/xxfJK8cXySvHF8krxxfJK8fayroH2sq6B9rKugfayroH2sq/x9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/Glsk/xpbJP8aWyT/ + Glsk/xdQH/8XUB//F1Af/xdQH/8eaWD/Hmlg/x5pYP8eaWD/Hmpg/x5qYP8eamD/Hmpg/xhTIP8YUyD/ + GFMg/xhTIP8YVCH/GFQh/xhUIf8YVCH/GFQh/xhUIf8YVCH/GFQh/xlVIf8ZVSH/GVUh/xlVIf8ZViL/ + GVYi/xlWIv8ZViL/GVci/xlXIv8ZVyL/GVci/xlYIv8ZWCL/GVgi/xlYIv8aWSP/Glkj/xpZI/8aWSP/ + Gloj/xpaI/8aWiP/Gloj/xpbJP8aWyT/Glsk/xpbJP8bWyT/G1sk/xtbJP8bWyT/G1wk/xtcJP8bXCT/ + G1wk/xtdJf8bXSX/G10l/xtdJf8bXiX/G14l/xteJf8bXiX/G18l6RtfJekbXyXpG18l6R9rKugfayro + H2sq6B9rKugfayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8aWyT/Glsk/xpbJP8aWyT/F1Af/xdQH/8XUB//F1Af/x5pYP8eaWD/ + Hmlg/x5pYP8eamD/Hmpg/x5qYP8eamD/GFMg/xhTIP8YUyD/GFMg/xhUIf8YVCH/GFQh/xhUIf8YVCH/ + GFQh/xhUIf8YVCH/GVUh/xlVIf8ZVSH/GVUh/xlWIv8ZViL/GVYi/xlWIv8ZVyL/GVci/xlXIv8ZVyL/ + GVgi/xlYIv8ZWCL/GVgi/xpZI/8aWSP/Glkj/xpZI/8aWiP/Gloj/xpaI/8aWiP/Glsk/xpbJP8aWyT/ + Glsk/xtbJP8bWyT/G1sk/xtbJP8bXCT/G1wk/xtcJP8bXCT/G10l/xtdJf8bXSX/G10l/xteJf8bXiX/ + G14l/xteJf8bXyXpG18l6RtfJekbXyXpH2sq6B9rKugfayroH2sq6B9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/xpbJP8aWyT/ + Glsk/xpbJP8XUB//F1Af/xdQH/8XUB//Hmlg/x5pYP8eaWD/Hmlg/x5qYP8eamD/Hmpg/x5qYP8YUyD/ + GFMg/xhTIP8YUyD/GFQh/xhUIf8YVCH/GFQh/xhUIf8YVCH/GFQh/xhUIf8ZVSH/GVUh/xlVIf8ZVSH/ + GVYi/xlWIv8ZViL/GVYi/xlXIv8ZVyL/GVci/xlXIv8ZWCL/GVgi/xlYIv8ZWCL/Glkj/xpZI/8aWSP/ + Glkj/xpaI/8aWiP/Gloj/xpaI/8aWyT/Glsk/xpbJP8aWyT/G1sk/xtbJP8bWyT/G1sk/xtcJP8bXCT/ + G1wk/xtcJP8bXSX/G10l/xtdJf8bXSX/G14l/xteJf8bXiX/G14l/xtfJekbXyXpG18l6RtfJekfayro + H2sq6B9rKugfayroH2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/Glsk/xpbJP8aWyT/Glsk/xdQH/8XUB//F1Af/xdQH/8eaWD/ + Hmlg/x5pYP8eaWD/Hmpg/x5qYP8eamD/Hmpg/xhTIP8YUyD/GFMg/xhTIP8YVCH/GFQh/xhUIf8YVCH/ + GFQh/xhUIf8YVCH/GFQh/xlVIf8ZVSH/GVUh/xlVIf8ZViL/GVYi/xlWIv8ZViL/GVci/xlXIv8ZVyL/ + GVci/xlYIv8ZWCL/GVgi/xlYIv8aWSP/Glkj/xpZI/8aWSP/Gloj/xpaI/8aWiP/Gloj/xpbJP8aWyT/ + Glsk/xpbJP8bWyT/G1sk/xtbJP8bWyT/G1wk/xtcJP8bXCT/G1wk/xtdJf8bXSX/G10l/xtdJf8bXiX/ + G14l/xteJf8bXiX/G18l6RtfJekbXyXpG18l6SBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/xtbJP8bWyT/G1sk/xtbJP8eaFr/ + Hmha/x5oWv8eaFr/JYKy/yWCsv8lgrL/JYKy/ymT3/8pk9//KZPf/ymT3/8pk9//KZPf/ymT3/8pk9// + JYKu/yWCrv8lgq7/JYKu/x5nVP8eZ1T/HmdU/x5nVP8ZVSL/GVUi/xlVIv8ZVSL/GVYi/xlWIv8ZViL/ + GVYi/xlXIv8ZVyL/GVci/xlXIv8aWCP/Glgj/xpYI/8aWCP/Glgj/xpYI/8aWCP/Glgj/xpZI/8aWSP/ + Glkj/xpZI/8bWyT/G1sk/xtbJP8bWyT/G1sk/xtbJP8bWyT/G1sk/xtcJP8bXCT/G1wk/xtcJP8bXSX/ + G10l/xtdJf8bXSX/HF4l/xxeJf8cXiX/HF4l/xxfJf8cXyX/HF8l/xxfJf8cYCb/HGAm/xxgJv8cYCb/ + IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/G1sk/xtbJP8bWyT/G1sk/x5oWv8eaFr/Hmha/x5oWv8lgrL/JYKy/yWCsv8lgrL/ + KZPf/ymT3/8pk9//KZPf/ymT3/8pk9//KZPf/ymT3/8lgq7/JYKu/yWCrv8lgq7/HmdU/x5nVP8eZ1T/ + HmdU/xlVIv8ZVSL/GVUi/xlVIv8ZViL/GVYi/xlWIv8ZViL/GVci/xlXIv8ZVyL/GVci/xpYI/8aWCP/ + Glgj/xpYI/8aWCP/Glgj/xpYI/8aWCP/Glkj/xpZI/8aWSP/Glkj/xtbJP8bWyT/G1sk/xtbJP8bWyT/ + G1sk/xtbJP8bWyT/G1wk/xtcJP8bXCT/G1wk/xtdJf8bXSX/G10l/xtdJf8cXiX/HF4l/xxeJf8cXiX/ + HF8l/xxfJf8cXyX/HF8l/xxgJv8cYCb/HGAm/xxgJv8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8bWyT/G1sk/xtbJP8bWyT/ + Hmha/x5oWv8eaFr/Hmha/yWCsv8lgrL/JYKy/yWCsv8pk9//KZPf/ymT3/8pk9//KZPf/ymT3/8pk9// + KZPf/yWCrv8lgq7/JYKu/yWCrv8eZ1T/HmdU/x5nVP8eZ1T/GVUi/xlVIv8ZVSL/GVUi/xlWIv8ZViL/ + GVYi/xlWIv8ZVyL/GVci/xlXIv8ZVyL/Glgj/xpYI/8aWCP/Glgj/xpYI/8aWCP/Glgj/xpYI/8aWSP/ + Glkj/xpZI/8aWSP/G1sk/xtbJP8bWyT/G1sk/xtbJP8bWyT/G1sk/xtbJP8bXCT/G1wk/xtcJP8bXCT/ + G10l/xtdJf8bXSX/G10l/xxeJf8cXiX/HF4l/xxeJf8cXyX/HF8l/xxfJf8cXyX/HGAm/xxgJv8cYCb/ + HGAm/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/IG0r/xtbJP8bWyT/G1sk/xtbJP8eaFr/Hmha/x5oWv8eaFr/JYKy/yWCsv8lgrL/ + JYKy/ymT3/8pk9//KZPf/ymT3/8pk9//KZPf/ymT3/8pk9//JYKu/yWCrv8lgq7/JYKu/x5nVP8eZ1T/ + HmdU/x5nVP8ZVSL/GVUi/xlVIv8ZVSL/GVYi/xlWIv8ZViL/GVYi/xlXIv8ZVyL/GVci/xlXIv8aWCP/ + Glgj/xpYI/8aWCP/Glgj/xpYI/8aWCP/Glgj/xpZI/8aWSP/Glkj/xpZI/8bWyT/G1sk/xtbJP8bWyT/ + G1sk/xtbJP8bWyT/G1sk/xtcJP8bXCT/G1wk/xtcJP8bXSX/G10l/xtdJf8bXSX/HF4l/xxeJf8cXiX/ + HF4l/xxfJf8cXyX/HF8l/xxfJf8cYCb/HGAm/xxgJv8cYCb/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8dZUD/HWVA/x1lQP8dZUD/JIGn/ySBp/8kgaf/ + JIGn/ymU3/8plN//KZTf/ymU3/8upPf/LqT3/y6k9/8upPf/L6j9/y+o/f8vqP3/L6j9/y+o/f8vqP3/ + L6j9/y+o/f8upPf/LqT3/y6k9/8upPf/KZTf/ymU3/8plN//KZTf/ySApf8kgKX/JICl/ySApf8cYkL/ + HGJC/xxiQv8cYkL/GVcj/xlXI/8ZVyP/GVcj/xlYJP8ZWCT/GVgk/xlYJP8aWCT/Glgk/xpYJP8aWCT/ + Glkl/xpZJf8aWSX/Glkl/xpaJf8aWiX/Glol/xpaJf8bWyX/G1sl/xtbJf8bWyX/G1wm/xtcJv8bXCb/ + G1wm/xtdJv8bXSb/G10m/xtdJv8bXib/G14m/xteJv8bXib/HF8n/xxfJ/8cXyf/HF8n/xxgJ/8cYCf/ + HGAn/xxgJ/8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/x1lQP8dZUD/HWVA/x1lQP8kgaf/JIGn/ySBp/8kgaf/KZTf/ymU3/8plN//KZTf/y6k9/8upPf/ + LqT3/y6k9/8vqP3/L6j9/y+o/f8vqP3/L6j9/y+o/f8vqP3/L6j9/y6k9/8upPf/LqT3/y6k9/8plN// + KZTf/ymU3/8plN//JICl/ySApf8kgKX/JICl/xxiQv8cYkL/HGJC/xxiQv8ZVyP/GVcj/xlXI/8ZVyP/ + GVgk/xlYJP8ZWCT/GVgk/xpYJP8aWCT/Glgk/xpYJP8aWSX/Glkl/xpZJf8aWSX/Glol/xpaJf8aWiX/ + Glol/xtbJf8bWyX/G1sl/xtbJf8bXCb/G1wm/xtcJv8bXCb/G10m/xtdJv8bXSb/G10m/xteJv8bXib/ + G14m/xteJv8cXyf/HF8n/xxfJ/8cXyf/HGAn/xxgJ/8cYCf/HGAn/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/HWVA/x1lQP8dZUD/HWVA/ySBp/8kgaf/ + JIGn/ySBp/8plN//KZTf/ymU3/8plN//LqT3/y6k9/8upPf/LqT3/y+o/f8vqP3/L6j9/y+o/f8vqP3/ + L6j9/y+o/f8vqP3/LqT3/y6k9/8upPf/LqT3/ymU3/8plN//KZTf/ymU3/8kgKX/JICl/ySApf8kgKX/ + HGJC/xxiQv8cYkL/HGJC/xlXI/8ZVyP/GVcj/xlXI/8ZWCT/GVgk/xlYJP8ZWCT/Glgk/xpYJP8aWCT/ + Glgk/xpZJf8aWSX/Glkl/xpZJf8aWiX/Glol/xpaJf8aWiX/G1sl/xtbJf8bWyX/G1sl/xtcJv8bXCb/ + G1wm/xtcJv8bXSb/G10m/xtdJv8bXSb/G14m/xteJv8bXib/G14m/xxfJ/8cXyf/HF8n/xxfJ/8cYCf/ + HGAn/xxgJ/8cYCf/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/yBuLf8dZUD/HWVA/x1lQP8dZUD/JIGn/ySBp/8kgaf/JIGn/ymU3/8plN//KZTf/ymU3/8upPf/ + LqT3/y6k9/8upPf/L6j9/y+o/f8vqP3/L6j9/y+o/f8vqP3/L6j9/y+o/f8upPf/LqT3/y6k9/8upPf/ + KZTf/ymU3/8plN//KZTf/ySApf8kgKX/JICl/ySApf8cYkL/HGJC/xxiQv8cYkL/GVcj/xlXI/8ZVyP/ + GVcj/xlYJP8ZWCT/GVgk/xlYJP8aWCT/Glgk/xpYJP8aWCT/Glkl/xpZJf8aWSX/Glkl/xpaJf8aWiX/ + Glol/xpaJf8bWyX/G1sl/xtbJf8bWyX/G1wm/xtcJv8bXCb/G1wm/xtdJv8bXSb/G10m/xtdJv8bXib/ + G14m/xteJv8bXib/HF8n/xxfJ/8cXyf/HF8n/xxgJ/8cYCf/HGAn/xxgJ/8hcC7/IXAu/yFwLv8hcC7/ + IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/ + IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/ + IXAu/yFwLv8hcS//IXEv/yFxL/8hcS//JHx+/yR8fv8kfH7/JHx+/ymR1P8pkdT/KZHU/ymR1P8vpfb/ + L6X2/y+l9v8vpfb/MKn8/zCp/P8wqfz/MKn8/yybzf8sm83/LJvN/yybzf8gblr/IG5a/yBuWv8gblr/ + IGxY/yBsWP8gbFj/IGxY/yyazP8smsz/LJrM/yyazP8wqfz/MKn8/zCp/P8wqfz/L6X2/y+l9v8vpfb/ + L6X2/yqR1P8qkdT/KpHU/yqR1P8gdHH/IHRx/yB0cf8gdHH/Glgk/xpYJP8aWCT/Glgk/xpZJf8aWSX/ + Glkl/xpZJf8bWiX/G1ol/xtaJf8bWiX/G1sl/xtbJf8bWyX/G1sl/xtcJv8bXCb/G1wm/xtcJv8bXSb/ + G10m/xtdJv8bXSb/HF4n/xxeJ/8cXif/HF4n/xxfJ/8cXyf/HF8n/xxfJ/8cYCf/HGAn/xxgJ/8cYCf/ + HGEo/xxhKP8cYSj/HGEo/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/ + IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/ + IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFxL/8hcS//IXEv/yFxL/8kfH7/ + JHx+/yR8fv8kfH7/KZHU/ymR1P8pkdT/KZHU/y+l9v8vpfb/L6X2/y+l9v8wqfz/MKn8/zCp/P8wqfz/ + LJvN/yybzf8sm83/LJvN/yBuWv8gblr/IG5a/yBuWv8gbFj/IGxY/yBsWP8gbFj/LJrM/yyazP8smsz/ + LJrM/zCp/P8wqfz/MKn8/zCp/P8vpfb/L6X2/y+l9v8vpfb/KpHU/yqR1P8qkdT/KpHU/yB0cf8gdHH/ + IHRx/yB0cf8aWCT/Glgk/xpYJP8aWCT/Glkl/xpZJf8aWSX/Glkl/xtaJf8bWiX/G1ol/xtaJf8bWyX/ + G1sl/xtbJf8bWyX/G1wm/xtcJv8bXCb/G1wm/xtdJv8bXSb/G10m/xtdJv8cXif/HF4n/xxeJ/8cXif/ + HF8n/xxfJ/8cXyf/HF8n/xxgJ/8cYCf/HGAn/xxgJ/8cYSj/HGEo/xxhKP8cYSj/IXAu/yFwLv8hcC7/ + IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/ + IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/ + IXAu/yFwLv8hcC7/IXEv/yFxL/8hcS//IXEv/yR8fv8kfH7/JHx+/yR8fv8pkdT/KZHU/ymR1P8pkdT/ + L6X2/y+l9v8vpfb/L6X2/zCp/P8wqfz/MKn8/zCp/P8sm83/LJvN/yybzf8sm83/IG5a/yBuWv8gblr/ + IG5a/yBsWP8gbFj/IGxY/yBsWP8smsz/LJrM/yyazP8smsz/MKn8/zCp/P8wqfz/MKn8/y+l9v8vpfb/ + L6X2/y+l9v8qkdT/KpHU/yqR1P8qkdT/IHRx/yB0cf8gdHH/IHRx/xpYJP8aWCT/Glgk/xpYJP8aWSX/ + Glkl/xpZJf8aWSX/G1ol/xtaJf8bWiX/G1ol/xtbJf8bWyX/G1sl/xtbJf8bXCb/G1wm/xtcJv8bXCb/ + G10m/xtdJv8bXSb/G10m/xxeJ/8cXif/HF4n/xxeJ/8cXyf/HF8n/xxfJ/8cXyf/HGAn/xxgJ/8cYCf/ + HGAn/xxhKP8cYSj/HGEo/xxhKP8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/ + IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/ + IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcS//IXEv/yFxL/8hcS// + JHx+/yR8fv8kfH7/JHx+/ymR1P8pkdT/KZHU/ymR1P8vpfb/L6X2/y+l9v8vpfb/MKn8/zCp/P8wqfz/ + MKn8/yybzf8sm83/LJvN/yybzf8gblr/IG5a/yBuWv8gblr/IGxY/yBsWP8gbFj/IGxY/yyazP8smsz/ + LJrM/yyazP8wqfz/MKn8/zCp/P8wqfz/L6X2/y+l9v8vpfb/L6X2/yqR1P8qkdT/KpHU/yqR1P8gdHH/ + IHRx/yB0cf8gdHH/Glgk/xpYJP8aWCT/Glgk/xpZJf8aWSX/Glkl/xpZJf8bWiX/G1ol/xtaJf8bWiX/ + G1sl/xtbJf8bWyX/G1sl/xtcJv8bXCb/G1wm/xtcJv8bXSb/G10m/xtdJv8bXSb/HF4n/xxeJ/8cXif/ + HF4n/xxfJ/8cXyf/HF8n/xxfJ/8cYCf/HGAn/xxgJ/8cYCf/HGEo/xxhKP8cYSj/HGEo/yJxL/8icS// + InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS// + InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS// + I3Q7/yN0O/8jdDv/I3Q7/yeHqv8nh6r/J4eq/yeHqv8tn+z/LZ/s/y2f7P8tn+z/MKr8/zCq/P8wqvz/ + MKr8/y6f2P8un9j/Lp/Y/y6f2P8hcmb/IXJm/yFyZv8hcmb/GFEi/xhRIv8YUSL/GFEi/xlSIv8ZUiL/ + GVIi/xlSIv8ZUyL/GVMi/xlTIv8ZUyL/GVQj/xlUI/8ZVCP/GVQj/yJ0Z/8idGf/InRn/yJ0Z/8un9j/ + Lp/Y/y6f2P8un9j/MKr8/zCq/P8wqvz/MKr8/y2f7P8tn+z/LZ/s/y2f7P8lhKP/JYSj/yWEo/8lhKP/ + HF4z/xxeM/8cXjP/HF4z/xtaJf8bWiX/G1ol/xtaJf8bWyb/G1sm/xtbJv8bWyb/HFwm/xxcJv8cXCb/ + HFwm/xxdJ/8cXSf/HF0n/xxdJ/8cXif/HF4n/xxeJ/8cXif/HV8n/x1fJ/8dXyf/HV8n/x1gKP8dYCj/ + HWAo/x1gKP8dYSj/HWEo/x1hKP8dYSj/InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS// + InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS// + InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8jdDv/I3Q7/yN0O/8jdDv/J4eq/yeHqv8nh6r/ + J4eq/y2f7P8tn+z/LZ/s/y2f7P8wqvz/MKr8/zCq/P8wqvz/Lp/Y/y6f2P8un9j/Lp/Y/yFyZv8hcmb/ + IXJm/yFyZv8YUSL/GFEi/xhRIv8YUSL/GVIi/xlSIv8ZUiL/GVIi/xlTIv8ZUyL/GVMi/xlTIv8ZVCP/ + GVQj/xlUI/8ZVCP/InRn/yJ0Z/8idGf/InRn/y6f2P8un9j/Lp/Y/y6f2P8wqvz/MKr8/zCq/P8wqvz/ + LZ/s/y2f7P8tn+z/LZ/s/yWEo/8lhKP/JYSj/yWEo/8cXjP/HF4z/xxeM/8cXjP/G1ol/xtaJf8bWiX/ + G1ol/xtbJv8bWyb/G1sm/xtbJv8cXCb/HFwm/xxcJv8cXCb/HF0n/xxdJ/8cXSf/HF0n/xxeJ/8cXif/ + HF4n/xxeJ/8dXyf/HV8n/x1fJ/8dXyf/HWAo/x1gKP8dYCj/HWAo/x1hKP8dYSj/HWEo/x1hKP8icS// + InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS// + InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS// + InEv/yN0O/8jdDv/I3Q7/yN0O/8nh6r/J4eq/yeHqv8nh6r/LZ/s/y2f7P8tn+z/LZ/s/zCq/P8wqvz/ + MKr8/zCq/P8un9j/Lp/Y/y6f2P8un9j/IXJm/yFyZv8hcmb/IXJm/xhRIv8YUSL/GFEi/xhRIv8ZUiL/ + GVIi/xlSIv8ZUiL/GVMi/xlTIv8ZUyL/GVMi/xlUI/8ZVCP/GVQj/xlUI/8idGf/InRn/yJ0Z/8idGf/ + Lp/Y/y6f2P8un9j/Lp/Y/zCq/P8wqvz/MKr8/zCq/P8tn+z/LZ/s/y2f7P8tn+z/JYSj/yWEo/8lhKP/ + JYSj/xxeM/8cXjP/HF4z/xxeM/8bWiX/G1ol/xtaJf8bWiX/G1sm/xtbJv8bWyb/G1sm/xxcJv8cXCb/ + HFwm/xxcJv8cXSf/HF0n/xxdJ/8cXSf/HF4n/xxeJ/8cXif/HF4n/x1fJ/8dXyf/HV8n/x1fJ/8dYCj/ + HWAo/x1gKP8dYCj/HWEo/x1hKP8dYSj/HWEo/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS// + InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS// + InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//I3Q7/yN0O/8jdDv/I3Q7/yeHqv8nh6r/ + J4eq/yeHqv8tn+z/LZ/s/y2f7P8tn+z/MKr8/zCq/P8wqvz/MKr8/y6f2P8un9j/Lp/Y/y6f2P8hcmb/ + IXJm/yFyZv8hcmb/GFEi/xhRIv8YUSL/GFEi/xlSIv8ZUiL/GVIi/xlSIv8ZUyL/GVMi/xlTIv8ZUyL/ + GVQj/xlUI/8ZVCP/GVQj/yJ0Z/8idGf/InRn/yJ0Z/8un9j/Lp/Y/y6f2P8un9j/MKr8/zCq/P8wqvz/ + MKr8/y2f7P8tn+z/LZ/s/y2f7P8lhKP/JYSj/yWEo/8lhKP/HF4z/xxeM/8cXjP/HF4z/xtaJf8bWiX/ + G1ol/xtaJf8bWyb/G1sm/xtbJv8bWyb/HFwm/xxcJv8cXCb/HFwm/xxdJ/8cXSf/HF0n/xxdJ/8cXif/ + HF4n/xxeJ/8cXif/HV8n/x1fJ/8dXyf/HV8n/x1gKP8dYCj/HWAo/x1gKP8dYSj/HWEo/x1hKP8dYSj/ + LHg6/yx4Ov8seDr/LHg6/yVzM/8lczP/JXMz/yVzM/8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/ + I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yR0PP8kdDz/ + JHQ8/yR0PP8pj73/KY+9/ymPvf8pj73/MKn5/zCp+f8wqfn/MKn5/zCo9P8wqPT/MKj0/zCo9P8mgYn/ + JoGJ/yaBif8mgYn/GVAl/xlQJf8ZUCX/GVAl/xhQIv8YUCL/GFAi/xhQIv8ZUCP/GVAj/xlQI/8ZUCP/ + GVIj/xlSI/8ZUiP/GVIj/xlTJP8ZUyT/GVMk/xlTJP8aVCT/GlQk/xpUJP8aVCT/GlQk/xpUJP8aVCT/ + GlQk/xtXKP8bVyj/G1co/xtXKP8nhY3/J4WN/yeFjf8nhY3/MKr2/zCq9v8wqvb/MKr2/zCp+f8wqfn/ + MKn5/zCp+f8pjr3/KY69/ymOvf8pjr3/HV8z/x1fM/8dXzP/HV8z/xxbJ/8cWyf/HFsn/xxbJ/8cXCf/ + HFwn/xxcJ/8cXCf/HF0o/xxdKP8cXSj/HF0o/x1dKP8dXSj/HV0o/x1dKP8dXyn/HV8p/x1fKf8dXyn/ + HWAp/x1gKf8dYCn/HWAp/x5hKv8eYSr/HmEq/x5hKv8seDr/LHg6/yx4Ov8seDr/JXMz/yVzM/8lczP/ + JXMz/yNyMf8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/ + I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/JHQ8/yR0PP8kdDz/JHQ8/ymPvf8pj73/KY+9/ymPvf8wqfn/ + MKn5/zCp+f8wqfn/MKj0/zCo9P8wqPT/MKj0/yaBif8mgYn/JoGJ/yaBif8ZUCX/GVAl/xlQJf8ZUCX/ + GFAi/xhQIv8YUCL/GFAi/xlQI/8ZUCP/GVAj/xlQI/8ZUiP/GVIj/xlSI/8ZUiP/GVMk/xlTJP8ZUyT/ + GVMk/xpUJP8aVCT/GlQk/xpUJP8aVCT/GlQk/xpUJP8aVCT/G1co/xtXKP8bVyj/G1co/yeFjf8nhY3/ + J4WN/yeFjf8wqvb/MKr2/zCq9v8wqvb/MKn5/zCp+f8wqfn/MKn5/ymOvf8pjr3/KY69/ymOvf8dXzP/ + HV8z/x1fM/8dXzP/HFsn/xxbJ/8cWyf/HFsn/xxcJ/8cXCf/HFwn/xxcJ/8cXSj/HF0o/xxdKP8cXSj/ + HV0o/x1dKP8dXSj/HV0o/x1fKf8dXyn/HV8p/x1fKf8dYCn/HWAp/x1gKf8dYCn/HmEq/x5hKv8eYSr/ + HmEq/yx4Ov8seDr/LHg6/yx4Ov8lczP/JXMz/yVzM/8lczP/I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/ + I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yNyMf8kdDz/ + JHQ8/yR0PP8kdDz/KY+9/ymPvf8pj73/KY+9/zCp+f8wqfn/MKn5/zCp+f8wqPT/MKj0/zCo9P8wqPT/ + JoGJ/yaBif8mgYn/JoGJ/xlQJf8ZUCX/GVAl/xlQJf8YUCL/GFAi/xhQIv8YUCL/GVAj/xlQI/8ZUCP/ + GVAj/xlSI/8ZUiP/GVIj/xlSI/8ZUyT/GVMk/xlTJP8ZUyT/GlQk/xpUJP8aVCT/GlQk/xpUJP8aVCT/ + GlQk/xpUJP8bVyj/G1co/xtXKP8bVyj/J4WN/yeFjf8nhY3/J4WN/zCq9v8wqvb/MKr2/zCq9v8wqfn/ + MKn5/zCp+f8wqfn/KY69/ymOvf8pjr3/KY69/x1fM/8dXzP/HV8z/x1fM/8cWyf/HFsn/xxbJ/8cWyf/ + HFwn/xxcJ/8cXCf/HFwn/xxdKP8cXSj/HF0o/xxdKP8dXSj/HV0o/x1dKP8dXSj/HV8p/x1fKf8dXyn/ + HV8p/x1gKf8dYCn/HWAp/x1gKf8eYSr/HmEq/x5hKv8eYSr/LHg6/yx4Ov8seDr/LHg6/yVzM/8lczP/ + JXMz/yVzM/8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/ + I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yR0PP8kdDz/JHQ8/yR0PP8pj73/KY+9/ymPvf8pj73/ + MKn5/zCp+f8wqfn/MKn5/zCo9P8wqPT/MKj0/zCo9P8mgYn/JoGJ/yaBif8mgYn/GVAl/xlQJf8ZUCX/ + GVAl/xhQIv8YUCL/GFAi/xhQIv8ZUCP/GVAj/xlQI/8ZUCP/GVIj/xlSI/8ZUiP/GVIj/xlTJP8ZUyT/ + GVMk/xlTJP8aVCT/GlQk/xpUJP8aVCT/GlQk/xpUJP8aVCT/GlQk/xtXKP8bVyj/G1co/xtXKP8nhY3/ + J4WN/yeFjf8nhY3/MKr2/zCq9v8wqvb/MKr2/zCp+f8wqfn/MKn5/zCp+f8pjr3/KY69/ymOvf8pjr3/ + HV8z/x1fM/8dXzP/HV8z/xxbJ/8cWyf/HFsn/xxbJ/8cXCf/HFwn/xxcJ/8cXCf/HF0o/xxdKP8cXSj/ + HF0o/x1dKP8dXSj/HV0o/x1dKP8dXyn/HV8p/x1fKf8dXyn/HWAp/x1gKf8dYCn/HWAp/x5hKv8eYSr/ + HmEq/x5hKv9SkV3/UpFd/1KRXf9SkV3/UpFd/1KRXf9SkV3/UpFd/0mLVf9Ji1X/SYtV/0mLVf8+hEr/ + PoRK/z6ESv8+hEr/M35A/zN+QP8zfkD/M35A/yh3Nv8odzb/KHc2/yh3Nv8kdjv/JHY7/yR2O/8kdjv/ + KpPA/yqTwP8qk8D/KpPA/zGr+/8xq/v/Mav7/zGr+/8unc3/Lp3N/y6dzf8unc3/HWBC/x1gQv8dYEL/ + HWBC/xhOIv8YTiL/GE4i/xhOIv8ZTyL/GU8i/xlPIv8ZTyL/GVAj/xlQI/8ZUCP/GVAj/xlRI/8ZUSP/ + GVEj/xlRI/8ZUiP/GVIj/xlSI/8ZUiP/GlMk/xpTJP8aUyT/GlMk/xpUJP8aVCT/GlQk/xpUJP8aVSX/ + GlUl/xpVJf8aVSX/G1Yl/xtWJf8bViX/G1Yl/xtXJf8bVyX/G1cl/xtXJf8gaEn/IGhJ/yBoSf8gaEn/ + LqDT/y6g0/8uoNP/LqDT/zGr+/8xq/v/Mav7/zGr+/8qk8D/KpPA/yqTwP8qk8D/HmAy/x5gMv8eYDL/ + HmAy/x1cKP8dXCj/HVwo/x1cKP8dXSj/HV0o/x1dKP8dXSj/HV4p/x1eKf8dXin/HV4p/x5fKf8eXyn/ + Hl8p/x5fKf8eYCr/HmAq/x5gKv8eYCr/HmEq/x5hKv8eYSr/HmEq/1KRXf9SkV3/UpFd/1KRXf9SkV3/ + UpFd/1KRXf9SkV3/SYtV/0mLVf9Ji1X/SYtV/z6ESv8+hEr/PoRK/z6ESv8zfkD/M35A/zN+QP8zfkD/ + KHc2/yh3Nv8odzb/KHc2/yR2O/8kdjv/JHY7/yR2O/8qk8D/KpPA/yqTwP8qk8D/Mav7/zGr+/8xq/v/ + Mav7/y6dzf8unc3/Lp3N/y6dzf8dYEL/HWBC/x1gQv8dYEL/GE4i/xhOIv8YTiL/GE4i/xlPIv8ZTyL/ + GU8i/xlPIv8ZUCP/GVAj/xlQI/8ZUCP/GVEj/xlRI/8ZUSP/GVEj/xlSI/8ZUiP/GVIj/xlSI/8aUyT/ + GlMk/xpTJP8aUyT/GlQk/xpUJP8aVCT/GlQk/xpVJf8aVSX/GlUl/xpVJf8bViX/G1Yl/xtWJf8bViX/ + G1cl/xtXJf8bVyX/G1cl/yBoSf8gaEn/IGhJ/yBoSf8uoNP/LqDT/y6g0/8uoNP/Mav7/zGr+/8xq/v/ + Mav7/yqTwP8qk8D/KpPA/yqTwP8eYDL/HmAy/x5gMv8eYDL/HVwo/x1cKP8dXCj/HVwo/x1dKP8dXSj/ + HV0o/x1dKP8dXin/HV4p/x1eKf8dXin/Hl8p/x5fKf8eXyn/Hl8p/x5gKv8eYCr/HmAq/x5gKv8eYSr/ + HmEq/x5hKv8eYSr/UpFd/1KRXf9SkV3/UpFd/1KRXf9SkV3/UpFd/1KRXf9Ji1X/SYtV/0mLVf9Ji1X/ + PoRK/z6ESv8+hEr/PoRK/zN+QP8zfkD/M35A/zN+QP8odzb/KHc2/yh3Nv8odzb/JHY7/yR2O/8kdjv/ + JHY7/yqTwP8qk8D/KpPA/yqTwP8xq/v/Mav7/zGr+/8xq/v/Lp3N/y6dzf8unc3/Lp3N/x1gQv8dYEL/ + HWBC/x1gQv8YTiL/GE4i/xhOIv8YTiL/GU8i/xlPIv8ZTyL/GU8i/xlQI/8ZUCP/GVAj/xlQI/8ZUSP/ + GVEj/xlRI/8ZUSP/GVIj/xlSI/8ZUiP/GVIj/xpTJP8aUyT/GlMk/xpTJP8aVCT/GlQk/xpUJP8aVCT/ + GlUl/xpVJf8aVSX/GlUl/xtWJf8bViX/G1Yl/xtWJf8bVyX/G1cl/xtXJf8bVyX/IGhJ/yBoSf8gaEn/ + IGhJ/y6g0/8uoNP/LqDT/y6g0/8xq/v/Mav7/zGr+/8xq/v/KpPA/yqTwP8qk8D/KpPA/x5gMv8eYDL/ + HmAy/x5gMv8dXCj/HVwo/x1cKP8dXCj/HV0o/x1dKP8dXSj/HV0o/x1eKf8dXin/HV4p/x1eKf8eXyn/ + Hl8p/x5fKf8eXyn/HmAq/x5gKv8eYCr/HmAq/x5hKv8eYSr/HmEq/x5hKv9SkV3/UpFd/1KRXf9SkV3/ + UpFd/1KRXf9SkV3/UpFd/0mLVf9Ji1X/SYtV/0mLVf8+hEr/PoRK/z6ESv8+hEr/M35A/zN+QP8zfkD/ + M35A/yh3Nv8odzb/KHc2/yh3Nv8kdjv/JHY7/yR2O/8kdjv/KpPA/yqTwP8qk8D/KpPA/zGr+/8xq/v/ + Mav7/zGr+/8unc3/Lp3N/y6dzf8unc3/HWBC/x1gQv8dYEL/HWBC/xhOIv8YTiL/GE4i/xhOIv8ZTyL/ + GU8i/xlPIv8ZTyL/GVAj/xlQI/8ZUCP/GVAj/xlRI/8ZUSP/GVEj/xlRI/8ZUiP/GVIj/xlSI/8ZUiP/ + GlMk/xpTJP8aUyT/GlMk/xpUJP8aVCT/GlQk/xpUJP8aVSX/GlUl/xpVJf8aVSX/G1Yl/xtWJf8bViX/ + G1Yl/xtXJf8bVyX/G1cl/xtXJf8gaEn/IGhJ/yBoSf8gaEn/LqDT/y6g0/8uoNP/LqDT/zGr+/8xq/v/ + Mav7/zGr+/8qk8D/KpPA/yqTwP8qk8D/HmAy/x5gMv8eYDL/HmAy/x1cKP8dXCj/HVwo/x1cKP8dXSj/ + HV0o/x1dKP8dXSj/HV4p/x1eKf8dXin/HV4p/x5fKf8eXyn/Hl8p/x5fKf8eYCr/HmAq/x5gKv8eYCr/ + HmEq/x5hKv8eYSr/HmEq/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/ + VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1Smuf9Uprn/ + VKa5/1Smuf9Jtvv/Sbb7/0m2+/9Jtvv/NZy9/zWcvf81nL3/NZy9/1l9Xf9ZfV3/WX1d/1l9Xf9ig2L/ + YoNi/2KDYv9ig2L/Y4Ni/2ODYv9jg2L/Y4Ni/2OEYv9jhGL/Y4Ri/2OEYv9jhWL/Y4Vi/2OFYv9jhWL/ + Y4Vi/2OFYv9jhWL/Y4Vi/2OGY/9jhmP/Y4Zj/2OGY/9jh2P/Y4dj/2OHY/9jh2P/ZIdk/2SHZP9kh2T/ + ZIdk/2SIZP9kiGT/ZIhk/2SIZP9kiWT/ZIlk/2SJZP9kiWT/ZIlk/2SJZP9kiWT/ZIlk/2WKZP9limT/ + ZYpk/2WKZP9ahWL/WoVi/1qFYv9ahWL/MJvC/zCbwv8wm8L/MJvC/zKt+/8yrfv/Mq37/zKt+/8qkKn/ + KpCp/yqQqf8qkKn/HVwo/x1cKP8dXCj/HVwo/x1dKf8dXSn/HV0p/x1dKf8eXin/Hl4p/x5eKf8eXin/ + Hl8p/x5fKf8eXyn/Hl8p/x5gKv8eYCr/HmAq/x5gKv8fYiv/H2Ir/x9iK/8fYiv/VpRh/1aUYf9WlGH/ + VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/ + VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VKa5/1Smuf9Uprn/VKa5/0m2+/9Jtvv/Sbb7/0m2+/81nL3/ + NZy9/zWcvf81nL3/WX1d/1l9Xf9ZfV3/WX1d/2KDYv9ig2L/YoNi/2KDYv9jg2L/Y4Ni/2ODYv9jg2L/ + Y4Ri/2OEYv9jhGL/Y4Ri/2OFYv9jhWL/Y4Vi/2OFYv9jhWL/Y4Vi/2OFYv9jhWL/Y4Zj/2OGY/9jhmP/ + Y4Zj/2OHY/9jh2P/Y4dj/2OHY/9kh2T/ZIdk/2SHZP9kh2T/ZIhk/2SIZP9kiGT/ZIhk/2SJZP9kiWT/ + ZIlk/2SJZP9kiWT/ZIlk/2SJZP9kiWT/ZYpk/2WKZP9limT/ZYpk/1qFYv9ahWL/WoVi/1qFYv8wm8L/ + MJvC/zCbwv8wm8L/Mq37/zKt+/8yrfv/Mq37/yqQqf8qkKn/KpCp/yqQqf8dXCj/HVwo/x1cKP8dXCj/ + HV0p/x1dKf8dXSn/HV0p/x5eKf8eXin/Hl4p/x5eKf8eXyn/Hl8p/x5fKf8eXyn/HmAq/x5gKv8eYCr/ + HmAq/x9iK/8fYiv/H2Ir/x9iK/9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/ + VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9Uprn/ + VKa5/1Smuf9Uprn/Sbb7/0m2+/9Jtvv/Sbb7/zWcvf81nL3/NZy9/zWcvf9ZfV3/WX1d/1l9Xf9ZfV3/ + YoNi/2KDYv9ig2L/YoNi/2ODYv9jg2L/Y4Ni/2ODYv9jhGL/Y4Ri/2OEYv9jhGL/Y4Vi/2OFYv9jhWL/ + Y4Vi/2OFYv9jhWL/Y4Vi/2OFYv9jhmP/Y4Zj/2OGY/9jhmP/Y4dj/2OHY/9jh2P/Y4dj/2SHZP9kh2T/ + ZIdk/2SHZP9kiGT/ZIhk/2SIZP9kiGT/ZIlk/2SJZP9kiWT/ZIlk/2SJZP9kiWT/ZIlk/2SJZP9limT/ + ZYpk/2WKZP9limT/WoVi/1qFYv9ahWL/WoVi/zCbwv8wm8L/MJvC/zCbwv8yrfv/Mq37/zKt+/8yrfv/ + KpCp/yqQqf8qkKn/KpCp/x1cKP8dXCj/HVwo/x1cKP8dXSn/HV0p/x1dKf8dXSn/Hl4p/x5eKf8eXin/ + Hl4p/x5fKf8eXyn/Hl8p/x5fKf8eYCr/HmAq/x5gKv8eYCr/H2Ir/x9iK/8fYiv/H2Ir/1aUYf9WlGH/ + VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/ + VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1Smuf9Uprn/VKa5/1Smuf9Jtvv/Sbb7/0m2+/9Jtvv/ + NZy9/zWcvf81nL3/NZy9/1l9Xf9ZfV3/WX1d/1l9Xf9ig2L/YoNi/2KDYv9ig2L/Y4Ni/2ODYv9jg2L/ + Y4Ni/2OEYv9jhGL/Y4Ri/2OEYv9jhWL/Y4Vi/2OFYv9jhWL/Y4Vi/2OFYv9jhWL/Y4Vi/2OGY/9jhmP/ + Y4Zj/2OGY/9jh2P/Y4dj/2OHY/9jh2P/ZIdk/2SHZP9kh2T/ZIdk/2SIZP9kiGT/ZIhk/2SIZP9kiWT/ + ZIlk/2SJZP9kiWT/ZIlk/2SJZP9kiWT/ZIlk/2WKZP9limT/ZYpk/2WKZP9ahWL/WoVi/1qFYv9ahWL/ + MJvC/zCbwv8wm8L/MJvC/zKt+/8yrfv/Mq37/zKt+/8qkKn/KpCp/yqQqf8qkKn/HVwo/x1cKP8dXCj/ + HVwo/x1dKf8dXSn/HV0p/x1dKf8eXin/Hl4p/x5eKf8eXin/Hl8p/x5fKf8eXyn/Hl8p/x5gKv8eYCr/ + HmAq/x5gKv8fYiv/H2Ir/x9iK/8fYiv/WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/ + WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/WJdl/1iXZf9bn4j/W5+I/1ufiP9bn4j/ + YsD6/2LA+v9iwPr/YsD6/16xzf9esc3/XrHN/16xzf/O1Mb/ztTG/87Uxv/O1Mb/19nN/9fZzf/X2c3/ + 19nN/8TKuv/Eyrr/xMq6/8TKuv+/xrT/v8a0/7/GtP+/xrT/v8az/7/Gs/+/xrP/v8az/7/Gs/+/xrP/ + v8az/7/Gs/+/xrP/v8az/7/Gs/+/xrP/v8e0/7/HtP+/x7T/v8e0/7/HtP+/x7T/v8e0/7/HtP+/x7T/ + v8e0/7/HtP+/x7T/v8e0/7/HtP+/x7T/v8e0/7/ItP+/yLT/v8i0/7/ItP+/yLT/v8i0/7/ItP+/yLT/ + v8i0/7/ItP+/yLT/v8i0/83Swv/N0sL/zdLC/83Swv++ybb/vsm2/77Jtv++ybb/Lp3D/y6dw/8uncP/ + Lp3D/zKt+v8yrfr/Mq36/zKt+v8jdV7/I3Ve/yN1Xv8jdV7/HV4q/x1eKv8dXir/HV4q/x1fKv8dXyr/ + HV8q/x1fKv8eYCv/HmAr/x5gK/8eYCv/HmEr/x5hK/8eYSv/HmEr/x5iLP8eYiz/HmIs/x5iLP9Yl2X/ + WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/ + WJdl/1iXZf9Yl2X/WJdl/1ufiP9bn4j/W5+I/1ufiP9iwPr/YsD6/2LA+v9iwPr/XrHN/16xzf9esc3/ + XrHN/87Uxv/O1Mb/ztTG/87Uxv/X2c3/19nN/9fZzf/X2c3/xMq6/8TKuv/Eyrr/xMq6/7/GtP+/xrT/ + v8a0/7/GtP+/xrP/v8az/7/Gs/+/xrP/v8az/7/Gs/+/xrP/v8az/7/Gs/+/xrP/v8az/7/Gs/+/x7T/ + v8e0/7/HtP+/x7T/v8e0/7/HtP+/x7T/v8e0/7/HtP+/x7T/v8e0/7/HtP+/x7T/v8e0/7/HtP+/x7T/ + v8i0/7/ItP+/yLT/v8i0/7/ItP+/yLT/v8i0/7/ItP+/yLT/v8i0/7/ItP+/yLT/zdLC/83Swv/N0sL/ + zdLC/77Jtv++ybb/vsm2/77Jtv8uncP/Lp3D/y6dw/8uncP/Mq36/zKt+v8yrfr/Mq36/yN1Xv8jdV7/ + I3Ve/yN1Xv8dXir/HV4q/x1eKv8dXir/HV8q/x1fKv8dXyr/HV8q/x5gK/8eYCv/HmAr/x5gK/8eYSv/ + HmEr/x5hK/8eYSv/HmIs/x5iLP8eYiz/HmIs/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/ + WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/W5+I/1ufiP9bn4j/ + W5+I/2LA+v9iwPr/YsD6/2LA+v9esc3/XrHN/16xzf9esc3/ztTG/87Uxv/O1Mb/ztTG/9fZzf/X2c3/ + 19nN/9fZzf/Eyrr/xMq6/8TKuv/Eyrr/v8a0/7/GtP+/xrT/v8a0/7/Gs/+/xrP/v8az/7/Gs/+/xrP/ + v8az/7/Gs/+/xrP/v8az/7/Gs/+/xrP/v8az/7/HtP+/x7T/v8e0/7/HtP+/x7T/v8e0/7/HtP+/x7T/ + v8e0/7/HtP+/x7T/v8e0/7/HtP+/x7T/v8e0/7/HtP+/yLT/v8i0/7/ItP+/yLT/v8i0/7/ItP+/yLT/ + v8i0/7/ItP+/yLT/v8i0/7/ItP/N0sL/zdLC/83Swv/N0sL/vsm2/77Jtv++ybb/vsm2/y6dw/8uncP/ + Lp3D/y6dw/8yrfr/Mq36/zKt+v8yrfr/I3Ve/yN1Xv8jdV7/I3Ve/x1eKv8dXir/HV4q/x1eKv8dXyr/ + HV8q/x1fKv8dXyr/HmAr/x5gK/8eYCv/HmAr/x5hK/8eYSv/HmEr/x5hK/8eYiz/HmIs/x5iLP8eYiz/ + WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/ + WJdl/1iXZf9Yl2X/WJdl/1iXZf9bn4j/W5+I/1ufiP9bn4j/YsD6/2LA+v9iwPr/YsD6/16xzf9esc3/ + XrHN/16xzf/O1Mb/ztTG/87Uxv/O1Mb/19nN/9fZzf/X2c3/19nN/8TKuv/Eyrr/xMq6/8TKuv+/xrT/ + v8a0/7/GtP+/xrT/v8az/7/Gs/+/xrP/v8az/7/Gs/+/xrP/v8az/7/Gs/+/xrP/v8az/7/Gs/+/xrP/ + v8e0/7/HtP+/x7T/v8e0/7/HtP+/x7T/v8e0/7/HtP+/x7T/v8e0/7/HtP+/x7T/v8e0/7/HtP+/x7T/ + v8e0/7/ItP+/yLT/v8i0/7/ItP+/yLT/v8i0/7/ItP+/yLT/v8i0/7/ItP+/yLT/v8i0/83Swv/N0sL/ + zdLC/83Swv++ybb/vsm2/77Jtv++ybb/Lp3D/y6dw/8uncP/Lp3D/zKt+v8yrfr/Mq36/zKt+v8jdV7/ + I3Ve/yN1Xv8jdV7/HV4q/x1eKv8dXir/HV4q/x1fKv8dXyr/HV8q/x1fKv8eYCv/HmAr/x5gK/8eYCv/ + HmEr/x5hK/8eYSv/HmEr/x5iLP8eYiz/HmIs/x5iLP9cmmj/XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/ + XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/XJpo/2W73/9lu9// + Zbvf/2W73/9lv+3/Zb/t/2W/7f9lv+3/VIBm/1SAZv9UgGb/VIBm//v07f/79O3/+/Tt//v07f9fgmT/ + X4Jk/1+CZP9fgmT/Unpa/1J6Wv9Selr/Unpa/1B4WP9QeFj/UHhY/1B4WP88akX/PGpF/zxqRf88akX/ + IFUr/yBVK/8gVSv/IFUr/xpRJP8aUST/GlEk/xpRJP8nWzH/J1sx/ydbMf8nWzH/J1wx/ydcMf8nXDH/ + J1wx/xtUJv8bVCb/G1Qm/xtUJv8bVSb/G1Um/xtVJv8bVSb/G1Yn/xtWJ/8bVif/G1Yn/xxXJ/8cVyf/ + HFcn/xxXJ/8cWCj/HFgo/xxYKP8cWCj/LGQ1/yxkNf8sZDX/LGQ1//nw5//58Of/+fDn//nw5/8gZT7/ + IGU+/yBlPv8gZT7/Mqrr/zKq6/8yquv/Mqrr/zGk1/8xpNf/MaTX/zGk1/8eXir/Hl4q/x5eKv8eXir/ + Hl8r/x5fK/8eXyv/Hl8r/x5gK/8eYCv/HmAr/x5gK/8fYCv/H2Ar/x9gK/8fYCv/H2Is/x9iLP8fYiz/ + H2Is/1yaaP9cmmj/XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/ + XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/Zbvf/2W73/9lu9//Zbvf/2W/7f9lv+3/Zb/t/2W/7f9UgGb/ + VIBm/1SAZv9UgGb/+/Tt//v07f/79O3/+/Tt/1+CZP9fgmT/X4Jk/1+CZP9Selr/Unpa/1J6Wv9Selr/ + UHhY/1B4WP9QeFj/UHhY/zxqRf88akX/PGpF/zxqRf8gVSv/IFUr/yBVK/8gVSv/GlEk/xpRJP8aUST/ + GlEk/ydbMf8nWzH/J1sx/ydbMf8nXDH/J1wx/ydcMf8nXDH/G1Qm/xtUJv8bVCb/G1Qm/xtVJv8bVSb/ + G1Um/xtVJv8bVif/G1Yn/xtWJ/8bVif/HFcn/xxXJ/8cVyf/HFcn/xxYKP8cWCj/HFgo/xxYKP8sZDX/ + LGQ1/yxkNf8sZDX/+fDn//nw5//58Of/+fDn/yBlPv8gZT7/IGU+/yBlPv8yquv/Mqrr/zKq6/8yquv/ + MaTX/zGk1/8xpNf/MaTX/x5eKv8eXir/Hl4q/x5eKv8eXyv/Hl8r/x5fK/8eXyv/HmAr/x5gK/8eYCv/ + HmAr/x9gK/8fYCv/H2Ar/x9gK/8fYiz/H2Is/x9iLP8fYiz/XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/ + XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/XJpo/1yaaP9lu9// + Zbvf/2W73/9lu9//Zb/t/2W/7f9lv+3/Zb/t/1SAZv9UgGb/VIBm/1SAZv/79O3/+/Tt//v07f/79O3/ + X4Jk/1+CZP9fgmT/X4Jk/1J6Wv9Selr/Unpa/1J6Wv9QeFj/UHhY/1B4WP9QeFj/PGpF/zxqRf88akX/ + PGpF/yBVK/8gVSv/IFUr/yBVK/8aUST/GlEk/xpRJP8aUST/J1sx/ydbMf8nWzH/J1sx/ydcMf8nXDH/ + J1wx/ydcMf8bVCb/G1Qm/xtUJv8bVCb/G1Um/xtVJv8bVSb/G1Um/xtWJ/8bVif/G1Yn/xtWJ/8cVyf/ + HFcn/xxXJ/8cVyf/HFgo/xxYKP8cWCj/HFgo/yxkNf8sZDX/LGQ1/yxkNf/58Of/+fDn//nw5//58Of/ + IGU+/yBlPv8gZT7/IGU+/zKq6/8yquv/Mqrr/zKq6/8xpNf/MaTX/zGk1/8xpNf/Hl4q/x5eKv8eXir/ + Hl4q/x5fK/8eXyv/Hl8r/x5fK/8eYCv/HmAr/x5gK/8eYCv/H2Ar/x9gK/8fYCv/H2Ar/x9iLP8fYiz/ + H2Is/x9iLP9cmmj/XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/ + XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/XJpo/2W73/9lu9//Zbvf/2W73/9lv+3/Zb/t/2W/7f9lv+3/ + VIBm/1SAZv9UgGb/VIBm//v07f/79O3/+/Tt//v07f9fgmT/X4Jk/1+CZP9fgmT/Unpa/1J6Wv9Selr/ + Unpa/1B4WP9QeFj/UHhY/1B4WP88akX/PGpF/zxqRf88akX/IFUr/yBVK/8gVSv/IFUr/xpRJP8aUST/ + GlEk/xpRJP8nWzH/J1sx/ydbMf8nWzH/J1wx/ydcMf8nXDH/J1wx/xtUJv8bVCb/G1Qm/xtUJv8bVSb/ + G1Um/xtVJv8bVSb/G1Yn/xtWJ/8bVif/G1Yn/xxXJ/8cVyf/HFcn/xxXJ/8cWCj/HFgo/xxYKP8cWCj/ + LGQ1/yxkNf8sZDX/LGQ1//nw5//58Of/+fDn//nw5/8gZT7/IGU+/yBlPv8gZT7/Mqrr/zKq6/8yquv/ + Mqrr/zGk1/8xpNf/MaTX/zGk1/8eXir/Hl4q/x5eKv8eXir/Hl8r/x5fK/8eXyv/Hl8r/x5gK/8eYCv/ + HmAr/x5gK/8fYCv/H2Ar/x9gK/8fYCv/H2Is/x9iLP8fYiz/H2Is/2CdbP9gnWz/YJ1s/2CdbP9gnWz/ + YJ1s/2CdbP9gnWz/YJ1s/2CdbP9gnWz/YJ1s/2CdbP9gnWz/YJ1s/2CdbP9ho4P/YaOD/2Gjg/9ho4P/ + acX8/2nF/P9pxfz/acX8/2Cgof9goKH/YKCh/2Cgof9Velz/VXpc/1V6XP9Velz/+/Xw//v18P/79fD/ + +/Xw/1+DZv9fg2b/X4Nm/1+DZv9VfV7/VX1e/1V9Xv9VfV7/VX1e/1V9Xv9VfV7/VX1e/1V9Xv9VfV7/ + VX1e/1V9Xv9UfV3/VH1d/1R9Xf9UfV3/PGtF/zxrRf88a0X/PGtF/5Cnjv+Qp47/kKeO/5Cnjv+Ppoz/ + j6aM/4+mjP+Ppoz/G1Qn/xtUJ/8bVCf/G1Qn/xtVJ/8bVSf/G1Un/xtVJ/8cVij/HFYo/xxWKP8cVij/ + HFgo/xxYKP8cWCj/HFgo/xxZKf8cWSn/HFkp/xxZKf8rYjX/K2I1/ytiNf8rYjX/+vLq//ry6v/68ur/ + +vLq/x1bKv8dWyr/HVsq/x1bKv8piIf/KYiH/ymIh/8piIf/M7D7/zOw+/8zsPv/M7D7/yNwUP8jcFD/ + I3BQ/yNwUP8eXyz/Hl8s/x5fLP8eXyz/H2As/x9gLP8fYCz/H2As/x9hLf8fYS3/H2Et/x9hLf8gYy3/ + IGMt/yBjLf8gYy3/YJ1s/2CdbP9gnWz/YJ1s/2CdbP9gnWz/YJ1s/2CdbP9gnWz/YJ1s/2CdbP9gnWz/ + YJ1s/2CdbP9gnWz/YJ1s/2Gjg/9ho4P/YaOD/2Gjg/9pxfz/acX8/2nF/P9pxfz/YKCh/2Cgof9goKH/ + YKCh/1V6XP9Velz/VXpc/1V6XP/79fD/+/Xw//v18P/79fD/X4Nm/1+DZv9fg2b/X4Nm/1V9Xv9VfV7/ + VX1e/1V9Xv9VfV7/VX1e/1V9Xv9VfV7/VX1e/1V9Xv9VfV7/VX1e/1R9Xf9UfV3/VH1d/1R9Xf88a0X/ + PGtF/zxrRf88a0X/kKeO/5Cnjv+Qp47/kKeO/4+mjP+Ppoz/j6aM/4+mjP8bVCf/G1Qn/xtUJ/8bVCf/ + G1Un/xtVJ/8bVSf/G1Un/xxWKP8cVij/HFYo/xxWKP8cWCj/HFgo/xxYKP8cWCj/HFkp/xxZKf8cWSn/ + HFkp/ytiNf8rYjX/K2I1/ytiNf/68ur/+vLq//ry6v/68ur/HVsq/x1bKv8dWyr/HVsq/ymIh/8piIf/ + KYiH/ymIh/8zsPv/M7D7/zOw+/8zsPv/I3BQ/yNwUP8jcFD/I3BQ/x5fLP8eXyz/Hl8s/x5fLP8fYCz/ + H2As/x9gLP8fYCz/H2Et/x9hLf8fYS3/H2Et/yBjLf8gYy3/IGMt/yBjLf9gnWz/YJ1s/2CdbP9gnWz/ + YJ1s/2CdbP9gnWz/YJ1s/2CdbP9gnWz/YJ1s/2CdbP9gnWz/YJ1s/2CdbP9gnWz/YaOD/2Gjg/9ho4P/ + YaOD/2nF/P9pxfz/acX8/2nF/P9goKH/YKCh/2Cgof9goKH/VXpc/1V6XP9Velz/VXpc//v18P/79fD/ + +/Xw//v18P9fg2b/X4Nm/1+DZv9fg2b/VX1e/1V9Xv9VfV7/VX1e/1V9Xv9VfV7/VX1e/1V9Xv9VfV7/ + VX1e/1V9Xv9VfV7/VH1d/1R9Xf9UfV3/VH1d/zxrRf88a0X/PGtF/zxrRf+Qp47/kKeO/5Cnjv+Qp47/ + j6aM/4+mjP+Ppoz/j6aM/xtUJ/8bVCf/G1Qn/xtUJ/8bVSf/G1Un/xtVJ/8bVSf/HFYo/xxWKP8cVij/ + HFYo/xxYKP8cWCj/HFgo/xxYKP8cWSn/HFkp/xxZKf8cWSn/K2I1/ytiNf8rYjX/K2I1//ry6v/68ur/ + +vLq//ry6v8dWyr/HVsq/x1bKv8dWyr/KYiH/ymIh/8piIf/KYiH/zOw+/8zsPv/M7D7/zOw+/8jcFD/ + I3BQ/yNwUP8jcFD/Hl8s/x5fLP8eXyz/Hl8s/x9gLP8fYCz/H2As/x9gLP8fYS3/H2Et/x9hLf8fYS3/ + IGMt/yBjLf8gYy3/IGMt/2CdbP9gnWz/YJ1s/2CdbP9gnWz/YJ1s/2CdbP9gnWz/YJ1s/2CdbP9gnWz/ + YJ1s/2CdbP9gnWz/YJ1s/2CdbP9ho4P/YaOD/2Gjg/9ho4P/acX8/2nF/P9pxfz/acX8/2Cgof9goKH/ + YKCh/2Cgof9Velz/VXpc/1V6XP9Velz/+/Xw//v18P/79fD/+/Xw/1+DZv9fg2b/X4Nm/1+DZv9VfV7/ + VX1e/1V9Xv9VfV7/VX1e/1V9Xv9VfV7/VX1e/1V9Xv9VfV7/VX1e/1V9Xv9UfV3/VH1d/1R9Xf9UfV3/ + PGtF/zxrRf88a0X/PGtF/5Cnjv+Qp47/kKeO/5Cnjv+Ppoz/j6aM/4+mjP+Ppoz/G1Qn/xtUJ/8bVCf/ + G1Qn/xtVJ/8bVSf/G1Un/xtVJ/8cVij/HFYo/xxWKP8cVij/HFgo/xxYKP8cWCj/HFgo/xxZKf8cWSn/ + HFkp/xxZKf8rYjX/K2I1/ytiNf8rYjX/+vLq//ry6v/68ur/+vLq/x1bKv8dWyr/HVsq/x1bKv8piIf/ + KYiH/ymIh/8piIf/M7D7/zOw+/8zsPv/M7D7/yNwUP8jcFD/I3BQ/yNwUP8eXyz/Hl8s/x5fLP8eXyz/ + H2As/x9gLP8fYCz/H2As/x9hLf8fYS3/H2Et/x9hLf8gYy3/IGMt/yBjLf8gYy3/Y59v/2Ofb/9jn2// + Y59v/2Ofb/9jn2//Y59v/2Ofb/9jn2//Y59v/2Ofb/9jn2//Y59v/2Ofb/9jn2//Y59v/2eztP9ns7T/ + Z7O0/2eztP9rxff/a8X3/2vF9/9rxff/WYFq/1mBav9ZgWr/WYFq/1d8X/9XfF//V3xf/1d8X//89vH/ + /Pbx//z28f/89vH/YoRp/2KEaf9ihGn/YoRp/1h+YP9YfmD/WH5g/1h+YP9Yf2D/WH9g/1h/YP9Yf2D/ + WX9h/1l/Yf9Zf2H/WX9h/1mAYf9ZgGH/WYBh/1mAYf9ZgWL/WYFi/1mBYv9ZgWL/r7+t/6+/rf+vv63/ + r7+t/6G0nv+htJ7/obSe/6G0nv8eVir/HlYq/x5WKv8eVir/HFUn/xxVJ/8cVSf/HFUn/xxWKP8cVij/ + HFYo/xxWKP8cVyj/HFco/xxXKP8cVyj/HVgp/x1YKf8dWCn/HVgp/ytiNf8rYjX/K2I1/ytiNf/78+z/ + +/Ps//vz7P/78+z/Hlsq/x5bKv8eWyr/Hlsq/yBmPf8gZj3/IGY9/yBmPf80sPf/NLD3/zSw9/80sPf/ + K5CX/yuQl/8rkJf/K5CX/x9fLP8fXyz/H18s/x9fLP8fYCz/H2As/x9gLP8fYCz/IGEt/yBhLf8gYS3/ + IGEt/yBiLv8gYi7/IGIu/yBiLv9jn2//Y59v/2Ofb/9jn2//Y59v/2Ofb/9jn2//Y59v/2Ofb/9jn2// + Y59v/2Ofb/9jn2//Y59v/2Ofb/9jn2//Z7O0/2eztP9ns7T/Z7O0/2vF9/9rxff/a8X3/2vF9/9ZgWr/ + WYFq/1mBav9ZgWr/V3xf/1d8X/9XfF//V3xf//z28f/89vH//Pbx//z28f9ihGn/YoRp/2KEaf9ihGn/ + WH5g/1h+YP9YfmD/WH5g/1h/YP9Yf2D/WH9g/1h/YP9Zf2H/WX9h/1l/Yf9Zf2H/WYBh/1mAYf9ZgGH/ + WYBh/1mBYv9ZgWL/WYFi/1mBYv+vv63/r7+t/6+/rf+vv63/obSe/6G0nv+htJ7/obSe/x5WKv8eVir/ + HlYq/x5WKv8cVSf/HFUn/xxVJ/8cVSf/HFYo/xxWKP8cVij/HFYo/xxXKP8cVyj/HFco/xxXKP8dWCn/ + HVgp/x1YKf8dWCn/K2I1/ytiNf8rYjX/K2I1//vz7P/78+z/+/Ps//vz7P8eWyr/Hlsq/x5bKv8eWyr/ + IGY9/yBmPf8gZj3/IGY9/zSw9/80sPf/NLD3/zSw9/8rkJf/K5CX/yuQl/8rkJf/H18s/x9fLP8fXyz/ + H18s/x9gLP8fYCz/H2As/x9gLP8gYS3/IGEt/yBhLf8gYS3/IGIu/yBiLv8gYi7/IGIu/2Ofb/9jn2// + Y59v/2Ofb/9jn2//Y59v/2Ofb/9jn2//Y59v/2Ofb/9jn2//Y59v/2Ofb/9jn2//Y59v/2Ofb/9ns7T/ + Z7O0/2eztP9ns7T/a8X3/2vF9/9rxff/a8X3/1mBav9ZgWr/WYFq/1mBav9XfF//V3xf/1d8X/9XfF// + /Pbx//z28f/89vH//Pbx/2KEaf9ihGn/YoRp/2KEaf9YfmD/WH5g/1h+YP9YfmD/WH9g/1h/YP9Yf2D/ + WH9g/1l/Yf9Zf2H/WX9h/1l/Yf9ZgGH/WYBh/1mAYf9ZgGH/WYFi/1mBYv9ZgWL/WYFi/6+/rf+vv63/ + r7+t/6+/rf+htJ7/obSe/6G0nv+htJ7/HlYq/x5WKv8eVir/HlYq/xxVJ/8cVSf/HFUn/xxVJ/8cVij/ + HFYo/xxWKP8cVij/HFco/xxXKP8cVyj/HFco/x1YKf8dWCn/HVgp/x1YKf8rYjX/K2I1/ytiNf8rYjX/ + +/Ps//vz7P/78+z/+/Ps/x5bKv8eWyr/Hlsq/x5bKv8gZj3/IGY9/yBmPf8gZj3/NLD3/zSw9/80sPf/ + NLD3/yuQl/8rkJf/K5CX/yuQl/8fXyz/H18s/x9fLP8fXyz/H2As/x9gLP8fYCz/H2As/yBhLf8gYS3/ + IGEt/yBhLf8gYi7/IGIu/yBiLv8gYi7/Y59v/2Ofb/9jn2//Y59v/2Ofb/9jn2//Y59v/2Ofb/9jn2// + Y59v/2Ofb/9jn2//Y59v/2Ofb/9jn2//Y59v/2eztP9ns7T/Z7O0/2eztP9rxff/a8X3/2vF9/9rxff/ + WYFq/1mBav9ZgWr/WYFq/1d8X/9XfF//V3xf/1d8X//89vH//Pbx//z28f/89vH/YoRp/2KEaf9ihGn/ + YoRp/1h+YP9YfmD/WH5g/1h+YP9Yf2D/WH9g/1h/YP9Yf2D/WX9h/1l/Yf9Zf2H/WX9h/1mAYf9ZgGH/ + WYBh/1mAYf9ZgWL/WYFi/1mBYv9ZgWL/r7+t/6+/rf+vv63/r7+t/6G0nv+htJ7/obSe/6G0nv8eVir/ + HlYq/x5WKv8eVir/HFUn/xxVJ/8cVSf/HFUn/xxWKP8cVij/HFYo/xxWKP8cVyj/HFco/xxXKP8cVyj/ + HVgp/x1YKf8dWCn/HVgp/ytiNf8rYjX/K2I1/ytiNf/78+z/+/Ps//vz7P/78+z/Hlsq/x5bKv8eWyr/ + Hlsq/yBmPf8gZj3/IGY9/yBmPf80sPf/NLD3/zSw9/80sPf/K5CX/yuQl/8rkJf/K5CX/x9fLP8fXyz/ + H18s/x9fLP8fYCz/H2As/x9gLP8fYCz/IGEt/yBhLf8gYS3/IGEt/yBiLv8gYi7/IGIu/yBiLv9no3P/ + Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9no3P/ + bb7X/22+1/9tvtf/bb7X/2y81/9svNf/bLzX/2y81/9bfmL/W35i/1t+Yv9bfmL/W39j/1t/Y/9bf2P/ + W39j//z48//8+PP//Pjz//z48/9mh2z/Zods/2aHbP9mh2z/XIFk/1yBZP9cgWT/XIFk/1yBZP9cgWT/ + XIFk/1yBZP9miG3/Zoht/2aIbf9miG3/sMCv/7DAr/+wwK//sMCv/7LCsf+ywrH/ssKx/7LCsf/Z3tT/ + 2d7U/9ne1P/Z3tT/2d7U/9ne1P/Z3tT/2d7U/6/Arf+vwK3/r8Ct/6/Arf+bspr/m7Ka/5uymv+bspr/ + KV80/ylfNP8pXzT/KV80/x1XKP8dVyj/HVco/x1XKP8dWCn/HVgp/x1YKf8dWCn/K2M2/ytjNv8rYzb/ + K2M2//v17v/79e7/+/Xu//v17v8eXCv/Hlwr/x5cK/8eXCv/Hl0r/x5dK/8eXSv/Hl0r/zGjy/8xo8v/ + MaPL/zGjy/8wosb/MKLG/zCixv8wosb/H2As/x9gLP8fYCz/H2As/yBhLf8gYS3/IGEt/yBhLf8gYi3/ + IGIt/yBiLf8gYi3/IGMu/yBjLv8gYy7/IGMu/2ejc/9no3P/Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9no3P/ + Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9tvtf/bb7X/22+1/9tvtf/bLzX/2y81/9svNf/ + bLzX/1t+Yv9bfmL/W35i/1t+Yv9bf2P/W39j/1t/Y/9bf2P//Pjz//z48//8+PP//Pjz/2aHbP9mh2z/ + Zods/2aHbP9cgWT/XIFk/1yBZP9cgWT/XIFk/1yBZP9cgWT/XIFk/2aIbf9miG3/Zoht/2aIbf+wwK// + sMCv/7DAr/+wwK//ssKx/7LCsf+ywrH/ssKx/9ne1P/Z3tT/2d7U/9ne1P/Z3tT/2d7U/9ne1P/Z3tT/ + r8Ct/6/Arf+vwK3/r8Ct/5uymv+bspr/m7Ka/5uymv8pXzT/KV80/ylfNP8pXzT/HVco/x1XKP8dVyj/ + HVco/x1YKf8dWCn/HVgp/x1YKf8rYzb/K2M2/ytjNv8rYzb/+/Xu//v17v/79e7/+/Xu/x5cK/8eXCv/ + Hlwr/x5cK/8eXSv/Hl0r/x5dK/8eXSv/MaPL/zGjy/8xo8v/MaPL/zCixv8wosb/MKLG/zCixv8fYCz/ + H2As/x9gLP8fYCz/IGEt/yBhLf8gYS3/IGEt/yBiLf8gYi3/IGIt/yBiLf8gYy7/IGMu/yBjLv8gYy7/ + Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9no3P/ + Z6Nz/22+1/9tvtf/bb7X/22+1/9svNf/bLzX/2y81/9svNf/W35i/1t+Yv9bfmL/W35i/1t/Y/9bf2P/ + W39j/1t/Y//8+PP//Pjz//z48//8+PP/Zods/2aHbP9mh2z/Zods/1yBZP9cgWT/XIFk/1yBZP9cgWT/ + XIFk/1yBZP9cgWT/Zoht/2aIbf9miG3/Zoht/7DAr/+wwK//sMCv/7DAr/+ywrH/ssKx/7LCsf+ywrH/ + 2d7U/9ne1P/Z3tT/2d7U/9ne1P/Z3tT/2d7U/9ne1P+vwK3/r8Ct/6/Arf+vwK3/m7Ka/5uymv+bspr/ + m7Ka/ylfNP8pXzT/KV80/ylfNP8dVyj/HVco/x1XKP8dVyj/HVgp/x1YKf8dWCn/HVgp/ytjNv8rYzb/ + K2M2/ytjNv/79e7/+/Xu//v17v/79e7/Hlwr/x5cK/8eXCv/Hlwr/x5dK/8eXSv/Hl0r/x5dK/8xo8v/ + MaPL/zGjy/8xo8v/MKLG/zCixv8wosb/MKLG/x9gLP8fYCz/H2As/x9gLP8gYS3/IGEt/yBhLf8gYS3/ + IGIt/yBiLf8gYi3/IGIt/yBjLv8gYy7/IGMu/yBjLv9no3P/Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9no3P/ + Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9no3P/bb7X/22+1/9tvtf/bb7X/2y81/9svNf/ + bLzX/2y81/9bfmL/W35i/1t+Yv9bfmL/W39j/1t/Y/9bf2P/W39j//z48//8+PP//Pjz//z48/9mh2z/ + Zods/2aHbP9mh2z/XIFk/1yBZP9cgWT/XIFk/1yBZP9cgWT/XIFk/1yBZP9miG3/Zoht/2aIbf9miG3/ + sMCv/7DAr/+wwK//sMCv/7LCsf+ywrH/ssKx/7LCsf/Z3tT/2d7U/9ne1P/Z3tT/2d7U/9ne1P/Z3tT/ + 2d7U/6/Arf+vwK3/r8Ct/6/Arf+bspr/m7Ka/5uymv+bspr/KV80/ylfNP8pXzT/KV80/x1XKP8dVyj/ + HVco/x1XKP8dWCn/HVgp/x1YKf8dWCn/K2M2/ytjNv8rYzb/K2M2//v17v/79e7/+/Xu//v17v8eXCv/ + Hlwr/x5cK/8eXCv/Hl0r/x5dK/8eXSv/Hl0r/zGjy/8xo8v/MaPL/zGjy/8wosb/MKLG/zCixv8wosb/ + H2As/x9gLP8fYCz/H2As/yBhLf8gYS3/IGEt/yBhLf8gYi3/IGIt/yBiLf8gYi3/IGMu/yBjLv8gYy7/ + IGMu/2qld/9qpXf/aqV3/2qld/9qpXf/aqV3/2qld/9qpXf/aqV3/2qld/9qpXf/aqV3/2qld/9qpXf/ + aqV3/2qld/9xxuz/ccbs/3HG7P9xxuz/bLO//2yzv/9ss7//bLO//16AZf9egGX/XoBl/16AZf9egWX/ + XoFl/16BZf9egWX//fn1//359f/9+fX//fn1/2iJb/9oiW//aIlv/2iJb/9eg2f/XoNn/16DZ/9eg2f/ + XoNn/16DZ/9eg2f/XoNn/2iKcP9oinD/aIpw/2iKcP+xwbH/scGx/7HBsf+xwbH/s8Oz/7PDs/+zw7P/ + s8Oz/9vg1v/b4Nb/2+DW/9vg1v/b4Nb/2+DW/9vg1v/b4Nb/tMS0/7TEtP+0xLT/tMS0/7LDsv+yw7L/ + ssOy/7LDsv9Sflz/Un5c/1J+XP9Sflz/IFos/yBaLP8gWiz/IFos/x1YKv8dWCr/HVgq/x1YKv8rYjb/ + K2I2/ytiNv8rYjb//Pbw//z28P/89vD//Pbw/x5bLP8eWyz/Hlss/x5bLP8eXCz/Hlws/x5cLP8eXCz/ + Lpiq/y6Yqv8umKr/Lpiq/zSt5f80reX/NK3l/zSt5f8fXy3/H18t/x9fLf8fXy3/H2Au/x9gLv8fYC7/ + H2Au/yBhLv8gYS7/IGEu/yBhLv8gYy//IGMv/yBjL/8gYy//aqV3/2qld/9qpXf/aqV3/2qld/9qpXf/ + aqV3/2qld/9qpXf/aqV3/2qld/9qpXf/aqV3/2qld/9qpXf/aqV3/3HG7P9xxuz/ccbs/3HG7P9ss7// + bLO//2yzv/9ss7//XoBl/16AZf9egGX/XoBl/16BZf9egWX/XoFl/16BZf/9+fX//fn1//359f/9+fX/ + aIlv/2iJb/9oiW//aIlv/16DZ/9eg2f/XoNn/16DZ/9eg2f/XoNn/16DZ/9eg2f/aIpw/2iKcP9oinD/ + aIpw/7HBsf+xwbH/scGx/7HBsf+zw7P/s8Oz/7PDs/+zw7P/2+DW/9vg1v/b4Nb/2+DW/9vg1v/b4Nb/ + 2+DW/9vg1v+0xLT/tMS0/7TEtP+0xLT/ssOy/7LDsv+yw7L/ssOy/1J+XP9Sflz/Un5c/1J+XP8gWiz/ + IFos/yBaLP8gWiz/HVgq/x1YKv8dWCr/HVgq/ytiNv8rYjb/K2I2/ytiNv/89vD//Pbw//z28P/89vD/ + Hlss/x5bLP8eWyz/Hlss/x5cLP8eXCz/Hlws/x5cLP8umKr/Lpiq/y6Yqv8umKr/NK3l/zSt5f80reX/ + NK3l/x9fLf8fXy3/H18t/x9fLf8fYC7/H2Au/x9gLv8fYC7/IGEu/yBhLv8gYS7/IGEu/yBjL/8gYy// + IGMv/yBjL/9qpXf/aqV3/2qld/9qpXf/aqV3/2qld/9qpXf/aqV3/2qld/9qpXf/aqV3/2qld/9qpXf/ + aqV3/2qld/9qpXf/ccbs/3HG7P9xxuz/ccbs/2yzv/9ss7//bLO//2yzv/9egGX/XoBl/16AZf9egGX/ + XoFl/16BZf9egWX/XoFl//359f/9+fX//fn1//359f9oiW//aIlv/2iJb/9oiW//XoNn/16DZ/9eg2f/ + XoNn/16DZ/9eg2f/XoNn/16DZ/9oinD/aIpw/2iKcP9oinD/scGx/7HBsf+xwbH/scGx/7PDs/+zw7P/ + s8Oz/7PDs//b4Nb/2+DW/9vg1v/b4Nb/2+DW/9vg1v/b4Nb/2+DW/7TEtP+0xLT/tMS0/7TEtP+yw7L/ + ssOy/7LDsv+yw7L/Un5c/1J+XP9Sflz/Un5c/yBaLP8gWiz/IFos/yBaLP8dWCr/HVgq/x1YKv8dWCr/ + K2I2/ytiNv8rYjb/K2I2//z28P/89vD//Pbw//z28P8eWyz/Hlss/x5bLP8eWyz/Hlws/x5cLP8eXCz/ + Hlws/y6Yqv8umKr/Lpiq/y6Yqv80reX/NK3l/zSt5f80reX/H18t/x9fLf8fXy3/H18t/x9gLv8fYC7/ + H2Au/x9gLv8gYS7/IGEu/yBhLv8gYS7/IGMv/yBjL/8gYy//IGMv/2qld/9qpXf/aqV3/2qld/9qpXf/ + aqV3/2qld/9qpXf/aqV3/2qld/9qpXf/aqV3/2qld/9qpXf/aqV3/2qld/9xxuz/ccbs/3HG7P9xxuz/ + bLO//2yzv/9ss7//bLO//16AZf9egGX/XoBl/16AZf9egWX/XoFl/16BZf9egWX//fn1//359f/9+fX/ + /fn1/2iJb/9oiW//aIlv/2iJb/9eg2f/XoNn/16DZ/9eg2f/XoNn/16DZ/9eg2f/XoNn/2iKcP9oinD/ + aIpw/2iKcP+xwbH/scGx/7HBsf+xwbH/s8Oz/7PDs/+zw7P/s8Oz/9vg1v/b4Nb/2+DW/9vg1v/b4Nb/ + 2+DW/9vg1v/b4Nb/tMS0/7TEtP+0xLT/tMS0/7LDsv+yw7L/ssOy/7LDsv9Sflz/Un5c/1J+XP9Sflz/ + IFos/yBaLP8gWiz/IFos/x1YKv8dWCr/HVgq/x1YKv8rYjb/K2I2/ytiNv8rYjb//Pbw//z28P/89vD/ + /Pbw/x5bLP8eWyz/Hlss/x5bLP8eXCz/Hlws/x5cLP8eXCz/Lpiq/y6Yqv8umKr/Lpiq/zSt5f80reX/ + NK3l/zSt5f8fXy3/H18t/x9fLf8fXy3/H2Au/x9gLv8fYC7/H2Au/yBhLv8gYS7/IGEu/yBhLv8gYy// + IGMv/yBjL/8gYy//bah6/22oev9tqHr/bah6/22oev9tqHr/bah6/22oev9tqHr/bah6/22oev9tqHr/ + bal//22pf/9tqX//bal//3TM+/90zPv/dMz7/3TM+/9rqaj/a6mo/2upqP9rqaj/YIJo/2CCaP9ggmj/ + YIJo/2CDaP9gg2j/YINo/2CDaP/9+vb//fr2//369v/9+vb/a4ty/2uLcv9ri3L/a4ty/2GFaf9hhWn/ + YYVp/2GFaf9ihmn/YoZp/2KGaf9ihmn/YoZq/2KGav9ihmr/YoZq/2KHav9ih2r/Yodq/2KHav9jiGv/ + Y4hr/2OIa/9jiGv/tcW1/7XFtf+1xbX/tcW1/7XFtv+1xbb/tcW2/7XFtv9jimv/Y4pr/2OKa/9jimv/ + Y4ps/2OKbP9jimz/Y4ps/2OLbP9ji2z/Y4ts/2OLbP9ahGT/WoRk/1qEZP9ahGT/LGM4/yxjOP8sYzj/ + LGM4/ytiN/8rYjf/K2I3/ytiN//89/L//Pfy//z38v/89/L/Hlws/x5cLP8eXCz/Hlws/x5dLP8eXSz/ + Hl0s/x5dLP8rioj/K4qI/yuKiP8rioj/NbT5/zW0+f81tPn/NbT5/yFkNf8hZDX/IWQ1/yFkNf8gYS7/ + IGEu/yBhLv8gYS7/IGIv/yBiL/8gYi//IGIv/yFjL/8hYy//IWMv/yFjL/9tqHr/bah6/22oev9tqHr/ + bah6/22oev9tqHr/bah6/22oev9tqHr/bah6/22oev9tqX//bal//22pf/9tqX//dMz7/3TM+/90zPv/ + dMz7/2upqP9rqaj/a6mo/2upqP9ggmj/YIJo/2CCaP9ggmj/YINo/2CDaP9gg2j/YINo//369v/9+vb/ + /fr2//369v9ri3L/a4ty/2uLcv9ri3L/YYVp/2GFaf9hhWn/YYVp/2KGaf9ihmn/YoZp/2KGaf9ihmr/ + YoZq/2KGav9ihmr/Yodq/2KHav9ih2r/Yodq/2OIa/9jiGv/Y4hr/2OIa/+1xbX/tcW1/7XFtf+1xbX/ + tcW2/7XFtv+1xbb/tcW2/2OKa/9jimv/Y4pr/2OKa/9jimz/Y4ps/2OKbP9jimz/Y4ts/2OLbP9ji2z/ + Y4ts/1qEZP9ahGT/WoRk/1qEZP8sYzj/LGM4/yxjOP8sYzj/K2I3/ytiN/8rYjf/K2I3//z38v/89/L/ + /Pfy//z38v8eXCz/Hlws/x5cLP8eXCz/Hl0s/x5dLP8eXSz/Hl0s/yuKiP8rioj/K4qI/yuKiP81tPn/ + NbT5/zW0+f81tPn/IWQ1/yFkNf8hZDX/IWQ1/yBhLv8gYS7/IGEu/yBhLv8gYi//IGIv/yBiL/8gYi// + IWMv/yFjL/8hYy//IWMv/22oev9tqHr/bah6/22oev9tqHr/bah6/22oev9tqHr/bah6/22oev9tqHr/ + bah6/22pf/9tqX//bal//22pf/90zPv/dMz7/3TM+/90zPv/a6mo/2upqP9rqaj/a6mo/2CCaP9ggmj/ + YIJo/2CCaP9gg2j/YINo/2CDaP9gg2j//fr2//369v/9+vb//fr2/2uLcv9ri3L/a4ty/2uLcv9hhWn/ + YYVp/2GFaf9hhWn/YoZp/2KGaf9ihmn/YoZp/2KGav9ihmr/YoZq/2KGav9ih2r/Yodq/2KHav9ih2r/ + Y4hr/2OIa/9jiGv/Y4hr/7XFtf+1xbX/tcW1/7XFtf+1xbb/tcW2/7XFtv+1xbb/Y4pr/2OKa/9jimv/ + Y4pr/2OKbP9jimz/Y4ps/2OKbP9ji2z/Y4ts/2OLbP9ji2z/WoRk/1qEZP9ahGT/WoRk/yxjOP8sYzj/ + LGM4/yxjOP8rYjf/K2I3/ytiN/8rYjf//Pfy//z38v/89/L//Pfy/x5cLP8eXCz/Hlws/x5cLP8eXSz/ + Hl0s/x5dLP8eXSz/K4qI/yuKiP8rioj/K4qI/zW0+f81tPn/NbT5/zW0+f8hZDX/IWQ1/yFkNf8hZDX/ + IGEu/yBhLv8gYS7/IGEu/yBiL/8gYi//IGIv/yBiL/8hYy//IWMv/yFjL/8hYy//bah6/22oev9tqHr/ + bah6/22oev9tqHr/bah6/22oev9tqHr/bah6/22oev9tqHr/bal//22pf/9tqX//bal//3TM+/90zPv/ + dMz7/3TM+/9rqaj/a6mo/2upqP9rqaj/YIJo/2CCaP9ggmj/YIJo/2CDaP9gg2j/YINo/2CDaP/9+vb/ + /fr2//369v/9+vb/a4ty/2uLcv9ri3L/a4ty/2GFaf9hhWn/YYVp/2GFaf9ihmn/YoZp/2KGaf9ihmn/ + YoZq/2KGav9ihmr/YoZq/2KHav9ih2r/Yodq/2KHav9jiGv/Y4hr/2OIa/9jiGv/tcW1/7XFtf+1xbX/ + tcW1/7XFtv+1xbb/tcW2/7XFtv9jimv/Y4pr/2OKa/9jimv/Y4ps/2OKbP9jimz/Y4ps/2OLbP9ji2z/ + Y4ts/2OLbP9ahGT/WoRk/1qEZP9ahGT/LGM4/yxjOP8sYzj/LGM4/ytiN/8rYjf/K2I3/ytiN//89/L/ + /Pfy//z38v/89/L/Hlws/x5cLP8eXCz/Hlws/x5dLP8eXSz/Hl0s/x5dLP8rioj/K4qI/yuKiP8rioj/ + NbT5/zW0+f81tPn/NbT5/yFkNf8hZDX/IWQ1/yFkNf8gYS7/IGEu/yBhLv8gYS7/IGIv/yBiL/8gYi// + IGIv/yFjL/8hYy//IWMv/yFjL/9xq37/cat+/3Grfv9xq37/cat+/3Grfv9xq37/cat+/3Grfv9xq37/ + cat+/3Grfv9yr4z/cq+M/3KvjP9yr4z/eM37/3jN+/94zfv/eM37/22loP9tpaD/baWg/22loP9khGv/ + ZIRr/2SEa/9khGv/ZIVr/2SFa/9khWv/ZIVr//36+P/9+vj//fr4//36+P9ujnX/bo51/26Odf9ujnX/ + ZYht/2WIbf9liG3/ZYht/2WIbf9liG3/ZYht/2WIbf9liW3/ZYlt/2WJbf9liW3/Zopt/2aKbf9mim3/ + Zopt/2aKbv9mim7/Zopu/2aKbv+1xbb/tcW2/7XFtv+1xbb/tcW2/7XFtv+1xbb/tcW2/2eMb/9njG// + Z4xv/2eMb/9njW//Z41v/2eNb/9njW//Z45v/2eOb/9njm//Z45v/2eOcP9njnD/Z45w/2eOcP9mjm7/ + Zo5u/2aObv9mjm7/THtW/0x7Vv9Me1b/THtW//z49P/8+PT//Pj0//z49P8eWyz/Hlss/x5bLP8eWyz/ + H10s/x9dLP8fXSz/H10s/yqDd/8qg3f/KoN3/yqDd/82tfn/NrX5/za1+f82tfn/I21H/yNtR/8jbUf/ + I21H/yBhLv8gYS7/IGEu/yBhLv8hYi//IWIv/yFiL/8hYi//IWMw/yFjMP8hYzD/IWMw/3Grfv9xq37/ + cat+/3Grfv9xq37/cat+/3Grfv9xq37/cat+/3Grfv9xq37/cat+/3KvjP9yr4z/cq+M/3KvjP94zfv/ + eM37/3jN+/94zfv/baWg/22loP9tpaD/baWg/2SEa/9khGv/ZIRr/2SEa/9khWv/ZIVr/2SFa/9khWv/ + /fr4//36+P/9+vj//fr4/26Odf9ujnX/bo51/26Odf9liG3/ZYht/2WIbf9liG3/ZYht/2WIbf9liG3/ + ZYht/2WJbf9liW3/ZYlt/2WJbf9mim3/Zopt/2aKbf9mim3/Zopu/2aKbv9mim7/Zopu/7XFtv+1xbb/ + tcW2/7XFtv+1xbb/tcW2/7XFtv+1xbb/Z4xv/2eMb/9njG//Z4xv/2eNb/9njW//Z41v/2eNb/9njm// + Z45v/2eOb/9njm//Z45w/2eOcP9njnD/Z45w/2aObv9mjm7/Zo5u/2aObv9Me1b/THtW/0x7Vv9Me1b/ + /Pj0//z49P/8+PT//Pj0/x5bLP8eWyz/Hlss/x5bLP8fXSz/H10s/x9dLP8fXSz/KoN3/yqDd/8qg3f/ + KoN3/za1+f82tfn/NrX5/za1+f8jbUf/I21H/yNtR/8jbUf/IGEu/yBhLv8gYS7/IGEu/yFiL/8hYi// + IWIv/yFiL/8hYzD/IWMw/yFjMP8hYzD/cat+/3Grfv9xq37/cat+/3Grfv9xq37/cat+/3Grfv9xq37/ + cat+/3Grfv9xq37/cq+M/3KvjP9yr4z/cq+M/3jN+/94zfv/eM37/3jN+/9tpaD/baWg/22loP9tpaD/ + ZIRr/2SEa/9khGv/ZIRr/2SFa/9khWv/ZIVr/2SFa//9+vj//fr4//36+P/9+vj/bo51/26Odf9ujnX/ + bo51/2WIbf9liG3/ZYht/2WIbf9liG3/ZYht/2WIbf9liG3/ZYlt/2WJbf9liW3/ZYlt/2aKbf9mim3/ + Zopt/2aKbf9mim7/Zopu/2aKbv9mim7/tcW2/7XFtv+1xbb/tcW2/7XFtv+1xbb/tcW2/7XFtv9njG// + Z4xv/2eMb/9njG//Z41v/2eNb/9njW//Z41v/2eOb/9njm//Z45v/2eOb/9njnD/Z45w/2eOcP9njnD/ + Zo5u/2aObv9mjm7/Zo5u/0x7Vv9Me1b/THtW/0x7Vv/8+PT//Pj0//z49P/8+PT/Hlss/x5bLP8eWyz/ + Hlss/x9dLP8fXSz/H10s/x9dLP8qg3f/KoN3/yqDd/8qg3f/NrX5/za1+f82tfn/NrX5/yNtR/8jbUf/ + I21H/yNtR/8gYS7/IGEu/yBhLv8gYS7/IWIv/yFiL/8hYi//IWIv/yFjMP8hYzD/IWMw/yFjMP9xq37/ + cat+/3Grfv9xq37/cat+/3Grfv9xq37/cat+/3Grfv9xq37/cat+/3Grfv9yr4z/cq+M/3KvjP9yr4z/ + eM37/3jN+/94zfv/eM37/22loP9tpaD/baWg/22loP9khGv/ZIRr/2SEa/9khGv/ZIVr/2SFa/9khWv/ + ZIVr//36+P/9+vj//fr4//36+P9ujnX/bo51/26Odf9ujnX/ZYht/2WIbf9liG3/ZYht/2WIbf9liG3/ + ZYht/2WIbf9liW3/ZYlt/2WJbf9liW3/Zopt/2aKbf9mim3/Zopt/2aKbv9mim7/Zopu/2aKbv+1xbb/ + tcW2/7XFtv+1xbb/tcW2/7XFtv+1xbb/tcW2/2eMb/9njG//Z4xv/2eMb/9njW//Z41v/2eNb/9njW// + Z45v/2eOb/9njm//Z45v/2eOcP9njnD/Z45w/2eOcP9mjm7/Zo5u/2aObv9mjm7/THtW/0x7Vv9Me1b/ + THtW//z49P/8+PT//Pj0//z49P8eWyz/Hlss/x5bLP8eWyz/H10s/x9dLP8fXSz/H10s/yqDd/8qg3f/ + KoN3/yqDd/82tfn/NrX5/za1+f82tfn/I21H/yNtR/8jbUf/I21H/yBhLv8gYS7/IGEu/yBhLv8hYi// + IWIv/yFiL/8hYi//IWMw/yFjMP8hYzD/IWMw/3Stgf90rYH/dK2B/3Stgf90rYH/dK2B/3Stgf90rYH/ + dK2B/3Stgf90rYH/dK2B/3Wyk/91spP/dbKT/3Wyk/97z/v/e8/7/3vP+/97z/v/cKWe/3Clnv9wpZ7/ + cKWe/2eGbv9nhm7/Z4Zu/2eGbv9nh2//Z4dv/2eHb/9nh2///fr4//36+P/9+vj//fr4/3OSef9zknn/ + c5J5/3OSef9oim//aIpv/2iKb/9oim//aIpw/2iKcP9oinD/aIpw/2mLcf9pi3H/aYtx/2mLcf9pjHH/ + aYxx/2mMcf9pjHH/aYxx/2mMcf9pjHH/aYxx/3KUef9ylHn/cpR5/3KUef9ylHr/cpR6/3KUev9ylHr/ + aY5y/2mOcv9pjnL/aY5y/2qPc/9qj3P/ao9z/2qPc/9qkHP/apBz/2qQc/9qkHP/apBz/2qQc/9qkHP/ + apBz/2uRc/9rkXP/a5Fz/2uRc/91mX3/dZl9/3WZff91mX3//fr3//369//9+vf//fr3/yNeMP8jXjD/ + I14w/yNeMP8fXC3/H1wt/x9cLf8fXC3/KYNz/ymDc/8pg3P/KYNz/za2+f82tvn/Nrb5/za2+f8lcU3/ + JXFN/yVxTf8lcU3/IWEv/yFhL/8hYS//IWEv/yFiMP8hYjD/IWIw/yFiMP8hZDH/IWQx/yFkMf8hZDH/ + dK2B/3Stgf90rYH/dK2B/3Stgf90rYH/dK2B/3Stgf90rYH/dK2B/3Stgf90rYH/dbKT/3Wyk/91spP/ + dbKT/3vP+/97z/v/e8/7/3vP+/9wpZ7/cKWe/3Clnv9wpZ7/Z4Zu/2eGbv9nhm7/Z4Zu/2eHb/9nh2// + Z4dv/2eHb//9+vj//fr4//36+P/9+vj/c5J5/3OSef9zknn/c5J5/2iKb/9oim//aIpv/2iKb/9oinD/ + aIpw/2iKcP9oinD/aYtx/2mLcf9pi3H/aYtx/2mMcf9pjHH/aYxx/2mMcf9pjHH/aYxx/2mMcf9pjHH/ + cpR5/3KUef9ylHn/cpR5/3KUev9ylHr/cpR6/3KUev9pjnL/aY5y/2mOcv9pjnL/ao9z/2qPc/9qj3P/ + ao9z/2qQc/9qkHP/apBz/2qQc/9qkHP/apBz/2qQc/9qkHP/a5Fz/2uRc/9rkXP/a5Fz/3WZff91mX3/ + dZl9/3WZff/9+vf//fr3//369//9+vf/I14w/yNeMP8jXjD/I14w/x9cLf8fXC3/H1wt/x9cLf8pg3P/ + KYNz/ymDc/8pg3P/Nrb5/za2+f82tvn/Nrb5/yVxTf8lcU3/JXFN/yVxTf8hYS//IWEv/yFhL/8hYS// + IWIw/yFiMP8hYjD/IWIw/yFkMf8hZDH/IWQx/yFkMf90rYH/dK2B/3Stgf90rYH/dK2B/3Stgf90rYH/ + dK2B/3Stgf90rYH/dK2B/3Stgf91spP/dbKT/3Wyk/91spP/e8/7/3vP+/97z/v/e8/7/3Clnv9wpZ7/ + cKWe/3Clnv9nhm7/Z4Zu/2eGbv9nhm7/Z4dv/2eHb/9nh2//Z4dv//36+P/9+vj//fr4//36+P9zknn/ + c5J5/3OSef9zknn/aIpv/2iKb/9oim//aIpv/2iKcP9oinD/aIpw/2iKcP9pi3H/aYtx/2mLcf9pi3H/ + aYxx/2mMcf9pjHH/aYxx/2mMcf9pjHH/aYxx/2mMcf9ylHn/cpR5/3KUef9ylHn/cpR6/3KUev9ylHr/ + cpR6/2mOcv9pjnL/aY5y/2mOcv9qj3P/ao9z/2qPc/9qj3P/apBz/2qQc/9qkHP/apBz/2qQc/9qkHP/ + apBz/2qQc/9rkXP/a5Fz/2uRc/9rkXP/dZl9/3WZff91mX3/dZl9//369//9+vf//fr3//369/8jXjD/ + I14w/yNeMP8jXjD/H1wt/x9cLf8fXC3/H1wt/ymDc/8pg3P/KYNz/ymDc/82tvn/Nrb5/za2+f82tvn/ + JXFN/yVxTf8lcU3/JXFN/yFhL/8hYS//IWEv/yFhL/8hYjD/IWIw/yFiMP8hYjD/IWQx/yFkMf8hZDH/ + IWQx/3Stgf90rYH/dK2B/3Stgf90rYH/dK2B/3Stgf90rYH/dK2B/3Stgf90rYH/dK2B/3Wyk/91spP/ + dbKT/3Wyk/97z/v/e8/7/3vP+/97z/v/cKWe/3Clnv9wpZ7/cKWe/2eGbv9nhm7/Z4Zu/2eGbv9nh2// + Z4dv/2eHb/9nh2///fr4//36+P/9+vj//fr4/3OSef9zknn/c5J5/3OSef9oim//aIpv/2iKb/9oim// + aIpw/2iKcP9oinD/aIpw/2mLcf9pi3H/aYtx/2mLcf9pjHH/aYxx/2mMcf9pjHH/aYxx/2mMcf9pjHH/ + aYxx/3KUef9ylHn/cpR5/3KUef9ylHr/cpR6/3KUev9ylHr/aY5y/2mOcv9pjnL/aY5y/2qPc/9qj3P/ + ao9z/2qPc/9qkHP/apBz/2qQc/9qkHP/apBz/2qQc/9qkHP/apBz/2uRc/9rkXP/a5Fz/2uRc/91mX3/ + dZl9/3WZff91mX3//fr3//369//9+vf//fr3/yNeMP8jXjD/I14w/yNeMP8fXC3/H1wt/x9cLf8fXC3/ + KYNz/ymDc/8pg3P/KYNz/za2+f82tvn/Nrb5/za2+f8lcU3/JXFN/yVxTf8lcU3/IWEv/yFhL/8hYS// + IWEv/yFiMP8hYjD/IWIw/yFiMP8hZDH/IWQx/yFkMf8hZDH/d6+E/3evhP93r4T/d6+E/3evhP93r4T/ + d6+E/3evhP93r4T/d6+E/3evhP93r4T/eLWX/3i1l/94tZf/eLWX/37Q+/9+0Pv/ftD7/37Q+/9ypZ3/ + cqWd/3Klnf9ypZ3/aolx/2qJcf9qiXH/aolx/2qJcf9qiXH/aolx/2qJcf/Z39j/2d/Y/9nf2P/Z39j/ + 4ebg/+Hm4P/h5uD/4ebg/9je1v/Y3tb/2N7W/9je1v/Y3tb/2N7W/9je1v/Y3tb/2N/W/9jf1v/Y39b/ + 2N/W/9jf1v/Y39b/2N/W/9jf1v/Y39f/2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/ + 2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/2N/X/9jg1//Y4Nf/2ODX/9jg1//Y4Nf/ + 2ODX/9jg1//Y4Nf/2ODX/9jg1//Y4Nf/2ODX/+Hn4f/h5+H/4efh/+Hn4f/Z4tn/2eLZ/9ni2f/Z4tn/ + X4pp/1+Kaf9fimn/X4pp/yZhNP8mYTT/JmE0/yZhNP8pgG3/KYBt/ymAbf8pgG3/N7f5/ze3+f83t/n/ + N7f5/yZyUv8mclL/JnJS/yZyUv8hYTD/IWEw/yFhMP8hYTD/IWIw/yFiMP8hYjD/IWIw/yJjMf8iYzH/ + ImMx/yJjMf93r4T/d6+E/3evhP93r4T/d6+E/3evhP93r4T/d6+E/3evhP93r4T/d6+E/3evhP94tZf/ + eLWX/3i1l/94tZf/ftD7/37Q+/9+0Pv/ftD7/3Klnf9ypZ3/cqWd/3Klnf9qiXH/aolx/2qJcf9qiXH/ + aolx/2qJcf9qiXH/aolx/9nf2P/Z39j/2d/Y/9nf2P/h5uD/4ebg/+Hm4P/h5uD/2N7W/9je1v/Y3tb/ + 2N7W/9je1v/Y3tb/2N7W/9je1v/Y39b/2N/W/9jf1v/Y39b/2N/W/9jf1v/Y39b/2N/W/9jf1//Y39f/ + 2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/ + 2N/X/9jf1//Y39f/2ODX/9jg1//Y4Nf/2ODX/9jg1//Y4Nf/2ODX/9jg1//Y4Nf/2ODX/9jg1//Y4Nf/ + 4efh/+Hn4f/h5+H/4efh/9ni2f/Z4tn/2eLZ/9ni2f9fimn/X4pp/1+Kaf9fimn/JmE0/yZhNP8mYTT/ + JmE0/ymAbf8pgG3/KYBt/ymAbf83t/n/N7f5/ze3+f83t/n/JnJS/yZyUv8mclL/JnJS/yFhMP8hYTD/ + IWEw/yFhMP8hYjD/IWIw/yFiMP8hYjD/ImMx/yJjMf8iYzH/ImMx/3evhP93r4T/d6+E/3evhP93r4T/ + d6+E/3evhP93r4T/d6+E/3evhP93r4T/d6+E/3i1l/94tZf/eLWX/3i1l/9+0Pv/ftD7/37Q+/9+0Pv/ + cqWd/3Klnf9ypZ3/cqWd/2qJcf9qiXH/aolx/2qJcf9qiXH/aolx/2qJcf9qiXH/2d/Y/9nf2P/Z39j/ + 2d/Y/+Hm4P/h5uD/4ebg/+Hm4P/Y3tb/2N7W/9je1v/Y3tb/2N7W/9je1v/Y3tb/2N7W/9jf1v/Y39b/ + 2N/W/9jf1v/Y39b/2N/W/9jf1v/Y39b/2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/ + 2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/2N/X/9jf1//Y4Nf/2ODX/9jg1//Y4Nf/ + 2ODX/9jg1//Y4Nf/2ODX/9jg1//Y4Nf/2ODX/9jg1//h5+H/4efh/+Hn4f/h5+H/2eLZ/9ni2f/Z4tn/ + 2eLZ/1+Kaf9fimn/X4pp/1+Kaf8mYTT/JmE0/yZhNP8mYTT/KYBt/ymAbf8pgG3/KYBt/ze3+f83t/n/ + N7f5/ze3+f8mclL/JnJS/yZyUv8mclL/IWEw/yFhMP8hYTD/IWEw/yFiMP8hYjD/IWIw/yFiMP8iYzH/ + ImMx/yJjMf8iYzH/d6+E/3evhP93r4T/d6+E/3evhP93r4T/d6+E/3evhP93r4T/d6+E/3evhP93r4T/ + eLWX/3i1l/94tZf/eLWX/37Q+/9+0Pv/ftD7/37Q+/9ypZ3/cqWd/3Klnf9ypZ3/aolx/2qJcf9qiXH/ + aolx/2qJcf9qiXH/aolx/2qJcf/Z39j/2d/Y/9nf2P/Z39j/4ebg/+Hm4P/h5uD/4ebg/9je1v/Y3tb/ + 2N7W/9je1v/Y3tb/2N7W/9je1v/Y3tb/2N/W/9jf1v/Y39b/2N/W/9jf1v/Y39b/2N/W/9jf1v/Y39f/ + 2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/ + 2N/X/9jf1//Y39f/2N/X/9jg1//Y4Nf/2ODX/9jg1//Y4Nf/2ODX/9jg1//Y4Nf/2ODX/9jg1//Y4Nf/ + 2ODX/+Hn4f/h5+H/4efh/+Hn4f/Z4tn/2eLZ/9ni2f/Z4tn/X4pp/1+Kaf9fimn/X4pp/yZhNP8mYTT/ + JmE0/yZhNP8pgG3/KYBt/ymAbf8pgG3/N7f5/ze3+f83t/n/N7f5/yZyUv8mclL/JnJS/yZyUv8hYTD/ + IWEw/yFhMP8hYTD/IWIw/yFiMP8hYjD/IWIw/yJjMf8iYzH/ImMx/yJjMf96soj/erKI/3qyiP96soj/ + erKI/3qyiP96soj/erKI/3qyiP96soj/erKI/3qyiP97uJ3/e7id/3u4nf97uJ3/gNL7/4DS+/+A0vv/ + gNL7/3Olm/9zpZv/c6Wb/3Olm/9si3T/bIt0/2yLdP9si3T/bYt1/22Ldf9ti3X/bYt1/3KQev9ykHr/ + cpB6/3KQev+Yrp3/mK6d/5iunf+Yrp3/nbKh/52yof+dsqH/nbKh/7fGuf+3xrn/t8a5/7fGuf/r7un/ + 6+7p/+vu6f/r7un/nrSi/560ov+etKL/nrSi/560ov+etKL/nrSi/560ov+etaL/nrWi/561ov+etaL/ + nrWj/561o/+etaP/nrWj/561o/+etaP/nrWj/561o/+etqT/nrak/562pP+etqT/6+7q/+vu6v/r7ur/ + 6+7q/7fJu/+3ybv/t8m7/7fJu/+ft6T/n7ek/5+3pP+ft6T/mrSg/5q0oP+atKD/mrSg/3Wafv91mn7/ + dZp+/3Wafv9xl3r/cZd6/3GXev9xl3r/ZpBw/2aQcP9mkHD/ZpBw/zWFcP81hXD/NYVw/zWFcP83uPn/ + N7j5/ze4+f83uPn/J3ZY/yd2WP8ndlj/J3ZY/yFhMf8hYTH/IWEx/yFhMf8hYjH/IWIx/yFiMf8hYjH/ + ImYz/yJmM/8iZjP/ImYz/3qyiP96soj/erKI/3qyiP96soj/erKI/3qyiP96soj/erKI/3qyiP96soj/ + erKI/3u4nf97uJ3/e7id/3u4nf+A0vv/gNL7/4DS+/+A0vv/c6Wb/3Olm/9zpZv/c6Wb/2yLdP9si3T/ + bIt0/2yLdP9ti3X/bYt1/22Ldf9ti3X/cpB6/3KQev9ykHr/cpB6/5iunf+Yrp3/mK6d/5iunf+dsqH/ + nbKh/52yof+dsqH/t8a5/7fGuf+3xrn/t8a5/+vu6f/r7un/6+7p/+vu6f+etKL/nrSi/560ov+etKL/ + nrSi/560ov+etKL/nrSi/561ov+etaL/nrWi/561ov+etaP/nrWj/561o/+etaP/nrWj/561o/+etaP/ + nrWj/562pP+etqT/nrak/562pP/r7ur/6+7q/+vu6v/r7ur/t8m7/7fJu/+3ybv/t8m7/5+3pP+ft6T/ + n7ek/5+3pP+atKD/mrSg/5q0oP+atKD/dZp+/3Wafv91mn7/dZp+/3GXev9xl3r/cZd6/3GXev9mkHD/ + ZpBw/2aQcP9mkHD/NYVw/zWFcP81hXD/NYVw/ze4+f83uPn/N7j5/ze4+f8ndlj/J3ZY/yd2WP8ndlj/ + IWEx/yFhMf8hYTH/IWEx/yFiMf8hYjH/IWIx/yFiMf8iZjP/ImYz/yJmM/8iZjP/erKI/3qyiP96soj/ + erKI/3qyiP96soj/erKI/3qyiP96soj/erKI/3qyiP96soj/e7id/3u4nf97uJ3/e7id/4DS+/+A0vv/ + gNL7/4DS+/9zpZv/c6Wb/3Olm/9zpZv/bIt0/2yLdP9si3T/bIt0/22Ldf9ti3X/bYt1/22Ldf9ykHr/ + cpB6/3KQev9ykHr/mK6d/5iunf+Yrp3/mK6d/52yof+dsqH/nbKh/52yof+3xrn/t8a5/7fGuf+3xrn/ + 6+7p/+vu6f/r7un/6+7p/560ov+etKL/nrSi/560ov+etKL/nrSi/560ov+etKL/nrWi/561ov+etaL/ + nrWi/561o/+etaP/nrWj/561o/+etaP/nrWj/561o/+etaP/nrak/562pP+etqT/nrak/+vu6v/r7ur/ + 6+7q/+vu6v+3ybv/t8m7/7fJu/+3ybv/n7ek/5+3pP+ft6T/n7ek/5q0oP+atKD/mrSg/5q0oP91mn7/ + dZp+/3Wafv91mn7/cZd6/3GXev9xl3r/cZd6/2aQcP9mkHD/ZpBw/2aQcP81hXD/NYVw/zWFcP81hXD/ + N7j5/ze4+f83uPn/N7j5/yd2WP8ndlj/J3ZY/yd2WP8hYTH/IWEx/yFhMf8hYTH/IWIx/yFiMf8hYjH/ + IWIx/yJmM/8iZjP/ImYz/yJmM/96soj/erKI/3qyiP96soj/erKI/3qyiP96soj/erKI/3qyiP96soj/ + erKI/3qyiP97uJ3/e7id/3u4nf97uJ3/gNL7/4DS+/+A0vv/gNL7/3Olm/9zpZv/c6Wb/3Olm/9si3T/ + bIt0/2yLdP9si3T/bYt1/22Ldf9ti3X/bYt1/3KQev9ykHr/cpB6/3KQev+Yrp3/mK6d/5iunf+Yrp3/ + nbKh/52yof+dsqH/nbKh/7fGuf+3xrn/t8a5/7fGuf/r7un/6+7p/+vu6f/r7un/nrSi/560ov+etKL/ + nrSi/560ov+etKL/nrSi/560ov+etaL/nrWi/561ov+etaL/nrWj/561o/+etaP/nrWj/561o/+etaP/ + nrWj/561o/+etqT/nrak/562pP+etqT/6+7q/+vu6v/r7ur/6+7q/7fJu/+3ybv/t8m7/7fJu/+ft6T/ + n7ek/5+3pP+ft6T/mrSg/5q0oP+atKD/mrSg/3Wafv91mn7/dZp+/3Wafv9xl3r/cZd6/3GXev9xl3r/ + ZpBw/2aQcP9mkHD/ZpBw/zWFcP81hXD/NYVw/zWFcP83uPn/N7j5/ze4+f83uPn/J3ZY/yd2WP8ndlj/ + J3ZY/yFhMf8hYTH/IWEx/yFhMf8hYjH/IWIx/yFiMf8hYjH/ImYz/yJmM/8iZjP/ImYz/361i/9+tYv/ + frWL/361i/9+tYv/frWL/361i/9+tYv/frWL/361i/9+tYv/frWL/3+7o/9/u6P/f7uj/3+7o/+E0/v/ + hNP7/4TT+/+E0/v/d6Wa/3elmv93pZr/d6Wa/3CNd/9wjXf/cI13/3CNd/9wjnj/cI54/3COeP9wjnj/ + cI94/3CPeP9wj3j/cI94/3CPef9wj3n/cI95/3CPef9xkHn/cZB5/3GQef9xkHn/kamX/5Gpl/+RqZf/ + kamX/+zw7P/s8Oz/7PDs/+zw7P9yknr/cpJ6/3KSev9yknr/cpN6/3KTev9yk3r/cpN6/3KUev9ylHr/ + cpR6/3KUev9ylHv/cpR7/3KUe/9ylHv/c5V7/3OVe/9zlXv/c5V7/3OWfP9zlnz/c5Z8/3OWfP/s8Oz/ + 7PDs/+zw7P/s8Oz/k66Z/5Oumf+Trpn/k66Z/3SYfP90mHz/dJh8/3SYfP90mH3/dJh9/3SYff90mH3/ + dJl9/3SZff90mX3/dJl9/3SZfv90mX7/dJl+/3SZfv90mn7/dJp+/3Safv90mn7/c6mZ/3Opmf9zqZn/ + c6mZ/0S8+P9EvPj/RLz4/0S8+P8oeF3/KHhd/yh4Xf8oeF3/IWEx/yFhMf8hYTH/IWEx/yJlM/8iZTP/ + ImUz/yJlM/8sgEH/LIBB/yyAQf8sgEH/frWL/361i/9+tYv/frWL/361i/9+tYv/frWL/361i/9+tYv/ + frWL/361i/9+tYv/f7uj/3+7o/9/u6P/f7uj/4TT+/+E0/v/hNP7/4TT+/93pZr/d6Wa/3elmv93pZr/ + cI13/3CNd/9wjXf/cI13/3COeP9wjnj/cI54/3COeP9wj3j/cI94/3CPeP9wj3j/cI95/3CPef9wj3n/ + cI95/3GQef9xkHn/cZB5/3GQef+RqZf/kamX/5Gpl/+RqZf/7PDs/+zw7P/s8Oz/7PDs/3KSev9yknr/ + cpJ6/3KSev9yk3r/cpN6/3KTev9yk3r/cpR6/3KUev9ylHr/cpR6/3KUe/9ylHv/cpR7/3KUe/9zlXv/ + c5V7/3OVe/9zlXv/c5Z8/3OWfP9zlnz/c5Z8/+zw7P/s8Oz/7PDs/+zw7P+Trpn/k66Z/5Oumf+Trpn/ + dJh8/3SYfP90mHz/dJh8/3SYff90mH3/dJh9/3SYff90mX3/dJl9/3SZff90mX3/dJl+/3SZfv90mX7/ + dJl+/3Safv90mn7/dJp+/3Safv9zqZn/c6mZ/3Opmf9zqZn/RLz4/0S8+P9EvPj/RLz4/yh4Xf8oeF3/ + KHhd/yh4Xf8hYTH/IWEx/yFhMf8hYTH/ImUz/yJlM/8iZTP/ImUz/yyAQf8sgEH/LIBB/yyAQf9+tYv/ + frWL/361i/9+tYv/frWL/361i/9+tYv/frWL/361i/9+tYv/frWL/361i/9/u6P/f7uj/3+7o/9/u6P/ + hNP7/4TT+/+E0/v/hNP7/3elmv93pZr/d6Wa/3elmv9wjXf/cI13/3CNd/9wjXf/cI54/3COeP9wjnj/ + cI54/3CPeP9wj3j/cI94/3CPeP9wj3n/cI95/3CPef9wj3n/cZB5/3GQef9xkHn/cZB5/5Gpl/+RqZf/ + kamX/5Gpl//s8Oz/7PDs/+zw7P/s8Oz/cpJ6/3KSev9yknr/cpJ6/3KTev9yk3r/cpN6/3KTev9ylHr/ + cpR6/3KUev9ylHr/cpR7/3KUe/9ylHv/cpR7/3OVe/9zlXv/c5V7/3OVe/9zlnz/c5Z8/3OWfP9zlnz/ + 7PDs/+zw7P/s8Oz/7PDs/5Oumf+Trpn/k66Z/5Oumf90mHz/dJh8/3SYfP90mHz/dJh9/3SYff90mH3/ + dJh9/3SZff90mX3/dJl9/3SZff90mX7/dJl+/3SZfv90mX7/dJp+/3Safv90mn7/dJp+/3Opmf9zqZn/ + c6mZ/3Opmf9EvPj/RLz4/0S8+P9EvPj/KHhd/yh4Xf8oeF3/KHhd/yFhMf8hYTH/IWEx/yFhMf8iZTP/ + ImUz/yJlM/8iZTP/LIBB/yyAQf8sgEH/LIBB/361i/9+tYv/frWL/361i/9+tYv/frWL/361i/9+tYv/ + frWL/361i/9+tYv/frWL/3+7o/9/u6P/f7uj/3+7o/+E0/v/hNP7/4TT+/+E0/v/d6Wa/3elmv93pZr/ + d6Wa/3CNd/9wjXf/cI13/3CNd/9wjnj/cI54/3COeP9wjnj/cI94/3CPeP9wj3j/cI94/3CPef9wj3n/ + cI95/3CPef9xkHn/cZB5/3GQef9xkHn/kamX/5Gpl/+RqZf/kamX/+zw7P/s8Oz/7PDs/+zw7P9yknr/ + cpJ6/3KSev9yknr/cpN6/3KTev9yk3r/cpN6/3KUev9ylHr/cpR6/3KUev9ylHv/cpR7/3KUe/9ylHv/ + c5V7/3OVe/9zlXv/c5V7/3OWfP9zlnz/c5Z8/3OWfP/s8Oz/7PDs/+zw7P/s8Oz/k66Z/5Oumf+Trpn/ + k66Z/3SYfP90mHz/dJh8/3SYfP90mH3/dJh9/3SYff90mH3/dJl9/3SZff90mX3/dJl9/3SZfv90mX7/ + dJl+/3SZfv90mn7/dJp+/3Safv90mn7/c6mZ/3Opmf9zqZn/c6mZ/0S8+P9EvPj/RLz4/0S8+P8oeF3/ + KHhd/yh4Xf8oeF3/IWEx/yFhMf8hYTH/IWEx/yJlM/8iZTP/ImUz/yJlM/8sgEH/LIBB/yyAQf8sgEH/ + gbeO/4G3jv+Bt47/gbeO/4G3jv+Bt47/gbeO/4G3jv+Bt47/gbeO/4G3jv+Bt47/gr6n/4K+p/+Cvqf/ + gr6n/4fU+/+H1Pv/h9T7/4fU+/95pJj/eaSY/3mkmP95pJj/c496/3OPev9zj3r/c496/3OQev9zkHr/ + c5B6/3OQev9zkXr/c5F6/3ORev9zkXr/dJJ7/3SSe/90knv/dJJ7/3SSe/90knv/dJJ7/3SSe/94loD/ + eJaA/3iWgP94loD/7fDs/+3w7P/t8Oz/7fDs/9Te1v/U3tb/1N7W/9Te1v+/zcL/v83C/7/Nwv+/zcL/ + v83C/7/Nwv+/zcL/v83C/7/Owv+/zsL/v87C/7/Owv+/zsL/v87C/7/Owv+/zsL/1d/X/9Xf1//V39f/ + 1d/X/+3w7f/t8O3/7fDt/+3w7f96nIP/epyD/3qcg/96nIP/dpl//3aZf/92mX//dpl//3eaf/93mn// + d5p//3eaf/93m3//d5t//3ebf/93m3//d5uA/3ebgP93m4D/d5uA/3ecgf93nIH/d5yB/3ecgf98rp3/ + fK6d/3yunf98rp3/ftH6/37R+v9+0fr/ftH6/zOBaP8zgWj/M4Fo/zOBaP8iZDL/ImQy/yJkMv8iZDL/ + LYJB/y2CQf8tgkH/LYJB/y+JRf8viUX/L4lF/y+JRf+Bt47/gbeO/4G3jv+Bt47/gbeO/4G3jv+Bt47/ + gbeO/4G3jv+Bt47/gbeO/4G3jv+Cvqf/gr6n/4K+p/+Cvqf/h9T7/4fU+/+H1Pv/h9T7/3mkmP95pJj/ + eaSY/3mkmP9zj3r/c496/3OPev9zj3r/c5B6/3OQev9zkHr/c5B6/3ORev9zkXr/c5F6/3ORev90knv/ + dJJ7/3SSe/90knv/dJJ7/3SSe/90knv/dJJ7/3iWgP94loD/eJaA/3iWgP/t8Oz/7fDs/+3w7P/t8Oz/ + 1N7W/9Te1v/U3tb/1N7W/7/Nwv+/zcL/v83C/7/Nwv+/zcL/v83C/7/Nwv+/zcL/v87C/7/Owv+/zsL/ + v87C/7/Owv+/zsL/v87C/7/Owv/V39f/1d/X/9Xf1//V39f/7fDt/+3w7f/t8O3/7fDt/3qcg/96nIP/ + epyD/3qcg/92mX//dpl//3aZf/92mX//d5p//3eaf/93mn//d5p//3ebf/93m3//d5t//3ebf/93m4D/ + d5uA/3ebgP93m4D/d5yB/3ecgf93nIH/d5yB/3yunf98rp3/fK6d/3yunf9+0fr/ftH6/37R+v9+0fr/ + M4Fo/zOBaP8zgWj/M4Fo/yJkMv8iZDL/ImQy/yJkMv8tgkH/LYJB/y2CQf8tgkH/L4lF/y+JRf8viUX/ + L4lF/4G3jv+Bt47/gbeO/4G3jv+Bt47/gbeO/4G3jv+Bt47/gbeO/4G3jv+Bt47/gbeO/4K+p/+Cvqf/ + gr6n/4K+p/+H1Pv/h9T7/4fU+/+H1Pv/eaSY/3mkmP95pJj/eaSY/3OPev9zj3r/c496/3OPev9zkHr/ + c5B6/3OQev9zkHr/c5F6/3ORev9zkXr/c5F6/3SSe/90knv/dJJ7/3SSe/90knv/dJJ7/3SSe/90knv/ + eJaA/3iWgP94loD/eJaA/+3w7P/t8Oz/7fDs/+3w7P/U3tb/1N7W/9Te1v/U3tb/v83C/7/Nwv+/zcL/ + v83C/7/Nwv+/zcL/v83C/7/Nwv+/zsL/v87C/7/Owv+/zsL/v87C/7/Owv+/zsL/v87C/9Xf1//V39f/ + 1d/X/9Xf1//t8O3/7fDt/+3w7f/t8O3/epyD/3qcg/96nIP/epyD/3aZf/92mX//dpl//3aZf/93mn// + d5p//3eaf/93mn//d5t//3ebf/93m3//d5t//3ebgP93m4D/d5uA/3ebgP93nIH/d5yB/3ecgf93nIH/ + fK6d/3yunf98rp3/fK6d/37R+v9+0fr/ftH6/37R+v8zgWj/M4Fo/zOBaP8zgWj/ImQy/yJkMv8iZDL/ + ImQy/y2CQf8tgkH/LYJB/y2CQf8viUX/L4lF/y+JRf8viUX/gbeO/4G3jv+Bt47/gbeO/4G3jv+Bt47/ + gbeO/4G3jv+Bt47/gbeO/4G3jv+Bt47/gr6n/4K+p/+Cvqf/gr6n/4fU+/+H1Pv/h9T7/4fU+/95pJj/ + eaSY/3mkmP95pJj/c496/3OPev9zj3r/c496/3OQev9zkHr/c5B6/3OQev9zkXr/c5F6/3ORev9zkXr/ + dJJ7/3SSe/90knv/dJJ7/3SSe/90knv/dJJ7/3SSe/94loD/eJaA/3iWgP94loD/7fDs/+3w7P/t8Oz/ + 7fDs/9Te1v/U3tb/1N7W/9Te1v+/zcL/v83C/7/Nwv+/zcL/v83C/7/Nwv+/zcL/v83C/7/Owv+/zsL/ + v87C/7/Owv+/zsL/v87C/7/Owv+/zsL/1d/X/9Xf1//V39f/1d/X/+3w7f/t8O3/7fDt/+3w7f96nIP/ + epyD/3qcg/96nIP/dpl//3aZf/92mX//dpl//3eaf/93mn//d5p//3eaf/93m3//d5t//3ebf/93m3// + d5uA/3ebgP93m4D/d5uA/3ecgf93nIH/d5yB/3ecgf98rp3/fK6d/3yunf98rp3/ftH6/37R+v9+0fr/ + ftH6/zOBaP8zgWj/M4Fo/zOBaP8iZDL/ImQy/yJkMv8iZDL/LYJB/y2CQf8tgkH/LYJB/y+JRf8viUX/ + L4lF/y+JRf+EuZH/hLmR/4S5kf+EuZH/hLmR/4S5kf+EuZH/hLmR/4S5kf+EuZH/hLmR/4S5kf+FwKz/ + hcCs/4XArP+FwKz/idb7/4nW+/+J1vv/idb7/32qof99qqH/faqh/32qof92kXz/dpF8/3aRfP92kXz/ + dpJ9/3aSff92kn3/dpJ9/3aTfv92k37/dpN+/3aTfv92k37/dpN+/3aTfv92k37/dpR+/3aUfv92lH7/ + dpR+/3eUfv93lH7/d5R+/3eUfv+Cnor/gp6K/4Keiv+Cnor/tca5/7XGuf+1xrn/tca5/8DOw//AzsP/ + wM7D/8DOw//Az8P/wM/D/8DPw//Az8P/wM/E/8DPxP/Az8T/wM/E/8DPxP/Az8T/wM/E/8DPxP+2yLr/ + tsi6/7bIuv+2yLr/hKOL/4Sji/+Eo4v/hKOL/3mbgv95m4L/eZuC/3mbgv95m4L/eZuC/3mbgv95m4L/ + eZyC/3mcgv95nIL/eZyC/3mdgv95nYL/eZ2C/3mdgv96nYP/ep2D/3qdg/96nYP/ep6D/3qeg/96noP/ + ep6D/4Cypf+AsqX/gLKl/4Cypf+J1vv/idb7/4nW+/+J1vv/dKyc/3SsnP90rJz/dKyc/zSGSv80hkr/ + NIZK/zSGSv8wikf/MIpH/zCKR/8wikf/MIpH/zCKR/8wikf/MIpH/4S5kf+EuZH/hLmR/4S5kf+EuZH/ + hLmR/4S5kf+EuZH/hLmR/4S5kf+EuZH/hLmR/4XArP+FwKz/hcCs/4XArP+J1vv/idb7/4nW+/+J1vv/ + faqh/32qof99qqH/faqh/3aRfP92kXz/dpF8/3aRfP92kn3/dpJ9/3aSff92kn3/dpN+/3aTfv92k37/ + dpN+/3aTfv92k37/dpN+/3aTfv92lH7/dpR+/3aUfv92lH7/d5R+/3eUfv93lH7/d5R+/4Keiv+Cnor/ + gp6K/4Keiv+1xrn/tca5/7XGuf+1xrn/wM7D/8DOw//AzsP/wM7D/8DPw//Az8P/wM/D/8DPw//Az8T/ + wM/E/8DPxP/Az8T/wM/E/8DPxP/Az8T/wM/E/7bIuv+2yLr/tsi6/7bIuv+Eo4v/hKOL/4Sji/+Eo4v/ + eZuC/3mbgv95m4L/eZuC/3mbgv95m4L/eZuC/3mbgv95nIL/eZyC/3mcgv95nIL/eZ2C/3mdgv95nYL/ + eZ2C/3qdg/96nYP/ep2D/3qdg/96noP/ep6D/3qeg/96noP/gLKl/4Cypf+AsqX/gLKl/4nW+/+J1vv/ + idb7/4nW+/90rJz/dKyc/3SsnP90rJz/NIZK/zSGSv80hkr/NIZK/zCKR/8wikf/MIpH/zCKR/8wikf/ + MIpH/zCKR/8wikf/hLmR/4S5kf+EuZH/hLmR/4S5kf+EuZH/hLmR/4S5kf+EuZH/hLmR/4S5kf+EuZH/ + hcCs/4XArP+FwKz/hcCs/4nW+/+J1vv/idb7/4nW+/99qqH/faqh/32qof99qqH/dpF8/3aRfP92kXz/ + dpF8/3aSff92kn3/dpJ9/3aSff92k37/dpN+/3aTfv92k37/dpN+/3aTfv92k37/dpN+/3aUfv92lH7/ + dpR+/3aUfv93lH7/d5R+/3eUfv93lH7/gp6K/4Keiv+Cnor/gp6K/7XGuf+1xrn/tca5/7XGuf/AzsP/ + wM7D/8DOw//AzsP/wM/D/8DPw//Az8P/wM/D/8DPxP/Az8T/wM/E/8DPxP/Az8T/wM/E/8DPxP/Az8T/ + tsi6/7bIuv+2yLr/tsi6/4Sji/+Eo4v/hKOL/4Sji/95m4L/eZuC/3mbgv95m4L/eZuC/3mbgv95m4L/ + eZuC/3mcgv95nIL/eZyC/3mcgv95nYL/eZ2C/3mdgv95nYL/ep2D/3qdg/96nYP/ep2D/3qeg/96noP/ + ep6D/3qeg/+AsqX/gLKl/4Cypf+AsqX/idb7/4nW+/+J1vv/idb7/3SsnP90rJz/dKyc/3SsnP80hkr/ + NIZK/zSGSv80hkr/MIpH/zCKR/8wikf/MIpH/zCKR/8wikf/MIpH/zCKR/+EuZH/hLmR/4S5kf+EuZH/ + hLmR/4S5kf+EuZH/hLmR/4S5kf+EuZH/hLmR/4S5kf+FwKz/hcCs/4XArP+FwKz/idb7/4nW+/+J1vv/ + idb7/32qof99qqH/faqh/32qof92kXz/dpF8/3aRfP92kXz/dpJ9/3aSff92kn3/dpJ9/3aTfv92k37/ + dpN+/3aTfv92k37/dpN+/3aTfv92k37/dpR+/3aUfv92lH7/dpR+/3eUfv93lH7/d5R+/3eUfv+Cnor/ + gp6K/4Keiv+Cnor/tca5/7XGuf+1xrn/tca5/8DOw//AzsP/wM7D/8DOw//Az8P/wM/D/8DPw//Az8P/ + wM/E/8DPxP/Az8T/wM/E/8DPxP/Az8T/wM/E/8DPxP+2yLr/tsi6/7bIuv+2yLr/hKOL/4Sji/+Eo4v/ + hKOL/3mbgv95m4L/eZuC/3mbgv95m4L/eZuC/3mbgv95m4L/eZyC/3mcgv95nIL/eZyC/3mdgv95nYL/ + eZ2C/3mdgv96nYP/ep2D/3qdg/96nYP/ep6D/3qeg/96noP/ep6D/4Cypf+AsqX/gLKl/4Cypf+J1vv/ + idb7/4nW+/+J1vv/dKyc/3SsnP90rJz/dKyc/zSGSv80hkr/NIZK/zSGSv8wikf/MIpH/zCKR/8wikf/ + MIpH/zCKR/8wikf/MIpH/4e8lf+HvJX/h7yV/4e8lf+HvJX/h7yV/4e8lf+HvJX/h7yV/4e8lf+HvJX/ + h7yV/4i/oP+Iv6D/iL+g/4i/oP+M1vX/jNb1/4zW9f+M1vX/jdj6/43Y+v+N2Pr/jdj6/4rM2/+KzNv/ + iszb/4rM2/+Fu7v/hbu7/4W7u/+Fu7v/gKmc/4CpnP+AqZz/gKmc/3uYg/97mIP/e5iD/3uYg/96l4L/ + epeC/3qXgv96l4L/e5eC/3uXgv97l4L/e5eC/3uYgv97mIL/e5iC/3uYgv97mIL/e5iC/3uYgv97mIL/ + e5mD/3uZg/97mYP/e5mD/3uZg/97mYP/e5mD/3uZg/98moP/fJqD/3yag/98moP/fJuE/3ybhP98m4T/ + fJuE/3ychP98nIT/fJyE/3ychP98nIX/fJyF/3ychf98nIX/fJ2F/3ydhf98nYX/fJ2F/32dhf99nYX/ + fZ2F/32dhf9+oIf/fqCH/36gh/9+oIf/gq6g/4KuoP+CrqD/gq6g/4a/vP+Gv7z/hr+8/4a/vP+Kzdz/ + is3c/4rN3P+Kzdz/jdj6/43Y+v+N2Pr/jdj6/43W9f+N1vX/jdb1/43W9f+HvqH/h76h/4e+of+HvqH/ + drKF/3ayhf92soX/drKF/zOMSv8zjEr/M4xK/zOMSv8xi0j/MYtI/zGLSP8xi0j/h7yV/4e8lf+HvJX/ + h7yV/4e8lf+HvJX/h7yV/4e8lf+HvJX/h7yV/4e8lf+HvJX/iL+g/4i/oP+Iv6D/iL+g/4zW9f+M1vX/ + jNb1/4zW9f+N2Pr/jdj6/43Y+v+N2Pr/iszb/4rM2/+KzNv/iszb/4W7u/+Fu7v/hbu7/4W7u/+AqZz/ + gKmc/4CpnP+AqZz/e5iD/3uYg/97mIP/e5iD/3qXgv96l4L/epeC/3qXgv97l4L/e5eC/3uXgv97l4L/ + e5iC/3uYgv97mIL/e5iC/3uYgv97mIL/e5iC/3uYgv97mYP/e5mD/3uZg/97mYP/e5mD/3uZg/97mYP/ + e5mD/3yag/98moP/fJqD/3yag/98m4T/fJuE/3ybhP98m4T/fJyE/3ychP98nIT/fJyE/3ychf98nIX/ + fJyF/3ychf98nYX/fJ2F/3ydhf98nYX/fZ2F/32dhf99nYX/fZ2F/36gh/9+oIf/fqCH/36gh/+CrqD/ + gq6g/4KuoP+CrqD/hr+8/4a/vP+Gv7z/hr+8/4rN3P+Kzdz/is3c/4rN3P+N2Pr/jdj6/43Y+v+N2Pr/ + jdb1/43W9f+N1vX/jdb1/4e+of+HvqH/h76h/4e+of92soX/drKF/3ayhf92soX/M4xK/zOMSv8zjEr/ + M4xK/zGLSP8xi0j/MYtI/zGLSP+HvJX/h7yV/4e8lf+HvJX/h7yV/4e8lf+HvJX/h7yV/4e8lf+HvJX/ + h7yV/4e8lf+Iv6D/iL+g/4i/oP+Iv6D/jNb1/4zW9f+M1vX/jNb1/43Y+v+N2Pr/jdj6/43Y+v+KzNv/ + iszb/4rM2/+KzNv/hbu7/4W7u/+Fu7v/hbu7/4CpnP+AqZz/gKmc/4CpnP97mIP/e5iD/3uYg/97mIP/ + epeC/3qXgv96l4L/epeC/3uXgv97l4L/e5eC/3uXgv97mIL/e5iC/3uYgv97mIL/e5iC/3uYgv97mIL/ + e5iC/3uZg/97mYP/e5mD/3uZg/97mYP/e5mD/3uZg/97mYP/fJqD/3yag/98moP/fJqD/3ybhP98m4T/ + fJuE/3ybhP98nIT/fJyE/3ychP98nIT/fJyF/3ychf98nIX/fJyF/3ydhf98nYX/fJ2F/3ydhf99nYX/ + fZ2F/32dhf99nYX/fqCH/36gh/9+oIf/fqCH/4KuoP+CrqD/gq6g/4KuoP+Gv7z/hr+8/4a/vP+Gv7z/ + is3c/4rN3P+Kzdz/is3c/43Y+v+N2Pr/jdj6/43Y+v+N1vX/jdb1/43W9f+N1vX/h76h/4e+of+HvqH/ + h76h/3ayhf92soX/drKF/3ayhf8zjEr/M4xK/zOMSv8zjEr/MYtI/zGLSP8xi0j/MYtI/4e8lf+HvJX/ + h7yV/4e8lf+HvJX/h7yV/4e8lf+HvJX/h7yV/4e8lf+HvJX/h7yV/4i/oP+Iv6D/iL+g/4i/oP+M1vX/ + jNb1/4zW9f+M1vX/jdj6/43Y+v+N2Pr/jdj6/4rM2/+KzNv/iszb/4rM2/+Fu7v/hbu7/4W7u/+Fu7v/ + gKmc/4CpnP+AqZz/gKmc/3uYg/97mIP/e5iD/3uYg/96l4L/epeC/3qXgv96l4L/e5eC/3uXgv97l4L/ + e5eC/3uYgv97mIL/e5iC/3uYgv97mIL/e5iC/3uYgv97mIL/e5mD/3uZg/97mYP/e5mD/3uZg/97mYP/ + e5mD/3uZg/98moP/fJqD/3yag/98moP/fJuE/3ybhP98m4T/fJuE/3ychP98nIT/fJyE/3ychP98nIX/ + fJyF/3ychf98nIX/fJ2F/3ydhf98nYX/fJ2F/32dhf99nYX/fZ2F/32dhf9+oIf/fqCH/36gh/9+oIf/ + gq6g/4KuoP+CrqD/gq6g/4a/vP+Gv7z/hr+8/4a/vP+Kzdz/is3c/4rN3P+Kzdz/jdj6/43Y+v+N2Pr/ + jdj6/43W9f+N1vX/jdb1/43W9f+HvqH/h76h/4e+of+HvqH/drKF/3ayhf92soX/drKF/zOMSv8zjEr/ + M4xK/zOMSv8xi0j/MYtI/zGLSP8xi0j/ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ + ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/4rBof+KwaH/isGh/4rBof+NysX/jcrF/43Kxf+NysX/ + jtPk/47T5P+O0+T/jtPk/4/Z+v+P2fr/j9n6/4/Z+v+P2fr/j9n6/4/Z+v+P2fr/j9j4/4/Y+P+P2Pj/ + j9j4/47U7P+O1Oz/jtTs/47U7P+Nz93/jc/d/43P3f+Nz93/i8fO/4vHzv+Lx87/i8fO/4rEx/+KxMf/ + isTH/4rEx/+JwcH/icHB/4nBwf+JwcH/ib68/4m+vP+Jvrz/ib68/4m/vP+Jv7z/ib+8/4m/vP+JwsL/ + icLC/4nCwv+JwsL/isTH/4rEx/+KxMf/isTH/4vJz/+Lyc//i8nP/4vJz/+Nz93/jc/d/43P3f+Nz93/ + jtTs/47U7P+O1Oz/jtTs/4/Y+P+P2Pj/j9j4/4/Y+P+P2fr/j9n6/4/Z+v+P2fr/j9n6/4/Z+v+P2fr/ + j9n6/47T5v+O0+b/jtPm/47T5v+My8j/jMvI/4zLyP+My8j/i8Ch/4vAof+LwKH/i8Ch/4q+mP+Kvpj/ + ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/Z6t4/2ereP9nq3j/Z6t4/zKNSf8yjUn/Mo1J/zKNSf+Kvpj/ + ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ + isGh/4rBof+KwaH/isGh/43Kxf+NysX/jcrF/43Kxf+O0+T/jtPk/47T5P+O0+T/j9n6/4/Z+v+P2fr/ + j9n6/4/Z+v+P2fr/j9n6/4/Z+v+P2Pj/j9j4/4/Y+P+P2Pj/jtTs/47U7P+O1Oz/jtTs/43P3f+Nz93/ + jc/d/43P3f+Lx87/i8fO/4vHzv+Lx87/isTH/4rEx/+KxMf/isTH/4nBwf+JwcH/icHB/4nBwf+Jvrz/ + ib68/4m+vP+Jvrz/ib+8/4m/vP+Jv7z/ib+8/4nCwv+JwsL/icLC/4nCwv+KxMf/isTH/4rEx/+KxMf/ + i8nP/4vJz/+Lyc//i8nP/43P3f+Nz93/jc/d/43P3f+O1Oz/jtTs/47U7P+O1Oz/j9j4/4/Y+P+P2Pj/ + j9j4/4/Z+v+P2fr/j9n6/4/Z+v+P2fr/j9n6/4/Z+v+P2fr/jtPm/47T5v+O0+b/jtPm/4zLyP+My8j/ + jMvI/4zLyP+LwKH/i8Ch/4vAof+LwKH/ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/4q+mP9nq3j/ + Z6t4/2ereP9nq3j/Mo1J/zKNSf8yjUn/Mo1J/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ + ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+KwaH/isGh/4rBof+KwaH/jcrF/43Kxf+NysX/ + jcrF/47T5P+O0+T/jtPk/47T5P+P2fr/j9n6/4/Z+v+P2fr/j9n6/4/Z+v+P2fr/j9n6/4/Y+P+P2Pj/ + j9j4/4/Y+P+O1Oz/jtTs/47U7P+O1Oz/jc/d/43P3f+Nz93/jc/d/4vHzv+Lx87/i8fO/4vHzv+KxMf/ + isTH/4rEx/+KxMf/icHB/4nBwf+JwcH/icHB/4m+vP+Jvrz/ib68/4m+vP+Jv7z/ib+8/4m/vP+Jv7z/ + icLC/4nCwv+JwsL/icLC/4rEx/+KxMf/isTH/4rEx/+Lyc//i8nP/4vJz/+Lyc//jc/d/43P3f+Nz93/ + jc/d/47U7P+O1Oz/jtTs/47U7P+P2Pj/j9j4/4/Y+P+P2Pj/j9n6/4/Z+v+P2fr/j9n6/4/Z+v+P2fr/ + j9n6/4/Z+v+O0+b/jtPm/47T5v+O0+b/jMvI/4zLyP+My8j/jMvI/4vAof+LwKH/i8Ch/4vAof+Kvpj/ + ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/2ereP9nq3j/Z6t4/2ereP8yjUn/Mo1J/zKNSf8yjUn/ + ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ + ir6Y/4rBof+KwaH/isGh/4rBof+NysX/jcrF/43Kxf+NysX/jtPk/47T5P+O0+T/jtPk/4/Z+v+P2fr/ + j9n6/4/Z+v+P2fr/j9n6/4/Z+v+P2fr/j9j4/4/Y+P+P2Pj/j9j4/47U7P+O1Oz/jtTs/47U7P+Nz93/ + jc/d/43P3f+Nz93/i8fO/4vHzv+Lx87/i8fO/4rEx/+KxMf/isTH/4rEx/+JwcH/icHB/4nBwf+JwcH/ + ib68/4m+vP+Jvrz/ib68/4m/vP+Jv7z/ib+8/4m/vP+JwsL/icLC/4nCwv+JwsL/isTH/4rEx/+KxMf/ + isTH/4vJz/+Lyc//i8nP/4vJz/+Nz93/jc/d/43P3f+Nz93/jtTs/47U7P+O1Oz/jtTs/4/Y+P+P2Pj/ + j9j4/4/Y+P+P2fr/j9n6/4/Z+v+P2fr/j9n6/4/Z+v+P2fr/j9n6/47T5v+O0+b/jtPm/47T5v+My8j/ + jMvI/4zLyP+My8j/i8Ch/4vAof+LwKH/i8Ch/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ + Z6t4/2ereP9nq3j/Z6t4/zKNSf8yjUn/Mo1J/zKNSf+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcKj/43Co/+NwqP/jcKj/4/Iuf+PyLn/j8i5/4/Iuf+Pzcn/ + j83J/4/Nyf+Pzcn/kNHZ/5DR2f+Q0dn/kNHZ/5HV6P+R1ej/kdXo/5HV6P+R1/L/kdfy/5HX8v+R1/L/ + kdn2/5HZ9v+R2fb/kdn2/5La+v+S2vr/ktr6/5La+v+S2vv/ktr7/5La+/+S2vv/ktr7/5La+/+S2vv/ + ktr7/5La+v+S2vr/ktr6/5La+v+R2fb/kdn2/5HZ9v+R2fb/kdfy/5HX8v+R1/L/kdfy/5HV6P+R1ej/ + kdXo/5HV6P+Q0dj/kNHY/5DR2P+Q0dj/j8zI/4/MyP+PzMj/j8zI/4/Iuf+PyLn/j8i5/4/Iuf+NwqP/ + jcKj/43Co/+NwqP/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/VKFp/1Shaf9UoWn/ + VKFp/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwqP/ + jcKj/43Co/+NwqP/j8i5/4/Iuf+PyLn/j8i5/4/Nyf+Pzcn/j83J/4/Nyf+Q0dn/kNHZ/5DR2f+Q0dn/ + kdXo/5HV6P+R1ej/kdXo/5HX8v+R1/L/kdfy/5HX8v+R2fb/kdn2/5HZ9v+R2fb/ktr6/5La+v+S2vr/ + ktr6/5La+/+S2vv/ktr7/5La+/+S2vv/ktr7/5La+/+S2vv/ktr6/5La+v+S2vr/ktr6/5HZ9v+R2fb/ + kdn2/5HZ9v+R1/L/kdfy/5HX8v+R1/L/kdXo/5HV6P+R1ej/kdXo/5DR2P+Q0dj/kNHY/5DR2P+PzMj/ + j8zI/4/MyP+PzMj/j8i5/4/Iuf+PyLn/j8i5/43Co/+NwqP/jcKj/43Co/+NwJv/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwJv/jcCb/43Am/9UoWn/VKFp/1Shaf9UoWn/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Co/+NwqP/jcKj/43Co/+PyLn/j8i5/4/Iuf+PyLn/ + j83J/4/Nyf+Pzcn/j83J/5DR2f+Q0dn/kNHZ/5DR2f+R1ej/kdXo/5HV6P+R1ej/kdfy/5HX8v+R1/L/ + kdfy/5HZ9v+R2fb/kdn2/5HZ9v+S2vr/ktr6/5La+v+S2vr/ktr7/5La+/+S2vv/ktr7/5La+/+S2vv/ + ktr7/5La+/+S2vr/ktr6/5La+v+S2vr/kdn2/5HZ9v+R2fb/kdn2/5HX8v+R1/L/kdfy/5HX8v+R1ej/ + kdXo/5HV6P+R1ej/kNHY/5DR2P+Q0dj/kNHY/4/MyP+PzMj/j8zI/4/MyP+PyLn/j8i5/4/Iuf+PyLn/ + jcKj/43Co/+NwqP/jcKj/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/1Shaf9UoWn/ + VKFp/1Shaf+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/ + jcKj/43Co/+NwqP/jcKj/4/Iuf+PyLn/j8i5/4/Iuf+Pzcn/j83J/4/Nyf+Pzcn/kNHZ/5DR2f+Q0dn/ + kNHZ/5HV6P+R1ej/kdXo/5HV6P+R1/L/kdfy/5HX8v+R1/L/kdn2/5HZ9v+R2fb/kdn2/5La+v+S2vr/ + ktr6/5La+v+S2vv/ktr7/5La+/+S2vv/ktr7/5La+/+S2vv/ktr7/5La+v+S2vr/ktr6/5La+v+R2fb/ + kdn2/5HZ9v+R2fb/kdfy/5HX8v+R1/L/kdfy/5HV6P+R1ej/kdXo/5HV6P+Q0dj/kNHY/5DR2P+Q0dj/ + j8zI/4/MyP+PzMj/j8zI/4/Iuf+PyLn/j8i5/4/Iuf+NwqP/jcKj/43Co/+NwqP/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/VKFp/1Shaf9UoWn/VKFp/4zAmvGMwJrxjMCa8YzAmvGQwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKe/5DCnv+Qwp7/kMKe/5DEo/+QxKP/kMSj/5DEo/+QxKL/ + kMSi/5DEov+QxKL/kMKe/5DCnv+Qwp7/kMKe/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+NwZrx + jcGa8Y3BmvGNwZrxjMCa8YzAmvGMwJrxjMCa8ZDCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp7/ + kMKe/5DCnv+Qwp7/kMSj/5DEo/+QxKP/kMSj/5DEov+QxKL/kMSi/5DEov+Qwp7/kMKe/5DCnv+Qwp7/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/43BmvGNwZrxjcGa8Y3BmvGMwJrxjMCa8YzAmvGMwJrx + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnv+Qwp7/kMKe/5DCnv+QxKP/kMSj/5DEo/+QxKP/ + kMSi/5DEov+QxKL/kMSi/5DCnv+Qwp7/kMKe/5DCnv+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + jcGa8Y3BmvGNwZrxjcGa8YzAmvGMwJrxjMCa8YzAmvGQwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKe/5DCnv+Qwp7/kMKe/5DEo/+QxKP/kMSj/5DEo/+QxKL/kMSi/5DEov+QxKL/kMKe/5DCnv+Qwp7/ + kMKe/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+NwZrxjcGa8Y3BmvGNwZrxhr6XxIa+l8SGvpfE + hr6XxJTFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/4/CncaPwp3Gj8Kdxo/CncaGvpfEhr6XxIa+l8SGvpfElMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/j8Kdxo/CncaPwp3Gj8Kdxoa+l8SGvpfE + hr6XxIa+l8SUxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+Pwp3Gj8Kdxo/CncaPwp3Ghr6XxIa+l8SGvpfEhr6XxJTFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/4/CncaPwp3Gj8Kdxo/CncZ8u48p + fLuPKXy7jyl8u48pk8ag9ZPGoPWTxqD1k8ag9ZbHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+YyKX2 + mMil9pjIpfaYyKX2mceoMpnHqDKZx6gymceoMny7jyl8u48pfLuPKXy7jymTxqD1k8ag9ZPGoPWTxqD1 + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5jIpfaYyKX2mMil9pjIpfaZx6gymceoMpnHqDKZx6gy + fLuPKXy7jyl8u48pfLuPKZPGoPWTxqD1k8ag9ZPGoPWWx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + mMil9pjIpfaYyKX2mMil9pnHqDKZx6gymceoMpnHqDJ8u48pfLuPKXy7jyl8u48pk8ag9ZPGoPWTxqD1 + k8ag9ZbHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+YyKX2mMil9pjIpfaYyKX2mceoMpnHqDKZx6gy + mceoMgAAAAAAAAAAAAAAAAAAAAB8u48pfLuPKXy7jyl8u48pjMKbxYzCm8WMwpvFjMKbxZbHo/KWx6Py + lsej8pbHo/KZyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+ayafzmsmn85rJp/OayafzlsaiyZbGosmWxqLJ + lsaiyZvIqjObyKozm8iqM5vIqjMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHy7jyl8u48p + fLuPKXy7jymMwpvFjMKbxYzCm8WMwpvFlsej8pbHo/KWx6Pylsej8pnJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5rJp/Oayafzmsmn85rJp/OWxqLJlsaiyZbGosmWxqLJm8iqM5vIqjObyKozm8iqMwAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfLuPKXy7jyl8u48pfLuPKYzCm8WMwpvFjMKbxYzCm8WWx6Py + lsej8pbHo/KWx6Pymcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/msmn85rJp/Oayafzmsmn85bGosmWxqLJ + lsaiyZbGosmbyKozm8iqM5vIqjObyKozAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB8u48p + fLuPKXy7jyl8u48pjMKbxYzCm8WMwpvFjMKbxZbHo/KWx6Pylsej8pbHo/KZyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+ayafzmsmn85rJp/OayafzlsaiyZbGosmWxqLJlsaiyZvIqjObyKozm8iqM5vIqjMAAAAA + AAAAAAAAAAAAAAAA8AAAAAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAAAP + 8AAAAAAAAAAAAAAAAAAADwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAPAAAAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAA + AAAAD/AAAAAAAAAAAAAAAAAAAA8oAAAAQAAAAIAAAAABACAAAAAAAABAAAATCwAAEwsAAAAAAAAAAAAA + AAAAAAAAAAAbZCQcG2QkHB1nJqkdZyapHGcm5xxnJuccZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/ + HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/ + HGcm/xxnJv8YWiH/GFoh/xZSHv8WUh7/F1Mf/xdTH/8XVB//F1Qf/xdUH/8XVB//F1Yg/xdWIP8XViD/ + F1Yg/xhXIP8YVyD/GFgg/xhYIP8YWSH/GFkh/xhaIf8YWiH/GVoh/xlaIf8YXCLpGFwi6RpcIq8aXCKv + GVohHxlaIR8AAAAAAAAAAAAAAAAAAAAAG2QkHBtkJBwdZyapHWcmqRxnJuccZybnHGcm/xxnJv8cZyb/ + HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/ + HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/GFoh/xhaIf8WUh7/FlIe/xdTH/8XUx//F1Qf/xdUH/8XVB// + F1Qf/xdWIP8XViD/F1Yg/xdWIP8YVyD/GFcg/xhYIP8YWCD/GFkh/xhZIf8YWiH/GFoh/xlaIf8ZWiH/ + GFwi6RhcIukaXCKvGlwirxlaIR8ZWiEfAAAAAAAAAAAbZCQcG2QkHB1oJ+0daCftHWgn/x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8ZWiL/GVoi/xdRHv8XUR7/F1If/xdSH/8XUx// + F1Mf/xdUH/8XVB//GFQg/xhUIP8YVSD/GFUg/xhWIP8YViD/GFch/xhXIf8ZWCH/GVgh/xlZIf8ZWSH/ + GVoi/xlaIv8ZWyL/GVsi/xlbIv8ZWyL/Glwj/xpcI/8aXSLvGl0i7xlaIR8ZWiEfG2QkHBtkJBwdaCft + HWgn7R1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/GVoi/xlaIv8XUR7/ + F1Ee/xdSH/8XUh//F1Mf/xdTH/8XVB//F1Qf/xhUIP8YVCD/GFUg/xhVIP8YViD/GFYg/xhXIf8YVyH/ + GVgh/xlYIf8ZWSH/GVkh/xlaIv8ZWiL/GVsi/xlbIv8ZWyL/GVsi/xpcI/8aXCP/Gl0i7xpdIu8ZWiEf + GVohHx5qKakeaimpHmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8aWyL/ + Glsi/xdRH/8XUR//F1If/xdSH/8XUx//F1Mf/xhUIP8YVCD/GFQg/xhUIP8YVSD/GFUg/xhWIP8YViD/ + GVch/xlXIf8ZWCH/GVgh/xlZIv8ZWSL/GVoi/xlaIv8aWyL/Glsi/xpbI/8aWyP/Glwj/xpcI/8aXSP/ + Gl0j/xteI/8bXiP/HF8krxxfJK8eaimpHmopqR5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Glsi/xpbIv8XUR//F1Ef/xdSH/8XUh//F1Mf/xdTH/8YVCD/GFQg/xhUIP8YVCD/ + GFUg/xhVIP8YViD/GFYg/xlXIf8ZVyH/GVgh/xlYIf8ZWSL/GVki/xlaIv8ZWiL/Glsi/xpbIv8aWyP/ + Glsj/xpcI/8aXCP/Gl0j/xpdI/8bXiP/G14j/xxfJK8cXySvH2sq6B9rKugfayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8aWyT/Glsk/xdQH/8XUB//Hmlg/x5pYP8eamD/Hmpg/xhTIP8YUyD/ + GFQh/xhUIf8YVCH/GFQh/xlVIf8ZVSH/GVYi/xlWIv8ZVyL/GVci/xlYIv8ZWCL/Glkj/xpZI/8aWiP/ + Gloj/xpbJP8aWyT/G1sk/xtbJP8bXCT/G1wk/xtdJf8bXSX/G14l/xteJf8bXyXpG18l6R9rKugfayro + H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/Glsk/xpbJP8XUB//F1Af/x5pYP8eaWD/ + Hmpg/x5qYP8YUyD/GFMg/xhUIf8YVCH/GFQh/xhUIf8ZVSH/GVUh/xlWIv8ZViL/GVci/xlXIv8ZWCL/ + GVgi/xpZI/8aWSP/Gloj/xpaI/8aWyT/Glsk/xtbJP8bWyT/G1wk/xtcJP8bXSX/G10l/xteJf8bXiX/ + G18l6RtfJekgbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8bWyT/G1sk/x5oWv8eaFr/ + JYKy/yWCsv8pk9//KZPf/ymT3/8pk9//JYKu/yWCrv8eZ1T/HmdU/xlVIv8ZVSL/GVYi/xlWIv8ZVyL/ + GVci/xpYI/8aWCP/Glgj/xpYI/8aWSP/Glkj/xtbJP8bWyT/G1sk/xtbJP8bXCT/G1wk/xtdJf8bXSX/ + HF4l/xxeJf8cXyX/HF8l/xxgJv8cYCb/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + G1sk/xtbJP8eaFr/Hmha/yWCsv8lgrL/KZPf/ymT3/8pk9//KZPf/yWCrv8lgq7/HmdU/x5nVP8ZVSL/ + GVUi/xlWIv8ZViL/GVci/xlXIv8aWCP/Glgj/xpYI/8aWCP/Glkj/xpZI/8bWyT/G1sk/xtbJP8bWyT/ + G1wk/xtcJP8bXSX/G10l/xxeJf8cXiX/HF8l/xxfJf8cYCb/HGAm/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/yBuLf8dZUD/HWVA/ySBp/8kgaf/KZTf/ymU3/8upPf/LqT3/y+o/f8vqP3/L6j9/y+o/f8upPf/ + LqT3/ymU3/8plN//JICl/ySApf8cYkL/HGJC/xlXI/8ZVyP/GVgk/xlYJP8aWCT/Glgk/xpZJf8aWSX/ + Glol/xpaJf8bWyX/G1sl/xtcJv8bXCb/G10m/xtdJv8bXib/G14m/xxfJ/8cXyf/HGAn/xxgJ/8gbi3/ + IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/HWVA/x1lQP8kgaf/JIGn/ymU3/8plN//LqT3/y6k9/8vqP3/ + L6j9/y+o/f8vqP3/LqT3/y6k9/8plN//KZTf/ySApf8kgKX/HGJC/xxiQv8ZVyP/GVcj/xlYJP8ZWCT/ + Glgk/xpYJP8aWSX/Glkl/xpaJf8aWiX/G1sl/xtbJf8bXCb/G1wm/xtdJv8bXSb/G14m/xteJv8cXyf/ + HF8n/xxgJ/8cYCf/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/ + IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXEv/yFxL/8kfH7/JHx+/ymR1P8pkdT/L6X2/y+l9v8wqfz/ + MKn8/yybzf8sm83/IG5a/yBuWv8gbFj/IGxY/yyazP8smsz/MKn8/zCp/P8vpfb/L6X2/yqR1P8qkdT/ + IHRx/yB0cf8aWCT/Glgk/xpZJf8aWSX/G1ol/xtaJf8bWyX/G1sl/xtcJv8bXCb/G10m/xtdJv8cXif/ + HF4n/xxfJ/8cXyf/HGAn/xxgJ/8cYSj/HGEo/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/ + IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFxL/8hcS//JHx+/yR8fv8pkdT/ + KZHU/y+l9v8vpfb/MKn8/zCp/P8sm83/LJvN/yBuWv8gblr/IGxY/yBsWP8smsz/LJrM/zCp/P8wqfz/ + L6X2/y+l9v8qkdT/KpHU/yB0cf8gdHH/Glgk/xpYJP8aWSX/Glkl/xtaJf8bWiX/G1sl/xtbJf8bXCb/ + G1wm/xtdJv8bXSb/HF4n/xxeJ/8cXyf/HF8n/xxgJ/8cYCf/HGEo/xxhKP8icS//InEv/yJxL/8icS// + InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//I3Q7/yN0O/8nh6r/ + J4eq/y2f7P8tn+z/MKr8/zCq/P8un9j/Lp/Y/yFyZv8hcmb/GFEi/xhRIv8ZUiL/GVIi/xlTIv8ZUyL/ + GVQj/xlUI/8idGf/InRn/y6f2P8un9j/MKr8/zCq/P8tn+z/LZ/s/yWEo/8lhKP/HF4z/xxeM/8bWiX/ + G1ol/xtbJv8bWyb/HFwm/xxcJv8cXSf/HF0n/xxeJ/8cXif/HV8n/x1fJ/8dYCj/HWAo/x1hKP8dYSj/ + InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS// + InEv/yN0O/8jdDv/J4eq/yeHqv8tn+z/LZ/s/zCq/P8wqvz/Lp/Y/y6f2P8hcmb/IXJm/xhRIv8YUSL/ + GVIi/xlSIv8ZUyL/GVMi/xlUI/8ZVCP/InRn/yJ0Z/8un9j/Lp/Y/zCq/P8wqvz/LZ/s/y2f7P8lhKP/ + JYSj/xxeM/8cXjP/G1ol/xtaJf8bWyb/G1sm/xxcJv8cXCb/HF0n/xxdJ/8cXif/HF4n/x1fJ/8dXyf/ + HWAo/x1gKP8dYSj/HWEo/yx4Ov8seDr/JXMz/yVzM/8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/ + I3Ix/yNyMf8jcjH/JHQ8/yR0PP8pj73/KY+9/zCp+f8wqfn/MKj0/zCo9P8mgYn/JoGJ/xlQJf8ZUCX/ + GFAi/xhQIv8ZUCP/GVAj/xlSI/8ZUiP/GVMk/xlTJP8aVCT/GlQk/xpUJP8aVCT/G1co/xtXKP8nhY3/ + J4WN/zCq9v8wqvb/MKn5/zCp+f8pjr3/KY69/x1fM/8dXzP/HFsn/xxbJ/8cXCf/HFwn/xxdKP8cXSj/ + HV0o/x1dKP8dXyn/HV8p/x1gKf8dYCn/HmEq/x5hKv8seDr/LHg6/yVzM/8lczP/I3Ix/yNyMf8jcjH/ + I3Ix/yNyMf8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yR0PP8kdDz/KY+9/ymPvf8wqfn/MKn5/zCo9P8wqPT/ + JoGJ/yaBif8ZUCX/GVAl/xhQIv8YUCL/GVAj/xlQI/8ZUiP/GVIj/xlTJP8ZUyT/GlQk/xpUJP8aVCT/ + GlQk/xtXKP8bVyj/J4WN/yeFjf8wqvb/MKr2/zCp+f8wqfn/KY69/ymOvf8dXzP/HV8z/xxbJ/8cWyf/ + HFwn/xxcJ/8cXSj/HF0o/x1dKP8dXSj/HV8p/x1fKf8dYCn/HWAp/x5hKv8eYSr/UpFd/1KRXf9SkV3/ + UpFd/0mLVf9Ji1X/PoRK/z6ESv8zfkD/M35A/yh3Nv8odzb/JHY7/yR2O/8qk8D/KpPA/zGr+/8xq/v/ + Lp3N/y6dzf8dYEL/HWBC/xhOIv8YTiL/GU8i/xlPIv8ZUCP/GVAj/xlRI/8ZUSP/GVIj/xlSI/8aUyT/ + GlMk/xpUJP8aVCT/GlUl/xpVJf8bViX/G1Yl/xtXJf8bVyX/IGhJ/yBoSf8uoNP/LqDT/zGr+/8xq/v/ + KpPA/yqTwP8eYDL/HmAy/x1cKP8dXCj/HV0o/x1dKP8dXin/HV4p/x5fKf8eXyn/HmAq/x5gKv8eYSr/ + HmEq/1KRXf9SkV3/UpFd/1KRXf9Ji1X/SYtV/z6ESv8+hEr/M35A/zN+QP8odzb/KHc2/yR2O/8kdjv/ + KpPA/yqTwP8xq/v/Mav7/y6dzf8unc3/HWBC/x1gQv8YTiL/GE4i/xlPIv8ZTyL/GVAj/xlQI/8ZUSP/ + GVEj/xlSI/8ZUiP/GlMk/xpTJP8aVCT/GlQk/xpVJf8aVSX/G1Yl/xtWJf8bVyX/G1cl/yBoSf8gaEn/ + LqDT/y6g0/8xq/v/Mav7/yqTwP8qk8D/HmAy/x5gMv8dXCj/HVwo/x1dKP8dXSj/HV4p/x1eKf8eXyn/ + Hl8p/x5gKv8eYCr/HmEq/x5hKv9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/ + VpRh/1aUYf9Uprn/VKa5/0m2+/9Jtvv/NZy9/zWcvf9ZfV3/WX1d/2KDYv9ig2L/Y4Ni/2ODYv9jhGL/ + Y4Ri/2OFYv9jhWL/Y4Vi/2OFYv9jhmP/Y4Zj/2OHY/9jh2P/ZIdk/2SHZP9kiGT/ZIhk/2SJZP9kiWT/ + ZIlk/2SJZP9limT/ZYpk/1qFYv9ahWL/MJvC/zCbwv8yrfv/Mq37/yqQqf8qkKn/HVwo/x1cKP8dXSn/ + HV0p/x5eKf8eXin/Hl8p/x5fKf8eYCr/HmAq/x9iK/8fYiv/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/ + VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VKa5/1Smuf9Jtvv/Sbb7/zWcvf81nL3/WX1d/1l9Xf9ig2L/ + YoNi/2ODYv9jg2L/Y4Ri/2OEYv9jhWL/Y4Vi/2OFYv9jhWL/Y4Zj/2OGY/9jh2P/Y4dj/2SHZP9kh2T/ + ZIhk/2SIZP9kiWT/ZIlk/2SJZP9kiWT/ZYpk/2WKZP9ahWL/WoVi/zCbwv8wm8L/Mq37/zKt+/8qkKn/ + KpCp/x1cKP8dXCj/HV0p/x1dKf8eXin/Hl4p/x5fKf8eXyn/HmAq/x5gKv8fYiv/H2Ir/1iXZf9Yl2X/ + WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/WJdl/1iXZf9bn4j/W5+I/2LA+v9iwPr/XrHN/16xzf/O1Mb/ + ztTG/9fZzf/X2c3/xMq6/8TKuv+/xrT/v8a0/7/Gs/+/xrP/v8az/7/Gs/+/xrP/v8az/7/HtP+/x7T/ + v8e0/7/HtP+/x7T/v8e0/7/HtP+/x7T/v8i0/7/ItP+/yLT/v8i0/7/ItP+/yLT/zdLC/83Swv++ybb/ + vsm2/y6dw/8uncP/Mq36/zKt+v8jdV7/I3Ve/x1eKv8dXir/HV8q/x1fKv8eYCv/HmAr/x5hK/8eYSv/ + HmIs/x5iLP9Yl2X/WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/W5+I/1ufiP9iwPr/ + YsD6/16xzf9esc3/ztTG/87Uxv/X2c3/19nN/8TKuv/Eyrr/v8a0/7/GtP+/xrP/v8az/7/Gs/+/xrP/ + v8az/7/Gs/+/x7T/v8e0/7/HtP+/x7T/v8e0/7/HtP+/x7T/v8e0/7/ItP+/yLT/v8i0/7/ItP+/yLT/ + v8i0/83Swv/N0sL/vsm2/77Jtv8uncP/Lp3D/zKt+v8yrfr/I3Ve/yN1Xv8dXir/HV4q/x1fKv8dXyr/ + HmAr/x5gK/8eYSv/HmEr/x5iLP8eYiz/XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/XJpo/1yaaP9cmmj/ + XJpo/2W73/9lu9//Zb/t/2W/7f9UgGb/VIBm//v07f/79O3/X4Jk/1+CZP9Selr/Unpa/1B4WP9QeFj/ + PGpF/zxqRf8gVSv/IFUr/xpRJP8aUST/J1sx/ydbMf8nXDH/J1wx/xtUJv8bVCb/G1Um/xtVJv8bVif/ + G1Yn/xxXJ/8cVyf/HFgo/xxYKP8sZDX/LGQ1//nw5//58Of/IGU+/yBlPv8yquv/Mqrr/zGk1/8xpNf/ + Hl4q/x5eKv8eXyv/Hl8r/x5gK/8eYCv/H2Ar/x9gK/8fYiz/H2Is/1yaaP9cmmj/XJpo/1yaaP9cmmj/ + XJpo/1yaaP9cmmj/XJpo/1yaaP9lu9//Zbvf/2W/7f9lv+3/VIBm/1SAZv/79O3/+/Tt/1+CZP9fgmT/ + Unpa/1J6Wv9QeFj/UHhY/zxqRf88akX/IFUr/yBVK/8aUST/GlEk/ydbMf8nWzH/J1wx/ydcMf8bVCb/ + G1Qm/xtVJv8bVSb/G1Yn/xtWJ/8cVyf/HFcn/xxYKP8cWCj/LGQ1/yxkNf/58Of/+fDn/yBlPv8gZT7/ + Mqrr/zKq6/8xpNf/MaTX/x5eKv8eXir/Hl8r/x5fK/8eYCv/HmAr/x9gK/8fYCv/H2Is/x9iLP9gnWz/ + YJ1s/2CdbP9gnWz/YJ1s/2CdbP9gnWz/YJ1s/2Gjg/9ho4P/acX8/2nF/P9goKH/YKCh/1V6XP9Velz/ + +/Xw//v18P9fg2b/X4Nm/1V9Xv9VfV7/VX1e/1V9Xv9VfV7/VX1e/1R9Xf9UfV3/PGtF/zxrRf+Qp47/ + kKeO/4+mjP+Ppoz/G1Qn/xtUJ/8bVSf/G1Un/xxWKP8cVij/HFgo/xxYKP8cWSn/HFkp/ytiNf8rYjX/ + +vLq//ry6v8dWyr/HVsq/ymIh/8piIf/M7D7/zOw+/8jcFD/I3BQ/x5fLP8eXyz/H2As/x9gLP8fYS3/ + H2Et/yBjLf8gYy3/YJ1s/2CdbP9gnWz/YJ1s/2CdbP9gnWz/YJ1s/2CdbP9ho4P/YaOD/2nF/P9pxfz/ + YKCh/2Cgof9Velz/VXpc//v18P/79fD/X4Nm/1+DZv9VfV7/VX1e/1V9Xv9VfV7/VX1e/1V9Xv9UfV3/ + VH1d/zxrRf88a0X/kKeO/5Cnjv+Ppoz/j6aM/xtUJ/8bVCf/G1Un/xtVJ/8cVij/HFYo/xxYKP8cWCj/ + HFkp/xxZKf8rYjX/K2I1//ry6v/68ur/HVsq/x1bKv8piIf/KYiH/zOw+/8zsPv/I3BQ/yNwUP8eXyz/ + Hl8s/x9gLP8fYCz/H2Et/x9hLf8gYy3/IGMt/2Ofb/9jn2//Y59v/2Ofb/9jn2//Y59v/2Ofb/9jn2// + Z7O0/2eztP9rxff/a8X3/1mBav9ZgWr/V3xf/1d8X//89vH//Pbx/2KEaf9ihGn/WH5g/1h+YP9Yf2D/ + WH9g/1l/Yf9Zf2H/WYBh/1mAYf9ZgWL/WYFi/6+/rf+vv63/obSe/6G0nv8eVir/HlYq/xxVJ/8cVSf/ + HFYo/xxWKP8cVyj/HFco/x1YKf8dWCn/K2I1/ytiNf/78+z/+/Ps/x5bKv8eWyr/IGY9/yBmPf80sPf/ + NLD3/yuQl/8rkJf/H18s/x9fLP8fYCz/H2As/yBhLf8gYS3/IGIu/yBiLv9jn2//Y59v/2Ofb/9jn2// + Y59v/2Ofb/9jn2//Y59v/2eztP9ns7T/a8X3/2vF9/9ZgWr/WYFq/1d8X/9XfF///Pbx//z28f9ihGn/ + YoRp/1h+YP9YfmD/WH9g/1h/YP9Zf2H/WX9h/1mAYf9ZgGH/WYFi/1mBYv+vv63/r7+t/6G0nv+htJ7/ + HlYq/x5WKv8cVSf/HFUn/xxWKP8cVij/HFco/xxXKP8dWCn/HVgp/ytiNf8rYjX/+/Ps//vz7P8eWyr/ + Hlsq/yBmPf8gZj3/NLD3/zSw9/8rkJf/K5CX/x9fLP8fXyz/H2As/x9gLP8gYS3/IGEt/yBiLv8gYi7/ + Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9tvtf/bb7X/2y81/9svNf/W35i/1t+Yv9bf2P/ + W39j//z48//8+PP/Zods/2aHbP9cgWT/XIFk/1yBZP9cgWT/Zoht/2aIbf+wwK//sMCv/7LCsf+ywrH/ + 2d7U/9ne1P/Z3tT/2d7U/6/Arf+vwK3/m7Ka/5uymv8pXzT/KV80/x1XKP8dVyj/HVgp/x1YKf8rYzb/ + K2M2//v17v/79e7/Hlwr/x5cK/8eXSv/Hl0r/zGjy/8xo8v/MKLG/zCixv8fYCz/H2As/yBhLf8gYS3/ + IGIt/yBiLf8gYy7/IGMu/2ejc/9no3P/Z6Nz/2ejc/9no3P/Z6Nz/2ejc/9no3P/bb7X/22+1/9svNf/ + bLzX/1t+Yv9bfmL/W39j/1t/Y//8+PP//Pjz/2aHbP9mh2z/XIFk/1yBZP9cgWT/XIFk/2aIbf9miG3/ + sMCv/7DAr/+ywrH/ssKx/9ne1P/Z3tT/2d7U/9ne1P+vwK3/r8Ct/5uymv+bspr/KV80/ylfNP8dVyj/ + HVco/x1YKf8dWCn/K2M2/ytjNv/79e7/+/Xu/x5cK/8eXCv/Hl0r/x5dK/8xo8v/MaPL/zCixv8wosb/ + H2As/x9gLP8gYS3/IGEt/yBiLf8gYi3/IGMu/yBjLv9qpXf/aqV3/2qld/9qpXf/aqV3/2qld/9qpXf/ + aqV3/3HG7P9xxuz/bLO//2yzv/9egGX/XoBl/16BZf9egWX//fn1//359f9oiW//aIlv/16DZ/9eg2f/ + XoNn/16DZ/9oinD/aIpw/7HBsf+xwbH/s8Oz/7PDs//b4Nb/2+DW/9vg1v/b4Nb/tMS0/7TEtP+yw7L/ + ssOy/1J+XP9Sflz/IFos/yBaLP8dWCr/HVgq/ytiNv8rYjb//Pbw//z28P8eWyz/Hlss/x5cLP8eXCz/ + Lpiq/y6Yqv80reX/NK3l/x9fLf8fXy3/H2Au/x9gLv8gYS7/IGEu/yBjL/8gYy//aqV3/2qld/9qpXf/ + aqV3/2qld/9qpXf/aqV3/2qld/9xxuz/ccbs/2yzv/9ss7//XoBl/16AZf9egWX/XoFl//359f/9+fX/ + aIlv/2iJb/9eg2f/XoNn/16DZ/9eg2f/aIpw/2iKcP+xwbH/scGx/7PDs/+zw7P/2+DW/9vg1v/b4Nb/ + 2+DW/7TEtP+0xLT/ssOy/7LDsv9Sflz/Un5c/yBaLP8gWiz/HVgq/x1YKv8rYjb/K2I2//z28P/89vD/ + Hlss/x5bLP8eXCz/Hlws/y6Yqv8umKr/NK3l/zSt5f8fXy3/H18t/x9gLv8fYC7/IGEu/yBhLv8gYy// + IGMv/22oev9tqHr/bah6/22oev9tqHr/bah6/22pf/9tqX//dMz7/3TM+/9rqaj/a6mo/2CCaP9ggmj/ + YINo/2CDaP/9+vb//fr2/2uLcv9ri3L/YYVp/2GFaf9ihmn/YoZp/2KGav9ihmr/Yodq/2KHav9jiGv/ + Y4hr/7XFtf+1xbX/tcW2/7XFtv9jimv/Y4pr/2OKbP9jimz/Y4ts/2OLbP9ahGT/WoRk/yxjOP8sYzj/ + K2I3/ytiN//89/L//Pfy/x5cLP8eXCz/Hl0s/x5dLP8rioj/K4qI/zW0+f81tPn/IWQ1/yFkNf8gYS7/ + IGEu/yBiL/8gYi//IWMv/yFjL/9tqHr/bah6/22oev9tqHr/bah6/22oev9tqX//bal//3TM+/90zPv/ + a6mo/2upqP9ggmj/YIJo/2CDaP9gg2j//fr2//369v9ri3L/a4ty/2GFaf9hhWn/YoZp/2KGaf9ihmr/ + YoZq/2KHav9ih2r/Y4hr/2OIa/+1xbX/tcW1/7XFtv+1xbb/Y4pr/2OKa/9jimz/Y4ps/2OLbP9ji2z/ + WoRk/1qEZP8sYzj/LGM4/ytiN/8rYjf//Pfy//z38v8eXCz/Hlws/x5dLP8eXSz/K4qI/yuKiP81tPn/ + NbT5/yFkNf8hZDX/IGEu/yBhLv8gYi//IGIv/yFjL/8hYy//cat+/3Grfv9xq37/cat+/3Grfv9xq37/ + cq+M/3KvjP94zfv/eM37/22loP9tpaD/ZIRr/2SEa/9khWv/ZIVr//36+P/9+vj/bo51/26Odf9liG3/ + ZYht/2WIbf9liG3/ZYlt/2WJbf9mim3/Zopt/2aKbv9mim7/tcW2/7XFtv+1xbb/tcW2/2eMb/9njG// + Z41v/2eNb/9njm//Z45v/2eOcP9njnD/Zo5u/2aObv9Me1b/THtW//z49P/8+PT/Hlss/x5bLP8fXSz/ + H10s/yqDd/8qg3f/NrX5/za1+f8jbUf/I21H/yBhLv8gYS7/IWIv/yFiL/8hYzD/IWMw/3Grfv9xq37/ + cat+/3Grfv9xq37/cat+/3KvjP9yr4z/eM37/3jN+/9tpaD/baWg/2SEa/9khGv/ZIVr/2SFa//9+vj/ + /fr4/26Odf9ujnX/ZYht/2WIbf9liG3/ZYht/2WJbf9liW3/Zopt/2aKbf9mim7/Zopu/7XFtv+1xbb/ + tcW2/7XFtv9njG//Z4xv/2eNb/9njW//Z45v/2eOb/9njnD/Z45w/2aObv9mjm7/THtW/0x7Vv/8+PT/ + /Pj0/x5bLP8eWyz/H10s/x9dLP8qg3f/KoN3/za1+f82tfn/I21H/yNtR/8gYS7/IGEu/yFiL/8hYi// + IWMw/yFjMP90rYH/dK2B/3Stgf90rYH/dK2B/3Stgf91spP/dbKT/3vP+/97z/v/cKWe/3Clnv9nhm7/ + Z4Zu/2eHb/9nh2///fr4//36+P9zknn/c5J5/2iKb/9oim//aIpw/2iKcP9pi3H/aYtx/2mMcf9pjHH/ + aYxx/2mMcf9ylHn/cpR5/3KUev9ylHr/aY5y/2mOcv9qj3P/ao9z/2qQc/9qkHP/apBz/2qQc/9rkXP/ + a5Fz/3WZff91mX3//fr3//369/8jXjD/I14w/x9cLf8fXC3/KYNz/ymDc/82tvn/Nrb5/yVxTf8lcU3/ + IWEv/yFhL/8hYjD/IWIw/yFkMf8hZDH/dK2B/3Stgf90rYH/dK2B/3Stgf90rYH/dbKT/3Wyk/97z/v/ + e8/7/3Clnv9wpZ7/Z4Zu/2eGbv9nh2//Z4dv//36+P/9+vj/c5J5/3OSef9oim//aIpv/2iKcP9oinD/ + aYtx/2mLcf9pjHH/aYxx/2mMcf9pjHH/cpR5/3KUef9ylHr/cpR6/2mOcv9pjnL/ao9z/2qPc/9qkHP/ + apBz/2qQc/9qkHP/a5Fz/2uRc/91mX3/dZl9//369//9+vf/I14w/yNeMP8fXC3/H1wt/ymDc/8pg3P/ + Nrb5/za2+f8lcU3/JXFN/yFhL/8hYS//IWIw/yFiMP8hZDH/IWQx/3evhP93r4T/d6+E/3evhP93r4T/ + d6+E/3i1l/94tZf/ftD7/37Q+/9ypZ3/cqWd/2qJcf9qiXH/aolx/2qJcf/Z39j/2d/Y/+Hm4P/h5uD/ + 2N7W/9je1v/Y3tb/2N7W/9jf1v/Y39b/2N/W/9jf1v/Y39f/2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/ + 2N/X/9jf1//Y39f/2ODX/9jg1//Y4Nf/2ODX/9jg1//Y4Nf/4efh/+Hn4f/Z4tn/2eLZ/1+Kaf9fimn/ + JmE0/yZhNP8pgG3/KYBt/ze3+f83t/n/JnJS/yZyUv8hYTD/IWEw/yFiMP8hYjD/ImMx/yJjMf93r4T/ + d6+E/3evhP93r4T/d6+E/3evhP94tZf/eLWX/37Q+/9+0Pv/cqWd/3Klnf9qiXH/aolx/2qJcf9qiXH/ + 2d/Y/9nf2P/h5uD/4ebg/9je1v/Y3tb/2N7W/9je1v/Y39b/2N/W/9jf1v/Y39b/2N/X/9jf1//Y39f/ + 2N/X/9jf1//Y39f/2N/X/9jf1//Y39f/2N/X/9jg1//Y4Nf/2ODX/9jg1//Y4Nf/2ODX/+Hn4f/h5+H/ + 2eLZ/9ni2f9fimn/X4pp/yZhNP8mYTT/KYBt/ymAbf83t/n/N7f5/yZyUv8mclL/IWEw/yFhMP8hYjD/ + IWIw/yJjMf8iYzH/erKI/3qyiP96soj/erKI/3qyiP96soj/e7id/3u4nf+A0vv/gNL7/3Olm/9zpZv/ + bIt0/2yLdP9ti3X/bYt1/3KQev9ykHr/mK6d/5iunf+dsqH/nbKh/7fGuf+3xrn/6+7p/+vu6f+etKL/ + nrSi/560ov+etKL/nrWi/561ov+etaP/nrWj/561o/+etaP/nrak/562pP/r7ur/6+7q/7fJu/+3ybv/ + n7ek/5+3pP+atKD/mrSg/3Wafv91mn7/cZd6/3GXev9mkHD/ZpBw/zWFcP81hXD/N7j5/ze4+f8ndlj/ + J3ZY/yFhMf8hYTH/IWIx/yFiMf8iZjP/ImYz/3qyiP96soj/erKI/3qyiP96soj/erKI/3u4nf97uJ3/ + gNL7/4DS+/9zpZv/c6Wb/2yLdP9si3T/bYt1/22Ldf9ykHr/cpB6/5iunf+Yrp3/nbKh/52yof+3xrn/ + t8a5/+vu6f/r7un/nrSi/560ov+etKL/nrSi/561ov+etaL/nrWj/561o/+etaP/nrWj/562pP+etqT/ + 6+7q/+vu6v+3ybv/t8m7/5+3pP+ft6T/mrSg/5q0oP91mn7/dZp+/3GXev9xl3r/ZpBw/2aQcP81hXD/ + NYVw/ze4+f83uPn/J3ZY/yd2WP8hYTH/IWEx/yFiMf8hYjH/ImYz/yJmM/9+tYv/frWL/361i/9+tYv/ + frWL/361i/9/u6P/f7uj/4TT+/+E0/v/d6Wa/3elmv9wjXf/cI13/3COeP9wjnj/cI94/3CPeP9wj3n/ + cI95/3GQef9xkHn/kamX/5Gpl//s8Oz/7PDs/3KSev9yknr/cpN6/3KTev9ylHr/cpR6/3KUe/9ylHv/ + c5V7/3OVe/9zlnz/c5Z8/+zw7P/s8Oz/k66Z/5Oumf90mHz/dJh8/3SYff90mH3/dJl9/3SZff90mX7/ + dJl+/3Safv90mn7/c6mZ/3Opmf9EvPj/RLz4/yh4Xf8oeF3/IWEx/yFhMf8iZTP/ImUz/yyAQf8sgEH/ + frWL/361i/9+tYv/frWL/361i/9+tYv/f7uj/3+7o/+E0/v/hNP7/3elmv93pZr/cI13/3CNd/9wjnj/ + cI54/3CPeP9wj3j/cI95/3CPef9xkHn/cZB5/5Gpl/+RqZf/7PDs/+zw7P9yknr/cpJ6/3KTev9yk3r/ + cpR6/3KUev9ylHv/cpR7/3OVe/9zlXv/c5Z8/3OWfP/s8Oz/7PDs/5Oumf+Trpn/dJh8/3SYfP90mH3/ + dJh9/3SZff90mX3/dJl+/3SZfv90mn7/dJp+/3Opmf9zqZn/RLz4/0S8+P8oeF3/KHhd/yFhMf8hYTH/ + ImUz/yJlM/8sgEH/LIBB/4G3jv+Bt47/gbeO/4G3jv+Bt47/gbeO/4K+p/+Cvqf/h9T7/4fU+/95pJj/ + eaSY/3OPev9zj3r/c5B6/3OQev9zkXr/c5F6/3SSe/90knv/dJJ7/3SSe/94loD/eJaA/+3w7P/t8Oz/ + 1N7W/9Te1v+/zcL/v83C/7/Nwv+/zcL/v87C/7/Owv+/zsL/v87C/9Xf1//V39f/7fDt/+3w7f96nIP/ + epyD/3aZf/92mX//d5p//3eaf/93m3//d5t//3ebgP93m4D/d5yB/3ecgf98rp3/fK6d/37R+v9+0fr/ + M4Fo/zOBaP8iZDL/ImQy/y2CQf8tgkH/L4lF/y+JRf+Bt47/gbeO/4G3jv+Bt47/gbeO/4G3jv+Cvqf/ + gr6n/4fU+/+H1Pv/eaSY/3mkmP9zj3r/c496/3OQev9zkHr/c5F6/3ORev90knv/dJJ7/3SSe/90knv/ + eJaA/3iWgP/t8Oz/7fDs/9Te1v/U3tb/v83C/7/Nwv+/zcL/v83C/7/Owv+/zsL/v87C/7/Owv/V39f/ + 1d/X/+3w7f/t8O3/epyD/3qcg/92mX//dpl//3eaf/93mn//d5t//3ebf/93m4D/d5uA/3ecgf93nIH/ + fK6d/3yunf9+0fr/ftH6/zOBaP8zgWj/ImQy/yJkMv8tgkH/LYJB/y+JRf8viUX/hLmR/4S5kf+EuZH/ + hLmR/4S5kf+EuZH/hcCs/4XArP+J1vv/idb7/32qof99qqH/dpF8/3aRfP92kn3/dpJ9/3aTfv92k37/ + dpN+/3aTfv92lH7/dpR+/3eUfv93lH7/gp6K/4Keiv+1xrn/tca5/8DOw//AzsP/wM/D/8DPw//Az8T/ + wM/E/8DPxP/Az8T/tsi6/7bIuv+Eo4v/hKOL/3mbgv95m4L/eZuC/3mbgv95nIL/eZyC/3mdgv95nYL/ + ep2D/3qdg/96noP/ep6D/4Cypf+AsqX/idb7/4nW+/90rJz/dKyc/zSGSv80hkr/MIpH/zCKR/8wikf/ + MIpH/4S5kf+EuZH/hLmR/4S5kf+EuZH/hLmR/4XArP+FwKz/idb7/4nW+/99qqH/faqh/3aRfP92kXz/ + dpJ9/3aSff92k37/dpN+/3aTfv92k37/dpR+/3aUfv93lH7/d5R+/4Keiv+Cnor/tca5/7XGuf/AzsP/ + wM7D/8DPw//Az8P/wM/E/8DPxP/Az8T/wM/E/7bIuv+2yLr/hKOL/4Sji/95m4L/eZuC/3mbgv95m4L/ + eZyC/3mcgv95nYL/eZ2C/3qdg/96nYP/ep6D/3qeg/+AsqX/gLKl/4nW+/+J1vv/dKyc/3SsnP80hkr/ + NIZK/zCKR/8wikf/MIpH/zCKR/+HvJX/h7yV/4e8lf+HvJX/h7yV/4e8lf+Iv6D/iL+g/4zW9f+M1vX/ + jdj6/43Y+v+KzNv/iszb/4W7u/+Fu7v/gKmc/4CpnP97mIP/e5iD/3qXgv96l4L/e5eC/3uXgv97mIL/ + e5iC/3uYgv97mIL/e5mD/3uZg/97mYP/e5mD/3yag/98moP/fJuE/3ybhP98nIT/fJyE/3ychf98nIX/ + fJ2F/3ydhf99nYX/fZ2F/36gh/9+oIf/gq6g/4KuoP+Gv7z/hr+8/4rN3P+Kzdz/jdj6/43Y+v+N1vX/ + jdb1/4e+of+HvqH/drKF/3ayhf8zjEr/M4xK/zGLSP8xi0j/h7yV/4e8lf+HvJX/h7yV/4e8lf+HvJX/ + iL+g/4i/oP+M1vX/jNb1/43Y+v+N2Pr/iszb/4rM2/+Fu7v/hbu7/4CpnP+AqZz/e5iD/3uYg/96l4L/ + epeC/3uXgv97l4L/e5iC/3uYgv97mIL/e5iC/3uZg/97mYP/e5mD/3uZg/98moP/fJqD/3ybhP98m4T/ + fJyE/3ychP98nIX/fJyF/3ydhf98nYX/fZ2F/32dhf9+oIf/fqCH/4KuoP+CrqD/hr+8/4a/vP+Kzdz/ + is3c/43Y+v+N2Pr/jdb1/43W9f+HvqH/h76h/3ayhf92soX/M4xK/zOMSv8xi0j/MYtI/4q+mP+Kvpj/ + ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/isGh/4rBof+NysX/jcrF/47T5P+O0+T/j9n6/4/Z+v+P2fr/ + j9n6/4/Y+P+P2Pj/jtTs/47U7P+Nz93/jc/d/4vHzv+Lx87/isTH/4rEx/+JwcH/icHB/4m+vP+Jvrz/ + ib+8/4m/vP+JwsL/icLC/4rEx/+KxMf/i8nP/4vJz/+Nz93/jc/d/47U7P+O1Oz/j9j4/4/Y+P+P2fr/ + j9n6/4/Z+v+P2fr/jtPm/47T5v+My8j/jMvI/4vAof+LwKH/ir6Y/4q+mP+Kvpj/ir6Y/2ereP9nq3j/ + Mo1J/zKNSf+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/4rBof+KwaH/jcrF/43Kxf+O0+T/ + jtPk/4/Z+v+P2fr/j9n6/4/Z+v+P2Pj/j9j4/47U7P+O1Oz/jc/d/43P3f+Lx87/i8fO/4rEx/+KxMf/ + icHB/4nBwf+Jvrz/ib68/4m/vP+Jv7z/icLC/4nCwv+KxMf/isTH/4vJz/+Lyc//jc/d/43P3f+O1Oz/ + jtTs/4/Y+P+P2Pj/j9n6/4/Z+v+P2fr/j9n6/47T5v+O0+b/jMvI/4zLyP+LwKH/i8Ch/4q+mP+Kvpj/ + ir6Y/4q+mP9nq3j/Z6t4/zKNSf8yjUn/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwJv/jcCb/43Am/+NwqP/jcKj/4/Iuf+PyLn/j83J/4/Nyf+Q0dn/kNHZ/5HV6P+R1ej/ + kdfy/5HX8v+R2fb/kdn2/5La+v+S2vr/ktr7/5La+/+S2vv/ktr7/5La+v+S2vr/kdn2/5HZ9v+R1/L/ + kdfy/5HV6P+R1ej/kNHY/5DR2P+PzMj/j8zI/4/Iuf+PyLn/jcKj/43Co/+NwJv/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/9UoWn/VKFp/43Am/+NwJv/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcKj/43Co/+PyLn/j8i5/4/Nyf+Pzcn/ + kNHZ/5DR2f+R1ej/kdXo/5HX8v+R1/L/kdn2/5HZ9v+S2vr/ktr6/5La+/+S2vv/ktr7/5La+/+S2vr/ + ktr6/5HZ9v+R2fb/kdfy/5HX8v+R1ej/kdXo/5DR2P+Q0dj/j8zI/4/MyP+PyLn/j8i5/43Co/+NwqP/ + jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/VKFp/1Shaf+MwJrx + jMCa8ZDCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKe/5DCnv+QxKP/ + kMSj/5DEov+QxKL/kMKe/5DCnv+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/43BmvGNwZrxjMCa8YzAmvGQwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnv+Qwp7/kMSj/5DEo/+QxKL/kMSi/5DCnv+Qwp7/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+NwZrxjcGa8Ya+l8SGvpfElMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/j8Kdxo/CncaGvpfEhr6XxJTFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/4/CncaPwp3G + fLuPKXy7jymTxqD1k8ag9ZbHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + mMil9pjIpfaZx6gymceoMny7jyl8u48pk8ag9ZPGoPWWx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5jIpfaYyKX2mceoMpnHqDIAAAAAAAAAAHy7jyl8u48pjMKbxYzCm8WWx6Py + lsej8pnJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5rJp/OayafzlsaiyZbGosmbyKozm8iqMwAAAAAAAAAAAAAAAAAAAAB8u48p + fLuPKYzCm8WMwpvFlsej8pbHo/KZyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+ayafzmsmn85bGosmWxqLJm8iqM5vIqjMAAAAA + AAAAAMAAAAAAAAADwAAAAAAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAAAAAA8AAAAAAAAADKAAAADAAAABgAAAAAQAgAAAAAAAAJAAA + EwsAABMLAAAAAAAAAAAAAAAAAAAbZCQOG2QkHB1nJqkcZybIHGcm5xxnJv8cZyb/HGcm/xxnJv8cZyb/ + HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xhaIf8XViD/ + FlIe/xdTH/8XVB//F1Qf/xdUH/8XVSD/F1Yg/xdWIP8YVyD/GFcg/xhYIP8YWSH/GFkh/xhaIf8ZWiH/ + GVoh/xhcIukZXCLMGlwirxlaIR8ZWiEQAAAAABtkJA4dZyZJHWgnhR1oJ9QdaCfkHWgn8x1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8cZCX/ + G2Ek/xhWIP8XVB//F1If/xdTH/8XVB//F1Qf/xhUIP8YVSD/GFYg/xhWIP8YVyD/GFch/xlYIf8ZWSH/ + GVkh/xlaIv8ZWiL/GVsi/xlbIvQZXCLmGlwj1xpdIocaXCJLGVohEBtkJBwdaCeFHWgn7R1oJ/8daCf/ + HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/x1oJ/8bYSX/GVoi/xdRHv8XUh//F1If/xdTH/8XVB//F1Qf/xhUIP8YVSD/GFUg/xhWIP8YVyH/ + GFch/xlYIf8ZWSH/GVkh/xlaIv8ZWyL/GVsi/xlbIv8aXCP/Glwj/xpdIu8aXSKHGVohHx5qKakeaijU + Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8eaij/Hmoo/xpbIv8ZViH/F1Ef/xdSH/8XUx//F1Mf/xhUIP8YVCD/GFQg/xhVIP8YViD/ + GFYg/xlXIf8ZWCH/GVgh/xlZIv8ZWiL/GVoi/xpbIv8aWyP/Glsj/xpcI/8aXSP/Gl0j/xteI/8bXiPX + HF8krx9rKskfaynkH2sp/x9rKf8fayn/H2sp/x9rKf8fayn/H2sp/x9rKf8fayn/H2sp/x9rKf8fayn/ + H2sp/x9rKf8fayn/H2sp/x9rKf8dZyj/HGMm/xlWIf8aWTD/G11A/xteQP8ZWTD/GFMg/xhUIf8YVCH/ + GFQh/xlVIf8ZViH/GVYh/xlXIv8ZWCL/GVgi/xpZI/8aWiP/Gloj/xpbI/8aWyP/G1sk/xtcJP8bXST/ + G10k/xteJP8bXiTmG18lzB9rKugfayr0H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8dYyf/Glsk/xdQH/8bXUD/Hmlg/x5qYP8bX0D/ + GFMg/xhUIf8YVCH/GFQh/xlVIf8ZViL/GVYi/xlXIv8ZWCL/GVgi/xpZI/8aWiP/Gloj/xpbJP8bWyT/ + G1sk/xtcJP8bXSX/G10l/xteJf8bXiX0G18l6SBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/xtbJP8dYj//Hmha/yWCsv8ni8n/ + KZPf/ymT3/8ni8f/JYKu/x5nVP8cXjv/GVUi/xlWIv8ZVyL/GVci/xpYI/8aWCP/Glgj/xpZI/8bWiT/ + G1sk/xtbJP8bXCT/G1wk/xtdJf8cXiX/HF4l/xxfJf8cYCb/HGAm/yBuLP8gbiz/IG4s/yBuLP8gbiz/ + IG4s/yBuLP8gbiz/IG4s/yBuLP8gbiz/IG4s/yBuLP8gbiz/IG4s/yBuLP8fazH/H2k2/yBuZv8idoH/ + JH6d/yqT1f8rmOH/LJ7u/yye7v8rmOD/KpPT/yR+mv8hdH//H2tk/xtcMv8aWir/GVcj/xpYJP8aWCT/ + Glgk/xpZJP8aWiT/G1sl/xtbJf8bXCX/G1wl/xtdJv8bXib/HF4m/xxfJv8cYCb/HGAn/yBuLf8gbi3/ + IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/IG4t/yBuLf8fajf/ + HWVA/ySBp/8ni8P/KZTf/y6k9/8vpvr/L6j9/y+o/f8vpvr/LqT3/ymU3/8nisL/JICl/xxiQv8bXTP/ + GVcj/xlYJP8aWCT/Glgk/xpZJf8aWiX/Glol/xtbJf8bXCb/G1wm/xtdJv8bXib/G14m/xxfJ/8cYCf/ + HGAn/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcC7/IXAu/yFwLv8hcS// + IXEv/yR8fv8nh6n/KZHU/y+l9v8wp/n/MKn8/yybzf8mhZT/IG5a/yBsWP8mg5L/LJrM/zCp/P8wp/n/ + L6X2/yqR1P8lg6P/IHRx/xpYJP8aWSX/Glkl/xtaJf8bWyX/G1sl/xtcJv8bXSb/G10m/xxeJ/8cXyf/ + HF8n/xxgJ/8cYSj/HGEo/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS// + InEv/yJyNf8jd1H/JHxt/ymOtf8rls//LZ7o/y+i5/8smMz/KY6x/yJ2eP8fa1v/HWA+/x1gPf8ga1r/ + I3d4/ymPsv8smMz/L6Ln/y2e6P8qlMv/J4qv/yBuZP8dZUj/G1ws/xtaJf8bWyX/G1sm/xxcJv8cXSb/ + HF0n/xxeJ/8cXyf/HV8n/x1gKP8dYSj/HWEo/yJxL/8icS//InEv/yJxL/8icS//InEv/yJxL/8icS// + InEv/yJxL/8icS//InEv/yN0O/8lfnP/J4eq/y2f7P8vpfT/MKr8/y6f2P8oiZ//IXJm/xhRIv8ZUiL/ + GVIi/xlTIv8ZVCP/GVQj/yJ0Z/8oiqD/Lp/Y/zCq/P8vpfT/LZ/s/yWEo/8hcWv/HF4z/xtaJf8bWyb/ + G1sm/xxcJv8cXSf/HF0n/xxeJ/8dXyf/HV8n/x1gKP8dYSj/HWEo/yx4Ov8pdjf/JXMz/yNyMf8jcjH/ + I3Ix/yNyMf8jcjH/I3Ix/yNyMf8kczf/JHQ8/ymPvf8tnNv/MKn5/zCo9P8rlb//JoGJ/xlQJf8ZUCT/ + GFAi/xlQI/8ZUSP/GVIj/xlTJP8aVCT/GlQk/xpUJP8bVib/G1co/yeFjf8smML/MKr2/zCp+f8tnNv/ + KY69/x1fM/8dXS3/HFsn/xxcJ/8cXSj/HF0o/x1dKP8dXin/HV8p/x1gKf8eYSr/HmEq/z+FTP89g0r/ + PIJI/zZ/Q/8zfUD/MXs+/yt4Of8odjb/JnU0/yR0Nv8lfFr/J4R+/y2d3P8uoOD/L6Pj/yeEm/8jdnj/ + H2hW/xlQJP8ZUCP/GVAj/xlRI/8ZUSP/GVIj/xpTJP8aVCT/GlQk/xpVJf8bVib/G1cn/yFuWf8lfHz/ + KImg/y+l5v8uoeH/LZ3c/yR5ev8ga1P/HV4t/x1cKP8dXSj/HV0o/x1eKf8dXin/Hl8p/x5gKv8eYSr/ + HmEq/1KRXf9SkV3/UpFd/0mLVf9EiFD/PoRK/zN+QP8uezv/KHc2/yR2O/8nhX7/KpPA/zGr+/8wpOT/ + Lp3N/x1gQv8bVzL/GE4i/xlPIv8ZUCP/GVAj/xlRI/8ZUiP/GVIj/xpTJP8aVCT/GlQk/xpVJf8bViX/ + G1Yl/xtXJf8eYDf/IGhJ/y6g0/8wpuf/Mav7/yqTwP8kenn/HmAy/x1cKP8dXSj/HV0o/x1eKf8eXyn/ + Hl8p/x5gKv8eYSr/HmEq/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1Smuf9Prtr/ + Sbb7/zWcvf9HjY3/WX1d/2KDYv9jg2L/Y4Ni/2OEYv9jhWL/Y4Vi/2OFYv9jhmP/Y4Zj/2OHY/9kh2T/ + ZIdk/2SIZP9kiWT/ZIlk/2SJZP9limT/ZYpk/1qFYv9FkJL/MJvC/zKt+/8un9L/KpCp/x1cKP8dXSn/ + HV0p/x5eKf8eXyn/Hl8p/x5gKv8fYSv/H2Ir/1eWY/9XlmP/V5Zj/1eWY/9XlmP/V5Zj/1eWY/9YmGz/ + WZp1/1uz2v9Xs9//VLTk/4K4wv+Nsqv/mKuV/5Onjv+Spo3/kaWL/5Gli/+RpYv/kaaL/5Gmi/+Rpov/ + kaeM/5GnjP+Rp4z/kqeM/5KojP+SqIz/kqmM/5KpjP+SqYz/kqmM/5Sskv+Fr6f/d7K8/zCl3/8votj/ + Lp/S/yBpQ/8fYzb/HV4q/x5fKv8eXyr/HmAq/x5hK/8eYSv/H2Is/1iXZf9Yl2X/WJdl/1iXZf9Yl2X/ + WJdl/1iXZf9am3f/W5+I/2LA+v9gueT/XrHN/87Uxv/T18r/19nN/8TKuv/CyLf/v8a0/7/Gs/+/xrP/ + v8az/7/Gs/+/x7T/v8e0/7/HtP+/x7T/v8e0/7/HtP+/yLT/v8i0/7/ItP+/yLT/v8i0/83Swv/Gzrz/ + vsm2/y6dw/8wpd//Mq36/yN1Xv8gakT/HV4q/x1fKv8eYCv/HmAr/x5hK/8eYiz/HmIs/1yaaP9cmmj/ + XJpo/1yaaP9cmmj/XJpo/1yaaP9hq6T/Zbvf/2W/7f9doKr/VIBm//v07f+tu6n/X4Jk/1J6Wv9ReVn/ + UHhY/zxqRf8uYDj/IFUr/xpRJP8hViv/J1sx/ydcMf8hWCz/G1Qm/xtVJv8bVif/G1Yn/xxXJ/8cWCj/ + HFgo/yxkNf+Tqo7/+fDn/yBlPv8piJX/Mqrr/zGk1/8ogYH/Hl4q/x5fK/8eYCv/HmAr/x9gK/8fYSz/ + H2Is/16cav9enGr/Xpxq/16cav9enGr/Xpxq/1+fdv9jr7L/Z8Du/2Owx/9clpT/VX1h//v17/+tvKr/ + X4Nl/1R8XP9Te1z/U3tb/0l0Uv9Bbkv/OmlE/yteNf9DcEr/XIFg/1uBX/87a0P/G1Qn/xtVJ/8bVif/ + HFYo/xxYKP8cWCj/HFkp/yxjNf+Tqo//+vHp/x9gNP8mfXf/Lpm5/zKq6f8piZP/IWc9/x5fLP8eYCz/ + H2As/x9hLP8fYiz/IGMt/2CdbP9gnWz/YJ1s/2CdbP9gnWz/YJ1s/2Gjg/9ltMD/acX8/2Cgof9bjX// + VXpc//v18P+tvKv/X4Nm/1V9Xv9VfV7/VX1e/1V9Xv9VfV7/VH1d/zxrRf9miWr/kKeO/4+mjP9VfVr/ + G1Qn/xtVJ/8cVij/HFYo/xxYKP8cWSn/HFkp/ytiNf+TqpD/+vLq/x1bKv8jcln/KYiH/zOw+/8rkKb/ + I3BQ/x5fLP8fYCz/H2As/x9hLf8gYi3/IGMt/2Ofb/9jn2//Y59v/2Ofb/9jn2//Y59v/2eztP9pvNb/ + a8X3/1mBav9Yf2X/V3xf//z28f+vva3/YoRp/1h+YP9Yf2D/WH9g/1l/Yf9ZgGH/WYBh/1mBYv+EoIj/ + r7+t/6G0nv9ghWT/HlYq/xxVJ/8cVij/HFYo/xxXKP8dWCn/HVgp/ytiNf+Tq5H/+/Ps/x5bKv8fYTT/ + IGY9/zSw9/8woMf/K5CX/x9fLP8fYCz/H2As/yBhLf8gYi7/IGIu/2Whcf9loXH/ZaFx/2Whcf9loXH/ + ZaFx/2q5xv9rvdb/bMHn/1qAZv9af2T/WX5h//z38v+wvq7/ZIZr/1qAYv9agGL/WoBi/2CEZ/9yknj/ + haCI/4aiiv+luKX/xM/B/73Juf+SqpL/Z4ts/1yEYf8/b0f/I1su/x1XKP8dWCn/HVgp/ytjNv+Tq5H/ + +/Tt/x5cK/8fXy//H2I0/zOq4f8wocj/Lpmv/x9gLP8fYCz/IGEt/yBiLf8gYi7/IGMu/2ejc/9no3P/ + Z6Nz/2ejc/9no3P/Z6Nz/22+1/9tvdf/bLzX/1t+Yv9bf2P/W39j//z48/+xwLD/Zods/1yBZP9cgWT/ + XIFk/2aIbf+LpI7/sMCv/7LCsf/G0MP/2d7U/9ne1P/Ez8H/r8Ct/5uymv9iiWf/KV80/x1XKP8dWCn/ + HVgp/ytjNv+TrJL/+/Xu/x5cK/8eXSv/Hl0r/zGjy/8xo8n/MKLG/x9gLP8gYS3/IGEt/yBiLf8gYy7/ + IGMu/2qld/9qpXf/aqV3/2qld/9qpXf/aqV3/3HG7P9vvdb/bLO//16AZf9egWX/XoFl//359f+zwbL/ + aIlv/16DZ/9eg2f/XoNn/2iKcP+NppH/scGx/7PDs//H0sX/2+DW/9vg1v/I0sX/tMS0/7LDsv+CoYf/ + Un5c/yBaLP8fWSv/HVgq/ytiNv+UrJP//Pbw/x5bLP8eXCz/Hlws/y6Yqv8xo8j/NK3l/x9fLf8fYC7/ + H2Au/yBhLv8gYi//IGMv/2ynef9sp3n/bKd5/2ynef9sp3r/bKd7/3PJ9P9vvNT/bK60/1+BZ/9fgmf/ + X4Jn//369v+zwrP/aopx/2CEaP9ghGj/YIVo/2WIbf93ln3/iqSO/4umj/+qvKr/yNPG/8jTxv+qvav/ + jKeQ/4unj/9zlnr/W4Vk/z1vSP8xZj3/JV4x/ytiN/+UrJT//Pfx/x5cLP8eXCz/Hl0s/y2Rmf8xocT/ + NbHv/yBiMf8gYTD/IGEu/yBiL/8gYi//IWMv/22oev9tqHr/bah6/22oev9tqX3/bal//3TM+/9wu9L/ + a6mo/2CCaP9gg2j/YINo//369v+0w7T/a4ty/2GFaf9ihmn/YoZp/2KGav9ih2r/Yodq/2OIa/+Mp5D/ + tcW1/7XFtv+MqJH/Y4pr/2OKbP9ji2z/Y4ts/1qEZP9DdE7/LGM4/ytiN/+UrZX//Pfy/x5cLP8eXSz/ + Hl0s/yuKiP8wn8H/NbT5/yFkNf8hYzL/IGEu/yBiL/8hYy//IWMv/3Grfv9xq37/cat+/3Grfv9yrYX/ + cq+M/3jN+/9zuc7/baWg/2SEa/9khWv/ZIVr//36+P+2xLf/bo51/2WIbf9liG3/ZYht/2WJbf9mim3/ + Zopt/2aKbv+OqJL/tcW2/7XFtv+OqZP/Z4xv/2eNb/9njm//Z45v/2eOcP9njm//Zo5u/0x7Vv+kuqX/ + /Pj0/x5bLP8fXCz/H10s/yqDd/8wnLj/NrX5/yNtR/8iZzv/IGEu/yFiL/8hYzD/IWMw/3OsgP9zrID/ + c6yA/3OsgP9zroj/dLGQ/3rO+/90us3/b6Wf/2aFbf9mhm3/ZoZt//36+P+3xbj/cZB3/2eJbv9niW7/ + Z4lv/2eKb/9ni2//aItv/2iLcP9+nIT/lK2Y/5StmP9+nYT/aI1x/2mOcf9pj3H/aY9x/2mPcv9pj3H/ + aZBx/2GKav+vwrD//fn2/yFdLv8gXS3/H10t/yqDdf8wnLf/Nrb5/yRvSv8iaDz/IWEv/yFiMP8hYzD/ + IWQx/3Stgf90rYH/dK2B/3Stgf91sIr/dbKT/3vP+/92us3/cKWe/2eGbv9nh2//Z4dv//36+P+4xrn/ + c5J5/2iKb/9oinD/aIpw/2mLcf9pjHH/aYxx/2mMcf9ukHX/cpR5/3KUev9ukXb/aY5y/2qPc/9qkHP/ + apBz/2qQc/9rkXP/a5Fz/3WZff+5yrr//fr3/yNeMP8hXS//H1wt/ymDc/8wnbb/Nrb5/yVxTf8jaT7/ + IWEv/yFiMP8hYzH/IWQx/3evhP93r4T/d6+E/3evhP94so7/eLWX/37Q+/94u8z/cqWd/2qJcf9qiXH/ + aolx/9nf2P/d49z/4ebg/9je1v/Y3tb/2N7W/9jf1v/Y39b/2N/W/9jf1//Y39f/2N/X/9jf1//Y39f/ + 2N/X/9jf1//Y4Nf/2ODX/9jg1//Y4Nf/2ODX/+Hn4f/d5d3/2eLZ/1+Kaf9Ddk//JmE0/ymAbf8wnLP/ + N7f5/yZyUv8kakH/IWEw/yFiMP8iYzH/ImMx/3mxhv95sYb/ebGG/3mxhv95tJD/erea/3/R+/95u8z/ + c6Wc/2uKc/9rinP/bIpz/6a4qf+xwbT/vcq//7vIvP/BzcL/yNLI/+Ln4P/O2M7/u8q8/7vKvf+7yr3/ + u8q9/7vKvf+7yr3/u8q9/7vLvv/O2c//4ufh/8jVyf/C0MP/vMy+/77Owf+yxrb/p76s/2iRcv9XhWL/ + RnlS/y+Db/8znbT/N7j5/yd0Vf8ka0P/IWEx/yFiMf8iYzH/ImUy/3qyiP96soj/erKI/3qyiP97tZP/ + e7id/4DS+/96vMv/c6Wb/2yLdP9ti3X/bYt1/3KQev+Fn4z/mK6d/52yof+qvK3/t8a5/+vu6f/F0cb/ + nrSi/560ov+etaL/nrWi/561o/+etaP/nrWj/562pP/F0sf/6+7q/7fJu/+rwLD/n7ek/5q0oP+Ip4// + dZp+/3GXev9slHX/ZpBw/zWFcP82n7X/N7j5/yd2WP8kbEX/IWEx/yFiMf8iZDL/ImYz/361i/9+tYv/ + frWL/361i/9/uJf/f7uj/4TT+/9+vMv/d6Wa/3CNd/9wjnj/cI54/3CPeP9wj3n/cI95/3GQef+BnYj/ + kamX/+zw7P+vwbP/cpJ6/3KTev9ylHr/cpR6/3KUe/9zlXv/c5V7/3OWfP+ww7T/7PDs/5Oumf+Eo4v/ + dJh8/3SYff90mX3/dJl9/3SZfv90mn7/dJp+/3Opmf9cs8n/RLz4/yh4Xf8lbUf/IWEx/yJlM/8nczr/ + LIBB/4C2jf+Ato3/gLaN/4C2jf+AuZn/gb2l/4bU+/9/vMr/eKWZ/3KOef9yj3n/co95/3KQef9ykHr/ + cpF6/3ORev98mIP/haCM/+3w7P/I1Mr/o7io/5mwnv+ZsJ7/mbGe/5mxn/+ZsZ//mbKf/6S7qv/I1cv/ + 7fDt/4eljv9+n4b/dZl+/3aZfv92mn7/dpp+/3aaf/92m3//dpuA/3ism/9sucr/Ycf5/y59Y/8ocEr/ + ImMy/yh0Ov8rfD//LoVD/4G3jv+Bt47/gbeO/4G3jv+Cu5v/gr6n/4fU+/+AvMr/eaSY/3OPev9zkHr/ + c5B6/3ORev90knv/dJJ7/3SSe/92lH7/eJaA/+3w7P/h5+H/1N7W/7/Nwv+/zcL/v83C/7/Owv+/zsL/ + v87C/9Xf1//h6OL/7fDt/3qcg/94m4H/dpl//3eaf/93m3//d5t//3ebgP93nIH/d5yB/3yunf99wMz/ + ftH6/zOBaP8rc03/ImQy/y2CQf8uhkP/L4lF/4S5kf+EuZH/hLmR/4S5kf+FvZ//hcCs/4nW+/+DwM7/ + faqh/3aRfP92kn3/dpJ9/3aTfv92k37/dpN+/3aUfv93lH7/d5R+/4Keiv+csqL/tca5/8DOw//Az8P/ + wM/D/8DPxP/Az8T/wM/E/7bIuv+dtqP/hKOL/3mbgv95m4L/eZuC/3mcgv95nYL/eZ2C/3qdg/96noP/ + ep6D/4Cypf+FxND/idb7/3SsnP9UmXP/NIZK/zCKR/8wikf/MIpH/4a7k/+Gu5P/hruT/4a7k/+GvZ3/ + h8Cm/4vW+P+IzOP/hcHO/4CvrP9/q6T/fqec/3uejf96mof/eZaB/3iWgP95loD/eZaA/3+bhv+LpZL/ + mK+e/560o/+etKP/nrSj/561pP+etaT/nrWk/5myn/+NqZT/gKCI/3uchP97nIT/e5yE/3yehf99oov/ + fqaR/4CuoP+Bsqj/graw/4fF0P+JzuT/i9b4/361n/9pqYP/VZxo/zKLSf8xi0j/MYtI/4e8lf+HvJX/ + h7yV/4e8lf+Ivpv/iL+g/4zW9f+N1/j/jdj6/4rM2/+IxMv/hbu7/4CpnP9+oZD/e5iD/3qXgv97l4L/ + e5eC/3uYgv97mIL/e5iC/3uZg/97mYP/e5mD/3yag/98m4T/fJuE/3ychP98nIX/fJyF/3ydhf99nYX/ + fZ2F/36gh/+Ap5T/gq6g/4a/vP+Ixsz/is3c/43Y+v+N1/j/jdb1/4e+of9/uJP/drKF/zOMSv8yjEn/ + MYtI/4q+mP+Kvpj/ir6Y/4q+mP+Kvpj/ir6Y/4rBof+MxrP/jcrF/47T5P+P1u//j9n6/4/Z+v+P2fn/ + j9j4/47U7P+O0uX/jc/d/4vHzv+Lxsv/isTH/4nBwf+JwL//ib68/4m/vP+Jwb//icLC/4rEx/+Lx8v/ + i8nP/43P3f+O0uX/jtTs/4/Y+P+P2fn/j9n6/4/Z+v+P1vD/jtPm/4zLyP+MxrX/i8Ch/4q+mP+Kvpj/ + ir6Y/2ereP9NnGH/Mo1J/4y/mv+Mv5r/jL+a/4y/mv+Mv5r/jL+a/4zBnv+Mw6f/jcWw/47KwP+OzMf/ + js7P/4/R2v+P0t3/j9Ph/4/T4/+P0uP/j9Lj/47P4P+Oz9//js/f/47O3v+Ozd3/jszc/47N3P+Ozd3/ + js7e/47P3/+Oz+D/jtDh/4/S4/+P0uL/j9Pi/4/S4P+P0d3/j9Ha/47Oz/+OzMj/jsrB/43Gsv+Mw6j/ + jMCe/4y/mv+Mv5r/jL+a/3q2iv9fpnH/Q5dZ/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/ + jcCb/43Am/+NwZ//jcKj/4/Iuf+Py8H/j83J/5DR2f+R0+H/kdXo/5HX8v+R2PT/kdn2/5La+v+S2vv/ + ktr7/5La+/+S2vv/ktr6/5HZ9v+R2PT/kdfy/5HV6P+R0+D/kNHY/4/MyP+PysH/j8i5/43Co/+NwZ// + jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/9xsYL/VKFp/4zAmvGOwZz4kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnv+Qw6H/kMSj/5DEov+Qw6D/kMKe/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Pwpz4jcGa8Ym/mduOwZzt + ksSf/5LEn/+SxJ//ksSf/5LEn/+SxJ//ksSf/5LEn/+SxJ//ksSf/5LEn/+SxJ//ksSf/5LEn/+SxJ// + ksSf/5LEn/+SxJ//ksSf/5LEoP+SxKH/ksWi/5LFov+SxKH/ksSg/5LEn/+SxJ//ksSf/5LEn/+SxJ// + ksSf/5LEn/+SxJ//ksSf/5LEn/+SxJ//ksSf/5LEn/+SxJ//ksSf/5LEn/+SxJ//ksSf/5LEn/+Qw53t + jsGb3Ia+l8SOwp3ilMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+SxJ/jj8Kdxny7jymQxJ6Pk8ag9ZbHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5jIpfaYyKaUmceoMny7jxWNw5xSkMSej5LFoOKUxqLtlsek+ZjIpf+YyKX/ + mMil/5jIpf+YyKX/mMil/5jIpf+YyKX/mMil/5jIpf+YyKX/mMil/5jIpf+YyKX/mMil/5jIpf+YyKX/ + mMil/5jIpf+YyKX/mMil/5jIpf+YyKX/mMil/5jIpf+YyKX/mMil/5jIpf+YyKX/mMil/5jIpf+YyKX/ + mMil/5jIpf+YyKX/mMil/5jIpfmXx6Tvlsej5JnIppWZyKZXmceoGQAAAAB8u48VfLuPKYzCm8WSxZ/c + lsej8pnJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5rJp/OYyKXelsaiyZvIqjObyKoaAAAAAIAAAAAAAQAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAACAAAAAAAEAACgAAAAgAAAAQAAAAAEAIAAAAAAAABAAABMLAAATCwAAAAAAAAAAAAAAAAAA + G2QkHB1nJqkcZybnHGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/HGcm/xxnJv8cZyb/ + GFoh/xZSHv8XUx//F1Qf/xdUH/8XViD/F1Yg/xhXIP8YWCD/GFkh/xhaIf8ZWiH/GFwi6RpcIq8ZWiEf + AAAAABtkJBwdaCftHWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/HWgn/x1oJ/8daCf/ + HWgn/xlaIv8XUR7/F1If/xdTH/8XVB//GFQg/xhVIP8YViD/GFch/xlYIf8ZWSH/GVoi/xlbIv8ZWyL/ + Glwj/xpdIu8ZWiEfHmopqR5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/Hmoo/x5qKP8eaij/ + Hmoo/x5qKP8aWyL/F1Ef/xdSH/8XUx//GFQg/xhUIP8YVSD/GFYg/xlXIf8ZWCH/GVki/xlaIv8aWyL/ + Glsj/xpcI/8aXSP/G14j/xxfJK8fayroH2sq/x9rKv8fayr/H2sq/x9rKv8fayr/H2sq/x9rKv8fayr/ + H2sq/x9rKv8fayr/Glsk/xdQH/8eaWD/Hmpg/xhTIP8YVCH/GFQh/xlVIf8ZViL/GVci/xlYIv8aWSP/ + Gloj/xpbJP8bWyT/G1wk/xtdJf8bXiX/G18l6SBtK/8gbSv/IG0r/yBtK/8gbSv/IG0r/yBtK/8gbSv/ + IG0r/yBtK/8gbSv/IG0r/xtbJP8eaFr/JYKy/ymT3/8pk9//JYKu/x5nVP8ZVSL/GVYi/xlXIv8aWCP/ + Glgj/xpZI/8bWyT/G1sk/xtcJP8bXSX/HF4l/xxfJf8cYCb/IG4t/yBuLf8gbi3/IG4t/yBuLf8gbi3/ + IG4t/yBuLf8gbi3/IG4t/yBuLf8dZUD/JIGn/ymU3/8upPf/L6j9/y+o/f8upPf/KZTf/ySApf8cYkL/ + GVcj/xlYJP8aWCT/Glkl/xpaJf8bWyX/G1wm/xtdJv8bXib/HF8n/xxgJ/8hcC7/IXAu/yFwLv8hcC7/ + IXAu/yFwLv8hcC7/IXAu/yFwLv8hcS//JHx+/ymR1P8vpfb/MKn8/yybzf8gblr/IGxY/yyazP8wqfz/ + L6X2/yqR1P8gdHH/Glgk/xpZJf8bWiX/G1sl/xtcJv8bXSb/HF4n/xxfJ/8cYCf/HGEo/yJxL/8icS// + InEv/yJxL/8icS//InEv/yJxL/8icS//I3Q7/yeHqv8tn+z/MKr8/y6f2P8hcmb/GFEi/xlSIv8ZUyL/ + GVQj/yJ0Z/8un9j/MKr8/y2f7P8lhKP/HF4z/xtaJf8bWyb/HFwm/xxdJ/8cXif/HV8n/x1gKP8dYSj/ + LHg6/yVzM/8jcjH/I3Ix/yNyMf8jcjH/I3Ix/yR0PP8pj73/MKn5/zCo9P8mgYn/GVAl/xhQIv8ZUCP/ + GVIj/xlTJP8aVCT/GlQk/xtXKP8nhY3/MKr2/zCp+f8pjr3/HV8z/xxbJ/8cXCf/HF0o/x1dKP8dXyn/ + HWAp/x5hKv9SkV3/UpFd/0mLVf8+hEr/M35A/yh3Nv8kdjv/KpPA/zGr+/8unc3/HWBC/xhOIv8ZTyL/ + GVAj/xlRI/8ZUiP/GlMk/xpUJP8aVSX/G1Yl/xtXJf8gaEn/LqDT/zGr+/8qk8D/HmAy/x1cKP8dXSj/ + HV4p/x5fKf8eYCr/HmEq/1aUYf9WlGH/VpRh/1aUYf9WlGH/VpRh/1Smuf9Jtvv/NZy9/1l9Xf9ig2L/ + Y4Ni/2OEYv9jhWL/Y4Vi/2OGY/9jh2P/ZIdk/2SIZP9kiWT/ZIlk/2WKZP9ahWL/MJvC/zKt+/8qkKn/ + HVwo/x1dKf8eXin/Hl8p/x5gKv8fYiv/WJdl/1iXZf9Yl2X/WJdl/1iXZf9bn4j/YsD6/16xzf/O1Mb/ + 19nN/8TKuv+/xrT/v8az/7/Gs/+/xrP/v8e0/7/HtP+/x7T/v8e0/7/ItP+/yLT/v8i0/83Swv++ybb/ + Lp3D/zKt+v8jdV7/HV4q/x1fKv8eYCv/HmEr/x5iLP9cmmj/XJpo/1yaaP9cmmj/XJpo/2W73/9lv+3/ + VIBm//v07f9fgmT/Unpa/1B4WP88akX/IFUr/xpRJP8nWzH/J1wx/xtUJv8bVSb/G1Yn/xxXJ/8cWCj/ + LGQ1//nw5/8gZT7/Mqrr/zGk1/8eXir/Hl8r/x5gK/8fYCv/H2Is/2CdbP9gnWz/YJ1s/2CdbP9ho4P/ + acX8/2Cgof9Velz/+/Xw/1+DZv9VfV7/VX1e/1V9Xv9UfV3/PGtF/5Cnjv+Ppoz/G1Qn/xtVJ/8cVij/ + HFgo/xxZKf8rYjX/+vLq/x1bKv8piIf/M7D7/yNwUP8eXyz/H2As/x9hLf8gYy3/Y59v/2Ofb/9jn2// + Y59v/2eztP9rxff/WYFq/1d8X//89vH/YoRp/1h+YP9Yf2D/WX9h/1mAYf9ZgWL/r7+t/6G0nv8eVir/ + HFUn/xxWKP8cVyj/HVgp/ytiNf/78+z/Hlsq/yBmPf80sPf/K5CX/x9fLP8fYCz/IGEt/yBiLv9no3P/ + Z6Nz/2ejc/9no3P/bb7X/2y81/9bfmL/W39j//z48/9mh2z/XIFk/1yBZP9miG3/sMCv/7LCsf/Z3tT/ + 2d7U/6/Arf+bspr/KV80/x1XKP8dWCn/K2M2//v17v8eXCv/Hl0r/zGjy/8wosb/H2As/yBhLf8gYi3/ + IGMu/2qld/9qpXf/aqV3/2qld/9xxuz/bLO//16AZf9egWX//fn1/2iJb/9eg2f/XoNn/2iKcP+xwbH/ + s8Oz/9vg1v/b4Nb/tMS0/7LDsv9Sflz/IFos/x1YKv8rYjb//Pbw/x5bLP8eXCz/Lpiq/zSt5f8fXy3/ + H2Au/yBhLv8gYy//bah6/22oev9tqHr/bal//3TM+/9rqaj/YIJo/2CDaP/9+vb/a4ty/2GFaf9ihmn/ + YoZq/2KHav9jiGv/tcW1/7XFtv9jimv/Y4ps/2OLbP9ahGT/LGM4/ytiN//89/L/Hlws/x5dLP8rioj/ + NbT5/yFkNf8gYS7/IGIv/yFjL/9xq37/cat+/3Grfv9yr4z/eM37/22loP9khGv/ZIVr//36+P9ujnX/ + ZYht/2WIbf9liW3/Zopt/2aKbv+1xbb/tcW2/2eMb/9njW//Z45v/2eOcP9mjm7/THtW//z49P8eWyz/ + H10s/yqDd/82tfn/I21H/yBhLv8hYi//IWMw/3Stgf90rYH/dK2B/3Wyk/97z/v/cKWe/2eGbv9nh2// + /fr4/3OSef9oim//aIpw/2mLcf9pjHH/aYxx/3KUef9ylHr/aY5y/2qPc/9qkHP/apBz/2uRc/91mX3/ + /fr3/yNeMP8fXC3/KYNz/za2+f8lcU3/IWEv/yFiMP8hZDH/d6+E/3evhP93r4T/eLWX/37Q+/9ypZ3/ + aolx/2qJcf/Z39j/4ebg/9je1v/Y3tb/2N/W/9jf1v/Y39f/2N/X/9jf1//Y39f/2N/X/9jg1//Y4Nf/ + 2ODX/+Hn4f/Z4tn/X4pp/yZhNP8pgG3/N7f5/yZyUv8hYTD/IWIw/yJjMf96soj/erKI/3qyiP97uJ3/ + gNL7/3Olm/9si3T/bYt1/3KQev+Yrp3/nbKh/7fGuf/r7un/nrSi/560ov+etaL/nrWj/561o/+etqT/ + 6+7q/7fJu/+ft6T/mrSg/3Wafv9xl3r/ZpBw/zWFcP83uPn/J3ZY/yFhMf8hYjH/ImYz/361i/9+tYv/ + frWL/3+7o/+E0/v/d6Wa/3CNd/9wjnj/cI94/3CPef9xkHn/kamX/+zw7P9yknr/cpN6/3KUev9ylHv/ + c5V7/3OWfP/s8Oz/k66Z/3SYfP90mH3/dJl9/3SZfv90mn7/c6mZ/0S8+P8oeF3/IWEx/yJlM/8sgEH/ + gbeO/4G3jv+Bt47/gr6n/4fU+/95pJj/c496/3OQev9zkXr/dJJ7/3SSe/94loD/7fDs/9Te1v+/zcL/ + v83C/7/Owv+/zsL/1d/X/+3w7f96nIP/dpl//3eaf/93m3//d5uA/3ecgf98rp3/ftH6/zOBaP8iZDL/ + LYJB/y+JRf+EuZH/hLmR/4S5kf+FwKz/idb7/32qof92kXz/dpJ9/3aTfv92k37/dpR+/3eUfv+Cnor/ + tca5/8DOw//Az8P/wM/E/8DPxP+2yLr/hKOL/3mbgv95m4L/eZyC/3mdgv96nYP/ep6D/4Cypf+J1vv/ + dKyc/zSGSv8wikf/MIpH/4e8lf+HvJX/h7yV/4i/oP+M1vX/jdj6/4rM2/+Fu7v/gKmc/3uYg/96l4L/ + e5eC/3uYgv97mIL/e5mD/3uZg/98moP/fJuE/3ychP98nIX/fJ2F/32dhf9+oIf/gq6g/4a/vP+Kzdz/ + jdj6/43W9f+HvqH/drKF/zOMSv8xi0j/ir6Y/4q+mP+Kvpj/ir6Y/4rBof+NysX/jtPk/4/Z+v+P2fr/ + j9j4/47U7P+Nz93/i8fO/4rEx/+JwcH/ib68/4m/vP+JwsL/isTH/4vJz/+Nz93/jtTs/4/Y+P+P2fr/ + j9n6/47T5v+My8j/i8Ch/4q+mP+Kvpj/Z6t4/zKNSf+NwJv/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/ + jcKj/4/Iuf+Pzcn/kNHZ/5HV6P+R1/L/kdn2/5La+v+S2vv/ktr7/5La+v+R2fb/kdfy/5HV6P+Q0dj/ + j8zI/4/Iuf+NwqP/jcCb/43Am/+NwJv/jcCb/43Am/+NwJv/VKFp/4zAmvGQwp3/kMKd/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKe/5DEo/+QxKL/kMKe/5DCnf+Qwp3/ + kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+Qwp3/kMKd/5DCnf+NwZrxhr6XxJTFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/ + lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/5TFof+UxaH/lMWh/4/CncZ8u48p + k8ag9ZbHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/ + lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+Wx6T/lsek/5bHpP+YyKX2 + mceoMgAAAAB8u48pjMKbxZbHo/KZyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/ + mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+Zyab/mcmm/5nJpv+ayafz + lsaiyZvIqjMAAAAAgAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAIAAAAEoAAAAEAAAACAAAAABACAAAAAAAAAEAAATCwAAEwsAAAAAAAAAAAAA + HWcmSR1oJ+QdaCf/HWgn/x1oJ/8daCf/HWgn/xxkJf8XVB//F1Qf/xhVIP8YVyD/GVkh/xlaIv8ZXCLm + GlwiSx9rKeQfayn/H2sp/x9rKf8fayn/H2sp/x1nKP8aWTD/GVkw/xhUIf8ZViH/GVgi/xpaI/8aWyP/ + G10k/xteJOYgbiz/IG4s/yBuLP8gbiz/IG4s/x9rMf8idoH/K5jh/yuY4P8hdH//Gloq/xpYJP8aWiT/ + G1wl/xteJv8cYCb/InEv/yJxL/8icS//InEv/yN3Uf8rls//LJjM/x9rW/8ga1r/LJjM/yqUy/8dZUj/ + G1sl/xxdJv8cXyf/HWEo/z2DSv8zfUD/KHY2/yV8Wv8uoOD/I3Z4/xlQI/8ZUSP/GlQk/xtWJv8lfHz/ + LqHh/yBrU/8dXSj/HV4p/x5hKv9XlmP/V5Zj/1iYbP9Xs9//jbKr/5Kmjf+RpYv/kaaL/5GnjP+SqIz/ + kqmM/4Wvp/8votj/H2M2/x5fKv8eYSv/Xpxq/16cav9jr7L/XJaU/628qv9Te1z/QW5L/0NwSv87a0P/ + G1Yn/xxYKP+Tqo//Jn13/ymJk/8eYCz/H2Is/2Whcf9loXH/a73W/1p/ZP+wvq7/WoBi/3KSeP+luKX/ + kqqS/z9vR/8dWCn/k6uR/x9fL/8wocj/H2As/yBiLv9sp3n/bKd6/2+81P9fgmf/s8Kz/2CEaP93ln3/ + qryq/6q9q/9zlnr/MWY9/5SslP8eXCz/MaHE/yBhMP8gYi//c6yA/3OuiP90us3/ZoZt/7fFuP9niW7/ + Z4tv/36chP9+nYT/aY9x/2mPcf+vwrD/IF0t/zCct/8iaDz/IWMw/3mxhv95tJD/ebvM/2uKc/+xwbT/ + wc3C/87Yzv+7yr3/u8q9/87Zz//C0MP/ssa2/1eFYv8znbT/JGtD/yJjMf+Ato3/gLmZ/3+8yv9yj3n/ + cpB6/3yYg//I1Mr/mbCe/5mxn//I1cv/fp+G/3aafv92m3//bLnK/yhwSv8rfD//hruT/4a9nf+IzOP/ + f6uk/3qah/95loD/i6WS/560o/+etaT/jamU/3uchP99oov/gbKo/4nO5P9pqYP/MYtI/4y/mv+Mv5r/ + jMOn/47Mx/+P0t3/j9Lj/47P3/+Ozd3/js3d/47P4P+P0uL/j9Hd/47MyP+Mw6j/jL+a/1+mcf+OwZzt + ksSf/5LEn/+SxJ//ksSf/5LEn/+SxJ//ksSh/5LEof+SxJ//ksSf/5LEn/+SxJ//ksSf/5LEn/+Qw53t + jcOcUpTGou2YyKX/mMil/5jIpf+YyKX/mMil/5jIpf+YyKX/mMil/5jIpf+YyKX/mMil/5jIpf+Xx6Tv + mcimVwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAA= + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/SecureSandbox/about.png b/Demo_Source_Code/CSharpDemo/SecureSandbox/about.png new file mode 100644 index 0000000..4017add Binary files /dev/null and b/Demo_Source_Code/CSharpDemo/SecureSandbox/about.png differ diff --git a/Demo_Source_Code/CSharpDemo/SecureSandbox/app.config b/Demo_Source_Code/CSharpDemo/SecureSandbox/app.config new file mode 100644 index 0000000..c5e1dae --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/SecureSandbox/app.config @@ -0,0 +1,3 @@ + + + diff --git a/Demo_Source_Code/CSharpDemo/SecureSandbox/app.manifest b/Demo_Source_Code/CSharpDemo/SecureSandbox/app.manifest new file mode 100644 index 0000000..aee0ba0 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/SecureSandbox/app.manifest @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Demo_Source_Code/CSharpDemo/SecureShare/ConsoleForm.Designer.cs b/Demo_Source_Code/CSharpDemo/SecureShare/ConsoleForm.Designer.cs new file mode 100644 index 0000000..f6dfd7f --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/SecureShare/ConsoleForm.Designer.cs @@ -0,0 +1,202 @@ +namespace SecureShare +{ + partial class ConsoleForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ConsoleForm)); + this.menuStrip1 = new System.Windows.Forms.MenuStrip(); + this.optionsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.shareManagerToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.exitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStrip1 = new System.Windows.Forms.ToolStrip(); + this.toolStripButton_StartFilter = new System.Windows.Forms.ToolStripButton(); + this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); + this.toolStripButton_Stop = new System.Windows.Forms.ToolStripButton(); + this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator(); + this.toolStripButton_ClearMessage = new System.Windows.Forms.ToolStripButton(); + this.toolStripSeparator3 = new System.Windows.Forms.ToolStripSeparator(); + this.toolStripButton_Help = new System.Windows.Forms.ToolStripButton(); + this.listView_Info = new System.Windows.Forms.ListView(); + this.menuStrip1.SuspendLayout(); + this.toolStrip1.SuspendLayout(); + this.SuspendLayout(); + // + // menuStrip1 + // + this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.optionsToolStripMenuItem, + this.shareManagerToolStripMenuItem, + this.exitToolStripMenuItem}); + this.menuStrip1.Location = new System.Drawing.Point(0, 0); + this.menuStrip1.Name = "menuStrip1"; + this.menuStrip1.Size = new System.Drawing.Size(974, 28); + this.menuStrip1.TabIndex = 0; + this.menuStrip1.Text = "menuStrip1"; + // + // optionsToolStripMenuItem + // + this.optionsToolStripMenuItem.Name = "optionsToolStripMenuItem"; + this.optionsToolStripMenuItem.Size = new System.Drawing.Size(74, 24); + this.optionsToolStripMenuItem.Text = "Settings"; + this.optionsToolStripMenuItem.Click += new System.EventHandler(this.settingsToolStripMenuItem_Click); + // + // shareManagerToolStripMenuItem + // + this.shareManagerToolStripMenuItem.Name = "shareManagerToolStripMenuItem"; + this.shareManagerToolStripMenuItem.Size = new System.Drawing.Size(148, 24); + this.shareManagerToolStripMenuItem.Text = "Share File Manager"; + this.shareManagerToolStripMenuItem.Click += new System.EventHandler(this.shareManagerToolStripMenuItem_Click); + // + // exitToolStripMenuItem + // + this.exitToolStripMenuItem.Name = "exitToolStripMenuItem"; + this.exitToolStripMenuItem.Size = new System.Drawing.Size(45, 24); + this.exitToolStripMenuItem.Text = "Exit"; + this.exitToolStripMenuItem.Click += new System.EventHandler(this.exitToolStripMenuItem_Click); + // + // toolStrip1 + // + this.toolStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.toolStripButton_StartFilter, + this.toolStripSeparator1, + this.toolStripButton_Stop, + this.toolStripSeparator2, + this.toolStripButton_ClearMessage, + this.toolStripSeparator3, + this.toolStripButton_Help}); + this.toolStrip1.Location = new System.Drawing.Point(0, 28); + this.toolStrip1.Name = "toolStrip1"; + this.toolStrip1.Size = new System.Drawing.Size(974, 27); + this.toolStrip1.TabIndex = 1; + this.toolStrip1.Text = "toolStrip1"; + // + // toolStripButton_StartFilter + // + this.toolStripButton_StartFilter.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton_StartFilter.Image"))); + this.toolStripButton_StartFilter.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButton_StartFilter.Name = "toolStripButton_StartFilter"; + this.toolStripButton_StartFilter.Size = new System.Drawing.Size(111, 24); + this.toolStripButton_StartFilter.Text = "Start Service"; + this.toolStripButton_StartFilter.Click += new System.EventHandler(this.toolStripButton_StartFilter_Click); + // + // toolStripSeparator1 + // + this.toolStripSeparator1.Name = "toolStripSeparator1"; + this.toolStripSeparator1.Size = new System.Drawing.Size(6, 27); + // + // toolStripButton_Stop + // + this.toolStripButton_Stop.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton_Stop.Image"))); + this.toolStripButton_Stop.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButton_Stop.Name = "toolStripButton_Stop"; + this.toolStripButton_Stop.Size = new System.Drawing.Size(111, 24); + this.toolStripButton_Stop.Text = "Stop Service"; + this.toolStripButton_Stop.Click += new System.EventHandler(this.toolStripButton_Stop_Click); + // + // toolStripSeparator2 + // + this.toolStripSeparator2.Name = "toolStripSeparator2"; + this.toolStripSeparator2.Size = new System.Drawing.Size(6, 27); + // + // toolStripButton_ClearMessage + // + this.toolStripButton_ClearMessage.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton_ClearMessage.Image"))); + this.toolStripButton_ClearMessage.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButton_ClearMessage.Name = "toolStripButton_ClearMessage"; + this.toolStripButton_ClearMessage.Size = new System.Drawing.Size(131, 24); + this.toolStripButton_ClearMessage.Text = "Clear messages"; + this.toolStripButton_ClearMessage.Click += new System.EventHandler(this.toolStripButton_ClearMessage_Click); + // + // toolStripSeparator3 + // + this.toolStripSeparator3.Name = "toolStripSeparator3"; + this.toolStripSeparator3.Size = new System.Drawing.Size(6, 27); + // + // toolStripButton_Help + // + this.toolStripButton_Help.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton_Help.Image"))); + this.toolStripButton_Help.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButton_Help.Name = "toolStripButton_Help"; + this.toolStripButton_Help.Size = new System.Drawing.Size(61, 24); + this.toolStripButton_Help.Text = "Help"; + this.toolStripButton_Help.Click += new System.EventHandler(this.toolStripButton_Help_Click); + // + // listView_Info + // + this.listView_Info.Dock = System.Windows.Forms.DockStyle.Fill; + this.listView_Info.FullRowSelect = true; + this.listView_Info.HoverSelection = true; + this.listView_Info.LabelEdit = true; + this.listView_Info.Location = new System.Drawing.Point(0, 55); + this.listView_Info.Name = "listView_Info"; + this.listView_Info.ShowItemToolTips = true; + this.listView_Info.Size = new System.Drawing.Size(974, 451); + this.listView_Info.TabIndex = 2; + this.listView_Info.UseCompatibleStateImageBehavior = false; + this.listView_Info.View = System.Windows.Forms.View.Details; + // + // ConsoleForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(974, 506); + this.Controls.Add(this.listView_Info); + this.Controls.Add(this.toolStrip1); + this.Controls.Add(this.menuStrip1); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.MainMenuStrip = this.menuStrip1; + this.Name = "ConsoleForm"; + this.Text = "EaseFilter Secure File Sharing Demo"; + this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.ConsoleForm_FormClosed); + this.menuStrip1.ResumeLayout(false); + this.menuStrip1.PerformLayout(); + this.toolStrip1.ResumeLayout(false); + this.toolStrip1.PerformLayout(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.MenuStrip menuStrip1; + private System.Windows.Forms.ToolStrip toolStrip1; + private System.Windows.Forms.ToolStripButton toolStripButton_StartFilter; + private System.Windows.Forms.ToolStripButton toolStripButton_Stop; + private System.Windows.Forms.ToolStripButton toolStripButton_ClearMessage; + private System.Windows.Forms.ListView listView_Info; + private System.Windows.Forms.ToolStripMenuItem optionsToolStripMenuItem; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator1; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator2; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator3; + private System.Windows.Forms.ToolStripMenuItem shareManagerToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem exitToolStripMenuItem; + private System.Windows.Forms.ToolStripButton toolStripButton_Help; + } +} + diff --git a/Demo_Source_Code/CSharpDemo/SecureShare/ConsoleForm.cs b/Demo_Source_Code/CSharpDemo/SecureShare/ConsoleForm.cs new file mode 100644 index 0000000..c3fb4ee --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/SecureShare/ConsoleForm.cs @@ -0,0 +1,299 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +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; +using System.Reflection; +using System.IO; +using System.Diagnostics; +using System.Runtime.InteropServices; + +using EaseFilter.FilterControl; +using EaseFilter.CommonObjects; + +namespace SecureShare +{ + public partial class ConsoleForm : Form + { + //Purchase a license key with the link: http://www.easefilter.com/Order.htm + //Email us to request a trial key: info@easefilter.com //free email is not accepted. + string licenseKey = "******************************************"; + + EncryptEventHandler encryptEventHandler = null; + FilterControl filterControl = new FilterControl(); + + public ConsoleForm() + { + + GlobalConfig.filterType = FilterAPI.FilterType.MONITOR_FILTER | FilterAPI.FilterType.CONTROL_FILTER | FilterAPI.FilterType.ENCRYPTION_FILTER + | FilterAPI.FilterType.PROCESS_FILTER | FilterAPI.FilterType.REGISTRY_FILTER; + + InitializeComponent(); + + StartPosition = FormStartPosition.CenterScreen; + + encryptEventHandler = new EncryptEventHandler(listView_Info); + + DisplayVersion(); + + } + + private void DisplayVersion() + { + string version = Assembly.GetExecutingAssembly().GetName().Version.ToString(); + try + { + string filterDllPath = Path.Combine(GlobalConfig.AssemblyPath, "FilterAPI.Dll"); + version = FileVersionInfo.GetVersionInfo(filterDllPath).ProductVersion; + } + catch (Exception ex) + { + EventManager.WriteMessage(43, "LoadFilterAPI Dll", EventLevel.Error, "FilterAPI.dll can't be found." + ex.Message); + } + + this.Text += " Version: " + version; + } + + ~ConsoleForm() + { + GlobalConfig.Stop(); + } + + private void MonitorForm_FormClosing(object sender, FormClosingEventArgs e) + { + GlobalConfig.Stop(); + } + + void SendSettingsToFilter() + { + filterControl.ClearFilters(); + + string[] whiteList = null; + string[] blacklist = null; + + FileFilterRule filterRuleShareFolder = new FileFilterRule(); + filterRuleShareFolder.IncludeFileFilterMask = GlobalConfig.ShareFolder + "\\*"; + filterRuleShareFolder.AccessFlag |= (uint)FilterAPI.AccessFlag.ENABLE_FILE_ENCRYPTION_RULE | FilterAPI.ALLOW_MAX_RIGHT_ACCESS; + filterRuleShareFolder.AccessFlag &= (uint)(~FilterAPI.AccessFlag.ALLOW_ENCRYPT_NEW_FILE);// this folder won't encrypt the new file. + filterRuleShareFolder.AccessFlag &= (uint)(~FilterAPI.AccessFlag.ALLOW_READ_ENCRYPTED_FILES);// all process can't read the encyrpted file except the authorized processes. + filterRuleShareFolder.EncryptMethod = (int)FilterAPI.EncryptionMethod.ENCRYPT_FILE_WITH_SAME_KEY_AND_UNIQUE_IV; + filterRuleShareFolder.EncryptionPassPhrase = GlobalConfig.MasterPassword; + + //for whitelist process, it has maximum acess rights. + if (GlobalConfig.ProtectFolderWhiteList == "*") + { + //allow all processes to read the encrypted file except the black list processes. + filterRuleShareFolder.AccessFlag |= (uint)(FilterAPI.AccessFlag.ALLOW_READ_ENCRYPTED_FILES); + } + else + { + //for whitelist process, it has maximum acess rights. + whiteList = GlobalConfig.ShareFolderWhiteList.Split(new char[] { ';' }); + if (whiteList.Length > 0) + { + foreach (string authorizedUser in whiteList) + { + if (authorizedUser.Trim().Length > 0) + { + //not allow to encrypt the new file + uint accessFlag = filterRuleShareFolder.AccessFlag | (uint)(FilterAPI.AccessFlag.ALLOW_READ_ENCRYPTED_FILES); + filterRuleShareFolder.ProcessNameRights += ";" + authorizedUser + "!" + accessFlag.ToString(); + } + } + } + + } + + //for blacklist process, it has maximum acess rights. + blacklist = GlobalConfig.ShareFolderBlackList.Split(new char[] { ';' }); + if (blacklist.Length > 0) + { + foreach (string unAuthorizedUser in blacklist) + { + if (unAuthorizedUser.Trim().Length > 0) + { + //can't read the encrypted files, not allow to encrypt the new file + uint accessFlag = filterRuleShareFolder.AccessFlag; + filterRuleShareFolder.ProcessNameRights += ";" + unAuthorizedUser + "!" + accessFlag.ToString(); + } + } + } + + FileFilter shareFolderFileFilter = filterRuleShareFolder.ToFileFilter(); + shareFolderFileFilter.OnFilterRequestEncryptKey += encryptEventHandler.OnFilterRequestEncryptKey; + filterControl.AddFilter(shareFolderFileFilter); + + FileFilterRule filterRuleProtectFolder = new FileFilterRule(); + filterRuleProtectFolder.IncludeFileFilterMask = GlobalConfig.ProtectFolder + "\\*"; + filterRuleProtectFolder.AccessFlag |= (uint)FilterAPI.AccessFlag.ENABLE_FILE_ENCRYPTION_RULE | FilterAPI.ALLOW_MAX_RIGHT_ACCESS; + filterRuleProtectFolder.AccessFlag &= (uint)(~FilterAPI.AccessFlag.ALLOW_READ_ENCRYPTED_FILES);// all process can't read the encyrpted file except the authorized processes. + filterRuleProtectFolder.EncryptMethod = (int)FilterAPI.EncryptionMethod.ENCRYPT_FILE_WITH_SAME_KEY_AND_UNIQUE_IV; + filterRuleProtectFolder.EncryptionPassPhrase = GlobalConfig.MasterPassword; + + //for whitelist process, it has maximum acess rights. + if (GlobalConfig.ProtectFolderWhiteList == "*") + { + //allow all processes to read the encrypted file except the black list processes. + filterRuleProtectFolder.AccessFlag |= (uint)(FilterAPI.AccessFlag.ALLOW_READ_ENCRYPTED_FILES); + } + else + { + //for whitelist process, it has maximum acess rights. + whiteList = GlobalConfig.ProtectFolderWhiteList.Split(new char[] { ';' }); + if (whiteList.Length > 0) + { + foreach (string authorizedUser in whiteList) + { + if (authorizedUser.Trim().Length > 0) + { + filterRuleProtectFolder.ProcessNameRights += ";" + authorizedUser + "!" + FilterAPI.ALLOW_MAX_RIGHT_ACCESS.ToString(); + } + } + } + } + + //for blacklist process, it has maximum acess rights. + blacklist = GlobalConfig.ProtectFolderBlackList.Split(new char[] { ';' }); + if (blacklist.Length > 0) + { + foreach (string unAuthorizedUser in blacklist) + { + if (unAuthorizedUser.Trim().Length > 0) + { + //can't read the encrypted files + uint accessFlag = FilterAPI.ALLOW_MAX_RIGHT_ACCESS & (uint)(~FilterAPI.AccessFlag.ALLOW_READ_ENCRYPTED_FILES); + filterRuleProtectFolder.ProcessNameRights += ";" + unAuthorizedUser + "!" + accessFlag.ToString(); + } + } + } + + FileFilter protectFolderFileFilter = filterRuleProtectFolder.ToFileFilter(); + protectFolderFileFilter.OnFilterRequestEncryptKey += encryptEventHandler.OnFilterRequestEncryptKey; + filterControl.AddFilter(protectFolderFileFilter); + + string lastError = string.Empty; + if (!filterControl.SendConfigSettingsToFilter(ref lastError)) + { + MessageBox.Show(lastError, "StartFilter", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + + } + + + private void toolStripButton_StartFilter_Click(object sender, EventArgs e) + { + try + { + string lastError = string.Empty; + + bool ret = filterControl.StartFilter(GlobalConfig.filterType, GlobalConfig.FilterConnectionThreads, GlobalConfig.ConnectionTimeOut, licenseKey, ref lastError); + if (!ret) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("Start filter failed." + lastError); + return; + } + + SendSettingsToFilter(); + + toolStripButton_StartFilter.Enabled = false; + toolStripButton_Stop.Enabled = true; + + EventManager.WriteMessage(102, "StartFilter", EventLevel.Information, "Start filter service succeeded."); + } + catch (Exception ex) + { + EventManager.WriteMessage(104, "StartFilter", EventLevel.Error, "Start filter service failed with error " + ex.Message); + } + + } + + private void toolStripButton_Stop_Click(object sender, EventArgs e) + { + filterControl.StopFilter(); + + toolStripButton_StartFilter.Enabled = true; + toolStripButton_Stop.Enabled = false; + } + + private void toolStripButton_ClearMessage_Click(object sender, EventArgs e) + { + encryptEventHandler.InitListView(); + } + + + private void settingsToolStripMenuItem_Click(object sender, EventArgs e) + { + ShareFileSettingForm settingForm = new ShareFileSettingForm(); + settingForm.StartPosition = FormStartPosition.CenterParent; + settingForm.ShowDialog(); + } + + + private void ConsoleForm_FormClosed(object sender, FormClosedEventArgs e) + { + FilterAPI.ResetConfigData(); + GlobalConfig.Stop(); + filterControl.StopFilter(); + Application.Exit(); + } + + private void unInstallFilterDriverToolStripMenuItem_Click(object sender, EventArgs e) + { + filterControl.StopFilter(); + FilterAPI.UnInstallDriver(); + } + + private void shareManagerToolStripMenuItem_Click(object sender, EventArgs e) + { + ShareFileManagerInLocal shareManager = new ShareFileManagerInLocal(); + shareManager.ShowDialog(); + } + + private void toolStripButton_Help_Click(object sender, EventArgs e) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + string helpInfo = "1.Setup the configuration by clicking the settings to test in local or in EaseFilter Server.\r\n"; + helpInfo += "2.Create encrypted files in the share file manager.\r\n"; + helpInfo += "3.Distribute the shared file to the clients.\r\n"; + helpInfo += "4. Copy the shared file to the share file drop folder in the client.\r\n"; + helpInfo += "5. if you want to copy the shared file to real time protected folder in the client, you have to stop the filter service first, or the file will be encrypted again.\r\n"; + helpInfo += "6. Start the filter service in the client.\r\n"; + helpInfo += "7. Open the shared file in the client.\r\n"; + helpInfo += "8. You can check who accessed your files from the access log in the share file manager when you test with the EaseFilter Server.\r\n"; + + MessageBox.Show(helpInfo, "How to use this application?", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + + private void exitToolStripMenuItem_Click(object sender, EventArgs e) + { + FilterAPI.ResetConfigData(); + GlobalConfig.Stop(); + filterControl.StopFilter(); + Close(); + } + + + + } +} diff --git a/Demo_Source_Code/CSharpDemo/SecureShare/ConsoleForm.resx b/Demo_Source_Code/CSharpDemo/SecureShare/ConsoleForm.resx new file mode 100644 index 0000000..a7a44c8 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/SecureShare/ConsoleForm.resx @@ -0,0 +1,1331 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + + 126, 17 + + + + + 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 + AAAAAElFTkSuQmCC + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAAEnQAABJ0Ad5mH3gAAAJFSURBVDhPrdBbSNNxHAXwo2aKl8ZyMy/bKl3WPypvyBQL + iTLCBUoQQdRLYZJGzgqtEKxB5CVSRNuDhkg4NfNBxTKjBokJBkPqRQgNqSU5L7kplTZP7u/vyYd88fPy + 53vO4f/ww6aKtYS/SGuMnTlQrR2JNqu6cRGFyMMeUW8spj6ivfpLPlvcd9i1VMF+1jLnpWFutfJZW2yk + BDpFWcj35p8ltLrvsY81PN6d7hItPmxF9oA/4sW5ThUMac92OuumctkwY6J1sZRdfMDD1kOfxQLvAHVP + EMYHAlAgIqEcutRW3fSN0XSaJ3JoHjtHY1PMcqenjFLDrkGxktmCYbKp4OkLwFERAcpHwU3XRjJo+mRg + Rmf0PO4iF0XIt/4qZlidolbMZO+34aQ9CnwVitciAlJa9zvPDklMtGpcqESCHJZDgSr/CpghybdgV6Fs + Qg8OquF93DVxLfrFLJuevrUoFZFsJQLSfBTur4Qh1Hv/UCNhQgvXjAQOR2BSHnlpnihthh4NUYNjIpIt + JwfWsyiR45G4PKXBpdmDgfNM9eOfBHBIjUYxW2VB5t4OlWf1e1Ukst9G7RAbz9NxKnLp760MMk8is0Lp + 2O0zPayEVszWbGnzNflZfMfQju0iwtIFaYw9heTzK/T+iJVGOtMUzskdMIjJOm1IQjOyxYWFmyfctFeQ + b26TnQX8mhTyzaGETtT/R8DPdf3IIt1vydHHZH8xPQ9zuJAc8lRMNsY47JuND7JMZ4b3Ok/rP06eiZtz + pSh6Rb0ZgH+3pe/eCrdDkgAAAABJRU5ErkJggg== + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAAEnQAABJ0Ad5mH3gAAAI3SURBVDhPrZPNaxpBGMaHfvwNrZe2t/ZW6Kn9B3oJpee2 + 9FpoDukmEbHWKBRDDw1iiCFUhbCINArRJGBjKUtBBKMs+IHFGKNbxa/UVKqRukbdp7M6PYT2kEMeGHZ2 + dn7Ps++8DLlQmc1fr4RC5WeBwMEnQSi2wuGiIgg5ZXs70XK5vgRXVoJPfT7fZbb9rPb3cScSaaYqld/4 + n7pdQBRrcDi2kl6vcJthE0WjvVt7ez+P2F4oCtCTRyAP1kHur6PVAo6PgVoNqFYBl8vfsNn4GwwnJBgs + bQ6HE1h9/p1/jh+NBwZAowGUy8DhISBJgMn03sdwQiKRRl8FRiNAloF+jya2T5GWOrDuSBjSqioVoFgE + stnJ3G73yAwnJB6n9lR9anNyQk0o8Hz1ANemY7g5Gwfoe6kE5PNAJjMxWlvzKgwnZHf3W0Wtu9MB2m16 + YNREFXmZAplO0gUKFSbpqRRQrwNarTnJcELcbpHL53+N/0A16dHRbCsgr8sghjKkugKJ1q6mqwfp8YQU + nW5hiuFq/82X/P4Mn802xyYDmvh46xQah4zrjh6mfH0UaHouB8RiRczP698x9KwCgfQLnheq0UgBP77L + GNDWddXW0fQ0rUQ9A6fTO7JYLBqG/CtRFK/SPj9cXnabFhftH+bmFj5ubISRSACFwpCmG4Js6/nEcQYN + z++MW7e05JSNRuNd9ul8MpnevqL3ATabq6/Xv3nCls8nq3X1kVarq8zMzG5yHHePLV+kCPkDsM7o3DIQ + mQoAAAAASUVORK5CYII= + + + + + AAABAAEAgIAAAAEAIAAoCAEAFgAAACgAAACAAAAAAAEAAAEAIAAAAAAAAAABABMLAAATCwAAAAAAAAAA + AAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAIAAAADAAAAAwAA + AAQAAAAEAAAABAAAAAMAAAADAAAAAgAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAEAAAABAAAAAgAAAAQAAAAFAAAACAAAAAkAAAAKAAAACwAAAAsAAAALAAAACgAAAAkAAAAHAAAABQAA + AAMAAAACAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAACAAAAAwAAAAUAAAAIAAAADAAAAA4AAAASAAAAFQAA + ABgAAAAaAAAAGgAAABoAAAAXAAAAFQAAABEAAAAOAAAACgAAAAcAAAAFAAAAAgAAAAEAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABAAAABAAA + AAYAAAAKAAAADgAAABQAAAAZAAAAHQAAACIAAAAmAAAAKgAAAC0AAAAuAAAALgAAACwAAAAoAAAAJAAA + AB4AAAAXAAAAEgAAAA0AAAAJAAAABQAAAAIAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAABAAAAAgAAAAUAAAAJAAAADwAAABQAAAAYAAAAGgAAACUAAQE3AQEBRAEB + AU0BAQFQAAEBTAAAAEYAAAA+AAAAPQAAAD0AAAA6AAAAMwAAACsAAAAjAAAAGwAAABMAAAANAAAACQAA + AAUAAAACAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAQAAAAIAAAADQAA + ABIAAAATAAAAIRAREUkuLi6DTk1NsHBsbNN9eHjqhoGB9oN+fvN3c3PiYV9fzD08PK0fHx+EAAEBXAAA + AEoAAABGAAAAQgAAADkAAAAvAAAAJAAAABsAAAASAAAACwAAAAcAAAADAAAAAgAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAQAAAAIAAAAFAAAACwAAAA8AAAAPAgICJicoKG1cWlq9iYOD9qaenv+zqan/taqq/7es + rP+4ra3/ua2t/7itrf+3rq7/tKur/56YmP93c3PpPT09sg4ODnUAAABRAAAASwAAAEUAAAA6AAAALQAA + ACEAAAAXAAAADwAAAAgAAAAEAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAADAAAABwAAAAwAAAAMAQEBGygo + KG1oZmbUnpaW/7OoqP+2qqr/sqam/7asrP+/trb/x8C//83Gxf/LxMP/x7++/7+1tf+4ra3/uq+v/72y + sv+0q6v/jIeH90ZFRb0MDAx1AAAAUwAAAE4AAABDAAAANQAAACgAAAAcAAAAEgAAAAsAAAAGAAAAAwAA + AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAABAAAABAAAAAgAAAALAAAADBscHEtgXl7DnZWV/7Spqf+zqKj/s6io/8S8vP/Y0tH/2dLN/8nC + vf+zqqv/p5ye/6qfof+5sK//0MnD/9rU0f/Tzc3/wbi4/7mvr/+/tbX/t6+v/4WBgfQ2NjatAgICZQAA + AFIAAABLAAAAPQAAAC4AAAAhAAAAFQAAAAwAAAAHAAAAAwAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAQAAAAJAAAACQYHBxs/Pz+KioaG9rKo + qP+zp6f/s6en/8vEw//g29f/xr67/5KGj/9uY3//YVeD/2Zelf9qZJ7/aGKc/2BYjP9hV33/eGp8/6OX + mP/TzMf/3tnX/8W9vf+7sbH/wrm5/62np/9mZWXeFBQUhAAAAFcAAABRAAAAQwAAADMAAAAlAAAAGAAA + AA8AAAAIAAAAAwAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAEAAAAFAAAACQAAAAYTFBQ1Y2JiwaScnP+1qqr/sKSk/8O6uv/i3Nr/xby5/4B0hf9gWIf/bGqw/4KC + z/+Ki93/kJHh/5CR4f+QkeP/jY/k/4aI3f96ecj/YVub/2FVdv+Wio7/1c7J/9vW1f/AuLj/wLe3/8C4 + uP+Nior5Li4uqAAAAF4AAABUAAAASAAAADgAAAAoAAAAGgAAAA8AAAAIAAAAAwAAAAEAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAABQAAAAkAAAAGHyAgVXp3d+ewpqb/s6io/7Wq + qv/a1dP/1s/K/4h8iP9dVYn/dHO+/4qL2/+Oj97/jIzc/4yM2/+MjNz/jIzc/4uM3f+Ljd//jI3g/42O + 5P+PkOj/hYXb/2Zhpf9dUHH/opWV/+Ld2v/Qysr/vrW1/8a9vf+ooqL/SEhIxwICAmkAAABWAAAASwAA + ADsAAAAqAAAAHAAAABAAAAAIAAAAAwAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAA + AAUAAAAHAAAACTc4OHSOiYn4tqur/7Glpf/BuLj/5eDd/7KoqP9hV37/ZGOv/3x+1P+Agtb/f4DU/4CA + 1f+Bgdf/goLZ/4WF2v+Ghtv/h4jd/4mJ3v+KiuD/i4vh/4uL4f+NjeP/kJHo/4KE2f9dVpH/cGJ0/8zD + v//f29r/wrm5/8e9vf+4sbH/YF9f2gsLC3cAAABWAAAATgAAADwAAAArAAAAHAAAABAAAAAIAAAAAwAA + AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAEAAAABgAAAAxBQUGJmZOT/7arq/+wpKT/zcbG/+Pe + 2P+Kfoz/U02O/2hpxf9zdNH/cXLO/3Fyz/9zdND/dHTS/3Z11P93d9X/eHjX/3t72P99fdv/f3/c/4CA + 3f+Dg+D/hobg/4iH4P+JieH/jI7l/46Q6P9wb7z/V0tw/6mdnP/n4t//ycHB/8a9vf/Curr/cW9v5g4O + Dn8AAABYAAAATwAAAD0AAAAsAAAAHAAAABAAAAAIAAAABAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAABQAA + AAUAAAAMR0ZGmp+YmP+3q6v/saam/9jS0f/X0Mv/bmOB/05MoP9jZcn/ZWbJ/2RlyP9lZsr/ZmfL/2do + zv9pac//amrR/2tr0v9ubtX/cHDX/3Jy2P90dNn/dXXb/3h43f97e93/fX3e/4CB3/+Dg+D/hofi/42O + 6f+Cg9n/Vk2C/4t+hP/k4Nz/0MrK/8W8vP/Gvr7/fXt77xISEoYAAABYAAAAUAAAAD4AAAArAAAAGwAA + AA8AAAAIAAAAAwAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAQAAAAFAAAAC0hHR5qmnp7/t6ur/7Opqf/g29n/y8K+/1xT + fv9JSaz/WlvE/1hZwv9YWcP/WFnF/1pbxv9bXMn/W1zK/11czP9eXs7/YGDQ/2Fh0f9kZNT/ZWXV/2ho + 1/9qatn/bW3Z/29v2v9yctz/dXXd/3h43f97fN//f4Dg/4WH5f+GiOT/W1aX/3dodP/e2dT/1tDQ/8a9 + vv/Mw8P/gX5+7xESEoYAAABYAAAATwAAADwAAAArAAAAGgAAAA8AAAAHAAAAAwAAAAEAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAABQAA + AAtISEiZpp6e/7esrP+zqar/497b/8K5tf9PR3//QUOv/01Pvv9MTbz/S02+/0xNv/9NTsL/Tk/E/09Q + xv9QUMf/UVHJ/1NTy/9UVM3/V1bQ/1lZ0f9aWtP/XFzV/19f1v9hYdf/ZGTY/2dn2f9qatn/bW7b/3Bx + 3P9zdd3/d3nf/3x+4v+Chuj/Xlyn/2tcbP/b1M//2tTU/8i/v//NxcX/gX9/7xISEoYAAABYAAAATgAA + ADsAAAApAAAAGQAAAA0AAAAGAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAABAAAAAwAAAAUAAAAFQ0NDj6Sdnf+4rKz/tKqq/+Pf3P++trb/RD2A/zo7 + rf9BQ7f/QUK2/0FBuP9AQbv/QUG8/0JDvv9DQ8D/REPC/0VExf9GRsf/R0fJ/0lJy/9KSsz/TU3P/05O + 0f9RUdP/U1PT/1ZW1P9ZWNX/W1vW/15f2P9hY9j/ZWba/2lq2/9sbt3/cHLe/3V34f99gej/XVyu/2BR + av/UzMf/29bW/8nBwf/Oxsb/e3l57QwMDH0AAABYAAAATQAAADkAAAAmAAAAFwAAAAwAAAAFAAAAAgAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAFAAAAAkA/ + P3ufmJj/uK2t/7Sqqv/k393/wbm4/0A7gv8tMKr/Njey/zU2sf81NrL/NTW1/zU1tv82Nrn/Nja7/zg4 + vf84OL//OjrB/zs7xP88PMb/PT7J/0A/yv9CQsz/Q0PP/0VF0P9ISND/S0rR/01N0/9RUdT/VFXV/1ZY + 1v9aXNj/XWDZ/2Fk2/9maN3/aWzd/25y4P91euj/XF20/19Qaf/Vzsj/29fX/8vDw//LxMT/cnBw5QkK + CnYAAABXAAAASgAAADYAAAAkAAAAFQAAAAsAAAAEAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAEAAAACAAAABQAAAAA2NjZjl5KS/biurv+0qqr/49/c/8W9uv88NoD/IyWk/ysr + q/8qKqv/Kiqt/ykqsP8pKrL/Kiq0/yortf8rK7j/LCy6/y0tvf8uLr7/MDDB/zAxw/8xMsX/NDPI/zU1 + y/84OMz/OjrN/z09zv8/QM//QkLQ/0VF0f9IStL/S07U/05R1f9SVdf/V1na/1te2/9fYtz/Y2fe/2ds + 4f9wduj/VVey/19Raf/e2NH/29bW/87Hx//Jw8P/YmBg2gMEBG0AAABWAAAARwAAADIAAAAhAAAAEwAA + AAkAAAAEAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAUAAAAAIiIiSY2J + ifG5r6//s6mp/97Z1//QyMX/Qjt8/xcZnP8fIKX/HyCl/x4fqP8eH6r/Hh+s/x4frf8eH7D/Hh+y/x8h + tP8gIbf/IiG5/yMjvP8jJL7/JCXB/ycnwv8pKcX/KirJ/ywsyf8vL8n/MTLL/zQ1zP83OM3/OzvO/z0/ + 0P9AQ9L/REfU/0hL1f9LT9b/T1TZ/1RZ2/9YXt3/XGPf/2Fo4v9ocOn/T1Cq/2pbbP/h3Nf/2tTU/9HK + yv/Dvr7/Tk5OyAAAAGMAAABUAAAAQwAAAC8AAAAeAAAAEAAAAAcAAAADAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAEAAAADAAAAABQVFSt8eXniua+v/7Opqf/Y0tH/3NXP/0lCf/8MDpX/FBWf/xMU + n/8TFKH/ExSk/xMUpv8SE6f/EhOq/xITrP8SE6//FBSx/xQUtP8VFbb/Fxe5/xcYu/8YGb7/GxvB/x0c + w/8eHsX/ISHG/yMjx/8mJ8j/KSrJ/ywty/8vMMz/MjTO/zY40P85PNH/PEHU/0BG1v9FStj/Sk/Z/05U + 3P9TWd7/Vl7g/1xk5P9jbev/SEih/3Zncv/n49//1tHR/9XOzv+4tLT/OTk5tAAAAF0AAABSAAAAPwAA + ACsAAAAaAAAADgAAAAYAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAELCwsSamhoxras + rP+1qqr/z8jH/+nj3P9cU4T/BQeM/wsNmv8MDZr/DA2d/wwNn/8MDaH/DA2j/wsMpf8LDKj/Cwyr/wsM + rf8LC6//Cwuy/wwMtP8MDbf/DA25/w0Ou/8PD77/ERHA/xMTw/8VFcP/FxjE/xobxv8dHsf/ISLI/yQm + yv8nKcz/Ky3N/y8z0P8yN9L/NjvU/zpA1v8/Rdn/REvb/0hQ3f9NVeD/UVvi/1hh5v9daOn/QT+S/4h5 + fv/s6eX/083N/9jR0f+ppaX/IyMjnAAAAFgAAABPAAAAOgAAACcAAAAXAAAACwAAAAUAAAABAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAIAAAADAAAAA0tKSpuupaX/uK2t/8S8vP/w7OT/d26P/wgJh/8LDZf/DQ+Z/w0O + m/8NDp3/DQ6g/w0Oov8NDqT/DA2n/wwNqf8MDar/DA2t/wwNr/8MDLL/Cwu1/wsLtv8KC7n/Cgu7/woK + vf8KCr//CgrA/wsLwP8MDcH/DxDD/xITxP8WF8X/GBvI/xwfyv8gIsv/JCjO/ygt0P8rMdL/LzfU/zQ8 + 1/85Qdr/PUfc/0JN3v9HUuH/TVjj/1Nf6v9UYeb/Pjl//6GTkf/v6+r/08zM/9rT0/+MiorzDxAQgwAA + AFcAAABKAAAANQAAACIAAAATAAAACQAAAAMAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAABAAAAAA8PT1uoZub/7uw + sP+9s7P/8u3o/5iQof8QEIL/CQyV/w0Pl/8ND5n/DQ6c/w0Onv8OD6H/Dg+j/w0Opf8NDqj/DQ6p/wwN + rP8MDa7/DA2x/wwMs/8MDLX/DAy3/wsMuv8LC73/Cwu//wsLwf8LC8H/CgrB/woLwf8KC8H/CwzD/wwN + w/8NEMX/EBTH/xUZyv8ZHcv/HSLO/yEo0f8kLdP/KTLW/y442P8zPtv/OUPe/z1K4f9CUOP/SFXm/09e + 7f9MWd3/Qjhv/7uxrf/q5+b/1M3N/9XQ0P9tbGzgAwQEbQAAAFQAAABEAAAALwAAAB0AAAAPAAAABwAA + AAIAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAMAAAAAISIiO46JifC9srL/t66u/+rm4v+6srf/IB1//wgKk/8OEJb/DhCY/w4Q + mv8OD5z/Dg+e/w4PoP8OD6P/Dg+m/w0OqP8NDqv/DQ6t/w0OsP8NDbH/DQ2z/w0Ntv8MDbj/Cw27/wwM + vf8MDMD/CwvB/wsLwf8LDML/CwzC/wsNwv8MDcL/Cw3D/wsOxf8LD8b/DBHI/w4Uyf8SGMz/Fh3P/xsi + 0f8fKdX/Iy/Y/yg02/8uO93/NEHh/zhH5P89Tub/RFTp/0te8/9CTs//T0Fm/9bOx//k4OD/2NLS/8nF + xf9HR0fCAAAAXwAAAFIAAAA/AAAAKgAAABkAAAAMAAAABQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAA8QEBRwbm7Mua+v/7es + rf/b1tX/29TQ/zs2gP8GCI//DxCU/w4Qlv8OEJj/DxCb/w8Qnf8PEJ//DxCi/w8QpP8OD6b/Dg+p/w4P + q/8OD63/Dg+w/w4Osf8NDbT/DQ22/wwNuf8MDbv/DAy9/wwMwP8MDMH/DAzB/wwNwv8MDcL/DA3C/wwN + w/8MD8T/DBDF/w0Rx/8NEcj/DBLK/w0Uy/8NFc7/ERnR/xUf0/8aJtf/Hiva/yQy3f8pOOD/Lz/j/zRG + 5/85TOn/QFPt/0dd9v84QLP/aFhr/+jj3v/d2Nj/3dfX/7Ovr/8nJyefAAAAVwAAAE4AAAA4AAAAJAAA + ABUAAAAKAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAMpKSkATExMlbCnp/+6sLD/y8XE/+/r4/9iW4z/BwmK/w8Qkv8PEZP/DxGW/w8R + mf8PEZv/DxCe/w8QoP8PEKP/DxCk/w4Ppv8OD6n/Dg+r/w4Prf8OD7D/Dg6z/w4Otf8ODrf/DQ65/w0N + u/8MDL7/DQ3A/w0Nwf8MDMH/DAzC/wwNw/8NDsP/DQ7E/w0Pxf8NEMb/DRHI/w0Syf8NFMr/DhXN/w4W + zv8OF9H/DhnT/xAd1v8UItn/GSnc/x4v4P8lN+P/Kz7m/zBF6v82S+7/PFPy/0FZ9/8yNJP/i3yA//Dt + 6v/a1NT/4NnZ/4yKivINDQ1+AAAAVgAAAEcAAAAxAAAAHwAAABEAAAAHAAAAAgAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAACkpKVGclpb/vbOz/761 + tf/08ev/koui/w4PhP8ND5D/EBGR/w8RlP8PEpf/EBKZ/xARm/8QEJ3/DxCg/w8Qo/8PEKX/Dg+n/w4P + qv8OD6v/Dg+u/w8PsP8PD7P/Dw+1/w4PuP8NDrr/DQ27/w0Nvv8NDcH/DQ3B/w0Nwf8NDcL/DA3C/w0P + xP8ND8T/DRDG/w0Rx/8OEsj/DhPJ/w4Vyv8OFs3/DxbQ/w8Z0f8PGtT/DxvW/w8e2P8RIdz/FSff/xou + 4/8gNef/Jz3q/y1E7v8yS/H/OVX5/zpS7/83MHT/t6um/+7r6v/b1dX/2NPT/19fX9UAAABkAAAAUwAA + AEAAAAArAAAAGQAAAA0AAAAFAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAgAAAAATExMeenh42b60tP+5r6//6OTh/8W+wv8jIYH/Cg2N/xETkP8REpP/EBKV/xAS + mP8QEpn/EBKb/xARnv8QEaD/EBGj/xARpf8PEKf/DxCq/w8QrP8PEK7/DxCx/w8Ps/8PD7b/Dw+4/w4P + uv8OD73/Dg6//w0Nwf8ODsH/Dg7B/w0Owv8NDsL/Dg/E/w4QxP8OEcb/DhLH/w4TyP8OFMn/DxXM/w8W + zv8QF8//EBnS/xAb1f8QHtf/ESDZ/xEh3P8RI9//Eifj/xct5v8cNOr/Izzu/ylE8v8wTPX/N1b//zBD + 1P9OQGb/29PM/+bj4//h29v/wL29/zExMasAAABZAAAATgAAADgAAAAkAAAAFAAAAAkAAAADAAAAAQAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAACKisrAFBPT5y1rq7/u7Cw/9PO + zf/q5d//S0WI/wcJif8RE47/EROQ/xESkv8RE5X/EROY/xETmv8QEZz/ERGf/xESoP8REqP/ERKl/xAR + qP8QEar/EBGs/xARr/8QELH/Dw+z/xAPtf8QELj/DxC7/w4Pvf8ODr//Dg7B/w4Owf8ODsH/Dg/C/w4P + wv8PD8T/DxDE/w4Rxv8OEsf/DxPJ/w8Vy/8PFsz/EBbN/w8Y0P8QGtL/ER3V/xEf2P8RINr/EiPc/xIl + 4P8SJ+P/Eyrn/xQt6/8YNO7/Hzzy/yZE9/8tS/r/MlL//ycxq/91ZXH/7+vn/9/b2//k39//lpOT9Q4O + DoEAAABVAAAARwAAADEAAAAeAAAAEAAAAAcAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAwAAAAAqKytRoJqa/7+1tf/Cubn/9/Tu/4N8nv8JC4X/EBKN/xIUjv8SFJH/EhOS/xET + lf8RE5j/EROa/xESnf8REp//ERKh/xESo/8REqX/EBGo/xARqv8QEaz/EBGv/xARsf8QELP/EBC1/xAQ + uP8PELv/DxC9/w8PwP8PD8L/Dg7C/w8Pwv8PD8L/Dg/C/w8QxP8PEcT/DxLG/w8Tx/8QFMn/DxXL/w8W + zP8QF83/EBnQ/xEb0v8RHNX/ER7Y/xIh2/8SJN3/EyXg/xMo4/8UK+f/FC7r/xQw7/8XNPP/HDz3/yND + +f8pSfz/LEn2/yspgv+qnZr/8vDv/9/a2v/d2Nj/YWBg1wAAAGMAAABSAAAAPwAAACkAAAAYAAAADAAA + AAQAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAEBERFnh1ddS/tbX/u7Gx/+vo + 5f/Cu8L/HRuE/w0Pjf8SFIz/EhSO/xIUkP8TFJP/EhSW/xETmP8RE5r/EhOd/xITn/8SE6L/EhOk/xIT + pv8REqj/ERKq/xESrP8REq//ERKy/xERtP8QELb/EBC4/xARuv8QEL3/EA/A/w8Pwv8PD8L/Dw/D/w8Q + w/8PEMP/DxHD/xASxP8PEsb/DxPH/xAUyf8QFsr/ERfN/xEYzv8QGc//ERzS/xIe1f8SINj/EiHb/xIk + 3f8UJuD/FCnj/xQr5/8VLuv/FTHv/xYz8v8WNvb/GTv4/x9A+f8mSP//Ijrd/0I2Z//Y0Mj/6+jo/+Xg + 4P/Cvr7/LS0tpQAAAFgAAABMAAAANgAAACIAAAATAAAACAAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAiIjIwBKSUmKs6ur/72zs//Uzs7/7Ojj/0pFi/8IC43/EhWN/xIUjP8TFY7/ExWR/xMU + lP8SFJb/EhSY/xIUmv8SE53/EhOf/xITof8TFKT/ExSm/xITqP8SE6v/EhOs/xESr/8RErL/ERG0/xER + tv8REbj/EBG6/xARvf8QEL//EBDC/xAQwv8QEML/EBHD/w8Qw/8PEcP/EBLE/xATxv8QFMf/ERXJ/xAV + yv8QF83/ERjP/xIZ0P8SHNL/Eh7V/xIg1/8TIdv/EyTd/xQn4P8UKeP/FSvn/xUu6v8WMO7/FjPy/xY2 + 9f8XOPj/Fzn4/xw++f8iRf//HCeu/3Zmcv/w7un/49/g/+jk5P+OjIzxCQoKeQAAAFQAAABEAAAALgAA + ABsAAAANAAAABgAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAIiMjOZWRkffCuLj/wbm5//bz + 7f+Oh6T/DQ6J/xEUkf8TFY3/ExWM/xMVjv8UFpH/ExSU/xIUlv8TFZn/ExWb/xMVnf8TFJ//ExSh/xMU + o/8TFKb/EhOp/xITq/8SE63/EhOu/xITsf8SErT/EhK2/xESuP8QEbv/ERG9/xERv/8QEML/EBDC/xAQ + wv8QEcP/EBHE/xESxP8RE8X/EBPG/xAUx/8RFcj/ERbL/xIXzf8SGM//ERnQ/xIc0f8THtT/EyDX/xMh + 2v8TJN3/FCfg/xUo4/8VK+b/Fi3p/xYv7f8WM/H/Fjb0/xc4+P8XOPj/Fzj4/xo8+/8cO/T/JyR9/7Kl + n//z8fD/5eDg/9vX1/9PTk7FAAAAXQAAAFAAAAA7AAAAJgAAABQAAAAJAAAAAwAAAAEAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAABAAAAAQMDAwVmZma5vbS0/72zs//l4d//z8jK/yYkh/8ND5P/FBaR/xQWjv8UFo3/FBaP/xQW + kf8UFZP/ExWW/xMVmP8TFZv/FBWd/xQVn/8UFaL/FBWj/xQVpv8TFKn/ExSr/xMUrf8TFK//ExSx/xMT + s/8SErb/EhK5/xESu/8REr3/ERG//xERwf8REcL/EBDC/xERw/8REsT/EBLE/xESxf8RFMf/ERXH/xIV + yP8SF8r/ERfL/xIYzv8SGtD/ExzR/xMd1P8TINf/FCLZ/xQj3P8UJt//FSji/xUq5P8WLOj/Fi/r/xYx + 7/8WNPL/Fzf1/xc5+P8XOfj/Fzj4/xg8//8TKtP/TT9n/+Lb1P/r6Oj/7Ofn/7Gvr/8ZGRmQAAAAVQAA + AEgAAAAxAAAAHgAAAA8AAAAGAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAOTk5XqagoP/BuLj/zcbG//Pv + 6P9gWpP/CAuR/xMVlP8UFpH/FBaO/xQWjf8VF4//FBaR/xQVlP8UFpb/FBaY/xQWm/8UFp3/FBWg/xQV + ov8UFaP/FBWm/xMUqP8TFKv/ExSt/xMUr/8TFLL/ExOz/xMTtv8TE7j/EhO7/xESvf8REb//EhLB/xIS + wv8REcL/ERLD/xESw/8REsT/EhPF/xIUxv8RFMf/ERbI/xIXyf8SF8z/ExnO/xIaz/8TG9L/Ex7U/xQg + 1v8UItj/FCTb/xQl3v8VKOH/FSrj/xYs5v8WLur/FjDt/xYy8P8XNfP/Fzf1/xc5+P8XOfj/Fzj5/xU4 + /v8UHZ3/i3yA//b08f/n4+P/6OTk/29ubtwAAABnAAAAUgAAAD8AAAApAAAAFwAAAAoAAAAEAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAABAAAAABISEhR+e3vTw7q6/7+3t//w7Oj/q6S1/xUViv8QEpj/FRaU/xUXkf8VF4//FReM/xUX + j/8VF5H/FRaU/xQWlv8UF5j/FReb/xUWnP8VFZ//FBWi/xQVo/8UFab/FBWo/xMUqv8TFK3/ExSv/xMU + sv8UFLT/FBS1/xQUuP8SE7r/EhO9/xISv/8SEsH/EhLC/xISwv8SE8L/EhPD/xESxP8SFMX/EhTG/xIV + x/8SFsj/EhfK/xIXy/8TGcz/ExrO/xMc0f8THdT/FB/U/xQi1/8UI9r/FSXd/xUo4P8WKeL/Firl/xYt + 6P8WL+r/FjHt/xYz8P8WNPP/Fjb0/xc39f8XN/b/Fjj6/w8s5/8wKGz/zMO7//Lw8P/s6Oj/ycbG/ywr + K6QAAABXAAAASwAAADQAAAAfAAAAEAAAAAcAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEUFRUARkZGe7Krq//BuLj/19HQ/+bh + 3P9DP43/Cw6Y/xQWmP8VFpX/FRaS/xUXj/8WGI3/FReP/xUXkf8WF5T/FheW/xUXmP8VF5v/FRec/xUW + n/8VFqH/FRaj/xUWpv8VFqj/FBWq/xQVrf8UFa//FBWx/xQUtP8UFLb/FBS3/xQUuv8TFLz/EhK//xIS + wf8TE8L/EhLC/xISwv8SE8P/EhPD/xMUxP8TFMb/EhXH/xIWyP8TF8r/ExfL/xMYzP8TGs//FBzR/xQd + 0/8UH9T/FCDW/xUj2f8VJdv/FSfe/xYp4f8WKeP/Fivm/xYu6P8WL+r/FjDt/xYy7/8WM/H/FjTy/xY0 + 8/8WNPP/FTT5/wwatf9sXXD/8e7p/+vn6P/u6ur/iYiI6wQEBHEAAABTAAAAQAAAACsAAAAYAAAACwAA + AAQAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAABAAAAABQVFR+Jhobmxby8/8S8vP/z8Or/kImm/w4Pkf8TFZz/FReY/xUXlf8WF5P/FhiP/xYY + jv8WGI//FhiR/xYXk/8WF5X/FhiY/xYYm/8VF5z/Fhef/xYXof8WF6P/Fhel/xYXqP8VFqv/FRat/xUW + r/8VFrD/FBSz/xQUtv8VFbj/FBW5/xMUvP8TE77/ExPB/xMTw/8TE8P/ExPD/xMUxP8SFMT/EhTE/xMV + xv8TFcb/ExfI/xMXyf8TGMv/ExnM/xQazf8UG8//FB3S/xQf1P8VINb/FSLX/xUj2v8VJtz/Fijf/xYo + 4v8WKeP/Fivl/xYt6P8WLur/FjDs/xYx7f8WMe7/FjHv/xYw7/8WMfH/ECvs/x8dff+3qqX/9/b1/+3p + 6f/Z1dX/PDw8tQAAAFkAAABMAAAANgAAACEAAAARAAAABwAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEWFhYATUxMjLqxsf/CuLj/39rZ/9fR + z/8wLo3/Dg+e/xUXnP8VF5n/FReW/xYXk/8XGJD/FxmO/xcZjv8XGZH/FxiU/xcYlv8WGJf/Fhia/xYY + nf8WF5//Fheh/xYXo/8WF6X/Fhen/xUWqv8VFq3/FRau/xUWsP8VFrL/FRW1/xUVuP8VFbr/FBW7/xQV + vf8UE8D/FBTC/xQUw/8TE8P/ExTE/xMUxP8TFMT/FBXF/xQWxv8TFsf/FBjJ/xQYyv8UGMz/FBnM/xQb + zv8UHdD/FR7T/xUf1f8VIdf/FSLY/xUk2v8WJt3/Fifg/xYo4v8WKeP/Fivl/xYs5v8WLef/Fi7q/xYu + 6v8WLuv/Fi7r/xUu6v8UL/D/CxvC/1dJav/s5uD/8O3t//Lv7/+ZmJjyCgoKeAAAAFMAAABCAAAAKwAA + ABkAAAALAAAABAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAABAAAAABYWFimQjIzxyL6+/8nBwf/08Or/fnig/wwOl/8VFqD/FRec/xYYmv8WGJf/FxiU/xcZ + kf8XGY7/FxmO/xcZkf8YGZT/GBmV/xYYmP8WGJr/Fxmc/xcYnv8XGKD/Fxij/xcYpv8XGKj/Fhep/xYX + rP8WF67/Fhew/xYXsv8VFbT/FRW3/xYWuv8VFrv/FBW8/xQUv/8UFML/FBTD/xQUw/8UFMT/FBXE/xMV + xP8UFcT/FBbG/xQWxv8UF8j/FBjJ/xQYy/8UGcz/FBvN/xQcz/8VHdH/FR/U/xUg1f8VItf/FSPY/xYk + 2v8WJ93/Fiff/xYo4f8WKeL/Firk/xYr5f8WK+b/Fizn/xYr5/8VK+f/FSvn/xQr5/8QJuj/GBmI/6ib + mP/5+Pb/7+zs/+He3v9GRka+AAAAWQAAAEwAAAA2AAAAIQAAABEAAAAHAAAAAgAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEWFhYATk1Nk7y1tf/Durr/49/d/8zF + yf8oJo//EBKj/xYXoP8WF53/Fhia/xYYl/8XGJX/GBmS/xgaj/8YGo7/GBqQ/xgakv8YGZX/FxmY/xcZ + mv8XGZz/Fxie/xcYof8YGaL/GBml/xgZp/8XGKn/Fxis/xcYrf8WF7D/Fhez/xYWtP8WFrX/Fha4/xYW + u/8VFr3/FRW//xUVwf8VFcP/FBTD/xQUw/8UFcT/FBXF/xQWxf8UFsX/FBbG/xQXx/8VGMj/FRnK/xQZ + zP8VGs3/FRzO/xUcz/8VHtL/FR/U/xUh1f8VItf/FSPY/xYl2v8WJtz/Fife/xYo4P8WKOH/Fini/xYp + 4/8WKuP/FSrj/xUq4/8UKeP/FCji/xQo5v8KGcf/Sj5r/+bg2P/z8fH/9fLy/56dnfcLCwt8AAAAUgAA + AEEAAAAqAAAAGAAAAAsAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAABYWFimRjY3xycDA/8vDw//x7eb/dG+d/wwOnP8WF6T/Fheh/xYYnv8XGZv/FxmY/xgZ + lf8YGpP/GBqP/xgajv8ZG5D/GRuT/xgZlf8YGZf/GBqZ/xgam/8YGp7/GBmg/xgZof8YGaT/GBmm/xgZ + qf8XGKv/Fxit/xcYr/8XGLH/Fxi0/xcXtv8WFrf/Fhe6/xUXvP8VFb7/FRW//xUVwv8VFcP/FRXD/xUV + xP8UFcT/FBXF/xUWxf8VF8f/FRjH/xQYx/8VGcn/FRnK/xUazP8VG87/FRzO/xUd0P8VHtL/FR/U/xYh + 1f8WItf/FSPY/xYk2f8WJdv/Fibd/xYn3v8WJ9//FSjg/xUo4P8VKOD/FSjh/xQm4P8TJuD/EyXf/w8i + 4v8UFYz/oJOU//z6+P/y7+//4+Dg/0ZGRr8AAABZAAAASwAAADUAAAAgAAAAEAAAAAcAAAABAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wAVFRUAFRUVABUVFQAVFRUAFRUVABUVFQAVFRUATk1Nkr22tv/FvLz/497c/8rD + xv8pKJP/EBKn/xcYpP8XGKH/Fxie/xcZm/8XGZn/GBmX/xkalP8ZG5H/GRuO/xkbkP8ZG5P/GRqV/xka + lv8YGpn/GRuc/xkanv8ZGZ//GRqi/xkapP8ZGqb/GBmp/xcYq/8YGa3/GBmu/xgZsf8XGLP/Fxe2/xcX + t/8XF7j/Fxe7/xYXvv8WFcD/FhbC/xYWw/8VFcP/FRXE/xUWxP8VFsT/FRbF/xUXxv8VGMf/FRjH/xUZ + yP8VGcr/FRnL/xUbzf8VG87/FRzO/xUd0P8WH9L/FSDU/xYh1f8WIdf/FSPX/xYk2f8WJNr/FSTb/xUl + 3P8VJtz/FSbe/xQm3v8UJt7/FCXe/xMj3f8SI9z/EiPf/wkWxv9KP27/5uHZ//b09P/49vb/n56e9wsL + C3sAAABRAAAAQAAAACkAAAAWAAAACgAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////ABUVFQAVFRUAFRUVABUV + FQAVFRUAFRUVABUVFSCRjY3rysHB/8zFxf/x7eb/dnGf/w0OoP8WF6n/Fxil/xcYov8XGJ//GBqd/xga + mv8YGpf/GRqV/xkbkv8ZG4//GhuP/xobkv8aG5T/GhuW/xkbmf8ZG5v/GRuc/xkbn/8ZGqL/GRqk/xka + pv8ZGqf/GBmq/xgZrf8YGa//GBmw/xgZsf8YGLT/GBi3/xgYuf8XGLv/Fhe8/xYWv/8WFsL/FhbD/xYW + w/8WFsP/FhbE/xUWxP8VF8X/FhfF/xYYx/8VGMf/FRnH/xUZyf8WGcr/FRrL/xUbzf8WHM7/FRzP/xUe + 0P8WH9H/FSDT/xUh1f8WIdb/FSHX/xUi1/8VI9n/FSPZ/xUk2f8VJNv/FCTa/xQj2v8UItr/EyLa/xMh + 2v8SINn/Dh3d/xUVjv+hlJX//fz6//Xy8v/k4uL/QEBAtwAAAFgAAABKAAAAMwAAAB0AAAAOAAAABQAA + AAEAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8AERISABESEgAREhIAERISABESEgAREhIASEhIfLu0tP/Gvr7/497d/83G + yP8rKZT/ERKr/xYYqP8XGab/GBmj/xgZoP8YGp7/GBqb/xgbmP8aG5b/GhuS/xobkP8aG4//GhuR/xob + lP8aG5b/GhyZ/xocm/8aHJ3/GRue/xkaof8ZGqP/GRql/xkaqP8ZGqn/GBmr/xgZrv8ZGrD/GRqx/xgZ + s/8YGLb/GBi5/xgYuv8XGLv/Fxe9/xcWwP8XF8L/FhbD/xYWw/8WFsP/FhfE/xYXxf8WF8X/FhjG/xYY + x/8WGcf/FRnI/xYZyf8WGsr/FRrL/xUbzf8WHM7/FRzP/xUe0P8WHtD/Fh/T/xUg1P8VINX/FSHW/xUh + 1v8VItf/FSLX/xQi1/8UIdj/EyDY/xMg2P8TINf/Eh/X/xIe1v8RHdn/CBK//01Bbf/o4tr/9/b2//r4 + +P+Uk5PvBAQEcQAAAFAAAAA8AAAAJQAAABQAAAAIAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAA////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wAREhIAERISABES + EgAREhIAERISABESEhCFgoLbysLC/8zExP/w6+X/gXuj/w4Qof8WF63/Fxmp/xgZpv8YGaT/GRmh/xka + nv8ZG5z/GRua/xobl/8aG5T/GxyR/xsckP8aG5H/GxyU/xsclf8bHJj/Ghya/xocnf8aHJ7/Ghug/xob + o/8aG6X/Ghuo/xobqf8ZGqr/GRqt/xkar/8ZGrL/GRqz/xkZtf8YGLf/GBi5/xgZu/8XGLz/Fxe+/xcX + wf8XF8P/FxfE/xcWw/8WFsP/FhfE/xYXxP8WF8X/FhjG/xYYx/8WGcj/FhnI/xYZyf8WGcr/FRrL/xUb + zf8WG87/Fh3O/xUdz/8VHtD/FR7R/xUf0v8VH9P/FR/U/xUf1f8UH9X/FCDV/xQg1f8UH9X/Ex/V/xIe + 1P8SHdT/EhzT/xEb0/8MF9b/GReH/6ygnf/+/Pv/+ff3/9vY2P8wMDCnAAAAUwAAAEUAAAAuAAAAGgAA + AAwAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AAIDAwACAwMAAgMDAAIDAwACAwMAMzMzW7Ourv/KwcH/3trZ/9fR + z/82NJb/EBKv/xcYrP8XGKr/GBqo/xkapf8ZGqL/GRqf/xkbnP8aHJr/GhyX/xsclf8bHJP/GxyQ/xsc + kf8bHJT/HB2W/xsdmP8aHJr/Gh2b/xsdnv8bHKD/Gxyi/xscpP8bHKX/Gxyo/xobq/8ZGqz/GRqu/xob + sf8aG7L/GRq0/xkZtv8ZGbj/GRm7/xgZvP8YGb7/GBe//xcXwv8XF8T/FxfE/xcXxP8XF8T/FhfE/xYY + xP8XGMX/FxjG/xYZx/8WGcj/FhnJ/xYZyf8WGcr/FhrL/xUbzP8WG87/FhzO/xYdz/8VHc//FR3P/xUd + 0f8VHdL/FR7S/xQe0/8UHtP/FB7T/xMe0/8THdP/ExzS/xIc0f8SGtH/EBrQ/xAZ1P8HDrT/XFBz//Ht + 5//59/f/+vj4/3x7e98AAABkAAAATQAAADcAAAAhAAAAEAAAAAcAAAACAAAAAAAAAAAAAAAAAAAAAP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAgMDAAID + AwACAwMAAgMDAAIDAwFvbW25ycLC/8vDw//u6+X/l5Cr/xMUov8WF7L/GBmt/xgZq/8YGqj/GRqm/xoa + o/8aG6D/Ghye/xocm/8aHJn/GxyW/xwdk/8cHZD/HB2Q/xwdkv8cHZX/HB2Y/xwdmf8bHZv/Gx2d/xsd + oP8bHKL/Gxyk/xscpv8bHKj/Gxyp/xobrP8aG63/Ghuv/xobsv8aG7T/Ghq2/xoat/8aGrn/GRq8/xgZ + vf8YGb7/GBjB/xgYw/8YGMT/FxfE/xcXxP8XGMX/FxjF/xYXxf8XGMX/FxnG/xcZx/8WGcj/FhrJ/xYa + yf8WGcn/FhrK/xUbzP8VG83/FhvN/xUczv8VHM//FRzP/xUcz/8UHND/FBzQ/xQc0P8THNH/ExzR/xMb + 0f8TG9H/ERrQ/xEZz/8RGM7/EBfO/woSzv8jHnz/vrSu//79/P/7+Pj/xcTE/x4eHpEAAABQAAAAPwAA + ACgAAAAVAAAACQAAAAMAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wAmJycAJicnACYnJwAmJycAJicnM6KenvrNxsb/2NPS/+Tf + 2f9OS5r/Dg+v/xgZsv8YGa//GBms/xkaqf8aG6f/Ghuk/xobof8aHJ//Gx2c/xsdmf8cHZf/HB2V/xwd + kv8cHZD/HR6R/x0elP8dHpb/HR6Z/xwem/8cHp3/HB6f/xwdoP8cHaP/HB2l/xwdp/8cHan/Gxyq/xsc + rf8bHK//Gxyx/xscs/8aG7X/Ghq2/xoauP8aGrn/GRq8/xkavv8ZGMD/GBjB/xgYw/8YGMT/GBjE/xcX + xf8XGMX/FxjF/xcYxf8XGMX/FxnG/xcZx/8WGcj/FhrJ/xYayf8WGcn/FhnK/xYay/8VGsz/FRvN/xUb + zf8VG83/FRvO/xQbzv8UG87/FBvO/xMbzv8TGs7/ExrO/xIZz/8SGM7/ERfO/xEWzf8QFsz/DhbQ/woN + pv96bn//+fby//bz8//v7e3/WFhYyAAAAFgAAABGAAAAMAAAABsAAAANAAAABQAAAAEAAAAAAAAAAAAA + AAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAME + BAADBAQAAwQEAAMEBABLS0uGwru7/8vDw//o5OH/tq+6/x4en/8VFrf/GBmy/xkasP8ZGq3/GRuq/xkb + qP8bHKX/Gxyi/xscoP8bHZ7/Gx2b/xwemP8dHpb/HR6U/x0ekP8dHpH/HR6U/x0elv8dHpf/HB6a/xwe + nf8cHp7/HB6f/xwdof8cHaT/HB2n/xwdqP8cHan/Gxyr/xscrv8bHLH/Gxyy/xscs/8bG7b/Gxu3/xsb + uf8aGrr/GRq9/xkav/8ZGMD/GRjB/xgYxP8YGMT/GBjE/xgYxf8XGMX/FxjF/xcYxf8XGMX/FxjG/xcZ + x/8XGcj/FhrI/xYayf8WGcn/FhnJ/xYZyv8WGcr/FRrL/xUazP8UGs3/FBrN/xQazf8UGcz/ExnM/xMY + zP8SGM3/EhjN/xIXy/8RF8z/EBbM/xAWy/8PFcz/CA7F/zgwdP/a08v/+fj3//n29v+enZ31BgYGcQAA + AEsAAAA3AAAAIQAAABAAAAAGAAAAAgAAAAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8AAwQEAAMEBAADBAQAAwQECIJ/f9HPx8f/0crK/+3o + 4f9xbKH/Dg+t/xgYt/8ZGbP/GRqx/xkarv8aG6v/Ghyp/xscpf8bHKT/HByi/xwdn/8cHpz/HB6a/x0e + l/8dHpX/HR6S/x0ekP8dHpP/HR6V/x0el/8dHpn/HB6b/xwenf8cHp//HB2i/xwdo/8cHaX/HB2n/x0e + qf8cHar/Gxyt/xscr/8bHLD/Gxyy/xsctf8bG7f/Gxu5/xsbuv8aG7v/GRu9/xkav/8ZGcD/GRnC/xkZ + xP8YGMT/GBjE/xgYxf8YGMX/FxjF/xcYxf8XGMX/FxjF/xcZx/8XGcf/FhnI/xYZyP8WGcj/FhnI/xYZ + yf8VGcr/FRnK/xUZyv8UGMv/FBjL/xMYy/8TGMv/ExjL/xIXyv8SF8r/ERfK/xEWyf8RFsn/EBTJ/xAU + yf8MEcz/EhGQ/6CVlv/8+/n/9fLy/9bU1P8rKyufAAAATQAAAD8AAAAnAAAAFQAAAAkAAAADAAAAAAAA + AAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wAqKioAKioqACoqKgAqKio+q6am/c/Hx//f2tj/19DO/zg2nf8QErn/GRm3/xkZtP8aG7L/Ghuv/xob + rP8aHKr/Gx2n/xwdpf8cHaL/HB6f/xwenv8cHpv/HR6Y/x0elv8dHpP/Hh6R/x4fkv8eH5T/Hh+W/x4e + mf8eHpv/HR6c/x0en/8dHqH/HR6j/x0epf8eH6f/Hh+o/x0eqv8cHaz/HB2t/xwdsP8bHLL/Gxyz/xsc + tP8bG7b/Gxu5/xsbuv8bG7v/Ghu+/xoav/8ZGcD/GRnC/xkZxP8ZGcT/GBjE/xgYxf8YGMX/FxjF/xcY + xf8XGMX/FxjF/xcZxv8XGcf/FhnH/xYZyP8WGcj/FRnI/xUZyP8VGcn/FRnJ/xUZyf8UGMn/FBjK/xMX + yv8TF8r/ExfJ/xIXyP8SFsj/ERXI/xEVyP8QFMj/DxPH/w4Syv8HCrH/X1V5//Hu5//z8fH/8O3t/2Vl + Zc8AAABZAAAARQAAAC4AAAAZAAAACwAAAAQAAAABAAAAAAAAAAD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AAMDAwADAwMAAwMDAE5OToXHwMD/zsbG/+zo + 5P+moLT/GBim/xYXvf8ZGbj/Ghq1/xobs/8aG7D/Gxyt/xscq/8cHan/HB2m/xwdpP8cHqH/HB6e/xwe + nP8dHpr/Hh6X/x4flP8eH5H/HyCR/x8glP8fIJb/Hx+Y/x8fm/8fIJz/HyCd/x8gn/8fIKL/HyCl/x8g + pv8eH6f/Hh+q/x4frP8dHq3/HB2u/xwdsf8cHbP/HB20/xwctf8bG7f/Gxu5/xsbuv8aG7z/Ghu+/xoa + v/8aGcH/GRnC/xkZxP8ZGcT/GRnE/xgYxP8YGMX/GBjF/xcYxf8XGMX/FxjF/xcYxf8XGMb/FxjH/xYY + x/8WGMf/FRjH/xUYx/8UGMj/FBjI/xQYyP8TF8j/ExfI/xMXyP8SFsj/EhbI/xEVx/8QFcf/EBPG/xAT + xv8PEsb/DxHG/wgLxP8sJnn/z8fB//f19f/28vL/oqCg9QYGBnAAAABKAAAANQAAAB8AAAAPAAAABQAA + AAEAAAAAAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8AAwMDAAMDAwADAwMFfnx8y9DJyf/Uzc3/7Off/21oov8OELP/GRq8/xkauP8aGrf/Gxu0/xsc + sf8bHK//Gxys/xsdqv8cHaf/HB2l/x0eo/8dHqD/HR6d/x0fm/8fH5j/HyCW/yAhlP8gIZL/ICGT/yEi + lf8hIZj/ISGa/yAhm/8gIZ7/ICGg/yAhov8gIaT/ICGl/yAhp/8fIKr/HyCq/x4frP8eH67/Hh+v/x0e + sf8dHrP/HR61/xwctv8cHLf/HBu5/xwbu/8aG7z/Ghu+/xobv/8aGsH/GhnC/xkZw/8ZGcT/GRnE/xgY + xP8YGMX/GBjF/xcYxf8XGMX/FxjF/xcYxf8XGMX/FhjG/xYYx/8WGMf/FRfH/xUXx/8UF8f/FBfH/xQX + x/8TFsf/ExbH/xIVx/8SFcf/ERTH/xEUxv8RE8b/EBLF/xASxf8PEMT/DQ7I/xAPk/+flJf/+vj2//Lv + 7//Ny8v/KSkpmgAAAEsAAAA7AAAAIwAAABIAAAAHAAAAAgAAAAAAAAAA////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wAkJSUAJCUlACQlJSein5/208zM/97Z + 2P/Y08//Pz2f/xESvf8ZGr3/GRq6/xobt/8bHLX/Gxyy/xscsP8bHK7/Gx2r/x0eqP8dHqb/Hh+j/x4f + ov8fIJ//HyCd/yAgm/8hIZj/ISKW/yIik/8iI5P/IiSV/yIkmP8iIpr/ISKc/yEinf8iI5//ISKh/yEi + ov8hIqX/ISKn/yEiqP8hIqr/ICKs/x8grf8fIK7/HyCw/x4fsv8eH7P/HR61/x0ct/8cHLj/HBy5/xwc + u/8aG73/Ghu+/xobwP8aGsH/GhrC/xkZw/8ZGcT/GRnE/xkYxP8YGMX/GBjF/xcYxf8XGMX/FxjF/xYX + xf8WF8X/FhfG/xYXxv8WF8b/FRfG/xUWxv8VFsb/FBbF/xQWxf8TFcX/ExXF/xIUxv8SFMb/EhLF/xES + xf8QEsT/EBHD/w8Qw/8ND8b/CAms/2lefv/y8On/8O3t/+nl5f9RUFC/AAAAUQAAAEAAAAAoAAAAFQAA + AAkAAAADAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////ADY2NgA2NjYANjY2Zb65uf/Rycn/6OPh/7mzu/8mJqn/GRnD/xkavv8aG7v/Ghu5/xsb + tv8bHLP/Gxyx/xwdrv8cHqz/HB+q/x8fp/8fIKX/ICGj/yAhof8gIZ//ISKc/yIimv8iJJn/IyWW/yMk + lP8kJZX/JCaY/yQlmf8kJZv/JCWd/yQln/8kJaH/JCWi/yMjpP8jJKb/IySn/yIjqf8jI6z/ISKs/yAh + rv8gIbD/ICGx/x8gs/8fILT/Hh+1/x0et/8cHLj/HBy5/xwcu/8bHL3/Ghu+/xoav/8aGsH/GhrC/xoa + w/8ZGcT/GRnE/xkZxP8YGMT/GBjF/xgYxf8XGMX/FxjF/xYXxP8WF8T/FhfF/xUWxf8VFsX/FRbF/xQW + xv8UFcT/FBXE/xMUxP8SFMT/EhTF/xITxf8RE8T/EBLE/xARxP8PEMP/DxDD/w4PxP8HCb7/PTR4/+Da + 0v/y8PD/7+zs/4aFheYAAABgAAAARAAAAC4AAAAZAAAACwAAAAQAAAAAAAAAAP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAAEBAAABAQBlZGSbzcbG/9PN + zf/t6eL/jIas/x8ft/8jI8b/Hh/A/xkavP8aG7n/Gxu3/xwctf8cHbP/HR6w/x0erv8eH6v/HyGp/yAh + p/8gIqX/ISKj/yIjoP8iI53/IySc/yQkmv8kJpf/JSeV/yUnlf8mKJf/Jiia/yYnnP8mJ53/Jief/yYn + oP8mJ6P/Jiek/yYmpv8lJaf/JSSo/yQkqv8kJKz/IyOt/yEir/8hIrD/ICGy/yAhs/8gILX/Hx+1/x4e + t/8dHbj/HRy6/xwcu/8cHLz/Ghy9/xobvv8aGsD/GhrC/xoaw/8ZGcP/GRnE/xkZxP8YGMT/GBjE/xgX + xP8XF8X/FxfF/xYXxP8WF8T/FRfE/xUWxP8VFsX/FBXF/xQVxf8TFMT/ExTE/xIUxP8SE8P/EhPE/xES + xP8REsP/EBHD/xARw/8PEMP/Dw/D/woLxP8fGof/u7Kv//b08//x7e3/raur+xESEnoAAABHAAAAMwAA + AB0AAAAOAAAABQAAAAEAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wAAAQEAAAEBB4KAgM/Uzc3/2dTT/+fi2/9jX6P/HBzB/ycnx/8mJsP/ISK//xoc + u/8aG7j/HB22/x0ftP8eH7H/Hh+v/yAhrf8gIqv/IiOp/yMjp/8kJKX/JCWi/yUmof8mJ5//Jied/yYn + m/8oKpj/KCqW/ygql/8pKpr/KSqc/ykqnf8pKp//KSqg/ykqo/8pKqT/KCim/ygop/8oKKn/Jyeq/ycm + rP8mJq3/JCWu/yIkr/8iI7H/ISKy/yAitP8gIbT/HyC2/x8et/8eHrj/HR25/x0cu/8cHLz/Gxy9/xob + vv8aGr//GhrB/xoZwf8ZGcP/GRnE/xkZxP8YGMT/GBjE/xgXxP8XF8T/FxfE/xYWw/8WFsP/FhbE/xUW + xP8VFcT/FBXE/xQVxP8TFMT/ExTE/xITw/8SE8P/EhLD/xERwv8REcL/EBDC/xAPwv8PD8L/DQ3G/woJ + m/+TiJL/+Pbz/+3o6P/Qzc3/LS0tmwAAAEcAAAA3AAAAIQAAAA8AAAAGAAAAAQAAAAD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////ABQVFQAUFRUgn5yc9NjR + 0f/f29n/083L/0VEp/8jI8n/JyfH/ygoxf8oKML/JSa//x0euv8cHbf/Hh+1/x8gs/8gIbH/ICKv/yIj + rf8kJKv/JSSp/yUlp/8mJ6T/Jyij/ygpof8pKp//Kiuc/yosm/8qLZn/Ky2X/ysumf8rLpz/LC2d/ywt + n/8sLaD/Kyyj/ysspP8rLKX/Kyun/yoqqP8qKqr/KSmr/ygorP8nJ67/Jiav/yQmsP8kJbH/IySy/yIj + s/8hIrX/ICG2/yAgt/8eHrj/Hh25/x0duv8cHLz/Gxy8/xocvv8aG77/GhrA/xoZwf8aGcH/GRnC/xkZ + w/8YGMT/GBjE/xgYxP8XF8T/FxfE/xYWw/8WFsP/FRXD/xUVw/8VFcP/FBTE/xQUxP8TE8T/ExPD/xIS + wv8SEcL/ERHC/xERwv8QEML/EBDC/w8Pwv8ODsT/CQmt/2Zcgf/w7Ob/6+jo/+bi4v9KSkq6AAAATAAA + ADsAAAAkAAAAEgAAAAcAAAACAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8AMzMzADMzM1O5tbX/1s/P/+fj4P+8t73/LS2v/yYmzv8pKMn/KSnG/ykp + xP8qK8L/KSq//yMku/8fILf/ICG1/yIjs/8jJLH/JCSv/yUlrf8mJ6v/KCep/ykpp/8qK6X/Kyyj/ywt + ov8sLaD/LS+e/y4wm/8uMJr/LjCa/y8xm/8vMZ7/LzCf/y8woP8uMKP/LS+k/y4vpf8tLqf/LC2o/yws + qv8sLKv/Kyqs/yoqrf8pKa7/Jyiv/yUnsP8lJrH/JCWz/yMktP8hI7X/ICK2/yAgt/8fH7j/Hh65/x4d + uv8dHLv/HBy8/xobvf8aG73/Ghu//xobwP8aGcH/GRnB/xkZwf8YGML/GBjD/xgYxP8XF8T/FxfE/xYW + w/8WFsP/FRXD/xUVw/8UFMP/FBTD/xQTw/8TE8P/ExLD/xISwv8SEsL/ERHC/xERwv8QEML/EBDB/w8P + wf8HCLv/QTl6/+Te1v/t6ur/6OTk/3d2dtoAAABZAAAAPgAAACcAAAAVAAAACQAAAAMAAAAA////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wA6OTkAOjk5eM3H + x//W0ND/6+fi/5yWsv8pKbv/KSrP/ysryv8rK8j/KyvG/yssw/8sLcH/LS6//yoqu/8kJLf/IyS0/yQl + sv8mJ7H/Jyiw/ykprv8rK6z/LCuq/y0tqP8tL6X/LjCk/y8xov8xMaH/MTOf/zI0nP8yNJv/MjSc/zM1 + nv8zNKD/MzOh/zEzo/8xM6T/MTOm/zAyp/8vMaj/Ly+q/y4uq/8tLqv/LC2t/ywrrv8qK6//KCmw/yco + sf8mJ7H/JSaz/yQltP8iI7T/ISK2/yAgt/8fH7j/Hh64/x0duf8dHLv/HBy7/xscvP8aG73/Ghu+/xob + v/8ZGr//GRnA/xkYwP8YGMH/GBjC/xcXwv8XF8P/FxfD/xYWw/8WFsP/FRXD/xUVw/8UFMP/FBTD/xMT + w/8TE8P/EhLB/xISwf8REcH/ERHA/xEQv/8QEL7/EA++/wkLvv8qJYP/ysK///Hu7f/s6Oj/lZSU8QAA + AGMAAABBAAAAKwAAABcAAAAJAAAAAwAAAAD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AAEBAQBtbGyh083N/9nU1P/q5d3/f3ur/yMkxP8tLc//LS7M/y4u + yf8uLsf/Ly/F/y8ww/8wMMH/MTK//zExvP8rLLj/Jyi0/ycosv8qK7D/Kyyv/y0trf8uLqz/Ly+q/y8x + qP8xM6f/MjSl/zM0o/80NqL/NTeg/zY4nv82OJ3/Njie/zY4oP82OKL/Njej/zU3pP80Nqb/NDan/zM1 + qP8yNKr/MTKr/zAxq/8uL63/Li+u/y0ur/8sLK//Kiuw/ykpsv8mKLL/Jiez/yUmtP8jJLT/ISO1/yEi + tv8gILf/Hh64/x4euP8dHLr/HBy7/xwcu/8aG7v/Ghu8/xobvv8ZGr7/GRq//xgZv/8YGL//GBi//xcX + wP8XF8H/FhbB/xYWwf8WFcH/FRXB/xUUwf8UFMD/FBTA/xMTwP8TE8D/EhK//xISvv8REb3/EBG9/xAR + vf8PEbz/DA69/xYTj/+wpqf/8/Hw/+vm5v+zsLD8FxgYewAAAEIAAAAuAAAAGQAAAAsAAAADAAAAAP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAQEBBIB/ + f8bX0dH/3djY/+Te1/9pZaj/JCXN/y8v0P8vMM3/MDDL/zExyv8xMcj/MTPG/zIzxP80NcL/NjXA/zc3 + vv80Nbv/Li+2/ywss/8tLbH/LzCw/zEyr/8yM63/MzSr/zQ2qv82OKj/Njmm/zg5pf85OqP/Ojuh/zo8 + n/86PJ//Ojyh/zo8o/86O6T/Ojul/zg6p/84Oqf/Nzmo/zY3qv81Nqv/MzSs/zIzrf8xMq3/MDGu/y4v + r/8tLbD/Kyyw/yorsf8oKbL/Jiez/yUmtP8jJbT/IiS1/yEitv8gILb/Hx+3/x4et/8dHLj/HBy5/xwc + uv8bG7v/Gxu7/xobu/8aGrz/GRq9/xgavf8YGb7/GBi+/xcYvv8XF7//Fhe//xYXv/8VFr//FRW//xQV + vv8UFL3/ExS9/xMTvf8SE73/EhO9/xESvP8RErv/EBK6/xARuf8OD7z/DQyZ/5WKlv/18u//5+Li/8bD + w/8qKiqUAAAAQgAAADEAAAAbAAAADAAAAAQAAAAA////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wAAAQENj4yM59zW1v/h3dz/1tHO/1RSrf8qK9P/MDDS/zAx + 0P8yMs3/MzPL/zMzyf81Ncf/NjfF/zY3wv84OcH/OjvA/zw9v/88PLz/ODi5/zMztf8yMrL/MzSx/zY3 + sP83OK7/ODms/zk7q/87Par/Oz2o/z0+pv8+P6X/PkCj/z9Bof8/QaH/P0Gj/z5Apf8+P6X/Pj+n/zw+ + qP86Pan/Ojyq/zg6q/83Oav/Njet/zU1rf8yNK7/MTKv/y8wr/8uL7D/LC2w/yorsf8pKrL/Jyiz/yUm + s/8kJbT/IiO0/yEitf8gIbb/Hx+2/x4etv8dHbf/HBy4/xwcuf8bG7n/Gxu6/xsbuv8aGrv/Ghq8/xkZ + vP8YGbz/Fxm7/xcYu/8XGLz/Fhe8/xYXvf8VFr3/FRa8/xQVu/8UFbz/ExS7/xMUuv8TE7r/EhO6/xIS + uf8SErj/ERG3/xAQuf8LC6L/d2yL//Hu6f/l4eH/19PT/zU1NakAAABCAAAAMwAAAB4AAAAOAAAABAAA + AAH///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////ACUl + JSCppaX03tfX/+Tg3//MxcX/RUSy/y4u1v8yMtP/MzTR/zQ1z/82Nsz/NzfL/zg4yf85Ocf/OjvF/zs9 + xP89PsH/Pz/A/0BAv/9CQr3/QkK7/z4+uP85ObT/ODmy/zo7sf89PbD/Pj+u/z9BrP8/Qqv/QUOq/0JE + qP9DRKf/Q0Wl/0RFo/9DRaT/Q0Sl/0JEp/9CQ6j/QUKo/z9Bqv89QKr/PD6r/zs9rP86O63/ODit/zY3 + rf81Nq//MzSv/zEyr/8uL7D/LS6w/ywssP8pKrL/KCmy/yYns/8kJbP/IiOz/yEis/8gIbT/HyC1/x4e + tv8dHbb/HBy3/xwbuP8bG7j/Gxu5/xsbuP8aGrj/Ghq5/xkZuv8YGbr/GBi6/xgYuv8XF7r/Fxe6/xYW + uv8WFrr/FRa6/xUVuv8UFbn/FBS4/xQUuP8TE7f/ExO3/xIStv8SEbb/ERG3/woKqf9eVoX/7enh/+Xh + 4f/g29v/TExMuQAAAEYAAAA1AAAAHwAAAA4AAAAFAAAAAf///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8ALy8vPLezs/zc19f/5uLg/8K7vv85OLb/MzPY/zU1 + 1f82NtL/NzjQ/zg5z/87Osz/OzvL/zw8yv8+P8f/P0DG/0BBxf9DQ8P/RETC/0ZGwP9ISL7/SUm9/0lJ + u/9ERbf/QEG1/z9Asv9CQrH/Q0Ww/0RGr/9FR63/Rkis/0hIqv9ISaj/SEmn/0hJpv9HSKb/R0io/0ZH + qf9GR6n/REWq/0NEq/9BQ6v/P0Gt/z5Arf88Pa3/Ojqu/zc4rv82N6//NDWv/zIzr/8vMK//LS+w/yws + sP8qK7H/Jyqx/yYnsf8kJbL/IiOy/yEis/8gIbT/HiC0/x0etP8dHbT/HB21/xsbtf8bG7b/Gxu3/xsa + t/8aGrj/Ghm4/xkZt/8ZGbj/GBi4/xgYuP8XF7j/Fxe4/xYWuP8WFrj/FRW3/xUUt/8UFLb/FBS2/xMT + tf8TE7T/EhK0/xISs/8RErP/Bwqu/0pBfv/q5Nv/5uLi/+Hc3P9oZ2fLAAAATQAAADYAAAAgAAAADwAA + AAUAAAAB////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wAxMTFPwLy8/93W1v/r5+T/sKq3/zc3vP82Ntn/ODjV/zk51P86OtL/OzvQ/z09z/8/P83/QEDM/0JC + yv9DRMj/REbH/0dHxv9JSMT/SkrD/0xMwv9OTcD/UE+//1FSvv9QUbz/TE25/0hJtf9HSLL/SUuy/0pN + sf9LTa//TE6u/01Orf9NTqv/TU6p/01OqP9MTaj/S0yq/0pLqv9JSqv/R0ms/0VHrP9ERq3/QkSt/0BC + rv8+P67/PDyu/zk6r/83OK//NTav/zM0r/8wMq//Ly+w/y0tsP8rK7D/KCqw/yUnsP8kJbH/IySx/yEi + sv8gIbL/Hh+y/x0fs/8cHrP/HBy0/xsctP8bHLT/Gxy2/xoatv8aGrb/GRm1/xkZtf8YGLb/GBi2/xgX + tv8XF7b/Fxa2/xYWtf8WFbX/FRW0/xUVtP8UFLT/FBSz/xMUsv8TE7H/EhOw/xESsP8JC67/PDWA/9/Z + 0v/n4+P/4dzc/3h2dtgAAABSAAAANgAAACEAAAAPAAAABQAAAAH///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////ADU1NWLLxsb/3tjY/+vo5P+inLP/OzvC/zg4 + 2f86Otb/PDvW/z091P89PtL/QEDS/0JCz/9DQ87/RUTN/0ZHy/9JSsn/S0vI/01Nxv9PT8b/UFHE/1JS + w/9TU8L/VVXB/1dYwP9ZWr//WVq9/1VWuv9QUbb/T1C0/1BRs/9RUrL/UlKw/1NSrv9SVK3/UlOr/1JT + qv9RUqv/T1Cs/05PrP9NTq3/Skyt/0hLrf9FSa3/REau/0JDrv9AQa7/PT+u/zs7r/84Oa//Njev/zM0 + r/8wMa//Li+v/y0tr/8rK6//KCqv/yYor/8kJrD/IiOw/yEisP8fILH/Hh+x/x0esf8dHrL/Gxyy/xsc + sv8bHLP/Gxyz/xobtP8aG7T/GRq0/xkZs/8YGbP/GBi0/xcYtP8XF7T/Fhez/xYXs/8VFrL/FRax/xQV + sf8UFbH/ExSx/xITsP8SE67/ERKu/wsNrf80LoP/1c3J/+nl5P/j3t7/hoSE4wAAAFYAAAA3AAAAIQAA + AA8AAAAFAAAAAf///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8ANjY2bNDLy//f2tr/6ubg/5aRsf85Ocb/OzvZ/z091/8+Ptf/QD/X/0FB1f9DQ9P/RUXR/0dH + 0P9ISM//S0vN/01Oy/9PUMr/UVLJ/1NTyP9VVcf/V1jG/1hZxf9aW8T/W1zD/15fwv9gYcH/YWLA/2Fi + v/9dXrz/WVq4/1ZXtf9WV7T/WFiz/1hZsf9YWbD/V1iu/1ZXrP9VVqz/VFWt/1JTrv9QUa7/Tk+u/0tN + rv9IS67/RUiu/0NFr/9BQ6//PkCu/zw8rv85Oq7/Njev/zQ1rv8xMq//Li+u/y0trv8rLK//KCmv/yYm + rv8kJK//IiOv/yAhr/8fILD/Hh+w/x0esP8cHbD/HB2x/xscsf8bHLH/Ghux/xobsf8aG7L/GRqy/xka + sv8YGbH/GBmx/xcYsf8XGLH/Fhex/xYXr/8VFq//FBWv/xQVr/8TFK7/ExSu/xITrP8SE6z/DA6r/ysn + hv/Lw8L/6ubl/+Pd3f+LiYnqAAAAWAAAADcAAAAhAAAADwAAAAUAAAAB////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wA5OTmA29bW/+Db2//p5N//npi1/z4+ + x/89Pdn/Pz/X/0FB2P9CQtj/RUXW/0ZH1P9ISdP/SkvS/01M0P9PT8//UVHO/1NUzf9VVsz/VlfK/1lZ + yv9cXcn/Xl/H/19gx/9hYcb/Y2TG/2Rnxf9nZ8T/aGjC/2lqwv9qa8H/Z2i+/2Njuv9fYLf/XV21/11d + tP9dXrH/XF2w/1tcrv9ZWq7/V1iv/1VWr/9TU6//UFCv/01Pr/9KTK//R0mv/0VHr/9CRK7/P0Gu/zw9 + rv85Oq7/Nzet/zQ1rf8xMq3/Li+t/y0trf8rK63/KCit/yYmrf8kJa7/IiOu/yAhrv8eH67/HR6u/xwd + rv8cHa//Gxyv/xscsP8bHK//Ghuu/xobr/8ZGrD/GRqw/xgZr/8YGa//Fxiu/xYXrv8WF67/Fheu/xUW + rv8VFqz/FBWs/xQVq/8TFKv/ExSr/xITqv8MDqn/LSmG/8zFw//p5eT/5N7e/5mWlvYAAABcAAAANgAA + ACEAAAAPAAAABQAAAAH///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////ADk5OYDc19f/4t3d/+bh3P+Yk7X/PT3K/0BA2f9CQtf/RETY/0VG2f9IR9j/SUnX/0tL + 1f9OTtT/UVHT/1NS0v9UVdD/V1jO/1lZzv9cXM3/Xl7N/2Bhy/9jZMv/ZWbK/2dnyv9pasj/amzI/2xt + x/9vb8b/b3DG/3Bwxf9xcsT/cXLC/3Bxwf9sbb3/Z2e6/2Njtv9hYrT/X2Gy/15fsP9dXrD/Wluw/1hZ + sP9WVbD/U1Kw/09Qr/9MTa//SEuv/0ZIrv9DRa7/QEGu/z0+rv86Oq3/Nzet/zM0rf8wMa3/LjCs/y0s + rP8qKqz/KCis/yUlrP8kJKz/ISOs/yAhrP8eH6z/HR6s/xwdrP8bHKz/Gxys/xscrf8aG63/Ghut/xka + rf8ZGq3/GBmt/xgZrf8XGK3/Fxis/xYXrP8WF6z/FRas/xUWq/8UFar/ExSq/xMUqf8TFKj/ExSn/w4Q + qP8jIIf/wLe4/+zo5v/j3Nz/mZaW9gAAAFwAAAA2AAAAIQAAAA8AAAAFAAAAAf///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AOTk5gN3Y2P/j39//5uHb/5aS + tf8+P8v/Q0La/0VF2P9HR9n/SUnZ/0pK2f9MTNn/T0/Y/1BS1v9UVNX/V1bU/1lZ0/9cW9H/Xl7Q/2Fh + 0P9kZM//ZmbO/2hpzf9ra83/bG7M/29wzP9xcsv/cnPK/3R1yv92dsn/d3fI/3d3x/94eMb/eHjF/3d4 + xP93d8L/dHTA/25vvP9oarj/ZGW0/2Fjsv9fYLH/XV6x/1pbsf9XV7H/VFSw/1FRr/9NTq//SUuv/0ZI + rv9DRa3/QEKt/zw+rf85Oq3/Njes/zMzrP8vMKv/LS6r/ywsq/8qKqv/Jyeq/yQkqv8jI6r/IiKq/yAh + qv8eH6r/HR6q/xwdq/8cHar/HB2q/xscq/8aG6z/GRqr/xkaqv8ZGqv/GBmr/xgZq/8XGKr/Fxip/xYX + qf8WF6n/Fhep/xUWqP8VFqj/FBWm/xQVpf8TFKb/DxGm/yMfhv++tbb/6+jm/+Lc3P+YlZX2AAAAXAAA + ADYAAAAhAAAADwAAAAUAAAAB////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wA5OTmA3tnZ/+Xg4P/k39r/oZy1/0ZGyv9FRdv/R0fa/0pK2v9MTNn/TU3a/1BQ + 2/9SUtn/VFXY/1dY1/9aWtb/XV3U/2Bg1P9iYtP/ZmbS/2ho0f9ra9H/bW3R/3Bx0P9ydND/dXXP/3d4 + zv94ec7/enrN/3x8zf9+fsz/fn7L/35/yv9+f8n/fX/I/31+xv98fcX/e3zD/3l6wf90dr7/bnC6/2hp + tf9jZLP/X2Cy/1tdsf9ZWbH/VVWw/1JSsP9OT6//Skyu/0ZIrf9CRa3/P0Gt/zw+rP84Oqv/Njar/zI0 + q/8vMKr/LS2q/ysrqf8oKKn/Jiao/yQkqP8iI6n/ISKp/x8gqf8eH6n/HR6p/xwdqf8cHan/HB2p/xsc + qf8bHKn/Ghup/xkaqf8ZGqj/GRqo/xgZqP8YGaj/Fxin/xcYpv8WF6b/Fhem/xUWpf8VFqT/FBWk/xQU + o/8OD6P/LiqF/8jBv//p5uX/4dra/5iVlfYAAABbAAAANQAAACEAAAAQAAAABQAAAAH///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////ADk5OYDf2tr/49/f/+rl + 4P+hnLb/SEjL/0hI2/9KStr/TU3a/05O2/9RUdr/U1Pb/1VV2/9YWdr/WlzZ/15f2P9iYtf/ZGTW/2dn + 1f9qatX/bW3U/3Bw0/9zc9P/dnbT/3h50/97fNL/fX7S/3+A0v+AgtH/goPR/4SE0P+Fhc//hoXO/4aG + zf+Fhsz/hIXL/4ODyf+Bgsf/gIDG/31/w/96fcH/d3m+/3N0u/9sbrf/ZWe0/19gsv9aW7H/VVaw/1FR + r/9OT67/Skut/0ZHrf9CRKz/PkGs/zs9qv83Oqr/NDap/zIyqf8vMKj/LSyo/yoqqP8nKKf/JiWn/yMj + pv8hIqb/ICGn/x8gp/8dHqf/HR6n/xwdp/8cHaf/HB2m/xscpv8bHKf/Ghun/xobp/8ZGqb/GRqm/xgZ + pv8XGKb/Fxil/xYXo/8WF6P/FRaj/xUWo/8UFaL/FBWi/w4PoP8vKob/0MnI/+bh4P/g2dn/l5SU9gAA + AFsAAAA1AAAAIQAAAA8AAAAFAAAAAf///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8AOTk5gODc3P/l4OD/6ubh/6KeuP9MTM3/Skrb/05O2v9QUNv/UVHb/1RU + 3P9WVtz/WVnc/1xc3P9eXtv/YmLa/2Vm2f9oaNj/bGzX/29v1/9yctf/dXXW/3h41v97e9b/fn7W/4GC + 1v+DhNX/hYbV/4iJ1f+JitT/i4vU/4yM0/+MjNL/jI3R/4yM0P+LjM//iovN/4iJzP+Gh8r/g4TH/4CB + xP99fsL/enzA/3d5vf9zdbr/b3C5/2hptv9hYrT/Wluy/1NTr/9OT63/SUqs/0VGq/9BQ6r/PT+q/zk8 + qf83Oaj/Mzao/zAyp/8tL6f/Kyym/ykppv8nJ6b/JCSl/yIjpf8hIqX/HyCl/x4fpf8dHqX/HB2k/xwd + pP8cHaX/Gxyl/xscpP8aG6X/Ghul/xkapP8YGaT/GBmj/xgZo/8XGKP/Fxii/xYXov8WFqH/FRag/xQV + n/8UFZ//Dg+f/y8rh//Qysj/5N/e/9/Y2P+XlJT2AAAAWgAAADQAAAAgAAAADwAAAAUAAAAB////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wA6OTmA4d3d/+Xh + 4f/q5eH/o5+4/1FSz/9MTNz/UFDa/1JS2/9VVdz/V1fc/1pa3f9cXN3/X1/d/2Ji3f9lZtz/aWnc/21s + 2/9wcNr/dHTZ/3Z22f96etn/fn7Z/4CA2P+EhNj/iIfZ/4qL2P+Mjdj/jo/Y/5CR2P+Sktf/k5TX/5OU + 1v+TlNX/k5TU/5KT0v+RktH/j5DQ/42Nzv+Ki8v/h4jJ/4SExv+AgMT/fH3B/3h6vv90drz/cHK5/21u + uP9pabf/Y2S1/1xdsv9UVrD/TU6u/0dHq/9AQqn/PD6o/zc5p/81N6f/MTOm/y4wpf8sLqX/Kiuk/yco + pP8mJqP/IyOj/yEio/8gIaP/Hh+j/x4fo/8cHaP/HB2j/xwdo/8cHKP/Gxyj/xobov8aG6L/GRqi/xka + ov8YGaH/GBih/xcYoP8WGKD/Fheg/xYXnv8VFp3/FRad/xQWnf8OEJ3/MCyG/9HKyf/j3t3/3tfX/5eU + lPYAAABaAAAANAAAACAAAAAPAAAABQAAAAH///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////ADc3N3LZ1dX/6OPj/+rn4v+embb/UlLP/09P3f9SUtz/VVXc/1dX + 3P9aWtz/XFze/19f3v9jY97/Zmbf/2lp3v9sbd7/cHHd/3R03P94eNv/fHzc/39/3P+Dg9v/hobb/4qK + 2/+Ojdz/kJDc/5OS2/+Vldv/l5fb/5mZ2v+amtr/m5vZ/5uc2P+am9j/mZrW/5iY1f+WltT/k5TS/5GR + 0P+Ojs3/i4vK/4eHyP+Cg8X/fn/D/3l7wP91d7z/cHK6/21tt/9oabb/ZGW1/2Bhs/9bXLL/Vlex/1BR + r/9JSqz/QUOq/zs+qP81N6X/MDKk/y0vo/8qK6P/Jyii/yYnof8jJKH/IiOh/yAhoP8fIKD/Hh+g/x0e + of8cHqD/HB6g/xwdoP8bHKD/Gxug/xoboP8aGqD/GRqf/xkan/8YGp//Fxme/xcYnf8WGJ3/Fhid/xUX + nP8UF5v/FBaa/w4Rmf8wLYb/0svK/+Pe3f/b1NT/jYqK7wAAAFcAAAA0AAAAIAAAAA8AAAAFAAAAAf// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8ANTU1Y9TQ + 0P/q5ub/7Ofi/5iTs/9RUs7/UVHd/1VV3P9XV93/Wlrd/11d3f9fX97/Y2Pf/2Zm4P9qauD/bW3g/3Bw + 4P90dN//eHjf/3x83v+AgN7/hITd/4iI3v+MjN7/kJDe/5OT3v+Wlt7/mZne/5yc3v+ent7/oKDe/6Ki + 3v+jo93/o6Pc/6Kj2/+gotr/n6DZ/52e1/+am9b/l5jU/5OV0f+Qkc7/jI3M/4iJyf+DhMf/fn/E/3p7 + wf91d73/cXK6/21tt/9nabX/Y2Sz/15fsv9aW7H/Vlew/1JTr/9OT63/SUqs/0RGqv8/Qan/OTum/zU2 + pf8wMaT/Kyyi/ycooP8jJJ//ISKf/x8gnv8dHp7/HB2e/xsdnv8bHp7/HB6e/xsdnv8aHJ7/Ghye/xoc + nv8ZG53/GRuc/xganP8YGpz/Fxmb/xYYmv8WGJr/FRea/xUXmf8UFpf/DhGY/y4rhf/SzMv/4t7c/9nS + 0v+DgYHjAAAAVAAAADQAAAAfAAAADgAAAAUAAAAB////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wA1NTVk1tLS/+vn5//s6OL/mJOz/1RVz/9UVN3/V1fc/1pa + 3f9dXd3/X1/e/2Ji3v9mZuD/aWnh/21t4f9wcOH/dHTh/3h44f98fOH/gIHh/4WF4P+JieD/jY3g/5GR + 4f+VleH/mJng/5ud4P+goOH/pKPh/6am4f+oqOH/qqrh/6qq4f+qquD/qqrf/6iq3v+nqN3/pKXa/6Ch + 2f+en9j/mpvV/5WW0v+QkdD/jo7N/4mKyv+DhMf/f3/E/3l7wf91dr7/cHG7/2xst/9maLT/YmOy/11e + sf9ZWrD/VFau/1BSrf9MTqv/SUmq/0VGqf9BQqj/Pj+o/zs8p/83OKX/NDWl/zEypP8tLqL/KSqh/yYn + oP8jJZ//ISOe/x8hnv8eIJ3/HR+c/xwdnP8aHJz/Ghyb/xkbm/8ZG5r/GBqa/xcZmf8WGJn/FhiY/xUX + l/8VF5f/FReX/xQWlv8PEpb/Mi6G/9LMzP/h3dz/2NHR/4SBgeQAAABUAAAANAAAAB8AAAAOAAAABQAA + AAH///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////ADY1 + NWTW09P/6+jo/+zn4v+Yk7P/VlbQ/1ZX3v9aWtz/XFzd/19f3v9iYt//ZWXf/2lp4P9sbOH/cHDh/3R0 + 4v93d+P/fHzj/4CA4/+EheP/iYnj/46O4/+SkuP/lZbj/5ma4/+en+P/oqPk/6an5P+qquX/rK3l/6+v + 5P+xseX/srLk/7Ky5P+ysuP/sLDi/66v4f+srN//qKnd/6Sl2/+hotn/m53W/5aX0/+Sk9D/jo7N/4iJ + y/+DhMj/fn/E/3l6wf90db7/b3C7/2prt/9lZrT/YWKy/1tcr/9XWK7/U1Ws/09Rq/9LTKr/R0mo/0NF + p/9AQab/PT6l/zo7pf83OKP/NDWj/zM0o/8yMaL/MDCi/y0uof8sLaH/Kyyg/ykrn/8oKp//Jiif/yUm + nv8jJZ3/IiSc/yAinP8fIZv/HR+Z/xwemf8bHZj/GhyX/xoblv8ZGpb/GBmV/xYXl/87N4r/0s3N/+Dc + 2v/Xz8//hIGB5AAAAFQAAAA0AAAAHwAAAA4AAAAFAAAAAf///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8ANjY2ZNfU1P/s6en/7Ojj/5iTs/9YWND/WVnf/11d + 3f9fX93/YWHe/2Vl4P9nZ+D/a2vg/29v4f9zc+L/d3fi/3t74/9/f+T/g4Pl/4iI5f+MjeX/kpLk/5aW + 5P+amuX/n5/l/6Sk5v+oqeb/q63n/7Cw5/+ztOf/trfn/7m55/+6uuf/urrn/7q65v+4uOX/tbXl/7Oz + 4/+vsOH/q6ze/6eo2/+iotr/nJ3X/5eX0/+SktH/jY7O/4eIyv+Cg8j/fX3F/3d4wf9zc77/bm67/2hp + uP9kZbX/Xl+x/1pbr/9WV6z/UVOq/01Pqf9JS6j/RUin/0JEpv8/QKX/PD2k/zk7o/82OKL/NDWh/zMz + of8xMaD/MDCg/y4voP8tLp//LS6e/yssnv8qK57/KSqe/ykpnf8oKZ3/Jyic/yYnm/8lJpr/JCWa/yMk + mv8iI5n/ICKY/yAhlv8eH5b/Gx2X/z06i//Tzc3/4NrZ/9bPz/+DgYHkAAAAVAAAADQAAAAfAAAADgAA + AAUAAAAB////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wA2NTVk2NXV/+7q6v/s6eT/l5Kz/1pZ0f9bW9//Xl7e/2Fh3v9kZN//Z2fg/2tr4P9ubuH/cnLh/3Z2 + 4/96euT/fn7k/4KC5f+Hh+f/jIvm/5CR5v+Vlub/mprn/5+f5/+kpOf/qano/66u6f+ys+n/trfq/7q7 + 6v++v+v/wMDr/8LC6//Cwuv/wsLq/8DA6f++vef/urrl/7a25P+ysuL/ra3f/6eo3f+hotr/nJ3W/5aX + 1P+RktH/jIzN/4aGy/+Agcj/enzE/3V1wf9wcb7/a2y7/2dnuP9hY7X/XV2y/1hZr/9UVqz/UFGp/0tO + p/9ISqb/REal/0JDo/8+QKP/Oz2i/zk7of82OKD/MzWf/zIzn/8xMZ7/MDCe/y8wnf8uL53/LS6d/ywt + nf8rLJ3/Kiuc/ykpm/8oKZr/Jyia/yYomf8lJpj/JCaX/yMll/8iJJb/ISOV/yAik/8cIJX/PjuL/9PN + zv/f2tn/1c3N/4OAgOQAAABUAAAANAAAAB8AAAAOAAAABQAAAAH///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////ADY2NmTZ1tb/7+vr/+rm4v+nobj/YGDQ/1xc + 3/9hYd7/Y2Pf/2Zm3/9qauD/bW3h/3Bw4v90dOL/eHjj/3x85P+BgeX/hYXm/4qK5/+Pj+j/lJTo/5mZ + 5/+enuj/o6Pp/6mp6v+urur/s7Pr/7i57P+9vuz/wcLt/8TG7f/IyO7/ysru/8rK7v/Jyu3/yMjs/8XF + 6//Bwen/vb3m/7i45f+zsuL/ra3f/6eo3P+hotn/mpzW/5WW1P+Pj9D/iorN/4OEyv9+fsf/eXnE/3N0 + wf9tbr7/aWm6/2Rkt/9fYLX/W1yy/1ZYr/9SVK3/TlCq/0pMp/9HSaX/Q0Wj/0BCov88PqH/Ojuf/zg6 + nv83OJ7/NDae/zEznf8xMpz/MDGc/y8wnP8vMJz/Li+b/y0um/8sLZv/KiuZ/ykqmf8oKpj/KCmY/yYp + lv8mJ5b/JSaW/yQmlf8jJZP/IiST/x0glP9HQ4v/1tDP/97Y2P/UzMz/g4CA5AAAAFMAAAAzAAAAHwAA + AA8AAAAFAAAAAf///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8ANjY2ZNrX1//w7e3/6OTh/6ymtv9mZ9H/Xl7g/2Nj3v9lZd//aGjg/2xs4P9vb+H/c3Pi/3d3 + 4v97e+P/f3/l/4OD5v+IiOb/jY3n/5KS6P+Xl+n/nZ3q/6Ki6v+np+v/ra3r/7Kz7P+5uO3/vr7u/8PD + 7//IyPD/zMzw/8/P8f/R0fH/0tLx/9HS8P/P0PD/zMzu/8jI7P/Dw+r/vr7n/7i45f+xsuL/q6zf/6Sm + 3P+fn9n/mJnW/5OS0/+NjdD/hofN/4CByf97fMb/dXfE/3Bwwf9rbL3/Zme7/2FjuP9cXrX/WFmy/1RV + r/9QUa3/TE6r/0hKqf9FR6b/QkOl/z9Bo/87PqD/OTue/zg5nv83N53/NDWb/zIzm/8xMpv/MDGa/zAx + mv8vMJr/Li+Z/y0umf8sLZj/KyyX/yorl/8oK5b/JyqW/yYolv8mJ5X/JSeV/yQmlf8jJZX/HiGW/1NO + jv/f2tf/29bV/9LLy/+CgIDkAAAAUgAAADMAAAAfAAAADgAAAAUAAAAB////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wA2NjZk29jY/+/t7f/w7er/q6W2/2dn + 0f9gYOD/ZGTf/2ho3/9qauD/bm7h/3Fx4f91deL/eXnj/3195P+BgeX/hobm/4qK5/+QkOj/lJTp/5qa + 6v+fn+v/pqbs/6ur7f+xse3/trbu/7297//Dw+//ycnx/87O8v/T0/P/19f0/9nZ9P/a2vT/2drz/9fX + 8v/T1PH/zc7u/8nJ7P/Dw+r/vLzn/7a25f+vsOL/qKnf/6Kj3P+bnNn/lZbV/5CQ0v+KidD/hIPM/31+ + yf94ecb/c3PD/21uwP9oab7/YmW6/15guP9ZW7X/VVez/1JTsP9OT67/Skyr/0dIqv9DRaj/QUKl/z0/ + pP87PKP/Ojqh/zg5n/82OJ7/NDWd/zI0nP8xMpz/MTGc/zAxm/8wMJr/LzCa/y4vmv8tLpn/LC2Z/yot + mf8pK5n/KCqY/ycpmP8mKJj/JieY/yUmmP8fIZr/VE+R/+Xh3v/X0ND/0svL/4J/f+QAAABSAAAAMgAA + AB4AAAANAAAABQAAAAH///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////ADY2NmTb2dn/8O3t//Hu6/+sprb/amzT/2Fh4f9mZuD/aWng/2tr4P9wcOL/c3Pi/3d3 + 4v97e+T/f3/k/4SE5f+IiOf/jY3n/5KS6P+Xl+r/nZ3q/6Ki7P+np+3/ra3t/7S07v+7u+//wMDw/8fH + 8f/NzfL/1NT0/9nZ9f/e3vb/4uL3/+Pj9//i4vb/3t71/9nZ9P/U1PH/zs7v/8fH7P/AwOn/urrn/7Ky + 5P+sq+H/paXe/56f2/+Xmdj/kpLV/4yL0v+Fhs7/gH/M/3p6yf91dcb/b3DC/2prwP9lZr3/YGK7/1te + uP9XWbb/U1Wz/09RsP9MTa7/SEqs/0VHq/9CQqj/QECn/z0+pf86O6T/OTmi/zg4ov83N6D/NTWg/zQ0 + n/8zNJ//MjOe/zExnv8wMJ7/LzCd/y4wnP8tL5z/LC6c/yssnP8qK5z/KSqc/ycpnP8mJ5z/JSac/yIj + nf9ZVJT/5eDd/9TOzv/Rycn/gX5+5AAAAFIAAAAyAAAAHgAAAA0AAAAFAAAAAf///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8ANjY2Zt3a2v/y7u7/8e7r/62n + t/9tb9T/Y2Ph/2ho3/9qauH/bW3h/3Fx4f90dOL/eHjj/3195P+BgeX/hYXm/4qK5/+Ojuj/lJTp/5mZ + 6v+enuv/paXs/6ur7v+wsO7/t7fv/7298P/ExPH/y8vy/9HR9P/Y2PX/39/2/+Xl+f/p6fn/6+v5/+rq + +f/m5vj/39/1/9nZ8//R0vH/ysvu/8TE6/+8vOj/tbXl/66u4v+np+D/oaHd/5qZ2f+TlNf/jo7U/4eH + 0f+Cgs7/fXzL/3Z3yP9xcsX/a2zD/2ZnwP9iY73/XV+7/1lauP9UVrX/UFK0/01Psv9JS6//R0it/0RF + q/9BQqr/Pz+p/zw9p/86Oqb/ODik/zc4o/82NqP/NTaj/zQ1ov8zNKL/MjOh/zEyoP8wMaD/MDCg/y4w + oP8tL5//LC6f/yssn/8qK5//KSqf/ycpn/8mKJ//JCah/19amP/l4N7/1M3N/9DJyf+Cf3/kAAAAUgAA + ADEAAAAdAAAADQAAAAQAAAAB////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wAzMzNX1NLS//Tx8f/y7+z/rKa3/2pr0v9lZeL/aWng/2xs4f9vb+H/cnLh/3Z2 + 4/96euP/fn7k/4KC5f+Ghub/i4vn/5CQ6P+Vlen/mprq/6Cg6/+lpez/rKzu/7Ky7/+4uPD/v7/y/8bG + 8v/NzfP/1dX1/9zc9v/j4/j/6ur6//Hx/P/09Pz/8fH8/+vr+v/k5Pf/3Nz0/9TU8v/Nze//xsbs/76+ + 6f+3t+f/sLDk/6mp4f+jot7/m5vb/5SW2P+Pj9b/iYnT/4KD0P99fs3/eHjK/3JzyP9tbsT/aGnC/2Nk + wP9eYL3/Wlu6/1ZXuP9TVLb/T1C1/0tMs/9ISbD/Rkev/0JDrf9AQaz/Pj6q/zo8qf84Oqj/ODin/zc4 + pv82N6X/NTel/zQ2pf8zNaT/MTSj/zAyo/8wMaP/LzCj/y8wo/8tMKP/LC6j/ystov8qLKL/KSyj/ycq + o/8iJaP/V1KV/+bi3v/TzMz/zsbG/3l2dtwAAABOAAAAMAAAABwAAAANAAAABAAAAAD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AEpKSkbKyMj/9vPz//Pw + 7f+qpLb/YmPO/2dn4v9ra+D/bW3g/3Bw4v90dOL/eHjj/3t75P9/f+X/g4Pl/4iI5/+Njef/kZHo/5eX + 6f+cnOr/oaHs/6io7f+tre7/s7Pv/7q68P/AwPL/yMjz/87O9f/W1vb/3t74/+bm+f/u7vr/9vb9//z8 + /v/39/3/7+/7/+bm+P/e3vX/1tbz/87O8P/Hx+7/wMDr/7m56P+xseX/qqri/6Oj3/+cnNz/lpba/4+Q + 1/+Ki9X/hITS/31/z/94ecz/c3XK/25vx/9pasT/ZWXC/2Bhv/9cXL3/V1i7/1NUuf9QUbf/TE21/0lK + s/9HR7L/RESw/0BBrv8/P63/PT6s/zs8q/85Oqr/ODmp/zc5qf83OKn/NTin/zQ3p/8zNqf/MjWn/zEz + pv8xMqb/MDGm/y8xpv8uMKb/LS+l/ystpv8rLKb/KSum/yMlpv9UUJX/5+Pf/9PLy//LxMT/bmxs0AAA + AEgAAAAuAAAAGwAAAAsAAAAEAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8AZ2dnSMjGxv/39PT/8/Ht/6qktv9iY87/aWni/2xs4f9ubuH/cXHh/3V1 + 4/95eeP/fHzk/4CA5f+FheX/iYnn/42N6P+Skun/l5fq/52d6v+iouz/p6ft/66u7v+zs/D/urrx/8HB + 8v/Hx/T/z8/1/9bW9v/d3fj/5eX5/+3t+v/09P3/+fn9//b2/f/u7vv/5ub4/97e9v/W1vP/zs7x/8bH + 7v/AwOz/ubjp/7Ky5v+qquP/pKTh/52d3v+Wl9v/kZLY/4uM1f+EhdP/f4DR/3l6zv90dcv/b3DK/2ps + x/9lZ8T/YWLC/11ev/9ZWr7/VVa7/1FSuf9NTrj/Sku2/0hIs/9FRbL/QkOx/0BAsP8/P67/PT6t/zo8 + rf85Oq3/ODms/zg5q/84OKv/Nzir/zU3qv80Nqr/MzSq/zIzqf8xMqn/MDGo/zAwqP8vMKn/LS+p/ywt + qP8rLKj/JCWp/1RQlv/o5OD/0crK/8rCwv9vbW3QAAAARAAAACsAAAAYAAAACgAAAAMAAAAA////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wBjY2NIycfH//f1 + 9f/z8e3/rKa3/2do0P9paeL/a2vg/25u4v9ycuL/dnbi/3p65P99feT/gYHl/4WF5v+Jieb/jo7o/5OT + 6P+YmOr/nZ3r/6Ki7P+np+3/rq7u/7Oz7/+6uvH/wcHy/8fH8//OzvT/1dX2/9vb+P/i4vn/6en6/+7u + +//x8fz/7+/8/+rq+v/j4/f/3Nz1/9XV8//OzvD/xsfv/76/7P+4uer/sbLn/6uq5P+kpOL/nZ3f/5aX + 3P+Qktr/i4vX/4WG1f9/gNP/envQ/3V1zf9vccz/amvJ/2Znxv9hY8T/Xl/C/1pbwP9WV77/UlO7/09Q + uv9MTLn/SUm3/0ZGtf9ERLT/QUKz/z9Asv8+PrD/PD2w/zs8r/85Oq//OTqv/zk4rv84OK7/Nzit/zU3 + rP81Nq3/MzSt/zIzrP8xMqz/MDCs/y8wq/8tLqv/Kyyq/ygpqv8nKaz/Xlma/+fj3//Qycn/ycHB/3Bu + bs0AAAA8AAAAJQAAABQAAAAJAAAAAgAAAAD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AGNjY0jKyMj/+ff3//Tx7v+po7f/d3jU/3195v96euP/eHjj/3V1 + 4v92duP/eXnk/3195P+BgeX/hYXm/4qK5/+Ojuj/k5Pp/5iY6v+dnev/oqLs/6en7f+uru7/s7Pv/7i4 + 8f+/v/L/xsbz/8zM9f/S0vb/2dn3/97e+P/j4/n/5+f6/+np+v/o6Pn/5OT4/9/f9//Y2PX/0dHz/8vL + 8P/Fxe//vb7s/7a36v+vsOf/qqrl/6Oj4/+dneD/l5fe/5CS2/+Li9n/hYbW/4CA1P96e9H/dXbP/3Bx + zv9sbMv/ZmjI/2Jjx/9fX8X/W1vD/1dXwf9TVL7/UFG9/01Nu/9KSrr/R0e4/0VFt/9DRLb/QUK1/0BA + tP8+P7P/PD2y/zs8sv87PLL/Ojux/zk5sf84ObH/ODiw/zY3sP81Na//MzSv/zAxrv8uMK7/MjOv/zo6 + sv9HSLj/UFG9/11fw/9pZKD/5N/e/9DJyP/IwMD/cW5uygAAADIAAAAdAAAAEAAAAAYAAAABAAAAAP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AY2NjScvK + yv/6+Pj/9PLv/7SuvP9rbM3/g4Pq/4mI6f+MjOn/j4/o/4yM5/+IiOb/hITm/4KC5f+Fheb/iYnn/46O + 5/+Skun/mJjp/52d6/+hoez/p6ft/6ys7v+xse//uLjw/7298v/Dw/P/yMj0/8/P9f/U1Pf/2dn3/97e + 9//g4Pj/4eH5/+Dg+P/d3ff/2dn2/9TU9P/OzvL/yMjx/8LB7/+7vOz/tbbq/66v6P+oqeX/oaPj/5uc + 4f+Wlt//kZHc/4qL2v+Fhtf/gIDW/3p70/92dtH/cHLP/2xszP9naMv/Y2TJ/2Bgx/9cW8T/WFfC/1RU + wP9RUb//Tk++/0tMvf9ISbv/Rka6/0RFuP9BQ7f/QEG3/z9Atv89P7b/PD60/zw9tP87PLT/OTuz/zk6 + s/83OLP/MzWx/zQ2sf87PbT/S0y7/1xdwv9tbcj/cnPL/3Fyzf9ub83/T1HB/1lTlP/r5+L/zsbG/8e/ + v/9zcXHHAAAAJQAAABQAAAALAAAABAAAAAEAAAAA////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wBeXl4vvLq6+f37+//39fX/1c/N/4uJvP9lZsj/bm/S/3Fy + 2P93eOD/iYnn/5OT6/+YmOv/mJjq/5OT6f+Pj+j/jo7o/5GR6P+Wlun/nJzq/6Gh6/+lpez/q6vu/7Cw + 7/+2tvD/u7vx/8DA8v/FxfP/ysr0/8/P9f/U1Pb/19f3/9nZ9//a2vf/2dn3/9fX9v/U1PT/z8/z/8rK + 8v/ExPH/v7/v/7m57P+zs+r/razp/6en5/+goeT/m5vi/5aW4P+QkN7/iorb/4WF2f+Af9f/envU/3Z2 + 0v9wcdD/bG3O/2dpzf9jZMv/YGDJ/1xcx/9YWMT/VlbD/1JSwv9PT8D/TEy+/0lKvv9GR7z/RUa7/0JE + uv9BQbr/QEC5/z4/uP89P7j/PD63/zs8t/84OrX/Nji0/z4+t/9QUL7/ZGXG/3N0zP90dc7/Z2jK/1FT + wv8+QLj/MzSq/ysrof8wLZD/opuu//Dt6f/Hv7//xb29/2BfX6wAAAASAAAADQAAAAYAAAACAAAAAQAA + AAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AF1d + XQWOjo7L+PX1//b09P/y8O//1tDP/8O9wv+no7f/npu+/42Lv/94d8T/dXbR/31+3P+Mjef/nJzt/6Gh + 7f+goOv/m5vq/5iY6v+amur/np7r/6Sk7P+pqe3/rq7v/7Oz7/+4uPD/vb3y/8HB8v/GxvP/ysr0/87O + 9f/R0fb/09P2/9PT9v/S0vb/0ND1/87O8//KyvP/xcXx/8DA8P+7u+7/trbs/6+v6v+qqun/paXn/5+f + 5P+amuL/lJTg/4+P3v+Kitz/hYXa/39/2P96etb/dnXT/3Fx0v9sbdD/aGjO/2VkzP9hYcv/XV3I/1lZ + x/9WVsb/U1PE/1BRw/9NTsD/SkvA/0hJv/9GR77/REW9/0JDvP9AQbv/QEC7/z8/u/87PLn/PD25/0lK + vv9gYcb/dHTN/3V1z/9jZMr/SUu+/zc4rf8zMp7/S0eX/2ljmv+Lhaj/saq4/83HyP/v7On/0MrK/8e+ + vv+zrKz/MTIyaQAAAAIAAAAIAAAAAwAAAAEAAAAAAAAAAP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8AXV1dAGFhYVvCwMD//Pr6//Ty8v/08vL/8O7s//Du + 6v/p5N7/3NbR/8vFxv+wq7r/mZa8/4GAwP99ftH/h4jf/5qa6/+np+//qanu/6Wl7f+goOv/oaHr/6am + 7P+rq+7/sLDv/7W17/+5ufH/vb3y/8HB8v/FxfP/yMjz/8rK9P/MzPT/zMz0/8zM9P/KyvT/x8f0/8TE + 8v/AwPD/vLzv/7e37f+ysuz/ra3r/6io6f+iouf/nZ3l/5iY4/+Tk+L/jo7g/4mJ3f+EhNv/f3/a/3p6 + 1/91ddX/cXHU/2xs0f9oaND/ZWXP/2FhzP9dXcv/WlrJ/1dXyP9UVMf/UVHF/05PxP9LTML/SUrB/0ZH + wf9FRsD/REW+/0FCvv8+P7z/QEC9/1NUxP9rbM3/eHjS/2xsz/9PUML/OTqv/zo5nv9dWJj/j4mp/8C5 + wP/e2db/8Ozk/+3o4//n4uD/3tnY/8nCwv/FvLz/xr6+/3Z0dMsNDQ0SAAAABAAAAAMAAAABAAAAAAAA + AAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wBdXV0AYWFhAGlpaYi9vLz/8/Dw//n29v/39PT/9PHx//Tx8f/18vL/8e7t/+/s6f/l4Nv/0cvL/7ex + vf+YlLv/hoXG/4iJ2f+amun/q6vw/7Cw8P+srO3/p6ft/6io7f+srO3/sbHv/7W18P+5ufH/vLzx/8DA + 8v/CwvP/xMTz/8bG8//GxvP/xcXz/8XF8//CwvP/v7/y/7u78f+3t+//s7Pu/6+v7P+qqur/paXp/6Cg + 6P+bm+b/l5fk/5KS4v+NjeD/h4ff/4OD3f9+ftr/eXnZ/3V11/9xcdb/bGzT/2hp0v9kZdH/YGHO/15e + zP9aWsz/V1fK/1RUyf9RUcj/T0/G/0xMxf9KS8T/SEnD/0ZGwv9CQ8D/Q0TB/1VWxv9wcM//eHnU/2Rl + zv9FRrv/Ozuk/1lVm/+Ri6n/ycPG/+rl4P/u6+X/49/d/9TOzv/KwsL/xr6+/8S7u//Hvb3/yb+//7+3 + t/+Afn7eGBkZMQ0NDQAAAAADAAAAAQAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AF1dXQBhYWEAaWlpAGFhYU+HhobErays98G/ + v/7Z1tb/6OXl//Hu7v/08fH/8O3t//Hu7//y7+//7uvo/+Pd2P/KxMX/qaO5/5COwv+Li9T/m5vm/7Cw + 8f+1tfD/sbHv/6ys7v+tre7/sbHv/7W18P+4uPD/u7vx/7298f++vvL/v7/y/7+/8v+/v/L/vr7y/7y8 + 8f+6uvH/trbw/7Oz7/+vr+7/q6vs/6am6/+ioun/nZ7o/5ma5v+UleX/kJDj/4uL4f+Ght//goLe/319 + 3P95edr/dXXZ/3Bw1v9sbNX/aGjU/2Rl0v9hYtH/Xl7P/1pbzv9XWMz/VFTL/1JSyv9PUMj/TU3H/0tL + xv9GR8T/R0fE/1dXyf9xcdH/eHjW/19gzf9CQ7f/RkOg/3ZxoP+4sbv/5eDa/+/r5f/h3Nr/z8nJ/8e/ + v//Hvb3/ycDA/8W9vf/Aubn/s62t/6OenvyIhYXoUlJSkRMTExwYGRkAAAAAAQAAAAEAAAAAAAAAAAAA + AAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8AXV1dAGFhYQBpaWkAYWFhAF5eXgNcXFwdYWFhQmdnZ2x3dnaclZSU1LSysvvW09P/6+jo//Ht + 7f/t6ur/7+zs/+/s7P/q5+L/1c/M/7Otu/+Rj73/kZHU/6Gh6P+1tfL/uLjx/7Oz7/+uru7/sLDu/7Oz + 7/+2tvD/uLjw/7m58f+6uvH/urrx/7m58f+4uPH/t7fw/7S08P+xse//rq7v/6ur7v+np+z/o6Pr/5+f + 6v+am+j/lpbm/5KS5P+NjuP/iYrj/4WF4P+AgN//fHze/3h42/90dNr/cHDY/2xs1v9oaNX/ZWXU/2Fi + 0/9dXtH/WlvP/1dYzv9VVs3/UlPM/1BQy/9MTcn/SErI/1NVy/9vcNP/envZ/2Fi0P9ERLn/UE2h/4aA + pf/Mxsf/7enj/+fi4P/Uzs3/yMDA/8e/v//JwcH/w7u7/7Krq/+Sjo7td3R0uUxMTIUwMDBYKisrMgME + BA5SUlIAExMTABgZGQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wBdXV0AYWFhAGlpaQBhYWEAXl5eAFxc + XABhYWEAZ2dnAHd2dgBcXFwGXV1dMWhoaHSGhYW9rqys+dbT0//r5+f/7enp/+rn5//u6+v/6+jl/9nT + z/+5s73/mZbA/5CR1f+oqev/ubnz/7m58f+xse//rq7u/7Cw7v+zs+//tLTv/7W17/+0tO//tLTv/7Oz + 7/+ysu//r6/v/62t7v+qqu7/p6fs/6Oj7P+goOv/nJzq/5iX6f+Tk+f/j4/m/4qL5f+Hh+P/g4Ph/35/ + 4P97e9//d3fd/3Nz3P9vb9v/a2vY/2dn1/9kZNb/YWHV/15e0/9bW9L/WFjR/1VWz/9SU87/Tk7M/1FS + zf9patT/fH3b/2lq1f9HSb3/T0yj/5KLqf/V0M3/7enj/+Hd2//NxsX/x76+/8rBwf/Fvb3/sKqq/4uH + h+JhYGCbNDQ0VBQUFBkAAAABTExMADAwMAAqKysAAwQEAFJSUgATExMAGBkZAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AF1dXQBhYWEAaWlpAGFhYQBeXl4AXFxcAGFhYQBnZ2cAd3Z2AFxcXABdXV0AaGhoAIaF + hQBcXFwqamlpf42MjNe/vb3/5ODg/+vn5//o5OT/6+no/+zo5v/Y0s//ta+8/5KQwP+XmNv/r6/u/7u7 + 8/+1tfD/rq7u/6ys7v+uru7/r6/v/6+v7/+vr+//rq7u/62t7v+rq+7/qKjt/6Wl7f+jo+z/oKDr/5yc + 6v+YmOr/lZXp/5GR6P+Njef/iIjm/4WF5f+BgeL/fX7h/3l64P92dt3/cnLd/25v3P9ra9r/Z2fY/2Vl + 2P9hYdf/Xl7V/1tb1P9YWNL/VFXR/1FS0P9hYtT/enrc/3Z23P9SU8f/TEqo/4iCp//Qysr/7enk/97Z + 2f/Kw8P/yL+//8rCwv++t7f/m5eX9WhmZq8zMzNXEBAQEGFgYAA0NDQAFBQUAAAAAABMTEwAMDAwACor + KwADBAQAUlJSABMTEwAYGRkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AXV1dAGFhYQBpaWkAYWFhAF5e + XgBcXFwAYWFhAGdnZwB3dnYAXFxcAF1dXQBoaGgAhoWFAFxcXABqaWkAXV1dCGBgYFB9fHy3sa6u+9zY + 2P/p5eX/5eHh/+rn5//r5+T/083L/6ynuv+Ojsb/n5/j/7W18v+5ufH/r6/u/6mp7f+qqu3/qqrt/6qq + 7f+pqe3/p6fs/6am7P+kpOz/oaHs/5+f6/+cnOr/mZnq/5aW6v+Skun/jo7o/4uL5v+Hh+b/g4Pl/39/ + 5P98e+L/eHjh/3R04P9wcd7/bW7d/2pq3P9naNr/ZGXZ/2Fh2P9eXtf/W1vV/1dX1P9aWtX/c3Pb/39/ + 4P9iYtP/Skmz/3Nvo//Gv8L/7enj/+Dc2//Kw8P/yMDA/8rBwf+3sbH/jImJ5kxLS4chIiIpaGZmADMz + MwAQEBAAYWBgADQ0NAAUFBQAAAAAAExMTAAwMDAAKisrAAMEBABSUlIAExMTABgZGQAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wBdXV0AYWFhAGlpaQBhYWEAXl5eAFxcXABhYWEAZ2dnAHd2dgBcXFwAXV1dAGho + aACGhYUAXFxcAGppaQBdXV0AYGBgAH18fABdXl43dXR0rKuoqPzb19f/5+Li/+Pe3v/q5+b/5+Pf/8rD + xf+dmbv/kpLS/6ip6/+4uPL/sbHv/6en7P+kpOz/paXs/6Sk7P+jo+z/oqLs/6Cg7P+enuv/m5vq/5iY + 6v+Vlen/kpLo/4+P6P+MjOf/iYnn/4WF5v+BgeX/fn7k/3p64/93d+P/c3Ph/3Bv4P9tbN//aWrd/2Zn + 3P9jZNv/YGHa/11e2P9ZWdf/Zmba/35/4f92d+D/UlLE/15bpf+spbT/6OTe/+bh3//Nxsb/x7+//8vC + wv+3sbH/hYOD4EVGRnQQEREVTEtLACEiIgBoZmYAMzMzABAQEABhYGAANDQ0ABQUFAAAAAAATExMADAw + MAAqKysAAwQEAFJSUgATExMAGBkZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AF1dXQBhYWEAaWlpAGFh + YQBeXl4AXFxcAGFhYQBnZ2cAd3Z2AFxcXABdXV0AaGhoAIaFhQBcXFwAamlpAF1dXQBgYGAAfXx8AF1e + XgB1dHQAXFxcNnd2drCxrq7+39vb/+Pe3v/i3t7/6+fm/9/a1f+2sbz/jozA/5eX3v+xsfH/srLv/6Wl + 7P+goOv/oKDs/5+f6/+dnev/nJzr/5qa6v+Xl+n/lZXp/5KS6f+Pj+j/jIzo/4mJ5/+Ghub/g4Pl/39/ + 5f98fOT/eXnj/3V14/9ycuL/b2/g/2xs4P9pad//Zmbe/2Nj3f9eX9v/Xl7a/3Jy3/+Dg+X/ZWfY/09P + s/+Hgaf/19HO/+vo5P/Uzs7/x76+/8vCwv+8trb/i4iI5UVERHYQEBAURUZGABAREQAAAAABAAAAAQAA + AAAAAAAAEBAQAGFgYAA0NDQAFBQUAAAAAABMTEwAMDAwACorKwADBAQAUlJSABMTEwAYGRkAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8AXV1dAGFhYQBpaWkAYWFhAF5eXgBcXFwAYWFhAGdnZwB3dnYAXFxcAF1d + XQBoaGgAhoWFAFxcXABqaWkAXV1dAGBgYAB9fHwAXV5eAHV0dABcXFwAd3Z2AF5eXkWAf3/MwLy8/+Ld + 3f/f2tr/5ODg/+rm4//OyMf/n5u6/5CQ0v+lpuz/sbDx/6Wl7P+bm+r/mprq/5mZ6v+YmOr/lpbp/5SU + 6f+Skuj/j4/n/42N5/+Kiuf/h4fm/4SE5v+BgeX/fn7k/3t74/93d+P/dXXi/3Jy4f9vb+H/bGzh/2lp + 4P9mZt//YWHe/2Rk3v99feT/f37m/1lazP9jYKj/s624/+vm4f/e2dn/yMDA/8rBwf/Fvb3/mpaW901N + TY0REREcRUREABAQEAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAQEBAAYWBgADQ0NAAUFBQAAAAAAExM + TAAwMDAAKisrAAMEBABSUlIAExMTABgZGQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wBdXV0AYWFhAGlp + aQBhYWEAXl5eAFxcXABhYWEAZ2dnAHd2dgBcXFwAXV1dAGhoaACGhYUAXFxcAGppaQBdXV0AYGBgAH18 + fABdXl4AdXR0AFxcXAB3dnYAXl5eAF5fXwdjY2NtlZKS69LNzf/h29v/3djY/+jk4//g29b/tK67/4+N + xf+ZmuP/ra3w/6Wl7f+Xl+n/lZXp/5WV6f+Tk+j/kZHo/4+P6P+MjOf/iorm/4eH5v+Fheb/goLl/39/ + 5P98fOT/eXnj/3Z24/9zc+L/cHDi/25u4P9ra+D/aGjf/2Nj3/9tbeH/hITn/3V24/9YWcD/hH+p/9XO + zP/q5uL/0MrK/8e+vv/Lw8P/raen/2lnZ7ojIyM0TU1NABEREQAAAAABAAAAAQAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAABAQEABhYGAANDQ0ABQUFAAAAAAATExMADAwMAAqKysAAwQEAFJSUgATExMAGBkZAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AF1dXQBhYWEAaWlpAGFhYQBeXl4AXFxcAGFhYQBnZ2cAd3Z2AFxc + XABdXV0AaGhoAIaFhQBcXFwAamlpAF1dXQBgYGAAfXx8AF1eXgB1dHQAXFxcAHd2dgBeXl4AXl9fAGNj + YwBdXV0hcXFxqbKurv/e2Nj/29XV/+Hd3f/o4+D/xr/B/5SSvP+Njtn/pqfu/6Sk7f+Vlen/kJDo/4+P + 6P+Ojuj/jIzn/4qK5v+Hh+b/hITm/4OD5f+AgOT/fX3k/3t75P94eOP/dXXj/3Jy4f9wcOH/bW3h/2pq + 4P9mZt//dHTi/4eH6f9sbdv/X1+0/6Odsf/l4Nv/4dzb/8jAwP/KwcH/wbq6/4iFhec4ODhnAQEBBiMj + IwAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQAGFgYAA0NDQAFBQUAAAA + AABMTEwAMDAwACorKwADBAQAUlJSABMTEwAYGRkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AXV1dAGFh + YQBpaWkAYWFhAF5eXgBcXFwAYWFhAGdnZwB3dnYAXFxcAF1dXQBoaGgAhoWFAFxcXABqaWkAXV1dAGBg + YAB9fHwAXV5eAHV0dABcXFwAd3Z2AF5eXgBeX18AY2NjAF1dXQBxcXEAYGBgWJCOjufRy8v/3dbW/9vV + 1f/o5OP/19HN/6GcuP+EhM3/nZ3q/6Sj7f+Skuj/i4vn/4uL5/+Jief/h4fm/4WF5v+Dg+b/gIDl/35+ + 5P98fOP/eXnj/3Z24/90dOL/cXHh/29v4f9ra+D/aWng/3t75P+Ghun/ZGXS/2tprP+/uL7/6ubh/9bQ + z//Gvb3/y8PD/6ynp/9fX1+wExQUIzg4OAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAQEBAAYWBgADQ0NAAUFBQAAAAAAExMTAAwMDAAKisrAAMEBABSUlIAExMTABgZ + GQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wBdXV0AYWFhAGlpaQBhYWEAXl5eAFxcXABhYWEAZ2dnAHd2 + dgBcXFwAXV1dAGhoaACGhYUAXFxcAGppaQBdXV0AYGBgAH18fABdXl4AdXR0AFxcXAB3dnYAXl5eAF5f + XwBjY2MAXV1dAHFxcQBgYGAAXV1dIXR0dLa6tbX/3NXV/9fR0f/j39//4NrV/6+puv+Dg8X/lJTl/6Gh + 7v+QkOj/hobm/4aG5v+Fheb/g4Pl/4GB5f9+fuT/fHzk/3p65P94eOP/dXXj/3Jy4v9xceH/bW3g/2xs + 4P+AgOb/hITo/2Bhyf99eqv/0cvJ/+fj4P/Nxsb/yL+//8a9vf+QjY3wPT09cAAAAAYTFBQAAAAAAgAA + AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEABhYGAANDQ0ABQU + FAAAAAAATExMADAwMAAqKysAAwQEAFJSUgATExMAGBkZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AF1d + XQBhYWEAaWlpAGFhYQBeXl4AXFxcAGFhYQBnZ2cAd3Z2AFxcXABdXV0AaGhoAIaFhQBcXFwAamlpAF1d + XQBgYGAAfXx8AF1eXgB1dHQAXFxcAHd2dgBeXl4AXl9fAGNjYwBdXV0AcXFxAGBgYABdXV0AX2BgAWRk + ZHignZ3519HR/9bPz//e2dn/5eHd/763vv+FhL//iovg/56e7f+Rken/hITl/4GB5f+AgOX/fn7k/319 + 5P97e+T/eXnj/3Z24/90dOL/cXHi/21t4f9zc+L/hobn/4GB5v9hYcL/kYyu/97Y0//i3t3/x7+//8rB + wf+6tLT/dXNzzxYWFjY9PT0AAAAAAgAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAEBAQAGFgYAA0NDQAFBQUAAAAAABMTEwAMDAwACorKwADBAQAUlJSABMT + EwAYGRkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8AXV1dAGFhYQBpaWkAYWFhAF5eXgBcXFwAYWFhAGdn + ZwB3dnYAXFxcAF1dXQBoaGgAhoWFAFxcXABqaWkAXV1dAGBgYAB9fHwAXV5eAHV0dABcXFwAd3Z2AF5e + XgBeX18AY2NjAF1dXQBxcXEAYGBgAF1dXQBfYGAAZGRkAF5eXkWLiYnjzsjI/9XPz//Y09P/5+Pg/8jB + w/+Jh7v/g4Pb/5qa7P+Wlun/h4fm/39/5P97e+T/eXnk/3h44/92duP/c3Pi/3Fx4v90dOL/f3/l/4yM + 6f97e+L/ZGS+/6Casf/l4Nr/29bV/8W9vf/KwcH/raen/1pZWaQREhIYFhYWAAAAAAMAAAABAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAAYWBgADQ0 + NAAUFBQAAAAAAExMTAAwMDAAKisrAAMEBABSUlIAExMTABgZGQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wBdXV0AYWFhAGlpaQBhYWEAXl5eAFxcXABhYWEAZ2dnAHd2dgBcXFwAXV1dAGhoaACGhYUAXFxcAGpp + aQBdXV0AYGBgAH18fABdXl4AdXR0AFxcXAB3dnYAXl5eAF5fXwBjY2MAXV1dAHFxcQBgYGAAXV1dAF9g + YABkZGQAXl5eAF5eXiF5eHjFwby8/9bOzv/Uzc3/5uLf/9DJyP+Sj7j/eXrQ/46O6P+YmOz/kpLp/4iI + 5v+CguX/f3/k/35+5P9/f+T/hYXm/42N6f+Jier/b2/a/2tquP+uqLf/6OPd/9XQ0P/EvLz/ycDA/52Y + mPpAQEB6AAAABRESEgAAAAADAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEABhYGAANDQ0ABQUFAAAAAAATExMADAwMAAqKysAAwQEAFJS + UgATExMAGBkZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AF1dXQBhYWEAaWlpAGFhYQBeXl4AXFxcAGFh + YQBnZ2cAd3Z2AFxcXABdXV0AaGhoAIaFhQBcXFwAamlpAF1dXQBgYGAAfXx8AF1eXgB1dHQAXFxcAHd2 + dgBeXl4AXl9fAGNjYwBdXV0AcXFxAGBgYABdXV0AX2BgAGRkZABeXl4AXl5eAF5fXw5ubm6itbCw/9TN + zf/Ry8v/49/e/9rU0P+oo7r/eHfB/3d32P+IiOj/kZHr/5GR6/+QkOn/j4/p/46O6v+IiOn/dHXe/2Rk + x/+BfrP/xb/C/+fi3v/Qysr/xby8/8e+vv+LiIjrMTIyVkBAQAAAAAADAAAAAwAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQAGFg + YAA0NDQAFBQUAAAAAABMTEwAMDAwACorKwADBAQAUlJSABMTEwAYGRkAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8AXV1dAGFhYQBpaWkAYWFhAF5eXgBcXFwAYWFhAGdnZwB3dnYAXFxcAF1dXQBoaGgAhoWFAFxc + XABqaWkAXV1dAGBgYAB9fHwAXV5eAHV0dABcXFwAd3Z2AF5eXgBeX18AY2NjAF1dXQBxcXEAYGBgAF1d + XQBfYGAAZGRkAF5eXgBeXl4AXl9fAG5ubgBmZmaGqqWl/9TNzf/Ox8f/3NfW/+Tf2v/Fv8L/lpO3/3t6 + v/9ycs7/d3fX/3Nz2v90dNn/b2/S/2xsxP9/fbT/q6a4/9zX0//i3tv/ysPD/8e9vf/Curr/fnx83RYX + FzkxMjIAAAAABAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAAYWBgADQ0NAAUFBQAAAAAAExMTAAwMDAAKisrAAME + BABSUlIAExMTABgZGQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wBdXV0AYWFhAGlpaQBhYWEAXl5eAFxc + XABhYWEAZ2dnAHd2dgBcXFwAXV1dAGhoaACGhYUAXFxcAGppaQBdXV0AYGBgAH18fABdXl4AdXR0AFxc + XAB3dnYAXl5eAF5fXwBjY2MAXV1dAHFxcQBgYGAAXV1dAF9gYABkZGQAXl5eAF5eXgBeX18Abm5uAGZm + ZgBjY2NrmpeX+c/Hx//Px8f/0crK/9/b2f/f2tX/zsjH/7Suu/+fmrf/mJS5/5uXuP+knrX/xL7B/9nT + z//j39v/1M3N/8W8vP/JwMD/urOz/3RycscWFhYkFhcXAAAAAAMAAAABAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQ + EABhYGAANDQ0ABQUFAAAAAAATExMADAwMAAqKysAAwQEAFJSUgATExMAGBkZAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AF1dXQBhYWEAaWlpAGFhYQBeXl4AXFxcAGFhYQBnZ2cAd3Z2AFxcXABdXV0AaGhoAIaF + hQBcXFwAamlpAF1dXQBgYGAAfXx8AF1eXgB1dHQAXFxcAHd2dgBeXl4AXl9fAGNjYwBdXV0AcXFxAGBg + YABdXV0AX2BgAGRkZABeXl4AXl5eAF5fXwBubm4AZmZmAGNjYwBfYGA+gX9/17iysv/PyMj/zMTE/9DI + yP/X0dH/3tnW/9/a1v/c1tH/3dfS/+Db1//a1NP/0MrJ/8e+vv/Iv7//xb29/6Oenv1PTk6SDxAQDhYW + FgAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQAGFgYAA0NDQAFBQUAAAAAABMTEwAMDAwACor + KwADBAQAUlJSABMTEwAYGRkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AXV1dAGFhYQBpaWkAYWFhAF5e + XgBcXFwAYWFhAGdnZwB3dnYAXFxcAF1dXQBoaGgAhoWFAFxcXABqaWkAXV1dAGBgYAB9fHwAXV5eAHV0 + dABcXFwAd3Z2AF5eXgBeX18AY2NjAF1dXQBxcXEAYGBgAF1dXQBfYGAAZGRkAF5eXgBeXl4AXl9fAG5u + bgBmZmYAY2NjAF9gYABfX18OZ2dnf5CNjeu5s7P/ysLC/83ExP/KwcH/ysLC/8zExP/Kw8P/x7+//8e/ + v//JwMD/w7u7/6ulpf9vbW3DKysrQE9OTgAPEBAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAQEBAAYWBgADQ0NAAUFBQAAAAAAExMTAAwMDAAKisrAAMEBABSUlIAExMTABgZGQAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wBdXV0AYWFhAGlpaQBhYWEAXl5eAFxcXABhYWEAZ2dnAHd2dgBcXFwAXV1dAGho + aACGhYUAXFxcAGppaQBdXV0AYGBgAH18fABdXl4AdXR0AFxcXAB3dnYAXl5eAF5fXwBjY2MAXV1dAHFx + cQBgYGAAXV1dAF9gYABkZGQAXl5eAF5eXgBeX18Abm5uAGZmZgBjY2MAX2BgAF9fXwBnZ2cAX19fGWdn + Z3iBf3/RnZmZ+rGrq/+9tbX/wLi4/7+3t/+2r6//pqGh/42Jie1pZ2epLi4uSgMEBAUrKysAT05OAA8Q + EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEABhYGAANDQ0ABQUFAAAAAAATExMADAw + MAAqKysAAwQEAFJSUgATExMAGBkZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AF1dXQBhYWEAaWlpAGFh + YQBeXl4AXFxcAGFhYQBnZ2cAd3Z2AFxcXABdXV0AaGhoAIaFhQBcXFwAamlpAF1dXQBgYGAAfXx8AF1e + XgB1dHQAXFxcAHd2dgBeXl4AXl9fAGNjYwBdXV0AcXFxAGBgYABdXV0AX2BgAGRkZABeXl4AXl5eAF5f + XwBubm4AZmZmAGNjYwBfYGAAX19fAGdnZwBfX18AZ2dnAF5fXyhlZGRgcnBwlHp4eLh8enrBfHp6wHZ1 + dalwb298Ojo6RA0ODg8uLi4AAwQEACsrKwBPTk4ADxAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAEBAQAGFgYAA0NDQAFBQUAAAAAABMTEwAMDAwACorKwADBAQAUlJSABMTEwAYGRkAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A/////////////////////////////////////////////////////4// + //////////////////gA//////////////////+AAB/////////////////+AAAH//////////////// + +AAAAf////////////////AAAAB////////////////AAAAAP///////////////gAAAAB////////// + /////wAAAAAH//////////////4AAAAAA//////////////8AAAAAAH/////////////+AAAAAAA//// + //////////AAAAAAAH/////////////gAAAAAAA/////////////wAAAAAAAH////////////4AAAAAA + AA////////////8AAAAAAAAH////////////AAAAAAAAB////////////AAAAAAAAAP///////////wA + AAAAAAAB///////////xAAAAAAAAAP//////////8gAAAAAAAAD//////////+QAAAAAAAAAf/////// + ///gAAAAAAAAAD//////////wAAAAAAAAAAf/////////5AAAAAAAAAAD/////////+gAAAAAAAAAA// + ////////QAAAAAAAAAAP/////////0AAAAAAAAAAB/////////6AAAAAAAAAAAP////////9AAAAAAAA + AAAB////////+QAAAAAAAAAAAf////////oAAAAAAAAAAAD////////0AAAAAAAAAAAA////////9AAA + AAAAAAAAAH///////+gAAAAAAAAAAAA////////AAAAAAAAAAAAAP///////0AAAAAAAAAAAAD////// + /6AAAAAAAAAAAAAf//////+gAAAAAAAAAAAAD///////QAAAAAAAAAAAAA///////0AAAAAAAAAAAAAH + //////6AAAAAAAAAAAAAB//////+gAAAAAAAAAAAAAf//////wAAAAAAAAAAAAAD//////8AAAAAAAAA + AAAAA//////+AAAAAAAAAAAAAAH//////gAAAAAAAAAAAAAB//////wAAAAAAAAAAAAAAf/////8AAAA + AAAAAAAAAAD/////+AAAAAAAAAAAAAAA//////gAAAAAAAAAAAAAAH/////4AAAAAAAAAAAAAAB///// + 8AAAAAAAAAAAAAAAf/////AAAAAAAAAAAAAAAD/////wAAAAAAAAAAAAAAA/////4AAAAAAAAAAAAAAA + P////+AAAAAAAAAAAAAAAD/////gAAAAAAAAAAAAAAA/////4AAAAAAAAAAAAAAAH////8AAAAAAAAAA + AAAAAB/////AAAAAAAAAAAAAAAAf////wAAAAAAAAAAAAAAAH////8AAAAAAAAAAAAAAAB/////AAAAA + AAAAAAAAAAAf////gAAAAAAAAAAAAAAAH////4AAAAAAAAAAAAAAAA////+AAAAAAAAAAAAAAAAP//// + gAAAAAAAAAAAAAAAD////4AAAAAAAAAAAAAAAA////+AAAAAAAAAAAAAAAAP////gAAAAAAAAAAAAAAA + D////4AAAAAAAAAAAAAAAA////+AAAAAAAAAAAAAAAAP////gAAAAAAAAAAAAAAAD////4AAAAAAAAAA + AAAAAA////+AAAAAAAAAAAAAAAAP////gAAAAAAAAAAAAAAAD////4AAAAAAAAAAAAAAAA////+AAAAA + AAAAAAAAAAAP////gAAAAAAAAAAAAAAAD////4AAAAAAAAAAAAAAAA////+AAAAAAAAAAAAAAAAP//// + gAAAAAAAAAAAAAAAD////4AAAAAAAAAAAAAAAA////+AAAAAAAAAAAAAAAAP////gAAAAAAAAAAAAAAA + D////4AAAAAAAAAAAAAAAA////+AAAAAAAAAAAAAAAAP////gAAAAAAAAAAAAAAAD////4AAAAAAAAAA + AAAAAB////+AAAAAAAAAAAAAAAAf////gAAAAAAAAAAAAAAAH////4AAAAAAAAAAAAAAAB////+AAAAA + AAAAAAAAAAAf////gAAAAAAAAAAAAAAAH////4AAAAAAAAAAAAAAAB////+AAAAAAAAAAAAAAAA///// + wAAAAAAAAAAAAAAAf////+AAAAAAAAAAAAAABP/////wAAAAAAAAAAAAAAn/////+AAAAAAAAAAAAAA/ + ///////AAAAAAAAAAAAD/////////AAAAAAAAAAAP/////////8AAAAAAAAAAf//////////4AAAAAAA + AAf///////////gAAAAAAAAZ///////////+AAAAAAAAZ////////////wAAAAAAAZ/////////////A + AAAAAAJ/////////////8AAAAAAJ//////////////gAAAAAE//////////////8AAAAAE////////// + /////wAAAACf//////////////+AAAABP///////////////wAAABP////////////////AAAAn///// + ///////////4AAAT/////////////////AAAL/////////////////4AAN//////////////////gAH/ + /////////////////+AH//////////////////////////////////////////////////////////// + //////////////////////////////////8= + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/SecureShare/CreateShareEncryptedFileForm.Designer.cs b/Demo_Source_Code/CSharpDemo/SecureShare/CreateShareEncryptedFileForm.Designer.cs new file mode 100644 index 0000000..db83445 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/SecureShare/CreateShareEncryptedFileForm.Designer.cs @@ -0,0 +1,344 @@ +namespace FileProtector +{ + partial class ShareEncryptedFileCreationForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ShareEncryptedFileCreationForm)); + this.button_CreateShareEncryptedFile = new System.Windows.Forms.Button(); + this.label2 = new System.Windows.Forms.Label(); + this.label1 = new System.Windows.Forms.Label(); + this.textBox_FileName = new System.Windows.Forms.TextBox(); + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.button_OpenFile = new System.Windows.Forms.Button(); + this.label3 = new System.Windows.Forms.Label(); + this.textBox_ExcludeUserNames = new System.Windows.Forms.TextBox(); + this.label4 = new System.Windows.Forms.Label(); + this.textBox_IncludeUserNames = new System.Windows.Forms.TextBox(); + this.label5 = new System.Windows.Forms.Label(); + this.label_AccessFlags = new System.Windows.Forms.Label(); + this.dateTimePicker_ExpireTime = new System.Windows.Forms.DateTimePicker(); + this.label12 = new System.Windows.Forms.Label(); + this.textBox_FileAccessFlags = new System.Windows.Forms.TextBox(); + this.button_FileAccessFlags = new System.Windows.Forms.Button(); + this.textBox_ExcludeProcessNames = new System.Windows.Forms.TextBox(); + this.label11 = new System.Windows.Forms.Label(); + this.textBox_IncludeProcessNames = new System.Windows.Forms.TextBox(); + this.label10 = new System.Windows.Forms.Label(); + this.textBox1 = new System.Windows.Forms.TextBox(); + this.label6 = new System.Windows.Forms.Label(); + this.textBox2 = new System.Windows.Forms.TextBox(); + this.label8 = new System.Windows.Forms.Label(); + this.button1 = new System.Windows.Forms.Button(); + this.groupBox1.SuspendLayout(); + this.SuspendLayout(); + // + // button_CreateShareEncryptedFile + // + this.button_CreateShareEncryptedFile.Location = new System.Drawing.Point(509, 418); + this.button_CreateShareEncryptedFile.Name = "button_CreateShareEncryptedFile"; + this.button_CreateShareEncryptedFile.Size = new System.Drawing.Size(75, 23); + this.button_CreateShareEncryptedFile.TabIndex = 8; + this.button_CreateShareEncryptedFile.Text = "Start"; + this.button_CreateShareEncryptedFile.UseVisualStyleBackColor = true; + this.button_CreateShareEncryptedFile.Click += new System.EventHandler(this.button_CreateShareEncryptedFile_Click); + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(16, 93); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(104, 13); + this.label2.TabIndex = 2; + this.label2.Text = "Share file expire time"; + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(16, 13); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(100, 13); + this.label1.TabIndex = 1; + this.label1.Text = "Input file name path"; + // + // textBox_FileName + // + this.textBox_FileName.Location = new System.Drawing.Point(213, 13); + this.textBox_FileName.Name = "textBox_FileName"; + this.textBox_FileName.Size = new System.Drawing.Size(242, 20); + this.textBox_FileName.TabIndex = 0; + this.textBox_FileName.Text = "c:\\test\\test.txt"; + // + // groupBox1 + // + this.groupBox1.Controls.Add(this.button1); + this.groupBox1.Controls.Add(this.textBox2); + this.groupBox1.Controls.Add(this.label8); + this.groupBox1.Controls.Add(this.textBox1); + this.groupBox1.Controls.Add(this.label6); + this.groupBox1.Controls.Add(this.button_OpenFile); + this.groupBox1.Controls.Add(this.label3); + this.groupBox1.Controls.Add(this.textBox_ExcludeUserNames); + this.groupBox1.Controls.Add(this.label4); + this.groupBox1.Controls.Add(this.textBox_IncludeUserNames); + this.groupBox1.Controls.Add(this.label5); + this.groupBox1.Controls.Add(this.label_AccessFlags); + this.groupBox1.Controls.Add(this.dateTimePicker_ExpireTime); + this.groupBox1.Controls.Add(this.label12); + this.groupBox1.Controls.Add(this.textBox_FileAccessFlags); + this.groupBox1.Controls.Add(this.button_FileAccessFlags); + this.groupBox1.Controls.Add(this.textBox_ExcludeProcessNames); + this.groupBox1.Controls.Add(this.label11); + this.groupBox1.Controls.Add(this.textBox_IncludeProcessNames); + this.groupBox1.Controls.Add(this.label10); + this.groupBox1.Controls.Add(this.label2); + this.groupBox1.Controls.Add(this.textBox_FileName); + this.groupBox1.Controls.Add(this.label1); + this.groupBox1.Location = new System.Drawing.Point(12, 12); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size(572, 386); + this.groupBox1.TabIndex = 11; + this.groupBox1.TabStop = false; + // + // button_OpenFile + // + this.button_OpenFile.Location = new System.Drawing.Point(461, 11); + this.button_OpenFile.Name = "button_OpenFile"; + this.button_OpenFile.Size = new System.Drawing.Size(75, 23); + this.button_OpenFile.TabIndex = 64; + this.button_OpenFile.Text = "browse"; + this.button_OpenFile.UseVisualStyleBackColor = true; + this.button_OpenFile.Click += new System.EventHandler(this.button_OpenFile_Click); + // + // label3 + // + this.label3.AutoSize = true; + this.label3.Font = new System.Drawing.Font("Microsoft Sans Serif", 6.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.label3.Location = new System.Drawing.Point(211, 233); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(215, 12); + this.label3.TabIndex = 63; + this.label3.Text = "(Seperate with \';\' ,user name format \"domain\\user\" )"; + // + // textBox_ExcludeUserNames + // + this.textBox_ExcludeUserNames.Location = new System.Drawing.Point(213, 253); + this.textBox_ExcludeUserNames.Name = "textBox_ExcludeUserNames"; + this.textBox_ExcludeUserNames.Size = new System.Drawing.Size(242, 20); + this.textBox_ExcludeUserNames.TabIndex = 62; + // + // label4 + // + this.label4.AutoSize = true; + this.label4.Location = new System.Drawing.Point(16, 253); + this.label4.Name = "label4"; + this.label4.Size = new System.Drawing.Size(140, 13); + this.label4.TabIndex = 61; + this.label4.Text = "Disallow access user names"; + // + // textBox_IncludeUserNames + // + this.textBox_IncludeUserNames.Location = new System.Drawing.Point(213, 213); + this.textBox_IncludeUserNames.Name = "textBox_IncludeUserNames"; + this.textBox_IncludeUserNames.Size = new System.Drawing.Size(242, 20); + this.textBox_IncludeUserNames.TabIndex = 60; + // + // label5 + // + this.label5.AutoSize = true; + this.label5.Location = new System.Drawing.Point(16, 213); + this.label5.Name = "label5"; + this.label5.Size = new System.Drawing.Size(126, 13); + this.label5.TabIndex = 59; + this.label5.Text = "Allow access user names"; + // + // label_AccessFlags + // + this.label_AccessFlags.AutoSize = true; + this.label_AccessFlags.Location = new System.Drawing.Point(16, 333); + this.label_AccessFlags.Name = "label_AccessFlags"; + this.label_AccessFlags.Size = new System.Drawing.Size(120, 13); + this.label_AccessFlags.TabIndex = 12; + this.label_AccessFlags.Text = "File access control flags"; + // + // dateTimePicker_ExpireTime + // + this.dateTimePicker_ExpireTime.CustomFormat = "yyyy-MM-dd HH:mm:ss"; + this.dateTimePicker_ExpireTime.Format = System.Windows.Forms.DateTimePickerFormat.Custom; + this.dateTimePicker_ExpireTime.Location = new System.Drawing.Point(213, 93); + this.dateTimePicker_ExpireTime.Name = "dateTimePicker_ExpireTime"; + this.dateTimePicker_ExpireTime.Size = new System.Drawing.Size(242, 20); + this.dateTimePicker_ExpireTime.TabIndex = 58; + // + // label12 + // + this.label12.AutoSize = true; + this.label12.Font = new System.Drawing.Font("Microsoft Sans Serif", 6.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.label12.Location = new System.Drawing.Point(211, 154); + this.label12.Name = "label12"; + this.label12.Size = new System.Drawing.Size(209, 12); + this.label12.TabIndex = 57; + this.label12.Text = "( Seperate with \';\' , process format \"notepad.exe\" )"; + // + // textBox_FileAccessFlags + // + this.textBox_FileAccessFlags.Location = new System.Drawing.Point(213, 333); + this.textBox_FileAccessFlags.Name = "textBox_FileAccessFlags"; + this.textBox_FileAccessFlags.Size = new System.Drawing.Size(242, 20); + this.textBox_FileAccessFlags.TabIndex = 11; + this.textBox_FileAccessFlags.Text = "0"; + // + // button_FileAccessFlags + // + this.button_FileAccessFlags.Location = new System.Drawing.Point(461, 333); + this.button_FileAccessFlags.Name = "button_FileAccessFlags"; + this.button_FileAccessFlags.Size = new System.Drawing.Size(41, 20); + this.button_FileAccessFlags.TabIndex = 14; + this.button_FileAccessFlags.Text = "..."; + this.button_FileAccessFlags.UseVisualStyleBackColor = true; + this.button_FileAccessFlags.Click += new System.EventHandler(this.button_FileAccessFlags_Click); + // + // textBox_ExcludeProcessNames + // + this.textBox_ExcludeProcessNames.Location = new System.Drawing.Point(213, 173); + this.textBox_ExcludeProcessNames.Name = "textBox_ExcludeProcessNames"; + this.textBox_ExcludeProcessNames.Size = new System.Drawing.Size(242, 20); + this.textBox_ExcludeProcessNames.TabIndex = 56; + // + // label11 + // + this.label11.AutoSize = true; + this.label11.Location = new System.Drawing.Point(16, 173); + this.label11.Name = "label11"; + this.label11.Size = new System.Drawing.Size(160, 13); + this.label11.TabIndex = 55; + this.label11.Text = "Disallow access process names"; + // + // textBox_IncludeProcessNames + // + this.textBox_IncludeProcessNames.Location = new System.Drawing.Point(213, 133); + this.textBox_IncludeProcessNames.Name = "textBox_IncludeProcessNames"; + this.textBox_IncludeProcessNames.Size = new System.Drawing.Size(242, 20); + this.textBox_IncludeProcessNames.TabIndex = 54; + // + // label10 + // + this.label10.AutoSize = true; + this.label10.Location = new System.Drawing.Point(16, 133); + this.label10.Name = "label10"; + this.label10.Size = new System.Drawing.Size(143, 13); + this.label10.TabIndex = 53; + this.label10.Text = "Allow access process names"; + // + // textBox1 + // + this.textBox1.Location = new System.Drawing.Point(213, 53); + this.textBox1.Name = "textBox1"; + this.textBox1.Size = new System.Drawing.Size(242, 20); + this.textBox1.TabIndex = 65; + this.textBox1.Text = "c:\\test\\test.txt"; + // + // label6 + // + this.label6.AutoSize = true; + this.label6.Location = new System.Drawing.Point(16, 53); + this.label6.Name = "label6"; + this.label6.Size = new System.Drawing.Size(108, 13); + this.label6.TabIndex = 66; + this.label6.Text = "Output file name path"; + // + // textBox2 + // + this.textBox2.Location = new System.Drawing.Point(212, 293); + this.textBox2.Name = "textBox2"; + this.textBox2.Size = new System.Drawing.Size(242, 20); + this.textBox2.TabIndex = 68; + // + // label8 + // + this.label8.AutoSize = true; + this.label8.Location = new System.Drawing.Point(16, 293); + this.label8.Name = "label8"; + this.label8.Size = new System.Drawing.Size(128, 13); + this.label8.TabIndex = 67; + this.label8.Text = "Allow access computer Id"; + // + // button1 + // + this.button1.Location = new System.Drawing.Point(461, 293); + this.button1.Name = "button1"; + this.button1.Size = new System.Drawing.Size(41, 20); + this.button1.TabIndex = 69; + this.button1.Text = "..."; + this.button1.UseVisualStyleBackColor = true; + // + // ShareEncryptedFileCreationForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(596, 453); + this.Controls.Add(this.groupBox1); + this.Controls.Add(this.button_CreateShareEncryptedFile); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.MaximizeBox = false; + this.Name = "ShareEncryptedFileCreationForm"; + this.Text = "Create share encrypted file"; + this.groupBox1.ResumeLayout(false); + this.groupBox1.PerformLayout(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.Label label2; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.TextBox textBox_FileName; + private System.Windows.Forms.Button button_CreateShareEncryptedFile; + private System.Windows.Forms.GroupBox groupBox1; + private System.Windows.Forms.TextBox textBox_FileAccessFlags; + private System.Windows.Forms.Label label_AccessFlags; + private System.Windows.Forms.Button button_FileAccessFlags; + private System.Windows.Forms.TextBox textBox_ExcludeProcessNames; + private System.Windows.Forms.Label label11; + private System.Windows.Forms.TextBox textBox_IncludeProcessNames; + private System.Windows.Forms.Label label10; + private System.Windows.Forms.Label label12; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.TextBox textBox_ExcludeUserNames; + private System.Windows.Forms.Label label4; + private System.Windows.Forms.TextBox textBox_IncludeUserNames; + private System.Windows.Forms.Label label5; + private System.Windows.Forms.DateTimePicker dateTimePicker_ExpireTime; + private System.Windows.Forms.Button button_OpenFile; + private System.Windows.Forms.TextBox textBox1; + private System.Windows.Forms.Label label6; + private System.Windows.Forms.Button button1; + private System.Windows.Forms.TextBox textBox2; + private System.Windows.Forms.Label label8; + } +} \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/SecureShare/CreateShareEncryptedFileForm.cs b/Demo_Source_Code/CSharpDemo/SecureShare/CreateShareEncryptedFileForm.cs new file mode 100644 index 0000000..c870e3c --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/SecureShare/CreateShareEncryptedFileForm.cs @@ -0,0 +1,132 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2012 EaseFilter Technologies Inc. +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +/////////////////////////////////////////////////////////////////////////////// + +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; + +using EaseFilter.CommonObjects; + +namespace FileProtector +{ + public partial class ShareEncryptedFileCreationForm : Form + { + public ShareEncryptedFileCreationForm() + { + InitializeComponent(); + textBox_FileAccessFlags.Text = FilterAPI.ALLOW_MAX_RIGHT_ACCESS.ToString(); + dateTimePicker_ExpireTime.Value = DateTime.Now + TimeSpan.FromDays(1); + } + + private void button_FileAccessFlags_Click(object sender, EventArgs e) + { + OptionForm optionForm = new OptionForm(OptionForm.OptionType.Access_Flag, textBox_FileAccessFlags.Text); + + if (optionForm.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + textBox_FileAccessFlags.Text = optionForm.AccessFlags.ToString(); + } + } + + + private void button_CreateShareEncryptedFile_Click(object sender, EventArgs e) + { + if (textBox_FileName.Text.Trim().Length == 0) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("The file name can't be empty.", "Create share encrypted file", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + if (textBox_PassPhrase.Text.Trim().Length == 0) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("The pass phrase can't be empty.", "Create share encrypted file", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + AESAccessPolicy policy = new AESAccessPolicy(); + + if (textBox_IncludeProcessNames.Text.Trim().Length > 0 || textBox_ExcludeProcessNames.Text.Trim().Length > 0) + { + policy.AESFlags |= (uint)AESFlags.Flags_Enabled_Check_ProcessName; + } + + if (textBox_IncludeUserNames.Text.Trim().Length > 0 || textBox_ExcludeUserNames.Text.Trim().Length > 0) + { + policy.AESFlags |= (uint)AESFlags.Flags_Enabled_Check_UserName; + } + + policy.AESFlags |= (uint)AESFlags.Flags_Enabled_Check_AccessFlags | (uint)AESFlags.Flags_Enabled_Expire_Time; + + string encryptionPassPhrase = textBox_PassPhrase.Text; + uint accessFlags = uint.Parse(textBox_FileAccessFlags.Text); + + policy.AccessFlags = accessFlags; + policy.IncludeProcessNames = textBox_IncludeProcessNames.Text.Trim(); + policy.LengthOfIncludeProcessNames = (uint)textBox_IncludeProcessNames.Text.Length * 2; + policy.ExcludeProcessNames = textBox_ExcludeProcessNames.Text.Trim(); + policy.LengthOfExcludeProcessNames = (uint)textBox_ExcludeProcessNames.Text.Length * 2; + policy.IncludeUserNames = textBox_IncludeUserNames.Text.Trim(); + policy.LengthOfIncludeUserNames = (uint)textBox_IncludeUserNames.Text.Length * 2; + policy.ExcludeUserNames = textBox_ExcludeUserNames.Text.Trim(); + policy.LengthOfExcludeUserNames = (uint)textBox_ExcludeUserNames.Text.Length * 2; + policy.ExpireTime = dateTimePicker_ExpireTime.Value.ToUniversalTime().ToFileTimeUtc(); + + string lastError = string.Empty; + + if (!EncryptionHandler.EncryptFileWithEmbeddedPolicy(textBox_FileName.Text, textBox_PassPhrase.Text, policy, out lastError)) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("Create share encrypted file failed with error:" + lastError, "Process share encrypted file", MessageBoxButtons.OK, MessageBoxIcon.Error); + + return; + } + else + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("Create share encrypted file succeeded.", "Process share encrypted file", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + + } + + + private void checkBox_DisplayPassword_CheckedChanged(object sender, EventArgs e) + { + if (checkBox_DisplayPassword.Checked) + { + textBox_PassPhrase.UseSystemPasswordChar = false; + } + else + { + textBox_PassPhrase.UseSystemPasswordChar = true; + } + } + + private void button_OpenFile_Click(object sender, EventArgs e) + { + OpenFileDialog openFileDialog = new OpenFileDialog(); + + if (openFileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + textBox_FileName.Text = openFileDialog.FileName; + } + } + + + + + } +} diff --git a/Demo_Source_Code/CSharpDemo/SecureShare/CreateShareEncryptedFileForm.resx b/Demo_Source_Code/CSharpDemo/SecureShare/CreateShareEncryptedFileForm.resx new file mode 100644 index 0000000..b5a6f9c --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/SecureShare/CreateShareEncryptedFileForm.resx @@ -0,0 +1,570 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + AAABAAgAEBAAAAEACABoBQAAhgAAABAQAAABACAAaAQAAO4FAAAYGAAAAQAIAMgGAABWCgAAGBgAAAEA + IACICQAAHhEAACAgAAABAAgAqAgAAKYaAAAgIAAAAQAgAKgQAABOIwAAMDAAAAEACACoDgAA9jMAADAw + AAABACAAqCUAAJ5CAAAoAAAAEAAAACAAAAABAAgAAAAAAEABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP// + /wCec3MA4LS0AIBOTgC9lJQA7NnZAJ+MjADFq6sAkmBgAOPHxwD38fEArYGBAJZ/fwDz5eUA7b29AMef + nwC3n58Ai2pqAIhXVwCxi4sA0qenANK0tADbvb0A6NDQALCWlgCRc3MApHp6AL+MjACig4MAiF5eAKiI + iACteXkAvqOjAMKamgDKpaUAm4aGAPv29gCAVlYA58LCAN/CwgDv3t4A5MzMANawsACGUFAA7dPTAOC6 + ugCbfHwAk3t7ALOSkgCkcnIA/fv7AMSjowC5m5sA3LGxAItmZgDw4uIAzaioAMeZmQCMYGAAlXFxAL6Y + mADq1tYA4b+/AKSGhgCziIgA0KSkAMGdnQCIW1sApImJAL6goADnysoA6dPTAIpZWQDmzs4A5cXFAOHF + xQCDT08A3MHBAKd7ewDBl5cAiVVVAPHg4ADjysoA5sjIAODHxwDev78A2ru7AJyIiAClg4MAzaWlAKR0 + dACkeHgA3r29AOzX1wCJZ2cA5tHRAMmgoADFoKAA7d7eANy/vwB/T08A8ubmAOnR0QDiyckA4sbGAKN5 + eQDewcEA38DAAN++vgCsgoIAzKenAMGZmQDp1NQA5s3NAOPIyADhxMQA3MLCAM2kpADKpqYAyqSkAPHi + 4gDr19cA6NHRAOfQ0ADlzMwA5MrKAOPJyQDiyMgA4cfHAOPGxgDhxsYAqYiIANu7uwDCnZ0AAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + 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 + tQByQ0MA7NraAL+SkgCDX18AnImJANWhoQDiyMgA9u3tALJ/fwCyn58AgU5OAJJ5eQDru7sAlWVlAKmS + kgDEnp4Az6ysALSKigDgrKwA8uPjAOfR0QDevr4AildXAKt4eADns7MAnnl5AIpoaADJlpYAk21tALSU + lAB2SkoAmH9/AKKDgwCqi4sAu5ycAI9gYADIp6cA+fPzAPHV1QDWp6cA47m5AKqBgQDNn58AnGhoAJtv + bwDUsLAAeU9PALmOjgDy3d0A4MPDAN6xsQDAl5cA3Lm5ALqIiADNpKQAuZeXAPPp6QDq1dUAh2RkAOXM + zACgbGwAtYODAHxLSwDbq6sAlWBgAO7g4ACXd3cAx6OjAKN0dADOqKgAhFFRAIphYQDjwMAAjWtrAOa8 + vADZvb0A1bi4AKh1dQCjeHgA0bOzAJ+GhgCnjo4AmWxsANikpACyh4cAspGRAPfw8ACxfHwAyJmZANGv + rwC0jY0Aw5OTAMCamgDkz88AjWZmAOXGxgDjrq4ArX9/AMuqqgC8kJAA7t3dAHdNTQDq2NgAjFlZAIhf + XwDat7cAnHd3ANqzswCce3sAqXp6ALCdnQC0nZ0Af0xMAOfOzgDixcUA3Ly8AN+6ugDUtLQAyqCgALib + mwD26ekA8ufnAIBQUADp09MAhmJiAOrR0QCJZmYA5MrKAJtmZgCZaGgAlGtrAN/BwQDivr4AonJyAKZ4 + eADPqqoA1KOjAMunpwC1iIgAq42NALiMjADFnJwA8uXlAPLh4QCVY2MAqn9/ANqpqQB4S0sA7NzcAN7E + xADgv78AtIaGAM2mpgCnkZEAqY+PALaLiwCCUFAA8OHhAItmZgDiysoA5bm5ANa1tQDNqqoAt46OALuO + jgC+kJAA9+7uAPXs7AB+S0sA9OrqAPHk5ADv398A7d7eAO3b2wDr2dkAlF9fAOvW1gDo1NQA6NLSAOjQ + 0ACVbGwA5s3NAOPJyQDhx8cA48bGAJZ4eADhxMQA3729ANu4uADZtrYA2bS0ANCrqwC/mZkA8ODgAOrX + 1wDq1NQAoG1tAOTLywDhxsYAmH5+AODCwgDfwMAA3r+/AOC+vgCfhYUAooSEANy7uwDcuroAuY2NANCu + rgDOqakAe0tLAH9LSwDz6uoA9OnpAIlXVwDz5+cAi1lZAO/h4QCJYWEA7+DgAO7e3gDv3d0A7dzcAO3a + 2gDr2toA69jYAJpsbADp1dUA6dTUAOjR0QDn0NAA5s7OAOTMzADlysoA4snJAOPIyADix8cA4sbGAOHF + xQDixMQA4MTEAOHDwwDfwsIA37+/AN++vgDevb0A3bm5ANu5uQDauLgAu5CQAMCSkgAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaSKCAAAAAAAAAAAAAAAAAAAAAAAAAAAjURusAAAAAA8AAAAA + AAAAAAAAAL0AAABNLpGUogAAMsgEAAAAAAAAAAAAbInbYstCTs/+Sn7XFkMvPgAAAAAAAABUO6UCL0Fk + iHf9QAwcLMJnHgAAAAAAAAC4T+7xN6RMzRn6A3pvwvsnAAAAAAAAAAAAUoG6g/G7Cu+6yTX8bXh0AAAA + AAAAAAAAIGZ18Mrxyr7Mzb7t0jGEaxoOCAAAADCFRCi3vrk/7ckK9YfNP7+fCRAfBwAAcFeMqT3zGOu2 + SVyWNr6Hh/L7wMEGlwAA5xeY42q+6LRgjwAAAEO+zbrS08+RgAAASHyvsenw5uIRAAAAAI359crN1Vbf + AAAALRVTaAXwsZOgAAAAAKh28/LzlUsAAAAAAABVWNr4RaFe2EbRSHk/CvV2jrOGAAAAAAByW6vyBeDF + i18rKrbJ7/f2mgbdAAAAAADUNNncON7eReGyters97q89GMnAAAAAA1QKQsLPNLrRbDlxuzOuabEFKfQ + AAAAAACQ2WHDmaq2v/jNzr5/R26dJB0AAAAAAAAA/yYAIdatrn3eBWrHExIAAAAAAAAAAAAAAAAAAJyr + kjmbcaPkXSUAAAAAAAAAAAAAAAAAADpaXXMAAGUUigAAAAAAAAAAAAAAAAAAAHszWQAAAACeAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A/8f/AP+HvwD7gx8A8AAPAOAADwDgAB8A8AAfAPAA + AQDAAAEAgAABAIAcAQCAPAMAgDwHAOAAAwDgAAMA4AADAMAAAwDgAAcA8gA/AP8APwD/DH8A/x7/AP// + /wAoAAAAGAAAADAAAAABACAAAAAAAGAJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcjc3E28+ + PtpuOjradT4+owAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfEJCb6h1df+reHj/f0xM/oNERD4AAAAAAAAAAGYy + MgtxOTlzbjY2GgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH89PQmCS0uMiFBQTgAA + AAAAAAAAe0REns2fn//FnJz/lWNj/3pDQ6oAAAAAfEZGIG45Oc+gbW3/bjs77Hk+PkUAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAhFlZDX9JScWicnL/i1hY/oNOTr+DTEx9eEJC6ea8vP/gvr7/u5CQ/4ZS + Uv59SEjneUVF7uCsrP/aq6v/nGho/3I6OqEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAi09Pa7mX + l//WtbX/o3Bw/5xoaP+1g4P/466u/+K+vv/cvLz/2ri4/6BsbP+yf3//57Oz/+O5uf/ZtLT/vJCQ/3Q8 + PJwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjVNTtdm9vf/lysr/4sfH/8CXl//lubn/48DA/9/A + wP/evr7/3r29/9i1tf/KoKD/2rOz/9m0tP/dubn/kWFh/nhAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAklpaTqV5ef7q0dH/48nJ/+TKyv/ix8f/4cfH/+LIyP/iycn/48nJ/+TLy//gw8P/27m5/9q3 + t//furr/gExM/XVFRUl6ODgJQEhIBAAAAAAAAAAAAAAAAAAAAAAAAAAAhD4+BItXV73Lqqr/587O/+PI + yP/hxsb/4sfH/+HGxv/hxMT/4MLC/9/AwP/hxMT/5MzM/9y7u//UsLD/m2Zm/4xZWf+MWFj+gk1N+nlC + QlUAAAAAAAAAAJ5nZzKZZGTUmmdn95VgYP/Ip6f/6NDQ/+HExP/mzc3/5czM/+TMzP/ky8v/4sjI/+DE + xP/fwcH/38DA/+XMzP/fvb3/touL/9Whof/ru7v/yZaW/287O60AAAAAAAAAAJJdXaDYpKT/1KOj/76Q + kP/q1dX/4cXF/+fR0f/n0ND/6NLS/86oqP/KmZn236qq7OCzs/7hxMT/38HB/9/Bwf/ixsb/3bm5/9u4 + uP/Ztrb/v5KS/3NAQOQAAAAAAAAAAJllZePy4+P/7Nzc/+3c3P/q2Nj/4cTE/+nV1f/r1tb/wJqa/6p0 + dI6+oaEJAAAAAPO6ukffrKzz4cTE/9/AwP/jycn/3Lu7/9y6uv/gvr7/xZyc/3RAQK8AAAAAAAAAAKNx + ce/26en/79/f/+3b2//p1NT/48jI/+vY2P/v3d3/lWNj9oI8PAQAAAAAAAAAAAAAAADdpKSf376+/+DE + xP/hxsb/38DA/9Curv+bbW3+fUhIv4FNTS4AAAAAAAAAAKpycr+2jIz+0bOz/+7d3f/s2tr/48jI/+3b + 2//y4eH/hFFR/o9ZWTcAAAAAAAAAALGPjwjAiYnR4sXF/+HFxf/ixsb/4cXF/6p/f/+BTEzFdTg4CQAA + AAAAAAAAAAAAAAAAAAC9f38mom5ufrSIiP306en/37+//+7g4P/w4eH/tI2N/35HR/OKU1OYl19fhqJr + a9fUtLT/5czM/+LIyP/gxMT/4sXF/7WIiP+UX1//jVZWwAAAAAAAAAAAAAAAAAAAAAAAAAAAtnt7UbJ8 + fPn17Oz/4sbG/+za2v/v4OD/8ODg/8+qqv/Dk5P/1qen//HV1f/o0tL/5MvL/+LJyf/fwsL/4cPD/+C/ + v/+/kpL/jFlZ/HpUVA0AAAAAAAAAAAAAAADGh4cmu46O+/Ld3f/z6ur/8+fn/9y5uf/v4eH/7+Hh/+7g + 4P/u3t7/69nZ/+jU1P/o0dH/5s7O/9/Cwv/jycn/48bG/+LExP/lxsb/jltb7ZdISAsAAAAAAAAAAAAA + AAC+g4NS1bi4//nz8//27e3/9u3t//Pp6f/cu7v/59DQ/+7g4P/t3t7/69ra/+rX1//mzs7/3r+//+bN + zf/Nqqr/v5mZ/8+srP+3jo7/kFlZfAAAAAAAAAAAAAAAAAAAAADHlZUdu4qK6vPq6v/kz8//0Kur/97E + xP/37u7/6NLS/9+9vf/fv7//38DA/96/v//hxMT/6dPT/8ejo/+WYGCxnWVlZJpiYpCWX1+pkVFRDgAA + AAAAAAAAAAAAAAAAAAAAAAAA1pmZQMeMjMfJjo6HyY2NQrqDg5bOqan/9Orq//Hk5P/y5+f/7+Hh/+za + 2v/q2Nj/6tTU/8Senv+ibW1sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAMqSkiPNpqb/9ezs//Ll5f+8iYn4t35+zqt3d+jiysr/7dra/9Cvr/+ocHCOAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMuTkyPNpKT/9/Dw/9Gv + r/+8iIhtAAAAAMGEhCuvfX3uzqys/6Zzc+a2d3dGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAMSengfAjo6UvYmJ0bWHh7z/iIgCAAAAAAAAAACze3s7pXBwf650 + dA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA////AP/H/wD/h78A+4MfAPAADwDgAA8A4AAfAPAAHwDwAAEAwAABAIAAAQCAHAEAgDwDAIA8 + BwDgAAMA4AADAOAAAwDAAAMA4AAHAPIAPwD/AD8A/wx/AP8e/wD///8AKAAAACAAAABAAAAAAQAIAAAA + AACABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8Aom9vAN+zswBuQEAAq5iYAOva2gCIV1cAzpycAJeF + hQC3hIQA4sjIAPXt7QCJa2sAuqWlAL+RkQB9SkoAzaysAO67uwCseXkAlmNjAJB2dgDsz88ApoaGANq+ + vgDap6cAnXp6ALqbmwDz4uIAsIyMAIdiYgCdjY0AfFRUAMijowDUtLQAvIqKAOS7uwDEnJwAj1xcAJR9 + fQCmkJAAq4CAAJtrawCRb28A1KGhAIBaWgDHlJQAg1BQAK6engDWrq4A59TUAKd0dAC1lpYA5M3NAOXB + wQB1SEgAmXFxAM+mpgDbubkA6be3AI9lZQDz6ekA8dfXAOGurgC4oKAArpGRAKWVlQB4UFAAm4GBAMCX + lwCxfn4A7t/fAIReXgDfwsIA5bKyAKCHhwDCpKQAuZCQAJZ5eQCzhoYAjmBgAI5paQCVaWkAim9vANus + rAClgoIAsIKCALuVlQC4jIwA1Li4AMSfnwCrhIQAgE1NAOfQ0ADdxsYA37y8AJlmZgDasrIAn2xsAJNz + cwDQr68A0qmpAKR3dwCnenoAyqenAJ5+fgCxm5sAg1dXAOS3twDEkZEAeUZGAKGLiwDx5eUAhVNTAIZa + WgDhwMAAhWVlANi7uwCgcnIAs56eAOrX1wB9V1cA5MrKANm1tQCVgIAAqn19AMCOjgDv29sAkl9fAJJi + YgCNbGwAj3JyANSxsQCYfHwAwJSUAItnZwCSZ2cAnW5uAJp4eADMpKQAqXh4AKOSkgC4mJgApHJyAObS + 0gDhxMQAjVtbAOK5uQCbaGgA2KWlANajowCgfHwAzJ6eALSBgQC6iIgAsJOTAOrT0wDcwcEA3Lu7AIxx + cQCda2sA17OzANOtrQDIpqYAt5ycALySkgC0jY0A9OvrAPDj4wDt3d0AgFBQAIdVVQDmzs4AiVpaAOXI + yADhyckA3r+/AJhpaQDgtbUA17m5AJ9vbwDXsLAA2ampAM6qqgCahYUA0aGhAK19fQCgjY0AsYSEAMCZ + mQC6j48Aqnt7AMihoQCrlpYAuZKSAOnV1QDo0tIA5czMAN29vQCcbGwAnXBwANKwsACnd3cAl4GBANCo + qACtgYEAvouLALWMjAC+j48Ae0pKAODIyACUYmIA2ru7ANe1tQCpmJgA9u7uAPLn5wDv4OAAfktLAOzc + 3ADr2NgAiVZWAIlYWADn0dEAiFlZAIRfXwDjyckAhmNjAOLGxgDhw8MAl2RkAO26ugDfwMAAjmtrAOW4 + uADZvLwA3Lq6AJtvbwChbm4A2re3AKBwcADZtrYAo3FxANm0tADYsrIApXNzANOysgCVfn4AqHV1AJiE + hACtenoAz6urAKx8fACqf38Ay6amALGBgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAANNyB0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC/6oBD5AAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAD5jJnuJnkAAAAACQRTAAAAAAAAAAAAAAAAAB/jAAAAAIN+zIvwbgAAAJ9xzi9D + AAAAAAAAAAAAAAC4B6AvhwAAa7k676WS0eEtlBIIM1wAAAAAAAAAAAAAAFCEjPLmcdMjbOw6ofL6+Jrn + 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 + t//curr/27m5/9azs/+jcXH/rXp6/6h1df+6iIj/7bq6/+W4uP/Wrq7/wJOT/4NRUf9uOTlMAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAg1BQn8KkpP/jyMj/0rCw/7CCgv+kcXH/vIqK/9qn + p//lsrL/5Lu7/929vf/cvLz/3Lq6/7qOjv+ndHT/sX5+/9ilpf/gtbX/2LKy/9ewsP/Vrq7/glFR/nA9 + PTIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACGUlLn1rm5/+HFxf/hxcX/4cTE/86q + qv/Mnp7/4rm5/+G/v//fwMD/3r+//96+vv/dvb3/3Lu7/9e1tf/MpKT/17Cw/9m1tf/ZtLT/2LKy/7eM + jP90QUG6AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIpWVoGrgID/4sjI/+LH + x//ix8f/4sbG/+HFxf/hxMT/4MTE/+HGxv/iyMj/48rK/+PKyv/ix8f/38HB/9y6uv/bubn/2re3/9m2 + tv/ZtLT/mmtr/3dDQ48AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfz8/CI5b + W9fNrKz/48rK/+PJyf/jycn/4sjI/+HGxv/iyMj/4sfH/+HExP/gw8P/38LC/+DExP/jycn/5c3N/9/B + wf/bubn/2re3/9i0tP+lc3P/fktL/HZFRYV2QkJwcz8/aHI8PEwAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACZZmYKkFxcbJ1ubv/jycn/5MzM/+PKyv/gxMT/4sjI/+PIyP/ix8f/4cbG/+HExP/gw8P/38LC/9/A + wP/ev7//48rK/+LHx//bubn/17Oz/6Rycv+ib2//rXp6/616ev+tenr/gU5O/m4+PiUAAAAAAAAAAH9f + XwiSX1+rk2Bg3pViYvqZZmb/oHBw/+XOzv/lzc3/38LC/+TLy//kzMz/5MrK/+PJyf/iyMj/4sfH/+HF + xf/gxMT/4MLC/9/AwP/ev7//4sjI/+HGxv/bubn/yKGh/7F+fv/Wo6P/4a6u/+m3t/+WY2P/dD8/cAAA + AAAAAAAAk2JiU6x5ef/UoaH/x5SU/7SBgf/Enp7/59HR/+HFxf/kysr/5s/P/+XOzv/lzc3/5MvL/9y8 + vP/WsLD/2rKy/9+7u//hw8P/4MLC/9/AwP/ev7//48rK/96/v//bubn/062t/9iysv/YsrL/z6am/59s + bP92QkK8AAAAAAAAAACWY2Ow0qmp/+XBwf/evLz/2ru7/+TNzf/o09P/3sDA/+jS0v/n0dH/59DQ/+TM + zP/Al5f/uIWFzcWRkXfMmZlq16Ojot6trfnhwMD/4MLC/9/AwP/fwMD/48nJ/9y6uv/buLj/2ra2/9m0 + tP/YsrL/p3Z2/3lFRbUAAAAAAAAAAJpmZt3jzc3/69jY/+rY2P/q19f/6tfX/+XNzf/ix8f/6dXV/+jU + 1P/o0tL/v5mZ/6Jvb6B/f38CAAAAAAAAAAAAAAAA16SkQdyrq/vgw8P/4MLC/9/AwP/jycn/3b29/9y6 + uv/buLj/2ra2/9awsP+fcHD/eUZGbQAAAAAAAAAAnGlp6OfU1P/s2tr/7Nra/+za2v/r2dn/4sjI/+XO + zv/q19f/6tbW/+nV1f+ba2v/lWBgHQAAAAAAAAAAAAAAAAAAAAAAAAAA05+ftt+8vP/gxMT/38LC/+HF + xf/fwcH/3Lu7/9i2tv+1i4v/ilhY+3xJSaR4PDwRAAAAAAAAAACfbGzw1Li4/+vZ2f/t3d3/7dzc/+3c + 3P/iyMj/5tDQ/+vZ2f/r2Nj/5tHR/4lWVv+HUlIiAAAAAAAAAAAAAAAAAAAAAAAAAADHk5O83bu7/+HF + xf/gw8P/4cTE/+DCwv/dvb3/mGlp/4NQULh8Tk4nAAAAAAAAAAAAAAAAAAAAAKJtbU2icHCxqHd397+Z + mf/dxsb/7t7e/+XOzv/ky8v/7Nzc/+za2v/o1dX/jVtb/4BNTa5/Pz8IAAAAAAAAAAAAAAAAr319U8GS + kv3ix8f/4sfH/+HExP/hxMT/38LC/96+vv+cbGz/h1RU7INQUEYAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACfb28QpnNzX659fffs3Nz/7Nvb/929vf/u3t7/7dzc/+zb2/+7lZX/jVpa/4FNTdyHVFSLkl5efJtp + aba1h4f94cbG/+TKyv/iyMj/4cbG/+DExP/fwsL/3r+//6Bubv+baGj/iFVV+4ROTksAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACqdHQYq3h44+HJyf/w4uL/3b29/+vZ2f/u39//7d3d/+rY2P/DnJz/t4SE/7aD + g//EkZH/37Oz//HX1//lzs7/5MvL/+PJyf/ix8f/38LC/+DCwv/fwMD/z6ur/619ff+ZZmb/g1BQjwAA + AAAAAAAAAAAAAAAAAAAAAAAAqnh4JK57e93SqKj/79vb//Hl5f/s29v/27q6/+/g4P/u39//7d3d/+zb + 2//mz8//5cjI/+zPz//q09P/59HR/+bPz//lzc3/5MrK/9/Cwv/gxMT/4MPD/9/Bwf/ev7//27q6/7GE + hP+EUlKtAAAAAAAAAAAAAAAAAAAAAAAAAACue3uP1LS0//Pi4v/z6Oj/8ufn//Lm5v/mz8//3r6+/+/g + 4P/u39//7d3d/+zb2//r2dn/6tfX/+nU1P/o0tL/59DQ/+XOzv/hxMT/38HB/+LHx//hxMT/4MLC/97A + wP/dvb3/oHJy/4dTU1wAAAAAAAAAAAAAAAAAAAAAAAAAALJ+frPl0tL/9Ovr//Tq6v/z6en/8+jo//Lm + 5v/n0ND/27i4/+rX1//u3t7/7dzc/+za2v/r2Nj/6dbW/+jT0//mz8//3sDA/9/Bwf/jysr/2Lu7/8il + pf/TsrL/3L29/8umpv+KV1fUVVVVAwAAAAAAAAAAAAAAAAAAAAAAAAAAs4GBlNCvr//27u7/9e3t//Tr + 6//r2tr/8OPj//Lm5v/t3d3/3r+//9u4uP/hxcX/5czM/+XNzf/ix8f/3b29/9y7u//jycn/5c3N/8Sf + n/+da2vpl2RkopRhYcmTYGDyk2Bg/Y1ZWVMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC/f38IuISEyte5 + uf/Us7P/wpWV/bqHh9TAkJD42r6+//Dj4//w4+P/7t/f/+fR0f/jyMj/4sbG/+TKyv/n0dH/6NPT/+fQ + 0P/mzs7/qnt7/5tnZzYAAAAAAAAAAKpVVQOQWFgXAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAC2iIgcu4eHnL2IiGW8jY0bAAAAALuHhyK9iYnK4MjI//Hk5P/w4uL/7+Dg/+3d3f/s29v/6dXV/+rW + 1v/o1NT/59HR/+bPz/+peHj/nGhoTgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL+Kipzgx8f/8eXl//Dj4//n09P/vpGR/7OC + gvqtenrvxJ6e/+nU1P/n0tL/5s/P/7KGhv+da2twAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwI6OnOHIyP/y5ub/8OPj/8ad + nf62gIBptm1tB6pxcQmreHjDyqen/+jS0v/ZvLz/qXt7/p1qam4AAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADDkJCa1LCw/+bS + 0v/cwcH/uISEwv8AAAEAAAAAAAAAAKFraxOqd3fWuo+P/6Rxcd6hbGxSAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL+N + jSTBjY2FvoqKvbuIiOG3goIrAAAAAAAAAAAAAAAAAAAAAKp3dx6nc3NmjXFxCQAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////+H////g////wPH/88Dg/+DAAP/gA + AD/wAAA/8AAAP/AAAD/4AAAH+AAAA8AAAAGAAAABgAAAAYAD4AGAB+ADgAfgD8ADwA/wAAAH+AAAA/AA + AAPgAAAD4AAAB+AAAAfwAAH/+cAB///AAP//wMD//8Hh///j9///////KAAAADAAAABgAAAAAQAIAAAA + AACACgAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8Aom9vAN6zswBvPT0Aq5iYAOva2gCJV1cAzZycAJeF + hQC4hIQA4sfHAPXt7QCJa2sAuaWlAL+RkQB9SkoAzK6uAPG/vwCreXkAl2NjAJJ3dwD3ysoApoWFANnA + wADZp6cAnXx8ALqbmwDz4eEArY2NAIhiYgCdjY0AfFRUAMijowDUtbUAvIqKAOO7uwDEnJwAj1xcAJR9 + fQCmkpIAqYGBAJlsbACRcHAA06KiAIFbWwDIlpYAg1BQAK6engDWra0A6NTUAKd0dAC1lpYA5M3NAObB + wQB1SEgAm3R0ANGlpQDbubkA6re3AI9lZQD16OgA+tbWAN+trQC+oaEArY+PAKWVlQB3T08Am4ODAMCY + mACyfn4A79/fAIleXgDfwsIA5bKyAJ+IiADDp6cAt5GRAJR5eQCyh4cAjmBgAI5paQCUamoAjG9vANys + rACigoIAsIKCALyVlQC5i4sA07m5AMSfnwCshYUAgE1NAOfQ0ADdxcUA4Ly8AJlmZgDbsrIAoGtrAJd1 + dQDPsLAA06mpAJ92dgCoenoAyKioAJ5+fgC0mZkAg1hYAOW3twDEkJAAd0REAKaMjADx5eUAhFNTAIZa + WgDhv78AhWVlANm6ugCfdHQAs56eAOrX1wB9V1cA5MrKANq1tQCVgIAAqn19AMGNjQDu2toAk19fAJNh + YQCMa2sAj3JyANWwsACYfHwAwZWVAItnZwCSZ2cAnW5uAJx3dwDLo6MAq3h4AKSSkgC4mJgApXJyAOfS + 0gDhxMQAjVtbAOK5uQCcaWkA2KWlANajowChfHwAzJ+fALWBgQC6h4cAs5SUAOvT0wDcwsIA3Ly8AIxx + cQCeamoA2LOzANSsrADFqakAtZycALySkgC0jo4A9evrAPDj4wDt3d0Af1BQAIVVVQDmzs4AiVpaAOzH + xwDiysoA3r+/AJhpaQDgtbUA17m5AJ5vbwDXsLAA2qmpAMypqQCaiYkA0aGhAK98fACgjo4As4SEAMGZ + mQC7jo4Aq3t7AMqgoACslJQAtpOTAOnV1QDo0tIA5czMAN29vQCbbW0AnXBwANKwsACnd3cAl4GBANCo + qACtgYEAv4uLALWMjAC+kJAAekpKAODIyACVYWEA2ru7ANe2tgCpmJgA+fDwAPLn5wDv4OAAfkxMAO3c + 3ADs2NgAiVZWAIlYWADn0dEAiVlZAIRfXwDkyckAh2NjAOLGxgDhw8MAlmVlAOy6ugDfwMAAjmtrAOa4 + uADZvb0A3bq6AJtvbwChbm4A27e3AKFwcADZtrYAo3FxANm0tADYsrIApnJyANCysgCVfn4AqXZ2AJiE + hACte3sAz6urAKx8fACpf38Ay6amALGBgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + 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 + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB3Pj6sajc3+Wo3N+JqNzfIbDk5qng6 + OioAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIJHR0p2Q0P+t4WF/6Nw + cP+XZGT/fktL/3U+PqsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHlB + QaqzhIT/wY2N/6t4eP+kcXH/mWZm/3A7O/iEQEAbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAG02 + NhB3OzsZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAHhBQdjRpKT/vouL/6RwcP+caWn/m2ho/3xJSf96Q0N9AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAdz4+M2g0NOFpNTX1dDw8bAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJBLSx+ETU1RdDg4BQAA + AAAAAAAAAAAAAAAAAAAAAAAAfjw8DnE8PPjsvLz/y56e/76Rkf+7jo7/nGlp/45bW/90Pz/glUlJBAAA + AAAAAAAAAAAAAAAAAAB8Q0NYZTIy9LmGhv+odnb/cDw8/m83N7N9Pj4YAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjlJSMXpG + RuV/TU3/fEhI0oxUVEkAAAAAAAAAAAAAAAAAAAAAgU9PNXZERP76yMj/27m5/925uf/fvr7/tIiI/5ll + Zf94RUX/dkVFWlsAAAMAAAAAXgAAA3lFRYVtOTn90Jyc///W1v+pdnb/r3x8/4FOTv9yOjrZAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACOU1NBeEND76t8fP+0gYH/lWFh/39NTf6HTk64kFFRLwAAAACSUVEuekZGooxbW//0w8P/2rm5/9u4 + uP/bubn/1rGx/5VgYP+OW1v/dUJC/nZDQ+t6RES8c0BAv3pISP7ls7P//MjI//vIyP+fa2v/p3R0/6h1 + df9wODj2AAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAJNYWDJ9R0f2vZWV/+K8vP+kcHD/pHFx/6d0dP+RX1//gExM+4BMTN98SUn+lWVl/9Gh + of/pu7v/3Lq6/9u5uf/burr/37+//6h5ef+mcnL/t4SE/616ev+hbm7/onFx//C9vf/0wMD/8b+//9uy + sv/Sqqr/rXt7/6Btbf9uNDT4nqOjAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAIlOTpenf3//7dfX/+HFxf+ib2//nWho/6NwcP+ndHT/pHJy/7mJ + if/Xp6f/5LGx/+u3t//jurr/3L29/9y7u//curr/3bu7/8ujo/+famr/q3d3/7F+fv+5hob/2aen/++8 + vP/qubn/2bKy/9ewsP/Xr6//2rS0/7mMjP9xOjr1AAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAk0ZGCH5JSerbxcX/69fX/+LFxf/kyMj/wpyc/59r + a/+ibm7/pXFx/92rq//dqan/5LCw/+64uP/hvLz/3b29/929vf/cvLz/3Ly8/9/AwP+icXH/nWpq/6h1 + df+xfX3/2aen/+W3t//Ys7P/2LKy/9exsf/YsLD/3La2/6p9ff94Pz/FAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkVpaTY1bW//z4OD/4cXF/+HF + xf/ixcX/5MjI/+HFxf+9k5P/om1t/+axsf/ks7P/5Ly8/+DBwf/ewcH/3r+//96+vv/dvb3/3by8/928 + vP/hwMD/2La2/8ienv+7jIz/2ays/9q2tv/ZtLT/2LOz/9iysv/YsrL/27W1/3ZCQv6CR0dIAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAnF5eNYdS + UvvbvLz/5MrK/+LGxv/ixsb/4cfH/+LGxv/lysr/3L6+/+TCwv/gxcX/4MTE/+DCwv/fwcH/38DA/97A + wP/evr7/3r29/928vP/dvLz/3by8/969vf/dvLz/3Lq6/9q4uP/atrb/2bW1/9izs//ct7f/q39//3ZA + QMcAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAJJZWZacbGz/6tLS/+TJyf/iyMj/4sfH/+LHx//ixsb/48fH/+HFxf/hxcX/4cTE/+HF + xf/iycn/5M3N/+fPz//m0dH/5tLS/+fR0f/kzMz/4MPD/927u//cubn/27m5/9u4uP/at7f/2ra2/9m2 + tv/eubn/lWFh/3dCQt+APj4SAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAJ1paRGJU1PlxqKi/+fQ0P/jycn/48nJ/+PJyf/jyMj/4sjI/+LH + x//hxsb/4snJ/+LKyv/ix8f/4cbG/+DExP/gwcH/4MHB/+DExP/ix8f/5tHR/+nV1f/jyMj/3Lu7/9u5 + uf/buLj/2re3/9u3t//Vr6//pnJy/4VSUv96Rkaqb0VFDI4tLQaVAAACAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACXXl5Xj1tb/ufOzv/lzc3/5MvL/+TK + yv/jy8v/48rK/+HFxf/hxsb/4sfH/+LGxv/hxsb/4cXF/+HExP/gw8P/4MLC/9/Bwf/fwMD/3r6+/9/B + wf/lzs7/6NTU/96/v//burr/27i4/9y5uf/FnJz/oW1t/6NwcP93RET+bz09+249PfhtPj70cz4+7Xk/ + P+OMTExHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI9CQgSPYmIbjlhY066F + hf/p09P/5czM/+TNzf/jy8v/38LC/+HGxv/jysr/48nJ/+PIyP/ix8f/4sbG/+HFxf/hxcX/4MTE/+DD + w//fwsL/38DA/96/v//evb3/4cTE/+nX1//gw8P/27q6/925uf/Rqqr/m2ho/6Ftbf/FlJT/3qys/96q + qv/frKz/5rOz/6NwcP92Pz+rAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAApWhoFJ5mZnmeZGSinGVlyZJh + YeyTYGD9k2Bg/7KIiP/q1NT/587O/+bPz//dv7//4sfH/+TNzf/ky8v/5MrK/+PKyv/jycn/4sjI/+LH + x//ixsb/4cXF/+HExP/gw8P/4MLC/9/Bwf/ewMD/3r6+/9/AwP/p1tb/38HB/9u6uv/fvLz/wpiY/5di + Yv/KmJj/2qam/+Ctrf/qtrb/+8fH/6x5ef9yPj7vejs7CQAAAAAAAAAAAAAAAAAAAAAAAAAAnWVlmKFw + cP+3hYX/u4mJ/7qIiP+xf3//n2pq/8inp//q1NT/59LS/+DCwv/gw8P/58/P/+XNzf/lzc3/5MzM/+TL + y//kysr/5MrK/+TKyv/jysr/48nJ/+LHx//hxcX/4MPD/+DCwv/fwcH/3sDA/96+vv/gw8P/6NTU/928 + vP/bubn/376+/7CCgv/Pn5//1aen/9utrf/fs7P/3bGx/6Rxcf99Skr/cD8/SAAAAAAAAAAAAAAAAAAA + AACmb28Kklxc7d+trf/lsLD/0p6e/8SQkP+2gYH/qHJy/+nT0//o1NT/5s/P/9u5uf/n0dH/5tHR/+bP + z//mzs7/5c3N/+bOzv/n0ND/4sfH/9WwsP/Uqan/16ys/9yzs//hvb3/4sbG/+DExP/gwsL/38HB/97A + wP/evb3/4snJ/+TMzP/cubn/3Lq6/9y6uv/cubn/2be3/9m1tf/Ys7P/0amp/55qav+OW1v/c0BAkQAA + AAAAAAAAAAAAAAAAAACVYGBYoG5u//rIyP/muLj/3bKy/9ewsP/UsLD/2bq6/+zY2P/p1dX/3r+//+LH + x//o09P/59HR/+fQ0P/m0ND/59DQ/+rV1f/KpKT/t4KC+82Tk7jcoaF64Kioa+Wvr4/eqqrd4LCw/uLC + wv/gxMT/4MLC/9/Bwf/ewMD/3r6+/+fS0v/ev7//3Lq6/9u5uf/at7f/2ra2/9m1tf/Ys7P/27i4/6t6 + ev+NWlr/dUBAfwAAAAAAAAAAAAAAAAAAAACXYmKgwJ2d/+7e3v/q2tr/69ra/+zZ2f/s2dn/7NnZ/+nX + 1//r19f/2LGx/+jV1f/o09P/6NPT/+jS0v/n0dH/7NfX/7+Zmf+oc3PazJGRMgAAAAAAAAAAAAAAAAAA + AAD3jY0G7Lm5feKurv3iwsL/4MTE/+DCwv/fwcH/3r+//+LIyP/jyMj/3Lu7/9y6uv/buLj/2re3/9m2 + tv/ZtLT/27a2/8yiov+BTU3/eUREOwAAAAAAAAAAAAAAAAAAAACVYGCuyKio/+7d3f/r2Nj/69jY/+vY + 2P/r2Nj/6tjY/+rY2P/n0ND/2bW1/+vZ2f/p1dX/6dTU/+jU1P/q1tb/3cTE/5hhYfS4eXkmAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAO22to3fsLD/4sbG/+DDw//fwsL/38DA/9/Bwf/lz8//3bu7/9y7 + u//bubn/27i4/9u4uP/dubn/4b6+/7SJif97RkbudE5OBwAAAAAAAAAAAAAAAAAAAACYY2O4zK6u/+/e + 3v/s2tr/7Nra/+za2v/r2tr/69nZ/+za2v/ky8v/3Lu7/+va2v/q19f/6tbW/+nV1f/u2tr/uZWV/5ti + YqQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOKurhXWo6P64cXF/+LExP/gw8P/38HB/9+/ + v//lzs7/3r6+/928vP/du7v/3r29/+K/v/+7kpL/hlRU/nxGRtqLUlJRAAAAAAAAAAAAAAAAAAAAAAAA + AACYZWXD07m5//Pk5P/u3d3/7dzc/+zc3P/s29v/7Nvb/+3d3f/jycn/3b6+/+zc3P/r2Nj/6tfX/+rX + 1//x4OD/mGlp/5ZeXogAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANCGhgTOm5vu4MHB/+HG + xv/gxMT/4MLC/9/Bwf/jy8v/38HB/929vf/gwMD/vJWV/4lZWf9+S0vailRUYHM3NwUAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACfa2vCtImJ/9nAwP/x5OT/8uTk/+/g4P/u3t7/7d3d/+7d3f/kzMz/3bu7/+3d + 3f/s2tr/69nZ/+zY2P/w4OD/ilRU/41UVLsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAM+c + nCnFkZH948nJ/+PGxv/hxcX/4MPD/+DCwv/jyMj/38HB/92/v//evr7/e0ZG/4NRUamGJCQGAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACteXklrHd3h5pwcN2gcHD+vpeX/9vDw//y5eX/8ODg/+/f + 3//p09P/2LGx/+/g4P/s29v/7Nra/+vb2//x4+P/mWZm/39JSf2UVlZRAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA3pKSBLiEhLjMoaH/5c3N/+LHx//hxsb/4cTE/+DDw//hx8f/38HB/9+/v//dvLz/jltb/4ZV + VfyIWlqCkQAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAGtf381sXd3i6Zu + bt+seXn+8+fn/+/i4v/v4OD/0aWl/+7g4P/t3t7/7dzc/+zb2//x4eH/uJGR/45ZWf96SEj3iVNTd6Fb + Ww0AAAAAAAAAAAAAAAC5fX0sqXFxuruNjf/n0dH/48vL/+PIyP/ix8f/4cXF/+DExP/ixsb/38HB/9/A + wP/UsLD/lmFh/5xpaf+JV1f/hFVVrqFcXA0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAJdzcwemb2/g28TE//Hk5P/x5eX/2bOz/+bNzf/v4OD/7d3d/+3c3P/t3d3/6tjY/55q + av+gbGz/hVJS/35LS/KNVVXClV1dtJhiYtWYY2P9x52d//vr6//lzMz/5MvL/+PJyf/iyMj/4sbG/+HE + xP/gw8P/38LC/+HCwv/Rra3/lV9f/6Btbf+lcnL/jVtb/49XV48AAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAALmMjAaocnLAxZ2d//Pp6f/x5OT/6NHR/9Wrq//w5eX/7uDg/+7e + 3v/t3t7/7+Dg/+LMzP+xfn7/v4qK/8OPj/++i4v/xpKS/9+trf//2tr//+fn/+fQ0P/lzc3/5MvL/+PK + yv/jyMj/48jI/+DDw//gw8P/4MLC/9/Cwv/hw8P/0K2t/6d0dP+mcnL/m2ho/45WVrwAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAuXp6Dq54eLi1goL+57+///Po6P/y5eX/8unp/9as + rP/kysr/8ePj/+7f3//u3t7/7d3d/+7f3//u3t7/17a2/9arq//ks7P/88XF//rS0v/w1tb/5tHR/+bP + z//lzs7/5czM/+TLy//jycn/4cfH/96/v//ixMT/4MPD/9/Bwf/gwMD/4MHB/+DBwf++kpL/om5u/4xV + Vd8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADGlZUMrnp6y72Rkf/x0dH/79PT//Po + 6P/x5eX/8ufn/+3d3f/QoaH/7Nvb//Di4v/u39//7t7e/+3d3f/t3d3/7t3d/+3d3f/r2tr/6tjY/+nW + 1v/o09P/59LS/+fQ0P/mz8//5c3N/+TNzf/kzMz/3b6+/+DDw//hxcX/4MTE/+DCwv/fwcH/3r+//96+ + vv/jxMT/wJiY/4ZVVeKcAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC+hoZItYSE//zt + 7f/14uL/9Orq//Pp6f/y5+f/8ubm//Lo6P/nz8//0aKi/+7d3f/w5OT/7t/f/+7e3v/t3d3/7Nvb/+za + 2v/r2Nj/6tfX/+nV1f/p1NT/6NPT/+fR0f/mz8//5c/P/+XOzv/evr7/3sDA/+PJyf/jxsb/4cTE/+DD + w//fwcH/3sDA/9+/v//kxsb/l2Vl/49ZWXQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AADAhoZuxJyc//329v/06+v/9Ovr//Pp6f/z6Oj/8+fn//Lm5v/z6en/5czM/86fn//o1NT/8eXl/+/g + 4P/v3t7/7dzc/+zb2//r2dn/69jY/+rW1v/p1dX/6NPT/+fT0//o0dH/58/P/927u//dvb3/5MvL/+TJ + yf/ly8v/5cvL/+PHx//hxcX/4MHB/+HCwv/JpKT/hk9P6JJjYwwAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAADEiIiU0LCw//r19f/17Oz/9evr//Tr6//06ur/8+np//Po6P/y6Oj/9Ojo/+rZ + 2f/QoqL/2re3/+za2v/w5eX/7uDg/+7e3v/t29v/69ra/+vY2P/q2Nj/69bW/+nU1P/hxcX/2LOz/9+/ + v//mz8//587O/+bNzf+8lJT/tIqK/8Kdnf/QsLD/38HB/+rMzP+YaGj/lVxcdAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADPkpJauIWF/vTq6v/48fH/9e3t//bu7v/27+//+PHx//fx + 8f/27e3/8+np//Ln5//y5+f/4cTE/8+goP/Wra3/4MLC/+fQ0P/q19f/69fX/+fS0v/iyMj/3Lu7/9at + rf/bt7f/5czM/+fQ0P/o0dH/0LCw/51sbP6ZZ2fBoWlplJxlZb6RYWHni1hY/ZJgYP+MWVnokmJiDAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAxIqKlL+Rkf/89/f//Pn5//Tq + 6v/excX/yqGh/7qHh//Wtrb/9ezs//Xq6v/y5+f/8ebm//Lm5v/o0dH/3by8/9avr//UqKj/06en/9Wt + rf/btrb/4MPD/+fS0v/q1dX/6NHR/+bQ0P/r1dX/pHFx/55tbYSMAAACAAAAAAAAAACSAAACmGJiGJ1k + ZECpaGglAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAxJOTBrqE + hMHIn5//xJiY/7yDg/rJj4/EzpSUetCVlU7Hjo7Av4qK/t3Bwf/16ur/8eTk//Hk5P/w4+P/7+Pj//Di + 4v/v4OD/7t/f/+3d3f/r2tr/69jY/+nV1f/o1NT/59HR/+bQ0P/nzs7/oGpq/6p0dHEAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAANGTkxjOlpaL0JaWWc6SkhQAAAAAAAAAAAAAAAAAAAAAyZOTV7V+fv706+v/8eXl//Dj + 4//w4uL/8ODg/+/h4f/v4eH/7+Dg/+/g4P/v3t7/7NnZ/+nW1v/o09P/59HR/+bR0f/n0ND/nWlp/6xy + cpMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1ZCQGbqF + hf317Oz/8+fn//Hk5P/w4uL/8OPj/+vb2//UtbX/zKmp/8ScnP+7jo7/3cPD/+zZ2f/o09P/59LS/+jQ + 0P/r1tb/pXJy/6x0dLUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA1Z2dGbyFhf306+v/8ubm//Hl5f/w5OT/9enp/76QkP+zfX3HvYODmMGFhXu5f3+KrXd3/uTN + zf/q19f/6dLS/+fQ0P/t2Nj/sYaG/6xzc9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA1ZycGb2IiP307e3/8ujo//Hl5f/z5+f/2b29/7WAgNvMkZEKAAAAAAAA + AAAAAAAAuoaGhq58fP7p09P/69bW/+zX1//fxMT/p3d3/693d8YAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1JycGb+Kiv358vL/9e3t//Tq6v/x5OT/u4aG/dGW + lksAAAAAAAAAAAAAAAAAAAAAjQAAAq19faOxgoL/59LS/72Vlf+hamr1rHNzgbV4eAoAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA6qqqDsSQkO3GmZn/0q2t/9/G + xv/LpKT/xo6OrQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANR+fgepd3e8p3Jy/q93d7G6fn4jAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANKO + jhXAjIxOvYiIh7qHh8C7hYXXxY+PHwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC4cXEMs3x8MQAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////AAD///////8AAP//8H///wAA///wP/// + AAD//+A///8AAP//4B/H/wAA/+/gHwP/AAD/x+AOAf8AAP+BwAAB/wAA/wAAAAH/AAD+AAAAAf8AAP4A + AAAB/wAA/gAAAAP/AAD+AAAAA/8AAP4AAAAD/wAA/wAAAAH/AAD/AAAAAA8AAP+AAAAABwAA8AAAAAAH + AADgAAAAAAcAAOAAAAAAAwAAwAAAAAADAADAAAfgAAcAAMAAD/AABwAAwAAP+AAHAADAAA/4AB8AAMAA + D/gAfwAA4AAH8AA/AAD8AAPgAB8AAP8AAAAADwAA/wAAAAAPAAD+AAAAAA8AAPwAAAAADwAA/AAAAAAP + AAD4AAAAAB8AAPgAAAAAHwAA+AAAAAA/AAD8AAAAH/8AAP4EAAAf/wAA/z4AAB//AAD//wAAH/8AAP// + AAAf/wAA//8B4B//AAD//wPwP/8AAP//A/j//wAA///H////AAD///////8AAP///////wAA + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/SecureShare/DRServer.cs b/Demo_Source_Code/CSharpDemo/SecureShare/DRServer.cs new file mode 100644 index 0000000..924af86 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/SecureShare/DRServer.cs @@ -0,0 +1,581 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; +using Microsoft.Win32.SafeHandles; +using System.Runtime.InteropServices; +using System.Security.Principal; +using System.Threading; +using System.Diagnostics; +using System.Management; +using System.Collections; +using System.Configuration; +using System.Windows.Forms; + +using EaseFilter.FilterControl; +using EaseFilter.CommonObjects; + +namespace SecureShare +{ + + public enum AESFlags : uint + { + Flags_Enabled_Expire_Time = 0x00000010, + Flags_Enabled_Check_ProcessName = 0x00000020, + Flags_Enabled_Check_UserName = 0x00000040, + Flags_Enabled_Check_AccessFlags = 0x00000080, + Flags_Enabled_Check_User_Permit = 0x00000100, + Flags_AES_Key_Was_Embedded = 0x00000200, + Flags_Request_AccessFlags_From_User = 0x00000400, + Flags_Request_IV_And_Key_From_User = 0x00000800, + Flags_Enabled_Check_Computer_Id = 0x00001000, + Flags_Enabled_Check_User_Password = 0x00002000, + + } + + /// + /// this is the return data structure for encryption to filter driver. + /// when the filter command is FILTER_REQUEST_ENCRYPTION_IV_AND_KEY, + /// FILTER_REQUEST_ENCRYPTION_IV_AND_KEY_AND_ACCESSFLAG or FILTER_REQUEST_ENCRYPTION_IV_AND_KEY_AND_TAGDATA + /// + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + public struct AESDataBuffer + { + public uint AccessFlags; + public uint IVLength; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] + public byte[] IV; + public uint EncryptionKeyLength; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] + public byte[] EncryptionKey; + public uint TagDataLength; + public byte[] TagData; + } + + /// + /// This is the DR info meta data which will be stored in server if revoke access control is enabled. + /// + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + public class DRPolicy + { + /// + /// If it is not empty, only the processes in the process list can access the files. + /// + public string AuthorizedProcessNames; + /// + /// If it is not empty, all the processes in the process list can not access the files. + /// + public string UnauthorizedProcessNames; + /// + /// If it is not empty, only the users in the user name list can access the files. + /// + public string AuthorizedUserNames; + /// + /// If it is not empty, all the useres in the user name list can not access the files. + /// + public string UnauthorizedUserNames; + /// + /// If it is not empty, only the computer in the computer id list can access the files. + /// + public string AuthorizedComputerIds; + /// + /// the password of the shared file. + /// + public string UserPassword; + /// + /// the access flags of the shared file. + /// + public uint AccessFlags; + /// + /// The file will be expired after the expire time in UTC format, and it can't be accessed. + /// + public long ExpireTime; + /// + /// The time in UTC format of the encrypted file was created. + /// + public long CreationTime; + /// + /// the file name which was applied with policy. + /// + public string FileName; + /// + /// The encryption key hex string. + /// + public string EncryptionKey; + /// + /// the iv hex string. + /// + public string EncryptionIV; + } + + + /// + /// This the DR data which will be embedded to the encyrpted file + /// + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + public struct DRPolicyData + { + + public uint AESVerificationKey; + public AESFlags AESFlags; + public uint IVLength; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] + public byte[] IV; + public uint EncryptionKeyLength; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] + public byte[] EncryptionKey; + public long CreationTime; + public long ExpireTime; + public uint AccessFlags; + public long FileSize; + public uint LengthOfAuthorizedProcessNames; + public uint LengthOfUnauthorizedProcessNames; + public uint LengthOfAuthorizedUserNames; + public uint LengthOfUnauthorizedUserNames; + public uint LengthOfAccountName; + public uint LengthOfComputerIds; + public uint LengthOfUserPassword; + public string AuthorizedProcessNames; + public string UnauthorizedProcessNames; + public string AuthorizedUserNames; + public string UnauthorizedUserNames; + public string AccountName; + public string ComputerIds; + public string UserPassword; + public uint SizeOfAESData; + + } + + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + public struct UserInfo + { + /// + /// the owner account name + /// + public string AccountName; + /// + /// the password of the account + /// + public string AccountPassword; + /// + /// the process name which access the file. + /// + public string ProcessName; + /// + /// the user name who access the file. + /// + public string UserName; + /// + /// the computer information which access the file. + /// + public string ComputerId; + /// + /// the encrypted file which was accessed. + /// + public string FileName; + /// + /// the creation time of the file which was accessed. + /// + public long CreationTime; + /// + /// the password of the user input. + /// + public string UserPassword; + /// the encryption iv hex string; + /// + public string EncryptionIV; + } + + + public class DigitalRightControl + { + public const uint AES_VERIFICATION_KEY = 0xccb76e80; + public static string PassPhrase = "PassPhrase"; + + private static byte[] ConvertDRPolicyDataToByteArray(DRPolicyData policy) + { + MemoryStream ms = new MemoryStream(); + BinaryWriter bw = new BinaryWriter(ms); + bw.Write(AES_VERIFICATION_KEY); + bw.Write((uint)(policy.AESFlags)); + bw.Write(policy.IVLength); + bw.Write(policy.IV); + bw.Write(policy.EncryptionKeyLength); + bw.Write(policy.EncryptionKey); + bw.Write(policy.CreationTime); + bw.Write(policy.ExpireTime); + bw.Write((uint)policy.AccessFlags); + bw.Write(policy.FileSize); + bw.Write(policy.LengthOfAuthorizedProcessNames); + bw.Write(policy.LengthOfUnauthorizedProcessNames); + bw.Write(policy.LengthOfAuthorizedUserNames); + bw.Write(policy.LengthOfUnauthorizedUserNames); + bw.Write(policy.LengthOfAccountName); + bw.Write(policy.LengthOfComputerIds); + bw.Write(policy.LengthOfUserPassword); + + byte[] strBuffer; + if (policy.LengthOfAuthorizedProcessNames > 0) + { + strBuffer = UnicodeEncoding.Unicode.GetBytes(policy.AuthorizedProcessNames); + bw.Write(strBuffer); + } + + if (policy.LengthOfUnauthorizedProcessNames > 0) + { + strBuffer = UnicodeEncoding.Unicode.GetBytes(policy.UnauthorizedProcessNames); + bw.Write(strBuffer); + } + + if (policy.LengthOfAuthorizedUserNames > 0) + { + strBuffer = UnicodeEncoding.Unicode.GetBytes(policy.AuthorizedUserNames); + bw.Write(strBuffer); + } + + if (policy.LengthOfUnauthorizedUserNames > 0) + { + strBuffer = UnicodeEncoding.Unicode.GetBytes(policy.UnauthorizedUserNames); + bw.Write(strBuffer); + } + + if (policy.LengthOfAccountName > 0) + { + strBuffer = UnicodeEncoding.Unicode.GetBytes(policy.AccountName); + bw.Write(strBuffer); + } + + if (policy.LengthOfComputerIds > 0) + { + strBuffer = UnicodeEncoding.Unicode.GetBytes(policy.ComputerIds); + bw.Write(strBuffer); + } + + if (policy.LengthOfUserPassword > 0) + { + strBuffer = UnicodeEncoding.Unicode.GetBytes(policy.UserPassword); + bw.Write(strBuffer); + } + + //append the sizeof the DR policy + int sizeofDRDataArray = (int)ms.Length + 4;// the size of sizeofDRDataArray takes 4 bytes memory as a int data + bw.Write(sizeofDRDataArray); + + byte[] AESBuffer = ms.ToArray(); + + return AESBuffer; + } + } + + + public class CacheUserAccessInfo + { + public string index = string.Empty; + public bool accessStatus = false; + public bool isDownloaded = false; + public uint accessFlags = 0; + public DateTime lastAccessTime = DateTime.MinValue; + public string iv = string.Empty; + public string key = string.Empty; + public AutoResetEvent syncEvent = new AutoResetEvent(true); + public string lastError = string.Empty; + + } + + public class DRServer + { + + static Dictionary userAccessCache = new Dictionary(); + static int cacheTimeOutInSeconds = 20; + static System.Timers.Timer deleteCachedItemTimer = new System.Timers.Timer(); + + static DRServer() + { + deleteCachedItemTimer.Interval = cacheTimeOutInSeconds * 1000 ; //millisecond + deleteCachedItemTimer.Start(); + deleteCachedItemTimer.Enabled = true; + deleteCachedItemTimer.Elapsed += new System.Timers.ElapsedEventHandler(deleteCachedItemTimer_Elapsed); + } + + static public bool GetFileAccessPermission(EncryptEventArgs encryptEventtArgs) + { + Boolean retVal = true; + string fileName = encryptEventtArgs.FileName; + string lastError = string.Empty; + string processName = encryptEventtArgs.ProcessName; + string userName = encryptEventtArgs.UserName; + string encryptKey = string.Empty; + + try + { + + if (null == encryptEventtArgs.EncryptionTag || encryptEventtArgs.EncryptionTag.Length == 0) + { + encryptEventtArgs.Description = "There are no encryption tag data."; + + return false; + } + + //by default the tag data format is "accountName;ivStr" + string tagStr = UnicodeEncoding.Unicode.GetString(encryptEventtArgs.EncryptionTag); + + int index = tagStr.IndexOf(";"); + byte[] iv = encryptEventtArgs.EncryptionTag; + + if (index > 0) + { + string serverAccount = tagStr.Substring(0, index); + string ivStr = tagStr.Substring(index + 1); + iv = Utils.ConvertHexStrToByteArray(ivStr); + } + + uint accessFlag = 0; + + retVal = IsFileAccessAuthorized(fileName, + userName, + processName, + tagStr, + ref encryptKey, + ref accessFlag, + ref lastError); + + if (retVal && !string.IsNullOrEmpty(encryptKey)) + { + byte[] keyArray = Utils.ConvertHexStrToByteArray(encryptKey); + + encryptEventtArgs.AccessFlags = FilterAPI.ALLOW_MAX_RIGHT_ACCESS; + encryptEventtArgs.IV = iv; + encryptEventtArgs.EncryptionKey = keyArray; + encryptEventtArgs.ReturnStatus = NtStatus.Status.Success; + + } + else + { + encryptEventtArgs.IoStatus = encryptEventtArgs.ReturnStatus = NtStatus.Status.AccessDenied; + encryptEventtArgs.Description = lastError; + + } + } + catch (Exception ex) + { + lastError = "GetFileAccessPermission exception." + ex.Message; + encryptEventtArgs.Description = lastError; + + EventManager.WriteMessage(340, "GetFileAccessPermission", EventLevel.Error, lastError); + retVal = false; + } + + return retVal; + + } + + + static private bool IsFileAccessAuthorized(string fileName, + string userName, + string processName, + string tagStr, + ref string encryptKey, + ref uint accessFlag, + ref string lastError) + { + Boolean retVal = true; + string expireTime = string.Empty; + string authorizedProcessNames = string.Empty; + string unauthorizedProcessNames = string.Empty; + string authorizedUserNames = string.Empty; + string unauthorizedUserNames = string.Empty; + string accessFlags = string.Empty; + + lastError = string.Empty; + DateTime currentTime = DateTime.Now; + + try + { + + string drFilePath = GlobalConfig.DRInfoFolder + "\\" + tagStr + ".xml"; + Dictionary keyValues = new Dictionary(); + + if (!File.Exists(drFilePath)) + { + lastError = "The meta data file " + drFilePath + " doesn't exist."; + return false; + } + + Utils.LoadAppSetting(drFilePath, ref keyValues); + + encryptKey = string.Empty; + keyValues.TryGetValue("key", out encryptKey); + if (string.IsNullOrEmpty(encryptKey)) + { + lastError = "The encryption key is empty."; + return false; + } + + keyValues.TryGetValue("accessFlags", out accessFlags); + uint.TryParse(accessFlags, out accessFlag); + keyValues.TryGetValue("expireTime", out expireTime); + keyValues.TryGetValue("authorizedProcessNames", out authorizedProcessNames); + keyValues.TryGetValue("unauthorizedProcessNames", out unauthorizedProcessNames); + keyValues.TryGetValue("authorizedUserNames", out authorizedUserNames); + keyValues.TryGetValue("unauthorizeUserNames", out unauthorizedUserNames); + + if (!string.IsNullOrEmpty(expireTime)) + { + DateTime exTime = DateTime.FromFileTime(long.Parse(expireTime)); + + if (currentTime > exTime) + { + lastError = "the file is expired,current time:" + currentTime.ToString("yyyy-MM-dd-HH-mm-ss") + ",expire time:" + exTime.ToString("yyyy-MM-dd-HH-mm-ss"); + return false; + } + } + + if (!string.IsNullOrEmpty(authorizedProcessNames)) + { + if (authorizedProcessNames.IndexOf(processName.ToLower().Trim()) < 0) + { + lastError = "the process " + processName + " is not in authorized process list."; + return false; + } + } + + if (!string.IsNullOrEmpty(unauthorizedProcessNames)) + { + if (unauthorizedProcessNames.IndexOf(processName.ToLower().Trim()) >= 0) + { + lastError = "the process " + processName + " is in unauthorized process list."; + return false; + } + } + + if (!string.IsNullOrEmpty(authorizedUserNames)) + { + if (authorizedUserNames.IndexOf(userName.ToLower().Trim()) < 0) + { + lastError = "the user " + userName + " is not in authorized user list."; + return false; + } + } + + if (!string.IsNullOrEmpty(unauthorizedUserNames)) + { + if (unauthorizedUserNames.IndexOf(userName.ToLower().Trim()) >= 0) + { + lastError = "the user " + userName + " is in unauthorized user list."; + return false; + } + } + + + } + catch (Exception ex) + { + EventManager.WriteMessage(286, "IsFileAccessAuthorized", EventLevel.Error, "Get file " + fileName + "permission failed with exception:" + ex.Message); + retVal = false; + } + + return retVal; + + } + + static public bool AddDRInfoToFile(string fileName, + string authorizedProcessNames, + string unauthorizedProcessNames, + string authorizedUserNames, + string unauthorizedUserNames, + DateTime expireTime, + byte[] encryptIV, + byte[] encryptKey, + string accessFlags) + { + + try + { + if (!Directory.Exists(GlobalConfig.DRInfoFolder)) + { + Directory.CreateDirectory(GlobalConfig.DRInfoFolder); + } + + string iv = Utils.ByteArrayToHexStr(encryptIV); + string key = Utils.ByteArrayToHexStr(encryptKey); + + string drFilePath = GlobalConfig.DRInfoFolder + "\\" + iv + ".xml"; + Dictionary keyValues = new Dictionary(); + + keyValues.Add("fileName", fileName); + keyValues.Add("key", key); + keyValues.Add("iv", iv); + keyValues.Add("accessFlags", accessFlags); + keyValues.Add("authorizedProcessNames", authorizedProcessNames.ToLower()); + keyValues.Add("unauthorizedProcessNames", unauthorizedProcessNames.ToLower()); + keyValues.Add("authorizedUserNames", authorizedUserNames.ToLower()); + keyValues.Add("unauthorizedUserNames", unauthorizedUserNames.ToLower()); + keyValues.Add("expireTime", expireTime.ToFileTime().ToString()); + keyValues.Add("creationTime", DateTime.Now.ToFileTime().ToString()); + + Utils.SaveAppSetting(drFilePath, keyValues); + + return true; + } + catch (Exception ex) + { + return false; + } + + } + + static private void deleteCachedItemTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) + { + + try + { + List keysToRemove = new List(); + + foreach (KeyValuePair userItem in userAccessCache) + { + + TimeSpan tsSinceLastAccess = DateTime.Now - userItem.Value.lastAccessTime; + + if (tsSinceLastAccess.TotalSeconds >= cacheTimeOutInSeconds) + { + keysToRemove.Add(userItem.Key); + } + } + + foreach (string key in keysToRemove) + { + lock (userAccessCache) + { + userAccessCache.Remove(key); + + EventManager.WriteMessage(573, "deleteCachedItemTimer_Elapsed", EventLevel.Verbose, "Delete cached item " + key); + } + } + } + catch (System.Exception ex) + { + EventManager.WriteMessage(46, "deleteCachedItemTimer_Elapsed", EventLevel.Error, "Delete cached item failed with error:" + ex.Message); + } + + } + + } +} diff --git a/Demo_Source_Code/CSharpDemo/SecureShare/EncryptEventHandler.cs b/Demo_Source_Code/CSharpDemo/SecureShare/EncryptEventHandler.cs new file mode 100644 index 0000000..1eea0a9 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/SecureShare/EncryptEventHandler.cs @@ -0,0 +1,286 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; +using System.Runtime.InteropServices; +using System.Security.Principal; +using System.IO; +using System.Threading; +using System.Reflection; + +using EaseFilter.FilterControl; +using EaseFilter.CommonObjects; + +namespace SecureShare +{ + + public class EncryptEventHandler : IDisposable + { + + ListView listView_Message = null; + Thread messageThread = null; + Queue messageQueue = new Queue(); + + AutoResetEvent autoEvent = new AutoResetEvent(false); + bool disposed = false; + + + public EncryptEventHandler(ListView lvMessage) + { + this.listView_Message = lvMessage; + InitListView(); + messageThread = new Thread(new ThreadStart(ProcessMessage)); + messageThread.Name = "ProcessMessage"; + messageThread.Start(); + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + private void Dispose(bool disposing) + { + if (!this.disposed) + { + } + + autoEvent.Set(); + messageThread.Abort(); + disposed = true; + } + + ~EncryptEventHandler() + { + Dispose(false); + } + + public void InitListView() + { + messageQueue.Clear(); + //init ListView control + listView_Message.Clear(); //clear control + //create column header for ListView + listView_Message.Columns.Add("MessageId#", 40, System.Windows.Forms.HorizontalAlignment.Left); + listView_Message.Columns.Add("Time", 120, System.Windows.Forms.HorizontalAlignment.Left); + listView_Message.Columns.Add("UserName", 150, System.Windows.Forms.HorizontalAlignment.Left); + listView_Message.Columns.Add("ProcessName(PID)", 100, System.Windows.Forms.HorizontalAlignment.Left); + listView_Message.Columns.Add("ThreadId", 60, System.Windows.Forms.HorizontalAlignment.Left); + listView_Message.Columns.Add("I/O Name", 160, System.Windows.Forms.HorizontalAlignment.Left); + listView_Message.Columns.Add("FileObject", 100, System.Windows.Forms.HorizontalAlignment.Left); + listView_Message.Columns.Add("FileName", 350, System.Windows.Forms.HorizontalAlignment.Left); + listView_Message.Columns.Add("FileSize", 70, System.Windows.Forms.HorizontalAlignment.Left); + listView_Message.Columns.Add("FileAttributes", 70, System.Windows.Forms.HorizontalAlignment.Left); + listView_Message.Columns.Add("LastWriteTime", 120, System.Windows.Forms.HorizontalAlignment.Left); + listView_Message.Columns.Add("Return Status", 100, System.Windows.Forms.HorizontalAlignment.Left); + listView_Message.Columns.Add("Description", 500, System.Windows.Forms.HorizontalAlignment.Left); + } + + public void DisplayEventMessage(FileIOEventArgs fileIOEventArgs) + { + if (GlobalConfig.OutputMessageToConsole) + { + lock (messageQueue) + { + if (messageQueue.Count > GlobalConfig.MaximumFilterMessages) + { + messageQueue.Clear(); + } + + messageQueue.Enqueue(fileIOEventArgs); + } + + autoEvent.Set(); + } + + } + + + void ProcessMessage() + { + int waitTimeout = 2000; //2seconds + List itemList = new List(); + + WaitHandle[] waitHandles = new WaitHandle[] { autoEvent, GlobalConfig.stopEvent }; + + while (GlobalConfig.isRunning) + { + if (messageQueue.Count == 0) + { + int result = WaitHandle.WaitAny(waitHandles, waitTimeout); + if (!GlobalConfig.isRunning) + { + return; + } + } + + System.Diagnostics.Stopwatch stopWatch = new System.Diagnostics.Stopwatch(); + stopWatch.Start(); + + while (messageQueue.Count > 0) + { + FileIOEventArgs fileIOEventArgs = null; + + lock (messageQueue) + { + fileIOEventArgs = (FileIOEventArgs)messageQueue.Dequeue(); + } + + if (GlobalConfig.DisableDirIO && (fileIOEventArgs.FileAttributes & (uint)FileAttributes.Directory) == (uint)FileAttributes.Directory) + { + //don't display the directory IO + continue; + } + + string[] filterMessages = new string[0]; + ListViewItem lvItem = GetFilterMessage(fileIOEventArgs, ref filterMessages); + + if (null == lvItem) + { + //no display message. + continue; + } + + if (GlobalConfig.OutputMessageToConsole) + { + itemList.Add(lvItem); + + if (itemList.Count > GlobalConfig.MaximumFilterMessages) + { + AddItemToList(itemList); + itemList.Clear(); + + Thread.Sleep(1000); + } + } + + } + + if (itemList.Count > 0) + { + AddItemToList(itemList); + itemList.Clear(); + } + + } + + } + + + void AddItemToList(List itemList) + { + if (itemList.Count < 1) + { + return; + } + + if (listView_Message.InvokeRequired) + { + listView_Message.Invoke(new MethodInvoker(delegate { AddItemToList(itemList); })); + } + else + { + + while (listView_Message.Items.Count > 0 && listView_Message.Items.Count + itemList.Count > GlobalConfig.MaximumFilterMessages) + { + //the message records in the list view reached to the maximum value, remove the first one till the record less than the maximum value. + listView_Message.Items.RemoveAt(0); + } + + + if (itemList.Count > 0) + { + listView_Message.Items.AddRange(itemList.ToArray()); + // listView_Message.EnsureVisible(listView_Message.Items.Count - 1); + + itemList.Clear(); + + } + } + } + + ListViewItem GetFilterMessage(FileIOEventArgs fileIOEventArgs, ref string[] filterMessages) + { + ListViewItem lvItem = new ListViewItem(); + + try + { + string[] listData = new string[listView_Message.Columns.Count]; + int col = 0; + listData[col++] = fileIOEventArgs.MessageId.ToString(); + listData[col++] = DateTime.FromFileTime(fileIOEventArgs.TransactionTime).ToString("yyyy-MM-ddTHH:mm"); + listData[col++] = fileIOEventArgs.UserName; + listData[col++] = fileIOEventArgs.ProcessName + " (" + fileIOEventArgs.ProcessId + ")"; + listData[col++] = fileIOEventArgs.ThreadId.ToString(); + listData[col++] = fileIOEventArgs.EventName; + listData[col++] = fileIOEventArgs.FileObject.ToString("X"); + listData[col++] = fileIOEventArgs.FileName; + listData[col++] = fileIOEventArgs.FileSize.ToString(); + listData[col++] = ((FileAttributes)fileIOEventArgs.FileAttributes).ToString(); + listData[col++] = DateTime.FromFileTime(fileIOEventArgs.LastWriteTime).ToString("yyyy-MM-ddTHH:mm"); + listData[col++] = fileIOEventArgs.IOStatusToString(); + listData[col++] = fileIOEventArgs.Description; + + filterMessages = listData; + + lvItem = new ListViewItem(listData, 0); + + if ((uint)fileIOEventArgs.IoStatus >= (uint)NtStatus.Status.Error) + { + lvItem.BackColor = Color.LightGray; + lvItem.ForeColor = Color.Red; + } + else if ((uint)fileIOEventArgs.IoStatus > (uint)NtStatus.Status.Warning) + { + lvItem.BackColor = Color.LightGray; + lvItem.ForeColor = Color.Yellow; + } + + + } + catch (Exception ex) + { + EventManager.WriteMessage(445, "GetFilterMessage", EventLevel.Error, "Add callback message failed." + ex.Message); + lvItem = null; + } + + return lvItem; + } + + /// + /// Fires this event after the new file was created, the handle is not closed. + /// + public void OnFilterRequestEncryptKey(object sender, EncryptEventArgs e) + { + + if (!DRServer.GetFileAccessPermission(e)) + { + e.IoStatus = e.ReturnStatus = NtStatus.Status.AccessDenied; + } + + DisplayEventMessage(e); + } + + } +} \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/SecureShare/FilterWorker.cs b/Demo_Source_Code/CSharpDemo/SecureShare/FilterWorker.cs new file mode 100644 index 0000000..0a3f0c0 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/SecureShare/FilterWorker.cs @@ -0,0 +1,280 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; +using Microsoft.Win32.SafeHandles; +using System.Runtime.InteropServices; +using System.Security.Principal; +using System.Threading; +using System.Diagnostics; +using System.Management; +using System.Collections; +using System.Windows.Forms; + +using EaseFilter.CommonObjects; + +namespace SecureShare +{ + + public class FilterWorker + { + + public FilterMessage filterMessage = null; + + public FilterWorker(ListView listView_Info) + { + this.filterMessage = new FilterMessage(listView_Info); + + } + + public bool StartService(ref string lastError) + { + //Purchase a license key with the link: http://www.easefilter.com/Order.htm + //Email us to request a trial key: info@easefilter.com //free email is not accepted. + string registerKey = GlobalConfig.registerKey; + + bool ret = false; + lastError = string.Empty; + + try + { + + ret = FilterAPI.StartFilter((int)GlobalConfig.FilterConnectionThreads + , registerKey + , new FilterAPI.FilterDelegate(FilterCallback) + , new FilterAPI.DisconnectDelegate(DisconnectCallback) + , ref lastError); + if (!ret) + { + lastError = "Start filter service failed with error " + lastError; + EventManager.WriteMessage(43, "StartFilter", EventLevel.Error, lastError); + return ret; + } + + GlobalConfig.RemoveAllFilterRules(); + + ApplySettingsToFilterDriver(); + + EventManager.WriteMessage(102, "StartFilter", EventLevel.Information, "Start filter service succeeded."); + } + catch (Exception ex) + { + lastError = "Start filter service failed with error " + ex.Message; + EventManager.WriteMessage(104, "StartFilter", EventLevel.Error, lastError); + } + + return ret; + } + + static public void ApplySettingsToFilterDriver() + { + GlobalConfig.RemoveAllFilterRules(); + string[] whiteList = null; + string[] blacklist = null; + + FilterRule filterRuleShareFolder = new FilterRule(); + filterRuleShareFolder.IncludeFileFilterMask = GlobalConfig.ShareFolder + "\\*"; + filterRuleShareFolder.AccessFlag |= (uint)FilterAPI.AccessFlag.ENABLE_FILE_ENCRYPTION_RULE | FilterAPI.ALLOW_MAX_RIGHT_ACCESS; + filterRuleShareFolder.AccessFlag &= (uint)(~FilterAPI.AccessFlag.ALLOW_ENCRYPT_NEW_FILE);// this folder won't encrypt the new file. + filterRuleShareFolder.AccessFlag &= (uint)(~FilterAPI.AccessFlag.ALLOW_READ_ENCRYPTED_FILES);// all process can't read the encyrpted file except the authorized processes. + filterRuleShareFolder.EncryptMethod = (int)FilterAPI.EncryptionMethod.ENCRYPT_FILE_WITH_SAME_KEY_AND_UNIQUE_IV; + filterRuleShareFolder.EncryptionPassPhrase = GlobalConfig.MasterPassword; + + //for whitelist process, it has maximum acess rights. + if (GlobalConfig.ProtectFolderWhiteList == "*") + { + //allow all processes to read the encrypted file except the black list processes. + filterRuleShareFolder.AccessFlag |= (uint)(FilterAPI.AccessFlag.ALLOW_READ_ENCRYPTED_FILES); + } + else + { + //for whitelist process, it has maximum acess rights. + whiteList = GlobalConfig.ShareFolderWhiteList.Split(new char[] { ';' }); + if (whiteList.Length > 0) + { + foreach (string authorizedUser in whiteList) + { + if (authorizedUser.Trim().Length > 0) + { + //not allow to encrypt the new file + uint accessFlag = filterRuleShareFolder.AccessFlag |(uint)(FilterAPI.AccessFlag.ALLOW_READ_ENCRYPTED_FILES); + filterRuleShareFolder.ProcessRights += ";" + authorizedUser + "!" + accessFlag.ToString(); + } + } + } + + } + + //for blacklist process, it has maximum acess rights. + blacklist = GlobalConfig.ShareFolderBlackList.Split(new char[] { ';' }); + if (blacklist.Length > 0) + { + foreach (string unAuthorizedUser in blacklist) + { + if (unAuthorizedUser.Trim().Length > 0) + { + //can't read the encrypted files, not allow to encrypt the new file + uint accessFlag = filterRuleShareFolder.AccessFlag ; + filterRuleShareFolder.ProcessRights += ";" + unAuthorizedUser + "!" + accessFlag.ToString(); + } + } + } + + + FilterRule filterRuleProtectFolder = new FilterRule(); + filterRuleProtectFolder.IncludeFileFilterMask = GlobalConfig.ProtectFolder + "\\*"; + filterRuleProtectFolder.AccessFlag |= (uint)FilterAPI.AccessFlag.ENABLE_FILE_ENCRYPTION_RULE | FilterAPI.ALLOW_MAX_RIGHT_ACCESS; + filterRuleProtectFolder.AccessFlag &= (uint)(~FilterAPI.AccessFlag.ALLOW_READ_ENCRYPTED_FILES);// all process can't read the encyrpted file except the authorized processes. + filterRuleProtectFolder.EncryptMethod = (int)FilterAPI.EncryptionMethod.ENCRYPT_FILE_WITH_SAME_KEY_AND_UNIQUE_IV; + filterRuleProtectFolder.EncryptionPassPhrase = GlobalConfig.MasterPassword; + + //for whitelist process, it has maximum acess rights. + if (GlobalConfig.ProtectFolderWhiteList == "*") + { + //allow all processes to read the encrypted file except the black list processes. + filterRuleProtectFolder.AccessFlag |= (uint)(FilterAPI.AccessFlag.ALLOW_READ_ENCRYPTED_FILES); + } + else + { + //for whitelist process, it has maximum acess rights. + whiteList = GlobalConfig.ProtectFolderWhiteList.Split(new char[] { ';' }); + if (whiteList.Length > 0) + { + foreach (string authorizedUser in whiteList) + { + if (authorizedUser.Trim().Length > 0) + { + filterRuleProtectFolder.ProcessRights += ";" + authorizedUser + "!" + FilterAPI.ALLOW_MAX_RIGHT_ACCESS.ToString(); + } + } + } + } + + //for blacklist process, it has maximum acess rights. + blacklist = GlobalConfig.ProtectFolderBlackList.Split(new char[] { ';' }); + if (blacklist.Length > 0) + { + foreach (string unAuthorizedUser in blacklist) + { + if (unAuthorizedUser.Trim().Length > 0) + { + //can't read the encrypted files + uint accessFlag = FilterAPI.ALLOW_MAX_RIGHT_ACCESS & (uint)(~FilterAPI.AccessFlag.ALLOW_READ_ENCRYPTED_FILES); + filterRuleProtectFolder.ProcessRights += ";" + unAuthorizedUser + "!" + accessFlag.ToString(); + } + } + } + + GlobalConfig.AddFilterRule(filterRuleShareFolder); + GlobalConfig.AddFilterRule(filterRuleProtectFolder); + + //send the filter rule settings to the filter driver here. + GlobalConfig.SaveConfigSetting(); + + } + + static void DisconnectCallback() + { + EventManager.WriteMessage(697, "DisconnectCallback", EventLevel.Information, "Filter Disconnected." + FilterAPI.GetLastErrorMessage()); + } + + + public bool StopService() + { + FilterAPI.StopFilter(); + GlobalConfig.Stop(); + + return true; + } + + public void ClearMessage() + { + filterMessage.InitListView(); + } + + private Boolean FilterCallback(IntPtr sendDataPtr, IntPtr replyDataPtr) + { + bool retVal = true; + + try + { + FilterAPI.MessageSendData messageSend = new FilterAPI.MessageSendData(); + messageSend = (FilterAPI.MessageSendData)Marshal.PtrToStructure(sendDataPtr, typeof(FilterAPI.MessageSendData)); + + if (FilterAPI.MESSAGE_SEND_VERIFICATION_NUMBER != messageSend.VerificationNumber) + { + EventManager.WriteMessage(139, "FilterCallback", EventLevel.Error, "Received message corrupted.Please check if the MessageSendData structure is correct."); + return false; + } + + if ( messageSend.MessageType == (uint)FilterAPI.FilterCommand.FILTER_REQUEST_ENCRYPTION_IV_AND_KEY) + { + + if ((replyDataPtr.ToInt64() != 0)) + { + + //this is the customized tag data which was attahced to the encrypted file when it was created. + uint tagDataLength = messageSend.DataBufferLength; + byte[] tagData = messageSend.DataBuffer; + + FilterAPI.MessageReplyData messageReply = (FilterAPI.MessageReplyData)Marshal.PtrToStructure(replyDataPtr, typeof(FilterAPI.MessageReplyData)); + messageReply.MessageId = messageSend.MessageId; + messageReply.MessageType = messageSend.MessageType; + + //get permission for secure shared file from server, here just demo the server in local, + //in reality, your server could be in remote computer. + retVal = DRServer.GetFileAccessPermission(ref messageSend, ref messageReply); + + if (retVal) + { + messageReply.ReturnStatus = (uint)FilterAPI.NTSTATUS.STATUS_SUCCESS; + } + else + { + //if you don't want to authorize the process to read the encrytped file,you can set the value as below: + messageReply.ReturnStatus = (uint)FilterAPI.NTSTATUS.STATUS_ACCESS_DENIED; + messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION; + } + + Marshal.StructureToPtr(messageReply, replyDataPtr, true); + + if (!retVal) + { + messageSend.Status = (uint)FilterAPI.NTSTATUS.STATUS_ACCESS_DENIED; + } + + } + } + + filterMessage.AddMessage(messageSend); + } + catch (Exception ex) + { + EventManager.WriteMessage(134, "FilterCallback", EventLevel.Error, "filter callback exception." + ex.Message); + return false; + } + + return retVal; + + } + + } + +} diff --git a/Demo_Source_Code/CSharpDemo/SecureShare/Program.cs b/Demo_Source_Code/CSharpDemo/SecureShare/Program.cs new file mode 100644 index 0000000..9d7c770 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/SecureShare/Program.cs @@ -0,0 +1,39 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Windows.Forms; + +namespace SecureShare +{ + static class Program + { + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main() + { + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + Application.Run(new SecureShareManager()); + + } + } +} diff --git a/Demo_Source_Code/CSharpDemo/SecureShare/Properties/AssemblyInfo.cs b/Demo_Source_Code/CSharpDemo/SecureShare/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..cc91c05 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/SecureShare/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("SecureShare")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("SecureShare")] +[assembly: AssemblyCopyright("Copyright © 2018")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("cce6e96f-de72-4554-8f32-a70c75bc8ce0")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +[assembly: AssemblyVersion("5.2.3.2001")] +//[assembly: AssemblyFileVersion("1.0.0.0")] + diff --git a/Demo_Source_Code/CSharpDemo/SecureShare/Properties/Resources.Designer.cs b/Demo_Source_Code/CSharpDemo/SecureShare/Properties/Resources.Designer.cs new file mode 100644 index 0000000..6cb517a --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/SecureShare/Properties/Resources.Designer.cs @@ -0,0 +1,63 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace SecureShare.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // 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", "16.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + 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() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [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("SecureShare.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + } +} diff --git a/Demo_Source_Code/CSharpDemo/SecureShare/Properties/Resources.resx b/Demo_Source_Code/CSharpDemo/SecureShare/Properties/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/SecureShare/Properties/Resources.resx @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/SecureShare/Properties/Settings.Designer.cs b/Demo_Source_Code/CSharpDemo/SecureShare/Properties/Settings.Designer.cs new file mode 100644 index 0000000..0af1322 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/SecureShare/Properties/Settings.Designer.cs @@ -0,0 +1,26 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace SecureShare.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.10.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default { + get { + return defaultInstance; + } + } + } +} diff --git a/Demo_Source_Code/CSharpDemo/SecureShare/Properties/Settings.settings b/Demo_Source_Code/CSharpDemo/SecureShare/Properties/Settings.settings new file mode 100644 index 0000000..3964565 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/SecureShare/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + diff --git a/Demo_Source_Code/CSharpDemo/SecureShare/SecureForm.Designer.cs b/Demo_Source_Code/CSharpDemo/SecureShare/SecureForm.Designer.cs new file mode 100644 index 0000000..fcd000a --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/SecureShare/SecureForm.Designer.cs @@ -0,0 +1,93 @@ +namespace SecureShare +{ + partial class SecureForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(SecureForm)); + this.panel1 = new System.Windows.Forms.Panel(); + this.button_Start = new System.Windows.Forms.Button(); + this.button1 = new System.Windows.Forms.Button(); + this.button2 = new System.Windows.Forms.Button(); + this.button3 = new System.Windows.Forms.Button(); + this.panel1.SuspendLayout(); + this.SuspendLayout(); + // + // panel1 + // + this.panel1.Controls.Add(this.button3); + this.panel1.Controls.Add(this.button2); + this.panel1.Controls.Add(this.button1); + this.panel1.Controls.Add(this.button_Start); + resources.ApplyResources(this.panel1, "panel1"); + this.panel1.Name = "panel1"; + // + // button_Start + // + resources.ApplyResources(this.button_Start, "button_Start"); + this.button_Start.Name = "button_Start"; + this.button_Start.UseVisualStyleBackColor = true; + // + // button1 + // + resources.ApplyResources(this.button1, "button1"); + this.button1.Name = "button1"; + this.button1.UseVisualStyleBackColor = true; + // + // button2 + // + resources.ApplyResources(this.button2, "button2"); + this.button2.Name = "button2"; + this.button2.UseVisualStyleBackColor = true; + // + // button3 + // + resources.ApplyResources(this.button3, "button3"); + this.button3.Name = "button3"; + this.button3.UseVisualStyleBackColor = true; + // + // SecureForm + // + resources.ApplyResources(this, "$this"); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.panel1); + this.MaximizeBox = false; + this.Name = "SecureForm"; + this.panel1.ResumeLayout(false); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.Panel panel1; + private System.Windows.Forms.Button button3; + private System.Windows.Forms.Button button2; + private System.Windows.Forms.Button button1; + private System.Windows.Forms.Button button_Start; + } +} \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/SecureShare/SecureForm.cs b/Demo_Source_Code/CSharpDemo/SecureShare/SecureForm.cs new file mode 100644 index 0000000..432d6f3 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/SecureShare/SecureForm.cs @@ -0,0 +1,19 @@ +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 SecureShare +{ + public partial class SecureForm : Form + { + public SecureForm() + { + InitializeComponent(); + } + } +} diff --git a/Demo_Source_Code/CSharpDemo/SecureShare/SecureForm.resx b/Demo_Source_Code/CSharpDemo/SecureShare/SecureForm.resx new file mode 100644 index 0000000..e34286e --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/SecureShare/SecureForm.resx @@ -0,0 +1,355 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + Arial Narrow, 14.25pt, style=Bold + + + 12, 284 + + + 221, 61 + + + + 3 + + + Online Help + + + button3 + + + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + panel1 + + + 0 + + + Arial Narrow, 14.25pt, style=Bold + + + 12, 201 + + + 221, 61 + + + 2 + + + File Access Log + + + button2 + + + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + panel1 + + + 1 + + + Arial Narrow, 14.25pt, style=Bold + + + 12, 113 + + + 221, 61 + + + 1 + + + Secure File Share + + + button1 + + + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + panel1 + + + 2 + + + Arial Narrow, 14.25pt, style=Bold + + + MiddleLeft + + + 12, 29 + + + 221, 61 + + + 0 + + + Start Secure Agent + + + button_Start + + + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + panel1 + + + 3 + + + + Fill + + + 0, 0 + + + 245, 383 + + + 0 + + + panel1 + + + System.Windows.Forms.Panel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + $this + + + 0 + + + True + + + 6, 13 + + + 245, 383 + + + + AAABAAEAICAAAAEAIACoEAAAFgAAACgAAAAgAAAAQAAAAAEAIAAAAAAAABAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFhQUBhkYGBAZFxcgFxUVOBUT + E04VFBReFhUVZhUUFGIVFBRUFxYWQhkXFyoaGBgUFxUVCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWFBQIGBYWGB0e + HXwgIR/jIiMh+yQmJP8mKCb/JScl/yQlI/0hIyHrHyAfnRoZGSIWFRUKAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACQm + JBwnKie5LjEu/zY5Nf85PDn/OTw5/zk8OP85PDn/Oj06/zg7N/8yNTL/Ky4r2ScpJzoAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAkJiQuKi0q5zY6Nv89QT3/Oz87/zY6Nv87PTf/TEo+/0FBOf81ODX/Oj46/z1BPf86PTr/MDQw+Ssu + K1gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAJCYkGisuK+U6Pjr/P0M//zg7N/9mUD7/rGVC/9VyRP/ZdUb/2HFB/75sRf99WD//Ojw2/z1B + Pf8+QT3/NTg1+y8yL0IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAtLy2zPD87/0VJRP89Pzv/jk81/9FgL//jdzT/6H81/+qEOv/pgDb/5Xk1/9ll + L/+tVTP/RkA5/0JGQf9BRUH/ODs34zI1MQwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAMDIwOjs+O/9KTkr/REdE/4FHMv/XbDj/6X81/++OPf/yl0H/9q1k//Sf + Tv/wkT7/6oM3/+F2Pf+kSy3/RUdC/0tPSv9DRkP/Ojw5dgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA7PTqdSk1J/1JVUv9WSEH/x1kr/+h+NP/zp2T/8aBN/65y + N/9+VzD/kmIz/9yOQP/0pVz/6oY9/9dkLf9xSTv/UlVR/1FUUP9DRkLZAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAERGQ+FYW1f/WFtX/35GNP/fcjX/7ow7//Se + Rf+XaTr/bGlc/35/ef97eG7/aVU8/9yPQv/wkD7/5Hcy/6NPMf9YW1j/X2Jf/09RTv9FSEUcAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQj8IUVRQ/2VoZP9gY1//m04w/+R5 + M//xlkP/3I5A/2deT/+Agn//gIOA/4CDgP94eXL/qXlL//OYQv/ofjT/u1Im/2RlYP9tb2z/XmFd/1RX + U0QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE9TThReYV3/cnVy/3F0 + cf+kVDP/54A7//SraP/Xi0T/oqGY/2ptaf9qbWn/am1p/3x+dv/CmG7/9q9o/+mDOv/CXDD/eHRv/3h7 + eP9sbmv/YmVhUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAXGBbCGxv + bP+DhYL/hoiG/59ZO//kejT/8ZVA/+uWQ//bybz/YGBb/1daVv9WWVT/pqWg/9+dZP/ymEL/5300/7ZR + Jv+Ki4j/iIqH/3d5dv9ucW1CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAfoB93ZOVkv+cnZv/mW9d/992Nv/tjjz/9qVN/+SbXv/NvKr/p6Oc/7qzqv/drIf/8Z1J/++P + Pv/idDL/p2FE/5yenP+Vl5X/gYOB/3Z5dRoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACOkI2XoKGf/62vrf+tqKX/vF8v/+aDNv/zq2X/97Fh/+2hVv/rqGv/66Fd//So + WP/0rGj/6IM4/81hK/+mjoP/qqyq/5+gn/+LjYrTAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAJqbmTKoqaj/u7y7/8LDwv+tj4L/0HI5/+iNRP/wo1r/86pe//W2 + cf/0ql//8aNb/+qSTv/Zdjz/pm5W/7/Av/+4ubj/paal/5SVk2wAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALCwr6W/wL//z8/P/9PT0/+zlIj/u2Av/+KI + R//ql1T/7KBg/+qZV//kjE3/xWMt/6Z1Yf/Ny8r/y8vL/72+vf+pqqnZm5uaCAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAtbe0ELe4t+3R0tH/3d3d/97e + 3v/Ox8X/sIV1/7FsTP+yZD7/sGZE/615Zf+9saz/19jX/9jZ2P/Q0dD/urq6+66vrjIAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAXF1c28zM + y//c3Nz/5+fn/+bn5v/n6Of/5+jn/+Ld0//m5ub/5ubm/+Hh4f/k5OT/2tva/8nKyf93eHfvAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AABPUE7Zu7m3/7q7uvnj4+P75ubm/+jo6P/r6+v/6dq9/+rq6v/o6Oj/5OTk/9/g3/+5urn7vby5/2Rl + Y+8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAFpbWte7urf/cnNy2+Hh4CDo6OeB7e3txe3u7e/t7u3/7O3s9+rr6tPk5OSV3N3cNmZo + ZsO8vLr/Zmdl7wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAY2Rj08fHxP9xcnHdAAAAAAAAAAAAAAAAAAAAAO/v7wIAAAAAAAAAAAAA + AAAAAAAAenx6w8jIxv9rbGvvAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABrbGvR3d3b/3J0ct0AAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACFhoXD2tvZ/3FxcO8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAG1ubc3p6ej/cnNy4wAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAHt8e8vk5OT/bGxs6wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbm5ur+Pj4v94eXf9ODo5FAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABUVlMGfX588+Lj4v9hYmHNAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABqa2puycnI/66u + rv8+Pz54AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF5gXmakpaT/zc7O/1laWYkAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFBR + UBSHh4bz6erp/2lqafdKTEo8AAAAAAAAAAAAAAAAAAAAAAAAAABoaWc2cnNy8eLj4v+Wl5b5UlNSIgAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAFxcW3K2trb/1tbW/3l7efleYF6JYGJgLmBiYBJmZ2YueXp4iYGCgPfOzs3/xsfG/3N0 + c4EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAG9vbp3BwcH/3t7e/5aXlv93eHf/fH18/4CBgP+ampn/1tbW/8XG + xf97fHujUFBPAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAG9wb2yhoqHv2NnY/+jp6P/f4N//5+fn/9bX + 1v+hoqHtdnd2bAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFdYVwx6e3paj5CPkZuc + m5+Pj46PeXl4VltcWwoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA///////4B///4AP//8AB//+AAP//AAB//wAAf/4AAD/+AAA//gAAP/4A + AD/+AAA//gAAP/4AAD//AAB//wAAf/+AAP//gAD//4AA//+ICP//j/j//4/4//+P+P//j/j//8/4///H + 8f//4cH//+AD///4D////j////////////8= + + + + CenterScreen + + + SecureShare + + + SecureForm + + + System.Windows.Forms.Form, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/SecureShare/SecureShare.csproj b/Demo_Source_Code/CSharpDemo/SecureShare/SecureShare.csproj new file mode 100644 index 0000000..b1eb9ae --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/SecureShare/SecureShare.csproj @@ -0,0 +1,191 @@ + + + + Debug + x86 + 8.0.30703 + 2.0 + {32877C42-32C7-411F-B110-CF2FD9CF11D8} + WinExe + Properties + SecureShare + SecureShare + v4.5 + + + 512 + SAK + SAK + SAK + SAK + + + AnyCPU + true + full + false + ..\..\Release\ + DEBUG;TRACE + prompt + 4 + false + false + + + AnyCPU + pdbonly + true + ..\..\Release\ + TRACE + prompt + 4 + false + false + + + SecureShareManager.ico + + + true + ..\..\Release\ + DEBUG;TRACE + full + AnyCPU + bin\Debug\SecureShareManager.exe.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + true + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + true + false + + + ..\..\Release\ + TRACE + true + pdbonly + AnyCPU + bin\Release\SecureShareManager.exe.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + true + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + true + false + + + app.manifest + + + + + + + + + + + + + + + + + + + + + Form + + + SecureShareManager.cs + + + + + Form + + + ShareFileSettingForm.cs + + + Form + + + ShareFileForm.cs + + + Form + + + ShareFileManagerInLocal.cs + + + SecureShareManager.cs + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + True + Resources.resx + True + + + ShareFileSettingForm.cs + + + ShareFileForm.cs + + + ShareFileManagerInLocal.cs + + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + + + {34CB783E-DDA2-4CE3-80BC-37B25AA33E5F} + CommonObjects + + + {21540012-A296-45CE-8D35-3EA5A07B32A6} + FilterControl + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/SecureShare/SecureShare.csproj.user b/Demo_Source_Code/CSharpDemo/SecureShare/SecureShare.csproj.user new file mode 100644 index 0000000..cf1f6c6 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/SecureShare/SecureShare.csproj.user @@ -0,0 +1,6 @@ + + + + true + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/SecureShare/SecureShare.vs2019.csproj b/Demo_Source_Code/CSharpDemo/SecureShare/SecureShare.vs2019.csproj new file mode 100644 index 0000000..582ea44 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/SecureShare/SecureShare.vs2019.csproj @@ -0,0 +1,232 @@ + + + + Debug + x86 + 8.0.30703 + 2.0 + {32877C42-32C7-411F-B110-CF2FD9CF11D8} + WinExe + Properties + SecureShare + SecureShare + v4.5 + + + 512 + SAK + SAK + SAK + SAK + + + AnyCPU + true + full + false + ..\..\Release\ + DEBUG;TRACE + prompt + 4 + false + false + + + AnyCPU + pdbonly + true + ..\..\Release\ + TRACE + prompt + 4 + false + false + + + SecureShareManager.ico + + + true + ..\..\Release\ + DEBUG;TRACE + full + AnyCPU + bin\Debug\SecureShareManager.exe.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + true + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + true + false + + + ..\..\Release\ + TRACE + true + pdbonly + AnyCPU + bin\Release\SecureShareManager.exe.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + true + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + true + false + + + app.manifest + + + true + bin\ARM64\Debug\ + DEBUG;TRACE + full + ARM64 + 7.3 + prompt + MinimumRecommendedRules.ruleset + + + bin\ARM64\Release\ + TRACE + true + pdbonly + ARM64 + 7.3 + prompt + MinimumRecommendedRules.ruleset + + + + + + + + + + + + + + + + + + + + + Form + + + ConsoleForm.cs + + + + ShareFileManagerInServer.cs + + + + + True + True + Reference.svcmap + + + + SharedFileAccessLogForm.cs + + + Form + + + ShareFileSettingForm.cs + + + Form + + + ShareFileForm.cs + + + Form + + + ShareFileManagerInLocal.cs + + + + ConsoleForm.cs + + + ShareFileManagerInServer.cs + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + True + Resources.resx + True + + + SharedFileAccessLogForm.cs + + + ShareFileSettingForm.cs + + + ShareFileForm.cs + + + ShareFileManagerInLocal.cs + + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + + + + + WCF Proxy Generator + Reference.cs + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/SecureShare/SecureShare2015.csproj b/Demo_Source_Code/CSharpDemo/SecureShare/SecureShare2015.csproj new file mode 100644 index 0000000..63a651d --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/SecureShare/SecureShare2015.csproj @@ -0,0 +1,222 @@ + + + + Debug + x86 + 8.0.30703 + 2.0 + {32877C42-32C7-411F-B110-CF2FD9CF11D8} + WinExe + Properties + SecureShare + SecureShare + v4.5 + + + 512 + SAK + SAK + SAK + SAK + + + AnyCPU + true + full + false + ..\..\Release\ + DEBUG;TRACE + prompt + 4 + false + false + + + AnyCPU + pdbonly + true + ..\..\Release\ + TRACE + prompt + 4 + false + false + + + SecureShareManager.ico + + + true + ..\..\Release\ + DEBUG;TRACE + full + AnyCPU + bin\Debug\SecureShareManager.exe.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + true + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + true + false + + + ..\..\Release\ + TRACE + true + pdbonly + AnyCPU + bin\Release\SecureShareManager.exe.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + true + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + true + false + + + app.manifest + + + + + + + + + + + + + + + + + + + + + Form + + + ConsoleForm.cs + + + + ShareFileManagerInServer.cs + + + + + True + True + Reference.svcmap + + + + SharedFileAccessLogForm.cs + + + Form + + + ShareFileSettingForm.cs + + + Form + + + ShareFileForm.cs + + + Form + + + ShareFileManagerInLocal.cs + + + + ConsoleForm.cs + + + ShareFileManagerInServer.cs + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + True + Resources.resx + True + + + SharedFileAccessLogForm.cs + + + ShareFileSettingForm.cs + + + ShareFileForm.cs + + + ShareFileManagerInLocal.cs + + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + + + + {34cb783e-dda2-4ce3-80bc-37b25aa33e5f} + CommonObjects2015 + + + {21540012-A296-45CE-8D35-3EA5A07B32A6} + FilterControl + + + + + + WCF Proxy Generator + Reference.cs + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/SecureShare/SecureShareManager.Designer.cs b/Demo_Source_Code/CSharpDemo/SecureShare/SecureShareManager.Designer.cs new file mode 100644 index 0000000..c47b8c3 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/SecureShare/SecureShareManager.Designer.cs @@ -0,0 +1,202 @@ +namespace SecureShare +{ + partial class SecureShareManager + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(SecureShareManager)); + this.menuStrip1 = new System.Windows.Forms.MenuStrip(); + this.optionsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.shareManagerToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.exitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStrip1 = new System.Windows.Forms.ToolStrip(); + this.toolStripButton_StartFilter = new System.Windows.Forms.ToolStripButton(); + this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); + this.toolStripButton_Stop = new System.Windows.Forms.ToolStripButton(); + this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator(); + this.toolStripButton_ClearMessage = new System.Windows.Forms.ToolStripButton(); + this.toolStripSeparator3 = new System.Windows.Forms.ToolStripSeparator(); + this.toolStripButton_Help = new System.Windows.Forms.ToolStripButton(); + this.listView_Info = new System.Windows.Forms.ListView(); + this.menuStrip1.SuspendLayout(); + this.toolStrip1.SuspendLayout(); + this.SuspendLayout(); + // + // menuStrip1 + // + this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.optionsToolStripMenuItem, + this.shareManagerToolStripMenuItem, + this.exitToolStripMenuItem}); + this.menuStrip1.Location = new System.Drawing.Point(0, 0); + this.menuStrip1.Name = "menuStrip1"; + this.menuStrip1.Size = new System.Drawing.Size(974, 28); + this.menuStrip1.TabIndex = 0; + this.menuStrip1.Text = "menuStrip1"; + // + // optionsToolStripMenuItem + // + this.optionsToolStripMenuItem.Name = "optionsToolStripMenuItem"; + this.optionsToolStripMenuItem.Size = new System.Drawing.Size(74, 24); + this.optionsToolStripMenuItem.Text = "Settings"; + this.optionsToolStripMenuItem.Click += new System.EventHandler(this.settingsToolStripMenuItem_Click); + // + // shareManagerToolStripMenuItem + // + this.shareManagerToolStripMenuItem.Name = "shareManagerToolStripMenuItem"; + this.shareManagerToolStripMenuItem.Size = new System.Drawing.Size(148, 24); + this.shareManagerToolStripMenuItem.Text = "Share File Manager"; + this.shareManagerToolStripMenuItem.Click += new System.EventHandler(this.shareManagerToolStripMenuItem_Click); + // + // exitToolStripMenuItem + // + this.exitToolStripMenuItem.Name = "exitToolStripMenuItem"; + this.exitToolStripMenuItem.Size = new System.Drawing.Size(45, 24); + this.exitToolStripMenuItem.Text = "Exit"; + this.exitToolStripMenuItem.Click += new System.EventHandler(this.exitToolStripMenuItem_Click); + // + // toolStrip1 + // + this.toolStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.toolStripButton_StartFilter, + this.toolStripSeparator1, + this.toolStripButton_Stop, + this.toolStripSeparator2, + this.toolStripButton_ClearMessage, + this.toolStripSeparator3, + this.toolStripButton_Help}); + this.toolStrip1.Location = new System.Drawing.Point(0, 28); + this.toolStrip1.Name = "toolStrip1"; + this.toolStrip1.Size = new System.Drawing.Size(974, 27); + this.toolStrip1.TabIndex = 1; + this.toolStrip1.Text = "toolStrip1"; + // + // toolStripButton_StartFilter + // + this.toolStripButton_StartFilter.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton_StartFilter.Image"))); + this.toolStripButton_StartFilter.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButton_StartFilter.Name = "toolStripButton_StartFilter"; + this.toolStripButton_StartFilter.Size = new System.Drawing.Size(111, 24); + this.toolStripButton_StartFilter.Text = "Start Service"; + this.toolStripButton_StartFilter.Click += new System.EventHandler(this.toolStripButton_StartFilter_Click); + // + // toolStripSeparator1 + // + this.toolStripSeparator1.Name = "toolStripSeparator1"; + this.toolStripSeparator1.Size = new System.Drawing.Size(6, 27); + // + // toolStripButton_Stop + // + this.toolStripButton_Stop.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton_Stop.Image"))); + this.toolStripButton_Stop.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButton_Stop.Name = "toolStripButton_Stop"; + this.toolStripButton_Stop.Size = new System.Drawing.Size(111, 24); + this.toolStripButton_Stop.Text = "Stop Service"; + this.toolStripButton_Stop.Click += new System.EventHandler(this.toolStripButton_Stop_Click); + // + // toolStripSeparator2 + // + this.toolStripSeparator2.Name = "toolStripSeparator2"; + this.toolStripSeparator2.Size = new System.Drawing.Size(6, 27); + // + // toolStripButton_ClearMessage + // + this.toolStripButton_ClearMessage.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton_ClearMessage.Image"))); + this.toolStripButton_ClearMessage.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButton_ClearMessage.Name = "toolStripButton_ClearMessage"; + this.toolStripButton_ClearMessage.Size = new System.Drawing.Size(131, 24); + this.toolStripButton_ClearMessage.Text = "Clear messages"; + this.toolStripButton_ClearMessage.Click += new System.EventHandler(this.toolStripButton_ClearMessage_Click); + // + // toolStripSeparator3 + // + this.toolStripSeparator3.Name = "toolStripSeparator3"; + this.toolStripSeparator3.Size = new System.Drawing.Size(6, 27); + // + // toolStripButton_Help + // + this.toolStripButton_Help.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton_Help.Image"))); + this.toolStripButton_Help.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButton_Help.Name = "toolStripButton_Help"; + this.toolStripButton_Help.Size = new System.Drawing.Size(61, 24); + this.toolStripButton_Help.Text = "Help"; + this.toolStripButton_Help.Click += new System.EventHandler(this.toolStripButton_Help_Click); + // + // listView_Info + // + this.listView_Info.Dock = System.Windows.Forms.DockStyle.Fill; + this.listView_Info.FullRowSelect = true; + this.listView_Info.HoverSelection = true; + this.listView_Info.LabelEdit = true; + this.listView_Info.Location = new System.Drawing.Point(0, 55); + this.listView_Info.Name = "listView_Info"; + this.listView_Info.ShowItemToolTips = true; + this.listView_Info.Size = new System.Drawing.Size(974, 451); + this.listView_Info.TabIndex = 2; + this.listView_Info.UseCompatibleStateImageBehavior = false; + this.listView_Info.View = System.Windows.Forms.View.Details; + // + // ConsoleForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(974, 506); + this.Controls.Add(this.listView_Info); + this.Controls.Add(this.toolStrip1); + this.Controls.Add(this.menuStrip1); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.MainMenuStrip = this.menuStrip1; + this.Name = "ConsoleForm"; + this.Text = "EaseFilter Secure File Sharing Demo"; + this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.ConsoleForm_FormClosed); + this.menuStrip1.ResumeLayout(false); + this.menuStrip1.PerformLayout(); + this.toolStrip1.ResumeLayout(false); + this.toolStrip1.PerformLayout(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.MenuStrip menuStrip1; + private System.Windows.Forms.ToolStrip toolStrip1; + private System.Windows.Forms.ToolStripButton toolStripButton_StartFilter; + private System.Windows.Forms.ToolStripButton toolStripButton_Stop; + private System.Windows.Forms.ToolStripButton toolStripButton_ClearMessage; + private System.Windows.Forms.ListView listView_Info; + private System.Windows.Forms.ToolStripMenuItem optionsToolStripMenuItem; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator1; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator2; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator3; + private System.Windows.Forms.ToolStripMenuItem shareManagerToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem exitToolStripMenuItem; + private System.Windows.Forms.ToolStripButton toolStripButton_Help; + } +} + diff --git a/Demo_Source_Code/CSharpDemo/SecureShare/SecureShareManager.cs b/Demo_Source_Code/CSharpDemo/SecureShare/SecureShareManager.cs new file mode 100644 index 0000000..fa51101 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/SecureShare/SecureShareManager.cs @@ -0,0 +1,300 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +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; +using System.Reflection; +using System.IO; +using System.Diagnostics; +using System.Runtime.InteropServices; + +using EaseFilter.FilterControl; +using EaseFilter.CommonObjects; + +namespace SecureShare +{ + public partial class SecureShareManager : Form + { + + EncryptEventHandler encryptEventHandler = null; + FilterControl filterControl = new FilterControl(); + + public SecureShareManager() + { + + GlobalConfig.filterType = FilterAPI.FilterType.MONITOR_FILTER | FilterAPI.FilterType.CONTROL_FILTER | FilterAPI.FilterType.ENCRYPTION_FILTER + | FilterAPI.FilterType.PROCESS_FILTER | FilterAPI.FilterType.REGISTRY_FILTER; + + InitializeComponent(); + + StartPosition = FormStartPosition.CenterScreen; + + encryptEventHandler = new EncryptEventHandler(listView_Info); + + DisplayVersion(); + + } + + private void DisplayVersion() + { + string version = Assembly.GetExecutingAssembly().GetName().Version.ToString(); + try + { + string filterDllPath = Path.Combine(GlobalConfig.AssemblyPath, "FilterAPI.Dll"); + version = FileVersionInfo.GetVersionInfo(filterDllPath).ProductVersion; + } + catch (Exception ex) + { + EventManager.WriteMessage(43, "LoadFilterAPI Dll", EventLevel.Error, "FilterAPI.dll can't be found." + ex.Message); + } + + this.Text += " Version: " + version; + } + + ~SecureShareManager() + { + GlobalConfig.Stop(); + } + + private void MonitorForm_FormClosing(object sender, FormClosingEventArgs e) + { + GlobalConfig.Stop(); + } + + void SendSettingsToFilter() + { + filterControl.ClearFilters(); + + string[] whiteList = null; + string[] blacklist = null; + + FileFilterRule filterRuleShareFolder = new FileFilterRule(); + filterRuleShareFolder.IncludeFileFilterMask = GlobalConfig.ShareFolder + "\\*"; + filterRuleShareFolder.AccessFlag |= (uint)FilterAPI.AccessFlag.ENABLE_FILE_ENCRYPTION_RULE | FilterAPI.ALLOW_MAX_RIGHT_ACCESS; + filterRuleShareFolder.AccessFlag &= (uint)(~FilterAPI.AccessFlag.ALLOW_ENCRYPT_NEW_FILE);// this folder won't encrypt the new file. + filterRuleShareFolder.AccessFlag &= (uint)(~FilterAPI.AccessFlag.ALLOW_READ_ENCRYPTED_FILES);// all process can't read the encyrpted file except the authorized processes. + filterRuleShareFolder.EncryptMethod = (int)FilterAPI.EncryptionMethod.ENCRYPT_FILE_WITH_SAME_KEY_AND_UNIQUE_IV; + filterRuleShareFolder.EncryptionPassPhrase = GlobalConfig.MasterPassword; + + //for whitelist process, it has maximum acess rights. + if (GlobalConfig.ProtectFolderWhiteList == "*") + { + //allow all processes to read the encrypted file except the black list processes. + filterRuleShareFolder.AccessFlag |= (uint)(FilterAPI.AccessFlag.ALLOW_READ_ENCRYPTED_FILES); + } + else + { + //for whitelist process, it has maximum acess rights. + whiteList = GlobalConfig.ShareFolderWhiteList.Split(new char[] { ';' }); + if (whiteList.Length > 0) + { + foreach (string authorizedUser in whiteList) + { + if (authorizedUser.Trim().Length > 0) + { + //not allow to encrypt the new file + uint accessFlag = filterRuleShareFolder.AccessFlag | (uint)(FilterAPI.AccessFlag.ALLOW_READ_ENCRYPTED_FILES); + filterRuleShareFolder.ProcessNameRights += ";" + authorizedUser + "!" + accessFlag.ToString(); + } + } + } + + } + + //for blacklist process, it has maximum acess rights. + blacklist = GlobalConfig.ShareFolderBlackList.Split(new char[] { ';' }); + if (blacklist.Length > 0) + { + foreach (string unAuthorizedUser in blacklist) + { + if (unAuthorizedUser.Trim().Length > 0) + { + //can't read the encrypted files, not allow to encrypt the new file + uint accessFlag = filterRuleShareFolder.AccessFlag; + filterRuleShareFolder.ProcessNameRights += ";" + unAuthorizedUser + "!" + accessFlag.ToString(); + } + } + } + + FileFilter shareFolderFileFilter = filterRuleShareFolder.ToFileFilter(); + shareFolderFileFilter.OnFilterRequestEncryptKey += encryptEventHandler.OnFilterRequestEncryptKey; + filterControl.AddFilter(shareFolderFileFilter); + + FileFilterRule filterRuleProtectFolder = new FileFilterRule(); + filterRuleProtectFolder.IncludeFileFilterMask = GlobalConfig.ProtectFolder + "\\*"; + filterRuleProtectFolder.AccessFlag |= (uint)FilterAPI.AccessFlag.ENABLE_FILE_ENCRYPTION_RULE | FilterAPI.ALLOW_MAX_RIGHT_ACCESS; + filterRuleProtectFolder.AccessFlag &= (uint)(~FilterAPI.AccessFlag.ALLOW_READ_ENCRYPTED_FILES);// all process can't read the encyrpted file except the authorized processes. + filterRuleProtectFolder.EncryptMethod = (int)FilterAPI.EncryptionMethod.ENCRYPT_FILE_WITH_SAME_KEY_AND_UNIQUE_IV; + filterRuleProtectFolder.EncryptionPassPhrase = GlobalConfig.MasterPassword; + + //for whitelist process, it has maximum acess rights. + if (GlobalConfig.ProtectFolderWhiteList == "*") + { + //allow all processes to read the encrypted file except the black list processes. + filterRuleProtectFolder.AccessFlag |= (uint)(FilterAPI.AccessFlag.ALLOW_READ_ENCRYPTED_FILES); + } + else + { + //for whitelist process, it has maximum acess rights. + whiteList = GlobalConfig.ProtectFolderWhiteList.Split(new char[] { ';' }); + if (whiteList.Length > 0) + { + foreach (string authorizedUser in whiteList) + { + if (authorizedUser.Trim().Length > 0) + { + filterRuleProtectFolder.ProcessNameRights += ";" + authorizedUser + "!" + FilterAPI.ALLOW_MAX_RIGHT_ACCESS.ToString(); + } + } + } + } + + //for blacklist process, it has maximum acess rights. + blacklist = GlobalConfig.ProtectFolderBlackList.Split(new char[] { ';' }); + if (blacklist.Length > 0) + { + foreach (string unAuthorizedUser in blacklist) + { + if (unAuthorizedUser.Trim().Length > 0) + { + //can't read the encrypted files + uint accessFlag = FilterAPI.ALLOW_MAX_RIGHT_ACCESS & (uint)(~FilterAPI.AccessFlag.ALLOW_READ_ENCRYPTED_FILES); + filterRuleProtectFolder.ProcessNameRights += ";" + unAuthorizedUser + "!" + accessFlag.ToString(); + } + } + } + + FileFilter protectFolderFileFilter = filterRuleProtectFolder.ToFileFilter(); + protectFolderFileFilter.OnFilterRequestEncryptKey += encryptEventHandler.OnFilterRequestEncryptKey; + filterControl.AddFilter(protectFolderFileFilter); + + string lastError = string.Empty; + if (!filterControl.SendConfigSettingsToFilter(ref lastError)) + { + MessageBox.Show(lastError, "StartFilter", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + + } + + + private void toolStripButton_StartFilter_Click(object sender, EventArgs e) + { + try + { + //Purchase a license key with the link: http://www.easefilter.com/Order.htm + //Email us to request a trial key: info@easefilter.com //free email is not accepted. + string licenseKey = GlobalConfig.LicenseKey; + + string lastError = string.Empty; + + bool ret = filterControl.StartFilter(GlobalConfig.filterType, GlobalConfig.FilterConnectionThreads, GlobalConfig.ConnectionTimeOut, licenseKey, ref lastError); + if (!ret) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("Start filter failed." + lastError, "StartFilter", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + SendSettingsToFilter(); + + toolStripButton_StartFilter.Enabled = false; + toolStripButton_Stop.Enabled = true; + + EventManager.WriteMessage(102, "StartFilter", EventLevel.Information, "Start filter service succeeded."); + } + catch (Exception ex) + { + EventManager.WriteMessage(104, "StartFilter", EventLevel.Error, "Start filter service failed with error " + ex.Message); + } + + } + + private void toolStripButton_Stop_Click(object sender, EventArgs e) + { + filterControl.StopFilter(); + + toolStripButton_StartFilter.Enabled = true; + toolStripButton_Stop.Enabled = false; + } + + private void toolStripButton_ClearMessage_Click(object sender, EventArgs e) + { + encryptEventHandler.InitListView(); + } + + + private void settingsToolStripMenuItem_Click(object sender, EventArgs e) + { + ShareFileSettingForm settingForm = new ShareFileSettingForm(); + settingForm.StartPosition = FormStartPosition.CenterParent; + settingForm.ShowDialog(); + } + + + private void ConsoleForm_FormClosed(object sender, FormClosedEventArgs e) + { + FilterAPI.ResetConfigData(); + GlobalConfig.Stop(); + filterControl.StopFilter(); + Application.Exit(); + } + + private void unInstallFilterDriverToolStripMenuItem_Click(object sender, EventArgs e) + { + filterControl.StopFilter(); + FilterAPI.UnInstallDriver(); + } + + private void shareManagerToolStripMenuItem_Click(object sender, EventArgs e) + { + ShareFileManagerInLocal shareManager = new ShareFileManagerInLocal(); + shareManager.ShowDialog(); + } + + private void toolStripButton_Help_Click(object sender, EventArgs e) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + string helpInfo = "1.Setup the configuration by clicking the settings to test in local or in EaseFilter Server.\r\n"; + helpInfo += "2.Create encrypted files in the share file manager.\r\n"; + helpInfo += "3.Distribute the shared file to the clients.\r\n"; + helpInfo += "4. Copy the shared file to the share file drop folder in the client.\r\n"; + helpInfo += "5. if you want to copy the shared file to real time protected folder in the client, you have to stop the filter service first, or the file will be encrypted again.\r\n"; + helpInfo += "6. Start the filter service in the client.\r\n"; + helpInfo += "7. Open the shared file in the client.\r\n"; + helpInfo += "8. You can check who accessed your files from the access log in the share file manager when you test with the EaseFilter Server.\r\n"; + + MessageBox.Show(helpInfo, "How to use this application?", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + + private void exitToolStripMenuItem_Click(object sender, EventArgs e) + { + FilterAPI.ResetConfigData(); + GlobalConfig.Stop(); + filterControl.StopFilter(); + Close(); + } + + + + } +} diff --git a/Demo_Source_Code/CSharpDemo/SecureShare/SecureShareManager.ico b/Demo_Source_Code/CSharpDemo/SecureShare/SecureShareManager.ico new file mode 100644 index 0000000..d1aa314 Binary files /dev/null and b/Demo_Source_Code/CSharpDemo/SecureShare/SecureShareManager.ico differ diff --git a/Demo_Source_Code/CSharpDemo/SecureShare/SecureShareManager.resx b/Demo_Source_Code/CSharpDemo/SecureShare/SecureShareManager.resx new file mode 100644 index 0000000..a7a44c8 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/SecureShare/SecureShareManager.resx @@ -0,0 +1,1331 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + + 126, 17 + + + + + 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 + AAAAAElFTkSuQmCC + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAAEnQAABJ0Ad5mH3gAAAJFSURBVDhPrdBbSNNxHAXwo2aKl8ZyMy/bKl3WPypvyBQL + iTLCBUoQQdRLYZJGzgqtEKxB5CVSRNuDhkg4NfNBxTKjBokJBkPqRQgNqSU5L7kplTZP7u/vyYd88fPy + 53vO4f/ww6aKtYS/SGuMnTlQrR2JNqu6cRGFyMMeUW8spj6ivfpLPlvcd9i1VMF+1jLnpWFutfJZW2yk + BDpFWcj35p8ltLrvsY81PN6d7hItPmxF9oA/4sW5ThUMac92OuumctkwY6J1sZRdfMDD1kOfxQLvAHVP + EMYHAlAgIqEcutRW3fSN0XSaJ3JoHjtHY1PMcqenjFLDrkGxktmCYbKp4OkLwFERAcpHwU3XRjJo+mRg + Rmf0PO4iF0XIt/4qZlidolbMZO+34aQ9CnwVitciAlJa9zvPDklMtGpcqESCHJZDgSr/CpghybdgV6Fs + Qg8OquF93DVxLfrFLJuevrUoFZFsJQLSfBTur4Qh1Hv/UCNhQgvXjAQOR2BSHnlpnihthh4NUYNjIpIt + JwfWsyiR45G4PKXBpdmDgfNM9eOfBHBIjUYxW2VB5t4OlWf1e1Ukst9G7RAbz9NxKnLp760MMk8is0Lp + 2O0zPayEVszWbGnzNflZfMfQju0iwtIFaYw9heTzK/T+iJVGOtMUzskdMIjJOm1IQjOyxYWFmyfctFeQ + b26TnQX8mhTyzaGETtT/R8DPdf3IIt1vydHHZH8xPQ9zuJAc8lRMNsY47JuND7JMZ4b3Ok/rP06eiZtz + pSh6Rb0ZgH+3pe/eCrdDkgAAAABJRU5ErkJggg== + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAAEnQAABJ0Ad5mH3gAAAI3SURBVDhPrZPNaxpBGMaHfvwNrZe2t/ZW6Kn9B3oJpee2 + 9FpoDukmEbHWKBRDDw1iiCFUhbCINArRJGBjKUtBBKMs+IHFGKNbxa/UVKqRukbdp7M6PYT2kEMeGHZ2 + dn7Ps++8DLlQmc1fr4RC5WeBwMEnQSi2wuGiIgg5ZXs70XK5vgRXVoJPfT7fZbb9rPb3cScSaaYqld/4 + n7pdQBRrcDi2kl6vcJthE0WjvVt7ez+P2F4oCtCTRyAP1kHur6PVAo6PgVoNqFYBl8vfsNn4GwwnJBgs + bQ6HE1h9/p1/jh+NBwZAowGUy8DhISBJgMn03sdwQiKRRl8FRiNAloF+jya2T5GWOrDuSBjSqioVoFgE + stnJ3G73yAwnJB6n9lR9anNyQk0o8Hz1ANemY7g5Gwfoe6kE5PNAJjMxWlvzKgwnZHf3W0Wtu9MB2m16 + YNREFXmZAplO0gUKFSbpqRRQrwNarTnJcELcbpHL53+N/0A16dHRbCsgr8sghjKkugKJ1q6mqwfp8YQU + nW5hiuFq/82X/P4Mn802xyYDmvh46xQah4zrjh6mfH0UaHouB8RiRczP698x9KwCgfQLnheq0UgBP77L + GNDWddXW0fQ0rUQ9A6fTO7JYLBqG/CtRFK/SPj9cXnabFhftH+bmFj5ubISRSACFwpCmG4Js6/nEcQYN + z++MW7e05JSNRuNd9ul8MpnevqL3ATabq6/Xv3nCls8nq3X1kVarq8zMzG5yHHePLV+kCPkDsM7o3DIQ + mQoAAAAASUVORK5CYII= + + + + + AAABAAEAgIAAAAEAIAAoCAEAFgAAACgAAACAAAAAAAEAAAEAIAAAAAAAAAABABMLAAATCwAAAAAAAAAA + AAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAIAAAADAAAAAwAA + AAQAAAAEAAAABAAAAAMAAAADAAAAAgAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAEAAAABAAAAAgAAAAQAAAAFAAAACAAAAAkAAAAKAAAACwAAAAsAAAALAAAACgAAAAkAAAAHAAAABQAA + AAMAAAACAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAACAAAAAwAAAAUAAAAIAAAADAAAAA4AAAASAAAAFQAA + ABgAAAAaAAAAGgAAABoAAAAXAAAAFQAAABEAAAAOAAAACgAAAAcAAAAFAAAAAgAAAAEAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABAAAABAAA + AAYAAAAKAAAADgAAABQAAAAZAAAAHQAAACIAAAAmAAAAKgAAAC0AAAAuAAAALgAAACwAAAAoAAAAJAAA + AB4AAAAXAAAAEgAAAA0AAAAJAAAABQAAAAIAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAABAAAAAgAAAAUAAAAJAAAADwAAABQAAAAYAAAAGgAAACUAAQE3AQEBRAEB + AU0BAQFQAAEBTAAAAEYAAAA+AAAAPQAAAD0AAAA6AAAAMwAAACsAAAAjAAAAGwAAABMAAAANAAAACQAA + AAUAAAACAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAQAAAAIAAAADQAA + ABIAAAATAAAAIRAREUkuLi6DTk1NsHBsbNN9eHjqhoGB9oN+fvN3c3PiYV9fzD08PK0fHx+EAAEBXAAA + AEoAAABGAAAAQgAAADkAAAAvAAAAJAAAABsAAAASAAAACwAAAAcAAAADAAAAAgAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAQAAAAIAAAAFAAAACwAAAA8AAAAPAgICJicoKG1cWlq9iYOD9qaenv+zqan/taqq/7es + rP+4ra3/ua2t/7itrf+3rq7/tKur/56YmP93c3PpPT09sg4ODnUAAABRAAAASwAAAEUAAAA6AAAALQAA + ACEAAAAXAAAADwAAAAgAAAAEAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAADAAAABwAAAAwAAAAMAQEBGygo + KG1oZmbUnpaW/7OoqP+2qqr/sqam/7asrP+/trb/x8C//83Gxf/LxMP/x7++/7+1tf+4ra3/uq+v/72y + sv+0q6v/jIeH90ZFRb0MDAx1AAAAUwAAAE4AAABDAAAANQAAACgAAAAcAAAAEgAAAAsAAAAGAAAAAwAA + AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAABAAAABAAAAAgAAAALAAAADBscHEtgXl7DnZWV/7Spqf+zqKj/s6io/8S8vP/Y0tH/2dLN/8nC + vf+zqqv/p5ye/6qfof+5sK//0MnD/9rU0f/Tzc3/wbi4/7mvr/+/tbX/t6+v/4WBgfQ2NjatAgICZQAA + AFIAAABLAAAAPQAAAC4AAAAhAAAAFQAAAAwAAAAHAAAAAwAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAQAAAAJAAAACQYHBxs/Pz+KioaG9rKo + qP+zp6f/s6en/8vEw//g29f/xr67/5KGj/9uY3//YVeD/2Zelf9qZJ7/aGKc/2BYjP9hV33/eGp8/6OX + mP/TzMf/3tnX/8W9vf+7sbH/wrm5/62np/9mZWXeFBQUhAAAAFcAAABRAAAAQwAAADMAAAAlAAAAGAAA + AA8AAAAIAAAAAwAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAEAAAAFAAAACQAAAAYTFBQ1Y2JiwaScnP+1qqr/sKSk/8O6uv/i3Nr/xby5/4B0hf9gWIf/bGqw/4KC + z/+Ki93/kJHh/5CR4f+QkeP/jY/k/4aI3f96ecj/YVub/2FVdv+Wio7/1c7J/9vW1f/AuLj/wLe3/8C4 + uP+Nior5Li4uqAAAAF4AAABUAAAASAAAADgAAAAoAAAAGgAAAA8AAAAIAAAAAwAAAAEAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAABQAAAAkAAAAGHyAgVXp3d+ewpqb/s6io/7Wq + qv/a1dP/1s/K/4h8iP9dVYn/dHO+/4qL2/+Oj97/jIzc/4yM2/+MjNz/jIzc/4uM3f+Ljd//jI3g/42O + 5P+PkOj/hYXb/2Zhpf9dUHH/opWV/+Ld2v/Qysr/vrW1/8a9vf+ooqL/SEhIxwICAmkAAABWAAAASwAA + ADsAAAAqAAAAHAAAABAAAAAIAAAAAwAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAA + AAUAAAAHAAAACTc4OHSOiYn4tqur/7Glpf/BuLj/5eDd/7KoqP9hV37/ZGOv/3x+1P+Agtb/f4DU/4CA + 1f+Bgdf/goLZ/4WF2v+Ghtv/h4jd/4mJ3v+KiuD/i4vh/4uL4f+NjeP/kJHo/4KE2f9dVpH/cGJ0/8zD + v//f29r/wrm5/8e9vf+4sbH/YF9f2gsLC3cAAABWAAAATgAAADwAAAArAAAAHAAAABAAAAAIAAAAAwAA + AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAEAAAABgAAAAxBQUGJmZOT/7arq/+wpKT/zcbG/+Pe + 2P+Kfoz/U02O/2hpxf9zdNH/cXLO/3Fyz/9zdND/dHTS/3Z11P93d9X/eHjX/3t72P99fdv/f3/c/4CA + 3f+Dg+D/hobg/4iH4P+JieH/jI7l/46Q6P9wb7z/V0tw/6mdnP/n4t//ycHB/8a9vf/Curr/cW9v5g4O + Dn8AAABYAAAATwAAAD0AAAAsAAAAHAAAABAAAAAIAAAABAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAABQAA + AAUAAAAMR0ZGmp+YmP+3q6v/saam/9jS0f/X0Mv/bmOB/05MoP9jZcn/ZWbJ/2RlyP9lZsr/ZmfL/2do + zv9pac//amrR/2tr0v9ubtX/cHDX/3Jy2P90dNn/dXXb/3h43f97e93/fX3e/4CB3/+Dg+D/hofi/42O + 6f+Cg9n/Vk2C/4t+hP/k4Nz/0MrK/8W8vP/Gvr7/fXt77xISEoYAAABYAAAAUAAAAD4AAAArAAAAGwAA + AA8AAAAIAAAAAwAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAQAAAAFAAAAC0hHR5qmnp7/t6ur/7Opqf/g29n/y8K+/1xT + fv9JSaz/WlvE/1hZwv9YWcP/WFnF/1pbxv9bXMn/W1zK/11czP9eXs7/YGDQ/2Fh0f9kZNT/ZWXV/2ho + 1/9qatn/bW3Z/29v2v9yctz/dXXd/3h43f97fN//f4Dg/4WH5f+GiOT/W1aX/3dodP/e2dT/1tDQ/8a9 + vv/Mw8P/gX5+7xESEoYAAABYAAAATwAAADwAAAArAAAAGgAAAA8AAAAHAAAAAwAAAAEAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAABQAA + AAtISEiZpp6e/7esrP+zqar/497b/8K5tf9PR3//QUOv/01Pvv9MTbz/S02+/0xNv/9NTsL/Tk/E/09Q + xv9QUMf/UVHJ/1NTy/9UVM3/V1bQ/1lZ0f9aWtP/XFzV/19f1v9hYdf/ZGTY/2dn2f9qatn/bW7b/3Bx + 3P9zdd3/d3nf/3x+4v+Chuj/Xlyn/2tcbP/b1M//2tTU/8i/v//NxcX/gX9/7xISEoYAAABYAAAATgAA + ADsAAAApAAAAGQAAAA0AAAAGAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAABAAAAAwAAAAUAAAAFQ0NDj6Sdnf+4rKz/tKqq/+Pf3P++trb/RD2A/zo7 + rf9BQ7f/QUK2/0FBuP9AQbv/QUG8/0JDvv9DQ8D/REPC/0VExf9GRsf/R0fJ/0lJy/9KSsz/TU3P/05O + 0f9RUdP/U1PT/1ZW1P9ZWNX/W1vW/15f2P9hY9j/ZWba/2lq2/9sbt3/cHLe/3V34f99gej/XVyu/2BR + av/UzMf/29bW/8nBwf/Oxsb/e3l57QwMDH0AAABYAAAATQAAADkAAAAmAAAAFwAAAAwAAAAFAAAAAgAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAFAAAAAkA/ + P3ufmJj/uK2t/7Sqqv/k393/wbm4/0A7gv8tMKr/Njey/zU2sf81NrL/NTW1/zU1tv82Nrn/Nja7/zg4 + vf84OL//OjrB/zs7xP88PMb/PT7J/0A/yv9CQsz/Q0PP/0VF0P9ISND/S0rR/01N0/9RUdT/VFXV/1ZY + 1v9aXNj/XWDZ/2Fk2/9maN3/aWzd/25y4P91euj/XF20/19Qaf/Vzsj/29fX/8vDw//LxMT/cnBw5QkK + CnYAAABXAAAASgAAADYAAAAkAAAAFQAAAAsAAAAEAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAEAAAACAAAABQAAAAA2NjZjl5KS/biurv+0qqr/49/c/8W9uv88NoD/IyWk/ysr + q/8qKqv/Kiqt/ykqsP8pKrL/Kiq0/yortf8rK7j/LCy6/y0tvf8uLr7/MDDB/zAxw/8xMsX/NDPI/zU1 + y/84OMz/OjrN/z09zv8/QM//QkLQ/0VF0f9IStL/S07U/05R1f9SVdf/V1na/1te2/9fYtz/Y2fe/2ds + 4f9wduj/VVey/19Raf/e2NH/29bW/87Hx//Jw8P/YmBg2gMEBG0AAABWAAAARwAAADIAAAAhAAAAEwAA + AAkAAAAEAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAUAAAAAIiIiSY2J + ifG5r6//s6mp/97Z1//QyMX/Qjt8/xcZnP8fIKX/HyCl/x4fqP8eH6r/Hh+s/x4frf8eH7D/Hh+y/x8h + tP8gIbf/IiG5/yMjvP8jJL7/JCXB/ycnwv8pKcX/KirJ/ywsyf8vL8n/MTLL/zQ1zP83OM3/OzvO/z0/ + 0P9AQ9L/REfU/0hL1f9LT9b/T1TZ/1RZ2/9YXt3/XGPf/2Fo4v9ocOn/T1Cq/2pbbP/h3Nf/2tTU/9HK + yv/Dvr7/Tk5OyAAAAGMAAABUAAAAQwAAAC8AAAAeAAAAEAAAAAcAAAADAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAEAAAADAAAAABQVFSt8eXniua+v/7Opqf/Y0tH/3NXP/0lCf/8MDpX/FBWf/xMU + n/8TFKH/ExSk/xMUpv8SE6f/EhOq/xITrP8SE6//FBSx/xQUtP8VFbb/Fxe5/xcYu/8YGb7/GxvB/x0c + w/8eHsX/ISHG/yMjx/8mJ8j/KSrJ/ywty/8vMMz/MjTO/zY40P85PNH/PEHU/0BG1v9FStj/Sk/Z/05U + 3P9TWd7/Vl7g/1xk5P9jbev/SEih/3Zncv/n49//1tHR/9XOzv+4tLT/OTk5tAAAAF0AAABSAAAAPwAA + ACsAAAAaAAAADgAAAAYAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAELCwsSamhoxras + rP+1qqr/z8jH/+nj3P9cU4T/BQeM/wsNmv8MDZr/DA2d/wwNn/8MDaH/DA2j/wsMpf8LDKj/Cwyr/wsM + rf8LC6//Cwuy/wwMtP8MDbf/DA25/w0Ou/8PD77/ERHA/xMTw/8VFcP/FxjE/xobxv8dHsf/ISLI/yQm + yv8nKcz/Ky3N/y8z0P8yN9L/NjvU/zpA1v8/Rdn/REvb/0hQ3f9NVeD/UVvi/1hh5v9daOn/QT+S/4h5 + fv/s6eX/083N/9jR0f+ppaX/IyMjnAAAAFgAAABPAAAAOgAAACcAAAAXAAAACwAAAAUAAAABAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAIAAAADAAAAA0tKSpuupaX/uK2t/8S8vP/w7OT/d26P/wgJh/8LDZf/DQ+Z/w0O + m/8NDp3/DQ6g/w0Oov8NDqT/DA2n/wwNqf8MDar/DA2t/wwNr/8MDLL/Cwu1/wsLtv8KC7n/Cgu7/woK + vf8KCr//CgrA/wsLwP8MDcH/DxDD/xITxP8WF8X/GBvI/xwfyv8gIsv/JCjO/ygt0P8rMdL/LzfU/zQ8 + 1/85Qdr/PUfc/0JN3v9HUuH/TVjj/1Nf6v9UYeb/Pjl//6GTkf/v6+r/08zM/9rT0/+MiorzDxAQgwAA + AFcAAABKAAAANQAAACIAAAATAAAACQAAAAMAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAABAAAAAA8PT1uoZub/7uw + sP+9s7P/8u3o/5iQof8QEIL/CQyV/w0Pl/8ND5n/DQ6c/w0Onv8OD6H/Dg+j/w0Opf8NDqj/DQ6p/wwN + rP8MDa7/DA2x/wwMs/8MDLX/DAy3/wsMuv8LC73/Cwu//wsLwf8LC8H/CgrB/woLwf8KC8H/CwzD/wwN + w/8NEMX/EBTH/xUZyv8ZHcv/HSLO/yEo0f8kLdP/KTLW/y442P8zPtv/OUPe/z1K4f9CUOP/SFXm/09e + 7f9MWd3/Qjhv/7uxrf/q5+b/1M3N/9XQ0P9tbGzgAwQEbQAAAFQAAABEAAAALwAAAB0AAAAPAAAABwAA + AAIAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAMAAAAAISIiO46JifC9srL/t66u/+rm4v+6srf/IB1//wgKk/8OEJb/DhCY/w4Q + mv8OD5z/Dg+e/w4PoP8OD6P/Dg+m/w0OqP8NDqv/DQ6t/w0OsP8NDbH/DQ2z/w0Ntv8MDbj/Cw27/wwM + vf8MDMD/CwvB/wsLwf8LDML/CwzC/wsNwv8MDcL/Cw3D/wsOxf8LD8b/DBHI/w4Uyf8SGMz/Fh3P/xsi + 0f8fKdX/Iy/Y/yg02/8uO93/NEHh/zhH5P89Tub/RFTp/0te8/9CTs//T0Fm/9bOx//k4OD/2NLS/8nF + xf9HR0fCAAAAXwAAAFIAAAA/AAAAKgAAABkAAAAMAAAABQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAA8QEBRwbm7Mua+v/7es + rf/b1tX/29TQ/zs2gP8GCI//DxCU/w4Qlv8OEJj/DxCb/w8Qnf8PEJ//DxCi/w8QpP8OD6b/Dg+p/w4P + q/8OD63/Dg+w/w4Osf8NDbT/DQ22/wwNuf8MDbv/DAy9/wwMwP8MDMH/DAzB/wwNwv8MDcL/DA3C/wwN + w/8MD8T/DBDF/w0Rx/8NEcj/DBLK/w0Uy/8NFc7/ERnR/xUf0/8aJtf/Hiva/yQy3f8pOOD/Lz/j/zRG + 5/85TOn/QFPt/0dd9v84QLP/aFhr/+jj3v/d2Nj/3dfX/7Ovr/8nJyefAAAAVwAAAE4AAAA4AAAAJAAA + ABUAAAAKAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAMpKSkATExMlbCnp/+6sLD/y8XE/+/r4/9iW4z/BwmK/w8Qkv8PEZP/DxGW/w8R + mf8PEZv/DxCe/w8QoP8PEKP/DxCk/w4Ppv8OD6n/Dg+r/w4Prf8OD7D/Dg6z/w4Otf8ODrf/DQ65/w0N + u/8MDL7/DQ3A/w0Nwf8MDMH/DAzC/wwNw/8NDsP/DQ7E/w0Pxf8NEMb/DRHI/w0Syf8NFMr/DhXN/w4W + zv8OF9H/DhnT/xAd1v8UItn/GSnc/x4v4P8lN+P/Kz7m/zBF6v82S+7/PFPy/0FZ9/8yNJP/i3yA//Dt + 6v/a1NT/4NnZ/4yKivINDQ1+AAAAVgAAAEcAAAAxAAAAHwAAABEAAAAHAAAAAgAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAACkpKVGclpb/vbOz/761 + tf/08ev/koui/w4PhP8ND5D/EBGR/w8RlP8PEpf/EBKZ/xARm/8QEJ3/DxCg/w8Qo/8PEKX/Dg+n/w4P + qv8OD6v/Dg+u/w8PsP8PD7P/Dw+1/w4PuP8NDrr/DQ27/w0Nvv8NDcH/DQ3B/w0Nwf8NDcL/DA3C/w0P + xP8ND8T/DRDG/w0Rx/8OEsj/DhPJ/w4Vyv8OFs3/DxbQ/w8Z0f8PGtT/DxvW/w8e2P8RIdz/FSff/xou + 4/8gNef/Jz3q/y1E7v8yS/H/OVX5/zpS7/83MHT/t6um/+7r6v/b1dX/2NPT/19fX9UAAABkAAAAUwAA + AEAAAAArAAAAGQAAAA0AAAAFAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAgAAAAATExMeenh42b60tP+5r6//6OTh/8W+wv8jIYH/Cg2N/xETkP8REpP/EBKV/xAS + mP8QEpn/EBKb/xARnv8QEaD/EBGj/xARpf8PEKf/DxCq/w8QrP8PEK7/DxCx/w8Ps/8PD7b/Dw+4/w4P + uv8OD73/Dg6//w0Nwf8ODsH/Dg7B/w0Owv8NDsL/Dg/E/w4QxP8OEcb/DhLH/w4TyP8OFMn/DxXM/w8W + zv8QF8//EBnS/xAb1f8QHtf/ESDZ/xEh3P8RI9//Eifj/xct5v8cNOr/Izzu/ylE8v8wTPX/N1b//zBD + 1P9OQGb/29PM/+bj4//h29v/wL29/zExMasAAABZAAAATgAAADgAAAAkAAAAFAAAAAkAAAADAAAAAQAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAACKisrAFBPT5y1rq7/u7Cw/9PO + zf/q5d//S0WI/wcJif8RE47/EROQ/xESkv8RE5X/EROY/xETmv8QEZz/ERGf/xESoP8REqP/ERKl/xAR + qP8QEar/EBGs/xARr/8QELH/Dw+z/xAPtf8QELj/DxC7/w4Pvf8ODr//Dg7B/w4Owf8ODsH/Dg/C/w4P + wv8PD8T/DxDE/w4Rxv8OEsf/DxPJ/w8Vy/8PFsz/EBbN/w8Y0P8QGtL/ER3V/xEf2P8RINr/EiPc/xIl + 4P8SJ+P/Eyrn/xQt6/8YNO7/Hzzy/yZE9/8tS/r/MlL//ycxq/91ZXH/7+vn/9/b2//k39//lpOT9Q4O + DoEAAABVAAAARwAAADEAAAAeAAAAEAAAAAcAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAwAAAAAqKytRoJqa/7+1tf/Cubn/9/Tu/4N8nv8JC4X/EBKN/xIUjv8SFJH/EhOS/xET + lf8RE5j/EROa/xESnf8REp//ERKh/xESo/8REqX/EBGo/xARqv8QEaz/EBGv/xARsf8QELP/EBC1/xAQ + uP8PELv/DxC9/w8PwP8PD8L/Dg7C/w8Pwv8PD8L/Dg/C/w8QxP8PEcT/DxLG/w8Tx/8QFMn/DxXL/w8W + zP8QF83/EBnQ/xEb0v8RHNX/ER7Y/xIh2/8SJN3/EyXg/xMo4/8UK+f/FC7r/xQw7/8XNPP/HDz3/yND + +f8pSfz/LEn2/yspgv+qnZr/8vDv/9/a2v/d2Nj/YWBg1wAAAGMAAABSAAAAPwAAACkAAAAYAAAADAAA + AAQAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAEBERFnh1ddS/tbX/u7Gx/+vo + 5f/Cu8L/HRuE/w0Pjf8SFIz/EhSO/xIUkP8TFJP/EhSW/xETmP8RE5r/EhOd/xITn/8SE6L/EhOk/xIT + pv8REqj/ERKq/xESrP8REq//ERKy/xERtP8QELb/EBC4/xARuv8QEL3/EA/A/w8Pwv8PD8L/Dw/D/w8Q + w/8PEMP/DxHD/xASxP8PEsb/DxPH/xAUyf8QFsr/ERfN/xEYzv8QGc//ERzS/xIe1f8SINj/EiHb/xIk + 3f8UJuD/FCnj/xQr5/8VLuv/FTHv/xYz8v8WNvb/GTv4/x9A+f8mSP//Ijrd/0I2Z//Y0Mj/6+jo/+Xg + 4P/Cvr7/LS0tpQAAAFgAAABMAAAANgAAACIAAAATAAAACAAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAiIjIwBKSUmKs6ur/72zs//Uzs7/7Ojj/0pFi/8IC43/EhWN/xIUjP8TFY7/ExWR/xMU + lP8SFJb/EhSY/xIUmv8SE53/EhOf/xITof8TFKT/ExSm/xITqP8SE6v/EhOs/xESr/8RErL/ERG0/xER + tv8REbj/EBG6/xARvf8QEL//EBDC/xAQwv8QEML/EBHD/w8Qw/8PEcP/EBLE/xATxv8QFMf/ERXJ/xAV + yv8QF83/ERjP/xIZ0P8SHNL/Eh7V/xIg1/8TIdv/EyTd/xQn4P8UKeP/FSvn/xUu6v8WMO7/FjPy/xY2 + 9f8XOPj/Fzn4/xw++f8iRf//HCeu/3Zmcv/w7un/49/g/+jk5P+OjIzxCQoKeQAAAFQAAABEAAAALgAA + ABsAAAANAAAABgAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAIiMjOZWRkffCuLj/wbm5//bz + 7f+Oh6T/DQ6J/xEUkf8TFY3/ExWM/xMVjv8UFpH/ExSU/xIUlv8TFZn/ExWb/xMVnf8TFJ//ExSh/xMU + o/8TFKb/EhOp/xITq/8SE63/EhOu/xITsf8SErT/EhK2/xESuP8QEbv/ERG9/xERv/8QEML/EBDC/xAQ + wv8QEcP/EBHE/xESxP8RE8X/EBPG/xAUx/8RFcj/ERbL/xIXzf8SGM//ERnQ/xIc0f8THtT/EyDX/xMh + 2v8TJN3/FCfg/xUo4/8VK+b/Fi3p/xYv7f8WM/H/Fjb0/xc4+P8XOPj/Fzj4/xo8+/8cO/T/JyR9/7Kl + n//z8fD/5eDg/9vX1/9PTk7FAAAAXQAAAFAAAAA7AAAAJgAAABQAAAAJAAAAAwAAAAEAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAABAAAAAQMDAwVmZma5vbS0/72zs//l4d//z8jK/yYkh/8ND5P/FBaR/xQWjv8UFo3/FBaP/xQW + kf8UFZP/ExWW/xMVmP8TFZv/FBWd/xQVn/8UFaL/FBWj/xQVpv8TFKn/ExSr/xMUrf8TFK//ExSx/xMT + s/8SErb/EhK5/xESu/8REr3/ERG//xERwf8REcL/EBDC/xERw/8REsT/EBLE/xESxf8RFMf/ERXH/xIV + yP8SF8r/ERfL/xIYzv8SGtD/ExzR/xMd1P8TINf/FCLZ/xQj3P8UJt//FSji/xUq5P8WLOj/Fi/r/xYx + 7/8WNPL/Fzf1/xc5+P8XOfj/Fzj4/xg8//8TKtP/TT9n/+Lb1P/r6Oj/7Ofn/7Gvr/8ZGRmQAAAAVQAA + AEgAAAAxAAAAHgAAAA8AAAAGAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAOTk5XqagoP/BuLj/zcbG//Pv + 6P9gWpP/CAuR/xMVlP8UFpH/FBaO/xQWjf8VF4//FBaR/xQVlP8UFpb/FBaY/xQWm/8UFp3/FBWg/xQV + ov8UFaP/FBWm/xMUqP8TFKv/ExSt/xMUr/8TFLL/ExOz/xMTtv8TE7j/EhO7/xESvf8REb//EhLB/xIS + wv8REcL/ERLD/xESw/8REsT/EhPF/xIUxv8RFMf/ERbI/xIXyf8SF8z/ExnO/xIaz/8TG9L/Ex7U/xQg + 1v8UItj/FCTb/xQl3v8VKOH/FSrj/xYs5v8WLur/FjDt/xYy8P8XNfP/Fzf1/xc5+P8XOfj/Fzj5/xU4 + /v8UHZ3/i3yA//b08f/n4+P/6OTk/29ubtwAAABnAAAAUgAAAD8AAAApAAAAFwAAAAoAAAAEAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAABAAAAABISEhR+e3vTw7q6/7+3t//w7Oj/q6S1/xUViv8QEpj/FRaU/xUXkf8VF4//FReM/xUX + j/8VF5H/FRaU/xQWlv8UF5j/FReb/xUWnP8VFZ//FBWi/xQVo/8UFab/FBWo/xMUqv8TFK3/ExSv/xMU + sv8UFLT/FBS1/xQUuP8SE7r/EhO9/xISv/8SEsH/EhLC/xISwv8SE8L/EhPD/xESxP8SFMX/EhTG/xIV + x/8SFsj/EhfK/xIXy/8TGcz/ExrO/xMc0f8THdT/FB/U/xQi1/8UI9r/FSXd/xUo4P8WKeL/Firl/xYt + 6P8WL+r/FjHt/xYz8P8WNPP/Fjb0/xc39f8XN/b/Fjj6/w8s5/8wKGz/zMO7//Lw8P/s6Oj/ycbG/ywr + K6QAAABXAAAASwAAADQAAAAfAAAAEAAAAAcAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEUFRUARkZGe7Krq//BuLj/19HQ/+bh + 3P9DP43/Cw6Y/xQWmP8VFpX/FRaS/xUXj/8WGI3/FReP/xUXkf8WF5T/FheW/xUXmP8VF5v/FRec/xUW + n/8VFqH/FRaj/xUWpv8VFqj/FBWq/xQVrf8UFa//FBWx/xQUtP8UFLb/FBS3/xQUuv8TFLz/EhK//xIS + wf8TE8L/EhLC/xISwv8SE8P/EhPD/xMUxP8TFMb/EhXH/xIWyP8TF8r/ExfL/xMYzP8TGs//FBzR/xQd + 0/8UH9T/FCDW/xUj2f8VJdv/FSfe/xYp4f8WKeP/Fivm/xYu6P8WL+r/FjDt/xYy7/8WM/H/FjTy/xY0 + 8/8WNPP/FTT5/wwatf9sXXD/8e7p/+vn6P/u6ur/iYiI6wQEBHEAAABTAAAAQAAAACsAAAAYAAAACwAA + AAQAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAABAAAAABQVFR+Jhobmxby8/8S8vP/z8Or/kImm/w4Pkf8TFZz/FReY/xUXlf8WF5P/FhiP/xYY + jv8WGI//FhiR/xYXk/8WF5X/FhiY/xYYm/8VF5z/Fhef/xYXof8WF6P/Fhel/xYXqP8VFqv/FRat/xUW + r/8VFrD/FBSz/xQUtv8VFbj/FBW5/xMUvP8TE77/ExPB/xMTw/8TE8P/ExPD/xMUxP8SFMT/EhTE/xMV + xv8TFcb/ExfI/xMXyf8TGMv/ExnM/xQazf8UG8//FB3S/xQf1P8VINb/FSLX/xUj2v8VJtz/Fijf/xYo + 4v8WKeP/Fivl/xYt6P8WLur/FjDs/xYx7f8WMe7/FjHv/xYw7/8WMfH/ECvs/x8dff+3qqX/9/b1/+3p + 6f/Z1dX/PDw8tQAAAFkAAABMAAAANgAAACEAAAARAAAABwAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEWFhYATUxMjLqxsf/CuLj/39rZ/9fR + z/8wLo3/Dg+e/xUXnP8VF5n/FReW/xYXk/8XGJD/FxmO/xcZjv8XGZH/FxiU/xcYlv8WGJf/Fhia/xYY + nf8WF5//Fheh/xYXo/8WF6X/Fhen/xUWqv8VFq3/FRau/xUWsP8VFrL/FRW1/xUVuP8VFbr/FBW7/xQV + vf8UE8D/FBTC/xQUw/8TE8P/ExTE/xMUxP8TFMT/FBXF/xQWxv8TFsf/FBjJ/xQYyv8UGMz/FBnM/xQb + zv8UHdD/FR7T/xUf1f8VIdf/FSLY/xUk2v8WJt3/Fifg/xYo4v8WKeP/Fivl/xYs5v8WLef/Fi7q/xYu + 6v8WLuv/Fi7r/xUu6v8UL/D/CxvC/1dJav/s5uD/8O3t//Lv7/+ZmJjyCgoKeAAAAFMAAABCAAAAKwAA + ABkAAAALAAAABAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAABAAAAABYWFimQjIzxyL6+/8nBwf/08Or/fnig/wwOl/8VFqD/FRec/xYYmv8WGJf/FxiU/xcZ + kf8XGY7/FxmO/xcZkf8YGZT/GBmV/xYYmP8WGJr/Fxmc/xcYnv8XGKD/Fxij/xcYpv8XGKj/Fhep/xYX + rP8WF67/Fhew/xYXsv8VFbT/FRW3/xYWuv8VFrv/FBW8/xQUv/8UFML/FBTD/xQUw/8UFMT/FBXE/xMV + xP8UFcT/FBbG/xQWxv8UF8j/FBjJ/xQYy/8UGcz/FBvN/xQcz/8VHdH/FR/U/xUg1f8VItf/FSPY/xYk + 2v8WJ93/Fiff/xYo4f8WKeL/Firk/xYr5f8WK+b/Fizn/xYr5/8VK+f/FSvn/xQr5/8QJuj/GBmI/6ib + mP/5+Pb/7+zs/+He3v9GRka+AAAAWQAAAEwAAAA2AAAAIQAAABEAAAAHAAAAAgAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEWFhYATk1Nk7y1tf/Durr/49/d/8zF + yf8oJo//EBKj/xYXoP8WF53/Fhia/xYYl/8XGJX/GBmS/xgaj/8YGo7/GBqQ/xgakv8YGZX/FxmY/xcZ + mv8XGZz/Fxie/xcYof8YGaL/GBml/xgZp/8XGKn/Fxis/xcYrf8WF7D/Fhez/xYWtP8WFrX/Fha4/xYW + u/8VFr3/FRW//xUVwf8VFcP/FBTD/xQUw/8UFcT/FBXF/xQWxf8UFsX/FBbG/xQXx/8VGMj/FRnK/xQZ + zP8VGs3/FRzO/xUcz/8VHtL/FR/U/xUh1f8VItf/FSPY/xYl2v8WJtz/Fife/xYo4P8WKOH/Fini/xYp + 4/8WKuP/FSrj/xUq4/8UKeP/FCji/xQo5v8KGcf/Sj5r/+bg2P/z8fH/9fLy/56dnfcLCwt8AAAAUgAA + AEEAAAAqAAAAGAAAAAsAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAABYWFimRjY3xycDA/8vDw//x7eb/dG+d/wwOnP8WF6T/Fheh/xYYnv8XGZv/FxmY/xgZ + lf8YGpP/GBqP/xgajv8ZG5D/GRuT/xgZlf8YGZf/GBqZ/xgam/8YGp7/GBmg/xgZof8YGaT/GBmm/xgZ + qf8XGKv/Fxit/xcYr/8XGLH/Fxi0/xcXtv8WFrf/Fhe6/xUXvP8VFb7/FRW//xUVwv8VFcP/FRXD/xUV + xP8UFcT/FBXF/xUWxf8VF8f/FRjH/xQYx/8VGcn/FRnK/xUazP8VG87/FRzO/xUd0P8VHtL/FR/U/xYh + 1f8WItf/FSPY/xYk2f8WJdv/Fibd/xYn3v8WJ9//FSjg/xUo4P8VKOD/FSjh/xQm4P8TJuD/EyXf/w8i + 4v8UFYz/oJOU//z6+P/y7+//4+Dg/0ZGRr8AAABZAAAASwAAADUAAAAgAAAAEAAAAAcAAAABAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wAVFRUAFRUVABUVFQAVFRUAFRUVABUVFQAVFRUATk1Nkr22tv/FvLz/497c/8rD + xv8pKJP/EBKn/xcYpP8XGKH/Fxie/xcZm/8XGZn/GBmX/xkalP8ZG5H/GRuO/xkbkP8ZG5P/GRqV/xka + lv8YGpn/GRuc/xkanv8ZGZ//GRqi/xkapP8ZGqb/GBmp/xcYq/8YGa3/GBmu/xgZsf8XGLP/Fxe2/xcX + t/8XF7j/Fxe7/xYXvv8WFcD/FhbC/xYWw/8VFcP/FRXE/xUWxP8VFsT/FRbF/xUXxv8VGMf/FRjH/xUZ + yP8VGcr/FRnL/xUbzf8VG87/FRzO/xUd0P8WH9L/FSDU/xYh1f8WIdf/FSPX/xYk2f8WJNr/FSTb/xUl + 3P8VJtz/FSbe/xQm3v8UJt7/FCXe/xMj3f8SI9z/EiPf/wkWxv9KP27/5uHZ//b09P/49vb/n56e9wsL + C3sAAABRAAAAQAAAACkAAAAWAAAACgAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////ABUVFQAVFRUAFRUVABUV + FQAVFRUAFRUVABUVFSCRjY3rysHB/8zFxf/x7eb/dnGf/w0OoP8WF6n/Fxil/xcYov8XGJ//GBqd/xga + mv8YGpf/GRqV/xkbkv8ZG4//GhuP/xobkv8aG5T/GhuW/xkbmf8ZG5v/GRuc/xkbn/8ZGqL/GRqk/xka + pv8ZGqf/GBmq/xgZrf8YGa//GBmw/xgZsf8YGLT/GBi3/xgYuf8XGLv/Fhe8/xYWv/8WFsL/FhbD/xYW + w/8WFsP/FhbE/xUWxP8VF8X/FhfF/xYYx/8VGMf/FRnH/xUZyf8WGcr/FRrL/xUbzf8WHM7/FRzP/xUe + 0P8WH9H/FSDT/xUh1f8WIdb/FSHX/xUi1/8VI9n/FSPZ/xUk2f8VJNv/FCTa/xQj2v8UItr/EyLa/xMh + 2v8SINn/Dh3d/xUVjv+hlJX//fz6//Xy8v/k4uL/QEBAtwAAAFgAAABKAAAAMwAAAB0AAAAOAAAABQAA + AAEAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8AERISABESEgAREhIAERISABESEgAREhIASEhIfLu0tP/Gvr7/497d/83G + yP8rKZT/ERKr/xYYqP8XGab/GBmj/xgZoP8YGp7/GBqb/xgbmP8aG5b/GhuS/xobkP8aG4//GhuR/xob + lP8aG5b/GhyZ/xocm/8aHJ3/GRue/xkaof8ZGqP/GRql/xkaqP8ZGqn/GBmr/xgZrv8ZGrD/GRqx/xgZ + s/8YGLb/GBi5/xgYuv8XGLv/Fxe9/xcWwP8XF8L/FhbD/xYWw/8WFsP/FhfE/xYXxf8WF8X/FhjG/xYY + x/8WGcf/FRnI/xYZyf8WGsr/FRrL/xUbzf8WHM7/FRzP/xUe0P8WHtD/Fh/T/xUg1P8VINX/FSHW/xUh + 1v8VItf/FSLX/xQi1/8UIdj/EyDY/xMg2P8TINf/Eh/X/xIe1v8RHdn/CBK//01Bbf/o4tr/9/b2//r4 + +P+Uk5PvBAQEcQAAAFAAAAA8AAAAJQAAABQAAAAIAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAA////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wAREhIAERISABES + EgAREhIAERISABESEhCFgoLbysLC/8zExP/w6+X/gXuj/w4Qof8WF63/Fxmp/xgZpv8YGaT/GRmh/xka + nv8ZG5z/GRua/xobl/8aG5T/GxyR/xsckP8aG5H/GxyU/xsclf8bHJj/Ghya/xocnf8aHJ7/Ghug/xob + o/8aG6X/Ghuo/xobqf8ZGqr/GRqt/xkar/8ZGrL/GRqz/xkZtf8YGLf/GBi5/xgZu/8XGLz/Fxe+/xcX + wf8XF8P/FxfE/xcWw/8WFsP/FhfE/xYXxP8WF8X/FhjG/xYYx/8WGcj/FhnI/xYZyf8WGcr/FRrL/xUb + zf8WG87/Fh3O/xUdz/8VHtD/FR7R/xUf0v8VH9P/FR/U/xUf1f8UH9X/FCDV/xQg1f8UH9X/Ex/V/xIe + 1P8SHdT/EhzT/xEb0/8MF9b/GReH/6ygnf/+/Pv/+ff3/9vY2P8wMDCnAAAAUwAAAEUAAAAuAAAAGgAA + AAwAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AAIDAwACAwMAAgMDAAIDAwACAwMAMzMzW7Ourv/KwcH/3trZ/9fR + z/82NJb/EBKv/xcYrP8XGKr/GBqo/xkapf8ZGqL/GRqf/xkbnP8aHJr/GhyX/xsclf8bHJP/GxyQ/xsc + kf8bHJT/HB2W/xsdmP8aHJr/Gh2b/xsdnv8bHKD/Gxyi/xscpP8bHKX/Gxyo/xobq/8ZGqz/GRqu/xob + sf8aG7L/GRq0/xkZtv8ZGbj/GRm7/xgZvP8YGb7/GBe//xcXwv8XF8T/FxfE/xcXxP8XF8T/FhfE/xYY + xP8XGMX/FxjG/xYZx/8WGcj/FhnJ/xYZyf8WGcr/FhrL/xUbzP8WG87/FhzO/xYdz/8VHc//FR3P/xUd + 0f8VHdL/FR7S/xQe0/8UHtP/FB7T/xMe0/8THdP/ExzS/xIc0f8SGtH/EBrQ/xAZ1P8HDrT/XFBz//Ht + 5//59/f/+vj4/3x7e98AAABkAAAATQAAADcAAAAhAAAAEAAAAAcAAAACAAAAAAAAAAAAAAAAAAAAAP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAgMDAAID + AwACAwMAAgMDAAIDAwFvbW25ycLC/8vDw//u6+X/l5Cr/xMUov8WF7L/GBmt/xgZq/8YGqj/GRqm/xoa + o/8aG6D/Ghye/xocm/8aHJn/GxyW/xwdk/8cHZD/HB2Q/xwdkv8cHZX/HB2Y/xwdmf8bHZv/Gx2d/xsd + oP8bHKL/Gxyk/xscpv8bHKj/Gxyp/xobrP8aG63/Ghuv/xobsv8aG7T/Ghq2/xoat/8aGrn/GRq8/xgZ + vf8YGb7/GBjB/xgYw/8YGMT/FxfE/xcXxP8XGMX/FxjF/xYXxf8XGMX/FxnG/xcZx/8WGcj/FhrJ/xYa + yf8WGcn/FhrK/xUbzP8VG83/FhvN/xUczv8VHM//FRzP/xUcz/8UHND/FBzQ/xQc0P8THNH/ExzR/xMb + 0f8TG9H/ERrQ/xEZz/8RGM7/EBfO/woSzv8jHnz/vrSu//79/P/7+Pj/xcTE/x4eHpEAAABQAAAAPwAA + ACgAAAAVAAAACQAAAAMAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wAmJycAJicnACYnJwAmJycAJicnM6KenvrNxsb/2NPS/+Tf + 2f9OS5r/Dg+v/xgZsv8YGa//GBms/xkaqf8aG6f/Ghuk/xobof8aHJ//Gx2c/xsdmf8cHZf/HB2V/xwd + kv8cHZD/HR6R/x0elP8dHpb/HR6Z/xwem/8cHp3/HB6f/xwdoP8cHaP/HB2l/xwdp/8cHan/Gxyq/xsc + rf8bHK//Gxyx/xscs/8aG7X/Ghq2/xoauP8aGrn/GRq8/xkavv8ZGMD/GBjB/xgYw/8YGMT/GBjE/xcX + xf8XGMX/FxjF/xcYxf8XGMX/FxnG/xcZx/8WGcj/FhrJ/xYayf8WGcn/FhnK/xYay/8VGsz/FRvN/xUb + zf8VG83/FRvO/xQbzv8UG87/FBvO/xMbzv8TGs7/ExrO/xIZz/8SGM7/ERfO/xEWzf8QFsz/DhbQ/woN + pv96bn//+fby//bz8//v7e3/WFhYyAAAAFgAAABGAAAAMAAAABsAAAANAAAABQAAAAEAAAAAAAAAAAAA + AAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAME + BAADBAQAAwQEAAMEBABLS0uGwru7/8vDw//o5OH/tq+6/x4en/8VFrf/GBmy/xkasP8ZGq3/GRuq/xkb + qP8bHKX/Gxyi/xscoP8bHZ7/Gx2b/xwemP8dHpb/HR6U/x0ekP8dHpH/HR6U/x0elv8dHpf/HB6a/xwe + nf8cHp7/HB6f/xwdof8cHaT/HB2n/xwdqP8cHan/Gxyr/xscrv8bHLH/Gxyy/xscs/8bG7b/Gxu3/xsb + uf8aGrr/GRq9/xkav/8ZGMD/GRjB/xgYxP8YGMT/GBjE/xgYxf8XGMX/FxjF/xcYxf8XGMX/FxjG/xcZ + x/8XGcj/FhrI/xYayf8WGcn/FhnJ/xYZyv8WGcr/FRrL/xUazP8UGs3/FBrN/xQazf8UGcz/ExnM/xMY + zP8SGM3/EhjN/xIXy/8RF8z/EBbM/xAWy/8PFcz/CA7F/zgwdP/a08v/+fj3//n29v+enZ31BgYGcQAA + AEsAAAA3AAAAIQAAABAAAAAGAAAAAgAAAAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8AAwQEAAMEBAADBAQAAwQECIJ/f9HPx8f/0crK/+3o + 4f9xbKH/Dg+t/xgYt/8ZGbP/GRqx/xkarv8aG6v/Ghyp/xscpf8bHKT/HByi/xwdn/8cHpz/HB6a/x0e + l/8dHpX/HR6S/x0ekP8dHpP/HR6V/x0el/8dHpn/HB6b/xwenf8cHp//HB2i/xwdo/8cHaX/HB2n/x0e + qf8cHar/Gxyt/xscr/8bHLD/Gxyy/xsctf8bG7f/Gxu5/xsbuv8aG7v/GRu9/xkav/8ZGcD/GRnC/xkZ + xP8YGMT/GBjE/xgYxf8YGMX/FxjF/xcYxf8XGMX/FxjF/xcZx/8XGcf/FhnI/xYZyP8WGcj/FhnI/xYZ + yf8VGcr/FRnK/xUZyv8UGMv/FBjL/xMYy/8TGMv/ExjL/xIXyv8SF8r/ERfK/xEWyf8RFsn/EBTJ/xAU + yf8MEcz/EhGQ/6CVlv/8+/n/9fLy/9bU1P8rKyufAAAATQAAAD8AAAAnAAAAFQAAAAkAAAADAAAAAAAA + AAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wAqKioAKioqACoqKgAqKio+q6am/c/Hx//f2tj/19DO/zg2nf8QErn/GRm3/xkZtP8aG7L/Ghuv/xob + rP8aHKr/Gx2n/xwdpf8cHaL/HB6f/xwenv8cHpv/HR6Y/x0elv8dHpP/Hh6R/x4fkv8eH5T/Hh+W/x4e + mf8eHpv/HR6c/x0en/8dHqH/HR6j/x0epf8eH6f/Hh+o/x0eqv8cHaz/HB2t/xwdsP8bHLL/Gxyz/xsc + tP8bG7b/Gxu5/xsbuv8bG7v/Ghu+/xoav/8ZGcD/GRnC/xkZxP8ZGcT/GBjE/xgYxf8YGMX/FxjF/xcY + xf8XGMX/FxjF/xcZxv8XGcf/FhnH/xYZyP8WGcj/FRnI/xUZyP8VGcn/FRnJ/xUZyf8UGMn/FBjK/xMX + yv8TF8r/ExfJ/xIXyP8SFsj/ERXI/xEVyP8QFMj/DxPH/w4Syv8HCrH/X1V5//Hu5//z8fH/8O3t/2Vl + Zc8AAABZAAAARQAAAC4AAAAZAAAACwAAAAQAAAABAAAAAAAAAAD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AAMDAwADAwMAAwMDAE5OToXHwMD/zsbG/+zo + 5P+moLT/GBim/xYXvf8ZGbj/Ghq1/xobs/8aG7D/Gxyt/xscq/8cHan/HB2m/xwdpP8cHqH/HB6e/xwe + nP8dHpr/Hh6X/x4flP8eH5H/HyCR/x8glP8fIJb/Hx+Y/x8fm/8fIJz/HyCd/x8gn/8fIKL/HyCl/x8g + pv8eH6f/Hh+q/x4frP8dHq3/HB2u/xwdsf8cHbP/HB20/xwctf8bG7f/Gxu5/xsbuv8aG7z/Ghu+/xoa + v/8aGcH/GRnC/xkZxP8ZGcT/GRnE/xgYxP8YGMX/GBjF/xcYxf8XGMX/FxjF/xcYxf8XGMb/FxjH/xYY + x/8WGMf/FRjH/xUYx/8UGMj/FBjI/xQYyP8TF8j/ExfI/xMXyP8SFsj/EhbI/xEVx/8QFcf/EBPG/xAT + xv8PEsb/DxHG/wgLxP8sJnn/z8fB//f19f/28vL/oqCg9QYGBnAAAABKAAAANQAAAB8AAAAPAAAABQAA + AAEAAAAAAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8AAwMDAAMDAwADAwMFfnx8y9DJyf/Uzc3/7Off/21oov8OELP/GRq8/xkauP8aGrf/Gxu0/xsc + sf8bHK//Gxys/xsdqv8cHaf/HB2l/x0eo/8dHqD/HR6d/x0fm/8fH5j/HyCW/yAhlP8gIZL/ICGT/yEi + lf8hIZj/ISGa/yAhm/8gIZ7/ICGg/yAhov8gIaT/ICGl/yAhp/8fIKr/HyCq/x4frP8eH67/Hh+v/x0e + sf8dHrP/HR61/xwctv8cHLf/HBu5/xwbu/8aG7z/Ghu+/xobv/8aGsH/GhnC/xkZw/8ZGcT/GRnE/xgY + xP8YGMX/GBjF/xcYxf8XGMX/FxjF/xcYxf8XGMX/FhjG/xYYx/8WGMf/FRfH/xUXx/8UF8f/FBfH/xQX + x/8TFsf/ExbH/xIVx/8SFcf/ERTH/xEUxv8RE8b/EBLF/xASxf8PEMT/DQ7I/xAPk/+flJf/+vj2//Lv + 7//Ny8v/KSkpmgAAAEsAAAA7AAAAIwAAABIAAAAHAAAAAgAAAAAAAAAA////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wAkJSUAJCUlACQlJSein5/208zM/97Z + 2P/Y08//Pz2f/xESvf8ZGr3/GRq6/xobt/8bHLX/Gxyy/xscsP8bHK7/Gx2r/x0eqP8dHqb/Hh+j/x4f + ov8fIJ//HyCd/yAgm/8hIZj/ISKW/yIik/8iI5P/IiSV/yIkmP8iIpr/ISKc/yEinf8iI5//ISKh/yEi + ov8hIqX/ISKn/yEiqP8hIqr/ICKs/x8grf8fIK7/HyCw/x4fsv8eH7P/HR61/x0ct/8cHLj/HBy5/xwc + u/8aG73/Ghu+/xobwP8aGsH/GhrC/xkZw/8ZGcT/GRnE/xkYxP8YGMX/GBjF/xcYxf8XGMX/FxjF/xYX + xf8WF8X/FhfG/xYXxv8WF8b/FRfG/xUWxv8VFsb/FBbF/xQWxf8TFcX/ExXF/xIUxv8SFMb/EhLF/xES + xf8QEsT/EBHD/w8Qw/8ND8b/CAms/2lefv/y8On/8O3t/+nl5f9RUFC/AAAAUQAAAEAAAAAoAAAAFQAA + AAkAAAADAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////ADY2NgA2NjYANjY2Zb65uf/Rycn/6OPh/7mzu/8mJqn/GRnD/xkavv8aG7v/Ghu5/xsb + tv8bHLP/Gxyx/xwdrv8cHqz/HB+q/x8fp/8fIKX/ICGj/yAhof8gIZ//ISKc/yIimv8iJJn/IyWW/yMk + lP8kJZX/JCaY/yQlmf8kJZv/JCWd/yQln/8kJaH/JCWi/yMjpP8jJKb/IySn/yIjqf8jI6z/ISKs/yAh + rv8gIbD/ICGx/x8gs/8fILT/Hh+1/x0et/8cHLj/HBy5/xwcu/8bHL3/Ghu+/xoav/8aGsH/GhrC/xoa + w/8ZGcT/GRnE/xkZxP8YGMT/GBjF/xgYxf8XGMX/FxjF/xYXxP8WF8T/FhfF/xUWxf8VFsX/FRbF/xQW + xv8UFcT/FBXE/xMUxP8SFMT/EhTF/xITxf8RE8T/EBLE/xARxP8PEMP/DxDD/w4PxP8HCb7/PTR4/+Da + 0v/y8PD/7+zs/4aFheYAAABgAAAARAAAAC4AAAAZAAAACwAAAAQAAAAAAAAAAP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAAEBAAABAQBlZGSbzcbG/9PN + zf/t6eL/jIas/x8ft/8jI8b/Hh/A/xkavP8aG7n/Gxu3/xwctf8cHbP/HR6w/x0erv8eH6v/HyGp/yAh + p/8gIqX/ISKj/yIjoP8iI53/IySc/yQkmv8kJpf/JSeV/yUnlf8mKJf/Jiia/yYnnP8mJ53/Jief/yYn + oP8mJ6P/Jiek/yYmpv8lJaf/JSSo/yQkqv8kJKz/IyOt/yEir/8hIrD/ICGy/yAhs/8gILX/Hx+1/x4e + t/8dHbj/HRy6/xwcu/8cHLz/Ghy9/xobvv8aGsD/GhrC/xoaw/8ZGcP/GRnE/xkZxP8YGMT/GBjE/xgX + xP8XF8X/FxfF/xYXxP8WF8T/FRfE/xUWxP8VFsX/FBXF/xQVxf8TFMT/ExTE/xIUxP8SE8P/EhPE/xES + xP8REsP/EBHD/xARw/8PEMP/Dw/D/woLxP8fGof/u7Kv//b08//x7e3/raur+xESEnoAAABHAAAAMwAA + AB0AAAAOAAAABQAAAAEAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wAAAQEAAAEBB4KAgM/Uzc3/2dTT/+fi2/9jX6P/HBzB/ycnx/8mJsP/ISK//xoc + u/8aG7j/HB22/x0ftP8eH7H/Hh+v/yAhrf8gIqv/IiOp/yMjp/8kJKX/JCWi/yUmof8mJ5//Jied/yYn + m/8oKpj/KCqW/ygql/8pKpr/KSqc/ykqnf8pKp//KSqg/ykqo/8pKqT/KCim/ygop/8oKKn/Jyeq/ycm + rP8mJq3/JCWu/yIkr/8iI7H/ISKy/yAitP8gIbT/HyC2/x8et/8eHrj/HR25/x0cu/8cHLz/Gxy9/xob + vv8aGr//GhrB/xoZwf8ZGcP/GRnE/xkZxP8YGMT/GBjE/xgXxP8XF8T/FxfE/xYWw/8WFsP/FhbE/xUW + xP8VFcT/FBXE/xQVxP8TFMT/ExTE/xITw/8SE8P/EhLD/xERwv8REcL/EBDC/xAPwv8PD8L/DQ3G/woJ + m/+TiJL/+Pbz/+3o6P/Qzc3/LS0tmwAAAEcAAAA3AAAAIQAAAA8AAAAGAAAAAQAAAAD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////ABQVFQAUFRUgn5yc9NjR + 0f/f29n/083L/0VEp/8jI8n/JyfH/ygoxf8oKML/JSa//x0euv8cHbf/Hh+1/x8gs/8gIbH/ICKv/yIj + rf8kJKv/JSSp/yUlp/8mJ6T/Jyij/ygpof8pKp//Kiuc/yosm/8qLZn/Ky2X/ysumf8rLpz/LC2d/ywt + n/8sLaD/Kyyj/ysspP8rLKX/Kyun/yoqqP8qKqr/KSmr/ygorP8nJ67/Jiav/yQmsP8kJbH/IySy/yIj + s/8hIrX/ICG2/yAgt/8eHrj/Hh25/x0duv8cHLz/Gxy8/xocvv8aG77/GhrA/xoZwf8aGcH/GRnC/xkZ + w/8YGMT/GBjE/xgYxP8XF8T/FxfE/xYWw/8WFsP/FRXD/xUVw/8VFcP/FBTE/xQUxP8TE8T/ExPD/xIS + wv8SEcL/ERHC/xERwv8QEML/EBDC/w8Pwv8ODsT/CQmt/2Zcgf/w7Ob/6+jo/+bi4v9KSkq6AAAATAAA + ADsAAAAkAAAAEgAAAAcAAAACAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8AMzMzADMzM1O5tbX/1s/P/+fj4P+8t73/LS2v/yYmzv8pKMn/KSnG/ykp + xP8qK8L/KSq//yMku/8fILf/ICG1/yIjs/8jJLH/JCSv/yUlrf8mJ6v/KCep/ykpp/8qK6X/Kyyj/ywt + ov8sLaD/LS+e/y4wm/8uMJr/LjCa/y8xm/8vMZ7/LzCf/y8woP8uMKP/LS+k/y4vpf8tLqf/LC2o/yws + qv8sLKv/Kyqs/yoqrf8pKa7/Jyiv/yUnsP8lJrH/JCWz/yMktP8hI7X/ICK2/yAgt/8fH7j/Hh65/x4d + uv8dHLv/HBy8/xobvf8aG73/Ghu//xobwP8aGcH/GRnB/xkZwf8YGML/GBjD/xgYxP8XF8T/FxfE/xYW + w/8WFsP/FRXD/xUVw/8UFMP/FBTD/xQTw/8TE8P/ExLD/xISwv8SEsL/ERHC/xERwv8QEML/EBDB/w8P + wf8HCLv/QTl6/+Te1v/t6ur/6OTk/3d2dtoAAABZAAAAPgAAACcAAAAVAAAACQAAAAMAAAAA////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wA6OTkAOjk5eM3H + x//W0ND/6+fi/5yWsv8pKbv/KSrP/ysryv8rK8j/KyvG/yssw/8sLcH/LS6//yoqu/8kJLf/IyS0/yQl + sv8mJ7H/Jyiw/ykprv8rK6z/LCuq/y0tqP8tL6X/LjCk/y8xov8xMaH/MTOf/zI0nP8yNJv/MjSc/zM1 + nv8zNKD/MzOh/zEzo/8xM6T/MTOm/zAyp/8vMaj/Ly+q/y4uq/8tLqv/LC2t/ywrrv8qK6//KCmw/yco + sf8mJ7H/JSaz/yQltP8iI7T/ISK2/yAgt/8fH7j/Hh64/x0duf8dHLv/HBy7/xscvP8aG73/Ghu+/xob + v/8ZGr//GRnA/xkYwP8YGMH/GBjC/xcXwv8XF8P/FxfD/xYWw/8WFsP/FRXD/xUVw/8UFMP/FBTD/xMT + w/8TE8P/EhLB/xISwf8REcH/ERHA/xEQv/8QEL7/EA++/wkLvv8qJYP/ysK///Hu7f/s6Oj/lZSU8QAA + AGMAAABBAAAAKwAAABcAAAAJAAAAAwAAAAD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AAEBAQBtbGyh083N/9nU1P/q5d3/f3ur/yMkxP8tLc//LS7M/y4u + yf8uLsf/Ly/F/y8ww/8wMMH/MTK//zExvP8rLLj/Jyi0/ycosv8qK7D/Kyyv/y0trf8uLqz/Ly+q/y8x + qP8xM6f/MjSl/zM0o/80NqL/NTeg/zY4nv82OJ3/Njie/zY4oP82OKL/Njej/zU3pP80Nqb/NDan/zM1 + qP8yNKr/MTKr/zAxq/8uL63/Li+u/y0ur/8sLK//Kiuw/ykpsv8mKLL/Jiez/yUmtP8jJLT/ISO1/yEi + tv8gILf/Hh64/x4euP8dHLr/HBy7/xwcu/8aG7v/Ghu8/xobvv8ZGr7/GRq//xgZv/8YGL//GBi//xcX + wP8XF8H/FhbB/xYWwf8WFcH/FRXB/xUUwf8UFMD/FBTA/xMTwP8TE8D/EhK//xISvv8REb3/EBG9/xAR + vf8PEbz/DA69/xYTj/+wpqf/8/Hw/+vm5v+zsLD8FxgYewAAAEIAAAAuAAAAGQAAAAsAAAADAAAAAP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAQEBBIB/ + f8bX0dH/3djY/+Te1/9pZaj/JCXN/y8v0P8vMM3/MDDL/zExyv8xMcj/MTPG/zIzxP80NcL/NjXA/zc3 + vv80Nbv/Li+2/ywss/8tLbH/LzCw/zEyr/8yM63/MzSr/zQ2qv82OKj/Njmm/zg5pf85OqP/Ojuh/zo8 + n/86PJ//Ojyh/zo8o/86O6T/Ojul/zg6p/84Oqf/Nzmo/zY3qv81Nqv/MzSs/zIzrf8xMq3/MDGu/y4v + r/8tLbD/Kyyw/yorsf8oKbL/Jiez/yUmtP8jJbT/IiS1/yEitv8gILb/Hx+3/x4et/8dHLj/HBy5/xwc + uv8bG7v/Gxu7/xobu/8aGrz/GRq9/xgavf8YGb7/GBi+/xcYvv8XF7//Fhe//xYXv/8VFr//FRW//xQV + vv8UFL3/ExS9/xMTvf8SE73/EhO9/xESvP8RErv/EBK6/xARuf8OD7z/DQyZ/5WKlv/18u//5+Li/8bD + w/8qKiqUAAAAQgAAADEAAAAbAAAADAAAAAQAAAAA////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wAAAQENj4yM59zW1v/h3dz/1tHO/1RSrf8qK9P/MDDS/zAx + 0P8yMs3/MzPL/zMzyf81Ncf/NjfF/zY3wv84OcH/OjvA/zw9v/88PLz/ODi5/zMztf8yMrL/MzSx/zY3 + sP83OK7/ODms/zk7q/87Par/Oz2o/z0+pv8+P6X/PkCj/z9Bof8/QaH/P0Gj/z5Apf8+P6X/Pj+n/zw+ + qP86Pan/Ojyq/zg6q/83Oav/Njet/zU1rf8yNK7/MTKv/y8wr/8uL7D/LC2w/yorsf8pKrL/Jyiz/yUm + s/8kJbT/IiO0/yEitf8gIbb/Hx+2/x4etv8dHbf/HBy4/xwcuf8bG7n/Gxu6/xsbuv8aGrv/Ghq8/xkZ + vP8YGbz/Fxm7/xcYu/8XGLz/Fhe8/xYXvf8VFr3/FRa8/xQVu/8UFbz/ExS7/xMUuv8TE7r/EhO6/xIS + uf8SErj/ERG3/xAQuf8LC6L/d2yL//Hu6f/l4eH/19PT/zU1NakAAABCAAAAMwAAAB4AAAAOAAAABAAA + AAH///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////ACUl + JSCppaX03tfX/+Tg3//MxcX/RUSy/y4u1v8yMtP/MzTR/zQ1z/82Nsz/NzfL/zg4yf85Ocf/OjvF/zs9 + xP89PsH/Pz/A/0BAv/9CQr3/QkK7/z4+uP85ObT/ODmy/zo7sf89PbD/Pj+u/z9BrP8/Qqv/QUOq/0JE + qP9DRKf/Q0Wl/0RFo/9DRaT/Q0Sl/0JEp/9CQ6j/QUKo/z9Bqv89QKr/PD6r/zs9rP86O63/ODit/zY3 + rf81Nq//MzSv/zEyr/8uL7D/LS6w/ywssP8pKrL/KCmy/yYns/8kJbP/IiOz/yEis/8gIbT/HyC1/x4e + tv8dHbb/HBy3/xwbuP8bG7j/Gxu5/xsbuP8aGrj/Ghq5/xkZuv8YGbr/GBi6/xgYuv8XF7r/Fxe6/xYW + uv8WFrr/FRa6/xUVuv8UFbn/FBS4/xQUuP8TE7f/ExO3/xIStv8SEbb/ERG3/woKqf9eVoX/7enh/+Xh + 4f/g29v/TExMuQAAAEYAAAA1AAAAHwAAAA4AAAAFAAAAAf///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8ALy8vPLezs/zc19f/5uLg/8K7vv85OLb/MzPY/zU1 + 1f82NtL/NzjQ/zg5z/87Osz/OzvL/zw8yv8+P8f/P0DG/0BBxf9DQ8P/RETC/0ZGwP9ISL7/SUm9/0lJ + u/9ERbf/QEG1/z9Asv9CQrH/Q0Ww/0RGr/9FR63/Rkis/0hIqv9ISaj/SEmn/0hJpv9HSKb/R0io/0ZH + qf9GR6n/REWq/0NEq/9BQ6v/P0Gt/z5Arf88Pa3/Ojqu/zc4rv82N6//NDWv/zIzr/8vMK//LS+w/yws + sP8qK7H/Jyqx/yYnsf8kJbL/IiOy/yEis/8gIbT/HiC0/x0etP8dHbT/HB21/xsbtf8bG7b/Gxu3/xsa + t/8aGrj/Ghm4/xkZt/8ZGbj/GBi4/xgYuP8XF7j/Fxe4/xYWuP8WFrj/FRW3/xUUt/8UFLb/FBS2/xMT + tf8TE7T/EhK0/xISs/8RErP/Bwqu/0pBfv/q5Nv/5uLi/+Hc3P9oZ2fLAAAATQAAADYAAAAgAAAADwAA + AAUAAAAB////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wAxMTFPwLy8/93W1v/r5+T/sKq3/zc3vP82Ntn/ODjV/zk51P86OtL/OzvQ/z09z/8/P83/QEDM/0JC + yv9DRMj/REbH/0dHxv9JSMT/SkrD/0xMwv9OTcD/UE+//1FSvv9QUbz/TE25/0hJtf9HSLL/SUuy/0pN + sf9LTa//TE6u/01Orf9NTqv/TU6p/01OqP9MTaj/S0yq/0pLqv9JSqv/R0ms/0VHrP9ERq3/QkSt/0BC + rv8+P67/PDyu/zk6r/83OK//NTav/zM0r/8wMq//Ly+w/y0tsP8rK7D/KCqw/yUnsP8kJbH/IySx/yEi + sv8gIbL/Hh+y/x0fs/8cHrP/HBy0/xsctP8bHLT/Gxy2/xoatv8aGrb/GRm1/xkZtf8YGLb/GBi2/xgX + tv8XF7b/Fxa2/xYWtf8WFbX/FRW0/xUVtP8UFLT/FBSz/xMUsv8TE7H/EhOw/xESsP8JC67/PDWA/9/Z + 0v/n4+P/4dzc/3h2dtgAAABSAAAANgAAACEAAAAPAAAABQAAAAH///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////ADU1NWLLxsb/3tjY/+vo5P+inLP/OzvC/zg4 + 2f86Otb/PDvW/z091P89PtL/QEDS/0JCz/9DQ87/RUTN/0ZHy/9JSsn/S0vI/01Nxv9PT8b/UFHE/1JS + w/9TU8L/VVXB/1dYwP9ZWr//WVq9/1VWuv9QUbb/T1C0/1BRs/9RUrL/UlKw/1NSrv9SVK3/UlOr/1JT + qv9RUqv/T1Cs/05PrP9NTq3/Skyt/0hLrf9FSa3/REau/0JDrv9AQa7/PT+u/zs7r/84Oa//Njev/zM0 + r/8wMa//Li+v/y0tr/8rK6//KCqv/yYor/8kJrD/IiOw/yEisP8fILH/Hh+x/x0esf8dHrL/Gxyy/xsc + sv8bHLP/Gxyz/xobtP8aG7T/GRq0/xkZs/8YGbP/GBi0/xcYtP8XF7T/Fhez/xYXs/8VFrL/FRax/xQV + sf8UFbH/ExSx/xITsP8SE67/ERKu/wsNrf80LoP/1c3J/+nl5P/j3t7/hoSE4wAAAFYAAAA3AAAAIQAA + AA8AAAAFAAAAAf///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8ANjY2bNDLy//f2tr/6ubg/5aRsf85Ocb/OzvZ/z091/8+Ptf/QD/X/0FB1f9DQ9P/RUXR/0dH + 0P9ISM//S0vN/01Oy/9PUMr/UVLJ/1NTyP9VVcf/V1jG/1hZxf9aW8T/W1zD/15fwv9gYcH/YWLA/2Fi + v/9dXrz/WVq4/1ZXtf9WV7T/WFiz/1hZsf9YWbD/V1iu/1ZXrP9VVqz/VFWt/1JTrv9QUa7/Tk+u/0tN + rv9IS67/RUiu/0NFr/9BQ6//PkCu/zw8rv85Oq7/Njev/zQ1rv8xMq//Li+u/y0trv8rLK//KCmv/yYm + rv8kJK//IiOv/yAhr/8fILD/Hh+w/x0esP8cHbD/HB2x/xscsf8bHLH/Ghux/xobsf8aG7L/GRqy/xka + sv8YGbH/GBmx/xcYsf8XGLH/Fhex/xYXr/8VFq//FBWv/xQVr/8TFK7/ExSu/xITrP8SE6z/DA6r/ysn + hv/Lw8L/6ubl/+Pd3f+LiYnqAAAAWAAAADcAAAAhAAAADwAAAAUAAAAB////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wA5OTmA29bW/+Db2//p5N//npi1/z4+ + x/89Pdn/Pz/X/0FB2P9CQtj/RUXW/0ZH1P9ISdP/SkvS/01M0P9PT8//UVHO/1NUzf9VVsz/VlfK/1lZ + yv9cXcn/Xl/H/19gx/9hYcb/Y2TG/2Rnxf9nZ8T/aGjC/2lqwv9qa8H/Z2i+/2Njuv9fYLf/XV21/11d + tP9dXrH/XF2w/1tcrv9ZWq7/V1iv/1VWr/9TU6//UFCv/01Pr/9KTK//R0mv/0VHr/9CRK7/P0Gu/zw9 + rv85Oq7/Nzet/zQ1rf8xMq3/Li+t/y0trf8rK63/KCit/yYmrf8kJa7/IiOu/yAhrv8eH67/HR6u/xwd + rv8cHa//Gxyv/xscsP8bHK//Ghuu/xobr/8ZGrD/GRqw/xgZr/8YGa//Fxiu/xYXrv8WF67/Fheu/xUW + rv8VFqz/FBWs/xQVq/8TFKv/ExSr/xITqv8MDqn/LSmG/8zFw//p5eT/5N7e/5mWlvYAAABcAAAANgAA + ACEAAAAPAAAABQAAAAH///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////ADk5OYDc19f/4t3d/+bh3P+Yk7X/PT3K/0BA2f9CQtf/RETY/0VG2f9IR9j/SUnX/0tL + 1f9OTtT/UVHT/1NS0v9UVdD/V1jO/1lZzv9cXM3/Xl7N/2Bhy/9jZMv/ZWbK/2dnyv9pasj/amzI/2xt + x/9vb8b/b3DG/3Bwxf9xcsT/cXLC/3Bxwf9sbb3/Z2e6/2Njtv9hYrT/X2Gy/15fsP9dXrD/Wluw/1hZ + sP9WVbD/U1Kw/09Qr/9MTa//SEuv/0ZIrv9DRa7/QEGu/z0+rv86Oq3/Nzet/zM0rf8wMa3/LjCs/y0s + rP8qKqz/KCis/yUlrP8kJKz/ISOs/yAhrP8eH6z/HR6s/xwdrP8bHKz/Gxys/xscrf8aG63/Ghut/xka + rf8ZGq3/GBmt/xgZrf8XGK3/Fxis/xYXrP8WF6z/FRas/xUWq/8UFar/ExSq/xMUqf8TFKj/ExSn/w4Q + qP8jIIf/wLe4/+zo5v/j3Nz/mZaW9gAAAFwAAAA2AAAAIQAAAA8AAAAFAAAAAf///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AOTk5gN3Y2P/j39//5uHb/5aS + tf8+P8v/Q0La/0VF2P9HR9n/SUnZ/0pK2f9MTNn/T0/Y/1BS1v9UVNX/V1bU/1lZ0/9cW9H/Xl7Q/2Fh + 0P9kZM//ZmbO/2hpzf9ra83/bG7M/29wzP9xcsv/cnPK/3R1yv92dsn/d3fI/3d3x/94eMb/eHjF/3d4 + xP93d8L/dHTA/25vvP9oarj/ZGW0/2Fjsv9fYLH/XV6x/1pbsf9XV7H/VFSw/1FRr/9NTq//SUuv/0ZI + rv9DRa3/QEKt/zw+rf85Oq3/Njes/zMzrP8vMKv/LS6r/ywsq/8qKqv/Jyeq/yQkqv8jI6r/IiKq/yAh + qv8eH6r/HR6q/xwdq/8cHar/HB2q/xscq/8aG6z/GRqr/xkaqv8ZGqv/GBmr/xgZq/8XGKr/Fxip/xYX + qf8WF6n/Fhep/xUWqP8VFqj/FBWm/xQVpf8TFKb/DxGm/yMfhv++tbb/6+jm/+Lc3P+YlZX2AAAAXAAA + ADYAAAAhAAAADwAAAAUAAAAB////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wA5OTmA3tnZ/+Xg4P/k39r/oZy1/0ZGyv9FRdv/R0fa/0pK2v9MTNn/TU3a/1BQ + 2/9SUtn/VFXY/1dY1/9aWtb/XV3U/2Bg1P9iYtP/ZmbS/2ho0f9ra9H/bW3R/3Bx0P9ydND/dXXP/3d4 + zv94ec7/enrN/3x8zf9+fsz/fn7L/35/yv9+f8n/fX/I/31+xv98fcX/e3zD/3l6wf90dr7/bnC6/2hp + tf9jZLP/X2Cy/1tdsf9ZWbH/VVWw/1JSsP9OT6//Skyu/0ZIrf9CRa3/P0Gt/zw+rP84Oqv/Njar/zI0 + q/8vMKr/LS2q/ysrqf8oKKn/Jiao/yQkqP8iI6n/ISKp/x8gqf8eH6n/HR6p/xwdqf8cHan/HB2p/xsc + qf8bHKn/Ghup/xkaqf8ZGqj/GRqo/xgZqP8YGaj/Fxin/xcYpv8WF6b/Fhem/xUWpf8VFqT/FBWk/xQU + o/8OD6P/LiqF/8jBv//p5uX/4dra/5iVlfYAAABbAAAANQAAACEAAAAQAAAABQAAAAH///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////ADk5OYDf2tr/49/f/+rl + 4P+hnLb/SEjL/0hI2/9KStr/TU3a/05O2/9RUdr/U1Pb/1VV2/9YWdr/WlzZ/15f2P9iYtf/ZGTW/2dn + 1f9qatX/bW3U/3Bw0/9zc9P/dnbT/3h50/97fNL/fX7S/3+A0v+AgtH/goPR/4SE0P+Fhc//hoXO/4aG + zf+Fhsz/hIXL/4ODyf+Bgsf/gIDG/31/w/96fcH/d3m+/3N0u/9sbrf/ZWe0/19gsv9aW7H/VVaw/1FR + r/9OT67/Skut/0ZHrf9CRKz/PkGs/zs9qv83Oqr/NDap/zIyqf8vMKj/LSyo/yoqqP8nKKf/JiWn/yMj + pv8hIqb/ICGn/x8gp/8dHqf/HR6n/xwdp/8cHaf/HB2m/xscpv8bHKf/Ghun/xobp/8ZGqb/GRqm/xgZ + pv8XGKb/Fxil/xYXo/8WF6P/FRaj/xUWo/8UFaL/FBWi/w4PoP8vKob/0MnI/+bh4P/g2dn/l5SU9gAA + AFsAAAA1AAAAIQAAAA8AAAAFAAAAAf///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8AOTk5gODc3P/l4OD/6ubh/6KeuP9MTM3/Skrb/05O2v9QUNv/UVHb/1RU + 3P9WVtz/WVnc/1xc3P9eXtv/YmLa/2Vm2f9oaNj/bGzX/29v1/9yctf/dXXW/3h41v97e9b/fn7W/4GC + 1v+DhNX/hYbV/4iJ1f+JitT/i4vU/4yM0/+MjNL/jI3R/4yM0P+LjM//iovN/4iJzP+Gh8r/g4TH/4CB + xP99fsL/enzA/3d5vf9zdbr/b3C5/2hptv9hYrT/Wluy/1NTr/9OT63/SUqs/0VGq/9BQ6r/PT+q/zk8 + qf83Oaj/Mzao/zAyp/8tL6f/Kyym/ykppv8nJ6b/JCSl/yIjpf8hIqX/HyCl/x4fpf8dHqX/HB2k/xwd + pP8cHaX/Gxyl/xscpP8aG6X/Ghul/xkapP8YGaT/GBmj/xgZo/8XGKP/Fxii/xYXov8WFqH/FRag/xQV + n/8UFZ//Dg+f/y8rh//Qysj/5N/e/9/Y2P+XlJT2AAAAWgAAADQAAAAgAAAADwAAAAUAAAAB////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wA6OTmA4d3d/+Xh + 4f/q5eH/o5+4/1FSz/9MTNz/UFDa/1JS2/9VVdz/V1fc/1pa3f9cXN3/X1/d/2Ji3f9lZtz/aWnc/21s + 2/9wcNr/dHTZ/3Z22f96etn/fn7Z/4CA2P+EhNj/iIfZ/4qL2P+Mjdj/jo/Y/5CR2P+Sktf/k5TX/5OU + 1v+TlNX/k5TU/5KT0v+RktH/j5DQ/42Nzv+Ki8v/h4jJ/4SExv+AgMT/fH3B/3h6vv90drz/cHK5/21u + uP9pabf/Y2S1/1xdsv9UVrD/TU6u/0dHq/9AQqn/PD6o/zc5p/81N6f/MTOm/y4wpf8sLqX/Kiuk/yco + pP8mJqP/IyOj/yEio/8gIaP/Hh+j/x4fo/8cHaP/HB2j/xwdo/8cHKP/Gxyj/xobov8aG6L/GRqi/xka + ov8YGaH/GBih/xcYoP8WGKD/Fheg/xYXnv8VFp3/FRad/xQWnf8OEJ3/MCyG/9HKyf/j3t3/3tfX/5eU + lPYAAABaAAAANAAAACAAAAAPAAAABQAAAAH///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////ADc3N3LZ1dX/6OPj/+rn4v+embb/UlLP/09P3f9SUtz/VVXc/1dX + 3P9aWtz/XFze/19f3v9jY97/Zmbf/2lp3v9sbd7/cHHd/3R03P94eNv/fHzc/39/3P+Dg9v/hobb/4qK + 2/+Ojdz/kJDc/5OS2/+Vldv/l5fb/5mZ2v+amtr/m5vZ/5uc2P+am9j/mZrW/5iY1f+WltT/k5TS/5GR + 0P+Ojs3/i4vK/4eHyP+Cg8X/fn/D/3l7wP91d7z/cHK6/21tt/9oabb/ZGW1/2Bhs/9bXLL/Vlex/1BR + r/9JSqz/QUOq/zs+qP81N6X/MDKk/y0vo/8qK6P/Jyii/yYnof8jJKH/IiOh/yAhoP8fIKD/Hh+g/x0e + of8cHqD/HB6g/xwdoP8bHKD/Gxug/xoboP8aGqD/GRqf/xkan/8YGp//Fxme/xcYnf8WGJ3/Fhid/xUX + nP8UF5v/FBaa/w4Rmf8wLYb/0svK/+Pe3f/b1NT/jYqK7wAAAFcAAAA0AAAAIAAAAA8AAAAFAAAAAf// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8ANTU1Y9TQ + 0P/q5ub/7Ofi/5iTs/9RUs7/UVHd/1VV3P9XV93/Wlrd/11d3f9fX97/Y2Pf/2Zm4P9qauD/bW3g/3Bw + 4P90dN//eHjf/3x83v+AgN7/hITd/4iI3v+MjN7/kJDe/5OT3v+Wlt7/mZne/5yc3v+ent7/oKDe/6Ki + 3v+jo93/o6Pc/6Kj2/+gotr/n6DZ/52e1/+am9b/l5jU/5OV0f+Qkc7/jI3M/4iJyf+DhMf/fn/E/3p7 + wf91d73/cXK6/21tt/9nabX/Y2Sz/15fsv9aW7H/Vlew/1JTr/9OT63/SUqs/0RGqv8/Qan/OTum/zU2 + pf8wMaT/Kyyi/ycooP8jJJ//ISKf/x8gnv8dHp7/HB2e/xsdnv8bHp7/HB6e/xsdnv8aHJ7/Ghye/xoc + nv8ZG53/GRuc/xganP8YGpz/Fxmb/xYYmv8WGJr/FRea/xUXmf8UFpf/DhGY/y4rhf/SzMv/4t7c/9nS + 0v+DgYHjAAAAVAAAADQAAAAfAAAADgAAAAUAAAAB////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wA1NTVk1tLS/+vn5//s6OL/mJOz/1RVz/9UVN3/V1fc/1pa + 3f9dXd3/X1/e/2Ji3v9mZuD/aWnh/21t4f9wcOH/dHTh/3h44f98fOH/gIHh/4WF4P+JieD/jY3g/5GR + 4f+VleH/mJng/5ud4P+goOH/pKPh/6am4f+oqOH/qqrh/6qq4f+qquD/qqrf/6iq3v+nqN3/pKXa/6Ch + 2f+en9j/mpvV/5WW0v+QkdD/jo7N/4mKyv+DhMf/f3/E/3l7wf91dr7/cHG7/2xst/9maLT/YmOy/11e + sf9ZWrD/VFau/1BSrf9MTqv/SUmq/0VGqf9BQqj/Pj+o/zs8p/83OKX/NDWl/zEypP8tLqL/KSqh/yYn + oP8jJZ//ISOe/x8hnv8eIJ3/HR+c/xwdnP8aHJz/Ghyb/xkbm/8ZG5r/GBqa/xcZmf8WGJn/FhiY/xUX + l/8VF5f/FReX/xQWlv8PEpb/Mi6G/9LMzP/h3dz/2NHR/4SBgeQAAABUAAAANAAAAB8AAAAOAAAABQAA + AAH///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////ADY1 + NWTW09P/6+jo/+zn4v+Yk7P/VlbQ/1ZX3v9aWtz/XFzd/19f3v9iYt//ZWXf/2lp4P9sbOH/cHDh/3R0 + 4v93d+P/fHzj/4CA4/+EheP/iYnj/46O4/+SkuP/lZbj/5ma4/+en+P/oqPk/6an5P+qquX/rK3l/6+v + 5P+xseX/srLk/7Ky5P+ysuP/sLDi/66v4f+srN//qKnd/6Sl2/+hotn/m53W/5aX0/+Sk9D/jo7N/4iJ + y/+DhMj/fn/E/3l6wf90db7/b3C7/2prt/9lZrT/YWKy/1tcr/9XWK7/U1Ws/09Rq/9LTKr/R0mo/0NF + p/9AQab/PT6l/zo7pf83OKP/NDWj/zM0o/8yMaL/MDCi/y0uof8sLaH/Kyyg/ykrn/8oKp//Jiif/yUm + nv8jJZ3/IiSc/yAinP8fIZv/HR+Z/xwemf8bHZj/GhyX/xoblv8ZGpb/GBmV/xYXl/87N4r/0s3N/+Dc + 2v/Xz8//hIGB5AAAAFQAAAA0AAAAHwAAAA4AAAAFAAAAAf///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8ANjY2ZNfU1P/s6en/7Ojj/5iTs/9YWND/WVnf/11d + 3f9fX93/YWHe/2Vl4P9nZ+D/a2vg/29v4f9zc+L/d3fi/3t74/9/f+T/g4Pl/4iI5f+MjeX/kpLk/5aW + 5P+amuX/n5/l/6Sk5v+oqeb/q63n/7Cw5/+ztOf/trfn/7m55/+6uuf/urrn/7q65v+4uOX/tbXl/7Oz + 4/+vsOH/q6ze/6eo2/+iotr/nJ3X/5eX0/+SktH/jY7O/4eIyv+Cg8j/fX3F/3d4wf9zc77/bm67/2hp + uP9kZbX/Xl+x/1pbr/9WV6z/UVOq/01Pqf9JS6j/RUin/0JEpv8/QKX/PD2k/zk7o/82OKL/NDWh/zMz + of8xMaD/MDCg/y4voP8tLp//LS6e/yssnv8qK57/KSqe/ykpnf8oKZ3/Jyic/yYnm/8lJpr/JCWa/yMk + mv8iI5n/ICKY/yAhlv8eH5b/Gx2X/z06i//Tzc3/4NrZ/9bPz/+DgYHkAAAAVAAAADQAAAAfAAAADgAA + AAUAAAAB////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wA2NTVk2NXV/+7q6v/s6eT/l5Kz/1pZ0f9bW9//Xl7e/2Fh3v9kZN//Z2fg/2tr4P9ubuH/cnLh/3Z2 + 4/96euT/fn7k/4KC5f+Hh+f/jIvm/5CR5v+Vlub/mprn/5+f5/+kpOf/qano/66u6f+ys+n/trfq/7q7 + 6v++v+v/wMDr/8LC6//Cwuv/wsLq/8DA6f++vef/urrl/7a25P+ysuL/ra3f/6eo3f+hotr/nJ3W/5aX + 1P+RktH/jIzN/4aGy/+Agcj/enzE/3V1wf9wcb7/a2y7/2dnuP9hY7X/XV2y/1hZr/9UVqz/UFGp/0tO + p/9ISqb/REal/0JDo/8+QKP/Oz2i/zk7of82OKD/MzWf/zIzn/8xMZ7/MDCe/y8wnf8uL53/LS6d/ywt + nf8rLJ3/Kiuc/ykpm/8oKZr/Jyia/yYomf8lJpj/JCaX/yMll/8iJJb/ISOV/yAik/8cIJX/PjuL/9PN + zv/f2tn/1c3N/4OAgOQAAABUAAAANAAAAB8AAAAOAAAABQAAAAH///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////ADY2NmTZ1tb/7+vr/+rm4v+nobj/YGDQ/1xc + 3/9hYd7/Y2Pf/2Zm3/9qauD/bW3h/3Bw4v90dOL/eHjj/3x85P+BgeX/hYXm/4qK5/+Pj+j/lJTo/5mZ + 5/+enuj/o6Pp/6mp6v+urur/s7Pr/7i57P+9vuz/wcLt/8TG7f/IyO7/ysru/8rK7v/Jyu3/yMjs/8XF + 6//Bwen/vb3m/7i45f+zsuL/ra3f/6eo3P+hotn/mpzW/5WW1P+Pj9D/iorN/4OEyv9+fsf/eXnE/3N0 + wf9tbr7/aWm6/2Rkt/9fYLX/W1yy/1ZYr/9SVK3/TlCq/0pMp/9HSaX/Q0Wj/0BCov88PqH/Ojuf/zg6 + nv83OJ7/NDae/zEznf8xMpz/MDGc/y8wnP8vMJz/Li+b/y0um/8sLZv/KiuZ/ykqmf8oKpj/KCmY/yYp + lv8mJ5b/JSaW/yQmlf8jJZP/IiST/x0glP9HQ4v/1tDP/97Y2P/UzMz/g4CA5AAAAFMAAAAzAAAAHwAA + AA8AAAAFAAAAAf///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8ANjY2ZNrX1//w7e3/6OTh/6ymtv9mZ9H/Xl7g/2Nj3v9lZd//aGjg/2xs4P9vb+H/c3Pi/3d3 + 4v97e+P/f3/l/4OD5v+IiOb/jY3n/5KS6P+Xl+n/nZ3q/6Ki6v+np+v/ra3r/7Kz7P+5uO3/vr7u/8PD + 7//IyPD/zMzw/8/P8f/R0fH/0tLx/9HS8P/P0PD/zMzu/8jI7P/Dw+r/vr7n/7i45f+xsuL/q6zf/6Sm + 3P+fn9n/mJnW/5OS0/+NjdD/hofN/4CByf97fMb/dXfE/3Bwwf9rbL3/Zme7/2FjuP9cXrX/WFmy/1RV + r/9QUa3/TE6r/0hKqf9FR6b/QkOl/z9Bo/87PqD/OTue/zg5nv83N53/NDWb/zIzm/8xMpv/MDGa/zAx + mv8vMJr/Li+Z/y0umf8sLZj/KyyX/yorl/8oK5b/JyqW/yYolv8mJ5X/JSeV/yQmlf8jJZX/HiGW/1NO + jv/f2tf/29bV/9LLy/+CgIDkAAAAUgAAADMAAAAfAAAADgAAAAUAAAAB////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wA2NjZk29jY/+/t7f/w7er/q6W2/2dn + 0f9gYOD/ZGTf/2ho3/9qauD/bm7h/3Fx4f91deL/eXnj/3195P+BgeX/hobm/4qK5/+QkOj/lJTp/5qa + 6v+fn+v/pqbs/6ur7f+xse3/trbu/7297//Dw+//ycnx/87O8v/T0/P/19f0/9nZ9P/a2vT/2drz/9fX + 8v/T1PH/zc7u/8nJ7P/Dw+r/vLzn/7a25f+vsOL/qKnf/6Kj3P+bnNn/lZbV/5CQ0v+KidD/hIPM/31+ + yf94ecb/c3PD/21uwP9oab7/YmW6/15guP9ZW7X/VVez/1JTsP9OT67/Skyr/0dIqv9DRaj/QUKl/z0/ + pP87PKP/Ojqh/zg5n/82OJ7/NDWd/zI0nP8xMpz/MTGc/zAxm/8wMJr/LzCa/y4vmv8tLpn/LC2Z/yot + mf8pK5n/KCqY/ycpmP8mKJj/JieY/yUmmP8fIZr/VE+R/+Xh3v/X0ND/0svL/4J/f+QAAABSAAAAMgAA + AB4AAAANAAAABQAAAAH///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////ADY2NmTb2dn/8O3t//Hu6/+sprb/amzT/2Fh4f9mZuD/aWng/2tr4P9wcOL/c3Pi/3d3 + 4v97e+T/f3/k/4SE5f+IiOf/jY3n/5KS6P+Xl+r/nZ3q/6Ki7P+np+3/ra3t/7S07v+7u+//wMDw/8fH + 8f/NzfL/1NT0/9nZ9f/e3vb/4uL3/+Pj9//i4vb/3t71/9nZ9P/U1PH/zs7v/8fH7P/AwOn/urrn/7Ky + 5P+sq+H/paXe/56f2/+Xmdj/kpLV/4yL0v+Fhs7/gH/M/3p6yf91dcb/b3DC/2prwP9lZr3/YGK7/1te + uP9XWbb/U1Wz/09RsP9MTa7/SEqs/0VHq/9CQqj/QECn/z0+pf86O6T/OTmi/zg4ov83N6D/NTWg/zQ0 + n/8zNJ//MjOe/zExnv8wMJ7/LzCd/y4wnP8tL5z/LC6c/yssnP8qK5z/KSqc/ycpnP8mJ5z/JSac/yIj + nf9ZVJT/5eDd/9TOzv/Rycn/gX5+5AAAAFIAAAAyAAAAHgAAAA0AAAAFAAAAAf///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8ANjY2Zt3a2v/y7u7/8e7r/62n + t/9tb9T/Y2Ph/2ho3/9qauH/bW3h/3Fx4f90dOL/eHjj/3195P+BgeX/hYXm/4qK5/+Ojuj/lJTp/5mZ + 6v+enuv/paXs/6ur7v+wsO7/t7fv/7298P/ExPH/y8vy/9HR9P/Y2PX/39/2/+Xl+f/p6fn/6+v5/+rq + +f/m5vj/39/1/9nZ8//R0vH/ysvu/8TE6/+8vOj/tbXl/66u4v+np+D/oaHd/5qZ2f+TlNf/jo7U/4eH + 0f+Cgs7/fXzL/3Z3yP9xcsX/a2zD/2ZnwP9iY73/XV+7/1lauP9UVrX/UFK0/01Psv9JS6//R0it/0RF + q/9BQqr/Pz+p/zw9p/86Oqb/ODik/zc4o/82NqP/NTaj/zQ1ov8zNKL/MjOh/zEyoP8wMaD/MDCg/y4w + oP8tL5//LC6f/yssn/8qK5//KSqf/ycpn/8mKJ//JCah/19amP/l4N7/1M3N/9DJyf+Cf3/kAAAAUgAA + ADEAAAAdAAAADQAAAAQAAAAB////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wAzMzNX1NLS//Tx8f/y7+z/rKa3/2pr0v9lZeL/aWng/2xs4f9vb+H/cnLh/3Z2 + 4/96euP/fn7k/4KC5f+Ghub/i4vn/5CQ6P+Vlen/mprq/6Cg6/+lpez/rKzu/7Ky7/+4uPD/v7/y/8bG + 8v/NzfP/1dX1/9zc9v/j4/j/6ur6//Hx/P/09Pz/8fH8/+vr+v/k5Pf/3Nz0/9TU8v/Nze//xsbs/76+ + 6f+3t+f/sLDk/6mp4f+jot7/m5vb/5SW2P+Pj9b/iYnT/4KD0P99fs3/eHjK/3JzyP9tbsT/aGnC/2Nk + wP9eYL3/Wlu6/1ZXuP9TVLb/T1C1/0tMs/9ISbD/Rkev/0JDrf9AQaz/Pj6q/zo8qf84Oqj/ODin/zc4 + pv82N6X/NTel/zQ2pf8zNaT/MTSj/zAyo/8wMaP/LzCj/y8wo/8tMKP/LC6j/ystov8qLKL/KSyj/ycq + o/8iJaP/V1KV/+bi3v/TzMz/zsbG/3l2dtwAAABOAAAAMAAAABwAAAANAAAABAAAAAD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AEpKSkbKyMj/9vPz//Pw + 7f+qpLb/YmPO/2dn4v9ra+D/bW3g/3Bw4v90dOL/eHjj/3t75P9/f+X/g4Pl/4iI5/+Njef/kZHo/5eX + 6f+cnOr/oaHs/6io7f+tre7/s7Pv/7q68P/AwPL/yMjz/87O9f/W1vb/3t74/+bm+f/u7vr/9vb9//z8 + /v/39/3/7+/7/+bm+P/e3vX/1tbz/87O8P/Hx+7/wMDr/7m56P+xseX/qqri/6Oj3/+cnNz/lpba/4+Q + 1/+Ki9X/hITS/31/z/94ecz/c3XK/25vx/9pasT/ZWXC/2Bhv/9cXL3/V1i7/1NUuf9QUbf/TE21/0lK + s/9HR7L/RESw/0BBrv8/P63/PT6s/zs8q/85Oqr/ODmp/zc5qf83OKn/NTin/zQ3p/8zNqf/MjWn/zEz + pv8xMqb/MDGm/y8xpv8uMKb/LS+l/ystpv8rLKb/KSum/yMlpv9UUJX/5+Pf/9PLy//LxMT/bmxs0AAA + AEgAAAAuAAAAGwAAAAsAAAAEAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8AZ2dnSMjGxv/39PT/8/Ht/6qktv9iY87/aWni/2xs4f9ubuH/cXHh/3V1 + 4/95eeP/fHzk/4CA5f+FheX/iYnn/42N6P+Skun/l5fq/52d6v+iouz/p6ft/66u7v+zs/D/urrx/8HB + 8v/Hx/T/z8/1/9bW9v/d3fj/5eX5/+3t+v/09P3/+fn9//b2/f/u7vv/5ub4/97e9v/W1vP/zs7x/8bH + 7v/AwOz/ubjp/7Ky5v+qquP/pKTh/52d3v+Wl9v/kZLY/4uM1f+EhdP/f4DR/3l6zv90dcv/b3DK/2ps + x/9lZ8T/YWLC/11ev/9ZWr7/VVa7/1FSuf9NTrj/Sku2/0hIs/9FRbL/QkOx/0BAsP8/P67/PT6t/zo8 + rf85Oq3/ODms/zg5q/84OKv/Nzir/zU3qv80Nqr/MzSq/zIzqf8xMqn/MDGo/zAwqP8vMKn/LS+p/ywt + qP8rLKj/JCWp/1RQlv/o5OD/0crK/8rCwv9vbW3QAAAARAAAACsAAAAYAAAACgAAAAMAAAAA////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wBjY2NIycfH//f1 + 9f/z8e3/rKa3/2do0P9paeL/a2vg/25u4v9ycuL/dnbi/3p65P99feT/gYHl/4WF5v+Jieb/jo7o/5OT + 6P+YmOr/nZ3r/6Ki7P+np+3/rq7u/7Oz7/+6uvH/wcHy/8fH8//OzvT/1dX2/9vb+P/i4vn/6en6/+7u + +//x8fz/7+/8/+rq+v/j4/f/3Nz1/9XV8//OzvD/xsfv/76/7P+4uer/sbLn/6uq5P+kpOL/nZ3f/5aX + 3P+Qktr/i4vX/4WG1f9/gNP/envQ/3V1zf9vccz/amvJ/2Znxv9hY8T/Xl/C/1pbwP9WV77/UlO7/09Q + uv9MTLn/SUm3/0ZGtf9ERLT/QUKz/z9Asv8+PrD/PD2w/zs8r/85Oq//OTqv/zk4rv84OK7/Nzit/zU3 + rP81Nq3/MzSt/zIzrP8xMqz/MDCs/y8wq/8tLqv/Kyyq/ygpqv8nKaz/Xlma/+fj3//Qycn/ycHB/3Bu + bs0AAAA8AAAAJQAAABQAAAAJAAAAAgAAAAD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AGNjY0jKyMj/+ff3//Tx7v+po7f/d3jU/3195v96euP/eHjj/3V1 + 4v92duP/eXnk/3195P+BgeX/hYXm/4qK5/+Ojuj/k5Pp/5iY6v+dnev/oqLs/6en7f+uru7/s7Pv/7i4 + 8f+/v/L/xsbz/8zM9f/S0vb/2dn3/97e+P/j4/n/5+f6/+np+v/o6Pn/5OT4/9/f9//Y2PX/0dHz/8vL + 8P/Fxe//vb7s/7a36v+vsOf/qqrl/6Oj4/+dneD/l5fe/5CS2/+Li9n/hYbW/4CA1P96e9H/dXbP/3Bx + zv9sbMv/ZmjI/2Jjx/9fX8X/W1vD/1dXwf9TVL7/UFG9/01Nu/9KSrr/R0e4/0VFt/9DRLb/QUK1/0BA + tP8+P7P/PD2y/zs8sv87PLL/Ojux/zk5sf84ObH/ODiw/zY3sP81Na//MzSv/zAxrv8uMK7/MjOv/zo6 + sv9HSLj/UFG9/11fw/9pZKD/5N/e/9DJyP/IwMD/cW5uygAAADIAAAAdAAAAEAAAAAYAAAABAAAAAP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AY2NjScvK + yv/6+Pj/9PLv/7SuvP9rbM3/g4Pq/4mI6f+MjOn/j4/o/4yM5/+IiOb/hITm/4KC5f+Fheb/iYnn/46O + 5/+Skun/mJjp/52d6/+hoez/p6ft/6ys7v+xse//uLjw/7298v/Dw/P/yMj0/8/P9f/U1Pf/2dn3/97e + 9//g4Pj/4eH5/+Dg+P/d3ff/2dn2/9TU9P/OzvL/yMjx/8LB7/+7vOz/tbbq/66v6P+oqeX/oaPj/5uc + 4f+Wlt//kZHc/4qL2v+Fhtf/gIDW/3p70/92dtH/cHLP/2xszP9naMv/Y2TJ/2Bgx/9cW8T/WFfC/1RU + wP9RUb//Tk++/0tMvf9ISbv/Rka6/0RFuP9BQ7f/QEG3/z9Atv89P7b/PD60/zw9tP87PLT/OTuz/zk6 + s/83OLP/MzWx/zQ2sf87PbT/S0y7/1xdwv9tbcj/cnPL/3Fyzf9ub83/T1HB/1lTlP/r5+L/zsbG/8e/ + v/9zcXHHAAAAJQAAABQAAAALAAAABAAAAAEAAAAA////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wBeXl4vvLq6+f37+//39fX/1c/N/4uJvP9lZsj/bm/S/3Fy + 2P93eOD/iYnn/5OT6/+YmOv/mJjq/5OT6f+Pj+j/jo7o/5GR6P+Wlun/nJzq/6Gh6/+lpez/q6vu/7Cw + 7/+2tvD/u7vx/8DA8v/FxfP/ysr0/8/P9f/U1Pb/19f3/9nZ9//a2vf/2dn3/9fX9v/U1PT/z8/z/8rK + 8v/ExPH/v7/v/7m57P+zs+r/razp/6en5/+goeT/m5vi/5aW4P+QkN7/iorb/4WF2f+Af9f/envU/3Z2 + 0v9wcdD/bG3O/2dpzf9jZMv/YGDJ/1xcx/9YWMT/VlbD/1JSwv9PT8D/TEy+/0lKvv9GR7z/RUa7/0JE + uv9BQbr/QEC5/z4/uP89P7j/PD63/zs8t/84OrX/Nji0/z4+t/9QUL7/ZGXG/3N0zP90dc7/Z2jK/1FT + wv8+QLj/MzSq/ysrof8wLZD/opuu//Dt6f/Hv7//xb29/2BfX6wAAAASAAAADQAAAAYAAAACAAAAAQAA + AAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AF1d + XQWOjo7L+PX1//b09P/y8O//1tDP/8O9wv+no7f/npu+/42Lv/94d8T/dXbR/31+3P+Mjef/nJzt/6Gh + 7f+goOv/m5vq/5iY6v+amur/np7r/6Sk7P+pqe3/rq7v/7Oz7/+4uPD/vb3y/8HB8v/GxvP/ysr0/87O + 9f/R0fb/09P2/9PT9v/S0vb/0ND1/87O8//KyvP/xcXx/8DA8P+7u+7/trbs/6+v6v+qqun/paXn/5+f + 5P+amuL/lJTg/4+P3v+Kitz/hYXa/39/2P96etb/dnXT/3Fx0v9sbdD/aGjO/2VkzP9hYcv/XV3I/1lZ + x/9WVsb/U1PE/1BRw/9NTsD/SkvA/0hJv/9GR77/REW9/0JDvP9AQbv/QEC7/z8/u/87PLn/PD25/0lK + vv9gYcb/dHTN/3V1z/9jZMr/SUu+/zc4rf8zMp7/S0eX/2ljmv+Lhaj/saq4/83HyP/v7On/0MrK/8e+ + vv+zrKz/MTIyaQAAAAIAAAAIAAAAAwAAAAEAAAAAAAAAAP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8AXV1dAGFhYVvCwMD//Pr6//Ty8v/08vL/8O7s//Du + 6v/p5N7/3NbR/8vFxv+wq7r/mZa8/4GAwP99ftH/h4jf/5qa6/+np+//qanu/6Wl7f+goOv/oaHr/6am + 7P+rq+7/sLDv/7W17/+5ufH/vb3y/8HB8v/FxfP/yMjz/8rK9P/MzPT/zMz0/8zM9P/KyvT/x8f0/8TE + 8v/AwPD/vLzv/7e37f+ysuz/ra3r/6io6f+iouf/nZ3l/5iY4/+Tk+L/jo7g/4mJ3f+EhNv/f3/a/3p6 + 1/91ddX/cXHU/2xs0f9oaND/ZWXP/2FhzP9dXcv/WlrJ/1dXyP9UVMf/UVHF/05PxP9LTML/SUrB/0ZH + wf9FRsD/REW+/0FCvv8+P7z/QEC9/1NUxP9rbM3/eHjS/2xsz/9PUML/OTqv/zo5nv9dWJj/j4mp/8C5 + wP/e2db/8Ozk/+3o4//n4uD/3tnY/8nCwv/FvLz/xr6+/3Z0dMsNDQ0SAAAABAAAAAMAAAABAAAAAAAA + AAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wBdXV0AYWFhAGlpaYi9vLz/8/Dw//n29v/39PT/9PHx//Tx8f/18vL/8e7t/+/s6f/l4Nv/0cvL/7ex + vf+YlLv/hoXG/4iJ2f+amun/q6vw/7Cw8P+srO3/p6ft/6io7f+srO3/sbHv/7W18P+5ufH/vLzx/8DA + 8v/CwvP/xMTz/8bG8//GxvP/xcXz/8XF8//CwvP/v7/y/7u78f+3t+//s7Pu/6+v7P+qqur/paXp/6Cg + 6P+bm+b/l5fk/5KS4v+NjeD/h4ff/4OD3f9+ftr/eXnZ/3V11/9xcdb/bGzT/2hp0v9kZdH/YGHO/15e + zP9aWsz/V1fK/1RUyf9RUcj/T0/G/0xMxf9KS8T/SEnD/0ZGwv9CQ8D/Q0TB/1VWxv9wcM//eHnU/2Rl + zv9FRrv/Ozuk/1lVm/+Ri6n/ycPG/+rl4P/u6+X/49/d/9TOzv/KwsL/xr6+/8S7u//Hvb3/yb+//7+3 + t/+Afn7eGBkZMQ0NDQAAAAADAAAAAQAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AF1dXQBhYWEAaWlpAGFhYU+HhobErays98G/ + v/7Z1tb/6OXl//Hu7v/08fH/8O3t//Hu7//y7+//7uvo/+Pd2P/KxMX/qaO5/5COwv+Li9T/m5vm/7Cw + 8f+1tfD/sbHv/6ys7v+tre7/sbHv/7W18P+4uPD/u7vx/7298f++vvL/v7/y/7+/8v+/v/L/vr7y/7y8 + 8f+6uvH/trbw/7Oz7/+vr+7/q6vs/6am6/+ioun/nZ7o/5ma5v+UleX/kJDj/4uL4f+Ght//goLe/319 + 3P95edr/dXXZ/3Bw1v9sbNX/aGjU/2Rl0v9hYtH/Xl7P/1pbzv9XWMz/VFTL/1JSyv9PUMj/TU3H/0tL + xv9GR8T/R0fE/1dXyf9xcdH/eHjW/19gzf9CQ7f/RkOg/3ZxoP+4sbv/5eDa/+/r5f/h3Nr/z8nJ/8e/ + v//Hvb3/ycDA/8W9vf/Aubn/s62t/6OenvyIhYXoUlJSkRMTExwYGRkAAAAAAQAAAAEAAAAAAAAAAAAA + AAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8AXV1dAGFhYQBpaWkAYWFhAF5eXgNcXFwdYWFhQmdnZ2x3dnaclZSU1LSysvvW09P/6+jo//Ht + 7f/t6ur/7+zs/+/s7P/q5+L/1c/M/7Otu/+Rj73/kZHU/6Gh6P+1tfL/uLjx/7Oz7/+uru7/sLDu/7Oz + 7/+2tvD/uLjw/7m58f+6uvH/urrx/7m58f+4uPH/t7fw/7S08P+xse//rq7v/6ur7v+np+z/o6Pr/5+f + 6v+am+j/lpbm/5KS5P+NjuP/iYrj/4WF4P+AgN//fHze/3h42/90dNr/cHDY/2xs1v9oaNX/ZWXU/2Fi + 0/9dXtH/WlvP/1dYzv9VVs3/UlPM/1BQy/9MTcn/SErI/1NVy/9vcNP/envZ/2Fi0P9ERLn/UE2h/4aA + pf/Mxsf/7enj/+fi4P/Uzs3/yMDA/8e/v//JwcH/w7u7/7Krq/+Sjo7td3R0uUxMTIUwMDBYKisrMgME + BA5SUlIAExMTABgZGQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wBdXV0AYWFhAGlpaQBhYWEAXl5eAFxc + XABhYWEAZ2dnAHd2dgBcXFwGXV1dMWhoaHSGhYW9rqys+dbT0//r5+f/7enp/+rn5//u6+v/6+jl/9nT + z/+5s73/mZbA/5CR1f+oqev/ubnz/7m58f+xse//rq7u/7Cw7v+zs+//tLTv/7W17/+0tO//tLTv/7Oz + 7/+ysu//r6/v/62t7v+qqu7/p6fs/6Oj7P+goOv/nJzq/5iX6f+Tk+f/j4/m/4qL5f+Hh+P/g4Ph/35/ + 4P97e9//d3fd/3Nz3P9vb9v/a2vY/2dn1/9kZNb/YWHV/15e0/9bW9L/WFjR/1VWz/9SU87/Tk7M/1FS + zf9patT/fH3b/2lq1f9HSb3/T0yj/5KLqf/V0M3/7enj/+Hd2//NxsX/x76+/8rBwf/Fvb3/sKqq/4uH + h+JhYGCbNDQ0VBQUFBkAAAABTExMADAwMAAqKysAAwQEAFJSUgATExMAGBkZAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AF1dXQBhYWEAaWlpAGFhYQBeXl4AXFxcAGFhYQBnZ2cAd3Z2AFxcXABdXV0AaGhoAIaF + hQBcXFwqamlpf42MjNe/vb3/5ODg/+vn5//o5OT/6+no/+zo5v/Y0s//ta+8/5KQwP+XmNv/r6/u/7u7 + 8/+1tfD/rq7u/6ys7v+uru7/r6/v/6+v7/+vr+//rq7u/62t7v+rq+7/qKjt/6Wl7f+jo+z/oKDr/5yc + 6v+YmOr/lZXp/5GR6P+Njef/iIjm/4WF5f+BgeL/fX7h/3l64P92dt3/cnLd/25v3P9ra9r/Z2fY/2Vl + 2P9hYdf/Xl7V/1tb1P9YWNL/VFXR/1FS0P9hYtT/enrc/3Z23P9SU8f/TEqo/4iCp//Qysr/7enk/97Z + 2f/Kw8P/yL+//8rCwv++t7f/m5eX9WhmZq8zMzNXEBAQEGFgYAA0NDQAFBQUAAAAAABMTEwAMDAwACor + KwADBAQAUlJSABMTEwAYGRkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AXV1dAGFhYQBpaWkAYWFhAF5e + XgBcXFwAYWFhAGdnZwB3dnYAXFxcAF1dXQBoaGgAhoWFAFxcXABqaWkAXV1dCGBgYFB9fHy3sa6u+9zY + 2P/p5eX/5eHh/+rn5//r5+T/083L/6ynuv+Ojsb/n5/j/7W18v+5ufH/r6/u/6mp7f+qqu3/qqrt/6qq + 7f+pqe3/p6fs/6am7P+kpOz/oaHs/5+f6/+cnOr/mZnq/5aW6v+Skun/jo7o/4uL5v+Hh+b/g4Pl/39/ + 5P98e+L/eHjh/3R04P9wcd7/bW7d/2pq3P9naNr/ZGXZ/2Fh2P9eXtf/W1vV/1dX1P9aWtX/c3Pb/39/ + 4P9iYtP/Skmz/3Nvo//Gv8L/7enj/+Dc2//Kw8P/yMDA/8rBwf+3sbH/jImJ5kxLS4chIiIpaGZmADMz + MwAQEBAAYWBgADQ0NAAUFBQAAAAAAExMTAAwMDAAKisrAAMEBABSUlIAExMTABgZGQAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wBdXV0AYWFhAGlpaQBhYWEAXl5eAFxcXABhYWEAZ2dnAHd2dgBcXFwAXV1dAGho + aACGhYUAXFxcAGppaQBdXV0AYGBgAH18fABdXl43dXR0rKuoqPzb19f/5+Li/+Pe3v/q5+b/5+Pf/8rD + xf+dmbv/kpLS/6ip6/+4uPL/sbHv/6en7P+kpOz/paXs/6Sk7P+jo+z/oqLs/6Cg7P+enuv/m5vq/5iY + 6v+Vlen/kpLo/4+P6P+MjOf/iYnn/4WF5v+BgeX/fn7k/3p64/93d+P/c3Ph/3Bv4P9tbN//aWrd/2Zn + 3P9jZNv/YGHa/11e2P9ZWdf/Zmba/35/4f92d+D/UlLE/15bpf+spbT/6OTe/+bh3//Nxsb/x7+//8vC + wv+3sbH/hYOD4EVGRnQQEREVTEtLACEiIgBoZmYAMzMzABAQEABhYGAANDQ0ABQUFAAAAAAATExMADAw + MAAqKysAAwQEAFJSUgATExMAGBkZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AF1dXQBhYWEAaWlpAGFh + YQBeXl4AXFxcAGFhYQBnZ2cAd3Z2AFxcXABdXV0AaGhoAIaFhQBcXFwAamlpAF1dXQBgYGAAfXx8AF1e + XgB1dHQAXFxcNnd2drCxrq7+39vb/+Pe3v/i3t7/6+fm/9/a1f+2sbz/jozA/5eX3v+xsfH/srLv/6Wl + 7P+goOv/oKDs/5+f6/+dnev/nJzr/5qa6v+Xl+n/lZXp/5KS6f+Pj+j/jIzo/4mJ5/+Ghub/g4Pl/39/ + 5f98fOT/eXnj/3V14/9ycuL/b2/g/2xs4P9pad//Zmbe/2Nj3f9eX9v/Xl7a/3Jy3/+Dg+X/ZWfY/09P + s/+Hgaf/19HO/+vo5P/Uzs7/x76+/8vCwv+8trb/i4iI5UVERHYQEBAURUZGABAREQAAAAABAAAAAQAA + AAAAAAAAEBAQAGFgYAA0NDQAFBQUAAAAAABMTEwAMDAwACorKwADBAQAUlJSABMTEwAYGRkAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8AXV1dAGFhYQBpaWkAYWFhAF5eXgBcXFwAYWFhAGdnZwB3dnYAXFxcAF1d + XQBoaGgAhoWFAFxcXABqaWkAXV1dAGBgYAB9fHwAXV5eAHV0dABcXFwAd3Z2AF5eXkWAf3/MwLy8/+Ld + 3f/f2tr/5ODg/+rm4//OyMf/n5u6/5CQ0v+lpuz/sbDx/6Wl7P+bm+r/mprq/5mZ6v+YmOr/lpbp/5SU + 6f+Skuj/j4/n/42N5/+Kiuf/h4fm/4SE5v+BgeX/fn7k/3t74/93d+P/dXXi/3Jy4f9vb+H/bGzh/2lp + 4P9mZt//YWHe/2Rk3v99feT/f37m/1lazP9jYKj/s624/+vm4f/e2dn/yMDA/8rBwf/Fvb3/mpaW901N + TY0REREcRUREABAQEAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAQEBAAYWBgADQ0NAAUFBQAAAAAAExM + TAAwMDAAKisrAAMEBABSUlIAExMTABgZGQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wBdXV0AYWFhAGlp + aQBhYWEAXl5eAFxcXABhYWEAZ2dnAHd2dgBcXFwAXV1dAGhoaACGhYUAXFxcAGppaQBdXV0AYGBgAH18 + fABdXl4AdXR0AFxcXAB3dnYAXl5eAF5fXwdjY2NtlZKS69LNzf/h29v/3djY/+jk4//g29b/tK67/4+N + xf+ZmuP/ra3w/6Wl7f+Xl+n/lZXp/5WV6f+Tk+j/kZHo/4+P6P+MjOf/iorm/4eH5v+Fheb/goLl/39/ + 5P98fOT/eXnj/3Z24/9zc+L/cHDi/25u4P9ra+D/aGjf/2Nj3/9tbeH/hITn/3V24/9YWcD/hH+p/9XO + zP/q5uL/0MrK/8e+vv/Lw8P/raen/2lnZ7ojIyM0TU1NABEREQAAAAABAAAAAQAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAABAQEABhYGAANDQ0ABQUFAAAAAAATExMADAwMAAqKysAAwQEAFJSUgATExMAGBkZAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AF1dXQBhYWEAaWlpAGFhYQBeXl4AXFxcAGFhYQBnZ2cAd3Z2AFxc + XABdXV0AaGhoAIaFhQBcXFwAamlpAF1dXQBgYGAAfXx8AF1eXgB1dHQAXFxcAHd2dgBeXl4AXl9fAGNj + YwBdXV0hcXFxqbKurv/e2Nj/29XV/+Hd3f/o4+D/xr/B/5SSvP+Njtn/pqfu/6Sk7f+Vlen/kJDo/4+P + 6P+Ojuj/jIzn/4qK5v+Hh+b/hITm/4OD5f+AgOT/fX3k/3t75P94eOP/dXXj/3Jy4f9wcOH/bW3h/2pq + 4P9mZt//dHTi/4eH6f9sbdv/X1+0/6Odsf/l4Nv/4dzb/8jAwP/KwcH/wbq6/4iFhec4ODhnAQEBBiMj + IwAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQAGFgYAA0NDQAFBQUAAAA + AABMTEwAMDAwACorKwADBAQAUlJSABMTEwAYGRkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AXV1dAGFh + YQBpaWkAYWFhAF5eXgBcXFwAYWFhAGdnZwB3dnYAXFxcAF1dXQBoaGgAhoWFAFxcXABqaWkAXV1dAGBg + YAB9fHwAXV5eAHV0dABcXFwAd3Z2AF5eXgBeX18AY2NjAF1dXQBxcXEAYGBgWJCOjufRy8v/3dbW/9vV + 1f/o5OP/19HN/6GcuP+EhM3/nZ3q/6Sj7f+Skuj/i4vn/4uL5/+Jief/h4fm/4WF5v+Dg+b/gIDl/35+ + 5P98fOP/eXnj/3Z24/90dOL/cXHh/29v4f9ra+D/aWng/3t75P+Ghun/ZGXS/2tprP+/uL7/6ubh/9bQ + z//Gvb3/y8PD/6ynp/9fX1+wExQUIzg4OAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAQEBAAYWBgADQ0NAAUFBQAAAAAAExMTAAwMDAAKisrAAMEBABSUlIAExMTABgZ + GQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wBdXV0AYWFhAGlpaQBhYWEAXl5eAFxcXABhYWEAZ2dnAHd2 + dgBcXFwAXV1dAGhoaACGhYUAXFxcAGppaQBdXV0AYGBgAH18fABdXl4AdXR0AFxcXAB3dnYAXl5eAF5f + XwBjY2MAXV1dAHFxcQBgYGAAXV1dIXR0dLa6tbX/3NXV/9fR0f/j39//4NrV/6+puv+Dg8X/lJTl/6Gh + 7v+QkOj/hobm/4aG5v+Fheb/g4Pl/4GB5f9+fuT/fHzk/3p65P94eOP/dXXj/3Jy4v9xceH/bW3g/2xs + 4P+AgOb/hITo/2Bhyf99eqv/0cvJ/+fj4P/Nxsb/yL+//8a9vf+QjY3wPT09cAAAAAYTFBQAAAAAAgAA + AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEABhYGAANDQ0ABQU + FAAAAAAATExMADAwMAAqKysAAwQEAFJSUgATExMAGBkZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AF1d + XQBhYWEAaWlpAGFhYQBeXl4AXFxcAGFhYQBnZ2cAd3Z2AFxcXABdXV0AaGhoAIaFhQBcXFwAamlpAF1d + XQBgYGAAfXx8AF1eXgB1dHQAXFxcAHd2dgBeXl4AXl9fAGNjYwBdXV0AcXFxAGBgYABdXV0AX2BgAWRk + ZHignZ3519HR/9bPz//e2dn/5eHd/763vv+FhL//iovg/56e7f+Rken/hITl/4GB5f+AgOX/fn7k/319 + 5P97e+T/eXnj/3Z24/90dOL/cXHi/21t4f9zc+L/hobn/4GB5v9hYcL/kYyu/97Y0//i3t3/x7+//8rB + wf+6tLT/dXNzzxYWFjY9PT0AAAAAAgAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAEBAQAGFgYAA0NDQAFBQUAAAAAABMTEwAMDAwACorKwADBAQAUlJSABMT + EwAYGRkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8AXV1dAGFhYQBpaWkAYWFhAF5eXgBcXFwAYWFhAGdn + ZwB3dnYAXFxcAF1dXQBoaGgAhoWFAFxcXABqaWkAXV1dAGBgYAB9fHwAXV5eAHV0dABcXFwAd3Z2AF5e + XgBeX18AY2NjAF1dXQBxcXEAYGBgAF1dXQBfYGAAZGRkAF5eXkWLiYnjzsjI/9XPz//Y09P/5+Pg/8jB + w/+Jh7v/g4Pb/5qa7P+Wlun/h4fm/39/5P97e+T/eXnk/3h44/92duP/c3Pi/3Fx4v90dOL/f3/l/4yM + 6f97e+L/ZGS+/6Casf/l4Nr/29bV/8W9vf/KwcH/raen/1pZWaQREhIYFhYWAAAAAAMAAAABAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAAYWBgADQ0 + NAAUFBQAAAAAAExMTAAwMDAAKisrAAMEBABSUlIAExMTABgZGQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wBdXV0AYWFhAGlpaQBhYWEAXl5eAFxcXABhYWEAZ2dnAHd2dgBcXFwAXV1dAGhoaACGhYUAXFxcAGpp + aQBdXV0AYGBgAH18fABdXl4AdXR0AFxcXAB3dnYAXl5eAF5fXwBjY2MAXV1dAHFxcQBgYGAAXV1dAF9g + YABkZGQAXl5eAF5eXiF5eHjFwby8/9bOzv/Uzc3/5uLf/9DJyP+Sj7j/eXrQ/46O6P+YmOz/kpLp/4iI + 5v+CguX/f3/k/35+5P9/f+T/hYXm/42N6f+Jier/b2/a/2tquP+uqLf/6OPd/9XQ0P/EvLz/ycDA/52Y + mPpAQEB6AAAABRESEgAAAAADAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEABhYGAANDQ0ABQUFAAAAAAATExMADAwMAAqKysAAwQEAFJS + UgATExMAGBkZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AF1dXQBhYWEAaWlpAGFhYQBeXl4AXFxcAGFh + YQBnZ2cAd3Z2AFxcXABdXV0AaGhoAIaFhQBcXFwAamlpAF1dXQBgYGAAfXx8AF1eXgB1dHQAXFxcAHd2 + dgBeXl4AXl9fAGNjYwBdXV0AcXFxAGBgYABdXV0AX2BgAGRkZABeXl4AXl5eAF5fXw5ubm6itbCw/9TN + zf/Ry8v/49/e/9rU0P+oo7r/eHfB/3d32P+IiOj/kZHr/5GR6/+QkOn/j4/p/46O6v+IiOn/dHXe/2Rk + x/+BfrP/xb/C/+fi3v/Qysr/xby8/8e+vv+LiIjrMTIyVkBAQAAAAAADAAAAAwAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQAGFg + YAA0NDQAFBQUAAAAAABMTEwAMDAwACorKwADBAQAUlJSABMTEwAYGRkAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8AXV1dAGFhYQBpaWkAYWFhAF5eXgBcXFwAYWFhAGdnZwB3dnYAXFxcAF1dXQBoaGgAhoWFAFxc + XABqaWkAXV1dAGBgYAB9fHwAXV5eAHV0dABcXFwAd3Z2AF5eXgBeX18AY2NjAF1dXQBxcXEAYGBgAF1d + XQBfYGAAZGRkAF5eXgBeXl4AXl9fAG5ubgBmZmaGqqWl/9TNzf/Ox8f/3NfW/+Tf2v/Fv8L/lpO3/3t6 + v/9ycs7/d3fX/3Nz2v90dNn/b2/S/2xsxP9/fbT/q6a4/9zX0//i3tv/ysPD/8e9vf/Curr/fnx83RYX + FzkxMjIAAAAABAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAAYWBgADQ0NAAUFBQAAAAAAExMTAAwMDAAKisrAAME + BABSUlIAExMTABgZGQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wBdXV0AYWFhAGlpaQBhYWEAXl5eAFxc + XABhYWEAZ2dnAHd2dgBcXFwAXV1dAGhoaACGhYUAXFxcAGppaQBdXV0AYGBgAH18fABdXl4AdXR0AFxc + XAB3dnYAXl5eAF5fXwBjY2MAXV1dAHFxcQBgYGAAXV1dAF9gYABkZGQAXl5eAF5eXgBeX18Abm5uAGZm + ZgBjY2NrmpeX+c/Hx//Px8f/0crK/9/b2f/f2tX/zsjH/7Suu/+fmrf/mJS5/5uXuP+knrX/xL7B/9nT + z//j39v/1M3N/8W8vP/JwMD/urOz/3RycscWFhYkFhcXAAAAAAMAAAABAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQ + EABhYGAANDQ0ABQUFAAAAAAATExMADAwMAAqKysAAwQEAFJSUgATExMAGBkZAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AF1dXQBhYWEAaWlpAGFhYQBeXl4AXFxcAGFhYQBnZ2cAd3Z2AFxcXABdXV0AaGhoAIaF + hQBcXFwAamlpAF1dXQBgYGAAfXx8AF1eXgB1dHQAXFxcAHd2dgBeXl4AXl9fAGNjYwBdXV0AcXFxAGBg + YABdXV0AX2BgAGRkZABeXl4AXl5eAF5fXwBubm4AZmZmAGNjYwBfYGA+gX9/17iysv/PyMj/zMTE/9DI + yP/X0dH/3tnW/9/a1v/c1tH/3dfS/+Db1//a1NP/0MrJ/8e+vv/Iv7//xb29/6Oenv1PTk6SDxAQDhYW + FgAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQAGFgYAA0NDQAFBQUAAAAAABMTEwAMDAwACor + KwADBAQAUlJSABMTEwAYGRkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AXV1dAGFhYQBpaWkAYWFhAF5e + XgBcXFwAYWFhAGdnZwB3dnYAXFxcAF1dXQBoaGgAhoWFAFxcXABqaWkAXV1dAGBgYAB9fHwAXV5eAHV0 + dABcXFwAd3Z2AF5eXgBeX18AY2NjAF1dXQBxcXEAYGBgAF1dXQBfYGAAZGRkAF5eXgBeXl4AXl9fAG5u + bgBmZmYAY2NjAF9gYABfX18OZ2dnf5CNjeu5s7P/ysLC/83ExP/KwcH/ysLC/8zExP/Kw8P/x7+//8e/ + v//JwMD/w7u7/6ulpf9vbW3DKysrQE9OTgAPEBAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAQEBAAYWBgADQ0NAAUFBQAAAAAAExMTAAwMDAAKisrAAMEBABSUlIAExMTABgZGQAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wBdXV0AYWFhAGlpaQBhYWEAXl5eAFxcXABhYWEAZ2dnAHd2dgBcXFwAXV1dAGho + aACGhYUAXFxcAGppaQBdXV0AYGBgAH18fABdXl4AdXR0AFxcXAB3dnYAXl5eAF5fXwBjY2MAXV1dAHFx + cQBgYGAAXV1dAF9gYABkZGQAXl5eAF5eXgBeX18Abm5uAGZmZgBjY2MAX2BgAF9fXwBnZ2cAX19fGWdn + Z3iBf3/RnZmZ+rGrq/+9tbX/wLi4/7+3t/+2r6//pqGh/42Jie1pZ2epLi4uSgMEBAUrKysAT05OAA8Q + EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEABhYGAANDQ0ABQUFAAAAAAATExMADAw + MAAqKysAAwQEAFJSUgATExMAGBkZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AF1dXQBhYWEAaWlpAGFh + YQBeXl4AXFxcAGFhYQBnZ2cAd3Z2AFxcXABdXV0AaGhoAIaFhQBcXFwAamlpAF1dXQBgYGAAfXx8AF1e + XgB1dHQAXFxcAHd2dgBeXl4AXl9fAGNjYwBdXV0AcXFxAGBgYABdXV0AX2BgAGRkZABeXl4AXl5eAF5f + XwBubm4AZmZmAGNjYwBfYGAAX19fAGdnZwBfX18AZ2dnAF5fXyhlZGRgcnBwlHp4eLh8enrBfHp6wHZ1 + dalwb298Ojo6RA0ODg8uLi4AAwQEACsrKwBPTk4ADxAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAEBAQAGFgYAA0NDQAFBQUAAAAAABMTEwAMDAwACorKwADBAQAUlJSABMTEwAYGRkAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A/////////////////////////////////////////////////////4// + //////////////////gA//////////////////+AAB/////////////////+AAAH//////////////// + +AAAAf////////////////AAAAB////////////////AAAAAP///////////////gAAAAB////////// + /////wAAAAAH//////////////4AAAAAA//////////////8AAAAAAH/////////////+AAAAAAA//// + //////////AAAAAAAH/////////////gAAAAAAA/////////////wAAAAAAAH////////////4AAAAAA + AA////////////8AAAAAAAAH////////////AAAAAAAAB////////////AAAAAAAAAP///////////wA + AAAAAAAB///////////xAAAAAAAAAP//////////8gAAAAAAAAD//////////+QAAAAAAAAAf/////// + ///gAAAAAAAAAD//////////wAAAAAAAAAAf/////////5AAAAAAAAAAD/////////+gAAAAAAAAAA// + ////////QAAAAAAAAAAP/////////0AAAAAAAAAAB/////////6AAAAAAAAAAAP////////9AAAAAAAA + AAAB////////+QAAAAAAAAAAAf////////oAAAAAAAAAAAD////////0AAAAAAAAAAAA////////9AAA + AAAAAAAAAH///////+gAAAAAAAAAAAA////////AAAAAAAAAAAAAP///////0AAAAAAAAAAAAD////// + /6AAAAAAAAAAAAAf//////+gAAAAAAAAAAAAD///////QAAAAAAAAAAAAA///////0AAAAAAAAAAAAAH + //////6AAAAAAAAAAAAAB//////+gAAAAAAAAAAAAAf//////wAAAAAAAAAAAAAD//////8AAAAAAAAA + AAAAA//////+AAAAAAAAAAAAAAH//////gAAAAAAAAAAAAAB//////wAAAAAAAAAAAAAAf/////8AAAA + AAAAAAAAAAD/////+AAAAAAAAAAAAAAA//////gAAAAAAAAAAAAAAH/////4AAAAAAAAAAAAAAB///// + 8AAAAAAAAAAAAAAAf/////AAAAAAAAAAAAAAAD/////wAAAAAAAAAAAAAAA/////4AAAAAAAAAAAAAAA + P////+AAAAAAAAAAAAAAAD/////gAAAAAAAAAAAAAAA/////4AAAAAAAAAAAAAAAH////8AAAAAAAAAA + AAAAAB/////AAAAAAAAAAAAAAAAf////wAAAAAAAAAAAAAAAH////8AAAAAAAAAAAAAAAB/////AAAAA + AAAAAAAAAAAf////gAAAAAAAAAAAAAAAH////4AAAAAAAAAAAAAAAA////+AAAAAAAAAAAAAAAAP//// + gAAAAAAAAAAAAAAAD////4AAAAAAAAAAAAAAAA////+AAAAAAAAAAAAAAAAP////gAAAAAAAAAAAAAAA + D////4AAAAAAAAAAAAAAAA////+AAAAAAAAAAAAAAAAP////gAAAAAAAAAAAAAAAD////4AAAAAAAAAA + AAAAAA////+AAAAAAAAAAAAAAAAP////gAAAAAAAAAAAAAAAD////4AAAAAAAAAAAAAAAA////+AAAAA + AAAAAAAAAAAP////gAAAAAAAAAAAAAAAD////4AAAAAAAAAAAAAAAA////+AAAAAAAAAAAAAAAAP//// + gAAAAAAAAAAAAAAAD////4AAAAAAAAAAAAAAAA////+AAAAAAAAAAAAAAAAP////gAAAAAAAAAAAAAAA + D////4AAAAAAAAAAAAAAAA////+AAAAAAAAAAAAAAAAP////gAAAAAAAAAAAAAAAD////4AAAAAAAAAA + AAAAAB////+AAAAAAAAAAAAAAAAf////gAAAAAAAAAAAAAAAH////4AAAAAAAAAAAAAAAB////+AAAAA + AAAAAAAAAAAf////gAAAAAAAAAAAAAAAH////4AAAAAAAAAAAAAAAB////+AAAAAAAAAAAAAAAA///// + wAAAAAAAAAAAAAAAf////+AAAAAAAAAAAAAABP/////wAAAAAAAAAAAAAAn/////+AAAAAAAAAAAAAA/ + ///////AAAAAAAAAAAAD/////////AAAAAAAAAAAP/////////8AAAAAAAAAAf//////////4AAAAAAA + AAf///////////gAAAAAAAAZ///////////+AAAAAAAAZ////////////wAAAAAAAZ/////////////A + AAAAAAJ/////////////8AAAAAAJ//////////////gAAAAAE//////////////8AAAAAE////////// + /////wAAAACf//////////////+AAAABP///////////////wAAABP////////////////AAAAn///// + ///////////4AAAT/////////////////AAAL/////////////////4AAN//////////////////gAH/ + /////////////////+AH//////////////////////////////////////////////////////////// + //////////////////////////////////8= + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/SecureShare/Service References/ServiceReference1/Reference.cs b/Demo_Source_Code/CSharpDemo/SecureShare/Service References/ServiceReference1/Reference.cs new file mode 100644 index 0000000..675d2ed --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/SecureShare/Service References/ServiceReference1/Reference.cs @@ -0,0 +1,1151 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace SecureShare.ServiceReference1 { + + + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ServiceModel.ServiceContractAttribute(ConfigurationName="ServiceReference1.ServiceSoap")] + public interface ServiceSoap { + + // CODEGEN: Generating message contract since element name accountName from namespace http://tempuri.org/ is not marked nillable + [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/SignInAccount", ReplyAction="*")] + SecureShare.ServiceReference1.SignInAccountResponse SignInAccount(SecureShare.ServiceReference1.SignInAccountRequest request); + + // CODEGEN: Generating message contract since element name accountName from namespace http://tempuri.org/ is not marked nillable + [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/SignUpAccount", ReplyAction="*")] + SecureShare.ServiceReference1.SignUpAccountResponse SignUpAccount(SecureShare.ServiceReference1.SignUpAccountRequest request); + + // CODEGEN: Generating message contract since element name accountName from namespace http://tempuri.org/ is not marked nillable + [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/GetFileList", ReplyAction="*")] + SecureShare.ServiceReference1.GetFileListResponse GetFileList(SecureShare.ServiceReference1.GetFileListRequest request); + + // CODEGEN: Generating message contract since element name accountName from namespace http://tempuri.org/ is not marked nillable + [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/AddShareFile", ReplyAction="*")] + SecureShare.ServiceReference1.AddShareFileResponse AddShareFile(SecureShare.ServiceReference1.AddShareFileRequest request); + + // CODEGEN: Generating message contract since element name accountName from namespace http://tempuri.org/ is not marked nillable + [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/DeleteSharedFile", ReplyAction="*")] + SecureShare.ServiceReference1.DeleteSharedFileResponse DeleteSharedFile(SecureShare.ServiceReference1.DeleteSharedFileRequest request); + + // CODEGEN: Generating message contract since element name accountName from namespace http://tempuri.org/ is not marked nillable + [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/GetSharedFileDRInfo", ReplyAction="*")] + SecureShare.ServiceReference1.GetSharedFileDRInfoResponse GetSharedFileDRInfo(SecureShare.ServiceReference1.GetSharedFileDRInfoRequest request); + + // CODEGEN: Generating message contract since element name accountName from namespace http://tempuri.org/ is not marked nillable + [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/ModifySharedFileDRInfo", ReplyAction="*")] + SecureShare.ServiceReference1.ModifySharedFileDRInfoResponse ModifySharedFileDRInfo(SecureShare.ServiceReference1.ModifySharedFileDRInfoRequest request); + + // CODEGEN: Generating message contract since element name accountName from namespace http://tempuri.org/ is not marked nillable + [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/GetAccessLog", ReplyAction="*")] + SecureShare.ServiceReference1.GetAccessLogResponse GetAccessLog(SecureShare.ServiceReference1.GetAccessLogRequest request); + + // CODEGEN: Generating message contract since element name accountName from namespace http://tempuri.org/ is not marked nillable + [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/ClearAccessLog", ReplyAction="*")] + SecureShare.ServiceReference1.ClearAccessLogResponse ClearAccessLog(SecureShare.ServiceReference1.ClearAccessLogRequest request); + + // CODEGEN: Generating message contract since element name userInfoStr from namespace http://tempuri.org/ is not marked nillable + [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/GetSharedFilePermission", ReplyAction="*")] + SecureShare.ServiceReference1.GetSharedFilePermissionResponse GetSharedFilePermission(SecureShare.ServiceReference1.GetSharedFilePermissionRequest request); + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.ServiceModel.MessageContractAttribute(IsWrapped=false)] + public partial class SignInAccountRequest { + + [System.ServiceModel.MessageBodyMemberAttribute(Name="SignInAccount", Namespace="http://tempuri.org/", Order=0)] + public SecureShare.ServiceReference1.SignInAccountRequestBody Body; + + public SignInAccountRequest() { + } + + public SignInAccountRequest(SecureShare.ServiceReference1.SignInAccountRequestBody Body) { + this.Body = Body; + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.Runtime.Serialization.DataContractAttribute(Namespace="http://tempuri.org/")] + public partial class SignInAccountRequestBody { + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=0)] + public string accountName; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=1)] + public string password; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=2)] + public string lastError; + + public SignInAccountRequestBody() { + } + + public SignInAccountRequestBody(string accountName, string password, string lastError) { + this.accountName = accountName; + this.password = password; + this.lastError = lastError; + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.ServiceModel.MessageContractAttribute(IsWrapped=false)] + public partial class SignInAccountResponse { + + [System.ServiceModel.MessageBodyMemberAttribute(Name="SignInAccountResponse", Namespace="http://tempuri.org/", Order=0)] + public SecureShare.ServiceReference1.SignInAccountResponseBody Body; + + public SignInAccountResponse() { + } + + public SignInAccountResponse(SecureShare.ServiceReference1.SignInAccountResponseBody Body) { + this.Body = Body; + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.Runtime.Serialization.DataContractAttribute(Namespace="http://tempuri.org/")] + public partial class SignInAccountResponseBody { + + [System.Runtime.Serialization.DataMemberAttribute(Order=0)] + public bool SignInAccountResult; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=1)] + public string lastError; + + public SignInAccountResponseBody() { + } + + public SignInAccountResponseBody(bool SignInAccountResult, string lastError) { + this.SignInAccountResult = SignInAccountResult; + this.lastError = lastError; + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.ServiceModel.MessageContractAttribute(IsWrapped=false)] + public partial class SignUpAccountRequest { + + [System.ServiceModel.MessageBodyMemberAttribute(Name="SignUpAccount", Namespace="http://tempuri.org/", Order=0)] + public SecureShare.ServiceReference1.SignUpAccountRequestBody Body; + + public SignUpAccountRequest() { + } + + public SignUpAccountRequest(SecureShare.ServiceReference1.SignUpAccountRequestBody Body) { + this.Body = Body; + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.Runtime.Serialization.DataContractAttribute(Namespace="http://tempuri.org/")] + public partial class SignUpAccountRequestBody { + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=0)] + public string accountName; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=1)] + public string password; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=2)] + public string lastError; + + public SignUpAccountRequestBody() { + } + + public SignUpAccountRequestBody(string accountName, string password, string lastError) { + this.accountName = accountName; + this.password = password; + this.lastError = lastError; + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.ServiceModel.MessageContractAttribute(IsWrapped=false)] + public partial class SignUpAccountResponse { + + [System.ServiceModel.MessageBodyMemberAttribute(Name="SignUpAccountResponse", Namespace="http://tempuri.org/", Order=0)] + public SecureShare.ServiceReference1.SignUpAccountResponseBody Body; + + public SignUpAccountResponse() { + } + + public SignUpAccountResponse(SecureShare.ServiceReference1.SignUpAccountResponseBody Body) { + this.Body = Body; + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.Runtime.Serialization.DataContractAttribute(Namespace="http://tempuri.org/")] + public partial class SignUpAccountResponseBody { + + [System.Runtime.Serialization.DataMemberAttribute(Order=0)] + public bool SignUpAccountResult; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=1)] + public string lastError; + + public SignUpAccountResponseBody() { + } + + public SignUpAccountResponseBody(bool SignUpAccountResult, string lastError) { + this.SignUpAccountResult = SignUpAccountResult; + this.lastError = lastError; + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.ServiceModel.MessageContractAttribute(IsWrapped=false)] + public partial class GetFileListRequest { + + [System.ServiceModel.MessageBodyMemberAttribute(Name="GetFileList", Namespace="http://tempuri.org/", Order=0)] + public SecureShare.ServiceReference1.GetFileListRequestBody Body; + + public GetFileListRequest() { + } + + public GetFileListRequest(SecureShare.ServiceReference1.GetFileListRequestBody Body) { + this.Body = Body; + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.Runtime.Serialization.DataContractAttribute(Namespace="http://tempuri.org/")] + public partial class GetFileListRequestBody { + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=0)] + public string accountName; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=1)] + public string password; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=2)] + public string fileList; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=3)] + public string lastError; + + public GetFileListRequestBody() { + } + + public GetFileListRequestBody(string accountName, string password, string fileList, string lastError) { + this.accountName = accountName; + this.password = password; + this.fileList = fileList; + this.lastError = lastError; + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.ServiceModel.MessageContractAttribute(IsWrapped=false)] + public partial class GetFileListResponse { + + [System.ServiceModel.MessageBodyMemberAttribute(Name="GetFileListResponse", Namespace="http://tempuri.org/", Order=0)] + public SecureShare.ServiceReference1.GetFileListResponseBody Body; + + public GetFileListResponse() { + } + + public GetFileListResponse(SecureShare.ServiceReference1.GetFileListResponseBody Body) { + this.Body = Body; + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.Runtime.Serialization.DataContractAttribute(Namespace="http://tempuri.org/")] + public partial class GetFileListResponseBody { + + [System.Runtime.Serialization.DataMemberAttribute(Order=0)] + public bool GetFileListResult; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=1)] + public string fileList; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=2)] + public string lastError; + + public GetFileListResponseBody() { + } + + public GetFileListResponseBody(bool GetFileListResult, string fileList, string lastError) { + this.GetFileListResult = GetFileListResult; + this.fileList = fileList; + this.lastError = lastError; + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.ServiceModel.MessageContractAttribute(IsWrapped=false)] + public partial class AddShareFileRequest { + + [System.ServiceModel.MessageBodyMemberAttribute(Name="AddShareFile", Namespace="http://tempuri.org/", Order=0)] + public SecureShare.ServiceReference1.AddShareFileRequestBody Body; + + public AddShareFileRequest() { + } + + public AddShareFileRequest(SecureShare.ServiceReference1.AddShareFileRequestBody Body) { + this.Body = Body; + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.Runtime.Serialization.DataContractAttribute(Namespace="http://tempuri.org/")] + public partial class AddShareFileRequestBody { + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=0)] + public string accountName; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=1)] + public string password; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=2)] + public string policy; + + [System.Runtime.Serialization.DataMemberAttribute(Order=3)] + public long creationTime; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=4)] + public string key; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=5)] + public string iv; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=6)] + public string lastError; + + public AddShareFileRequestBody() { + } + + public AddShareFileRequestBody(string accountName, string password, string policy, long creationTime, string key, string iv, string lastError) { + this.accountName = accountName; + this.password = password; + this.policy = policy; + this.creationTime = creationTime; + this.key = key; + this.iv = iv; + this.lastError = lastError; + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.ServiceModel.MessageContractAttribute(IsWrapped=false)] + public partial class AddShareFileResponse { + + [System.ServiceModel.MessageBodyMemberAttribute(Name="AddShareFileResponse", Namespace="http://tempuri.org/", Order=0)] + public SecureShare.ServiceReference1.AddShareFileResponseBody Body; + + public AddShareFileResponse() { + } + + public AddShareFileResponse(SecureShare.ServiceReference1.AddShareFileResponseBody Body) { + this.Body = Body; + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.Runtime.Serialization.DataContractAttribute(Namespace="http://tempuri.org/")] + public partial class AddShareFileResponseBody { + + [System.Runtime.Serialization.DataMemberAttribute(Order=0)] + public bool AddShareFileResult; + + [System.Runtime.Serialization.DataMemberAttribute(Order=1)] + public long creationTime; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=2)] + public string key; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=3)] + public string iv; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=4)] + public string lastError; + + public AddShareFileResponseBody() { + } + + public AddShareFileResponseBody(bool AddShareFileResult, long creationTime, string key, string iv, string lastError) { + this.AddShareFileResult = AddShareFileResult; + this.creationTime = creationTime; + this.key = key; + this.iv = iv; + this.lastError = lastError; + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.ServiceModel.MessageContractAttribute(IsWrapped=false)] + public partial class DeleteSharedFileRequest { + + [System.ServiceModel.MessageBodyMemberAttribute(Name="DeleteSharedFile", Namespace="http://tempuri.org/", Order=0)] + public SecureShare.ServiceReference1.DeleteSharedFileRequestBody Body; + + public DeleteSharedFileRequest() { + } + + public DeleteSharedFileRequest(SecureShare.ServiceReference1.DeleteSharedFileRequestBody Body) { + this.Body = Body; + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.Runtime.Serialization.DataContractAttribute(Namespace="http://tempuri.org/")] + public partial class DeleteSharedFileRequestBody { + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=0)] + public string accountName; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=1)] + public string password; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=2)] + public string encryptionIV; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=3)] + public string lastError; + + public DeleteSharedFileRequestBody() { + } + + public DeleteSharedFileRequestBody(string accountName, string password, string encryptionIV, string lastError) { + this.accountName = accountName; + this.password = password; + this.encryptionIV = encryptionIV; + this.lastError = lastError; + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.ServiceModel.MessageContractAttribute(IsWrapped=false)] + public partial class DeleteSharedFileResponse { + + [System.ServiceModel.MessageBodyMemberAttribute(Name="DeleteSharedFileResponse", Namespace="http://tempuri.org/", Order=0)] + public SecureShare.ServiceReference1.DeleteSharedFileResponseBody Body; + + public DeleteSharedFileResponse() { + } + + public DeleteSharedFileResponse(SecureShare.ServiceReference1.DeleteSharedFileResponseBody Body) { + this.Body = Body; + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.Runtime.Serialization.DataContractAttribute(Namespace="http://tempuri.org/")] + public partial class DeleteSharedFileResponseBody { + + [System.Runtime.Serialization.DataMemberAttribute(Order=0)] + public bool DeleteSharedFileResult; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=1)] + public string lastError; + + public DeleteSharedFileResponseBody() { + } + + public DeleteSharedFileResponseBody(bool DeleteSharedFileResult, string lastError) { + this.DeleteSharedFileResult = DeleteSharedFileResult; + this.lastError = lastError; + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.ServiceModel.MessageContractAttribute(IsWrapped=false)] + public partial class GetSharedFileDRInfoRequest { + + [System.ServiceModel.MessageBodyMemberAttribute(Name="GetSharedFileDRInfo", Namespace="http://tempuri.org/", Order=0)] + public SecureShare.ServiceReference1.GetSharedFileDRInfoRequestBody Body; + + public GetSharedFileDRInfoRequest() { + } + + public GetSharedFileDRInfoRequest(SecureShare.ServiceReference1.GetSharedFileDRInfoRequestBody Body) { + this.Body = Body; + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.Runtime.Serialization.DataContractAttribute(Namespace="http://tempuri.org/")] + public partial class GetSharedFileDRInfoRequestBody { + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=0)] + public string accountName; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=1)] + public string password; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=2)] + public string ivStr; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=3)] + public string encryptedDRPolicy; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=4)] + public string lastError; + + public GetSharedFileDRInfoRequestBody() { + } + + public GetSharedFileDRInfoRequestBody(string accountName, string password, string ivStr, string encryptedDRPolicy, string lastError) { + this.accountName = accountName; + this.password = password; + this.ivStr = ivStr; + this.encryptedDRPolicy = encryptedDRPolicy; + this.lastError = lastError; + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.ServiceModel.MessageContractAttribute(IsWrapped=false)] + public partial class GetSharedFileDRInfoResponse { + + [System.ServiceModel.MessageBodyMemberAttribute(Name="GetSharedFileDRInfoResponse", Namespace="http://tempuri.org/", Order=0)] + public SecureShare.ServiceReference1.GetSharedFileDRInfoResponseBody Body; + + public GetSharedFileDRInfoResponse() { + } + + public GetSharedFileDRInfoResponse(SecureShare.ServiceReference1.GetSharedFileDRInfoResponseBody Body) { + this.Body = Body; + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.Runtime.Serialization.DataContractAttribute(Namespace="http://tempuri.org/")] + public partial class GetSharedFileDRInfoResponseBody { + + [System.Runtime.Serialization.DataMemberAttribute(Order=0)] + public bool GetSharedFileDRInfoResult; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=1)] + public string encryptedDRPolicy; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=2)] + public string lastError; + + public GetSharedFileDRInfoResponseBody() { + } + + public GetSharedFileDRInfoResponseBody(bool GetSharedFileDRInfoResult, string encryptedDRPolicy, string lastError) { + this.GetSharedFileDRInfoResult = GetSharedFileDRInfoResult; + this.encryptedDRPolicy = encryptedDRPolicy; + this.lastError = lastError; + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.ServiceModel.MessageContractAttribute(IsWrapped=false)] + public partial class ModifySharedFileDRInfoRequest { + + [System.ServiceModel.MessageBodyMemberAttribute(Name="ModifySharedFileDRInfo", Namespace="http://tempuri.org/", Order=0)] + public SecureShare.ServiceReference1.ModifySharedFileDRInfoRequestBody Body; + + public ModifySharedFileDRInfoRequest() { + } + + public ModifySharedFileDRInfoRequest(SecureShare.ServiceReference1.ModifySharedFileDRInfoRequestBody Body) { + this.Body = Body; + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.Runtime.Serialization.DataContractAttribute(Namespace="http://tempuri.org/")] + public partial class ModifySharedFileDRInfoRequestBody { + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=0)] + public string accountName; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=1)] + public string password; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=2)] + public string encryptedDRPolicy; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=3)] + public string lastError; + + public ModifySharedFileDRInfoRequestBody() { + } + + public ModifySharedFileDRInfoRequestBody(string accountName, string password, string encryptedDRPolicy, string lastError) { + this.accountName = accountName; + this.password = password; + this.encryptedDRPolicy = encryptedDRPolicy; + this.lastError = lastError; + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.ServiceModel.MessageContractAttribute(IsWrapped=false)] + public partial class ModifySharedFileDRInfoResponse { + + [System.ServiceModel.MessageBodyMemberAttribute(Name="ModifySharedFileDRInfoResponse", Namespace="http://tempuri.org/", Order=0)] + public SecureShare.ServiceReference1.ModifySharedFileDRInfoResponseBody Body; + + public ModifySharedFileDRInfoResponse() { + } + + public ModifySharedFileDRInfoResponse(SecureShare.ServiceReference1.ModifySharedFileDRInfoResponseBody Body) { + this.Body = Body; + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.Runtime.Serialization.DataContractAttribute(Namespace="http://tempuri.org/")] + public partial class ModifySharedFileDRInfoResponseBody { + + [System.Runtime.Serialization.DataMemberAttribute(Order=0)] + public bool ModifySharedFileDRInfoResult; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=1)] + public string lastError; + + public ModifySharedFileDRInfoResponseBody() { + } + + public ModifySharedFileDRInfoResponseBody(bool ModifySharedFileDRInfoResult, string lastError) { + this.ModifySharedFileDRInfoResult = ModifySharedFileDRInfoResult; + this.lastError = lastError; + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.ServiceModel.MessageContractAttribute(IsWrapped=false)] + public partial class GetAccessLogRequest { + + [System.ServiceModel.MessageBodyMemberAttribute(Name="GetAccessLog", Namespace="http://tempuri.org/", Order=0)] + public SecureShare.ServiceReference1.GetAccessLogRequestBody Body; + + public GetAccessLogRequest() { + } + + public GetAccessLogRequest(SecureShare.ServiceReference1.GetAccessLogRequestBody Body) { + this.Body = Body; + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.Runtime.Serialization.DataContractAttribute(Namespace="http://tempuri.org/")] + public partial class GetAccessLogRequestBody { + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=0)] + public string accountName; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=1)] + public string password; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=2)] + public string accessLog; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=3)] + public string lastError; + + public GetAccessLogRequestBody() { + } + + public GetAccessLogRequestBody(string accountName, string password, string accessLog, string lastError) { + this.accountName = accountName; + this.password = password; + this.accessLog = accessLog; + this.lastError = lastError; + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.ServiceModel.MessageContractAttribute(IsWrapped=false)] + public partial class GetAccessLogResponse { + + [System.ServiceModel.MessageBodyMemberAttribute(Name="GetAccessLogResponse", Namespace="http://tempuri.org/", Order=0)] + public SecureShare.ServiceReference1.GetAccessLogResponseBody Body; + + public GetAccessLogResponse() { + } + + public GetAccessLogResponse(SecureShare.ServiceReference1.GetAccessLogResponseBody Body) { + this.Body = Body; + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.Runtime.Serialization.DataContractAttribute(Namespace="http://tempuri.org/")] + public partial class GetAccessLogResponseBody { + + [System.Runtime.Serialization.DataMemberAttribute(Order=0)] + public bool GetAccessLogResult; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=1)] + public string accessLog; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=2)] + public string lastError; + + public GetAccessLogResponseBody() { + } + + public GetAccessLogResponseBody(bool GetAccessLogResult, string accessLog, string lastError) { + this.GetAccessLogResult = GetAccessLogResult; + this.accessLog = accessLog; + this.lastError = lastError; + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.ServiceModel.MessageContractAttribute(IsWrapped=false)] + public partial class ClearAccessLogRequest { + + [System.ServiceModel.MessageBodyMemberAttribute(Name="ClearAccessLog", Namespace="http://tempuri.org/", Order=0)] + public SecureShare.ServiceReference1.ClearAccessLogRequestBody Body; + + public ClearAccessLogRequest() { + } + + public ClearAccessLogRequest(SecureShare.ServiceReference1.ClearAccessLogRequestBody Body) { + this.Body = Body; + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.Runtime.Serialization.DataContractAttribute(Namespace="http://tempuri.org/")] + public partial class ClearAccessLogRequestBody { + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=0)] + public string accountName; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=1)] + public string password; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=2)] + public string lastError; + + public ClearAccessLogRequestBody() { + } + + public ClearAccessLogRequestBody(string accountName, string password, string lastError) { + this.accountName = accountName; + this.password = password; + this.lastError = lastError; + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.ServiceModel.MessageContractAttribute(IsWrapped=false)] + public partial class ClearAccessLogResponse { + + [System.ServiceModel.MessageBodyMemberAttribute(Name="ClearAccessLogResponse", Namespace="http://tempuri.org/", Order=0)] + public SecureShare.ServiceReference1.ClearAccessLogResponseBody Body; + + public ClearAccessLogResponse() { + } + + public ClearAccessLogResponse(SecureShare.ServiceReference1.ClearAccessLogResponseBody Body) { + this.Body = Body; + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.Runtime.Serialization.DataContractAttribute(Namespace="http://tempuri.org/")] + public partial class ClearAccessLogResponseBody { + + [System.Runtime.Serialization.DataMemberAttribute(Order=0)] + public bool ClearAccessLogResult; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=1)] + public string lastError; + + public ClearAccessLogResponseBody() { + } + + public ClearAccessLogResponseBody(bool ClearAccessLogResult, string lastError) { + this.ClearAccessLogResult = ClearAccessLogResult; + this.lastError = lastError; + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.ServiceModel.MessageContractAttribute(IsWrapped=false)] + public partial class GetSharedFilePermissionRequest { + + [System.ServiceModel.MessageBodyMemberAttribute(Name="GetSharedFilePermission", Namespace="http://tempuri.org/", Order=0)] + public SecureShare.ServiceReference1.GetSharedFilePermissionRequestBody Body; + + public GetSharedFilePermissionRequest() { + } + + public GetSharedFilePermissionRequest(SecureShare.ServiceReference1.GetSharedFilePermissionRequestBody Body) { + this.Body = Body; + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.Runtime.Serialization.DataContractAttribute(Namespace="http://tempuri.org/")] + public partial class GetSharedFilePermissionRequestBody { + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=0)] + public string userInfoStr; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=1)] + public string key; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=2)] + public string iv; + + [System.Runtime.Serialization.DataMemberAttribute(Order=3)] + public uint accessFlags; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=4)] + public string lastError; + + public GetSharedFilePermissionRequestBody() { + } + + public GetSharedFilePermissionRequestBody(string userInfoStr, string key, string iv, uint accessFlags, string lastError) { + this.userInfoStr = userInfoStr; + this.key = key; + this.iv = iv; + this.accessFlags = accessFlags; + this.lastError = lastError; + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.ServiceModel.MessageContractAttribute(IsWrapped=false)] + public partial class GetSharedFilePermissionResponse { + + [System.ServiceModel.MessageBodyMemberAttribute(Name="GetSharedFilePermissionResponse", Namespace="http://tempuri.org/", Order=0)] + public SecureShare.ServiceReference1.GetSharedFilePermissionResponseBody Body; + + public GetSharedFilePermissionResponse() { + } + + public GetSharedFilePermissionResponse(SecureShare.ServiceReference1.GetSharedFilePermissionResponseBody Body) { + this.Body = Body; + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + [System.Runtime.Serialization.DataContractAttribute(Namespace="http://tempuri.org/")] + public partial class GetSharedFilePermissionResponseBody { + + [System.Runtime.Serialization.DataMemberAttribute(Order=0)] + public bool GetSharedFilePermissionResult; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=1)] + public string key; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=2)] + public string iv; + + [System.Runtime.Serialization.DataMemberAttribute(Order=3)] + public uint accessFlags; + + [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=4)] + public string lastError; + + public GetSharedFilePermissionResponseBody() { + } + + public GetSharedFilePermissionResponseBody(bool GetSharedFilePermissionResult, string key, string iv, uint accessFlags, string lastError) { + this.GetSharedFilePermissionResult = GetSharedFilePermissionResult; + this.key = key; + this.iv = iv; + this.accessFlags = accessFlags; + this.lastError = lastError; + } + } + + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + public interface ServiceSoapChannel : SecureShare.ServiceReference1.ServiceSoap, System.ServiceModel.IClientChannel { + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + public partial class ServiceSoapClient : System.ServiceModel.ClientBase, SecureShare.ServiceReference1.ServiceSoap { + + public ServiceSoapClient() { + } + + public ServiceSoapClient(string endpointConfigurationName) : + base(endpointConfigurationName) { + } + + public ServiceSoapClient(string endpointConfigurationName, string remoteAddress) : + base(endpointConfigurationName, remoteAddress) { + } + + public ServiceSoapClient(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) : + base(endpointConfigurationName, remoteAddress) { + } + + public ServiceSoapClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) : + base(binding, remoteAddress) { + } + + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + SecureShare.ServiceReference1.SignInAccountResponse SecureShare.ServiceReference1.ServiceSoap.SignInAccount(SecureShare.ServiceReference1.SignInAccountRequest request) { + return base.Channel.SignInAccount(request); + } + + public bool SignInAccount(string accountName, string password, ref string lastError) { + SecureShare.ServiceReference1.SignInAccountRequest inValue = new SecureShare.ServiceReference1.SignInAccountRequest(); + inValue.Body = new SecureShare.ServiceReference1.SignInAccountRequestBody(); + inValue.Body.accountName = accountName; + inValue.Body.password = password; + inValue.Body.lastError = lastError; + SecureShare.ServiceReference1.SignInAccountResponse retVal = ((SecureShare.ServiceReference1.ServiceSoap)(this)).SignInAccount(inValue); + lastError = retVal.Body.lastError; + return retVal.Body.SignInAccountResult; + } + + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + SecureShare.ServiceReference1.SignUpAccountResponse SecureShare.ServiceReference1.ServiceSoap.SignUpAccount(SecureShare.ServiceReference1.SignUpAccountRequest request) { + return base.Channel.SignUpAccount(request); + } + + public bool SignUpAccount(string accountName, string password, ref string lastError) { + SecureShare.ServiceReference1.SignUpAccountRequest inValue = new SecureShare.ServiceReference1.SignUpAccountRequest(); + inValue.Body = new SecureShare.ServiceReference1.SignUpAccountRequestBody(); + inValue.Body.accountName = accountName; + inValue.Body.password = password; + inValue.Body.lastError = lastError; + SecureShare.ServiceReference1.SignUpAccountResponse retVal = ((SecureShare.ServiceReference1.ServiceSoap)(this)).SignUpAccount(inValue); + lastError = retVal.Body.lastError; + return retVal.Body.SignUpAccountResult; + } + + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + SecureShare.ServiceReference1.GetFileListResponse SecureShare.ServiceReference1.ServiceSoap.GetFileList(SecureShare.ServiceReference1.GetFileListRequest request) { + return base.Channel.GetFileList(request); + } + + public bool GetFileList(string accountName, string password, ref string fileList, ref string lastError) { + SecureShare.ServiceReference1.GetFileListRequest inValue = new SecureShare.ServiceReference1.GetFileListRequest(); + inValue.Body = new SecureShare.ServiceReference1.GetFileListRequestBody(); + inValue.Body.accountName = accountName; + inValue.Body.password = password; + inValue.Body.fileList = fileList; + inValue.Body.lastError = lastError; + SecureShare.ServiceReference1.GetFileListResponse retVal = ((SecureShare.ServiceReference1.ServiceSoap)(this)).GetFileList(inValue); + fileList = retVal.Body.fileList; + lastError = retVal.Body.lastError; + return retVal.Body.GetFileListResult; + } + + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + SecureShare.ServiceReference1.AddShareFileResponse SecureShare.ServiceReference1.ServiceSoap.AddShareFile(SecureShare.ServiceReference1.AddShareFileRequest request) { + return base.Channel.AddShareFile(request); + } + + public bool AddShareFile(string accountName, string password, string policy, ref long creationTime, ref string key, ref string iv, ref string lastError) { + SecureShare.ServiceReference1.AddShareFileRequest inValue = new SecureShare.ServiceReference1.AddShareFileRequest(); + inValue.Body = new SecureShare.ServiceReference1.AddShareFileRequestBody(); + inValue.Body.accountName = accountName; + inValue.Body.password = password; + inValue.Body.policy = policy; + inValue.Body.creationTime = creationTime; + inValue.Body.key = key; + inValue.Body.iv = iv; + inValue.Body.lastError = lastError; + SecureShare.ServiceReference1.AddShareFileResponse retVal = ((SecureShare.ServiceReference1.ServiceSoap)(this)).AddShareFile(inValue); + creationTime = retVal.Body.creationTime; + key = retVal.Body.key; + iv = retVal.Body.iv; + lastError = retVal.Body.lastError; + return retVal.Body.AddShareFileResult; + } + + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + SecureShare.ServiceReference1.DeleteSharedFileResponse SecureShare.ServiceReference1.ServiceSoap.DeleteSharedFile(SecureShare.ServiceReference1.DeleteSharedFileRequest request) { + return base.Channel.DeleteSharedFile(request); + } + + public bool DeleteSharedFile(string accountName, string password, string encryptionIV, ref string lastError) { + SecureShare.ServiceReference1.DeleteSharedFileRequest inValue = new SecureShare.ServiceReference1.DeleteSharedFileRequest(); + inValue.Body = new SecureShare.ServiceReference1.DeleteSharedFileRequestBody(); + inValue.Body.accountName = accountName; + inValue.Body.password = password; + inValue.Body.encryptionIV = encryptionIV; + inValue.Body.lastError = lastError; + SecureShare.ServiceReference1.DeleteSharedFileResponse retVal = ((SecureShare.ServiceReference1.ServiceSoap)(this)).DeleteSharedFile(inValue); + lastError = retVal.Body.lastError; + return retVal.Body.DeleteSharedFileResult; + } + + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + SecureShare.ServiceReference1.GetSharedFileDRInfoResponse SecureShare.ServiceReference1.ServiceSoap.GetSharedFileDRInfo(SecureShare.ServiceReference1.GetSharedFileDRInfoRequest request) { + return base.Channel.GetSharedFileDRInfo(request); + } + + public bool GetSharedFileDRInfo(string accountName, string password, string ivStr, ref string encryptedDRPolicy, ref string lastError) { + SecureShare.ServiceReference1.GetSharedFileDRInfoRequest inValue = new SecureShare.ServiceReference1.GetSharedFileDRInfoRequest(); + inValue.Body = new SecureShare.ServiceReference1.GetSharedFileDRInfoRequestBody(); + inValue.Body.accountName = accountName; + inValue.Body.password = password; + inValue.Body.ivStr = ivStr; + inValue.Body.encryptedDRPolicy = encryptedDRPolicy; + inValue.Body.lastError = lastError; + SecureShare.ServiceReference1.GetSharedFileDRInfoResponse retVal = ((SecureShare.ServiceReference1.ServiceSoap)(this)).GetSharedFileDRInfo(inValue); + encryptedDRPolicy = retVal.Body.encryptedDRPolicy; + lastError = retVal.Body.lastError; + return retVal.Body.GetSharedFileDRInfoResult; + } + + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + SecureShare.ServiceReference1.ModifySharedFileDRInfoResponse SecureShare.ServiceReference1.ServiceSoap.ModifySharedFileDRInfo(SecureShare.ServiceReference1.ModifySharedFileDRInfoRequest request) { + return base.Channel.ModifySharedFileDRInfo(request); + } + + public bool ModifySharedFileDRInfo(string accountName, string password, string encryptedDRPolicy, ref string lastError) { + SecureShare.ServiceReference1.ModifySharedFileDRInfoRequest inValue = new SecureShare.ServiceReference1.ModifySharedFileDRInfoRequest(); + inValue.Body = new SecureShare.ServiceReference1.ModifySharedFileDRInfoRequestBody(); + inValue.Body.accountName = accountName; + inValue.Body.password = password; + inValue.Body.encryptedDRPolicy = encryptedDRPolicy; + inValue.Body.lastError = lastError; + SecureShare.ServiceReference1.ModifySharedFileDRInfoResponse retVal = ((SecureShare.ServiceReference1.ServiceSoap)(this)).ModifySharedFileDRInfo(inValue); + lastError = retVal.Body.lastError; + return retVal.Body.ModifySharedFileDRInfoResult; + } + + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + SecureShare.ServiceReference1.GetAccessLogResponse SecureShare.ServiceReference1.ServiceSoap.GetAccessLog(SecureShare.ServiceReference1.GetAccessLogRequest request) { + return base.Channel.GetAccessLog(request); + } + + public bool GetAccessLog(string accountName, string password, ref string accessLog, ref string lastError) { + SecureShare.ServiceReference1.GetAccessLogRequest inValue = new SecureShare.ServiceReference1.GetAccessLogRequest(); + inValue.Body = new SecureShare.ServiceReference1.GetAccessLogRequestBody(); + inValue.Body.accountName = accountName; + inValue.Body.password = password; + inValue.Body.accessLog = accessLog; + inValue.Body.lastError = lastError; + SecureShare.ServiceReference1.GetAccessLogResponse retVal = ((SecureShare.ServiceReference1.ServiceSoap)(this)).GetAccessLog(inValue); + accessLog = retVal.Body.accessLog; + lastError = retVal.Body.lastError; + return retVal.Body.GetAccessLogResult; + } + + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + SecureShare.ServiceReference1.ClearAccessLogResponse SecureShare.ServiceReference1.ServiceSoap.ClearAccessLog(SecureShare.ServiceReference1.ClearAccessLogRequest request) { + return base.Channel.ClearAccessLog(request); + } + + public bool ClearAccessLog(string accountName, string password, ref string lastError) { + SecureShare.ServiceReference1.ClearAccessLogRequest inValue = new SecureShare.ServiceReference1.ClearAccessLogRequest(); + inValue.Body = new SecureShare.ServiceReference1.ClearAccessLogRequestBody(); + inValue.Body.accountName = accountName; + inValue.Body.password = password; + inValue.Body.lastError = lastError; + SecureShare.ServiceReference1.ClearAccessLogResponse retVal = ((SecureShare.ServiceReference1.ServiceSoap)(this)).ClearAccessLog(inValue); + lastError = retVal.Body.lastError; + return retVal.Body.ClearAccessLogResult; + } + + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + SecureShare.ServiceReference1.GetSharedFilePermissionResponse SecureShare.ServiceReference1.ServiceSoap.GetSharedFilePermission(SecureShare.ServiceReference1.GetSharedFilePermissionRequest request) { + return base.Channel.GetSharedFilePermission(request); + } + + public bool GetSharedFilePermission(string userInfoStr, ref string key, ref string iv, ref uint accessFlags, ref string lastError) { + SecureShare.ServiceReference1.GetSharedFilePermissionRequest inValue = new SecureShare.ServiceReference1.GetSharedFilePermissionRequest(); + inValue.Body = new SecureShare.ServiceReference1.GetSharedFilePermissionRequestBody(); + inValue.Body.userInfoStr = userInfoStr; + inValue.Body.key = key; + inValue.Body.iv = iv; + inValue.Body.accessFlags = accessFlags; + inValue.Body.lastError = lastError; + SecureShare.ServiceReference1.GetSharedFilePermissionResponse retVal = ((SecureShare.ServiceReference1.ServiceSoap)(this)).GetSharedFilePermission(inValue); + key = retVal.Body.key; + iv = retVal.Body.iv; + accessFlags = retVal.Body.accessFlags; + lastError = retVal.Body.lastError; + return retVal.Body.GetSharedFilePermissionResult; + } + } +} diff --git a/Demo_Source_Code/CSharpDemo/SecureShare/Service References/ServiceReference1/Reference.svcmap b/Demo_Source_Code/CSharpDemo/SecureShare/Service References/ServiceReference1/Reference.svcmap new file mode 100644 index 0000000..f37698c --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/SecureShare/Service References/ServiceReference1/Reference.svcmap @@ -0,0 +1,31 @@ + + + + false + true + + false + false + false + + + true + Auto + true + true + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/SecureShare/Service References/ServiceReference1/configuration.svcinfo b/Demo_Source_Code/CSharpDemo/SecureShare/Service References/ServiceReference1/configuration.svcinfo new file mode 100644 index 0000000..f6ecac6 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/SecureShare/Service References/ServiceReference1/configuration.svcinfo @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/SecureShare/Service References/ServiceReference1/configuration91.svcinfo b/Demo_Source_Code/CSharpDemo/SecureShare/Service References/ServiceReference1/configuration91.svcinfo new file mode 100644 index 0000000..0bb869c --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/SecureShare/Service References/ServiceReference1/configuration91.svcinfo @@ -0,0 +1,201 @@ + + + + + + + ServiceSoap + + + + + + + + + + + + + + + + + + + + + StrongWildcard + + + + + + 65536 + + + + + + + + + System.ServiceModel.Configuration.XmlDictionaryReaderQuotasElement + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + System.Text.UTF8Encoding + + + Buffered + + + + + + Text + + + System.ServiceModel.Configuration.BasicHttpSecurityElement + + + None + + + System.ServiceModel.Configuration.HttpTransportSecurityElement + + + None + + + None + + + System.Security.Authentication.ExtendedProtection.Configuration.ExtendedProtectionPolicyElement + + + Never + + + TransportSelected + + + (Collection) + + + + + + System.ServiceModel.Configuration.BasicHttpMessageSecurityElement + + + UserName + + + Default + + + + + + + + + http://encryptme.net/webapi.asmx + + + + + + basicHttpBinding + + + ServiceSoap + + + ServiceReference1.ServiceSoap + + + System.ServiceModel.Configuration.AddressHeaderCollectionElement + + + <Header /> + + + System.ServiceModel.Configuration.IdentityElement + + + System.ServiceModel.Configuration.UserPrincipalNameElement + + + + + + System.ServiceModel.Configuration.ServicePrincipalNameElement + + + + + + System.ServiceModel.Configuration.DnsElement + + + + + + System.ServiceModel.Configuration.RsaElement + + + + + + System.ServiceModel.Configuration.CertificateElement + + + + + + System.ServiceModel.Configuration.CertificateReferenceElement + + + My + + + LocalMachine + + + FindBySubjectDistinguishedName + + + + + + False + + + ServiceSoap + + + + + + + + + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/SecureShare/Service References/ServiceReference1/webapi.disco b/Demo_Source_Code/CSharpDemo/SecureShare/Service References/ServiceReference1/webapi.disco new file mode 100644 index 0000000..a1c38a7 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/SecureShare/Service References/ServiceReference1/webapi.disco @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/SecureShare/Service References/ServiceReference1/webapi.wsdl b/Demo_Source_Code/CSharpDemo/SecureShare/Service References/ServiceReference1/webapi.wsdl new file mode 100644 index 0000000..a1d994d --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/SecureShare/Service References/ServiceReference1/webapi.wsdl @@ -0,0 +1,494 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/SecureShare/ShareFileForm.Designer.cs b/Demo_Source_Code/CSharpDemo/SecureShare/ShareFileForm.Designer.cs new file mode 100644 index 0000000..1d1623b --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/SecureShare/ShareFileForm.Designer.cs @@ -0,0 +1,291 @@ +namespace SecureShare +{ + partial class ShareFileForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ShareFileForm)); + this.label2 = new System.Windows.Forms.Label(); + this.label1 = new System.Windows.Forms.Label(); + this.textBox_FileName = new System.Windows.Forms.TextBox(); + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.label3 = new System.Windows.Forms.Label(); + this.textBox_UnauthorizedUserNames = new System.Windows.Forms.TextBox(); + this.label4 = new System.Windows.Forms.Label(); + this.textBox_AuthorizedUserNames = new System.Windows.Forms.TextBox(); + this.label5 = new System.Windows.Forms.Label(); + this.textBox_UnauthorizedProcessNames = new System.Windows.Forms.TextBox(); + this.label11 = new System.Windows.Forms.Label(); + this.textBox_TargetName = new System.Windows.Forms.TextBox(); + this.label6 = new System.Windows.Forms.Label(); + this.dateTimePicker_ExpireDate = new System.Windows.Forms.DateTimePicker(); + this.button_OpenFile = new System.Windows.Forms.Button(); + this.dateTimePicker_ExpireTime = new System.Windows.Forms.DateTimePicker(); + this.label12 = new System.Windows.Forms.Label(); + this.textBox_authorizedProcessNames = new System.Windows.Forms.TextBox(); + this.label10 = new System.Windows.Forms.Label(); + this.button_CreateFile = new System.Windows.Forms.Button(); + this.groupBox1.SuspendLayout(); + this.SuspendLayout(); + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(16, 90); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(104, 13); + this.label2.TabIndex = 2; + this.label2.Text = "Share file expire time"; + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(16, 20); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(114, 13); + this.label1.TabIndex = 1; + this.label1.Text = "File name to be shared"; + // + // textBox_FileName + // + this.textBox_FileName.Location = new System.Drawing.Point(213, 20); + this.textBox_FileName.Name = "textBox_FileName"; + this.textBox_FileName.Size = new System.Drawing.Size(242, 20); + this.textBox_FileName.TabIndex = 2; + this.textBox_FileName.Text = "c:\\test\\test.txt"; + // + // groupBox1 + // + this.groupBox1.Controls.Add(this.label3); + this.groupBox1.Controls.Add(this.textBox_UnauthorizedUserNames); + this.groupBox1.Controls.Add(this.label4); + this.groupBox1.Controls.Add(this.textBox_AuthorizedUserNames); + this.groupBox1.Controls.Add(this.label5); + this.groupBox1.Controls.Add(this.textBox_UnauthorizedProcessNames); + this.groupBox1.Controls.Add(this.label11); + this.groupBox1.Controls.Add(this.textBox_TargetName); + this.groupBox1.Controls.Add(this.label6); + this.groupBox1.Controls.Add(this.dateTimePicker_ExpireDate); + this.groupBox1.Controls.Add(this.button_OpenFile); + this.groupBox1.Controls.Add(this.dateTimePicker_ExpireTime); + this.groupBox1.Controls.Add(this.label12); + this.groupBox1.Controls.Add(this.textBox_authorizedProcessNames); + this.groupBox1.Controls.Add(this.label10); + this.groupBox1.Controls.Add(this.label2); + this.groupBox1.Controls.Add(this.textBox_FileName); + this.groupBox1.Controls.Add(this.label1); + this.groupBox1.Location = new System.Drawing.Point(12, 2); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size(538, 309); + this.groupBox1.TabIndex = 11; + this.groupBox1.TabStop = false; + // + // label3 + // + this.label3.AutoSize = true; + this.label3.Font = new System.Drawing.Font("Microsoft Sans Serif", 6.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.label3.Location = new System.Drawing.Point(209, 230); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(195, 12); + this.label3.TabIndex = 80; + this.label3.Text = "(split with \';\' ,user name format \"domain\\user\" )"; + // + // textBox_UnauthorizedUserNames + // + this.textBox_UnauthorizedUserNames.Location = new System.Drawing.Point(214, 253); + this.textBox_UnauthorizedUserNames.Name = "textBox_UnauthorizedUserNames"; + this.textBox_UnauthorizedUserNames.Size = new System.Drawing.Size(242, 20); + this.textBox_UnauthorizedUserNames.TabIndex = 76; + // + // label4 + // + this.label4.AutoSize = true; + this.label4.Location = new System.Drawing.Point(17, 253); + this.label4.Name = "label4"; + this.label4.Size = new System.Drawing.Size(127, 13); + this.label4.TabIndex = 79; + this.label4.Text = "Unauthorized user names"; + // + // textBox_AuthorizedUserNames + // + this.textBox_AuthorizedUserNames.Location = new System.Drawing.Point(214, 210); + this.textBox_AuthorizedUserNames.Name = "textBox_AuthorizedUserNames"; + this.textBox_AuthorizedUserNames.Size = new System.Drawing.Size(242, 20); + this.textBox_AuthorizedUserNames.TabIndex = 75; + // + // label5 + // + this.label5.AutoSize = true; + this.label5.Location = new System.Drawing.Point(17, 213); + this.label5.Name = "label5"; + this.label5.Size = new System.Drawing.Size(114, 13); + this.label5.TabIndex = 78; + this.label5.Text = "Authorized user names"; + // + // textBox_UnauthorizedProcessNames + // + this.textBox_UnauthorizedProcessNames.Location = new System.Drawing.Point(214, 173); + this.textBox_UnauthorizedProcessNames.Name = "textBox_UnauthorizedProcessNames"; + this.textBox_UnauthorizedProcessNames.Size = new System.Drawing.Size(242, 20); + this.textBox_UnauthorizedProcessNames.TabIndex = 74; + this.textBox_UnauthorizedProcessNames.Text = "explorer.exe;"; + // + // label11 + // + this.label11.AutoSize = true; + this.label11.Location = new System.Drawing.Point(17, 173); + this.label11.Name = "label11"; + this.label11.Size = new System.Drawing.Size(147, 13); + this.label11.TabIndex = 77; + this.label11.Text = "Unauthorized process names"; + // + // textBox_TargetName + // + this.textBox_TargetName.Location = new System.Drawing.Point(214, 54); + this.textBox_TargetName.Name = "textBox_TargetName"; + this.textBox_TargetName.Size = new System.Drawing.Size(242, 20); + this.textBox_TargetName.TabIndex = 72; + this.textBox_TargetName.Text = "c:\\test\\test.txt"; + // + // label6 + // + this.label6.AutoSize = true; + this.label6.Location = new System.Drawing.Point(17, 54); + this.label6.Name = "label6"; + this.label6.Size = new System.Drawing.Size(118, 13); + this.label6.TabIndex = 73; + this.label6.Text = "Target shared file name"; + // + // dateTimePicker_ExpireDate + // + this.dateTimePicker_ExpireDate.CustomFormat = "yyyy-MM-dd"; + this.dateTimePicker_ExpireDate.Format = System.Windows.Forms.DateTimePickerFormat.Custom; + this.dateTimePicker_ExpireDate.Location = new System.Drawing.Point(212, 90); + this.dateTimePicker_ExpireDate.Name = "dateTimePicker_ExpireDate"; + this.dateTimePicker_ExpireDate.Size = new System.Drawing.Size(120, 20); + this.dateTimePicker_ExpireDate.TabIndex = 71; + // + // button_OpenFile + // + this.button_OpenFile.Location = new System.Drawing.Point(470, 18); + this.button_OpenFile.Name = "button_OpenFile"; + this.button_OpenFile.Size = new System.Drawing.Size(51, 23); + this.button_OpenFile.TabIndex = 3; + this.button_OpenFile.Text = "browse"; + this.button_OpenFile.UseVisualStyleBackColor = true; + this.button_OpenFile.Click += new System.EventHandler(this.button_OpenFile_Click); + // + // dateTimePicker_ExpireTime + // + this.dateTimePicker_ExpireTime.CustomFormat = " HH:mm:ss"; + this.dateTimePicker_ExpireTime.Format = System.Windows.Forms.DateTimePickerFormat.Time; + this.dateTimePicker_ExpireTime.Location = new System.Drawing.Point(335, 90); + this.dateTimePicker_ExpireTime.Name = "dateTimePicker_ExpireTime"; + this.dateTimePicker_ExpireTime.ShowUpDown = true; + this.dateTimePicker_ExpireTime.Size = new System.Drawing.Size(120, 20); + this.dateTimePicker_ExpireTime.TabIndex = 5; + // + // label12 + // + this.label12.AutoSize = true; + this.label12.Font = new System.Drawing.Font("Microsoft Sans Serif", 6.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.label12.Location = new System.Drawing.Point(211, 151); + this.label12.Name = "label12"; + this.label12.Size = new System.Drawing.Size(244, 12); + this.label12.TabIndex = 57; + this.label12.Text = "( split with \';\' , process format \"notepad.exe;wordpad.exe\")"; + // + // textBox_authorizedProcessNames + // + this.textBox_authorizedProcessNames.Location = new System.Drawing.Point(213, 127); + this.textBox_authorizedProcessNames.Name = "textBox_authorizedProcessNames"; + this.textBox_authorizedProcessNames.Size = new System.Drawing.Size(242, 20); + this.textBox_authorizedProcessNames.TabIndex = 6; + // + // label10 + // + this.label10.AutoSize = true; + this.label10.Location = new System.Drawing.Point(16, 130); + this.label10.Name = "label10"; + this.label10.Size = new System.Drawing.Size(131, 13); + this.label10.TabIndex = 53; + this.label10.Text = "Authorized process names"; + // + // button_CreateFile + // + this.button_CreateFile.DialogResult = System.Windows.Forms.DialogResult.OK; + this.button_CreateFile.Location = new System.Drawing.Point(419, 335); + this.button_CreateFile.Name = "button_CreateFile"; + this.button_CreateFile.Size = new System.Drawing.Size(114, 23); + this.button_CreateFile.TabIndex = 15; + this.button_CreateFile.Text = "Create Share File"; + this.button_CreateFile.UseVisualStyleBackColor = true; + this.button_CreateFile.Click += new System.EventHandler(this.button_CreateFile_Click); + // + // ShareFileForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(571, 394); + this.Controls.Add(this.button_CreateFile); + this.Controls.Add(this.groupBox1); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "ShareFileForm"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "EaseFilter Secure File Creation"; + this.groupBox1.ResumeLayout(false); + this.groupBox1.PerformLayout(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.Label label2; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.TextBox textBox_FileName; + private System.Windows.Forms.GroupBox groupBox1; + private System.Windows.Forms.TextBox textBox_authorizedProcessNames; + private System.Windows.Forms.Label label10; + private System.Windows.Forms.Label label12; + private System.Windows.Forms.DateTimePicker dateTimePicker_ExpireTime; + private System.Windows.Forms.Button button_OpenFile; + private System.Windows.Forms.Button button_CreateFile; + private System.Windows.Forms.DateTimePicker dateTimePicker_ExpireDate; + private System.Windows.Forms.TextBox textBox_TargetName; + private System.Windows.Forms.Label label6; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.TextBox textBox_UnauthorizedUserNames; + private System.Windows.Forms.Label label4; + private System.Windows.Forms.TextBox textBox_AuthorizedUserNames; + private System.Windows.Forms.Label label5; + private System.Windows.Forms.TextBox textBox_UnauthorizedProcessNames; + private System.Windows.Forms.Label label11; + } +} \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/SecureShare/ShareFileForm.cs b/Demo_Source_Code/CSharpDemo/SecureShare/ShareFileForm.cs new file mode 100644 index 0000000..5ac02e7 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/SecureShare/ShareFileForm.cs @@ -0,0 +1,234 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.IO; +using System.Windows.Forms; +using System.Runtime.InteropServices; + +using EaseFilter.FilterControl; +using EaseFilter.CommonObjects; + +namespace SecureShare +{ + public partial class ShareFileForm : Form + { + + DRPolicy selectedDRPolicy = null; + + public ShareFileForm(DRPolicy drPolicy) + { + InitializeComponent(); + + textBox_FileName.Text = drPolicy.FileName; + + selectedDRPolicy = drPolicy; + textBox_FileName.Enabled = false; + textBox_TargetName.Enabled = false; + button_OpenFile.Enabled = false; + + dateTimePicker_ExpireDate.Value = DateTime.FromFileTime(drPolicy.ExpireTime); + dateTimePicker_ExpireTime.Value = DateTime.FromFileTime(drPolicy.ExpireTime); + textBox_authorizedProcessNames.Text = drPolicy.AuthorizedProcessNames; + textBox_UnauthorizedProcessNames.Text = drPolicy.UnauthorizedProcessNames; + textBox_AuthorizedUserNames.Text = drPolicy.AuthorizedUserNames; + textBox_UnauthorizedUserNames.Text = drPolicy.UnauthorizedUserNames; + + button_CreateFile.Text = "Apply change"; + } + + public ShareFileForm() + { + InitializeComponent(); + dateTimePicker_ExpireDate.Value = DateTime.Now.AddDays(1); + dateTimePicker_ExpireTime.Value = DateTime.Now; + + button_CreateFile.Text = "Create Share File"; + } + + private DRPolicy GetDRSetting() + { + DRPolicy drPolicy = new DRPolicy(); + + try + { + drPolicy.AuthorizedProcessNames = textBox_authorizedProcessNames.Text.Trim().ToLower(); + drPolicy.UnauthorizedProcessNames = textBox_UnauthorizedProcessNames.Text.Trim().ToLower(); + drPolicy.AuthorizedUserNames = textBox_AuthorizedUserNames.Text.Trim().ToLower(); + drPolicy.UnauthorizedUserNames = textBox_UnauthorizedUserNames.Text.Trim().ToLower(); + DateTime expireDate = dateTimePicker_ExpireDate.Value.Date + dateTimePicker_ExpireTime.Value.TimeOfDay; + drPolicy.FileName = Path.GetFileName(textBox_TargetName.Text); + drPolicy.ExpireTime = expireDate.ToFileTime(); + + if (null != selectedDRPolicy) + { + drPolicy.EncryptionIV = selectedDRPolicy.EncryptionIV; + } + } + catch (Exception ex) + { + throw new Exception("Apply digital right failed with error:" + ex.Message); + } + + return drPolicy; + } + + + private bool CreateOrModifyShareEncryptFile() + { + string lastError = string.Empty; + + string authorizedProcessNames = textBox_authorizedProcessNames.Text.Trim(); + string unauthorizedProcessNames = textBox_UnauthorizedProcessNames.Text.Trim(); + string authorizedUserNames = textBox_AuthorizedUserNames.Text.Trim(); + string unauthorizedUserNames = textBox_UnauthorizedUserNames.Text.Trim(); + string fileName = textBox_FileName.Text.Trim(); + string targetFileName = textBox_TargetName.Text; + + try + { + if (fileName.Length == 0) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("The file name can't be empty.", "Create share encrypted file", MessageBoxButtons.OK, MessageBoxIcon.Error); + return false; + } + + DateTime expireDateTime = dateTimePicker_ExpireDate.Value.Date + dateTimePicker_ExpireTime.Value.TimeOfDay; + if (expireDateTime <= DateTime.Now) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("The expire time can't be less than current time.", "Create share encrypted file", MessageBoxButtons.OK, MessageBoxIcon.Error); + return false; + } + + + //here we generate the random unique IV and key, you can use your own key and iv + byte[] encryptionIV = Utils.GetRandomIV(); + byte[] encryptionKey = Utils.GetRandomKey(); + + string keyStr = string.Empty; + string ivStr = string.Empty; + string tagStr = Utils.ByteArrayToHexStr(encryptionIV); + + byte[] tagData = UnicodeEncoding.Unicode.GetBytes(tagStr); + + bool retVal = false; + + if (fileName.Equals(targetFileName, StringComparison.CurrentCulture)) + { + retVal = FilterAPI.AESEncryptFileWithTag(fileName, (uint)encryptionKey.Length, encryptionKey, (uint)encryptionIV.Length, encryptionIV, (uint)tagData.Length, tagData); + } + else + { + retVal = FilterAPI.AESEncryptFileToFileWithTag(fileName, targetFileName, (uint)encryptionKey.Length, encryptionKey, (uint)encryptionIV.Length, encryptionIV, (uint)tagData.Length, tagData); + } + + if (!retVal) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("Create encrypted file " + targetFileName + " failed with error:" + FilterAPI.GetLastErrorMessage(), "Create share encrypted file", MessageBoxButtons.OK, MessageBoxIcon.Error); + + if (!fileName.Equals(targetFileName, StringComparison.CurrentCulture)) + { + File.Delete(targetFileName); + } + + return false; + } + else + { + //set this flag to the encrypted file, require to get permission from user mode when the file open + if (!FilterAPI.SetHeaderFlags(targetFileName, (uint)AESFlags.Flags_Request_IV_And_Key_From_User,FilterAPI.ALLOW_MAX_RIGHT_ACCESS)) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("SetHeaderFlags for file " + targetFileName + " failed with error:" + FilterAPI.GetLastErrorMessage(), "SetHeaderFlags", MessageBoxButtons.OK, MessageBoxIcon.Error); + + return false; + } + + if (!GlobalConfig.StoreSharedFileMetaDataInServer) + { + //add the permission meta data to a file and store it in the server, it will be used when the file open. + if (!DRServer.AddDRInfoToFile(targetFileName, authorizedProcessNames, unauthorizedProcessNames, authorizedUserNames, unauthorizedUserNames + , expireDateTime, encryptionIV, encryptionKey, FilterAPI.ALLOW_MAX_RIGHT_ACCESS.ToString())) + { + return false; + } + + } + + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + string message = "Create encrypted file " + targetFileName + " succeeded, you can distribute this encrypted file to your client.\r\n\r\nDownload this file to the share file drop folder in the client,"; + message += " then start the filter service there, now you can open the encrypted file if the process in client has the permission."; + MessageBox.Show(message, "Share encrypted file", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + + return true; + + } + catch (Exception ex) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("Create share file failed with error " + ex.Message, "Create share encrypted file", MessageBoxButtons.OK, MessageBoxIcon.Error); + + return false; + } + } + + + private void button_OpenFile_Click(object sender, EventArgs e) + { + OpenFileDialog openFileDialog = new OpenFileDialog(); + + if (openFileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + textBox_FileName.Text = openFileDialog.FileName; + textBox_TargetName.Text = openFileDialog.FileName; + } + } + + + private void button_CreateFile_Click(object sender, EventArgs e) + { + try + { + string lastError = string.Empty; + if (CreateOrModifyShareEncryptFile()) + { + this.Close(); + } + + } + catch (Exception ex) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("Add digital right information to file " + textBox_FileName + " failed with error " + ex.Message, "Create", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + + } + + + } +} diff --git a/Demo_Source_Code/CSharpDemo/SecureShare/ShareFileForm.resx b/Demo_Source_Code/CSharpDemo/SecureShare/ShareFileForm.resx new file mode 100644 index 0000000..6cb06c8 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/SecureShare/ShareFileForm.resx @@ -0,0 +1,1253 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + AAABAAEAgIAAAAEAIAAoCAEAFgAAACgAAACAAAAAAAEAAAEAIAAAAAAAAAABABMLAAATCwAAAAAAAAAA + AAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAIAAAADAAAAAwAA + AAQAAAAEAAAABAAAAAMAAAADAAAAAgAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAEAAAABAAAAAgAAAAQAAAAFAAAACAAAAAkAAAAKAAAACwAAAAsAAAALAAAACgAAAAkAAAAHAAAABQAA + AAMAAAACAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAACAAAAAwAAAAUAAAAIAAAADAAAAA4AAAASAAAAFQAA + ABgAAAAaAAAAGgAAABoAAAAXAAAAFQAAABEAAAAOAAAACgAAAAcAAAAFAAAAAgAAAAEAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABAAAABAAA + AAYAAAAKAAAADgAAABQAAAAZAAAAHQAAACIAAAAmAAAAKgAAAC0AAAAuAAAALgAAACwAAAAoAAAAJAAA + AB4AAAAXAAAAEgAAAA0AAAAJAAAABQAAAAIAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAABAAAAAgAAAAUAAAAJAAAADwAAABQAAAAYAAAAGgAAACUAAQE3AQEBRAEB + AU0BAQFQAAEBTAAAAEYAAAA+AAAAPQAAAD0AAAA6AAAAMwAAACsAAAAjAAAAGwAAABMAAAANAAAACQAA + AAUAAAACAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAQAAAAIAAAADQAA + ABIAAAATAAAAIRAREUkuLi6DTk1NsHBsbNN9eHjqhoGB9oN+fvN3c3PiYV9fzD08PK0fHx+EAAEBXAAA + AEoAAABGAAAAQgAAADkAAAAvAAAAJAAAABsAAAASAAAACwAAAAcAAAADAAAAAgAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAQAAAAIAAAAFAAAACwAAAA8AAAAPAgICJicoKG1cWlq9iYOD9qaenv+zqan/taqq/7es + rP+4ra3/ua2t/7itrf+3rq7/tKur/56YmP93c3PpPT09sg4ODnUAAABRAAAASwAAAEUAAAA6AAAALQAA + ACEAAAAXAAAADwAAAAgAAAAEAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAADAAAABwAAAAwAAAAMAQEBGygo + KG1oZmbUnpaW/7OoqP+2qqr/sqam/7asrP+/trb/x8C//83Gxf/LxMP/x7++/7+1tf+4ra3/uq+v/72y + sv+0q6v/jIeH90ZFRb0MDAx1AAAAUwAAAE4AAABDAAAANQAAACgAAAAcAAAAEgAAAAsAAAAGAAAAAwAA + AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAABAAAABAAAAAgAAAALAAAADBscHEtgXl7DnZWV/7Spqf+zqKj/s6io/8S8vP/Y0tH/2dLN/8nC + vf+zqqv/p5ye/6qfof+5sK//0MnD/9rU0f/Tzc3/wbi4/7mvr/+/tbX/t6+v/4WBgfQ2NjatAgICZQAA + AFIAAABLAAAAPQAAAC4AAAAhAAAAFQAAAAwAAAAHAAAAAwAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAQAAAAJAAAACQYHBxs/Pz+KioaG9rKo + qP+zp6f/s6en/8vEw//g29f/xr67/5KGj/9uY3//YVeD/2Zelf9qZJ7/aGKc/2BYjP9hV33/eGp8/6OX + mP/TzMf/3tnX/8W9vf+7sbH/wrm5/62np/9mZWXeFBQUhAAAAFcAAABRAAAAQwAAADMAAAAlAAAAGAAA + AA8AAAAIAAAAAwAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAEAAAAFAAAACQAAAAYTFBQ1Y2JiwaScnP+1qqr/sKSk/8O6uv/i3Nr/xby5/4B0hf9gWIf/bGqw/4KC + z/+Ki93/kJHh/5CR4f+QkeP/jY/k/4aI3f96ecj/YVub/2FVdv+Wio7/1c7J/9vW1f/AuLj/wLe3/8C4 + uP+Nior5Li4uqAAAAF4AAABUAAAASAAAADgAAAAoAAAAGgAAAA8AAAAIAAAAAwAAAAEAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAABQAAAAkAAAAGHyAgVXp3d+ewpqb/s6io/7Wq + qv/a1dP/1s/K/4h8iP9dVYn/dHO+/4qL2/+Oj97/jIzc/4yM2/+MjNz/jIzc/4uM3f+Ljd//jI3g/42O + 5P+PkOj/hYXb/2Zhpf9dUHH/opWV/+Ld2v/Qysr/vrW1/8a9vf+ooqL/SEhIxwICAmkAAABWAAAASwAA + ADsAAAAqAAAAHAAAABAAAAAIAAAAAwAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAA + AAUAAAAHAAAACTc4OHSOiYn4tqur/7Glpf/BuLj/5eDd/7KoqP9hV37/ZGOv/3x+1P+Agtb/f4DU/4CA + 1f+Bgdf/goLZ/4WF2v+Ghtv/h4jd/4mJ3v+KiuD/i4vh/4uL4f+NjeP/kJHo/4KE2f9dVpH/cGJ0/8zD + v//f29r/wrm5/8e9vf+4sbH/YF9f2gsLC3cAAABWAAAATgAAADwAAAArAAAAHAAAABAAAAAIAAAAAwAA + AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAEAAAABgAAAAxBQUGJmZOT/7arq/+wpKT/zcbG/+Pe + 2P+Kfoz/U02O/2hpxf9zdNH/cXLO/3Fyz/9zdND/dHTS/3Z11P93d9X/eHjX/3t72P99fdv/f3/c/4CA + 3f+Dg+D/hobg/4iH4P+JieH/jI7l/46Q6P9wb7z/V0tw/6mdnP/n4t//ycHB/8a9vf/Curr/cW9v5g4O + Dn8AAABYAAAATwAAAD0AAAAsAAAAHAAAABAAAAAIAAAABAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAABQAA + AAUAAAAMR0ZGmp+YmP+3q6v/saam/9jS0f/X0Mv/bmOB/05MoP9jZcn/ZWbJ/2RlyP9lZsr/ZmfL/2do + zv9pac//amrR/2tr0v9ubtX/cHDX/3Jy2P90dNn/dXXb/3h43f97e93/fX3e/4CB3/+Dg+D/hofi/42O + 6f+Cg9n/Vk2C/4t+hP/k4Nz/0MrK/8W8vP/Gvr7/fXt77xISEoYAAABYAAAAUAAAAD4AAAArAAAAGwAA + AA8AAAAIAAAAAwAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAQAAAAFAAAAC0hHR5qmnp7/t6ur/7Opqf/g29n/y8K+/1xT + fv9JSaz/WlvE/1hZwv9YWcP/WFnF/1pbxv9bXMn/W1zK/11czP9eXs7/YGDQ/2Fh0f9kZNT/ZWXV/2ho + 1/9qatn/bW3Z/29v2v9yctz/dXXd/3h43f97fN//f4Dg/4WH5f+GiOT/W1aX/3dodP/e2dT/1tDQ/8a9 + vv/Mw8P/gX5+7xESEoYAAABYAAAATwAAADwAAAArAAAAGgAAAA8AAAAHAAAAAwAAAAEAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAABQAA + AAtISEiZpp6e/7esrP+zqar/497b/8K5tf9PR3//QUOv/01Pvv9MTbz/S02+/0xNv/9NTsL/Tk/E/09Q + xv9QUMf/UVHJ/1NTy/9UVM3/V1bQ/1lZ0f9aWtP/XFzV/19f1v9hYdf/ZGTY/2dn2f9qatn/bW7b/3Bx + 3P9zdd3/d3nf/3x+4v+Chuj/Xlyn/2tcbP/b1M//2tTU/8i/v//NxcX/gX9/7xISEoYAAABYAAAATgAA + ADsAAAApAAAAGQAAAA0AAAAGAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAABAAAAAwAAAAUAAAAFQ0NDj6Sdnf+4rKz/tKqq/+Pf3P++trb/RD2A/zo7 + rf9BQ7f/QUK2/0FBuP9AQbv/QUG8/0JDvv9DQ8D/REPC/0VExf9GRsf/R0fJ/0lJy/9KSsz/TU3P/05O + 0f9RUdP/U1PT/1ZW1P9ZWNX/W1vW/15f2P9hY9j/ZWba/2lq2/9sbt3/cHLe/3V34f99gej/XVyu/2BR + av/UzMf/29bW/8nBwf/Oxsb/e3l57QwMDH0AAABYAAAATQAAADkAAAAmAAAAFwAAAAwAAAAFAAAAAgAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAFAAAAAkA/ + P3ufmJj/uK2t/7Sqqv/k393/wbm4/0A7gv8tMKr/Njey/zU2sf81NrL/NTW1/zU1tv82Nrn/Nja7/zg4 + vf84OL//OjrB/zs7xP88PMb/PT7J/0A/yv9CQsz/Q0PP/0VF0P9ISND/S0rR/01N0/9RUdT/VFXV/1ZY + 1v9aXNj/XWDZ/2Fk2/9maN3/aWzd/25y4P91euj/XF20/19Qaf/Vzsj/29fX/8vDw//LxMT/cnBw5QkK + CnYAAABXAAAASgAAADYAAAAkAAAAFQAAAAsAAAAEAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAEAAAACAAAABQAAAAA2NjZjl5KS/biurv+0qqr/49/c/8W9uv88NoD/IyWk/ysr + q/8qKqv/Kiqt/ykqsP8pKrL/Kiq0/yortf8rK7j/LCy6/y0tvf8uLr7/MDDB/zAxw/8xMsX/NDPI/zU1 + y/84OMz/OjrN/z09zv8/QM//QkLQ/0VF0f9IStL/S07U/05R1f9SVdf/V1na/1te2/9fYtz/Y2fe/2ds + 4f9wduj/VVey/19Raf/e2NH/29bW/87Hx//Jw8P/YmBg2gMEBG0AAABWAAAARwAAADIAAAAhAAAAEwAA + AAkAAAAEAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAUAAAAAIiIiSY2J + ifG5r6//s6mp/97Z1//QyMX/Qjt8/xcZnP8fIKX/HyCl/x4fqP8eH6r/Hh+s/x4frf8eH7D/Hh+y/x8h + tP8gIbf/IiG5/yMjvP8jJL7/JCXB/ycnwv8pKcX/KirJ/ywsyf8vL8n/MTLL/zQ1zP83OM3/OzvO/z0/ + 0P9AQ9L/REfU/0hL1f9LT9b/T1TZ/1RZ2/9YXt3/XGPf/2Fo4v9ocOn/T1Cq/2pbbP/h3Nf/2tTU/9HK + yv/Dvr7/Tk5OyAAAAGMAAABUAAAAQwAAAC8AAAAeAAAAEAAAAAcAAAADAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAEAAAADAAAAABQVFSt8eXniua+v/7Opqf/Y0tH/3NXP/0lCf/8MDpX/FBWf/xMU + n/8TFKH/ExSk/xMUpv8SE6f/EhOq/xITrP8SE6//FBSx/xQUtP8VFbb/Fxe5/xcYu/8YGb7/GxvB/x0c + w/8eHsX/ISHG/yMjx/8mJ8j/KSrJ/ywty/8vMMz/MjTO/zY40P85PNH/PEHU/0BG1v9FStj/Sk/Z/05U + 3P9TWd7/Vl7g/1xk5P9jbev/SEih/3Zncv/n49//1tHR/9XOzv+4tLT/OTk5tAAAAF0AAABSAAAAPwAA + ACsAAAAaAAAADgAAAAYAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAELCwsSamhoxras + rP+1qqr/z8jH/+nj3P9cU4T/BQeM/wsNmv8MDZr/DA2d/wwNn/8MDaH/DA2j/wsMpf8LDKj/Cwyr/wsM + rf8LC6//Cwuy/wwMtP8MDbf/DA25/w0Ou/8PD77/ERHA/xMTw/8VFcP/FxjE/xobxv8dHsf/ISLI/yQm + yv8nKcz/Ky3N/y8z0P8yN9L/NjvU/zpA1v8/Rdn/REvb/0hQ3f9NVeD/UVvi/1hh5v9daOn/QT+S/4h5 + fv/s6eX/083N/9jR0f+ppaX/IyMjnAAAAFgAAABPAAAAOgAAACcAAAAXAAAACwAAAAUAAAABAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAIAAAADAAAAA0tKSpuupaX/uK2t/8S8vP/w7OT/d26P/wgJh/8LDZf/DQ+Z/w0O + m/8NDp3/DQ6g/w0Oov8NDqT/DA2n/wwNqf8MDar/DA2t/wwNr/8MDLL/Cwu1/wsLtv8KC7n/Cgu7/woK + vf8KCr//CgrA/wsLwP8MDcH/DxDD/xITxP8WF8X/GBvI/xwfyv8gIsv/JCjO/ygt0P8rMdL/LzfU/zQ8 + 1/85Qdr/PUfc/0JN3v9HUuH/TVjj/1Nf6v9UYeb/Pjl//6GTkf/v6+r/08zM/9rT0/+MiorzDxAQgwAA + AFcAAABKAAAANQAAACIAAAATAAAACQAAAAMAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAABAAAAAA8PT1uoZub/7uw + sP+9s7P/8u3o/5iQof8QEIL/CQyV/w0Pl/8ND5n/DQ6c/w0Onv8OD6H/Dg+j/w0Opf8NDqj/DQ6p/wwN + rP8MDa7/DA2x/wwMs/8MDLX/DAy3/wsMuv8LC73/Cwu//wsLwf8LC8H/CgrB/woLwf8KC8H/CwzD/wwN + w/8NEMX/EBTH/xUZyv8ZHcv/HSLO/yEo0f8kLdP/KTLW/y442P8zPtv/OUPe/z1K4f9CUOP/SFXm/09e + 7f9MWd3/Qjhv/7uxrf/q5+b/1M3N/9XQ0P9tbGzgAwQEbQAAAFQAAABEAAAALwAAAB0AAAAPAAAABwAA + AAIAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAMAAAAAISIiO46JifC9srL/t66u/+rm4v+6srf/IB1//wgKk/8OEJb/DhCY/w4Q + mv8OD5z/Dg+e/w4PoP8OD6P/Dg+m/w0OqP8NDqv/DQ6t/w0OsP8NDbH/DQ2z/w0Ntv8MDbj/Cw27/wwM + vf8MDMD/CwvB/wsLwf8LDML/CwzC/wsNwv8MDcL/Cw3D/wsOxf8LD8b/DBHI/w4Uyf8SGMz/Fh3P/xsi + 0f8fKdX/Iy/Y/yg02/8uO93/NEHh/zhH5P89Tub/RFTp/0te8/9CTs//T0Fm/9bOx//k4OD/2NLS/8nF + xf9HR0fCAAAAXwAAAFIAAAA/AAAAKgAAABkAAAAMAAAABQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAA8QEBRwbm7Mua+v/7es + rf/b1tX/29TQ/zs2gP8GCI//DxCU/w4Qlv8OEJj/DxCb/w8Qnf8PEJ//DxCi/w8QpP8OD6b/Dg+p/w4P + q/8OD63/Dg+w/w4Osf8NDbT/DQ22/wwNuf8MDbv/DAy9/wwMwP8MDMH/DAzB/wwNwv8MDcL/DA3C/wwN + w/8MD8T/DBDF/w0Rx/8NEcj/DBLK/w0Uy/8NFc7/ERnR/xUf0/8aJtf/Hiva/yQy3f8pOOD/Lz/j/zRG + 5/85TOn/QFPt/0dd9v84QLP/aFhr/+jj3v/d2Nj/3dfX/7Ovr/8nJyefAAAAVwAAAE4AAAA4AAAAJAAA + ABUAAAAKAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAMpKSkATExMlbCnp/+6sLD/y8XE/+/r4/9iW4z/BwmK/w8Qkv8PEZP/DxGW/w8R + mf8PEZv/DxCe/w8QoP8PEKP/DxCk/w4Ppv8OD6n/Dg+r/w4Prf8OD7D/Dg6z/w4Otf8ODrf/DQ65/w0N + u/8MDL7/DQ3A/w0Nwf8MDMH/DAzC/wwNw/8NDsP/DQ7E/w0Pxf8NEMb/DRHI/w0Syf8NFMr/DhXN/w4W + zv8OF9H/DhnT/xAd1v8UItn/GSnc/x4v4P8lN+P/Kz7m/zBF6v82S+7/PFPy/0FZ9/8yNJP/i3yA//Dt + 6v/a1NT/4NnZ/4yKivINDQ1+AAAAVgAAAEcAAAAxAAAAHwAAABEAAAAHAAAAAgAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAACkpKVGclpb/vbOz/761 + tf/08ev/koui/w4PhP8ND5D/EBGR/w8RlP8PEpf/EBKZ/xARm/8QEJ3/DxCg/w8Qo/8PEKX/Dg+n/w4P + qv8OD6v/Dg+u/w8PsP8PD7P/Dw+1/w4PuP8NDrr/DQ27/w0Nvv8NDcH/DQ3B/w0Nwf8NDcL/DA3C/w0P + xP8ND8T/DRDG/w0Rx/8OEsj/DhPJ/w4Vyv8OFs3/DxbQ/w8Z0f8PGtT/DxvW/w8e2P8RIdz/FSff/xou + 4/8gNef/Jz3q/y1E7v8yS/H/OVX5/zpS7/83MHT/t6um/+7r6v/b1dX/2NPT/19fX9UAAABkAAAAUwAA + AEAAAAArAAAAGQAAAA0AAAAFAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAgAAAAATExMeenh42b60tP+5r6//6OTh/8W+wv8jIYH/Cg2N/xETkP8REpP/EBKV/xAS + mP8QEpn/EBKb/xARnv8QEaD/EBGj/xARpf8PEKf/DxCq/w8QrP8PEK7/DxCx/w8Ps/8PD7b/Dw+4/w4P + uv8OD73/Dg6//w0Nwf8ODsH/Dg7B/w0Owv8NDsL/Dg/E/w4QxP8OEcb/DhLH/w4TyP8OFMn/DxXM/w8W + zv8QF8//EBnS/xAb1f8QHtf/ESDZ/xEh3P8RI9//Eifj/xct5v8cNOr/Izzu/ylE8v8wTPX/N1b//zBD + 1P9OQGb/29PM/+bj4//h29v/wL29/zExMasAAABZAAAATgAAADgAAAAkAAAAFAAAAAkAAAADAAAAAQAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAACKisrAFBPT5y1rq7/u7Cw/9PO + zf/q5d//S0WI/wcJif8RE47/EROQ/xESkv8RE5X/EROY/xETmv8QEZz/ERGf/xESoP8REqP/ERKl/xAR + qP8QEar/EBGs/xARr/8QELH/Dw+z/xAPtf8QELj/DxC7/w4Pvf8ODr//Dg7B/w4Owf8ODsH/Dg/C/w4P + wv8PD8T/DxDE/w4Rxv8OEsf/DxPJ/w8Vy/8PFsz/EBbN/w8Y0P8QGtL/ER3V/xEf2P8RINr/EiPc/xIl + 4P8SJ+P/Eyrn/xQt6/8YNO7/Hzzy/yZE9/8tS/r/MlL//ycxq/91ZXH/7+vn/9/b2//k39//lpOT9Q4O + DoEAAABVAAAARwAAADEAAAAeAAAAEAAAAAcAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAwAAAAAqKytRoJqa/7+1tf/Cubn/9/Tu/4N8nv8JC4X/EBKN/xIUjv8SFJH/EhOS/xET + lf8RE5j/EROa/xESnf8REp//ERKh/xESo/8REqX/EBGo/xARqv8QEaz/EBGv/xARsf8QELP/EBC1/xAQ + uP8PELv/DxC9/w8PwP8PD8L/Dg7C/w8Pwv8PD8L/Dg/C/w8QxP8PEcT/DxLG/w8Tx/8QFMn/DxXL/w8W + zP8QF83/EBnQ/xEb0v8RHNX/ER7Y/xIh2/8SJN3/EyXg/xMo4/8UK+f/FC7r/xQw7/8XNPP/HDz3/yND + +f8pSfz/LEn2/yspgv+qnZr/8vDv/9/a2v/d2Nj/YWBg1wAAAGMAAABSAAAAPwAAACkAAAAYAAAADAAA + AAQAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAEBERFnh1ddS/tbX/u7Gx/+vo + 5f/Cu8L/HRuE/w0Pjf8SFIz/EhSO/xIUkP8TFJP/EhSW/xETmP8RE5r/EhOd/xITn/8SE6L/EhOk/xIT + pv8REqj/ERKq/xESrP8REq//ERKy/xERtP8QELb/EBC4/xARuv8QEL3/EA/A/w8Pwv8PD8L/Dw/D/w8Q + w/8PEMP/DxHD/xASxP8PEsb/DxPH/xAUyf8QFsr/ERfN/xEYzv8QGc//ERzS/xIe1f8SINj/EiHb/xIk + 3f8UJuD/FCnj/xQr5/8VLuv/FTHv/xYz8v8WNvb/GTv4/x9A+f8mSP//Ijrd/0I2Z//Y0Mj/6+jo/+Xg + 4P/Cvr7/LS0tpQAAAFgAAABMAAAANgAAACIAAAATAAAACAAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAiIjIwBKSUmKs6ur/72zs//Uzs7/7Ojj/0pFi/8IC43/EhWN/xIUjP8TFY7/ExWR/xMU + lP8SFJb/EhSY/xIUmv8SE53/EhOf/xITof8TFKT/ExSm/xITqP8SE6v/EhOs/xESr/8RErL/ERG0/xER + tv8REbj/EBG6/xARvf8QEL//EBDC/xAQwv8QEML/EBHD/w8Qw/8PEcP/EBLE/xATxv8QFMf/ERXJ/xAV + yv8QF83/ERjP/xIZ0P8SHNL/Eh7V/xIg1/8TIdv/EyTd/xQn4P8UKeP/FSvn/xUu6v8WMO7/FjPy/xY2 + 9f8XOPj/Fzn4/xw++f8iRf//HCeu/3Zmcv/w7un/49/g/+jk5P+OjIzxCQoKeQAAAFQAAABEAAAALgAA + ABsAAAANAAAABgAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAIiMjOZWRkffCuLj/wbm5//bz + 7f+Oh6T/DQ6J/xEUkf8TFY3/ExWM/xMVjv8UFpH/ExSU/xIUlv8TFZn/ExWb/xMVnf8TFJ//ExSh/xMU + o/8TFKb/EhOp/xITq/8SE63/EhOu/xITsf8SErT/EhK2/xESuP8QEbv/ERG9/xERv/8QEML/EBDC/xAQ + wv8QEcP/EBHE/xESxP8RE8X/EBPG/xAUx/8RFcj/ERbL/xIXzf8SGM//ERnQ/xIc0f8THtT/EyDX/xMh + 2v8TJN3/FCfg/xUo4/8VK+b/Fi3p/xYv7f8WM/H/Fjb0/xc4+P8XOPj/Fzj4/xo8+/8cO/T/JyR9/7Kl + n//z8fD/5eDg/9vX1/9PTk7FAAAAXQAAAFAAAAA7AAAAJgAAABQAAAAJAAAAAwAAAAEAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAABAAAAAQMDAwVmZma5vbS0/72zs//l4d//z8jK/yYkh/8ND5P/FBaR/xQWjv8UFo3/FBaP/xQW + kf8UFZP/ExWW/xMVmP8TFZv/FBWd/xQVn/8UFaL/FBWj/xQVpv8TFKn/ExSr/xMUrf8TFK//ExSx/xMT + s/8SErb/EhK5/xESu/8REr3/ERG//xERwf8REcL/EBDC/xERw/8REsT/EBLE/xESxf8RFMf/ERXH/xIV + yP8SF8r/ERfL/xIYzv8SGtD/ExzR/xMd1P8TINf/FCLZ/xQj3P8UJt//FSji/xUq5P8WLOj/Fi/r/xYx + 7/8WNPL/Fzf1/xc5+P8XOfj/Fzj4/xg8//8TKtP/TT9n/+Lb1P/r6Oj/7Ofn/7Gvr/8ZGRmQAAAAVQAA + AEgAAAAxAAAAHgAAAA8AAAAGAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAOTk5XqagoP/BuLj/zcbG//Pv + 6P9gWpP/CAuR/xMVlP8UFpH/FBaO/xQWjf8VF4//FBaR/xQVlP8UFpb/FBaY/xQWm/8UFp3/FBWg/xQV + ov8UFaP/FBWm/xMUqP8TFKv/ExSt/xMUr/8TFLL/ExOz/xMTtv8TE7j/EhO7/xESvf8REb//EhLB/xIS + wv8REcL/ERLD/xESw/8REsT/EhPF/xIUxv8RFMf/ERbI/xIXyf8SF8z/ExnO/xIaz/8TG9L/Ex7U/xQg + 1v8UItj/FCTb/xQl3v8VKOH/FSrj/xYs5v8WLur/FjDt/xYy8P8XNfP/Fzf1/xc5+P8XOfj/Fzj5/xU4 + /v8UHZ3/i3yA//b08f/n4+P/6OTk/29ubtwAAABnAAAAUgAAAD8AAAApAAAAFwAAAAoAAAAEAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAABAAAAABISEhR+e3vTw7q6/7+3t//w7Oj/q6S1/xUViv8QEpj/FRaU/xUXkf8VF4//FReM/xUX + j/8VF5H/FRaU/xQWlv8UF5j/FReb/xUWnP8VFZ//FBWi/xQVo/8UFab/FBWo/xMUqv8TFK3/ExSv/xMU + sv8UFLT/FBS1/xQUuP8SE7r/EhO9/xISv/8SEsH/EhLC/xISwv8SE8L/EhPD/xESxP8SFMX/EhTG/xIV + x/8SFsj/EhfK/xIXy/8TGcz/ExrO/xMc0f8THdT/FB/U/xQi1/8UI9r/FSXd/xUo4P8WKeL/Firl/xYt + 6P8WL+r/FjHt/xYz8P8WNPP/Fjb0/xc39f8XN/b/Fjj6/w8s5/8wKGz/zMO7//Lw8P/s6Oj/ycbG/ywr + K6QAAABXAAAASwAAADQAAAAfAAAAEAAAAAcAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEUFRUARkZGe7Krq//BuLj/19HQ/+bh + 3P9DP43/Cw6Y/xQWmP8VFpX/FRaS/xUXj/8WGI3/FReP/xUXkf8WF5T/FheW/xUXmP8VF5v/FRec/xUW + n/8VFqH/FRaj/xUWpv8VFqj/FBWq/xQVrf8UFa//FBWx/xQUtP8UFLb/FBS3/xQUuv8TFLz/EhK//xIS + wf8TE8L/EhLC/xISwv8SE8P/EhPD/xMUxP8TFMb/EhXH/xIWyP8TF8r/ExfL/xMYzP8TGs//FBzR/xQd + 0/8UH9T/FCDW/xUj2f8VJdv/FSfe/xYp4f8WKeP/Fivm/xYu6P8WL+r/FjDt/xYy7/8WM/H/FjTy/xY0 + 8/8WNPP/FTT5/wwatf9sXXD/8e7p/+vn6P/u6ur/iYiI6wQEBHEAAABTAAAAQAAAACsAAAAYAAAACwAA + AAQAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAABAAAAABQVFR+Jhobmxby8/8S8vP/z8Or/kImm/w4Pkf8TFZz/FReY/xUXlf8WF5P/FhiP/xYY + jv8WGI//FhiR/xYXk/8WF5X/FhiY/xYYm/8VF5z/Fhef/xYXof8WF6P/Fhel/xYXqP8VFqv/FRat/xUW + r/8VFrD/FBSz/xQUtv8VFbj/FBW5/xMUvP8TE77/ExPB/xMTw/8TE8P/ExPD/xMUxP8SFMT/EhTE/xMV + xv8TFcb/ExfI/xMXyf8TGMv/ExnM/xQazf8UG8//FB3S/xQf1P8VINb/FSLX/xUj2v8VJtz/Fijf/xYo + 4v8WKeP/Fivl/xYt6P8WLur/FjDs/xYx7f8WMe7/FjHv/xYw7/8WMfH/ECvs/x8dff+3qqX/9/b1/+3p + 6f/Z1dX/PDw8tQAAAFkAAABMAAAANgAAACEAAAARAAAABwAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEWFhYATUxMjLqxsf/CuLj/39rZ/9fR + z/8wLo3/Dg+e/xUXnP8VF5n/FReW/xYXk/8XGJD/FxmO/xcZjv8XGZH/FxiU/xcYlv8WGJf/Fhia/xYY + nf8WF5//Fheh/xYXo/8WF6X/Fhen/xUWqv8VFq3/FRau/xUWsP8VFrL/FRW1/xUVuP8VFbr/FBW7/xQV + vf8UE8D/FBTC/xQUw/8TE8P/ExTE/xMUxP8TFMT/FBXF/xQWxv8TFsf/FBjJ/xQYyv8UGMz/FBnM/xQb + zv8UHdD/FR7T/xUf1f8VIdf/FSLY/xUk2v8WJt3/Fifg/xYo4v8WKeP/Fivl/xYs5v8WLef/Fi7q/xYu + 6v8WLuv/Fi7r/xUu6v8UL/D/CxvC/1dJav/s5uD/8O3t//Lv7/+ZmJjyCgoKeAAAAFMAAABCAAAAKwAA + ABkAAAALAAAABAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAABAAAAABYWFimQjIzxyL6+/8nBwf/08Or/fnig/wwOl/8VFqD/FRec/xYYmv8WGJf/FxiU/xcZ + kf8XGY7/FxmO/xcZkf8YGZT/GBmV/xYYmP8WGJr/Fxmc/xcYnv8XGKD/Fxij/xcYpv8XGKj/Fhep/xYX + rP8WF67/Fhew/xYXsv8VFbT/FRW3/xYWuv8VFrv/FBW8/xQUv/8UFML/FBTD/xQUw/8UFMT/FBXE/xMV + xP8UFcT/FBbG/xQWxv8UF8j/FBjJ/xQYy/8UGcz/FBvN/xQcz/8VHdH/FR/U/xUg1f8VItf/FSPY/xYk + 2v8WJ93/Fiff/xYo4f8WKeL/Firk/xYr5f8WK+b/Fizn/xYr5/8VK+f/FSvn/xQr5/8QJuj/GBmI/6ib + mP/5+Pb/7+zs/+He3v9GRka+AAAAWQAAAEwAAAA2AAAAIQAAABEAAAAHAAAAAgAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEWFhYATk1Nk7y1tf/Durr/49/d/8zF + yf8oJo//EBKj/xYXoP8WF53/Fhia/xYYl/8XGJX/GBmS/xgaj/8YGo7/GBqQ/xgakv8YGZX/FxmY/xcZ + mv8XGZz/Fxie/xcYof8YGaL/GBml/xgZp/8XGKn/Fxis/xcYrf8WF7D/Fhez/xYWtP8WFrX/Fha4/xYW + u/8VFr3/FRW//xUVwf8VFcP/FBTD/xQUw/8UFcT/FBXF/xQWxf8UFsX/FBbG/xQXx/8VGMj/FRnK/xQZ + zP8VGs3/FRzO/xUcz/8VHtL/FR/U/xUh1f8VItf/FSPY/xYl2v8WJtz/Fife/xYo4P8WKOH/Fini/xYp + 4/8WKuP/FSrj/xUq4/8UKeP/FCji/xQo5v8KGcf/Sj5r/+bg2P/z8fH/9fLy/56dnfcLCwt8AAAAUgAA + AEEAAAAqAAAAGAAAAAsAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAABYWFimRjY3xycDA/8vDw//x7eb/dG+d/wwOnP8WF6T/Fheh/xYYnv8XGZv/FxmY/xgZ + lf8YGpP/GBqP/xgajv8ZG5D/GRuT/xgZlf8YGZf/GBqZ/xgam/8YGp7/GBmg/xgZof8YGaT/GBmm/xgZ + qf8XGKv/Fxit/xcYr/8XGLH/Fxi0/xcXtv8WFrf/Fhe6/xUXvP8VFb7/FRW//xUVwv8VFcP/FRXD/xUV + xP8UFcT/FBXF/xUWxf8VF8f/FRjH/xQYx/8VGcn/FRnK/xUazP8VG87/FRzO/xUd0P8VHtL/FR/U/xYh + 1f8WItf/FSPY/xYk2f8WJdv/Fibd/xYn3v8WJ9//FSjg/xUo4P8VKOD/FSjh/xQm4P8TJuD/EyXf/w8i + 4v8UFYz/oJOU//z6+P/y7+//4+Dg/0ZGRr8AAABZAAAASwAAADUAAAAgAAAAEAAAAAcAAAABAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wAVFRUAFRUVABUVFQAVFRUAFRUVABUVFQAVFRUATk1Nkr22tv/FvLz/497c/8rD + xv8pKJP/EBKn/xcYpP8XGKH/Fxie/xcZm/8XGZn/GBmX/xkalP8ZG5H/GRuO/xkbkP8ZG5P/GRqV/xka + lv8YGpn/GRuc/xkanv8ZGZ//GRqi/xkapP8ZGqb/GBmp/xcYq/8YGa3/GBmu/xgZsf8XGLP/Fxe2/xcX + t/8XF7j/Fxe7/xYXvv8WFcD/FhbC/xYWw/8VFcP/FRXE/xUWxP8VFsT/FRbF/xUXxv8VGMf/FRjH/xUZ + yP8VGcr/FRnL/xUbzf8VG87/FRzO/xUd0P8WH9L/FSDU/xYh1f8WIdf/FSPX/xYk2f8WJNr/FSTb/xUl + 3P8VJtz/FSbe/xQm3v8UJt7/FCXe/xMj3f8SI9z/EiPf/wkWxv9KP27/5uHZ//b09P/49vb/n56e9wsL + C3sAAABRAAAAQAAAACkAAAAWAAAACgAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////ABUVFQAVFRUAFRUVABUV + FQAVFRUAFRUVABUVFSCRjY3rysHB/8zFxf/x7eb/dnGf/w0OoP8WF6n/Fxil/xcYov8XGJ//GBqd/xga + mv8YGpf/GRqV/xkbkv8ZG4//GhuP/xobkv8aG5T/GhuW/xkbmf8ZG5v/GRuc/xkbn/8ZGqL/GRqk/xka + pv8ZGqf/GBmq/xgZrf8YGa//GBmw/xgZsf8YGLT/GBi3/xgYuf8XGLv/Fhe8/xYWv/8WFsL/FhbD/xYW + w/8WFsP/FhbE/xUWxP8VF8X/FhfF/xYYx/8VGMf/FRnH/xUZyf8WGcr/FRrL/xUbzf8WHM7/FRzP/xUe + 0P8WH9H/FSDT/xUh1f8WIdb/FSHX/xUi1/8VI9n/FSPZ/xUk2f8VJNv/FCTa/xQj2v8UItr/EyLa/xMh + 2v8SINn/Dh3d/xUVjv+hlJX//fz6//Xy8v/k4uL/QEBAtwAAAFgAAABKAAAAMwAAAB0AAAAOAAAABQAA + AAEAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8AERISABESEgAREhIAERISABESEgAREhIASEhIfLu0tP/Gvr7/497d/83G + yP8rKZT/ERKr/xYYqP8XGab/GBmj/xgZoP8YGp7/GBqb/xgbmP8aG5b/GhuS/xobkP8aG4//GhuR/xob + lP8aG5b/GhyZ/xocm/8aHJ3/GRue/xkaof8ZGqP/GRql/xkaqP8ZGqn/GBmr/xgZrv8ZGrD/GRqx/xgZ + s/8YGLb/GBi5/xgYuv8XGLv/Fxe9/xcWwP8XF8L/FhbD/xYWw/8WFsP/FhfE/xYXxf8WF8X/FhjG/xYY + x/8WGcf/FRnI/xYZyf8WGsr/FRrL/xUbzf8WHM7/FRzP/xUe0P8WHtD/Fh/T/xUg1P8VINX/FSHW/xUh + 1v8VItf/FSLX/xQi1/8UIdj/EyDY/xMg2P8TINf/Eh/X/xIe1v8RHdn/CBK//01Bbf/o4tr/9/b2//r4 + +P+Uk5PvBAQEcQAAAFAAAAA8AAAAJQAAABQAAAAIAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAA////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wAREhIAERISABES + EgAREhIAERISABESEhCFgoLbysLC/8zExP/w6+X/gXuj/w4Qof8WF63/Fxmp/xgZpv8YGaT/GRmh/xka + nv8ZG5z/GRua/xobl/8aG5T/GxyR/xsckP8aG5H/GxyU/xsclf8bHJj/Ghya/xocnf8aHJ7/Ghug/xob + o/8aG6X/Ghuo/xobqf8ZGqr/GRqt/xkar/8ZGrL/GRqz/xkZtf8YGLf/GBi5/xgZu/8XGLz/Fxe+/xcX + wf8XF8P/FxfE/xcWw/8WFsP/FhfE/xYXxP8WF8X/FhjG/xYYx/8WGcj/FhnI/xYZyf8WGcr/FRrL/xUb + zf8WG87/Fh3O/xUdz/8VHtD/FR7R/xUf0v8VH9P/FR/U/xUf1f8UH9X/FCDV/xQg1f8UH9X/Ex/V/xIe + 1P8SHdT/EhzT/xEb0/8MF9b/GReH/6ygnf/+/Pv/+ff3/9vY2P8wMDCnAAAAUwAAAEUAAAAuAAAAGgAA + AAwAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AAIDAwACAwMAAgMDAAIDAwACAwMAMzMzW7Ourv/KwcH/3trZ/9fR + z/82NJb/EBKv/xcYrP8XGKr/GBqo/xkapf8ZGqL/GRqf/xkbnP8aHJr/GhyX/xsclf8bHJP/GxyQ/xsc + kf8bHJT/HB2W/xsdmP8aHJr/Gh2b/xsdnv8bHKD/Gxyi/xscpP8bHKX/Gxyo/xobq/8ZGqz/GRqu/xob + sf8aG7L/GRq0/xkZtv8ZGbj/GRm7/xgZvP8YGb7/GBe//xcXwv8XF8T/FxfE/xcXxP8XF8T/FhfE/xYY + xP8XGMX/FxjG/xYZx/8WGcj/FhnJ/xYZyf8WGcr/FhrL/xUbzP8WG87/FhzO/xYdz/8VHc//FR3P/xUd + 0f8VHdL/FR7S/xQe0/8UHtP/FB7T/xMe0/8THdP/ExzS/xIc0f8SGtH/EBrQ/xAZ1P8HDrT/XFBz//Ht + 5//59/f/+vj4/3x7e98AAABkAAAATQAAADcAAAAhAAAAEAAAAAcAAAACAAAAAAAAAAAAAAAAAAAAAP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAgMDAAID + AwACAwMAAgMDAAIDAwFvbW25ycLC/8vDw//u6+X/l5Cr/xMUov8WF7L/GBmt/xgZq/8YGqj/GRqm/xoa + o/8aG6D/Ghye/xocm/8aHJn/GxyW/xwdk/8cHZD/HB2Q/xwdkv8cHZX/HB2Y/xwdmf8bHZv/Gx2d/xsd + oP8bHKL/Gxyk/xscpv8bHKj/Gxyp/xobrP8aG63/Ghuv/xobsv8aG7T/Ghq2/xoat/8aGrn/GRq8/xgZ + vf8YGb7/GBjB/xgYw/8YGMT/FxfE/xcXxP8XGMX/FxjF/xYXxf8XGMX/FxnG/xcZx/8WGcj/FhrJ/xYa + yf8WGcn/FhrK/xUbzP8VG83/FhvN/xUczv8VHM//FRzP/xUcz/8UHND/FBzQ/xQc0P8THNH/ExzR/xMb + 0f8TG9H/ERrQ/xEZz/8RGM7/EBfO/woSzv8jHnz/vrSu//79/P/7+Pj/xcTE/x4eHpEAAABQAAAAPwAA + ACgAAAAVAAAACQAAAAMAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wAmJycAJicnACYnJwAmJycAJicnM6KenvrNxsb/2NPS/+Tf + 2f9OS5r/Dg+v/xgZsv8YGa//GBms/xkaqf8aG6f/Ghuk/xobof8aHJ//Gx2c/xsdmf8cHZf/HB2V/xwd + kv8cHZD/HR6R/x0elP8dHpb/HR6Z/xwem/8cHp3/HB6f/xwdoP8cHaP/HB2l/xwdp/8cHan/Gxyq/xsc + rf8bHK//Gxyx/xscs/8aG7X/Ghq2/xoauP8aGrn/GRq8/xkavv8ZGMD/GBjB/xgYw/8YGMT/GBjE/xcX + xf8XGMX/FxjF/xcYxf8XGMX/FxnG/xcZx/8WGcj/FhrJ/xYayf8WGcn/FhnK/xYay/8VGsz/FRvN/xUb + zf8VG83/FRvO/xQbzv8UG87/FBvO/xMbzv8TGs7/ExrO/xIZz/8SGM7/ERfO/xEWzf8QFsz/DhbQ/woN + pv96bn//+fby//bz8//v7e3/WFhYyAAAAFgAAABGAAAAMAAAABsAAAANAAAABQAAAAEAAAAAAAAAAAAA + AAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAME + BAADBAQAAwQEAAMEBABLS0uGwru7/8vDw//o5OH/tq+6/x4en/8VFrf/GBmy/xkasP8ZGq3/GRuq/xkb + qP8bHKX/Gxyi/xscoP8bHZ7/Gx2b/xwemP8dHpb/HR6U/x0ekP8dHpH/HR6U/x0elv8dHpf/HB6a/xwe + nf8cHp7/HB6f/xwdof8cHaT/HB2n/xwdqP8cHan/Gxyr/xscrv8bHLH/Gxyy/xscs/8bG7b/Gxu3/xsb + uf8aGrr/GRq9/xkav/8ZGMD/GRjB/xgYxP8YGMT/GBjE/xgYxf8XGMX/FxjF/xcYxf8XGMX/FxjG/xcZ + x/8XGcj/FhrI/xYayf8WGcn/FhnJ/xYZyv8WGcr/FRrL/xUazP8UGs3/FBrN/xQazf8UGcz/ExnM/xMY + zP8SGM3/EhjN/xIXy/8RF8z/EBbM/xAWy/8PFcz/CA7F/zgwdP/a08v/+fj3//n29v+enZ31BgYGcQAA + AEsAAAA3AAAAIQAAABAAAAAGAAAAAgAAAAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8AAwQEAAMEBAADBAQAAwQECIJ/f9HPx8f/0crK/+3o + 4f9xbKH/Dg+t/xgYt/8ZGbP/GRqx/xkarv8aG6v/Ghyp/xscpf8bHKT/HByi/xwdn/8cHpz/HB6a/x0e + l/8dHpX/HR6S/x0ekP8dHpP/HR6V/x0el/8dHpn/HB6b/xwenf8cHp//HB2i/xwdo/8cHaX/HB2n/x0e + qf8cHar/Gxyt/xscr/8bHLD/Gxyy/xsctf8bG7f/Gxu5/xsbuv8aG7v/GRu9/xkav/8ZGcD/GRnC/xkZ + xP8YGMT/GBjE/xgYxf8YGMX/FxjF/xcYxf8XGMX/FxjF/xcZx/8XGcf/FhnI/xYZyP8WGcj/FhnI/xYZ + yf8VGcr/FRnK/xUZyv8UGMv/FBjL/xMYy/8TGMv/ExjL/xIXyv8SF8r/ERfK/xEWyf8RFsn/EBTJ/xAU + yf8MEcz/EhGQ/6CVlv/8+/n/9fLy/9bU1P8rKyufAAAATQAAAD8AAAAnAAAAFQAAAAkAAAADAAAAAAAA + AAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wAqKioAKioqACoqKgAqKio+q6am/c/Hx//f2tj/19DO/zg2nf8QErn/GRm3/xkZtP8aG7L/Ghuv/xob + rP8aHKr/Gx2n/xwdpf8cHaL/HB6f/xwenv8cHpv/HR6Y/x0elv8dHpP/Hh6R/x4fkv8eH5T/Hh+W/x4e + mf8eHpv/HR6c/x0en/8dHqH/HR6j/x0epf8eH6f/Hh+o/x0eqv8cHaz/HB2t/xwdsP8bHLL/Gxyz/xsc + tP8bG7b/Gxu5/xsbuv8bG7v/Ghu+/xoav/8ZGcD/GRnC/xkZxP8ZGcT/GBjE/xgYxf8YGMX/FxjF/xcY + xf8XGMX/FxjF/xcZxv8XGcf/FhnH/xYZyP8WGcj/FRnI/xUZyP8VGcn/FRnJ/xUZyf8UGMn/FBjK/xMX + yv8TF8r/ExfJ/xIXyP8SFsj/ERXI/xEVyP8QFMj/DxPH/w4Syv8HCrH/X1V5//Hu5//z8fH/8O3t/2Vl + Zc8AAABZAAAARQAAAC4AAAAZAAAACwAAAAQAAAABAAAAAAAAAAD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AAMDAwADAwMAAwMDAE5OToXHwMD/zsbG/+zo + 5P+moLT/GBim/xYXvf8ZGbj/Ghq1/xobs/8aG7D/Gxyt/xscq/8cHan/HB2m/xwdpP8cHqH/HB6e/xwe + nP8dHpr/Hh6X/x4flP8eH5H/HyCR/x8glP8fIJb/Hx+Y/x8fm/8fIJz/HyCd/x8gn/8fIKL/HyCl/x8g + pv8eH6f/Hh+q/x4frP8dHq3/HB2u/xwdsf8cHbP/HB20/xwctf8bG7f/Gxu5/xsbuv8aG7z/Ghu+/xoa + v/8aGcH/GRnC/xkZxP8ZGcT/GRnE/xgYxP8YGMX/GBjF/xcYxf8XGMX/FxjF/xcYxf8XGMb/FxjH/xYY + x/8WGMf/FRjH/xUYx/8UGMj/FBjI/xQYyP8TF8j/ExfI/xMXyP8SFsj/EhbI/xEVx/8QFcf/EBPG/xAT + xv8PEsb/DxHG/wgLxP8sJnn/z8fB//f19f/28vL/oqCg9QYGBnAAAABKAAAANQAAAB8AAAAPAAAABQAA + AAEAAAAAAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8AAwMDAAMDAwADAwMFfnx8y9DJyf/Uzc3/7Off/21oov8OELP/GRq8/xkauP8aGrf/Gxu0/xsc + sf8bHK//Gxys/xsdqv8cHaf/HB2l/x0eo/8dHqD/HR6d/x0fm/8fH5j/HyCW/yAhlP8gIZL/ICGT/yEi + lf8hIZj/ISGa/yAhm/8gIZ7/ICGg/yAhov8gIaT/ICGl/yAhp/8fIKr/HyCq/x4frP8eH67/Hh+v/x0e + sf8dHrP/HR61/xwctv8cHLf/HBu5/xwbu/8aG7z/Ghu+/xobv/8aGsH/GhnC/xkZw/8ZGcT/GRnE/xgY + xP8YGMX/GBjF/xcYxf8XGMX/FxjF/xcYxf8XGMX/FhjG/xYYx/8WGMf/FRfH/xUXx/8UF8f/FBfH/xQX + x/8TFsf/ExbH/xIVx/8SFcf/ERTH/xEUxv8RE8b/EBLF/xASxf8PEMT/DQ7I/xAPk/+flJf/+vj2//Lv + 7//Ny8v/KSkpmgAAAEsAAAA7AAAAIwAAABIAAAAHAAAAAgAAAAAAAAAA////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wAkJSUAJCUlACQlJSein5/208zM/97Z + 2P/Y08//Pz2f/xESvf8ZGr3/GRq6/xobt/8bHLX/Gxyy/xscsP8bHK7/Gx2r/x0eqP8dHqb/Hh+j/x4f + ov8fIJ//HyCd/yAgm/8hIZj/ISKW/yIik/8iI5P/IiSV/yIkmP8iIpr/ISKc/yEinf8iI5//ISKh/yEi + ov8hIqX/ISKn/yEiqP8hIqr/ICKs/x8grf8fIK7/HyCw/x4fsv8eH7P/HR61/x0ct/8cHLj/HBy5/xwc + u/8aG73/Ghu+/xobwP8aGsH/GhrC/xkZw/8ZGcT/GRnE/xkYxP8YGMX/GBjF/xcYxf8XGMX/FxjF/xYX + xf8WF8X/FhfG/xYXxv8WF8b/FRfG/xUWxv8VFsb/FBbF/xQWxf8TFcX/ExXF/xIUxv8SFMb/EhLF/xES + xf8QEsT/EBHD/w8Qw/8ND8b/CAms/2lefv/y8On/8O3t/+nl5f9RUFC/AAAAUQAAAEAAAAAoAAAAFQAA + AAkAAAADAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////ADY2NgA2NjYANjY2Zb65uf/Rycn/6OPh/7mzu/8mJqn/GRnD/xkavv8aG7v/Ghu5/xsb + tv8bHLP/Gxyx/xwdrv8cHqz/HB+q/x8fp/8fIKX/ICGj/yAhof8gIZ//ISKc/yIimv8iJJn/IyWW/yMk + lP8kJZX/JCaY/yQlmf8kJZv/JCWd/yQln/8kJaH/JCWi/yMjpP8jJKb/IySn/yIjqf8jI6z/ISKs/yAh + rv8gIbD/ICGx/x8gs/8fILT/Hh+1/x0et/8cHLj/HBy5/xwcu/8bHL3/Ghu+/xoav/8aGsH/GhrC/xoa + w/8ZGcT/GRnE/xkZxP8YGMT/GBjF/xgYxf8XGMX/FxjF/xYXxP8WF8T/FhfF/xUWxf8VFsX/FRbF/xQW + xv8UFcT/FBXE/xMUxP8SFMT/EhTF/xITxf8RE8T/EBLE/xARxP8PEMP/DxDD/w4PxP8HCb7/PTR4/+Da + 0v/y8PD/7+zs/4aFheYAAABgAAAARAAAAC4AAAAZAAAACwAAAAQAAAAAAAAAAP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAAEBAAABAQBlZGSbzcbG/9PN + zf/t6eL/jIas/x8ft/8jI8b/Hh/A/xkavP8aG7n/Gxu3/xwctf8cHbP/HR6w/x0erv8eH6v/HyGp/yAh + p/8gIqX/ISKj/yIjoP8iI53/IySc/yQkmv8kJpf/JSeV/yUnlf8mKJf/Jiia/yYnnP8mJ53/Jief/yYn + oP8mJ6P/Jiek/yYmpv8lJaf/JSSo/yQkqv8kJKz/IyOt/yEir/8hIrD/ICGy/yAhs/8gILX/Hx+1/x4e + t/8dHbj/HRy6/xwcu/8cHLz/Ghy9/xobvv8aGsD/GhrC/xoaw/8ZGcP/GRnE/xkZxP8YGMT/GBjE/xgX + xP8XF8X/FxfF/xYXxP8WF8T/FRfE/xUWxP8VFsX/FBXF/xQVxf8TFMT/ExTE/xIUxP8SE8P/EhPE/xES + xP8REsP/EBHD/xARw/8PEMP/Dw/D/woLxP8fGof/u7Kv//b08//x7e3/raur+xESEnoAAABHAAAAMwAA + AB0AAAAOAAAABQAAAAEAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wAAAQEAAAEBB4KAgM/Uzc3/2dTT/+fi2/9jX6P/HBzB/ycnx/8mJsP/ISK//xoc + u/8aG7j/HB22/x0ftP8eH7H/Hh+v/yAhrf8gIqv/IiOp/yMjp/8kJKX/JCWi/yUmof8mJ5//Jied/yYn + m/8oKpj/KCqW/ygql/8pKpr/KSqc/ykqnf8pKp//KSqg/ykqo/8pKqT/KCim/ygop/8oKKn/Jyeq/ycm + rP8mJq3/JCWu/yIkr/8iI7H/ISKy/yAitP8gIbT/HyC2/x8et/8eHrj/HR25/x0cu/8cHLz/Gxy9/xob + vv8aGr//GhrB/xoZwf8ZGcP/GRnE/xkZxP8YGMT/GBjE/xgXxP8XF8T/FxfE/xYWw/8WFsP/FhbE/xUW + xP8VFcT/FBXE/xQVxP8TFMT/ExTE/xITw/8SE8P/EhLD/xERwv8REcL/EBDC/xAPwv8PD8L/DQ3G/woJ + m/+TiJL/+Pbz/+3o6P/Qzc3/LS0tmwAAAEcAAAA3AAAAIQAAAA8AAAAGAAAAAQAAAAD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////ABQVFQAUFRUgn5yc9NjR + 0f/f29n/083L/0VEp/8jI8n/JyfH/ygoxf8oKML/JSa//x0euv8cHbf/Hh+1/x8gs/8gIbH/ICKv/yIj + rf8kJKv/JSSp/yUlp/8mJ6T/Jyij/ygpof8pKp//Kiuc/yosm/8qLZn/Ky2X/ysumf8rLpz/LC2d/ywt + n/8sLaD/Kyyj/ysspP8rLKX/Kyun/yoqqP8qKqr/KSmr/ygorP8nJ67/Jiav/yQmsP8kJbH/IySy/yIj + s/8hIrX/ICG2/yAgt/8eHrj/Hh25/x0duv8cHLz/Gxy8/xocvv8aG77/GhrA/xoZwf8aGcH/GRnC/xkZ + w/8YGMT/GBjE/xgYxP8XF8T/FxfE/xYWw/8WFsP/FRXD/xUVw/8VFcP/FBTE/xQUxP8TE8T/ExPD/xIS + wv8SEcL/ERHC/xERwv8QEML/EBDC/w8Pwv8ODsT/CQmt/2Zcgf/w7Ob/6+jo/+bi4v9KSkq6AAAATAAA + ADsAAAAkAAAAEgAAAAcAAAACAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8AMzMzADMzM1O5tbX/1s/P/+fj4P+8t73/LS2v/yYmzv8pKMn/KSnG/ykp + xP8qK8L/KSq//yMku/8fILf/ICG1/yIjs/8jJLH/JCSv/yUlrf8mJ6v/KCep/ykpp/8qK6X/Kyyj/ywt + ov8sLaD/LS+e/y4wm/8uMJr/LjCa/y8xm/8vMZ7/LzCf/y8woP8uMKP/LS+k/y4vpf8tLqf/LC2o/yws + qv8sLKv/Kyqs/yoqrf8pKa7/Jyiv/yUnsP8lJrH/JCWz/yMktP8hI7X/ICK2/yAgt/8fH7j/Hh65/x4d + uv8dHLv/HBy8/xobvf8aG73/Ghu//xobwP8aGcH/GRnB/xkZwf8YGML/GBjD/xgYxP8XF8T/FxfE/xYW + w/8WFsP/FRXD/xUVw/8UFMP/FBTD/xQTw/8TE8P/ExLD/xISwv8SEsL/ERHC/xERwv8QEML/EBDB/w8P + wf8HCLv/QTl6/+Te1v/t6ur/6OTk/3d2dtoAAABZAAAAPgAAACcAAAAVAAAACQAAAAMAAAAA////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wA6OTkAOjk5eM3H + x//W0ND/6+fi/5yWsv8pKbv/KSrP/ysryv8rK8j/KyvG/yssw/8sLcH/LS6//yoqu/8kJLf/IyS0/yQl + sv8mJ7H/Jyiw/ykprv8rK6z/LCuq/y0tqP8tL6X/LjCk/y8xov8xMaH/MTOf/zI0nP8yNJv/MjSc/zM1 + nv8zNKD/MzOh/zEzo/8xM6T/MTOm/zAyp/8vMaj/Ly+q/y4uq/8tLqv/LC2t/ywrrv8qK6//KCmw/yco + sf8mJ7H/JSaz/yQltP8iI7T/ISK2/yAgt/8fH7j/Hh64/x0duf8dHLv/HBy7/xscvP8aG73/Ghu+/xob + v/8ZGr//GRnA/xkYwP8YGMH/GBjC/xcXwv8XF8P/FxfD/xYWw/8WFsP/FRXD/xUVw/8UFMP/FBTD/xMT + w/8TE8P/EhLB/xISwf8REcH/ERHA/xEQv/8QEL7/EA++/wkLvv8qJYP/ysK///Hu7f/s6Oj/lZSU8QAA + AGMAAABBAAAAKwAAABcAAAAJAAAAAwAAAAD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AAEBAQBtbGyh083N/9nU1P/q5d3/f3ur/yMkxP8tLc//LS7M/y4u + yf8uLsf/Ly/F/y8ww/8wMMH/MTK//zExvP8rLLj/Jyi0/ycosv8qK7D/Kyyv/y0trf8uLqz/Ly+q/y8x + qP8xM6f/MjSl/zM0o/80NqL/NTeg/zY4nv82OJ3/Njie/zY4oP82OKL/Njej/zU3pP80Nqb/NDan/zM1 + qP8yNKr/MTKr/zAxq/8uL63/Li+u/y0ur/8sLK//Kiuw/ykpsv8mKLL/Jiez/yUmtP8jJLT/ISO1/yEi + tv8gILf/Hh64/x4euP8dHLr/HBy7/xwcu/8aG7v/Ghu8/xobvv8ZGr7/GRq//xgZv/8YGL//GBi//xcX + wP8XF8H/FhbB/xYWwf8WFcH/FRXB/xUUwf8UFMD/FBTA/xMTwP8TE8D/EhK//xISvv8REb3/EBG9/xAR + vf8PEbz/DA69/xYTj/+wpqf/8/Hw/+vm5v+zsLD8FxgYewAAAEIAAAAuAAAAGQAAAAsAAAADAAAAAP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAQEBBIB/ + f8bX0dH/3djY/+Te1/9pZaj/JCXN/y8v0P8vMM3/MDDL/zExyv8xMcj/MTPG/zIzxP80NcL/NjXA/zc3 + vv80Nbv/Li+2/ywss/8tLbH/LzCw/zEyr/8yM63/MzSr/zQ2qv82OKj/Njmm/zg5pf85OqP/Ojuh/zo8 + n/86PJ//Ojyh/zo8o/86O6T/Ojul/zg6p/84Oqf/Nzmo/zY3qv81Nqv/MzSs/zIzrf8xMq3/MDGu/y4v + r/8tLbD/Kyyw/yorsf8oKbL/Jiez/yUmtP8jJbT/IiS1/yEitv8gILb/Hx+3/x4et/8dHLj/HBy5/xwc + uv8bG7v/Gxu7/xobu/8aGrz/GRq9/xgavf8YGb7/GBi+/xcYvv8XF7//Fhe//xYXv/8VFr//FRW//xQV + vv8UFL3/ExS9/xMTvf8SE73/EhO9/xESvP8RErv/EBK6/xARuf8OD7z/DQyZ/5WKlv/18u//5+Li/8bD + w/8qKiqUAAAAQgAAADEAAAAbAAAADAAAAAQAAAAA////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wAAAQENj4yM59zW1v/h3dz/1tHO/1RSrf8qK9P/MDDS/zAx + 0P8yMs3/MzPL/zMzyf81Ncf/NjfF/zY3wv84OcH/OjvA/zw9v/88PLz/ODi5/zMztf8yMrL/MzSx/zY3 + sP83OK7/ODms/zk7q/87Par/Oz2o/z0+pv8+P6X/PkCj/z9Bof8/QaH/P0Gj/z5Apf8+P6X/Pj+n/zw+ + qP86Pan/Ojyq/zg6q/83Oav/Njet/zU1rf8yNK7/MTKv/y8wr/8uL7D/LC2w/yorsf8pKrL/Jyiz/yUm + s/8kJbT/IiO0/yEitf8gIbb/Hx+2/x4etv8dHbf/HBy4/xwcuf8bG7n/Gxu6/xsbuv8aGrv/Ghq8/xkZ + vP8YGbz/Fxm7/xcYu/8XGLz/Fhe8/xYXvf8VFr3/FRa8/xQVu/8UFbz/ExS7/xMUuv8TE7r/EhO6/xIS + uf8SErj/ERG3/xAQuf8LC6L/d2yL//Hu6f/l4eH/19PT/zU1NakAAABCAAAAMwAAAB4AAAAOAAAABAAA + AAH///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////ACUl + JSCppaX03tfX/+Tg3//MxcX/RUSy/y4u1v8yMtP/MzTR/zQ1z/82Nsz/NzfL/zg4yf85Ocf/OjvF/zs9 + xP89PsH/Pz/A/0BAv/9CQr3/QkK7/z4+uP85ObT/ODmy/zo7sf89PbD/Pj+u/z9BrP8/Qqv/QUOq/0JE + qP9DRKf/Q0Wl/0RFo/9DRaT/Q0Sl/0JEp/9CQ6j/QUKo/z9Bqv89QKr/PD6r/zs9rP86O63/ODit/zY3 + rf81Nq//MzSv/zEyr/8uL7D/LS6w/ywssP8pKrL/KCmy/yYns/8kJbP/IiOz/yEis/8gIbT/HyC1/x4e + tv8dHbb/HBy3/xwbuP8bG7j/Gxu5/xsbuP8aGrj/Ghq5/xkZuv8YGbr/GBi6/xgYuv8XF7r/Fxe6/xYW + uv8WFrr/FRa6/xUVuv8UFbn/FBS4/xQUuP8TE7f/ExO3/xIStv8SEbb/ERG3/woKqf9eVoX/7enh/+Xh + 4f/g29v/TExMuQAAAEYAAAA1AAAAHwAAAA4AAAAFAAAAAf///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8ALy8vPLezs/zc19f/5uLg/8K7vv85OLb/MzPY/zU1 + 1f82NtL/NzjQ/zg5z/87Osz/OzvL/zw8yv8+P8f/P0DG/0BBxf9DQ8P/RETC/0ZGwP9ISL7/SUm9/0lJ + u/9ERbf/QEG1/z9Asv9CQrH/Q0Ww/0RGr/9FR63/Rkis/0hIqv9ISaj/SEmn/0hJpv9HSKb/R0io/0ZH + qf9GR6n/REWq/0NEq/9BQ6v/P0Gt/z5Arf88Pa3/Ojqu/zc4rv82N6//NDWv/zIzr/8vMK//LS+w/yws + sP8qK7H/Jyqx/yYnsf8kJbL/IiOy/yEis/8gIbT/HiC0/x0etP8dHbT/HB21/xsbtf8bG7b/Gxu3/xsa + t/8aGrj/Ghm4/xkZt/8ZGbj/GBi4/xgYuP8XF7j/Fxe4/xYWuP8WFrj/FRW3/xUUt/8UFLb/FBS2/xMT + tf8TE7T/EhK0/xISs/8RErP/Bwqu/0pBfv/q5Nv/5uLi/+Hc3P9oZ2fLAAAATQAAADYAAAAgAAAADwAA + AAUAAAAB////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wAxMTFPwLy8/93W1v/r5+T/sKq3/zc3vP82Ntn/ODjV/zk51P86OtL/OzvQ/z09z/8/P83/QEDM/0JC + yv9DRMj/REbH/0dHxv9JSMT/SkrD/0xMwv9OTcD/UE+//1FSvv9QUbz/TE25/0hJtf9HSLL/SUuy/0pN + sf9LTa//TE6u/01Orf9NTqv/TU6p/01OqP9MTaj/S0yq/0pLqv9JSqv/R0ms/0VHrP9ERq3/QkSt/0BC + rv8+P67/PDyu/zk6r/83OK//NTav/zM0r/8wMq//Ly+w/y0tsP8rK7D/KCqw/yUnsP8kJbH/IySx/yEi + sv8gIbL/Hh+y/x0fs/8cHrP/HBy0/xsctP8bHLT/Gxy2/xoatv8aGrb/GRm1/xkZtf8YGLb/GBi2/xgX + tv8XF7b/Fxa2/xYWtf8WFbX/FRW0/xUVtP8UFLT/FBSz/xMUsv8TE7H/EhOw/xESsP8JC67/PDWA/9/Z + 0v/n4+P/4dzc/3h2dtgAAABSAAAANgAAACEAAAAPAAAABQAAAAH///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////ADU1NWLLxsb/3tjY/+vo5P+inLP/OzvC/zg4 + 2f86Otb/PDvW/z091P89PtL/QEDS/0JCz/9DQ87/RUTN/0ZHy/9JSsn/S0vI/01Nxv9PT8b/UFHE/1JS + w/9TU8L/VVXB/1dYwP9ZWr//WVq9/1VWuv9QUbb/T1C0/1BRs/9RUrL/UlKw/1NSrv9SVK3/UlOr/1JT + qv9RUqv/T1Cs/05PrP9NTq3/Skyt/0hLrf9FSa3/REau/0JDrv9AQa7/PT+u/zs7r/84Oa//Njev/zM0 + r/8wMa//Li+v/y0tr/8rK6//KCqv/yYor/8kJrD/IiOw/yEisP8fILH/Hh+x/x0esf8dHrL/Gxyy/xsc + sv8bHLP/Gxyz/xobtP8aG7T/GRq0/xkZs/8YGbP/GBi0/xcYtP8XF7T/Fhez/xYXs/8VFrL/FRax/xQV + sf8UFbH/ExSx/xITsP8SE67/ERKu/wsNrf80LoP/1c3J/+nl5P/j3t7/hoSE4wAAAFYAAAA3AAAAIQAA + AA8AAAAFAAAAAf///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8ANjY2bNDLy//f2tr/6ubg/5aRsf85Ocb/OzvZ/z091/8+Ptf/QD/X/0FB1f9DQ9P/RUXR/0dH + 0P9ISM//S0vN/01Oy/9PUMr/UVLJ/1NTyP9VVcf/V1jG/1hZxf9aW8T/W1zD/15fwv9gYcH/YWLA/2Fi + v/9dXrz/WVq4/1ZXtf9WV7T/WFiz/1hZsf9YWbD/V1iu/1ZXrP9VVqz/VFWt/1JTrv9QUa7/Tk+u/0tN + rv9IS67/RUiu/0NFr/9BQ6//PkCu/zw8rv85Oq7/Njev/zQ1rv8xMq//Li+u/y0trv8rLK//KCmv/yYm + rv8kJK//IiOv/yAhr/8fILD/Hh+w/x0esP8cHbD/HB2x/xscsf8bHLH/Ghux/xobsf8aG7L/GRqy/xka + sv8YGbH/GBmx/xcYsf8XGLH/Fhex/xYXr/8VFq//FBWv/xQVr/8TFK7/ExSu/xITrP8SE6z/DA6r/ysn + hv/Lw8L/6ubl/+Pd3f+LiYnqAAAAWAAAADcAAAAhAAAADwAAAAUAAAAB////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wA5OTmA29bW/+Db2//p5N//npi1/z4+ + x/89Pdn/Pz/X/0FB2P9CQtj/RUXW/0ZH1P9ISdP/SkvS/01M0P9PT8//UVHO/1NUzf9VVsz/VlfK/1lZ + yv9cXcn/Xl/H/19gx/9hYcb/Y2TG/2Rnxf9nZ8T/aGjC/2lqwv9qa8H/Z2i+/2Njuv9fYLf/XV21/11d + tP9dXrH/XF2w/1tcrv9ZWq7/V1iv/1VWr/9TU6//UFCv/01Pr/9KTK//R0mv/0VHr/9CRK7/P0Gu/zw9 + rv85Oq7/Nzet/zQ1rf8xMq3/Li+t/y0trf8rK63/KCit/yYmrf8kJa7/IiOu/yAhrv8eH67/HR6u/xwd + rv8cHa//Gxyv/xscsP8bHK//Ghuu/xobr/8ZGrD/GRqw/xgZr/8YGa//Fxiu/xYXrv8WF67/Fheu/xUW + rv8VFqz/FBWs/xQVq/8TFKv/ExSr/xITqv8MDqn/LSmG/8zFw//p5eT/5N7e/5mWlvYAAABcAAAANgAA + ACEAAAAPAAAABQAAAAH///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////ADk5OYDc19f/4t3d/+bh3P+Yk7X/PT3K/0BA2f9CQtf/RETY/0VG2f9IR9j/SUnX/0tL + 1f9OTtT/UVHT/1NS0v9UVdD/V1jO/1lZzv9cXM3/Xl7N/2Bhy/9jZMv/ZWbK/2dnyv9pasj/amzI/2xt + x/9vb8b/b3DG/3Bwxf9xcsT/cXLC/3Bxwf9sbb3/Z2e6/2Njtv9hYrT/X2Gy/15fsP9dXrD/Wluw/1hZ + sP9WVbD/U1Kw/09Qr/9MTa//SEuv/0ZIrv9DRa7/QEGu/z0+rv86Oq3/Nzet/zM0rf8wMa3/LjCs/y0s + rP8qKqz/KCis/yUlrP8kJKz/ISOs/yAhrP8eH6z/HR6s/xwdrP8bHKz/Gxys/xscrf8aG63/Ghut/xka + rf8ZGq3/GBmt/xgZrf8XGK3/Fxis/xYXrP8WF6z/FRas/xUWq/8UFar/ExSq/xMUqf8TFKj/ExSn/w4Q + qP8jIIf/wLe4/+zo5v/j3Nz/mZaW9gAAAFwAAAA2AAAAIQAAAA8AAAAFAAAAAf///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AOTk5gN3Y2P/j39//5uHb/5aS + tf8+P8v/Q0La/0VF2P9HR9n/SUnZ/0pK2f9MTNn/T0/Y/1BS1v9UVNX/V1bU/1lZ0/9cW9H/Xl7Q/2Fh + 0P9kZM//ZmbO/2hpzf9ra83/bG7M/29wzP9xcsv/cnPK/3R1yv92dsn/d3fI/3d3x/94eMb/eHjF/3d4 + xP93d8L/dHTA/25vvP9oarj/ZGW0/2Fjsv9fYLH/XV6x/1pbsf9XV7H/VFSw/1FRr/9NTq//SUuv/0ZI + rv9DRa3/QEKt/zw+rf85Oq3/Njes/zMzrP8vMKv/LS6r/ywsq/8qKqv/Jyeq/yQkqv8jI6r/IiKq/yAh + qv8eH6r/HR6q/xwdq/8cHar/HB2q/xscq/8aG6z/GRqr/xkaqv8ZGqv/GBmr/xgZq/8XGKr/Fxip/xYX + qf8WF6n/Fhep/xUWqP8VFqj/FBWm/xQVpf8TFKb/DxGm/yMfhv++tbb/6+jm/+Lc3P+YlZX2AAAAXAAA + ADYAAAAhAAAADwAAAAUAAAAB////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wA5OTmA3tnZ/+Xg4P/k39r/oZy1/0ZGyv9FRdv/R0fa/0pK2v9MTNn/TU3a/1BQ + 2/9SUtn/VFXY/1dY1/9aWtb/XV3U/2Bg1P9iYtP/ZmbS/2ho0f9ra9H/bW3R/3Bx0P9ydND/dXXP/3d4 + zv94ec7/enrN/3x8zf9+fsz/fn7L/35/yv9+f8n/fX/I/31+xv98fcX/e3zD/3l6wf90dr7/bnC6/2hp + tf9jZLP/X2Cy/1tdsf9ZWbH/VVWw/1JSsP9OT6//Skyu/0ZIrf9CRa3/P0Gt/zw+rP84Oqv/Njar/zI0 + q/8vMKr/LS2q/ysrqf8oKKn/Jiao/yQkqP8iI6n/ISKp/x8gqf8eH6n/HR6p/xwdqf8cHan/HB2p/xsc + qf8bHKn/Ghup/xkaqf8ZGqj/GRqo/xgZqP8YGaj/Fxin/xcYpv8WF6b/Fhem/xUWpf8VFqT/FBWk/xQU + o/8OD6P/LiqF/8jBv//p5uX/4dra/5iVlfYAAABbAAAANQAAACEAAAAQAAAABQAAAAH///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////ADk5OYDf2tr/49/f/+rl + 4P+hnLb/SEjL/0hI2/9KStr/TU3a/05O2/9RUdr/U1Pb/1VV2/9YWdr/WlzZ/15f2P9iYtf/ZGTW/2dn + 1f9qatX/bW3U/3Bw0/9zc9P/dnbT/3h50/97fNL/fX7S/3+A0v+AgtH/goPR/4SE0P+Fhc//hoXO/4aG + zf+Fhsz/hIXL/4ODyf+Bgsf/gIDG/31/w/96fcH/d3m+/3N0u/9sbrf/ZWe0/19gsv9aW7H/VVaw/1FR + r/9OT67/Skut/0ZHrf9CRKz/PkGs/zs9qv83Oqr/NDap/zIyqf8vMKj/LSyo/yoqqP8nKKf/JiWn/yMj + pv8hIqb/ICGn/x8gp/8dHqf/HR6n/xwdp/8cHaf/HB2m/xscpv8bHKf/Ghun/xobp/8ZGqb/GRqm/xgZ + pv8XGKb/Fxil/xYXo/8WF6P/FRaj/xUWo/8UFaL/FBWi/w4PoP8vKob/0MnI/+bh4P/g2dn/l5SU9gAA + AFsAAAA1AAAAIQAAAA8AAAAFAAAAAf///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8AOTk5gODc3P/l4OD/6ubh/6KeuP9MTM3/Skrb/05O2v9QUNv/UVHb/1RU + 3P9WVtz/WVnc/1xc3P9eXtv/YmLa/2Vm2f9oaNj/bGzX/29v1/9yctf/dXXW/3h41v97e9b/fn7W/4GC + 1v+DhNX/hYbV/4iJ1f+JitT/i4vU/4yM0/+MjNL/jI3R/4yM0P+LjM//iovN/4iJzP+Gh8r/g4TH/4CB + xP99fsL/enzA/3d5vf9zdbr/b3C5/2hptv9hYrT/Wluy/1NTr/9OT63/SUqs/0VGq/9BQ6r/PT+q/zk8 + qf83Oaj/Mzao/zAyp/8tL6f/Kyym/ykppv8nJ6b/JCSl/yIjpf8hIqX/HyCl/x4fpf8dHqX/HB2k/xwd + pP8cHaX/Gxyl/xscpP8aG6X/Ghul/xkapP8YGaT/GBmj/xgZo/8XGKP/Fxii/xYXov8WFqH/FRag/xQV + n/8UFZ//Dg+f/y8rh//Qysj/5N/e/9/Y2P+XlJT2AAAAWgAAADQAAAAgAAAADwAAAAUAAAAB////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wA6OTmA4d3d/+Xh + 4f/q5eH/o5+4/1FSz/9MTNz/UFDa/1JS2/9VVdz/V1fc/1pa3f9cXN3/X1/d/2Ji3f9lZtz/aWnc/21s + 2/9wcNr/dHTZ/3Z22f96etn/fn7Z/4CA2P+EhNj/iIfZ/4qL2P+Mjdj/jo/Y/5CR2P+Sktf/k5TX/5OU + 1v+TlNX/k5TU/5KT0v+RktH/j5DQ/42Nzv+Ki8v/h4jJ/4SExv+AgMT/fH3B/3h6vv90drz/cHK5/21u + uP9pabf/Y2S1/1xdsv9UVrD/TU6u/0dHq/9AQqn/PD6o/zc5p/81N6f/MTOm/y4wpf8sLqX/Kiuk/yco + pP8mJqP/IyOj/yEio/8gIaP/Hh+j/x4fo/8cHaP/HB2j/xwdo/8cHKP/Gxyj/xobov8aG6L/GRqi/xka + ov8YGaH/GBih/xcYoP8WGKD/Fheg/xYXnv8VFp3/FRad/xQWnf8OEJ3/MCyG/9HKyf/j3t3/3tfX/5eU + lPYAAABaAAAANAAAACAAAAAPAAAABQAAAAH///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////ADc3N3LZ1dX/6OPj/+rn4v+embb/UlLP/09P3f9SUtz/VVXc/1dX + 3P9aWtz/XFze/19f3v9jY97/Zmbf/2lp3v9sbd7/cHHd/3R03P94eNv/fHzc/39/3P+Dg9v/hobb/4qK + 2/+Ojdz/kJDc/5OS2/+Vldv/l5fb/5mZ2v+amtr/m5vZ/5uc2P+am9j/mZrW/5iY1f+WltT/k5TS/5GR + 0P+Ojs3/i4vK/4eHyP+Cg8X/fn/D/3l7wP91d7z/cHK6/21tt/9oabb/ZGW1/2Bhs/9bXLL/Vlex/1BR + r/9JSqz/QUOq/zs+qP81N6X/MDKk/y0vo/8qK6P/Jyii/yYnof8jJKH/IiOh/yAhoP8fIKD/Hh+g/x0e + of8cHqD/HB6g/xwdoP8bHKD/Gxug/xoboP8aGqD/GRqf/xkan/8YGp//Fxme/xcYnf8WGJ3/Fhid/xUX + nP8UF5v/FBaa/w4Rmf8wLYb/0svK/+Pe3f/b1NT/jYqK7wAAAFcAAAA0AAAAIAAAAA8AAAAFAAAAAf// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8ANTU1Y9TQ + 0P/q5ub/7Ofi/5iTs/9RUs7/UVHd/1VV3P9XV93/Wlrd/11d3f9fX97/Y2Pf/2Zm4P9qauD/bW3g/3Bw + 4P90dN//eHjf/3x83v+AgN7/hITd/4iI3v+MjN7/kJDe/5OT3v+Wlt7/mZne/5yc3v+ent7/oKDe/6Ki + 3v+jo93/o6Pc/6Kj2/+gotr/n6DZ/52e1/+am9b/l5jU/5OV0f+Qkc7/jI3M/4iJyf+DhMf/fn/E/3p7 + wf91d73/cXK6/21tt/9nabX/Y2Sz/15fsv9aW7H/Vlew/1JTr/9OT63/SUqs/0RGqv8/Qan/OTum/zU2 + pf8wMaT/Kyyi/ycooP8jJJ//ISKf/x8gnv8dHp7/HB2e/xsdnv8bHp7/HB6e/xsdnv8aHJ7/Ghye/xoc + nv8ZG53/GRuc/xganP8YGpz/Fxmb/xYYmv8WGJr/FRea/xUXmf8UFpf/DhGY/y4rhf/SzMv/4t7c/9nS + 0v+DgYHjAAAAVAAAADQAAAAfAAAADgAAAAUAAAAB////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wA1NTVk1tLS/+vn5//s6OL/mJOz/1RVz/9UVN3/V1fc/1pa + 3f9dXd3/X1/e/2Ji3v9mZuD/aWnh/21t4f9wcOH/dHTh/3h44f98fOH/gIHh/4WF4P+JieD/jY3g/5GR + 4f+VleH/mJng/5ud4P+goOH/pKPh/6am4f+oqOH/qqrh/6qq4f+qquD/qqrf/6iq3v+nqN3/pKXa/6Ch + 2f+en9j/mpvV/5WW0v+QkdD/jo7N/4mKyv+DhMf/f3/E/3l7wf91dr7/cHG7/2xst/9maLT/YmOy/11e + sf9ZWrD/VFau/1BSrf9MTqv/SUmq/0VGqf9BQqj/Pj+o/zs8p/83OKX/NDWl/zEypP8tLqL/KSqh/yYn + oP8jJZ//ISOe/x8hnv8eIJ3/HR+c/xwdnP8aHJz/Ghyb/xkbm/8ZG5r/GBqa/xcZmf8WGJn/FhiY/xUX + l/8VF5f/FReX/xQWlv8PEpb/Mi6G/9LMzP/h3dz/2NHR/4SBgeQAAABUAAAANAAAAB8AAAAOAAAABQAA + AAH///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////ADY1 + NWTW09P/6+jo/+zn4v+Yk7P/VlbQ/1ZX3v9aWtz/XFzd/19f3v9iYt//ZWXf/2lp4P9sbOH/cHDh/3R0 + 4v93d+P/fHzj/4CA4/+EheP/iYnj/46O4/+SkuP/lZbj/5ma4/+en+P/oqPk/6an5P+qquX/rK3l/6+v + 5P+xseX/srLk/7Ky5P+ysuP/sLDi/66v4f+srN//qKnd/6Sl2/+hotn/m53W/5aX0/+Sk9D/jo7N/4iJ + y/+DhMj/fn/E/3l6wf90db7/b3C7/2prt/9lZrT/YWKy/1tcr/9XWK7/U1Ws/09Rq/9LTKr/R0mo/0NF + p/9AQab/PT6l/zo7pf83OKP/NDWj/zM0o/8yMaL/MDCi/y0uof8sLaH/Kyyg/ykrn/8oKp//Jiif/yUm + nv8jJZ3/IiSc/yAinP8fIZv/HR+Z/xwemf8bHZj/GhyX/xoblv8ZGpb/GBmV/xYXl/87N4r/0s3N/+Dc + 2v/Xz8//hIGB5AAAAFQAAAA0AAAAHwAAAA4AAAAFAAAAAf///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8ANjY2ZNfU1P/s6en/7Ojj/5iTs/9YWND/WVnf/11d + 3f9fX93/YWHe/2Vl4P9nZ+D/a2vg/29v4f9zc+L/d3fi/3t74/9/f+T/g4Pl/4iI5f+MjeX/kpLk/5aW + 5P+amuX/n5/l/6Sk5v+oqeb/q63n/7Cw5/+ztOf/trfn/7m55/+6uuf/urrn/7q65v+4uOX/tbXl/7Oz + 4/+vsOH/q6ze/6eo2/+iotr/nJ3X/5eX0/+SktH/jY7O/4eIyv+Cg8j/fX3F/3d4wf9zc77/bm67/2hp + uP9kZbX/Xl+x/1pbr/9WV6z/UVOq/01Pqf9JS6j/RUin/0JEpv8/QKX/PD2k/zk7o/82OKL/NDWh/zMz + of8xMaD/MDCg/y4voP8tLp//LS6e/yssnv8qK57/KSqe/ykpnf8oKZ3/Jyic/yYnm/8lJpr/JCWa/yMk + mv8iI5n/ICKY/yAhlv8eH5b/Gx2X/z06i//Tzc3/4NrZ/9bPz/+DgYHkAAAAVAAAADQAAAAfAAAADgAA + AAUAAAAB////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wA2NTVk2NXV/+7q6v/s6eT/l5Kz/1pZ0f9bW9//Xl7e/2Fh3v9kZN//Z2fg/2tr4P9ubuH/cnLh/3Z2 + 4/96euT/fn7k/4KC5f+Hh+f/jIvm/5CR5v+Vlub/mprn/5+f5/+kpOf/qano/66u6f+ys+n/trfq/7q7 + 6v++v+v/wMDr/8LC6//Cwuv/wsLq/8DA6f++vef/urrl/7a25P+ysuL/ra3f/6eo3f+hotr/nJ3W/5aX + 1P+RktH/jIzN/4aGy/+Agcj/enzE/3V1wf9wcb7/a2y7/2dnuP9hY7X/XV2y/1hZr/9UVqz/UFGp/0tO + p/9ISqb/REal/0JDo/8+QKP/Oz2i/zk7of82OKD/MzWf/zIzn/8xMZ7/MDCe/y8wnf8uL53/LS6d/ywt + nf8rLJ3/Kiuc/ykpm/8oKZr/Jyia/yYomf8lJpj/JCaX/yMll/8iJJb/ISOV/yAik/8cIJX/PjuL/9PN + zv/f2tn/1c3N/4OAgOQAAABUAAAANAAAAB8AAAAOAAAABQAAAAH///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////ADY2NmTZ1tb/7+vr/+rm4v+nobj/YGDQ/1xc + 3/9hYd7/Y2Pf/2Zm3/9qauD/bW3h/3Bw4v90dOL/eHjj/3x85P+BgeX/hYXm/4qK5/+Pj+j/lJTo/5mZ + 5/+enuj/o6Pp/6mp6v+urur/s7Pr/7i57P+9vuz/wcLt/8TG7f/IyO7/ysru/8rK7v/Jyu3/yMjs/8XF + 6//Bwen/vb3m/7i45f+zsuL/ra3f/6eo3P+hotn/mpzW/5WW1P+Pj9D/iorN/4OEyv9+fsf/eXnE/3N0 + wf9tbr7/aWm6/2Rkt/9fYLX/W1yy/1ZYr/9SVK3/TlCq/0pMp/9HSaX/Q0Wj/0BCov88PqH/Ojuf/zg6 + nv83OJ7/NDae/zEznf8xMpz/MDGc/y8wnP8vMJz/Li+b/y0um/8sLZv/KiuZ/ykqmf8oKpj/KCmY/yYp + lv8mJ5b/JSaW/yQmlf8jJZP/IiST/x0glP9HQ4v/1tDP/97Y2P/UzMz/g4CA5AAAAFMAAAAzAAAAHwAA + AA8AAAAFAAAAAf///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8ANjY2ZNrX1//w7e3/6OTh/6ymtv9mZ9H/Xl7g/2Nj3v9lZd//aGjg/2xs4P9vb+H/c3Pi/3d3 + 4v97e+P/f3/l/4OD5v+IiOb/jY3n/5KS6P+Xl+n/nZ3q/6Ki6v+np+v/ra3r/7Kz7P+5uO3/vr7u/8PD + 7//IyPD/zMzw/8/P8f/R0fH/0tLx/9HS8P/P0PD/zMzu/8jI7P/Dw+r/vr7n/7i45f+xsuL/q6zf/6Sm + 3P+fn9n/mJnW/5OS0/+NjdD/hofN/4CByf97fMb/dXfE/3Bwwf9rbL3/Zme7/2FjuP9cXrX/WFmy/1RV + r/9QUa3/TE6r/0hKqf9FR6b/QkOl/z9Bo/87PqD/OTue/zg5nv83N53/NDWb/zIzm/8xMpv/MDGa/zAx + mv8vMJr/Li+Z/y0umf8sLZj/KyyX/yorl/8oK5b/JyqW/yYolv8mJ5X/JSeV/yQmlf8jJZX/HiGW/1NO + jv/f2tf/29bV/9LLy/+CgIDkAAAAUgAAADMAAAAfAAAADgAAAAUAAAAB////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wA2NjZk29jY/+/t7f/w7er/q6W2/2dn + 0f9gYOD/ZGTf/2ho3/9qauD/bm7h/3Fx4f91deL/eXnj/3195P+BgeX/hobm/4qK5/+QkOj/lJTp/5qa + 6v+fn+v/pqbs/6ur7f+xse3/trbu/7297//Dw+//ycnx/87O8v/T0/P/19f0/9nZ9P/a2vT/2drz/9fX + 8v/T1PH/zc7u/8nJ7P/Dw+r/vLzn/7a25f+vsOL/qKnf/6Kj3P+bnNn/lZbV/5CQ0v+KidD/hIPM/31+ + yf94ecb/c3PD/21uwP9oab7/YmW6/15guP9ZW7X/VVez/1JTsP9OT67/Skyr/0dIqv9DRaj/QUKl/z0/ + pP87PKP/Ojqh/zg5n/82OJ7/NDWd/zI0nP8xMpz/MTGc/zAxm/8wMJr/LzCa/y4vmv8tLpn/LC2Z/yot + mf8pK5n/KCqY/ycpmP8mKJj/JieY/yUmmP8fIZr/VE+R/+Xh3v/X0ND/0svL/4J/f+QAAABSAAAAMgAA + AB4AAAANAAAABQAAAAH///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////ADY2NmTb2dn/8O3t//Hu6/+sprb/amzT/2Fh4f9mZuD/aWng/2tr4P9wcOL/c3Pi/3d3 + 4v97e+T/f3/k/4SE5f+IiOf/jY3n/5KS6P+Xl+r/nZ3q/6Ki7P+np+3/ra3t/7S07v+7u+//wMDw/8fH + 8f/NzfL/1NT0/9nZ9f/e3vb/4uL3/+Pj9//i4vb/3t71/9nZ9P/U1PH/zs7v/8fH7P/AwOn/urrn/7Ky + 5P+sq+H/paXe/56f2/+Xmdj/kpLV/4yL0v+Fhs7/gH/M/3p6yf91dcb/b3DC/2prwP9lZr3/YGK7/1te + uP9XWbb/U1Wz/09RsP9MTa7/SEqs/0VHq/9CQqj/QECn/z0+pf86O6T/OTmi/zg4ov83N6D/NTWg/zQ0 + n/8zNJ//MjOe/zExnv8wMJ7/LzCd/y4wnP8tL5z/LC6c/yssnP8qK5z/KSqc/ycpnP8mJ5z/JSac/yIj + nf9ZVJT/5eDd/9TOzv/Rycn/gX5+5AAAAFIAAAAyAAAAHgAAAA0AAAAFAAAAAf///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8ANjY2Zt3a2v/y7u7/8e7r/62n + t/9tb9T/Y2Ph/2ho3/9qauH/bW3h/3Fx4f90dOL/eHjj/3195P+BgeX/hYXm/4qK5/+Ojuj/lJTp/5mZ + 6v+enuv/paXs/6ur7v+wsO7/t7fv/7298P/ExPH/y8vy/9HR9P/Y2PX/39/2/+Xl+f/p6fn/6+v5/+rq + +f/m5vj/39/1/9nZ8//R0vH/ysvu/8TE6/+8vOj/tbXl/66u4v+np+D/oaHd/5qZ2f+TlNf/jo7U/4eH + 0f+Cgs7/fXzL/3Z3yP9xcsX/a2zD/2ZnwP9iY73/XV+7/1lauP9UVrX/UFK0/01Psv9JS6//R0it/0RF + q/9BQqr/Pz+p/zw9p/86Oqb/ODik/zc4o/82NqP/NTaj/zQ1ov8zNKL/MjOh/zEyoP8wMaD/MDCg/y4w + oP8tL5//LC6f/yssn/8qK5//KSqf/ycpn/8mKJ//JCah/19amP/l4N7/1M3N/9DJyf+Cf3/kAAAAUgAA + ADEAAAAdAAAADQAAAAQAAAAB////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wAzMzNX1NLS//Tx8f/y7+z/rKa3/2pr0v9lZeL/aWng/2xs4f9vb+H/cnLh/3Z2 + 4/96euP/fn7k/4KC5f+Ghub/i4vn/5CQ6P+Vlen/mprq/6Cg6/+lpez/rKzu/7Ky7/+4uPD/v7/y/8bG + 8v/NzfP/1dX1/9zc9v/j4/j/6ur6//Hx/P/09Pz/8fH8/+vr+v/k5Pf/3Nz0/9TU8v/Nze//xsbs/76+ + 6f+3t+f/sLDk/6mp4f+jot7/m5vb/5SW2P+Pj9b/iYnT/4KD0P99fs3/eHjK/3JzyP9tbsT/aGnC/2Nk + wP9eYL3/Wlu6/1ZXuP9TVLb/T1C1/0tMs/9ISbD/Rkev/0JDrf9AQaz/Pj6q/zo8qf84Oqj/ODin/zc4 + pv82N6X/NTel/zQ2pf8zNaT/MTSj/zAyo/8wMaP/LzCj/y8wo/8tMKP/LC6j/ystov8qLKL/KSyj/ycq + o/8iJaP/V1KV/+bi3v/TzMz/zsbG/3l2dtwAAABOAAAAMAAAABwAAAANAAAABAAAAAD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AEpKSkbKyMj/9vPz//Pw + 7f+qpLb/YmPO/2dn4v9ra+D/bW3g/3Bw4v90dOL/eHjj/3t75P9/f+X/g4Pl/4iI5/+Njef/kZHo/5eX + 6f+cnOr/oaHs/6io7f+tre7/s7Pv/7q68P/AwPL/yMjz/87O9f/W1vb/3t74/+bm+f/u7vr/9vb9//z8 + /v/39/3/7+/7/+bm+P/e3vX/1tbz/87O8P/Hx+7/wMDr/7m56P+xseX/qqri/6Oj3/+cnNz/lpba/4+Q + 1/+Ki9X/hITS/31/z/94ecz/c3XK/25vx/9pasT/ZWXC/2Bhv/9cXL3/V1i7/1NUuf9QUbf/TE21/0lK + s/9HR7L/RESw/0BBrv8/P63/PT6s/zs8q/85Oqr/ODmp/zc5qf83OKn/NTin/zQ3p/8zNqf/MjWn/zEz + pv8xMqb/MDGm/y8xpv8uMKb/LS+l/ystpv8rLKb/KSum/yMlpv9UUJX/5+Pf/9PLy//LxMT/bmxs0AAA + AEgAAAAuAAAAGwAAAAsAAAAEAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8AZ2dnSMjGxv/39PT/8/Ht/6qktv9iY87/aWni/2xs4f9ubuH/cXHh/3V1 + 4/95eeP/fHzk/4CA5f+FheX/iYnn/42N6P+Skun/l5fq/52d6v+iouz/p6ft/66u7v+zs/D/urrx/8HB + 8v/Hx/T/z8/1/9bW9v/d3fj/5eX5/+3t+v/09P3/+fn9//b2/f/u7vv/5ub4/97e9v/W1vP/zs7x/8bH + 7v/AwOz/ubjp/7Ky5v+qquP/pKTh/52d3v+Wl9v/kZLY/4uM1f+EhdP/f4DR/3l6zv90dcv/b3DK/2ps + x/9lZ8T/YWLC/11ev/9ZWr7/VVa7/1FSuf9NTrj/Sku2/0hIs/9FRbL/QkOx/0BAsP8/P67/PT6t/zo8 + rf85Oq3/ODms/zg5q/84OKv/Nzir/zU3qv80Nqr/MzSq/zIzqf8xMqn/MDGo/zAwqP8vMKn/LS+p/ywt + qP8rLKj/JCWp/1RQlv/o5OD/0crK/8rCwv9vbW3QAAAARAAAACsAAAAYAAAACgAAAAMAAAAA////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wBjY2NIycfH//f1 + 9f/z8e3/rKa3/2do0P9paeL/a2vg/25u4v9ycuL/dnbi/3p65P99feT/gYHl/4WF5v+Jieb/jo7o/5OT + 6P+YmOr/nZ3r/6Ki7P+np+3/rq7u/7Oz7/+6uvH/wcHy/8fH8//OzvT/1dX2/9vb+P/i4vn/6en6/+7u + +//x8fz/7+/8/+rq+v/j4/f/3Nz1/9XV8//OzvD/xsfv/76/7P+4uer/sbLn/6uq5P+kpOL/nZ3f/5aX + 3P+Qktr/i4vX/4WG1f9/gNP/envQ/3V1zf9vccz/amvJ/2Znxv9hY8T/Xl/C/1pbwP9WV77/UlO7/09Q + uv9MTLn/SUm3/0ZGtf9ERLT/QUKz/z9Asv8+PrD/PD2w/zs8r/85Oq//OTqv/zk4rv84OK7/Nzit/zU3 + rP81Nq3/MzSt/zIzrP8xMqz/MDCs/y8wq/8tLqv/Kyyq/ygpqv8nKaz/Xlma/+fj3//Qycn/ycHB/3Bu + bs0AAAA8AAAAJQAAABQAAAAJAAAAAgAAAAD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AGNjY0jKyMj/+ff3//Tx7v+po7f/d3jU/3195v96euP/eHjj/3V1 + 4v92duP/eXnk/3195P+BgeX/hYXm/4qK5/+Ojuj/k5Pp/5iY6v+dnev/oqLs/6en7f+uru7/s7Pv/7i4 + 8f+/v/L/xsbz/8zM9f/S0vb/2dn3/97e+P/j4/n/5+f6/+np+v/o6Pn/5OT4/9/f9//Y2PX/0dHz/8vL + 8P/Fxe//vb7s/7a36v+vsOf/qqrl/6Oj4/+dneD/l5fe/5CS2/+Li9n/hYbW/4CA1P96e9H/dXbP/3Bx + zv9sbMv/ZmjI/2Jjx/9fX8X/W1vD/1dXwf9TVL7/UFG9/01Nu/9KSrr/R0e4/0VFt/9DRLb/QUK1/0BA + tP8+P7P/PD2y/zs8sv87PLL/Ojux/zk5sf84ObH/ODiw/zY3sP81Na//MzSv/zAxrv8uMK7/MjOv/zo6 + sv9HSLj/UFG9/11fw/9pZKD/5N/e/9DJyP/IwMD/cW5uygAAADIAAAAdAAAAEAAAAAYAAAABAAAAAP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AY2NjScvK + yv/6+Pj/9PLv/7SuvP9rbM3/g4Pq/4mI6f+MjOn/j4/o/4yM5/+IiOb/hITm/4KC5f+Fheb/iYnn/46O + 5/+Skun/mJjp/52d6/+hoez/p6ft/6ys7v+xse//uLjw/7298v/Dw/P/yMj0/8/P9f/U1Pf/2dn3/97e + 9//g4Pj/4eH5/+Dg+P/d3ff/2dn2/9TU9P/OzvL/yMjx/8LB7/+7vOz/tbbq/66v6P+oqeX/oaPj/5uc + 4f+Wlt//kZHc/4qL2v+Fhtf/gIDW/3p70/92dtH/cHLP/2xszP9naMv/Y2TJ/2Bgx/9cW8T/WFfC/1RU + wP9RUb//Tk++/0tMvf9ISbv/Rka6/0RFuP9BQ7f/QEG3/z9Atv89P7b/PD60/zw9tP87PLT/OTuz/zk6 + s/83OLP/MzWx/zQ2sf87PbT/S0y7/1xdwv9tbcj/cnPL/3Fyzf9ub83/T1HB/1lTlP/r5+L/zsbG/8e/ + v/9zcXHHAAAAJQAAABQAAAALAAAABAAAAAEAAAAA////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wBeXl4vvLq6+f37+//39fX/1c/N/4uJvP9lZsj/bm/S/3Fy + 2P93eOD/iYnn/5OT6/+YmOv/mJjq/5OT6f+Pj+j/jo7o/5GR6P+Wlun/nJzq/6Gh6/+lpez/q6vu/7Cw + 7/+2tvD/u7vx/8DA8v/FxfP/ysr0/8/P9f/U1Pb/19f3/9nZ9//a2vf/2dn3/9fX9v/U1PT/z8/z/8rK + 8v/ExPH/v7/v/7m57P+zs+r/razp/6en5/+goeT/m5vi/5aW4P+QkN7/iorb/4WF2f+Af9f/envU/3Z2 + 0v9wcdD/bG3O/2dpzf9jZMv/YGDJ/1xcx/9YWMT/VlbD/1JSwv9PT8D/TEy+/0lKvv9GR7z/RUa7/0JE + uv9BQbr/QEC5/z4/uP89P7j/PD63/zs8t/84OrX/Nji0/z4+t/9QUL7/ZGXG/3N0zP90dc7/Z2jK/1FT + wv8+QLj/MzSq/ysrof8wLZD/opuu//Dt6f/Hv7//xb29/2BfX6wAAAASAAAADQAAAAYAAAACAAAAAQAA + AAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AF1d + XQWOjo7L+PX1//b09P/y8O//1tDP/8O9wv+no7f/npu+/42Lv/94d8T/dXbR/31+3P+Mjef/nJzt/6Gh + 7f+goOv/m5vq/5iY6v+amur/np7r/6Sk7P+pqe3/rq7v/7Oz7/+4uPD/vb3y/8HB8v/GxvP/ysr0/87O + 9f/R0fb/09P2/9PT9v/S0vb/0ND1/87O8//KyvP/xcXx/8DA8P+7u+7/trbs/6+v6v+qqun/paXn/5+f + 5P+amuL/lJTg/4+P3v+Kitz/hYXa/39/2P96etb/dnXT/3Fx0v9sbdD/aGjO/2VkzP9hYcv/XV3I/1lZ + x/9WVsb/U1PE/1BRw/9NTsD/SkvA/0hJv/9GR77/REW9/0JDvP9AQbv/QEC7/z8/u/87PLn/PD25/0lK + vv9gYcb/dHTN/3V1z/9jZMr/SUu+/zc4rf8zMp7/S0eX/2ljmv+Lhaj/saq4/83HyP/v7On/0MrK/8e+ + vv+zrKz/MTIyaQAAAAIAAAAIAAAAAwAAAAEAAAAAAAAAAP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8AXV1dAGFhYVvCwMD//Pr6//Ty8v/08vL/8O7s//Du + 6v/p5N7/3NbR/8vFxv+wq7r/mZa8/4GAwP99ftH/h4jf/5qa6/+np+//qanu/6Wl7f+goOv/oaHr/6am + 7P+rq+7/sLDv/7W17/+5ufH/vb3y/8HB8v/FxfP/yMjz/8rK9P/MzPT/zMz0/8zM9P/KyvT/x8f0/8TE + 8v/AwPD/vLzv/7e37f+ysuz/ra3r/6io6f+iouf/nZ3l/5iY4/+Tk+L/jo7g/4mJ3f+EhNv/f3/a/3p6 + 1/91ddX/cXHU/2xs0f9oaND/ZWXP/2FhzP9dXcv/WlrJ/1dXyP9UVMf/UVHF/05PxP9LTML/SUrB/0ZH + wf9FRsD/REW+/0FCvv8+P7z/QEC9/1NUxP9rbM3/eHjS/2xsz/9PUML/OTqv/zo5nv9dWJj/j4mp/8C5 + wP/e2db/8Ozk/+3o4//n4uD/3tnY/8nCwv/FvLz/xr6+/3Z0dMsNDQ0SAAAABAAAAAMAAAABAAAAAAAA + AAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wBdXV0AYWFhAGlpaYi9vLz/8/Dw//n29v/39PT/9PHx//Tx8f/18vL/8e7t/+/s6f/l4Nv/0cvL/7ex + vf+YlLv/hoXG/4iJ2f+amun/q6vw/7Cw8P+srO3/p6ft/6io7f+srO3/sbHv/7W18P+5ufH/vLzx/8DA + 8v/CwvP/xMTz/8bG8//GxvP/xcXz/8XF8//CwvP/v7/y/7u78f+3t+//s7Pu/6+v7P+qqur/paXp/6Cg + 6P+bm+b/l5fk/5KS4v+NjeD/h4ff/4OD3f9+ftr/eXnZ/3V11/9xcdb/bGzT/2hp0v9kZdH/YGHO/15e + zP9aWsz/V1fK/1RUyf9RUcj/T0/G/0xMxf9KS8T/SEnD/0ZGwv9CQ8D/Q0TB/1VWxv9wcM//eHnU/2Rl + zv9FRrv/Ozuk/1lVm/+Ri6n/ycPG/+rl4P/u6+X/49/d/9TOzv/KwsL/xr6+/8S7u//Hvb3/yb+//7+3 + t/+Afn7eGBkZMQ0NDQAAAAADAAAAAQAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AF1dXQBhYWEAaWlpAGFhYU+HhobErays98G/ + v/7Z1tb/6OXl//Hu7v/08fH/8O3t//Hu7//y7+//7uvo/+Pd2P/KxMX/qaO5/5COwv+Li9T/m5vm/7Cw + 8f+1tfD/sbHv/6ys7v+tre7/sbHv/7W18P+4uPD/u7vx/7298f++vvL/v7/y/7+/8v+/v/L/vr7y/7y8 + 8f+6uvH/trbw/7Oz7/+vr+7/q6vs/6am6/+ioun/nZ7o/5ma5v+UleX/kJDj/4uL4f+Ght//goLe/319 + 3P95edr/dXXZ/3Bw1v9sbNX/aGjU/2Rl0v9hYtH/Xl7P/1pbzv9XWMz/VFTL/1JSyv9PUMj/TU3H/0tL + xv9GR8T/R0fE/1dXyf9xcdH/eHjW/19gzf9CQ7f/RkOg/3ZxoP+4sbv/5eDa/+/r5f/h3Nr/z8nJ/8e/ + v//Hvb3/ycDA/8W9vf/Aubn/s62t/6OenvyIhYXoUlJSkRMTExwYGRkAAAAAAQAAAAEAAAAAAAAAAAAA + AAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8AXV1dAGFhYQBpaWkAYWFhAF5eXgNcXFwdYWFhQmdnZ2x3dnaclZSU1LSysvvW09P/6+jo//Ht + 7f/t6ur/7+zs/+/s7P/q5+L/1c/M/7Otu/+Rj73/kZHU/6Gh6P+1tfL/uLjx/7Oz7/+uru7/sLDu/7Oz + 7/+2tvD/uLjw/7m58f+6uvH/urrx/7m58f+4uPH/t7fw/7S08P+xse//rq7v/6ur7v+np+z/o6Pr/5+f + 6v+am+j/lpbm/5KS5P+NjuP/iYrj/4WF4P+AgN//fHze/3h42/90dNr/cHDY/2xs1v9oaNX/ZWXU/2Fi + 0/9dXtH/WlvP/1dYzv9VVs3/UlPM/1BQy/9MTcn/SErI/1NVy/9vcNP/envZ/2Fi0P9ERLn/UE2h/4aA + pf/Mxsf/7enj/+fi4P/Uzs3/yMDA/8e/v//JwcH/w7u7/7Krq/+Sjo7td3R0uUxMTIUwMDBYKisrMgME + BA5SUlIAExMTABgZGQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wBdXV0AYWFhAGlpaQBhYWEAXl5eAFxc + XABhYWEAZ2dnAHd2dgBcXFwGXV1dMWhoaHSGhYW9rqys+dbT0//r5+f/7enp/+rn5//u6+v/6+jl/9nT + z/+5s73/mZbA/5CR1f+oqev/ubnz/7m58f+xse//rq7u/7Cw7v+zs+//tLTv/7W17/+0tO//tLTv/7Oz + 7/+ysu//r6/v/62t7v+qqu7/p6fs/6Oj7P+goOv/nJzq/5iX6f+Tk+f/j4/m/4qL5f+Hh+P/g4Ph/35/ + 4P97e9//d3fd/3Nz3P9vb9v/a2vY/2dn1/9kZNb/YWHV/15e0/9bW9L/WFjR/1VWz/9SU87/Tk7M/1FS + zf9patT/fH3b/2lq1f9HSb3/T0yj/5KLqf/V0M3/7enj/+Hd2//NxsX/x76+/8rBwf/Fvb3/sKqq/4uH + h+JhYGCbNDQ0VBQUFBkAAAABTExMADAwMAAqKysAAwQEAFJSUgATExMAGBkZAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AF1dXQBhYWEAaWlpAGFhYQBeXl4AXFxcAGFhYQBnZ2cAd3Z2AFxcXABdXV0AaGhoAIaF + hQBcXFwqamlpf42MjNe/vb3/5ODg/+vn5//o5OT/6+no/+zo5v/Y0s//ta+8/5KQwP+XmNv/r6/u/7u7 + 8/+1tfD/rq7u/6ys7v+uru7/r6/v/6+v7/+vr+//rq7u/62t7v+rq+7/qKjt/6Wl7f+jo+z/oKDr/5yc + 6v+YmOr/lZXp/5GR6P+Njef/iIjm/4WF5f+BgeL/fX7h/3l64P92dt3/cnLd/25v3P9ra9r/Z2fY/2Vl + 2P9hYdf/Xl7V/1tb1P9YWNL/VFXR/1FS0P9hYtT/enrc/3Z23P9SU8f/TEqo/4iCp//Qysr/7enk/97Z + 2f/Kw8P/yL+//8rCwv++t7f/m5eX9WhmZq8zMzNXEBAQEGFgYAA0NDQAFBQUAAAAAABMTEwAMDAwACor + KwADBAQAUlJSABMTEwAYGRkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AXV1dAGFhYQBpaWkAYWFhAF5e + XgBcXFwAYWFhAGdnZwB3dnYAXFxcAF1dXQBoaGgAhoWFAFxcXABqaWkAXV1dCGBgYFB9fHy3sa6u+9zY + 2P/p5eX/5eHh/+rn5//r5+T/083L/6ynuv+Ojsb/n5/j/7W18v+5ufH/r6/u/6mp7f+qqu3/qqrt/6qq + 7f+pqe3/p6fs/6am7P+kpOz/oaHs/5+f6/+cnOr/mZnq/5aW6v+Skun/jo7o/4uL5v+Hh+b/g4Pl/39/ + 5P98e+L/eHjh/3R04P9wcd7/bW7d/2pq3P9naNr/ZGXZ/2Fh2P9eXtf/W1vV/1dX1P9aWtX/c3Pb/39/ + 4P9iYtP/Skmz/3Nvo//Gv8L/7enj/+Dc2//Kw8P/yMDA/8rBwf+3sbH/jImJ5kxLS4chIiIpaGZmADMz + MwAQEBAAYWBgADQ0NAAUFBQAAAAAAExMTAAwMDAAKisrAAMEBABSUlIAExMTABgZGQAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wBdXV0AYWFhAGlpaQBhYWEAXl5eAFxcXABhYWEAZ2dnAHd2dgBcXFwAXV1dAGho + aACGhYUAXFxcAGppaQBdXV0AYGBgAH18fABdXl43dXR0rKuoqPzb19f/5+Li/+Pe3v/q5+b/5+Pf/8rD + xf+dmbv/kpLS/6ip6/+4uPL/sbHv/6en7P+kpOz/paXs/6Sk7P+jo+z/oqLs/6Cg7P+enuv/m5vq/5iY + 6v+Vlen/kpLo/4+P6P+MjOf/iYnn/4WF5v+BgeX/fn7k/3p64/93d+P/c3Ph/3Bv4P9tbN//aWrd/2Zn + 3P9jZNv/YGHa/11e2P9ZWdf/Zmba/35/4f92d+D/UlLE/15bpf+spbT/6OTe/+bh3//Nxsb/x7+//8vC + wv+3sbH/hYOD4EVGRnQQEREVTEtLACEiIgBoZmYAMzMzABAQEABhYGAANDQ0ABQUFAAAAAAATExMADAw + MAAqKysAAwQEAFJSUgATExMAGBkZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AF1dXQBhYWEAaWlpAGFh + YQBeXl4AXFxcAGFhYQBnZ2cAd3Z2AFxcXABdXV0AaGhoAIaFhQBcXFwAamlpAF1dXQBgYGAAfXx8AF1e + XgB1dHQAXFxcNnd2drCxrq7+39vb/+Pe3v/i3t7/6+fm/9/a1f+2sbz/jozA/5eX3v+xsfH/srLv/6Wl + 7P+goOv/oKDs/5+f6/+dnev/nJzr/5qa6v+Xl+n/lZXp/5KS6f+Pj+j/jIzo/4mJ5/+Ghub/g4Pl/39/ + 5f98fOT/eXnj/3V14/9ycuL/b2/g/2xs4P9pad//Zmbe/2Nj3f9eX9v/Xl7a/3Jy3/+Dg+X/ZWfY/09P + s/+Hgaf/19HO/+vo5P/Uzs7/x76+/8vCwv+8trb/i4iI5UVERHYQEBAURUZGABAREQAAAAABAAAAAQAA + AAAAAAAAEBAQAGFgYAA0NDQAFBQUAAAAAABMTEwAMDAwACorKwADBAQAUlJSABMTEwAYGRkAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8AXV1dAGFhYQBpaWkAYWFhAF5eXgBcXFwAYWFhAGdnZwB3dnYAXFxcAF1d + XQBoaGgAhoWFAFxcXABqaWkAXV1dAGBgYAB9fHwAXV5eAHV0dABcXFwAd3Z2AF5eXkWAf3/MwLy8/+Ld + 3f/f2tr/5ODg/+rm4//OyMf/n5u6/5CQ0v+lpuz/sbDx/6Wl7P+bm+r/mprq/5mZ6v+YmOr/lpbp/5SU + 6f+Skuj/j4/n/42N5/+Kiuf/h4fm/4SE5v+BgeX/fn7k/3t74/93d+P/dXXi/3Jy4f9vb+H/bGzh/2lp + 4P9mZt//YWHe/2Rk3v99feT/f37m/1lazP9jYKj/s624/+vm4f/e2dn/yMDA/8rBwf/Fvb3/mpaW901N + TY0REREcRUREABAQEAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAQEBAAYWBgADQ0NAAUFBQAAAAAAExM + TAAwMDAAKisrAAMEBABSUlIAExMTABgZGQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wBdXV0AYWFhAGlp + aQBhYWEAXl5eAFxcXABhYWEAZ2dnAHd2dgBcXFwAXV1dAGhoaACGhYUAXFxcAGppaQBdXV0AYGBgAH18 + fABdXl4AdXR0AFxcXAB3dnYAXl5eAF5fXwdjY2NtlZKS69LNzf/h29v/3djY/+jk4//g29b/tK67/4+N + xf+ZmuP/ra3w/6Wl7f+Xl+n/lZXp/5WV6f+Tk+j/kZHo/4+P6P+MjOf/iorm/4eH5v+Fheb/goLl/39/ + 5P98fOT/eXnj/3Z24/9zc+L/cHDi/25u4P9ra+D/aGjf/2Nj3/9tbeH/hITn/3V24/9YWcD/hH+p/9XO + zP/q5uL/0MrK/8e+vv/Lw8P/raen/2lnZ7ojIyM0TU1NABEREQAAAAABAAAAAQAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAABAQEABhYGAANDQ0ABQUFAAAAAAATExMADAwMAAqKysAAwQEAFJSUgATExMAGBkZAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AF1dXQBhYWEAaWlpAGFhYQBeXl4AXFxcAGFhYQBnZ2cAd3Z2AFxc + XABdXV0AaGhoAIaFhQBcXFwAamlpAF1dXQBgYGAAfXx8AF1eXgB1dHQAXFxcAHd2dgBeXl4AXl9fAGNj + YwBdXV0hcXFxqbKurv/e2Nj/29XV/+Hd3f/o4+D/xr/B/5SSvP+Njtn/pqfu/6Sk7f+Vlen/kJDo/4+P + 6P+Ojuj/jIzn/4qK5v+Hh+b/hITm/4OD5f+AgOT/fX3k/3t75P94eOP/dXXj/3Jy4f9wcOH/bW3h/2pq + 4P9mZt//dHTi/4eH6f9sbdv/X1+0/6Odsf/l4Nv/4dzb/8jAwP/KwcH/wbq6/4iFhec4ODhnAQEBBiMj + IwAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQAGFgYAA0NDQAFBQUAAAA + AABMTEwAMDAwACorKwADBAQAUlJSABMTEwAYGRkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AXV1dAGFh + YQBpaWkAYWFhAF5eXgBcXFwAYWFhAGdnZwB3dnYAXFxcAF1dXQBoaGgAhoWFAFxcXABqaWkAXV1dAGBg + YAB9fHwAXV5eAHV0dABcXFwAd3Z2AF5eXgBeX18AY2NjAF1dXQBxcXEAYGBgWJCOjufRy8v/3dbW/9vV + 1f/o5OP/19HN/6GcuP+EhM3/nZ3q/6Sj7f+Skuj/i4vn/4uL5/+Jief/h4fm/4WF5v+Dg+b/gIDl/35+ + 5P98fOP/eXnj/3Z24/90dOL/cXHh/29v4f9ra+D/aWng/3t75P+Ghun/ZGXS/2tprP+/uL7/6ubh/9bQ + z//Gvb3/y8PD/6ynp/9fX1+wExQUIzg4OAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAQEBAAYWBgADQ0NAAUFBQAAAAAAExMTAAwMDAAKisrAAMEBABSUlIAExMTABgZ + GQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wBdXV0AYWFhAGlpaQBhYWEAXl5eAFxcXABhYWEAZ2dnAHd2 + dgBcXFwAXV1dAGhoaACGhYUAXFxcAGppaQBdXV0AYGBgAH18fABdXl4AdXR0AFxcXAB3dnYAXl5eAF5f + XwBjY2MAXV1dAHFxcQBgYGAAXV1dIXR0dLa6tbX/3NXV/9fR0f/j39//4NrV/6+puv+Dg8X/lJTl/6Gh + 7v+QkOj/hobm/4aG5v+Fheb/g4Pl/4GB5f9+fuT/fHzk/3p65P94eOP/dXXj/3Jy4v9xceH/bW3g/2xs + 4P+AgOb/hITo/2Bhyf99eqv/0cvJ/+fj4P/Nxsb/yL+//8a9vf+QjY3wPT09cAAAAAYTFBQAAAAAAgAA + AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEABhYGAANDQ0ABQU + FAAAAAAATExMADAwMAAqKysAAwQEAFJSUgATExMAGBkZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AF1d + XQBhYWEAaWlpAGFhYQBeXl4AXFxcAGFhYQBnZ2cAd3Z2AFxcXABdXV0AaGhoAIaFhQBcXFwAamlpAF1d + XQBgYGAAfXx8AF1eXgB1dHQAXFxcAHd2dgBeXl4AXl9fAGNjYwBdXV0AcXFxAGBgYABdXV0AX2BgAWRk + ZHignZ3519HR/9bPz//e2dn/5eHd/763vv+FhL//iovg/56e7f+Rken/hITl/4GB5f+AgOX/fn7k/319 + 5P97e+T/eXnj/3Z24/90dOL/cXHi/21t4f9zc+L/hobn/4GB5v9hYcL/kYyu/97Y0//i3t3/x7+//8rB + wf+6tLT/dXNzzxYWFjY9PT0AAAAAAgAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAEBAQAGFgYAA0NDQAFBQUAAAAAABMTEwAMDAwACorKwADBAQAUlJSABMT + EwAYGRkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8AXV1dAGFhYQBpaWkAYWFhAF5eXgBcXFwAYWFhAGdn + ZwB3dnYAXFxcAF1dXQBoaGgAhoWFAFxcXABqaWkAXV1dAGBgYAB9fHwAXV5eAHV0dABcXFwAd3Z2AF5e + XgBeX18AY2NjAF1dXQBxcXEAYGBgAF1dXQBfYGAAZGRkAF5eXkWLiYnjzsjI/9XPz//Y09P/5+Pg/8jB + w/+Jh7v/g4Pb/5qa7P+Wlun/h4fm/39/5P97e+T/eXnk/3h44/92duP/c3Pi/3Fx4v90dOL/f3/l/4yM + 6f97e+L/ZGS+/6Casf/l4Nr/29bV/8W9vf/KwcH/raen/1pZWaQREhIYFhYWAAAAAAMAAAABAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAAYWBgADQ0 + NAAUFBQAAAAAAExMTAAwMDAAKisrAAMEBABSUlIAExMTABgZGQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wBdXV0AYWFhAGlpaQBhYWEAXl5eAFxcXABhYWEAZ2dnAHd2dgBcXFwAXV1dAGhoaACGhYUAXFxcAGpp + aQBdXV0AYGBgAH18fABdXl4AdXR0AFxcXAB3dnYAXl5eAF5fXwBjY2MAXV1dAHFxcQBgYGAAXV1dAF9g + YABkZGQAXl5eAF5eXiF5eHjFwby8/9bOzv/Uzc3/5uLf/9DJyP+Sj7j/eXrQ/46O6P+YmOz/kpLp/4iI + 5v+CguX/f3/k/35+5P9/f+T/hYXm/42N6f+Jier/b2/a/2tquP+uqLf/6OPd/9XQ0P/EvLz/ycDA/52Y + mPpAQEB6AAAABRESEgAAAAADAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEABhYGAANDQ0ABQUFAAAAAAATExMADAwMAAqKysAAwQEAFJS + UgATExMAGBkZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AF1dXQBhYWEAaWlpAGFhYQBeXl4AXFxcAGFh + YQBnZ2cAd3Z2AFxcXABdXV0AaGhoAIaFhQBcXFwAamlpAF1dXQBgYGAAfXx8AF1eXgB1dHQAXFxcAHd2 + dgBeXl4AXl9fAGNjYwBdXV0AcXFxAGBgYABdXV0AX2BgAGRkZABeXl4AXl5eAF5fXw5ubm6itbCw/9TN + zf/Ry8v/49/e/9rU0P+oo7r/eHfB/3d32P+IiOj/kZHr/5GR6/+QkOn/j4/p/46O6v+IiOn/dHXe/2Rk + x/+BfrP/xb/C/+fi3v/Qysr/xby8/8e+vv+LiIjrMTIyVkBAQAAAAAADAAAAAwAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQAGFg + YAA0NDQAFBQUAAAAAABMTEwAMDAwACorKwADBAQAUlJSABMTEwAYGRkAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8AXV1dAGFhYQBpaWkAYWFhAF5eXgBcXFwAYWFhAGdnZwB3dnYAXFxcAF1dXQBoaGgAhoWFAFxc + XABqaWkAXV1dAGBgYAB9fHwAXV5eAHV0dABcXFwAd3Z2AF5eXgBeX18AY2NjAF1dXQBxcXEAYGBgAF1d + XQBfYGAAZGRkAF5eXgBeXl4AXl9fAG5ubgBmZmaGqqWl/9TNzf/Ox8f/3NfW/+Tf2v/Fv8L/lpO3/3t6 + v/9ycs7/d3fX/3Nz2v90dNn/b2/S/2xsxP9/fbT/q6a4/9zX0//i3tv/ysPD/8e9vf/Curr/fnx83RYX + FzkxMjIAAAAABAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAAYWBgADQ0NAAUFBQAAAAAAExMTAAwMDAAKisrAAME + BABSUlIAExMTABgZGQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wBdXV0AYWFhAGlpaQBhYWEAXl5eAFxc + XABhYWEAZ2dnAHd2dgBcXFwAXV1dAGhoaACGhYUAXFxcAGppaQBdXV0AYGBgAH18fABdXl4AdXR0AFxc + XAB3dnYAXl5eAF5fXwBjY2MAXV1dAHFxcQBgYGAAXV1dAF9gYABkZGQAXl5eAF5eXgBeX18Abm5uAGZm + ZgBjY2NrmpeX+c/Hx//Px8f/0crK/9/b2f/f2tX/zsjH/7Suu/+fmrf/mJS5/5uXuP+knrX/xL7B/9nT + z//j39v/1M3N/8W8vP/JwMD/urOz/3RycscWFhYkFhcXAAAAAAMAAAABAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQ + EABhYGAANDQ0ABQUFAAAAAAATExMADAwMAAqKysAAwQEAFJSUgATExMAGBkZAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AF1dXQBhYWEAaWlpAGFhYQBeXl4AXFxcAGFhYQBnZ2cAd3Z2AFxcXABdXV0AaGhoAIaF + hQBcXFwAamlpAF1dXQBgYGAAfXx8AF1eXgB1dHQAXFxcAHd2dgBeXl4AXl9fAGNjYwBdXV0AcXFxAGBg + YABdXV0AX2BgAGRkZABeXl4AXl5eAF5fXwBubm4AZmZmAGNjYwBfYGA+gX9/17iysv/PyMj/zMTE/9DI + yP/X0dH/3tnW/9/a1v/c1tH/3dfS/+Db1//a1NP/0MrJ/8e+vv/Iv7//xb29/6Oenv1PTk6SDxAQDhYW + FgAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQAGFgYAA0NDQAFBQUAAAAAABMTEwAMDAwACor + KwADBAQAUlJSABMTEwAYGRkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AXV1dAGFhYQBpaWkAYWFhAF5e + XgBcXFwAYWFhAGdnZwB3dnYAXFxcAF1dXQBoaGgAhoWFAFxcXABqaWkAXV1dAGBgYAB9fHwAXV5eAHV0 + dABcXFwAd3Z2AF5eXgBeX18AY2NjAF1dXQBxcXEAYGBgAF1dXQBfYGAAZGRkAF5eXgBeXl4AXl9fAG5u + bgBmZmYAY2NjAF9gYABfX18OZ2dnf5CNjeu5s7P/ysLC/83ExP/KwcH/ysLC/8zExP/Kw8P/x7+//8e/ + v//JwMD/w7u7/6ulpf9vbW3DKysrQE9OTgAPEBAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAQEBAAYWBgADQ0NAAUFBQAAAAAAExMTAAwMDAAKisrAAMEBABSUlIAExMTABgZGQAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wBdXV0AYWFhAGlpaQBhYWEAXl5eAFxcXABhYWEAZ2dnAHd2dgBcXFwAXV1dAGho + aACGhYUAXFxcAGppaQBdXV0AYGBgAH18fABdXl4AdXR0AFxcXAB3dnYAXl5eAF5fXwBjY2MAXV1dAHFx + cQBgYGAAXV1dAF9gYABkZGQAXl5eAF5eXgBeX18Abm5uAGZmZgBjY2MAX2BgAF9fXwBnZ2cAX19fGWdn + Z3iBf3/RnZmZ+rGrq/+9tbX/wLi4/7+3t/+2r6//pqGh/42Jie1pZ2epLi4uSgMEBAUrKysAT05OAA8Q + EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEABhYGAANDQ0ABQUFAAAAAAATExMADAw + MAAqKysAAwQEAFJSUgATExMAGBkZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AF1dXQBhYWEAaWlpAGFh + YQBeXl4AXFxcAGFhYQBnZ2cAd3Z2AFxcXABdXV0AaGhoAIaFhQBcXFwAamlpAF1dXQBgYGAAfXx8AF1e + XgB1dHQAXFxcAHd2dgBeXl4AXl9fAGNjYwBdXV0AcXFxAGBgYABdXV0AX2BgAGRkZABeXl4AXl5eAF5f + XwBubm4AZmZmAGNjYwBfYGAAX19fAGdnZwBfX18AZ2dnAF5fXyhlZGRgcnBwlHp4eLh8enrBfHp6wHZ1 + dalwb298Ojo6RA0ODg8uLi4AAwQEACsrKwBPTk4ADxAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAEBAQAGFgYAA0NDQAFBQUAAAAAABMTEwAMDAwACorKwADBAQAUlJSABMTEwAYGRkAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A/////////////////////////////////////////////////////4// + //////////////////gA//////////////////+AAB/////////////////+AAAH//////////////// + +AAAAf////////////////AAAAB////////////////AAAAAP///////////////gAAAAB////////// + /////wAAAAAH//////////////4AAAAAA//////////////8AAAAAAH/////////////+AAAAAAA//// + //////////AAAAAAAH/////////////gAAAAAAA/////////////wAAAAAAAH////////////4AAAAAA + AA////////////8AAAAAAAAH////////////AAAAAAAAB////////////AAAAAAAAAP///////////wA + AAAAAAAB///////////xAAAAAAAAAP//////////8gAAAAAAAAD//////////+QAAAAAAAAAf/////// + ///gAAAAAAAAAD//////////wAAAAAAAAAAf/////////5AAAAAAAAAAD/////////+gAAAAAAAAAA// + ////////QAAAAAAAAAAP/////////0AAAAAAAAAAB/////////6AAAAAAAAAAAP////////9AAAAAAAA + AAAB////////+QAAAAAAAAAAAf////////oAAAAAAAAAAAD////////0AAAAAAAAAAAA////////9AAA + AAAAAAAAAH///////+gAAAAAAAAAAAA////////AAAAAAAAAAAAAP///////0AAAAAAAAAAAAD////// + /6AAAAAAAAAAAAAf//////+gAAAAAAAAAAAAD///////QAAAAAAAAAAAAA///////0AAAAAAAAAAAAAH + //////6AAAAAAAAAAAAAB//////+gAAAAAAAAAAAAAf//////wAAAAAAAAAAAAAD//////8AAAAAAAAA + AAAAA//////+AAAAAAAAAAAAAAH//////gAAAAAAAAAAAAAB//////wAAAAAAAAAAAAAAf/////8AAAA + AAAAAAAAAAD/////+AAAAAAAAAAAAAAA//////gAAAAAAAAAAAAAAH/////4AAAAAAAAAAAAAAB///// + 8AAAAAAAAAAAAAAAf/////AAAAAAAAAAAAAAAD/////wAAAAAAAAAAAAAAA/////4AAAAAAAAAAAAAAA + P////+AAAAAAAAAAAAAAAD/////gAAAAAAAAAAAAAAA/////4AAAAAAAAAAAAAAAH////8AAAAAAAAAA + AAAAAB/////AAAAAAAAAAAAAAAAf////wAAAAAAAAAAAAAAAH////8AAAAAAAAAAAAAAAB/////AAAAA + AAAAAAAAAAAf////gAAAAAAAAAAAAAAAH////4AAAAAAAAAAAAAAAA////+AAAAAAAAAAAAAAAAP//// + gAAAAAAAAAAAAAAAD////4AAAAAAAAAAAAAAAA////+AAAAAAAAAAAAAAAAP////gAAAAAAAAAAAAAAA + D////4AAAAAAAAAAAAAAAA////+AAAAAAAAAAAAAAAAP////gAAAAAAAAAAAAAAAD////4AAAAAAAAAA + AAAAAA////+AAAAAAAAAAAAAAAAP////gAAAAAAAAAAAAAAAD////4AAAAAAAAAAAAAAAA////+AAAAA + AAAAAAAAAAAP////gAAAAAAAAAAAAAAAD////4AAAAAAAAAAAAAAAA////+AAAAAAAAAAAAAAAAP//// + gAAAAAAAAAAAAAAAD////4AAAAAAAAAAAAAAAA////+AAAAAAAAAAAAAAAAP////gAAAAAAAAAAAAAAA + D////4AAAAAAAAAAAAAAAA////+AAAAAAAAAAAAAAAAP////gAAAAAAAAAAAAAAAD////4AAAAAAAAAA + AAAAAB////+AAAAAAAAAAAAAAAAf////gAAAAAAAAAAAAAAAH////4AAAAAAAAAAAAAAAB////+AAAAA + AAAAAAAAAAAf////gAAAAAAAAAAAAAAAH////4AAAAAAAAAAAAAAAB////+AAAAAAAAAAAAAAAA///// + wAAAAAAAAAAAAAAAf////+AAAAAAAAAAAAAABP/////wAAAAAAAAAAAAAAn/////+AAAAAAAAAAAAAA/ + ///////AAAAAAAAAAAAD/////////AAAAAAAAAAAP/////////8AAAAAAAAAAf//////////4AAAAAAA + AAf///////////gAAAAAAAAZ///////////+AAAAAAAAZ////////////wAAAAAAAZ/////////////A + AAAAAAJ/////////////8AAAAAAJ//////////////gAAAAAE//////////////8AAAAAE////////// + /////wAAAACf//////////////+AAAABP///////////////wAAABP////////////////AAAAn///// + ///////////4AAAT/////////////////AAAL/////////////////4AAN//////////////////gAH/ + /////////////////+AH//////////////////////////////////////////////////////////// + //////////////////////////////////8= + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/SecureShare/ShareFileManagerInLocal.Designer.cs b/Demo_Source_Code/CSharpDemo/SecureShare/ShareFileManagerInLocal.Designer.cs new file mode 100644 index 0000000..2acc32d --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/SecureShare/ShareFileManagerInLocal.Designer.cs @@ -0,0 +1,105 @@ +namespace SecureShare +{ + partial class ShareFileManagerInLocal + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ShareFileManagerInLocal)); + this.groupBox2 = new System.Windows.Forms.GroupBox(); + this.listView_SharedFiles = new System.Windows.Forms.ListView(); + this.button_Delete = new System.Windows.Forms.Button(); + this.button_CreateShareEncryptedFile = new System.Windows.Forms.Button(); + this.groupBox2.SuspendLayout(); + this.SuspendLayout(); + // + // groupBox2 + // + this.groupBox2.Controls.Add(this.listView_SharedFiles); + this.groupBox2.Location = new System.Drawing.Point(23, 24); + this.groupBox2.Name = "groupBox2"; + this.groupBox2.Size = new System.Drawing.Size(538, 235); + this.groupBox2.TabIndex = 17; + this.groupBox2.TabStop = false; + this.groupBox2.Text = "Shared Files With Revoke Access Control"; + // + // listView_SharedFiles + // + this.listView_SharedFiles.Dock = System.Windows.Forms.DockStyle.Fill; + this.listView_SharedFiles.FullRowSelect = true; + this.listView_SharedFiles.GridLines = true; + this.listView_SharedFiles.Location = new System.Drawing.Point(3, 16); + this.listView_SharedFiles.MultiSelect = false; + this.listView_SharedFiles.Name = "listView_SharedFiles"; + this.listView_SharedFiles.Size = new System.Drawing.Size(532, 216); + this.listView_SharedFiles.TabIndex = 0; + this.listView_SharedFiles.UseCompatibleStateImageBehavior = false; + this.listView_SharedFiles.View = System.Windows.Forms.View.Details; + // + // button_Delete + // + this.button_Delete.Location = new System.Drawing.Point(435, 281); + this.button_Delete.Name = "button_Delete"; + this.button_Delete.Size = new System.Drawing.Size(123, 23); + this.button_Delete.TabIndex = 19; + this.button_Delete.Text = "Delete Shared File"; + this.button_Delete.UseVisualStyleBackColor = true; + this.button_Delete.Click += new System.EventHandler(this.button_Delete_Click); + // + // button_CreateShareEncryptedFile + // + this.button_CreateShareEncryptedFile.Location = new System.Drawing.Point(26, 281); + this.button_CreateShareEncryptedFile.Name = "button_CreateShareEncryptedFile"; + this.button_CreateShareEncryptedFile.Size = new System.Drawing.Size(127, 23); + this.button_CreateShareEncryptedFile.TabIndex = 18; + this.button_CreateShareEncryptedFile.Text = "Create New Share File"; + this.button_CreateShareEncryptedFile.UseVisualStyleBackColor = true; + this.button_CreateShareEncryptedFile.Click += new System.EventHandler(this.button_CreateShareEncryptedFile_Click); + // + // ShareFilesManagerForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(584, 350); + this.Controls.Add(this.button_Delete); + this.Controls.Add(this.button_CreateShareEncryptedFile); + this.Controls.Add(this.groupBox2); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Name = "ShareFilesManagerForm"; + this.Text = "Share File Manager"; + this.groupBox2.ResumeLayout(false); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.GroupBox groupBox2; + private System.Windows.Forms.ListView listView_SharedFiles; + private System.Windows.Forms.Button button_Delete; + private System.Windows.Forms.Button button_CreateShareEncryptedFile; + } +} \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/SecureShare/ShareFileManagerInLocal.cs b/Demo_Source_Code/CSharpDemo/SecureShare/ShareFileManagerInLocal.cs new file mode 100644 index 0000000..beaf5a1 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/SecureShare/ShareFileManagerInLocal.cs @@ -0,0 +1,153 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +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; +using System.IO; + +using EaseFilter.FilterControl; +using EaseFilter.CommonObjects; + +namespace SecureShare +{ + public partial class ShareFileManagerInLocal : Form + { + + + public ShareFileManagerInLocal() + { + InitializeComponent(); + InitListView(); + StartPosition = FormStartPosition.CenterParent; + } + + public void InitListView() + { + listView_SharedFiles.Clear(); + //create column header for ListView + listView_SharedFiles.Columns.Add("fileName", 250, System.Windows.Forms.HorizontalAlignment.Left); + listView_SharedFiles.Columns.Add("creationTime",200, System.Windows.Forms.HorizontalAlignment.Left); + listView_SharedFiles.Columns.Add("expireTime", 200, System.Windows.Forms.HorizontalAlignment.Left); + listView_SharedFiles.Columns.Add("authorizedProcessNames", 200, System.Windows.Forms.HorizontalAlignment.Left); + listView_SharedFiles.Columns.Add("unauthorizedProcessNames", 200, System.Windows.Forms.HorizontalAlignment.Left); + listView_SharedFiles.Columns.Add("authorizedUserNames", 200, System.Windows.Forms.HorizontalAlignment.Left); + listView_SharedFiles.Columns.Add("unauthorizedUserNames", 200, System.Windows.Forms.HorizontalAlignment.Left); + listView_SharedFiles.Columns.Add("accessFlags", 200, System.Windows.Forms.HorizontalAlignment.Left); + + try + { + string[] sharedFiles = Directory.GetFiles(GlobalConfig.DRInfoFolder); + + foreach (string sharedFile in sharedFiles) + { + string fileName = string.Empty; + string expireTime = string.Empty; + string creationTime = string.Empty; + string authorizedProcessNames = string.Empty; + string unauthorizedProcessNames = string.Empty; + string authorizedUserNames = string.Empty; + string unauthorizedUserNames = string.Empty; + string accessFlags = string.Empty; + DateTime currentTime = DateTime.Now; + + Dictionary keyValues = new Dictionary(); + Utils.LoadAppSetting(sharedFile, ref keyValues); + + keyValues.TryGetValue("fileName", out fileName); + keyValues.TryGetValue("creationTime", out creationTime); + keyValues.TryGetValue("expireTime", out expireTime); + keyValues.TryGetValue("authorizedProcessNames", out authorizedProcessNames); + keyValues.TryGetValue("unauthorizedProcessNames", out unauthorizedProcessNames); + keyValues.TryGetValue("authorizedUserNames", out authorizedUserNames); + keyValues.TryGetValue("unauthorizedUserNames", out unauthorizedUserNames); + keyValues.TryGetValue("accessFlags", out accessFlags); + + + ListViewItem lvItem = new ListViewItem(); + string[] listData = new string[listView_SharedFiles.Columns.Count]; + listData[0] = fileName; + long dateTimeN = long.Parse(creationTime); + DateTime dateTimeD = DateTime.FromFileTime(dateTimeN).ToLocalTime(); + listData[1] = String.Format("{0:F}", dateTimeD); + dateTimeN = long.Parse(expireTime); + dateTimeD = DateTime.FromFileTime(dateTimeN).ToLocalTime(); + listData[2] = String.Format("{0:F}", dateTimeD); + listData[3] = authorizedProcessNames; + listData[4] = unauthorizedProcessNames; + listData[5] = authorizedUserNames; + listData[6] = unauthorizedUserNames; + listData[7] = accessFlags; + + lvItem = new ListViewItem(listData, 0); + lvItem.Tag = sharedFile; + + listView_SharedFiles.Items.Add(lvItem); + + } + } + catch + { + } + } + + private void button_CreateShareEncryptedFile_Click(object sender, EventArgs e) + { + ShareFileForm shareFileForm = new ShareFileForm(); + shareFileForm.ShowDialog(); + InitListView(); + } + + private void button_Delete_Click(object sender, EventArgs e) + { + button_Delete.Enabled = false; + + try + { + if (listView_SharedFiles.SelectedItems.Count != 1) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("Please select a file.", "Delete", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + string drFileName = (string)listView_SharedFiles.SelectedItems[0].Tag; + + File.Delete(drFileName); + + InitListView(); + + } + catch (Exception ex) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("Delete shared file failed with error " + ex.Message, "DeleteSharedFile", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + finally + { + button_Delete.Enabled = true; + } + } + + + } +} diff --git a/Demo_Source_Code/CSharpDemo/SecureShare/ShareFileManagerInLocal.resx b/Demo_Source_Code/CSharpDemo/SecureShare/ShareFileManagerInLocal.resx new file mode 100644 index 0000000..d4c25b6 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/SecureShare/ShareFileManagerInLocal.resx @@ -0,0 +1,168 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + AAABAAIAEBAAAAEACABoBQAAJgAAABAQAAABACAAaAQAAI4FAAAoAAAAEAAAACAAAAABAAgAAAAAAAAB + AAAAAAAAAAAAAAABAAAAAQAAAAAAAAAfKgAAPyoAVR8qAFU/KgAAXyoAAH8qAFVfKgBVP1UAVV9VAFV/ + VQBVf38Aqn9/AFWfVQBVv1UAVZ9/AFW/fwBV/38Aqp9/AAB/qgBVf6oAVd+qAACf1AAAn/8AVZ/UAFW/ + 1ABVn/8AVb//AFXf/wCAgIAAqp+qAKSgoACqv6oA/7+qAKrfqgDwyqYAqr/UAKq//wD/v9QAqt/UAKr/ + 1ACq3/8Aqv//AMDcwAD/zMwA/9/UAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA////AP8KBgUFAgEAAAAAAAAAAAANIhEiDQ8KAgAAAAAAAAAADyIiFQoO + DQIAAAAAAAAAAA8oIhAiChAJICAgICAgICAAHg///w8HHx0HCAQHBAggAAAJCAkKKy0rLCsjISMEIAAA + Hh4dCR0lGRMUExMsCCAEAysmHh0JJxsZFxgTIwQgCAggKyQeHSkbGxgXEy0EIAsJCQsJKx0pHBkbGRMs + BCAACR0eDAgeKSkcGRoWLAQgAB4LHQsgKikcJRwZFi0EIAAr////KSkpKRwbGxgrCCAAI/8nJycnJxsn + GRsZLQQgAB7///////////////8IIAASEhISEhISEhISEhISEgAB/wAAAP8AAAD/AAAAAAAAgAAAAMAA + AACAAAAAAAAAAAAAAAAAAAAAgAAAAIAAAACAAAAAgAAAAIAAAACAAQAAKAAAABAAAAAgAAAAAQAgAAAA + AABABAAAAAAAAAAAAAAAAAAAAAAAAP////9Vf1X/AH8q/wBfKv8AXyr/AD8q/wAfKv8AAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABVn1X/qt+q/1X/f/+q36r/VZ9V/1Wff/9Vf1X/AD8q/wAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVZ9//6rfqv+q36r/Vd+q/1V/Vf9Vv1X/VZ9V/wA/ + Kv8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFWff/+q/9T/qt+q/1W/f/+q36r/VX9V/1W/ + f/9VX1X/qr+q/6q/qv+qv6r/qr+q/6q/qv+qv6r/qr+q/6q/qv8AAAAAqp+q/1Wff////////////1Wf + f/9VXyr/pKCg/4CAgP9VXyr/VT9V/1U/Kv9VXyr/VT8q/1U/Vf+qv6r/AAAAAAAAAABVX1X/VT9V/1Vf + Vf9Vf1X/wNzA///f1P/A3MD//8zM/8DcwP/wyqb//7+q//DKpv9VPyr/qr+q/wAAAAAAAAD/qp+q/6qf + qv+AgID/VV9V/4CAgP+qv///Vb/U/wB/qv9Vf6r/AH+q/wB/qv//zMz/VT9V/6q/qv9VPyr/VR8q/8Dc + wP//v9T/qp+q/4CAgP9VX1X/qt/U/1W///9Vv9T/AJ///1Wf1P8Af6r/8Mqm/1U/Kv+qv6r/VT9V/1U/ + Vf+qv6r/wNzA/6q/1P+qn6r/gICA/6rf//9Vv///Vb///1Wf1P8An///AH+q///f1P9VPyr/qr+q/1V/ + f/9VX1X/VV9V/1V/f/9VX1X/wNzA/4CAgP+q3///Vd///1W/1P9Vv///Vb/U/wB/qv//zMz/VT8q/6q/ + qv8AAAAAVV9V/4CAgP+qn6r/qn9//1U/Vf+qn6r/qt///6rf//9V3///Vb/U/1Wf//8An9T//8zM/1U/ + Kv+qv6r/AAAAAKqfqv9Vf3//gICA/1V/f/+qv6r/qv///6rf//9V3///qr///1Xf//9Vv9T/AJ/U///f + 1P9VPyr/qr+q/wAAAADA3MD/////////////////qt///6rf//+q3///qt///1Xf//9Vv///Vb///1Wf + 1P/A3MD/VT9V/6q/qv8AAAAA8Mqm//////+q39T/qt/U/6rf1P+q39T/qt/U/1W///+q39T/Vb/U/1W/ + //9Vv9T//9/U/1U/Kv+qv6r/AAAAAKqfqv////////////////////////////////////////////// + //////////////////9VP1X/qr+q/wAAAACqn3//qp9//6qff/+qn3//qp9//6qff/+qn3//qp9//6qf + f/+qn3//qp9//6qff/+qn3//qp9//wAAAAAB/wAAAP8AAAD/AAAAAAAAgAAAAMAAAACAAAAAAAAAAAAA + AAAAAAAAgAAAAIAAAACAAAAAgAAAAIAAAACAAQAA + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/SecureShare/ShareFileManagerInServer.Designer.cs b/Demo_Source_Code/CSharpDemo/SecureShare/ShareFileManagerInServer.Designer.cs new file mode 100644 index 0000000..bf47bba --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/SecureShare/ShareFileManagerInServer.Designer.cs @@ -0,0 +1,187 @@ +namespace SecureShare +{ + partial class ShareFileManagerInServer + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ShareFileManagerInServer)); + this.imageList1 = new System.Windows.Forms.ImageList(this.components); + this.toolStrip2 = new System.Windows.Forms.ToolStrip(); + this.toolStripSeparator6 = new System.Windows.Forms.ToolStripSeparator(); + this.toolStripButton_RefreshList = new System.Windows.Forms.ToolStripButton(); + this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator(); + this.toolStripButton_CreateShareFile = new System.Windows.Forms.ToolStripButton(); + this.toolStripSeparator7 = new System.Windows.Forms.ToolStripSeparator(); + this.toolStripButton_RemoveShareFile = new System.Windows.Forms.ToolStripButton(); + this.toolStripSeparator8 = new System.Windows.Forms.ToolStripSeparator(); + this.toolStripButton_ModifyShareFile = new System.Windows.Forms.ToolStripButton(); + this.toolStripButton_AccessLog = new System.Windows.Forms.ToolStripButton(); + this.listView_SharedFiles = new System.Windows.Forms.ListView(); + this.toolStrip2.SuspendLayout(); + this.SuspendLayout(); + // + // imageList1 + // + this.imageList1.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imageList1.ImageStream"))); + this.imageList1.TransparentColor = System.Drawing.Color.Transparent; + this.imageList1.Images.SetKeyName(0, "folder_ok.png"); + // + // toolStrip2 + // + this.toolStrip2.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.toolStripSeparator6, + this.toolStripButton_RefreshList, + this.toolStripSeparator2, + this.toolStripButton_CreateShareFile, + this.toolStripSeparator7, + this.toolStripButton_RemoveShareFile, + this.toolStripSeparator8, + this.toolStripButton_ModifyShareFile, + this.toolStripButton_AccessLog}); + this.toolStrip2.Location = new System.Drawing.Point(0, 0); + this.toolStrip2.Name = "toolStrip2"; + this.toolStrip2.Size = new System.Drawing.Size(890, 27); + this.toolStrip2.TabIndex = 3; + this.toolStrip2.Text = "toolStrip2"; + // + // toolStripSeparator6 + // + this.toolStripSeparator6.Name = "toolStripSeparator6"; + this.toolStripSeparator6.Size = new System.Drawing.Size(6, 27); + // + // toolStripButton_RefreshList + // + this.toolStripButton_RefreshList.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton_RefreshList.Image"))); + this.toolStripButton_RefreshList.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButton_RefreshList.Name = "toolStripButton_RefreshList"; + this.toolStripButton_RefreshList.Size = new System.Drawing.Size(104, 24); + this.toolStripButton_RefreshList.Text = "Refresh List"; + this.toolStripButton_RefreshList.Click += new System.EventHandler(this.toolStripButton_RefreshList_Click); + // + // toolStripSeparator2 + // + this.toolStripSeparator2.Name = "toolStripSeparator2"; + this.toolStripSeparator2.Size = new System.Drawing.Size(6, 27); + // + // toolStripButton_CreateShareFile + // + this.toolStripButton_CreateShareFile.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton_CreateShareFile.Image"))); + this.toolStripButton_CreateShareFile.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButton_CreateShareFile.Name = "toolStripButton_CreateShareFile"; + this.toolStripButton_CreateShareFile.Size = new System.Drawing.Size(140, 24); + this.toolStripButton_CreateShareFile.Text = "Create Share File"; + this.toolStripButton_CreateShareFile.Click += new System.EventHandler(this.toolStripButton_CreateShareFile_Click); + // + // toolStripSeparator7 + // + this.toolStripSeparator7.Name = "toolStripSeparator7"; + this.toolStripSeparator7.Size = new System.Drawing.Size(6, 27); + // + // toolStripButton_RemoveShareFile + // + this.toolStripButton_RemoveShareFile.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton_RemoveShareFile.Image"))); + this.toolStripButton_RemoveShareFile.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButton_RemoveShareFile.Name = "toolStripButton_RemoveShareFile"; + this.toolStripButton_RemoveShareFile.Size = new System.Drawing.Size(156, 24); + this.toolStripButton_RemoveShareFile.Text = "Delete Shared Files"; + this.toolStripButton_RemoveShareFile.Click += new System.EventHandler(this.toolStripButton_RemoveShareFile_Click); + // + // toolStripSeparator8 + // + this.toolStripSeparator8.Name = "toolStripSeparator8"; + this.toolStripSeparator8.Size = new System.Drawing.Size(6, 27); + // + // toolStripButton_ModifyShareFile + // + this.toolStripButton_ModifyShareFile.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton_ModifyShareFile.Image"))); + this.toolStripButton_ModifyShareFile.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButton_ModifyShareFile.Name = "toolStripButton_ModifyShareFile"; + this.toolStripButton_ModifyShareFile.Size = new System.Drawing.Size(210, 24); + this.toolStripButton_ModifyShareFile.Text = "Modify Shared File Settings"; + this.toolStripButton_ModifyShareFile.Click += new System.EventHandler(this.toolStripButton_ModifyShareFile_Click); + // + // toolStripButton_AccessLog + // + this.toolStripButton_AccessLog.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton_AccessLog.Image"))); + this.toolStripButton_AccessLog.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButton_AccessLog.Name = "toolStripButton_AccessLog"; + this.toolStripButton_AccessLog.Size = new System.Drawing.Size(102, 24); + this.toolStripButton_AccessLog.Text = "Access Log"; + this.toolStripButton_AccessLog.Click += new System.EventHandler(this.toolStripButton_AccessLog_Click); + // + // listView_SharedFiles + // + this.listView_SharedFiles.Dock = System.Windows.Forms.DockStyle.Fill; + this.listView_SharedFiles.FullRowSelect = true; + this.listView_SharedFiles.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable; + this.listView_SharedFiles.HideSelection = false; + this.listView_SharedFiles.HoverSelection = true; + this.listView_SharedFiles.Location = new System.Drawing.Point(0, 27); + this.listView_SharedFiles.MultiSelect = false; + this.listView_SharedFiles.Name = "listView_SharedFiles"; + this.listView_SharedFiles.ShowItemToolTips = true; + this.listView_SharedFiles.Size = new System.Drawing.Size(890, 292); + this.listView_SharedFiles.TabIndex = 4; + this.listView_SharedFiles.UseCompatibleStateImageBehavior = false; + this.listView_SharedFiles.View = System.Windows.Forms.View.Details; + // + // ShareFileManagerInServer + // + this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 17F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(890, 319); + this.Controls.Add(this.listView_SharedFiles); + this.Controls.Add(this.toolStrip2); + this.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Name = "ShareFileManagerInServer"; + this.Text = "Secure File Sharing Manager In Server"; + this.toolStrip2.ResumeLayout(false); + this.toolStrip2.PerformLayout(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.ImageList imageList1; + private System.Windows.Forms.ToolStrip toolStrip2; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator6; + private System.Windows.Forms.ToolStripButton toolStripButton_RefreshList; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator2; + private System.Windows.Forms.ToolStripButton toolStripButton_CreateShareFile; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator7; + private System.Windows.Forms.ToolStripButton toolStripButton_RemoveShareFile; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator8; + private System.Windows.Forms.ToolStripButton toolStripButton_ModifyShareFile; + private System.Windows.Forms.ToolStripButton toolStripButton_AccessLog; + private System.Windows.Forms.ListView listView_SharedFiles; + } +} + diff --git a/Demo_Source_Code/CSharpDemo/SecureShare/ShareFileManagerInServer.cs b/Demo_Source_Code/CSharpDemo/SecureShare/ShareFileManagerInServer.cs new file mode 100644 index 0000000..3427430 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/SecureShare/ShareFileManagerInServer.cs @@ -0,0 +1,217 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.IO; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; +using System.Configuration; +using System.Diagnostics; +using System.Runtime.InteropServices; + +using EaseFilter.FilterControl; +using EaseFilter.CommonObjects; + +namespace SecureShare +{ + public partial class ShareFileManagerInServer: Form + { + DRPolicy selectedDRPolicy = new DRPolicy(); + public Dictionary sharedFileList = new Dictionary(); + + public ShareFileManagerInServer() + { + + InitializeComponent(); + StartPosition = FormStartPosition.CenterParent; + + GetSharedFileList(); + } + + public void InitShareFileListView() + { + listView_SharedFiles.Clear(); + //create column header for ListView + listView_SharedFiles.Columns.Add("FileName", 150, System.Windows.Forms.HorizontalAlignment.Left); + listView_SharedFiles.Columns.Add("CreationTime", 100, System.Windows.Forms.HorizontalAlignment.Left); + listView_SharedFiles.Columns.Add("ExpireTime", 100, System.Windows.Forms.HorizontalAlignment.Left); + listView_SharedFiles.Columns.Add("AuthorizedProcessNames", 100, System.Windows.Forms.HorizontalAlignment.Left); + listView_SharedFiles.Columns.Add("UnauthorizedProcessNames", 100, System.Windows.Forms.HorizontalAlignment.Left); + listView_SharedFiles.Columns.Add("AuthorizedUserNames", 100, System.Windows.Forms.HorizontalAlignment.Left); + listView_SharedFiles.Columns.Add("UnauthorizedUserNames", 100, System.Windows.Forms.HorizontalAlignment.Left); + + try + { + foreach (DRPolicy sharedFile in sharedFileList.Values) + { + int index = 0; + ListViewItem lvItem = new ListViewItem(); + string[] listEntry = new string[listView_SharedFiles.Columns.Count]; + + string fileName = sharedFile.FileName; + + if (fileName.EndsWith(GlobalConfig.ShareFileExt)) + { + fileName = fileName.Replace(GlobalConfig.ShareFileExt, ""); + } + + listEntry[index++] = fileName; + long dateTimeN = sharedFile.CreationTime; + DateTime dateTimeD = DateTime.FromFileTime(dateTimeN); + listEntry[index++] = dateTimeD.ToShortDateString();// String.Format("{0:F}", dateTimeD); + dateTimeN = sharedFile.ExpireTime; + dateTimeD = DateTime.FromFileTime(dateTimeN); + listEntry[index++] = dateTimeD.ToShortDateString();//String.Format("{0:F}", dateTimeD); + listEntry[index++] = sharedFile.AuthorizedProcessNames; + listEntry[index++] = sharedFile.UnauthorizedProcessNames; + listEntry[index++] = sharedFile.AuthorizedUserNames; + listEntry[index++] = sharedFile.UnauthorizedUserNames; + + lvItem = new ListViewItem(listEntry, 0); + lvItem.Tag = sharedFile; + + int insertIndex = 0; + if (listView_SharedFiles.Items.Count > 0) + { + for (insertIndex = 0; insertIndex < listView_SharedFiles.Items.Count; insertIndex++) + { + DRPolicy sharedFileInList = (DRPolicy)(listView_SharedFiles.Items[insertIndex]).Tag; + + if (sharedFile.CreationTime < sharedFileInList.CreationTime) + { + break; + } + } + + } + + listView_SharedFiles.Items.Insert(insertIndex, lvItem); + + } + } + catch + { + } + } + + public bool GetSharedFileList() + { + string lastError = string.Empty; + string encryptFileList = string.Empty; + + sharedFileList.Clear(); + + bool retVal = WebAPIServices.GetFileList( ref encryptFileList, ref lastError); + if (!retVal) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show(lastError, "GetFileList", MessageBoxButtons.OK, MessageBoxIcon.Error); + + return false; + } + else + { + if (encryptFileList.Length > 0) + { + List decrypFileList = Utils.DecryptStrToObject>(encryptFileList); + sharedFileList.Clear(); + + foreach (DRPolicy drPolicy in decrypFileList) + { + sharedFileList.Add(drPolicy.EncryptionIV, drPolicy); + } + } + + InitShareFileListView(); + + } + + return true; + } + + private void toolStripButton_RefreshList_Click(object sender, EventArgs e) + { + GetSharedFileList(); + } + + private void toolStripButton_CreateShareFile_Click(object sender, EventArgs e) + { + ShareFileForm shareFileForm = new ShareFileForm(); + + if (shareFileForm.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + GetSharedFileList(); + } + } + + private void toolStripButton_RemoveShareFile_Click(object sender, EventArgs e) + { + if (listView_SharedFiles.SelectedItems.Count != 1) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("Please select a file.", "Delete", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + DRPolicy drPolicy = (DRPolicy)listView_SharedFiles.SelectedItems[0].Tag; + string lastError = string.Empty; + + if (!WebAPIServices.DeleteShareFile(drPolicy.EncryptionIV, ref lastError)) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("Delete shared file " + selectedDRPolicy.FileName + " failed with error:" + lastError, "DeleteSharedFile", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + + GetSharedFileList(); + } + + private void toolStripButton_ModifyShareFile_Click(object sender, EventArgs e) + { + if (listView_SharedFiles.SelectedItems.Count != 1) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("Please select a file.", "Edit", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + DRPolicy drPolicy = (DRPolicy)listView_SharedFiles.SelectedItems[0].Tag; + + ShareFileForm shareFileForm = new ShareFileForm(drPolicy); + shareFileForm.Text = "EaseFilter Shared File Modification"; + + if (shareFileForm.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + GetSharedFileList(); + InitShareFileListView(); + } + } + + private void toolStripButton_AccessLog_Click(object sender, EventArgs e) + { + SharedFileAccessLogForm accessLog = new SharedFileAccessLogForm(); + accessLog.ShowDialog(); + } + + } +} diff --git a/Demo_Source_Code/CSharpDemo/SecureShare/ShareFileManagerInServer.resx b/Demo_Source_Code/CSharpDemo/SecureShare/ShareFileManagerInServer.resx new file mode 100644 index 0000000..621a3f3 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/SecureShare/ShareFileManagerInServer.resx @@ -0,0 +1,553 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 279, 17 + + + + AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w + LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 + ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAACQ + CwAAAk1TRnQBSQFMAwEBAAEwAQEBMAEBASABAAEgAQAE/wEJAQAI/wFCAU0BNgEEBgABNgEEAgABKAMA + AYADAAEgAwABAQEAAQgGAAEQGAABgAIAAYADAAKAAQABgAMAAYABAAGAAQACgAIAA8ABAAHAAdwBwAEA + AfABygGmAQABMwUAATMBAAEzAQABMwEAAjMCAAMWAQADHAEAAyIBAAMpAQADVQEAA00BAANCAQADOQEA + AYABfAH/AQACUAH/AQABkwEAAdYBAAH/AewBzAEAAcYB1gHvAQAB1gLnAQABkAGpAa0CAAH/ATMDAAFm + AwABmQMAAcwCAAEzAwACMwIAATMBZgIAATMBmQIAATMBzAIAATMB/wIAAWYDAAFmATMCAAJmAgABZgGZ + AgABZgHMAgABZgH/AgABmQMAAZkBMwIAAZkBZgIAApkCAAGZAcwCAAGZAf8CAAHMAwABzAEzAgABzAFm + AgABzAGZAgACzAIAAcwB/wIAAf8BZgIAAf8BmQIAAf8BzAEAATMB/wIAAf8BAAEzAQABMwEAAWYBAAEz + AQABmQEAATMBAAHMAQABMwEAAf8BAAH/ATMCAAMzAQACMwFmAQACMwGZAQACMwHMAQACMwH/AQABMwFm + AgABMwFmATMBAAEzAmYBAAEzAWYBmQEAATMBZgHMAQABMwFmAf8BAAEzAZkCAAEzAZkBMwEAATMBmQFm + AQABMwKZAQABMwGZAcwBAAEzAZkB/wEAATMBzAIAATMBzAEzAQABMwHMAWYBAAEzAcwBmQEAATMCzAEA + ATMBzAH/AQABMwH/ATMBAAEzAf8BZgEAATMB/wGZAQABMwH/AcwBAAEzAv8BAAFmAwABZgEAATMBAAFm + AQABZgEAAWYBAAGZAQABZgEAAcwBAAFmAQAB/wEAAWYBMwIAAWYCMwEAAWYBMwFmAQABZgEzAZkBAAFm + ATMBzAEAAWYBMwH/AQACZgIAAmYBMwEAA2YBAAJmAZkBAAJmAcwBAAFmAZkCAAFmAZkBMwEAAWYBmQFm + AQABZgKZAQABZgGZAcwBAAFmAZkB/wEAAWYBzAIAAWYBzAEzAQABZgHMAZkBAAFmAswBAAFmAcwB/wEA + AWYB/wIAAWYB/wEzAQABZgH/AZkBAAFmAf8BzAEAAcwBAAH/AQAB/wEAAcwBAAKZAgABmQEzAZkBAAGZ + AQABmQEAAZkBAAHMAQABmQMAAZkCMwEAAZkBAAFmAQABmQEzAcwBAAGZAQAB/wEAAZkBZgIAAZkBZgEz + AQABmQEzAWYBAAGZAWYBmQEAAZkBZgHMAQABmQEzAf8BAAKZATMBAAKZAWYBAAOZAQACmQHMAQACmQH/ + AQABmQHMAgABmQHMATMBAAFmAcwBZgEAAZkBzAGZAQABmQLMAQABmQHMAf8BAAGZAf8CAAGZAf8BMwEA + AZkBzAFmAQABmQH/AZkBAAGZAf8BzAEAAZkC/wEAAcwDAAGZAQABMwEAAcwBAAFmAQABzAEAAZkBAAHM + AQABzAEAAZkBMwIAAcwCMwEAAcwBMwFmAQABzAEzAZkBAAHMATMBzAEAAcwBMwH/AQABzAFmAgABzAFm + ATMBAAGZAmYBAAHMAWYBmQEAAcwBZgHMAQABmQFmAf8BAAHMAZkCAAHMAZkBMwEAAcwBmQFmAQABzAKZ + AQABzAGZAcwBAAHMAZkB/wEAAswCAALMATMBAALMAWYBAALMAZkBAAPMAQACzAH/AQABzAH/AgABzAH/ + ATMBAAGZAf8BZgEAAcwB/wGZAQABzAH/AcwBAAHMAv8BAAHMAQABMwEAAf8BAAFmAQAB/wEAAZkBAAHM + ATMCAAH/AjMBAAH/ATMBZgEAAf8BMwGZAQAB/wEzAcwBAAH/ATMB/wEAAf8BZgIAAf8BZgEzAQABzAJm + AQAB/wFmAZkBAAH/AWYBzAEAAcwBZgH/AQAB/wGZAgAB/wGZATMBAAH/AZkBZgEAAf8CmQEAAf8BmQHM + AQAB/wGZAf8BAAH/AcwCAAH/AcwBMwEAAf8BzAFmAQAB/wHMAZkBAAH/AswBAAH/AcwB/wEAAv8BMwEA + AcwB/wFmAQAC/wGZAQAC/wHMAQACZgH/AQABZgH/AWYBAAFmAv8BAAH/AmYBAAH/AWYB/wEAAv8BZgEA + ASEBAAGlAQADXwEAA3cBAAOGAQADlgEAA8sBAAOyAQAD1wEAA90BAAPjAQAD6gEAA/EBAAP4AQAB8AH7 + Af8BAAGkAqABAAOAAwAB/wIAAf8DAAL/AQAB/wMAAf8BAAH/AQAC/wIAA/8IAAP/CAAD/wT0A/9pAAL/ + AvQE/wQAAv8B8wHwAQcC7wEHAfAB8wL/aAAB/wHzAgcBvAHyAfQF/wH0AbwB7QFPAkkBTwHsAe0B9wHw + AfQB/2cAAfMCUQEcAfcBkgHvAQcB8QHzAfQB8wGYBAIDSAEnAewB7QG8AfQB/2UAAf8BmQExASoBMQIq + AXQBHAGSAfcB7wFyAQIFLQECA0gBcgHtAfAC/2QAAf8BUgFZASoDOAIxASoBHAFyAy0BVQF4ATQDLQEC + AkgB7AH3AfMB/2QAAfQBKgFeASoEWQE4AVkBeQECAS4BLQE0AfMB/wEbATQDLQECAUgBJwHtAfAB/2MA + Af8BGgExAeUBKgVZAXoBVgFPAi4B8QL0Af8BGwE0Ay0CSAHsAQcB9GMAAf8BeQFYAeUBKgVZAaABTwFW + AS0B8AH0BP8BGwE0Ai0BAgFIAU8B7wH0YwAB/wEqAuUBKwVZAaABLgGXAU8C/wGYAS4BCAL/ARsBNAIt + AUgBAgH3AfRiAAH/ARsBMQLlATEBegRZAaABLgF4AS4ClwE0AVUBLgEIAv8BGwE0AS0BSAECAfcB9GIA + Af8BmQFYAqABMQF6AeUCegFZAaABTwF4AVYCVQFWAlUBLgEIAv8BGwE0AQIBTwH3AfRiAAH/ASoDoAEx + AXoE5QGgAXgBVgF4BFYCVQEuAQgC/wGYAQIBUAH3AfRhAAH/ARsBMQOgATEBegXlAZ8BLgGYBVYCVQEu + AZgBCAFVAQIBHAH3AfRhAAH/AZkBeQOgATEBmgXlAaABeAFVAZgEVgNVAS4BLQECAZcBdAH3AfRhAAH/ + AUsDoAHDATEDoATlAaABUAFVAZgBeAJWA1UBNAEtAVABwwEqAfcB9GAAAf8BGwExAsMBoAHDATEGoALl + AcMBeAEuAVYCeAGXAVYBTwEtAZcCwwEqAfcB9GAAAf8BmQF5BMMBMQigAeUBoAEaAXgETwGXAZkDwwEq + AfcB9GAAAf8BSwXDATEBwwygAsMDoAPDASoB9wH0YAAB8gExAfYEwwExAcMKoAXlAXoEwwEqAfcB9GAA + ApkB/wH2A8MBMQLDC6AD5QGaBMMBKgH3AfRgAAFSATECUgJ5AaABMQTDCqAB5QF6BcMBKgH3AfRgAAH/ + AfQBGwIaAZkBeQExARoBmgF6A5oJoAGaBcMBKgH3AfRlAAL/AVIC9gTDAqADmgJ6AZoBegGgBcMBKgH3 + AfRnAAFSAvYFwwX2CcMBKgH3AfRnAAFSAfYB/wj2BMMB9gXDAfYBKgH3AfRnAAFYAXkCmQGaAxoBwwL2 + A/8I9gEqAfcB9GcAARsBGgOZA3kBWAJSATEBKgGZCPYBKgEHAfRpAAr/ARsBUgH/BvYBGgFRAfAB/3MA + Af8BMQf/AXQBHAHzAf90AAF5ATEDKwQqAfMC/3UACf9iAAFCAU0BPgcAAT4DAAEoAwABgAMAASADAAEB + AQABAQYAAQIWAAP/AQAB/gE/AcABDwwAAfgBBwGAAQcMAAH4AgABAwwAAfgCAAEBDAAB8A8AAfAPAAHw + DwAB4A8AAeAPAAHgDwABwA8AAcAPAAHADwABgA8AAYAPAAGAfwAB+A8AAf4PAAH+DwAB/g8AAf4PAAH/ + AYAOAAL/AeANAAL/AfANAAL/AfgBAwwACw== + + + + 730, 17 + + + + + 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 + SUVORK5CYII= + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAAEnQAABJ0Ad5mH3gAAAH2SURBVDhPrVNra9NgGM1/8mcpI9QmbdM26SVd7CxVNhmC + HwRxwgYOVHRY3cXipo66D8IQp8NKKbXYC71faHt8z2tqKO6DiAfOh7zkXJ7nTZT/huyLemH9aIRb+R5W + 91q4masj+6yKzOMyVra/4drWOZYffIJ97xRL2lbBlf3C2kG7cPp9ir/FyVlj0YTJhKqq8Pl88Pv9krqu + IxAIIBgMIhQKIRwOS45GI5jr7+DKFYW1iblY07QLhZFIBNFoVBpE1448A85MFItFlEollMtlVCoVVKtV + 1Go1NBoNtNtt9Ho9DIdDjMdjhG/kPQMujNi5pOCl4L5gXvBQkGLLshCLxRCPx5FIJDCZTBC6vucZcNtE + TghY2zAMWflYPDebTXQ6nYX02WyGgJPzDHhVxK4QHLjJbwXfC7J6MpmEbdtIpVJwHEe+q9k7ngHvmeC8 + 9Xpd1m61Wr+TB4OBXByrz3E19sQzcDa/yMP5xk3TlDNzXorPRJNzwaJgSZBQw9uegX3/ozxkYrfblan9 + fl/OzGSK0+k0MpkMKq7Bkr7pGSTufpCHTOc9c+tM59zT6RRf3WSKf7gGV3wbnoF156TAz5NpJDfNebnt + i/D6zWdcVjcW/wfr9nGBn2dk9RBG9hWCK7vQl5/Dn3gKn/kIqvFQ1mbyH+J/h6L8BMb9UobuNQmJAAAA + AElFTkSuQmCC + + + + + AAABAAEAQEAAAAEAIAAoQgAAFgAAACgAAABAAAAAgAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOTX0YDk19H/5NfR/+TX0f/k19H/5NfR/+TX + 0f/k19H/5NfR/+TX0f/k19H/5NfR/+TX0f/k19H/5NfR/+TX0f/k19H/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADRydP/RGLg/0Ri + 4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/+TX + 0f8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AADk19FARGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri + 4P9EYuD/RGLg/0Ri4P/k19H/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA5NfRQERi4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri + 4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/5NfR/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQjs4/0I7OP9COzj/Qjs4/0I7OP9COzj/Qjs4/0I7 + OP9COzj/Qjs4/0I7OP9COzj/Qjs4/0I7OP9COzj/Qjs4/0I7OP9COzj/Qjs4/0I7OP9COzj/Qjs4/0I7 + OP9COzj/Qjs4/0I7OP9COzj/Qjs4/0I7OP9COzj/Qjs4/2tiXv9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri + 4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/+TX0f8AAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEI7OP9fVVH/X1VR/19V + Uf9fVVH/X1VR/19VUf9fVVH/X1VR/19VUf9fVVH/X1VR/19VUf9fVVH/X1VR/19VUf9fVVH/X1VR/19V + Uf9fVVH/X1VR/19VUf9fVVH/X1VR/19VUf9fVVH/X1VR/19VUf9fVVH/X1VR/19VUf+AdnH/RGLg/0Ri + 4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri + 4P/k19H/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AABCOzj/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/iHx4/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri + 4P9EYuD/RGLg/0Ri4P9EYuD/5NfR/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAQjs4/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/4h8eP9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri + 4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/+TX0f8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEI7OP9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv+IfHj/RGLg/0Ri4P9EYuD/RGLg/0Ri + 4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P/k19H/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABCOzj/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/iHx4/0Ri + 4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri + 4P9EYuD/5NfR/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAQjs4/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/4h8eP9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri + 4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/+TX0f8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAEI7OP9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv+IfHj/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri + 4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P/k19H/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABCOzj/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/+TX0f+8utX/RGLg/0Ri + 4P9EYuD/vLrV/7y61f+8utX/vLrV/7y61f+8utX/vLrV/7y61f9EYuD/RGLg/0Ri4P/k19H/5NfR/wAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQjs4/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/5NfR/0Ri4P9EYuD/RGLg/+TX0f9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv/k19H/RGLg/0Ri + 4P9EYuD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAEI7OP9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/+TX0f9EYuD/RGLg/0Ri4P/k19H/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/5NfR/0Ri4P9EYuD/RGLg/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABCOzj/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv/k19H/RGLg/0Ri4P9EYuD/5NfR/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/+TX0f9EYuD/RGLg/0Ri4P8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQjs4/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/5NfR/0Ri + 4P9EYuD/RGLg/+TX0f9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv/k19H/RGLg/0Ri4P9EYuD/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEI7 + OP9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/+TX0f9EYuD/RGLg/0Ri4P/k19H/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/5NfR/0Ri + 4P9EYuD/RGLg/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAABCOzj/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv/k19H/RGLg/0Ri4P9EYuD/5NfR/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/1hx3v9EYuD/RGLg/0Ri4P8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQjs4/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/3dDK/0Ri4P9EYuD/RGLg/0Ri + 4P+XjIf/aV5a/2leWv9pXlr/aV5a/+TX0f9EYuD/RGLg/0Ri4P/k19H/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEI7OP9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv/k19H/RGLg/0Ri4P9EYuD/5NfR/9XIw/9pXlr/aV5a/+TX0f9EYuD/RGLg/0Ri4P9EYuD/5NfR/wAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AABCOzj/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/5NfR/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/vLrV/2x/3P9EYuD/RGLg/0Ri + 4P9EYuD/Tmnf/+TX0WAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAQjs4/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv/k19H/RGLg/0Ri4P9EYuD/RGLg/0Ri + 4P9EYuD/RGLg/0Ri4P9EYuD/RGLg/+TX0f8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEI7OP9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/+TX + 0f9EYuD/RGLg/0Ri4P9EYuD/RGLg/0Ri4P9EYuD/Tmnf/+TX0f8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABCOzj/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/5NfR/+TX0f+Kldn/RGLg/0Ri4P/k19H/5NfR/5eMh/8AAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAQjs4/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAEI7OP9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABCOzj/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQjs4/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAEI7OP9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABCOzj/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQjs4/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEI7 + OP+Ddm7/g3Zu/4N2bv+Ddm7/g3Zu/4N2bv+Ddm7/g3Zu/4N2bv+Ddm7/g3Zu/4N2bv+Ddm7/g3Zu/4N2 + bv+Ddm7/g3Zu/4N2bv+Ddm7/g3Zu/2tgW/9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/wAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAABCOzj/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19U + UP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP+Ddm7/bmNe/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQjs4/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19U + UP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/4N2 + bv9uY17/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEI7OP9fVFD/X1RQ/19U + UP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19U + UP9fVFD/X1RQ/19UUP9fVFD/g3Zu/4N2bv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2le + Wv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9pXlr/aV5a/2leWv9zZ2L/dmpk/wAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AABCOzj/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19U + UP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/T0ZD/0I7OP9COzj/Qjs4/0I7OP9COzj/Qjs4/0I7 + OP9COzj/Qjs4/0I7OP9COzj/Qjs4/0I7OP9COzj/Qjs4/0I7OP9COzj/Qjs4/0I7OP9COzj/Qjs4/wAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAQjs4/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19U + UP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/wAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEI7OP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19U + UP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19U + UP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABCOzj/X1RQ/19U + UP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19U + UP9fVFD/X1RQ/19UUP9fVFD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAQjs4/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19U + UP9fVFD/X1RQ/19UUP9fVFD/X1RQ/19UUP9fVFD/Qjs4/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABCOzigQjs4/0I7OP9COzj/Qjs4/0I7OP9COzj/Qjs4/0I7 + OP9COzj/Qjs4/0I7OP9COzj/Qjs4/0I7OP9COzj/Qjs4/0I7OP9COzj/Qjs4/wAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA//////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////+AAD///////4AAH///////AAAf/// + ///8AAB//gAAAAAAAH/+AAAAAAAAf/4AAAAAAAB//gAAAAAAAH/+AAAAAAAAf/4AAAAAAAB//gAAAAAA + AH/+AAAAAAAAf/4AAAAAAAB//gAAAAAAAf/+AAAAAAAB//4AAAAAAAH//gAAAAAAAf/+AAAAAAAB//4A + AAAAAAH//gAAAAAAAf/+AAAAAAAB//4AAAAAAAH//gAAAAAAA//+AAAAAAAH//4AAAAAAA///gAAAAAA + D//+AAAAAAAP//4AAAAAAA///gAAAAAAD//+AAAAAAAP//4AAAAAAA///gAAAAAAD//+AAAAAAAP//4A + AAAAAA///gAAAAAAD//+AAAAAAAP//4AAAAAAB///gAAB//////+AAAH//////4AAAf//////gAAB/// + ////AAAP//////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////8= + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/SecureShare/ShareFileSettingForm.Designer.cs b/Demo_Source_Code/CSharpDemo/SecureShare/ShareFileSettingForm.Designer.cs new file mode 100644 index 0000000..d779cfe --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/SecureShare/ShareFileSettingForm.Designer.cs @@ -0,0 +1,337 @@ +namespace SecureShare +{ + partial class ShareFileSettingForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ShareFileSettingForm)); + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.label7 = new System.Windows.Forms.Label(); + this.label9 = new System.Windows.Forms.Label(); + this.textBox_ShareFolderBlackList = new System.Windows.Forms.TextBox(); + this.label13 = new System.Windows.Forms.Label(); + this.textBox_ShareFolderWhiteList = new System.Windows.Forms.TextBox(); + this.label14 = new System.Windows.Forms.Label(); + this.label2 = new System.Windows.Forms.Label(); + this.label6 = new System.Windows.Forms.Label(); + this.button1 = new System.Windows.Forms.Button(); + this.textBox_ProtectFolder = new System.Windows.Forms.TextBox(); + this.label12 = new System.Windows.Forms.Label(); + this.textBox_ProtectFolderBlackList = new System.Windows.Forms.TextBox(); + this.label11 = new System.Windows.Forms.Label(); + this.textBox_ProtectFolderWhiteList = new System.Windows.Forms.TextBox(); + this.label10 = new System.Windows.Forms.Label(); + this.button_BrowseDRFolder = new System.Windows.Forms.Button(); + this.textBox_DRFolder = new System.Windows.Forms.TextBox(); + this.label1 = new System.Windows.Forms.Label(); + this.button_BrowseFolder = new System.Windows.Forms.Button(); + this.textBox_ShareFolder = new System.Windows.Forms.TextBox(); + this.button_help = new System.Windows.Forms.Button(); + this.button_ApplySetting = new System.Windows.Forms.Button(); + this.label3 = new System.Windows.Forms.Label(); + this.groupBox1.SuspendLayout(); + this.SuspendLayout(); + // + // groupBox1 + // + this.groupBox1.Controls.Add(this.label3); + this.groupBox1.Controls.Add(this.label7); + this.groupBox1.Controls.Add(this.label9); + this.groupBox1.Controls.Add(this.textBox_ShareFolderBlackList); + this.groupBox1.Controls.Add(this.label13); + this.groupBox1.Controls.Add(this.textBox_ShareFolderWhiteList); + this.groupBox1.Controls.Add(this.label14); + this.groupBox1.Controls.Add(this.label2); + this.groupBox1.Controls.Add(this.label6); + this.groupBox1.Controls.Add(this.button1); + this.groupBox1.Controls.Add(this.textBox_ProtectFolder); + this.groupBox1.Controls.Add(this.label12); + this.groupBox1.Controls.Add(this.textBox_ProtectFolderBlackList); + this.groupBox1.Controls.Add(this.label11); + this.groupBox1.Controls.Add(this.textBox_ProtectFolderWhiteList); + this.groupBox1.Controls.Add(this.label10); + this.groupBox1.Controls.Add(this.button_BrowseDRFolder); + this.groupBox1.Controls.Add(this.textBox_DRFolder); + this.groupBox1.Controls.Add(this.label1); + this.groupBox1.Controls.Add(this.button_BrowseFolder); + this.groupBox1.Controls.Add(this.textBox_ShareFolder); + this.groupBox1.Location = new System.Drawing.Point(12, 21); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size(628, 382); + this.groupBox1.TabIndex = 0; + this.groupBox1.TabStop = false; + // + // label7 + // + this.label7.AutoSize = true; + this.label7.Location = new System.Drawing.Point(211, 179); + this.label7.Name = "label7"; + this.label7.Size = new System.Drawing.Size(215, 13); + this.label7.TabIndex = 74; + this.label7.Text = "You can drop the encrypted file to this folder"; + // + // label9 + // + this.label9.AutoSize = true; + this.label9.Font = new System.Drawing.Font("Microsoft Sans Serif", 6.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.label9.Location = new System.Drawing.Point(212, 225); + this.label9.Name = "label9"; + this.label9.Size = new System.Drawing.Size(189, 12); + this.label9.TabIndex = 71; + this.label9.Text = "( split with \';\' , process format \"notepad.exe\" )"; + // + // textBox_ShareFolderBlackList + // + this.textBox_ShareFolderBlackList.Location = new System.Drawing.Point(215, 246); + this.textBox_ShareFolderBlackList.Name = "textBox_ShareFolderBlackList"; + this.textBox_ShareFolderBlackList.Size = new System.Drawing.Size(297, 20); + this.textBox_ShareFolderBlackList.TabIndex = 68; + this.textBox_ShareFolderBlackList.Text = "explorer.exe;"; + // + // label13 + // + this.label13.AutoSize = true; + this.label13.Location = new System.Drawing.Point(16, 246); + this.label13.Name = "label13"; + this.label13.Size = new System.Drawing.Size(147, 13); + this.label13.TabIndex = 70; + this.label13.Text = "Unauthorized process names"; + // + // textBox_ShareFolderWhiteList + // + this.textBox_ShareFolderWhiteList.Location = new System.Drawing.Point(215, 203); + this.textBox_ShareFolderWhiteList.Name = "textBox_ShareFolderWhiteList"; + this.textBox_ShareFolderWhiteList.Size = new System.Drawing.Size(297, 20); + this.textBox_ShareFolderWhiteList.TabIndex = 67; + this.textBox_ShareFolderWhiteList.Text = "*"; + // + // label14 + // + this.label14.AutoSize = true; + this.label14.Location = new System.Drawing.Point(19, 203); + this.label14.Name = "label14"; + this.label14.Size = new System.Drawing.Size(131, 13); + this.label14.TabIndex = 69; + this.label14.Text = "Authorized process names"; + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(211, 43); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(247, 13); + this.label2.TabIndex = 66; + this.label2.Text = "The file will be encrypted automatically in this folder"; + // + // label6 + // + this.label6.AutoSize = true; + this.label6.Location = new System.Drawing.Point(16, 23); + this.label6.Name = "label6"; + this.label6.Size = new System.Drawing.Size(133, 13); + this.label6.TabIndex = 65; + this.label6.Text = "RealTime Protected Folder"; + // + // button1 + // + this.button1.Location = new System.Drawing.Point(537, 15); + this.button1.Name = "button1"; + this.button1.Size = new System.Drawing.Size(31, 23); + this.button1.TabIndex = 64; + this.button1.Text = "..."; + this.button1.UseVisualStyleBackColor = true; + // + // textBox_ProtectFolder + // + this.textBox_ProtectFolder.Location = new System.Drawing.Point(215, 18); + this.textBox_ProtectFolder.Name = "textBox_ProtectFolder"; + this.textBox_ProtectFolder.Size = new System.Drawing.Size(297, 20); + this.textBox_ProtectFolder.TabIndex = 63; + // + // label12 + // + this.label12.AutoSize = true; + this.label12.Font = new System.Drawing.Font("Microsoft Sans Serif", 6.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.label12.Location = new System.Drawing.Point(212, 89); + this.label12.Name = "label12"; + this.label12.Size = new System.Drawing.Size(189, 12); + this.label12.TabIndex = 62; + this.label12.Text = "( split with \';\' , process format \"notepad.exe\" )"; + // + // textBox_ProtectFolderBlackList + // + this.textBox_ProtectFolderBlackList.Location = new System.Drawing.Point(215, 110); + this.textBox_ProtectFolderBlackList.Name = "textBox_ProtectFolderBlackList"; + this.textBox_ProtectFolderBlackList.Size = new System.Drawing.Size(297, 20); + this.textBox_ProtectFolderBlackList.TabIndex = 59; + this.textBox_ProtectFolderBlackList.Text = "explorer.exe;"; + // + // label11 + // + this.label11.AutoSize = true; + this.label11.Location = new System.Drawing.Point(16, 110); + this.label11.Name = "label11"; + this.label11.Size = new System.Drawing.Size(147, 13); + this.label11.TabIndex = 61; + this.label11.Text = "Unauthorized process names"; + // + // textBox_ProtectFolderWhiteList + // + this.textBox_ProtectFolderWhiteList.Location = new System.Drawing.Point(215, 67); + this.textBox_ProtectFolderWhiteList.Name = "textBox_ProtectFolderWhiteList"; + this.textBox_ProtectFolderWhiteList.Size = new System.Drawing.Size(297, 20); + this.textBox_ProtectFolderWhiteList.TabIndex = 58; + this.textBox_ProtectFolderWhiteList.Text = "*"; + // + // label10 + // + this.label10.AutoSize = true; + this.label10.Location = new System.Drawing.Point(19, 67); + this.label10.Name = "label10"; + this.label10.Size = new System.Drawing.Size(131, 13); + this.label10.TabIndex = 60; + this.label10.Text = "Authorized process names"; + // + // button_BrowseDRFolder + // + this.button_BrowseDRFolder.Location = new System.Drawing.Point(537, 301); + this.button_BrowseDRFolder.Name = "button_BrowseDRFolder"; + this.button_BrowseDRFolder.Size = new System.Drawing.Size(31, 23); + this.button_BrowseDRFolder.TabIndex = 6; + this.button_BrowseDRFolder.Text = "..."; + this.button_BrowseDRFolder.UseVisualStyleBackColor = true; + // + // textBox_DRFolder + // + this.textBox_DRFolder.Location = new System.Drawing.Point(215, 301); + this.textBox_DRFolder.Name = "textBox_DRFolder"; + this.textBox_DRFolder.Size = new System.Drawing.Size(297, 20); + this.textBox_DRFolder.TabIndex = 4; + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(19, 159); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(118, 13); + this.label1.TabIndex = 1; + this.label1.Text = "Shared File Drop Folder"; + // + // button_BrowseFolder + // + this.button_BrowseFolder.Location = new System.Drawing.Point(537, 154); + this.button_BrowseFolder.Name = "button_BrowseFolder"; + this.button_BrowseFolder.Size = new System.Drawing.Size(31, 23); + this.button_BrowseFolder.TabIndex = 1; + this.button_BrowseFolder.Text = "..."; + this.button_BrowseFolder.UseVisualStyleBackColor = true; + this.button_BrowseFolder.Click += new System.EventHandler(this.button_BrowseFolder_Click); + // + // textBox_ShareFolder + // + this.textBox_ShareFolder.Location = new System.Drawing.Point(214, 154); + this.textBox_ShareFolder.Name = "textBox_ShareFolder"; + this.textBox_ShareFolder.Size = new System.Drawing.Size(298, 20); + this.textBox_ShareFolder.TabIndex = 0; + // + // button_help + // + this.button_help.Image = ((System.Drawing.Image)(resources.GetObject("button_help.Image"))); + this.button_help.Location = new System.Drawing.Point(34, 413); + this.button_help.Name = "button_help"; + this.button_help.Size = new System.Drawing.Size(36, 33); + this.button_help.TabIndex = 77; + this.button_help.UseVisualStyleBackColor = true; + this.button_help.Click += new System.EventHandler(this.button_help_Click); + // + // button_ApplySetting + // + this.button_ApplySetting.DialogResult = System.Windows.Forms.DialogResult.OK; + this.button_ApplySetting.Location = new System.Drawing.Point(505, 423); + this.button_ApplySetting.Name = "button_ApplySetting"; + this.button_ApplySetting.Size = new System.Drawing.Size(75, 23); + this.button_ApplySetting.TabIndex = 2; + this.button_ApplySetting.Text = "Apply"; + this.button_ApplySetting.UseVisualStyleBackColor = true; + this.button_ApplySetting.Click += new System.EventHandler(this.button_ApplySettings_Click); + // + // label3 + // + this.label3.AutoSize = true; + this.label3.Location = new System.Drawing.Point(19, 301); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(133, 13); + this.label3.TabIndex = 75; + this.label3.Text = "The DRM data store folder"; + // + // ShareFileSettingForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(664, 474); + this.Controls.Add(this.button_help); + this.Controls.Add(this.button_ApplySetting); + this.Controls.Add(this.groupBox1); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "ShareFileSettingForm"; + this.Text = "Shared File Settings"; + this.groupBox1.ResumeLayout(false); + this.groupBox1.PerformLayout(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.GroupBox groupBox1; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Button button_BrowseFolder; + private System.Windows.Forms.TextBox textBox_ShareFolder; + private System.Windows.Forms.Button button_ApplySetting; + private System.Windows.Forms.Button button_BrowseDRFolder; + private System.Windows.Forms.TextBox textBox_DRFolder; + private System.Windows.Forms.Label label7; + private System.Windows.Forms.Label label9; + private System.Windows.Forms.TextBox textBox_ShareFolderBlackList; + private System.Windows.Forms.Label label13; + private System.Windows.Forms.TextBox textBox_ShareFolderWhiteList; + private System.Windows.Forms.Label label14; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.Label label6; + private System.Windows.Forms.Button button1; + private System.Windows.Forms.TextBox textBox_ProtectFolder; + private System.Windows.Forms.Label label12; + private System.Windows.Forms.TextBox textBox_ProtectFolderBlackList; + private System.Windows.Forms.Label label11; + private System.Windows.Forms.TextBox textBox_ProtectFolderWhiteList; + private System.Windows.Forms.Label label10; + private System.Windows.Forms.Button button_help; + private System.Windows.Forms.Label label3; + } +} \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/SecureShare/ShareFileSettingForm.cs b/Demo_Source_Code/CSharpDemo/SecureShare/ShareFileSettingForm.cs new file mode 100644 index 0000000..9503537 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/SecureShare/ShareFileSettingForm.cs @@ -0,0 +1,116 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.IO; +using System.Windows.Forms; + +using EaseFilter.CommonObjects; + +namespace SecureShare +{ + public partial class ShareFileSettingForm : Form + { + + public ShareFileSettingForm() + { + StartPosition = FormStartPosition.CenterScreen; + InitializeComponent(); + + this.textBox_DRFolder.Text = GlobalConfig.DRInfoFolder; + this.textBox_ShareFolder.Text = GlobalConfig.ShareFolder; + this.textBox_ShareFolderWhiteList.Text = GlobalConfig.ShareFolderWhiteList; + this.textBox_ShareFolderBlackList.Text = GlobalConfig.ShareFolderBlackList; + this.textBox_ProtectFolder.Text = GlobalConfig.ProtectFolder; + this.textBox_ProtectFolderWhiteList.Text = GlobalConfig.ProtectFolderWhiteList; + this.textBox_ProtectFolderBlackList.Text = GlobalConfig.ProtectFolderBlackList; + + } + + private void button_BrowseFolder_Click(object sender, EventArgs e) + { + FolderBrowserDialog fbd = new FolderBrowserDialog(); + if (fbd.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + textBox_ShareFolder.Text = fbd.SelectedPath; + } + } + + private void button_ApplySettings_Click(object sender, EventArgs e) + { + if (textBox_ShareFolder.Text.Length == 0) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("The share file folder name can't be empty.", "share file folder", MessageBoxButtons.OK, MessageBoxIcon.Error); + return ; + } + + if (textBox_DRFolder.Text.Length == 0) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + MessageBox.Show("The DR folder name can't be empty.", "share file folder", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + GlobalConfig.ProtectFolder = textBox_ProtectFolder.Text; + GlobalConfig.ProtectFolderWhiteList = textBox_ProtectFolderWhiteList.Text; + GlobalConfig.ProtectFolderBlackList = textBox_ProtectFolderBlackList.Text; + + GlobalConfig.ShareFolder = textBox_ShareFolder.Text; + GlobalConfig.ShareFolderWhiteList = textBox_ShareFolderWhiteList.Text; + GlobalConfig.ShareFolderBlackList = textBox_ShareFolderBlackList.Text; + + GlobalConfig.StoreSharedFileMetaDataInServer = false; + GlobalConfig.DRInfoFolder = textBox_DRFolder.Text; + + if (!Directory.Exists(GlobalConfig.ShareFolder)) + { + Directory.CreateDirectory(GlobalConfig.ShareFolder); + } + + if (!Directory.Exists(GlobalConfig.ProtectFolder)) + { + Directory.CreateDirectory(GlobalConfig.ProtectFolder); + } + + if (!Directory.Exists(GlobalConfig.DRInfoFolder)) + { + Directory.CreateDirectory(GlobalConfig.DRInfoFolder); + } + + GlobalConfig.SaveConfigSetting(); + + this.Close(); + } + + private void button_help_Click(object sender, EventArgs e) + { + MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); + string helpInfo = "1.Protected folder is a real time encryption and decryption folder, if you copy a file to this folder, it will be encrypted automatically with default 256 bits encryption key and a random unique iv, so don't copy the encrypted files this folder, or it will be encrypted again. if you want to copy the encrypted file out of this folder, you need to add the process name to unauhtorized process list, for example if you copy it with Windows explorer, then add explorer.exe to the black list.\r\n\r\n"; + helpInfo += "2.Shared file drop folder, you can copy the encrypted share files to this folder, this folder won't encrypt the new created file, but it can decrypt the encrypted file automatically for the authorized processes.\r\n\r\n"; + helpInfo += "3.When you create the encrypted file from share file manager, the meta data of the encrypted file will be stored in local or in server, if you store the meta data in server, you can grant or revoke access rights anytime anywhere.\r\n"; + + MessageBox.Show(helpInfo, "How to set the configuration?", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + } +} diff --git a/Demo_Source_Code/CSharpDemo/SecureShare/ShareFileSettingForm.resx b/Demo_Source_Code/CSharpDemo/SecureShare/ShareFileSettingForm.resx new file mode 100644 index 0000000..c7f1985 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/SecureShare/ShareFileSettingForm.resx @@ -0,0 +1,615 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + 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 + DPgfKTU+503JE84AAAAASUVORK5CYII= + + + + + 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 + qLcAAAAAAAAAAAAAAAAAAAAAioF8/42Dff+2sKz/AH+y/53N1v9cusv/WLnL/1W4y/9Pt8n/M+L//y3Q + 7v8gsd3/DIa2/wBuoeQAAAAAAAAAAIp+eP//////+vTp/wCBtP/H8vb/k+jz/47l8f+N5PH/X7rL/0Xi + //9F4P//RuL//z/P8P8AbaD/AAAAAAAAAACThn///////+POxP8AhLf/x+He/5XS0v+U1tr/muv0/27A + y/9c6v//WOn//1bk/v9k2u3/AG+i/wAAAAAAAAAAm46H///////i0Mn/AIa5/9Pl4v+m3Nf/pN7d/6rw + 9f99xsz/c/P//2zw//9MyeP/qv///wBypf8AAAAAAAAAAKGUjf//////4tDK/x+Ww//b5eL/st3X/7Lh + 3f+49vn/jMvQ/4X2//9+9f//Xcvf/9H///8AdKf/AAAAAAAAAACilY7///////79/f8Air3/2O/z//Hu + 6/+v5u3/uPD0/6LP0f+U+P//ZdLn/6r0+f/a////AHeq/wAAAAAAAAAAopWO///////l1dH/AI3A/+HP + xv/fycH/wd7h/77m7v+8ys3/Zcbf/1/C2//T////5////wB5rP8AAAAAAAAAAKSWjv///////////x6e + zv8noMv/O6jP/43M5P+409v/z97e//H////m////3v////P///8AfK//AAAAAAAAAACqnJT///////// + ///+/fv/vrOu/76zrv9nq8T/JpG6/ACKwfUUkMD8////////////////AH6x/wAAAAAAAAAAq52V//// + ///+/v7//vz6/5iIgP/y5Nz/pJSM/5iIgFgAAAAAAIu+9u32+v///////////wB+sf8AAAAAAAAAAKud + lf+rnZX/o5OL/56Ohv+YiID/pJSM/5iIgFgAAAAAAAAAAACSzLoAhrn/AIS3/wCCtf8AcqedAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAD//wAA4f8AAOA/AADABwAAgAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAIABAACAAQAAgEEAAIDB + AAD//wAAKAAAABgAAAAwAAAAAQAIAAAAAACgAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8ACqLTAKKf + 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 + 5v/mw73/IIaw/7bt7f+b3eL/mtzg/5na3v+Y2dz/l9XY/57o8P+g6/P/f8LG/0rp//9M5P//TeL//07h + //9Jz+r/s////ySLtv8AAAAAAAAAAAAAAACin57h/////+7q6//oxsL/HYa0/8Xy8f+l4uP/peLh/6Tf + 3/+j393/otvZ/6nu8f+r8fP/iMXH/1ru//9Z6f//Wej//1Tg+f+A5vP/vf///yWNt/8AAAAAAAAAAG3E + 7xWPkpP5//////Lu7f/rxb3/Goe1/9T48f+x5uT/sObi/6/j4P+v497/rN/a/7Xy8v+39fT/lMvJ/2n0 + //9m7f//Ze///17a7v+5////xf///ymPuP8AAAAAAAAAAA2EtW+KjpD///////r29v/729P/HIy4/935 + 8/+25eL/uOXf/7fi3v+14tz/s97Y/7zz8v++9/X/nM3K/3T2//9x8P//aur8/4/p8v/D////z////yiP + uP8AAAAAAAAAAAd/s9Gin5z/////////////////I5vI//H////P////zf///8n8+//H9vb/w/Du/8P2 + 9//H+Pb/os7L/331//968v//bt/w/8T9/f/H////1v///yqRuf8AAAAAAAAAAByXzXKfnJzw//////bx + 8P/qxb3/FIq4/+358//G6Ob/yOjm/8nr6P/I7On/yO3q/8z39//O9/j/q9DM/4b4//+A7/7/mOjy/9X/ + ///L////3////yuQu/8AAAAAAAAAAAAAAACxrqzh//////7///////3/HZrI//z////V9fT/1PPx/9Hv + 7f/R7ej/zuji/9T29v/V+fj/sc/N/43o+P+A3/D/zv39/9b////T////6P///yyRuv8AAAAAAAAAAAAA + AACysrLh////////////////HZ3L///////3////9P////D////P5+X/0ero/87n5P/I4d//tdDN/+n/ + ///j////3v///9v////a////7////y6TvP8AAAAAAAAAAAAAAAC2trTh////////////////FpzK/0Ox + 1v9MtNf/W7rZ/2vC4P9ywdr/hcvi/5HL3P+TxNP/vOXu//T////j////4////+P////i////+v///zCT + vP8AAAAAAAAAAAAAAAC2tLTh//////7+/v/////////////////x9/n/3+70/9bt9v9vhoz/mJ2c/0R4 + jc8LmtVjAHy2yPr////3////9P////T////z/////////x6Kt+wAAAAAAAAAAAAAAAC2tbXh//////// + //////////////////////////////////+Jf3v/i4KAv5OMiQ8AAAAAHKTXZH7D2//K6PL/xObv/8no + 8f/M6vL/td3p/wF5rZ4AAAAAAAAAAAAAAACkpKTLq6ur6qmpqfCqqqr2qqqq+6qqqv6rqqr/rays/6uq + qv95enqrjY6OCAAAAAAAAAAAd8zvEBiSv20NibluCoW1bgGAs24AfrFuAHWrbkecwigAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA////AP///wD9//8A+D//AMAD/wDAAH8AwAAHAMAAAQDAAAEAwAABAMAAAQDAAAEAwAABAIAA + AQCAAAEAgAABAMAAAQDAAAEAwAABAMAAAQDABgEAwA8DAP///wD///8AKAAAACAAAABAAAAAAQAIAAAA + AACABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8ABKrdAKaKfgB18f8A5r+2AElvgwBesb4AAHClADLZ + /wC45eEAlMfFADmOtwDs4N8Aenp6AGHM5gDQnocANrfTANH//wCn//8AAIvAAArH9wCKprIAlN3jAK+i + mgBU5f8AxbexAJGSkwAZgK0A6rSbACOfywCx0M4AE+L/ACS86gBbmLAA29DNAH/L4wBAzOoA0O3qAD+o + vwC68vkAdrrCAFa42gD77+sAgN/vAHCjuwD72NAAo+nuAIaGhgDp//8Ai+z7ABRyogAAfLIAZ+b3APHK + wwBJlLkAxt7WAB/U/QBrtdEAS6nOAI3R1gCm4eAAE5fGAETf/wAPvekAOoOmADWm0ABsydkAVdryAG/S + 5wCXjIcA4LWoAMLn8AAuyO4Awf//AOnq6wDb9/UAo8nHAFO2ywAAn9IAj8/nAB2MtwAtvt4A8PT0AAtq + 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 + 3v+W2Nz/ldfb/5TU1/+c5u7/nez2/5zl7P92usL/Sub//0vj//9L4v//TOD//07h//9AzOr/i+z7/6n/ + //8Aa5//AAAAAAAAAAAAAAAAn5qYGoaFhf/+/v7/9Pb2/+PZ2f/qycP/DIKy/6Hd5/+j5OT/oeDj/6Df + 4f+f3uD/nt3f/57c3f+d2tv/nNfY/6Pp7/+j7/X/o+jt/3y9wf9V6P//Uub//1Pl//9U5f//VOD9/1PQ + 6P+t/P//rv///wBrof8AAAAAAAAAAAAAAABustFOjYaE///////4+fr/5dvb/+3KxP8HgLP/ruLp/6vm + 5v+o4+T/p+Li/6fh4f+m4N//pd/e/6Td3P+j2tr/qezx/6zy9/+s6+3/g8DC/17r//9b6f//W+j//1vp + //9V2vL/g+j1/7D8//+2////AGyh/wAAAAAAAAAAAAAAACaVw6OViYX///////r7+//n3dz/8MnB/wOB + tP+55uv/surl/6/m5P+w5eP/ruTh/63j4P+s4d7/q+Dd/6ve2f+y8PD/s/b4/7Pv7v+LxcT/ae7//2Tu + //9j6///Y+v//1rU5/+1/v//s////7z///8Ab6T/AAAAAAAAAADo9P8KAHis8JqOiP///////f7+/+re + 2//vx73/A4G0/77o7P+46eb/tefk/7Tm4/+05eL/s+Tg/7Lj3/+x4t3/sODb/7jy8v+5+Pj/ufHu/5HH + xP9x8v//bPD//2rw//9n5vf/guXw/8D///+7////w////wFvpP8AAAAAAAAAADOSulAPhLH/mIyG//// + ////////9fHw///p4f8Dhbj/xerw/77r6P+55uL/uOTg/7fj4P+4497/t+Le/7bi3P+13tn/vfPx/735 + +f+98u//lsbF/3bx/v9y8f//b/D//2bZ7P+z+vv/wf///77////I////AHCm/wAAAAAAAAAAGYKyq4rM + 3/+Wi4f///////7//////////////wiOwv/O9fr/1P///83////N////yPv6/8b19f/C8vD/wO3r/77p + 5P/C9PP/wvj4/8Lx7/+bx8b/ffH//3nx//9y6vv/f+Dv/83////E////xP///87///8AcqX/AAAAAAAA + AAAFeqzzHYy3/5yQi////////////+7l5P/72ND/AIW5/8/w8//R+PX/zPf2/835+P/O/Pv/zv7//8/+ + ///N/f//zPz9/8j5+f/H9/j/x/Hw/6DJxv+D8///f/P//3Th8v+v9Pj/zP///8f////J////0v///wBx + p/8AAAAAAAAAAILP7SRPmbtampGO////////////7ODf//HLxP8AhLj/0u3w/87r6f/I5uT/x+Xi/8bk + 4P/F5N//xuPe/8bl4P/G5eD/y/Tz/834+P/N8/D/pcnH/4r0//+F8f//f9zt/9b////O////zf///87/ + ///Y////AHOn/wAAAAAAAAAAAAAAAKKalxmWlZT////////////7+vr////5/wCLv//Y8/f/2/f1/9Ly + 8P/R7+3/zuzo/8zm4//J4t7/yOLc/8be1v/P8/H/0fr6/9Hz8f+pysj/g+P0/3zg8/+s7/f/2P///9L/ + ///S////0////97///8Ac6j/AAAAAAAAAAAAAAAAoKCgGZaWlv//////////////////////AIrA/+P6 + /P/n////3v///9/////f////3v///+D////e////2/v6/9j6+v/W9/j/0u3q/6vHx//F9vv/uvL5/9n/ + /f/Y////1////9f////a////3P///wV2qv8AAAAAAAAAAAAAAACenp4ZmZmZ//////////////////// + //8AisD/8P/+//v////x////7v///+r////q////udTT/7nX1v+72Nj/utnZ/7rY2P+x0M7/rMzM/+T/ + ///f////3f///9z////c////3P///93////h////A3eq/wAAAAAAAAAAAAAAAK6urhmZmZn///////// + /////////////wCLwf9/y+P/nNjq/6rc7P+44/D/x+vz/9nz+f/Q5Of/7vb0//b28P/79er/7+zk/+Xo + 4v/0////5f///+L////i////4f///+H////h////5P///+j///8Dd6z/AAAAAAAAAAAAAAAAra2tGZqa + mv//////////////////////j8/n/1a42v9GsNX/NabQ/yOfy/8Tl8b/CZPF/wB/tf8Agbv/AH+6/wB9 + uv8Afbj/AHu0/6zc6//y////5////+f////n////5v///+b////p////7////wN4rP8AAAAAAAAAAAAA + AACurq4ZmZmZ///////+/v7//v7+/////////////////////////////////////f//////ppmU/+q0 + m//Qnof/h3p02rW6uC0ypdB7S6nO///////t////7f///+z////s////7P////T////C5/D/BHmt2QAA + AAAAAAAAAAAAAJ6enhmZmZn///////39/f/+/v7//v7+//7+/v/8/Pz/+/z8//n5+f/39/f/9fX1//// + //+Rk5X/ppCH/3l+fdeYmJgcAAAAAKbs/ycAhr3//////////////////////////////////////2u1 + 0f8Zh7KNAAAAAAAAAAAAAAAAoKCgGZubm////////v7+//////////////////////////////////// + /////////////4SEhP9+foDXkpKSGQAAAAAAAAAAAAAAAAWWzt0Ae7L/AHyx/wB7sf8Ae7D/AH2w/wB8 + sP8MgrP/AHSs/2q/40IAAAAAAAAAAAAAAACmpqYVjo6O2IeHh9+Dg4PlhIWF64SCgvKDhIT3hYOD+4OD + g/6FhYX/h4eH/4iIh/+Li4r/fX190IWFhRcAAAAAAAAAAAAAAAAAAAAA2Pz/E77i6iaSx+Eml8vjJobC + 2SZjsdMmaLTVJkOiwiZuvOElAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///////////h////wD///gAH//4AAH/+AA + AP/gAAAf4AAAA+AAAAHgAAAB4AAAAeAAAAHgAAAB4AAAAeAAAAHAAAABwAAAAYAAAAGAAAABgAAAAcAA + AAHgAAAB4AAAAeAAAAHgAAAB4AAAAeAAEAHgADgB4AB4A+AA////////KAAAADAAAABgAAAAAQAIAAAA + AACACgAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8ACqrcAKaKfgB18P8A18C8AElvgwBesb4AA3KlADHX + /wC55eEAlLbGADGRtQDq4+AAe3t7AGHM5gDOo44ANLrYANH//wCn+f8AAozAAAzI9wCYpa4AltvjALSn + oABV5f8Az7iyAJGRkQAifqkA5rWdACSfyQCw0dIAE+L/ACC/7ABdla4A2NLQAH7K4ABDzOoAz+zrAEOq + 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 + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAV3 + rTcAap3bAG+h1gBwopkAcaZKAHiSCQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAFwp74SsuD/C57N/wGDtf8Chbj/AG+k8AB0qqsAd7BcAHe0EwAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGpq + agh7e3srXFxcBgAAAAAAAAAAAIOvDQBqoPYl3P//F7Tg/wSOwP8P2v//C8z7/wer3f8Di73/AHKm+AB2 + q7wAeK9tAIC1IQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAHd3eCBxcXH+cHFx73JzdMB3dHOKSm9+gQ+Dr/8t5///HsDq/wSJu/8X2f//FNP//xPT + //8S1v//DtH//wqz4/8Fk8X/AXaq/AB1qs4Ad69/AHizMQCQigIAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAHZ2diB6eHj/z7ux/7SnoP+fl5L/jIWC/3lzb/9rc3P/Q4KX/weH + uP8nzfL/HdT8/xnX//8X1f//F9X//xTV//8U1v//Edb//wu86/8Gm8z/AXqt/gBvpd0AeK+RAHmwQgCQ + vwYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHV1dSB6enn/2cvE/9TGwP/Wx8H/2MrC/9fI + wv/Nvrf/ip6m/wmCsf9Ps8r/Qqm//zytx/80uNb/K8Lk/yPM8/8b1f//F9f//xbW//8U1///Edf//w3D + 8/8JotL/A4G0/wBupOsAdaqjAHasVAB5tw4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH9/fyB8e3z/39fU/9jS + 0P/Y0s//2dLP/9rS0P/e1dH/p73G/w+IuP943PD/ctbs/2nP5f9fxtz/VrvS/0yxx/9Dqb7/O7HK/zO7 + 2f8oxOf/Hs73/xXW//8U2P//Fdj//xPM+v8Nqdr/Bom6/wBwpPUAdaq1AHavZgB9thkAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH5+ + fiB8fX3/5OTj/9/f3//e39//3t/f/+Df3//j4eD/qsfS/xCKuP9/4/X/dd3y/3bc8v933PH/dt3y/3fc + 8/912/H/a9Hm/2DG3P9Xus//TK/E/0Srwf86s87/L73d/yfH7f8e0f3/Gtn//xnS//8SseH/CZDB/wBy + p/wAcqnHAHeudwB8sykAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAH5+fiB9fX3/5ebk/+Dg4P/g4OD/4eHh/+Hi4//l5OP/rMjV/xCKuf+G5Pf/et7y/3rd + 8v953fL/ed3x/3jd8f953PH/eN3y/3nc8f943fL/ed7z/3Xa7/9rz+L/YMTY/1a4zf9MrsL/RK7E/zu3 + 0v8wxef/Idf//yLU//8ZuOf/DpbH/wN2qv4AcabYAHOriQV5sTsAQYoEAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAH5+fiCAfn7/5+bm/+Li4v/i4uL/4uLh/9C7tP/ZyMT/prrE/xGM + uv+O6Pj/fuH0/37h9P9/4fP/fd/z/33f8v983vL/fN7y/3ve8f973vH/et3w/3ve8f963fD/edzw/3rd + 8f963fD/ctDh/2O/0P9Es8v/JNX//yfU//8n1P//KdX//ynW//8hvu7/E5zO/wV7rf8AbaDmAXOonAB1 + q0wAZbYLAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH5+fiCAf3//6ujo/+Pj4//l5eX/4+Tj/8qv + p//Osqr/mqSp/xCKuP+M1+L/e9Lf/33W5f9+2en/gd3u/4Lg8/+C4/T/gOLz/4Hh8/9/3/P/f9/x/37e + 8f9+3vD/fd7w/3zd8f973O//edbm/3DK2v9Ht83/Kdj//yrV//8r1P//K9P//yzT//8t0///L9X//zDV + //8pxvX/GaPV/wd+sP8AbKHvAHaqKQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH5+fiCBgoD/6urr/+Xl + 5f/l5eX/5ebl/8uzq//Ptq7/m6eu/xOLuf+U2uT/ftDd/37Q3P9+z9z/fc/a/33O2v9+z9z/f9Th/4DX + 5f+B3Or/g9/u/4Ti8/+C4fL/guHw/4Hf8P+A3vD/ftfn/3TL2f9Muc3/Ldr//y/X//8w1v//MNX//zHU + //8x1P//MdP//zLS//8z0v//MtD8/zbL7P9Br9L/AGqelQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH5+ + fiCEgoP/7O3r/+fn5//n5+f/6Ofn/821rv/SuLH/nKew/xOMuv+c3+b/gtLe/4PS3v+C0t3/gtHc/4HR + 3P+B0Nv/gM/a/4DP2f+Aztj/f8zW/3/N1/+A0Nv/hd3s/4bh8P+F4PD/g9nm/3nN2v9Rus3/Mtz//zTZ + //802P//Ndf//zXW//821v//NtX//zfU//831P//Mcjx/1rZ8/9u2PD/AGedygAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAIiIiCCEg4P/7u3t/+np6f/p6en/6unp/862sf/SurT/namz/xONu/+j4Oj/h9Xg/4jV + 3/+H1N7/h9Pe/4bT3f+G0tz/htLb/4XR2v+E0dn/hNDY/4PP2P+DztX/iNzp/4vk8v+K4vH/iNvn/37P + 2v9Wvc7/N97//znb//852v//Otr//zrZ//872P//O9f//zzW//891v//McTo/3/r/P954PT/AGie1gAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAIeHhyCFhIT/8fDw/+vr6//r6+v/6uvr/8+5tP/TvLf/nqu1/xSP + u/+r5en/jNjh/43X4P+M1t//jNbf/4zV3v+L1d3/itTc/4rT2/+K09r/idLZ/4nR2P+I0Nb/j97q/5Dm + 8/+P5PH/jd3p/4PR2/9bv9D/POD//z7e//8+3f//P9z//z/b//8/2v//QNn//0HY//8/0/n/R83p/5Pz + //983/P/AGee1gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIeHhyCGh4X/8vLy/+zs7P/u7u7/7e3t/9C7 + t//Uvrr/n624/xSQvP+z6Ov/kdri/5LZ4f+R2eH/kdjg/5DY3/+Q197/j9bd/4/W3P+O1dv/jtTa/43T + 2f+N09j/kuDq/5Xo8/+U5vL/kN/o/4jT2/9gwc//QeP//0Pg//9D3///RN7//0Td//9F3P//Rdv//0fb + //9Azu//bt/0/5b0//+A4fP/AGqf1gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIeHhyCJh4j/9PTz/+7u + 7v/u7u7/7+/v/9K9u//XwL3/oLC6/xaSvf+66u7/ltzj/5fc4v+W2+H/ltrh/5ba3/+V2d//ldje/5TY + 3f+T19z/k9bb/5LV2v+S1df/l+Lr/5rq9P+Z6PP/l+Ho/4zV3P9lw8//R+X//0ji//9I4f//SeH//0nf + //9K3///St///0rd/v9Byuf/lfL9/5j0//+E4/P/AGuf1gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIeH + hyCJiIj/9vX1//Dw8P/w8PD/8fHw/9O/vf/YxMD/oLK9/xeTvv/C7e7/m9/k/5ze4/+b3eL/m93h/5rc + 4P+a29//mdve/5na3f+Y2dz/mNjb/5fY2v+X19j/nObr/5/t9P+e6vP/muPq/5HX3P9rxdH/Tef//03k + //9N5P//TuL//07i//9P4f//T+D//03Y9v9i2e7/oPf//573//+K5PP/AGqg1gAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAIiHhiCLi4n/9/f3//Ly8v/y8vL/8/Ly/9TBwP/ZxsT/obK//xeTv//I8fH/oOHl/6Hg + 5P+h4OP/oN/i/6De4f+f3uD/nt3f/57c3v+d3N3/ndvc/5za2/+c2dr/oefs/6Tv9f+j7vT/n+Xp/5bZ + 3f9wx9D/VOr//1Ln//9T5v//U+X//1Tk//9U4///VuP//03S6/+N7Pn/o/f//6P3//+N5vP/AGqg1gAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAGCDli+OjIn/+fn5//Pz8//09PT/9PT0/9XCwf/ax8X/obTA/xqW + wP/O8vH/pePl/6bj5P+m4uP/peHi/6Xg4f+k4OD/pN/f/6Pe3v+i3d3/ot3c/6Hc2/+h29n/puns/6nx + 9f+o8PT/pufr/5vb3f91ydD/Wuz//1jp//9Y6P//WOf//1nm//9Z5f//WeL7/13W6v+r+///pvj//6j5 + //+R6fT/AGuh1gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB6AqniTjYv/+/r6//X19f/39/f/9vb2/9bD + wf/bxsX/mbLA/yGawv/U9PL/q+Xm/6vk5f+r5OT/quPj/6rj4v+p4uH/qOHg/6jg3/+n397/p9/d/6be + 3P+l3dv/q+vt/67z9v+t8PT/qenq/6Dd3v97zNL/Yu7//1/r//9d6v//Xun//17o//9g6P//W9vy/4Xp + 9f+v+///q/r//638//+W6vT/AGuh1gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9/sMqVjov//fz8//f3 + 9//39/f/+Pj3/9jDwf/eyMP/mrLA/yObxf/b9/T/sOfm/7Dm5f+x5+T/r+Xj/7Dk4v+u5OH/r+Pg/63i + 3/+s4d7/rOLd/6vg3P+r39r/su7t/7P19v+z9PX/r+vs/6Xf3v+AztH/Z/D//2Xt//9j7P//Y+v//2Pq + //9k6v7/YNfq/676/v+y/P//sPz//7L+//+V6PL/AGyh0AAAAAAAAAAAAAAAAAAAAAAAAAAAAIG7Iw98 + qfyVkIv//v7+//n6+v/5+fn/+vn5/9nEv//ex8T/m7LA/yScxP/f+PP/tOjm/7Tn5f+z5+T/s+bj/7Ll + 4v+y5eH/s+Tg/7Hj3/+y4t7/sOLd/6/h3P+v4Nr/tu7u/7n39/+29PX/tO7r/6ri3v+Fz9H/bvL//2vv + //9o7v//aO3//2ju//9n5Pb/geXx/7v///+2/v//tv7//7n///+Y6PD/AGyizQAAAAAAAAAAAAAAAAAA + AAAAAAAAAH20ek+kwv+Ujov///////r6+v/7+/v/+/v7/9nCvf/exsH/nLK+/yWdxf/i9/P/uejm/7fo + 5f+35+T/tubj/7bm4v+15eL/teTg/7Tk3/+0497/s+Ld/7Lh3P+y4dr/uPDu/7v39/+79vT/t+3r/63j + 3/+J0NP/c/P//3Dw//9t7///bO7//23u//9p3O7/qvj7/73///+6////uv///73///+c6fD/AGyizQAA + AAAAAAAAAAAAAAAAAAAAAAABAHev0KTZ5P+RjIv///////z9/f/+/v7//f7+//Hp5//z5eL/p8XS/yWe + xv/m+vb/v+ro/7vn5f+65uP/uuXi/7nm4/+45eL/uOTh/7fk4P+349//tuPe/7bi3f+14dr/ve/u/773 + 9/+99fb/ue3r/7Hi3/+M0dL/dvP//3Tw//9x7///b+7//3Dp+/974e//xP///77///++////vf///7// + //+f6fD/AG2jzQAAAAAAAAAAAAAAAAAAAAAAebEsCX+v/t77+f+Pi4v///////39/f/+/v7//v////// + ////////t97t/yiiy//u////z////8v9/v/J+/r/x/j3/8T19P/C8e//wO7r/77r6P+86OT/uuPf/7nh + 3P+44Nr/v+/t/8H4+P/A9fb/vu/t/7Ti3/+Q0dT/evP//3jw//917///c+///3Hi8/+h8Pf/w////8H/ + ///B////wf///8T///+i6fD/AG2jzQAAAAAAAAAAAAAAAAAAAAAAdKeBaLfR/+v//P+Qjoz///////7+ + /v////////////z7+v//////uN/u/ymjy//x////1P///87////N////zv7+/8z9/f/L/f3/yvz8/8v8 + /P/K+/z/yfv7/8j4+f/G9vX/xvf3/8b39//D9/X/we7s/7bi4P+U0dP/fvP//33x//968f//d+39/3fe + 7v/G/v7/xv///8T////E////xP///8f///+k6fD/AG2jzQAAAAAAAAAAAAAAAAAAAAAAdanEGIa0/z+Z + vP+Zk5D//////////////////v7+/9rFwf/gysf/mLXE/y2jyv/t/fn/0vTz/8v08//M9fT/zvn4/876 + +f/O+/z/zv7+/878/f/N+/v/zPv8/8r6+v/J+fn/yfn5/8j39//I9vf/xO7s/7ni4P+X0tP/hPT//4Hx + //9+8f//eeb1/5zs9f/L////yP///8j////I////x////8r///+n6fD/AHCmzQAAAAAAAAAAAAAAAAAA + AAAAf7YPAH22MSR9omKbl5P//////////////////v7+/9zHxv/izMr/lLbG/zKlzP/t+Pb/0e3s/8jq + 6P/I6ef/x+jm/8bm4//G5+L/xeXh/8bo5f/H6eb/x+vn/8fs6f/I7uz/yvT1/8v39//K9vf/xvDu/77k + 4P+b0tX/iPT//4Xx//+C8P//fN7t/8T8/f/N////zP///8v////L////y////87///+q6fD/AG+lzQAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAJ2YliCYl5X//////////////////v39/9rGxf/gy8r/k7TF/zKl + zP/v+fX/1e7t/8vq6P/L6ef/yujm/8ro5f/J5+T/yObi/8jl4f/H5OD/x+Te/8bi3f/F4dr/zPDu/874 + +P/N9vf/y+/t/8Hj4P+e0tX/jPX//4ry//+E6fj/mOfz/9P////P////z////8/////P////zv///9H/ + //+u6fD/AG+lzQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJiYmCCYmJn///////////////////////// + ////////qdfo/zWq0P/1//7/3/j5/9T08//T8/L/0vDu/9Du6//O6+j/zObj/8vl4f/K5N//yuTe/8nj + 3P/J4dr/z/Du/9H5+f/R9/f/zvDu/8Tk4P+f0NP/h+b1/4fn9v+B4PD/w/j8/9X////T////0v///9L/ + ///S////0v///9X///+w6fH/AG+nzQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJiYmCCZmZn///////// + ////////////////////////qNjp/zqt0//5////6P///97////e////3v///93////c/v//3P3+/9r9 + /f/Z+vr/1/f2/9X08//S8O7/1fb1/9X4+P/T9fX/zu3r/8Tg3f+u09T/wff7/7Xx+P+z8Pj/2f///9b/ + ///W////1v///9b////V////1f///9j///+r5O7/AHGlxQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJeX + lyCampv/////////////////////////////////otbp/0Kx1f/6////6v///+D////g////4P7+/9/+ + /v/e/f3/3fz8/938/P/d/P3/3P39/9v6+//Z+Pj/1fX1/9Px8f/Q7u7/zebk/8Ha2P+219f/3v///9z/ + ///c////2////9r////Z////2f///9n////Z////2f///93///+t5O7/AHClxQAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAKKioiCbnJr/////////////////////////////////otbp/0Ky1f/9////8P///+n/ + ///o////5/7+/+X+/v/j/f3/4vz8/9r29v+yz8//t9TU/7vY2P+82dn/vtna/7/a2v+82Nn/t9PS/63K + y//N7e3/3v///93////d////3f///93////c////3P///9z////c////3P///97///+w5O7/AHCnxQAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAKChoSCcm5v/////////////////////////////////otfp/0i0 + 2P/////////////////+/////v////3////7////+/////n////g6ej/8Pn1/+fw7v/h7On/2+fk/9bj + 4P/R3tv/wdbV/9Tr6//l////4f///+H////h////4P///+D////g////4P///+D////g////3////+L/ + //+y5O7/AHCmxQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKChoSCenZ3///////////////////////// + ////////p9rr/wCNw/8Zn8z/IqPP/zCq0f8+rtT/SbPW/1e62f9jv9v/cMTe/37K4P93vNH/ltDg/6DS + 3/+r1d7/udjd/8La2/+509j/2u/x//j////v////5f///+T////k////5P///+T////k////5P///+P/ + ///j////4////+f///+15O7/AHCmxQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKCgoSCenJ3///////// + /////////////////////////////9vv9//P6vT/wOTw/7Le7P+k1+n/l9Dl/4fK4P95w93/bLzY/2G4 + 1v8nhaj/PZm6/zKUt/8ljrP/FIiw/wKDsv0AiMHiAH+38CWZxP//////6P///+j////o////6P///+f/ + ///n////5////+f////n////5////+r///+75e//AHGnxQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKCh + oSCcnZv///////7+/v/+/v7//////////////////////////////////////////////fz///38///8 + +///+vn///r4/////P+Mh4b/4byp/+a1nf/XpY3/jIB8/I+IhWkAAAAAAAAAAACCuPv/////7f///+v/ + ///q////6v///+r////q////6f///+n////p////6f////H///+u3On/AG+mugAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAKGhoSCbm5r///////7+/v/9/f3//v7+//7+/v/+/v7//v7+//7+/v/9/f3//Pz8//v7 + +//6+vr/+fn5//j4+P/29vb/9fX1//r6+v+Fh4j/1K+c/8uijv+DgX77h4iJYwAAAAAAAAAAAAAAAACF + wdHO6/P/9////+7////u////7v///+3////t////7f///+3////t////7v////r///9er87/AHWqeAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAKKioiCampn///////v7+//8/Pz//Pz8//39/f/9/f3//f39//z8 + /P/8/Pz/+/v7//r6+v/5+fn/+Pj4//b29v/19fX/8/Pz//j4+P+AgoT/yaKO/4WCgPuIiYpkAAAAAAAA + AAAAAAAAAAAAAACLx5CFx97///////n////3////+P////b////2////9f////b////0////9P////// + //8LgLH/AHetLgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJeXlyCampn///////z8/P/9/f3//P39//7+ + /f/9/vz//f78//z8/P/8/Pz/+/v7//r6+v/4+fn/9/j4//b39//19PT/9PT0//Hx8f9+f37/h4OB/IuM + jGUAAAAAAAAAAAAAAAAAAAAAAAAAAACPyU8ynsj/0Orz/8zp8f/Q6vL/0Ory/9Dq8v/X7vT/2e/1/9nw + 9f/X7vX/4vX5/8jn8f8Ac67gAIqBAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJiYmCCVlZb/zszJ/87L + yv/Qzcz/1NHP/9bT0v/Y1dP/2tfV/97a1//f3Nj/4t3b/+Tg3f/l4d//5uLf/+rj4P/r5eH/7efl/8zI + xf99fn78jo6PXwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACLwBAAgra6AHyyxAB5sMoAeK/NAHeuzQB1 + q80AdavTAHOq1gBwqdYAcKfWAG+n3gBzqN8Agbp+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJaW + lhKQkJCPj4+Pl42NjZ2NjY2ijY2NqYuLi7CLi4y1ioqKvImJicSIiIjJhoeHzoWFhtaEhITcgoOD4oOD + hOiBgoLvf4CA9ICAgOqHh4dZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////AAD///////8AAP/j/////wAA/8A///// + AAD/wAf///8AAPgAAP///wAA+AAAH///AAD4AAAB//8AAPgAAAA//wAA+AAAAAf/AAD4AAAAAP8AAPgA + AAAAHwAA+AAAAAAHAAD4AAAAAAMAAPgAAAAAAwAA+AAAAAADAAD4AAAAAAMAAPgAAAAAAwAA+AAAAAAD + AAD4AAAAAAMAAPgAAAAAAwAA+AAAAAADAADwAAAAAAMAAPAAAAAAAwAA8AAAAAADAADgAAAAAAMAAOAA + AAAAAwAA4AAAAAADAADAAAAAAAMAAMAAAAAAAwAA8AAAAAADAAD4AAAAAAMAAPgAAAAAAwAA+AAAAAAD + AAD4AAAAAAMAAPgAAAAAAwAA+AAAAAADAAD4AAAAAAMAAPgAAAAAAwAA+AAABgADAAD4AAAOAAMAAPgA + AB4ABwAA+AAAPwAHAAD4AAB/AAcAAPgAAP///wAA////////AAD///////8AAP///////wAA + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/SecureShare/SharedFileAccessLogForm.Designer.cs b/Demo_Source_Code/CSharpDemo/SecureShare/SharedFileAccessLogForm.Designer.cs new file mode 100644 index 0000000..81e8dca --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/SecureShare/SharedFileAccessLogForm.Designer.cs @@ -0,0 +1,115 @@ +namespace SecureShare +{ + partial class SharedFileAccessLogForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(SharedFileAccessLogForm)); + this.toolStrip1 = new System.Windows.Forms.ToolStrip(); + this.toolStripButton1 = new System.Windows.Forms.ToolStripButton(); + this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); + this.listView_AccessLog = new System.Windows.Forms.ListView() ; + this.toolStripButton_ClearMessage = new System.Windows.Forms.ToolStripButton(); + this.toolStrip1.SuspendLayout(); + this.SuspendLayout(); + // + // toolStrip1 + // + this.toolStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.toolStripButton1, + this.toolStripSeparator1, + this.toolStripButton_ClearMessage}); + this.toolStrip1.Location = new System.Drawing.Point(0, 0); + this.toolStrip1.Name = "toolStrip1"; + this.toolStrip1.Size = new System.Drawing.Size(961, 25); + this.toolStrip1.TabIndex = 3; + this.toolStrip1.Text = "toolStrip1"; + // + // toolStripButton1 + // + this.toolStripButton1.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton1.Image"))); + this.toolStripButton1.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButton1.Name = "toolStripButton1"; + this.toolStripButton1.Size = new System.Drawing.Size(123, 22); + this.toolStripButton1.Text = "Refresh access log"; + this.toolStripButton1.Click += new System.EventHandler(this.toolStripButton_GetAccessLog_Click); + // + // toolStripSeparator1 + // + this.toolStripSeparator1.Name = "toolStripSeparator1"; + this.toolStripSeparator1.Size = new System.Drawing.Size(6, 25); + // + // listView_AccessLog + // + this.listView_AccessLog.Dock = System.Windows.Forms.DockStyle.Fill; + this.listView_AccessLog.FullRowSelect = true; + this.listView_AccessLog.HoverSelection = true; + this.listView_AccessLog.LabelEdit = true; + this.listView_AccessLog.Location = new System.Drawing.Point(0, 25); + this.listView_AccessLog.Name = "listView_AccessLog"; + this.listView_AccessLog.ShowItemToolTips = true; + this.listView_AccessLog.Size = new System.Drawing.Size(961, 521); + this.listView_AccessLog.TabIndex = 4; + this.listView_AccessLog.UseCompatibleStateImageBehavior = false; + this.listView_AccessLog.View = System.Windows.Forms.View.Details; + // + // toolStripButton_ClearMessage + // + this.toolStripButton_ClearMessage.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton_ClearMessage.Image"))); + this.toolStripButton_ClearMessage.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButton_ClearMessage.Name = "toolStripButton_ClearMessage"; + this.toolStripButton_ClearMessage.Size = new System.Drawing.Size(111, 22); + this.toolStripButton_ClearMessage.Text = "Clear access log"; + this.toolStripButton_ClearMessage.Click += new System.EventHandler(this.toolStripButton_ClearMessage_Click); + // + // SharedFileAccessLogForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(961, 546); + this.Controls.Add(this.listView_AccessLog); + this.Controls.Add(this.toolStrip1); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Name = "SharedFileAccessLogForm"; + this.Text = "Shared Files Access Log"; + this.Shown += new System.EventHandler(this.AccessLogForm_Shown); + this.toolStrip1.ResumeLayout(false); + this.toolStrip1.PerformLayout(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.ToolStrip toolStrip1; + private System.Windows.Forms.ToolStripButton toolStripButton1; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator1; + private System.Windows.Forms.ListView listView_AccessLog; + private System.Windows.Forms.ToolStripButton toolStripButton_ClearMessage; + } +} \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/SecureShare/SharedFileAccessLogForm.cs b/Demo_Source_Code/CSharpDemo/SecureShare/SharedFileAccessLogForm.cs new file mode 100644 index 0000000..f2b7bbe --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/SecureShare/SharedFileAccessLogForm.cs @@ -0,0 +1,172 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011 EaseFilter Technologies +// All Rights Reserved +// +// This software is part of a licensed software product and may +// only be used or copied in accordance with the terms of that license. +// +// NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +// +// This module contains sample code provided for convenience and +// demonstration purposes only,this software is provided on an +// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. +// +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.IO; +using System.Windows.Forms; + +using EaseFilter.FilterControl; +using EaseFilter.CommonObjects; + +namespace SecureShare +{ + public partial class SharedFileAccessLogForm : Form + { + public string accessLogStr = string.Empty; + + public SharedFileAccessLogForm() + { + this.StartPosition = FormStartPosition.CenterParent; + InitializeComponent(); + + toolStripButton_GetAccessLog_Click(null,null); + + InitListView(); + } + + public void InitListView() + { + + listView_AccessLog.Clear(); + //create column header for ListView + listView_AccessLog.Columns.Add("Status", 80, System.Windows.Forms.HorizontalAlignment.Left); + listView_AccessLog.Columns.Add("AccessTime",160, System.Windows.Forms.HorizontalAlignment.Left); + listView_AccessLog.Columns.Add("UserName",100, System.Windows.Forms.HorizontalAlignment.Left); + listView_AccessLog.Columns.Add("ProcessName",100, System.Windows.Forms.HorizontalAlignment.Left); + listView_AccessLog.Columns.Add("FileName",150, System.Windows.Forms.HorizontalAlignment.Left); + listView_AccessLog.Columns.Add("Location", 200, System.Windows.Forms.HorizontalAlignment.Left); + listView_AccessLog.Columns.Add("Description", 350, System.Windows.Forms.HorizontalAlignment.Left); + + try + { + if( accessLogStr.Length == 0 ) + { + return; + } + + string accessLog = Utils.AESEncryptDecryptStr(accessLogStr, Utils.EncryptType.Decryption); + StringReader sr = new StringReader(accessLog); + + while (true) + { + string accessInfo = sr.ReadLine().Trim(); + if (string.IsNullOrEmpty(accessInfo)) + { + break; + } + + try + { + + string[] infos = accessInfo.Split(new char[] { '|' }); + + if (infos.Length < 7) + { + continue; + } + + ListViewItem lvItem = new ListViewItem(); + string[] listData = new string[listView_AccessLog.Columns.Count]; + + if (infos[0].Trim() == "1") + { + listData[0] = "Authorized"; + } + else + { + listData[0] = "Denied"; + listData[6] = infos[6].Trim(); + } + + long accessTimeL = 0; + + if (long.TryParse(infos[1].Trim(), out accessTimeL)) + { + DateTime accessTime = DateTime.FromFileTime(accessTimeL); + listData[1] = accessTime.ToString("F"); + } + + listData[2] = infos[2].Trim(); + listData[3] = infos[3].Trim(); + listData[4] = infos[4].Trim(); + listData[5] = infos[5].Trim(); + + lvItem = new ListViewItem(listData, 0); + + if (infos[0].Trim() == "0") + { + lvItem.BackColor = Color.LightGray; + lvItem.ForeColor = Color.Red; + } + + + listView_AccessLog.Items.Add(lvItem); + } + catch + { + } + } + + } + catch + { + } + } + + private void AccessLogForm_Shown(object sender, EventArgs e) + { + InitListView(); + } + + + private void toolStripButton_GetAccessLog_Click(object sender, EventArgs e) + { + string logStr = string.Empty; + string lastError = string.Empty; + + bool retVal = WebAPIServices.GetAccessLog( ref logStr, ref lastError); + + if (retVal) + { + accessLogStr = logStr; + InitListView(); + } + + } + + private void toolStripButton_ClearMessage_Click(object sender, EventArgs e) + { + string lastError = string.Empty; + + bool retVal = WebAPIServices.ClearAccessLog(ref lastError); + + if (retVal) + { + accessLogStr = string.Empty; + InitListView(); + } + } + + + } +} diff --git a/Demo_Source_Code/CSharpDemo/SecureShare/SharedFileAccessLogForm.resx b/Demo_Source_Code/CSharpDemo/SecureShare/SharedFileAccessLogForm.resx new file mode 100644 index 0000000..d3cbfbc --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/SecureShare/SharedFileAccessLogForm.resx @@ -0,0 +1,605 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 132, 17 + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAJWSURBVDhPrZNfSFNhGMZf6CKQIvBi3QRJgUIlNbtIMqGg + pLwXoyS8a1KaElEz/wylNtdY/9Pl2kJKjUk125xQF0nidRgVRBdiS6a5cn/dzpl7+t5vxwbmXT3wci7O + 9/y+9zzve+i/yNI3Dq7uuz6021/ismUEzV1DaOkaPkk1tIkayEoGKtGO/y02rxUDOuzeHKSF2gqMG1W6 + SDcEcINmy8vcG9BsQDabRVpdkYDVok4q3v5YB72vCNRKds2Wl+mWV7PnACkBiKczmAktodnkBl2izUUu + Heq+VkJ3vzBNFtqiWXMy3Xzxx6xmskgqK4gJwOvJz7KmPn3ELs82NM1V42CgGEeu1xs1a06tPR4JCMbn + UTNWi2/RRfxazshgbdM26If1qHq3F92RWhydKMXO27ux407ZgGYnumJ+hiV1CWXe/bgWO4UDoxUIxiLg + bJQVBdXjJ2COnYYbDbAm61DiKsVgYBKanWjQP4HDvkr5kg/x4WP+43B63srOEpkEKl4dknC9uOTD99lc + Nqs6M9SE8iflsj1uk9vd83Qfqu7VSwBn8yP5U37eTDSEcDKD8239eYDHPwXrc7cMiIPiwFyjY/C9eS8B + y2IqCRFsNJWR2SwkVJxre5gHSInRbH1QmOZR8ch4dJwNK57Om8NJFaG4AFx1rAGwxJLwsvDS8PJc6ByQ + AG55Udy6IIyhmIrZiAKDsW8dAK+pWNeCVrG2Yn1tDp8EzMcVYVQwF1UQFOYv4RTOGnvXAayKfxzxA/U4 + RtDY8UiUE43tTvHd/bIMon1+aqf/RUS/AVVJ5okbVkF5AAAAAElFTkSuQmCC + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAJFSURBVDhPrdBbSNNxHAXwo2aKl8ZyMy/brFzWPypvyBQL + iTJCAyWIIOqlMEkjZ4VWCNYg8hIpou1BQyScmvmgwzKjBokJBiL1IoSG1JKcl9wclTZP7u/vyYd88fPy + 53vO4f/ww6aKNYe/SGuKnT1Qox2NNql6cBFFyMceUW9sd0NER82XAra67rB7qZL9rGPuS8P8auWztthI + KXSK8pDvLT9LaXHdYx9rebwn3SlafNiKnAF/xItznWoY0p7FOOqn89g4a6TFXcZuPuBhy6HPYoF3gNoa + hImBABSKSKiALrVNN3NjLJ2myVyaxs8xuzlmuctTTqlx56BYyWzBMNpU8PQF4KiIAOWj4OZroxk0fjIw + oyt6AXeRh2IUWH6VMKxeUSdmsvfbcHIkCnwVitciAlLa9jvODklMtGicqEKCHFZAgWr/SpggybcwokL5 + pB4cVMP7uGviWvXuLJuevnUoE5FsJQLSQhTur4Qh1Hv/UCNhUgvnrAQOR2BKHnlpnihtBquGqMUxEcmW + kwMbWJzIiUhcntbg0tzBwAWm+vFPAjikRpOYrTIjc2+nyrP6vSoS2e9s7RCbztN+KnLp760MMl8is0Jp + 3+UzM6yEVszWbGn3NfqZfcfRge0iwtIFaZzWIvL5FXp/xKpsOtIUjqkdMIjJOu1IQgtyxIXFmydcHKkk + 39wmuwr5NSnkm10Jnaj/j4Cf8/oRN11vybHHZH8JPQ9zuZgc8lRMNsY47JuLDzLPZIb3Ok7rP06diZt3 + pih6Rb0ZgH+vle/bCJhHDQAAAABJRU5ErkJggg== + + + + + AAABAAgAEBAAAAEACABoBQAAhgAAABAQAAABACAAaAQAAO4FAAAYGAAAAQAIAMgGAABWCgAAGBgAAAEA + IACICQAAHhEAACAgAAABAAgAqAgAAKYaAAAgIAAAAQAgAKgQAABOIwAAMDAAAAEACACoDgAA9jMAADAw + AAABACAAqCUAAJ5CAAAoAAAAEAAAACAAAAABAAgAAAAAAEABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP// + /wCFe3sA1LS0AOvZ2QC3kpIAuaqqAPPFxQCXi4sA1svLAKicnADkvLwAw5ycANvX1wDlzs4Apo6OANDB + wQB8c3MAlYGBAODg4ADdxMQAxK2tALWamgD3zMwA7tLSAKOVlQDAlZUA6sjIAJ2FhQCuk5MA5NXVANzR + 0QDcvr4A2ri4AMuwsADn4uIAloaGAKWJiQDk2toA7s3NAK6OjgCumJgAvJycAJ+RkQDhysoAi319AKiS + kgC5lpYAv6qqANfT0wCzlZUA6dPTAO/JyQDbzMwAvZKSANnBwQCaiIgA4dDQAOC6ugDQsrIAqZWVAMKZ + mQDzy8sA29TUAOHNzQC8mZkAw5+fAOHX1wCjjIwA2c/PAODCwgDsy8sAvpeXAOPf3wDe2NgA4dTUAKaU + lADdwcEAuZubAL+dnQDq19cA5dfXAObT0wCik5MA5tDQALyUlADp1dUAo46OAJ+TkwDp0dEA3M/PALmY + mADr0tIA3dbWANnV1QCskpIA38/PALCXlwDm2toAqpKSAKuVlQDa0dEAvpSUAOrU1ACgkpIA59TUAOLW + 1gCnkZEA5dTUAKSUlACllZUAqJSUAN3S0gDb0tIA2svLALSZmQDju7sA27e3ANGzswCaiYkA3dfXAK6S + kgDhz88ArpeXAL6VlQDAlpYAmYiIAO3S0gCfkpIA5dXVAOHW1gDc1tYAqJGRAKmSkgCklZUAtJWVAL+V + lQC6m5sA4bq6AM+ysgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAFcua2tuhhloKyuACAAAAAApgR5RS3F4XYMNMVgAAAAAe0eHOAoTAQEBAV6A + AAAAAGFnUARQUjk1CUpFaAAAAABhRy95RCQCEGUBP1MAAAAAiX9ZXDNnVnpaI3BtAAAAACobW193Bg4s + ckkfTAAAAABBJ0ZNNxhqAQEBQ28AAAAASCdGTTcYQIJLgmA8AAAAAEg0Mg9+i2IBAQEmZAAAAAB8Pooh + diBZaVJsVIQAAAAAZhd0Czp1AzsiFRSFAAAAABoHVQUoJRwSLREwYwAAAAA2iIh9PQxCT04Wcx0AAAAA + AAAAAAAAAAAAAAAAAAD//wAAwAMAAMADAADAAwAAwAMAAMADAADAAwAAwAMAAMADAADAAwAAwAMAAMAD + AADAAwAAwAMAAMADAAD//wAAKAAAABAAAAAgAAAAAQAgAAAAAABABAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAKSPj/qpk5P9qJKS/aiSkv2mlpb8pZaW/KSWlvyhk5P9oJKS/aCSkv2gk5P9mIyM/AAA + AAAAAAAAAAAAAAAAAACwmZn95dXV/+TV1f/l19f/4dTU/9vS0v/d19f/3dbW/9zW1v/b19f/19PT/6CU + lP0AAAAAAAAAAAAAAAAAAAAAsJiY/ezLy/+0lZX/moiI/6icnP/g4OD//////////////////////9nV + 1f+gk5P9AAAAAAAAAAAAAAAAAAAAALKYmP3q1NT/6tfX/+vZ2f/q19f/5tPT/+HQ0P/bzMz/1svL/97Y + 2P/Zz8//oZOT/QAAAAAAAAAAAAAAAAAAAACymJj97MvL/7mWlv+ukpL/o4yM/5aGhv+Fe3v/0MHB/9rR + 0f//////29TU/6OUlP0AAAAAAAAAAAAAAAAAAAAAu5yc/O3S0v/p0dH/69LS/+nT0//q1NT/6dXV/+HP + z//cz8//5+Li/93S0v+llZX9AAAAAAAAAAAAAAAAAAAAAL2dnfzqyMj/uZiY/6ySkv+aiYn/uaqq/+XO + zv/hysr/2svL/+Pf3//c0dH/p5WV/QAAAAAAAAAAAAAAAAAAAAC+mpr97s3N/+DCwv/dwcH/2cHB/+7S + 0v/i1tb/////////////////4dfX/6mVlf0AAAAAAAAAAAAAAAAAAAAAwJiY/e7Nzf/gwsL/3cHB/9nB + wf/u0tL/4c3N/+HW1v/h1NT/4dbW/9/Pz/+rlpb9AAAAAAAAAAAAAAAAAAAAAMCYmP3vycn/s5WV/6aO + jv+ZiIj/z7Ky/+ba2v/////////////////k2tr/rZaW/QAAAAAAAAAAAAAAAAAAAADAlpb988vL/+G6 + uv/auLj/0bOz/9y+vv/p0dH/59TU/+bT0//l1NT/5tDQ/6mSkv0AAAAAAAAAAAAAAAAAAAAAwJWV/ffM + zP/ju7v/5Ly8/+C6uv/bt7f/1LS0/9Cysv/LsLD/xK2t/93ExP+rk5P9AAAAAAAAAAAAAAAAAAAAAMKW + lv3zxcX/vJSU/7eSkv+ujo7/pYmJ/52Fhf+VgYH/i319/3xzc/+/qqr/rJOT/QAAAAAAAAAAAAAAAAAA + AAC/k5P6wZaW/cGWlv3Cl5f9xJqa/cWdnf3FoKD9wZ6e/bucnP23m5v9tpqa/bCUlPsAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAD//wAAwAMAAMADAADAAwAAwAMAAMADAADAAwAAwAMAAMADAADAAwAAwAMAAMADAADAAwAAwAMAAMAD + AAD//wAAKAAAABgAAAAwAAAAAQAIAAAAAACgAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8AlXh4AOCx + sQBeXV0ApqKiAP/U1ADUz88AypqaAK2HhwB7bW0A5uDgAMGtrQDpxMQAnZOTAM67uwC1mJgA6tLSAPP1 + 9QCZhIQAh39/ALuMjAC/oqIAa2NjANCkpADdvb0A0cXFAN7X1wDTrq4A4czMAKmQkAD2zs4AsqSkAIt0 + dACkmpoApYKCAIJ4eADnu7sAcmhoAPXV1QCcfX0A3MTEAM20tACtm5sAyKGhAPj7+wCciooAyq6uAMGc + nADxyckA29HRANjKygC5q6sAgnBwANm4uACcm5sAuJOTAOPb2wC3oKAA1bS0AOrKygCulpYA49LSANHK + ygCvoKAA8NDQAOLCwgC6nJwAo5SUAIh4eADh4OAA6M7OAJ+PjwC2j48A0be3AHNsbADX09MAqIyMALaK + igC+qakAqZSUAMilpQC5p6cA+tPTAOXJyQDdyckAqIiIANi8vADWq6sAtJ2dAM2goACXiooApJCQAIuB + gQDtxsYA1sfHAMSfnwDs1dUA9Pj4AP7R0QD00tIA4s/PANrU1ADX0NAAm46OAOK/vwDRsrIAu5+fAPv9 + /QD50NAAmX9/APLU1ADm1NQA3s7OANDNzQCmlpYA1MPDAKuiogDHsLAA4NHRANnHxwC0oKAAxa2tAO7S + 0gDs0NAA2szMAKWgoACooKAAs5qaALiamgCwnp4AsKKiANO1tQDKo6MAw6urAOPh4QDzz88A5dDQAN3T + 0wDlzc0Aq5eXAMKhoQD5+fkA5t7eAPfS0gDn0tIA6dDQAOHKygDmxMQA0sfHANGiogDFoaEAzaSkAPrV + 1QD20NAA1cnJAKakpACroKAAt6KiAL+goADZuroAwqOjAPb6+gD+09MA+NTUAO/PzwDqzc0A2dLSAN/P + zwDZz88A3svLANjIyAC/nZ0Az6GhAMyvrwD6+/sA/NHRAPLS0gDw0tIA7NLSAOXS0gDn0NAA2NTUAOPN + zQCpoqIA1s/PAK6iogDcy8sA0s3NANrKygC6oKAAtKSkANPJyQC9oKAAyqGhANWurgDPsrIA/9LSAPvU + 1ADh398A99XVAPbU1AD01NQA+NHRAOPa2gD00dEA69PTAOvR0QC2l5cA5NPTAOrPzwDi0dEA5s/PAOHQ + 0ADc0NAA4c7OANbR0QDa0NAA4szMANTQ0ADfzc0Aw6CgAMagoADgyckAyaCgANnLywDQy8sA0qOjANrG + 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 + lv+plJT/pJCQ/5+Pj/+Xior/sJ6e//LU1P+9oqL4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA0KKi+P/S + 0v/gsbH/u4yM/7aKiv+th4f/pYKC/5x9ff+VeHj/i3R0/4JwcP97bW3/cmho/2tjY/9eXV3/h39///XV + 1f+/oqL4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1KSk+P/U1P/+0dH//tPT//7S0v/90tL//dPT//3T + 0//71NT/+9TU//rV1f/609P/+tTU//jU1P/41NT/9tLS//XU1P/CpKT4AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAzpub8dWlpfjSo6P40aOj+NCjo/jQo6P4zaOj+Myjo/jLo6P4yqOj+Mmjo/jIo6P4x6Oj+Maj + o/jFo6P4xKOj+MWlpfi6m5vxAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA////AOAABwDgAAcA4AAHAOAABwDgAAcA4AAHAOAABwDgAAcA4AAHAOAABwDgAAcA4AAHAOAA + BwDgAAcA4AAHAOAABwDgAAcA4AAHAOAABwDgAAcA4AAHAOAABwD///8AKAAAACAAAABAAAAAAQAIAAAA + AACABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8AlXR0ANO2tgBJTEwA/tTUAKuZmQBqZmYA1tLSAOjr + 6wC0hIQAx5iYAPLExAC8r68AgWtrAF5YWADSpqYAl5SUAM7ExADq09MAoYGBAOG/vwDy9vYA3uHhAH53 + dwC/jIwA4crKAMW3twC2k5MAs6ioAGBhYQD3zs4AiHJyAHZlZQCik5MAVlJSAJ55eQBrXl4A18nJAKyA + gADXvb0A7s3NAPXV1QDg0tIAwJOTAMbAwADqvb0AybGxANy4uADOvLwArYeHAJmZmQCtk5MAd2trAJV6 + egC0iooA+fv7ANzFxQDv8fEAjG1tALOYmABkXFwA+tjYAObOzgDczs4A0s3NAMStrQBxYWEA18LCAOLl + 5QCPdnYA6MnJAKeDgwCcfn4Afm9vANvd3QDx0NAAy8jIAMy1tQCclJQA/NDQAOO7uwDMwMAAZGRkAJBw + cAC4jY0Ap5aWANzCwgDdvLwA07q6AHJqagD51NQAhmxsAINxcQCYd3cA4cbGANDKygBvZmYA8szMAOXS + 0gDc0tIA28nJANi2tgC7k5MA0r29ALyKigDWqKgAinV1AOzQ0ADY1dUAoHx8ANTFxQDz8/MA9tDQAOHP + zwDXzMwA2Lq6AKiTkwDOubkAs5WVAMa0tABNTU0AaGNjAJFzcwDmzMwA08HBAJeWlgB7bW0A59XVAN7M + zADDlZUAybe3APv9/QBiWloA9tbWAO/OzgDo0NAA3dDQANnQ0ADU0NAA48jIANDHxwDYwMAAc2RkAPvV + 1QD/0dEA+tDQAOrNzQDjzc0AqX5+AOC6ugDVwMAAycHBANC1tQBKTk4A/P//APHz8wCBaWkAkHh4APPS + 0gDw0tIA5NDQAK2BgQDVzs4A2szMANTMzACZlJQA5ry8AOS9vQCflJQAzcbGAKWTkwDcv78A0cPDAM3C + wgCwk5MAz8DAALOTkwDLs7MAZGJiAPnR0QDyz88A0MzMANO4uABgWVkA9Pf3AOrs7AD719cA4OLiAPnW + 1gD709MA99LSAPTPzwDu0dEA9czMAOzS0gDo09MA7M7OAOvPzwDi0dEA4c3NALKJiQDkysoA38nJALqM + jAC9jY0A0srKAKmVlQDewMAA28LCANq7uwDUvb0A1bu7ANG7uwDWt7cA1bW1ANK0tADHuLgA+/v7AIRs + bADw9vYA8PHxAKB5eQDwzMwA5tHRAOjOzgDe0tIA39DQANjS0gDb0NAA19DQAN3OzgCrk5MA2c7OANzM + zADTzs4AuZOTAL6TkwDYyckA2MLCANXBwQByYmIAdWRkAHZqagD9/v4A8/X1AJd2dgCbfX0A/9XVAP/T + 0wD519cAooCAAPzU1AD61NQA/dHRAPfV1QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAGVqsiIiKpqampqU9PT0+mpqamERERfjMAAAAAAAAAAM+Ax+Pj44mJiYnliuWKiuaK5ovmi4ttfgAA + AAAAAAAAdWOB6oGkpKSkpHNzc6VzpaVBQUG2QQgRAAAAAAAAAAB1oYHjcuOJ44lAjeulpUFBQUFBQU22 + CBEAAAAAAAAAAHVjcllZdoMbDe7mAdra2tra2tr0CWAIpgAAAAAAAAAANODHaZX22/EjG6P13d3d3d3d + 3XC8zgimAAAAAAAAAAA0iHKhoWOAxGPHb65SUphSmJiYmC1z5KYAAAAAAAAAADSIlJShcqFycnJycuPj + iUCkqs5gqqVkTwAAAAAAAAAANIg/V1fR70SXaGgxMdkmQGUJAQG6JmRPAAAAAAAAAACvbIgZCifeAjud + ISW4eR1yZRdwcLwm4k8AAAAAAAAAAK9sP3x8P5Q/lJRylHKBcoGBUhISmKTiqQAAAAAAAAAAr8F8iD+I + iOCIiOCUyMjIgYGNc3ONpCupAAAAAAAAAACxwcbQrKwo1NV2eIjIyMiBgUUBAQllK6kAAAAAAAAAALHB + bGknJFSdQ4UEw5TIyMiBS5xwvGUrIgAAAAAAAAAAsaDFxWxsbGxswz/hlHyUlJSwra1SgcciAAAAAAAA + AAAcTClsbGzBwcHG4T856aRzc+lz6aVlxyIAAAAAAAAAAByfTBVY0nS3TlnG4WgBhISEhIT0uUTEIgAA + AAAAAAAAHJ9MLJVeXPIPGKCT0xY6Ojo6OpwJRMSrAAAAAAAAAADscYe1TJ+fKp+HxZOMRPDw8PB9fa0a + xKsAAAAAAAAAAOxx30y1TExMTEzBxV/iQEDnQEBAc8sTqwAAAAAAAAAA7L/AqJYwZtYDmUKHKJs4ODg4 + OIS50RN1AAAAAAAAAABntHGCom57Do89mkeO3Do6Ojo6nAlXE3UAAAAAAAAAAGe0H3G/v79b/ZC/wEfv + jo6XjpdEfcrDdQAAAAAAAAAAZ/7CwmLCYmLfYt8pKd+HKSkpk5OT4cPoAAAAAAAAAADt/h+Svr78/P39 + kJC9vbu7u/o+PirGwTQAAAAAAAAAAO3+khBVVckySBRJNp5rXUo1WgezU4agNAAAAAAAAAAALJFQas3M + NzJI+/c2RiBdf/Nheh4e+qA0AAAAAAAAAAAskVAMLi6np1GWljAwZmbX2JmZsi+fn68AAAAAAAAAAIL4 + kZH5+fn5+fkFBQX8/JCQkL29W5//dwAAAAAAAAAAC4IsLCzt7WdnZ2fs7OwcHBwcsbGxsXc8AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AA + AA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AA + AA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/////8oAAAAIAAAAEAAAAABACAAAAAAAIAQ + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAArJiY56iWlvCllJTwpJSU8KSU + lPCilJTwoZSU8KCUlPCglJTwn5SU8J6UlPCdlJTwnJSU8JyUlPCblJTwmpSU8JmUlPCZlJTwmJSU8JeU + lPCWlJTwlpSU8JaWlvCYmJjnAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACrlpb159XV/+LR + 0f/g0ND/39DQ/+DQ0P/e0ND/3dDQ/9zQ0P/d0ND/29DQ/9rQ0P/b0ND/2dDQ/9jQ0P/X0ND/2NDQ/9bQ + 0P/V0ND/1tDQ/9TQ0P/T0dH/2NXV/5iWlvUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKmU + lPXk0tL/3s3N/9zMzP/dzMz/28zM/9rMzP/ZzMz/2czM/9nMzP/YzMz/2MzM/9bMzP/VzMz/1szM/9TM + zP/TzMz/0szM/9LMzP/RzMz/0MzM/9HNzf/V0tL/l5SU9QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAqpSU9eTR0f/ezMz/38/P/+DPz//fz8//3tDQ/9/Q0P/e0ND/3M7O/9DHx//Tzs7/08zM/9PM + zP/SzMz/0szM/9LMzP/RzMz/0czM/9LNzf/LyMj/0MvL/9XS0v+YlJT1AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACrlJT15dHR/+HPz//Tu7v/0rq6/825uf/Jt7f/xba2/7yvr//Yycn/19HR//7/ + ///7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v//f7+/+nr6//Qycn/1tLS/5mUlPUAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAK6UlPXm0dH/49HR/7uKiv+pfn7/l3Z2/4RsbP9yYmL/VlJS/8W3 + t//Vzs7/8/X1//Dx8f/w8fH/8PHx//Dx8f/w8fH/8PHx//Dx8f/z8/P/4OHh/9LKyv/X0tL/mpSU9QAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAArpSU9efR0f/izs7/5NDQ/+TR0f/l0tL/5tTU/+fT + 0//l0tL/4tDQ/9TFxf/NwsL/y8DA/8zAwP/KwMD/y8DA/8nBwf/KwcH/yMHB/8rBwf/GwMD/1svL/9jS + 0v+blJT1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACvlJT16NHR/+TMzP/jzs7/48/P/+LP + z//jz8//4s/P/+HPz//hz8//4dDQ/+HQ0P/g0ND/4NDQ/93Pz//bzs7/28vL/83Gxv/Sysr/0MrK/8zG + xv/Vy8v/29LS/5yUlPUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALCUlPXp0dH/5s/P/9zC + wv/cwcH/28LC/9jCwv/XwcH/1b+//9K+vv/Rvb3/zry8/868vP/HuLj/18jI/9zOzv/aycn/6Ovr//7/ + ////////6uzs/9bJyf/c0tL/nZSU9QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsZSU9ezR + 0f/o0dH/v4yM/7SEhP+sf3//oHl5/5V0dP+MbW3/gGlp/3ZlZf9rXl7/YFlZ/01NTf+zqKj/4M/P/9vJ + yf/e4eH/8/T0//P09P/g4uL/18nJ/93S0v+elJT1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACylJT17NHR/+fOzv/my8v/5czM/+bOzv/kzc3/5c7O/+POzv/jzc3/4s7O/+LNzf/izs7/3szM/+DP + z//ezc3/3cvL/8zBwf/OxMT/zsTE/8nBwf/Zy8v/3tLS/5+UlPUAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAALOUlPXt0dH/58zM/+jPz//nz8//6NDQ/+fQ0P/m0ND/6NHR/+fR0f/m0dH/5M7O/+HN + zf/gzc3/4MzM/97MzP/ezMz/0MbG/9bLy//Wy8v/z8fH/9rLy//f0tL/oJSU9QAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAtJSU9e7R0f/qz8//3sDA/9y/v//bv7//1729/9W7u//Ru7v/zrm5/8a0 + tP/n0ND/4czM/+DMzP/gzMz/38zM/97Ly//i5eX//v////7////o6+v/2snJ/+DS0v+hlJT1AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC1lJT179HR/+zR0f+8ior/rICA/555ef+QcHD/gWlp/3Fh + Yf9iWlr/SUxM/+vS0v/izMz/4czM/+HMzP/gzMz/38vL/9vd3f/x8/P/8vPz/9/i4v/bycn/4dLS/6KU + lPUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALaUlPXw0dH/687O/+zNzf/s0ND/69DQ/+zQ + 0P/r0ND/7NHR/+vS0v/nzs7/6c7O/+TMzP/lzMz/48zM/+LMzP/jzMz/z8DA/9HDw//Qw8P/zMHB/9/L + y//i0tL/o5SU9QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAt5SU9fHR0f/tzMz/7c/P/+3P + z//s0ND/7tDQ/+3R0f/t0dH/6s/P/+jOzv/mzc3/3MXF/9nOzv/ZzMz/18zM/9jNzf/Zzc3/2M3N/9nN + zf/Vy8v/2snJ/+PS0v+klJT1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC4lJT19NHR//DP + z//hv7//3by8/9q7u//Yurr/07i4/8y1tf/Turr/68/P/+jNzf/Svb3///////v8/P/7/Pz/+/z8//v8 + /P/7/Pz//P7+//T39//WwsL/59PT/6WUlPUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALmU + lPX00dH/8dHR/8CSkv+pfn7/mHd3/4ZsbP91ZGT/XlhY/353d//w0tL/6c3N/9S9vf/y9vb/7/Hx/+/x + 8f/v8fH/7/Hx/+/x8f/w8/P/6Ozs/9fCwv/n09P/ppSU9QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAupSU9fXR0f/wzs7/8s7O//LR0f/z0dH/89LS//TU1P/y0tL/78/P/+zOzv/pzc3/48jI/9bC + wv/VwcH/1cHB/9TBwf/UwcH/08HB/9PBwf/RwsL/4crK/+jS0v+nlJT1AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAC7lJT19tHR//DMzP/xz8//8s/P//LQ0P/x0ND/8dDQ//LR0f/x0dH/79DQ/+3O + zv/hxsb/3tHR/9zOzv/czs7/3c7O/9vOzv/bzs7/3M/P/9jNzf/fycn/6dLS/6iUlPUAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAALyUlPX30dH/9M/P/+S9vf/gu7v/3Lm5/9m3t//Wt7f/07a2/8+0 + tP/Era3/787O/9e9vf/8////+fv7//n7+//5+/v/+fv7//n7+//7/f3/8/f3/9rCwv/q09P/qZSU9QAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAvZSU9fjR0f/20ND/w5SU/62Bgf+gfHz/kXNz/4Fr + a/9zZGT/ZFxc/0pOTv/oycn/2b+///D29v/u8fH/7/Hx/+/x8f/v8fH/7/Hx//Dz8//o7Oz/3MLC/+vT + 0/+qlJT1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC+lJT1+dHR//bOzv/3z8//99LS//jS + 0v/40tL/+dPT//nU1P/61dX/99LS//PPz//nyMj/2MLC/9fAwP/YwMD/1sDA/9fAwP/VwMD/1sHB/9LB + wf/kysr/69LS/6uUlPUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL+UlPX80dH/9czM//TM + zP/zzMz/9MzM//LMzP/xzMz/8MzM//HMzP/vzMz/7szM/+7Nzf/wzc3/783N/+3Nzf/uzc3/7c3N/+vN + zf/qzc3/683N/+jNzf/s0tL/rZSU9QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwJSU9fzR + 0f/3zc3/+c/P//vS0v/709P//NTU//vU1P/61NT/+tTU//zV1f/71dX/+tbW//nW1v/719f/+tfX//rX + 1//519f/+djY//rY2P/11dX/68/P/+3R0f+ulJT1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AADBlJT1/dHR//rQ0P/Spqb/uIyM/7iNjf+yiYn/rIeH/6eDg/+hgYH/nH5+/5V6ev+QeHj/inV1/4Nx + cf9+b2//d2tr/3Jqav9qZmb/ZGJi/2RkZP/21tb/8NHR/66UlPUAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAMKUlPX+0dH//NDQ/9aoqP+9jY3/uoyM/7SKiv+thob/p4OD/6KAgP+bfX3/lHp6/492 + dv+IcnL/gnFx/3ttbf92amr/b2Zm/2hjY/9gYGD/YGFh//jX1//w0dH/sJSU9QAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAw5SU9f/S0v/8z8//8sTE/+q9vf/pvLz/5ru7/+W8vP/ju7v/4Lq6/9+5 + uf/duLj/3Le3/9i2tv/Xtrb/1bW1/9K0tP/QtbX/z7S0/8uzs//JsbH/8tLS//LS0v+xlJT1AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADGlpb1/9XV///R0f//0tL//9PT///T0///09P//tPT///T + 0//+09P//dTU//7U1P/91NT//NTU//vU1P/81dX/+9XV//rV1f/51dX/+dXV//jU1P/00tL/99XV/7SW + lvUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMqYmO3Glpb1w5SU9cKUlPXClJT1wZSU9cCU + lPW/lJT1vpSU9b6UlPW9lJT1vJSU9buUlPW6lJT1uZSU9bmUlPW4lJT1t5SU9baUlPW1lJT1tZSU9bSU + lPW1lpb1tZiY7QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/////wAAAP8AAAD/AAAA/wAAAP8AAAD/AA + AA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AA + AA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA//////KAAAADAAAABgAAAAAQAIAAAA + AACACgAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8AlXR0ANO2tgBJTEwA/tTUAKuZmQBqZ2cA1NLSAOjr + 6wC0hIQAxJycAPHAwAC7ra0AgWtrAF5YWADNpqYAlYyMAM7ExADq09MAn4ODAOK/vwDy9vYA3+DgAIF4 + eADAjo4A4svLAMW3twC2k5MAuKOjAF9fXwD4zc0AhnR0AHZlZQChkZEAVlJSAJ55eQBrXl4A18nJAKyA + gADYvr4A7s3NAPXV1QDg0tIAwJKSAMS+vgDrv78AzK+vANy4uADOvr4ArIiIAJuYmACulJQAdm1tAJR9 + fQC0i4sA+fr6ANvFxQDu8PAAjG1tALSamgBkXFwA+tjYAObOzgDczc0A0s3NAMSpqQBxYWEA1sTEAOTm + 5gCNdnYA58fHAKaFhQCYgYEAfnBwANvb2wDw0NAAyMbGAMy1tQCdk5MA/M/PAOa1tQDLv78AZGRkAJBw + cAC4jo4ApZiYANzDwwDdvb0A07m5AHFqagD51NQAhmxsAIJycgCYd3cA4cbGANDKygBuaGgA8szMAOXS + 0gDc0tIA28nJANi2tgC7lZUA0r6+ALyKigDVra0AiHZ2AO3PzwDX19cAoHx8ANXGxgDz8/MA9dHRAOHP + zwDXzc0A2Lu7AKmRkQDPuroAs5WVAMi1tQBNTU0AamRkAJFzcwDnzMwA0sLCAJmXlwB6bm4A59XVAN7M + zADClpYAy7e3APz9/QBiWloA9tbWAO/OzgDpz88A3s/PANnQ0ADT0dEA5MfHANDHxwDYwMAAc2RkAPvV + 1QD/0dEA+s/PAOrNzQDjzc0AqX5+AOK2tgDVwMAAyMHBANC1tQBKTk4A/P//APHz8wCBaWkAjnl5APXS + 0gDw0tIA5M/PAK2BgQDVzc0A2szMANTMzACakZEA576+AOW/vwCgl5cAysXFAKaUlADcvr4A0cPDAMzD + wwCwkJAA0L+/ALSQkADPsbEAZGFhAPnR0QDyz88A0M3NANO4uABgWVkA9vf3AOzu7gD719cA4uPjAPnW + 1gD709MA99LSAPXPzwDv0NAA9czMAOzS0gDo09MA7M7OAOvPzwDi0tIA4c3NALCKigDlyckA3snJALqN + jQC9jo4A0srKAKmVlQDewMAA28LCANq8vADVvr4A1rq6ANG6ugDWt7cA1bW1ANGzswDGu7sA+/v7AIRs + bADw9vYA8PHxAKB5eQDvzMwA5tHRAOjOzgDe0tIA4NDQANjS0gDb0NAA19DQAN7OzgCrk5MA2c3NANzM + zADQz88AuZWVAL6VlQDZysoA2cPDANXCwgByYmIAdWRkAHZqagD9/v4A9PX1AJd2dgCZfX0A/9XVAP/T + 0wD519cAoYCAAPzU1AD61NQA/dHRAPfV1QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + 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 + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACrmZnaq5iY56mYmOeql5fnqJeX56mXl+eml5fnp5eX56WX + l+eml5fnpJeX56WXl+ejl5fno5eX56SXl+eil5fno5eX56GXl+eil5fnoJeX56GXl+efl5fnoJeX556X + l+efl5fnnJeX552Xl+ebl5fnnJeX55qXl+ebl5fnmZeX55mXl+eal5fnmJeX55mYmOeYmJjnmZmZ2gAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACrmJjwyLW1/9HAwP/Rv7//z7+//9C/ + v//Qv7//z7+//8+/v//Ov7//zr+//82/v//Nv7//zL+//8y/v//Lv7//y7+//8u/v//Kv7//yr+//8m/ + v//Jv7//yL+//8i/v//Hv7//x7+//8a/v//Gv7//xb+//8W/v//Ev7//xL+//8O/v//Dv7//wr+//8PA + wP+3tbX/mZiY8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACrl5fw0b+//9/O + zv/dzc3/3c3N/9zNzf/czc3/283N/9vNzf/bzc3/2s3N/9rNzf/Zzc3/2c3N/9jNzf/Yzc3/183N/9fN + zf/Xzc3/1s3N/9bNzf/Vzc3/1c3N/9TNzf/Uzc3/083N/9PNzf/Tzc3/0s3N/9LNzf/Rzc3/0c3N/9DN + zf/Qzc3/z83N/9DOzv/Bv7//mJeX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACtl5fw0b6+/97Nzf/dzMz/3MzM/9zMzP/czMz/28zM/9vMzP/azMz/2szM/9nMzP/ZzMz/2MzM/9jM + zP/YzMz/18zM/9fMzP/WzMz/1szM/9XMzP/VzMz/1MzM/9TMzP/UzMz/08zM/9PMzP/SzMz/0szM/9HM + zP/RzMz/0MzM/9DMzP/QzMz/z8zM/9DNzf/Cvr7/mZeX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACsl5fw076+/9/Nzf/ezMz/3czM/93MzP/czMz/3MzM/9vMzP/bzMz/2szM/9rM + zP/azMz/2czM/9nMzP/YzMz/2c3N/9fMzP/XzMz/2MzM/9bMzP/XzMz/1czM/9XMzP/UzMz/1MzM/9PM + zP/TzMz/08zM/9LMzP/SzMz/0czM/9HMzP/Rzc3/0MzM/9DNzf/Bvr7/m5eX8AAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACtl5fw0r6+/+DNzf/ezMz/3szM/93MzP/dzMz/3czM/9zM + zP/czMz/28zM/9vMzP/azMz/2szM/9nMzP/azc3/yL+//9TS0v/T0dH/09HR/9PR0f/U0dH/0tHR/9LR + 0f/S0dH/0tHR/9LR0f/S0dH/0tHR/9LR0f/T0dH/0dHR/9PS0v/Dv7//0s3N/9HNzf/Cvr7/mpeX8AAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACvl5fw076+/+DNzf/fzMz/4M3N/+DQ + 0P/h0ND/4NDQ/+HQ0P/g0dH/4dHR/+DS0v/h0tL/4tLS/97Pz//czc3/ycDA//39/f/5+vr/+fr6//n6 + +v/6+vr/+vr6//r6+v/6+vr/+vr6//r6+v/6+vr/+vr6//r6+v/6+vr/+vr6//3+/v/Bvb3/0s3N/9LN + zf/Dvr7/nJeX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACul5fw1L6+/+HN + zf/gzc3/2sTE/7mPj/+0kJD/rYuL/6SHh/+cg4P/lH9//4p6ev+BdXX/dW5u/6CXl//ez8//x7+///X1 + 9f/y8vL/8vLy//Ly8v/y8vL/8vLy//Ly8v/y8vL/8vLy//Ly8v/y8vL/8vLy//Ly8v/y8vL/8vLy//X2 + 9v/BvLz/083N/9PNzf/Fvr7/m5eX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACwl5fw1r6+/+LNzf/izc3/3MTE/76MjP+1i4v/rIaG/6GAgP+Ye3v/jXZ2/4Jycv93bGz/amRk/5qS + kv/g0ND/yMDA//Dw8P/u7u7/7u7u/+7u7v/u7u7/7u7u/+7u7v/u7u7/7u7u/+7u7v/u7u7/7u7u/+7u + 7v/u7u7/7u7u//Dx8f/BvLz/1M3N/9PNzf/Evr7/nJeX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACvl5fw1b6+/+PNzf/hzMz/4cvL/93Fxf/cxsb/3MXF/9rExP/YxcX/18TE/9XD + w//VwsL/0sLC/9bGxv/ezc3/y8DA/8vGxv/KxcX/ysXF/8rFxf/KxcX/ysXF/8rFxf/JxcX/ycXF/8nF + xf/JxcX/ycXF/8nFxf/IxcX/yMXF/8jGxv/HwMD/1M3N/9TNzf/Fvr7/npeX8AAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwl5fw1r6+/+PNzf/izMz/4czM/+HNzf/izc3/4M3N/+HN + zf/gzc3/4M3N/9/Nzf/fzc3/383N/97Nzf/ezMz/3c3N/93Nzf/czMz/3MzM/9vMzP/bzMz/28zM/9rM + zP/azMz/2czM/9nNzf/Zzc3/2c3N/9fNzf/Xzc3/2M3N/9bNzf/Wzc3/1MzM/9XNzf/Hvr7/nZeX8AAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACyl5fw2L6+/+TNzf/jzMz/4szM/+LM + zP/hzMz/4czM/+DMzP/gzMz/4MzM/9/MzP/fzMz/3szM/97MzP/dzMz/3czM/9zMzP/czMz/3MzM/9vM + zP/bzMz/2szM/9rMzP/ZzMz/2czM/9nLy//Evb3/yMLC/8jCwv/IwsL/yMLC/8fDw//Mw8P/1s3N/9XN + zf/Gvr7/n5eX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACxl5fw176+/+XN + zf/jzMz/5M3N/+TOzv/kzs7/5M/P/+PPz//jz8//4s/P/+PPz//hz8//4s/P/+LPz//hz8//4s/P/+HQ + 0P/h0ND/4NDQ/+DQ0P/f0ND/3s/P/9zMzP/azMz/2szM/9jJyf/f4OD//f7+//v8/P/7/Pz/+/z8//// + ///Evb3/183N/9bNzf/Hvr7/npeX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACyl5fw2L6+/+bNzf/kzMz/4cbG/8ympv/Lpqb/yaam/8Wjo//Co6P/vqCg/7uenv+4np7/tJub/6+Z + mf+tl5f/qJeX/6aUlP+hkpL/nZGR/5qPj/+VjIz/p52d/97Pz//bzMz/2szM/9jJyf/b29v/9fX1//Pz + 8//z8/P/8/Pz//b29v/Dvb3/183N/9fNzf/Ivr7/n5eX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAC0l5fw2r6+/+bNzf/mzc3/4MTE/8KPj/+/j4//uY2N/7SKiv+th4f/qIWF/6KB + gf+dfn7/lnt7/5F4eP+Ldnb/hnNz/39vb/94bGz/c2pq/21mZv9mYmL/hH19/+HQ0P/czMz/28zM/9nK + yv/X2Nj/8fHx//Dw8P/w8PD/8PDw//Lz8//FvLz/2M3N/9jNzf/Kvr7/oZeX8AAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACzl5fw2b6+/+fNzf/lzMz/5MnJ/9i1tf/XtbX/07Oz/9Cy + sv/PsbH/zLCw/8qvr//Hra3/xKys/8Krq/+/qqr/vKmp/7qoqP+3pqb/tKWl/7KkpP+uoqL/uq2t/+DO + zv/czMz/3MzM/9vKyv+/wMD/0M/P/8/Ozv/Pzs7/z87O/9DPz//EvLz/2c3N/9jNzf/Jvr7/oJeX8AAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC0l5fw2r6+/+jNzf/mzMz/583N/+bN + zf/mzs7/5c7O/+XOzv/mzs7/5M7O/+XOzv/kzs7/5M7O/+POzv/jzs7/5M7O/+LOzv/jz8//4s/P/+LP + z//hz8//4M7O/93MzP/dzMz/3czM/93Nzf/fzc3/3c3N/93Nzf/czc3/3M3N/9vNzf/bzc3/2szM/9nN + zf/Kvr7/oZeX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC2l5fw276+/+jN + zf/nzMz/5szM/+bMzP/mzMz/5czM/+XMzP/kzMz/5MzM/+PMzP/jzMz/48zM/+LMzP/izMz/4czM/+HM + zP/gzMz/4MzM/9/MzP/fzMz/38zM/97MzP/ezMz/3czM/97Nzf/Jvb3/xrq6/8W6uv/Gurr/xLq6/8S6 + uv/SxcX/2szM/9rNzf/Mvr7/o5eX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAC1l5fw3b6+/+nNzf/ozMz/6M3N/+jOzv/nzs7/6M7O/+fOzv/nzs7/6M7O/+fPz//nz8//5s/P/+bP + z//lz8//5s/P/+TOzv/hzMz/4czM/+DMzP/gzMz/38zM/9/MzP/ezMz/3szM/9/MzP/Z2Nj///////z9 + /f/8/f3//P39///////Fvb3/283N/9vNzf/Lvr7/opeX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAC2l5fw3L6+/+rNzf/ozMz/5cfH/9Ktrf/Pra3/zKys/8mqqv/FqKj/waam/72l + pf+5o6P/taGh/7Ofn/+unZ3/qZub/8u3t//kzc3/4czM/+HMzP/gzMz/4MzM/+DMzP/fzMz/38zM/9/M + zP/U09P/9vb2//T09P/09PT/9PT0//f4+P/Gvb3/3c3N/9vNzf/Mvr7/o5eX8AAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC4l5fw3b6+/+vNzf/pzc3/48TE/72MjP+4jIz/sImJ/6mF + hf+ggID/mXx8/5F5ef+IdXX/gXBw/3hsbP9vZ2f/ZGFh/66hof/mzs7/4szM/+LMzP/hzMz/4czM/+DM + zP/gzMz/38zM/+DMzP/S0dH/8fHx/+/v7//v7+//7+/v//Ly8v/HvLz/3M3N/9zNzf/Ovr7/pZeX8AAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC3l5fw376+/+vNzf/qzMz/58fH/9Ss + rP/Qq6v/zKmp/8empv/DpKT/vqKi/7mgoP+1np7/sJub/6yZmf+nl5f/oZOT/8e0tP/lzs7/48zM/+LM + zP/izMz/4czM/+HMzP/hzMz/4MzM/+LMzP/BwcH/1tfX/9XW1v/V1tb/1dbW/9bX1//Furr/3c3N/93N + zf/Pvr7/pJeX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6l5fw3r6+/+zN + zf/rzMz/683N/+vOzv/rzs7/687O/+rPz//rz8//6s/P/+rPz//qz8//6c/P/+rPz//pz8//6c/P/+bO + zv/kzMz/5czM/+TNzf/kzc3/483N/+PNzf/izc3/4s3N/+HNzf/fysr/3snJ/93Jyf/cycn/3MnJ/9vJ + yf/ezMz/3czM/93Nzf/Pvr7/ppeX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAC5l5fw376+/+3Nzf/rzMz/68zM/+vMzP/qzMz/6szM/+nMzP/pzMz/6MzM/+jMzP/nzMz/58zM/+bM + zP/mzMz/5szM/+XMzP/lzMz/5czM/9nDw//Tvr7/0r6+/9K+vv/Rvr7/0b6+/9G+vv/Qvr7/0L6+/9C+ + vv/Pvr7/z76+/8+/v//Xxsb/38zM/97Nzf/Qvr7/pZeX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAC6l5fw4L6+/+7Nzf/szMz/7c3N/+zNzf/tzs7/687O/+zOzv/rzs7/687O/+vO + zv/qzs7/687O/+rOzv/ozc3/5szM/+bMzP/lzMz/5szM/9DLy//z9fX/8fPz//Lz8//y8/P/8vPz//Lz + 8//y8/P/8vPz//Lz8//y8/P/8vPz//T29v/Lw8P/38zM/9/Nzf/Rvr7/ppeX8AAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC7l5fw4r6+/+7Nzf/tzMz/7svL/9q2tv/Ytrb/17a2/9Kz + s//Qs7P/zbCw/8mwsP/Grq7/w6ys/72pqf/cw8P/6M3N/+fMzP/mzMz/6MzM/9PNzf/4+Pj/9vb2//b2 + 9v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//j5+f/NxMT/4MzM/+DNzf/Qvr7/qZeX8AAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC9l5fw4b6+/+/Nzf/vzMz/7czM/7qM + jP+1i4v/rIeH/6KBgf+afX3/j3h4/4V0dP98bm7/cmpq/2NgYP/Er6//687O/+fMzP/nzMz/58zM/9HL + y//x8vL/7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v//Ly8v/Mw8P/4c3N/+DN + zf/Rvr7/qJeX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC8l5fw4r6+//DN + zf/uzMz/78zM/9CkpP/JoaH/w56e/7ybm/+2l5f/rpSU/6mRkf+hjY3/m4qK/5CFhf/QuLj/6s3N/+jM + zP/ozMz/6czM/8rFxf/j5eX/4uPj/+Lj4//i4+P/4uPj/+Lj4//i4+P/4uPj/+Lj4//i4+P/4uPj/+Pl + 5f/Iv7//483N/+HNzf/Tvr7/qZeX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAC+l5fw476+//HNzf/vzMz/8M3N//DOzv/xz8//8M/P//DPz//vz8//8NDQ//HQ0P/w0ND/8dDQ/+/Q + 0P/szs7/6czM/+nMzP/ozMz/6czM/93Fxf/ZwcH/18DA/9jAwP/WwMD/1sDA/9fAwP/VwMD/1cDA/9bA + wP/UwMD/1MDA/9TAwP/ax8f/4szM/+LNzf/Svr7/q5eX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAC9l5fw5b6+//HNzf/wzMz/78zM/+/MzP/vzMz/7szM/+7MzP/tzMz/7czM/+zM + zP/szMz/68zM/+vMzP/qzMz/6szM/+rMzP/pzMz/6szM/+XJyf/kyMj/48fH/+PHx//hx8f/4cfH/+LH + x//gx8f/4cfH/9/Hx//fx8f/4MfH/97IyP/iy8v/4szM/+PNzf/Tvr7/qpeX8AAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC+l5fw5L6+//LNzf/xzMz/8MzM//HNzf/wzc3/8M3N/+/N + zf/vzc3/7s3N/+7Nzf/vzc3/7c3N/+7Nzf/tzc3/7c3N/+vNzf/qzMz/6szM/8vFxf/k5+f/5OXl/+Tl + 5f/k5eX/5OXl/+Tl5f/k5eX/5OXl/+Tl5f/k5eX/5OXl/+Xn5//Kv7//5c3N/+PNzf/Vvr7/q5eX8AAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAl5fw5b6+//PNzf/xzMz/8czM/+bA + wP/lwMD/5L+//+O+vv/hv7//376+/929vf/cvLz/2ru7/9i7u//Wurr/07m5/97Bwf/tzc3/68zM/9XN + zf/4+fn/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//n5+f/PxMT/5MzM/+TN + zf/Uvr7/rZeX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC/l5fw576+//TN + zf/yzMz/8czM/7qNjf+4jIz/sImJ/6iFhf+hgID/mH19/5F5ef+IdXX/gHBw/3ltbf9waWn/ZGJi/5yQ + kP/vz8//7MzM/9HKyv/y8vL/8PDw//Dw8P/w8PD/8PDw//Dw8P/w8PD/8PDw//Dw8P/w8PD/8PDw//Lz + 8//NwsL/5czM/+XNzf/Vvr7/rJeX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AADAl5fw5r6+//TNzf/zzMz/88vL/8qbm//GmZn/vpaW/7iTk/+wkJD/qouL/6OIiP+dhYX/lYKC/49/ + f/+JfHz/fnV1/62bm//wz8//7szM/8/Jyf/u8PD/7O7u/+zu7v/s7u7/7O7u/+zu7v/s7u7/7O7u/+zu + 7v/s7u7/7O7u/+7x8f/NwsL/583N/+XNzf/Xvr7/rpeX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAADCl5fw576+//XNzf/0zMz/9M3N//XPz//1z8//9c/P//TQ0P/10ND/9NDQ//XQ + 0P/20dH/9dHR//bR0f/10tL/9dLS//HPz//uzMz/7c3N/9jAwP/Qurr/0Lq6/9G6uv/Purr/z7q6/9C6 + uv/Ourr/zrq6/8+6uv/Nurr/zbq6/826uv/ZwsL/5s3N/+bNzf/Wvr7/rZeX8AAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADBl5fw6L6+//bNzf/0zMz/9MzM//PMzP/zzMz/88zM//LM + zP/yzMz/8czM//HMzP/wzMz/8MzM/+/MzP/vzMz/7szM/+7MzP/uzMz/7czM/+7Nzf/uzc3/7s3N/+3N + zf/tzc3/683N/+zNzf/qzc3/683N/+vNzf/qzc3/6s3N/+jNzf/ozc3/5szM/+fNzf/Xvr7/rpeX8AAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADCl5fw6r6+//fNzf/1zMz/9czM//TM + zP/0zMz/88zM//PMzP/yzMz/8szM//LMzP/xzMz/8czM//DMzP/wzMz/78zM/+/MzP/uzMz/7szM/+3M + zP/tzMz/7MzM/+zMzP/szMz/68zM/+vMzP/qzMz/6szM/+nMzP/pzMz/6MzM/+jMzP/nzMz/58zM/+jN + zf/Zvr7/sJeX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADEl5fw6b6+//fN + zf/2zMz/9czM//bNzf/3zs7/9s7O//bOzv/1zs7/9c7O//TOzv/1zs7/887O//TOzv/yzs7/887O//LO + zv/yz8//8s/P//HPz//xz8//8M/P//HPz//vz8//8M/P/+7Pz//vz8//7s/P/+7Pz//uz8//7c/P/+3P + z//pzc3/6czM/+jNzf/avr7/r5eX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AADDl5fw6r6+//jNzf/3zMz/983N/+K2tv/Zrq7/2K6u/9etrf/Vra3/1Kys/9Krq//Qqqr/zqmp/8yp + qf/KqKj/yKen/8ampv/EpaX/w6Sk/8Cjo/+/oqL/vKGh/7uhof+4oKD/t5+f/7Senv+ynZ3/sJyc/66b + m/+smpr/qpqa/6WXl//gxcX/6c3N/+nNzf/Zvr7/sZeX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAADFl5fw676+//nNzf/3zMz/+c/P/86goP++kZH/vpGR/7uPj/+4jo7/tYyM/7KL + i/+tiYn/qoaG/6iEhP+jhIT/oIGB/5x/f/+ZfX3/lX19/5F6ev+OeHj/iXZ2/4d1df+Cc3P/gHFx/3tv + b/94bm7/dGxs/3Bqav9taGj/aWVl/15fX//Yvb3/6s3N/+rNzf/avr7/sJeX8AAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADEl5fw7b6+//rNzf/4zMz/+8/P/9Kjo//ElJT/wZOT/76R + kf+7kJD/t46O/7SMjP+wior/rYmJ/6mHh/+mhYX/ooOD/5+Bgf+bgID/mH5+/5R8fP+Qenr/jXl5/4l3 + d/+GdXX/gnNz/35ycv97cHD/d25u/3RsbP9wamr/bGlp/2JiYv/Zvr7/7M3N/+vNzf/cvr7/sZeX8AAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADFl5fw7L6+//rNzf/5zMz/+s7O/9Sj + o//FlJT/wpSU/7+Rkf+8j4//t42N/7SMjP+wior/rYiI/6iGhv+lhYX/oYOD/56AgP+Zfn7/l319/5J7 + e/+PeXn/ind3/4d2dv+DdHT/gHFx/3xxcf95bm7/dGxs/3Fqav9taWn/amdn/19fX//ZvLz/7c3N/+vN + zf/dvr7/s5eX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADHl5fw7b6+//vN + zf/6zMz/+czM//nMzP/6zc3/+c7O//jMzP/5zMz/98zM//jNzf/3zc3/983N//bNzf/1zc3/9s3N//XN + zf/2zc3/9c7O//XOzv/0zs7/88/P//TNzf/yzc3/887O//LOzv/yzs7/8c7O//DOzv/xzs7/8M7O/+/O + zv/tzc3/68zM/+zNzf/cvr7/speX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AADGl5fw77+///3Ozv/7zc3/+83N//rNzf/6zc3/+s3N//nNzf/6zc3/+M3N//jNzf/3zc3/983N//bN + zf/2zc3/9c3N//XNzf/2zc3/9M3N//XNzf/zzc3/9M3N//LNzf/zzc3/8c3N//LNzf/wzc3/8M3N//HN + zf/vzc3/8M3N/+7Nzf/uzc3/7c3N/+7Ozv/ev7//s5eX8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAADImJjw5rW1//HAwP/wv7//77+//++/v//uv7//7r+//+2/v//tv7//7L+//+y/ + v//sv7//67+//+u/v//qv7//6r+//+m/v//pv7//6L+//+i/v//nv7//57+//+a/v//mv7//5b+//+W/ + v//kv7//5L+//+S/v//jv7//47+//+K/v//iv7//4b+//+LAwP/VtbX/tZiY8AAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADKmJjjyJiY8MiYmPDGl5fwxpeX8MeXl/DFl5fwxJeX8MSX + l/DFl5fww5eX8MSXl/DCl5fww5eX8MGXl/DCl5fwwJeX8MGXl/C/l5fwwJeX8L6Xl/C/l5fwvZeX8L6X + l/C8l5fwvZeX8LuXl/C8l5fwupeX8LmXl/C5l5fwupeX8LeXl/C2l5fwtpeX8LeYmPC2mJjwt5iY4wAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////AAD4AAAAAB8AAPgAAAAAHwAA+AAAAAAf + AAD4AAAAAB8AAPgAAAAAHwAA+AAAAAAfAAD4AAAAAB8AAPgAAAAAHwAA+AAAAAAfAAD4AAAAAB8AAPgA + AAAAHwAA+AAAAAAfAAD4AAAAAB8AAPgAAAAAHwAA+AAAAAAfAAD4AAAAAB8AAPgAAAAAHwAA+AAAAAAf + AAD4AAAAAB8AAPgAAAAAHwAA+AAAAAAfAAD4AAAAAB8AAPgAAAAAHwAA+AAAAAAfAAD4AAAAAB8AAPgA + AAAAHwAA+AAAAAAfAAD4AAAAAB8AAPgAAAAAHwAA+AAAAAAfAAD4AAAAAB8AAPgAAAAAHwAA+AAAAAAf + AAD4AAAAAB8AAPgAAAAAHwAA+AAAAAAfAAD4AAAAAB8AAPgAAAAAHwAA+AAAAAAfAAD4AAAAAB8AAPgA + AAAAHwAA+AAAAAAfAAD4AAAAAB8AAPgAAAAAHwAA+AAAAAAfAAD4AAAAAB8AAP///////wAA + + + \ No newline at end of file diff --git a/Demo_Source_Code/CSharpDemo/SecureShare/WebAPIService.cs b/Demo_Source_Code/CSharpDemo/SecureShare/WebAPIService.cs new file mode 100644 index 0000000..3e6de3d --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/SecureShare/WebAPIService.cs @@ -0,0 +1,296 @@ +using System; +using System.IO; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; +using System.Runtime.InteropServices; +using System.Configuration; +using System.ServiceModel; +using System.Diagnostics; + +using EaseFilter.FilterControl; +using EaseFilter.CommonObjects; + +namespace SecureShare +{ + public static class WebAPIServices + { + public static string serverURI = "http://www.encryptme.net/WebAPI.asmx"; + static string accountName = GlobalConfig.AccountName; + static string password = "testpassword"; + + static WebAPIServices() + { + if (accountName.Trim().Length == 0) + { + accountName = "testaccount." + Environment.MachineName + "." + Guid.NewGuid().ToString(); + GlobalConfig.AccountName = accountName; + } + + accountName = Utils.AESEncryptDecryptStr(accountName, Utils.EncryptType.Encryption); + } + + + private static ServiceReference1.ServiceSoapClient GetServiceClient(ref string lastError) + { + ServiceReference1.ServiceSoapClient client = null; + + try + { + BasicHttpBinding binding = new BasicHttpBinding(); + binding.OpenTimeout = new TimeSpan(0, 0, 10); + binding.CloseTimeout = new TimeSpan(0, 0, 10); + binding.SendTimeout = new TimeSpan(0, 0, 10); + binding.ReceiveTimeout = new TimeSpan(0, 0, 10); + + EndpointAddress endpoint = new EndpointAddress(new Uri(serverURI)); + + client = new SecureShare.ServiceReference1.ServiceSoapClient(binding, endpoint); + } + catch (Exception ex) + { + lastError = "Connecting to server failed with error " + ex.Message; + } + + return client; + } + + public static bool AddShareFile(string policy,ref long creationTime,ref string key,ref string iv, ref string lastError) + { + bool retVal = false; + + try + { + + lastError = string.Empty; + ServiceReference1.ServiceSoapClient client = GetServiceClient(ref lastError); + + if (null == client) + { + return false; + } + + retVal = client.AddShareFile(accountName, password, policy, ref creationTime, ref key, ref iv, ref lastError); + } + catch (Exception ex) + { + lastError = "Add new file to server failed with error:" + ex.Message; + retVal = false; + } + + return retVal; + } + + public static bool GetSharedFilePermission( string fileName, string processName, string userName, string tagStr, ref string iv, ref string key, ref uint accessFlags, ref string lastError) + { + bool retVal = false; + + try + { + + lastError = string.Empty; + ServiceReference1.ServiceSoapClient client = GetServiceClient(ref lastError); + + if (null == client) + { + return false; + } + + string ivStr = tagStr; + string serverAccount = GlobalConfig.AccountName; + int index = tagStr.IndexOf(";"); + if ( index > 0) + { + serverAccount = tagStr.Substring(0, index); + ivStr = tagStr.Substring(index + 1); + } + + UserInfo userInfo = new UserInfo(); + string keyStr = string.Empty; + + userInfo.FileName =fileName; + userInfo.AccountName = serverAccount; + userInfo.ProcessName = processName; + userInfo.UserName = userName; + userInfo.UserPassword = password; + userInfo.CreationTime = DateTime.Now.ToFileTime(); ; + userInfo.EncryptionIV = ivStr; + + string userInfoStr = Utils.EncryptObjectToStr(userInfo); + + retVal = client.GetSharedFilePermission(userInfoStr, ref key, ref iv, ref accessFlags, ref lastError); + } + catch (Exception ex) + { + lastError = "Get file key failed with error:" + ex.Message; + retVal = false; + } + + return retVal; + } + + public static bool GetFileDRInfo( string encryptionIV, ref string encryptedDRPolicy, ref string lastError) + { + bool retVal = false; + + try + { + + lastError = string.Empty; + ServiceReference1.ServiceSoapClient client = GetServiceClient(ref lastError); + + if (null == client) + { + return false; + } + + retVal = client.GetSharedFileDRInfo(accountName, password, encryptionIV, ref encryptedDRPolicy, ref lastError); + + } + catch (Exception ex) + { + lastError = "Get file DR info failed with error:" + ex.Message; + retVal = false; + } + + return retVal; + } + + public static bool ModifySharedFileDRInfo(string encryptedDRPolicy, ref string lastError) + { + bool retVal = false; + + try + { + + lastError = string.Empty; + ServiceReference1.ServiceSoapClient client = GetServiceClient(ref lastError); + + if (null == client) + { + return false; + } + + retVal = client.ModifySharedFileDRInfo(accountName, password, encryptedDRPolicy, ref lastError); + + } + catch (Exception ex) + { + lastError = "Set file DR info failed with error:" + ex.Message; + retVal = false; + } + + return retVal; + } + + public static bool DeleteShareFile( string encryptionIV, ref string lastError) + { + bool retVal = false; + + try + { + + lastError = string.Empty; + ServiceReference1.ServiceSoapClient client = GetServiceClient(ref lastError); + + if (null == client) + { + return false; + } + + retVal = client.DeleteSharedFile(accountName, password, encryptionIV, ref lastError); + + } + catch (Exception ex) + { + lastError = "DeleteShareFile failed with error:" + ex.Message; + retVal = false; + } + + return retVal; + } + + + public static bool GetFileList( ref string fileListStr, ref string lastError) + { + bool retVal = false; + + try + { + lastError = string.Empty; + ServiceReference1.ServiceSoapClient client = GetServiceClient(ref lastError); + + if (null == client) + { + return false; + } + + retVal = client.GetFileList(accountName, password, ref fileListStr, ref lastError); + + } + catch (Exception ex) + { + lastError = "Get file list failed with error:" + ex.Message; + retVal = false; + } + + return retVal; + } + + public static bool GetAccessLog(ref string accessLog, ref string lastError) + { + bool retVal = false; + + try + { + + lastError = string.Empty; + ServiceReference1.ServiceSoapClient client = GetServiceClient(ref lastError); + + if (null == client) + { + return false; + } + + retVal = client.GetAccessLog(accountName, password, ref accessLog, ref lastError); + } + catch (Exception ex) + { + lastError = "Get access log failed with error:" + ex.Message; + retVal = false; + } + + return retVal; + } + + public static bool ClearAccessLog(ref string lastError) + { + bool retVal = false; + + try + { + + lastError = string.Empty; + ServiceReference1.ServiceSoapClient client = GetServiceClient(ref lastError); + + if (null == client) + { + return false; + } + + retVal = client.ClearAccessLog(accountName, password, ref lastError); + } + catch (Exception ex) + { + lastError = "Clear access log failed with error:" + ex.Message; + retVal = false; + } + + return retVal; + } + } +} diff --git a/Demo_Source_Code/CSharpDemo/SecureShare/app.config b/Demo_Source_Code/CSharpDemo/SecureShare/app.config new file mode 100644 index 0000000..193d618 --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/SecureShare/app.config @@ -0,0 +1,7 @@ + + + + + + + diff --git a/Demo_Source_Code/CSharpDemo/SecureShare/app.manifest b/Demo_Source_Code/CSharpDemo/SecureShare/app.manifest new file mode 100644 index 0000000..ef8303a --- /dev/null +++ b/Demo_Source_Code/CSharpDemo/SecureShare/app.manifest @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Demo_Source_Code/Demo.sln b/Demo_Source_Code/Demo.sln index 0ff1365..8707006 100644 --- a/Demo_Source_Code/Demo.sln +++ b/Demo_Source_Code/Demo.sln @@ -1,50 +1,52 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.26228.73 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.34902.97 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CommonObjects", "CommonObjects\CommonObjects.csproj", "{34CB783E-DDA2-4CE3-80BC-37B25AA33E5F}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CommonObjects", "CSharpDemo\CommonObjects\CommonObjects.csproj", "{34CB783E-DDA2-4CE3-80BC-37B25AA33E5F}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FileMonitor", "FileMonitor\FileMonitor.csproj", "{F50E9F98-5BFA-4CF2-9373-0D8E0A623E60}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FileMonitor", "CSharpDemo\FileMonitor\FileMonitor.csproj", "{F50E9F98-5BFA-4CF2-9373-0D8E0A623E60}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FileProtector", "FileProtector\FileProtector.csproj", "{5D68B347-6B7E-4B0A-9DBF-82E287A52A21}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FileProtector", "CSharpDemo\FileProtector\FileProtector.csproj", "{5D68B347-6B7E-4B0A-9DBF-82E287A52A21}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "CSharpDemo", "CSharpDemo", "{9962A820-513B-4A87-8313-0D8F6EA3765A}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "CPlusPlusDemo", "CPlusPlusDemo", "{7C8FC956-4439-4917-BE4F-ED8F97B80863}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "EaseFltCPPDemo", "EaseFltCPPDemo\EaseFltCPPDemo.vcxproj", "{E9382993-43C9-4CEC-9D94-90DEF64FD214}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AutoFileCryptTool", "CSharpDemo\AutoFileCryptTool\AutoFileCryptTool.csproj", "{BCEBE26C-6C20-4086-AF65-76113DE08189}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AutoFileCryptTool", "AutoFileCryptTool\AutoFileCryptTool.csproj", "{BCEBE26C-6C20-4086-AF65-76113DE08189}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EaseFltCSConsoleDemo", "CSharpDemo\EaseFltCSConsoleDemo\EaseFltCSConsoleDemo.csproj", "{B2571F4D-C611-409C-A885-53FDDA045269}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EaseFltCSConsoleDemo", "EaseFltCSConsoleDemo\EaseFltCSConsoleDemo.csproj", "{B2571F4D-C611-409C-A885-53FDDA045269}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RegMon", "CSharpDemo\RegMon\RegMon.csproj", "{3159257E-F264-4B6A-B96E-F3D46ABF90A3}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RegMon", "RegMon\RegMon.csproj", "{3159257E-F264-4B6A-B96E-F3D46ABF90A3}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProcessMon", "CSharpDemo\ProcessMon\ProcessMon.csproj", "{BB797E16-A353-478D-9335-1D1B6AED38F8}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProcessMon", "ProcessMon\ProcessMon.csproj", "{BB797E16-A353-478D-9335-1D1B6AED38F8}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SecureSandbox", "CSharpDemo\SecureSandbox\SecureSandbox.csproj", "{E6D17F25-C5AA-4C56-906C-0B9B35E600BC}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SecureSandbox", "SecureSandbox\SecureSandbox.csproj", "{E6D17F25-C5AA-4C56-906C-0B9B35E600BC}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FolderLocker", "CSharpDemo\FolderLocker\FolderLocker.csproj", "{8EB7E6DC-D83A-45E7-9F09-72931F2EED66}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FolderLocker", "FolderLocker\FolderLocker.csproj", "{8EB7E6DC-D83A-45E7-9F09-72931F2EED66}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SecureShare", "CSharpDemo\SecureShare\SecureShare.csproj", "{32877C42-32C7-411F-B110-CF2FD9CF11D8}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SecureShare", "SecureShare\SecureShare.csproj", "{32877C42-32C7-411F-B110-CF2FD9CF11D8}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FilterControl", "CSharpDemo\FilterControl\FilterControl.csproj", "{21540012-A296-45CE-8D35-3EA5A07B32A6}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FilterControl", "FilterControl\FilterControl.csproj", "{21540012-A296-45CE-8D35-3EA5A07B32A6}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AutoEncryptDemo", "CSharpDemo\AutoEncryptDemo\AutoEncryptDemo.csproj", "{89B88C2F-1FF5-4D84-A010-6BF74436576B}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AutoEncryptDemo", "AutoEncryptDemo\AutoEncryptDemo.csproj", "{89B88C2F-1FF5-4D84-A010-6BF74436576B}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FileMonitorConsole", "CSharpDemo\FileMonitorConsole\FileMonitorConsole.csproj", "{D2549779-D9A0-4A92-9390-93973CC5249A}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FileMonitorConsole", "FileMonitorConsole\FileMonitorConsole.csproj", "{D2549779-D9A0-4A92-9390-93973CC5249A}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FileProtectorConsole", "CSharpDemo\FileProtectorConsole\FileProtectorConsole.csproj", "{1A0641F2-8857-46D7-965D-B6B3BD1771BC}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FileProtectorConsole", "FileProtectorConsole\FileProtectorConsole.csproj", "{1A0641F2-8857-46D7-965D-B6B3BD1771BC}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "EaseFltCPPDemo", "CPlusPlusDemo\EaseFltCPPDemo.vs2019.vcxproj", "{E9382993-43C9-4CEC-9D94-90DEF64FD214}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU + Debug|ARM64 = Debug|ARM64 Debug|Mixed Platforms = Debug|Mixed Platforms Debug|Win32 = Debug|Win32 Debug|x64 = Debug|x64 Debug|x86 = Debug|x86 Release|Any CPU = Release|Any CPU + Release|ARM64 = Release|ARM64 Release|Mixed Platforms = Release|Mixed Platforms Release|Win32 = Release|Win32 Release|x64 = Release|x64 @@ -53,6 +55,7 @@ Global GlobalSection(ProjectConfigurationPlatforms) = postSolution {34CB783E-DDA2-4CE3-80BC-37B25AA33E5F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {34CB783E-DDA2-4CE3-80BC-37B25AA33E5F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {34CB783E-DDA2-4CE3-80BC-37B25AA33E5F}.Debug|ARM64.ActiveCfg = Debug|Any CPU {34CB783E-DDA2-4CE3-80BC-37B25AA33E5F}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU {34CB783E-DDA2-4CE3-80BC-37B25AA33E5F}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU {34CB783E-DDA2-4CE3-80BC-37B25AA33E5F}.Debug|Win32.ActiveCfg = Debug|Any CPU @@ -62,6 +65,7 @@ Global {34CB783E-DDA2-4CE3-80BC-37B25AA33E5F}.Debug|x86.ActiveCfg = Debug|Any CPU {34CB783E-DDA2-4CE3-80BC-37B25AA33E5F}.Release|Any CPU.ActiveCfg = Release|Any CPU {34CB783E-DDA2-4CE3-80BC-37B25AA33E5F}.Release|Any CPU.Build.0 = Release|Any CPU + {34CB783E-DDA2-4CE3-80BC-37B25AA33E5F}.Release|ARM64.ActiveCfg = Release|Any CPU {34CB783E-DDA2-4CE3-80BC-37B25AA33E5F}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU {34CB783E-DDA2-4CE3-80BC-37B25AA33E5F}.Release|Mixed Platforms.Build.0 = Release|Any CPU {34CB783E-DDA2-4CE3-80BC-37B25AA33E5F}.Release|Win32.ActiveCfg = Release|Any CPU @@ -69,6 +73,7 @@ Global {34CB783E-DDA2-4CE3-80BC-37B25AA33E5F}.Release|x64.Build.0 = Release|Any CPU {34CB783E-DDA2-4CE3-80BC-37B25AA33E5F}.Release|x86.ActiveCfg = Release|Any CPU {F50E9F98-5BFA-4CF2-9373-0D8E0A623E60}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F50E9F98-5BFA-4CF2-9373-0D8E0A623E60}.Debug|ARM64.ActiveCfg = Debug|Any CPU {F50E9F98-5BFA-4CF2-9373-0D8E0A623E60}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU {F50E9F98-5BFA-4CF2-9373-0D8E0A623E60}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU {F50E9F98-5BFA-4CF2-9373-0D8E0A623E60}.Debug|Win32.ActiveCfg = Debug|Any CPU @@ -78,6 +83,7 @@ Global {F50E9F98-5BFA-4CF2-9373-0D8E0A623E60}.Debug|x86.ActiveCfg = Debug|x86 {F50E9F98-5BFA-4CF2-9373-0D8E0A623E60}.Debug|x86.Build.0 = Debug|x86 {F50E9F98-5BFA-4CF2-9373-0D8E0A623E60}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F50E9F98-5BFA-4CF2-9373-0D8E0A623E60}.Release|ARM64.ActiveCfg = Release|Any CPU {F50E9F98-5BFA-4CF2-9373-0D8E0A623E60}.Release|Mixed Platforms.ActiveCfg = Release|x86 {F50E9F98-5BFA-4CF2-9373-0D8E0A623E60}.Release|Mixed Platforms.Build.0 = Release|x86 {F50E9F98-5BFA-4CF2-9373-0D8E0A623E60}.Release|Win32.ActiveCfg = Release|Any CPU @@ -86,6 +92,7 @@ Global {F50E9F98-5BFA-4CF2-9373-0D8E0A623E60}.Release|x86.ActiveCfg = Release|x86 {F50E9F98-5BFA-4CF2-9373-0D8E0A623E60}.Release|x86.Build.0 = Release|x86 {5D68B347-6B7E-4B0A-9DBF-82E287A52A21}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5D68B347-6B7E-4B0A-9DBF-82E287A52A21}.Debug|ARM64.ActiveCfg = Debug|Any CPU {5D68B347-6B7E-4B0A-9DBF-82E287A52A21}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU {5D68B347-6B7E-4B0A-9DBF-82E287A52A21}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU {5D68B347-6B7E-4B0A-9DBF-82E287A52A21}.Debug|Win32.ActiveCfg = Debug|Any CPU @@ -95,6 +102,7 @@ Global {5D68B347-6B7E-4B0A-9DBF-82E287A52A21}.Debug|x86.ActiveCfg = Debug|x86 {5D68B347-6B7E-4B0A-9DBF-82E287A52A21}.Debug|x86.Build.0 = Debug|x86 {5D68B347-6B7E-4B0A-9DBF-82E287A52A21}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5D68B347-6B7E-4B0A-9DBF-82E287A52A21}.Release|ARM64.ActiveCfg = Release|Any CPU {5D68B347-6B7E-4B0A-9DBF-82E287A52A21}.Release|Mixed Platforms.ActiveCfg = Release|x86 {5D68B347-6B7E-4B0A-9DBF-82E287A52A21}.Release|Mixed Platforms.Build.0 = Release|x86 {5D68B347-6B7E-4B0A-9DBF-82E287A52A21}.Release|Win32.ActiveCfg = Release|Any CPU @@ -102,22 +110,8 @@ Global {5D68B347-6B7E-4B0A-9DBF-82E287A52A21}.Release|x64.Build.0 = Release|Any CPU {5D68B347-6B7E-4B0A-9DBF-82E287A52A21}.Release|x86.ActiveCfg = Release|x86 {5D68B347-6B7E-4B0A-9DBF-82E287A52A21}.Release|x86.Build.0 = Release|x86 - {E9382993-43C9-4CEC-9D94-90DEF64FD214}.Debug|Any CPU.ActiveCfg = Debug|x64 - {E9382993-43C9-4CEC-9D94-90DEF64FD214}.Debug|Mixed Platforms.ActiveCfg = Debug|x64 - {E9382993-43C9-4CEC-9D94-90DEF64FD214}.Debug|Mixed Platforms.Build.0 = Debug|x64 - {E9382993-43C9-4CEC-9D94-90DEF64FD214}.Debug|Win32.ActiveCfg = Debug|Win32 - {E9382993-43C9-4CEC-9D94-90DEF64FD214}.Debug|x64.ActiveCfg = Debug|x64 - {E9382993-43C9-4CEC-9D94-90DEF64FD214}.Debug|x64.Build.0 = Debug|x64 - {E9382993-43C9-4CEC-9D94-90DEF64FD214}.Debug|x86.ActiveCfg = Debug|x64 - {E9382993-43C9-4CEC-9D94-90DEF64FD214}.Release|Any CPU.ActiveCfg = Release|x64 - {E9382993-43C9-4CEC-9D94-90DEF64FD214}.Release|Mixed Platforms.ActiveCfg = Release|x64 - {E9382993-43C9-4CEC-9D94-90DEF64FD214}.Release|Mixed Platforms.Build.0 = Release|x64 - {E9382993-43C9-4CEC-9D94-90DEF64FD214}.Release|Win32.ActiveCfg = Release|Win32 - {E9382993-43C9-4CEC-9D94-90DEF64FD214}.Release|Win32.Build.0 = Release|Win32 - {E9382993-43C9-4CEC-9D94-90DEF64FD214}.Release|x64.ActiveCfg = Release|x64 - {E9382993-43C9-4CEC-9D94-90DEF64FD214}.Release|x64.Build.0 = Release|x64 - {E9382993-43C9-4CEC-9D94-90DEF64FD214}.Release|x86.ActiveCfg = Release|x64 {BCEBE26C-6C20-4086-AF65-76113DE08189}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BCEBE26C-6C20-4086-AF65-76113DE08189}.Debug|ARM64.ActiveCfg = Debug|Any CPU {BCEBE26C-6C20-4086-AF65-76113DE08189}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU {BCEBE26C-6C20-4086-AF65-76113DE08189}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU {BCEBE26C-6C20-4086-AF65-76113DE08189}.Debug|Win32.ActiveCfg = Debug|Any CPU @@ -127,6 +121,7 @@ Global {BCEBE26C-6C20-4086-AF65-76113DE08189}.Debug|x86.ActiveCfg = Debug|x86 {BCEBE26C-6C20-4086-AF65-76113DE08189}.Debug|x86.Build.0 = Debug|x86 {BCEBE26C-6C20-4086-AF65-76113DE08189}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BCEBE26C-6C20-4086-AF65-76113DE08189}.Release|ARM64.ActiveCfg = Release|Any CPU {BCEBE26C-6C20-4086-AF65-76113DE08189}.Release|Mixed Platforms.ActiveCfg = Release|x86 {BCEBE26C-6C20-4086-AF65-76113DE08189}.Release|Mixed Platforms.Build.0 = Release|x86 {BCEBE26C-6C20-4086-AF65-76113DE08189}.Release|Win32.ActiveCfg = Release|Any CPU @@ -136,6 +131,7 @@ Global {BCEBE26C-6C20-4086-AF65-76113DE08189}.Release|x86.Build.0 = Release|x86 {B2571F4D-C611-409C-A885-53FDDA045269}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {B2571F4D-C611-409C-A885-53FDDA045269}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B2571F4D-C611-409C-A885-53FDDA045269}.Debug|ARM64.ActiveCfg = Debug|Any CPU {B2571F4D-C611-409C-A885-53FDDA045269}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU {B2571F4D-C611-409C-A885-53FDDA045269}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU {B2571F4D-C611-409C-A885-53FDDA045269}.Debug|Win32.ActiveCfg = Debug|Any CPU @@ -143,141 +139,202 @@ Global {B2571F4D-C611-409C-A885-53FDDA045269}.Debug|x86.ActiveCfg = Debug|Any CPU {B2571F4D-C611-409C-A885-53FDDA045269}.Release|Any CPU.ActiveCfg = Release|Any CPU {B2571F4D-C611-409C-A885-53FDDA045269}.Release|Any CPU.Build.0 = Release|Any CPU + {B2571F4D-C611-409C-A885-53FDDA045269}.Release|ARM64.ActiveCfg = Release|Any CPU {B2571F4D-C611-409C-A885-53FDDA045269}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU {B2571F4D-C611-409C-A885-53FDDA045269}.Release|Mixed Platforms.Build.0 = Release|Any CPU {B2571F4D-C611-409C-A885-53FDDA045269}.Release|Win32.ActiveCfg = Release|Any CPU {B2571F4D-C611-409C-A885-53FDDA045269}.Release|x64.ActiveCfg = Release|Any CPU + {B2571F4D-C611-409C-A885-53FDDA045269}.Release|x64.Build.0 = Release|Any CPU {B2571F4D-C611-409C-A885-53FDDA045269}.Release|x86.ActiveCfg = Release|Any CPU {3159257E-F264-4B6A-B96E-F3D46ABF90A3}.Debug|Any CPU.ActiveCfg = Debug|x86 + {3159257E-F264-4B6A-B96E-F3D46ABF90A3}.Debug|ARM64.ActiveCfg = Debug|x86 {3159257E-F264-4B6A-B96E-F3D46ABF90A3}.Debug|Mixed Platforms.ActiveCfg = Debug|x86 {3159257E-F264-4B6A-B96E-F3D46ABF90A3}.Debug|Mixed Platforms.Build.0 = Debug|x86 {3159257E-F264-4B6A-B96E-F3D46ABF90A3}.Debug|Win32.ActiveCfg = Debug|x86 - {3159257E-F264-4B6A-B96E-F3D46ABF90A3}.Debug|x64.ActiveCfg = Debug|x86 + {3159257E-F264-4B6A-B96E-F3D46ABF90A3}.Debug|x64.ActiveCfg = Debug|Any CPU + {3159257E-F264-4B6A-B96E-F3D46ABF90A3}.Debug|x64.Build.0 = Debug|Any CPU {3159257E-F264-4B6A-B96E-F3D46ABF90A3}.Debug|x86.ActiveCfg = Debug|x86 {3159257E-F264-4B6A-B96E-F3D46ABF90A3}.Debug|x86.Build.0 = Debug|x86 {3159257E-F264-4B6A-B96E-F3D46ABF90A3}.Release|Any CPU.ActiveCfg = Release|x86 + {3159257E-F264-4B6A-B96E-F3D46ABF90A3}.Release|ARM64.ActiveCfg = Release|x86 {3159257E-F264-4B6A-B96E-F3D46ABF90A3}.Release|Mixed Platforms.ActiveCfg = Release|x86 {3159257E-F264-4B6A-B96E-F3D46ABF90A3}.Release|Mixed Platforms.Build.0 = Release|x86 {3159257E-F264-4B6A-B96E-F3D46ABF90A3}.Release|Win32.ActiveCfg = Release|x86 - {3159257E-F264-4B6A-B96E-F3D46ABF90A3}.Release|x64.ActiveCfg = Release|x86 + {3159257E-F264-4B6A-B96E-F3D46ABF90A3}.Release|x64.ActiveCfg = Release|Any CPU + {3159257E-F264-4B6A-B96E-F3D46ABF90A3}.Release|x64.Build.0 = Release|Any CPU {3159257E-F264-4B6A-B96E-F3D46ABF90A3}.Release|x86.ActiveCfg = Release|x86 {3159257E-F264-4B6A-B96E-F3D46ABF90A3}.Release|x86.Build.0 = Release|x86 {BB797E16-A353-478D-9335-1D1B6AED38F8}.Debug|Any CPU.ActiveCfg = Debug|x86 + {BB797E16-A353-478D-9335-1D1B6AED38F8}.Debug|ARM64.ActiveCfg = Debug|x86 {BB797E16-A353-478D-9335-1D1B6AED38F8}.Debug|Mixed Platforms.ActiveCfg = Debug|x86 {BB797E16-A353-478D-9335-1D1B6AED38F8}.Debug|Mixed Platforms.Build.0 = Debug|x86 {BB797E16-A353-478D-9335-1D1B6AED38F8}.Debug|Win32.ActiveCfg = Debug|x86 - {BB797E16-A353-478D-9335-1D1B6AED38F8}.Debug|x64.ActiveCfg = Debug|x86 + {BB797E16-A353-478D-9335-1D1B6AED38F8}.Debug|x64.ActiveCfg = Debug|Any CPU + {BB797E16-A353-478D-9335-1D1B6AED38F8}.Debug|x64.Build.0 = Debug|Any CPU {BB797E16-A353-478D-9335-1D1B6AED38F8}.Debug|x86.ActiveCfg = Debug|x86 {BB797E16-A353-478D-9335-1D1B6AED38F8}.Debug|x86.Build.0 = Debug|x86 {BB797E16-A353-478D-9335-1D1B6AED38F8}.Release|Any CPU.ActiveCfg = Release|x86 + {BB797E16-A353-478D-9335-1D1B6AED38F8}.Release|ARM64.ActiveCfg = Release|x86 {BB797E16-A353-478D-9335-1D1B6AED38F8}.Release|Mixed Platforms.ActiveCfg = Release|x86 {BB797E16-A353-478D-9335-1D1B6AED38F8}.Release|Mixed Platforms.Build.0 = Release|x86 {BB797E16-A353-478D-9335-1D1B6AED38F8}.Release|Win32.ActiveCfg = Release|x86 - {BB797E16-A353-478D-9335-1D1B6AED38F8}.Release|x64.ActiveCfg = Release|x86 + {BB797E16-A353-478D-9335-1D1B6AED38F8}.Release|x64.ActiveCfg = Release|Any CPU + {BB797E16-A353-478D-9335-1D1B6AED38F8}.Release|x64.Build.0 = Release|Any CPU {BB797E16-A353-478D-9335-1D1B6AED38F8}.Release|x86.ActiveCfg = Release|x86 {BB797E16-A353-478D-9335-1D1B6AED38F8}.Release|x86.Build.0 = Release|x86 {E6D17F25-C5AA-4C56-906C-0B9B35E600BC}.Debug|Any CPU.ActiveCfg = Debug|x86 + {E6D17F25-C5AA-4C56-906C-0B9B35E600BC}.Debug|ARM64.ActiveCfg = Debug|x86 {E6D17F25-C5AA-4C56-906C-0B9B35E600BC}.Debug|Mixed Platforms.ActiveCfg = Debug|x86 {E6D17F25-C5AA-4C56-906C-0B9B35E600BC}.Debug|Mixed Platforms.Build.0 = Debug|x86 {E6D17F25-C5AA-4C56-906C-0B9B35E600BC}.Debug|Win32.ActiveCfg = Debug|x86 - {E6D17F25-C5AA-4C56-906C-0B9B35E600BC}.Debug|x64.ActiveCfg = Debug|x86 + {E6D17F25-C5AA-4C56-906C-0B9B35E600BC}.Debug|x64.ActiveCfg = Debug|Any CPU + {E6D17F25-C5AA-4C56-906C-0B9B35E600BC}.Debug|x64.Build.0 = Debug|Any CPU {E6D17F25-C5AA-4C56-906C-0B9B35E600BC}.Debug|x86.ActiveCfg = Debug|x86 {E6D17F25-C5AA-4C56-906C-0B9B35E600BC}.Debug|x86.Build.0 = Debug|x86 {E6D17F25-C5AA-4C56-906C-0B9B35E600BC}.Release|Any CPU.ActiveCfg = Release|x86 + {E6D17F25-C5AA-4C56-906C-0B9B35E600BC}.Release|ARM64.ActiveCfg = Release|x86 {E6D17F25-C5AA-4C56-906C-0B9B35E600BC}.Release|Mixed Platforms.ActiveCfg = Release|x86 {E6D17F25-C5AA-4C56-906C-0B9B35E600BC}.Release|Mixed Platforms.Build.0 = Release|x86 {E6D17F25-C5AA-4C56-906C-0B9B35E600BC}.Release|Win32.ActiveCfg = Release|x86 - {E6D17F25-C5AA-4C56-906C-0B9B35E600BC}.Release|x64.ActiveCfg = Release|x86 + {E6D17F25-C5AA-4C56-906C-0B9B35E600BC}.Release|x64.ActiveCfg = Release|Any CPU + {E6D17F25-C5AA-4C56-906C-0B9B35E600BC}.Release|x64.Build.0 = Release|Any CPU {E6D17F25-C5AA-4C56-906C-0B9B35E600BC}.Release|x86.ActiveCfg = Release|x86 {E6D17F25-C5AA-4C56-906C-0B9B35E600BC}.Release|x86.Build.0 = Release|x86 {8EB7E6DC-D83A-45E7-9F09-72931F2EED66}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {8EB7E6DC-D83A-45E7-9F09-72931F2EED66}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8EB7E6DC-D83A-45E7-9F09-72931F2EED66}.Debug|ARM64.ActiveCfg = Debug|Any CPU {8EB7E6DC-D83A-45E7-9F09-72931F2EED66}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU {8EB7E6DC-D83A-45E7-9F09-72931F2EED66}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU {8EB7E6DC-D83A-45E7-9F09-72931F2EED66}.Debug|Win32.ActiveCfg = Debug|Any CPU - {8EB7E6DC-D83A-45E7-9F09-72931F2EED66}.Debug|x64.ActiveCfg = Debug|x86 + {8EB7E6DC-D83A-45E7-9F09-72931F2EED66}.Debug|x64.ActiveCfg = Debug|Any CPU + {8EB7E6DC-D83A-45E7-9F09-72931F2EED66}.Debug|x64.Build.0 = Debug|Any CPU {8EB7E6DC-D83A-45E7-9F09-72931F2EED66}.Debug|x86.ActiveCfg = Debug|x86 {8EB7E6DC-D83A-45E7-9F09-72931F2EED66}.Debug|x86.Build.0 = Debug|x86 {8EB7E6DC-D83A-45E7-9F09-72931F2EED66}.Release|Any CPU.ActiveCfg = Release|Any CPU {8EB7E6DC-D83A-45E7-9F09-72931F2EED66}.Release|Any CPU.Build.0 = Release|Any CPU + {8EB7E6DC-D83A-45E7-9F09-72931F2EED66}.Release|ARM64.ActiveCfg = Release|Any CPU {8EB7E6DC-D83A-45E7-9F09-72931F2EED66}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU {8EB7E6DC-D83A-45E7-9F09-72931F2EED66}.Release|Mixed Platforms.Build.0 = Release|Any CPU {8EB7E6DC-D83A-45E7-9F09-72931F2EED66}.Release|Win32.ActiveCfg = Release|Any CPU - {8EB7E6DC-D83A-45E7-9F09-72931F2EED66}.Release|x64.ActiveCfg = Release|x86 + {8EB7E6DC-D83A-45E7-9F09-72931F2EED66}.Release|x64.ActiveCfg = Release|Any CPU + {8EB7E6DC-D83A-45E7-9F09-72931F2EED66}.Release|x64.Build.0 = Release|Any CPU {8EB7E6DC-D83A-45E7-9F09-72931F2EED66}.Release|x86.ActiveCfg = Release|x86 {8EB7E6DC-D83A-45E7-9F09-72931F2EED66}.Release|x86.Build.0 = Release|x86 {32877C42-32C7-411F-B110-CF2FD9CF11D8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {32877C42-32C7-411F-B110-CF2FD9CF11D8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {32877C42-32C7-411F-B110-CF2FD9CF11D8}.Debug|ARM64.ActiveCfg = Debug|Any CPU {32877C42-32C7-411F-B110-CF2FD9CF11D8}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU {32877C42-32C7-411F-B110-CF2FD9CF11D8}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU {32877C42-32C7-411F-B110-CF2FD9CF11D8}.Debug|Win32.ActiveCfg = Debug|Any CPU - {32877C42-32C7-411F-B110-CF2FD9CF11D8}.Debug|x64.ActiveCfg = Debug|x86 + {32877C42-32C7-411F-B110-CF2FD9CF11D8}.Debug|x64.ActiveCfg = Debug|Any CPU + {32877C42-32C7-411F-B110-CF2FD9CF11D8}.Debug|x64.Build.0 = Debug|Any CPU {32877C42-32C7-411F-B110-CF2FD9CF11D8}.Debug|x86.ActiveCfg = Debug|x86 {32877C42-32C7-411F-B110-CF2FD9CF11D8}.Debug|x86.Build.0 = Debug|x86 {32877C42-32C7-411F-B110-CF2FD9CF11D8}.Release|Any CPU.ActiveCfg = Release|Any CPU {32877C42-32C7-411F-B110-CF2FD9CF11D8}.Release|Any CPU.Build.0 = Release|Any CPU + {32877C42-32C7-411F-B110-CF2FD9CF11D8}.Release|ARM64.ActiveCfg = Release|Any CPU {32877C42-32C7-411F-B110-CF2FD9CF11D8}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU {32877C42-32C7-411F-B110-CF2FD9CF11D8}.Release|Mixed Platforms.Build.0 = Release|Any CPU {32877C42-32C7-411F-B110-CF2FD9CF11D8}.Release|Win32.ActiveCfg = Release|Any CPU - {32877C42-32C7-411F-B110-CF2FD9CF11D8}.Release|x64.ActiveCfg = Release|x86 + {32877C42-32C7-411F-B110-CF2FD9CF11D8}.Release|x64.ActiveCfg = Release|Any CPU + {32877C42-32C7-411F-B110-CF2FD9CF11D8}.Release|x64.Build.0 = Release|Any CPU {32877C42-32C7-411F-B110-CF2FD9CF11D8}.Release|x86.ActiveCfg = Release|x86 {32877C42-32C7-411F-B110-CF2FD9CF11D8}.Release|x86.Build.0 = Release|x86 {21540012-A296-45CE-8D35-3EA5A07B32A6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {21540012-A296-45CE-8D35-3EA5A07B32A6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {21540012-A296-45CE-8D35-3EA5A07B32A6}.Debug|ARM64.ActiveCfg = Debug|Any CPU {21540012-A296-45CE-8D35-3EA5A07B32A6}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU {21540012-A296-45CE-8D35-3EA5A07B32A6}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU {21540012-A296-45CE-8D35-3EA5A07B32A6}.Debug|Win32.ActiveCfg = Debug|Any CPU {21540012-A296-45CE-8D35-3EA5A07B32A6}.Debug|x64.ActiveCfg = Debug|Any CPU + {21540012-A296-45CE-8D35-3EA5A07B32A6}.Debug|x64.Build.0 = Debug|Any CPU {21540012-A296-45CE-8D35-3EA5A07B32A6}.Debug|x86.ActiveCfg = Debug|Any CPU {21540012-A296-45CE-8D35-3EA5A07B32A6}.Release|Any CPU.ActiveCfg = Release|Any CPU {21540012-A296-45CE-8D35-3EA5A07B32A6}.Release|Any CPU.Build.0 = Release|Any CPU + {21540012-A296-45CE-8D35-3EA5A07B32A6}.Release|ARM64.ActiveCfg = Release|Any CPU {21540012-A296-45CE-8D35-3EA5A07B32A6}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU {21540012-A296-45CE-8D35-3EA5A07B32A6}.Release|Mixed Platforms.Build.0 = Release|Any CPU {21540012-A296-45CE-8D35-3EA5A07B32A6}.Release|Win32.ActiveCfg = Release|Any CPU {21540012-A296-45CE-8D35-3EA5A07B32A6}.Release|x64.ActiveCfg = Release|Any CPU + {21540012-A296-45CE-8D35-3EA5A07B32A6}.Release|x64.Build.0 = Release|Any CPU {21540012-A296-45CE-8D35-3EA5A07B32A6}.Release|x86.ActiveCfg = Release|Any CPU + {21540012-A296-45CE-8D35-3EA5A07B32A6}.Release|x86.Build.0 = Release|Any CPU {89B88C2F-1FF5-4D84-A010-6BF74436576B}.Debug|Any CPU.ActiveCfg = Debug|x86 + {89B88C2F-1FF5-4D84-A010-6BF74436576B}.Debug|ARM64.ActiveCfg = Debug|x86 {89B88C2F-1FF5-4D84-A010-6BF74436576B}.Debug|Mixed Platforms.ActiveCfg = Debug|x86 {89B88C2F-1FF5-4D84-A010-6BF74436576B}.Debug|Mixed Platforms.Build.0 = Debug|x86 {89B88C2F-1FF5-4D84-A010-6BF74436576B}.Debug|Win32.ActiveCfg = Debug|x86 - {89B88C2F-1FF5-4D84-A010-6BF74436576B}.Debug|x64.ActiveCfg = Debug|x86 + {89B88C2F-1FF5-4D84-A010-6BF74436576B}.Debug|x64.ActiveCfg = Debug|Any CPU + {89B88C2F-1FF5-4D84-A010-6BF74436576B}.Debug|x64.Build.0 = Debug|Any CPU {89B88C2F-1FF5-4D84-A010-6BF74436576B}.Debug|x86.ActiveCfg = Debug|x86 {89B88C2F-1FF5-4D84-A010-6BF74436576B}.Debug|x86.Build.0 = Debug|x86 {89B88C2F-1FF5-4D84-A010-6BF74436576B}.Release|Any CPU.ActiveCfg = Release|x86 + {89B88C2F-1FF5-4D84-A010-6BF74436576B}.Release|ARM64.ActiveCfg = Release|x86 {89B88C2F-1FF5-4D84-A010-6BF74436576B}.Release|Mixed Platforms.ActiveCfg = Release|x86 {89B88C2F-1FF5-4D84-A010-6BF74436576B}.Release|Mixed Platforms.Build.0 = Release|x86 {89B88C2F-1FF5-4D84-A010-6BF74436576B}.Release|Win32.ActiveCfg = Release|x86 - {89B88C2F-1FF5-4D84-A010-6BF74436576B}.Release|x64.ActiveCfg = Release|x86 + {89B88C2F-1FF5-4D84-A010-6BF74436576B}.Release|x64.ActiveCfg = Release|Any CPU + {89B88C2F-1FF5-4D84-A010-6BF74436576B}.Release|x64.Build.0 = Release|Any CPU {89B88C2F-1FF5-4D84-A010-6BF74436576B}.Release|x86.ActiveCfg = Release|x86 {89B88C2F-1FF5-4D84-A010-6BF74436576B}.Release|x86.Build.0 = Release|x86 {D2549779-D9A0-4A92-9390-93973CC5249A}.Debug|Any CPU.ActiveCfg = Debug|x86 + {D2549779-D9A0-4A92-9390-93973CC5249A}.Debug|ARM64.ActiveCfg = Debug|x86 {D2549779-D9A0-4A92-9390-93973CC5249A}.Debug|Mixed Platforms.ActiveCfg = Debug|x86 {D2549779-D9A0-4A92-9390-93973CC5249A}.Debug|Mixed Platforms.Build.0 = Debug|x86 {D2549779-D9A0-4A92-9390-93973CC5249A}.Debug|Win32.ActiveCfg = Debug|x86 - {D2549779-D9A0-4A92-9390-93973CC5249A}.Debug|x64.ActiveCfg = Debug|x86 + {D2549779-D9A0-4A92-9390-93973CC5249A}.Debug|x64.ActiveCfg = Debug|Any CPU + {D2549779-D9A0-4A92-9390-93973CC5249A}.Debug|x64.Build.0 = Debug|Any CPU {D2549779-D9A0-4A92-9390-93973CC5249A}.Debug|x86.ActiveCfg = Debug|x86 {D2549779-D9A0-4A92-9390-93973CC5249A}.Debug|x86.Build.0 = Debug|x86 {D2549779-D9A0-4A92-9390-93973CC5249A}.Release|Any CPU.ActiveCfg = Release|x86 + {D2549779-D9A0-4A92-9390-93973CC5249A}.Release|ARM64.ActiveCfg = Release|x86 {D2549779-D9A0-4A92-9390-93973CC5249A}.Release|Mixed Platforms.ActiveCfg = Release|x86 {D2549779-D9A0-4A92-9390-93973CC5249A}.Release|Mixed Platforms.Build.0 = Release|x86 {D2549779-D9A0-4A92-9390-93973CC5249A}.Release|Win32.ActiveCfg = Release|x86 - {D2549779-D9A0-4A92-9390-93973CC5249A}.Release|x64.ActiveCfg = Release|x86 + {D2549779-D9A0-4A92-9390-93973CC5249A}.Release|x64.ActiveCfg = Release|Any CPU + {D2549779-D9A0-4A92-9390-93973CC5249A}.Release|x64.Build.0 = Release|Any CPU {D2549779-D9A0-4A92-9390-93973CC5249A}.Release|x86.ActiveCfg = Release|x86 {D2549779-D9A0-4A92-9390-93973CC5249A}.Release|x86.Build.0 = Release|x86 {1A0641F2-8857-46D7-965D-B6B3BD1771BC}.Debug|Any CPU.ActiveCfg = Debug|x86 + {1A0641F2-8857-46D7-965D-B6B3BD1771BC}.Debug|ARM64.ActiveCfg = Debug|x86 {1A0641F2-8857-46D7-965D-B6B3BD1771BC}.Debug|Mixed Platforms.ActiveCfg = Debug|x86 {1A0641F2-8857-46D7-965D-B6B3BD1771BC}.Debug|Mixed Platforms.Build.0 = Debug|x86 {1A0641F2-8857-46D7-965D-B6B3BD1771BC}.Debug|Win32.ActiveCfg = Debug|x86 - {1A0641F2-8857-46D7-965D-B6B3BD1771BC}.Debug|x64.ActiveCfg = Debug|x86 + {1A0641F2-8857-46D7-965D-B6B3BD1771BC}.Debug|x64.ActiveCfg = Debug|Any CPU + {1A0641F2-8857-46D7-965D-B6B3BD1771BC}.Debug|x64.Build.0 = Debug|Any CPU {1A0641F2-8857-46D7-965D-B6B3BD1771BC}.Debug|x86.ActiveCfg = Debug|x86 {1A0641F2-8857-46D7-965D-B6B3BD1771BC}.Debug|x86.Build.0 = Debug|x86 {1A0641F2-8857-46D7-965D-B6B3BD1771BC}.Release|Any CPU.ActiveCfg = Release|x86 + {1A0641F2-8857-46D7-965D-B6B3BD1771BC}.Release|ARM64.ActiveCfg = Release|x86 {1A0641F2-8857-46D7-965D-B6B3BD1771BC}.Release|Mixed Platforms.ActiveCfg = Release|x86 {1A0641F2-8857-46D7-965D-B6B3BD1771BC}.Release|Mixed Platforms.Build.0 = Release|x86 {1A0641F2-8857-46D7-965D-B6B3BD1771BC}.Release|Win32.ActiveCfg = Release|x86 - {1A0641F2-8857-46D7-965D-B6B3BD1771BC}.Release|x64.ActiveCfg = Release|x86 + {1A0641F2-8857-46D7-965D-B6B3BD1771BC}.Release|x64.ActiveCfg = Release|Any CPU + {1A0641F2-8857-46D7-965D-B6B3BD1771BC}.Release|x64.Build.0 = Release|Any CPU {1A0641F2-8857-46D7-965D-B6B3BD1771BC}.Release|x86.ActiveCfg = Release|x86 {1A0641F2-8857-46D7-965D-B6B3BD1771BC}.Release|x86.Build.0 = Release|x86 + {E9382993-43C9-4CEC-9D94-90DEF64FD214}.Debug|Any CPU.ActiveCfg = Debug|Win32 + {E9382993-43C9-4CEC-9D94-90DEF64FD214}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {E9382993-43C9-4CEC-9D94-90DEF64FD214}.Debug|ARM64.Build.0 = Debug|ARM64 + {E9382993-43C9-4CEC-9D94-90DEF64FD214}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 + {E9382993-43C9-4CEC-9D94-90DEF64FD214}.Debug|Mixed Platforms.Build.0 = Debug|Win32 + {E9382993-43C9-4CEC-9D94-90DEF64FD214}.Debug|Win32.ActiveCfg = Debug|Win32 + {E9382993-43C9-4CEC-9D94-90DEF64FD214}.Debug|Win32.Build.0 = Debug|Win32 + {E9382993-43C9-4CEC-9D94-90DEF64FD214}.Debug|x64.ActiveCfg = Debug|x64 + {E9382993-43C9-4CEC-9D94-90DEF64FD214}.Debug|x64.Build.0 = Debug|x64 + {E9382993-43C9-4CEC-9D94-90DEF64FD214}.Debug|x86.ActiveCfg = Debug|Win32 + {E9382993-43C9-4CEC-9D94-90DEF64FD214}.Debug|x86.Build.0 = Debug|Win32 + {E9382993-43C9-4CEC-9D94-90DEF64FD214}.Release|Any CPU.ActiveCfg = Release|Win32 + {E9382993-43C9-4CEC-9D94-90DEF64FD214}.Release|ARM64.ActiveCfg = Release|ARM64 + {E9382993-43C9-4CEC-9D94-90DEF64FD214}.Release|ARM64.Build.0 = Release|ARM64 + {E9382993-43C9-4CEC-9D94-90DEF64FD214}.Release|Mixed Platforms.ActiveCfg = Release|Win32 + {E9382993-43C9-4CEC-9D94-90DEF64FD214}.Release|Mixed Platforms.Build.0 = Release|Win32 + {E9382993-43C9-4CEC-9D94-90DEF64FD214}.Release|Win32.ActiveCfg = Release|Win32 + {E9382993-43C9-4CEC-9D94-90DEF64FD214}.Release|Win32.Build.0 = Release|Win32 + {E9382993-43C9-4CEC-9D94-90DEF64FD214}.Release|x64.ActiveCfg = Release|x64 + {E9382993-43C9-4CEC-9D94-90DEF64FD214}.Release|x64.Build.0 = Release|x64 + {E9382993-43C9-4CEC-9D94-90DEF64FD214}.Release|x86.ActiveCfg = Release|Win32 + {E9382993-43C9-4CEC-9D94-90DEF64FD214}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -286,7 +343,6 @@ Global {34CB783E-DDA2-4CE3-80BC-37B25AA33E5F} = {9962A820-513B-4A87-8313-0D8F6EA3765A} {F50E9F98-5BFA-4CF2-9373-0D8E0A623E60} = {9962A820-513B-4A87-8313-0D8F6EA3765A} {5D68B347-6B7E-4B0A-9DBF-82E287A52A21} = {9962A820-513B-4A87-8313-0D8F6EA3765A} - {E9382993-43C9-4CEC-9D94-90DEF64FD214} = {7C8FC956-4439-4917-BE4F-ED8F97B80863} {BCEBE26C-6C20-4086-AF65-76113DE08189} = {9962A820-513B-4A87-8313-0D8F6EA3765A} {B2571F4D-C611-409C-A885-53FDDA045269} = {9962A820-513B-4A87-8313-0D8F6EA3765A} {3159257E-F264-4B6A-B96E-F3D46ABF90A3} = {9962A820-513B-4A87-8313-0D8F6EA3765A} @@ -298,5 +354,9 @@ Global {89B88C2F-1FF5-4D84-A010-6BF74436576B} = {9962A820-513B-4A87-8313-0D8F6EA3765A} {D2549779-D9A0-4A92-9390-93973CC5249A} = {9962A820-513B-4A87-8313-0D8F6EA3765A} {1A0641F2-8857-46D7-965D-B6B3BD1771BC} = {9962A820-513B-4A87-8313-0D8F6EA3765A} + {E9382993-43C9-4CEC-9D94-90DEF64FD214} = {7C8FC956-4439-4917-BE4F-ED8F97B80863} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {6EB06818-9A5E-45A4-A7C6-100C11226592} EndGlobalSection EndGlobal diff --git a/Demo_Source_Code/PythonDemo/README.md b/Demo_Source_Code/PythonDemo/README.md new file mode 100644 index 0000000..9aed609 --- /dev/null +++ b/Demo_Source_Code/PythonDemo/README.md @@ -0,0 +1,208 @@ +# EaseFilter Python + +This is a demo library that provides a Pythonic API over the EaseFilter driver. +The source code is throughly documented, and intended to serve as an example +for using EaseFilter. + +A CLI is included, based on the C++ demo. + +*Python version 3.9 or above is required* to use this program. +Also, **a license key is required**. Contact +[info@easefilter.com](mailto:info@easefilter.com) for a trial key. + +The provided interfaces include: + +* Monitoring of the Windows Registry + +* Monitoring of specific processes + +* Monitoring of file/folder access + +* Control of file/folder access + +* Filesystem-level encryption of specific folders and files + +## Installation + +NOTE: Administrator permissions are required to run EaseFilter. + +### Install with Hatch + +The recommended installation method uses [Hatch](https://hatch.pypa.io/latest/), +which takes care of the project dependencies. + +First, [install Python](https://www.python.org/downloads/). + +Then, install hatch: + + pip install hatch + +Edit the license key field in `config.toml`: + + license_key = "..." + +Change to this directory, and to run the included CLI, use: + + hatch run cli [args] + +Otherwise, to start a Python REPL (command line), run: + + hatch run py + +In this environment, you can import the `easefilter` module to interface with +the filter. The CLI's code is available at `easefilter/cli/main.py`, and can +serve as an example for using this library. + +### Manual installation + +If you do not wish to use Hatch, you can run this project directly through Python. + +First, [install Python](https://www.python.org/downloads/). + +Then, install the dependencies: + + pip install -r requirements.txt + +Edit the license key field in `config.toml`: + + license_key = "..." + +To run the CLI, use: + + python -m easefilter.cli [args] + +And to start a Python REPL, change directory here, and run Python normally: + + python + +## Visual Studio + +Visual Studio can be used to navigate this codebase easily. Open +`ef-python.sln` to open this project. + +There are no integrations for debugging/running the code directly in VS. Use +the terminal to install and run this project. + +It may be helpful to set up a virtual environment; to do this, select `Tools / +Python / Python Environments` and click `Add environment`. + +## CLI examples + +Here are a few example CLI commands to try. + +To get detailled help, run + + hatch run cli --help + +or, for help on a specific subcommand, + + hatch run cli monitor --help + +For documentation on event types you can register, see the file `easefilter/enums.py`. + +### Monitor filter + +Default settings, creates a test directory (`C:\easefilter_demo`) and monitors its contents: + + hatch run cli monitor + +Monitor events for all files on your device: + + hatch run cli monitor * + +Monitor a specific directory: + + hatch run cli monitor "C:\directory\*" + +Enable monitoring all specific events (the `--io-mask` is shorthand for all the bitflags combined): + + hatch run cli monitor --io-mask 192118399729052330 + +Monitor all file handle creation events: + + hatch run cli monitor --io-sym POST_CREATE + +### Control filter + +Deny all file writes in a directory: + + hatch run cli control --deny-sym "ALLOW_WRITE_ACCESS,ALLOW_OPEN_WITH_CREATE_OR_OVERWRITE_ACCESS" C:\a_directory\* + +Deny all reads in the directory (also denies `cd`-ing into directory): + + hatch run cli control --deny-sym "ALLOW_READ_ACCESS,ALLOW_OPEN_WITH_READ_ACCESS" C:\a_directory\* + +Deny file listing in a directory (makes directory seem empty): + + hatch run cli control --deny-sym ALLOW_DIRECTORY_LIST_ACCESS C:\a_directory\* + +### Process filter + +Monitor all process creations/deletions (try starting a PowerShell to test this): + + hatch run cli process + +Monitor specifically `cmd.exe`: + + hatch run cli process --proc-mask C:\Windows\System32\cmd.exe + +Monitor all System32 processes: + + hatch run cli process --proc-mask C:\Windows\System32\* + +(**BE CAREFUL** with this flag) Prevent `cmd.exe` from running: + + hatch run cli process --proc-control-sym DENY_NEW_PROCESS_CREATION --proc-mask C:\Windows\System32\cmd.exe + +### Encryption filter + +Transparently encrypt a directory: + + hatch run cli encryption 'C:\my_encrypted_dir\*' + +This will prompt for a password. The password prompt does not show the +characters you type in. + +Files will only be decrypted while the filter is running. Once stopped, files +will be encrypted and unreadable. + +### Registry filter + +Monitor all registry events: + + hatch run cli registry + +Monitor all registry events for keys with a matching name: + + hatch run cli registry *KeyName* + +Monitor all registry events coming from regedit: + + hatch run cli registry --proc-mask C:\Windows\regedit.exe + +Monitor all registry key rename events coming from regedit: + + hatch run cli registry --reg-class-sym Reg_Pre_Rename_Key --proc-mask C:\Windows\regedit.exe + +Prevent regedit from deleting keys: + + hatch run cli registry --reg-deny-sym REG_ALLOW_DELETE_KEY --proc-mask C:\Windows\regedit.exe + +## Development + +To format/lint after changing any code, run + + hatch fmt + +or, to do a dry-run and avoid making changes, + + hatch fmt --check + +These will run [Ruff](https://astral.sh/ruff) and [Pyright](https://github.com/microsoft/pyright). + +Tests can be performed with [pytest](https://pytest.org/) like this: + + hatch test + +You may specify a test to run by adding its path (e.g. `tests/test_something.py`) as an argument. +Consult [pytest's documentation](https://docs.pytest.org/en/stable/) for more information. diff --git a/Demo_Source_Code/PythonDemo/config.toml b/Demo_Source_Code/PythonDemo/config.toml new file mode 100644 index 0000000..8cd0cd6 --- /dev/null +++ b/Demo_Source_Code/PythonDemo/config.toml @@ -0,0 +1,3 @@ +# License key can be purchased at http://www.easefilter.com/order.htm +# For a trial key, contact info@easefilter.com +license_key = "" diff --git a/Demo_Source_Code/PythonDemo/easefilter/__about__.py b/Demo_Source_Code/PythonDemo/easefilter/__about__.py new file mode 100644 index 0000000..1b23640 --- /dev/null +++ b/Demo_Source_Code/PythonDemo/easefilter/__about__.py @@ -0,0 +1 @@ +version = "2.0.0" diff --git a/Demo_Source_Code/PythonDemo/easefilter/__init__.py b/Demo_Source_Code/PythonDemo/easefilter/__init__.py new file mode 100644 index 0000000..9643d45 --- /dev/null +++ b/Demo_Source_Code/PythonDemo/easefilter/__init__.py @@ -0,0 +1,57 @@ +############################################################################### +## +## (C) Copyright 2022 EaseFilter Technologies +## All Rights Reserved +## +## This software is part of a licensed software product and may +## only be used or copied in accordance with the terms of that license. +## +## NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +## +## This module contains sample code provided for convenience and +## demonstration purposes only,this software is provided on an +## "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +## either express or implied. +## +############################################################################### + +from ._ef_class import _EaseFilter + +# this class is a shim over _EaseFilter, because Pyright does not display +# re-exported names in autocomplete + + +class EaseFilter(_EaseFilter): + r"""High-level filter control handle. + + Example usage of this class:: + + from pathlib import Path + + from easefilter import EaseFilter + from easefilter.enums import FileEventType, FilterType + from easefilter.events import FileEvent + from easefilter.rules import FileRule + from easefilter.types import BaseEvent, BaseReply + + + def msg_hook(event_data: BaseEvent) -> BaseReply | None: + if not isinstance(event_data, FileEvent): + # only deal with file events here + return + + print(event_data) + + + ef_handle = EaseFilter(license_key="...") + with ef_handle as ef: + ef.set_filter_type(FilterType.MONITOR) + ef.message_callback = msg_hook + + # monitor file creations + rule = FileRule(file_path=Path("*"), change_event_filter=FileEventType.CREATED) + rule.install(ef) + """ + + +__all__ = ["EaseFilter"] diff --git a/Demo_Source_Code/PythonDemo/easefilter/_ef_class.py b/Demo_Source_Code/PythonDemo/easefilter/_ef_class.py new file mode 100644 index 0000000..5fee369 --- /dev/null +++ b/Demo_Source_Code/PythonDemo/easefilter/_ef_class.py @@ -0,0 +1,268 @@ +############################################################################### +## +## (C) Copyright 2022 EaseFilter Technologies +## All Rights Reserved +## +## This software is part of a licensed software product and may +## only be used or copied in accordance with the terms of that license. +## +## NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +## +## This module contains sample code provided for convenience and +## demonstration purposes only,this software is provided on an +## "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +## either express or implied. +## +############################################################################### + +"""Main high-level, Pythonic, EaseFilter class implementation.""" + +from __future__ import annotations + +import logging +from typing import TYPE_CHECKING + +from typing_extensions import Self + +from easefilter.enums import BooleanConfig +from easefilter.errors import FilterError +from easefilter.events import handle_msg, handle_msg_reply +from easefilter.filter_api import ( + MESSAGE_SEND_DATA, + FilterApi, +) + +if TYPE_CHECKING: + from collections.abc import Callable + from pathlib import Path + + from easefilter.enums import ( + FilterType, + ) + from easefilter.types import ( + DisconCallback, + MsgCallback, + ) + + +class _EaseFilter: + """Main class implementation. + + See `__init__.py` for the public docstring. + """ + + def __init__( + self, + dll_path: Path | None = None, + license_key: str | None = None, + *, + reset_on_start: bool = True, + ) -> None: + r"""Inits the low-level API handle. + + Args: + license_key: Activation licence key. + dll_path: Absolute path or relative path prefixed with .\ to the Filter API DLL. + reset_on_start: Automatically reset configuration on filter start. + """ + self.api = FilterApi(dll_path=dll_path) + self.__reset_on_start: bool = reset_on_start + self.__license_key = license_key + + self.custom_msg_cb: Callable | None = None + """Custom low-level handler, used instead of the Pythonic `message_callback`. + + Using this handler is almost exactly like writing C++ callback code:: + + def handler(send_data_p, reply_data_p): + # raw struct + send_data: MESSAGE_SEND_DATA = send_data_p.contents + + # do stuff with the data... + + # modify the reply data struct... + + # the `[0]` is a pointer dereference + reply_data_p[0].ReturnStatus = FileStatus.SUCCESS + + return 1 + + ef_handle = EaseFilter(license_key="...") + with ef_handle as ef: + ef.custom_msg_cb = handler + ... # further setup code... + """ + + def handle_error(self, ret: int) -> None: + """Handle the Filter API's error conditions if needed. + + Args: + ret: Return code of a FilterAPI function. + + Raises: + FilterError: The return code signals an error. + """ + if ret == 0: + err = self.api.GetLastErrorMessage() + raise FilterError(err) + + def uninstall_driver(self) -> None: + """Uninstalls the EaseFilter driver.""" + ret = self.api.UnInstallDriver() + self.handle_error(ret) + logging.debug("Uninstalled driver.") + + def install_driver(self) -> None: + """Installs the EaseFilter driver.""" + if not self.api.IsDriverServiceRunning(): + logging.debug("Driver is not installed.") + ret = self.api.InstallDriver() + self.handle_error(ret) + logging.debug("Installed driver.") + else: + logging.debug("Driver is installed.") + + __filter_started = False + + @property + def filter_started(self) -> bool: + return self.__filter_started + + def start_filter(self, thread_count: int = 20) -> None: + """Start the filter, and register callbacks. + + Args: + thread_count: threads to use for callbacks. + """ + + def message_callback(send_data_p, reply_data_p) -> int: # noqa: ANN001 + # raw struct + send_data: MESSAGE_SEND_DATA = send_data_p.contents + + logging.debug("Message callback called. Processing...") + + msg_data = handle_msg(send_data, can_reply=bool(reply_data_p)) + + logging.debug("Message callback data:\n%s", msg_data) + + if self.message_callback is None: + self._default_msg_cb() + return 1 + + ret = self.message_callback(msg_data) + + handle_msg_reply(ret, reply_data_p) + + return 1 + + def disconnect_callback() -> None: # no cov + logging.debug("Disconnect callback called.") + if self.discon_callback is not None: + self.discon_callback() + + if self.filter_started: + logging.debug("Filter was already started; not starting again.") + return + + logging.info("Starting filter.") + + if not self.api.IsDriverServiceRunning(): + self.install_driver() + + self.handle_error(self.api.SetRegistrationKey(self.__license_key or "")) + + if self.__reset_on_start: + self.reset_config() + + self.handle_error( + self.api.RegisterMessageCallback( + thread_count, + self.custom_msg_cb or message_callback, + disconnect_callback, + ), + ) + + self.__filter_started = True + + def stop_filter(self) -> None: + """Stop the filter.""" + if not self.filter_started: + logging.debug("Filter was not started; not stopping.") + return + logging.debug("Calling disconnect on service.") + self.api.Disconnect() + self.__filter_started = False + + def __enter__(self) -> Self: + self.start_filter() + return self + + def __exit__(self, e_type, value, traceback) -> None: # noqa: ANN001 + self.stop_filter() + logging.debug( + "Leaving context manager. type: %s, value: %s, traceback: %s", + e_type, + value, + traceback, + ) + + warned_msg_cb: bool = False + + def _default_msg_cb(self) -> None: # no cov + if not self.warned_msg_cb: + self.warned_msg_cb = True + logging.warning( + "message_callback was fired, but no handler function was assigned.", + ) + + message_callback: MsgCallback | None = None + """Handler for filter events (e.g. I/O). This may return a `BaseReply` subclass to the filter.""" + + discon_callback: DisconCallback | None = None + """Hook to be run when EaseFilter is unloaded.""" + + _rule_id: int = 0 + + @property + def rule_id(self) -> int: + """Current filter rule ID. Automatically increments on read; keep a copy of it.""" + ret = self._rule_id + self._rule_id += 1 + return ret + + __has_set_type: bool = False + + @property + def has_set_type(self) -> bool: + """Is filter type set yet?""" + return self.__has_set_type + + def set_filter_type(self, filter_type: FilterType) -> None: + """Set the filter types active in the driver. + + Args: + filter_type: Filter types bitmask. See `easefilter.enums.FilterType`. + """ + self.__has_set_type = True + self.handle_error(self.api.SetFilterType(filter_type)) + + __boolean_config: BooleanConfig = BooleanConfig(0) + + @property + def boolean_config(self) -> BooleanConfig: + """Set global configuration flags. + + This is in contrast to rule-specific flags, that can be set in the rule class. + See `easefilter.enums.BooleanConfig` for more information. + """ + return self.__boolean_config + + @boolean_config.setter + def boolean_config(self, config: BooleanConfig) -> None: + self.handle_error(self.api.SetBooleanConfig(config)) + self.__boolean_config = config + + def reset_config(self) -> None: + """Reset all configuration data in the filter driver.""" + self.__has_set_type = False + self.handle_error(self.api.ResetConfigData()) diff --git a/Demo_Source_Code/PythonDemo/easefilter/bin/EaseFlt.sys b/Demo_Source_Code/PythonDemo/easefilter/bin/EaseFlt.sys new file mode 100644 index 0000000..d446c55 Binary files /dev/null and b/Demo_Source_Code/PythonDemo/easefilter/bin/EaseFlt.sys differ diff --git a/Demo_Source_Code/PythonDemo/easefilter/bin/FilterAPI.dll b/Demo_Source_Code/PythonDemo/easefilter/bin/FilterAPI.dll new file mode 100644 index 0000000..c67d672 Binary files /dev/null and b/Demo_Source_Code/PythonDemo/easefilter/bin/FilterAPI.dll differ diff --git a/Demo_Source_Code/PythonDemo/easefilter/bitmask.py b/Demo_Source_Code/PythonDemo/easefilter/bitmask.py new file mode 100644 index 0000000..c9ec726 --- /dev/null +++ b/Demo_Source_Code/PythonDemo/easefilter/bitmask.py @@ -0,0 +1,53 @@ +############################################################################### +## +## (C) Copyright 2022 EaseFilter Technologies +## All Rights Reserved +## +## This software is part of a licensed software product and may +## only be used or copied in accordance with the terms of that license. +## +## NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +## +## This module contains sample code provided for convenience and +## demonstration purposes only,this software is provided on an +## "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +## either express or implied. +## +############################################################################### + +"""Utilities for managing bitmasks.""" + +from __future__ import annotations + +from enum import IntFlag +from functools import reduce +from typing import TYPE_CHECKING, TypeVar + +if TYPE_CHECKING: + from collections.abc import Iterator + +T = TypeVar("T", bound=IntFlag) + + +def str_flag(strs: list[str] | set[str], flags: type[T]) -> T: + """Convert a series of string symbols to a bitmask. + + Args: + strs: List of string symbols to convert. + flags: IntFlag type to convert to. + """ + return reduce(lambda x, y: x | flags[y], strs, flags(0)) + + +T = TypeVar("T", bound=IntFlag) + + +def flag_extract(flags: T) -> Iterator[T]: + """Convert a bitmask integer to individual bitflags. + + Args: + flags: Bitmask (IntFlag type.) + """ + for flag in type(flags): + if flag & flags == flag and flag: + yield flag diff --git a/Demo_Source_Code/PythonDemo/easefilter/cli/__init__.py b/Demo_Source_Code/PythonDemo/easefilter/cli/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/Demo_Source_Code/PythonDemo/easefilter/cli/__main__.py b/Demo_Source_Code/PythonDemo/easefilter/cli/__main__.py new file mode 100644 index 0000000..d55d039 --- /dev/null +++ b/Demo_Source_Code/PythonDemo/easefilter/cli/__main__.py @@ -0,0 +1,22 @@ +############################################################################### +## +## (C) Copyright 2024 EaseFilter Technologies +## All Rights Reserved +## +## This software is part of a licensed software product and may +## only be used or copied in accordance with the terms of that license. +## +## NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +## +## This module contains sample code provided for convenience and +## demonstration purposes only,this software is provided on an +## "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +## either express or implied. +## +############################################################################### + +"""Entry point for `python -m easefilter.cli`.""" + +from .main import entrypoint + +entrypoint() diff --git a/Demo_Source_Code/PythonDemo/easefilter/cli/formatters.py b/Demo_Source_Code/PythonDemo/easefilter/cli/formatters.py new file mode 100644 index 0000000..8a53a7c --- /dev/null +++ b/Demo_Source_Code/PythonDemo/easefilter/cli/formatters.py @@ -0,0 +1,150 @@ +############################################################################### +## +## (C) Copyright 2024 EaseFilter Technologies +## All Rights Reserved +## +## This software is part of a licensed software product and may +## only be used or copied in accordance with the terms of that license. +## +## NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +## +## This module contains sample code provided for convenience and +## demonstration purposes only,this software is provided on an +## "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +## either express or implied. +## +############################################################################### + +"""Basic functions that format filter events.""" + +import textwrap + +from easefilter.enums import FileEventType, RegCallbackClass +from easefilter.events import EncryptEvent, FileEvent, ProcessEvent, RegistryEvent + + +def str_join(strs: list[str]) -> str: + return "\n" + "".join(textwrap.dedent(s).lstrip() for s in strs).strip("\n") + "\n" + + +def fmt_file_event(ev: FileEvent) -> str: + return str_join( + [ + f""" + I/O type: {ev.io_event_type!r} + User: {ev.account.username}\\{ev.account.domain} + File name: {ev.file_name} + Process name: {ev.process.path} + Process ID: {ev.process.pid} + Thread ID: {ev.process.tid} + """, + f""" + Information class: {ev.info_class} + """ + if ev.info_class + else "", + f""" + Filter message ID: {ev.message_id} + """, + f""" + --- + Renamed to '{ev.new_path}'. + """ + if isinstance(ev.io_event_type, FileEventType) + and FileEventType.RENAMED in ev.io_event_type + else "", + f""" + --- + Copied from '{ev.new_path}'. + """ + if isinstance(ev.io_event_type, FileEventType) + and FileEventType.COPIED in ev.io_event_type + else "", + ] + ) + + +def fmt_process_event(ev: ProcessEvent) -> str: + return str_join( + [ + f""" + I/O type: {ev.io_event_type!r} + User: {ev.account.username}\\{ev.account.domain} + Executable path: {ev.process.path} + Process ID: {ev.process.pid} + Thread ID: {ev.process.tid} + """, + f""" + Parent name: {ev.parent_proc.path} + Parent PID: {ev.parent_proc.pid} + """ + if ev.parent_proc is not None + else "", + f""" + Creator name: {ev.creating_proc.path} + Creator PID: {ev.creating_proc.pid} + """ + if ev.creating_proc is not None + else "", + f""" + Command line: {ev.command_line} + """ + if ev.command_line is not None + else "", + f""" + Filter message ID: {ev.message_id} + """, + ] + ) + + +def fmt_encrypt_event(ev: EncryptEvent) -> str: + TRUNCATE_LEN = 32 + """Truncate tag data to this many bytes.""" + + return str_join( + [ + f""" + I/O type: {ev.io_event_type!r} + User: {ev.account.username}\\{ev.account.domain} + File name: {ev.file_name} + """, + f""" + Tag data: {ev.tag_data if len(ev.tag_data) <= TRUNCATE_LEN else ev.tag_data[:TRUNCATE_LEN]} + """ + if ev.tag_data + else "", + f""" + Process name: {ev.process.path} + Process ID: {ev.process.pid} + Thread ID: {ev.process.tid} + Filter message ID: {ev.message_id} + """, + ] + ) + + +def fmt_registry_event(ev: RegistryEvent) -> str: + return str_join( + [ + f""" + I/O type: {ev.io_event_type!r} + User: {ev.account.username}\\{ev.account.domain} + Key name: {ev.key_name} + Process name: {ev.process.path} + Process ID: {ev.process.pid} + Thread ID: {ev.process.tid} + Filter message ID: {ev.message_id} + """, + f""" + --- + Renamed to '{ev.new_path}'. + """ + if ev.io_event_type + in ( + RegCallbackClass.Reg_Pre_Rename_Key, + RegCallbackClass.Reg_Post_Rename_Key, + ) + else "", + ] + ) diff --git a/Demo_Source_Code/PythonDemo/easefilter/cli/main.py b/Demo_Source_Code/PythonDemo/easefilter/cli/main.py new file mode 100644 index 0000000..6718deb --- /dev/null +++ b/Demo_Source_Code/PythonDemo/easefilter/cli/main.py @@ -0,0 +1,395 @@ +############################################################################### +## +## (C) Copyright 2024 EaseFilter Technologies +## All Rights Reserved +## +## This software is part of a licensed software product and may +## only be used or copied in accordance with the terms of that license. +## +## NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +## +## This module contains sample code provided for convenience and +## demonstration purposes only,this software is provided on an +## "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +## either express or implied. +## +############################################################################### + +"""Demo CLI interface for the library. + +This is a non-exhaustive overview of EaseFilter's features. +""" + +from __future__ import annotations + +import argparse +import ctypes +import logging +from argparse import Namespace +from pathlib import Path +from typing import TYPE_CHECKING + +import easefilter +from easefilter import errors +from easefilter.cli.formatters import ( + fmt_encrypt_event, + fmt_file_event, + fmt_process_event, + fmt_registry_event, +) +from easefilter.cli.rules import ( + control_rule, + encryption_rule, + monitor_rule, + process_rule, + registry_rule, +) +from easefilter.config import get_config +from easefilter.enums import ( + FilterType, +) +from easefilter.events import EncryptEvent, FileEvent, ProcessEvent, RegistryEvent + +if TYPE_CHECKING: + from easefilter.rules import ( + FilterRule, + ) + from easefilter.types import BaseEvent, BaseReply + +################################ +################################ +## main demo implementation +################################ +################################ + + +################################ +## event handler +################################ + + +def msg_handler(ev: BaseEvent) -> BaseReply | None: + outp: str = "" + ev_map = { + FileEvent: fmt_file_event, + ProcessEvent: fmt_process_event, + EncryptEvent: fmt_encrypt_event, + RegistryEvent: fmt_registry_event, + } + + for ( + ev_type, + fmt_func, + ) in ev_map.items(): + if isinstance(ev, ev_type): + outp = fmt_func(ev) + break + else: + logging.error("Could not format event: %s", ev) + + print(outp, end="") + + +################################ +## main function +################################ + + +def main(args: Namespace) -> None: + config = get_config(args.config) + + if args.subcommand in ("install", "uninstall"): + ef = easefilter.EaseFilter(dll_path=args.dll_path) + f_map = {"install": ef.install_driver, "uninstall": ef.uninstall_driver} + f_map[args.subcommand]() + + with easefilter.EaseFilter( + dll_path=args.dll_path, + license_key=config.get("license_key"), + reset_on_start=True, + ) as ef: + ef.install_driver() + ef.message_callback = msg_handler + + filt_type = FilterType[args.subcommand.upper()] + ef.set_filter_type(filt_type) + + test_dir: Path = Path("C:\\easefilter_demo") + + rule: FilterRule | None = None + + rule_map = { + FilterType.MONITOR: monitor_rule, + FilterType.CONTROL: control_rule, + FilterType.ENCRYPTION: encryption_rule, + FilterType.PROCESS: process_rule, + FilterType.REGISTRY: registry_rule, + } + + if filt_type in ( + FilterType.MONITOR | FilterType.CONTROL | FilterType.ENCRYPTION + ): + filter_mask = args.pathmask or test_dir / "*" + rule = rule_map[filt_type](args, filter_mask) + else: + rule = rule_map[filt_type](args) + + if rule is None: + msg = "`rule` is `None`." + raise RuntimeError(msg) + + # Defer CONTROL rule installation to after we create the test directory, + # in case writing is denied. + if filt_type != FilterType.CONTROL: + rule.install(ef) + + if filt_type in ( + FilterType.MONITOR | FilterType.CONTROL | FilterType.ENCRYPTION + ): + test_dir_exists = test_dir.exists() + if not test_dir_exists: + if input(f"Create test directory at {test_dir!s}? (Y/N): ").lower() in ( + "yes", + "y", + ): + logging.info("Creating test directory...") + test_dir.mkdir(exist_ok=True) + test_dir_exists = True + else: + logging.info("Test directory was not created.") + if test_dir_exists: + readme = test_dir / "README.txt" + readme.write_text( + "\n\n".join( + ( + "This is a testing directory for the EaseFilter Python demo.", + "Try moving or editing this file." + if filt_type == FilterType.MONITOR + else "", + ) + ) + ) + else: + logging.info("Test directory was not created.") + + if filt_type == FilterType.CONTROL: + rule.install(ef) + + logging.warning("Filter started. Press ENTER to stop the filter.") + input() + + +################################ +################################ +## CLI argument parser code +################################ +################################ + +################################ +## general params +################################ + +parser = argparse.ArgumentParser( + prog="easefilter-cli", + description="A demo of EaseFilter's features.", + epilog="For any questions, including obtaining a licence key, contact info@easefilter.com.", +) + +parser.add_argument( + "--log", + choices=["DEBUG", "INFO", "WARNING", "ERROR"], + default="INFO", + help="Sets log level.", +) + +parser.add_argument( + "--dll-path", + help="Override the default EaseFilter DLL path.", +) + +parser.add_argument( + "--config", + type=Path, + help="Override the default `config.yml` location.", + default=None, +) + +subparsers = parser.add_subparsers( + title="Subcommands", dest="subcommand", required=True +) + +################################ +## install/uninstall +################################ + +parser_install = subparsers.add_parser( + "install", help="Installs the EaseFilter system driver." +) +parser_uninstall = subparsers.add_parser( + "uninstall", help="Uninstalls the EaseFilter system driver." +) + +################################ +## monitor filter +################################ + +parser_monitor = subparsers.add_parser("monitor", help="Monitor filter demo.") +mon_change_event = parser_monitor.add_mutually_exclusive_group() +mon_change_event.add_argument( + "--change-sym", + help="Comma-separated string symbols of `FileEventType`s to monitor.", + type=str, +) +mon_change_event.add_argument( + "--change-mask", + type=int, + help="Integer (decimal form) bitmask of `FileEventType`s to monitor.", +) +mon_io_event = parser_monitor.add_mutually_exclusive_group() +mon_io_event.add_argument( + "--io-sym", + help="Comma-separated string symbols of `IOCallbackClass` granular events to monitor.", + type=str, +) +mon_io_event.add_argument( + "--io-mask", + type=int, + help="Integer (decimal form) bitmask of `IOCallbackClass` granular events to monitor.", +) +parser_monitor.add_argument( + "pathmask", + type=Path, + help="Path to monitor. This may contain `*` wildcards.", + default=None, + nargs="?", +) + +################################ +## control filter +################################ + +parser_control = subparsers.add_parser("control", help="Control filter demo.") +con_deny = parser_control.add_mutually_exclusive_group() +con_deny.add_argument( + "--deny-sym", + help="Comma-separated string symbols of `AccessFlag` events to deny.", + type=str, +) +con_deny.add_argument( + "--deny-mask", + type=int, + help="Integer (decimal form) bitmask of `AccessFlag` events to deny.", +) +con_io_event = parser_control.add_mutually_exclusive_group() +con_io_event.add_argument( + "--io-sym", + help="Comma-separated string symbols of `IOCallbackClass` granular events to monitor.", + type=str, +) +con_io_event.add_argument( + "--io-mask", + type=int, + help="Integer (decimal form) bitmask of `IOCallbackClass` granular events to monitor.", +) +parser_control.add_argument( + "pathmask", + type=Path, + help="Path to control. This may contain `*` wildcards.", + default=None, + nargs="?", +) + +################################ +## encryption filter +################################ + +parser_encryption = subparsers.add_parser("encryption", help="Encryption filter demo.") +parser_encryption.add_argument( + "--password", + help="Password to use for encryption.\n\nPassing passwords via command-line argument is insecure.\nIf this argument is not used, you will be instead prompted for a password.", + type=str, +) +parser_encryption.add_argument( + "pathmask", + type=Path, + help="Path to encrypt. This can be a directory followed by `*`.", + default=None, + nargs="?", +) + +################################ +## process filter +################################ + +parser_process = subparsers.add_parser("process", help="Process filter demo.") +parser_process.add_argument( + "--proc-control-sym", + help="Comma-separated string symbols of `ProcessControlFlag` events to register / control flags. WARNING: Be careful setting DENY_NEW_PROCESS_CREATION.", + type=str, +) +parser_process.add_argument( + "--proc-control-mask", + type=int, + help="Integer (decimal form) bitmask of `ProcessControlFlag` events to register / control flags. WARNING: Be careful setting 0x1 (deny process creation).", +) +parser_process.add_argument( + "--proc-mask", + help="Executable paths to monitor (or directory with `*` at the end.)", + type=Path, +) + +################################ +## registry filter +################################ + +parser_registry = subparsers.add_parser( + "registry", help="Windows Registry filter demo." +) +parser_registry.add_argument( + "keymask", + help="Registry key to monitor, may include wildcards (for example `*KeyName*`).", + type=str, + default="*", + nargs="?", +) +parser_registry.add_argument( + "--reg-class-sym", + help="Comma-separated string symbols of `RegCallbackClass` events to monitor.", + type=str, +) +parser_registry.add_argument( + "--reg-class-mask", + help="Integer (decimal form) bitmask of `RegCallbackClass` events to monitor.", + type=int, +) +parser_registry.add_argument( + "--reg-deny-sym", + help="Comma-separated string symbols of `RegControlFlag` events to deny. WARNING: Be careful with this.", + type=str, +) +parser_registry.add_argument( + "--reg-deny-mask", + help="Integer (decimal form) bitmask of `RegControlFlag` events to deny. WARNING: Be careful with this.", + type=int, +) +parser_registry.add_argument( + "--proc-mask", + help="Monitor a specific executable path's registry events. Accepts `*` wildcards.", + type=Path, +) + + +def entrypoint() -> None: + args = parser.parse_args() + + if not ctypes.windll.shell32.IsUserAnAdmin(): + raise errors.PrivilegeError + + logging.basicConfig(level=getattr(logging, str.upper(args.log))) + logging.info("Log level is %s.", args.log) + + main(args) + + +if __name__ == "__main__": + entrypoint() diff --git a/Demo_Source_Code/PythonDemo/easefilter/cli/rules.py b/Demo_Source_Code/PythonDemo/easefilter/cli/rules.py new file mode 100644 index 0000000..a473575 --- /dev/null +++ b/Demo_Source_Code/PythonDemo/easefilter/cli/rules.py @@ -0,0 +1,129 @@ +############################################################################### +## +## (C) Copyright 2024 EaseFilter Technologies +## All Rights Reserved +## +## This software is part of a licensed software product and may +## only be used or copied in accordance with the terms of that license. +## +## NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +## +## This module contains sample code provided for convenience and +## demonstration purposes only,this software is provided on an +## "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +## either express or implied. +## +############################################################################### + +"""Rule definitions for the CLI demo.""" + +import hashlib +import logging +import operator +from argparse import Namespace +from functools import reduce +from getpass import getpass +from pathlib import Path + +from easefilter.bitmask import str_flag +from easefilter.enums import ( + AccessFlag, + FileEventType, + IOCallbackClass, + ProcessControlFlag, + RegCallbackClass, + RegControlFlag, +) +from easefilter.rules import EncryptRule, FileRule, ProcessRule, RegistryProcNameRule + + +def monitor_rule(args: Namespace, filter_mask: Path) -> FileRule: + change_event_filter: FileEventType = args.change_mask or reduce( + operator.ior, FileEventType + ) + if args.change_sym: + change_event_filter = str_flag(args.change_sym.split(","), FileEventType) + + monitor_io_filter: IOCallbackClass = IOCallbackClass.NONE + if args.io_mask: + monitor_io_filter = IOCallbackClass(args.io_mask) + if args.io_sym: + monitor_io_filter = str_flag(args.io_sym.split(","), IOCallbackClass) + + logging.info("Monitoring '%s'.", filter_mask) + + return FileRule( + filter_mask, + change_event_filter=change_event_filter, + monitor_io_filter=monitor_io_filter, + ) + + +def control_rule(args: Namespace, filter_mask: Path) -> FileRule: + access_flag: AccessFlag = AccessFlag.ALLOW_MAX_RIGHT_ACCESS + if args.deny_mask: + access_flag &= ~AccessFlag(args.deny_mask) + elif args.deny_sym: + access_flag &= ~str_flag(args.deny_sym.split(","), AccessFlag) + + control_io_filter: IOCallbackClass = IOCallbackClass.NONE + if args.io_mask: + control_io_filter = IOCallbackClass(args.io_mask) + if args.io_sym: + control_io_filter = str_flag(args.io_sym.split(","), IOCallbackClass) + + logging.info("Controlling '%s'.", filter_mask) + + return FileRule( + filter_mask, + control_io_filter=control_io_filter, + access_flag=access_flag, + ) + + +def process_rule(args: Namespace) -> ProcessRule: + control_flag: ProcessControlFlag = ( + ProcessControlFlag.PROCESS_CREATION_NOTIFICATION + | ProcessControlFlag.PROCESS_TERMINATION_NOTIFICATION + ) + if args.proc_control_mask: + control_flag = ProcessControlFlag(args.proc_control_mask) + elif args.proc_control_sym: + control_flag = str_flag(args.proc_control_sym.split(","), ProcessControlFlag) + + return ProcessRule(args.proc_mask or Path("*"), control_flag=control_flag) + + +def encryption_rule(args: Namespace, filter_mask: Path) -> EncryptRule: + salt: bytes = b"use-a-random-salt-in-production" + password = args.password or getpass("Enter encryption password: ") + key: bytes = hashlib.scrypt( + password.encode(), salt=salt, n=16384, r=8, p=1, dklen=32 + ) + + logging.info("Encrypting '%s'.", filter_mask) + + return EncryptRule(filter_mask, encryption_key=key) + + +def registry_rule(args: Namespace) -> RegistryProcNameRule: + reg_mask: RegCallbackClass = reduce(operator.ior, RegCallbackClass) + if args.reg_class_mask: + reg_mask = RegCallbackClass(args.reg_class_mask) + elif args.reg_class_sym: + reg_mask = str_flag(args.reg_class_sym.split(","), RegCallbackClass) + + deny_mask = RegControlFlag(0) + if args.reg_deny_mask: + deny_mask = RegControlFlag(args.reg_deny_mask) + if args.reg_deny_sym: + deny_mask = str_flag(args.reg_deny_sym.split(","), RegControlFlag) + + logging.info("Monitoring Registry key '%s'.", args.keymask) + + return RegistryProcNameRule( + key_mask=args.keymask, + callback_class=reg_mask, + access_flag=RegControlFlag.REG_MAX_ACCESS_FLAG & ~deny_mask, + proc_name=args.proc_mask or Path("*"), + ) diff --git a/Demo_Source_Code/PythonDemo/easefilter/config.py b/Demo_Source_Code/PythonDemo/easefilter/config.py new file mode 100644 index 0000000..25d3ded --- /dev/null +++ b/Demo_Source_Code/PythonDemo/easefilter/config.py @@ -0,0 +1,39 @@ +############################################################################### +## +## (C) Copyright 2024 EaseFilter Technologies +## All Rights Reserved +## +## This software is part of a licensed software product and may +## only be used or copied in accordance with the terms of that license. +## +## NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +## +## This module contains sample code provided for convenience and +## demonstration purposes only,this software is provided on an +## "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +## either express or implied. +## +############################################################################### + +from __future__ import annotations + +import logging +from pathlib import Path +from typing import Any + +try: + import tomllib +except ModuleNotFoundError: # no cov + import tomli as tomllib # pyright: ignore reportMissingImports + + +def get_config(config_path: Path | None = None) -> dict[str, Any]: + if config_path is None: + config_path = Path(__file__).parents[1] / "config.toml" + if not config_path.is_file(): + msg = f"Configuration file {config_path} is not a file." + raise ValueError(msg) + + with config_path.open("rb") as f: + logging.debug("Loading config file at %s.", config_path) + return tomllib.load(f) diff --git a/Demo_Source_Code/PythonDemo/easefilter/enums.py b/Demo_Source_Code/PythonDemo/easefilter/enums.py new file mode 100644 index 0000000..0cb05da --- /dev/null +++ b/Demo_Source_Code/PythonDemo/easefilter/enums.py @@ -0,0 +1,937 @@ +############################################################################### +## +## (C) Copyright 2022 EaseFilter Technologies +## All Rights Reserved +## +## This software is part of a licensed software product and may +## only be used or copied in accordance with the terms of that license. +## +## NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +## +## This module contains sample code provided for convenience and +## demonstration purposes only +## "AS-IS" BASIS +## either express or implied. +## +############################################################################### + +import enum +import logging +import platform +from collections.abc import Iterator +from enum import IntEnum, IntFlag, auto +from typing import Optional, TypeVar + +from typing_extensions import Self + +from easefilter import bitmask + +"""Definitions for various hardcoded Enums.""" + + +################################ +################################ +## helper functions +################################ +################################ + +T = TypeVar("T", bound=IntEnum) + + +def enum_coerce(enum: type[T], val: int) -> Optional[T]: # noqa: FA100 (import future annotations does weird things to typevars) + """See if a value fits in an enum, and if so return the enum.""" + try: + return enum(val) + except ValueError: + return None + + +T = TypeVar("T", bound=IntFlag) + + +def autoflag_member_iter(flags: T) -> Iterator[T]: + """__iter__ implementation for instances of IntFlag in Python 3.11+. + + This won't work on the class itself. + """ + yield from flags._iter_member_(flags.value) # type: ignore reportAttributeAccessIssue + + +if [int(i) for i in platform.python_version_tuple()] < [3, 11, 0]: + logging.debug("using intflag shim (python < 3.11)") + autoflag_member_iter = bitmask.flag_extract + + +class AutoFlag(IntFlag): + """IntFlag with extra compatibility shim.""" + + def __iter__(self) -> Iterator[Self]: + """Shim for __iter__ on an IntFlag pre-Python 3.11.""" + if isinstance(self, enum.EnumMeta): + yield from self._member_map_.values() # type: ignore generalTypeIssues + else: + yield from autoflag_member_iter(self) + + def new_iter(self) -> Iterator[Self]: + """New iter for after Python 3.11.""" + if isinstance(self, enum.EnumMeta): + yield from self._member_map_.values() # type: ignore generalTypeIssues + else: + yield from self._iter_member_by_value_(self.value) # type: ignore reportAttributeAccessIssue + + +class AutoEnum(IntEnum): + @staticmethod + def _generate_next_value_(name, start, count, last_values) -> int: # noqa: ANN001 + """Emulate C++'s default enum behaviour for enum values.""" + del name + del start + + if count > 0: + return last_values[-1] + 1 + + return 0 + + def __iter__(self) -> Iterator[Self]: + """Emulate bitflag's iter on its members. + + Iterating over the class should yield all members, + and iterating over a single member should give itself. + """ + if isinstance(self, enum.EnumMeta): + yield from self._member_map_.values() # type: ignore generalTypeIssues + else: + yield self + + +################################ +################################ +## easefilter enums +################################ +################################ + + +class FilterType(AutoFlag): + """Enable specific Filter capabilities.""" + + CONTROL = 0x01 + """File I/O control.""" + + ENCRYPTION = 0x02 + """Transparent file encryption.""" + + MONITOR = 0x04 + """File I/O monitoring.""" + + REGISTRY = 0x08 + """Registry I/O monitoring & control.""" + + PROCESS = 0x10 + """Process/thread monitor & control.""" + + HSM = 0x40 + """Hierarchical storage management.""" + + CLOUD = 0x80 + """Cloud storage.""" + + +class FileEventType(AutoFlag): + """Select specific file events.""" + + CREATED = 0x00000020 + WRITTEN = 0x00000040 + RENAMED = 0x00000080 + DELETED = 0x00000100 + SECURITY_CHANGED = 0x00000200 + INFO_CHANGED = 0x00000400 + READ = 0x00000800 + COPIED = 0x00001000 + """File copy; only available on Windows 11.""" + + +class IOName(AutoEnum): + """Types of I/O filesystem events.""" + + PRE_FILE_CREATE = 0x00020001 + POST_FILE_CREATE = auto() + PRE_FILE_READ = auto() + POST_FILE_READ = auto() + PRE_FILE_WRITE = auto() + POST_FILE_WRITE = auto() + PRE_QUERY_FILE_SIZE = auto() + POST_QUERY_FILE_SIZE = auto() + PRE_QUERY_FILE_BASIC_INFO = auto() + POST_QUERY_FILE_BASIC_INFO = auto() + PRE_QUERY_FILE_STANDARD_INFO = auto() + POST_QUERY_FILE_STANDARD_INFO = auto() + PRE_QUERY_FILE_NETWORK_INFO = auto() + POST_QUERY_FILE_NETWORK_INFO = auto() + PRE_QUERY_FILE_ID = auto() + POST_QUERY_FILE_ID = auto() + PRE_QUERY_FILE_INFO = auto() + POST_QUERY_FILE_INFO = auto() + PRE_SET_FILE_SIZE = auto() + POST_SET_FILE_SIZE = auto() + PRE_SET_FILE_BASIC_INFO = auto() + POST_SET_FILE_BASIC_INFO = auto() + PRE_SET_FILE_STANDARD_INFO = auto() + POST_SET_FILE_STANDARD_INFO = auto() + PRE_SET_FILE_NETWORK_INFO = auto() + POST_SET_FILE_NETWORK_INFO = auto() + PRE_MOVE_OR_RENAME_FILE = auto() + POST_MOVE_OR_RENAME_FILE = auto() + PRE_DELETE_FILE = auto() + POST_DELETE_FILE = auto() + PRE_SET_FILE_INFO = auto() + POST_SET_FILE_INFO = auto() + PRE_QUERY_DIRECTORY_FILE = auto() + POST_QUERY_DIRECTORY_FILE = auto() + PRE_QUERY_FILE_SECURITY = auto() + POST_QUERY_FILE_SECURITY = auto() + PRE_SET_FILE_SECURITY = auto() + POST_SET_FILE_SECURITY = auto() + PRE_FILE_HANDLE_CLOSE = auto() + POST_FILE_HANDLE_CLOSE = auto() + PRE_FILE_CLOSE = auto() + POST_FILE_CLOSE = auto() + + +class IOCallbackClass(AutoFlag): + """I/O types that can be intercepted via monitor/control filter. + + Monitor can only register events after they occur (post I/O), + while control can register all events (pre and post). + + See [Wikipedia](https://en.m.wikipedia.org/wiki/I/O_request_packet) + for basic information about what an IRP is. + """ + + NONE = 0 + + PRE_CREATE = 0x00000001 + """`IRP_MJ_CREATE`: open file handle.""" + + POST_CREATE = 0x00000002 + """`IRP_MJ_CREATE`: open file handle.""" + + PRE_NEW_FILE_CREATED = 0x0000000100000000 + POST_NEW_FILE_CREATED = 0x0000000200000000 + + PRE_FASTIO_READ = 0x00000004 + """Fast I/O read. Returns true if data is cached. If not cached, a new cache read IRP will be generated.""" + POST_FASTIO_READ = 0x00000008 + """Fast I/O read. Returns true if data is cached. If not cached, a new cache read IRP will be generated.""" + + PRE_CACHE_READ = 0x00000010 + """`IRP_MJ_READ`: read data from cache. If not cached, a paging read request is generated.""" + POST_CACHE_READ = 0x00000020 + """`IRP_MJ_READ`: read data from cache. If not cached, a paging read request is generated.""" + + PRE_NOCACHE_READ = 0x00000040 + """`IRP_MJ_READ`: read data without cache, bypassing the cache manager.""" + POST_NOCACHE_READ = 0x00000080 + """`IRP_MJ_READ`: read data without cache, bypassing the cache manager.""" + + PRE_PAGING_IO_READ = 0x00000100 + """`IRP_MJ_READ`: paging read that caches on-disk data.""" + POST_PAGING_IO_READ = 0x00000200 + """`IRP_MJ_READ`: paging read that caches on-disk data.""" + + PRE_FASTIO_WRITE = 0x00000400 + """Fast I/O write. + + Data written to cache if the request is immediately satisfied, otherwise an IRP cache write will be generated. + """ + POST_FASTIO_WRITE = 0x00000800 + """Fast I/O write. + + Data written to cache if the request is immediately satisfied, otherwise an IRP cache write will be generated. + """ + + PRE_CACHE_WRITE = 0x00001000 + """`IRP_MJ_WRITE` cache write. + + A paging write IRP will be generated after this. + """ + POST_CACHE_WRITE = 0x00002000 + """`IRP_MJ_WRITE` cache write. + + A paging write IRP will be generated after this. + """ + + PRE_NOCACHE_WRITE = 0x00004000 + """`IRP_MJ_WRITE`: write directly to disk, bypassing cache manager.""" + POST_NOCACHE_WRITE = 0x00008000 + """`IRP_MJ_WRITE`: write directly to disk, bypassing cache manager.""" + + PRE_PAGING_IO_WRITE = 0x00010000 + """`IRP_MJ_WRITE`: paging write that moves data from cache to disk.""" + POST_PAGING_IO_WRITE = 0x00020000 + """`IRP_MJ_WRITE`: paging write that moves data from cache to disk.""" + + PRE_QUERY_INFORMATION = 0x00040000 + """`IRP_QUERY_INFORMATION`: file information query. + + This flag registers all queries; other `PRE_QUERY` flags can watch specific queries, e.g. only file size. + """ + POST_QUERY_INFORMATION = 0x00080000 + """`IRP_QUERY_INFORMATION`: file information query. + + This flag registers all queries; other `QUERY` flags can watch specific queries, e.g. only file size. + """ + + PRE_QUERY_FILE_SIZE = 0x0000000400000000 + """`IRP_QUERY_INFORMATION`: file size.""" + POST_QUERY_FILE_SIZE = 0x0000000800000000 + """`IRP_QUERY_INFORMATION`: file size.""" + + PRE_QUERY_FILE_BASIC_INFO = 0x0000001000000000 + """`IRP_QUERY_INFORMATION`: basic file information.""" + POST_QUERY_FILE_BASIC_INFO = 0x0000002000000000 + """`IRP_QUERY_INFORMATION`: basic file information.""" + + PRE_QUERY_FILE_STANDARD_INFO = 0x0000004000000000 + """`IRP_QUERY_INFORMATION`: standard file information.""" + POST_QUERY_FILE_STANDARD_INFO = 0x0000008000000000 + """`IRP_QUERY_INFORMATION`: standard file information.""" + + PRE_QUERY_FILE_NETWORK_INFO = 0x0000010000000000 + """`IRP_QUERY_INFORMATION`: file network information.""" + POST_QUERY_FILE_NETWORK_INFO = 0x0000020000000000 + """`IRP_QUERY_INFORMATION`: file network information.""" + + PRE_QUERY_FILE_ID = 0x0000040000000000 + """`IRP_QUERY_INFORMATION`: file ID.""" + POST_QUERY_FILE_ID = 0x0000080000000000 + """`IRP_QUERY_INFORMATION`: file ID.""" + + PRE_SET_INFORMATION = 0x00100000 + """`IRP_SET_INFORMATION`: set file information. + + This flag registers all requests; other `SET` flags can watch specific requests, e.g. only file size. + """ + POST_SET_INFORMATION = 0x00200000 + """`IRP_SET_INFORMATION`: set file information. + + This flag registers all requests; other `SET` flags can watch specific requests, e.g. only file size. + """ + + PRE_SET_FILE_SIZE = 0x0000400000000000 + """`IRP_SET_INFORMATION`: file size.""" + POST_SET_FILE_SIZE = 0x0000800000000000 + """`IRP_SET_INFORMATION`: file size.""" + + PRE_SET_FILE_BASIC_INFO = 0x0001000000000000 + """`IRP_SET_INFORMATION`: file basic information.""" + POST_SET_FILE_BASIC_INFO = 0x0002000000000000 + """`IRP_SET_INFORMATION`: file basic information.""" + + PRE_SET_FILE_STANDARD_INFO = 0x0004000000000000 + """`IRP_SET_INFORMATION`: file standard information.""" + POST_SET_FILE_STANDARD_INFO = 0x0008000000000000 + """`IRP_SET_INFORMATION`: file standard information.""" + + PRE_SET_FILE_NETWORK_INFO = 0x0010000000000000 + """`IRP_SET_INFORMATION`: file network information.""" + POST_SET_FILE_NETWORK_INFO = 0x0020000000000000 + """`IRP_SET_INFORMATION`: file network information.""" + + PRE_RENAME_FILE = 0x0040000000000000 + """`IRP_SET_INFORMATION`: file rename.""" + POST_RENAME_FILE = 0x0080000000000000 + """`IRP_SET_INFORMATION`: file rename.""" + + PRE_DELETE_FILE = 0x0100000000000000 + """`IRP_SET_INFORMATION`: file delete.""" + POST_DELETE_FILE = 0x0200000000000000 + """`IRP_SET_INFORMATION`: file delete.""" + + PRE_DIRECTORY = 0x00400000 + """`IRP_MJ_DIRECTORY_CONTROL`: query directory information.""" + POST_DIRECTORY = 0x00800000 + """`IRP_MJ_DIRECTORY_CONTROL`: query directory information.""" + + PRE_QUERY_SECURITY = 0x01000000 + """`IRP_MJ_QUERY_SECURITY`: query file security information.""" + POST_QUERY_SECURITY = 0x02000000 + """`IRP_MJ_QUERY_SECURITY`: query file security information.""" + + PRE_SET_SECURITY = 0x04000000 + """`IRP_MJ_SET_SECURITY`: set file security information.""" + POST_SET_SECURITY = 0x08000000 + """`IRP_MJ_SET_SECURITY`: set file security information.""" + + PRE_CLEANUP = 0x10000000 + """`IRP_MJ_CLEANUP`: close file handle.""" + POST_CLEANUP = 0x20000000 + """`IRP_MJ_CLEANUP`: close file handle.""" + + PRE_CLOSE = 0x40000000 + """`IRP_MJ_CLOSE`: close file I/O.""" + POST_CLOSE = 0x80000000 + """`IRP_MJ_CLOSE`: close file I/O.""" + + +class AccessFlag(AutoFlag): + """Access control for a file. + + Only for Control mode. + + IMPORTANT: Do not set this to 0 for least access. + See `AccessFlag.LEAST_ACCESS_FLAG`. + """ + + EXCLUDE_FILTER_RULE = 0x00000000 + """Filter driver skips all I/O on this file. + + (i.e, no access protection.) + """ + + EXCLUDE_FILE_ACCESS = 0x00000001 + """Block file open.""" + + ENABLE_REPARSE_FILE_OPEN = 0x00000002 + """Allow reparsing the file to another filename through a reparse mask.""" + + ENABLE_HIDE_FILES_IN_DIRECTORY_BROWSING = 0x00000004 + """Allow hiding files in a directory through a hide file mask.""" + + ENABLE_FILE_ENCRYPTION_RULE = 0x00000008 + """Enable transparent file encryption if an encryption key is added.""" + + ALLOW_OPEN_WITH_ACCESS_SYSTEM_SECURITY = 0x00000010 + """Allow file open to access the file's security information.""" + + ALLOW_OPEN_WITH_READ_ACCESS = 0x00000020 + """Allow file open with read access.""" + + ALLOW_OPEN_WITH_WRITE_ACCESS = 0x00000040 + """Allow file open with write access.""" + + ALLOW_OPEN_WITH_CREATE_OR_OVERWRITE_ACCESS = 0x00000080 + """Allow file open with create/overwrite access.""" + + ALLOW_OPEN_WITH_DELETE_ACCESS = 0x00000100 + """Allow file open with delete access.""" + + ALLOW_READ_ACCESS = 0x00000200 + """Allow reading data from file.""" + + ALLOW_WRITE_ACCESS = 0x00000400 + """Allow writing data from file.""" + + ALLOW_QUERY_INFORMATION_ACCESS = 0x00000800 + """Allow querying the file's information.""" + + ALLOW_SET_INFORMATION = 0x00001000 + """Allow changing the file's information: + + - File attributes + - File size + - File name + - Delete file + """ + + ALLOW_FILE_RENAME = 0x00002000 + """Allow renaming the file.""" + + ALLOW_FILE_DELETE = 0x00004000 + """Allow deleting the file.""" + + ALLOW_FILE_SIZE_CHANGE = 0x00008000 + """Allow changing file size.""" + + ALLOW_QUERY_SECURITY_ACCESS = 0x00010000 + """Allow querying the file's security information.""" + + ALLOW_SET_SECURITY_ACCESS = 0x00020000 + """Allow changing the file's security information.""" + + ALLOW_DIRECTORY_LIST_ACCESS = 0x00040000 + """Allow listing the directory's contents""" + + ALLOW_FILE_ACCESS_FROM_NETWORK = 0x00080000 + """Allow remote access via share folder.""" + + ALLOW_ENCRYPT_NEW_FILE = 0x00100000 + """Allow encrypting a new file if the encryption filter rule is enabled.""" + + ALLOW_READ_ENCRYPTED_FILES = 0x00200000 + """Allow applications to read encrypted files; if not set, return encrypted data.""" + + ALLOW_ALL_SAVE_AS = 0x00400000 + """Allow applications to create a new file after opening the protected file.""" + + ALLOW_COPY_PROTECTED_FILES_OUT = 0x00800000 + """Allow copying protected files out of the protected folder if `ALLOW_ALL_SAVE_AS` is enabled.""" + + ALLOW_FILE_MEMORY_MAPPED = 0x01000000 + """Allow file to be memory mapped.""" + + DISABLE_ENCRYPT_DATA_ON_READ = 0x02000000 + """Disable encrypting data on read when the encryption filter is enabled.""" + + ALLOW_COPY_PROTECTED_FILES_TO_USB = 0x04000000 + """Allow copying protected files to USB storage.""" + + LEAST_ACCESS_FLAG = 0xF0000000 + """Disable all access to this file. + + IMPORTANT: Do not set `AccessFlag` to 0. + This is equivalent to disabling all protections + (`EXCLUDE_FILTER_RULE`). + """ + + ALLOW_MAX_RIGHT_ACCESS = 0xFFFFFFF0 + """Allow all access to the file.""" + + +class FilterCommand(AutoEnum): + MESSAGE_TYPE_RESTORE_BLOCK_OR_FILE = 0x00000001 + MESSAGE_TYPE_RESTORE_FILE_TO_ORIGINAL_FOLDER = 0x00000002 + MESSAGE_TYPE_GET_FILE_LIST = 0x00000004 + MESSAGE_TYPE_RESTORE_FILE_TO_CACHE = 0x00000008 + MESSAGE_TYPE_SEND_EVENT_NOTIFICATION = 0x00000010 + MESSAGE_TYPE_DELETE_FILE = 0x00000020 + MESSAGE_TYPE_RENAME_FILE = 0x00000040 + MESSAGE_TYPE_SEND_MESSAGE_FILENAME = 0x00000080 + FILTER_SEND_FILE_CHANGED_EVENT = 0x00010001 + FILTER_REQUEST_USER_PERMIT = 0x00010002 + FILTER_REQUEST_ENCRYPTION_KEY = 0x00010003 + FILTER_REQUEST_ENCRYPTION_IV_AND_KEY = 0x00010004 + FILTER_REQUEST_ENCRYPTION_IV_AND_KEY_AND_ACCESSFLAG = 0x00010005 + FILTER_REQUEST_ENCRYPTION_IV_AND_KEY_AND_TAGDATA = 0x00010006 + FILTER_SEND_REG_CALLBACK_INFO = 0x00010007 + FILTER_SEND_PROCESS_CREATION_INFO = 0x00010008 + FILTER_SEND_PROCESS_TERMINATION_INFO = 0x00010009 + FILTER_SEND_THREAD_CREATION_INFO = 0x0001000A + FILTER_SEND_THREAD_TERMINATION_INFO = 0x0001000B + FILTER_SEND_PROCESS_HANDLE_INFO = 0x0001000C + FILTER_SEND_THREAD_HANDLE_INFO = 0x0001000D + FILTER_SEND_ATTACHED_VOLUME_INFO = 0x0001000E + FILTER_SEND_DETACHED_VOLUME_INFO = 0x0001000F + FILTER_SEND_DENIED_FILE_IO_EVENT = 0x00010010 + FILTER_SEND_DENIED_VOLUME_DISMOUNT_EVENT = 0x00010011 + FILTER_SEND_DENIED_PROCESS_EVENT = 0x00010012 + FILTER_SEND_DENIED_REGISTRY_ACCESS_EVENT = 0x00010013 + FILTER_SEND_DENIED_PROCESS_TERMINATED_EVENT = 0x00010014 + FILTER_SEND_DENIED_USB_READ_EVENT = 0x00010015 + FILTER_SEND_DENIED_USB_WRITE_EVENT = 0x00010016 + FILTER_SEND_PRE_TERMINATE_PROCESS_INFO = 0x00010017 + + +class FilterStatus(AutoFlag): + """Return status for `CallbackReplyData`.""" + + FILTER_MESSAGE_IS_DIRTY = 0x00000001 + """Message needs to be processed.""" + + FILTER_COMPLETE_PRE_OPERATION = 0x00000002 + """Pre-operation completed by your code.""" + + FILTER_DATA_BUFFER_IS_UPDATED = 0x00000004 + """Callback's reply data contains an update.""" + + FILTER_BLOCK_DATA_WAS_RETURNED = 0x00000008 + """Read block databuffer is returned to filter.""" + + FILTER_CACHE_FILE_WAS_RETURNED = 0x00000010 + """The whole cache file was downloaded.""" + + FILTER_REHYDRATE_FILE_VIA_CACHE_FILE = 0x00000020 + """Whole cache file downloaded, and stub file needs to be rehydrated.""" + + +class ProcessControlFlag(AutoFlag): + DENY_NEW_PROCESS_CREATION = 0x00000001 + """Deny the new process creation if the flag is on.""" + + PROCESS_PRE_TERMINATION_REQUEST = 0x00000002 + """Send the callback request before the process is going to be terminated. + + You can block the process termination in the callback function. + """ + + PROCESS_CREATION_NOTIFICATION = 0x00000100 + """Get a notification when a new process is being created.""" + + PROCESS_TERMINATION_NOTIFICATION = 0x00000200 + """Get a notification when a process was terminated.""" + + PROCESS_HANDLE_OP_NOTIFICATION = 0x00000400 + """Get a notification for process handle operations, + when a handle for a process is being created or duplicated.""" + + THREAD_CREATION_NOTIFICATION = 0x00000800 + """Get a notifcation when a new thread is being created.""" + + THREAD_TERMINATION_NOTIFICATION = 0x00001000 + """Get a notification when a thread was terminated.""" + + THREAD_HANDLE_OP_NOTIFICATION = 0x00002000 + """Get a notification for thread handle operations, when a handle for a process + is being created or duplicated.""" + + +class BooleanConfig(AutoFlag): + """Configuration and feature switches. + + Use `easefilter.EaseFilter.configure()` to apply this. + """ + + ENABLE_NO_RECALL_FLAG = 0x00000001 + """EaseTag: if true, after opening the reparse point file, won't restore data back for read/write.""" + + DISABLE_FILTER_UNLOAD_FLAG = 0x00000002 + """If true, disables unloading the filter driver.""" + + ENABLE_SET_OFFLINE_FLAG = 0x00000004 + """If true, sets the offline attribute for virtual files.""" + + ENABLE_DEFAULT_IV_TAG = 0x00000008 + """If true, uses a default IV to encrypt files in encryption mode.""" + + ENABLE_ADD_MESSAGE_TO_FILE = 0x00000010 + """If true, sends message data to a persistent file, otherwise send the event to the service immediately.""" + + ENCRYPT_FILE_WITH_REPARSE_POINT_TAG = 0x00000020 + """(Version 5.0) If true, encrypted file metadata is embedded in the reparse point tag.""" + + REQUEST_ENCRYPT_KEY_AND_IV_FROM_SERVICE = 0x00000040 + """Deprecated.""" + + ENABLE_PROTECTION_IN_BOOT_TIME = 0x00000080 + """If true, enables control filter rules at boot time.""" + + REQUEST_ENCRYPT_KEY_IV_AND_TAGDATA_FROM_SERVICE = 0x00000100 + """ + If true, encryption rules get the encryption key and IV, plus optional tag + data from your user-mode callback code instead of storing it in the driver. + """ + + ENABLE_SEND_DATA_BUFFER = 0x00000200 + """If enabled, will send read/write data to user-mode callback code.""" + + ENABLE_REOPEN_FILE_ON_REHYDRATION = 0x00000400 + """If true, will re-open files when rehydrating the stub.""" + + ENABLE_MONITOR_EVENT_BUFFER = 0x00000800 + """If true, queues monitor mode events in a buffer, then processes them asynchronously. + + This avoids blocking I/O requests, but may result in events being dropped when the buffer is full. + """ + + ENABLE_SEND_DENIED_EVENT = 0x00001000 + """If true, sends events even if they are blocked.""" + + ENABLE_WRITE_WITH_ZERO_DATA_AND_SEND_DATA = 0x00002000 + """If true, and write access is disabled, writes return success and write zero data to the file, and sends write data to user mode.""" + + DISABLE_REMOVABLE_MEDIA_AS_USB = 0x00004000 + """If true, treats portable massive storage as USB. + + This is for the volume control flag for `BLOCK_USB_READ`, `BLOCK_USB_WRITE`. + """ + + DISABLE_RENAME_ENCRYPTED_FILE = 0x00008000 + """If true, blocks moving an encrypted file to a different folder. + + By default, moving a file out of an encrypted folder results in the file + being unable to be decrypted. + """ + + DISABLE_FILE_SYNCHRONIZATION = 0x00010000 + """If true, disables file synchronization for file reading in CloudTier.""" + + ENABLE_PROTECTION_IF_SERVICE_STOPPED = 0x00020000 + """If true, data protection will continue after the service process is stopped.""" + + ENABLE_SIGNAL_WRITE_ENCRYPT_INFO_EVENT = 0x00020000 + """If true and write encrypt info to cache is enabled, signals the system thread to write cached data to disk right away.""" + + ENABLE_BLOCK_SAVE_AS_FLAG = 0x00040000 + """ + Enable this feature for the `ALLOW_SAVE_AS` or + `ALLOW_COPY_PROTECTED_FILES_OUT` accessFlag values. By default this feature + is disabled, because if these two flags are disabled this will block all new + file creation of the process which has read the protected files. + """ + + +class RegCallbackClass(AutoFlag): + """REGISTRY mode filter driver callback class. + + These are registry events that can be subscribed to. + """ + + Reg_Pre_Delete_Key = 0x00000001 + Reg_Pre_Set_Value_Key = 0x00000002 + Reg_Pre_Delete_Value_Key = 0x00000004 + Reg_Pre_SetInformation_Key = 0x00000008 + Reg_Pre_Rename_Key = 0x00000010 + Reg_Pre_Enumerate_Key = 0x00000020 + Reg_Pre_Enumerate_Value_Key = 0x00000040 + Reg_Pre_Query_Key = 0x00000080 + Reg_Pre_Query_Value_Key = 0x00000100 + Reg_Pre_Query_Multiple_Value_Key = 0x00000200 + Reg_Pre_Create_Key = 0x00000400 + Reg_Post_Create_Key = 0x00000800 + Reg_Pre_Open_Key = 0x00001000 + Reg_Post_Open_Key = 0x00002000 + Reg_Pre_Key_Handle_Close = 0x00004000 + + # .NET only values + Reg_Post_Delete_Key = 0x00008000 + Reg_Post_Set_Value_Key = 0x00010000 + Reg_Post_Delete_Value_Key = 0x00020000 + Reg_Post_SetInformation_Key = 0x00040000 + Reg_Post_Rename_Key = 0x00080000 + Reg_Post_Enumerate_Key = 0x00100000 + Reg_Post_Enumerate_Value_Key = 0x00200000 + Reg_Post_Query_Key = 0x00400000 + Reg_Post_Query_Value_Key = 0x00800000 + Reg_Post_Query_Multiple_Value_Key = 0x01000000 + Reg_Post_Key_Handle_Close = 0x02000000 + Reg_Pre_Create_KeyEx = 0x04000000 + Reg_Post_Create_KeyEx = 0x08000000 + Reg_Pre_Open_KeyEx = 0x10000000 + Reg_Post_Open_KeyEx = 0x20000000 + + # Available in Windows Vista and later + Reg_Pre_Flush_Key = 0x40000000 + Reg_Post_Flush_Key = 0x80000000 + + Reg_Pre_Load_Key = 0x100000000 + Reg_Post_Load_Key = 0x200000000 + Reg_Pre_UnLoad_Key = 0x400000000 + Reg_Post_UnLoad_Key = 0x800000000 + Reg_Pre_Query_Key_Security = 0x1000000000 + Reg_Post_Query_Key_Security = 0x2000000000 + Reg_Pre_Set_Key_Security = 0x4000000000 + Reg_Post_Set_Key_Security = 0x8000000000 + + Reg_Callback_Object_Context_Cleanup = 0x10000000000 + """Per-object context cleanup.""" + + # Available in Windows Vista SP2 and later + Reg_Pre_Restore_Key = 0x20000000000 + Reg_Post_Restore_Key = 0x40000000000 + Reg_Pre_Save_Key = 0x80000000000 + Reg_Post_Save_Key = 0x100000000000 + Reg_Pre_Replace_Key = 0x200000000000 + Reg_Post_Replace_Key = 0x400000000000 + + # Available in Windows 10 and later + Reg_Pre_Query_KeyName = 0x800000000000 + Reg_Post_Query_KeyName = 0x1000000000000 + + Max_Reg_Callback_Class = 0xFFFFFFFFFFFFFFFF + + +class RegControlFlag(AutoFlag): + """Permission flags for the REGISTRY mode filter.""" + + REG_ALLOW_OPEN_KEY = 0x00000001 + REG_ALLOW_CREATE_KEY = 0x00000002 + REG_ALLOW_QUERY_KEY = 0x00000004 + REG_ALLOW_RENAME_KEY = 0x00000008 + REG_ALLOW_DELETE_KEY = 0x00000010 + REG_ALLOW_SET_VALUE_KEY_INFORMATION = 0x00000020 + REG_ALLOW_SET_INFORMATION_KEY = 0x00000040 + REG_ALLOW_ENUMERATE_KEY = 0x00000080 + REG_ALLOW_QUERY_VALUE_KEY = 0x00000100 + REG_ALLOW_ENUMERATE_VALUE_KEY = 0x00000200 + REG_ALLOW_QUERY_MULTIPLE_VALUE_KEY = 0x00000400 + REG_ALLOW_DELETE_VALUE_KEY = 0x00000800 + REG_ALLOW_QUERY_KEY_SECURITY = 0x00001000 + REG_ALLOW_SET_KEY_SECRUITY = 0x00002000 + REG_ALLOW_RESTORE_KEY = 0x00004000 + REG_ALLOW_REPLACE_KEY = 0x00008000 + REG_ALLOW_SAVE_KEY = 0x00010000 + REG_ALLOW_FLUSH_KEY = 0x00020000 + REG_ALLOW_LOAD_KEY = 0x00040000 + REG_ALLOW_UNLOAD_KEY = 0x00080000 + REG_ALLOW_KEY_CLOSE = 0x00100000 + REG_ALLOW_QUERY_KEYNAME = 0x00200000 + REG_MAX_ACCESS_FLAG = 0xFFFFFFFF + + +################################ +################################ +## Windows data structures +################################ +################################ + + +class FileStatus(IntEnum): + SUCCESS = 0 + ACCESS_DENIED = 0xC0000022 + REPARSE = 0x00000104 + NO_MORE_FILES = 0x80000006 + WARNING = 0x80000000 + ERROR = 0xC0000000 + + +class InformationClass(AutoEnum): + """The specific class a generic POST_SET_INFORMATION event. + + For more information, see https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-fscc/4718fc40-e539-4014-8e33-b675af74e3e1 + """ + + FileDirectoryInformation = 1 + FileFullDirectoryInformation = auto() + FileBothDirectoryInformation = auto() + FileBasicInformation = auto() + FileStandardInformation = auto() + FileInternalInformation = auto() + FileEaInformation = auto() + FileAccessInformation = auto() + FileNameInformation = auto() + FileRenameInformation = auto() + FileLinkInformation = auto() + FileNamesInformation = auto() + FileDispositionInformation = auto() + FilePositionInformation = auto() + FileFullEaInformation = auto() + FileModeInformation = auto() + FileAlignmentInformation = auto() + FileAllInformation = auto() + FileAllocationInformation = auto() + FileEndOfFileInformation = auto() + FileAlternateNameInformation = auto() + FileStreamInformation = auto() + FilePipeInformation = auto() + FilePipeLocalInformation = auto() + FilePipeRemoteInformation = auto() + FileMailslotQueryInformation = auto() + FileMailslotSetInformation = auto() + FileCompressionInformation = auto() + FileObjectIdInformation = auto() + FileCompletionInformation = auto() + FileMoveClusterInformation = auto() + FileQuotaInformation = auto() + FileReparsePointInformation = auto() + FileNetworkOpenInformation = auto() + FileAttributeTagInformation = auto() + FileTrackingInformation = auto() + FileIdBothDirectoryInformation = auto() + FileIdFullDirectoryInformation = auto() + FileValidDataLengthInformation = auto() + FileShortNameInformation = auto() + FileIoCompletionNotificationInformation = auto() + FileIoStatusBlockRangeInformation = auto() + FileIoPriorityHintInformation = auto() + FileSfioReserveInformation = auto() + FileSfioVolumeInformation = auto() + FileHardLinkInformation = auto() + FileProcessIdsUsingFileInformation = auto() + FileNormalizedNameInformation = auto() + FileNetworkPhysicalNameInformation = auto() + FileIdGlobalTxDirectoryInformation = auto() + FileIsRemoteDeviceInformation = auto() + FileUnusedInformation = auto() + FileNumaNodeInformation = auto() + FileStandardLinkInformation = auto() + FileRemoteProtocolInformation = auto() + + # + # These are special versions of these operations (defined earlier) + # which can be used by kernel mode drivers only to bypass security + # access checks for Rename and HardLink operations. These operations + # are only recognized by the IOManager, a file system should never + # receive these. + # + + FileRenameInformationBypassAccessCheck = auto() + FileLinkInformationBypassAccessCheck = auto() + + # + # End of special information classes reserved for IOManager. + # + + FileVolumeNameInformation = auto() + FileIdInformation = auto() + FileIdExtdDirectoryInformation = auto() + FileReplaceCompletionInformation = auto() + FileHardLinkFullIdInformation = auto() + FileIdExtdBothDirectoryInformation = auto() + FileDispositionInformationEx = auto() + FileRenameInformationEx = auto() + FileRenameInformationExBypassAccessCheck = auto() + FileDesiredStorageClassInformation = auto() + FileStatInformation = auto() + FileMemoryPartitionInformation = auto() + FileStatLxInformation = auto() + FileCaseSensitiveInformation = auto() + FileLinkInformationEx = auto() + FileLinkInformationExBypassAccessCheck = auto() + FileStorageReserveIdInformation = auto() + FileCaseSensitiveInformationForceAccessCheck = auto() + FileKnownFolderInformation = auto() + + FileMaximumInformation = auto() + + +################################ +################################ +## python library enums +################################ +################################ + + +class ProcessEventType(AutoEnum): + """Namespace for specific process-related FilterCommand members. + + FilterCommand should be able to be directly casted to this. + """ + + ProcessCreationBlocked = FilterCommand.FILTER_SEND_DENIED_PROCESS_EVENT + """Tried to run an executable; blocked by filter.""" + + ProcessTerminated = FilterCommand.FILTER_SEND_PROCESS_TERMINATION_INFO + """Process stopped.""" + + ThreadCreated = FilterCommand.FILTER_SEND_THREAD_CREATION_INFO + """New thread created.""" + + ThreadTerminated = FilterCommand.FILTER_SEND_THREAD_TERMINATION_INFO + """Thread stopped.""" + + ProcessHandleInfo = FilterCommand.FILTER_SEND_PROCESS_HANDLE_INFO + """Notification for opening a new Windows process handle.""" + + ThreadHandleInfo = FilterCommand.FILTER_SEND_THREAD_HANDLE_INFO + """Notification for opening a new Windows thread handle.""" + + # these two are separate because they can be denied + ProcessCreationInfo = FilterCommand.FILTER_SEND_PROCESS_CREATION_INFO + """Process is being created; can be blocked by your filter code.""" + ProcessPreTerminateInfo = FilterCommand.FILTER_SEND_PRE_TERMINATE_PROCESS_INFO + """Process is being terminated forcefully; can be blocked by your filter code.""" + + +class EncryptEventType(AutoEnum): + """Namespace for encryption-related FilterCommand members. + + FilterCommand should be able to be directly casted to this. + """ + + RequestKey = FilterCommand.FILTER_REQUEST_ENCRYPTION_KEY + """Your code has to provide an encryption key.""" + + RequestIvAndKey = FilterCommand.FILTER_REQUEST_ENCRYPTION_IV_AND_KEY + """Your code has to provide an encryption key and IV. + + This event may also contain existing tag data for the file. + """ + + RequestIvAndKeyAndTagData = ( + FilterCommand.FILTER_REQUEST_ENCRYPTION_IV_AND_KEY_AND_TAGDATA + ) + """Your code has to provide an encryption key and IV, and optionally set tag data for the file.""" + + RequestIvAndKeyAndAccessFlag = ( + FilterCommand.FILTER_REQUEST_ENCRYPTION_IV_AND_KEY_AND_ACCESSFLAG + ) + """Your code has to provide an encryption key, IV, and the `AccessFlag`.""" diff --git a/Demo_Source_Code/PythonDemo/easefilter/errors.py b/Demo_Source_Code/PythonDemo/easefilter/errors.py new file mode 100644 index 0000000..e3fa615 --- /dev/null +++ b/Demo_Source_Code/PythonDemo/easefilter/errors.py @@ -0,0 +1,31 @@ +############################################################################### +## +## (C) Copyright 2024 EaseFilter Technologies +## All Rights Reserved +## +## This software is part of a licensed software product and may +## only be used or copied in accordance with the terms of that license. +## +## NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +## +## This module contains sample code provided for convenience and +## demonstration purposes only,this software is provided on an +## "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +## either express or implied. +## +############################################################################### + +"""Custom exceptions.""" + + +class FilterError(Exception): + """Generic error in the filter.""" + + +class CorruptionError(FilterError): + """Communication between driver and userspace got corrupted.""" + + +class PrivilegeError(Exception): + def __init__(self) -> None: + super().__init__("Please run this program with administrator privileges.") diff --git a/Demo_Source_Code/PythonDemo/easefilter/events.py b/Demo_Source_Code/PythonDemo/easefilter/events.py new file mode 100644 index 0000000..7922e54 --- /dev/null +++ b/Demo_Source_Code/PythonDemo/easefilter/events.py @@ -0,0 +1,452 @@ +############################################################################### +## +## (C) Copyright 2024 EaseFilter Technologies +## All Rights Reserved +## +## This software is part of a licensed software product and may +## only be used or copied in accordance with the terms of that license. +## +## NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +## +## This module contains sample code provided for convenience and +## demonstration purposes only,this software is provided on an +## "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +## either express or implied. +## +############################################################################### + +"""Object-oriented event types. + +These provide a cleaner interface over the message send/reply structs. +""" + +from __future__ import annotations + +import ctypes +import logging +from dataclasses import dataclass +from pathlib import Path +from typing import TYPE_CHECKING, TypedDict + +from typing_extensions import override + +from easefilter.enums import ( + AccessFlag, + EncryptEventType, + FileStatus, + FilterCommand, + FilterStatus, + InformationClass, + ProcessEventType, + RegCallbackClass, + enum_coerce, +) +from easefilter.errors import CorruptionError + +if TYPE_CHECKING: + from easefilter.filter_api import MESSAGE_SEND_DATA +from easefilter.enums import FileEventType, IOCallbackClass +from easefilter.filter_api import ( + AES_MAX_TAG_DATA_SIZE, + MESSAGE_REPLY_DATA, + MESSAGE_SEND_VERIFICATION_NUMBER, + PPROCESS_INFO, + AccountData, + ConvertSidToStringSidW, + GetProcessPathByPid, + LookupAccountSidW, +) +from easefilter.types import ( + BaseEvent, + BaseReply, + FileTimes, + IOEvent, + ProcessData, +) + +################################ +################################ +## incoming event handlers +################################ +################################ + + +class BaseEventArgs(TypedDict): + """Fields common to all filter events.""" + + message_id: int + io_event_type: IOEvent + filter_rule_id: int + sid: str + can_reply: bool + account: AccountData + + +def base_args(msg: MESSAGE_SEND_DATA, ev: IOEvent, *, can_reply: bool) -> BaseEventArgs: + """Processes fields common to all filter events. + + Args: + msg: Data to make arguments from. + ev: Event type. + can_reply: True if event can be replied to (message reply pointer not null). + """ + return { + "message_id": int(msg.MessageId), + "io_event_type": ev, + "filter_rule_id": int(msg.FilterRuleId), + "sid": ConvertSidToStringSidW(msg.Sid), + "can_reply": can_reply, + "account": LookupAccountSidW(msg.Sid), + } + + +@dataclass +class FileEvent(BaseEvent): + """File I/O (monitor & control mode) event.""" + + file_name: Path + """File path affected by this event.""" + + process: ProcessData + """Information about the process that initiated this event.""" + + time: FileTimes + """File timestamps.""" + + info_class: InformationClass | None + """File information class, if event changes information. See `InformationClass`.""" + + new_path: Path | None + """New path for copy/rename operations. + + (Old path for copy operation.) + """ + + @override + @classmethod + def from_msg( + cls: type[FileEvent], msg: MESSAGE_SEND_DATA, base_args: BaseEventArgs + ) -> FileEvent: + """Instantiate from MESSAGE_SEND data.""" + info_class: InformationClass | None = None + ev: IOEvent = base_args["io_event_type"] + if isinstance(ev, IOCallbackClass) and ( + IOCallbackClass.POST_SET_INFORMATION in ev + or IOCallbackClass.PRE_SET_INFORMATION in ev + ): + info_class = InformationClass(msg.InfoClass) + + new_path: Path | None = None + if ( + isinstance(ev, FileEventType) + and (FileEventType.RENAMED in ev or FileEventType.COPIED in ev) + and int(msg.DataBufferLength) > 0 + ): + s = ctypes.cast(msg.DataBuffer, ctypes.c_wchar_p).value + if s is not None: + new_path = Path(s) + + return cls( + **base_args, + file_name=Path(str(msg.FileName)), + process=ProcessData.from_msg(msg), + time=FileTimes.from_msg(msg), + info_class=info_class, + new_path=new_path, + ) + + +@dataclass +class ProcessEvent(BaseEvent): + """Process mode event. Includes process and thread events.""" + + process: ProcessData + """Information about the relevant process/thread for this event.""" + + parent_proc: ProcessData | None + """Information about the parent process/thread. + + Only available on a process start event. + """ + + creating_proc: ProcessData | None + """Information about the creating process/thread. + + This may be different from the parent process in some cases. + + Only available on a process start event. + """ + + command_line: str | None + """Full command line used to start this process. + + Only available on a process start event. + """ + + @override + @classmethod + def from_msg( + cls: type[ProcessEvent], msg: MESSAGE_SEND_DATA, base_args: BaseEventArgs + ) -> ProcessEvent: + """Instantiate from MESSAGE_SEND data.""" + proc_info_p = ctypes.cast(msg.DataBuffer, PPROCESS_INFO) + proc_info = proc_info_p.contents + + cmd_line: str | None = str(proc_info.CommandLine) + if cmd_line == "": + cmd_line = None + + is_create_ev: bool = ( + base_args["io_event_type"] == ProcessEventType.ProcessCreationInfo + ) + + par_proc: ProcessData | None = None + create_proc: ProcessData | None = None + if is_create_ev: + par_path = GetProcessPathByPid(proc_info.ParentProcessId) + par_proc = ProcessData( + int(proc_info.ParentProcessId), + None, + Path(par_path) if par_path else None, + ) + create_path = GetProcessPathByPid(proc_info.ParentProcessId) + create_proc = ProcessData( + int(proc_info.CreatingProcessId), + int(proc_info.CreatingThreadId), + Path(create_path) if create_path else None, + ) + + return cls( + **base_args, + process=ProcessData( + int(msg.ProcessId), + int(msg.ThreadId), + Path(str(msg.FileName)), + ), + creating_proc=create_proc, + parent_proc=par_proc, + command_line=cmd_line, + ) + + +@dataclass +class EncryptEvent(BaseEvent): + """Encryption mode event. + + This is only used when callback code is enabled through + `BooleanConfig.REQUEST_ENCRYPT_KEY_IV_AND_TAGDATA_FROM_SERVICE`. Reply to + this event either with a `DenyReply` or an `EncryptReply`. + """ + + file_name: Path + """File path to decrypt/encrypt.""" + + process: ProcessData + """Information about the process that initiated this event.""" + + tag_data: bytes | None + + io_status: FileStatus + """Operation status.""" + + @override + @classmethod + def from_msg( + cls: type[EncryptEvent], msg: MESSAGE_SEND_DATA, base_args: BaseEventArgs + ) -> EncryptEvent: + """Instantiate from MESSAGE_SEND data.""" + tag_data: bytes | None = None + if base_args["io_event_type"] == EncryptEventType.RequestIvAndKey: + data_len = int(msg.DataBufferLength) + logging.debug("tag data length: %d", data_len) + if data_len > 0: + tag_data = bytes(msg.DataBuffer)[:data_len] + + return cls( + **base_args, + file_name=Path(str(msg.FileName)), + process=ProcessData.from_msg(msg), + tag_data=tag_data, + io_status=FileStatus(msg.Status), + ) + + +@dataclass +class RegistryEvent(BaseEvent): + """Registry mode event.""" + + new_path: str | None + """New key name for rename operations.""" + + key_name: str + """Registry key being affected by this operation.""" + + process: ProcessData + """Process triggering this operation.""" + + @classmethod + def from_msg( + cls: type[RegistryEvent], msg: MESSAGE_SEND_DATA, base_args: BaseEventArgs + ) -> RegistryEvent: + new_path: str | None = None + if base_args["io_event_type"] in ( + RegCallbackClass.Reg_Pre_Rename_Key, + RegCallbackClass.Reg_Post_Rename_Key, + ): + new_path = ctypes.cast(msg.DataBuffer, ctypes.c_wchar_p).value + return cls( + **base_args, + new_path=new_path, + key_name=str(msg.FileName), + process=ProcessData.from_msg(msg), + ) + + +def handle_msg(msg: MESSAGE_SEND_DATA, *, can_reply: bool) -> BaseEvent: + """Takes a MESSAGE_SEND struct and returns an equivalent Event. + + Args: + msg: Struct to parse. + can_reply: True if event can be replied to (message struct pointer non-NULL). + """ + if msg.VerificationNumber != MESSAGE_SEND_VERIFICATION_NUMBER: + m = "Driver-to-userspace communication was corrupted. This may be a struct layout issue." + raise CorruptionError(m) + + if ev := enum_coerce(ProcessEventType, int(msg.FilterCommand)): + args = base_args(msg, ev, can_reply=can_reply) + return ProcessEvent.from_msg(msg, args) + if ev := enum_coerce(EncryptEventType, int(msg.FilterCommand)): + args = base_args(msg, ev, can_reply=can_reply) + return EncryptEvent.from_msg(msg, args) + if msg.FilterCommand == FilterCommand.FILTER_SEND_FILE_CHANGED_EVENT: + args = base_args(msg, FileEventType(msg.InfoClass), can_reply=can_reply) + return FileEvent.from_msg(msg, args) + if msg.FilterCommand == FilterCommand.FILTER_SEND_REG_CALLBACK_INFO: + args = base_args(msg, RegCallbackClass(msg.MessageType), can_reply=can_reply) + return RegistryEvent.from_msg(msg, args) + + args = base_args(msg, IOCallbackClass(msg.MessageType), can_reply=can_reply) + return FileEvent.from_msg(msg, args) + + +################################ +################################ +## outgoing reply handlers +################################ +################################ + + +def handle_msg_reply(reply: BaseReply | None, reply_data_p) -> None: # noqa: ANN001 + """Convert a reply object to a MESSAGE_REPLY struct. + + Args: + reply: Data to convert. + reply_data_p: Output struct pointer. + """ + if reply: + if reply_data_p: + reply.to_msg(reply_data_p) + logging.debug("replying with: %s", reply) + else: + logging.warning("Callback reply discarded, because it can not be used.") + + +@dataclass +class DenyReply(BaseReply): + """Deny a filter event, if possible. + + This has different effects in different modes: + CONTROL: I/O request is denied. + REGISTRY: I/O request is denied. + PROCESS: Process creation/termination is denied. + ENCRYPTION: File data is returned encrypted to the reading process. + """ + + def to_msg(self, reply_data_p) -> None: # noqa: ANN001 + reply_data: MESSAGE_REPLY_DATA = reply_data_p.contents + reply_data.ReturnStatus = ctypes.c_ulong(FileStatus.ACCESS_DENIED) + reply_data.FilterStatus = ctypes.c_ulong( + FilterStatus.FILTER_MESSAGE_IS_DIRTY + | FilterStatus.FILTER_COMPLETE_PRE_OPERATION + ) + + +@dataclass +class EncryptReply(BaseReply): + """Reply to a request for encryption key, IV, and other data. + + To deny a decryption request, use `DenyReply` instead. + """ + + encryption_key: bytes + """Encryption key to use. + + Must be 16, 24, or 32 bytes in length. + """ + + iv: bytes | None = None + """Specific 16-byte initialization vector to use for encryption. + + If not provided, a unique auto-generated IV will be used for each file. + """ + + tag_data: bytes | None = None + """Optional metadata to attach to the file header. + + Only set this for a EncryptEventType.RequestIvAndKeyAndTagData reply. + """ + + def to_msg(self, reply_data_p) -> None: # noqa: ANN001 + ln = len(self.encryption_key) + if ln not in (16, 24, 32): + msg = f"Encryption key must be 16, 24, or 32 bytes (got {ln})." + raise ValueError(msg) + reply_data: MESSAGE_REPLY_DATA = reply_data_p.contents + reply_data.ReplyData.AESData.Data.EncryptionKeyLength = ctypes.c_ulong(ln) + buf = (ctypes.c_byte * ln).from_buffer_copy(self.encryption_key) + ctypes.memmove( + reply_data.ReplyData.AESData.Data.EncryptionKey, + buf, + ln, + ) + + if self.iv: + IV_LENGTH = 16 + ln = len(self.iv) + if ln != IV_LENGTH: + msg = f"IV must be {IV_LENGTH} bytes (got {ln})." + raise ValueError(msg) + reply_data_p[0].ReplyData.AESData.Data.IVLength = ln + buf = (ctypes.c_ubyte * ln).from_buffer(bytearray(self.iv)) + ctypes.memmove( + reply_data_p[0].ReplyData.AESData.Data.IV, + buf, + ln, + ) + else: + reply_data_p[0].ReplyData.AESData.IVLength = 0 + + data_size = ctypes.sizeof(reply_data_p[0].ReplyData.AESData.Data) + + if self.tag_data is not None: + ln: int = len(self.tag_data) + if ln > AES_MAX_TAG_DATA_SIZE: + msg = f"Tag data too large: {ln} > {AES_MAX_TAG_DATA_SIZE} bytes." + raise ValueError(msg) + data_size += ln + reply_data_p[0].ReplyData.AESData.Data.TagDataLength = ln + ctypes.memmove( + reply_data_p[0].ReplyData.AESData.Data.TagData, + self.tag_data, + ln, + ) + + reply_data_p[0].ReplyData.AESData.SizeOfData = data_size + reply_data_p[ + 0 + ].ReplyData.AESData.Data.AccessFlag = AccessFlag.ALLOW_MAX_RIGHT_ACCESS + reply_data_p[0].ReturnStatus = FileStatus.SUCCESS + + self.encryption_key = b"" + self.iv = b"" diff --git a/Demo_Source_Code/PythonDemo/easefilter/filter_api.py b/Demo_Source_Code/PythonDemo/easefilter/filter_api.py new file mode 100644 index 0000000..d5247eb --- /dev/null +++ b/Demo_Source_Code/PythonDemo/easefilter/filter_api.py @@ -0,0 +1,861 @@ +############################################################################### +## +## (C) Copyright 2024 EaseFilter Technologies +## All Rights Reserved +## +## This software is part of a licensed software product and may +## only be used or copied in accordance with the terms of that license. +## +## NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +## +## This module contains sample code provided for convenience and +## demonstration purposes only,this software is provided on an +## "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +## either express or implied. +## +############################################################################### + +"""Low-level EaseFilter DLL interface + Windows functions. + +This API is faithful to FilterApi.h in the C++ +demo, although some parts are unimplemented. +""" + +from __future__ import annotations + +import ctypes +import datetime +import logging +from ctypes import ( + POINTER, + WINFUNCTYPE, + Array, + Structure, + Union, + addressof, + byref, + c_longlong, + c_ubyte, + c_uint, + c_ulong, + c_ulonglong, + c_void_p, + c_wchar_p, + cast, + create_string_buffer, + create_unicode_buffer, +) +from ctypes.wintypes import ( + BOOL, + DWORD, + HANDLE, + HMODULE, + LPCWSTR, + LPDWORD, + LPWSTR, + MAX_PATH, + PCHAR, + PULONG, + PWCHAR, + ULONG, + WCHAR, +) +from dataclasses import dataclass +from datetime import timezone +from pathlib import Path +from typing import ( + TYPE_CHECKING, + Annotated, + Any, + get_args, + get_origin, + get_type_hints, +) + +if TYPE_CHECKING: + from collections.abc import Callable + + from easefilter.enums import ( + AccessFlag, + BooleanConfig, + FilterType, + IOCallbackClass, + ProcessControlFlag, + RegCallbackClass, + RegControlFlag, + ) + +################################################################ +################################################################ + +# utility functions + +################################################################ +################################################################ + + +def windows_timestamp(t: int) -> datetime.datetime: + """Convert a Windows 'file time' to a Python datetime. + + A file time is a 64-bit int that represents the number of 100-nanosecond + intervals elapsed since 12:00 AM on January 1, 1601 UTC. + + Args: + t: File time (64-bit signed integer). + """ + us = t / 10 + epoch = datetime.datetime(1601, 1, 1, tzinfo=timezone.utc) + return epoch + datetime.timedelta(microseconds=us) + + +def windows_check_error(ret: int) -> None: + """Ctypes error-check function on Windows API functions that return BOOL.""" + if ret == 0: + raise ctypes.WinError(ctypes.get_last_error()) + + +PSID = ctypes.c_void_p + + +def ConvertSidToStringSidW(sid: Array[c_ubyte]) -> str: + fct: ctypes._FuncPointer = ctypes.windll.Advapi32.ConvertSidToStringSidW + fct.argtypes = [PSID, POINTER(LPWSTR)] + fct.restype = BOOL + fct.restype = windows_check_error + + ptr = LPWSTR() + fct(sid, byref(ptr)) + + if ptr.value is None: + msg = "Got unexpected null pointer." + raise RuntimeError(msg) + + return ptr.value + + +@dataclass +class AccountData: + """A user account (Python representation).""" + + username: str + + domain: str + """User's domain name.""" + + +def LookupAccountSidW(sid: Array[c_ubyte]) -> AccountData: + """Look up account information based on an Sid struct. + + See https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-lookupaccountsidw + """ + fct = ctypes.windll.Advapi32.LookupAccountSidW + fct.argtypes = [ + LPCWSTR, + PSID, + LPWSTR, + LPDWORD, + LPWSTR, + LPDWORD, + POINTER(c_uint), + ] + fct.restype = windows_check_error + + # these have the sizes of our buffers. if they're too small they get updated to what the size should be + cch_user = DWORD(MAX_PATH) + cch_domain = DWORD(MAX_PATH) + + user_str = create_unicode_buffer("", size=MAX_PATH) + domain_str = create_unicode_buffer("", size=MAX_PATH) + + # SID_NAME_USE enum, which is discarded + peUse = c_uint() + fct( + cast(0, LPCWSTR), + sid, + user_str, + byref(cch_user), + domain_str, + byref(cch_domain), + byref(peUse), + ) + + if user_str.value is None: + msg = "Got empty username." + raise RuntimeError(msg) + + if domain_str.value is None: + msg = "Got empty domain name." + raise RuntimeError(msg) + + return AccountData(username=user_str.value, domain=domain_str.value) + + +# https://learn.microsoft.com/en-us/windows/win32/api/psapi/nf-psapi-getmodulefilenameexw +GetModuleFileNameExW = ctypes.windll.psapi.GetModuleFileNameExW +GetModuleFileNameExW.restype = windows_check_error +GetModuleFileNameExW.argtypes = [HANDLE, HMODULE, LPWSTR, DWORD] + +# https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-openprocess +OpenProcess = ctypes.windll.kernel32.OpenProcess +OpenProcess.restype = HANDLE +OpenProcess.argtypes = [DWORD, BOOL, DWORD] + + +def GetProcessPathByPid(pid: c_ulong) -> str | None: + PROCESS_QUERY_INFORMATION = 0x0400 + PROCESS_VM_READ = 0x0010 + + try: + h = OpenProcess(PROCESS_VM_READ | PROCESS_QUERY_INFORMATION, False, pid) # noqa: FBT003 (boolean positional arg) + if h is None: + logging.debug("Could not open process handle for PID %s.", pid) + return None + name = create_unicode_buffer("", MAX_PATH) + GetModuleFileNameExW(h, 0, name, MAX_PATH) + except OSError: + logging.debug("Could not get process path for PID %d.", pid) + return None + else: + return name.value + + +def _pretty_fields(dct: dict[str, Any]) -> None: + """Convert a namespace's type annotations to _fields_ in ctypes structs/unions.""" + + class TypeDummy: + __annotations__ = dct.get("__annotations__", {}) + + # this line helps with [PEP 563](https://peps.python.org/pep-0563/) + # some type hints may be strings, and this will convert them back to real code + fields = get_type_hints(TypeDummy, localns=dct, include_extras=True) + + old_fields: list[tuple[str, Any]] = dct.get("_fields_", []) + field_list: list[tuple[str, Any]] = [] + + # this relies on dictionaries preserving insertion order to preserve struct field order + # see https://stackoverflow.com/a/39980744 + for k, v in fields.items(): + # special treatment for arrays + # example syntax: Annotated[Array[c_ubyte], 16] + if get_origin(v) is Annotated: + args = get_args(v) + arr_len = args[1] + arr_type = get_args(args[0])[0] + field_list.append((k, arr_type * arr_len)) + else: + field_list.append((k, v)) + + dct["_fields_"] = field_list + old_fields + + +class PrettyStruct(type(Structure)): + """Metaclass to make struct definitions pretty in Python. + + (For unions, see `PrettyUnion`.) + + By default, struct definitions look like this:: + + ``` + class Foo(Structure): + _fields_ = [ + ("arr", c_int * 5), + ("x", c_int), + ] + ``` + + This metaclass gives both type hints, cleaner syntax, and the possibility for docstrings:: + + ``` + class Foo(Structure, metaclass=PrettyStruct): + arr: Annotated[Array[c_int], 5] + '''This is an array type.''' + + y: c_int + '''This is an integer.''' + ``` + + Remember to use `typing.Annotated` for array types, as type checkers don't understand the ctypes array syntax. + You can use the ctypes `type * len` syntax, but you will have to ignore the type checker errors. + + In case some fields can not be expressed in pretty syntax, you can fall back to `_fields_` syntax. + Fields defined in `_fields_` syntax will be invariably placed AFTER the pretty fields. + It is not optimal to mix pretty and `_fields_` syntax, as field order is hard to define. + """ + + def __new__( + cls, name: str, base: tuple[type], dct: dict[str, Any] + ) -> type[Structure]: + _pretty_fields(dct) + return super().__new__(cls, name, base, dct) + + +class PrettyUnion(type(Union)): + """Metaclass to make union definitions cleaner. + + See `PrettyStruct`. + """ + + def __new__(cls, name: str, base: tuple[type], dct: dict[str, Any]) -> type[Union]: + _pretty_fields(dct) + return super().__new__(cls, name, base, dct) + + +################################################################ +################################################################ + +# struct definitions + +################################################################ +################################################################ + + +################################ +# filter-userspace communication +################################ + +MESSAGE_SEND_VERIFICATION_NUMBER = 0xFF000001 + +INET_ADDR_STR_LEN = 22 +MAX_FILE_NAME_LENGTH = 1024 +MAX_SID_LENGTH = 256 +MAX_BUFFER_SIZE = 16384 +AES_MAX_TAG_DATA_SIZE = 914 + + +class MESSAGE_SEND_DATA(Structure, metaclass=PrettyStruct): + """Structure for driver to app communication.""" + + VerificationNumber: ULONG + """Field for data integrity checking (should be equal to `MESSAGE_SEND_VERIFICATION_NUMBER`).""" + + FilterCommand: ULONG + """Command ID sent by the driver.""" + + MessageId: ULONG + """Sequential message ID.""" + + FilterRuleId: ULONG + """ID of the filter rule associated to this message.""" + + RemoteIP: Annotated[Array[WCHAR], INET_ADDR_STR_LEN] + """IP address of remote computer for files accessed over SMB (Windows 7+ only).""" + + FileObject: c_void_p + """Equivalent to file handle. Unique per file stream opened.""" + + FsContext: c_void_p + """Context, unique per file.""" + + MessageType: c_longlong + """File I/O message type registry class.""" + + ProcessId: ULONG + """PID for the thread that originally requested the I/O operation.""" + + ThreadId: ULONG + """Thread ID that requested the I/O operation.""" + + Offset: c_longlong + """Read/write offset.""" + + Length: ULONG + """Read/write length.""" + + FileSize: c_longlong + """Size of the file affected by the I/O operation.""" + + TransactionTime: c_longlong + """Transaction time of this request, UTC.""" + + CreationTime: c_longlong + """Creation time of the file, UTC.""" + + LastAccessTime: c_longlong + """Last access time of the file, UTC.""" + + LastWriteTime: c_longlong + """Last write time of the file, UTC.""" + + FileAttributes: ULONG + """File attributes.""" + + DesiredAccess: ULONG + """See the CreateFile Windows API.""" + Disposition: ULONG + """See the CreateFile Windows API.""" + ShareAccess: ULONG + """See the CreateFile Windows API.""" + CreateOptions: ULONG + """See the CreateFile Windows API.""" + CreateStatus: ULONG + """See the CreateFile Windows API.""" + + InfoClass: ULONG + """Information class for security/directory/information I/O""" + + Status: ULONG + """File system I/O status.""" + + ReturnLength: ULONG + """Return I/O (read/write) length.""" + + FileNameLength: ULONG + """File name length, in bytes.""" + + FileName: Annotated[Array[WCHAR], MAX_FILE_NAME_LENGTH] + """Name of the file affected by the I/O.""" + + SidLength: ULONG + """Security identifier length.""" + + Sid: Annotated[Array[c_ubyte], MAX_SID_LENGTH] + """Security identifier.""" + + DataBufferLength: ULONG + """Length of data buffer.""" + + DataBuffer: Annotated[Array[c_ubyte], MAX_BUFFER_SIZE] + """Data for read/write/query info/set info operations.""" + + +class MESSAGE_REPLY_DATA(Structure, metaclass=PrettyStruct): + """Data returned from user mode to the filter driver.""" + + class _ReplyData(Union, metaclass=PrettyUnion): + class _Data(Structure, metaclass=PrettyStruct): + BLOCK_SIZE = 65536 + + DataBufferLength: ULONG + DataBuffer: Annotated[Array[c_ubyte], BLOCK_SIZE] + + class _AESData(Structure, metaclass=PrettyStruct): + class _Data(Structure, metaclass=PrettyStruct): + AccessFlag: ULONG + IVLength: ULONG + IV: Annotated[Array[c_ubyte], 16] + EncryptionKeyLength: ULONG + EncryptionKey: Annotated[Array[c_ubyte], 32] + TagDataLength: ULONG + TagData: Annotated[Array[c_ubyte], 1] + + SizeOfData: ULONG + Data: _Data + + class _UserInfo(Structure, metaclass=PrettyStruct): + UserNameLength: ULONG + UserName: PWCHAR + + class _FileInfo(Structure, metaclass=PrettyStruct): + FileNameLength: ULONG + FileName: PWCHAR + + Data: _Data + AESData: _AESData + UserInfo: _UserInfo + FileInfo: _FileInfo + + MessageId: ULONG + MessageType: ULONG + ReturnStatus: ULONG + FilterStatus: ULONG + ReplyData: _ReplyData + + +class PROCESS_INFO(Structure, metaclass=PrettyStruct): + """Supplementary data for a PROCESS mode event. + + This data can be found under `MESSAGE_SEND_DATA.DataBuffer`. + + The executable file path (image name) can be found in `MESSAGE_SEND_DATA.FileName`. + """ + + ParentProcessId: ULONG + """Parent PID. May be different from CreatingProcessId!""" + + CreatingProcessId: ULONG + """PID of the creator of this process.""" + + CreatingThreadId: ULONG + """TID of the creator of this process.""" + + DesiredAccess: ULONG + """An `ACCESS_MASK` value that specifies the access rights to grant for the handle for `OB_PRE_CREATE_HANDLE_INFORMATION`.""" + + Operation: ULONG + """The type of handle operation. + + May be: `OB_OPERATION_HANDLE_CREATE`, `OB_OPERATION_HANDLE_DUPLICATE`. + """ + + FileOpenNameAvailable: ULONG + """Boolean, specifies whether `ImageFileName` contains the exact file name that is used to open the process executable file.""" + + CommandLineLength: ULONG + """Length of the CommandLine field.""" + + CommandLine: Annotated[Array[WCHAR], MAX_FILE_NAME_LENGTH] + """Command used to start a process, including arguments.""" + + +PPROCESS_INFO = POINTER(PROCESS_INFO) + + +################################################################ +################################################################ + +# Filter API class + +################################################################ +################################################################ + + +class FilterApi: + """Low-level interface for the Filter API. + + Functions that return `int` should return `1` for success and `0` for failure. + + Args: + dll_path: Path to Filter API DLL file. + """ + + def __init__(self, dll_path: Path | None = None) -> None: + """Loads the DLL and stores the handle.""" + path: Path = ( + dll_path if dll_path else Path(__file__).parent / "bin" / "FilterApi.dll" + ) + self._dll: ctypes.CDLL = ctypes.cdll.LoadLibrary(str(path)) + + def GetLastErrorMessage(self) -> str: + """Get an error message from EaseFilter. + + Returns: + A string with the error message. Empty if there is none. + + Raises: + OSError: EaseFilter could not retrieve the error message. + """ + length = ULONG(0) + + # Retrieve message length + self._dll.GetLastErrorMessage(None, cast(addressof(length), PULONG)) + + buf = create_unicode_buffer(length.value) + + # Retrieve message contents + self._dll.GetLastErrorMessage(buf, cast(addressof(length), PULONG)) + + return buf.value + + ################################ + ## driver and service control + ################################ + + def InstallDriver(self) -> int: + """Installs the EaseFilter Windows driver.""" + return self._dll.InstallDriver() + + def UnInstallDriver(self) -> int: + """Uninstalls the EaseFilter Windows driver.""" + return self._dll.UnInstallDriver() + + def IsDriverServiceRunning(self) -> bool: + """Check if driver service is running.""" + return self._dll.IsDriverServiceRunning() + + def SetRegistrationKey(self, key: str) -> int: + """Activate the service using a licence key.""" + self._dll.SetRegistrationKey.argtypes = [PCHAR] + buf = create_string_buffer(key.encode()) + return self._dll.SetRegistrationKey(buf) + + def Disconnect(self) -> None: + """Stop the filter service.""" + self._dll.Disconnect() + + ################################ + ################################ + ## filter configuration + ################################ + ################################ + + def SetBooleanConfig(self, booleanConfig: BooleanConfig) -> int: + """Apply global boolean configuration settings. + + Args: + booleanConfig: Configuration flags. + """ + self._dll.SetBooleanConfig.argtypes = [ULONG] + return self._dll.SetBooleanConfig(booleanConfig) + + def AddBooleanConfigToFilterRule( + self, filterMask: Path, booleanConfig: BooleanConfig + ) -> int: + """Apply boolean configuration settings for a rule.""" + self._dll.AddBooleanConfigToFilterRule.argtypes = [PWCHAR, ULONG] + return self._dll.AddBooleanConfigToFilterRule(str(filterMask), booleanConfig) + + def ResetConfigData(self) -> bool: + """Resets all filter driver configuration settings to default.""" + return self._dll.ResetConfigData() + + def SetConnectionTimeout(self, connectionTimeout: int) -> int: + """Set timeout for the driver sending messages to the service. + + Args: + connectionTimeout: Timeout in seconds. + """ + return self._dll.SetConnectionTimeout(connectionTimeout) + + def SetFilterType(self, filterType: FilterType) -> int: + """Set filter type. + + Args: + filterType: Bitflags of filter type. + """ + self._dll.SetFilterType.argtypes = [ULONG] + return self._dll.SetFilterType(filterType) + + Proto_Message_Callback = WINFUNCTYPE( + BOOL, + POINTER(MESSAGE_SEND_DATA), + POINTER(MESSAGE_REPLY_DATA), + ) + Proto_Disconnect_Callback = WINFUNCTYPE(None) + + def RegisterMessageCallback( + self, + ThreadCount: int, + MessageCallback: Callable, + DisconnectCallback: Callable, + ) -> int: + """Create the filter driver connection and set up callbacks. + + Args: + ThreadCount: Number of threads waiting for the callback. + MessageCallback: Callback function. + DisconnectCallback: Callback run on disconnect. + """ + # assigning as member variable to prevent these functions from going out of scope + # if that happens the program silently crashes when the callback is called (it disappeared) + self.message_callback = self.Proto_Message_Callback(MessageCallback) + self.disconnect_callback = self.Proto_Disconnect_Callback(DisconnectCallback) + + self._dll.RegisterMessageCallback.argtypes = [ + ULONG, + self.Proto_Message_Callback, + self.Proto_Disconnect_Callback, + ] + return self._dll.RegisterMessageCallback( + ThreadCount, + self.message_callback, + self.disconnect_callback, + ) + + ################################ + ## file filters + ################################ + + def AddFileFilterRule( + self, + accessFlag: AccessFlag, + filterMask: Path, + isResident: bool = False, + ruleId: int = 0, + ) -> int: + """Add a new file filter rule to the driver. + + Args: + accessFlag: Bitmask for access control rights to match. + filterMask: File path for this rule (must be unique). + isResident: Determines if rule is active at boot time (it will be added to registry if true). + ruleId: ID for this rule. Will show up in `messageSend.FilterRuleId` if there is a callback. + """ + self._dll.AddFileFilterRule.argtypes = [ULONG, PWCHAR, BOOL, ULONG] + return self._dll.AddFileFilterRule( + accessFlag, str(filterMask), isResident, ruleId + ) + + def RemoveFilterRule(self, FilterMask: Path) -> None: + """Remove a file filter rule from the driver. + + Args: + FilterMask: File path of the rule. + """ + self._dll.RemoveFilterRule.argtypes = [PWCHAR] + return self._dll.RemoveFilterRule(c_wchar_p(str(FilterMask))) + + def RegisterFileChangedEventsToFilterRule( + self, + filterMask: Path, + eventType: int, + ) -> bool: + """Set events to get notified for in a filter rule. + + Args: + filterMask: File path of the filter rule. + eventType: Bitmask of events to register to (see `easefilter.enums.FileEventType`). + """ + self._dll.RegisterFileChangedEventsToFilterRule.argtypes = [PWCHAR, ULONG] + return self._dll.RegisterFileChangedEventsToFilterRule( + str(filterMask), eventType + ) + + def RegisterMonitorIOToFilterRule( + self, filterMask: Path, registerIO: IOCallbackClass + ) -> bool: + """Set I/O events to monitor in a filter rule. + + Args: + filterMask: File path of the filter rule. + registerIO: Bitmask of events to register to. + """ + self._dll.RegisterMonitorIOToFilterRule.argtypes = [PWCHAR, c_ulonglong] + return self._dll.RegisterMonitorIOToFilterRule(str(filterMask), registerIO) + + def RegisterControlIOToFilterRule( + self, filterMask: Path, registerIO: IOCallbackClass + ) -> bool: + """Set I/O events to control in a filter rule. + + Args: + filterMask: File path of the filter rule. + registerIO: Bitmask of events to register to. + """ + self._dll.RegisterControlIOToFilterRule.argtypes = [PWCHAR, c_ulonglong] + return self._dll.RegisterControlIOToFilterRule(str(filterMask), registerIO) + + def AddEncryptionKeyToFilterRule( + self, filterMask: Path, encryptionKeyLength: int, encryptionKey: bytes + ) -> bool: + """Encrypt a folder, giving each file its own IV. + + Encryption information will be prepended to the file in a header. + + Args: + filterMask: File path of the filter rule. + encryptionKeyLength: Byte length of the key. + encryptionKey: Key data. + """ + self._dll.AddEncryptionKeyToFilterRule.argtypes = [ + PWCHAR, + ULONG, + POINTER(c_ubyte), + ] + self._dll.AddEncryptionKeyToFilterRule.restype = BOOL + + key_buf = (c_ubyte * len(encryptionKey)).from_buffer(bytearray(encryptionKey)) + + return self._dll.AddEncryptionKeyToFilterRule( + str(filterMask), encryptionKeyLength, key_buf + ) + + ################################ + ## process filters + ################################ + + def AddProcessFilterRule( + self, + processNameMaskLength: int, + processNameMask: Path, + controlFlag: ProcessControlFlag, + filterRuleId: int = 0, + ) -> int: + """Apply a new rule on a process. + + Args: + processNameMaskLength: Length (in BYTES!) of the executable file path mask. + processNameMask: Executable file path (can be a glob). + controlFlag: Specific rules to apply. + filterRuleId: Rule ID, which appears in `messageSend.FilterRuleId` as sent to the callback. + """ + self._dll.AddProcessFilterRule.argtypes = [ULONG, c_wchar_p, ULONG, ULONG] + return self._dll.AddProcessFilterRule( + processNameMaskLength, str(processNameMask), controlFlag, filterRuleId + ) + + def RemoveProcessFilterRule( + self, processNameMaskLength: int, processNameMask: Path + ) -> int: + self._dll.RemoveProcessFilterRule.argtypes = [ULONG, c_wchar_p] + return self._dll.RemoveProcessFilterRule( + processNameMaskLength, str(processNameMask) + ) + + ################################ + ## registry filters + ################################ + + def AddRegistryFilterRule( + self, + processNameLength: int, + processName: Path | None, + processId: int, + userNameLength: int, + userName: str, + keyNameLength: int, + keyNameFilterMask: str, + accessFlag: RegControlFlag, + regCallbackClass: RegCallbackClass, + isExcludeFilter: bool, + filterRuleId: int, + ) -> int: + """Create a new registry filter rule. + + Args: + processNameLength: Length of process name IN BYTES (`wchar` = 2 bytes). + processName: Process to filter, or `*` for all processes. + processId: Process ID to filter, instead of `processName`. + userNameLength: Length of user name. + userName: User mask to filter. + keyNameLength: Length of registry key filter. + keyNameFilterMask: Registry key mask to filter. + accessFlag: Access control flag for the registry. + regCallbackClass: Registry events to listen for. + isExcludeFilter: If true, does not filter events that match this rule. + filterRuleId: Rule ID. + """ + self._dll.AddRegistryFilterRule.argtypes = [ + ULONG, + c_wchar_p, + ULONG, + ULONG, + c_wchar_p, + ULONG, + c_wchar_p, + ULONG, + c_ulonglong, + BOOL, + ULONG, + ] + return self._dll.AddRegistryFilterRule( + processNameLength, + c_wchar_p(str(processName)), + processId, + userNameLength, + c_wchar_p(str(userName)), + keyNameLength, + c_wchar_p(str(keyNameFilterMask)), + accessFlag, + regCallbackClass, + isExcludeFilter, + filterRuleId, + ) + + def RemoveRegistryFilterRuleByProcessId(self, processId: int) -> int: + """Remove a registry filter rule by the PID it matches.""" + self._dll.RemoveRegistryFilterRuleByProcessId.argtypes = [ULONG] + return self._dll.RemoveRegistryFilterRuleByProcessId(processId) + + def RemoveRegistryFilterRuleByProcessName( + self, processNameLength: int, processName: str + ) -> int: + """Remove a registry filter rule by the process name it matches. + + Args: + processNameLength: Length IN BYTES (`wchar` = 2 bytes) of the process name. + processName: Process name. + """ + self._dll.RemoveRegistryFilterRuleByProcessName.argtypes = [ULONG, c_wchar_p] + return self._dll.RemoveRegistryFilterRuleByProcessName( + processNameLength, processName + ) diff --git a/Demo_Source_Code/PythonDemo/easefilter/py.typed b/Demo_Source_Code/PythonDemo/easefilter/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/Demo_Source_Code/PythonDemo/easefilter/rules.py b/Demo_Source_Code/PythonDemo/easefilter/rules.py new file mode 100644 index 0000000..c41cef1 --- /dev/null +++ b/Demo_Source_Code/PythonDemo/easefilter/rules.py @@ -0,0 +1,335 @@ +############################################################################### +## +## (C) Copyright 2024 EaseFilter Technologies +## All Rights Reserved +## +## This software is part of a licensed software product and may +## only be used or copied in accordance with the terms of that license. +## +## NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +## +## This module contains sample code provided for convenience and +## demonstration purposes only,this software is provided on an +## "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +## either express or implied. +## +############################################################################### + +"""High-level rule interfaces.""" + +from __future__ import annotations + +import warnings +from abc import ABC, abstractmethod +from dataclasses import dataclass, field +from pathlib import Path +from typing import TYPE_CHECKING + +from typing_extensions import override + +if TYPE_CHECKING: + from easefilter import EaseFilter + +from easefilter.enums import ( + AccessFlag, + BooleanConfig, + FileEventType, + IOCallbackClass, + ProcessControlFlag, + RegCallbackClass, + RegControlFlag, +) + + +@dataclass() +class FilterRule(ABC): + """Interface for filter rules. + + Each type of rule has a different configuration interface in the C++ API, + so each type of rule needs specific code to install it. + + This class should also include all configuration options for a given rule, + so that `install` may apply them. Because of this, subclasses of this + should also be dataclasses. + """ + + def install(self, ef: EaseFilter) -> None: + """Apply this rule (i.e. send it to the driver). + + Args: + ef: EaseFilter handle. + """ + if not ef.has_set_type: + warnings.warn( + RuntimeWarning( + "Filter type is not set. Set with `ef.set_filter_type()`." + ), + stacklevel=3, + ) + + @abstractmethod + def uninstall(self, ef: EaseFilter) -> None: + """Remove this rule from the driver. + + Args: + ef: EaseFilter handle. + """ + + _rule_id: int | None = field(init=False, repr=True, default=None) + + @property + def rule_id(self) -> int | None: + """Unique rule ID. Read only.""" + return self._rule_id + + +@dataclass +class _BaseFileRule(FilterRule): + """Parent class for MONITOR/CONTROL/ENCRYPTION rules. + + Do not instantiate directly. + """ + + file_path: Path + """File path to monitor (may be a glob, e.g. '*'). + + This must be unique, otherwise it overwrites the older rule. + """ + + access_flag: AccessFlag = AccessFlag.ALLOW_MAX_RIGHT_ACCESS + """Allow/disallow flags for file access (Control/encryption mode only).""" + + boolean_config: BooleanConfig = field(default=BooleanConfig(0)) + """Rule-specific configuration flags. + + This is in contrast to global configuration at `EaseFilter.boolean_config`. + """ + + def uninstall(self, ef: EaseFilter) -> None: + ef.api.RemoveFilterRule(self.file_path) + + +@dataclass() +class FileRule(_BaseFileRule): + """File rule, for either MONITOR or CONTROL mode. + + See `FilterRule` for more information. + """ + + change_event_filter: FileEventType = field(default=FileEventType(0)) + """List of file change events to monitor.""" + + is_resident: bool = False + """'Resident' CONTROL mode rules are always active, even at boot time.""" + + monitor_io_filter: IOCallbackClass = IOCallbackClass.NONE + """List of I/O events to monitor.""" + + control_io_filter: IOCallbackClass = IOCallbackClass.NONE + """List of I/O events to send to the control filter.""" + + def install(self, ef: EaseFilter) -> None: + super().install(ef) + self._rule_id = ef.rule_id + ef.handle_error( + ef.api.AddFileFilterRule( + self.access_flag, + self.file_path, + isResident=self.is_resident, + ruleId=self._rule_id, + ), + ) + + ef.api.AddBooleanConfigToFilterRule(self.file_path, self.boolean_config) + + ef.handle_error( + ef.api.RegisterFileChangedEventsToFilterRule( + self.file_path, + self.change_event_filter, + ), + ) + ef.handle_error( + ef.api.RegisterMonitorIOToFilterRule( + self.file_path, + self.monitor_io_filter, + ), + ) + ef.handle_error( + ef.api.RegisterControlIOToFilterRule( + self.file_path, + self.control_io_filter, + ), + ) + + +@dataclass +class ProcessRule(FilterRule): + """Process rule. See `FilterRule` for more information.""" + + executable_mask: Path + """Path to an executable (may be a glob).""" + + control_flag: ProcessControlFlag + """Sets process events to be notified for, and sets permissions.""" + + def install(self, ef: EaseFilter) -> None: + super().install(ef) + self._rule_id = ef.rule_id + ef.handle_error( + ef.api.AddProcessFilterRule( + len(str(self.executable_mask)) * 2, + self.executable_mask, + self.control_flag, + self._rule_id, + ) + ) + + def uninstall(self, ef: EaseFilter) -> None: + ef.handle_error( + ef.api.RemoveProcessFilterRule( + len(str(self.executable_mask)) * 2, self.executable_mask + ) + ) + + +@dataclass +class EncryptRule(_BaseFileRule): + """Encryption rule. See `FilterRule` for more information.""" + + encryption_key: bytes | None = None + """Encryption key to use. + + If `None`, requires your callback code to provide a key every time a file is opened. + In this case, you must enable `BooleanConfig.REQUEST_ENCRYPT_KEY_IV_AND_TAGDATA_FROM_SERVICE`. + + Must be 16, 24, or 32 bytes in length. + """ + + access_flag: AccessFlag = ( + AccessFlag.ALLOW_MAX_RIGHT_ACCESS | AccessFlag.ENABLE_FILE_ENCRYPTION_RULE + ) + """Allow/disallow flags for file access.""" + + @override + def install(self, ef: EaseFilter) -> None: + super().install(ef) + self._rule_id = ef.rule_id + ef.handle_error( + ef.api.AddFileFilterRule( + self.access_flag, + self.file_path, + isResident=False, + ruleId=self._rule_id, + ), + ) + + ef.api.AddBooleanConfigToFilterRule(self.file_path, self.boolean_config) + + if self.encryption_key: + if ln := len(self.encryption_key) not in (16, 24, 32): + msg = f"Encryption key must be 16, 24, or 32 bytes (got {ln})." + raise ValueError(msg) + ef.handle_error( + ef.api.AddEncryptionKeyToFilterRule( + self.file_path, len(self.encryption_key), self.encryption_key + ) + ) + elif ( + BooleanConfig.REQUEST_ENCRYPT_KEY_IV_AND_TAGDATA_FROM_SERVICE + not in self.boolean_config + ): + msg = "BooleanConfig.REQUEST_ENCRYPT_KEY_IV_AND_TAGDATA_FROM_SERVICE is required when encryption_key is None." + raise ValueError(msg) + + +@dataclass +class _BaseRegistryRule(FilterRule): + """Registry rule base class.""" + + key_mask: str + """Registry key filter that this rule will apply to. + + May contain a wildcard (`*`). + """ + + callback_class: RegCallbackClass + + access_flag: RegControlFlag = field(default=RegControlFlag.REG_MAX_ACCESS_FLAG) + """Permission flags.""" + + exclude_filter: bool = field(default=False) + """If true, excludes all events matching this rule from being filtered.""" + + def install(self, ef: EaseFilter) -> None: + super().install(ef) + self._rule_id = ef.rule_id + + proc_name: Path | None = getattr(self, "proc_name", None) or Path("*") + proc_id: int = getattr(self, "proc_id", None) or 0 + username: str | None = getattr(self, "username", None) or "*" + + ef.api.AddRegistryFilterRule( + len(str(proc_name or "")) * 2, + proc_name, + proc_id, + len(username or "") * 2, + username or "", + len(self.key_mask) * 2, + self.key_mask, + self.access_flag, + self.callback_class, + self.exclude_filter, + self._rule_id, + ) + + +class NoDefault: + """Sentinel value type for `NO_DEFAULT`.""" + + def __bool__(self) -> bool: + return False + + +NO_DEFAULT = NoDefault() +"""Sentinel to be used with `NoDefaultMixin`.""" + + +class NoDefaultMixin: + """Mixin to have non-default dataclass values in Python 3.9. + + See https://stackoverflow.com/a/54653255. + """ + + def __post_init__(self) -> None: + for k, v in self.__dict__.items(): + if v is NO_DEFAULT: + msg = f"missing required argument: '{k}'" + raise TypeError(msg) + + +@dataclass +class RegistryProcNameRule(_BaseRegistryRule, NoDefaultMixin): + """Registry rule that matches by process path.""" + + proc_name: Path | NoDefault = NO_DEFAULT + """Process name (may contain wildcard `*` for all processes.)""" + + def uninstall(self, ef: EaseFilter) -> None: + if isinstance(self.proc_name, NoDefault): + msg = "Sentinel value still exists." + raise TypeError(msg) + s = str(self.proc_name) + ef.api.RemoveRegistryFilterRuleByProcessName(len(s) * 2, s) + + +@dataclass +class RegistryProcIdRule(_BaseRegistryRule, NoDefaultMixin): + """Registry rule that matches by process ID.""" + + proc_id: int | NoDefault = NO_DEFAULT + + def uninstall(self, ef: EaseFilter) -> None: + if isinstance(self.proc_id, NoDefault): + msg = "Sentinel value still exists." + raise TypeError(msg) + ef.api.RemoveRegistryFilterRuleByProcessId(self.proc_id) diff --git a/Demo_Source_Code/PythonDemo/easefilter/types.py b/Demo_Source_Code/PythonDemo/easefilter/types.py new file mode 100644 index 0000000..ddb3f80 --- /dev/null +++ b/Demo_Source_Code/PythonDemo/easefilter/types.py @@ -0,0 +1,167 @@ +############################################################################### +## +## (C) Copyright 2024 EaseFilter Technologies +## All Rights Reserved +## +## This software is part of a licensed software product and may +## only be used or copied in accordance with the terms of that license. +## +## NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +## +## This module contains sample code provided for convenience and +## demonstration purposes only,this software is provided on an +## "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +## either express or implied. +## +############################################################################### + +"""Miscellaneous high-level interface types.""" + +from __future__ import annotations + +from abc import ABC, ABCMeta, abstractmethod +from dataclasses import dataclass +from typing import TYPE_CHECKING, Optional, Union + +from typing_extensions import Self + +from easefilter.filter_api import ( + MESSAGE_SEND_DATA, + AccountData, + GetProcessPathByPid, + windows_timestamp, +) + +if TYPE_CHECKING: + import datetime + + from easefilter.events import BaseEventArgs +from collections.abc import Callable +from pathlib import Path + +from easefilter.enums import ( + EncryptEventType, + FileEventType, + IOCallbackClass, + ProcessEventType, + RegCallbackClass, +) + + +@dataclass +class ProcessData: + """Process/thread information. + + Fields may be unknown, depending on the + situation, in which case they will be `None`. + """ + + pid: int | None + """Process ID.""" + + tid: int | None + """Thread ID.""" + + path: Path | None + """Executable path.""" + + @classmethod + def from_msg(cls: type[Self], msg: MESSAGE_SEND_DATA) -> Self: + """Instantiate from MESSAGE_SEND.""" + process_path = GetProcessPathByPid(msg.ProcessId) + + return cls( + pid=int(msg.ProcessId), + tid=int(msg.ThreadId), + path=Path(process_path) if process_path else None, + ) + + +@dataclass +class FileTimes: + """Timestamps for a file.""" + + create: datetime.datetime + """Creation time.""" + + access: datetime.datetime + """Last access time.""" + + write: datetime.datetime + """Last write time.""" + + @classmethod + def from_msg(cls: type[Self], msg: MESSAGE_SEND_DATA) -> Self: + """Instantiate from MESSAGE_SEND.""" + return cls( + create=windows_timestamp(int(msg.CreationTime)), + access=windows_timestamp(int(msg.LastAccessTime)), + write=windows_timestamp(int(msg.LastWriteTime)), + ) + + +IOEvent = Union[ + IOCallbackClass, FileEventType, ProcessEventType, EncryptEventType, RegCallbackClass +] + + +@dataclass +class BaseEvent(metaclass=ABCMeta): + """Base class for data about a filter event. + + Do not instantiate directly. + Subclasses should also be data-classes. + """ + + @classmethod + @abstractmethod + def from_msg( + cls: type[BaseEvent], msg: MESSAGE_SEND_DATA, base_args: BaseEventArgs + ) -> BaseEvent: + """Instantiate class from a raw MESSAGE_SEND_DATA struct. + + Args: + msg: Data to instantiate from. + base_args: Pre-computed arguments in the BaseEvent dataclass. Subclasses should only deal with their own arguments, and splat these common arguments out. + """ + + io_event_type: IOEvent + """I/O event type(s).""" + + filter_rule_id: int + """ID of the filter rule that fired this event.""" + + message_id: int + """Sequential message ID.""" + + sid: str + """Windows Security Identifier (SID) string of the user that initiated this event.""" + + account: AccountData + """Data about the user that initiated this event.""" + + can_reply: bool + """Set to `True` if this event may be replied to with a `CallbackReplyData`.""" + + +@dataclass +class BaseReply(ABC): + """Base class that the Python callback code can send to the driver in a reply. + + Do not instantiate directly. + + This is useful in, e.g., Control mode, where userspace needs to tell the + driver to deny/modify an I/O operation. + """ + + @abstractmethod + def to_msg(self, reply_data_p) -> None: # noqa: ANN001 + """Convert this class into a raw MESSAGE_REPLY_DATA struct. + + Args: + reply_data_p: Pointer to the struct. Guaranteed non-null by caller. + """ + + +MsgCallback = Callable[[BaseEvent], Optional[BaseReply]] +DisconCallback = Callable[[], None] diff --git a/Demo_Source_Code/PythonDemo/ef-python.pyproj b/Demo_Source_Code/PythonDemo/ef-python.pyproj new file mode 100644 index 0000000..30702eb --- /dev/null +++ b/Demo_Source_Code/PythonDemo/ef-python.pyproj @@ -0,0 +1,71 @@ + + + + Debug + 2.0 + {ec474f31-c400-47eb-b5e6-059bd8286a56} + + + + . + . + {888888a0-9f3d-457c-b088-3a5042f75d52} + Standard Python launcher + MSBuild|env|$(MSBuildProjectFullPath) + Pytest + + + + + 10.0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + env + env (Python 3.11 (64-bit)) + Scripts\python.exe + Scripts\pythonw.exe + 3.11 + X64 + PYTHONPATH + + + + \ No newline at end of file diff --git a/Demo_Source_Code/PythonDemo/ef-python.sln b/Demo_Source_Code/PythonDemo/ef-python.sln new file mode 100644 index 0000000..7c4e1f8 --- /dev/null +++ b/Demo_Source_Code/PythonDemo/ef-python.sln @@ -0,0 +1,23 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.34407.143 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{888888A0-9F3D-457C-B088-3A5042F75D52}") = "ef-python", "ef-python.pyproj", "{EC474F31-C400-47EB-B5E6-059BD8286A56}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {EC474F31-C400-47EB-B5E6-059BD8286A56}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EC474F31-C400-47EB-B5E6-059BD8286A56}.Release|Any CPU.ActiveCfg = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {6BBD78DC-5584-40DE-AB09-0F38084E5FEA} + EndGlobalSection +EndGlobal diff --git a/Demo_Source_Code/PythonDemo/pyproject.toml b/Demo_Source_Code/PythonDemo/pyproject.toml new file mode 100644 index 0000000..4e4d950 --- /dev/null +++ b/Demo_Source_Code/PythonDemo/pyproject.toml @@ -0,0 +1,173 @@ +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[project] +name = "easefilter" +description = 'High-level Pythonic API for EaseFilter' +readme = "README.md" +requires-python = ">=3.9" +license = "licenseref-proprietary" +keywords = [] +authors = [ + { name = "EaseFilter", email = "info@easefilter.com" }, +] +classifiers = [ + "Development Status :: 4 - Beta", + "Programming Language :: Python", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: Implementation :: CPython", + "Programming Language :: Python :: Implementation :: PyPy", + "Operating System :: Microsoft :: Windows" +] +dependencies = [ + "tomli >= 1.1.0 ; python_version < '3.11'", + "typing-extensions >= 4.12.2, < 5" +] +dynamic = ["version"] + +[project.urls] + +[project.scripts] +easefilter-cli = "easefilter.cli.main:entrypoint" + +[tool.hatch.version] +path = "easefilter/__about__.py" + +[tool.hatch.build.targets.sdist] +[tool.hatch.build.targets.wheel] + +[tool.hatch.envs.default.scripts] +cli = "python -m easefilter.cli.main {args}" + +[[tool.hatch.envs.test.matrix]] +python = ["3.9", "3.10", "3.11", "3.12"] + +[tool.coverage.run] +branch = true +parallel = true +omit = [ + "easefilter/__about__.py", + "tests/*" +] + +[tool.coverage.report] +exclude_lines = [ + "no cov", + "if __name__ == .__main__.:", + "if TYPE_CHECKING:", + "@(abc\\.)?abstractmethod", +] + +[tool.hatch.envs.hatch-static-analysis] +dependencies = [ + "ruff==0.5.5", + "pyright==1.1.374", + + # project dependencies for type-checking + "tomli >= 1.1.0 ; python_version < '3.11'", + "typing-extensions >= 4.12.2, < 5", + "pytest", +] + +[tool.hatch.envs.hatch-static-analysis.scripts] +config-path = "pyproject.toml" +format-check = [ + "ruff check {args:.}", +] +format-fix = [ + "- ruff check --fix {args:.}", + "ruff format {args:.}", +] +lint-check = "- pyright {args:.}" +lint-fix = "lint-check" + +[tool.ruff] +# make it the same as black +line-length = 88 + +[tool.ruff.lint] +explicit-preview-rules = true +select = [ "ALL" ] +ignore = [ + "ANN101", # missing `self` type annotation (type-checker can infer this) + + "COM812", # missing trailing comma (defer to formatter) + "ISC001", # string concatenation on one line (defer to formatter) + + "D100", # missing docstring in public module + "D101", # missing docstring in public class + "D102", # missing docstring in public method + "D103", # missing docstring in public function + "D104", # missing docstring in public package + "D105", # missing docstring in magic method + "D106", # missing docstring in public nested class + "D107", # missing docstring in __init__ + + "E266", # too many leading `#` before block comment + "E501", # line too long + + # c++ style names are used in places where appropriate. ignore these + "N801", + "N802", + "N803", + "N806", + + "TD001", # line contains FIXME, XXX (FIX already flags this) + "TD002", # missing todo author + "TD003", # missing todo issue link +] + +[tool.ruff.lint.per-file-ignores] +"easefilter/filter_api.py" = [ + "PLR0913", # too many arguments in function + "FBT001", # boolean positional arg + "FBT002", # boolean positional arg +] +# tests +"tests/*" = [ + "C901", # too complex + "PLR0912", # too many branches + "PLR0915", # too many statements + "PLR2004", # magic values + "S101", # asserts + "S602", # subprocess with shell=True + "S603", # check for untrusted input in subprocess call + "S607", # subprocess with partial executable path +] + +"tests/test*" = [ + "ANN001", # missing function argument type annotation + "ANN201", # missing public function return type annotation + "ANN202", # missing private function return type annotation + "S404", # subprocess module is insecure +] + +"tests/conftest.py" = [ + "ANN001", # missing type annotation for func arg + "ANN201", # missing public function return type annotation + "ANN202", # missing private function return type annotation +] + +"easefilter/cli/main.py" = [ + "T201" # `print` found +] + +[tool.ruff.lint.pydocstyle] +convention = "google" + +[tool.ruff.lint.mccabe] +max-complexity = 20 + +[tool.ruff.lint.flake8-pytest-style] +fixture-parentheses = false # make PT001 behaviour consistent + +[tool.ruff.format] +docstring-code-format = true + +[tool.pyright] +pythonVersion="3.9" +pythonPlatform="Windows" diff --git a/Demo_Source_Code/PythonDemo/requirements.txt b/Demo_Source_Code/PythonDemo/requirements.txt new file mode 100644 index 0000000..af8bcce --- /dev/null +++ b/Demo_Source_Code/PythonDemo/requirements.txt @@ -0,0 +1,10 @@ +colorama==0.4.6 +coverage==7.6.0 +iniconfig==2.0.0 +packaging==24.1 +pluggy==1.5.0 +pytest==8.3.2 +pytest-cov==5.0.0 +pytest-repeat==0.9.3 +tomli==1.1.0 +typing_extensions==4.12.2 diff --git a/Demo_Source_Code/PythonDemo/tests/__init__.py b/Demo_Source_Code/PythonDemo/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/Demo_Source_Code/PythonDemo/tests/conftest.py b/Demo_Source_Code/PythonDemo/tests/conftest.py new file mode 100644 index 0000000..01d7009 --- /dev/null +++ b/Demo_Source_Code/PythonDemo/tests/conftest.py @@ -0,0 +1,107 @@ +############################################################################### +## +## (C) Copyright 2022 EaseFilter Technologies +## All Rights Reserved +## +## This software is part of a licensed software product and may +## only be used or copied in accordance with the terms of that license. +## +## NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +## +## This module contains sample code provided for convenience and +## demonstration purposes only,this software is provided on an +## "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +## either express or implied. +## +############################################################################### + +import contextlib +import ctypes +import subprocess +from typing import TYPE_CHECKING + +import pytest + +import easefilter +from easefilter.config import get_config + +if TYPE_CHECKING: + from pathlib import Path + +with contextlib.suppress(ModuleNotFoundError): + pass + + +@pytest.fixture +def check_installed(): + """Check that EaseFilter is loaded and installed.""" + + def _check_installed(): + sc_proc = subprocess.run( + ["C:\\Windows\\System32\\sc", "query", "EaseFilter"], + capture_output=True, + check=False, + ) + if sc_proc.returncode != 0: + return False + + fltmc_proc = subprocess.run( + ["C:\\Windows\\System32\\fltmc"], + capture_output=True, + text=True, + check=False, + ) + return any(word == "EaseFilter" for word in fltmc_proc.stdout.split()) + + return _check_installed + + +@pytest.fixture +def win_sid(): + """The Windows Security Identifier for the current user.""" + return ( + subprocess.check_output("C:\\Windows\\System32\\whoami /User") + .decode() + .splitlines()[-1] + .split()[-1] + ) + + +def _ef_handle(*, activate: bool = True): + config = get_config() + + license_key = config.get("license_key") if activate else None + + if not ctypes.windll.shell32.IsUserAnAdmin(): # pragma: no cover + pytest.fail("Please run the tests with administrator privileges.") + return easefilter.EaseFilter(license_key=license_key) + + +@pytest.fixture +def ef_handle_unauth(): + """Get an EaseFilter handle, without activating with the license key.""" + return _ef_handle(activate=False) + + +@pytest.fixture(scope="session") +def ef_handle(): + """Get an EaseFilter handle, activated with the license key.""" + return _ef_handle() + + +@pytest.fixture +def _clean_driver(): + """Ensure EaseFilter is unloaded and uninstalled.""" + subprocess.run( + ["C:\\Windows\\System32\\fltmc", "unload", "EaseFilter"], + check=False, + ) + subprocess.run(["C:\\Windows\\System32\\sc", "stop", "EaseFilter"], check=False) + subprocess.run(["C:\\Windows\\System32\\sc", "delete", "EaseFilter"], check=False) + + +@pytest.fixture +def test_dir(tmp_path_factory): + """Create a temp directory for testing.""" + test_dir: Path = tmp_path_factory.mktemp("easefilter_pytest") + return test_dir diff --git a/Demo_Source_Code/PythonDemo/tests/fixtures/__init__.py b/Demo_Source_Code/PythonDemo/tests/fixtures/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/Demo_Source_Code/PythonDemo/tests/test_bitmasks.py b/Demo_Source_Code/PythonDemo/tests/test_bitmasks.py new file mode 100644 index 0000000..581aa58 --- /dev/null +++ b/Demo_Source_Code/PythonDemo/tests/test_bitmasks.py @@ -0,0 +1,165 @@ +############################################################################### +## +## (C) Copyright 2022 EaseFilter Technologies +## All Rights Reserved +## +## This software is part of a licensed software product and may +## only be used or copied in accordance with the terms of that license. +## +## NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +## +## This module contains sample code provided for convenience and +## demonstration purposes only,this software is provided on an +## "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +## either express or implied. +## +############################################################################### + +import random +from platform import python_version_tuple + +import easefilter.bitmask +import easefilter.enums +from easefilter.enums import AutoEnum, IOCallbackClass + + +def test_flag_extract() -> None: + """Test pre-Python 3.11 shim on __iter__.""" + rand = random.Random(0) # noqa: S311 (PRNG not suitable for crypto) + for _ in range(2500): + num = rand.randint(0, (easefilter.enums.IOCallbackClass.POST_CLOSE << 1) - 1) + assert set(easefilter.enums.IOCallbackClass(num)) == set( + easefilter.bitmask.flag_extract(easefilter.enums.IOCallbackClass(num)) + ) + + s = set(easefilter.enums.IOCallbackClass) + # behaviour changed in 3.11. zero will not appear + if [int(i) for i in python_version_tuple()] < [3, 11, 0]: + s.remove(IOCallbackClass(0)) + + assert s == { + IOCallbackClass.PRE_CREATE, + IOCallbackClass.POST_CREATE, + IOCallbackClass.PRE_NEW_FILE_CREATED, + IOCallbackClass.POST_NEW_FILE_CREATED, + IOCallbackClass.PRE_FASTIO_READ, + IOCallbackClass.POST_FASTIO_READ, + IOCallbackClass.PRE_CACHE_READ, + IOCallbackClass.POST_CACHE_READ, + IOCallbackClass.PRE_NOCACHE_READ, + IOCallbackClass.POST_NOCACHE_READ, + IOCallbackClass.PRE_PAGING_IO_READ, + IOCallbackClass.POST_PAGING_IO_READ, + IOCallbackClass.PRE_FASTIO_WRITE, + IOCallbackClass.POST_FASTIO_WRITE, + IOCallbackClass.PRE_CACHE_WRITE, + IOCallbackClass.POST_CACHE_WRITE, + IOCallbackClass.PRE_NOCACHE_WRITE, + IOCallbackClass.POST_NOCACHE_WRITE, + IOCallbackClass.PRE_PAGING_IO_WRITE, + IOCallbackClass.POST_PAGING_IO_WRITE, + IOCallbackClass.PRE_QUERY_INFORMATION, + IOCallbackClass.POST_QUERY_INFORMATION, + IOCallbackClass.PRE_QUERY_FILE_SIZE, + IOCallbackClass.POST_QUERY_FILE_SIZE, + IOCallbackClass.PRE_QUERY_FILE_BASIC_INFO, + IOCallbackClass.POST_QUERY_FILE_BASIC_INFO, + IOCallbackClass.PRE_QUERY_FILE_STANDARD_INFO, + IOCallbackClass.POST_QUERY_FILE_STANDARD_INFO, + IOCallbackClass.PRE_QUERY_FILE_NETWORK_INFO, + IOCallbackClass.POST_QUERY_FILE_NETWORK_INFO, + IOCallbackClass.PRE_QUERY_FILE_ID, + IOCallbackClass.POST_QUERY_FILE_ID, + IOCallbackClass.PRE_SET_INFORMATION, + IOCallbackClass.POST_SET_INFORMATION, + IOCallbackClass.PRE_SET_FILE_SIZE, + IOCallbackClass.POST_SET_FILE_SIZE, + IOCallbackClass.PRE_SET_FILE_BASIC_INFO, + IOCallbackClass.POST_SET_FILE_BASIC_INFO, + IOCallbackClass.PRE_SET_FILE_STANDARD_INFO, + IOCallbackClass.POST_SET_FILE_STANDARD_INFO, + IOCallbackClass.PRE_SET_FILE_NETWORK_INFO, + IOCallbackClass.POST_SET_FILE_NETWORK_INFO, + IOCallbackClass.PRE_RENAME_FILE, + IOCallbackClass.POST_RENAME_FILE, + IOCallbackClass.PRE_DELETE_FILE, + IOCallbackClass.POST_DELETE_FILE, + IOCallbackClass.PRE_DIRECTORY, + IOCallbackClass.POST_DIRECTORY, + IOCallbackClass.PRE_QUERY_SECURITY, + IOCallbackClass.POST_QUERY_SECURITY, + IOCallbackClass.PRE_SET_SECURITY, + IOCallbackClass.POST_SET_SECURITY, + IOCallbackClass.PRE_CLEANUP, + IOCallbackClass.POST_CLEANUP, + IOCallbackClass.PRE_CLOSE, + IOCallbackClass.POST_CLOSE, + } + + +def test_str_flag() -> None: + """Test str_flag (convert strings to int-flags) and converting int-flags back. + + Using an int-flag as an iterable is a feature introduced in Python 3.11. + """ + sym_strs = [ + "POST_CREATE", + "POST_FASTIO_READ", + "POST_CACHE_READ", + "POST_NOCACHE_READ", + "POST_PAGING_IO_READ", + "POST_FASTIO_WRITE", + "POST_CACHE_WRITE", + "POST_NOCACHE_WRITE", + "POST_PAGING_IO_WRITE", + "POST_QUERY_INFORMATION", + "POST_SET_INFORMATION", + "POST_DIRECTORY", + "POST_QUERY_SECURITY", + "POST_SET_SECURITY", + "POST_CLEANUP", + "POST_CLOSE", + ] + + num = 2863311530 + + assert ( + easefilter.bitmask.str_flag( + sym_strs, + easefilter.enums.IOCallbackClass, + ) + == num + ) + + syms: easefilter.enums.IOCallbackClass = easefilter.enums.IOCallbackClass(num) + assert {sym.name for sym in syms} == set(sym_strs) + + l2 = [ + "POST_CREATE", + "POST_FASTIO_READ", + ] + + assert ( + easefilter.bitmask.str_flag( + l2, + easefilter.enums.IOCallbackClass, + ) + == 10 + ) + + assert {sym.name for sym in easefilter.enums.IOCallbackClass(10)} == set(l2) + + +def test_enums() -> None: + """Test enum iteration behaviour. + + Iterating over an enum instance should yield only itself. + """ + + class e(AutoEnum): + a = 1 + b = 2 + c = 3 + + assert set(e) == {e.a, e.b, e.c} + assert tuple(set(i) for i in e) == tuple({i} for i in e) diff --git a/Demo_Source_Code/PythonDemo/tests/test_control_filter.py b/Demo_Source_Code/PythonDemo/tests/test_control_filter.py new file mode 100644 index 0000000..7874be9 --- /dev/null +++ b/Demo_Source_Code/PythonDemo/tests/test_control_filter.py @@ -0,0 +1,401 @@ +############################################################################### +## +## (C) Copyright 2024 EaseFilter Technologies +## All Rights Reserved +## +## This software is part of a licensed software product and may +## only be used or copied in accordance with the terms of that license. +## +## NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +## +## This module contains sample code provided for convenience and +## demonstration purposes only,this software is provided on an +## "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +## either express or implied. +## +############################################################################### + +"""Test control filter features.""" + +from __future__ import annotations + +import logging +import operator +from functools import reduce +from time import sleep +from typing import TYPE_CHECKING + +import pytest + +from easefilter.bitmask import str_flag +from easefilter.enums import ( + AccessFlag, + FileEventType, + FilterType, + InformationClass, + IOCallbackClass, +) +from easefilter.events import DenyReply, FileEvent +from easefilter.rules import FileRule + +if TYPE_CHECKING: + from collections.abc import Callable + from pathlib import Path + + from easefilter import EaseFilter + from easefilter.types import BaseEvent + + +def perm_tester( + test_dir: Path, disable_rule: Callable[[Callable], None] +) -> set[AccessFlag]: + """Test manipulations on files, reporting ones that fail. + + Args: + test_dir: Directory to perform the test in. + disable_rule: Wrapper closure that temporarily disables the filter rule. + """ + fails: set[AccessFlag] = set() + file: Path = test_dir / "MAGIC_FILE_NAME" + file2: Path = test_dir / "NEW_FILE_NAME" + + disable_rule(file.touch) + + Err = (OSError, PermissionError) + + try: + file.read_text() + except Err: + fails.add(AccessFlag.ALLOW_READ_ACCESS) + + try: + file.write_text("test text") + except Err: + fails.add(AccessFlag.ALLOW_WRITE_ACCESS) + + try: + file.rename(file2) + if not file2.exists: + raise OSError + except Err: + fails.add(AccessFlag.ALLOW_FILE_RENAME) + else: + disable_rule(file.touch) + + try: + file.unlink() + if file.exists(): + raise OSError + except Err: + fails.add(AccessFlag.ALLOW_FILE_DELETE) + else: + disable_rule(file.touch) + + try: + f = file.open("r") + f.close() + except Err: + fails.add(AccessFlag.ALLOW_OPEN_WITH_READ_ACCESS) + + try: + f = file.open("w") + f.close() + except Err: + fails.add(AccessFlag.ALLOW_OPEN_WITH_WRITE_ACCESS) + + disable_rule(file.unlink) + try: + f = file.touch() + except Err: + fails.add(AccessFlag.ALLOW_OPEN_WITH_CREATE_OR_OVERWRITE_ACCESS) + + return fails + + +@pytest.mark.parametrize( + ("deny_perms", "expected_fails"), + [ + pytest.param((), set(), id="empty"), + pytest.param( + (AccessFlag.ALLOW_READ_ACCESS), + {AccessFlag.ALLOW_READ_ACCESS}, + id="read", + ), + pytest.param( + (AccessFlag.ALLOW_WRITE_ACCESS), + {AccessFlag.ALLOW_WRITE_ACCESS}, + id="write", + ), + pytest.param( + (AccessFlag.ALLOW_WRITE_ACCESS, AccessFlag.ALLOW_READ_ACCESS), + {AccessFlag.ALLOW_WRITE_ACCESS, AccessFlag.ALLOW_READ_ACCESS}, + id="read-write", + ), + pytest.param( + (AccessFlag.ALLOW_FILE_RENAME,), + {AccessFlag.ALLOW_FILE_RENAME}, + id="rename", + ), + pytest.param( + (AccessFlag.ALLOW_FILE_DELETE,), + {AccessFlag.ALLOW_FILE_DELETE}, + id="delete", + ), + pytest.param( + (AccessFlag.ALLOW_OPEN_WITH_READ_ACCESS,), + { + AccessFlag.ALLOW_READ_ACCESS, + AccessFlag.ALLOW_OPEN_WITH_READ_ACCESS, + AccessFlag.ALLOW_OPEN_WITH_CREATE_OR_OVERWRITE_ACCESS, + AccessFlag.ALLOW_WRITE_ACCESS, + AccessFlag.ALLOW_OPEN_WITH_WRITE_ACCESS, + AccessFlag.ALLOW_FILE_RENAME, + }, + id="openread", + ), + pytest.param( + (AccessFlag.ALLOW_OPEN_WITH_WRITE_ACCESS,), + { + AccessFlag.ALLOW_WRITE_ACCESS, + AccessFlag.ALLOW_OPEN_WITH_WRITE_ACCESS, + AccessFlag.ALLOW_FILE_RENAME, + AccessFlag.ALLOW_FILE_DELETE, + AccessFlag.ALLOW_OPEN_WITH_CREATE_OR_OVERWRITE_ACCESS, + }, + id="openwrite", + ), + pytest.param( + (AccessFlag.ALLOW_OPEN_WITH_CREATE_OR_OVERWRITE_ACCESS,), + { + AccessFlag.ALLOW_OPEN_WITH_CREATE_OR_OVERWRITE_ACCESS, + AccessFlag.ALLOW_WRITE_ACCESS, + AccessFlag.ALLOW_OPEN_WITH_WRITE_ACCESS, + }, + id="opencreate", + ), + ], +) +def test_permissions( + ef_handle: EaseFilter, + test_dir: Path, + deny_perms: tuple[AccessFlag], + expected_fails: set[AccessFlag], +) -> None: + """Test denying certain permissions for files. + + This test is by no means exhaustive. + """ + deny_mask: AccessFlag = reduce(operator.ior, deny_perms, AccessFlag(0)) + logging.debug("deny mask is %s", deny_mask) + + def msg_hook(_): + pass + + with ef_handle as ef: + ef.message_callback = msg_hook + + ef.set_filter_type(FilterType.CONTROL) + rule = FileRule( + file_path=test_dir / "MAGIC_FILE_NAME", + change_event_filter=str_flag( + [ + "CREATED", + "WRITTEN", + "RENAMED", + "DELETED", + "READ", + ], + FileEventType, + ), + access_flag=AccessFlag.ALLOW_MAX_RIGHT_ACCESS & ~deny_mask, + ) + + rule.install(ef) + + def disable_rule(f: Callable): + """Disable rule and run function.""" + rule.uninstall(ef) + f() + rule.install(ef) + + sleep(0.01) + + fails = perm_tester(test_dir, disable_rule) + + assert fails == expected_fails + + +def test_dir_permissions( + ef_handle: EaseFilter, + test_dir: Path, +) -> None: + """Test denying directory list access.""" + file: Path = test_dir / "MAGIC_FILE_NAME" + + def msg_hook(_): + pass + + with ef_handle as ef: + ef.message_callback = msg_hook + + file.touch() + + ef.set_filter_type(FilterType.CONTROL) + rule = FileRule( + file_path=test_dir / "*", + change_event_filter=str_flag( + [], + FileEventType, + ), + access_flag=AccessFlag.ALLOW_MAX_RIGHT_ACCESS + & ~AccessFlag.ALLOW_DIRECTORY_LIST_ACCESS, + ) + + assert list(test_dir.iterdir()) == [file] + + rule.install(ef) + + sleep(0.01) + + with pytest.raises(PermissionError): + list(test_dir.iterdir()) + + file.write_text("test text") + assert file.read_text() == "test text" + + +@pytest.mark.parametrize( + ("control_mask", "expected_fails"), + [ + pytest.param((), set()), + pytest.param( + { + IOCallbackClass.PRE_CREATE, + IOCallbackClass.PRE_DELETE_FILE, + }, + { + AccessFlag.ALLOW_READ_ACCESS, + AccessFlag.ALLOW_OPEN_WITH_READ_ACCESS, + AccessFlag.ALLOW_OPEN_WITH_CREATE_OR_OVERWRITE_ACCESS, + AccessFlag.ALLOW_WRITE_ACCESS, + AccessFlag.ALLOW_OPEN_WITH_WRITE_ACCESS, + AccessFlag.ALLOW_FILE_RENAME, + AccessFlag.ALLOW_FILE_DELETE, + }, + ), + pytest.param( + { + IOCallbackClass.PRE_CACHE_READ, + IOCallbackClass.PRE_NOCACHE_READ, + IOCallbackClass.PRE_FASTIO_READ, + IOCallbackClass.PRE_PAGING_IO_READ, + }, + { + AccessFlag.ALLOW_READ_ACCESS, + }, + ), + pytest.param( + { + IOCallbackClass.PRE_CACHE_WRITE, + IOCallbackClass.PRE_NOCACHE_WRITE, + IOCallbackClass.PRE_FASTIO_WRITE, + IOCallbackClass.PRE_PAGING_IO_WRITE, + }, + { + AccessFlag.ALLOW_WRITE_ACCESS, + }, + ), + pytest.param( + {IOCallbackClass.PRE_DELETE_FILE, IOCallbackClass.PRE_SET_INFORMATION}, + { + AccessFlag.ALLOW_FILE_DELETE, + }, + ), + pytest.param( + {IOCallbackClass.PRE_RENAME_FILE, IOCallbackClass.PRE_SET_INFORMATION}, + { + AccessFlag.ALLOW_FILE_RENAME, + }, + ), + pytest.param( + set(IOCallbackClass), + { + AccessFlag.ALLOW_READ_ACCESS, + AccessFlag.ALLOW_OPEN_WITH_READ_ACCESS, + AccessFlag.ALLOW_OPEN_WITH_CREATE_OR_OVERWRITE_ACCESS, + AccessFlag.ALLOW_WRITE_ACCESS, + AccessFlag.ALLOW_OPEN_WITH_WRITE_ACCESS, + AccessFlag.ALLOW_FILE_RENAME, + AccessFlag.ALLOW_FILE_DELETE, + }, + ), + ], +) +@pytest.mark.parametrize("control_all", [False, True]) +def test_dynamic_deny( + ef_handle: EaseFilter, + test_dir: Path, + control_mask: set[IOCallbackClass], + expected_fails: set[AccessFlag], + *, + control_all: bool, +) -> None: + """Test denying access programmatically.""" + + def msg_hook(data: BaseEvent) -> DenyReply | None: + if not isinstance(data, FileEvent): + return None + + if isinstance(data.io_event_type, IOCallbackClass) and ( + any( + i in data.io_event_type + for i in control_mask + if i != IOCallbackClass.PRE_SET_INFORMATION + ) + or ( + data.info_class + in ( + InformationClass.FileRenameInformationEx, + InformationClass.FileRenameInformation, + ) + and IOCallbackClass.PRE_RENAME_FILE in control_mask + ) + or ( + data.info_class + in ( + InformationClass.FileDispositionInformation, + InformationClass.FileDispositionInformationEx, + ) + and IOCallbackClass.PRE_DELETE_FILE in control_mask + ) + ): + return DenyReply() + + return None + + with ef_handle as ef: + ef.message_callback = msg_hook + + ef.set_filter_type(FilterType.CONTROL) + + rule = FileRule( + file_path=test_dir / "*", + control_io_filter=reduce( + operator.ior, IOCallbackClass if control_all else control_mask, 0 + ), + access_flag=AccessFlag.ALLOW_MAX_RIGHT_ACCESS, + ) + + rule.install(ef) + + def disable_rule(f: Callable): + """Disable rule and run function.""" + rule.uninstall(ef) + f() + rule.install(ef) + + sleep(0.01) + + fails = perm_tester(test_dir, disable_rule) + + assert fails == expected_fails diff --git a/Demo_Source_Code/PythonDemo/tests/test_driver_basics.py b/Demo_Source_Code/PythonDemo/tests/test_driver_basics.py new file mode 100644 index 0000000..599fcfd --- /dev/null +++ b/Demo_Source_Code/PythonDemo/tests/test_driver_basics.py @@ -0,0 +1,88 @@ +############################################################################### +## +## (C) Copyright 2024 EaseFilter Technologies +## All Rights Reserved +## +## This software is part of a licensed software product and may +## only be used or copied in accordance with the terms of that license. +## +## NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +## +## This module contains sample code provided for convenience and +## demonstration purposes only,this software is provided on an +## "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +## either express or implied. +## +############################################################################### + +"""Test basic driver installation/activation, start/stop features.""" + +import subprocess +from pathlib import Path +from threading import Event + +import pytest + +from easefilter import EaseFilter +from easefilter.errors import FilterError +from easefilter.rules import FileRule + + +@pytest.mark.usefixtures("_clean_driver") +def test_install(ef_handle_unauth, check_installed): + """Test driver installation.""" + ef_handle_unauth.install_driver() + assert check_installed() + + # Ensure installing twice at once does not error + ef_handle_unauth.install_driver() + + +def test_uninstall(ef_handle_unauth, check_installed): + """Test driver uninstallation.""" + ef_handle_unauth.install_driver() + ef_handle_unauth.uninstall_driver() + assert not check_installed() + + +def test_license_check(ef_handle): + """Test that the license key works.""" + with ef_handle as _: + pass + + +def test_license_fail_check(ef_handle_unauth): + """Test that an absent license key does not work.""" + with pytest.raises(FilterError), ef_handle_unauth as _: + pass + + +def test_discon_callback(ef_handle: EaseFilter): + """Test that disconnecting the driver fires the disconnect hook.""" + disconnected = Event() + + def discon_hook(): + nonlocal disconnected + disconnected.set() + + with ef_handle as ef: + ef.discon_callback = discon_hook + + proc = subprocess.run( + ["C:\\Windows\\System32\\fltmc", "unload", "easefilter"], + check=True, + ) + assert proc.returncode == 0 + + # disconnect *should* fire when the with block is exited but it doesn't so whatever + + assert disconnected.wait(timeout=0.5) + + +def test_filter_type_warning(ef_handle: EaseFilter): + """Test that the filter will warn if a rule is applied without setting filter type.""" + with ef_handle as ef: + ef.message_callback = lambda _: None + rule = FileRule(Path(__file__)) + with pytest.warns(RuntimeWarning, match="Filter type"): + rule.install(ef) diff --git a/Demo_Source_Code/PythonDemo/tests/test_encryption_filter.py b/Demo_Source_Code/PythonDemo/tests/test_encryption_filter.py new file mode 100644 index 0000000..65f239a --- /dev/null +++ b/Demo_Source_Code/PythonDemo/tests/test_encryption_filter.py @@ -0,0 +1,165 @@ +############################################################################### +## +## (C) Copyright 2024 EaseFilter Technologies +## All Rights Reserved +## +## This software is part of a licensed software product and may +## only be used or copied in accordance with the terms of that license. +## +## NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +## +## This module contains sample code provided for convenience and +## demonstration purposes only,this software is provided on an +## "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +## either express or implied. +## +############################################################################### + +"""Test encryption filter features.""" + +from __future__ import annotations + +import logging +from threading import Event +from typing import TYPE_CHECKING + +import pytest + +from easefilter.enums import AccessFlag, BooleanConfig, EncryptEventType, FilterType +from easefilter.events import DenyReply, EncryptEvent, EncryptReply +from easefilter.rules import EncryptRule + +if TYPE_CHECKING: + from pathlib import Path + + from easefilter import EaseFilter + from easefilter.types import BaseEvent + + +def test_encryption( + *, + ef_handle: EaseFilter, + test_dir: Path, +): + """Test encryption with pre-set key (i.e. no callback).""" + test_file = test_dir / "test_file" + with ef_handle as ef: + ef.set_filter_type(FilterType.ENCRYPTION) + + test_text = b"lorem ipsum dolor sit amet" + + encryption_key = b"0123456789abcdef" + + rule = EncryptRule( + file_path=test_file, + encryption_key=encryption_key, + ) + rule.install(ef) + test_file.write_bytes(test_text) + assert test_file.read_bytes() == test_text + rule.uninstall(ef) + encrypted: bytes = test_file.read_bytes() + assert encrypted != test_text + + rule2 = EncryptRule( + file_path=test_file, + encryption_key=encryption_key, + access_flag=AccessFlag.ALLOW_MAX_RIGHT_ACCESS + & ~(AccessFlag.ALLOW_READ_ENCRYPTED_FILES), + ) + rule2.install(ef) + assert test_file.read_bytes() == encrypted + rule2.uninstall(ef) + assert test_file.read_bytes() == encrypted + + +def test_callback_encryption( + *, + ef_handle: EaseFilter, + test_dir: Path, +): + """Test dynamic encryption (i.e. with callback).""" + enc_folder = test_dir / "encrypted" + enc_folder.mkdir() + test_file1 = enc_folder / "test_file1" + test_file2 = enc_folder / "test_file2" + + enc_key: bytes = b"1234567890abcdef" * 2 + iv = b"1234567890abcdef" + + def msg_hook(msg: BaseEvent) -> EncryptReply | DenyReply | None: + """Deny processes from decrypting one file.""" + if not isinstance(msg, EncryptEvent): + logging.warning("spurious event %s", msg) + return None + + if msg.file_name == test_file2: + return DenyReply() + + return EncryptReply(encryption_key=enc_key, iv=iv) + + test_data: bytes = b"lorem ipsum dolor sit amet" + + with ef_handle as ef: + ef.message_callback = msg_hook + ef.set_filter_type(FilterType.ENCRYPTION) + + rule = EncryptRule( + file_path=enc_folder / "*", + encryption_key=None, + boolean_config=BooleanConfig.REQUEST_ENCRYPT_KEY_IV_AND_TAGDATA_FROM_SERVICE, + ) + rule.install(ef) + + test_file1.write_bytes(test_data) + assert test_file1.read_bytes() == test_data + + with pytest.raises(OSError, match="Permission denied"): + test_file2.write_bytes(test_data) + + +def test_tag_data(*, ef_handle: EaseFilter, test_dir: Path): + """Test storing tag data in files.""" + enc_folder = test_dir / "encrypted" + enc_folder.mkdir() + + enc_key: bytes = b"1234567890abcdef" + + found = Event() + """Tag data was found.""" + + bad = Event() + """Tag data found was incorrect.""" + + def msg_hook(msg: BaseEvent) -> EncryptReply | None: + """Tag files with their file path.""" + if not isinstance(msg, EncryptEvent): + logging.warning("spurious event %s", msg) + return None + + if msg.io_event_type == EncryptEventType.RequestIvAndKey and msg.tag_data: + found.set() + if msg.tag_data.decode() != str(msg.file_name): + bad.set() + + return EncryptReply( + encryption_key=enc_key, tag_data=str(msg.file_name).encode() + ) + + with ef_handle as ef: + ef.message_callback = msg_hook + ef.set_filter_type(FilterType.ENCRYPTION) + rule = EncryptRule( + file_path=test_dir / "*", + boolean_config=BooleanConfig.REQUEST_ENCRYPT_KEY_IV_AND_TAGDATA_FROM_SERVICE, + ) + rule.install(ef) + + name = "file.txt" + f = test_dir / name + test_text = "lorem ipsum" + f.write_text(test_text) + assert f.read_text() == test_text + + assert found.wait(timeout=0.2) + assert not bad.wait(timeout=0.2) diff --git a/Demo_Source_Code/PythonDemo/tests/test_monitor_filter.py b/Demo_Source_Code/PythonDemo/tests/test_monitor_filter.py new file mode 100644 index 0000000..e320226 --- /dev/null +++ b/Demo_Source_Code/PythonDemo/tests/test_monitor_filter.py @@ -0,0 +1,570 @@ +############################################################################### +## +## (C) Copyright 2024 EaseFilter Technologies +## All Rights Reserved +## +## This software is part of a licensed software product and may +## only be used or copied in accordance with the terms of that license. +## +## NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +## +## This module contains sample code provided for convenience and +## demonstration purposes only,this software is provided on an +## "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +## either express or implied. +## +############################################################################### + +"""Test monitor filter features.""" + +import logging +import os +import subprocess +import threading +import time +from datetime import datetime, timedelta, timezone +from pathlib import Path +from threading import Event + +import pytest + +from easefilter import EaseFilter +from easefilter.bitmask import str_flag +from easefilter.enums import FileEventType, FilterType +from easefilter.events import FileEvent +from easefilter.rules import FileRule +from easefilter.types import BaseEvent + + +def test_events(ef_handle: EaseFilter, test_dir: Path) -> None: + """Test the monitor filter on specific events, and test uninstalling rules.""" + found_good: dict[FileEventType, Event] = {k: Event() for k in FileEventType} + found_wrong = Event() + + magic_file: Path = test_dir / "MAGIC_FILE_NAME" + new_magic_file: Path = test_dir / "NEW_MAGIC_FILE_NAME" + wrong_file: Path = test_dir / "WRONG_FILE_NAME" + + rule_id_set = Event() + rule_id: int + + def msg_hook(event_data: BaseEvent): + if not isinstance(event_data, FileEvent): + return + + if not rule_id_set.wait(timeout=1): + found_wrong.set() + msg = "rule id not set when message callback called" + raise RuntimeError(msg) + + if event_data.file_name in (magic_file, new_magic_file): + t = event_data.io_event_type + if isinstance(t, FileEventType): + for sym in t: + found_good[sym].set() + else: + found_wrong.set() + msg = f"spurious event {t} found" + raise RuntimeError(msg) + if event_data.file_name == wrong_file: + found_wrong.set() + msg = f"wrong file name {event_data.file_name} found" + raise RuntimeError(msg) + if event_data.filter_rule_id != rule_id: + found_wrong.set() + msg = f"wrong rule id {event_data.filter_rule_id} found" + raise RuntimeError(msg) + + def reset_events(): + for k in found_good: + found_good[k].clear() + + def get_events(): + assert not found_wrong.wait(timeout=0.1) + return {k for k in FileEventType if found_good[k].wait(timeout=0.1)} + + with ef_handle as ef: + ef.message_callback = msg_hook + + ef.set_filter_type(FilterType.MONITOR) + rule = FileRule( + file_path=test_dir / "*", + change_event_filter=str_flag( + [ + "CREATED", + "WRITTEN", + "RENAMED", + "DELETED", + "READ", + ], + FileEventType, + ), + ) + + for rule_install in [False, True]: + if rule_install: + rule.install(ef) + assert rule.rule_id is not None + rule_id = rule.rule_id + rule_id_set.set() + logging.debug("Rule ID: %d", rule_id) + else: + rule.uninstall(ef) + + magic_file.touch() + logging.debug("Touched %s.", magic_file) + ev = get_events() + if rule_install: + assert ev == {FileEventType.CREATED} + else: + assert ev == set() + reset_events() + + with magic_file.open("w") as f: + f.write("test contents") + logging.debug("Wrote to %s.", magic_file) + ev = get_events() + if rule_install: + assert ev == {FileEventType.WRITTEN} + else: + assert ev == set() + + reset_events() + + magic_file.rename(new_magic_file) + logging.debug("File moved to %s.", new_magic_file) + ev = get_events() + if rule_install: + assert ev == {FileEventType.RENAMED} + else: + assert ev == set() + reset_events() + + with new_magic_file.open("r") as f: + _ = f.read() + logging.debug("Read content from %s.", new_magic_file) + ev = get_events() + if rule_install: + assert ev == {FileEventType.READ} + else: + assert ev == set() + reset_events() + + new_magic_file.unlink() + logging.debug("Deleted %s.", new_magic_file) + ev = get_events() + if rule_install: + assert ev == {FileEventType.DELETED} + else: + assert ev == set() + reset_events() + + +def test_rule_id(ef_handle: EaseFilter, test_dir: Path) -> None: + """Test that monitor rule IDs make sense.""" + file1: Path = test_dir / "MAGIC_FILE_NAME" + file2: Path = test_dir / "NEWER_FILE_NAME" + + rule1_id: int + rule2_id: int + + found1 = Event() + found2 = Event() + + wrong = Event() + + def msg_hook(event_data: BaseEvent): + if not isinstance(event_data, FileEvent): + return + + if event_data.file_name == file1: + found1.set() + if rule1_id != event_data.filter_rule_id: + wrong.set() + if event_data.file_name == file2: + found2.set() + if rule2_id != event_data.filter_rule_id: + wrong.set() + + with ef_handle as ef: + ef.message_callback = msg_hook + + ef.set_filter_type(FilterType.MONITOR) + rule1 = FileRule( + file_path=test_dir / "MAGIC_FILE_NAME", + change_event_filter=str_flag( + [ + "CREATED", + "WRITTEN", + "RENAMED", + "DELETED", + "READ", + ], + FileEventType, + ), + ) + rule1.install(ef) + assert rule1.rule_id is not None + rule1_id = rule1.rule_id + + rule2 = FileRule( + file_path=test_dir / "NEWER_FILE_NAME", + change_event_filter=str_flag( + [ + "CREATED", + "WRITTEN", + "RENAMED", + "DELETED", + "READ", + ], + FileEventType, + ), + ) + rule2.install(ef) + assert rule2.rule_id is not None + rule2_id = rule2.rule_id + assert rule2_id != rule1_id + + file1.touch() + file2.touch() + + assert not wrong.wait(timeout=0.1) + assert found1.wait(timeout=0.1) + assert found2.wait(timeout=0.1) + + +def test_ids(ef_handle: EaseFilter, test_dir: Path, win_sid) -> None: + """Test that PID/thread IDs, SID and user/domain info come back correctly.""" + file: Path = test_dir / "MAGIC_FILE_NAME" + + pid: int + tid: int + sid: str + whoami: str + + found = Event() + wrong = Event() + + def msg_hook(event_data: BaseEvent): + if not isinstance(event_data, FileEvent): + return + if event_data.file_name == file: + found.set() + if event_data.process.tid != tid: + logging.debug( + "Thread ID wrong, got: '%d'; expected '%d'", + event_data.process.tid, + tid, + ) + wrong.set() + if event_data.process.pid != pid: + logging.debug( + "PID wrong, got: '%d'; expected '%d'", + event_data.process.pid, + pid, + ) + wrong.set() + if event_data.sid != sid: + logging.debug("SID wrong, got: '%s'; expected '%s'", event_data.sid, sid) + wrong.set() + + got_whoami: str = ( + f"{event_data.account.domain}\\{event_data.account.username}".lower() + ) + if got_whoami != whoami: + logging.debug( + "User info wrong, got '%s'; expected '%s'", + got_whoami, + whoami, + ) + wrong.set() + + with ef_handle as ef: + ef.message_callback = msg_hook + + pid = os.getpid() + tid = threading.get_ident() + sid = win_sid + whoami = ( + subprocess.check_output("C:\\Windows\\System32\\whoami") + .decode() + .lower() + .strip() + ) + + ef.set_filter_type(FilterType.MONITOR) + rule1 = FileRule( + file_path=test_dir / "MAGIC_FILE_NAME", + change_event_filter=str_flag( + [ + "CREATED", + "WRITTEN", + "RENAMED", + "DELETED", + "READ", + ], + FileEventType, + ), + ) + rule1.install(ef) + + file.touch() + + assert not wrong.wait(timeout=0.1) + assert found.wait(timeout=0.1) + + +def test_process_path(ef_handle: EaseFilter, test_dir: Path) -> None: + """Test process file path.""" + file: Path = test_dir / "MAGIC_FILE_NAME" + with file.open("w") as f: + f.write("file contents") + + found = Event() + wrong = Event() + + def msg_hook(event_data: BaseEvent): + if not isinstance(event_data, FileEvent): + return + if event_data.file_name == file: + found.set() + if (path := event_data.process.path) != ( + cmd_path := Path("C:\\") / "Windows" / "System32" / "cmd.exe" + ): + logging.debug("Process path wrong, got '%s'; expected '%s'", path, cmd_path) + wrong.set() + + with ef_handle as ef: + ef.message_callback = msg_hook + + ef.set_filter_type(FilterType.MONITOR) + rule1 = FileRule( + file_path=file, + change_event_filter=str_flag( + [ + "READ", + ], + FileEventType, + ), + ) + rule1.install(ef) + + # ping as delay + cmd_line = [ + "cmd.exe", + "/C", + "type", + str(file), + "&&", + "ping", + "localhost", + "-n", + "2", + ">nul", + ] + logging.debug("Running '%s'", " ".join(cmd_line)) + outp: str = subprocess.check_output(cmd_line).decode() + assert outp == "file contents" + + assert not wrong.wait(timeout=0.1) + assert found.wait(timeout=0.1) + + +def test_timestamps(ef_handle: EaseFilter, test_dir: Path) -> None: + """Test file timestamps.""" + file: Path = test_dir / "MAGIC_FILE_NAME" + file.touch() + + def ns_ts_to_date(t: int) -> datetime: + """Round Unix timestamp nanoseconds to the nearest 100 nanosecond tick. + + This makes it correspond to the resolution of Windows' timestamps. + """ + # hundred-nanosecond tick + t = t // 100 + + return datetime.fromtimestamp(0, tz=timezone.utc) + timedelta( + microseconds=t / 10, + ) + + time_create = ns_ts_to_date(file.stat().st_ctime_ns) + + # ensure we have different timestamps for create/write + time.sleep(0.1) + with file.open("w") as f: + f.write("file contents") + time_write = ns_ts_to_date(file.stat().st_mtime_ns) + + # lock to ensure we read the access time through python before verifying + # filter's time against it + ready = Event() + + time_access = None + + found = Event() + wrong = Event() + + def msg_hook(event_data: BaseEvent): + if not isinstance(event_data, FileEvent): + return + if event_data.file_name == file: + assert ready.wait(timeout=0.1) + found.set() + + def fuzzy_eq( + t1: datetime, + t2: datetime, + epsilon: timedelta = timedelta(microseconds=5), + ) -> bool: + """Fuzzy equality for timestamps. + + Arguments: + t1: Timestamp. + t2: Timestamp. + epsilon: Maximum allowed difference between timestamps. + + Returns: + If the timestamps are similar enough to be considered qual. + """ + if t2 > t1: + t1, t2 = t2, t1 + + return t2 - t1 <= epsilon + + assert time_access is not None + + # access time may not be always updated for performance reasons + # it could be equal to write time + if not fuzzy_eq(event_data.time.access, time_access) and not fuzzy_eq( + event_data.time.access, + time_write, + ): + logging.debug( + "Got atime %s, expected %s", + event_data.time.access, + time_access, + ) + wrong.set() + if not fuzzy_eq(event_data.time.write, time_write): + logging.debug( + "Got mtime %s, expected %s", + event_data.time.write, + time_write, + ) + wrong.set() + if not fuzzy_eq(event_data.time.create, time_create): + logging.debug( + "Got ctime %s, expected %s", + event_data.time.create, + time_create, + ) + wrong.set() + + with ef_handle as ef: + ef.message_callback = msg_hook + + ef.set_filter_type(FilterType.MONITOR) + rule1 = FileRule( + file_path=file, + change_event_filter=str_flag( + [ + "READ", + ], + FileEventType, + ), + ) + rule1.install(ef) + + time.sleep(0.05) + + with file.open("r") as f: + content = f.read() + assert content == "file contents" + time_access = ns_ts_to_date(file.stat().st_atime_ns) + ready.set() + + assert not wrong.wait(timeout=0.1) + assert found.wait(timeout=0.1) + + +@pytest.mark.parametrize("event_type", ["RENAMED", "COPIED"]) +def test_rename_copy(ef_handle: EaseFilter, test_dir: Path, event_type: str) -> None: + """Test that rename/copied events have the correct new file name.""" + if event_type == "COPIED": + pytest.skip() # COPIED broken in the test environment + + file: Path = test_dir / "MAGIC_FILE_NAME" + file2: Path = test_dir / "NEW_MAGIC_FILE_NAME" + file3: Path = test_dir / "NEWER_MAGIC_FILE_NAME" + + found = Event() + wrong = Event() + + def msg_hook(event_data: BaseEvent): + if not isinstance(event_data, FileEvent): + return + target: Path = file2 + + if event_type == "RENAMED": + if event_data.file_name == file: + found.set() + target = file2 + elif event_data.file_name == file2: + found.set() + target = file3 + elif event_type == "COPIED": + if event_data.file_name == file2: + found.set() + target = file + elif event_data.file_name == file3: + found.set() + target = file2 + + if event_data.new_path is None: + wrong.set() + msg = "New path was empty." + raise ValueError(msg) + if event_data.new_path != target: + logging.debug( + "New path wrong, got: '%s'; expected '%s'", + event_data.new_path, + target, + ) + wrong.set() + + with ef_handle as ef: + ef.message_callback = msg_hook + + ef.set_filter_type(FilterType.MONITOR) + rule1 = FileRule( + file_path=test_dir / "*", + change_event_filter=str_flag( + [ + event_type, + ], + FileEventType, + ), + ) + logging.debug("applying rule: %s", rule1) + rule1.install(ef) + + def copy(f1: Path, f2: Path): + cmd = ["copy", str(f1), str(f2)] + logging.debug("performing: %s", cmd) + subprocess.run(cmd, shell=True, check=True) + + file.touch() + if event_type == "RENAMED": + file.rename(file2) + file2.rename(file3) + elif event_type == "COPIED": + assert not file2.exists() + copy(file, file2) + assert file2.exists() + + assert not file3.exists() + copy(file2, file3) + assert file3.exists() + + assert not wrong.wait(timeout=0.1) + assert found.wait(timeout=0.1) diff --git a/Demo_Source_Code/PythonDemo/tests/test_process_filter.py b/Demo_Source_Code/PythonDemo/tests/test_process_filter.py new file mode 100644 index 0000000..e83f22e --- /dev/null +++ b/Demo_Source_Code/PythonDemo/tests/test_process_filter.py @@ -0,0 +1,373 @@ +############################################################################### +## +## (C) Copyright 2024 EaseFilter Technologies +## All Rights Reserved +## +## This software is part of a licensed software product and may +## only be used or copied in accordance with the terms of that license. +## +## NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +## +## This module contains sample code provided for convenience and +## demonstration purposes only,this software is provided on an +## "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +## either express or implied. +## +############################################################################### + +"""Test process filter features.""" + +from __future__ import annotations + +import inspect +import logging +import os +import shutil +import subprocess +import sys +import threading +import venv +from pathlib import Path +from threading import Event, Lock +from typing import TYPE_CHECKING + +import pytest + +if TYPE_CHECKING: + from easefilter import EaseFilter + from easefilter.types import BaseEvent + +from easefilter.enums import FilterType, ProcessControlFlag, ProcessEventType +from easefilter.events import DenyReply, ProcessEvent +from easefilter.rules import ProcessRule + + +def process_test(n_threads: int): + """Test script that spawns threads. + + Do not call directly; this is a helper for `test_process_thread_monitor`. + It is intended to run in a separate script file, under another Python process, so that it may be isolated in the test. + + Args: + n_threads: Total number of threads to spawn, including the initial one which already exists. + """ + + def thread_worker(_): + import time + + return time.sleep(0.02) + + import os + import threading + + if __name__ == "__main__": + print(os.getpid()) # noqa: T201 + workers = [] + for i in range(n_threads - 1): + t = threading.Thread(target=thread_worker, args=(i,)) + t.start() + workers.append(t) + + _ = threading.current_thread() + assert len(threading.enumerate()) == n_threads + + for t in workers: + t.join() + + +@pytest.mark.parametrize("enable_rule", [False, True]) +@pytest.mark.parametrize("n_processes", [1, 3, 5]) +@pytest.mark.parametrize("n_threads", list(range(1, 3))) +def test_process_thread_monitor( + *, + ef_handle: EaseFilter, + test_dir: Path, + n_processes: int, + enable_rule: bool, + n_threads: int, +): + """Monitor process/thread creation/termination. + + Currently, thread monitoring is not tested because Python venv threads are + hard to manage consistently, and thus make for flaky tests. + + Args: + ef_handle: EaseFilter handle. + test_dir: Testing temp dir. + n_processes: Number of processes to spawn. + n_threads: Threads per process to spawn. + enable_rule: If disabled, uninstalls filter rule immediately. + """ + lock = Lock() + process_create: int = 0 + process_del: int = 0 + thread_create: int = 0 + thread_del: int = 0 + good = Event() + bad = Event() + + def msg_hook(data: BaseEvent): + if not isinstance(data, ProcessEvent): + return + + nonlocal process_create, process_del, thread_create, thread_del + lock.acquire(timeout=5) + if data.io_event_type == ProcessEventType.ProcessCreationInfo: + process_create += 1 + elif data.io_event_type == ProcessEventType.ProcessTerminated: + process_del += 1 + elif data.io_event_type == ProcessEventType.ThreadCreated: + thread_create += 1 + elif data.io_event_type == ProcessEventType.ThreadTerminated: + thread_del += 1 + + if not enable_rule and ( + max(process_create, process_del, thread_create, thread_del) > 0 + ): + bad.set() + logging.error("process/thread detected when rule disabled") + if max(process_create, process_del) > n_processes: + bad.set() + logging.error("too many processes %d / %d", process_create, process_del) + if process_create == n_processes and process_del == n_processes: + good.set() + lock.release() + + venv_path = test_dir / Path("venv") + exec_path = venv_path / Path("Scripts/python.exe") + + with ef_handle as ef: + ef.message_callback = msg_hook + ef.set_filter_type(FilterType.PROCESS) + + # we're going to run a script using a separate copy of Python + venv.create(venv_path) + script: str = ( + inspect.getsource(process_test) + f"""\nprocess_test({n_threads})""" + ) + script_path = test_dir / Path("script.py") + script_path.write_text(script) + + rule = ProcessRule( + executable_mask=venv_path / Path("*"), + control_flag=ProcessControlFlag.PROCESS_CREATION_NOTIFICATION + | ProcessControlFlag.PROCESS_TERMINATION_NOTIFICATION + | ProcessControlFlag.THREAD_CREATION_NOTIFICATION + | ProcessControlFlag.THREAD_TERMINATION_NOTIFICATION, + ) + rule.install(ef) + if not enable_rule: + rule.uninstall(ef) + + pids: set[str] = set() + for _ in range(n_processes): + pids.add( + subprocess.check_output([str(exec_path), str(script_path)]) + .decode("utf-8") + .strip() + ) + assert len(pids) == n_processes + logging.debug(pids) + + if enable_rule: + assert good.wait(timeout=0.5) + assert not bad.wait(timeout=0.1) + + lock.acquire(timeout=5) + if enable_rule: + assert process_create == n_processes + assert process_del == n_processes + else: + assert process_create == 0 + assert process_del == 0 + lock.release() + + +def test_deny_process(*, ef_handle: EaseFilter, test_dir: Path): + """Deny process start.""" + # hatch venv python won't work outside of venv + # however it will run if it is not denied + src_path = Path(sys.executable) + exec_path = test_dir / "python.exe" + shutil.copy(src_path, exec_path) + + def msg_hook(_): ... + + rule = ProcessRule( + exec_path, + ProcessControlFlag.DENY_NEW_PROCESS_CREATION, + ) + + with ef_handle as ef: + ef.message_callback = msg_hook + ef.set_filter_type(FilterType.PROCESS) + + rule.install(ef) + with pytest.raises(PermissionError): + subprocess.check_call(exec_path) + + rule.uninstall(ef) + + # this binary should be broken and return non-zero + # still it should run + with pytest.raises(subprocess.CalledProcessError): + subprocess.check_call([exec_path, "garbage_arg"]) + + +def test_dynamic_deny(*, ef_handle: EaseFilter, test_dir: Path): + """Deny process start, programmatically.""" + # hatch venv python won't work outside of venv + # however it will run if it is not denied + src_path = Path(sys.executable) + exec_path = test_dir / "python.exe" + shutil.copy(src_path, exec_path) + + forbidden_word: str = "password123" + + def msg_hook(msg: BaseEvent) -> DenyReply | None: + if not isinstance(msg, ProcessEvent): + return None + if msg.command_line and forbidden_word in msg.command_line: + return DenyReply() + return None + + rule = ProcessRule( + exec_path, + ProcessControlFlag.PROCESS_CREATION_NOTIFICATION, + ) + + with ef_handle as ef: + ef.message_callback = msg_hook + ef.set_filter_type(FilterType.PROCESS) + + rule.install(ef) + subprocess.run(exec_path, check=False) + subprocess.run([exec_path, "argument", "--flag"], check=False) + + with pytest.raises(PermissionError): + subprocess.run( + [exec_path, "--secret", forbidden_word, "--flag"], check=False + ) + + +def info_test(): + """Helper script that prints PID/TID. + + Do not call directly, as this is intended to run in a separate Python instance. + """ + import os + from threading import get_native_id + + # https://stackoverflow.com/a/64891362 + # this should be just getpid(), but windows venv breaks that + print(os.getppid()) # noqa: T201 + print(get_native_id()) # noqa: T201 + + +def test_process_info(*, ef_handle: EaseFilter, test_dir: Path): + """Test PROCESS_INFO struct fields. + + Notably: + - Parent process + - Creating process/thread + - Child process + - Command line + """ + venv_path = test_dir / Path("venv") + exec_path = venv_path / Path("Scripts/python.exe") + + magic_param = "MAGIC_COOKIE1234👍🐸" + """Argument to be passed to the child process to test the command line field. + + Includes some emoji for good measure. + """ + + par_pid = os.getpid() + """Parent process ID (reference value).""" + creating_tid = threading.get_native_id() + """Creator thread ID (reference value).""" + good_p_pid = Event() + """Has par_pid been found in the callback thread yet.""" + good_cr_tid = Event() + """Has creating_tid been found in the callback thread yet.""" + + child_pid: int | None = None + """Child PID, assigned in the callback thread and verified in the parent.""" + found_child_pid = Event() + """Has `child_pid` been set by the callback thread yet.""" + + bad = Event() + """Has an error occured in the callback.""" + + def msg_hook(msg: BaseEvent): + if not isinstance(msg, ProcessEvent): + logging.error("spurious event %s", msg) + bad.set() + return + + if msg.io_event_type == ProcessEventType.ProcessCreationInfo: + nonlocal child_pid + child_pid = msg.process.pid + found_child_pid.set() + if msg.creating_proc: + if msg.creating_proc.tid != creating_tid: + bad.set() + logging.error( + "creating tid invalid: got %d instead of %d", + msg.creating_proc.tid, + creating_tid, + ) + else: + good_cr_tid.set() + + if msg.parent_proc: + if msg.parent_proc.pid != par_pid: + bad.set() + logging.error( + "parent pid invalid: got %d instead of %d", + msg.parent_proc.pid, + par_pid, + ) + else: + good_p_pid.set() + + if msg.command_line: + assert msg.command_line.endswith(magic_param) + + with ef_handle as ef: + ef.message_callback = msg_hook + ef.set_filter_type(FilterType.PROCESS) + + # we're going to run a script using a separate copy of Python + venv.create(venv_path) + script: str = inspect.getsource(info_test) + """\ninfo_test()""" + script_path = test_dir / Path("script.py") + script_path.write_text(script) + + rule = ProcessRule( + executable_mask=exec_path, + control_flag=ProcessControlFlag.PROCESS_CREATION_NOTIFICATION + | ProcessControlFlag.PROCESS_TERMINATION_NOTIFICATION + | ProcessControlFlag.THREAD_CREATION_NOTIFICATION, + ) + rule.install(ef) + + child_proc = subprocess.Popen( + [exec_path, script_path, magic_param], stdout=subprocess.PIPE, text=True + ) + logging.debug("process opened.") + stdout, _ = child_proc.communicate() + logging.debug("communication finished.") + outp = stdout.splitlines() + logging.debug("child stdout: %s", outp) + + # child pid/tid as seen by itself + p_child_pid, child_tid = (int(i) for i in outp) + assert p_child_pid == child_proc.pid + logging.debug("child pid / tid : %d / %d", p_child_pid, child_tid) + + assert found_child_pid.wait(timeout=0.5) + assert child_pid == p_child_pid + + assert all([e.wait(timeout=0.5) for e in [good_p_pid, good_cr_tid]]) # noqa: C419 (unnecessary list comprehension; useful in pytest output) + assert not bad.wait(timeout=0.5) diff --git a/Demo_Source_Code/PythonDemo/tests/test_registry_filter.py b/Demo_Source_Code/PythonDemo/tests/test_registry_filter.py new file mode 100644 index 0000000..5be4570 --- /dev/null +++ b/Demo_Source_Code/PythonDemo/tests/test_registry_filter.py @@ -0,0 +1,200 @@ +############################################################################### +## +## (C) Copyright 2024 EaseFilter Technologies +## All Rights Reserved +## +## This software is part of a licensed software product and may +## only be used or copied in accordance with the terms of that license. +## +## NOTE: THIS MODULE IS UNSUPPORTED SAMPLE CODE +## +## This module contains sample code provided for convenience and +## demonstration purposes only,this software is provided on an +## "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +## either express or implied. +## +############################################################################### + +"""Test registry filter features.""" + +from __future__ import annotations + +import functools +import logging +import operator +import os +import subprocess +import winreg +from pathlib import Path +from threading import Event, Lock +from typing import TYPE_CHECKING + +import pytest + +from easefilter.enums import FilterType, RegCallbackClass, RegControlFlag +from easefilter.events import DenyReply, RegistryEvent +from easefilter.rules import RegistryProcIdRule, RegistryProcNameRule + +if TYPE_CHECKING: + from easefilter import EaseFilter + from easefilter.types import BaseEvent + + +def test_no_default(): + """Test that invalid rules can not be created.""" + with pytest.raises(TypeError): + RegistryProcIdRule(key_mask="", callback_class=RegCallbackClass(0)) + with pytest.raises(TypeError): + RegistryProcNameRule(key_mask="", callback_class=RegCallbackClass(0)) + + +def test_proc_name_monitor(ef_handle: EaseFilter): + """Test registry event monitoring, matching by process name.""" + app_name = "EasefilterPython" + + rule = RegistryProcNameRule( + f"*\\{app_name}\\*", + functools.reduce(operator.ior, RegCallbackClass), + proc_name=Path(f"{os.environ['WINDIR']}\\system32\\reg.exe"), + ) + + test_keys = {"1", "test_name", "1234", "TEST"} + + lock = Lock() + found_keys: set[str] = set() + done = Event() + bad = Event() + + def msg_hook(ev: BaseEvent) -> None: + if not isinstance(ev, RegistryEvent): + logging.warning("spurious event %s", ev) + return + + with lock: + found_keys.add(ev.key_name.split("\\")[-1].strip(":")) + if len(found_keys) > len(test_keys): + logging.info("too many keys: %s", found_keys) + bad.set() + if len(found_keys) == len(test_keys): + done.set() + + with ef_handle as ef: + ef.set_filter_type(FilterType.REGISTRY) + ef.message_callback = msg_hook + rule.install(ef) + logging.debug("applied rule: %s", rule) + + with ( + winreg.OpenKeyEx(winreg.HKEY_CURRENT_USER, "Software\\") as soft_key, + winreg.CreateKey(soft_key, app_name + "\\"), + ): + for k in test_keys: + key_path = "HKCU\\Software\\" + app_name + "\\" + k + + c = ["reg", "add", key_path, "/f"] + logging.debug("running: %s", c) + subprocess.run(c, check=True, shell=True) + + c = ["reg", "delete", key_path, "/f"] + logging.debug("running: %s", c) + subprocess.run(c, check=True, shell=True) + + assert done.wait(timeout=0.2) + assert not bad.wait(timeout=0.2) + with lock: + assert found_keys == test_keys + + +def key_exists(k: str) -> bool: + try: + subprocess.run(["reg", "query", k], shell=True, check=True) + except subprocess.CalledProcessError: + return False + else: + return True + + +@pytest.mark.parametrize("install", [False, True]) +def test_proc_deny(*, ef_handle: EaseFilter, install: bool): + """Test denying access to a key via rule.""" + app_name = "EasefilterPython" + + rule = RegistryProcNameRule( + f"*\\{app_name}\\*", + functools.reduce(operator.ior, RegCallbackClass), + proc_name=Path(f"{os.environ['WINDIR']}\\system32\\reg.exe"), + access_flag=RegControlFlag.REG_MAX_ACCESS_FLAG + & ~RegControlFlag.REG_ALLOW_OPEN_KEY, + ) + + with ef_handle as ef: + ef.message_callback = lambda _: None + + ef.set_filter_type(FilterType.REGISTRY) + rule.install(ef) + + if not install: + rule.uninstall(ef) + + with ( + winreg.OpenKeyEx(winreg.HKEY_CURRENT_USER, "Software\\") as soft_key, + winreg.CreateKey(soft_key, app_name + "\\"), + ): + k = "static_deny_key" + key_path = "HKCU\\Software\\" + app_name + "\\" + k + + c = ["reg", "add", key_path, "/f"] + logging.debug("running: %s", c) + subprocess.run(c, check=True, shell=True) + exists = key_exists(key_path) + assert exists != install + if exists: + c = ["reg", "delete", key_path, "/f"] + logging.debug("running: %s", c) + subprocess.run(c, check=True, shell=True) + + +def test_proc_dynamic_deny(*, ef_handle: EaseFilter): + """Test denying access to a key via callback.""" + deny_list = {"deny_1", "deny_👍🐸"} + key_list = {"allow_1", "allow_👍🐸", *deny_list} + + app_name = "EasefilterPython" + rule = RegistryProcNameRule( + f"*\\{app_name}\\*", + functools.reduce(operator.ior, RegCallbackClass), + proc_name=Path(f"{os.environ['WINDIR']}\\system32\\reg.exe"), + ) + + def msg_hook(ev: BaseEvent) -> DenyReply | None: + if not isinstance(ev, RegistryEvent): + logging.warning("spurious event %s", ev) + return None + + if ev.key_name.strip(":").split("\\")[-1] in deny_list: + return DenyReply() + + return None + + with ef_handle as ef: + ef.message_callback = msg_hook + ef.set_filter_type(FilterType.REGISTRY) + rule.install(ef) + + with ( + winreg.OpenKeyEx(winreg.HKEY_CURRENT_USER, "Software\\") as soft_key, + winreg.CreateKey(soft_key, app_name + "\\"), + ): + for k in key_list: + key_path = "HKCU\\Software\\" + app_name + "\\" + k + + c = ["reg", "add", key_path, "/f"] + logging.debug("running: %s", c) + subprocess.run(c, check=True, shell=True) + + exists = key_exists(key_path) + assert exists == (k not in deny_list) + if exists: + c = ["reg", "delete", key_path, "/f"] + logging.debug("running: %s", c) + subprocess.run(c, check=True, shell=True) diff --git a/Demo_Source_Code/ReadMe.txt b/Demo_Source_Code/ReadMe.txt new file mode 100644 index 0000000..26aca6d --- /dev/null +++ b/Demo_Source_Code/ReadMe.txt @@ -0,0 +1,71 @@ +EaseFilter File System Filter Driver SDK ReadMe + +Known Issues: +1. The transparent encryption doesn't support the earlier office 97-2003 version real time encryption. +2. The transparent encryption doesn't support the Database real time encryption. +3. To install the driver in Windows 7/8/8.1/2008R2/2012/2012R2, the KB3033929 is required. + +What can yo do with EaseFilter SDK? +1. The File Monitor Filter Driver allows you to monitor the file I/O activities, get the notification when the file was changed. +2. The File Control Filter Driver allows you to control the file access, modify the file I/O data. +3. The File Encryption Filter Driver allows you to encrypt or decrypt the files transparently. +4. The Process Filter Driver allows you to get the notification when the process was created or terminated, prevent untrusted process from being launching. +5. The Registry Filter Driver allows you to monitor the registry access, block the registry change by the unauthorized processes. + +How to use EaseFilter SDK? + +The EaseFilter SDK includes two components (EaseFlt.sys and FilterAPI.dll), The EaseFlt.sys and FilterAPI.dll are different for 32bit and 64bit windows system. +EaseFlt.sys is the file system filter driver which implements all the functionalities in the file system level. +FilterAPI.dll is a wrapper DLL which exports the API to the user mode applications. +The right platform(32bit or 64bit) EaseFlt.sys and FilterAPI.dll have to be copied to the same folder of your application.. + +For C++ application: +Copy FilterAPI.h and FilterAPI.lib to your application folder, add "FilterAPI.h" to your C++ project, include "FilterAPI.lib" to your project. +We provide a C++ example project "EaseFltCPPDemo" for your reference, it demostrates how to use EaseFilter SDK in C++. + +For C# application: +You need to add the reference "FilterControl" to your project. Include the namespace "EaseFilter.FilterControl" in your project files to use the FilterAPI interface. + +Below are some c# projects to demostrate the EaseFilter SDK used cases in different scenarios: + +1.FileMonitorConsole +This is simple console application to demostrate how to use the File Monitor Filter Driver SDK. For more funtionalities you can reference the GUI demo project "FileMonitor". + +2.FileProtectorConsole +This is simple console application to demostrate how to use the File Control Filter Driver SDK. For more funtionalities you can reference the GUI demo project "FileProtector". + +3. EaseFltCSConsoleDemo +This is a simple C# console project to demostrate how to use File Monitor and Control Filter Driver SDK, how to run as Windows service. + +4. AutoEncryptDemo.exe +This is a simple encryption demo project. You can create an auto encryption folder in computer A, all new created files in this folder will be encrypted. You can setup the authorized +processes or users who can decrypt the encrypted files in computer A. The encrypted files can be copied or transferred to the other computer B, to keep the files encrypted, +make sure the copy or transfer application was not included in the authorized process list, or you will copy the decrypted files instead of the encrypted files. You can create +an auto decryption folder in computer B, you can copy the encrypted files to this folder, the files are still kept encrypted in the disk, you can setup the authorized processes +or users who can decrypt the encrypted files in computer B. + +5. AutoFileCryptTool.exe +This is another encryption demo project with more settings to create multiple encryption folders with auhorized or unauthorized processes or users setting. + +6. FileMonitor.exe +This project demostrates how to monitor the file I/Os in real time, track the file access and file change. + +7. FileProtector.exe +This project demostrates how to monitor the file I/Os, allow or deny the file access to the specific folders, authorized the users or processes to access the sensitive files in the folder. + +8. SecureShare.exe +This project demostrates how to share the encrypted file with embedded digital rights, you can grant or revoke your shared files at anytime and anywhere, and track who and when your shared files were accessed. + +9. FolderLocker.exe +This project demostrates how to prevent your files being read/written/deleted/renamed in protected folders , it also allow you to encrypt the files, hide the files in the folder, secure file sharing. + +10. RegMon.exe +This project demostrates how to track the registry access activities, to know who query the registry key/value, to protect your registry key being modified or deleted. + +11. ProcessMon.exe +This project demostrates how to track the process creation or termination, prevent the suspicious executable binaries( malware) from launching. + +12. SecureSandbox.exe +This project demostrate how to create a sandbox folder, prevent the suspicious executable binaries( malware) from launching inside the sandbox, protect the files inside the sandbox, prevent the files from being read or written. + + diff --git a/FileMonitor.exe b/FileMonitor.exe index 74f4c5a..b34b3cd 100644 Binary files a/FileMonitor.exe and b/FileMonitor.exe differ diff --git a/FileProtector.exe b/FileProtector.exe index f9e3c42..b69c73f 100644 Binary files a/FileProtector.exe and b/FileProtector.exe differ diff --git a/FilterControl.dll b/FilterControl.dll index 5c8c3d4..74c6d3d 100644 Binary files a/FilterControl.dll and b/FilterControl.dll differ diff --git a/FolderLocker.exe b/FolderLocker.exe index 92cccde..5e95c68 100644 Binary files a/FolderLocker.exe and b/FolderLocker.exe differ diff --git a/ProcessMon.exe b/ProcessMon.exe index f208eb6..6f238dc 100644 Binary files a/ProcessMon.exe and b/ProcessMon.exe differ diff --git a/ReadMe.txt b/ReadMe.txt index e8ebb76..26aca6d 100644 --- a/ReadMe.txt +++ b/ReadMe.txt @@ -14,8 +14,10 @@ What can yo do with EaseFilter SDK? How to use EaseFilter SDK? -The EaseFilter SDK includes two components (EaseFlt.sys and FilterAPI.dll), The EaseFlt.sys and FilterAPI.dll are different for 32bit and 64bit windows system. EaseFlt.sys is the file system filter driver which implements all the functionalities in the file system level. FilterAPI.dll is a wrapper DLL which exports the API to the user mode applications. -You need to copy the right version of these two files to the folder of your application based on your OS platform. +The EaseFilter SDK includes two components (EaseFlt.sys and FilterAPI.dll), The EaseFlt.sys and FilterAPI.dll are different for 32bit and 64bit windows system. +EaseFlt.sys is the file system filter driver which implements all the functionalities in the file system level. +FilterAPI.dll is a wrapper DLL which exports the API to the user mode applications. +The right platform(32bit or 64bit) EaseFlt.sys and FilterAPI.dll have to be copied to the same folder of your application.. For C++ application: Copy FilterAPI.h and FilterAPI.lib to your application folder, add "FilterAPI.h" to your C++ project, include "FilterAPI.lib" to your project. @@ -26,38 +28,44 @@ You need to add the reference "FilterControl" to your project. Include the names Below are some c# projects to demostrate the EaseFilter SDK used cases in different scenarios: -1. AutoEncryptDemo.exe +1.FileMonitorConsole +This is simple console application to demostrate how to use the File Monitor Filter Driver SDK. For more funtionalities you can reference the GUI demo project "FileMonitor". + +2.FileProtectorConsole +This is simple console application to demostrate how to use the File Control Filter Driver SDK. For more funtionalities you can reference the GUI demo project "FileProtector". + +3. EaseFltCSConsoleDemo +This is a simple C# console project to demostrate how to use File Monitor and Control Filter Driver SDK, how to run as Windows service. + +4. AutoEncryptDemo.exe This is a simple encryption demo project. You can create an auto encryption folder in computer A, all new created files in this folder will be encrypted. You can setup the authorized processes or users who can decrypt the encrypted files in computer A. The encrypted files can be copied or transferred to the other computer B, to keep the files encrypted, make sure the copy or transfer application was not included in the authorized process list, or you will copy the decrypted files instead of the encrypted files. You can create an auto decryption folder in computer B, you can copy the encrypted files to this folder, the files are still kept encrypted in the disk, you can setup the authorized processes or users who can decrypt the encrypted files in computer B. -2. AutoFileCryptTool.exe +5. AutoFileCryptTool.exe This is another encryption demo project with more settings to create multiple encryption folders with auhorized or unauthorized processes or users setting. -3. FileMonitor.exe +6. FileMonitor.exe This project demostrates how to monitor the file I/Os in real time, track the file access and file change. -4. FileProtector.exe +7. FileProtector.exe This project demostrates how to monitor the file I/Os, allow or deny the file access to the specific folders, authorized the users or processes to access the sensitive files in the folder. -5. SecureShare.exe +8. SecureShare.exe This project demostrates how to share the encrypted file with embedded digital rights, you can grant or revoke your shared files at anytime and anywhere, and track who and when your shared files were accessed. -6. FolderLocker.exe +9. FolderLocker.exe This project demostrates how to prevent your files being read/written/deleted/renamed in protected folders , it also allow you to encrypt the files, hide the files in the folder, secure file sharing. -7. RegMon.exe +10. RegMon.exe This project demostrates how to track the registry access activities, to know who query the registry key/value, to protect your registry key being modified or deleted. -8. ProcessMon.exe +11. ProcessMon.exe This project demostrates how to track the process creation or termination, prevent the suspicious executable binaries( malware) from launching. -9. SecureSandbox.exe +12. SecureSandbox.exe This project demostrate how to create a sandbox folder, prevent the suspicious executable binaries( malware) from launching inside the sandbox, protect the files inside the sandbox, prevent the files from being read or written. -10. EaseFltCSConsoleDemo.exe -This is a simple C# console project to demostrate how to use EaseFilter SDK. - diff --git a/RegMon.exe b/RegMon.exe index 2ac0304..25f8bdc 100644 Binary files a/RegMon.exe and b/RegMon.exe differ diff --git a/SecureSandbox.exe b/SecureSandbox.exe index 916ada0..ba0a443 100644 Binary files a/SecureSandbox.exe and b/SecureSandbox.exe differ diff --git a/SecureShare.exe b/SecureShare.exe index 76910f0..6f034b3 100644 Binary files a/SecureShare.exe and b/SecureShare.exe differ