From 07245774db5cd3571650d9bcb3b68668283aee8f Mon Sep 17 00:00:00 2001 From: Anonymous Coward Date: Wed, 21 Aug 2013 18:37:28 +0200 Subject: [PATCH 1/4] Feature: Export index as ADC (Advanced Direct Connect) XML filelist, with optional LZ4 compression. Did not test compilation against MinGW. See sample autohotkey script for usage. --- FileSearch/CDriveIndex.cpp | 203 ++- FileSearch/CDriveIndex.h | 27 +- FileSearch/FileSearch.def | 3 +- FileSearch/FileSearch.vcxproj | 23 +- FileSearch/FileSearch.vcxproj.filters | 18 + FileSearch/FileSearch.vcxproj.user | 22 +- FileSearch/gel.cpp | 29 + FileSearch/lz4.c | 819 ++++++++++ FileSearch/lz4.h | 206 +++ FileSearch/stxutif.h | 58 + FileSearch/tinyxml2.cpp | 2101 +++++++++++++++++++++++++ FileSearch/tinyxml2.h | 1987 +++++++++++++++++++++++ Release/Exportall.ahk | 131 ++ Release/FileSearch.dll | Bin 70656 -> 111616 bytes x64/Release/FileSearch.dll | Bin 86016 -> 142848 bytes 15 files changed, 5605 insertions(+), 22 deletions(-) create mode 100644 FileSearch/gel.cpp create mode 100644 FileSearch/lz4.c create mode 100644 FileSearch/lz4.h create mode 100644 FileSearch/stxutif.h create mode 100644 FileSearch/tinyxml2.cpp create mode 100644 FileSearch/tinyxml2.h create mode 100644 Release/Exportall.ahk diff --git a/FileSearch/CDriveIndex.cpp b/FileSearch/CDriveIndex.cpp index fadde0b..de31eb0 100644 --- a/FileSearch/CDriveIndex.cpp +++ b/FileSearch/CDriveIndex.cpp @@ -7,9 +7,37 @@ Credits for original code this is based on: Jeffrey Cooperstein & Jeffrey Richte #include "stdafx.h" #include "CDriveIndex.h" #include +#include +#include #include #include +#include +#include "lz4.h" + +#include "stxutif.h" +using namespace gel; + +using namespace tinyxml2; + +namespace { +template +T swap_endian(T u) +{ + union + { + T u; + unsigned char u8[sizeof(T)]; + } source, dest; + + source.u = u; + + for (size_t k = 0; k < sizeof(T); k++) + dest.u8[k] = source.u8[sizeof(T) - k - 1]; + + return dest.u; +} +}; // Exported function to create the index of a drive @@ -30,6 +58,162 @@ void _stdcall DeleteIndex(CDriveIndex *di) delete di; } +void CDriveIndex::attach(vector &dirHandles, unordered_map::size_type> &umDirFrnToHandle, int NodeType, DWORDLONG Index) const +{ + if (umDirFrnToHandle.find(Index) != umDirFrnToHandle.end()) { // already processed? + return; + } + + USNEntry file = FRNToName(Index); + if (file.ParentIndex == 0) { // No upper directory + return; + } + if(!(file.ParentIndex == 0 && file.Name.length() == 2 && file.Name[1] == wchar_t(L':'))) // to exclude drive itself + { + SearchResultFile srf; + srf.Filename = file.Name; + srf.Path.reserve(MAX_PATH); + // Obtain path into buffer, and split it + Get(Index, &srf.Path); + if(srf.Path.length() < 3) { + return; + } + + WCHAR szDrive[_MAX_DRIVE]; + WCHAR szPath[_MAX_PATH]; + WCHAR szName[_MAX_FNAME]; + WCHAR szExt[_MAX_EXT]; + _wsplitpath(srf.Path.c_str(), szDrive, szPath, szName, szExt); + + // Skip metadata files and other special directories + int compareCount = sizeof(L"$RECYCLE.BIN") / sizeof(WCHAR) - 1; + if (*szDrive == wchar_t(0) || srf.Path.compare(3, compareCount, L"$RECYCLE.BIN", compareCount) == 0) { + return; + } + + unordered_map::size_type>::const_iterator it(umDirFrnToHandle.find(file.ParentIndex)); + if (it == umDirFrnToHandle.end()) { + attach(dirHandles, umDirFrnToHandle, IN_DIRECTORIES, file.ParentIndex); + } + it = umDirFrnToHandle.find(file.ParentIndex); + if (it == umDirFrnToHandle.end()) { + return; // unexpected + } + XMLHandle parentHandle(dirHandles[it->second]); + + XMLNode * parent = parentHandle.ToNode(); + if (!parent) { + return; + } + + XMLElement * element = parent->GetDocument()->NewElement( (NodeType == IN_DIRECTORIES) ? "Directory" : "File" ); + element->SetAttribute("Name", stdx::wstring_to_utf8(file.Name).c_str()); + + if (NodeType == IN_DIRECTORIES) { + vector::iterator insertedIt(dirHandles.insert(dirHandles.end(), XMLHandle(element))); + umDirFrnToHandle[Index] = insertedIt - dirHandles.begin(); + } + else { + HANDLE hFile = CreateFile( srf.Path.c_str(), 0, + FILE_SHARE_READ, 0, OPEN_EXISTING, + FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, 0 ); + if (hFile != INVALID_HANDLE_VALUE) { + BY_HANDLE_FILE_INFORMATION FileInfo = {0}; + GetFileInformationByHandle(hFile, &FileInfo); + if (!(FileInfo.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) { + ULARGE_INTEGER filesize = {FileInfo.nFileSizeLow, FileInfo.nFileSizeHigh}; + element->SetAttribute("Size", std::to_string(DWORDLONG(filesize.QuadPart)).c_str());; + } + CloseHandle(hFile); + } + } + + parent->InsertEndChild(element); + } +} + + +// Exports database to an exchange format. +// format is ignored for now, pass 0 for the default format. +// returns number of processed entries and 0 if an error occured. +BOOL CDriveIndex::ExportToFileListing(wstring &strPath, int format) const +{ + if (format < ExportFormat::ExportFormatAdcXml || format > ExportFormat::ExportFormatAdcXml_LZ4) { + return FALSE; + } + vector results; + XMLDocument doc; + XMLPrinter printer; + __time64_t tm; + CHAR tmbuf[200]; + + _time64(&tm); + strftime(tmbuf, sizeof(tmbuf) / sizeof(tmbuf[0]), "%Y-%m-%dT%H:%M:%SZ", _gmtime64(&tm)); + + stringstream emptyxml; + emptyxml << + "\n" + ""; + + XMLError err = doc.Parse(emptyxml.str().c_str()); + if (err != XML_SUCCESS) { + return false; + } + XMLHandle docHandle( &doc ); + + vector dirHandles; + dirHandles.reserve(rgDirectories.size()); + unordered_map::size_type> umDirFrnToHandle; + + vector::iterator insertedIt(dirHandles.insert(dirHandles.end(), XMLHandle(docHandle.FirstChildElement()))); + umDirFrnToHandle[m_dwDriveFRN] = insertedIt - dirHandles.begin(); + + for(unsigned int j = 0; j != rgDirectories.size(); j++) { + const IndexedDirectory* i = &rgDirectories[j]; + attach(dirHandles, umDirFrnToHandle, IN_DIRECTORIES, i->Index); + } + for(unsigned int j = 0; j != rgFiles.size(); j++) { + const IndexedFile* i = &rgFiles[j]; + attach(dirHandles, umDirFrnToHandle, IN_FILES, i->Index); + } + doc.Print( &printer ); + + std::ofstream file; // closes at end of scope + file.open(strPath.c_str(), ios::out|ios::binary|ios::trunc); + if (file.is_open()) + { + if (format == ExportFormat::ExportFormatAdcXml) { + file.write(printer.CStr(), printer.CStrSize()); + return file.good(); + } + else if (format == ExportFormat::ExportFormatAdcXml_LZ4) { + int const uncompressed_size = printer.CStrSize(); + int max_compressed_size = LZ4_compressBound( uncompressed_size ); + std::unique_ptr compressed( new char[max_compressed_size] ); + int const compressed_size = LZ4_compress( printer.CStr(), compressed.get(), uncompressed_size ); + int const final_compressed_size = ( compressed_size >= uncompressed_size ) ? uncompressed_size : compressed_size; + +#if defined(BIG_ENDIAN) + int value; + value = swap_endian(uncompressed_size); file.write(reinterpret_cast(&value), sizeof(int)); + value = swap_endian(final_compressed_size); file.write(reinterpret_cast(&value), sizeof(int)); +#else + file.write(reinterpret_cast(&uncompressed_size), sizeof(int)); + file.write(reinterpret_cast(&final_compressed_size), sizeof(int)); +#endif + file.write(( compressed_size >= uncompressed_size ) ? printer.CStr() : compressed.get(), final_compressed_size); + + return true; + } + } + + + return false; +} // Exported function to search in the index of a drive. @@ -97,6 +281,13 @@ void _stdcall GetDriveInfo(CDriveIndex *di, DriveInfo *driveInfo) +BOOL _stdcall ExportIndex(CDriveIndex *di, WCHAR *szPath, int format) +{ + if(dynamic_cast(di) && szPath) + return di->ExportToFileListing(wstring(szPath), format); + return false; +} + // Constructor CDriveIndex::CDriveIndex() { @@ -150,7 +341,7 @@ BOOL CDriveIndex::Create(DWORDLONG MaximumSize, DWORDLONG AllocationDelta) } // Return statistics about the journal on the current volume -BOOL CDriveIndex::Query(PUSN_JOURNAL_DATA pUsnJournalData) +BOOL CDriveIndex::Query(PUSN_JOURNAL_DATA pUsnJournalData) const { DWORD cb; BOOL fOk = DeviceIoControl(m_hVol, FSCTL_QUERY_USN_JOURNAL, NULL, 0, @@ -718,7 +909,7 @@ BOOL CDriveIndex::Empty() // Constructs a path for a file -BOOL CDriveIndex::Get(DWORDLONG Index, wstring *sz) +BOOL CDriveIndex::Get(DWORDLONG Index, wstring *sz) const { *sz = TEXT(""); int n = 0; @@ -734,7 +925,7 @@ BOOL CDriveIndex::Get(DWORDLONG Index, wstring *sz) // Constructs a path for a directory -BOOL CDriveIndex::GetDir(DWORDLONG Index, wstring *sz) +BOOL CDriveIndex::GetDir(DWORDLONG Index, wstring *sz) const { *sz = TEXT(""); do { @@ -935,7 +1126,7 @@ void CDriveIndex::PopulateIndex() } // Resolve FRN to filename by enumerating USN journal with StartFileReferenceNumber=FRN -USNEntry CDriveIndex::FRNToName(DWORDLONG FRN) +USNEntry CDriveIndex::FRNToName(DWORDLONG FRN) const { if(FRN == m_dwDriveFRN) return USNEntry(wstring(1, m_cDrive) + wstring(TEXT(":")), 0); @@ -966,7 +1157,7 @@ USNEntry CDriveIndex::FRNToName(DWORDLONG FRN) // Saves the database to disk. The file can be used to create an instance of CDriveIndex. -BOOL CDriveIndex::SaveToDisk(wstring &strPath) +BOOL CDriveIndex::SaveToDisk(wstring &strPath) const { ofstream::pos_type size; ofstream file (strPath.c_str(), ios::out|ios::binary|ios::trunc); @@ -1051,7 +1242,7 @@ CDriveIndex::CDriveIndex(wstring &strPath) // Returns the number of files and folders on this drive -DriveInfo CDriveIndex::GetInfo() +DriveInfo CDriveIndex::GetInfo() const { DriveInfo di; di.NumFiles = (DWORDLONG) rgFiles.size(); diff --git a/FileSearch/CDriveIndex.h b/FileSearch/CDriveIndex.h index 740e49e..1e3454b 100644 --- a/FileSearch/CDriveIndex.h +++ b/FileSearch/CDriveIndex.h @@ -12,7 +12,9 @@ Credits for original code this is based on: Jeffrey Cooperstein & Jeffrey Richte #include #include #include -#include +#include +#include "tinyxml2.h" + using namespace std; #define NO_WHERE 0 @@ -133,6 +135,9 @@ struct SearchResult } }; class CDriveIndex { +public: + enum ExportFormat {ExportFormatAdcXml, ExportFormatAdcXml_LZ4}; + public: CDriveIndex(); CDriveIndex(wstring &strPath); @@ -140,29 +145,31 @@ class CDriveIndex { BOOL Init(WCHAR cDrive); int Find(wstring *strQuery, wstring *strPath, vector *rgsrfResults, BOOL bSort = true, BOOL bEnhancedSearch = true, int maxResults = -1); void PopulateIndex(); - BOOL SaveToDisk(wstring &strPath); - DriveInfo GetInfo(); + BOOL SaveToDisk(wstring &strPath) const; + BOOL ExportToFileListing(wstring &strPath, int format) const; + DriveInfo GetInfo() const; protected: BOOL Empty(); HANDLE Open(WCHAR cDriveLetter, DWORD dwAccess); BOOL Create(DWORDLONG MaximumSize, DWORDLONG AllocationDelta); - BOOL Query(PUSN_JOURNAL_DATA pUsnJournalData); + BOOL Query(PUSN_JOURNAL_DATA pUsnJournalData) const; void FindRecursively(wstring &strQuery, const WCHAR* &szQueryLower, DWORDLONG QueryFilter, DWORDLONG QueryLength, wstring * strQueryPath, vector &rgsrfResults, BOOL bEnhancedSearch, int maxResults, int &nResults); template void FindInJournal(wstring &strQuery, const WCHAR* &szQueryLower, DWORDLONG QueryFilter, DWORDLONG QueryLength, wstring * strQueryPath, vector &rgJournalIndex, vector &rgsrfResults, unsigned int iOffset, BOOL bEnhancedSearch, int maxResults, int &nResults); void FindInPreviousResults(wstring &strQuery, const WCHAR* &szQueryLower, DWORDLONG QueryFilter, DWORDLONG QueryLength, wstring * strQueryPath, vector &rgsrfResults, unsigned int iOffset, BOOL bEnhancedSearch, int maxResults, int &nResults); + void attach(vector &dirHandles, unordered_map::size_type> &umDirFrnToHandle, int NodeType, DWORDLONG Index) const; INT64 FindOffsetByIndex(DWORDLONG Index); INT64 FindDirOffsetByIndex(DWORDLONG Index); DWORDLONG MakeFilter(wstring *szName); - USNEntry FRNToName(DWORDLONG FRN); + USNEntry FRNToName(DWORDLONG FRN) const; void CleanUp(); BOOL Add(DWORDLONG Index, wstring *szName, DWORDLONG ParentIndex, DWORDLONG Address = 0); BOOL AddDir(DWORDLONG Index, wstring *szName, DWORDLONG ParentIndex, DWORDLONG Address = 0); - BOOL Get(DWORDLONG Index, wstring *sz); - BOOL GetDir(DWORDLONG Index, wstring *sz); - unsigned int GetParentDirectory(DWORDLONG Index); + BOOL Get(DWORDLONG Index, wstring *sz) const; + BOOL GetDir(DWORDLONG Index, wstring *sz) const; + //unsigned int GetParentDirectory(DWORDLONG Index); void ClearLastResult(); // Members used to enumerate journal records HANDLE m_hVol; // handle to volume @@ -184,4 +191,6 @@ WCHAR* _stdcall Search(CDriveIndex *di, WCHAR *szQuery, WCHAR *szPath, BOOL bSor void _stdcall FreeResultsBuffer(WCHAR *szResults); BOOL _stdcall SaveIndexToDisk(CDriveIndex *di, WCHAR *szPath); CDriveIndex* _stdcall LoadIndexFromDisk(WCHAR *szPath); -void _stdcall GetDriveInfo(CDriveIndex *di, DriveInfo *driveInfo); \ No newline at end of file +void _stdcall GetDriveInfo(CDriveIndex *di, DriveInfo *driveInfo); +BOOL _stdcall SaveIndexToDisk(CDriveIndex *di, WCHAR *szPath); +BOOL _stdcall ExportIndex(CDriveIndex *di, WCHAR *szPath, int format); diff --git a/FileSearch/FileSearch.def b/FileSearch/FileSearch.def index 5f2f91d..e612086 100644 --- a/FileSearch/FileSearch.def +++ b/FileSearch/FileSearch.def @@ -7,4 +7,5 @@ EXPORTS FreeResultsBuffer @4 LoadIndexFromDisk @5 SaveIndexToDisk @6 - GetDriveInfo @7 \ No newline at end of file + GetDriveInfo @7 + ExportIndex @8 \ No newline at end of file diff --git a/FileSearch/FileSearch.vcxproj b/FileSearch/FileSearch.vcxproj index cae9dbb..8157908 100644 --- a/FileSearch/FileSearch.vcxproj +++ b/FileSearch/FileSearch.vcxproj @@ -144,8 +144,11 @@ + + + @@ -163,12 +166,30 @@ + + NotUsing + NotUsing + NotUsing + NotUsing + + + NotUsing + NotUsing + NotUsing + NotUsing + Create - Create Create + Create Create + + NotUsing + NotUsing + NotUsing + NotUsing + diff --git a/FileSearch/FileSearch.vcxproj.filters b/FileSearch/FileSearch.vcxproj.filters index a3bc8e4..00fe964 100644 --- a/FileSearch/FileSearch.vcxproj.filters +++ b/FileSearch/FileSearch.vcxproj.filters @@ -30,6 +30,15 @@ Headerdateien + + Headerdateien + + + Headerdateien + + + Headerdateien + @@ -41,5 +50,14 @@ Quelldateien + + Quelldateien + + + Quelldateien + + + Quelldateien + \ No newline at end of file diff --git a/FileSearch/FileSearch.vcxproj.user b/FileSearch/FileSearch.vcxproj.user index 1710a9f..9cd3b79 100644 --- a/FileSearch/FileSearch.vcxproj.user +++ b/FileSearch/FileSearch.vcxproj.user @@ -1,15 +1,27 @@  + + C:\Program Files (x86)\AutoHotkey\AutoHotkey.exe + WindowsLocalDebugger + $(OutDir)Exportall.ahk + $(OutDir) + - C:\Program Files\Autohotkey\Autohotkey.exe + C:\Program Files (x86)\AutoHotkey\AutoHotkey.exe WindowsLocalDebugger - $(OutDir)FileSearchTest.ahk + $(OutDir)Exportall.ahk $(OutDir) - - C:\Program Files\Autohotkey\AutoHotkey.exe + + C:\Program Files\AutoHotkey\AutoHotkey.exe + WindowsLocalDebugger + $(OutDir)Exportall.ahk + $(OutDir) + + + C:\Program Files\AutoHotkey\AutoHotkey.exe WindowsLocalDebugger - $(OutDir)FileSearchTest.ahk + $(OutDir)Exportall.ahk $(OutDir) \ No newline at end of file diff --git a/FileSearch/gel.cpp b/FileSearch/gel.cpp new file mode 100644 index 0000000..6374561 --- /dev/null +++ b/FileSearch/gel.cpp @@ -0,0 +1,29 @@ +#include "stxutif.h" +#include + +#ifdef __MINGW32_VERSION +#ifndef _GLIBCXX_USE_WCHAR_T + +namespace std +{ + //instantiate the codecvt facet id for the required types + locale::id codecvt::id; +} + +#endif //_GLIBCXX_USE_WCHAR_T +#endif //__MINGW32_VERSION + + +namespace gel +{namespace stdx +{ + //instantiate the global locale + std::locale utf8_locale(std::locale(), new std::codecvt_utf8()); // VS2010 and further + + // convert wstring to UTF-8 string + std::string wstring_to_utf8 (const std::wstring& str) { + std::wstring_convert> myconv; + return myconv.to_bytes(str); + } + +}} diff --git a/FileSearch/lz4.c b/FileSearch/lz4.c new file mode 100644 index 0000000..7fef165 --- /dev/null +++ b/FileSearch/lz4.c @@ -0,0 +1,819 @@ +/* + LZ4 - Fast LZ compression algorithm + Copyright (C) 2011-2013, Yann Collet. + BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following disclaimer + in the documentation and/or other materials provided with the + distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + You can contact the author at : + - LZ4 homepage : http://fastcompression.blogspot.com/p/lz4.html + - LZ4 source repository : http://code.google.com/p/lz4/ +*/ + +//************************************** +// Tuning parameters +//************************************** +// MEMORY_USAGE : +// Memory usage formula : N->2^N Bytes (examples : 10 -> 1KB; 12 -> 4KB ; 16 -> 64KB; 20 -> 1MB; etc.) +// Increasing memory usage improves compression ratio +// Reduced memory usage can improve speed, due to cache effect +// Default value is 14, for 16KB, which nicely fits into Intel x86 L1 cache +#define MEMORY_USAGE 14 + +// HEAPMODE : +// Select how default compression functions will allocate memory for their hash table, +// in memory stack (0:default, fastest), or in memory heap (1:requires memory allocation (malloc)). +#define HEAPMODE 0 + + +//************************************** +// CPU Feature Detection +//************************************** +// 32 or 64 bits ? +#if (defined(__x86_64__) || defined(_M_X64) || defined(_WIN64) \ + || defined(__powerpc64__) || defined(__ppc64__) || defined(__PPC64__) \ + || defined(__64BIT__) || defined(_LP64) || defined(__LP64__) \ + || defined(__ia64) || defined(__itanium__) || defined(_M_IA64) ) // Detects 64 bits mode +# define LZ4_ARCH64 1 +#else +# define LZ4_ARCH64 0 +#endif + +// Little Endian or Big Endian ? +// Overwrite the #define below if you know your architecture endianess +#if defined (__GLIBC__) +# include +# if (__BYTE_ORDER == __BIG_ENDIAN) +# define LZ4_BIG_ENDIAN 1 +# endif +#elif (defined(__BIG_ENDIAN__) || defined(__BIG_ENDIAN) || defined(_BIG_ENDIAN)) && !(defined(__LITTLE_ENDIAN__) || defined(__LITTLE_ENDIAN) || defined(_LITTLE_ENDIAN)) +# define LZ4_BIG_ENDIAN 1 +#elif defined(__sparc) || defined(__sparc__) \ + || defined(__powerpc__) || defined(__ppc__) || defined(__PPC__) \ + || defined(__hpux) || defined(__hppa) \ + || defined(_MIPSEB) || defined(__s390__) +# define LZ4_BIG_ENDIAN 1 +#else +// Little Endian assumed. PDP Endian and other very rare endian format are unsupported. +#endif + +// Unaligned memory access is automatically enabled for "common" CPU, such as x86. +// For others CPU, such as ARM, the compiler may be more cautious, inserting unnecessary extra code to ensure aligned access property +// If you know your target CPU supports unaligned memory access, you want to force this option manually to improve performance +#if defined(__ARM_FEATURE_UNALIGNED) +# define LZ4_FORCE_UNALIGNED_ACCESS 1 +#endif + +// Define this parameter if your target system or compiler does not support hardware bit count +#if defined(_MSC_VER) && defined(_WIN32_WCE) // Visual Studio for Windows CE does not support Hardware bit count +# define LZ4_FORCE_SW_BITCOUNT +#endif + +// BIG_ENDIAN_NATIVE_BUT_INCOMPATIBLE : +// This option may provide a small boost to performance for some big endian cpu, although probably modest. +// You may set this option to 1 if data will remain within closed environment. +// This option is useless on Little_Endian CPU (such as x86) +//#define BIG_ENDIAN_NATIVE_BUT_INCOMPATIBLE 1 + + +//************************************** +// Compiler Options +//************************************** +#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) // C99 +/* "restrict" is a known keyword */ +#else +# define restrict // Disable restrict +#endif + +#ifdef _MSC_VER // Visual Studio +# define FORCE_INLINE static __forceinline +# include // For Visual 2005 +# if LZ4_ARCH64 // 64-bits +# pragma intrinsic(_BitScanForward64) // For Visual 2005 +# pragma intrinsic(_BitScanReverse64) // For Visual 2005 +# else // 32-bits +# pragma intrinsic(_BitScanForward) // For Visual 2005 +# pragma intrinsic(_BitScanReverse) // For Visual 2005 +# endif +# pragma warning(disable : 4127) // disable: C4127: conditional expression is constant +#else +# ifdef __GNUC__ +# define FORCE_INLINE static inline __attribute__((always_inline)) +# else +# define FORCE_INLINE static inline +# endif +#endif + +#ifdef _MSC_VER +# define lz4_bswap16(x) _byteswap_ushort(x) +#else +# define lz4_bswap16(x) ((unsigned short int) ((((x) >> 8) & 0xffu) | (((x) & 0xffu) << 8))) +#endif + +#define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) + +#if (GCC_VERSION >= 302) || (__INTEL_COMPILER >= 800) || defined(__clang__) +# define expect(expr,value) (__builtin_expect ((expr),(value)) ) +#else +# define expect(expr,value) (expr) +#endif + +#define likely(expr) expect((expr) != 0, 1) +#define unlikely(expr) expect((expr) != 0, 0) + + +//************************************** +// Memory routines +//************************************** +#include // malloc, calloc, free +#define ALLOCATOR(n,s) calloc(n,s) +#define FREEMEM free +#include // memset, memcpy +#define MEM_INIT memset + + +//************************************** +// Includes +//************************************** +#include "lz4.h" + + +//************************************** +// Basic Types +//************************************** +#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L // C99 +# include + typedef uint8_t BYTE; + typedef uint16_t U16; + typedef uint32_t U32; + typedef int32_t S32; + typedef uint64_t U64; +#else + typedef unsigned char BYTE; + typedef unsigned short U16; + typedef unsigned int U32; + typedef signed int S32; + typedef unsigned long long U64; +#endif + +typedef const BYTE* Ptr; + +#if defined(__GNUC__) && !defined(LZ4_FORCE_UNALIGNED_ACCESS) +# define _PACKED __attribute__ ((packed)) +#else +# define _PACKED +#endif + +#if !defined(LZ4_FORCE_UNALIGNED_ACCESS) && !defined(__GNUC__) +# ifdef __IBMC__ +# pragma pack(1) +# else +# pragma pack(push, 1) +# endif +#endif + +typedef struct { U16 v; } _PACKED U16_S; +typedef struct { U32 v; } _PACKED U32_S; +typedef struct { U64 v; } _PACKED U64_S; +typedef struct {size_t v;} _PACKED size_t_S; + +#if !defined(LZ4_FORCE_UNALIGNED_ACCESS) && !defined(__GNUC__) +# pragma pack(pop) +#endif + +#define A16(x) (((U16_S *)(x))->v) +#define A32(x) (((U32_S *)(x))->v) +#define A64(x) (((U64_S *)(x))->v) +#define AARCH(x) (((size_t_S *)(x))->v) + + +//************************************** +// Constants +//************************************** +#define LZ4_HASHLOG (MEMORY_USAGE-2) +#define HASHTABLESIZE (1 << MEMORY_USAGE) +#define HASHNBCELLS4 (1 << LZ4_HASHLOG) + +#define MINMATCH 4 + +#define COPYLENGTH 8 +#define LASTLITERALS 5 +#define MFLIMIT (COPYLENGTH+MINMATCH) +const int LZ4_minLength = (MFLIMIT+1); + +#define LZ4_64KLIMIT ((1<<16) + (MFLIMIT-1)) +#define SKIPSTRENGTH 6 // Increasing this value will make the compression run slower on incompressible data + +#define MAXD_LOG 16 +#define MAX_DISTANCE ((1 << MAXD_LOG) - 1) + +#define ML_BITS 4 +#define ML_MASK ((1U<=e; + + +//**************************** +// Private functions +//**************************** +#if LZ4_ARCH64 + +FORCE_INLINE int LZ4_NbCommonBytes (register U64 val) +{ +# if defined(LZ4_BIG_ENDIAN) +# if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT) + unsigned long r = 0; + _BitScanReverse64( &r, val ); + return (int)(r>>3); +# elif defined(__GNUC__) && (GCC_VERSION >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT) + return (__builtin_clzll(val) >> 3); +# else + int r; + if (!(val>>32)) { r=4; } else { r=0; val>>=32; } + if (!(val>>16)) { r+=2; val>>=8; } else { val>>=24; } + r += (!val); + return r; +# endif +# else +# if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT) + unsigned long r = 0; + _BitScanForward64( &r, val ); + return (int)(r>>3); +# elif defined(__GNUC__) && (GCC_VERSION >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT) + return (__builtin_ctzll(val) >> 3); +# else + static const int DeBruijnBytePos[64] = { 0, 0, 0, 0, 0, 1, 1, 2, 0, 3, 1, 3, 1, 4, 2, 7, 0, 2, 3, 6, 1, 5, 3, 5, 1, 3, 4, 4, 2, 5, 6, 7, 7, 0, 1, 2, 3, 3, 4, 6, 2, 6, 5, 5, 3, 4, 5, 6, 7, 1, 2, 4, 6, 4, 4, 5, 7, 2, 6, 5, 7, 6, 7, 7 }; + return DeBruijnBytePos[((U64)((val & -(long long)val) * 0x0218A392CDABBD3FULL)) >> 58]; +# endif +# endif +} + +#else + +FORCE_INLINE int LZ4_NbCommonBytes (register U32 val) +{ +# if defined(LZ4_BIG_ENDIAN) +# if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT) + unsigned long r = 0; + _BitScanReverse( &r, val ); + return (int)(r>>3); +# elif defined(__GNUC__) && (GCC_VERSION >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT) + return (__builtin_clz(val) >> 3); +# else + int r; + if (!(val>>16)) { r=2; val>>=8; } else { r=0; val>>=24; } + r += (!val); + return r; +# endif +# else +# if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT) + unsigned long r; + _BitScanForward( &r, val ); + return (int)(r>>3); +# elif defined(__GNUC__) && (GCC_VERSION >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT) + return (__builtin_ctz(val) >> 3); +# else + static const int DeBruijnBytePos[32] = { 0, 0, 3, 0, 3, 1, 3, 0, 3, 2, 2, 1, 3, 2, 0, 1, 3, 3, 1, 2, 2, 2, 2, 0, 3, 1, 2, 0, 1, 0, 1, 1 }; + return DeBruijnBytePos[((U32)((val & -(S32)val) * 0x077CB531U)) >> 27]; +# endif +# endif +} + +#endif + + +//**************************** +// Compression functions +//**************************** +FORCE_INLINE int LZ4_hashSequence(U32 sequence, tableType_t tableType) +{ + if (tableType == byU16) + return (((sequence) * 2654435761U) >> ((MINMATCH*8)-(LZ4_HASHLOG+1))); + else + return (((sequence) * 2654435761U) >> ((MINMATCH*8)-LZ4_HASHLOG)); +} + +FORCE_INLINE int LZ4_hashPosition(Ptr p, tableType_t tableType) { return LZ4_hashSequence(A32(p), tableType); } + +FORCE_INLINE void LZ4_putPositionOnHash(Ptr p, U32 h, void* tableBase, tableType_t tableType, Ptr srcBase) +{ + switch (tableType) + { + case byPtr: { Ptr* hashTable = (Ptr*) tableBase; hashTable[h] = p; break; } + case byU32: { U32* hashTable = (U32*) tableBase; hashTable[h] = p-srcBase; break; } + case byU16: { U16* hashTable = (U16*) tableBase; hashTable[h] = (U16)(p-srcBase); break; } + } +} + +FORCE_INLINE void LZ4_putPosition(Ptr p, void* tableBase, tableType_t tableType, Ptr srcBase) +{ + U32 h = LZ4_hashPosition(p, tableType); + LZ4_putPositionOnHash(p, h, tableBase, tableType, srcBase); +} + +FORCE_INLINE Ptr LZ4_getPositionOnHash(U32 h, void* tableBase, tableType_t tableType, Ptr srcBase) +{ + if (tableType == byPtr) { Ptr* hashTable = (Ptr*) tableBase; return hashTable[h]; } + if (tableType == byU32) { U32* hashTable = (U32*) tableBase; return hashTable[h] + srcBase; } + { U16* hashTable = (U16*) tableBase; return hashTable[h] + srcBase; } // default, to ensure a return +} + +FORCE_INLINE Ptr LZ4_getPosition(Ptr p, void* tableBase, tableType_t tableType, Ptr srcBase) +{ + U32 h = LZ4_hashPosition(p, tableType); + return LZ4_getPositionOnHash(h, tableBase, tableType, srcBase); +} + + +FORCE_INLINE int LZ4_compress_generic( + void* ctx, + const char* source, + char* dest, + int inputSize, + int maxOutputSize, + + limitedOutput_directive limitedOutput, + tableType_t tableType, + prefix64k_directive prefix) +{ + Ptr ip = (Ptr) source; + Ptr const base = (prefix==withPrefix) ? ((LZ4_Data_Structure*)ctx)->base : (Ptr) source; + Ptr const lowLimit = ((prefix==withPrefix) ? ((LZ4_Data_Structure*)ctx)->bufferStart : (Ptr)source); + Ptr anchor = (Ptr) source; + Ptr const iend = ip + inputSize; + Ptr const mflimit = iend - MFLIMIT; + Ptr const matchlimit = iend - LASTLITERALS; + + BYTE* op = (BYTE*) dest; + BYTE* const oend = op + maxOutputSize; + + int length; + const int skipStrength = SKIPSTRENGTH; + U32 forwardH; + + // Init conditions + if ((prefix==withPrefix) && (ip != ((LZ4_Data_Structure*)ctx)->nextBlock)) return 0; // must continue from end of previous block + if (prefix==withPrefix) ((LZ4_Data_Structure*)ctx)->nextBlock=iend; // do it now, due to potential early exit + if ((tableType == byU16) && (inputSize>=LZ4_64KLIMIT)) return 0; // Size too large (not within 64K limit) + if (inputSize> skipStrength; + ip = forwardIp; + forwardIp = ip + step; + + if unlikely(forwardIp > mflimit) { goto _last_literals; } + + forwardH = LZ4_hashPosition(forwardIp, tableType); + ref = LZ4_getPositionOnHash(h, ctx, tableType, base); + LZ4_putPositionOnHash(ip, h, ctx, tableType, base); + + } while ((ref + MAX_DISTANCE < ip) || (A32(ref) != A32(ip))); + + // Catch up + while ((ip>anchor) && (ref > lowLimit) && unlikely(ip[-1]==ref[-1])) { ip--; ref--; } + + // Encode Literal length + length = (int)(ip - anchor); + token = op++; + if ((limitedOutput) && unlikely(op + length + (2 + 1 + LASTLITERALS) + (length>>8) > oend)) return 0; // Check output limit + if (length>=(int)RUN_MASK) + { + int len = length-RUN_MASK; + *token=(RUN_MASK<= 255 ; len-=255) *op++ = 255; + *op++ = (BYTE)len; + } + else *token = (BYTE)(length<>8) > oend)) return 0; // Check output limit + if (length>=(int)ML_MASK) + { + *token += ML_MASK; + length -= ML_MASK; + for (; length > 509 ; length-=510) { *op++ = 255; *op++ = 255; } + if (length >= 255) { length-=255; *op++ = 255; } + *op++ = (BYTE)length; + } + else *token += (BYTE)(length); + + // Test end of chunk + if (ip > mflimit) { anchor = ip; break; } + + // Fill table + LZ4_putPosition(ip-2, ctx, tableType, base); + + // Test next position + ref = LZ4_getPosition(ip, ctx, tableType, base); + LZ4_putPosition(ip, ctx, tableType, base); + if ((ref + MAX_DISTANCE >= ip) && (A32(ref) == A32(ip))) { token = op++; *token=0; goto _next_match; } + + // Prepare next loop + anchor = ip++; + forwardH = LZ4_hashPosition(ip, tableType); + } + +_last_literals: + // Encode Last Literals + { + int lastRun = (int)(iend - anchor); + if ((limitedOutput) && (((char*)op - dest) + lastRun + 1 + ((lastRun+255-RUN_MASK)/255) > (U32)maxOutputSize)) return 0; // Check output limit + if (lastRun>=(int)RUN_MASK) { *op++=(RUN_MASK<= 255 ; lastRun-=255) *op++ = 255; *op++ = (BYTE) lastRun; } + else *op++ = (BYTE)(lastRun<hashTable, 0, sizeof(lz4ds->hashTable)); + lz4ds->bufferStart = base; + lz4ds->base = base; + lz4ds->nextBlock = base; +} + + +void* LZ4_create (const char* inputBuffer) +{ + void* lz4ds = ALLOCATOR(1, sizeof(LZ4_Data_Structure)); + LZ4_init ((LZ4_Data_Structure*)lz4ds, (Ptr)inputBuffer); + return lz4ds; +} + + +int LZ4_free (void* LZ4_Data) +{ + FREEMEM(LZ4_Data); + return (0); +} + + +char* LZ4_slideInputBuffer (void* LZ4_Data) +{ + LZ4_Data_Structure* lz4ds = (LZ4_Data_Structure*)LZ4_Data; + size_t delta = lz4ds->nextBlock - (lz4ds->bufferStart + 64 KB); + + if(lz4ds->base - delta > lz4ds->base) // underflow control + { + size_t newBaseDelta = (lz4ds->nextBlock - 64 KB) - lz4ds->base; + int nH; + + for (nH=0; nH < HASHNBCELLS4; nH++) + { + if (lz4ds->hashTable[nH] < (U32)newBaseDelta) lz4ds->hashTable[nH] = 0; + else lz4ds->hashTable[nH] -= newBaseDelta; + } + lz4ds->base += newBaseDelta; + } + memcpy((void*)(lz4ds->bufferStart), (const void*)(lz4ds->nextBlock - 64 KB), 64 KB); + lz4ds->nextBlock -= delta; + lz4ds->base -= delta; + + return (char*)(lz4ds->nextBlock); +} + + +//**************************** +// Decompression functions +//**************************** + +// This generic decompression function cover all use cases. +// It shall be instanciated several times, using different sets of directives +// Note that it is essential this generic function is really inlined, +// in order to remove useless branches during compilation optimisation. +FORCE_INLINE int LZ4_decompress_generic( + const char* source, + char* dest, + int inputSize, // + int outputSize, // OutputSize must be != 0; if endOnInput==endOnInputSize, this value is the max size of Output Buffer. + + int endOnInput, // endOnOutputSize, endOnInputSize + int prefix64k, // noPrefix, withPrefix + int partialDecoding, // full, partial + int targetOutputSize // only used if partialDecoding==partial + ) +{ + // Local Variables + Ptr restrict ip = (Ptr) source; + Ptr ref; + Ptr const iend = ip + inputSize; + + BYTE* op = (BYTE*) dest; + BYTE* const oend = op + outputSize; + BYTE* cpy; + BYTE* oexit = op + targetOutputSize; + + size_t dec32table[] = {0, 3, 2, 3, 0, 0, 0, 0}; +#if LZ4_ARCH64 + size_t dec64table[] = {0, 0, 0, (size_t)-1, 0, 1, 2, 3}; +#endif + + + // Special cases + if ((partialDecoding) && (oexit> oend-MFLIMIT)) oexit = oend-MFLIMIT; // targetOutputSize too high => decode everything + if ((endOnInput) && unlikely(outputSize==0)) return ((inputSize==1) && (*ip==0)) ? 0 : -1; // Empty output buffer + if ((!endOnInput) && unlikely(outputSize==0)) return (*ip==0?1:-1); + + + // Main Loop + while (1) + { + unsigned token; + size_t length; + + // get runlength + token = *ip++; + if ((length=(token>>ML_BITS)) == RUN_MASK) + { + unsigned s=255; + while (((endOnInput)?ip(partialDecoding?oexit:oend-MFLIMIT)) || (ip+length>iend-(2+1+LASTLITERALS))) ) + || ((!endOnInput) && (cpy>oend-COPYLENGTH))) + { + if (partialDecoding) + { + if (cpy > oend) goto _output_error; // Error : write attempt beyond end of output buffer + if ((endOnInput) && (ip+length > iend)) goto _output_error; // Error : read attempt beyond end of input buffer + } + else + { + if ((!endOnInput) && (cpy != oend)) goto _output_error; // Error : block decoding must stop exactly there + if ((endOnInput) && ((ip+length != iend) || (cpy > oend))) goto _output_error; // Error : input must be consumed + } + memcpy(op, ip, length); + ip += length; + op += length; + break; // Necessarily EOF, due to parsing restrictions + } + LZ4_WILDCOPY(op, ip, cpy); ip -= (op-cpy); op = cpy; + + // get offset + LZ4_READ_LITTLEENDIAN_16(ref,cpy,ip); ip+=2; + if ((prefix64k==noPrefix) && unlikely(ref < (BYTE* const)dest)) goto _output_error; // Error : offset outside destination buffer + + // get matchlength + if ((length=(token&ML_MASK)) == ML_MASK) + { + while ((!endOnInput) || (ipoend-COPYLENGTH-(STEPSIZE-4)) + { + if (cpy > oend-LASTLITERALS) goto _output_error; // Error : last 5 bytes must be literals + LZ4_SECURECOPY(op, ref, (oend-COPYLENGTH)); + while(op The memory position where the next input data block must start is provided as the result of the function. + +Compression can then resume, using LZ4_compress_continue() or LZ4_compress_limitedOutput_continue(), as usual. + +When compression is completed, a call to LZ4_free() will release the memory used by the LZ4 Data Structure. +*/ + + +//**************************** +// Obsolete Functions +//**************************** + +static inline int LZ4_uncompress (const char* source, char* dest, int outputSize) { return LZ4_decompress_fast(source, dest, outputSize); } +static inline int LZ4_uncompress_unknownOutputSize (const char* source, char* dest, int isize, int maxOutputSize) { return LZ4_decompress_safe(source, dest, isize, maxOutputSize); } + +/* +These functions are deprecated and should no longer be used. +They are provided here for compatibility with existing user programs. +*/ + + + +#if defined (__cplusplus) +} +#endif diff --git a/FileSearch/stxutif.h b/FileSearch/stxutif.h new file mode 100644 index 0000000..4554f40 --- /dev/null +++ b/FileSearch/stxutif.h @@ -0,0 +1,58 @@ +#ifndef _UTIF_H_ +#define _UTIF_H_ 1 + +#include +#include +#include +#include + +#ifdef __MINGW32_VERSION +#ifndef _GLIBCXX_USE_WCHAR_T + +namespace std +{ + /// declare a coecvt between wchar_t and char + /*! + * If Mingw support for wchar_t is not activated, the following declarations are + * required to properly let the code to be translatable + */ + template<> + class codecvt: + public __codecvt_abstract_base + { + protected: + explicit codecvt(size_t refs=0) + :__codecvt_abstract_base(refs) + {} + public: + static locale::id id; + }; + + // wide types for char dependent templates + typedef basic_ios wios; + typedef basic_streambuf wstreambuf; + typedef basic_istream wistream; + typedef basic_ostream wostream; + typedef basic_iostream wiostream; + typedef basic_stringbuf wstringbuf; + typedef basic_istringstream wistringstream; + typedef basic_ostringstream wostringstream; + typedef basic_stringstream wstringstream; + typedef basic_filebuf wfilebuf; + typedef basic_ifstream wifstream; + typedef basic_ofstream wofstream; + typedef basic_fstream wfstream; +} + +#endif //_GLIBCXX_USE_WCHAR_T +#endif //__MINGW32_VERSION + +namespace gel +{namespace stdx +{ + extern std::locale utf8_locale; ///< global locale with UTF-8 conversion capabilities. + + std::string wstring_to_utf8 (const std::wstring& str); +}} + +#endif diff --git a/FileSearch/tinyxml2.cpp b/FileSearch/tinyxml2.cpp new file mode 100644 index 0000000..7ec259e --- /dev/null +++ b/FileSearch/tinyxml2.cpp @@ -0,0 +1,2101 @@ +/* +Original code by Lee Thomason (www.grinninglizard.com) + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any +damages arising from the use of this software. + +Permission is granted to anyone to use this software for any +purpose, including commercial applications, and to alter it and +redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and +must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source +distribution. +*/ + +#include "tinyxml2.h" + +#include // yes, this one new style header, is in the Android SDK. +# ifdef ANDROID_NDK +# include +#else +# include +#endif + +static const char LINE_FEED = (char)0x0a; // all line endings are normalized to LF +static const char LF = LINE_FEED; +static const char CARRIAGE_RETURN = (char)0x0d; // CR gets filtered out +static const char CR = CARRIAGE_RETURN; +static const char SINGLE_QUOTE = '\''; +static const char DOUBLE_QUOTE = '\"'; + +// Bunch of unicode info at: +// http://www.unicode.org/faq/utf_bom.html +// ef bb bf (Microsoft "lead bytes") - designates UTF-8 + +static const unsigned char TIXML_UTF_LEAD_0 = 0xefU; +static const unsigned char TIXML_UTF_LEAD_1 = 0xbbU; +static const unsigned char TIXML_UTF_LEAD_2 = 0xbfU; + + +#define DELETE_NODE( node ) { \ + if ( node ) { \ + MemPool* pool = node->_memPool; \ + node->~XMLNode(); \ + pool->Free( node ); \ + } \ + } +#define DELETE_ATTRIBUTE( attrib ) { \ + if ( attrib ) { \ + MemPool* pool = attrib->_memPool; \ + attrib->~XMLAttribute(); \ + pool->Free( attrib ); \ + } \ + } + +namespace tinyxml2 +{ + +struct Entity { + const char* pattern; + int length; + char value; +}; + +static const int NUM_ENTITIES = 5; +static const Entity entities[NUM_ENTITIES] = { + { "quot", 4, DOUBLE_QUOTE }, + { "amp", 3, '&' }, + { "apos", 4, SINGLE_QUOTE }, + { "lt", 2, '<' }, + { "gt", 2, '>' } +}; + + +StrPair::~StrPair() +{ + Reset(); +} + + +void StrPair::Reset() +{ + if ( _flags & NEEDS_DELETE ) { + delete [] _start; + } + _flags = 0; + _start = 0; + _end = 0; +} + + +void StrPair::SetStr( const char* str, int flags ) +{ + Reset(); + size_t len = strlen( str ); + _start = new char[ len+1 ]; + memcpy( _start, str, len+1 ); + _end = _start + len; + _flags = flags | NEEDS_DELETE; +} + + +char* StrPair::ParseText( char* p, const char* endTag, int strFlags ) +{ + TIXMLASSERT( endTag && *endTag ); + + char* start = p; // fixme: hides a member + char endChar = *endTag; + size_t length = strlen( endTag ); + + // Inner loop of text parsing. + while ( *p ) { + if ( *p == endChar && strncmp( p, endTag, length ) == 0 ) { + Set( start, p, strFlags ); + return p + length; + } + ++p; + } + return 0; +} + + +char* StrPair::ParseName( char* p ) +{ + char* start = p; + + if ( !start || !(*start) ) { + return 0; + } + + while( *p && ( p == start ? XMLUtil::IsNameStartChar( *p ) : XMLUtil::IsNameChar( *p ) )) { + ++p; + } + + if ( p > start ) { + Set( start, p, 0 ); + return p; + } + return 0; +} + + +void StrPair::CollapseWhitespace() +{ + // Trim leading space. + _start = XMLUtil::SkipWhiteSpace( _start ); + + if ( _start && *_start ) { + char* p = _start; // the read pointer + char* q = _start; // the write pointer + + while( *p ) { + if ( XMLUtil::IsWhiteSpace( *p )) { + p = XMLUtil::SkipWhiteSpace( p ); + if ( *p == 0 ) { + break; // don't write to q; this trims the trailing space. + } + *q = ' '; + ++q; + } + *q = *p; + ++q; + ++p; + } + *q = 0; + } +} + + +const char* StrPair::GetStr() +{ + if ( _flags & NEEDS_FLUSH ) { + *_end = 0; + _flags ^= NEEDS_FLUSH; + + if ( _flags ) { + char* p = _start; // the read pointer + char* q = _start; // the write pointer + + while( p < _end ) { + if ( (_flags & NEEDS_NEWLINE_NORMALIZATION) && *p == CR ) { + // CR-LF pair becomes LF + // CR alone becomes LF + // LF-CR becomes LF + if ( *(p+1) == LF ) { + p += 2; + } + else { + ++p; + } + *q++ = LF; + } + else if ( (_flags & NEEDS_NEWLINE_NORMALIZATION) && *p == LF ) { + if ( *(p+1) == CR ) { + p += 2; + } + else { + ++p; + } + *q++ = LF; + } + else if ( (_flags & NEEDS_ENTITY_PROCESSING) && *p == '&' ) { + // Entities handled by tinyXML2: + // - special entities in the entity table [in/out] + // - numeric character reference [in] + // 中 or 中 + + if ( *(p+1) == '#' ) { + char buf[10] = { 0 }; + int len; + p = const_cast( XMLUtil::GetCharacterRef( p, buf, &len ) ); + for( int i=0; i(p); + // Check for BOM: + if ( *(pu+0) == TIXML_UTF_LEAD_0 + && *(pu+1) == TIXML_UTF_LEAD_1 + && *(pu+2) == TIXML_UTF_LEAD_2 ) { + *bom = true; + p += 3; + } + return p; +} + + +void XMLUtil::ConvertUTF32ToUTF8( unsigned long input, char* output, int* length ) +{ + const unsigned long BYTE_MASK = 0xBF; + const unsigned long BYTE_MARK = 0x80; + const unsigned long FIRST_BYTE_MARK[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; + + if (input < 0x80) { + *length = 1; + } + else if ( input < 0x800 ) { + *length = 2; + } + else if ( input < 0x10000 ) { + *length = 3; + } + else if ( input < 0x200000 ) { + *length = 4; + } + else { + *length = 0; // This code won't covert this correctly anyway. + return; + } + + output += *length; + + // Scary scary fall throughs. + switch (*length) { + case 4: + --output; + *output = (char)((input | BYTE_MARK) & BYTE_MASK); + input >>= 6; + case 3: + --output; + *output = (char)((input | BYTE_MARK) & BYTE_MASK); + input >>= 6; + case 2: + --output; + *output = (char)((input | BYTE_MARK) & BYTE_MASK); + input >>= 6; + case 1: + --output; + *output = (char)(input | FIRST_BYTE_MARK[*length]); + default: + break; + } +} + + +const char* XMLUtil::GetCharacterRef( const char* p, char* value, int* length ) +{ + // Presume an entity, and pull it out. + *length = 0; + + if ( *(p+1) == '#' && *(p+2) ) { + unsigned long ucs = 0; + ptrdiff_t delta = 0; + unsigned mult = 1; + + if ( *(p+2) == 'x' ) { + // Hexadecimal. + if ( !*(p+3) ) { + return 0; + } + + const char* q = p+3; + q = strchr( q, ';' ); + + if ( !q || !*q ) { + return 0; + } + + delta = q-p; + --q; + + while ( *q != 'x' ) { + if ( *q >= '0' && *q <= '9' ) { + ucs += mult * (*q - '0'); + } + else if ( *q >= 'a' && *q <= 'f' ) { + ucs += mult * (*q - 'a' + 10); + } + else if ( *q >= 'A' && *q <= 'F' ) { + ucs += mult * (*q - 'A' + 10 ); + } + else { + return 0; + } + mult *= 16; + --q; + } + } + else { + // Decimal. + if ( !*(p+2) ) { + return 0; + } + + const char* q = p+2; + q = strchr( q, ';' ); + + if ( !q || !*q ) { + return 0; + } + + delta = q-p; + --q; + + while ( *q != '#' ) { + if ( *q >= '0' && *q <= '9' ) { + ucs += mult * (*q - '0'); + } + else { + return 0; + } + mult *= 10; + --q; + } + } + // convert the UCS to UTF-8 + ConvertUTF32ToUTF8( ucs, value, length ); + return p + delta + 1; + } + return p+1; +} + + +void XMLUtil::ToStr( int v, char* buffer, int bufferSize ) +{ + TIXML_SNPRINTF( buffer, bufferSize, "%d", v ); +} + + +void XMLUtil::ToStr( unsigned v, char* buffer, int bufferSize ) +{ + TIXML_SNPRINTF( buffer, bufferSize, "%u", v ); +} + + +void XMLUtil::ToStr( bool v, char* buffer, int bufferSize ) +{ + TIXML_SNPRINTF( buffer, bufferSize, "%d", v ? 1 : 0 ); +} + + +void XMLUtil::ToStr( float v, char* buffer, int bufferSize ) +{ + TIXML_SNPRINTF( buffer, bufferSize, "%f", v ); +} + + +void XMLUtil::ToStr( double v, char* buffer, int bufferSize ) +{ + TIXML_SNPRINTF( buffer, bufferSize, "%f", v ); +} + + +bool XMLUtil::ToInt( const char* str, int* value ) +{ + if ( TIXML_SSCANF( str, "%d", value ) == 1 ) { + return true; + } + return false; +} + +bool XMLUtil::ToUnsigned( const char* str, unsigned *value ) +{ + if ( TIXML_SSCANF( str, "%u", value ) == 1 ) { + return true; + } + return false; +} + +bool XMLUtil::ToBool( const char* str, bool* value ) +{ + int ival = 0; + if ( ToInt( str, &ival )) { + *value = (ival==0) ? false : true; + return true; + } + if ( StringEqual( str, "true" ) ) { + *value = true; + return true; + } + else if ( StringEqual( str, "false" ) ) { + *value = false; + return true; + } + return false; +} + + +bool XMLUtil::ToFloat( const char* str, float* value ) +{ + if ( TIXML_SSCANF( str, "%f", value ) == 1 ) { + return true; + } + return false; +} + +bool XMLUtil::ToDouble( const char* str, double* value ) +{ + if ( TIXML_SSCANF( str, "%lf", value ) == 1 ) { + return true; + } + return false; +} + + +char* XMLDocument::Identify( char* p, XMLNode** node ) +{ + XMLNode* returnNode = 0; + char* start = p; + p = XMLUtil::SkipWhiteSpace( p ); + if( !p || !*p ) { + return p; + } + + // What is this thing? + // - Elements start with a letter or underscore, but xml is reserved. + // - Comments: + // + // With a special case: + // + // + // + // + // Where the closing element (/foo) *must* be the next thing after the opening + // element, and the names must match. BUT the tricky bit is that the closing + // element will be read by the child. + // + // 'endTag' is the end tag for this node, it is returned by a call to a child. + // 'parentEnd' is the end tag for the parent, which is filled in and returned. + + while( p && *p ) { + XMLNode* node = 0; + + p = _document->Identify( p, &node ); + if ( p == 0 || node == 0 ) { + break; + } + + StrPair endTag; + p = node->ParseDeep( p, &endTag ); + if ( !p ) { + DELETE_NODE( node ); + node = 0; + if ( !_document->Error() ) { + _document->SetError( XML_ERROR_PARSING, 0, 0 ); + } + break; + } + + // We read the end tag. Return it to the parent. + if ( node->ToElement() && node->ToElement()->ClosingType() == XMLElement::CLOSING ) { + if ( parentEnd ) { + *parentEnd = static_cast(node)->_value; + } + node->_memPool->SetTracked(); // created and then immediately deleted. + DELETE_NODE( node ); + return p; + } + + // Handle an end tag returned to this level. + // And handle a bunch of annoying errors. + XMLElement* ele = node->ToElement(); + if ( ele ) { + if ( endTag.Empty() && ele->ClosingType() == XMLElement::OPEN ) { + _document->SetError( XML_ERROR_MISMATCHED_ELEMENT, node->Value(), 0 ); + p = 0; + } + else if ( !endTag.Empty() && ele->ClosingType() != XMLElement::OPEN ) { + _document->SetError( XML_ERROR_MISMATCHED_ELEMENT, node->Value(), 0 ); + p = 0; + } + else if ( !endTag.Empty() ) { + if ( !XMLUtil::StringEqual( endTag.GetStr(), node->Value() )) { + _document->SetError( XML_ERROR_MISMATCHED_ELEMENT, node->Value(), 0 ); + p = 0; + } + } + } + if ( p == 0 ) { + DELETE_NODE( node ); + node = 0; + } + if ( node ) { + this->InsertEndChild( node ); + } + } + return 0; +} + +// --------- XMLText ---------- // +char* XMLText::ParseDeep( char* p, StrPair* ) +{ + const char* start = p; + if ( this->CData() ) { + p = _value.ParseText( p, "]]>", StrPair::NEEDS_NEWLINE_NORMALIZATION ); + if ( !p ) { + _document->SetError( XML_ERROR_PARSING_CDATA, start, 0 ); + } + return p; + } + else { + int flags = _document->ProcessEntities() ? StrPair::TEXT_ELEMENT : StrPair::TEXT_ELEMENT_LEAVE_ENTITIES; + if ( _document->WhitespaceMode() == COLLAPSE_WHITESPACE ) { + flags |= StrPair::COLLAPSE_WHITESPACE; + } + + p = _value.ParseText( p, "<", flags ); + if ( !p ) { + _document->SetError( XML_ERROR_PARSING_TEXT, start, 0 ); + } + if ( p && *p ) { + return p-1; + } + } + return 0; +} + + +XMLNode* XMLText::ShallowClone( XMLDocument* doc ) const +{ + if ( !doc ) { + doc = _document; + } + XMLText* text = doc->NewText( Value() ); // fixme: this will always allocate memory. Intern? + text->SetCData( this->CData() ); + return text; +} + + +bool XMLText::ShallowEqual( const XMLNode* compare ) const +{ + return ( compare->ToText() && XMLUtil::StringEqual( compare->ToText()->Value(), Value() )); +} + + +bool XMLText::Accept( XMLVisitor* visitor ) const +{ + return visitor->Visit( *this ); +} + + +// --------- XMLComment ---------- // + +XMLComment::XMLComment( XMLDocument* doc ) : XMLNode( doc ) +{ +} + + +XMLComment::~XMLComment() +{ +} + + +char* XMLComment::ParseDeep( char* p, StrPair* ) +{ + // Comment parses as text. + const char* start = p; + p = _value.ParseText( p, "-->", StrPair::COMMENT ); + if ( p == 0 ) { + _document->SetError( XML_ERROR_PARSING_COMMENT, start, 0 ); + } + return p; +} + + +XMLNode* XMLComment::ShallowClone( XMLDocument* doc ) const +{ + if ( !doc ) { + doc = _document; + } + XMLComment* comment = doc->NewComment( Value() ); // fixme: this will always allocate memory. Intern? + return comment; +} + + +bool XMLComment::ShallowEqual( const XMLNode* compare ) const +{ + return ( compare->ToComment() && XMLUtil::StringEqual( compare->ToComment()->Value(), Value() )); +} + + +bool XMLComment::Accept( XMLVisitor* visitor ) const +{ + return visitor->Visit( *this ); +} + + +// --------- XMLDeclaration ---------- // + +XMLDeclaration::XMLDeclaration( XMLDocument* doc ) : XMLNode( doc ) +{ +} + + +XMLDeclaration::~XMLDeclaration() +{ + //printf( "~XMLDeclaration\n" ); +} + + +char* XMLDeclaration::ParseDeep( char* p, StrPair* ) +{ + // Declaration parses as text. + const char* start = p; + p = _value.ParseText( p, "?>", StrPair::NEEDS_NEWLINE_NORMALIZATION ); + if ( p == 0 ) { + _document->SetError( XML_ERROR_PARSING_DECLARATION, start, 0 ); + } + return p; +} + + +XMLNode* XMLDeclaration::ShallowClone( XMLDocument* doc ) const +{ + if ( !doc ) { + doc = _document; + } + XMLDeclaration* dec = doc->NewDeclaration( Value() ); // fixme: this will always allocate memory. Intern? + return dec; +} + + +bool XMLDeclaration::ShallowEqual( const XMLNode* compare ) const +{ + return ( compare->ToDeclaration() && XMLUtil::StringEqual( compare->ToDeclaration()->Value(), Value() )); +} + + + +bool XMLDeclaration::Accept( XMLVisitor* visitor ) const +{ + return visitor->Visit( *this ); +} + +// --------- XMLUnknown ---------- // + +XMLUnknown::XMLUnknown( XMLDocument* doc ) : XMLNode( doc ) +{ +} + + +XMLUnknown::~XMLUnknown() +{ +} + + +char* XMLUnknown::ParseDeep( char* p, StrPair* ) +{ + // Unknown parses as text. + const char* start = p; + + p = _value.ParseText( p, ">", StrPair::NEEDS_NEWLINE_NORMALIZATION ); + if ( !p ) { + _document->SetError( XML_ERROR_PARSING_UNKNOWN, start, 0 ); + } + return p; +} + + +XMLNode* XMLUnknown::ShallowClone( XMLDocument* doc ) const +{ + if ( !doc ) { + doc = _document; + } + XMLUnknown* text = doc->NewUnknown( Value() ); // fixme: this will always allocate memory. Intern? + return text; +} + + +bool XMLUnknown::ShallowEqual( const XMLNode* compare ) const +{ + return ( compare->ToUnknown() && XMLUtil::StringEqual( compare->ToUnknown()->Value(), Value() )); +} + + +bool XMLUnknown::Accept( XMLVisitor* visitor ) const +{ + return visitor->Visit( *this ); +} + +// --------- XMLAttribute ---------- // +char* XMLAttribute::ParseDeep( char* p, bool processEntities ) +{ + // Parse using the name rules: bug fix, was using ParseText before + p = _name.ParseName( p ); + if ( !p || !*p ) { + return 0; + } + + // Skip white space before = + p = XMLUtil::SkipWhiteSpace( p ); + if ( !p || *p != '=' ) { + return 0; + } + + ++p; // move up to opening quote + p = XMLUtil::SkipWhiteSpace( p ); + if ( *p != '\"' && *p != '\'' ) { + return 0; + } + + char endTag[2] = { *p, 0 }; + ++p; // move past opening quote + + p = _value.ParseText( p, endTag, processEntities ? StrPair::ATTRIBUTE_VALUE : StrPair::ATTRIBUTE_VALUE_LEAVE_ENTITIES ); + return p; +} + + +void XMLAttribute::SetName( const char* n ) +{ + _name.SetStr( n ); +} + + +XMLError XMLAttribute::QueryIntValue( int* value ) const +{ + if ( XMLUtil::ToInt( Value(), value )) { + return XML_NO_ERROR; + } + return XML_WRONG_ATTRIBUTE_TYPE; +} + + +XMLError XMLAttribute::QueryUnsignedValue( unsigned int* value ) const +{ + if ( XMLUtil::ToUnsigned( Value(), value )) { + return XML_NO_ERROR; + } + return XML_WRONG_ATTRIBUTE_TYPE; +} + + +XMLError XMLAttribute::QueryBoolValue( bool* value ) const +{ + if ( XMLUtil::ToBool( Value(), value )) { + return XML_NO_ERROR; + } + return XML_WRONG_ATTRIBUTE_TYPE; +} + + +XMLError XMLAttribute::QueryFloatValue( float* value ) const +{ + if ( XMLUtil::ToFloat( Value(), value )) { + return XML_NO_ERROR; + } + return XML_WRONG_ATTRIBUTE_TYPE; +} + + +XMLError XMLAttribute::QueryDoubleValue( double* value ) const +{ + if ( XMLUtil::ToDouble( Value(), value )) { + return XML_NO_ERROR; + } + return XML_WRONG_ATTRIBUTE_TYPE; +} + + +void XMLAttribute::SetAttribute( const char* v ) +{ + _value.SetStr( v ); +} + + +void XMLAttribute::SetAttribute( int v ) +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr( v, buf, BUF_SIZE ); + _value.SetStr( buf ); +} + + +void XMLAttribute::SetAttribute( unsigned v ) +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr( v, buf, BUF_SIZE ); + _value.SetStr( buf ); +} + + +void XMLAttribute::SetAttribute( bool v ) +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr( v, buf, BUF_SIZE ); + _value.SetStr( buf ); +} + +void XMLAttribute::SetAttribute( double v ) +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr( v, buf, BUF_SIZE ); + _value.SetStr( buf ); +} + +void XMLAttribute::SetAttribute( float v ) +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr( v, buf, BUF_SIZE ); + _value.SetStr( buf ); +} + + +// --------- XMLElement ---------- // +XMLElement::XMLElement( XMLDocument* doc ) : XMLNode( doc ), + _closingType( 0 ), + _rootAttribute( 0 ) +{ +} + + +XMLElement::~XMLElement() +{ + while( _rootAttribute ) { + XMLAttribute* next = _rootAttribute->_next; + DELETE_ATTRIBUTE( _rootAttribute ); + _rootAttribute = next; + } +} + + +XMLAttribute* XMLElement::FindAttribute( const char* name ) +{ + XMLAttribute* a = 0; + for( a=_rootAttribute; a; a = a->_next ) { + if ( XMLUtil::StringEqual( a->Name(), name ) ) { + return a; + } + } + return 0; +} + + +const XMLAttribute* XMLElement::FindAttribute( const char* name ) const +{ + XMLAttribute* a = 0; + for( a=_rootAttribute; a; a = a->_next ) { + if ( XMLUtil::StringEqual( a->Name(), name ) ) { + return a; + } + } + return 0; +} + + +const char* XMLElement::Attribute( const char* name, const char* value ) const +{ + const XMLAttribute* a = FindAttribute( name ); + if ( !a ) { + return 0; + } + if ( !value || XMLUtil::StringEqual( a->Value(), value )) { + return a->Value(); + } + return 0; +} + + +const char* XMLElement::GetText() const +{ + if ( FirstChild() && FirstChild()->ToText() ) { + return FirstChild()->ToText()->Value(); + } + return 0; +} + + +XMLError XMLElement::QueryIntText( int* ival ) const +{ + if ( FirstChild() && FirstChild()->ToText() ) { + const char* t = FirstChild()->ToText()->Value(); + if ( XMLUtil::ToInt( t, ival ) ) { + return XML_SUCCESS; + } + return XML_CAN_NOT_CONVERT_TEXT; + } + return XML_NO_TEXT_NODE; +} + + +XMLError XMLElement::QueryUnsignedText( unsigned* uval ) const +{ + if ( FirstChild() && FirstChild()->ToText() ) { + const char* t = FirstChild()->ToText()->Value(); + if ( XMLUtil::ToUnsigned( t, uval ) ) { + return XML_SUCCESS; + } + return XML_CAN_NOT_CONVERT_TEXT; + } + return XML_NO_TEXT_NODE; +} + + +XMLError XMLElement::QueryBoolText( bool* bval ) const +{ + if ( FirstChild() && FirstChild()->ToText() ) { + const char* t = FirstChild()->ToText()->Value(); + if ( XMLUtil::ToBool( t, bval ) ) { + return XML_SUCCESS; + } + return XML_CAN_NOT_CONVERT_TEXT; + } + return XML_NO_TEXT_NODE; +} + + +XMLError XMLElement::QueryDoubleText( double* dval ) const +{ + if ( FirstChild() && FirstChild()->ToText() ) { + const char* t = FirstChild()->ToText()->Value(); + if ( XMLUtil::ToDouble( t, dval ) ) { + return XML_SUCCESS; + } + return XML_CAN_NOT_CONVERT_TEXT; + } + return XML_NO_TEXT_NODE; +} + + +XMLError XMLElement::QueryFloatText( float* fval ) const +{ + if ( FirstChild() && FirstChild()->ToText() ) { + const char* t = FirstChild()->ToText()->Value(); + if ( XMLUtil::ToFloat( t, fval ) ) { + return XML_SUCCESS; + } + return XML_CAN_NOT_CONVERT_TEXT; + } + return XML_NO_TEXT_NODE; +} + + + +XMLAttribute* XMLElement::FindOrCreateAttribute( const char* name ) +{ + XMLAttribute* last = 0; + XMLAttribute* attrib = 0; + for( attrib = _rootAttribute; + attrib; + last = attrib, attrib = attrib->_next ) { + if ( XMLUtil::StringEqual( attrib->Name(), name ) ) { + break; + } + } + if ( !attrib ) { + attrib = new (_document->_attributePool.Alloc() ) XMLAttribute(); + attrib->_memPool = &_document->_attributePool; + if ( last ) { + last->_next = attrib; + } + else { + _rootAttribute = attrib; + } + attrib->SetName( name ); + attrib->_memPool->SetTracked(); // always created and linked. + } + return attrib; +} + + +void XMLElement::DeleteAttribute( const char* name ) +{ + XMLAttribute* prev = 0; + for( XMLAttribute* a=_rootAttribute; a; a=a->_next ) { + if ( XMLUtil::StringEqual( name, a->Name() ) ) { + if ( prev ) { + prev->_next = a->_next; + } + else { + _rootAttribute = a->_next; + } + DELETE_ATTRIBUTE( a ); + break; + } + prev = a; + } +} + + +char* XMLElement::ParseAttributes( char* p ) +{ + const char* start = p; + XMLAttribute* prevAttribute = 0; + + // Read the attributes. + while( p ) { + p = XMLUtil::SkipWhiteSpace( p ); + if ( !p || !(*p) ) { + _document->SetError( XML_ERROR_PARSING_ELEMENT, start, Name() ); + return 0; + } + + // attribute. + if (XMLUtil::IsNameStartChar( *p ) ) { + XMLAttribute* attrib = new (_document->_attributePool.Alloc() ) XMLAttribute(); + attrib->_memPool = &_document->_attributePool; + attrib->_memPool->SetTracked(); + + p = attrib->ParseDeep( p, _document->ProcessEntities() ); + if ( !p || Attribute( attrib->Name() ) ) { + DELETE_ATTRIBUTE( attrib ); + _document->SetError( XML_ERROR_PARSING_ATTRIBUTE, start, p ); + return 0; + } + // There is a minor bug here: if the attribute in the source xml + // document is duplicated, it will not be detected and the + // attribute will be doubly added. However, tracking the 'prevAttribute' + // avoids re-scanning the attribute list. Preferring performance for + // now, may reconsider in the future. + if ( prevAttribute ) { + prevAttribute->_next = attrib; + } + else { + _rootAttribute = attrib; + } + prevAttribute = attrib; + } + // end of the tag + else if ( *p == '/' && *(p+1) == '>' ) { + _closingType = CLOSED; + return p+2; // done; sealed element. + } + // end of the tag + else if ( *p == '>' ) { + ++p; + break; + } + else { + _document->SetError( XML_ERROR_PARSING_ELEMENT, start, p ); + return 0; + } + } + return p; +} + + +// +// +// foobar +// +char* XMLElement::ParseDeep( char* p, StrPair* strPair ) +{ + // Read the element name. + p = XMLUtil::SkipWhiteSpace( p ); + if ( !p ) { + return 0; + } + + // The closing element is the form. It is + // parsed just like a regular element then deleted from + // the DOM. + if ( *p == '/' ) { + _closingType = CLOSING; + ++p; + } + + p = _value.ParseName( p ); + if ( _value.Empty() ) { + return 0; + } + + p = ParseAttributes( p ); + if ( !p || !*p || _closingType ) { + return p; + } + + p = XMLNode::ParseDeep( p, strPair ); + return p; +} + + + +XMLNode* XMLElement::ShallowClone( XMLDocument* doc ) const +{ + if ( !doc ) { + doc = _document; + } + XMLElement* element = doc->NewElement( Value() ); // fixme: this will always allocate memory. Intern? + for( const XMLAttribute* a=FirstAttribute(); a; a=a->Next() ) { + element->SetAttribute( a->Name(), a->Value() ); // fixme: this will always allocate memory. Intern? + } + return element; +} + + +bool XMLElement::ShallowEqual( const XMLNode* compare ) const +{ + const XMLElement* other = compare->ToElement(); + if ( other && XMLUtil::StringEqual( other->Value(), Value() )) { + + const XMLAttribute* a=FirstAttribute(); + const XMLAttribute* b=other->FirstAttribute(); + + while ( a && b ) { + if ( !XMLUtil::StringEqual( a->Value(), b->Value() ) ) { + return false; + } + a = a->Next(); + b = b->Next(); + } + if ( a || b ) { + // different count + return false; + } + return true; + } + return false; +} + + +bool XMLElement::Accept( XMLVisitor* visitor ) const +{ + if ( visitor->VisitEnter( *this, _rootAttribute ) ) { + for ( const XMLNode* node=FirstChild(); node; node=node->NextSibling() ) { + if ( !node->Accept( visitor ) ) { + break; + } + } + } + return visitor->VisitExit( *this ); +} + + +// --------- XMLDocument ----------- // +XMLDocument::XMLDocument( bool processEntities, Whitespace whitespace ) : + XMLNode( 0 ), + _writeBOM( false ), + _processEntities( processEntities ), + _errorID( XML_NO_ERROR ), + _whitespace( whitespace ), + _errorStr1( 0 ), + _errorStr2( 0 ), + _charBuffer( 0 ) +{ + _document = this; // avoid warning about 'this' in initializer list +} + + +XMLDocument::~XMLDocument() +{ + DeleteChildren(); + delete [] _charBuffer; + +#if 0 + _textPool.Trace( "text" ); + _elementPool.Trace( "element" ); + _commentPool.Trace( "comment" ); + _attributePool.Trace( "attribute" ); +#endif + +#ifdef DEBUG + if ( Error() == false ) { + TIXMLASSERT( _elementPool.CurrentAllocs() == _elementPool.Untracked() ); + TIXMLASSERT( _attributePool.CurrentAllocs() == _attributePool.Untracked() ); + TIXMLASSERT( _textPool.CurrentAllocs() == _textPool.Untracked() ); + TIXMLASSERT( _commentPool.CurrentAllocs() == _commentPool.Untracked() ); + } +#endif +} + + +void XMLDocument::Clear() +{ + DeleteChildren(); + + _errorID = XML_NO_ERROR; + _errorStr1 = 0; + _errorStr2 = 0; + + delete [] _charBuffer; + _charBuffer = 0; +} + + +XMLElement* XMLDocument::NewElement( const char* name ) +{ + XMLElement* ele = new (_elementPool.Alloc()) XMLElement( this ); + ele->_memPool = &_elementPool; + ele->SetName( name ); + return ele; +} + + +XMLComment* XMLDocument::NewComment( const char* str ) +{ + XMLComment* comment = new (_commentPool.Alloc()) XMLComment( this ); + comment->_memPool = &_commentPool; + comment->SetValue( str ); + return comment; +} + + +XMLText* XMLDocument::NewText( const char* str ) +{ + XMLText* text = new (_textPool.Alloc()) XMLText( this ); + text->_memPool = &_textPool; + text->SetValue( str ); + return text; +} + + +XMLDeclaration* XMLDocument::NewDeclaration( const char* str ) +{ + XMLDeclaration* dec = new (_commentPool.Alloc()) XMLDeclaration( this ); + dec->_memPool = &_commentPool; + dec->SetValue( str ? str : "xml version=\"1.0\" encoding=\"UTF-8\"" ); + return dec; +} + + +XMLUnknown* XMLDocument::NewUnknown( const char* str ) +{ + XMLUnknown* unk = new (_commentPool.Alloc()) XMLUnknown( this ); + unk->_memPool = &_commentPool; + unk->SetValue( str ); + return unk; +} + + +XMLError XMLDocument::LoadFile( const char* filename ) +{ + Clear(); + FILE* fp = 0; + +#if defined(_MSC_VER) && (_MSC_VER >= 1400 ) + errno_t err = fopen_s(&fp, filename, "rb" ); + if ( !fp || err) { +#else + fp = fopen( filename, "rb" ); + if ( !fp) { +#endif + SetError( XML_ERROR_FILE_NOT_FOUND, filename, 0 ); + return _errorID; + } + LoadFile( fp ); + fclose( fp ); + return _errorID; +} + + +XMLError XMLDocument::LoadFile( FILE* fp ) +{ + Clear(); + + fseek( fp, 0, SEEK_END ); + size_t size = ftell( fp ); + fseek( fp, 0, SEEK_SET ); + + if ( size == 0 ) { + SetError( XML_ERROR_EMPTY_DOCUMENT, 0, 0 ); + return _errorID; + } + + _charBuffer = new char[size+1]; + size_t read = fread( _charBuffer, 1, size, fp ); + if ( read != size ) { + SetError( XML_ERROR_FILE_READ_ERROR, 0, 0 ); + return _errorID; + } + + _charBuffer[size] = 0; + + const char* p = _charBuffer; + p = XMLUtil::SkipWhiteSpace( p ); + p = XMLUtil::ReadBOM( p, &_writeBOM ); + if ( !p || !*p ) { + SetError( XML_ERROR_EMPTY_DOCUMENT, 0, 0 ); + return _errorID; + } + + ParseDeep( _charBuffer + (p-_charBuffer), 0 ); + return _errorID; +} + + +XMLError XMLDocument::SaveFile( const char* filename, bool compact ) +{ + FILE* fp = 0; +#if defined(_MSC_VER) && (_MSC_VER >= 1400 ) + errno_t err = fopen_s(&fp, filename, "w" ); + if ( !fp || err) { +#else + fp = fopen( filename, "w" ); + if ( !fp) { +#endif + SetError( XML_ERROR_FILE_COULD_NOT_BE_OPENED, filename, 0 ); + return _errorID; + } + SaveFile(fp, compact); + fclose( fp ); + return _errorID; +} + + +XMLError XMLDocument::SaveFile( FILE* fp, bool compact ) +{ + XMLPrinter stream( fp, compact ); + Print( &stream ); + return _errorID; +} + + +XMLError XMLDocument::Parse( const char* p, size_t len ) +{ + const char* start = p; + Clear(); + + if ( !p || !*p ) { + SetError( XML_ERROR_EMPTY_DOCUMENT, 0, 0 ); + return _errorID; + } + if ( len == (size_t)(-1) ) { + len = strlen( p ); + } + _charBuffer = new char[ len+1 ]; + memcpy( _charBuffer, p, len ); + _charBuffer[len] = 0; + + p = XMLUtil::SkipWhiteSpace( p ); + p = XMLUtil::ReadBOM( p, &_writeBOM ); + if ( !p || !*p ) { + SetError( XML_ERROR_EMPTY_DOCUMENT, 0, 0 ); + return _errorID; + } + + ptrdiff_t delta = p - start; // skip initial whitespace, BOM, etc. + ParseDeep( _charBuffer+delta, 0 ); + return _errorID; +} + + +void XMLDocument::Print( XMLPrinter* streamer ) const +{ + XMLPrinter stdStreamer( stdout ); + if ( !streamer ) { + streamer = &stdStreamer; + } + Accept( streamer ); +} + + +void XMLDocument::SetError( XMLError error, const char* str1, const char* str2 ) +{ + _errorID = error; + _errorStr1 = str1; + _errorStr2 = str2; +} + + +void XMLDocument::PrintError() const +{ + if ( _errorID ) { + static const int LEN = 20; + char buf1[LEN] = { 0 }; + char buf2[LEN] = { 0 }; + + if ( _errorStr1 ) { + TIXML_SNPRINTF( buf1, LEN, "%s", _errorStr1 ); + } + if ( _errorStr2 ) { + TIXML_SNPRINTF( buf2, LEN, "%s", _errorStr2 ); + } + + printf( "XMLDocument error id=%d str1=%s str2=%s\n", + _errorID, buf1, buf2 ); + } +} + + +XMLPrinter::XMLPrinter( FILE* file, bool compact, int depth ) : + _elementJustOpened( false ), + _firstElement( true ), + _fp( file ), + _depth( depth ), + _textDepth( -1 ), + _processEntities( true ), + _compactMode( compact ) +{ + for( int i=0; i'] = true; // not required, but consistency is nice + _buffer.Push( 0 ); +} + + +void XMLPrinter::Print( const char* format, ... ) +{ + va_list va; + va_start( va, format ); + + if ( _fp ) { + vfprintf( _fp, format, va ); + } + else { + // This seems brutally complex. Haven't figured out a better + // way on windows. +#ifdef _MSC_VER + int len = -1; + int expand = 1000; + while ( len < 0 ) { + len = vsnprintf_s( _accumulator.Mem(), _accumulator.Capacity(), _TRUNCATE, format, va ); + if ( len < 0 ) { + expand *= 3/2; + _accumulator.PushArr( expand ); + } + } + char* p = _buffer.PushArr( len ) - 1; + memcpy( p, _accumulator.Mem(), len+1 ); +#else + int len = vsnprintf( 0, 0, format, va ); + // Close out and re-start the va-args + va_end( va ); + va_start( va, format ); + char* p = _buffer.PushArr( len ) - 1; + vsnprintf( p, len+1, format, va ); +#endif + } + va_end( va ); +} + + +void XMLPrinter::PrintSpace( int depth ) +{ + for( int i=0; i 0 && *q < ENTITY_RANGE ) { + // Check for entities. If one is found, flush + // the stream up until the entity, write the + // entity, and keep looking. + if ( flag[(unsigned)(*q)] ) { + while ( p < q ) { + Print( "%c", *p ); + ++p; + } + for( int i=0; i 0) ) { + Print( "%s", p ); + } +} + + +void XMLPrinter::PushHeader( bool writeBOM, bool writeDec ) +{ + if ( writeBOM ) { + static const unsigned char bom[] = { TIXML_UTF_LEAD_0, TIXML_UTF_LEAD_1, TIXML_UTF_LEAD_2, 0 }; + Print( "%s", bom ); + } + if ( writeDec ) { + PushDeclaration( "xml version=\"1.0\"" ); + } +} + + +void XMLPrinter::OpenElement( const char* name ) +{ + if ( _elementJustOpened ) { + SealElement(); + } + _stack.Push( name ); + + if ( _textDepth < 0 && !_firstElement && !_compactMode ) { + Print( "\n" ); + } + if ( !_compactMode ) { + PrintSpace( _depth ); + } + + Print( "<%s", name ); + _elementJustOpened = true; + _firstElement = false; + ++_depth; +} + + +void XMLPrinter::PushAttribute( const char* name, const char* value ) +{ + TIXMLASSERT( _elementJustOpened ); + Print( " %s=\"", name ); + PrintString( value, false ); + Print( "\"" ); +} + + +void XMLPrinter::PushAttribute( const char* name, int v ) +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr( v, buf, BUF_SIZE ); + PushAttribute( name, buf ); +} + + +void XMLPrinter::PushAttribute( const char* name, unsigned v ) +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr( v, buf, BUF_SIZE ); + PushAttribute( name, buf ); +} + + +void XMLPrinter::PushAttribute( const char* name, bool v ) +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr( v, buf, BUF_SIZE ); + PushAttribute( name, buf ); +} + + +void XMLPrinter::PushAttribute( const char* name, double v ) +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr( v, buf, BUF_SIZE ); + PushAttribute( name, buf ); +} + + +void XMLPrinter::CloseElement() +{ + --_depth; + const char* name = _stack.Pop(); + + if ( _elementJustOpened ) { + Print( "/>" ); + } + else { + if ( _textDepth < 0 && !_compactMode) { + Print( "\n" ); + PrintSpace( _depth ); + } + Print( "", name ); + } + + if ( _textDepth == _depth ) { + _textDepth = -1; + } + if ( _depth == 0 && !_compactMode) { + Print( "\n" ); + } + _elementJustOpened = false; +} + + +void XMLPrinter::SealElement() +{ + _elementJustOpened = false; + Print( ">" ); +} + + +void XMLPrinter::PushText( const char* text, bool cdata ) +{ + _textDepth = _depth-1; + + if ( _elementJustOpened ) { + SealElement(); + } + if ( cdata ) { + Print( "" ); + } + else { + PrintString( text, true ); + } +} + +void XMLPrinter::PushText( int value ) +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr( value, buf, BUF_SIZE ); + PushText( buf, false ); +} + + +void XMLPrinter::PushText( unsigned value ) +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr( value, buf, BUF_SIZE ); + PushText( buf, false ); +} + + +void XMLPrinter::PushText( bool value ) +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr( value, buf, BUF_SIZE ); + PushText( buf, false ); +} + + +void XMLPrinter::PushText( float value ) +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr( value, buf, BUF_SIZE ); + PushText( buf, false ); +} + + +void XMLPrinter::PushText( double value ) +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr( value, buf, BUF_SIZE ); + PushText( buf, false ); +} + + +void XMLPrinter::PushComment( const char* comment ) +{ + if ( _elementJustOpened ) { + SealElement(); + } + if ( _textDepth < 0 && !_firstElement && !_compactMode) { + Print( "\n" ); + PrintSpace( _depth ); + } + _firstElement = false; + Print( "", comment ); +} + + +void XMLPrinter::PushDeclaration( const char* value ) +{ + if ( _elementJustOpened ) { + SealElement(); + } + if ( _textDepth < 0 && !_firstElement && !_compactMode) { + Print( "\n" ); + PrintSpace( _depth ); + } + _firstElement = false; + Print( "", value ); +} + + +void XMLPrinter::PushUnknown( const char* value ) +{ + if ( _elementJustOpened ) { + SealElement(); + } + if ( _textDepth < 0 && !_firstElement && !_compactMode) { + Print( "\n" ); + PrintSpace( _depth ); + } + _firstElement = false; + Print( "", value ); +} + + +bool XMLPrinter::VisitEnter( const XMLDocument& doc ) +{ + _processEntities = doc.ProcessEntities(); + if ( doc.HasBOM() ) { + PushHeader( true, false ); + } + return true; +} + + +bool XMLPrinter::VisitEnter( const XMLElement& element, const XMLAttribute* attribute ) +{ + OpenElement( element.Name() ); + while ( attribute ) { + PushAttribute( attribute->Name(), attribute->Value() ); + attribute = attribute->Next(); + } + return true; +} + + +bool XMLPrinter::VisitExit( const XMLElement& ) +{ + CloseElement(); + return true; +} + + +bool XMLPrinter::Visit( const XMLText& text ) +{ + PushText( text.Value(), text.CData() ); + return true; +} + + +bool XMLPrinter::Visit( const XMLComment& comment ) +{ + PushComment( comment.Value() ); + return true; +} + +bool XMLPrinter::Visit( const XMLDeclaration& declaration ) +{ + PushDeclaration( declaration.Value() ); + return true; +} + + +bool XMLPrinter::Visit( const XMLUnknown& unknown ) +{ + PushUnknown( unknown.Value() ); + return true; +} + +} // namespace tinyxml2 + diff --git a/FileSearch/tinyxml2.h b/FileSearch/tinyxml2.h new file mode 100644 index 0000000..c9b9078 --- /dev/null +++ b/FileSearch/tinyxml2.h @@ -0,0 +1,1987 @@ +/* +Original code by Lee Thomason (www.grinninglizard.com) + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any +damages arising from the use of this software. + +Permission is granted to anyone to use this software for any +purpose, including commercial applications, and to alter it and +redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. + + +2. Altered source versions must be plainly marked as such, and +must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source +distribution. +*/ + +#ifndef TINYXML2_INCLUDED +#define TINYXML2_INCLUDED + +#if defined(ANDROID_NDK) || defined(__BORLANDC__) +# include +# include +# include +# include +# include +# include +#else +# include +# include +# include +# include +# include +# include +#endif + +/* + TODO: intern strings instead of allocation. +*/ +/* + gcc: + g++ -Wall -DDEBUG tinyxml2.cpp xmltest.cpp -o gccxmltest.exe + + Formatting, Artistic Style: + AStyle.exe --style=1tbs --indent-switches --break-closing-brackets --indent-preprocessor tinyxml2.cpp tinyxml2.h +*/ + +#if defined( _DEBUG ) || defined( DEBUG ) || defined (__DEBUG__) +# ifndef DEBUG +# define DEBUG +# endif +#endif + +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable: 4251) +#endif + +#ifdef _WIN32 +# ifdef TINYXML2_EXPORT +# define TINYXML2_LIB __declspec(dllexport) +# elif defined(TINYXML2_IMPORT) +# define TINYXML2_LIB __declspec(dllimport) +# else +# define TINYXML2_LIB +# endif +#else +# define TINYXML2_LIB +#endif + + +#if defined(DEBUG) +# if defined(_MSC_VER) +# define TIXMLASSERT( x ) if ( !(x)) { __debugbreak(); } //if ( !(x)) WinDebugBreak() +# elif defined (ANDROID_NDK) +# include +# define TIXMLASSERT( x ) if ( !(x)) { __android_log_assert( "assert", "grinliz", "ASSERT in '%s' at %d.", __FILE__, __LINE__ ); } +# else +# include +# define TIXMLASSERT assert +# endif +# else +# define TIXMLASSERT( x ) {} +#endif + + +#if defined(_MSC_VER) && (_MSC_VER >= 1400 ) +// Microsoft visual studio, version 2005 and higher. +/*int _snprintf_s( + char *buffer, + size_t sizeOfBuffer, + size_t count, + const char *format [, + argument] ... +);*/ +inline int TIXML_SNPRINTF( char* buffer, size_t size, const char* format, ... ) +{ + va_list va; + va_start( va, format ); + int result = vsnprintf_s( buffer, size, _TRUNCATE, format, va ); + va_end( va ); + return result; +} +#define TIXML_SSCANF sscanf_s +#else +// GCC version 3 and higher +//#warning( "Using sn* functions." ) +#define TIXML_SNPRINTF snprintf +#define TIXML_SSCANF sscanf +#endif + +static const int TIXML2_MAJOR_VERSION = 1; +static const int TIXML2_MINOR_VERSION = 0; +static const int TIXML2_PATCH_VERSION = 11; + +namespace tinyxml2 +{ +class XMLDocument; +class XMLElement; +class XMLAttribute; +class XMLComment; +class XMLText; +class XMLDeclaration; +class XMLUnknown; +class XMLPrinter; + +/* + A class that wraps strings. Normally stores the start and end + pointers into the XML file itself, and will apply normalization + and entity translation if actually read. Can also store (and memory + manage) a traditional char[] +*/ +class StrPair +{ +public: + enum { + NEEDS_ENTITY_PROCESSING = 0x01, + NEEDS_NEWLINE_NORMALIZATION = 0x02, + COLLAPSE_WHITESPACE = 0x04, + + TEXT_ELEMENT = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION, + TEXT_ELEMENT_LEAVE_ENTITIES = NEEDS_NEWLINE_NORMALIZATION, + ATTRIBUTE_NAME = 0, + ATTRIBUTE_VALUE = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION, + ATTRIBUTE_VALUE_LEAVE_ENTITIES = NEEDS_NEWLINE_NORMALIZATION, + COMMENT = NEEDS_NEWLINE_NORMALIZATION + }; + + StrPair() : _flags( 0 ), _start( 0 ), _end( 0 ) {} + ~StrPair(); + + void Set( char* start, char* end, int flags ) { + Reset(); + _start = start; + _end = end; + _flags = flags | NEEDS_FLUSH; + } + + const char* GetStr(); + + bool Empty() const { + return _start == _end; + } + + void SetInternedStr( const char* str ) { + Reset(); + _start = const_cast(str); + } + + void SetStr( const char* str, int flags=0 ); + + char* ParseText( char* in, const char* endTag, int strFlags ); + char* ParseName( char* in ); + +private: + void Reset(); + void CollapseWhitespace(); + + enum { + NEEDS_FLUSH = 0x100, + NEEDS_DELETE = 0x200 + }; + + // After parsing, if *_end != 0, it can be set to zero. + int _flags; + char* _start; + char* _end; +}; + + +/* + A dynamic array of Plain Old Data. Doesn't support constructors, etc. + Has a small initial memory pool, so that low or no usage will not + cause a call to new/delete +*/ +template +class DynArray +{ +public: + DynArray< T, INIT >() { + _mem = _pool; + _allocated = INIT; + _size = 0; + } + + ~DynArray() { + if ( _mem != _pool ) { + delete [] _mem; + } + } + + void Push( T t ) { + EnsureCapacity( _size+1 ); + _mem[_size++] = t; + } + + T* PushArr( int count ) { + EnsureCapacity( _size+count ); + T* ret = &_mem[_size]; + _size += count; + return ret; + } + + T Pop() { + return _mem[--_size]; + } + + void PopArr( int count ) { + TIXMLASSERT( _size >= count ); + _size -= count; + } + + bool Empty() const { + return _size == 0; + } + + T& operator[](int i) { + TIXMLASSERT( i>= 0 && i < _size ); + return _mem[i]; + } + + const T& operator[](int i) const { + TIXMLASSERT( i>= 0 && i < _size ); + return _mem[i]; + } + + int Size() const { + return _size; + } + + int Capacity() const { + return _allocated; + } + + const T* Mem() const { + return _mem; + } + + T* Mem() { + return _mem; + } + +private: + void EnsureCapacity( int cap ) { + if ( cap > _allocated ) { + int newAllocated = cap * 2; + T* newMem = new T[newAllocated]; + memcpy( newMem, _mem, sizeof(T)*_size ); // warning: not using constructors, only works for PODs + if ( _mem != _pool ) { + delete [] _mem; + } + _mem = newMem; + _allocated = newAllocated; + } + } + + T* _mem; + T _pool[INIT]; + int _allocated; // objects allocated + int _size; // number objects in use +}; + + +/* + Parent virtual class of a pool for fast allocation + and deallocation of objects. +*/ +class MemPool +{ +public: + MemPool() {} + virtual ~MemPool() {} + + virtual int ItemSize() const = 0; + virtual void* Alloc() = 0; + virtual void Free( void* ) = 0; + virtual void SetTracked() = 0; +}; + + +/* + Template child class to create pools of the correct type. +*/ +template< int SIZE > +class MemPoolT : public MemPool +{ +public: + MemPoolT() : _root(0), _currentAllocs(0), _nAllocs(0), _maxAllocs(0), _nUntracked(0) {} + ~MemPoolT() { + // Delete the blocks. + for( int i=0; i<_blockPtrs.Size(); ++i ) { + delete _blockPtrs[i]; + } + } + + virtual int ItemSize() const { + return SIZE; + } + int CurrentAllocs() const { + return _currentAllocs; + } + + virtual void* Alloc() { + if ( !_root ) { + // Need a new block. + Block* block = new Block(); + _blockPtrs.Push( block ); + + for( int i=0; ichunk[i].next = &block->chunk[i+1]; + } + block->chunk[COUNT-1].next = 0; + _root = block->chunk; + } + void* result = _root; + _root = _root->next; + + ++_currentAllocs; + if ( _currentAllocs > _maxAllocs ) { + _maxAllocs = _currentAllocs; + } + _nAllocs++; + _nUntracked++; + return result; + } + virtual void Free( void* mem ) { + if ( !mem ) { + return; + } + --_currentAllocs; + Chunk* chunk = (Chunk*)mem; +#ifdef DEBUG + memset( chunk, 0xfe, sizeof(Chunk) ); +#endif + chunk->next = _root; + _root = chunk; + } + void Trace( const char* name ) { + printf( "Mempool %s watermark=%d [%dk] current=%d size=%d nAlloc=%d blocks=%d\n", + name, _maxAllocs, _maxAllocs*SIZE/1024, _currentAllocs, SIZE, _nAllocs, _blockPtrs.Size() ); + } + + void SetTracked() { + _nUntracked--; + } + + int Untracked() const { + return _nUntracked; + } + + // This number is perf sensitive. 4k seems like a good tradeoff on my machine. + // The test file is large, 170k. + // Release: VS2010 gcc(no opt) + // 1k: 4000 + // 2k: 4000 + // 4k: 3900 21000 + // 16k: 5200 + // 32k: 4300 + // 64k: 4000 21000 + enum { COUNT = (4*1024)/SIZE }; // Some compilers do not accept to use COUNT in private part if COUNT is private + +private: + union Chunk { + Chunk* next; + char mem[SIZE]; + }; + struct Block { + Chunk chunk[COUNT]; + }; + DynArray< Block*, 10 > _blockPtrs; + Chunk* _root; + + int _currentAllocs; + int _nAllocs; + int _maxAllocs; + int _nUntracked; +}; + + + +/** + Implements the interface to the "Visitor pattern" (see the Accept() method.) + If you call the Accept() method, it requires being passed a XMLVisitor + class to handle callbacks. For nodes that contain other nodes (Document, Element) + you will get called with a VisitEnter/VisitExit pair. Nodes that are always leafs + are simply called with Visit(). + + If you return 'true' from a Visit method, recursive parsing will continue. If you return + false, no children of this node or its siblings will be visited. + + All flavors of Visit methods have a default implementation that returns 'true' (continue + visiting). You need to only override methods that are interesting to you. + + Generally Accept() is called on the XMLDocument, although all nodes support visiting. + + You should never change the document from a callback. + + @sa XMLNode::Accept() +*/ +class TINYXML2_LIB XMLVisitor +{ +public: + virtual ~XMLVisitor() {} + + /// Visit a document. + virtual bool VisitEnter( const XMLDocument& /*doc*/ ) { + return true; + } + /// Visit a document. + virtual bool VisitExit( const XMLDocument& /*doc*/ ) { + return true; + } + + /// Visit an element. + virtual bool VisitEnter( const XMLElement& /*element*/, const XMLAttribute* /*firstAttribute*/ ) { + return true; + } + /// Visit an element. + virtual bool VisitExit( const XMLElement& /*element*/ ) { + return true; + } + + /// Visit a declaration. + virtual bool Visit( const XMLDeclaration& /*declaration*/ ) { + return true; + } + /// Visit a text node. + virtual bool Visit( const XMLText& /*text*/ ) { + return true; + } + /// Visit a comment node. + virtual bool Visit( const XMLComment& /*comment*/ ) { + return true; + } + /// Visit an unknown node. + virtual bool Visit( const XMLUnknown& /*unknown*/ ) { + return true; + } +}; + + +/* + Utility functionality. +*/ +class XMLUtil +{ +public: + // Anything in the high order range of UTF-8 is assumed to not be whitespace. This isn't + // correct, but simple, and usually works. + static const char* SkipWhiteSpace( const char* p ) { + while( !IsUTF8Continuation(*p) && isspace( *reinterpret_cast(p) ) ) { + ++p; + } + return p; + } + static char* SkipWhiteSpace( char* p ) { + while( !IsUTF8Continuation(*p) && isspace( *reinterpret_cast(p) ) ) { + ++p; + } + return p; + } + static bool IsWhiteSpace( char p ) { + return !IsUTF8Continuation(p) && isspace( static_cast(p) ); + } + + inline static bool IsNameStartChar( unsigned char ch ) { + return ( ( ch < 128 ) ? isalpha( ch ) : 1 ) + || ch == ':' + || ch == '_'; + } + + inline static bool IsNameChar( unsigned char ch ) { + return IsNameStartChar( ch ) + || isdigit( ch ) + || ch == '.' + || ch == '-'; + } + + inline static bool StringEqual( const char* p, const char* q, int nChar=INT_MAX ) { + int n = 0; + if ( p == q ) { + return true; + } + while( *p && *q && *p == *q && n(const_cast(this)->FirstChildElement( value )); + } + + /// Get the last child node, or null if none exists. + const XMLNode* LastChild() const { + return _lastChild; + } + + XMLNode* LastChild() { + return const_cast(const_cast(this)->LastChild() ); + } + + /** Get the last child element or optionally the last child + element with the specified name. + */ + const XMLElement* LastChildElement( const char* value=0 ) const; + + XMLElement* LastChildElement( const char* value=0 ) { + return const_cast(const_cast(this)->LastChildElement(value) ); + } + + /// Get the previous (left) sibling node of this node. + const XMLNode* PreviousSibling() const { + return _prev; + } + + XMLNode* PreviousSibling() { + return _prev; + } + + /// Get the previous (left) sibling element of this node, with an optionally supplied name. + const XMLElement* PreviousSiblingElement( const char* value=0 ) const ; + + XMLElement* PreviousSiblingElement( const char* value=0 ) { + return const_cast(const_cast(this)->PreviousSiblingElement( value ) ); + } + + /// Get the next (right) sibling node of this node. + const XMLNode* NextSibling() const { + return _next; + } + + XMLNode* NextSibling() { + return _next; + } + + /// Get the next (right) sibling element of this node, with an optionally supplied name. + const XMLElement* NextSiblingElement( const char* value=0 ) const; + + XMLElement* NextSiblingElement( const char* value=0 ) { + return const_cast(const_cast(this)->NextSiblingElement( value ) ); + } + + /** + Add a child node as the last (right) child. + */ + XMLNode* InsertEndChild( XMLNode* addThis ); + + XMLNode* LinkEndChild( XMLNode* addThis ) { + return InsertEndChild( addThis ); + } + /** + Add a child node as the first (left) child. + */ + XMLNode* InsertFirstChild( XMLNode* addThis ); + /** + Add a node after the specified child node. + */ + XMLNode* InsertAfterChild( XMLNode* afterThis, XMLNode* addThis ); + + /** + Delete all the children of this node. + */ + void DeleteChildren(); + + /** + Delete a child of this node. + */ + void DeleteChild( XMLNode* node ); + + /** + Make a copy of this node, but not its children. + You may pass in a Document pointer that will be + the owner of the new Node. If the 'document' is + null, then the node returned will be allocated + from the current Document. (this->GetDocument()) + + Note: if called on a XMLDocument, this will return null. + */ + virtual XMLNode* ShallowClone( XMLDocument* document ) const = 0; + + /** + Test if 2 nodes are the same, but don't test children. + The 2 nodes do not need to be in the same Document. + + Note: if called on a XMLDocument, this will return false. + */ + virtual bool ShallowEqual( const XMLNode* compare ) const = 0; + + /** Accept a hierarchical visit of the nodes in the TinyXML-2 DOM. Every node in the + XML tree will be conditionally visited and the host will be called back + via the XMLVisitor interface. + + This is essentially a SAX interface for TinyXML-2. (Note however it doesn't re-parse + the XML for the callbacks, so the performance of TinyXML-2 is unchanged by using this + interface versus any other.) + + The interface has been based on ideas from: + + - http://www.saxproject.org/ + - http://c2.com/cgi/wiki?HierarchicalVisitorPattern + + Which are both good references for "visiting". + + An example of using Accept(): + @verbatim + XMLPrinter printer; + tinyxmlDoc.Accept( &printer ); + const char* xmlcstr = printer.CStr(); + @endverbatim + */ + virtual bool Accept( XMLVisitor* visitor ) const = 0; + + // internal + virtual char* ParseDeep( char*, StrPair* ); + +protected: + XMLNode( XMLDocument* ); + virtual ~XMLNode(); + XMLNode( const XMLNode& ); // not supported + XMLNode& operator=( const XMLNode& ); // not supported + + XMLDocument* _document; + XMLNode* _parent; + mutable StrPair _value; + + XMLNode* _firstChild; + XMLNode* _lastChild; + + XMLNode* _prev; + XMLNode* _next; + +private: + MemPool* _memPool; + void Unlink( XMLNode* child ); +}; + + +/** XML text. + + Note that a text node can have child element nodes, for example: + @verbatim + This is bold + @endverbatim + + A text node can have 2 ways to output the next. "normal" output + and CDATA. It will default to the mode it was parsed from the XML file and + you generally want to leave it alone, but you can change the output mode with + SetCData() and query it with CData(). +*/ +class TINYXML2_LIB XMLText : public XMLNode +{ + friend class XMLBase; + friend class XMLDocument; +public: + virtual bool Accept( XMLVisitor* visitor ) const; + + virtual XMLText* ToText() { + return this; + } + virtual const XMLText* ToText() const { + return this; + } + + /// Declare whether this should be CDATA or standard text. + void SetCData( bool isCData ) { + _isCData = isCData; + } + /// Returns true if this is a CDATA text element. + bool CData() const { + return _isCData; + } + + char* ParseDeep( char*, StrPair* endTag ); + virtual XMLNode* ShallowClone( XMLDocument* document ) const; + virtual bool ShallowEqual( const XMLNode* compare ) const; + +protected: + XMLText( XMLDocument* doc ) : XMLNode( doc ), _isCData( false ) {} + virtual ~XMLText() {} + XMLText( const XMLText& ); // not supported + XMLText& operator=( const XMLText& ); // not supported + +private: + bool _isCData; +}; + + +/** An XML Comment. */ +class TINYXML2_LIB XMLComment : public XMLNode +{ + friend class XMLDocument; +public: + virtual XMLComment* ToComment() { + return this; + } + virtual const XMLComment* ToComment() const { + return this; + } + + virtual bool Accept( XMLVisitor* visitor ) const; + + char* ParseDeep( char*, StrPair* endTag ); + virtual XMLNode* ShallowClone( XMLDocument* document ) const; + virtual bool ShallowEqual( const XMLNode* compare ) const; + +protected: + XMLComment( XMLDocument* doc ); + virtual ~XMLComment(); + XMLComment( const XMLComment& ); // not supported + XMLComment& operator=( const XMLComment& ); // not supported + +private: +}; + + +/** In correct XML the declaration is the first entry in the file. + @verbatim + + @endverbatim + + TinyXML-2 will happily read or write files without a declaration, + however. + + The text of the declaration isn't interpreted. It is parsed + and written as a string. +*/ +class TINYXML2_LIB XMLDeclaration : public XMLNode +{ + friend class XMLDocument; +public: + virtual XMLDeclaration* ToDeclaration() { + return this; + } + virtual const XMLDeclaration* ToDeclaration() const { + return this; + } + + virtual bool Accept( XMLVisitor* visitor ) const; + + char* ParseDeep( char*, StrPair* endTag ); + virtual XMLNode* ShallowClone( XMLDocument* document ) const; + virtual bool ShallowEqual( const XMLNode* compare ) const; + +protected: + XMLDeclaration( XMLDocument* doc ); + virtual ~XMLDeclaration(); + XMLDeclaration( const XMLDeclaration& ); // not supported + XMLDeclaration& operator=( const XMLDeclaration& ); // not supported +}; + + +/** Any tag that TinyXML-2 doesn't recognize is saved as an + unknown. It is a tag of text, but should not be modified. + It will be written back to the XML, unchanged, when the file + is saved. + + DTD tags get thrown into XMLUnknowns. +*/ +class TINYXML2_LIB XMLUnknown : public XMLNode +{ + friend class XMLDocument; +public: + virtual XMLUnknown* ToUnknown() { + return this; + } + virtual const XMLUnknown* ToUnknown() const { + return this; + } + + virtual bool Accept( XMLVisitor* visitor ) const; + + char* ParseDeep( char*, StrPair* endTag ); + virtual XMLNode* ShallowClone( XMLDocument* document ) const; + virtual bool ShallowEqual( const XMLNode* compare ) const; + +protected: + XMLUnknown( XMLDocument* doc ); + virtual ~XMLUnknown(); + XMLUnknown( const XMLUnknown& ); // not supported + XMLUnknown& operator=( const XMLUnknown& ); // not supported +}; + + +enum XMLError { + XML_NO_ERROR = 0, + XML_SUCCESS = 0, + + XML_NO_ATTRIBUTE, + XML_WRONG_ATTRIBUTE_TYPE, + + XML_ERROR_FILE_NOT_FOUND, + XML_ERROR_FILE_COULD_NOT_BE_OPENED, + XML_ERROR_FILE_READ_ERROR, + XML_ERROR_ELEMENT_MISMATCH, + XML_ERROR_PARSING_ELEMENT, + XML_ERROR_PARSING_ATTRIBUTE, + XML_ERROR_IDENTIFYING_TAG, + XML_ERROR_PARSING_TEXT, + XML_ERROR_PARSING_CDATA, + XML_ERROR_PARSING_COMMENT, + XML_ERROR_PARSING_DECLARATION, + XML_ERROR_PARSING_UNKNOWN, + XML_ERROR_EMPTY_DOCUMENT, + XML_ERROR_MISMATCHED_ELEMENT, + XML_ERROR_PARSING, + + XML_CAN_NOT_CONVERT_TEXT, + XML_NO_TEXT_NODE +}; + + +/** An attribute is a name-value pair. Elements have an arbitrary + number of attributes, each with a unique name. + + @note The attributes are not XMLNodes. You may only query the + Next() attribute in a list. +*/ +class TINYXML2_LIB XMLAttribute +{ + friend class XMLElement; +public: + /// The name of the attribute. + const char* Name() const { + return _name.GetStr(); + } + /// The value of the attribute. + const char* Value() const { + return _value.GetStr(); + } + /// The next attribute in the list. + const XMLAttribute* Next() const { + return _next; + } + + /** IntValue interprets the attribute as an integer, and returns the value. + If the value isn't an integer, 0 will be returned. There is no error checking; + use QueryIntValue() if you need error checking. + */ + int IntValue() const { + int i=0; + QueryIntValue( &i ); + return i; + } + /// Query as an unsigned integer. See IntValue() + unsigned UnsignedValue() const { + unsigned i=0; + QueryUnsignedValue( &i ); + return i; + } + /// Query as a boolean. See IntValue() + bool BoolValue() const { + bool b=false; + QueryBoolValue( &b ); + return b; + } + /// Query as a double. See IntValue() + double DoubleValue() const { + double d=0; + QueryDoubleValue( &d ); + return d; + } + /// Query as a float. See IntValue() + float FloatValue() const { + float f=0; + QueryFloatValue( &f ); + return f; + } + + /** QueryIntValue interprets the attribute as an integer, and returns the value + in the provided parameter. The function will return XML_NO_ERROR on success, + and XML_WRONG_ATTRIBUTE_TYPE if the conversion is not successful. + */ + XMLError QueryIntValue( int* value ) const; + /// See QueryIntValue + XMLError QueryUnsignedValue( unsigned int* value ) const; + /// See QueryIntValue + XMLError QueryBoolValue( bool* value ) const; + /// See QueryIntValue + XMLError QueryDoubleValue( double* value ) const; + /// See QueryIntValue + XMLError QueryFloatValue( float* value ) const; + + /// Set the attribute to a string value. + void SetAttribute( const char* value ); + /// Set the attribute to value. + void SetAttribute( int value ); + /// Set the attribute to value. + void SetAttribute( unsigned value ); + /// Set the attribute to value. + void SetAttribute( bool value ); + /// Set the attribute to value. + void SetAttribute( double value ); + /// Set the attribute to value. + void SetAttribute( float value ); + +private: + enum { BUF_SIZE = 200 }; + + XMLAttribute() : _next( 0 ), _memPool( 0 ) {} + virtual ~XMLAttribute() {} + + XMLAttribute( const XMLAttribute& ); // not supported + void operator=( const XMLAttribute& ); // not supported + void SetName( const char* name ); + + char* ParseDeep( char* p, bool processEntities ); + + mutable StrPair _name; + mutable StrPair _value; + XMLAttribute* _next; + MemPool* _memPool; +}; + + +/** The element is a container class. It has a value, the element name, + and can contain other elements, text, comments, and unknowns. + Elements also contain an arbitrary number of attributes. +*/ +class TINYXML2_LIB XMLElement : public XMLNode +{ + friend class XMLBase; + friend class XMLDocument; +public: + /// Get the name of an element (which is the Value() of the node.) + const char* Name() const { + return Value(); + } + /// Set the name of the element. + void SetName( const char* str, bool staticMem=false ) { + SetValue( str, staticMem ); + } + + virtual XMLElement* ToElement() { + return this; + } + virtual const XMLElement* ToElement() const { + return this; + } + virtual bool Accept( XMLVisitor* visitor ) const; + + /** Given an attribute name, Attribute() returns the value + for the attribute of that name, or null if none + exists. For example: + + @verbatim + const char* value = ele->Attribute( "foo" ); + @endverbatim + + The 'value' parameter is normally null. However, if specified, + the attribute will only be returned if the 'name' and 'value' + match. This allow you to write code: + + @verbatim + if ( ele->Attribute( "foo", "bar" ) ) callFooIsBar(); + @endverbatim + + rather than: + @verbatim + if ( ele->Attribute( "foo" ) ) { + if ( strcmp( ele->Attribute( "foo" ), "bar" ) == 0 ) callFooIsBar(); + } + @endverbatim + */ + const char* Attribute( const char* name, const char* value=0 ) const; + + /** Given an attribute name, IntAttribute() returns the value + of the attribute interpreted as an integer. 0 will be + returned if there is an error. For a method with error + checking, see QueryIntAttribute() + */ + int IntAttribute( const char* name ) const { + int i=0; + QueryIntAttribute( name, &i ); + return i; + } + /// See IntAttribute() + unsigned UnsignedAttribute( const char* name ) const { + unsigned i=0; + QueryUnsignedAttribute( name, &i ); + return i; + } + /// See IntAttribute() + bool BoolAttribute( const char* name ) const { + bool b=false; + QueryBoolAttribute( name, &b ); + return b; + } + /// See IntAttribute() + double DoubleAttribute( const char* name ) const { + double d=0; + QueryDoubleAttribute( name, &d ); + return d; + } + /// See IntAttribute() + float FloatAttribute( const char* name ) const { + float f=0; + QueryFloatAttribute( name, &f ); + return f; + } + + /** Given an attribute name, QueryIntAttribute() returns + XML_NO_ERROR, XML_WRONG_ATTRIBUTE_TYPE if the conversion + can't be performed, or XML_NO_ATTRIBUTE if the attribute + doesn't exist. If successful, the result of the conversion + will be written to 'value'. If not successful, nothing will + be written to 'value'. This allows you to provide default + value: + + @verbatim + int value = 10; + QueryIntAttribute( "foo", &value ); // if "foo" isn't found, value will still be 10 + @endverbatim + */ + XMLError QueryIntAttribute( const char* name, int* value ) const { + const XMLAttribute* a = FindAttribute( name ); + if ( !a ) { + return XML_NO_ATTRIBUTE; + } + return a->QueryIntValue( value ); + } + /// See QueryIntAttribute() + XMLError QueryUnsignedAttribute( const char* name, unsigned int* value ) const { + const XMLAttribute* a = FindAttribute( name ); + if ( !a ) { + return XML_NO_ATTRIBUTE; + } + return a->QueryUnsignedValue( value ); + } + /// See QueryIntAttribute() + XMLError QueryBoolAttribute( const char* name, bool* value ) const { + const XMLAttribute* a = FindAttribute( name ); + if ( !a ) { + return XML_NO_ATTRIBUTE; + } + return a->QueryBoolValue( value ); + } + /// See QueryIntAttribute() + XMLError QueryDoubleAttribute( const char* name, double* value ) const { + const XMLAttribute* a = FindAttribute( name ); + if ( !a ) { + return XML_NO_ATTRIBUTE; + } + return a->QueryDoubleValue( value ); + } + /// See QueryIntAttribute() + XMLError QueryFloatAttribute( const char* name, float* value ) const { + const XMLAttribute* a = FindAttribute( name ); + if ( !a ) { + return XML_NO_ATTRIBUTE; + } + return a->QueryFloatValue( value ); + } + + + /** Given an attribute name, QueryAttribute() returns + XML_NO_ERROR, XML_WRONG_ATTRIBUTE_TYPE if the conversion + can't be performed, or XML_NO_ATTRIBUTE if the attribute + doesn't exist. It is overloaded for the primitive types, + and is a generally more convenient replacement of + QueryIntAttribute() and related functions. + + If successful, the result of the conversion + will be written to 'value'. If not successful, nothing will + be written to 'value'. This allows you to provide default + value: + + @verbatim + int value = 10; + QueryAttribute( "foo", &value ); // if "foo" isn't found, value will still be 10 + @endverbatim + */ + int QueryAttribute( const char* name, int* value ) const { + return QueryIntAttribute( name, value ); + } + + int QueryAttribute( const char* name, unsigned int* value ) const { + return QueryUnsignedAttribute( name, value ); + } + + int QueryAttribute( const char* name, bool* value ) const { + return QueryBoolAttribute( name, value ); + } + + int QueryAttribute( const char* name, double* value ) const { + return QueryDoubleAttribute( name, value ); + } + + int QueryAttribute( const char* name, float* value ) const { + return QueryFloatAttribute( name, value ); + } + + /// Sets the named attribute to value. + void SetAttribute( const char* name, const char* value ) { + XMLAttribute* a = FindOrCreateAttribute( name ); + a->SetAttribute( value ); + } + /// Sets the named attribute to value. + void SetAttribute( const char* name, int value ) { + XMLAttribute* a = FindOrCreateAttribute( name ); + a->SetAttribute( value ); + } + /// Sets the named attribute to value. + void SetAttribute( const char* name, unsigned value ) { + XMLAttribute* a = FindOrCreateAttribute( name ); + a->SetAttribute( value ); + } + /// Sets the named attribute to value. + void SetAttribute( const char* name, bool value ) { + XMLAttribute* a = FindOrCreateAttribute( name ); + a->SetAttribute( value ); + } + /// Sets the named attribute to value. + void SetAttribute( const char* name, double value ) { + XMLAttribute* a = FindOrCreateAttribute( name ); + a->SetAttribute( value ); + } + + /** + Delete an attribute. + */ + void DeleteAttribute( const char* name ); + + /// Return the first attribute in the list. + const XMLAttribute* FirstAttribute() const { + return _rootAttribute; + } + /// Query a specific attribute in the list. + const XMLAttribute* FindAttribute( const char* name ) const; + + /** Convenience function for easy access to the text inside an element. Although easy + and concise, GetText() is limited compared to getting the XMLText child + and accessing it directly. + + If the first child of 'this' is a XMLText, the GetText() + returns the character string of the Text node, else null is returned. + + This is a convenient method for getting the text of simple contained text: + @verbatim + This is text + const char* str = fooElement->GetText(); + @endverbatim + + 'str' will be a pointer to "This is text". + + Note that this function can be misleading. If the element foo was created from + this XML: + @verbatim + This is text + @endverbatim + + then the value of str would be null. The first child node isn't a text node, it is + another element. From this XML: + @verbatim + This is text + @endverbatim + GetText() will return "This is ". + */ + const char* GetText() const; + + /** + Convenience method to query the value of a child text node. This is probably best + shown by example. Given you have a document is this form: + @verbatim + + 1 + 1.4 + + @endverbatim + + The QueryIntText() and similar functions provide a safe and easier way to get to the + "value" of x and y. + + @verbatim + int x = 0; + float y = 0; // types of x and y are contrived for example + const XMLElement* xElement = pointElement->FirstChildElement( "x" ); + const XMLElement* yElement = pointElement->FirstChildElement( "y" ); + xElement->QueryIntText( &x ); + yElement->QueryFloatText( &y ); + @endverbatim + + @returns XML_SUCCESS (0) on success, XML_CAN_NOT_CONVERT_TEXT if the text cannot be converted + to the requested type, and XML_NO_TEXT_NODE if there is no child text to query. + + */ + XMLError QueryIntText( int* ival ) const; + /// See QueryIntText() + XMLError QueryUnsignedText( unsigned* uval ) const; + /// See QueryIntText() + XMLError QueryBoolText( bool* bval ) const; + /// See QueryIntText() + XMLError QueryDoubleText( double* dval ) const; + /// See QueryIntText() + XMLError QueryFloatText( float* fval ) const; + + // internal: + enum { + OPEN, // + CLOSED, // + CLOSING // + }; + int ClosingType() const { + return _closingType; + } + char* ParseDeep( char* p, StrPair* endTag ); + virtual XMLNode* ShallowClone( XMLDocument* document ) const; + virtual bool ShallowEqual( const XMLNode* compare ) const; + +private: + XMLElement( XMLDocument* doc ); + virtual ~XMLElement(); + XMLElement( const XMLElement& ); // not supported + void operator=( const XMLElement& ); // not supported + + XMLAttribute* FindAttribute( const char* name ); + XMLAttribute* FindOrCreateAttribute( const char* name ); + //void LinkAttribute( XMLAttribute* attrib ); + char* ParseAttributes( char* p ); + + int _closingType; + // The attribute list is ordered; there is no 'lastAttribute' + // because the list needs to be scanned for dupes before adding + // a new attribute. + XMLAttribute* _rootAttribute; +}; + + +enum Whitespace { + PRESERVE_WHITESPACE, + COLLAPSE_WHITESPACE +}; + + +/** A Document binds together all the functionality. + It can be saved, loaded, and printed to the screen. + All Nodes are connected and allocated to a Document. + If the Document is deleted, all its Nodes are also deleted. +*/ +class TINYXML2_LIB XMLDocument : public XMLNode +{ + friend class XMLElement; +public: + /// constructor + XMLDocument( bool processEntities = true, Whitespace = PRESERVE_WHITESPACE ); + ~XMLDocument(); + + virtual XMLDocument* ToDocument() { + return this; + } + virtual const XMLDocument* ToDocument() const { + return this; + } + + /** + Parse an XML file from a character string. + Returns XML_NO_ERROR (0) on success, or + an errorID. + + You may optionally pass in the 'nBytes', which is + the number of bytes which will be parsed. If not + specified, TinyXML-2 will assume 'xml' points to a + null terminated string. + */ + XMLError Parse( const char* xml, size_t nBytes=(size_t)(-1) ); + + /** + Load an XML file from disk. + Returns XML_NO_ERROR (0) on success, or + an errorID. + */ + XMLError LoadFile( const char* filename ); + + /** + Load an XML file from disk. You are responsible + for providing and closing the FILE*. + + Returns XML_NO_ERROR (0) on success, or + an errorID. + */ + XMLError LoadFile( FILE* ); + + /** + Save the XML file to disk. + Returns XML_NO_ERROR (0) on success, or + an errorID. + */ + XMLError SaveFile( const char* filename, bool compact = false ); + + /** + Save the XML file to disk. You are responsible + for providing and closing the FILE*. + + Returns XML_NO_ERROR (0) on success, or + an errorID. + */ + XMLError SaveFile( FILE* fp, bool compact = false ); + + bool ProcessEntities() const { + return _processEntities; + } + Whitespace WhitespaceMode() const { + return _whitespace; + } + + /** + Returns true if this document has a leading Byte Order Mark of UTF8. + */ + bool HasBOM() const { + return _writeBOM; + } + /** Sets whether to write the BOM when writing the file. + */ + void SetBOM( bool useBOM ) { + _writeBOM = useBOM; + } + + /** Return the root element of DOM. Equivalent to FirstChildElement(). + To get the first node, use FirstChild(). + */ + XMLElement* RootElement() { + return FirstChildElement(); + } + const XMLElement* RootElement() const { + return FirstChildElement(); + } + + /** Print the Document. If the Printer is not provided, it will + print to stdout. If you provide Printer, this can print to a file: + @verbatim + XMLPrinter printer( fp ); + doc.Print( &printer ); + @endverbatim + + Or you can use a printer to print to memory: + @verbatim + XMLPrinter printer; + doc.Print( &printer ); + // printer.CStr() has a const char* to the XML + @endverbatim + */ + void Print( XMLPrinter* streamer=0 ) const; + virtual bool Accept( XMLVisitor* visitor ) const; + + /** + Create a new Element associated with + this Document. The memory for the Element + is managed by the Document. + */ + XMLElement* NewElement( const char* name ); + /** + Create a new Comment associated with + this Document. The memory for the Comment + is managed by the Document. + */ + XMLComment* NewComment( const char* comment ); + /** + Create a new Text associated with + this Document. The memory for the Text + is managed by the Document. + */ + XMLText* NewText( const char* text ); + /** + Create a new Declaration associated with + this Document. The memory for the object + is managed by the Document. + + If the 'text' param is null, the standard + declaration is used.: + @verbatim + + @endverbatim + */ + XMLDeclaration* NewDeclaration( const char* text=0 ); + /** + Create a new Unknown associated with + this Document. The memory for the object + is managed by the Document. + */ + XMLUnknown* NewUnknown( const char* text ); + + /** + Delete a node associated with this document. + It will be unlinked from the DOM. + */ + void DeleteNode( XMLNode* node ) { + node->_parent->DeleteChild( node ); + } + + void SetError( XMLError error, const char* str1, const char* str2 ); + + /// Return true if there was an error parsing the document. + bool Error() const { + return _errorID != XML_NO_ERROR; + } + /// Return the errorID. + XMLError ErrorID() const { + return _errorID; + } + /// Return a possibly helpful diagnostic location or string. + const char* GetErrorStr1() const { + return _errorStr1; + } + /// Return a possibly helpful secondary diagnostic location or string. + const char* GetErrorStr2() const { + return _errorStr2; + } + /// If there is an error, print it to stdout. + void PrintError() const; + + /// Clear the document, resetting it to the initial state. + void Clear(); + + // internal + char* Identify( char* p, XMLNode** node ); + + virtual XMLNode* ShallowClone( XMLDocument* /*document*/ ) const { + return 0; + } + virtual bool ShallowEqual( const XMLNode* /*compare*/ ) const { + return false; + } + +private: + XMLDocument( const XMLDocument& ); // not supported + void operator=( const XMLDocument& ); // not supported + + bool _writeBOM; + bool _processEntities; + XMLError _errorID; + Whitespace _whitespace; + const char* _errorStr1; + const char* _errorStr2; + char* _charBuffer; + + MemPoolT< sizeof(XMLElement) > _elementPool; + MemPoolT< sizeof(XMLAttribute) > _attributePool; + MemPoolT< sizeof(XMLText) > _textPool; + MemPoolT< sizeof(XMLComment) > _commentPool; +}; + + +/** + A XMLHandle is a class that wraps a node pointer with null checks; this is + an incredibly useful thing. Note that XMLHandle is not part of the TinyXML-2 + DOM structure. It is a separate utility class. + + Take an example: + @verbatim + + + + + + + @endverbatim + + Assuming you want the value of "attributeB" in the 2nd "Child" element, it's very + easy to write a *lot* of code that looks like: + + @verbatim + XMLElement* root = document.FirstChildElement( "Document" ); + if ( root ) + { + XMLElement* element = root->FirstChildElement( "Element" ); + if ( element ) + { + XMLElement* child = element->FirstChildElement( "Child" ); + if ( child ) + { + XMLElement* child2 = child->NextSiblingElement( "Child" ); + if ( child2 ) + { + // Finally do something useful. + @endverbatim + + And that doesn't even cover "else" cases. XMLHandle addresses the verbosity + of such code. A XMLHandle checks for null pointers so it is perfectly safe + and correct to use: + + @verbatim + XMLHandle docHandle( &document ); + XMLElement* child2 = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).FirstChild().NextSibling().ToElement(); + if ( child2 ) + { + // do something useful + @endverbatim + + Which is MUCH more concise and useful. + + It is also safe to copy handles - internally they are nothing more than node pointers. + @verbatim + XMLHandle handleCopy = handle; + @endverbatim + + See also XMLConstHandle, which is the same as XMLHandle, but operates on const objects. +*/ +class TINYXML2_LIB XMLHandle +{ +public: + /// Create a handle from any node (at any depth of the tree.) This can be a null pointer. + XMLHandle( XMLNode* node ) { + _node = node; + } + /// Create a handle from a node. + XMLHandle( XMLNode& node ) { + _node = &node; + } + /// Copy constructor + XMLHandle( const XMLHandle& ref ) { + _node = ref._node; + } + /// Assignment + XMLHandle& operator=( const XMLHandle& ref ) { + _node = ref._node; + return *this; + } + + /// Get the first child of this handle. + XMLHandle FirstChild() { + return XMLHandle( _node ? _node->FirstChild() : 0 ); + } + /// Get the first child element of this handle. + XMLHandle FirstChildElement( const char* value=0 ) { + return XMLHandle( _node ? _node->FirstChildElement( value ) : 0 ); + } + /// Get the last child of this handle. + XMLHandle LastChild() { + return XMLHandle( _node ? _node->LastChild() : 0 ); + } + /// Get the last child element of this handle. + XMLHandle LastChildElement( const char* _value=0 ) { + return XMLHandle( _node ? _node->LastChildElement( _value ) : 0 ); + } + /// Get the previous sibling of this handle. + XMLHandle PreviousSibling() { + return XMLHandle( _node ? _node->PreviousSibling() : 0 ); + } + /// Get the previous sibling element of this handle. + XMLHandle PreviousSiblingElement( const char* _value=0 ) { + return XMLHandle( _node ? _node->PreviousSiblingElement( _value ) : 0 ); + } + /// Get the next sibling of this handle. + XMLHandle NextSibling() { + return XMLHandle( _node ? _node->NextSibling() : 0 ); + } + /// Get the next sibling element of this handle. + XMLHandle NextSiblingElement( const char* _value=0 ) { + return XMLHandle( _node ? _node->NextSiblingElement( _value ) : 0 ); + } + + /// Safe cast to XMLNode. This can return null. + XMLNode* ToNode() { + return _node; + } + /// Safe cast to XMLElement. This can return null. + XMLElement* ToElement() { + return ( ( _node && _node->ToElement() ) ? _node->ToElement() : 0 ); + } + /// Safe cast to XMLText. This can return null. + XMLText* ToText() { + return ( ( _node && _node->ToText() ) ? _node->ToText() : 0 ); + } + /// Safe cast to XMLUnknown. This can return null. + XMLUnknown* ToUnknown() { + return ( ( _node && _node->ToUnknown() ) ? _node->ToUnknown() : 0 ); + } + /// Safe cast to XMLDeclaration. This can return null. + XMLDeclaration* ToDeclaration() { + return ( ( _node && _node->ToDeclaration() ) ? _node->ToDeclaration() : 0 ); + } + +private: + XMLNode* _node; +}; + + +/** + A variant of the XMLHandle class for working with const XMLNodes and Documents. It is the + same in all regards, except for the 'const' qualifiers. See XMLHandle for API. +*/ +class TINYXML2_LIB XMLConstHandle +{ +public: + XMLConstHandle( const XMLNode* node ) { + _node = node; + } + XMLConstHandle( const XMLNode& node ) { + _node = &node; + } + XMLConstHandle( const XMLConstHandle& ref ) { + _node = ref._node; + } + + XMLConstHandle& operator=( const XMLConstHandle& ref ) { + _node = ref._node; + return *this; + } + + const XMLConstHandle FirstChild() const { + return XMLConstHandle( _node ? _node->FirstChild() : 0 ); + } + const XMLConstHandle FirstChildElement( const char* value=0 ) const { + return XMLConstHandle( _node ? _node->FirstChildElement( value ) : 0 ); + } + const XMLConstHandle LastChild() const { + return XMLConstHandle( _node ? _node->LastChild() : 0 ); + } + const XMLConstHandle LastChildElement( const char* _value=0 ) const { + return XMLConstHandle( _node ? _node->LastChildElement( _value ) : 0 ); + } + const XMLConstHandle PreviousSibling() const { + return XMLConstHandle( _node ? _node->PreviousSibling() : 0 ); + } + const XMLConstHandle PreviousSiblingElement( const char* _value=0 ) const { + return XMLConstHandle( _node ? _node->PreviousSiblingElement( _value ) : 0 ); + } + const XMLConstHandle NextSibling() const { + return XMLConstHandle( _node ? _node->NextSibling() : 0 ); + } + const XMLConstHandle NextSiblingElement( const char* _value=0 ) const { + return XMLConstHandle( _node ? _node->NextSiblingElement( _value ) : 0 ); + } + + + const XMLNode* ToNode() const { + return _node; + } + const XMLElement* ToElement() const { + return ( ( _node && _node->ToElement() ) ? _node->ToElement() : 0 ); + } + const XMLText* ToText() const { + return ( ( _node && _node->ToText() ) ? _node->ToText() : 0 ); + } + const XMLUnknown* ToUnknown() const { + return ( ( _node && _node->ToUnknown() ) ? _node->ToUnknown() : 0 ); + } + const XMLDeclaration* ToDeclaration() const { + return ( ( _node && _node->ToDeclaration() ) ? _node->ToDeclaration() : 0 ); + } + +private: + const XMLNode* _node; +}; + + +/** + Printing functionality. The XMLPrinter gives you more + options than the XMLDocument::Print() method. + + It can: + -# Print to memory. + -# Print to a file you provide. + -# Print XML without a XMLDocument. + + Print to Memory + + @verbatim + XMLPrinter printer; + doc.Print( &printer ); + SomeFunction( printer.CStr() ); + @endverbatim + + Print to a File + + You provide the file pointer. + @verbatim + XMLPrinter printer( fp ); + doc.Print( &printer ); + @endverbatim + + Print without a XMLDocument + + When loading, an XML parser is very useful. However, sometimes + when saving, it just gets in the way. The code is often set up + for streaming, and constructing the DOM is just overhead. + + The Printer supports the streaming case. The following code + prints out a trivially simple XML file without ever creating + an XML document. + + @verbatim + XMLPrinter printer( fp ); + printer.OpenElement( "foo" ); + printer.PushAttribute( "foo", "bar" ); + printer.CloseElement(); + @endverbatim +*/ +class TINYXML2_LIB XMLPrinter : public XMLVisitor +{ +public: + /** Construct the printer. If the FILE* is specified, + this will print to the FILE. Else it will print + to memory, and the result is available in CStr(). + If 'compact' is set to true, then output is created + with only required whitespace and newlines. + */ + XMLPrinter( FILE* file=0, bool compact = false, int depth = 0 ); + ~XMLPrinter() {} + + /** If streaming, write the BOM and declaration. */ + void PushHeader( bool writeBOM, bool writeDeclaration ); + /** If streaming, start writing an element. + The element must be closed with CloseElement() + */ + void OpenElement( const char* name ); + /// If streaming, add an attribute to an open element. + void PushAttribute( const char* name, const char* value ); + void PushAttribute( const char* name, int value ); + void PushAttribute( const char* name, unsigned value ); + void PushAttribute( const char* name, bool value ); + void PushAttribute( const char* name, double value ); + /// If streaming, close the Element. + void CloseElement(); + + /// Add a text node. + void PushText( const char* text, bool cdata=false ); + /// Add a text node from an integer. + void PushText( int value ); + /// Add a text node from an unsigned. + void PushText( unsigned value ); + /// Add a text node from a bool. + void PushText( bool value ); + /// Add a text node from a float. + void PushText( float value ); + /// Add a text node from a double. + void PushText( double value ); + + /// Add a comment + void PushComment( const char* comment ); + + void PushDeclaration( const char* value ); + void PushUnknown( const char* value ); + + virtual bool VisitEnter( const XMLDocument& /*doc*/ ); + virtual bool VisitExit( const XMLDocument& /*doc*/ ) { + return true; + } + + virtual bool VisitEnter( const XMLElement& element, const XMLAttribute* attribute ); + virtual bool VisitExit( const XMLElement& element ); + + virtual bool Visit( const XMLText& text ); + virtual bool Visit( const XMLComment& comment ); + virtual bool Visit( const XMLDeclaration& declaration ); + virtual bool Visit( const XMLUnknown& unknown ); + + /** + If in print to memory mode, return a pointer to + the XML file in memory. + */ + const char* CStr() const { + return _buffer.Mem(); + } + /** + If in print to memory mode, return the size + of the XML file in memory. (Note the size returned + includes the terminating null.) + */ + int CStrSize() const { + return _buffer.Size(); + } + +private: + void SealElement(); + void PrintSpace( int depth ); + void PrintString( const char*, bool restrictedEntitySet ); // prints out, after detecting entities. + void Print( const char* format, ... ); + + bool _elementJustOpened; + bool _firstElement; + FILE* _fp; + int _depth; + int _textDepth; + bool _processEntities; + bool _compactMode; + + enum { + ENTITY_RANGE = 64, + BUF_SIZE = 200 + }; + bool _entityFlag[ENTITY_RANGE]; + bool _restrictedEntityFlag[ENTITY_RANGE]; + + DynArray< const char*, 10 > _stack; + DynArray< char, 20 > _buffer; +#ifdef _MSC_VER + DynArray< char, 20 > _accumulator; +#endif +}; + + +} // tinyxml2 + +#if defined(_MSC_VER) +# pragma warning(pop) +#endif + +#endif // TINYXML2_INCLUDED diff --git a/Release/Exportall.ahk b/Release/Exportall.ahk new file mode 100644 index 0000000..32b9f26 --- /dev/null +++ b/Release/Exportall.ahk @@ -0,0 +1,131 @@ +#SingleInstance off +#NoEnv +#Warn +FileEncoding, UTF-8-RAW + +; Name of function in DLL to export a drive's index +DllExportFuncname := "ExportIndex" + +RunAsAdmin() { + global + params := + Loop, %0% ; For each parameter: + params .= A_Space . %A_Index% + local ShellExecute + ShellExecute := A_IsUnicode ? "shell32\ShellExecute":"shell32\ShellExecuteA" + if not A_IsAdmin + { + A_IsCompiled + ? DllCall(ShellExecute, uint, 0, str, "RunAs", str, A_ScriptFullPath, str, params , str, A_WorkingDir, int, 1) + : DllCall(ShellExecute, uint, 0, str, "RunAs", str, A_AhkPath, str, """" . A_ScriptFullPath . """" . A_Space . params, str, A_WorkingDir, int, 1) + ExitApp + } +} + +ToHex(num) +{ + if num is not integer + return num + oldFmt := A_FormatInteger + SetFormat, integer, hex + num := num + 0 + SetFormat, integer,% oldFmt + return num +} +;returns positive hex value of last error +GetLastError() +{ + return ToHex(A_LastError < 0 ? A_LastError & 0xFFFFFFFF : A_LastError) +} + +ErrorFormat(error_id) +{ + VarSetCapacity(msg,500+500*A_IsUnicode,0) + if !len := DllCall("FormatMessage" + ,"UInt",FORMAT_MESSAGE_FROM_SYSTEM := 0x00001000 | FORMAT_MESSAGE_IGNORE_INSERTS := 0x00000200 ;dwflags + ,"Ptr",0 ;lpSource + ,"UInt",error_id ;dwMessageId + ,"UInt",0 ;dwLanguageId + ,"Ptr",&msg ;lpBuffer + ,"UInt",500) ;nSize + return + return strget(&msg,len) +} + +ExitWithMessage(msg) { + MsgBox, 16, % "[Autohotkey message, will auto-close in 30 seconds]", % msg, 30 + ExitApp +} + +Class NtfsFastProc { + Description := "Quickly process NTFS filesystem metadata on a local disk." + LoggedInitError := "" + + Class ErrorModeHelper { + __New() { + ; prevent error mode dialogs from hanging the application + this.oldErrMode := DllCall("SetErrorMode", "UInt", SEM_FAILCRITICALERRORS := 0x0001) + } + __Delete() { + DllCall("SetErrorMode", "UInt", this.oldErrMode) + } + } + + __New(providerDllPath) { + global DllExportFuncname + this.DllPath := providerDllPath + foo := new NtfsFastProc.ErrorModeHelper + this.hModule := DllCall("LoadLibrary", "Str", providerDllPath, "PTR") + if !this.hModule + { + this.LoggedInitError := "Failed to load provider dll: " providerDllPath "`n`nMake sure it is a valid executable and that all runtime dependencies are satisfied.`n`nMessage: " ErrorFormat(GetLastError()) + return this + } + this.QueryProc := DllCall("GetProcAddress", "PTR", this.hModule, "AStr", DllExportFuncname, "PTR") + if !this.QueryProc + { + this.LoggedInitError := "Could not find a '" DllExportFuncname "' export symbol in provider dll: " providerDllPath "`n`nIt may not be a supported dll or the file is corrupt.`n`nMessage: " ErrorFormat(GetLastError()) + return this + } + } + + __Delete() { + if this.hModule + { + DllCall("FreeLibrary", "PTR", this.hModule) + this.hModule := 0 + } + } + + BuildFileDatabase(LoadExisting = true) { + NTFSDrives := this.GetIndexingDrives() + for index, Drive in NTFSDrives + { + ExportPath := A_ScriptDir "\" Drive "_export.xmlz4" + DriveIndex := DllCall(this.DllPath "\CreateIndex", "ushort", NumGet(Drive, "ushort"), "PTR") + if (DriveIndex) + { + hSrResult := DllCall(this.QueryProc, "PTR", DriveIndex, "wstr", ExportPath, "int", ExportFormatAdcXml_LZ4 := 1, PTR) + SoundPlay, *64 + } + } + } + + GetIndexingDrives() { + return ["J"] + } +} + + + + +RunAsAdmin() + +DllPath := A_ScriptDir "\FileSearch.dll" + +fastProc := new NtfsFastProc(DllPath) +fastProc.LoggedInitError <> "" ? ExitWithMessage(fastProc.loggedInitError) : + +fastProc.BuildFileDatabase() + + diff --git a/Release/FileSearch.dll b/Release/FileSearch.dll index f2618a98eeb1d8787efa23278835fe9d654f5934..b2942d97ec34763d5c79eb8b5c244ea8fec21bda 100644 GIT binary patch literal 111616 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 z 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 delta 29070 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 W%~Z`M%?XWC8>>yzlEJn#@P7gDr@kBj diff --git a/x64/Release/FileSearch.dll b/x64/Release/FileSearch.dll index 2d18dd52dfe6af89b2bef4bd40aa53f271a41436..976052595394b7f9555c072496ad62f3aebf8e05 100644 GIT binary patch literal 142848 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 From 7b4095489a71149c8f1883e72a79a8b40565bd27 Mon Sep 17 00:00:00 2001 From: Anonymous Coward Date: Thu, 22 Aug 2013 03:01:46 +0200 Subject: [PATCH 2/4] commit fix for small extraneous byte issue in XML stream --- FileSearch/CDriveIndex.cpp | 4 ++-- Release/Exportall.ahk | 11 +++++++++-- Release/FileSearch.dll | Bin 111616 -> 111616 bytes x64/Release/FileSearch.dll | Bin 142848 -> 142848 bytes 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/FileSearch/CDriveIndex.cpp b/FileSearch/CDriveIndex.cpp index de31eb0..66d80b7 100644 --- a/FileSearch/CDriveIndex.cpp +++ b/FileSearch/CDriveIndex.cpp @@ -187,11 +187,11 @@ BOOL CDriveIndex::ExportToFileListing(wstring &strPath, int format) const if (file.is_open()) { if (format == ExportFormat::ExportFormatAdcXml) { - file.write(printer.CStr(), printer.CStrSize()); + file.write(printer.CStr(), printer.CStrSize() - 1); return file.good(); } else if (format == ExportFormat::ExportFormatAdcXml_LZ4) { - int const uncompressed_size = printer.CStrSize(); + int const uncompressed_size = printer.CStrSize() - 1; int max_compressed_size = LZ4_compressBound( uncompressed_size ); std::unique_ptr compressed( new char[max_compressed_size] ); int const compressed_size = LZ4_compress( printer.CStr(), compressed.get(), uncompressed_size ); diff --git a/Release/Exportall.ahk b/Release/Exportall.ahk index 32b9f26..b9040ba 100644 --- a/Release/Exportall.ahk +++ b/Release/Exportall.ahk @@ -101,13 +101,20 @@ Class NtfsFastProc { NTFSDrives := this.GetIndexingDrives() for index, Drive in NTFSDrives { - ExportPath := A_ScriptDir "\" Drive "_export.xmlz4" + ExportPath := A_ScriptDir "\" Drive "_export.xml" DriveIndex := DllCall(this.DllPath "\CreateIndex", "ushort", NumGet(Drive, "ushort"), "PTR") if (DriveIndex) { - hSrResult := DllCall(this.QueryProc, "PTR", DriveIndex, "wstr", ExportPath, "int", ExportFormatAdcXml_LZ4 := 1, PTR) + hSrResult := DllCall(this.QueryProc, "PTR", DriveIndex, "wstr", ExportPath, "int", ExportFormatAdcXml := 0, PTR) SoundPlay, *64 } +; ExportPath := A_ScriptDir "\" Drive "_export.xmlz4" +; DriveIndex := DllCall(this.DllPath "\CreateIndex", "ushort", NumGet(Drive, "ushort"), "PTR") +; if (DriveIndex) +; { +; hSrResult := DllCall(this.QueryProc, "PTR", DriveIndex, "wstr", ExportPath, "int", ExportFormatAdcXml_LZ4 := 1, PTR) +; SoundPlay, *64 +; } } } diff --git a/Release/FileSearch.dll b/Release/FileSearch.dll index b2942d97ec34763d5c79eb8b5c244ea8fec21bda..9486d9b7569ad17b676ca0748367f4078d916f5c 100644 GIT binary patch delta 246 zcmZp8!PfACZNd+x{MQqI`7vi7VBGA@s3{_TmYIQ}+m*-qFn{YFMj*3AC5DB8!DDil zs4L@|$rnVAF;1O4U2K-zDmF%jZWk4qmux`k<{ymwt$#tvd%(&)C;N#zF!oID7oWfw zJy}6QkI`nbzeFHo*W`r~Q@EG1Ff!}_DrR`eFxf#;jY%YYvZ92>G@?&lmVcP7?s3{_Lnwf#2+m*-qFn{ZAMj*3AC5DB8VRE;q zE92V97e$XTPMbVKY?kb5Hb#bS7ZsV8>_FM(AB_C1e?Y2xAgTkz9T@v2PZXcP6dN%) zOHzZaw?xI@h27*pi9n{FfXOq(v?rgJ$lzYi!pN`#sEy$z(_|+}HAbkn=@U1wtZSZqZqI0Y{Q3!Uk(2oHW{rp+F^9m x=(>@LagOm;7b zUm9@6e1R2DCkv1)%=?A+r9Iqc1toVtw)5GC=H`?`GZ_VPM8>Q2{I zHOTX+X`%U)OgI7usE+V=Y=i1Jq*O9jX9>}hNpz`b$K2Anx=e`VIIN@;(#=A2;_=b0 zxwc3q;VOu&P=e-sB^)n<<8vpdr#5#Y8ZNeov z>Tx^Uv4CE^u=GXLZ236LwXh~Jnz@U-5jBaHz8pKo9LZDLTbp}XFa^uKmVRyzHG^iq z0_099N`)~`0u=twn5zhO8m-6tWh|I#2pDAPMe4kocFM0_m-EwR)oI(MmOXON?a>wl zbdRH$2qo8KJB&L5Xz^a+}H~F zR6Sb>NB2Mf0ox~@pnUpS3!mKi+4LH?a%2}>39FP#(RsJW{CbAY-9l0})F>ZhmGBYy zGt0N;1NOJvKZ7s}CQ-km-$G-ZPr_o%gzc2~?`Kh=;^R%Ywv(C{Y z7wPfw!&~r$Mp8rkw2Q|_`p)ttD?%x=7@L9{v%w6oAf{J?$gON z8$TEuz-iz?&6S_8=wa)$W=1Lwqjyo90$`8dkA{LS$VcD0;#|i z;B;_(OgDj4;2V$%v_L8_Bi}CYC`h9X%mFWe*z&;MrViD&4EC#~t@S*dFu=m*bV+ohc@tNg>oSTtpOQ&MNFeP61$fH7`;@h6VC zh%wu^D(&*fy0%`%M!6Mbd>_x}mg{xD#`s9v5mPwT(|C`z%Xx|KK7hjleX~~hj^kr+?;#lw?X+TSmF(IQE$c`$fj32fscYveJ(=M+&nu1Vz z)9i$t3WS#4>eX0OY|Z1MBi!J4b49v?{&yr2nB!gB*e2_P=K2*qp z`}W@xRp$%6xweQTT}1En?TBU TWVXy|dFA?8Hq)l-*CYP`SF>tJ From ce676bff2f4a7e0b649d60f074f7baefe02a7ac7 Mon Sep 17 00:00:00 2001 From: Anonymous Coward Date: Tue, 14 Jul 2015 21:21:07 +0200 Subject: [PATCH 3/4] Have CreateIndex() export return null if very few files found (unaccessible/BitLocker) --- FileSearch/CDriveIndex.cpp | 6 ++++++ FileSearch/FileSearch.vcxproj | 7 ++++++- Release/FileSearch.dll | Bin 111616 -> 106496 bytes 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/FileSearch/CDriveIndex.cpp b/FileSearch/CDriveIndex.cpp index 66d80b7..061865c 100644 --- a/FileSearch/CDriveIndex.cpp +++ b/FileSearch/CDriveIndex.cpp @@ -46,6 +46,12 @@ CDriveIndex* _stdcall CreateIndex(WCHAR cDrive) CDriveIndex *di = new CDriveIndex(); di->Init(cDrive); di->PopulateIndex(); + DriveInfo info(di->GetInfo()); + if (info.NumFiles <= 2) + { + delete di; + di = 0; + } return di; } diff --git a/FileSearch/FileSearch.vcxproj b/FileSearch/FileSearch.vcxproj index 8157908..bf1700a 100644 --- a/FileSearch/FileSearch.vcxproj +++ b/FileSearch/FileSearch.vcxproj @@ -1,5 +1,5 @@  - + Debug @@ -28,23 +28,27 @@ DynamicLibrary true Unicode + v120 DynamicLibrary true Unicode + v120 DynamicLibrary false true Unicode + v120 DynamicLibrary false true Unicode + v120 @@ -73,6 +77,7 @@ false + C:\Program Files\Microsoft SDKs\Windows\v6.0A\Lib\x64;$(LibraryPath) diff --git a/Release/FileSearch.dll b/Release/FileSearch.dll index 9486d9b7569ad17b676ca0748367f4078d916f5c..fc5e9d6c845719609bc204cee21a819918e59cfb 100644 GIT binary patch literal 106496 zcmeFa4R}=5wKqPK8Il18&Y+0~O(oXYrXA`{4VJ{gYrbX@l)!|Kgcbq4RT@*Tr7#0p z2_H^IIo+O?dn<2ktGBkL@1?!=Uhlm|sf9KHnh78Bp_F3bwz1{5CnisgABBLF^ZtH& zpZQ8ctG#{x|L1+4HxJC&XMe7}_F8+dz1G_MG=6G}!{u-|-1u)<4#y5W`Bx=>|Mbr= zk|$4lakAsN@h@Gw!#U@rYZtcOySjMgs?U99)m?vI{OP;yzyEWQ;=jA6cvbZN;(PBe zuA8@@`0qb=_dPdEnlz!rt~$D*?e>pf<1S48pEc*z!kh5^Z$I8sScd1UIVTHml+V+J zx5(#z7tX+Q@U_G8`SEMU73z4O^O@HQXUgXZyWFqjbIxaeA)oW_{d6naNcJckbU5ZX z$2ne^@a;v(xIRbDwG*9Qbl&N3+^J&knu)Lv;V_;IF`VOY9W-2ogpF2nOnqw>`t z_W%9;6)?~`G}q}f-!5@FKDp;0{#yI^{+sms5x&2YdS4_4+pN~-<~V(Ke~ZnBo0?m` zg@N~#|1@j_-?{rcjBJ}>6_m_(`owT-uUl^)N(3)3I&MWSYjcRhR>8us)0fB_Y}hXCo)+4D_DsHF{DR_ni0iOw+bSNitY7$=ee&teW+oMnDhW*tb&cqI*GC27OP+m z-r5{($iGsXs)j!W^-8@Zb&tz1!@i%b#D5um1;LHRR5 zkF#04naF(>{fOQ@}y>z!HJ6XcxG!_lV20d2P zGv5k(kykXh1Gl-OlZ7LY6ZJgn1UgXg#xC{D=xwq;fd+SU5^@K<(cEX9Dzj>9$0@*; zf?notYPOFLU%rTWN7P-uZ$L8|cNk5n@!H>ns>GqN`M)*;r;QgxPx(vB%>HYf z4luh-vfU%i;rW1_^?=0h)2GfC)}bpzArjntSO0~ zi4KxlPv3Ik|l4Al{8f zj*N(XLdHIs6}voRAKVpM3(&N8Ce1Nk}c^5ja2j6Ki z))%hOgQpY0;XL#LgRdTvaaZWMdc7}EFXL9|c}DPbU?@@hRugR=WxW@hdrw>F`Z844fe5qw0O`69!vyJ;l&XcMx7gEoimg9RGW!<35Pf= z8$TE}Z;*BN$vO|pyprmcCqiYcsr;oxXa)m`Pz4{$mY8=GWe_7M661mOaY0pjeOxfc z0twtihemdd9a~li9!k_ojOew#6}n5bdwQ@G2F^ytw^`v9^BVxss4onhh*@ zw!Mn~$b~qLtC;IUeXDZBCos#eQ{Lw(3_BXxSSA#ziH<5_W?8%8- zAN$Q8W9_CKkz>|zMG-+$Qc>_U2LXe9?93i#WOA(ih|IQAX8R&)$y~CRh{nP4m&|9b zlH-+{Bosc*Wa6VFg^!_Ze7rew#PsMf4%&J-Xo{pj&>$uZ1;&AcAh|&gnt<|z5j>Fy z4ifbDO6DiR<~QymnGedIok)_eswGvYNj$t)GDn^Dqv}j3Tqc6DDnQ8^!Db*mSJ;?a zW-e^PIJcjM0G4k>kBLQQlQ?Yt+jfVeg)n&&p;;^;dJ>^31`?q<%5x(}U7F$YlE(xH?*+(5+`k#c^Z5MkHzd+ct~^^BIzlJm)9Y2<7g zG_mJQk?07PeHF`(X!nZ4dc5=;@E`Q)ai0w2i}x`oeXR7+rYb4C$k#yo%j_8tWMSwHi!Ne1Fb}RA(JM?yI7>d!sgB})*)=3 z!Vl*uBfb|Q&SYUb<>fXYw{sg}H(hjN&RAP3jO~0o$G6B$tFLTsWymldN32=ff$TCv z?3_oJ<%~E}v|9Nn-?u{du2fOtK-lVJx2#U~)vUh(JhY2VxwMB{09K(QiDgBs{j@{tC_oKu-qtdTHQqLt4dBC#avJM6OPCd=4g;YI zRrfpq=<`G;2c=TRMX$6vi7ld&Xl=`BX*MT=CP$V12+PVcfjq6_2~;l{d=Nvtn{|Uj z6yK+HJdD`bE{=50i;Dr5nC;#%2Tv`yJ8TX^uVZW_{>2HyxEoLNo&%_52*Z(sS=q<= zxb;pJJ79j}4-Q9Dv(ex)U+W|CnVrLC=G>lYB6^$Zm;RLOoshI<7$wMRt#mhuUbA2x zVU{F#SV-dWm)SJdeKE&;1j%|?e;4>MITUgb+Z^_2wmKZeIc+ZN=$u&NtOBSYxSJ$# z2^4BWWi!xPB3_1HL}2F^Hh(=$?xPGD$xWdfrOv7>ZigeUG>T8T!^qa>kpQN zbxPvGmBK}0N#f#XzskbJnc1B93Os~Lj==)c^*VD%ng{Uc)(KSaS*2N>M0|P= zHpZG%n6K8PeC)j-HpSK#c~*I?HJ(%p4Q&zG2?W( zM21R<9ON&QQq@FARmn`YT*bUeX$*C$^{}ocH5qRjoRvA>j93!S#oE12ZW!W6u!Gkg zU4~W@@y8HmyNURgROoR#gvs5WGYn$~N8tPCfUQ9(vV#LoT`{G?nK;+oD!EWC*mH2 z3FZoY>o6D(;`kJQ_tD`nCIr5l;m?q77(@+j!|)-$=|?kS=*7Z?*zE-`j5CZXHWPgm zvByF9&tR|hVm=ZPz7vrz9w909nhOy&wh~Uf)H7kTN(dkv+f{-DpAr^UO|&}Ml3eQv zdTbYg_9WuWq)D_EBSgr1;>_t_5rQd;7%~pCtnB|z)&Jbs1Cq@hO-PVv-*YkD?od{n z@iXEkZdf9DqaP5{dX;dkFRTF@zHFUi&=}KWK*lZr+Z6`TqAmD&`gY=M|mp z?>?U+c6Xc8T)QLJ+yVe^T{E%OyNK!=M-vn`hQT_`M=6gCV#uE6o4yKMXT-Y@MtvU9 z$#x8bZHCSJ-okIQAt6W>-+mjA-^p~N-sA6Nm8z;R=bEc9Z|P;1g6g*NGvy~meG#-$ zkutY60}~5@Xv+y>#gZ+4VHjgJuh>{qh#tvm&i2=)`xQ75?NS3L>ht~ezV8j8n~^G3 zYusG|x!gChYOH{E)zesYeZH~Ahk~_`F;LkdRT6>I~JVqL|CaY8~e^hb^bSp;|) z9~N?0)Noqi3gXHzdXXyPd-*E|F%f53?mPqCk=(EpjYWJL(hXxfelufN%GgL&EO?=h z1pYYWKeRAGNJa-Wd9Y|Wn%Zu}Ae?4~udL?sr*exp%Rtpv<&JvWa$LPu!E=}@2PU*R z7_MTscFh1>SWK~*cR;}cjo9C!ZV<7mqTy@vv4%fKqAuv-G%KsbM!U*g`PjHYRIfeW ztxKX1=lV~A7oeBX;ztk=2CLbzY2(I?v(NVH24^PM(O9>y`+S~FjIM4>6s4eXA%)3K zo7N_Z<5nlL3xh42KRJwQ_k#1;9WiXkz6W;696#3@w=#ew${p6XlKK>+j7ZTZ3nn|j zEaH$V{xz*pHZh-*O*#|ALh9?teQ5V5K#hY6Qq_5MJ<&0anYV$1?6?NEQT?>uF^Lk4 zJrb4JPhlpNE$;;CFhxn=o|S0ajxdy*C1E*PB;tHWGnlKNNrj%ZLqhU`@aR~}$rXB) zTLlvFZFUw+n)%}6P1Y+a0Z^lhL(xH04>Ck1#AG(dDAnBP*+Wq*s4PdsIeDoLGxUz^ zu#97epFoGFBl=9d1HaBhyaA8rkS8)p#1|rLmC4>wAq>&eV6s(kO7?#-!YU>~IMB0J z#3aKHq{6Z9vhItC_(nXK(JI(1kr~FjRd7&-pO9gN*kh7*PvAEpd2}Stk)pt?_|4?G zjWV_)D^{_zs)ec^V8mg51+s`pfEv2S+Eo2)q7ospbX`=C31_qM`Br1@vqWZH*%K0z zp(jMxZPYxW*WLKI`C>iDW$q5uC2?q(bv^qdm23FvUlMX;s)S{IcN%lIsrsIlq!@Zy z*7r2(d(wPy9_!m~6_EBu)tB1u{d-!(hz+*d+daLmP-L{uk*_mTbhRmG8r*ZdM*bh^$zFlBGQzGQ|n9 zyf$piDY?UJsX}sHN%4=!aCUMI@|O&7lUa;NM+-96nKx8Xr&)w>VWOi1I}!&K8&WAc;Z= zBvh2|t9lV5=Q#UoZA4~bpOoENyX>?Q7IDcqGR{VH0QXqS`# zfGbd?M0+XBDOaMfPb@4cYBK-ps~FA*v;fe`dPUCwH|jb1HFAglKyrt_eAyCo=g#tj z<}#0ByP_0}fW9FPgR~}Kg|X-HOruMR{>Rm(MC{mLX`23vv+2LWrvG+o;_fJ+1?-Nt zmD!pQ(tH&FEg_K>nffgtVi1&5l5>4Jaujy?A`pfBM zPDw>}Pm9shNS^BH2=fv53rc@ek=dW(bbksnRXL@0Z=h_!l7A*r0YuFp4|>g4pg;nw z7@HX!8}m2Ny#UA}Y|SK?5QpsDO$yA?B$&$pb0L5{oI7e3c`gye?CNkxsm|V=NTF2^4g=7)wa*2I-qtqI>X2w^Mw9u*<7jhD znIv{w#htC-j;#lgc&s&rl8Y|6t)#M^W{iuzLB})<~3XKXYY;KD*E4cv32EVVFs=Yq&RNVU1wO#J0&I;LUEAn@x(x}SNbAQNr9(d4#=Tt=?I|u=mIUVsLAsUC0 z#Ld~Ju@8#VH(f~<6tZa{L5y3l!)9SLZ49&fZ?(2&GG|yZCptZprS5;zXxwfNniz`V zSWl_V2CzFwJ3|ZlUEG3|y}r)5T&1owWQ=I{uye1*lJzYrESBK9&e>CNNY?&7OpjldzP(jNJOx z`%pZ7Qap7B8|nBggouG$;~UJ5wiO&`ReK@7N#Dw*jN87sB6e=7_ULy(w%QBl%lDPP zY^?pJ_AhV7E*5LGN6YueE>O$X?>)BnHmGb;JsRPv)^C4Wwfe-80>4R<4m=3AqI zQT5!TbzmMJqkb)ZL%M?NR0VfM7mTXley!uDBTy;(7126=Fjo9(E&ek!XhXIiK|r=D znm?-Idj{H&a!)imDrHrqc~so$6h79D)t&oO$&1HIzFUh|rGdIh0d?;fK;1v^GXV9u z=x6}$k93a$YDKEmUyp@~Ra$&M;%!v?1VPjdd@cnMAp}hQ%UH!CTKp^NVx)WHwj;%{JfzZjSwJAXrTT$h@D>_85cXhJnD)a zs8SSPqnItQRq}KEDQrKXL|ABSj-7|=%BBMw0qcNgeJ*+o6j#U2T@`&z$jpg2xf98b z*!jFQ<6h)6Q@*eJ*B_YJJMk4=@{cYv0>`TgZ7Yt5lU*se%A|oD(VaE#VJhdu_aP|X zlnaBJ?{2EgSejr_zSMjtuvp}y0c?lFQf`J4ad#5P2Yn9R7zE$zPf-`BOZ8?V&Q%2! zVt-F9BD<4_zk@gx^4W1(d?z9}oo-`4!>!yy7>!#J!Kd*GNjbR1tcG4eDW{CJrABZI zjF^6@RsJ)!`YmDeIQE3G_HELLxkV`+E@5!AC+M&-Z?V}2Nl-*jLr#RPy&uCu=b`>ps%rAvxE1l5#VxPbaS_Wr-o%&_5BVxD(P$b? zIRh^2$5seutUG4~)LVb>?>~AD4lQQbXzViI!N#x62`p0G5w@a75DCTiEs%PZ@f#NL z$K!9K)3Nqr5^r58>o;ha(c7R%m+dElRC^JyE;>VOkr_AcVqpiAxLy5sPeiSfHrScR z>;)6cqwOaY2 z)vC7_+@Ashxk|3k-OGT%+Q8Dy(fvY_q%132ft81a^*Behyeob(Qi2tHfh0IdfO_z0 z;@1E{!`;I1!KFmwidd)tmsL6HGGy7j+Pw4DP@(;n3p_1k1Zf zt%=}HSthtc6$ox$Jrz=ARpc5t;~By2&4Azbw;Px!a`oW$1neKcU&yD!87Y*n2X_LC zBOO_QvT@8MTT&yqJttBX>-%GD7vY43gfOg{Vo9*9<0>aG1P#TQJ&~ORb>wb$Mn0Hk zo}>$eL{kQPir@}N#+Bt(CIiIUcY2KIcI^fC16pl#dwOWrqhXY&4-7{S3pu4=3^Y_Q z5h&2(r!Xu76B6>t&LeSVY{PvJhGQGx>+cq!D!sl{gzAVFVKks-z5YIIX=?2WV(T14HJMjn39>qwtcHRd z;f0zI5$sMP&TJ|awnGECDr;<49b!DRh?F6aWV$$GNjR}x)0v)#SK+}bKy%E<0_>?Q zAR0HrJ?sjIq!2=brf4)pa8Nf$0RxvSwlgn-`0E!#DZ}w{BOYsUffW{o?X{ZC0!cK4FbrO|Bk$0^^KmPh#eeV9Y5$ zS-JE`N3E!R=@v zY;FKim7nCUYwI34t$M9!S8BrvBCk*jifAmVg5LzX7CUD}Jb`ZQ%lj1gt{#|OJV=0> zz@TmGz87;8a24yR5(d!$d{zUYx_nWn2=r?4w}6LK^^%#U64#N-*@ipN-41?BF3k3P zx!;<&U)d&ggCoc_j)HUSAs;aMDH+Q5Xb%@~v|Rl@Jh0xZfK#p)i%x8J&fNarW9Oy4 zz__csVtp5@`u`gdv0jWJN0MV${<7+-zLlav|KA~+6bPQoU}{NZ=B+TL5qllXltnpB zGU9F#Ez)JhwhP7=MPzuw z6iPdD;5v9Uuu;fz^c=uL8u&XGBeJ|}qLc^A_rZS#?<1Gq#x778W+hKka~Pgc_e{cw z$c$)1v=lcf_pctsFK|mi6?*iPSX%`5R?ZQ9w(FJoBN&iHFQzO1AzL{G<0BMP{zJCy zO0}O%lSG!bM#lETjIGt}$3%Li;hs%Vx5t-BLIdMs`>csaIe$tHfacof03k_?TqI52 zLQ0O(sP;B6sEp8#=nAp>x^C)kmd5vO_~bgzrt`iJI~=R$#db;B6>^BR_|2d!MFZk6 zq?;l|0icHF1%GOsFM_1|sfrs>-2kF&l451`KGXz6m+!-B1*WL$4uiNx5)YzCJQ$6& ze-E54EsDJh?=^VI0QXjOq9qBne+#Ns6CBz`h-`s?W8g~F7r1>zKWBr3-Y-R0SV4FJ zKrrfy0EHsrvAUIp;HRt6Cp14L*}O+JKaihpF+I)3+VdTe4~k|tR))#`?kuXo%n~*q zc?8w%^-!9V{)7;oATFIS8c!Hfu(F9MZ2o-^h(p5i(!dF=;|mxSDIQF;%2U%GDpCHX ziCU>jqt9vMAe^jL7lA3NB3Dbf=ma_}0ghK;AqhK*E>N*`ZH{2U%B@~t2n|ASTqwObwTE8@ zNm|hpss&lD|EGvbYDm?7@GF`7K@Vi{l>RH*-%mH*!Dc|T7eh-8uR=XOjMq&Yd~ly} zh+v5xzrf^R8CD@o`}!^if8$=R36FjTo*nGh4oWq2EjAjr*>3xwrETVowH&+)IYve63yBEt*rVmjme>nB3aScc*&KQAVZ4ZD!f0WCkE2 z>Ca0K?^yc|sJ!w4lM&p8rFt7TYxz`?#yyCX>&*{<0yUmzvu7UNNRX63R@}u@+GAjg-o#tKWaGSIBAYcb^x)5bW4`NUDJ@kXp z(GM^|wB@uOK{^tUj5Nbe`vjUkl;fE{7Rc^xF zA{S%RW38cnvhkSt74!y*7s@)_MEDBr{%&naR}!dI=)*DV6*zTE7&+}r>d^jX+|EzI zVE9NsfCjSxe$hDHa!5g_(xZL(IA?aH|8yLI`vb&ybOZ=7@xwM~F zzyyz(AE=TfJZ?;mh)kpt6S`avcvr-Bk?_>HmckSjUXuQfnMa{Yw>l-pC0iT8V^(y! z6)m+o*}E`SKCC&gG(&QMzZasK&6nVSphhWHVMQ9Vk%UeHZAqti@)}$)0TWg%a+Xz4 z2rlC`;h$00Ko#gVL7@x&SRcgtSC(B_3M;J9rdu%EF;0>@Dqk3>JkJxyjXyL3D>=MBl3-n;GsJX*mvshnr zP;Wfe+=6LPZ$D*kL}q{?#nLjpv5(8HCvZSBu4UA!#ja?dj`_EFhS)DcW!E+4Ul;Uk zdJWy476|&Z_#V)ApfO*IzlcEh>mP`<7df;?e}I=&<0}^xYL9*!!C3or2mD?Z?S)n3 z^&-jYp^EM#^cP4m&JxfK+c=KkRf?hjSKw-k$M(#$5> zPl1_26)DEwjb6~9;%g&%gJTYMXTTJvWrs9&=w#)xQmANoz{Xx5WS?Y5xJNskp19;5 zEqbChu&fk*ZtbTs3t4OB#C6*I1-#1Bn>3v7$pRNvlci;mYeldZa}q|@U0Jvx2#@+M zOhQdK!MVmAHcx;_#iE0v@mMU_S5*z-P=rF)18l?wK>O0Db^)5$Crw3$We!FAIPbH3 zS@}y#%vdTRxilx~6ZWYi>Ge6~yaIdLh{d^ai=aW*)>@fPU`wr-bYy7+6FmVGJ6a&) zY%zk*h0UimQq~g=W6{nZQvYhNzB@RVLdG>3pA4IKtVEu@?q+cW-0kFKbJgFWS{}58 zsqUUXsgH#VneR{|T&qO^$w~4I7QaIgm z$%*0FkrTs{Hv2y(+ILvNC(t3zFPuU2#>XK%apn+>j{|toJu#uhhad?_UEfHhIgjqV z`CBzqNz-=5c=&=T{dsKg&eZHNay*{M8jsJ@Tq)1zsPT~c3XaATax^ZRoRWVqAhGp6 zha8lw(KvMf$kBN0&i^|`O%1~cGqc_~ z{f`%6?+1(IVy1sW=%rm<%Z)6#m*MrZRa`A)g)M36m0p$ra(YDx3kp zOPB_L)^{A^9rSzmVqK!GUfe?SJe+V%Oa!f`z+7SJ0ihyL0Bwv`7#Q&gYaF2)h(C?U z@-q`Vx8aF1H~7U-4Td|5@Ty{vy6E5K!L!?P1v)uk(aTUTV@zWW2uWswm1nB0X@}H_#;UMCNhV^)hNxH% z4*oFBXdX7a!_aZ~0>>j>2wlzQv6w`sFbFlAFw zD@$_pE?TbL;%MN=>MPX#<4pAoU&K{E;0(FO2YOcx!HpMrbXl>8pGLS1=89)ndK4sS z2-M&xILeZ6L}LPu_!lj|l4R&@NT39# z=>A)Zjt%;tr$-p3D`zZe~X6k1{%j{E0ZzD5JR3Pwh;{nob-r+)>EiT4!=#$ zBT%Mwd1&r4(gl<0C@9LrRM=#n;Gci2u@lIOB zIT9wBg*T~9g0bFnCN#q*aB8cSLZi){^V~cwgF%P)dIoD2qNvzPvK4WLQ>@v4imZ78 zdFg;Ynl(=$E)nm;FM&w1=5HWIDKcph4aNS3n!L?hDFGf*L$MLWXT; z2;fu=pa`2+anRMwCQ%P_{|M>y8y!Bn~hFR&-y$1)77 zITs#!68Qex(|Cp{kOc|a-3X+nz)RwJ(@EmF6?qL=G(81!zJwnEeyx@HnD~6=&u#_) zk`r1)b-usarwA47(4fm%QsR@-DJ_O^&Yn11De<`<4%I@2g(U936rcaG0rhO%j+(Ra z`8KyX6732m;FFos_#{WA@VOZ;&?kPDWf;~aWW*#h1zoCDc%4kwMT*$4@cR^mktGYq2qF&kSwBG=5F=;eFzlgCyy7{(9nf zG`)TW4Xg2cFZ8PL`=PdM{2CAVjAoy*Z$ahAHEX`%t%5XU)%E&p&a?aT^*WX%FAB+j zLZJX$2w!EIrPFLkQo95jvb^lpL+vP(*)1FcMw(qp{j}krxiu}E{u>}Q^^QH^OYTty^C7Sc0qo3=e zlAdVfNohP}<9A`JrsfE>{;eq%$Fp*Y*+u@NXJ1d(DUOHDt3OXcMrt5qyM}-z9EGM{ z3z$-R@lF|*?zVB64j^InVon(vwnO$f$-_GwH+gu6fkd1{&CJQeJ3m)>xec=q@34As zy)(A!8RjJj3?xC2VFiLrmkmE_*P4hwXNPdm3?X%Xh#?6A13Y##3IryM1_8^ahlnKz z3?xC2VFiLrmmp9$WXBRxtdSvm%eiYW8-!6z%09_T7%7P=Yrm;{v>rZz;Y(gKlhOgG z{mw^1sr}}rK?yJs0$JgC)O50)3;K5ATG1EiN2s00(2SW8ABMWueg%a_d2-zd`41$vESOR1>9%RQj^ZTV7 zdN!0zcH0ocp=JKm&?ey-1p}I&fR-fXu_P&PJD-=PJhmP-{jzz2EGdtXvbE9HKI*6% zkI6{`7r>3)HXH+>IMjz<#TYy`t2)1xN#<*4Ni6e;HTilcxfvjjvoY3(S5;^PZA*-? zG%%K%WYh;fOpLLis&_M!q^9;9A1)#_vc3zL2?Vmaf=WH>;{Nre7rV*zQflp1+J zMreS{Hiba_noG0p>mN$7uJ&*b=3A@tAlmJJ9>L`OCZElmPoG8A_MxGSI|ap?Fa@N% zfCjyWL65Akd7vOQ2~u~eb-aw?V9y)_r!rKg)VW-b5yBoq7PJrLhVs>`UtaM7ehqqz zpa&;mwVba9vw2^l*_a3ZEn|YOu_^Y)m<{T%wYR;81Aa> zJ{Ky7M8ea~sI~i--HjF4)rg589AWyMo-Wg?IWRqI@GW4xGGsnvWfT=@kStF)Ld&j<* z$JXeLC2#S59;{d9r=OQZoujVk;dUyiEgVS)bO;EWu4!`9joT9L!#fnaN8p62b>ztD z8`MC*TZ37xf?goQikh(9{PF+~Lu(y#x$rvLZ2Cy&LYy1)kO+FvM@Lo#B2);Xff}DG zkZ!0=c*{q&3Zw~QsOiTdja=m?A=2I=uq0rOfMu_ZmmjbpO!UEH{5honLmC_w*5vb! zGnW4>%EP106aA?IX3)NzDI1u%C23-WheleYRG^L0u>iCpv+M?fHdu}uWFoU|{gs5z zzBsL|5SOSCw1b(jCc!*NFpCwKMP>wb!6rQz{jtKlJq*UKBJ>f;OlzRTFc>z!FoSC= z2dR8tN0(N2&UyuwDxMO@StymKC*F!=+-`9fA2{rYq5RfPT;-XFvmD0)n|g%OKKeKY zb(QiBQD|*x%K@vnaN7WH9sot*OgYi5_=ll|@=UpmBmZo{nR4l#X0VAwoUq=FEWk|} zR&%@=Tkphgr7v1+NtZAjHD|2sRTvY-DKsQx>5aQ2{E-DHe1+ZZ7(BaGx1~+wFYc%+ zm^_SL0tl>vy=Yk(&c|S5nz~?TwGVE}^V=(pxla=jb!A&57D8L(`Ry$@zx|kbehO!H zoZn`xW1ZiI{mV@Ae{67JO86adIm}yn^ckF3Xx|Qd681=X@HxHl*+B0auH*gJgE2E5 z7n+*rH}_v3L@d0^u7Sh+B-ka#9fUJN|2eQHU-t545HFA-l8Zsa+I&>QB?rMO7C`X<#X_! zjy?aR)Z}8Njvnu?!;H>)c zwIfi`%ijMhx=B=Y@#R~1iCrA0#kL|)eiFWkOLyo?cj}GX0MLEXo+X0MBo|G<(Eu{# zu?G=-4xPXm2NVfD?SDJ+QL$);Sf1~CIreVKj4RroUQs#A2k;^vt%fsc;1G_+EZrd% z?G%mM06Pq;+Yt9u;CQrnsd6 z5u5 zBCo?7b!K2iWlr=m`_|gi*Puu0eqMQpYmPl1XBvKB-d7jczL3r=`#s~4LqvLDuG@RMVeCUSX$S_52&sTfWt_yg z!Z%J`K>@XY^~Bb9uzv>4V=7zF?B5R`5pUqIR&y@N6Jlw8;9c>yR&$o8j6|c)$Pcd& zIV%Fr=m$XZ@S>g@eS^OA(dz>5t}a}@46f5lmhOi8^$X0Te5wcf%DV#Z!l@opEz>e3 zCNagRcH`_Qu1=QM0c744&3wcspu#n|FyAi{ld)p>c^6@`yU7gGAt=>tucFvQ2vhHm~driP;vLT!UM?=5E$=E;BQ1Tcz%47cb z)u;3yFw2Z3{OR`$@siU)bS-dJ>yWC-JTVWVQnbMCpO|dkkA`u0d9P<+jacUP_lhh0 zzvw=f+x>2C;K14&n6G!fXmOj(3y`nbjf{w+C)Z6ZSkDN5UaYUnl{;{g2zmUwrHjYf z8lfRy_iu7tug({*n1w9ek}M4u5nOY(_a3kWj^YAwnKEx`vBY%&Q`2zvEXqOx0ju_xlVuuO})$@+xQ2EGpA$`sh`J5*BZoKg9M?){L=Q(4@C>M{Wbksp2!Mmxaf?}gqNT$a|oR^hsdkXvtYiyF7iTMBK%P4Jzt>Ei*y;5*A> zUB1-b!oDvUvk3?oa9?fTOQc9QQSX(o+xPV5NmXJV)QC2P2egO}*E8e#A#P(21!hLy zT4t$BewQziQ-Y$`zssao^wySG!l@hUDW*WO9%5_8yjHLg?%lysGAxzKv#?}B2ecLr zP;!u)afTr{#Ca1)MjE2|f(sr2nLAJ3v6Cm%O+|H;7vPpuFrC?QpQFr)Wd@pKvhXZE zveq|BYFT&qkY7PlvF>Es=6>v_=@qABI*j+3&@9~6%&H@kMaWBKjXm;s!+jEL1a^X= zWMFzS;7bOIlYuf7h^?4)F?q$Ybv>^=N=<2ihxT?*S!fmxxJ|%(XpiLrvD5>PtmuR# zs5|6!Q-a8oYdWR?=#Pa(#;_6Lrx zE+EqCfVAbC3&ox#c7^em5uUK~E!A3ImPI`4NDPJ|KcMMhZ~1tTwaKVpTd+MBI7(hg}E!M{8s*qHntHBNap@ zK+3VlJ~nrjGl@g&KbJ4r>=E55w#yt(akN>~6p1pdfVd&W8z@^-i2`)^op|$H9Qiv_ zGb<{%{rvU@=OSRh`-1h$}9FI|oOXkld4Z5*Uqe~*x-(zS#_hR&FI92>(;pgLu)?(IQ)%;3ix8DXW$Cf+5^&H^(3e^%%aNt%iFE7~&yczZIoXd;E%%YMryPc8G@oq<6?v;;$TNXdL zZlUbhTv5-C)yvWO#fE_F*iE8-x}TR~aaii*u$1IPR^s>;h9uG|>NyEWoya11oz z?jf(h%}fJ9+-K!GvpXkpvt8mwH22@KxnE^BcThIhgC6-&VVP==m~>+*qMnmT(-*rh zjkn??-heO2WB>8~*0(zodD}A2v8#!-5 z7Cex5lRGEHhTI&q#MXx$Y9J%mi1l70R9BgY38Z{Vyu`Zi-W}5EBP50xt!hwPu#Ux_&6B{fn)yazv*A0osrEpa=Q91!^BG zEIdIRJRrLJKhNq0J)7?+nZ`@(%tNqA;l8g14v(#WT30f|2e=Evm`!FF3rkA0TKph4 z0{DUBL6ewUg&d{qp8WBLjSw|E$ACjZyPX6|rt0gE zQj519cZH+>UF?@yi{1EsNH7nH6yKOiLnPly=A9v_;qtKd`~lo)=#w{s;p0J86cTWeF}JSL z6PdDkDwt+AEEmflIS8b)1G%O+k@TJp%yD#Brisfj$1yl zD;0-{2C@}8mExDyOn#|I^GjJazckqV@+z;tq}W6hTqhPx7dPT4C7Qm{2$4x{FS3~g zQd~c83y3|G%nJOiYV0zJUXJhO<&Z^vra*BUI-xc6F|6w{bJwo<1);ePsFKUlU z=Dnk2R^XRf>>wz&r5R*dW**>n3ehacJ0Kwie@wAODT%UlbAAOVRo*x0!&fINWMq%K z%pnV)prm6k7VrgjMIro<4dmsN9cGCEkNUSO@?sM^s>>^3I@`k*hGx5JHo@>bIpd}z-qIFTCG z2C*KujY2wcZVm;Ng%SIIoap!H>v1Fnib0V=nY2FY>%){{d+<4^DpX73 zfY-4c+73SLVE`~v8oE~Gw!tjz<o77K{$FTbF%;Q^7G0>-r^Daf#l({ zOjTC}dN6uFAT5Y$KL7*bd)^O>k^-CBu1(9&L1D@?d6 zY<--4<@L=M%)}t|pFIz&Q9gE9)%9I6Rc zc|~py6b3LvK^58qJBJFT<~J#ywUBAN;vu*hXIXjt=PKKMT1~qz@OE?##QMsRFDspG zgSS@|iYuCMUbM%Z<1ja)RT@bkfqC&2k5v51%=jkWfI3+&9FY(%(cpboSKB?2Mm0Du}d#x7fVvQAg?Zga$0AKdpWI;07fa60MJBCm`^uAZA@xoe!wwDn$RI%!# zAi7d$b>G0CVAHY+7%AU}COwM8X!KkTtEWd|=fyiP{wwtS29~x*QGR9W0gj{0qFyi>~RGwwa3dX_G5)UtH%6CEY>NCxn#dfVDZJSz|04wf`@$lBzcp!I>78D-vb_gXW z6AufT%m_qV#oS{eL6yxwLZ(3n{l{hGU>Tp@IE-(Hj<<~^UdICQNnZ_ITwB9GqW!&L5+ED|P1 zmv_NyrYVEBNfp3{G(L(qFFAf!V*Fan+AHYR6G$w-y6fx-NL(Jr#&)kGvJkhguAa95 zezUN^*ZhhIDiM=)Q2t5M?bY}`wYm2{B`;veFeloJb$OS*jNhWgp2rbL(4A+=)m_W& zn!z8MO&9nw8sW~(ZaRyeh>VgD#|8u(Hn|&+ZvshwLwc<8UFXM}M(zr>`!I2mW$iwvjx`V0F^9 zulr&yG-Z0{9E4%Sl=pffkE8pwTqsjJ3A*`Z__g43)UmxjF;V4UHL5%cx0t^SBEtf= z5prTKL^c58N~oN0KTGEfo6o77vMTYG|4lR>!j1wL&k~p>bMH;ap1L#($A{TjSzY&U zb6sckT93Zktq1xy0|I-Ae2VUZLUmx5?DV_N^@XZJalHH2xlOL0!{x0FHA6)hKe_%I zm1ZY$ffsPD(WU!%x{s8V7Px^E zqq-_=CZG>SPpPQ}QApg2Zhz3L+6N^dqyGr5@(P>NKOx73HQ_y0>#ib-7PyJe-SAQ? zlCZhi=;!|dUfo|xp;e)%i7kiSvE5b1>?(6Td_U1w3ICaYLzVJ&ax<|x?%)h0q!Lwt1FqoYOVmx z&6(PF`;)L=+lH!=ig>P1azcW`^{bfkua|6l>ss8Vw+mh41%mR+_Po#t)3+@SapMA< zOa#cy<|jj_Zz9oDEAJM=bV()Jg!JTNxPPpdgJiHxUT(M_S%wZ_8IwvswBH2PMidUi zFa+T10?^{(}e~I7MOX2Ade7iaQlbBjQki$a+eak z5c}Ow_ix>Cy_pk$V-Z6dW_)(&FDOX8L~#XJNL=a2Wu>hmNsepdTNx`*F26)cqQKWRf!fsLze)(Ym2q0^O0IR&&JOHgchcaDz373ozXBb#I064zIF6i*OyBe_ z%W03oG1XzXmt>%#7vxQB>{DMK;Bq%pwh1yg`+JfP`uR+|ez?u%Hl ztP-FG4n<1Qp!9bpy_>P$7aCP2`35kB2ve00x#6tbhib7}6q*ZVgXqH-lDhMX!kL?I&xLZ5(3R%!Id802cHY?X6ZMU0F7Zet#+%2 zbc(@*e)iQM_}`0>VD_27_j;&_N&%{e1%z6e6I1yz1tyO5~BEp6PZ+ z@1{3Y1=jv0@OgsAM~&BY_)j%JfUd-v12ZsdlPVS#9xK9X6AEn)Ii`Mu>}uX%a7@g%Cf8kXC(Mo?B0=U>UH4 z+vg&eH{iBn6OLY;sN=?y{gC(J;}J|&R|wluA!-s4*mGdfABtRKt+g%sMa?5E`a{uO zggbH{O@*H&LSg^QFy4P27gtNb{g|9+yqD%gd?b#L76R~6+jw7?G~O4&vNxUPMrmp+ zq)D`&cRXaM;{MYq^Nje++!yx@1HxmndOF;smS_8~z?rc{e8Fq1suTRo06z9sq}NoCksU6lUNcLdiEAHgim;k> z2jOLf1UOG;RH5ciPjmShND^4suiwP8vePL4{};zHDSc|mbNTk%+m#Op{YM_m-L#wO0>^U>UAMpT_QJK}kN%$2 z*yHLI3p}D+xc9sE8AV?d`Cr8GBDi*A!Gii?JfzmJXz&K+xz|pDCal2|&{ks|8~6oe zi9myQ?KOzh0u3Jc4+FD}ULB&#c%5t3C%I(lLAi{4gU!!GC%ygq#~2CJ$CGrRID`JS{KJqb0>A1sOe)DM#(IqSvnZ^QHM@k`u{&S^?2j-!Bm^CbQAP{7lMGQP)|otmmTDSxT`xU%=uV~3Ju&w+{C-woA%U=KD9 zTFnVLr3Ln6*$KeLZH61JHvATw7_cnZRzE2Z>g5RduE~o_l?mr$Ci!hu{9E zOZ0F_vWv3S9@WDo>>?vDLUR12{aV0Ym2Hc|-bEzfg};04hm&ZdxgmwNWSum*Ks8hS;l)W0uTC2bhgx0AB%N^zD=86j*qlT-zG zA{(G6=0&=p&WL#rCo_C^23)_hcMZRR7luKFHAcOhj@, zxsFokag>HZ<7)UtnBPH!jnJ%vcKm2fuD(7Ws&anhEQhKbs>-vZE2$1iZ9sru(d3aT zWB-)y^SNUG(SDM^YOVa`z#?$yB3zQdmCkiE>osG1?D87RyZ^%S7@m*%r<{Gg85>Nw zqnA5u*IVEug446wSAHfC1vr@GmD%3)X7;-ckfd*UzEpcY_okmdRkZ2eBVTbkoZ9mt zXZaEQ=G^---(}c!?|vEXMZEjoeW~!cjBsv7I8Ut27srzk_ja?ubw?^&3fKCu9Kwt3 z(DG%5dkWFDT z+sg4LK(Sed7xzpWUVeg-FuVle^&9yJp}Tc$k>QP#(d}{I1`d`Mh%CXhauqu&D4|@i zK@8^rIOwOKdNRC^n%{(TM$(>wEJ$lH{m{ny3O{vn`;t{b0bg-T;o zOO4SL{)_Vdz0if&@7+4^DfL4`Xbo+KjrkpUNQs(XwE9!<;9!Op4KQqh;1FK^|12QBFPo-f;q|7Y!EJ)C-5%AQDS z9b-KdzmUgyZ6!-;U9p!HtSaa*2ualXAP2ar;U^}~N5X@pv@(<*xeiXN7=+2cmcmGZ z6bIlJV>UlQN+E)qCvqEBC&N-aB0-zU7Lf)P!5cZU3hfDPpB&F{{wy~ z4T!oa`PX+LEjC;gxmoHv0o2EM#3=G%S<4serc{YJQz|wG`=kb{P_;m}^H0SNyU}Nu zq(3Wih+X#5!Z)Y@I6Ncaau~q(E9>DrS&K^RWTk&giG%BntM`l5Rbn>kJ%u80+(x~u z)Q3t33S&KVwe4St8At^Oc1gfh-+0l8uNYl`7q<^OA2?(dBc;vR=9VzK_N%ioJO1JO zTnySzE7TDM1QgfTx|3OKWsusT0qJs+hSMW*la|X-n^TtDp@p%z9vmg9B?GJ z=u1f(+&YGnXRR=?kT42C7?+7Tg(Qp#fdl;DxFighq>8DRq>7&dL5eD-rm12&Z8E61 z!TrU$sUU@^S)`Cn2OklQr{Jt1cVPk_N8=}#s@yoxR+u7)!RW_95FbOOH;kw>n+`mr zgNbtoHq9M)MGZasmZ&Q%29Ox{!qm8%qsLu;hT{&zw&Qad>LfLwk>h?qk;eNRcL>TE zhpaNE3$DlSZN5AIXXZOhcJ>^%0?H}%J&wbpZ))fM0e8CL7F}!%vgX2^|H_yPmu1g| zi&w;MO@8EKj7p_%+qd7$oFxiI2h8Vx{YyOL zEUoZ;FwI|^28W=lNGbeB_^TMjxJHXOTU4UQ3uU+%cSy@Xskj;6u9CqDT&u}I4J0Og zYd(UBcnN;lH+|Q1guaLFL2rE>+EU+m;8!WjSZ2;luQ)2|W_r{|U-0!8d;KuX6yOsD_$`_nNa3bIGf` zmo~Qm_lMb^${7~iHhq4ktP~vWPCm9LBtzI2jb1$ z_bB=`WQS=60|+u@$8i+vdMNUD88VC~SlLGQlrE>a^Wo~Z$YMeq5N#}n!TLbUtI9F$%0X+&OfRD!Lb!WF&(ne?`X zK$)vc!b@KSa&RNR64w&Wzm$!aHK>pqTe3O=VoUVJPAAtO#64dXUF zJU}xZJaDl%FXg!twD{-H8Qb*)3IMthSS3uXSivN}%40A3v0Y)7V1`-DAg_9f=OY;F z!F_ur2vn=7U6(JS0+I)o1vw${az=deDepW!aCVhlllst8c756M0`5e7$$WS{=mlDU z8OftPQe=F;>lvq7(O6RcGWU-5LRKs)am_vxf~6x?H0c?EF9$Pmwi_3uY~}oVw%_he z%3DI~m@#T)Q}@07$>nWZa(VkkYI*yI^z!ydYI!5n8OvMVcY*Be<*kT0)biHnlIPA%mv|6%Nx6pnmFah5g9Xjd7}r%Sj$^Hy}bQq*`=1Z zR}W)w-}~}*TR*bD&*hEdms;Lte+6CGMS4pvZ-+61WKOxGWsoP4J3ViN&FcYkYI$oM z7;i6c0u`S?*8iC}LeMTXUI#%P|M#wMlYusF(K3;pM(g`u-+p}P((BueuoV2i^=&U` z=})e2Waz(eecK3H{Qq`+E41W#Z0}quu&b8~1l9$)x@EfKRmz-N{9W|#{VsK1U7K3! z?EUfW8T!C6?PCJUv_Wo>&7?|j-$+)|99(`vhuytENIL z3Om`Cu{)p|^XxOMjGlLU2uKsQ(+dFxlTM|RGUSEXnfS~fOFt=I#VtIIgE(XkMVt-C zx3+&B`oT$F=-S{EXccTk5*(&n_*TSfFMJ=wj32_3em^x#8y~8Z^532EyJV8_; zc?Xi`iRcg>aLXE603kJ>io3n?9*UyYG93Da10Bx6BDQtm19*dznR&-XkVA9`PFOcd z2(GZ^yPM6QZJ^u_Pk#V;nvi6BUfEg};1jyd4?@~e_c6d9lP=NDq;qIByo?J2`=h_J zHMqzR`}q0tF8{gmGqHrL`;DByeyx5OHVa%O>)9f5jM?sxUVR~OHu^TKyJP6@l)q!_ zu!W<75BV&u<{=u#VIqg2FOlsC0FA(xvG(EqH|Y!jcM$U-TmcUI_(PD+d3eY^cc+5M zFDe_}2h2~;mx2I}m40}1)(QWIy|)36syO?H&t{iog@s);Xw;|?L8(DaO|XFtn2_uy zd;|i41e7l;U_gYJ>_V(0ByLbPheK&=TW$3zR-fmgEp2H_Ewxk=LbDMl1m(f_QH?FO zXARXTJSIrWzQ5m`b2cYS0@{E3zSs3$|KysTIrDMPJ@?!*bI;d3@`zG32QfNt;^n)q z(3RZp-W}d1$4vWhDb!J(nJpke>y6)`9y)+MeeDQ=IA#rca0MPJNI(^wc~5;;XNKJL zSC4kOtL@JGH?hTqlTbMOyKFS{kR}vG=DDx{uWXDH`!qI$WaD}l7N~Ig1li`--^iV6NlTkgeMFw2=Ot_DApq&$+OkMN3Db+`MRWOF#V>2!4nlc#e& z2fc7RTpfyUC_@i4X9x4C3@-?UTQgGvE!n|YDS=S7GE;RI_WFN=vzE;|20UVG)FaD# zq9=NUs8p5NP^&nDjq*WKcv6*O-+FRZ?FRB>g zF0ofmb!QyGqVVS@&2&K;>j6QT89HTLw$A%dE$fF>44D9+$g^|j7p@_lv{#!*J3>Zw zd6)8usvxa{>d!7fS#8C?Sbh^r>$HluZ&(pncc!*=2uD&m4TPoJL=g!;$)Ogxw>a#Y=(UjNG)3rBMm`8BaU?~AtQ z3R8Oye3%{R%np16jAI*i4zo5j>@PFxnMsHkoRuWcOb*Us!$zxSz87fESYO|K(eaMw zYjhC;+iegO{9OAdMfo1X)3Ag74s1It9$>LVS)3Hg6*o77x#;<50X8M zvxQ2261pwXM-_oDR=`V8F-=f0Lr^gj`$GjtE3vP_Nf*D`8Ib)a`E7sT$N`6GC0G0 zxvS}198OlX#9rM>z0@miWgJygd)%Kbsk{^icaA%!9G|0hwBnc|kM6YT9!GQ!o!4mr zKcT#l8aZ=qawU!nuW3Bx{A(i~M)|}!-}Z-;dnh{KYlZXfRs^;%Fd70+#9rL$ynTA| zx}|mJBwReK9MbexYv)kyCDY0{>!-3+nb$iYW4l3GB6;-*3 z!OElwccCga+HjuqpnPYEc>RTnh#!ZHjQUh#+79vWM=z_HUe`CBvkpoxtGw@gdhL2G zhF(9=J(!XH_x~}y7GV?W;`F+IaC+(ZqqaYh&!oPN6JLSPQfjIoNNDmOR-Cs6(3*MV z<8`I5r$l{|^VDX@pikkPYhiEdKDj;cUL(Sfo|T)Q!soo6qdmCrzArTd&ECcCrs@%p zGM)g(;%1(FrgJ#0<7$8&{vP=_AQ|~?{6^q2ON|Q(lO6JLB>FkdydhYxW+L{k{7&k- zax*VG<4g-wZv6$)7UNPDOLKBurs7|Qydv6H6xM6d^Ua=fza7Y<6YXfkCj7>ZSQY|3 zuse4~o2I?4T|d(!46D4Me4rdKu|#lfV|5|j93v^UWIGn_H%PCeCh&K5YAQnNwtzXH{E$+`7$ zy#`)G4V0=$+9)Zi;D}ZQU4i$ySOw?gmS`2AgHCM@;%sk6SBa>FgX&hj7T(Zm;dQl| z9@RZ^H)}!9d!rmUXVk*$=zN2h_p1dU_b%E|Gr-~maLr|`07PR29Kn4lP@mPugdMm& z3Q?^ei8X!`tM3U5YA12zke8qR&{+i-JwkdFM&>DL%(!ahw#>4sj~c=*{&0A2VF} zO`K5`2cKE9awxc{CzZ`kaJ!Py3bX-0m;GrZsn*FP;QhKayg}@EA&{Hl(^rmcn@$f zTRn?57p(5W9I7&la>B>c1mNpAiFsdhUxT)dBv50lOmCE5SARw_hO&{Q;*aPV00#iT z81ANZ(@@pQBS7+qx{Sco_VJ9!P0o6Zg9snHv_#FH^Cv{cBrukstBs9md`f#KRca)n^ zb=XEJ(P}OSU6p*Wl#PN{$XS06l4U#=Jnpd%_q zx#7GSKu1*EfUDJ*KoK66Io6Hyog8bqQj0x&Y7J=1(UI?+94PdhIYovcdqB zwfS9vj|gJ~puvlnIm1U#@9-N6!+1~wgD4w^g?DTGpsVa2gdap-hLtil=TqGu3O6?@gA_#U81qlL9h~> zWTiL2N}(jM#5;i9j~kXNvs9g*41UNF{NN@(Ocwl*Nq$HofPKEvAcoElHM2<$u2)Ur z#o-)&4TWQlE3hw#Jo3{R9(h3Uh-&PJ7_5>dSmjQ#id(SCc-%?`t1v5_RccBI9JQj| zoA&a{j;xAY0i3B*lfXW^V%Xw#8q(R}x zRy9S;5V+Lj=vSmQ4nwlpuJEq}JAloSG&Z}3=)WV-*V(M5nCZbo+7;_uevLq4mTGOj z8u*BLX{H++iY#L`Xw?WmhXpNYE{&TaMEtGTinAxU^PMq^i%2c83&U%?k zD|jBqH@rk$)`LFXG|OyXMJeU{d8Q`+XbW}P0^u8}XK+Nk>1>?b9jrc$et#Zcvba|M zOp`A|^0}wF&&i+Q7~d&26GWNU>wc|z@upX6?$(u>C>h^S9P#oyZd{?t!{}s{FAZJ} zadMs=+P*E2e%zl`57XmXTk*yh;)GK7DULeb6F2J*04z>YPhXMHHt9!5{s@?y`%TI@+%9zX2*Z#5GWBQ)hyVXFU|#K6l8E zH_FiOiGZnrkEp5yvikQ767&g2aGB_l6Qu_#!^K{_jNj3hQY$9Xv$EchKTACe&DbGp`lnpde-lgkz#EKt zd1^aw9wIxeLA#eIcl$pAr3^SouRZ>NX%^s|fi5Q8iHI)^^o(_GEx`Uu_EUjB;{lPT z9;@66{Yy>nC18&Us?n5WsF+r-%@M2ll)Db9T|Dtq*jubPCa5+oU=$~huhHW*1ePLF zCmuk>`oEUqC8qG4md~a3lq!xiR3yZ)SNdW=z7sGpjs2D8dp+C2adne`c36GJ9JgFR z!~L;TPj71VX}oU;kxl)Y7G)@S3If>-0T1^q?$f-1Af`j=cz8pn4I)hM7yVlJQ@|Z> z3H@-K-M=bTGa*c!iEJ7JK-@O+z7yyg{OmW6P}O@cPO5nSck-_6C`kST1656 z^XeWH7}HYtL-fKyn0780`}d2JNW@Q|5vXp2nvY{dk?1hSP7wnI{Q8|p7t@!EGe+0l zjeJb2hXy?h%=8@Wea+y!=cyrTJ6@Nme;qAD$;Xsnr+c5X{uO@B$H2W~8(wqv>?fIU z*4NXhVOO{dO$KT<1oaBrR|E@NmBL-59!NKoOVLGY#!pGNR(G?p6y2)c053V0bjtVi-@V*FWp%hbY7h^ucuoZKGmuGsW*B!=CFPMF%uF4xKot#c18zEQx7V(%Zt=jdf*IpS7}kI2XelcS^kQi zg%lp3INvc$eGcD&{V95Hf*~H-bk(iG(^zoR$E(1}6b=boAMD2JlnnfO+4$R!p5^M` z`yhqftRyaCqodlb5XPH=E=-@M2R?}71P=;v4hHA-U`QV;)2_` zkH`W#S*)*MRS1EOBPit8zl088FnJ(wGATM_Vosthi+Q2fOV{5OuXs+TzlzQX&^#xL zkhN9G2T4%J_}Cb)ZsrcfhuGGKlE>7um_Hg&Ha4A?r{I^QV(z{4mXzXbWPL4&qdde} z?8A^J0DXjfe1&su(+X#0yKRNDrWtu~i$--Xu&uwj!seb(d4t@78+0Re{IXeBh?Fg~ zhrw|Pu1L2S>yMZP&ld}t?#xODpd$xtRJV2h74}d}blv`5e?uRd#`yn+m}!Ecjmaj~ z`no@a0Bc_88(XsmOTc{+fs&OCZB9*pvqDo`u<*2!cs;I@Dz-1nhoRu$6R!J_&5Kiy z@EHd6J$jJMi^1lnQ@aJ5AEGCQ^m)C-U~{Ls7vKHZTz-8v2FCvs-eyME#2;-v7H?|E zA8X5g$Gbl$?L!%j&cyjgNqNUTicPS-;yA3)A5-UfJ%Mo2bS%L@{|iK1h&S?C(93ho z5Wzer-219$$Zu{#d6mS&5FFjpPKtIg)ICkDv=qRfJbD;`iesZpPQ-`J!=?ZrVs4vv z7-|zX{2sC{GIa0rk5X)NkSMQ3g)%Y4wvlOCl&^usYjS!p1Iuf{HB37mD3@O^qG*u< zRaB6c$alEH4lcjzd@dLDnIdQbqI?3iapckNkNRlB_0M$y4~4z`jzL@OC5TFEuQHCx4O z9(ZQsN1N+skA!mGP`8n-Jdr1a_%t|Wg6Ya%F2CY|Zoo^$Vz9P|* zgy!QEIxzLJfZmYDs?733UQ{0ILO%mNQm6GdUeF_p!L(pJ4tr{wul@Faaq1Uatr(&E z#?x!z$CnB*GJ7*HGUNFpyu=nWZuUIS(Z1EZ0sB6@0@WB6jiJ5YxT!r4{e=e00S3jR zMPSE%!W3#%@E@|}zRM?=PXzrv=tPuczZetRt5>5RrAApLr?E(VH$%uSmg(|Yu1@=V zsWlYKRwfA}nPtmQqL2}lS?utOneTJ84-&>HWUM5M=Iw6Z@Pt1fGZtk@BZ0SDyUqLj z`=0|`2r6c{yWl6|%|A*m*!zd%g1vvdR%oAzil(=(j z>ys+tW|&S6Vh+!i^FPkjrSP&fD);VrR&08#ikLvx!R5MC2dWAwn6VLJ1lMBMu&xgyFhNWekw*} z+Ytb^b<16PZ-p-E0A_6%vzswye~O&-F}qu-#B~!8LI@v6)Els|cpe#mk5T?{I`UjL z;}TfER>08bc{is-N(^{lXryKRG*!XoiX^U*895k{; z>BZw-7@a;=Y}JA_o2#dBeEnDS@AG=uwci6=V!HN6`giRvaU^XHrk~zHIZA6!Y)q)x zQf##A&%@E~vj|UK7pt>y8%yg8!N=?_ z|4+Nbm!`*di72lz4p-x0KSSbW^?gO`pFr=HoOjUX&bO_<31YSFpgW=RTCk4op!HK- z+&v|KqKmt%jXxqV!TRYEw%SvD3psuA5c&h`CPCW7T!dALio_<;ghlr1eDnwN&_Aq` zXY8|4r&l_1#F0N|xN$N^U$j14b=8Hj;k@Qt=6#LUN2 zN{rX!61y0wQ+vbjKLs_}u>XOpezcdv78rsakkuk1_uvHV=XpRSGKMkr!fE`2sV>wz z;fZIcIt#^j;NfUpr3_92o~In77Na-ASxkC}V^L}aWEy;` zpCJI+Gt2{^EGC6Vr^Z&cmcKkNML$khors5YJxO@J&EuMo;H;;_g?F1KK*!)VIAmLDK+6#4rV@B)CD|H*j@La*Cm^wE#2@NMo|kCQCxxU*B9UAq3TNqZ zVe$m0v!16Xi`Ic)9Jh4`$Z>`L5anwVN;30ykn- zfpW53o5n_oJG76u1CodQ%f))=^t7Zm#y(aG3L=~bI4ED?hBYQmQYmJZ6a0zmCTS0^ zxzGC2WoWo{%~9qJg|Wjp<`kFm2v?*i2`YlFS3E-};IS@?ms$j|Uhhw=ctxCv=D}DO zlwDZ;U8&vBl%B5XfcuA)91l+-&Gt zg=f{1O7TG5$a0)_$D<5-Qw(`ia8d|5h?4P(7mBEG6wjq&?E`)p^uyta(O6H5Ta^J< z_Ga%CUELS7@nGlrB!aA13cqX>Ry`vl=K^>r;UxMEoaDz-H+(@hPW=mbHD&{d!Yw*0 z4XHp)rZ~Ydy59+oSR?{9DR_k=vd$5Wbw2X)O#5OSBRpTXsy;r7`sL~;OBSdS*T#V= z&J$$2@IXt^9Q1$c38IV1G-}MG-A3>SyH$ZUi}-9ANg4m_GR<18SxbfG8+!g@TBt9i zRfm9MKTr2ee&k{b74D(?kpEeIflF~EWj60~B;#@;wg-x!E|7XMs4kGI8Vq%TP&4VU zhKi{w5Kk_tch3?cD0(-cDG*wD#oJFyT5QyyXy^&#mwx6yc6*2T>*#|)V)aS(44_Xk z6r)eF2Z{o_v23Vm!lO7weUkKjFY0?y^?}7k@vp^NIf|bfQ*0N?TWoDAEmF&74p`!Q zj3SdA_|TMHGHVUg`dPWudpvt(&mp0tw{S0{9~%~G_A(&kIfQXZa^`yWif7dd_k_HnRPH0r`uP~k zo%sul^7F9of}2Xd zn*!A;E+8EPrpGoX$H7GpY|PW6#TL&j5IN8U4Nb_)|9v1HeiZrPdeeSAtq~hKhK|af z9qz8m5veW6si;K#A$D&%i{-*YP`~O7>>%#?+r`euzK$H9rElxgysXK>Q6)O4)283iaTLXhdfWGU?40~bEZKa0Xoi2 z4^p%;C)v_3$(E33irlE|K8L94zyMr=@e9NiC2PduO5FED}{;oE(D-IwHNnAUx8-Q^8aB2yS}9i<+I)Y zNk25orVkS216Itoo5FFYeu5ra&^Yj(_0*4L0Z${#%6*mykQ9hp1Uy;%ZnoxjCNwlP zcGxy2SP#na$~t?{DtmjOeK62$$EmTC@~=r398%Egtf@!CPtbo~U?1*EXl20N5}vDQ zjthR9#n9^9eH1GB}un|=lC5gSpo=s4T>R|Di(>?Yw@V&V!peuX;@x)k@t@lKvb z<)f9u8{#L%`4grXv`ST&0SV-*O>hRnPK~H_Xa0c>vnH*sDehb(BIwlpo~+gC2lgo| z_tD$hx*}vn;^w$%cp*mQP#xZdI5DpCmPL7tY=twN zBPUGuU#iuZd^WcwK?*+!q~%YhXiX=qqF=^plBi=1i_{jJ{1tpig3JLmTC82*A>yo; zEZg9j_b$ROB9X=^)>e&~JFSiH*@{4rl4A8o9#kQ=2i{2)E#CSJTb10*rPRV+Y_wKS z6g^F|{OdLZpgH4lHi2nSv_JV>t=ToHiNU?16ERx2M(mKFv)0ZNwewitW+|fWQB=Fu zzUeNhDA{Yz?IFS4U2xmvWcl>@w++R+t-E<%U0zcJ5)^OVr3A`&F=mfZCI~}E%(ccY-+hpeQmZ~@AFrL;z6+% zQ`0@GH{DLrbmJr5&DVJ~p6k4U8|a%;!ngl}w%%{VYgx&-x?ygfce8oMcY#4zt9tV+Fc^Z( z^L%E|*gz!EfSTDLrkRfLLP37q6f{HJ6*`qF+96tO`X3eBSI|t=x9~t6C&v1e0`fp~ zzG+`zaSb%5)T0Uulgozq`o^joa3ORDBp&Ar(9KPiSvaI-Z}3{Y^^FgAaoJ+1_^yA1yQSLEu)vZtCAAT2{(muD7WLeActlNF*1~cO91pt(k!tA5z0x?zD8@- zSYcUIl)ois99{?(Ps@o6C@*mdfnll>2gfcls}_+v5V;#SKF|&Mu$Yjjy*3Ua>9Z_c z3lTYb1ybE!n-LSw$nafq5!0qc(aMB16a0ao8b0c`BcF4ApWbLH3`%rI%s24ujyJN$ zB+|&9%R*S4F(bk16zc^tE-Q9h^+c6@iBP>Eh;m4mtEI~o$YcGjAs&3;Ka={gQe(lh zjAKzo9EG<-!YEQp?gB$X)Y$K`wjeoZ2Ia?M2C3_l#(D~t;IU>*ozU8rWW%MK=M7Wx z`LJt4LOww^#HUvGVs1BT;y(WsrF>LmC%6-g55Bw#=^Ew@)40?B&Jx^_)$foGSPIwKZPC~{OZ9RK9nvlD$2YR@j|yn|tx&KJ&>8eyXtb}hnuNub=5 zqEKjT{-L#JZ}SbQJ$ozqBCI2cJQ^0G{k?^W9#2WHyA9`l1}b0>k43gDLBSS-+$f@; z1@HFjWU)zou0!Atc{m$-sa#`gNMOqsOHh_$ zZTBn@jHp)t=pQ(l+&57ne^j67PGG^D^@aGwbBryLRQDClhi?vno7UTKdV9Uy8AxOd zr`#0ii1S@hJ9)VO(%Kr!Q2!VVF)h}i;ZD>aIOzJ?$wU2DBV@RLm>$BzC|*Wsh2zsE zi?jYkIBF-~jYbCkqndDuA*XfN|q3_tc%pn2Sc8d2#{XR<3ueI`ATGcFO(WYx!Zqtu(px;UZ7(_THo>gk2WmR@(J7OqM>5eyPZowwDU5nBcL1`1N=b@)bY zGMwE_=Lmjdi(pYZ4vvQ6IAwZV{j1t)MhTvURMuN+KdbU@tbN3aXjW(aYlybWjauH0h9~3A3+P67 z*8d*97#yATyWyCMduHhTELl~~`p5B|mA1i=HDROO`BGy*P3s($buYeG=-;KCmu2NR zw`^cM@5U+-=PS;iw@l@sz#anezucL($_*v>rW}2G^ZP(>m!1EGLcUPU`$0u z0HS2PfRhM>a-;t}E-m14=MnWZMIqh|wq;wz^Z=}~1aEg6_oPhpGL|ysQ=eLE{a51M z2$Y;%j_4eHTCWgBui&hwjJPW9#V6Sm4y)U{Aqwudq1PWTKRy;g$`AO9yRlrhbk>i; zM=37(&Bu9U3;|1m^T#TSsp6!W>yvhAmF>l+HAp2Ejq#oZe0iBZ@&a(QnqZZsA@I~OD3kz#DeMB0`_SE@CR)a9!&sG*BUdeQh;-~N8z`u6M+z4Pn8u-z4k zuev*`sY=~M4w%Vjj@@z&&dTBCgY414oFq9XS^G!{=1_YGBE-vHgp8JFj@CX9lA>P# z>V{Z|9+5I8mii6RO_LS-i<+kGZ=r_EXnu$A(njEsB*}MoNvSs9#-#$}mz#vc-v%bR z7r=z{m21ZGg%Kg_MT)XX+>%IM#i4wP`e^N|kAS!hb$*@T zYDE_WC-xJ?pkZgcCZFM<184mdcqoO~z7$2`a(7%tW&rr`IC(N0RUCW{@$cFL}X7>a3QCC7o7)pF8iG}@?K-DbAS^ zq<<6wCEt2f2va|YOoCOTc{V>kCHP2k_y_P{3}u$XKTkc0h6J_0a+msNxS)!p#n;kc zuYbjNhgLp{rM@dB9`s*U_Zj988>?Ln1(s~@l=@fvCo~@%Z}oi(WWXeBvg8W_tomKH z&gr&QP|=i$t=pU|QPP|=&alwx){kY`5?J+YZK(Rr>w#JDk)%+53Zu%i#)k4m#RZp$ z*B+>`4Y^0UAr^pyU|_!*Wnk3GfHXzvH!Xr_5+(`IS)e&Md3wbGfyyH1CkAuu$cUR( z&`c%J!e&<=PJ`uTY8qU|5*xBezaBhoO3fKcRT^HT2xX^1>w*-@&Sc3#*@6}W!j5@W zQwQD0s=}r9H|)V`Yf#I#tcok!gMJsfjU1|UDiVRDUqZcF4`(h3<)jTmmcg7X+;hV& zp%+T@GYf8|-tnfmKvjmtZw%f+G2fkzoxPMjM*@sTkq+L!FIAbU(e?r0QtKMDapw9n(7h9x-9E@vk%igcV8 z{;!(<=gqgc%ya)JJuv@gnCe86xyY!{M-SBGUZW=N#M=X?Nf&AowaB?VDijr|)q%M{ zI{gLlAF>6S9O~8J0`9DTg3Yl3>C=z?eA-CR|1YR~gZ?hk|5bSO(SO;8{}la`{+;ws z!vHxL{TZfy9hZK;2>lxk`o92f>!UyPFMI*|e-Cv>`v35A(I2mxX!O4i$qf3Z2>yph zAN^09{HN%j^6#X78J4XEqd&t`C&bh*LjU~+{qF>~_0fOC7oz{wT^jv=iDVb&|FH)B z|AHzv=s#BQKRo*AzpV40qJQGQlm027aR}>=_(Ly2E4DWD{`q6|3(BWGeew`hM-D6v zg{%Sr{oK+cX_D_tIB!~+CQnb3*Ck`Ly&O*)J)DAJQH-yV$~27h!OArBRd2`#^$}g| zWWR4dY}tRthyIP{jUGiSL zq?DZcS0SYcAD=TSq70EYCU@?Fo+s_piCD*q5)S!k>xUnwzg5c147dwdgSQ`fwR#~k zSAX|+;CmdI@AFOm+?gjvGao9yODzGw;3p6WH>s#JUbn+E*waH*n04FWQ`f{_430AO zv}T7AxIi4r=VFBv$`?XrC||7bhO}p8@XU-Brb*8ELUPuHDIR*`jjJ5n5JH6%i1R)} zAa8YAgAb>51F9xbt?ye*mfsmLGo19?)?m#QE3T+i=x+y1=EpSN)_t@{t;Xly#x!R&Q13a>VWia2W_%LRzdH6 zi_)Q7jo#W}6C4f^^zJuP3FW5H6ZC#d1FltLaC(X+V?sF_DnXfUYskKJvuBw4F)r=m z@D)mV9q{2UiL;)|i&d8oP`=v9lboAA1$b>$x++>&Zz&a z$$p17dIZ%bDr4U1CDhwip0yalC)Q4+U=bz{I>V$xDIrehJQD3qiqV<C=dtNX3?6 zPQ`9~m{u4@Tnud(_dtr`ltjy6cIE*5sBa#WlGQG>>U=x4FLK9$-6U^`GTouxKtfJ; zxu+-kFVQ;{JJeYpRFkl_1)5z!+4<7IBjY6hFrFKPuHPDr@zJddA=X9vpIDhX7u-Uz zLLLI%U6O{yyx<}`E(O+qi=>_IQb!4PLj9rFQb+Qmu(wDZ$7yJLH`o@4V%}6~+Fa6j z8QU%W*?Hj27i@AQ7O8JwAdzzuwapg|DChn-fp<@`hR>#Qbii228=$T0@-h4KGeShi zz<>tltp5>FWON=}Wl`b(Z-3DTUuS&{qRJa_VG9&spS%==T}l4Dk!feS zkoGFL#6&hjOk|D0;Q~`w-%$3?H(~zjzk!=08pq(zogXh* zdzx?KCv826%SjmHuuNq80!vDcm?b5BQ&P#9@z3u|Zo%AR1qB0(E*6AxGC(#6 z3ECXgn2%>`o_Sq}AIvFG>Yfyle4P1(a;mh@4Z^CcrG>vxUA^XjYjf1KCF}hs3{7U90AR>rm9y7Ihtqy4s_zx8Z6Push&V>eA4wgz6ml z)nL2W%iu3m$8J<}B}HAyQCCXTH9G3zLU23jP{+Oso5OWHx~aik7>%_w>RJ|cl|@~v zqpot@6`X3r%=^6g+836`7R`*Fryp1z<8k^>JS!e@l?_E#i!ot{tjpF`N%SY$xcVJ> z%qZ%FmsqfxE9J*n97ThIrqrfS1S^2`FoJEK1c`EbaaM+kJ@{?KyMzh{bQp!HxGA-9?9d{ z94@?LA$fjqv7vS;G|&QTNZZTT?>OjdmilUC$U7D#kV5f7zV?n2AKo-t5H3E2%2Yd6 zOoBCI)&J;-YPUD_N5Ch*N(M^5quqzqw0{LwT-u1icSd}#OKGxJ}8 zkBW+F0hMBKdi32`+88*QZ3Dl5BfYp3LEJFpz1WHw?xt5zb+erwTr_gbQQvx}ADaI! z;8O;A#n7sxKN2Pa5g+X7t2PX(=uSc!8{#$&xiRF;qNVpSiy-)e=d`Tz z@>x7(t{=KcJ%ckC*sK%hIf{#Lbw}NNE%?Ek4S_;F*kVhN)Prw9d}w8TE~%aHk^l1A zhb_PJ53hYV?qz=he4&WjimB!G+-kfU3FRwNo2}4EhC{`XIa#;|s%_Qn!QzX7o{lUo zy=q~m(uw&8*8hL`dHPqe&fLq=;i{7I*wf4*-huPnD|qh3($~yEsR;Zq2n9v|6ncz( zmKaMOGe$k-F^+X1(H$ldew$5q zcB7T$=&;yrT4a$=wp(Ohldoh+`YD^p z3q(L}kGw#1iq-Hn_!6ioTZu60$=&1|iaONCg5ZBJV(_ICOtw`d7SUUPxZDyE`J6Ys zH)&l1e~Gg?Uhd~4DuqJ1G{8S0=4}pK;>J}rj|+ODpf)J-0?841fux9xtm0-jZhR$f ziafkhevFhEqGE&JEr`~?R19RPn6g;CoTd5>-O5&ynWZ}F8;Uy^(NZxm_!6_L6Oaiw zjQjABQf2EQgsFeQsvtPKV73OdNPX#QaRy__J?GumudR0Q3<-Me1tmE2BOix?Lcdj6 za7FFIiBfQp!&$!*5XFY|ci|{)h{IHH>mzVxWmm7q&UtMXcHGv;Z{ih~chV#7Pn`Lj zr;g%zYUfMwMP)tcRc5Qd;6$vj7h|}?3)PnIV_x2Hb^0rNc#I=6$u}IA8geGp<730e zo!2V1sgaCL+4w5!#Se6$sSh#zJf6b`6fZ7-<75c0MLIVwH8#n2SsB;!N?Oo3)R7`0bTQeLtsJt|3tIU30%gO>Iixf z2()<6B2sgyj?a4IfK7C^4kFp|BF30{{!0eh_M8!)A~JkvYUKSGDrgK0KEkx&D@ zZ^0u~UPl3u4SHSu$oi6&k__e>SH=SbCF+m4QwEx_hDy|@@g;VMO4M(N$jP7zjxtyf z1+&RTKu~xX6dI)d=4lxTT1*x-mMJK5he44HM2J%4n!fj0b=r*7((Cor;vFKDjTRK@ z#r%{UWK`84`TviIW*UT^QnzaeKFcAqwT*v8fGFc+}bWU!aMTcQ?^#@N&MhJ2 z4@F2L+aN_MrDbpqcj1W-*o(TL4}fn+D>)hf<(u1)^$O>?eSs$EInK<6jtam0wuya4^XQ)dawB-4Lwg3DsMCe&J;MeED(;u>MI^- z%6PF5#j%D`k17QjL9F;r^M4w8{CNs%_zTu#$|ad{T*R9t&&+}r5%i7cuQ8(7a1$8sbA6yzVvdDQN@L9QY%R+c{ z;?cqv%TW^Wvyw9!2fA7XUo`#`d|}jY>%Xdg)4p*1X0v{~2B=^9iT3ZhQ2kyFNpsNl zzmzpB4ch)|jrtv+{im2}@zEmlN3Ho|m-x6q{XS}Dhes*U7*+acw)umV9XL~DwEwx) z*FoldaW2Rylu)J~73as4g0yHq@PAU@T)X?1wC8bOxV}Yy-#b8k(~tH2W9&o^-rwJX zIvcdU=d-@M(4tN4+0@@Jy+C~zm}}K%{@8B*ICRna?lDInZLZ=X^T!5J-}8<7UdaA_ z+=~lAPOZNm7p-S;F(3Z_WPgt)j(L8z+dHmi1}2ADpq?Ch5xt_+{b%R4rtUX}wPLMO z>`cx~liQo#i<=#}vsk?j6E=B-f(ve#?e$yF4AzWW61?snxg<>yahFnH0mhWC!@VgktnuhU9XEcD^!JZW%~y;Ta1}a`DBN2&KsSxmTNXK73>3`**=N zdftB*e50lRYv8+wOWQ0if843&um?M9hazM6UJs}Sn#Q3@d}B(>_D+Q8Rnr^!$|^^R zdNpo3i8Cz;rRou|`~n;#=uA}GqTVIy9^u_0YB(~6YO5k+MvLE8ELlXx?C09XB=vh1 zm*lfTflkRP+p3hv$a;7$SRi*{TRjV^Af97{=T6`U2PTHBN}9j8IdBs+;Vf=ml~}fU zJ&xDZBG16`x24EVtE{WLqz2dS$e2b!g}wMKDXT@&$jH@1bC8m!H)e~HtLGpX zmpwQM1%Dm@L$=Z1qx(q`n^Zw&vu6jyQcJ0G6YuRjTmD_4QDf^!d=&hy9T-1Huk^^W zXOoaG4`LMAI`I&WZv+ls9_VuZVi@M;U7ZOi7?MEDdK+otpzi#7_1i2__)&Okl9so>1sO#rRzlJa*qs=%OxkAYZv1eNX2zfpZa`9Za)}MAS18)uWY| zyb%-ynNST~rj0-}z438t_&3547MJX+9k^`rU+~Zfg99VoBJsfF!J7l#2?FA(xFxetD43qaOymH8OF5I?Gqo*GgMz}+??6qwY3G?Fj5 zjJ6s8NF?(OhYCvG{lm-6@Qw@-71)@qZ!bI8!J*PE{vqlV)DR+TtS{aW1@H2OhgGh! z9c(W}l&l)FS!XBG-{Q%hYDaLAYa8g}!J8g_$An3Q?yNrs#Gy!iNFWmD&wREG7z2?J z1|n?&04tprw{%~%8q=$20GGIofN5`>(*gn!i~ly1_7;Q`vt6Vi#Bg(_Y~*x_?ip#r zv=K;H{nHI#S0Y+>`!$U>vJAcqBSoqn9szE69T!haS@1rtr(<@J`a1Ug7c6L&m#a9I zatf(X?tbmIMWsT_X1vT98bVs2Jw-&z9hm`cU1fRh30B9Os1D-X4m&W3UV!Siud=9( ztf;a}Y*M4zMCT$Vt~)sz#9no!x(by7;tg39x8RRodamk8(0aI!zaz`}d+loejxXcy zq-FSBv1Q~oVGXYr*0oE8HDsZ%#>^Mit#e^L{q-T6VaXopxeda$Jy#1`@z|f+!tYIQ zW2GWAq!l%4ku1`)41BI0U!fsY_$9)jAsa*}7TSkw)?KS?^B-uGLbY4)&9fcaw=9N< z;EW+X_-^XJ9ZehA2H$1J$k3FcFgI;p@H4%#|spuaH?F9UHJV6G)NGliu`hn{*@2h;U!#4~M6d)Cj-n`wc zjzDFBLyYWK!yh?E#%vQk^%n8FS^U=G*H|m0T{gjut?9^k0V;2_3+o{+1tzt_I5+rZ zPjC7kih|442ws!qs}f?&K*xrwi<+Wj=%DFZ7KC^P?pdNW?AhAbkqExl+H=|VbaWmZ ztJV8aErI<>97%ivr*acc;62D&>96vTNkNvi)%ly8MCWf7#N#;?YZDgDub~dSatEHk zx&$x0TMxU>R1BRGXdLT)twQA)_vk|@ed|@L&Xu{Ukhv)7v&6DU91+xxMSj`SgW^TY zf^wpSj8q2WQa9iiOGRh`bAi{b^efUr=AfN%iLKE$QO+I>McdtNfewpK9y3M6>UuNk zQHG>jmx%_|=zO9H7u)-4j8_NxNT?;y3ZT*Bw}p3O;y=OeLr=S?Sr8_@v2H?Xq)nYXZGk_rfRY9Wt`!fQEfU8plY5T{wA`4mCr#AlV8nQwhJF1=yXg zO^0zLs%iM8`J5lRhP8qpw&7O%(V%E)V&w-9*1UAG%;I{PKb^zmc+f5`(iUjJBR3T| zm&5SW4Cl{4;gIgi1jj7HZ`qUV*HTa;3&2TBh5thFJ74_H6~9H|cLsiOcOr>+eIIV8ZA*@{9g)%Kq5LrZy@ZFhcgJ1p+Y;}JI5kmqeu<41(7j3 zL7~W)9pd+S@w;98J}rKq6u(c1-)-V|i})=Nzj@*}P4hvY6d99;-`UEH(YDl9$X;zX zw#xg*NL{GI){3EW(}E|^BiKea-zs4_Vw2PvM*i6%-3s&L5V@;~Aq=!4=`dalr)WmgsMnBbI!H zfy1`Y5V1-N9@0v~Aj$5#L)b3gErG*!EeiTqJ<5(0-{pbBDVjIhvhHo%rZ+7miUthI zh3DUb!KJVZk3xkD>6|;-u1s;r(@v(hs#&=0v8M<89(G^|!u!ge-RMP}^_Y#K0q;Hs zwRPbnBtrjz0NfeV1O5S}ZQ;n57+`?g1#o}oEs$wFaPdCKo^dMy_*alQ^xhEgk*pQT zU=yF;8_u+FT&lQ97XHkP;vqnKO29;GSHDh}O9^v{0TbMSo`G{N$S8P^p~)3~Y8=7C znH=6qr@-&DJgo~53JKwPLbz6gpeTEBzB@eTopTXI*+Azs;ao=N&u<1wif}#;r%}=d zI|2br5{R*|pW+4ZsxC)h`6h0qL0V1+zyNMsRgCCBC?eK3VV?>A(Ji3Lw zH~bN7jYwPMX`2E69rPC1Hr6=eC_eV=VrI_*Nu5Ztr>(F4Jcmqq9TIsx4UjsE9g?TD z0%n65W;J2j9stZj4JOeki=y$iJgpr`N<|WzhQ>4|$!3zPkpvo>!&M(Z!Zx`0dBndN zQ8WTw%g9?8`R~}&67^ZmiWw5k!XY=zg%47F%o`wrtbc=R&mN}wjh0F;tf23Sa1tvR zbZ)$fc4K%CZKaBEe+s9(iEHG75?BC~0{_WR5Mx{T>j(wmcZ44kDUz7tcVRFNfK<|} z@I?4`X3UO(pIH7VW`)E|C1%&^t4!~SNw4gOycniRWks?71J17rXDgj|0idEh&j`E!%=V|! z`6J;J5w0`k*f0Zu$aJX4l&wc%rpXT?)3zRiq4oCu{%As;%NF>iaPDQhJR+Qj=(}Gy zMRWcUrg4gLk`aC;e0MU!bHe#Nots63V~n8mL3p$e!u^~g>I~el3-N&5eY|HPdg29e z?I|akUy7m`Wk^NIWBvXC%4eex3g80>H!xin(|wG4Sb7S%u$6u6cybw?$>CcJ=h*P= ze`84;1ekGsUtKrYHGpj=Nv|~kNKFbx{eu5*?29|?Y2^Ihh^V!sXP9IulRT&;F_4_5 zBHl)ZZei#w10b#!h?WDH1mjoNIWZ8FMaJxcT%!#TDUmUU@PW(DkujU;Fj_t#-b#ok z2=O1dgA5c0gtycT&mI}GcTjkL!nLnGDQf}mr~foO4rR8mHO)jMqWUO7FC^$W8fZaK zHqxFHBkF#6S|g&CB5Jf7p2l?BneJ+&WBk@={JrwDJ&1p^IsVm*e~9rvfCxGuJ<84W zNWubTKYD1Ra_;R0QWy@1|Gp0Zw})`Q3Aj3YVf@(3aZ~=CtqmfRt{EXyy2$8yR zyUai>O5Z21H;SSUN!?)+eLuj*o=hfwkyq0U?m7XuM;Nq>K|e6y_6z?x!@C&1F&eJ( zvnF;4ehzO&ef5c5q~$s$+)#mpUL&E7wNls?E?dBQZVNZgG2uhW>MkbR!DLP&8RKQ@ z@wdgscQU@K67k=K*r?G%$v}r2ejg)^qSVtl^nd7FP3OBHl%njX^H`K-7%(OHAp1rY z_=qm*1-SN95%6OMU>$#h-}=h0hBpINU-?PcbxgmP>Af-OmBN#eF(=56Mn$}h_+G}x zGhD9l6*2L{oqqr`6n2DfB*KLq6jGB+xKCs91SU`PA^GbN0d-6@EBq6Y{zUjM*D?JG zrf;Xy$i4&VLw`g1dZzzwYR+l9R|ya$q9H2rp@e;nyG!c`N}X+ol8 z3l#8@Vz^ACYYi_I_O5W1IX(N=e38Bvu1QRv=12PBed!C#@pmHDmC^Xa8Gkk7{|TZa z@Px*9JRE*Ud7EL@D1M*q5|L;Tune4XUi&-i5q`lk~BnvEsK@J}ImqI{tt z$=fWhT_qTe1wBJUl48CS`+dv9cVhyM6WaqkfAHJq5fuI{q%h?D|I@!GHdv$|!ZgAh zhUtL$5JsxDNG_O?uUn*Sm|I|6FsHX74on+NBMkqx!oC~kCYY0oMLGb}0J8#S8q94l zE|}9>5C-!E%xaiyn9(pjvPIepvjJuz%%=?&=>?c_m|I{vg1`}`1SSQhW3xqC2a^SJ z`f-c&B8(4aB8&~@@M9KfGfWc!uVVSV4-$sqPSL!gaVj6K^esn>F;nl%@S8FlEzOZUQm(WB zW(HihNmHb$(o7K}Z)L^u`+RFF9>$k<sd{krn#zgyF1v5is4}0geB$l5!+l%jT7SiT%U7(exPSR=YnJQR%kZf7PlR#y5}uDO4*21Xi{g0;%!754&-Nu#{?R{9vHc=^2*_m!pO z=2fg*w|wfFWy`Bla#K@Na*C!#qc2~Ucdu{xq)`Mj5hm*{pp&w0c}3;QwQDAg`togQ zqf(Zyxo_<<+lu{B+J}M=5YTl$# zX=&b^;^0k#KeJG{0 zPSjr3+{r1vwQEyQtoxy~QHvAx`0BmOQtks;33D|_-#@k_ZMhdq`>Mv{<%qK#-;Dvu zwXI5WZHL(f<9Y;}Ea3U=usdM#;GPV#t44CQZIoP%wFs}1T(vM&NPkL)w-oSN@tp>E z3lYBrCaoNKRcP>*!kz{{170J(xA`PjCj9Pz83(f)>Hng`n-6&W<9<&f@f<0+mW~BX zm^PY3!2OcN<$~#;KWqu{y5Qdd!|=h(Sj1~X+b_Qy<$%E@A=lE&&0vJTr!WkD zMp%&^RtvvvFy^pjde~*?H)zaZtbb8AYuD&ZD@iHK5GO3Tk`VW8q+R-<)V~30&aLhN-;|b%VHLVH@d5C;koBtmyBCQi}__$`Tt6@2+qm{U(^ry8q2^ zZ-bkCSr*I_x|{9wA^%#zNB2HhF5L?*gqO4$KKH|9L5pzK4Y%G(zpNW*?#a!|nVWMD zzhM?Fnk?OV>tyLJ03xglwbpray=bjy1IQr-e~2!Pxes`bsdUrL_LYUelrfc}17KNh z2hgnB$5awF@fcId+~B@zOeOQox!tloZ(B*cL~}m~r?vn>2izO$NTr2A`(CuABnX*B5qT=HV){xS+9K znp2!tyz)DzRz7laYQcZEee+#^@7nJZ@7#$C*RQR3U}68E`_>0BbRKQTXer2unk-ddo^e(=nVY((G+nD2BCKc!nPrd{L4RcI%z5T$w9(g z2vY~iF9l(V-_Yn73o{L2nF!+;78{n0FyA0yMF`u4uz||A6k)D!;Rw?JFxwC|_M6%` z$%-|XuNGk^0nv3wj-<^VFs;@up&4b z5w=Xnlm2Erx5cD0hcTTQ7jsxFF6J=eVx)`BPox7qjWU?ibs^nSgfR{O%wZh}(|ol) zF->pl^kbPvo4(msX2yIMn7$c*zUiB|EHi!cq`>N!?|RcW(?6|$GcWSSF;h6}q&Mc< zrS~le68L7AzL|fv>09*m`ZwK_X?B?4G5%areBx7J`o^ckHp%u!xADg|+!f=;_9>ZY z%eZWpt{6YI$CMa9w!<{tZzrF$j!ugm3t2|G0DE zmj^$l+k42jCgMk67MwNj2N zCBY1oZ-yy8@u-dY-W*eoV=-lw0H1YjW;V=acQ%TS)Ya<(=5ezEKM2C zdLYe>xU^YstRu4@>zQ?G_z`9q;uH*mQxa%O9yH>c+me|tS+=(U$2LgZHo)19uz|{* zrPsZY2VpS2@lBg)8E=cJ{M!bpYnFw0o71zsv2E=^nt|v?o+AI`fi|(>EZa^~JrXVs z5lh9{So4MX6lO{e){|lKrdXt3zzoU7S~^S_%=cl&=UJq0!L-4+JXm*z`I6TnJpi*8 zMulj+QE|R8PPZQMBaD1r0NSZc1O*?Gn{TJB8??W91$EDVbz(~o_a2*Gm zFunqtI5U46&c(qx@6RabQa$YhdfIimU8nmKjsvNSE&zwXNwY>h%|RW;ao8-&d$3uK zldy?XxBeYBMe`pH8+WLrB-oVWZ`AGEU{ju(0GoK=a*lND0(cOIa>PY6sR}mBSPPpt zJf(j>3!6Cn2sU97udxqYm_{9li)hkG*vx}A(-Qu&i=<7<)zWq#9bxRn`Apj9^zUEa zE=6JOx(KYLfMw+S_C?}u)AMC~($Ix7Y|J6i?Hf-W-_gY+(=P!rN@9T8?ZwO~Q`b3ZS57^9~uoBl?m<~$;gK>#> z_C?}uLtI3Yz7LzQ{|h$p{DlsKe)SiD(V@p>x?PCNG>tK7=*RNGirRGZk6|>&kR}_p z@wezftzEGm>}xMv=Cph*ybv~FEr3lLFm2vN($?x}pV8C)NKZ@p)m|iRo1XUXdfGF( z9aqp-U;8ftBh3`I>mqTN>T!u%a`}a6vJG(&P5LQp(&V?gy-$b1w!IWESZ~{6U@?Ad zeet^sX&Ik?hE4w-_-np>^|=QyNq-vROPHIIi6%9F7a3zlg7Z!NL!9H^z*|eZq=|2K4u(q+w}ofHa+z}=N~j$Fuxso zer*@YZ;lH+oi`Pza_1|aM@F4YT;vH6X$f;EN>2M z^1v+EMt{2OBCu)^7fGbeunFrsunFsV-QSo890IQ}p7H&0hL+CwZi@;3QKlB|gS{EX zh<7X|-js>`;h6KOL)edF!rM*hr)FUf5Qg|>R$*TRhB$V8OS2JG;LQ1Z5vLMnBa96549t&V_QD*3 z;V6@Uo-Q6z$`FjyrXAX4t5-|8IB(|Dj$TQ5*u*v5o~rV-6+Uq!OY&AMUp{AfrGK@r za*BV&iscnj{&JswWNXD*X~x=nmx+kpinR~st*m@ND!x}g%{6ze_AQQip^m;re6+u0 zp2aJ|8V=8N>VJ2_Z|)qNZG5E9Z#T{o;uf*A!IbuwIM0b&yGF8p_WwOM`hU-j{=3eN z?$etK+fb?Wl{hp5I;XC|DaZ%!ULWiF2?D%^QYp=ilt2fCYTlogqmVO95J01@X~2zn6s$8u(8igH(ee!S4B}V zwN>`f?~WQXfcxC|)>SZe&3BoyRClBa+jTvZoKx(TK~LN@VOpw+O3)3Sy@pDecrzge zyHAfbp9>uoZ%hk-)^S`9wQZvpJN+I@tB=JZ9w*H!%N+PrbaJz+|ehz!6^2O z;t5YE67(<+;hV31S$&)dOkEL3&c=ep)pHkdJe$B}m}(ba74f_4;UF&8$N-s+#QZR+ z$(dm;o&+m~FiCE2G|p^7?*KM7?>0lemg*k)HfM@^MXWK=7e#Cs&&`cQYP=EZBG`q* zoH@zuX^1UzI}MqKC%YRCOU;-JHR|JdtbsZG@OQVLsX*`1xZ6kFahX5r4u-?<$Zkl- z<*LS@;xtJ+k%PRa|A~dV`**J0A7a$78PIM3cn-q{xM%=4fvrf8(-v(Cw%+p|_XO+r0X4 z#6QAfl(4EOo|^(LS4EL~NhuxF+$lED?P*#TjE_vwDD7QY=)N3g`O{>(-sgfgVV~c- zBJL`NF&q=})$E8xc~>FByh8P%zUaa<#TwM!`p-9FiNSZlQXNtqa}3k$0gz*vEiT@ed3 zpRxoBeP$Y3m%-&mTc4!c%R|udv>_3hAZL+uIiySAMG#4B*+33WkO2p(D<9bT8`lol~ zz8q+pIPkH{)IVJ+r{x&=a zR5;rCiLL7RHw7RBuq=knOq$|&VdJR^!8qKPf&Sc=Q7P4_Huw=Tjv$jHeu^CY6cwXm zAqk|MRJ)#bd`gX&@6*_j1k%Z&ZzMEtO0~f-l=BjVgV#tX%vms8N_NV3lBaWrL@2)hW}S zGaLx{C3v&SDS1v+3!ub_yfu(ej;!+^ZBHx3Q3g86X-y*Z%}KT=w9>OG=57po@y?WM zg#6r~q>;Q5l<6dB42ul12szpaER!{B8MR~_W4I!UTBVWZWiB_ZyFE0Abp)}AG>rxu zJpAVgnVx&e(Nnz$WM1xHnarM(pJTgs(rbt4s z<%7 zpARN;C5<`O%7soOAIY#W8%}SV(Wcn%jrs$wBTWq$()wtOu>_g~e#4o=W4ECwqSbH3 zX!Uz;N(p@{)n5^I>N)0XtoMxlec9x)n6m6A7iKn2(Zf>3zMP-^;%8CjMvu|YGh+#gW-;iT5 z|MVYvaOTtB{$+7eFkN%+sK)y~_*aX66IXu+7A4l-FGlJ=T2Z@P%-HKS3(BkO@lI_x z>cXqZtMFwJ<; zk7}!v%6TW~jPz>^u};*9B4DX&WbNSSeV(W&n$Ta;MwnH+Cw~07MM;@h2coDib^-8C zNI9w=CmE`t&BQT|E>J+9nQ|OUFNBoRGM{*=7JvaDUDvT)>?PcM>1JuYltno5 z5&4p2%6H3EN{=!_U83$+-`7spUouk7&#W`;vu(zOz2az>#(v4o;mi2D`7Gf&VV%$= z*y22~TD(X6mc&a>O8-h~$XD`Wfh81EucN75xqnY=-2A&^^N)@W1I1N;|n9j zoMZB4yE)IQg_fUNDfaocU~Bd@)SeZ1{}3NbSd)91`y=-!?mPUs{1to^e=C0ne~{P6 zeWX))OnFt=uIyD9^+}c0ex@BnKc#x7t{cVXM)N|e%zDOp&t~edj|sAFW`E4?14d?X z66fXaFGC$&LspBBPsPdA8BYFupY z!8psU8!;pQZDrZ#*caG^cBLJ(8|_!@oi_fA&a^|v^V$2^H@WvXSx6NZiCe^N(jTOQ z($`Wp;mJI*h}023Sw|iv{p7b~m`svq%IC?fEXm8|=j1o!o${CRca$Z{HA)z0xmS5y zd0y#Pb}D6RtvaAi)7EJlv}d*5T2TL^eo#*{!p8TF&Bpa+ubF9S)(zGJK=zq-fqjcj z8J61Y4E93SVq4iy*{NJUcMW$p_cZqkw-c62=cn-nd=X#GFXbbA6aNIim;aidDr5@9 zLR`3AxJTG1?7%3_7V|_=+$Ii)`@~`K9VwRx2<~skVEp#a+|zW-X{M}c}uwq z9`|Q024vr;Kd3*a_v?b88p{pVtTs29f?WiAJ!|*bA5o0JV9oegz%FL5XYXXwxkbE( zzmLxsE*7p5z7%rA*%FcFl3U0Da+UnFyiYzL&r)P%zS5xFq};FkRY_N8s&}b_>SFCm zEu;y0kzS=o;8Bn0b;bzm<^pT6^_;cE+HDP5uiD#bznzIdvxuz$1AT#hujAUd zF76N9On#>@BrF!a;tk>^@gq@@E|t2aXQa2KKS?#@Qn^z8wY)=4Q?it8$}Z)4^<6bx zleJs4Htlik=h`+cP0vE_AL-vVY~u!_#dy$o%6Ji;l5SpL1*~T41M4l?e~;rH%tE%6 z+s1vw&F1F|_lQI)m3}Gp0*yiC5%@)#dXctLpK0V90khfsk$J!QklAg%Ztgd~GSjSY zSm#*8`Y-E`^w6BGc(({2pRzyW+W9Z}YB4CLlWF8y@U)b z!lr%Tr;v3mMs$O9v-KluGrVHhI?bMLGyCzb5_I_&_6)X#y$>AU1CH-w-(cTk30J~B z#a+bTCfqA@3Oj}A;wYGGr1hDoQrYyaM$szd>6lk-^S+&Jwm#eAx;-F#YS;Z z3`#d4Qd~st07D;;XDYdhuH2_QqV}q_KxwYwH6Ah&ea^9J?PmKn`$^gtRw(N5v4=g# zp2p4LYWWWSIY@tpp9h4zE0#!Wr01lUAxos*MKY2S%%LkMSF0 zx3SO2HZL?Kb2;X6Ej-}`)3knPd2J>q#qrb0u-9E+w;9|c+;iL@_XPhIuL$20)(TGv ze(^@JUHpmokhn|yO1wl`h{*RdX}k0RnB{CzNkZg0aufLld7q@nvt(0VDzBCAm46|> zFQ+K8l(|YN;?5?eS#41tRi9SBRyD0mtJEly|5|@TKO2!}nGrRb%@*@f^J(*IQv>f- zT0uK*-(x>ue~Ng6_ac#d{Tr*Y#q28Xe(r7V5KznWSM$sHoB2EW7x~xtef($q*}_G_ zJh1Thg&ztJ3eO0A!XzLegy`dre>J@6WdX?%| z8-Vb&>TT*B>fP#3)yLH5)mPNF5T!p;J=%+i)URsWwfD5IwKDy3{c7E(Z_{7X-_gI+ z&oE{fTaCAk58>f|2V!+|u32GLnGv%IQE{DlpV@_(-i*24YHl+>H2(^gzQDTJ62a9j zi$;@0R*iMF<+HA_BGw9PwY3SJ^b6}X>wW7JE8AWR4BlyX+ppP!3BGjUY)N2oGJ85Z zi_K;I?2GKTxY=AK_XOwVw_^r!g(X6Z@Pbe&J_D{UkRFgq$r|zoNkx{#mk;6r#xYR7Ih9|X1tx_B2z5^M}2B}lpDD_C2rCw=^ zv{mYp`lSJ&euuP6+9M50d!-?1SlSPKq>~IXon(?Ml1*|D+4D&OVTni-Vh|T8CZ(jD zRKQPaNG;;8j|AZ{5fTTER>L|iKvElNCmm!x*?^2-Bk3aDq=#%qgxf;4l0LGB43fQM z2=RJ9BGEx|h%j=hoGxd`)8$M#OU{;a54nU(DTdFLD-}wmQlr!=b;$mL zN=S()aiv*Vt*lX65Z&9rza7X_Hz=LTM$AArvbN1iFYvlm=|j{XP<9~3>`?}h9}OWZ z*{>W>4l0L`E2XOGYKA%;h|W^8f$3Z|AE;(kQB_n!b*aU`cDY)iR;o3~8|qY_8dO7S zM2)M>>S}cjc%W5nQ`^-Jb-lVl?Nm3aU23=5qizNlZc(?YeQH0ljqS)(cd2_2UH7U( z>M*j&1L{HbkczEbTDq2@P1iEDEG=8h(Q>tXtw3WnQByQSb7{p|saCF4fMaU3TCGm= zX+cEih!)qHwbj}htwn1^#BA3(wDrhmI>DM1M#P94&Bkg(*;b>?Xa_Pk7@bBJa_Ao9M7_oq_-3EcZwwea zj9tbaW6;=Z3>m}5exUb|!I-ILx;fpsna>`3*gk}u7H68G=*?iW*#g#J%h_5sgu1AW-N1GurVX%r*kSe% zo54*-Y|G_DPT@)s<7&A&F2cpR7Os_B&u!qkxgKsS*T?PPc5y@8FnF2av-oUY=zDwAFmbf7v5h-QJ^THrPW%&rDr+kn*#z-c!Sx(k)TkhUMS3ZrM}1-hsks9A!j z+vH*+6cAAp*C>Ky4*38w5_nI`Efk7LQ=gXNG{f z4XAy(5jVCV&l)gyAQRea4kH`NvU06rM2$++TS2Q8SbiiLUc~*qK+AM7 zTg(-UfsslvBCY{KI>gQ57O@Y=*bii6OSw`3a8cu+A`aH?1RDB*h6AY4a=_y(IJ_7r z2!X5D0|9+xJ2?0d$;QmnXm22@1u^r@nEOu5H=XSvIaNtVc9*ZPil`W1;TkY-5WL$0 z&g}rx_JCgpP`x&bfFGo r+%IH^`N&p#fpI#D3PiAWM5#fbHy8Q_5luD&r3~UisSM%&kAMCLYhsJK literal 111616 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 From 660b46da77331840f013f64cfefe1d7edafe1eb6 Mon Sep 17 00:00:00 2001 From: Anonymous Coward Date: Thu, 11 Feb 2016 21:01:48 +0100 Subject: [PATCH 4/4] Fix compilation for Win8 SDK; Fix encoding for UTF-16 surrogate pairs (SMP) --- FileSearch/CDriveIndex.cpp | 2635 ++++++++++++++++++------------------ FileSearch/gel.cpp | 67 +- Release/Exportall.ahk | 277 ++-- Release/FileSearch.dll | Bin 106496 -> 107520 bytes Release/FileSearch.exp | Bin 0 -> 2074 bytes x64/Release/FileSearch.dll | Bin 142848 -> 128512 bytes 6 files changed, 1499 insertions(+), 1480 deletions(-) create mode 100644 Release/FileSearch.exp diff --git a/FileSearch/CDriveIndex.cpp b/FileSearch/CDriveIndex.cpp index 061865c..38e9b18 100644 --- a/FileSearch/CDriveIndex.cpp +++ b/FileSearch/CDriveIndex.cpp @@ -1,1314 +1,1323 @@ -/********************************************************************************** -Module name: CDriveIndex.cpp -Written by: Christian Sander -Credits for original code this is based on: Jeffrey Cooperstein & Jeffrey Richter -**********************************************************************************/ - -#include "stdafx.h" -#include "CDriveIndex.h" -#include -#include -#include -#include -#include -#include - -#include "lz4.h" - -#include "stxutif.h" -using namespace gel; - -using namespace tinyxml2; - -namespace { -template -T swap_endian(T u) -{ - union - { - T u; - unsigned char u8[sizeof(T)]; - } source, dest; - - source.u = u; - - for (size_t k = 0; k < sizeof(T); k++) - dest.u8[k] = source.u8[sizeof(T) - k - 1]; - - return dest.u; -} -}; - - -// Exported function to create the index of a drive -CDriveIndex* _stdcall CreateIndex(WCHAR cDrive) -{ - CDriveIndex *di = new CDriveIndex(); - di->Init(cDrive); - di->PopulateIndex(); - DriveInfo info(di->GetInfo()); - if (info.NumFiles <= 2) - { - delete di; - di = 0; - } - return di; -} - - - -// Exported function to delete the index of a drive -void _stdcall DeleteIndex(CDriveIndex *di) -{ - if(dynamic_cast(di)) - delete di; -} - -void CDriveIndex::attach(vector &dirHandles, unordered_map::size_type> &umDirFrnToHandle, int NodeType, DWORDLONG Index) const -{ - if (umDirFrnToHandle.find(Index) != umDirFrnToHandle.end()) { // already processed? - return; - } - - USNEntry file = FRNToName(Index); - if (file.ParentIndex == 0) { // No upper directory - return; - } - if(!(file.ParentIndex == 0 && file.Name.length() == 2 && file.Name[1] == wchar_t(L':'))) // to exclude drive itself - { - SearchResultFile srf; - srf.Filename = file.Name; - srf.Path.reserve(MAX_PATH); - // Obtain path into buffer, and split it - Get(Index, &srf.Path); - if(srf.Path.length() < 3) { - return; - } - - WCHAR szDrive[_MAX_DRIVE]; - WCHAR szPath[_MAX_PATH]; - WCHAR szName[_MAX_FNAME]; - WCHAR szExt[_MAX_EXT]; - _wsplitpath(srf.Path.c_str(), szDrive, szPath, szName, szExt); - - // Skip metadata files and other special directories - int compareCount = sizeof(L"$RECYCLE.BIN") / sizeof(WCHAR) - 1; - if (*szDrive == wchar_t(0) || srf.Path.compare(3, compareCount, L"$RECYCLE.BIN", compareCount) == 0) { - return; - } - - unordered_map::size_type>::const_iterator it(umDirFrnToHandle.find(file.ParentIndex)); - if (it == umDirFrnToHandle.end()) { - attach(dirHandles, umDirFrnToHandle, IN_DIRECTORIES, file.ParentIndex); - } - it = umDirFrnToHandle.find(file.ParentIndex); - if (it == umDirFrnToHandle.end()) { - return; // unexpected - } - XMLHandle parentHandle(dirHandles[it->second]); - - XMLNode * parent = parentHandle.ToNode(); - if (!parent) { - return; - } - - XMLElement * element = parent->GetDocument()->NewElement( (NodeType == IN_DIRECTORIES) ? "Directory" : "File" ); - element->SetAttribute("Name", stdx::wstring_to_utf8(file.Name).c_str()); - - if (NodeType == IN_DIRECTORIES) { - vector::iterator insertedIt(dirHandles.insert(dirHandles.end(), XMLHandle(element))); - umDirFrnToHandle[Index] = insertedIt - dirHandles.begin(); - } - else { - HANDLE hFile = CreateFile( srf.Path.c_str(), 0, - FILE_SHARE_READ, 0, OPEN_EXISTING, - FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, 0 ); - if (hFile != INVALID_HANDLE_VALUE) { - BY_HANDLE_FILE_INFORMATION FileInfo = {0}; - GetFileInformationByHandle(hFile, &FileInfo); - if (!(FileInfo.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) { - ULARGE_INTEGER filesize = {FileInfo.nFileSizeLow, FileInfo.nFileSizeHigh}; - element->SetAttribute("Size", std::to_string(DWORDLONG(filesize.QuadPart)).c_str());; - } - CloseHandle(hFile); - } - } - - parent->InsertEndChild(element); - } -} - - -// Exports database to an exchange format. -// format is ignored for now, pass 0 for the default format. -// returns number of processed entries and 0 if an error occured. -BOOL CDriveIndex::ExportToFileListing(wstring &strPath, int format) const -{ - if (format < ExportFormat::ExportFormatAdcXml || format > ExportFormat::ExportFormatAdcXml_LZ4) { - return FALSE; - } - vector results; - XMLDocument doc; - XMLPrinter printer; - __time64_t tm; - CHAR tmbuf[200]; - - _time64(&tm); - strftime(tmbuf, sizeof(tmbuf) / sizeof(tmbuf[0]), "%Y-%m-%dT%H:%M:%SZ", _gmtime64(&tm)); - - stringstream emptyxml; - emptyxml << - "\n" - ""; - - XMLError err = doc.Parse(emptyxml.str().c_str()); - if (err != XML_SUCCESS) { - return false; - } - XMLHandle docHandle( &doc ); - - vector dirHandles; - dirHandles.reserve(rgDirectories.size()); - unordered_map::size_type> umDirFrnToHandle; - - vector::iterator insertedIt(dirHandles.insert(dirHandles.end(), XMLHandle(docHandle.FirstChildElement()))); - umDirFrnToHandle[m_dwDriveFRN] = insertedIt - dirHandles.begin(); - - for(unsigned int j = 0; j != rgDirectories.size(); j++) { - const IndexedDirectory* i = &rgDirectories[j]; - attach(dirHandles, umDirFrnToHandle, IN_DIRECTORIES, i->Index); - } - for(unsigned int j = 0; j != rgFiles.size(); j++) { - const IndexedFile* i = &rgFiles[j]; - attach(dirHandles, umDirFrnToHandle, IN_FILES, i->Index); - } - doc.Print( &printer ); - - std::ofstream file; // closes at end of scope - file.open(strPath.c_str(), ios::out|ios::binary|ios::trunc); - if (file.is_open()) - { - if (format == ExportFormat::ExportFormatAdcXml) { - file.write(printer.CStr(), printer.CStrSize() - 1); - return file.good(); - } - else if (format == ExportFormat::ExportFormatAdcXml_LZ4) { - int const uncompressed_size = printer.CStrSize() - 1; - int max_compressed_size = LZ4_compressBound( uncompressed_size ); - std::unique_ptr compressed( new char[max_compressed_size] ); - int const compressed_size = LZ4_compress( printer.CStr(), compressed.get(), uncompressed_size ); - int const final_compressed_size = ( compressed_size >= uncompressed_size ) ? uncompressed_size : compressed_size; - -#if defined(BIG_ENDIAN) - int value; - value = swap_endian(uncompressed_size); file.write(reinterpret_cast(&value), sizeof(int)); - value = swap_endian(final_compressed_size); file.write(reinterpret_cast(&value), sizeof(int)); -#else - file.write(reinterpret_cast(&uncompressed_size), sizeof(int)); - file.write(reinterpret_cast(&final_compressed_size), sizeof(int)); -#endif - file.write(( compressed_size >= uncompressed_size ) ? printer.CStr() : compressed.get(), final_compressed_size); - - return true; - } - } - - - return false; -} - - -// Exported function to search in the index of a drive. -// Returns a string that contains the filepaths of the results, -// separated by newlines for easier processing in non-C++ languages. -// nResults is -1 if more results than the limit were found and 0 if an error occured. In this case the return value is NULL. -WCHAR* _stdcall Search(CDriveIndex *di, WCHAR *szQuery, WCHAR *szPath, BOOL bSort, BOOL bEnhancedSearch, int maxResults, int *nResults) -{ - if(dynamic_cast(di) && szQuery) - { - vector results; - wstring result; - int numResults = di->Find(&wstring(szQuery), szPath != NULL ? &wstring(szPath) : NULL, &results, bSort, bEnhancedSearch, maxResults); - if(nResults != NULL) - *nResults = numResults; - for(unsigned int i = 0; i != results.size(); i++) - result += (i == 0 ? TEXT("") : TEXT("\n")) + results[i].Path + results[i].Filename; - WCHAR * szOutput = new WCHAR[result.length() + 1]; - ZeroMemory(szOutput, (result.length() + 1) * sizeof(szOutput[0])); - _snwprintf(szOutput, result.length(), TEXT("%s"), result.c_str()); - return szOutput; - } - if(nResults != NULL) - *nResults = 0; - return NULL; -} - - - -// Exported function to clear the memory of the string returned by Search(). -// This needs to be called after every call to Search to avoid memory leaks. -void _stdcall FreeResultsBuffer(WCHAR *szResults) -{ - if(szResults) - delete[] szResults; -} - - - -// Exported function that loads the database from disk -CDriveIndex* _stdcall LoadIndexFromDisk(WCHAR *szPath) -{ - if(szPath) - return new CDriveIndex(wstring(szPath)); - return NULL; -} - - - -// Exported function that saves the database to disk -BOOL _stdcall SaveIndexToDisk(CDriveIndex *di, WCHAR *szPath) -{ - if(dynamic_cast(di) && szPath) - return di->SaveToDisk(wstring(szPath)); - return false; -} - - -// Exported function that returns the number of files and directories -void _stdcall GetDriveInfo(CDriveIndex *di, DriveInfo *driveInfo) -{ - if(dynamic_cast(di)) - *driveInfo = di->GetInfo(); -} - - - -BOOL _stdcall ExportIndex(CDriveIndex *di, WCHAR *szPath, int format) -{ - if(dynamic_cast(di) && szPath) - return di->ExportToFileListing(wstring(szPath), format); - return false; -} - -// Constructor -CDriveIndex::CDriveIndex() -{ - // Initialize member variables - m_hVol = INVALID_HANDLE_VALUE; -} - - - -// Destructor -CDriveIndex::~CDriveIndex() -{ - CleanUp(); -} - - - -// Cleanup function to free resources -void CDriveIndex::CleanUp() -{ - // Cleanup the memory and handles we were using - if (m_hVol != INVALID_HANDLE_VALUE) - CloseHandle(m_hVol); -} - - - -// This is a helper function that opens a handle to the volume specified -// by the cDriveLetter parameter. -HANDLE CDriveIndex::Open(TCHAR cDriveLetter, DWORD dwAccess) -{ - TCHAR szVolumePath[_MAX_PATH]; - wsprintf(szVolumePath, TEXT("\\\\.\\%c:"), cDriveLetter); - HANDLE hCJ = CreateFile(szVolumePath, dwAccess, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); - return(hCJ); -} - - -// This function creates a journal on the volume. If a journal already -// exists this function will adjust the MaximumSize and AllocationDelta -// parameters of the journal -BOOL CDriveIndex::Create(DWORDLONG MaximumSize, DWORDLONG AllocationDelta) -{ - DWORD cb; - CREATE_USN_JOURNAL_DATA cujd; - cujd.MaximumSize = MaximumSize; - cujd.AllocationDelta = AllocationDelta; - BOOL fOk = DeviceIoControl(m_hVol, FSCTL_CREATE_USN_JOURNAL, - &cujd, sizeof(cujd), NULL, 0, &cb, NULL); - return(fOk); -} - -// Return statistics about the journal on the current volume -BOOL CDriveIndex::Query(PUSN_JOURNAL_DATA pUsnJournalData) const -{ - DWORD cb; - BOOL fOk = DeviceIoControl(m_hVol, FSCTL_QUERY_USN_JOURNAL, NULL, 0, - pUsnJournalData, sizeof(*pUsnJournalData), &cb, NULL); - return(fOk); -} - -// Call this to initialize the structure. The cDrive parameter -// specifies the drive that this instance will access. The cbBuffer -// parameter specifies the size of the interal buffer used to read records -// from the journal. This should be large enough to hold several records -// (for example, 10 kilobytes will allow this class to buffer several -// dozen journal records at a time) -BOOL CDriveIndex::Init(WCHAR cDrive) -{ - // You should not call this function twice for one instance. - if (m_hVol != INVALID_HANDLE_VALUE) - DebugBreak(); - m_cDrive = cDrive; - ClearLastResult(); - BOOL fOk = FALSE; - __try { - // Open a handle to the volume - m_hVol = Open(m_cDrive, GENERIC_WRITE | GENERIC_READ); - if (INVALID_HANDLE_VALUE == m_hVol) - __leave; - fOk = TRUE; - } - __finally { - if (!fOk) - CleanUp(); - } - return(fOk); -} - -void CDriveIndex::ClearLastResult() -{ - LastResult = SearchResult(); -} - -// Adds a file to the database -BOOL CDriveIndex::Add(DWORDLONG Index, wstring *szName, DWORDLONG ParentIndex, DWORDLONG Filter) -{ - IndexedFile i; - i.Index = Index; - if(!Filter) - Filter = MakeFilter(szName); - i.Filter = Filter; - rgFiles.insert(rgFiles.end(), i); - return(TRUE); -} - - - -// Adds a directory to the database -BOOL CDriveIndex::AddDir(DWORDLONG Index, wstring *szName, DWORDLONG ParentIndex, DWORDLONG Filter) -{ - IndexedDirectory i; - i.Index = Index; - if(!Filter) - Filter = MakeFilter(szName); - i.Filter = Filter; - i.nFiles = 0; - rgDirectories.insert(rgDirectories.end(), i); - return(TRUE); -} - - - -// Calculates a 64bit value that is used to filter out many files before comparing their filenames -// This method gives a huge speed boost. -DWORDLONG CDriveIndex::MakeFilter(wstring *szName) -{ - /* - Creates an address that is used to filter out strings that don't contain the queried characters - Explanation of the meaning of the single bits: - 0-25 a-z - 26-35 0-9 - 36 . - 37 space - 38 !#$&'()+,-~_ - 39 2 same characters - 40 3 same characters - The fields below indicate the presence of 2-character sequences. Based off http://en.wikipedia.org/wiki/Letter_frequency - 41 TH - 42 HE - 43 AN - 44 RE - 45 ER - 46 IN - 47 ON - 48 AT - 49 ND - 50 ST - 51 ES - 52 EN - 53 OF - 54 TE - 55 ED - 56 OR - 57 TI - 58 HI - 59 AS - 60 TO - 61-63 length (max. 8 characters. Queries are usually shorter than this) - */ - if(!(szName->length() > 0)) - return 0; - DWORDLONG Address = 0; - WCHAR c; - wstring szlower(*szName); - transform(szlower.begin(), szlower.end(), szlower.begin(), tolower); - int counts[26] = {0}; //This array is used to check if characters occur two or three times in the string - wstring::size_type l = szlower.length(); - for(unsigned int i = 0; i != l; i++) - { - c = szlower[i]; - if(c > 96 && c < 123) //a-z - { - Address |= 1ui64 << (DWORDLONG)((DWORDLONG)c - 97ui64); - counts[c-97]++; - if(i < l - 1) - { - if(c == L't' && szlower[i+1] == L'h') //th - Address |= 1ui64 << 41; - else if(c == L'h' && szlower[i+1] == L'e') //he - Address |= 1ui64 << 41; - else if(c == L'a' && szlower[i+1] == L'n') //an - Address |= 1ui64 << 41; - else if(c == L'r' && szlower[i+1] == L'e') //re - Address |= 1ui64 << 41; - else if(c == L'e' && szlower[i+1] == L'r') //er - Address |= 1ui64 << 41; - else if(c == L'i' && szlower[i+1] == L'n') //in - Address |= 1ui64 << 41; - else if(c == L'o' && szlower[i+1] == L'n') //on - Address |= 1ui64 << 41; - else if(c == L'a' && szlower[i+1] == L't') //at - Address |= 1ui64 << 41; - else if(c == L'n' && szlower[i+1] == L'd') //nd - Address |= 1ui64 << 41; - else if(c == L's' && szlower[i+1] == L't') //st - Address |= 1ui64 << 41; - else if(c == L'e' && szlower[i+1] == L's') //es - Address |= 1ui64 << 41; - else if(c == L'e' && szlower[i+1] == L'n') //en - Address |= 1ui64 << 41; - else if(c == L'o' && szlower[i+1] == L'f') //of - Address |= 1ui64 << 41; - else if(c == L't' && szlower[i+1] == L'e') //te - Address |= 1ui64 << 41; - else if(c == L'e' && szlower[i+1] == L'd') //ed - Address |= 1ui64 << 41; - else if(c == L'o' && szlower[i+1] == L'r') //or - Address |= 1ui64 << 41; - else if(c == L't' && szlower[i+1] == L'i') //ti - Address |= 1ui64 << 41; - else if(c == L'h' && szlower[i+1] == L'i') //hi - Address |= 1ui64 << 41; - else if(c == L'a' && szlower[i+1] == L's') //as - Address |= 1ui64 << 41; - else if(c == L't' && szlower[i+1] == L'o') //to - Address |= 1ui64 << 41; - } - } - else if(c >= L'0' && c <= '9') //0-9 - Address |= 1ui64 << (c - L'0' + 26ui64); - else if(c == L'.') //. - Address |= 1ui64 << 36; - else if(c == L' ') // space - Address |= 1ui64 << 37; - else if(c == L'!' || c == L'#' || c == L'$' || c == L'&' || c == L'\'' || c == L'(' || c == L')' || c == L'+' || c == L',' || c == L'-' || c == L'~' || c == L'_') - Address |= 1ui64 << 38; // !#$&'()+,-~_ - } - for(unsigned int i = 0; i != 26; i++) - { - if(counts[i] == 2) - Address |= 1ui64 << 39; - else if(counts[i] > 2) - Address |= 1ui64 << 40; - } - DWORDLONG length = (szlower.length() > 7 ? 7ui64 : (DWORDLONG)szlower.length()) & 0x00000007ui64; //3 bits for length -> 8 max - Address |= length << 61ui64; - return Address; -} - - - -// Internal function for searching in the database. -// For projects in C++ which use this project it might be preferable to use this function -// to skip the wrapper. -// Returns: number of results, -1 if maxResults != -1 and not all results were found -int CDriveIndex::Find(wstring *strQuery, wstring *strQueryPath, vector *rgsrfResults, BOOL bSort, BOOL bEnhancedSearch, int maxResults) -{ - //These variables are used to control the flow of execution in this function. - - //Indicates where results should be searched - unsigned int SearchWhere = IN_FILES; - //Offset for vector marked by SearchWhere - unsigned int iOffset = 0; - //Used to skip the search when the previous two properties should be carried over to the next search without actually using them now. - BOOL bSkipSearch = false; - - //Number of results in this search. -1 if more than maximum number of results. - int nResults = 0; - - //No query, just ignore this call - if(strQuery->length() == 0) - { - // Store this query - LastResult.Query = wstring(TEXT("")); - LastResult.Results = vector(); - return nResults; - } - - if(strQueryPath != NULL) - { - //Check if the path actually matches the drive of this index - WCHAR szDrive[_MAX_DRIVE]; - _wsplitpath(strQueryPath->c_str(), szDrive, NULL, NULL, NULL); - for(unsigned int j = 0; j != _MAX_DRIVE; j++) - szDrive[j] = toupper(szDrive[j]); - if(wstring(szDrive).compare(wstring(1,toupper(m_cDrive))) == 0) - return 0; - } - - //Create lower query string for case-insensitive search - wstring strQueryLower(*strQuery); - for(unsigned int j = 0; j != strQueryLower.length(); j++) - strQueryLower[j] = tolower(strQueryLower[j]); - const WCHAR *szQueryLower = strQueryLower.c_str(); - - //Create lower query path string for case-insensitive search - wstring strQueryPathLower(strQueryPath != NULL ? *strQueryPath : TEXT("")); - for(unsigned int j = 0; j != strQueryPathLower.length(); j++) - strQueryPathLower[j] = tolower((*strQueryPath)[j]); - wstring* pstrQueryPathLower = strQueryPath != NULL && strQueryPathLower.length() > 0 ? &strQueryPathLower : NULL; - - //If the query path is different from the last query so that the results are not valid anymore, the last query needs to be dropped - if(!(strQueryPath != NULL && (LastResult.maxResults == -1 || LastResult.iOffset == 0) && (LastResult.SearchPath.length() == 0 || strQueryPathLower.find(LastResult.SearchPath) == 0))) - LastResult = SearchResult(); - - //Calculate Filter value and length of the current query which are compared with the cached ones to skip many of them - DWORDLONG QueryFilter = MakeFilter(&strQueryLower); - DWORDLONG QueryLength = (QueryFilter & 0xE000000000000000ui64) >> 61ui64; //Bits 61-63 for storing lengths up to 8 - QueryFilter = QueryFilter & 0x1FFFFFFFFFFFFFFFui64; //All but the last 3 bits - - //If the same query string as in the last query was used - if(strQueryLower.compare(LastResult.Query) == 0 && LastResult.Results.size() > 0 && (LastResult.SearchEndedWhere == NO_WHERE && iOffset != 1)) // need proper condition here to skip - { - //Keep the position of the last result - SearchWhere = LastResult.SearchEndedWhere; - iOffset = LastResult.iOffset; - bSkipSearch = true; - for(int i = 0; i != LastResult.Results.size(); i++) - { - BOOL bFound = true; - if(pstrQueryPathLower != NULL) - { - wstring strPathLower(LastResult.Results[i].Path); - for(unsigned int j = 0; j != strPathLower.length(); j++) - strPathLower[j] = tolower(LastResult.Results[i].Path[j]); - bFound = strPathLower.find(strQueryPathLower) != -1; - } - if(bFound) - { - nResults++; - //If the result limit has decreased and we have found all (shouldn't happen in common scenarios) - if(maxResults != -1 && nResults > maxResults) - { - nResults = -1; - - //If we get here, the next incremental should start fresh, but only if it requires more results than this one. - //To accomplish this we make this result contain no information about the origin of these results. - SearchWhere = NO_WHERE; - iOffset = 1; - break; - } - rgsrfResults->insert(rgsrfResults->end(), LastResult.Results[i]); - } - } - //if the last search was limited and didn't finish because it found enough files and we don't have the maximum number of results yet - //we need to continue the search where the last one stopped. - if(LastResult.maxResults != -1 && LastResult.SearchEndedWhere != NO_WHERE && (maxResults == -1 || nResults < maxResults)) - bSkipSearch = false; - } - //If this query is more specific than the previous one, it can use the results from the previous query - else if(strQueryLower.find(LastResult.Query) != -1 && LastResult.Results.size() > 0) - { - bSkipSearch = true; - //Keep the position of the last result - SearchWhere = LastResult.SearchEndedWhere; - iOffset = LastResult.iOffset; - FindInPreviousResults(*strQuery, szQueryLower, QueryFilter, QueryLength, pstrQueryPathLower, *rgsrfResults, 0, bEnhancedSearch, maxResults, nResults); - - //if the last search was limited and didn't finish because it found enough files and we don't have the maximum number of results yet - //we need to continue the search where the last one stopped. - if(LastResult.maxResults != -1 && LastResult.SearchEndedWhere != NO_WHERE && (maxResults == -1 || nResults < maxResults)) - bSkipSearch = false; - } - DWORDLONG FRNPath; - long long nFilesInDir = -1; - if(strQueryPath != NULL && strQueryPath->length()) - { - FRNPath = PathToFRN(strQueryPath); - wstring strPath2; - GetDir(FRNPath, &strPath2); - int iOffset = (int) FindDirOffsetByIndex(FRNPath); - if(iOffset != -1) - nFilesInDir = rgDirectories[iOffset].nFiles; - } - if(SearchWhere == IN_FILES && iOffset == 0 && nFilesInDir != -1 && nFilesInDir < 10000 && !bSkipSearch) - { - FindRecursively(*strQuery, szQueryLower, QueryFilter, QueryLength, strQueryPath, *rgsrfResults, bEnhancedSearch, maxResults, nResults); - SearchWhere = NO_WHERE; - } - else if(SearchWhere == IN_FILES && !bSkipSearch) - { - //Find in file index - FindInJournal(*strQuery, szQueryLower, QueryFilter, QueryLength, (strQueryPath != NULL ? &strQueryPathLower : NULL), rgFiles, *rgsrfResults, iOffset, bEnhancedSearch, maxResults, nResults); - //If we found the maximum number of results in the file index we stop here - if(maxResults != -1 && nResults == -1) - iOffset++; //Start with next entry on the next incremental search - else //Search isn't limited or not all results found yet, continue in directory index - { - SearchWhere = IN_DIRECTORIES; - iOffset = 0; - } - } - - if(SearchWhere == IN_DIRECTORIES && !bSkipSearch) - { - //Find in directory index - FindInJournal(*strQuery, szQueryLower, QueryFilter, QueryLength, pstrQueryPathLower, rgDirectories, *rgsrfResults, iOffset, bEnhancedSearch, maxResults, nResults); - //If we found the maximum number of results in the directory index we stop here - if(maxResults != -1 && nResults == -1) - iOffset++; //Start with next entry on the next incremental search - else //Search isn't limited or less than the maximum number of results found - { - SearchWhere = NO_WHERE; - iOffset = 0; - } - } - - //Sort by match quality and name - if(bSort) - sort(rgsrfResults->begin(), rgsrfResults->end()); - - // Store this query - LastResult.Query = wstring(strQueryLower); - - // Store search path - LastResult.SearchPath = strQueryPathLower; - - //Clear old results, they will be replaced with the current ones - LastResult.Results = vector(); - - //Store number of results (Needed for incremental search) - LastResult.iOffset = iOffset; - - //Store if this search was limited - LastResult.maxResults = maxResults; - - //Store where the current search ended due to file limit (or if it didn't); - LastResult.SearchEndedWhere = SearchWhere; - - //Update last results - for(unsigned int i = 0; i != rgsrfResults->size(); i++) - LastResult.Results.insert(LastResult.Results.end(), (*rgsrfResults)[i]); - - return nResults; -} - -void CDriveIndex::FindRecursively(wstring &strQuery, const WCHAR* &szQueryLower, DWORDLONG QueryFilter, DWORDLONG QueryLength, wstring* strQueryPath, vector &rgsrfResults, BOOL bEnhancedSearch, int maxResults, int &nResults) -{ - WIN32_FIND_DATA ffd; - size_t length_of_arg; - HANDLE hFind = INVALID_HANDLE_VALUE; - - // Check that the input path plus 3 is not longer than MAX_PATH. - // Three characters are for the "\*" plus NULL appended below. - length_of_arg = strQueryPath->length(); - if (length_of_arg > (MAX_PATH - 3)) - return; - - // Prepare string for use with FindFile functions. First, copy the - // string to a buffer, then append '\*' to the directory name. - wstring strPath = wstring(*strQueryPath); - if((*strQueryPath)[strQueryPath->length() - 1] != L'\\') - strPath += wstring(TEXT("\\*")); - else - strPath += wstring(TEXT("*")); - - const WCHAR* szDir = strPath.c_str(); - - // Find the first file in the directory. - hFind = FindFirstFile(szDir, &ffd); - - if (hFind == INVALID_HANDLE_VALUE) - return; - unsigned int nFiles = 0; - // List all the files in the directory with some info about them. - do - { - if(ffd.dwFileAttributes & FILE_ATTRIBUTE_VIRTUAL || ffd.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) - continue; - float MatchQuality; - wstring strFilename(ffd.cFileName); - if(strFilename.compare(TEXT(".")) == 0 || strFilename.compare(TEXT("..")) == 0) - continue; - nFiles++; - if(bEnhancedSearch) - MatchQuality = FuzzySearch(strFilename, strQuery); - else - { - wstring szLower(strFilename); - for(unsigned int j = 0; j != szLower.length(); j++) - szLower[j] = tolower(szLower[j]); - MatchQuality = szLower.find(strQuery) != -1; - } - - if(MatchQuality > 0.6f) - { - nResults++; - if(maxResults != -1 && nResults > maxResults) - { - nResults = -1; - break; - } - SearchResultFile srf; - srf.Filename = strFilename; - srf.Path = *strQueryPath + TEXT("\\"); - srf.Filter = MAXULONG64; - srf.MatchQuality = MatchQuality; - rgsrfResults.insert(rgsrfResults.end(), srf); - } - - if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - { - wstring strSubPath = wstring(*strQueryPath); - if((*strQueryPath)[strQueryPath->length() - 1] != L'\\') - strSubPath += L'\\'; - strSubPath += ffd.cFileName; - FindRecursively(strQuery, szQueryLower, QueryFilter, QueryLength, &strSubPath, rgsrfResults, bEnhancedSearch, maxResults, nResults); - if(nResults == -1) - break; - } - } - while (FindNextFile(hFind, &ffd) != 0); - FindClose(hFind); -} - -//T needs to be IndexedFile or IndexedDirectory -template -void CDriveIndex::FindInJournal(wstring &strQuery, const WCHAR* &szQueryLower, DWORDLONG QueryFilter, DWORDLONG QueryLength, wstring * strQueryPath, vector &rgJournalIndex, vector &rgsrfResults, unsigned int iOffset, BOOL bEnhancedSearch, int maxResults, int &nResults) -{ - for(unsigned int j = 0; j != rgJournalIndex.size(); j++) - { - IndexedFile* i = (IndexedFile*)&rgJournalIndex[j]; - DWORDLONG Length = (i->Filter & 0xE000000000000000ui64) >> 61ui64; //Bits 61-63 for storing lengths up to 8 - DWORDLONG Filter = i->Filter & 0x1FFFFFFFFFFFFFFFui64; //All but the last 3 bits - if((Filter & QueryFilter) == QueryFilter && QueryLength <= Length) - { - USNEntry file = FRNToName(i->Index); - float MatchQuality; - if(bEnhancedSearch) - MatchQuality = FuzzySearch(file.Name, strQuery); - else - { - wstring szLower(file.Name); - for(unsigned int j = 0; j != szLower.length(); j++) - szLower[j] = tolower(szLower[j]); - MatchQuality = szLower.find(strQuery) != -1; - } - - if(MatchQuality > 0.6f) - { - nResults++; - if(maxResults != -1 && nResults > maxResults) - { - nResults = -1; - break; - } - SearchResultFile srf; - srf.Filename = file.Name; - srf.Path.reserve(MAX_PATH); - Get(i->Index, &srf.Path); - BOOL bFound = true; - if(strQueryPath != NULL) - { - wstring strPathLower(srf.Path); - for(unsigned int j = 0; j != strPathLower.length(); j++) - strPathLower[j] = tolower(strPathLower[j]); - bFound = strPathLower.find(*strQueryPath) != -1; - } - if(bFound) - { - //split path - WCHAR szDrive[_MAX_DRIVE]; - WCHAR szPath[_MAX_PATH]; - WCHAR szName[_MAX_FNAME]; - WCHAR szExt[_MAX_EXT]; - _wsplitpath(srf.Path.c_str(), szDrive, szPath, szName, szExt); - srf.Path = wstring(szDrive) + wstring(szPath); - srf.Filter = i->Filter; - srf.MatchQuality = MatchQuality; - rgsrfResults.insert(rgsrfResults.end(), srf); - } - } - } - } -} -void CDriveIndex::FindInPreviousResults(wstring &strQuery, const WCHAR* &szQueryLower, DWORDLONG QueryFilter, DWORDLONG QueryLength, wstring * strQueryPath, vector &rgsrfResults, unsigned int iOffset, BOOL bEnhancedSearch, int maxResults, int &nResults) -{ - for(int i = 0; i != LastResult.Results.size() && (maxResults == -1 || i < maxResults); i++) - { - SearchResultFile *srf = & LastResult.Results[i]; - DWORDLONG Length = (srf->Filter & 0xE000000000000000ui64) >> 61ui64; //Bits 61-63 for storing lengths up to 8 - DWORDLONG Filter = srf->Filter & 0x1FFFFFFFFFFFFFFFui64; //All but the last 3 bits - if((Filter & QueryFilter) == QueryFilter && QueryLength <= Length) - { - if(bEnhancedSearch) - srf->MatchQuality = FuzzySearch(srf->Filename, strQuery); - else - { - wstring szLower(srf->Filename); - for(unsigned int j = 0; j != szLower.length(); j++) - szLower[j] = tolower(szLower[j]); - srf->MatchQuality = szLower.find(szQueryLower) != -1; - } - if(srf->MatchQuality > 0.6f) - { - BOOL bFound = true; - if(strQueryPath != NULL) - { - wstring strPathLower(srf->Path); - for(unsigned int j = 0; j != srf->Path.length(); j++) - strPathLower[j] = tolower(srf->Path[j]); - bFound = strPathLower.find(*strQueryPath) != -1; - } - if(bFound) - { - nResults++; - if(maxResults != -1 && nResults > maxResults) - { - nResults = -1; - break; - } - rgsrfResults.insert(rgsrfResults.end(), *srf); - } - } - } - } -} - - -// Clears the database -BOOL CDriveIndex::Empty() -{ - rgFiles.clear(); - rgDirectories.clear(); - return(TRUE); -} - - - -// Constructs a path for a file -BOOL CDriveIndex::Get(DWORDLONG Index, wstring *sz) const -{ - *sz = TEXT(""); - int n = 0; - do { - USNEntry file = FRNToName(Index); - *sz = file.Name + ((n != 0) ? TEXT("\\") : TEXT("")) + *sz; - Index = file.ParentIndex; - n++; - } while (Index != 0); - return(TRUE); -} - - - -// Constructs a path for a directory -BOOL CDriveIndex::GetDir(DWORDLONG Index, wstring *sz) const -{ - *sz = TEXT(""); - do { - USNEntry file = FRNToName(Index); - *sz = file.Name + ((sz->length() != 0) ? TEXT("\\") : TEXT("")) + *sz; - Index = file.ParentIndex; - } while (Index != 0); - return(TRUE); -} - - - -//Finds the position of a file in the database by the FileReferenceNumber -INT64 CDriveIndex::FindOffsetByIndex(DWORDLONG Index) { - - vector::difference_type pos; - IndexedFile i; - i.Index = Index; - pos = distance(rgFiles.begin(), lower_bound(rgFiles.begin(), rgFiles.end(), i)); - return (INT64) (pos == rgFiles.size() ? -1 : pos); // this is valid because the number of files doesn't exceed the range of INT64 -} - - - -//Finds the position of a directory in the database by the FileReferenceNumber -INT64 CDriveIndex::FindDirOffsetByIndex(DWORDLONG Index) -{ - vector::difference_type pos; - IndexedDirectory i; - i.Index = Index; - pos = distance(rgDirectories.begin(), lower_bound(rgDirectories.begin(), rgDirectories.end(), i)); - return (INT64) (pos == rgDirectories.size() ? -1 : pos); // this is valid because the number of files doesn't exceed the range of INT64 -} - -DWORDLONG PathToFRN(wstring* strPath) -{ - HANDLE hDir = CreateFile(strPath->c_str(), 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); - if(hDir == INVALID_HANDLE_VALUE) - return 0; - BY_HANDLE_FILE_INFORMATION fi; - GetFileInformationByHandle(hDir, &fi); - CloseHandle(hDir); - return (((DWORDLONG) fi.nFileIndexHigh) << 32) | fi.nFileIndexLow; -} - -// Enumerate the MFT for all entries. Store the file reference numbers of -// any directories in the database. -void CDriveIndex::PopulateIndex() -{ - Empty(); - - vector FileParents; - vector DirectoryParents; - - USN_JOURNAL_DATA ujd; - Query(&ujd); - - // Get the FRN of the root directory - // This had BETTER work, or we can't do anything - - WCHAR szRoot[_MAX_PATH]; - wsprintf(szRoot, TEXT("%c:\\"), m_cDrive); - HANDLE hDir = CreateFile(szRoot, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, - NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); - - BY_HANDLE_FILE_INFORMATION fi; - GetFileInformationByHandle(hDir, &fi); - CloseHandle(hDir); - DWORDLONG IndexRoot = (((DWORDLONG) fi.nFileIndexHigh) << 32) | fi.nFileIndexLow; - wsprintf(szRoot, TEXT("%c:"), m_cDrive); - AddDir(IndexRoot, &wstring(szRoot), 0); - DirectoryParents.insert(DirectoryParents.end(), 0); - m_dwDriveFRN = IndexRoot; - - MFT_ENUM_DATA med; - med.StartFileReferenceNumber = 0; - med.LowUsn = 0; - med.HighUsn = ujd.NextUsn; - - // Process MFT in 64k chunks - BYTE pData[sizeof(DWORDLONG) + 0x10000]; - DWORDLONG fnLast = 0; - DWORD cb; - unsigned int num = 0; - unsigned int numDirs = 1; - while (DeviceIoControl(m_hVol, FSCTL_ENUM_USN_DATA, &med, sizeof(med), pData, sizeof(pData), &cb, NULL) != FALSE) { - - PUSN_RECORD pRecord = (PUSN_RECORD) &pData[sizeof(USN)]; - while ((PBYTE) pRecord < (pData + cb)) { - if ((pRecord->FileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0) - numDirs++; - else - num++; - pRecord = (PUSN_RECORD) ((PBYTE) pRecord + pRecord->RecordLength); - } - med.StartFileReferenceNumber = * (DWORDLONG *) pData; - } - - FileParents.reserve(num); - DirectoryParents.reserve(numDirs); - rgFiles.reserve(num); - rgDirectories.reserve(numDirs); - hash_map hmFiles; - hash_map hmDirectories; - hash_map::iterator it; - med.StartFileReferenceNumber = 0; - while (DeviceIoControl(m_hVol, FSCTL_ENUM_USN_DATA, &med, sizeof(med), pData, sizeof(pData), &cb, NULL) != FALSE) - { - PUSN_RECORD pRecord = (PUSN_RECORD) &pData[sizeof(USN)]; - while ((PBYTE) pRecord < (pData + cb)) - { - wstring sz((LPCWSTR) ((PBYTE) pRecord + pRecord->FileNameOffset), pRecord->FileNameLength / sizeof(WCHAR)); - if ((pRecord->FileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0) - { - AddDir(pRecord->FileReferenceNumber, &sz, pRecord->ParentFileReferenceNumber); - //DirectoryParents.insert(DirectoryParents.end(), pRecord->ParentFileReferenceNumber); - HashMapEntry hme; - hme.iOffset = rgDirectories.size() - 1; - hme.ParentFRN = pRecord->ParentFileReferenceNumber; - hmDirectories[pRecord->FileReferenceNumber] = hme; - } - else - { - Add(pRecord->FileReferenceNumber, &sz, pRecord->ParentFileReferenceNumber); - HashMapEntry hme; - hme.iOffset = rgFiles.size() - 1; - hme.ParentFRN = pRecord->ParentFileReferenceNumber; - //FileParents.insert(FileParents.end(), pRecord->ParentFileReferenceNumber); - hmFiles[pRecord->FileReferenceNumber] = hme; - } - pRecord = (PUSN_RECORD) ((PBYTE) pRecord + pRecord->RecordLength); - } - med.StartFileReferenceNumber = * (DWORDLONG *) pData; - } - - //Calculate files per directory. This takes most of the indexing time, but this information can be useful to reduce the time needed - //for searching in directories with few files (less than 10k). - for ( it=hmFiles.begin() ; it != hmFiles.end(); it++ ) - { - HashMapEntry* hme = &hmDirectories[it->second.ParentFRN]; - do - { - rgDirectories[hme->iOffset].nFiles++; - HashMapEntry* hme2 = &hmDirectories[it->second.ParentFRN]; - - if(hme != hme2) - hme = hme2; - else // This must not happen, otherwise a directory is its own parent! - break; - } while(hme->ParentFRN != 0); - } - //for(unsigned int i = 0; i != FileParents.size(); i++) - //{ - // DWORDLONG dwIndex = FileParents[i]; - // while(dwIndex != 0) - // { - // int iOffset = -1; - // for(unsigned int j = 0; j != rgDirectories.size(); j++) - // if(rgDirectories[j].Index == dwIndex) - // { - // iOffset = j; - // break; - // } - // if(iOffset == -1) - // break; - // rgDirectories[iOffset].nFiles++; - // DWORDLONG dwIndex2 = DirectoryParents[iOffset]; - - // if(dwIndex != dwIndex2) - // dwIndex = dwIndex2; - // else // This must not happen, otherwise a directory is its own parent! - // break; - // } - // //wstring strPath; - // //GetDir(dwIndex, &strPath); - - // //do { - // // //USNEntry file = FRNToName(dwIndex); - // // int iOffset = -1; - // // for(int j = 0; j != rgDirectories.size(); j++) - // // if(rgDirectories[j].Index == dwIndex) - // // { - // // iOffset = j; - // // break; - // // } - // // if(iOffset == -1) - // // break; - // // //USNEntry parent = FRNToName(file.ParentIndex); - // // //USNEntry parent2 = FRNToName(rgDirectories[iOffset].Index); - // // rgDirectories[iOffset].nFiles++; - // // dwIndex = file.ParentIndex; - // //} while (dwIndex != 0); - //} - rgFiles.shrink_to_fit(); - rgDirectories.shrink_to_fit(); - sort(rgFiles.begin(), rgFiles.end()); - sort(rgDirectories.begin(), rgDirectories.end()); -} - -// Resolve FRN to filename by enumerating USN journal with StartFileReferenceNumber=FRN -USNEntry CDriveIndex::FRNToName(DWORDLONG FRN) const -{ - if(FRN == m_dwDriveFRN) - return USNEntry(wstring(1, m_cDrive) + wstring(TEXT(":")), 0); - USN_JOURNAL_DATA ujd; - Query(&ujd); - - MFT_ENUM_DATA med; - med.StartFileReferenceNumber = FRN; - med.LowUsn = 0; - med.HighUsn = ujd.NextUsn; - - // The structure only needs a single entry so it can be pretty small - BYTE pData[sizeof(DWORDLONG) + 0x300]; - DWORD cb; - while (DeviceIoControl(m_hVol, FSCTL_ENUM_USN_DATA, &med, sizeof(med), pData, sizeof(pData), &cb, NULL) != FALSE) { - - PUSN_RECORD pRecord = (PUSN_RECORD) &pData[sizeof(USN)]; - while ((PBYTE) pRecord < (pData + cb)) { - if(pRecord->FileReferenceNumber == FRN) - return USNEntry(wstring((LPCWSTR) ((PBYTE) pRecord + pRecord->FileNameOffset), pRecord->FileNameLength / sizeof(WCHAR)), pRecord->ParentFileReferenceNumber); - pRecord = (PUSN_RECORD) ((PBYTE) pRecord + pRecord->RecordLength); - } - med.StartFileReferenceNumber = * (DWORDLONG *) pData; - } - return USNEntry(wstring(TEXT("")), 0); -} - - - -// Saves the database to disk. The file can be used to create an instance of CDriveIndex. -BOOL CDriveIndex::SaveToDisk(wstring &strPath) const -{ - ofstream::pos_type size; - ofstream file (strPath.c_str(), ios::out|ios::binary|ios::trunc); - if (file.is_open()) - { - //Drive character - file.write((char*) &m_cDrive, sizeof(m_cDrive)); - - //Drive FileReferenceNumber - file.write((char*) &m_dwDriveFRN, sizeof(m_dwDriveFRN)); - - unsigned int size = rgFiles.size(); - //Number of files - file.write((char*) &size, sizeof(rgFiles.size())); - //indexed files - file.write((char*) &(rgFiles[0]), sizeof(IndexedFile) * rgFiles.size()); - - size = rgDirectories.size(); - //Number of directories - file.write((char*) &size, sizeof(rgDirectories.size())); - //indexed directories - file.write((char*) &(rgDirectories[0]), sizeof(IndexedDirectory) * rgDirectories.size()); - file.close(); - return true; - } - return false; -} - - - -// Constructor for loading the index from a previously saved file -CDriveIndex::CDriveIndex(wstring &strPath) -{ - m_hVol = INVALID_HANDLE_VALUE; - Empty(); - - ifstream::pos_type size; - - ifstream file (strPath.c_str(), ios::in | ios::binary); - if (file.is_open()) - { - //Drive - WCHAR cDrive; - file.read((char*) &cDrive, sizeof(WCHAR)); - - if(Init(cDrive)) - { - // Drive FileReferenceNumber - file.read((char*) &m_dwDriveFRN, sizeof(m_dwDriveFRN)); - - //Number of files - unsigned int numFiles = 0; - file.read((char*) &numFiles, sizeof(numFiles)); - rgFiles.reserve(numFiles); - - //indexed files - for(unsigned int j = 0; j != numFiles; j++) - { - IndexedFile i; - file.read((char*) &i, sizeof(IndexedFile)); - rgFiles.insert(rgFiles.end(), i); - } - - //Number of directories - unsigned int numDirs = 0; - file.read((char*) &numDirs, sizeof(numDirs)); - rgDirectories.reserve(numDirs); - - //indexed directories - for(unsigned int j = 0; j != numDirs; j++) - { - IndexedDirectory i; - file.read((char*) &i, sizeof(IndexedDirectory)); - rgDirectories.insert(rgDirectories.end(), i); - } - } - file.close(); - } - return; -} - - - -// Returns the number of files and folders on this drive -DriveInfo CDriveIndex::GetInfo() const -{ - DriveInfo di; - di.NumFiles = (DWORDLONG) rgFiles.size(); - di.NumDirectories = (DWORDLONG) rgDirectories.size(); - return di; -} - - - - -//Performs a fuzzy search for shorter in longer. -//return values range from 0.0 = identical to 1.0 = completely different. 0.4 seems appropriate -float FuzzySearch(wstring &longer, wstring &shorter) -{ - //Note: All string lengths are shorter than MAX_PATH, so an uint is perfectly fitted. - unsigned int lenl = (unsigned int) longer.length(); - unsigned int lens = (unsigned int) shorter.length(); - - if(lens > lenl) - return 0.0f; - - //Check if the shorter string is a substring of the longer string - unsigned int Contained = (unsigned int) longer.find(shorter); - if(Contained != wstring::npos) - return Contained == 0 ? 1.0f : 0.8f; - - wstring longerlower(longer); - wstring shorterlower(shorter); - for(unsigned int i = 0; i != lenl; i++) - longerlower[i] = tolower(longer[i]); - for(unsigned int i = 0; i != lens; i++) - shorterlower[i] = tolower(shorter[i]); - - //Check if the shorter string is a substring of the longer string - Contained = (unsigned int) longerlower.find(shorterlower); - if(Contained != wstring::npos) - return Contained == 0 ? 0.9f : 0.7f; - - //Check if string can be matched by omitting characters - if(lens < 5) - { - unsigned int pos = 0; - unsigned int matched = 0; - for(unsigned int i = 0; i != lens; i++) - { - WCHAR c = toupper(shorter[i]); //only look for capital letters in longer string, (e.g. match tc in TrueCrypt) - for(unsigned int j = 0; j != lenl - pos; j++) - { - if(longer[pos + j] == c) - { - pos = j; - matched++; - break; - } - else - continue; - } - } - if(matched == lens) - return 0.9f; //Slightly worse than direct matches - } - return 0; +/********************************************************************************** +Module name: CDriveIndex.cpp +Written by: Christian Sander +Credits for original code this is based on: Jeffrey Cooperstein & Jeffrey Richter +**********************************************************************************/ + +#include "stdafx.h" +#include "CDriveIndex.h" +#include +#include +#include +#include +#include +#include + +#include "lz4.h" + +#include "stxutif.h" +using namespace gel; + +using namespace tinyxml2; + +#if (NTDDI_VERSION >= NTDDI_WIN8) +typedef MFT_ENUM_DATA_V0 LEGACY_MFT_ENUM_DATA; +#else +typedef MFT_ENUM_DATA LEGACY_MFT_ENUM_DATA; +#endif + + +namespace { +template +T swap_endian(T u) +{ + union + { + T u; + unsigned char u8[sizeof(T)]; + } source, dest; + + source.u = u; + + for (size_t k = 0; k < sizeof(T); k++) + dest.u8[k] = source.u8[sizeof(T) - k - 1]; + + return dest.u; +} +}; + + +// Exported function to create the index of a drive +CDriveIndex* _stdcall CreateIndex(WCHAR cDrive) +{ + CDriveIndex *di = new CDriveIndex(); + di->Init(cDrive); + di->PopulateIndex(); + DriveInfo info(di->GetInfo()); + if (info.NumFiles <= 2) + { + delete di; + di = 0; + } + return di; +} + + + +// Exported function to delete the index of a drive +void _stdcall DeleteIndex(CDriveIndex *di) +{ + if(dynamic_cast(di)) + delete di; +} + +void CDriveIndex::attach(vector &dirHandles, unordered_map::size_type> &umDirFrnToHandle, int NodeType, DWORDLONG Index) const +{ + if (umDirFrnToHandle.find(Index) != umDirFrnToHandle.end()) { // already processed? + return; + } + + USNEntry file = FRNToName(Index); + if (file.ParentIndex == 0) { // No upper directory + return; + } + if(!(file.ParentIndex == 0 && file.Name.length() == 2 && file.Name[1] == wchar_t(L':'))) // to exclude drive itself + { + SearchResultFile srf; + srf.Filename = file.Name; + srf.Path.reserve(MAX_PATH); + // Obtain path into buffer, and split it + Get(Index, &srf.Path); + if(srf.Path.length() < 3) { + return; + } + + WCHAR szDrive[_MAX_DRIVE]; + WCHAR szPath[_MAX_PATH]; + WCHAR szName[_MAX_FNAME]; + WCHAR szExt[_MAX_EXT]; + _wsplitpath(srf.Path.c_str(), szDrive, szPath, szName, szExt); + + // Skip metadata files and other special directories + int compareCount = sizeof(L"$RECYCLE.BIN") / sizeof(WCHAR) - 1; + if (*szDrive == wchar_t(0) || srf.Path.compare(3, compareCount, L"$RECYCLE.BIN", compareCount) == 0) { + return; + } + + unordered_map::size_type>::const_iterator it(umDirFrnToHandle.find(file.ParentIndex)); + if (it == umDirFrnToHandle.end()) { + attach(dirHandles, umDirFrnToHandle, IN_DIRECTORIES, file.ParentIndex); + } + it = umDirFrnToHandle.find(file.ParentIndex); + if (it == umDirFrnToHandle.end()) { + return; // unexpected + } + XMLHandle parentHandle(dirHandles[it->second]); + + XMLNode * parent = parentHandle.ToNode(); + if (!parent) { + return; + } + + XMLElement * element = parent->GetDocument()->NewElement( (NodeType == IN_DIRECTORIES) ? "Directory" : "File" ); + element->SetAttribute("Name", stdx::wstring_to_utf8(file.Name).c_str()); + + if (NodeType == IN_DIRECTORIES) { + vector::iterator insertedIt(dirHandles.insert(dirHandles.end(), XMLHandle(element))); + umDirFrnToHandle[Index] = insertedIt - dirHandles.begin(); + } + else { + HANDLE hFile = CreateFile( srf.Path.c_str(), 0, + FILE_SHARE_READ, 0, OPEN_EXISTING, + FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, 0 ); + if (hFile != INVALID_HANDLE_VALUE) { + BY_HANDLE_FILE_INFORMATION FileInfo = {0}; + GetFileInformationByHandle(hFile, &FileInfo); + if (!(FileInfo.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) { + ULARGE_INTEGER filesize = {FileInfo.nFileSizeLow, FileInfo.nFileSizeHigh}; + element->SetAttribute("Size", std::to_string(DWORDLONG(filesize.QuadPart)).c_str());; + } + CloseHandle(hFile); + } + } + + parent->InsertEndChild(element); + } +} + + +// Exports database to an exchange format. +// format is ignored for now, pass 0 for the default format. +// returns number of processed entries and 0 if an error occured. +BOOL CDriveIndex::ExportToFileListing(wstring &strPath, int format) const +{ + if (format < ExportFormat::ExportFormatAdcXml || format > ExportFormat::ExportFormatAdcXml_LZ4) { + return FALSE; + } + vector results; + XMLDocument doc; + XMLPrinter printer; + __time64_t tm; + CHAR tmbuf[200]; + + _time64(&tm); + strftime(tmbuf, sizeof(tmbuf) / sizeof(tmbuf[0]), "%Y-%m-%dT%H:%M:%SZ", _gmtime64(&tm)); + + stringstream emptyxml; + emptyxml << + "\n" + ""; + + XMLError err = doc.Parse(emptyxml.str().c_str()); + if (err != XML_SUCCESS) { + return false; + } + XMLHandle docHandle( &doc ); + + vector dirHandles; + dirHandles.reserve(rgDirectories.size()); + unordered_map::size_type> umDirFrnToHandle; + + vector::iterator insertedIt(dirHandles.insert(dirHandles.end(), XMLHandle(docHandle.FirstChildElement()))); + umDirFrnToHandle[m_dwDriveFRN] = insertedIt - dirHandles.begin(); + + for(unsigned int j = 0; j != rgDirectories.size(); j++) { + const IndexedDirectory* i = &rgDirectories[j]; + attach(dirHandles, umDirFrnToHandle, IN_DIRECTORIES, i->Index); + } + for(unsigned int j = 0; j != rgFiles.size(); j++) { + const IndexedFile* i = &rgFiles[j]; + attach(dirHandles, umDirFrnToHandle, IN_FILES, i->Index); + } + doc.Print( &printer ); + + std::ofstream file; // closes at end of scope + file.open(strPath.c_str(), ios::out|ios::binary|ios::trunc); + if (file.is_open()) + { + if (format == ExportFormat::ExportFormatAdcXml) { + file.write(printer.CStr(), printer.CStrSize() - 1); + return file.good(); + } + else if (format == ExportFormat::ExportFormatAdcXml_LZ4) { + int const uncompressed_size = printer.CStrSize() - 1; + int max_compressed_size = LZ4_compressBound( uncompressed_size ); + std::unique_ptr compressed( new char[max_compressed_size] ); + int const compressed_size = LZ4_compress( printer.CStr(), compressed.get(), uncompressed_size ); + int const final_compressed_size = ( compressed_size >= uncompressed_size ) ? uncompressed_size : compressed_size; + +#if defined(BIG_ENDIAN) + int value; + value = swap_endian(uncompressed_size); file.write(reinterpret_cast(&value), sizeof(int)); + value = swap_endian(final_compressed_size); file.write(reinterpret_cast(&value), sizeof(int)); +#else + file.write(reinterpret_cast(&uncompressed_size), sizeof(int)); + file.write(reinterpret_cast(&final_compressed_size), sizeof(int)); +#endif + file.write(( compressed_size >= uncompressed_size ) ? printer.CStr() : compressed.get(), final_compressed_size); + + return true; + } + } + + + return false; +} + + +// Exported function to search in the index of a drive. +// Returns a string that contains the filepaths of the results, +// separated by newlines for easier processing in non-C++ languages. +// nResults is -1 if more results than the limit were found and 0 if an error occured. In this case the return value is NULL. +WCHAR* _stdcall Search(CDriveIndex *di, WCHAR *szQuery, WCHAR *szPath, BOOL bSort, BOOL bEnhancedSearch, int maxResults, int *nResults) +{ + if(dynamic_cast(di) && szQuery) + { + vector results; + wstring result; + int numResults = di->Find(&wstring(szQuery), szPath != NULL ? &wstring(szPath) : NULL, &results, bSort, bEnhancedSearch, maxResults); + if(nResults != NULL) + *nResults = numResults; + for(unsigned int i = 0; i != results.size(); i++) + result += (i == 0 ? TEXT("") : TEXT("\n")) + results[i].Path + results[i].Filename; + WCHAR * szOutput = new WCHAR[result.length() + 1]; + ZeroMemory(szOutput, (result.length() + 1) * sizeof(szOutput[0])); + _snwprintf(szOutput, result.length(), TEXT("%s"), result.c_str()); + return szOutput; + } + if(nResults != NULL) + *nResults = 0; + return NULL; +} + + + +// Exported function to clear the memory of the string returned by Search(). +// This needs to be called after every call to Search to avoid memory leaks. +void _stdcall FreeResultsBuffer(WCHAR *szResults) +{ + if(szResults) + delete[] szResults; +} + + + +// Exported function that loads the database from disk +CDriveIndex* _stdcall LoadIndexFromDisk(WCHAR *szPath) +{ + if(szPath) + return new CDriveIndex(wstring(szPath)); + return NULL; +} + + + +// Exported function that saves the database to disk +BOOL _stdcall SaveIndexToDisk(CDriveIndex *di, WCHAR *szPath) +{ + if(dynamic_cast(di) && szPath) + return di->SaveToDisk(wstring(szPath)); + return false; +} + + +// Exported function that returns the number of files and directories +void _stdcall GetDriveInfo(CDriveIndex *di, DriveInfo *driveInfo) +{ + if(dynamic_cast(di)) + *driveInfo = di->GetInfo(); +} + + + +BOOL _stdcall ExportIndex(CDriveIndex *di, WCHAR *szPath, int format) +{ + if(dynamic_cast(di) && szPath) + return di->ExportToFileListing(wstring(szPath), format); + return false; +} + +// Constructor +CDriveIndex::CDriveIndex() +{ + // Initialize member variables + m_hVol = INVALID_HANDLE_VALUE; +} + + + +// Destructor +CDriveIndex::~CDriveIndex() +{ + CleanUp(); +} + + + +// Cleanup function to free resources +void CDriveIndex::CleanUp() +{ + // Cleanup the memory and handles we were using + if (m_hVol != INVALID_HANDLE_VALUE) + CloseHandle(m_hVol); +} + + + +// This is a helper function that opens a handle to the volume specified +// by the cDriveLetter parameter. +HANDLE CDriveIndex::Open(TCHAR cDriveLetter, DWORD dwAccess) +{ + TCHAR szVolumePath[_MAX_PATH]; + wsprintf(szVolumePath, TEXT("\\\\.\\%c:"), cDriveLetter); + HANDLE hCJ = CreateFile(szVolumePath, dwAccess, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); + return(hCJ); +} + + +// This function creates a journal on the volume. If a journal already +// exists this function will adjust the MaximumSize and AllocationDelta +// parameters of the journal +BOOL CDriveIndex::Create(DWORDLONG MaximumSize, DWORDLONG AllocationDelta) +{ + DWORD cb; + CREATE_USN_JOURNAL_DATA cujd; + cujd.MaximumSize = MaximumSize; + cujd.AllocationDelta = AllocationDelta; + BOOL fOk = DeviceIoControl(m_hVol, FSCTL_CREATE_USN_JOURNAL, + &cujd, sizeof(cujd), NULL, 0, &cb, NULL); + return(fOk); +} + +// Return statistics about the journal on the current volume +BOOL CDriveIndex::Query(PUSN_JOURNAL_DATA pUsnJournalData) const +{ + DWORD cb; + BOOL fOk = DeviceIoControl(m_hVol, FSCTL_QUERY_USN_JOURNAL, NULL, 0, + pUsnJournalData, sizeof(*pUsnJournalData), &cb, NULL); + return(fOk); +} + +// Call this to initialize the structure. The cDrive parameter +// specifies the drive that this instance will access. The cbBuffer +// parameter specifies the size of the interal buffer used to read records +// from the journal. This should be large enough to hold several records +// (for example, 10 kilobytes will allow this class to buffer several +// dozen journal records at a time) +BOOL CDriveIndex::Init(WCHAR cDrive) +{ + // You should not call this function twice for one instance. + if (m_hVol != INVALID_HANDLE_VALUE) + DebugBreak(); + m_cDrive = cDrive; + ClearLastResult(); + BOOL fOk = FALSE; + __try { + // Open a handle to the volume + m_hVol = Open(m_cDrive, GENERIC_WRITE | GENERIC_READ); + if (INVALID_HANDLE_VALUE == m_hVol) + __leave; + fOk = TRUE; + } + __finally { + if (!fOk) + CleanUp(); + } + return(fOk); +} + +void CDriveIndex::ClearLastResult() +{ + LastResult = SearchResult(); +} + +// Adds a file to the database +BOOL CDriveIndex::Add(DWORDLONG Index, wstring *szName, DWORDLONG ParentIndex, DWORDLONG Filter) +{ + IndexedFile i; + i.Index = Index; + if(!Filter) + Filter = MakeFilter(szName); + i.Filter = Filter; + rgFiles.insert(rgFiles.end(), i); + return(TRUE); +} + + + +// Adds a directory to the database +BOOL CDriveIndex::AddDir(DWORDLONG Index, wstring *szName, DWORDLONG ParentIndex, DWORDLONG Filter) +{ + IndexedDirectory i; + i.Index = Index; + if(!Filter) + Filter = MakeFilter(szName); + i.Filter = Filter; + i.nFiles = 0; + rgDirectories.insert(rgDirectories.end(), i); + return(TRUE); +} + + + +// Calculates a 64bit value that is used to filter out many files before comparing their filenames +// This method gives a huge speed boost. +DWORDLONG CDriveIndex::MakeFilter(wstring *szName) +{ + /* + Creates an address that is used to filter out strings that don't contain the queried characters + Explanation of the meaning of the single bits: + 0-25 a-z + 26-35 0-9 + 36 . + 37 space + 38 !#$&'()+,-~_ + 39 2 same characters + 40 3 same characters + The fields below indicate the presence of 2-character sequences. Based off http://en.wikipedia.org/wiki/Letter_frequency + 41 TH + 42 HE + 43 AN + 44 RE + 45 ER + 46 IN + 47 ON + 48 AT + 49 ND + 50 ST + 51 ES + 52 EN + 53 OF + 54 TE + 55 ED + 56 OR + 57 TI + 58 HI + 59 AS + 60 TO + 61-63 length (max. 8 characters. Queries are usually shorter than this) + */ + if(!(szName->length() > 0)) + return 0; + DWORDLONG Address = 0; + WCHAR c; + wstring szlower(*szName); + transform(szlower.begin(), szlower.end(), szlower.begin(), tolower); + int counts[26] = {0}; //This array is used to check if characters occur two or three times in the string + wstring::size_type l = szlower.length(); + for(unsigned int i = 0; i != l; i++) + { + c = szlower[i]; + if(c > 96 && c < 123) //a-z + { + Address |= 1ui64 << (DWORDLONG)((DWORDLONG)c - 97ui64); + counts[c-97]++; + if(i < l - 1) + { + if(c == L't' && szlower[i+1] == L'h') //th + Address |= 1ui64 << 41; + else if(c == L'h' && szlower[i+1] == L'e') //he + Address |= 1ui64 << 41; + else if(c == L'a' && szlower[i+1] == L'n') //an + Address |= 1ui64 << 41; + else if(c == L'r' && szlower[i+1] == L'e') //re + Address |= 1ui64 << 41; + else if(c == L'e' && szlower[i+1] == L'r') //er + Address |= 1ui64 << 41; + else if(c == L'i' && szlower[i+1] == L'n') //in + Address |= 1ui64 << 41; + else if(c == L'o' && szlower[i+1] == L'n') //on + Address |= 1ui64 << 41; + else if(c == L'a' && szlower[i+1] == L't') //at + Address |= 1ui64 << 41; + else if(c == L'n' && szlower[i+1] == L'd') //nd + Address |= 1ui64 << 41; + else if(c == L's' && szlower[i+1] == L't') //st + Address |= 1ui64 << 41; + else if(c == L'e' && szlower[i+1] == L's') //es + Address |= 1ui64 << 41; + else if(c == L'e' && szlower[i+1] == L'n') //en + Address |= 1ui64 << 41; + else if(c == L'o' && szlower[i+1] == L'f') //of + Address |= 1ui64 << 41; + else if(c == L't' && szlower[i+1] == L'e') //te + Address |= 1ui64 << 41; + else if(c == L'e' && szlower[i+1] == L'd') //ed + Address |= 1ui64 << 41; + else if(c == L'o' && szlower[i+1] == L'r') //or + Address |= 1ui64 << 41; + else if(c == L't' && szlower[i+1] == L'i') //ti + Address |= 1ui64 << 41; + else if(c == L'h' && szlower[i+1] == L'i') //hi + Address |= 1ui64 << 41; + else if(c == L'a' && szlower[i+1] == L's') //as + Address |= 1ui64 << 41; + else if(c == L't' && szlower[i+1] == L'o') //to + Address |= 1ui64 << 41; + } + } + else if(c >= L'0' && c <= '9') //0-9 + Address |= 1ui64 << (c - L'0' + 26ui64); + else if(c == L'.') //. + Address |= 1ui64 << 36; + else if(c == L' ') // space + Address |= 1ui64 << 37; + else if(c == L'!' || c == L'#' || c == L'$' || c == L'&' || c == L'\'' || c == L'(' || c == L')' || c == L'+' || c == L',' || c == L'-' || c == L'~' || c == L'_') + Address |= 1ui64 << 38; // !#$&'()+,-~_ + } + for(unsigned int i = 0; i != 26; i++) + { + if(counts[i] == 2) + Address |= 1ui64 << 39; + else if(counts[i] > 2) + Address |= 1ui64 << 40; + } + DWORDLONG length = (szlower.length() > 7 ? 7ui64 : (DWORDLONG)szlower.length()) & 0x00000007ui64; //3 bits for length -> 8 max + Address |= length << 61ui64; + return Address; +} + + + +// Internal function for searching in the database. +// For projects in C++ which use this project it might be preferable to use this function +// to skip the wrapper. +// Returns: number of results, -1 if maxResults != -1 and not all results were found +int CDriveIndex::Find(wstring *strQuery, wstring *strQueryPath, vector *rgsrfResults, BOOL bSort, BOOL bEnhancedSearch, int maxResults) +{ + //These variables are used to control the flow of execution in this function. + + //Indicates where results should be searched + unsigned int SearchWhere = IN_FILES; + //Offset for vector marked by SearchWhere + unsigned int iOffset = 0; + //Used to skip the search when the previous two properties should be carried over to the next search without actually using them now. + BOOL bSkipSearch = false; + + //Number of results in this search. -1 if more than maximum number of results. + int nResults = 0; + + //No query, just ignore this call + if(strQuery->length() == 0) + { + // Store this query + LastResult.Query = wstring(TEXT("")); + LastResult.Results = vector(); + return nResults; + } + + if(strQueryPath != NULL) + { + //Check if the path actually matches the drive of this index + WCHAR szDrive[_MAX_DRIVE]; + _wsplitpath(strQueryPath->c_str(), szDrive, NULL, NULL, NULL); + for(unsigned int j = 0; j != _MAX_DRIVE; j++) + szDrive[j] = toupper(szDrive[j]); + if(wstring(szDrive).compare(wstring(1,toupper(m_cDrive))) == 0) + return 0; + } + + //Create lower query string for case-insensitive search + wstring strQueryLower(*strQuery); + for(unsigned int j = 0; j != strQueryLower.length(); j++) + strQueryLower[j] = tolower(strQueryLower[j]); + const WCHAR *szQueryLower = strQueryLower.c_str(); + + //Create lower query path string for case-insensitive search + wstring strQueryPathLower(strQueryPath != NULL ? *strQueryPath : TEXT("")); + for(unsigned int j = 0; j != strQueryPathLower.length(); j++) + strQueryPathLower[j] = tolower((*strQueryPath)[j]); + wstring* pstrQueryPathLower = strQueryPath != NULL && strQueryPathLower.length() > 0 ? &strQueryPathLower : NULL; + + //If the query path is different from the last query so that the results are not valid anymore, the last query needs to be dropped + if(!(strQueryPath != NULL && (LastResult.maxResults == -1 || LastResult.iOffset == 0) && (LastResult.SearchPath.length() == 0 || strQueryPathLower.find(LastResult.SearchPath) == 0))) + LastResult = SearchResult(); + + //Calculate Filter value and length of the current query which are compared with the cached ones to skip many of them + DWORDLONG QueryFilter = MakeFilter(&strQueryLower); + DWORDLONG QueryLength = (QueryFilter & 0xE000000000000000ui64) >> 61ui64; //Bits 61-63 for storing lengths up to 8 + QueryFilter = QueryFilter & 0x1FFFFFFFFFFFFFFFui64; //All but the last 3 bits + + //If the same query string as in the last query was used + if(strQueryLower.compare(LastResult.Query) == 0 && LastResult.Results.size() > 0 && (LastResult.SearchEndedWhere == NO_WHERE && iOffset != 1)) // need proper condition here to skip + { + //Keep the position of the last result + SearchWhere = LastResult.SearchEndedWhere; + iOffset = LastResult.iOffset; + bSkipSearch = true; + for(int i = 0; i != LastResult.Results.size(); i++) + { + BOOL bFound = true; + if(pstrQueryPathLower != NULL) + { + wstring strPathLower(LastResult.Results[i].Path); + for(unsigned int j = 0; j != strPathLower.length(); j++) + strPathLower[j] = tolower(LastResult.Results[i].Path[j]); + bFound = strPathLower.find(strQueryPathLower) != -1; + } + if(bFound) + { + nResults++; + //If the result limit has decreased and we have found all (shouldn't happen in common scenarios) + if(maxResults != -1 && nResults > maxResults) + { + nResults = -1; + + //If we get here, the next incremental should start fresh, but only if it requires more results than this one. + //To accomplish this we make this result contain no information about the origin of these results. + SearchWhere = NO_WHERE; + iOffset = 1; + break; + } + rgsrfResults->insert(rgsrfResults->end(), LastResult.Results[i]); + } + } + //if the last search was limited and didn't finish because it found enough files and we don't have the maximum number of results yet + //we need to continue the search where the last one stopped. + if(LastResult.maxResults != -1 && LastResult.SearchEndedWhere != NO_WHERE && (maxResults == -1 || nResults < maxResults)) + bSkipSearch = false; + } + //If this query is more specific than the previous one, it can use the results from the previous query + else if(strQueryLower.find(LastResult.Query) != -1 && LastResult.Results.size() > 0) + { + bSkipSearch = true; + //Keep the position of the last result + SearchWhere = LastResult.SearchEndedWhere; + iOffset = LastResult.iOffset; + FindInPreviousResults(*strQuery, szQueryLower, QueryFilter, QueryLength, pstrQueryPathLower, *rgsrfResults, 0, bEnhancedSearch, maxResults, nResults); + + //if the last search was limited and didn't finish because it found enough files and we don't have the maximum number of results yet + //we need to continue the search where the last one stopped. + if(LastResult.maxResults != -1 && LastResult.SearchEndedWhere != NO_WHERE && (maxResults == -1 || nResults < maxResults)) + bSkipSearch = false; + } + DWORDLONG FRNPath; + long long nFilesInDir = -1; + if(strQueryPath != NULL && strQueryPath->length()) + { + FRNPath = PathToFRN(strQueryPath); + wstring strPath2; + GetDir(FRNPath, &strPath2); + int iOffset = (int) FindDirOffsetByIndex(FRNPath); + if(iOffset != -1) + nFilesInDir = rgDirectories[iOffset].nFiles; + } + if(SearchWhere == IN_FILES && iOffset == 0 && nFilesInDir != -1 && nFilesInDir < 10000 && !bSkipSearch) + { + FindRecursively(*strQuery, szQueryLower, QueryFilter, QueryLength, strQueryPath, *rgsrfResults, bEnhancedSearch, maxResults, nResults); + SearchWhere = NO_WHERE; + } + else if(SearchWhere == IN_FILES && !bSkipSearch) + { + //Find in file index + FindInJournal(*strQuery, szQueryLower, QueryFilter, QueryLength, (strQueryPath != NULL ? &strQueryPathLower : NULL), rgFiles, *rgsrfResults, iOffset, bEnhancedSearch, maxResults, nResults); + //If we found the maximum number of results in the file index we stop here + if(maxResults != -1 && nResults == -1) + iOffset++; //Start with next entry on the next incremental search + else //Search isn't limited or not all results found yet, continue in directory index + { + SearchWhere = IN_DIRECTORIES; + iOffset = 0; + } + } + + if(SearchWhere == IN_DIRECTORIES && !bSkipSearch) + { + //Find in directory index + FindInJournal(*strQuery, szQueryLower, QueryFilter, QueryLength, pstrQueryPathLower, rgDirectories, *rgsrfResults, iOffset, bEnhancedSearch, maxResults, nResults); + //If we found the maximum number of results in the directory index we stop here + if(maxResults != -1 && nResults == -1) + iOffset++; //Start with next entry on the next incremental search + else //Search isn't limited or less than the maximum number of results found + { + SearchWhere = NO_WHERE; + iOffset = 0; + } + } + + //Sort by match quality and name + if(bSort) + sort(rgsrfResults->begin(), rgsrfResults->end()); + + // Store this query + LastResult.Query = wstring(strQueryLower); + + // Store search path + LastResult.SearchPath = strQueryPathLower; + + //Clear old results, they will be replaced with the current ones + LastResult.Results = vector(); + + //Store number of results (Needed for incremental search) + LastResult.iOffset = iOffset; + + //Store if this search was limited + LastResult.maxResults = maxResults; + + //Store where the current search ended due to file limit (or if it didn't); + LastResult.SearchEndedWhere = SearchWhere; + + //Update last results + for(unsigned int i = 0; i != rgsrfResults->size(); i++) + LastResult.Results.insert(LastResult.Results.end(), (*rgsrfResults)[i]); + + return nResults; +} + +void CDriveIndex::FindRecursively(wstring &strQuery, const WCHAR* &szQueryLower, DWORDLONG QueryFilter, DWORDLONG QueryLength, wstring* strQueryPath, vector &rgsrfResults, BOOL bEnhancedSearch, int maxResults, int &nResults) +{ + WIN32_FIND_DATA ffd; + size_t length_of_arg; + HANDLE hFind = INVALID_HANDLE_VALUE; + + // Check that the input path plus 3 is not longer than MAX_PATH. + // Three characters are for the "\*" plus NULL appended below. + length_of_arg = strQueryPath->length(); + if (length_of_arg > (MAX_PATH - 3)) + return; + + // Prepare string for use with FindFile functions. First, copy the + // string to a buffer, then append '\*' to the directory name. + wstring strPath = wstring(*strQueryPath); + if((*strQueryPath)[strQueryPath->length() - 1] != L'\\') + strPath += wstring(TEXT("\\*")); + else + strPath += wstring(TEXT("*")); + + const WCHAR* szDir = strPath.c_str(); + + // Find the first file in the directory. + hFind = FindFirstFile(szDir, &ffd); + + if (hFind == INVALID_HANDLE_VALUE) + return; + unsigned int nFiles = 0; + // List all the files in the directory with some info about them. + do + { + if(ffd.dwFileAttributes & FILE_ATTRIBUTE_VIRTUAL || ffd.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) + continue; + float MatchQuality; + wstring strFilename(ffd.cFileName); + if(strFilename.compare(TEXT(".")) == 0 || strFilename.compare(TEXT("..")) == 0) + continue; + nFiles++; + if(bEnhancedSearch) + MatchQuality = FuzzySearch(strFilename, strQuery); + else + { + wstring szLower(strFilename); + for(unsigned int j = 0; j != szLower.length(); j++) + szLower[j] = tolower(szLower[j]); + MatchQuality = szLower.find(strQuery) != -1; + } + + if(MatchQuality > 0.6f) + { + nResults++; + if(maxResults != -1 && nResults > maxResults) + { + nResults = -1; + break; + } + SearchResultFile srf; + srf.Filename = strFilename; + srf.Path = *strQueryPath + TEXT("\\"); + srf.Filter = MAXULONG64; + srf.MatchQuality = MatchQuality; + rgsrfResults.insert(rgsrfResults.end(), srf); + } + + if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + { + wstring strSubPath = wstring(*strQueryPath); + if((*strQueryPath)[strQueryPath->length() - 1] != L'\\') + strSubPath += L'\\'; + strSubPath += ffd.cFileName; + FindRecursively(strQuery, szQueryLower, QueryFilter, QueryLength, &strSubPath, rgsrfResults, bEnhancedSearch, maxResults, nResults); + if(nResults == -1) + break; + } + } + while (FindNextFile(hFind, &ffd) != 0); + FindClose(hFind); +} + +//T needs to be IndexedFile or IndexedDirectory +template +void CDriveIndex::FindInJournal(wstring &strQuery, const WCHAR* &szQueryLower, DWORDLONG QueryFilter, DWORDLONG QueryLength, wstring * strQueryPath, vector &rgJournalIndex, vector &rgsrfResults, unsigned int iOffset, BOOL bEnhancedSearch, int maxResults, int &nResults) +{ + for(unsigned int j = 0; j != rgJournalIndex.size(); j++) + { + IndexedFile* i = (IndexedFile*)&rgJournalIndex[j]; + DWORDLONG Length = (i->Filter & 0xE000000000000000ui64) >> 61ui64; //Bits 61-63 for storing lengths up to 8 + DWORDLONG Filter = i->Filter & 0x1FFFFFFFFFFFFFFFui64; //All but the last 3 bits + if((Filter & QueryFilter) == QueryFilter && QueryLength <= Length) + { + USNEntry file = FRNToName(i->Index); + float MatchQuality; + if(bEnhancedSearch) + MatchQuality = FuzzySearch(file.Name, strQuery); + else + { + wstring szLower(file.Name); + for(unsigned int j = 0; j != szLower.length(); j++) + szLower[j] = tolower(szLower[j]); + MatchQuality = szLower.find(strQuery) != -1; + } + + if(MatchQuality > 0.6f) + { + nResults++; + if(maxResults != -1 && nResults > maxResults) + { + nResults = -1; + break; + } + SearchResultFile srf; + srf.Filename = file.Name; + srf.Path.reserve(MAX_PATH); + Get(i->Index, &srf.Path); + BOOL bFound = true; + if(strQueryPath != NULL) + { + wstring strPathLower(srf.Path); + for(unsigned int j = 0; j != strPathLower.length(); j++) + strPathLower[j] = tolower(strPathLower[j]); + bFound = strPathLower.find(*strQueryPath) != -1; + } + if(bFound) + { + //split path + WCHAR szDrive[_MAX_DRIVE]; + WCHAR szPath[_MAX_PATH]; + WCHAR szName[_MAX_FNAME]; + WCHAR szExt[_MAX_EXT]; + _wsplitpath(srf.Path.c_str(), szDrive, szPath, szName, szExt); + srf.Path = wstring(szDrive) + wstring(szPath); + srf.Filter = i->Filter; + srf.MatchQuality = MatchQuality; + rgsrfResults.insert(rgsrfResults.end(), srf); + } + } + } + } +} +void CDriveIndex::FindInPreviousResults(wstring &strQuery, const WCHAR* &szQueryLower, DWORDLONG QueryFilter, DWORDLONG QueryLength, wstring * strQueryPath, vector &rgsrfResults, unsigned int iOffset, BOOL bEnhancedSearch, int maxResults, int &nResults) +{ + for(int i = 0; i != LastResult.Results.size() && (maxResults == -1 || i < maxResults); i++) + { + SearchResultFile *srf = & LastResult.Results[i]; + DWORDLONG Length = (srf->Filter & 0xE000000000000000ui64) >> 61ui64; //Bits 61-63 for storing lengths up to 8 + DWORDLONG Filter = srf->Filter & 0x1FFFFFFFFFFFFFFFui64; //All but the last 3 bits + if((Filter & QueryFilter) == QueryFilter && QueryLength <= Length) + { + if(bEnhancedSearch) + srf->MatchQuality = FuzzySearch(srf->Filename, strQuery); + else + { + wstring szLower(srf->Filename); + for(unsigned int j = 0; j != szLower.length(); j++) + szLower[j] = tolower(szLower[j]); + srf->MatchQuality = szLower.find(szQueryLower) != -1; + } + if(srf->MatchQuality > 0.6f) + { + BOOL bFound = true; + if(strQueryPath != NULL) + { + wstring strPathLower(srf->Path); + for(unsigned int j = 0; j != srf->Path.length(); j++) + strPathLower[j] = tolower(srf->Path[j]); + bFound = strPathLower.find(*strQueryPath) != -1; + } + if(bFound) + { + nResults++; + if(maxResults != -1 && nResults > maxResults) + { + nResults = -1; + break; + } + rgsrfResults.insert(rgsrfResults.end(), *srf); + } + } + } + } +} + + +// Clears the database +BOOL CDriveIndex::Empty() +{ + rgFiles.clear(); + rgDirectories.clear(); + return(TRUE); +} + + + +// Constructs a path for a file +BOOL CDriveIndex::Get(DWORDLONG Index, wstring *sz) const +{ + *sz = TEXT(""); + int n = 0; + do { + USNEntry file = FRNToName(Index); + *sz = file.Name + ((n != 0) ? TEXT("\\") : TEXT("")) + *sz; + Index = file.ParentIndex; + n++; + } while (Index != 0); + return(TRUE); +} + + + +// Constructs a path for a directory +BOOL CDriveIndex::GetDir(DWORDLONG Index, wstring *sz) const +{ + *sz = TEXT(""); + do { + USNEntry file = FRNToName(Index); + *sz = file.Name + ((sz->length() != 0) ? TEXT("\\") : TEXT("")) + *sz; + Index = file.ParentIndex; + } while (Index != 0); + return(TRUE); +} + + + +//Finds the position of a file in the database by the FileReferenceNumber +INT64 CDriveIndex::FindOffsetByIndex(DWORDLONG Index) { + + vector::difference_type pos; + IndexedFile i; + i.Index = Index; + pos = distance(rgFiles.begin(), lower_bound(rgFiles.begin(), rgFiles.end(), i)); + return (INT64) (pos == rgFiles.size() ? -1 : pos); // this is valid because the number of files doesn't exceed the range of INT64 +} + + + +//Finds the position of a directory in the database by the FileReferenceNumber +INT64 CDriveIndex::FindDirOffsetByIndex(DWORDLONG Index) +{ + vector::difference_type pos; + IndexedDirectory i; + i.Index = Index; + pos = distance(rgDirectories.begin(), lower_bound(rgDirectories.begin(), rgDirectories.end(), i)); + return (INT64) (pos == rgDirectories.size() ? -1 : pos); // this is valid because the number of files doesn't exceed the range of INT64 +} + +DWORDLONG PathToFRN(wstring* strPath) +{ + HANDLE hDir = CreateFile(strPath->c_str(), 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); + if(hDir == INVALID_HANDLE_VALUE) + return 0; + BY_HANDLE_FILE_INFORMATION fi; + GetFileInformationByHandle(hDir, &fi); + CloseHandle(hDir); + return (((DWORDLONG) fi.nFileIndexHigh) << 32) | fi.nFileIndexLow; +} + +// Enumerate the MFT for all entries. Store the file reference numbers of +// any directories in the database. +void CDriveIndex::PopulateIndex() +{ + Empty(); + + vector FileParents; + vector DirectoryParents; + + USN_JOURNAL_DATA ujd; + Query(&ujd); + + // Get the FRN of the root directory + // This had BETTER work, or we can't do anything + + WCHAR szRoot[_MAX_PATH]; + wsprintf(szRoot, TEXT("%c:\\"), m_cDrive); + HANDLE hDir = CreateFile(szRoot, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); + + BY_HANDLE_FILE_INFORMATION fi; + GetFileInformationByHandle(hDir, &fi); + CloseHandle(hDir); + DWORDLONG IndexRoot = (((DWORDLONG) fi.nFileIndexHigh) << 32) | fi.nFileIndexLow; + wsprintf(szRoot, TEXT("%c:"), m_cDrive); + AddDir(IndexRoot, &wstring(szRoot), 0); + DirectoryParents.insert(DirectoryParents.end(), 0); + m_dwDriveFRN = IndexRoot; + + LEGACY_MFT_ENUM_DATA med; + med.StartFileReferenceNumber = 0; + med.LowUsn = 0; + med.HighUsn = ujd.NextUsn; + + // Process MFT in 64k chunks + BYTE pData[sizeof(DWORDLONG) + 0x10000]; + DWORDLONG fnLast = 0; + DWORD cb; + unsigned int num = 0; + unsigned int numDirs = 1; + while (DeviceIoControl(m_hVol, FSCTL_ENUM_USN_DATA, &med, sizeof(med), pData, sizeof(pData), &cb, NULL) != FALSE) { + + PUSN_RECORD pRecord = (PUSN_RECORD) &pData[sizeof(USN)]; + while ((PBYTE) pRecord < (pData + cb)) { + if ((pRecord->FileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0) + numDirs++; + else + num++; + pRecord = (PUSN_RECORD) ((PBYTE) pRecord + pRecord->RecordLength); + } + med.StartFileReferenceNumber = * (DWORDLONG *) pData; + } + DWORD err1 = GetLastError(); + + FileParents.reserve(num); + DirectoryParents.reserve(numDirs); + rgFiles.reserve(num); + rgDirectories.reserve(numDirs); + hash_map hmFiles; + hash_map hmDirectories; + hash_map::iterator it; + med.StartFileReferenceNumber = 0; + while (DeviceIoControl(m_hVol, FSCTL_ENUM_USN_DATA, &med, sizeof(med), pData, sizeof(pData), &cb, NULL) != FALSE) + { + PUSN_RECORD pRecord = (PUSN_RECORD) &pData[sizeof(USN)]; + while ((PBYTE) pRecord < (pData + cb)) + { + wstring sz((LPCWSTR) ((PBYTE) pRecord + pRecord->FileNameOffset), pRecord->FileNameLength / sizeof(WCHAR)); + if ((pRecord->FileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0) + { + AddDir(pRecord->FileReferenceNumber, &sz, pRecord->ParentFileReferenceNumber); + //DirectoryParents.insert(DirectoryParents.end(), pRecord->ParentFileReferenceNumber); + HashMapEntry hme; + hme.iOffset = rgDirectories.size() - 1; + hme.ParentFRN = pRecord->ParentFileReferenceNumber; + hmDirectories[pRecord->FileReferenceNumber] = hme; + } + else + { + Add(pRecord->FileReferenceNumber, &sz, pRecord->ParentFileReferenceNumber); + HashMapEntry hme; + hme.iOffset = rgFiles.size() - 1; + hme.ParentFRN = pRecord->ParentFileReferenceNumber; + //FileParents.insert(FileParents.end(), pRecord->ParentFileReferenceNumber); + hmFiles[pRecord->FileReferenceNumber] = hme; + } + pRecord = (PUSN_RECORD) ((PBYTE) pRecord + pRecord->RecordLength); + } + med.StartFileReferenceNumber = * (DWORDLONG *) pData; + } + err1 = GetLastError(); + + //Calculate files per directory. This takes most of the indexing time, but this information can be useful to reduce the time needed + //for searching in directories with few files (less than 10k). + for ( it=hmFiles.begin() ; it != hmFiles.end(); it++ ) + { + HashMapEntry* hme = &hmDirectories[it->second.ParentFRN]; + do + { + rgDirectories[hme->iOffset].nFiles++; + HashMapEntry* hme2 = &hmDirectories[it->second.ParentFRN]; + + if(hme != hme2) + hme = hme2; + else // This must not happen, otherwise a directory is its own parent! + break; + } while(hme->ParentFRN != 0); + } + //for(unsigned int i = 0; i != FileParents.size(); i++) + //{ + // DWORDLONG dwIndex = FileParents[i]; + // while(dwIndex != 0) + // { + // int iOffset = -1; + // for(unsigned int j = 0; j != rgDirectories.size(); j++) + // if(rgDirectories[j].Index == dwIndex) + // { + // iOffset = j; + // break; + // } + // if(iOffset == -1) + // break; + // rgDirectories[iOffset].nFiles++; + // DWORDLONG dwIndex2 = DirectoryParents[iOffset]; + + // if(dwIndex != dwIndex2) + // dwIndex = dwIndex2; + // else // This must not happen, otherwise a directory is its own parent! + // break; + // } + // //wstring strPath; + // //GetDir(dwIndex, &strPath); + + // //do { + // // //USNEntry file = FRNToName(dwIndex); + // // int iOffset = -1; + // // for(int j = 0; j != rgDirectories.size(); j++) + // // if(rgDirectories[j].Index == dwIndex) + // // { + // // iOffset = j; + // // break; + // // } + // // if(iOffset == -1) + // // break; + // // //USNEntry parent = FRNToName(file.ParentIndex); + // // //USNEntry parent2 = FRNToName(rgDirectories[iOffset].Index); + // // rgDirectories[iOffset].nFiles++; + // // dwIndex = file.ParentIndex; + // //} while (dwIndex != 0); + //} + rgFiles.shrink_to_fit(); + rgDirectories.shrink_to_fit(); + sort(rgFiles.begin(), rgFiles.end()); + sort(rgDirectories.begin(), rgDirectories.end()); +} + +// Resolve FRN to filename by enumerating USN journal with StartFileReferenceNumber=FRN +USNEntry CDriveIndex::FRNToName(DWORDLONG FRN) const +{ + if(FRN == m_dwDriveFRN) + return USNEntry(wstring(1, m_cDrive) + wstring(TEXT(":")), 0); + USN_JOURNAL_DATA ujd; + Query(&ujd); + + LEGACY_MFT_ENUM_DATA med; + med.StartFileReferenceNumber = FRN; + med.LowUsn = 0; + med.HighUsn = ujd.NextUsn; + + // The structure only needs a single entry so it can be pretty small + BYTE pData[sizeof(DWORDLONG) + 0x300]; + DWORD cb; + while (DeviceIoControl(m_hVol, FSCTL_ENUM_USN_DATA, &med, sizeof(med), pData, sizeof(pData), &cb, NULL) != FALSE) { + + PUSN_RECORD pRecord = (PUSN_RECORD) &pData[sizeof(USN)]; + while ((PBYTE) pRecord < (pData + cb)) { + if(pRecord->FileReferenceNumber == FRN) + return USNEntry(wstring((LPCWSTR) ((PBYTE) pRecord + pRecord->FileNameOffset), pRecord->FileNameLength / sizeof(WCHAR)), pRecord->ParentFileReferenceNumber); + pRecord = (PUSN_RECORD) ((PBYTE) pRecord + pRecord->RecordLength); + } + med.StartFileReferenceNumber = * (DWORDLONG *) pData; + } + return USNEntry(wstring(TEXT("")), 0); +} + + + +// Saves the database to disk. The file can be used to create an instance of CDriveIndex. +BOOL CDriveIndex::SaveToDisk(wstring &strPath) const +{ + ofstream::pos_type size; + ofstream file (strPath.c_str(), ios::out|ios::binary|ios::trunc); + if (file.is_open()) + { + //Drive character + file.write((char*) &m_cDrive, sizeof(m_cDrive)); + + //Drive FileReferenceNumber + file.write((char*) &m_dwDriveFRN, sizeof(m_dwDriveFRN)); + + unsigned int size = rgFiles.size(); + //Number of files + file.write((char*) &size, sizeof(rgFiles.size())); + //indexed files + file.write((char*) &(rgFiles[0]), sizeof(IndexedFile) * rgFiles.size()); + + size = rgDirectories.size(); + //Number of directories + file.write((char*) &size, sizeof(rgDirectories.size())); + //indexed directories + file.write((char*) &(rgDirectories[0]), sizeof(IndexedDirectory) * rgDirectories.size()); + file.close(); + return true; + } + return false; +} + + + +// Constructor for loading the index from a previously saved file +CDriveIndex::CDriveIndex(wstring &strPath) +{ + m_hVol = INVALID_HANDLE_VALUE; + Empty(); + + ifstream::pos_type size; + + ifstream file (strPath.c_str(), ios::in | ios::binary); + if (file.is_open()) + { + //Drive + WCHAR cDrive; + file.read((char*) &cDrive, sizeof(WCHAR)); + + if(Init(cDrive)) + { + // Drive FileReferenceNumber + file.read((char*) &m_dwDriveFRN, sizeof(m_dwDriveFRN)); + + //Number of files + unsigned int numFiles = 0; + file.read((char*) &numFiles, sizeof(numFiles)); + rgFiles.reserve(numFiles); + + //indexed files + for(unsigned int j = 0; j != numFiles; j++) + { + IndexedFile i; + file.read((char*) &i, sizeof(IndexedFile)); + rgFiles.insert(rgFiles.end(), i); + } + + //Number of directories + unsigned int numDirs = 0; + file.read((char*) &numDirs, sizeof(numDirs)); + rgDirectories.reserve(numDirs); + + //indexed directories + for(unsigned int j = 0; j != numDirs; j++) + { + IndexedDirectory i; + file.read((char*) &i, sizeof(IndexedDirectory)); + rgDirectories.insert(rgDirectories.end(), i); + } + } + file.close(); + } + return; +} + + + +// Returns the number of files and folders on this drive +DriveInfo CDriveIndex::GetInfo() const +{ + DriveInfo di; + di.NumFiles = (DWORDLONG) rgFiles.size(); + di.NumDirectories = (DWORDLONG) rgDirectories.size(); + return di; +} + + + + +//Performs a fuzzy search for shorter in longer. +//return values range from 0.0 = identical to 1.0 = completely different. 0.4 seems appropriate +float FuzzySearch(wstring &longer, wstring &shorter) +{ + //Note: All string lengths are shorter than MAX_PATH, so an uint is perfectly fitted. + unsigned int lenl = (unsigned int) longer.length(); + unsigned int lens = (unsigned int) shorter.length(); + + if(lens > lenl) + return 0.0f; + + //Check if the shorter string is a substring of the longer string + unsigned int Contained = (unsigned int) longer.find(shorter); + if(Contained != wstring::npos) + return Contained == 0 ? 1.0f : 0.8f; + + wstring longerlower(longer); + wstring shorterlower(shorter); + for(unsigned int i = 0; i != lenl; i++) + longerlower[i] = tolower(longer[i]); + for(unsigned int i = 0; i != lens; i++) + shorterlower[i] = tolower(shorter[i]); + + //Check if the shorter string is a substring of the longer string + Contained = (unsigned int) longerlower.find(shorterlower); + if(Contained != wstring::npos) + return Contained == 0 ? 0.9f : 0.7f; + + //Check if string can be matched by omitting characters + if(lens < 5) + { + unsigned int pos = 0; + unsigned int matched = 0; + for(unsigned int i = 0; i != lens; i++) + { + WCHAR c = toupper(shorter[i]); //only look for capital letters in longer string, (e.g. match tc in TrueCrypt) + for(unsigned int j = 0; j != lenl - pos; j++) + { + if(longer[pos + j] == c) + { + pos = j; + matched++; + break; + } + else + continue; + } + } + if(matched == lens) + return 0.9f; //Slightly worse than direct matches + } + return 0; } \ No newline at end of file diff --git a/FileSearch/gel.cpp b/FileSearch/gel.cpp index 6374561..514b062 100644 --- a/FileSearch/gel.cpp +++ b/FileSearch/gel.cpp @@ -1,29 +1,38 @@ -#include "stxutif.h" -#include - -#ifdef __MINGW32_VERSION -#ifndef _GLIBCXX_USE_WCHAR_T - -namespace std -{ - //instantiate the codecvt facet id for the required types - locale::id codecvt::id; -} - -#endif //_GLIBCXX_USE_WCHAR_T -#endif //__MINGW32_VERSION - - -namespace gel -{namespace stdx -{ - //instantiate the global locale - std::locale utf8_locale(std::locale(), new std::codecvt_utf8()); // VS2010 and further - - // convert wstring to UTF-8 string - std::string wstring_to_utf8 (const std::wstring& str) { - std::wstring_convert> myconv; - return myconv.to_bytes(str); - } - -}} +#include "stxutif.h" +#include + +#ifdef __MINGW32_VERSION +#ifndef _GLIBCXX_USE_WCHAR_T + +namespace std +{ + //instantiate the codecvt facet id for the required types + locale::id codecvt::id; +} + +#endif //_GLIBCXX_USE_WCHAR_T +#endif //__MINGW32_VERSION + + +namespace gel +{namespace stdx +{ +#if 0 + //instantiate the global locale + std::locale utf8_locale(std::locale(), new std::codecvt_utf8()); // VS2010 and further + + // convert wstring to UTF-8 string + std::string wstring_to_utf8 (const std::wstring& str) { + std::wstring_convert> myconv; + return myconv.to_bytes(str); + } +#else + + std::wstring_convert, wchar_t> conversion; + std::string wstring_to_utf8(const std::wstring& str) { + return conversion.to_bytes(str); + } + +#endif + +}} diff --git a/Release/Exportall.ahk b/Release/Exportall.ahk index b9040ba..7fbcf89 100644 --- a/Release/Exportall.ahk +++ b/Release/Exportall.ahk @@ -1,138 +1,139 @@ -#SingleInstance off -#NoEnv -#Warn -FileEncoding, UTF-8-RAW - -; Name of function in DLL to export a drive's index -DllExportFuncname := "ExportIndex" - -RunAsAdmin() { - global - params := - Loop, %0% ; For each parameter: - params .= A_Space . %A_Index% - local ShellExecute - ShellExecute := A_IsUnicode ? "shell32\ShellExecute":"shell32\ShellExecuteA" - if not A_IsAdmin - { - A_IsCompiled - ? DllCall(ShellExecute, uint, 0, str, "RunAs", str, A_ScriptFullPath, str, params , str, A_WorkingDir, int, 1) - : DllCall(ShellExecute, uint, 0, str, "RunAs", str, A_AhkPath, str, """" . A_ScriptFullPath . """" . A_Space . params, str, A_WorkingDir, int, 1) - ExitApp - } -} - -ToHex(num) -{ - if num is not integer - return num - oldFmt := A_FormatInteger - SetFormat, integer, hex - num := num + 0 - SetFormat, integer,% oldFmt - return num -} -;returns positive hex value of last error -GetLastError() -{ - return ToHex(A_LastError < 0 ? A_LastError & 0xFFFFFFFF : A_LastError) -} - -ErrorFormat(error_id) -{ - VarSetCapacity(msg,500+500*A_IsUnicode,0) - if !len := DllCall("FormatMessage" - ,"UInt",FORMAT_MESSAGE_FROM_SYSTEM := 0x00001000 | FORMAT_MESSAGE_IGNORE_INSERTS := 0x00000200 ;dwflags - ,"Ptr",0 ;lpSource - ,"UInt",error_id ;dwMessageId - ,"UInt",0 ;dwLanguageId - ,"Ptr",&msg ;lpBuffer - ,"UInt",500) ;nSize - return - return strget(&msg,len) -} - -ExitWithMessage(msg) { - MsgBox, 16, % "[Autohotkey message, will auto-close in 30 seconds]", % msg, 30 - ExitApp -} - -Class NtfsFastProc { - Description := "Quickly process NTFS filesystem metadata on a local disk." - LoggedInitError := "" - - Class ErrorModeHelper { - __New() { - ; prevent error mode dialogs from hanging the application - this.oldErrMode := DllCall("SetErrorMode", "UInt", SEM_FAILCRITICALERRORS := 0x0001) - } - __Delete() { - DllCall("SetErrorMode", "UInt", this.oldErrMode) - } - } - - __New(providerDllPath) { - global DllExportFuncname - this.DllPath := providerDllPath - foo := new NtfsFastProc.ErrorModeHelper - this.hModule := DllCall("LoadLibrary", "Str", providerDllPath, "PTR") - if !this.hModule - { - this.LoggedInitError := "Failed to load provider dll: " providerDllPath "`n`nMake sure it is a valid executable and that all runtime dependencies are satisfied.`n`nMessage: " ErrorFormat(GetLastError()) - return this - } - this.QueryProc := DllCall("GetProcAddress", "PTR", this.hModule, "AStr", DllExportFuncname, "PTR") - if !this.QueryProc - { - this.LoggedInitError := "Could not find a '" DllExportFuncname "' export symbol in provider dll: " providerDllPath "`n`nIt may not be a supported dll or the file is corrupt.`n`nMessage: " ErrorFormat(GetLastError()) - return this - } - } - - __Delete() { - if this.hModule - { - DllCall("FreeLibrary", "PTR", this.hModule) - this.hModule := 0 - } - } - - BuildFileDatabase(LoadExisting = true) { - NTFSDrives := this.GetIndexingDrives() - for index, Drive in NTFSDrives - { - ExportPath := A_ScriptDir "\" Drive "_export.xml" - DriveIndex := DllCall(this.DllPath "\CreateIndex", "ushort", NumGet(Drive, "ushort"), "PTR") - if (DriveIndex) - { - hSrResult := DllCall(this.QueryProc, "PTR", DriveIndex, "wstr", ExportPath, "int", ExportFormatAdcXml := 0, PTR) - SoundPlay, *64 - } -; ExportPath := A_ScriptDir "\" Drive "_export.xmlz4" -; DriveIndex := DllCall(this.DllPath "\CreateIndex", "ushort", NumGet(Drive, "ushort"), "PTR") -; if (DriveIndex) -; { -; hSrResult := DllCall(this.QueryProc, "PTR", DriveIndex, "wstr", ExportPath, "int", ExportFormatAdcXml_LZ4 := 1, PTR) -; SoundPlay, *64 -; } - } - } - - GetIndexingDrives() { - return ["J"] - } -} - - - - -RunAsAdmin() - -DllPath := A_ScriptDir "\FileSearch.dll" - -fastProc := new NtfsFastProc(DllPath) -fastProc.LoggedInitError <> "" ? ExitWithMessage(fastProc.loggedInitError) : - -fastProc.BuildFileDatabase() - - +#SingleInstance off +#NoEnv +#Warn +FileEncoding, UTF-8-RAW + +; Name of function in DLL to export a drive's index +DllExportFuncname := "ExportIndex" + +RunAsAdmin() { + global + params := + Loop, %0% ; For each parameter: + params .= A_Space . %A_Index% + local ShellExecute + ShellExecute := A_IsUnicode ? "shell32\ShellExecute":"shell32\ShellExecuteA" + if not A_IsAdmin + { + A_IsCompiled + ? DllCall(ShellExecute, uint, 0, str, "RunAs", str, A_ScriptFullPath, str, params , str, A_WorkingDir, int, 1) + : DllCall(ShellExecute, uint, 0, str, "RunAs", str, A_AhkPath, str, """" . A_ScriptFullPath . """" . A_Space . params, str, A_WorkingDir, int, 1) + ExitApp + } +} + +ToHex(num) +{ + if num is not integer + return num + oldFmt := A_FormatInteger + SetFormat, integer, hex + num := num + 0 + SetFormat, integer,% oldFmt + return num +} +;returns positive hex value of last error +GetLastError() +{ + return ToHex(A_LastError < 0 ? A_LastError & 0xFFFFFFFF : A_LastError) +} + +ErrorFormat(error_id) +{ + VarSetCapacity(msg,500+500*A_IsUnicode,0) + if !len := DllCall("FormatMessage" + ,"UInt",FORMAT_MESSAGE_FROM_SYSTEM := 0x00001000 | FORMAT_MESSAGE_IGNORE_INSERTS := 0x00000200 ;dwflags + ,"Ptr",0 ;lpSource + ,"UInt",error_id ;dwMessageId + ,"UInt",0 ;dwLanguageId + ,"Ptr",&msg ;lpBuffer + ,"UInt",500) ;nSize + return + return strget(&msg,len) +} + +ExitWithMessage(msg) { + MsgBox, 16, % "[Autohotkey message, will auto-close in 30 seconds]", % msg, 30 + ExitApp +} + +Class NtfsFastProc { + Description := "Quickly process NTFS filesystem metadata on a local disk." + LoggedInitError := "" + + Class ErrorModeHelper { + __New() { + ; prevent error mode dialogs from hanging the application + this.oldErrMode := DllCall("SetErrorMode", "UInt", SEM_FAILCRITICALERRORS := 0x0001) + } + __Delete() { + DllCall("SetErrorMode", "UInt", this.oldErrMode) + } + } + + __New(providerDllPath) { + global DllExportFuncname + this.DllPath := providerDllPath + foo := new NtfsFastProc.ErrorModeHelper + this.hModule := DllCall("LoadLibrary", "Str", providerDllPath, "PTR") + if !this.hModule + { + this.LoggedInitError := "Failed to load provider dll: " providerDllPath "`n`nMake sure it is a valid executable and that all runtime dependencies are satisfied.`n`nMessage: " ErrorFormat(GetLastError()) + return this + } + this.QueryProc := DllCall("GetProcAddress", "PTR", this.hModule, "AStr", DllExportFuncname, "PTR") + if !this.QueryProc + { + this.LoggedInitError := "Could not find a '" DllExportFuncname "' export symbol in provider dll: " providerDllPath "`n`nIt may not be a supported dll or the file is corrupt.`n`nMessage: " ErrorFormat(GetLastError()) + return this + } + } + + __Delete() { + if this.hModule + { + DllCall("FreeLibrary", "PTR", this.hModule) + this.hModule := 0 + } + } + + BuildFileDatabase(LoadExisting = true) { + NTFSDrives := this.GetIndexingDrives() + for index, Drive in NTFSDrives + { + ExportPath := A_ScriptDir "\" Drive "_export.xml" + DriveIndex := DllCall(this.DllPath "\CreateIndex", "ushort", NumGet(Drive, "ushort"), "PTR") + ; May be locked with BitLocker if DriveIndex is null + if (DriveIndex) + { + hSrResult := DllCall(this.QueryProc, "PTR", DriveIndex, "wstr", ExportPath, "int", ExportFormatAdcXml := 0, PTR) + SoundPlay, *64 + } +; ExportPath := A_ScriptDir "\" Drive "_export.xmlz4" +; DriveIndex := DllCall(this.DllPath "\CreateIndex", "ushort", NumGet(Drive, "ushort"), "PTR") +; if (DriveIndex) +; { +; hSrResult := DllCall(this.QueryProc, "PTR", DriveIndex, "wstr", ExportPath, "int", ExportFormatAdcXml_LZ4 := 1, PTR) +; SoundPlay, *64 +; } + } + } + + GetIndexingDrives() { + return ["J"] + } +} + + + + +RunAsAdmin() + +DllPath := A_ScriptDir "\FileSearch.dll" + +fastProc := new NtfsFastProc(DllPath) +fastProc.LoggedInitError <> "" ? ExitWithMessage(fastProc.loggedInitError) : + +fastProc.BuildFileDatabase() + + diff --git a/Release/FileSearch.dll b/Release/FileSearch.dll index fc5e9d6c845719609bc204cee21a819918e59cfb..07dec414998a651ae8553f7e58db009d72796a17 100644 GIT binary patch delta 26869 zcmeIbdt6ji_dkC2aB);{Mg;`{0R=_zGWQE}0WTmb=qQSKM?*!jA_X&32L;k`oKlZ= ztkfvGSXoitsH{MJgp7=O%q*=3pR8uoipmVlobP*`nNjL_p6~bhetxgtU%%h+wa(sq z?X}ikd+oK?-e;dPSWzEZ(GnQu0S>u%Ps^|cibAOE1qWs!>zeX#NnsdL8 zR*C5+(H1fNd$b1WmDcNGs*G1hZ$LR`;b+l$G5x{M=Mht7{BvTOv+#};oob{cz^8?6MPLkM_g>hU4$<7e^vN7oT`${_`S#^bvf)iKA@gmg*1$g=Hm&!j7?JsCFh{Hb<}-Y!aB5_J z_z70T59&5Hs!N}aji8Cji|uHoAHT6%5=-G<>-Gr9t+Fw=KP*dNOZXRL+a+8&Zj5k_Fn@We{1~{N9Z_?o92y#t>jKu0_5bmf8odVj1M+UW^(?A z*LugaNBBA!fllT-f2v#)D_t7qT`u)T8u+Jr4u{Sk^-RM3)j6@eJR%e}?j3P=;S)DF zuJVeMv~s!Je|WtmocmkGI9K(Ko1(H3n>R8HZB!l)_Tf;L`^vWB(mW=2Ri}8p-r^?s z6sm&7Dyhq*_}%MuhfU!B8L@_aF4t;YT zJdO5TW2C7Ek5k4~gS)Namc%`n|GHNZL}d5Q=|i1`w%*9SlaQ%TaJkMBnY-l{|7!1H z5c*~B@$6ZCP*i$&9V~UZO9>a$li&wH7`;notv?d*Qw? zIw|Zp7^<(8b;#v@K>UrL0gaZnZ;W9D}6Ge zH;J`2k+Mb1?-26`_{^9hN#(En%Q3N%gJJypF~)?GV<2@xoi~yQou}q_lMf){^ULOD z&)s~#SVhXoiA1#5*Y3X%-FD0^{K{A-Tf~RPr7$Z$JWk0B`{%`}S)U=WlQSpDj6rj@ zxx#WK7@SEZT)z7P|7zbv2{)PlxbHm@YiB+qJ`O#Z6CWe_W+eYmyhW8loNeH9lqE$t zW+i37BuUd;IZ3hZ$1NOpVsugldmAByvpG+pI>MdDUy6^x@PsDxlT4BFgA?Le6hAH@ zJ?U$+NYpqwNdt1u{fio&wkj!B>TFvY?k!6a9kVtuLGoHB{-cDI#Fd!NzUDV3CPN%5 zV)ljlJUZ;ow4DUcp60X|_{)iVJBi+KJXnbD!6NzB`gQTmh1YVT_)q(F4=ui%$%~`; zEB#7X0Y9z(6v@ZI{44#9ESvwX{{jS|+$06_@@tZ!*h9RKw1eH`70Fu3pl{S3zo@?>!%=uCnk&X*yV1;O;qmA z&oVT|y$LL$YSk-np%O`P3u?UO&92-dh!eZ`3}bKh4PRiK%5Ls|)woE)1iqK~E=kZ8 z{vmTCyTOmL^e$N7E)bb2qy(57^wbyeqvNCfPD#5nqxqLh|u<{3{vJ zlD5%&Q-)Ct6+XtxL9VeP+YXVfA0IQq$M#(RtZ#ifgmJ#{ouA3%MNd;Rwz`@i#<@d& z;-`;{U7-2nme-jjcVtC4vtk`t360gwH*di=IIgj}<#z6LAeVX5R}}#^UoPr)F4mtb zL5LlKJVjnxNrtQ1z<)6^2CjN-q*k#C6*dH-V1x!FV$`qR3#9s5*Ms|zI;s`8JF7`C z$H63i=BS6J6UK3H1(a}9ufqL-XxX&-g|eR2H7Gc@KTCHpf4Qs6)dXU9RjU`Y6{v7k z6Q9i|aFWYKnmM*t0oPc)fge6P#qOVM&V$qy=dILtsB;b8Ak#tWQF#wA5ytIW4wH&R zh#b+4q11n8H8C}21d9cqgleL$JRx<6MOS{iE3DmgvP^C|Qx=90pYJ|hiFk25%;};& zs%KntRwp5YF6C37YLR!0kh<0|r)Ubth%je$HX*C)ad%edi238VyQ<~5+lr+eEo-gF zlYlzHl|;F!Yk5UxKdhm7nOZwZbyi=*y@YdAA3*xA%swXK_F1cVKi8S_DzHjou&V3J zE4`5k6xyrF9a2R{X=o2JomdvXmZo6*@~*{UQ!$GogRzF?yIkZ+?yh6WN@_A?s%RNv zX#@++j6btX^Bel}Y_PaAye2C#TomO_MSyl5)bR7OhN=iN%{3v`{YbjFz`I=gsGU|Y z`Ih@2m#d91r+^_}l=BT)QIp6X&>>*qf8Rw})yqLxpPuv$Eg9G4BD1;e8+TH|TbeM*l^yH;)Jj$)f0^dYPDss;t$X>Umj?gl5xZ*lHr$Xnk2bjDvxAO0 zstdtOQ@Xl9%tSb&Jhu*Bd{kTw`yn)&URF9Ku)wM z1r%o%EK2bM+e7GOb04v1k@i$@icJ4glRj&Qob9y`{pO!6`YTqbfJI3uSd@rvTXax0 zVQ-ssGYU5Mio1!4@(xioGHC@LGcNviyc2_mt15&X+|(vp*Ni=&Q;Z@GajN`33>UKM znc}9>7cxW*6$t2mV6@O$RRc!WwFWcUXGQ;DSGFh zOu3bDc7Fr^jd%J?8CmjYQ@U2jUHNh>z0NUGL?yI2*%g+7_0v1L2@eelAZ-5rY#dFj zgmH?q&3Q1%jskT{ph=e{zccH|ul~cVBLQN+?q2t%Ax|9p8@NVzVn?m-(F9StDVKS;wVt4@bj zJ_BG<7_*|vCOap{O-<#N>i5gWxF%pFsK9#RT`tGI7P}qqXV`r=^80h*loZ5M8$f~y zW^?b>p?Q(SIU&I~A*pO4jA?2pA5vXkHX5Ox_J1rl&3?fEy8H;|Q8bgT2gUqnm3C-fEfT=ejny}aRLpT`k#hdnCUy984p?6dca7ELibP^+DvNL`CwV{f zRnTM1DN|ed6`N=r+A>wXb0DAtWdb@NpXc>iuv#R5u*T}T+d3Ta=bXM^AnHJ)BNe3PF@tY<@&5R)Zsne7RG$`i95fhhfQod2#?f7zm-CkoR&2n$$JIy4$thaC3 z4+v@Iy%S<2lRxKUC-xcHIqUWwbnO)bmWiji%}lQTnFV=T+DOpz{L-%8gG4V5jk>--fEt!?_r)<%7(&IKy zDGJ0>`3`kX+K3hIHY*Xz*2QBD@E)YDd1Um!0`==5eiHWAu2^943|zt$U+u7Ab5;)_ zPFmEDAcH7`J8k~zk-BoLMT z46NUTgmC|cM?(y&6gXnq>t|}Le)bOGHe^c>fvbrF!`KXp4D#oH^fe8bRsn1i^T(}6C^?Eb4153 zazn?#ChA1A_aHG)c%d?d7qR*>bfj6Je!sE$-?i={E~jsrW!@y+(7h6`Ba0t3C7yl3 z-!-K_8_%zwGB=VAli+JoR~EK!uF+`A8+n}n9aP8pn5lhm*G(OYd(qTkxbst|NVrM7 zXKErlz<140WjlF&{(P3lKaoGY$1i=w=W;~dC6K~7<4*JE@}s*p)0$E4cAj#d;=TDX zI9-dG)(3apG#rFr-I#=B!yUuVpO&g4Qdj0_+a&Mu2v_Ds8`aFj%pYZ%EiL~W)C_iI zUTMs{LMDc`VWPIp{IO|@fTUP=0{_P}eY#IlGf7JDNs4tB4db{mrqx%<--T*u*srJS zomj{z4_13GCt>m-?=In&6{tF;fad9_C;5E^I#$PjT~Lfew4CX2IFTrsp46c>HqpoC zjod`~yOKn;n#BAnF@J#nWct`x!u-1_dL@jFGH_|ND#qokk_VbHZV5BR!S8k{c7o70!?I$H&_b@n)R zns>||!d~DH%^oiKO~-#X`$3T;2i336F+jq1bENTNdCL|*3KCiPQ=*W+Zz|_SqAT29LJ9EaV3Ki70?E8K;k^r z7+Qp<>=Riz+=;AA&KntUyG13#+4uhgzWbN-rxh_eSAZ z_Rzib+Th&1eI?7@}R*cex+Y)K3<B>912~dljJthY!~^V%Vxkq9A$%ed$Ejf zS(c8_A}@>XKt8b}d3xDck$eF=&;M8!g*QCX@&pM&)8O(9*x>H+!6P@oXjS!P;d2|a zGB{jwXb#}ydrgMVqvnbT@$}xw{G*Ws^WbHg??mwx{`PhWdu3(EWF~Rr3z%{WLFCd`QwM;21>w-5z20rqEe%-c%$cMslp@GkQAR|Gz zN_;qFuLrqnV&T8#n+l>1e4m1^lgJn4jTA%e#L|D^)2@-Uoi2&DYu2LU>w* z627pc;yBz;xi%U8H*M{-ZvNOrJ4p9quk%ONzAHIX%dc9uUh?2`d`RUmU$^PiN%b{f zw?|c`Lc)EOev6!?s&l@ozg3ctU#=`hb5p7Y_42Fh$h-+B3PG<*tFr#qZuUlda%yY1U;zvq#Di0PXj z*<%%5ufrIC+9|{0nA%X;+HRYK$zevHoiaLDCM=Fw9hp)*h<6cv=>A8OS$|%5^nJ|O zd7BS}hk?JU9#2=@=%rx4Ej(;}XiJ{N{xn=Zo5pTyF+BF2t^JX|uyvHAsD>ZFzl6fa zyjHUADPFqGhWhE-X2Mtpw~b&m{BPSTd)}TPj@&DlBg1K^UE5<(`_lHI7_PJ1WBbqA z1+$*1K3CSw6&z!mJjq=N1k|ov6G0nh+F0!G{n&eqzqU=uciNFN?6wPCL0BY_)b~s& zx|iWt&}O4m(Y^fw_Q07}>ZM|qsfJTc@=UmHrr&kj9xsOc=}-L7&94}=5`)3iCzt*e_34vJ$@Q_k zbmzO+JT&e+gpUK(?3#zQqIFjaVsq!+!;m-Zp4f?A>eg*}k$+@&Y#inNkJUJPr_PqQ zh+~C~LlXa9O)vh--Gf*m-|4AGAy0TJ4>B%4H4O6l)FdOHQInn_%5%KT$&Wc_yPc~q zLLLs>IA>4^hZE%BpbxON{~wysL-YOZHA5Ljc-|Z>Kl7QcY#+bqnKkJBx6c%^Yy6l! zaac_j>?y;x<%>P9(thTPJu&>V&-DXI<8!o0y8N7pN%s$YJ_%Cx=e#hU=IoBW>m>8- zeC&&TAW#3|2B7L+TrjZrb2N?d(#-eRUe?#SJrxLju3-Pd39dVi61uf`U1kB(pW zlFrxI{?jjQ3$$Cc@2~B4dPQt^$g5(zD_(Q;d|-udPHQ;-GIo93{;1kG7Tf6+JOG`b zz2LDDJSI-`wBnl^++~|U-bIm*o!`+(Te$W-4hs^a5)CZk=f>rtm0pJ zy&ooX%j*f)Tm1BTq_PE7#aA9cpvY{sxy@_Qba@-XfL7$}<((Xy?><;TUK#Alz2c2@ z^ZGa5V8Qz@y%8*dQMMe4;yWGOC(c+E|Ls9~KfC2n3F79>Lo*mF=BL%23+}s;5>;w}xXC*`NOQv0zXKzKiIye`I}CDBH_7p7>Z&clZ7$8utZD+~fJ|=4_JL z{5`wH+du5hQuYfU9-|?e`O!?tiGuxgAN38zi@VQ0t@XWu-hD1Z^7^FxAD%G=1KsJ| zCXjABH%_uUXMgLt6lOny4&PaH12Oo{P9m@{d6S7UP!gA^d^{dFfAU5uz||Pqnh(>S zxXp<0OYg`1o-sM!JrmCCA1#vN-;vmJZXYnwi#Gr9lI`}vQVDC!Y-_=&HHOeVY8oCi zBg-(Nd(INl|8g^=4FwqnxH04kax~N@Le5hTM-Cy-DmAOMyhW!hXGVS(nPz_;*p}E)S}>-bO{)yEvQTF88Up-cH3% z@8WccyWF+1HK^kH&6sPICqmTc98<$8Zw1MA9dpc%z<#2WYaDaPE{}BP%AIFYWvPE3 zX*wy}ZUxuG?i|^+ z`kAwj#?t0bUGI>Y-oJzLcA7hC1WIm{%Bpl| z$eA1aHuYE>Bcn`Kl}Jc@S`ov^4ue4|J1k#l`gvJj*IF(K9Wfn~t^XMz*xaP3SJ=U{xtR zwz89?Vs#9Mj+TeOc~*CF$~JWO+B=QMkSDq{%Y&{ty_G+NI$NBl#{d12Q&#cM^oo-e zAn8 zQtC^J#6-Mfz42=9!TjP9Nv>vo~gy$Bzf}%ma?hy2i}CeEB!(#HXoG6&8xi+$7oPkQ8L-Gap}P-A}yCzxR#Kep|TdBUu$W zp!ji3FCo>h3bZ_Jo^b$uQ8)%nR+0JB- z?0}w??Lo5YOEl?n>qzX6X^J2Us0+Lm=oJpp=KzI#26crWKU zbDJx#%Vm`>kqT(3p|V{ndw2^$#agVMr)_!ur;A)SHqf3gfet+1!tp9B-O03Nb0EO^0d1a&X|-$|6(KI7 zqkJo95a<5+QQF|S<@Dj$XWu2;pMe~2`4R6K&vxYS2~%U{fo6D*&6T?o+f#@xj#@#R zr=5+NI}@;2+uUk=Q0Z?^R!yhIf8yHwC$7znnVWrFf6zB5FkDb$=4rHq@5Wm20Kusbl<4uSN7aL!Vh-0TsWRy1gUeo857&lE36OvWNC3dCmo~$G3hT&+gfu@cqL< zu|JOhPwvgsUs4aYyhlgwVd@WE!TPy#X1YJ%kG9b!_}jJt*y)D<^at`?e;yJ{=O{eB z=9B%F70e+ZmifMBP2%VOOvka?e;$vM)(bytaPRfY@NV?Y<1{Ssj!}45n#Je+G7X=Q zz5I&;)#rbij%O>~)v-8OuechG{1aFE0sqcb16sUxHKFT1n6aw zm9#1Q^=GEy7hOw)EXTD9^smcr&j+^$L9_bbqWI?D`ldcJT(rh9|EEs5H`O1`al8D; z%}pRZ0;mN%%SX0P$LFc{wcn5Xh4%Gq-~PqdosupA^PZT)_sx%DF?{cvRV-=$&YN8r z%ijOO9|swfo$b9F_xHUsS<=B|_6_!*hr3Fc9jV|9V)wDFhkp-ZGAecrLGhWx4~4L3 z_E*^}4j&F>zd@exnv^MI;)kMBrTLR>jxkdA%fb&*HjV8QvO2RgR&#i5XEs72+9FCg z*A)RhN!T97h6YUC?idwebH9JMC5%l8`b$HSFLQ-#IZNwAqlgn@!69d(!GB85CLoFH zE+$L5vym+6@N3=K1t!$=WNX=FpQI1${5bDtAbk*tiV4!;n|f*Bhk?CZsbg7J%9Y!2HY;A_Qx zY?UypH%ms{y53ZGxVATYH<%3*?u%u;!+L#Ahh_-o?y%2=t+A|#Jumzgi|^{~Lf<$R z&*lnNO45ZnaX=b`>NrSD686Tie3l}3J;ZyHn=wti z$xXOdT1JcEEJ$5{EWaeU1m}|*fSx|x*@i=w48-|8M6f3VH$>%-lBj|?$0`Tl;b6|O zl8E92Jnp$G@Nr<}g7chLOQcS%8C>2oj?9a6vK)q~jQ8V{gtaNGXE+gvRbFkzlfu&} zEMfq);l+mu;UopeIqiEP-NS{LxZWgL54)Vm({{Nf6PHg9ApDf=IE zRo7>Ty1H-SVWBwJ0#%g@0S4(FZO=Z90+>&}_3@W?i zRr{!>Ioo_lN09f-pA99N!ZMf*i$6e}@iU7S_vu7RI4n?U<6x!;CN+hp2C-iDAoaB@ zBk8+icm-7#;^rrqHaWHg zyG^px#Y!(L9|nL6-o9Z6 zdK+Fv_s9ym$E~8fb_LxnWwuC;oHO{u2f7ymWWAmv6u`kLbCJGkR3>zncSXD zVj8?>Gg7=J+q09(_yP(35ONlNz_4L|8kIxkd$yt27_tHP&cPfWf;WlP^bowmpDPJ2 zxVxTftk@~Mh0`}yEc`N*-ODxz^M|onN!vsx-7MZWiT5hp#ivvMtvFiv=P%R%$vMIWGNFC3}^E~_dWoM=)=v!SqvMHMBbL!uFkxQ^JP45qo}0J z5MKr_e{DEX5W?=07sb)6^eino>#KI!bv5I>sc#~6=qJp`>kKS-sw(lt#Cuh`t+p=Jd5Q@9ofNn zvajDm2>iCkn_LT(gdr-1-&i5%P0kkY8u6Y3&jUtStzydVqs4*^cLc4<BiWl!*0b_d0-=Ri4ND2%Fo>Q{+bSEPJgWx@lQb-XwFwI~ ztZ$!e)EskW9>DXDtSSr=Di<911N%_VaACJb4BPK%Smcs+JTW?RPm_S}16hSfH5kiL z?nTdFq|PZxQrE~Z=eTBdll$?Xff#oaxkr(!D_G3rp1Jt-j_4>(aX=}c7gg{OMI{CT1D9sF-t#K^88}}9WRR6(*uN! zT9(Mp3j4Gy#y%B&bGhn>Xyq4_r5_M^p2ANJe82zkM0`Wpc5ItHpARGgIlRF$M-(V# z^TaHDn&EL%U&WvOc;ZAh`e~16vM8(-4~w4OB9^|(@$9scJq$jBY&-x3V2SLX0yeQC zSC>$N{&fR2*~FE**|QgRb>%+mu?-Z~=vc2l2558)+kDS(QVk=+>E^ej!9c9SQ4cJ&X6x*o}1{ zgrawSPl~o9HyydUVqt6=0>n41APrDv!~CdEqmu%jC2D^24;$tHe5s%CEgFq4psIU(Re{FGxzVzn7^{T- zCYId$0K%>>fFyX6TTpQ3y1mJpgt;ab$<7PqCf2_Ljntc5e~0EZ(1b?ahgMz@R+?B} z!yRFNA{03gmx4X&;di=r5JW$gay0M79xrjiCnp1p5n$kgE{Uh>^YFy2o@f)uxLqBU*RzbHY@H2 z&s%uSe%taFLHUsfl(VSnDOCB|41|2De~s$h!Y_~zRToc-N}!g;Z8_DJ2}7(b%D$n1 z4AkOjoz$TTS~b#%sAegekOi6`x&l9a?O*9-L@!+i`hWc5SIOnlP`D2{P3Eei>|imw zgt9WI<#L4{r+l#Rz7;{VRJdYgDN%Ls(K`xLcb2;$`+zVcokiQ-G)RHooJVCARkl*Y zy#fvUqDQl*>)&AE+*VH>d3|mxEtuIICcrpi??mijWnljdtD~ROmv}xnPW%@=Jw^VD z#NS)mQ9vsMG=2vGtAukE%Vx@v&;?_axNfvd(E+WkHQVewu*(8q)0{^t6 z2Q1YFO^<#HO*fOMtv*p=H)&NXh6I`>g(NA!vH>iQg2g%R9*RTN#C@8$r*_~DC=}*- z?)475_$>8B=syw4Q~@Z7|FB|Z_;}x z&zUE@-Zu|WF7-#RcYlK=3vgotmd{{2M`7L>S4z11uO*&0l2GCu3+3z zzXVx;3PnU z21)?W1L&$kBPD=*fEADg=my{bSJB?LfU|%TfJ1iN_5pSSHUl08tN|A?(Ovn()U^Lr8jNJ$v}`EVfEw|4!uQN`bDK z$K>_vIC;$joV*rL4@g*v79gw^X&WF3`M!Yq)ttO#4QT9~+*ZNKD*!9N|BGK=io ztbjZ-=yiaM`=IsxK6#}`2Loph2y6kOW*H}s0UJp z0y^S4=55{Z-U84HkW(6t!|a9ZKhpmvc{R7-Kesr$yrL76Z|)4OVwwEMx8LIqEPych z;O5~>UIWNTMK1xT7lB3v9LB5`5WuIP@%o#bXug0MDJ=&6KQ(@*L-5Qy1>~d9NHoS7 zP}3U%dLTu^f1>$|#X8mn8nktXl>n^(Ii+&^s2*|((Sdq&rUf8&z>Z84dR$LE8;YI* z0zF%Tu`Y#~_I5CDpn;B!{<}QR-{l;JrVx;Ud@F`@TL(D-p8wGNvvn*DJbp(Gzs{70`Z9(kX-xg|)WfTMhh@cJ~? zJ46apw(xX5>mA;XnkGMG3ZVuL3iA^a1D*Yh?og)Kx&dWUC0JBpC}~8bbkRAG<}c(| zQNI~DQ4b+;8ta*s0`8kYp9i`P)Az3`i?VRTAto1w;SZ?4X`3)-66-bS$X}W$>YxJg zrfg?&>SM4lsQ}&G2l9&o-WEg^bYKhtp&3NB4me__K12ckzf+9pHlY)wh#V^fC%itH zMFd0DHfnNU^pwY#d=(sx2I|&>fHQ!8BN(>?kTjBU zTL9kxqDC<;8}JYyax^{y0n`H80P`~$ho1#<;{iJXO@KDQ$T5uD3iuunl?{HtD}b*7 z{l}sVSTUBBa5c!(1Fi!U;qf}3>uFO8DKBK4M@phTmj$}Kr0|77lHsQ0AB)B z6Ygw10`}||!bj7{LRVX`m|GS7q~8E%sND^RE)Cl571{bx5g+V@OHp zDL*N>Y`sVt$Bpnc5QdaUdn2WWNZL&zNl5WijQ3OI`_p-TJW3%@uOe% zlN~}zZ8spLcAJrs@X!3^fBMt!kiWT7*qwdh27E#?xfg*7vf)thtKh0(Rr`7^Z((90t5|5YS9M#z|l{sRqaF592l{AmGF5?|;~??y`OWSbTryKOcL zj;!(1@9j_@Ec{dm-)r?(x&2k7l|ii1CS>|rO+`wb()rU7NU7Bvq|~WtNU7DX$Zsar z7$Ij4lNN3U9w_cfq{RO`Qqt^ofB6VfGMXDH#ob^0xz-3T*My6K+)pL6PZz zcFkw%gk}^oPz+r6Eb+Mu8G^g-jxq`IF}_BJA|-w!Qqr0T%|61%pj*73Y_*@v;U}X$ ztmq&wrPfdQp`Y+`fBH{91GRCa1A|CC-JE1U>Fg zpYfBDHx!imthPbOEn)+QwxEjaLsuZBQ9KL059?dlNL;P(bP<-AdPv9!)FGX*iThJ| zipyt95_eTpEK)w!CoKwTV9Zm55ery+ct!`*6cN>{)Q_T`Row5>ujYPX_k7k**s*{m zjBNrkpa2a7DR&mQi~thp$(lcFwHakAPJe5#^f7?&P!NK z<{&eZn*qe$@&I=F0A#r~-j@cPfi@Xe@Q6!wKl{_;e%dhM^(CxlbgLh&z_UJ)6|V4+ zZxX9JXZX>0tO2#X_9`d#ZZxP;0D*=r{=X^e#$OGkzR^lUumj~fz*#^A{uF6xAHYC- zvWPQ>Qa}d&Y(py`V+hCn2AZG;87Bk80EPn606BnJ0Qj>o{vPJYZ4wJ8svZ zI-E&;fqcPa>`EUZCf`+ngEiYE922g*gUiR+X10)cFYEpPAD8}r`?z$@|GUSf!Xu^Z z5t&UgWWQIhX$_ZG$ zqd;#!iloEko1?aWgQtK}{BQ7K2)q@j6BL_Rgnct|H8nUCCUyK*-5$o_?D+N-5kzM# z`CJ}17xzs3m_Lsj%T44apgb1$Ead5WC-}!(fjy3o-KSl;SWD}e`2DTFBqnyQ40@K3|dN1o%XoD969KyweyndgE2L8vni zr3Iq&EaaC#azJ7p@bl2lUE*Oco^v>R9|#Ckk4E(}RFWd4U|S5qI6lRt=2YBJG`bkr z1knFyvBU5emY3ikmU~3aJF@d3dnu&fk*VZ{aSA)#07@`q;c%FVy)F}p??p39I`rqi zYnJ22iE?rvW05F<>{ANMP`4JL=VfRsfV1C0Cg67`qqsrnp9(4|IsBCVLEe3^RJk4IF6+?8|Cy;ZqN#5S6=nX_;G(%ZSbH=&hqpiZ z=)uz4{kh|ESj*w995)5Ev@0j32YyN56{}fo};&Pd+k_pX)ZBEcSWK?rx>Yt zPH|rGjbg3xY2~ZR?y7OB`&C<1yH#D(aq2Mlhvu^85$*HZliJJLAv%L@v~Gs3M%Sk6s*liT=x6GS z^bhJc=pWM;8crMjY1n2wZv4nNJMF==4QY?rp;?G&tf|0MWZGvMYc4PsnO`$sGOxDq zmNzZmS}t4uuq0c@TJx<-tshyxwf<^-EPZb}&0@qfZn$E+=3&haO_Wxty`=qJ8=>2- zo2swXM;fLX+6@0RhNm4h1)G1i^tSf3hEh1mz-}1H?~0+yvC8erD3yJs>M_+`Rk}J$ zov#+uJv1uKE1I6#0_`8VJiVZQ+;GDXW?X1|(WpzyOk0?Cf7*_;XVWC66Q)m1*G$Yj z)T}aZHfLF8LD63=%-Y|owx(H2tkbA58@T~~-lq7Q;v>b6ieD9p%7MzM%9+YX(ey24 zw)REsVY{|g|EB&6eXIVeUT%2DkYPM#l%{2+6{OXsjWe29+gX*``KdZZF zhH7SNc5C*)XFk*rItfN>h5n{K*HCJF$Jl1P zW?YqaAT7?6g+a2KubA`ETi$Zb(#e`)9d6ZHCs~WEE39j*pJRB`>90`FOR?=k@=wK2 ziZQAP^?Y@+`i$l~ja1uBJ48EDo3EX(E!CF8W6=Mz+OM=XwLNqLbSkKjse4FwLU%#; zEu1G+zevAQZ-+m>q<>5QzW%KKTm5vy62o~zU*q$}ea62TFBw;)T~CvmdYSB|M@+{} zE_0JP$uiFJsO5FbVaq_P*(z9N>4Va(=^N62AjK-MY9Z;QNKuq1wkuv&*xy&2QGBP6 zD!VC%C`T&umGhOQ%5vq)%8MAGPO1piXjPf&5tX2NR&`nxtnRBGsMe@Ypg-TLuc*J& zBx%*!+1fX>b=oHFDeXet65YePO}ct?;qUs-^*kovPsU~N^vbkn(hj9HrKwFu)7>V8 zIp6%MS#2F@z1MC%XgzMdWX(;_OJAM7HJyUN3TP-*OjgcQKB-Jm4O7il{jN$-576i| zqqOU_SGBWsufsl9b$#@D{doO7`fB|y{dK+6(96IZS`B%|>Bc2Sb=t_ZscEHYk74c? znj+1Km{kYOxt2W3Ay4X?FBuOT zPZ&efqR{-Mv}jX0hNsH(jOjJgyO=dnbFyWjWrgJ%%jecf_H?dRoGIJ}#Ra+@7vHp4eNyM{M;{$2EOev;?<`w2G=3VAJ=6&Xm%x&gB%%PU9mUxTK z^0mcd5y!Y5uO`r+{ff=X-J1+n zJ~Lb}TrylW+%j}A%8Zf5;YO`7+ql43W_-dp+PcJgKjwzr`mlA2^^o<5^$TmO_4D+9 zq;qYeFLG1tidl*x_+qKTuBcW#s(4)SyyB4Jh~jfBrM;BN$|~hXC9mA2Jg4lY>ZyuW z8PyM{*Q;G>9wGR+`j%R%3D@-2^w(%KR?R3)uEwExThpNVO4Drq)O^$2Y;jv|SR$5-thi6%Q0zlrLzQx+S$UUoy|P5LLbXG+PjyJuTV11W z$8y7If;DqAEg1K5?R(l7on3cMcM-!9VMsMN4UZZ38goo_rU-MMnfEsuXU$13PG6b6 ziyFhjZV{4Zg6Xc09%G(tF0d3?)?2n%zOwYO4zg;j+38c#A4p%DehP~gzQ4f!wu>TKk))WeT&;Xt zdETxJRrOF=RpV6)RZFqXzpOfe$bC!IRXsqhQqNJ}tzM_zin0Eu+O7UUeN}x!-Br^| z6QfDc=rviI9L-!!nZ}Mq_%+R&nyZ={nozA=8>#K1RcOr!On1YsPiYTo-$rmct^GlJ zLmQ+E*Y(uJ=*H{vbOpNEI{SQGvF-`oTe=T*pXko&uIPT!{hzQv=Q|C142KLqz}IgWIAf?W%-GY|$CzkLfzRuV7GtI{*ErQU&sbu-&sc7>8)^IT zqVY}RQR64Z5ox=zZoY&?ts(8Jv_Ym}CaY<*>3P%3cGEkibEY3nznW^yZ<`x2!vDY$ z6JzObQCPGVn`Nq{)Uw?2kY$7A5z98q6P6mw^Oi=-=a#FM5NkJUgtd<~!8*V?#Hz9y ztXAu2>o}_odxcrnN37edyR0u;k6J&p-n7n3FG*jTzA61>Y;jJ)TfR@fkxu{LNe#{a zU@WA&6+grOHA<&)l&Tg(5Ukc?;e0}^(QMT;Yr?c^wJEwngx!l+9aHpLy;VO2Yh<EM-mu89!LZ%1+wh)2f+#SY;B-@76dFHQR(t*a^7WHPNZy@f5w zXmgqQ1@n96n=12A%M8m#%a4}P*2&O(zI7pXI?JtVtxl_WsDbCJBCO|2RHaymDll<2 z9G2~1^MYo!DW$3~m0T62Qm8a4gUXDhDqCd}X+fphjBQPws!4Sgo3^XyP=q>49ji{j z@?}t))fw0sWUF)3h3MuIb(MM>d~C0JA7Vfk#Np{TMZiq4_7>5{hj8lw-#tP#G z<7VRyPFokzwylc~1($1!} zrn%GF(%RF4O-ZI9CXFe>RA{O&ZNhf1&UDt~HielZ%(3Pq^ANMfY=&iW%u~#T<_f!c z1GZK>%r)k{*ae+7pEtYBQj6RYYcX3!TXHN@unj4KcWkrlv^;CsXE}g%?YO1ca@um< za?#Reky~T2{*SiiSf^MEtrgZy@Q5bsS?fh>aC%sJM0!GcMtXL-Eqzw{s`M)O#;kmGt&>t`y%-g<-BnDH5<%P$&$|H(q#aTr=0(2Pm3bzCyhNv30MyR((W$9+O+D ziO|Gq%$m`d)Ww<=nku_y6PDWpnj@OC8aL*4gfQ?xZ`wGF#% Y4K@KQu+=|~z#-Qw^f*3!iv9k-0Fq(c$N&HU delta 26032 zcmeIadt8)N_cwg)VZ>2EMg>I$85I=8!<^3tR6snS;|V;A<$+L(6befn6s8!*N$j#N zGb=6Yrm~{cq%y-ap(4XOGc&uxqMAwWZYnb>bKdW|W>D(Bf4}GXz3=D!>v_h{y7t~{ zueJ8tYp=cbzV@}TtRb?jF0#rhY3Fv>C%9aNQ&fYb@f~2D`f0ol<(H0~h*u)DPW>!i zEv7B;HZlD=UW>H#(uZQI8q_7;gYwjsm*Nd#dOpneg_urVc|lBP-gavNwZVmd&PMR8m@6O~w441Ta=VwZW>6_62 z$>1bNw^8BdFCFcVS-X7o9k+6#Xbw$qy;1+b!51Yn*$$;_d_mhZCinl8%(!_c8u2S= zrt()e%S}}N=tg;tx3w@>aA+!%FWW~AIcM-cZ0+MJ)CS{{XEM3Bz5Jxqv$3r{^BUE< zgT=iIIq!$TxYaVEcSlA=tMyR z)xL(>kg>>Mjg7U8<7Y`#lH}3+ebOXmt~yJkuPgZRT;ogj;p$m@4tfXMu|lnb$kn6L6( zqo|QvqE4~d{D|mD@gw_pZUj{2E$tZQ@%+~4WR}do6#W3m?L8;rd0$Tj+s6N`=R=Y< zJ8zHiGbuk@K9p_Yr^p|PXb*DyxAKt#9{ri)X5{*^<^D^}9Ov^b`!yImh2ix}__SW5 zSR6mM*C2Kue|N7rk}s3^)4isT-hQQn#Bp^J$6>T(H1<9P$58V zxnDW1yj4b8`F#FAg26)0AITW!bMJy@0xfZ(RkQ&|2;oqU3YDD&MYEXP=T3zK7c{^> zP{oN=GM`WRdobv~mcxJ9=Kvbr9y@~_C3}osQKHqsF^SAxMzu0#S zgnr(43fsw#=;w$&1WR4+UdTl>1mn{Al73@Z9shK{T$ajT>o-{P)`xsjJfWt?_r-HX zd~#GB7%&~W=LX{x{KN6K{w6pSY=V9S648^zg9b{vOyKVwWK)aLtBs;padNC@VRAZ5 zlAPz8nw;SG*f{P~MshlPgW{9Zdm7cT{t5hdg9c)FB9n$lio5b7lW6KsPI4rFWEF|( zGm^C+=lox3;AtC@6J*}Dwb8-iWYIBe6bi|Qk^F~A_YjxD!9L=*DpDX06$2Z)ggiRx z=Cqvw&(8DOwESg7byv|FPD+KC-k3@+4elPA3vW${=RY3YE3#-60-%X+9bAanoi}8* zn3_7W*RbpG zOfl+&LWYjNKlM4(sYet-!eb+HdP_xrkJVg_Ig(N0#{{^-UmFq6uJCaq@9AnomnjB4 zJn}7w&rN#^o$Nbm90bfAMGgKi>L9D+pB`-k=Bv>oF?v169AcgjEjjN^)bjW02Qr=)^wo)E!D4wq-E743UMZqHcDZLk1C<%S&`_WFEU<{G z6)(Vr3MBiwI6)ZxKhII=lfc2l?=Vi-)pI7-|-Wy zx#-PqYd)0v-MR|-mA3K7KWEDwxW^w-P|4MEP%Y@qxwd4n=7R2D>?d zH1uwa^5)3uGk1|6<<0QsRQWOwIsJQipS=Vo*^$1IFLaEP{O}F`f}_7gp2;^jOk$`A zFUq zWW{>35xeI4i`ZQ zkGmMpyZguF)vbu>gGdh2hxX7@%wO)|^EH6jU(p-{Z7C{zZsK!>1kUjJNHfnv8-S~K zm+@mKq`JbB&3l--;=P{sCUx$3Fv4<}dQ{RIOoZ|K?t)20B1De<^^w$nubY_a)1_h| zBtbMz`6-!4Ec$ZWeNpX}_lo6~bHz~z@wxu9<%kz2qr5)qqh|h9uR8%5bSanmRE@l6 zoXoe0c|}ur#zlGE>4bFG;^}o~i20*<`rNU2ItyeREo;rllYkn+6)Jr0YF?Q!gvIi+ zGIY~Os@L6uXCdctA3*x=%poS?4q2<ALYn&|e=(zfe-0~E zuFpsQ;_rn;-0LQLrMYE%&&>XPs5UQbxi7L&>l?+JGY3bDTz(ZIuJ`aLz94h7D?~Xh z!N1cXuGl``eiHc&m_qA!1lB6ToCSuQi#iSGl6LMmtan5G4lDlWZp2hP6+z096rZp8 zk60v!{U}5n_nx*i#FT4M%`3CiES|qLYly1}O?!N2@x0-7@u2oTM1$saQ~rkA1ul}? zod>PYO?-cKyNkfpyPNSOe+d>TX85ub{9oBgA998~Z?+;WJE8XZ=bjt+OF-|E;;HCNMc8Zx;k9#&U*r|Zq=^sFb4ox7@WR~MG?rr3zU11-OsFHW0 z)Z?b!c(E-a9cTO$;}TW&h;A4xk~;m8&ER>c6}7Lq5M8^by@!4OuPkQE1UP!gT|;9s z-Xl_ZN~I*%=ylUTc{yi!oy_TTSE1napIc2lln>4ApJMJ1wGT|eYFqy1d1wxo%qK?D zZ5cA1ERFX6qp3H4My4(Ru}|c^X=(}wo`+WB87zv0f#v>>&Co!cZF$~tv1#M5;UO10 z-Y(7dxXX|eElSbCn+1zfaPYYmqD9|xWs&w&@QO_TZ%z7&3vwQ+hUnM+WYM3n{B&59 zl!8Tx=!Qi{xCwj1q?IT*{r9aRCdzw6)ySl!{D?_OH-cHny(_v&nt!q zj~HS8KgNO>_aafCsGAaTI@C;s>m7_K7A4;%O#YAw!;`lVZ_yog^h5Fgp&e-eMAw|T ziR>u4=AZ1yqhYVxMRfl=t{Jl9u);sv(N`+><;s1_k~!~08R8R!&Gbd3V`&U#G|>A1 z5YBLic4rVTVZ7p8^O6xVRYpU7xgAsJOvEH}Q zP}=cRV&}QwVOp<6IZKPk1~epMc=X<-@SghRz>j;+-Z+p)<{R8i$wN{Sh zBBK1wHgt_E*76GzCxs8u05O!$2OS<<|K1_V1F@F?V-;)!+Kn9D64N|6~K`}3m*?+s03!kNwzj>0R7xxRT z_8me_@-fo}O17NmM@<_reni%d4d&)n+7IpHs+e5!jwiEqR&Jitmw9E`Q)DCWagSS0 zv13t`w?yXMDEAzep;+&(t{^LD!+zZ7+a^}+!IOAbc-(~W*Nnmtg|?#D zbN~}`BwgynK5aJDeu)#E5GPrDhPTP*JBpW9fA^)lbo%gFlqYw8ZXzS~>fMdVg>^d0Z<=mmPxH0YQ}7PB@;Lc_KL&Wir&?`uiZ2u zA^crOio+@cAu-j3nd;p~kpq&({{XUuh{0~+z%X{hFcQxHTq;?Z8oD`*6RB7GfueCF zh8ttjq0ql60k`UomVDD>G}mCMNH6x$(K842rB1S<6C^|3}Xx{zLt^0_}8=7XB*GM;XuQ2Gz;%CiD!n^Fc zSwq<>UYNBcj!uf;YcgLJwr{=+v=xl2<9p0b!bwuv>;ZUY%^rr{NB_4fABH6 z16c!~mOB8?tlS~pY2BECWy7Dwugy)<6R9urtaC>2u2^4Yi<4?rVdhV;ERvPH12v_- z%+~tMRx&ZPjS{tO;6KV$c1TL_EBWX=gCiuVkt8WXk`nyIV>oW2Wn*i}F{p-y!+QGO zOn{scsU~cH2aS3=8xv-*&+U?yaJq%Eu5Rk%K3ZdCU>e$7#v~? z##NI3zGP9YlVW~@n6Kf#oI5FjF#qZN3#YPve&W2j>~ntayz%TF{;PSzy3SI-bE4aM z`Ftf#8ph3c;JJDJ2=;gW`T2P`l8IPQg0qM93vwjiyvH{z(Bkai&P9XxfeY0@Pg^*d zweXKD9L0|CrxuQtbT#n5EL<;=OhxsvMMg;YWsw`lWg8cd?dHrwFw)c6>Yyb9_zxFn zb^A8=CMH!PpU7t~$zr$j+m{UQojVJPp%zZl6v3w zpX9sck4`v+FDRmP@pLH)JAUu!w64e7Bc1-=`I-5tERw%Be;~`{h5WJXDqo*ZM`mY! zOyZ-K_8asXriZtuH&ce~!>k#ejWS=R%xl81-Yw1ZkK)HI9f)(+MN5<7eermF799}nTzU(;h5u!#J<*EsM4-JpKD?0RdOxhsY{MoJ-y5|2%v*-BQT+N_ zCb9SU6SoY74&UA~6(?HSTi4@w`Ndn8#K**;iD^;Z^WJWroNM$QByYwn|3e?}Da+oJ zhmRD>r&$@kK*VJn{BhYFI{nIC(THc<${ajzU3nYMmOfb7jj>nwPYMjo%E#Q6$ZGk~ zw~ZJ)3fdtsNW7=(Bf%;^l{J++m6ZwII{fhN+r~g7&v*FuRmTN;6nIEVNRg$CWE!7#$zvo-JfmPjk=VlqAr#?cJXyo-o~6SK@uebc3< zCOWxO6DM_2$X_@V6C-NX%%P7%a_}yk7>e_XHbMWc{^nKv)HFesES`75JI+a;Xu!~h zW;&N!#qy0)VI%+Es_n5C!B)O0ohwN~BQeKLfG?I`vwAQ)&2L|w!_M-buO7$zeA1ds zJeRMT2%mUiO+3y)POYJ@1eezgk~~$*_qcscf?RY$89pnO^ueaoH!Z^?EACalDeZF_my*SW&pvcUW{JTXnyKhE( z4U?tZNzOav&Owq1hxt`^CgXEP)t$qkPVJpJ>=!9gcMzY)~nys0) zt(^}K@vIxcZ(rGqe{f|#{?oO31RVLg{+(E+cV=;{n>RYjKn63zYBk)Zxz&8gdbv0AQio4?@kd}|T zYe-Kwh(aiw5Ni3%yV4c+Um-pmtc#y3rsw}hzDy8x;`G*&cF^R9;v>C$9E)|?%wd*8&QB{@#C(J9$>luzvw6XNRTEibLJ0`jM z62D>d{gOxa^If)#3H6&km$YXj*=$E$?pt;%QBl?Eb z^<-Xy7j;3eE_Wl#@#R>h4tA@U#6r^PQ?ff45^;;$1QC1O4?@J)`^G@y#rHi1%(eS4 zZ4M5;zYAj%4i2wOpzj44p2voLb_N@ujaTF`TQ0(rgC)%{TF6M=Q}~vf)2{izFYMvF zZk;&f_Au$%b^n=c%pSgI>o|<*D_e*5u74E65Lz)pK97$oTQ&FwI?$WYmtwCEXH=VT zQa%dq=*d#jmLSKgz{j`Sz5V)!XIQuJ1iRd$V|MY6dl#@>{BPbz5GHnRn~KPEXhs+M2l8^WUbD&JFf(f2xy0jRw(STfU&mp8XNXJB?1(PwWA9VQd@ zczc8=Q-(M6?xGLf`9KPrzzYw&ixpz&_CwJ!@K@B~rK=}>2pm#{BNP7Bs#%gJ_QL10 zY3z0sz-8auf$!h^r5zI_6;JTP9()dkGY{${Pd?7ecqi)T@e5$A!~8h@+`}q<_|92< zZp;x+PAjI#SQ>2K&IGoPe{Sb!4A}Xd2}3vRfnm?NKP&F(lMZywoZ){82q<2@DVBE9 zwBb0|@1eICzCL~O@P;urT&NYXkpxoTGiB&rx@UQtlh#K6Lzl2M&TOr%*w1eksGXOD z1jW;jpqA~SoCqv4?sn1NIIlJp`TO?aH@d?!fAkR=;2~=J6^5I>drfG~1WudqE;z2m; z#T5Xb&x)r%@KP}NQ%o;+GQZ|YJ-_8yeWC z+#Q=^e-$!(}r1tgrLh;3819)fcF|fwGHWsVMLC5PSq@eD&3o+o}__rz|F;?~O zoROR_Jh=PR0jWebmCt@Zn`FNKPd12mHTGlK2ZhEHG(-zdFOYnbcd+*Kph#BAe{!}a z^ws(C3+a+G&VwI(Y?1=q^};rg?z}Kra%{@M<_oDTzZM<7x$1Vr;G0{Cj)f_hLX;gP zahb}+OM~}^VB9Eh)kiktN)JXOv|I03#?DXW{X>Sje)Rt8%c-u<+)snxpM`Uc+&mF+ zO+>84c@v8M-%#PL|MRt;oHi^4XXyJ>r%N`X8VK;-ISR~i98h^T#(KJXGvhrHZ>HST zHKqdV0A3*yOp=(2Dh}i2P1@R{?ANk&-D6%o?wi6qF_-6-{aP2Z)Fz*CmT< ziBFVtV~|7(#dms+F z*Id24$a~(#;b3Q7^zqA)qK(Slue&@EUjdnjixQPCd%yXz1~`R?>n*BX_I}&tBo~mJ zl$hg>VW_#X_uDV`IDUE1u`Xians<(@%uE)OFz*>MeLu??@0{2TW-?h!W&dDTZxY5p z;fuN};@$EMKj&!ep(U5&#=E*$*ovlKDt zPJLDao_O1fqEoOeBc0dOXNfmWR(P_KY2_=_B9~s7HU8$EJeg->E2<*?s|$H~cnJe% zy#FhVviH=VrwAqnpZ|F*CU(i^w3B=E^QkUe5uCx^^tV_Z(jlRDstblP_jCdEi~0(K=Aszz!^J*ksjiPHxv%| z9XrxO`;y+YVZz#;@00eQL18-KCH}`RN3r>Q(pPmIm9si36JO+i_$mo6alKk5jB7;T zp5wFK%_8t#2(WzkWUD{$a?QqDuVhrq0au z<(&0Tdzrue8|yr%5ZD4vygQsM-{_}fJWokW%!JIdr#SBN8ESsd+IayC@}Gz{&ABL!_Z!gdkw|l&Me#h#ImhEb6bd|Cs@2NV?=%C zSu}&YPfgemw|FM-tNn?Xvs?WM{l2A(1el+=Rz|a`V|C?^f`aES_)W}vFgEa61bdcm zYfWMs56b^}UqpgrJh*bMrTvt4xalo)?PQeZ1E16YH}!wUztToKx^r#AST+Ag+aJjP z{=+CKoeJ={ju!JvmXz)#7l*E6D)^Z{(ut${$0;~WJoBR#&&Z#~_M}UDdC<_0KPge&_|rVLhaYxj65fuAuJlKK>y;tEzi`Ef7QeZo=ur&=R@ANk+8bTX z_xd>vSliE}&9a|=WaIg~tAinH{navb@VBeaNM%xJR`W|dfAp6@X|IeG?QtS}S10G1 z=7Yul$HK^}^AXsN0O|mT_%7}9*j|1~`<-~6X}_OUADs8ASJM4vu;Rzep$m0guT?O` z!EM*NGuCiW_~S5xvN^$3c)k`~z!Zn$*w@%h9r>Lx7gFKg2zCd1^2p@~7DL6~r6|5~ zWK|c|pZ!&K`;oszvR@!ictXaMG2%_fIkMcDPR~S{{|(_EGM2}x1${SWW_ym@*^P~p zh_;9q-tWO)1D89BjqWgYyJteI)Bov_x+pd~;x7$J7EKe3a%S#IqliOMVZEGXfd81B zO+ymhOH3B_V&j?O$P>NTC5A2g(tBeCcOSNaeI`g^Sp~}#?vG`InN)Z-mL-C#K9-G1 z6vug%6Kj*dG7+ZFO2^rj_x)4SuAKjUp?4fBM&Iv`V^YRag>8M=XfVFsmn~*Hh5r56 z5LPN!`>_<%-O`Whj#Twy$E0kKFg=0wi;Db|j&cyG{nyS5YZKTq_OS3t0vpEe5UwY% zBsN{Zjn5=DRY%bb22UF;cG?>zW zX%b91iD$XZk41tjj?mPd$Ssr>;WRvW|~wd>U|W?+=4R1wP4(8 zQue>lRa2KP>gvCaZBfA*8&uto2wE>q-YwWhFhy*UATDYT#9?8|e&am#vq-pe1REo{ zxLepag2fhy`o>X*=&urBftZTj)GoA#)}e~?o{}ifB3b!mspTJQ7n&@^KjRRNdS!|z z{w}BqQRR8@0!Tg)R70H!Gm91v=|oC+Y*49iBvVRBO~EyS^>syP zu4b8l$F4)Nq_|sQlD|}n6;oGGi9s$X#iPCp)uMNte>==OZyrt}_<~}pUWkXkn2;nI z?P7GLn!5WV%5BXka>WS+l={md5^TlM!4fen2jd7G>{28M8l3SV$P}c(L5qZ{G&VC~ z@~5~{0!y`&2U*D&h#U#FS+pZmekxo~V~-Ei!Ul!xshuSI0%TL&d8FmGox+h(%-|~B zh2BON(=)D!o{6jJsVktTZ5f^`w#8M6NpyvnB<71rmxW@IGFMDS&qlImdzVTi-c0VP z4Pq*NsthT<1ULOv2k^*vf>x z8Vm&8eDJTtx>$ZPe$k0wO0mdNBxH_dOC#l_pfDXdFqREu!xS)`H?v)nc?E~1*v+G; zqD*QigAbfeydDexRI&+zQ^gWZxp~K~6fpT)^uY0AB!*EEY$`t`wfwU7hb4h$rhg(;!_#I!1aPD8NwnpQ}s$03sdn#)GAMD z+ATbxWiBxTayL(Q`-A%W_-!@%TW_NI|7# zv8-Ll(y~DV;!$(Ln|Y|b8E>;ukWjw-&>z^727|NL>;R!8^Tiq~%1e_%SZ+2vr z0ZAIxqnwt&ZzO(pvdlL=$~(DH)8K#PM<6C&LvA~AwfVO(d0+|t{zP;auQ;L<(ea%t zr?vdJJn+aU5|3;`;DJ$sLdRnD`-vwp#Dm)_I13A;{DUsGZJ_LAF-w1P6L@Jjlo0>= zCa{0FP^iO_+$?OsO9t35>ep=%F>^}1Y94H6#5I6z?H8l+m2my;92~gi_a&A zHw4Cr0>$i5F-!Lk0=3jv@efx5e~4`K$0-4|D6E-;{UT!NT0~%jgY01p8D#4rC;&@j z|IlF*J94$Dh3H>TP?Jr3IaPsD*wvS_KcGkz7VBBx0WxTG0$ct-kd(lP{351D1OE~p z&|_V%5nk4_IPnfW?3meD-po2iu<<(4?-?$93Buk|{H;VF2P%pUoedNW7y265;Fxs6 z4*(v=MuF1rge(Ia6t|6#|NJdP>?*A^IjR0&7@^vCxOW=*+LLVa=Z1YotiQxv(eWO@^HlPfr zsbYFGprF*Zj6~@^BT;7q(Zhs0A!1*s2uadm|g<@)KWX2cO8?7`omSp!1K=&F#QFVzvP{#{!NN!qR24z@ab6b?6dY z;8`&%5)1-C$3)mV6_ptG?%#KeJBM6t!WuN%)DC4`A$7$IUV*Q1Ng{N4D{w)~(w(co zhhnyoeCni_6cUFHeAC}QbePT(mqyPvX^A^}}_3DD(>&@HdPmYWh*(t?&0 zp0QhNKnO)|{U<5fj@&%tYKw#sW(0_LE`hXzG8^Vc{a~tZ6PB7;-|0Gdr8lR6rtZj& zY-(Wax1?eejg~g4lTBnH0ZsV4S(|V>EV1{O@UUSHz?X&!r_g9pK2@y=RdqBz*^ic8 z#JEj}u&|VVH3++*0HO${G@^jl-e5|l;IObb)*{TYu%Vr3WWki9H)*zmCQ@++T6sa3 zZ()OsH--I)P~<>dk_IA_H@hLKvgI;VS@^J3jHPi_HY8>*$s2GL28VMtD1Q7wXVJbi+9^X91b>&2z#f$W5{qp|R;$w?r>O z@C?XuXe6Ml45Ka#wqX}~o`@1eB418aAiLq_SWdnIa}K9AqJ#xD)?czKNw~|#23w7H zg6DO7N4{bB7Epc|0Oc~OdID9UHaj9d)xSjbZNf*85MQaFHKn7LhV3q@-5^BSS-h)Y z9vP@9P&czv6SQbJh^TrknuzIWg6NE4`l`Ru#}K`I9q7NnC+_fM(qcLXzCKIls-SH5 zk14yFvR}XveZI((ls_vxYZu?P8tp7Kz7jPz6{hao<%jH}LX?B`ceT(Ub@b*UDzm84 zPYw6&Xjp8$u`zJ@9auQ0IWQCwk5aSU^YlECvKe@o!2LB!ue z{Qb^TzC%DW+OPi>0xEPeaLSZh2n5}n#`RBGj4TLvm zny7~EAva(= zC7O8i@m(b5y^xVNA8(}6(S%?sHNN>cT_+5@NR^#U{do(drr!;zFZ@fGGM?#%h5qUs z-`acq+d=S&*Y;!68h8yW9)DbN!L@S(+)=;= zfEjRgE8|`T6ahv8nmtewkPA=%nkyN17r+X*azEo<2NVO$04d<~eT=IFWB{bNXEF$2 z1gr*Z0~`P}0>0erV%&f&U04bn-6XX5?I0o1Yco?t^umw;GxE*i{U@jmVU8m<^Z=7!TM3zqk)j1b7BOzmdRq{LH=Z%7lM%fC8YT zQs|e+4bm}rycU-Y>^KGJ^rQdKLfDnXw9&8PwUsL94Y}dSr&(-+#N`i3C<1!#QXG?( zbMmTEPQDjV1CZa#$(<0m7ilvf19>~3W)mlGa&hvyGSqM815zs9Rllss4C{z0MddlHh_ZCXeK|p0_N-_qjUbhl2>ybesP_1$*a0Tvu+rZ1SbF28*g!kmNR)ee6VIL zdIZQ%!v`6_*_CKe4IIX-3DAL0MdMA^IMI9^W~8(L`2VW$n+n1^Zx%3D;-N@?^afDV z4+45aIW*jv=D*8#G??EDRsysE6qL&GH|UU4h7L5NGi?B|11@A5(Bo$6*=Y0x(9yHi z80#{ask)PSI~w@!lo0Ep&=Cwx5x|Lj8-{gfCpjJb|LgIOfgosK1lWsw5g`A6V3Cf7 zIu8vEcXL-J-~C8`;jL-xaDV(=7&miP#;n^O{^_=RTPJ1zt?9upO0M1UC_Cbt&K5)_ zCOm{5z}rD4{^(nO3p_b>Cvd{j8LUs2MikErKg?nMx>=Fk38)cz<+7x~MaXWrC5%Fz zB+N#d0UYIPg&n!9U$l%k!qvM7HN2Y<6x6honuw)2PW1GnW2mAqKb0x^?&?&gGpKx& z_X5PWgu!{N&yZcv_gc6OV#CQO7ll#oQ03ZAVcLAwFSU~-l03B&3$anRslP?SjJd2| zm!lwe3Nz3NSNmT$FA`@M*N8L$@K;-qMEa4=@u2_jXo&6_TKAJoED%(tUl2be!do+0 zq!b-$Ce4QT&v+Qk!RtgCJg76(oblbiv!w=!lk)522B=GUD`1vYQ^3O z%6V)ds|w}!&tnPTIzEr}!MBr-=dmUINsBTHis2uPj354~5H7)z!m|00T_u#vXK6UN z**Bl{8J!HJNPY(gr5Ay_0fLhdG{FTkg(Lm~YaE@1LF zs%z@hRg!c_*t~$H#braq_`g&&3&$7WM5ao(w1ACunJkQ(m5yZ}a1}6q9QG7|jPZ^%VZt2=HL;3&WkkWa)u1n>$VIvf0e0>B4=h)Il_ z04MAR1SkVE0{Ty3+$2CHpaCG8icJlm6oCI2iaQU$)fO%v@F<`G z&<%aiIqAKaYr{2Bg#wNs|gMFJ?(2@bV!J@TxG$UEy?d7*FJM z^y?(@fx@<>Ot!o(T=#yM_8d~u;1W`5y%i}n@k_WY86Uz&Bc`rAVo>Wk{*1N5bWONU5o3krFF4pDK)7!jcl3fkKIEMM_hV zQX(NS%R~~U6qYVwim0*NjfxtvB07Jg0fMni5V&BkeE%MmwJ+>GFXBC07tmi^6FsQW9MjPQ6Hp zm5g&dRqL!c~Z*eVfB5s;;>`L|%8h zfIn#&BGlf(D!r)usU&@K0=5mmd=y^yo>PO%#K=dc_I!e@2a#Bb?Bhrq6Ro;2C1M>V%6$?96#8rhWNQFvNkmzb* z&2lyY-y~mN&id$@flUXtAwAcmbnt;j(+R~ZO1^wag%SlX(K8~SgY7rw{%pI&9j9wE7;If4rhj)o4EVA zn`&xNN1U^f3N?#ZY`3B?bE(LzDEJHW9S3eQ??GLMKB;@b2SMEPNJ-+WNXdl9k#=;T zxf6q&n{u-vs`#d)xb$!Z&0ixbNLs#-Siq8c6`_iXB}hs5Mj@ww4NNHpRXU0tznFJI zN|J=?u!N?NgqpB~!(j<;iV_lA{vu(+MM0Epc8dlh`K3^5~rbXsgNm>b3#q@KuTi! zA|+Xak&>AypD*+(#7gfBlgx60*QS!Dhip&^)_l*(iHg;M_ zhg75_RD+b-9fy>xF&$~gJXjXyt6Isr#RHFOt`aHnJ&ct2_6z-2VR!a}U_vtDS!0N* z7-=QoI@ub(v*EO(JYLwmiVf_t+05k63Hy-kJ;}=C3jrk4Sc)6KrNZe|Y(VcQZAfD8 za5}0~_zn2}T)3>Hw|D#+z(eUZfvskJx}}HFyTqca?g}UN?f|H&MCl=F;-KH(!~aR? z-1T(*0l~ZjP)-G81Ih;AMP?u%75knvq=58MSk?jQqd9IRXx0H-059M%z;l43>zRaW z6h2+Y>HTU2(@F)chYc1McyO!6U%{dTZ6$k9Xsl%M zg5J$~3T^oFBq8-a*7L}V9+ofRnzoyi2)3xn23B@;T)p)%(;hs(WcBYwpzS&^)f`u1(aA&`#7Y)2`9Jt-Yr0qFbR`tvjrH zSNEZApgvhYQ9nzcYgl2pYUpCzWsEe%nUA;U1=u-DM$GW0OU z8qz{SSMJW0E7+vDWdS;~U4%4jK$2lzmuPtsJYGqPtJGOBb(K>A%ze zu8%c5WSC>DF~*tlOl>CDm*!~8+g7RVM|(fVAP1L@jSv_kmA|V-t0$=+QpaoV(LAiF z);P3T+FY%m?X6SmUeNW?&(;57m}L}T@aEA~qcE+4BGWZkEH zMEMQ;WPnPix>fa{>UGt(s_tsNdW!mj`igphMyHvnnXB<>-q!q6^OHuab;%qHc=r0UfVWj)9Ce?`n~!W^g+GSP-J-CP;2zQo=&xwV^Dsv$2*c7DUNZD*^UCo?T&XH=Nw!Sb{|l3sPZx8 z-&L1X28|T|TbcH#_LS}uUAykOEXX$6^^YzR159|M?Z_uCCx9TN^zJ?(Nr9o#{ zWq8$a#&FK?yJ4U)&sb=@10J*6_?+=IV}tRWagu4FsnOKa{IGeC`LOwdxxf;zv|A#r zcUU)B4_PMZ_f(Hkk5}iaZ&4SiOVrP+Th!OpT{W?q3{A1-0ga&9uQ{ucY6oeDYqi=_+D7d+ z+E(r7x@5gZzexXzzERZ$N5)T$y!jFH59W22^)5@f67oq4X8oo!hO;xS>MAcV) zPUF|i(%!0dXJI2$(S4@-mu{|pqG7h7-f-3sX^c0XGM+bXG<{)`nGNRq z&D+e+nU9!HnIkRnX#P7(f0xx^by+K{Pg-BH9>au@*;4E)?4|av?VpkYHR3GcW+*FF zr&QmmhN-7$1g&0|t$RyX3zsY~K7-j2X-YHSZRu-GwXU$0+IH9;vpr=yVEfS4X8Xey zY42fAvg_?%*#r2?2(AuCCrG|m9#mDSe^=*fT?Ja1zNh|9y;pBE*bVy(Zx|%j;a09m z4D{S7^?7xcagMRd_^|0|(|ilpj5!Md=MaGJS4SG+47@>xP^vafG0iZoFqN3DTD#g5 zwqds0Y~?l&ta=iGYPJ1NbjfAE&%VQc2y>&=-rXU0aBVoGf&X#clrhQ*<)euAHHh~o zm1mTflzLUB>Lpd0daGu)X0PU)My?&8O+tL1pv}RIS*YEmeP4S<`@Qy}^=oSsrd>ON zc8c9#Uuxfp;fr%*I-YZUMi#^lkOG=c=|W^Us{C2mSEW!*RjpGAs(aLxYFD-TsQQ$8 zxTZ!U(?)6K+F0%F+GcHm&W&XwO}`z{`ih~iG1+J_K5Bf%RBKuYS53CwYJJKYYIL-H zp`+BX)$sx~hRt+7l8efAWp~wR)k5`7^{bHnxjGA8@`W~2SEhSa_qJiD@oi(VdB6FJ z+3B(zfVeDcu62!di?z}!SU<2{uzq7ru#K?kY^yMyn=v0=x7q9;*>81l3MNk12w03q zoQqREqk2`NwZvAuC3BOu6;^-Ui*i3tZoL@!GpRc-PedPgY>iY ztM&Kj-TF86xEp8~U~t(Cw-`1Xb{pO_d}(0D0mcc&Y%D@A8cR(TroWk9HeENF&6CWt z%@oz^EoUr)uneuVuCH@W+>OI z9#eg$x(3%(s~4+Rsqa%is6M8CU;T~xNA)00noE;~h`dST)jX+rMRQUk(aN+vF$e>+ zX2zkDQ@2pJQRmfFVMct6>G!?v zims=AfPSccGy;%Cze>MOU#j1z-=eS7zplTa|EK;(eY-x&(94i$7-i5JTvH4)4EGzJ zG`wUuVHj;(f}S5WoTf@0vcvqWz<3sreWd?)S`1=1b=5=1G=mmc^E3mQ$AZEuUL{x5QZEtaaAU ztlwgy2jR9B+XR=*X`5p!vXx+weAxD=ts0|!2;*I6J7xRU_A4TGihYb-i@2R`r=?}4 zeXf16eVM(`USz+^zQO(?Ce)ku_w8TW|7lNfY=$E~=s4hb-_ab3oawlQ0EdiFMk@y> zla*blLhc{TaO!OHQ_7j$yH( z*s#m+wBbd=NrT_;v*EfS2}{rY#%kkX<1ynG#v!ITrh80BOn*o3)6BP+A2eS!r(q|s zz_QzN0j|Bwy3_g$b^}+e!)*@R2HOj^3z({R*iYL3Za-)LatOk~kM^r}i6hZL?@tQ6 zw&tsssSDJrvD|D>m#Hg`B<*2KBNkj!aq4(=f?BIKs;%k_^+I)su1H-Bx}EA>>b>e( zb%VMQ3)B_06bn?mCPAanXf;Mnwq~kkwq~_vgJzqi3Y)Y8nC=al^Vq7jAdI&PpFP1& zxHyb2Uc^MXxV)F)b1!DS6 zEV%p42h6qR^Vkvi&28AEaF!^`D2vu&#b%`do4B2pLzX&Av!%@vYfZ2wTSr;7R;x9` zI@LPcy3kr+t#nzdth=mxt<}~V>rv}PYm2qbD!0Ykl5H8bskYg+h1m72Mm*SqUC#md z$WesWM%!7$z7|_6;$OTy*`5IpnT@ShfxQxOaF4wSv9Q%1<%o48I8q(i4yR+TW0|AE zvCXm5vBy#EXmFf$T%o{KM0Yf3gRWFyf2&j)F>|LXi;=+6|2&! z(pCAY)v97ut*Q|l@m5tk1|~y27eiL6u2An+*I*c$ux?yaM_~vQFn_vc8TJZg2;|i; zd@ZJVi>3`BJwcnS&CpKO&ej%b%Us%RnB#}A8#;*q+=d-|f-YG%N@vu~)#d97bj7-z zy1lwOU4!l{<~XNU=u`Ddy-}Z`Uxt`gs^6vGuRp18(zofa=@Sge;_SAam1 zvt4IsFf_u6rA8S7da6-r)Eccur*W<^A6vRU8;ljkZN{DO>>A@qVEqNDA=1?9nsria4m0!x`YQb){Y5=zP@pB;bh`fk04PlKLjV8( diff --git a/Release/FileSearch.exp b/Release/FileSearch.exp new file mode 100644 index 0000000000000000000000000000000000000000..e63acc59df4afae9961a9f57dc7ac9c6bfecab28 GIT binary patch literal 2074 zcmb_d%}*0i5TCY`Mf{?E#e;`E)C5G!r&vA=TUtwvr8JZ;%_gvPU(1HJ+w5+kn2>n$ zV&XyWCSLgyjNxeXWIW?PU`&kBJI=gq>AFQN#tHN5yx-33yf-`ZNP2wmvGdhJ#1C)< zxOhTLRV>9`5PnB}hWf-qD}YO=68?o$wpPgpGsKa6@&Y7KogzWkR7f>g*4kus{u&zB zG2bszi=(~Nc}mw&(>nKmemx+7589y({NRPSR$v*X7}@oZS|~u&V2Z`=msD1T7%Q;4 zeXm;94a?@^24i!~tQ0JBs*=kw1E!f3Gqg>N%juBR6_q>24ZRrC%nisW^ax)$uiI;$ z58wk7*RmI0G5wVS1K}0H)0Nse^xRpR`=hjWc^V~{uB)=G1U3`^Br0NMUj2Ph7 zJmM*CNr)G?wT#%wtuW$6ZpnzJxix`E-&=rHMB1$Y{fL*jr6Qi?7VY;NY6%ZB4jxJe z(J^^TH#X$BVp@$F-zwsg8S)&KRxz2}coJgOGW5bkK)_%sg)NkHXB%Kf%Nn|==Pa>% zu18GXPd$KbxEp}%mim`ejTFGDjGWVko;Q@DNKZ_$yBZ$pksI${)Xa)f5HnUq)pT)S zFw`$EM&&iFBp0;O25u8uxfj9#50-k;(Jqqoa5^1XjMf?fzqTZ;EJ=^x20DAm+0jqr zyzKTy-#+y1AYVtnk#EB7n~tn3B`_d}0c{k})ReUpd<&!KC6Jf1QIFk2IAvXl zr1E>Q>F4`XAKrc5^{UwOXoCv*`?=J^hp zOr{RMb>GVKHRasqhPmoX>qY zbDw&v)L!#fpO1EDn? zJLQ*cIjzh6%???wo=0(QRerKyLmtH=J-JmF*@;W@MrN$1FE8<5!kEh|UWqUn^B@mG zPB4K;(0k_=Yck39Eyt|l6~sVx1vioUryJSgd(ZoyyQuG?;N+|^qj!jeER(%uhd%M zplzqjuFl=)@g83LLSbC`KK z!P#_{t`;y_MK!y9T?6U?+~pWu<-8>L8x5uoapI^;mD^^l&EeyK|JL0OG34tw8M5Bpf-Kv$gcQ}pO%v#1S_$mfp zLRsY=(vDJ->ebCyNt0gjj6L^@v}N8`(jjA5y|tB}3?3Qy7aJ)}=ea0^$g;F27g_qB zBDF@*zfja6^q;M7UX!V>o9S|ROSe*$@>AU>+;f(C+mt1pg1|_@EVp324An|)kRSJr z$x>hyrKH_-fk0OXBuft=^JSoE-wyrk+me@<1o1k-kA*5A+|l?5=;?$YCG}RFZWev* z73#Pc30LgXdn3gYRo}OU^z_Yv#`G5j;vwN3^*p^I02mt6XX?GRC6(@@L`iugO@?Ho z=jy3ji~Y;#f07gYhN8+E@6Bdd4)%xW8`Bl`;kPrj)a@me{^e5yQ!wcQsqXeRPTRxM z_A0k+%?Tc_+Rho3+xAX|Wk`2AZbI`O>gIEHgFH9qhT)>HIhX(4kxFk2u1+Mx=)nnn)?b|EE(TcY z4)DGbML1@WwI_?*rWoSae5c}X=11x4OG58yfr!q3^K|W$?ypCZz;<&;Sg_9Sd_cyr zTjmR0GSrJhF|$Xpr+pt~R!f0yzQ9spf9_JBuf0pVcgx@e?bL4Vo-N^hz4?g~Q*V4E znAJVZmOH`ZV#Yy(x=S$EmxLP`L^;*-5=ThgWnSGnCumStdjuikac}wyf+BB9tGBi? zq${sj?6GOgeD&f>A{Rr;4MuOx2ARH*zARv*uValV`p)j`^g-4EBRzk823ygJeKDc$ zS|RYSfG?LyW9epjRzX>qKb^li8t#{I$J5PyjnQ;-r(xA}3ay88Y5iX>mnpjR7=ue_ zs?@9hJF!r=7FX)2YX9=dtk1R+ z+;o{tsX*oqT!tB6v(2FPx)u7I;15-Wn!R3)-BJSuVoRNFE$q{)Urhc|H=lKaE2suY z7WK|;06(m6N;KCA|NX3tBJ1*!2E)9p)G)6rH_SgpuDJ4wj1&&5wR{xs!5?sgw(*@u zg~*-YflGxxcFU5YS2&{1oTR5$7V{V4uav)X{wnzk>z1zD+dg6ly#+FoK?wOZZR3lw z4nJHhRKLUi`dRW@6Vl6SiuLZ{LOnH{zv6Jc{gs4Yia$f2OhDd*M3rKY%bO$eSR@0A zR_cHw@_xp}4APpf+m9b5@6Runk#0*I?gTHD;iqq7jJGky+rktUdqwBEMNH*3rgB>; z{X4;v)O1zf-WuylDoG?Z*Z+>* zMf$flU{cj0?dsy@?ijFKxoi`^9$ck=l}oJoT>UN&@#nqR(Rs=n(@9r0AQSuc=6mZxsLpi4Ikd9W>JPDQ^sc6+?KFIi-meS;GXQ9VIS zb$6mTR$UiJ6zQgK@HIUh)pd(MZVC*u%c$JT{s6mZt`huO%&=@ zyu)5U>^SRU=5xq)VX~F#;de3AbaQdPzWReg;Ig7xH{-kY)d%DzaY}O#Rpl|crgE2k z8Xoi^2h}CA`=^I{S0cSTKWsLJ2qk}N(C$U zu}<_<*GF-)4?x7UIeofSpY5f-3vkA@Io)xXt&+F)ErNNv@R7u1 z0f5xDeF~}FoI@_lbFQ0nt`j-e$(-w3a;{f+*CV7R{0$qp^mYiX#mpLy)(o={{2T$f z#myOgaqHN=SoQNs=xX~Yayuqgt&fl!(n>_VOK{jrdiCaHCZA%ZLAZFH_@Ch%+NAru2#1TfzZZ0OO@j@TrTu#*?uBT*St1y=$G(l5}{h~&9`e~br)RW~eSx2EnE?QgPC-JdA3Pku_O^YmDn+O3*G zWP}CHi|jiuqA*=N@PcsVD6Ym-LhCFS4bO**N>nrPB1S8=RXks7)#N$BAB%GU`z$r= zXl?&WS$gr1Xr$5i`TLN+LjI=mH-o=p;pQP_AtZQhe{@LPHOY(3=nN73W;DRh=e{)-fGrE97M92iH9QvDScz`Gbil2*TPYIpE+<$| zJw}^q>GU_I5q4=rQg3v(=oMle#5wyg6s#g$HQrfS`il}mJqhFNsBdaEpP zS6*?Mt08*!SnAdg*xDm_HT+KSuXx$$uD2#6J)mh9H;Uz&8s*AR3u?}Kp1QR%+eQfg zhqQqrQB&!*aT_)e%XE&;)=G_xUdi%}9l#=xwT#{MTJ-nGMUnc*#SyhkckNfpba)cO z>W%hg)cJLCZx%g;m(pFW%l)!ii*9GK`n@B525rq09=b|jv_mLn@dn+p_A*2Jcas5L z#q->DfN6Webb%!l<^)q0(4@Lr%~j0o!y3N{xIWe=kg===X6FRss+QFN(b)qRg1wk^ z-ee2|zuwz^FD<$txPKj&jp_Sa`4MtIB38E9*fmTm^2F}KF-os@%Z;=w&u)j-g>0?h z!-7o9YLYJYeOI3LA^+^h?{+V(U^^A;SG^KT(S!YL=JswGr~OpsHnI64Red}&1mT}7nFIuRY z_9O~}?WaV6`s;_~`GgM->Gft>X?GG@t@&QeI{P~KXJ8&GL`F+T`BRqO`IUOv`Q>`& zfBsbcJ4xR^pm!h4mldMhKG%3c^j7}O)C>9(pEas~dy6dFNnqmye-W2u8yl|Dt`(Dj z1{>tRWoRZ9&)eaDk!Q8;vnI%+75lGf4(8T-+VtqXQiSSoxhOE|3Lz7DGyq6sDYEK2 zrR663((lkpZ*;9fd2e(bG)IM6Q4EoHPbyai(>%rV&xrKi>C_<-hY*oTR?Jnp-tHv- zs@@r#=>8PM01C39GG2DT=ynj&7nSHSR>bR>w^7!GB96;rIIsEgcv-i>jbUz;$MQ(c zA9OSS81pxrE~9K0Afu7ZEK#wty|L;)HnSSPfYM&j4`CYG9MC0T`s@mC@NVbG@M-Zh zJjHa>6C>5-7iBms(wtT8fQWKUXnV4KRj0g5EAy?h4j5$zbQ!mGaX?ybu(zBqz^*hu z&`lSk##0%L8fdGdkSeIG2guq?AAN*%^StuRl9y2iz(|9vXq6&!XTJ{t^wx?Q<+VLd zivqo0O84hs%A8jmd5UGzr~k(guO@0xW zgK~)WbhEt=PIdZXOK9Nk^{(RI?*t#=#Y~H^b=Bq5_C~b3dInhJeIk+DAC^We_3}2c ztvXk?wzlpcDA?6~aH6@n+n!m_Z$$zHoAo7F)0HwAm?$0Xtfl8V5h~1<-t51>N;^Yl ze>IP__(dgkSYqXoP5=$SxMh|MXEwtbc?e$Q;o)kGFI9_`s>RjdV@sHqTl&5(ID=mg zQ_J*&^MOPGQ=xRFy@1f1TsXm>t7^*dNz77mzzKelXR@9*Il=Go8gi^rybVgQ=#0NX zH~o5=DoWynxmIpAxdVB}X5>Sa6TF1i>E5kbJ)C4k0~`^aBE9ht`Vu9IU7g^QbKO2G z@&CDfDi4PzJ1uKiWV1gm!&cW$@IBsG2hq7i*}hwFXIlO8lS?9 zEvRz~^pQ7ORYB1KQEAfcZo@_I$?}y})Sg)hLPM%AY$IgTd|p~7CFu6{El0UG4RSN- zNUwx?_I)$F61jQ%aIXY3+sD7HR-Bd&U*b5B(%}R*oF@x*biHoYci6LTkj~`sBzlUN zJ%jlWJnV&h7Uihs7=heRB8wxJk9gBY{N3NbS4az!_wo7aSLsH& zbHY#PbCkaUq^fvJ2>%+&RRF!i^=sTAbSGh!^p(Z@QO-)>62wG3E#z>eU$52@({=M` zCwP&f(j9vB%;ej;sg3AK^jS$+rq7Ij{rl^^@%<+YG2_gPuW-!xM(bDCm%M`yq+ed` zjXsc3u1bM5%GFg{8L+rQq7$R$>$m`jb;M*+Evupxe~XxZuf=5@|X|uO6Rqaa_ z#c7j>9&Ls*?bWFEUVv_T?JC+^XGT{b?#s>SP5hMBrk9GtAigHfLSohT8W=Wr;2RK~ zzvVSoOYdcU7493`XLw&v9!N~JIBvZ+oZuR%hfK*&&y1KKL6vtxrfZC{KK-e$HoE`B zW24qU)@4_*!JorAsI_eb3UTvUmWxsddA@aQTJQc-Aq#ORR)883Jd&sFj-l1Qq-JxS z#cZT`DHSaYh|NVsSr>O5GV0Mo_C>4!Vm*uu@{dr;AxIfD-7ad#GK*junZej`Gv-+J zcCCFO%Ov$S>P~kjMB&r-ziw#Z9wo`Hl&;JnM!E5Pt1v3X=;HX#mt(O2cBrIflRt+0 z<{`B2D#Z%*8(Ha{;4@JX0aC1N(ueT>x#J!~W@dbi@ZGgg>z#V_&cvlSwJXsla^1N@ zw3T(|UMKF{>qfhCcd7~*ckXrK&b`ia=hooP?G<-!e2o))Na`VBCJT}aYSX8Rq=`=y zG4pCritZ~>JhghOu-YgwBZHg>PoG5-;-Xak-3IYUdZ7zZKhwW1Y2`(D^4Tt$6P{H5 z$O9FxAZ|j61;0fF&jCDKD}4@0B|O?)i3_EA$r9%VcpFn^UFl2i z^BgQn4?JNhs1ezcxJoL8Wfo{IqJvg~4#3n%Fg$UD zk?M1D_oVvQWYDRtbvcoI zSK<;_DV7i|K2-)5*3AgoWCV55s5Hv-a-|KX3rjx9T!A}uR29D#C@hI+(N_VOhbgLeUUXofFJcbHHCg7o|BKr^k4y3#Svt zj;ePe4eIHMj|%rF_fvEaZ-m=l5f|{VBcW)txg)409?fs7aS6@+5+{U+inTKG)mvo( zS8jnGR=>4DT9O_!E41=Om_?hO$WE?9ssMY2P;T%4lgM6d?k&1b;Oy{hOcnikhdt>^ zs!F)knjab!haI{?6@)1W+gr|oQ|2y8*DNyUUY@SG+??Bxu4#}Ig^Qp_Q2cqZ3Rl{X z!(X1(+Yuh6_1;&~DuaTka)Oz+Q%9zxg6qr#&XOD#atAq@bU?_os?XwBw9W4h&@ zESPq&YTjeNzF0|)#rNoD@}8KP{DqPFSYir)Af#{)zdbRt<)K)*Wz9URaAnN8;T{&O z|BhALiTSlA-s!#ZvcDM4R%6#&Jd0^_--x&WIdO8VY%rp2jD6NeobDVUJgDX}LIS<< z>JO8DkzS-#>2a`-t2ODCjpEUqvy>q{ZeMsTc`{~iyd9tBHRxP1*5bzjhA+gQA%rM- zdOkxv3&^u4|Mpq+G;BN}zhVAl_})}{=4cyd=+>ME8dJkZYiq>Mu5Bcg)ct@8PUtV} z)u#+Qwbn+%n(M@>`?S!-=49h|H4@1MQe&PqrynYw zwBiUTIMw}T4gn9I!rP}1?ws<$;4Cgfgrc}Cw&uLX8|SQ;U}!&ndiexOzL6|2rhFK2 zx}s)Zyn3hB-cO(j*l&F77#S@NE}ySet{#;uA22lisRQ}a^zdNOH+cB~QNlvq*`EBX zk#Z&~5d-fJ*UlO?y5BfEHpLOnlWZV#*{13|JTf?~;p=uYSuGboWM8!Uuxx!ACqn*S?$9B#PD)N8wK6)imGL z)Ag+wa?y%Ei=DGlq%m*fK3`hWApc!2|1FJGT^-Qc^WApE1w}L0_|dtp8CHSa;P+*n zv*N?{F!>XPb)|%hhh@DvIoIiLewkX?WRfM41|obhEGyB>OBi&jCE)7v!%pxDDtqQ* zC%yF<)}3qVnEIXea#Xi<2*ysmeP7}l^!hHndcWjoTv3^;)PF|x=jCWD5v6{~Xr=yO zl^W1qcScJ@sb4ZysRubPP>ls{=|J8zW|w-_A(pGP`2mMP+|0k6;JIG{<9#uJ6(aDY zfO5AW&k24>`mpYon@xymgeoa3c{~((pW2eIJ3EuI4lM9H!8a>qJW&N33n@=>-4ij$?Fpqp;IOjkZ@36Dzs~-kPGwt=t zeyCTqlqSwJ%=a~wpJ>$=(`dOYq+D5xi@8`_tZkgSoHztRt1(^JjDK~%UY#sWvJgkJ z)wxPXJLn+}0hDDxmL*DhH&oZd_H5;+TRe;<;qwiWZW^ug2CB^J$Hpa*Lfi(so#3O47L(5;${8g?WEM#>=o(R* zUm5ApSgKdKU?-?tuoi44-i%{1T}La23{d5P9X|^AHEz9tH$1-#Zy4~#%z8VHI(CkN zFvR%{mpCT~apJsK%p6*V1l)^v17)0(tG_e?WqI4EemB`CFx8|TqFB-041X>9NBWwz zJlER(4rn5&P3!r=G0Ig3S3a%%_xx|9R;|Q4JOl8>tt*!yumXmP`QecH4EC_rb^t8U zvex!rQoZ`1w&p=DVr4HG4*AcF&rI${@fpgfS2BuX37?xUz#>x`t0pI=s@w_kCf+s7 z--_}{lGe_+xdls1OztrCe2tN+yyP@P5-d_(aM-rNHy%}d#Pf(Y=UL1(%(U%#*$#cz z0mFP+FYAtBjairG4_Y$kj7p@J_3OJ1YHeuyLLm+If9w`*dbeQ_sHq-KOwW)x%JfeA z330bs3q!iKKq=Ex+*11|?(;Cu!}f{_7K)lh>A8!{n#x3ftK^}Y&f-s*HVC$xOCjN`X6*B&d@kO22>z_~0=EKkSL+E zC0(`VgAHKZ$a>@|97)7EjHb0a&V;(nUN;w~{UmM-^G=zzQKr_XYyd0cyi<<5eCoj~ zKcODH@;;3#({fqVT+_iLab7gA_Fhkc&wLLnXyrfCYJ%#-BQo+HfUkvuHq(Z_1a_a% zs(1g99KFpUgi60)2;lZLrWbb_1^2AwHg4`vD;4X2?*cmhfEN0EiTS#;8J3AjEr1s? z3Z8TGIq~*Pf>ArE*{=jiCxYZ=;xng>2ol6~Uve{vRE^rIFN!PNFDMy>-=cHLa;k>-9pTz#W_<1xawEDQ4m~ zx9Zo6@9^Pz$g>B3@Jb`qQ#TrvdS}+pI?Bl^?wBP#jJSGp;&Va^13$xR#APC503*x5 zk5Gkguu#U9k%3y9!?P@I+ul)kjCc|w)~r8r%gfgf?BQZ8?Zy#7!Uac=HK3r;CT82{ z;T}RywdQXYF$_gk|4Q`?*+k4cg}i{rGA=vZ%LWNoFBR`!ohWj;WYLBdxLl8*8C@$E zrQ#|Hk)}sBT?ZkPR&jE-OwN(?WtkZ!j#K!USX;HUWNFKc^z9|r4-y|!JenC=Y9~xx zf3FDVYxLCD1HQx+NL%~9=?oj!l1GfF2k9u}811CjP9(f^T1wJ^cX@xn=d13;GkGt0 zLSe(4TW;Ro7f^(!7EJV%FPDpatiKn8EK@N>l5BkV7aMS}T&1Uo=3b_+b^^0~zLpEC zz=GC}3kUJ)!31zDEeQ)uDr1u3F1f(v;*&!dA%(_)$%$xi6^^-oKtlQWDXxc`1>@Mn zC@>@`wm-j#TT(r1cZx?1(32=6-2i_gb*{&RXO%Ae!Pcn0GO&OB7J)rfG=ol-I>~7c z#K#bq4R|PDhCuNR&LICbxk`;Axl+b#-cGi#HMd-RKlF{;b)@g?6urL3;y%;&(`*n> zeIMcWJrxz~HR-#;84Stf&DREtRb%E5kEZbm_dVbfz^9(96CO!mu^fhMF-+26$T-O1 zxi?8a$dQdv?U6pR@1>%>!vu0!QPl!%v~*@1F`_Gq6SoaB;7*Q`cA`q*6y0eYq=_}^95>K3zjJrhoB}4i`s!80?U4PK4MyB zh(nm^mOj;rYk%1LP7>RLY%Dj{2o=_zBx{?bp<-~~ezWS}*a1R~aE8aNm z#HK#&#Fg-UQQ>;}l|V*&2UHzP$6Ljv4?Vvu+*2oHjNkjoQh7VwvQ{_S%he?;f#A{A zb%FrH>Q#X}Mxw3xuEe8zqrFo~m9e6M{N6oC!70Er?SXCTRm63gi2 zMP;f(z1YYb&}O0?jj7x9k1yx7j>Jh3H-u#cpN8ISKa{dA)3R0Hp_(pO%EQ4@SJA-0 z__5UdgY-AH=AI=o2ubZzNa%2aUo8U|jE{%IvcPg>)#GuVIGg8yWtqEBJW%K(GbwQP zI_$8_`fo<-w8!=av^$QckgLhs9mQNRq1{OJF9&q2M3F@ z`j_6@CHfaR&tzbc^ZY!UAain_^OjFCH!D3Wk&v;B^enP3r&qDzbb9^t{<^*Xy6JBc zVMbVfbf5XlKjZb8#8ZCIuifz?of+nifj)jyPgX)~zQhdI?(4D-9tWUHhXytXKX`P5 zM`c4}y1pZ3x^4hc!zB^^fw@A9MB=KV8xm)m!xDcKdJ)`<{o8?7)ghKy2MX2Kv42aI zLUo(dV}7hxw`{=vHHG$-gIxB$K(I#$!M+eP=ZiAkVLxN2c$jSMRH{{Xqjuvv+GYDj z(bvQip(CXABJI@u+Bd~*N)V914F$S#fY>L~h`>JTKl zL73FLq)w}f@OcG>_q041x6gh?cyCl+Cyn2iG8xFFkX2%$R1qi+l5!zGq=M{=)&;b- zS4JTb&WG_cllLb2GNT<&X1MZ!XpW%a=~{7Ow%m?m1{pGlPu*p)b-DQqE`N2{#aA(Z z(F|N1z~EuCU8sz!N;m0;E7tR9hpVWW?ULQBUssb+pOi4DfzjY9VrOuHgHU(2J zJ@^P@hX87~iPa;i_EArYhC;0I3sNG$O$iSl?AgD#>oiI3S6k7T}udt{jqY|kK zJfqtDxm0o6`x@;@hr@1%d$Ipip(O%d7LHx}gmHdd(#2e~(kDtb$edPhl?7sC0b&1| ztRIn!4C}gGEFWEhAmX3@MnAG#L|-Gn?5nzY{~8Kn<~3LHhyYIgny6$Dyd&!dAWW+@ zvg|v`l*#HLi1vq2J6LS)!6>@ZTX!So!CID_axd>f>DW6Nay)%qsMfq;6}#N}iZ^-C=H0R zH~NzB6@%HyLRG)XuB<`KY-93O@tuje<^i$eGV22fc}Yy9O^BLJB6H-w#hYAtv!aBA zjvhR2w<&qEQ{>I!JJBc0E4Be4!ccL^cxJkX z&NVhi`r8+;T2Y=jt70FLY87G!*TCG+U?Ey?NcAs{E^oq%>G@95N+N2a%@K2-QN5x( z*=wNa7OOXBl!&YBw{gf=Wa=h+CCr?i)61^8`jYa2$TS|KF-q}RJL_jB7uTXHA)!v}m?ryIoC2~gCee|8c~ENK zaji^(y(7bkujTH0J_)&V$Ual?KsFzfaoZl_xou_RMFG_ZiND~rofu13xK7)-0oQ4Z zL6;3xxcgqmF30~IkN=+6U-RT(<0>4#C+F#My zhtP@Ht0IAJC9lBF&*26MbSqG=-YO^%C3_?zF}zSVNL-9$l(Lbe0JG>}!iq{njz-Hn zE?VA#Y6UH^FeGA~5rh{j{)Rp>f{*9ybpaP2T~ar-D&PYpxRg{nt)L{-JO(9ie>IB| zRMe5J==X$Zz}xz(r*8^0rcn<*5hFKKJA)BDUG_;B(bLz_P}vxSoUFR?5TcWiSScH+ z$H7N|R1|!S!N%ZBo(neKJro-=hnSy-1;GK?K(cO=s(E`!AZ8k{aimhu=CPBCPZn6r zL>lfS0bq}@-xe#kdpKW`C)unJDDfzza)nr=;I-FG)j#tg-Hmn)l z%_M#H#;ke8%2C}l$d&-vU%2Yoc-edws~!VS77l*YI`$HHz4WoJ&`URaIx7vSHa4vu zBQU1b!clol-7kUj-y#pnsLf8@Uvpj&BmOvY6> zC%fZkC3PQu>~wA@#Ikz-Aa9iI#S`7fOJZE=Y1oD$$(9>ZzfY75%dc5<&-eL}iM4kW zh}jO{NZCq9Lj2>!f#ZYNq_^ zR|O|*oogvZlZ9uL_aX`;5h#WgFSkS3E@+HT%Fx^pgEZ^}7m?-iI6e7Pq;0Rg2v;eK zC1EbM6dLJD;yY|YiQ2LUg=LuSEbk_!$sQDz+UM-;-(=KjHrAw{9HI?=hULd>7bg`Y z;NyqzVg{+cH0D*O)mdaowj~4S{%xafr9{Uxzb$w1(9VLph)@Jc|9kacc7a;5~ zm{RZJQ?}aWAxm`gk^3U22NH!2>4jKzd2Goh1lDC<$%i>kLY z&(y2;sJBm0Z(r%YE%DF2_GVr+%xI}m7In`BsP1V#F&o9v^y(q?<{;$f1W)k#1@Fc7 zBJ@>288*t|h~$lP1+_48%LqqjH+5yy4@k3}x+tIS@f?JY{Qyg_)FA(P z+s7_Y9f(7UXH7KOikmB^i`$WH8L4qdA8I{yI~lceEK9YX%nAQLCeO_?aB@C%jhj|J zK?rrRIE1YGN9fdY>6GQhqtk9JwH<;*A0Y3srqbADYa17SSuc3u69q?x%Rh9pGHU$$ zYEH+V{*B_XXvZhWg!3honvSkdw`|B*w|F!~CfwZ#gcT+yV^KgItY1*aI5gpGPv5;( z(4oTZ?X6sLg2C!{-hS%mf6yL#XXay{eNQNE78K{=nqv~K?RzNV^IZ$(XH4<=%KC1d zuv*+gt71!7gW_vrv$|td(RC}P>AMD$A3{RIT_}w)lVryQ=2TqORJ^F9VI8^cWDl{C z-9O)qZT5QyCooWTepf)Y)%ga|hV_76HQ(Pn8PgOnNBag5fcTYF(1ReR7@O=zYf)x3 zv=d#)bfij$7Kk>n`*6K(o<=5oN6b8rPF}QseTP8hIT^$r;R+>gx3%^C&k%Hg%Q#q`g4Q*?u`PoXu}A{X#oYjfqNCw+SdtC$Cu^bdr|PF zg1*pdUh@ zst=8iq0{~mhPuE@7pWYKq)u42P91vT;pkR{qhW9(B$vU_@HjXMtoCqJUz$bH3j$O@ z5zlfl6o>9J2trGUhwKY)Q26oZ;wRd#O%E4is}!JH9kNcA2bD$@h8HsoUA;%Uqe^nt z{!gth34&e&8^uFpO7yE+PL-?~<;l7_DA!AfV#h)PM5dNIO zewsu0^Vh;ypUR)0U-s~s`Zujft!_DEr;@C z_om)GP52X~!wDXQRk3$6dsAClU61qFy{V`*wPoto3jFwH(O%Qfqc8u3SQWK)L-w$*Pn zh&qG)v?ycst(OO8(JxKuL9DzwbQ$HAdN*d`|8Qzi(CT8<5%O7a+KOT~?0QgJhH&4s z?2TG;IixNa5segZONfL$N^Z1SnKkR})n5P-=@xV)3GLvLB1d#FBsSuLVyjE7oRJaj z&^a>CI-lXVrxC`|w@Oh}rbVK`_GvUH{`W4||GwS{22^8XN0Vx~*R9cty#TpprpQp% z$#`37W0)Y=iK1MX@x24ba3M}jw6sHQU@uNH)&M?xG7S?%r_p}K9}o$eZ6hpjQWmgZ ztRyR{9%SvUXrE_n9p(i8KFPJU{tVo4=nCzHK~Y%jC^?*}x|>53t8VirX1I%F^`7NJ z^hblJT;DlFnRSslGE*zwYJVBH(N?RAJoB;u02z(I5h%CP_jA>qxq7QGY{rYJ_A}KfCWHnu9NZue z*u9kcI-I~#ak#Km*xnRWeLYdK8_UQzC z=>@yeZj3+D7*Yn+1+1FfG>XgDw%|;G4Q} z>ei;8?1D@(2Rf*=tx7ts>J&{lQEDboTs&t*9v@+6eozbI+$T-^w`8d!rp0S=LWO+KHsb zp^|(q1+YXVi4qAoh%yp0uO)DBbs$>(ms|X3VFTT=%4Wr0+@R$BVZKM-17 zdHv7wy2`9FB(qA^9t#CXloEM;edhI#K}+WK_ton$Yq498O_W@jEo}2~*gt0W4?M{f zB@0RIA@~_LY7fDWMdIZN7{zEOJ!Mm7*I z{lPWp5ZPgHrFIbvl8L?D!Pg^sHlJ&MUSac$SFxD~{)O>N8bPnzv~ffFWs#Oz!4)Y( zyE)uuILe06hAccaf#*)L&^JzvIKf{-m$l|@0y5^awPiaJC&$f;i}Bw{0@HFf2eJKw zvn#B^V>njh*l=Q!vpG_|EBQKk%r84VPH%+WrVmD{-%n1KG0bNSg9X|pk~K7 ziAOogYJ+yrWQ7(~;u@Qn|BEVGDN8>o-mLp?|5kX%-NB}n3Ja{>+A32U=U^3&sXYE8 z+7w`w5iOYT$t9}i8uyI&-WrjszMca3xNF?rh#6KRj4gyUZCzK#j9UnV+*?(HltI+ z&ICP@$3(LSgMOLv=2IjglYRGF8rO}t+hHgB9NdIE((JYjJ{=(~BO(q=c_mkvajl!v zbt~f6aDPfV!BdVjxl8d4a%D@J0dv~fPEfqm#{{}&_2ye{jus7 zk`N4_F{j%vA|jc{fU+LV9Y)!9W79|muV{lY^JSy^1J=1MZlHH}Ob+c?;Fn}yrSiEk zS}J5C!PUE0MB{=MlHj-7OW21d$7GW4V1HG0hs{t%!my`n;#kh;i$sb4RdRy$f{6qF z25U${Yqp=!nbxuDmsgZ=W=yL(Gp69>k^bJhIMW~5+Nf7GUn95tVz%leIEq)2R(9EY zXGz-}E#E7VF*27wX*}c=oKD@guEfzXIn_v7Jj{Mad@t#_euNyj^Bb_ z)|cy2Au7CMv{ywD)4-!xQCYI`&X*8!lBAadwuw3u0|7DfsF*1+16@viozcC(EbQjw z+ipWnzGXL?oO~`irbhRK>~Fe-~(`p6a2Ri`SywKbg}p; zgrpbJ#2mPWv1>|i^<2{S3bxXSxlt}|GZ$;%N};NjaUmKp8V)^(Tn8TbW$Hv+>wKp} zJU)n4t7wI~A{eo{`(Da8cbTEAldABW=pGzLK|f^YTq6Z=nycIueM!AoSmiyj{$&|6 zOkY&>A=~QkvCUSst)e@X$U$WHu4$z~`PaKl6yfQhkk17u`Ky)+-CQlL3F|MZ zF$?j9P&@DNYl3MEyDX2}iORmq?pFNYSsF;j|6IS@2%LT zr-AI;PWPu@-E_D&UGC5Bv_JLLp^x?S0-Kq%I>Bj@&R{KAE5HWo2tg!qD-RWY^Q0U2 zybQ!bGAsKL@mU~hn9|sMiG}L$|57v3RI3cP_4$b@l3JVES{k|HvMs5DPI58;_ioqw z6J;c_gbf5NqFjz`Std3F9>2&UeThE~{@A&w7i^D|^~pqP!XyPs)z7QvOZ*h+)w`OH zf_a?az5^H)Ys)!pEz^NW*gEQy7UB#d#A$0uB|l`fRO$r>g%%~|b|BO|@llx@`-#)QGE@bDsS<*B7T6YyqT#djb>V_ zt1a8iu?DqiAIT(V9p~xni!|kPri2-(a~KlYQI21gs%z74ZeBZmOU3hi4G9d2E&}nf zZAcN{0(77{V@bZw@sE&Tq4r4r7Md$e;x>rL6s6OX$Y5GAL9e=C*)20;Rgq=Q>{5;Z z%*e7xSzd&XElHoIUwb6a?ZK1R=B+fq>2+BD6J=ePtgCn7;AM*AM1kZ$D@|?2)6JV{ zLkLl8`>8@)aPfXo&^hUWtf@K0hBxp!ZsD0Juhf+t87b&Lk%s40>Pt352Q-#B_H7=VDeIut_K<30 z4(uaCfOnXR-$;YWIg846r2~q@cr&qFjtiuBjGW-VlX5-ou#Zv0p32MPjdQzTh2b|`vT1idVtW+B^h<(BZmxLM~% zmXRM9FJR?~Fhg;0<)Vb9-uk;R3|iPOt?dcH0h}6$?CZ`;+{hMl^u%+0iKSu@uKk_@ z%tC+*Qg2K0j?hAo?ljt~V^^iy-oD2dIg zk1{;&a=OS}PIcxY%jpk9gdvVscdzGx6PyQxWDV6t!06VMe%A-D_65M)pLu`ON_vrc zJ7*lI^Xr98{3d1|$N<{9~dM(7hJsEe?sZ&rbKn8+gazE$)~)&Iyuuaa>|xjWG-awp0` z9jCpgCOW}W8Lm@r7k*JU)f4Mq+=+gXBi}i;OHFi0y)ahiQ@eB|%y%)hcLVNBpt)mzSY9HtFf< zI;#asg1gkPP1V=>xWcykO_%*L9YOdll8$WM>1sqdnn@4OU6nm!|32z=YZYC`IwH1O zI!^{*{Lcn(i#q@S6}k*X=#mP4;9W`-sROv(m7s{)tO$t;=K84fg44kW4Lv=+MSxS557~UkC%`O2| z3!1PRm0o-|5Fo>Pr7szZXit#_bdNOR1pfwc$(LWMdm>tN-@x0jNbTC>8;`N08q%(x z*%O_})(|}%pU4!C^2<{zI#Ev@4B(IJUQ4fKdZY5a>rJQ!Q=SuOtM&eD*i?m#gm!1?5+X78K^1u8+z=i6rpN+ z=SSV#&HOD+G?odPm$AMz>zT8oF2BoTlf9Cc6Oq;GLU;1j$1g9(e9h@$vXSCq6EI3k)goF-vzDi+xPw+>2Wp zOb-p*teSq#8Bi&Oz0p%OK&@haEwgLawqV^Uc65SmlBti(;LTcdNNby|27o}SpPk8h z`(}|mvn~b5AAGE>8GwIb`BP)nJDR5}c_z$ulzlj%?7?DTG9rpCvthEM_~?;hm!sB# zvijNb7Uk?M%`K~4dpclUtX{wweX9FLPhqj@MGb`Jy{6(vA(xIKroeyJRDkIUC}CL~ z8Bk<&ST2azMUif`CWGeR*;w8_ZY7a;sxClxV5GY6~I4F5qi>ud)?{|WK zrjqtZa{u5}f|LwA<42j%*>vEPZ7%56m+WTK%FAwko$l<=o|<|@Ryr*e%4&b*8;?uv z!Pk*!hr{xGpYKgqz7?vw&vUm5Q|>-ma-gdbFNA@j{Y zZ@zq=RK!$BId?*tY2Y`+QYlvy9G8i|jATiC-R}LIn%m7DDJb8b6TAQ{Au_O?={2&v+xLbfMy2C)S3W`v8&egi$yM0d$xT73 z0~B@o49B~=){jVQ<>rs5ZyILgHL_YMc6?wB7H~ILh}&oiwq!#9pU27$8t+G~};74x=SvrZ3Zb`tw`;uTnVstsGekQI3cIDz7Rxy6DP#7{HeQfjyQM z7FUMn2C(l0chPLFJr>9@Jh8`qD#aN)i0>h*w{z^VIyAHNMY;A^gL=a%Dpyse(ITAp}+){<+YW3sV zV@;G`kI56U$71sK{}Frat1=z2$Nu^!F2=FP&SOq4Ju3PUyV?udS-%wH4T)%d=U(C6 z4{e!}y5_tIno~y&5(Ncwdj-l$vlGe8-d3U0F#(zp`ouLSzWpPZG|h{jc#m?119L*S zcd52&ialpI%AY3|MM{R;o3Q({2xs_`CY<3SNSS0_&ZxMZr&?m|%hGx-3m!UOF^AQB z*UNnG8&dO?YbUt>kE7;01Uvon^UVld=DY?Ol%4Y-RxYY8w%h!sn82i_GFnC!B>mK2 zX8T8(+3Siuv}!ryV#bTqxW=FHq4O1TQ}Y$>w9iuM%inQ1bz)At;Me!h&R5n~q^9># z?2vAL9S54N;-q_w>R}aA`Tz+_9tb@=W0VcYs(11cDG8z`Pe+fPhco| z_E3hOiEOyp46@RXBs3hY5*kYB(T$%>_#b37xV-MJXSihpY9kczQFe3Q3i+zonXsZ0 z{K{TIrWj3zwK7ld6kCUXtJs;ZlFg>8S{166IDo2mHita9d=83SdPX~ zFnAUZlY^pDNCf|YUr;bbt;X{Ca24oc3HBZUYLd{sWtoe|E(d9i=@~@$q*0F?T#~8i zBF*SlsXdPECV=+%>C@?b3d}>E;cJJ`dl=6T^giFE_dg?vo#5xCnl~Kg2nD;x_Nd{^ zlaoqz*mpqg0}n9tLm{|RHS*3Mq!AB-Cm~fJ*O%nYVcrxda?YL{_6j@{r}&qDUO1&h zVELCESOVuMfN>B5pAXF!44xwJ1N%F{||q_ zRl0dWFS3h^l>6wZyAM0g9q6*@e+4V8wmG7;) zD^q4!8ki&Qlq~UOG9B-N2lx)z?-l6g7aQ2qp&ZaX`56~tZj-ciOTr|-TSy<*&=0>y%4h&<#Wa^4ue?1u7PV2 z9wT$(>`T?2r*{ZELTwaGo}zNet!-^zFS!kWArIk-U@QXWzOn| z07LcyuDIS=;r=6?#hvN{du6J7UY4nf{MD_qNCbMLP`QZnWr$$!Gde^nhF5{-utKJ8 z@El%F@CkW2=bvnwU*WTg5txC>1G=uaI*pDvXGzUGKfgU%8w#N|BR1mtu9`llRS6@5m?OJzn;C(H^q0lqbHe zMAVuXJb@n?)^$&NikUwt2|@2rxSXI=_QIIdtT*{0tkL}uIXF+dsadvS9=>}kJdjDx z8l5&JSy!opxOaX^!|}2ma@NME6D;*jS=>;SKnl(wrSE)*(B?dhJwTbWJM!WThqMB= zYhjy{A0}MSK_If96FEZWgS?GY+|oROBQ;+eEYb`1R5(WU9<-@FG545)u=v2LbE#qX ziW3l<|Cbzz>jWo5`Le4GKvI)9YRqgaVZVrP5D)RQyJa9{oR7pHnD{|HCJH2aT}TY8 z#C4%0KC`*WJz@8`xVcrGn~p~I_UZUrDV49FnRls1C9$ixR-Hgwo)0$SY@LEzTG_u) z7%!lj;u-hXM%bVJ*aoTeXj2Gk_;lrXGFwz*?Z!;y1k4^ijT^!$WTcr}&Vl%naG*Xgi_yf(`VPgE3_h)5~Nt=Z~_r+`d^pb!@ejv@%Bdi~=q|?{w0;+-EHPxa@#T zTS&5@S{ExjaO zF<1{@4eUwCj@;7g$fDEQR!dLJz&nrhAB_K(`#ydAmel!_@dKa?_)=XAqA&R^IbKQ3 zSO4in*wRPSw5FHGcGKA5dGl=yf7W$ouY^BD!t z3cc$EhZ$*z6TBHIJeGvLW8o}$-X0;6c+)Meob+l5e{ByN~D`SmhbD%^(_k-W6;i(+X7%~$95Vr3Yk|8BV=)3HIH?$4%9^WF=Q*R)CPSFc~uNUxjL;RR} zntEv5Sol{2WNp`Ffa36z@v+2t`Zk__#6Ra*c^SH*@k~NW=_cRF1VV;bom&8ixOI`T zvSmkNi77VM`q&X`bSl$>lVuUlg_2vFBZ_ZE2opDaL8eo-M+(`B-Tgr!$H#fX*Ok0Q z5%Uiyrv-cT>X&tG&dVZhXB&hW*Zc(RNmT`~IsR|^)z3fa8x2@bORY&js znAP|>Pn6n+l}iJhApvR;qW1X_xfjf{6NXQQ=Xqk&K0_6NesZGA-chY^ZkS5}1|2If zcmI`Sr!$R$KNto3-0bNq0|P^JO@7<+3TfV_p%svXiDX<_z^6?o#L;}Uk?I1f&)I!p z8N~v>J7Tk2gju;>CZDPm0GIXK7fT>CHP=t|1q@b7Qr$yJ9=J{Nl`%ISpiPJNXqJTA z_Xod<(lDe#JUi?qsuQNE$g_F}>3CL6V4W7I8PZd1hPJ{(+H{5?HL7aNXYU7Gv9ecaCr0cNZZr0SG1hs9UR2L| z!LYpQ=6(tjlG_M9pC$8wwD!cIzJ$ZZk$v9iO2 z5j(h)8MAJiFMAyM0o`V`F5quiQ+w>YP8R&#KLJZ~$W|26$+0rmhgfcwq*CqDu;Hu8W7r(yFwOgfk^4H`%uZxGd6 zk}vC)F0Cg{89fU2J7xR#5T!Duy|MfW?|;l9y$$Vl6&Vq9JGD=jB`pq-T$hP1$}yPP z93u87tC%8QC)OfXDoBD@ahR?5bN$Q=%}h&#ge%L{`6lXQgoi+-tP}3Xn#GJ_B^Q4h zQ5RFtJn~Q8bVGUdI@Q5iIY6Gzz=#yTv@++{zMIjOIx%7I*|t#vukWb#D>-{rD3 z$UEi~T_s|6$%loo$h~l}){bOjcW#*f#fP!Y30}TKnw2F&YkQQ(Ui>jPTk=+^VsX~I z#e%N}M*ep;6uA&3Y2hL-@MsqOjO@lSkw*zQE3{P7&^ls(wi9wYl{A1CwkdD<W`_WrZKa(ZXTW>P{ybJ^YMp7)) z{e!dYYniU@Ml~y(wk|##qieOK66~Sd_AXr`lfv9FI(yU!UcVjCP3sX;-i@`UOwARywYFVI*w#l^(*ZYI zxd8^*m~3+5XzEy*rXHQ?1$x$f!Sm@lvpVF<0#oC>1A` zi9CR(*B})|us0#pOWj86uKvN^92$$1qr6M9F^ zWkOy5oIQ6B7#*?au9Y$Cvi%D?3|F;CIedv6B|*skE>(3LyRKOZJi9JD#;z+DfmP|* zb)zG&*?b8n_&PDFwyq@l@f0Um$RLO^NZd#E#hbC|_#C$pE;C)%pYAjSWJwy8eD2L3 zoMrfZl>h!x&wsB17$g3BB3@tzc{@ojn2$pK+$~>JPjGIH@!c!0{SKK7Gs-ac!1wt& zv7ADHa&SIq!ZABupbzIQ4vQDO5Pue!t9+K34wW zI}l4w@F!0zB#D3cb~dg$;veRGX#B(9VkL5;Lr}Ksqb1bjx^syTl7^+`8eUs&U)i^Bt^Nab8Nyu}e7%H$vL%L*B~JU{M(j2gGB74oU1yn6|n{ z#oackdap}8*Y7JI<$Fl+@>!hrAQF*(*#O)+RsCUA-3uRm-U}T)na^ZVt#5F5`Ljp- zp9&ojq*I|I2_Z@P5Wa(&0I?4A+Zi{aRYmNFf9#?OT5`j&Q_$wk9hvwWF!vl5YIBi7 zS*4)N%>o*&AG!SKraGy#CV`oFFs>dypfn#`E1x^8FcMHYLp{wB%=iH%6cnyjOv{b7dt0`d7QL z6OiJC>)s{+kO_SvLsYnq?NtiqXYeaQ2|}VZ0XHzg@vVUT+#h{9$W`vuCqvt%SGAQh zB=K++a>EaDP?2XbqM7slHY?5%FE@0%;&_R7gJo~Kx;O5e&dp@hY2RW*rxx`Kn) zID@W(sgaK=N^Yo_bpk3?&={X?M)9^#iE>igf&cfCpe!YynY>c%HeKyjXRR^BaaTRMOi zhaJm@0{4qdot^cg!Et?TFf2eHYy;n}T`DfVi@VX-29M$$kxdOkWKAMHSc=4H0X9P} z2{0fxGAz#|diW(d!uXmF4=CQLU~{E$*;0QSQib?a%7NSs^A8-?byhRPTkf4}f+VUX zQP_C&R}h*{h^_O4S;x2i`M!5|#45V9N9N?kwO@3*m-!=?1tXV*BbP-ZmlH-V(Y7xr z^={?I-OnB}AmCY>$@(al^Euy?kL*Y~aKUKdsN^MkPe!j%G?^#Mlaiz3;TH|PGOMBI zVizOJ`PfD38UGlmN9w)3A|~B<3%FfTDA;uo%Wlzagw0Y1oE5|z9s_qHnEdu8!6dvl zJ{o7LrD-IJcnHAeM)$Tpkuz(=ex4j7B7j3yAC~tf1=FO3C^hy+SMfL;)rD z;2BI74wGR8j+=X9Wv?6NK-}a5(;pJyeN&lSv$mPe}{eD zF3US@8%vuO>_xs{CoFy>+7MiFd=mYj_r~doQxyc3yb;OCN7-`UMUI_SBO^fqSBc>>IVmke|#B#u#6p}KArw&K{RIml!%&vWq?yh z@dD{2_Nig2QtO7$_l)uiGs>HgF7K1azgl^$62??qEfIx^4A7Ug!llDK`4$gMV zO&V-ibYI{LWg|z6*;x4}3s2z;azSK#aCMebyCaDlj7>GHPl~K- zR+tjbZg%(a>=&3l&dVRm$t2?mk}Eer7L2HFes#BP^^F=s`Q$+NU%u;k1_c#vhoLgo9H<%Wv( zqXK~Id0W`kLga=smE0gSIa!m(a2hPRT9%yY^F-nL!e`b<#|?+;m(8i~JSK=qC-L6Z zwvxRBq>^Ee=Kx!eXb$blGYclPfy0))fk=teeTvEBU31Zyw3s@R`6U!3=Wm9#Y|5c` zn%N3ZZs~o7adV+bjgD5G&sWKppmc#jiwsfq^cEeg*jGs>#pY71F7gE_-4qEj&y-;% zW^=Me%a9M-*9sz3qx3mW`#J1OP&Thh=HEbZB6Ef8r?}rrV6bz>3x=lK;S&_*80AXc zA{0e;5WT5(B$S@;RivOY+=~`|L(K?lawS$_N4>IGp!YI__zjW7??t z_JEFK1?byxW#;?`?CU_?7oos`yYF=IV8t?5ZBI#cBwG?N#Hu6z_^@>3`pk|Tu!1qB zg0Iq%YDD+z$WPa(j{G^*>W;)Pwo_oxJx)LB8E}Yx6j~+!-2PO%tuiK*{3FG zin>_w%kT+xq)S}t%Z`fX*qa!I!Z>lombzhUcgTj`$f32D7oKXBU0M)1334O!|LvC* z#o_!9`=ouZvaF9EQ(NCM*%N^|+Ju=yavg_l6UUdSA86Ky z@qYjX((QDAmHwd^c0sPWL6UU|*;aNkq%|^`oIPT64Wq!u!mK}O+6I%V7#q>&DRO2` z%{@@Mj|7~;9m0U5fI3Z{YYVt5^bzg~eE{|N_7bDwTTzETTlT?lLBSsJK0$sUZ2w}f zsJZPGa=(eF-)by7k*A)+Jrx z(itcVjJ-pMP1ow|or=LgWRPpyxW?^7-1=~n+b}X)Wr>|s@4e;oY&aSQQQ~6i*y2?D z3d4(*zZ6h6mq*HYPgLhQe|d;XxjgbAzM^Z4Nvu%b=6Ze_Tx=#TW)mtrzQMWb1&|{K z4xY%A5(s(#hDLn-w=9i`Lp^y!4c5RTzxqzM|HJr}8{PCBl4OmdqhKdK{0_4axit3RQPU?uD-mCaXN$NC@cUhztvsRe8L3 ze2v!A!d1?HTtd71G=z^ocwR=qm2KAYPci%UEM(QM?y{Eelb6V;O?aGI_n16W!fNM8 zhNp^;lOa*HS`30|p*b}cH`)gk+E!SMNaCX>qZsk%Mx*N4F9YTeoq0*S`xq>?23 z(xLEq;eQ?spG(GL|A=K(-}~dF+rG(l33B1DMk$ucbeFb50hc#Xpy*I}>)_}WDMO;T$h@$J z%O1s_^`$g=)q%r}>{dp0>%i=mM%odQA5gkAwi4BaPEH=+z|Tqlu%maHYK2nSu1@Cv zP{Z1#M|Tt(?C5H(XI||TJtG~kG@yM57AEumMJEoJ#HA!I?29o=r|36XNQ0&2Fh)u@ z_sft(&Cz((R=Gh`09&P1@mLQ)1lYi%ry*`#PMiV1st>$>|D(cfUwB)VKA<|Snq|L( z1d_$CE6l_HqGUCY2cTLb+*tCCbDP2EYs>2Q|gsd4sclSZC#}(Z->y^ zzanI(k$GO?)W8h8@;#)d{scECli==w^Hciu0E#=~K}~VRESf2>(hReh z5ZncQ=#)68eRqrMm6#_|k*2o`=%wE{#Q>7Kx_xi)iiw z=kR9_LUUIdI91Tg+ta_i7$A-8?US_ZYvhdL>0Ti@?~U`1~iIKPqtTzbop zgWldH3&X+a?a3P0E;F|K(A&p1sSZff+fRO{TGpT5W}s}lPSF>9`YcUu*N{R_(E;f# zv`^F9I-$2mGT8gl+l9J;TQTN}2|mQZNhh0y)P=bhFR(NNO`q+Sm z=F}wfZ-yCMh2YTn4KX*sbChL|e4KB|{O>;?oxE2B(embkCiY7$pJg9|MJrq8thgTW zq91D>56hm+x5%QBjYMdWWSD!r5@k#a9(cM$bcWPei(WvIiu^lX?h%pc$ak2VzdR_9 z`OCz$qe7gMxyd! zlRE`IkUYJo^gq%@mFbkJ<5iWnP`*CxcU{Ke&yo%G@ezy!X$lw%7^RxpXiV9I8q;XM z(fr}hc%CpX#j>+n%85q5mAH(*3%f0@mGrtREBgFrxZlPq|1{!`SK(+`6(5t&a;8~~ z@8uTf_%y#=v7KW8xO0FHt)QSMqrVe|0IonP64ekk-}I+HZFpuFH~|IqDEsjO4-P72 z6Itn3#jI3}kM^PJXRte?nU!H1t5N&7FyGtX%$Z@27=>q%$b~cPS(xR@rs9d+ zvai55ZiNq*S>-RGRE9qjvtI1l&?aD;FpU~Hc$5^=Kb-b#XJmxp#|1m4=D~V)C|Bi@ znllNfshpBcl(hU!dYF2PjmiR2Bg6 z2kH=rV6>k{VZkRS#u_9 z*1&+enrth#2Cju`zZo0J!tm_1VYxMMs@m|%xHXVS=@K#Qo^FdnpY4%Z)9qPVw1NKE z9yw28T>4{%??%BX{ZTI01|Hpew#W_8Dlz5dC>RSDdu4JU>|E71$^0omm)S8tP?K|s zj#{d z{L7e(Vv`_4huNrxic;#awcN)vP|*t^rxM#BgbSA@dL!%osQ74w>#ChFehu)ZHM-n>6I;Sl+SoZ-l(WlQyViT@2Kj)^$t&u^#$Dd4 z+P!CRVe@x>s1~gytp3YC^}rl+m0#kR*Z2rSk=mg5GQXPG5`0CJ=xS*M*-Asm-dznI zp^jEs0bIy3%PPnFoy40mXfVyMzzfvWLXNK#TV+$kr_0TGYCnakEmF2>a9c4f){S5%Ci5K|iGrz--TCl}AN)$Kt=NK=``v0^uOue%hnd}_4NH?!&i|nlTFA>WmzxR$4lm_UNtYuzq z?`t>Q#E4PSH06@@dZFv$EMM_`l4lvjdXw6!-!f2{SO8U3M&}^#~WqcgzV}AT3 zMU6H8IADJXu@LnYr?i3XC3P}L{3+g!OLpBW3F#i)E64`VIX`uK#YF^b^p;d-w7ju1 zvqMzJ(Lvc%!66cONL+?@??gCQ3b(z<5g+T8{hDBzoua3mi`4rP>1`~LIL@I?g87#< z>&klmMIm#qf7!P!taOTYsUuV^`?I{acLAoxfU?2bG{!}XrJ`ZnLHI6f&+BS_XQaHw zPfW}EK6cJ0E7&jvT((r#Cv+WmaPyh;I9g7K8RVA8HLO=&A4X`;)Q7ywppMy1Cn=u? zFLC7l_*N=n*82iGtro|}y{_b07k%G5YIyJQ+)cQX15i7gMyo}El^<&A_;9Y>_?~yv zFttXMZ;AeFz>$&Bn_tkMedk~Lm{5BDQETe_$rsPRAG$rAo`2~AzsmgMC=x4*9Fl75 zH~%t#`6uRI3Yv`hmr>#u%)eufkm2xU=U?A4`_8|gr3PBY{5v*(p!p{R(vM@8QWnIQ zMWsF6kN)q+>Ue8sMX6TnEH18(FD8|EU0{r1^IJ>`IWb}4*-+#xhH%C3GOnN~>rck~ zmXl+8=ZzY}_M0N6r>Ir9=vicou-y}CXcYm_HHbqNQ7mB?_|)rOWWm@G16^ax}9c#VFgjXT2Se{Xy-RKBO_WR-NYQ>Ehy3?KCk{fdj+jvA6R zqFTWEWf$`+RGw^_VhZ%>RJx2UPL_T>LF6lu!#I15x1gCov(1SfE_1n)!jg^c)#V@E z7z!oktrq@L6Y(b}DNs*D^cCu}M!%k*xX<#}uy@ekPp6oW;zr-CsV;w86%{>`LL>ib zmG6;ciVYkhwF%wYqySNZVP}oAlg{rchfqloWRiW3Ua+=HGU6v-v$L5LirXb8w$Fc+ z46?o$bfsuSM?oyBg}6CTVo>lZwL_4>D+-}7HeLHz{2CWt0$^QIq94II*>ZsMu=_9W#ST4Du@la| zaU|A6jR3Y?9KXC3=Aa)k<8WbB(E=TY{Zr#mYJ<>qHok*&3qOUDqG?JfVeK^b1~xWr zqqzX3@dP}(H%<_O0mm$v#BuBhuWt|}my=_POs?hQw#H3iY|_g^&{MI8Lev`*0+gfh zCEtkkDoYAt7#X3(!@Z-jIl&rg>G27@4V8b;xS7n+DHP*vMODLXEo&o(DOOx14$65~ z7zor?0zu0<{?_`uzAUdVkK?SIRy7?=fmmIgA=QOB{Cb$zmrW@{$q%H%dF1%3Z+J+p z1jLNW>&d2{y}n^Y!NgPMsB_uwp}gMxvJ$#-F5;h>u>NJD%k^_b z&!*L*^f!%g^ej(PvW!_iA^=YfpUeN}oM%U>PRF2mSJO$U^M7an9Npi}m+x!kj zUXZmZGG33LQ6ddq=A&qHQj(_-S!u8%WvW22(L$w zu|4~wFF4lmZgu(grPo#Cv$kGp@y*0Ubb8_#Wn{^IOkzZVEQ;luEpO!(p&xi885D}6 zl;UEREUV}lxzzz77}<9z-dZ;G4im8g5rf0qc$;uAyfKr+st~QJ1Fby?z2J(bS48DBmd@ z(I&l~f#hT(0R4(4G#jJb$))PTw<(;n$gJ4xhLp|j#%k}hXT*;d*1}vjN!6n01J+Qo zT|mVPR~l3$0GlHUh3u;LW4NBdKCC~RwH5ZX(0e=TaJVXQ{yhtIBoej7C`Nn6+`tiV z%bP>wo*WtbiHR{Qadu2Of@*&|7bU(ooX7#iFF5;IsFlD{ivcqOeF~B<#y`&68Q)*G zigv(zU|lJ^P|;>*Ln;z+TN&y-?ffU-M7QCW!CWJsSijjUudB2(o0P+v^S-Mwb^ufuFx47Mfj~09 zP?Di1x#M_2tgSs3hz-fr*9d|QqL;6~pPKba5!ZTK^Mk0wt{?BO#Bx_TjX^Ge!Fk#G zi;I1TtRNf4Z~#R{*0QNGAdAHuZ_f_sB}$Ra&iB34EUH`bB}N=Su(l$Pp$Tex;dNC3 z%4|YL7UaO)7-7D8Tdz@@-#FTLg_lG_#?2l2U`L$AHtlTx7sJh%s=|x>n}{^w#3DHD zPrR+-j=nmv&@bbn5>jjLV5k0lEkZ5*JGbL*V-5iq#+A{4I*Fv_Zqr@m2Dmbx~V zNkETiaNjIeb!t$16+&@MUFjR-$F8SKC{0xV-Xq znF{?nre*2-I>EMN{)r?AiG+vfS6%*@cf~lxwN#%h6XBApgm+C{jZw;(;Q;>StqfBt zGbI8SbJQH#FLQuHV6xULO%nuJE-RFE8YQ^!4c0wr8XQKzf%gyzsr{|o8D%5JG>xX$ z2UU1|BgRyCN9By6PlnB~bH+?B%Nf&j3g2_aoGX#%N+c;pjDgLVA(10>Mw17ACRD@( z$>KC~6H)|goGV3Ogq}r?;Z4GcW=U1Ur7DCA@tLDCu)@lsn8g>hci3eWF+BlZl{tu8 zftvbCP?F8lbiA%7kF44Ok4iaIcyB37HALVUt=i#2WLl9WrG865(t;U<43(Bkh8ZTq zD8Qx3SE9`&`5*y;)Wf`^r~udp86XBxiU9(CM5P1>AdqCb!_b@*sGHq3ggL2%cPAJ= zcUch5MV19+SxT2N8^t0VYUNYsP|mJ`u6WeCnZ3{0`$DF7B7qMICAlEs=AG53#Ow~Q zuM5PE50&p)`b|;IWn-uieuf?P5znx@knF0?ZWCLz>(b{6p#FPF0ZX z%E-0kc^x&PUHpOGQKHrY)l_8$FU@aRU(la_3S048!oa5t(jDGvw&6_X+x+Mri4DJ-e7ab24+K@w*Nzz2V4KS>skm{r5599C@@l_w#% zXq;eCPJ#uI+HlwBJfyxtNVix;`{iS`SfOmg$j7;hDEY$aFjAr+mJML^9mu8(tZG?bJH5WGdQg43^t_DoSQNvd>MjOY zmt&O;Q{xLKy#ajKgv2AO8B{VBwlcMHx<2GFyj97Y;Vx7d>y|t&gKff$L{5lIS5zlv zaCwlgvdfX=Z7O-!UV>5KHhdBVQzMU&U0wdn(&=XKX?-=#x`5Hw)l?!ic1fX-#*C75 z#pps3=k_aU$vR0*(y>zMs99~uI}FTs6kQfX(NCpHnL)Sc-9h*M9+B+m2l3C@Wj*e8 zjYxuu14%0@gjYt#f1z5`FLUZw0i}|8ukgXm!y~SPfhUteHnASq`4CoNA+78VXK#H( zr~m-EvNDe|z~kDbmgoon+x@Y2$>XWcxS%>Q{mXa8iVe$xVa&^=530+?e)T?BvEgRb z2O+cw$_ZGPh&Y)&a!{1s@ki;Vv|Q#Ym}DD4Sh9P-8Ll%?POSB|-o}fepI}%<1lkP< zNxkJ=M)FZjr?a9W97m2}J_MKsqM8U4FfWwC#41D^82v9-1JYX(Dz9;%iB8k;q?fJ{ zZ3jtt3i)IbP=HnLYkZRrMoAGuK~xPaEAZ`^%ph_yLD7G^{w;*Bg;8Z$myNWY&eJC= zrU?D3;!|eQ5W~U#QO8U$uVr~w2Qu!*&84a6U3wRmKf^$lm3*&oZkKp$3nv$GOIbp%VgXD00S#>fc6&O7rZ zLiNkkfISTZ1eUQ~z;va+6e@px$#Q<8vmmQfbPRt>SF3yAm1ds3)Yk^!>yJ)VCcJ${ zWrIv*$OA~@F!xkgVTnYxpxWM2ZR0==-P_Yhg?{IkW{k78rgo)SY8xOB%J)EUmOJGP zn}%{V%T+MKu4yHUchvNhn$s|OmGG2llEHKqjVLNzoTbh?`LQ>xQ}%5v*g^XO8Q0Z}`cBulY&WjmG{pvhf)mg>dq|PeoR#{=M6ct<{&{s@NCDicmqsBd*fU2=dZSuO9@WNMV&6_XQX z1|s{X^2h!O%c0?yHWuN0QlTEzC>j@ouy)LWo>bX0@b> z{NnYUyOVWQ@gZm$vA_)@^|id?gHOpZvWF6T&fO_&Nrfo1Qu?faLL6DUWP`{eYX^`; z&h0CUaPQkW!hvM)r>wr&8{kF`A&;zRyE!F~F!+?*Va*PHhC;cg_J?$|c|P@?^mFmu zJj;5m`>hW+hcLcEz)6_{=*JGV>fky8lGPI=&O;HHTtXsL5ty=Z7@R`@GM2lN`O~DPMD9uq+-Z3) zZQlV~<1ApaVU@B*mTee_Of48m-At@elI{-*_=yxC29RtREviwfmr!Xk{{gB6?9PfB z4dr4BONCM_6^fM;w;2V={1pOOXGO8J5H|^hft9$j;rbV`Tx3W1pbiR!t?JXw=KOI> zvs@qZvfDk47;@#wxmM(+030GNjd73^qkX!Y_1R--(LvUKWfLLREUdV)^TYv@n(Fu< zs2vDn+0dp?)n&uHt-oU=2$`;}O4Mfs{~}Js!)4{()*pxrVzYm{W@vq7*~#8pF5*LM zU#y7>HruQ0j^3%UeQn-<`w?IH5Zl+?l-JUIe3iYv_q5o)olV1Ay1hX~0(y^)?b|Ew zLxPWBRqN>;+0vaI+xJ=3(QUz&w%j0BP*&Nm<4-K;{qedgd=w82B|_{!4C}o(h+oH| zO-Zh7Wbi&M4)@{JZ-cPQ-b6L`5VQ4F41}W+x5oGw+c(8~3)*)NcuTf>*F4+u=9Km~ z1_zT}_F7U8ZzuhdtyOH5Ww&<^#wLOd&s$z2Baa@>ji<7UV{dJLXIOp9JAwM(@E7X2 zv$Z9A(4$Gfu0OH;QO~P{!`tiQLwXx2C2~f{9%hw4?QKP2Ez&z~f7*kIRRRj&$36iX zXeSK+ny!{NrjW6+?3>XXmKB&{@rfmc_ZB9WONNP47G4s2151G*O-CTi_O97bKipd% z&y!S=CscNdcf~dPQJt2b74+WK5tJPcbqBaPAAsjt?$*7htMUH?z}Ic9^$SbcW(kqOLMgh1L2|!N)y? zG*DqERQ{^B^$Ze(?8)4*azx;)-QI`2^_6(08~=!ByvLK>ULWL``7LtYsQ2Nu-iJ4| zcMn_MBUl~Y-dhk%ypgHL1Aw!b-bql85Qg zG%DEMGq}p$Ud6?a!Pthj-qK0pDXM8~@Np#uxA%;wN>oTxcki*J9UXjJ#^9rX;Nj!W zKU^Nyf$OiW3U+;(SJZ#M2&>x1zj)n%u9 zSBN(+!F3>1J~-gL>q*&`P@#mAn^9a!a24NI}V(VrKE#R-#qqvC3$lTvv*A6qXRiukjuhE84k0 zV2M!-G_gj6nsstr^jmD;p%yx>_f=YXR=*w6M>tOG$!K3mzxXtLSL>}a0?Xd?a=ZCP zp`hs8Qgm4F=du=*%WA6E0z3DxCSI7IcJ615?$e;uw{HDy_u4G+8FP~=(_MU}el~9U z-EXS=C8k8Ml)uDVSjUq28z}fG4*U5qRL2bi{u1}f2|2M-E$>tZobFKRey`FgcYEw_ z(FLcLiA9$Eg0qb+6VAw0ec?@Wc;1-d!{rtCi*!2AT|l$MmzNdKJaE*JQwS0aISJ_Q z(p|;!rw$aP+ozZsV^Ry=*gwA9xHIhIUvqC`1v;%v|C(D4^sl)WxJ^S=}()Ob}$=*yy+`Q_?k?A%SPBplDXNClt7bMKUgc>Y9!Wd7y_ z;<-au8oCkuj(n02$^0$+YK;wQcJ51*RL_>+g|A*B#4E*EWFjV6{>a7LVAJGJ=3k_; zjC^-L39zU6+QE5___1A*$d<;-u{_o-{5R@1_>}>?D9hxCfBj9BOH`Vf42#nLq_!=u zAO8}PSGUaI&Z=M0Pii0B4{>GceDEHD2w<{Li1&Wz%!lE4)h$&ef2)ko`AP6E!aRlJ zHyly9at`wB4STqo{(YWz*tu6xcV+2>D+s)mxl0J*xzqVY_ZjEXY4**a{jh*lm>z!a zIyDZ*C!9_i-16QMDu2e?`YH>6mAF#&-HwnnJlWNBJ&KL09|}*&;T$1l%vexcb&EPN z0f7@{Ig$U$=Tg+jRs#BMp13^ruAD)U*hzbD-$?c9>g+P9gc_~#7unZU4X=K`J}qB( z*DwI}WR{HIxmJ=SE@SDJyTmPdE4y-!TqKTqSS}LZ;cQ^5z4u5tka>b&1kiTSggwgn z@Q#(Rnbc-izb_pL5y*@Tti%Oi{K|e=^d;J4kc=&B2U&3q?ut74tLL}U33k;F(Ft+? zViDt9LowzvB1I8Oq&I}AxVPn5!8wi52Ws-X-}xgST=&b~Ths}bvMZ0k<(?`d=_G&W zw&X}!;sw}LXH+F=2`xB{CZ|5~L}e+z%l$KqHErkAPp8=4$8#sc3WE6_xt|`A@a>3n zR-Dcf56qXTx5egdhI+ffyiHPXSIb*$(np`tj>x3y_`HJZc)c&!F_@iKvmu>-Cy}Dr z`=hN-eedyk#RD&$UcDokzm#d%^JjTY8 zyh9e_{5PZ=;(O5wSK&QyFnxi%RP}xcFM^@?Ob%u0xz|y(gZ^c*C@&<*Wd2Xcsg5RA zA1}Mk-BYBXdzJq<6ad|To?=g2eWY1WMLs=W!#`ct$AikJGW+})9+V!b2_T)m4R)-e zZivWl-r-4WaRS7MA&pGh(CodU%)xnwpYy#iACr={mUS-n7uZbY;WH?m~Fhf)!DG;y|-LSQFG6cJWOQaohrQ#j}4+- z4Z;e;?-g}aXTK<=#Ir()e-m+ob*%CCLE9578x;L@xV+=W6GRVEUH;;Y>}aeJ#f6nD z&590ZgH4D-`R0Xh1#Ks6zXBsw^j^#7-X)cliRcHxj_jSm<@+hnv*e^lmd9c-%lgnZ2`eWr=Y5#T3*#EZ|-9WLtMmaAmeN`)MJL z@O~}p^4Q*Eo1tPa2W%Vv0bf*|IFBvm0J6-(ZR|~OBhR`)v}!G8WNcA))yFILb8kZv zhvGe<67G3;Lhy$181Wd8wKx7fl$iE8eoC8srpaOjm!ongrX?j}G(~%G5-=z#QGT02$10kmJW($Gpd93-lBaiN$-*ygRyLH%lqEt$ssF#)6*m>hkpq|0Our+An?0rp|uv!|Yo=%(0K2F(Bkc>FWCUMGPU^H+Q2Xk{Ct< zpVZJ|9Au1uvB9#@QLfFBUZpENJwF0wxGEakv+#5EC=8ju%6_`CXmhY-pLa<)5{H*w zmmJIYsRo>y?)Wz{JASQn{C2nFyLxkiZExgMt{hI*Y7sRyg^OT_@6;LOM3seV(ENr<~#_c=K%@;H4hL-|A~3f7adv+A3zi>qRU^=O%KBEc>?cfq<+$PdV?D60+(&An(i9%ldS{ zs+SVS*^f~A*+lMz2qs#dG;-nv4f4U26Wtt2eo&$mJirblJiS{Q&vHg%K$(_Y$Ew_! zlB+JEpZq}~w@M-UTzA%u;l1Nm-xl!$`2nxnY$-Jr@2SXh<7fDi`L_@s zZ-VaQlRMs25ZK+R^weCz@_k~AeS?yOQd&&i-aT1T49!(F;ZAIl)YQhRALrs$o_#_nz$hm17nCeI$33O zjLua_)uOPQwJx|v0T~%4zL=BwpHf87``G(=u%vk*t{tqB8`g4;?|sA_Iw}&BO2PHTJh2M10F>=QEZie9z8DhX{>1mHb?lqy;k6jPL6$g zPNXdM>DAFGy=O`6Y2G!vgoUiv@#HusawPGQvGUc@U-M#Ud_T=vINZDDYFgXb`bzYE zX`xhd7*Xickdt7@sm3^Yh_JGcI#_l08b`YXR z%J}lG;UMB2Is(T7>vm_yBE2!W(*D!P5gmj5Rt4|g>R2SHzl$FuxQ`HC+&enW9=e(cM@lw3Ez z%PQxDP|LSf#B~Ls_~M<_@!3vw{JQRHt|ksAPP_Fw+0PH!Ub`I?U}RjZd}Q?4*y5~V z(GkM$bPOKWqp+P^CyyV4JK0f*l@E)KCe_I3+it3tiQ3(sFxcN8kWPX*+XJW3bM*0sN*|*L2i;vJ{c(IAThhz5=TJfCm z#1$a$dY12t@!K>s*eM=*T(oMBVwXeUx_8dp+1CWGh;@y28V4}IUV6W%+LT451*+J zQMxY3ffx7V&)kpw=$9g0DJLr4H9v@HxYtShoYoQ#oWOva~6A|ojhS<=?~hNhb$!!n{>+9`-O z>qB3C^zK11Wexp)b{2=WX4{5JH_YSy%wkv6j5cYFqx2xAj6I zWYGJ0D27G_$Q(iAaW}xzh9#Gy;Z|f5zPM5b@Mq6U!<$cNv zAEdki+k1SU^3>hFiIKfTFV@V6l@JZ?O2Q39M|Wwc@okJ%3YWJ*l3z%X8w1 z7=VeN3wwwu9($XCihoWGhXIR^OX&@DR=l}})ALz9%iLPb`#fEfNBS+JCT}a(MgsCc zwS9c>+Io&KfU83&yTX3YH9NH16&FWdNkO6+0Yvi5Q4Au8X zCZ6aIJvZ79P+el=E|?^+F;F*{s&abkEQE1gZ%*%pbix6Jb63uRZDCF-mv@FYPkYajaRszLlZ1kbFpob3iU<;H{X(pxo>0Ri%lVG#w;4XHI55Z{G6*xeT|5c|m;k)U6`$rqfDa&KMnIC10^_oH zkSsH3hyEZb_*?ATQ&Av2BQnYi_F!r+M_iICjBsOt4T!W@NN*pD6UCZ~e<**+yFzWt z<`#QfeCy8l9xk6Dc!NSM(kuZ$<|(SRZO9RZs4E{omgO% z%`1-HV^$Kiq|Spp%%d{lykTCiT4%-Q@@a17r&N!*`dvX8_XD@FGZn7^TfE251xe?Z zvK$=-H_sD)414)H-G>j58lFjsZHzxH2M3h%eD}U|IGmKp(E=;3H;36dGKPC1&0I|f zu!H3C|FNae(bnmF49BnKvJ1G=W+e^I%yT^AieI<@&6DCgUb%-nmc*4LF2rNiF7M5i z;)aP6rm(WYHP~B%$@3|~kx|R_pY{-M>n|WJYU`{mGKLQdk$El6wJdF7?~wYWDr-{+ z7uK%~MRjxp={(*Q5AwBlE>;Bv@*bV-ytND9*a$>dT}Dr#UYf6#*mX%*2+~Dg(Vrus7;A7Y!b)U{ROG}|6d8laY8vc(-Dsd-$`dyX1;bna-V5?#i~!z$W}FDvaGA;0_; zhvVN4@W*6XNavnManiA?_J~9vb7Z(Me#P8_aw!N}@vgV^msH(T4bxrC-sc#sw8e0L z2r!geQ9e^=iicfi0p5^w%s;)Y}=DH3~q&@wx{7790R> zD@AEpbU{iGXz6p`iEGanTU1M>qG*Yfg%i0Ia8K$q!lSg_Re>X8xL{FqY=YY zdCd)0XMimz7iLo`;~?@L=eRN|awo8m9c_;&^OvIoco5)v&CBuxc4wx#Hv`^ctMfT!aPJxmK^``eG0p&g*$nVuGQdYOz@sBq!|A55cox$%_2RZv zhuCFnYq}6aRjN|0cfv@8h5KAOrt5BQB-zKW=X({>NYVn=8KCITO5Q zr*oztPE3Q~SVU3FzNaWZY#y7Bb@?47slPw7zob4X`t6jixw*hAO3{rv5lT^`gI?so zOH3RW$(eX^w2Vaui$vT)bDsM9>{y@2VF5THS%6UG6{FZY)8p)rGyG82QY|l-70Z2R znN(j?zqmi?@udcq)0dy0d0zifbx?jDIRu`9!y37B8Df?)(XR7E&VoU%L&yN6nRUXT zLvt4eU_My(;UM76E+JYmx^WUBiQw#s|H7IhgVX?W@zp(R;EXiH3f@eiXA#*y6!R=| zUO6G2rC)c>rgKWzee8(TdDr+_pN*LN!!p*dt*l?HA@FCcUp4Of)!zCn>zDc-nUG@8 zj>Z9NDYZm@qM422w1BiuuVqSLVgc%hVgqk#|HQar@q>jrbv^4lX#Rt8v1>BYsLp!| z{I5BY9^o*z;JQ0+hlAFQ_anjpkOCmW#uiJ#G{3?Hww7^@@!QRN1?*xENG% z#mWjE<{ip-D*gCDt@PuN%J|K2q&MTl`sM-V8%|b18oTF?(kRd}^MRtBMiM zlUqpH1%my|Vc(!`&$QI8)p_h%JrfpwK3%BAU4dwMD@!My&NYFFnd}oiL6Wf2j_G}( zX+GzfugOrn)YqvCv$AoAbSZ=Bya0}ik{5u`e!DfQD`e-dj{)ET{o&fiA@L!mC?-p+ zr>pFb)Mm_?U2w6HKI))vF$FRa}a0#bg(gy3Ui(S;v)2!fT{S=`-gNUO}MOUr5`UBIM)uFzf87n^{I;?YQ zt;hz_pu|jIc+Q#pH$mLYLaS`1Kbix~*l}(ZH2*?0zo79*VdclREJI}E;#e#;RBR`_ zw4oBR$*Gh%hECxBKnv3hVA-+k%T~_gehj^=I(M=UP;K8xC+t-hfd5q>qg`+aqCrN{ zULz89ErU43xlX5qtUNFn9OqJdve zB@I1IuB$8^UnCQA1`~4v3Hxl|7CNOT0SGwhoT`eHE!_CbVn8hwI9JT46J)cdR#X^_ z2mw}97a>h6Wl&@uXgYwt!!++hXp!+C)5F_3oZ+U#<@2R8RL5+0s(2Q1zb-OUQ_IO_ z|L`l(`_c5C7X6V~yeobxD7J5|vp~Dh=VqbLw5hd4A_U2s-x3fw{bz4?*7B@DsL&vM z)98zpJ^*>?(DYi#OQ(yx#JFO;0f(~Y*i;%l!j+)ZLZe0xalL;}uRcgs{T3gV%*>?{ z$tp-=GIfM`s47ksoEIxa7COQs{}~Nofy+)j#pF%oF027R+|V9BzktBcU!gDrO1-4i zObpud8MEit)OQAJJrXmEzXtwLe4x!qXkR@C2;Fi z$(FBF!FL@U?9{S%r-VJf3Ky^(qvZD4KDY zsKm&i>ZS@`oZDUE++Px}V3brKaaJJp%fWup>{irR@!|1`TAu1eMUDb)2Bi1}6u33c z)vrn0QY2NcI!32r;5-O?s*hwd?Ev_`Zs5ZR=1_noay#Htu$4Uku#Q&`3D_6Ir^era z@RfZP_$GtmjtcZ%1Hd@$OTqX*i@(#=5HR>#A(jDuo(@K(i@jC4j~Bo4g{b@=hOc_y z{+0W04>9mk{o9B2&>l#gA1DUwyylX3^Pzn67bNo^4oY?No7E!I$rK8dp3ZKk z%q2ylS(RZ%0;Q)O=dQ=!Cx^O}07j_`rEjzI>*GjmPiqdWJT-gw;25%yVR8N?(3iyt ztejsPD}O&a7C!Fr=wY$NgZ>)L>zKx_SF||o zh|ehKtT+ZvBU#^B;paSaqGh!LqvZh!I$JzYHcgCM^diur7J<%|@kET3G>Mi{9<6vw zu>_qhvVp84D!%n-fE1b^>Ik%XIwW}jfpJ50XGcXPkW^S%SsfKu@mH7C(IRUT!F@Wo zUjn7p71a4j5*uc+0+1fn|3&Zz70Wwyjr(g!D8h>1B zUaoRW;c`7+L(g@>^d}VJV0TBdez_%MpP!hlBN{wb7Cazri6 z^Ncu{SoAF{TiDi#qT^pQF1E<;@wWb*evO^O!|OZlCDD&(qE?r8roGU_b8?hM!3@p|M4IwBtkBgz-_tMk?=M8as2OfW+f! zw%S|lOJ^n5I^RVTZ_PdrLNmmQpWT(5HmhavF`lJI#}*IuMDt^dPw+&)P8l7P0f*v@ zqX_kp+m;GA?|US7YKi}>{O_6sS*p!jqW|FA_xYv{6mD|fK>|*~f(T#DOlD$f%BFc~ zt?y5U3X*YV7Ev$77E2Q}VVSKz()sYuXLn)mmdKxOs{0=0_Fkbtu267IBJxNR86{GK zd9s>V0&9%%An?9Xp&N8QX}HS?ctL$B5g!p@fd0D9FF+TURU8u?V#pt|``FTo6QUf& z%Kxn?XDDeqFdP;-n<;9k0dLk%*NDIl%3+qB2noq9-B&NggU6`8I*#I0Up=Zs$W3xU zdLq@lb1viQ7xFEUKTbgif4a%JQ-67tSS7(K5yLeq=!p`m?vlq8p>ND$pfzi!1OlH= z?Z@{UI(Ja80_PNpQdq8517n)PH79xUf2*r@hLS+zx=3(cZ12rD??<|SHR;}9vo?kA zVj@-%q4C{OF;tBTWfE~!&%>lNFdh`X_k#w$TS+`1d?QW0b4l<;@I6CGg3(}q_&y_I zK=_XM67Zep!uJlk&H>@O!PL8f1YZQ-nI_#&N!JH|*B%VMg`{-xhqEM3PhGY$=#Sl0 z>xqnEkFHP<1I-ICu)-uo@@;V)^rcCOQZ`S=kIY_Ynp~=Gqcz^@+$O^gS^YA_F=6k5 zbncui@k%kg-8ou4=ig1?;v*B?O%EGc>efjtE;c)#N-GliG2-R*DI#6P=^xct6*=4; z$Ly~Hzq5@>4UlR+Df!L2=5na#J}WW3!1?8K9OUw@VL?_(m|J9K%eYsW`Z$qs_ZMMw z$TyFCYW8e(c9BOX?=y${rk|WnKO1Uy$n=M$(?9ox>6tfBpxoclGvXiy6ueZn=-Opx zNOu(5d(!7;ExD1=9&u(efAlwDcsN6OV_x~P()HEl1Zw6|qZ1KsnIcg6RKesnu*rh-J#(q#TZDN?D6B3us_d_={=RNXlS zZgfz|Zu`P(kuf-Q=A1T|l(T1CYq3kO0DCNp0xel?Dz0U2RVJoS=*RD@O|Gp@1RAXC zx*DwP&7rt;cL+xC@8S6E3ltbl4W_9V@-Qe_vA~{zQlp}wd`9!K>^OpWMI>3VMD98o zkREIA^udN?h+LfgJ-wv62*5O*gw`6 z_fK5$TAY&*Me|EPHSXBT>izWtNPIb{EQ!5JcAPW_VZ6N$Elp-_6zl+~Hef{x!TJ|CFTj=7q z4*UjiZO<(XGVJdc6u$+E>;5|^?u+03Uje^=IP1&d_gkc6{5DbaK=@^oE7L#8fb?Z+ zzwvv76q$iv70>uBAzk0``!wX_5cK8L0qILE^rcoK`T>`|{CCH)5D{6Q3d~maOLoX_ zf0Dhie8w@$ri<8CEJU<4arRJaHphj^&SZ(4jbe`Llte0Xoa)1*-NV_1misV-c;}MF ziWiAYUmS13Plc?EvvCKAMl(A*drMp%Wn)fr(+BD|?`647Tk*VJEEV+CZ@TsmdVhKZ zOKm#+?+%%MBFknv{jx)*zn*0CO1CUn)PpcGu~3%ByzuRa(=45D*Ni0_*IS9=2;v+z*ZC` zP@O-0Azul*gq-2|0K454Uk3s^_sTzr($IT5IyFxccV0>Sy6|a^W#>#_ZUCK?*PAOo zfW0McJ1y_;N47jd*S^;~IQUnxP{Lx~TlNl$cpp7pdY~{DtJ3?3q8FNpO6Gr9C@+rM z+q+K{Ir35!@e&bX``xhJ9p-#}%X@j@@{b!Y50y=hd?>zl))E~m8yxwskbPJ(|2Mp` z`z8bE*AfvQoP?bpnXgK^gD<>zcu^^C<~>~A8_f-ucSn8^wtFqRxA%uu%jZckh<`en zKeI?mOXgoC8RNN~538VyAU^3qeyhZOV!Hr)%cSq|-t!dCC2c($3B)1zia+y^LXy4X zKs3!F7ih|TTx02CUfDh#p^=mg*VD`C(foNb01_k5Bk0UMjWm+lc?TRK=;O2`|1_Oo zH}E=7^SLv32&o2!2<%-9jk`pWn) z9bz4p8jB0mSk!tq&hFZB8df1DUhBm3=l&8aniH! zn;g))7YxV-d|q;^yj3J7J@_-6{EV1xTl(Y<8;ZzmYvc=6n`{zSLF zA^aS=f*ph{laAvP2vg4U9Gq2n9vzzF(WIbf9j}TX;Cu#zsr1n!Nb6MSVKGEm$Uglw zM$2$;?%b=2RUVjfKjee>*oDS&Eml1D-{jrSeMJK3_3z|O2xdIDhEJWjC-Ft9?acM_ zBm=lJ_Z0J_*UIbKWRQ=OoSivYG8)t0?U9%NTnY~7_}z~PpChZ?k7WEcl+kfSG1{`e zRD>hORXA?>E8_t+7HfQ51gC~pX*D+pi65E|Tk5(1a);%8=w&M#ccQg<$t|qj3z~ga z(d)t?)q%rc^2J_94mb$NQnWa{Q?j?D@KuTqUF}ww;<0GJkV~9qA()!-yrFb?6xY*B zwX>Al>VR^emz?nPlj!XUKTy9h_1ma^FH*l#`K3V_|H89_6V07q+3h&92#l@rK3vPf z*j5nAZWAY$$JsR_!sX944udpjZyh8Q3ECyJOEq>zIqVuJ~N#hB653_7` z%-SM@l3Uq4gE!vM$l)QOdF12JKxV#do$s@nL+49Q_{Mk{9fkZd&M$*5_wdM3nN%aJMIi3y>mXf_5OUdUj3Dp6%i6XRO&>;S-+;&0aU%9_vGG z<71fP9x!irFx$(ms%wJTa*g-h;q0z(2~}-SZR&a9BQ%bw^+tG~1q`BQ<9{J!Uj|?w zsx!9S)K!6pB#zK+4%z$EJ>Zr06*-mm#W_KH9dHfO{y~E$wgqEv)>nEfx67;>8y27S z;+)4~n?@|=)B$?6?xhVBmf#?i5ek}xkRKGDY8xvV1y9gE$`bFtTm!}3P70(@_R9jI zvk{8d4>F~^I&p0#TzI+2fa^X{g>N;>aUZa>I!Y}s8Pvvo%#b%){=xR)*zsW*)72%f zgyD+|!bMxFz2`nRCu|=xL55j%`EyN&*9Vus>DgJG_>l+eH*uB3*XU01<{f5gu;#4y ztxHbGQDgORHCClI%f2;02|eSFXQ1k546gk>V|kZ&?#IGX6T1y2Hw1{GJhEkue?N1a z`;CuNYXCD3Q}9Rib$>?pez_@F#9vAZ3i*0v%1bwOi5@ zzN((@&*gbyyDFzHhv%K!)N@R}=Lr0XTkGVxRF|WkPu0(*Qg5+9NE&(m`T415+VATb zn-SNg%M~BrJx{f%I<`t4|915Z*X-#zyHw@Z@O7k~u^o;{^b43P8}N-eanHBJ@JP2v zQc1%el2ZbyPr|15e8w>g7uOOJEg0=-)$MDL=K|W4(eDA>@4l8f0s1}h07;yWkD+8u zq!YKUluU2Q7xTPLKTFDElf_Y=G?@LC8B=hfM<9QWu22w+m{A$dd{n~y7mis>5l*hZme?<4|Ua2cj zAW7U>ASnIp=svhnIN9a2I^1OAXYKA&1V-EO*x>F+Atspz;nYheP}7}X2Ie{?ZO`VN9Bto{Sy)Un30zwc9{ZEcNn z0p+Od6Ed@3Pj+{1tMO^Z>-dLL^eiCwyX)|Nh&Stkyp^BPg);2A0***hx= zSlT4?5um53k7uivT=6l8$b_E$c2RL4d`AcsUr3<^X_($cYBn%kR(lATdx#q#8lD%J}LTD;P4*Rt?X6+ja2*_9l_d7$F<6 z!*~q#f{Aza;mY(kcfpmZg55IKUy?3w?|EOcJg+IQ=c>%|JVLuadQ#D*RRU`vDi-SL zmgiHUQ#?1wvtK`}^y@Ry@72#L{byrU`UR4Hr+%*CnfWz{$}{*yyeTuBt81N`{zPq> zTIr!`zU&#V*vo}Bc1kF!2K2T5Nn>HjuH;YFTR`sdT{J&$CjPfACAa z(`{Ye{(yk}uex~wLD}+l?7%!dSM~W+tjgz8YEo(?|3nTD3s)zCM=DD0_={IVld|l* zc=dSaYXc?f%w73iCLaI#XKz{R_e2j5+ttmLb`_KLVuogQowFQv`M|2;)upS-iY-cGC^rkrAC$ewrlOklw-0_V?2T2u?EK%_`ZjycBt&&3jin+joY%CUWl) zYsq--C#z(m6yh7#?{B*Ai}d?O{VsI4Wm4t+9uGc=bKg~QvrrbsbKm%hl!FyvBd1%A z9Zm{yrcvyaRVS0q-&P9^kk?aqRogGmjD=Q%m`U5n=;Ml_e-J7{9-s6YkK9AlL7+Z+l0UTFI~2iK)!UZNg-GswT*zuN5cfSc+P1s<<=_Wkggo8}D@lBoY zXC{o8@DdZAV#4>{(CL0>!s|_Vk_q4L*75h5@DdZ|nXqezj=#x-l_tzF;oYz6_^V7f z)`Ty=roXQ;;YB7q+=Sa-HSs2#ZokZP)ou zG2sO!jF|9V6Rt7gUK5`4lFqlxgnu^SXC|~>*72<-e9VL=8F;^ELU$YtGVnb0qR#h- z3IE-M|7OAl6JB7#N)wiv@DvjsW5Qu3{Nx2)?oJbKH{nJT{@H|oFyVtHTxG)Vm~e>+ z8%=nv2`@KcjR`FijyGYR3EzHR!|}2SpD^LQCR}2|MiVxe@G28tWWwntoNU6gO*r0! zhnsMO2?v?*qvv$}jtO5j;Z_r_H{oL@{DTP}G~s9+nXtixl_o4TVWA0+GvVPT z{D+|fFPgB;guDCEhy8}$xZ}hP!#+<;wZw!z6Z%b9?8dtpOt@-lmdba1l@9wwtJm<` zf4)Q>(ARm`z3{Z%n&oL*pz$W(2l`iR>++n+zU8jkr{9Y|(c!n}%$w6VceW=w@49*O z7tZs~X>6R|NP%d2%JA2Z&hDc<=IcJ=~^XX0Vqm8rY)X#7H_MFq_ z&54{5tgJY_A#%g@<0el$Ln;c-ZHmmD_iYR``}`Z{pC%Z%29PF=n|e)CMABY3=bFaZ z4gQMC#<@4n3C+89PP4zFsK_6z38j+Hxwi6}$ec;&q&=Q7F)E>8H|rN`;s zkInod!)pE>FyHULU4Ji*>9EFx3*4|pe=j{xms8WK-`h-hs`-AB35!?icz;}no?A_N z6Z&lZUTf;l*=^DZO#JON-&ZH}_exXlWVil>`upldI&|Uk+@#;nGU@umRcGRNF4pP% zCf!jc9Baa@rv86q;AJI(tl6V{lp&4dl6 zywxVXo9~|uA92fb>E>t+N5F)uO;|k2z-Q8R_sh4{#CN-)TVB6>d2WB1_!<*mcZht& z{qnUMI_`$u2dQuC4>f*Qf3D%LG5t2(gf-@Soe3AX;a;8o{!etc;4>YrGGW&bOh20R zdFI_`#^u}ZSI=uTwI`oXtp*t@R7S@`6^SJ!d zxjLWEg#Fv?nDSk?-Oz>a|EVx`iiTrVkq*00HR0EE=$W9ytzU8+eO0*JcDZ5kiMqZz z6Z*y*c*g1QeiJTm$Adc$Ch7RqChU*T=6iJf0@GjJra$__>%!rN{o}vt`~Alm_)WOV z%!BS@_4i@}&m#wc=d0G|!tI9r^RIU2r3qIVeAbzFzX_ZFhx)reJO`UE?tCjgQse30 z?>TZxNlD3+r=JQ>;dm#Mo2x!Nv8%`B-g%^~4GaE~mRHbmdiMS`%TuftF9m;25ah;y-73q-Kjybesza2P*F))R2;H#N#?$DPjL~62JFR z`PKiV{i1~Q>sOUu+AArV*QC?Q8relYQP9gjiIH@&))r=zH=Oqx-Wv$zUuL@IN7Cg< zy8C&rlSKS;(@EIB-cr&HRBz;A-QK$hhmx<2&`&7;-0}pz-_Q(n~tu0O=(C-apE({-^qb^rhzAElNg4P+F`F{Vs_D*(APuk)$-}B8kk1Nlc|5|Im>s{}9*JZD@ z_g?EH`^V&o?;zn2DCfyj`<+U>!t+7#tpzjto38IUp#RoMk50lNH>@jOyU+FUsb4N3 zoM~tAAMP73Z-j7WzUmJLddK)?6Ar?cX=lv?lRaa6rx8vQKI}#bq@T)rqpCzF?llyrwD7^Cg;gh|9a@LF+N8>!b1+%7@s&c`S@h#D#Drl zO?(9zd_lq?;^lPRYp2`xD`cJIB?*Vz@QL{9v+yZ>u1}uq7b2XgpX?IZHVZC7*4 zZQI5_QoMKvkGx_n+uAQL+qNOr7~^T(wy_6}m&9wgXUfkEkCmQ2k!I|=k8uu~$mvSl zcfG^sR~pIioZf>war~29zYE>Zxhzno%Z!V|GYlQg!mG4tw3+gP??IQ&fN6)K z&=TlGt{nd4tKhGKzw^Dv%iKf!ku0)?h&xqXPNe65yX;de^QqeAF!GAAOL_u(PjoGk zVas~L+3cGc*O|8S3E9lwK1VX-Rl(;uKi|O&zG3(@zRLOej%M&3n}E-}Z!90l2>&j- ze#IGl_3(MlpKmyWFA1NZ_mg#^uUJ z=f0T1*PS7+6TSi^!1>G3nZf7D%jCi+MWA$symt8f8hd<4GWZU|=d}an zEk4aF3o^jj0+xc{g)H zK8>ki_;?qSm9Lvv)tAOpji0=;%gU#9llU~IYW(D#V^%&dQe&#dPu@X#QKP6Bt=A+^ zW2(ka-pP$#_dNa>^-c9d-W__EM=|-wv2n`ZAM5||cwQw^y@&Q5e@*cnS>nZc)ED3R za`yXAWP<$EHmiK;2|7-4xBAkA-XAb~KEN}VEWAqK*H~p%`FMxr$nyW|M9wj;4I?Mb z^Z8NQo2f@V<@R#(+qsJTvN^@J`}Fg3h0uS5bi9*0F6pre@>!da&j@^; z^Xt=|!RPU4+zb2i+dF}sRbNMaGEUW&W7-%aTgfiGGxV|_MSqOilG+XLJV&p4o-{U+ zE^_|zRr$)GYZKLR1lgYRryt5lf3kKmQJYj9dd@Fj_3C$r;Zxs|^Yb0d;G3wOI{osW z#$<;6Jm&YyOMY-H-sWciD}DKg#;&FQl)W7%eLPAzmV*9!jCy*AF>Qi8JpOKYJl9DY zFXY$rNJc(E!b|?ymih zsrJV^Rf!(wIwr8=5?@9ePoMv@Nt?BJI?On&9) z&pTd^eH8sMDvR{y9scNb&y#5*KSzjkYB#(i^w>wyAEUOZcF4QU(d(YaAEQ2?_Rc$X z@A7e|D~EmM9h#sXf*E=FB}PeeY;VBuuJ$M!Jz zAsswUe|qWVcfkqr31{f;PbHhE{Cv~k7v=ct0L;X;0but6zd_ zD0}g4{y4e*7>(H)pZON#I6k#qFV=4#wdZV3_DxN2EgOFzm-*fb`e$B_$t%qXJGcQX z%r%8&1*ULAUflZgOkrtWykvf^nN~L2O#6Lay#9LH4nj-L%ri4;r<)mN)69(b6*=({ z;%6?%GYe`9O>x;2N6vQmgZFSgIyaz$KZcsc=g5r5|v2o@(_karL zviVRlXO`rd5^OUY8|Q7viOV*7$y3)t$d$VUl<)Om*iBan%C&&Hb|)yg_q*{AfRa&i zNuHS<_^nZSCWWoN;>h35!*yMcx_NAK^Qd<*;l?Wuxj1_*#s4`r63IOWD&M#8vPJoJ zfeJqzvgQ0SsBqyz{^2S>r7u}lWG*Z#4V)2J5}2AUOcjje4cnSDM)qEdZlx@`#oOWP z@NQS9y`b{i2WrkZ1ZqD2v>QGQdd_(lLBM-Xq;UsJ)rD4|FtKGrYQPHYpW#11c<(3tnokSAlX5fx7aP z8~&twz2r>B@Au_|C3gh5*T5q=5m%00hAUhL%C)&+XZ)v4m2h6%?6T>S;po=w$_OsC z>D~;=z1t0!oHd#Izzt?vV7`2`ep^WBb7ow2qhCt7mRWHYa<#7qgy zH94e_t{vp_2y&%c2Wdi=S^qXrZqN;vymp$oFmbk7T)W7eUAEAi?r#@SD{CvVo*|87 zb-MXS%4|3Z%Kfg~hD%;kXyym5G}F>WsVO7*!~StHjGX5&vg9O@BRt^ZL69PuL!jEl zuidav?cmQYPQKBGXM%ngeyx>z<`p*fQc&{GdY!G;he3s30F}=h_{dfH)Pf4%?}mQ~ zs{PI7*ka||%Xg^i@BaZhdaSg2HP2mT!yj5>$HYER*ITc$@*V`0U&-Z#=G^wznT7Ss z%$&emOnyACYH~Q&xz84;j!;5;A-6mixmfPvDo}bxUEJozkGS$%*K!f}2~ZaKnj8KJ zsB#^1!ymlbmiIksz_>0@azAjbE$?gA+3@3_%5l|oHvC3V?p<#92{-(8&?(=deC~(E zX3DTvGS(NgKRv5kIKRNmuP@|z-CQ&E#nVmhvkOgdy)hqx>bnDGAw2$Y2{)=x*#a{o zFxwQQ^HTo%Sn8bt^FH{MXWX^H9bo4THZHJ%i?}mE+2M9l80=Ok`3t zhkmMla?q6<-e~#W3(9>2l$P# zoqQiuTRiH9kAVe*b2rn!H(UKa1j;=MO6F&_*me-uYQx(Z7$y5npxSvKDA|WV$^I&s z4+d|s?fUcJ6vF3M+Heo3@aNs|)*74s3!w5F0p*?tRmPInPT_v@e#Vt|A6KXK*kS`p zh%ZPPjV`u>vc=oo@PnY=g=$^xaeNb0K0g5` zfspD<&t9Rq?2MY;* z+zrp1r!o8@#_$WAFx!!W4wj({p}%8l=E^UU1e zkDp1XU!~s>FmEEAc+=!H9+iQUtTI1xi#sN!<;(^KZtul0V)=Bx!+GwHT zYV%C;cIpipK48ZVf4JoA0&{j^nmMy}swpWeGDR)7o2`DyJyikFCK` zw}pAL8>nir=|);@#7{s+4m@(xK>11vbF>z7Y_B}6{zay+B`-d6L9SWAT5ZOLB4<64 zbae{3GS<5?s=%Q(EB`-0x!F6djw?Xb$97Qp2MQ*cf)%+bjbn~|5``wZi+UANo`uT_ z%(9nq&GgzSX7VOlV8->pg_F&NwajhGCOPwrKo0FI7Au5%>DcMR{fs>o&igqOROwSMG0I zxn`@i`E)SlreAWWq;uZ_C4V<4`JVvQe*X=W-PAVDt3AUkQo9YzGDYbrsr+GPDem~Z zggozpU%VmY$2+XQ<84IZmfmf{*5-MJeQ)M&Xb;bo7AnWY__&hS6q&_|5_5KKu{o>k zbaNVcI`=j=KjY@dzBwn)$KPS|`Q^K8I54Zg%-U3FX3>6Tl}=AhjTcn~<`kGYi794I zEm)Rs=9JD%dHR@p**61OeURk~XS4B^rmS*rbZr}V@lH2BexKFnASm};P${Oo z+uHeRPH}gO%ZLgDDJlJ z7jsPT{j4XTr-xiyXT$|A&oh@ZmK0(uJyUV=d$GWTKES*TdP(UtmTby%!uJrD`w`o| zb=@C6E)Df+{*kpNG-}&%VO#fpo`A*#>7lUL)p z>qMSzGZ8NWoQy1QOmw1|;3-0;o+WUt4-$;6-ckPRy@ zxg;o`@{yYbO23k6tcSKw(VZJLzdFqk(dMkI!D1D@-(AM@CDo##qN7qtM+P1BB?Zv%BT!gUa z;*__XK*WmxKTDjyy@rQup8G+$@3~>6m3u2F-#b9%^-(we>!9*=+FPl;zpET2MT|`= z#@eJ4w{Ws4-tLvyw$&iKp7Zp7@?*!B=`e8-j}Z*se0-U1B+e^S@CjRTYgL2;nCGRJoWWDR44flh}S2E;Y29?jOTWr{0@6vUm za_n`>5h9)BT?Bgidze{{?x)6=qntEeInu6PTR-8bW$p(h=OIvXqMx+kouKklTDjGr z^xy7={rXGCiRv!SHMwC|-p@g~k`*(|()L~E;`(-Te%UKL+xfkjo}QX294Q#ii%+id z=1pr!?>z&LyLsOMO6nd^IzQ;fOK$p8R_`A^tq{*OKW)qNrq9^&^@1wL++iEO0+g(F zP_A#-rhgff`^&HmpQ^qgpT0>~uLG{W2VH#+`Sgu`*2<4Q<78*ne9r3g+###qyw6*G z-wCR$J)rbG3d)`F1)F{sDEC%3JW+idyGyB=AG>^icGJ1f{KED<$29ICQ%zorea|sM z8nuNH^bQ}k`P~f4o%SUgw(G5ov7h@vgzI~t;!oOpm_O{SWfzw?;;%q!!5P&zjqn8p2&``+kWwupHi_miU1{M16N1>rAb z&ZxOk`m3z1zs7SBSH3@7GB4N6+~ABy&b_7EExRo(_YG_yTXlLs=BA0MCdKuOzcI$+4+lzE?`w^_sfe+e@wtV$%lxT41BZy4Pu%>{ z;`H3q?2%c+!MI&3aIdBg=3rB;6*6ttkzugC0l9{$*N;*HqdSY&YnVX>fFjp+x#QM0bz@&&@^ds)OpSJS-;S)WV+={;MLm!nb z>6YyPsPNNZ3YqfX_hXoF4}-G6A3>FW`cLfjz--n?=rWu66Kf^6y|7;3`XOk@)yp3) zSuxF&CC)J6+Ii+8p8tnfTaMnTqjud8M!&nrM>>qS`hDNk?^j^xMSJZ5Q0`Gs`uzr! zerNp5)o(KOg-owLI*I=n6#W-#uW@0gAG7wUos4aBP2?!gy`YZ$me(J4`bcSBnkS@T zr(RwxGBXp@i~HQ7K-ptX+O@}-Q_Y#~^QJTDcW2V?&fG9BU7VUb z9LS$!@>ker%nRq{nYl0VZvVwXo?#W3=ed3i|$_wePsF`#d1U^*3|3@a}*9aEbHI^c>!q&d>VJv>bapPg$gY#I?yf7gLm4 z@#O()t5u+UKb&O4$3Xd>%(dZRQ2ZsAQr5CL1q%X&1>>Fv&}OxUj6^82(*|jKjALgq zcAUvLc4n#D2EAuQo5t2@jy-se8lN68k3i-bYmaeZ*#n;FjDUGB>fTp7)8w*N2nKma3T>0@*?fn=nmYLG6f^Zup(#idncPi5=Xwo1jc)$p_lNy5 zN>1ZBz;;{a5P1cHT4zo%LCU3drhh&XhW94uh$A=d2C=;hDv`1TmazAjx{&EE8 z1^In)BStlQf{sA<9M>!d5Nok8vW#60p*+VMyt~zu=6sj#}Fv@TTs4&GRw0NR5_jp z9er2ko0Z&mUQb_`bJxshFiansl53`Hn4Hob${7>5KLsymZ41r+g8D7>^z39aF6a(dPG;Dj#%VicPQM$S4<%n4 zFu#Egx#`D+ojh2}ToEw$Lmtn#u*;L;`X#R$;~5tg5A`?1_2(e3kB!a`sP}-G~8P1l5 zbE!-NG%5#u6mEjb58HBOhO?y!MX(PvDo6GqTmf~sax%l&(s0g~`I29b>_hl#&|z0j zW;k1#j^zRKPROs1!Vg2iFWGWshO?#N{3>%kG%5#u6ut!7>dMIs`_tIA?X0QC-VbbI z%}e?zEBS8Kl`$@?v6Oste-5t-nAMPzKmE}kCTKJ!%yhp!?ObQah(E06{ zVf($T$209Z=0cFEv>2GC?`Wr(X*{cSo?j-WuwG`(yeXgcGT(-l&Ph=O<9wer%g#k3 zU%`%0rYnBg#%UbYwPNUv*f7)8x^YXg$Pll$r^YX5Ll!wv=FD=Te?2}A#cThToL`Qa zd_1rA5oPjKxw4%L{L?*R1bvT9PzV^d!TMe-_KUfGtT#a=2F%I zkiLlvP$kaff7$ z(_75za~Nvny}F4L!go~bsOlBF*K!JXW6YSpH!B;PTVrl;ZeUexXG2Zw>gJWrO^KG~ zM)L|o`u4V4S1`uk#uqz*H4RO*YZ_YYS>aoFx8TIAkF`5lY%xtv*pX>AE9Z5b`m@>| ztbXn44eM90yR7sQ-8IbJlXkVnIY2v6x5eDJarFi-{+_(X+J>Ec<(;=9wqr;0&KUb# zDk?6E+_ZdaboKJBk(=$BQe|Uv&25!+R2h37ax2@KeBoR2>UOm>B)IYqIhA#-vDj@5BiM7sE-w^V1JV&9e3G^ zxyb2{060n$G6tR z)r~kM%ltl2S-qq6)=Ed9X`EEKV=T8HsUZT1OM}>o{rwmFwsd4gQ9@R;_fuTF&v;ko;@(Vf4ARv3a{=xa!7OgxV4~ zW5h}g2Ah?%VMjc&v{cP@D5s)w({KYmoBTkW(DVlDqUl&>DEMjr6c^fbe|{P znug|h%pKvJq3lLA?6$f{1nHGq)=I;blPhTF)or)dCulk22F06}SFWdwznxUkP#dW@ zr>40!R7?H6SZ`DzBz(nMwuUa9Ma;(KmDgffRN7oe z|4VpAFO`;?%StsM|5t8BtA$bLcQo`$7>)Kzv47J?pq`sO?IGXwt%WySiQ2L)u zs^A8K#b2!e2EFAK%QuhK6|$T$@>SYWdZ^7`s}|E*-%yveHkH|0OtzLPU9}XCkQ$t> zKI!G?{XELajZYg`zS&E5a)a5s_ndKg*;M}*vZ`E9x$?*5)lB<4QG4`k_C8EPN|l>b*+=7xr3GzZE9$G)h$8Ut3Ig3@6n?e>_!zhxow?3?=(h<2!|=W$(ii* z%cfT=My08|Mq^y%HIlPAw}Md+DaQ>mzV@`jZBHv!NrB78+EysHqCqPBRf)}=x+8c^ z?9^K3=&WTRw}NpODC^NcTiD5tOedSPK#3!<0(-)xx$&>jVkeKN4C*w zc)MSRQfBEA|C!Tr`B9)mY_!O)ru)3bU&@mv^h!9NHpcyC zEXz~uFxRQyY6?6${Hnb#q~Gj*_5D}E*3x;+cN`n&_UE;{SD}uq&JAs>?KMrVXxHua zRd-|QR9CbHHDLT{)lzzn|JM~Zrc5-he%r_+4wVzvNt*l zsaLCq+KlelTamDiS?FJzUaQd2k?9mG*lVxf%&Dku+*Q51wX&(XhF`9UxPxOQ1C=|= z)X?h8@WO$LiWSW9+$K7@BCfnvc1Tc)>swg&G-+lRsnndlT60=QRCsKnr6QZ(Wy}^U zw`89##*w-{w#%DNd+1lePPmtrUgoUKg>;?sNaxI=j_34b(6;S;ax3Mk{JU|JN~dg> zuZWnH&b6_7#+aVEy4ksUyvcNJqjRltjpnL8YwD7Df*LEUIH&Ta>Xs&NCaRH6!#$4{ zG}2OruV$MMk122}6Jm3@9dW%|-dJj9V09i@n5~(2RX^A0G>w&jou}c^nBcpynn%!d zd2KBwjCj`d+nr)Lk67G^J2m8F{3NMX#cEn&b&=zZuLi0S$Zx>QG_NdjYW4)Foc5(v zc64-=eQsd2el0E*ZFZK9=D&FMM`JC{gRiEV*vjTMElN#LPo`G3wX`6@O?`E(neB_+RIjN3k>&@AWm(8i z{cYkA&hl10OOwy64pgpeZ-=va*VvNUY!9%OZ*O1I!aCMIR%^M8@9^AbR_u0@kJ%dM zK0NZm#UH$oeVlIyeY5Uay)m-yu=c#!p0^!!vDn47y=I)NY8!tp_a&?ge2Z+8?fTa1 z)@^R!_v)HkBK#!aZhkU~C7COA0{*BT(#1}ZUkhj~W!JGhB1yz<Xln)BjaMmH=1mEI?px7 zSuMMso=RgA)a-nt%41Y-ZfR>bJ3sd?CIyYv{A#V<_l&!TWz)Cfoavddxn2KQ=)Oq+4O*K6VK*Pg>QL+v1EH2 z3vOT8q`?GoS2xB^UEgu`UUN$JSk+w9mNkQH`na_@PW5bj*yBd~v(DpKy{7d)0>eRL zu7>nYe+M|=`iH>pLi%nj4KAL^Sq%93T~_l9v==|W?P@OO+bG5J`>^H_Nb&qetVu)r z@C)xfjqiLE4}KSt%oMnOw)IEB4oLhC&N1eY_`&6K`5qs?&K11obk3Sc+B5&o=X;_K z{Q9ow2hcJ6DR9#~D@W(%H7?`~>@L0u10R8u?+{qH$nxl{x4jpz_YR&UcnA{D2w2XX zSo%c3T1fHE*=3jTeb+v|0p$CoKSM|H>pP|{XzhOFgSku54Zpr?`ZTl$|1h|s)XI#4 zI%n%3@xs@YvA+br&dSpHR7)PCT;P|lV&4OPo#9lp9yyOA6ZFnS5;okx{;zJn!36Jy z_TkrAM;B~luK<3XS2VbZ_mVy62LAnx*aUwEc-m&lhF@m_&1IF5kRQ|;GJATdJMfMM z>aGuda2IdPkIE13gB*K;ziX!79>5N9))SE8BjD3eH}S(@+Km_9emi9+-hVEO&TGkU z;XM@b!Z}b1e+b+RNv6(N$w?rK_#k)%Giw=WO@qf?H5JGBK!{GTHR{uD7+ugLQLG%RIzuodgLGR2E;lofBJi@1-1b&?dvUm@2 z@Q1+#_wc?Re+c{wqIOavseXsRviog(1bhHeJiiTY&U=rI4}*6@ithv)JEQfx7VvTU~z#_{j&X%waJ9{Z@|uED)Uu@;&HZNh>_#1GF*x{xdxM z=X>a!k0Gd-GdP5Yp^NYf{{St+??1;wXMWT}>xdUNK~?yLZBQJ){~QmU@9_%sZsLW1 zf%f6op=f;%(SPv|f!BSQ`g(%43jPMl{V44ayd{Zl_^ZIPx)?j~hrm7iII9D{|9lCZ zJMkT;mU!V$p?3UfuGy`K>SUfams+?~}AQumw^d z>;SJnVEO%LLEKKU+`;>^=H0F89zZ<@PfnG1i$uBFZ~j23BP|owDw7F z{W9bEC;8SJybW50-@pG^`=b8Cp-$Sgu#m_>Wp9(nm0{(sY{d1D~{(<#tU+~30 zoVd90qfWD7E4K8@Wmdn3?SNnRu1^o&h;q#FBH01(|Qnsz8z(qge zo=Cj#Ff<>(@HuFi_`&v{(3kQ1_tG9BuJA=;hKU!>gPz5&{jvA`jQat8{~lNEeZA}7 zsNa8KKMT0*DD51-e{ZYyyf*%vdoA(8+o8Sq{d-uoxAnGPP#44t?|_~a59sY>6;A#Y zIuI``gv@7XOW>owwq>vS4dVc$F;;t6Z%bnbc;eufe#dx)-@lL4zsFR2O=tXpI)z7g z33L#@un9UWIpE7L(FX9FmuZKPGZ*?Jb2-Rq58z#p#*I$!W03lt_JTh6C;Htm_YQE$ zG0PtY8zAw-!4LgA`HBaueg!+=?*y;=3;i5_2RH;NFX4Yd%FDl>Q~Nx>2<3h@;Gp(# z7UTEt=hQyWZ$L|k7rqEB!=DD9Gkn)B8-o9l%ibU2^^N@^NO^_9-xX0N#ZP4)1LVYm zZ-ShAEBG5oa?;>}X_hAh_CdNo4uLh(nO`8szyDJEGH1>RnAy)*)V|9l`2G7YwJ-A( zsGN9Veh@wJ`}a-y_f%?c<(Fp$%-i7+J`Z){7oIhXGcfUoz_U-Iui*FZkJNt3*4dox zLcDMnWZ3g4d^c2#-@jKkomScKyTPhEf~v-$$wal-FOzoa^%zWBBjDFT4lp#IOC3zb<3U zz@G*SFK0jh7icq}x1Z6!S5bQy&;2{vBs{_}v<<&-Bh-k$3OuXa+QGjc(Z5$wdl-A5 zPWXj~p?&y;zk{B{Z(bWP?}s!F`1dJl|6<7%ns-=yE&dnr`}Zko|Kca0mxvcW2Niq~ zdxGA+Md3|QG4aCP&_(z=z&=QG1OJ{y?PV-oM%m#JRzOkw5g{ag;X5JKX(#wGNbPeN z{Hg0tgLAI5@&3Jx{(X+x|JVd2kT2{IzjOmX0PV%^-@oYJ+o(N{;nxSu)9?syf=2KQ z-v*`d`}ZvR_cLmrf!!N9bR7T-Lu0I8ycDZL-Lj=W%&wugEMci{xEna6e3=~#qk}eJxLihq9-K3&a^Ls?V^w~g2dc9`<<}XFI%D$i6U;wvqJ2Rr z{5m^N=j=sUy9sk{roZ6V8FV_UF7$DW58@BwPl8{7Bva?Dg>IpJK7~9`XNDCVL@uba zmBb^wY#Y};MLmH!J4o@u2cYh!?Os;xLsh&`dr;*UYJaKxLhT`yU-*ja*PhW3HG`$DY;j??#(yLTm!Tt-;@lWKZHo;;YH0MpnXY<5xEVqgPjP zwUukqBTlLYn~~ju^f8%B%_Z6SG;~&;j-%1*4U2ijk`k#XllK3 zaa&8%6|FV(u^rW|7w>4OX=!e4u1j28)4bz~>ed~X>|DAy#AlBUb+OjOW`Ayo3Wb&> zTH0FKUR~GhN?UXiX_qZ>(vh+?R@25NvfXZ&n3mY>ZR8TGo$myQ;W_$Kp@V~{yx&Je49^N;y@5sK?zN7oh{(}8m_gC$Y?{D89>R!@a z-W};)+a2xR+FjLM-yQF6@9yZ{)7{y#P0-96NOuzR?Br29yBs{3eny8BqS=_%+5 z_7wModY1Hrd&+wvJ!^ZSJzIO?J?%XmJ$rgOd-nDud%AmudJgss_Z;pS={eGq>N(nz z?m5kPx3(|Zx3#aTufA_jUuWOmzM;P1 zzLCCEU%GGPz>x!~14j>}4;(vS`V0Dl{l)#E{w4k4{__4v|Jwd&|JMGh{`&rSe|vvN z|DOKN{=NOl{_g&v{)7F8`$zhZ^r!ld_NV)g^_zi$f#5*#KxkmeKzN{hATqFaAUd#h zplYCgAU@DO&@r%QpmSjFKysjaU})gr!0^D~fsuhD1F3>S)Xm>ldL92z`0I6QcGaAfevU~2H_V0!S_ zpy^;PsP>pFNCuO|$xw1hGMp?=Mv`lj(d5=-RkA)APqrsJl6#V!$-T*BvO77HJeV9# z9!`!Vk0evcqsesgSkiPAbOpPLyFy({y24%MU6HP}UD2+sT~%H6UGc8=u8yufU7cNf zyOLeqT|-?5yN0{Edrg`-ELq!JBjnYI++)cwX_8&(uE-;ukE9+6Kid9i^3lVO2KUAH z4eu-7AK72OzjOb{{$u+?k0l>F{8;+2(Bsj^J02f;JoR{x7FR|48m2XcXgmK~I@`3XvctMq#GOw0qN;5}}0%Ed)zLky~hIXt|W8 zOhz(iyCo{ss&K5Y$3u_Tsz?i3N!r?^Ezq!)de(DaYvPyp_{w}fUpaq{nZiIe9qy>5A^W7*BuF1z~1(Bi9ay6NUb=(9^g%aS*RuDdDJe9{&XpbXof4W_I>qO^ zwZ!Lp$bG9X;d?-R@8p~Nz0~Kc@bMr2a-Y5qo5m;N|J2Cg}y?pkR_=aS0-{Id`i6tu& zl%1ILK$f|WsUPzB+Rj>b&DDvkeZIO3mFd&>Z+za)XVJef(>cqn=IcJ1f)D_MPG7l; zt6Wv;^`6z?R#bCjuD%l}J$hWd@L9{2FI!BJ!U?$XNtNn}>Mgn9W-2};#0;*~9L^k9 zZx*Hh|Gy#(Y?dY5_IUoEZdL5Pr^KgcN_6M6Yr9H(`4abwo>^Gszf4cP9HQof)HI*f z%_CHIf(_I@w5=pDSvU7M!BctC&3@fnSXHa1wui2A2ifWy-J|puaQibG%*l_Q^g7M@ zUI{tDH&W8Uke+F-sx|r3`?8_ydS^`a`L28J!HCaSGj!WgYqmL#vsyKhG5e*7svnd3 zHua_Ebvvb1P2X)56;fSayj!5E*VpNFeMO+D2{N;4-JGnacP8HN1dn6S>*?Oa(J|Ba zs9;Jr2O>^@M%5n91pdm)^ffPcs?v(bp<%slyFk%V=ji4$F>_bUst5`;ETFP33uo@E zVtTvp7Fh3~ubqzG-&Cp5KHS|{*Q;B10=zZ9s`j-X>4*2mtO(ugwtx12Wb|#i8LR5h z>mIj{okx4~{;Ksd?wakLd*oR(zQkLrU&yMO&#+R5ww5H0a)NgY0CdROT;WXy z4CL!K=IiTbrk1(uR;pe;8V98HxvI74cMAfAf)BU_8w4yXwNXCY7Nr!#tdr{KH{ax)^HDB&uo+>yiO`wgpqwQ+HPB{$*2TiEEwUABFZ9 zRd<^ws=}(iq72=dTWudRL8Bi^qs;P_%yJ-7#L_Cn^5?m{W@amO^P#Fv0VlP+P3=fM z6La@-t&A0t8OjpqI5B}grjx6cHoP$=9lH3b!%R= z{SSbQnOC*MGFP^kb6PXAfoq3=qU)xNklJ4BaR#;h9uF_LRCZI3z?eh1p1HrOS6-ME zH%|3X-c{Afo0z#30PFs0zLmM5D)hP*h_v$Gg{|6IeYfk$*?MYgwd}f9`?McQ^C6ic zqzaUmR>y!tcBDO-vYy98ZphBm&EK%e?Q=ip^QC*Wb=$I2wX^$fE&o|bw)C9mpqJ9b z8L0zrjajSnR*zb%8)U6+sH#=ub*$9w@Yc1}2~MG|_AqPng{n>gh2@!Zp)8L#$u-+$ z@>gBCNNtRFpug)YAs}F_SU9Da29J!Q!N2O6>sYTd3hQ+p>vbI{`AmzRsnIjn`}qqL zNb-6}60j9X{tN*>mLxB_Yr<)IBzaM_eOFPVX&xP)K%*Yr5)R%tlsHW{rwVg@pKe~_ zx3AnQ%QDpo{?96UE`X$GZtm!xvl3#2_aQ@ALc!BaLs-bdsy4&CqS7$04;kk2YQub~ zh=RhhTSwD!Sle{uks)yE1lwg8SElH~*FOxq%`{c=7vis)zk2?{{ON45R{JjYgWg{z zaAeD9sBL;$c=4Q51?=7SMKSqQJR|H;vXURnufl$xEN($ixa3{T-(bcFn$!_T_-WTl zAd?}lI7RxLTQ5lB{quL0_>d!+I{@qs0K0>IGq=(!e2hZi;4M?QgDKom?F7H4UMiq! z89yg@z45~fE@6XNKd5Rw!qnEhyaDba8?8g_e6wPj-=n8=&rv>KGu)xoFndLuEfsFS zGhE^42PqQ{!9uk9W2|kP&_Gx=PWDR_H7u+OYw1JOQoC%yep$j6`|MUlQ>*s-k`=@K z(uWoAw7>p_g9IyOx;|xSzq&JIXiYmqi)7~^)*N2A#v97V9eb1sC=jL z27A(asZ4o>23B+fNcHPlQ*=Y!&i2f-)|k99pK@WyqWJ5nRh!F}8+`QomrbGN2KfIS z;Icp3E8Mp3Iq9iAvxuHnt#hk%I>8pV$~u=JFY2K}=djP6hScnpLE{^AE8Qt;56(g{ z%jzrz3%o+9W_BG;@Y|@(F>_IG%v`XcJ+-RCr*+*{;qyf{Pm@+=bhDlsDO-NDZcTq0 za&>~YK^l+isouBZ=77=I8`EYD(9s4X^`_s@n)byT2jbeSKB{jP_)=SsibL7wX)^@~ zpSG!_y`eOz@xD|~^_3dVKr)-Hj3~X261~4ysJmI4)myhSTT!>O+3YhG_eRsb$*D%_ z$h2kC%|2~yFRZZZw=x4Wx?eXB>V1C;xmwqN6Z|yu@itXhDQQYQLuCuQ>e^UE?MWy2 zL1_YhsGn2PAdv7_MGXl7)y)gX7We9lx5esuW2g4T8fNP&rt5o$_0)i)*Yw58dgEo_ z^2*Rf=8SEI2!u=hF*Ckj^&e~8m#omuU0MHJGq%ky8?Lc05sWqJfdub;*=K|^h2Ixt);rwyq7`!cKb&tfJ_yMxhy4MUyYqD zbedXO8Cb?@SJLzm>A`%`UQi`H=^>=Q{m2v%SgBRj0mT~vPVh2dPy=Y`tx$z-&OvZ0 z{YaBhY9NTW%Y*~A=#7KR&-1?RTJd2WVb!A7Jfru$S*AD62_&JwJ@&fY(g%3C$S;f> zkyt*IJ+V-}QkA=fG!Xhk=}OJmJH7i|SPwhD!XC_Kh*Y-hz5%`2Cc+hokjkfG00CqYGJsHZ$7F$2GbsAX)K% z{p;66vX5SikI7227CTQVti?wrk6nx1I4aaQ7b}<)SJ&GkuIBTn7f?dO~s8S76NnKDx>I;UVW~Vu$|zUQo*!De2UI; zeVE5J+eOY^b>$VVQs>EH`S9$m)NLVF`WYcO!|w$DoIvXLVity6S<_V6o@w%nG%qsM zR4<}0N9IQsL@tdevEFf5iS?ezjNYH_VI5tS{{E`{^2)5J!God<)O5F>H8w|L=4+xu zJ1D=kk<>_uc2DqFYVz17|1FjOI&{kt8_zze8kE)TFy8XP)ZY zUcSZ50j%DeLB*pky;&QXi4%N4)vEaX3qWag_N=2#CcPdgvB@UOUd*I7swbAOXnvDV51 z?*`=ETYnQI55ZaLgbXZ8W@BIbZFxH&%;m%1alcx@qo`oVy%H<v=|NWZ$cl<#&voR@zD4Cj8t_Tly?R``*t!^O1-{F#g6_EL^ZBT@3^&m*>%6j)9AP?U>&nuyk{r0)) zp<0K@A8nr?js7@cP1PyY&p?$w$~vwe|dM;BO3i4M9Inycz#^j;s?EZ%S(Wy^}Mw-0@T?;i8!a{x{SveB2~rmdR~z)~6Sxx|_6 z?0qEpZl?v&xE~Ob0o}X;)9$(CpH=a@J)1Qw zFB8=+r=(laPS5;&(mwH3$B8)G_0+b?e76&H7BRPruKyD?`s|QiGrLm%uY)X5BF-r7 z?d{skE-)?NQ&JcY!b4URjrRi@x#K~3^XO<^CFD`A`tM8jIl-wcfNr%2Z)kz%*&jGv zv6Qtg*HSzd`4ymJr=>&KV1r^5(DWR)>9e^@XI=4138|=}~0g=d97^5hCO3W_svq%))DTQoRpN@2mSs$6E zpu1r@&70eeBH_wY~K1ZIh*lA{8o^~aFx;F;~8)dpLIW1zflsduZmX`Rk{IC%DgD2{^IWeV;<-XkKn9y~#dqk>K3Z zp?-2LV7;3FUMd|;B!Dk+3&soJ^Hf2_wMh7a0M0-fV}#@vr^rM+0bD|(9-vYJc*Z&I zgA%}BLu#oK5x^&$?Uk@4>{S?YlvF%{{xhcUbLjhjhXAgI@ZL=TCxS}&+8w`?^+hP7 z*V4q?G5kaJY9!^9Xz6-3pJ^#7-3i^*ZeG*b*?D-lY;WHilgzDs_RO+Dt9eR5UkoLz z6Usv;%S87#!(D4dTXPjB`-j-L=0S5nUL)Az146@5YmTx`;X$&cA0ecjdnLPa-P@FQQwo_9BspJExRn;hA;UwVE@Q|jj=*j`@v}-PmhEmxr@6iH zVbw=!)p}oI24k*wg5S7C#*}X(5a@f~Cm@q8vR&GY-6B60N*8x~*q1m?iBl(7r-otI zIKdt@&V(E0zduv7VLEB@t{dj#($Pd4=7Vm*_zhE`3M$SMPMp_RTW?ZN!uw@g2)!?w zB-8RX%wW4Bes{yXeCIWKKjOkaChCaTeqUb-pQ` zgEXP!#=c}_%uILk9UrT1E?DW-d4W2eTa+M6U>-u=e_fp??W~{1R3&s}jf{dy$~N10F^c;|}%8dAlUs^w}--Bd%d`V89*F(^GF zQLcAom&hL(=kI*pbqeD!z&gIW16)}&fYeX}tXIXBs^t!Fx(tx{uJlFEFM8XWCp7~; z?>b%0K*{$s89!e44y2NYpSLdjs@PJs-0lacCV)$URdKP~z3g@cIG=Y_i_+@p59xKh zal!vqQU8DEtqZ;?wp1;*|D|sK(j)zU_C|LB)RW7V`bz=ee}%2P1!{d4&T*y3InKXQ zC@aS~vL9#9**GZqQ?48QLG(j1!k?kkSmpuOgA=UWO)IyCeF_$IkNqpMz&we42`%tH zL9Tw@;n@4~hh+@UuSU=o_gdtt$d!>rk%hV7ZNa~1eOZV_MCU5cM{eL}sm?ro#Q{>J4>Pc2k4E9M9~GF~-v zj~jkZ5qSrIuPhn`z-WKs4OOoaBRnXe_ebx^c@lL+K@~4%=~Yr)qLZTLk+?Y+GyfPP zIAShZUDs~e~W0-g#<1g5IZW3$k#ut7CKt3GuVHSuEvRL~z9qjQs=%<5C zb-jl9kK!(VOBb8$FVIDg8C?M|wPy5YKB}AHnjvvY;BELdRI|yzDP1+4?S=z<)gIT; zyU7Vgu44Y)DABq<#WG9!af~e46h5@0BykK?54%-gAdg6@;;<;qG)Bzlg`!%N1#RF= z_*Ks6mBa|;c`5fiFGlJK2k(p4wVCMwea!mU5~xtOKDk=&J5VvtYMxY$r*Q%A($5)M zv)D_U?0-X~p{)Ua%qk~7F{n^AA3LlkZayK#oqBbz{cR=7iov{D=)^-j(|JXv^TMb( z$Eo3LGv6FNg|UE(%c$`UEq$?2su}+l{*cYAy-z>}k59$n7PI2e!Kw%SF`}vW;znNCCRG=FOS%0op`Ao$9(0j=FZ!(X*m`9dY1UMII!$rT+c#3rZ$9Rvk(NrU$WcoI$!2LBvH;63TY`V zURp{$@ozQmwrr^o2DK9ud zQvu zjl#swFCT}A*G_X6uZ_iH;k-ndqWn6*F^v{M#jzygwAy>ggCe=4#R*TOmwv8s1uzSJvwMD~n|a7K?vk7-A;CPo~|XB}{Y zFHuWUk-nhd5>oq8740CkZh?HwcA3Cc+mPRDUhb8iWW=1r9FiAi#gG3)3t<3VRj?!8 zkbQuyZy*1x@X3)}4vg?;GJ*QqsX{uPZke6b&Slws&wbs(Ytahq+tDhU&8s?^Gv6HG z*_@Neq#jpaR%TLzd=Z#C<&%~EfNtJbCEUh->HCEeCzxzy#R+(N8;4J+B+ota39%Jr zu<2Bm>2Z)<8C*97 zBB*yM0ry)af-a73n}>m-==-JpoSbm!XM5`?27x?SP>9bi{WjF0)+Db^dD0=XG6aEq z@sHq02qb!XowM0RZ}dU5SCpew_vYz?P(d8|eGQx;W+jnz$$Mkwk_U~{KSX98!Zmv@ znMgZg=BjVud0&Z&bT9A!7HiBVs^c~P6VWz_)2HN8Hd0fj{468&>r%>+2c#2eBpqf} zZITH8tZNwS7q*GA+iboNGyCKCRJ*#dp<*bKzYxR+_%mcvslb%6MZSdiGkzuC!u%Ec z(}7Lk6!>Oon`VTqS>I|;jl5sG=ez75ZPPB2l)mMn@;CeSsUuFawaKvNI57#+I8SQZ{5)007cOxNADgi7I=AruOjvlcmd;QhU9aJj(U&IA zf5!o?oUo7Uv~<+#<5O-QS0}F+-^WcZ94AcJN5U<93nClea=Dg(TW!fia4d6&`Z86<_p#h9Bz8SP;Z0ilt1P!53vMZJTsILMRQnjkQVl?&*4AQU@!#j#Lps_!pF#G1XDq0UNH=u_X!Udq={vcj19R(395PfpC@|5Fp6 z<6F7X*6^WvwAy!-Y^qEOslCHxDW zq8^ifiOMg&ghS>R}#^z`0npLMwj*jW!!vKlI}X< z=6(q!t`z>A!FrFG!_hiN?6EeuJn}>`QtzyqFaIr+|5{=Vw+FOziUKSErEtVDs{&X6 ztK4jn;JG5)@p0SVX#*RE6>r6&^Vz>6Kq6KII*TL&!3~#x8oR=eFV1;eZTq6$R~?NqVZkRCjhKv%;|bj4SoWP7}qa z*Se%c&2i?{GArWcA~`@ruOMQhXDzq`6_ji;KxAYZZnQs7EEZjRf%{aCuAS~B64nof z23$L9BYBSQ@S{6-afo6lI6Rvg;VvgJsjheU$>}aa07of`fKxBvR3kT(5h~Vdwf(#- zM8rI-Hzey5^9&VxMO+l(uhxQUI_EDMMjI2kf%IEd&F2wq)3g(u;3qB;WR=fUjA(i{5|SLF%|C8^bw{^jo{ zqc6aQCWY0_eHbE+Igf}Y7@Y*fL(m!NhFFkMn@`fbqX+f=IUc327D~T>q*VLRHaVB@ z66X?DE%h%u8jPU;ucsp^95)3yrS&0q<)kVrmn>8ry^C0yI6GiAE2Bw#(m=_Bu8%Uz z@+u+h?M$ESpj8J2$*V|^pH}GvAB>M)5&^=%$-Y&P|32w&xfQ>%yE3cXJ73{_#ykXK_+YV?AX zHr<*-;>)(=PrRX=;M;SBld8q$Lx$vIzW|fk(#waNwI&lF{!Lx7+~l>}^A?eJbnde3 zl#0{14LT_xuR%IDqxG=lWJTOOkPWbBtL@MIUGlj1ONoImt}pv3@)bG@**URO_v1zC zHmqc8%$$cwAZZEY>KrG&6UDT0JSEQAlOyrQK0})|qNkn2S;T9!O{MJ(C1N@DK?vmB zJA0DZ>al@jnb|-O^3;q}ZH<~~p@C*3?R>;4 z1~b*nH>9lXy>xpz9mUPpym&)OZCw&B9u{I<+^<_R$m;)Ng;BOv)(zg{35*3IjTUSK zDKO^7EyRlt&4MMuacVLBUO zIt0niF~%{SUST?0K%W}WT9n`Pd^3{+m^&NsR@-c0v`KT{@OA)JTmR>LQGDYEe97|- zhJ4!}*P4DiF~8`f?l^vNlglrz9mOxA|CC?!yHv6VTwssp_yxL{9C&b9MjDo(AmR|n zc9&xag+8sQcSxGLw+eBq>L}gZtJfT_2o4Kf>}=fCJKRJ;64Ed7a@?yrr1@1?)f}S9 zELtaQ@=7`9Dti}=B-4ajsI1^cYQl@ulsh>nq8RT^?*gC{w^z>al~a%3mzSob+Gj3l zi2!7rTxKsR*v8HaDQfYL?9l z>1N^ZANV$g=frVX3g>ETl_E*O7yW+pRxS8LCSU}d%JUU=y5jr5-5PNjf$#zGLxEA; zY@$|&&2%^LQb7KbW9*HELm1C~iJZ7F>@Cu^HwQ_Ux%@b|OEV#LOJeNd(m# zC#gBE@+(K(LcFygZa1=QK8ik~bg7=YJ>W}R4Vl|l&Jd~@$uSL~lV~r|n~jXdR()E= z+I5W7QC}}2QN3|n;%I#x%N;i0=;p$KfMN{l=mtvb{ZZx0l);2nB)>iVH^4-VneR(p zt*72}5?64@EO5Hdx9VcvE`(J!3GH((2#gS|nh+zb6*}pvPH`}fL&stC4^-fPxZ_BV zukzKfqLr-U5R>Mh${um(GQj-Y01qgXlXdE%+{JYa7e1rFEaRwJ%wnma;A<;A@;M%W zTbyJ7|I~bETeEphRqL?DP%L&UFaQMI%+DT|8YxZQq9&L8ob+d^!2qa!%)+y{#p4&& zJv0V{s!k7t87>IZi$KUuC;m5-Etgl#=Kj={PT3fVI>Vd?Cplknkf)0Y_AjK$mP?i_ z>Bg}#PH=IGXODf%S6Bs4d=x05Sax6!s z?8P*aQ`*Um{B7p1cZ~6OvEK0U#0OQ(>6HsmJum^W{_OAL;ZRoKEV|V*gqByp!?b;5MRkoYFn zyzDPmtEdcr?Tn5A?TnS1b+h6>o}dTubfyRCB$kPH$1>4Q&+unk#Ka5mKr5<-Fq}3x zP@DP=Ve97FmFhdYL0@x6pah__d%i@1CzA*$`NDzOReoHi1(*77pp+5&CPf_PTzG_p zE70o7L}qTIVXri#8OMZHaV+yr{q2P`*^oFh;)X7*;N)h`U@UBbyz=sB!3NdsWuN6` zw%R>ZiG6qg(y-5&sOCqcCdlt~k-vdFq%ep8HeLoqo#C6cwi8&$yZaD@-U&6{<5d%-@p`t;NVM*` z>{0v|A$+{JpYX~w19rS@O2piz6x+m&0z`gD$ii0`?tYXYi$<`vuU)(8RqcvHqiE|}bgi9zSo{3nWZxqHmO3Pv zcE}_-b?$HQYxjyvoz6n`v0Fx+!j`#&?DJ!+fmLyO1mtrsf(&~7-O?3A8r8+IaRURk zxx}nH!Lt|;x@%LLP|nY_azd-S+p)SrG zHMy;{HPFD|8yy@dAtnH0qb27im5MrAz)YyAaz()&`}QSJ0R4E{>N=qA5pDJAoVE(d z#<=tY>*WJEeU)c%W?fNDx}cci)`E~ItlC`ZN?nG*E1h^#wf*LWg0BS~qOP)eqbq^c zRajf)Nas5#tW)I##ZmU6AG!RZfa2Z46mlpQ8U)3wK=G=2cNIcTaD!A4`Z<*DgpvbV z*M2_6^0*>F>Md;xprX@_>zA zMyP0#s_AN%t8CW?Hi-TwWukJrOjWw+aDwN3oRpc~MAPsV?j8^xk@06w8%15$&@P8D zMF89fz^SJVRHAe7chdO{9;CjG4)sA?J@hM2x_E;2s$uwaaOIHsNo4Q?s_vBwqG|D(M@wyoCrlk=Rce zr*1V)?ZYV7(sO0{4e@KWdm?;Gty=9%yx%YfMZ3K&gqVwPM64BfhxbX>{m~bMr2xXy zvI_lVaj@+S^LLPBzrAjbQso+wPbcQpJ*V7x#r|UnVDJ}xp@{$X7x?cR_2c;O)5!sE zPA1V;GvJBN;uIA%@E$gd!s+e;6YkTl=yjooR9;a2sCd5bK^JhUI@$@0BYn?FZu`?~~QbRo9GTr~0twxQSFU1=c)hFge%-0R^a*I!ik|r+BuDEQv7${lPr8}-N2cHr^(Uq( zPbm)78?vw9pi3-K4w8MO`3diBQc`|Wa=P-RDmU8B?6B)kZJ4C@7rRFYt{64D#hr?Z zs@x-StF<)yc_fsA1^s1vtfrTPyOI}(1uqH+n#Wl8$TE0>tdL90ZbeuJuEdYsqmD#b3DBdL|Fo64p^r z{EH8@>*l9PrQb*lP3d>-VJej*@zF!{WZF~XYx zSnjpU<+J9wXi-*2XqU&YhSa@RgdP#>!Pg-Rk?o5KevsuEG5^jfxZ`9i zsdxw!}MqMd_GOY*>qF-!7c$*yvjq`i1a=GW1Ow~~rbF1ezcv&Sq*_8b|=TM)^Is+T*tCSH%nq^_*TnALbt z-pgwIZTxCH_ZAcMRzVWg$6P2O);9i(L>1eUNFO+(P?#@95JmK zi4XkTT?G>;`p116`MVlJTR@ZOPm*$wk1Y_S7yQ>k{Jy$6P+r>cRY&UoIZ=zt5(l{&a{s!r+)~C12Y! z4~Rg^dqf1jQ63R_0Wea@{@nSBi>O2uTmpnr>^V;(vk6g3w{FByYLfrJXp+~@m1$7B z_>XHwPzdla5n2=98_w4~#Wx2WQ8x$pf!L*&_kMH0Z^qsn&|;tbF;UKxgN&g?shVzN z*ul9s$X)VP1Uk7v$eM=S$zLCo{14OJpX$vUS8MX49-E%Hbu6=POf`g-(ddE)rbGsN!Fy1qoID?h>V5Ul_*rd#(_s2;4e zypk&tj_)}XIX93fcXnh;oqn@KFO#gxWpD;>EHyx$O#gL&f-XSmBsPsoz;J`@Pt`HL zxPOR>*gJWMb17@3iaPAEC!Z*VtGZ*>3OEo1@uWTbB-Epa=U3_73s6TE`5qB|;RFv0 zFOd0e_6uU7s3^3Q54jg(5iE95C4X{p<;N}q!{WvWyA{}Tas(xuyB9;8F9G`xL`pFc zY85T_N9*a9afwlM6O73$TJMd!IydfQcieUExO}K_H&S&of4wr^e#WCsN_6#pO+TPoDs`hjTJ zZqD{g;;>;JrSyAiRQ~XBWF2~L`_ZG0x`xHsm07zPz++~603ZLFS6}(n5C5P&`sz$| z6`vCv;OwtjNo25h^)Uix+^u?x5wGz<{nWjB!-ApWtMug9PT4-}yNz+Pe6L*lXs+@| zqp?4UvwTmM$;S3FGj)w#EjM2H^#(m4SDE;-zvJq)fZj0AzkCXAsioLoOS2WZ>-F#z zCRfNApV?5pxU>m;t;ACSvM-PeBs<*r${zdsUt@(H`7ie>8vHB^*6TGS1s^HV?*5v% zQXKJbtaqa-I(?M@@4C1-Ic|}@&1FnNp;o-d-gXOL%(QwoEkWDxBxyhK;xE{z7GF14 z6U>`r)QlMBWdUWcHSS8b$}uf2_0Ttq+~ps3*?@M>aSEJ119e5rDQTQrrTn_jfS zO)sPPwHSokj+Z4THUyt00Sf0$o8Q1881T%%gL>+~L8I&f4pPC#aR!3*J@#8*M_L&* zlXQ-&I0Knz>pPLdBh~Mn9BN&1sGpD=04YZfBQB@-*U6y+a_IQKAcy2Z>L2|UV`Ngh*b zs0A%*DMD!o#5|J1sy`}_XUM;pR}hz_9{C9*g}S>v14L2 zeRA~5{>iOU1%~yGG2&8X2^7bOtrf6$99WU8$RIaBW45VpQI(6UL<4Vhhwr&R`5k=UC*qQcRU^YMR}=e z*eAUy*v%|jNi+Ve0oCj?ZnN*X&Ey@;p0`vpd9wffhBPxRF*?NBS^A3Tg7;U6Aw#w% zX?JeoctopSjt8hHd;Iaohig7O>K6j?{u}EDRXuJ*xkK~@Y>1Ye6(slDVeNeS$1)hBxrxX0VTSLtZPAa2H{%C~XYz&Xk6a5-m#HbstsV@( z%oWoK6`6l11y1nSCovE5p6PTy@K>Ys+W9`h`9A!j-&@25=rnIEM2Ctjg*)j;ltf#N zwx|_m90t`Du%l=z7j`T^&fBjIclZ-C%rd=fNN;>**+B-S*XU3-BPRk~P4N;m#oy!> zvM^n_gv^q)uoiX3*iSlF#|7ST@zheYdNpSQdj4i;NuLIv=c(OBbjYKY!XTLs{?hsa?sjNH%BDod^=&(ygW3>-{nY4^z(jV_RXD zD?@VVFLgV)85qs)lf6}I@2qqO9fZftmp0ZV{#;T9Rf`2+!T_#JyZMH(yH}ZRl+Gj@iIM@%gYhRe(p^0F4qp& zn^`cv-^*wngVBkfN@5d5&2m0>&gNfi^zA2u9?MP*d5R3l*Lu6Vfmx8We4=|iQC({q zn^p@oxL2Op9}r0-CkryswxT)}Hw&d?ny1ye{q!irv2$v5=>va|4B?i?$@^JHKbwW2 zWeu;l*5cky9^KolvAw-Y^P=7^X+C9}sb8A9$EA>F#6 zYCW{jrf4DRvUKxVb@1m(;94$vVZgw*G4s(wD1l(qu)Ent(={Cm^-g8jqVJ#@4 zE9!oQy3LuNZv<@-A#v7htvm?IDNayqsuv{ZSK7ZPF*0iYxw%0#aIbPy25l}LBFTPC zFi}PJP(XEqUgY&vO<#t&C}h+u!jT!RHX5R#Pq<$g=2OSnC zc0@FU(jE!2dgCA7yfm06mfQ4#l)qyrLq&EbTClDGOaPP6|mE{Af;}}IMcdpv+OMFV2 zpu&o8>xcLZ-5Grcz{kv`g;wrd&MKOV+vBw3l`WH-l39`Eg>VCamFu8CDdh(Dr>xm7 zdpmb8&bSM(-{HO+wWA~xnfq?kvbgu%+^S~Y^$B;S-1~06M-njFW}%u{ag~C_t0sE9 z2=|nG-_3W98+G4}$fF!Hk{h&_$_efDvJm~zO|F93TIuCm9Q+TaC<mS&n-Qfe7w$yrvI8~h?xJ= zPJ42<aSozYecJ_G3kD{}KGB zZJ(ivc3CfMN)v1HgcoJv_g5X17>Xlu7}P|Pj!VxH>0BJ&vCiun0$3c1UKpE+1D1Eik+i(KHS zGr!BU<66NnSGg>rrjRN3EpxpJhjzx|$ek~u9Y#oqBtmB1%OUX#@uPr^yR@zi5OK^z zB+c>{G=z8!N$QAt+l}m&i>q0MjeC=|@&gDla}o(5TG#b7CYjUTq`+X;4R;j1?N`wOaj7T z@zTJ)5WwbdNIbT$P~&sx`?dG6D5C%&#@_cPdiypvn`lUsEhbK)2VHTTATdwh?E1;S zS4s|viY5LM(&Trp0^)^art$iGix^0@%CC^g7-cN!95w_d;iZ0iM0}&lgDRKw5OK$F zQQ`BjtafB!aRgm0aJa~9Q_iS_#EK=`(_Q%dP3MrDg6cyGszFUbg`d8r1e1)*(YIV;&}sQissRkah`Lk({63(>n6@YVQm z=HEdhR1{82;W}`$ZG><%dmppx;Y-ZC)*q{R(dhd}nGigQaVupYtNeAr$%R(=O9~f~ zj4X2l9c^wVYifIVG%jR|DSXt9!bjNsZ5Z%@Ii-FbGlvi21};91V_P}F-lIq1gAl^j z<@4ki)Fd*_5JkSKB{3 zRe&LKQ!VLB)$+4$D501i817y)cdJ(RukTDG=2j&FKQ(Xs@ zqxva1eC}ZHIKd81r9kxt^fk4>Y-D5SjP{)Mtv5cs{91{pJW(ZE8s$5O=}Ulms{PgL z6{eXI&ozX?=;AM2ZwS$lhO*sdR{OnaG(gsnkJuJF^vvAAT&tW*bJTaXX`PVKJ1@a_ z{KsI#=BEP&!;U_U2mt#G0)oO`;FfWsb?{1~W@rAaVo?%|(YSB<9M1@@wm&p#v7qdC zTP%Wkg*93TjTWzw@O$-pt+kkGux~H%y1r*E#1i$)?woiNJyxwTK2S{ zIfPRN9K&MJ%ehr!>K(k#{g?uqbBJ;lP}JoT^&@DfusfaLeP}~uN5I0wbTs+RyCzib zt6~ISXg&+xY6WlhQwq6bf2&nmkUu9P{!nD4 zU)`9Ms6pM(4J1Cylq~H?2eHHDoMnl$>5Khxsh!!>rkCxC)C^?&ska;y@?OBGCJzi^ zhuf5jHd3W(E%qB_0|?^f1T26$1C-(JYHT{UKKLk2Op%ilUVAv6PHQrvoGeZW##ziV ziwmyaC>xOlmtSo=5?Vg#kr1=WR>%fAUYO%*a=?fX6Gz@VoctTFlbSk_L5KOy6S(ln zOl%Q%awukfxItVsKO~%lmn{@CPnK=W0ik2j`_=j30ekR83OQ#4PnF+xT;8E)pjufJ z`Dkm-R10)WquhNHM*Ha(e9OAFW@?AOE?-sU)_xzlhHv;DRXCT1JB*s`dP!4<>d*|h zFN~Vs>Lr3=U2+pLylrYTpRCyxDSIO0mx07#0YX%tNKtyr4VFDyn(;fse1yq4FRCZK z=DKTbuGt!KdYdyoA;*{rE`+^@C7GBr-allGQgc@V0t+@oR#J>Jp)JDu_2Q-Th>Z^j zBg~+(=%3G| zSTEUODp}Cn8#ha&%a)k==~iQLDGEmn=}{5U9`k>Qd1Jiz}04f5x@3uNp6%P_+5Tv-bQE7#^m5A*LwDHTX#c5 z^%LnJ(1?yo0 zNzOR5wKR#wCPhzrCH^R&lOvvbfgnROWx@*5czcUD`?-b_HLkF-qOD&bbh z{U(5K<7ml*z@Mam*Ic;wOaS-FGwGN)$zaTQD=@DXRDbcR{;U`!}OCZ#mSK;<;OaWb@;zvk39bUbrPke&hlTwbr zkaA%{x^<=Bjk}3_my5cdmSUY;2IXC>SgKl=e^hY4RB?i@stQ)c!>|WEQ??@|Mze26 zDkC4N#x>N?`%~-W1^>*7#`U-_Q(xdauRG-(|J+|@kwiIci@uqZ!R}#c?#N|wEsYzZ zh!Xnk$k}4;gzbVIgCci z$UO>C{PNfgEX|e5{d*Zal!V#$g8>?L0;ew-ifF%r>3>bSA#SPW_N3FeBcetBK71M- zHg_*M@Tf*9X;w3LL?`(~zln3^CVISI-dfQ~+$|Eor`Ol5`{g>KXx$+^&M1`&jwcsu zl5+nS^nL1c*e1X!9J$0|5}!MDj`&*(4ofZx=7BO6MB%ieuP6nP`=4#1>j!k}Yl{5L zdpi}dA1zTK;qIH*1agnVy|eiu@W`kFL4F)_(P4gVDshe)&>ehd%)D3T%<+pyWfSrH z>VlTWA@?UerMYyo;~v=(Bm*#fL-Z9b{UnbvGhFyu`fO1Xxznx|}E6xFdmO zBo*zknJ^jvEWE+L{3D`JAl)Ml z8PZg1QmRIis2X*>lxa~AnZG_*H^1U;-hGK%9jw3wlE+PcL=JS-rRj77ioCSESgD0nwkf-uFIvJ z2|rtKdM+*S^Yzk&bvY=0^KI>(6M14|pB=+*ieJOqlE>S>#l@1Xlx_Gy8HAm7JWg@7 zrH=1r!4{k@tz;*z?d{?S+NcWQ?sLKHBGrn$akkrRM|q_hNTI_huy#3F_=h)k6dQGMtuv2qX&cl9_muWB!Zy)$Ad-(dlq0Lz^|k91|BvgM1Z%ol75L zHQUHUB$&|hw%~Bl>9HCP!jGNxESYwGeg4X74_^iK$%GYZn054c#d4d8##r&gPVgX= zw1?r*f;z=kj(38u^O6&$_X9J)fxHErjCw=l2KyoI)by1_PuCX@rF-wHD~<es$TJ{%sf}zY|5Sn=s9< zsHf9->KO&!B{Y#=^)ura2;aMJU=-i0hVRvq??4FqCCPTl=R7EXi5%mqlqh4455}x- z3tNhq!v;9>CCdoA4dNl{7iB5ygAZ-#ghb3sjOK&uGF8cq>SY7U(5qLoUMnj@MNZ(3`1X5hCvs=V^z zWSacuJtBXzoU*TY>xht&DxV7Dq`?hUEd_laWkwvuS6!+2J$r-sip>>LoS#FUXxFwF zXp0B*#Z35!f%{TO-YA37c^cm;dnVRA6HFArPkPVEF8o(YD36_~I6<=&#>QpJGu*<+ z=q88AKxE1_W)$AGC!^+JpZtEAgHktgbK^iQlZa(L04p#nDw!m2m?!r;__^MJi9lK8 z4vLAbd$vuz%r$S{DQ?ZzmM{$a*JX?l#>;&h!pe@fae%<_q z$TL?ZFX>h)xfA@|h>)?92ytg3P~5>H-GSdiTnD%^Eb;#%QZjfKD!zOld_AK&Q37I| z(k^f-aicsvV}3z8=WlY?0QoGg+!BuRJ1v#MpCJ}g;B$ii26ocDw@nuD_m16>--GSr z$$N0J%l_sCg7pDTbK&~97aEWf zzi6ZPT>Rp`&$5~-ezATJEXa)-9WT!K)cz4LpjEyqjzZl0*{7Kde8qfK2 zTOb4b)Z+wtvTR*{Zi;E*TdCXUdURdkBmWOEw!pW|3T zWb?^t9iL{Jc1eIH?_j^DUuVFH?RSZ9i#yHT| z$7Zn1aZ?1?{vKM@!QRoF)ZL#2{(+kiJFH?cdxY*mCcFvnJF6@q{OzC&wfa4J-<9Vb z54_qypMI?X75nLS)f2k7kb$hV=cySB55K}CKeHvmdXK%}KF1N~6cfYb__*q#*hX+0 z^M7GJO3K^+_*-$qw`J8v85f26j3;SM?s&g@wzygUxMmZKM*_TxSxVuNpOn361(SvC}kk`3qIeS8F>9>Vxi&t1B!V(w>EaSSxvg{`%43ZV0DAJJJAAH$pHVn}&8_UxV zycZ~dyNlj!dvqZS(Vm&Xf^lF0MI;~>=S|H@y}Dj9$8J;8r8C(+c~759l4?B!_27xS zZ*nT|?EzAYRJOn~M&pPg&A&igPVft_FnP}3#TxfuoJbBya^{8B416R5j=ef4Dec?k z(9>>v84qsS{5TBlQC(dvUBNIEhOh#}JFT!ZL`%Wajp|}GQC4du-TXW^d-y{#w<Q=Jj|B-8K%TKf`LLpEGnH=-^sED`(@G#gxYp?bv=G|C*UX%Vn?>$$m#-cGJL z$PJ$2klHITNbZsphF9+bC0uX#VsSW)LuD7lPyXoN6e{N`RGv|UN^6EfrPkF2jd=4H zbTY@O+1Y}`zZ4qw5Qn-~M%elyOuz3d^*U*^Oi8 ziXVet?2}8y7$Y;#_7E)oS=oeNhB-RHs=vyNi_qaFZX{LVBvq&=YuEBKU3BcW*BmRj zAg1(9g^RaKl9#&_HJ2^eo~h2>$RZ|x|8DpYQv;Z<+%^^;`2uj)o~g;6;^CT2C!4WR zh~Z6b6K3F(?XQ1dZDg;;^0B-17SEz7py@Eo3cMywZ!5Q9yiBAN&8 z?&L-e06iu2S#0=;HitZdNDbOWpg0gIE;cpbPhYG2|QZPU?`u6YtC z2uUd%NJ824Mn;8%DJ#8Egw%0F3XQ4+&gT-x=My+TT9m+<94@-{U-~I@V$?wAu>Y-K zlDtoq=o!&wJ&xFcwe6A=jv6koyS+4@`4*T^}}lXX&U zr=wJV1V`3y?US}Chn5rk)5{`isUnxn zUI>ff_LsE?ma*y#^dEEWv!eV5M5Zp&XmNLf5GZax@_vY1>E`WZzov~X<j2K%7>epA=H_$u$X;^M<_A3P|FAu@HGnojl7~4miwtWT zk8@cJ7jK8>yd&NU`1(xoKm#j|MKBoPjGs+z`^&rG>~>1Q*=~3oI4hq&3TIRM#^9_V z-#w%MRUB;U?B%m|s9g@#UmA{^yJDvf#2V)5E2bNJq5lELK=~{ipb*W4w9K-d7n$X3 zOJ<3GMs7-hd+f^k=bEuyP=~s0pcR`}E*nTtgLNVTN{4w0oQNu{py}saaRKDt03YC-m|(x z+)`~uR&FTO(yRkR5JhY_N9%e>J#acY(m@12rpV^&a>cC$ zgG`fqZ=@on*{S%v2NmIR=!HsbZkQBmg9pNn=%6o4PT?wh_+ot58_M}bGIt_jHIa?# zA<`OK?2DC^GKtW;O=A6|qDcsV6HVfq2j1f(J|`9b#YtGeI}XRiD4PhP$?p}Sp+Eo2 z5a}t$^{5YW{#`YPrsE^xvHs&vq_^A;I`Ye?SBjHb(f1fx5HWj2@S=2ju30Vp0uzmF z4)ed<(MjlV+MlGi5m>L*1s~1%FN;$Oj-g7-A|uthNF1t|Y*$o+n=pUu*SW3ywRw(9 zv*Pj96Syn9ebEHb*-5&$ETTpx>whthuI{fT{cee??7Tsf9fvwx9hvjm@3$vgI+O>3A`i{?~_1+ zVi_F;mf`)3q**byqljhjYj18SLF;;({nq(N23R?;_bLy?ZeH@Bc#{kJ+p4w5(66KCeS|N1O&b$s^05{wZ=sDofidD zi7C#2mL|H)Wxmbb4+^LqdI>bFW10`#b*KC!oVu*v?Gb)Gw5A{=aX`(bsB#44#v)RIf z*-y9+Q{(~v7gIQ=H~SF`mKXn9)Q9E!MKW8{f1{q3@YEv%O2CWlx|Zr2kzp0I3 zGu_{Hu683=FA=>Fet--K>2B7I!4F#D{*QDZXNZl1#Rz+s%@S#?*_R2pKZKl@|DMup z9*N**HD7ZtCsG#^VNA#+Mf@%>KqvuEesOK#j-u;!&Y0@+)%4v~QNe1gR z%g`89(kQMHGDOQD24Yy^!Y$huH>Yu3Y@g~dPTmX0nFiGTMEi;~hN*??i9C&A>T;zq zgykl*u+j;RQs>t_V_5b-F2I7uFkz_}moctp5Gz_DLj{dt;`}D`c@hM>dXuakg7p<1 zdUO+wqf}QXvt!4gv6GF&o^)CQ!h&*c6v3}wEC}Ri&MBaq%dnYjQ8V!$H6B#%lkY?D zPB2c-xK9qo8lS{{@~XH`PQ*oVlyaZ!&x$_wYuA198y>PccC~#5I}U5*lj8qUCzdX7 zl>qdtsbaw4=a_-}WQX0!#!y9~G!%Y3VMlo_v?2FIC`HQEqG~;yc<|@=rwVr}zZ^#1 zI4k|1-GJ%&RyG>obXOjxqJ1-Un@W3k5#>h0$ISt2GzR01Fj6~ zlhs9buVGvz%u}`OlOqXf&>y;KamppB3`R<61%`6XSY@s{Ws3c-5qJOomay}xppL4EBp)gld z%*7W@Ls4{s{m(Gl(eVW|78PGmC_P5l%HEvkf>ZtF4TKnoG;j~aj9KxrUMKkcb7BPN zLk*%p7O|YVo$a$S)368?fW;eB*gAV~zHAySdGDeL%&Tzzj8j}#=QF}RQ+p=mZ{u8T zG#&IyCi;_pF;>E-rH2*NX1tyZw&}^7bXni3}NyBXB zpd*I}l3&D!aVn+OSu0pu+3)PdT~q+VWW*XUC?=+;?g@W$%GlWO8X zz1bJoe3-E>6s5d*QgxpWog;XQec{G8C=~ZTP-FMdap?RWD06Hwv{x>XXnoFdiVZ2s z9YUXLbhavCAQXMgA@)!y7B9LUq3RO*zVlsT|K<@PHoBKm`hnps@_jC)-yt$Xm+EOs z;}{V-Z+V!qS&R6eZ?g9`yQH2hq!wlKP26+GQ*@;vfjcgtGxVL5%f<&P8;_v2zDau? zZz1g>Wn}Mae-3Fk09X!bm1II+w(p{17H4gDt3b2E+PqqK-RVBW%obr|sgoR%Gwa)Q z23`e6rM%N$mipQK$EO%4`q-g6gW$*K(v~sozX{!Xw7khXk~UYfSqi;r16V0f94lBa zVDq2*)KY5-uh5g-|J0$CyMFfBwp4^Y0!noqcfTS7#o7O<5VyVLK-~L&MeHQm`xS2y zzw;bPf!1@s;@3vOFtP`ZIU!`W2g#`C?5~zBi|mBX-m-X5fGySUoFpuTE_%x={E*#? zy2+Uhj5YQK#`G<-Foxy6_AuJxlZ{CJV(1k_$4KwxlkKDI9#ayHfZd7zd65nWWOF0N zqY6!%$;9E1L?x!=*4zt8?pR6pb4W5?@5xz$)@Y?4?}rXQKSR2~sF`Yn$Cm^lKK0$DCK4}hU{-*T%{ zL{gigsx@=QE~2o7Lh_%8!WO*-hqH@&pnMfS>T-Z{qoD2}vek})`q}RU*oxBv?Ozp; zx#EM6EV*8_MwF{3Sdw8f{T*oi;|x)#YR@H6b0K0-%;a)j(3?DFp>?39oux;z=^QVF zEVWYJ`4AY@gI&{P@{JdM$rUx@goN0-WcXA(E9C>`(XyS8&573;vHKP7V0_e9l*zjw zUU-^pLTt8MAx)p)O_Iq=JNU5U4juqFe4>od{27#y)A`m(XjLc82!I zXUQpSY}C2~=9htruT-Y5w+^ELfzIx3^{e5dgB9;#a;fEUbUTj+1Y(6_+_#Y=nDAn= z*bqK!kr88_SWXd|;}G2<9&e1mG_Vky=X3M&*o%4iPqii|R5e$uHOeYvsxIL8elx5f z2SqewQWIV)sR@rIa-#u80)s4M3ogc7z#^ymipM6F-3!Axv0@Yv5ErJwsh*Z#gS7duR z%yot?*azr>y%-kLucEWhD9Mv8guyfF9VVN!P6k!xt>><`g*YR`6!3H*XiBv4$E-c0 zbVM6ii|+J=zb4I|>U={|@iUl3XfEX)O;xf(U~qIzp#wi#XjAKx>xg2%%=v(PLy{=S z{=&l-f$C?&c2h|?pSrKgUteoiUPR?~tuH%mI2EHnoxz~PILBno5w}>9TeuS+CHSzB zrW?S_7qPQa+al~7T%@PEHT4U5CdbALe#e`^V{=R%GOVv;L}c-#&a!EK?1i2#1R?_= zDW3E%`+q2}2N}y(9_8fV` zSnMuuu+KQ_;WiR9AQ?wy#MK5eyvU;8I!mfZhnoSgn5{NUiB($@Hm57M?N?dKCGuGP zgWXZri1Ek9TCjouF*iMB+Vza)=;qF2*-cJ%e{rP9`Vj};6B33#N9H&A(;za6)!@t4 z=M(fmiyAqOutxIKFE-+1Pzm1?`v>#;02aPsMB#>Tk@eiUG9K)wG5AOaZlj1`@hFLZ z!qr+NpW1`gPFkJ+!L|W>#oRDWS5YxLry6I$K1kgCy_YiEiod#+hE&75sX_Bk_43<%W~x4#EkPK_=1LrfwdO}6rlA#XS{$Cg?Lr;$w4P1D z%!ye+^BFnwh@@2Kc40bA=ND`LdttEPebOx!OVql1Xk8mBlxM;31ib3io?Cy-4^j)F zqg-4iJafr^gTLrA4OB>WXwetqA)mGQF`6y!O0}k)b7xTzl#$%b zLk!6(>S!A_VIH-rIPOJ!*2er4`(^WHVp|J!8S{6^P56{1FJ|bc0_MfA?HcQwKS>cj1z*mQPxrNiz}`ehJ1GET+ds{O(0uQr@jN6`@$U z3}{^vU0;UcdcB?#DJR?GF?mKl$eLTyCsUMIheOCkF2RGb>+h9s7sAK-owShiojgzm zcEux#xS!@?tnDQQI z!=#ch-E&Hm+a*e{lRk@(7U3JKLpC2Ir>n@iYGa_{(9A@KSxBb8_B~8=9d>fGu0Zv~ z68kKc-!cL@%#tduYLT^aGme+=mG11DK2NW+#%BXMS&qD$Tpoz7MO?0BlNR`WR7R-p zMMkLm1is)j-&1*nHyJT*pXN)7M^5vV6J8pf6J8cGUCywNZ#+;)tqYYz`g4%?w}Cu1eAjCdfBxLEO}0K><1Q%O4UqqeKCtkDY<(bPZd8>3_e&pI z!QHl2z;WC-RTH1Tj4^|ZRq90Va`oV|i^`ak?uKy?WgDd{N5B*?* zIaDI_t@BNx_-{l=g%-TyY5n287{yi-*l3m3A}7I{cul$0(@ILEVNeA4AzVLs) zKH00jFbS-PzVMxYMPGR2FAUUwSzk!3{nzw`$K<;lec{dm;Glb=miEvWrrSVvpNsm^ z7pf`#KhYNow7Grg3vWK7h}(<4@MlWc0y(2FglvU@SvtKm?pWIXs+13Z-JusBWJ=go8tfQLt`ex=J4GtXNr@OM2r~ zTWBxG*tCHziLvR;jx;2dSZoM%)A(Os+B+`#GKdX}hWIgoVr<5&XT9^JaFki(k<9=o zl<1H{j>Ke;^8Q^y!jLG~7pt2~n}}#L!0E7E8eADgKf&m_rKNc|R*{tVL8{SWY~%Gw zF+4F_BFc@JqP9dX(fAbXQk)|sMa5J)oEU);kpi+OKIQ!ft@7kRIhsUw$$y{a5nejk zeIGmOyBG0T0@5#0u+~`b-XVb7oj6XaOjAL6h^;xZ(Zq4+y766`Q(pfv;nAa(!@0rO zk@6`RbN%E_aW_8Ljn5NJwM_GaslC(0m9|RbO+K*>K1*ocyM}Cg4r@81cl530<X$}~iBz@5hNyIe|;n$(Fh?Tr#AWK)8H7;?|Ab?7l8LyzYD zp$D#tEP4cT>2ZS`sCi`ak3yDaAy}Vec}5uhe@K?m4q2MhWKol@j1QX_x>3Mkc%_HN zBkKN1QgdQIl8wxtU?C0IkyW1aEipS23=nhz4!_P&N_jUtE@M^f;TmvA&SnNN0f%nH z0O3;hfyf>${%bAn1i_skJEH73xWm~CkN?Bdx>43YNJ* zzh_h4Q54iLM!h>h?uK`dh2+x%q!o5FJ}UvYRVJ11Pkf_J8C4>7-0(Y>XYX_^<3TVIo)6H`JsqsQ02x7 zcx-!O_2#BQL}wIiA;Z*cLJP)~1A8-=)RD_!V5&lepPOu5!bgDB3hqK>Mh&SckeD zzei*ciD3!e6^Z2T#Px`*WWT(|GYnv;r@XTs6SmS+WgLB!LQ@gT27(bM2fiS=iWK5U zmGhv=ePCotOyVuYWIrF-XSKND7Na7&0wX9pzp^7XbUZj)-!k-gv+e(Edi+#1lAiQ9 zO@`$D(Ib6AZx%gf!v5_4BzoEL+d9 zJCMkXV8!Y{Mn#vM*KGk!eUF{gjakALUgo)D6Jy^V?`&AVqf1001C^nU$a&SeRm>gC z%jL3KC}VOCJmvZrkz&SuM#Wkgh8vkEyW~!P7Ieu*?;U77tJz$Q>qp|hGGSKs%iI$) zFpUz5KL>ReoqN4ihMUeXze*z3UKD+yMDN*oPNP}rg!Wg)yjCPPKIC_?uMj=?EN2E);}sL8=H3%D|QR=^|Pcgj8n zIkT|3eGV%1dh5I05O_@nfh#DU2IS6}il&{J4&LqU6HPl6P5QmG#eRh}avwQ3jh4cp zpye4me*i2n6c%TfKI-~gS-P%88{v_fPMpWqGM)v^V>q6ykzD}w=C}u? z(O3<3tZ|PT)g6(i#fnkstnG5uB?68=s7kMHHU3GC-jM*nfb0j)H&V}W)KYQsJs_?U zcs1U*c-H&nNtS{k_{$zo z_OY2nRzOjL*jTH*&Qo?{ghMD9o17IWBkciF!@Evw_heD?7~Z^{~RXE6kiH#G*U zKW#eMh~Ki<5p~l}78?jTifz67TKkqsb!)JC$MjbM)&FQZQH!p#>g;!=vVw<8hpV^;lPGIsN8AJ`!#>Sb0B;6OrU~Brj zM)e-q<4WI%_E|Oa0FnSiJNbIg^bdpPt3h*%>I=c@SDJ`_AW(qx6{}{Bn0`ut1%SC; z%j(HNaBDtC2yj6gj~yJsd=Q8(FX6-Kox$oiW*8ybPQxRkkT$8RY}g9*=U9?AB3DtTra+pR~p3-sL}NG#WFiGsL*iTg3e+(Qkt7Koj{GY~ru%~Ul_(cl&d%SV9SQL#bIhD5DFOy!2%t=v24MR znM|?-!(d+^J`9|!#~05ZNfkQaQFvXpu;~M zr92h>LC)-U_~(tLfQ?8gb=LGT0TWb_=9aQH|FA0*{6Qr_E<7Ylb2&pHc1Q?(hsc8x zh^_#pH>N)ssQz-sWx@CbRu(_8%Jh0_;UytnPQhNS00RB=HPjUIODV6F6iK zNv@mdcDAD?sQNvvIx>ewJgrBuC<;`68pguV-yyM@3xvePWD5_NW3?_LcAycvgdp;< zB_Y|J${_?D*m0pW0ZA9agwhKg9C9!OgM=nml=7R$g95Q{&^a-utSC*qEPMbs!scwp z0_5u50su{NoCgaxO+p913y$D)#nCu`P-YB@`NJGb-<2UV(4xM5q`mJ2;>5MedjlL6 z=eP`@QZ80Dr$K>?-=I>*RFLD+5~nx}YXo9fF_Kv$1!584LC==cUxigkhn!h6^_Y** z2aaOXLl}!nzP-tuvB7AJwt<}XlH{ABpWAb@DBZn%KSI7obY*|f>JRXJz|0v?(e~2h zE4lT!3cQXVTR)1bFZbMWkFJ*`H@=z_WMO%qXx8+B z={oxM06F18_JG94_>A}{bS(mD+u!X^!axs3FPXDzL>^|fvOCcH&#jXlf4DS z6)k$rsB(_VzFho2&$#B4pjZen3V$rI+wEWE+G+CV)(D4Hic@gM7I*$-Ag!}rW|hbM z&?q0r2UquMy_iS;^=nt15NVu|#5S0W7f-8K&9L1MwvpZuwcwtD&EztTDZ1!=@8#solR5G#RE~7=KvwYZLL?;*w!6ed ztB!{{tyRAlnqQQW5~1zZ6Fg%-IDz3;9R|H?8lX2PzG$R%r`2(kECs?B2IDoLL{|sL zmqMF#ATLM4J#S5;4)#C|&s2QzcIyhQ_^QJ~V7i`~>yG)Pt`XX0MzzpjQ}Rj{tL z8=2tNDl3L{){zSArR7F^qFb*uKXN)V2P1 z((!aXL=|kep5_^cFB~Ry+2DB&qQ2;y0d_>-_LO(&{Yt1@oKj+|U7|DP{i&2dss_+! z7TlmycIZTj=3D!%98QLdn|#8_SL>{O)u$_5`H1vH9zt-jY1sxX1mRtRBD@9rl7r$Q zX0<{N!1i|$4;d-=3>KtZDfoMR(nAW~#pC^xg5MUSlq&+S;wE=IMn6D#dMzlMWH$#m zUYFg%t}F|h8*rR>?kE>4I9-C{$s-|xz08P>K@-Q~5YFpo=Q7;oj>l`z`@hSQ1*Jdw zQNKWnH8|#2R>z;t`8xIuZVFZh%-U65fzgGlnmE$oxlqAs_i^E>39-Ue^166Jj6Y&3 zi%&YZU!eNM*(>=IDU(S0g4KMYb-1N>YUxmX0u1d>xgB6jNvL|`oEk=8X8dXUqlc|( zVx?BNii+GivRXX9TNShIa>Ib`rd7pq=-Qo!s0-~moV}`8P=ZdI zjg~ui>u40b_JU2-cWr)Mt&&=tmq8p9n3+7ScgX0A4I7^A&j^^Ta2r@^YzR~z)HG7U z5AdNKm&FhME+d+NwZ&V->NiHNi|W;p_c;705WB26d3vC_zAF$nx|)vG`CGIoR*JHg zC(|W{dil8epy}_jwhzQEFBU~TRJ|hdL&F?~=QEcZp67gI&L-N2ewA5>Zm{($bdZ8e`B5n7kNmR!fffXmGx_`bXluUdPoR{{? zD4rSLbFH8`g(dFI$RHMX(GQV9oG;Jv^I1$kb1u~BI9;AS)IKE1Y71$!x~YKUeuG@rOCkPF&mrC4$z|8cpq&B;=Z(WvMZSV*9n};9*B); z55=x)XVH99dkOoDJa=wqECtO|hD-Q6OF1

vmm1X>?@?iwFNCL@d(Z7Et>*B^pPP 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