diff --git a/ROMVault2.sln b/ROMVault2.sln new file mode 100644 index 0000000..602de35 --- /dev/null +++ b/ROMVault2.sln @@ -0,0 +1,30 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0.30501.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ROMVault2", "ROMVault2\ROMVault2.csproj", "{437E12AB-46F3-4A75-A3D5-6C524B5A79B5}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{FFD35B18-3366-4460-9095-2B520EE73C87}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {437E12AB-46F3-4A75-A3D5-6C524B5A79B5}.Debug|Any CPU.ActiveCfg = Debug|x86 + {437E12AB-46F3-4A75-A3D5-6C524B5A79B5}.Debug|Any CPU.Build.0 = Debug|x86 + {437E12AB-46F3-4A75-A3D5-6C524B5A79B5}.Debug|x86.ActiveCfg = Debug|x86 + {437E12AB-46F3-4A75-A3D5-6C524B5A79B5}.Debug|x86.Build.0 = Debug|x86 + {437E12AB-46F3-4A75-A3D5-6C524B5A79B5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {437E12AB-46F3-4A75-A3D5-6C524B5A79B5}.Release|Any CPU.Build.0 = Release|Any CPU + {437E12AB-46F3-4A75-A3D5-6C524B5A79B5}.Release|x86.ActiveCfg = Release|Any CPU + {437E12AB-46F3-4A75-A3D5-6C524B5A79B5}.Release|x86.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/ROMVault2/BackGroundWorkerInterface.cs b/ROMVault2/BackGroundWorkerInterface.cs new file mode 100644 index 0000000..4e11ae6 --- /dev/null +++ b/ROMVault2/BackGroundWorkerInterface.cs @@ -0,0 +1,152 @@ +/****************************************************** + * ROMVault2 is written by Gordon J. * + * Contact gordon@romvault.com * + * Copyright 2014 * + ******************************************************/ + +using ROMVault2.SupportedFiles; + +namespace ROMVault2 +{ + + + public class bgwProgress + { + public bgwProgress(int Progress) + { + this.Progress = Progress; + } + public int Progress { get; private set; } + } + + + public class bgwText + { + public bgwText(string Text) + { + this.Text = Text; + } + + public string Text { get; private set; } + } + public class bgwText2 + { + public bgwText2(string Text) + { + this.Text = Text; + } + + public string Text { get; private set; } + } + public class bgwText3 + { + public bgwText3(string Text) + { + this.Text = Text; + } + + public string Text { get; private set; } + } + + + public class bgwSetRange + { + public bgwSetRange(int MaxVal) + { + this.MaxVal = MaxVal; + } + + public int MaxVal { get; private set; } + } + public class bgwSetRange2 + { + public bgwSetRange2(int MaxVal) + { + this.MaxVal = MaxVal; + } + + public int MaxVal { get; private set; } + } + + + + public class bgwValue2 + { + public bgwValue2(int Value) + { + this.Value = Value; + } + + public int Value { get; private set; } + } + + + public class bgwRange2Visible + { + public bgwRange2Visible(bool Visible) + { + this.Visible = Visible; + } + + public bool Visible { get; private set; } + } + + public class bgwShowCorrupt + { + public bgwShowCorrupt(ZipReturn zr, string filename) + { + this.zr = zr; + this.filename = filename; + } + + public ZipReturn zr { get; private set; } + public string filename { get; private set; } + } + + public class bgwShowError + { + public bgwShowError(string filename, string error) + { + this.error = error; + this.filename = filename; + } + + public string filename { get; private set; } + public string error { get; private set; } + } + + + public class bgwShowFix + { + public bgwShowFix(string fixDir, string fixZip, string fixFile, ulong? size, string dir, string sourceDir, string sourceZip, string sourceFile) + { + FixDir = fixDir; + FixZip = fixZip; + FixFile = fixFile; + Size = size.ToString(); + Dir = dir; + SourceDir = sourceDir; + SourceZip = sourceZip; + SourceFile = sourceFile; + } + + public string FixDir { get; private set; } + public string FixZip { get; private set; } + public string FixFile { get; private set; } + public string Size { get; private set; } + public string Dir { get; private set; } + public string SourceDir { get; private set; } + public string SourceZip { get; private set; } + public string SourceFile { get; private set; } + } + + public class bgwShowFixError + { + public bgwShowFixError(string FixError) + { + this.FixError = FixError; + } + + public string FixError { get; private set; } + } +} diff --git a/ROMVault2/DBHelper.cs b/ROMVault2/DBHelper.cs new file mode 100644 index 0000000..02211fe --- /dev/null +++ b/ROMVault2/DBHelper.cs @@ -0,0 +1,507 @@ +/****************************************************** + * ROMVault2 is written by Gordon J. * + * Contact gordon@romvault.com * + * Copyright 2013 * + ******************************************************/ + +using System; +using System.Collections.Generic; +using ROMVault2.RvDB; +using ROMVault2.Utils; + +namespace ROMVault2 +{ + public enum EFile + { + Keep, + Delete + } + + public static class DBHelper + { + + + private static readonly byte[] ZeroByteMD5; + private static readonly byte[] ZeroByteSHA1; + private static readonly byte[] ZeroByteCRC; + + static DBHelper() + { + ZeroByteMD5 = VarFix.CleanMD5SHA1("d41d8cd98f00b204e9800998ecf8427e", 32); + ZeroByteSHA1 = VarFix.CleanMD5SHA1("da39a3ee5e6b4b0d3255bfef95601890afd80709", 40); + ZeroByteCRC = VarFix.CleanMD5SHA1("00000000", 8); + } + + + + public static void GetSelectedDirList(ref List lstDir) + { + GetSelectedDirList(ref lstDir, DB.DirTree); + } + private static void GetSelectedDirList(ref List lstDir, RvDir thisDir) + { + for (int i = 0; i < thisDir.ChildCount; i++) + { + if (thisDir.DatStatus != DatStatus.InDatCollect) continue; + RvDir tDir = thisDir.Child(i) as RvDir; + if (tDir == null) continue; + if (tDir.Tree == null) continue; + if (tDir.Tree.Checked == RvTreeRow.TreeSelect.Selected) + lstDir.Add(tDir); + + GetSelectedDirList(ref lstDir, tDir); + } + } + + + public static int CompareName(RvBase var1, RvBase var2) + { + int retv = TrrntZipStringCompare(var1.Name, var2.Name); + if (retv != 0) return retv; + + FileType f1 = var1.FileType; + FileType f2 = var2.FileType; + + if (f1 == FileType.ZipFile) + { + if (f2 != FileType.ZipFile) + ReportError.SendAndShow("Incompatible Compare type"); + + return Math.Sign(String.Compare(var1.Name, var2.Name, StringComparison.Ordinal)); + } + return f1.CompareTo(f2); + } + + private static int TrrntZipStringCompare(string string1, string string2) + { + char[] bytes1 = string1.ToCharArray(); + char[] bytes2 = string2.ToCharArray(); + + int pos1 = 0; + int pos2 = 0; + + for (; ; ) + { + if (pos1 == bytes1.Length) + return ((pos2 == bytes2.Length) ? 0 : -1); + if (pos2 == bytes2.Length) + return 1; + + int byte1 = bytes1[pos1++]; + int byte2 = bytes2[pos2++]; + + if (byte1 >= 65 && byte1 <= 90) byte1 += 0x20; + if (byte2 >= 65 && byte2 <= 90) byte2 += 0x20; + + if (byte1 < byte2) + return -1; + if (byte1 > byte2) + return 1; + } + } + + + + + public static int DatCompare(RvDat var1, RvDat var2) + { + int retv = Math.Sign(string.Compare(var1.GetData(RvDat.DatData.DatFullName), var2.GetData(RvDat.DatData.DatFullName), StringComparison.CurrentCultureIgnoreCase)); + if (retv != 0) return retv; + + + retv = Math.Sign(var1.TimeStamp.CompareTo(var2.TimeStamp)); + if (retv != 0) return retv; + + retv = Math.Sign(var1.AutoAddDirectory.CompareTo(var2.AutoAddDirectory)); + if (retv != 0) return retv; + + return 0; + } + + public static string GetRealPath(string rootPath) + { + string strFullPath = ""; + int lenFound = 0; + foreach (DirMap dirPathMap in Settings.DirPathMap) + { + string dirKey = dirPathMap.DirKey; + int dirKeyLen = dirKey.Length; + + if (rootPath.Length >= dirKeyLen) + if (String.Compare(rootPath.Substring(0, dirKeyLen), dirKey, StringComparison.Ordinal) == 0) + { + if (lenFound < dirKeyLen) + { + string dirPath = dirPathMap.DirPath; + lenFound = dirKeyLen; + strFullPath = rootPath == dirKey ? dirPath : IO.Path.Combine(dirPath, rootPath.Substring(dirKeyLen + 1)); + } + } + } + return strFullPath; + } + + public static string GetDatPath(string rootPath) + { + if (rootPath == "") + return Settings.DatRoot; + if (rootPath.Substring(0, 6) == "ToSort") + return "Error"; + if (rootPath.Substring(0, 8) == "RomVault") + return Settings.DatRoot + rootPath.Substring(8); + + return Settings.DatRoot; + + } + + + + + + + + public static void GetSelectedFilesSortCRCSize(out List lstFiles) + { + lstFiles = new List(); + GetSelectedFilesSortCRCSize(ref lstFiles, DB.DirTree, true); + RomSortCRCSize(lstFiles); + } + private static void GetSelectedFilesSortCRCSize(ref List lstFiles, RvBase val, bool selected) + { + if (selected) + { + RvFile rvFile = val as RvFile; + if (rvFile != null) + { + if ((rvFile.Size != null && rvFile.CRC != null) || rvFile.Size == 0) + lstFiles.Add(rvFile); + } + } + + RvDir rvVal = val as RvDir; + if (rvVal == null) return; + + for (int i = 0; i < rvVal.ChildCount; i++) + { + bool nextSelect = selected; + if (rvVal.Tree != null) + nextSelect = rvVal.Tree.Checked == RvTreeRow.TreeSelect.Selected; + GetSelectedFilesSortCRCSize(ref lstFiles, rvVal.Child(i), nextSelect); + } + } + + private static void RomSortCRCSize(List lstFiles) + { + RomSortCRCSize(0, lstFiles.Count, lstFiles); + } + private static void RomSortCRCSize(int intBase, int intTop, List lstFiles) + { + if ((intTop - intBase) <= 1) return; + int intMiddle = (intTop + intBase) / 2; + + if ((intMiddle - intBase) > 1) + RomSortCRCSize(intBase, intMiddle, lstFiles); + + if ((intTop - intMiddle) > 1) + RomSortCRCSize(intMiddle, intTop, lstFiles); + + int intBottomSize = intMiddle - intBase; + int intTopSize = intTop - intMiddle; + + RvFile[] lstBottom = new RvFile[intBottomSize]; + RvFile[] lstTop = new RvFile[intTopSize]; + + for (int intloop = 0; intloop < intBottomSize; intloop++) + lstBottom[intloop] = lstFiles[intBase + intloop]; + + for (int intloop = 0; intloop < intTopSize; intloop++) + lstTop[intloop] = lstFiles[intMiddle + intloop]; + + int intBottomCount = 0; + int intTopCount = 0; + int intCount = intBase; + + while (intBottomCount < intBottomSize && intTopCount < intTopSize) + { + if (RomSortCRCSizeFunc(lstBottom[intBottomCount], lstTop[intTopCount]) < 1) + { + lstFiles[intCount] = lstBottom[intBottomCount]; + intCount++; + intBottomCount++; + } + else + { + lstFiles[intCount] = lstTop[intTopCount]; + intCount++; + intTopCount++; + } + } + + while (intBottomCount < intBottomSize) + { + lstFiles[intCount] = lstBottom[intBottomCount]; + intCount++; + intBottomCount++; + } + while (intTopCount < intTopSize) + { + lstFiles[intCount] = lstTop[intTopCount]; + intCount++; + intTopCount++; + } + } + private static int RomSortCRCSizeFunc(RvFile a, RvFile b) + { + int retv = ArrByte.iCompare(a.CRC, b.CRC); + + if (retv == 0) + retv = ULong.iCompare(a.Size, b.Size); + + return retv; + } + + public static int RomSearchCRCSize(RvFile tRom, List lstFiles, out int index) + { + if (lstFiles.Count == 0) + { + index = 0; + return -1; + } + + // this one below method will always return the first item in a list if there is more than one matching result. + int intBottom = -1; + int intTop = lstFiles.Count - 1; + + while (intBottom + 1 < intTop) + { + int intMid = (intBottom + intTop + 1) / 2; + + int intRes = RomSortCRCSizeFunc(lstFiles[intMid], tRom); + if (intRes >= 0) + intTop = intMid; + else + intBottom = intMid; + + } + intBottom++; + index = intBottom; + return RomSortCRCSizeFunc(lstFiles[intBottom], tRom); + } + + // find all of the files that we think we have that match the needed CRC and Size. + public static void RomSearchFindFixes(RvFile tRom, List lstFiles, out List lstFilesOut) + { + lstFilesOut = new List(); + if (tRom.CRC == null || tRom.Size == null) + return; + + int intIndex; + int intRes = RomSearchCRCSize(tRom, lstFiles, out intIndex); + + while (intRes == 0) + { + if (lstFiles[intIndex].GotStatus == GotStatus.Got && FindFixes.CheckIfMissingFileCanBeFixedByGotFile(tRom, lstFiles[intIndex])) + lstFilesOut.Add(lstFiles[intIndex]); + + intIndex++; + intRes = intIndex < lstFiles.Count ? RomSortCRCSizeFunc(lstFiles[intIndex], tRom) : 1; + } + } + + // find all of the files that we think we have that match the needed CRC and Size. + public static void RomSearchFindMatchingFiles(RvFile tRom, List lstFiles, out int startIndex, out int length) + { + int intIndex; + int intRes = RomSearchCRCSize(tRom, lstFiles, out intIndex); + startIndex = intIndex; + + while (intRes == 0) + { + intIndex++; + intRes = intIndex < lstFiles.Count ? RomSortCRCSizeFunc(lstFiles[intIndex], tRom) : 1; + } + length = intIndex - startIndex; + } + + + public static bool IsZeroLengthFile(RvFile tFile) + { + if (tFile.MD5 != null) + { + if (!ArrByte.bCompare(tFile.MD5, ZeroByteMD5)) + return false; + } + + if (tFile.SHA1 != null) + { + if (!ArrByte.bCompare(tFile.SHA1, ZeroByteSHA1)) + return false; + } + + if (tFile.CRC != null) + if (!ArrByte.bCompare(tFile.CRC, ZeroByteCRC)) + return false; + + return tFile.Size == 0; + } + + public static bool RomFromSameGame(RvFile a, RvFile b) + { + if (a.Parent == null) + return false; + if (b.Parent == null) + return false; + + return a.Parent == b.Parent; + } + + + + public static void GetSelectedFilesSortSHA1CHD(out List lstFiles) + { + lstFiles = new List(); + GetSelectedFilesSortSHA1CHD(ref lstFiles, DB.DirTree, true); + RomSortSHA1CHD(lstFiles); + } + private static void GetSelectedFilesSortSHA1CHD(ref List lstFiles, RvBase val, bool selected) + { + if (selected) + { + RvFile rvFile = val as RvFile; + if (rvFile != null) + { + if (rvFile.SHA1CHD != null) + lstFiles.Add(rvFile); + } + } + + RvDir rvVal = val as RvDir; + if (rvVal == null) return; + + for (int i = 0; i < rvVal.ChildCount; i++) + { + bool nextSelect = selected; + if (rvVal.Tree != null) + nextSelect = rvVal.Tree.Checked == RvTreeRow.TreeSelect.Selected; + GetSelectedFilesSortSHA1CHD(ref lstFiles, rvVal.Child(i), nextSelect); + } + } + + private static void RomSortSHA1CHD(List lstFiles) + { + RomSortSHA1CHD(0, lstFiles.Count, lstFiles); + } + private static void RomSortSHA1CHD(int intBase, int intTop, List lstFiles) + { + if ((intTop - intBase) <= 1) return; + int intMiddle = (intTop + intBase) / 2; + + if ((intMiddle - intBase) > 1) + RomSortSHA1CHD(intBase, intMiddle, lstFiles); + + if ((intTop - intMiddle) > 1) + RomSortSHA1CHD(intMiddle, intTop, lstFiles); + + int intBottomSize = intMiddle - intBase; + int intTopSize = intTop - intMiddle; + + RvFile[] lstBottom = new RvFile[intBottomSize]; + RvFile[] lstTop = new RvFile[intTopSize]; + + for (int intloop = 0; intloop < intBottomSize; intloop++) + lstBottom[intloop] = lstFiles[intBase + intloop]; + + for (int intloop = 0; intloop < intTopSize; intloop++) + lstTop[intloop] = lstFiles[intMiddle + intloop]; + + int intBottomCount = 0; + int intTopCount = 0; + int intCount = intBase; + + while (intBottomCount < intBottomSize && intTopCount < intTopSize) + { + if (RomSortSHA1CHDFunc(lstBottom[intBottomCount], lstTop[intTopCount]) < 1) + { + lstFiles[intCount] = lstBottom[intBottomCount]; + intCount++; + intBottomCount++; + } + else + { + lstFiles[intCount] = lstTop[intTopCount]; + intCount++; + intTopCount++; + } + } + + while (intBottomCount < intBottomSize) + { + lstFiles[intCount] = lstBottom[intBottomCount]; + intCount++; + intBottomCount++; + } + while (intTopCount < intTopSize) + { + lstFiles[intCount] = lstTop[intTopCount]; + intCount++; + intTopCount++; + } + } + private static int RomSortSHA1CHDFunc(RvFile a, RvFile b) + { + int retv = ArrByte.iCompare(a.SHA1CHD, b.SHA1CHD); + + return retv; + } + + + private static int RomSearchSHA1CHD(RvFile tRom, List lstFiles, out int index) + { + if (lstFiles.Count == 0) + { + index = 0; + return -1; + } + + // this one below method will always return the first item in a list if there is more than one matching result. + int intBottom = -1; + int intTop = lstFiles.Count - 1; + + while (intBottom + 1 < intTop) + { + int intMid = (intBottom + intTop + 1) / 2; + + int intRes = RomSortSHA1CHDFunc(lstFiles[intMid], tRom); + if (intRes >= 0) + intTop = intMid; + else + intBottom = intMid; + + } + intBottom++; + index = intBottom; + return RomSortSHA1CHDFunc(lstFiles[intBottom], tRom); + } + + + // find all of the files that we have that match the needed SHA1 CHD. + public static void RomSearchFindFixesSHA1CHD(RvFile tRom, List lstFiles, out List lstFilesOut) + { + lstFilesOut = new List(); + if (tRom.SHA1CHD == null) + return; + + int intIndex; + int intRes = RomSearchSHA1CHD(tRom, lstFiles, out intIndex); + + while (intRes == 0) + { + if (lstFiles[intIndex].GotStatus == GotStatus.Got) + lstFilesOut.Add(lstFiles[intIndex]); + + intIndex++; + intRes = intIndex < lstFiles.Count ? RomSortSHA1CHDFunc(lstFiles[intIndex], tRom) : 1; + } + } + } +} diff --git a/ROMVault2/DatMaker.cs b/ROMVault2/DatMaker.cs new file mode 100644 index 0000000..e86175c --- /dev/null +++ b/ROMVault2/DatMaker.cs @@ -0,0 +1,105 @@ +/****************************************************** + * ROMVault2 is written by Gordon J. * + * Contact gordon@romvault.com * + * Copyright 2014 * + ******************************************************/ + +using System; +using System.IO; +using ROMVault2.RvDB; + +namespace ROMVault2 +{ + public static class DatMaker + { + private static StreamWriter _sw; + private static string _datName; + private static string _datDir; + public static void MakeDatFromDir(RvDir startingDir) + { + _datName = startingDir.Name; + _datDir = startingDir.Name; + Console.WriteLine("Creating Dat: " + startingDir.Name + ".dat"); + _sw = new StreamWriter(startingDir.Name + ".dat"); + + WriteDatFile(startingDir); + + _sw.Close(); + + Console.WriteLine("Dat creation complete"); + Console.ReadLine(); + } + + private static void WriteDatFile(RvDir dir) + { + WriteLine(""); + WriteLine(""); + WriteLine(""); + WriteHeader(); + + /* write Games/Dirs */ + ProcessDir(dir); + + WriteLine(""); + } + + private static void WriteHeader() + { + WriteLine("
"); + WriteLine(" " + clean(_datName) + ""); + WriteLine(" " + clean(_datDir) + ""); + WriteLine("
"); + } + + private static void WriteLine(string s) + { + _sw.WriteLine(s); + } + + private static string clean(string s) + { + s = s.Replace("\"", """); + s = s.Replace("'", "'"); + s = s.Replace("<", "<"); + s = s.Replace(">", ">"); + s = s.Replace("&", "&"); + return s; + } + + + private static void ProcessDir(RvDir dir, int depth = 1) + { + string d = new string(' ', 4 * depth); + + for (int i = 0; i < dir.ChildCount; i++) + { + RvDir game = dir.Child(i) as RvDir; + if (game != null && game.FileType == FileType.Zip) + { + WriteLine(d + ""); + WriteLine(d + " " + clean(Path.GetFileNameWithoutExtension(game.Name)) + ""); + + + for (int j = 0; j < game.ChildCount; j++) + { + RvFile file = game.Child(j) as RvFile; + if (file != null) + { + WriteLine(d + " "); + } + } + WriteLine(d + ""); + } + if (game != null && game.FileType == FileType.Dir) + { + WriteLine(d + ""); + ProcessDir(game, depth + 1); + WriteLine(d + ""); + } + } + } + + + + } +} diff --git a/ROMVault2/DatReaders/DatCmpReader.cs b/ROMVault2/DatReaders/DatCmpReader.cs new file mode 100644 index 0000000..35f1b38 --- /dev/null +++ b/ROMVault2/DatReaders/DatCmpReader.cs @@ -0,0 +1,615 @@ +/****************************************************** + * ROMVault2 is written by Gordon J. * + * Contact gordon@romvault.com * + * Copyright 2014 * + ******************************************************/ + +using System; +using System.ComponentModel; +using System.IO; +using ROMVault2.Properties; +using ROMVault2.RvDB; +using ROMVault2.Utils; + +namespace ROMVault2.DatReaders +{ + public static class DatCmpReader + { + private static bool _cleanFileNames = true; + + + public static bool ReadDat(ref RvDir tDat, string strFilename) + { + RvDir tNow = tDat; + FileType thisFileType = FileType.ZipFile; + + int errorCode = DatFileLoader.LoadDat(strFilename); + if (errorCode != 0) + { + DatUpdate.ShowDat(new Win32Exception(errorCode).Message, strFilename); + return false; + } + + DatFileLoader.Gn(); + if (DatFileLoader.EndOfStream()) + return false; + if (DatFileLoader.Next.ToLower() == "clrmamepro") + { + _cleanFileNames = true; + DatFileLoader.Gn(); + if (!LoadHeaderFromDat(ref tNow, ref thisFileType)) + return false; + DatFileLoader.Gn(); + } + if (DatFileLoader.Next.ToLower() == "romvault") + { + _cleanFileNames = false; + DatFileLoader.Gn(); + if (!LoadHeaderFromDat(ref tNow, ref thisFileType)) + return false; + DatFileLoader.Gn(); + } + + if (tNow.Dat == null) + { + tNow.Dat = new RvDat(); + string cleanedName = IO.Path.GetFileNameWithoutExtension(strFilename); + tNow.Dat.AddData(RvDat.DatData.DatName, cleanedName); + tNow.Dat.AddData(RvDat.DatData.Description, cleanedName); + } + + + while (!DatFileLoader.EndOfStream()) + { + switch (DatFileLoader.Next.ToLower()) + { + case "dir": + DatFileLoader.Gn(); + if (!LoadDirFromDat(ref tNow, ref thisFileType)) + return false; + DatFileLoader.Gn(); + break; + case "game": + DatFileLoader.Gn(); + if (!LoadGameFromDat(ref tNow, false, thisFileType)) + return false; + DatFileLoader.Gn(); + break; + case "resource": + DatFileLoader.Gn(); + if (!LoadGameFromDat(ref tNow, true, thisFileType)) + return false; + DatFileLoader.Gn(); + break; + case "emulator": + DatFileLoader.Gn(); + if (!LoadEmulator()) + return false; + DatFileLoader.Gn(); + break; + default: + DatUpdate.SendAndShowDat(Resources.DatCmpReader_ReadDat_Error_keyword + DatFileLoader.Next + Resources.DatCmpReader_ReadDat_not_known, DatFileLoader.Filename); + DatFileLoader.Gn(); + break; + } + } + + DatFileLoader.Close(); + + return true; + } + + + private static bool LoadHeaderFromDat(ref RvDir tDir, ref FileType thisFileType) + { + + if (DatFileLoader.Next != "(") + { + DatUpdate.SendAndShowDat(Resources.DatCmpReader_LoadHeaderFromDat_not_found_after_clrmamepro, DatFileLoader.Filename); + return false; + } + DatFileLoader.Gn(); + + string forceZipping = ""; + + RvDat tDat = new RvDat(); + while (DatFileLoader.Next != ")") + { + switch (DatFileLoader.Next.ToLower()) + { + case "name": tDat.AddData(RvDat.DatData.DatName, VarFix.CleanFileName(DatFileLoader.GnRest())); DatFileLoader.Gn(); break; + case "description": tDat.AddData(RvDat.DatData.Description, DatFileLoader.GnRest()); DatFileLoader.Gn(); break; + case "category": tDat.AddData(RvDat.DatData.Category, DatFileLoader.GnRest()); DatFileLoader.Gn(); break; + case "version": tDat.AddData(RvDat.DatData.Version, DatFileLoader.GnRest()); DatFileLoader.Gn(); break; + case "date": tDat.AddData(RvDat.DatData.Date, DatFileLoader.GnRest()); DatFileLoader.Gn(); break; + case "author": tDat.AddData(RvDat.DatData.Author, DatFileLoader.GnRest()); DatFileLoader.Gn(); break; + case "email": tDat.AddData(RvDat.DatData.Email, DatFileLoader.GnRest()); DatFileLoader.Gn(); break; + case "homepage": tDat.AddData(RvDat.DatData.HomePage, DatFileLoader.GnRest()); DatFileLoader.Gn(); break; + case "url": tDat.AddData(RvDat.DatData.URL, DatFileLoader.GnRest()); DatFileLoader.Gn(); break; + + case "comment": DatFileLoader.GnRest(); DatFileLoader.Gn(); break; + case "header": DatFileLoader.GnRest(); DatFileLoader.Gn(); break; + case "forcezipping": forceZipping = DatFileLoader.GnRest(); DatFileLoader.Gn(); break; + case "forcepacking": DatFileLoader.GnRest(); DatFileLoader.Gn(); break; // incorrect usage + case "forcemerging": tDat.AddData(RvDat.DatData.MergeType, DatFileLoader.GnRest()); DatFileLoader.Gn(); break; + case "forcenodump": DatFileLoader.GnRest(); DatFileLoader.Gn(); break; + case "dir": tDat.AddData(RvDat.DatData.DirSetup, DatFileLoader.GnRest()); DatFileLoader.Gn(); break; + default: + DatUpdate.SendAndShowDat(Resources.DatCmpReader_ReadDat_Error_keyword + DatFileLoader.Next + Resources.DatCmpReader_LoadHeaderFromDat_not_known_in_clrmamepro, DatFileLoader.Filename); + DatFileLoader.Gn(); + break; + } + } + + thisFileType = forceZipping.ToLower() != "no" ? FileType.ZipFile : FileType.File; + tDir.Dat = tDat; + return true; + + } + + private static bool LoadEmulator() + { + if (DatFileLoader.Next != "(") + { + DatUpdate.SendAndShowDat("( not found after emulator", DatFileLoader.Filename); + return false; + } + DatFileLoader.Gn(); + while (DatFileLoader.Next != ")") + { + switch (DatFileLoader.Next.ToLower()) + { + case "name": DatFileLoader.GnRest(); DatFileLoader.Gn(); break; + case "version": DatFileLoader.GnRest(); DatFileLoader.Gn(); break; + } + } + return true; + } + + + + private static bool LoadDirFromDat(ref RvDir tDat, ref FileType thisFileType) + { + if (DatFileLoader.Next != "(") + { + DatUpdate.SendAndShowDat(Resources.DatCmpReader_LoadGameFromDat_not_found_after_game, DatFileLoader.Filename); + return false; + } + DatFileLoader.Gn(); + + if (DatFileLoader.Next.ToLower() != "name") + { + DatUpdate.SendAndShowDat(Resources.DatCmpReader_LoadGameFromDat_Name_not_found_as_first_object_in, DatFileLoader.Filename); + return false; + } + + RvDir parent = tDat; + + string fullname = VarFix.CleanFullFileName(DatFileLoader.GnRest()); + while (fullname.Contains("/")) + { + int firstSlash = fullname.IndexOf("/", StringComparison.Ordinal); + string dir = fullname.Substring(0, firstSlash); + dir = VarFix.CleanFileName(dir); + + fullname = fullname.Substring(firstSlash + 1); + int index; + if (parent.ChildNameSearch(new RvDir(FileType.Dir) { Name = dir }, out index) == 0) + { + parent = (RvDir)parent.Child(index); + } + else + { + RvDir tpDir = new RvDir(FileType.Dir) + { + Name = dir, + DatStatus = DatStatus.InDatCollect, + Dat = tDat.Dat, + Tree = new RvTreeRow() + }; + parent.ChildAdd(tpDir, index); + parent = tpDir; + } + } + + RvDir tDir = new RvDir(FileType.Dir) + { + Name = fullname + }; + + DatFileLoader.Gn(); + tDir.DatStatus = DatStatus.InDatCollect; + tDir.Dat = tDat.Dat; + + int index1; + if (parent.ChildNameSearch(tDir, out index1) == 0) + tDir = (RvDir)parent.Child(index1); + else + parent.ChildAdd(tDir, index1); + + while (DatFileLoader.Next != ")") + { + switch (DatFileLoader.Next.ToLower()) + { + case "dir": + DatFileLoader.Gn(); + if (!LoadDirFromDat(ref tDir, ref thisFileType)) + return false; + DatFileLoader.Gn(); + break; + case "game": + DatFileLoader.Gn(); + if (!LoadGameFromDat(ref tDir, false, thisFileType)) + return false; + DatFileLoader.Gn(); + break; + case "resource": + DatFileLoader.Gn(); + if (!LoadGameFromDat(ref tDir, true, thisFileType)) + return false; + DatFileLoader.Gn(); + break; + default: + DatUpdate.SendAndShowDat(Resources.DatCmpReader_LoadDirFromDat_Error_Keyword + DatFileLoader.Next + Resources.DatCmpReader_LoadDirFromDat_not_know_in_dir, DatFileLoader.Filename); + DatFileLoader.Gn(); + break; + } + } + return true; + } + + private static bool LoadGameFromDat(ref RvDir tDat, bool bolresource, FileType thisFileType) + { + if (DatFileLoader.Next != "(") + { + DatUpdate.SendAndShowDat(Resources.DatCmpReader_LoadGameFromDat_not_found_after_game, DatFileLoader.Filename); + return false; + } + DatFileLoader.Gn(); + + string snext = DatFileLoader.Next.ToLower(); + + string pathextra = ""; + if (snext == "rebuildto") + { + pathextra = VarFix.CleanFullFileName(DatFileLoader.Gn()); DatFileLoader.Gn(); + snext = DatFileLoader.Next.ToLower(); + } + + if (snext != "name") + { + DatUpdate.SendAndShowDat(Resources.DatCmpReader_LoadGameFromDat_Name_not_found_as_first_object_in, DatFileLoader.Filename); + return false; + } + + RvDir parent = tDat; + + string fullname = VarFix.CleanFullFileName(DatFileLoader.GnRest()); + if (_cleanFileNames) + fullname = fullname.Replace("/", "-"); + + if (!String.IsNullOrEmpty(pathextra)) + fullname = pathextra + "/" + fullname; + + while (fullname.Contains("/")) + { + int firstSlash = fullname.IndexOf("/", StringComparison.Ordinal); + string dir = fullname.Substring(0, firstSlash); + fullname = fullname.Substring(firstSlash + 1); + int index; + if (parent.ChildNameSearch(new RvDir(FileType.Dir) { Name = dir }, out index) == 0) + { + parent = (RvDir)parent.Child(index); + } + else + { + RvDir tpDir = new RvDir(FileType.Dir) + { + Name = dir, + DatStatus = DatStatus.InDatCollect, + Dat = tDat.Dat, + Tree = new RvTreeRow() + }; + parent.ChildAdd(tpDir, index); + parent = tpDir; + } + } + + RvDir tDir = new RvDir(thisFileType == FileType.File ? FileType.Dir : FileType.Zip) + { + Name = fullname, + DatStatus = DatStatus.InDatCollect, + Dat = tDat.Dat + }; + + int index1; + string testName = tDir.Name; + int nameCount = 0; + while (parent.ChildNameSearch(tDir, out index1) == 0) + { + tDir.Name = testName + "_" + nameCount; + nameCount++; + } + + DatFileLoader.Gn(); + tDir.Game = new RvGame(); + tDir.Game.AddData(RvGame.GameData.IsBios, bolresource ? "Yes" : "No"); + + RvDir tDirCHD = new RvDir(FileType.Dir) + { + Name = tDir.Name, + DatStatus = tDir.DatStatus, + Dat = tDir.Dat, + Game = tDir.Game + }; + + while (DatFileLoader.Next != ")") + { + switch (DatFileLoader.Next.ToLower()) + { + case "romof": tDir.Game.AddData(RvGame.GameData.RomOf, VarFix.CleanFileName(DatFileLoader.GnRest())); DatFileLoader.Gn(); break; + case "description": tDir.Game.AddData(RvGame.GameData.Description, DatFileLoader.GnRest()); DatFileLoader.Gn(); break; + + case "sourcefile": tDir.Game.AddData(RvGame.GameData.Sourcefile, DatFileLoader.GnRest()); DatFileLoader.Gn(); break; + case "cloneof": tDir.Game.AddData(RvGame.GameData.CloneOf, DatFileLoader.GnRest()); DatFileLoader.Gn(); break; + case "sampleof": tDir.Game.AddData(RvGame.GameData.SampleOf, DatFileLoader.GnRest()); DatFileLoader.Gn(); break; + case "board": tDir.Game.AddData(RvGame.GameData.Board, DatFileLoader.GnRest()); DatFileLoader.Gn(); break; + case "year": tDir.Game.AddData(RvGame.GameData.Year, DatFileLoader.GnRest()); DatFileLoader.Gn(); break; + case "manufacturer": tDir.Game.AddData(RvGame.GameData.Manufacturer, DatFileLoader.GnRest()); DatFileLoader.Gn(); break; + case "serial": DatFileLoader.GnRest(); DatFileLoader.Gn(); break; + case "rebuildto": DatFileLoader.GnRest(); DatFileLoader.Gn(); break; + + case "sample": DatFileLoader.GnRest(); DatFileLoader.Gn(); break; + case "biosset": DatFileLoader.GnRest(); DatFileLoader.Gn(); break; + + case "chip": DatFileLoader.GnRest(); DatFileLoader.Gn(); break; + case "video": DatFileLoader.GnRest(); DatFileLoader.Gn(); break; + case "sound": DatFileLoader.GnRest(); DatFileLoader.Gn(); break; + case "input": DatFileLoader.GnRest(); DatFileLoader.Gn(); break; + case "dipswitch": DatFileLoader.GnRest(); DatFileLoader.Gn(); break; + case "driver": DatFileLoader.GnRest(); DatFileLoader.Gn(); break; + + + case "rom": + DatFileLoader.Gn(); + if (!LoadRomFromDat(ref tDir, thisFileType)) + return false; + DatFileLoader.Gn(); + break; + case "disk": + DatFileLoader.Gn(); + if (!LoadDiskFromDat(ref tDirCHD)) + return false; + DatFileLoader.Gn(); + break; + + case "archive": + DatFileLoader.Gn(); + if (!LoadArchiveFromDat()) + return false; + DatFileLoader.Gn(); + break; + + default: + DatUpdate.SendAndShowDat(Resources.DatCmpReader_ReadDat_Error_keyword + DatFileLoader.Next + Resources.DatCmpReader_LoadGameFromDat_not_known_in_game, DatFileLoader.Filename); + DatFileLoader.Gn(); + break; + } + } + + if (tDir.ChildCount > 0) + parent.ChildAdd(tDir, index1); + if (tDirCHD.ChildCount > 0) + parent.ChildAdd(tDirCHD); + + return true; + } + + private static bool LoadRomFromDat(ref RvDir tGame, FileType thisFileType) + { + + if (DatFileLoader.Next != "(") + { + DatUpdate.SendAndShowDat(Resources.DatCmpReader_LoadRomFromDat_not_found_after_rom, DatFileLoader.Filename); + return false; + } + DatFileLoader.Gn(); + + if (DatFileLoader.Next.ToLower() != "name") + { + DatUpdate.SendAndShowDat(Resources.DatCmpReader_LoadGameFromDat_Name_not_found_as_first_object_in, DatFileLoader.Filename); + return false; + } + + + string filename = VarFix.CleanFullFileName(DatFileLoader.Gn()); + RvFile tRom = new RvFile(thisFileType) { Name = filename }; + + DatFileLoader.Gn(); + tRom.Dat = tGame.Dat; + + while (DatFileLoader.Next != ")") + { + switch (DatFileLoader.Next.ToLower()) + { + case "size": tRom.Size = VarFix.ULong(DatFileLoader.Gn()); DatFileLoader.Gn(); break; + case "crc": tRom.CRC = VarFix.CleanMD5SHA1(DatFileLoader.Gn(), 8); DatFileLoader.Gn(); break; + case "sha1": tRom.SHA1 = VarFix.CleanMD5SHA1(DatFileLoader.Gn(), 40); DatFileLoader.Gn(); break; + case "md5": tRom.MD5 = VarFix.CleanMD5SHA1(DatFileLoader.Gn(), 32); DatFileLoader.Gn(); break; + case "merge": tRom.Merge = VarFix.CleanFullFileName(DatFileLoader.Gn()); DatFileLoader.Gn(); break; + case "flags": tRom.Status = VarFix.ToLower(DatFileLoader.Gn()); DatFileLoader.Gn(); break; + case "date": DatFileLoader.Gn(); DatFileLoader.Gn(); break; + case "bios": DatFileLoader.Gn(); DatFileLoader.Gn(); break; + case "region": DatFileLoader.Gn(); DatFileLoader.Gn(); break; + case "offs": DatFileLoader.Gn(); DatFileLoader.Gn(); break; + case "nodump": tRom.Status = "nodump"; DatFileLoader.Gn(); break; + default: + DatUpdate.SendAndShowDat(Resources.DatCmpReader_ReadDat_Error_keyword + DatFileLoader.Next + Resources.DatCmpReader_LoadRomFromDat_not_known_in_rom, DatFileLoader.Filename); + DatFileLoader.Gn(); + break; + } + } + + if (tRom.Size != null) tRom.FileStatusSet(FileStatus.SizeFromDAT); + if (tRom.CRC != null) tRom.FileStatusSet(FileStatus.CRCFromDAT); + if (tRom.SHA1 != null) tRom.FileStatusSet(FileStatus.SHA1FromDAT); + if (tRom.MD5 != null) tRom.FileStatusSet(FileStatus.MD5FromDAT); + + tGame.ChildAdd(tRom); + + return true; + } + + private static bool LoadDiskFromDat(ref RvDir tGame) + { + + if (DatFileLoader.Next != "(") + { + DatUpdate.SendAndShowDat(Resources.DatCmpReader_LoadRomFromDat_not_found_after_rom, DatFileLoader.Filename); + return false; + } + DatFileLoader.Gn(); + + if (DatFileLoader.Next.ToLower() != "name") + { + DatUpdate.SendAndShowDat(Resources.DatCmpReader_LoadGameFromDat_Name_not_found_as_first_object_in, DatFileLoader.Filename); + return false; + } + + + string filename = VarFix.CleanFullFileName(DatFileLoader.Gn()); + RvFile tRom = new RvFile(FileType.File) { Name = filename }; + + DatFileLoader.Gn(); + tRom.Dat = tGame.Dat; + + while (DatFileLoader.Next != ")") + { + switch (DatFileLoader.Next.ToLower()) + { + case "sha1": tRom.SHA1CHD = VarFix.CleanMD5SHA1(DatFileLoader.Gn(), 40); DatFileLoader.Gn(); break; + case "md5": tRom.MD5CHD = VarFix.CleanMD5SHA1(DatFileLoader.Gn(), 32); DatFileLoader.Gn(); break; + case "merge": tRom.Merge = VarFix.CleanFullFileName(DatFileLoader.Gn()); DatFileLoader.Gn(); break; + case "flags": tRom.Status = VarFix.ToLower(DatFileLoader.Gn()); DatFileLoader.Gn(); break; + case "nodump": tRom.Status = "nodump"; DatFileLoader.Gn(); break; + default: + DatUpdate.SendAndShowDat(Resources.DatCmpReader_ReadDat_Error_keyword + DatFileLoader.Next + Resources.DatCmpReader_LoadRomFromDat_not_known_in_rom, DatFileLoader.Filename); + DatFileLoader.Gn(); + break; + } + } + + if (tRom.SHA1CHD != null) tRom.FileStatusSet(FileStatus.SHA1CHDFromDAT); + if (tRom.MD5CHD != null) tRom.FileStatusSet(FileStatus.MD5CHDFromDAT); + + tGame.ChildAdd(tRom); + + return true; + } + + private static bool LoadArchiveFromDat() + { + + if (DatFileLoader.Next != "(") + { + DatUpdate.SendAndShowDat("( not found after Archive", DatFileLoader.Filename); + return false; + } + DatFileLoader.Gn(); + + while (DatFileLoader.Next != ")") + { + switch (DatFileLoader.Next.ToLower()) + { + case "name": DatFileLoader.Gn(); DatFileLoader.Gn(); break; + default: + DatUpdate.SendAndShowDat(Resources.DatCmpReader_ReadDat_Error_keyword + DatFileLoader.Next + " not know in Archive", DatFileLoader.Filename); + DatFileLoader.Gn(); + break; + } + } + return true; + } + + + + private static class DatFileLoader + { + public static String Filename { get; private set; } + private static Stream _fileStream; + private static StreamReader _streamReader; + private static string _line = ""; + public static string Next; + + public static int LoadDat(string strFilename) + { + Filename = strFilename; + _streamReader = null; + int errorCode = IO.FileStream.OpenFileRead(strFilename, out _fileStream); + if (errorCode != 0) + return errorCode; + _streamReader = new StreamReader(_fileStream, Program.Enc); + return 0; + } + public static void Close() + { + _streamReader.Close(); + _fileStream.Close(); + _streamReader.Dispose(); + _fileStream.Dispose(); + } + + public static bool EndOfStream() + { + return _streamReader.EndOfStream; + } + + public static string GnRest() + { + string strret = _line.Replace("\"", ""); + _line = ""; + Next = strret; + return strret; + } + + public static string Gn() + { + string ret; + while ((_line.Trim().Length == 0) && (!_streamReader.EndOfStream)) + { + _line = _streamReader.ReadLine(); + _line = (_line??"").Replace("" + (char)9, " "); + if (_line.TrimStart().Length > 2 && _line.TrimStart().Substring(0, 2) == @"//") _line = ""; + if (_line.TrimStart().Length > 1 && _line.TrimStart().Substring(0, 1) == @"#") _line = ""; + if (_line.TrimStart().Length > 1 && _line.TrimStart().Substring(0, 1) == @";") _line = ""; + _line = _line.Trim() + " "; + } + + if (_line.Trim().Length > 0) + { + int intS; + if (_line.Substring(0, 1) == "\"") + { + intS = (_line + "\"").IndexOf("\"", 1, StringComparison.Ordinal); + ret = _line.Substring(1, intS - 1); + _line = (_line + " ").Substring(intS + 1).Trim(); + } + else + { + intS = (_line + " ").IndexOf(" ", StringComparison.Ordinal); + ret = _line.Substring(0, intS); + _line = (_line + " ").Substring(intS).Trim(); + } + } + else + { + ret = ""; + } + + Next = ret; + return ret; + } + } + + } +} diff --git a/ROMVault2/DatReaders/DatDOSReader.cs b/ROMVault2/DatReaders/DatDOSReader.cs new file mode 100644 index 0000000..c094b09 --- /dev/null +++ b/ROMVault2/DatReaders/DatDOSReader.cs @@ -0,0 +1,321 @@ +/****************************************************** + * ROMVault2 is written by Gordon J. * + * Contact gordon@romvault.com * + * Copyright 2014 * + ******************************************************/ + +using System; +using System.ComponentModel; +using System.IO; +using ROMVault2.Properties; +using ROMVault2.RvDB; +using ROMVault2.Utils; + +namespace ROMVault2.DatReaders +{ + public static class DatDOSReader + { + private static bool _cleanFileNames = true; + + + public static bool ReadDat(ref RvDir tDat, string strFilename) + { + RvDir tNow = tDat; + FileType thisFileType = FileType.Unknown; + + int errorCode = DatFileLoader.LoadDat(strFilename); + if (errorCode != 0) + { + DatUpdate.ShowDat(new Win32Exception(errorCode).Message, strFilename); + return false; + } + + DatFileLoader.Gn(); + while (!DatFileLoader.EndOfStream()) + { + switch (DatFileLoader.Next.ToLower()) + { + case "doscenter": + _cleanFileNames = true; + DatFileLoader.Gn(); + if (!LoadHeaderFromDat(ref tNow, ref thisFileType)) + return false; + DatFileLoader.Gn(); + break; + case "game": + DatFileLoader.Gn(); + if (!LoadGameFromDat(ref tNow, thisFileType)) + return false; + DatFileLoader.Gn(); + break; + default: + DatUpdate.SendAndShowDat(Resources.DatCmpReader_ReadDat_Error_keyword + DatFileLoader.Next + Resources.DatCmpReader_ReadDat_not_known, DatFileLoader.Filename); + DatFileLoader.Gn(); + break; + } + } + + DatFileLoader.Close(); + return true; + } + + private static bool LoadHeaderFromDat(ref RvDir tDir, ref FileType thisFileType) + { + + if (DatFileLoader.Next != "(") + { + DatUpdate.SendAndShowDat(Resources.DatCmpReader_LoadHeaderFromDat_not_found_after_clrmamepro, DatFileLoader.Filename); + return false; + } + DatFileLoader.Gn(); + + RvDat tDat = new RvDat(); + while (DatFileLoader.Next != ")") + { + string nextstr = DatFileLoader.Next.ToLower(); + if (nextstr.Length > 5 && nextstr.Substring(0, 5) == "name:") + { + tDat.AddData(RvDat.DatData.DatName, VarFix.CleanFileName(DatFileLoader.Next.Substring(5) + " " + DatFileLoader.GnRest()).Trim()); DatFileLoader.Gn(); + } + else + { + switch (nextstr) + { + case "name:": tDat.AddData(RvDat.DatData.DatName, VarFix.CleanFileName(DatFileLoader.GnRest())); DatFileLoader.Gn(); break; + case "description:": tDat.AddData(RvDat.DatData.Description , DatFileLoader.GnRest()); DatFileLoader.Gn(); break; + case "version:": tDat.AddData(RvDat.DatData.Version , DatFileLoader.GnRest()); DatFileLoader.Gn(); break; + case "date:": tDat.AddData(RvDat.DatData.Date , DatFileLoader.GnRest()); DatFileLoader.Gn(); break; + case "author:": tDat.AddData(RvDat.DatData.Author , DatFileLoader.GnRest()); DatFileLoader.Gn(); break; + case "homepage:": tDat.AddData(RvDat.DatData.HomePage , DatFileLoader.GnRest()); DatFileLoader.Gn(); break; + + case "comment:": DatFileLoader.GnRest(); DatFileLoader.Gn(); break; + default: + DatUpdate.SendAndShowDat(Resources.DatCmpReader_ReadDat_Error_keyword + DatFileLoader.Next + Resources.DatCmpReader_LoadHeaderFromDat_not_known_in_clrmamepro, DatFileLoader.Filename); + DatFileLoader.Gn(); + break; + } + } + } + + thisFileType = FileType.ZipFile; + tDir.Dat = tDat; + return true; + + } + + + + + private static bool LoadGameFromDat(ref RvDir tDat, FileType thisFileType) + { + if (DatFileLoader.Next != "(") + { + DatUpdate.SendAndShowDat(Resources.DatCmpReader_LoadGameFromDat_not_found_after_game, DatFileLoader.Filename); + return false; + } + DatFileLoader.Gn(); + + string snext = DatFileLoader.Next.ToLower(); + + if (snext != "name") + { + DatUpdate.SendAndShowDat(Resources.DatCmpReader_LoadGameFromDat_Name_not_found_as_first_object_in, DatFileLoader.Filename); + return false; + } + + RvDir parent = tDat; + + string fullname = VarFix.CleanFullFileName(DatFileLoader.GnRest()); + if (_cleanFileNames) + fullname = fullname.Replace("/", "-"); + + while (fullname.Contains("/")) + { + int firstSlash = fullname.IndexOf("/", StringComparison.Ordinal); + string dir = fullname.Substring(0, firstSlash); + fullname = fullname.Substring(firstSlash + 1); + int index; + if (parent.ChildNameSearch(new RvDir(FileType.Dir) { Name = dir }, out index) == 0) + { + parent = (RvDir)parent.Child(index); + } + else + { + RvDir tpDir = new RvDir(FileType.Dir) + { + Name = dir, + DatStatus = DatStatus.InDatCollect, + Dat = tDat.Dat, + Tree = new RvTreeRow() + }; + parent.ChildAdd(tpDir, index); + parent = tpDir; + } + } + + if (fullname.Length > 4 && fullname.ToLower().Substring(fullname.Length - 4, 4) == ".zip") + fullname = fullname.Substring(0, fullname.Length - 4); + + RvDir tDir = new RvDir(thisFileType == FileType.File ? FileType.Dir : FileType.Zip) { Name = fullname }; + + DatFileLoader.Gn(); + tDir.Game = new RvGame(); + tDir.DatStatus = DatStatus.InDatCollect; + tDir.Dat = tDat.Dat; + int index1; + + string testName = tDir.Name; + int nameCount = 0; + while (parent.ChildNameSearch(tDir, out index1) == 0) + { + tDir.Name = testName + "_" + nameCount; + nameCount++; + } + parent.ChildAdd(tDir, index1); + + + while (DatFileLoader.Next != ")") + { + switch (DatFileLoader.Next.ToLower()) + { + case "file": + DatFileLoader.Gn(); + if (!LoadRomFromDat(ref tDir, thisFileType)) + return false; + DatFileLoader.Gn(); + break; + default: + DatUpdate.SendAndShowDat(Resources.DatCmpReader_ReadDat_Error_keyword + DatFileLoader.Next + Resources.DatCmpReader_LoadGameFromDat_not_known_in_game, DatFileLoader.Filename); + DatFileLoader.Gn(); + break; + } + } + + + return true; + } + + private static bool LoadRomFromDat(ref RvDir tGame, FileType thisFileType) + { + + if (DatFileLoader.Next != "(") + { + DatUpdate.SendAndShowDat(Resources.DatCmpReader_LoadRomFromDat_not_found_after_rom, DatFileLoader.Filename); + return false; + } + string line=DatFileLoader.GnRest(); + string linelc = line.ToLower(); + + int posName = linelc.IndexOf("name ", StringComparison.Ordinal); + int posSize = linelc.IndexOf(" size ", posName+5,StringComparison.Ordinal); + int posDate = linelc.IndexOf(" date ", posSize+6,StringComparison.Ordinal); + int posCrc = linelc.IndexOf(" crc ", posDate+6,StringComparison.Ordinal); + int posEnd = linelc.IndexOf(" )", posCrc+5,StringComparison.Ordinal); + + if (posName < 0 || posSize < 0 || posDate < 0 || posCrc < 0 || posEnd < 0) + { + DatFileLoader.Gn(); + return false; + } + + string name = line.Substring(posName + 5, posSize - (posName + 5)); + string size = line.Substring(posSize + 6, posDate - (posSize + 6)); + //string date = line.Substring(posDate + 6, posCrc - (posDate + 6)); + string crc = line.Substring(posCrc + 5, posEnd - (posCrc + 5)); + + RvFile tRom = new RvFile(thisFileType) + { + Dat = tGame.Dat, + Name = VarFix.CleanFullFileName(name.Trim()), + Size = VarFix.ULong(size.Trim()), + CRC = VarFix.CleanMD5SHA1(crc.Trim(), 8) + }; + + + if (tRom.Size != null) tRom.FileStatusSet(FileStatus.SizeFromDAT); + if (tRom.CRC != null) tRom.FileStatusSet(FileStatus.CRCFromDAT); + + tGame.ChildAdd(tRom); + + return true; + } + + + + private static class DatFileLoader + { + public static String Filename { get; private set; } + private static Stream _fileStream; + private static StreamReader _streamReader; + private static string _line = ""; + public static string Next; + + public static int LoadDat(string strFilename) + { + Filename = strFilename; + _streamReader = null; + int errorCode = IO.FileStream.OpenFileRead(strFilename, out _fileStream); + if (errorCode != 0) + return errorCode; + _streamReader = new StreamReader(_fileStream, Program.Enc); + return 0; + } + public static void Close() + { + _streamReader.Close(); + _fileStream.Close(); + _streamReader.Dispose(); + _fileStream.Dispose(); + } + + public static bool EndOfStream() + { + return _streamReader.EndOfStream; + } + + public static string GnRest() + { + string strret = _line.Replace("\"", ""); + _line = ""; + Next = strret; + return strret; + } + + public static void Gn() + { + string ret; + while ((_line.Trim().Length == 0) && (!_streamReader.EndOfStream)) + { + _line = _streamReader.ReadLine(); + if (String.IsNullOrEmpty(_line)) _line = ""; + _line = _line.Replace("" + (char)9, " "); + _line = _line.Trim() + " "; + } + + if (_line.Trim().Length > 0) + { + int intS; + if (_line.Substring(0, 1) == "\"") + { + intS = (_line + "\"").IndexOf("\"", 1, StringComparison.Ordinal); + ret = _line.Substring(1, intS - 1); + _line = (_line + " ").Substring(intS + 1).Trim(); + } + else + { + intS = (_line + " ").IndexOf(" ", StringComparison.Ordinal); + ret = _line.Substring(0, intS); + _line = (_line + " ").Substring(intS).Trim(); + } + } + else + { + ret = ""; + } + + Next = ret; + } + } + + } +} diff --git a/ROMVault2/DatReaders/DatMessXMLReader.cs b/ROMVault2/DatReaders/DatMessXMLReader.cs new file mode 100644 index 0000000..cb91e03 --- /dev/null +++ b/ROMVault2/DatReaders/DatMessXMLReader.cs @@ -0,0 +1,223 @@ +/****************************************************** + * ROMVault2 is written by Gordon J. * + * Contact gordon@romvault.com * + * Copyright 2014 * + ******************************************************/ + +using System.Xml; +using ROMVault2.RvDB; +using ROMVault2.Utils; + +namespace ROMVault2.DatReaders +{ + public static class DatMessXmlReader + { + private static int _indexContinue; + + public static bool ReadDat(ref RvDir tDat, XmlDocument doc) + { + if (!LoadHeaderFromDat(ref tDat, ref doc)) + return false; + + if (doc.DocumentElement == null) + return false; + XmlNodeList gameNodeList = doc.DocumentElement.SelectNodes("software"); + + if (gameNodeList == null) + return false; + for (int i = 0; i < gameNodeList.Count; i++) + { + LoadGameFromDat(ref tDat, gameNodeList[i]); + } + + return true; + } + + private static bool LoadHeaderFromDat(ref RvDir tDir, ref XmlDocument doc) + { + XmlNodeList head = doc.SelectNodes("softwarelist"); + if (head == null) + return false; + + if (head.Count == 0) + return false; + + if (head[0].Attributes == null) + return false; + + RvDat tDat = new RvDat(); + tDat.AddData(RvDat.DatData.DatName, VarFix.CleanFileName(head[0].Attributes.GetNamedItem("name"))); + tDat.AddData(RvDat.DatData.Description, VarFix.String(head[0].Attributes.GetNamedItem("description"))); + + string val = VarFix.String(head[0].Attributes.GetNamedItem("forcemerging")).ToLower(); + switch (val.ToLower()) + { + case "split": + tDat.AddData(RvDat.DatData.MergeType, "split"); + break; + case "full": + tDat.AddData(RvDat.DatData.MergeType, "full"); + break; + default: + tDat.AddData(RvDat.DatData.MergeType, "split"); + break; + } + + + + tDir.Dat = tDat; + return true; + } + + private static void LoadGameFromDat(ref RvDir tDat, XmlNode gameNode) + { + if (gameNode.Attributes == null) + return; + + RvDir parent = tDat; + + RvDir tDir = new RvDir(FileType.Zip) + { + Name = VarFix.CleanFileName(gameNode.Attributes.GetNamedItem("name")), + Game = new RvGame(), + Dat = tDat.Dat, + DatStatus = DatStatus.InDatCollect + }; + + + tDir.Game.AddData(RvGame.GameData.Description, VarFix.String(gameNode.SelectSingleNode("description"))); + + tDir.Game.AddData(RvGame.GameData.RomOf, VarFix.CleanFileName(gameNode.Attributes.GetNamedItem("cloneof"))); + tDir.Game.AddData(RvGame.GameData.CloneOf, VarFix.CleanFileName(gameNode.Attributes.GetNamedItem("cloneof"))); + tDir.Game.AddData(RvGame.GameData.Year, VarFix.CleanFileName(gameNode.SelectSingleNode("year"))); + tDir.Game.AddData(RvGame.GameData.Manufacturer, VarFix.CleanFileName(gameNode.SelectSingleNode("publisher"))); + + + + RvDir tDirCHD = new RvDir(FileType.Dir) + { + Name = VarFix.CleanFileName(gameNode.Attributes.GetNamedItem("name")), + Game = new RvGame(), + Dat = tDat.Dat, + DatStatus = DatStatus.InDatCollect + + }; + + tDirCHD.Game.AddData(RvGame.GameData.Description, VarFix.String(gameNode.SelectSingleNode("description"))); + + tDirCHD.Game.AddData(RvGame.GameData.RomOf, VarFix.CleanFileName(gameNode.Attributes.GetNamedItem("cloneof"))); + tDirCHD.Game.AddData(RvGame.GameData.CloneOf, VarFix.CleanFileName(gameNode.Attributes.GetNamedItem("cloneof"))); + tDirCHD.Game.AddData(RvGame.GameData.Year, VarFix.CleanFileName(gameNode.SelectSingleNode("year"))); + tDirCHD.Game.AddData(RvGame.GameData.Manufacturer, VarFix.CleanFileName(gameNode.SelectSingleNode("publisher"))); + + + + int index1; + string testName = tDir.Name; + int nameCount = 0; + while (parent.ChildNameSearch(tDir, out index1) == 0) + { + tDir.Name = testName + "_" + nameCount; + nameCount++; + } + tDirCHD.Name = tDir.Name; + + + XmlNodeList partNodeList = gameNode.SelectNodes("part"); + if (partNodeList == null) return; + + for (int iP = 0; iP < partNodeList.Count; iP++) + { + _indexContinue = -1; + XmlNodeList dataAreaNodeList = partNodeList[iP].SelectNodes("dataarea"); + if (dataAreaNodeList != null) + for (int iD = 0; iD < dataAreaNodeList.Count; iD++) + { + XmlNodeList romNodeList = dataAreaNodeList[iD].SelectNodes("rom"); + if (romNodeList != null) + for (int iR = 0; iR < romNodeList.Count; iR++) + { + LoadRomFromDat(ref tDir, romNodeList[iR]); + } + } + } + for (int iP = 0; iP < partNodeList.Count; iP++) + { + XmlNodeList diskAreaNodeList = partNodeList[iP].SelectNodes("diskarea"); + if (diskAreaNodeList != null) + for (int iD = 0; iD < diskAreaNodeList.Count; iD++) + { + XmlNodeList romNodeList = diskAreaNodeList[iD].SelectNodes("disk"); + if (romNodeList != null) + for (int iR = 0; iR < romNodeList.Count; iR++) + { + LoadDiskFromDat(ref tDirCHD, romNodeList[iR]); + } + } + } + + if (tDir.ChildCount > 0) + parent.ChildAdd(tDir, index1); + if (tDirCHD.ChildCount > 0) + parent.ChildAdd(tDirCHD, index1); + + + } + + private static void LoadRomFromDat(ref RvDir tGame, XmlNode romNode) + { + if (romNode.Attributes == null) + return; + + XmlNode name = romNode.Attributes.GetNamedItem("name"); + string loadflag = VarFix.String(romNode.Attributes.GetNamedItem("loadflag")); + if (name != null) + { + RvFile tRom = new RvFile(FileType.ZipFile) + { + Name = VarFix.CleanFullFileName(name), + Size = VarFix.ULong(romNode.Attributes.GetNamedItem("size")), + CRC = VarFix.CleanMD5SHA1(romNode.Attributes.GetNamedItem("crc"), 8), + SHA1 = VarFix.CleanMD5SHA1(romNode.Attributes.GetNamedItem("sha1"), 40), + Status = VarFix.ToLower(romNode.Attributes.GetNamedItem("status")), + + Dat = tGame.Dat + }; + + if (tRom.Size != null) tRom.FileStatusSet(FileStatus.SizeFromDAT); + if (tRom.CRC != null) tRom.FileStatusSet(FileStatus.CRCFromDAT); + if (tRom.SHA1 != null) tRom.FileStatusSet(FileStatus.SHA1FromDAT); + + _indexContinue = tGame.ChildAdd(tRom); + } + else if (loadflag.ToLower() == "continue") + { + RvFile tZippedFile = (RvFile)tGame.Child(_indexContinue); + tZippedFile.Size += VarFix.ULong(romNode.Attributes.GetNamedItem("size")); + } + + } + + private static void LoadDiskFromDat(ref RvDir tGame, XmlNode romNode) + { + if (romNode.Attributes == null) + return; + + XmlNode name = romNode.Attributes.GetNamedItem("name"); + RvFile tRom = new RvFile(FileType.File) + { + Name = VarFix.CleanFullFileName(name) + ".chd", + SHA1CHD = VarFix.CleanMD5SHA1(romNode.Attributes.GetNamedItem("sha1"), 40), + Status = VarFix.ToLower(romNode.Attributes.GetNamedItem("status")), + + Dat = tGame.Dat + }; + + if (tRom.SHA1CHD != null) tRom.FileStatusSet(FileStatus.SHA1CHDFromDAT); + + tGame.ChildAdd(tRom); + } + + + } +} diff --git a/ROMVault2/DatReaders/DatReader.cs b/ROMVault2/DatReaders/DatReader.cs new file mode 100644 index 0000000..c4c2ae0 --- /dev/null +++ b/ROMVault2/DatReaders/DatReader.cs @@ -0,0 +1,601 @@ +/****************************************************** + * ROMVault2 is written by Gordon J. * + * Contact gordon@romvault.com * + * Copyright 2014 * + ******************************************************/ + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Diagnostics; +using System.Xml; +using ROMVault2.RvDB; +using ROMVault2.Utils; + +namespace ROMVault2.DatReaders +{ + public static class DatReader + { + private static BackgroundWorker _bgw; + + public static RvDir ReadInDatFile(RvDat datFile, BackgroundWorker bgw) + { + _bgw = bgw; + + RvDir newDir = new RvDir(FileType.Dir); + + string datFullName = datFile.GetData(RvDat.DatData.DatFullName); + + System.IO.Stream fs; + int errorCode = IO.FileStream.OpenFileRead(datFullName, out fs); + if (errorCode != 0) + { + _bgw.ReportProgress(0, new bgwShowError(datFullName, errorCode + ": " + new Win32Exception(errorCode).Message)); + return null; + } + + System.IO.StreamReader myfile = new System.IO.StreamReader(fs, Program.Enc); + string strLine = myfile.ReadLine(); + myfile.Close(); + fs.Close(); + fs.Dispose(); + + if (strLine == null) + return null; + + if (strLine.ToLower().IndexOf("xml", StringComparison.Ordinal) >= 0) + { + if (!ReadXMLDat(ref newDir, datFullName)) + return null; + } + + else if (strLine.ToLower().IndexOf("clrmamepro", StringComparison.Ordinal) >= 0 || strLine.ToLower().IndexOf("romvault", StringComparison.Ordinal) >= 0 || strLine.ToLower().IndexOf("game", StringComparison.Ordinal) >= 0) + { + if (!DatCmpReader.ReadDat(ref newDir, datFullName)) + return null; + } + else if (strLine.ToLower().IndexOf("doscenter", StringComparison.Ordinal) >= 0) + { + if (!DatDOSReader.ReadDat(ref newDir, datFullName)) + return null; + } + else + { + _bgw.ReportProgress(0, new bgwShowError(datFullName, "Invalid DAT File")); + return null; + } + + if (newDir.Dat == null) + { + _bgw.ReportProgress(0, new bgwShowError(datFullName, "Invalid Header")); + return null; + } + + newDir.Dat.AddData(RvDat.DatData.DatFullName, datFullName); + newDir.Dat.TimeStamp = datFile.TimeStamp; + newDir.Dat.Status = DatUpdateStatus.Correct; + + DatSetRemoveUnneededDirs(newDir); + DatSetCheckParentSets(newDir); + DatSetRenameAndRemoveDups(newDir); + + if (newDir.Dat.GetData(RvDat.DatData.MergeType).ToLower() == "full") + DatSetMergeSets(newDir); + + DatSetCheckCollect(newDir); + + DatSetCreateSubDirs(newDir); + + if (newDir.Dat.GetData(RvDat.DatData.DirSetup).ToLower() == "nogame") + { + DatSetRemoveGameDir(newDir); + } + + return newDir; + } + + + + + private static bool ReadXMLDat(ref RvDir tDat, string strFilename) + { + System.IO.Stream fs; + int errorCode = IO.FileStream.OpenFileRead(strFilename, out fs); + if (errorCode != 0) + { + _bgw.ReportProgress(0, new bgwShowError(strFilename, errorCode + ": " + new Win32Exception(errorCode).Message)); + return false; + } + + XmlDocument doc = new XmlDocument { XmlResolver = null }; + try + { + doc.Load(fs); + } + catch (Exception e) + { + fs.Close(); + fs.Dispose(); + string message = string.Format("Error Occured Reading Dat: {0}\r\nSource: {1}\r\nMessage: {2}\r\n", strFilename, e.Source, e.Message); + if (e.InnerException != null) + message += string.Format("\r\nINNER EXCEPTION:\r\nSource: {0}\r\nMessage: {1}\r\n", e.InnerException.Source, e.InnerException.Message); + ReportError.SendErrorMessageDat(message, strFilename); + _bgw.ReportProgress(0, new bgwShowError(strFilename, string.Format("Error Occured Reading Dat:\r\n{0}\r\n", e.Message))); + return false; + } + fs.Close(); + fs.Dispose(); + + if (doc.DocumentElement == null) + return false; + + XmlNode mame = doc.SelectSingleNode("mame"); + if (mame != null) + return DatXmlReader.ReadMameDat(ref tDat, doc); + + if (doc.DocumentElement != null) + { + XmlNode head = doc.DocumentElement.SelectSingleNode("header"); + if (head != null) + return DatXmlReader.ReadDat(ref tDat, doc); + } + + XmlNodeList headList = doc.SelectNodes("softwarelist"); + if (headList != null) + return DatMessXmlReader.ReadDat(ref tDat, doc); + + return false; + } + + private static void DatSetRenameAndRemoveDups(RvDir tDat) + { + for (int g = 0; g < tDat.ChildCount; g++) + { + RvDir tDir = (RvDir)tDat.Child(g); + if (tDir.Game == null) + { + DatSetRenameAndRemoveDups(tDir); + } + else + { + for (int r = 0; r < tDir.ChildCount - 1; r++) + { + RvFile f0 = (RvFile)tDir.Child(r); + RvFile f1 = (RvFile)tDir.Child(r + 1); + + if (f0.Name != f1.Name) + continue; + + if (f0.Size != f1.Size || !ArrByte.bCompare(f0.CRC, f1.CRC)) + { + tDir.ChildRemove(r + 1); // remove F1 + f1.Name = f1.Name + "_" + ArrByte.ToString(f1.CRC); // rename F1; + int pos = tDir.ChildAdd(f1); + if (pos < r) + r = pos; + // if this rename moved the File back up the list, start checking again from that file. + } + else + { + tDir.ChildRemove(r + 1); + } + r--; + } + } + } + } + private static void DatSetRemoveUnneededDirs(RvDir tDat) + { + for (int g = 0; g < tDat.ChildCount; g++) + { + RvDir tGame = (RvDir)tDat.Child(g); + if (tGame.Game == null) + { + DatSetRemoveUnneededDirs(tGame); + } + else + { + for (int r = 0; r < tGame.ChildCount - 1; r++) + { + // first find any directories, zero length with filename ending in a '/' + // there are RvFiles that are really directories (probably inside a zip file) + RvFile f0 = (RvFile)tGame.Child(r); + if (f0.Name.Length == 0) + continue; + if (f0.Name.Substring(f0.Name.Length - 1, 1) != "/") + continue; + + // if the next file contains that found directory, then the directory file can be deleted + RvFile f1 = (RvFile)tGame.Child(r + 1); + if (f1.Name.Length <= f0.Name.Length) + continue; + + if (f0.Name != f1.Name.Substring(0, f0.Name.Length)) + continue; + + tGame.ChildRemove(r); + r--; + } + } + } + } + + + private static void DatSetCheckParentSets(RvDir tDat) + { + // First we are going to try and fix any missing CRC information by checking for roms with the same names + // in Parent and Child sets, and if the same named rom is found and one has a CRC and the other does not + // then we will set the missing CRC by using the CRC in the other set. + + // we keep trying to find fixes until no more fixes are found. + // this is need as the first time round a fix could be found in a parent set from one child set. + // then the second time around that fixed parent set could fix another of its childs sets. + + for (int g = 0; g < tDat.ChildCount; g++) + { + RvDir mGame = (RvDir)tDat.Child(g); + if (mGame.Game == null) + // this is a directory so recuse into it + DatSetCheckParentSets(mGame); + } + + bool fix = true; + while (fix) + { + fix = false; + + // loop around every ROM Set looking for fixes. + for (int g = 0; g < tDat.ChildCount; g++) + { + + // get a list of that ROM Sets parents. + RvDir mGame = (RvDir)tDat.Child(g); + + if (mGame.Game == null) + continue; + + List lstParentGames = new List(); + FindParentSet(mGame, tDat, ref lstParentGames); + + // if this set have parents + if (lstParentGames.Count == 0) + continue; + + // now loop every ROM in the current set. + for (int r = 0; r < mGame.ChildCount; r++) + { + // and loop every ROM of every parent set of this current set. + // and see if anything can be fixed. + bool found = false; + + // loop the parent sets + foreach (RvDir romofGame in lstParentGames) + { + // loop the ROMs in the parent sets + for (int r1 = 0; r1 < romofGame.ChildCount; r1++) + { + // only find fixes if the Name and the Size of the ROMs are the same + if (mGame.Child(r).Name != romofGame.Child(r1).Name || ((RvFile)mGame.Child(r)).Size != ((RvFile)romofGame.Child(r1)).Size) + continue; + + // now check if one of the matching roms has missing or incorrect CRC information + bool b1 = ((RvFile)mGame.Child(r)).CRC == null; + bool b2 = ((RvFile)romofGame.Child(r1)).CRC == null; + + // if one has correct information and the other does not, fix the missing one + if (b1 == b2) + continue; + + if (b1) + { + ((RvFile)mGame.Child(r)).CRC = ((RvFile)romofGame.Child(r1)).CRC; + ((RvFile)mGame.Child(r)).Status = "(CRCFound)"; + } + else + { + ((RvFile)romofGame.Child(r1)).CRC = ((RvFile)mGame.Child(r)).CRC; + ((RvFile)romofGame.Child(r1)).Status = "(CRCFound)"; + } + + // flag that a fix was found so that we will go all the way around again. + fix = true; + found = true; + break; + } + if (found) break; + } + } + } + } + } + + private static void DatSetMergeSets(RvDir tDat) + { + for (int g = tDat.ChildCount - 1; g >= 0; g--) + { + RvDir mGame = (RvDir)tDat.Child(g); + + if (mGame.Game == null) + { + DatSetMergeSets(mGame); + continue; + } + + List lstParentGames = new List(); + FindParentSet(mGame, tDat, ref lstParentGames); + while (lstParentGames.Count > 0 && lstParentGames[lstParentGames.Count - 1].Game.GetData(RvGame.GameData.IsBios).ToLower() == "yes") + lstParentGames.RemoveAt(lstParentGames.Count - 1); + + if (lstParentGames.Count <= 0) continue; + + RvDir romofGame = lstParentGames[lstParentGames.Count - 1]; + + bool founderror = false; + for (int r = 0; r < mGame.ChildCount; r++) + { + string name = mGame.Child(r).Name; + string mergename = ((RvFile)mGame.Child(r)).Merge; + + for (int r1 = 0; r1 < romofGame.ChildCount; r1++) + { + if ((name == romofGame.Child(r1).Name || mergename == romofGame.Child(r1).Name) && + (ArrByte.iCompare(((RvFile)mGame.Child(r)).CRC, ((RvFile)romofGame.Child(r1)).CRC) != 0 || + ((RvFile)mGame.Child(r)).Size != ((RvFile)romofGame.Child(r1)).Size)) + founderror = true; + + } + } + if (founderror) + { + mGame.Game.DeleteData(RvGame.GameData.RomOf); + continue; + } + + for (int r = 0; r < mGame.ChildCount; r++) + { + string name = mGame.Child(r).Name; + string mergename = ((RvFile)mGame.Child(r)).Merge; + + bool found = false; + for (int r1 = 0; r1 < romofGame.ChildCount; r1++) + { + if ((name == romofGame.Child(r1).Name || mergename == romofGame.Child(r1).Name) && + (ArrByte.iCompare(((RvFile)mGame.Child(r)).CRC, ((RvFile)romofGame.Child(r1)).CRC) == 0 && + ((RvFile)mGame.Child(r)).Size == ((RvFile)romofGame.Child(r1)).Size)) + { + found = true; + break; + } + } + if (!found) + romofGame.ChildAdd(mGame.Child(r)); + } + tDat.ChildRemove(g); + } + } + + + + private static void DatSetCheckCollect(RvDir tDat) + { + // now look for merged roms. + // check if a rom exists in a parent set where the Name,Size and CRC all match. + + for (int g = 0; g < tDat.ChildCount; g++) + { + RvDir mGame = (RvDir)tDat.Child(g); + + if (mGame.Game == null) + DatSetCheckCollect(mGame); + else + { + List lstParentGames = new List(); + FindParentSet(mGame, tDat, ref lstParentGames); + + if (lstParentGames.Count == 0) + { + for (int r = 0; r < mGame.ChildCount; r++) + RomCheckCollect((RvFile)mGame.Child(r), false); + } + else + { + for (int r = 0; r < mGame.ChildCount; r++) + { + bool found = false; + foreach (RvDir romofGame in lstParentGames) + { + for (int r1 = 0; r1 < romofGame.ChildCount; r1++) + { + if (mGame.Child(r).Name != romofGame.Child(r1).Name) continue; + + ulong? Size0 = ((RvFile)mGame.Child(r)).Size; + ulong? Size1 = ((RvFile)romofGame.Child(r1)).Size; + if (Size0 != null && Size1 != null && Size0 != Size1) continue; + + byte[] CRC0 = ((RvFile)mGame.Child(r)).CRC; + byte[] CRC1 = ((RvFile)romofGame.Child(r1)).CRC; + if (CRC0 != null && CRC1 != null && !ArrByte.bCompare(CRC0, CRC1)) continue; + + byte[] SHA0 = ((RvFile)mGame.Child(r)).SHA1; + byte[] SHA1 = ((RvFile)romofGame.Child(r1)).SHA1; + if (SHA0 != null && SHA1 != null && !ArrByte.bCompare(SHA0, SHA1)) continue; + + byte[] MD50 = ((RvFile)mGame.Child(r)).MD5; + byte[] MD51 = ((RvFile)romofGame.Child(r1)).MD5; + if (MD50 != null && MD51 != null && !ArrByte.bCompare(MD50, MD51)) continue; + + byte[] chdSHA0 = ((RvFile)mGame.Child(r)).SHA1CHD; + byte[] chdSHA1 = ((RvFile)romofGame.Child(r1)).SHA1CHD; + if (chdSHA0 != null && chdSHA1 != null && !ArrByte.bCompare(chdSHA0, chdSHA1)) continue; + + byte[] chdMD50 = ((RvFile)mGame.Child(r)).MD5CHD; + byte[] chdMD51 = ((RvFile)romofGame.Child(r1)).MD5CHD; + if (chdMD50 != null && chdMD51 != null && !ArrByte.bCompare(chdMD50, chdMD51)) continue; + + + found = true; + break; + } + if (found) break; + } + RomCheckCollect((RvFile)mGame.Child(r), found); + } + } + } + } + } + private static void FindParentSet(RvDir searchGame, RvDir parentDir, ref List lstParentGames) + { + if (searchGame.Game == null) + return; + + string parentName = searchGame.Game.GetData(RvGame.GameData.RomOf); + if (String.IsNullOrEmpty(parentName) || parentName==searchGame.Name) + parentName = searchGame.Game.GetData(RvGame.GameData.CloneOf); + if (String.IsNullOrEmpty(parentName) || parentName==searchGame.Name) + return; + + int intIndex; + int intResult = parentDir.ChildNameSearch(new RvDir(searchGame.FileType) { Name = parentName }, out intIndex); + if (intResult == 0) + { + RvDir parentGame = (RvDir)parentDir.Child(intIndex); + lstParentGames.Add(parentGame); + FindParentSet(parentGame, parentDir, ref lstParentGames); + } + } + + + /* + * In the mame Dat: + * status="nodump" has a size but no CRC + * status="baddump" has a size and crc + */ + + + private static void RomCheckCollect(RvFile tRom, bool merge) + { + if (merge) + { + if (string.IsNullOrEmpty(tRom.Merge)) + tRom.Merge = "(Auto Merged)"; + + tRom.DatStatus = DatStatus.InDatMerged; + return; + } + + if (!string.IsNullOrEmpty(tRom.Merge)) + tRom.Merge = "(No-Merge) " + tRom.Merge; + + if (tRom.Status == "nodump") + { + tRom.CRC = null; + tRom.DatStatus = DatStatus.InDatBad; + return; + } + + if (ArrByte.bCompare(tRom.CRC, new byte[] { 0, 0, 0, 0 }) && tRom.Size == 0) + { + tRom.DatStatus = DatStatus.InDatCollect; + return; + } + + /* + if (ArrByte.bCompare(tRom.CRC, new byte[] { 0, 0, 0, 0 }) || (tRom.CRC.Length != 8)) + { + tRom.CRC = null; + tRom.DatStatus = DatStatus.InDatBad; + return; + } + */ + + tRom.DatStatus = DatStatus.InDatCollect; + } + + private static void DatSetCreateSubDirs(RvDir tDat) + { + for (int g = 0; g < tDat.ChildCount; g++) + { + if (tDat.Child(g).FileType == FileType.Zip) + continue; + + RvDir datGame = (RvDir)tDat.Child(g); + + // first do a quick check to see if anything needs done. + bool fixNeeded = false; + for (int r = 0; r < datGame.ChildCount; r++) + { + fixNeeded = datGame.Child(r).Name.Contains("/"); + + if (fixNeeded) + break; + } + // if nothing needs done skip to next game + if (!fixNeeded) + continue; + + + RvDir fixedGame = new RvDir(FileType.Dir); + while (datGame.ChildCount > 0) + { + RvBase nextChild = datGame.Child(0); + datGame.ChildRemove(0); + if (nextChild.GetType() == typeof(RvFile)) + { + RvFile tFile = (RvFile)nextChild; + if (tFile.Name.Contains("/")) + { + RvDir tBase = fixedGame; + Debug.WriteLine("tFile " + tFile.TreeFullName); + while (tFile.Name.Contains("/")) + { + int dirIndex = tFile.Name.IndexOf("/", StringComparison.Ordinal); + string dirName = tFile.Name.Substring(0, dirIndex); + RvDir tDir = new RvDir(FileType.Dir) + { + Name = dirName, + DatStatus = DatStatus.InDatCollect, + Dat = datGame.Dat + }; + int index; + if (tBase.ChildNameSearch(tDir, out index) != 0) + tBase.ChildAdd(tDir, index); + tBase = (RvDir)tBase.Child(index); + tFile.Name = tFile.Name.Substring(tFile.Name.IndexOf("/", StringComparison.Ordinal) + 1); + } + tBase.ChildAdd(tFile); + } + else + fixedGame.ChildAdd(nextChild); + } + else + fixedGame.ChildAdd(nextChild); + + + } + + for (int r = 0; r < fixedGame.ChildCount; r++) + datGame.ChildAdd(fixedGame.Child(r), r); + } + } + + + private static void DatSetRemoveGameDir(RvDir newDir) + { + if (newDir.ChildCount != 1) + return; + + RvDir child = newDir.Child(0) as RvDir; + if (child.FileType != FileType.Dir) + return; + + if (child.Game == null) + return; + + newDir.ChildRemove(0); + newDir.Game = child.Game; + for (int i = 0; i < child.ChildCount; i++) + newDir.ChildAdd(child.Child(i), i); + } + } +} diff --git a/ROMVault2/DatReaders/DatXMLReader.cs b/ROMVault2/DatReaders/DatXMLReader.cs new file mode 100644 index 0000000..d421215 --- /dev/null +++ b/ROMVault2/DatReaders/DatXMLReader.cs @@ -0,0 +1,410 @@ +/****************************************************** + * ROMVault2 is written by Gordon J. * + * Contact gordon@romvault.com * + * Copyright 2014 * + ******************************************************/ + +using System; +using System.Xml; +using ROMVault2.RvDB; +using ROMVault2.Utils; + +namespace ROMVault2.DatReaders +{ + public static class DatXmlReader + { + private static bool _cleanFileNames = true; + + public static bool ReadDat(ref RvDir tDat, XmlDocument doc) + { + FileType thisFileType = FileType.Unknown; + + if (!LoadHeaderFromDat(ref tDat, ref doc, ref thisFileType)) + return false; + + if (doc.DocumentElement == null) + return false; + + XmlNodeList dirNodeList = doc.DocumentElement.SelectNodes("dir"); + if (dirNodeList != null) + { + for (int i = 0; i < dirNodeList.Count; i++) + { + LoadDirFromDat(ref tDat, dirNodeList[i], thisFileType); + } + } + + XmlNodeList gameNodeList = doc.DocumentElement.SelectNodes("game"); + + if (gameNodeList != null) + { + for (int i = 0; i < gameNodeList.Count; i++) + { + LoadGameFromDat(ref tDat, gameNodeList[i], thisFileType); + } + } + + return true; + } + + public static bool ReadMameDat(ref RvDir tDat, XmlDocument doc) + { + FileType thisFileType = FileType.Unknown; + + if (!LoadMameHeaderFromDat(ref tDat, ref doc, ref thisFileType)) + return false; + + if (doc.DocumentElement == null) + return false; + + XmlNodeList dirNodeList = doc.DocumentElement.SelectNodes("dir"); + if (dirNodeList != null) + { + for (int i = 0; i < dirNodeList.Count; i++) + { + LoadDirFromDat(ref tDat, dirNodeList[i], thisFileType); + } + } + + XmlNodeList gameNodeList = doc.DocumentElement.SelectNodes("game"); + + if (gameNodeList != null) + { + for (int i = 0; i < gameNodeList.Count; i++) + { + LoadGameFromDat(ref tDat, gameNodeList[i], thisFileType); + } + } + + return true; + } + + + + private static bool LoadHeaderFromDat(ref RvDir tDir, ref XmlDocument doc, ref FileType thisFileType) + { + if (doc.DocumentElement == null) + return false; + XmlNode head = doc.DocumentElement.SelectSingleNode("header"); + + if (head == null) + return false; + RvDat tDat = new RvDat(); + tDat.AddData(RvDat.DatData.DatName, VarFix.CleanFileName(head.SelectSingleNode("name"))); + tDat.AddData(RvDat.DatData.RootDir, VarFix.CleanFileName(head.SelectSingleNode("rootdir"))); + tDat.AddData(RvDat.DatData.Description, VarFix.String(head.SelectSingleNode("description"))); + tDat.AddData(RvDat.DatData.Category, VarFix.String(head.SelectSingleNode("category"))); + tDat.AddData(RvDat.DatData.Version, VarFix.String(head.SelectSingleNode("version"))); + tDat.AddData(RvDat.DatData.Date, VarFix.String(head.SelectSingleNode("date"))); + tDat.AddData(RvDat.DatData.Author, VarFix.String(head.SelectSingleNode("author"))); + tDat.AddData(RvDat.DatData.Email, VarFix.String(head.SelectSingleNode("email"))); + tDat.AddData(RvDat.DatData.HomePage, VarFix.String(head.SelectSingleNode("homepage"))); + tDat.AddData(RvDat.DatData.URL, VarFix.String(head.SelectSingleNode("url"))); + + + string superDAT = VarFix.String(head.SelectSingleNode("type")); + _cleanFileNames = superDAT.ToLower() != "superdat" && superDAT.ToLower() != "gigadat"; + if (!_cleanFileNames) tDat.AddData(RvDat.DatData.SuperDat, "superdat"); + + thisFileType = FileType.ZipFile; + + // Look for: + XmlNode packingNode = head.SelectSingleNode("romvault"); + if (packingNode == null) + // Look for: + packingNode = head.SelectSingleNode("clrmamepro"); + if (packingNode != null) + { + if (packingNode.Attributes != null) + { + string val = VarFix.String(packingNode.Attributes.GetNamedItem("forcepacking")).ToLower(); + switch (val.ToLower()) + { + case "zip": + tDat.AddData(RvDat.DatData.FileType, "zip"); + thisFileType = FileType.ZipFile; + break; + case "unzip": + case "file": + tDat.AddData(RvDat.DatData.FileType, "file"); + thisFileType = FileType.File; + break; + default: + thisFileType = FileType.ZipFile; + break; + } + + val = VarFix.String(packingNode.Attributes.GetNamedItem("forcemerging")).ToLower(); + switch (val.ToLower()) + { + case "split": + tDat.AddData(RvDat.DatData.MergeType, "split"); + break; + case "full": + tDat.AddData(RvDat.DatData.MergeType, "full"); + break; + default: + tDat.AddData(RvDat.DatData.MergeType, "split"); + break; + } + val = VarFix.String(packingNode.Attributes.GetNamedItem("dir")).ToLower(); // noautodir , nogame + if (!String.IsNullOrEmpty(val)) + tDat.AddData(RvDat.DatData.DirSetup,val); + } + } + + // Look for: true + string notzipped = VarFix.String(head.SelectSingleNode("notzipped")); + if (notzipped.ToLower() == "true" || notzipped.ToLower() == "yes") thisFileType = FileType.File; + + tDir.Dat = tDat; + return true; + } + + private static bool LoadMameHeaderFromDat(ref RvDir tDir, ref XmlDocument doc, ref FileType thisFileType) + { + if (doc.DocumentElement == null) + return false; + XmlNode head = doc.SelectSingleNode("mame"); + + if (head == null || head.Attributes == null) + return false; + RvDat tDat = new RvDat(); + tDat.AddData(RvDat.DatData.DatName, VarFix.CleanFileName(head.Attributes.GetNamedItem("build"))); + tDat.AddData(RvDat.DatData.Description, VarFix.String(head.Attributes.GetNamedItem("build"))); + + thisFileType = FileType.ZipFile; + tDir.Dat = tDat; + return true; + } + + + private static void LoadDirFromDat(ref RvDir tDat, XmlNode dirNode, FileType thisFileType) + { + if (dirNode.Attributes == null) + return; + + RvDir parent = tDat; + + string fullname = VarFix.CleanFullFileName(dirNode.Attributes.GetNamedItem("name")); + while (fullname.Contains("/")) + { + int firstSlash = fullname.IndexOf("/", StringComparison.Ordinal); + string dir = fullname.Substring(0, firstSlash); + dir = VarFix.CleanFileName(dir); + + fullname = fullname.Substring(firstSlash + 1); + int index; + if (parent.ChildNameSearch(new RvDir(FileType.Dir) { Name = dir }, out index) == 0) + { + parent = (RvDir)parent.Child(index); + } + else + { + RvDir tpDir = new RvDir(FileType.Dir) + { + Name = dir, + DatStatus = DatStatus.InDatCollect, + Dat = tDat.Dat, + Tree = new RvTreeRow() + }; + parent.ChildAdd(tpDir, index); + parent = tpDir; + } + } + + RvDir tDir = new RvDir(FileType.Dir) + { + Name = fullname, + DatStatus = DatStatus.InDatCollect, + Dat = tDat.Dat, + Tree = new RvTreeRow() + }; + + int index1; + if (parent.ChildNameSearch(tDir, out index1) == 0) + tDir = (RvDir)parent.Child(index1); + else + tDat.ChildAdd(tDir, index1); + + XmlNodeList dirNodeList = dirNode.SelectNodes("dir"); + if (dirNodeList != null) + { + for (int i = 0; i < dirNodeList.Count; i++) + { + LoadDirFromDat(ref tDir, dirNodeList[i], thisFileType); + } + } + + XmlNodeList gameNodeList = dirNode.SelectNodes("game"); + if (gameNodeList != null) + { + for (int i = 0; i < gameNodeList.Count; i++) + { + LoadGameFromDat(ref tDir, gameNodeList[i], thisFileType); + } + } + } + + private static void LoadGameFromDat(ref RvDir tDat, XmlNode gameNode, FileType thisFileType) + { + if (gameNode.Attributes == null) + return; + + RvDir parent = tDat; + RvDir tDir; + int index1 = 0; + + string fullname = VarFix.CleanFullFileName(gameNode.Attributes.GetNamedItem("name")); + if (_cleanFileNames) + fullname = fullname.Replace("/", "-"); + else + { + while (fullname.Contains("/")) + { + int firstSlash = fullname.IndexOf("/", StringComparison.Ordinal); + string dir = fullname.Substring(0, firstSlash); + dir = VarFix.CleanFileName(dir); + + fullname = fullname.Substring(firstSlash + 1); + int index; + if (parent.ChildNameSearch(new RvDir(FileType.Dir) { Name = dir }, out index) == 0) + { + parent = (RvDir)parent.Child(index); + } + else + { + RvDir tpDir = new RvDir(FileType.Dir) + { + Name = dir, + DatStatus = DatStatus.InDatCollect, + Dat = tDat.Dat, + Tree = new RvTreeRow() + }; + parent.ChildAdd(tpDir, index); + parent = tpDir; + } + } + } + + tDir = new RvDir(DBTypeGet.DirFromFile(thisFileType)) + { + Name = fullname, + DatStatus = DatStatus.InDatCollect, + Dat = tDat.Dat + }; + + string testName = tDir.Name; + int nameCount = 0; + while (parent.ChildNameSearch(tDir, out index1) == 0) + { + tDir.Name = testName + "_" + nameCount; + nameCount++; + } + + tDir.Game = new RvGame(); + tDir.Game.AddData(RvGame.GameData.RomOf, VarFix.CleanFileName(gameNode.Attributes.GetNamedItem("romof"))); + tDir.Game.AddData(RvGame.GameData.Description, VarFix.String(gameNode.SelectSingleNode("description"))); + + tDir.Game.AddData(RvGame.GameData.Sourcefile, VarFix.String(gameNode.Attributes.GetNamedItem("sourcefile"))); + tDir.Game.AddData(RvGame.GameData.IsBios, VarFix.String(gameNode.Attributes.GetNamedItem("isbios"))); + tDir.Game.AddData(RvGame.GameData.CloneOf, VarFix.CleanFileName(gameNode.Attributes.GetNamedItem("cloneof"))); + tDir.Game.AddData(RvGame.GameData.SampleOf, VarFix.CleanFileName(gameNode.Attributes.GetNamedItem("sampleof"))); + tDir.Game.AddData(RvGame.GameData.Board, VarFix.String(gameNode.Attributes.GetNamedItem("board"))); + tDir.Game.AddData(RvGame.GameData.Year, VarFix.String(gameNode.SelectSingleNode("year"))); + tDir.Game.AddData(RvGame.GameData.Manufacturer, VarFix.String(gameNode.SelectSingleNode("manufacturer"))); + + XmlNode trurip = gameNode.SelectSingleNode("trurip"); + if (trurip != null) + { + tDir.Game.AddData(RvGame.GameData.Trurip, "yes"); + tDir.Game.AddData(RvGame.GameData.Year, VarFix.String(trurip.SelectSingleNode("year"))); + tDir.Game.AddData(RvGame.GameData.Publisher, VarFix.String(trurip.SelectSingleNode("publisher"))); + tDir.Game.AddData(RvGame.GameData.Developer, VarFix.String(trurip.SelectSingleNode("developer"))); + tDir.Game.AddData(RvGame.GameData.Edition, VarFix.String(trurip.SelectSingleNode("edition"))); + tDir.Game.AddData(RvGame.GameData.Version, VarFix.String(trurip.SelectSingleNode("version"))); + tDir.Game.AddData(RvGame.GameData.Type, VarFix.String(trurip.SelectSingleNode("type"))); + tDir.Game.AddData(RvGame.GameData.Media, VarFix.String(trurip.SelectSingleNode("media"))); + tDir.Game.AddData(RvGame.GameData.Language, VarFix.String(trurip.SelectSingleNode("language"))); + tDir.Game.AddData(RvGame.GameData.Players, VarFix.String(trurip.SelectSingleNode("players"))); + tDir.Game.AddData(RvGame.GameData.Ratings, VarFix.String(trurip.SelectSingleNode("ratings"))); + tDir.Game.AddData(RvGame.GameData.Peripheral, VarFix.String(trurip.SelectSingleNode("peripheral"))); + tDir.Game.AddData(RvGame.GameData.Genre, VarFix.String(trurip.SelectSingleNode("genre"))); + tDir.Game.AddData(RvGame.GameData.MediaCatalogNumber, VarFix.String(trurip.SelectSingleNode("mediacatalognumber"))); + tDir.Game.AddData(RvGame.GameData.BarCode, VarFix.String(trurip.SelectSingleNode("barcode"))); + } + + RvDir tDirCHD = new RvDir(FileType.Dir) + { + Name = tDir.Name, + DatStatus = tDir.DatStatus, + Dat = tDir.Dat, + Game = tDir.Game + }; + + XmlNodeList romNodeList = gameNode.SelectNodes("rom"); + if (romNodeList != null) + for (int i = 0; i < romNodeList.Count; i++) + LoadRomFromDat(ref tDir, romNodeList[i], thisFileType); + + XmlNodeList diskNodeList = gameNode.SelectNodes("disk"); + if (diskNodeList != null) + for (int i = 0; i < diskNodeList.Count; i++) + LoadDiskFromDat(ref tDirCHD, diskNodeList[i]); + + if (tDir.ChildCount > 0) + parent.ChildAdd(tDir, index1); + if (tDirCHD.ChildCount > 0) + parent.ChildAdd(tDirCHD); + } + + private static void LoadRomFromDat(ref RvDir tGame, XmlNode romNode, FileType thisFileType) + { + if (romNode.Attributes == null) + return; + + + RvFile tRom = new RvFile(thisFileType) + { + Dat = tGame.Dat, + Size = VarFix.ULong(romNode.Attributes.GetNamedItem("size")), + Name = VarFix.CleanFullFileName(romNode.Attributes.GetNamedItem("name")), + CRC = VarFix.CleanMD5SHA1(romNode.Attributes.GetNamedItem("crc"), 8), + SHA1 = VarFix.CleanMD5SHA1(romNode.Attributes.GetNamedItem("sha1"), 40), + MD5 = VarFix.CleanMD5SHA1(romNode.Attributes.GetNamedItem("md5"), 32), + Merge = VarFix.CleanFullFileName(romNode.Attributes.GetNamedItem("merge")), + Status = VarFix.ToLower(romNode.Attributes.GetNamedItem("status")) + }; + + if (tRom.Size != null) tRom.FileStatusSet(FileStatus.SizeFromDAT); + if (tRom.CRC != null) tRom.FileStatusSet(FileStatus.CRCFromDAT); + if (tRom.SHA1 != null) tRom.FileStatusSet(FileStatus.SHA1FromDAT); + if (tRom.MD5 != null) tRom.FileStatusSet(FileStatus.MD5FromDAT); + + tGame.ChildAdd(tRom); + } + + private static void LoadDiskFromDat(ref RvDir tGame, XmlNode romNode) + { + if (romNode.Attributes == null) + return; + + + RvFile tRom = new RvFile(FileType.File) + { + Dat = tGame.Dat, + Name = VarFix.CleanFullFileName(romNode.Attributes.GetNamedItem("name")) + ".chd", + SHA1CHD = VarFix.CleanMD5SHA1(romNode.Attributes.GetNamedItem("sha1"), 40), + MD5CHD = VarFix.CleanMD5SHA1(romNode.Attributes.GetNamedItem("md5"), 32), + Merge = VarFix.CleanFullFileName(romNode.Attributes.GetNamedItem("merge")), + Status = VarFix.ToLower(romNode.Attributes.GetNamedItem("status")) + }; + + if (tRom.SHA1CHD != null) tRom.FileStatusSet(FileStatus.SHA1CHDFromDAT); + if (tRom.MD5CHD != null) tRom.FileStatusSet(FileStatus.MD5CHDFromDAT); + + tGame.ChildAdd(tRom); + } + + } +} diff --git a/ROMVault2/DatUpdate.cs b/ROMVault2/DatUpdate.cs new file mode 100644 index 0000000..183f6fb --- /dev/null +++ b/ROMVault2/DatUpdate.cs @@ -0,0 +1,784 @@ +/****************************************************** + * ROMVault2 is written by Gordon J. * + * Contact gordon@romvault.com * + * Copyright 2013 * + ******************************************************/ + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Diagnostics; +using System.Threading; +using ROMVault2.IO; +using ROMVault2.DatReaders; +using ROMVault2.Properties; +using ROMVault2.RvDB; +using ROMVault2.Utils; + +namespace ROMVault2 +{ + public static class DatUpdate + { + private static int _datCount; + private static int _datsProcessed; + private static BackgroundWorker _bgw; + + public static void ShowDat(string message, string filename) + { + if (_bgw != null) + _bgw.ReportProgress(0, new bgwShowError(filename, message)); + } + + public static void SendAndShowDat(string message, string filename) + { + ReportError.SendErrorMessageDat(message, filename); + if (_bgw != null) + _bgw.ReportProgress(0, new bgwShowError(filename, message)); + } + + + public static void UpdateDat(object sender, DoWorkEventArgs e) + { + try + { + _bgw = sender as BackgroundWorker; + if (_bgw == null) return; + + Program.SyncCont = e.Argument as SynchronizationContext; + if (Program.SyncCont == null) + { + _bgw = null; + return; + } + + + _bgw.ReportProgress(0, new bgwText("Clearing DB Status")); + RepairStatus.ReportStatusReset(DB.DirTree); + + _datCount = 0; + + _bgw.ReportProgress(0, new bgwText("Finding Dats")); + RvDir datRoot = new RvDir(FileType.Dir) { Name = "RomVault", DatStatus = DatStatus.InDatCollect }; + + // build a datRoot tree of the DAT's in DatRoot, and count how many dats are found + if (!RecursiveDatTree(datRoot, out _datCount)) + { + _bgw.ReportProgress(0, new bgwText("Dat Update Complete")); + _bgw = null; + Program.SyncCont = null; + return; + } + + _bgw.ReportProgress(0, new bgwText("Scanning Dats")); + _datsProcessed = 0; + + // now compare the database DAT's with datRoot removing any old DAT's + RemoveOldDats(DB.DirTree.Child(0), datRoot); + + // next clean up the File status removing any old DAT's + RemoveOldDatsCleanUpFiles(DB.DirTree.Child(0)); + + _bgw.ReportProgress(0, new bgwSetRange(_datCount - 1)); + + // next add in new DAT and update the files + UpdateDatList((RvDir)DB.DirTree.Child(0),datRoot); + + // finally remove any unneeded DIR's from the TreeView + RemoveOldTree(DB.DirTree.Child(0)); + + _bgw.ReportProgress(0, new bgwText("Updating Cache")); + DB.Write(); + + _bgw.ReportProgress(0, new bgwText("Dat Update Complete")); + _bgw = null; + Program.SyncCont = null; + } + catch (Exception exc) + { + ReportError.UnhandledExceptionHandler(exc); + + if (_bgw != null) _bgw.ReportProgress(0, new bgwText("Updating Cache")); + DB.Write(); + if (_bgw != null) _bgw.ReportProgress(0, new bgwText("Complete")); + + _bgw = null; + Program.SyncCont = null; + } + } + + private static bool RecursiveDatTree(RvDir tDir, out int datCount) + { + datCount = 0; + string strPath = tDir.DatFullName; + + if (!Directory.Exists(strPath)) + { + ReportError.Show(Resources.DatUpdate_UpdateDatList_Path + strPath + Resources.DatUpdate_UpdateDatList_Not_Found); + return false; + } + + DirectoryInfo oDir = new DirectoryInfo(strPath); + + FileInfo[] oFilesIn = oDir.GetFiles("*.dat", false); + datCount += oFilesIn.Length; + foreach (FileInfo file in oFilesIn) + { + RvDat tDat = new RvDat(); + tDat.AddData(RvDat.DatData.DatFullName, file.FullName); + tDat.TimeStamp = file.LastWriteTime; + tDir.DirDatAdd(tDat); + } + + + oFilesIn = oDir.GetFiles("*.xml", false); + datCount += oFilesIn.Length; + foreach (FileInfo file in oFilesIn) + { + RvDat tDat = new RvDat(); + tDat.AddData(RvDat.DatData.DatFullName, file.FullName); + tDat.TimeStamp = file.LastWriteTime; + tDir.DirDatAdd(tDat); + } + + if (tDir.DirDatCount > 1) + for (int i = 0; i < tDir.DirDatCount; i++) + tDir.DirDat(i).AutoAddDirectory = true; + + DirectoryInfo[] oSubDir = oDir.GetDirectories(false); + + foreach (DirectoryInfo t in oSubDir) + { + RvDir cDir = new RvDir(FileType.Dir) { Name = t.Name, DatStatus = DatStatus.InDatCollect }; + int index = tDir.ChildAdd(cDir); + + int retDatCount; + + RecursiveDatTree(cDir, out retDatCount); + datCount += retDatCount; + + if (retDatCount == 0) + tDir.ChildRemove(index); + } + + return true; + } + + + private static void RemoveOldDats(RvBase dbDir, RvDir tmpDir) + { + // now compare the old and new dats removing any old dats + // in the current directory + + RvDir lDir = dbDir as RvDir; + if (lDir == null) return; + + int dbIndex = 0; + int scanIndex = 0; + + while (dbIndex < lDir.DirDatCount || scanIndex < tmpDir.DirDatCount) + { + RvDat dbDat = null; + RvDat fileDat = null; + int res = 0; + + if (dbIndex < lDir.DirDatCount && scanIndex < tmpDir.DirDatCount) + { + dbDat = lDir.DirDat(dbIndex); + fileDat = tmpDir.DirDat(scanIndex); + res = DBHelper.DatCompare(dbDat, fileDat); + } + else if (scanIndex < tmpDir.DirDatCount) + { + //this is a new dat that we have now found at the end of the list + //fileDat = tmpDir.DirDat(scanIndex); + res = 1; + } + else if (dbIndex < lDir.DirDatCount) + { + dbDat = lDir.DirDat(dbIndex); + res = -1; + } + + switch (res) + { + case 0: + dbDat.Status = DatUpdateStatus.Correct; + dbIndex++; + scanIndex++; + break; + + case 1: + // this is a new dat that we will add next time around + scanIndex++; + break; + case -1: + dbDat.Status = DatUpdateStatus.Delete; + lDir.DirDatRemove(dbIndex); + break; + } + + } + + // now scan the child directory structure of this directory + dbIndex = 0; + scanIndex = 0; + + while (dbIndex < lDir.ChildCount || scanIndex < tmpDir.ChildCount) + { + RvBase dbChild = null; + RvBase fileChild = null; + int res = 0; + + if (dbIndex < lDir.ChildCount && scanIndex < tmpDir.ChildCount) + { + dbChild = lDir.Child(dbIndex); + fileChild = tmpDir.Child(scanIndex); + res = DBHelper.CompareName(dbChild, fileChild); + } + else if (scanIndex < tmpDir.ChildCount) + { + //found a new directory on the end of the list + //fileChild = tmpDir.Child(scanIndex); + res = 1; + } + else if (dbIndex < lDir.ChildCount) + { + dbChild = lDir.Child(dbIndex); + res = -1; + } + switch (res) + { + case 0: + // found a matching directory in DatRoot So recurse back into it + RemoveOldDats(dbChild, (RvDir)fileChild); + dbIndex++; + scanIndex++; + break; + + case 1: + // found a new directory will be added later + scanIndex++; + break; + case -1: + if (dbChild.FileType == FileType.Dir && dbChild.Dat == null) + RemoveOldDats(dbChild, new RvDir(FileType.Dir)); + dbIndex++; + break; + } + } + } + + private static EFile RemoveOldDatsCleanUpFiles(RvBase dbDir) + { + + if (dbDir.Dat != null) + { + if (dbDir.Dat.Status == DatUpdateStatus.Correct) + return EFile.Keep; + + if (dbDir.Dat.Status == DatUpdateStatus.Delete) + { + if (dbDir.DatRemove() == EFile.Delete) + return EFile.Delete; //delete + } + } + + FileType ft = dbDir.FileType; + // if we are checking a dir or zip recurse into it. + if (ft != FileType.Zip && ft != FileType.Dir) return EFile.Keep; + RvDir tDir = dbDir as RvDir; + + // remove all DATStatus's here they will get set back correctly when adding dats back in below. + dbDir.DatStatus = DatStatus.NotInDat; + + for (int i = 0; i < tDir.ChildCount; i++) + { + if (RemoveOldDatsCleanUpFiles(tDir.Child(i)) == EFile.Keep) continue; + tDir.ChildRemove(i); + i--; + } + if (ft == FileType.Zip && dbDir.GotStatus == GotStatus.Corrupt) return EFile.Keep; + + // if this directory is now empty it should be deleted + return tDir.ChildCount == 0 ? EFile.Delete : EFile.Keep; + } + + + + private static void UpdateDatList(RvDir dbDir, RvDir tmpDir) + { + AddNewDats(dbDir, tmpDir); + UpdateDirs(dbDir, tmpDir); + } + + /// + /// Add the new DAT's into the DAT list + /// And merge in the new DAT data into the database + /// + /// The Current database dir + /// A temp directory containing the DAT found in this directory in DatRoot + private static void AddNewDats(RvDir dbDir, RvDir tmpDir) + { + bool autoAddDirectory = (tmpDir.DirDatCount) > 1; + + int dbIndex = 0; + int scanIndex = 0; + + Debug.WriteLine(""); + Debug.WriteLine("Scanning for Adding new DATS"); + while (dbIndex < dbDir.DirDatCount || scanIndex < tmpDir.DirDatCount) + { + RvDat dbDat = null; + RvDat fileDat = null; + int res = 0; + + if (dbIndex < dbDir.DirDatCount && scanIndex < tmpDir.DirDatCount) + { + dbDat = dbDir.DirDat(dbIndex); + fileDat = tmpDir.DirDat(scanIndex); + res = DBHelper.DatCompare(dbDat, fileDat); + Debug.WriteLine("Checking " + dbDat.GetData(RvDat.DatData.DatFullName) + " : and " + fileDat.GetData(RvDat.DatData.DatFullName) + " : " + res); + } + else if (scanIndex < tmpDir.DirDatCount) + { + fileDat = tmpDir.DirDat(scanIndex); + res = 1; + Debug.WriteLine("Checking : and " + fileDat.GetData(RvDat.DatData.DatFullName) + " : " + res); + } + else if (dbIndex < dbDir.DirDatCount) + { + dbDat = dbDir.DirDat(dbIndex); + res = -1; + Debug.WriteLine("Checking " + dbDat.GetData(RvDat.DatData.DatFullName) + " : and : " + res); + } + + switch (res) + { + case 0: + _datsProcessed++; + _bgw.ReportProgress(_datsProcessed); + _bgw.ReportProgress(0, new bgwText("Dat : " + Path.GetFileNameWithoutExtension(fileDat.GetData(RvDat.DatData.DatFullName)))); + + + Debug.WriteLine("Correct"); + // Should already be set as correct above + dbDat.Status = DatUpdateStatus.Correct; + dbIndex++; + scanIndex++; + break; + + case 1: + _datsProcessed++; + _bgw.ReportProgress(_datsProcessed); + _bgw.ReportProgress(0, new bgwText("Scanning New Dat : " + Path.GetFileNameWithoutExtension(fileDat.GetData(RvDat.DatData.DatFullName)))); + + + Debug.WriteLine("Adding new DAT"); + if (UpdateDatFile(fileDat, autoAddDirectory, dbDir)) + dbIndex++; + scanIndex++; + break; + + case -1: + // This should not happen as deleted dat have been removed above + //dbIndex++; + ReportError.SendAndShow(Resources.DatUpdate_UpdateDatList_ERROR_Deleting_a_DAT_that_should_already_be_deleted); + break; + } + + } + } + + + + + + private static bool UpdateDatFile(RvDat file, bool autoAddDirectory, RvDir thisDirectory) + { + // Read the new Dat File into newDatFile + RvDir newDatFile = DatReader.ReadInDatFile(file, _bgw); + + // If we got a valid Dat File back + if (newDatFile == null || newDatFile.Dat == null) + { + ReportError.Show("Error reading Dat " + file.GetData(RvDat.DatData.DatFullName)); + return false; + } + + newDatFile.Dat.AutoAddDirectory = autoAddDirectory; + + if ((autoAddDirectory || !String.IsNullOrEmpty(newDatFile.Dat.GetData(RvDat.DatData.RootDir))) && newDatFile.Dat.GetData(RvDat.DatData.DirSetup)!= "noautodir") + { // if we are auto adding extra directorys then create a new directory. + + newDatFile.Name = !String.IsNullOrEmpty(newDatFile.Dat.GetData(RvDat.DatData.RootDir)) ? + newDatFile.Dat.GetData(RvDat.DatData.RootDir) : newDatFile.Dat.GetData(RvDat.DatData.DatName); + + newDatFile.DatStatus = DatStatus.InDatCollect; + newDatFile.Tree = new RvTreeRow(); + + RvDir newDirectory = new RvDir(FileType.Dir) { Dat = newDatFile.Dat }; + + // add the DAT into this directory + newDirectory.ChildAdd(newDatFile); + newDatFile = newDirectory; + } + + if (thisDirectory.Tree == null) + thisDirectory.Tree = new RvTreeRow(); + + RvDat conflictDat; + if (MergeInDat(thisDirectory, newDatFile, out conflictDat, true)) + { + ReportError.Show("Dat Merge conflict occured Cache contains " + conflictDat.GetData(RvDat.DatData.DatFullName) + " new dat " + newDatFile.Dat.GetData(RvDat.DatData.DatFullName) + " is trying to use the same dirctory and so will be ignored."); + return false; + } + + //SetInDat(thisDirectory); + + // Add the new Dat + thisDirectory.DirDatAdd(newDatFile.Dat); + + // Merge the files/directories in the Dat + MergeInDat(thisDirectory, newDatFile, out conflictDat, false); + return true; + } + + /* + private static void SetInDat(RvDir tDir) + { + tDir.DatStatus = DatStatus.InDatCollect; + if (tDir.Parent != null) + SetInDat(tDir.Parent); + } + */ + + private static Boolean MergeInDat(RvDir dbDat, RvDir newDat, out RvDat conflict, bool checkOnly) + { + conflict = null; + int dbIndex = 0; + int newIndex = 0; + while (dbIndex < dbDat.ChildCount || newIndex < newDat.ChildCount) + { + RvBase dbChild = null; + RvBase newDatChild = null; + int res = 0; + + if (dbIndex < dbDat.ChildCount && newIndex < newDat.ChildCount) + { + dbChild = dbDat.Child(dbIndex); // are files + newDatChild = newDat.Child(newIndex); // is from a dat item + res = DBHelper.CompareName(dbChild, newDatChild); + } + else if (newIndex < newDat.ChildCount) + { + newDatChild = newDat.Child(newIndex); + res = 1; + } + else if (dbIndex < dbDat.ChildCount) + { + dbChild = dbDat.Child(dbIndex); + res = -1; + } + + if (res == 0) + { + if (dbChild == null || newDatChild == null) + { + SendAndShowDat(Resources.DatUpdate_MergeInDat_Error_in_Logic, dbDat.FullName); + break; + } + + + List dbDats = new List(); + List newDats = new List(); + int dbDatsCount = 1; + int newDatsCount = 1; + + + dbDats.Add(dbChild); + newDats.Add(newDatChild); + + while (dbIndex + dbDatsCount < dbDat.ChildCount && DBHelper.CompareName(dbChild, dbDat.Child(dbIndex + dbDatsCount)) == 0) + { + dbDats.Add(dbDat.Child(dbIndex + dbDatsCount)); + dbDatsCount += 1; + } + while (newIndex + newDatsCount < newDat.ChildCount && DBHelper.CompareName(newDatChild, newDat.Child(newIndex + newDatsCount)) == 0) + { + newDats.Add(newDat.Child(newIndex + newDatsCount)); + newDatsCount += 1; + } + + if (dbDatsCount > 1 || newDatsCount > 1) + { + ReportError.SendAndShow("Double Name Found"); + } + + for (int indexdb = 0; indexdb < dbDatsCount; indexdb++) + { + if (dbDats[indexdb].DatStatus == DatStatus.NotInDat) continue; + + if (checkOnly) + { + conflict = dbChild.Dat; + return true; + } + + SendAndShowDat(Resources.DatUpdate_MergeInDat_Unkown_Update_Dat_Status + dbChild.DatStatus, dbDat.FullName); + break; + } + + if (!checkOnly) + { + for (int indexNewDats = 0; indexNewDats < newDatsCount; indexNewDats++) + { + if (newDats[indexNewDats].SearchFound) continue; + + for (int indexDbDats = 0; indexDbDats < dbDatsCount; indexDbDats++) + { + if (dbDats[indexDbDats].SearchFound) continue; + + bool matched = FullCompare(dbDats[indexDbDats], newDats[indexNewDats]); + if (!matched) continue; + + dbDats[indexDbDats].DatAdd(newDats[indexNewDats]); + + FileType ft = dbChild.FileType; + + if (ft == FileType.Zip || ft == FileType.Dir) + { + RvDir dChild = (RvDir)dbChild; + RvDir dNewChild = (RvDir)newDatChild; + MergeInDat(dChild, dNewChild, out conflict, checkOnly); + } + + dbDats[indexDbDats].SearchFound = true; + newDats[indexNewDats].SearchFound = true; + } + } + + for (int indexNewDats = 0; indexNewDats < newDatsCount; indexNewDats++) + { + if (newDats[indexNewDats].SearchFound) continue; + + dbDat.ChildAdd(newDats[indexNewDats], dbIndex); + dbChild = dbDat.Child(dbIndex); + SetMissingStatus(dbChild); + + dbIndex++; + } + } + + dbIndex += dbDatsCount; + newIndex += newDatsCount; + + } + + if (res == 1) + { + if (!checkOnly) + { + dbDat.ChildAdd(newDatChild, dbIndex); + dbChild = dbDat.Child(dbIndex); + SetMissingStatus(dbChild); + + dbIndex++; + } + newIndex++; + } + + if (res == -1) + { + dbIndex++; + } + } + return false; + } + + + private static void SetMissingStatus(RvBase dbChild) + { + if (dbChild.FileRemove() == EFile.Delete) + { + ReportError.SendAndShow("Error is Set Mssing Status in DatUpdate"); + return; + } + + + FileType ft = dbChild.FileType; + if (ft == FileType.Zip || ft == FileType.Dir) + { + RvDir dbDir = (RvDir)dbChild; + for (int i = 0; i < dbDir.ChildCount; i++) + SetMissingStatus(dbDir.Child(i)); + } + + } + + private static bool FullCompare(RvBase var1, RvBase var2) + { + int retv = DBHelper.CompareName(var1, var2); + if (retv != 0) return false; + + FileType v1 = var1.FileType; + FileType v2 = var2.FileType; + retv = Math.Sign(v1.CompareTo(v2)); + if (retv != 0) return false; + + // filetypes are now know to be the same + + // Dir's and Zip's are not deep scanned so matching here is done + if ((v1 == FileType.Dir) || (v1 == FileType.Zip)) + return true; + + RvFile f1 = (RvFile)var1; + RvFile f2 = (RvFile)var2; + + if (f1.Size != null && f2.Size != null) + { + retv = ULong.iCompare(f1.Size, f2.Size); + if (retv != 0) return false; + } + + if (f1.CRC != null && f2.CRC != null) + { + retv = ArrByte.iCompare(f1.CRC, f2.CRC); + if (retv != 0) return false; + } + + if (f1.SHA1 != null && f2.SHA1 != null) + { + retv = ArrByte.iCompare(f1.SHA1, f2.SHA1); + if (retv != 0) return false; + } + + if (f1.MD5 != null && f2.MD5 != null) + { + retv = ArrByte.iCompare(f1.MD5, f2.MD5); + if (retv != 0) return false; + } + + if (f1.SHA1CHD != null && f2.SHA1CHD != null) + { + retv = ArrByte.iCompare(f1.SHA1CHD, f2.SHA1CHD); + if (retv != 0) return false; + } + + if (f1.MD5CHD != null && f2.MD5CHD != null) + { + retv = ArrByte.iCompare(f1.MD5CHD, f2.MD5CHD); + if (retv != 0) return false; + } + + return true; + } + + + + private static void UpdateDirs(RvDir dbDir, RvDir fileDir) + { + int dbIndex = 0; + int scanIndex = 0; + + dbDir.DatStatus=DatStatus.InDatCollect; + if (dbDir.Tree == null) + { + Debug.WriteLine("Adding Tree View to " + dbDir.Name); + dbDir.Tree = new RvTreeRow(); + } + + + Debug.WriteLine(""); + Debug.WriteLine("Now scanning dirs"); + + while (dbIndex < dbDir.ChildCount || scanIndex < fileDir.ChildCount) + { + RvBase dbChild = null; + RvBase fileChild = null; + int res = 0; + + if (dbIndex < dbDir.ChildCount && scanIndex < fileDir.ChildCount) + { + dbChild = dbDir.Child(dbIndex); + fileChild = fileDir.Child(scanIndex); + res = DBHelper.CompareName(dbChild, fileChild); + Debug.WriteLine("Checking " + dbChild.Name + " : and " + fileChild.Name + " : " + res); + } + else if (scanIndex < fileDir.ChildCount) + { + fileChild = fileDir.Child(scanIndex); + res = 1; + Debug.WriteLine("Checking : and " + fileChild.Name + " : " + res); + } + else if (dbIndex < dbDir.ChildCount) + { + dbChild = dbDir.Child(dbIndex); + res = -1; + } + switch (res) + { + case 0: + // found a matching directory in DatRoot So recurse back into it + + if (dbChild.GotStatus == GotStatus.Got) + { + if (dbChild.Name != fileChild.Name) // check if the case of the Item in the DB is different from the Dat Root Actual filename + { + if (!string.IsNullOrEmpty(dbChild.FileName)) // if we do not already have a different case name stored + { + dbChild.FileName = dbChild.Name; // copy the DB filename to the FileName + } + else // We already have a different case filename found in RomRoot + { + if (dbChild.FileName == fileChild.Name) // check if the Datroot name does now match the name in the DB Filename + { + dbChild.FileName = null; // if it does undo the BadCase Flag + } + } + dbChild.Name = fileChild.Name; // Set the db Name to match the Datroot Name. + } + } + else + dbChild.Name = fileChild.Name; + + UpdateDatList((RvDir)dbChild,(RvDir)fileChild); + dbIndex++; + scanIndex++; + break; + + case 1: + // found a new directory in Dat + RvDir tDir = new RvDir(FileType.Dir) + { + Name = fileChild.Name, + Tree = new RvTreeRow(), + DatStatus = DatStatus.InDatCollect, + }; + dbDir.ChildAdd(tDir, dbIndex); + Debug.WriteLine("Adding new Dir and Calling back in to check this DIR " + tDir.Name); + UpdateDatList(tDir,(RvDir)fileChild); + + dbIndex++; + scanIndex++; + break; + case -1: + // all files + dbIndex++; + break; + } + } + } + + private static void RemoveOldTree(RvBase dbBase) + { + RvDir dbDir = dbBase as RvDir; + if (dbDir == null) return; + + if (dbDir.DatStatus == DatStatus.NotInDat && dbDir.Tree != null) + dbDir.Tree = null; + + for (int i = 0; i < dbDir.ChildCount; i++) + RemoveOldTree(dbDir.Child(i)); + } + } +} diff --git a/ROMVault2/DirCellDraw.cs b/ROMVault2/DirCellDraw.cs new file mode 100644 index 0000000..66de677 --- /dev/null +++ b/ROMVault2/DirCellDraw.cs @@ -0,0 +1,146 @@ +/****************************************************** + * ROMVault2 is written by Gordon J. * + * Contact gordon@romvault.com * + * Copyright 2014 * + ******************************************************/ + +using System.Diagnostics; +using System.Drawing; +using System.Globalization; +using System.Windows.Forms; +using ROMVault2.RvDB; +using ROMVault2.SupportedFiles; + +namespace ROMVault2 +{ + + public class RomCellDraw : DataGridViewImageCell + { + private readonly Color _bgCol; + private readonly string _bitmapName; + + public RomCellDraw(string name,Color bgCol) + { + _bitmapName = name; + _bgCol = bgCol; + + } + + protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates elementState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts) + { + graphics.FillRectangle(new SolidBrush(_bgCol), cellBounds); + + Bitmap bm= rvImages.GetBitmap(_bitmapName); + + if (bm != null) + { + graphics.DrawImage(bm, cellBounds.Left, cellBounds.Top, bm.Width,bm.Height); + bm.Dispose(); + } + + + else + Debug.WriteLine("Missing Graphic for " + _bitmapName); + } + + } + + public class DirCellDraw : DataGridViewImageCell + { + private readonly Color _bgCol; + private readonly RvDir _cellDir; + + public DirCellDraw(RvDir cellDir, Color bgCol) + { + _cellDir = cellDir; + _bgCol = bgCol; + } + + protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates elementState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts) + { + + graphics.FillRectangle(new SolidBrush(_bgCol), cellBounds); + + string bitmapName; + + switch (_cellDir.FileType) + { + case FileType.Zip: + if (_cellDir.RepStatus == RepStatus.DirCorrect && _cellDir.ZipStatus==ZipStatus.TrrntZip) + bitmapName = "ZipTZ"; + else + bitmapName = "Zip" + _cellDir.RepStatus; + break; + default: + bitmapName = "Dir" + _cellDir.RepStatus; + break; + } + + Bitmap bm = rvImages.GetBitmap(bitmapName); + + if (bm != null) + { + graphics.DrawImage(bm, cellBounds.Left + 10, cellBounds.Top, 21, 17); + bm.Dispose(); + } + else + Debug.WriteLine("Missing Graphic for " + bitmapName); + } + } + + public class DirCellStatusDraw : DataGridViewImageCell + { + private readonly RvDir _dir; + public DirCellStatusDraw(RvDir dir) + { + _dir = dir; + } + + protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates elementState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts) + { + Font drawFont = new Font("Arial", 9); + SolidBrush drawBrushBlack = new SolidBrush(Color.Black); + SolidBrush drawBrushWhite = new SolidBrush(Color.White); + + graphics.FillRectangle(drawBrushWhite, cellBounds); + + int gOff; + int columnIndex = 0; + for (int l = 0; l < RepairStatus.DisplayOrder.Length; l++) + { + if (l >= 13) columnIndex = l; + + if (_dir.DirStatus.Get(RepairStatus.DisplayOrder[l]) <= 0) continue; + + gOff = cellBounds.Left + FrmMain.GameGridColumnXPositions[columnIndex]; + Bitmap bm = rvImages.GetBitmap(@"G_" + RepairStatus.DisplayOrder[l]); + if (bm != null) + { + graphics.DrawImage(bm, gOff, cellBounds.Top, 21, 18); + bm.Dispose(); + } + else + Debug.WriteLine("Missing Graphics for " + "G_" + RepairStatus.DisplayOrder[l]); + + columnIndex++; + } + + columnIndex = 0; + for (int l = 0; l < RepairStatus.DisplayOrder.Length; l++) + { + if (l >= 13) + columnIndex = l; + + if (_dir.DirStatus.Get(RepairStatus.DisplayOrder[l]) > 0) + { + gOff = cellBounds.Left + FrmMain.GameGridColumnXPositions[columnIndex]; + graphics.DrawString(_dir.DirStatus.Get(RepairStatus.DisplayOrder[l]).ToString(CultureInfo.InvariantCulture), drawFont, drawBrushBlack, new PointF(gOff + 20, cellBounds.Top + 3)); + columnIndex++; + } + } + drawBrushBlack.Dispose(); + drawBrushWhite.Dispose(); + drawFont.Dispose(); + } + } +} \ No newline at end of file diff --git a/ROMVault2/FileScanning.cs b/ROMVault2/FileScanning.cs new file mode 100644 index 0000000..e8b3726 --- /dev/null +++ b/ROMVault2/FileScanning.cs @@ -0,0 +1,842 @@ +/****************************************************** + * ROMVault2 is written by Gordon J. * + * Contact gordon@romvault.com * + * Copyright 2014 * + ******************************************************/ + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Diagnostics; +using ROMVault2.IO; +using System.Threading; +using ROMVault2.Properties; +using ROMVault2.RvDB; +using ROMVault2.SupportedFiles; +using ROMVault2.SupportedFiles.CHD; +using ROMVault2.SupportedFiles.Files; +using ROMVault2.SupportedFiles.Zip; +using ROMVault2.Utils; +using FileInfo = ROMVault2.IO.FileInfo; + +namespace ROMVault2 +{ + public static class FileScanning + { + private static Stopwatch _cacheSaveTimer; + private static long _lastUpdateTime; + private static BackgroundWorker _bgw; + public static eScanLevel EScanLevel; + private static bool _fileErrorAbort; + + + public static void ScanFiles(object sender, DoWorkEventArgs e) + { + +#if !Debug + try + { +#endif + _fileErrorAbort = false; + _cacheSaveTimer = new Stopwatch(); + _cacheSaveTimer.Reset(); + if (Settings.CacheSaveTimerEnabled) + _cacheSaveTimer.Start(); + + _bgw = sender as BackgroundWorker; + if (_bgw == null) return; + + Program.SyncCont = e.Argument as SynchronizationContext; + if (Program.SyncCont == null) + { + _bgw = null; + return; + } + + + _bgw.ReportProgress(0, new bgwText("Clearing DB Status")); + RepairStatus.ReportStatusReset(DB.DirTree); + + _bgw.ReportProgress(0, new bgwText("Finding Dir's to Scan")); + //Next get a list of all the directories to be scanned + List lstDir = new List(); + DBHelper.GetSelectedDirList(ref lstDir); + + + _bgw.ReportProgress(0, new bgwText("Scanning Dir's")); + _bgw.ReportProgress(0, new bgwSetRange(lstDir.Count - 1)); + //Scan the list of directories. + for (int i = 0; i < lstDir.Count; i++) + { + _bgw.ReportProgress(i); + _bgw.ReportProgress(0, new bgwText("Scanning Dir : " + lstDir[i].FullName)); + string lDir = lstDir[i].FullName; + Console.WriteLine(lDir); + if (Directory.Exists(lDir)) + CheckADir(lstDir[i], true); + else + MarkAsMissing(lstDir[i]); + + if (_bgw.CancellationPending || _fileErrorAbort) break; + } + + _bgw.ReportProgress(0, new bgwText("Updating Cache")); + DB.Write(); + + + _bgw.ReportProgress(0, new bgwText("File Scan Complete")); + + _bgw = null; + Program.SyncCont = null; +#if !Debug + } + catch (Exception exc) + { + ReportError.UnhandledExceptionHandler(exc); + + if (_bgw != null) _bgw.ReportProgress(0, new bgwText("Updating Cache")); + DB.Write(); + if (_bgw != null) _bgw.ReportProgress(0, new bgwText("Complete")); + + _bgw = null; + Program.SyncCont = null; + + } +#endif + } + + + + private static void CheckADir(RvDir dbDir, bool report) + { + if (_cacheSaveTimer.Elapsed.TotalMinutes > Settings.CacheSaveTimePeriod) + { + _bgw.ReportProgress(0, "Saving Cache"); + DB.Write(); + _bgw.ReportProgress(0, "Saving Cache Complete"); + _cacheSaveTimer.Reset(); + _cacheSaveTimer.Start(); + } + + string fullDir = dbDir.FullName; + if (report) + _bgw.ReportProgress(0, new bgwText2(fullDir)); + + DatStatus chechingDatStatus = dbDir.IsInToSort ? DatStatus.InToSort : DatStatus.NotInDat; + + // this is a temporary rvDir structure to store the data about the actual directory/files we are scanning + // we will first populate this variable with the real file data from the directory, and then compare it + // with the data in dbDir. + RvDir fileDir = null; + + + Debug.WriteLine(fullDir); + + FileType ft = dbDir.FileType; + + #region "Populate fileDir" + + // if we are scanning a ZIP file then populate scanDir from the ZIP file + switch (ft) + { + case FileType.Zip: + { + fileDir = new RvDir(ft); + + // open the zip file + ZipFile checkZ = new ZipFile(); + + ZipReturn zr = checkZ.ZipFileOpen(fullDir, dbDir.TimeStamp, true); + + if (zr == ZipReturn.ZipGood) + { + dbDir.ZipStatus = checkZ.ZipStatus; + + // to be Scanning a ZIP file means it is either new or has changed. + // as the code below only calls back here if that is true. + // + // Level1: Only use header CRC's + // Just get the CRC for the ZIP headers. + // + // Level2: Fully checksum changed only files + // We know this file has been changed to do a full checksum scan. + // + // Level3: Fully checksum everything + // So do a full checksum scan. + if (EScanLevel == eScanLevel.Level2 || EScanLevel == eScanLevel.Level3) + checkZ.DeepScan(); + + // add all of the file information from the zip file into scanDir + for (int i = 0; i < checkZ.LocalFilesCount(); i++) + { + RvFile tFile = new RvFile(DBTypeGet.FileFromDir(ft)) + { + Name = checkZ.Filename(i), + ZipFileIndex = i, + ZipFileHeaderPosition = checkZ.LocalHeader(i), + Size = checkZ.UncompressedSize(i), + CRC = checkZ.CRC32(i) + }; + // all 3 levels read the CRC from the ZIP header + tFile.SetStatus(chechingDatStatus, GotStatus.Got); + tFile.FileStatusSet(FileStatus.SizeFromHeader | FileStatus.CRCFromHeader); + + // if we are in level 2 or level 3 then do a full CheckSum Scan. + if (EScanLevel == eScanLevel.Level2 || EScanLevel == eScanLevel.Level3) + { + // DeepScan will return ZipReturn.ZipCRCDecodeError if the headers CRC and + // the actual CRC do not match. + // So we just need to set the MD5 and SHA1 from the ZIP file. + zr = checkZ.FileStatus(i); + if (zr == ZipReturn.ZipUntested) + { + _bgw.ReportProgress(0, new bgwShowCorrupt(zr, fullDir + " : " + checkZ.Filename(i))); + } + else if (zr != ZipReturn.ZipGood) + { + _bgw.ReportProgress(0, new bgwShowCorrupt(zr, fullDir + " : " + checkZ.Filename(i))); + tFile.GotStatus = GotStatus.Corrupt; + } + else + { + tFile.MD5 = checkZ.MD5(i); + tFile.SHA1 = checkZ.SHA1(i); + tFile.FileStatusSet(FileStatus.SizeVerified | FileStatus.CRCVerified | FileStatus.SHA1Verified | FileStatus.MD5Verified); + } + } + + fileDir.ChildAdd(tFile); + } + } + else if (zr == ZipReturn.ZipFileLocked) + { + _bgw.ReportProgress(0, new bgwShowError(fullDir, "Zip File Locked")); + dbDir.TimeStamp = 0; + dbDir.GotStatus = GotStatus.FileLocked; + } + else + { + _bgw.ReportProgress(0, new bgwShowCorrupt(zr, fullDir)); + dbDir.GotStatus = GotStatus.Corrupt; + } + checkZ.ZipFileClose(); + } + break; + + case FileType.Dir: + { + fileDir = new RvDir(FileType.Dir); + + + DirectoryInfo oDir = new DirectoryInfo(fullDir); + DirectoryInfo[] oDirs = oDir.GetDirectories(); + FileInfo[] oFiles = oDir.GetFiles(); + + // add all the subdirectories into scanDir + foreach (DirectoryInfo dir in oDirs) + { + RvBase tDir = new RvDir(FileType.Dir) + { + Name = dir.Name, + TimeStamp = dir.LastWriteTime, + }; + tDir.SetStatus(chechingDatStatus, GotStatus.Got); + fileDir.ChildAdd(tDir); + } + + // add all the files into scanDir + foreach (FileInfo oFile in oFiles) + { + // if we find any zip files add them as zip files. + string fExt = Path.GetExtension(oFile.Name); + switch (fExt.ToLower()) + { + case ".zip": + { + RvDir tGame = new RvDir(FileType.Zip) + { + Name = Path.GetFileNameWithoutExtension(oFile.Name), + TimeStamp = oFile.LastWriteTime, + }; + tGame.SetStatus(chechingDatStatus, GotStatus.Got); + fileDir.ChildAdd(tGame); + } + break; + default: + { + string fName = oFile.Name; + if (fName == "__RomVault.tmp") + { + File.Delete(oFile.FullName); + continue; + } + + // Scanning a file + // + // Level1 & 2 : (are the same for files) Fully checksum changed only files + // Here we are just getting the TimeStamp of the File, and later + // if the TimeStamp was not matched we will have to read the files CRC, MD5 & SHA1 + // + // Level3: Fully checksum everything + // Get everything about the file right here so + // read CRC, MD5 & SHA1 + + + // add all the files in the sub-directory to scanDir + RvFile tFile = new RvFile(FileType.File) + { + Name = fName, + Size = (ulong)oFile.Length, + TimeStamp = oFile.LastWriteTime + }; + + tFile.FileStatusSet(FileStatus.SizeVerified); + + int errorCode = CHD.CheckFile(oFile, out tFile.SHA1CHD, out tFile.MD5CHD, out tFile.CHDVersion); + + if (errorCode == 0) + { + if (tFile.SHA1CHD != null) tFile.FileStatusSet(FileStatus.SHA1CHDFromHeader); + if (tFile.MD5CHD != null) tFile.FileStatusSet(FileStatus.MD5CHDFromHeader); + + tFile.SetStatus(chechingDatStatus, GotStatus.Got); + + // if we are scanning at Level3 then we get all the info here + if (EScanLevel == eScanLevel.Level3) + { + DeepScanFile(fullDir, tFile); + ChdManCheck(fullDir, tFile); + } + } + else if (errorCode == 32) + { + tFile.GotStatus = GotStatus.FileLocked; + _bgw.ReportProgress(0, new bgwShowError(fullDir, "File Locked")); + } + else + { + string filename = Path.Combine(fullDir, tFile.Name); + ReportError.Show("File: " + filename + " Error: " + new Win32Exception(errorCode).Message + ". Scan Aborted."); + _fileErrorAbort = true; + return; + } + fileDir.ChildAdd(tFile); + } + break; + } + } + } + break; + default: + ReportError.SendAndShow("Un supported file type in CheckADir " + ft); + break; + } + #endregion + + if (fileDir == null) + { + ReportError.SendAndShow("Unknown Reading File Type in Dir Scanner"); + return; + } + + if (report) + { + _bgw.ReportProgress(0, new bgwSetRange2(fileDir.ChildCount - 1)); + + _bgw.ReportProgress(0, new bgwRange2Visible(true)); + } + + if (!DBTypeGet.isCompressedDir(ft) && _bgw.CancellationPending) return; + + Compare(dbDir, fileDir, report, true); + } + + public static void Compare(RvDir dbDir, RvDir fileDir, bool report, bool enableCancel) + { + + string fullDir = dbDir.FullName; + FileType ft = dbDir.FileType; + + // now we scan down the dbDir and the scanDir, comparing them. + // if we find a match we mark dbDir as found. + // if we are missing a file in scanDir we mark that file in dbDir as missing. + // if we find extra files in scanDir we add it to dbDir and mark it as unknown. + // we also recurse into any sub directories. + int dbIndex = 0; + int fileIndex = 0; + + + while (dbIndex < dbDir.ChildCount || fileIndex < fileDir.ChildCount) + { + RvBase dbChild = null; + RvBase fileChild = null; + int res = 0; + + if (dbIndex < dbDir.ChildCount && fileIndex < fileDir.ChildCount) + { + dbChild = dbDir.Child(dbIndex); + fileChild = fileDir.Child(fileIndex); + res = DBHelper.CompareName(dbChild, fileChild); + } + else if (fileIndex < fileDir.ChildCount) + { + //Get any remaining filedir's + fileChild = fileDir.Child(fileIndex); + res = 1; + } + else if (dbIndex < dbDir.ChildCount) + { + //Get any remaining dbDir's + dbChild = dbDir.Child(dbIndex); + res = -1; + } + + if (report) + { + if (fileChild != null) + { + long timenow = DateTime.Now.Ticks; + if ((timenow - _lastUpdateTime) > (TimeSpan.TicksPerSecond / 10)) + { + _lastUpdateTime = timenow; + _bgw.ReportProgress(0, new bgwValue2(fileIndex)); + _bgw.ReportProgress(0, new bgwText2(Path.Combine(fullDir, fileChild.Name))); + } + } + } + + // if this file was found in the DB + switch (res) + { + case 0: + + if (dbChild == null || fileChild == null) + { + ReportError.SendAndShow(Resources.FileScanning_CheckADir_Error_in_File_Scanning_Code); + break; + } + + //Complete MultiName Compare + List dbs = new List(); + List files = new List(); + int dbsCount = 1; + int filesCount = 1; + + + dbs.Add(dbChild); + files.Add(fileChild); + + while (dbIndex + dbsCount < dbDir.ChildCount && DBHelper.CompareName(dbChild, dbDir.Child(dbIndex + dbsCount)) == 0) + { + dbs.Add(dbDir.Child(dbIndex + dbsCount)); + dbsCount += 1; + } + while (fileIndex + filesCount < fileDir.ChildCount && DBHelper.CompareName(fileChild, fileDir.Child(fileIndex + filesCount)) == 0) + { + files.Add(fileDir.Child(fileIndex + filesCount)); + filesCount += 1; + } + + for (int indexfile = 0; indexfile < filesCount; indexfile++) + { + if (files[indexfile].SearchFound) continue; + + for (int indexdb = 0; indexdb < dbsCount; indexdb++) + { + if (dbs[indexdb].SearchFound) continue; + + bool matched = FullCompare(dbs[indexdb], files[indexfile], false, fullDir, EScanLevel); + if (!matched) continue; + + MatchFound(dbs[indexdb], files[indexfile]); + dbs[indexdb].SearchFound = true; + files[indexfile].SearchFound = true; + } + + if (files[indexfile].SearchFound) continue; + + for (int indexdb = 0; indexdb < dbsCount; indexdb++) + { + if (dbs[indexdb].SearchFound) continue; + + bool matched = FullCompare(dbs[indexdb], files[indexfile], true, fullDir, EScanLevel); + if (!matched) continue; + + MatchFound(dbs[indexdb], files[indexfile]); + dbs[indexdb].SearchFound = true; + files[indexfile].SearchFound = true; + } + } + + + for (int indexdb = 0; indexdb < dbsCount; indexdb++) + { + if (dbs[indexdb].SearchFound) + { + dbIndex++; + continue; + } + DBFileNotFound(dbs[indexdb], dbDir, ref dbIndex); + } + + for (int indexfile = 0; indexfile < filesCount; indexfile++) + { + if (files[indexfile].SearchFound) + continue; + NewFileFound(files[indexfile], dbDir, dbIndex); + dbIndex++; + } + + fileIndex += filesCount; + break; + case 1: + NewFileFound(fileChild, dbDir, dbIndex); + dbIndex++; + fileIndex++; + break; + case -1: + DBFileNotFound(dbChild, dbDir, ref dbIndex); + break; + } + + if (_fileErrorAbort) return; + if (enableCancel && !DBTypeGet.isCompressedDir(ft) && _bgw.CancellationPending) return; + } + } + + private static void MatchFound(RvBase dbChild, RvBase fileChild) + { + // only check a zip if the filestamp has changed, we asume it is the same if the filestamp has not changed. + switch (dbChild.FileType) + { + case FileType.Zip: + if (dbChild.TimeStamp != fileChild.TimeStamp || EScanLevel == eScanLevel.Level3 || + (EScanLevel == eScanLevel.Level2 && !IsDeepScanned((RvDir)dbChild))) + { + // this is done first as the CheckADir could change this value if the zip turns out to be corrupt + dbChild.FileAdd(fileChild); + CheckADir((RvDir)dbChild, false); + } + else + // this is still needed incase the filenames case (upper/lower characters) have changed, but nothing else + dbChild.FileCheckName(fileChild); + break; + case FileType.Dir: + RvDir tDir = (RvDir)dbChild; + if (tDir.Tree == null) // do not recurse into directories that are in the tree, as they are processed by the top level code. + CheckADir(tDir, true); + if (_fileErrorAbort) return; + dbChild.FileAdd(fileChild); + break; + case FileType.File: + case FileType.ZipFile: + if (dbChild.TimeStamp == fileChild.TimeStamp && dbChild.GotStatus == GotStatus.Corrupt) + fileChild.GotStatus = GotStatus.Corrupt; + + dbChild.FileAdd(fileChild); + break; + default: + throw new Exception("Unsuported file type " + dbChild.FileType); + } + } + + private static void NewFileFound(RvBase fileChild, RvDir dbDir, int dbIndex) + { + if (fileChild == null) + { + ReportError.SendAndShow(Resources.FileScanning_CheckADir_Error_in_File_Scanning_Code); + return; + } + + // this could be an unknown file, or dirctory. + // if item is a directory add the directory and call back in again + + // add the newly found item + switch (fileChild.FileType) + { + case FileType.Zip: + dbDir.ChildAdd(fileChild, dbIndex); + CheckADir((RvDir)fileChild, false); + break; + case FileType.Dir: + dbDir.ChildAdd(fileChild, dbIndex); + CheckADir((RvDir)fileChild, true); + break; + case FileType.File: + + RvFile tChild = (RvFile)fileChild; + // if we have not read the files CRC in the checking code, we need to read it now. + if (tChild.GotStatus != GotStatus.FileLocked) + { + if (!IsDeepScanned(tChild)) + DeepScanFile(dbDir.FullName, tChild); + if (!IschdmanScanned(tChild) && EScanLevel == eScanLevel.Level2) + ChdManCheck(dbDir.FullName, tChild); + } + dbDir.ChildAdd(fileChild, dbIndex); + break; + case FileType.ZipFile: + dbDir.ChildAdd(fileChild, dbIndex); + break; + default: + throw new Exception("Unsuported file type " + fileChild.FileType); + } + + } + + private static void DBFileNotFound(RvBase dbChild, RvDir dbDir, ref int dbIndex) + { + if (dbChild == null) + { + ReportError.SendAndShow(Resources.FileScanning_CheckADir_Error_in_File_Scanning_Code); + return; + } + + if (dbChild.FileRemove() == EFile.Delete) + dbDir.ChildRemove(dbIndex); + else + { + switch (dbChild.FileType) + { + case FileType.Zip: + MarkAsMissing((RvDir)dbChild); + break; + case FileType.Dir: + RvDir tDir = (RvDir)dbChild; + if (tDir.Tree == null) + MarkAsMissing(tDir); + break; + } + dbIndex++; + } + } + + + private static bool IsDeepScanned(RvDir tZip) + { + for (int i = 0; i < tZip.ChildCount; i++) + { + RvFile zFile = tZip.Child(i) as RvFile; + if (zFile != null && zFile.GotStatus == GotStatus.Got && + (!zFile.FileStatusIs(FileStatus.SizeVerified) || !zFile.FileStatusIs(FileStatus.CRCVerified) || !zFile.FileStatusIs(FileStatus.SHA1Verified) || !zFile.FileStatusIs(FileStatus.MD5Verified))) + return false; + } + return true; + } + + private static void MarkAsMissing(RvDir dbDir) + { + for (int i = 0; i < dbDir.ChildCount; i++) + { + RvBase dbChild = dbDir.Child(i); + + if (dbChild.FileRemove() == EFile.Delete) + { + dbDir.ChildRemove(i); + i--; + } + else + { + switch (dbChild.FileType) + { + case FileType.Zip: + MarkAsMissing((RvDir)dbChild); + break; + case FileType.Dir: + RvDir tDir = (RvDir)dbChild; + if (tDir.Tree == null) + MarkAsMissing(tDir); + break; + } + } + } + } + + + private static bool FullCompare(RvBase dbFile, RvBase testFile, bool secondPass, string fullDir = "", eScanLevel sLevel = eScanLevel.Level3) + { + Debug.WriteLine("Comparing Dat File " + dbFile.TreeFullName); + Debug.WriteLine("Comparing File " + testFile.TreeFullName); + + int retv = DBHelper.CompareName(dbFile, testFile); + if (retv != 0) return false; + + FileType dbfileType = dbFile.FileType; + FileType dbtestFile = testFile.FileType; + retv = Math.Sign(dbfileType.CompareTo(dbtestFile)); + if (retv != 0) return false; + + // filetypes are now know to be the same + + // Dir's and Zip's are not deep scanned so matching here is done + if ((dbfileType == FileType.Dir) || (dbfileType == FileType.Zip)) + return true; + + RvFile dbFileF = (RvFile)dbFile; + RvFile testFileF = (RvFile)testFile; + + + if (dbFileF.Size != null && testFileF.Size != null) + { + retv = ULong.iCompare(dbFileF.Size, testFileF.Size); + if (retv != 0) return false; + } + + if (dbFileF.CRC != null && testFileF.CRC != null) + { + retv = ArrByte.iCompare(dbFileF.CRC, testFileF.CRC); + if (retv != 0) return false; + } + + if (dbFileF.SHA1 != null && testFileF.SHA1 != null) + { + retv = ArrByte.iCompare(dbFileF.SHA1, testFileF.SHA1); + if (retv != 0) return false; + } + + if (dbFileF.MD5 != null && testFileF.MD5 != null) + { + retv = ArrByte.iCompare(dbFileF.MD5, testFileF.MD5); + if (retv != 0) return false; + } + + if (dbFileF.SHA1CHD != null && testFileF.SHA1CHD != null) + { + retv = ArrByte.iCompare(dbFileF.SHA1CHD, testFileF.SHA1CHD); + if (retv != 0) return false; + } + + if (dbFileF.MD5CHD != null && testFileF.MD5CHD != null) + { + retv = ArrByte.iCompare(dbFileF.MD5CHD, testFileF.MD5CHD); + if (retv != 0) return false; + } + + // beyond here we only test files + if (dbtestFile != FileType.File) + return true; + + // if scanning at level 3 then we have already deep checked the file so all is OK. + if (sLevel == eScanLevel.Level3) + return true; + + // if we got this far then everything we have so far has matched, but that may not be enough. + // now we see if we need to get any more info and try again. + + + // if the file stamps do not match or the file in the DB we are comparing with has not been deep scanned + // and the file we are scanning has not already been deep scanned, then we need to do a deep scan, and check the deep scan values + + // files are always deep scanned, so the test for IsDeepScanned(dbFileF) is probably not really needed here. + + if ((dbFileF.TimeStamp != testFileF.TimeStamp || !IsDeepScanned(dbFileF)) && !IsDeepScanned(testFileF)) + { + if (!secondPass) + return false; + + DeepScanFile(fullDir, testFileF); + if (dbFileF.CRC != null && testFileF.CRC != null) + { + retv = ArrByte.iCompare(dbFileF.CRC, testFileF.CRC); + if (retv != 0) return false; + } + + if (dbFileF.SHA1 != null && testFileF.SHA1 != null) + { + retv = ArrByte.iCompare(dbFileF.SHA1, testFileF.SHA1); + if (retv != 0) return false; + } + + if (dbFileF.MD5 != null && testFileF.MD5 != null) + { + retv = ArrByte.iCompare(dbFileF.MD5, testFileF.MD5); + if (retv != 0) return false; + } + } + + // CHDman test, if we are only scanning at level 1 then don't do CHDman test so we are done. + if (sLevel == eScanLevel.Level1) + return true; + + if ((dbFileF.TimeStamp != testFileF.TimeStamp || (!IschdmanScanned(dbFileF)) && !IschdmanScanned(testFileF))) + { + ChdManCheck(fullDir, testFileF); + } + return true; + } + + + private static bool IsDeepScanned(RvFile tFile) + { + return ( + tFile.FileStatusIs(FileStatus.SizeVerified) && + tFile.FileStatusIs(FileStatus.CRCVerified) && + tFile.FileStatusIs(FileStatus.SHA1Verified) && + tFile.FileStatusIs(FileStatus.MD5Verified) + ); + } + + private static bool IschdmanScanned(RvFile tFile) + { + //if (!tFile.FileStatusIs(FileStatus.SHA1CHDFromHeader)) + // return true; + + if (tFile.GotStatus == GotStatus.Corrupt) + return true; + + return tFile.FileStatusIs(FileStatus.SHA1CHDVerified); + } + + private static void DeepScanFile(string directory, RvFile tFile) + { + string filename = Path.Combine(directory, tFile.Name); + int errorCode = UnCompFiles.CheckSumRead(filename, true, out tFile.CRC, out tFile.MD5, out tFile.SHA1); + if (errorCode == 32) + { + tFile.GotStatus = GotStatus.FileLocked; + return; + } + if (errorCode != 0) + { + ReportError.Show("File: " + filename + " Error: " + new Win32Exception(errorCode).Message + ". Scan Aborted."); + _fileErrorAbort = true; + return; + } + tFile.FileStatusSet(FileStatus.SizeVerified | FileStatus.CRCVerified | FileStatus.SHA1Verified | FileStatus.MD5Verified); + } + + private static void ChdManCheck(string directory, RvFile tFile) + { + string filename = Path.Combine(directory, tFile.Name); + + if (!tFile.FileStatusIs(FileStatus.SHA1CHDFromHeader)) return; + _bgw.ReportProgress(0, new bgwText2(filename)); + + string error; + CHD.CHDManCheck res = CHD.ChdmanCheck(filename, _bgw, out error); + switch (res) + { + case CHD.CHDManCheck.Good: + tFile.FileStatusSet(FileStatus.SHA1CHDVerified); + return; + case CHD.CHDManCheck.Corrupt: + _bgw.ReportProgress(0, new bgwShowError(error, filename)); + tFile.GotStatus = GotStatus.Corrupt; + return; + case CHD.CHDManCheck.CHDUnknownError: + _bgw.ReportProgress(0, new bgwShowError(error, filename)); + return; + case CHD.CHDManCheck.ChdmanNotFound: + return; + case CHD.CHDManCheck.CHDNotFound: + ReportError.Show("File: " + filename + " Error: Not Found scan Aborted."); + _fileErrorAbort = true; + return; + default: + ReportError.UnhandledExceptionHandler(error); + return; + } + } + } +} + diff --git a/ROMVault2/FindFixes.cs b/ROMVault2/FindFixes.cs new file mode 100644 index 0000000..9da0260 --- /dev/null +++ b/ROMVault2/FindFixes.cs @@ -0,0 +1,479 @@ +/****************************************************** + * ROMVault2 is written by Gordon J. * + * Contact gordon@romvault.com * + * Copyright 2014 * + ******************************************************/ + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Threading; +using ROMVault2.Properties; +using ROMVault2.RvDB; +using ROMVault2.Utils; + +namespace ROMVault2 +{ + + public static class FindFixes + { + private static BackgroundWorker _bgw; + + public static void ScanFiles(object sender, DoWorkEventArgs e) + { + try + { + _bgw = sender as BackgroundWorker; + if (_bgw == null) return; + + Program.SyncCont = e.Argument as SynchronizationContext; + if (Program.SyncCont == null) + { + _bgw = null; + return; + } + + _bgw.ReportProgress(0, new bgwText("Clearing DB Status")); + RepairStatus.ReportStatusReset(DB.DirTree); + + List lstRomTableSortedCRCSize; + List lstRomTableSortedSHA1CHD; + + _bgw.ReportProgress(0, new bgwText("Loading Rom List")); + DBHelper.GetSelectedFilesSortCRCSize(out lstRomTableSortedCRCSize); + DBHelper.GetSelectedFilesSortSHA1CHD(out lstRomTableSortedSHA1CHD); + + _bgw.ReportProgress(0, new bgwText("Scanning for Fixes")); + _bgw.ReportProgress(0, new bgwSetRange(lstRomTableSortedCRCSize.Count)); + + int romIndex0 = 0; + int romIndex1 = 1; + while (romIndex1 < lstRomTableSortedCRCSize.Count) + { + if (romIndex1 % 100 == 0) _bgw.ReportProgress(romIndex1); + + if (!ArrByte.bCompare(lstRomTableSortedCRCSize[romIndex0].CRC,lstRomTableSortedCRCSize[romIndex1].CRC) || lstRomTableSortedCRCSize[romIndex0].Size != lstRomTableSortedCRCSize[romIndex1].Size) + { + ListCheck(lstRomTableSortedCRCSize, romIndex0, romIndex1 - romIndex0); + romIndex0 = romIndex1; + } + romIndex1++; + } + + ListCheck(lstRomTableSortedCRCSize, romIndex0, romIndex1 - romIndex0); + + + + _bgw.ReportProgress(0, new bgwSetRange(lstRomTableSortedSHA1CHD.Count)); + + romIndex0 = 0; + romIndex1 = 1; + while (romIndex1 < lstRomTableSortedSHA1CHD.Count) + { + if (romIndex1 % 100 == 0) _bgw.ReportProgress(romIndex1); + + if (!ArrByte.bCompare(lstRomTableSortedSHA1CHD[romIndex0].SHA1CHD,lstRomTableSortedSHA1CHD[romIndex1].SHA1CHD) ) + { + ListCheckSHA1CHD(lstRomTableSortedSHA1CHD, romIndex0, romIndex1 - romIndex0); + romIndex0 = romIndex1; + } + romIndex1++; + } + + ListCheckSHA1CHD(lstRomTableSortedSHA1CHD, romIndex0, romIndex1 - romIndex0); + + + _bgw = null; + Program.SyncCont = null; + } + catch (Exception exc) + { + ReportError.UnhandledExceptionHandler(exc); + + if (_bgw != null) _bgw.ReportProgress(0, new bgwText("Updating Cache")); + DB.Write(); + if (_bgw != null) _bgw.ReportProgress(0, new bgwText("Complete")); + + _bgw = null; + Program.SyncCont = null; + } + } + + public static void ListCheck(List lstRomTableSortedCRC, int start, int length) + { + if (lstRomTableSortedCRC.Count == 0) + return; + + List missingFiles = new List(); // files we dont have that we need + + List correctFiles = new List(); // files we have that are in the correct place + List unNeededFiles = new List(); // files we have that are not in the correct place + List inToSortFiles = new List(); // files we have that are in tosort + List allGotFiles = new List(); // all files we have + + List corruptFiles = new List(); // corrupt files that we do not need, a corrupt file is missing if it is needed + + + // set the found status of this file + for (int iLoop = 0; iLoop < length; iLoop++) + { + RvFile tFile = lstRomTableSortedCRC[start + iLoop]; + + switch (tFile.RepStatus) + { + case RepStatus.UnScanned: + break; + case RepStatus.Missing: + missingFiles.Add(tFile); // these are checked in step 1 to fixes from the allGotFiles List. + break; + case RepStatus.Correct: + correctFiles.Add(tFile); + break; + case RepStatus.Corrupt: + if (tFile.DatStatus == DatStatus.InDatCollect) + missingFiles.Add(tFile); // corrupt files that are also InDatcollect are treated as missing files, and a fix should be found. + else + corruptFiles.Add(tFile); // all other corrupt files should be deleted or moved to tosort/corrupt + break; + case RepStatus.UnNeeded: + case RepStatus.Unknown: + unNeededFiles.Add(tFile); + break; + case RepStatus.NotCollected: + break; + case RepStatus.InToSort: + inToSortFiles.Add(tFile); + break; + case RepStatus.Ignore: + break; // Ignore File + default: + ReportError.SendAndShow(Resources.FindFixes_ListCheck_Unknown_test_status + tFile.DatFullName + Resources.Comma + tFile.DatStatus + Resources.Comma + tFile.RepStatus); + break; + + } + } + allGotFiles.AddRange(correctFiles); + allGotFiles.AddRange(unNeededFiles); + allGotFiles.AddRange(inToSortFiles); + + #region Step 1 Check the Missing files from the allGotFiles List. + // check to see if we can find any of the missing files in the gotFiles list. + // if we find them mark them as CanBeFixed, + // or if they are missing corrupt files set then as corruptCanBefixed + + foreach (RvFile missingFile in missingFiles) + { + if (DBHelper.IsZeroLengthFile(missingFile)) + { + missingFile.RepStatus = missingFile.RepStatus == RepStatus.Corrupt ? RepStatus.CorruptCanBeFixed : RepStatus.CanBeFixed; + continue; + } + + foreach (RvFile gotFile in allGotFiles) + { + if (!CheckIfMissingFileCanBeFixedByGotFile(missingFile, gotFile)) continue; + missingFile.RepStatus = missingFile.RepStatus == RepStatus.Corrupt ? RepStatus.CorruptCanBeFixed : RepStatus.CanBeFixed; + break; + } + if (missingFile.RepStatus == RepStatus.Corrupt) missingFile.RepStatus = RepStatus.MoveToCorrupt; + } + #endregion + + #region Step 2 Check all corrupt files. + // if we have a correct version of the corrupt file then the corrput file can just be deleted, + // otherwise if the corrupt file is not already in ToSort it should be moved out to ToSort. + + // we can only check corrupt files using the CRC from the ZIP header, as it is corrupt so we cannot get a correct SHA1 / MD5 to check with + + foreach (RvFile corruptFile in corruptFiles) + { + if (allGotFiles.Count>0) + corruptFile.RepStatus = RepStatus.Delete; + + if (corruptFile.RepStatus == RepStatus.Corrupt && corruptFile.DatStatus != DatStatus.InToSort) + corruptFile.RepStatus = RepStatus.MoveToCorrupt; + } + #endregion + + #region Step 3 Check if unNeeded files are needed for a fix, otherwise delete them or move them to tosort + foreach (RvFile unNeededFile in unNeededFiles) + { + /* + // check if we have a confirmed SHA1 / MD5 match of this file, and if we do we just mark this file to be deleted. + foreach (RvFile correctFile in correctFiles) + { + if (!FindSHA1MD5MatchingFiles(unNeededFile, correctFile)) continue; + unNeededFile.RepStatus = RepStatus.Delete; + break; + } + if (unNeededFile.RepStatus == RepStatus.Delete) continue; + */ + + if (DBHelper.IsZeroLengthFile(unNeededFile)) + { + unNeededFile.RepStatus = RepStatus.Delete; + continue; + } + + // check if the unNeededFile is needed to fix a missing file + foreach (RvFile missingFile in missingFiles) + { + if (!CheckIfMissingFileCanBeFixedByGotFile(missingFile, unNeededFile)) continue; + unNeededFile.RepStatus = RepStatus.NeededForFix; + break; + } + if (unNeededFile.RepStatus == RepStatus.NeededForFix) continue; + + // now that we know this file is not needed for a fix do a CRC only find against correct files to see if this file can be deleted. + foreach (RvFile correctFile in correctFiles) + { + if (!CheckIfGotfileAndMatchingFileAreFullMatches(unNeededFile, correctFile)) continue; + unNeededFile.RepStatus = RepStatus.Delete; + break; + } + if (unNeededFile.RepStatus == RepStatus.Delete) continue; + + // and finally see if the file is already in ToSort, and if it is deleted. + foreach (RvFile inToSortFile in inToSortFiles) + { + if (!CheckIfGotfileAndMatchingFileAreFullMatches(unNeededFile, inToSortFile)) continue; + unNeededFile.RepStatus = RepStatus.Delete; + break; + } + if (unNeededFile.RepStatus == RepStatus.Delete) continue; + + // otherwise move the file out to ToSort + unNeededFile.RepStatus = RepStatus.MoveToSort; + } + #endregion + + #region Step 4 Check if ToSort files are needed for a fix, otherwise delete them or leave them in tosort + foreach (RvFile inToSortFile in inToSortFiles) + { + /* + // check if we have a confirmed SHA1 / MD5 match of this file, and if we do we just mark this file to be deleted. + foreach (RvFile correctFile in correctFiles) + { + if (!FindSHA1MD5MatchingFiles(inToSortFile, correctFile)) continue; + inToSortFile.RepStatus = RepStatus.Delete; + break; + } + if (inToSortFile.RepStatus == RepStatus.Delete) continue; + */ + + // check if the ToSortFile is needed to fix a missing file + foreach (RvFile missingFile in missingFiles) + { + if (!CheckIfMissingFileCanBeFixedByGotFile(missingFile, inToSortFile)) continue; + inToSortFile.RepStatus = RepStatus.NeededForFix; + break; + } + if (inToSortFile.RepStatus == RepStatus.NeededForFix) continue; + + // now that we know this file is not needed for a fix do a CRC only find against correct files to see if this file can be deleted. + foreach (RvFile correctFile in correctFiles) + { + if (!CheckIfGotfileAndMatchingFileAreFullMatches(inToSortFile, correctFile)) continue; + inToSortFile.RepStatus = RepStatus.Delete; + break; + } + + // otherwise leave the file in ToSort + } + #endregion + + + //need to check here for roms that just need renamed inside the one ZIP + //this prevents Zips from self deadlocking + for (int iLoop0 = 0; iLoop0 < length; iLoop0++) + { + if (lstRomTableSortedCRC[start + iLoop0].RepStatus != RepStatus.NeededForFix) continue; + for (int iLoop1 = 0; iLoop1 < length; iLoop1++) + { + if (lstRomTableSortedCRC[start + iLoop1].RepStatus != RepStatus.CanBeFixed) continue; + + if (!CheckIfMissingFileCanBeFixedByGotFile(lstRomTableSortedCRC[start + iLoop1], lstRomTableSortedCRC[start + iLoop0])) continue; + + if (DBHelper.RomFromSameGame(lstRomTableSortedCRC[start + iLoop0], lstRomTableSortedCRC[start + iLoop1])) + lstRomTableSortedCRC[start + iLoop0].RepStatus = RepStatus.Rename; + } + } + + } + + // find fix files, if the gotFile has been fully scanned check the SHA1/MD5, if not then just return true as the CRC/Size is all we have to go on. + // this means that if the gotfile has not been fully scanned this will return true even with the source and destination SHA1/MD5 possibly different. + public static bool CheckIfMissingFileCanBeFixedByGotFile(RvFile missingFile, RvFile gotFile) + { + + if (missingFile.FileStatusIs(FileStatus.SHA1FromDAT) && gotFile.FileStatusIs(FileStatus.SHA1Verified) && !ArrByte.bCompare(missingFile.SHA1, gotFile.SHA1)) + return false; + if (missingFile.FileStatusIs(FileStatus.MD5FromDAT) && gotFile.FileStatusIs(FileStatus.MD5Verified) && !ArrByte.bCompare(missingFile.MD5, gotFile.MD5)) + return false; + + return true; + } + + + + private static bool CheckIfGotfileAndMatchingFileAreFullMatches(RvFile gotFile, RvFile matchingFile) + { + if (gotFile.FileStatusIs(FileStatus.SHA1Verified) && matchingFile.FileStatusIs(FileStatus.SHA1Verified) && !ArrByte.bCompare(gotFile.SHA1, matchingFile.SHA1)) + return false; + if (gotFile.FileStatusIs(FileStatus.MD5Verified) && matchingFile.FileStatusIs(FileStatus.MD5Verified) && !ArrByte.bCompare(gotFile.MD5, matchingFile.MD5)) + return false; + + return true; + } + + + private static void ListCheckSHA1CHD(List lstRomTableSortedSHA1CHD, int start, int length) + { + if (lstRomTableSortedSHA1CHD.Count == 0) + return; + + List missingFiles = new List(); // files we done have have that we need + + List correctFiles = new List(); // files we have that are in the correct place + List unNeededFiles = new List(); // files we have that are not in the correct place + List inToSortFiles = new List(); // files we have that are in tosort + List allGotFiles = new List(); // all files we have + + List corruptFiles = new List(); // corrupt files that we do not need, a corrupt file is missing if it is needed + + + // set the found status of this file + for (int iLoop = 0; iLoop < length; iLoop++) + { + RvFile tFile = lstRomTableSortedSHA1CHD[start + iLoop]; + + switch (tFile.RepStatus) + { + case RepStatus.Missing: + missingFiles.Add(tFile); // these are checked in step 1 to fixes from the allGotFiles List. + break; + case RepStatus.Correct: + correctFiles.Add(tFile); + break; + case RepStatus.Corrupt: + case RepStatus.MoveToCorrupt: + if (tFile.DatStatus == DatStatus.InDatCollect) + missingFiles.Add(tFile); // corrupt files that are also InDatcollect are treated as missing files, and a fix should be found. + else + corruptFiles.Add(tFile); // all other corrupt files should be deleted or moved to tosort/corrupt + break; + case RepStatus.UnNeeded: + case RepStatus.Unknown: + case RepStatus.MoveToSort: + case RepStatus.InToSort: + case RepStatus.Delete: + case RepStatus.NeededForFix: + case RepStatus.Rename: + if (tFile.IsInToSort) + inToSortFiles.Add(tFile); + else + unNeededFiles.Add(tFile); + break; + case RepStatus.NotCollected: + break; + case RepStatus.Ignore: + break; // Ignore File + + default: + ReportError.SendAndShow(Resources.FindFixes_ListCheck_Unknown_test_status + tFile.DatFullName + Resources.Comma + tFile.DatStatus + Resources.Comma + tFile.RepStatus); + break; + + } + } + allGotFiles.AddRange(correctFiles); + allGotFiles.AddRange(unNeededFiles); + allGotFiles.AddRange(inToSortFiles); + + + #region Step 1 Check the Missing files from the allGotFiles List. + // check to see if we can find any of the missing files in the gotFiles list. + // if we find them mark them as CanBeFixed, + + foreach (RvFile missingFile in missingFiles) + { + if (allGotFiles.Count>0) + missingFile.RepStatus = (missingFile.RepStatus == RepStatus.Corrupt) || (missingFile.RepStatus == RepStatus.MoveToCorrupt) ? RepStatus.CorruptCanBeFixed : RepStatus.CanBeFixed; + } + #endregion + + #region Step 2 Check all corrupt files. + // if we have a correct version of the corrupt file then the corrput file can just be deleted, + // otherwise if the corrupt file is not already in ToSort it should be moved out to ToSort. + + // we can only check corrupt files using the CRC from the ZIP header, as it is corrupt so we cannot get a correct SHA1 / MD5 to check with + + foreach (RvFile corruptFile in corruptFiles) + { + if (allGotFiles.Count > 0) + corruptFile.RepStatus = RepStatus.Delete; + + if (corruptFile.RepStatus == RepStatus.Corrupt && corruptFile.DatStatus != DatStatus.InToSort) + corruptFile.RepStatus = RepStatus.MoveToCorrupt; + } + #endregion + + + #region Step 3 Check if unNeeded files are needed for a fix, otherwise delete them or move them to tosort + foreach (RvFile unNeededFile in unNeededFiles) + { + // check if the unNeededFile is needed to fix a missing file + if (missingFiles.Count > 0) + { + unNeededFile.RepStatus = RepStatus.NeededForFix; + continue; + } + + // now that we know this file is not needed for a fix if we have a correct version of it, it can be deleted. + if (correctFiles.Count > 0) + { + // this probably should check its old state + if (unNeededFile.RepStatus!=RepStatus.NeededForFix) + unNeededFile.RepStatus = RepStatus.Delete; + continue; + } + + if (inToSortFiles.Count > 0) + { + if (unNeededFile.RepStatus != RepStatus.NeededForFix) + unNeededFile.RepStatus = RepStatus.Delete; + continue; + } + + // otherwise move the file out to ToSort + if (unNeededFile.RepStatus != RepStatus.NeededForFix) + unNeededFile.RepStatus = RepStatus.MoveToSort; + } + #endregion + + + #region Step 4 Check if ToSort files are needed for a fix, otherwise delete them or leave them in tosort + foreach (RvFile inToSortFile in inToSortFiles) + { + // check if the ToSortFile is needed to fix a missing file + if (missingFiles.Count > 0) + { + inToSortFile.RepStatus=RepStatus.NeededForFix; + continue; + } + + // now that we know this file is not needed for a fix do a CRC only find against correct files to see if this file can be deleted. + if (correctFiles.Count <= 0) continue; + + if (inToSortFile.RepStatus != RepStatus.NeededForFix) + inToSortFile.RepStatus = RepStatus.Delete; + + // otherwise leave the file in ToSort + } + #endregion + } + } + + + + +} diff --git a/ROMVault2/FixFileCopy.cs b/ROMVault2/FixFileCopy.cs new file mode 100644 index 0000000..027d427 --- /dev/null +++ b/ROMVault2/FixFileCopy.cs @@ -0,0 +1,675 @@ +/****************************************************** + * ROMVault2 is written by Gordon J. * + * Contact gordon@romvault.com * + * Copyright 2014 * + ******************************************************/ + +using System; +using System.ComponentModel; +using System.Diagnostics; +using System.Security.Cryptography; +using ROMVault2.RvDB; +using ROMVault2.SupportedFiles; +using ROMVault2.SupportedFiles.Zip; +using ROMVault2.SupportedFiles.Zip.ZLib; +using ROMVault2.Utils; + +namespace ROMVault2 +{ + + public enum ReturnCode { Good, RescanNeeded, FindFixes, LogicError, FileSystemError, SourceCRCCheckSumError, SourceCheckSumError, DestinationCheckSumError, StartOver } + + + public static class FixFileCopy + { + private const int BufferSize = 4096 * 128; + private static byte[] _buffer; + + // This Function returns: + // Good : Everything Worked Correctly + // RescanNeeded : Something unexpectidly changed in the files, so Stop prompt user to rescan. + // LogicError : This Should never happen and is a logic problem in the code + // FileSystemError : Something is wrong with the files + + + /// + /// Performs the RomVault File Copy, with the source and destination being files or zipped files + /// + /// This is the file being copied, it may be a zipped file or a regular file system file + /// This is the zip file that is being writen to, if it is null a new zip file will be made if we are coping to a zip + /// This is the name of the .zip file to be made that will be created in zipFileOut + /// This is the actual output filename + /// if true then we will do a raw copy, this is so that we can copy corrupt zips + /// This is the returned error message if this copy fails + /// If we are SHA1/MD5 checking the source file for the first time, and it is different from what we expected the correct values for this file are returned in foundFile + /// ReturnCode.Good is the valid return code otherwire we have an error + + public static ReturnCode CopyFile(RvFile fileIn, ref ZipFile zipFileOut, string zipFilenameOut, RvFile fileOut, bool forceRaw, out string error, out RvFile foundFile) + { + foundFile = null; + error = ""; + + if (_buffer == null) + _buffer = new byte[BufferSize]; + + bool rawCopy = RawCopy(fileIn, fileOut, forceRaw); + + ulong streamSize = 0; + ushort compressionMethod = 8; + bool sourceTrrntzip = false; + + + ZipFile zipFileIn = null; + System.IO.Stream readStream = null; + + + bool isZeroLengthFile = DBHelper.IsZeroLengthFile(fileOut); + if (!isZeroLengthFile) + { + #region check that the in and out file match + if (fileOut.FileStatusIs(FileStatus.SizeFromDAT) && fileOut.Size != null && fileIn.Size != fileOut.Size) + { + error = "Source and destination Size does not match. Logic Error."; + return ReturnCode.LogicError; + } + if (fileOut.FileStatusIs(FileStatus.CRCFromDAT) && fileOut.CRC != null && !ArrByte.bCompare(fileIn.CRC, fileOut.CRC)) + { + error = "Source and destination CRC does not match. Logic Error."; + return ReturnCode.LogicError; + } + + if (fileOut.FileStatusIs(FileStatus.SHA1FromDAT) && fileIn.FileStatusIs(FileStatus.SHA1Verified)) + { + if (fileIn.SHA1 != null && fileOut.SHA1 != null && !ArrByte.bCompare(fileIn.SHA1, fileOut.SHA1)) + { + error = "Source and destination SHA1 does not match. Logic Error."; + return ReturnCode.LogicError; + } + } + if (fileOut.FileStatusIs(FileStatus.MD5CHDFromDAT) && fileIn.FileStatusIs(FileStatus.MD5Verified)) + { + if (fileIn.MD5 != null && fileOut.MD5 != null && !ArrByte.bCompare(fileIn.MD5, fileOut.MD5)) + { + error = "Source and destination SHA1 does not match. Logic Error."; + return ReturnCode.LogicError; + } + } + + #endregion + + #region Find and Check/Open Input Files + + if (fileIn.FileType == FileType.ZipFile) // Input is a ZipFile + { + RvDir zZipFileIn = fileIn.Parent; + if (zZipFileIn.FileType != FileType.Zip) + { + error = "Zip File Open but Source File is not a zip, Logic Error."; + return ReturnCode.LogicError; + } + + string fileNameIn = zZipFileIn.FullName; + + sourceTrrntzip = (zZipFileIn.ZipStatus & ZipStatus.TrrntZip) == ZipStatus.TrrntZip; + + //if (zZipFileIn.ZipFileType == RvZip.ZipType.Zip) + //{ + zipFileIn = new ZipFile(); + + ZipReturn zr1; + if (fileIn.ZipFileHeaderPosition != null) + zr1 = zipFileIn.ZipFileOpen(fileNameIn, zZipFileIn.TimeStamp, false); + else + zr1 = zipFileIn.ZipFileOpen(fileNameIn, zZipFileIn.TimeStamp, true); + switch (zr1) + { + case ZipReturn.ZipGood: + break; + case ZipReturn.ZipErrorFileNotFound: + error = "File not found, Rescan required before fixing " + fileIn.Name; + return ReturnCode.FileSystemError; + case ZipReturn.ZipErrorTimeStamp: + error = "File has changed, Rescan required before fixing " + fileIn.Name; + return ReturnCode.FileSystemError; + default: + error = "Error Open Zip" + zr1 + ", with File " + fileIn.DatFullName; + return ReturnCode.FileSystemError; + } + if (fileIn.ZipFileHeaderPosition != null) + zipFileIn.ZipFileOpenReadStreamQuick((ulong)fileIn.ZipFileHeaderPosition, rawCopy, out readStream, out streamSize, out compressionMethod); + else + zipFileIn.ZipFileOpenReadStream(fileIn.ZipFileIndex, rawCopy, out readStream, out streamSize, out compressionMethod); + } + else // Input is a regular file + { + string fileNameIn = fileIn.FullName; + if (!IO.File.Exists(fileNameIn)) + { + error = "Rescan needed, File Changed :" + fileNameIn; + return ReturnCode.RescanNeeded; + } + IO.FileInfo fileInInfo = new IO.FileInfo(fileNameIn); + if (fileInInfo.LastWriteTime != fileIn.TimeStamp) + { + error = "Rescan needed, File Changed :" + fileNameIn; + return ReturnCode.RescanNeeded; + } + int errorCode = IO.FileStream.OpenFileRead(fileNameIn, out readStream); + if (errorCode != 0) + { + error = new Win32Exception(errorCode).Message + ". " + fileNameIn; + return ReturnCode.FileSystemError; + } + if (fileIn.Size == null) + { + error = "Null File Size found in Fixing File :" + fileNameIn; + return ReturnCode.LogicError; + } + streamSize = (ulong)fileIn.Size; + if ((ulong)readStream.Length != streamSize) + { + error = "Rescan needed, File Length Changed :" + fileNameIn; + return ReturnCode.RescanNeeded; + } + } + #endregion + } + else + { + sourceTrrntzip = true; + } + + if (!rawCopy && (Settings.FixLevel == eFixLevel.TrrntZipLevel1 || Settings.FixLevel == eFixLevel.TrrntZipLevel2 || Settings.FixLevel == eFixLevel.TrrntZipLevel3)) + compressionMethod = 8; + + #region Find and Check/Open Output Files + + System.IO.Stream writeStream; + if (fileOut.FileType == FileType.ZipFile) + { + // if ZipFileOut == null then we have not open the output zip yet so open it from writing. + if (zipFileOut == null) + { + if (IO.Path.GetFileName(zipFilenameOut) == "__RomVault.tmp") + { + if (IO.File.Exists(zipFilenameOut)) + IO.File.Delete(zipFilenameOut); + } + else if (IO.File.Exists(zipFilenameOut)) + { + error = "Rescan needed, File Changed :" + zipFilenameOut; + return ReturnCode.RescanNeeded; + } + + zipFileOut = new ZipFile(); + ZipReturn zrf = zipFileOut.ZipFileCreate(zipFilenameOut); + if (zrf != ZipReturn.ZipGood) + { + error = "Error Opening Write Stream " + zrf; + return ReturnCode.FileSystemError; + } + } + else + { + if (zipFileOut.ZipOpen != ZipOpenType.OpenWrite) + { + error = "Output Zip File is not set to OpenWrite, Logic Error."; + return ReturnCode.LogicError; + } + + if (zipFileOut.ZipFilename != (new IO.FileInfo(zipFilenameOut).FullName)) + { + error = "Output Zip file has changed name from " + zipFileOut.ZipFilename + " to " + zipFilenameOut + ". Logic Error"; + return ReturnCode.LogicError; + } + } + + if (fileIn.Size == null) + { + error = "Null File Size found in Fixing File :" + fileIn.FullName; + return ReturnCode.LogicError; + } + ZipReturn zr = zipFileOut.ZipFileOpenWriteStream(rawCopy, sourceTrrntzip, fileOut.Name, (ulong)fileIn.Size, compressionMethod, out writeStream); + if (zr != ZipReturn.ZipGood) + { + error = "Error Opening Write Stream " + zr; + return ReturnCode.FileSystemError; + } + } + else + { + if (IO.File.Exists(zipFilenameOut) && fileOut.GotStatus != GotStatus.Corrupt) + { + error = "Rescan needed, File Changed :" + zipFilenameOut; + return ReturnCode.RescanNeeded; + } + int errorCode = IO.FileStream.OpenFileWrite(zipFilenameOut, out writeStream); + if (errorCode != 0) + { + error = new Win32Exception(errorCode).Message + ". " + zipFilenameOut; + return ReturnCode.FileSystemError; + } + } + #endregion + + byte[] bCRC; + byte[] bMD5 = null; + byte[] bSHA1 = null; + if (!isZeroLengthFile) + { + #region Do Data Tranfer + + CRC32Hash crc32 = null; + MD5 md5 = null; + SHA1 sha1 = null; + + if (!rawCopy) + { + crc32 = new CRC32Hash(); + md5 = MD5.Create(); + sha1 = SHA1.Create(); + } + + ulong sizetogo = streamSize; + + while (sizetogo > 0) + { + int sizenow = sizetogo > BufferSize ? BufferSize : (int)sizetogo; + + try + { + readStream.Read(_buffer, 0, sizenow); + } + catch (ZlibException) + { + if (fileIn.FileType == FileType.ZipFile && zipFileIn != null) + { + ZipReturn zr = zipFileIn.ZipFileCloseReadStream(); + if (zr != ZipReturn.ZipGood) + { + error = "Error Closing " + zr + " Stream :" + zipFileIn.Filename(fileIn.ReportIndex); + return ReturnCode.FileSystemError; + } + zipFileIn.ZipFileClose(); + + } + else + { + readStream.Close(); + } + + if (fileOut.FileType == FileType.ZipFile) + { + ZipReturn zr = zipFileOut.ZipFileCloseWriteStream(new byte[] { 0, 0, 0, 0 }); + if (zr != ZipReturn.ZipGood) + { + error = "Error Closing Stream " + zr; + return ReturnCode.FileSystemError; + } + zipFileOut.ZipFileRollBack(); + } + else + { + writeStream.Flush(); + writeStream.Close(); + IO.File.Delete(zipFilenameOut); + } + + error = "Error in Data Stream"; + return ReturnCode.SourceCRCCheckSumError; + } + catch (Exception e) + { + error = "Error reading Source File " + e.Message; + return ReturnCode.FileSystemError; + } + + if (!rawCopy) + { + crc32.TransformBlock(_buffer, 0, sizenow, null, 0); + md5.TransformBlock(_buffer, 0, sizenow, null, 0); + sha1.TransformBlock(_buffer, 0, sizenow, null, 0); + } + try + { + writeStream.Write(_buffer, 0, sizenow); + } + catch (Exception e) + { + Debug.WriteLine(e.Message); + error = "Error writing out file. " + Environment.NewLine + e.Message; + return ReturnCode.FileSystemError; + } + sizetogo = sizetogo - (ulong)sizenow; + } + writeStream.Flush(); + + #endregion + + #region Collect Checksums + + + // if we did a full copy then we just calculated all the checksums while doing the copy + if (!rawCopy) + { + + crc32.TransformFinalBlock(_buffer, 0, 0); + md5.TransformFinalBlock(_buffer, 0, 0); + sha1.TransformFinalBlock(_buffer, 0, 0); + + bCRC = crc32.Hash; + bMD5 = md5.Hash; + bSHA1 = sha1.Hash; + + } + // if we raw copied and the source file has been FileChecked then we can trust the checksums in the source file + else + { + bCRC = ArrByte.Copy(fileIn.CRC); + if (fileIn.FileStatusIs(FileStatus.MD5Verified)) bMD5 = ArrByte.Copy(fileIn.MD5); + if (fileIn.FileStatusIs(FileStatus.SHA1Verified)) bSHA1 = ArrByte.Copy(fileIn.SHA1); + } + + #endregion + + #region close the ReadStream + + if (fileIn.FileType == FileType.ZipFile && zipFileIn != null) + { + ZipReturn zr = zipFileIn.ZipFileCloseReadStream(); + if (zr != ZipReturn.ZipGood) + { + error = "Error Closing " + zr + " Stream :" + zipFileIn.Filename(fileIn.ReportIndex); + return ReturnCode.FileSystemError; + } + zipFileIn.ZipFileClose(); + } + else + { + readStream.Close(); + + //if (IO.File.Exists(tmpFilename)) + // IO.File.Delete(tmpFilename); + } + + #endregion + } + else + { + // Zero Length File (Directory in a Zip) + if (fileOut.FileType == FileType.ZipFile) + { + zipFileOut.ZipFileAddDirectory(); + } + bCRC = VarFix.CleanMD5SHA1("00000000", 8); + bMD5 = VarFix.CleanMD5SHA1("d41d8cd98f00b204e9800998ecf8427e", 32); + bSHA1 = VarFix.CleanMD5SHA1("da39a3ee5e6b4b0d3255bfef95601890afd80709", 40); + } + + + #region close the WriteStream + if (fileOut.FileType == FileType.ZipFile) + { + ZipReturn zr = zipFileOut.ZipFileCloseWriteStream(bCRC); + if (zr != ZipReturn.ZipGood) + { + error = "Error Closing Stream " + zr; + return ReturnCode.FileSystemError; + } + fileOut.ZipFileIndex = zipFileOut.LocalFilesCount() - 1; + fileOut.ZipFileHeaderPosition = zipFileOut.LocalHeader(fileOut.ZipFileIndex); + } + else + { + writeStream.Flush(); + writeStream.Close(); + IO.FileInfo fi = new IO.FileInfo(zipFilenameOut); + fileOut.TimeStamp = fi.LastWriteTime; + } + #endregion + + if (!isZeroLengthFile) + { + + if (!rawCopy) + { + if (!ArrByte.bCompare(bCRC, fileIn.CRC)) + { + fileIn.GotStatus = GotStatus.Corrupt; + error = "Source CRC does not match Source Data stream, corrupt Zip"; + + if (fileOut.FileType == FileType.ZipFile) + zipFileOut.ZipFileRollBack(); + else + IO.File.Delete(zipFilenameOut); + + return ReturnCode.SourceCRCCheckSumError; + } + + fileIn.FileStatusSet(FileStatus.CRCVerified | FileStatus.SizeVerified); + + bool sourceFailed = false; + + // check to see if we have a MD5 from the DAT file + if (fileIn.FileStatusIs(FileStatus.MD5FromDAT)) + { + if (fileIn.MD5 == null) + { + error = "Should have an filein MD5 from Dat but not found. Logic Error."; + return ReturnCode.LogicError; + } + + if (!ArrByte.bCompare(fileIn.MD5, bMD5)) + sourceFailed = true; + else + fileIn.FileStatusSet(FileStatus.MD5Verified); + } + // check to see if we have an MD5 (not from the DAT) so must be from previously scanning this file. + else if (fileIn.MD5 != null) + { + if (!ArrByte.bCompare(fileIn.MD5, bMD5)) + { + // if we had an MD5 from a preview scan and it now does not match, something has gone really bad. + error = "The MD5 found does not match a previously scanned MD5, this should not happen, unless something got corrupt."; + return ReturnCode.LogicError; + } + } + else // (FileIn.MD5 == null) + { + fileIn.MD5 = bMD5; + fileIn.FileStatusSet(FileStatus.MD5Verified); + } + + + // check to see if we have a SHA1 from the DAT file + if (fileIn.FileStatusIs(FileStatus.SHA1FromDAT)) + { + if (fileIn.SHA1 == null) + { + error = "Should have an filein SHA1 from Dat but not found. Logic Error."; + return ReturnCode.LogicError; + } + + if (!ArrByte.bCompare(fileIn.SHA1, bSHA1)) + sourceFailed = true; + else + fileIn.FileStatusSet(FileStatus.SHA1Verified); + } + // check to see if we have an SHA1 (not from the DAT) so must be from previously scanning this file. + else if (fileIn.SHA1 != null) + { + if (!ArrByte.bCompare(fileIn.SHA1, bSHA1)) + { + // if we had an SHA1 from a preview scan and it now does not match, something has gone really bad. + error = "The SHA1 found does not match a previously scanned SHA1, this should not happen, unless something got corrupt."; + return ReturnCode.LogicError; + } + } + else // (FileIn.SHA1 == null) + { + fileIn.SHA1 = bSHA1; + fileIn.FileStatusSet(FileStatus.SHA1Verified); + } + + + + + if (sourceFailed) + { + if (fileIn.FileType == FileType.ZipFile) + { + RvFile tZFile = new RvFile(FileType.ZipFile); + foundFile = tZFile; + tZFile.ZipFileIndex = fileIn.ZipFileIndex; + tZFile.ZipFileHeaderPosition = fileIn.ZipFileHeaderPosition; + } + else + { + foundFile = new RvFile(fileIn.FileType); + } + + foundFile.Name = fileIn.Name; + foundFile.Size = fileIn.Size; + foundFile.CRC = bCRC; + foundFile.MD5 = bMD5; + foundFile.SHA1 = bSHA1; + foundFile.TimeStamp = fileIn.TimeStamp; + foundFile.SetStatus(DatStatus.NotInDat, GotStatus.Got); + + foundFile.FileStatusSet(FileStatus.SizeVerified | FileStatus.CRCVerified | FileStatus.MD5Verified | FileStatus.SHA1Verified); + + if (fileOut.FileType == FileType.ZipFile) + zipFileOut.ZipFileRollBack(); + else + IO.File.Delete(zipFilenameOut); + + return ReturnCode.SourceCheckSumError; + } + } + } + + if (fileOut.FileType == FileType.ZipFile) + { + fileOut.FileStatusSet(FileStatus.SizeFromHeader | FileStatus.CRCFromHeader); + } + + if (fileOut.FileStatusIs(FileStatus.CRCFromDAT) && fileOut.CRC != null && !ArrByte.bCompare(fileOut.CRC, bCRC)) + { + //Rollback the file + if (fileOut.FileType == FileType.ZipFile) + zipFileOut.ZipFileRollBack(); + else + IO.File.Delete(zipFilenameOut); + + return ReturnCode.DestinationCheckSumError; + } + + fileOut.CRC = bCRC; + if (!rawCopy || fileIn.FileStatusIs(FileStatus.CRCVerified)) + fileOut.FileStatusSet(FileStatus.CRCVerified); + + + if (bSHA1 != null) + { + if (fileOut.FileStatusIs(FileStatus.SHA1FromDAT) && fileOut.SHA1 != null && !ArrByte.bCompare(fileOut.SHA1, bSHA1)) + { + //Rollback the file + if (fileOut.FileType == FileType.ZipFile) + zipFileOut.ZipFileRollBack(); + else + IO.File.Delete(zipFilenameOut); + + return ReturnCode.DestinationCheckSumError; + } + + fileOut.SHA1 = bSHA1; + fileOut.FileStatusSet(FileStatus.SHA1Verified); + } + + if (bMD5 != null) + { + if (fileOut.FileStatusIs(FileStatus.MD5FromDAT) && fileOut.MD5 != null && !ArrByte.bCompare(fileOut.MD5, bMD5)) + { + //Rollback the file + if (fileOut.FileType == FileType.ZipFile) + zipFileOut.ZipFileRollBack(); + else + IO.File.Delete(zipFilenameOut); + + return ReturnCode.DestinationCheckSumError; + } + fileOut.MD5 = bMD5; + fileOut.FileStatusSet(FileStatus.MD5Verified); + } + + if (fileIn.Size != null) + { + fileOut.Size = fileIn.Size; + fileOut.FileStatusSet(FileStatus.SizeVerified); + } + + + + if (fileIn.GotStatus == GotStatus.Corrupt) + fileOut.GotStatus = GotStatus.Corrupt; + else + fileOut.GotStatus = GotStatus.Got; // Changes RepStatus to Correct + + fileOut.FileStatusSet(FileStatus.SizeVerified); + + if (fileOut.SHA1CHD == null && fileIn.SHA1CHD != null) fileOut.SHA1CHD = fileIn.SHA1CHD; + if (fileOut.MD5CHD == null && fileIn.MD5CHD != null) fileOut.MD5CHD = fileIn.MD5CHD; + + + fileOut.CHDVersion = fileIn.CHDVersion; + + fileOut.FileStatusSet(FileStatus.SHA1CHDFromHeader | FileStatus.MD5CHDFromHeader | FileStatus.SHA1CHDVerified | FileStatus.MD5CHDVerified, fileIn); + + + return ReturnCode.Good; + + } + + //Raw Copy + // Returns True is a raw copy can be used + // Returns False is a full recompression is required + + private static bool RawCopy(RvFile fileIn, RvFile fileOut, bool forceRaw) + { + if (fileIn == null || fileOut == null) + return false; + + if ((fileIn.FileType != FileType.ZipFile) || (fileOut.FileType != FileType.ZipFile)) + return false; + + if (fileIn.Parent == null) + return false; + + if (forceRaw) return true; + + bool trrntzipped = (fileIn.Parent.ZipStatus & ZipStatus.TrrntZip) == ZipStatus.TrrntZip; + + bool deepchecked = fileIn.FileStatusIs(FileStatus.SHA1Verified) && fileIn.FileStatusIs(FileStatus.MD5Verified); + + switch (Settings.FixLevel) + { + case eFixLevel.TrrntZipLevel1: + return trrntzipped; + case eFixLevel.TrrntZipLevel2: + return trrntzipped && deepchecked; + case eFixLevel.TrrntZipLevel3: + return false; + + case eFixLevel.Level1: + return true; + case eFixLevel.Level2: + return deepchecked; + case eFixLevel.Level3: + return false; + } + + return false; + } + + } +} diff --git a/ROMVault2/FixFiles.cs b/ROMVault2/FixFiles.cs new file mode 100644 index 0000000..676db6a --- /dev/null +++ b/ROMVault2/FixFiles.cs @@ -0,0 +1,1850 @@ +/****************************************************** + * ROMVault2 is written by Gordon J. * + * Contact gordon@romvault.com * + * Copyright 2014 * + ******************************************************/ + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Diagnostics; +using ROMVault2.IO; +using System.Threading; +using ROMVault2.Properties; +using ROMVault2.RvDB; +using ROMVault2.SupportedFiles; +using ROMVault2.SupportedFiles.Zip; + +namespace ROMVault2 +{ + + public static class FixFiles + { + private static Stopwatch _cacheSaveTimer; + + private static string _error; + + +#if !NEWFINDFIX + private static List _lstRomTableSortedCRCSize; + private static List _lstRomTableSortedSHA1CHD; +#endif + private static List _processList; + + private static int _fixed; + private static int _reportedFixed; + + private static BackgroundWorker _bgw; + + private static void ReportProgress(object prog) + { + _bgw.ReportProgress(0, prog); + } + + public static void PerformFixes(object sender, DoWorkEventArgs e) + { + try + { + + _cacheSaveTimer = new Stopwatch(); + _cacheSaveTimer.Reset(); + if (Settings.CacheSaveTimerEnabled) + _cacheSaveTimer.Start(); + + _bgw = sender as BackgroundWorker; + if (_bgw == null) return; + + Program.SyncCont = e.Argument as SynchronizationContext; + if (Program.SyncCont == null) + { + _bgw = null; + return; + } + + ReportProgress(new bgwText("Fixing Files")); + + int totalFixes = 0; + _fixed = 0; + _reportedFixed = 0; + for (int i = 0; i < DB.DirTree.ChildCount; i++) + { + RvDir tdir = (RvDir)DB.DirTree.Child(i); + totalFixes += CountFixDir(tdir, tdir.Tree.Checked == RvTreeRow.TreeSelect.Selected); + } + ReportProgress(new bgwSetRange(totalFixes)); + +#if !NEWFINDFIX + + DBHelper.GetSelectedFilesSortCRCSize(out _lstRomTableSortedCRCSize); + DBHelper.GetSelectedFilesSortSHA1CHD(out _lstRomTableSortedSHA1CHD); + + ReportError.ReportList(_lstRomTableSortedCRCSize); +#endif + _processList = new List(); + + for (int i = 0; i < DB.DirTree.ChildCount; i++) + { + RvDir tdir = (RvDir)DB.DirTree.Child(i); + ReturnCode returnCode = FixDir(tdir, tdir.Tree.Checked == RvTreeRow.TreeSelect.Selected); + if (returnCode != ReturnCode.Good) + break; + + if (_bgw.CancellationPending) break; + } + +#if !NEWFINDFIX + _lstRomTableSortedCRCSize = null; + _lstRomTableSortedSHA1CHD = null; +#endif + + ReportProgress(new bgwText("Updating Cache")); + DB.Write(); + ReportProgress(new bgwText("Complete")); + + _bgw = null; + Program.SyncCont = null; + + } + catch (Exception exc) + { + ReportError.UnhandledExceptionHandler(exc); + + if (_bgw != null) ReportProgress(new bgwText("Updating Cache")); + DB.Write(); + if (_bgw != null) ReportProgress(new bgwText("Complete")); + + _bgw = null; + Program.SyncCont = null; + } + } + + private static int CountFixDir(RvDir dir, bool lastSelected) + { + int count = 0; + + bool thisSelected = lastSelected; + if (dir.Tree != null) + thisSelected = dir.Tree.Checked == RvTreeRow.TreeSelect.Selected; + + for (int j = 0; j < dir.ChildCount; j++) + { + RvBase child = dir.Child(j); + + switch (child.FileType) + { + case FileType.Zip: + if (!thisSelected) + continue; + RvDir tZip = (RvDir)child; + count += tZip.DirStatus.CountCanBeFixed(); + + break; + + case FileType.Dir: + + count += CountFixDir((RvDir)child, thisSelected); + break; + + case FileType.File: + if (!thisSelected) + continue; + if (child.RepStatus == RepStatus.CanBeFixed) + count++; + break; + } + } + return count; + } + + private static ReturnCode FixDir(RvDir dir, bool lastSelected) + { + Debug.WriteLine(dir.FullName); + bool thisSelected = lastSelected; + if (dir.Tree != null) + thisSelected = dir.Tree.Checked == RvTreeRow.TreeSelect.Selected; + + + List lstToProcess = new List(); + for (int j = 0; j < dir.ChildCount; j++) + lstToProcess.Add(dir.Child(j)); + + foreach (RvBase child in lstToProcess) + { + ReturnCode returnCode = FixBase(child, thisSelected); + if (returnCode != ReturnCode.Good) + return returnCode; + + while (_processList.Count > 0) + { + returnCode = FixBase(_processList[0], true); + if (returnCode != ReturnCode.Good) + return returnCode; + _processList.RemoveAt(0); + } + + if (_fixed != _reportedFixed) + { + ReportProgress(new bgwProgress(_fixed)); + _reportedFixed = _fixed; + } + if (_bgw.CancellationPending) break; + } + // here we check to see if the directory we just scanned should be deleted + CheckDeleteObject(dir); + return ReturnCode.Good; + } + + private static ReturnCode FixBase(RvBase child, bool thisSelected) + { + // skip any files that have already been deleted + if (child.RepStatus == RepStatus.Deleted) + return ReturnCode.Good; + + + if (_cacheSaveTimer.Elapsed.Minutes > Settings.CacheSaveTimePeriod) + { + ReportProgress("Saving Cache"); + DB.Write(); + ReportProgress("Saving Cache Complete"); + _cacheSaveTimer.Reset(); + _cacheSaveTimer.Start(); + } + + ReturnCode returnCode = ReturnCode.LogicError; + switch (child.FileType) + { + case FileType.Zip: + if (!thisSelected) + return ReturnCode.Good; + + if (!String.IsNullOrEmpty(child.FileName)) + { + string strDir = child.Parent.FullName; + File.Move(Path.Combine(strDir, child.FileName + ".zip"), Path.Combine(strDir, child.Name + ".zip")); + child.FileName = null; + } + + do + { + returnCode = FixZip((RvDir)child); + } while (returnCode == ReturnCode.StartOver); + break; + + case FileType.Dir: + if (thisSelected) + { + if (!String.IsNullOrEmpty(child.FileName)) + { + string strDir = child.Parent.FullName; + System.IO.Directory.Move(Path.Combine(strDir, child.FileName), Path.Combine(strDir, "__RomVault.tmpDir")); + Directory.Move(Path.Combine(strDir, "__RomVault.tmpDir"), Path.Combine(strDir, child.Name)); + child.FileName = null; + } + } + + returnCode = FixDir((RvDir)child, thisSelected); + return returnCode; + + case FileType.File: + if (!thisSelected) + return ReturnCode.Good; + + do + { + returnCode = FixFile((RvFile)child); + } while (returnCode == ReturnCode.StartOver); + break; + } + switch (returnCode) + { + case ReturnCode.Good: + // all good, move alone. + break; + case ReturnCode.RescanNeeded: + ReportError.Show(_error); + break; + case ReturnCode.LogicError: + ReportError.UnhandledExceptionHandler(_error); + break; + case ReturnCode.FileSystemError: + ReportError.Show(_error); + break; + case ReturnCode.FindFixes: + ReportError.Show("You Need to Find Fixes before Fixing. (Incorrect File Status's found for fixing.)"); + break; + default: + ReportError.UnhandledExceptionHandler(Resources.FixFiles_FixDirChildren_Unknown_result_type + returnCode); + break; + } + return returnCode; + + } + + + private static ReturnCode FixFile(RvFile fixFile) + { + switch (fixFile.RepStatus) + { + case RepStatus.Unknown: + return ReturnCode.FindFixes; + + + case RepStatus.UnScanned: + return ReturnCode.Good; + + case RepStatus.Missing: + // nothing can be done so moving right along + return ReturnCode.Good; + + + case RepStatus.Correct: + // this is correct nothing to be done here + FixFileCheckName(fixFile); + return ReturnCode.Good; + + + case RepStatus.NotCollected: + // this is correct nothing to be done here + return ReturnCode.Good; + + // Unknown + + case RepStatus.Ignore: + // this is correct nothing to be done here + return ReturnCode.Good; + + // Corrupt + + case RepStatus.InToSort: + // this is correct nothing to be done here + return ReturnCode.Good; + + + case RepStatus.Delete: + return FixFileDelete(fixFile); + + case RepStatus.MoveToSort: + return FixFileMoveToSort(fixFile); + + case RepStatus.MoveToCorrupt: + return FixFileMoveToCorrupt(fixFile); + + case RepStatus.CanBeFixed: + case RepStatus.CorruptCanBeFixed: + return FixFileCanBeFixed(fixFile); + + case RepStatus.NeededForFix: + // this file can be left as is, it will be used to fix a file, and then marked to be deleted. + return ReturnCode.Good; + + // this is for a corrupt CHD already in ToSort + case RepStatus.Corrupt: + return ReturnCode.Good; + + case RepStatus.Rename: + // this file will be used and mark to be deleted in the CanBeFixed + // so nothing to be done to it here + return ReturnCode.Good; + + + default: + ReportError.UnhandledExceptionHandler(Resources.FixFiles_FixFile_Unknown_fix_file_type + fixFile.RepStatus + " Dat Status = " + fixFile.DatStatus + " GotStatus " + fixFile.GotStatus); + return ReturnCode.LogicError; + } + } + + private static void FixFileCheckName(RvFile fixFile) + { + if (!String.IsNullOrEmpty(fixFile.FileName)) + { + string sourceFullName = Path.Combine(fixFile.Parent.FullName, fixFile.FileName); + if (!File.SetAttributes(sourceFullName, FileAttributes.Normal)) + { + int error = Error.GetLastError(); + ReportProgress(new bgwShowError(sourceFullName, "Error Setting File Attributes to Normal. Before Case correction Rename. Code " + error)); + ReportError.SendErrorMessage("Error Setting File Attributes to Normal. Before Case correction Rename. Code" + error + " : " + sourceFullName); + } + + File.Move(sourceFullName, fixFile.FullName); + fixFile.FileName = null; + } + } + + private static ReturnCode FixFileDelete(RvFile fixFile) + { + ReturnCode retCode = DoubleCheckDelete(fixFile); + if (retCode != ReturnCode.Good) + return retCode; + + string filename = fixFile.FullName; + if (File.Exists(filename)) + { + if (!File.SetAttributes(filename, FileAttributes.Normal)) + { + int error = Error.GetLastError(); + ReportProgress(new bgwShowError(filename, "Error Setting File Attributes to Normal. Before Delete. Code " + error)); + ReportError.SendErrorMessage("Error Setting File Attributes to Normal. Before Delete. Code " + error + " : " + filename); + } + File.Delete(filename); + } + // here we just deleted a file so also delete it from the DB, + // and recurse up deleting unnedded DIR's + CheckDeleteObject(fixFile); + return ReturnCode.Good; + } + + private static ReturnCode FixFileMoveToSort(RvFile fixFile) + { + string fixFileFullName = fixFile.FullName; + + string toSortFullName = Path.Combine(Settings.ToSort(), fixFile.Name); + string toSortFileName = fixFile.Name; + int fileC = 0; + while (File.Exists(toSortFullName)) + { + fileC++; + toSortFullName = Path.Combine(Settings.ToSort(), fixFile.Name + fileC); + toSortFileName = fixFile.Name + fileC; + } + + //create new tosort record + // FileInfo toSortFile = new FileInfo(toSortFullName); + RvFile toSortRom = new RvFile(FileType.File) + { + Name = toSortFileName, + Size = fixFile.Size, + CRC = fixFile.CRC, + //TimeStamp = toSortFile.LastWriteTime, + DatStatus = DatStatus.InToSort + }; + + ReportProgress(new bgwShowFix(Path.GetDirectoryName(fixFileFullName), "", Path.GetFileName(fixFileFullName), fixFile.Size, "-->", "ToSort", "", fixFile.Name)); + + ZipFile tempZipOut = null; + RvFile foundFile; + ReturnCode returnCode = FixFileCopy.CopyFile(fixFile, ref tempZipOut, toSortFullName, toSortRom, false, out _error, out foundFile); + switch (returnCode) + { + case ReturnCode.Good: // correct reply to continue; + break; + default: + return returnCode; + } + + string fixFilePath = fixFile.FullName; + if (!File.SetAttributes(fixFilePath, FileAttributes.Normal)) + { + int error = Error.GetLastError(); + ReportProgress(new bgwShowError(fixFilePath, "Error Setting File Attributes to Normal. Before Delete Moving ToSort. Code " + error)); + ReportError.SendErrorMessage("Error Setting File Attributes to Normal. Before Delete Moving ToSort. Code " + error + " : " + fixFilePath); + } + File.Delete(fixFilePath); + + // here we just deleted a file so also delete it from the DB, + // and recurse up deleting unnedded DIR's + CheckDeleteObject(fixFile); + + RvDir toSort = (RvDir)DB.DirTree.Child(1); + toSort.ChildAdd(toSortRom); + + return ReturnCode.Good; + + } + + private static ReturnCode FixFileMoveToCorrupt(RvFile fixFile) + { + string corruptDir = Path.Combine(Settings.ToSort(), "Corrupt"); + if (!Directory.Exists(corruptDir)) + { + Directory.CreateDirectory(corruptDir); + } + + string fixFileFullName = fixFile.FullName; + + string toSortCorruptFullName = Path.Combine(corruptDir, fixFile.Name); + string toSortCorruptFileName = fixFile.Name; + int fileC = 0; + while (File.Exists(toSortCorruptFullName)) + { + fileC++; + toSortCorruptFileName = fixFile.Name + fileC; + toSortCorruptFullName = Path.Combine(corruptDir, toSortCorruptFileName); + } + + //create new tosort record + // FileInfo toSortCorruptFile = new FileInfo(toSortCorruptFullName); + RvFile toSortCorruptRom = new RvFile(FileType.File) + { + Name = toSortCorruptFileName, + Size = fixFile.Size, + CRC = fixFile.CRC, + //TimeStamp = toSortFile.LastWriteTime, + DatStatus = DatStatus.InToSort + }; + + _bgw.ReportProgress(0, new bgwShowFix(Path.GetDirectoryName(fixFileFullName), "", Path.GetFileName(fixFileFullName), fixFile.Size, "-->", "Corrupt", "", fixFile.Name)); + + ZipFile tempZipOut = null; + RvFile foundFile; + ReturnCode returnCode = FixFileCopy.CopyFile(fixFile, ref tempZipOut, toSortCorruptFullName, toSortCorruptRom, false, out _error, out foundFile); + switch (returnCode) + { + case ReturnCode.Good: // correct reply to continue; + break; + default: + return returnCode; + } + + string fixFilePath = fixFile.FullName; + if (!File.SetAttributes(fixFilePath, FileAttributes.Normal)) + { + int error = Error.GetLastError(); + _bgw.ReportProgress(0, new bgwShowError(fixFilePath, "Error Setting File Attributes to Normal. Before Delete Moving ToSort. Code " + error)); + ReportError.SendErrorMessage("Error Setting File Attributes to Normal. Before Delete Moving ToSort. Code " + error + " : " + fixFilePath); + } + File.Delete(fixFilePath); + + // here we just deleted a file so also delete it from the DB, + // and recurse up deleting unnedded DIR's + CheckDeleteObject(fixFile); + + RvDir toSort = (RvDir)DB.DirTree.Child(1); + int indexcorrupt; + RvDir rvCorruptDir = new RvDir(FileType.Dir) { Name = "Corrupt", DatStatus = DatStatus.InToSort }; + int found = toSort.ChildNameSearch(rvCorruptDir, out indexcorrupt); + if (found != 0) + { + rvCorruptDir.GotStatus = GotStatus.Got; + indexcorrupt = toSort.ChildAdd(rvCorruptDir); + } + + ((RvDir)toSort.Child(indexcorrupt)).ChildAdd(toSortCorruptRom); + + return ReturnCode.Good; + } + + + private static ReturnCode FixFilePreCheckFixFile(RvFile fixFile) + { + string fileName = fixFile.FullName; + + // find all files in the DB with this name + // there could be another file if: + // there is a wrong file with the same name that can just be deleted + // there is a wrong file with the same name that needs moved to ToSort + // there is a wrong file with the same name that is needed to fix another file + List testList = new List(); + + RvDir parent = fixFile.Parent; + int index; + // start by finding the first file in the DB. (This should always work, as it will at least find the current file that CanBeFixed + if (parent.ChildNameSearch(fixFile, out index) != 0) + { + ReportError.Show("Logic error trying to find the file we are fixing " + fileName); + return ReturnCode.LogicError; + } + testList.Add(parent.Child(index++)); + + // now loop to see if there are any more files with the same name. (This is a case insensative compare) + while (index < parent.ChildCount && DBHelper.CompareName(fixFile, parent.Child(index)) == 0) + { + testList.Add(parent.Child(index)); + index++; + } + + // if we found more that one file in the DB then we need to process the incorrect file first. + if (testList.Count > 1) + { + foreach (RvBase testChild in testList) + { + if (testChild == fixFile) + continue; + + if (testChild.DatStatus != DatStatus.NotInDat) + { + ReportError.Show(Resources.FixFiles_FixFile_Trying_to_fix_a_file_that_already_exists + fileName); + return ReturnCode.LogicError; + } + + RvFile testFile = testChild as RvFile; + if (testFile == null) + { + ReportError.Show("Did not find a file logic error while fixing duplicate named file. in FixFile"); + return ReturnCode.LogicError; + } + + switch (testFile.RepStatus) + { + case RepStatus.Delete: + { + ReturnCode ret = FixFileDelete(testFile); + if (ret != ReturnCode.Good) + return ret; + break; + } + case RepStatus.MoveToSort: + { + ReturnCode ret = FixFileMoveToSort(testFile); + if (ret != ReturnCode.Good) + return ret; + break; + } + case RepStatus.MoveToCorrupt: + { + ReturnCode ret = FixFileMoveToCorrupt(testFile); + if (ret != ReturnCode.Good) + return ret; + break; + } + case RepStatus.NeededForFix: + case RepStatus.Rename: + { + // so now we have found the file with the same case insensative name and can rename it to something else to get it out of the way for now. + // need to check that the .tmp filename does not already exists. + File.SetAttributes(testChild.FullName, FileAttributes.Normal); + File.Move(testChild.FullName, testChild.FullName + ".tmp"); + + if (!parent.FindChild(testChild, out index)) + { + ReportError.Show("Unknown file status in Matching File found of " + testFile.RepStatus); + return ReturnCode.LogicError; + } + parent.ChildRemove(index); + testChild.Name = testChild.Name + ".tmp"; + parent.ChildAdd(testChild); + break; + } + default: + { + ReportError.Show("Unknown file status in Matching File found of " + testFile.RepStatus); + return ReturnCode.LogicError; + } + } + } + } + else + { + // if there is only one file in the DB then it must be the current file that CanBeFixed + if (testList[0] != fixFile) + { + ReportError.Show("Logic error trying to find the file we are fixing " + fileName + " DB found file does not match"); + return ReturnCode.LogicError; + } + } + return ReturnCode.Good; + } + + private static ReturnCode FixFileCanBeFixed(RvFile fixFile) + { + string fixFileFullName = fixFile.FullName; + CheckCreateParent(fixFile.Parent); + + // check to see if there is already a file with the name of the fixFile, and move it out the way. + ReturnCode rc = FixFilePreCheckFixFile(fixFile); + if (rc != ReturnCode.Good) + return rc; + + + // now we can fix the file. + ZipFile tempZipOut = null; + RvFile foundFile; + ReturnCode returnCode; + + if (DBHelper.IsZeroLengthFile(fixFile)) + { + RvFile fileIn = new RvFile(FileType.File); + returnCode = FixFileCopy.CopyFile(fileIn, ref tempZipOut, fixFile.FullName, fixFile, false, out _error, out foundFile); + + switch (returnCode) + { + case ReturnCode.Good: // correct reply to continue; + break; + default: + _error = fixFile.FullName + " " + fixFile.RepStatus + " " + returnCode + " : " + _error; + ReCheckFile(fixFile); + return ReturnCode.StartOver; + } + _fixed++; + return ReturnCode.Good; + } + +#if NEWFINDFIX + List lstFixRomTable = new List(); + List family = fixFile.MyFamily.Family; + for (int iFind = 0; iFind < family.Count; iFind++) + { + if (family[iFind].GotStatus == GotStatus.Got && FindFixes.CheckIfMissingFileCanBeFixedByGotFile(fixFile, family[iFind])) + lstFixRomTable.Add(family[iFind]); + } + RvFile fixingFile = lstFixRomTable[0]; +#else + + // search for the database for the file to be used to repair this file: + List lstFixRomTableCRC; + DBHelper.RomSearchFindFixes(fixFile, _lstRomTableSortedCRCSize, out lstFixRomTableCRC); + + List lstFixRomTableSHA1CHD; + DBHelper.RomSearchFindFixesSHA1CHD(fixFile, _lstRomTableSortedSHA1CHD, out lstFixRomTableSHA1CHD); + + if (lstFixRomTableCRC.Count == 0 && lstFixRomTableSHA1CHD.Count == 0) + { + // thought we could fix the file, turns out we cannot + fixFile.GotStatus = GotStatus.NotGot; + return ReturnCode.Good; + } + + RvFile fixingFile = + lstFixRomTableCRC.Count > 0 ? + lstFixRomTableCRC[0] : + lstFixRomTableSHA1CHD[0]; +#endif + string fts = fixingFile.FullName; + ReportProgress(new bgwShowFix(Path.GetDirectoryName(fixFileFullName), "", Path.GetFileName(fixFileFullName), fixFile.Size, "<--", Path.GetDirectoryName(fts), Path.GetFileName(fts), fixingFile.Name)); + + + + returnCode = FixFileCopy.CopyFile(fixingFile, ref tempZipOut, fixFile.FullName, fixFile, false, out _error, out foundFile); + + switch (returnCode) + { + case ReturnCode.Good: // correct reply to continue; + break; + + case ReturnCode.SourceCRCCheckSumError: + { + ReportProgress(new bgwShowFixError("CRC Error")); + // the file we used for fix turns out to be corrupt + + // mark the source file as Corrupt + fixingFile.GotStatus = GotStatus.Corrupt; + + // recheck for the fix + ReCheckFile(fixFile); + + CheckReprocess(fixingFile); + + // and go back one and try again. + return ReturnCode.StartOver; + } + + + case ReturnCode.SourceCheckSumError: + { + // the file we used for fix turns out not not match its own DAT's correct MD5/SHA1 + // (Problem with logic here is that it could still match the file being fixed, but this case is not correctly handled) + ReportProgress(new bgwShowFixError("Failed")); + + + // remove the file we thought we correctly had (The file that we where trying to use for the fix) + if (fixingFile.FileRemove() == EFile.Delete) + { + _error = "Should not mark for delete as it is in a DAT"; + return ReturnCode.LogicError; + } + + // possibly use a check here to see if the index of the found file is futher down the zip and so we can just contine + // instead of restarting. + + // add in the actual file we found + fixingFile.Parent.ChildAdd(foundFile); + AddFoundFile(foundFile); + + // recheck for the fix + ReCheckFile(fixFile); + + CheckReprocess(fixingFile); + + // and go back one and try again. + return ReturnCode.StartOver; + } + case ReturnCode.DestinationCheckSumError: + { + ReportProgress(new bgwShowFixError("Failed")); + + // recheck for the fix + ReCheckFile(fixFile); + return ReturnCode.StartOver; + } + default: + return returnCode; + } + + + CheckReprocessClearList(); + // Check the files that we found that where used to fix this file, and if they not listed as correct files, they can be set to be deleted. + +#if NEWFINDFIX + foreach (RvFile file in lstFixRomTable) + { + if (file.RepStatus != RepStatus.NeededForFix && file.RepStatus != RepStatus.Rename) continue; + file.RepStatus = RepStatus.Delete; + CheckReprocess(file, true); + } +#else + + foreach (RvFile file in lstFixRomTableCRC) + { + if (file.RepStatus != RepStatus.NeededForFix && file.RepStatus != RepStatus.Rename) continue; + file.RepStatus = RepStatus.Delete; + CheckReprocess(file, true); + } + foreach (RvFile file in lstFixRomTableSHA1CHD) + { + if (file.RepStatus != RepStatus.NeededForFix && file.RepStatus != RepStatus.Rename) continue; + file.RepStatus = RepStatus.Delete; + CheckReprocess(file, true); + } +#endif + CheckReprocessFinalCheck(); + + _fixed++; + + return ReturnCode.Good; + } + + + + private static ReturnCode FixZip(RvDir fixZip) + { + //Check for error status + if (fixZip.DirStatus.HasUnknown()) + return ReturnCode.FindFixes; // Error + + bool needsTrrntzipped = fixZip.ZipStatus != ZipStatus.TrrntZip && fixZip.GotStatus == GotStatus.Got && fixZip.DatStatus == DatStatus.InDatCollect && (Settings.FixLevel == eFixLevel.TrrntZipLevel1 || Settings.FixLevel == eFixLevel.TrrntZipLevel2 || Settings.FixLevel == eFixLevel.TrrntZipLevel3); + + // file corrupt and not in tosort + // if file cannot be fully fixed copy to corrupt + // process zipfile + + if (fixZip.GotStatus == GotStatus.Corrupt && fixZip.DatStatus != DatStatus.InToSort) + { + ReturnCode movReturnCode = MoveZiptoCorrupt(fixZip); + if (movReturnCode != ReturnCode.Good) + return movReturnCode; + } + + // has fixable + // process zipfile + + else if (fixZip.DirStatus.HasFixable()) + { + // do nothing here but continue on to process zip. + } + + // need trrntzipped + // process zipfile + + else if (needsTrrntzipped) + { + // do nothing here but continue on to process zip. + } + + + // got empty zip that should be deleted + // process zipfile + else if (fixZip.GotStatus == GotStatus.Got && fixZip.GotStatus != GotStatus.Corrupt && !fixZip.DirStatus.HasAnyFiles()) + { + // do nothing here but continue on to process zip. + } + + // else + // skip this zipfile + else + { + // nothing can be done to return + return ReturnCode.Good; + } + + + + string fixZipFullName = fixZip.TreeFullName; + + if (!fixZip.DirStatus.HasFixable() && needsTrrntzipped) + ReportProgress(new bgwShowFix(Path.GetDirectoryName(fixZipFullName), Path.GetFileName(fixZipFullName), "", 0, "TrrntZipping", "", "", "")); + + + CheckCreateParent(fixZip.Parent); + ReportError.LogOut(""); + ReportError.LogOut(fixZipFullName + " : " + fixZip.RepStatus); + ReportError.LogOut("------------------------------------------------------------"); + Debug.WriteLine(fixZipFullName + " : " + fixZip.RepStatus); + ReportError.LogOut("Zip File Status Before Fix:"); + for (int intLoop = 0; intLoop < fixZip.ChildCount; intLoop++) + ReportError.LogOut((RvFile)fixZip.Child(intLoop)); + ReportError.LogOut(""); + + ZipFile tempZipOut = null; + + ZipFile toSortCorruptOut = null; + ZipFile toSortZipOut = null; + + RvDir toSortGame = null; + RvDir toSortCorruptGame = null; + + ReturnCode returnCode; + List fixZipTemp = new List(); + + for (int iRom = 0; iRom < fixZip.ChildCount; iRom++) + { + RvFile zipFileFixing = new RvFile(FileType.ZipFile); + fixZip.Child(iRom).CopyTo(zipFileFixing); + + if (iRom == fixZipTemp.Count) + fixZipTemp.Add(zipFileFixing); + else + fixZipTemp[iRom] = zipFileFixing; + + ReportError.LogOut(zipFileFixing.RepStatus + " : " + fixZip.Child(iRom).FullName); + + switch (zipFileFixing.RepStatus) + { + #region Nothing to copy + // any file we do not have or do not want in the destination zip + case RepStatus.Missing: + case RepStatus.NotCollected: + case RepStatus.Rename: + case RepStatus.Delete: + if (! + ( + // got the file in the original zip but will be deleting it + (zipFileFixing.DatStatus == DatStatus.NotInDat && zipFileFixing.GotStatus == GotStatus.Got) || + (zipFileFixing.DatStatus == DatStatus.NotInDat && zipFileFixing.GotStatus == GotStatus.Corrupt) || + (zipFileFixing.DatStatus == DatStatus.InDatMerged && zipFileFixing.GotStatus == GotStatus.Got) || + (zipFileFixing.DatStatus == DatStatus.InToSort && zipFileFixing.GotStatus == GotStatus.Got) || + (zipFileFixing.DatStatus == DatStatus.InToSort && zipFileFixing.GotStatus == GotStatus.Corrupt) || + + // do not have this file and cannot fix it here + (zipFileFixing.DatStatus == DatStatus.InDatCollect && zipFileFixing.GotStatus == GotStatus.NotGot) || + (zipFileFixing.DatStatus == DatStatus.InDatBad && zipFileFixing.GotStatus == GotStatus.NotGot) || + (zipFileFixing.DatStatus == DatStatus.InDatMerged && zipFileFixing.GotStatus == GotStatus.NotGot) + ) + ) + ReportError.SendAndShow(Resources.FixFiles_FixZip_Error_in_Fix_Rom_Status + zipFileFixing.RepStatus + Resources.FixFiles_FixZip_Colon + zipFileFixing.DatStatus + Resources.FixFiles_FixZip_Colon + zipFileFixing.GotStatus); + + if (zipFileFixing.RepStatus == RepStatus.Delete) + { + returnCode = DoubleCheckDelete(zipFileFixing); + if (returnCode != ReturnCode.Good) + goto ZipOpenFailed; + } + + zipFileFixing.GotStatus = GotStatus.NotGot; + break; + #endregion + #region Copy from Original to Destination + // any files we are just moving from the original zip to the destination zip + case RepStatus.Correct: + case RepStatus.InToSort: + case RepStatus.NeededForFix: + case RepStatus.Corrupt: + { + if (! + ( + (zipFileFixing.DatStatus == DatStatus.InDatCollect && zipFileFixing.GotStatus == GotStatus.Got) || + (zipFileFixing.DatStatus == DatStatus.InDatMerged && zipFileFixing.GotStatus == GotStatus.Got) || + (zipFileFixing.DatStatus == DatStatus.NotInDat && zipFileFixing.GotStatus == GotStatus.Got) || + (zipFileFixing.DatStatus == DatStatus.InToSort && zipFileFixing.GotStatus == GotStatus.Got) || + (zipFileFixing.DatStatus == DatStatus.InToSort && zipFileFixing.GotStatus == GotStatus.Corrupt) + ) + ) + ReportError.SendAndShow(Resources.FixFiles_FixZip_Error_in_Fix_Rom_Status + zipFileFixing.RepStatus + Resources.FixFiles_FixZip_Colon + zipFileFixing.DatStatus + Resources.FixFiles_FixZip_Colon + zipFileFixing.GotStatus); + + RvFile foundFile; + + bool rawcopy = (zipFileFixing.RepStatus == RepStatus.InToSort) || (zipFileFixing.RepStatus == RepStatus.Corrupt); + // Correct rawcopy=false + // NeededForFix rawcopy=false + // InToSort rawcopy=true + // Corrupt rawcopy=true + RepStatus originalStatus = zipFileFixing.RepStatus; + + returnCode = FixFileCopy.CopyFile( + (RvFile)fixZip.Child(iRom), + ref tempZipOut, + Path.Combine(fixZip.Parent.FullName, "__RomVault.tmp"), + zipFileFixing, rawcopy, + out _error, out foundFile); + + switch (returnCode) + { + case ReturnCode.Good: // correct reply to continue; + if (originalStatus == RepStatus.NeededForFix) + zipFileFixing.RepStatus = RepStatus.NeededForFix; + break; + case ReturnCode.SourceCRCCheckSumError: + { + RvFile tFile = (RvFile)fixZip.Child(iRom); + tFile.GotStatus = GotStatus.Corrupt; + ReCheckFile(tFile); + + //decrease index so this file gets reprocessed + iRom--; + + continue; + } + case ReturnCode.SourceCheckSumError: + { + // Set the file in the zip that we thought we correctly had as missing + RvFile tFile = (RvFile)fixZip.Child(iRom); + if (tFile.FileRemove() == EFile.Delete) + { + _error = "Should not mark for delete as it is in a DAT"; + return ReturnCode.LogicError; + } + + // Add in at the current location the incorrect file. (This file will be reprocessed and then at some point deleted.) + fixZip.ChildAdd(foundFile, iRom); + AddFoundFile(foundFile); + + ReCheckFile(tFile); + + //decrease index so this file gets reprocessed + iRom--; + + continue; + } + // not needed as source and destination are the same + // case ReturnCode.DestinationCheckSumError: + default: + _error = zipFileFixing.FullName + " " + zipFileFixing.RepStatus + " " + returnCode + " : " + _error; + goto ZipOpenFailed; + } + } + break; + #endregion + + #region Case.CanBeFixed + case RepStatus.CanBeFixed: + case RepStatus.CorruptCanBeFixed: + { + if (!(zipFileFixing.DatStatus == DatStatus.InDatCollect && (zipFileFixing.GotStatus == GotStatus.NotGot || zipFileFixing.GotStatus == GotStatus.Corrupt))) + ReportError.SendAndShow(Resources.FixFiles_FixZip_Error_in_Fix_Rom_Status + zipFileFixing.RepStatus + Resources.FixFiles_FixZip_Colon + zipFileFixing.DatStatus + Resources.FixFiles_FixZip_Colon + zipFileFixing.GotStatus); + + ReportError.LogOut("Fixing File:"); + ReportError.LogOut(zipFileFixing); + + string strPath = fixZip.Parent.FullName; + string tempZipFilename = Path.Combine(strPath, "__RomVault.tmp"); + + + if (DBHelper.IsZeroLengthFile(zipFileFixing)) + { + RvFile fileIn = new RvFile(FileType.ZipFile) { Size = 0 }; + RvFile foundFile; + returnCode = FixFileCopy.CopyFile(fileIn, ref tempZipOut, tempZipFilename, zipFileFixing, false, out _error, out foundFile); + + switch (returnCode) + { + case ReturnCode.Good: // correct reply to continue; + break; + default: + _error = zipFileFixing.FullName + " " + zipFileFixing.RepStatus + " " + returnCode + " : " + _error; + goto ZipOpenFailed; + } + break; + } + +#if NEWFINDFIX + List lstFixRomTable = new List(); + List family = zipFileFixing.MyFamily.Family; + for (int iFind = 0; iFind < family.Count; iFind++) + { + if (family[iFind].GotStatus == GotStatus.Got && FindFixes.CheckIfMissingFileCanBeFixedByGotFile(zipFileFixing, family[iFind])) + lstFixRomTable.Add(family[iFind]); + } +#else + List lstFixRomTable; + DBHelper.RomSearchFindFixes(zipFileFixing, _lstRomTableSortedCRCSize, out lstFixRomTable); +#endif + + ReportError.LogOut("Found Files To use for Fixes:"); + foreach (RvFile t in lstFixRomTable) + ReportError.LogOut(t); + + if (lstFixRomTable.Count > 0) + { + + string ts = lstFixRomTable[0].Parent.FullName; + string sourceDir; + string sourceFile; + if (lstFixRomTable[0].FileType == FileType.ZipFile) + { + sourceDir = Path.GetDirectoryName(ts); + sourceFile = Path.GetFileName(ts); + } + else + { + sourceDir = ts; + sourceFile = ""; + } + ReportProgress(new bgwShowFix(Path.GetDirectoryName(fixZipFullName), Path.GetFileName(fixZipFullName), zipFileFixing.Name, zipFileFixing.Size, "<--", sourceDir, sourceFile, lstFixRomTable[0].Name)); + + RvFile foundFile; + returnCode = FixFileCopy.CopyFile(lstFixRomTable[0], ref tempZipOut, tempZipFilename, zipFileFixing, false, out _error, out foundFile); + switch (returnCode) + { + case ReturnCode.Good: // correct reply so continue; + break; + + case ReturnCode.SourceCRCCheckSumError: + { + ReportProgress(new bgwShowFixError("CRC Error")); + // the file we used for fix turns out to be corrupt + + RvFile tFile = (RvFile)fixZip.Child(iRom); + + // mark the source file as Corrupt + lstFixRomTable[0].GotStatus = GotStatus.Corrupt; + + // recheck for the fix + ReCheckFile(tFile); + + // if the file being used from the fix is actually from this file then we have a big mess, and we are just going to + // start over on this zip. + if (lstFixRomTable[0].Parent == fixZip) + { + returnCode = ReturnCode.StartOver; + goto ZipOpenFailed; + } + + // add the fixing source zip into the processList so that it is also reprocessed and we just changed it. + if (!_processList.Contains(lstFixRomTable[0].Parent)) + _processList.Add(lstFixRomTable[0].Parent); + + // and go back one and try again. + iRom--; + continue; + } + + + case ReturnCode.SourceCheckSumError: + { + ReportProgress(new bgwShowFixError("Failed")); + // the file we used for fix turns out not not match its own DAT's correct MD5/SHA1 + // (Problem with logic here is that it could still match the file being fixed, but this case is not correctly handled) + + RvFile tFile = (RvFile)fixZip.Child(iRom); + + // remove the file we thought we correctly had (The file that we where trying to use for the fix) + if (lstFixRomTable[0].FileRemove() == EFile.Delete) + { + _error = "Should not mark for delete as it is in a DAT"; + return ReturnCode.LogicError; + } + + // possibly use a check here to see if the index of the found file is futher down the zip and so we can just contine + // instead of restarting. + + // add in the actual file we found + lstFixRomTable[0].Parent.ChildAdd(foundFile); + AddFoundFile(foundFile); + + // recheck for the fix + ReCheckFile(tFile); + + // if the file being used from the fix is actually from this file then we have a big mess, and we are just going to + // start over on this zip. + if (lstFixRomTable[0].Parent == fixZip) + { + returnCode = ReturnCode.StartOver; + goto ZipOpenFailed; + } + + // add the fixing source zip into the processList so that it is also reprocessed and we just changed it. + if (!_processList.Contains(lstFixRomTable[0].Parent)) + _processList.Add(lstFixRomTable[0].Parent); + + // and go back one and try again. + iRom--; + continue; + } + case ReturnCode.DestinationCheckSumError: + { + ReportProgress(new bgwShowFixError("Failed")); + // the file we used for fix turns out not to have the correct MD5/SHA1 + RvFile tFile = (RvFile)fixZip.Child(iRom); + + // recheck for the fix + ReCheckFile(tFile); + + // if the file being used from the fix is actually from this file then we have a big mess, and we are just going to + // start over on this zip. + // The need for this is that the file being pulled in from inside this zip will be marked as Rename + // and so would then automatically be deleted, in the case this exception happens, this source file instead + // should be set to move to tosort. + if (lstFixRomTable[0].Parent == fixZip) + { + returnCode = ReturnCode.StartOver; + goto ZipOpenFailed; + } + + // and go back one and try again. + iRom--; + continue; + } + default: + //_error = zipFileFixing.FullName + " " + zipFileFixing.RepStatus + " " + returnCode + Environment.NewLine + _error; + goto ZipOpenFailed; + } + + //Check to see if the files used for fix, can now be set to delete + CheckReprocessClearList(); + + foreach (RvFile tFixRom in lstFixRomTable) + { + if (tFixRom.RepStatus == RepStatus.NeededForFix) + { + tFixRom.RepStatus = RepStatus.Delete; + ReportError.LogOut("Setting File Status to Delete:"); + ReportError.LogOut(tFixRom); + CheckReprocess(tFixRom, true); + } + } + CheckReprocessFinalCheck(); + + _fixed++; + } + else + // thought we could fix it, turns out we cannot + zipFileFixing.GotStatus = GotStatus.NotGot; + } + break; + #endregion + #region Case.MoveToSort + case RepStatus.MoveToSort: + { + if (!(zipFileFixing.DatStatus == DatStatus.NotInDat && zipFileFixing.GotStatus == GotStatus.Got)) + ReportError.SendAndShow(Resources.FixFiles_FixZip_Error_in_Fix_Rom_Status + zipFileFixing.RepStatus + Resources.FixFiles_FixZip_Colon + zipFileFixing.DatStatus + Resources.FixFiles_FixZip_Colon + zipFileFixing.GotStatus); + + ReportError.LogOut("Moving File out to ToSort:"); + ReportError.LogOut(zipFileFixing); + // move the rom out to the To Sort Directory + + if (toSortGame == null) + { + string toSortFullName = Path.Combine(Settings.ToSort(), fixZip.Name + ".zip"); + string toSortFileName = fixZip.Name; + int fileC = 0; + while (File.Exists(toSortFullName)) + { + fileC++; + toSortFullName = Path.Combine(Settings.ToSort(), fixZip.Name + fileC + ".zip"); + toSortFileName = fixZip.Name + fileC; + } + + toSortGame = new RvDir(FileType.Zip) + { + Name = toSortFileName, + DatStatus = DatStatus.InToSort, + GotStatus = GotStatus.Got + }; + } + + RvFile toSortRom = new RvFile(FileType.ZipFile) + { + Name = zipFileFixing.Name, + Size = zipFileFixing.Size, + CRC = zipFileFixing.CRC, + SHA1 = zipFileFixing.SHA1, + MD5 = zipFileFixing.MD5 + }; + toSortRom.SetStatus(DatStatus.InToSort, GotStatus.Got); + toSortRom.FileStatusSet( + FileStatus.SizeFromHeader | FileStatus.SizeVerified | + FileStatus.CRCFromHeader | FileStatus.CRCVerified | + FileStatus.SHA1FromHeader | FileStatus.SHA1Verified | + FileStatus.MD5FromHeader | FileStatus.MD5Verified + , zipFileFixing); + + toSortGame.ChildAdd(toSortRom); + + string destination = Path.Combine(Settings.ToSort(), toSortGame.Name + ".zip"); + ReportProgress(new bgwShowFix(Path.GetDirectoryName(fixZipFullName), Path.GetFileName(fixZipFullName), zipFileFixing.Name, zipFileFixing.Size, "-->", "ToSort", Path.GetFileName(destination), toSortRom.Name)); + + RvFile foundFile; + returnCode = FixFileCopy.CopyFile((RvFile)fixZip.Child(iRom), ref toSortZipOut, destination, toSortRom, true, out _error, out foundFile); + switch (returnCode) + { + case ReturnCode.Good: // correct reply to continue; + break; + //raw copying so Checksums are not checked + //case ReturnCode.SourceCRCCheckSumError: + //case ReturnCode.SourceCheckSumError: + //case ReturnCode.DestinationCheckSumError: + default: + _error = zipFileFixing.FullName + " " + zipFileFixing.RepStatus + " " + returnCode + " : " + _error; + goto ZipOpenFailed; + } + zipFileFixing.GotStatus = GotStatus.NotGot; // Changes RepStatus to Deleted + } + break; + #endregion + #region Case.MoveToCorrupt + case RepStatus.MoveToCorrupt: + { + if (!((zipFileFixing.DatStatus == DatStatus.InDatCollect || zipFileFixing.DatStatus == DatStatus.NotInDat) && zipFileFixing.GotStatus == GotStatus.Corrupt)) + ReportError.SendAndShow(Resources.FixFiles_FixZip_Error_in_Fix_Rom_Status + zipFileFixing.RepStatus + Resources.FixFiles_FixZip_Colon + zipFileFixing.DatStatus + Resources.FixFiles_FixZip_Colon + zipFileFixing.GotStatus); + + ReportError.LogOut("Moving File to Corrupt"); + ReportError.LogOut(zipFileFixing); + + string toSortFullName; + if (toSortCorruptGame == null) + { + string corruptDir = Path.Combine(Settings.ToSort(), "Corrupt"); + if (!Directory.Exists(corruptDir)) + { + Directory.CreateDirectory(corruptDir); + } + + toSortFullName = Path.Combine(corruptDir, fixZip.Name + ".zip"); + string toSortFileName = fixZip.Name; + int fileC = 0; + while (File.Exists(toSortFullName)) + { + fileC++; + toSortFullName = Path.Combine(corruptDir, fixZip.Name + fileC + ".zip"); + toSortFileName = fixZip.Name + fileC; + } + + toSortCorruptGame = new RvDir(FileType.Zip) + { + Name = toSortFileName, + DatStatus = DatStatus.InToSort, + GotStatus = GotStatus.Got + }; + } + else + { + string corruptDir = Path.Combine(Settings.ToSort(), "Corrupt"); + toSortFullName = Path.Combine(corruptDir, toSortCorruptGame.Name + ".zip"); + } + + RvFile toSortCorruptRom = new RvFile(FileType.ZipFile) + { + Name = zipFileFixing.Name, + Size = zipFileFixing.Size, + CRC = zipFileFixing.CRC + }; + toSortCorruptRom.SetStatus(DatStatus.InToSort, GotStatus.Corrupt); + toSortCorruptGame.ChildAdd(toSortCorruptRom); + + ReportProgress(new bgwShowFix(Path.GetDirectoryName(fixZipFullName), Path.GetFileName(fixZipFullName), zipFileFixing.Name, zipFileFixing.Size, "-->", "Corrupt", Path.GetFileName(toSortFullName), zipFileFixing.Name)); + + RvFile foundFile; + returnCode = FixFileCopy.CopyFile((RvFile)fixZip.Child(iRom), ref toSortCorruptOut, toSortFullName, toSortCorruptRom, true, out _error, out foundFile); + switch (returnCode) + { + case ReturnCode.Good: // correct reply to continue; + break; + + // doing a raw copy so not needed + // case ReturnCode.SourceCRCCheckSumError: + // case ReturnCode.SourceCheckSumError: + // case ReturnCode.DestinationCheckSumError: + default: + _error = zipFileFixing.FullName + " " + zipFileFixing.RepStatus + " " + returnCode + " : " + _error; + goto ZipOpenFailed; + } + zipFileFixing.GotStatus = GotStatus.NotGot; + } + break; + #endregion + default: + + + + ReportError.UnhandledExceptionHandler("Unknown file status found " + zipFileFixing.RepStatus + " while fixing file " + fixZip.Name + " Dat Status = " + zipFileFixing.DatStatus + " GotStatus " + zipFileFixing.GotStatus); + break; + } + } + + + #region if ToSort Zip Made then close the zip and add this new zip to the Database + if (toSortGame != null) + { + toSortZipOut.ZipFileClose(); + + toSortGame.TimeStamp = toSortZipOut.TimeStamp; + toSortGame.DatStatus = DatStatus.InToSort; + toSortGame.GotStatus = GotStatus.Got; + toSortGame.ZipStatus = toSortZipOut.ZipStatus; + + RvDir toSort = (RvDir)DB.DirTree.Child(1); + toSort.ChildAdd(toSortGame); + } + #endregion + + #region if Corrupt Zip Made then close the zip and add this new zip to the Database + if (toSortCorruptGame != null) + { + toSortCorruptOut.ZipFileClose(); + + toSortCorruptGame.TimeStamp = toSortCorruptOut.TimeStamp; + toSortCorruptGame.DatStatus = DatStatus.InToSort; + toSortCorruptGame.GotStatus = GotStatus.Got; + + RvDir toSort = (RvDir)DB.DirTree.Child(1); + int indexcorrupt; + RvDir corruptDir = new RvDir(FileType.Dir) { Name = "Corrupt", DatStatus = DatStatus.InToSort }; + int found = toSort.ChildNameSearch(corruptDir, out indexcorrupt); + if (found != 0) + { + corruptDir.GotStatus = GotStatus.Got; + indexcorrupt = toSort.ChildAdd(corruptDir); + } + ((RvDir)toSort.Child(indexcorrupt)).ChildAdd(toSortCorruptGame); + } + #endregion + + + + #region Process original Zip + string filename = fixZip.FullName; + if (File.Exists(filename)) + { + if (!File.SetAttributes(filename, FileAttributes.Normal)) + { + int error = Error.GetLastError(); + ReportProgress(new bgwShowError(filename, "Error Setting File Attributes to Normal. Deleting Original Fix File. Code " + error)); + ReportError.SendErrorMessage("Error Setting File Attributes to Normal. Deleting Original Fix File. Code " + error + " : " + filename); + } + try + { + File.Delete(filename); + } + catch (Exception) + { + int error = Error.GetLastError(); + _error = "Error While trying to delete file " + filename + ". Code " + error; + ReportError.SendErrorMessage("Error While trying to delete file. Code " + error + " : " + filename); + + if (tempZipOut != null && tempZipOut.ZipOpen != ZipOpenType.Closed) + tempZipOut.ZipFileClose(); + + return ReturnCode.RescanNeeded; + } + + } + #endregion + + bool checkDelete = false; + #region process the temp Zip rename it to the original Zip + if (tempZipOut != null && tempZipOut.ZipOpen != ZipOpenType.Closed) + { + string tempFilename = tempZipOut.ZipFilename; + tempZipOut.ZipFileClose(); + + if (tempZipOut.LocalFilesCount() > 0) + { + // now rename the temp fix file to the correct filename + File.Move(tempFilename, filename); + FileInfo nFile = new FileInfo(filename); + RvDir tmpZip = new RvDir(FileType.Zip) + { + Name = Path.GetFileNameWithoutExtension(filename), + TimeStamp = nFile.LastWriteTime + }; + tmpZip.SetStatus(fixZip.DatStatus, GotStatus.Got); + + fixZip.FileAdd(tmpZip); + fixZip.ZipStatus = tempZipOut.ZipStatus; + } + else + { + File.Delete(tempFilename); + checkDelete = true; + } + } + else + checkDelete = true; + #endregion + + #region Now put the New Game Status information into the Database. + int intLoopFix = 0; + foreach (RvFile tmpZip in fixZipTemp) + { + tmpZip.CopyTo(fixZip.Child(intLoopFix)); + + if (fixZip.Child(intLoopFix).RepStatus == RepStatus.Deleted) + if (fixZip.Child(intLoopFix).FileRemove() == EFile.Delete) + { + fixZip.ChildRemove(intLoopFix); + continue; + } + + intLoopFix++; + } + #endregion + + if (checkDelete) + CheckDeleteObject(fixZip); + + ReportError.LogOut(""); + ReportError.LogOut("Zip File Status After Fix:"); + for (int intLoop = 0; intLoop < fixZip.ChildCount; intLoop++) + ReportError.LogOut((RvFile)fixZip.Child(intLoop)); + ReportError.LogOut(""); + + return ReturnCode.Good; + + + ZipOpenFailed: + if (tempZipOut != null) tempZipOut.ZipFileCloseFailed(); + if (toSortZipOut != null) toSortZipOut.ZipFileCloseFailed(); + if (toSortCorruptOut != null) toSortCorruptOut.ZipFileCloseFailed(); + return returnCode; + + } + + private static void AddFoundFile(RvFile foundFile) + { + if ((foundFile.Size == null || foundFile.CRC == null) && foundFile.Size != 0) return; + + int intIndex; + int intRes = DBHelper.RomSearchCRCSize(foundFile, _lstRomTableSortedCRCSize, out intIndex); + if (intRes == 0) + _lstRomTableSortedCRCSize.Insert(intIndex, foundFile); + } + + private static void ReCheckFile(RvFile searchFile) + { +#if NEWFINDFIX + FindFixesNew.ListCheck(searchFile.MyFamily); +#else + int index; + int length; + + DBHelper.RomSearchFindMatchingFiles(searchFile, _lstRomTableSortedCRCSize, out index, out length); + + for (int i = index; i < index + length; i++) + _lstRomTableSortedCRCSize[i].RepStatusReset(); + + FindFixes.ListCheck(_lstRomTableSortedCRCSize, index, length); +#endif + } + + private static ReturnCode DoubleCheckDelete(RvFile fileDeleting) + { + if (!Settings.DoubleCheckDelete) + return ReturnCode.Good; + + + ReportError.LogOut("Double Check deleting file "); + ReportError.LogOut(fileDeleting); + + if (DBHelper.IsZeroLengthFile(fileDeleting)) + return ReturnCode.Good; + +#if NEWFINDFIX + List lstFixRomTable = new List(); + List family = fileDeleting.MyFamily.Family; + for (int iFind = 0; iFind < family.Count; iFind++) + { + if (family[iFind].GotStatus == GotStatus.Got && FindFixes.CheckIfMissingFileCanBeFixedByGotFile(fileDeleting, family[iFind])) + lstFixRomTable.Add(family[iFind]); + } +#else + List lstFixRomTableCRCSize; + List lstFixRomTableSHA1CHD; + + DBHelper.RomSearchFindFixes(fileDeleting, _lstRomTableSortedCRCSize, out lstFixRomTableCRCSize); + DBHelper.RomSearchFindFixesSHA1CHD(fileDeleting, _lstRomTableSortedSHA1CHD, out lstFixRomTableSHA1CHD); + + List lstFixRomTable = new List(); + lstFixRomTable.AddRange(lstFixRomTableCRCSize); + lstFixRomTable.AddRange(lstFixRomTableSHA1CHD); +#endif + RvFile fileToCheck = null; + int i = 0; + while (i < lstFixRomTable.Count && fileToCheck == null) + { + + switch (lstFixRomTable[i].RepStatus) + { + case RepStatus.Delete: + i++; + break; + case RepStatus.Correct: + case RepStatus.InToSort: + case RepStatus.Rename: + case RepStatus.NeededForFix: + case RepStatus.MoveToSort: + case RepStatus.Ignore: + fileToCheck = lstFixRomTable[i]; + break; + default: + + ReportError.LogOut("Double Check Delete Error Unknown " + lstFixRomTable[i].FullName + " " + lstFixRomTable[i].RepStatus); + ReportError.UnhandledExceptionHandler("Unknown double check delete status " + lstFixRomTable[i].RepStatus); + break; + } + } + //ReportError.LogOut("Found Files when double check deleting"); + //foreach (RvFile t in lstFixRomTable) + // ReportError.LogOut(t); + + if (fileToCheck == null) + { + ReportError.UnhandledExceptionHandler("Double Check Delete could not find the correct file. (" + fileDeleting.FullName + ")"); + //this line of code never gets called because the above line terminates the program. + return ReturnCode.LogicError; + } + + //if it is a file then + // check it exists and the filestamp matches + //if it is a ZipFile then + // check the parent zip exists and the filestamp matches + + switch (fileToCheck.FileType) + { + case FileType.ZipFile: + { + string fullPathCheckDelete = fileToCheck.Parent.FullName; + if (!File.Exists(fullPathCheckDelete)) + { + _error = "Deleting " + fileDeleting.FullName + " Correct file not found. Resan for " + fullPathCheckDelete; + return ReturnCode.RescanNeeded; + } + FileInfo fi = new FileInfo(fullPathCheckDelete); + if (fi.LastWriteTime != fileToCheck.Parent.TimeStamp) + { + _error = "Deleting " + fileDeleting.FullName + " Correct file timestamp not found. Resan for " + fileToCheck.FullName; + return ReturnCode.RescanNeeded; + } + break; + } + case FileType.File: + { + string fullPathCheckDelete = fileToCheck.FullName; + if (!File.Exists(fullPathCheckDelete)) + { + _error = "Deleting " + fileDeleting.FullName + " Correct file not found. Resan for " + fullPathCheckDelete; + return ReturnCode.RescanNeeded; + } + FileInfo fi = new FileInfo(fullPathCheckDelete); + if (fi.LastWriteTime != fileToCheck.TimeStamp) + { + _error = "Deleting " + fileDeleting.FullName + " Correct file timestamp not found. Resan for " + fileToCheck.FullName; + return ReturnCode.RescanNeeded; + } + break; + } + default: + ReportError.UnhandledExceptionHandler("Unknown double check delete status " + fileToCheck.RepStatus); + break; + } + + + return ReturnCode.Good; + } + + private static ReturnCode MoveZiptoCorrupt(RvDir fixZip) + { + string fixZipFullName = fixZip.FullName; + if (!File.Exists(fixZipFullName)) + { + _error = "File for move to corrupt not found " + fixZip.FullName; + return ReturnCode.RescanNeeded; + } + FileInfo fi = new FileInfo(fixZipFullName); + if (fi.LastWriteTime != fixZip.TimeStamp) + { + _error = "File for move to corrupt timestamp not correct " + fixZip.FullName; + return ReturnCode.RescanNeeded; + } + + string corruptDir = Path.Combine(Settings.ToSort(), "Corrupt"); + if (!Directory.Exists(corruptDir)) + { + Directory.CreateDirectory(corruptDir); + } + + RvDir toSort = (RvDir)DB.DirTree.Child(1); + int indexcorrupt; + RvDir corruptDirNew = new RvDir(FileType.Dir) { Name = "Corrupt", DatStatus = DatStatus.InToSort }; + int found = toSort.ChildNameSearch(corruptDirNew, out indexcorrupt); + if (found != 0) + { + corruptDirNew.GotStatus = GotStatus.Got; + indexcorrupt = toSort.ChildAdd(corruptDirNew); + } + + string toSortFullName = Path.Combine(corruptDir, fixZip.Name + ".zip"); + string toSortFileName = fixZip.Name; + int fileC = 0; + while (File.Exists(toSortFullName)) + { + fileC++; + toSortFullName = Path.Combine(corruptDir, fixZip.Name + fileC + ".zip"); + toSortFileName = fixZip.Name + fileC; + } + + if (!File.SetAttributes(fixZipFullName, FileAttributes.Normal)) + { + int error = Error.GetLastError(); + ReportProgress(new bgwShowError(fixZipFullName, "Error Setting File Attributes to Normal. Before Moving To Corrupt. Code " + error)); + ReportError.SendErrorMessage("Error Setting File Attributes to Normal. Before Moving To Corrupt. Code " + error + " : " + fixZipFullName); + } + + + File.Copy(fixZipFullName, toSortFullName); + FileInfo toSortCorruptFile = new FileInfo(toSortFullName); + + RvDir toSortCorruptGame = new RvDir(FileType.Zip) + { + Name = toSortFileName, + DatStatus = DatStatus.InToSort, + TimeStamp = toSortCorruptFile.LastWriteTime, + GotStatus = GotStatus.Corrupt + }; + ((RvDir)toSort.Child(indexcorrupt)).ChildAdd(toSortCorruptGame); + + return ReturnCode.Good; + } + + private static void CheckCreateParent(RvBase parent) + { + if (parent == DB.DirTree) + return; + + string parentDir = parent.FullName; + if (Directory.Exists(parentDir) && parent.GotStatus == GotStatus.Got) return; + + CheckCreateParent(parent.Parent); + if (!Directory.Exists(parentDir)) + Directory.CreateDirectory(parentDir); + parent.GotStatus = GotStatus.Got; + } + + private static void CheckDeleteObject(RvBase tBase) + { + if (tBase.RepStatus == RepStatus.Deleted) + return; + + // look at the directories childrens status's to figure out if the directory should be deleted. + if (tBase.FileType == FileType.Dir) + { + RvDir tDir = tBase as RvDir; + if (tDir == null || tDir.ChildCount != 0) return; + // check if we are at the root of the tree so that we do not delete RomRoot and ToSort + if (tDir.Parent == DB.DirTree) return; + + string fullPath = tDir.FullName; + try + { + if (Directory.Exists(fullPath)) + Directory.Delete(fullPath); + } + catch (Exception e) + { + //need to report this to an error window + Debug.WriteLine(e.ToString()); + } + } + + // else check if this tBase should be removed from the DB + if (tBase.FileRemove() == EFile.Delete) + { + RvDir parent = tBase.Parent; + + if (parent == null) + { + ReportError.UnhandledExceptionHandler("Item being deleted had no parent " + tBase.FullName); + return; // this never happens as UnhandledException Terminates the program + } + + int index; + + if (!parent.FindChild(tBase, out index)) + { + ReportError.UnhandledExceptionHandler("Could not find self in delete code " + parent.FullName); + } + parent.ChildRemove(index); + CheckDeleteObject(parent); + } + } + + + + + private static List _checkList; + private static void CheckReprocessClearList() + { + _checkList = new List(); + } + private static void CheckReprocess(RvBase tCheck, bool fastProcess = false) + { + switch (tCheck.FileType) + { + case FileType.File: + if (tCheck.RepStatus == RepStatus.Delete && !_processList.Contains(tCheck)) + _processList.Add(tCheck); + break; + case FileType.ZipFile: + + RvDir p = tCheck.Parent; + if (fastProcess) + { + if (!_checkList.Contains(p)) + _checkList.Add(p); + break; + } + if (!_processList.Contains(p)) + { + bool hasdelete = false; + bool hasNeededForFix = false; + for (int i = 0; i < p.ChildCount; i++) + { + RvBase f = p.Child(i); + + if (f.RepStatus == RepStatus.Delete) + hasdelete = true; + else if (f.RepStatus == RepStatus.NeededForFix || f.RepStatus == RepStatus.Rename) + { + hasNeededForFix = true; + break; + } + } + if (hasdelete && !hasNeededForFix) + { + Debug.WriteLine(tCheck.Parent.FullName + " adding to process list."); + _processList.Add(p); + } + } + break; + default: + ReportError.SendAndShow("Unknow repair file type recheck."); + break; + + } + } + private static void CheckReprocessFinalCheck() + { + foreach (RvDir p in _checkList) + { + + if (_processList.Contains(p)) + continue; + bool hasdelete = false; + bool hasNeededForFix = false; + for (int i = 0; i < p.ChildCount; i++) + { + RvBase f = p.Child(i); + + if (f.RepStatus == RepStatus.Delete) + hasdelete = true; + else if (f.RepStatus == RepStatus.NeededForFix || f.RepStatus == RepStatus.Rename) + { + hasNeededForFix = true; + break; + } + } + if (!hasdelete || hasNeededForFix) continue; + + Debug.WriteLine(p.FullName + " adding to process list."); + _processList.Add(p); + } + } + } +} \ No newline at end of file diff --git a/ROMVault2/FrmProgressWindow.Designer.cs b/ROMVault2/FrmProgressWindow.Designer.cs new file mode 100644 index 0000000..56868a2 --- /dev/null +++ b/ROMVault2/FrmProgressWindow.Designer.cs @@ -0,0 +1,220 @@ +namespace ROMVault2 +{ + partial class FrmProgressWindow + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle1 = new System.Windows.Forms.DataGridViewCellStyle(); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FrmProgressWindow)); + this.progressBar2 = new System.Windows.Forms.ProgressBar(); + this.progressBar = new System.Windows.Forms.ProgressBar(); + this.label = new System.Windows.Forms.Label(); + this.cancelButton = new System.Windows.Forms.Button(); + this.label2 = new System.Windows.Forms.Label(); + this.lbl2Prog = new System.Windows.Forms.Label(); + this.ErrorGrid = new System.Windows.Forms.DataGridView(); + this.CError = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.CErrorFile = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.splitContainer1 = new System.Windows.Forms.SplitContainer(); + this.label3 = new System.Windows.Forms.Label(); + this.bgWork = new System.ComponentModel.BackgroundWorker(); + ((System.ComponentModel.ISupportInitialize)(this.ErrorGrid)).BeginInit(); + this.splitContainer1.Panel1.SuspendLayout(); + this.splitContainer1.Panel2.SuspendLayout(); + this.splitContainer1.SuspendLayout(); + this.SuspendLayout(); + // + // progressBar2 + // + this.progressBar2.Location = new System.Drawing.Point(12, 71); + this.progressBar2.Name = "progressBar2"; + this.progressBar2.Size = new System.Drawing.Size(400, 22); + this.progressBar2.TabIndex = 3; + this.progressBar2.Visible = false; + // + // progressBar + // + this.progressBar.Location = new System.Drawing.Point(12, 99); + this.progressBar.Name = "progressBar"; + this.progressBar.Size = new System.Drawing.Size(400, 23); + this.progressBar.TabIndex = 1; + // + // label + // + this.label.AutoEllipsis = true; + this.label.Location = new System.Drawing.Point(12, 9); + this.label.Name = "label"; + this.label.Size = new System.Drawing.Size(368, 15); + this.label.TabIndex = 0; + this.label.Text = "Starting operation..."; + // + // cancelButton + // + this.cancelButton.Location = new System.Drawing.Point(420, 99); + this.cancelButton.Name = "cancelButton"; + this.cancelButton.Size = new System.Drawing.Size(75, 23); + this.cancelButton.TabIndex = 2; + this.cancelButton.Text = "Cancel"; + this.cancelButton.Click += new System.EventHandler(this.CancelButtonClick); + // + // label2 + // + this.label2.AutoEllipsis = true; + this.label2.Location = new System.Drawing.Point(12, 34); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(480, 16); + this.label2.TabIndex = 4; + this.label2.Visible = false; + // + // lbl2Prog + // + this.lbl2Prog.Location = new System.Drawing.Point(386, 9); + this.lbl2Prog.Name = "lbl2Prog"; + this.lbl2Prog.Size = new System.Drawing.Size(109, 25); + this.lbl2Prog.TabIndex = 5; + this.lbl2Prog.TextAlign = System.Drawing.ContentAlignment.MiddleRight; + this.lbl2Prog.Visible = false; + // + // ErrorGrid + // + this.ErrorGrid.AllowUserToAddRows = false; + this.ErrorGrid.AllowUserToDeleteRows = false; + this.ErrorGrid.AllowUserToResizeRows = false; + this.ErrorGrid.AutoSizeRowsMode = System.Windows.Forms.DataGridViewAutoSizeRowsMode.AllCells; + this.ErrorGrid.BackgroundColor = System.Drawing.Color.White; + this.ErrorGrid.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; + this.ErrorGrid.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { + this.CError, + this.CErrorFile}); + this.ErrorGrid.Dock = System.Windows.Forms.DockStyle.Fill; + this.ErrorGrid.GridColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224))))); + this.ErrorGrid.Location = new System.Drawing.Point(0, 0); + this.ErrorGrid.MultiSelect = false; + this.ErrorGrid.Name = "ErrorGrid"; + this.ErrorGrid.ReadOnly = true; + this.ErrorGrid.RowHeadersVisible = false; + this.ErrorGrid.RowTemplate.Height = 17; + this.ErrorGrid.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect; + this.ErrorGrid.ShowCellErrors = false; + this.ErrorGrid.ShowCellToolTips = false; + this.ErrorGrid.ShowEditingIcon = false; + this.ErrorGrid.ShowRowErrors = false; + this.ErrorGrid.Size = new System.Drawing.Size(591, 186); + this.ErrorGrid.TabIndex = 6; + this.ErrorGrid.SelectionChanged += new System.EventHandler(this.ErrorGridSelectionChanged); + // + // CError + // + dataGridViewCellStyle1.WrapMode = System.Windows.Forms.DataGridViewTriState.True; + this.CError.DefaultCellStyle = dataGridViewCellStyle1; + this.CError.HeaderText = "Error"; + this.CError.Name = "CError"; + this.CError.ReadOnly = true; + this.CError.Width = 200; + // + // CErrorFile + // + this.CErrorFile.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill; + this.CErrorFile.HeaderText = "Error Filename"; + this.CErrorFile.Name = "CErrorFile"; + this.CErrorFile.ReadOnly = true; + // + // splitContainer1 + // + this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill; + this.splitContainer1.FixedPanel = System.Windows.Forms.FixedPanel.Panel1; + this.splitContainer1.IsSplitterFixed = true; + this.splitContainer1.Location = new System.Drawing.Point(0, 0); + this.splitContainer1.Name = "splitContainer1"; + this.splitContainer1.Orientation = System.Windows.Forms.Orientation.Horizontal; + // + // splitContainer1.Panel1 + // + this.splitContainer1.Panel1.Controls.Add(this.label3); + this.splitContainer1.Panel1.Controls.Add(this.progressBar2); + this.splitContainer1.Panel1.Controls.Add(this.label); + this.splitContainer1.Panel1.Controls.Add(this.progressBar); + this.splitContainer1.Panel1.Controls.Add(this.lbl2Prog); + this.splitContainer1.Panel1.Controls.Add(this.label2); + this.splitContainer1.Panel1.Controls.Add(this.cancelButton); + // + // splitContainer1.Panel2 + // + this.splitContainer1.Panel2.Controls.Add(this.ErrorGrid); + this.splitContainer1.Size = new System.Drawing.Size(591, 320); + this.splitContainer1.SplitterDistance = 130; + this.splitContainer1.TabIndex = 8; + // + // label3 + // + this.label3.AutoEllipsis = true; + this.label3.Location = new System.Drawing.Point(12, 50); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(480, 16); + this.label3.TabIndex = 6; + // + // bgWork + // + this.bgWork.WorkerReportsProgress = true; + this.bgWork.WorkerSupportsCancellation = true; + // + // FrmProgressWindow + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(591, 320); + this.Controls.Add(this.splitContainer1); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Name = "FrmProgressWindow"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "RomVault Progress"; + this.Shown += new System.EventHandler(this.FrmProgressWindowNewShown); + this.Resize += new System.EventHandler(this.FrmProgressWindow_Resize); + ((System.ComponentModel.ISupportInitialize)(this.ErrorGrid)).EndInit(); + this.splitContainer1.Panel1.ResumeLayout(false); + this.splitContainer1.Panel2.ResumeLayout(false); + this.splitContainer1.ResumeLayout(false); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.ProgressBar progressBar2; + private System.Windows.Forms.ProgressBar progressBar; + private System.Windows.Forms.Label label; + private System.Windows.Forms.Button cancelButton; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.Label lbl2Prog; + private System.Windows.Forms.DataGridView ErrorGrid; + private System.Windows.Forms.SplitContainer splitContainer1; + private System.ComponentModel.BackgroundWorker bgWork; + private System.Windows.Forms.DataGridViewTextBoxColumn CError; + private System.Windows.Forms.DataGridViewTextBoxColumn CErrorFile; + private System.Windows.Forms.Label label3; + } +} \ No newline at end of file diff --git a/ROMVault2/FrmProgressWindow.cs b/ROMVault2/FrmProgressWindow.cs new file mode 100644 index 0000000..648712d --- /dev/null +++ b/ROMVault2/FrmProgressWindow.cs @@ -0,0 +1,241 @@ +/****************************************************** + * ROMVault2 is written by Gordon J. * + * Contact gordon@romvault.com * + * Copyright 2014 * + ******************************************************/ + +using System; +using System.ComponentModel; +using System.Drawing; +using System.Threading; +using System.Windows.Forms; +using ROMVault2.Properties; + +namespace ROMVault2 +{ + public partial class FrmProgressWindow : Form + { + private readonly string _titleRoot; + private bool _errorOpen; + private bool _bDone; + private Form _parentForm; + + public FrmProgressWindow(Form parentForm, string titleRoot, DoWorkEventHandler function) + { + _parentForm = parentForm; + _titleRoot = titleRoot; + InitializeComponent(); + + ClientSize = new Size(498, 131); + + _titleRoot = titleRoot; + + bgWork.DoWork += function; + } + + protected override CreateParams CreateParams + { + get + { + const int CP_NOCLOSE_BUTTON = 0x200; + CreateParams mdiCp = base.CreateParams; + mdiCp.ClassStyle = mdiCp.ClassStyle | CP_NOCLOSE_BUTTON; + return mdiCp; + } + } + + + + private void FrmProgressWindowNewShown(object sender, EventArgs e) + { + bgWork.ProgressChanged += BgwProgressChanged; + bgWork.RunWorkerCompleted += BgwRunWorkerCompleted; + bgWork.RunWorkerAsync(SynchronizationContext.Current); + } + + private void BgwProgressChanged(object sender, ProgressChangedEventArgs e) + { + if (e.UserState == null) + { + if (e.ProgressPercentage >= progressBar.Minimum && e.ProgressPercentage <= progressBar.Maximum) + progressBar.Value = e.ProgressPercentage; + UpdateStatusText(); + return; + } + + bgwText bgwT = e.UserState as bgwText; + if (bgwT != null) + { + label.Text = bgwT.Text; + return; + } + bgwSetRange bgwSR = e.UserState as bgwSetRange; + if (bgwSR != null) + { + progressBar.Minimum = 0; + progressBar.Maximum = bgwSR.MaxVal >= 0 ? bgwSR.MaxVal : 0; + progressBar.Value = 0; + UpdateStatusText(); + return; + } + + + bgwText2 bgwT2 = e.UserState as bgwText2; + if (bgwT2 != null) + { + label2.Text = bgwT2.Text; + return; + } + + bgwValue2 bgwV2 = e.UserState as bgwValue2; + if (bgwV2 != null) + { + if (bgwV2.Value >= progressBar2.Minimum && bgwV2.Value <= progressBar2.Maximum) + progressBar2.Value = bgwV2.Value; + UpdateStatusText2(); + return; + } + + bgwSetRange2 bgwSR2 = e.UserState as bgwSetRange2; + if (bgwSR2 != null) + { + progressBar2.Minimum = 0; + progressBar2.Maximum = bgwSR2.MaxVal >= 0 ? bgwSR2.MaxVal : 0; + progressBar2.Value = 0; + UpdateStatusText2(); + return; + } + bgwRange2Visible bgwR2V = e.UserState as bgwRange2Visible; + if (bgwR2V != null) + { + label2.Visible = bgwR2V.Visible; + progressBar2.Visible = bgwR2V.Visible; + lbl2Prog.Visible = bgwR2V.Visible; + return; + } + + + bgwText3 bgwT3 = e.UserState as bgwText3; + if (bgwT3 != null) + { + label3.Text = bgwT3.Text; + return; + } + + bgwShowCorrupt bgwSC = e.UserState as bgwShowCorrupt; + if (bgwSC != null) + { + if (!_errorOpen) + { + _errorOpen = true; + ClientSize = new Size(498, 292); + MinimumSize = new Size(498, 292); + FormBorderStyle = FormBorderStyle.SizableToolWindow; + } + + ErrorGrid.Rows.Add(); + int row = ErrorGrid.Rows.Count - 1; + + ErrorGrid.Rows[row].Cells["CError"].Value = bgwSC.zr; + ErrorGrid.Rows[row].Cells["CError"].Style.ForeColor = Color.FromArgb(255, 0, 0); + + ErrorGrid.Rows[row].Cells["CErrorFile"].Value = bgwSC.filename; + ErrorGrid.Rows[row].Cells["CErrorFile"].Style.ForeColor = Color.FromArgb(255, 0, 0); + + if (row >= 0) ErrorGrid.FirstDisplayedScrollingRowIndex = row; + } + + + + bgwShowError bgwSDE = e.UserState as bgwShowError; + if (bgwSDE != null) + { + if (!_errorOpen) + { + _errorOpen = true; + ClientSize = new Size(498, 292); + MinimumSize = new Size(498, 292); + FormBorderStyle = FormBorderStyle.SizableToolWindow; + } + + ErrorGrid.Rows.Add(); + int row = ErrorGrid.Rows.Count - 1; + + ErrorGrid.Rows[row].Cells["CError"].Value = bgwSDE.error; + ErrorGrid.Rows[row].Cells["CError"].Style.ForeColor = Color.FromArgb(255, 0, 0); + + ErrorGrid.Rows[row].Cells["CErrorFile"].Value = bgwSDE.filename; + ErrorGrid.Rows[row].Cells["CErrorFile"].Style.ForeColor = Color.FromArgb(255, 0, 0); + + if (row >= 0) ErrorGrid.FirstDisplayedScrollingRowIndex = row; + + } + + + + } + private void UpdateStatusText() + { + int range = progressBar.Maximum - progressBar.Minimum; + int percent = range > 0 ? (progressBar.Value * 100) / range : 0; + + Text = _titleRoot + String.Format(" - {0}% complete", percent); + } + private void UpdateStatusText2() + { + lbl2Prog.Text = progressBar2.Maximum > 0 ? string.Format("{0}/{1}", progressBar2.Value, progressBar2.Maximum) : ""; + } + + private void BgwRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) + { + if (_errorOpen) + { + cancelButton.Text = Resources.ProgressWindowFix_DoDone_Close; + cancelButton.Enabled = true; + _bDone = true; + } + else + { + _parentForm.Show(); + Close(); + } + } + + private void CancelButtonClick(object sender, EventArgs e) + { + if (_bDone) + { + if (!_parentForm.Visible) _parentForm.Show(); + Close(); + } + else + { + cancelButton.Text = Resources.ProgressWindowFix_OnClosing_Cancelling; + cancelButton.Enabled = false; + bgWork.CancelAsync(); + } + } + + private void ErrorGridSelectionChanged(object sender, EventArgs e) + { + ErrorGrid.ClearSelection(); + } + + private void FrmProgressWindow_Resize(object sender, EventArgs e) + { + switch (WindowState) + { + case FormWindowState.Minimized: + if (_parentForm.Visible) _parentForm.Hide(); + return; + case FormWindowState.Maximized: + if (!_parentForm.Visible) _parentForm.Show(); + return; + case FormWindowState.Normal: + if (!_parentForm.Visible) _parentForm.Show(); + return; + } + } + + } +} diff --git a/ROMVault2/FrmProgressWindow.resx b/ROMVault2/FrmProgressWindow.resx new file mode 100644 index 0000000..f39702e --- /dev/null +++ b/ROMVault2/FrmProgressWindow.resx @@ -0,0 +1,1799 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + True + + + True + + + True + + + 17, 17 + + + + + AAABAAUAEBAAAAAAIABoBAAAVgAAACAgAAAAACAAqBAAAL4EAAAwMAAAAAAgAKglAABmFQAAQEAAAAAA + IAAoQgAADjsAAICAAAAAACAAKAgBADZ9AAAoAAAAEAAAACAAAAABACAAAAAAAEAEAAAAAAAAAAAAAAAA + AAAAAAAA7e3tvevr6//m5ub/4ODg/9nZ2f/Q0ND/wsLC/66urv+ampr/nJyc/6Kiov+tra3/ubm5/8XF + xf/R0dH/2trapenp6b3l5eX/3t7e/9bW1v/Kysr/ubm5/5+fn/92dnb/ampq/21tbf97e3v/jIyM/56e + nv+wsLD/wsLC/8/Pz6Xl5eW939/f/9bW1v/Jycn/uLi4/5ycnP9ubm7/YWFh/2pqav8tLS3/RERE/2lp + af+AgID/mJiY/7Kysv/FxcWl39/fvdjY2P/Ly8v/ubm5/56env9ycnL/VlZW/2RkZP92dnb/IyMj/yAg + IP8qKir/VlZW/319ff+ioqL/v7+/pdnZ2b3Nzc3/u7u7/6Kiov94eHj/U1NT/15eXv99fX3/IiIi/yYm + Jv8lJSX/IyMj/yAgIP8+Pj7/hoaG/76+vqXQ0NC9wMDA/6ampv+AgID/U1NT/1tbW/+BgYH/ISEh/yUl + Jf8lJSX/JiYm/yYmJv8lJSX/IiIi/2BgYP/Dw8OlxsbGva6urv+Hh4f/VlZW/1paWv+BgYH/JCQk/yUl + Jf8kJCT/JSUl/yUlJf8mJib/JiYm/yQkJP91dXX/zc3Npby8vL2Wlpb/XV1d/1tbW/+AgID/JiYm/zs7 + O/9ubm7/YWFh/ykpKf8kJCT/JSUl/yUlJf9ZWVn/xcXF/9XV1aW4uLi9dXV1/2JiYv9/f3//Kysr/0BA + QP/FxcX/zMzM/8vLy/+hoaH/JCQk/yQkJP9NTU3/v7+//9LS0v/c3NylvLy8vXJycv9/f3//NjY2/yMj + I/9lZWX/zc3N/83Nzf/MzMz/ycnJ/ykpKf9DQ0P/uLi4/9DQ0P/c3Nz/4+PjpcDAwL1/f3//QkJC/yQi + Iv8jIyP/Li4u/6ioqP/MzMz/ysrK/3h4eP88PDz/s7Oz/8/Pz//b29v/4+Pj/+jo6KXR0dG9bm5u/yQi + Iv9hJRr/SCQd/0QkHv8yJCH/Ozs7/zExMf82Njb/r6+v/9HR0f/b29v/4+Pj/+jo6P/s7Oyl29vbvX9/ + f/8lJSX/PiMe/1okGv9dJBr/VSQc/zokIP8yMjL/rq6u/9XV1f/e3t7/5OTk/+np6f/t7e3/8PDwpeXl + 5b3f39//t7e3/2tra/8lJSX/RyMd/1QlHP8vLi7/ra2t/93d3f/j4+P/6Ojo/+vr6//u7u7/8fHx//Pz + 86Xs7Oy96enp/+bm5v/i4uL/n5+f/zY2Nv9JSUn/q6ur/+bm5v/p6en/7Ozs/+7u7v/w8PD/8vLy//T0 + 9P/19fWl8fHxvfDw8P/u7u7/7Ozs/+rq6v/g4OD/39/f/+zs7P/u7u7/7+/v//Hx8f/y8vL/9PT0//X1 + 9f/29vb/9/f3pQAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA + //8AAP//AAD//wAA//8oAAAAIAAAAEAAAAABACAAAAAAAIAQAAAAAAAAAAAAAAAAAAAAAAAA7+/vee7u + 7v/t7e3/6+vr/+np6f/n5+f/5OTk/+Hh4f/e3t7/29vb/9fX1//T09P/zc3N/8XFxf++vr7/uLi4/7Cw + sP+rq6v/qKio/6ioqP+rq6v/rq6u/7Kysv+4uLj/vb29/8LCwv/Hx8f/zMzM/9HR0f/X19f/3Nzc/9/f + 303t7e157Ozs/+rq6v/o6Oj/5ubm/+Pj4//g4OD/3Nzc/9jY2P/U1NT/z8/P/8jIyP/AwMD/tra2/6qq + qv+YmJj/goKC/42Njf+NjY3/kZGR/5aWlv+bm5v/oqKi/6qqqv+wsLD/tra2/729vf/Dw8P/ysrK/9HR + 0f/X19f/29vbTevr63nq6ur/6Ojo/+Xl5f/i4uL/3t7e/9vb2//W1tb/0tLS/8zMzP/ExMT/u7u7/7Gx + sf+jo6P/kJCQ/3Z2dv9mZmb/c3Nz/3R0dP96enr/gICA/4iIiP+RkZH/mZmZ/6Ghof+pqan/sbGx/7m5 + uf/CwsL/ysrK/9HR0f/W1tZN6enpeefn5//l5eX/4uLi/97e3v/a2tr/1dXV/9DQ0P/Kysr/wsLC/7m5 + uf+tra3/n5+f/4mJif9ra2v/aWlp/29vb/9hYWH/YWFh/2dnZ/9tbW3/dXV1/35+fv+IiIj/kpKS/5yc + nP+lpaX/r6+v/7m5uf/CwsL/y8vL/9HR0U3n5+d55eXl/+Li4v/f39//29vb/9bW1v/Q0ND/ycnJ/8LC + wv+4uLj/ra2t/52dnf+IiIj/a2tr/0tLS/9oaGj/enp6/1hYWP9ERET/Ly8v/1NTU/9kZGT/bW1t/3d3 + d/+CgoL/jY2N/5iYmP+kpKT/sLCw/7u7u//Gxsb/zMzMTeXl5Xnj4+P/39/f/9vb2//X19f/0dHR/8rK + yv/BwcH/uLi4/62trf+enp7/iYmJ/2tra/9bW1v/WFhY/3h4eP91dXX/X19f/yAgIP8iIiL/Hx8f/zk5 + Of9aWlr/Z2dn/3Jycv9+fn7/i4uL/5mZmf+np6f/tbW1/8HBwf/JyclN4uLieeDg4P/c3Nz/2NjY/9LS + 0v/Kysr/wsLC/7i4uP+tra3/n5+f/4uLi/9tbW3/Q0ND/11dXf9dXV3/aWlp/5WVlf+QkJD/IiIi/yEh + If8eHh7/Hh4e/yQkJP9HR0f/YmJi/29vb/99fX3/jIyM/52dnf+vr6//vr6+/8fHx03g4OB53d3d/9jY + 2P/T09P/zMzM/8PDw/+5ubn/rq6u/6CgoP+MjIz/cnJy/19fX/9NTU3/ampq/3d3d/9TU1P/jo6O/yYm + Jv8jIyP/JiYm/yQkJP8hISH/Hh4e/x4eHv8wMDD/WFhY/21tbf99fX3/kpKS/6mpqf+8vLz/xsbGTd7e + 3nna2tr/1NTU/83Nzf/ExMT/u7u7/6+vr/+hoaH/j4+P/3V1df9HR0f/Wlpa/1ZWVv9paWn/fn5+/5ub + m/8dHR3/IyMj/yYmJv8mJib/JiYm/yUlJf8jIyP/Hx8f/x4eHv8hISH/QEBA/2xsbP+IiIj/o6Oj/7u7 + u//Hx8dN2traedXV1f/Ozs7/xsbG/7y8vP+xsbH/pKSk/5KSkv97e3v/ZGRk/0pKSv9gYGD/dXV1/0JC + Qv+qqqr/MjIy/yMjI/8mJib/JiYm/yYmJv8mJib/JiYm/yUlJf8lJSX/ISEh/x8fH/8fHx//LS0t/1JS + Uv+cnJz/u7u7/8fHx03W1tZ50dHR/8nJyf+/v7//s7Oz/6ampv+UlJT/fX19/01NTf9ZWVn/WFhY/2ho + aP9ubm7/mJiY/xsbG/8hISH/JSUl/yUlJf8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8lJSX/JCQk/yEh + If8gICD/KSkp/5ycnP++vr7/ycnJTdLS0nnMzMz/wsLC/7a2tv+pqan/l5eX/4KCgv9sbGz/SkpK/1tb + W/91dXX/Nzc3/7W1tf9HR0f/IiIi/yQkJP8lJSX/JSUl/yUlJf8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JSUl/yMjI/8jIyP/mJiY/8XFxf/MzMxNzs7OecfHx/+7u7v/ra2t/5ubm/+Ghob/WVlZ/1lZ + Wf9dXV3/ZWVl/2hoaP+Kior/KSkp/yEhIf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JSUl/zIyMv+goKD/ysrK/9DQ0E3Kysp5wcHB/7Kysv+goKD/ioqK/3Jy + cv9PT0//V1dX/3V1df8zMzP/q6ur/2ZmZv8gICD/JCQk/yUlJf8lJSX/JCQk/yQkJP8kJCT/JSUl/yUl + Jf8lJSX/JiYm/yYmJv8mJib/JiYm/yYmJv8hISH/Q0ND/76+vv/Nzc3/09PTTcXFxXm7u7v/qKio/5GR + kf9mZmb/Xl5e/2JiYv9eXl7/bGxs/3d3d/82Njb/Hx8f/yQkJP8kJCT/JSUl/ycnJ/8lJSX/JCQk/yQk + JP8kJCT/JSUl/yUlJf8lJSX/JSUl/yYmJv8mJib/Kioq/1hYWP+3t7f/ycnJ/9HR0f/X19dNwsLCebW1 + tf+enp7/gYGB/1hYWP9WVlb/dXV1/zg4OP+UlJT/ioqK/x8fH/8kJCT/LCws/3l5ef+tra3/v7+//7S0 + tP+IiIj/OTk5/yQkJP8kJCT/JCQk/yUlJf8lJSX/JSUl/yQkJP8xMTH/sbGx/8bGxv/Ozs7/1tbW/9ra + 2k3BwcF5srKy/4iIiP9xcXH/bGxs/1tbW/92dnb/YWFh/05OTv8eHh7/IyMj/zMzM/+wsLD/zMzM/8vL + y//Ly8v/zMzM/8vLy//BwcH/SkpK/yMjI/8kJCT/JCQk/yUlJf8oKCj/QkJC/6qqqv/ExMT/zMzM/9PT + 0//Z2dn/3d3dTcLCwnm0tLT/enp6/2FhYf97e3v/SEhI/319ff+np6f/ISEh/yEhIf8jIyP/iIiI/8zM + zP/MzMz/zc3N/83Nzf/MzMz/y8vL/8rKyv+vr6//JSUl/yQkJP8kJCT/IyMj/yUlJf+lpaX/w8PD/8vL + y//R0dH/19fX/93d3f/g4OBNw8PDebm5uf+JiYn/Y2Nj/4GBgf9WVlb/Y2Nj/ykpKf8hISH/IyMj/yQk + JP+wsLD/zc3N/83Nzf/Nzc3/zc3N/8zMzP/Ly8v/y8vL/8zMzP8zMzP/JCQk/yUlJf8zMzP/lpaW/8HB + wf/Kysr/0dHR/9fX1//c3Nz/4ODg/+Pj403FxcV5tra2/4aGhv9WVlb/bm5u/7i4uP8rKyv/ISEh/yQk + JP8kJCT/JCQk/52dnf/Nzc3/zc3N/83Nzf/Nzc3/zMzM/8zMzP/Ly8v/wcHB/yoqKv8jIyP/ICAg/5aW + lv/AwMD/ycnJ/9DQ0P/X19f/3Nzc/+Dg4P/k5OT/5ubmTcnJyXm2trb/jY2N/1JSUv9zc3P/PDw8/yEh + If8jIyP/IyMj/yMjI/8kJCT/T09P/8nJyf/Nzc3/zc3N/83Nzf/Nzc3/zMzM/8vLy/95eXn/JCQk/ygo + KP+Dg4P/wMDA/8jIyP/Q0ND/1tbW/9vb2//g4OD/4+Pj/+bm5v/o6OhNzc3NecDAwP9nZ2f/tLS0/zw8 + PP8eHh7/IiIi/ysiIf8iIiL/IyMj/yMjI/8jIyP/VlZW/7e3t//MzMz/zc3N/8zMzP/ExMT/d3d3/yYm + Jv8dHR3/h4eH/8HBwf/Jycn/0NDQ/9bW1v/b29v/39/f/+Pj4//m5ub/6enp/+vr603S0tJ5zMzM/6mp + qf9VVVX/ICAg/yMjI/84Ix//ayYa/yIiIf8qIiH/NCMg/zQjIP8jIyP/JiYm/0hISP9dXV3/UVFR/y0t + Lf8jIyP/IiIi/2tra//BwcH/ysrK/9HR0f/W1tb/29vb/9/f3//j4+P/5ubm/+np6f/r6+v/7e3tTdfX + 13nS0tL/kpKS/ygoKP8jIyP/KyIg/3omF/9mJRn/cyYY/14lGv9TJRz/UyUc/1ckG/8oIyH/IyMj/yMj + I/8jIyP/IyMj/x0dHf93d3f/xMTE/8vLy//S0tL/19fX/9vb2//f39//4+Pj/+bm5v/o6Oj/6+vr/+3t + 7f/u7u5N29vbedfX1/+FhYX/IyMj/yMjI/8jISH/TyQc/2QkGP9yJhj/WyQa/2slGf86Ix7/XCUb/2Ml + G/8+Ix//JSMi/yMjI/8hISH/VVVV/8bGxv/Ozs7/1NTU/9nZ2f/d3d3/4ODg/+Pj4//m5ub/6Ojo/+vr + 6//t7e3/7+/v//Dw8E3g4OB53d3d/9PT0/9/f3//LCws/yIiIv8hISH/ISEh/0UjHf9XIxr/bCUY/2El + Gv8/Ix7/VSQc/10mG/8nIyL/Hx8f/2VlZf/Kysr/09PT/9fX1//b29v/39/f/+Li4v/l5eX/5+fn/+np + 6f/r6+v/7e3t/+/v7//w8PD/8fHxTeTk5Hni4uL/3t7e/9vb2//Dw8P/YGBg/yQkJP8iIiL/ISEh/yEh + If9fJRr/ZSUZ/1IkHP9eJRv/JSMi/yIiIv9AQED/ysrK/9jY2P/b29v/39/f/+Li4v/l5eX/5+fn/+np + 6f/q6ur/7Ozs/+7u7v/v7+//8fHx//Ly8v/z8/NN6Ojoeebm5v/k5OT/4eHh/9/f3//c3Nz/v7+//6io + qP8vLy//IiIi/yEhIf81IyD/ZiYa/zskIP8gICD/VFRU/83Nzf/d3d3/4ODg/+Pj4//l5eX/5+fn/+np + 6f/r6+v/7Ozs/+3t7f/v7+//8PDw//Hx8f/y8vL/8/Pz//T09E3s7Ox56+vr/+np6f/n5+f/5OTk/+Li + 4v/h4eH/39/f/5aWlv8wMDD/IiIi/yIiIv8jIyP/IiIi/ywsLP/Gxsb/4uLi/+Tk5P/m5ub/6Ojo/+np + 6f/r6+v/7Ozs/+7u7v/v7+//8PDw//Hx8f/y8vL/8/Pz//Pz8//09PT/9fX1Te7u7nnt7e3/7Ozs/+vr + 6//p6en/6Ojo/+bm5v/k5OT/4+Pj/9PT0/9vb2//JiYm/y0tLf+ysrL/1NTU/+bm5v/n5+f/6enp/+rq + 6v/s7Oz/7e3t/+7u7v/v7+//8PDw//Hx8f/y8vL/8vLy//Pz8//09PT/9fX1//X19f/29vZN8fHxefDw + 8P/v7+//7u7u/+3t7f/s7Oz/6urq/+np6f/o6Oj/6Ojo/+jo6P++vr7/urq6/+np6f/q6ur/6+vr/+vr + 6//t7e3/7u7u/+/v7//v7+//8PDw//Hx8f/y8vL/8/Pz//Pz8//09PT/9PT0//X19f/29vb/9vb2//f3 + 903z8/N58vLy//Hx8f/w8PD/8PDw/+/v7//u7u7/7e3t/+3t7f/s7Oz/7e3t/+3t7f/t7e3/7e3t/+3t + 7f/u7u7/7+/v//Dw8P/w8PD/8fHx//Ly8v/y8vL/8/Pz//T09P/09PT/9fX1//X19f/29vb/9vb2//f3 + 9//39/f/9/f3TQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAKAAAADAAAABgAAAAAQAgAAAAAACAJQAAAAAAAAAAAAAAAAAAAAAAAPDw + 8Dfv7+//7u7u/+3t7f/s7Oz/6+vr/+rq6v/p6en/5+fn/+Xl5f/j4+P/4eHh/9/f3//d3d3/29vb/9nZ + 2f/X19f/1NTU/9DQ0P/Ly8v/x8fH/8LCwv++vr7/urq6/7a2tv+xsbH/rq6u/62trf+srKz/rKys/62t + rf+vr6//sbGx/7S0tP+3t7f/u7u7/76+vv/BwcH/xcXF/8jIyP/Ly8v/z8/P/9LS0v/V1dX/2NjY/9zc + 3P/f39/x////Ae7u7jfu7u7/7e3t/+zs7P/r6+v/6enp/+jo6P/m5ub/5eXl/+Pj4//g4OD/3t7e/9zc + 3P/Z2dn/19fX/9TU1P/R0dH/zc3N/8jIyP/CwsL/vLy8/7e3t/+xsbH/qqqq/6Ojo/+enp7/nJyc/5ub + m/+cnJz/np6e/6CgoP+jo6P/pqam/6qqqv+urq7/srKy/7a2tv+6urr/vr6+/8HBwf/FxcX/ycnJ/83N + zf/R0dH/1dXV/9nZ2f/c3Nzx////Ae3t7Tfs7Oz/6+vr/+rq6v/p6en/6Ojo/+bm5v/k5OT/4uLi/+Dg + 4P/d3d3/29vb/9jY2P/V1dX/0tLS/87Ozv/Kysr/xMTE/7+/v/+5ubn/sbGx/6ioqP+fn5//ioqK/21t + bf+Ghob/iIiI/4iIiP+Li4v/jo6O/5GRkf+VlZX/mZmZ/56env+kpKT/qKio/62trf+xsbH/tbW1/7q6 + uv++vr7/w8PD/8jIyP/MzMz/0dHR/9XV1f/Z2dnx////Aezs7Dfr6+v/6urq/+jo6P/n5+f/5eXl/+Pj + 4//h4eH/39/f/9zc3P/Z2dn/19fX/9TU1P/Q0ND/zMzM/8fHx//CwsL/vLy8/7a2tv+urq7/pKSk/5iY + mP+MjIz/cHBw/2JiYv9zc3P/dnZ2/3d3d/96enr/fn5+/4ODg/+Hh4f/jIyM/5KSkv+YmJj/nZ2d/6Oj + o/+oqKj/ra2t/7Kysv+3t7f/vb29/8LCwv/Hx8f/zMzM/9HR0f/W1tbx////Aerq6jfp6en/6Ojo/+fn + 5//l5eX/4+Pj/+Hh4f/e3t7/3Nzc/9nZ2f/W1tb/09PT/8/Pz//Ly8v/xsbG/8DAwP+6urr/s7Oz/6ur + q/+hoaH/lJSU/4WFhf94eHj/ampq/2hoaP9oaGj/ZmZm/2hoaP9tbW3/cXFx/3V1df96enr/f39//4aG + hv+MjIz/kpKS/5iYmP+enp7/pKSk/6qqqv+wsLD/tra2/7y8vP/CwsL/x8fH/83Nzf/S0tLx////Aenp + 6Tfo6Oj/5ubm/+Xl5f/j4+P/4eHh/9/f3//c3Nz/2dnZ/9bW1v/S0tL/zs7O/8rKyv/FxcX/v7+//7i4 + uP+xsbH/qamp/5+fn/+RkZH/f39//2BgYP9nZ2f/aGho/29vb/9vb2//W1tb/11dXf9hYWH/ZWVl/2lp + af9ubm7/c3Nz/3p6ev+AgID/h4eH/42Njf+UlJT/m5ub/6Ghof+oqKj/r6+v/7W1tf+8vLz/wsLC/8nJ + yf/Ozs7x////Aejo6Dfn5+f/5eXl/+Pj4//h4eH/39/f/9zc3P/Z2dn/1tbW/9LS0v/Ozs7/ycnJ/8TE + xP+/v7//uLi4/7Gxsf+oqKj/nZ2d/5CQkP+AgID/ZmZm/0pKSv9XV1f/a2tr/3R0dP9xcXH/UlJS/1NT + U/84ODj/PT09/1tbW/9jY2P/aGho/25ubv91dXX/fHx8/4ODg/+Kior/kZGR/5mZmf+goKD/qKio/6+v + r/+3t7f/vr6+/8XFxf/Ly8vx////Aefn5zfm5ub/4+Pj/+Hh4f/f39//3Nzc/9ra2v/W1tb/09PT/87O + zv/Jycn/xMTE/76+vv+4uLj/sLCw/6ioqP+enp7/kJCQ/4GBgf9vb2//Xl5e/01NTf9VVVX/cXFx/42N + jf9xcXH/S0tL/zExMf8gICD/Hh4e/ygoKP9JSUn/XV1d/2NjY/9paWn/cXFx/3h4eP+AgID/iIiI/5CQ + kP+YmJj/oKCg/6mpqf+ysrL/urq6/8LCwv/Jycnx////AeXl5Tfk5OT/4uLi/9/f3//d3d3/2tra/9fX + 1//T09P/z8/P/8rKyv/FxcX/v7+//7i4uP+xsbH/qKio/5+fn/+RkZH/gYGB/2ZmZv9eXl7/WVlZ/2Nj + Y/9aWlr/i4uL/2tra/93d3f/VFRU/x0dHf8kJCT/Hh4e/x4eHv8eHh7/MjIy/1JSUv9eXl7/ZmZm/25u + bv91dXX/fn5+/4eHh/+QkJD/mZmZ/6Ojo/+tra3/tra2/7+/v//Gxsbx////AePj4zfi4uL/4ODg/93d + 3f/b29v/2NjY/9TU1P/Pz8//ysrK/8XFxf+/v7//uLi4/7Gxsf+pqan/n5+f/5OTk/+CgoL/ampq/0ZG + Rv9ISEj/YWFh/2VlZf9dXV3/cHBw/3Jycv/CwsL/jIyM/yQkJP8fHx//Hx8f/x4eHv8eHh7/HR0d/yEh + If8+Pj7/Wlpa/2NjY/9ra2v/dHR0/319ff+Hh4f/kZGR/5ycnP+np6f/s7Oz/7y8vP/FxcXx////AeLi + 4jfg4OD/3t7e/9vb2//Y2Nj/1dXV/9HR0f/Ly8v/xsbG/8DAwP+5ubn/srKy/6mpqf+fn5//kpKS/4SE + hP9zc3P/YWFh/0RERP9FRUX/ampq/3x8fP9WVlb/Xl5e/7e3t/+zs7P/KCgo/yIiIv8kJCT/JiYm/yIi + Iv8fHx//Hh4e/x4eHv8eHh7/KSkp/0xMTP9hYWH/ampq/3Nzc/99fX3/iIiI/5SUlP+ioqL/r6+v/7u7 + u//ExMTx////AeDg4Dff39//3Nzc/9nZ2f/V1dX/0dHR/8zMzP/Hx8f/wcHB/7q6uv+ysrL/qqqq/6Gh + of+Tk5P/hISE/3BwcP9lZWX/W1tb/15eXv9GRkb/fHx8/39/f/9hYWH/RERE/4iIiP8uLi7/IiIi/yMj + I/8lJSX/JiYm/yUlJf8kJCT/ISEh/x8fH/8eHh7/Hh4e/x8fH/83Nzf/Wlpa/2dnZ/9xcXH/fX19/42N + jf+cnJz/q6ur/7m5uf/ExMTx////Ad/f3zfd3d3/2tra/9bW1v/R0dH/zc3N/8fHx//BwcH/u7u7/7Oz + s/+rq6v/oaGh/5aWlv+Hh4f/c3Nz/0pKSv9LS0v/XFxc/2ZmZv9GRkb/hISE/2JiYv+dnZ3/mpqa/xwc + HP8cHBz/IyMj/yYmJv8mJib/JSUl/yYmJv8mJib/JSUl/yMjI/8fHx//Hx8f/x4eHv8eHh7/JSUl/0VF + Rf9jY2P/dHR0/4aGhv+YmJj/qamp/7i4uP/ExMTx////Ad3d3Tfb29v/19fX/9LS0v/Ozs7/yMjI/8LC + wv+8vLz/tLS0/6ysrP+jo6P/l5eX/4mJif94eHj/ZmZm/0hISP9DQ0P/ZWVl/3Jycv89PT3/V1dX/5aW + lv/a2tr/Pj4+/yIiIv8kJCT/JiYm/yYmJv8lJSX/JSUl/yYmJv8lJSX/JiYm/yUlJf8kJCT/ISEh/x8f + H/8fHx//Hx8f/x8fH/8xMTH/YWFh/3BwcP+Li4v/paWl/7e3t//ExMTx////Advb2zfY2Nj/1NTU/8/P + z//Jycn/xMTE/729vf+1tbX/ra2t/6SkpP+ZmZn/jIyM/3t7e/9ra2v/X19f/1ZWVv9CQkL/cHBw/42N + jf9OTk7/ODg4/7S0tP9JSUn/IyMj/yIiIv8mJib/JiYm/yYmJv8lJSX/JiYm/yYmJv8mJib/JiYm/yYm + Jv8lJSX/JSUl/yMjI/8gICD/Hx8f/yAgIP8gICD/IiIi/zk5Of91dXX/paWl/7e3t//FxcXx////AdjY + 2DfV1dX/0NDQ/8vLy//FxcX/v7+//7e3t/+vr6//paWl/5ubm/+NjY3/fX19/1RUVP9OTk7/W1tb/2Rk + ZP8/Pz//i4uL/1xcXP+FhYX/h4eH/xsbG/8eHh7/ISEh/yUlJf8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8lJSX/IiIi/yAgIP8gICD/ICAg/yAgIP9jY2P/pqam/7q6 + uv/Gxsbx////AdXV1TfT09P/zc3N/8fHx//AwMD/ubm5/7CwsP+np6f/nJyc/4+Pj/+AgID/b29v/01N + Tf9AQED/YWFh/2xsbP83Nzf/VlZW/319ff/Y2Nj/aWlp/yEhIf8fHx//JCQk/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yYmJv8lJSX/JiYm/yUlJf8lJSX/JiYm/yUlJf8lJSX/JSUl/yUlJf8gICD/ICAg/yAg + IP9YWFj/paWl/7+/v//IyMjx////AdPT0zfQ0ND/ysrK/8PDw/+7u7v/srKy/6mpqf+enp7/kZGR/4SE + hP90dHT/ZWVl/1RUVP8/Pz//aWlp/4qKiv9LS0v/NjY2/7u7u/+BgYH/JCQk/yEhIf8kJCT/JSUl/yQk + JP8lJSX/JSUl/yUlJf8lJSX/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8lJSX/JCQk/yAgIP9TU1P/paWl/8PDw//Ly8vx////AdDQ0DfNzc3/xsbG/76+vv+2trb/rKys/6Gh + of+UlJT/hoaG/2VlZf9VVVX/XV1d/2NjY/89PT3/hISE/2tra/9ubm7/YmJi/zY2Nv8jIyP/IiIi/yYm + Jv8lJSX/JCQk/yUlJf8lJSX/JCQk/yUlJf8lJSX/JSUl/yUlJf8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8lJSX/JiYm/yYmJv8lJSX/JiYm/yYmJv9sbGz/qKio/8fHx//Ozs7x////Ac3NzTfJycn/wsLC/7m5 + uf+vr6//pKSk/5eXl/+IiIj/dnZ2/1RUVP9BQUH/Xl5e/2pqav83Nzf/YWFh/2pqav+5ubn/pqam/yAg + IP8bGxv/IyMj/yQkJP8kJCT/JSUl/yUlJf8kJCT/JCQk/yQkJP8lJSX/JSUl/yUlJf8lJSX/JiYm/yUl + Jf8mJib/JiYm/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/xoaGv9iYmL/u7u7/8rKyv/Q0NDx////AcvL + yzfGxsb/vr6+/7Ozs/+np6f/mpqa/4uLi/96enr/bGxs/1hYWP8+Pj7/ZGRk/35+fv9UVFT/NjY2/6en + p/+4uLj/Jycn/yEhIf8iIiL/JCQk/yUlJf8lJSX/JSUl/yQkJP8kJCT/JCQk/yQkJP8lJSX/JSUl/yUl + Jf8lJSX/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8lJSX/HBwc/zU1Nf+vr6//xsbG/83N + zf/S0tLx////AcjIyDfDw8P/ubm5/62trf+goKD/kJCQ/3Z2dv9cXFz/Y2Nj/2NjY/9GRkb/cHBw/4GB + gf9dXV3/R0dH/0FBQf8wMDD/ICAg/yMjI/8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8jIyP/JCQk/yQk + JP8kJCT/JCQk/yUlJf8lJSX/JSUl/yUlJf8lJSX/JiYm/yYmJv8lJSX/JiYm/yUlJf81NTX/Pz8//6mp + qf/ExMT/ysrK/8/Pz//V1dXx////AcbGxjfAwMD/tbW1/6ampv+Xl5f/g4OD/2JiYv9FRUX/X19f/2pq + av9BQUH/bm5u/1xcXP+VlZX/zc3N/yIiIv8YGBj/IyMj/yQkJP8kJCT/KCgo/0VFRf9jY2P/a2tr/11d + Xf89PT3/JiYm/yMjI/8jIyP/JCQk/yQkJP8lJSX/JCQk/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yAg + IP9HR0f/q6ur/8HBwf/Hx8f/zc3N/9LS0v/X19fx////AcTExDe+vr7/sbGx/6Kiov+Pj4//enp6/2Nj + Y/9AQED/Y2Nj/3Z2dv9eXl7/MTEx/4qKiv/Z2dn/Ozs7/yEhIf8kJCT/JCQk/yQkJP9kZGT/srKy/8rK + yv/Ly8v/zMzM/8zMzP/Kysr/qKio/1NTU/8kJCT/JCQk/yQkJP8kJCT/JSUl/yQkJP8lJSX/JSUl/yUl + Jf8lJSX/IyMj/x0dHf+YmJj/wMDA/8bGxv/Ly8v/0NDQ/9XV1f/a2trx////AcTExDe9vb3/rq6u/5ub + m/92dnb/eXl5/2xsbP9VVVX/Y2Nj/5GRkf9XV1f/Nzc3/09PT/9OTk7/ICAg/yIiIv8kJCT/KSkp/4+P + j//MzMz/zMzM/8vLy//Ly8v/zMzM/8zMzP/MzMz/y8vL/8nJyf9/f3//JCQk/yMjI/8kJCT/JCQk/yQk + JP8kJCT/JSUl/yUlJf8rKyv/ISEh/5GRkf+/v7//xcXF/8rKyv/Pz8//09PT/9jY2P/c3Nzx////AcTE + xDe9vb3/rq6u/4qKiv9SUlL/cHBw/3Jycv9UVFT/b29v/1paWv9+fn7/y8vL/y4uLv8bGxv/Hx8f/yMj + I/8kJCT/d3d3/8rKyv/Ly8v/zMzM/8zMzP/MzMz/zMzM/8zMzP/Ly8v/ysrK/8rKyv/Jycn/Y2Nj/yMj + I/8jIyP/JCQk/yQkJP8kJCT/JCQk/yQkJP8/Pz//mpqa/729vf/Dw8P/ycnJ/83Nzf/S0tL/1tbW/9ra + 2v/e3t7x////AcTExDe/v7//sbGx/42Njf9MTEz/cHBw/3p6ev9qamr/OTk5/3V1df/Q0ND/bW1t/yAg + IP8fHx//IyMj/yQkJP8xMTH/wMDA/8zMzP/MzMz/zc3N/83Nzf/Nzc3/zc3N/8zMzP/Ly8v/y8vL/8rK + yv/Ly8v/srKy/ygoKP8kJCT/JCQk/yQkJP8kJCT/IiIi/xMTE/95eXn/u7u7/8PDw//IyMj/zc3N/9HR + 0f/W1tb/2dnZ/9zc3P/g4ODx////AcXFxTfAwMD/tbW1/5KSkv9qamr/ZWVl/5KSkv9lZWX/Ojo6/2ho + aP98fHz/ICAg/x8fH/8jIyP/JCQk/yQkJP9NTU3/zc3N/83Nzf/MzMz/zc3N/83Nzf/Nzc3/zc3N/83N + zf/MzMz/y8vL/8vLy//MzMz/y8vL/zg4OP8kJCT/JCQk/yQkJP8mJib/FRUV/29vb/+4uLj/wcHB/8fH + x//Nzc3/0dHR/9XV1f/Z2dn/3Nzc/9/f3//i4uLx////AcbGxjfBwcH/t7e3/4uLi/9vb2//aGho/29v + b/9paWn/srKy/zw8PP8jIyP/ICAg/yQkJP8jIyP/JCQk/yMjI/9MTEz/zMzM/8zMzP/MzMz/zMzM/83N + zf/Nzc3/zc3N/8zMzP/MzMz/zMzM/8zMzP/MzMz/y8vL/zs7O/8jIyP/JCQk/yQkJP85OTn/gICA/7m5 + uf/AwMD/xsbG/8zMzP/R0dH/1dXV/9jY2P/b29v/39/f/+Hh4f/k5OTx////AcfHxzfDw8P/r6+v/4WF + hf99fX3/Pj4+/2VlZf+xsbH/qamp/yAgIP8fHx//JCQk/yQkJP8jIyP/JCQk/yQkJP8xMTH/wMDA/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/MzMz/zMzM/8vLy//Ly8v/tra2/ykpKf8jIyP/IyMj/xIS + Ev9dXV3/tbW1/8DAwP/Gxsb/zMzM/9DQ0P/V1dX/2NjY/9zc3P/f39//4eHh/+Tk5P/m5ubx////AcnJ + yTfGxsb/rq6u/5CQkP+AgID/ODg4/3p6ev+tra3/JSUl/yAgIP8jIyP/IyMj/yMjI/8jIyP/IyMj/yQk + JP8kJCT/fn5+/83Nzf/MzMz/zc3N/83Nzf/MzMz/zc3N/83Nzf/MzMz/zMzM/8vLy//Kysr/bm5u/yQk + JP8kJCT/FhYW/01NTf+ysrL/wMDA/8bGxv/Ly8v/0NDQ/9TU1P/Y2Nj/29vb/9/f3//h4eH/4+Pj/+Xl + 5f/n5+fx////AczMzDfJycn/tLS0/4mJif9ZWVn/kZGR/05OTv8uLi7/Hx8f/yEhIf8iIiL/IiIi/yIi + Iv8iIiL/IyMj/yMjI/8jIyP/Kysr/5iYmP/MzMz/zMzM/83Nzf/MzMz/zMzM/8zMzP/MzMz/zMzM/8vL + y/+QkJD/Jycn/yMjI/81NTX/ZGRk/7S0tP/BwcH/xsbG/8vLy//Q0ND/1NTU/9jY2P/b29v/3t7e/+Hh + 4f/j4+P/5eXl/+fn5//p6enx////Ac/PzzfMzMz/vb29/11dXf+Ojo7/zs7O/zExMf8cHBz/ISEh/yIi + Iv8iIiL/NSIf/yIiIv8jIyP/IyMj/yMjI/8jIyP/IyMj/ygoKP9xcXH/vb29/8zMzP/Nzc3/zc3N/83N + zf/MzMz/ubm5/2pqav8nJyf/IyMj/xkZGf88PDz/ra2t/8HBwf/Gxsb/y8vL/9DQ0P/U1NT/2NjY/9vb + 2//e3t7/4ODg/+Pj4//l5eX/5+fn/+np6f/q6urx////AdLS0jfPz8//ysrK/62trf/Nzc3/OTk5/x8f + H/8hISH/IyMj/yIiIv9ZJBv/dCcZ/yIiIf8iIiL/IyMj/yMjI/8oIiH/IyIi/yMjI/8jIyP/Kysr/1NT + U/9vb2//fHx8/29vb/9OTk7/Kioq/yMjI/8jIyP/Gxsb/yoqKv+oqKj/wsLC/8fHx//MzMz/0NDQ/9TU + 1P/Y2Nj/29vb/97e3v/g4OD/4uLi/+Xl5f/n5+f/6enp/+rq6v/s7Ozx////AdXV1TfT09P/zs7O/7e3 + t/9CQkL/IiIi/yIiIv8kJCT/IiIi/00jHP+oKhP/SiMc/0MiHP9xJhj/WiQa/1wlG/9+KBj/LSMh/zEj + IP8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/JCQk/yMjI/8vLy//TExM/6mpqf/Dw8P/yMjI/83N + zf/R0dH/1dXV/9jY2P/b29v/3t7e/+Dg4P/j4+P/5eXl/+fn5//o6Oj/6urq/+zs7P/t7e3x////AdnZ + 2TfW1tb/0tLS/7y8vP8zMzP/IyMj/yMjI/8iIiL/NyIe/50pFP8tIR//bSYZ/4knFv85Ix//TyQc/y4i + If9gJhv/XiUb/3ImGP9BIx7/KCMh/yMjI/8jIyP/IyMj/yMjI/8kJCT/IyMj/x4eHv8lJSX/o6Oj/8XF + xf/Kysr/zs7O/9LS0v/W1tb/2dnZ/9zc3P/e3t7/4ODg/+Pj4//l5eX/5+fn/+jo6P/q6ur/6+vr/+3t + 7f/u7u7x////Adzc3DfZ2dn/1dXV/7Gxsf8lJSX/IyMj/yMjI/8iIiL/JCEh/1gkG/97Jhb/aCQX/34n + F/95Jhf/aiUZ/3wmF/88Ix7/UCQc/20mGf9oJhr/bSYZ/zIjIP8iIiL/IyMj/yMjI/8jIyP/ISEh/xkZ + Gf+YmJj/yMjI/8zMzP/Q0ND/1NTU/9fX1//a2tr/3d3d/9/f3//h4eH/4+Pj/+Xl5f/n5+f/6Ojo/+rq + 6v/r6+v/7e3t/+7u7v/v7+/x////Ad/f3zfd3d3/2dnZ/8fHx/9OTk7/JCQk/yMjI/8iIiL/IiIi/yEh + If8pISD/QSMd/0QjHf9pJRn/ISAg/3QlF/9DIx3/WCQb/ywiIP84Ix//aiYa/2UmGv9TJRz/IiIi/yIi + Iv8rKyv/Pj4+/5WVlf/Ly8v/z8/P/9LS0v/V1dX/2dnZ/9zc3P/e3t7/4ODg/+Li4v/k5OT/5eXl/+fn + 5//p6en/6urq/+vr6//t7e3/7u7u/+/v7//w8PDx////AeHh4Tfg4OD/3d3d/9ra2v/V1dX/k5OT/zc3 + N/8iIiL/IiIi/yIiIv8hISH/ISEh/yQhIP9oJRn/cSQX/2glGf+EJxb/PiMe/0kjHP9BIx7/YiUa/28m + Gf8kIyL/IyMj/yIiIv8cHBz/kJCQ/87Ozv/S0tL/1dXV/9jY2P/b29v/3d3d/+Dg4P/i4uL/5OTk/+Xl + 5f/n5+f/6Ojo/+np6f/r6+v/7Ozs/+3t7f/u7u7/7+/v//Dw8P/x8fHx////AeTk5Dfj4+P/4ODg/97e + 3v/b29v/2dnZ/8vLy/91dXX/Kioq/yIiIv8iIiL/IiIi/yEhIf8hISH/ISEg/1wkGv90Jhj/QyIc/4An + F/8mIiH/ZyYa/ygjIv8jIyP/JCQk/xQUFP99fX3/0dHR/9bW1v/Y2Nj/2tra/93d3f/f39//4uLi/+Tk + 5P/l5eX/5+fn/+jo6P/p6en/6urq/+vr6//s7Oz/7u7u/+/v7//w8PD/8PDw//Hx8f/y8vLx////Aefn + 5zfm5ub/4+Pj/+Hh4f/g4OD/3t7e/9zc3P/Z2dn/t7e3/1paWv9PT0//NTU1/yIiIv8hISH/ISEh/yEh + If9UJBz/iSgW/0QjHf9yJhj/VCYd/yMjIv8nJyf/Nzc3/3Z2dv/S0tL/2dnZ/9vb2//e3t7/4ODg/+Li + 4v/k5OT/5eXl/+fn5//o6Oj/6enp/+rq6v/r6+v/7Ozs/+3t7f/u7u7/7+/v//Dw8P/x8fH/8vLy//Ly + 8v/z8/Px////Aenp6Tfp6en/5+fn/+Xl5f/j4+P/4uLi/+Dg4P/e3t7/3d3d/9vb2//a2tr/ysrK/0BA + QP8iIiL/IiIi/yIiIv8iIiL/KCIh/2snGv9RJR7/IyMi/yIiIv8bGxv/eXl5/9bW1v/d3d3/39/f/+Dg + 4P/i4uL/5OTk/+bm5v/n5+f/6Ojo/+np6f/q6ur/6+vr/+zs7P/t7e3/7u7u/+/v7//w8PD/8PDw//Hx + 8f/y8vL/8/Pz//Pz8//09PTx////Aezs7Dfr6+v/6urq/+jo6P/n5+f/5eXl/+Tk5P/j4+P/4eHh/+Dg + 4P/f39//3t7e/5SUlP8rKyv/IiIi/yIiIv8iIiL/IiIi/yMjI/8iIiL/IyMj/xYWFv9SUlL/1dXV/+Hh + 4f/i4uL/4+Pj/+Xl5f/m5ub/5+fn/+np6f/q6ur/6+vr/+zs7P/t7e3/7e3t/+7u7v/v7+//7+/v//Dw + 8P/x8fH/8vLy//Ly8v/z8/P/8/Pz//T09P/19fXx////Ae3t7Tft7e3/7Ozs/+vr6//q6ur/6enp/+fn + 5//m5ub/5eXl/+Tk5P/j4+P/4uLi/+Hh4f/IyMj/YmJi/yQkJP8jIyP/IyMj/yMjI/8kJCT/WFhY/11d + Xf/U1NT/5OTk/+Xl5f/m5ub/5+fn/+jo6P/p6en/6urq/+vr6//s7Oz/7e3t/+7u7v/u7u7/7+/v//Dw + 8P/w8PD/8fHx//Hx8f/y8vL/8/Pz//Pz8//09PT/9PT0//X19f/19fXx////Ae/v7zfu7u7/7u7u/+3t + 7f/s7Oz/6+vr/+rq6v/p6en/6Ojo/+fn5//m5ub/5eXl/+Xl5f/k5OT/4+Pj/7CwsP9HR0f/IyMj/yMj + I/+Dg4P/5OTk/+Xl5f/m5ub/5+fn/+jo6P/p6en/6urq/+vr6//s7Oz/7Ozs/+3t7f/u7u7/7+/v/+/v + 7//w8PD/8fHx//Hx8f/y8vL/8vLy//Ly8v/z8/P/8/Pz//T09P/09PT/9fX1//X19f/29vbx////AfHx + 8Tfw8PD/7+/v/+/v7//u7u7/7e3t/+zs7P/s7Oz/6+vr/+rq6v/p6en/6Ojo/+jo6P/n5+f/6Ojo/+jo + 6P/f39//kZGR/4GBgf/m5ub/6enp/+np6f/p6en/6urq/+vr6//s7Oz/7Ozs/+3t7f/u7u7/7u7u/+/v + 7//v7+//8PDw//Hx8f/x8fH/8vLy//Ly8v/z8/P/8/Pz//Pz8//09PT/9PT0//X19f/19fX/9vb2//b2 + 9v/29vbx////AfLy8jfy8vL/8fHx//Dw8P/w8PD/7+/v/+7u7v/u7u7/7e3t/+zs7P/s7Oz/6+vr/+vr + 6//q6ur/6urq/+rq6v/r6+v/6+vr/+vr6//r6+v/6+vr/+zs7P/s7Oz/7e3t/+3t7f/u7u7/7u7u/+/v + 7//v7+//8PDw//Dw8P/x8fH/8fHx//Ly8v/y8vL/8/Pz//Pz8//09PT/9PT0//T09P/19fX/9fX1//X1 + 9f/29vb/9vb2//f39//39/fx////AfPz8zfz8/P/8vLy//Ly8v/x8fH/8fHx//Dw8P/w8PD/7+/v/+/v + 7//u7u7/7u7u/+3t7f/t7e3/7e3t/+3t7f/t7e3/7e3t/+3t7f/t7e3/7u7u/+7u7v/u7u7/7+/v/+/v + 7//w8PD/8PDw//Dw8P/x8fH/8fHx//Ly8v/y8vL/8/Pz//Pz8//z8/P/9PT0//T09P/19fX/9fX1//X1 + 9f/29vb/9vb2//b29v/29vb/9/f3//f39//39/fx////AQAAAAAAAP//AAAAAAAA//8AAAAAAAD//wAA + AAAAAP//AAAAAAAA//8AAAAAAAD//wAAAAAAAP//AAAAAAAA//8AAAAAAAD//wAAAAAAAP//AAAAAAAA + //8AAAAAAAD//wAAAAAAAP//AAAAAAAA//8AAAAAAAD//wAAAAAAAP//AAAAAAAA//8AAAAAAAD//wAA + AAAAAP//AAAAAAAA//8AAAAAAAD//wAAAAAAAP//AAAAAAAA//8AAAAAAAD//wAAAAAAAP//AAAAAAAA + //8AAAAAAAD//wAAAAAAAP//AAAAAAAA//8AAAAAAAD//wAAAAAAAP//AAAAAAAA//8AAAAAAAD//wAA + AAAAAP//AAAAAAAA//8AAAAAAAD//wAAAAAAAP//AAAAAAAA//8AAAAAAAD//wAAAAAAAP//AAAAAAAA + //8AAAAAAAD//wAAAAAAAP//AAAAAAAA//8AAAAAAAD//wAAAAAAAP//AAAAAAAA//8AAAAAAAD//ygA + AABAAAAAgAAAAAEAIAAAAAAAAEIAAAAAAAAAAAAAAAAAAAAAAAD///8B7+/v8e/v7//u7u7/7u7u/+3t + 7f/s7Oz/6+vr/+rq6v/p6en/6Ojo/+fn5//m5ub/5OTk/+Pj4//h4eH/4ODg/97e3v/d3d3/29vb/9ra + 2v/Y2Nj/19fX/9XV1f/R0dH/zs7O/8vLy//Hx8f/xMTE/8HBwf++vr7/u7u7/7i4uP+1tbX/srKy/7Cw + sP+vr6//rq6u/62trf+urq7/r6+v/7CwsP+xsbH/s7Oz/7W1tf+3t7f/urq6/7y8vP+/v7//wcHB/8TE + xP/Gxsb/yMjI/8vLy//Nzc3/0NDQ/9LS0v/V1dX/19fX/9nZ2f/c3Nz/3t7e/+Dg4Jf///8B////Ae/v + 7/Hu7u7/7e3t/+3t7f/s7Oz/6+vr/+rq6v/p6en/6Ojo/+fn5//l5eX/5OTk/+Li4v/h4eH/39/f/93d + 3f/c3Nz/2tra/9jY2P/W1tb/1dXV/9LS0v/Q0ND/zMzM/8jIyP/ExMT/wMDA/7y8vP+4uLj/tLS0/7Cw + sP+srKz/qKio/6Wlpf+kpKT/o6Oj/6Kiov+ioqL/o6Oj/6Wlpf+np6f/qKio/6qqqv+tra3/sLCw/7Oz + s/+2trb/uLi4/7u7u/++vr7/wcHB/8PDw//Gxsb/ycnJ/8vLy//Ozs7/0dHR/9TU1P/W1tb/2dnZ/9zc + 3P/e3t6X////Af///wHu7u7x7e3t/+zs7P/s7Oz/6+vr/+rq6v/p6en/5+fn/+bm5v/l5eX/5OTk/+Li + 4v/g4OD/3t7e/93d3f/b29v/2dnZ/9fX1//U1NT/0tLS/9DQ0P/Nzc3/ycnJ/8bGxv/BwcH/vLy8/7e3 + t/+ysrL/rq6u/6ioqP+hoaH/k5OT/5iYmP+VlZX/lJSU/5SUlP+VlZX/lpaW/5iYmP+ampr/nJyc/5+f + n/+hoaH/paWl/6mpqf+srKz/r6+v/7Kysv+1tbX/uLi4/7u7u/++vr7/wcHB/8TExP/Hx8f/ysrK/87O + zv/R0dH/1NTU/9fX1//a2tr/3Nzcl////wH///8B7e3t8ezs7P/r6+v/6urq/+np6f/o6Oj/5+fn/+bm + 5v/k5OT/4+Pj/+Hh4f/f39//3t7e/9zc3P/a2tr/2NjY/9XV1f/T09P/0NDQ/87Ozv/Kysr/x8fH/8PD + w/+/v7//urq6/7W1tf+urq7/qKio/6Ghof+ZmZn/fX19/2RkZP94eHj/hoaG/4WFhf+Ghob/h4eH/4qK + iv+MjIz/jo6O/5GRkf+VlZX/mJiY/5ycnP+goKD/pKSk/6enp/+rq6v/rq6u/7Kysv+1tbX/uLi4/7u7 + u/+/v7//w8PD/8bGxv/Kysr/zs7O/9HR0f/U1NT/19fX/9ra2pf///8B////Aezs7PHr6+v/6urq/+np + 6f/o6Oj/5+fn/+Xl5f/k5OT/4uLi/+Hh4f/f39//3d3d/9vb2//Z2dn/19fX/9XV1f/S0tL/z8/P/8zM + zP/IyMj/xcXF/8HBwf+8vLz/uLi4/7Ozs/+tra3/pKSk/5ycnP+Tk5P/ioqK/2pqav9jY2P/ampq/3l5 + ef94eHj/eHh4/3p6ev99fX3/gYGB/4SEhP+Hh4f/i4uL/4+Pj/+Tk5P/l5eX/5ubm/+fn5//o6Oj/6en + p/+rq6v/r6+v/7Kysv+2trb/urq6/76+vv/CwsL/xsbG/8rKyv/Nzc3/0dHR/9XV1f/X19eX////Af// + /wHq6urx6enp/+jo6P/n5+f/5ubm/+Xl5f/k5OT/4uLi/+Dg4P/e3t7/3Nzc/9ra2v/Y2Nj/1tbW/9TU + 1P/R0dH/zs7O/8vLy//Hx8f/w8PD/7+/v/+6urr/tbW1/7CwsP+qqqr/oqKi/5iYmP+Ojo7/g4OD/3p6 + ev9oaGj/ZWVl/2dnZ/9tbW3/bGxs/21tbf9wcHD/c3Nz/3Z2dv96enr/fX19/4GBgf+FhYX/ioqK/46O + jv+Tk5P/l5eX/5ubm/+goKD/pKSk/6ioqP+srKz/sLCw/7W1tf+5ubn/vr6+/8LCwv/Gxsb/ysrK/87O + zv/S0tL/1dXVl////wH///8B6enp8ejo6P/n5+f/5ubm/+Xl5f/k5OT/4uLi/+Dg4P/e3t7/3Nzc/9ra + 2v/Y2Nj/1tbW/9PT0//R0dH/zs7O/8rKyv/Hx8f/w8PD/76+vv+5ubn/s7Oz/66urv+oqKj/oKCg/5aW + lv+MjIz/gICA/3Z2dv9ubm7/Z2dn/2tra/9tbW3/Y2Nj/2JiYv9jY2P/Z2dn/2pqav9tbW3/cHBw/3Nz + c/93d3f/fHx8/4CAgP+FhYX/ioqK/46Ojv+Tk5P/mJiY/52dnf+hoaH/pqam/6urq/+vr6//tLS0/7m5 + uf+9vb3/wsLC/8bGxv/Ly8v/z8/P/9LS0pf///8B////Aejo6PHn5+f/5ubm/+Xl5f/j4+P/4uLi/+Dg + 4P/f39//3d3d/9ra2v/Y2Nj/1tbW/9PT0//Q0ND/zc3N/8rKyv/Hx8f/w8PD/76+vv+4uLj/s7Oz/62t + rf+mpqb/n5+f/5SUlP+Kior/eHh4/1dXV/9fX1//Z2dn/2lpaf9vb2//dHR0/2VlZf9aWlr/W1tb/15e + Xv9hYWH/ZGRk/2dnZ/9qamr/bm5u/3Nzc/93d3f/fHx8/4GBgf+Ghob/i4uL/5CQkP+VlZX/mpqa/5+f + n/+kpKT/qqqq/6+vr/+0tLT/ubm5/76+vv/Dw8P/yMjI/8zMzP/Pz8+X////Af///wHo6Ojx5ubm/+Xl + 5f/k5OT/4uLi/+Dg4P/f39//3d3d/9vb2//Y2Nj/1tbW/9PT0//Q0ND/zc3N/8nJyf/Gxsb/wsLC/729 + vf+4uLj/s7Oz/62trf+mpqb/nZ2d/5SUlP+IiIj/fHx8/2JiYv9MTEz/TExM/2JiYv9sbGz/cXFx/3Z2 + dv9jY2P/UlJS/1RUVP9PT0//NDQ0/0xMTP9eXl7/YmJi/2ZmZv9qamr/b29v/3Nzc/95eXn/fn5+/4OD + g/+JiYn/jo6O/5SUlP+ZmZn/np6e/6SkpP+qqqr/r6+v/7W1tf+6urr/v7+//8XFxf/Jycn/zc3Nl/// + /wH///8B5+fn8eXl5f/k5OT/4uLi/+Hh4f/f39//3d3d/9vb2//Z2dn/1tbW/9PT0//Q0ND/zc3N/8nJ + yf/FxcX/wcHB/729vf+4uLj/s7Oz/62trf+mpqb/np6e/5SUlP+IiIj/fHx8/3BwcP9dXV3/TExM/0dH + R/9kZGT/b29v/319ff+CgoL/YWFh/0xMTP9JSUn/JCQk/xwcHP8gICD/NjY2/1RUVP9eXl7/YmJi/2Zm + Zv9ra2v/cHBw/3Z2dv97e3v/gYGB/4eHh/+MjIz/kpKS/5iYmP+enp7/pKSk/6urq/+xsbH/t7e3/7y8 + vP/CwsL/x8fH/8vLy5f///8B////Aebm5vHk5OT/4uLi/+Hh4f/f39//3d3d/9vb2//Z2dn/19fX/9TU + 1P/R0dH/zc3N/8rKyv/Gxsb/wcHB/729vf+4uLj/s7Oz/6ysrP+mpqb/np6e/5WVlf+JiYn/fn5+/3Bw + cP9iYmL/W1tb/1dXV/9NTU3/ZWVl/3l5ef+Xl5f/ampq/2xsbP9GRkb/JSUl/xsbG/8vLy//Hh4e/x4e + Hv8kJCT/QkJC/1hYWP9eXl7/Y2Nj/2hoaP9ubm7/c3Nz/3l5ef9/f3//hYWF/4yMjP+SkpL/mJiY/5+f + n/+mpqb/ra2t/7Ozs/+6urr/v7+//8XFxf/JycmX////Af///wHk5OTx4+Pj/+Hh4f/f39//3t7e/9zc + 3P/Z2dn/19fX/9TU1P/R0dH/zs7O/8rKyv/Gxsb/wsLC/729vf+4uLj/s7Oz/62trf+mpqb/n5+f/5WV + lf+Kior/fX19/2FhYf9eXl7/VlZW/1paWv9mZmb/VlZW/21tbf+Wlpb/Z2dn/2xsbP+Ghob/RERE/xsb + G/8mJib/HBwc/x4eHv8eHh7/Hh4e/x4eHv8sLCz/TExM/1paWv9gYGD/ZmZm/2xsbP9xcXH/d3d3/35+ + fv+EhIT/i4uL/5KSkv+ampr/oaGh/6ioqP+wsLD/t7e3/729vf/Dw8P/yMjIl////wH///8B4+Pj8eHh + 4f/g4OD/3t7e/9zc3P/a2tr/2NjY/9XV1f/S0tL/zs7O/8rKyv/Hx8f/wsLC/729vf+4uLj/s7Oz/66u + rv+np6f/n5+f/5eXl/+Kior/fn5+/2dnZ/9ISEj/QUFB/1FRUf9jY2P/ampq/01NTf+EhIT/bm5u/2Vl + Zf+IiIj/5eXl/39/f/8jIyP/Hx8f/x8fH/8eHh7/Hh4e/x4eHv8eHh7/HR0d/x8fH/83Nzf/VFRU/15e + Xv9kZGT/aWlp/3BwcP92dnb/fX19/4SEhP+MjIz/k5OT/5ycnP+kpKT/rKys/7S0tP+8vLz/wsLC/8fH + x5f///8B////AeLi4vHg4OD/3t7e/9zc3P/a2tr/2NjY/9bW1v/T09P/z8/P/8vLy//Hx8f/w8PD/76+ + vv+5ubn/s7Oz/62trf+np6f/n5+f/5aWlv+MjIz/f39//3Jycv9fX1//SUlJ/zo6Ov9XV1f/aWlp/3Bw + cP9PT0//V1dX/11dXf+IiIj/39/f/7S0tP8nJyf/Jycn/yEhIf8lJSX/JCQk/x8fH/8fHx//Hh4e/x4e + Hv8eHh7/Hh4e/yUlJf9ERET/W1tb/2JiYv9oaGj/b29v/3Z2dv99fX3/hYWF/42Njf+Wlpb/n5+f/6mp + qf+ysrL/urq6/8HBwf/GxsaX////Af///wHh4eHx39/f/93d3f/b29v/2NjY/9bW1v/T09P/0NDQ/8zM + zP/IyMj/w8PD/76+vv+5ubn/tLS0/66urv+np6f/oKCg/5aWlv+Li4v/gICA/3R0dP9nZ2f/XV1d/01N + Tf86Ojr/WVlZ/25ubv+Li4v/c3Nz/05OTv9dXV3/0dHR/8bGxv8uLi7/JiYm/yAgIP8kJCT/JSUl/yYm + Jv8lJSX/IiIi/x8fH/8eHh7/Hh4e/x4eHv8eHh7/Hh4e/zAwMP9RUVH/YWFh/2dnZ/9ubm7/dXV1/319 + ff+Ghob/kJCQ/5qamv+lpaX/r6+v/7m5uf/BwcH/xsbGl////wH///8B4ODg8d7e3v/b29v/2dnZ/9bW + 1v/T09P/0NDQ/8zMzP/IyMj/xMTE/7+/v/+6urr/tLS0/66urv+oqKj/oaGh/5iYmP+MjIz/gYGB/25u + bv9mZmb/Xl5e/1paWv9iYmL/SkpK/1lZWf+Ghob/hYWF/1hYWP9paWn/Ozs7/2xsbP81NTX/JiYm/yAg + IP8kJCT/JSUl/yYmJv8mJib/JiYm/yUlJf8kJCT/ISEh/x8fH/8eHh7/Hh4e/x4eHv8eHh7/IiIi/z4+ + Pv9bW1v/ZGRk/2tra/90dHT/fn5+/4qKiv+Wlpb/oaGh/62trf+3t7f/wcHB/8bGxpf///8B////Ad7e + 3vHc3Nz/2tra/9fX1//U1NT/0NDQ/8zMzP/IyMj/xMTE/8DAwP+7u7v/tbW1/6+vr/+oqKj/oaGh/5mZ + mf+Ojo7/goKC/3Jycv9OTk7/RUVF/1RUVP9dXV3/ZmZm/0ZGRv9qamr/ioqK/1RUVP99fX3/tLS0/4CA + gP8bGxv/HR0d/x4eHv8jIyP/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yUlJf8jIyP/Hx8f/x8f + H/8fHx//Hh4e/x4eHv8eHh7/KSkp/0pKSv9fX1//ampq/3d3d/+EhIT/kpKS/5+fn/+rq6v/tra2/8DA + wP/Hx8eX////Af///wHd3d3x2tra/9fX1//U1NT/0dHR/83Nzf/Jycn/xcXF/8DAwP+7u7v/tra2/7Cw + sP+qqqr/oqKi/5qamv+QkJD/hISE/3d3d/9nZ2f/TExM/zw8PP9SUlL/ZGRk/2pqav9BQUH/Wlpa/1RU + VP97e3v/ra2t/+rq6v9OTk7/IiIi/xsbG/8kJCT/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JSUl/yMjI/8hISH/Hx8f/x8fH/8fHx//Hx8f/x8fH/8gICD/NjY2/11dXf9ycnL/f39//4yM + jP+cnJz/qamp/7W1tf/AwMD/x8fHl////wH///8B29vb8djY2P/V1dX/0tLS/87Ozv/Kysr/xsbG/8HB + wf+8vLz/t7e3/7Gxsf+qqqr/pKSk/5ycnP+SkpL/h4eH/3p6ev9tbW3/YWFh/05OTv82Njb/VFRU/2lp + af94eHj/bGxs/zMzM/9fX1//pKSk/+/v7/9gYGD/JCQk/yAgIP8kJCT/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8lJSX/JCQk/yMjI/8fHx//Hx8f/x8fH/8fHx//Hx8f/x8f + H/8mJib/Tk5O/1xcXP9oaGj/k5OT/6enp/+0tLT/wMDA/8fHx5f///8B////AdnZ2fHW1tb/09PT/8/P + z//Ly8v/x8fH/8LCwv+9vb3/t7e3/7Kysv+rq6v/pKSk/52dnf+Tk5P/iIiI/3t7e/9vb2//ZWVl/1xc + XP9cXFz/SkpK/09PT/92dnb/l5eX/1lZWf9GRkb/MTEx/6enp/9tbW3/IiIi/yAgIP8iIiL/JSUl/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yUlJf8lJSX/JCQk/yIi + Iv8fHx//Hx8f/yAgIP8gICD/ICAg/yAgIP8pKSn/Wlpa/46Ojv+np6f/tbW1/8HBwf/Hx8eX////Af// + /wHX19fx1NTU/9DQ0P/MzMz/yMjI/8PDw/++vr7/ubm5/7Ozs/+srKz/paWl/52dnf+UlJT/iYmJ/319 + ff9cXFz/SkpK/1lZWf9aWlr/Y2Nj/0xMTP9TU1P/k5OT/2BgYP9sbGz/i4uL/2BgYP8YGBj/Hh4e/yEh + If8hISH/JSUl/yUlJf8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8lJSX/JCQk/yEhIf8gICD/ICAg/yAgIP8gICD/ICAg/zQ0NP+QkJD/qKio/7e3 + t//Dw8P/yMjIl////wH///8B1dXV8dLS0v/Ozs7/ycnJ/8XFxf/AwMD/urq6/7S0tP+urq7/p6en/5+f + n/+VlZX/i4uL/39/f/9xcXH/UVFR/zw8PP9OTk7/YWFh/2dnZ/9ISEj/UVFR/2lpaf9kZGT/ioqK/+fn + 5/+NjY3/Hh4e/xgYGP8fHx//JCQk/yUlJf8lJSX/JSUl/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yUlJf8lJSX/IyMj/yAgIP8gICD/ICAg/yEh + If8uLi7/jo6O/6urq/+7u7v/xcXF/8nJyZf///8B////AdPT0/HPz8//y8vL/8bGxv/BwcH/u7u7/7W1 + tf+vr6//qKio/6CgoP+Wlpb/jY2N/4GBgf91dXX/aWlp/1NTU/82Njb/TU1N/2dnZ/9vb2//Y2Nj/yoq + Kv9SUlL/hoaG/9/f3/+pqan/JSUl/yQkJP8gICD/JCQk/yUlJf8lJSX/JSUl/yUlJf8lJSX/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8kJCT/ISEh/yAgIP8gICD/Jycn/4ODg/+qqqr/wMDA/8fHx//Ly8uX////Af///wHR0dHxzc3N/8jI + yP/Dw8P/vb29/7e3t/+wsLD/qqqq/6Kiov+YmJj/jo6O/4SEhP93d3f/bW1t/2NjY/9aWlr/R0dH/0hI + SP9tbW3/jIyM/3R0dP8vLy//MjIy/6+vr//AwMD/Jycn/yYmJv8gICD/JCQk/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JSUl/yYmJv8kJCT/ICAg/yUlJf+EhIT/ra2t/8PDw//Jycn/zc3Nl/// + /wH///8Bz8/P8cvLy//Gxsb/wMDA/7q6uv+zs7P/rKys/6SkpP+bm5v/kZGR/4aGhv9xcXH/VVVV/19f + X/9dXV3/YmJi/1ZWVv8/Pz//h4eH/4GBgf9TU1P/cHBw/zc3N/8nJyf/R0dH/yQkJP8hISH/JiYm/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yUlJf81NTX/i4uL/6+v + r//Gxsb/y8vL/8/Pz5f///8B////Ac3NzfHIyMj/w8PD/7y8vP+1tbX/rq6u/6ampv+dnZ3/kpKS/4eH + h/96enr/WVlZ/0RERP9NTU3/Xl5e/2dnZ/9UVFT/QUFB/4uLi/9PT0//fHx8/7y8vP/Gxsb/Hh4e/xgY + GP8dHR3/JCQk/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yUl + Jf8lJSX/SUlJ/4+Pj/+4uLj/ycnJ/83Nzf/R0dGX////Af///wHLy8vxxcXF/7+/v/+4uLj/sLCw/6io + qP+fn5//lZWV/4mJif98fHz/b29v/1paWv8/Pz//SEhI/2VlZf9ra2v/YmJi/yQkJP9JSUn/enp6/7Gx + sf/k5OT/QEBA/yMjI/8dHR3/ISEh/yQkJP8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yUlJf8kJCT/ERER/y8vL/+rq6v/xcXF/8rKyv/Pz8//0tLSl////wH///8BycnJ8cPD + w/+8vLz/tLS0/6urq/+ioqL/l5eX/4yMjP9/f3//c3Nz/2lpaf9eXl7/RERE/0VFRf9paWn/fHx8/4uL + i/8nJyf/Ojo6/5ycnP/o6Oj/UlJS/yIiIv8gICD/IiIi/yQkJP8lJSX/JSUl/yUlJf8lJSX/JSUl/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8kJCT/FhYW/ywsLP+fn5//wsLC/8jIyP/MzMz/0NDQ/9TU + 1Jf///8B////AcbGxvHAwMD/ubm5/7CwsP+mpqb/m5ub/4+Pj/+AgID/YmJi/2ZmZv9kZGT/YWFh/2Bg + YP84ODj/d3d3/5SUlP9WVlb/W1tb/ygoKP87Ozv/XV1d/yEhIf8fHx//IiIi/yQkJP8lJSX/JSUl/yUl + Jf8lJSX/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8nJyf/Kysr/ygoKP+ZmZn/wMDA/8bG + xv/Kysr/zs7O/9LS0v/W1taX////Af///wHFxcXxvr6+/7W1tf+rq6v/oKCg/5OTk/+Ghob/a2tr/0tL + S/9MTEz/YWFh/2ZmZv9hYWH/NjY2/5KSkv9dXV3/aWlp/5KSkv/FxcX/ISEh/yEhIf8bGxv/IiIi/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JiYm/ysrK/8rKyv/KCgo/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JiYm/yYmJv8mJib/JiYm/yYmJv8lJSX/NTU1/2tr + a/+jo6P/v7+//8TExP/IyMj/zMzM/9HR0f/V1dX/2NjYl////wH///8Bw8PD8bu7u/+xsbH/pqam/5qa + mv+MjIz/fHx8/2ZmZv9JSUn/RkZG/2RkZP9sbGz/Z2dn/ycnJ/9UVFT/YmJi/4uLi//p6en/hoaG/x8f + H/8bGxv/ICAg/yUlJf8kJCT/IyMj/ygoKP9OTk7/f39//6Ghof+ysrL/s7Oz/6ioqP+Pj4//YmJi/zMz + M/8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8mJib/JiYm/yUl + Jf8lJSX/HBwc/xkZGf+Li4v/vLy8/8LCwv/Gxsb/y8vL/8/Pz//T09P/19fX/9nZ2Zf///8B////AcLC + wvG5ubn/r6+v/6Ojo/+Wlpb/hoaG/3d3d/9nZ2f/SkpK/0VFRf9qamr/dHR0/5CQkP8uLi7/Nzc3/4CA + gP/j4+P/m5ub/x0dHf8hISH/IiIi/yYmJv8kJCT/IyMj/0hISP+lpaX/ycnJ/8vLy//Ly8v/y8vL/8zM + zP/MzMz/zc3N/83Nzf++vr7/cnJy/yoqKv8kJCT/JCQk/yQkJP8kJCT/JCQk/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yYmJv8lJSX/IiIi/xEREf9/f3//u7u7/8LCwv/Gxsb/ycnJ/83Nzf/R0dH/1dXV/9jY + 2P/b29uX////Af///wHBwcHxuLi4/62trf+hoaH/h4eH/35+fv94eHj/bGxs/2hoaP9BQUH/bGxs/5OT + k/92dnb/RkZG/yQkJP9LS0v/lZWV/yAgIP8iIiL/ICAg/yUlJf8kJCT/JCQk/2lpaf/Gxsb/zc3N/8zM + zP/Ly8v/y8vL/8vLy//MzMz/zMzM/8zMzP/MzMz/y8vL/8rKyv+np6f/Nzc3/yMjI/8kJCT/JCQk/yQk + JP8kJCT/JCQk/yUlJf8lJSX/JSUl/yUlJf8lJSX/IyMj/wwMDP93d3f/uLi4/8HBwf/FxcX/ycnJ/8zM + zP/Q0ND/1NTU/9fX1//a2tr/3Nzcl////wH///8BwcHB8be3t/+srKz/mJiY/2FhYf9VVVX/eXl5/3Bw + cP9ubm7/Ojo6/4WFhf9+fn7/UFBQ/35+fv+bm5v/Jycn/zAwMP8bGxv/HR0d/yMjI/8kJCT/IyMj/19f + X//Gxsb/y8vL/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/Ly8v/y8vL/8rKyv/Kysr/ycnJ/6Oj + o/8rKyv/IyMj/yQkJP8kJCT/JCQk/yQkJP8lJSX/JSUl/yUlJf8lJSX/MjIy/1lZWf+AgID/t7e3/8DA + wP/ExMT/yMjI/8vLy//Pz8//0tLS/9bW1v/Z2dn/29vb/97e3pf///8B////AcLCwvG5ubn/ra2t/5WV + lf9fX1//SkpK/3l5ef90dHT/c3Nz/zIyMv9qamr/TU1N/3x8fP/CwsL/ycnJ/ywsLP8aGhr/Gxsb/yIi + Iv8jIyP/JCQk/zU1Nf+2trb/y8vL/8vLy//MzMz/zMzM/83Nzf/Nzc3/zc3N/8zMzP/MzMz/y8vL/8vL + y//Kysr/ysrK/8rKyv/Kysr/c3Nz/yQkJP8kJCT/JCQk/yQkJP8kJCT/JSUl/yUlJf8kJCT/ISEh/xUV + Ff9zc3P/s7Oz/7+/v//Dw8P/x8fH/8vLy//Ozs7/0tLS/9XV1f/Y2Nj/2tra/93d3f/f39+X////Af// + /wHDw8Pxu7u7/6+vr/+Wlpb/X19f/0dHR/96enr/enp6/4mJif9DQ0P/Pj4+/3Z2dv+0tLT/2dnZ/zk5 + Of8hISH/Hh4e/yIiIv8jIyP/JCQk/yQkJP9paWn/zMzM/83Nzf/MzMz/zMzM/83Nzf/Nzc3/zs7O/83N + zf/Nzc3/zMzM/8zMzP/Ly8v/y8vL/8vLy//Ly8v/zMzM/7Ozs/8rKyv/JCQk/yQkJP8kJCT/JCQk/yUl + Jf8kJCT/ISEh/w0NDf9RUVH/r6+v/76+vv/CwsL/x8fH/8rKyv/Ozs7/0dHR/9TU1P/X19f/2tra/9zc + 3P/f39//4eHhl////wH///8Bw8PD8b29vf+zs7P/mZmZ/3V1df9VVVX/c3Nz/4qKiv+Tk5P/RERE/zAw + MP9qamr/09PT/0NDQ/8hISH/Hh4e/yIiIv8jIyP/JCQk/yQkJP8kJCT/kJCQ/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/87Ozv/Ozs7/zs7O/83Nzf/MzMz/zMzM/8vLy//Ly8v/zMzM/83Nzf/Jycn/PDw8/yQk + JP8kJCT/JCQk/yQkJP8kJCT/IyMj/w4ODv9KSkr/qamp/729vf/BwcH/xsbG/8rKyv/Ozs7/0dHR/9TU + 1P/X19f/2tra/9zc3P/e3t7/4eHh/+Li4pf///8B////AcPDw/G9vb3/tra2/5aWlv9/f3//UFBQ/3R0 + dP+Xl5f/UlJS/29vb/92dnb/ISEh/y8vL/8fHx//Hx8f/yIiIv8jIyP/JCQk/yQkJP8kJCT/JCQk/5iY + mP/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zMzM/8zMzP/MzMz/zMzM/8zM + zP/MzMz/zMzM/0dHR/8kJCT/JCQk/yQkJP8kJCT/KSkp/0RERP9WVlb/q6ur/7y8vP/AwMD/xcXF/8rK + yv/Nzc3/0dHR/9TU1P/X19f/2dnZ/9zc3P/e3t7/4ODg/+Li4v/k5OSX////Af///wHFxcXxvr6+/7Oz + s/+Hh4f/goKC/0xMTP9wcHD/V1dX/2pqav+Tk5P/7u7u/1NTU/8eHh7/GRkZ/yQkJP8lJSX/JCQk/yQk + JP8kJCT/JCQk/yQkJP+Ghob/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/8zM + zP/MzMz/zMzM/8zMzP/MzMz/zMzM/8bGxv87Ozv/JCQk/yQkJP8kJCT/IyMj/xoaGv9ZWVn/pKSk/7y8 + vP/AwMD/xMTE/8nJyf/Nzc3/0NDQ/9TU1P/X19f/2dnZ/9zc3P/e3t7/4ODg/+Li4v/k5OT/5eXll/// + /wH///8BxsbG8cDAwP+oqKj/hYWF/4qKiv9fX1//Pj4+/2hoaP+Ojo7/6enp/3V1df8dHR3/ICAg/yMj + I/8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/VlZW/8vLy//Nzc3/zc3N/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/MzMz/zMzM/8zMzP/Ly8v/y8vL/8vLy/+pqan/KCgo/yQkJP8kJCT/IiIi/xIS + Ev8vLy//oqKi/7u7u//AwMD/xMTE/8nJyf/Nzc3/0NDQ/9TU1P/X19f/2dnZ/9zc3P/e3t7/4ODg/+Li + 4v/k5OT/5eXl/+bm5pf///8B////AcjIyPHDw8P/qKio/4qKiv+cnJz/X19f/zMzM/+CgoL/1tbW/4eH + h/8eHh7/ICAg/yEhIf8jIyP/IyMj/yMjI/8jIyP/IyMj/yQkJP8kJCT/JCQk/ysrK/+np6f/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/8zMzP/MzMz/y8vL/8vLy//Jycn/YWFh/yQk + JP8kJCT/IyMj/xUVFf8mJib/lZWV/7u7u//AwMD/xMTE/8nJyf/MzMz/0NDQ/9PT0//W1tb/2dnZ/9vb + 2//e3t7/4ODg/+Li4v/j4+P/5eXl/+fn5//o6OiX////Af///wHKysrxxcXF/6qqqv+bm5v/cnJy/1ZW + Vv9iYmL/MzMz/0NDQ/8qKir/ISEh/yAgIP8iIiL/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/JCQk/yQk + JP8kJCT/R0dH/729vf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zMzM/8vL + y//Kysr/kZGR/ycnJ/8kJCT/JSUl/zY2Nv8zMzP/lpaW/7u7u//AwMD/xMTE/8jIyP/MzMz/0NDQ/9PT + 0//W1tb/2dnZ/9vb2//d3d3/4ODg/+Li4v/j4+P/5eXl/+bm5v/o6Oj/6enpl////wH///8By8vL8cfH + x/+1tbX/e3t7/1BQUP9/f3//0dHR/4WFhf8mJib/GRkZ/x8fH/8iIiL/IyMj/yMjI/8jIyP/IyMj/yMj + I/8jIyP/IyMj/yMjI/8jIyP/JCQk/yQkJP9LS0v/tbW1/8zMzP/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/8zMzP/IyMj/j4+P/y4uLv8kJCT/IyMj/yIiIv9LS0v/lJSU/729vf/BwcH/xcXF/8jI + yP/MzMz/0NDQ/9PT0//W1tb/2dnZ/9vb2//d3d3/39/f/+Hh4f/j4+P/5eXl/+bm5v/o6Oj/6enp/+rq + 6pf///8B////Ac7OzvHKysr/urq6/1lZWf96enr/xcXF/7y8vP8kJCT/Hx8f/x0dHf8iIiL/IiIi/yIi + Iv8oIiH/PiId/yMiIv8iIiL/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/zMzM/+Dg4P/v7+//8vL + y//Nzc3/zc3N/83Nzf/Nzc3/zMzM/8rKyv+srKz/XV1d/yYmJv8kJCT/IyMj/xsbG/8UFBT/goKC/7u7 + u//CwsL/xcXF/8nJyf/Nzc3/0NDQ/9PT0//W1tb/2dnZ/9vb2//d3d3/39/f/+Hh4f/j4+P/5OTk/+bm + 5v/o6Oj/6enp/+rq6v/r6+uX////Af///wHQ0NDxzc3N/8nJyf+wsLD/t7e3/9LS0v8oKCj/ICAg/x0d + Hf8jIyP/IyMj/yIiIv8jISH/gicW/3UnGf8jIiH/IiIi/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMj + I/8jIyP/JCQk/zAwMP9dXV3/fX19/5OTk/+ZmZn/jo6O/29vb/9HR0f/Jycn/yQkJP8kJCT/IyMj/x0d + Hf8NDQ3/dXV1/7q6uv/CwsL/xsbG/8rKyv/Nzc3/0NDQ/9PT0//W1tb/2dnZ/9vb2//d3d3/39/f/+Hh + 4f/i4uL/5OTk/+bm5v/n5+f/6enp/+rq6v/r6+v/7Ozsl////wH///8B09PT8dDQ0P/MzMz/xcXF/3Z2 + dv88PDz/Hx8f/x8fH/8lJSX/IyMj/yIiIv8iISH/dyYX/44oFv8lIiH/IiIi/yQhIf88Ih7/KCIh/y0i + IP9gJRr/aCYa/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/IyMj/y0tLf8bGxv/cnJy/7i4uP/Dw8P/xsbG/8rKyv/Ozs7/0dHR/9TU1P/W1tb/2dnZ/9vb + 2//d3d3/39/f/+Hh4f/i4uL/5OTk/+bm5v/n5+f/6enp/+rq6v/r6+v/7Ozs/+3t7Zf///8B////AdXV + 1fHS0tL/z8/P/8jIyP9kZGT/NDQ0/yMjI/8kJCT/IyMj/yIiIv8iISH/aCQY/5cpFf+RKBX/fSYW/3kl + Fv+WKBT/jykW/3slFv9uJhn/UyUd/1omHf9GJB3/WSQa/ygiIf8jIyL/IyMj/yMjI/8jIyP/IyMj/yMj + I/8jIyP/JCQk/yQkJP8kJCT/IyMj/yIiIv9FRUX/gICA/729vf/ExMT/x8fH/8vLy//Ozs7/0dHR/9TU + 1P/X19f/2dnZ/9vb2//d3d3/39/f/+Hh4f/j4+P/5OTk/+bm5v/n5+f/6Ojo/+rq6v/r6+v/7Ozs/+3t + 7f/u7u6X////Af///wHY2Njx1dXV/9LS0v/Ly8v/UlJS/ycnJ/8iIiL/IyMj/yIiIv8iIiL/RiMd/7Yr + Ev8zIR7/JiAg/2QlGv+SKBX/LSIg/ykhIP9GIx3/KCIh/2ImG/9EJB7/aSYZ/2IkGf94Jhj/NiMf/yci + Iv8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8kJCT/IyMj/yAgIP8MDAz/Xl5e/7e3t//FxcX/ycnJ/8zM + zP/Pz8//0tLS/9XV1f/X19f/2tra/9zc3P/e3t7/39/f/+Hh4f/j4+P/5OTk/+bm5v/n5+f/6Ojo/+np + 6f/r6+v/7Ozs/+3t7f/u7u7/7+/vl////wH///8B2tra8dfX1//U1NT/ysrK/z4+Pv8iIiL/IyMj/yMj + I/8iIiL/IiIi/yUhIP9dJRv/kicU/1QiGf9QIhn/oyoU/0QiHP+TKBT/fScX/4YmFf9eJRr/LiIg/2ol + Gf+DJxf/bCYZ/2UmG/9yJhj/LCIh/yMiIv8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8NDQ3/TExM/7i4 + uP/IyMj/y8vL/83Nzf/Q0ND/09PT/9bW1v/Z2dn/29vb/93d3f/e3t7/4ODg/+Hh4f/j4+P/5OTk/+bm + 5v/n5+f/6Ojo/+rq6v/r6+v/7Ozs/+3t7f/u7u7/7+/v/+/v75f///8B////Ad3d3fHa2tr/19fX/83N + zf8/Pz//IyMj/yQkJP8jIyP/IyMj/yIiIv8hISH/ISEh/y4hH/9tJhn/gScX/0cjHf+aKRT/OiIe/yEh + If9LIxz/fScX/yUhIf8tIiD/KiIg/1clHP9HIx3/bSca/2smGv88Ix7/LCMh/yMjI/8jIyP/IyMj/ycn + J/8WFhb/RkZG/7S0tP/Kysr/zc3N/8/Pz//S0tL/1NTU/9fX1//a2tr/3Nzc/97e3v/f39//4eHh/+Li + 4v/j4+P/5eXl/+bm5v/n5+f/6Ojo/+rq6v/r6+v/7Ozs/+3t7f/u7u7/7+/v/+/v7//w8PCX////Af// + /wHf39/x3d3d/9ra2v/Y2Nj/vr6+/1xcXP8lJSX/IyMj/yMjI/8iIiL/IiIi/yIiIv8hISH/ISEh/yEh + If8nISD/likV/zAhHv8nIB//iSYU/1skG/92JRf/aCUZ/yIiIf8iIiH/RyMd/3QmGP9dJRv/ayca/zUk + IP8jIyP/IiIi/yMjI/9GRkb/a2tr/7m5uf/Nzc3/z8/P/9HR0f/U1NT/1tbW/9jY2P/b29v/3d3d/9/f + 3//g4OD/4uLi/+Pj4//k5OT/5eXl/+fn5//o6Oj/6enp/+rq6v/r6+v/7Ozs/+3t7f/u7u7/7+/v/+/v + 7//w8PD/8fHxl////wH///8B4eHh8d/f3//d3d3/29vb/9nZ2f/W1tb/paWl/0dHR/8jIyP/IyMj/yIi + Iv8iIiL/IiIi/yIiIv8hISH/ISEh/zkiHv99Jhb/hyYV/14kGv9tJBf/gicX/yQhIP8+Ih3/fCYX/0Ij + Hv9YJRz/hSgX/ykjIv8jIyP/IyMj/yMjI/8TExP/NjY2/62trf/Q0ND/0tLS/9TU1P/W1tb/2NjY/9ra + 2v/c3Nz/3t7e/+Dg4P/i4uL/4+Pj/+Tk5P/l5eX/5+fn/+jo6P/o6Oj/6enp/+rq6v/r6+v/7Ozs/+3t + 7f/u7u7/7+/v//Dw8P/w8PD/8fHx//Ly8pf///8B////AePj4/Hh4eH/39/f/93d3f/c3Nz/2tra/9jY + 2P/Pz8//ioqK/zU1Nf8iIiL/IyMj/yIiIv8iIiL/IiIi/yEhIf8hISH/ISEg/yIhIP9QIxv/qioT/y0h + H/82IR3/nCkU/zojH/8mIiH/YiUa/ysjIf8jIyL/IyMj/yQkJP8YGBj/KCgo/6urq//S0tL/1dXV/9fX + 1//Y2Nj/2tra/9zc3P/e3t7/4ODg/+Li4v/j4+P/5OTk/+Xl5f/n5+f/6Ojo/+jo6P/p6en/6urq/+vr + 6//s7Oz/7e3t/+7u7v/u7u7/7+/v//Dw8P/w8PD/8fHx//Ly8v/y8vKX////Af///wHl5eXx5OTk/+Li + 4v/g4OD/39/f/93d3f/c3Nz/2tra/9jY2P/BwcH/aWlp/ygoKP8iIiL/IiIi/yIiIv8iIiL/ISEh/yEh + If8hISH/KSEg/1kkG/+LJxT/pykT/00kHf8kIiH/fCcX/3QoGv8kIyL/IyMj/yQkJP8cHBz/ICAg/6Cg + oP/U1NT/19fX/9nZ2f/b29v/3Nzc/97e3v/g4OD/4eHh/+Pj4//k5OT/5ubm/+fn5//o6Oj/6Ojo/+np + 6f/q6ur/6+vr/+zs7P/s7Oz/7e3t/+7u7v/v7+//7+/v//Dw8P/x8fH/8fHx//Ly8v/z8/P/8/Pzl/// + /wH///8B5+fn8ebm5v/l5eX/4+Pj/+Li4v/g4OD/39/f/97e3v/c3Nz/29vb/9jY2P+tra3/lpaW/5eX + l/9aWlr/JCQk/yIiIv8iIiL/ISEh/yEhIf8iISH/MiIg/10mG/91Jhj/fSYX/30oGf8mIyL/IyMj/yMj + I/9BQUH/WVlZ/6ampv/X19f/2tra/9zc3P/d3d3/39/f/+Dg4P/i4uL/4+Pj/+Tk5P/m5ub/5+fn/+jo + 6P/o6Oj/6enp/+rq6v/r6+v/7Ozs/+zs7P/t7e3/7u7u/+7u7v/v7+//8PDw//Dw8P/x8fH/8fHx//Ly + 8v/z8/P/8/Pz//T09Jf///8B////Aenp6fHo6Oj/5+fn/+bm5v/k5OT/4+Pj/+Li4v/h4eH/39/f/97e + 3v/d3d3/3Nzc/9vb2//b29v/1NTU/1VVVf8iIiL/IiIi/yIiIv8iIiL/IiIi/yIiIv8kIiL/UCUd/1cm + Hf8mIyL/IyMj/yIiIv8aGhr/ICAg/5WVlf/Z2dn/3d3d/97e3v/f39//4eHh/+Li4v/j4+P/5eXl/+bm + 5v/n5+f/6Ojo/+np6f/q6ur/6urq/+vr6//s7Oz/7Ozs/+3t7f/u7u7/7u7u/+/v7//v7+//8PDw//Hx + 8f/x8fH/8vLy//Ly8v/z8/P/8/Pz//T09P/09PSX////Af///wHr6+vx6urq/+np6f/o6Oj/5+fn/+bm + 5v/l5eX/5OTk/+Pj4//i4uL/4eHh/9/f3//f39//3t7e/93d3f+Xl5f/KSkp/yMjI/8iIiL/IiIi/yIi + Iv8iIiL/IyMj/yMjI/8jIyP/IyMj/yIiIv8eHh7/DQ0N/4ODg//Z2dn/4ODg/+Hh4f/i4uL/4+Pj/+Tk + 5P/l5eX/5ubm/+fn5//o6Oj/6enp/+rq6v/r6+v/6+vr/+zs7P/t7e3/7e3t/+7u7v/u7u7/7+/v/+/v + 7//w8PD/8PDw//Hx8f/x8fH/8vLy//Pz8//z8/P/8/Pz//T09P/09PT/9fX1l////wH///8B7e3t8ezs + 7P/r6+v/6urq/+np6f/o6Oj/5+fn/+bm5v/l5eX/5OTk/+Pj4//j4+P/4uLi/+Hh4f/g4OD/39/f/7m5 + uf9YWFj/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yIiIv8gICD/DQ0N/3p6ev/Z2dn/4+Pj/+Pj + 4//k5OT/5eXl/+bm5v/n5+f/6Ojo/+np6f/p6en/6urq/+vr6//s7Oz/7Ozs/+3t7f/t7e3/7u7u/+/v + 7//v7+//8PDw//Dw8P/w8PD/8fHx//Hx8f/y8vL/8vLy//Pz8//z8/P/9PT0//T09P/19fX/9fX1//b2 + 9pf///8B////Ae7u7vHt7e3/7Ozs/+zs7P/r6+v/6urq/+rq6v/p6en/6Ojo/+fn5//m5ub/5eXl/+Tk + 5P/j4+P/4+Pj/+Li4v/i4uL/39/f/6Kiov8+Pj7/IyMj/yMjI/8jIyP/IyMj/yIiIv9ZWVn/tLS0/6en + p//c3Nz/5OTk/+Xl5f/m5ub/5+fn/+fn5//o6Oj/6enp/+rq6v/r6+v/6+vr/+zs7P/s7Oz/7e3t/+7u + 7v/u7u7/7+/v/+/v7//w8PD/8PDw//Hx8f/x8fH/8fHx//Ly8v/y8vL/8/Pz//Pz8//z8/P/9PT0//T0 + 9P/09PT/9fX1//X19f/29vaX////Af///wHv7+/x7u7u/+7u7v/t7e3/7Ozs/+zs7P/r6+v/6+vr/+rq + 6v/p6en/6Ojo/+fn5//n5+f/5ubm/+Xl5f/l5eX/5OTk/+Tk5P/l5eX/2NjY/4ODg/8xMTH/IiIi/yIi + Iv9NTU3/19fX/+bm5v/m5ub/5ubm/+fn5//o6Oj/6Ojo/+np6f/q6ur/6urq/+vr6//s7Oz/7Ozs/+3t + 7f/t7e3/7u7u/+7u7v/v7+//7+/v//Dw8P/w8PD/8fHx//Hx8f/y8vL/8vLy//Ly8v/y8vL/8/Pz//Pz + 8//09PT/9PT0//T09P/19fX/9fX1//X19f/29vb/9vb2l////wH///8B8PDw8fDw8P/v7+//7u7u/+7u + 7v/t7e3/7e3t/+zs7P/s7Oz/6+vr/+rq6v/q6ur/6enp/+jo6P/o6Oj/5+fn/+fn5//n5+f/5+fn/+fn + 5//m5ub/xMTE/2VlZf9LS0v/0tLS/+jo6P/p6en/6enp/+np6f/p6en/6urq/+rq6v/r6+v/7Ozs/+zs + 7P/t7e3/7e3t/+7u7v/u7u7/7+/v/+/v7//v7+//8PDw//Dw8P/x8fH/8fHx//Ly8v/y8vL/8vLy//Pz + 8//z8/P/8/Pz//T09P/09PT/9PT0//X19f/19fX/9fX1//b29v/29vb/9vb2//f395f///8B////AfHx + 8fHx8fH/8PDw//Dw8P/v7+//7+/v/+7u7v/u7u7/7e3t/+3t7f/s7Oz/7Ozs/+vr6//q6ur/6urq/+rq + 6v/p6en/6enp/+np6f/p6en/6enp/+rq6v/n5+f/4eHh/+rq6v/q6ur/6urq/+vr6//r6+v/6+vr/+zs + 7P/s7Oz/7e3t/+3t7f/u7u7/7u7u/+/v7//v7+//7+/v//Dw8P/w8PD/8PDw//Hx8f/x8fH/8vLy//Ly + 8v/y8vL/8/Pz//Pz8//z8/P/9PT0//T09P/09PT/9fX1//X19f/19fX/9vb2//b29v/29vb/9vb2//f3 + 9//39/eX////Af///wHy8vLx8vLy//Hx8f/x8fH/8PDw//Dw8P/w8PD/7+/v/+/v7//u7u7/7u7u/+3t + 7f/t7e3/7Ozs/+zs7P/s7Oz/7Ozs/+zs7P/r6+v/7Ozs/+zs7P/s7Oz/7Ozs/+zs7P/s7Oz/7Ozs/+zs + 7P/s7Oz/7e3t/+3t7f/t7e3/7u7u/+7u7v/v7+//7+/v/+/v7//w8PD/8PDw//Hx8f/x8fH/8fHx//Hx + 8f/y8vL/8vLy//Pz8//z8/P/8/Pz//T09P/09PT/9PT0//T09P/19fX/9fX1//X19f/29vb/9vb2//b2 + 9v/29vb/9/f3//f39//39/f/9/f3l////wH///8B8/Pz8fPz8//y8vL/8vLy//Ly8v/x8fH/8fHx//Dw + 8P/w8PD/8PDw/+/v7//v7+//7+/v/+7u7v/u7u7/7u7u/+7u7v/t7e3/7u7u/+7u7v/u7u7/7u7u/+7u + 7v/u7u7/7u7u/+7u7v/u7u7/7u7u/+7u7v/u7u7/7+/v/+/v7//w8PD/8PDw//Dw8P/x8fH/8fHx//Hx + 8f/y8vL/8vLy//Ly8v/y8vL/8/Pz//Pz8//z8/P/9PT0//T09P/09PT/9fX1//X19f/19fX/9fX1//b2 + 9v/29vb/9vb2//b29v/39/f/9/f3//f39//39/f/+Pj4//j4+Jf///8BAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAoAAAAgAAAAAABAAABACAAAAAAAAAIAQAAAAAAAAAAAAAAAAAAAAAA////Af// + /wHw8PDj8PDw/+/v7//v7+//7+/v/+7u7v/u7u7/7u7u/+3t7f/t7e3/7e3t/+zs7P/s7Oz/6+vr/+vr + 6//q6ur/6urq/+np6f/p6en/6Ojo/+jo6P/n5+f/5ubm/+bm5v/l5eX/5OTk/+Tk5P/j4+P/4uLi/+Hh + 4f/h4eH/4ODg/9/f3//e3t7/3t7e/93d3f/c3Nz/3Nzc/9vb2//a2tr/2dnZ/9nZ2f/Y2Nj/19fX/9bW + 1v/V1dX/09PT/9LS0v/Q0ND/zs7O/83Nzf/Ly8v/ysrK/8jIyP/Hx8f/xcXF/8TExP/CwsL/wcHB/8DA + wP++vr7/vb29/7u7u/+6urr/uLi4/7e3t/+1tbX/tLS0/7Ozs/+ysrL/sbGx/7Gxsf+wsLD/sLCw/7Cw + sP+wsLD/sLCw/7Gxsf+xsbH/sbGx/7Kysv+ysrL/srKy/7S0tP+0tLT/tbW1/7a2tv+3t7f/uLi4/7m5 + uf+7u7v/u7u7/729vf++vr7/wMDA/8HBwf/BwcH/w8PD/8TExP/FxcX/xsbG/8jIyP/Jycn/ysrK/8vL + y//MzMz/zs7O/8/Pz//Q0ND/0dHR/9PT0//T09P/1dXV/9bW1v/X19f/2NjY/9nZ2f/b29v/3Nzc/97e + 3v/e3t7/39/f/+Hh4f/h4eEx////Af///wH///8B////AfDw8OPv7+//7+/v/+/v7//v7+//7u7u/+7u + 7v/t7e3/7e3t/+zs7P/s7Oz/7Ozs/+vr6//r6+v/6urq/+rq6v/p6en/6enp/+jo6P/o6Oj/5+fn/+fn + 5//m5ub/5eXl/+Tk5P/k5OT/4+Pj/+Li4v/h4eH/4eHh/+Dg4P/f39//3t7e/93d3f/c3Nz/3Nzc/9vb + 2//a2tr/2tra/9nZ2f/Y2Nj/19fX/9bW1v/V1dX/1NTU/9PT0//R0dH/z8/P/83Nzf/MzMz/ysrK/8jI + yP/Hx8f/xcXF/8PDw//BwcH/wMDA/7+/v/+9vb3/vLy8/7q6uv+4uLj/t7e3/7W1tf+zs7P/srKy/7Cw + sP+vr6//rq6u/62trf+tra3/rKys/6urq/+rq6v/q6ur/6urq/+rq6v/rKys/62trf+tra3/ra2t/66u + rv+urq7/sLCw/7CwsP+ysrL/srKy/7Ozs/+1tbX/tra2/7e3t/+5ubn/urq6/7y8vP+9vb3/vr6+/7+/ + v//AwMD/wsLC/8PDw//ExMT/xcXF/8bGxv/IyMj/ycnJ/8vLy//MzMz/zc3N/87Ozv/Pz8//0dHR/9LS + 0v/T09P/1dXV/9bW1v/X19f/2NjY/9nZ2f/b29v/3Nzc/97e3v/f39//39/f/+Dg4DH///8B////Af// + /wH///8B7+/v4+/v7//u7u7/7u7u/+7u7v/t7e3/7e3t/+3t7f/s7Oz/7Ozs/+vr6//r6+v/6urq/+rq + 6v/p6en/6enp/+jo6P/o6Oj/5+fn/+fn5//m5ub/5eXl/+Xl5f/k5OT/4+Pj/+Pj4//i4uL/4eHh/+Dg + 4P/f39//3t7e/93d3f/d3d3/3Nzc/9vb2//a2tr/2dnZ/9nZ2f/Y2Nj/19fX/9bW1v/V1dX/1NTU/9PT + 0//S0tL/0NDQ/87Ozv/MzMz/ysrK/8nJyf/Gxsb/xcXF/8LCwv/BwcH/v7+//729vf+8vLz/urq6/7i4 + uP+2trb/tLS0/7Kysv+wsLD/rq6u/6ysrP+rq6v/qamp/6ioqP+np6f/p6en/6ampv+lpaX/paWl/6Wl + pf+lpaX/paWl/6ampv+mpqb/p6en/6ioqP+oqKj/qamp/6qqqv+rq6v/rKys/62trf+vr6//sLCw/7Gx + sf+ysrL/tLS0/7a2tv+2trb/uLi4/7m5uf+7u7v/vLy8/729vf+/v7//wMDA/8LCwv/CwsL/w8PD/8XF + xf/Gxsb/yMjI/8nJyf/Ly8v/zMzM/83Nzf/Pz8//0NDQ/9HR0f/S0tL/1NTU/9XV1f/W1tb/2NjY/9nZ + 2f/b29v/3Nzc/97e3v/e3t7/39/fMf///wH///8B////Af///wHv7+/j7+/v/+7u7v/u7u7/7u7u/+3t + 7f/t7e3/7Ozs/+zs7P/r6+v/6+vr/+rq6v/q6ur/6enp/+np6f/o6Oj/6Ojo/+fn5//m5ub/5ubm/+Xl + 5f/l5eX/5OTk/+Pj4//i4uL/4eHh/+Hh4f/g4OD/39/f/97e3v/d3d3/3Nzc/9vb2//a2tr/2tra/9nZ + 2f/Y2Nj/19fX/9bW1v/V1dX/1NTU/9PT0//S0tL/0NDQ/8/Pz//Nzc3/y8vL/8rKyv/Hx8f/xsbG/8PD + w//BwcH/v7+//729vf+7u7v/ubm5/7e3t/+1tbX/s7Oz/7Gxsf+urq7/rKys/6mpqf+np6f/paWl/6Oj + o/+ioqL/oaGh/6CgoP+goKD/n5+f/5+fn/+fn5//n5+f/5+fn/+goKD/oaGh/6Ghof+ioqL/o6Oj/6Sk + pP+lpaX/pqam/6enp/+oqKj/qamp/6qqqv+srKz/ra2t/6+vr/+xsbH/srKy/7Ozs/+1tbX/tra2/7i4 + uP+5ubn/u7u7/7y8vP+9vb3/v7+//8DAwP/BwcH/w8PD/8TExP/FxcX/x8fH/8jIyP/Kysr/y8vL/8zM + zP/Ozs7/z8/P/9HR0f/S0tL/1NTU/9XV1f/W1tb/2NjY/9nZ2f/b29v/3Nzc/97e3v/e3t4x////Af// + /wH///8B////Ae7u7uPu7u7/7u7u/+3t7f/t7e3/7Ozs/+zs7P/s7Oz/6+vr/+vr6//q6ur/6urq/+np + 6f/p6en/6Ojo/+jo6P/n5+f/5ubm/+bm5v/l5eX/5eXl/+Tk5P/j4+P/4uLi/+Hh4f/h4eH/4ODg/9/f + 3//e3t7/3d3d/9zc3P/b29v/2tra/9nZ2f/Y2Nj/19fX/9bW1v/V1dX/1NTU/9PT0//S0tL/0NDQ/8/P + z//Ozs7/zMzM/8rKyv/IyMj/x8fH/8TExP/CwsL/v7+//729vf+7u7v/uLi4/7e3t/+0tLT/srKy/7Cw + sP+tra3/qqqq/6enp/+lpaX/oaGh/6CgoP+dnZ3/m5ub/5qamv+ZmZn/mJiY/5iYmP+YmJj/mJiY/5iY + mP+YmJj/mZmZ/5qamv+bm5v/nJyc/52dnf+dnZ3/n5+f/6CgoP+hoaH/oqKi/6Ojo/+lpaX/pqam/6io + qP+qqqr/q6ur/62trf+urq7/sLCw/7Kysv+zs7P/tbW1/7a2tv+4uLj/ubm5/7u7u/+8vLz/vb29/7+/ + v//AwMD/wsLC/8PDw//ExMT/xsbG/8fHx//Jycn/y8vL/8zMzP/Ozs7/z8/P/9HR0f/S0tL/1NTU/9XV + 1f/X19f/2dnZ/9nZ2f/b29v/3Nzc/93d3TH///8B////Af///wH///8B7u7u4+3t7f/t7e3/7e3t/+zs + 7P/s7Oz/7Ozs/+vr6//r6+v/6urq/+np6f/p6en/6Ojo/+jo6P/n5+f/5+fn/+bm5v/l5eX/5eXl/+Tk + 5P/j4+P/4+Pj/+Li4v/h4eH/4ODg/9/f3//e3t7/3d3d/9zc3P/c3Nz/2tra/9nZ2f/Z2dn/19fX/9bW + 1v/V1dX/1NTU/9PT0//S0tL/0dHR/8/Pz//Nzc3/zMzM/8rKyv/IyMj/x8fH/8XFxf/Dw8P/wcHB/76+ + vv+7u7v/ubm5/7a2tv+0tLT/sbGx/66urv+srKz/qamp/6ampv+jo6P/n5+f/5mZmf+BgYH/ioqK/5SU + lP+Tk5P/kZGR/5CQkP+QkJD/kJCQ/5CQkP+QkJD/kZGR/5GRkf+SkpL/k5OT/5WVlf+Wlpb/lpaW/5eX + l/+ZmZn/mpqa/5ycnP+dnZ3/np6e/6CgoP+ioqL/o6Oj/6ampv+np6f/qamp/6urq/+srKz/rq6u/6+v + r/+xsbH/s7Oz/7S0tP+2trb/t7e3/7m5uf+6urr/vLy8/729vf+/v7//wMDA/8HBwf/ExMT/xcXF/8fH + x//Jycn/ysrK/8zMzP/Ozs7/z8/P/9HR0f/S0tL/1NTU/9bW1v/X19f/2dnZ/9ra2v/b29v/3NzcMf// + /wH///8B////Af///wHt7e3j7e3t/+zs7P/s7Oz/7Ozs/+vr6//r6+v/6urq/+rq6v/q6ur/6enp/+np + 6f/o6Oj/5+fn/+bm5v/m5ub/5eXl/+Xl5f/k5OT/4+Pj/+Li4v/i4uL/4ODg/+Dg4P/f39//3t7e/93d + 3f/c3Nz/29vb/9ra2v/Z2dn/2NjY/9fX1//W1tb/1NTU/9PT0//S0tL/0dHR/9DQ0P/Pz8//zc3N/8vL + y//Jycn/yMjI/8bGxv/Dw8P/wsLC/8DAwP++vr7/u7u7/7m5uf+2trb/s7Oz/6+vr/+srKz/qamp/6en + p/+jo6P/n5+f/5ycnP+VlZX/fX19/2RkZP9paWn/enp6/4qKiv+Li4v/iYmJ/4mJif+JiYn/iYmJ/4qK + iv+Kior/i4uL/4yMjP+Ojo7/j4+P/5CQkP+RkZH/kpKS/5SUlP+VlZX/l5eX/5mZmf+ampr/m5ub/56e + nv+fn5//oqKi/6SkpP+mpqb/p6en/6ioqP+rq6v/rKys/66urv+wsLD/sbGx/7Ozs/+0tLT/tra2/7i4 + uP+5ubn/u7u7/7y8vP++vr7/wMDA/8HBwf/Dw8P/xcXF/8fHx//Jycn/ysrK/8zMzP/Ozs7/z8/P/9HR + 0f/S0tL/1NTU/9bW1v/X19f/2dnZ/9ra2v/b29sx////Af///wH///8B////Ae3t7ePs7Oz/7Ozs/+vr + 6//r6+v/6urq/+rq6v/q6ur/6enp/+np6f/o6Oj/5+fn/+fn5//m5ub/5ubm/+Xl5f/k5OT/4+Pj/+Pj + 4//i4uL/4eHh/+Dg4P/f39//3t7e/93d3f/d3d3/29vb/9vb2//Z2dn/2NjY/9jY2P/W1tb/1dXV/9PT + 0//T09P/0tLS/9DQ0P/Pz8//zc3N/8zMzP/Kysr/yMjI/8bGxv/ExMT/wsLC/8DAwP++vr7/vLy8/7m5 + uf+3t7f/tLS0/7Kysv+urq7/qqqq/6enp/+jo6P/n5+f/5ubm/+Xl5f/k5OT/4CAgP9jY2P/YmJi/2Fh + Yf9iYmL/enp6/4ODg/+CgoL/gYGB/4GBgf+CgoL/goKC/4ODg/+EhIT/hoaG/4eHh/+IiIj/iYmJ/4uL + i/+MjIz/jo6O/4+Pj/+RkZH/k5OT/5WVlf+Xl5f/mZmZ/5qamv+dnZ3/n5+f/6Ghof+ioqL/pKSk/6am + pv+oqKj/qqqq/6urq/+tra3/r6+v/7Gxsf+ysrL/tLS0/7a2tv+4uLj/ubm5/7u7u/+9vb3/v7+//8HB + wf/CwsL/xMTE/8bGxv/IyMj/ysrK/8zMzP/Ozs7/z8/P/9HR0f/S0tL/1NTU/9bW1v/X19f/2dnZ/9nZ + 2TH///8B////Af///wH///8B7Ozs4+zs7P/r6+v/6+vr/+vr6//q6ur/6urq/+np6f/p6en/6Ojo/+fn + 5//n5+f/5ubm/+bm5v/l5eX/5OTk/+Pj4//i4uL/4uLi/+Hh4f/g4OD/39/f/97e3v/d3d3/3Nzc/9vb + 2//a2tr/2dnZ/9jY2P/X19f/1tbW/9XV1f/T09P/0tLS/9HR0f/Q0ND/zs7O/8zMzP/Kysr/ycnJ/8fH + x//FxcX/xMTE/8HBwf+/v7//vb29/7u7u/+5ubn/tra2/7S0tP+wsLD/ra2t/6qqqv+lpaX/oqKi/52d + nf+ZmZn/lJSU/5CQkP+MjIz/dnZ2/2FhYf9jY2P/YmJi/2FhYf92dnb/fX19/3x8fP98fHz/e3t7/3x8 + fP98fHz/fX19/35+fv+AgID/gYGB/4ODg/+EhIT/hYWF/4eHh/+JiYn/i4uL/4yMjP+Ojo7/kJCQ/5KS + kv+UlJT/lpaW/5mZmf+bm5v/nZ2d/56env+goKD/oqKi/6SkpP+mpqb/qKio/6qqqv+srKz/ra2t/7Cw + sP+xsbH/s7Oz/7W1tf+2trb/ubm5/7q6uv+9vb3/vr6+/8DAwP/CwsL/xMTE/8bGxv/IyMj/ysrK/8vL + y//Nzc3/z8/P/9HR0f/T09P/1dXV/9bW1v/X19f/2NjYMf///wH///8B////Af///wHr6+vj6+vr/+vr + 6//q6ur/6urq/+np6f/p6en/6Ojo/+jo6P/n5+f/5+fn/+bm5v/l5eX/5eXl/+Tk5P/j4+P/4uLi/+Hh + 4f/h4eH/39/f/9/f3//e3t7/3Nzc/9zc3P/b29v/2tra/9jY2P/X19f/19fX/9XV1f/V1dX/09PT/9LS + 0v/R0dH/z8/P/87Ozv/MzMz/ysrK/8jIyP/Gxsb/xMTE/8LCwv/AwMD/vr6+/7y8vP+5ubn/t7e3/7W1 + tf+ysrL/r6+v/6ysrP+pqan/pKSk/5+fn/+bm5v/lpaW/5GRkf+MjIz/iIiI/4SEhP9ycnL/YWFh/2Rk + ZP9iYmL/YWFh/3Fxcf92dnb/dnZ2/3V1df91dXX/dXV1/3V1df92dnb/eHh4/3p6ev97e3v/fX19/39/ + f/+AgID/goKC/4ODg/+Ghob/h4eH/4mJif+Li4v/jY2N/5CQkP+SkpL/lJSU/5aWlv+YmJj/mpqa/5yc + nP+enp7/oKCg/6Kiov+kpKT/pqam/6ioqP+qqqr/rKys/66urv+wsLD/srKy/7Ozs/+2trb/uLi4/7q6 + uv+8vLz/vr6+/8DAwP/CwsL/xMTE/8bGxv/IyMj/ysrK/8vLy//Nzc3/z8/P/9HR0f/T09P/1dXV/9bW + 1v/X19cx////Af///wH///8B////Aevr6+Pr6+v/6urq/+np6f/p6en/6Ojo/+jo6P/o6Oj/5+fn/+bm + 5v/m5ub/5eXl/+Tk5P/k5OT/4+Pj/+Li4v/h4eH/4ODg/9/f3//e3t7/3t7e/9zc3P/b29v/2tra/9nZ + 2f/Y2Nj/19fX/9bW1v/V1dX/1NTU/9PT0//R0dH/0NDQ/8/Pz//Nzc3/zMzM/8rKyv/IyMj/xsbG/8TE + xP/CwsL/v7+//729vf+7u7v/uLi4/7a2tv+zs7P/sLCw/62trf+rq6v/p6en/6Ojo/+enp7/mZmZ/5SU + lP+Ojo7/iYmJ/4SEhP9/f3//fHx8/21tbf9iYmL/ZWVl/2NjY/9iYmL/bW1t/3BwcP9wcHD/b29v/29v + b/9vb2//b29v/3Fxcf9zc3P/dHR0/3Z2dv94eHj/enp6/3t7e/99fX3/fn5+/4CAgP+CgoL/hISE/4aG + hv+JiYn/i4uL/42Njf+Pj4//kZGR/5SUlP+Wlpb/mJiY/5qamv+cnJz/np6e/6CgoP+jo6P/paWl/6am + pv+pqan/qqqq/62trf+vr6//sbGx/7Ozs/+1tbX/t7e3/7m5uf+8vLz/vr6+/7+/v//CwsL/xMTE/8bG + xv/IyMj/ysrK/8zMzP/Ozs7/z8/P/9HR0f/T09P/1dXV/9bW1jH///8B////Af///wH///8B6urq4+rq + 6v/p6en/6enp/+jo6P/o6Oj/5+fn/+fn5//m5ub/5ubm/+Xl5f/l5eX/5OTk/+Pj4//i4uL/4eHh/+Hh + 4f/f39//3t7e/93d3f/c3Nz/29vb/9ra2v/Z2dn/2NjY/9fX1//W1tb/1dXV/9TU1P/S0tL/0dHR/9DQ + 0P/Ozs7/zc3N/8vLy//Jycn/x8fH/8XFxf/Dw8P/wcHB/7+/v/+9vb3/urq6/7e3t/+1tbX/s7Oz/7Cw + sP+tra3/qamp/6ampv+ioqL/nZ2d/5iYmP+Tk5P/jY2N/4eHh/+CgoL/fX19/3h4eP91dXX/a2tr/2Rk + ZP9mZmb/ZWVl/2NjY/9paWn/ampq/2lpaf9paWn/aWlp/2pqav9ra2v/bW1t/25ubv9wcHD/cnJy/3Nz + c/91dXX/d3d3/3l5ef96enr/fHx8/319ff9/f3//gYGB/4SEhP+Hh4f/iYmJ/4uLi/+NjY3/kJCQ/5KS + kv+UlJT/lpaW/5iYmP+bm5v/nZ2d/5+fn/+hoaH/o6Oj/6ampv+oqKj/qqqq/6ysrP+urq7/sLCw/7Ky + sv+1tbX/t7e3/7m5uf+7u7v/vb29/8DAwP/CwsL/xMTE/8bGxv/IyMj/ysrK/8zMzP/Ozs7/0NDQ/9LS + 0v/U1NT/1dXVMf///wH///8B////Af///wHq6urj6enp/+np6f/o6Oj/6Ojo/+fn5//n5+f/5ubm/+Xl + 5f/l5eX/5OTk/+Tk5P/j4+P/4uLi/+Hh4f/g4OD/39/f/97e3v/d3d3/3Nzc/9vb2//a2tr/2dnZ/9fX + 1//X19f/1tbW/9TU1P/T09P/0tLS/9HR0f/Q0ND/zs7O/8zMzP/Kysr/ycnJ/8fHx//FxcX/w8PD/8HB + wf++vr7/vLy8/7m5uf+2trb/s7Oz/7Gxsf+urq7/rKys/6mpqf+lpaX/oaGh/5ubm/+Xl5f/kZGR/4uL + i/+Ghob/gYGB/3x8fP92dnb/cnJy/29vb/9oaGj/ZWVl/2lpaf9qamr/ampq/2hoaP9kZGT/Y2Nj/2Nj + Y/9kZGT/ZWVl/2ZmZv9oaGj/aWlp/2tra/9tbW3/bm5u/3BwcP9xcXH/c3Nz/3V1df92dnb/eHh4/3p6 + ev98fHz/fn5+/4GBgf+EhIT/hoaG/4mJif+Li4v/jY2N/4+Pj/+RkZH/lJSU/5aWlv+ZmZn/m5ub/56e + nv+fn5//oqKi/6SkpP+mpqb/qKio/6urq/+tra3/r6+v/7Kysv+0tLT/tra2/7m5uf+7u7v/vb29/7+/ + v//CwsL/xMTE/8bGxv/IyMj/ysrK/83Nzf/Pz8//0dHR/9PT0//T09Mx////Af///wH///8B////Aenp + 6ePp6en/6Ojo/+jo6P/n5+f/5+fn/+bm5v/l5eX/5eXl/+Tk5P/k5OT/4+Pj/+Li4v/h4eH/4ODg/9/f + 3//f39//3d3d/9zc3P/b29v/2tra/9nZ2f/Y2Nj/19fX/9bW1v/U1NT/09PT/9LS0v/R0dH/z8/P/87O + zv/MzMz/ysrK/8nJyf/Hx8f/xcXF/8PDw//BwcH/vr6+/7y8vP+5ubn/tra2/7Ozs/+wsLD/rq6u/6ur + q/+oqKj/pKSk/6CgoP+cnJz/lZWV/5CQkP+Li4v/hoaG/39/f/96enr/dnZ2/3Fxcf9ubm7/a2tr/2dn + Z/9nZ2f/a2tr/25ubv9ycnL/cHBw/2dnZ/9fX1//X19f/2BgYP9hYWH/YmJi/2RkZP9lZWX/Z2dn/2ho + aP9qamr/a2tr/21tbf9vb2//cHBw/3Jycv90dHT/dnZ2/3l5ef97e3v/fX19/4CAgP+CgoL/hYWF/4eH + h/+JiYn/i4uL/46Ojv+QkJD/k5OT/5WVlf+YmJj/mpqa/5ycnP+fn5//oaGh/6Ojo/+lpaX/qKio/6qq + qv+tra3/r6+v/7Gxsf+0tLT/tra2/7m5uf+7u7v/vb29/8DAwP/CwsL/xMTE/8fHx//Jycn/y8vL/83N + zf/Pz8//0dHR/9LS0jH///8B////Af///wH///8B6enp4+jo6P/o6Oj/5+fn/+fn5//m5ub/5eXl/+Xl + 5f/k5OT/4+Pj/+Pj4//i4uL/4eHh/+Dg4P/g4OD/3t7e/97e3v/c3Nz/29vb/9ra2v/Z2dn/2NjY/9fX + 1//W1tb/1NTU/9PT0//R0dH/0NDQ/8/Pz//Nzc3/zMzM/8rKyv/Jycn/x8fH/8XFxf/Dw8P/wMDA/76+ + vv+7u7v/uLi4/7W1tf+zs7P/sLCw/62trf+qqqr/p6en/6Ojo/+fn5//mpqa/5WVlf+Pj4//ioqK/4WF + hf97e3v/Y2Nj/11dXf9nZ2f/ampq/2pqav9nZ2f/Z2dn/2lpaf9sbGz/b29v/3Nzc/90dHT/b29v/1xc + XP9bW1v/XFxc/11dXf9eXl7/X19f/2FhYf9iYmL/ZGRk/2VlZf9nZ2f/aWlp/2pqav9sbGz/bW1t/29v + b/9xcXH/dHR0/3Z2dv94eHj/enp6/35+fv+AgID/goKC/4SEhP+Hh4f/ioqK/4yMjP+Ojo7/kZGR/5SU + lP+Wlpb/mJiY/5ubm/+dnZ3/oKCg/6Kiov+kpKT/p6en/6qqqv+tra3/r6+v/7Gxsf+0tLT/tra2/7m5 + uf+7u7v/vr6+/8DAwP/CwsL/xcXF/8fHx//Kysr/zMzM/87Ozv/Q0ND/0NDQMf///wH///8B////Af// + /wHp6enj6Ojo/+fn5//n5+f/5ubm/+Xl5f/l5eX/5OTk/+Pj4//j4+P/4uLi/+Hh4f/g4OD/4ODg/9/f + 3//e3t7/3d3d/9zc3P/a2tr/2dnZ/9jY2P/X19f/1tbW/9TU1P/T09P/0dHR/9DQ0P/Pz8//zc3N/8vL + y//Kysr/yMjI/8fHx//FxcX/w8PD/8DAwP++vr7/u7u7/7i4uP+1tbX/s7Oz/7CwsP+tra3/qamp/6am + pv+ioqL/np6e/5qamv+UlJT/j4+P/4mJif+EhIT/fX19/2NjY/9QUFD/S0tL/01NTf9dXV3/ZWVl/2Vl + Zf9oaGj/a2tr/25ubv9wcHD/c3Nz/3R0dP9wcHD/Wlpa/1dXV/9YWFj/WVlZ/1paWv9bW1v/XV1d/15e + Xv9gYGD/YWFh/2JiYv9kZGT/ZmZm/2dnZ/9paWn/a2tr/21tbf9vb2//cnJy/3R0dP92dnb/eXl5/3t7 + e/9+fn7/gICA/4ODg/+Ghob/iIiI/4uLi/+NjY3/kJCQ/5OTk/+VlZX/mJiY/5qamv+dnZ3/n5+f/6Gh + of+kpKT/p6en/6qqqv+tra3/r6+v/7Gxsf+0tLT/t7e3/7m5uf+7u7v/vr6+/8HBwf/Dw8P/xsbG/8jI + yP/Kysr/zMzM/8/Pz//Q0NAx////Af///wH///8B////Aejo6OPo6Oj/5+fn/+bm5v/m5ub/5eXl/+Tk + 5P/j4+P/4+Pj/+Li4v/h4eH/4ODg/+Dg4P/f39//3t7e/93d3f/c3Nz/2tra/9nZ2f/Y2Nj/19fX/9bW + 1v/U1NT/09PT/9HR0f/Q0ND/z8/P/83Nzf/Ly8v/ycnJ/8jIyP/Gxsb/xMTE/8LCwv/AwMD/vr6+/7u7 + u/+4uLj/tbW1/7Ozs/+wsLD/ra2t/6qqqv+mpqb/oqKi/56env+ZmZn/lJSU/42Njf+IiIj/goKC/319 + ff9ycnL/VFRU/09PT/9JSUn/RUVF/1VVVf9hYWH/ZGRk/2pqav9tbW3/cHBw/3Jycv90dHT/dXV1/3Bw + cP9XV1f/VFRU/1VVVf9WVlb/V1dX/1hYWP9XV1f/S0tL/0lJSf9YWFj/Xl5e/2BgYP9hYWH/Y2Nj/2Vl + Zf9nZ2f/aWlp/2tra/9tbW3/cHBw/3Jycv91dXX/d3d3/3p6ev98fHz/fn5+/4GBgf+EhIT/h4eH/4qK + iv+MjIz/j4+P/5GRkf+UlJT/l5eX/5mZmf+cnJz/np6e/6Ghof+kpKT/p6en/6qqqv+srKz/r6+v/7Ky + sv+0tLT/t7e3/7q6uv+9vb3/v7+//8HBwf/ExMT/xsbG/8nJyf/Ly8v/zs7O/8/PzzH///8B////Af// + /wH///8B6Ojo4+fn5//m5ub/5ubm/+Xl5f/k5OT/5OTk/+Pj4//i4uL/4eHh/+Dg4P/g4OD/39/f/97e + 3v/d3d3/3Nzc/9vb2//Z2dn/2NjY/9fX1//W1tb/1NTU/9PT0//R0dH/0NDQ/8/Pz//Nzc3/y8vL/8nJ + yf/IyMj/xsbG/8TExP/CwsL/wMDA/729vf+7u7v/uLi4/7W1tf+ysrL/sLCw/62trf+qqqr/pqam/6Gh + of+enp7/mZmZ/5OTk/+Ojo7/h4eH/4KCgv98fHz/dnZ2/2xsbP9VVVX/UVFR/0dHR/9DQ0P/UlJS/15e + Xv9nZ2f/bGxs/25ubv9xcXH/dHR0/3d3d/93d3f/cXFx/1NTU/9QUFD/UVFR/1JSUv9TU1P/UlJS/z4+ + Pv8fHx//Hh4e/zExMf9KSkr/Wlpa/15eXv9fX1//YmJi/2NjY/9lZWX/Z2dn/2lpaf9ra2v/bm5u/3Bw + cP9ycnL/dXV1/3h4eP96enr/fX19/4CAgP+Dg4P/hYWF/4iIiP+Li4v/jo6O/5CQkP+Tk5P/lpaW/5mZ + mf+bm5v/np6e/6Ghof+kpKT/p6en/6qqqv+tra3/r6+v/7Kysv+1tbX/uLi4/7q6uv+9vb3/wMDA/8PD + w//FxcX/x8fH/8rKyv/MzMz/zc3NMf///wH///8B////Af///wHn5+fj5+fn/+bm5v/l5eX/5eXl/+Tk + 5P/j4+P/4uLi/+Li4v/h4eH/4ODg/9/f3//e3t7/3d3d/9zc3P/b29v/2tra/9jY2P/X19f/1tbW/9TU + 1P/T09P/0dHR/9DQ0P/Pz8//zc3N/8vLy//Jycn/x8fH/8bGxv/ExMT/wcHB/8DAwP+9vb3/u7u7/7m5 + uf+1tbX/s7Oz/7CwsP+tra3/qqqq/6ampv+jo6P/np6e/5mZmf+UlJT/j4+P/4iIiP+CgoL/fHx8/3Z2 + dv9wcHD/ZmZm/1ZWVv9TU1P/RkZG/0JCQv9PT0//X19f/2lpaf9tbW3/b29v/3Jycv96enr/fn5+/3h4 + eP9xcXH/UVFR/01NTf9OTk7/T09P/09PT/9AQED/ISEh/xoaGv8bGxv/Hh4e/yYmJv88PDz/VFRU/1xc + XP9eXl7/YGBg/2FhYf9jY2P/ZWVl/2dnZ/9qamr/bGxs/25ubv9xcXH/dHR0/3d3d/96enr/fHx8/39/ + f/+BgYH/hISE/4eHh/+Kior/jY2N/5CQkP+Tk5P/lZWV/5mZmf+cnJz/np6e/6Kiov+kpKT/p6en/6qq + qv+tra3/sLCw/7Ozs/+2trb/ubm5/7y8vP+/v7//wcHB/8TExP/Gxsb/ycnJ/8zMzP/MzMwx////Af// + /wH///8B////Aefn5+Pm5ub/5ubm/+Tk5P/k5OT/4+Pj/+Li4v/i4uL/4eHh/+Dg4P/f39//3t7e/93d + 3f/c3Nz/29vb/9ra2v/Z2dn/19fX/9fX1//V1dX/1NTU/9LS0v/Q0ND/z8/P/83Nzf/Ly8v/ycnJ/8fH + x//Gxsb/w8PD/8HBwf+/v7//vb29/7u7u/+4uLj/tbW1/7Kysv+wsLD/ra2t/6mpqf+mpqb/oqKi/5+f + n/+ZmZn/lJSU/46Ojv+IiIj/goKC/3t7e/92dnb/b29v/2lpaf9gYGD/WFhY/1VVVf9ERET/QUFB/0tL + S/9eXl7/a2tr/25ubv9xcXH/enp6/46Ojv+VlZX/fHx8/3Nzc/9PT0//SUlJ/0pKSv9LS0v/PDw8/xsb + G/8TExP/HBwc/x4eHv8dHR3/Hh4e/x4eHv8oKCj/QEBA/1VVVf9bW1v/XV1d/19fX/9hYWH/Y2Nj/2Vl + Zf9oaGj/ampq/21tbf9wcHD/cnJy/3V1df94eHj/e3t7/319ff+AgID/g4OD/4aGhv+JiYn/jIyM/4+P + j/+SkpL/lZWV/5iYmP+bm5v/np6e/6Ghof+kpKT/qKio/6urq/+urq7/sbGx/7W1tf+3t7f/urq6/729 + vf/AwMD/w8PD/8XFxf/IyMj/y8vL/8vLyzH///8B////Af///wH///8B5ubm4+bm5v/l5eX/5OTk/+Pj + 4//i4uL/4uLi/+Hh4f/g4OD/39/f/97e3v/d3d3/3Nzc/9vb2//a2tr/2dnZ/9jY2P/X19f/1dXV/9TU + 1P/S0tL/0dHR/8/Pz//Nzc3/y8vL/8nJyf/IyMj/xcXF/8TExP/BwcH/v7+//729vf+7u7v/uLi4/7W1 + tf+zs7P/r6+v/6ysrP+pqan/pqam/6Ojo/+fn5//mpqa/5SUlP+Pj4//iYmJ/4SEhP99fX3/dnZ2/3Bw + cP9paWn/YmJi/1xcXP9bW1v/V1dX/0ZGRv9FRUX/SkpK/11dXf9sbGz/cHBw/3Z2dv+MjIz/oKCg/4+P + j/9vb2//dnZ2/1dXV/9GRkb/R0dH/z4+Pv8dHR3/EhIS/xgYGP8uLi7/LCws/x4eHv8eHh7/Hh4e/x4e + Hv8hISH/NDQ0/0xMTP9ZWVn/W1tb/11dXf9fX1//YWFh/2RkZP9mZmb/aWlp/2xsbP9ubm7/cXFx/3R0 + dP93d3f/enp6/319ff+AgID/goKC/4aGhv+JiYn/jIyM/4+Pj/+SkpL/lZWV/5iYmP+cnJz/np6e/6Ki + ov+mpqb/qamp/6ysrP+vr6//s7Oz/7a2tv+5ubn/vLy8/76+vv/CwsL/xMTE/8fHx//Kysr/y8vLMf// + /wH///8B////Af///wHm5ubj5eXl/+Tk5P/j4+P/4+Pj/+Li4v/h4eH/4ODg/9/f3//e3t7/3d3d/9zc + 3P/b29v/2tra/9nZ2f/Y2Nj/19fX/9XV1f/U1NT/0tLS/9HR0f/Pz8//zc3N/8zMzP/Kysr/yMjI/8bG + xv/Dw8P/wcHB/7+/v/+9vb3/u7u7/7i4uP+2trb/s7Oz/7CwsP+srKz/qamp/6ampv+jo6P/np6e/5mZ + mf+VlZX/j4+P/4qKiv+EhIT/fn5+/3h4eP9wcHD/ampq/2JiYv9bW1v/WFhY/11dXf9fX1//X19f/1lZ + Wf9MTEz/Xl5e/25ubv92dnb/h4eH/5+fn/+SkpL/VVVV/1ZWVv93d3f/bGxs/05OTv89PT3/JCQk/xMT + E/8YGBj/KCgo/zY2Nv8rKyv/Hh4e/x4eHv8eHh7/Hh4e/x4eHv8eHh7/JSUl/z09Pf9QUFD/WFhY/1tb + W/9dXV3/X19f/2FhYf9kZGT/Z2dn/2pqav9tbW3/cHBw/3Nzc/91dXX/eHh4/3t7e/9+fn7/goKC/4WF + hf+IiIj/i4uL/46Ojv+SkpL/lZWV/5mZmf+cnJz/n5+f/6Ojo/+mpqb/qqqq/62trf+xsbH/tLS0/7e3 + t/+6urr/vb29/8DAwP/Dw8P/xsbG/8nJyf/Kysox////Af///wH///8B////AeXl5ePk5OT/5OTk/+Pj + 4//i4uL/4eHh/+Dg4P/f39//39/f/97e3v/c3Nz/29vb/9ra2v/Z2dn/2NjY/9fX1//W1tb/1NTU/9LS + 0v/R0dH/0NDQ/83Nzf/MzMz/ysrK/8jIyP/Gxsb/xMTE/8HBwf+/v7//vb29/7u7u/+4uLj/tra2/7S0 + tP+wsLD/ra2t/6qqqv+mpqb/o6Oj/6CgoP+ampr/lZWV/5CQkP+JiYn/hISE/35+fv9zc3P/aWlp/2lp + af9kZGT/XFxc/1VVVf9UVFT/YGBg/2NjY/9mZmb/XFxc/09PT/9dXV3/c3Nz/4WFhf+bm5v/lpaW/11d + Xf9MTEz/cHBw/4aGhv92dnb/Y2Nj/ykpKf8WFhb/GBgY/ycnJ/8rKyv/Hx8f/xwcHP8eHh7/Hh4e/x4e + Hv8eHh7/Hh4e/x4eHv8eHh7/Hx8f/ywsLP9DQ0P/VVVV/1lZWf9bW1v/XV1d/2BgYP9jY2P/ZmZm/2lp + af9sbGz/b29v/3Jycv91dXX/eHh4/3t7e/9+fn7/gYGB/4SEhP+IiIj/i4uL/4+Pj/+SkpL/lpaW/5mZ + mf+dnZ3/oaGh/6SkpP+oqKj/q6ur/6+vr/+ysrL/tra2/7m5uf+8vLz/v7+//8LCwv/FxcX/yMjI/8rK + yjH///8B////Af///wH///8B5OTk4+Tk5P/j4+P/4uLi/+Hh4f/g4OD/4ODg/9/f3//e3t7/3d3d/9zc + 3P/b29v/2dnZ/9jY2P/X19f/1tbW/9XV1f/S0tL/0dHR/9DQ0P/Ozs7/zMzM/8rKyv/IyMj/xsbG/8TE + xP/CwsL/wMDA/729vf+7u7v/uLi4/7W1tf+zs7P/sbGx/62trf+qqqr/pqam/6Ojo/+fn5//m5ub/5aW + lv+Pj4//ioqK/4ODg/9+fn7/dHR0/1paWv9NTU3/U1NT/1lZWf9XV1f/UVFR/1RUVP9iYmL/ZWVl/2ho + aP9dXV3/UFBQ/2FhYf+BgYH/mpqa/56env9hYWH/SEhI/2pqav+MjIz/fHx8/5+fn/9nZ2f/HBwc/xcX + F/8lJSX/Kysr/xwcHP8aGhr/HBwc/x4eHv8eHh7/Hh4e/x4eHv8eHh7/Hh4e/x4eHv8eHh7/Hh4e/yMj + I/81NTX/S0tL/1ZWVv9aWlr/XFxc/19fX/9iYmL/ZmZm/2hoaP9ra2v/bm5u/3Fxcf90dHT/d3d3/3t7 + e/9+fn7/gYGB/4WFhf+IiIj/jIyM/4+Pj/+Tk5P/lpaW/5qamv+enp7/oaGh/6ampv+pqan/ra2t/7Gx + sf+0tLT/uLi4/7u7u/++vr7/wcHB/8XFxf/IyMj/ycnJMf///wH///8B////Af///wHj4+Pj4+Pj/+Li + 4v/h4eH/4ODg/9/f3//f39//3t7e/93d3f/c3Nz/29vb/9ra2v/Y2Nj/2NjY/9bW1v/V1dX/09PT/9LS + 0v/Q0ND/zs7O/8zMzP/Kysr/yMjI/8bGxv/ExMT/wsLC/8DAwP+9vb3/u7u7/7i4uP+1tbX/s7Oz/7Cw + sP+urq7/qqqq/6enp/+jo6P/n5+f/5ubm/+Wlpb/kJCQ/4qKiv+EhIT/fX19/3d3d/9eXl7/SkpK/0VF + Rf9BQUH/RUVF/1JSUv9PT0//XFxc/2VlZf9oaGj/ampq/1JSUv9OTk7/bW1t/5eXl/+cnJz/ampq/0dH + R/9mZmb/iYmJ/35+fv+vr6//+vr6/9HR0f84ODj/HR0d/ykpKf8hISH/GRkZ/xsbG/8dHR3/Hh4e/x8f + H/8fHx//Hh4e/x4eHv8eHh7/Hh4e/x4eHv8eHh7/HR0d/x0dHf8lJSX/PT09/09PT/9YWFj/W1tb/15e + Xv9hYWH/ZGRk/2dnZ/9paWn/bGxs/3BwcP9zc3P/dnZ2/3p6ev9+fn7/gYGB/4SEhP+IiIj/i4uL/4+P + j/+Tk5P/l5eX/5ubm/+enp7/o6Oj/6enp/+rq6v/r6+v/7Ozs/+3t7f/urq6/76+vv/BwcH/xMTE/8fH + x//IyMgx////Af///wH///8B////AePj4+Pi4uL/4uLi/+Hh4f/g4OD/39/f/97e3v/d3d3/3Nzc/9vb + 2//a2tr/2dnZ/9jY2P/W1tb/1dXV/9PT0//S0tL/0NDQ/87Ozv/MzMz/ysrK/8nJyf/Hx8f/xcXF/8LC + wv/AwMD/vr6+/7u7u/+5ubn/tbW1/7Ozs/+wsLD/rq6u/6urq/+np6f/pKSk/6CgoP+cnJz/l5eX/5KS + kv+Li4v/hISE/39/f/93d3f/cHBw/1VVVf9MTEz/Q0ND/z4+Pv9BQUH/T09P/1NTU/9jY2P/Z2dn/2pq + av9ra2v/S0tL/0hISP9xcXH/m5ub/2tra/9GRkb/YWFh/4eHh/98fHz/nZ2d//Hx8f/8/Pz/wsLC/zAw + MP8gICD/JSUl/yIiIv8hISH/IiIi/yEhIf8fHx//Hh4e/x4eHv8fHx//Hh4e/x4eHv8eHh7/Hh4e/x4e + Hv8eHh7/Hh4e/x0dHf8hISH/Ly8v/0hISP9XV1f/Wlpa/11dXf9gYGD/ZGRk/2ZmZv9paWn/bGxs/29v + b/9zc3P/dnZ2/3p6ev99fX3/gICA/4WFhf+IiIj/jY2N/5CQkP+UlJT/mZmZ/5ycnP+hoaH/paWl/6mp + qf+tra3/srKy/7a2tv+5ubn/vb29/8DAwP/ExMT/x8fH/8jIyDH///8B////Af///wH///8B4uLi4+Hh + 4f/h4eH/4ODg/9/f3//e3t7/3d3d/9zc3P/b29v/2tra/9nZ2f/Y2Nj/19fX/9bW1v/U1NT/0tLS/9HR + 0f/Ozs7/zc3N/8rKyv/Jycn/x8fH/8XFxf/Dw8P/wMDA/76+vv+7u7v/uLi4/7a2tv+zs7P/sLCw/62t + rf+qqqr/p6en/6Ojo/+fn5//m5ub/5eXl/+RkZH/i4uL/4aGhv9+fn7/eHh4/3BwcP9qamr/VlZW/1BQ + UP9BQUH/Ojo6/z09Pf9NTU3/XFxc/2dnZ/9qamr/bGxs/25ubv9LS0v/R0dH/19fX/9mZmb/RERE/1tb + W/+IiIj/goKC/6CgoP/09PT//Pz8/7y8vP8+Pj7/HBwc/ygoKP8oKCj/ICAg/yIiIv8kJCT/JSUl/yQk + JP8gICD/Hh4e/x8fH/8fHx//Hh4e/x4eHv8eHh7/Hh4e/x4eHv8eHh7/Hh4e/x4eHv8eHh7/IiIi/zY2 + Nv9MTEz/WFhY/1xcXP9fX1//YmJi/2VlZf9oaGj/a2tr/29vb/9ycnL/dnZ2/3l5ef98fHz/gYGB/4SE + hP+JiYn/jY2N/5GRkf+VlZX/mpqa/56env+ioqL/p6en/6ysrP+wsLD/tbW1/7m5uf+9vb3/wMDA/8PD + w//Gxsb/yMjIMf///wH///8B////Af///wHi4uLj4eHh/+Dg4P/f39//3t7e/93d3f/c3Nz/29vb/9ra + 2v/Z2dn/2NjY/9fX1//W1tb/1NTU/9PT0//R0dH/z8/P/83Nzf/Ly8v/ycnJ/8fHx//FxcX/w8PD/8HB + wf++vr7/vLy8/7m5uf+2trb/tLS0/7Gxsf+urq7/qqqq/6enp/+jo6P/n5+f/5ubm/+Wlpb/kZGR/4yM + jP+Ghob/gICA/3l5ef9zc3P/bGxs/2ZmZv9YWFj/UlJS/z8/P/83Nzf/Ozs7/09PT/9kZGT/aWlp/2tr + a/9tbW3/eHh4/2FhYf9LS0v/U1NT/0RERP9XV1f/f39//4aGhv+QkJD/6Ojo///////S0tL/R0dH/xwc + HP8nJyf/KSkp/yIiIv8fHx//IyMj/yQkJP8lJSX/JiYm/yUlJf8iIiL/Hx8f/x8fH/8fHx//Hx8f/x4e + Hv8eHh7/Hh4e/x4eHv8eHh7/Hh4e/x4eHv8eHh7/Hx8f/yoqKv9CQkL/VFRU/1xcXP9fX1//YmJi/2Vl + Zf9oaGj/bGxs/29vb/9ycnL/dnZ2/3l5ef9+fn7/gYGB/4aGhv+Kior/jo6O/5KSkv+Xl5f/nJyc/6Cg + oP+mpqb/qqqq/6+vr/+zs7P/t7e3/7y8vP/AwMD/w8PD/8bGxv/IyMgx////Af///wH///8B////AeHh + 4ePg4OD/4ODg/9/f3//e3t7/3d3d/9zc3P/a2tr/2dnZ/9jY2P/X19f/1tbW/9TU1P/T09P/0tLS/9DQ + 0P/Ozs7/y8vL/8nJyf/Hx8f/xcXF/8PDw//BwcH/vr6+/7y8vP+5ubn/tra2/7S0tP+xsbH/rq6u/6ur + q/+np6f/pKSk/6CgoP+bm5v/lpaW/5CQkP+MjIz/hoaG/4CAgP96enr/c3Nz/25ubv9nZ2f/YWFh/1lZ + Wf9VVVX/PT09/zQ0NP85OTn/TU1N/2ZmZv9ra2v/bW1t/3Z2dv+NjY3/kZGR/15eXv9VVVX/QEBA/15e + Xv+Dg4P/jo6O/+Hh4f/8/Pz/1dXV/1dXV/8cHBz/JiYm/ykpKf8hISH/Hx8f/yIiIv8kJCT/JSUl/yYm + Jv8mJib/Jycn/yYmJv8jIyP/ISEh/x8fH/8fHx//Hx8f/x8fH/8eHh7/Hh4e/x4eHv8eHh7/Hh4e/x4e + Hv8eHh7/Hh4e/yEhIf8wMDD/TExM/1hYWP9eXl7/YWFh/2RkZP9oaGj/a2tr/25ubv9xcXH/dXV1/3p6 + ev99fX3/goKC/4WFhf+Kior/j4+P/5SUlP+ZmZn/np6e/6Ojo/+oqKj/ra2t/7Kysv+3t7f/u7u7/7+/ + v//Dw8P/xsbG/8jIyDH///8B////Af///wH///8B4eHh4+Dg4P/f39//3t7e/93d3f/c3Nz/29vb/9ra + 2v/Z2dn/19fX/9bW1v/U1NT/09PT/9LS0v/Q0ND/zs7O/8zMzP/Kysr/yMjI/8bGxv/Dw8P/wcHB/76+ + vv+8vLz/ubm5/7e3t/+0tLT/sbGx/66urv+rq6v/qKio/6SkpP+goKD/m5ub/5aWlv+RkZH/i4uL/4aG + hv+AgID/enp6/3R0dP9ubm7/aGho/2JiYv9dXV3/W1tb/1paWv9ISEj/QkJC/zo6Ov9KSkr/Z2dn/2xs + bP91dXX/iYmJ/6CgoP+Kior/U1NT/1hYWP9JSUn/PT09/1dXV//X19f//////93d3f9oaGj/Hh4e/yYm + Jv8qKir/Hx8f/x4eHv8hISH/JCQk/yUlJf8mJib/JiYm/yYmJv8mJib/JiYm/yUlJf8kJCT/IiIi/yAg + IP8fHx//Hx8f/x8fH/8fHx//Hh4e/x4eHv8eHh7/Hh4e/x4eHv8eHh7/Hh4e/x4eHv8mJib/Ozs7/1JS + Uv9dXV3/YGBg/2RkZP9nZ2f/ampq/21tbf9xcXH/dXV1/3h4eP99fX3/gYGB/4aGhv+Li4v/kZGR/5eX + l/+bm5v/oaGh/6ampv+srKz/sbGx/7a2tv+7u7v/v7+//8PDw//Gxsb/yMjIMf///wH///8B////Af// + /wHg4ODj4ODg/9/f3//d3d3/3d3d/9vb2//a2tr/2dnZ/9fX1//W1tb/1NTU/9PT0//S0tL/0NDQ/87O + zv/MzMz/ysrK/8jIyP/Gxsb/xMTE/8LCwv+/v7//vb29/7q6uv+2trb/tLS0/7Kysv+urq7/q6ur/6io + qP+lpaX/oaGh/5ycnP+Xl5f/kZGR/4yMjP+Ghob/gYGB/3t7e/90dHT/b29v/2lpaf9jY2P/Xl5e/1lZ + Wf9cXFz/YGBg/2BgYP9YWFj/PT09/0dHR/9oaGj/cnJy/4aGhv+cnJz/kZGR/1dXV/9NTU3/YWFh/1hY + WP9AQED/NTU1/4uLi//W1tb/cHBw/yEhIf8iIiL/Kioq/yEhIf8eHh7/ISEh/yQkJP8lJSX/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yUlJf8mJib/JCQk/yIiIv8gICD/Hx8f/x8fH/8fHx//Hh4e/x4e + Hv8eHh7/Hh4e/x4eHv8eHh7/Hh4e/x4eHv8gICD/Li4u/0pKSv9aWlr/YGBg/2JiYv9lZWX/aGho/2xs + bP9wcHD/dHR0/3l5ef99fX3/goKC/4iIiP+Ojo7/lJSU/5mZmf+fn5//paWl/6urq/+wsLD/tbW1/7q6 + uv++vr7/w8PD/8bGxv/IyMgx////Af///wH///8B////AeDg4OPf39//3t7e/93d3f/b29v/2tra/9nZ + 2f/X19f/1tbW/9TU1P/T09P/0tLS/9DQ0P/Ozs7/zMzM/8rKyv/IyMj/xsbG/8TExP/CwsL/v7+//729 + vf+6urr/t7e3/7S0tP+ysrL/rq6u/6urq/+oqKj/pKSk/6Ghof+dnZ3/mJiY/5KSkv+MjIz/h4eH/4GB + gf97e3v/b29v/1tbW/9dXV3/YmJi/19fX/9ZWVn/VlZW/15eXv9jY2P/ZWVl/1lZWf87Ozv/R0dH/29v + b/+EhIT/nJyc/5WVlf9QUFD/SkpK/3Jycv+CgoL/aWlp/1FRUf8jIyP/GRkZ/zY2Nv8jIyP/ISEh/yoq + Kv8hISH/HR0d/yIiIv8lJSX/JSUl/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JSUl/yQkJP8hISH/Hx8f/x8fH/8fHx//Hx8f/x8fH/8fHx//Hh4e/x4eHv8eHh7/Hh4e/x4e + Hv8eHh7/ISEh/zMzM/9PT0//W1tb/19fX/9jY2P/ZmZm/2pqav9ubm7/dHR0/3l5ef9/f3//hYWF/4uL + i/+SkpL/l5eX/52dnf+jo6P/qamp/7CwsP+0tLT/urq6/76+vv/Dw8P/xsbG/8jIyDH///8B////Af// + /wH///8B39/f497e3v/d3d3/3Nzc/9vb2//a2tr/2NjY/9fX1//V1dX/09PT/9LS0v/Q0ND/zs7O/8zM + zP/Kysr/yMjI/8fHx//ExMT/wsLC/8DAwP+9vb3/u7u7/7i4uP+1tbX/srKy/6+vr/+rq6v/qKio/6Wl + pf+hoaH/nZ2d/5mZmf+UlJT/jo6O/4iIiP+Dg4P/fHx8/3Nzc/9ZWVn/SkpK/0dHR/9OTk7/WFhY/1ZW + Vv9VVVX/YGBg/2RkZP9nZ2f/Wlpa/zo6Ov9KSkr/fX19/5mZmf+YmJj/YGBg/0ZGRv9oaGj/iYmJ/3t7 + e/+wsLD/hISE/x4eHv8RERH/IiIi/yYmJv8eHh7/IiIi/xwcHP8fHx//IyMj/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yUlJf8iIiL/ISEh/x8f + H/8fHx//Hx8f/x8fH/8fHx//Hx8f/x4eHv8eHh7/Hh4e/x4eHv8eHh7/Hh4e/ykpKf8/Pz//VVVV/11d + Xf9hYWH/ZWVl/2pqav9wcHD/dXV1/3x8fP+CgoL/iYmJ/5CQkP+VlZX/nJyc/6Kiov+pqan/r6+v/7Oz + s/+5ubn/vr6+/8PDw//Hx8f/yMjIMf///wH///8B////Af///wHe3t7j3t7e/9zc3P/b29v/2tra/9jY + 2P/X19f/1dXV/9TU1P/S0tL/0NDQ/8/Pz//MzMz/y8vL/8jIyP/Gxsb/xMTE/8LCwv/AwMD/vb29/7u7 + u/+4uLj/tbW1/7Ozs/+vr6//rKys/6ioqP+lpaX/oaGh/52dnf+ZmZn/lJSU/4+Pj/+JiYn/goKC/319 + ff92dnb/ZWVl/05OTv9ISEj/QEBA/0BAQP9QUFD/U1NT/1paWv9jY2P/Z2dn/2hoaP9VVVX/MDAw/09P + T/+Tk5P/mZmZ/2BgYP9FRUX/aGho/4mJif97e3v/r6+v//f39//q6ur/dHR0/xgYGP8fHx//GBgY/xYW + Fv8ZGRn/Hx8f/yQkJP8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yUlJf8kJCT/ISEh/x4eHv8fHx//Hx8f/x8fH/8fHx//Hx8f/x8f + H/8fHx//Hh4e/x4eHv8eHh7/Hh4e/x8fH/8tLS3/RkZG/1hYWP9gYGD/ZWVl/2xsbP9ycnL/eXl5/4CA + gP+Hh4f/jo6O/5SUlP+bm5v/oaGh/6enp/+tra3/s7Oz/7m5uf++vr7/w8PD/8fHx//IyMgx////Af// + /wH///8B////Ad7e3uPd3d3/3Nzc/9ra2v/Z2dn/19fX/9XV1f/U1NT/09PT/9HR0f/Pz8//zc3N/8vL + y//Jycn/x8fH/8XFxf/Dw8P/wMDA/76+vv+7u7v/uLi4/7a2tv+zs7P/sLCw/62trf+pqan/pqam/6Ki + ov+enp7/mZmZ/5WVlf+QkJD/ioqK/4SEhP99fX3/d3d3/3BwcP9hYWH/UFBQ/0dHR/89PT3/PT09/01N + Tf9UVFT/YGBg/2VlZf9oaGj/ampq/1FRUf8rKyv/SkpK/5CQkP9paWn/RUVF/15eXv+IiIj/f39//6mp + qf/z8/P/+vr6/62trf83Nzf/HR0d/yAgIP8YGBj/Ghoa/x8fH/8lJSX/Jycn/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JSUl/yUl + Jf8kJCT/IiIi/yEhIf8fHx//Hx8f/x8fH/8fHx//Hx8f/x8fH/8fHx//Hx8f/x8fH/8fHx//Hx8f/x8f + H/8kJCT/Nzc3/1RUVP9iYmL/ampq/3BwcP93d3f/fn5+/4WFhf+MjIz/kpKS/5mZmf+goKD/pqam/62t + rf+ysrL/uLi4/76+vv/Dw8P/x8fH/8jIyDH///8B////Af///wH///8B3d3d49zc3P/b29v/2dnZ/9jY + 2P/W1tb/1NTU/9PT0//R0dH/0NDQ/83Nzf/Ly8v/ycnJ/8fHx//FxcX/w8PD/8HBwf++vr7/u7u7/7m5 + uf+2trb/s7Oz/7CwsP+tra3/qqqq/6ampv+ioqL/np6e/5qamv+VlZX/kZGR/4uLi/+FhYX/f39//3d3 + d/9xcXH/a2tr/19fX/9TU1P/RkZG/zo6Ov86Ojr/SkpK/1xcXP9lZWX/Z2dn/2lpaf9sbGz/WVlZ/y8v + L/87Ozv/UlJS/0ZGRv9dXV3/g4OD/4KCgv+ZmZn/8fHx//z8/P+/v7//ODg4/xwcHP8oKCj/JCQk/xwc + HP8fHx//JSUl/ycnJ/8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JSUl/yUlJf8kJCT/IyMj/yEhIf8fHx//Hx8f/x8f + H/8fHx//Hx8f/x8fH/8fHx//Hx8f/x8fH/8fHx//Hx8f/x8fH/8gICD/LCws/0RERP9iYmL/bW1t/3V1 + df97e3v/fHx8/4ODg/+Pj4//mJiY/56env+lpaX/q6ur/7Gxsf+4uLj/vr6+/8PDw//Hx8f/yMjIMf// + /wH///8B////Af///wHc3Nzj29vb/9ra2v/Y2Nj/1tbW/9XV1f/U1NT/0dHR/9DQ0P/Ozs7/zMzM/8rK + yv/IyMj/xcXF/8PDw//AwMD/vr6+/7y8vP+5ubn/tra2/7S0tP+xsbH/ra2t/6qqqv+np6f/o6Oj/5+f + n/+bm5v/lpaW/5GRkf+MjIz/hoaG/4CAgP95eXn/cnJy/2xsbP9mZmb/Xl5e/1VVVf9FRUX/Nzc3/zg4 + OP9ISEj/YWFh/2dnZ/9paWn/bGxs/3Z2dv97e3v/QUFB/zY2Nv8wMDD/SkpK/4KCgv+Ghob/mJiY/+rq + 6v/8/Pz/xsbG/0tLS/8aGhr/JiYm/yYmJv8dHR3/ISEh/yYmJv8nJyf/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JSUl/yUlJf8kJCT/JCQk/yQkJP8hISH/Hx8f/x8fH/8fHx//Hx8f/x8fH/8fHx//Hx8f/x8f + H/8fHx//Hx8f/x8fH/8fHx//ICAg/zg4OP9XV1f/b29v/3Fxcf9dXV3/Y2Nj/3l5ef+RkZH/nZ2d/6Oj + o/+qqqr/sbGx/7i4uP+9vb3/w8PD/8fHx//IyMgx////Af///wH///8B////Adzc3OPa2tr/2dnZ/9fX + 1//V1dX/1NTU/9LS0v/Q0ND/zs7O/8zMzP/Kysr/yMjI/8bGxv/ExMT/wcHB/7+/v/+8vLz/ubm5/7e3 + t/+0tLT/sbGx/66urv+rq6v/qKio/6SkpP+goKD/nJyc/5iYmP+Tk5P/jY2N/4iIiP+BgYH/e3t7/3R0 + dP9ubm7/aGho/2NjY/9dXV3/WFhY/0RERP81NTX/NTU1/0VFRf9iYmL/aWlp/2tra/90dHT/i4uL/5mZ + mf9cXFz/ODg4/y8vL/88PDz/dHR0/4eHh//q6ur//v7+/9jY2P9WVlb/Gxsb/yUlJf8pKSn/Hh4e/x8f + H/8kJCT/Jycn/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JSUl/yUlJf8lJSX/JSUl/yMj + I/8hISH/Hx8f/x8fH/8fHx//Hx8f/x8fH/8fHx//Hx8f/x8fH/8fHx//Hx8f/x8fH/8fHx//ISEh/ykp + Kf9ISEj/VVVV/01NTf9fX1//ZWVl/4ODg/+cnJz/o6Oj/6qqqv+wsLD/uLi4/76+vv/Dw8P/x8fH/8jI + yDH///8B////Af///wH///8B2tra49nZ2f/X19f/1tbW/9TU1P/S0tL/0dHR/8/Pz//Nzc3/y8vL/8nJ + yf/Hx8f/xMTE/8LCwv+/v7//vLy8/7q6uv+3t7f/tbW1/7Gxsf+urq7/q6ur/6enp/+lpaX/oKCg/5yc + nP+Xl5f/kpKS/42Njf+IiIj/goKC/3x8fP92dnb/b29v/2lpaf9kZGT/X19f/1xcXP9bW1v/VFRU/09P + T/88PDz/QEBA/2RkZP9ra2v/dHR0/4yMjP+fn5//g4OD/0xMTP8+Pj7/NjY2/ysrK/89PT3/tra2//z8 + /P/c3Nz/UVFR/xkZGf8lJSX/KCgo/x4eHv8fHx//IyMj/yUlJf8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yUlJf8lJSX/JSUl/yQkJP8iIiL/ISEh/yAgIP8fHx//Hh4e/x8f + H/8gICD/ICAg/yAgIP8gICD/ICAg/yAgIP8gICD/ICAg/yAgIP8oKCj/Ojo6/2BgYP9oaGj/f39//5ub + m/+jo6P/q6ur/7Gxsf+5ubn/vr6+/8TExP/Hx8f/yMjIMf///wH///8B////Af///wHa2trj2NjY/9bW + 1v/V1dX/09PT/9HR0f/Pz8//zs7O/8vLy//Jycn/x8fH/8XFxf/Dw8P/wMDA/729vf+6urr/uLi4/7W1 + tf+ysrL/r6+v/6urq/+oqKj/paWl/6Ghof+dnZ3/mZmZ/5OTk/+Ojo7/iYmJ/4ODg/99fX3/c3Nz/2tr + a/9qamr/ZWVl/2BgYP9cXFz/W1tb/15eXv9hYWH/YWFh/zs7O/8zMzP/ZGRk/3Fxcf+Ghob/n5+f/5GR + kf9NTU3/SkpK/2BgYP9DQ0P/NDQ0/ykpKf9LS0v/n5+f/2pqav8cHBz/IiIi/ykpKf8fHx//Gxsb/yEh + If8kJCT/JSUl/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/IyMj/yAgIP8eHh7/Hh4e/yAgIP8gICD/ICAg/yAgIP8gICD/ICAg/yAg + IP8gICD/ICAg/yAgIP8kJCT/Pj4+/2JiYv+BgYH/nJyc/6Ojo/+rq6v/srKy/7m5uf+/v7//xMTE/8fH + x//IyMgx////Af///wH///8B////AdjY2OPX19f/1dXV/9PT0//S0tL/0NDQ/87Ozv/MzMz/ysrK/8jI + yP/Gxsb/w8PD/8HBwf++vr7/u7u7/7i4uP+2trb/srKy/6+vr/+srKz/qKio/6Wlpf+hoaH/np6e/5mZ + mf+UlJT/jo6O/4mJif+EhIT/fX19/3Nzc/9WVlb/TU1N/1ZWVv9fX1//XFxc/1hYWP9bW1v/YWFh/2Rk + ZP9iYmL/OTk5/zIyMv9sbGz/hISE/5ycnP+QkJD/U1NT/0pKSv9ubm7/hoaG/21tbf9SUlL/GRkZ/xIS + Ev8gICD/IyMj/yEhIf8pKSn/IiIi/x8fH/8gICD/IyMj/yUlJf8lJSX/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8lJSX/IyMj/yEh + If8fHx//ICAg/yAgIP8gICD/ICAg/yAgIP8gICD/ICAg/yAgIP8gICD/ICAg/yAgIP8iIiL/R0dH/4KC + gv+cnJz/pKSk/6ysrP+ysrL/urq6/8DAwP/FxcX/yMjI/8jIyDH///8B////Af///wH///8B19fX49bW + 1v/U1NT/0tLS/9DQ0P/Pz8//zc3N/8vLy//IyMj/xsbG/8PDw//CwsL/v7+//7y8vP+5ubn/tra2/7Oz + s/+wsLD/ra2t/6mpqf+mpqb/oqKi/56env+ZmZn/lJSU/5CQkP+Kior/hISE/35+fv91dXX/XFxc/0tL + S/9ERET/QEBA/09PT/9ZWVn/WFhY/15eXv9jY2P/ZWVl/2JiYv8zMzP/MDAw/319ff+ampr/kpKS/1dX + V/9GRkb/a2tr/4uLi/9+fn7/vb29/8rKyv9NTU3/FRUV/xwcHP8dHR3/GBgY/x0dHf8dHR3/ISEh/yMj + I/8kJCT/JSUl/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yUlJf8lJSX/JSUl/yMjI/8iIiL/ISEh/yAgIP8gICD/ICAg/yAg + IP8gICD/ICAg/yAgIP8gICD/ICAg/yEhIf9ERET/hYWF/52dnf+lpaX/rKys/7Ozs/+7u7v/wcHB/8XF + xf/IyMj/ycnJMf///wH///8B////Af///wHW1tbj1dXV/9TU1P/R0dH/z8/P/83Nzf/Ly8v/ycnJ/8fH + x//FxcX/wsLC/7+/v/+8vLz/urq6/7e3t/+0tLT/sbGx/62trf+qqqr/pqam/6Kiov+enp7/mpqa/5aW + lv+QkJD/i4uL/4WFhf9+fn7/eXl5/25ubv9UVFT/TExM/0BAQP88PDz/SUlJ/1ZWVv9bW1v/YmJi/2Vl + Zf9nZ2f/YmJi/ywsLP8sLCz/ioqK/5ycnP9eXl7/RERE/2NjY/+IiIj/enp6/7S0tP/4+Pj/8fHx/39/ + f/8gICD/GRkZ/xUVFf8VFRX/Ghoa/yAgIP8jIyP/JCQk/yUlJf8lJSX/JSUl/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8lJSX/JSUl/yQkJP8jIyP/ISEh/yAgIP8gICD/ICAg/yAgIP8hISH/ISEh/yEhIf8hISH/ISEh/0BA + QP+FhYX/np6e/6enp/+vr6//tra2/76+vv/CwsL/xsbG/8nJyf/Kysox////Af///wH///8B////AdbW + 1uPU1NT/0tLS/9DQ0P/Ozs7/zMzM/8rKyv/Hx8f/xcXF/8PDw//AwMD/vb29/7q6uv+3t7f/tLS0/7Gx + sf+urq7/qqqq/6enp/+jo6P/n5+f/5ubm/+VlZX/kZGR/4uLi/+FhYX/f39//3l5ef90dHT/aWlp/1VV + Vf9NTU3/PT09/zg4OP9GRkb/VVVV/2FhYf9lZWX/aGho/2lpaf9mZmb/LS0t/yUlJf9oaGj/ZmZm/0RE + RP9iYmL/hoaG/319ff+pqan/+vr6//f39/+cnJz/Jycn/xwcHP8kJCT/Ghoa/xsbG/8gICD/IyMj/yQk + JP8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JSUl/yUlJf8kJCT/IiIi/yAg + IP8fHx//Hx8f/yAgIP8hISH/ISEh/yEhIf8hISH/Nzc3/319ff+Xl5f/pqam/7Ozs/+6urr/wMDA/8TE + xP/Hx8f/ysrK/8vLyzH///8B////Af///wH///8B1dXV49PT0//R0dH/z8/P/8zMzP/Kysr/yMjI/8bG + xv/Dw8P/wcHB/76+vv+8vLz/uLi4/7W1tf+ysrL/r6+v/6ysrP+oqKj/pKSk/6CgoP+bm5v/l5eX/5KS + kv+NjY3/hoaG/4GBgf96enr/dXV1/3BwcP9nZ2f/V1dX/05OTv85OTn/NTU1/0NDQ/9XV1f/ZWVl/2dn + Z/9paWn/bGxs/29vb/8zMzP/JSUl/zQ0NP9AQED/Wlpa/4ODg/98fHz/nZ2d/+/v7//7+/v/t7e3/zc3 + N/8cHBz/KCgo/yUlJf8eHh7/ICAg/yMjI/8kJCT/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8kJCT/IiIi/yAgIP8fHx//ICAg/yEhIf8hISH/ISEh/yEh + If8vLy//enp6/42Njf+cnJz/tra2/729vf/BwcH/xMTE/8fHx//Kysr/y8vLMf///wH///8B////Af// + /wHU1NTj0tLS/9DQ0P/Nzc3/y8vL/8nJyf/Gxsb/xMTE/8HBwf+/v7//vLy8/7m5uf+1tbX/srKy/6+v + r/+srKz/qKio/6Wlpf+goKD/m5ub/5aWlv+SkpL/jY2N/4iIiP+BgYH/e3t7/3Z2dv9wcHD/a2tr/2Rk + ZP9ZWVn/UFBQ/zc3N/8yMjL/QUFB/1paWv9oaGj/aWlp/21tbf94eHj/jo6O/11dXf8oKCj/Jycn/zg4 + OP93d3f/gICA/5qamv/19fX//v7+/7m5uf86Ojr/Ghoa/ygoKP8mJib/HR0d/yAgIP8jIyP/JCQk/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yUl + Jf8kJCT/IyMj/yMjI/8hISH/ICAg/x8fH/8gICD/ISEh/ysrK/95eXn/jY2N/5ubm/+6urr/v7+//8PD + w//Gxsb/ycnJ/8zMzP/MzMwx////Af///wH///8B////AdPT0+PR0dH/z8/P/8zMzP/Kysr/x8fH/8XF + xf/Dw8P/wMDA/729vf+6urr/tra2/7Ozs/+wsLD/ra2t/6mpqf+mpqb/oaGh/52dnf+Xl5f/k5OT/46O + jv+JiYn/hISE/319ff93d3f/cnJy/2xsbP9nZ2f/YWFh/1tbW/9RUVH/Pj4+/zc3N/89PT3/W1tb/2lp + af9ra2v/d3d3/42Njf+goKD/bGxs/y4uLv8mJib/KSkp/01NTf+Li4v/5ubm//7+/v/a2tr/RUVF/xoa + Gv8lJSX/KCgo/x8fH/8fHx//IiIi/yQkJP8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yUlJf8lJSX/JiYm/yUlJf8hISH/Hh4e/x8f + H/8hISH/LCws/3p6ev+Ojo7/nZ2d/729vf/BwcH/xMTE/8bGxv/Jycn/zMzM/83NzTH///8B////Af// + /wH///8B0tLS49DQ0P/Ozs7/y8vL/8nJyf/Gxsb/xMTE/8HBwf++vr7/u7u7/7i4uP+0tLT/sbGx/62t + rf+qqqr/pqam/6Kiov+dnZ3/mZmZ/5SUlP+Pj4//ioqK/4WFhf9/f3//dnZ2/3Jycv9tbW3/aGho/2Rk + ZP9eXl7/XV1d/15eXv9eXl7/R0dH/zQ0NP9WVlb/bGxs/3R0dP+NjY3/oKCg/4CAgP9GRkb/Pj4+/ysr + K/8mJib/LCws/3Fxcf/b29v/0dHR/1hYWP8bGxv/JCQk/ykpKf8hISH/Hx8f/yMjI/8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yQkJP8iIiL/Hx8f/x8fH/8pKSn/d3d3/5CQkP+dnZ3/vr6+/8LC + wv/FxcX/yMjI/8vLy//Nzc3/zs7OMf///wH///8B////Af///wHR0dHjz8/P/8zMzP/Kysr/yMjI/8bG + xv/Dw8P/v7+//7y8vP+5ubn/tra2/7Kysv+vr6//q6ur/6enp/+jo6P/n5+f/5mZmf+VlZX/kJCQ/4qK + iv+FhYX/gICA/3Nzc/9cXFz/YmJi/2dnZ/9kZGT/YGBg/1xcXP9fX1//YmJi/2VlZf9ISEj/Kysr/1JS + Uv9zc3P/h4eH/56env+FhYX/S0tL/0xMTP9wcHD/VVVV/yoqKv8gICD/Ghoa/09PT/9nZ2f/ISEh/yMj + I/8oKCj/ICAg/yEhIf8kJCT/Jycn/yYmJv8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8kJCT/IiIi/y0tLf97e3v/kZGR/56env+/v7//xMTE/8fHx//Jycn/zMzM/87Ozv/Pz88x////Af// + /wH///8B////Ac/Pz+POzs7/y8vL/8nJyf/Gxsb/xMTE/8HBwf++vr7/urq6/7e3t/+0tLT/sLCw/6ys + rP+oqKj/pKSk/6CgoP+cnJz/lpaW/5GRkf+MjIz/hoaG/4GBgf91dXX/W1tb/0tLS/9KSkr/UlJS/15e + Xv9cXFz/XFxc/2FhYf9lZWX/Z2dn/0VFRf8pKSn/VlZW/4aGhv+dnZ3/kJCQ/1BQUP9GRkb/bm5u/4iI + iP91dXX/dHR0/yAgIP8LCwv/KSkp/2tra/8pKSn/JSUl/yAgIP8fHx//JCQk/ycnJ/8mJib/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yUlJf8rKyv/WVlZ/42Njf+SkpL/np6e/8DA + wP/FxcX/yMjI/8vLy//Nzc3/z8/P/9DQ0DH///8B////Af///wH///8Bzs7O48zMzP/Kysr/x8fH/8XF + xf/CwsL/v7+//7u7u/+4uLj/tbW1/7Gxsf+urq7/qamp/6Wlpf+hoaH/nJyc/5iYmP+RkZH/jY2N/4aG + hv+AgID/enp6/2RkZP9PT0//SEhI/0NDQ/9ERET/V1dX/1lZWf9gYGD/ZWVl/2dnZ/9paWn/QUFB/yYm + Jv9jY2P/np6e/5OTk/9TU1P/RUVF/2tra/+IiIj/dnZ2/87Ozv/4+Pj/nJyc/x8fH/8eHh7/IiIi/xMT + E/8YGBj/Hh4e/yMjI/8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8lJSX/JiYm/0lJSf+EhIT/k5OT/5OTk/+kpKT/w8PD/8bGxv/Kysr/y8vL/87Ozv/Q0ND/0dHRMf// + /wH///8B////Af///wHNzc3jy8vL/8nJyf/Gxsb/xMTE/8DAwP+9vb3/urq6/7a2tv+zs7P/rq6u/6ur + q/+np6f/oqKi/56env+ZmZn/lJSU/42Njf+IiIj/gICA/3p6ev90dHT/YGBg/1FRUf9GRkb/Pz8//0JC + Qv9VVVX/Wlpa/2RkZP9mZmb/aWlp/2tra/89PT3/Hx8f/1tbW/+ampr/Xl5e/0JCQv9jY2P/hoaG/3p6 + ev+zs7P//Pz8//b29v+NjY3/Hx8f/x0dHf8VFRX/FBQU/x0dHf8gICD/IyMj/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JSUl/yQkJP8kJCT/Hx8f/zg4OP9+fn7/mZmZ/7W1 + tf/Gxsb/yMjI/8vLy//Nzc3/z8/P/9HR0f/S0tIx////Af///wH///8B////AczMzOPKysr/yMjI/8XF + xf/CwsL/vr6+/7u7u/+3t7f/s7Oz/7CwsP+srKz/qKio/6Ojo/+enp7/mZmZ/5SUlP+Pj4//iIiI/4KC + gv96enr/dHR0/25ubv9dXV3/VVVV/0RERP88PDz/Pj4+/1RUVP9gYGD/Z2dn/2lpaf9ra2v/bm5u/0FB + Qf8eHh7/MzMz/1VVVf9BQUH/Y2Nj/4WFhf95eXn/s7Oz//f39//z8/P/lJSU/yIiIv8cHBz/Jycn/x4e + Hv8bGxv/ICAg/yEhIf8kJCT/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yUl + Jf8jIyP/ISEh/w8PD/8CAgL/JSUl/4mJif+xsbH/w8PD/8fHx//Jycn/y8vL/83Nzf/Q0ND/0tLS/9LS + 0jH///8B////Af///wH///8BzMzM48nJyf/Gxsb/w8PD/8DAwP+8vLz/ubm5/7W1tf+xsbH/ra2t/6mp + qf+lpaX/oKCg/5ubm/+VlZX/kJCQ/4qKiv+Dg4P/fX19/3Z2dv9wcHD/a2tr/15eXv9YWFj/Q0ND/zg4 + OP88PDz/VFRU/2RkZP9paWn/a2tr/25ubv97e3v/Xl5e/x8fH/8hISH/NjY2/1hYWP+Dg4P/fHx8/6Gh + of/19fX//v7+/6enp/8wMDD/Ghoa/yYmJv8jIyP/Gxsb/x0dHf8hISH/IyMj/yQkJP8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8lJSX/JCQk/yMjI/8RERH/AwMD/yUlJf9vb2//r6+v/8HB + wf/FxcX/x8fH/8rKyv/MzMz/zs7O/9DQ0P/S0tL/09PTMf///wH///8B////Af///wHLy8vjyMjI/8bG + xv/CwsL/v7+//7u7u/+3t7f/s7Oz/66urv+qqqr/pqam/6Kiov+cnJz/lpaW/5GRkf+Li4v/hYWF/35+ + fv94eHj/cnJy/21tbf9paWn/X19f/1tbW/9CQkL/Nzc3/zk5Of9TU1P/ZmZm/2tra/9ubm7/e3t7/5OT + k/+Hh4f/LCws/x8fH/8wMDD/YWFh/4GBgf+cnJz/7e3t//r6+v++vr7/MTEx/xoaGv8mJib/JSUl/x4e + Hv8fHx//ISEh/yQkJP8kJCT/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8kJCT/JCQk/yQkJP8kJCT/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JSUl/yQk + JP8nJyf/FxcX/wMDA/8eHh7/e3t7/6Ghof+/v7//xMTE/8bGxv/IyMj/ysrK/83Nzf/Pz8//0dHR/9PT + 0//U1NQx////Af///wH///8B////AcrKyuPHx8f/xMTE/8DAwP+9vb3/ubm5/7W1tf+xsbH/rKys/6io + qP+ioqL/np6e/5iYmP+SkpL/jIyM/4aGhv+AgID/eHh4/3Nzc/9ubm7/ampq/2VlZf9fX1//Xl5e/1BQ + UP9JSUn/Nzc3/1BQUP9oaGj/bW1t/3h4eP+SkpL/oKCg/3R0dP8xMTH/Hx8f/yIiIv8zMzP/bGxs/+Xl + 5f/8/Pz/vLy8/0FBQf8ZGRn/JSUl/yQkJP8fHx//ICAg/yIiIv8kJCT/JCQk/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8lJSX/IyMj/xcXF/8DAwP/Hh4e/29vb/+kpKT/vb29/8LC + wv/ExMT/x8fH/8nJyf/Ly8v/zs7O/9DQ0P/S0tL/1NTU/9XV1TH///8B////Af///wH///8ByMjI48bG + xv/Dw8P/v7+//7y8vP+3t7f/s7Oz/6+vr/+qqqr/pqam/6CgoP+bm5v/lJSU/46Ojv+IiIj/goKC/3V1 + df9ubm7/b29v/2xsbP9nZ2f/YmJi/19fX/9hYWH/Y2Nj/1lZWf8yMjL/Q0ND/2hoaP92dnb/jIyM/5+f + n/+AgID/RkZG/0RERP84ODj/HR0d/yEhIf83Nzf/kJCQ/8XFxf9MTEz/GRkZ/yQkJP8lJSX/HR0d/x8f + H/8iIiL/JCQk/yQkJP8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8lJSX/JSUl/ycn + J/8XFxf/BAQE/xEREf9mZmb/np6e/7u7u//CwsL/xMTE/8bGxv/IyMj/y8vL/83Nzf/Pz8//0dHR/9PT + 0//V1dX/1tbWMf///wH///8B////Af///wHIyMjjxMTE/8HBwf+9vb3/urq6/7W1tf+xsbH/rKys/6en + p/+ioqL/m5ub/5aWlv+QkJD/ioqK/4ODg/90dHT/WFhY/09PT/9ZWVn/ZGRk/2RkZP9hYWH/YWFh/2Rk + ZP9nZ2f/W1tb/y4uLv88PDz/b29v/42Njf+hoaH/g4OD/0ZGRv9MTEz/dnZ2/3t7e/9BQUH/ISEh/w8P + D/8UFBT/QEBA/yEhIf8gICD/JiYm/x0dHf8fHx//IiIi/yQkJP8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yUlJf8uLi7/QUFB/y0tLf8hISH/aWlp/6SkpP+7u7v/wcHB/8PD + w//FxcX/x8fH/8rKyv/MzMz/zs7O/9DQ0P/S0tL/1NTU/9bW1v/X19cx////Af///wH///8B////AcbG + xuPExMT/wMDA/729vf+4uLj/s7Oz/6+vr/+pqan/pKSk/5+fn/+ZmZn/kpKS/4uLi/+FhYX/fHx8/2Fh + Yf9PT0//SEhI/0ZGRv9WVlb/YmJi/2BgYP9kZGT/ZmZm/2lpaf9aWlr/Kioq/0NDQ/+CgoL/oKCg/5GR + kf9KSkr/RkZG/29vb/+Ghob/e3t7/8DAwP95eXn/ExMT/xQUFP84ODj/ISEh/xwcHP8eHh7/Hh4e/yIi + Iv8kJCT/JSUl/yUlJf8lJSX/JSUl/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8lJSX/Kioq/0RE + RP9WVlb/e3t7/4KCgv+vr6//u7u7/8DAwP/CwsL/xMTE/8bGxv/IyMj/y8vL/83Nzf/Pz8//0dHR/9PT + 0//V1dX/19fX/9jY2DH///8B////Af///wH///8BxsbG48PDw/+/v7//u7u7/7e3t/+xsbH/rKys/6am + pv+hoaH/nJyc/5WVlf+Ojo7/hoaG/4CAgP92dnb/WVlZ/1FRUf9FRUX/QkJC/1JSUv9gYGD/YmJi/2dn + Z/9paWn/a2tr/1ZWVv8lJSX/RkZG/5WVlf+RkZH/UlJS/0ZGRv9qamr/hYWF/319ff/Kysr//f39/9/f + 3/9CQkL/HBwc/xsbG/8SEhL/FhYW/xwcHP8iIiL/JSUl/yUlJf8lJSX/JSUl/yQkJP8kJCT/JCQk/yQk + JP8jIyP/IyMj/yQkJP8nJyf/Kysr/zAwMP80NDT/NDQ0/zIyMv8uLi7/KSkp/yYmJv8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JSUl/yUlJf8qKir/PT09/1JSUv+IiIj/np6e/7u7u/+/v7//wcHB/8PD + w//FxcX/yMjI/8rKyv/MzMz/zs7O/9DQ0P/S0tL/1NTU/9bW1v/Y2Nj/2dnZMf///wH///8B////Af// + /wHFxcXjwsLC/729vf+5ubn/tbW1/6+vr/+qqqr/pKSk/5+fn/+ZmZn/kZGR/4qKiv+CgoL/e3t7/3Nz + c/9bW1v/U1NT/0FBQf8/Pz//UVFR/2BgYP9mZmb/aWlp/2tra/9tbW3/WFhY/yMjI/81NTX/f39//1ZW + Vv9BQUH/ZmZm/4aGhv96enr/u7u7//n5+f/s7Oz/gICA/xwcHP8fHx//Gxsb/xQUFP8aGhr/ISEh/yYm + Jv8lJSX/JCQk/yQkJP8kJCT/JCQk/yMjI/8jIyP/IyMj/ygoKP85OTn/WVlZ/3Fxcf+EhIT/lZWV/52d + nf+dnZ3/mJiY/46Ojv9+fn7/ampq/09PT/85OTn/JiYm/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yUlJf8jIyP/Hh4e/wsL + C/8UFBT/WVlZ/5aWlv+zs7P/vr6+/8DAwP/Dw8P/xcXF/8fHx//Jycn/y8vL/83Nzf/Pz8//0dHR/9PT + 0//V1dX/19fX/9nZ2f/a2tox////Af///wH///8B////AcTExOPBwcH/vb29/7i4uP+0tLT/rq6u/6io + qP+ioqL/nJyc/5aWlv+Ojo7/hoaG/319ff93d3f/b29v/1xcXP9UVFT/PT09/zs7O/9PT0//Y2Nj/2lp + af9sbGz/bm5u/3Jycv9kZGT/JCQk/yEhIf86Ojr/QEBA/11dXf+FhYX/fn5+/7CwsP/5+fn/9vb2/4eH + h/8kJCT/HBwc/yYmJv8hISH/HR0d/yEhIf8mJib/JiYm/yUlJf8kJCT/IyMj/yMjI/8jIyP/JiYm/zIy + Mv9fX1//jY2N/6ysrP++vr7/xcXF/8nJyf/Ly8v/y8vL/8vLy//Ly8v/y8vL/8nJyf/FxcX/vb29/6ur + q/99fX3/VFRU/zExMf8mJib/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yUlJf8lJSX/IyMj/yMjI/8LCwv/BgYG/0FBQf+Li4v/srKy/729vf/AwMD/wsLC/8TE + xP/Gxsb/yMjI/8vLy//Nzc3/zs7O/9DQ0P/S0tL/1dXV/9bW1v/Y2Nj/2tra/9ra2jH///8B////Af// + /wH///8BxMTE48DAwP+8vLz/t7e3/7Kysv+srKz/p6en/6Ghof+ampr/k5OT/4uLi/+Dg4P/enp6/3R0 + dP9tbW3/X19f/1VVVf86Ojr/ODg4/09PT/9lZWX/bGxs/25ubv9ycnL/goKC/4eHh/8yMjL/Hh4e/ysr + K/9OTk7/gICA/39/f/+qqqr/9vb2//Pz8/+ampr/Hh4e/xoaGv8lJSX/IiIi/x4eHv8iIiL/JiYm/yYm + Jv8lJSX/JCQk/yMjI/8jIyP/IyMj/zAwMP9nZ2f/o6Oj/8XFxf/Ly8v/y8vL/8vLy//Ly8v/y8vL/8vL + y//Ly8v/zMzM/8zMzP/MzMz/zc3N/83Nzf/Nzc3/zc3N/83Nzf/FxcX/m5ub/11dXf8uLi7/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yYmJv8mJib/JiYm/yYmJv8mJib/JSUl/yYmJv8jIyP/CwsL/wYG + Bv85OTn/kJCQ/7Kysv+9vb3/wMDA/8LCwv/ExMT/xsbG/8jIyP/Kysr/zMzM/87Ozv/Q0ND/0tLS/9TU + 1P/V1dX/19fX/9nZ2f/a2tr/29vbMf///wH///8B////Af///wHExMTjwMDA/7u7u/+2trb/sbGx/6ur + q/+mpqb/oKCg/5mZmf+SkpL/iYmJ/4GBgf95eXn/dHR0/25ubv9iYmL/VlZW/0JCQv88PDz/T09P/2dn + Z/9vb2//cXFx/319ff+Xl5f/oaGh/0tLS/8dHR3/IyMj/0BAQP9lZWX/nJyc//Dw8P/6+vr/rKys/zMz + M/8YGBj/JSUl/yEhIf8cHBz/ISEh/yYmJv8mJib/JSUl/yQkJP8jIyP/IyMj/yMjI/9AQED/jY2N/8DA + wP/MzMz/zMzM/8vLy//Ly8v/y8vL/8vLy//Ly8v/y8vL/8vLy//MzMz/zMzM/8zMzP/MzMz/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Ly8v/vLy8/4GBgf89PT3/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8mJib/JiYm/yUlJf8kJCT/Kysr/xISEv8CAgL/Ly8v/4WFhf+tra3/vLy8/7+/v//BwcH/w8PD/8bG + xv/Hx8f/ysrK/8vLy//Nzc3/z8/P/9HR0f/T09P/1dXV/9fX1//Y2Nj/2tra/9vb2//c3Nwx////Af// + /wH///8B////AcPDw+O/v7//u7u7/7W1tf+wsLD/qqqq/6Wlpf+enp7/l5eX/4yMjP+Hh4f/gYGB/3l5 + ef91dXX/b29v/2ZmZv9nZ2f/Z2dn/0lJSf9BQUH/ZWVl/3Jycv9/f3//lZWV/6Kiov91dXX/Ozs7/yws + LP8dHR3/JSUl/zg4OP+rq6v/7+/v/66urv8uLi7/GBgY/yUlJf8jIyP/HBwc/yAgIP8lJSX/JiYm/yUl + Jf8kJCT/IyMj/yMjI/8qKir/XV1d/7W1tf/Nzc3/zc3N/83Nzf/MzMz/zMzM/8vLy//Ly8v/y8vL/8vL + y//Ly8v/y8vL/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/Ly8v/ysrK/7Cw + sP9nZ2f/KSkp/yMjI/8jIyP/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/ycnJ/8PDw//AQEB/zIy + Mv+Hh4f/rKys/729vf+/v7//wcHB/8PDw//FxcX/x8fH/8nJyf/Ly8v/zMzM/8/Pz//Q0ND/0tLS/9TU + 1P/W1tb/19fX/9nZ2f/b29v/3Nzc/93d3TH///8B////Af///wH///8Bw8PD48DAwP+7u7v/tbW1/7Cw + sP+pqan/pKSk/52dnf+Li4v/bW1t/3Nzc/99fX3/e3t7/3h4eP9xcXH/aGho/2pqav9paWn/RUVF/zU1 + Nf9gYGD/e3t7/5OTk/+jo6P/fn5+/0VFRf9MTEz/ZGRk/zY2Nv8aGhr/HBwc/y4uLv9ycnL/Q0ND/xYW + Fv8iIiL/IyMj/xwcHP8fHx//IyMj/yUlJf8lJSX/JCQk/yQkJP8jIyP/KCgo/2lpaf+1tbX/zMzM/8zM + zP/Nzc3/zMzM/8zMzP/MzMz/zMzM/8vLy//Ly8v/y8vL/8vLy//Ly8v/zMzM/8zMzP/MzMz/zMzM/8zM + zP/MzMz/zMzM/8zMzP/Ly8v/y8vL/8vLy//Kysr/ysrK/7u7u/9mZmb/Kioq/yMjI/8jIyP/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yQkJP8pKSn/FxcX/wEBAf8dHR3/fX19/6ioqP+6urr/vr6+/8DAwP/Dw8P/xcXF/8bG + xv/Jycn/y8vL/8zMzP/Ozs7/0NDQ/9LS0v/T09P/1dXV/9fX1//Y2Nj/2tra/9vb2//d3d3/3d3dMf// + /wH///8B////Af///wHDw8Pjv7+//7q6uv+0tLT/r6+v/6mpqf+jo6P/lJSU/21tbf9aWlr/VVVV/19f + X/94eHj/eXl5/3Jycv9sbGz/bm5u/2xsbP9ERET/MzMz/2pqav+Pj4//oqKi/4aGhv9BQUH/SUlJ/3R0 + dP+BgYH/b29v/1BQUP8VFRX/DQ0N/zs7O/9DQ0P/HR0d/yQkJP8bGxv/HR0d/yIiIv8kJCT/JCQk/yQk + JP8kJCT/IyMj/yUlJf9kZGT/u7u7/8rKyv/Ly8v/y8vL/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zM + zP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/Ly8v/y8vL/8vLy//Kysr/ysrK/8rK + yv/Kysr/ycnJ/7W1tf9dXV3/JSUl/yMjI/8jIyP/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yQkJP8lJSX/MzMz/0tLS/9TU1P/SUlJ/4GB + gf+rq6v/urq6/76+vv/AwMD/wsLC/8TExP/Gxsb/yMjI/8rKyv/MzMz/zs7O/8/Pz//R0dH/09PT/9XV + 1f/W1tb/19fX/9nZ2f/a2tr/3Nzc/93d3f/e3t4x////Af///wH///8B////AcPDw+O/v7//urq6/7W1 + tf+vr6//qamp/6Ojo/+Hh4f/Y2Nj/1dXV/9NTU3/UlJS/3h4eP96enr/cXFx/3BwcP9xcXH/bm5u/z8/ + P/8xMTH/eXl5/6Ghof+Hh4f/SkpK/0ZGRv9ubm7/g4OD/4KCgv/R0dH/3d3d/2hoaP8SEhL/IyMj/x0d + Hf8UFBT/GBgY/xwcHP8gICD/IiIi/yQkJP8kJCT/JCQk/yQkJP8jIyP/Q0ND/6+vr//Kysr/ysrK/8vL + y//Ly8v/y8vL/8zMzP/MzMz/zMzM/8zMzP/Nzc3/zc3N/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zM + zP/MzMz/y8vL/8vLy//Ly8v/y8vL/8rKyv/Kysr/ysrK/8rKyv/Kysr/ycnJ/7Gxsf9DQ0P/IyMj/yMj + I/8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/y0tLf9ERET/U1NT/3Nzc/+Kior/rq6u/7u7u/+9vb3/v7+//8LCwv/ExMT/xsbG/8jI + yP/Kysr/y8vL/83Nzf/Pz8//0dHR/9LS0v/U1NT/1dXV/9fX1//Y2Nj/2tra/9vb2//d3d3/3t7e/9/f + 3zH///8B////Af///wH///8BxMTE48DAwP+7u7v/tra2/7CwsP+pqan/o6Oj/4WFhf9nZ2f/VVVV/0hI + SP9PT0//enp6/3l5ef9zc3P/c3Nz/3R0dP9ubm7/Ozs7/ywsLP95eXn/k5OT/01NTf9CQkL/bGxs/4eH + h/97e3v/ycnJ//v7+//d3d3/X19f/xcXF/8YGBj/EhIS/xYWFv8bGxv/ICAg/yIiIv8jIyP/JCQk/yQk + JP8kJCT/JCQk/zAwMP+Hh4f/yMjI/8vLy//Ly8v/y8vL/8vLy//Ly8v/zMzM/8zMzP/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zMzM/8zMzP/MzMz/zMzM/8zMzP/Ly8v/y8vL/8vLy//Ly8v/ysrK/8rK + yv/Kysr/ysrK/8rKyv/Kysr/ycnJ/4qKiv8uLi7/IyMj/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yUlJf8lJSX/JSUl/yUlJf8lJSX/JCQk/yMjI/8mJib/HR0d/x8fH/9FRUX/enp6/56e + nv+3t7f/vb29/7+/v//BwcH/w8PD/8XFxf/Hx8f/ycnJ/8vLy//Nzc3/zs7O/9DQ0P/S0tL/1NTU/9XV + 1f/W1tb/2NjY/9nZ2f/b29v/3Nzc/93d3f/f39//39/fMf///wH///8B////Af///wHExMTjwcHB/7y8 + vP+2trb/sbGx/6mpqf+jo6P/iIiI/2tra/9TU1P/RERE/0xMTP95eXn/d3d3/3V1df92dnb/d3d3/3Nz + c/8+Pj7/JCQk/0xMTP9RUVH/QUFB/2VlZf+Hh4f/eXl5/8fHx//+/v7/6Ojo/2RkZP8aGhr/Hh4e/yQk + JP8bGxv/HBwc/yEhIf8jIyP/IyMj/yQkJP8kJCT/JCQk/yQkJP8kJCT/XFxc/76+vv/MzMz/zMzM/8zM + zP/MzMz/zMzM/8zMzP/MzMz/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/8zM + zP/MzMz/zMzM/8vLy//Ly8v/y8vL/8vLy//Kysr/ysrK/8rKyv/Kysr/ysrK/8vLy//Ly8v/vLy8/1dX + V/8lJSX/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JSUl/yUlJf8lJSX/JSUl/yQk + JP8jIyP/IiIi/xkZGf8EBAT/ExMT/21tbf+goKD/uLi4/7y8vP++vr7/wcHB/8PDw//FxcX/x8fH/8nJ + yf/Kysr/zc3N/87Ozv/Q0ND/0dHR/9PT0//V1dX/1tbW/9jY2P/Z2dn/2tra/9vb2//d3d3/3t7e/9/f + 3//g4OAx////Af///wH///8B////AcTExOPBwcH/vb29/7i4uP+ysrL/q6ur/6SkpP+Hh4f/bm5u/1BQ + UP9CQkL/TU1N/3t7e/93d3f/eHh4/3h4eP97e3v/g4OD/01NTf8iIiL/MDAw/0RERP9gYGD/hYWF/3V1 + df+vr6//+Pj4//Hx8f+IiIj/Hh4e/xwcHP8lJSX/Hx8f/x0dHf8gICD/IiIi/yMjI/8kJCT/JCQk/yQk + JP8kJCT/JCQk/yUlJf+SkpL/zMzM/83Nzf/Nzc3/zc3N/8zMzP/MzMz/zMzM/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zs7O/87Ozv/Ozs7/zc3N/83Nzf/Nzc3/zc3N/8zMzP/MzMz/zMzM/8vLy//Ly8v/y8vL/8vL + y//Ly8v/y8vL/8vLy//Ly8v/y8vL/8zMzP/Jycn/hoaG/ywsLP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8lJSX/JSUl/yUlJf8lJSX/JCQk/yMjI/8bGxv/BAQE/wcHB/9RUVH/mZmZ/7S0 + tP+8vLz/vr6+/8DAwP/Dw8P/xcXF/8fHx//IyMj/ysrK/8zMzP/Ozs7/0NDQ/9HR0f/T09P/1NTU/9bW + 1v/X19f/2NjY/9ra2v/b29v/3d3d/97e3v/f39//4ODg/+Hh4TH///8B////Af///wH///8BxMTE48LC + wv++vr7/uLi4/7Ozs/+tra3/pqam/4iIiP9xcXH/T09P/0JCQv9LS0v/e3t7/3p6ev96enr/fX19/4iI + iP+enp7/eXl5/yUlJf8sLCz/Wlpa/3x8fP92dnb/srKy//j4+P/w8PD/ioqK/yIiIv8bGxv/JSUl/x8f + H/8cHBz/ICAg/yIiIv8jIyP/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/MjIy/7q6uv/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/87Ozv/Ozs7/zs7O/87Ozv/Ozs7/zc3N/83N + zf/Nzc3/zc3N/8zMzP/MzMz/y8vL/8vLy//Ly8v/y8vL/8vLy//Ly8v/y8vL/8zMzP/MzMz/zMzM/83N + zf+urq7/OTk5/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JSUl/yUlJf8lJSX/JSUl/yQk + JP8iIiL/Gxsb/wYGBv8ODg7/UVFR/5mZmf+1tbX/u7u7/76+vv/AwMD/wsLC/8TExP/Hx8f/ycnJ/8rK + yv/MzMz/zs7O/9DQ0P/R0dH/09PT/9TU1P/V1dX/2NjY/9nZ2f/a2tr/29vb/9zc3P/e3t7/39/f/+Dg + 4P/h4eH/4eHhMf///wH///8B////Af///wHExMTjwsLC/76+vv+6urr/tbW1/66urv+oqKj/ioqK/3d3 + d/9oaGj/Xl5e/05OTv94eHj/fX19/35+fv+IiIj/mpqa/5+fn/9kZGT/KCgo/yAgIP9KSkr/aWlp/5WV + lf/29vb/+vr6/56env8oKCj/GRkZ/yUlJf8hISH/HBwc/yAgIP8iIiL/IyMj/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP9LS0v/ysrK/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83N + zf/Ozs7/zs7O/87Ozv/Ozs7/zs7O/87Ozv/Ozs7/zs7O/83Nzf/Nzc3/zMzM/8zMzP/MzMz/zMzM/8zM + zP/Ly8v/y8vL/8vLy//MzMz/zMzM/83Nzf/Nzc3/zc3N/8HBwf9OTk7/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8lJSX/JSUl/yUlJf8kJCT/JSUl/x8fH/8HBwf/BgYG/05OTv+Pj4//r6+v/7u7 + u/+9vb3/wMDA/8LCwv/ExMT/xsbG/8jIyP/Kysr/zMzM/87Ozv/Pz8//0dHR/9PT0//U1NT/1dXV/9fX + 1//Y2Nj/2tra/9vb2//d3d3/3d3d/97e3v/g4OD/4eHh/+Li4v/i4uIx////Af///wH///8B////AcTE + xOPCwsL/v7+//7u7u/+3t7f/sbGx/6qqqv+Kior/e3t7/3x8fP9sbGz/Pj4+/1lZWf9+fn7/iIiI/5ub + m/+jo6P/bm5u/z8/P/9GRkb/MTEx/yYmJv9JSUn/YGBg/7Gxsf+qqqr/Ly8v/xgYGP8kJCT/IiIi/x0d + Hf8fHx//IiIi/yMjI/8jIyP/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/2BgYP/MzMz/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Ozs7/zs7O/87Ozv/Ozs7/zs7O/87O + zv/Ozs7/zc3N/83Nzf/Nzc3/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zc3N/83N + zf/Nzc3/ysrK/11dXf8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yUlJf8lJSX/JCQk/yQk + JP8fHx//CQkJ/wcHB/9FRUX/kJCQ/62trf+6urr/vLy8/7+/v//BwcH/xMTE/8bGxv/IyMj/ysrK/8zM + zP/Ozs7/0NDQ/9HR0f/T09P/1NTU/9XV1f/X19f/2NjY/9ra2v/b29v/3Nzc/93d3f/e3t7/4ODg/+Hh + 4f/i4uL/4+Pj/+Pj4zH///8B////Af///wH///8BxcXF48LCwv+/v7//vLy8/7i4uP+zs7P/qqqq/4iI + iP9+fn7/fn5+/2lpaf83Nzf/VlZW/4aGhv+YmJj/oaGh/3x8fP8+Pj7/TU1N/3h4eP9oaGj/NjY2/xkZ + Gf8TExP/IyMj/z4+Pv8eHh7/IiIi/yQkJP8cHBz/Hh4e/yIiIv8jIyP/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/aGho/8zMzP/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Ozs7/zs7O/87Ozv/Ozs7/zs7O/83Nzf/Nzc3/zc3N/83Nzf/MzMz/zMzM/8zM + zP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/Nzc3/zc3N/83Nzf/Nzc3/a2tr/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8lJSX/JSUl/yQkJP8mJib/NjY2/y0tLf8aGhr/Q0ND/5GRkf+urq7/ubm5/7y8 + vP+/v7//wcHB/8PDw//FxcX/yMjI/8rKyv/MzMz/zc3N/8/Pz//R0dH/09PT/9TU1P/V1dX/19fX/9jY + 2P/Z2dn/29vb/9zc3P/d3d3/3t7e/9/f3//g4OD/4eHh/+Li4v/j4+P/5OTkMf///wH///8B////Af// + /wHFxcXjwsLC/7+/v/+8vLz/uLi4/7S0tP+jo6P/hISE/4CAgP+AgID/aWlp/zY2Nv9cXFz/l5eX/6Oj + o/+AgID/RUVF/0lJSf9ycnL/g4OD/4ODg/+1tbX/S0tL/w4ODv8iIiL/Ozs7/x8fH/8eHh7/Hh4e/x4e + Hv8jIyP/JSUl/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP9hYWH/zMzM/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zM + zP/MzMz/zc3N/8vLy/9qamr/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yUlJf8kJCT/JCQk/zQ0 + NP9MTEz/X19f/2pqav+SkpL/s7Oz/7m5uf+7u7v/vr6+/8DAwP/Dw8P/xcXF/8fHx//Kysr/zMzM/83N + zf/Pz8//0dHR/9PT0//U1NT/1dXV/9fX1//Y2Nj/2dnZ/9ra2v/c3Nz/3d3d/97e3v/f39//4ODg/+Hh + 4f/i4uL/4+Pj/+Tk5P/k5OQx////Af///wH///8B////AcbGxuPDw8P/wMDA/7y8vP+5ubn/sbGx/5KS + kv+CgoL/goKC/4GBgf9lZWX/NDQ0/1xcXP+ioqL/iIiI/0VFRf9ERET/dHR0/4SEhP+BgYH/3t7e//z8 + /P+wsLD/Li4u/ycnJ/8bGxv/FBQU/xoaGv8gICD/JSUl/yYmJv8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/1FRUf/Ly8v/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zMzM/8zM + zP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/x8fH/1xcXP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yMjI/8jIyP/LS0t/0RERP9oaGj/hoaG/6+vr/+5ubn/vLy8/76+ + vv/AwMD/wsLC/8TExP/Hx8f/ycnJ/8vLy//Nzc3/z8/P/9DQ0P/S0tL/1NTU/9XV1f/X19f/2NjY/9nZ + 2f/a2tr/3Nzc/93d3f/e3t7/39/f/+Dg4P/h4eH/4uLi/+Pj4//k5OT/5eXl/+Xl5TH///8B////Af// + /wH///8BxsbG48TExP/BwcH/vb29/7q6uv+np6f/h4eH/4ODg/+Dg4P/g4OD/2VlZf8zMzP/Q0ND/4CA + gP9MTEz/QkJC/2hoaP+Hh4f/enp6/9DQ0P/9/f3/4ODg/1VVVf8ZGRn/Hx8f/xkZGf8WFhb/Hh4e/yUl + Jf8mJib/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/Ojo6/8HB + wf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zM + zP/MzMz/zMzM/8zMzP+8vLz/R0dH/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8iIiL/IiIi/xAQ + EP8GBgb/NjY2/4GBgf+hoaH/ubm5/7u7u/++vr7/wMDA/8LCwv/ExMT/xsbG/8nJyf/Ly8v/zc3N/8/P + z//Q0ND/0tLS/9TU1P/V1dX/19fX/9jY2P/Z2dn/2tra/9zc3P/d3d3/3t7e/9/f3//g4OD/4eHh/+Li + 4v/j4+P/5OTk/+Xl5f/l5eX/5ubmMf///wH///8B////Af///wHHx8fjxMTE/8HBwf++vr7/u7u7/5iY + mP+EhIT/hYWF/4WFhf+IiIj/dnZ2/zc3N/8sLCz/RUVF/0NDQ/9paWn/hYWF/319ff/IyMj/+/v7/+Dg + 4P9lZWX/FhYW/x0dHf8kJCT/Hh4e/x8fH/8jIyP/JSUl/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8mJib/n5+f/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/8zM + zP/MzMz/zMzM/8zMzP/MzMz/zMzM/8vLy//Ly8v/y8vL/8vLy//Ly8v/ysrK/5ycnP8yMjL/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/IiIi/yEhIf8TExP/AwMD/yoqKv+BgYH/qamp/7i4uP+8vLz/vr6+/8DA + wP/CwsL/xMTE/8fHx//Jycn/y8vL/83Nzf/Pz8//0dHR/9PT0//U1NT/1dXV/9fX1//Y2Nj/2dnZ/9vb + 2//c3Nz/3d3d/97e3v/f39//4ODg/+Hh4f/i4uL/4+Pj/+Tk5P/l5eX/5eXl/+bm5v/m5uYx////Af// + /wH///8B////AcjIyOPFxcX/wsLC/7+/v/+8vLz/k5OT/4WFhf+Ghob/iIiI/5KSkv+Ojo7/QkJC/yoq + Kv9eXl7/cHBw/4ODg/93d3f/vr6+//n5+f/n5+f/dHR0/xwcHP8cHBz/JSUl/x4eHv8fHx//JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP9wcHD/xsbG/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/8zMzP/MzMz/zMzM/8zMzP/Ly8v/y8vL/8vL + y//Ly8v/y8vL/8vLy//FxcX/eHh4/ykpKf8kJCT/JCQk/yQkJP8kJCT/JCQk/yMjI/8hISH/ExMT/wMD + A/8bGxv/dHR0/6Wlpf+4uLj/vLy8/76+vv/AwMD/wsLC/8TExP/Gxsb/ycnJ/8vLy//Nzc3/z8/P/9DQ + 0P/S0tL/09PT/9XV1f/X19f/2NjY/9nZ2f/a2tr/3Nzc/93d3f/e3t7/39/f/+Dg4P/h4eH/4uLi/+Pj + 4//j4+P/5OTk/+Xl5f/m5ub/5+fn/+fn5zH///8B////Af///wH///8ByMjI48bGxv/ExMT/wcHB/729 + vf+SkpL/hoaG/4iIiP+RkZH/oKCg/5eXl/9HR0f/JSUl/1JSUv+Li4v/gICA/66urv/6+vr/8fHx/3x8 + fP8eHh7/Gxsb/yUlJf8fHx//Hh4e/yIiIv8kJCT/JCQk/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/z4+Pv+np6f/zMzM/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zMzM/8zMzP/MzMz/zMzM/8vLy//Ly8v/y8vL/8vLy//Ly8v/y8vL/7CwsP9JSUn/JCQk/yQk + JP8kJCT/JCQk/yQkJP8jIyP/IyMj/xgYGP8EBAT/ExMT/2dnZ/+ampr/tra2/7y8vP++vr7/wMDA/8LC + wv/ExMT/xsbG/8nJyf/Ly8v/zMzM/8/Pz//Q0ND/0tLS/9PT0//U1NT/1tbW/9fX1//Z2dn/2tra/9zc + 3P/d3d3/3t7e/9/f3//g4OD/4eHh/+Li4v/j4+P/4+Pj/+Tk5P/l5eX/5ubm/+fn5//n5+f/5+fnMf// + /wH///8B////Af///wHJycnjx8fH/8XFxf/CwsL/vr6+/5KSkv+JiYn/kZGR/6CgoP+fn5//Y2Nj/zo6 + Ov8sLCz/Kioq/21tbf+QkJD/w8PD/+zs7P+RkZH/Hh4e/xoaGv8kJCT/ICAg/x0dHf8gICD/IyMj/yMj + I/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/KCgo/2dnZ//CwsL/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zMzM/8zMzP/MzMz/zMzM/8vL + y//Ly8v/y8vL/8vLy//Gxsb/ZmZm/ycnJ/8kJCT/JCQk/yQkJP8kJCT/IyMj/yIiIv8XFxf/BAQE/xkZ + Gf9oaGj/np6e/7S0tP+8vLz/vr6+/8DAwP/CwsL/xMTE/8fHx//IyMj/y8vL/8zMzP/Ozs7/0NDQ/9LS + 0v/T09P/1NTU/9bW1v/X19f/2dnZ/9ra2v/c3Nz/3d3d/97e3v/f39//4ODg/+Hh4f/i4uL/4+Pj/+Pj + 4//k5OT/5eXl/+bm5v/n5+f/5+fn/+jo6P/o6Ogx////Af///wH///8B////AcrKyuPIyMj/xsbG/8PD + w/+/v7//kpKS/5CQkP+dnZ3/o6Oj/3R0dP88PDz/Tk5O/2FhYf8vLy//LCws/z4+Pv8+Pj7/cHBw/zAw + MP8ZGRn/IyMj/yEhIf8dHR3/ICAg/yIiIv8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMj + I/8jIyP/IyMj/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/Li4u/5OTk//MzMz/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zMzM/8zMzP/MzMz/y8vL/8vLy//Ly8v/ycnJ/56env8xMTH/JCQk/yQk + JP8kJCT/IyMj/yMjI/8mJib/ISEh/wcHB/8KCgr/YWFh/5mZmf+2trb/vLy8/76+vv/AwMD/wsLC/8TE + xP/Gxsb/yMjI/8rKyv/MzMz/zs7O/9DQ0P/S0tL/09PT/9TU1P/W1tb/19fX/9nZ2f/a2tr/29vb/9zc + 3P/e3t7/39/f/+Dg4P/h4eH/4eHh/+Pj4//j4+P/5OTk/+Xl5f/l5eX/5ubm/+fn5//o6Oj/6Ojo/+np + 6TH///8B////Af///wH///8By8vL48nJyf/Hx8f/xcXF/7+/v/+YmJj/np6e/6Ojo/9ycnL/PT09/1JS + Uv96enr/fX19/3p6ev9RUVH/ERER/xISEv9MTEz/Pz8//yEhIf8iIiL/Hx8f/x8fH/8iIiL/IyMj/yMj + I/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/Nzc3/5WVlf/IyMj/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/MzMz/zMzM/8zM + zP/MzMz/y8vL/8rKyv+dnZ3/QEBA/yQkJP8kJCT/JCQk/yQkJP8jIyP/KSkp/0FBQf9RUVH/U1NT/2lp + af+qqqr/tra2/729vf+/v7//wcHB/8PDw//ExMT/x8fH/8jIyP/Kysr/zMzM/87Ozv/Q0ND/0tLS/9PT + 0//U1NT/1tbW/9fX1//Z2dn/2tra/9vb2//d3d3/3d3d/9/f3//g4OD/4eHh/+Li4v/i4uL/5OTk/+Tk + 5P/l5eX/5ubm/+bm5v/n5+f/6Ojo/+np6f/p6en/6enpMf///wH///8B////Af///wHMzMzjysrK/8jI + yP/Gxsb/wcHB/6Ojo/+mpqb/fX19/0FBQf9HR0f/dnZ2/4GBgf+Ghob/4eHh/9PT0/9MTEz/KSkp/zMz + M/8gICD/Ghoa/xwcHP8gICD/ISEh/yIiIv8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMj + I/8jIyP/IyMj/yMjI/8jIyP/IyMj/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8lJSX/QEBA/5aW + lv/Ly8v/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/MzMz/zMzM/8zMzP/Kysr/qamp/0lJSf8mJib/JCQk/yQk + JP8kJCT/IyMj/yQkJP8zMzP/SkpK/1tbW/94eHj/mJiY/7q6uv+8vLz/v7+//8HBwf/Dw8P/xcXF/8bG + xv/IyMj/ysrK/8zMzP/Ozs7/0NDQ/9LS0v/T09P/1NTU/9bW1v/X19f/2dnZ/9ra2v/c3Nz/3Nzc/93d + 3f/e3t7/39/f/+Dg4P/h4eH/4uLi/+Pj4//k5OT/5eXl/+bm5v/m5ub/5+fn/+jo6P/o6Oj/6enp/+rq + 6v/q6uox////Af///wH///8B////Ac3NzePLy8v/ycnJ/8fHx//ExMT/rKys/4SEhP9ERET/R0dH/29v + b/+CgoL/hYWF/+Li4v/7+/v/wMDA/zY2Nv8eHh7/HR0d/xISEv8ZGRn/Hh4e/yEhIf8iIiL/IyMj/yMj + I/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMj + I/8jIyP/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/MzMz/4KCgv+6urr/zMzM/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/8zM + zP/MzMz/v7+//4qKiv9AQED/JSUl/yQkJP8kJCT/JCQk/yMjI/8iIiL/ICAg/xISEv8nJyf/YWFh/42N + jf+ysrL/vb29/7+/v//BwcH/w8PD/8XFxf/Hx8f/ycnJ/8rKyv/MzMz/zs7O/9DQ0P/S0tL/09PT/9TU + 1P/W1tb/19fX/9nZ2f/a2tr/29vb/93d3f/d3d3/3t7e/9/f3//g4OD/4eHh/+Li4v/j4+P/5OTk/+Xl + 5f/m5ub/5ubm/+fn5//o6Oj/6Ojo/+np6f/q6ur/6urq/+vr6zH///8B////Af///wH///8Bz8/P483N + zf/Kysr/yMjI/8bGxv+jo6P/SkpK/0NDQ/9sbGz/goKC/35+fv/R0dH/+/v7/8zMzP9KSkr/ExMT/x0d + Hf8hISH/GRkZ/x4eHv8hISH/IiIi/yMjI/8jIyP/IyMj/yMjI/8iIiL/IiIi/yQiIf8iIiL/IiIi/yMj + I/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8kJCT/JCQk/yQk + JP8kJCT/LCws/1dXV/+jo6P/xsbG/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/x8fH/6mpqf9kZGT/Ly8v/yQkJP8kJCT/JCQk/yQk + JP8jIyP/IiIi/x4eHv8LCwv/BwcH/0BAQP+QkJD/sbGx/729vf/AwMD/wcHB/8PDw//FxcX/x8fH/8nJ + yf/Ly8v/zMzM/87Ozv/Q0ND/0tLS/9PT0//U1NT/1tbW/9fX1//Z2dn/2tra/9vb2//c3Nz/3d3d/97e + 3v/f39//4ODg/+Hh4f/i4uL/4+Pj/+Tk5P/k5OT/5ubm/+bm5v/n5+f/6Ojo/+jo6P/p6en/6urq/+rq + 6v/r6+v/6+vrMf///wH///8B////Af///wHPz8/jzs7O/8zMzP/Kysr/yMjI/7e3t/9vb2//aGho/4OD + g/94eHj/y8vL//v7+//T09P/VFRU/xcXF/8dHR3/IyMj/xwcHP8dHR3/ISEh/yMjI/8jIyP/IyMj/yIi + Iv8iIiL/IiIi/yIiIv86Ih7/ciQW/0AhHP8jISH/IiIi/yIiIv8jIyP/IyMj/yMjI/8jIyP/IyMj/yMj + I/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yQkJP8kJCT/JiYm/zo6Ov9oaGj/o6Oj/8HB + wf/Jycn/zMzM/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/8zMzP/Jycn/xMTE/62t + rf9wcHD/Pz8//ycnJ/8kJCT/JCQk/yQkJP8kJCT/IyMj/yIiIv8gICD/DAwM/wMDA/89PT3/h4eH/7Cw + sP+9vb3/v7+//8LCwv/ExMT/xsbG/8fHx//Jycn/y8vL/83Nzf/Pz8//0NDQ/9LS0v/T09P/1NTU/9bW + 1v/X19f/2dnZ/9ra2v/b29v/3Nzc/93d3f/e3t7/39/f/+Dg4P/h4eH/4uLi/+Li4v/j4+P/5OTk/+Xl + 5f/m5ub/5+fn/+jo6P/o6Oj/6enp/+rq6v/q6ur/6+vr/+vr6//s7Owx////Af///wH///8B////AdHR + 0ePPz8//zc3N/8vLy//Jycn/x8fH/7W1tf+SkpL/e3t7/76+vv/+/v7/5OTk/1paWv8UFBT/HBwc/yQk + JP8bGxv/HBwc/yEhIf8kJCT/IyMj/yMjI/8iIiL/IiIi/yIiIv8iIiL/NSIe/5EnFP/CLBH/ZCUa/yYi + If8iIiL/IiIi/yIiIv8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMj + I/8jIyP/IyMj/yQkJP8kJCT/JCQk/yQkJP8tLS3/TU1N/3Z2dv+goKD/rq6u/7q6uv/BwcH/yMjI/8nJ + yf/Hx8f/xcXF/729vf+urq7/m5ub/3p6ev9VVVX/MzMz/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yMj + I/8iIiL/ICAg/w4ODv8CAgL/Kioq/42Njf+tra3/vb29/8DAwP/CwsL/xMTE/8bGxv/IyMj/ysrK/8vL + y//Nzc3/z8/P/9DQ0P/S0tL/09PT/9TU1P/W1tb/19fX/9nZ2f/a2tr/3Nzc/93d3f/d3d3/3t7e/9/f + 3//g4OD/4eHh/+Li4v/i4uL/4+Pj/+Tk5P/l5eX/5ubm/+fn5//n5+f/6Ojo/+np6f/p6en/6urq/+vr + 6//r6+v/7Ozs/+zs7DH///8B////Af///wH///8B0tLS49DQ0P/Ozs7/zMzM/8vLy//Jycn/xsbG/7Ky + sv+xsbH/9PT0/+np6f98fHz/GRkZ/xkZGf8jIyP/Hx8f/xwcHP8hISH/JSUl/yQkJP8jIyP/IiIi/yIi + Iv8iIiL/IiIi/ykhIP9/JRX/xCwR/4UoGP8qIiH/IiIi/yIiIv8iIiL/IiIi/yMjI/8jIyP/IyMj/yMj + I/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8kJCT/JCQk/yQk + JP8kJCT/KCgo/zY2Nv9AQED/TExM/1lZWf9qamr/bW1t/2hoaP9iYmL/UVFR/0FBQf8zMzP/KCgo/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/IyMj/yEhIf8QEBD/AgIC/yAgIP90dHT/qqqq/7y8 + vP/AwMD/wsLC/8TExP/Gxsb/yMjI/8rKyv/MzMz/zc3N/8/Pz//R0dH/0tLS/9PT0//U1NT/1tbW/9fX + 1//Z2dn/2tra/9zc3P/c3Nz/3d3d/97e3v/f39//4ODg/+Hh4f/i4uL/4uLi/+Pj4//k5OT/5eXl/+bm + 5v/m5ub/5+fn/+jo6P/p6en/6enp/+rq6v/r6+v/6+vr/+zs7P/s7Oz/7OzsMf///wH///8B////Af// + /wHU1NTj0tLS/9DQ0P/Ozs7/zMzM/8rKyv/IyMj/wsLC/5GRkf+kpKT/cHBw/xsbG/8ZGRn/IiIi/x8f + H/8eHh7/IyMj/yYmJv8lJSX/IyMj/yIiIv8iIiL/IiIi/yIiIv8sIR//eSYX/8UtEf+CKBj/LiIg/yIi + Iv8iIiL/IiIi/yIiIv8iIiL/IiIi/yQiIv8jIyP/IyMj/yMjI/8jIiL/LCIh/0sjHP9vJRj/NSIf/yMj + I/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/IyMj/yQk + JP8nJyf/ERER/wICAv8lJSX/fX19/6ampv++vr7/wcHB/8PDw//ExMT/xsbG/8jIyP/Kysr/zMzM/83N + zf/Pz8//0dHR/9PT0//U1NT/1dXV/9bW1v/X19f/2dnZ/9ra2v/b29v/3d3d/93d3f/e3t7/39/f/+Dg + 4P/h4eH/4uLi/+Pj4//j4+P/5OTk/+Xl5f/m5ub/5+fn/+fn5//o6Oj/6enp/+np6f/q6ur/6urq/+vr + 6//r6+v/7Ozs/+3t7f/t7e0x////Af///wH///8B////AdXV1ePT09P/0dHR/8/Pz//Nzc3/zMzM/8rK + yv/BwcH/aGho/zs7O/9DQ0P/ISEh/yIiIv8eHh7/HR0d/yIiIv8mJib/JSUl/yMjI/8iIiL/IiIi/yIi + Iv8hISH/JCEh/3QlF//DLBD/tSsS/z4iHf8iISH/IiIi/yIiIv8iIiL/IiEh/yohH/9JIhz/YiIX/zch + Hf8kIiL/JiIh/0ciG/9+Jhb/jCgW/7csE/9GJB7/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMj + I/8jIyP/IyMj/yMjI/8kJCT/JCQk/yQkJP8kJCT/IyMj/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8jIyP/Li4u/z4+Pv8sLCz/Kysr/35+fv+qqqr/vLy8/8HB + wf/Dw8P/xcXF/8bGxv/IyMj/ysrK/8zMzP/Nzc3/z8/P/9HR0f/T09P/1NTU/9XV1f/X19f/2NjY/9nZ + 2f/a2tr/3Nzc/9zc3P/d3d3/3t7e/9/f3//g4OD/4eHh/+Li4v/i4uL/4+Pj/+Tk5P/l5eX/5ubm/+bm + 5v/n5+f/6Ojo/+jo6P/p6en/6urq/+rq6v/r6+v/7Ozs/+zs7P/t7e3/7e3t/+7u7jH///8B////Af// + /wH///8B1dXV49TU1P/T09P/0dHR/8/Pz//Nzc3/y8vL/8LCwv9vb2//U1NT/0dHR/8tLS3/JiYm/x4e + Hv8iIiL/JSUl/yUlJf8jIyP/IyMj/yIiIv8hISH/ISEh/yYgIP9fIxj/xSwR/7QsE/+7KxL/lycT/1Ui + GP80IR7/OSEc/0ohGv9tIxb/nygT/7wrEv+6LBL/hiYV/1MiGf98Jhb/kSgV/2QmG/9YJhz/nisW/ywj + If8jIiL/MyIf/z8iHf8vIiD/IyIi/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMj + I/8jIyP/IyMj/yMjI/8jIyP/IyMj/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8jIyP/IyMj/yYm + Jv9DQ0P/UVFR/2xsbP9/f3//s7Oz/7+/v//BwcH/xMTE/8XFxf/Hx8f/ycnJ/8rKyv/MzMz/zs7O/9DQ + 0P/R0dH/09PT/9TU1P/V1dX/19fX/9jY2P/Z2dn/2tra/9vb2//c3Nz/3d3d/97e3v/f39//4ODg/+Hh + 4f/i4uL/4+Pj/+Pj4//k5OT/5eXl/+bm5v/n5+f/5+fn/+jo6P/o6Oj/6enp/+rq6v/q6ur/6+vr/+vr + 6//s7Oz/7Ozs/+3t7f/u7u7/7u7uMf///wH///8B////Af///wHX19fj1dXV/9TU1P/S0tL/0NDQ/8/P + z//Nzc3/xcXF/35+fv9PT0//MDAw/ywsLP8mJib/ISEh/yQkJP8lJSX/IyMj/yMjI/8iIiL/IiIi/yEh + If8jICD/YiMZ/7srEf+fKhX/QSMd/1QkHP+eKhX/vCoQ/64pEf+sKBH/tioR/7ErE/+ZKhb/dCca/1Ml + HP98JRb/mCgU/3EnGv85JCD/JiMi/2smGv95KBn/IyMi/zQjIP+PJxT/hicW/3AkFv84Ix//IyIi/yMj + Iv8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yMjI/8jIyP/Hh4e/zIyMv9PT0//e3t7/5ycnP+9vb3/w8PD/8TE + xP/Gxsb/yMjI/8nJyf/Ly8v/zc3N/87Ozv/Q0ND/0dHR/9PT0//U1NT/1dXV/9fX1//Y2Nj/2dnZ/9ra + 2v/c3Nz/3Nzc/93d3f/e3t7/39/f/+Dg4P/h4eH/4uLi/+Pj4//k5OT/5OTk/+Xl5f/m5ub/5+fn/+fn + 5//o6Oj/6Ojo/+np6f/q6ur/6urq/+vr6//r6+v/7Ozs/+3t7f/t7e3/7e3t/+7u7v/u7u4x////Af// + /wH///8B////AdjY2OPX19f/1dXV/9PT0//S0tL/0NDQ/8/Pz//IyMj/gYGB/zc3N/8sLCz/KCgo/yEh + If8hISH/IyMj/yQkJP8jIyP/IiIi/yIiIv8hISH/ISEh/1EjG/+7KxH/tisS/0QjHf8iISD/IiEg/zUi + Hv9rJhn/tysS/7YqEf9eJBr/PiMe/y8iIP8lIiH/JCIh/0wkHf9DJB7/KCMi/yIiIv8qIiH/hSgX/1Ym + Hf8nIiH/QyQe/5YpFf9IIxz/TyUd/4gnFv9aJBn/JSIi/yMiIv8jIiL/IyMj/yMjI/8jIyP/IyMj/yMj + I/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/JCQk/yQkJP8kJCT/JCQk/yMjI/8jIyP/IyMj/xoa + Gv8GBgb/FxcX/2RkZP+enp7/u7u7/8PDw//FxcX/x8fH/8jIyP/Kysr/zMzM/87Ozv/Pz8//0NDQ/9LS + 0v/T09P/1dXV/9bW1v/X19f/2NjY/9ra2v/a2tr/3Nzc/9zc3P/d3d3/3t7e/9/f3//g4OD/4eHh/+Li + 4v/j4+P/5OTk/+Tk5P/l5eX/5ubm/+bm5v/n5+f/6Ojo/+jo6P/p6en/6enp/+rq6v/r6+v/6+vr/+zs + 7P/s7Oz/7e3t/+3t7f/u7u7/7u7u/+7u7jH///8B////Af///wH///8B2tra49jY2P/W1tb/1NTU/9PT + 0//S0tL/0NDQ/8XFxf9kZGT/LS0t/ygoKP8iIiL/IiIi/yMjI/8kJCT/IyMj/yMjI/8iIiL/IiIi/yEh + If8oISD/gCcX/8ctEf+gKBP/QSEb/yYgH/8gICD/ICAg/yAgH/9MIxz/tisS/34mFv8mISD/ISEh/yYh + IP83IR3/RSIb/0MiHP8zIR7/IyEh/0IkHv+ZKRX/OyMf/1ckG/9zJRf/WSUc/4MmFf9uJBf/pSoU/1Yl + HP9EIx3/SyMc/zMiH/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMj + I/8kJCT/JCQk/yQkJP8kJCT/IyMj/yIiIv8ZGRn/BQUF/wwMDP9bW1v/oaGh/7+/v//FxcX/xsbG/8jI + yP/Jycn/y8vL/8zMzP/Ozs7/0NDQ/9HR0f/T09P/1NTU/9XV1f/X19f/2NjY/9nZ2f/a2tr/29vb/9zc + 3P/d3d3/3t7e/9/f3//g4OD/4ODg/+Hh4f/i4uL/4+Pj/+Tk5P/k5OT/5eXl/+bm5v/n5+f/5+fn/+jo + 6P/o6Oj/6enp/+rq6v/q6ur/6+vr/+vr6//s7Oz/7e3t/+3t7f/u7u7/7u7u/+7u7v/v7+//7+/vMf// + /wH///8B////Af///wHa2trj2dnZ/9fX1//W1tb/1NTU/9PT0//S0tL/w8PD/1dXV/8sLCz/IyMj/yEh + If8jIyP/JCQk/yQkJP8jIyP/IyMj/yIiIv8iIiL/IiIi/yEhIf8zIh//aiYa/64qE/+uKRH/bSMW/y0f + Hf8gICD/ICAg/zshHf+tKhL/oioU/y0hH/8rIB7/bCMW/6QpEv+0KhH/rykR/5onEv9aIhj/WiQa/3cn + Gf8pIiH/SSQd/40nFP9YIhn/fiYW/6YqFP9dJRv/WSQa/5goFf+JKBb/gCYW/zUiHv8kIiL/IyMj/yMj + I/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yQkJP8kJCT/JCQk/yMjI/8iIiL/HBwc/wcH + B/8GBgb/SkpK/5ycnP+9vb3/xcXF/8fHx//Jycn/ysrK/8zMzP/Nzc3/zs7O/9DQ0P/S0tL/09PT/9XV + 1f/W1tb/19fX/9nZ2f/Z2dn/2tra/9vb2//d3d3/3d3d/97e3v/f39//4ODg/+Dg4P/h4eH/4uLi/+Pj + 4//k5OT/5OTk/+Xl5f/m5ub/5ubm/+fn5//o6Oj/6Ojo/+np6f/p6en/6urq/+vr6//r6+v/7Ozs/+zs + 7P/t7e3/7e3t/+7u7v/u7u7/7+/v/+/v7//w8PAx////Af///wH///8B////Advb2+Pa2tr/2dnZ/9fX + 1//W1tb/1NTU/9PT0//CwsL/UFBQ/yQkJP8hISH/IyMj/yQkJP8kJCT/JCQk/yMjI/8jIyP/IiIi/yIi + Iv8iIiL/ISEh/yEhIf8iISD/OSIe/3wnGP+zKhL/nycR/2YiFv9WIRf/kCUS/8UsEf93Jxn/MSEe/4Ul + FP+5KxL/gygX/0wkHf9FIx3/dicY/68qEv98JRb/KiIg/yIiIf8kIiH/QyMe/38nGP+NKRb/XCYb/1wk + Gv+dKRT/SyUe/ykjIv98KBn/licU/z0iHv8tIiD/JSIi/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMj + I/8jIyP/JCQk/yMjI/8jIyP/JCQk/yEhIf8JCQn/CQkJ/0hISP+YmJj/wMDA/8fHx//IyMj/ycnJ/8vL + y//MzMz/zs7O/8/Pz//R0dH/0tLS/9TU1P/V1dX/19fX/9jY2P/Z2dn/2tra/9vb2//c3Nz/3d3d/97e + 3v/e3t7/39/f/+Dg4P/h4eH/4uLi/+Li4v/j4+P/5OTk/+Tk5P/l5eX/5ubm/+fn5//n5+f/6Ojo/+jo + 6P/p6en/6urq/+rq6v/r6+v/6+vr/+zs7P/s7Oz/7e3t/+3t7f/u7u7/7u7u/+/v7//v7+//8PDw//Dw + 8DH///8B////Af///wH///8B3d3d49zc3P/a2tr/2dnZ/9fX1//W1tb/1NTU/8DAwP9GRkb/IiIi/yMj + I/8kJCT/JCQk/yQkJP8kJCT/IyMj/yMjI/8jIyP/IiIi/yIiIv8iIiL/ISEh/yEhIf8hISH/JyEg/04j + HP+QKBX/tioR/70rEP+3KxL/gygX/zsiHv9tJRj/viwR/3AmGf8rISD/ISEh/yEhIf8nISD/dicY/7Eq + Ev88Ih7/IiIi/yIiIv8iIiL/JiIh/ykiIf82Ih7/likV/10mHP8kIiL/OCIe/5UpFv9pJxv/RCMe/3Ym + F/8xIyD/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8kJCT/IyMj/yMjI/8jIyP/CgoK/wQE + BP9AQED/kpKS/7u7u//IyMj/ycnJ/8vLy//MzMz/zs7O/8/Pz//Q0ND/0dHR/9PT0//U1NT/1tbW/9fX + 1//Y2Nj/2tra/9vb2//c3Nz/3Nzc/97e3v/e3t7/39/f/+Dg4P/g4OD/4eHh/+Li4v/i4uL/4+Pj/+Tk + 5P/l5eX/5eXl/+bm5v/m5ub/5+fn/+jo6P/o6Oj/6enp/+rq6v/q6ur/6+vr/+vr6//s7Oz/7Ozs/+3t + 7f/t7e3/7u7u/+7u7v/v7+//7+/v/+/v7//w8PD/8PDwMf///wH///8B////Af///wHe3t7j3d3d/9zc + 3P/a2tr/2dnZ/9fX1//W1tb/y8vL/2hoaP8sLCz/IyMj/yMjI/8kJCT/JCQk/yMjI/8jIyP/IyMj/yMj + I/8iIiL/IiIi/yIiIv8hISH/ISEh/yEhIf8hISH/ISEg/ywhH/9BIx3/TyQc/0AjHv8pISD/NCIe/6Iq + FP+cKRX/KyEf/yEhIf8hISH/ISEh/yQhIP9sJRj/vSsR/0sjHf8hISH/MCEf/0QiHP8oISD/IiIi/yci + If9CJB7/JyIh/zciH/+IJxX/cica/0YkHf+RKBX/YiYc/zoiHv9kJBn/RyMd/yUiIv8jIyP/IyMj/yMj + I/8jIyP/IyMj/yMjI/8lJSX/MTEx/x8fH/8NDQ3/Pz8//5WVlf+5ubn/ycnJ/8vLy//MzMz/zc3N/8/P + z//Q0ND/0dHR/9LS0v/U1NT/1dXV/9bW1v/X19f/2dnZ/9ra2v/b29v/3Nzc/93d3f/e3t7/39/f/+Dg + 4P/g4OD/4eHh/+Li4v/i4uL/4+Pj/+Tk5P/k5OT/5eXl/+bm5v/m5ub/5+fn/+fn5//o6Oj/6enp/+np + 6f/q6ur/6urq/+vr6//r6+v/7Ozs/+zs7P/t7e3/7e3t/+7u7v/u7u7/7u7u/+/v7//v7+//8PDw//Dw + 8P/x8fEx////Af///wH///8B////Ad/f3+Pe3t7/3d3d/9zc3P/a2tr/2dnZ/9jY2P/X19f/xMTE/4yM + jP89PT3/JiYm/yMjI/8kJCT/IyMj/yMjI/8jIyP/IyMj/yMjI/8iIiL/IiIi/yIiIv8iIiL/IiIi/yEh + If8hISH/ISEh/yEhIf8hISH/ISEh/yEhIf8zIh//oioU/5AoFf8jICD/ISEh/yEhIf8gICD/OiEc/6Ao + Ev+rKhP/MiIf/ysgHv+EJhX/rikR/0QjHf8iIiL/IiIi/yIiIv8iIiL/TiMc/24nGv9CIx7/kikW/3co + Gf89Ix7/hicX/4EpGf9iJhv/KiMi/yMjI/8jIyP/IyMj/yMjI/8iIiL/JCQk/zg4OP9SUlL/XV1d/2Ji + Yv+ZmZn/xMTE/8zMzP/MzMz/zs7O/8/Pz//Q0ND/0dHR/9LS0v/U1NT/1dXV/9bW1v/X19f/2NjY/9nZ + 2f/b29v/3Nzc/93d3f/e3t7/39/f/9/f3//g4OD/4eHh/+Li4v/i4uL/4+Pj/+Pj4//k5OT/5eXl/+Xl + 5f/m5ub/5ubm/+fn5//o6Oj/6Ojo/+np6f/p6en/6urq/+rq6v/r6+v/7Ozs/+zs7P/t7e3/7e3t/+3t + 7f/u7u7/7u7u/+/v7//v7+//8PDw//Dw8P/w8PD/8fHx//Hx8TH///8B////Af///wH///8B4ODg49/f + 3//e3t7/3d3d/9zc3P/a2tr/2dnZ/9jY2P/X19f/0tLS/6qqqv9kZGT/Kysr/yMjI/8jIyP/IyMj/yMj + I/8jIyP/IyMj/yIiIv8iIiL/IiIi/yIiIv8iIiL/ISEh/yEhIf8hISH/ISEh/yEhIf8hISH/ISEh/yYh + IP9zJxn/sCoS/1QhGP8oIB7/IyAf/zcgG/+MJRP/visR/2YlGf8oIB//aSMX/78rEf+CKBj/LCIg/yIi + Iv8iIiH/IyIh/yIhIf8oIiH/NyIe/4AmFv99KBj/PSId/4EnFv95KBn/LSMi/yYjIv8jIyL/IyMj/yMj + I/8jIyP/IiIi/yIiIv8lJSX/OTk5/1NTU/9nZ2f/hYWF/7m5uf/Nzc3/zs7O/8/Pz//Q0ND/0dHR/9LS + 0v/T09P/1NTU/9bW1v/X19f/2NjY/9nZ2f/a2tr/29vb/9zc3P/d3d3/3t7e/9/f3//g4OD/4ODg/+Hh + 4f/i4uL/4+Pj/+Pj4//k5OT/5OTk/+Xl5f/m5ub/5ubm/+fn5//n5+f/6Ojo/+jo6P/p6en/6enp/+rq + 6v/r6+v/6+vr/+vr6//s7Oz/7Ozs/+3t7f/t7e3/7u7u/+7u7v/v7+//7+/v/+/v7//w8PD/8PDw//Hx + 8f/x8fH/8fHxMf///wH///8B////Af///wHh4eHj4ODg/9/f3//e3t7/3d3d/9zc3P/b29v/2tra/9nZ + 2f/Y2Nj/19fX/9TU1P+goKD/XFxc/y8vL/8iIiL/IyMj/yMjI/8jIyP/IyMj/yMjI/8iIiL/IiIi/yIi + Iv8iIiL/IiIi/yIiIv8iIiL/ISEh/yEhIf8hISH/ISEh/ykhIP9yJhj/qikS/54mEf+WJRH/rSgR/6sq + E/9kJRr/LyEe/3EkFv+/KxD/gygX/zAiH/8hISH/IiEh/zIiH/97JRX/VCMa/ysiIP9zJRf/eygZ/1Ek + HP+fKBP/likV/zMjIP8jIyP/IyMj/yMjI/8jIyP/IyMj/yIiIv8jIyP/JCQk/xEREf8HBwf/PT09/4GB + gf+0tLT/zs7O/8/Pz//R0dH/0tLS/9LS0v/T09P/1NTU/9XV1f/X19f/2NjY/9nZ2f/a2tr/29vb/9zc + 3P/d3d3/3t7e/9/f3//g4OD/4eHh/+Hh4f/i4uL/4+Pj/+Tk5P/k5OT/5eXl/+Xl5f/m5ub/5ubm/+fn + 5//n5+f/6Ojo/+jo6P/p6en/6enp/+rq6v/q6ur/6+vr/+vr6//s7Oz/7Ozs/+3t7f/t7e3/7u7u/+7u + 7v/u7u7/7+/v/+/v7//w8PD/8PDw//Hx8f/x8fH/8fHx//Ly8v/x8fEx////Af///wH///8B////AeLi + 4uPh4eH/4ODg/9/f3//e3t7/3d3d/9zc3P/b29v/2tra/9nZ2f/Y2Nj/19fX/9XV1f/ExMT/ioqK/0FB + Qf8kJCT/IyMj/yMjI/8jIyP/IyMj/yMjI/8iIiL/IiIi/yIiIv8iIiL/IiIi/yIiIv8iIiL/IiIi/yEh + If8hISH/ISEh/yghIP9FIx3/aCUZ/3UmGP9lJRn/QiMd/ychH/9YIhj/vSsR/5YpFf8wIh//ISEh/yEh + If8tIR//eSUW/7wsEf9lJhv/JyIh/0QkHv81IyD/YCUa/4spF/9UJR3/KyMh/yMjI/8jIyP/IyMj/yMj + I/8jIyP/IiIi/yQkJP8XFxf/AgIC/xwcHP95eXn/sbGx/87Ozv/Q0ND/0tLS/9PT0//U1NT/1NTU/9XV + 1f/W1tb/19fX/9nZ2f/a2tr/29vb/9vb2//d3d3/3d3d/9/f3//g4OD/4eHh/+Hh4f/i4uL/4+Pj/+Pj + 4//k5OT/5OTk/+Xl5f/m5ub/5ubm/+fn5//n5+f/6Ojo/+jo6P/p6en/6enp/+np6f/q6ur/6urq/+vr + 6//r6+v/7Ozs/+zs7P/t7e3/7e3t/+7u7v/u7u7/7+/v/+/v7//v7+//8PDw//Dw8P/w8PD/8fHx//Hx + 8f/y8vL/8vLy//Ly8jH///8B////Af///wH///8B4+Pj4+Li4v/h4eH/4ODg/9/f3//e3t7/3d3d/9zc + 3P/b29v/29vb/9ra2v/Z2dn/2NjY/9fX1//T09P/urq6/3t7e/81NTX/JSUl/yIiIv8jIyP/IyMj/yMj + I/8jIyP/IiIi/yIiIv8iIiL/IiIi/yIiIv8iIiL/IiIi/yEhIf8hISH/ISEh/yEhIP8iISD/JCEg/yIh + IP8lICD/WCIZ/7QqEf+sKxP/PiMe/yEhIP8hISH/KyAf/3klFv+7KxH/byca/yoiIf8iIiL/IyIi/y8i + IP9CIx3/MSMh/yQjIv8jIyL/IyMj/yMjI/8jIyP/IiIi/yMjI/8mJib/GBgY/wUFBf8eHh7/d3d3/7W1 + tf/Ozs7/0tLS/9PT0//U1NT/1dXV/9bW1v/X19f/19fX/9nZ2f/Z2dn/29vb/9zc3P/c3Nz/3t7e/97e + 3v/g4OD/4ODg/+Hh4f/i4uL/4+Pj/+Tk5P/k5OT/5eXl/+Xl5f/m5ub/5ubm/+fn5//n5+f/6Ojo/+jo + 6P/p6en/6enp/+rq6v/q6ur/6urq/+vr6//r6+v/7Ozs/+zs7P/t7e3/7e3t/+3t7f/u7u7/7u7u/+/v + 7//v7+//7+/v//Dw8P/w8PD/8PDw//Hx8f/x8fH/8vLy//Ly8v/y8vL/8/PzMf///wH///8B////Af// + /wHk5OTj5OTk/+Li4v/i4uL/4ODg/+Dg4P/e3t7/3t7e/93d3f/c3Nz/29vb/9ra2v/a2tr/2dnZ/9jY + 2P/X19f/09PT/6SkpP9gYGD/Kioq/yIiIv8jIyP/IyMj/yMjI/8jIyP/IyMj/yIiIv8iIiL/IiIi/yIi + Iv8iIiL/IiIi/yEhIf8hISH/ISEh/yEhIf8hISH/ISEh/zIhHv+TKBT/qCoT/6EpFP82IR3/ISAg/yYg + H/9nIxf/uysR/4MoF/8uIiD/IiIi/yIiIv8xIiD/iSgW/48oFf81IyD/IyMj/yMjI/8jIyP/IyMj/yMj + I/8iIiL/KSkp/x8fH/8FBQX/FRUV/2lpaf+urq7/0NDQ/9TU1P/V1dX/1dXV/9bW1v/X19f/2NjY/9nZ + 2f/Z2dn/29vb/9vb2//c3Nz/3d3d/97e3v/f39//4ODg/+Hh4f/i4uL/4+Pj/+Pj4//k5OT/5eXl/+Xl + 5f/m5ub/5ubm/+fn5//n5+f/6Ojo/+jo6P/p6en/6enp/+rq6v/q6ur/6urq/+vr6//r6+v/7Ozs/+zs + 7P/s7Oz/7e3t/+3t7f/u7u7/7u7u/+/v7//v7+//7+/v//Dw8P/w8PD/8PDw//Hx8f/x8fH/8fHx//Ly + 8v/y8vL/8vLy//Pz8//z8/Mx////Af///wH///8B////AeXl5ePl5eX/5OTk/+Pj4//i4uL/4eHh/+Dg + 4P/f39//3t7e/97e3v/c3Nz/3Nzc/9vb2//a2tr/2tra/9nZ2f/Y2Nj/1tbW/8nJyf+MjIz/RUVF/yYm + Jv8iIiL/IyMj/yMjI/8jIyP/IiIi/yIiIv8iIiL/IiIi/yIiIv8iIiL/IiIi/yEhIf8hISH/ISEh/yEh + If8hISH/JCEg/z0iHv9HIx3/pyoT/4gmE/9QIRj/dCQW/7orEf+OKRf/NCMf/yIiIv8iIiL/MCIf/4Em + Fv/ALRL/cCga/yojIv8jIyP/IyMj/yMjI/8jIyP/IiIi/yQkJP8eHh7/BQUF/wwMDP9hYWH/qamp/83N + zf/V1dX/1tbW/9fX1//X19f/2NjY/9nZ2f/a2tr/29vb/9zc3P/d3d3/3d3d/97e3v/f39//4ODg/+Hh + 4f/i4uL/4+Pj/+Pj4//k5OT/5eXl/+Xl5f/m5ub/5ubm/+fn5//n5+f/6Ojo/+jo6P/p6en/6enp/+rq + 6v/q6ur/6urq/+vr6//r6+v/6+vr/+zs7P/s7Oz/7e3t/+3t7f/t7e3/7u7u/+7u7v/v7+//7+/v/+/v + 7//w8PD/8PDw//Dw8P/x8fH/8fHx//Hx8f/y8vL/8vLy//Ly8v/z8/P/8/Pz//Pz8zH///8B////Af// + /wH///8B5ubm4+bm5v/l5eX/5OTk/+Pj4//i4uL/4eHh/+Hh4f/g4OD/39/f/9/f3//e3t7/3d3d/9zc + 3P/c3Nz/29vb/9ra2v/Z2dn/2dnZ/9fX1/+8vLz/fHx8/zg4OP8kJCT/IiIi/yMjI/8jIyP/IyMj/yIi + Iv8iIiL/IiIi/yIiIv8iIiL/IiIi/yIiIv8hISH/ISEh/yEhIf8hISH/ISEh/yMhIP9TJBz/nSkV/7gr + Ef+2KxL/uiwS/08kHP8iIiL/IiIi/yoiIP+AJhX/vywS/3YoGv8pIyL/IyMj/yMjI/8jIyP/IyMj/yIi + Iv8qKir/JSUl/wkJCf8RERH/Xl5e/6enp//Pz8//19fX/9jY2P/Y2Nj/2dnZ/9ra2v/a2tr/3Nzc/9zc + 3P/d3d3/3t7e/97e3v/f39//4ODg/+Hh4f/i4uL/4+Pj/+Tk5P/k5OT/5eXl/+Xl5f/m5ub/5+fn/+fn + 5//n5+f/6Ojo/+jo6P/p6en/6enp/+rq6v/q6ur/6+vr/+vr6//r6+v/7Ozs/+zs7P/s7Oz/7e3t/+3t + 7f/t7e3/7u7u/+7u7v/u7u7/7+/v/+/v7//w8PD/8PDw//Dw8P/x8fH/8fHx//Hx8f/y8vL/8vLy//Ly + 8v/z8/P/8/Pz//Pz8//z8/P/8/PzMf///wH///8B////Af///wHn5+fj5+fn/+bm5v/l5eX/5OTk/+Pj + 4//j4+P/4uLi/+Hh4f/g4OD/4ODg/9/f3//e3t7/3t7e/93d3f/c3Nz/29vb/9vb2//a2tr/2dnZ/9nZ + 2f/R0dH/pKSk/19fX/9LS0v/YmJi/2FhYf9PT0//LS0t/yIiIv8iIiL/IiIi/yIiIv8iIiL/IiIi/yIi + Iv8iIiL/ISEh/yEhIf8hISH/ISEh/yMhIP82Ix//TiQd/0okHf+iKhT/YCQZ/yQhIf8oISD/aCQY/8As + Ef+BKRn/MCMh/yMjI/8jIyP/IyMj/yMjI/8iIiL/Kysr/0xMTP9MTEz/QkJC/2RkZP+ysrL/zs7O/9jY + 2P/Z2dn/2dnZ/9ra2v/b29v/3Nzc/9zc3P/e3t7/3t7e/9/f3//g4OD/4ODg/+Hh4f/i4uL/4+Pj/+Pj + 4//k5OT/5eXl/+Xl5f/m5ub/5ubm/+fn5//n5+f/6Ojo/+jo6P/p6en/6enp/+np6f/q6ur/6urq/+vr + 6//r6+v/6+vr/+zs7P/s7Oz/7e3t/+3t7f/t7e3/7u7u/+7u7v/u7u7/7+/v/+/v7//v7+//8PDw//Dw + 8P/w8PD/8fHx//Hx8f/x8fH/8vLy//Ly8v/y8vL/8/Pz//Pz8//z8/P/8/Pz//T09P/z8/Mx////Af// + /wH///8B////Aejo6OPo6Oj/5+fn/+bm5v/m5ub/5eXl/+Tk5P/k5OT/4+Pj/+Li4v/h4eH/4eHh/+Dg + 4P/g4OD/39/f/97e3v/e3t7/3d3d/9zc3P/c3Nz/29vb/9ra2v/a2tr/1tbW/9TU1P/Y2Nj/19fX/9TU + 1P+1tbX/ZWVl/ysrK/8iIiL/IiIi/yIiIv8iIiL/IiIi/yIiIv8iIiL/ISEh/yEhIf8hISH/ISEh/yEh + If8iIiH/IiIh/2YnG/+zKxL/nCgT/6MoEv/BLBH/gSkZ/zAkIf8jIyL/IyMj/yMjI/8jIyP/IiIi/ycn + J/84ODj/VFRU/2JiYv92dnb/q6ur/9fX1//a2tr/2tra/9vb2//c3Nz/3d3d/93d3f/e3t7/39/f/9/f + 3//g4OD/4eHh/+Li4v/i4uL/4+Pj/+Tk5P/k5OT/5eXl/+bm5v/m5ub/5+fn/+fn5//o6Oj/6Ojo/+jo + 6P/p6en/6enp/+rq6v/q6ur/6+vr/+vr6//r6+v/7Ozs/+zs7P/s7Oz/7e3t/+3t7f/t7e3/7u7u/+7u + 7v/u7u7/7+/v/+/v7//v7+//7+/v//Dw8P/w8PD/8PDw//Hx8f/x8fH/8fHx//Hx8f/y8vL/8vLy//Pz + 8//z8/P/8/Pz//Pz8//09PT/9PT0//Pz8zH///8B////Af///wH///8B6enp4+np6f/o6Oj/5+fn/+fn + 5//m5ub/5eXl/+Xl5f/k5OT/4+Pj/+Pj4//i4uL/4eHh/+Hh4f/g4OD/4ODg/9/f3//e3t7/3t7e/93d + 3f/d3d3/3Nzc/9vb2//b29v/29vb/9ra2v/a2tr/2dnZ/9nZ2f/Dw8P/YmJi/yQkJP8jIyP/IiIi/yIi + Iv8iIiL/IiIi/yIiIv8iIiL/IiIi/yIiIv8iIiL/IiIi/yIiIv8iIiL/KiIh/10mHP+UKhb/nSsW/28o + G/8uIyH/IyMj/yMjI/8jIyP/IyMj/yIiIv8iIiL/ISEh/xQUFP8uLi7/Z2dn/4+Pj//Ozs7/29vb/9zc + 3P/c3Nz/3d3d/97e3v/e3t7/39/f/9/f3//g4OD/4eHh/+Li4v/i4uL/4+Pj/+Tk5P/k5OT/5eXl/+bm + 5v/m5ub/5ubm/+fn5//o6Oj/6Ojo/+jo6P/p6en/6enp/+rq6v/q6ur/6urq/+vr6//r6+v/7Ozs/+zs + 7P/s7Oz/7e3t/+3t7f/t7e3/7u7u/+7u7v/u7u7/7+/v/+/v7//v7+//8PDw//Dw8P/w8PD/8PDw//Hx + 8f/x8fH/8fHx//Ly8v/y8vL/8vLy//Ly8v/z8/P/8/Pz//Pz8//09PT/9PT0//T09P/09PT/9PT0Mf// + /wH///8B////Af///wHq6urj6urq/+np6f/o6Oj/6Ojo/+fn5//n5+f/5ubm/+bm5v/l5eX/5OTk/+Tk + 5P/j4+P/4+Pj/+Li4v/h4eH/4eHh/+Dg4P/g4OD/39/f/97e3v/e3t7/3d3d/93d3f/d3d3/3Nzc/9zc + 3P/b29v/29vb/9ra2v+mpqb/Kioq/yMjI/8iIiL/IiIi/yIiIv8iIiL/IiIi/yIiIv8iIiL/IiIi/yIi + Iv8iIiL/IiIi/yIiIv8iIiL/JCMi/ysjIv8sIyH/JiMi/yMjIv8jIyP/IyMj/yMjI/8iIiL/IiIi/x0d + Hf8ICAj/BQUF/zs7O/+Wlpb/x8fH/9zc3P/d3d3/3t7e/97e3v/f39//4ODg/+Dg4P/h4eH/4uLi/+Li + 4v/j4+P/4+Pj/+Tk5P/l5eX/5eXl/+bm5v/m5ub/5+fn/+jo6P/o6Oj/6Ojo/+np6f/p6en/6urq/+rq + 6v/q6ur/6+vr/+vr6//r6+v/7Ozs/+zs7P/s7Oz/7e3t/+3t7f/t7e3/7u7u/+7u7v/u7u7/7+/v/+/v + 7//v7+//7+/v/+/v7//w8PD/8PDw//Dw8P/x8fH/8fHx//Hx8f/y8vL/8vLy//Ly8v/y8vL/8/Pz//Pz + 8//z8/P/9PT0//T09P/09PT/9PT0//X19f/19fUx////Af///wH///8B////Aevr6+Pr6+v/6urq/+rq + 6v/p6en/6Ojo/+jo6P/n5+f/5+fn/+bm5v/m5ub/5eXl/+Tk5P/k5OT/4+Pj/+Pj4//i4uL/4uLi/+Hh + 4f/h4eH/4ODg/+Dg4P/f39//3t7e/97e3v/e3t7/3d3d/93d3f/c3Nz/3Nzc/8HBwf83Nzf/IiIi/yIi + Iv8jIyP/IyMj/yIiIv8iIiL/IiIi/yIiIv8iIiL/IiIi/yIiIv8iIiL/IyMj/yMjI/8jIyP/IyMj/yMj + I/8jIyP/IyMj/yMjI/8jIyP/IiIi/yIiIv8hISH/DQ0N/wMDA/80NDT/kJCQ/8nJyf/d3d3/39/f/9/f + 3//g4OD/4ODg/+Hh4f/h4eH/4uLi/+Li4v/j4+P/5OTk/+Tk5P/l5eX/5eXl/+bm5v/n5+f/5+fn/+fn + 5//o6Oj/6Ojo/+np6f/p6en/6urq/+rq6v/q6ur/6+vr/+vr6//r6+v/7Ozs/+zs7P/t7e3/7e3t/+3t + 7f/u7u7/7u7u/+7u7v/u7u7/7+/v/+/v7//v7+//7+/v//Dw8P/w8PD/8PDw//Hx8f/x8fH/8fHx//Hx + 8f/y8vL/8vLy//Ly8v/z8/P/8/Pz//Pz8//z8/P/8/Pz//T09P/09PT/9PT0//T09P/19fX/9fX1//X1 + 9TH///8B////Af///wH///8B7Ozs4+vr6//r6+v/6urq/+rq6v/p6en/6enp/+jo6P/o6Oj/5+fn/+bm + 5v/m5ub/5eXl/+Xl5f/k5OT/5OTk/+Pj4//j4+P/4uLi/+Li4v/h4eH/4eHh/+Dg4P/g4OD/39/f/9/f + 3//f39//3t7e/97e3v/d3d3/19fX/4uLi/89PT3/JCQk/yMjI/8jIyP/IyMj/yMjI/8iIiL/IiIi/yIi + Iv8iIiL/IiIi/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yIiIv8jIyP/JSUl/w4O + Dv8CAgL/IyMj/4KCgv/FxcX/39/f/+Dg4P/g4OD/4eHh/+Hh4f/i4uL/4uLi/+Pj4//j4+P/5OTk/+Tk + 5P/l5eX/5eXl/+bm5v/m5ub/5+fn/+fn5//o6Oj/6Ojo/+np6f/p6en/6urq/+rq6v/q6ur/6+vr/+vr + 6//r6+v/7Ozs/+zs7P/s7Oz/7e3t/+3t7f/t7e3/7u7u/+7u7v/u7u7/7+/v/+/v7//v7+//7+/v//Dw + 8P/w8PD/8PDw//Dw8P/x8fH/8fHx//Hx8f/x8fH/8vLy//Ly8v/y8vL/8vLy//Pz8//z8/P/8/Pz//Pz + 8//09PT/9PT0//T09P/19fX/9fX1//X19f/19fX/9fX1Mf///wH///8B////Af///wHt7e3j7Ozs/+zs + 7P/r6+v/6+vr/+rq6v/q6ur/6enp/+np6f/p6en/6Ojo/+jo6P/n5+f/5ubm/+bm5v/l5eX/5eXl/+Xl + 5f/k5OT/5OTk/+Pj4//j4+P/4uLi/+Li4v/h4eH/4eHh/+Hh4f/g4OD/4ODg/9/f3//f39//3d3d/76+ + vv9ycnL/ODg4/yQkJP8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMj + I/8jIyP/IyMj/yMjI/8jIyP/IiIi/yMjI/8RERH/AgIC/yYmJv+IiIj/xcXF/9/f3//i4uL/4uLi/+Li + 4v/j4+P/4+Pj/+Tk5P/k5OT/5eXl/+Xl5f/m5ub/5ubm/+bm5v/n5+f/5+fn/+jo6P/o6Oj/6enp/+np + 6f/p6en/6urq/+rq6v/r6+v/6+vr/+zs7P/s7Oz/7Ozs/+3t7f/t7e3/7e3t/+7u7v/u7u7/7u7u/+7u + 7v/v7+//7+/v/+/v7//v7+//8PDw//Dw8P/w8PD/8PDw//Hx8f/x8fH/8fHx//Hx8f/y8vL/8vLy//Ly + 8v/y8vL/8vLy//Pz8//z8/P/8/Pz//Pz8//09PT/9PT0//T09P/09PT/9fX1//X19f/19fX/9fX1//b2 + 9v/29vYx////Af///wH///8B////Ae3t7ePt7e3/7Ozs/+zs7P/s7Oz/6+vr/+vr6//q6ur/6urq/+np + 6f/p6en/6enp/+jo6P/o6Oj/5+fn/+fn5//m5ub/5ubm/+Xl5f/l5eX/5OTk/+Tk5P/j4+P/4+Pj/+Li + 4v/i4uL/4uLi/+Hh4f/h4eH/4eHh/+Dg4P/g4OD/4ODg/9TU1P+np6f/XFxc/yQkJP8iIiL/IyMj/yMj + I/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yIiIv8nJyf/FBQU/wIC + Av8cHBz/dnZ2/8TExP/f39//4uLi/+Pj4//j4+P/4+Pj/+Tk5P/k5OT/5eXl/+Xl5f/m5ub/5ubm/+fn + 5//n5+f/5+fn/+jo6P/o6Oj/6enp/+np6f/q6ur/6urq/+rq6v/r6+v/6+vr/+vr6//s7Oz/7Ozs/+3t + 7f/t7e3/7e3t/+7u7v/u7u7/7u7u/+7u7v/v7+//7+/v/+/v7//v7+//7+/v//Dw8P/w8PD/8PDw//Dw + 8P/x8fH/8fHx//Hx8f/x8fH/8vLy//Ly8v/y8vL/8vLy//Pz8//z8/P/8/Pz//Pz8//z8/P/9PT0//T0 + 9P/09PT/9PT0//X19f/19fX/9fX1//X19f/19fX/9vb2//b29jH///8B////Af///wH///8B7u7u4+3t + 7f/t7e3/7e3t/+zs7P/s7Oz/7Ozs/+vr6//r6+v/6+vr/+rq6v/q6ur/6enp/+np6f/p6en/6Ojo/+jo + 6P/n5+f/5+fn/+bm5v/m5ub/5eXl/+Xl5f/l5eX/5OTk/+Tk5P/j4+P/4+Pj/+Pj4//i4uL/4uLi/+Li + 4v/i4uL/4eHh/+Hh4f/X19f/l5eX/05OTv8oKCj/IiIi/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMj + I/8jIyP/IyMj/yMjI/8lJSX/Tk5O/5iYmP9zc3P/UVFR/5OTk//Gxsb/4uLi/+Tk5P/k5OT/5eXl/+Xl + 5f/l5eX/5ubm/+bm5v/n5+f/5+fn/+fn5//o6Oj/6Ojo/+np6f/p6en/6enp/+rq6v/q6ur/6urq/+vr + 6//r6+v/6+vr/+zs7P/s7Oz/7Ozs/+3t7f/t7e3/7e3t/+7u7v/u7u7/7u7u/+7u7v/u7u7/7+/v/+/v + 7//v7+//8PDw//Dw8P/w8PD/8PDw//Dw8P/x8fH/8fHx//Hx8f/x8fH/8fHx//Ly8v/y8vL/8vLy//Ly + 8v/y8vL/8/Pz//Pz8//z8/P/8/Pz//T09P/09PT/9PT0//T09P/09PT/9fX1//X19f/19fX/9fX1//b2 + 9v/29vb/9vb2Mf///wH///8B////Af///wHu7u7j7u7u/+7u7v/t7e3/7e3t/+3t7f/s7Oz/7Ozs/+zs + 7P/r6+v/6+vr/+vr6//q6ur/6urq/+rq6v/p6en/6enp/+jo6P/o6Oj/5+fn/+fn5//m5ub/5ubm/+Xl + 5f/l5eX/5eXl/+Tk5P/k5OT/5OTk/+Pj4//j4+P/4+Pj/+Pj4//i4uL/4uLi/+Pj4//g4OD/xMTE/3d3 + d/82Njb/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IiIi/0RERP+urq7/4uLi/+Li + 4v/a2tr/4ODg/+Tk5P/l5eX/5eXl/+Xl5f/l5eX/5ubm/+bm5v/n5+f/5+fn/+fn5//o6Oj/6Ojo/+jo + 6P/p6en/6enp/+rq6v/q6ur/6urq/+vr6//r6+v/6+vr/+zs7P/s7Oz/7Ozs/+3t7f/t7e3/7e3t/+7u + 7v/u7u7/7u7u/+/v7//v7+//7+/v/+/v7//v7+//8PDw//Dw8P/w8PD/8PDw//Hx8f/x8fH/8fHx//Hx + 8f/x8fH/8vLy//Ly8v/y8vL/8vLy//Ly8v/z8/P/8/Pz//Pz8//z8/P/8/Pz//T09P/09PT/9PT0//T0 + 9P/09PT/9fX1//X19f/19fX/9fX1//b29v/29vb/9vb2//b29v/29vYx////Af///wH///8B////Ae/v + 7+Pu7u7/7u7u/+7u7v/u7u7/7e3t/+3t7f/t7e3/7Ozs/+zs7P/s7Oz/6+vr/+vr6//r6+v/6urq/+rq + 6v/q6ur/6enp/+np6f/o6Oj/6Ojo/+fn5//n5+f/5+fn/+bm5v/m5ub/5eXl/+Xl5f/l5eX/5OTk/+Tk + 5P/k5OT/5OTk/+Pj4//j4+P/5OTk/+Tk5P/k5OT/29vb/7i4uP9ra2v/LS0t/yQkJP8iIiL/IyMj/yMj + I/8jIyP/IiIi/yMjI/84ODj/ra2t/+Li4v/l5eX/5eXl/+Xl5f/l5eX/5eXl/+bm5v/m5ub/5ubm/+fn + 5//n5+f/5+fn/+jo6P/o6Oj/6Ojo/+np6f/p6en/6enp/+rq6v/q6ur/6+vr/+vr6//r6+v/7Ozs/+zs + 7P/s7Oz/7e3t/+3t7f/t7e3/7e3t/+7u7v/u7u7/7u7u/+7u7v/v7+//7+/v/+/v7//v7+//8PDw//Dw + 8P/w8PD/8PDw//Hx8f/x8fH/8fHx//Hx8f/x8fH/8vLy//Ly8v/y8vL/8vLy//Ly8v/z8/P/8/Pz//Pz + 8//z8/P/8/Pz//T09P/09PT/9PT0//T09P/09PT/9PT0//X19f/19fX/9fX1//X19f/19fX/9vb2//b2 + 9v/29vb/9vb2//b29jH///8B////Af///wH///8B8PDw4+/v7//v7+//7+/v/+7u7v/u7u7/7u7u/+3t + 7f/t7e3/7e3t/+zs7P/s7Oz/7Ozs/+zs7P/r6+v/6+vr/+vr6//q6ur/6urq/+np6f/p6en/6enp/+jo + 6P/o6Oj/5+fn/+fn5//n5+f/5ubm/+bm5v/m5ub/5ubm/+bm5v/l5eX/5eXl/+Xl5f/l5eX/5eXl/+bm + 5v/m5ub/5ubm/9jY2P+dnZ3/V1dX/yYmJv8iIiL/IyMj/yMjI/8iIiL/PDw8/6CgoP/l5eX/5+fn/+fn + 5//n5+f/5+fn/+fn5//n5+f/5+fn/+jo6P/o6Oj/6Ojo/+jo6P/p6en/6enp/+np6f/q6ur/6urq/+rq + 6v/r6+v/6+vr/+vr6//s7Oz/7Ozs/+zs7P/t7e3/7e3t/+3t7f/t7e3/7u7u/+7u7v/u7u7/7u7u/+/v + 7//v7+//7+/v/+/v7//w8PD/8PDw//Dw8P/w8PD/8fHx//Hx8f/x8fH/8fHx//Ly8v/y8vL/8vLy//Ly + 8v/y8vL/8vLy//Pz8//z8/P/8/Pz//Pz8//z8/P/8/Pz//T09P/09PT/9PT0//T09P/09PT/9PT0//X1 + 9f/19fX/9fX1//X19f/19fX/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2Mf///wH///8B////Af// + /wHw8PDj8PDw//Dw8P/v7+//7+/v/+/v7//u7u7/7u7u/+7u7v/t7e3/7e3t/+3t7f/s7Oz/7Ozs/+zs + 7P/s7Oz/6+vr/+vr6//r6+v/6urq/+rq6v/p6en/6enp/+np6f/o6Oj/6Ojo/+jo6P/n5+f/5+fn/+fn + 5//n5+f/5ubm/+bm5v/m5ub/5ubm/+bm5v/m5ub/5ubm/+fn5//n5+f/5+fn/+Tk5P/MzMz/eHh4/zY2 + Nv8kJCT/IiIi/y0tLf+ampr/4ODg/+fn5//o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6enp/+np + 6f/p6en/6enp/+rq6v/q6ur/6urq/+rq6v/r6+v/6+vr/+vr6//s7Oz/7Ozs/+zs7P/t7e3/7e3t/+3t + 7f/t7e3/7u7u/+7u7v/u7u7/7+/v/+/v7//v7+//7+/v/+/v7//w8PD/8PDw//Dw8P/w8PD/8fHx//Hx + 8f/x8fH/8fHx//Hx8f/y8vL/8vLy//Ly8v/y8vL/8vLy//Pz8//z8/P/8/Pz//Pz8//z8/P/8/Pz//Pz + 8//09PT/9PT0//T09P/09PT/9PT0//X19f/19fX/9fX1//X19f/19fX/9fX1//b29v/29vb/9vb2//b2 + 9v/29vb/9vb2//f39//29vYx////Af///wH///8B////AfHx8ePx8fH/8PDw//Dw8P/w8PD/7+/v/+/v + 7//v7+//7+/v/+7u7v/u7u7/7u7u/+3t7f/t7e3/7e3t/+3t7f/s7Oz/7Ozs/+zs7P/r6+v/6+vr/+vr + 6//q6ur/6urq/+rq6v/p6en/6enp/+np6f/p6en/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo + 6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/k5OT/xcXF/3R0dP9MTEz/kZGR/+bm5v/p6en/6enp/+np + 6f/p6en/6enp/+np6f/q6ur/6urq/+rq6v/q6ur/6urq/+vr6//r6+v/6+vr/+vr6//r6+v/7Ozs/+zs + 7P/s7Oz/7e3t/+3t7f/t7e3/7u7u/+7u7v/u7u7/7u7u/+7u7v/v7+//7+/v/+/v7//v7+//8PDw//Dw + 8P/w8PD/8PDw//Dw8P/x8fH/8fHx//Hx8f/x8fH/8vLy//Ly8v/y8vL/8vLy//Ly8v/z8/P/8/Pz//Pz + 8//z8/P/8/Pz//Pz8//z8/P/9PT0//T09P/09PT/9PT0//T09P/09PT/9PT0//X19f/19fX/9fX1//X1 + 9f/19fX/9fX1//b29v/29vb/9vb2//b29v/29vb/9vb2//f39//39/f/9/f3//b29jH///8B////Af// + /wH///8B8fHx4/Hx8f/x8fH/8fHx//Dw8P/w8PD/8PDw/+/v7//v7+//7+/v/+/v7//u7u7/7u7u/+7u + 7v/t7e3/7e3t/+3t7f/t7e3/7e3t/+zs7P/s7Oz/6+vr/+vr6//r6+v/6urq/+rq6v/q6ur/6urq/+np + 6f/p6en/6enp/+np6f/p6en/6enp/+np6f/p6en/6enp/+np6f/p6en/6enp/+np6f/p6en/6enp/+np + 6f/p6en/3d3d/83Nzf/h4eH/6urq/+rq6v/q6ur/6urq/+rq6v/q6ur/6urq/+rq6v/q6ur/6urq/+vr + 6//r6+v/6+vr/+vr6//s7Oz/7Ozs/+zs7P/s7Oz/7e3t/+3t7f/t7e3/7u7u/+7u7v/u7u7/7u7u/+7u + 7v/v7+//7+/v/+/v7//v7+//8PDw//Dw8P/w8PD/8PDw//Dw8P/w8PD/8fHx//Hx8f/x8fH/8fHx//Ly + 8v/y8vL/8vLy//Ly8v/y8vL/8/Pz//Pz8//z8/P/8/Pz//Pz8//z8/P/9PT0//T09P/09PT/9PT0//T0 + 9P/09PT/9PT0//X19f/19fX/9fX1//X19f/19fX/9fX1//b29v/29vb/9vb2//b29v/29vb/9vb2//b2 + 9v/39/f/9/f3//f39//39/f/9vb2Mf///wH///8B////Af///wHy8vLj8fHx//Hx8f/x8fH/8fHx//Dw + 8P/w8PD/8PDw//Dw8P/v7+//7+/v/+/v7//v7+//7u7u/+7u7v/u7u7/7u7u/+3t7f/t7e3/7e3t/+3t + 7f/t7e3/7Ozs/+zs7P/s7Oz/7Ozs/+vr6//r6+v/6+vr/+vr6//r6+v/6urq/+rq6v/q6ur/6urq/+rq + 6v/q6ur/6urq/+rq6v/q6ur/6urq/+rq6v/q6ur/6urq/+rq6v/q6ur/6urq/+rq6v/r6+v/6+vr/+vr + 6//r6+v/6+vr/+vr6//r6+v/6+vr/+vr6//r6+v/7Ozs/+zs7P/s7Oz/7Ozs/+zs7P/t7e3/7e3t/+3t + 7f/u7u7/7u7u/+7u7v/u7u7/7u7u/+/v7//v7+//7+/v/+/v7//v7+//8PDw//Dw8P/w8PD/8PDw//Dw + 8P/x8fH/8fHx//Hx8f/x8fH/8fHx//Ly8v/y8vL/8vLy//Ly8v/y8vL/8/Pz//Pz8//z8/P/8/Pz//Pz + 8//z8/P/9PT0//T09P/09PT/9PT0//T09P/09PT/9PT0//T09P/19fX/9fX1//X19f/19fX/9fX1//X1 + 9f/19fX/9vb2//b29v/29vb/9vb2//b29v/29vb/9/f3//f39//39/f/9/f3//f39//39/cx////Af// + /wH///8B////AfLy8uPy8vL/8vLy//Ly8v/y8vL/8fHx//Hx8f/x8fH/8PDw//Dw8P/w8PD/8PDw/+/v + 7//v7+//7+/v/+/v7//u7u7/7u7u/+7u7v/u7u7/7u7u/+3t7f/t7e3/7e3t/+3t7f/s7Oz/7Ozs/+zs + 7P/s7Oz/7Ozs/+vr6//r6+v/6+vr/+vr6//r6+v/6+vr/+vr6//r6+v/6+vr/+vr6//r6+v/6+vr/+vr + 6//r6+v/6+vr/+vr6//r6+v/6+vr/+zs7P/s7Oz/7Ozs/+zs7P/s7Oz/7Ozs/+zs7P/s7Oz/7Ozs/+zs + 7P/t7e3/7e3t/+3t7f/t7e3/7e3t/+7u7v/u7u7/7u7u/+7u7v/v7+//7+/v/+/v7//v7+//7+/v//Dw + 8P/w8PD/8PDw//Dw8P/w8PD/8fHx//Hx8f/x8fH/8fHx//Hx8f/x8fH/8vLy//Ly8v/y8vL/8vLy//Ly + 8v/z8/P/8/Pz//Pz8//z8/P/8/Pz//Pz8//09PT/9PT0//T09P/09PT/9PT0//T09P/09PT/9fX1//X1 + 9f/19fX/9fX1//X19f/19fX/9fX1//b29v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9/f3//f3 + 9//39/f/9/f3//f39//39/f/9/f3//j4+DH///8B////Af///wH///8B8/Pz4/Pz8//y8vL/8vLy//Ly + 8v/y8vL/8fHx//Hx8f/x8fH/8fHx//Dw8P/w8PD/8PDw//Dw8P/w8PD/7+/v/+/v7//v7+//7+/v/+/v + 7//u7u7/7u7u/+7u7v/u7u7/7e3t/+3t7f/t7e3/7e3t/+3t7f/s7Oz/7Ozs/+zs7P/s7Oz/7Ozs/+zs + 7P/s7Oz/7Ozs/+zs7P/s7Oz/7Ozs/+zs7P/s7Oz/7Ozs/+zs7P/s7Oz/7Ozs/+zs7P/s7Oz/7Ozs/+zs + 7P/s7Oz/7e3t/+3t7f/t7e3/7e3t/+3t7f/t7e3/7e3t/+3t7f/t7e3/7u7u/+7u7v/u7u7/7u7u/+/v + 7//v7+//7+/v/+/v7//v7+//8PDw//Dw8P/w8PD/8PDw//Dw8P/x8fH/8fHx//Hx8f/x8fH/8fHx//Hx + 8f/x8fH/8vLy//Ly8v/y8vL/8vLy//Ly8v/z8/P/8/Pz//Pz8//z8/P/8/Pz//Pz8//09PT/9PT0//T0 + 9P/09PT/9PT0//T09P/09PT/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/29vb/9vb2//b2 + 9v/29vb/9vb2//b29v/29vb/9vb2//f39//39/f/9/f3//f39//39/f/9/f3//f39//4+Pj/+Pj4Mf// + /wH///8B////Af///wHz8/Pj8/Pz//Pz8//z8/P/8/Pz//Ly8v/y8vL/8vLy//Ly8v/x8fH/8fHx//Hx + 8f/x8fH/8fHx//Dw8P/w8PD/8PDw//Dw8P/w8PD/8PDw/+/v7//v7+//7+/v/+/v7//v7+//7u7u/+7u + 7v/u7u7/7u7u/+7u7v/u7u7/7e3t/+3t7f/t7e3/7e3t/+3t7f/t7e3/7e3t/+3t7f/t7e3/7e3t/+3t + 7f/t7e3/7e3t/+3t7f/t7e3/7e3t/+3t7f/t7e3/7e3t/+3t7f/u7u7/7u7u/+7u7v/u7u7/7u7u/+7u + 7v/u7u7/7u7u/+7u7v/v7+//7+/v/+/v7//v7+//7+/v//Dw8P/w8PD/8PDw//Dw8P/w8PD/8fHx//Hx + 8f/x8fH/8fHx//Hx8f/x8fH/8vLy//Ly8v/y8vL/8vLy//Ly8v/y8vL/8vLy//Pz8//z8/P/8/Pz//Pz + 8//z8/P/8/Pz//T09P/09PT/9PT0//T09P/09PT/9PT0//T09P/19fX/9fX1//X19f/19fX/9fX1//X1 + 9f/19fX/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b29v/39/f/9/f3//f39//39/f/9/f3//f3 + 9//39/f/9/f3//j4+P/4+Pj/+Pj4//j4+P/4+Pgx////Af///wH///8B////AfT09OP09PT/8/Pz//Pz + 8//z8/P/8/Pz//Pz8//y8vL/8vLy//Ly8v/y8vL/8vLy//Hx8f/x8fH/8fHx//Hx8f/w8PD/8PDw//Dw + 8P/w8PD/8PDw//Dw8P/w8PD/8PDw/+/v7//v7+//7+/v/+/v7//u7u7/7u7u/+7u7v/u7u7/7u7u/+7u + 7v/u7u7/7u7u/+7u7v/u7u7/7u7u/+7u7v/u7u7/7u7u/+7u7v/u7u7/7u7u/+7u7v/u7u7/7u7u/+7u + 7v/u7u7/7u7u/+7u7v/u7u7/7u7u/+7u7v/u7u7/7+/v/+/v7//v7+//7+/v/+/v7//v7+//8PDw//Dw + 8P/w8PD/8PDw//Dw8P/x8fH/8fHx//Hx8f/x8fH/8fHx//Hx8f/x8fH/8vLy//Ly8v/y8vL/8vLy//Ly + 8v/y8vL/8vLy//Pz8//z8/P/8/Pz//Pz8//z8/P/8/Pz//T09P/09PT/9PT0//T09P/09PT/9PT0//X1 + 9f/19fX/9fX1//X19f/19fX/9fX1//X19f/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b2 + 9v/29vb/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//j4+P/4+Pj/+Pj4//j4+P/4+Pj/+Pj4//j4 + +DH///8B////AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA + + + \ No newline at end of file diff --git a/ROMVault2/FrmProgressWindowFix.cs b/ROMVault2/FrmProgressWindowFix.cs new file mode 100644 index 0000000..9bbaa30 --- /dev/null +++ b/ROMVault2/FrmProgressWindowFix.cs @@ -0,0 +1,181 @@ +/****************************************************** + * ROMVault2 is written by Gordon J. * + * Contact gordon@romvault.com * + * Copyright 2014 * + ******************************************************/ + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Threading; +using System.Windows.Forms; +using ROMVault2.Properties; + +namespace ROMVault2 +{ + public partial class FrmProgressWindowFix : Form + { + + private bool _bDone; + private readonly Form _parentForm; + + private readonly Queue _rowQueue; + + public FrmProgressWindowFix(Form parentForm) + { + _rowQueue = new Queue(); + _parentForm = parentForm; + InitializeComponent(); + timer1.Interval = 100; + timer1.Enabled = true; + } + + + private void Timer1Tick(object sender, EventArgs e) + { + int rowCount = _rowQueue.Count; + if (rowCount == 0) + return; + + DataGridViewRow[] dgvr = new DataGridViewRow[rowCount]; + for (int i = 0; i < rowCount; i++) + dgvr[i] = _rowQueue.Dequeue(); + + dataGridView1.Rows.AddRange(dgvr); + int iRow = dataGridView1.Rows.Count - 1; + dataGridView1.FirstDisplayedScrollingRowIndex = iRow; + } + + + + protected override CreateParams CreateParams + { + get + { + const int CP_NOCLOSE_BUTTON = 0x200; + CreateParams mdiCp = base.CreateParams; + mdiCp.ClassStyle = mdiCp.ClassStyle | CP_NOCLOSE_BUTTON; + return mdiCp; + } + } + + + + private void FrmProgressWindowFixShown(object sender, EventArgs e) + { + bgWork.DoWork += FixFiles.PerformFixes; + bgWork.ProgressChanged += BgwProgressChanged; + bgWork.RunWorkerCompleted += BgwRunWorkerCompleted; + bgWork.RunWorkerAsync(SynchronizationContext.Current); + } + + private void BgwProgressChanged(object sender, ProgressChangedEventArgs e) + { + BgwProgressChanged(e.UserState); + } + + private void BgwProgressChanged(object e) + { + + + bgwShowFix bgwSf = e as bgwShowFix; + if (bgwSf != null) + { + DataGridViewRow dgrq = (DataGridViewRow)dataGridView1.RowTemplate.Clone(); + dgrq.CreateCells(dataGridView1, bgwSf.FixDir, bgwSf.FixZip, bgwSf.FixFile, bgwSf.Size, bgwSf.Dir, bgwSf.SourceDir, bgwSf.SourceZip, bgwSf.SourceFile); + _rowQueue.Enqueue(dgrq); + return; + + } + + bgwShowFixError bgwSFE = e as bgwShowFixError; + if (bgwSFE != null) + { + int iRow = dataGridView1.Rows.Count - 1; + dataGridView1.Rows[iRow].Cells[4].Style.BackColor = Color.Red; + dataGridView1.Rows[iRow].Cells[4].Style.ForeColor = Color.Black; + dataGridView1.Rows[iRow].Cells[4].Value = bgwSFE.FixError; + return; + } + + bgwProgress bgwProg = e as bgwProgress; + if (bgwProg != null) + { + if (bgwProg.Progress >= progressBar.Minimum && bgwProg.Progress <= progressBar.Maximum) + progressBar.Value = bgwProg.Progress; + UpdateStatusText(); + return; + } + + bgwText bgwT = e as bgwText; + if (bgwT != null) + { + label.Text = bgwT.Text; + return; + } + bgwSetRange bgwSR = e as bgwSetRange; + if (bgwSR != null) + { + progressBar.Minimum = 0; + progressBar.Maximum = bgwSR.MaxVal >= 0 ? bgwSR.MaxVal : 0; + progressBar.Value = 0; + UpdateStatusText(); + } + + + } + + private void BgwRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) + { + + cancelButton.Text = Resources.ProgressWindowFix_DoDone_Close; + cancelButton.Enabled = true; + _bDone = true; + } + + private void UpdateStatusText() + { + int range = progressBar.Maximum - progressBar.Minimum; + int percent = range > 0 ? (progressBar.Value * 100) / range : 0; + + Text = String.Format("Fixing Files - {0}% complete", percent); + } + + private void CancelButtonClick(object sender, EventArgs e) + { + if (_bDone) + Close(); + else + { + cancelButton.Enabled = false; + cancelButton.Text = Resources.ProgressWindowFix_OnClosing_Cancelling; + bgWork.CancelAsync(); + } + } + + private void DataGridView1SelectionChanged(object sender, EventArgs e) + { + dataGridView1.ClearSelection(); + } + + private void FrmProgressWindowFixResize(object sender, EventArgs e) + { + switch (WindowState) + { + case FormWindowState.Minimized: + if (_parentForm.Visible) _parentForm.Hide(); + return; + case FormWindowState.Maximized: + if (!_parentForm.Visible) _parentForm.Show(); + return; + case FormWindowState.Normal: + if (!_parentForm.Visible) _parentForm.Show(); + return; + } + } + + + + } +} diff --git a/ROMVault2/FrmProgressWindowFix.designer.cs b/ROMVault2/FrmProgressWindowFix.designer.cs new file mode 100644 index 0000000..59397e0 --- /dev/null +++ b/ROMVault2/FrmProgressWindowFix.designer.cs @@ -0,0 +1,290 @@ +namespace ROMVault2 +{ + partial class FrmProgressWindowFix + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FrmProgressWindowFix)); + this.splitContainer1 = new System.Windows.Forms.SplitContainer(); + this.cancelButton = new System.Windows.Forms.Button(); + this.progressBar = new System.Windows.Forms.ProgressBar(); + this.label = new System.Windows.Forms.Label(); + this.dataGridView1 = new System.Windows.Forms.DataGridView(); + this.DatTo = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.GameTo = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.RomTo = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.FileSize = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.Status = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.DatFrom = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.GameFrom = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.ROMFrom = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.dataGridViewTextBoxColumn1 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.dataGridViewTextBoxColumn2 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.dataGridViewTextBoxColumn3 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.dataGridViewTextBoxColumn4 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.dataGridViewTextBoxColumn5 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.dataGridViewTextBoxColumn6 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.dataGridViewTextBoxColumn7 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.bgWork = new System.ComponentModel.BackgroundWorker(); + this.timer1 = new System.Windows.Forms.Timer(this.components); + this.splitContainer1.Panel1.SuspendLayout(); + this.splitContainer1.Panel2.SuspendLayout(); + this.splitContainer1.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit(); + this.SuspendLayout(); + // + // splitContainer1 + // + this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill; + this.splitContainer1.FixedPanel = System.Windows.Forms.FixedPanel.Panel1; + this.splitContainer1.Location = new System.Drawing.Point(0, 0); + this.splitContainer1.Name = "splitContainer1"; + this.splitContainer1.Orientation = System.Windows.Forms.Orientation.Horizontal; + // + // splitContainer1.Panel1 + // + this.splitContainer1.Panel1.Controls.Add(this.cancelButton); + this.splitContainer1.Panel1.Controls.Add(this.progressBar); + this.splitContainer1.Panel1.Controls.Add(this.label); + // + // splitContainer1.Panel2 + // + this.splitContainer1.Panel2.Controls.Add(this.dataGridView1); + this.splitContainer1.Size = new System.Drawing.Size(1027, 500); + this.splitContainer1.SplitterDistance = 64; + this.splitContainer1.TabIndex = 7; + // + // cancelButton + // + this.cancelButton.Location = new System.Drawing.Point(759, 32); + this.cancelButton.Name = "cancelButton"; + this.cancelButton.Size = new System.Drawing.Size(75, 23); + this.cancelButton.TabIndex = 9; + this.cancelButton.Text = "Cancel"; + this.cancelButton.Click += new System.EventHandler(this.CancelButtonClick); + // + // progressBar + // + this.progressBar.Location = new System.Drawing.Point(12, 32); + this.progressBar.Name = "progressBar"; + this.progressBar.Size = new System.Drawing.Size(741, 23); + this.progressBar.TabIndex = 8; + // + // label + // + this.label.Location = new System.Drawing.Point(13, 9); + this.label.Name = "label"; + this.label.Size = new System.Drawing.Size(480, 20); + this.label.TabIndex = 4; + this.label.Text = "Starting operation..."; + // + // dataGridView1 + // + this.dataGridView1.AllowUserToAddRows = false; + this.dataGridView1.AllowUserToDeleteRows = false; + this.dataGridView1.AllowUserToResizeRows = false; + this.dataGridView1.BackgroundColor = System.Drawing.Color.White; + this.dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; + this.dataGridView1.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { + this.DatTo, + this.GameTo, + this.RomTo, + this.FileSize, + this.Status, + this.DatFrom, + this.GameFrom, + this.ROMFrom}); + this.dataGridView1.Dock = System.Windows.Forms.DockStyle.Fill; + this.dataGridView1.GridColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224))))); + this.dataGridView1.Location = new System.Drawing.Point(0, 0); + this.dataGridView1.MultiSelect = false; + this.dataGridView1.Name = "dataGridView1"; + this.dataGridView1.ReadOnly = true; + this.dataGridView1.RowHeadersVisible = false; + this.dataGridView1.RowTemplate.Height = 17; + this.dataGridView1.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect; + this.dataGridView1.ShowCellErrors = false; + this.dataGridView1.ShowCellToolTips = false; + this.dataGridView1.ShowEditingIcon = false; + this.dataGridView1.ShowRowErrors = false; + this.dataGridView1.Size = new System.Drawing.Size(1027, 432); + this.dataGridView1.TabIndex = 7; + this.dataGridView1.SelectionChanged += new System.EventHandler(this.DataGridView1SelectionChanged); + // + // DatTo + // + this.DatTo.HeaderText = "Directory (Fixing)"; + this.DatTo.Name = "DatTo"; + this.DatTo.ReadOnly = true; + this.DatTo.Width = 250; + // + // GameTo + // + this.GameTo.HeaderText = "Archive (Fixing)"; + this.GameTo.Name = "GameTo"; + this.GameTo.ReadOnly = true; + this.GameTo.Width = 200; + // + // RomTo + // + this.RomTo.HeaderText = "File (Fixing)"; + this.RomTo.Name = "RomTo"; + this.RomTo.ReadOnly = true; + this.RomTo.Width = 200; + // + // FileSize + // + this.FileSize.HeaderText = "Size (Fixing)"; + this.FileSize.Name = "FileSize"; + this.FileSize.ReadOnly = true; + // + // Status + // + this.Status.HeaderText = "Status"; + this.Status.Name = "Status"; + this.Status.ReadOnly = true; + // + // DatFrom + // + this.DatFrom.HeaderText = "Directory (From)"; + this.DatFrom.Name = "DatFrom"; + this.DatFrom.ReadOnly = true; + this.DatFrom.Width = 150; + // + // GameFrom + // + this.GameFrom.HeaderText = "Archive (From)"; + this.GameFrom.Name = "GameFrom"; + this.GameFrom.ReadOnly = true; + // + // ROMFrom + // + this.ROMFrom.HeaderText = "File (From)"; + this.ROMFrom.Name = "ROMFrom"; + this.ROMFrom.ReadOnly = true; + // + // dataGridViewTextBoxColumn1 + // + this.dataGridViewTextBoxColumn1.HeaderText = "Dat (Fixing)"; + this.dataGridViewTextBoxColumn1.Name = "dataGridViewTextBoxColumn1"; + this.dataGridViewTextBoxColumn1.ReadOnly = true; + this.dataGridViewTextBoxColumn1.Width = 150; + // + // dataGridViewTextBoxColumn2 + // + this.dataGridViewTextBoxColumn2.HeaderText = "Game (Fixing)"; + this.dataGridViewTextBoxColumn2.Name = "dataGridViewTextBoxColumn2"; + this.dataGridViewTextBoxColumn2.ReadOnly = true; + // + // dataGridViewTextBoxColumn3 + // + this.dataGridViewTextBoxColumn3.HeaderText = "ROM (Fixing)"; + this.dataGridViewTextBoxColumn3.Name = "dataGridViewTextBoxColumn3"; + this.dataGridViewTextBoxColumn3.ReadOnly = true; + // + // dataGridViewTextBoxColumn4 + // + this.dataGridViewTextBoxColumn4.HeaderText = "Status"; + this.dataGridViewTextBoxColumn4.Name = "dataGridViewTextBoxColumn4"; + this.dataGridViewTextBoxColumn4.ReadOnly = true; + // + // dataGridViewTextBoxColumn5 + // + this.dataGridViewTextBoxColumn5.HeaderText = "Dat (From)"; + this.dataGridViewTextBoxColumn5.Name = "dataGridViewTextBoxColumn5"; + this.dataGridViewTextBoxColumn5.ReadOnly = true; + this.dataGridViewTextBoxColumn5.Width = 150; + // + // dataGridViewTextBoxColumn6 + // + this.dataGridViewTextBoxColumn6.HeaderText = "Game (From)"; + this.dataGridViewTextBoxColumn6.Name = "dataGridViewTextBoxColumn6"; + this.dataGridViewTextBoxColumn6.ReadOnly = true; + // + // dataGridViewTextBoxColumn7 + // + this.dataGridViewTextBoxColumn7.HeaderText = "Rom (From)"; + this.dataGridViewTextBoxColumn7.Name = "dataGridViewTextBoxColumn7"; + this.dataGridViewTextBoxColumn7.ReadOnly = true; + // + // bgWork + // + this.bgWork.WorkerReportsProgress = true; + this.bgWork.WorkerSupportsCancellation = true; + // + // timer1 + // + this.timer1.Tick += new System.EventHandler(this.Timer1Tick); + // + // FrmProgressWindowFix + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.BackColor = System.Drawing.Color.White; + this.ClientSize = new System.Drawing.Size(1027, 500); + this.Controls.Add(this.splitContainer1); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Name = "FrmProgressWindowFix"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "Fixing Files"; + this.Shown += new System.EventHandler(this.FrmProgressWindowFixShown); + this.Resize += new System.EventHandler(this.FrmProgressWindowFixResize); + this.splitContainer1.Panel1.ResumeLayout(false); + this.splitContainer1.Panel2.ResumeLayout(false); + this.splitContainer1.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).EndInit(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn1; + private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn2; + private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn3; + private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn4; + private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn5; + private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn6; + private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn7; + private System.Windows.Forms.SplitContainer splitContainer1; + private System.Windows.Forms.Label label; + private System.Windows.Forms.Button cancelButton; + private System.Windows.Forms.ProgressBar progressBar; + private System.ComponentModel.BackgroundWorker bgWork; + private System.Windows.Forms.DataGridViewTextBoxColumn DatTo; + private System.Windows.Forms.DataGridViewTextBoxColumn GameTo; + private System.Windows.Forms.DataGridViewTextBoxColumn RomTo; + private System.Windows.Forms.DataGridViewTextBoxColumn Status; + private System.Windows.Forms.DataGridViewTextBoxColumn DatFrom; + private System.Windows.Forms.DataGridViewTextBoxColumn GameFrom; + private System.Windows.Forms.DataGridViewTextBoxColumn ROMFrom; + private System.Windows.Forms.DataGridViewTextBoxColumn FileSize; + private System.Windows.Forms.DataGridView dataGridView1; + private System.Windows.Forms.Timer timer1; + } +} \ No newline at end of file diff --git a/ROMVault2/FrmProgressWindowFix.resx b/ROMVault2/FrmProgressWindowFix.resx new file mode 100644 index 0000000..1c6a769 --- /dev/null +++ b/ROMVault2/FrmProgressWindowFix.resx @@ -0,0 +1,1817 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + 17, 17 + + + 112, 17 + + + + + AAABAAUAEBAAAAAAIABoBAAAVgAAACAgAAAAACAAqBAAAL4EAAAwMAAAAAAgAKglAABmFQAAQEAAAAAA + IAAoQgAADjsAAICAAAAAACAAKAgBADZ9AAAoAAAAEAAAACAAAAABACAAAAAAAEAEAAAAAAAAAAAAAAAA + AAAAAAAA7e3tvevr6//m5ub/4ODg/9nZ2f/Q0ND/wsLC/66urv+ampr/nJyc/6Kiov+tra3/ubm5/8XF + xf/R0dH/2trapenp6b3l5eX/3t7e/9bW1v/Kysr/ubm5/5+fn/92dnb/ampq/21tbf97e3v/jIyM/56e + nv+wsLD/wsLC/8/Pz6Xl5eW939/f/9bW1v/Jycn/uLi4/5ycnP9ubm7/YWFh/2pqav8tLS3/RERE/2lp + af+AgID/mJiY/7Kysv/FxcWl39/fvdjY2P/Ly8v/ubm5/56env9ycnL/VlZW/2RkZP92dnb/IyMj/yAg + IP8qKir/VlZW/319ff+ioqL/v7+/pdnZ2b3Nzc3/u7u7/6Kiov94eHj/U1NT/15eXv99fX3/IiIi/yYm + Jv8lJSX/IyMj/yAgIP8+Pj7/hoaG/76+vqXQ0NC9wMDA/6ampv+AgID/U1NT/1tbW/+BgYH/ISEh/yUl + Jf8lJSX/JiYm/yYmJv8lJSX/IiIi/2BgYP/Dw8OlxsbGva6urv+Hh4f/VlZW/1paWv+BgYH/JCQk/yUl + Jf8kJCT/JSUl/yUlJf8mJib/JiYm/yQkJP91dXX/zc3Npby8vL2Wlpb/XV1d/1tbW/+AgID/JiYm/zs7 + O/9ubm7/YWFh/ykpKf8kJCT/JSUl/yUlJf9ZWVn/xcXF/9XV1aW4uLi9dXV1/2JiYv9/f3//Kysr/0BA + QP/FxcX/zMzM/8vLy/+hoaH/JCQk/yQkJP9NTU3/v7+//9LS0v/c3NylvLy8vXJycv9/f3//NjY2/yMj + I/9lZWX/zc3N/83Nzf/MzMz/ycnJ/ykpKf9DQ0P/uLi4/9DQ0P/c3Nz/4+PjpcDAwL1/f3//QkJC/yQi + Iv8jIyP/Li4u/6ioqP/MzMz/ysrK/3h4eP88PDz/s7Oz/8/Pz//b29v/4+Pj/+jo6KXR0dG9bm5u/yQi + Iv9hJRr/SCQd/0QkHv8yJCH/Ozs7/zExMf82Njb/r6+v/9HR0f/b29v/4+Pj/+jo6P/s7Oyl29vbvX9/ + f/8lJSX/PiMe/1okGv9dJBr/VSQc/zokIP8yMjL/rq6u/9XV1f/e3t7/5OTk/+np6f/t7e3/8PDwpeXl + 5b3f39//t7e3/2tra/8lJSX/RyMd/1QlHP8vLi7/ra2t/93d3f/j4+P/6Ojo/+vr6//u7u7/8fHx//Pz + 86Xs7Oy96enp/+bm5v/i4uL/n5+f/zY2Nv9JSUn/q6ur/+bm5v/p6en/7Ozs/+7u7v/w8PD/8vLy//T0 + 9P/19fWl8fHxvfDw8P/u7u7/7Ozs/+rq6v/g4OD/39/f/+zs7P/u7u7/7+/v//Hx8f/y8vL/9PT0//X1 + 9f/29vb/9/f3pQAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA + //8AAP//AAD//wAA//8oAAAAIAAAAEAAAAABACAAAAAAAIAQAAAAAAAAAAAAAAAAAAAAAAAA7+/vee7u + 7v/t7e3/6+vr/+np6f/n5+f/5OTk/+Hh4f/e3t7/29vb/9fX1//T09P/zc3N/8XFxf++vr7/uLi4/7Cw + sP+rq6v/qKio/6ioqP+rq6v/rq6u/7Kysv+4uLj/vb29/8LCwv/Hx8f/zMzM/9HR0f/X19f/3Nzc/9/f + 303t7e157Ozs/+rq6v/o6Oj/5ubm/+Pj4//g4OD/3Nzc/9jY2P/U1NT/z8/P/8jIyP/AwMD/tra2/6qq + qv+YmJj/goKC/42Njf+NjY3/kZGR/5aWlv+bm5v/oqKi/6qqqv+wsLD/tra2/729vf/Dw8P/ysrK/9HR + 0f/X19f/29vbTevr63nq6ur/6Ojo/+Xl5f/i4uL/3t7e/9vb2//W1tb/0tLS/8zMzP/ExMT/u7u7/7Gx + sf+jo6P/kJCQ/3Z2dv9mZmb/c3Nz/3R0dP96enr/gICA/4iIiP+RkZH/mZmZ/6Ghof+pqan/sbGx/7m5 + uf/CwsL/ysrK/9HR0f/W1tZN6enpeefn5//l5eX/4uLi/97e3v/a2tr/1dXV/9DQ0P/Kysr/wsLC/7m5 + uf+tra3/n5+f/4mJif9ra2v/aWlp/29vb/9hYWH/YWFh/2dnZ/9tbW3/dXV1/35+fv+IiIj/kpKS/5yc + nP+lpaX/r6+v/7m5uf/CwsL/y8vL/9HR0U3n5+d55eXl/+Li4v/f39//29vb/9bW1v/Q0ND/ycnJ/8LC + wv+4uLj/ra2t/52dnf+IiIj/a2tr/0tLS/9oaGj/enp6/1hYWP9ERET/Ly8v/1NTU/9kZGT/bW1t/3d3 + d/+CgoL/jY2N/5iYmP+kpKT/sLCw/7u7u//Gxsb/zMzMTeXl5Xnj4+P/39/f/9vb2//X19f/0dHR/8rK + yv/BwcH/uLi4/62trf+enp7/iYmJ/2tra/9bW1v/WFhY/3h4eP91dXX/X19f/yAgIP8iIiL/Hx8f/zk5 + Of9aWlr/Z2dn/3Jycv9+fn7/i4uL/5mZmf+np6f/tbW1/8HBwf/JyclN4uLieeDg4P/c3Nz/2NjY/9LS + 0v/Kysr/wsLC/7i4uP+tra3/n5+f/4uLi/9tbW3/Q0ND/11dXf9dXV3/aWlp/5WVlf+QkJD/IiIi/yEh + If8eHh7/Hh4e/yQkJP9HR0f/YmJi/29vb/99fX3/jIyM/52dnf+vr6//vr6+/8fHx03g4OB53d3d/9jY + 2P/T09P/zMzM/8PDw/+5ubn/rq6u/6CgoP+MjIz/cnJy/19fX/9NTU3/ampq/3d3d/9TU1P/jo6O/yYm + Jv8jIyP/JiYm/yQkJP8hISH/Hh4e/x4eHv8wMDD/WFhY/21tbf99fX3/kpKS/6mpqf+8vLz/xsbGTd7e + 3nna2tr/1NTU/83Nzf/ExMT/u7u7/6+vr/+hoaH/j4+P/3V1df9HR0f/Wlpa/1ZWVv9paWn/fn5+/5ub + m/8dHR3/IyMj/yYmJv8mJib/JiYm/yUlJf8jIyP/Hx8f/x4eHv8hISH/QEBA/2xsbP+IiIj/o6Oj/7u7 + u//Hx8dN2traedXV1f/Ozs7/xsbG/7y8vP+xsbH/pKSk/5KSkv97e3v/ZGRk/0pKSv9gYGD/dXV1/0JC + Qv+qqqr/MjIy/yMjI/8mJib/JiYm/yYmJv8mJib/JiYm/yUlJf8lJSX/ISEh/x8fH/8fHx//LS0t/1JS + Uv+cnJz/u7u7/8fHx03W1tZ50dHR/8nJyf+/v7//s7Oz/6ampv+UlJT/fX19/01NTf9ZWVn/WFhY/2ho + aP9ubm7/mJiY/xsbG/8hISH/JSUl/yUlJf8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8lJSX/JCQk/yEh + If8gICD/KSkp/5ycnP++vr7/ycnJTdLS0nnMzMz/wsLC/7a2tv+pqan/l5eX/4KCgv9sbGz/SkpK/1tb + W/91dXX/Nzc3/7W1tf9HR0f/IiIi/yQkJP8lJSX/JSUl/yUlJf8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JSUl/yMjI/8jIyP/mJiY/8XFxf/MzMxNzs7OecfHx/+7u7v/ra2t/5ubm/+Ghob/WVlZ/1lZ + Wf9dXV3/ZWVl/2hoaP+Kior/KSkp/yEhIf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JSUl/zIyMv+goKD/ysrK/9DQ0E3Kysp5wcHB/7Kysv+goKD/ioqK/3Jy + cv9PT0//V1dX/3V1df8zMzP/q6ur/2ZmZv8gICD/JCQk/yUlJf8lJSX/JCQk/yQkJP8kJCT/JSUl/yUl + Jf8lJSX/JiYm/yYmJv8mJib/JiYm/yYmJv8hISH/Q0ND/76+vv/Nzc3/09PTTcXFxXm7u7v/qKio/5GR + kf9mZmb/Xl5e/2JiYv9eXl7/bGxs/3d3d/82Njb/Hx8f/yQkJP8kJCT/JSUl/ycnJ/8lJSX/JCQk/yQk + JP8kJCT/JSUl/yUlJf8lJSX/JSUl/yYmJv8mJib/Kioq/1hYWP+3t7f/ycnJ/9HR0f/X19dNwsLCebW1 + tf+enp7/gYGB/1hYWP9WVlb/dXV1/zg4OP+UlJT/ioqK/x8fH/8kJCT/LCws/3l5ef+tra3/v7+//7S0 + tP+IiIj/OTk5/yQkJP8kJCT/JCQk/yUlJf8lJSX/JSUl/yQkJP8xMTH/sbGx/8bGxv/Ozs7/1tbW/9ra + 2k3BwcF5srKy/4iIiP9xcXH/bGxs/1tbW/92dnb/YWFh/05OTv8eHh7/IyMj/zMzM/+wsLD/zMzM/8vL + y//Ly8v/zMzM/8vLy//BwcH/SkpK/yMjI/8kJCT/JCQk/yUlJf8oKCj/QkJC/6qqqv/ExMT/zMzM/9PT + 0//Z2dn/3d3dTcLCwnm0tLT/enp6/2FhYf97e3v/SEhI/319ff+np6f/ISEh/yEhIf8jIyP/iIiI/8zM + zP/MzMz/zc3N/83Nzf/MzMz/y8vL/8rKyv+vr6//JSUl/yQkJP8kJCT/IyMj/yUlJf+lpaX/w8PD/8vL + y//R0dH/19fX/93d3f/g4OBNw8PDebm5uf+JiYn/Y2Nj/4GBgf9WVlb/Y2Nj/ykpKf8hISH/IyMj/yQk + JP+wsLD/zc3N/83Nzf/Nzc3/zc3N/8zMzP/Ly8v/y8vL/8zMzP8zMzP/JCQk/yUlJf8zMzP/lpaW/8HB + wf/Kysr/0dHR/9fX1//c3Nz/4ODg/+Pj403FxcV5tra2/4aGhv9WVlb/bm5u/7i4uP8rKyv/ISEh/yQk + JP8kJCT/JCQk/52dnf/Nzc3/zc3N/83Nzf/Nzc3/zMzM/8zMzP/Ly8v/wcHB/yoqKv8jIyP/ICAg/5aW + lv/AwMD/ycnJ/9DQ0P/X19f/3Nzc/+Dg4P/k5OT/5ubmTcnJyXm2trb/jY2N/1JSUv9zc3P/PDw8/yEh + If8jIyP/IyMj/yMjI/8kJCT/T09P/8nJyf/Nzc3/zc3N/83Nzf/Nzc3/zMzM/8vLy/95eXn/JCQk/ygo + KP+Dg4P/wMDA/8jIyP/Q0ND/1tbW/9vb2//g4OD/4+Pj/+bm5v/o6OhNzc3NecDAwP9nZ2f/tLS0/zw8 + PP8eHh7/IiIi/ysiIf8iIiL/IyMj/yMjI/8jIyP/VlZW/7e3t//MzMz/zc3N/8zMzP/ExMT/d3d3/yYm + Jv8dHR3/h4eH/8HBwf/Jycn/0NDQ/9bW1v/b29v/39/f/+Pj4//m5ub/6enp/+vr603S0tJ5zMzM/6mp + qf9VVVX/ICAg/yMjI/84Ix//ayYa/yIiIf8qIiH/NCMg/zQjIP8jIyP/JiYm/0hISP9dXV3/UVFR/y0t + Lf8jIyP/IiIi/2tra//BwcH/ysrK/9HR0f/W1tb/29vb/9/f3//j4+P/5ubm/+np6f/r6+v/7e3tTdfX + 13nS0tL/kpKS/ygoKP8jIyP/KyIg/3omF/9mJRn/cyYY/14lGv9TJRz/UyUc/1ckG/8oIyH/IyMj/yMj + I/8jIyP/IyMj/x0dHf93d3f/xMTE/8vLy//S0tL/19fX/9vb2//f39//4+Pj/+bm5v/o6Oj/6+vr/+3t + 7f/u7u5N29vbedfX1/+FhYX/IyMj/yMjI/8jISH/TyQc/2QkGP9yJhj/WyQa/2slGf86Ix7/XCUb/2Ml + G/8+Ix//JSMi/yMjI/8hISH/VVVV/8bGxv/Ozs7/1NTU/9nZ2f/d3d3/4ODg/+Pj4//m5ub/6Ojo/+vr + 6//t7e3/7+/v//Dw8E3g4OB53d3d/9PT0/9/f3//LCws/yIiIv8hISH/ISEh/0UjHf9XIxr/bCUY/2El + Gv8/Ix7/VSQc/10mG/8nIyL/Hx8f/2VlZf/Kysr/09PT/9fX1//b29v/39/f/+Li4v/l5eX/5+fn/+np + 6f/r6+v/7e3t/+/v7//w8PD/8fHxTeTk5Hni4uL/3t7e/9vb2//Dw8P/YGBg/yQkJP8iIiL/ISEh/yEh + If9fJRr/ZSUZ/1IkHP9eJRv/JSMi/yIiIv9AQED/ysrK/9jY2P/b29v/39/f/+Li4v/l5eX/5+fn/+np + 6f/q6ur/7Ozs/+7u7v/v7+//8fHx//Ly8v/z8/NN6Ojoeebm5v/k5OT/4eHh/9/f3//c3Nz/v7+//6io + qP8vLy//IiIi/yEhIf81IyD/ZiYa/zskIP8gICD/VFRU/83Nzf/d3d3/4ODg/+Pj4//l5eX/5+fn/+np + 6f/r6+v/7Ozs/+3t7f/v7+//8PDw//Hx8f/y8vL/8/Pz//T09E3s7Ox56+vr/+np6f/n5+f/5OTk/+Li + 4v/h4eH/39/f/5aWlv8wMDD/IiIi/yIiIv8jIyP/IiIi/ywsLP/Gxsb/4uLi/+Tk5P/m5ub/6Ojo/+np + 6f/r6+v/7Ozs/+7u7v/v7+//8PDw//Hx8f/y8vL/8/Pz//Pz8//09PT/9fX1Te7u7nnt7e3/7Ozs/+vr + 6//p6en/6Ojo/+bm5v/k5OT/4+Pj/9PT0/9vb2//JiYm/y0tLf+ysrL/1NTU/+bm5v/n5+f/6enp/+rq + 6v/s7Oz/7e3t/+7u7v/v7+//8PDw//Hx8f/y8vL/8vLy//Pz8//09PT/9fX1//X19f/29vZN8fHxefDw + 8P/v7+//7u7u/+3t7f/s7Oz/6urq/+np6f/o6Oj/6Ojo/+jo6P++vr7/urq6/+np6f/q6ur/6+vr/+vr + 6//t7e3/7u7u/+/v7//v7+//8PDw//Hx8f/y8vL/8/Pz//Pz8//09PT/9PT0//X19f/29vb/9vb2//f3 + 903z8/N58vLy//Hx8f/w8PD/8PDw/+/v7//u7u7/7e3t/+3t7f/s7Oz/7e3t/+3t7f/t7e3/7e3t/+3t + 7f/u7u7/7+/v//Dw8P/w8PD/8fHx//Ly8v/y8vL/8/Pz//T09P/09PT/9fX1//X19f/29vb/9vb2//f3 + 9//39/f/9/f3TQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAKAAAADAAAABgAAAAAQAgAAAAAACAJQAAAAAAAAAAAAAAAAAAAAAAAPDw + 8Dfv7+//7u7u/+3t7f/s7Oz/6+vr/+rq6v/p6en/5+fn/+Xl5f/j4+P/4eHh/9/f3//d3d3/29vb/9nZ + 2f/X19f/1NTU/9DQ0P/Ly8v/x8fH/8LCwv++vr7/urq6/7a2tv+xsbH/rq6u/62trf+srKz/rKys/62t + rf+vr6//sbGx/7S0tP+3t7f/u7u7/76+vv/BwcH/xcXF/8jIyP/Ly8v/z8/P/9LS0v/V1dX/2NjY/9zc + 3P/f39/x////Ae7u7jfu7u7/7e3t/+zs7P/r6+v/6enp/+jo6P/m5ub/5eXl/+Pj4//g4OD/3t7e/9zc + 3P/Z2dn/19fX/9TU1P/R0dH/zc3N/8jIyP/CwsL/vLy8/7e3t/+xsbH/qqqq/6Ojo/+enp7/nJyc/5ub + m/+cnJz/np6e/6CgoP+jo6P/pqam/6qqqv+urq7/srKy/7a2tv+6urr/vr6+/8HBwf/FxcX/ycnJ/83N + zf/R0dH/1dXV/9nZ2f/c3Nzx////Ae3t7Tfs7Oz/6+vr/+rq6v/p6en/6Ojo/+bm5v/k5OT/4uLi/+Dg + 4P/d3d3/29vb/9jY2P/V1dX/0tLS/87Ozv/Kysr/xMTE/7+/v/+5ubn/sbGx/6ioqP+fn5//ioqK/21t + bf+Ghob/iIiI/4iIiP+Li4v/jo6O/5GRkf+VlZX/mZmZ/56env+kpKT/qKio/62trf+xsbH/tbW1/7q6 + uv++vr7/w8PD/8jIyP/MzMz/0dHR/9XV1f/Z2dnx////Aezs7Dfr6+v/6urq/+jo6P/n5+f/5eXl/+Pj + 4//h4eH/39/f/9zc3P/Z2dn/19fX/9TU1P/Q0ND/zMzM/8fHx//CwsL/vLy8/7a2tv+urq7/pKSk/5iY + mP+MjIz/cHBw/2JiYv9zc3P/dnZ2/3d3d/96enr/fn5+/4ODg/+Hh4f/jIyM/5KSkv+YmJj/nZ2d/6Oj + o/+oqKj/ra2t/7Kysv+3t7f/vb29/8LCwv/Hx8f/zMzM/9HR0f/W1tbx////Aerq6jfp6en/6Ojo/+fn + 5//l5eX/4+Pj/+Hh4f/e3t7/3Nzc/9nZ2f/W1tb/09PT/8/Pz//Ly8v/xsbG/8DAwP+6urr/s7Oz/6ur + q/+hoaH/lJSU/4WFhf94eHj/ampq/2hoaP9oaGj/ZmZm/2hoaP9tbW3/cXFx/3V1df96enr/f39//4aG + hv+MjIz/kpKS/5iYmP+enp7/pKSk/6qqqv+wsLD/tra2/7y8vP/CwsL/x8fH/83Nzf/S0tLx////Aenp + 6Tfo6Oj/5ubm/+Xl5f/j4+P/4eHh/9/f3//c3Nz/2dnZ/9bW1v/S0tL/zs7O/8rKyv/FxcX/v7+//7i4 + uP+xsbH/qamp/5+fn/+RkZH/f39//2BgYP9nZ2f/aGho/29vb/9vb2//W1tb/11dXf9hYWH/ZWVl/2lp + af9ubm7/c3Nz/3p6ev+AgID/h4eH/42Njf+UlJT/m5ub/6Ghof+oqKj/r6+v/7W1tf+8vLz/wsLC/8nJ + yf/Ozs7x////Aejo6Dfn5+f/5eXl/+Pj4//h4eH/39/f/9zc3P/Z2dn/1tbW/9LS0v/Ozs7/ycnJ/8TE + xP+/v7//uLi4/7Gxsf+oqKj/nZ2d/5CQkP+AgID/ZmZm/0pKSv9XV1f/a2tr/3R0dP9xcXH/UlJS/1NT + U/84ODj/PT09/1tbW/9jY2P/aGho/25ubv91dXX/fHx8/4ODg/+Kior/kZGR/5mZmf+goKD/qKio/6+v + r/+3t7f/vr6+/8XFxf/Ly8vx////Aefn5zfm5ub/4+Pj/+Hh4f/f39//3Nzc/9ra2v/W1tb/09PT/87O + zv/Jycn/xMTE/76+vv+4uLj/sLCw/6ioqP+enp7/kJCQ/4GBgf9vb2//Xl5e/01NTf9VVVX/cXFx/42N + jf9xcXH/S0tL/zExMf8gICD/Hh4e/ygoKP9JSUn/XV1d/2NjY/9paWn/cXFx/3h4eP+AgID/iIiI/5CQ + kP+YmJj/oKCg/6mpqf+ysrL/urq6/8LCwv/Jycnx////AeXl5Tfk5OT/4uLi/9/f3//d3d3/2tra/9fX + 1//T09P/z8/P/8rKyv/FxcX/v7+//7i4uP+xsbH/qKio/5+fn/+RkZH/gYGB/2ZmZv9eXl7/WVlZ/2Nj + Y/9aWlr/i4uL/2tra/93d3f/VFRU/x0dHf8kJCT/Hh4e/x4eHv8eHh7/MjIy/1JSUv9eXl7/ZmZm/25u + bv91dXX/fn5+/4eHh/+QkJD/mZmZ/6Ojo/+tra3/tra2/7+/v//Gxsbx////AePj4zfi4uL/4ODg/93d + 3f/b29v/2NjY/9TU1P/Pz8//ysrK/8XFxf+/v7//uLi4/7Gxsf+pqan/n5+f/5OTk/+CgoL/ampq/0ZG + Rv9ISEj/YWFh/2VlZf9dXV3/cHBw/3Jycv/CwsL/jIyM/yQkJP8fHx//Hx8f/x4eHv8eHh7/HR0d/yEh + If8+Pj7/Wlpa/2NjY/9ra2v/dHR0/319ff+Hh4f/kZGR/5ycnP+np6f/s7Oz/7y8vP/FxcXx////AeLi + 4jfg4OD/3t7e/9vb2//Y2Nj/1dXV/9HR0f/Ly8v/xsbG/8DAwP+5ubn/srKy/6mpqf+fn5//kpKS/4SE + hP9zc3P/YWFh/0RERP9FRUX/ampq/3x8fP9WVlb/Xl5e/7e3t/+zs7P/KCgo/yIiIv8kJCT/JiYm/yIi + Iv8fHx//Hh4e/x4eHv8eHh7/KSkp/0xMTP9hYWH/ampq/3Nzc/99fX3/iIiI/5SUlP+ioqL/r6+v/7u7 + u//ExMTx////AeDg4Dff39//3Nzc/9nZ2f/V1dX/0dHR/8zMzP/Hx8f/wcHB/7q6uv+ysrL/qqqq/6Gh + of+Tk5P/hISE/3BwcP9lZWX/W1tb/15eXv9GRkb/fHx8/39/f/9hYWH/RERE/4iIiP8uLi7/IiIi/yMj + I/8lJSX/JiYm/yUlJf8kJCT/ISEh/x8fH/8eHh7/Hh4e/x8fH/83Nzf/Wlpa/2dnZ/9xcXH/fX19/42N + jf+cnJz/q6ur/7m5uf/ExMTx////Ad/f3zfd3d3/2tra/9bW1v/R0dH/zc3N/8fHx//BwcH/u7u7/7Oz + s/+rq6v/oaGh/5aWlv+Hh4f/c3Nz/0pKSv9LS0v/XFxc/2ZmZv9GRkb/hISE/2JiYv+dnZ3/mpqa/xwc + HP8cHBz/IyMj/yYmJv8mJib/JSUl/yYmJv8mJib/JSUl/yMjI/8fHx//Hx8f/x4eHv8eHh7/JSUl/0VF + Rf9jY2P/dHR0/4aGhv+YmJj/qamp/7i4uP/ExMTx////Ad3d3Tfb29v/19fX/9LS0v/Ozs7/yMjI/8LC + wv+8vLz/tLS0/6ysrP+jo6P/l5eX/4mJif94eHj/ZmZm/0hISP9DQ0P/ZWVl/3Jycv89PT3/V1dX/5aW + lv/a2tr/Pj4+/yIiIv8kJCT/JiYm/yYmJv8lJSX/JSUl/yYmJv8lJSX/JiYm/yUlJf8kJCT/ISEh/x8f + H/8fHx//Hx8f/x8fH/8xMTH/YWFh/3BwcP+Li4v/paWl/7e3t//ExMTx////Advb2zfY2Nj/1NTU/8/P + z//Jycn/xMTE/729vf+1tbX/ra2t/6SkpP+ZmZn/jIyM/3t7e/9ra2v/X19f/1ZWVv9CQkL/cHBw/42N + jf9OTk7/ODg4/7S0tP9JSUn/IyMj/yIiIv8mJib/JiYm/yYmJv8lJSX/JiYm/yYmJv8mJib/JiYm/yYm + Jv8lJSX/JSUl/yMjI/8gICD/Hx8f/yAgIP8gICD/IiIi/zk5Of91dXX/paWl/7e3t//FxcXx////AdjY + 2DfV1dX/0NDQ/8vLy//FxcX/v7+//7e3t/+vr6//paWl/5ubm/+NjY3/fX19/1RUVP9OTk7/W1tb/2Rk + ZP8/Pz//i4uL/1xcXP+FhYX/h4eH/xsbG/8eHh7/ISEh/yUlJf8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8lJSX/IiIi/yAgIP8gICD/ICAg/yAgIP9jY2P/pqam/7q6 + uv/Gxsbx////AdXV1TfT09P/zc3N/8fHx//AwMD/ubm5/7CwsP+np6f/nJyc/4+Pj/+AgID/b29v/01N + Tf9AQED/YWFh/2xsbP83Nzf/VlZW/319ff/Y2Nj/aWlp/yEhIf8fHx//JCQk/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yYmJv8lJSX/JiYm/yUlJf8lJSX/JiYm/yUlJf8lJSX/JSUl/yUlJf8gICD/ICAg/yAg + IP9YWFj/paWl/7+/v//IyMjx////AdPT0zfQ0ND/ysrK/8PDw/+7u7v/srKy/6mpqf+enp7/kZGR/4SE + hP90dHT/ZWVl/1RUVP8/Pz//aWlp/4qKiv9LS0v/NjY2/7u7u/+BgYH/JCQk/yEhIf8kJCT/JSUl/yQk + JP8lJSX/JSUl/yUlJf8lJSX/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8lJSX/JCQk/yAgIP9TU1P/paWl/8PDw//Ly8vx////AdDQ0DfNzc3/xsbG/76+vv+2trb/rKys/6Gh + of+UlJT/hoaG/2VlZf9VVVX/XV1d/2NjY/89PT3/hISE/2tra/9ubm7/YmJi/zY2Nv8jIyP/IiIi/yYm + Jv8lJSX/JCQk/yUlJf8lJSX/JCQk/yUlJf8lJSX/JSUl/yUlJf8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8lJSX/JiYm/yYmJv8lJSX/JiYm/yYmJv9sbGz/qKio/8fHx//Ozs7x////Ac3NzTfJycn/wsLC/7m5 + uf+vr6//pKSk/5eXl/+IiIj/dnZ2/1RUVP9BQUH/Xl5e/2pqav83Nzf/YWFh/2pqav+5ubn/pqam/yAg + IP8bGxv/IyMj/yQkJP8kJCT/JSUl/yUlJf8kJCT/JCQk/yQkJP8lJSX/JSUl/yUlJf8lJSX/JiYm/yUl + Jf8mJib/JiYm/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/xoaGv9iYmL/u7u7/8rKyv/Q0NDx////AcvL + yzfGxsb/vr6+/7Ozs/+np6f/mpqa/4uLi/96enr/bGxs/1hYWP8+Pj7/ZGRk/35+fv9UVFT/NjY2/6en + p/+4uLj/Jycn/yEhIf8iIiL/JCQk/yUlJf8lJSX/JSUl/yQkJP8kJCT/JCQk/yQkJP8lJSX/JSUl/yUl + Jf8lJSX/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8lJSX/HBwc/zU1Nf+vr6//xsbG/83N + zf/S0tLx////AcjIyDfDw8P/ubm5/62trf+goKD/kJCQ/3Z2dv9cXFz/Y2Nj/2NjY/9GRkb/cHBw/4GB + gf9dXV3/R0dH/0FBQf8wMDD/ICAg/yMjI/8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8jIyP/JCQk/yQk + JP8kJCT/JCQk/yUlJf8lJSX/JSUl/yUlJf8lJSX/JiYm/yYmJv8lJSX/JiYm/yUlJf81NTX/Pz8//6mp + qf/ExMT/ysrK/8/Pz//V1dXx////AcbGxjfAwMD/tbW1/6ampv+Xl5f/g4OD/2JiYv9FRUX/X19f/2pq + av9BQUH/bm5u/1xcXP+VlZX/zc3N/yIiIv8YGBj/IyMj/yQkJP8kJCT/KCgo/0VFRf9jY2P/a2tr/11d + Xf89PT3/JiYm/yMjI/8jIyP/JCQk/yQkJP8lJSX/JCQk/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yAg + IP9HR0f/q6ur/8HBwf/Hx8f/zc3N/9LS0v/X19fx////AcTExDe+vr7/sbGx/6Kiov+Pj4//enp6/2Nj + Y/9AQED/Y2Nj/3Z2dv9eXl7/MTEx/4qKiv/Z2dn/Ozs7/yEhIf8kJCT/JCQk/yQkJP9kZGT/srKy/8rK + yv/Ly8v/zMzM/8zMzP/Kysr/qKio/1NTU/8kJCT/JCQk/yQkJP8kJCT/JSUl/yQkJP8lJSX/JSUl/yUl + Jf8lJSX/IyMj/x0dHf+YmJj/wMDA/8bGxv/Ly8v/0NDQ/9XV1f/a2trx////AcTExDe9vb3/rq6u/5ub + m/92dnb/eXl5/2xsbP9VVVX/Y2Nj/5GRkf9XV1f/Nzc3/09PT/9OTk7/ICAg/yIiIv8kJCT/KSkp/4+P + j//MzMz/zMzM/8vLy//Ly8v/zMzM/8zMzP/MzMz/y8vL/8nJyf9/f3//JCQk/yMjI/8kJCT/JCQk/yQk + JP8kJCT/JSUl/yUlJf8rKyv/ISEh/5GRkf+/v7//xcXF/8rKyv/Pz8//09PT/9jY2P/c3Nzx////AcTE + xDe9vb3/rq6u/4qKiv9SUlL/cHBw/3Jycv9UVFT/b29v/1paWv9+fn7/y8vL/y4uLv8bGxv/Hx8f/yMj + I/8kJCT/d3d3/8rKyv/Ly8v/zMzM/8zMzP/MzMz/zMzM/8zMzP/Ly8v/ysrK/8rKyv/Jycn/Y2Nj/yMj + I/8jIyP/JCQk/yQkJP8kJCT/JCQk/yQkJP8/Pz//mpqa/729vf/Dw8P/ycnJ/83Nzf/S0tL/1tbW/9ra + 2v/e3t7x////AcTExDe/v7//sbGx/42Njf9MTEz/cHBw/3p6ev9qamr/OTk5/3V1df/Q0ND/bW1t/yAg + IP8fHx//IyMj/yQkJP8xMTH/wMDA/8zMzP/MzMz/zc3N/83Nzf/Nzc3/zc3N/8zMzP/Ly8v/y8vL/8rK + yv/Ly8v/srKy/ygoKP8kJCT/JCQk/yQkJP8kJCT/IiIi/xMTE/95eXn/u7u7/8PDw//IyMj/zc3N/9HR + 0f/W1tb/2dnZ/9zc3P/g4ODx////AcXFxTfAwMD/tbW1/5KSkv9qamr/ZWVl/5KSkv9lZWX/Ojo6/2ho + aP98fHz/ICAg/x8fH/8jIyP/JCQk/yQkJP9NTU3/zc3N/83Nzf/MzMz/zc3N/83Nzf/Nzc3/zc3N/83N + zf/MzMz/y8vL/8vLy//MzMz/y8vL/zg4OP8kJCT/JCQk/yQkJP8mJib/FRUV/29vb/+4uLj/wcHB/8fH + x//Nzc3/0dHR/9XV1f/Z2dn/3Nzc/9/f3//i4uLx////AcbGxjfBwcH/t7e3/4uLi/9vb2//aGho/29v + b/9paWn/srKy/zw8PP8jIyP/ICAg/yQkJP8jIyP/JCQk/yMjI/9MTEz/zMzM/8zMzP/MzMz/zMzM/83N + zf/Nzc3/zc3N/8zMzP/MzMz/zMzM/8zMzP/MzMz/y8vL/zs7O/8jIyP/JCQk/yQkJP85OTn/gICA/7m5 + uf/AwMD/xsbG/8zMzP/R0dH/1dXV/9jY2P/b29v/39/f/+Hh4f/k5OTx////AcfHxzfDw8P/r6+v/4WF + hf99fX3/Pj4+/2VlZf+xsbH/qamp/yAgIP8fHx//JCQk/yQkJP8jIyP/JCQk/yQkJP8xMTH/wMDA/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/MzMz/zMzM/8vLy//Ly8v/tra2/ykpKf8jIyP/IyMj/xIS + Ev9dXV3/tbW1/8DAwP/Gxsb/zMzM/9DQ0P/V1dX/2NjY/9zc3P/f39//4eHh/+Tk5P/m5ubx////AcnJ + yTfGxsb/rq6u/5CQkP+AgID/ODg4/3p6ev+tra3/JSUl/yAgIP8jIyP/IyMj/yMjI/8jIyP/IyMj/yQk + JP8kJCT/fn5+/83Nzf/MzMz/zc3N/83Nzf/MzMz/zc3N/83Nzf/MzMz/zMzM/8vLy//Kysr/bm5u/yQk + JP8kJCT/FhYW/01NTf+ysrL/wMDA/8bGxv/Ly8v/0NDQ/9TU1P/Y2Nj/29vb/9/f3//h4eH/4+Pj/+Xl + 5f/n5+fx////AczMzDfJycn/tLS0/4mJif9ZWVn/kZGR/05OTv8uLi7/Hx8f/yEhIf8iIiL/IiIi/yIi + Iv8iIiL/IyMj/yMjI/8jIyP/Kysr/5iYmP/MzMz/zMzM/83Nzf/MzMz/zMzM/8zMzP/MzMz/zMzM/8vL + y/+QkJD/Jycn/yMjI/81NTX/ZGRk/7S0tP/BwcH/xsbG/8vLy//Q0ND/1NTU/9jY2P/b29v/3t7e/+Hh + 4f/j4+P/5eXl/+fn5//p6enx////Ac/PzzfMzMz/vb29/11dXf+Ojo7/zs7O/zExMf8cHBz/ISEh/yIi + Iv8iIiL/NSIf/yIiIv8jIyP/IyMj/yMjI/8jIyP/IyMj/ygoKP9xcXH/vb29/8zMzP/Nzc3/zc3N/83N + zf/MzMz/ubm5/2pqav8nJyf/IyMj/xkZGf88PDz/ra2t/8HBwf/Gxsb/y8vL/9DQ0P/U1NT/2NjY/9vb + 2//e3t7/4ODg/+Pj4//l5eX/5+fn/+np6f/q6urx////AdLS0jfPz8//ysrK/62trf/Nzc3/OTk5/x8f + H/8hISH/IyMj/yIiIv9ZJBv/dCcZ/yIiIf8iIiL/IyMj/yMjI/8oIiH/IyIi/yMjI/8jIyP/Kysr/1NT + U/9vb2//fHx8/29vb/9OTk7/Kioq/yMjI/8jIyP/Gxsb/yoqKv+oqKj/wsLC/8fHx//MzMz/0NDQ/9TU + 1P/Y2Nj/29vb/97e3v/g4OD/4uLi/+Xl5f/n5+f/6enp/+rq6v/s7Ozx////AdXV1TfT09P/zs7O/7e3 + t/9CQkL/IiIi/yIiIv8kJCT/IiIi/00jHP+oKhP/SiMc/0MiHP9xJhj/WiQa/1wlG/9+KBj/LSMh/zEj + IP8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/JCQk/yMjI/8vLy//TExM/6mpqf/Dw8P/yMjI/83N + zf/R0dH/1dXV/9jY2P/b29v/3t7e/+Dg4P/j4+P/5eXl/+fn5//o6Oj/6urq/+zs7P/t7e3x////AdnZ + 2TfW1tb/0tLS/7y8vP8zMzP/IyMj/yMjI/8iIiL/NyIe/50pFP8tIR//bSYZ/4knFv85Ix//TyQc/y4i + If9gJhv/XiUb/3ImGP9BIx7/KCMh/yMjI/8jIyP/IyMj/yMjI/8kJCT/IyMj/x4eHv8lJSX/o6Oj/8XF + xf/Kysr/zs7O/9LS0v/W1tb/2dnZ/9zc3P/e3t7/4ODg/+Pj4//l5eX/5+fn/+jo6P/q6ur/6+vr/+3t + 7f/u7u7x////Adzc3DfZ2dn/1dXV/7Gxsf8lJSX/IyMj/yMjI/8iIiL/JCEh/1gkG/97Jhb/aCQX/34n + F/95Jhf/aiUZ/3wmF/88Ix7/UCQc/20mGf9oJhr/bSYZ/zIjIP8iIiL/IyMj/yMjI/8jIyP/ISEh/xkZ + Gf+YmJj/yMjI/8zMzP/Q0ND/1NTU/9fX1//a2tr/3d3d/9/f3//h4eH/4+Pj/+Xl5f/n5+f/6Ojo/+rq + 6v/r6+v/7e3t/+7u7v/v7+/x////Ad/f3zfd3d3/2dnZ/8fHx/9OTk7/JCQk/yMjI/8iIiL/IiIi/yEh + If8pISD/QSMd/0QjHf9pJRn/ISAg/3QlF/9DIx3/WCQb/ywiIP84Ix//aiYa/2UmGv9TJRz/IiIi/yIi + Iv8rKyv/Pj4+/5WVlf/Ly8v/z8/P/9LS0v/V1dX/2dnZ/9zc3P/e3t7/4ODg/+Li4v/k5OT/5eXl/+fn + 5//p6en/6urq/+vr6//t7e3/7u7u/+/v7//w8PDx////AeHh4Tfg4OD/3d3d/9ra2v/V1dX/k5OT/zc3 + N/8iIiL/IiIi/yIiIv8hISH/ISEh/yQhIP9oJRn/cSQX/2glGf+EJxb/PiMe/0kjHP9BIx7/YiUa/28m + Gf8kIyL/IyMj/yIiIv8cHBz/kJCQ/87Ozv/S0tL/1dXV/9jY2P/b29v/3d3d/+Dg4P/i4uL/5OTk/+Xl + 5f/n5+f/6Ojo/+np6f/r6+v/7Ozs/+3t7f/u7u7/7+/v//Dw8P/x8fHx////AeTk5Dfj4+P/4ODg/97e + 3v/b29v/2dnZ/8vLy/91dXX/Kioq/yIiIv8iIiL/IiIi/yEhIf8hISH/ISEg/1wkGv90Jhj/QyIc/4An + F/8mIiH/ZyYa/ygjIv8jIyP/JCQk/xQUFP99fX3/0dHR/9bW1v/Y2Nj/2tra/93d3f/f39//4uLi/+Tk + 5P/l5eX/5+fn/+jo6P/p6en/6urq/+vr6//s7Oz/7u7u/+/v7//w8PD/8PDw//Hx8f/y8vLx////Aefn + 5zfm5ub/4+Pj/+Hh4f/g4OD/3t7e/9zc3P/Z2dn/t7e3/1paWv9PT0//NTU1/yIiIv8hISH/ISEh/yEh + If9UJBz/iSgW/0QjHf9yJhj/VCYd/yMjIv8nJyf/Nzc3/3Z2dv/S0tL/2dnZ/9vb2//e3t7/4ODg/+Li + 4v/k5OT/5eXl/+fn5//o6Oj/6enp/+rq6v/r6+v/7Ozs/+3t7f/u7u7/7+/v//Dw8P/x8fH/8vLy//Ly + 8v/z8/Px////Aenp6Tfp6en/5+fn/+Xl5f/j4+P/4uLi/+Dg4P/e3t7/3d3d/9vb2//a2tr/ysrK/0BA + QP8iIiL/IiIi/yIiIv8iIiL/KCIh/2snGv9RJR7/IyMi/yIiIv8bGxv/eXl5/9bW1v/d3d3/39/f/+Dg + 4P/i4uL/5OTk/+bm5v/n5+f/6Ojo/+np6f/q6ur/6+vr/+zs7P/t7e3/7u7u/+/v7//w8PD/8PDw//Hx + 8f/y8vL/8/Pz//Pz8//09PTx////Aezs7Dfr6+v/6urq/+jo6P/n5+f/5eXl/+Tk5P/j4+P/4eHh/+Dg + 4P/f39//3t7e/5SUlP8rKyv/IiIi/yIiIv8iIiL/IiIi/yMjI/8iIiL/IyMj/xYWFv9SUlL/1dXV/+Hh + 4f/i4uL/4+Pj/+Xl5f/m5ub/5+fn/+np6f/q6ur/6+vr/+zs7P/t7e3/7e3t/+7u7v/v7+//7+/v//Dw + 8P/x8fH/8vLy//Ly8v/z8/P/8/Pz//T09P/19fXx////Ae3t7Tft7e3/7Ozs/+vr6//q6ur/6enp/+fn + 5//m5ub/5eXl/+Tk5P/j4+P/4uLi/+Hh4f/IyMj/YmJi/yQkJP8jIyP/IyMj/yMjI/8kJCT/WFhY/11d + Xf/U1NT/5OTk/+Xl5f/m5ub/5+fn/+jo6P/p6en/6urq/+vr6//s7Oz/7e3t/+7u7v/u7u7/7+/v//Dw + 8P/w8PD/8fHx//Hx8f/y8vL/8/Pz//Pz8//09PT/9PT0//X19f/19fXx////Ae/v7zfu7u7/7u7u/+3t + 7f/s7Oz/6+vr/+rq6v/p6en/6Ojo/+fn5//m5ub/5eXl/+Xl5f/k5OT/4+Pj/7CwsP9HR0f/IyMj/yMj + I/+Dg4P/5OTk/+Xl5f/m5ub/5+fn/+jo6P/p6en/6urq/+vr6//s7Oz/7Ozs/+3t7f/u7u7/7+/v/+/v + 7//w8PD/8fHx//Hx8f/y8vL/8vLy//Ly8v/z8/P/8/Pz//T09P/09PT/9fX1//X19f/29vbx////AfHx + 8Tfw8PD/7+/v/+/v7//u7u7/7e3t/+zs7P/s7Oz/6+vr/+rq6v/p6en/6Ojo/+jo6P/n5+f/6Ojo/+jo + 6P/f39//kZGR/4GBgf/m5ub/6enp/+np6f/p6en/6urq/+vr6//s7Oz/7Ozs/+3t7f/u7u7/7u7u/+/v + 7//v7+//8PDw//Hx8f/x8fH/8vLy//Ly8v/z8/P/8/Pz//Pz8//09PT/9PT0//X19f/19fX/9vb2//b2 + 9v/29vbx////AfLy8jfy8vL/8fHx//Dw8P/w8PD/7+/v/+7u7v/u7u7/7e3t/+zs7P/s7Oz/6+vr/+vr + 6//q6ur/6urq/+rq6v/r6+v/6+vr/+vr6//r6+v/6+vr/+zs7P/s7Oz/7e3t/+3t7f/u7u7/7u7u/+/v + 7//v7+//8PDw//Dw8P/x8fH/8fHx//Ly8v/y8vL/8/Pz//Pz8//09PT/9PT0//T09P/19fX/9fX1//X1 + 9f/29vb/9vb2//f39//39/fx////AfPz8zfz8/P/8vLy//Ly8v/x8fH/8fHx//Dw8P/w8PD/7+/v/+/v + 7//u7u7/7u7u/+3t7f/t7e3/7e3t/+3t7f/t7e3/7e3t/+3t7f/t7e3/7u7u/+7u7v/u7u7/7+/v/+/v + 7//w8PD/8PDw//Dw8P/x8fH/8fHx//Ly8v/y8vL/8/Pz//Pz8//z8/P/9PT0//T09P/19fX/9fX1//X1 + 9f/29vb/9vb2//b29v/29vb/9/f3//f39//39/fx////AQAAAAAAAP//AAAAAAAA//8AAAAAAAD//wAA + AAAAAP//AAAAAAAA//8AAAAAAAD//wAAAAAAAP//AAAAAAAA//8AAAAAAAD//wAAAAAAAP//AAAAAAAA + //8AAAAAAAD//wAAAAAAAP//AAAAAAAA//8AAAAAAAD//wAAAAAAAP//AAAAAAAA//8AAAAAAAD//wAA + AAAAAP//AAAAAAAA//8AAAAAAAD//wAAAAAAAP//AAAAAAAA//8AAAAAAAD//wAAAAAAAP//AAAAAAAA + //8AAAAAAAD//wAAAAAAAP//AAAAAAAA//8AAAAAAAD//wAAAAAAAP//AAAAAAAA//8AAAAAAAD//wAA + AAAAAP//AAAAAAAA//8AAAAAAAD//wAAAAAAAP//AAAAAAAA//8AAAAAAAD//wAAAAAAAP//AAAAAAAA + //8AAAAAAAD//wAAAAAAAP//AAAAAAAA//8AAAAAAAD//wAAAAAAAP//AAAAAAAA//8AAAAAAAD//ygA + AABAAAAAgAAAAAEAIAAAAAAAAEIAAAAAAAAAAAAAAAAAAAAAAAD///8B7+/v8e/v7//u7u7/7u7u/+3t + 7f/s7Oz/6+vr/+rq6v/p6en/6Ojo/+fn5//m5ub/5OTk/+Pj4//h4eH/4ODg/97e3v/d3d3/29vb/9ra + 2v/Y2Nj/19fX/9XV1f/R0dH/zs7O/8vLy//Hx8f/xMTE/8HBwf++vr7/u7u7/7i4uP+1tbX/srKy/7Cw + sP+vr6//rq6u/62trf+urq7/r6+v/7CwsP+xsbH/s7Oz/7W1tf+3t7f/urq6/7y8vP+/v7//wcHB/8TE + xP/Gxsb/yMjI/8vLy//Nzc3/0NDQ/9LS0v/V1dX/19fX/9nZ2f/c3Nz/3t7e/+Dg4Jf///8B////Ae/v + 7/Hu7u7/7e3t/+3t7f/s7Oz/6+vr/+rq6v/p6en/6Ojo/+fn5//l5eX/5OTk/+Li4v/h4eH/39/f/93d + 3f/c3Nz/2tra/9jY2P/W1tb/1dXV/9LS0v/Q0ND/zMzM/8jIyP/ExMT/wMDA/7y8vP+4uLj/tLS0/7Cw + sP+srKz/qKio/6Wlpf+kpKT/o6Oj/6Kiov+ioqL/o6Oj/6Wlpf+np6f/qKio/6qqqv+tra3/sLCw/7Oz + s/+2trb/uLi4/7u7u/++vr7/wcHB/8PDw//Gxsb/ycnJ/8vLy//Ozs7/0dHR/9TU1P/W1tb/2dnZ/9zc + 3P/e3t6X////Af///wHu7u7x7e3t/+zs7P/s7Oz/6+vr/+rq6v/p6en/5+fn/+bm5v/l5eX/5OTk/+Li + 4v/g4OD/3t7e/93d3f/b29v/2dnZ/9fX1//U1NT/0tLS/9DQ0P/Nzc3/ycnJ/8bGxv/BwcH/vLy8/7e3 + t/+ysrL/rq6u/6ioqP+hoaH/k5OT/5iYmP+VlZX/lJSU/5SUlP+VlZX/lpaW/5iYmP+ampr/nJyc/5+f + n/+hoaH/paWl/6mpqf+srKz/r6+v/7Kysv+1tbX/uLi4/7u7u/++vr7/wcHB/8TExP/Hx8f/ysrK/87O + zv/R0dH/1NTU/9fX1//a2tr/3Nzcl////wH///8B7e3t8ezs7P/r6+v/6urq/+np6f/o6Oj/5+fn/+bm + 5v/k5OT/4+Pj/+Hh4f/f39//3t7e/9zc3P/a2tr/2NjY/9XV1f/T09P/0NDQ/87Ozv/Kysr/x8fH/8PD + w/+/v7//urq6/7W1tf+urq7/qKio/6Ghof+ZmZn/fX19/2RkZP94eHj/hoaG/4WFhf+Ghob/h4eH/4qK + iv+MjIz/jo6O/5GRkf+VlZX/mJiY/5ycnP+goKD/pKSk/6enp/+rq6v/rq6u/7Kysv+1tbX/uLi4/7u7 + u/+/v7//w8PD/8bGxv/Kysr/zs7O/9HR0f/U1NT/19fX/9ra2pf///8B////Aezs7PHr6+v/6urq/+np + 6f/o6Oj/5+fn/+Xl5f/k5OT/4uLi/+Hh4f/f39//3d3d/9vb2//Z2dn/19fX/9XV1f/S0tL/z8/P/8zM + zP/IyMj/xcXF/8HBwf+8vLz/uLi4/7Ozs/+tra3/pKSk/5ycnP+Tk5P/ioqK/2pqav9jY2P/ampq/3l5 + ef94eHj/eHh4/3p6ev99fX3/gYGB/4SEhP+Hh4f/i4uL/4+Pj/+Tk5P/l5eX/5ubm/+fn5//o6Oj/6en + p/+rq6v/r6+v/7Kysv+2trb/urq6/76+vv/CwsL/xsbG/8rKyv/Nzc3/0dHR/9XV1f/X19eX////Af// + /wHq6urx6enp/+jo6P/n5+f/5ubm/+Xl5f/k5OT/4uLi/+Dg4P/e3t7/3Nzc/9ra2v/Y2Nj/1tbW/9TU + 1P/R0dH/zs7O/8vLy//Hx8f/w8PD/7+/v/+6urr/tbW1/7CwsP+qqqr/oqKi/5iYmP+Ojo7/g4OD/3p6 + ev9oaGj/ZWVl/2dnZ/9tbW3/bGxs/21tbf9wcHD/c3Nz/3Z2dv96enr/fX19/4GBgf+FhYX/ioqK/46O + jv+Tk5P/l5eX/5ubm/+goKD/pKSk/6ioqP+srKz/sLCw/7W1tf+5ubn/vr6+/8LCwv/Gxsb/ysrK/87O + zv/S0tL/1dXVl////wH///8B6enp8ejo6P/n5+f/5ubm/+Xl5f/k5OT/4uLi/+Dg4P/e3t7/3Nzc/9ra + 2v/Y2Nj/1tbW/9PT0//R0dH/zs7O/8rKyv/Hx8f/w8PD/76+vv+5ubn/s7Oz/66urv+oqKj/oKCg/5aW + lv+MjIz/gICA/3Z2dv9ubm7/Z2dn/2tra/9tbW3/Y2Nj/2JiYv9jY2P/Z2dn/2pqav9tbW3/cHBw/3Nz + c/93d3f/fHx8/4CAgP+FhYX/ioqK/46Ojv+Tk5P/mJiY/52dnf+hoaH/pqam/6urq/+vr6//tLS0/7m5 + uf+9vb3/wsLC/8bGxv/Ly8v/z8/P/9LS0pf///8B////Aejo6PHn5+f/5ubm/+Xl5f/j4+P/4uLi/+Dg + 4P/f39//3d3d/9ra2v/Y2Nj/1tbW/9PT0//Q0ND/zc3N/8rKyv/Hx8f/w8PD/76+vv+4uLj/s7Oz/62t + rf+mpqb/n5+f/5SUlP+Kior/eHh4/1dXV/9fX1//Z2dn/2lpaf9vb2//dHR0/2VlZf9aWlr/W1tb/15e + Xv9hYWH/ZGRk/2dnZ/9qamr/bm5u/3Nzc/93d3f/fHx8/4GBgf+Ghob/i4uL/5CQkP+VlZX/mpqa/5+f + n/+kpKT/qqqq/6+vr/+0tLT/ubm5/76+vv/Dw8P/yMjI/8zMzP/Pz8+X////Af///wHo6Ojx5ubm/+Xl + 5f/k5OT/4uLi/+Dg4P/f39//3d3d/9vb2//Y2Nj/1tbW/9PT0//Q0ND/zc3N/8nJyf/Gxsb/wsLC/729 + vf+4uLj/s7Oz/62trf+mpqb/nZ2d/5SUlP+IiIj/fHx8/2JiYv9MTEz/TExM/2JiYv9sbGz/cXFx/3Z2 + dv9jY2P/UlJS/1RUVP9PT0//NDQ0/0xMTP9eXl7/YmJi/2ZmZv9qamr/b29v/3Nzc/95eXn/fn5+/4OD + g/+JiYn/jo6O/5SUlP+ZmZn/np6e/6SkpP+qqqr/r6+v/7W1tf+6urr/v7+//8XFxf/Jycn/zc3Nl/// + /wH///8B5+fn8eXl5f/k5OT/4uLi/+Hh4f/f39//3d3d/9vb2//Z2dn/1tbW/9PT0//Q0ND/zc3N/8nJ + yf/FxcX/wcHB/729vf+4uLj/s7Oz/62trf+mpqb/np6e/5SUlP+IiIj/fHx8/3BwcP9dXV3/TExM/0dH + R/9kZGT/b29v/319ff+CgoL/YWFh/0xMTP9JSUn/JCQk/xwcHP8gICD/NjY2/1RUVP9eXl7/YmJi/2Zm + Zv9ra2v/cHBw/3Z2dv97e3v/gYGB/4eHh/+MjIz/kpKS/5iYmP+enp7/pKSk/6urq/+xsbH/t7e3/7y8 + vP/CwsL/x8fH/8vLy5f///8B////Aebm5vHk5OT/4uLi/+Hh4f/f39//3d3d/9vb2//Z2dn/19fX/9TU + 1P/R0dH/zc3N/8rKyv/Gxsb/wcHB/729vf+4uLj/s7Oz/6ysrP+mpqb/np6e/5WVlf+JiYn/fn5+/3Bw + cP9iYmL/W1tb/1dXV/9NTU3/ZWVl/3l5ef+Xl5f/ampq/2xsbP9GRkb/JSUl/xsbG/8vLy//Hh4e/x4e + Hv8kJCT/QkJC/1hYWP9eXl7/Y2Nj/2hoaP9ubm7/c3Nz/3l5ef9/f3//hYWF/4yMjP+SkpL/mJiY/5+f + n/+mpqb/ra2t/7Ozs/+6urr/v7+//8XFxf/JycmX////Af///wHk5OTx4+Pj/+Hh4f/f39//3t7e/9zc + 3P/Z2dn/19fX/9TU1P/R0dH/zs7O/8rKyv/Gxsb/wsLC/729vf+4uLj/s7Oz/62trf+mpqb/n5+f/5WV + lf+Kior/fX19/2FhYf9eXl7/VlZW/1paWv9mZmb/VlZW/21tbf+Wlpb/Z2dn/2xsbP+Ghob/RERE/xsb + G/8mJib/HBwc/x4eHv8eHh7/Hh4e/x4eHv8sLCz/TExM/1paWv9gYGD/ZmZm/2xsbP9xcXH/d3d3/35+ + fv+EhIT/i4uL/5KSkv+ampr/oaGh/6ioqP+wsLD/t7e3/729vf/Dw8P/yMjIl////wH///8B4+Pj8eHh + 4f/g4OD/3t7e/9zc3P/a2tr/2NjY/9XV1f/S0tL/zs7O/8rKyv/Hx8f/wsLC/729vf+4uLj/s7Oz/66u + rv+np6f/n5+f/5eXl/+Kior/fn5+/2dnZ/9ISEj/QUFB/1FRUf9jY2P/ampq/01NTf+EhIT/bm5u/2Vl + Zf+IiIj/5eXl/39/f/8jIyP/Hx8f/x8fH/8eHh7/Hh4e/x4eHv8eHh7/HR0d/x8fH/83Nzf/VFRU/15e + Xv9kZGT/aWlp/3BwcP92dnb/fX19/4SEhP+MjIz/k5OT/5ycnP+kpKT/rKys/7S0tP+8vLz/wsLC/8fH + x5f///8B////AeLi4vHg4OD/3t7e/9zc3P/a2tr/2NjY/9bW1v/T09P/z8/P/8vLy//Hx8f/w8PD/76+ + vv+5ubn/s7Oz/62trf+np6f/n5+f/5aWlv+MjIz/f39//3Jycv9fX1//SUlJ/zo6Ov9XV1f/aWlp/3Bw + cP9PT0//V1dX/11dXf+IiIj/39/f/7S0tP8nJyf/Jycn/yEhIf8lJSX/JCQk/x8fH/8fHx//Hh4e/x4e + Hv8eHh7/Hh4e/yUlJf9ERET/W1tb/2JiYv9oaGj/b29v/3Z2dv99fX3/hYWF/42Njf+Wlpb/n5+f/6mp + qf+ysrL/urq6/8HBwf/GxsaX////Af///wHh4eHx39/f/93d3f/b29v/2NjY/9bW1v/T09P/0NDQ/8zM + zP/IyMj/w8PD/76+vv+5ubn/tLS0/66urv+np6f/oKCg/5aWlv+Li4v/gICA/3R0dP9nZ2f/XV1d/01N + Tf86Ojr/WVlZ/25ubv+Li4v/c3Nz/05OTv9dXV3/0dHR/8bGxv8uLi7/JiYm/yAgIP8kJCT/JSUl/yYm + Jv8lJSX/IiIi/x8fH/8eHh7/Hh4e/x4eHv8eHh7/Hh4e/zAwMP9RUVH/YWFh/2dnZ/9ubm7/dXV1/319 + ff+Ghob/kJCQ/5qamv+lpaX/r6+v/7m5uf/BwcH/xsbGl////wH///8B4ODg8d7e3v/b29v/2dnZ/9bW + 1v/T09P/0NDQ/8zMzP/IyMj/xMTE/7+/v/+6urr/tLS0/66urv+oqKj/oaGh/5iYmP+MjIz/gYGB/25u + bv9mZmb/Xl5e/1paWv9iYmL/SkpK/1lZWf+Ghob/hYWF/1hYWP9paWn/Ozs7/2xsbP81NTX/JiYm/yAg + IP8kJCT/JSUl/yYmJv8mJib/JiYm/yUlJf8kJCT/ISEh/x8fH/8eHh7/Hh4e/x4eHv8eHh7/IiIi/z4+ + Pv9bW1v/ZGRk/2tra/90dHT/fn5+/4qKiv+Wlpb/oaGh/62trf+3t7f/wcHB/8bGxpf///8B////Ad7e + 3vHc3Nz/2tra/9fX1//U1NT/0NDQ/8zMzP/IyMj/xMTE/8DAwP+7u7v/tbW1/6+vr/+oqKj/oaGh/5mZ + mf+Ojo7/goKC/3Jycv9OTk7/RUVF/1RUVP9dXV3/ZmZm/0ZGRv9qamr/ioqK/1RUVP99fX3/tLS0/4CA + gP8bGxv/HR0d/x4eHv8jIyP/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yUlJf8jIyP/Hx8f/x8f + H/8fHx//Hh4e/x4eHv8eHh7/KSkp/0pKSv9fX1//ampq/3d3d/+EhIT/kpKS/5+fn/+rq6v/tra2/8DA + wP/Hx8eX////Af///wHd3d3x2tra/9fX1//U1NT/0dHR/83Nzf/Jycn/xcXF/8DAwP+7u7v/tra2/7Cw + sP+qqqr/oqKi/5qamv+QkJD/hISE/3d3d/9nZ2f/TExM/zw8PP9SUlL/ZGRk/2pqav9BQUH/Wlpa/1RU + VP97e3v/ra2t/+rq6v9OTk7/IiIi/xsbG/8kJCT/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JSUl/yMjI/8hISH/Hx8f/x8fH/8fHx//Hx8f/x8fH/8gICD/NjY2/11dXf9ycnL/f39//4yM + jP+cnJz/qamp/7W1tf/AwMD/x8fHl////wH///8B29vb8djY2P/V1dX/0tLS/87Ozv/Kysr/xsbG/8HB + wf+8vLz/t7e3/7Gxsf+qqqr/pKSk/5ycnP+SkpL/h4eH/3p6ev9tbW3/YWFh/05OTv82Njb/VFRU/2lp + af94eHj/bGxs/zMzM/9fX1//pKSk/+/v7/9gYGD/JCQk/yAgIP8kJCT/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8lJSX/JCQk/yMjI/8fHx//Hx8f/x8fH/8fHx//Hx8f/x8f + H/8mJib/Tk5O/1xcXP9oaGj/k5OT/6enp/+0tLT/wMDA/8fHx5f///8B////AdnZ2fHW1tb/09PT/8/P + z//Ly8v/x8fH/8LCwv+9vb3/t7e3/7Kysv+rq6v/pKSk/52dnf+Tk5P/iIiI/3t7e/9vb2//ZWVl/1xc + XP9cXFz/SkpK/09PT/92dnb/l5eX/1lZWf9GRkb/MTEx/6enp/9tbW3/IiIi/yAgIP8iIiL/JSUl/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yUlJf8lJSX/JCQk/yIi + Iv8fHx//Hx8f/yAgIP8gICD/ICAg/yAgIP8pKSn/Wlpa/46Ojv+np6f/tbW1/8HBwf/Hx8eX////Af// + /wHX19fx1NTU/9DQ0P/MzMz/yMjI/8PDw/++vr7/ubm5/7Ozs/+srKz/paWl/52dnf+UlJT/iYmJ/319 + ff9cXFz/SkpK/1lZWf9aWlr/Y2Nj/0xMTP9TU1P/k5OT/2BgYP9sbGz/i4uL/2BgYP8YGBj/Hh4e/yEh + If8hISH/JSUl/yUlJf8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8lJSX/JCQk/yEhIf8gICD/ICAg/yAgIP8gICD/ICAg/zQ0NP+QkJD/qKio/7e3 + t//Dw8P/yMjIl////wH///8B1dXV8dLS0v/Ozs7/ycnJ/8XFxf/AwMD/urq6/7S0tP+urq7/p6en/5+f + n/+VlZX/i4uL/39/f/9xcXH/UVFR/zw8PP9OTk7/YWFh/2dnZ/9ISEj/UVFR/2lpaf9kZGT/ioqK/+fn + 5/+NjY3/Hh4e/xgYGP8fHx//JCQk/yUlJf8lJSX/JSUl/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yUlJf8lJSX/IyMj/yAgIP8gICD/ICAg/yEh + If8uLi7/jo6O/6urq/+7u7v/xcXF/8nJyZf///8B////AdPT0/HPz8//y8vL/8bGxv/BwcH/u7u7/7W1 + tf+vr6//qKio/6CgoP+Wlpb/jY2N/4GBgf91dXX/aWlp/1NTU/82Njb/TU1N/2dnZ/9vb2//Y2Nj/yoq + Kv9SUlL/hoaG/9/f3/+pqan/JSUl/yQkJP8gICD/JCQk/yUlJf8lJSX/JSUl/yUlJf8lJSX/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8kJCT/ISEh/yAgIP8gICD/Jycn/4ODg/+qqqr/wMDA/8fHx//Ly8uX////Af///wHR0dHxzc3N/8jI + yP/Dw8P/vb29/7e3t/+wsLD/qqqq/6Kiov+YmJj/jo6O/4SEhP93d3f/bW1t/2NjY/9aWlr/R0dH/0hI + SP9tbW3/jIyM/3R0dP8vLy//MjIy/6+vr//AwMD/Jycn/yYmJv8gICD/JCQk/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JSUl/yYmJv8kJCT/ICAg/yUlJf+EhIT/ra2t/8PDw//Jycn/zc3Nl/// + /wH///8Bz8/P8cvLy//Gxsb/wMDA/7q6uv+zs7P/rKys/6SkpP+bm5v/kZGR/4aGhv9xcXH/VVVV/19f + X/9dXV3/YmJi/1ZWVv8/Pz//h4eH/4GBgf9TU1P/cHBw/zc3N/8nJyf/R0dH/yQkJP8hISH/JiYm/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yUlJf81NTX/i4uL/6+v + r//Gxsb/y8vL/8/Pz5f///8B////Ac3NzfHIyMj/w8PD/7y8vP+1tbX/rq6u/6ampv+dnZ3/kpKS/4eH + h/96enr/WVlZ/0RERP9NTU3/Xl5e/2dnZ/9UVFT/QUFB/4uLi/9PT0//fHx8/7y8vP/Gxsb/Hh4e/xgY + GP8dHR3/JCQk/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yUl + Jf8lJSX/SUlJ/4+Pj/+4uLj/ycnJ/83Nzf/R0dGX////Af///wHLy8vxxcXF/7+/v/+4uLj/sLCw/6io + qP+fn5//lZWV/4mJif98fHz/b29v/1paWv8/Pz//SEhI/2VlZf9ra2v/YmJi/yQkJP9JSUn/enp6/7Gx + sf/k5OT/QEBA/yMjI/8dHR3/ISEh/yQkJP8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yUlJf8kJCT/ERER/y8vL/+rq6v/xcXF/8rKyv/Pz8//0tLSl////wH///8BycnJ8cPD + w/+8vLz/tLS0/6urq/+ioqL/l5eX/4yMjP9/f3//c3Nz/2lpaf9eXl7/RERE/0VFRf9paWn/fHx8/4uL + i/8nJyf/Ojo6/5ycnP/o6Oj/UlJS/yIiIv8gICD/IiIi/yQkJP8lJSX/JSUl/yUlJf8lJSX/JSUl/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8kJCT/FhYW/ywsLP+fn5//wsLC/8jIyP/MzMz/0NDQ/9TU + 1Jf///8B////AcbGxvHAwMD/ubm5/7CwsP+mpqb/m5ub/4+Pj/+AgID/YmJi/2ZmZv9kZGT/YWFh/2Bg + YP84ODj/d3d3/5SUlP9WVlb/W1tb/ygoKP87Ozv/XV1d/yEhIf8fHx//IiIi/yQkJP8lJSX/JSUl/yUl + Jf8lJSX/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8nJyf/Kysr/ygoKP+ZmZn/wMDA/8bG + xv/Kysr/zs7O/9LS0v/W1taX////Af///wHFxcXxvr6+/7W1tf+rq6v/oKCg/5OTk/+Ghob/a2tr/0tL + S/9MTEz/YWFh/2ZmZv9hYWH/NjY2/5KSkv9dXV3/aWlp/5KSkv/FxcX/ISEh/yEhIf8bGxv/IiIi/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JiYm/ysrK/8rKyv/KCgo/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JiYm/yYmJv8mJib/JiYm/yYmJv8lJSX/NTU1/2tr + a/+jo6P/v7+//8TExP/IyMj/zMzM/9HR0f/V1dX/2NjYl////wH///8Bw8PD8bu7u/+xsbH/pqam/5qa + mv+MjIz/fHx8/2ZmZv9JSUn/RkZG/2RkZP9sbGz/Z2dn/ycnJ/9UVFT/YmJi/4uLi//p6en/hoaG/x8f + H/8bGxv/ICAg/yUlJf8kJCT/IyMj/ygoKP9OTk7/f39//6Ghof+ysrL/s7Oz/6ioqP+Pj4//YmJi/zMz + M/8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8mJib/JiYm/yUl + Jf8lJSX/HBwc/xkZGf+Li4v/vLy8/8LCwv/Gxsb/y8vL/8/Pz//T09P/19fX/9nZ2Zf///8B////AcLC + wvG5ubn/r6+v/6Ojo/+Wlpb/hoaG/3d3d/9nZ2f/SkpK/0VFRf9qamr/dHR0/5CQkP8uLi7/Nzc3/4CA + gP/j4+P/m5ub/x0dHf8hISH/IiIi/yYmJv8kJCT/IyMj/0hISP+lpaX/ycnJ/8vLy//Ly8v/y8vL/8zM + zP/MzMz/zc3N/83Nzf++vr7/cnJy/yoqKv8kJCT/JCQk/yQkJP8kJCT/JCQk/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yYmJv8lJSX/IiIi/xEREf9/f3//u7u7/8LCwv/Gxsb/ycnJ/83Nzf/R0dH/1dXV/9jY + 2P/b29uX////Af///wHBwcHxuLi4/62trf+hoaH/h4eH/35+fv94eHj/bGxs/2hoaP9BQUH/bGxs/5OT + k/92dnb/RkZG/yQkJP9LS0v/lZWV/yAgIP8iIiL/ICAg/yUlJf8kJCT/JCQk/2lpaf/Gxsb/zc3N/8zM + zP/Ly8v/y8vL/8vLy//MzMz/zMzM/8zMzP/MzMz/y8vL/8rKyv+np6f/Nzc3/yMjI/8kJCT/JCQk/yQk + JP8kJCT/JCQk/yUlJf8lJSX/JSUl/yUlJf8lJSX/IyMj/wwMDP93d3f/uLi4/8HBwf/FxcX/ycnJ/8zM + zP/Q0ND/1NTU/9fX1//a2tr/3Nzcl////wH///8BwcHB8be3t/+srKz/mJiY/2FhYf9VVVX/eXl5/3Bw + cP9ubm7/Ojo6/4WFhf9+fn7/UFBQ/35+fv+bm5v/Jycn/zAwMP8bGxv/HR0d/yMjI/8kJCT/IyMj/19f + X//Gxsb/y8vL/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/Ly8v/y8vL/8rKyv/Kysr/ycnJ/6Oj + o/8rKyv/IyMj/yQkJP8kJCT/JCQk/yQkJP8lJSX/JSUl/yUlJf8lJSX/MjIy/1lZWf+AgID/t7e3/8DA + wP/ExMT/yMjI/8vLy//Pz8//0tLS/9bW1v/Z2dn/29vb/97e3pf///8B////AcLCwvG5ubn/ra2t/5WV + lf9fX1//SkpK/3l5ef90dHT/c3Nz/zIyMv9qamr/TU1N/3x8fP/CwsL/ycnJ/ywsLP8aGhr/Gxsb/yIi + Iv8jIyP/JCQk/zU1Nf+2trb/y8vL/8vLy//MzMz/zMzM/83Nzf/Nzc3/zc3N/8zMzP/MzMz/y8vL/8vL + y//Kysr/ysrK/8rKyv/Kysr/c3Nz/yQkJP8kJCT/JCQk/yQkJP8kJCT/JSUl/yUlJf8kJCT/ISEh/xUV + Ff9zc3P/s7Oz/7+/v//Dw8P/x8fH/8vLy//Ozs7/0tLS/9XV1f/Y2Nj/2tra/93d3f/f39+X////Af// + /wHDw8Pxu7u7/6+vr/+Wlpb/X19f/0dHR/96enr/enp6/4mJif9DQ0P/Pj4+/3Z2dv+0tLT/2dnZ/zk5 + Of8hISH/Hh4e/yIiIv8jIyP/JCQk/yQkJP9paWn/zMzM/83Nzf/MzMz/zMzM/83Nzf/Nzc3/zs7O/83N + zf/Nzc3/zMzM/8zMzP/Ly8v/y8vL/8vLy//Ly8v/zMzM/7Ozs/8rKyv/JCQk/yQkJP8kJCT/JCQk/yUl + Jf8kJCT/ISEh/w0NDf9RUVH/r6+v/76+vv/CwsL/x8fH/8rKyv/Ozs7/0dHR/9TU1P/X19f/2tra/9zc + 3P/f39//4eHhl////wH///8Bw8PD8b29vf+zs7P/mZmZ/3V1df9VVVX/c3Nz/4qKiv+Tk5P/RERE/zAw + MP9qamr/09PT/0NDQ/8hISH/Hh4e/yIiIv8jIyP/JCQk/yQkJP8kJCT/kJCQ/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/87Ozv/Ozs7/zs7O/83Nzf/MzMz/zMzM/8vLy//Ly8v/zMzM/83Nzf/Jycn/PDw8/yQk + JP8kJCT/JCQk/yQkJP8kJCT/IyMj/w4ODv9KSkr/qamp/729vf/BwcH/xsbG/8rKyv/Ozs7/0dHR/9TU + 1P/X19f/2tra/9zc3P/e3t7/4eHh/+Li4pf///8B////AcPDw/G9vb3/tra2/5aWlv9/f3//UFBQ/3R0 + dP+Xl5f/UlJS/29vb/92dnb/ISEh/y8vL/8fHx//Hx8f/yIiIv8jIyP/JCQk/yQkJP8kJCT/JCQk/5iY + mP/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zMzM/8zMzP/MzMz/zMzM/8zM + zP/MzMz/zMzM/0dHR/8kJCT/JCQk/yQkJP8kJCT/KSkp/0RERP9WVlb/q6ur/7y8vP/AwMD/xcXF/8rK + yv/Nzc3/0dHR/9TU1P/X19f/2dnZ/9zc3P/e3t7/4ODg/+Li4v/k5OSX////Af///wHFxcXxvr6+/7Oz + s/+Hh4f/goKC/0xMTP9wcHD/V1dX/2pqav+Tk5P/7u7u/1NTU/8eHh7/GRkZ/yQkJP8lJSX/JCQk/yQk + JP8kJCT/JCQk/yQkJP+Ghob/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/8zM + zP/MzMz/zMzM/8zMzP/MzMz/zMzM/8bGxv87Ozv/JCQk/yQkJP8kJCT/IyMj/xoaGv9ZWVn/pKSk/7y8 + vP/AwMD/xMTE/8nJyf/Nzc3/0NDQ/9TU1P/X19f/2dnZ/9zc3P/e3t7/4ODg/+Li4v/k5OT/5eXll/// + /wH///8BxsbG8cDAwP+oqKj/hYWF/4qKiv9fX1//Pj4+/2hoaP+Ojo7/6enp/3V1df8dHR3/ICAg/yMj + I/8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/VlZW/8vLy//Nzc3/zc3N/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/MzMz/zMzM/8zMzP/Ly8v/y8vL/8vLy/+pqan/KCgo/yQkJP8kJCT/IiIi/xIS + Ev8vLy//oqKi/7u7u//AwMD/xMTE/8nJyf/Nzc3/0NDQ/9TU1P/X19f/2dnZ/9zc3P/e3t7/4ODg/+Li + 4v/k5OT/5eXl/+bm5pf///8B////AcjIyPHDw8P/qKio/4qKiv+cnJz/X19f/zMzM/+CgoL/1tbW/4eH + h/8eHh7/ICAg/yEhIf8jIyP/IyMj/yMjI/8jIyP/IyMj/yQkJP8kJCT/JCQk/ysrK/+np6f/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/8zMzP/MzMz/y8vL/8vLy//Jycn/YWFh/yQk + JP8kJCT/IyMj/xUVFf8mJib/lZWV/7u7u//AwMD/xMTE/8nJyf/MzMz/0NDQ/9PT0//W1tb/2dnZ/9vb + 2//e3t7/4ODg/+Li4v/j4+P/5eXl/+fn5//o6OiX////Af///wHKysrxxcXF/6qqqv+bm5v/cnJy/1ZW + Vv9iYmL/MzMz/0NDQ/8qKir/ISEh/yAgIP8iIiL/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/JCQk/yQk + JP8kJCT/R0dH/729vf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zMzM/8vL + y//Kysr/kZGR/ycnJ/8kJCT/JSUl/zY2Nv8zMzP/lpaW/7u7u//AwMD/xMTE/8jIyP/MzMz/0NDQ/9PT + 0//W1tb/2dnZ/9vb2//d3d3/4ODg/+Li4v/j4+P/5eXl/+bm5v/o6Oj/6enpl////wH///8By8vL8cfH + x/+1tbX/e3t7/1BQUP9/f3//0dHR/4WFhf8mJib/GRkZ/x8fH/8iIiL/IyMj/yMjI/8jIyP/IyMj/yMj + I/8jIyP/IyMj/yMjI/8jIyP/JCQk/yQkJP9LS0v/tbW1/8zMzP/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/8zMzP/IyMj/j4+P/y4uLv8kJCT/IyMj/yIiIv9LS0v/lJSU/729vf/BwcH/xcXF/8jI + yP/MzMz/0NDQ/9PT0//W1tb/2dnZ/9vb2//d3d3/39/f/+Hh4f/j4+P/5eXl/+bm5v/o6Oj/6enp/+rq + 6pf///8B////Ac7OzvHKysr/urq6/1lZWf96enr/xcXF/7y8vP8kJCT/Hx8f/x0dHf8iIiL/IiIi/yIi + Iv8oIiH/PiId/yMiIv8iIiL/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/zMzM/+Dg4P/v7+//8vL + y//Nzc3/zc3N/83Nzf/Nzc3/zMzM/8rKyv+srKz/XV1d/yYmJv8kJCT/IyMj/xsbG/8UFBT/goKC/7u7 + u//CwsL/xcXF/8nJyf/Nzc3/0NDQ/9PT0//W1tb/2dnZ/9vb2//d3d3/39/f/+Hh4f/j4+P/5OTk/+bm + 5v/o6Oj/6enp/+rq6v/r6+uX////Af///wHQ0NDxzc3N/8nJyf+wsLD/t7e3/9LS0v8oKCj/ICAg/x0d + Hf8jIyP/IyMj/yIiIv8jISH/gicW/3UnGf8jIiH/IiIi/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMj + I/8jIyP/JCQk/zAwMP9dXV3/fX19/5OTk/+ZmZn/jo6O/29vb/9HR0f/Jycn/yQkJP8kJCT/IyMj/x0d + Hf8NDQ3/dXV1/7q6uv/CwsL/xsbG/8rKyv/Nzc3/0NDQ/9PT0//W1tb/2dnZ/9vb2//d3d3/39/f/+Hh + 4f/i4uL/5OTk/+bm5v/n5+f/6enp/+rq6v/r6+v/7Ozsl////wH///8B09PT8dDQ0P/MzMz/xcXF/3Z2 + dv88PDz/Hx8f/x8fH/8lJSX/IyMj/yIiIv8iISH/dyYX/44oFv8lIiH/IiIi/yQhIf88Ih7/KCIh/y0i + IP9gJRr/aCYa/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/IyMj/y0tLf8bGxv/cnJy/7i4uP/Dw8P/xsbG/8rKyv/Ozs7/0dHR/9TU1P/W1tb/2dnZ/9vb + 2//d3d3/39/f/+Hh4f/i4uL/5OTk/+bm5v/n5+f/6enp/+rq6v/r6+v/7Ozs/+3t7Zf///8B////AdXV + 1fHS0tL/z8/P/8jIyP9kZGT/NDQ0/yMjI/8kJCT/IyMj/yIiIv8iISH/aCQY/5cpFf+RKBX/fSYW/3kl + Fv+WKBT/jykW/3slFv9uJhn/UyUd/1omHf9GJB3/WSQa/ygiIf8jIyL/IyMj/yMjI/8jIyP/IyMj/yMj + I/8jIyP/JCQk/yQkJP8kJCT/IyMj/yIiIv9FRUX/gICA/729vf/ExMT/x8fH/8vLy//Ozs7/0dHR/9TU + 1P/X19f/2dnZ/9vb2//d3d3/39/f/+Hh4f/j4+P/5OTk/+bm5v/n5+f/6Ojo/+rq6v/r6+v/7Ozs/+3t + 7f/u7u6X////Af///wHY2Njx1dXV/9LS0v/Ly8v/UlJS/ycnJ/8iIiL/IyMj/yIiIv8iIiL/RiMd/7Yr + Ev8zIR7/JiAg/2QlGv+SKBX/LSIg/ykhIP9GIx3/KCIh/2ImG/9EJB7/aSYZ/2IkGf94Jhj/NiMf/yci + Iv8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8kJCT/IyMj/yAgIP8MDAz/Xl5e/7e3t//FxcX/ycnJ/8zM + zP/Pz8//0tLS/9XV1f/X19f/2tra/9zc3P/e3t7/39/f/+Hh4f/j4+P/5OTk/+bm5v/n5+f/6Ojo/+np + 6f/r6+v/7Ozs/+3t7f/u7u7/7+/vl////wH///8B2tra8dfX1//U1NT/ysrK/z4+Pv8iIiL/IyMj/yMj + I/8iIiL/IiIi/yUhIP9dJRv/kicU/1QiGf9QIhn/oyoU/0QiHP+TKBT/fScX/4YmFf9eJRr/LiIg/2ol + Gf+DJxf/bCYZ/2UmG/9yJhj/LCIh/yMiIv8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8NDQ3/TExM/7i4 + uP/IyMj/y8vL/83Nzf/Q0ND/09PT/9bW1v/Z2dn/29vb/93d3f/e3t7/4ODg/+Hh4f/j4+P/5OTk/+bm + 5v/n5+f/6Ojo/+rq6v/r6+v/7Ozs/+3t7f/u7u7/7+/v/+/v75f///8B////Ad3d3fHa2tr/19fX/83N + zf8/Pz//IyMj/yQkJP8jIyP/IyMj/yIiIv8hISH/ISEh/y4hH/9tJhn/gScX/0cjHf+aKRT/OiIe/yEh + If9LIxz/fScX/yUhIf8tIiD/KiIg/1clHP9HIx3/bSca/2smGv88Ix7/LCMh/yMjI/8jIyP/IyMj/ycn + J/8WFhb/RkZG/7S0tP/Kysr/zc3N/8/Pz//S0tL/1NTU/9fX1//a2tr/3Nzc/97e3v/f39//4eHh/+Li + 4v/j4+P/5eXl/+bm5v/n5+f/6Ojo/+rq6v/r6+v/7Ozs/+3t7f/u7u7/7+/v/+/v7//w8PCX////Af// + /wHf39/x3d3d/9ra2v/Y2Nj/vr6+/1xcXP8lJSX/IyMj/yMjI/8iIiL/IiIi/yIiIv8hISH/ISEh/yEh + If8nISD/likV/zAhHv8nIB//iSYU/1skG/92JRf/aCUZ/yIiIf8iIiH/RyMd/3QmGP9dJRv/ayca/zUk + IP8jIyP/IiIi/yMjI/9GRkb/a2tr/7m5uf/Nzc3/z8/P/9HR0f/U1NT/1tbW/9jY2P/b29v/3d3d/9/f + 3//g4OD/4uLi/+Pj4//k5OT/5eXl/+fn5//o6Oj/6enp/+rq6v/r6+v/7Ozs/+3t7f/u7u7/7+/v/+/v + 7//w8PD/8fHxl////wH///8B4eHh8d/f3//d3d3/29vb/9nZ2f/W1tb/paWl/0dHR/8jIyP/IyMj/yIi + Iv8iIiL/IiIi/yIiIv8hISH/ISEh/zkiHv99Jhb/hyYV/14kGv9tJBf/gicX/yQhIP8+Ih3/fCYX/0Ij + Hv9YJRz/hSgX/ykjIv8jIyP/IyMj/yMjI/8TExP/NjY2/62trf/Q0ND/0tLS/9TU1P/W1tb/2NjY/9ra + 2v/c3Nz/3t7e/+Dg4P/i4uL/4+Pj/+Tk5P/l5eX/5+fn/+jo6P/o6Oj/6enp/+rq6v/r6+v/7Ozs/+3t + 7f/u7u7/7+/v//Dw8P/w8PD/8fHx//Ly8pf///8B////AePj4/Hh4eH/39/f/93d3f/c3Nz/2tra/9jY + 2P/Pz8//ioqK/zU1Nf8iIiL/IyMj/yIiIv8iIiL/IiIi/yEhIf8hISH/ISEg/yIhIP9QIxv/qioT/y0h + H/82IR3/nCkU/zojH/8mIiH/YiUa/ysjIf8jIyL/IyMj/yQkJP8YGBj/KCgo/6urq//S0tL/1dXV/9fX + 1//Y2Nj/2tra/9zc3P/e3t7/4ODg/+Li4v/j4+P/5OTk/+Xl5f/n5+f/6Ojo/+jo6P/p6en/6urq/+vr + 6//s7Oz/7e3t/+7u7v/u7u7/7+/v//Dw8P/w8PD/8fHx//Ly8v/y8vKX////Af///wHl5eXx5OTk/+Li + 4v/g4OD/39/f/93d3f/c3Nz/2tra/9jY2P/BwcH/aWlp/ygoKP8iIiL/IiIi/yIiIv8iIiL/ISEh/yEh + If8hISH/KSEg/1kkG/+LJxT/pykT/00kHf8kIiH/fCcX/3QoGv8kIyL/IyMj/yQkJP8cHBz/ICAg/6Cg + oP/U1NT/19fX/9nZ2f/b29v/3Nzc/97e3v/g4OD/4eHh/+Pj4//k5OT/5ubm/+fn5//o6Oj/6Ojo/+np + 6f/q6ur/6+vr/+zs7P/s7Oz/7e3t/+7u7v/v7+//7+/v//Dw8P/x8fH/8fHx//Ly8v/z8/P/8/Pzl/// + /wH///8B5+fn8ebm5v/l5eX/4+Pj/+Li4v/g4OD/39/f/97e3v/c3Nz/29vb/9jY2P+tra3/lpaW/5eX + l/9aWlr/JCQk/yIiIv8iIiL/ISEh/yEhIf8iISH/MiIg/10mG/91Jhj/fSYX/30oGf8mIyL/IyMj/yMj + I/9BQUH/WVlZ/6ampv/X19f/2tra/9zc3P/d3d3/39/f/+Dg4P/i4uL/4+Pj/+Tk5P/m5ub/5+fn/+jo + 6P/o6Oj/6enp/+rq6v/r6+v/7Ozs/+zs7P/t7e3/7u7u/+7u7v/v7+//8PDw//Dw8P/x8fH/8fHx//Ly + 8v/z8/P/8/Pz//T09Jf///8B////Aenp6fHo6Oj/5+fn/+bm5v/k5OT/4+Pj/+Li4v/h4eH/39/f/97e + 3v/d3d3/3Nzc/9vb2//b29v/1NTU/1VVVf8iIiL/IiIi/yIiIv8iIiL/IiIi/yIiIv8kIiL/UCUd/1cm + Hf8mIyL/IyMj/yIiIv8aGhr/ICAg/5WVlf/Z2dn/3d3d/97e3v/f39//4eHh/+Li4v/j4+P/5eXl/+bm + 5v/n5+f/6Ojo/+np6f/q6ur/6urq/+vr6//s7Oz/7Ozs/+3t7f/u7u7/7u7u/+/v7//v7+//8PDw//Hx + 8f/x8fH/8vLy//Ly8v/z8/P/8/Pz//T09P/09PSX////Af///wHr6+vx6urq/+np6f/o6Oj/5+fn/+bm + 5v/l5eX/5OTk/+Pj4//i4uL/4eHh/9/f3//f39//3t7e/93d3f+Xl5f/KSkp/yMjI/8iIiL/IiIi/yIi + Iv8iIiL/IyMj/yMjI/8jIyP/IyMj/yIiIv8eHh7/DQ0N/4ODg//Z2dn/4ODg/+Hh4f/i4uL/4+Pj/+Tk + 5P/l5eX/5ubm/+fn5//o6Oj/6enp/+rq6v/r6+v/6+vr/+zs7P/t7e3/7e3t/+7u7v/u7u7/7+/v/+/v + 7//w8PD/8PDw//Hx8f/x8fH/8vLy//Pz8//z8/P/8/Pz//T09P/09PT/9fX1l////wH///8B7e3t8ezs + 7P/r6+v/6urq/+np6f/o6Oj/5+fn/+bm5v/l5eX/5OTk/+Pj4//j4+P/4uLi/+Hh4f/g4OD/39/f/7m5 + uf9YWFj/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yIiIv8gICD/DQ0N/3p6ev/Z2dn/4+Pj/+Pj + 4//k5OT/5eXl/+bm5v/n5+f/6Ojo/+np6f/p6en/6urq/+vr6//s7Oz/7Ozs/+3t7f/t7e3/7u7u/+/v + 7//v7+//8PDw//Dw8P/w8PD/8fHx//Hx8f/y8vL/8vLy//Pz8//z8/P/9PT0//T09P/19fX/9fX1//b2 + 9pf///8B////Ae7u7vHt7e3/7Ozs/+zs7P/r6+v/6urq/+rq6v/p6en/6Ojo/+fn5//m5ub/5eXl/+Tk + 5P/j4+P/4+Pj/+Li4v/i4uL/39/f/6Kiov8+Pj7/IyMj/yMjI/8jIyP/IyMj/yIiIv9ZWVn/tLS0/6en + p//c3Nz/5OTk/+Xl5f/m5ub/5+fn/+fn5//o6Oj/6enp/+rq6v/r6+v/6+vr/+zs7P/s7Oz/7e3t/+7u + 7v/u7u7/7+/v/+/v7//w8PD/8PDw//Hx8f/x8fH/8fHx//Ly8v/y8vL/8/Pz//Pz8//z8/P/9PT0//T0 + 9P/09PT/9fX1//X19f/29vaX////Af///wHv7+/x7u7u/+7u7v/t7e3/7Ozs/+zs7P/r6+v/6+vr/+rq + 6v/p6en/6Ojo/+fn5//n5+f/5ubm/+Xl5f/l5eX/5OTk/+Tk5P/l5eX/2NjY/4ODg/8xMTH/IiIi/yIi + Iv9NTU3/19fX/+bm5v/m5ub/5ubm/+fn5//o6Oj/6Ojo/+np6f/q6ur/6urq/+vr6//s7Oz/7Ozs/+3t + 7f/t7e3/7u7u/+7u7v/v7+//7+/v//Dw8P/w8PD/8fHx//Hx8f/y8vL/8vLy//Ly8v/y8vL/8/Pz//Pz + 8//09PT/9PT0//T09P/19fX/9fX1//X19f/29vb/9vb2l////wH///8B8PDw8fDw8P/v7+//7u7u/+7u + 7v/t7e3/7e3t/+zs7P/s7Oz/6+vr/+rq6v/q6ur/6enp/+jo6P/o6Oj/5+fn/+fn5//n5+f/5+fn/+fn + 5//m5ub/xMTE/2VlZf9LS0v/0tLS/+jo6P/p6en/6enp/+np6f/p6en/6urq/+rq6v/r6+v/7Ozs/+zs + 7P/t7e3/7e3t/+7u7v/u7u7/7+/v/+/v7//v7+//8PDw//Dw8P/x8fH/8fHx//Ly8v/y8vL/8vLy//Pz + 8//z8/P/8/Pz//T09P/09PT/9PT0//X19f/19fX/9fX1//b29v/29vb/9vb2//f395f///8B////AfHx + 8fHx8fH/8PDw//Dw8P/v7+//7+/v/+7u7v/u7u7/7e3t/+3t7f/s7Oz/7Ozs/+vr6//q6ur/6urq/+rq + 6v/p6en/6enp/+np6f/p6en/6enp/+rq6v/n5+f/4eHh/+rq6v/q6ur/6urq/+vr6//r6+v/6+vr/+zs + 7P/s7Oz/7e3t/+3t7f/u7u7/7u7u/+/v7//v7+//7+/v//Dw8P/w8PD/8PDw//Hx8f/x8fH/8vLy//Ly + 8v/y8vL/8/Pz//Pz8//z8/P/9PT0//T09P/09PT/9fX1//X19f/19fX/9vb2//b29v/29vb/9vb2//f3 + 9//39/eX////Af///wHy8vLx8vLy//Hx8f/x8fH/8PDw//Dw8P/w8PD/7+/v/+/v7//u7u7/7u7u/+3t + 7f/t7e3/7Ozs/+zs7P/s7Oz/7Ozs/+zs7P/r6+v/7Ozs/+zs7P/s7Oz/7Ozs/+zs7P/s7Oz/7Ozs/+zs + 7P/s7Oz/7e3t/+3t7f/t7e3/7u7u/+7u7v/v7+//7+/v/+/v7//w8PD/8PDw//Hx8f/x8fH/8fHx//Hx + 8f/y8vL/8vLy//Pz8//z8/P/8/Pz//T09P/09PT/9PT0//T09P/19fX/9fX1//X19f/29vb/9vb2//b2 + 9v/29vb/9/f3//f39//39/f/9/f3l////wH///8B8/Pz8fPz8//y8vL/8vLy//Ly8v/x8fH/8fHx//Dw + 8P/w8PD/8PDw/+/v7//v7+//7+/v/+7u7v/u7u7/7u7u/+7u7v/t7e3/7u7u/+7u7v/u7u7/7u7u/+7u + 7v/u7u7/7u7u/+7u7v/u7u7/7u7u/+7u7v/u7u7/7+/v/+/v7//w8PD/8PDw//Dw8P/x8fH/8fHx//Hx + 8f/y8vL/8vLy//Ly8v/y8vL/8/Pz//Pz8//z8/P/9PT0//T09P/09PT/9fX1//X19f/19fX/9fX1//b2 + 9v/29vb/9vb2//b29v/39/f/9/f3//f39//39/f/+Pj4//j4+Jf///8BAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAoAAAAgAAAAAABAAABACAAAAAAAAAIAQAAAAAAAAAAAAAAAAAAAAAA////Af// + /wHw8PDj8PDw/+/v7//v7+//7+/v/+7u7v/u7u7/7u7u/+3t7f/t7e3/7e3t/+zs7P/s7Oz/6+vr/+vr + 6//q6ur/6urq/+np6f/p6en/6Ojo/+jo6P/n5+f/5ubm/+bm5v/l5eX/5OTk/+Tk5P/j4+P/4uLi/+Hh + 4f/h4eH/4ODg/9/f3//e3t7/3t7e/93d3f/c3Nz/3Nzc/9vb2//a2tr/2dnZ/9nZ2f/Y2Nj/19fX/9bW + 1v/V1dX/09PT/9LS0v/Q0ND/zs7O/83Nzf/Ly8v/ysrK/8jIyP/Hx8f/xcXF/8TExP/CwsL/wcHB/8DA + wP++vr7/vb29/7u7u/+6urr/uLi4/7e3t/+1tbX/tLS0/7Ozs/+ysrL/sbGx/7Gxsf+wsLD/sLCw/7Cw + sP+wsLD/sLCw/7Gxsf+xsbH/sbGx/7Kysv+ysrL/srKy/7S0tP+0tLT/tbW1/7a2tv+3t7f/uLi4/7m5 + uf+7u7v/u7u7/729vf++vr7/wMDA/8HBwf/BwcH/w8PD/8TExP/FxcX/xsbG/8jIyP/Jycn/ysrK/8vL + y//MzMz/zs7O/8/Pz//Q0ND/0dHR/9PT0//T09P/1dXV/9bW1v/X19f/2NjY/9nZ2f/b29v/3Nzc/97e + 3v/e3t7/39/f/+Hh4f/h4eEx////Af///wH///8B////AfDw8OPv7+//7+/v/+/v7//v7+//7u7u/+7u + 7v/t7e3/7e3t/+zs7P/s7Oz/7Ozs/+vr6//r6+v/6urq/+rq6v/p6en/6enp/+jo6P/o6Oj/5+fn/+fn + 5//m5ub/5eXl/+Tk5P/k5OT/4+Pj/+Li4v/h4eH/4eHh/+Dg4P/f39//3t7e/93d3f/c3Nz/3Nzc/9vb + 2//a2tr/2tra/9nZ2f/Y2Nj/19fX/9bW1v/V1dX/1NTU/9PT0//R0dH/z8/P/83Nzf/MzMz/ysrK/8jI + yP/Hx8f/xcXF/8PDw//BwcH/wMDA/7+/v/+9vb3/vLy8/7q6uv+4uLj/t7e3/7W1tf+zs7P/srKy/7Cw + sP+vr6//rq6u/62trf+tra3/rKys/6urq/+rq6v/q6ur/6urq/+rq6v/rKys/62trf+tra3/ra2t/66u + rv+urq7/sLCw/7CwsP+ysrL/srKy/7Ozs/+1tbX/tra2/7e3t/+5ubn/urq6/7y8vP+9vb3/vr6+/7+/ + v//AwMD/wsLC/8PDw//ExMT/xcXF/8bGxv/IyMj/ycnJ/8vLy//MzMz/zc3N/87Ozv/Pz8//0dHR/9LS + 0v/T09P/1dXV/9bW1v/X19f/2NjY/9nZ2f/b29v/3Nzc/97e3v/f39//39/f/+Dg4DH///8B////Af// + /wH///8B7+/v4+/v7//u7u7/7u7u/+7u7v/t7e3/7e3t/+3t7f/s7Oz/7Ozs/+vr6//r6+v/6urq/+rq + 6v/p6en/6enp/+jo6P/o6Oj/5+fn/+fn5//m5ub/5eXl/+Xl5f/k5OT/4+Pj/+Pj4//i4uL/4eHh/+Dg + 4P/f39//3t7e/93d3f/d3d3/3Nzc/9vb2//a2tr/2dnZ/9nZ2f/Y2Nj/19fX/9bW1v/V1dX/1NTU/9PT + 0//S0tL/0NDQ/87Ozv/MzMz/ysrK/8nJyf/Gxsb/xcXF/8LCwv/BwcH/v7+//729vf+8vLz/urq6/7i4 + uP+2trb/tLS0/7Kysv+wsLD/rq6u/6ysrP+rq6v/qamp/6ioqP+np6f/p6en/6ampv+lpaX/paWl/6Wl + pf+lpaX/paWl/6ampv+mpqb/p6en/6ioqP+oqKj/qamp/6qqqv+rq6v/rKys/62trf+vr6//sLCw/7Gx + sf+ysrL/tLS0/7a2tv+2trb/uLi4/7m5uf+7u7v/vLy8/729vf+/v7//wMDA/8LCwv/CwsL/w8PD/8XF + xf/Gxsb/yMjI/8nJyf/Ly8v/zMzM/83Nzf/Pz8//0NDQ/9HR0f/S0tL/1NTU/9XV1f/W1tb/2NjY/9nZ + 2f/b29v/3Nzc/97e3v/e3t7/39/fMf///wH///8B////Af///wHv7+/j7+/v/+7u7v/u7u7/7u7u/+3t + 7f/t7e3/7Ozs/+zs7P/r6+v/6+vr/+rq6v/q6ur/6enp/+np6f/o6Oj/6Ojo/+fn5//m5ub/5ubm/+Xl + 5f/l5eX/5OTk/+Pj4//i4uL/4eHh/+Hh4f/g4OD/39/f/97e3v/d3d3/3Nzc/9vb2//a2tr/2tra/9nZ + 2f/Y2Nj/19fX/9bW1v/V1dX/1NTU/9PT0//S0tL/0NDQ/8/Pz//Nzc3/y8vL/8rKyv/Hx8f/xsbG/8PD + w//BwcH/v7+//729vf+7u7v/ubm5/7e3t/+1tbX/s7Oz/7Gxsf+urq7/rKys/6mpqf+np6f/paWl/6Oj + o/+ioqL/oaGh/6CgoP+goKD/n5+f/5+fn/+fn5//n5+f/5+fn/+goKD/oaGh/6Ghof+ioqL/o6Oj/6Sk + pP+lpaX/pqam/6enp/+oqKj/qamp/6qqqv+srKz/ra2t/6+vr/+xsbH/srKy/7Ozs/+1tbX/tra2/7i4 + uP+5ubn/u7u7/7y8vP+9vb3/v7+//8DAwP/BwcH/w8PD/8TExP/FxcX/x8fH/8jIyP/Kysr/y8vL/8zM + zP/Ozs7/z8/P/9HR0f/S0tL/1NTU/9XV1f/W1tb/2NjY/9nZ2f/b29v/3Nzc/97e3v/e3t4x////Af// + /wH///8B////Ae7u7uPu7u7/7u7u/+3t7f/t7e3/7Ozs/+zs7P/s7Oz/6+vr/+vr6//q6ur/6urq/+np + 6f/p6en/6Ojo/+jo6P/n5+f/5ubm/+bm5v/l5eX/5eXl/+Tk5P/j4+P/4uLi/+Hh4f/h4eH/4ODg/9/f + 3//e3t7/3d3d/9zc3P/b29v/2tra/9nZ2f/Y2Nj/19fX/9bW1v/V1dX/1NTU/9PT0//S0tL/0NDQ/8/P + z//Ozs7/zMzM/8rKyv/IyMj/x8fH/8TExP/CwsL/v7+//729vf+7u7v/uLi4/7e3t/+0tLT/srKy/7Cw + sP+tra3/qqqq/6enp/+lpaX/oaGh/6CgoP+dnZ3/m5ub/5qamv+ZmZn/mJiY/5iYmP+YmJj/mJiY/5iY + mP+YmJj/mZmZ/5qamv+bm5v/nJyc/52dnf+dnZ3/n5+f/6CgoP+hoaH/oqKi/6Ojo/+lpaX/pqam/6io + qP+qqqr/q6ur/62trf+urq7/sLCw/7Kysv+zs7P/tbW1/7a2tv+4uLj/ubm5/7u7u/+8vLz/vb29/7+/ + v//AwMD/wsLC/8PDw//ExMT/xsbG/8fHx//Jycn/y8vL/8zMzP/Ozs7/z8/P/9HR0f/S0tL/1NTU/9XV + 1f/X19f/2dnZ/9nZ2f/b29v/3Nzc/93d3TH///8B////Af///wH///8B7u7u4+3t7f/t7e3/7e3t/+zs + 7P/s7Oz/7Ozs/+vr6//r6+v/6urq/+np6f/p6en/6Ojo/+jo6P/n5+f/5+fn/+bm5v/l5eX/5eXl/+Tk + 5P/j4+P/4+Pj/+Li4v/h4eH/4ODg/9/f3//e3t7/3d3d/9zc3P/c3Nz/2tra/9nZ2f/Z2dn/19fX/9bW + 1v/V1dX/1NTU/9PT0//S0tL/0dHR/8/Pz//Nzc3/zMzM/8rKyv/IyMj/x8fH/8XFxf/Dw8P/wcHB/76+ + vv+7u7v/ubm5/7a2tv+0tLT/sbGx/66urv+srKz/qamp/6ampv+jo6P/n5+f/5mZmf+BgYH/ioqK/5SU + lP+Tk5P/kZGR/5CQkP+QkJD/kJCQ/5CQkP+QkJD/kZGR/5GRkf+SkpL/k5OT/5WVlf+Wlpb/lpaW/5eX + l/+ZmZn/mpqa/5ycnP+dnZ3/np6e/6CgoP+ioqL/o6Oj/6ampv+np6f/qamp/6urq/+srKz/rq6u/6+v + r/+xsbH/s7Oz/7S0tP+2trb/t7e3/7m5uf+6urr/vLy8/729vf+/v7//wMDA/8HBwf/ExMT/xcXF/8fH + x//Jycn/ysrK/8zMzP/Ozs7/z8/P/9HR0f/S0tL/1NTU/9bW1v/X19f/2dnZ/9ra2v/b29v/3NzcMf// + /wH///8B////Af///wHt7e3j7e3t/+zs7P/s7Oz/7Ozs/+vr6//r6+v/6urq/+rq6v/q6ur/6enp/+np + 6f/o6Oj/5+fn/+bm5v/m5ub/5eXl/+Xl5f/k5OT/4+Pj/+Li4v/i4uL/4ODg/+Dg4P/f39//3t7e/93d + 3f/c3Nz/29vb/9ra2v/Z2dn/2NjY/9fX1//W1tb/1NTU/9PT0//S0tL/0dHR/9DQ0P/Pz8//zc3N/8vL + y//Jycn/yMjI/8bGxv/Dw8P/wsLC/8DAwP++vr7/u7u7/7m5uf+2trb/s7Oz/6+vr/+srKz/qamp/6en + p/+jo6P/n5+f/5ycnP+VlZX/fX19/2RkZP9paWn/enp6/4qKiv+Li4v/iYmJ/4mJif+JiYn/iYmJ/4qK + iv+Kior/i4uL/4yMjP+Ojo7/j4+P/5CQkP+RkZH/kpKS/5SUlP+VlZX/l5eX/5mZmf+ampr/m5ub/56e + nv+fn5//oqKi/6SkpP+mpqb/p6en/6ioqP+rq6v/rKys/66urv+wsLD/sbGx/7Ozs/+0tLT/tra2/7i4 + uP+5ubn/u7u7/7y8vP++vr7/wMDA/8HBwf/Dw8P/xcXF/8fHx//Jycn/ysrK/8zMzP/Ozs7/z8/P/9HR + 0f/S0tL/1NTU/9bW1v/X19f/2dnZ/9ra2v/b29sx////Af///wH///8B////Ae3t7ePs7Oz/7Ozs/+vr + 6//r6+v/6urq/+rq6v/q6ur/6enp/+np6f/o6Oj/5+fn/+fn5//m5ub/5ubm/+Xl5f/k5OT/4+Pj/+Pj + 4//i4uL/4eHh/+Dg4P/f39//3t7e/93d3f/d3d3/29vb/9vb2//Z2dn/2NjY/9jY2P/W1tb/1dXV/9PT + 0//T09P/0tLS/9DQ0P/Pz8//zc3N/8zMzP/Kysr/yMjI/8bGxv/ExMT/wsLC/8DAwP++vr7/vLy8/7m5 + uf+3t7f/tLS0/7Kysv+urq7/qqqq/6enp/+jo6P/n5+f/5ubm/+Xl5f/k5OT/4CAgP9jY2P/YmJi/2Fh + Yf9iYmL/enp6/4ODg/+CgoL/gYGB/4GBgf+CgoL/goKC/4ODg/+EhIT/hoaG/4eHh/+IiIj/iYmJ/4uL + i/+MjIz/jo6O/4+Pj/+RkZH/k5OT/5WVlf+Xl5f/mZmZ/5qamv+dnZ3/n5+f/6Ghof+ioqL/pKSk/6am + pv+oqKj/qqqq/6urq/+tra3/r6+v/7Gxsf+ysrL/tLS0/7a2tv+4uLj/ubm5/7u7u/+9vb3/v7+//8HB + wf/CwsL/xMTE/8bGxv/IyMj/ysrK/8zMzP/Ozs7/z8/P/9HR0f/S0tL/1NTU/9bW1v/X19f/2dnZ/9nZ + 2TH///8B////Af///wH///8B7Ozs4+zs7P/r6+v/6+vr/+vr6//q6ur/6urq/+np6f/p6en/6Ojo/+fn + 5//n5+f/5ubm/+bm5v/l5eX/5OTk/+Pj4//i4uL/4uLi/+Hh4f/g4OD/39/f/97e3v/d3d3/3Nzc/9vb + 2//a2tr/2dnZ/9jY2P/X19f/1tbW/9XV1f/T09P/0tLS/9HR0f/Q0ND/zs7O/8zMzP/Kysr/ycnJ/8fH + x//FxcX/xMTE/8HBwf+/v7//vb29/7u7u/+5ubn/tra2/7S0tP+wsLD/ra2t/6qqqv+lpaX/oqKi/52d + nf+ZmZn/lJSU/5CQkP+MjIz/dnZ2/2FhYf9jY2P/YmJi/2FhYf92dnb/fX19/3x8fP98fHz/e3t7/3x8 + fP98fHz/fX19/35+fv+AgID/gYGB/4ODg/+EhIT/hYWF/4eHh/+JiYn/i4uL/4yMjP+Ojo7/kJCQ/5KS + kv+UlJT/lpaW/5mZmf+bm5v/nZ2d/56env+goKD/oqKi/6SkpP+mpqb/qKio/6qqqv+srKz/ra2t/7Cw + sP+xsbH/s7Oz/7W1tf+2trb/ubm5/7q6uv+9vb3/vr6+/8DAwP/CwsL/xMTE/8bGxv/IyMj/ysrK/8vL + y//Nzc3/z8/P/9HR0f/T09P/1dXV/9bW1v/X19f/2NjYMf///wH///8B////Af///wHr6+vj6+vr/+vr + 6//q6ur/6urq/+np6f/p6en/6Ojo/+jo6P/n5+f/5+fn/+bm5v/l5eX/5eXl/+Tk5P/j4+P/4uLi/+Hh + 4f/h4eH/39/f/9/f3//e3t7/3Nzc/9zc3P/b29v/2tra/9jY2P/X19f/19fX/9XV1f/V1dX/09PT/9LS + 0v/R0dH/z8/P/87Ozv/MzMz/ysrK/8jIyP/Gxsb/xMTE/8LCwv/AwMD/vr6+/7y8vP+5ubn/t7e3/7W1 + tf+ysrL/r6+v/6ysrP+pqan/pKSk/5+fn/+bm5v/lpaW/5GRkf+MjIz/iIiI/4SEhP9ycnL/YWFh/2Rk + ZP9iYmL/YWFh/3Fxcf92dnb/dnZ2/3V1df91dXX/dXV1/3V1df92dnb/eHh4/3p6ev97e3v/fX19/39/ + f/+AgID/goKC/4ODg/+Ghob/h4eH/4mJif+Li4v/jY2N/5CQkP+SkpL/lJSU/5aWlv+YmJj/mpqa/5yc + nP+enp7/oKCg/6Kiov+kpKT/pqam/6ioqP+qqqr/rKys/66urv+wsLD/srKy/7Ozs/+2trb/uLi4/7q6 + uv+8vLz/vr6+/8DAwP/CwsL/xMTE/8bGxv/IyMj/ysrK/8vLy//Nzc3/z8/P/9HR0f/T09P/1dXV/9bW + 1v/X19cx////Af///wH///8B////Aevr6+Pr6+v/6urq/+np6f/p6en/6Ojo/+jo6P/o6Oj/5+fn/+bm + 5v/m5ub/5eXl/+Tk5P/k5OT/4+Pj/+Li4v/h4eH/4ODg/9/f3//e3t7/3t7e/9zc3P/b29v/2tra/9nZ + 2f/Y2Nj/19fX/9bW1v/V1dX/1NTU/9PT0//R0dH/0NDQ/8/Pz//Nzc3/zMzM/8rKyv/IyMj/xsbG/8TE + xP/CwsL/v7+//729vf+7u7v/uLi4/7a2tv+zs7P/sLCw/62trf+rq6v/p6en/6Ojo/+enp7/mZmZ/5SU + lP+Ojo7/iYmJ/4SEhP9/f3//fHx8/21tbf9iYmL/ZWVl/2NjY/9iYmL/bW1t/3BwcP9wcHD/b29v/29v + b/9vb2//b29v/3Fxcf9zc3P/dHR0/3Z2dv94eHj/enp6/3t7e/99fX3/fn5+/4CAgP+CgoL/hISE/4aG + hv+JiYn/i4uL/42Njf+Pj4//kZGR/5SUlP+Wlpb/mJiY/5qamv+cnJz/np6e/6CgoP+jo6P/paWl/6am + pv+pqan/qqqq/62trf+vr6//sbGx/7Ozs/+1tbX/t7e3/7m5uf+8vLz/vr6+/7+/v//CwsL/xMTE/8bG + xv/IyMj/ysrK/8zMzP/Ozs7/z8/P/9HR0f/T09P/1dXV/9bW1jH///8B////Af///wH///8B6urq4+rq + 6v/p6en/6enp/+jo6P/o6Oj/5+fn/+fn5//m5ub/5ubm/+Xl5f/l5eX/5OTk/+Pj4//i4uL/4eHh/+Hh + 4f/f39//3t7e/93d3f/c3Nz/29vb/9ra2v/Z2dn/2NjY/9fX1//W1tb/1dXV/9TU1P/S0tL/0dHR/9DQ + 0P/Ozs7/zc3N/8vLy//Jycn/x8fH/8XFxf/Dw8P/wcHB/7+/v/+9vb3/urq6/7e3t/+1tbX/s7Oz/7Cw + sP+tra3/qamp/6ampv+ioqL/nZ2d/5iYmP+Tk5P/jY2N/4eHh/+CgoL/fX19/3h4eP91dXX/a2tr/2Rk + ZP9mZmb/ZWVl/2NjY/9paWn/ampq/2lpaf9paWn/aWlp/2pqav9ra2v/bW1t/25ubv9wcHD/cnJy/3Nz + c/91dXX/d3d3/3l5ef96enr/fHx8/319ff9/f3//gYGB/4SEhP+Hh4f/iYmJ/4uLi/+NjY3/kJCQ/5KS + kv+UlJT/lpaW/5iYmP+bm5v/nZ2d/5+fn/+hoaH/o6Oj/6ampv+oqKj/qqqq/6ysrP+urq7/sLCw/7Ky + sv+1tbX/t7e3/7m5uf+7u7v/vb29/8DAwP/CwsL/xMTE/8bGxv/IyMj/ysrK/8zMzP/Ozs7/0NDQ/9LS + 0v/U1NT/1dXVMf///wH///8B////Af///wHq6urj6enp/+np6f/o6Oj/6Ojo/+fn5//n5+f/5ubm/+Xl + 5f/l5eX/5OTk/+Tk5P/j4+P/4uLi/+Hh4f/g4OD/39/f/97e3v/d3d3/3Nzc/9vb2//a2tr/2dnZ/9fX + 1//X19f/1tbW/9TU1P/T09P/0tLS/9HR0f/Q0ND/zs7O/8zMzP/Kysr/ycnJ/8fHx//FxcX/w8PD/8HB + wf++vr7/vLy8/7m5uf+2trb/s7Oz/7Gxsf+urq7/rKys/6mpqf+lpaX/oaGh/5ubm/+Xl5f/kZGR/4uL + i/+Ghob/gYGB/3x8fP92dnb/cnJy/29vb/9oaGj/ZWVl/2lpaf9qamr/ampq/2hoaP9kZGT/Y2Nj/2Nj + Y/9kZGT/ZWVl/2ZmZv9oaGj/aWlp/2tra/9tbW3/bm5u/3BwcP9xcXH/c3Nz/3V1df92dnb/eHh4/3p6 + ev98fHz/fn5+/4GBgf+EhIT/hoaG/4mJif+Li4v/jY2N/4+Pj/+RkZH/lJSU/5aWlv+ZmZn/m5ub/56e + nv+fn5//oqKi/6SkpP+mpqb/qKio/6urq/+tra3/r6+v/7Kysv+0tLT/tra2/7m5uf+7u7v/vb29/7+/ + v//CwsL/xMTE/8bGxv/IyMj/ysrK/83Nzf/Pz8//0dHR/9PT0//T09Mx////Af///wH///8B////Aenp + 6ePp6en/6Ojo/+jo6P/n5+f/5+fn/+bm5v/l5eX/5eXl/+Tk5P/k5OT/4+Pj/+Li4v/h4eH/4ODg/9/f + 3//f39//3d3d/9zc3P/b29v/2tra/9nZ2f/Y2Nj/19fX/9bW1v/U1NT/09PT/9LS0v/R0dH/z8/P/87O + zv/MzMz/ysrK/8nJyf/Hx8f/xcXF/8PDw//BwcH/vr6+/7y8vP+5ubn/tra2/7Ozs/+wsLD/rq6u/6ur + q/+oqKj/pKSk/6CgoP+cnJz/lZWV/5CQkP+Li4v/hoaG/39/f/96enr/dnZ2/3Fxcf9ubm7/a2tr/2dn + Z/9nZ2f/a2tr/25ubv9ycnL/cHBw/2dnZ/9fX1//X19f/2BgYP9hYWH/YmJi/2RkZP9lZWX/Z2dn/2ho + aP9qamr/a2tr/21tbf9vb2//cHBw/3Jycv90dHT/dnZ2/3l5ef97e3v/fX19/4CAgP+CgoL/hYWF/4eH + h/+JiYn/i4uL/46Ojv+QkJD/k5OT/5WVlf+YmJj/mpqa/5ycnP+fn5//oaGh/6Ojo/+lpaX/qKio/6qq + qv+tra3/r6+v/7Gxsf+0tLT/tra2/7m5uf+7u7v/vb29/8DAwP/CwsL/xMTE/8fHx//Jycn/y8vL/83N + zf/Pz8//0dHR/9LS0jH///8B////Af///wH///8B6enp4+jo6P/o6Oj/5+fn/+fn5//m5ub/5eXl/+Xl + 5f/k5OT/4+Pj/+Pj4//i4uL/4eHh/+Dg4P/g4OD/3t7e/97e3v/c3Nz/29vb/9ra2v/Z2dn/2NjY/9fX + 1//W1tb/1NTU/9PT0//R0dH/0NDQ/8/Pz//Nzc3/zMzM/8rKyv/Jycn/x8fH/8XFxf/Dw8P/wMDA/76+ + vv+7u7v/uLi4/7W1tf+zs7P/sLCw/62trf+qqqr/p6en/6Ojo/+fn5//mpqa/5WVlf+Pj4//ioqK/4WF + hf97e3v/Y2Nj/11dXf9nZ2f/ampq/2pqav9nZ2f/Z2dn/2lpaf9sbGz/b29v/3Nzc/90dHT/b29v/1xc + XP9bW1v/XFxc/11dXf9eXl7/X19f/2FhYf9iYmL/ZGRk/2VlZf9nZ2f/aWlp/2pqav9sbGz/bW1t/29v + b/9xcXH/dHR0/3Z2dv94eHj/enp6/35+fv+AgID/goKC/4SEhP+Hh4f/ioqK/4yMjP+Ojo7/kZGR/5SU + lP+Wlpb/mJiY/5ubm/+dnZ3/oKCg/6Kiov+kpKT/p6en/6qqqv+tra3/r6+v/7Gxsf+0tLT/tra2/7m5 + uf+7u7v/vr6+/8DAwP/CwsL/xcXF/8fHx//Kysr/zMzM/87Ozv/Q0ND/0NDQMf///wH///8B////Af// + /wHp6enj6Ojo/+fn5//n5+f/5ubm/+Xl5f/l5eX/5OTk/+Pj4//j4+P/4uLi/+Hh4f/g4OD/4ODg/9/f + 3//e3t7/3d3d/9zc3P/a2tr/2dnZ/9jY2P/X19f/1tbW/9TU1P/T09P/0dHR/9DQ0P/Pz8//zc3N/8vL + y//Kysr/yMjI/8fHx//FxcX/w8PD/8DAwP++vr7/u7u7/7i4uP+1tbX/s7Oz/7CwsP+tra3/qamp/6am + pv+ioqL/np6e/5qamv+UlJT/j4+P/4mJif+EhIT/fX19/2NjY/9QUFD/S0tL/01NTf9dXV3/ZWVl/2Vl + Zf9oaGj/a2tr/25ubv9wcHD/c3Nz/3R0dP9wcHD/Wlpa/1dXV/9YWFj/WVlZ/1paWv9bW1v/XV1d/15e + Xv9gYGD/YWFh/2JiYv9kZGT/ZmZm/2dnZ/9paWn/a2tr/21tbf9vb2//cnJy/3R0dP92dnb/eXl5/3t7 + e/9+fn7/gICA/4ODg/+Ghob/iIiI/4uLi/+NjY3/kJCQ/5OTk/+VlZX/mJiY/5qamv+dnZ3/n5+f/6Gh + of+kpKT/p6en/6qqqv+tra3/r6+v/7Gxsf+0tLT/t7e3/7m5uf+7u7v/vr6+/8HBwf/Dw8P/xsbG/8jI + yP/Kysr/zMzM/8/Pz//Q0NAx////Af///wH///8B////Aejo6OPo6Oj/5+fn/+bm5v/m5ub/5eXl/+Tk + 5P/j4+P/4+Pj/+Li4v/h4eH/4ODg/+Dg4P/f39//3t7e/93d3f/c3Nz/2tra/9nZ2f/Y2Nj/19fX/9bW + 1v/U1NT/09PT/9HR0f/Q0ND/z8/P/83Nzf/Ly8v/ycnJ/8jIyP/Gxsb/xMTE/8LCwv/AwMD/vr6+/7u7 + u/+4uLj/tbW1/7Ozs/+wsLD/ra2t/6qqqv+mpqb/oqKi/56env+ZmZn/lJSU/42Njf+IiIj/goKC/319 + ff9ycnL/VFRU/09PT/9JSUn/RUVF/1VVVf9hYWH/ZGRk/2pqav9tbW3/cHBw/3Jycv90dHT/dXV1/3Bw + cP9XV1f/VFRU/1VVVf9WVlb/V1dX/1hYWP9XV1f/S0tL/0lJSf9YWFj/Xl5e/2BgYP9hYWH/Y2Nj/2Vl + Zf9nZ2f/aWlp/2tra/9tbW3/cHBw/3Jycv91dXX/d3d3/3p6ev98fHz/fn5+/4GBgf+EhIT/h4eH/4qK + iv+MjIz/j4+P/5GRkf+UlJT/l5eX/5mZmf+cnJz/np6e/6Ghof+kpKT/p6en/6qqqv+srKz/r6+v/7Ky + sv+0tLT/t7e3/7q6uv+9vb3/v7+//8HBwf/ExMT/xsbG/8nJyf/Ly8v/zs7O/8/PzzH///8B////Af// + /wH///8B6Ojo4+fn5//m5ub/5ubm/+Xl5f/k5OT/5OTk/+Pj4//i4uL/4eHh/+Dg4P/g4OD/39/f/97e + 3v/d3d3/3Nzc/9vb2//Z2dn/2NjY/9fX1//W1tb/1NTU/9PT0//R0dH/0NDQ/8/Pz//Nzc3/y8vL/8nJ + yf/IyMj/xsbG/8TExP/CwsL/wMDA/729vf+7u7v/uLi4/7W1tf+ysrL/sLCw/62trf+qqqr/pqam/6Gh + of+enp7/mZmZ/5OTk/+Ojo7/h4eH/4KCgv98fHz/dnZ2/2xsbP9VVVX/UVFR/0dHR/9DQ0P/UlJS/15e + Xv9nZ2f/bGxs/25ubv9xcXH/dHR0/3d3d/93d3f/cXFx/1NTU/9QUFD/UVFR/1JSUv9TU1P/UlJS/z4+ + Pv8fHx//Hh4e/zExMf9KSkr/Wlpa/15eXv9fX1//YmJi/2NjY/9lZWX/Z2dn/2lpaf9ra2v/bm5u/3Bw + cP9ycnL/dXV1/3h4eP96enr/fX19/4CAgP+Dg4P/hYWF/4iIiP+Li4v/jo6O/5CQkP+Tk5P/lpaW/5mZ + mf+bm5v/np6e/6Ghof+kpKT/p6en/6qqqv+tra3/r6+v/7Kysv+1tbX/uLi4/7q6uv+9vb3/wMDA/8PD + w//FxcX/x8fH/8rKyv/MzMz/zc3NMf///wH///8B////Af///wHn5+fj5+fn/+bm5v/l5eX/5eXl/+Tk + 5P/j4+P/4uLi/+Li4v/h4eH/4ODg/9/f3//e3t7/3d3d/9zc3P/b29v/2tra/9jY2P/X19f/1tbW/9TU + 1P/T09P/0dHR/9DQ0P/Pz8//zc3N/8vLy//Jycn/x8fH/8bGxv/ExMT/wcHB/8DAwP+9vb3/u7u7/7m5 + uf+1tbX/s7Oz/7CwsP+tra3/qqqq/6ampv+jo6P/np6e/5mZmf+UlJT/j4+P/4iIiP+CgoL/fHx8/3Z2 + dv9wcHD/ZmZm/1ZWVv9TU1P/RkZG/0JCQv9PT0//X19f/2lpaf9tbW3/b29v/3Jycv96enr/fn5+/3h4 + eP9xcXH/UVFR/01NTf9OTk7/T09P/09PT/9AQED/ISEh/xoaGv8bGxv/Hh4e/yYmJv88PDz/VFRU/1xc + XP9eXl7/YGBg/2FhYf9jY2P/ZWVl/2dnZ/9qamr/bGxs/25ubv9xcXH/dHR0/3d3d/96enr/fHx8/39/ + f/+BgYH/hISE/4eHh/+Kior/jY2N/5CQkP+Tk5P/lZWV/5mZmf+cnJz/np6e/6Kiov+kpKT/p6en/6qq + qv+tra3/sLCw/7Ozs/+2trb/ubm5/7y8vP+/v7//wcHB/8TExP/Gxsb/ycnJ/8zMzP/MzMwx////Af// + /wH///8B////Aefn5+Pm5ub/5ubm/+Tk5P/k5OT/4+Pj/+Li4v/i4uL/4eHh/+Dg4P/f39//3t7e/93d + 3f/c3Nz/29vb/9ra2v/Z2dn/19fX/9fX1//V1dX/1NTU/9LS0v/Q0ND/z8/P/83Nzf/Ly8v/ycnJ/8fH + x//Gxsb/w8PD/8HBwf+/v7//vb29/7u7u/+4uLj/tbW1/7Kysv+wsLD/ra2t/6mpqf+mpqb/oqKi/5+f + n/+ZmZn/lJSU/46Ojv+IiIj/goKC/3t7e/92dnb/b29v/2lpaf9gYGD/WFhY/1VVVf9ERET/QUFB/0tL + S/9eXl7/a2tr/25ubv9xcXH/enp6/46Ojv+VlZX/fHx8/3Nzc/9PT0//SUlJ/0pKSv9LS0v/PDw8/xsb + G/8TExP/HBwc/x4eHv8dHR3/Hh4e/x4eHv8oKCj/QEBA/1VVVf9bW1v/XV1d/19fX/9hYWH/Y2Nj/2Vl + Zf9oaGj/ampq/21tbf9wcHD/cnJy/3V1df94eHj/e3t7/319ff+AgID/g4OD/4aGhv+JiYn/jIyM/4+P + j/+SkpL/lZWV/5iYmP+bm5v/np6e/6Ghof+kpKT/qKio/6urq/+urq7/sbGx/7W1tf+3t7f/urq6/729 + vf/AwMD/w8PD/8XFxf/IyMj/y8vL/8vLyzH///8B////Af///wH///8B5ubm4+bm5v/l5eX/5OTk/+Pj + 4//i4uL/4uLi/+Hh4f/g4OD/39/f/97e3v/d3d3/3Nzc/9vb2//a2tr/2dnZ/9jY2P/X19f/1dXV/9TU + 1P/S0tL/0dHR/8/Pz//Nzc3/y8vL/8nJyf/IyMj/xcXF/8TExP/BwcH/v7+//729vf+7u7v/uLi4/7W1 + tf+zs7P/r6+v/6ysrP+pqan/pqam/6Ojo/+fn5//mpqa/5SUlP+Pj4//iYmJ/4SEhP99fX3/dnZ2/3Bw + cP9paWn/YmJi/1xcXP9bW1v/V1dX/0ZGRv9FRUX/SkpK/11dXf9sbGz/cHBw/3Z2dv+MjIz/oKCg/4+P + j/9vb2//dnZ2/1dXV/9GRkb/R0dH/z4+Pv8dHR3/EhIS/xgYGP8uLi7/LCws/x4eHv8eHh7/Hh4e/x4e + Hv8hISH/NDQ0/0xMTP9ZWVn/W1tb/11dXf9fX1//YWFh/2RkZP9mZmb/aWlp/2xsbP9ubm7/cXFx/3R0 + dP93d3f/enp6/319ff+AgID/goKC/4aGhv+JiYn/jIyM/4+Pj/+SkpL/lZWV/5iYmP+cnJz/np6e/6Ki + ov+mpqb/qamp/6ysrP+vr6//s7Oz/7a2tv+5ubn/vLy8/76+vv/CwsL/xMTE/8fHx//Kysr/y8vLMf// + /wH///8B////Af///wHm5ubj5eXl/+Tk5P/j4+P/4+Pj/+Li4v/h4eH/4ODg/9/f3//e3t7/3d3d/9zc + 3P/b29v/2tra/9nZ2f/Y2Nj/19fX/9XV1f/U1NT/0tLS/9HR0f/Pz8//zc3N/8zMzP/Kysr/yMjI/8bG + xv/Dw8P/wcHB/7+/v/+9vb3/u7u7/7i4uP+2trb/s7Oz/7CwsP+srKz/qamp/6ampv+jo6P/np6e/5mZ + mf+VlZX/j4+P/4qKiv+EhIT/fn5+/3h4eP9wcHD/ampq/2JiYv9bW1v/WFhY/11dXf9fX1//X19f/1lZ + Wf9MTEz/Xl5e/25ubv92dnb/h4eH/5+fn/+SkpL/VVVV/1ZWVv93d3f/bGxs/05OTv89PT3/JCQk/xMT + E/8YGBj/KCgo/zY2Nv8rKyv/Hh4e/x4eHv8eHh7/Hh4e/x4eHv8eHh7/JSUl/z09Pf9QUFD/WFhY/1tb + W/9dXV3/X19f/2FhYf9kZGT/Z2dn/2pqav9tbW3/cHBw/3Nzc/91dXX/eHh4/3t7e/9+fn7/goKC/4WF + hf+IiIj/i4uL/46Ojv+SkpL/lZWV/5mZmf+cnJz/n5+f/6Ojo/+mpqb/qqqq/62trf+xsbH/tLS0/7e3 + t/+6urr/vb29/8DAwP/Dw8P/xsbG/8nJyf/Kysox////Af///wH///8B////AeXl5ePk5OT/5OTk/+Pj + 4//i4uL/4eHh/+Dg4P/f39//39/f/97e3v/c3Nz/29vb/9ra2v/Z2dn/2NjY/9fX1//W1tb/1NTU/9LS + 0v/R0dH/0NDQ/83Nzf/MzMz/ysrK/8jIyP/Gxsb/xMTE/8HBwf+/v7//vb29/7u7u/+4uLj/tra2/7S0 + tP+wsLD/ra2t/6qqqv+mpqb/o6Oj/6CgoP+ampr/lZWV/5CQkP+JiYn/hISE/35+fv9zc3P/aWlp/2lp + af9kZGT/XFxc/1VVVf9UVFT/YGBg/2NjY/9mZmb/XFxc/09PT/9dXV3/c3Nz/4WFhf+bm5v/lpaW/11d + Xf9MTEz/cHBw/4aGhv92dnb/Y2Nj/ykpKf8WFhb/GBgY/ycnJ/8rKyv/Hx8f/xwcHP8eHh7/Hh4e/x4e + Hv8eHh7/Hh4e/x4eHv8eHh7/Hx8f/ywsLP9DQ0P/VVVV/1lZWf9bW1v/XV1d/2BgYP9jY2P/ZmZm/2lp + af9sbGz/b29v/3Jycv91dXX/eHh4/3t7e/9+fn7/gYGB/4SEhP+IiIj/i4uL/4+Pj/+SkpL/lpaW/5mZ + mf+dnZ3/oaGh/6SkpP+oqKj/q6ur/6+vr/+ysrL/tra2/7m5uf+8vLz/v7+//8LCwv/FxcX/yMjI/8rK + yjH///8B////Af///wH///8B5OTk4+Tk5P/j4+P/4uLi/+Hh4f/g4OD/4ODg/9/f3//e3t7/3d3d/9zc + 3P/b29v/2dnZ/9jY2P/X19f/1tbW/9XV1f/S0tL/0dHR/9DQ0P/Ozs7/zMzM/8rKyv/IyMj/xsbG/8TE + xP/CwsL/wMDA/729vf+7u7v/uLi4/7W1tf+zs7P/sbGx/62trf+qqqr/pqam/6Ojo/+fn5//m5ub/5aW + lv+Pj4//ioqK/4ODg/9+fn7/dHR0/1paWv9NTU3/U1NT/1lZWf9XV1f/UVFR/1RUVP9iYmL/ZWVl/2ho + aP9dXV3/UFBQ/2FhYf+BgYH/mpqa/56env9hYWH/SEhI/2pqav+MjIz/fHx8/5+fn/9nZ2f/HBwc/xcX + F/8lJSX/Kysr/xwcHP8aGhr/HBwc/x4eHv8eHh7/Hh4e/x4eHv8eHh7/Hh4e/x4eHv8eHh7/Hh4e/yMj + I/81NTX/S0tL/1ZWVv9aWlr/XFxc/19fX/9iYmL/ZmZm/2hoaP9ra2v/bm5u/3Fxcf90dHT/d3d3/3t7 + e/9+fn7/gYGB/4WFhf+IiIj/jIyM/4+Pj/+Tk5P/lpaW/5qamv+enp7/oaGh/6ampv+pqan/ra2t/7Gx + sf+0tLT/uLi4/7u7u/++vr7/wcHB/8XFxf/IyMj/ycnJMf///wH///8B////Af///wHj4+Pj4+Pj/+Li + 4v/h4eH/4ODg/9/f3//f39//3t7e/93d3f/c3Nz/29vb/9ra2v/Y2Nj/2NjY/9bW1v/V1dX/09PT/9LS + 0v/Q0ND/zs7O/8zMzP/Kysr/yMjI/8bGxv/ExMT/wsLC/8DAwP+9vb3/u7u7/7i4uP+1tbX/s7Oz/7Cw + sP+urq7/qqqq/6enp/+jo6P/n5+f/5ubm/+Wlpb/kJCQ/4qKiv+EhIT/fX19/3d3d/9eXl7/SkpK/0VF + Rf9BQUH/RUVF/1JSUv9PT0//XFxc/2VlZf9oaGj/ampq/1JSUv9OTk7/bW1t/5eXl/+cnJz/ampq/0dH + R/9mZmb/iYmJ/35+fv+vr6//+vr6/9HR0f84ODj/HR0d/ykpKf8hISH/GRkZ/xsbG/8dHR3/Hh4e/x8f + H/8fHx//Hh4e/x4eHv8eHh7/Hh4e/x4eHv8eHh7/HR0d/x0dHf8lJSX/PT09/09PT/9YWFj/W1tb/15e + Xv9hYWH/ZGRk/2dnZ/9paWn/bGxs/3BwcP9zc3P/dnZ2/3p6ev9+fn7/gYGB/4SEhP+IiIj/i4uL/4+P + j/+Tk5P/l5eX/5ubm/+enp7/o6Oj/6enp/+rq6v/r6+v/7Ozs/+3t7f/urq6/76+vv/BwcH/xMTE/8fH + x//IyMgx////Af///wH///8B////AePj4+Pi4uL/4uLi/+Hh4f/g4OD/39/f/97e3v/d3d3/3Nzc/9vb + 2//a2tr/2dnZ/9jY2P/W1tb/1dXV/9PT0//S0tL/0NDQ/87Ozv/MzMz/ysrK/8nJyf/Hx8f/xcXF/8LC + wv/AwMD/vr6+/7u7u/+5ubn/tbW1/7Ozs/+wsLD/rq6u/6urq/+np6f/pKSk/6CgoP+cnJz/l5eX/5KS + kv+Li4v/hISE/39/f/93d3f/cHBw/1VVVf9MTEz/Q0ND/z4+Pv9BQUH/T09P/1NTU/9jY2P/Z2dn/2pq + av9ra2v/S0tL/0hISP9xcXH/m5ub/2tra/9GRkb/YWFh/4eHh/98fHz/nZ2d//Hx8f/8/Pz/wsLC/zAw + MP8gICD/JSUl/yIiIv8hISH/IiIi/yEhIf8fHx//Hh4e/x4eHv8fHx//Hh4e/x4eHv8eHh7/Hh4e/x4e + Hv8eHh7/Hh4e/x0dHf8hISH/Ly8v/0hISP9XV1f/Wlpa/11dXf9gYGD/ZGRk/2ZmZv9paWn/bGxs/29v + b/9zc3P/dnZ2/3p6ev99fX3/gICA/4WFhf+IiIj/jY2N/5CQkP+UlJT/mZmZ/5ycnP+hoaH/paWl/6mp + qf+tra3/srKy/7a2tv+5ubn/vb29/8DAwP/ExMT/x8fH/8jIyDH///8B////Af///wH///8B4uLi4+Hh + 4f/h4eH/4ODg/9/f3//e3t7/3d3d/9zc3P/b29v/2tra/9nZ2f/Y2Nj/19fX/9bW1v/U1NT/0tLS/9HR + 0f/Ozs7/zc3N/8rKyv/Jycn/x8fH/8XFxf/Dw8P/wMDA/76+vv+7u7v/uLi4/7a2tv+zs7P/sLCw/62t + rf+qqqr/p6en/6Ojo/+fn5//m5ub/5eXl/+RkZH/i4uL/4aGhv9+fn7/eHh4/3BwcP9qamr/VlZW/1BQ + UP9BQUH/Ojo6/z09Pf9NTU3/XFxc/2dnZ/9qamr/bGxs/25ubv9LS0v/R0dH/19fX/9mZmb/RERE/1tb + W/+IiIj/goKC/6CgoP/09PT//Pz8/7y8vP8+Pj7/HBwc/ygoKP8oKCj/ICAg/yIiIv8kJCT/JSUl/yQk + JP8gICD/Hh4e/x8fH/8fHx//Hh4e/x4eHv8eHh7/Hh4e/x4eHv8eHh7/Hh4e/x4eHv8eHh7/IiIi/zY2 + Nv9MTEz/WFhY/1xcXP9fX1//YmJi/2VlZf9oaGj/a2tr/29vb/9ycnL/dnZ2/3l5ef98fHz/gYGB/4SE + hP+JiYn/jY2N/5GRkf+VlZX/mpqa/56env+ioqL/p6en/6ysrP+wsLD/tbW1/7m5uf+9vb3/wMDA/8PD + w//Gxsb/yMjIMf///wH///8B////Af///wHi4uLj4eHh/+Dg4P/f39//3t7e/93d3f/c3Nz/29vb/9ra + 2v/Z2dn/2NjY/9fX1//W1tb/1NTU/9PT0//R0dH/z8/P/83Nzf/Ly8v/ycnJ/8fHx//FxcX/w8PD/8HB + wf++vr7/vLy8/7m5uf+2trb/tLS0/7Gxsf+urq7/qqqq/6enp/+jo6P/n5+f/5ubm/+Wlpb/kZGR/4yM + jP+Ghob/gICA/3l5ef9zc3P/bGxs/2ZmZv9YWFj/UlJS/z8/P/83Nzf/Ozs7/09PT/9kZGT/aWlp/2tr + a/9tbW3/eHh4/2FhYf9LS0v/U1NT/0RERP9XV1f/f39//4aGhv+QkJD/6Ojo///////S0tL/R0dH/xwc + HP8nJyf/KSkp/yIiIv8fHx//IyMj/yQkJP8lJSX/JiYm/yUlJf8iIiL/Hx8f/x8fH/8fHx//Hx8f/x4e + Hv8eHh7/Hh4e/x4eHv8eHh7/Hh4e/x4eHv8eHh7/Hx8f/yoqKv9CQkL/VFRU/1xcXP9fX1//YmJi/2Vl + Zf9oaGj/bGxs/29vb/9ycnL/dnZ2/3l5ef9+fn7/gYGB/4aGhv+Kior/jo6O/5KSkv+Xl5f/nJyc/6Cg + oP+mpqb/qqqq/6+vr/+zs7P/t7e3/7y8vP/AwMD/w8PD/8bGxv/IyMgx////Af///wH///8B////AeHh + 4ePg4OD/4ODg/9/f3//e3t7/3d3d/9zc3P/a2tr/2dnZ/9jY2P/X19f/1tbW/9TU1P/T09P/0tLS/9DQ + 0P/Ozs7/y8vL/8nJyf/Hx8f/xcXF/8PDw//BwcH/vr6+/7y8vP+5ubn/tra2/7S0tP+xsbH/rq6u/6ur + q/+np6f/pKSk/6CgoP+bm5v/lpaW/5CQkP+MjIz/hoaG/4CAgP96enr/c3Nz/25ubv9nZ2f/YWFh/1lZ + Wf9VVVX/PT09/zQ0NP85OTn/TU1N/2ZmZv9ra2v/bW1t/3Z2dv+NjY3/kZGR/15eXv9VVVX/QEBA/15e + Xv+Dg4P/jo6O/+Hh4f/8/Pz/1dXV/1dXV/8cHBz/JiYm/ykpKf8hISH/Hx8f/yIiIv8kJCT/JSUl/yYm + Jv8mJib/Jycn/yYmJv8jIyP/ISEh/x8fH/8fHx//Hx8f/x8fH/8eHh7/Hh4e/x4eHv8eHh7/Hh4e/x4e + Hv8eHh7/Hh4e/yEhIf8wMDD/TExM/1hYWP9eXl7/YWFh/2RkZP9oaGj/a2tr/25ubv9xcXH/dXV1/3p6 + ev99fX3/goKC/4WFhf+Kior/j4+P/5SUlP+ZmZn/np6e/6Ojo/+oqKj/ra2t/7Kysv+3t7f/u7u7/7+/ + v//Dw8P/xsbG/8jIyDH///8B////Af///wH///8B4eHh4+Dg4P/f39//3t7e/93d3f/c3Nz/29vb/9ra + 2v/Z2dn/19fX/9bW1v/U1NT/09PT/9LS0v/Q0ND/zs7O/8zMzP/Kysr/yMjI/8bGxv/Dw8P/wcHB/76+ + vv+8vLz/ubm5/7e3t/+0tLT/sbGx/66urv+rq6v/qKio/6SkpP+goKD/m5ub/5aWlv+RkZH/i4uL/4aG + hv+AgID/enp6/3R0dP9ubm7/aGho/2JiYv9dXV3/W1tb/1paWv9ISEj/QkJC/zo6Ov9KSkr/Z2dn/2xs + bP91dXX/iYmJ/6CgoP+Kior/U1NT/1hYWP9JSUn/PT09/1dXV//X19f//////93d3f9oaGj/Hh4e/yYm + Jv8qKir/Hx8f/x4eHv8hISH/JCQk/yUlJf8mJib/JiYm/yYmJv8mJib/JiYm/yUlJf8kJCT/IiIi/yAg + IP8fHx//Hx8f/x8fH/8fHx//Hh4e/x4eHv8eHh7/Hh4e/x4eHv8eHh7/Hh4e/x4eHv8mJib/Ozs7/1JS + Uv9dXV3/YGBg/2RkZP9nZ2f/ampq/21tbf9xcXH/dXV1/3h4eP99fX3/gYGB/4aGhv+Li4v/kZGR/5eX + l/+bm5v/oaGh/6ampv+srKz/sbGx/7a2tv+7u7v/v7+//8PDw//Gxsb/yMjIMf///wH///8B////Af// + /wHg4ODj4ODg/9/f3//d3d3/3d3d/9vb2//a2tr/2dnZ/9fX1//W1tb/1NTU/9PT0//S0tL/0NDQ/87O + zv/MzMz/ysrK/8jIyP/Gxsb/xMTE/8LCwv+/v7//vb29/7q6uv+2trb/tLS0/7Kysv+urq7/q6ur/6io + qP+lpaX/oaGh/5ycnP+Xl5f/kZGR/4yMjP+Ghob/gYGB/3t7e/90dHT/b29v/2lpaf9jY2P/Xl5e/1lZ + Wf9cXFz/YGBg/2BgYP9YWFj/PT09/0dHR/9oaGj/cnJy/4aGhv+cnJz/kZGR/1dXV/9NTU3/YWFh/1hY + WP9AQED/NTU1/4uLi//W1tb/cHBw/yEhIf8iIiL/Kioq/yEhIf8eHh7/ISEh/yQkJP8lJSX/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yUlJf8mJib/JCQk/yIiIv8gICD/Hx8f/x8fH/8fHx//Hh4e/x4e + Hv8eHh7/Hh4e/x4eHv8eHh7/Hh4e/x4eHv8gICD/Li4u/0pKSv9aWlr/YGBg/2JiYv9lZWX/aGho/2xs + bP9wcHD/dHR0/3l5ef99fX3/goKC/4iIiP+Ojo7/lJSU/5mZmf+fn5//paWl/6urq/+wsLD/tbW1/7q6 + uv++vr7/w8PD/8bGxv/IyMgx////Af///wH///8B////AeDg4OPf39//3t7e/93d3f/b29v/2tra/9nZ + 2f/X19f/1tbW/9TU1P/T09P/0tLS/9DQ0P/Ozs7/zMzM/8rKyv/IyMj/xsbG/8TExP/CwsL/v7+//729 + vf+6urr/t7e3/7S0tP+ysrL/rq6u/6urq/+oqKj/pKSk/6Ghof+dnZ3/mJiY/5KSkv+MjIz/h4eH/4GB + gf97e3v/b29v/1tbW/9dXV3/YmJi/19fX/9ZWVn/VlZW/15eXv9jY2P/ZWVl/1lZWf87Ozv/R0dH/29v + b/+EhIT/nJyc/5WVlf9QUFD/SkpK/3Jycv+CgoL/aWlp/1FRUf8jIyP/GRkZ/zY2Nv8jIyP/ISEh/yoq + Kv8hISH/HR0d/yIiIv8lJSX/JSUl/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JSUl/yQkJP8hISH/Hx8f/x8fH/8fHx//Hx8f/x8fH/8fHx//Hh4e/x4eHv8eHh7/Hh4e/x4e + Hv8eHh7/ISEh/zMzM/9PT0//W1tb/19fX/9jY2P/ZmZm/2pqav9ubm7/dHR0/3l5ef9/f3//hYWF/4uL + i/+SkpL/l5eX/52dnf+jo6P/qamp/7CwsP+0tLT/urq6/76+vv/Dw8P/xsbG/8jIyDH///8B////Af// + /wH///8B39/f497e3v/d3d3/3Nzc/9vb2//a2tr/2NjY/9fX1//V1dX/09PT/9LS0v/Q0ND/zs7O/8zM + zP/Kysr/yMjI/8fHx//ExMT/wsLC/8DAwP+9vb3/u7u7/7i4uP+1tbX/srKy/6+vr/+rq6v/qKio/6Wl + pf+hoaH/nZ2d/5mZmf+UlJT/jo6O/4iIiP+Dg4P/fHx8/3Nzc/9ZWVn/SkpK/0dHR/9OTk7/WFhY/1ZW + Vv9VVVX/YGBg/2RkZP9nZ2f/Wlpa/zo6Ov9KSkr/fX19/5mZmf+YmJj/YGBg/0ZGRv9oaGj/iYmJ/3t7 + e/+wsLD/hISE/x4eHv8RERH/IiIi/yYmJv8eHh7/IiIi/xwcHP8fHx//IyMj/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yUlJf8iIiL/ISEh/x8f + H/8fHx//Hx8f/x8fH/8fHx//Hx8f/x4eHv8eHh7/Hh4e/x4eHv8eHh7/Hh4e/ykpKf8/Pz//VVVV/11d + Xf9hYWH/ZWVl/2pqav9wcHD/dXV1/3x8fP+CgoL/iYmJ/5CQkP+VlZX/nJyc/6Kiov+pqan/r6+v/7Oz + s/+5ubn/vr6+/8PDw//Hx8f/yMjIMf///wH///8B////Af///wHe3t7j3t7e/9zc3P/b29v/2tra/9jY + 2P/X19f/1dXV/9TU1P/S0tL/0NDQ/8/Pz//MzMz/y8vL/8jIyP/Gxsb/xMTE/8LCwv/AwMD/vb29/7u7 + u/+4uLj/tbW1/7Ozs/+vr6//rKys/6ioqP+lpaX/oaGh/52dnf+ZmZn/lJSU/4+Pj/+JiYn/goKC/319 + ff92dnb/ZWVl/05OTv9ISEj/QEBA/0BAQP9QUFD/U1NT/1paWv9jY2P/Z2dn/2hoaP9VVVX/MDAw/09P + T/+Tk5P/mZmZ/2BgYP9FRUX/aGho/4mJif97e3v/r6+v//f39//q6ur/dHR0/xgYGP8fHx//GBgY/xYW + Fv8ZGRn/Hx8f/yQkJP8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yUlJf8kJCT/ISEh/x4eHv8fHx//Hx8f/x8fH/8fHx//Hx8f/x8f + H/8fHx//Hh4e/x4eHv8eHh7/Hh4e/x8fH/8tLS3/RkZG/1hYWP9gYGD/ZWVl/2xsbP9ycnL/eXl5/4CA + gP+Hh4f/jo6O/5SUlP+bm5v/oaGh/6enp/+tra3/s7Oz/7m5uf++vr7/w8PD/8fHx//IyMgx////Af// + /wH///8B////Ad7e3uPd3d3/3Nzc/9ra2v/Z2dn/19fX/9XV1f/U1NT/09PT/9HR0f/Pz8//zc3N/8vL + y//Jycn/x8fH/8XFxf/Dw8P/wMDA/76+vv+7u7v/uLi4/7a2tv+zs7P/sLCw/62trf+pqan/pqam/6Ki + ov+enp7/mZmZ/5WVlf+QkJD/ioqK/4SEhP99fX3/d3d3/3BwcP9hYWH/UFBQ/0dHR/89PT3/PT09/01N + Tf9UVFT/YGBg/2VlZf9oaGj/ampq/1FRUf8rKyv/SkpK/5CQkP9paWn/RUVF/15eXv+IiIj/f39//6mp + qf/z8/P/+vr6/62trf83Nzf/HR0d/yAgIP8YGBj/Ghoa/x8fH/8lJSX/Jycn/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JSUl/yUl + Jf8kJCT/IiIi/yEhIf8fHx//Hx8f/x8fH/8fHx//Hx8f/x8fH/8fHx//Hx8f/x8fH/8fHx//Hx8f/x8f + H/8kJCT/Nzc3/1RUVP9iYmL/ampq/3BwcP93d3f/fn5+/4WFhf+MjIz/kpKS/5mZmf+goKD/pqam/62t + rf+ysrL/uLi4/76+vv/Dw8P/x8fH/8jIyDH///8B////Af///wH///8B3d3d49zc3P/b29v/2dnZ/9jY + 2P/W1tb/1NTU/9PT0//R0dH/0NDQ/83Nzf/Ly8v/ycnJ/8fHx//FxcX/w8PD/8HBwf++vr7/u7u7/7m5 + uf+2trb/s7Oz/7CwsP+tra3/qqqq/6ampv+ioqL/np6e/5qamv+VlZX/kZGR/4uLi/+FhYX/f39//3d3 + d/9xcXH/a2tr/19fX/9TU1P/RkZG/zo6Ov86Ojr/SkpK/1xcXP9lZWX/Z2dn/2lpaf9sbGz/WVlZ/y8v + L/87Ozv/UlJS/0ZGRv9dXV3/g4OD/4KCgv+ZmZn/8fHx//z8/P+/v7//ODg4/xwcHP8oKCj/JCQk/xwc + HP8fHx//JSUl/ycnJ/8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JSUl/yUlJf8kJCT/IyMj/yEhIf8fHx//Hx8f/x8f + H/8fHx//Hx8f/x8fH/8fHx//Hx8f/x8fH/8fHx//Hx8f/x8fH/8gICD/LCws/0RERP9iYmL/bW1t/3V1 + df97e3v/fHx8/4ODg/+Pj4//mJiY/56env+lpaX/q6ur/7Gxsf+4uLj/vr6+/8PDw//Hx8f/yMjIMf// + /wH///8B////Af///wHc3Nzj29vb/9ra2v/Y2Nj/1tbW/9XV1f/U1NT/0dHR/9DQ0P/Ozs7/zMzM/8rK + yv/IyMj/xcXF/8PDw//AwMD/vr6+/7y8vP+5ubn/tra2/7S0tP+xsbH/ra2t/6qqqv+np6f/o6Oj/5+f + n/+bm5v/lpaW/5GRkf+MjIz/hoaG/4CAgP95eXn/cnJy/2xsbP9mZmb/Xl5e/1VVVf9FRUX/Nzc3/zg4 + OP9ISEj/YWFh/2dnZ/9paWn/bGxs/3Z2dv97e3v/QUFB/zY2Nv8wMDD/SkpK/4KCgv+Ghob/mJiY/+rq + 6v/8/Pz/xsbG/0tLS/8aGhr/JiYm/yYmJv8dHR3/ISEh/yYmJv8nJyf/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JSUl/yUlJf8kJCT/JCQk/yQkJP8hISH/Hx8f/x8fH/8fHx//Hx8f/x8fH/8fHx//Hx8f/x8f + H/8fHx//Hx8f/x8fH/8fHx//ICAg/zg4OP9XV1f/b29v/3Fxcf9dXV3/Y2Nj/3l5ef+RkZH/nZ2d/6Oj + o/+qqqr/sbGx/7i4uP+9vb3/w8PD/8fHx//IyMgx////Af///wH///8B////Adzc3OPa2tr/2dnZ/9fX + 1//V1dX/1NTU/9LS0v/Q0ND/zs7O/8zMzP/Kysr/yMjI/8bGxv/ExMT/wcHB/7+/v/+8vLz/ubm5/7e3 + t/+0tLT/sbGx/66urv+rq6v/qKio/6SkpP+goKD/nJyc/5iYmP+Tk5P/jY2N/4iIiP+BgYH/e3t7/3R0 + dP9ubm7/aGho/2NjY/9dXV3/WFhY/0RERP81NTX/NTU1/0VFRf9iYmL/aWlp/2tra/90dHT/i4uL/5mZ + mf9cXFz/ODg4/y8vL/88PDz/dHR0/4eHh//q6ur//v7+/9jY2P9WVlb/Gxsb/yUlJf8pKSn/Hh4e/x8f + H/8kJCT/Jycn/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JSUl/yUlJf8lJSX/JSUl/yMj + I/8hISH/Hx8f/x8fH/8fHx//Hx8f/x8fH/8fHx//Hx8f/x8fH/8fHx//Hx8f/x8fH/8fHx//ISEh/ykp + Kf9ISEj/VVVV/01NTf9fX1//ZWVl/4ODg/+cnJz/o6Oj/6qqqv+wsLD/uLi4/76+vv/Dw8P/x8fH/8jI + yDH///8B////Af///wH///8B2tra49nZ2f/X19f/1tbW/9TU1P/S0tL/0dHR/8/Pz//Nzc3/y8vL/8nJ + yf/Hx8f/xMTE/8LCwv+/v7//vLy8/7q6uv+3t7f/tbW1/7Gxsf+urq7/q6ur/6enp/+lpaX/oKCg/5yc + nP+Xl5f/kpKS/42Njf+IiIj/goKC/3x8fP92dnb/b29v/2lpaf9kZGT/X19f/1xcXP9bW1v/VFRU/09P + T/88PDz/QEBA/2RkZP9ra2v/dHR0/4yMjP+fn5//g4OD/0xMTP8+Pj7/NjY2/ysrK/89PT3/tra2//z8 + /P/c3Nz/UVFR/xkZGf8lJSX/KCgo/x4eHv8fHx//IyMj/yUlJf8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yUlJf8lJSX/JSUl/yQkJP8iIiL/ISEh/yAgIP8fHx//Hh4e/x8f + H/8gICD/ICAg/yAgIP8gICD/ICAg/yAgIP8gICD/ICAg/yAgIP8oKCj/Ojo6/2BgYP9oaGj/f39//5ub + m/+jo6P/q6ur/7Gxsf+5ubn/vr6+/8TExP/Hx8f/yMjIMf///wH///8B////Af///wHa2trj2NjY/9bW + 1v/V1dX/09PT/9HR0f/Pz8//zs7O/8vLy//Jycn/x8fH/8XFxf/Dw8P/wMDA/729vf+6urr/uLi4/7W1 + tf+ysrL/r6+v/6urq/+oqKj/paWl/6Ghof+dnZ3/mZmZ/5OTk/+Ojo7/iYmJ/4ODg/99fX3/c3Nz/2tr + a/9qamr/ZWVl/2BgYP9cXFz/W1tb/15eXv9hYWH/YWFh/zs7O/8zMzP/ZGRk/3Fxcf+Ghob/n5+f/5GR + kf9NTU3/SkpK/2BgYP9DQ0P/NDQ0/ykpKf9LS0v/n5+f/2pqav8cHBz/IiIi/ykpKf8fHx//Gxsb/yEh + If8kJCT/JSUl/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/IyMj/yAgIP8eHh7/Hh4e/yAgIP8gICD/ICAg/yAgIP8gICD/ICAg/yAg + IP8gICD/ICAg/yAgIP8kJCT/Pj4+/2JiYv+BgYH/nJyc/6Ojo/+rq6v/srKy/7m5uf+/v7//xMTE/8fH + x//IyMgx////Af///wH///8B////AdjY2OPX19f/1dXV/9PT0//S0tL/0NDQ/87Ozv/MzMz/ysrK/8jI + yP/Gxsb/w8PD/8HBwf++vr7/u7u7/7i4uP+2trb/srKy/6+vr/+srKz/qKio/6Wlpf+hoaH/np6e/5mZ + mf+UlJT/jo6O/4mJif+EhIT/fX19/3Nzc/9WVlb/TU1N/1ZWVv9fX1//XFxc/1hYWP9bW1v/YWFh/2Rk + ZP9iYmL/OTk5/zIyMv9sbGz/hISE/5ycnP+QkJD/U1NT/0pKSv9ubm7/hoaG/21tbf9SUlL/GRkZ/xIS + Ev8gICD/IyMj/yEhIf8pKSn/IiIi/x8fH/8gICD/IyMj/yUlJf8lJSX/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8lJSX/IyMj/yEh + If8fHx//ICAg/yAgIP8gICD/ICAg/yAgIP8gICD/ICAg/yAgIP8gICD/ICAg/yAgIP8iIiL/R0dH/4KC + gv+cnJz/pKSk/6ysrP+ysrL/urq6/8DAwP/FxcX/yMjI/8jIyDH///8B////Af///wH///8B19fX49bW + 1v/U1NT/0tLS/9DQ0P/Pz8//zc3N/8vLy//IyMj/xsbG/8PDw//CwsL/v7+//7y8vP+5ubn/tra2/7Oz + s/+wsLD/ra2t/6mpqf+mpqb/oqKi/56env+ZmZn/lJSU/5CQkP+Kior/hISE/35+fv91dXX/XFxc/0tL + S/9ERET/QEBA/09PT/9ZWVn/WFhY/15eXv9jY2P/ZWVl/2JiYv8zMzP/MDAw/319ff+ampr/kpKS/1dX + V/9GRkb/a2tr/4uLi/9+fn7/vb29/8rKyv9NTU3/FRUV/xwcHP8dHR3/GBgY/x0dHf8dHR3/ISEh/yMj + I/8kJCT/JSUl/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yUlJf8lJSX/JSUl/yMjI/8iIiL/ISEh/yAgIP8gICD/ICAg/yAg + IP8gICD/ICAg/yAgIP8gICD/ICAg/yEhIf9ERET/hYWF/52dnf+lpaX/rKys/7Ozs/+7u7v/wcHB/8XF + xf/IyMj/ycnJMf///wH///8B////Af///wHW1tbj1dXV/9TU1P/R0dH/z8/P/83Nzf/Ly8v/ycnJ/8fH + x//FxcX/wsLC/7+/v/+8vLz/urq6/7e3t/+0tLT/sbGx/62trf+qqqr/pqam/6Kiov+enp7/mpqa/5aW + lv+QkJD/i4uL/4WFhf9+fn7/eXl5/25ubv9UVFT/TExM/0BAQP88PDz/SUlJ/1ZWVv9bW1v/YmJi/2Vl + Zf9nZ2f/YmJi/ywsLP8sLCz/ioqK/5ycnP9eXl7/RERE/2NjY/+IiIj/enp6/7S0tP/4+Pj/8fHx/39/ + f/8gICD/GRkZ/xUVFf8VFRX/Ghoa/yAgIP8jIyP/JCQk/yUlJf8lJSX/JSUl/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8lJSX/JSUl/yQkJP8jIyP/ISEh/yAgIP8gICD/ICAg/yAgIP8hISH/ISEh/yEhIf8hISH/ISEh/0BA + QP+FhYX/np6e/6enp/+vr6//tra2/76+vv/CwsL/xsbG/8nJyf/Kysox////Af///wH///8B////AdbW + 1uPU1NT/0tLS/9DQ0P/Ozs7/zMzM/8rKyv/Hx8f/xcXF/8PDw//AwMD/vb29/7q6uv+3t7f/tLS0/7Gx + sf+urq7/qqqq/6enp/+jo6P/n5+f/5ubm/+VlZX/kZGR/4uLi/+FhYX/f39//3l5ef90dHT/aWlp/1VV + Vf9NTU3/PT09/zg4OP9GRkb/VVVV/2FhYf9lZWX/aGho/2lpaf9mZmb/LS0t/yUlJf9oaGj/ZmZm/0RE + RP9iYmL/hoaG/319ff+pqan/+vr6//f39/+cnJz/Jycn/xwcHP8kJCT/Ghoa/xsbG/8gICD/IyMj/yQk + JP8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JSUl/yUlJf8kJCT/IiIi/yAg + IP8fHx//Hx8f/yAgIP8hISH/ISEh/yEhIf8hISH/Nzc3/319ff+Xl5f/pqam/7Ozs/+6urr/wMDA/8TE + xP/Hx8f/ysrK/8vLyzH///8B////Af///wH///8B1dXV49PT0//R0dH/z8/P/8zMzP/Kysr/yMjI/8bG + xv/Dw8P/wcHB/76+vv+8vLz/uLi4/7W1tf+ysrL/r6+v/6ysrP+oqKj/pKSk/6CgoP+bm5v/l5eX/5KS + kv+NjY3/hoaG/4GBgf96enr/dXV1/3BwcP9nZ2f/V1dX/05OTv85OTn/NTU1/0NDQ/9XV1f/ZWVl/2dn + Z/9paWn/bGxs/29vb/8zMzP/JSUl/zQ0NP9AQED/Wlpa/4ODg/98fHz/nZ2d/+/v7//7+/v/t7e3/zc3 + N/8cHBz/KCgo/yUlJf8eHh7/ICAg/yMjI/8kJCT/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8kJCT/IiIi/yAgIP8fHx//ICAg/yEhIf8hISH/ISEh/yEh + If8vLy//enp6/42Njf+cnJz/tra2/729vf/BwcH/xMTE/8fHx//Kysr/y8vLMf///wH///8B////Af// + /wHU1NTj0tLS/9DQ0P/Nzc3/y8vL/8nJyf/Gxsb/xMTE/8HBwf+/v7//vLy8/7m5uf+1tbX/srKy/6+v + r/+srKz/qKio/6Wlpf+goKD/m5ub/5aWlv+SkpL/jY2N/4iIiP+BgYH/e3t7/3Z2dv9wcHD/a2tr/2Rk + ZP9ZWVn/UFBQ/zc3N/8yMjL/QUFB/1paWv9oaGj/aWlp/21tbf94eHj/jo6O/11dXf8oKCj/Jycn/zg4 + OP93d3f/gICA/5qamv/19fX//v7+/7m5uf86Ojr/Ghoa/ygoKP8mJib/HR0d/yAgIP8jIyP/JCQk/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yUl + Jf8kJCT/IyMj/yMjI/8hISH/ICAg/x8fH/8gICD/ISEh/ysrK/95eXn/jY2N/5ubm/+6urr/v7+//8PD + w//Gxsb/ycnJ/8zMzP/MzMwx////Af///wH///8B////AdPT0+PR0dH/z8/P/8zMzP/Kysr/x8fH/8XF + xf/Dw8P/wMDA/729vf+6urr/tra2/7Ozs/+wsLD/ra2t/6mpqf+mpqb/oaGh/52dnf+Xl5f/k5OT/46O + jv+JiYn/hISE/319ff93d3f/cnJy/2xsbP9nZ2f/YWFh/1tbW/9RUVH/Pj4+/zc3N/89PT3/W1tb/2lp + af9ra2v/d3d3/42Njf+goKD/bGxs/y4uLv8mJib/KSkp/01NTf+Li4v/5ubm//7+/v/a2tr/RUVF/xoa + Gv8lJSX/KCgo/x8fH/8fHx//IiIi/yQkJP8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yUlJf8lJSX/JiYm/yUlJf8hISH/Hh4e/x8f + H/8hISH/LCws/3p6ev+Ojo7/nZ2d/729vf/BwcH/xMTE/8bGxv/Jycn/zMzM/83NzTH///8B////Af// + /wH///8B0tLS49DQ0P/Ozs7/y8vL/8nJyf/Gxsb/xMTE/8HBwf++vr7/u7u7/7i4uP+0tLT/sbGx/62t + rf+qqqr/pqam/6Kiov+dnZ3/mZmZ/5SUlP+Pj4//ioqK/4WFhf9/f3//dnZ2/3Jycv9tbW3/aGho/2Rk + ZP9eXl7/XV1d/15eXv9eXl7/R0dH/zQ0NP9WVlb/bGxs/3R0dP+NjY3/oKCg/4CAgP9GRkb/Pj4+/ysr + K/8mJib/LCws/3Fxcf/b29v/0dHR/1hYWP8bGxv/JCQk/ykpKf8hISH/Hx8f/yMjI/8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yQkJP8iIiL/Hx8f/x8fH/8pKSn/d3d3/5CQkP+dnZ3/vr6+/8LC + wv/FxcX/yMjI/8vLy//Nzc3/zs7OMf///wH///8B////Af///wHR0dHjz8/P/8zMzP/Kysr/yMjI/8bG + xv/Dw8P/v7+//7y8vP+5ubn/tra2/7Kysv+vr6//q6ur/6enp/+jo6P/n5+f/5mZmf+VlZX/kJCQ/4qK + iv+FhYX/gICA/3Nzc/9cXFz/YmJi/2dnZ/9kZGT/YGBg/1xcXP9fX1//YmJi/2VlZf9ISEj/Kysr/1JS + Uv9zc3P/h4eH/56env+FhYX/S0tL/0xMTP9wcHD/VVVV/yoqKv8gICD/Ghoa/09PT/9nZ2f/ISEh/yMj + I/8oKCj/ICAg/yEhIf8kJCT/Jycn/yYmJv8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8kJCT/IiIi/y0tLf97e3v/kZGR/56env+/v7//xMTE/8fHx//Jycn/zMzM/87Ozv/Pz88x////Af// + /wH///8B////Ac/Pz+POzs7/y8vL/8nJyf/Gxsb/xMTE/8HBwf++vr7/urq6/7e3t/+0tLT/sLCw/6ys + rP+oqKj/pKSk/6CgoP+cnJz/lpaW/5GRkf+MjIz/hoaG/4GBgf91dXX/W1tb/0tLS/9KSkr/UlJS/15e + Xv9cXFz/XFxc/2FhYf9lZWX/Z2dn/0VFRf8pKSn/VlZW/4aGhv+dnZ3/kJCQ/1BQUP9GRkb/bm5u/4iI + iP91dXX/dHR0/yAgIP8LCwv/KSkp/2tra/8pKSn/JSUl/yAgIP8fHx//JCQk/ycnJ/8mJib/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yUlJf8rKyv/WVlZ/42Njf+SkpL/np6e/8DA + wP/FxcX/yMjI/8vLy//Nzc3/z8/P/9DQ0DH///8B////Af///wH///8Bzs7O48zMzP/Kysr/x8fH/8XF + xf/CwsL/v7+//7u7u/+4uLj/tbW1/7Gxsf+urq7/qamp/6Wlpf+hoaH/nJyc/5iYmP+RkZH/jY2N/4aG + hv+AgID/enp6/2RkZP9PT0//SEhI/0NDQ/9ERET/V1dX/1lZWf9gYGD/ZWVl/2dnZ/9paWn/QUFB/yYm + Jv9jY2P/np6e/5OTk/9TU1P/RUVF/2tra/+IiIj/dnZ2/87Ozv/4+Pj/nJyc/x8fH/8eHh7/IiIi/xMT + E/8YGBj/Hh4e/yMjI/8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8lJSX/JiYm/0lJSf+EhIT/k5OT/5OTk/+kpKT/w8PD/8bGxv/Kysr/y8vL/87Ozv/Q0ND/0dHRMf// + /wH///8B////Af///wHNzc3jy8vL/8nJyf/Gxsb/xMTE/8DAwP+9vb3/urq6/7a2tv+zs7P/rq6u/6ur + q/+np6f/oqKi/56env+ZmZn/lJSU/42Njf+IiIj/gICA/3p6ev90dHT/YGBg/1FRUf9GRkb/Pz8//0JC + Qv9VVVX/Wlpa/2RkZP9mZmb/aWlp/2tra/89PT3/Hx8f/1tbW/+ampr/Xl5e/0JCQv9jY2P/hoaG/3p6 + ev+zs7P//Pz8//b29v+NjY3/Hx8f/x0dHf8VFRX/FBQU/x0dHf8gICD/IyMj/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JSUl/yQkJP8kJCT/Hx8f/zg4OP9+fn7/mZmZ/7W1 + tf/Gxsb/yMjI/8vLy//Nzc3/z8/P/9HR0f/S0tIx////Af///wH///8B////AczMzOPKysr/yMjI/8XF + xf/CwsL/vr6+/7u7u/+3t7f/s7Oz/7CwsP+srKz/qKio/6Ojo/+enp7/mZmZ/5SUlP+Pj4//iIiI/4KC + gv96enr/dHR0/25ubv9dXV3/VVVV/0RERP88PDz/Pj4+/1RUVP9gYGD/Z2dn/2lpaf9ra2v/bm5u/0FB + Qf8eHh7/MzMz/1VVVf9BQUH/Y2Nj/4WFhf95eXn/s7Oz//f39//z8/P/lJSU/yIiIv8cHBz/Jycn/x4e + Hv8bGxv/ICAg/yEhIf8kJCT/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yUl + Jf8jIyP/ISEh/w8PD/8CAgL/JSUl/4mJif+xsbH/w8PD/8fHx//Jycn/y8vL/83Nzf/Q0ND/0tLS/9LS + 0jH///8B////Af///wH///8BzMzM48nJyf/Gxsb/w8PD/8DAwP+8vLz/ubm5/7W1tf+xsbH/ra2t/6mp + qf+lpaX/oKCg/5ubm/+VlZX/kJCQ/4qKiv+Dg4P/fX19/3Z2dv9wcHD/a2tr/15eXv9YWFj/Q0ND/zg4 + OP88PDz/VFRU/2RkZP9paWn/a2tr/25ubv97e3v/Xl5e/x8fH/8hISH/NjY2/1hYWP+Dg4P/fHx8/6Gh + of/19fX//v7+/6enp/8wMDD/Ghoa/yYmJv8jIyP/Gxsb/x0dHf8hISH/IyMj/yQkJP8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8lJSX/JCQk/yMjI/8RERH/AwMD/yUlJf9vb2//r6+v/8HB + wf/FxcX/x8fH/8rKyv/MzMz/zs7O/9DQ0P/S0tL/09PTMf///wH///8B////Af///wHLy8vjyMjI/8bG + xv/CwsL/v7+//7u7u/+3t7f/s7Oz/66urv+qqqr/pqam/6Kiov+cnJz/lpaW/5GRkf+Li4v/hYWF/35+ + fv94eHj/cnJy/21tbf9paWn/X19f/1tbW/9CQkL/Nzc3/zk5Of9TU1P/ZmZm/2tra/9ubm7/e3t7/5OT + k/+Hh4f/LCws/x8fH/8wMDD/YWFh/4GBgf+cnJz/7e3t//r6+v++vr7/MTEx/xoaGv8mJib/JSUl/x4e + Hv8fHx//ISEh/yQkJP8kJCT/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8kJCT/JCQk/yQkJP8kJCT/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JSUl/yQk + JP8nJyf/FxcX/wMDA/8eHh7/e3t7/6Ghof+/v7//xMTE/8bGxv/IyMj/ysrK/83Nzf/Pz8//0dHR/9PT + 0//U1NQx////Af///wH///8B////AcrKyuPHx8f/xMTE/8DAwP+9vb3/ubm5/7W1tf+xsbH/rKys/6io + qP+ioqL/np6e/5iYmP+SkpL/jIyM/4aGhv+AgID/eHh4/3Nzc/9ubm7/ampq/2VlZf9fX1//Xl5e/1BQ + UP9JSUn/Nzc3/1BQUP9oaGj/bW1t/3h4eP+SkpL/oKCg/3R0dP8xMTH/Hx8f/yIiIv8zMzP/bGxs/+Xl + 5f/8/Pz/vLy8/0FBQf8ZGRn/JSUl/yQkJP8fHx//ICAg/yIiIv8kJCT/JCQk/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8lJSX/IyMj/xcXF/8DAwP/Hh4e/29vb/+kpKT/vb29/8LC + wv/ExMT/x8fH/8nJyf/Ly8v/zs7O/9DQ0P/S0tL/1NTU/9XV1TH///8B////Af///wH///8ByMjI48bG + xv/Dw8P/v7+//7y8vP+3t7f/s7Oz/6+vr/+qqqr/pqam/6CgoP+bm5v/lJSU/46Ojv+IiIj/goKC/3V1 + df9ubm7/b29v/2xsbP9nZ2f/YmJi/19fX/9hYWH/Y2Nj/1lZWf8yMjL/Q0ND/2hoaP92dnb/jIyM/5+f + n/+AgID/RkZG/0RERP84ODj/HR0d/yEhIf83Nzf/kJCQ/8XFxf9MTEz/GRkZ/yQkJP8lJSX/HR0d/x8f + H/8iIiL/JCQk/yQkJP8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8lJSX/JSUl/ycn + J/8XFxf/BAQE/xEREf9mZmb/np6e/7u7u//CwsL/xMTE/8bGxv/IyMj/y8vL/83Nzf/Pz8//0dHR/9PT + 0//V1dX/1tbWMf///wH///8B////Af///wHIyMjjxMTE/8HBwf+9vb3/urq6/7W1tf+xsbH/rKys/6en + p/+ioqL/m5ub/5aWlv+QkJD/ioqK/4ODg/90dHT/WFhY/09PT/9ZWVn/ZGRk/2RkZP9hYWH/YWFh/2Rk + ZP9nZ2f/W1tb/y4uLv88PDz/b29v/42Njf+hoaH/g4OD/0ZGRv9MTEz/dnZ2/3t7e/9BQUH/ISEh/w8P + D/8UFBT/QEBA/yEhIf8gICD/JiYm/x0dHf8fHx//IiIi/yQkJP8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yUlJf8uLi7/QUFB/y0tLf8hISH/aWlp/6SkpP+7u7v/wcHB/8PD + w//FxcX/x8fH/8rKyv/MzMz/zs7O/9DQ0P/S0tL/1NTU/9bW1v/X19cx////Af///wH///8B////AcbG + xuPExMT/wMDA/729vf+4uLj/s7Oz/6+vr/+pqan/pKSk/5+fn/+ZmZn/kpKS/4uLi/+FhYX/fHx8/2Fh + Yf9PT0//SEhI/0ZGRv9WVlb/YmJi/2BgYP9kZGT/ZmZm/2lpaf9aWlr/Kioq/0NDQ/+CgoL/oKCg/5GR + kf9KSkr/RkZG/29vb/+Ghob/e3t7/8DAwP95eXn/ExMT/xQUFP84ODj/ISEh/xwcHP8eHh7/Hh4e/yIi + Iv8kJCT/JSUl/yUlJf8lJSX/JSUl/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8lJSX/Kioq/0RE + RP9WVlb/e3t7/4KCgv+vr6//u7u7/8DAwP/CwsL/xMTE/8bGxv/IyMj/y8vL/83Nzf/Pz8//0dHR/9PT + 0//V1dX/19fX/9jY2DH///8B////Af///wH///8BxsbG48PDw/+/v7//u7u7/7e3t/+xsbH/rKys/6am + pv+hoaH/nJyc/5WVlf+Ojo7/hoaG/4CAgP92dnb/WVlZ/1FRUf9FRUX/QkJC/1JSUv9gYGD/YmJi/2dn + Z/9paWn/a2tr/1ZWVv8lJSX/RkZG/5WVlf+RkZH/UlJS/0ZGRv9qamr/hYWF/319ff/Kysr//f39/9/f + 3/9CQkL/HBwc/xsbG/8SEhL/FhYW/xwcHP8iIiL/JSUl/yUlJf8lJSX/JSUl/yQkJP8kJCT/JCQk/yQk + JP8jIyP/IyMj/yQkJP8nJyf/Kysr/zAwMP80NDT/NDQ0/zIyMv8uLi7/KSkp/yYmJv8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JSUl/yUlJf8qKir/PT09/1JSUv+IiIj/np6e/7u7u/+/v7//wcHB/8PD + w//FxcX/yMjI/8rKyv/MzMz/zs7O/9DQ0P/S0tL/1NTU/9bW1v/Y2Nj/2dnZMf///wH///8B////Af// + /wHFxcXjwsLC/729vf+5ubn/tbW1/6+vr/+qqqr/pKSk/5+fn/+ZmZn/kZGR/4qKiv+CgoL/e3t7/3Nz + c/9bW1v/U1NT/0FBQf8/Pz//UVFR/2BgYP9mZmb/aWlp/2tra/9tbW3/WFhY/yMjI/81NTX/f39//1ZW + Vv9BQUH/ZmZm/4aGhv96enr/u7u7//n5+f/s7Oz/gICA/xwcHP8fHx//Gxsb/xQUFP8aGhr/ISEh/yYm + Jv8lJSX/JCQk/yQkJP8kJCT/JCQk/yMjI/8jIyP/IyMj/ygoKP85OTn/WVlZ/3Fxcf+EhIT/lZWV/52d + nf+dnZ3/mJiY/46Ojv9+fn7/ampq/09PT/85OTn/JiYm/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yUlJf8jIyP/Hh4e/wsL + C/8UFBT/WVlZ/5aWlv+zs7P/vr6+/8DAwP/Dw8P/xcXF/8fHx//Jycn/y8vL/83Nzf/Pz8//0dHR/9PT + 0//V1dX/19fX/9nZ2f/a2tox////Af///wH///8B////AcTExOPBwcH/vb29/7i4uP+0tLT/rq6u/6io + qP+ioqL/nJyc/5aWlv+Ojo7/hoaG/319ff93d3f/b29v/1xcXP9UVFT/PT09/zs7O/9PT0//Y2Nj/2lp + af9sbGz/bm5u/3Jycv9kZGT/JCQk/yEhIf86Ojr/QEBA/11dXf+FhYX/fn5+/7CwsP/5+fn/9vb2/4eH + h/8kJCT/HBwc/yYmJv8hISH/HR0d/yEhIf8mJib/JiYm/yUlJf8kJCT/IyMj/yMjI/8jIyP/JiYm/zIy + Mv9fX1//jY2N/6ysrP++vr7/xcXF/8nJyf/Ly8v/y8vL/8vLy//Ly8v/y8vL/8nJyf/FxcX/vb29/6ur + q/99fX3/VFRU/zExMf8mJib/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yUlJf8lJSX/IyMj/yMjI/8LCwv/BgYG/0FBQf+Li4v/srKy/729vf/AwMD/wsLC/8TE + xP/Gxsb/yMjI/8vLy//Nzc3/zs7O/9DQ0P/S0tL/1dXV/9bW1v/Y2Nj/2tra/9ra2jH///8B////Af// + /wH///8BxMTE48DAwP+8vLz/t7e3/7Kysv+srKz/p6en/6Ghof+ampr/k5OT/4uLi/+Dg4P/enp6/3R0 + dP9tbW3/X19f/1VVVf86Ojr/ODg4/09PT/9lZWX/bGxs/25ubv9ycnL/goKC/4eHh/8yMjL/Hh4e/ysr + K/9OTk7/gICA/39/f/+qqqr/9vb2//Pz8/+ampr/Hh4e/xoaGv8lJSX/IiIi/x4eHv8iIiL/JiYm/yYm + Jv8lJSX/JCQk/yMjI/8jIyP/IyMj/zAwMP9nZ2f/o6Oj/8XFxf/Ly8v/y8vL/8vLy//Ly8v/y8vL/8vL + y//Ly8v/zMzM/8zMzP/MzMz/zc3N/83Nzf/Nzc3/zc3N/83Nzf/FxcX/m5ub/11dXf8uLi7/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yYmJv8mJib/JiYm/yYmJv8mJib/JSUl/yYmJv8jIyP/CwsL/wYG + Bv85OTn/kJCQ/7Kysv+9vb3/wMDA/8LCwv/ExMT/xsbG/8jIyP/Kysr/zMzM/87Ozv/Q0ND/0tLS/9TU + 1P/V1dX/19fX/9nZ2f/a2tr/29vbMf///wH///8B////Af///wHExMTjwMDA/7u7u/+2trb/sbGx/6ur + q/+mpqb/oKCg/5mZmf+SkpL/iYmJ/4GBgf95eXn/dHR0/25ubv9iYmL/VlZW/0JCQv88PDz/T09P/2dn + Z/9vb2//cXFx/319ff+Xl5f/oaGh/0tLS/8dHR3/IyMj/0BAQP9lZWX/nJyc//Dw8P/6+vr/rKys/zMz + M/8YGBj/JSUl/yEhIf8cHBz/ISEh/yYmJv8mJib/JSUl/yQkJP8jIyP/IyMj/yMjI/9AQED/jY2N/8DA + wP/MzMz/zMzM/8vLy//Ly8v/y8vL/8vLy//Ly8v/y8vL/8vLy//MzMz/zMzM/8zMzP/MzMz/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Ly8v/vLy8/4GBgf89PT3/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8mJib/JiYm/yUlJf8kJCT/Kysr/xISEv8CAgL/Ly8v/4WFhf+tra3/vLy8/7+/v//BwcH/w8PD/8bG + xv/Hx8f/ysrK/8vLy//Nzc3/z8/P/9HR0f/T09P/1dXV/9fX1//Y2Nj/2tra/9vb2//c3Nwx////Af// + /wH///8B////AcPDw+O/v7//u7u7/7W1tf+wsLD/qqqq/6Wlpf+enp7/l5eX/4yMjP+Hh4f/gYGB/3l5 + ef91dXX/b29v/2ZmZv9nZ2f/Z2dn/0lJSf9BQUH/ZWVl/3Jycv9/f3//lZWV/6Kiov91dXX/Ozs7/yws + LP8dHR3/JSUl/zg4OP+rq6v/7+/v/66urv8uLi7/GBgY/yUlJf8jIyP/HBwc/yAgIP8lJSX/JiYm/yUl + Jf8kJCT/IyMj/yMjI/8qKir/XV1d/7W1tf/Nzc3/zc3N/83Nzf/MzMz/zMzM/8vLy//Ly8v/y8vL/8vL + y//Ly8v/y8vL/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/Ly8v/ysrK/7Cw + sP9nZ2f/KSkp/yMjI/8jIyP/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/ycnJ/8PDw//AQEB/zIy + Mv+Hh4f/rKys/729vf+/v7//wcHB/8PDw//FxcX/x8fH/8nJyf/Ly8v/zMzM/8/Pz//Q0ND/0tLS/9TU + 1P/W1tb/19fX/9nZ2f/b29v/3Nzc/93d3TH///8B////Af///wH///8Bw8PD48DAwP+7u7v/tbW1/7Cw + sP+pqan/pKSk/52dnf+Li4v/bW1t/3Nzc/99fX3/e3t7/3h4eP9xcXH/aGho/2pqav9paWn/RUVF/zU1 + Nf9gYGD/e3t7/5OTk/+jo6P/fn5+/0VFRf9MTEz/ZGRk/zY2Nv8aGhr/HBwc/y4uLv9ycnL/Q0ND/xYW + Fv8iIiL/IyMj/xwcHP8fHx//IyMj/yUlJf8lJSX/JCQk/yQkJP8jIyP/KCgo/2lpaf+1tbX/zMzM/8zM + zP/Nzc3/zMzM/8zMzP/MzMz/zMzM/8vLy//Ly8v/y8vL/8vLy//Ly8v/zMzM/8zMzP/MzMz/zMzM/8zM + zP/MzMz/zMzM/8zMzP/Ly8v/y8vL/8vLy//Kysr/ysrK/7u7u/9mZmb/Kioq/yMjI/8jIyP/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yQkJP8pKSn/FxcX/wEBAf8dHR3/fX19/6ioqP+6urr/vr6+/8DAwP/Dw8P/xcXF/8bG + xv/Jycn/y8vL/8zMzP/Ozs7/0NDQ/9LS0v/T09P/1dXV/9fX1//Y2Nj/2tra/9vb2//d3d3/3d3dMf// + /wH///8B////Af///wHDw8Pjv7+//7q6uv+0tLT/r6+v/6mpqf+jo6P/lJSU/21tbf9aWlr/VVVV/19f + X/94eHj/eXl5/3Jycv9sbGz/bm5u/2xsbP9ERET/MzMz/2pqav+Pj4//oqKi/4aGhv9BQUH/SUlJ/3R0 + dP+BgYH/b29v/1BQUP8VFRX/DQ0N/zs7O/9DQ0P/HR0d/yQkJP8bGxv/HR0d/yIiIv8kJCT/JCQk/yQk + JP8kJCT/IyMj/yUlJf9kZGT/u7u7/8rKyv/Ly8v/y8vL/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zM + zP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/Ly8v/y8vL/8vLy//Kysr/ysrK/8rK + yv/Kysr/ycnJ/7W1tf9dXV3/JSUl/yMjI/8jIyP/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yQkJP8lJSX/MzMz/0tLS/9TU1P/SUlJ/4GB + gf+rq6v/urq6/76+vv/AwMD/wsLC/8TExP/Gxsb/yMjI/8rKyv/MzMz/zs7O/8/Pz//R0dH/09PT/9XV + 1f/W1tb/19fX/9nZ2f/a2tr/3Nzc/93d3f/e3t4x////Af///wH///8B////AcPDw+O/v7//urq6/7W1 + tf+vr6//qamp/6Ojo/+Hh4f/Y2Nj/1dXV/9NTU3/UlJS/3h4eP96enr/cXFx/3BwcP9xcXH/bm5u/z8/ + P/8xMTH/eXl5/6Ghof+Hh4f/SkpK/0ZGRv9ubm7/g4OD/4KCgv/R0dH/3d3d/2hoaP8SEhL/IyMj/x0d + Hf8UFBT/GBgY/xwcHP8gICD/IiIi/yQkJP8kJCT/JCQk/yQkJP8jIyP/Q0ND/6+vr//Kysr/ysrK/8vL + y//Ly8v/y8vL/8zMzP/MzMz/zMzM/8zMzP/Nzc3/zc3N/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zM + zP/MzMz/y8vL/8vLy//Ly8v/y8vL/8rKyv/Kysr/ysrK/8rKyv/Kysr/ycnJ/7Gxsf9DQ0P/IyMj/yMj + I/8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/y0tLf9ERET/U1NT/3Nzc/+Kior/rq6u/7u7u/+9vb3/v7+//8LCwv/ExMT/xsbG/8jI + yP/Kysr/y8vL/83Nzf/Pz8//0dHR/9LS0v/U1NT/1dXV/9fX1//Y2Nj/2tra/9vb2//d3d3/3t7e/9/f + 3zH///8B////Af///wH///8BxMTE48DAwP+7u7v/tra2/7CwsP+pqan/o6Oj/4WFhf9nZ2f/VVVV/0hI + SP9PT0//enp6/3l5ef9zc3P/c3Nz/3R0dP9ubm7/Ozs7/ywsLP95eXn/k5OT/01NTf9CQkL/bGxs/4eH + h/97e3v/ycnJ//v7+//d3d3/X19f/xcXF/8YGBj/EhIS/xYWFv8bGxv/ICAg/yIiIv8jIyP/JCQk/yQk + JP8kJCT/JCQk/zAwMP+Hh4f/yMjI/8vLy//Ly8v/y8vL/8vLy//Ly8v/zMzM/8zMzP/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zMzM/8zMzP/MzMz/zMzM/8zMzP/Ly8v/y8vL/8vLy//Ly8v/ysrK/8rK + yv/Kysr/ysrK/8rKyv/Kysr/ycnJ/4qKiv8uLi7/IyMj/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yUlJf8lJSX/JSUl/yUlJf8lJSX/JCQk/yMjI/8mJib/HR0d/x8fH/9FRUX/enp6/56e + nv+3t7f/vb29/7+/v//BwcH/w8PD/8XFxf/Hx8f/ycnJ/8vLy//Nzc3/zs7O/9DQ0P/S0tL/1NTU/9XV + 1f/W1tb/2NjY/9nZ2f/b29v/3Nzc/93d3f/f39//39/fMf///wH///8B////Af///wHExMTjwcHB/7y8 + vP+2trb/sbGx/6mpqf+jo6P/iIiI/2tra/9TU1P/RERE/0xMTP95eXn/d3d3/3V1df92dnb/d3d3/3Nz + c/8+Pj7/JCQk/0xMTP9RUVH/QUFB/2VlZf+Hh4f/eXl5/8fHx//+/v7/6Ojo/2RkZP8aGhr/Hh4e/yQk + JP8bGxv/HBwc/yEhIf8jIyP/IyMj/yQkJP8kJCT/JCQk/yQkJP8kJCT/XFxc/76+vv/MzMz/zMzM/8zM + zP/MzMz/zMzM/8zMzP/MzMz/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/8zM + zP/MzMz/zMzM/8vLy//Ly8v/y8vL/8vLy//Kysr/ysrK/8rKyv/Kysr/ysrK/8vLy//Ly8v/vLy8/1dX + V/8lJSX/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JSUl/yUlJf8lJSX/JSUl/yQk + JP8jIyP/IiIi/xkZGf8EBAT/ExMT/21tbf+goKD/uLi4/7y8vP++vr7/wcHB/8PDw//FxcX/x8fH/8nJ + yf/Kysr/zc3N/87Ozv/Q0ND/0dHR/9PT0//V1dX/1tbW/9jY2P/Z2dn/2tra/9vb2//d3d3/3t7e/9/f + 3//g4OAx////Af///wH///8B////AcTExOPBwcH/vb29/7i4uP+ysrL/q6ur/6SkpP+Hh4f/bm5u/1BQ + UP9CQkL/TU1N/3t7e/93d3f/eHh4/3h4eP97e3v/g4OD/01NTf8iIiL/MDAw/0RERP9gYGD/hYWF/3V1 + df+vr6//+Pj4//Hx8f+IiIj/Hh4e/xwcHP8lJSX/Hx8f/x0dHf8gICD/IiIi/yMjI/8kJCT/JCQk/yQk + JP8kJCT/JCQk/yUlJf+SkpL/zMzM/83Nzf/Nzc3/zc3N/8zMzP/MzMz/zMzM/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zs7O/87Ozv/Ozs7/zc3N/83Nzf/Nzc3/zc3N/8zMzP/MzMz/zMzM/8vLy//Ly8v/y8vL/8vL + y//Ly8v/y8vL/8vLy//Ly8v/y8vL/8zMzP/Jycn/hoaG/ywsLP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8lJSX/JSUl/yUlJf8lJSX/JCQk/yMjI/8bGxv/BAQE/wcHB/9RUVH/mZmZ/7S0 + tP+8vLz/vr6+/8DAwP/Dw8P/xcXF/8fHx//IyMj/ysrK/8zMzP/Ozs7/0NDQ/9HR0f/T09P/1NTU/9bW + 1v/X19f/2NjY/9ra2v/b29v/3d3d/97e3v/f39//4ODg/+Hh4TH///8B////Af///wH///8BxMTE48LC + wv++vr7/uLi4/7Ozs/+tra3/pqam/4iIiP9xcXH/T09P/0JCQv9LS0v/e3t7/3p6ev96enr/fX19/4iI + iP+enp7/eXl5/yUlJf8sLCz/Wlpa/3x8fP92dnb/srKy//j4+P/w8PD/ioqK/yIiIv8bGxv/JSUl/x8f + H/8cHBz/ICAg/yIiIv8jIyP/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/MjIy/7q6uv/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/87Ozv/Ozs7/zs7O/87Ozv/Ozs7/zc3N/83N + zf/Nzc3/zc3N/8zMzP/MzMz/y8vL/8vLy//Ly8v/y8vL/8vLy//Ly8v/y8vL/8zMzP/MzMz/zMzM/83N + zf+urq7/OTk5/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JSUl/yUlJf8lJSX/JSUl/yQk + JP8iIiL/Gxsb/wYGBv8ODg7/UVFR/5mZmf+1tbX/u7u7/76+vv/AwMD/wsLC/8TExP/Hx8f/ycnJ/8rK + yv/MzMz/zs7O/9DQ0P/R0dH/09PT/9TU1P/V1dX/2NjY/9nZ2f/a2tr/29vb/9zc3P/e3t7/39/f/+Dg + 4P/h4eH/4eHhMf///wH///8B////Af///wHExMTjwsLC/76+vv+6urr/tbW1/66urv+oqKj/ioqK/3d3 + d/9oaGj/Xl5e/05OTv94eHj/fX19/35+fv+IiIj/mpqa/5+fn/9kZGT/KCgo/yAgIP9KSkr/aWlp/5WV + lf/29vb/+vr6/56env8oKCj/GRkZ/yUlJf8hISH/HBwc/yAgIP8iIiL/IyMj/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP9LS0v/ysrK/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83N + zf/Ozs7/zs7O/87Ozv/Ozs7/zs7O/87Ozv/Ozs7/zs7O/83Nzf/Nzc3/zMzM/8zMzP/MzMz/zMzM/8zM + zP/Ly8v/y8vL/8vLy//MzMz/zMzM/83Nzf/Nzc3/zc3N/8HBwf9OTk7/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8lJSX/JSUl/yUlJf8kJCT/JSUl/x8fH/8HBwf/BgYG/05OTv+Pj4//r6+v/7u7 + u/+9vb3/wMDA/8LCwv/ExMT/xsbG/8jIyP/Kysr/zMzM/87Ozv/Pz8//0dHR/9PT0//U1NT/1dXV/9fX + 1//Y2Nj/2tra/9vb2//d3d3/3d3d/97e3v/g4OD/4eHh/+Li4v/i4uIx////Af///wH///8B////AcTE + xOPCwsL/v7+//7u7u/+3t7f/sbGx/6qqqv+Kior/e3t7/3x8fP9sbGz/Pj4+/1lZWf9+fn7/iIiI/5ub + m/+jo6P/bm5u/z8/P/9GRkb/MTEx/yYmJv9JSUn/YGBg/7Gxsf+qqqr/Ly8v/xgYGP8kJCT/IiIi/x0d + Hf8fHx//IiIi/yMjI/8jIyP/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/2BgYP/MzMz/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Ozs7/zs7O/87Ozv/Ozs7/zs7O/87O + zv/Ozs7/zc3N/83Nzf/Nzc3/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zc3N/83N + zf/Nzc3/ysrK/11dXf8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yUlJf8lJSX/JCQk/yQk + JP8fHx//CQkJ/wcHB/9FRUX/kJCQ/62trf+6urr/vLy8/7+/v//BwcH/xMTE/8bGxv/IyMj/ysrK/8zM + zP/Ozs7/0NDQ/9HR0f/T09P/1NTU/9XV1f/X19f/2NjY/9ra2v/b29v/3Nzc/93d3f/e3t7/4ODg/+Hh + 4f/i4uL/4+Pj/+Pj4zH///8B////Af///wH///8BxcXF48LCwv+/v7//vLy8/7i4uP+zs7P/qqqq/4iI + iP9+fn7/fn5+/2lpaf83Nzf/VlZW/4aGhv+YmJj/oaGh/3x8fP8+Pj7/TU1N/3h4eP9oaGj/NjY2/xkZ + Gf8TExP/IyMj/z4+Pv8eHh7/IiIi/yQkJP8cHBz/Hh4e/yIiIv8jIyP/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/aGho/8zMzP/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Ozs7/zs7O/87Ozv/Ozs7/zs7O/83Nzf/Nzc3/zc3N/83Nzf/MzMz/zMzM/8zM + zP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/Nzc3/zc3N/83Nzf/Nzc3/a2tr/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8lJSX/JSUl/yQkJP8mJib/NjY2/y0tLf8aGhr/Q0ND/5GRkf+urq7/ubm5/7y8 + vP+/v7//wcHB/8PDw//FxcX/yMjI/8rKyv/MzMz/zc3N/8/Pz//R0dH/09PT/9TU1P/V1dX/19fX/9jY + 2P/Z2dn/29vb/9zc3P/d3d3/3t7e/9/f3//g4OD/4eHh/+Li4v/j4+P/5OTkMf///wH///8B////Af// + /wHFxcXjwsLC/7+/v/+8vLz/uLi4/7S0tP+jo6P/hISE/4CAgP+AgID/aWlp/zY2Nv9cXFz/l5eX/6Oj + o/+AgID/RUVF/0lJSf9ycnL/g4OD/4ODg/+1tbX/S0tL/w4ODv8iIiL/Ozs7/x8fH/8eHh7/Hh4e/x4e + Hv8jIyP/JSUl/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP9hYWH/zMzM/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zM + zP/MzMz/zc3N/8vLy/9qamr/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yUlJf8kJCT/JCQk/zQ0 + NP9MTEz/X19f/2pqav+SkpL/s7Oz/7m5uf+7u7v/vr6+/8DAwP/Dw8P/xcXF/8fHx//Kysr/zMzM/83N + zf/Pz8//0dHR/9PT0//U1NT/1dXV/9fX1//Y2Nj/2dnZ/9ra2v/c3Nz/3d3d/97e3v/f39//4ODg/+Hh + 4f/i4uL/4+Pj/+Tk5P/k5OQx////Af///wH///8B////AcbGxuPDw8P/wMDA/7y8vP+5ubn/sbGx/5KS + kv+CgoL/goKC/4GBgf9lZWX/NDQ0/1xcXP+ioqL/iIiI/0VFRf9ERET/dHR0/4SEhP+BgYH/3t7e//z8 + /P+wsLD/Li4u/ycnJ/8bGxv/FBQU/xoaGv8gICD/JSUl/yYmJv8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/1FRUf/Ly8v/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zMzM/8zM + zP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/x8fH/1xcXP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yMjI/8jIyP/LS0t/0RERP9oaGj/hoaG/6+vr/+5ubn/vLy8/76+ + vv/AwMD/wsLC/8TExP/Hx8f/ycnJ/8vLy//Nzc3/z8/P/9DQ0P/S0tL/1NTU/9XV1f/X19f/2NjY/9nZ + 2f/a2tr/3Nzc/93d3f/e3t7/39/f/+Dg4P/h4eH/4uLi/+Pj4//k5OT/5eXl/+Xl5TH///8B////Af// + /wH///8BxsbG48TExP/BwcH/vb29/7q6uv+np6f/h4eH/4ODg/+Dg4P/g4OD/2VlZf8zMzP/Q0ND/4CA + gP9MTEz/QkJC/2hoaP+Hh4f/enp6/9DQ0P/9/f3/4ODg/1VVVf8ZGRn/Hx8f/xkZGf8WFhb/Hh4e/yUl + Jf8mJib/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/Ojo6/8HB + wf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zM + zP/MzMz/zMzM/8zMzP+8vLz/R0dH/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8iIiL/IiIi/xAQ + EP8GBgb/NjY2/4GBgf+hoaH/ubm5/7u7u/++vr7/wMDA/8LCwv/ExMT/xsbG/8nJyf/Ly8v/zc3N/8/P + z//Q0ND/0tLS/9TU1P/V1dX/19fX/9jY2P/Z2dn/2tra/9zc3P/d3d3/3t7e/9/f3//g4OD/4eHh/+Li + 4v/j4+P/5OTk/+Xl5f/l5eX/5ubmMf///wH///8B////Af///wHHx8fjxMTE/8HBwf++vr7/u7u7/5iY + mP+EhIT/hYWF/4WFhf+IiIj/dnZ2/zc3N/8sLCz/RUVF/0NDQ/9paWn/hYWF/319ff/IyMj/+/v7/+Dg + 4P9lZWX/FhYW/x0dHf8kJCT/Hh4e/x8fH/8jIyP/JSUl/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8mJib/n5+f/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/8zM + zP/MzMz/zMzM/8zMzP/MzMz/zMzM/8vLy//Ly8v/y8vL/8vLy//Ly8v/ysrK/5ycnP8yMjL/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/IiIi/yEhIf8TExP/AwMD/yoqKv+BgYH/qamp/7i4uP+8vLz/vr6+/8DA + wP/CwsL/xMTE/8fHx//Jycn/y8vL/83Nzf/Pz8//0dHR/9PT0//U1NT/1dXV/9fX1//Y2Nj/2dnZ/9vb + 2//c3Nz/3d3d/97e3v/f39//4ODg/+Hh4f/i4uL/4+Pj/+Tk5P/l5eX/5eXl/+bm5v/m5uYx////Af// + /wH///8B////AcjIyOPFxcX/wsLC/7+/v/+8vLz/k5OT/4WFhf+Ghob/iIiI/5KSkv+Ojo7/QkJC/yoq + Kv9eXl7/cHBw/4ODg/93d3f/vr6+//n5+f/n5+f/dHR0/xwcHP8cHBz/JSUl/x4eHv8fHx//JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP9wcHD/xsbG/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/8zMzP/MzMz/zMzM/8zMzP/Ly8v/y8vL/8vL + y//Ly8v/y8vL/8vLy//FxcX/eHh4/ykpKf8kJCT/JCQk/yQkJP8kJCT/JCQk/yMjI/8hISH/ExMT/wMD + A/8bGxv/dHR0/6Wlpf+4uLj/vLy8/76+vv/AwMD/wsLC/8TExP/Gxsb/ycnJ/8vLy//Nzc3/z8/P/9DQ + 0P/S0tL/09PT/9XV1f/X19f/2NjY/9nZ2f/a2tr/3Nzc/93d3f/e3t7/39/f/+Dg4P/h4eH/4uLi/+Pj + 4//j4+P/5OTk/+Xl5f/m5ub/5+fn/+fn5zH///8B////Af///wH///8ByMjI48bGxv/ExMT/wcHB/729 + vf+SkpL/hoaG/4iIiP+RkZH/oKCg/5eXl/9HR0f/JSUl/1JSUv+Li4v/gICA/66urv/6+vr/8fHx/3x8 + fP8eHh7/Gxsb/yUlJf8fHx//Hh4e/yIiIv8kJCT/JCQk/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/z4+Pv+np6f/zMzM/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zMzM/8zMzP/MzMz/zMzM/8vLy//Ly8v/y8vL/8vLy//Ly8v/y8vL/7CwsP9JSUn/JCQk/yQk + JP8kJCT/JCQk/yQkJP8jIyP/IyMj/xgYGP8EBAT/ExMT/2dnZ/+ampr/tra2/7y8vP++vr7/wMDA/8LC + wv/ExMT/xsbG/8nJyf/Ly8v/zMzM/8/Pz//Q0ND/0tLS/9PT0//U1NT/1tbW/9fX1//Z2dn/2tra/9zc + 3P/d3d3/3t7e/9/f3//g4OD/4eHh/+Li4v/j4+P/4+Pj/+Tk5P/l5eX/5ubm/+fn5//n5+f/5+fnMf// + /wH///8B////Af///wHJycnjx8fH/8XFxf/CwsL/vr6+/5KSkv+JiYn/kZGR/6CgoP+fn5//Y2Nj/zo6 + Ov8sLCz/Kioq/21tbf+QkJD/w8PD/+zs7P+RkZH/Hh4e/xoaGv8kJCT/ICAg/x0dHf8gICD/IyMj/yMj + I/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/KCgo/2dnZ//CwsL/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zMzM/8zMzP/MzMz/zMzM/8vL + y//Ly8v/y8vL/8vLy//Gxsb/ZmZm/ycnJ/8kJCT/JCQk/yQkJP8kJCT/IyMj/yIiIv8XFxf/BAQE/xkZ + Gf9oaGj/np6e/7S0tP+8vLz/vr6+/8DAwP/CwsL/xMTE/8fHx//IyMj/y8vL/8zMzP/Ozs7/0NDQ/9LS + 0v/T09P/1NTU/9bW1v/X19f/2dnZ/9ra2v/c3Nz/3d3d/97e3v/f39//4ODg/+Hh4f/i4uL/4+Pj/+Pj + 4//k5OT/5eXl/+bm5v/n5+f/5+fn/+jo6P/o6Ogx////Af///wH///8B////AcrKyuPIyMj/xsbG/8PD + w/+/v7//kpKS/5CQkP+dnZ3/o6Oj/3R0dP88PDz/Tk5O/2FhYf8vLy//LCws/z4+Pv8+Pj7/cHBw/zAw + MP8ZGRn/IyMj/yEhIf8dHR3/ICAg/yIiIv8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMj + I/8jIyP/IyMj/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/Li4u/5OTk//MzMz/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zMzM/8zMzP/MzMz/y8vL/8vLy//Ly8v/ycnJ/56env8xMTH/JCQk/yQk + JP8kJCT/IyMj/yMjI/8mJib/ISEh/wcHB/8KCgr/YWFh/5mZmf+2trb/vLy8/76+vv/AwMD/wsLC/8TE + xP/Gxsb/yMjI/8rKyv/MzMz/zs7O/9DQ0P/S0tL/09PT/9TU1P/W1tb/19fX/9nZ2f/a2tr/29vb/9zc + 3P/e3t7/39/f/+Dg4P/h4eH/4eHh/+Pj4//j4+P/5OTk/+Xl5f/l5eX/5ubm/+fn5//o6Oj/6Ojo/+np + 6TH///8B////Af///wH///8By8vL48nJyf/Hx8f/xcXF/7+/v/+YmJj/np6e/6Ojo/9ycnL/PT09/1JS + Uv96enr/fX19/3p6ev9RUVH/ERER/xISEv9MTEz/Pz8//yEhIf8iIiL/Hx8f/x8fH/8iIiL/IyMj/yMj + I/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/Nzc3/5WVlf/IyMj/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/MzMz/zMzM/8zM + zP/MzMz/y8vL/8rKyv+dnZ3/QEBA/yQkJP8kJCT/JCQk/yQkJP8jIyP/KSkp/0FBQf9RUVH/U1NT/2lp + af+qqqr/tra2/729vf+/v7//wcHB/8PDw//ExMT/x8fH/8jIyP/Kysr/zMzM/87Ozv/Q0ND/0tLS/9PT + 0//U1NT/1tbW/9fX1//Z2dn/2tra/9vb2//d3d3/3d3d/9/f3//g4OD/4eHh/+Li4v/i4uL/5OTk/+Tk + 5P/l5eX/5ubm/+bm5v/n5+f/6Ojo/+np6f/p6en/6enpMf///wH///8B////Af///wHMzMzjysrK/8jI + yP/Gxsb/wcHB/6Ojo/+mpqb/fX19/0FBQf9HR0f/dnZ2/4GBgf+Ghob/4eHh/9PT0/9MTEz/KSkp/zMz + M/8gICD/Ghoa/xwcHP8gICD/ISEh/yIiIv8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMj + I/8jIyP/IyMj/yMjI/8jIyP/IyMj/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8lJSX/QEBA/5aW + lv/Ly8v/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/MzMz/zMzM/8zMzP/Kysr/qamp/0lJSf8mJib/JCQk/yQk + JP8kJCT/IyMj/yQkJP8zMzP/SkpK/1tbW/94eHj/mJiY/7q6uv+8vLz/v7+//8HBwf/Dw8P/xcXF/8bG + xv/IyMj/ysrK/8zMzP/Ozs7/0NDQ/9LS0v/T09P/1NTU/9bW1v/X19f/2dnZ/9ra2v/c3Nz/3Nzc/93d + 3f/e3t7/39/f/+Dg4P/h4eH/4uLi/+Pj4//k5OT/5eXl/+bm5v/m5ub/5+fn/+jo6P/o6Oj/6enp/+rq + 6v/q6uox////Af///wH///8B////Ac3NzePLy8v/ycnJ/8fHx//ExMT/rKys/4SEhP9ERET/R0dH/29v + b/+CgoL/hYWF/+Li4v/7+/v/wMDA/zY2Nv8eHh7/HR0d/xISEv8ZGRn/Hh4e/yEhIf8iIiL/IyMj/yMj + I/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMj + I/8jIyP/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/MzMz/4KCgv+6urr/zMzM/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/8zM + zP/MzMz/v7+//4qKiv9AQED/JSUl/yQkJP8kJCT/JCQk/yMjI/8iIiL/ICAg/xISEv8nJyf/YWFh/42N + jf+ysrL/vb29/7+/v//BwcH/w8PD/8XFxf/Hx8f/ycnJ/8rKyv/MzMz/zs7O/9DQ0P/S0tL/09PT/9TU + 1P/W1tb/19fX/9nZ2f/a2tr/29vb/93d3f/d3d3/3t7e/9/f3//g4OD/4eHh/+Li4v/j4+P/5OTk/+Xl + 5f/m5ub/5ubm/+fn5//o6Oj/6Ojo/+np6f/q6ur/6urq/+vr6zH///8B////Af///wH///8Bz8/P483N + zf/Kysr/yMjI/8bGxv+jo6P/SkpK/0NDQ/9sbGz/goKC/35+fv/R0dH/+/v7/8zMzP9KSkr/ExMT/x0d + Hf8hISH/GRkZ/x4eHv8hISH/IiIi/yMjI/8jIyP/IyMj/yMjI/8iIiL/IiIi/yQiIf8iIiL/IiIi/yMj + I/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8kJCT/JCQk/yQk + JP8kJCT/LCws/1dXV/+jo6P/xsbG/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/x8fH/6mpqf9kZGT/Ly8v/yQkJP8kJCT/JCQk/yQk + JP8jIyP/IiIi/x4eHv8LCwv/BwcH/0BAQP+QkJD/sbGx/729vf/AwMD/wcHB/8PDw//FxcX/x8fH/8nJ + yf/Ly8v/zMzM/87Ozv/Q0ND/0tLS/9PT0//U1NT/1tbW/9fX1//Z2dn/2tra/9vb2//c3Nz/3d3d/97e + 3v/f39//4ODg/+Hh4f/i4uL/4+Pj/+Tk5P/k5OT/5ubm/+bm5v/n5+f/6Ojo/+jo6P/p6en/6urq/+rq + 6v/r6+v/6+vrMf///wH///8B////Af///wHPz8/jzs7O/8zMzP/Kysr/yMjI/7e3t/9vb2//aGho/4OD + g/94eHj/y8vL//v7+//T09P/VFRU/xcXF/8dHR3/IyMj/xwcHP8dHR3/ISEh/yMjI/8jIyP/IyMj/yIi + Iv8iIiL/IiIi/yIiIv86Ih7/ciQW/0AhHP8jISH/IiIi/yIiIv8jIyP/IyMj/yMjI/8jIyP/IyMj/yMj + I/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yQkJP8kJCT/JiYm/zo6Ov9oaGj/o6Oj/8HB + wf/Jycn/zMzM/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/8zMzP/Jycn/xMTE/62t + rf9wcHD/Pz8//ycnJ/8kJCT/JCQk/yQkJP8kJCT/IyMj/yIiIv8gICD/DAwM/wMDA/89PT3/h4eH/7Cw + sP+9vb3/v7+//8LCwv/ExMT/xsbG/8fHx//Jycn/y8vL/83Nzf/Pz8//0NDQ/9LS0v/T09P/1NTU/9bW + 1v/X19f/2dnZ/9ra2v/b29v/3Nzc/93d3f/e3t7/39/f/+Dg4P/h4eH/4uLi/+Li4v/j4+P/5OTk/+Xl + 5f/m5ub/5+fn/+jo6P/o6Oj/6enp/+rq6v/q6ur/6+vr/+vr6//s7Owx////Af///wH///8B////AdHR + 0ePPz8//zc3N/8vLy//Jycn/x8fH/7W1tf+SkpL/e3t7/76+vv/+/v7/5OTk/1paWv8UFBT/HBwc/yQk + JP8bGxv/HBwc/yEhIf8kJCT/IyMj/yMjI/8iIiL/IiIi/yIiIv8iIiL/NSIe/5EnFP/CLBH/ZCUa/yYi + If8iIiL/IiIi/yIiIv8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMj + I/8jIyP/IyMj/yQkJP8kJCT/JCQk/yQkJP8tLS3/TU1N/3Z2dv+goKD/rq6u/7q6uv/BwcH/yMjI/8nJ + yf/Hx8f/xcXF/729vf+urq7/m5ub/3p6ev9VVVX/MzMz/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yMj + I/8iIiL/ICAg/w4ODv8CAgL/Kioq/42Njf+tra3/vb29/8DAwP/CwsL/xMTE/8bGxv/IyMj/ysrK/8vL + y//Nzc3/z8/P/9DQ0P/S0tL/09PT/9TU1P/W1tb/19fX/9nZ2f/a2tr/3Nzc/93d3f/d3d3/3t7e/9/f + 3//g4OD/4eHh/+Li4v/i4uL/4+Pj/+Tk5P/l5eX/5ubm/+fn5//n5+f/6Ojo/+np6f/p6en/6urq/+vr + 6//r6+v/7Ozs/+zs7DH///8B////Af///wH///8B0tLS49DQ0P/Ozs7/zMzM/8vLy//Jycn/xsbG/7Ky + sv+xsbH/9PT0/+np6f98fHz/GRkZ/xkZGf8jIyP/Hx8f/xwcHP8hISH/JSUl/yQkJP8jIyP/IiIi/yIi + Iv8iIiL/IiIi/ykhIP9/JRX/xCwR/4UoGP8qIiH/IiIi/yIiIv8iIiL/IiIi/yMjI/8jIyP/IyMj/yMj + I/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8kJCT/JCQk/yQk + JP8kJCT/KCgo/zY2Nv9AQED/TExM/1lZWf9qamr/bW1t/2hoaP9iYmL/UVFR/0FBQf8zMzP/KCgo/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/IyMj/yEhIf8QEBD/AgIC/yAgIP90dHT/qqqq/7y8 + vP/AwMD/wsLC/8TExP/Gxsb/yMjI/8rKyv/MzMz/zc3N/8/Pz//R0dH/0tLS/9PT0//U1NT/1tbW/9fX + 1//Z2dn/2tra/9zc3P/c3Nz/3d3d/97e3v/f39//4ODg/+Hh4f/i4uL/4uLi/+Pj4//k5OT/5eXl/+bm + 5v/m5ub/5+fn/+jo6P/p6en/6enp/+rq6v/r6+v/6+vr/+zs7P/s7Oz/7OzsMf///wH///8B////Af// + /wHU1NTj0tLS/9DQ0P/Ozs7/zMzM/8rKyv/IyMj/wsLC/5GRkf+kpKT/cHBw/xsbG/8ZGRn/IiIi/x8f + H/8eHh7/IyMj/yYmJv8lJSX/IyMj/yIiIv8iIiL/IiIi/yIiIv8sIR//eSYX/8UtEf+CKBj/LiIg/yIi + Iv8iIiL/IiIi/yIiIv8iIiL/IiIi/yQiIv8jIyP/IyMj/yMjI/8jIiL/LCIh/0sjHP9vJRj/NSIf/yMj + I/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/IyMj/yQk + JP8nJyf/ERER/wICAv8lJSX/fX19/6ampv++vr7/wcHB/8PDw//ExMT/xsbG/8jIyP/Kysr/zMzM/83N + zf/Pz8//0dHR/9PT0//U1NT/1dXV/9bW1v/X19f/2dnZ/9ra2v/b29v/3d3d/93d3f/e3t7/39/f/+Dg + 4P/h4eH/4uLi/+Pj4//j4+P/5OTk/+Xl5f/m5ub/5+fn/+fn5//o6Oj/6enp/+np6f/q6ur/6urq/+vr + 6//r6+v/7Ozs/+3t7f/t7e0x////Af///wH///8B////AdXV1ePT09P/0dHR/8/Pz//Nzc3/zMzM/8rK + yv/BwcH/aGho/zs7O/9DQ0P/ISEh/yIiIv8eHh7/HR0d/yIiIv8mJib/JSUl/yMjI/8iIiL/IiIi/yIi + Iv8hISH/JCEh/3QlF//DLBD/tSsS/z4iHf8iISH/IiIi/yIiIv8iIiL/IiEh/yohH/9JIhz/YiIX/zch + Hf8kIiL/JiIh/0ciG/9+Jhb/jCgW/7csE/9GJB7/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMj + I/8jIyP/IyMj/yMjI/8kJCT/JCQk/yQkJP8kJCT/IyMj/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8jIyP/Li4u/z4+Pv8sLCz/Kysr/35+fv+qqqr/vLy8/8HB + wf/Dw8P/xcXF/8bGxv/IyMj/ysrK/8zMzP/Nzc3/z8/P/9HR0f/T09P/1NTU/9XV1f/X19f/2NjY/9nZ + 2f/a2tr/3Nzc/9zc3P/d3d3/3t7e/9/f3//g4OD/4eHh/+Li4v/i4uL/4+Pj/+Tk5P/l5eX/5ubm/+bm + 5v/n5+f/6Ojo/+jo6P/p6en/6urq/+rq6v/r6+v/7Ozs/+zs7P/t7e3/7e3t/+7u7jH///8B////Af// + /wH///8B1dXV49TU1P/T09P/0dHR/8/Pz//Nzc3/y8vL/8LCwv9vb2//U1NT/0dHR/8tLS3/JiYm/x4e + Hv8iIiL/JSUl/yUlJf8jIyP/IyMj/yIiIv8hISH/ISEh/yYgIP9fIxj/xSwR/7QsE/+7KxL/lycT/1Ui + GP80IR7/OSEc/0ohGv9tIxb/nygT/7wrEv+6LBL/hiYV/1MiGf98Jhb/kSgV/2QmG/9YJhz/nisW/ywj + If8jIiL/MyIf/z8iHf8vIiD/IyIi/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMj + I/8jIyP/IyMj/yMjI/8jIyP/IyMj/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8jIyP/IyMj/yYm + Jv9DQ0P/UVFR/2xsbP9/f3//s7Oz/7+/v//BwcH/xMTE/8XFxf/Hx8f/ycnJ/8rKyv/MzMz/zs7O/9DQ + 0P/R0dH/09PT/9TU1P/V1dX/19fX/9jY2P/Z2dn/2tra/9vb2//c3Nz/3d3d/97e3v/f39//4ODg/+Hh + 4f/i4uL/4+Pj/+Pj4//k5OT/5eXl/+bm5v/n5+f/5+fn/+jo6P/o6Oj/6enp/+rq6v/q6ur/6+vr/+vr + 6//s7Oz/7Ozs/+3t7f/u7u7/7u7uMf///wH///8B////Af///wHX19fj1dXV/9TU1P/S0tL/0NDQ/8/P + z//Nzc3/xcXF/35+fv9PT0//MDAw/ywsLP8mJib/ISEh/yQkJP8lJSX/IyMj/yMjI/8iIiL/IiIi/yEh + If8jICD/YiMZ/7srEf+fKhX/QSMd/1QkHP+eKhX/vCoQ/64pEf+sKBH/tioR/7ErE/+ZKhb/dCca/1Ml + HP98JRb/mCgU/3EnGv85JCD/JiMi/2smGv95KBn/IyMi/zQjIP+PJxT/hicW/3AkFv84Ix//IyIi/yMj + Iv8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yMjI/8jIyP/Hh4e/zIyMv9PT0//e3t7/5ycnP+9vb3/w8PD/8TE + xP/Gxsb/yMjI/8nJyf/Ly8v/zc3N/87Ozv/Q0ND/0dHR/9PT0//U1NT/1dXV/9fX1//Y2Nj/2dnZ/9ra + 2v/c3Nz/3Nzc/93d3f/e3t7/39/f/+Dg4P/h4eH/4uLi/+Pj4//k5OT/5OTk/+Xl5f/m5ub/5+fn/+fn + 5//o6Oj/6Ojo/+np6f/q6ur/6urq/+vr6//r6+v/7Ozs/+3t7f/t7e3/7e3t/+7u7v/u7u4x////Af// + /wH///8B////AdjY2OPX19f/1dXV/9PT0//S0tL/0NDQ/8/Pz//IyMj/gYGB/zc3N/8sLCz/KCgo/yEh + If8hISH/IyMj/yQkJP8jIyP/IiIi/yIiIv8hISH/ISEh/1EjG/+7KxH/tisS/0QjHf8iISD/IiEg/zUi + Hv9rJhn/tysS/7YqEf9eJBr/PiMe/y8iIP8lIiH/JCIh/0wkHf9DJB7/KCMi/yIiIv8qIiH/hSgX/1Ym + Hf8nIiH/QyQe/5YpFf9IIxz/TyUd/4gnFv9aJBn/JSIi/yMiIv8jIiL/IyMj/yMjI/8jIyP/IyMj/yMj + I/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/JCQk/yQkJP8kJCT/JCQk/yMjI/8jIyP/IyMj/xoa + Gv8GBgb/FxcX/2RkZP+enp7/u7u7/8PDw//FxcX/x8fH/8jIyP/Kysr/zMzM/87Ozv/Pz8//0NDQ/9LS + 0v/T09P/1dXV/9bW1v/X19f/2NjY/9ra2v/a2tr/3Nzc/9zc3P/d3d3/3t7e/9/f3//g4OD/4eHh/+Li + 4v/j4+P/5OTk/+Tk5P/l5eX/5ubm/+bm5v/n5+f/6Ojo/+jo6P/p6en/6enp/+rq6v/r6+v/6+vr/+zs + 7P/s7Oz/7e3t/+3t7f/u7u7/7u7u/+7u7jH///8B////Af///wH///8B2tra49jY2P/W1tb/1NTU/9PT + 0//S0tL/0NDQ/8XFxf9kZGT/LS0t/ygoKP8iIiL/IiIi/yMjI/8kJCT/IyMj/yMjI/8iIiL/IiIi/yEh + If8oISD/gCcX/8ctEf+gKBP/QSEb/yYgH/8gICD/ICAg/yAgH/9MIxz/tisS/34mFv8mISD/ISEh/yYh + IP83IR3/RSIb/0MiHP8zIR7/IyEh/0IkHv+ZKRX/OyMf/1ckG/9zJRf/WSUc/4MmFf9uJBf/pSoU/1Yl + HP9EIx3/SyMc/zMiH/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMj + I/8kJCT/JCQk/yQkJP8kJCT/IyMj/yIiIv8ZGRn/BQUF/wwMDP9bW1v/oaGh/7+/v//FxcX/xsbG/8jI + yP/Jycn/y8vL/8zMzP/Ozs7/0NDQ/9HR0f/T09P/1NTU/9XV1f/X19f/2NjY/9nZ2f/a2tr/29vb/9zc + 3P/d3d3/3t7e/9/f3//g4OD/4ODg/+Hh4f/i4uL/4+Pj/+Tk5P/k5OT/5eXl/+bm5v/n5+f/5+fn/+jo + 6P/o6Oj/6enp/+rq6v/q6ur/6+vr/+vr6//s7Oz/7e3t/+3t7f/u7u7/7u7u/+7u7v/v7+//7+/vMf// + /wH///8B////Af///wHa2trj2dnZ/9fX1//W1tb/1NTU/9PT0//S0tL/w8PD/1dXV/8sLCz/IyMj/yEh + If8jIyP/JCQk/yQkJP8jIyP/IyMj/yIiIv8iIiL/IiIi/yEhIf8zIh//aiYa/64qE/+uKRH/bSMW/y0f + Hf8gICD/ICAg/zshHf+tKhL/oioU/y0hH/8rIB7/bCMW/6QpEv+0KhH/rykR/5onEv9aIhj/WiQa/3cn + Gf8pIiH/SSQd/40nFP9YIhn/fiYW/6YqFP9dJRv/WSQa/5goFf+JKBb/gCYW/zUiHv8kIiL/IyMj/yMj + I/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yQkJP8kJCT/JCQk/yMjI/8iIiL/HBwc/wcH + B/8GBgb/SkpK/5ycnP+9vb3/xcXF/8fHx//Jycn/ysrK/8zMzP/Nzc3/zs7O/9DQ0P/S0tL/09PT/9XV + 1f/W1tb/19fX/9nZ2f/Z2dn/2tra/9vb2//d3d3/3d3d/97e3v/f39//4ODg/+Dg4P/h4eH/4uLi/+Pj + 4//k5OT/5OTk/+Xl5f/m5ub/5ubm/+fn5//o6Oj/6Ojo/+np6f/p6en/6urq/+vr6//r6+v/7Ozs/+zs + 7P/t7e3/7e3t/+7u7v/u7u7/7+/v/+/v7//w8PAx////Af///wH///8B////Advb2+Pa2tr/2dnZ/9fX + 1//W1tb/1NTU/9PT0//CwsL/UFBQ/yQkJP8hISH/IyMj/yQkJP8kJCT/JCQk/yMjI/8jIyP/IiIi/yIi + Iv8iIiL/ISEh/yEhIf8iISD/OSIe/3wnGP+zKhL/nycR/2YiFv9WIRf/kCUS/8UsEf93Jxn/MSEe/4Ul + FP+5KxL/gygX/0wkHf9FIx3/dicY/68qEv98JRb/KiIg/yIiIf8kIiH/QyMe/38nGP+NKRb/XCYb/1wk + Gv+dKRT/SyUe/ykjIv98KBn/licU/z0iHv8tIiD/JSIi/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMj + I/8jIyP/JCQk/yMjI/8jIyP/JCQk/yEhIf8JCQn/CQkJ/0hISP+YmJj/wMDA/8fHx//IyMj/ycnJ/8vL + y//MzMz/zs7O/8/Pz//R0dH/0tLS/9TU1P/V1dX/19fX/9jY2P/Z2dn/2tra/9vb2//c3Nz/3d3d/97e + 3v/e3t7/39/f/+Dg4P/h4eH/4uLi/+Li4v/j4+P/5OTk/+Tk5P/l5eX/5ubm/+fn5//n5+f/6Ojo/+jo + 6P/p6en/6urq/+rq6v/r6+v/6+vr/+zs7P/s7Oz/7e3t/+3t7f/u7u7/7u7u/+/v7//v7+//8PDw//Dw + 8DH///8B////Af///wH///8B3d3d49zc3P/a2tr/2dnZ/9fX1//W1tb/1NTU/8DAwP9GRkb/IiIi/yMj + I/8kJCT/JCQk/yQkJP8kJCT/IyMj/yMjI/8jIyP/IiIi/yIiIv8iIiL/ISEh/yEhIf8hISH/JyEg/04j + HP+QKBX/tioR/70rEP+3KxL/gygX/zsiHv9tJRj/viwR/3AmGf8rISD/ISEh/yEhIf8nISD/dicY/7Eq + Ev88Ih7/IiIi/yIiIv8iIiL/JiIh/ykiIf82Ih7/likV/10mHP8kIiL/OCIe/5UpFv9pJxv/RCMe/3Ym + F/8xIyD/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8kJCT/IyMj/yMjI/8jIyP/CgoK/wQE + BP9AQED/kpKS/7u7u//IyMj/ycnJ/8vLy//MzMz/zs7O/8/Pz//Q0ND/0dHR/9PT0//U1NT/1tbW/9fX + 1//Y2Nj/2tra/9vb2//c3Nz/3Nzc/97e3v/e3t7/39/f/+Dg4P/g4OD/4eHh/+Li4v/i4uL/4+Pj/+Tk + 5P/l5eX/5eXl/+bm5v/m5ub/5+fn/+jo6P/o6Oj/6enp/+rq6v/q6ur/6+vr/+vr6//s7Oz/7Ozs/+3t + 7f/t7e3/7u7u/+7u7v/v7+//7+/v/+/v7//w8PD/8PDwMf///wH///8B////Af///wHe3t7j3d3d/9zc + 3P/a2tr/2dnZ/9fX1//W1tb/y8vL/2hoaP8sLCz/IyMj/yMjI/8kJCT/JCQk/yMjI/8jIyP/IyMj/yMj + I/8iIiL/IiIi/yIiIv8hISH/ISEh/yEhIf8hISH/ISEg/ywhH/9BIx3/TyQc/0AjHv8pISD/NCIe/6Iq + FP+cKRX/KyEf/yEhIf8hISH/ISEh/yQhIP9sJRj/vSsR/0sjHf8hISH/MCEf/0QiHP8oISD/IiIi/yci + If9CJB7/JyIh/zciH/+IJxX/cica/0YkHf+RKBX/YiYc/zoiHv9kJBn/RyMd/yUiIv8jIyP/IyMj/yMj + I/8jIyP/IyMj/yMjI/8lJSX/MTEx/x8fH/8NDQ3/Pz8//5WVlf+5ubn/ycnJ/8vLy//MzMz/zc3N/8/P + z//Q0ND/0dHR/9LS0v/U1NT/1dXV/9bW1v/X19f/2dnZ/9ra2v/b29v/3Nzc/93d3f/e3t7/39/f/+Dg + 4P/g4OD/4eHh/+Li4v/i4uL/4+Pj/+Tk5P/k5OT/5eXl/+bm5v/m5ub/5+fn/+fn5//o6Oj/6enp/+np + 6f/q6ur/6urq/+vr6//r6+v/7Ozs/+zs7P/t7e3/7e3t/+7u7v/u7u7/7u7u/+/v7//v7+//8PDw//Dw + 8P/x8fEx////Af///wH///8B////Ad/f3+Pe3t7/3d3d/9zc3P/a2tr/2dnZ/9jY2P/X19f/xMTE/4yM + jP89PT3/JiYm/yMjI/8kJCT/IyMj/yMjI/8jIyP/IyMj/yMjI/8iIiL/IiIi/yIiIv8iIiL/IiIi/yEh + If8hISH/ISEh/yEhIf8hISH/ISEh/yEhIf8zIh//oioU/5AoFf8jICD/ISEh/yEhIf8gICD/OiEc/6Ao + Ev+rKhP/MiIf/ysgHv+EJhX/rikR/0QjHf8iIiL/IiIi/yIiIv8iIiL/TiMc/24nGv9CIx7/kikW/3co + Gf89Ix7/hicX/4EpGf9iJhv/KiMi/yMjI/8jIyP/IyMj/yMjI/8iIiL/JCQk/zg4OP9SUlL/XV1d/2Ji + Yv+ZmZn/xMTE/8zMzP/MzMz/zs7O/8/Pz//Q0ND/0dHR/9LS0v/U1NT/1dXV/9bW1v/X19f/2NjY/9nZ + 2f/b29v/3Nzc/93d3f/e3t7/39/f/9/f3//g4OD/4eHh/+Li4v/i4uL/4+Pj/+Pj4//k5OT/5eXl/+Xl + 5f/m5ub/5ubm/+fn5//o6Oj/6Ojo/+np6f/p6en/6urq/+rq6v/r6+v/7Ozs/+zs7P/t7e3/7e3t/+3t + 7f/u7u7/7u7u/+/v7//v7+//8PDw//Dw8P/w8PD/8fHx//Hx8TH///8B////Af///wH///8B4ODg49/f + 3//e3t7/3d3d/9zc3P/a2tr/2dnZ/9jY2P/X19f/0tLS/6qqqv9kZGT/Kysr/yMjI/8jIyP/IyMj/yMj + I/8jIyP/IyMj/yIiIv8iIiL/IiIi/yIiIv8iIiL/ISEh/yEhIf8hISH/ISEh/yEhIf8hISH/ISEh/yYh + IP9zJxn/sCoS/1QhGP8oIB7/IyAf/zcgG/+MJRP/visR/2YlGf8oIB//aSMX/78rEf+CKBj/LCIg/yIi + Iv8iIiH/IyIh/yIhIf8oIiH/NyIe/4AmFv99KBj/PSId/4EnFv95KBn/LSMi/yYjIv8jIyL/IyMj/yMj + I/8jIyP/IiIi/yIiIv8lJSX/OTk5/1NTU/9nZ2f/hYWF/7m5uf/Nzc3/zs7O/8/Pz//Q0ND/0dHR/9LS + 0v/T09P/1NTU/9bW1v/X19f/2NjY/9nZ2f/a2tr/29vb/9zc3P/d3d3/3t7e/9/f3//g4OD/4ODg/+Hh + 4f/i4uL/4+Pj/+Pj4//k5OT/5OTk/+Xl5f/m5ub/5ubm/+fn5//n5+f/6Ojo/+jo6P/p6en/6enp/+rq + 6v/r6+v/6+vr/+vr6//s7Oz/7Ozs/+3t7f/t7e3/7u7u/+7u7v/v7+//7+/v/+/v7//w8PD/8PDw//Hx + 8f/x8fH/8fHxMf///wH///8B////Af///wHh4eHj4ODg/9/f3//e3t7/3d3d/9zc3P/b29v/2tra/9nZ + 2f/Y2Nj/19fX/9TU1P+goKD/XFxc/y8vL/8iIiL/IyMj/yMjI/8jIyP/IyMj/yMjI/8iIiL/IiIi/yIi + Iv8iIiL/IiIi/yIiIv8iIiL/ISEh/yEhIf8hISH/ISEh/ykhIP9yJhj/qikS/54mEf+WJRH/rSgR/6sq + E/9kJRr/LyEe/3EkFv+/KxD/gygX/zAiH/8hISH/IiEh/zIiH/97JRX/VCMa/ysiIP9zJRf/eygZ/1Ek + HP+fKBP/likV/zMjIP8jIyP/IyMj/yMjI/8jIyP/IyMj/yIiIv8jIyP/JCQk/xEREf8HBwf/PT09/4GB + gf+0tLT/zs7O/8/Pz//R0dH/0tLS/9LS0v/T09P/1NTU/9XV1f/X19f/2NjY/9nZ2f/a2tr/29vb/9zc + 3P/d3d3/3t7e/9/f3//g4OD/4eHh/+Hh4f/i4uL/4+Pj/+Tk5P/k5OT/5eXl/+Xl5f/m5ub/5ubm/+fn + 5//n5+f/6Ojo/+jo6P/p6en/6enp/+rq6v/q6ur/6+vr/+vr6//s7Oz/7Ozs/+3t7f/t7e3/7u7u/+7u + 7v/u7u7/7+/v/+/v7//w8PD/8PDw//Hx8f/x8fH/8fHx//Ly8v/x8fEx////Af///wH///8B////AeLi + 4uPh4eH/4ODg/9/f3//e3t7/3d3d/9zc3P/b29v/2tra/9nZ2f/Y2Nj/19fX/9XV1f/ExMT/ioqK/0FB + Qf8kJCT/IyMj/yMjI/8jIyP/IyMj/yMjI/8iIiL/IiIi/yIiIv8iIiL/IiIi/yIiIv8iIiL/IiIi/yEh + If8hISH/ISEh/yghIP9FIx3/aCUZ/3UmGP9lJRn/QiMd/ychH/9YIhj/vSsR/5YpFf8wIh//ISEh/yEh + If8tIR//eSUW/7wsEf9lJhv/JyIh/0QkHv81IyD/YCUa/4spF/9UJR3/KyMh/yMjI/8jIyP/IyMj/yMj + I/8jIyP/IiIi/yQkJP8XFxf/AgIC/xwcHP95eXn/sbGx/87Ozv/Q0ND/0tLS/9PT0//U1NT/1NTU/9XV + 1f/W1tb/19fX/9nZ2f/a2tr/29vb/9vb2//d3d3/3d3d/9/f3//g4OD/4eHh/+Hh4f/i4uL/4+Pj/+Pj + 4//k5OT/5OTk/+Xl5f/m5ub/5ubm/+fn5//n5+f/6Ojo/+jo6P/p6en/6enp/+np6f/q6ur/6urq/+vr + 6//r6+v/7Ozs/+zs7P/t7e3/7e3t/+7u7v/u7u7/7+/v/+/v7//v7+//8PDw//Dw8P/w8PD/8fHx//Hx + 8f/y8vL/8vLy//Ly8jH///8B////Af///wH///8B4+Pj4+Li4v/h4eH/4ODg/9/f3//e3t7/3d3d/9zc + 3P/b29v/29vb/9ra2v/Z2dn/2NjY/9fX1//T09P/urq6/3t7e/81NTX/JSUl/yIiIv8jIyP/IyMj/yMj + I/8jIyP/IiIi/yIiIv8iIiL/IiIi/yIiIv8iIiL/IiIi/yEhIf8hISH/ISEh/yEhIP8iISD/JCEg/yIh + IP8lICD/WCIZ/7QqEf+sKxP/PiMe/yEhIP8hISH/KyAf/3klFv+7KxH/byca/yoiIf8iIiL/IyIi/y8i + IP9CIx3/MSMh/yQjIv8jIyL/IyMj/yMjI/8jIyP/IiIi/yMjI/8mJib/GBgY/wUFBf8eHh7/d3d3/7W1 + tf/Ozs7/0tLS/9PT0//U1NT/1dXV/9bW1v/X19f/19fX/9nZ2f/Z2dn/29vb/9zc3P/c3Nz/3t7e/97e + 3v/g4OD/4ODg/+Hh4f/i4uL/4+Pj/+Tk5P/k5OT/5eXl/+Xl5f/m5ub/5ubm/+fn5//n5+f/6Ojo/+jo + 6P/p6en/6enp/+rq6v/q6ur/6urq/+vr6//r6+v/7Ozs/+zs7P/t7e3/7e3t/+3t7f/u7u7/7u7u/+/v + 7//v7+//7+/v//Dw8P/w8PD/8PDw//Hx8f/x8fH/8vLy//Ly8v/y8vL/8/PzMf///wH///8B////Af// + /wHk5OTj5OTk/+Li4v/i4uL/4ODg/+Dg4P/e3t7/3t7e/93d3f/c3Nz/29vb/9ra2v/a2tr/2dnZ/9jY + 2P/X19f/09PT/6SkpP9gYGD/Kioq/yIiIv8jIyP/IyMj/yMjI/8jIyP/IyMj/yIiIv8iIiL/IiIi/yIi + Iv8iIiL/IiIi/yEhIf8hISH/ISEh/yEhIf8hISH/ISEh/zIhHv+TKBT/qCoT/6EpFP82IR3/ISAg/yYg + H/9nIxf/uysR/4MoF/8uIiD/IiIi/yIiIv8xIiD/iSgW/48oFf81IyD/IyMj/yMjI/8jIyP/IyMj/yMj + I/8iIiL/KSkp/x8fH/8FBQX/FRUV/2lpaf+urq7/0NDQ/9TU1P/V1dX/1dXV/9bW1v/X19f/2NjY/9nZ + 2f/Z2dn/29vb/9vb2//c3Nz/3d3d/97e3v/f39//4ODg/+Hh4f/i4uL/4+Pj/+Pj4//k5OT/5eXl/+Xl + 5f/m5ub/5ubm/+fn5//n5+f/6Ojo/+jo6P/p6en/6enp/+rq6v/q6ur/6urq/+vr6//r6+v/7Ozs/+zs + 7P/s7Oz/7e3t/+3t7f/u7u7/7u7u/+/v7//v7+//7+/v//Dw8P/w8PD/8PDw//Hx8f/x8fH/8fHx//Ly + 8v/y8vL/8vLy//Pz8//z8/Mx////Af///wH///8B////AeXl5ePl5eX/5OTk/+Pj4//i4uL/4eHh/+Dg + 4P/f39//3t7e/97e3v/c3Nz/3Nzc/9vb2//a2tr/2tra/9nZ2f/Y2Nj/1tbW/8nJyf+MjIz/RUVF/yYm + Jv8iIiL/IyMj/yMjI/8jIyP/IiIi/yIiIv8iIiL/IiIi/yIiIv8iIiL/IiIi/yEhIf8hISH/ISEh/yEh + If8hISH/JCEg/z0iHv9HIx3/pyoT/4gmE/9QIRj/dCQW/7orEf+OKRf/NCMf/yIiIv8iIiL/MCIf/4Em + Fv/ALRL/cCga/yojIv8jIyP/IyMj/yMjI/8jIyP/IiIi/yQkJP8eHh7/BQUF/wwMDP9hYWH/qamp/83N + zf/V1dX/1tbW/9fX1//X19f/2NjY/9nZ2f/a2tr/29vb/9zc3P/d3d3/3d3d/97e3v/f39//4ODg/+Hh + 4f/i4uL/4+Pj/+Pj4//k5OT/5eXl/+Xl5f/m5ub/5ubm/+fn5//n5+f/6Ojo/+jo6P/p6en/6enp/+rq + 6v/q6ur/6urq/+vr6//r6+v/6+vr/+zs7P/s7Oz/7e3t/+3t7f/t7e3/7u7u/+7u7v/v7+//7+/v/+/v + 7//w8PD/8PDw//Dw8P/x8fH/8fHx//Hx8f/y8vL/8vLy//Ly8v/z8/P/8/Pz//Pz8zH///8B////Af// + /wH///8B5ubm4+bm5v/l5eX/5OTk/+Pj4//i4uL/4eHh/+Hh4f/g4OD/39/f/9/f3//e3t7/3d3d/9zc + 3P/c3Nz/29vb/9ra2v/Z2dn/2dnZ/9fX1/+8vLz/fHx8/zg4OP8kJCT/IiIi/yMjI/8jIyP/IyMj/yIi + Iv8iIiL/IiIi/yIiIv8iIiL/IiIi/yIiIv8hISH/ISEh/yEhIf8hISH/ISEh/yMhIP9TJBz/nSkV/7gr + Ef+2KxL/uiwS/08kHP8iIiL/IiIi/yoiIP+AJhX/vywS/3YoGv8pIyL/IyMj/yMjI/8jIyP/IyMj/yIi + Iv8qKir/JSUl/wkJCf8RERH/Xl5e/6enp//Pz8//19fX/9jY2P/Y2Nj/2dnZ/9ra2v/a2tr/3Nzc/9zc + 3P/d3d3/3t7e/97e3v/f39//4ODg/+Hh4f/i4uL/4+Pj/+Tk5P/k5OT/5eXl/+Xl5f/m5ub/5+fn/+fn + 5//n5+f/6Ojo/+jo6P/p6en/6enp/+rq6v/q6ur/6+vr/+vr6//r6+v/7Ozs/+zs7P/s7Oz/7e3t/+3t + 7f/t7e3/7u7u/+7u7v/u7u7/7+/v/+/v7//w8PD/8PDw//Dw8P/x8fH/8fHx//Hx8f/y8vL/8vLy//Ly + 8v/z8/P/8/Pz//Pz8//z8/P/8/PzMf///wH///8B////Af///wHn5+fj5+fn/+bm5v/l5eX/5OTk/+Pj + 4//j4+P/4uLi/+Hh4f/g4OD/4ODg/9/f3//e3t7/3t7e/93d3f/c3Nz/29vb/9vb2//a2tr/2dnZ/9nZ + 2f/R0dH/pKSk/19fX/9LS0v/YmJi/2FhYf9PT0//LS0t/yIiIv8iIiL/IiIi/yIiIv8iIiL/IiIi/yIi + Iv8iIiL/ISEh/yEhIf8hISH/ISEh/yMhIP82Ix//TiQd/0okHf+iKhT/YCQZ/yQhIf8oISD/aCQY/8As + Ef+BKRn/MCMh/yMjI/8jIyP/IyMj/yMjI/8iIiL/Kysr/0xMTP9MTEz/QkJC/2RkZP+ysrL/zs7O/9jY + 2P/Z2dn/2dnZ/9ra2v/b29v/3Nzc/9zc3P/e3t7/3t7e/9/f3//g4OD/4ODg/+Hh4f/i4uL/4+Pj/+Pj + 4//k5OT/5eXl/+Xl5f/m5ub/5ubm/+fn5//n5+f/6Ojo/+jo6P/p6en/6enp/+np6f/q6ur/6urq/+vr + 6//r6+v/6+vr/+zs7P/s7Oz/7e3t/+3t7f/t7e3/7u7u/+7u7v/u7u7/7+/v/+/v7//v7+//8PDw//Dw + 8P/w8PD/8fHx//Hx8f/x8fH/8vLy//Ly8v/y8vL/8/Pz//Pz8//z8/P/8/Pz//T09P/z8/Mx////Af// + /wH///8B////Aejo6OPo6Oj/5+fn/+bm5v/m5ub/5eXl/+Tk5P/k5OT/4+Pj/+Li4v/h4eH/4eHh/+Dg + 4P/g4OD/39/f/97e3v/e3t7/3d3d/9zc3P/c3Nz/29vb/9ra2v/a2tr/1tbW/9TU1P/Y2Nj/19fX/9TU + 1P+1tbX/ZWVl/ysrK/8iIiL/IiIi/yIiIv8iIiL/IiIi/yIiIv8iIiL/ISEh/yEhIf8hISH/ISEh/yEh + If8iIiH/IiIh/2YnG/+zKxL/nCgT/6MoEv/BLBH/gSkZ/zAkIf8jIyL/IyMj/yMjI/8jIyP/IiIi/ycn + J/84ODj/VFRU/2JiYv92dnb/q6ur/9fX1//a2tr/2tra/9vb2//c3Nz/3d3d/93d3f/e3t7/39/f/9/f + 3//g4OD/4eHh/+Li4v/i4uL/4+Pj/+Tk5P/k5OT/5eXl/+bm5v/m5ub/5+fn/+fn5//o6Oj/6Ojo/+jo + 6P/p6en/6enp/+rq6v/q6ur/6+vr/+vr6//r6+v/7Ozs/+zs7P/s7Oz/7e3t/+3t7f/t7e3/7u7u/+7u + 7v/u7u7/7+/v/+/v7//v7+//7+/v//Dw8P/w8PD/8PDw//Hx8f/x8fH/8fHx//Hx8f/y8vL/8vLy//Pz + 8//z8/P/8/Pz//Pz8//09PT/9PT0//Pz8zH///8B////Af///wH///8B6enp4+np6f/o6Oj/5+fn/+fn + 5//m5ub/5eXl/+Xl5f/k5OT/4+Pj/+Pj4//i4uL/4eHh/+Hh4f/g4OD/4ODg/9/f3//e3t7/3t7e/93d + 3f/d3d3/3Nzc/9vb2//b29v/29vb/9ra2v/a2tr/2dnZ/9nZ2f/Dw8P/YmJi/yQkJP8jIyP/IiIi/yIi + Iv8iIiL/IiIi/yIiIv8iIiL/IiIi/yIiIv8iIiL/IiIi/yIiIv8iIiL/KiIh/10mHP+UKhb/nSsW/28o + G/8uIyH/IyMj/yMjI/8jIyP/IyMj/yIiIv8iIiL/ISEh/xQUFP8uLi7/Z2dn/4+Pj//Ozs7/29vb/9zc + 3P/c3Nz/3d3d/97e3v/e3t7/39/f/9/f3//g4OD/4eHh/+Li4v/i4uL/4+Pj/+Tk5P/k5OT/5eXl/+bm + 5v/m5ub/5ubm/+fn5//o6Oj/6Ojo/+jo6P/p6en/6enp/+rq6v/q6ur/6urq/+vr6//r6+v/7Ozs/+zs + 7P/s7Oz/7e3t/+3t7f/t7e3/7u7u/+7u7v/u7u7/7+/v/+/v7//v7+//8PDw//Dw8P/w8PD/8PDw//Hx + 8f/x8fH/8fHx//Ly8v/y8vL/8vLy//Ly8v/z8/P/8/Pz//Pz8//09PT/9PT0//T09P/09PT/9PT0Mf// + /wH///8B////Af///wHq6urj6urq/+np6f/o6Oj/6Ojo/+fn5//n5+f/5ubm/+bm5v/l5eX/5OTk/+Tk + 5P/j4+P/4+Pj/+Li4v/h4eH/4eHh/+Dg4P/g4OD/39/f/97e3v/e3t7/3d3d/93d3f/d3d3/3Nzc/9zc + 3P/b29v/29vb/9ra2v+mpqb/Kioq/yMjI/8iIiL/IiIi/yIiIv8iIiL/IiIi/yIiIv8iIiL/IiIi/yIi + Iv8iIiL/IiIi/yIiIv8iIiL/JCMi/ysjIv8sIyH/JiMi/yMjIv8jIyP/IyMj/yMjI/8iIiL/IiIi/x0d + Hf8ICAj/BQUF/zs7O/+Wlpb/x8fH/9zc3P/d3d3/3t7e/97e3v/f39//4ODg/+Dg4P/h4eH/4uLi/+Li + 4v/j4+P/4+Pj/+Tk5P/l5eX/5eXl/+bm5v/m5ub/5+fn/+jo6P/o6Oj/6Ojo/+np6f/p6en/6urq/+rq + 6v/q6ur/6+vr/+vr6//r6+v/7Ozs/+zs7P/s7Oz/7e3t/+3t7f/t7e3/7u7u/+7u7v/u7u7/7+/v/+/v + 7//v7+//7+/v/+/v7//w8PD/8PDw//Dw8P/x8fH/8fHx//Hx8f/y8vL/8vLy//Ly8v/y8vL/8/Pz//Pz + 8//z8/P/9PT0//T09P/09PT/9PT0//X19f/19fUx////Af///wH///8B////Aevr6+Pr6+v/6urq/+rq + 6v/p6en/6Ojo/+jo6P/n5+f/5+fn/+bm5v/m5ub/5eXl/+Tk5P/k5OT/4+Pj/+Pj4//i4uL/4uLi/+Hh + 4f/h4eH/4ODg/+Dg4P/f39//3t7e/97e3v/e3t7/3d3d/93d3f/c3Nz/3Nzc/8HBwf83Nzf/IiIi/yIi + Iv8jIyP/IyMj/yIiIv8iIiL/IiIi/yIiIv8iIiL/IiIi/yIiIv8iIiL/IyMj/yMjI/8jIyP/IyMj/yMj + I/8jIyP/IyMj/yMjI/8jIyP/IiIi/yIiIv8hISH/DQ0N/wMDA/80NDT/kJCQ/8nJyf/d3d3/39/f/9/f + 3//g4OD/4ODg/+Hh4f/h4eH/4uLi/+Li4v/j4+P/5OTk/+Tk5P/l5eX/5eXl/+bm5v/n5+f/5+fn/+fn + 5//o6Oj/6Ojo/+np6f/p6en/6urq/+rq6v/q6ur/6+vr/+vr6//r6+v/7Ozs/+zs7P/t7e3/7e3t/+3t + 7f/u7u7/7u7u/+7u7v/u7u7/7+/v/+/v7//v7+//7+/v//Dw8P/w8PD/8PDw//Hx8f/x8fH/8fHx//Hx + 8f/y8vL/8vLy//Ly8v/z8/P/8/Pz//Pz8//z8/P/8/Pz//T09P/09PT/9PT0//T09P/19fX/9fX1//X1 + 9TH///8B////Af///wH///8B7Ozs4+vr6//r6+v/6urq/+rq6v/p6en/6enp/+jo6P/o6Oj/5+fn/+bm + 5v/m5ub/5eXl/+Xl5f/k5OT/5OTk/+Pj4//j4+P/4uLi/+Li4v/h4eH/4eHh/+Dg4P/g4OD/39/f/9/f + 3//f39//3t7e/97e3v/d3d3/19fX/4uLi/89PT3/JCQk/yMjI/8jIyP/IyMj/yMjI/8iIiL/IiIi/yIi + Iv8iIiL/IiIi/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yIiIv8jIyP/JSUl/w4O + Dv8CAgL/IyMj/4KCgv/FxcX/39/f/+Dg4P/g4OD/4eHh/+Hh4f/i4uL/4uLi/+Pj4//j4+P/5OTk/+Tk + 5P/l5eX/5eXl/+bm5v/m5ub/5+fn/+fn5//o6Oj/6Ojo/+np6f/p6en/6urq/+rq6v/q6ur/6+vr/+vr + 6//r6+v/7Ozs/+zs7P/s7Oz/7e3t/+3t7f/t7e3/7u7u/+7u7v/u7u7/7+/v/+/v7//v7+//7+/v//Dw + 8P/w8PD/8PDw//Dw8P/x8fH/8fHx//Hx8f/x8fH/8vLy//Ly8v/y8vL/8vLy//Pz8//z8/P/8/Pz//Pz + 8//09PT/9PT0//T09P/19fX/9fX1//X19f/19fX/9fX1Mf///wH///8B////Af///wHt7e3j7Ozs/+zs + 7P/r6+v/6+vr/+rq6v/q6ur/6enp/+np6f/p6en/6Ojo/+jo6P/n5+f/5ubm/+bm5v/l5eX/5eXl/+Xl + 5f/k5OT/5OTk/+Pj4//j4+P/4uLi/+Li4v/h4eH/4eHh/+Hh4f/g4OD/4ODg/9/f3//f39//3d3d/76+ + vv9ycnL/ODg4/yQkJP8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMj + I/8jIyP/IyMj/yMjI/8jIyP/IiIi/yMjI/8RERH/AgIC/yYmJv+IiIj/xcXF/9/f3//i4uL/4uLi/+Li + 4v/j4+P/4+Pj/+Tk5P/k5OT/5eXl/+Xl5f/m5ub/5ubm/+bm5v/n5+f/5+fn/+jo6P/o6Oj/6enp/+np + 6f/p6en/6urq/+rq6v/r6+v/6+vr/+zs7P/s7Oz/7Ozs/+3t7f/t7e3/7e3t/+7u7v/u7u7/7u7u/+7u + 7v/v7+//7+/v/+/v7//v7+//8PDw//Dw8P/w8PD/8PDw//Hx8f/x8fH/8fHx//Hx8f/y8vL/8vLy//Ly + 8v/y8vL/8vLy//Pz8//z8/P/8/Pz//Pz8//09PT/9PT0//T09P/09PT/9fX1//X19f/19fX/9fX1//b2 + 9v/29vYx////Af///wH///8B////Ae3t7ePt7e3/7Ozs/+zs7P/s7Oz/6+vr/+vr6//q6ur/6urq/+np + 6f/p6en/6enp/+jo6P/o6Oj/5+fn/+fn5//m5ub/5ubm/+Xl5f/l5eX/5OTk/+Tk5P/j4+P/4+Pj/+Li + 4v/i4uL/4uLi/+Hh4f/h4eH/4eHh/+Dg4P/g4OD/4ODg/9TU1P+np6f/XFxc/yQkJP8iIiL/IyMj/yMj + I/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yIiIv8nJyf/FBQU/wIC + Av8cHBz/dnZ2/8TExP/f39//4uLi/+Pj4//j4+P/4+Pj/+Tk5P/k5OT/5eXl/+Xl5f/m5ub/5ubm/+fn + 5//n5+f/5+fn/+jo6P/o6Oj/6enp/+np6f/q6ur/6urq/+rq6v/r6+v/6+vr/+vr6//s7Oz/7Ozs/+3t + 7f/t7e3/7e3t/+7u7v/u7u7/7u7u/+7u7v/v7+//7+/v/+/v7//v7+//7+/v//Dw8P/w8PD/8PDw//Dw + 8P/x8fH/8fHx//Hx8f/x8fH/8vLy//Ly8v/y8vL/8vLy//Pz8//z8/P/8/Pz//Pz8//z8/P/9PT0//T0 + 9P/09PT/9PT0//X19f/19fX/9fX1//X19f/19fX/9vb2//b29jH///8B////Af///wH///8B7u7u4+3t + 7f/t7e3/7e3t/+zs7P/s7Oz/7Ozs/+vr6//r6+v/6+vr/+rq6v/q6ur/6enp/+np6f/p6en/6Ojo/+jo + 6P/n5+f/5+fn/+bm5v/m5ub/5eXl/+Xl5f/l5eX/5OTk/+Tk5P/j4+P/4+Pj/+Pj4//i4uL/4uLi/+Li + 4v/i4uL/4eHh/+Hh4f/X19f/l5eX/05OTv8oKCj/IiIi/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMj + I/8jIyP/IyMj/yMjI/8lJSX/Tk5O/5iYmP9zc3P/UVFR/5OTk//Gxsb/4uLi/+Tk5P/k5OT/5eXl/+Xl + 5f/l5eX/5ubm/+bm5v/n5+f/5+fn/+fn5//o6Oj/6Ojo/+np6f/p6en/6enp/+rq6v/q6ur/6urq/+vr + 6//r6+v/6+vr/+zs7P/s7Oz/7Ozs/+3t7f/t7e3/7e3t/+7u7v/u7u7/7u7u/+7u7v/u7u7/7+/v/+/v + 7//v7+//8PDw//Dw8P/w8PD/8PDw//Dw8P/x8fH/8fHx//Hx8f/x8fH/8fHx//Ly8v/y8vL/8vLy//Ly + 8v/y8vL/8/Pz//Pz8//z8/P/8/Pz//T09P/09PT/9PT0//T09P/09PT/9fX1//X19f/19fX/9fX1//b2 + 9v/29vb/9vb2Mf///wH///8B////Af///wHu7u7j7u7u/+7u7v/t7e3/7e3t/+3t7f/s7Oz/7Ozs/+zs + 7P/r6+v/6+vr/+vr6//q6ur/6urq/+rq6v/p6en/6enp/+jo6P/o6Oj/5+fn/+fn5//m5ub/5ubm/+Xl + 5f/l5eX/5eXl/+Tk5P/k5OT/5OTk/+Pj4//j4+P/4+Pj/+Pj4//i4uL/4uLi/+Pj4//g4OD/xMTE/3d3 + d/82Njb/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IiIi/0RERP+urq7/4uLi/+Li + 4v/a2tr/4ODg/+Tk5P/l5eX/5eXl/+Xl5f/l5eX/5ubm/+bm5v/n5+f/5+fn/+fn5//o6Oj/6Ojo/+jo + 6P/p6en/6enp/+rq6v/q6ur/6urq/+vr6//r6+v/6+vr/+zs7P/s7Oz/7Ozs/+3t7f/t7e3/7e3t/+7u + 7v/u7u7/7u7u/+/v7//v7+//7+/v/+/v7//v7+//8PDw//Dw8P/w8PD/8PDw//Hx8f/x8fH/8fHx//Hx + 8f/x8fH/8vLy//Ly8v/y8vL/8vLy//Ly8v/z8/P/8/Pz//Pz8//z8/P/8/Pz//T09P/09PT/9PT0//T0 + 9P/09PT/9fX1//X19f/19fX/9fX1//b29v/29vb/9vb2//b29v/29vYx////Af///wH///8B////Ae/v + 7+Pu7u7/7u7u/+7u7v/u7u7/7e3t/+3t7f/t7e3/7Ozs/+zs7P/s7Oz/6+vr/+vr6//r6+v/6urq/+rq + 6v/q6ur/6enp/+np6f/o6Oj/6Ojo/+fn5//n5+f/5+fn/+bm5v/m5ub/5eXl/+Xl5f/l5eX/5OTk/+Tk + 5P/k5OT/5OTk/+Pj4//j4+P/5OTk/+Tk5P/k5OT/29vb/7i4uP9ra2v/LS0t/yQkJP8iIiL/IyMj/yMj + I/8jIyP/IiIi/yMjI/84ODj/ra2t/+Li4v/l5eX/5eXl/+Xl5f/l5eX/5eXl/+bm5v/m5ub/5ubm/+fn + 5//n5+f/5+fn/+jo6P/o6Oj/6Ojo/+np6f/p6en/6enp/+rq6v/q6ur/6+vr/+vr6//r6+v/7Ozs/+zs + 7P/s7Oz/7e3t/+3t7f/t7e3/7e3t/+7u7v/u7u7/7u7u/+7u7v/v7+//7+/v/+/v7//v7+//8PDw//Dw + 8P/w8PD/8PDw//Hx8f/x8fH/8fHx//Hx8f/x8fH/8vLy//Ly8v/y8vL/8vLy//Ly8v/z8/P/8/Pz//Pz + 8//z8/P/8/Pz//T09P/09PT/9PT0//T09P/09PT/9PT0//X19f/19fX/9fX1//X19f/19fX/9vb2//b2 + 9v/29vb/9vb2//b29jH///8B////Af///wH///8B8PDw4+/v7//v7+//7+/v/+7u7v/u7u7/7u7u/+3t + 7f/t7e3/7e3t/+zs7P/s7Oz/7Ozs/+zs7P/r6+v/6+vr/+vr6//q6ur/6urq/+np6f/p6en/6enp/+jo + 6P/o6Oj/5+fn/+fn5//n5+f/5ubm/+bm5v/m5ub/5ubm/+bm5v/l5eX/5eXl/+Xl5f/l5eX/5eXl/+bm + 5v/m5ub/5ubm/9jY2P+dnZ3/V1dX/yYmJv8iIiL/IyMj/yMjI/8iIiL/PDw8/6CgoP/l5eX/5+fn/+fn + 5//n5+f/5+fn/+fn5//n5+f/5+fn/+jo6P/o6Oj/6Ojo/+jo6P/p6en/6enp/+np6f/q6ur/6urq/+rq + 6v/r6+v/6+vr/+vr6//s7Oz/7Ozs/+zs7P/t7e3/7e3t/+3t7f/t7e3/7u7u/+7u7v/u7u7/7u7u/+/v + 7//v7+//7+/v/+/v7//w8PD/8PDw//Dw8P/w8PD/8fHx//Hx8f/x8fH/8fHx//Ly8v/y8vL/8vLy//Ly + 8v/y8vL/8vLy//Pz8//z8/P/8/Pz//Pz8//z8/P/8/Pz//T09P/09PT/9PT0//T09P/09PT/9PT0//X1 + 9f/19fX/9fX1//X19f/19fX/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2Mf///wH///8B////Af// + /wHw8PDj8PDw//Dw8P/v7+//7+/v/+/v7//u7u7/7u7u/+7u7v/t7e3/7e3t/+3t7f/s7Oz/7Ozs/+zs + 7P/s7Oz/6+vr/+vr6//r6+v/6urq/+rq6v/p6en/6enp/+np6f/o6Oj/6Ojo/+jo6P/n5+f/5+fn/+fn + 5//n5+f/5ubm/+bm5v/m5ub/5ubm/+bm5v/m5ub/5ubm/+fn5//n5+f/5+fn/+Tk5P/MzMz/eHh4/zY2 + Nv8kJCT/IiIi/y0tLf+ampr/4ODg/+fn5//o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6enp/+np + 6f/p6en/6enp/+rq6v/q6ur/6urq/+rq6v/r6+v/6+vr/+vr6//s7Oz/7Ozs/+zs7P/t7e3/7e3t/+3t + 7f/t7e3/7u7u/+7u7v/u7u7/7+/v/+/v7//v7+//7+/v/+/v7//w8PD/8PDw//Dw8P/w8PD/8fHx//Hx + 8f/x8fH/8fHx//Hx8f/y8vL/8vLy//Ly8v/y8vL/8vLy//Pz8//z8/P/8/Pz//Pz8//z8/P/8/Pz//Pz + 8//09PT/9PT0//T09P/09PT/9PT0//X19f/19fX/9fX1//X19f/19fX/9fX1//b29v/29vb/9vb2//b2 + 9v/29vb/9vb2//f39//29vYx////Af///wH///8B////AfHx8ePx8fH/8PDw//Dw8P/w8PD/7+/v/+/v + 7//v7+//7+/v/+7u7v/u7u7/7u7u/+3t7f/t7e3/7e3t/+3t7f/s7Oz/7Ozs/+zs7P/r6+v/6+vr/+vr + 6//q6ur/6urq/+rq6v/p6en/6enp/+np6f/p6en/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo + 6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/k5OT/xcXF/3R0dP9MTEz/kZGR/+bm5v/p6en/6enp/+np + 6f/p6en/6enp/+np6f/q6ur/6urq/+rq6v/q6ur/6urq/+vr6//r6+v/6+vr/+vr6//r6+v/7Ozs/+zs + 7P/s7Oz/7e3t/+3t7f/t7e3/7u7u/+7u7v/u7u7/7u7u/+7u7v/v7+//7+/v/+/v7//v7+//8PDw//Dw + 8P/w8PD/8PDw//Dw8P/x8fH/8fHx//Hx8f/x8fH/8vLy//Ly8v/y8vL/8vLy//Ly8v/z8/P/8/Pz//Pz + 8//z8/P/8/Pz//Pz8//z8/P/9PT0//T09P/09PT/9PT0//T09P/09PT/9PT0//X19f/19fX/9fX1//X1 + 9f/19fX/9fX1//b29v/29vb/9vb2//b29v/29vb/9vb2//f39//39/f/9/f3//b29jH///8B////Af// + /wH///8B8fHx4/Hx8f/x8fH/8fHx//Dw8P/w8PD/8PDw/+/v7//v7+//7+/v/+/v7//u7u7/7u7u/+7u + 7v/t7e3/7e3t/+3t7f/t7e3/7e3t/+zs7P/s7Oz/6+vr/+vr6//r6+v/6urq/+rq6v/q6ur/6urq/+np + 6f/p6en/6enp/+np6f/p6en/6enp/+np6f/p6en/6enp/+np6f/p6en/6enp/+np6f/p6en/6enp/+np + 6f/p6en/3d3d/83Nzf/h4eH/6urq/+rq6v/q6ur/6urq/+rq6v/q6ur/6urq/+rq6v/q6ur/6urq/+vr + 6//r6+v/6+vr/+vr6//s7Oz/7Ozs/+zs7P/s7Oz/7e3t/+3t7f/t7e3/7u7u/+7u7v/u7u7/7u7u/+7u + 7v/v7+//7+/v/+/v7//v7+//8PDw//Dw8P/w8PD/8PDw//Dw8P/w8PD/8fHx//Hx8f/x8fH/8fHx//Ly + 8v/y8vL/8vLy//Ly8v/y8vL/8/Pz//Pz8//z8/P/8/Pz//Pz8//z8/P/9PT0//T09P/09PT/9PT0//T0 + 9P/09PT/9PT0//X19f/19fX/9fX1//X19f/19fX/9fX1//b29v/29vb/9vb2//b29v/29vb/9vb2//b2 + 9v/39/f/9/f3//f39//39/f/9vb2Mf///wH///8B////Af///wHy8vLj8fHx//Hx8f/x8fH/8fHx//Dw + 8P/w8PD/8PDw//Dw8P/v7+//7+/v/+/v7//v7+//7u7u/+7u7v/u7u7/7u7u/+3t7f/t7e3/7e3t/+3t + 7f/t7e3/7Ozs/+zs7P/s7Oz/7Ozs/+vr6//r6+v/6+vr/+vr6//r6+v/6urq/+rq6v/q6ur/6urq/+rq + 6v/q6ur/6urq/+rq6v/q6ur/6urq/+rq6v/q6ur/6urq/+rq6v/q6ur/6urq/+rq6v/r6+v/6+vr/+vr + 6//r6+v/6+vr/+vr6//r6+v/6+vr/+vr6//r6+v/7Ozs/+zs7P/s7Oz/7Ozs/+zs7P/t7e3/7e3t/+3t + 7f/u7u7/7u7u/+7u7v/u7u7/7u7u/+/v7//v7+//7+/v/+/v7//v7+//8PDw//Dw8P/w8PD/8PDw//Dw + 8P/x8fH/8fHx//Hx8f/x8fH/8fHx//Ly8v/y8vL/8vLy//Ly8v/y8vL/8/Pz//Pz8//z8/P/8/Pz//Pz + 8//z8/P/9PT0//T09P/09PT/9PT0//T09P/09PT/9PT0//T09P/19fX/9fX1//X19f/19fX/9fX1//X1 + 9f/19fX/9vb2//b29v/29vb/9vb2//b29v/29vb/9/f3//f39//39/f/9/f3//f39//39/cx////Af// + /wH///8B////AfLy8uPy8vL/8vLy//Ly8v/y8vL/8fHx//Hx8f/x8fH/8PDw//Dw8P/w8PD/8PDw/+/v + 7//v7+//7+/v/+/v7//u7u7/7u7u/+7u7v/u7u7/7u7u/+3t7f/t7e3/7e3t/+3t7f/s7Oz/7Ozs/+zs + 7P/s7Oz/7Ozs/+vr6//r6+v/6+vr/+vr6//r6+v/6+vr/+vr6//r6+v/6+vr/+vr6//r6+v/6+vr/+vr + 6//r6+v/6+vr/+vr6//r6+v/6+vr/+zs7P/s7Oz/7Ozs/+zs7P/s7Oz/7Ozs/+zs7P/s7Oz/7Ozs/+zs + 7P/t7e3/7e3t/+3t7f/t7e3/7e3t/+7u7v/u7u7/7u7u/+7u7v/v7+//7+/v/+/v7//v7+//7+/v//Dw + 8P/w8PD/8PDw//Dw8P/w8PD/8fHx//Hx8f/x8fH/8fHx//Hx8f/x8fH/8vLy//Ly8v/y8vL/8vLy//Ly + 8v/z8/P/8/Pz//Pz8//z8/P/8/Pz//Pz8//09PT/9PT0//T09P/09PT/9PT0//T09P/09PT/9fX1//X1 + 9f/19fX/9fX1//X19f/19fX/9fX1//b29v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9/f3//f3 + 9//39/f/9/f3//f39//39/f/9/f3//j4+DH///8B////Af///wH///8B8/Pz4/Pz8//y8vL/8vLy//Ly + 8v/y8vL/8fHx//Hx8f/x8fH/8fHx//Dw8P/w8PD/8PDw//Dw8P/w8PD/7+/v/+/v7//v7+//7+/v/+/v + 7//u7u7/7u7u/+7u7v/u7u7/7e3t/+3t7f/t7e3/7e3t/+3t7f/s7Oz/7Ozs/+zs7P/s7Oz/7Ozs/+zs + 7P/s7Oz/7Ozs/+zs7P/s7Oz/7Ozs/+zs7P/s7Oz/7Ozs/+zs7P/s7Oz/7Ozs/+zs7P/s7Oz/7Ozs/+zs + 7P/s7Oz/7e3t/+3t7f/t7e3/7e3t/+3t7f/t7e3/7e3t/+3t7f/t7e3/7u7u/+7u7v/u7u7/7u7u/+/v + 7//v7+//7+/v/+/v7//v7+//8PDw//Dw8P/w8PD/8PDw//Dw8P/x8fH/8fHx//Hx8f/x8fH/8fHx//Hx + 8f/x8fH/8vLy//Ly8v/y8vL/8vLy//Ly8v/z8/P/8/Pz//Pz8//z8/P/8/Pz//Pz8//09PT/9PT0//T0 + 9P/09PT/9PT0//T09P/09PT/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/29vb/9vb2//b2 + 9v/29vb/9vb2//b29v/29vb/9vb2//f39//39/f/9/f3//f39//39/f/9/f3//f39//4+Pj/+Pj4Mf// + /wH///8B////Af///wHz8/Pj8/Pz//Pz8//z8/P/8/Pz//Ly8v/y8vL/8vLy//Ly8v/x8fH/8fHx//Hx + 8f/x8fH/8fHx//Dw8P/w8PD/8PDw//Dw8P/w8PD/8PDw/+/v7//v7+//7+/v/+/v7//v7+//7u7u/+7u + 7v/u7u7/7u7u/+7u7v/u7u7/7e3t/+3t7f/t7e3/7e3t/+3t7f/t7e3/7e3t/+3t7f/t7e3/7e3t/+3t + 7f/t7e3/7e3t/+3t7f/t7e3/7e3t/+3t7f/t7e3/7e3t/+3t7f/u7u7/7u7u/+7u7v/u7u7/7u7u/+7u + 7v/u7u7/7u7u/+7u7v/v7+//7+/v/+/v7//v7+//7+/v//Dw8P/w8PD/8PDw//Dw8P/w8PD/8fHx//Hx + 8f/x8fH/8fHx//Hx8f/x8fH/8vLy//Ly8v/y8vL/8vLy//Ly8v/y8vL/8vLy//Pz8//z8/P/8/Pz//Pz + 8//z8/P/8/Pz//T09P/09PT/9PT0//T09P/09PT/9PT0//T09P/19fX/9fX1//X19f/19fX/9fX1//X1 + 9f/19fX/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b29v/39/f/9/f3//f39//39/f/9/f3//f3 + 9//39/f/9/f3//j4+P/4+Pj/+Pj4//j4+P/4+Pgx////Af///wH///8B////AfT09OP09PT/8/Pz//Pz + 8//z8/P/8/Pz//Pz8//y8vL/8vLy//Ly8v/y8vL/8vLy//Hx8f/x8fH/8fHx//Hx8f/w8PD/8PDw//Dw + 8P/w8PD/8PDw//Dw8P/w8PD/8PDw/+/v7//v7+//7+/v/+/v7//u7u7/7u7u/+7u7v/u7u7/7u7u/+7u + 7v/u7u7/7u7u/+7u7v/u7u7/7u7u/+7u7v/u7u7/7u7u/+7u7v/u7u7/7u7u/+7u7v/u7u7/7u7u/+7u + 7v/u7u7/7u7u/+7u7v/u7u7/7u7u/+7u7v/u7u7/7+/v/+/v7//v7+//7+/v/+/v7//v7+//8PDw//Dw + 8P/w8PD/8PDw//Dw8P/x8fH/8fHx//Hx8f/x8fH/8fHx//Hx8f/x8fH/8vLy//Ly8v/y8vL/8vLy//Ly + 8v/y8vL/8vLy//Pz8//z8/P/8/Pz//Pz8//z8/P/8/Pz//T09P/09PT/9PT0//T09P/09PT/9PT0//X1 + 9f/19fX/9fX1//X19f/19fX/9fX1//X19f/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b2 + 9v/29vb/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//j4+P/4+Pj/+Pj4//j4+P/4+Pj/+Pj4//j4 + +DH///8B////AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA + + + \ No newline at end of file diff --git a/ROMVault2/FrmRegistration.Designer.cs b/ROMVault2/FrmRegistration.Designer.cs new file mode 100644 index 0000000..bb0ccaf --- /dev/null +++ b/ROMVault2/FrmRegistration.Designer.cs @@ -0,0 +1,121 @@ +namespace ROMVault2 +{ + partial class FrmRegistration + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.label1 = new System.Windows.Forms.Label(); + this.label2 = new System.Windows.Forms.Label(); + this.label3 = new System.Windows.Forms.Label(); + this.txtName = new System.Windows.Forms.TextBox(); + this.txtEmail = new System.Windows.Forms.TextBox(); + this.btnOK = new System.Windows.Forms.Button(); + this.SuspendLayout(); + // + // label1 + // + this.label1.Location = new System.Drawing.Point(12, 9); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(420, 49); + this.label1.TabIndex = 0; + this.label1.Text = "To make RomVault 2 the best is can be, RomVault 2 will send error reports to the " + + "author. Please fill out this from so that the Author can contact you in the case" + + " of a crash."; + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(12, 58); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(120, 13); + this.label2.TabIndex = 1; + this.label2.Text = "Your Name: (Username)"; + // + // label3 + // + this.label3.AutoSize = true; + this.label3.Location = new System.Drawing.Point(12, 100); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(103, 13); + this.label3.TabIndex = 2; + this.label3.Text = "Your Contact Email :"; + // + // txtName + // + this.txtName.Location = new System.Drawing.Point(15, 74); + this.txtName.Name = "txtName"; + this.txtName.Size = new System.Drawing.Size(417, 20); + this.txtName.TabIndex = 3; + // + // txtEmail + // + this.txtEmail.Location = new System.Drawing.Point(15, 116); + this.txtEmail.Name = "txtEmail"; + this.txtEmail.Size = new System.Drawing.Size(417, 20); + this.txtEmail.TabIndex = 4; + // + // btnOK + // + this.btnOK.Location = new System.Drawing.Point(303, 145); + this.btnOK.Name = "btnOK"; + this.btnOK.Size = new System.Drawing.Size(128, 23); + this.btnOK.TabIndex = 5; + this.btnOK.Text = "OK"; + this.btnOK.UseVisualStyleBackColor = true; + this.btnOK.Click += new System.EventHandler(this.btnOK_Click); + // + // FrmRegistration + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(444, 178); + this.ControlBox = false; + this.Controls.Add(this.btnOK); + this.Controls.Add(this.txtEmail); + this.Controls.Add(this.txtName); + this.Controls.Add(this.label3); + this.Controls.Add(this.label2); + this.Controls.Add(this.label1); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow; + this.Name = "FrmRegistration"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Text = "Registration"; + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.TextBox txtName; + private System.Windows.Forms.TextBox txtEmail; + private System.Windows.Forms.Button btnOK; + } +} \ No newline at end of file diff --git a/ROMVault2/FrmRegistration.cs b/ROMVault2/FrmRegistration.cs new file mode 100644 index 0000000..22f08ad --- /dev/null +++ b/ROMVault2/FrmRegistration.cs @@ -0,0 +1,28 @@ +/****************************************************** + * ROMVault2 is written by Gordon J. * + * Contact gordon@romvault.com * + * Copyright 2014 * + ******************************************************/ + +using System; +using System.Windows.Forms; + +namespace ROMVault2 +{ + public partial class FrmRegistration : Form + { + public FrmRegistration() + { + InitializeComponent(); + txtName.Text = Settings.Username; + txtEmail.Text = Settings.EMail; + } + + private void btnOK_Click(object sender, EventArgs e) + { + Settings.Username = txtName.Text; + Settings.EMail = txtEmail.Text; + Close(); + } + } +} diff --git a/ROMVault2/FrmRegistration.resx b/ROMVault2/FrmRegistration.resx new file mode 100644 index 0000000..5ea0895 --- /dev/null +++ b/ROMVault2/FrmRegistration.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/ROMVault2/IO/RVIO.cs b/ROMVault2/IO/RVIO.cs new file mode 100644 index 0000000..0d90862 --- /dev/null +++ b/ROMVault2/IO/RVIO.cs @@ -0,0 +1,606 @@ +/****************************************************** + * ROMVault2 is written by Gordon J. * + * Contact gordon@romvault.com * + * Copyright 2014 * + ******************************************************/ + +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using System.Text; +using Microsoft.Win32.SafeHandles; + +namespace ROMVault2.IO +{ + [Flags] + [ComVisible(true)] + [Serializable] + public enum FileAttributes + { + ReadOnly = 1, + Hidden = 2, + System = 4, + Directory = 16, + Archive = 32, + Device = 64, + Normal = 128, + Temporary = 256, + SparseFile = 512, + ReparsePoint = 1024, + Compressed = 2048, + Offline = 4096, + NotContentIndexed = 8192, + Encrypted = 16384, + } + public static class Error + { + public static int GetLastError() + { + return Marshal.GetLastWin32Error(); + } + } + + public class FileInfo + { + + public string Name; + public string FullName; + public long LastWriteTime; + public long Length; + public int fileAttributes; + + public bool isHidden + { + get { return (fileAttributes & Win32Native.FILE_ATTRIBUTE_HIDDEN) != 0; } + } + + public FileInfo() + { } + + public FileInfo(string path) + { + FullName = path; + Name = Path.GetFileName(path); + + string fileName = NameFix.AddLongPathPrefix(path); + Win32Native.WIN32_FILE_ATTRIBUTE_DATA wIn32FileAttributeData = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA(); + + bool b = Win32Native.GetFileAttributesEx(fileName, 0, ref wIn32FileAttributeData); + + if (!b || (wIn32FileAttributeData.fileAttributes & Win32Native.FILE_ATTRIBUTE_DIRECTORY) != 0) return; + + Length = Convert.Length(wIn32FileAttributeData.fileSizeHigh, wIn32FileAttributeData.fileSizeLow); + LastWriteTime = Convert.Time(wIn32FileAttributeData.ftLastWriteTimeHigh, wIn32FileAttributeData.ftLastWriteTimeLow); + fileAttributes = wIn32FileAttributeData.fileAttributes; + } + + } + + public class DirectoryInfo + { + public string Name; + public string FullName; + public long LastWriteTime; + public int fileAttributes; + + public bool isHidden + { + get { return (fileAttributes & Win32Native.FILE_ATTRIBUTE_HIDDEN) != 0; } + } + + public DirectoryInfo() + { } + public DirectoryInfo(string path) + { + FullName = path; + Name = Path.GetFileName(path); + + string fileName = NameFix.AddLongPathPrefix(path); + Win32Native.WIN32_FILE_ATTRIBUTE_DATA wIn32FileAttributeData = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA(); + + bool b = Win32Native.GetFileAttributesEx(fileName, 0, ref wIn32FileAttributeData); + + if (!b || (wIn32FileAttributeData.fileAttributes & Win32Native.FILE_ATTRIBUTE_DIRECTORY) == 0) return; + LastWriteTime = Convert.Time(wIn32FileAttributeData.ftLastWriteTimeHigh, wIn32FileAttributeData.ftLastWriteTimeLow); + fileAttributes = wIn32FileAttributeData.fileAttributes; + } + + + + public DirectoryInfo[] GetDirectories(bool includeHidden = true) + { + return GetDirectories("*", includeHidden); + } + public DirectoryInfo[] GetDirectories(string SearchPattern, bool includeHidden = true) + { + List dirs = new List(); + + string dirName = NameFix.AddLongPathPrefix(FullName); + + Win32Native.WIN32_FIND_DATA findData = new Win32Native.WIN32_FIND_DATA(); + SafeFindHandle findHandle = Win32Native.FindFirstFile(dirName + @"\" + SearchPattern, findData); + + if (!findHandle.IsInvalid) + { + do + { + string currentFileName = findData.cFileName; + + // if this is a directory, find its contents + if ((findData.dwFileAttributes & Win32Native.FILE_ATTRIBUTE_DIRECTORY) == 0) continue; + if (currentFileName == "." || currentFileName == "..") continue; + if (!includeHidden && (findData.dwFileAttributes & Win32Native.FILE_ATTRIBUTE_HIDDEN) != 0) continue; + + DirectoryInfo di = new DirectoryInfo + { + Name = currentFileName, + FullName = Path.Combine(FullName, currentFileName), + LastWriteTime = Convert.Time(findData.ftLastWriteTimeHigh, findData.ftLastWriteTimeLow), + fileAttributes = findData.dwFileAttributes + }; + dirs.Add(di); + } + while (Win32Native.FindNextFile(findHandle, findData)); + } + + // close the find handle + findHandle.Dispose(); + + return dirs.ToArray(); + } + + public FileInfo[] GetFiles() + { + return GetFiles("*"); + } + public FileInfo[] GetFiles(string SearchPattern, bool includeHidden = true) + { + List files = new List(); + + string dirName = NameFix.AddLongPathPrefix(FullName); + + Win32Native.WIN32_FIND_DATA findData = new Win32Native.WIN32_FIND_DATA(); + SafeFindHandle findHandle = Win32Native.FindFirstFile(dirName + @"\" + SearchPattern, findData); + + if (!findHandle.IsInvalid) + { + do + { + string currentFileName = findData.cFileName; + + // if this is a directory, find its contents + if ((findData.dwFileAttributes & Win32Native.FILE_ATTRIBUTE_DIRECTORY) != 0) continue; + if (!includeHidden && (findData.dwFileAttributes & Win32Native.FILE_ATTRIBUTE_HIDDEN) != 0) continue; + + FileInfo fi = new FileInfo + { + Name = currentFileName, + FullName = Path.Combine(FullName, currentFileName), + Length = Convert.Length(findData.nFileSizeHigh, findData.nFileSizeLow), + LastWriteTime = Convert.Time(findData.ftLastWriteTimeHigh, findData.ftLastWriteTimeLow), + fileAttributes = findData.dwFileAttributes + }; + files.Add(fi); + } + while (Win32Native.FindNextFile(findHandle, findData)); + } + + // close the find handle + findHandle.Dispose(); + + return files.ToArray(); + } + } + + public static class Directory + { + public static bool Exists(string path) + { + string fixPath = NameFix.AddLongPathPrefix(path); + + Win32Native.WIN32_FILE_ATTRIBUTE_DATA wIn32FileAttributeData = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA(); + + bool b = Win32Native.GetFileAttributesEx(fixPath, 0, ref wIn32FileAttributeData); + return b && (wIn32FileAttributeData.fileAttributes & Win32Native.FILE_ATTRIBUTE_DIRECTORY) != 0; + } + public static void Move(String sourceDirName, String destDirName) + { + if (sourceDirName == null) + throw new ArgumentNullException("sourceDirName"); + if (sourceDirName.Length == 0) + throw new ArgumentException("Argument_EmptyFileName", "sourceDirName"); + + if (destDirName == null) + throw new ArgumentNullException("destDirName"); + if (destDirName.Length == 0) + throw new ArgumentException("Argument_EmptyFileName", "destDirName"); + + String fullsourceDirName = NameFix.AddLongPathPrefix(sourceDirName); + + String fulldestDirName = NameFix.AddLongPathPrefix(destDirName); + + if (!Win32Native.MoveFile(fullsourceDirName, fulldestDirName)) + { + int hr = Marshal.GetLastWin32Error(); + if (hr == Win32Native.ERROR_FILE_NOT_FOUND) // Source dir not found + { + throw new Exception("ERROR_PATH_NOT_FOUND " + fullsourceDirName); + } + if (hr == Win32Native.ERROR_ACCESS_DENIED) // WinNT throws IOException. This check is for Win9x. We can't change it for backcomp. + { + throw new Exception("UnauthorizedAccess_IODenied_Path" + sourceDirName); + } + } + } + public static void Delete(String path) + { + String fullPath = NameFix.AddLongPathPrefix(path); + + Win32Native.RemoveDirectory(fullPath); + } + + public static void CreateDirectory(String path) + { + if (path == null) + throw new ArgumentNullException("path"); + if (path.Length == 0) + throw new ArgumentException("Argument_PathEmpty"); + + String fullPath = NameFix.AddLongPathPrefix(path); + + Win32Native.CreateDirectory(fullPath, IntPtr.Zero); + } + } + + public static class File + { + public static bool Exists(string path) + { + string fixPath = NameFix.AddLongPathPrefix(path); + + Win32Native.WIN32_FILE_ATTRIBUTE_DATA wIn32FileAttributeData = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA(); + + bool b = Win32Native.GetFileAttributesEx(fixPath, 0, ref wIn32FileAttributeData); + return b && (wIn32FileAttributeData.fileAttributes & Win32Native.FILE_ATTRIBUTE_DIRECTORY) == 0; + } + public static void Copy(String sourceFileName, string destfileName) + { + Copy(sourceFileName, destfileName, true); + } + public static void Copy(String sourceFileName, String destFileName, bool overwrite) + { + if (sourceFileName == null || destFileName == null) + throw new ArgumentNullException((sourceFileName == null ? "sourceFileName" : "destFileName"), "ArgumentNull_FileName"); + if (sourceFileName.Length == 0 || destFileName.Length == 0) + throw new ArgumentException("Argument_EmptyFileName", (sourceFileName.Length == 0 ? "sourceFileName" : "destFileName")); + + String fullSourceFileName = NameFix.AddLongPathPrefix(sourceFileName); + String fullDestFileName = NameFix.AddLongPathPrefix(destFileName); + + bool r = Win32Native.CopyFile(fullSourceFileName, fullDestFileName, !overwrite); + if (!r) + { + // Save Win32 error because subsequent checks will overwrite this HRESULT. + int errorCode = Marshal.GetLastWin32Error(); + String fileName = destFileName; + + /* + if (errorCode != Win32Native.ERROR_FILE_EXISTS) + { + // For a number of error codes (sharing violation, path + // not found, etc) we don't know if the problem was with + // the source or dest file. Try reading the source file. + using (SafeFileHandle handle = Win32Native.UnsafeCreateFile(fullSourceFileName, FileStream.GENERIC_READ, FileShare.Read, null, FileMode.Open, 0, IntPtr.Zero)) + { + if (handle.IsInvalid) + fileName = sourceFileName; + } + + if (errorCode == Win32Native.ERROR_ACCESS_DENIED) + { + if (Directory.InternalExists(fullDestFileName)) + throw new IOException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Arg_FileIsDirectory_Name"), destFileName), Win32Native.ERROR_ACCESS_DENIED, fullDestFileName); + } + } + + __Error.WinIOError(errorCode, fileName); + + */ + } + } + public static void Move(String sourceFileName, String destFileName) + { + if (sourceFileName == null || destFileName == null) + throw new ArgumentNullException((sourceFileName == null ? "sourceFileName" : "destFileName"), "ArgumentNull_FileName"); + if (sourceFileName.Length == 0 || destFileName.Length == 0) + throw new ArgumentException("Argument_EmptyFileName", (sourceFileName.Length == 0 ? "sourceFileName" : "destFileName")); + + String fullSourceFileName = NameFix.AddLongPathPrefix(sourceFileName); + String fullDestFileName = NameFix.AddLongPathPrefix(destFileName); + + if (!Exists(fullSourceFileName)) + throw new Exception("ERROR_FILE_NOT_FOUND" + fullSourceFileName); + + if (!Win32Native.MoveFile(fullSourceFileName, fullDestFileName)) + { + int hr = Marshal.GetLastWin32Error(); + throw new Exception("ERROR_MOVING_FILE. Error Code ("+hr+")"); + } + } + public static void Delete(String path) + { + string fixPath = NameFix.AddLongPathPrefix(path); + + if (!Win32Native.DeleteFile(fixPath)) + { + int hr = Marshal.GetLastWin32Error(); + if (hr != Win32Native.ERROR_FILE_NOT_FOUND) + throw new Exception("Error while deleting file :" + path); + } + } + + public static bool SetAttributes(String path, FileAttributes fileAttributes) + { + String fullPath = NameFix.AddLongPathPrefix(path); + return Win32Native.SetFileAttributes(fullPath, (int)fileAttributes); + } + + + private const int ERROR_INVALID_PARAMETER = 87; + private const int ERROR_ACCESS_DENIED = 0x5; + } + + public static class Path + { + public static readonly char DirectorySeparatorChar = '\\'; + public static readonly char AltDirectorySeparatorChar = '/'; + public static readonly char VolumeSeparatorChar = ':'; + + public static string GetExtension(String path) + { + return System.IO.Path.GetExtension(path); + } + public static string Combine(string path1, string path2) + { + if (path1 == null || path2 == null) + throw new ArgumentNullException((path1 == null) ? "path1" : "path2"); + //CheckInvalidPathChars(path1); + //CheckInvalidPathChars(path2); + + if (path2.Length == 0) + return path1; + + if (path1.Length == 0) + return path2; + + if (IsPathRooted(path2)) + return path2; + + char ch = path1[path1.Length - 1]; + if (ch != DirectorySeparatorChar && ch != AltDirectorySeparatorChar && ch != VolumeSeparatorChar) + return path1 + DirectorySeparatorChar + path2; + return path1 + path2; + } + private static bool IsPathRooted(String path) + { + if (path != null) + { + //CheckInvalidPathChars(path); + + int length = path.Length; + if ( + (length >= 1 && (path[0] == DirectorySeparatorChar || + path[0] == AltDirectorySeparatorChar)) || + (length >= 2 && path[1] == VolumeSeparatorChar) + ) return true; + } + return false; + } + /* + private static void CheckInvalidPathChars(string path) + { + for (int index = 0; index < path.Length; ++index) + { + int num = path[index]; + switch (num) + { + case 34: + case 60: + case 62: + case 124: + ReportError.SendErrorMessage("Invalid Character " + num + " in filename " + path); + continue; + default: + if (num >= 32) + continue; + + goto case 34; + } + } + } + */ + + public static string GetFileNameWithoutExtension(string path) + { + return System.IO.Path.GetFileNameWithoutExtension(path); + } + + public static string GetFileName(String path) + { + return System.IO.Path.GetFileName(path); + } + public static String GetDirectoryName(String path) + { + if (path != null) + { + int root = GetRootLength(path); + int i = path.Length; + if (i > root) + { + i = path.Length; + if (i == root) return null; + while (i > root && path[--i] != DirectorySeparatorChar && path[i] != AltDirectorySeparatorChar) ; + return path.Substring(0, i); + } + } + return null; + } + + private static int GetRootLength(String path) + { + int i = 0; + int length = path.Length; + + if (length >= 1 && (IsDirectorySeparator(path[0]))) + { + // handles UNC names and directories off current drive's root. + i = 1; + if (length >= 2 && (IsDirectorySeparator(path[1]))) + { + i = 2; + int n = 2; + while (i < length && ((path[i] != DirectorySeparatorChar && path[i] != AltDirectorySeparatorChar) || --n > 0)) i++; + } + } + else if (length >= 2 && path[1] == VolumeSeparatorChar) + { + // handles A:\foo. + i = 2; + if (length >= 3 && (IsDirectorySeparator(path[2]))) i++; + } + return i; + } + private static bool IsDirectorySeparator(char c) + { + return (c == DirectorySeparatorChar || c == AltDirectorySeparatorChar); + } + + } + + + public static class FileStream + { + private const uint GENERIC_READ = 0x80000000; + private const uint GENERIC_WRITE = 0x40000000; + + private const uint FILE_ATTRIBUTE_NORMAL = 0x80; + + // errorMessage = new Win32Exception(errorCode).Message; + + public static int OpenFileRead(string path, out System.IO.Stream stream) + { + + string filename = NameFix.AddLongPathPrefix(path); + SafeFileHandle hFile = Win32Native.CreateFile(filename, + GENERIC_READ, + System.IO.FileShare.Read, + IntPtr.Zero, + System.IO.FileMode.Open, + FILE_ATTRIBUTE_NORMAL, + IntPtr.Zero); + + if (hFile.IsInvalid) + { + stream = null; + return Marshal.GetLastWin32Error(); + } + stream = new System.IO.FileStream(hFile, System.IO.FileAccess.Read); + return 0; + } + + public static int OpenFileWrite(string path, out System.IO.Stream stream) + { + string filename = NameFix.AddLongPathPrefix(path); + SafeFileHandle hFile = Win32Native.CreateFile(filename, + GENERIC_WRITE, + System.IO.FileShare.None, + IntPtr.Zero, + System.IO.FileMode.Create, + FILE_ATTRIBUTE_NORMAL, + IntPtr.Zero); + + if (hFile.IsInvalid) + { + stream = null; + return Marshal.GetLastWin32Error(); + } + + stream = new System.IO.FileStream(hFile, System.IO.FileAccess.Write); + return 0; + } + + + } + + public static class NameFix + { + public static string GetShortPath(string path) + { + int remove = 0; + string retPath; + if (path.StartsWith(@"\\")) + { + retPath = @"\\?\UNC\" + path.Substring(2); + remove = 8; + } + else + { + retPath = path; + if (path.Substring(1, 1) != ":") + retPath = Path.Combine(System.IO.Directory.GetCurrentDirectory(), retPath); + + retPath = cleandots(retPath); + retPath = @"\\?\" + retPath; + remove = 4; + } + + + const int MAX_PATH = 300; + var shortPath = new StringBuilder(MAX_PATH); + Win32Native.GetShortPathName(retPath, shortPath, MAX_PATH); + retPath = shortPath.ToString(); + + retPath = retPath.Substring(remove); + if (remove == 8) retPath = "\\" + retPath; + + return retPath; + } + + + + internal static string AddLongPathPrefix(string path) + { + if (string.IsNullOrEmpty(path) || path.StartsWith(@"\\?\")) + return path; + + if (path.StartsWith(@"\\")) + return @"\\?\UNC\" + path.Substring(2); + + string retPath = path; + if (path.Substring(1, 1) != ":") + retPath = Path.Combine(System.IO.Directory.GetCurrentDirectory(), retPath); + + retPath = cleandots(retPath); + + return @"\\?\" + retPath; + + } + + private static string cleandots(string path) + { + string retPath = path; + while (retPath.Contains(@"\..\")) + { + int index = retPath.IndexOf(@"\..\"); + string path1 = retPath.Substring(0, index); + string path2 = retPath.Substring(index + 4); + + int path1Back = path1.LastIndexOf(@"\"); + + retPath = path1.Substring(0, path1Back + 1) + path2; + } + return retPath; + + } + } +} diff --git a/ROMVault2/IO/Win32Native.cs b/ROMVault2/IO/Win32Native.cs new file mode 100644 index 0000000..400c183 --- /dev/null +++ b/ROMVault2/IO/Win32Native.cs @@ -0,0 +1,181 @@ +/****************************************************** + * ROMVault2 is written by Gordon J. * + * Contact gordon@romvault.com * + * Copyright 2014 * + ******************************************************/ + +using System; +using System.IO; +using System.Runtime.ConstrainedExecution; +using System.Runtime.InteropServices; +using System.Runtime.Versioning; +using System.Security.Permissions; +using System.Text; +using Microsoft.Win32.SafeHandles; + +namespace ROMVault2.IO +{ + internal static class Win32Native + { + + private const String KERNEL32 = "kernel32.dll"; + + public const int FILE_ATTRIBUTE_DIRECTORY = 0x00000010; + public const int FILE_ATTRIBUTE_HIDDEN = 0x00000002; + + + internal const int ERROR_FILE_NOT_FOUND = 0x2; + internal const int ERROR_ACCESS_DENIED = 0x5; + internal const int ERROR_FILE_EXISTS = 0x50; + + + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + [BestFitMapping(false)] + internal class WIN32_FIND_DATA + { + internal int dwFileAttributes = 0; + internal uint ftCreationTimeLow; + internal uint ftCreationTimeHigh; + internal uint ftLastAccessTimeLow; + internal uint ftLastAccessTimeHigh; + internal uint ftLastWriteTimeLow; + internal uint ftLastWriteTimeHigh; + internal int nFileSizeHigh = 0; + internal int nFileSizeLow = 0; + internal int dwReserved0 = 0; + internal int dwReserved1 = 0; + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] + internal String cFileName = null; + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)] + internal String cAlternateFileName = null; + } + + [StructLayout(LayoutKind.Sequential), Serializable] + internal struct WIN32_FILE_ATTRIBUTE_DATA + { + internal int fileAttributes; + internal uint ftCreationTimeLow; + internal uint ftCreationTimeHigh; + internal uint ftLastAccessTimeLow; + internal uint ftLastAccessTimeHigh; + internal uint ftLastWriteTimeLow; + internal uint ftLastWriteTimeHigh; + internal int fileSizeHigh; + internal int fileSizeLow; + } + + [DllImport(KERNEL32, SetLastError = true, CharSet = CharSet.Auto, BestFitMapping = false)] + [ResourceExposure(ResourceScope.None)] + internal static extern bool GetFileAttributesEx(String fileName, int fileInfoLevel, ref WIN32_FILE_ATTRIBUTE_DATA lpFileInformation); + + [DllImport(KERNEL32, SetLastError = true, CharSet = CharSet.Auto, BestFitMapping = false)] + [ResourceExposure(ResourceScope.None)] + internal static extern SafeFindHandle FindFirstFile(String fileName, [In, Out] WIN32_FIND_DATA data); + + [DllImport(KERNEL32, SetLastError = true, CharSet = CharSet.Auto, BestFitMapping = false)] + [ResourceExposure(ResourceScope.None)] + internal static extern bool FindNextFile(SafeFindHandle hndFindFile, [In, Out, MarshalAs(UnmanagedType.LPStruct)] WIN32_FIND_DATA lpFindFileData); + + [DllImport(KERNEL32)] + [ResourceExposure(ResourceScope.None)] + [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] + internal static extern bool FindClose(IntPtr handle); + + [DllImport(KERNEL32, SetLastError = true, CharSet = CharSet.Auto, BestFitMapping = false)] + [ResourceExposure(ResourceScope.Machine)] + internal static extern SafeFileHandle CreateFile(String lpFileName, + uint dwDesiredAccess, FileShare dwShareMode, + IntPtr securityAttrs, FileMode dwCreationDisposition, + uint dwFlagsAndAttributes, IntPtr hTemplateFile); + + [DllImport(KERNEL32, SetLastError = true, CharSet = CharSet.Auto, BestFitMapping = false)] + [ResourceExposure(ResourceScope.Machine)] + internal static extern bool CreateDirectory(String path, IntPtr lpSecurityAttributes); + + [DllImport(KERNEL32, SetLastError = true, CharSet = CharSet.Auto, BestFitMapping = false)] + [ResourceExposure(ResourceScope.Machine)] + internal static extern bool RemoveDirectory(String path); + + + + [DllImport(KERNEL32, SetLastError = true, CharSet = CharSet.Auto, BestFitMapping = false)] + [ResourceExposure(ResourceScope.Machine)] + internal static extern bool CopyFile(String src, String dst, bool failIfExists); + + [DllImport(KERNEL32, SetLastError = true, CharSet = CharSet.Auto, BestFitMapping = false)] + [ResourceExposure(ResourceScope.Machine)] + internal static extern bool MoveFile(String src, String dst); + + [DllImport(KERNEL32, SetLastError = true, CharSet = CharSet.Auto, BestFitMapping = false)] + [ResourceExposure(ResourceScope.Machine)] + internal static extern bool DeleteFile(String path); + + [DllImport(KERNEL32, SetLastError = true, CharSet = CharSet.Auto, BestFitMapping = false)] + [ResourceExposure(ResourceScope.None)] + internal static extern bool SetFileAttributes(String name, int attr); + + + [DllImport(KERNEL32, SetLastError = true, CharSet = CharSet.Auto, BestFitMapping = false)] + [ResourceExposure(ResourceScope.Machine)] + internal static extern int GetShortPathName( + [MarshalAs(UnmanagedType.LPTStr)] string path, + [MarshalAs(UnmanagedType.LPTStr)] StringBuilder shortPath, + int shortPathLength + ); + + } + + internal sealed class SafeFindHandle : SafeHandleZeroOrMinusOneIsInvalid + { + [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)] + internal SafeFindHandle() : base(true) { } + + override protected bool ReleaseHandle() + { + return Win32Native.FindClose(handle); + } + } + + + + internal static class Convert + { + private const long TicksPerMillisecond = 10000; + private const long TicksPerSecond = TicksPerMillisecond * 1000; + private const long TicksPerMinute = TicksPerSecond * 60; + private const long TicksPerHour = TicksPerMinute * 60; + private const long TicksPerDay = TicksPerHour * 24; + + // Number of days in a non-leap year + private const int DaysPerYear = 365; + // Number of days in 4 years + private const int DaysPer4Years = DaysPerYear * 4 + 1; + // Number of days in 100 years + private const int DaysPer100Years = DaysPer4Years * 25 - 1; + // Number of days in 400 years + private const int DaysPer400Years = DaysPer100Years * 4 + 1; + + // Number of days from 1/1/0001 to 12/31/1600 + private const int DaysTo1601 = DaysPer400Years * 4; + public const long FileTimeOffset = DaysTo1601 * TicksPerDay; + + + // Number of days from 1/1/0001 to 12/31/9999 + private const int DaysTo10000 = DaysPer400Years * 25 - 366; + private const long MinTicks = 0; + private const long MaxTicks = DaysTo10000 * TicksPerDay - 1; + + + public static long Length(int high, int low) + { + return ((long) high) << 32 | ((long) low & 0xFFFFFFFFL); + } + + public static long Time(uint high, uint low) + { + return ((long)high << 32) | low; + } + + } +} diff --git a/ROMVault2/Program.cs b/ROMVault2/Program.cs new file mode 100644 index 0000000..b7f9035 --- /dev/null +++ b/ROMVault2/Program.cs @@ -0,0 +1,54 @@ +/****************************************************** + * ROMVault2 is written by Gordon J. * + * Contact gordon@romvault.com * + * Copyright 2014 * + ******************************************************/ +using System; +using System.Text; +using System.Threading; +using System.Windows.Forms; + +namespace ROMVault2 +{ + static class Program + { + //public static UsernamePassword Up; + public static readonly Encoding Enc = Encoding.GetEncoding(28591); + public const string Version = "2.1"; + public const int SubVersion = 25; + + public static string ErrorMessage; + public static string URL; + + public static SynchronizationContext SyncCont; + + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main() + { + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + +#if !DEBUG + Application.ThreadException += ReportError.UnhandledExceptionHandler; +#endif + + FrmSplashScreen progress = new FrmSplashScreen(); + progress.ShowDialog(); + + progress.Dispose(); + + if (!String.IsNullOrEmpty(ErrorMessage)) + { + MessageBox.Show(ErrorMessage); + if (!String.IsNullOrEmpty(URL)) + System.Diagnostics.Process.Start(URL); + return; + } + + Application.Run(new FrmMain()); + } + } +} diff --git a/ROMVault2/Properties/AssemblyInfo.cs b/ROMVault2/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..9e1d7e2 --- /dev/null +++ b/ROMVault2/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("ROMVault2")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Microsoft")] +[assembly: AssemblyProduct("ROMVault2")] +[assembly: AssemblyCopyright("Copyright © Microsoft 2010")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("12c7682b-3530-4e92-a696-94a92cf3fedf")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/ROMVault2/Properties/Resources.Designer.cs b/ROMVault2/Properties/Resources.Designer.cs new file mode 100644 index 0000000..0b9414f --- /dev/null +++ b/ROMVault2/Properties/Resources.Designer.cs @@ -0,0 +1,741 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.34003 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace ROMVault2.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ROMVault2.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to , . + /// + internal static string Comma { + get { + return ResourceManager.GetString("Comma", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Error Keyword . + /// + internal static string DatCmpReader_LoadDirFromDat_Error_Keyword { + get { + return ResourceManager.GetString("DatCmpReader_LoadDirFromDat_Error_Keyword", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to not know in dir. + /// + internal static string DatCmpReader_LoadDirFromDat_not_know_in_dir { + get { + return ResourceManager.GetString("DatCmpReader_LoadDirFromDat_not_know_in_dir", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Name not found as first object in ( ). + /// + internal static string DatCmpReader_LoadGameFromDat_Name_not_found_as_first_object_in { + get { + return ResourceManager.GetString("DatCmpReader_LoadGameFromDat_Name_not_found_as_first_object_in", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to ( not found after game. + /// + internal static string DatCmpReader_LoadGameFromDat_not_found_after_game { + get { + return ResourceManager.GetString("DatCmpReader_LoadGameFromDat_not_found_after_game", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to ' not known in game. + /// + internal static string DatCmpReader_LoadGameFromDat_not_known_in_game { + get { + return ResourceManager.GetString("DatCmpReader_LoadGameFromDat_not_known_in_game", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to ( not found after clrmamepro. + /// + internal static string DatCmpReader_LoadHeaderFromDat_not_found_after_clrmamepro { + get { + return ResourceManager.GetString("DatCmpReader_LoadHeaderFromDat_not_found_after_clrmamepro", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to ' not known in clrmamepro. + /// + internal static string DatCmpReader_LoadHeaderFromDat_not_known_in_clrmamepro { + get { + return ResourceManager.GetString("DatCmpReader_LoadHeaderFromDat_not_known_in_clrmamepro", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to ( not found after rom. + /// + internal static string DatCmpReader_LoadRomFromDat_not_found_after_rom { + get { + return ResourceManager.GetString("DatCmpReader_LoadRomFromDat_not_found_after_rom", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to ' not known in rom. + /// + internal static string DatCmpReader_LoadRomFromDat_not_known_in_rom { + get { + return ResourceManager.GetString("DatCmpReader_LoadRomFromDat_not_known_in_rom", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Error: key word '. + /// + internal static string DatCmpReader_ReadDat_Error_keyword { + get { + return ResourceManager.GetString("DatCmpReader_ReadDat_Error_keyword", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to ' not known. + /// + internal static string DatCmpReader_ReadDat_not_known { + get { + return ResourceManager.GetString("DatCmpReader_ReadDat_not_known", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Error dat found on item listed as not in dat. + /// + internal static string DatUpdate_ClearOldDats_Error_dat_found_on_item_listed_as_not_in_dat { + get { + return ResourceManager.GetString("DatUpdate_ClearOldDats_Error_dat_found_on_item_listed_as_not_in_dat", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Got to a non dir when checking Dir's for dats to remove. + /// + internal static string DatUpdate_ClearOldDats_Got_to_a_non_dir_when_checking_Dir_s_for_dats_to_remove { + get { + return ResourceManager.GetString("DatUpdate_ClearOldDats_Got_to_a_non_dir_when_checking_Dir_s_for_dats_to_remove", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to This is bad, rBase.Dat is set to a dat, and rBase.DatStatus is not. + /// + internal static string DatUpdate_ClearOldDats_This_is_bad__rBase_Dat_is_set_to_a_dat_and_rBase_DatStatus_is_not { + get { + return ResourceManager.GetString("DatUpdate_ClearOldDats_This_is_bad__rBase_Dat_is_set_to_a_dat_and_rBase_DatStatus" + + "_is_not", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Unknown File Delete Test . + /// + internal static string DatUpdate_ClearOldDats_Unknown_File_Delete_Test { + get { + return ResourceManager.GetString("DatUpdate_ClearOldDats_Unknown_File_Delete_Test", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Unknown file setup. + /// + internal static string DatUpdate_ClearOldDats_Unknown_file_setup { + get { + return ResourceManager.GetString("DatUpdate_ClearOldDats_Unknown_file_setup", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to This should also never happen.. + /// + internal static string DatUpdate_ClearRemovedDatsFromTheDb_This_should_also_never_happen { + get { + return ResourceManager.GetString("DatUpdate_ClearRemovedDatsFromTheDb_This_should_also_never_happen", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Error in Logic. + /// + internal static string DatUpdate_MergeInDat_Error_in_Logic { + get { + return ResourceManager.GetString("DatUpdate_MergeInDat_Error_in_Logic", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Unkown Update Dat Status . + /// + internal static string DatUpdate_MergeInDat_Unkown_Update_Dat_Status { + get { + return ResourceManager.GetString("DatUpdate_MergeInDat_Unkown_Update_Dat_Status", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Unknown Merge Status. + /// + internal static string DatUpdate_UpdateDatFile_Unknown_Merge_Status { + get { + return ResourceManager.GetString("DatUpdate_UpdateDatFile_Unknown_Merge_Status", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to ' Directory will be ignored.. + /// + internal static string DatUpdate_UpdateDatList_Directory_will_be_ignored { + get { + return ResourceManager.GetString("DatUpdate_UpdateDatList_Directory_will_be_ignored", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Empty Directories found in '. + /// + internal static string DatUpdate_UpdateDatList_Empty_Directories_found_in { + get { + return ResourceManager.GetString("DatUpdate_UpdateDatList_Empty_Directories_found_in", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to ERROR Deleting a DAT that should already be deleted. + /// + internal static string DatUpdate_UpdateDatList_ERROR_Deleting_a_DAT_that_should_already_be_deleted { + get { + return ResourceManager.GetString("DatUpdate_UpdateDatList_ERROR_Deleting_a_DAT_that_should_already_be_deleted", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Not Found.. + /// + internal static string DatUpdate_UpdateDatList_Not_Found { + get { + return ResourceManager.GetString("DatUpdate_UpdateDatList_Not_Found", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Path: . + /// + internal static string DatUpdate_UpdateDatList_Path { + get { + return ResourceManager.GetString("DatUpdate_UpdateDatList_Path", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to RomValue Scan Error:. + /// + internal static string DatUpdate_UpdateDatList_RomValue_Scan_Error { + get { + return ResourceManager.GetString("DatUpdate_UpdateDatList_RomValue_Scan_Error", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Data Cache version is out of date you should now rescan your dat directory and roms directory.. + /// + internal static string DB_Read_Data_Cache_version_is_out_of_date_you_should_now_rescan_your_dat_directory_and_roms_directory_ { + get { + return ResourceManager.GetString("DB_Read_Data_Cache_version_is_out_of_date_you_should_now_rescan_your_dat_director" + + "y_and_roms_directory_", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Error in File Scanning Code.. + /// + internal static string FileScanning_CheckADir_Error_in_File_Scanning_Code { + get { + return ResourceManager.GetString("FileScanning_CheckADir_Error_in_File_Scanning_Code", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Error Case . + /// + internal static string FindFixes_ListCheck_Error_Case { + get { + return ResourceManager.GetString("FindFixes_ListCheck_Error_Case", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Nothing Set For . + /// + internal static string FindFixes_ListCheck_Nothing_Set_For { + get { + return ResourceManager.GetString("FindFixes_ListCheck_Nothing_Set_For", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Unknown test status . + /// + internal static string FindFixes_ListCheck_Unknown_test_status { + get { + return ResourceManager.GetString("FindFixes_ListCheck_Unknown_test_status", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Unknown result type. + /// + internal static string FixFiles_FixDirChildren_Unknown_result_type { + get { + return ResourceManager.GetString("FixFiles_FixDirChildren_Unknown_result_type", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to But the case of the unknown file is wrong. Rescan and try agian.. + /// + internal static string FixFiles_FixFile__But_the_case_of_the_unknown_file_is_wrong_Rescan_and_try_agian { + get { + return ResourceManager.GetString("FixFiles_FixFile__But_the_case_of_the_unknown_file_is_wrong_Rescan_and_try_agian", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Did you manualy fix this file without rescanning?. + /// + internal static string FixFiles_FixFile__Did_you_manualy_fix_this_file_without_rescanning { + get { + return ResourceManager.GetString("FixFiles_FixFile__Did_you_manualy_fix_this_file_without_rescanning", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Trying to fix a file that already exists . + /// + internal static string FixFiles_FixFile_Trying_to_fix_a_file_that_already_exists { + get { + return ResourceManager.GetString("FixFiles_FixFile_Trying_to_fix_a_file_that_already_exists", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Unable to Find the file used to fix . + /// + internal static string FixFiles_FixFile_Unable_to_Find_the_file_used_to_fix { + get { + return ResourceManager.GetString("FixFiles_FixFile_Unable_to_Find_the_file_used_to_fix", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Unknown fix file type . + /// + internal static string FixFiles_FixFile_Unknown_fix_file_type { + get { + return ResourceManager.GetString("FixFiles_FixFile_Unknown_fix_file_type", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Unsupported file Fix. + /// + internal static string FixFiles_FixFile_Unsupported_file_Fix { + get { + return ResourceManager.GetString("FixFiles_FixFile_Unsupported_file_Fix", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to : . + /// + internal static string FixFiles_FixZip_Colon { + get { + return ResourceManager.GetString("FixFiles_FixZip_Colon", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Error finding Fixing Rom, Database is corrupt.. + /// + internal static string FixFiles_FixZip_Error_finding_Fixing_Rom_Database_is_corrupt { + get { + return ResourceManager.GetString("FixFiles_FixZip_Error_finding_Fixing_Rom_Database_is_corrupt", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Error in Fix Rom Status . + /// + internal static string FixFiles_FixZip_Error_in_Fix_Rom_Status { + get { + return ResourceManager.GetString("FixFiles_FixZip_Error_in_Fix_Rom_Status", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Error processing zip . + /// + internal static string FixFiles_FixZip_Error_processing_zip { + get { + return ResourceManager.GetString("FixFiles_FixZip_Error_processing_zip", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to This Delete case should never happen, help . + /// + internal static string FixFiles_FixZip_This_Delete_case_should_never_happen__help { + get { + return ResourceManager.GetString("FixFiles_FixZip_This_Delete_case_should_never_happen__help", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to This Delete case should never happen, you do not delete a rom you collect.. + /// + internal static string FixFiles_FixZip_This_Delete_case_should_never_happen__you_do_not_delete_a_rom_you_collect { + get { + return ResourceManager.GetString("FixFiles_FixZip_This_Delete_case_should_never_happen__you_do_not_delete_a_rom_you" + + "_collect", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Unknown type. + /// + internal static string FixFiles_FixZip_Unknown_type { + get { + return ResourceManager.GetString("FixFiles_FixZip_Unknown_type", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to did you delete it?. + /// + internal static string FixFiles_OpenOriginalZip_did_you_delete_it { + get { + return ResourceManager.GetString("FixFiles_OpenOriginalZip_did_you_delete_it", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to File not found :. + /// + internal static string FixFiles_OpenOriginalZip_File_not_found { + get { + return ResourceManager.GetString("FixFiles_OpenOriginalZip_File_not_found", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to File TimeStamp has changed in file . + /// + internal static string FixFiles_OpenOriginalZip_File_TimeStamp_has_changed_in_file { + get { + return ResourceManager.GetString("FixFiles_OpenOriginalZip_File_TimeStamp_has_changed_in_file", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Found an unknown file :. + /// + internal static string FixFiles_OpenOriginalZip_Found_an_unknown_file { + get { + return ResourceManager.GetString("FixFiles_OpenOriginalZip_Found_an_unknown_file", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Trying to open an unscanned file :. + /// + internal static string FixFiles_OpenOriginalZip_Trying_to_open_an_unscanned_file { + get { + return ResourceManager.GetString("FixFiles_OpenOriginalZip_Trying_to_open_an_unscanned_file", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Unknown File Open Type.. + /// + internal static string FixFiles_OpenOriginalZip_Unknown_File_Open_Type { + get { + return ResourceManager.GetString("FixFiles_OpenOriginalZip_Unknown_File_Open_Type", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Trying to fix unscanned dir's. + /// + internal static string FixFiles_PerformFixes_Trying_to_fix_unscanned_dir_s { + get { + return ResourceManager.GetString("FixFiles_PerformFixes_Trying_to_fix_unscanned_dir_s", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Set ROM DIR. + /// + internal static string FrmMain_DirTreeRvSelected_Set_ROM_DIR { + get { + return ResourceManager.GetString("FrmMain_DirTreeRvSelected_Set_ROM_DIR", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to File Type Missing . + /// + internal static string FrmMain_UpdateRomGrid_File_Type_Missing_ { + get { + return ResourceManager.GetString("FrmMain_UpdateRomGrid_File_Type_Missing_", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Directory Settings. + /// + internal static string FrmSetDir_BtnDeleteSelectedClick_Directory_Settings { + get { + return ResourceManager.GetString("FrmSetDir_BtnDeleteSelectedClick_Directory_Settings", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to RomVault Rom Location. + /// + internal static string FrmSetDir_BtnDeleteSelectedClick_RomVault_Rom_Location { + get { + return ResourceManager.GetString("FrmSetDir_BtnDeleteSelectedClick_RomVault_Rom_Location", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to You cannot delete the . + /// + internal static string FrmSetDir_BtnDeleteSelectedClick_You_cannot_delete_the { + get { + return ResourceManager.GetString("FrmSetDir_BtnDeleteSelectedClick_You_cannot_delete_the", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Please select a folder for This Rom Set. + /// + internal static string FrmSetDir_BtnSetRomLocationClick_Please_select_a_folder_for_This_Rom_Set { + get { + return ResourceManager.GetString("FrmSetDir_BtnSetRomLocationClick_Please_select_a_folder_for_This_Rom_Set", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Edit Existing Directory Mapping. + /// + internal static string FrmSetDir_DataGridGamesDoubleClick_Edit_Existing_Directory_Mapping { + get { + return ResourceManager.GetString("FrmSetDir_DataGridGamesDoubleClick_Edit_Existing_Directory_Mapping", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Please select a folder for DAT Root. + /// + internal static string FrmSettings_BtnDatClick_Please_select_a_folder_for_DAT_Root { + get { + return ResourceManager.GetString("FrmSettings_BtnDatClick_Please_select_a_folder_for_DAT_Root", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to There is a new release download now from . + /// + internal static string Program_Main_There_is_a_new_release_download_now_from { + get { + return ResourceManager.GetString("Program_Main_There_is_a_new_release_download_now_from", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to You are not Authorised to use this program.. + /// + internal static string Program_Main_You_are_not_Authorised_to_use_this_program { + get { + return ResourceManager.GetString("Program_Main_You_are_not_Authorised_to_use_this_program", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to You must have a 'user - <NAME>.xml' file to use RomVault. + /// + internal static string Program_Main_You_must_have_a__user____NAME__xml__file_to_use_RomVault { + get { + return ResourceManager.GetString("Program_Main_You_must_have_a__user____NAME__xml__file_to_use_RomVault", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Close. + /// + internal static string ProgressWindowFix_DoDone_Close { + get { + return ResourceManager.GetString("ProgressWindowFix_DoDone_Close", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Cancelling. + /// + internal static string ProgressWindowFix_OnClosing_Cancelling { + get { + return ResourceManager.GetString("ProgressWindowFix_OnClosing_Cancelling", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Please select a folder for Dats. + /// + internal static string Report_MakeFixFiles_Please_select_a_folder_for_Dats { + get { + return ResourceManager.GetString("Report_MakeFixFiles_Please_select_a_folder_for_Dats", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to , . + /// + internal static string RvBase_Check { + get { + return ResourceManager.GetString("RvBase_Check", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Unknown Error Status File . + /// + internal static string RvBase_Check_Unknown_Error_Status_File { + get { + return ResourceManager.GetString("RvBase_Check_Unknown_Error_Status_File", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Dat found without an index. + /// + internal static string RvBase_Read_Dat_found_without_an_index { + get { + return ResourceManager.GetString("RvBase_Read_Dat_found_without_an_index", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Unknown Set Got Status . + /// + internal static string RvBase_SetGot_Unknown_Set_Got_Status { + get { + return ResourceManager.GetString("RvBase_SetGot_Unknown_Set_Got_Status", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Clearing Dir with a dat list. + /// + internal static string RvDir_ClearDat_Clearing_Dir_with_a_dat_list { + get { + return ResourceManager.GetString("RvDir_ClearDat_Clearing_Dir_with_a_dat_list", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Setting Dir with a dat list. + /// + internal static string RvDir_SetDat_Setting_Dir_with_a_dat_list { + get { + return ResourceManager.GetString("RvDir_SetDat_Setting_Dir_with_a_dat_list", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Count went negative.. + /// + internal static string RvDir_UpdateArrGotStatus_Count_went_negative { + get { + return ResourceManager.GetString("RvDir_UpdateArrGotStatus_Count_went_negative", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Unknown Reset Got status . + /// + internal static string Utils_ResetGotStatus_Unknown_Reset_Got_status { + get { + return ResourceManager.GetString("Utils_ResetGotStatus_Unknown_Reset_Got_status", resourceCulture); + } + } + } +} diff --git a/ROMVault2/Properties/Resources.resx b/ROMVault2/Properties/Resources.resx new file mode 100644 index 0000000..26249ad --- /dev/null +++ b/ROMVault2/Properties/Resources.resx @@ -0,0 +1,345 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Error dat found on item listed as not in dat + + + This is bad, rBase.Dat is set to a dat, and rBase.DatStatus is not + + + Unknown File Delete Test + + + Got to a non dir when checking Dir's for dats to remove + + + Unknown file setup + + + Path: + + + Not Found. + + + Empty Directories found in ' + + + ' Directory will be ignored. + + + RomValue Scan Error: + + + Error: key word ' + + + ' not known + + + ( not found after clrmamepro + + + ' not known in clrmamepro + + + ( not found after game + + + Name not found as first object in ( ) + + + ' not known in game + + + ( not found after rom + + + ' not known in rom + + + Trying to fix a file that already exists + + + Did you manualy fix this file without rescanning? + + + But the case of the unknown file is wrong. Rescan and try agian. + + + Unable to Find the file used to fix + + + Unsupported file Fix + + + Unknown fix file type + + + Error finding Fixing Rom, Database is corrupt. + + + Unknown type + + + This Delete case should never happen, you do not delete a rom you collect. + + + This Delete case should never happen, help + + + Unknown File Open Type. + + + File TimeStamp has changed in file + + + File not found : + + + Trying to open an unscanned file : + + + Found an unknown file : + + + did you delete it? + + + Trying to fix unscanned dir's + + + Error in Logic + + + Unkown Update Dat Status + + + File Type Missing + + + Dat found without an index + + + Clearing Dir with a dat list + + + Setting Dir with a dat list + + + Data Cache version is out of date you should now rescan your dat directory and roms directory. + + + Cancelling + + + Close + + + Unknown test status + + + , + + + Error Case + + + Nothing Set For + + + Unknown Reset Got status + + + Please select a folder for This Rom Set + + + You cannot delete the + + + Directory Settings + + + RomVault Rom Location + + + Edit Existing Directory Mapping + + + Please select a folder for DAT Root + + + Unknown Error Status File + + + , + + + Unknown Set Got Status + + + Count went negative. + + + This should also never happen. + + + Unknown Merge Status + + + Unknown result type + + + Error in Fix Rom Status + + + : + + + Error in File Scanning Code. + + + Error Keyword + + + not know in dir + + + You must have a 'user - <NAME>.xml' file to use RomVault + + + You are not Authorised to use this program. + + + There is a new release download now from + + + ERROR Deleting a DAT that should already be deleted + + + Error processing zip + + + Please select a folder for Dats + + + Set ROM DIR + + \ No newline at end of file diff --git a/ROMVault2/Properties/Settings.Designer.cs b/ROMVault2/Properties/Settings.Designer.cs new file mode 100644 index 0000000..8d7048d --- /dev/null +++ b/ROMVault2/Properties/Settings.Designer.cs @@ -0,0 +1,26 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.34003 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace ROMVault2.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "12.0.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default { + get { + return defaultInstance; + } + } + } +} diff --git a/ROMVault2/Properties/Settings.settings b/ROMVault2/Properties/Settings.settings new file mode 100644 index 0000000..abf36c5 --- /dev/null +++ b/ROMVault2/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + diff --git a/ROMVault2/ROMVault2.csproj b/ROMVault2/ROMVault2.csproj new file mode 100644 index 0000000..3af2556 --- /dev/null +++ b/ROMVault2/ROMVault2.csproj @@ -0,0 +1,337 @@ + + + + Debug + x86 + 8.0.30703 + 2.0 + {437E12AB-46F3-4A75-A3D5-6C524B5A79B5} + WinExe + Properties + ROMVault2 + ROMVault21 + v3.5 + + + 512 + false + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + true + + + x86 + true + full + false + ..\..\Stage\ + TRACE;DEBUG;UNMANAGED, COMPRESS, LZMA_STREAM, DOTNET20 + prompt + 4 + false + false + + + x86 + pdbonly + true + ..\..\Stage\ + TRACE + prompt + 4 + false + + + true + ..\..\Stage\ + TRACE;DEBUG;UNMANAGED, COMPRESS, LZMA_STREAM, DOTNET20 + full + x86 + ..\..\Stage2\ROMVault2.exe.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + false + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false + + + ..\..\Stage\ + TRACE;UNMANAGED, COMPRESS, LZMA_STREAM, DOTNET20 + true + pdbonly + AnyCPU + bin\Release\ROMVault2.exe.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false + + + chip.ico + + + + + + + + + + + + + + + + + + + + + Form + + + FrmProgressWindowFix.cs + + + + + + + + + + + + + + + + + + + + + Form + + + frmHelpAbout.cs + + + Form + + + frmKey.cs + + + Form + + + FrmProgressWindow.cs + + + Form + + + FrmRegistration.cs + + + Form + + + frmSetDir.cs + + + Form + + + frmSettings.cs + + + + Form + + + frmShowError.cs + + + Form + + + frmSplashScreen.cs + + + + True + True + rvImages1.resx + + + + UserControl + + + rvTree.cs + + + True + True + Reference.svcmap + + + + + Form + + + FrmMain.cs + + + + + + + + + + + + + + + + + + + + + + + + + frmHelpAbout.cs + + + frmKey.cs + Designer + + + FrmMain.cs + + + FrmProgressWindow.cs + + + FrmProgressWindowFix.cs + + + FrmRegistration.cs + + + frmSettings.cs + Designer + + + frmShowError.cs + + + frmSplashScreen.cs + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + True + Resources.resx + True + + + ResXFileCodeGenerator + rvImages1.Designer.cs + Designer + + + rvTree.cs + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + Designer + + + + Designer + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + False + Windows Installer 3.1 + true + + + + + PreserveNewest + + + + + WCF Proxy Generator + Reference.cs + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ROMVault2/RepairStatus.cs b/ROMVault2/RepairStatus.cs new file mode 100644 index 0000000..0e05480 --- /dev/null +++ b/ROMVault2/RepairStatus.cs @@ -0,0 +1,318 @@ +/****************************************************** + * ROMVault2 is written by Gordon J. * + * Contact gordon@romvault.com * + * Copyright 2014 * + ******************************************************/ + +using System; +using System.Collections.Generic; +using ROMVault2.RvDB; + +namespace ROMVault2 +{ + + public enum RepStatus + { + + // Scanning Status: + Error, + + UnSet, + + UnScanned, + + DirCorrect, + DirMissing, + DirUnknown, + DirInToSort, + DirCorrupt, + + + Missing, // a files or directory from a DAT that we do not have + Correct, // a files or directory from a DAT that we have + NotCollected, // a file from a DAT that is not collected that we do not have (either a merged or bad file.) + UnNeeded, // a file from a DAT that is not collected that we do have, and so do not need. (a merged file in a child set) + Unknown, // a file that is not in a DAT + InToSort, // a file that is in the ToSort directory + + Corrupt, // either a Zip file that is corrupt, or a Zipped file that is corrupt + Ignore, // a file found in the ignore list + + + // Fix Status: + CanBeFixed, // a missing file that can be fixed from another file. (Will be set to correct once it has been corrected) + MoveToSort, // a file that is not in any DAT (Unknown) and should be moved to ToSort + Delete, // a file that can be deleted + NeededForFix, // a file that is Unknown where it is, but is needed somewhere else. + Rename, // a file that is Unknown where it is, but is needed with other name inside the same Zip. + + CorruptCanBeFixed, // a corrupt file that can be replaced and fixed from another file. + MoveToCorrupt, // a corrupt file that should just be moved out the way to a corrupt directory in ToSort. + + Deleted, // this is a temporary value used while fixing sets, this value should never been seen. + + EndValue + + } + + public static class RepairStatus + { + public static List[, ,] StatusCheck; + + public static RepStatus[] DisplayOrder; + + + public static void InitStatusCheck() + { + StatusCheck = new List + [ + Enum.GetValues(typeof(FileType)).Length, + Enum.GetValues(typeof(DatStatus)).Length, + Enum.GetValues(typeof(GotStatus)).Length + ]; + + //sorted alphabetically + StatusCheck[(int)FileType.Dir, (int)DatStatus.InDatCollect, (int)GotStatus.Got] = new List { RepStatus.DirCorrect }; + StatusCheck[(int)FileType.Dir, (int)DatStatus.InDatCollect, (int)GotStatus.NotGot] = new List { RepStatus.DirMissing }; + StatusCheck[(int)FileType.Dir, (int)DatStatus.InToSort, (int)GotStatus.Got] = new List { RepStatus.DirInToSort }; + StatusCheck[(int)FileType.Dir, (int)DatStatus.InToSort, (int)GotStatus.NotGot] = new List { RepStatus.Deleted }; + StatusCheck[(int)FileType.Dir, (int)DatStatus.NotInDat, (int)GotStatus.Got] = new List { RepStatus.DirUnknown }; + StatusCheck[(int)FileType.Dir, (int)DatStatus.NotInDat, (int)GotStatus.NotGot] = new List { RepStatus.Deleted }; + + StatusCheck[(int)FileType.Zip, (int)DatStatus.InDatCollect, (int)GotStatus.Got] = new List { RepStatus.DirCorrect }; + StatusCheck[(int)FileType.Zip, (int)DatStatus.InDatCollect, (int)GotStatus.Corrupt] = new List { RepStatus.DirCorrupt }; + StatusCheck[(int)FileType.Zip, (int)DatStatus.InDatCollect, (int)GotStatus.FileLocked] = new List { RepStatus.UnScanned }; + StatusCheck[(int)FileType.Zip, (int)DatStatus.InDatCollect, (int)GotStatus.NotGot] = new List { RepStatus.DirMissing }; + StatusCheck[(int)FileType.Zip, (int)DatStatus.InToSort, (int)GotStatus.Got] = new List { RepStatus.DirInToSort }; + StatusCheck[(int)FileType.Zip, (int)DatStatus.InToSort, (int)GotStatus.Corrupt] = new List { RepStatus.DirCorrupt }; + StatusCheck[(int)FileType.Zip, (int)DatStatus.InToSort, (int)GotStatus.FileLocked] = new List { RepStatus.UnScanned }; + StatusCheck[(int)FileType.Zip, (int)DatStatus.InToSort, (int)GotStatus.NotGot] = new List { RepStatus.Deleted }; + StatusCheck[(int)FileType.Zip, (int)DatStatus.NotInDat, (int)GotStatus.Got] = new List { RepStatus.DirUnknown }; + StatusCheck[(int)FileType.Zip, (int)DatStatus.NotInDat, (int)GotStatus.Corrupt] = new List { RepStatus.DirCorrupt }; + StatusCheck[(int)FileType.Zip, (int)DatStatus.NotInDat, (int)GotStatus.FileLocked] = new List { RepStatus.UnScanned }; + StatusCheck[(int)FileType.Zip, (int)DatStatus.NotInDat, (int)GotStatus.NotGot] = new List { RepStatus.Deleted }; + + + StatusCheck[(int)FileType.File, (int)DatStatus.InDatBad, (int)GotStatus.FileLocked] = new List { RepStatus.UnScanned }; + StatusCheck[(int)FileType.File, (int)DatStatus.InDatBad, (int)GotStatus.NotGot] = new List { RepStatus.NotCollected }; + StatusCheck[(int)FileType.File, (int)DatStatus.InDatCollect, (int)GotStatus.Corrupt] = new List { RepStatus.Corrupt, RepStatus.MoveToCorrupt, RepStatus.CorruptCanBeFixed }; + StatusCheck[(int)FileType.File, (int)DatStatus.InDatCollect, (int)GotStatus.FileLocked] = new List { RepStatus.UnScanned }; + StatusCheck[(int)FileType.File, (int)DatStatus.InDatCollect, (int)GotStatus.Got] = new List { RepStatus.Correct }; + StatusCheck[(int)FileType.File, (int)DatStatus.InDatCollect, (int)GotStatus.NotGot] = new List { RepStatus.Missing, RepStatus.CanBeFixed }; + StatusCheck[(int)FileType.File, (int)DatStatus.InDatMerged, (int)GotStatus.Corrupt] = new List { RepStatus.Corrupt, RepStatus.MoveToCorrupt, RepStatus.Delete }; + StatusCheck[(int)FileType.File, (int)DatStatus.InDatMerged, (int)GotStatus.FileLocked] = new List { RepStatus.UnScanned }; + StatusCheck[(int)FileType.File, (int)DatStatus.InDatMerged, (int)GotStatus.Got] = new List { RepStatus.UnNeeded, RepStatus.Delete, RepStatus.NeededForFix }; + StatusCheck[(int)FileType.File, (int)DatStatus.InDatMerged, (int)GotStatus.NotGot] = new List { RepStatus.NotCollected }; + StatusCheck[(int)FileType.File, (int)DatStatus.InToSort, (int)GotStatus.Corrupt] = new List { RepStatus.Corrupt, RepStatus.Delete }; + StatusCheck[(int)FileType.File, (int)DatStatus.InToSort, (int)GotStatus.FileLocked] = new List { RepStatus.UnScanned }; + StatusCheck[(int)FileType.File, (int)DatStatus.InToSort, (int)GotStatus.Got] = new List { RepStatus.InToSort, RepStatus.Ignore, RepStatus.NeededForFix, RepStatus.Delete }; + StatusCheck[(int)FileType.File, (int)DatStatus.InToSort, (int)GotStatus.NotGot] = new List { RepStatus.Deleted }; + StatusCheck[(int)FileType.File, (int)DatStatus.NotInDat, (int)GotStatus.Corrupt] = new List { RepStatus.Corrupt, RepStatus.MoveToCorrupt, RepStatus.Delete }; + StatusCheck[(int)FileType.File, (int)DatStatus.NotInDat, (int)GotStatus.Got] = new List { RepStatus.Unknown, RepStatus.Ignore, RepStatus.Delete, RepStatus.MoveToSort, RepStatus.NeededForFix, RepStatus.Rename }; + StatusCheck[(int)FileType.File, (int)DatStatus.NotInDat, (int)GotStatus.FileLocked] = new List { RepStatus.UnScanned }; + StatusCheck[(int)FileType.File, (int)DatStatus.NotInDat, (int)GotStatus.NotGot] = new List { RepStatus.Deleted }; + + + StatusCheck[(int)FileType.ZipFile, (int)DatStatus.InDatBad, (int)GotStatus.NotGot] = new List { RepStatus.NotCollected }; + StatusCheck[(int)FileType.ZipFile, (int)DatStatus.InDatBad, (int)GotStatus.Got] = new List { RepStatus.Correct }; + StatusCheck[(int)FileType.ZipFile, (int)DatStatus.InDatCollect, (int)GotStatus.Corrupt] = new List { RepStatus.Corrupt, RepStatus.MoveToCorrupt, RepStatus.CorruptCanBeFixed }; + StatusCheck[(int)FileType.ZipFile, (int)DatStatus.InDatCollect, (int)GotStatus.Got] = new List { RepStatus.Correct }; + StatusCheck[(int)FileType.ZipFile, (int)DatStatus.InDatCollect, (int)GotStatus.FileLocked] = new List { RepStatus.UnScanned }; + StatusCheck[(int)FileType.ZipFile, (int)DatStatus.InDatCollect, (int)GotStatus.NotGot] = new List { RepStatus.Missing, RepStatus.CanBeFixed }; + StatusCheck[(int)FileType.ZipFile, (int)DatStatus.InDatMerged, (int)GotStatus.Got] = new List { RepStatus.UnNeeded, RepStatus.Delete, RepStatus.NeededForFix, RepStatus.Rename }; + StatusCheck[(int)FileType.ZipFile, (int)DatStatus.InDatMerged, (int)GotStatus.NotGot] = new List { RepStatus.NotCollected }; + StatusCheck[(int)FileType.ZipFile, (int)DatStatus.InToSort, (int)GotStatus.Corrupt] = new List { RepStatus.Corrupt, RepStatus.Delete }; + StatusCheck[(int)FileType.ZipFile, (int)DatStatus.InToSort, (int)GotStatus.Got] = new List { RepStatus.InToSort, RepStatus.NeededForFix, RepStatus.Delete }; + StatusCheck[(int)FileType.ZipFile, (int)DatStatus.InToSort, (int)GotStatus.NotGot] = new List { RepStatus.Deleted }; + StatusCheck[(int)FileType.ZipFile, (int)DatStatus.NotInDat, (int)GotStatus.Corrupt] = new List { RepStatus.Corrupt, RepStatus.MoveToCorrupt, RepStatus.Delete }; + StatusCheck[(int)FileType.ZipFile, (int)DatStatus.NotInDat, (int)GotStatus.Got] = new List { RepStatus.Unknown, RepStatus.Delete, RepStatus.MoveToSort, RepStatus.NeededForFix, RepStatus.Rename }; + StatusCheck[(int)FileType.ZipFile, (int)DatStatus.NotInDat, (int)GotStatus.NotGot] = new List { RepStatus.Deleted }; + + DisplayOrder = new[] + { + RepStatus.Error, + RepStatus.UnSet, + + RepStatus.UnScanned, + + //RepStatus.DirCorrect, + //RepStatus.DirCorrectBadCase, + //RepStatus.DirMissing, + //RepStatus.DirUnknown, + RepStatus.DirCorrupt, + + RepStatus.MoveToCorrupt, + RepStatus.CorruptCanBeFixed, + RepStatus.CanBeFixed, + RepStatus.MoveToSort, + RepStatus.Delete, + RepStatus.NeededForFix, + RepStatus.Rename, + + RepStatus.Corrupt, + RepStatus.Unknown, + RepStatus.UnNeeded, + RepStatus.Missing, + RepStatus.Correct, + RepStatus.InToSort, + + RepStatus.NotCollected, + RepStatus.Ignore, + RepStatus.Deleted + }; + + } + + public static void ReportStatusReset(RvBase tBase) + { + + tBase.RepStatusReset(); + + FileType ftBase = tBase.FileType; + if (ftBase != FileType.Zip && ftBase != FileType.Dir) return; + + RvDir tDir = (RvDir)tBase; + + for (int i = 0; i < tDir.ChildCount; i++) + ReportStatusReset(tDir.Child(i)); + } + } + + public class ReportStatus + { + private readonly int[] _arrRepStatus = new int[(int)RepStatus.EndValue]; + + public void UpdateRepStatus(ReportStatus rs, int dir) + { + for (int i = 0; i < _arrRepStatus.Length; i++) + _arrRepStatus[i] += rs.Get((RepStatus)i) * dir; + } + + public void UpdateRepStatus(RepStatus rs, int dir) + { + _arrRepStatus[(int)rs] += dir; + } + + #region "arrGotStatus Processing" + + + + public int Get(RepStatus v) + { + return _arrRepStatus[(int)v]; + } + + public int CountCorrect() + { + return _arrRepStatus[(int)RepStatus.Correct]; + } + public bool HasCorrect() + { + return CountCorrect() > 0; + } + + public int CountMissing() + { + return ( + _arrRepStatus[(int)RepStatus.UnScanned] + + _arrRepStatus[(int)RepStatus.Missing] + + _arrRepStatus[(int)RepStatus.DirCorrupt] + + _arrRepStatus[(int)RepStatus.Corrupt] + + _arrRepStatus[(int)RepStatus.CanBeFixed] + + _arrRepStatus[(int)RepStatus.CorruptCanBeFixed] + ); + } + public bool HasMissing() + { + return CountMissing() > 0; + } + + + + public int CountFixesNeeded() + { + return ( + _arrRepStatus[(int)RepStatus.CanBeFixed] + + _arrRepStatus[(int)RepStatus.MoveToSort] + + _arrRepStatus[(int)RepStatus.Delete] + + _arrRepStatus[(int)RepStatus.NeededForFix] + + _arrRepStatus[(int)RepStatus.Rename] + + _arrRepStatus[(int)RepStatus.CorruptCanBeFixed] + + _arrRepStatus[(int)RepStatus.MoveToCorrupt] + ); + } + public bool HasFixesNeeded() + { + return CountFixesNeeded() > 0; + } + + + public int CountCanBeFixed() + { + return ( + _arrRepStatus[(int)RepStatus.CanBeFixed] + + _arrRepStatus[(int)RepStatus.CorruptCanBeFixed]); + } + + private int CountFixable() + { + return ( + _arrRepStatus[(int)RepStatus.CanBeFixed] + + _arrRepStatus[(int)RepStatus.MoveToSort] + + _arrRepStatus[(int)RepStatus.Delete] + + _arrRepStatus[(int)RepStatus.CorruptCanBeFixed] + + _arrRepStatus[(int)RepStatus.MoveToCorrupt] + ); + } + public bool HasFixable() + { + return CountFixable() > 0; + } + + private int CountAnyFiles() + { + // this list include probably more status's than are needed, but all are here to double check I don't delete something I should not. + return ( + _arrRepStatus[(int)RepStatus.Correct] + + _arrRepStatus[(int)RepStatus.UnNeeded] + + _arrRepStatus[(int)RepStatus.Unknown] + + _arrRepStatus[(int)RepStatus.InToSort] + + _arrRepStatus[(int)RepStatus.Corrupt] + + _arrRepStatus[(int)RepStatus.Ignore] + + _arrRepStatus[(int)RepStatus.MoveToSort] + + _arrRepStatus[(int)RepStatus.Delete] + + _arrRepStatus[(int)RepStatus.NeededForFix] + + _arrRepStatus[(int)RepStatus.Rename] + + _arrRepStatus[(int)RepStatus.MoveToCorrupt] + ); + } + public bool HasAnyFiles() + { + return CountAnyFiles() > 0; + } + + public int CountUnknown() + { + return _arrRepStatus[(int)RepStatus.Unknown]; + } + public bool HasUnknown() + { + return CountUnknown() > 0; + } + + + + public int CountInToSort() + { + return _arrRepStatus[(int)RepStatus.InToSort]; + } + public bool HasInToSort() + { + return CountInToSort() > 0; + } + + #endregion + + + } +} diff --git a/ROMVault2/Report.cs b/ROMVault2/Report.cs new file mode 100644 index 0000000..373f77c --- /dev/null +++ b/ROMVault2/Report.cs @@ -0,0 +1,430 @@ +/****************************************************** + * ROMVault2 is written by Gordon J. * + * Contact gordon@romvault.com * + * Copyright 2014 * + ******************************************************/ + +using System; +using System.IO; +using System.Linq; +using System.Windows.Forms; +using ROMVault2.RvDB; +using ROMVault2.Utils; + +namespace ROMVault2 +{ + static class Report + { + private static StreamWriter _ts; + private static RvDat _tDat; + private static string _outdir; + + private static string Etxt(string e) + { + string ret = e; + ret = ret.Replace("&", "&"); + ret = ret.Replace("\"", """); + ret = ret.Replace("'", "'"); + ret = ret.Replace("<", "<"); + ret = ret.Replace(">", ">"); + + return ret; + } + + public static void MakeFixFiles() + { + _tDat = null; + _ts = null; + + FolderBrowserDialog browse = new FolderBrowserDialog + { + ShowNewFolderButton = true, + Description = @"Please select a folder for Dats", + RootFolder = Environment.SpecialFolder.DesktopDirectory, + SelectedPath = @"apps" + }; + + if (browse.ShowDialog() != DialogResult.OK) return; + + _outdir = browse.SelectedPath; + _tDat = null; + MakeFixFilesRecurse(DB.DirTree.Child(0), true); + + if (_ts == null) return; + + _ts.WriteLine(""); + _ts.Close(); + } + + private static void MakeFixFilesRecurse(RvBase b, bool selected) + { + if (selected) + { + if (b.Dat != null) + { + RvDir tDir = b as RvDir; + if (tDir != null && tDir.Game != null && tDir.DirStatus.HasMissing()) + { + if (_tDat != b.Dat) + { + if (_tDat != null) + { + _ts.WriteLine(""); + _ts.WriteLine(); + } + + if (_ts != null) _ts.Close(); + + _tDat = b.Dat; + int test = 0; + string datFilename = Path.Combine(_outdir, "fixDat_" + Path.GetFileNameWithoutExtension(_tDat.GetData(RvDat.DatData.DatFullName)) + ".dat"); + while (File.Exists(datFilename)) + { + test++; + datFilename = Path.Combine(_outdir, "fixDat_" + Path.GetFileNameWithoutExtension(_tDat.GetData(RvDat.DatData.DatFullName)) + "(" + test + ").dat"); + } + _ts = new StreamWriter(datFilename); + + _ts.WriteLine(""); + _ts.WriteLine( + ""); + _ts.WriteLine(""); + _ts.WriteLine(""); + _ts.WriteLine("\t
"); + _ts.WriteLine("\t\tfix_" + Etxt(_tDat.GetData(RvDat.DatData.DatName)) + ""); + if (_tDat.GetData(RvDat.DatData.SuperDat) == "superdat") + _ts.WriteLine("\t\tSuperDAT"); + _ts.WriteLine("\t\tfix_" + Etxt(_tDat.GetData(RvDat.DatData.Description)) + ""); + _ts.WriteLine("\t\tFIXDATFILE"); + _ts.WriteLine("\t\t" + DateTime.Now.ToString("MM/dd/yyyy HH:mm:ss") + ""); + _ts.WriteLine("\t\t" + DateTime.Now.ToString("MM/dd/yyyy") + ""); + _ts.WriteLine("\t\tRomVault"); + _ts.WriteLine("\t
"); + } + + _ts.WriteLine("\t"); + if (!string.IsNullOrEmpty(tDir.Game.GetData(RvGame.GameData.Description))) + _ts.WriteLine("\t\t" + Etxt(tDir.Game.GetData(RvGame.GameData.Description)) + ""); + + } + + RvFile tRom = b as RvFile; + if (tRom != null) + { + + if (tRom.DatStatus == DatStatus.InDatCollect && tRom.GotStatus != GotStatus.Got) + { + string strRom; + if (tRom.FileStatusIs(FileStatus.SHA1CHDFromDAT | FileStatus.MD5CHDFromDAT)) + strRom = "\t\t"); + } + } + } + + } + + private enum ReportType + { + Complete, + CompletelyMissing, + PartialMissing, + Fixing + } + + private static string CleanTime() + { + return " (" + DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss") + ")"; + } + + public static void GenerateReport() + { + SaveFileDialog saveFileDialog1 = new SaveFileDialog + { + Title = @"Generate Full Report", + FileName = @"RVFullReport"+CleanTime()+".txt", + Filter = @"Rom Vault Report (*.txt)|*.txt|All Files (*.*)|*.*", + FilterIndex = 1 + }; + + if (saveFileDialog1.ShowDialog() == DialogResult.OK) + { + _ts = new StreamWriter(saveFileDialog1.FileName); + + _ts.WriteLine("Complete DAT Sets"); + _ts.WriteLine("-----------------------------------------"); + FindAllDats(DB.DirTree.Child(0), ReportType.Complete); + _ts.WriteLine(""); + _ts.WriteLine(""); + _ts.WriteLine("Empty DAT Sets"); + _ts.WriteLine("-----------------------------------------"); + FindAllDats(DB.DirTree.Child(0), ReportType.CompletelyMissing); + _ts.WriteLine(""); + _ts.WriteLine(""); + _ts.WriteLine("Partial DAT Sets - (Listing Missing ROMs)"); + _ts.WriteLine("-----------------------------------------"); + FindAllDats(DB.DirTree.Child(0), ReportType.PartialMissing); + _ts.Close(); + } + } + + public static void GenerateFixReport() + { + SaveFileDialog saveFileDialog1 = new SaveFileDialog + { + Title = @"Generate Fix Report", + FileName = @"RVFixReport"+CleanTime()+".txt", + Filter = @"Rom Vault Fixing Report (*.txt)|*.txt|All Files (*.*)|*.*", + FilterIndex = 1 + }; + + if (saveFileDialog1.ShowDialog() == DialogResult.OK) + { + _ts = new StreamWriter(saveFileDialog1.FileName); + + _ts.WriteLine("Listing Fixes"); + _ts.WriteLine("-----------------------------------------"); + FindAllDats(DB.DirTree.Child(0), ReportType.Fixing); + _ts.Close(); + } + } + + private static void FindAllDats(RvBase b, ReportType rt) + { + RvDir d = b as RvDir; + if (d == null) return; + if (d.DirDatCount > 0) + { + for (int i = 0; i < d.DirDatCount; i++) + { + RvDat dat = d.DirDat(i); + + int correct = 0; + int missing = 0; + int fixesNeeded = 0; + + if (d.Dat == dat) + { + correct += d.DirStatus.CountCorrect(); + missing += d.DirStatus.CountMissing(); + fixesNeeded += d.DirStatus.CountFixesNeeded(); + } + else + { + for (int j = 0; j < d.ChildCount; j++) + { + RvDir c = d.Child(j) as RvDir; + + if (c == null || c.Dat != dat) continue; + + correct += c.DirStatus.CountCorrect(); + missing += c.DirStatus.CountMissing(); + fixesNeeded += c.DirStatus.CountFixesNeeded(); + + } + } + + switch (rt) + { + case ReportType.Complete: + if (correct > 0 && missing == 0 && fixesNeeded == 0) + _ts.WriteLine(RemoveBase(dat.GetData(RvDat.DatData.DatFullName))); + break; + case ReportType.CompletelyMissing: + if (correct == 0 && missing > 0 && fixesNeeded == 0) + _ts.WriteLine(RemoveBase(dat.GetData(RvDat.DatData.DatFullName))); + break; + case ReportType.PartialMissing: + if ((correct > 0 && missing > 0) || fixesNeeded > 0) + { + _ts.WriteLine(RemoveBase(dat.GetData(RvDat.DatData.DatFullName))); + _fileNameLength = 0; + _fileSizeLength = 0; + _repStatusLength = 0; + ReportMissingFindSizes(d, dat, rt); + ReportDrawBars(); + ReportMissing(d, dat, rt); + ReportDrawBars(); + _ts.WriteLine(); + } + break; + case ReportType.Fixing: + if (fixesNeeded > 0) + { + _ts.WriteLine(RemoveBase(dat.GetData(RvDat.DatData.DatFullName))); + _fileNameLength = 0; + _fileSizeLength = 0; + _repStatusLength = 0; + ReportMissingFindSizes(d, dat, rt); + ReportDrawBars(); + ReportMissing(d, dat, rt); + ReportDrawBars(); + _ts.WriteLine(); + } + break; + } + } + } + + if (b.Dat != null) return; + + for (int i = 0; i < d.ChildCount; i++) + FindAllDats(d.Child(i), rt); + } + + private static string RemoveBase(string name) + { + int p = name.IndexOf("\\", StringComparison.Ordinal); + return p > 0 ? name.Substring(p + 1) : name; + } + + private static int _fileNameLength; + private static int _fileSizeLength; + private static int _repStatusLength; + + private static readonly RepStatus[] Partial = + { + RepStatus.UnScanned, + RepStatus.Missing, + RepStatus.Corrupt, + RepStatus.CanBeFixed, + RepStatus.CorruptCanBeFixed, + }; + + private static readonly RepStatus[] Fixing = + { + RepStatus.CanBeFixed, + RepStatus.MoveToSort, + RepStatus.Delete, + RepStatus.NeededForFix, + RepStatus.Rename, + RepStatus.CorruptCanBeFixed, + RepStatus.MoveToCorrupt + }; + + + private static void ReportMissingFindSizes(RvDir dir, RvDat dat, ReportType rt) + { + for (int i = 0; i < dir.ChildCount; i++) + { + RvBase b = dir.Child(i); + if (b.Dat != null && b.Dat != dat) + continue; + + RvFile f = b as RvFile; + + if (f != null) + { + if ( + (rt == ReportType.PartialMissing && Partial.Contains(f.RepStatus)) || + (rt == ReportType.Fixing && Fixing.Contains(f.RepStatus)) + ) + { + int fileNameLength = f.FileNameInsideGame().Length; + int fileSizeLength = f.Size.ToString().Length; + int repStatusLength = f.RepStatus.ToString().Length; + + if (fileNameLength > _fileNameLength) _fileNameLength = fileNameLength; + if (fileSizeLength > _fileSizeLength) _fileSizeLength = fileSizeLength; + if (repStatusLength > _repStatusLength) _repStatusLength = repStatusLength; + } + } + RvDir d = b as RvDir; + if (d != null) + ReportMissingFindSizes(d, dat, rt); + } + + } + + private static void ReportDrawBars() + { + _ts.WriteLine("+" + new string('-', _fileNameLength + 2) + "+" + new string('-', _fileSizeLength + 2) + "+----------+" + new string('-', _repStatusLength + 2) + "+"); + } + + private static void ReportMissing(RvDir dir, RvDat dat, ReportType rt) + { + for (int i = 0; i < dir.ChildCount; i++) + { + RvBase b = dir.Child(i); + if (b.Dat != null && b.Dat != dat) + continue; + + RvFile f = b as RvFile; + + if (f != null) + { + if ( + (rt == ReportType.PartialMissing && Partial.Contains(f.RepStatus)) || + (rt == ReportType.Fixing && Fixing.Contains(f.RepStatus)) + ) + { + string filename = f.FileNameInsideGame(); + string crc = ArrByte.ToString(f.CRC); + _ts.WriteLine("| " + filename + new string(' ', _fileNameLength + 1 - filename.Length) + "| " + + f.Size + new string(' ', _fileSizeLength + 1 - f.Size.ToString().Length) + "| " + + crc + new string(' ', 9 - crc.Length) + "| " + + f.RepStatus + new string(' ', _repStatusLength + 1 - f.RepStatus.ToString().Length) + "|"); + } + } + RvDir d = b as RvDir; + if (d != null) + ReportMissing(d, dat, rt); + } + + } + + } +} diff --git a/ROMVault2/ReportError.cs b/ROMVault2/ReportError.cs new file mode 100644 index 0000000..6abeefd --- /dev/null +++ b/ROMVault2/ReportError.cs @@ -0,0 +1,228 @@ +/****************************************************** + * ROMVault2 is written by Gordon J. * + * Contact gordon@romvault.com * + * Copyright 2014 * + ******************************************************/ + +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.ServiceModel; +using System.Windows.Forms; +using ROMVault2.RVRef; +using ROMVault2.RvDB; +using ROMVault2.Utils; + + +namespace ROMVault2 +{ + public static class ReportError + { + + public static void UnhandledExceptionHandler(object sender, System.Threading.ThreadExceptionEventArgs e) + { + try + { + // Create Error Message + string message = string.Format("An Application Error has occurred.\r\n\r\nEXCEPTION:\r\nSource: {0}\r\nMessage: {1}\r\n", e.Exception.Source, e.Exception.Message); + if (e.Exception.InnerException != null) + { + message += string.Format("\r\nINNER EXCEPTION:\r\nSource: {0}\r\nMessage: {1}\r\n", e.Exception.InnerException.Source, e.Exception.InnerException.Message); + } + message += string.Format("\r\nSTACK TRACE:\r\n{0}", e.Exception.StackTrace); + + SendErrorMessage(message); + + frmShowError fshow = new frmShowError(); + fshow.settype(message); + fshow.ShowDialog(); + + Environment.Exit(0); + } + catch + { + Environment.Exit(0); + } + } + + public static void UnhandledExceptionHandler(Exception e) + { + try + { + // Create Error Message + string message = string.Format("An Application Error has occurred.\r\n\r\nEXCEPTION:\r\nSource: {0}\r\nMessage: {1}\r\n", e.Source, e.Message); + if (e.InnerException != null) + { + message += string.Format("\r\nINNER EXCEPTION:\r\nSource: {0}\r\nMessage: {1}\r\n", e.InnerException.Source, e.InnerException.Message); + } + message += string.Format("\r\nSTACK TRACE:\r\n{0}", e.StackTrace); + + SendErrorMessage(message); + + frmShowError fshow = new frmShowError(); + fshow.settype(message); + fshow.ShowDialog(); + + } + catch + { + } + } + + public static void UnhandledExceptionHandler(string e1) + { + try + { + // Create Error Message + string message = string.Format("An Application Error has occurred.\r\n\r\nEXCEPTION:\r\nMessage:"); + message += e1 + "\r\n"; + + message += string.Format("\r\nSTACK TRACE:\r\n{0}", Environment.StackTrace); + + SendErrorMessage(message); + + frmShowError fshow = new frmShowError(); + fshow.settype(message); + fshow.ShowDialog(); + + Environment.Exit(0); + } + catch + { + Environment.Exit(0); + } + } + + + //public static void SendAndShowDat(string message, string filename) + //{ + // SendErrorMessageDat(message, filename); + // Show(message, "RomVault - Dat Reading Error"); + //} + + public static void SendAndShow(string message, string caption = "RomVault", MessageBoxButtons buttons = MessageBoxButtons.OK, MessageBoxIcon icon = MessageBoxIcon.Exclamation) + { + SendErrorMessage(message); + Show(message, caption, buttons, icon); + } + + public static void Show(string text, string caption = "RomVault", MessageBoxButtons buttons = MessageBoxButtons.OK, MessageBoxIcon icon = MessageBoxIcon.Exclamation) + { + if (Program.SyncCont != null) + Program.SyncCont.Send(callback => MessageBox.Show(text, caption, buttons, icon), null); + else + MessageBox.Show(text, caption, buttons, icon); + } + + public static void SendErrorMessage(string message) + { + + bool isNetworkAvailable = System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable(); + if (!isNetworkAvailable) return; + + string st = Environment.StackTrace; + + BasicHttpBinding b = new BasicHttpBinding { SendTimeout = new TimeSpan(0, 0, 5), ReceiveTimeout = new TimeSpan(0, 0, 5) }; + EndpointAddress e = new EndpointAddress(@"http://services.romvault.com/Service1.svc"); + + Service1Client s = new Service1Client(b, e); + + try + { + s.SendErrorMessage3(Settings.Username, Settings.EMail, Program.Version, Program.SubVersion, message + "\n" + st); + } + catch + { + } + s.Close(); + } + + public static void SendErrorMessageDat(string message, string filename) + { + bool isNetworkAvailable = System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable(); + if (!isNetworkAvailable) return; + + BasicHttpBinding b = new BasicHttpBinding { SendTimeout = new TimeSpan(0, 0, 5), ReceiveTimeout = new TimeSpan(0, 0, 5) }; + EndpointAddress e = new EndpointAddress(@"http://services.romvault.com/Service1.svc"); + + Service1Client s = new Service1Client(b, e); + + try + { + s.SendDATErrorMessage3(Settings.Username, Settings.EMail, Program.Version, Program.SubVersion, message, filename); + } + catch + { + } + s.Close(); + } + + private static string _logfilename; + + public static void ReportList(List files) + { + if (!Settings.DebugLogsEnabled) return; + + string dir, now; + OpenLogFile(out dir, out now); + dir = Path.Combine(dir, now + " DataBaseLog.txt"); + TextWriter sw = new StreamWriter(dir, false); + for (int i = 0; i < files.Count; i++) + { + RvFile f = files[i]; + f.ReportIndex = i; + ReportFile(sw, f); + } + + sw.Flush(); + sw.Close(); + } + + private static void OpenLogFile(out string dir, out string now) + { + dir = Path.Combine(Application.StartupPath, "Logs"); + if (!Directory.Exists(dir)) + Directory.CreateDirectory(dir); + + now = DateTime.Now.ToString(CultureInfo.InvariantCulture); + now = now.Replace("\\", "-"); + now = now.Replace("/", "-"); + now = now.Replace(":", "-"); + + _logfilename = Path.Combine(dir, now + " UpdateLog.txt"); + + } + + private static void ReportFile(TextWriter sw, RvFile f) + { + sw.WriteLine(f.ReportIndex.ToString("D8") + " " + ArrByte.ToString(f.CRC) + " " + f.GotStatus.ToString().PadRight(10) + " " + f.RepStatus.ToString().PadRight(15) + " " + f.TreeFullName); + } + + public static void LogOut(string s) + { + if (!Settings.DebugLogsEnabled) return; + + if (_logfilename == null) + { + string dir, now; + OpenLogFile(out dir, out now); + } + + StreamWriter sw = new StreamWriter(_logfilename, true); + sw.WriteLine(s); + sw.Flush(); + sw.Close(); + + } + public static void LogOut(RvFile f) + { + if (!Settings.DebugLogsEnabled) return; + + StreamWriter sw = new StreamWriter(_logfilename, true); + ReportFile(sw, f); + sw.Flush(); + sw.Close(); + } + } +} \ No newline at end of file diff --git a/ROMVault2/RvDB/DB.cs b/ROMVault2/RvDB/DB.cs new file mode 100644 index 0000000..a37b81e --- /dev/null +++ b/ROMVault2/RvDB/DB.cs @@ -0,0 +1,138 @@ +/****************************************************** + * ROMVault2 is written by Gordon J. * + * Contact gordon@romvault.com * + * Copyright 2014 * + ******************************************************/ + +using System.ComponentModel; +using System.IO; +using System.Threading; +using ROMVault2.Properties; + +namespace ROMVault2.RvDB +{ + + + public static class DBVersion + { + public static int VersionNow; + public const int Version = 7; + } + + public static class DB + { + private const ulong EndCacheMarker = 0x15a600dda7; + + public static BackgroundWorker Bgw; + + public static RvDir DirTree; + + private static void OpenDefaultDB() + { + DirTree = new RvDir(FileType.Dir) + { + Tree = new RvTreeRow(), + DatStatus = DatStatus.InDatCollect + }; + + RvDir rv = new RvDir(FileType.Dir) + { + Name = "RomVault", + Tree = new RvTreeRow(), + DatStatus = DatStatus.InDatCollect + }; + DirTree.ChildAdd(rv); + + RvDir ts = new RvDir(FileType.Dir) + { + Name = "ToSort", + Tree = new RvTreeRow(), + DatStatus = DatStatus.InDatCollect + }; + DirTree.ChildAdd(ts); + } + + public static void Write() + { + if (File.Exists(Settings.CacheFile)) + { + string bname = Settings.CacheFile + "Backup"; + if (File.Exists(bname)) + File.Delete(bname); + File.Move(Settings.CacheFile, bname); + + } + FileStream fs = new FileStream(Settings.CacheFile, FileMode.CreateNew, FileAccess.Write); + BinaryWriter bw = new BinaryWriter(fs); + DBVersion.VersionNow = DBVersion.Version; + bw.Write(DBVersion.Version); + DirTree.Write(bw); + + bw.Write(EndCacheMarker); + + bw.Flush(); + bw.Close(); + + fs.Close(); + fs.Dispose(); + } + public static void Read(object sender, DoWorkEventArgs e) + { + Bgw = sender as BackgroundWorker; + Program.SyncCont = e.Argument as SynchronizationContext; + + if (!File.Exists(Settings.CacheFile)) + { + OpenDefaultDB(); + Bgw = null; + Program.SyncCont = null; + return; + } + DirTree = new RvDir(FileType.Dir); + FileStream fs = new FileStream(Settings.CacheFile, FileMode.Open, FileAccess.Read); + if (fs.Length < 4) + ReportError.UnhandledExceptionHandler("Cache is Corrupt, revert to Backup."); + + + BinaryReader br = new BinaryReader(fs); + + if (Bgw != null) + Bgw.ReportProgress(0, new bgwSetRange((int)fs.Length)); + + DBVersion.VersionNow = br.ReadInt32(); + + if (DBVersion.VersionNow != DBVersion.Version) + { + ReportError.Show(Resources.DB_Read_Data_Cache_version_is_out_of_date_you_should_now_rescan_your_dat_directory_and_roms_directory_); + OpenDefaultDB(); + } + else + { + DirTree.Read(br, null); + } + + if (fs.Position > fs.Length - 8) + ReportError.UnhandledExceptionHandler("Cache is Corrupt, revert to Backup."); + + ulong testEOF = br.ReadUInt64(); + if (testEOF != EndCacheMarker) + ReportError.UnhandledExceptionHandler("Cache is Corrupt, revert to Backup."); + + br.Close(); + fs.Close(); + fs.Dispose(); + + Bgw = null; + Program.SyncCont = null; + } + + public static string Fn(string v) + { + return v ?? ""; + } + } + +} + + + diff --git a/ROMVault2/RvDB/FileStatus.cs b/ROMVault2/RvDB/FileStatus.cs new file mode 100644 index 0000000..074e331 --- /dev/null +++ b/ROMVault2/RvDB/FileStatus.cs @@ -0,0 +1,35 @@ +/****************************************************** + * ROMVault2 is written by Gordon J. * + * Contact gordon@romvault.com * + * Copyright 2014 * + ******************************************************/ + +using System; + +namespace ROMVault2.RvDB +{ + [Flags] + public enum FileStatus + { + SizeFromDAT = 0x00000001, + CRCFromDAT = 0x00000002, + SHA1FromDAT = 0x00000004, + MD5FromDAT = 0x00000008, + SHA1CHDFromDAT = 0x00000010, + MD5CHDFromDAT = 0x00000020, + + SizeFromHeader = 0x00000100, + CRCFromHeader = 0x00000200, + SHA1FromHeader = 0x00000400, + MD5FromHeader = 0x00000800, + SHA1CHDFromHeader = 0x00001000, + MD5CHDFromHeader = 0x00002000, + + SizeVerified = 0x00010000, + CRCVerified = 0x00020000, + SHA1Verified = 0x00040000, + MD5Verified = 0x00080000, + SHA1CHDVerified = 0x00100000, + MD5CHDVerified = 0x00200000 + } +} diff --git a/ROMVault2/RvDB/RvBase.cs b/ROMVault2/RvDB/RvBase.cs new file mode 100644 index 0000000..063ad43 --- /dev/null +++ b/ROMVault2/RvDB/RvBase.cs @@ -0,0 +1,308 @@ +/****************************************************** + * ROMVault2 is written by Gordon J. * + * Contact gordon@romvault.com * + * Copyright 2014 * + ******************************************************/ + +using System; +using System.Collections.Generic; +using System.IO; +using ROMVault2.Properties; + +namespace ROMVault2.RvDB +{ + public enum DatStatus { InDatCollect, InDatMerged, InDatBad, NotInDat, InToSort } + public enum GotStatus { NotGot, Got, Corrupt, FileLocked } + public enum FileType { Unknown, Dir, Zip, xSevenZip, xRAR, File, ZipFile, xSevenZipFile } + + public abstract class RvBase + { + private readonly FileType _type; + + public string Name; // The Name of the File or Directory + public string FileName; // Found filename if different from Name + public RvDir Parent; // A link to the Parent Directory + public RvDat Dat; + public long TimeStamp; + public int ReportIndex; + + public bool SearchFound; + + private DatStatus _datStatus = DatStatus.NotInDat; + private GotStatus _gotStatus = GotStatus.NotGot; + private RepStatus _repStatus = RepStatus.UnSet; + + protected RvBase(FileType type) + { + _type = type; + } + + public FileType FileType + { + get { return _type; } + } + + public virtual void Write(BinaryWriter bw) + { + bw.Write(DB.Fn(Name)); + bw.Write(DB.Fn(FileName)); + bw.Write(TimeStamp); + if (Dat == null) + { + bw.Write(false); + } + else + { + //Debug.WriteLine("Dat is not null"); + bw.Write(true); + //Debug.WriteLine("Dat index is "+ Dat.DatIndex); + bw.Write(Dat.DatIndex); + } + + bw.Write((byte)_datStatus); + bw.Write((byte)_gotStatus); + } + public virtual void Read(BinaryReader br, List parentDirDats) + { + Name = br.ReadString(); + FileName = br.ReadString(); + TimeStamp = br.ReadInt64(); + bool foundDat = br.ReadBoolean(); + if (foundDat) + { + int index = br.ReadInt32(); + if (index == -1) + ReportError.SendAndShow(Resources.RvBase_Read_Dat_found_without_an_index); + else + Dat = parentDirDats[index]; + } + else + { + Dat = null; + } + + _datStatus = (DatStatus)br.ReadByte(); + _gotStatus = (GotStatus)br.ReadByte(); + RepStatusReset(); + } + + + public virtual EFile DatRemove() + { + Dat = null; + if (GotStatus == GotStatus.NotGot) + return EFile.Delete; + + if (!String.IsNullOrEmpty(FileName)) + { + Name = FileName; + FileName = null; + } + DatStatus = DatStatus.NotInDat; + return EFile.Keep; + } + public virtual void DatAdd(RvBase b) + { + // Parent , TimeStamp Should already be correct. + + if (GotStatus == GotStatus.NotGot) + ReportError.SendAndShow("Error Adding DAT to NotGot File " + b.GotStatus); + + SetStatus(b.DatStatus, GotStatus.Got); + + if (Name == b.Name) // case match so all is good + { + FileName = null; + } + else + { + FileName = Name; + Name = b.Name; + } + + Dat = b.Dat; + } + + public virtual EFile FileRemove() + { + TimeStamp = 0; + FileName = null; + + GotStatus = (Parent.GotStatus == GotStatus.FileLocked) ? GotStatus.FileLocked : GotStatus.NotGot; + switch (DatStatus) + { + case DatStatus.InDatCollect: + case DatStatus.InDatMerged: + case DatStatus.InDatBad: + return EFile.Keep; + + case DatStatus.NotInDat: + case DatStatus.InToSort: + return EFile.Delete; // this item should be removed from the db. + default: + ReportError.SendAndShow(Resources.RvBase_SetGot_Unknown_Set_Got_Status + DatStatus); + return EFile.Keep; + } + } + public virtual void FileAdd(RvBase file) + { + TimeStamp = file.TimeStamp; + FileCheckName(file); + if (file.GotStatus == GotStatus.NotGot) + ReportError.SendAndShow("Error setting got to a NotGot File"); + GotStatus = file.GotStatus; + } + + public void FileCheckName(RvBase file) + { + // Don't care about bad case if the file is not in a dat. + if (DatStatus == DatStatus.NotInDat || DatStatus == DatStatus.InToSort) + Name = file.Name; + + FileName = Name == file.Name ? null : file.Name; + } + + public virtual void CopyTo(RvBase c) + { + c.Name = Name; + c.FileName = FileName; + //c.Parent = Parent; + c.Dat = Dat; + c.TimeStamp = TimeStamp; + c.ReportIndex = ReportIndex; + c._datStatus = _datStatus; + c._gotStatus = _gotStatus; + c.RepStatus = RepStatus; + } + + + + private string Extention + { + get + { + switch (FileType) + { + case FileType.Zip: return ".zip"; + //case FileType.SevenZip: return ".7z"; + //case FileType.RAR: return ".rar"; + } + return ""; + } + } + public string FullName + { + get { return DBHelper.GetRealPath(TreeFullName); } + } + public string DatFullName + { + get { return DBHelper.GetDatPath(TreeFullName); } + } + public string TreeFullName + { + get + { + if (Parent == null) return Name + Extention; + return IO.Path.Combine(Parent.TreeFullName, Name + Extention); + } + } + public bool IsInToSort + { + get + { + string fullName = TreeFullName; + return fullName.Substring(0, 6) == "ToSort"; + } + } + + public string SuperDatFileName() + { + return SuperDatFileName(Dat); + } + + private string SuperDatFileName(RvDat dat) + { + if (dat.AutoAddDirectory) + { + if (Parent == null || Parent.Parent == null || Parent.Parent.Dat != dat) return Name; + } + else + { + if (Parent == null || Parent.Dat != dat) return Name; + } + return IO.Path.Combine(Parent.SuperDatFileName(dat), Name); + } + + public string FileNameInsideGame() + { + RvDir d = this as RvDir; + if (d != null && d.Game != null) return Name; + + return IO.Path.Combine(Parent.FileNameInsideGame(), Name); + } + + public DatStatus DatStatus + { + set + { + _datStatus = value; + RepStatusReset(); + } + get { return _datStatus; } + } + + + + public GotStatus GotStatus + { + get { return _gotStatus; } + set + { + _gotStatus = value; + RepStatusReset(); + } + } + + public void SetStatus(DatStatus dt, GotStatus flag) + { + _datStatus = dt; + _gotStatus = flag; + RepStatusReset(); + } + + + public RepStatus RepStatus + { + get { return _repStatus; } + set + { + if (Parent != null) Parent.UpdateRepStatusUpTree(_repStatus, -1); + + List rs = RepairStatus.StatusCheck[(int)FileType, (int)_datStatus, (int)_gotStatus]; + if (rs == null || !rs.Contains(value)) + { + ReportError.SendAndShow(FullName + " " + Resources.RvBase_Check + FileType + Resources.RvBase_Check + _datStatus + Resources.RvBase_Check + _gotStatus + " from: " + _repStatus + " to: " + value); + _repStatus = RepStatus.Error; + } + else + _repStatus = value; + + if (Parent != null) Parent.UpdateRepStatusUpTree(_repStatus, 1); + } + } + public void RepStatusReset() + { + SearchFound = false; + if ((RepStatus == RepStatus.UnSet || RepStatus == RepStatus.Unknown || RepStatus == RepStatus.Ignore) && FileType == FileType.File && GotStatus == GotStatus.Got && DatStatus==DatStatus.NotInDat) + foreach (string file in Settings.IgnoreFiles) + if (Name == file) + { + RepStatus = RepStatus.Ignore; + return; + } + + List rs = RepairStatus.StatusCheck[(int)FileType, (int)_datStatus, (int)_gotStatus]; + RepStatus = rs == null ? RepStatus.Error : rs[0]; + } + } +} diff --git a/ROMVault2/RvDB/RvDat.cs b/ROMVault2/RvDB/RvDat.cs new file mode 100644 index 0000000..20ea3d6 --- /dev/null +++ b/ROMVault2/RvDB/RvDat.cs @@ -0,0 +1,118 @@ +/****************************************************** + * ROMVault2 is written by Gordon J. * + * Contact gordon@romvault.com * + * Copyright 2014 * + ******************************************************/ + +using System; +using System.Collections.Generic; +using System.IO; + +namespace ROMVault2.RvDB +{ + public enum DatUpdateStatus + { + Delete, + Correct + } + + public class RvDat + { + public int DatIndex = -1; + public DatUpdateStatus Status; + + public long TimeStamp; + public bool AutoAddDirectory; + + public enum DatData + { + DatName = 1, + DatFullName = 2, + + RootDir = 3, + Description = 4, + Category = 5, + Version = 6, + Date = 7, + Author = 8, + Email = 9, + HomePage = 10, + URL = 11, + FileType = 12, + MergeType = 13, + SuperDat = 14, + DirSetup = 15 + } + + private class GameMetaData + { + public DatData Id { get; private set; } + public String Value { get; private set; } + + public GameMetaData(DatData id, String value) + { + Id = id; + Value = value; + } + public GameMetaData(BinaryReader br) + { + Id = (DatData)br.ReadByte(); + Value = br.ReadString(); + } + + public void Write(BinaryWriter bw) + { + bw.Write((byte)Id); + bw.Write(DB.Fn(Value)); + } + } + + private readonly List _gameMetaData = new List(); + + + public void Write(BinaryWriter bw) + { + bw.Write(TimeStamp); + bw.Write(AutoAddDirectory); + + bw.Write((byte)_gameMetaData.Count); + foreach (GameMetaData gameMD in _gameMetaData) + gameMD.Write(bw); + } + + public void Read(BinaryReader br) + { + TimeStamp = br.ReadInt64(); + AutoAddDirectory = br.ReadBoolean(); + + byte c = br.ReadByte(); + _gameMetaData.Clear(); + _gameMetaData.Capacity = c; + for (byte i = 0; i < c; i++) + _gameMetaData.Add(new GameMetaData(br)); + } + + public void AddData(DatData id, string val) + { + if (string.IsNullOrEmpty(val)) + return; + + int pos = 0; + while (pos < _gameMetaData.Count && _gameMetaData[pos].Id < id) + pos++; + + _gameMetaData.Insert(pos, new GameMetaData(id, val)); + } + + public string GetData(DatData id) + { + foreach (GameMetaData gameMD in _gameMetaData) + { + if (id == gameMD.Id) return gameMD.Value; + if (id < gameMD.Id) return ""; + } + return ""; + } + } + +} diff --git a/ROMVault2/RvDB/RvDir.cs b/ROMVault2/RvDB/RvDir.cs new file mode 100644 index 0000000..f245de0 --- /dev/null +++ b/ROMVault2/RvDB/RvDir.cs @@ -0,0 +1,345 @@ +/****************************************************** + * ROMVault2 is written by Gordon J. * + * Contact gordon@romvault.com * + * Copyright 2014 * + ******************************************************/ + +using System.Collections.Generic; +using System.IO; +using ROMVault2.Properties; +using ROMVault2.SupportedFiles; +using ROMVault2.Utils; + +namespace ROMVault2.RvDB +{ + public class RvDir : RvBase + { + + public RvTreeRow Tree; + public RvGame Game; + private readonly List _dirDats = new List(); + private readonly List _children = new List(); + public readonly ReportStatus DirStatus = new ReportStatus(); + + public ZipStatus ZipStatus; + + public RvDir(FileType type) + : base(type) + { + if (type != FileType.Dir && type != FileType.Zip) + ReportError.SendAndShow("Trying to set Dir type to " + type); + } + + + + public override void Write(BinaryWriter bw) + { + base.Write(bw); + if (Tree == null) + bw.Write(false); + else + { + bw.Write(true); + Tree.Write(bw); + } + + if (Game == null) + bw.Write(false); + else + { + bw.Write(true); + Game.Write(bw); + } + + int count = _dirDats.Count; + bw.Write(count); + for (int i = 0; i < count; i++) + { + _dirDats[i].Write(bw); + } + + count = _children.Count; + bw.Write(count); + for (int i = 0; i < count; i++) + { + FileType type = _children[i].FileType; + bw.Write((byte)type); + _children[i].Write(bw); + } + + if (DBTypeGet.isCompressedDir(FileType)) + bw.Write((byte)ZipStatus); + + } + public override void Read(BinaryReader br, List parentDirDats) + { + base.Read(br, parentDirDats); + bool foundTree = br.ReadBoolean(); + if (foundTree) + { + Tree = new RvTreeRow(); + Tree.Read(br); + } + else + Tree = null; + + bool foundGame = br.ReadBoolean(); + if (foundGame) + { + Game = new RvGame(); + Game.Read(br); + } + else + Game = null; + + int count = br.ReadInt32(); + _dirDats.Clear(); + for (int i = 0; i < count; i++) + { + RvDat dat = new RvDat { DatIndex = i }; + dat.Read(br); + _dirDats.Add(dat); + + string datname = TreeFullName + @"\" + dat.GetData(RvDat.DatData.DatName); + if (datname.Length >= 9 && datname.Substring(0, 9) == @"RomVault\") + datname = datname.Substring(9); + + DB.Bgw.ReportProgress(0, new bgwText("Loading: " + datname)); + DB.Bgw.ReportProgress((int)br.BaseStream.Position); + + } + if (_dirDats.Count > 0) + parentDirDats = _dirDats; + + count = br.ReadInt32(); + _children.Clear(); + for (int i = 0; i < count; i++) + { + RvBase tChild = DBTypeGet.GetRvType((FileType)br.ReadByte()); + + tChild.Parent = this; + tChild.Read(br, parentDirDats); + _children.Add(tChild); + } + + if (DBTypeGet.isCompressedDir(FileType)) + ZipStatus = (ZipStatus)br.ReadByte(); + + } + + + public override EFile DatRemove() + { + Tree = null; + Game = null; + _dirDats.Clear(); + return base.DatRemove(); + } + public override void DatAdd(RvBase b) + { + Tree = ((RvDir)b).Tree; + Game = ((RvDir)b).Game; + if (_dirDats.Count > 0) + ReportError.SendAndShow(Resources.RvDir_SetDat_Setting_Dir_with_a_dat_list); + base.DatAdd(b); + } + + + public override EFile FileRemove() + { + ZipStatus = ZipStatus.None; + return base.FileRemove(); + } + + + + + + + + public int DirDatCount + { + get + { + return _dirDats.Count; + } + } + public RvDat DirDat(int index) + { + return _dirDats[index]; + } + public void DirDatAdd(RvDat dat) + { + int index; + DirDatSearch(dat, out index); + _dirDats.Insert(index, dat); + for (int i = 0; i < _dirDats.Count; i++) + _dirDats[i].DatIndex = i; + } + public void DirDatRemove(int index) + { + _dirDats.RemoveAt(index); + for (int i = 0; i < _dirDats.Count; i++) + _dirDats[i].DatIndex = i; + } + + private void DirDatSearch(RvDat dat, out int index) + { + int intBottom = 0; + int intTop = _dirDats.Count; + int intMid = 0; + int intRes = -1; + + //Binary chop to find the closest match + while (intBottom < intTop && intRes != 0) + { + intMid = (intBottom + intTop) / 2; + + intRes = DBHelper.DatCompare(dat, _dirDats[intMid]); + if (intRes < 0) + intTop = intMid; + else if (intRes > 0) + intBottom = intMid + 1; + } + index = intMid; + + // if match was found check up the list for the first match + if (intRes == 0) + { + int intRes1 = 0; + while (index > 0 && intRes1 == 0) + { + intRes1 = DBHelper.DatCompare(dat, _dirDats[index - 1]); + if (intRes1 == 0) + index--; + } + } + // if the search is greater than the closest match move one up the list + else if (intRes > 0) + index++; + } + + + + public int ChildCount + { + get + { + return _children.Count; + } + } + public RvBase Child(int index) + { + return _children[index]; + } + + public int ChildAdd(RvBase child) + { + int index; + ChildNameSearch(child, out index); + ChildAdd(child, index); + return index; + } + public void ChildAdd(RvBase child, int index) + { + if ( + (FileType == FileType.Dir && child.FileType == FileType.ZipFile) || + (FileType == FileType.Zip && child.FileType != FileType.ZipFile) + ) + ReportError.SendAndShow("Typing to add a " + child.FileType + " to a " + FileType); + + _children.Insert(index, child); + child.Parent = this; + UpdateRepStatusArrUpTree(child, 1); + } + + public void ChildRemove(int index) + { + UpdateRepStatusArrUpTree(_children[index], -1); + if (_children[index].Parent == this) + _children[index].Parent = null; + _children.RemoveAt(index); + } + + public int ChildNameSearch(RvBase lName, out int index) + { + int intBottom = 0; + int intTop = _children.Count; + int intMid = 0; + int intRes = -1; + + //Binary chop to find the closest match + while (intBottom < intTop && intRes != 0) + { + intMid = (intBottom + intTop) / 2; + + intRes = DBHelper.CompareName(lName, _children[intMid]); + if (intRes < 0) + intTop = intMid; + else if (intRes > 0) + intBottom = intMid + 1; + } + index = intMid; + + // if match was found check up the list for the first match + if (intRes == 0) + { + int intRes1 = 0; + while (index > 0 && intRes1 == 0) + { + intRes1 = DBHelper.CompareName(lName, _children[index - 1]); + if (intRes1 == 0) + index--; + } + } + // if the search is greater than the closest match move one up the list + else if (intRes > 0) + index++; + + return intRes; + } + + + public bool FindChild(RvBase lName, out int index) + { + if (ChildNameSearch(lName, out index) != 0) + { + ReportError.UnhandledExceptionHandler("Could not find self in Parent " + FullName); + return false; + } + + do + { + if (_children[index] == lName) + return true; + index++; + + } while (index < _children.Count && DBHelper.CompareName(lName, _children[index]) == 0); + + return false; + } + + + + public void UpdateRepStatusUpTree(RepStatus rStat, int dir) + { + DirStatus.UpdateRepStatus(rStat, dir); + if (Parent != null) + Parent.UpdateRepStatusUpTree(rStat, dir); + } + + private void UpdateRepStatusArrUpTree(RvBase child, int dir) + { + DirStatus.UpdateRepStatus(child.RepStatus, dir); + RvDir rvDir = child as RvDir; + if (rvDir != null) + DirStatus.UpdateRepStatus(rvDir.DirStatus, dir); + + if (Parent != null) + Parent.UpdateRepStatusArrUpTree(child, dir); + } + + + } + +} diff --git a/ROMVault2/RvDB/RvFile.cs b/ROMVault2/RvDB/RvFile.cs new file mode 100644 index 0000000..cfda15c --- /dev/null +++ b/ROMVault2/RvDB/RvFile.cs @@ -0,0 +1,251 @@ +/****************************************************** + * ROMVault2 is written by Gordon J. * + * Contact gordon@romvault.com * + * Copyright 2014 * + ******************************************************/ + +using System; +using System.Collections.Generic; +using System.IO; +using ROMVault2.Utils; + +namespace ROMVault2.RvDB +{ + public class RvFile : RvBase + { + public ulong? Size; + public byte[] CRC; + public byte[] SHA1; + public byte[] MD5; + public byte[] SHA1CHD; + public byte[] MD5CHD; + + public string Merge = ""; + public string Status; + private FileStatus _fileStatus; + + public int ZipFileIndex = -1; + public ulong? ZipFileHeaderPosition; + + public uint? CHDVersion; + + public RvFile(FileType type) + : base(type) + { + if (type != FileType.File && type != FileType.ZipFile) + ReportError.SendAndShow("Trying to set file type to " + type); + } + + [Flags] + private enum FileFlags + { + Size = 0x01, + CRC = 0x02, + SHA1 = 0x04, + MD5 = 0x08, + SHA1CHD = 0x10, + MD5CHD = 0x20, + Merge = 0x40, + Status = 0x80, + ZipFileIndex = 0x100, + ZipFileHeader = 0x200, + CHDVersion = 0x400 + } + + public override void Write(BinaryWriter bw) + { + base.Write(bw); + + FileFlags fFlags = 0; + if (Size != null) fFlags |= FileFlags.Size; + if (CRC != null) fFlags |= FileFlags.CRC; + if (SHA1 != null) fFlags |= FileFlags.SHA1; + if (MD5 != null) fFlags |= FileFlags.MD5; + if (SHA1CHD != null) fFlags |= FileFlags.SHA1CHD; + if (MD5CHD != null) fFlags |= FileFlags.MD5CHD; + if (!String.IsNullOrEmpty(Merge)) fFlags |= FileFlags.Merge; + if (!String.IsNullOrEmpty(Status)) fFlags |= FileFlags.Status; + if (ZipFileIndex >= 0) fFlags |= FileFlags.ZipFileIndex; + if (ZipFileHeaderPosition != null) fFlags |= FileFlags.ZipFileHeader; + if (CHDVersion != null) fFlags |= FileFlags.CHDVersion; + + bw.Write((UInt16)fFlags); + + if (Size != null) bw.Write((ulong)Size); + if (CRC != null) ArrByte.Write(bw, CRC); + if (SHA1 != null) ArrByte.Write(bw, SHA1); + if (MD5 != null) ArrByte.Write(bw, MD5); + if (SHA1CHD != null) ArrByte.Write(bw, SHA1CHD); + if (MD5CHD != null) ArrByte.Write(bw, MD5CHD); + if (!String.IsNullOrEmpty(Merge)) bw.Write(Merge); + if (!String.IsNullOrEmpty(Status)) bw.Write(Status); + if (ZipFileIndex >= 0) bw.Write(ZipFileIndex); + if (ZipFileHeaderPosition != null) bw.Write((long)ZipFileHeaderPosition); + if (CHDVersion != null) bw.Write((uint)CHDVersion); + + bw.Write((uint)_fileStatus); + } + public override void Read(BinaryReader br, List parentDirDats) + { + base.Read(br, parentDirDats); + + FileFlags fFlags = (FileFlags)br.ReadUInt16(); + + Size = (fFlags & FileFlags.Size) > 0 ? (ulong?)br.ReadUInt64() : null; + CRC = (fFlags & FileFlags.CRC) > 0 ? ArrByte.Read(br) : null; + SHA1 = (fFlags & FileFlags.SHA1) > 0 ? ArrByte.Read(br) : null; + MD5 = (fFlags & FileFlags.MD5) > 0 ? ArrByte.Read(br) : null; + SHA1CHD = (fFlags & FileFlags.SHA1CHD) > 0 ? ArrByte.Read(br) : null; + MD5CHD = (fFlags & FileFlags.MD5CHD) > 0 ? ArrByte.Read(br) : null; + Merge = (fFlags & FileFlags.Merge) > 0 ? br.ReadString() : null; + Status = (fFlags & FileFlags.Status) > 0 ? br.ReadString() : null; + ZipFileIndex = (fFlags & FileFlags.ZipFileIndex) > 0 ? br.ReadInt32() : -1; + ZipFileHeaderPosition = (fFlags & FileFlags.ZipFileHeader) > 0 ? (ulong?)br.ReadUInt64() : null; + CHDVersion = (fFlags & FileFlags.CHDVersion) > 0 ? (uint?)br.ReadInt32() : null; + + _fileStatus = (FileStatus)br.ReadUInt32(); + } + + public override EFile DatRemove() + { + if (!FileStatusIs(FileStatus.SizeFromHeader) && !FileStatusIs(FileStatus.SizeVerified)) Size = null; + if (!FileStatusIs(FileStatus.CRCFromHeader) && !FileStatusIs(FileStatus.CRCVerified)) CRC = null; + if (!FileStatusIs(FileStatus.SHA1FromHeader) && !FileStatusIs(FileStatus.SHA1Verified)) SHA1 = null; + if (!FileStatusIs(FileStatus.MD5FromHeader) && !FileStatusIs(FileStatus.MD5Verified)) MD5 = null; + if (!FileStatusIs(FileStatus.SHA1CHDFromHeader) && !FileStatusIs(FileStatus.SHA1CHDVerified)) SHA1CHD = null; + if (!FileStatusIs(FileStatus.MD5CHDFromHeader) && !FileStatusIs(FileStatus.MD5CHDVerified)) MD5CHD = null; + + FileStatusClear(FileStatus.SizeFromDAT | FileStatus.CRCFromDAT | FileStatus.SHA1FromDAT | FileStatus.MD5FromDAT | FileStatus.SHA1CHDFromDAT | FileStatus.MD5CHDFromDAT); + + Merge = ""; + Status = ""; + return base.DatRemove(); + } + public override void DatAdd(RvBase file) + { + RvFile tFile = file as RvFile; + if (tFile == null) + { + ReportError.SendAndShow("Error setting Dat Set Got"); + return; + } + + if (Size == null && tFile.Size != null) Size = tFile.Size; + if (CRC == null && tFile.CRC != null) CRC = tFile.CRC; + if (SHA1 == null && tFile.SHA1 != null) SHA1 = tFile.SHA1; + if (MD5 == null && tFile.MD5 != null) MD5 = tFile.MD5; + if (SHA1CHD == null && tFile.SHA1CHD != null) SHA1CHD = tFile.SHA1CHD; + if (MD5CHD == null && tFile.MD5CHD != null) MD5CHD = tFile.MD5CHD; + + FileStatusSet( + FileStatus.SizeFromDAT | FileStatus.CRCFromDAT | FileStatus.SHA1FromDAT | FileStatus.MD5FromDAT | FileStatus.SHA1CHDFromDAT | FileStatus.MD5CHDFromDAT, + tFile); + + Merge = tFile.Merge; + Status = tFile.Status; + base.DatAdd(file); + } + + public override EFile FileRemove() + { + ZipFileIndex = -1; + ZipFileHeaderPosition = null; + + if (base.FileRemove() == EFile.Delete) + return EFile.Delete; + + if (!FileStatusIs(FileStatus.SizeFromDAT)) Size = null; + if (!FileStatusIs(FileStatus.CRCFromDAT)) CRC = null; + if (!FileStatusIs(FileStatus.SHA1FromDAT)) SHA1 = null; + if (!FileStatusIs(FileStatus.MD5FromDAT)) MD5 = null; + if (!FileStatusIs(FileStatus.SHA1CHDFromDAT)) SHA1CHD = null; + if (!FileStatusIs(FileStatus.MD5CHDFromDAT)) MD5CHD = null; + + CHDVersion = null; + + FileStatusClear( + FileStatus.SizeFromHeader | FileStatus.CRCFromHeader | FileStatus.SHA1FromHeader | FileStatus.MD5FromHeader | FileStatus.SHA1CHDFromHeader | FileStatus.MD5CHDFromHeader | + FileStatus.SizeVerified | FileStatus.CRCVerified | FileStatus.SHA1Verified | FileStatus.MD5Verified | FileStatus.SHA1CHDVerified | FileStatus.MD5CHDVerified); + + return EFile.Keep; + } + public override void FileAdd(RvBase file) + { + RvFile tFile = file as RvFile; + if (tFile == null) + { + ReportError.SendAndShow("Error setting File Got"); + return; + } + + if (Size == null && tFile.Size != null) Size = tFile.Size; + if (CRC == null && tFile.CRC != null) CRC = tFile.CRC; + if (SHA1 == null && tFile.SHA1 != null) SHA1 = tFile.SHA1; + if (MD5 == null && tFile.MD5 != null) MD5 = tFile.MD5; + if (SHA1CHD == null && tFile.SHA1CHD != null) SHA1CHD = tFile.SHA1CHD; + if (MD5CHD == null && tFile.MD5CHD != null) MD5CHD = tFile.MD5CHD; + + CHDVersion = tFile.CHDVersion; + + FileStatusSet( + FileStatus.SizeFromHeader | FileStatus.CRCFromHeader | FileStatus.SHA1FromHeader | FileStatus.MD5FromHeader | FileStatus.SHA1CHDFromHeader | FileStatus.MD5CHDFromHeader | + FileStatus.SizeVerified | FileStatus.CRCVerified | FileStatus.SHA1Verified | FileStatus.MD5Verified | FileStatus.SHA1CHDVerified | FileStatus.MD5CHDVerified, + tFile); + + ZipFileIndex = tFile.ZipFileIndex; + ZipFileHeaderPosition = tFile.ZipFileHeaderPosition; + + base.FileAdd(file); + } + + public override void CopyTo(RvBase c) + { + RvFile cf = c as RvFile; + if (cf != null) + { + cf.Size = Size; + cf.CRC = CRC; + cf.SHA1 = SHA1; + cf.MD5 = MD5; + cf.Merge = Merge; + cf.Status = Status; + cf._fileStatus = _fileStatus; + cf.SHA1CHD = SHA1CHD; + cf.MD5CHD = MD5CHD; + + cf.ZipFileIndex = ZipFileIndex; + cf.ZipFileHeaderPosition = ZipFileHeaderPosition; + + cf.CHDVersion = CHDVersion; + } + base.CopyTo(c); + } + + + + + public void FileStatusSet(FileStatus flag) + { + _fileStatus |= flag; + } + public void FileStatusSet(FileStatus flag, RvFile copyFrom) + { + _fileStatus |= (flag & copyFrom._fileStatus); + } + + + + private void FileStatusClear(FileStatus flag) + { + _fileStatus &= ~flag; + } + public bool FileStatusIs(FileStatus flag) + { + return (_fileStatus & flag) == flag; + } + + + + } + +} diff --git a/ROMVault2/RvDB/RvGame.cs b/ROMVault2/RvDB/RvGame.cs new file mode 100644 index 0000000..c2cd0c3 --- /dev/null +++ b/ROMVault2/RvDB/RvGame.cs @@ -0,0 +1,122 @@ +/****************************************************** + * ROMVault2 is written by Gordon J. * + * Contact gordon@romvault.com * + * Copyright 2014 * + ******************************************************/ + +using System; +using System.Collections.Generic; +using System.IO; + +namespace ROMVault2.RvDB +{ + public class RvGame + { + + public enum GameData + { + Description = 1, + RomOf = 2, + IsBios = 3, + Sourcefile = 4, + CloneOf = 5, + SampleOf = 6, + Board = 7, + Year = 8, + Manufacturer = 9, + + Trurip = 10, + Publisher = 11, + Developer = 12, + Edition = 13, + Version = 14, + Type = 15, + Media = 16, + Language = 17, + Players = 18, + Ratings = 19, + Peripheral = 20, + Genre = 21, + MediaCatalogNumber=22, + BarCode=23 + } + + private class GameMetaData + { + public GameData Id { get; private set; } + public String Value { get; private set; } + + public GameMetaData(GameData id, String value) + { + Id = id; + Value = value; + } + public GameMetaData(BinaryReader br) + { + Id = (GameData)br.ReadByte(); + Value = br.ReadString(); + } + + public void Write(BinaryWriter bw) + { + bw.Write((byte)Id); + bw.Write(DB.Fn(Value)); + } + } + + private readonly List _gameMetaData = new List(); + + + public void Write(BinaryWriter bw) + { + bw.Write((byte)_gameMetaData.Count); + foreach (GameMetaData gameMD in _gameMetaData) + gameMD.Write(bw); + } + + public void Read(BinaryReader br) + { + byte c = br.ReadByte(); + _gameMetaData.Clear(); + _gameMetaData.Capacity = c; + for (byte i = 0; i < c; i++) + _gameMetaData.Add(new GameMetaData(br)); + } + + public void AddData(GameData id, string val) + { + if (string.IsNullOrEmpty(val)) + return; + + int pos = 0; + while (pos < _gameMetaData.Count && _gameMetaData[pos].Id < id) + pos++; + + _gameMetaData.Insert(pos, new GameMetaData(id, val)); + } + + public string GetData(GameData id) + { + foreach (GameMetaData gameMD in _gameMetaData) + { + if (id == gameMD.Id) return gameMD.Value; + if (id < gameMD.Id) return ""; + } + return ""; + } + + public void DeleteData(GameData id) + { + for (int i = 0; i < _gameMetaData.Count; i++) + { + if (id == _gameMetaData[i].Id) + { + _gameMetaData.RemoveAt(i); + return; + } + if (id < _gameMetaData[i].Id) return; + } + } + } + +} diff --git a/ROMVault2/Service References/RVRef/Reference.cs b/ROMVault2/Service References/RVRef/Reference.cs new file mode 100644 index 0000000..23e665c --- /dev/null +++ b/ROMVault2/Service References/RVRef/Reference.cs @@ -0,0 +1,137 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.34003 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace ROMVault2.RVRef { + + + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ServiceModel.ServiceContractAttribute(ConfigurationName="RVRef.IService1")] + public interface IService1 { + + [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IService1/CheckPassword", ReplyAction="http://tempuri.org/IService1/CheckPasswordResponse")] + string CheckPassword(string username, string password); + + [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IService1/SendUser", ReplyAction="http://tempuri.org/IService1/SendUserResponse")] + string SendUser(string username, string email, int version); + + [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IService1/SendUser1", ReplyAction="http://tempuri.org/IService1/SendUser1Response")] + string SendUser1(string username, string email, string version, int subversion); + + [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IService1/GetLatestVersion", ReplyAction="http://tempuri.org/IService1/GetLatestVersionResponse")] + int GetLatestVersion(int versionNow); + + [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IService1/GetLatestVersion1", ReplyAction="http://tempuri.org/IService1/GetLatestVersion1Response")] + string GetLatestVersion1(string version, int subversion); + + [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IService1/GetUpdateLink", ReplyAction="http://tempuri.org/IService1/GetUpdateLinkResponse")] + string GetUpdateLink(); + + [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IService1/GetUpdateLink1", ReplyAction="http://tempuri.org/IService1/GetUpdateLink1Response")] + string GetUpdateLink1(string version, int subversion); + + [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IService1/SendErrorMessage", ReplyAction="http://tempuri.org/IService1/SendErrorMessageResponse")] + void SendErrorMessage(string username, string error); + + [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IService1/SendErrorMessage1", ReplyAction="http://tempuri.org/IService1/SendErrorMessage1Response")] + void SendErrorMessage1(string username, string email, string error); + + [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IService1/SendErrorMessage2", ReplyAction="http://tempuri.org/IService1/SendErrorMessage2Response")] + void SendErrorMessage2(string username, string email, int version, string error); + + [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IService1/SendErrorMessage3", ReplyAction="http://tempuri.org/IService1/SendErrorMessage3Response")] + void SendErrorMessage3(string username, string email, string version, int subversion, string error); + + [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IService1/SendDATErrorMessage2", ReplyAction="http://tempuri.org/IService1/SendDATErrorMessage2Response")] + void SendDATErrorMessage2(string username, string email, int version, string error, string filename); + + [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IService1/SendDATErrorMessage3", ReplyAction="http://tempuri.org/IService1/SendDATErrorMessage3Response")] + void SendDATErrorMessage3(string username, string email, string version, int subversion, string error, string filename); + } + + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + public interface IService1Channel : ROMVault2.RVRef.IService1, System.ServiceModel.IClientChannel { + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + public partial class Service1Client : System.ServiceModel.ClientBase, ROMVault2.RVRef.IService1 { + + public Service1Client() { + } + + public Service1Client(string endpointConfigurationName) : + base(endpointConfigurationName) { + } + + public Service1Client(string endpointConfigurationName, string remoteAddress) : + base(endpointConfigurationName, remoteAddress) { + } + + public Service1Client(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) : + base(endpointConfigurationName, remoteAddress) { + } + + public Service1Client(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) : + base(binding, remoteAddress) { + } + + public string CheckPassword(string username, string password) { + return base.Channel.CheckPassword(username, password); + } + + public string SendUser(string username, string email, int version) { + return base.Channel.SendUser(username, email, version); + } + + public string SendUser1(string username, string email, string version, int subversion) { + return base.Channel.SendUser1(username, email, version, subversion); + } + + public int GetLatestVersion(int versionNow) { + return base.Channel.GetLatestVersion(versionNow); + } + + public string GetLatestVersion1(string version, int subversion) { + return base.Channel.GetLatestVersion1(version, subversion); + } + + public string GetUpdateLink() { + return base.Channel.GetUpdateLink(); + } + + public string GetUpdateLink1(string version, int subversion) { + return base.Channel.GetUpdateLink1(version, subversion); + } + + public void SendErrorMessage(string username, string error) { + base.Channel.SendErrorMessage(username, error); + } + + public void SendErrorMessage1(string username, string email, string error) { + base.Channel.SendErrorMessage1(username, email, error); + } + + public void SendErrorMessage2(string username, string email, int version, string error) { + base.Channel.SendErrorMessage2(username, email, version, error); + } + + public void SendErrorMessage3(string username, string email, string version, int subversion, string error) { + base.Channel.SendErrorMessage3(username, email, version, subversion, error); + } + + public void SendDATErrorMessage2(string username, string email, int version, string error, string filename) { + base.Channel.SendDATErrorMessage2(username, email, version, error, filename); + } + + public void SendDATErrorMessage3(string username, string email, string version, int subversion, string error, string filename) { + base.Channel.SendDATErrorMessage3(username, email, version, subversion, error, filename); + } + } +} diff --git a/ROMVault2/Service References/RVRef/Reference.svcmap b/ROMVault2/Service References/RVRef/Reference.svcmap new file mode 100644 index 0000000..5c2ebfa --- /dev/null +++ b/ROMVault2/Service References/RVRef/Reference.svcmap @@ -0,0 +1,33 @@ + + + + false + true + + false + false + false + + + true + Auto + true + true + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ROMVault2/Service References/RVRef/Service1.xsd b/ROMVault2/Service References/RVRef/Service1.xsd new file mode 100644 index 0000000..32e1c19 --- /dev/null +++ b/ROMVault2/Service References/RVRef/Service1.xsd @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ROMVault2/Service References/RVRef/Service11.disco b/ROMVault2/Service References/RVRef/Service11.disco new file mode 100644 index 0000000..d705778 --- /dev/null +++ b/ROMVault2/Service References/RVRef/Service11.disco @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/ROMVault2/Service References/RVRef/Service11.wsdl b/ROMVault2/Service References/RVRef/Service11.wsdl new file mode 100644 index 0000000..9dd5eac --- /dev/null +++ b/ROMVault2/Service References/RVRef/Service11.wsdl @@ -0,0 +1,266 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ROMVault2/Service References/RVRef/Service11.xsd b/ROMVault2/Service References/RVRef/Service11.xsd new file mode 100644 index 0000000..e6bd8df --- /dev/null +++ b/ROMVault2/Service References/RVRef/Service11.xsd @@ -0,0 +1,198 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ROMVault2/Service References/RVRef/configuration.svcinfo b/ROMVault2/Service References/RVRef/configuration.svcinfo new file mode 100644 index 0000000..36c7f28 --- /dev/null +++ b/ROMVault2/Service References/RVRef/configuration.svcinfo @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/ROMVault2/Service References/RVRef/configuration91.svcinfo b/ROMVault2/Service References/RVRef/configuration91.svcinfo new file mode 100644 index 0000000..a1e7b23 --- /dev/null +++ b/ROMVault2/Service References/RVRef/configuration91.svcinfo @@ -0,0 +1,201 @@ + + + + + + + BasicHttpBinding_IService1 + + + + + + + + + + + + + + + + + + + + + StrongWildcard + + + + + + 65536 + + + + + + + + + System.ServiceModel.Configuration.XmlDictionaryReaderQuotasElement + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + System.Text.UTF8Encoding + + + Buffered + + + + + + Text + + + System.ServiceModel.Configuration.BasicHttpSecurityElement + + + None + + + System.ServiceModel.Configuration.HttpTransportSecurityElement + + + None + + + None + + + System.Security.Authentication.ExtendedProtection.Configuration.ExtendedProtectionPolicyElement + + + Never + + + TransportSelected + + + (Collection) + + + + + + System.ServiceModel.Configuration.BasicHttpMessageSecurityElement + + + UserName + + + Default + + + + + + + + + http://services.romvault.com/Service1.svc + + + + + + basicHttpBinding + + + BasicHttpBinding_IService1 + + + RVRef.IService1 + + + System.ServiceModel.Configuration.AddressHeaderCollectionElement + + + <Header /> + + + System.ServiceModel.Configuration.IdentityElement + + + System.ServiceModel.Configuration.UserPrincipalNameElement + + + + + + System.ServiceModel.Configuration.ServicePrincipalNameElement + + + + + + System.ServiceModel.Configuration.DnsElement + + + + + + System.ServiceModel.Configuration.RsaElement + + + + + + System.ServiceModel.Configuration.CertificateElement + + + + + + System.ServiceModel.Configuration.CertificateReferenceElement + + + My + + + LocalMachine + + + FindBySubjectDistinguishedName + + + + + + False + + + BasicHttpBinding_IService1 + + + + + + + + + + + \ No newline at end of file diff --git a/ROMVault2/Settings.cs b/ROMVault2/Settings.cs new file mode 100644 index 0000000..a5b726b --- /dev/null +++ b/ROMVault2/Settings.cs @@ -0,0 +1,314 @@ +/****************************************************** + * ROMVault2 is written by Gordon J. * + * Contact gordon@romvault.com * + * Copyright 2014 * + ******************************************************/ + +using System; +using System.Collections.Generic; +using System.IO; +using Microsoft.Win32; +using ROMVault2.RvDB; + +namespace ROMVault2 +{ + + public enum eScanLevel + { + Level1, + Level2, + Level3 + } + + + public enum eFixLevel + { + TrrntZipLevel1, + TrrntZipLevel2, + TrrntZipLevel3, + Level1, + Level2, + Level3 + } + + public static class Settings + { + + public static string DatRoot; + public static string CacheFile; + public static eScanLevel ScanLevel; + public static eFixLevel FixLevel; + + public static List DirPathMap; + + public static List IgnoreFiles; + + public static bool DoubleCheckDelete = true; + public static bool DebugLogsEnabled; + public static bool CacheSaveTimerEnabled = true; + public static int CacheSaveTimePeriod = 10; + + public static string EMail + { + get + { + RegistryKey regKey1 = Registry.CurrentUser; + regKey1 = regKey1.CreateSubKey("Software\\RomVault2\\User"); + return regKey1.GetValue("Email", "").ToString(); + + } + + set + { + RegistryKey regKey = Registry.CurrentUser; + regKey = regKey.CreateSubKey("Software\\RomVault2\\User"); + regKey.SetValue("Email", value); + } + } + + public static string Username + { + get + { + RegistryKey regKey1 = Registry.CurrentUser; + regKey1 = regKey1.CreateSubKey("Software\\RomVault2\\User"); + return regKey1.GetValue("UserName", "").ToString(); + + } + set + { + RegistryKey regKey = Registry.CurrentUser; + regKey = regKey.CreateSubKey("Software\\RomVault2\\User"); + regKey.SetValue("UserName", value); + } + } + + + + + public static void SetDefaults() + { + CacheFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "RomVault2_"+DBVersion.Version+".Cache"); + + //DatRoot = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "DatRoot"); + DatRoot = "DatRoot"; + + ScanLevel = eScanLevel.Level2; + FixLevel = eFixLevel.TrrntZipLevel2; + + IgnoreFiles = new List { "_ReadMe_.txt" }; + + ResetDirectories(); + + ReadConfig(); + + DirPathMap.Sort(); + } + + public static void ResetDirectories() + { + DirPathMap = new List + { + new DirMap("RomVault", "RomRoot"), + new DirMap("ToSort", "ToSort") + }; + } + + public static string ToSort() + { + foreach (DirMap t in DirPathMap) + { + if (t.DirKey == "ToSort") + return t.DirPath; + } + return Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "ToSort"); + } + + public static void WriteConfig() + { + if (File.Exists(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "RomVault2.cfg"))) + File.Delete(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "RomVault2.cfg")); + + FileStream fs = new FileStream(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "RomVault2.cfg"), FileMode.CreateNew, FileAccess.Write); + BinaryWriter bw = new BinaryWriter(fs); + const int ver = 5; + + bw.Write(ver); //int + bw.Write(DatRoot); //string + bw.Write((Int32)ScanLevel); + bw.Write((Int32)FixLevel); + bw.Write(DebugLogsEnabled); //bool + + bw.Write(IgnoreFiles.Count); //int + foreach (string t in IgnoreFiles) + { + bw.Write(t); //string + } + + bw.Write(DirPathMap.Count); //int + foreach (DirMap t in DirPathMap) + { + bw.Write(t.DirKey); //string + bw.Write(t.DirPath); //string + } + + bw.Write(CacheSaveTimerEnabled); //bool + bw.Write(CacheSaveTimePeriod); //int + bw.Write(DoubleCheckDelete); //bool + + fs.Flush(); + fs.Close(); + } + + private static void ReadConfig() + { + if (!File.Exists(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "RomVault2.cfg"))) return; + + FileStream fs = new FileStream(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "RomVault2.cfg"), FileMode.Open, FileAccess.Read); + BinaryReader br = new BinaryReader(fs); + + int ver = br.ReadInt32(); + if (ver == 1) + { + DatRoot = br.ReadString(); + ScanLevel = eScanLevel.Level1; + FixLevel = (eFixLevel)br.ReadInt32(); + + IgnoreFiles = new List(); + int c = br.ReadInt32(); + for (int i = 0; i < c; i++) + IgnoreFiles.Add(br.ReadString()); + + DirPathMap = new List(); + c = br.ReadInt32(); + for (int i = 0; i < c; i++) + DirPathMap.Add(new DirMap(br.ReadString(), br.ReadString())); + } + if (ver == 2) + { + DatRoot = br.ReadString(); + ScanLevel = (eScanLevel)br.ReadInt32(); + FixLevel = (eFixLevel)br.ReadInt32(); + + IgnoreFiles = new List(); + int c = br.ReadInt32(); + for (int i = 0; i < c; i++) + IgnoreFiles.Add(br.ReadString()); + + DirPathMap = new List(); + c = br.ReadInt32(); + for (int i = 0; i < c; i++) + DirPathMap.Add(new DirMap(br.ReadString(), br.ReadString())); + } + if (ver == 3) + { + DatRoot = br.ReadString(); + ScanLevel = (eScanLevel)br.ReadInt32(); + FixLevel = (eFixLevel)br.ReadInt32(); + DebugLogsEnabled = br.ReadBoolean(); + + IgnoreFiles = new List(); + int c = br.ReadInt32(); + for (int i = 0; i < c; i++) + IgnoreFiles.Add(br.ReadString()); + + DirPathMap = new List(); + c = br.ReadInt32(); + for (int i = 0; i < c; i++) + DirPathMap.Add(new DirMap(br.ReadString(), br.ReadString())); + } + + if (ver == 4) + { + DatRoot = br.ReadString(); + ScanLevel = (eScanLevel)br.ReadInt32(); + FixLevel = (eFixLevel)br.ReadInt32(); + DebugLogsEnabled = br.ReadBoolean(); + + IgnoreFiles = new List(); + int c = br.ReadInt32(); + for (int i = 0; i < c; i++) + IgnoreFiles.Add(br.ReadString()); + + DirPathMap = new List(); + c = br.ReadInt32(); + for (int i = 0; i < c; i++) + DirPathMap.Add(new DirMap(br.ReadString(), br.ReadString())); + + CacheSaveTimerEnabled = br.ReadBoolean(); + CacheSaveTimePeriod = br.ReadInt32(); + } + + if (ver == 5) + { + DatRoot = br.ReadString(); + ScanLevel = (eScanLevel)br.ReadInt32(); + FixLevel = (eFixLevel)br.ReadInt32(); + DebugLogsEnabled = br.ReadBoolean(); + + IgnoreFiles = new List(); + int c = br.ReadInt32(); + for (int i = 0; i < c; i++) + IgnoreFiles.Add(br.ReadString()); + + DirPathMap = new List(); + c = br.ReadInt32(); + for (int i = 0; i < c; i++) + DirPathMap.Add(new DirMap(br.ReadString(), br.ReadString())); + + CacheSaveTimerEnabled = br.ReadBoolean(); + CacheSaveTimePeriod = br.ReadInt32(); + + DoubleCheckDelete = br.ReadBoolean(); + } + + if (ver == 6) + { + DatRoot = br.ReadString(); + ScanLevel = (eScanLevel)br.ReadInt32(); + FixLevel = (eFixLevel)br.ReadInt32(); + DebugLogsEnabled = br.ReadBoolean(); + bool UserLongFilenames = br.ReadBoolean(); + + IgnoreFiles = new List(); + int c = br.ReadInt32(); + for (int i = 0; i < c; i++) + IgnoreFiles.Add(br.ReadString()); + + DirPathMap = new List(); + c = br.ReadInt32(); + for (int i = 0; i < c; i++) + DirPathMap.Add(new DirMap(br.ReadString(), br.ReadString())); + + CacheSaveTimerEnabled = br.ReadBoolean(); + CacheSaveTimePeriod = br.ReadInt32(); + + DoubleCheckDelete = br.ReadBoolean(); + } + + + br.Close(); + fs.Close(); + } + } + + + public class DirMap : IComparable + { + public readonly string DirKey; + public readonly string DirPath; + + public DirMap(string key, string path) + { + DirKey = key; + DirPath = path; + } + + public int CompareTo(DirMap obj) + { + return Math.Sign(String.Compare(DirKey, obj.DirKey, StringComparison.Ordinal)); + } + } +} + + diff --git a/ROMVault2/SupportedFiles/CHD/CHD.cs b/ROMVault2/SupportedFiles/CHD/CHD.cs new file mode 100644 index 0000000..36131b7 --- /dev/null +++ b/ROMVault2/SupportedFiles/CHD/CHD.cs @@ -0,0 +1,438 @@ +/****************************************************** + * ROMVault2 is written by Gordon J. * + * Contact gordon@romvault.com * + * Copyright 2014 * + ******************************************************/ + +using System; +using System.ComponentModel; +using System.Diagnostics; +using System.IO; +using ROMVault2.IO; +using File = System.IO.File; +using Path = System.IO.Path; + +namespace ROMVault2.SupportedFiles.CHD +{ + public static class CHD + { + private const int MaxHeader = 124; + + public static int CheckFile(IO.FileInfo ofile, out byte[] SHA1CHD, out byte[] MD5CHD, out uint? version) + { + + SHA1CHD = null; + MD5CHD = null; + version = null; + + string ext = IO.Path.GetExtension(ofile.Name).ToLower(); + if (ext != ".chd") + return 0; + + + if (ofile.Length < MaxHeader) + return 0; + + + Stream s; + int retval = IO.FileStream.OpenFileRead(ofile.FullName, out s); + if (retval != 0) + return retval; + if (s == null) return 1; + + CheckFile(s, out SHA1CHD, out MD5CHD, out version); + + s.Close(); + s.Dispose(); + + return 0; + } + + + private static void CheckFile(Stream s, out byte[] SHA1CHD, out byte[] MD5CHD, out uint? version) + { + using (BinaryReader br = new BinaryReader(s)) + { + byte[] buff = br.ReadBytes(MaxHeader); + + CheckFile(buff, out SHA1CHD, out MD5CHD, out version); + } + } + + private static void CheckFile(byte[] buff, out byte[] SHA1CHD, out byte[] MD5CHD, out uint? version) + { + + SHA1CHD = null; + MD5CHD = null; + version = null; + UInt32 compression = 0; + + byte[] header = new[] { (byte)'M', (byte)'C', (byte)'o', (byte)'m', (byte)'p', (byte)'r', (byte)'H', (byte)'D' }; + + for (int i = 0; i < header.Length; i++) + { + if (buff[i] != header[i]) + return; + } + + UInt32 length = ReadUInt32(buff, 8); + version = ReadUInt32(buff, 12); + + if (version > 5) + return; + + switch (version) + { + case 1: + if (length != 76) return; + + // V1 header: + // [ 0] char tag[8]; // 'MComprHD' + // [ 8] UINT32 length; // length of header (including tag and length fields) + // [ 12] UINT32 version; // drive format version + // [ 16] UINT32 flags; // flags (see below) + // [ 20] UINT32 compression; // compression type + compression = ReadUInt32(buff, 20); + if (compression == 0) return; + + // [ 24] UINT32 hunksize; // 512-byte sectors per hunk + // [ 28] UINT32 totalhunks; // total # of hunks represented + // [ 32] UINT32 cylinders; // number of cylinders on hard disk + // [ 36] UINT32 heads; // number of heads on hard disk + // [ 40] UINT32 sectors; // number of sectors on hard disk + // [ 44] UINT8 md5[16]; // MD5 checksum of raw data + MD5CHD = ReadBytes(buff, 44, 16); + // [ 60] UINT8 parentmd5[16]; // MD5 checksum of parent file + // [ 76] (V1 header length) + + return; + + case 2: + if (length != 80) return; + + // V2 header: + // [ 0] char tag[8]; // 'MComprHD' + // [ 8] UINT32 length; // length of header (including tag and length fields) + // [ 12] UINT32 version; // drive format version + // [ 16] UINT32 flags; // flags (see below) + // [ 20] UINT32 compression; // compression type + compression = ReadUInt32(buff, 20); + if (compression == 0) return; + + // [ 24] UINT32 hunksize; // seclen-byte sectors per hunk + // [ 28] UINT32 totalhunks; // total # of hunks represented + // [ 32] UINT32 cylinders; // number of cylinders on hard disk + // [ 36] UINT32 heads; // number of heads on hard disk + // [ 40] UINT32 sectors; // number of sectors on hard disk + // [ 44] UINT8 md5[16]; // MD5 checksum of raw data + MD5CHD = ReadBytes(buff, 44, 16); + // [ 60] UINT8 parentmd5[16]; // MD5 checksum of parent file + // [ 76] UINT32 seclen; // number of bytes per sector + // [ 80] (V2 header length) + return; + + case 3: + if (length != 120) return; + + // V3 header: + // [ 0] char tag[8]; // 'MComprHD' + // [ 8] UINT32 length; // length of header (including tag and length fields) + // [ 12] UINT32 version; // drive format version + // [ 16] UINT32 flags; // flags (see below) + // [ 20] UINT32 compression; // compression type + compression = ReadUInt32(buff, 20); + if (compression == 0) return; + // [ 24] UINT32 totalhunks; // total # of hunks represented + // [ 28] UINT64 logicalbytes; // logical size of the data (in bytes) + // [ 36] UINT64 metaoffset; // offset to the first blob of metadata + // [ 44] UINT8 md5[16]; // MD5 checksum of raw data + MD5CHD = ReadBytes(buff, 44, 16); + // [ 60] UINT8 parentmd5[16]; // MD5 checksum of parent file + // [ 76] UINT32 hunkbytes; // number of bytes per hunk + // [ 80] UINT8 sha1[20]; // SHA1 checksum of raw data + SHA1CHD = ReadBytes(buff, 80, 20); + // [100] UINT8 parentsha1[20];// SHA1 checksum of parent file + // [120] (V3 header length) + return; + + case 4: + if (length != 108) return; + + // V4 header: + // [ 0] char tag[8]; // 'MComprHD' + // [ 8] UINT32 length; // length of header (including tag and length fields) + // [ 12] UINT32 version; // drive format version + // [ 16] UINT32 flags; // flags (see below) + // [ 20] UINT32 compression; // compression type + compression = ReadUInt32(buff, 20); + if (compression == 0) return; + // [ 24] UINT32 totalhunks; // total # of hunks represented + // [ 28] UINT64 logicalbytes; // logical size of the data (in bytes) + // [ 36] UINT64 metaoffset; // offset to the first blob of metadata + // [ 44] UINT32 hunkbytes; // number of bytes per hunk + // [ 48] UINT8 sha1[20]; // combined raw+meta SHA1 + SHA1CHD = ReadBytes(buff, 48, 20); + // [ 68] UINT8 parentsha1[20];// combined raw+meta SHA1 of parent + // [ 88] UINT8 rawsha1[20]; // raw data SHA1 + // [108] (V4 header length) + return; + + case 5: + if (length != 124) return; + + // V5 header: + // [ 0] char tag[8]; // 'MComprHD' + // [ 8] UINT32 length; // length of header (including tag and length fields) + // [ 12] UINT32 version; // drive format version + // [ 16] UINT32 compressors[4];// which custom compressors are used? + UInt32 compression0 = ReadUInt32(buff, 16); + UInt32 compression1 = ReadUInt32(buff, 20); + UInt32 compression2 = ReadUInt32(buff, 24); + UInt32 compression3 = ReadUInt32(buff, 28); + if (compression0 == 0 && compression1 == 0 && compression2 == 0 && compression3 == 0) return; + // [ 32] UINT64 logicalbytes; // logical size of the data (in bytes) + // [ 40] UINT64 mapoffset; // offset to the map + // [ 48] UINT64 metaoffset; // offset to the first blob of metadata + // [ 56] UINT32 hunkbytes; // number of bytes per hunk (512k maximum) + // [ 60] UINT32 unitbytes; // number of bytes per unit within each hunk + // [ 64] UINT8 rawsha1[20]; // raw data SHA1 + // [ 84] UINT8 sha1[20]; // combined raw+meta SHA1 + SHA1CHD = ReadBytes(buff, 84, 20); + // [104] UINT8 parentsha1[20];// combined raw+meta SHA1 of parent + // [124] (V5 header length) + return; + } + } + + + private static UInt32 ReadUInt32(byte[] b, int p) + { + return + ((UInt32)b[p + 0]) << 24 | + ((UInt32)b[p + 1]) << 16 | + ((UInt32)b[p + 2]) << 8 | + (b[p + 3]); + } + + private static byte[] ReadBytes(byte[] b, int p, int length) + { + byte[] ret = new byte[length]; + for (int i = 0; i < length; i++) + ret[i] = b[p + i]; + return ret; + } + + private static string _result; + private static BackgroundWorker _bgw; + private static CHDManCheck _resultType; + + public enum CHDManCheck + { + Unset, + Good, + Corrupt, + CHDNotFound, + ChdmanNotFound, + CHDUnknownError, + CHDReturnError + } + + + + public static CHDManCheck ChdmanCheck(string filename, BackgroundWorker bgw, out string result) + { + _bgw = bgw; + _result = ""; + _resultType = CHDManCheck.Unset; + + string chdPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "chdman.exe"); + if (!File.Exists(chdPath)) + { + result = "chdman not found"; + return CHDManCheck.ChdmanNotFound; + } + + if (!IO.File.Exists(filename)) + { + result = filename + " Not Found."; + return CHDManCheck.CHDNotFound; + } + + string shortName = NameFix.GetShortPath(filename); + + + using (Process exeProcess = new Process()) + { + exeProcess.StartInfo.FileName = chdPath; + ReportError.LogOut("CHD: FileName :" + exeProcess.StartInfo.FileName); + + + exeProcess.StartInfo.Arguments = "verify -i \"" + shortName + "\""; + ReportError.LogOut("CHD: Arguments :" + exeProcess.StartInfo.Arguments); + + // Set UseShellExecute to false for redirection. + exeProcess.StartInfo.UseShellExecute = false; + // Stops the Command window from popping up. + exeProcess.StartInfo.CreateNoWindow = true; + + // Redirect the standard output. + // This stream is read asynchronously using an event handler. + exeProcess.StartInfo.RedirectStandardOutput = true; + exeProcess.StartInfo.RedirectStandardError = true; + + // Set our event handler to asynchronously read the process output. + exeProcess.OutputDataReceived += CHDOutputHandler; + exeProcess.ErrorDataReceived += CHDErrorHandler; + + _outputLineCount = 0; + _errorLines=0; + + ReportError.LogOut("CHD: Scanning Starting"); + exeProcess.Start(); + + // Start the asynchronous read of the process output stream. + exeProcess.BeginOutputReadLine(); + exeProcess.BeginErrorReadLine(); + + // Wait for the process finish. + exeProcess.WaitForExit(); + ReportError.LogOut("CHD: Scanning Finished"); + + } + + result = _result; + + if (_resultType == CHDManCheck.Unset) + _resultType = CHDManCheck.Good; + + _bgw.ReportProgress(0, new bgwText3("")); + + ReportError.LogOut("CHD: returning result " + _resultType + " " + result); + + return _resultType; + } + + /* + chdman - MAME Compressed Hunks of Data (CHD) manager 0.147 (Sep 18 2012) + Raw SHA1 verification successful! + Overall SHA1 verification successful! + */ + + private static int _outputLineCount; + + private static void CHDOutputHandler(object sendingProcess, DataReceivedEventArgs outLine) + { + // Collect the process command output. + if (String.IsNullOrEmpty(outLine.Data)) return; + + string sOut = outLine.Data; + //ReportError.LogOut("CHDOutput: " + _outputLineCount + " : " + sOut); + switch (_outputLineCount) + { + case 0: + if (sOut.Length < 53 || sOut.Substring(0, 53) != "chdman - MAME Compressed Hunks of Data (CHD) manager ") + { + _result = "Incorrect startup of CHDMan :" + sOut; + _resultType = CHDManCheck.CHDReturnError; + } + break; + case 1: + if (sOut != "Raw SHA1 verification successful!") + { + _result = "Raw SHA1 check failed :" + sOut; + _resultType = CHDManCheck.CHDReturnError; + } + break; + case 2: + if (sOut != "Overall SHA1 verification successful!") + { + _result = "Overall SHA1 check failed :" + sOut; + _resultType = CHDManCheck.CHDReturnError; + } + break; + default: + _result = "Unexpected output from chdman :" + sOut; + ReportError.SendErrorMessage("CHDOutputHandler returned =" + sOut); + _resultType = CHDManCheck.CHDUnknownError; + break; + } + + _outputLineCount++; + } + + private static int _errorLines; + + private static void CHDErrorHandler(object sendingProcess, DataReceivedEventArgs outLine) + { + // Collect the process command output. + if (String.IsNullOrEmpty(outLine.Data)) return; + + string sOut = outLine.Data; + ReportError.LogOut("CHDError: " + sOut); + + _bgw.ReportProgress(0, new bgwText3(sOut)); + + if (_resultType != CHDManCheck.Unset) + { + if(_errorLines>0) + { + _errorLines -= 1; + _result += "\r\n" + sOut; + } + return; + } + + if (sOut.Length > 44) + if (sOut.Substring(0, 23) == "Error reading CHD file " && sOut.Substring(sOut.Length - 21, 21) == ": decompression error") + { + _result = sOut; + _resultType = CHDManCheck.Corrupt; + return; + } + if (sOut.Length > 35) + if (sOut.Substring(0, 23) == "Error opening CHD file " && sOut.Substring(sOut.Length - 21, 21) == ": decompression error") + { + _result = sOut; + _resultType = CHDManCheck.Corrupt; + return; + } + if (sOut.Length > 35) + if (sOut.Substring(0, 23) == "Error opening CHD file " && sOut.Substring(sOut.Length - 12, 12) == ": read error") + { + _result = sOut; + _resultType = CHDManCheck.Corrupt; + return; + } + if (sOut.Length > 25) + if (sOut.Substring(0, 25) == "Error: Raw SHA1 in header") + { + _result = sOut; + _errorLines = 1; + _resultType = CHDManCheck.Corrupt; + return; + } + if (sOut.Length == 13) + if (sOut == "Out of memory") + { + _result = sOut; + _resultType = CHDManCheck.Corrupt; + return; + } + + // check for Verifying message + if (sOut.Length >= 24) + if (sOut.Substring(0, 11) == "Verifying, " && sOut.Substring(sOut.Length - 13, 13) == " complete... ") + { + //_resultType = CHDManCheck.Good; + return; + } + + + ReportError.SendErrorMessage("CHDErrorHandler returned =" + sOut); + _result = "Unknown message : " + sOut; + _resultType = CHDManCheck.CHDUnknownError; + } + + + } +} diff --git a/ROMVault2/SupportedFiles/Files/UnCompFiles.cs b/ROMVault2/SupportedFiles/Files/UnCompFiles.cs new file mode 100644 index 0000000..11bc1fb --- /dev/null +++ b/ROMVault2/SupportedFiles/Files/UnCompFiles.cs @@ -0,0 +1,70 @@ +/****************************************************** + * ROMVault2 is written by Gordon J. * + * Contact gordon@romvault.com * + * Copyright 2014 * + ******************************************************/ + +using System.IO; +using System.Security.Cryptography; +using ROMVault2.SupportedFiles.Zip.ZLib; + +namespace ROMVault2.SupportedFiles.Files +{ + public static class UnCompFiles + { + private const int Buffersize = 4096; + private static readonly byte[] Buffer; + + static UnCompFiles() + { + Buffer = new byte[Buffersize]; + } + + public static int CheckSumRead(string filename, bool testDeep, out byte[] crc, out byte[] bMD5, out byte[] bSHA1) + { + bMD5 = null; + bSHA1 = null; + crc = null; + + Stream ds; + int errorCode = IO.FileStream.OpenFileRead(filename, out ds); + if (errorCode != 0) + return errorCode; + + CRC32Hash crc32 = new CRC32Hash(); + + MD5 md5 = null; + if (testDeep) md5 = MD5.Create(); + SHA1 sha1 = null; + if (testDeep) sha1 = SHA1.Create(); + + long sizetogo = ds.Length; + + while (sizetogo > 0) + { + int sizenow = sizetogo > Buffersize ? Buffersize : (int)sizetogo; + + ds.Read(Buffer, 0, sizenow); + crc32.TransformBlock(Buffer, 0, sizenow, null, 0); + if (testDeep) md5.TransformBlock(Buffer, 0, sizenow, null, 0); + if (testDeep) sha1.TransformBlock(Buffer, 0, sizenow, null, 0); + sizetogo -= sizenow; + } + + crc32.TransformFinalBlock(Buffer, 0, 0); + if (testDeep) md5.TransformFinalBlock(Buffer, 0, 0); + if (testDeep) sha1.TransformFinalBlock(Buffer, 0, 0); + + ds.Close(); + + crc = crc32.Hash; + if (testDeep) bMD5 = md5.Hash; + if (testDeep) bSHA1 = sha1.Hash; + + return 0; + } + + + + } +} diff --git a/ROMVault2/SupportedFiles/Zip/ZLib/Crc32.cs b/ROMVault2/SupportedFiles/Zip/ZLib/Crc32.cs new file mode 100644 index 0000000..8e6ac29 --- /dev/null +++ b/ROMVault2/SupportedFiles/Zip/ZLib/Crc32.cs @@ -0,0 +1,856 @@ +// CRC32.cs +// ------------------------------------------------------------------ +// +// Copyright (c) 2011 Dino Chiesa. +// All rights reserved. +// +// This code module is part of DotNetZip, a zipfile class library. +// +// ------------------------------------------------------------------ +// +// This code is licensed under the Microsoft Public License. +// See the file License.txt for the license details. +// More info on: http://dotnetzip.codeplex.com +// +// ------------------------------------------------------------------ +// +// Last Saved: <2011-August-02 18:25:54> +// +// ------------------------------------------------------------------ +// +// This module defines the CRC32 class, which can do the CRC32 algorithm, using +// arbitrary starting polynomials, and bit reversal. The bit reversal is what +// distinguishes this CRC-32 used in BZip2 from the CRC-32 that is used in PKZIP +// files, or GZIP files. This class does both. +// +// ------------------------------------------------------------------ + + +using System; +using System.Security.Cryptography; +using System.Runtime.InteropServices; + +namespace ROMVault2.SupportedFiles.Zip.ZLib +{ + /// + /// Computes a CRC-32. The CRC-32 algorithm is parameterized - you + /// can set the polynomial and enable or disable bit + /// reversal. This can be used for GZIP, BZip2, or ZIP. + /// + /// + /// This type is used internally by DotNetZip; it is generally not used + /// directly by applications wishing to create, read, or manipulate zip + /// archive files. + /// + + [Guid("ebc25cf6-9120-4283-b972-0e5520d0000C")] + [System.Runtime.InteropServices.ComVisible(true)] +#if !NETCF + [System.Runtime.InteropServices.ClassInterface(System.Runtime.InteropServices.ClassInterfaceType.AutoDispatch)] +#endif + public class CRC32 + { + /// + /// Indicates the total number of bytes applied to the CRC. + /// + public Int64 TotalBytesRead + { + get + { + return _TotalBytesRead; + } + } + + /// + /// Indicates the current CRC for all blocks slurped in. + /// + public Int32 Crc32Result + { + get + { + return unchecked((Int32)(~_register)); + } + } + public uint Crc32ResultU + { + get + { + return ~_register; + } + } + + + /// + /// Returns the CRC32 for the specified stream. + /// + /// The stream over which to calculate the CRC32 + /// the CRC32 calculation + public Int32 GetCrc32(System.IO.Stream input) + { + return GetCrc32AndCopy(input, null); + } + + /// + /// Returns the CRC32 for the specified stream, and writes the input into the + /// output stream. + /// + /// The stream over which to calculate the CRC32 + /// The stream into which to deflate the input + /// the CRC32 calculation + public Int32 GetCrc32AndCopy(System.IO.Stream input, System.IO.Stream output) + { + if (input == null) + throw new Exception("The input stream must not be null."); + + unchecked + { + byte[] buffer = new byte[BUFFER_SIZE]; + int readSize = BUFFER_SIZE; + + _TotalBytesRead = 0; + int count = input.Read(buffer, 0, readSize); + if (output != null) output.Write(buffer, 0, count); + _TotalBytesRead += count; + while (count > 0) + { + SlurpBlock(buffer, 0, count); + count = input.Read(buffer, 0, readSize); + if (output != null) output.Write(buffer, 0, count); + _TotalBytesRead += count; + } + + return (Int32)(~_register); + } + } + + + /// + /// Get the CRC32 for the given (word,byte) combo. This is a + /// computation defined by PKzip for PKZIP 2.0 (weak) encryption. + /// + /// The word to start with. + /// The byte to combine it with. + /// The CRC-ized result. + public Int32 ComputeCrc32(Int32 W, byte B) + { + return _InternalComputeCrc32((UInt32)W, B); + } + + internal Int32 _InternalComputeCrc32(UInt32 W, byte B) + { + return (Int32)(crc32Table[(W ^ B) & 0xFF] ^ (W >> 8)); + } + + + /// + /// Update the value for the running CRC32 using the given block of bytes. + /// This is useful when using the CRC32() class in a Stream. + /// + /// block of bytes to slurp + /// starting point in the block + /// how many bytes within the block to slurp + public void SlurpBlock(byte[] block, int offset, int count) + { + if (block == null) + throw new Exception("The data buffer must not be null."); + + // bzip algorithm + for (int i = 0; i < count; i++) + { + int x = offset + i; + byte b = block[x]; + if (this.reverseBits) + { + UInt32 temp = (_register >> 24) ^ b; + _register = (_register << 8) ^ crc32Table[temp]; + } + else + { + UInt32 temp = (_register & 0x000000FF) ^ b; + _register = (_register >> 8) ^ crc32Table[temp]; + } + } + _TotalBytesRead += count; + } + + + /// + /// Process one byte in the CRC. + /// + /// the byte to include into the CRC . + public void UpdateCRC(byte b) + { + if (this.reverseBits) + { + UInt32 temp = (_register >> 24) ^ b; + _register = (_register << 8) ^ crc32Table[temp]; + } + else + { + UInt32 temp = (_register & 0x000000FF) ^ b; + _register = (_register >> 8) ^ crc32Table[temp]; + } + } + + /// + /// Process a run of N identical bytes into the CRC. + /// + /// + /// + /// This method serves as an optimization for updating the CRC when a + /// run of identical bytes is found. Rather than passing in a buffer of + /// length n, containing all identical bytes b, this method accepts the + /// byte value and the length of the (virtual) buffer - the length of + /// the run. + /// + /// + /// the byte to include into the CRC. + /// the number of times that byte should be repeated. + public void UpdateCRC(byte b, int n) + { + while (n-- > 0) + { + if (this.reverseBits) + { + uint temp = (_register >> 24) ^ b; + _register = (_register << 8) ^ crc32Table[(temp >= 0) + ? temp + : (temp + 256)]; + } + else + { + UInt32 temp = (_register & 0x000000FF) ^ b; + _register = (_register >> 8) ^ crc32Table[(temp >= 0) + ? temp + : (temp + 256)]; + + } + } + } + + + + private static uint ReverseBits(uint data) + { + unchecked + { + uint ret = data; + ret = (ret & 0x55555555) << 1 | (ret >> 1) & 0x55555555; + ret = (ret & 0x33333333) << 2 | (ret >> 2) & 0x33333333; + ret = (ret & 0x0F0F0F0F) << 4 | (ret >> 4) & 0x0F0F0F0F; + ret = (ret << 24) | ((ret & 0xFF00) << 8) | ((ret >> 8) & 0xFF00) | (ret >> 24); + return ret; + } + } + + private static byte ReverseBits(byte data) + { + unchecked + { + uint u = (uint)data * 0x00020202; + uint m = 0x01044010; + uint s = u & m; + uint t = (u << 2) & (m << 1); + return (byte)((0x01001001 * (s + t)) >> 24); + } + } + + + + private void GenerateLookupTable() + { + crc32Table = new UInt32[256]; + unchecked + { + UInt32 dwCrc; + byte i = 0; + do + { + dwCrc = i; + for (byte j = 8; j > 0; j--) + { + if ((dwCrc & 1) == 1) + { + dwCrc = (dwCrc >> 1) ^ dwPolynomial; + } + else + { + dwCrc >>= 1; + } + } + if (reverseBits) + { + crc32Table[ReverseBits(i)] = ReverseBits(dwCrc); + } + else + { + crc32Table[i] = dwCrc; + } + i++; + } while (i != 0); + } + +#if VERBOSE + Console.WriteLine(); + Console.WriteLine("private static readonly UInt32[] crc32Table = {"); + for (int i = 0; i < crc32Table.Length; i+=4) + { + Console.Write(" "); + for (int j=0; j < 4; j++) + { + Console.Write(" 0x{0:X8}U,", crc32Table[i+j]); + } + Console.WriteLine(); + } + Console.WriteLine("};"); + Console.WriteLine(); +#endif + } + + + private uint gf2_matrix_times(uint[] matrix, uint vec) + { + uint sum = 0; + int i = 0; + while (vec != 0) + { + if ((vec & 0x01) == 0x01) + sum ^= matrix[i]; + vec >>= 1; + i++; + } + return sum; + } + + private void gf2_matrix_square(uint[] square, uint[] mat) + { + for (int i = 0; i < 32; i++) + square[i] = gf2_matrix_times(mat, mat[i]); + } + + + + /// + /// Combines the given CRC32 value with the current running total. + /// + /// + /// This is useful when using a divide-and-conquer approach to + /// calculating a CRC. Multiple threads can each calculate a + /// CRC32 on a segment of the data, and then combine the + /// individual CRC32 values at the end. + /// + /// the crc value to be combined with this one + /// the length of data the CRC value was calculated on + public void Combine(int crc, int length) + { + uint[] even = new uint[32]; // even-power-of-two zeros operator + uint[] odd = new uint[32]; // odd-power-of-two zeros operator + + if (length == 0) + return; + + uint crc1 = ~_register; + uint crc2 = (uint)crc; + + // put operator for one zero bit in odd + odd[0] = this.dwPolynomial; // the CRC-32 polynomial + uint row = 1; + for (int i = 1; i < 32; i++) + { + odd[i] = row; + row <<= 1; + } + + // put operator for two zero bits in even + gf2_matrix_square(even, odd); + + // put operator for four zero bits in odd + gf2_matrix_square(odd, even); + + uint len2 = (uint)length; + + // apply len2 zeros to crc1 (first square will put the operator for one + // zero byte, eight zero bits, in even) + do + { + // apply zeros operator for this bit of len2 + gf2_matrix_square(even, odd); + + if ((len2 & 1) == 1) + crc1 = gf2_matrix_times(even, crc1); + len2 >>= 1; + + if (len2 == 0) + break; + + // another iteration of the loop with odd and even swapped + gf2_matrix_square(odd, even); + if ((len2 & 1) == 1) + crc1 = gf2_matrix_times(odd, crc1); + len2 >>= 1; + + + } while (len2 != 0); + + crc1 ^= crc2; + + _register = ~crc1; + + //return (int) crc1; + return; + } + + + /// + /// Create an instance of the CRC32 class using the default settings: no + /// bit reversal, and a polynomial of 0xEDB88320. + /// + public CRC32() + : this(false) + { + } + + /// + /// Create an instance of the CRC32 class, specifying whether to reverse + /// data bits or not. + /// + /// + /// specify true if the instance should reverse data bits. + /// + /// + /// + /// In the CRC-32 used by BZip2, the bits are reversed. Therefore if you + /// want a CRC32 with compatibility with BZip2, you should pass true + /// here. In the CRC-32 used by GZIP and PKZIP, the bits are not + /// reversed; Therefore if you want a CRC32 with compatibility with + /// those, you should pass false. + /// + /// + public CRC32(bool reverseBits) : + this(unchecked((int)0xEDB88320), reverseBits) + { + } + + + /// + /// Create an instance of the CRC32 class, specifying the polynomial and + /// whether to reverse data bits or not. + /// + /// + /// The polynomial to use for the CRC, expressed in the reversed (LSB) + /// format: the highest ordered bit in the polynomial value is the + /// coefficient of the 0th power; the second-highest order bit is the + /// coefficient of the 1 power, and so on. Expressed this way, the + /// polynomial for the CRC-32C used in IEEE 802.3, is 0xEDB88320. + /// + /// + /// specify true if the instance should reverse data bits. + /// + /// + /// + /// + /// In the CRC-32 used by BZip2, the bits are reversed. Therefore if you + /// want a CRC32 with compatibility with BZip2, you should pass true + /// here for the reverseBits parameter. In the CRC-32 used by + /// GZIP and PKZIP, the bits are not reversed; Therefore if you want a + /// CRC32 with compatibility with those, you should pass false for the + /// reverseBits parameter. + /// + /// + public CRC32(int polynomial, bool reverseBits) + { + this.reverseBits = reverseBits; + this.dwPolynomial = (uint)polynomial; + this.GenerateLookupTable(); + } + + /// + /// Reset the CRC-32 class - clear the CRC "remainder register." + /// + /// + /// + /// Use this when employing a single instance of this class to compute + /// multiple, distinct CRCs on multiple, distinct data blocks. + /// + /// + public void Reset() + { + _register = 0xFFFFFFFFU; + } + + // private member vars + private UInt32 dwPolynomial; + private Int64 _TotalBytesRead; + private bool reverseBits; + private UInt32[] crc32Table; + private const int BUFFER_SIZE = 8192; + private UInt32 _register = 0xFFFFFFFFU; + } + + + /// + /// A Stream that calculates a CRC32 (a checksum) on all bytes read, + /// or on all bytes written. + /// + /// + /// + /// + /// This class can be used to verify the CRC of a ZipEntry when + /// reading from a stream, or to calculate a CRC when writing to a + /// stream. The stream should be used to either read, or write, but + /// not both. If you intermix reads and writes, the results are not + /// defined. + /// + /// + /// + /// This class is intended primarily for use internally by the + /// DotNetZip library. + /// + /// + public class CrcCalculatorStream : System.IO.Stream, System.IDisposable + { + private static readonly Int64 UnsetLengthLimit = -99; + + internal System.IO.Stream _innerStream; + private CRC32 _Crc32; + private Int64 _lengthLimit = -99; + private bool _leaveOpen; + + /// + /// The default constructor. + /// + /// + /// + /// Instances returned from this constructor will leave the underlying + /// stream open upon Close(). The stream uses the default CRC32 + /// algorithm, which implies a polynomial of 0xEDB88320. + /// + /// + /// The underlying stream + public CrcCalculatorStream(System.IO.Stream stream) + : this(true, CrcCalculatorStream.UnsetLengthLimit, stream, null) + { + } + + /// + /// The constructor allows the caller to specify how to handle the + /// underlying stream at close. + /// + /// + /// + /// The stream uses the default CRC32 algorithm, which implies a + /// polynomial of 0xEDB88320. + /// + /// + /// The underlying stream + /// true to leave the underlying stream + /// open upon close of the CrcCalculatorStream; false otherwise. + public CrcCalculatorStream(System.IO.Stream stream, bool leaveOpen) + : this(leaveOpen, CrcCalculatorStream.UnsetLengthLimit, stream, null) + { + } + + /// + /// A constructor allowing the specification of the length of the stream + /// to read. + /// + /// + /// + /// The stream uses the default CRC32 algorithm, which implies a + /// polynomial of 0xEDB88320. + /// + /// + /// Instances returned from this constructor will leave the underlying + /// stream open upon Close(). + /// + /// + /// The underlying stream + /// The length of the stream to slurp + public CrcCalculatorStream(System.IO.Stream stream, Int64 length) + : this(true, length, stream, null) + { + if (length < 0) + throw new ArgumentException("length"); + } + + /// + /// A constructor allowing the specification of the length of the stream + /// to read, as well as whether to keep the underlying stream open upon + /// Close(). + /// + /// + /// + /// The stream uses the default CRC32 algorithm, which implies a + /// polynomial of 0xEDB88320. + /// + /// + /// The underlying stream + /// The length of the stream to slurp + /// true to leave the underlying stream + /// open upon close of the CrcCalculatorStream; false otherwise. + public CrcCalculatorStream(System.IO.Stream stream, Int64 length, bool leaveOpen) + : this(leaveOpen, length, stream, null) + { + if (length < 0) + throw new ArgumentException("length"); + } + + /// + /// A constructor allowing the specification of the length of the stream + /// to read, as well as whether to keep the underlying stream open upon + /// Close(), and the CRC32 instance to use. + /// + /// + /// + /// The stream uses the specified CRC32 instance, which allows the + /// application to specify how the CRC gets calculated. + /// + /// + /// The underlying stream + /// The length of the stream to slurp + /// true to leave the underlying stream + /// open upon close of the CrcCalculatorStream; false otherwise. + /// the CRC32 instance to use to calculate the CRC32 + public CrcCalculatorStream(System.IO.Stream stream, Int64 length, bool leaveOpen, + CRC32 crc32) + : this(leaveOpen, length, stream, crc32) + { + if (length < 0) + throw new ArgumentException("length"); + } + + + // This ctor is private - no validation is done here. This is to allow the use + // of a (specific) negative value for the _lengthLimit, to indicate that there + // is no length set. So we validate the length limit in those ctors that use an + // explicit param, otherwise we don't validate, because it could be our special + // value. + private CrcCalculatorStream + (bool leaveOpen, Int64 length, System.IO.Stream stream, CRC32 crc32) + : base() + { + _innerStream = stream; + _Crc32 = crc32 ?? new CRC32(); + _lengthLimit = length; + _leaveOpen = leaveOpen; + } + + + /// + /// Gets the total number of bytes run through the CRC32 calculator. + /// + /// + /// + /// This is either the total number of bytes read, or the total number of + /// bytes written, depending on the direction of this stream. + /// + public Int64 TotalBytesSlurped + { + get { return _Crc32.TotalBytesRead; } + } + + /// + /// Provides the current CRC for all blocks slurped in. + /// + /// + /// + /// The running total of the CRC is kept as data is written or read + /// through the stream. read this property after all reads or writes to + /// get an accurate CRC for the entire stream. + /// + /// + public Int32 Crc + { + get { return _Crc32.Crc32Result; } + } + + /// + /// Indicates whether the underlying stream will be left open when the + /// CrcCalculatorStream is Closed. + /// + /// + /// + /// Set this at any point before calling . + /// + /// + public bool LeaveOpen + { + get { return _leaveOpen; } + set { _leaveOpen = value; } + } + + /// + /// Read from the stream + /// + /// the buffer to read + /// the offset at which to start + /// the number of bytes to read + /// the number of bytes actually read + public override int Read(byte[] buffer, int offset, int count) + { + int bytesToRead = count; + + // Need to limit the # of bytes returned, if the stream is intended to have + // a definite length. This is especially useful when returning a stream for + // the uncompressed data directly to the application. The app won't + // necessarily read only the UncompressedSize number of bytes. For example + // wrapping the stream returned from OpenReader() into a StreadReader() and + // calling ReadToEnd() on it, We can "over-read" the zip data and get a + // corrupt string. The length limits that, prevents that problem. + + if (_lengthLimit != CrcCalculatorStream.UnsetLengthLimit) + { + if (_Crc32.TotalBytesRead >= _lengthLimit) return 0; // EOF + Int64 bytesRemaining = _lengthLimit - _Crc32.TotalBytesRead; + if (bytesRemaining < count) bytesToRead = (int)bytesRemaining; + } + int n = _innerStream.Read(buffer, offset, bytesToRead); + if (n > 0) _Crc32.SlurpBlock(buffer, offset, n); + return n; + } + + /// + /// Write to the stream. + /// + /// the buffer from which to write + /// the offset at which to start writing + /// the number of bytes to write + public override void Write(byte[] buffer, int offset, int count) + { + if (count > 0) _Crc32.SlurpBlock(buffer, offset, count); + _innerStream.Write(buffer, offset, count); + } + + /// + /// Indicates whether the stream supports reading. + /// + public override bool CanRead + { + get { return _innerStream.CanRead; } + } + + /// + /// Indicates whether the stream supports seeking. + /// + /// + /// + /// Always returns false. + /// + /// + public override bool CanSeek + { + get { return false; } + } + + /// + /// Indicates whether the stream supports writing. + /// + public override bool CanWrite + { + get { return _innerStream.CanWrite; } + } + + /// + /// Flush the stream. + /// + public override void Flush() + { + _innerStream.Flush(); + } + + /// + /// Returns the length of the underlying stream. + /// + public override long Length + { + get + { + if (_lengthLimit == CrcCalculatorStream.UnsetLengthLimit) + return _innerStream.Length; + else return _lengthLimit; + } + } + + /// + /// The getter for this property returns the total bytes read. + /// If you use the setter, it will throw + /// . + /// + public override long Position + { + get { return _Crc32.TotalBytesRead; } + set { throw new NotSupportedException(); } + } + + /// + /// Seeking is not supported on this stream. This method always throws + /// + /// + /// N/A + /// N/A + /// N/A + public override long Seek(long offset, System.IO.SeekOrigin origin) + { + throw new NotSupportedException(); + } + + /// + /// This method always throws + /// + /// + /// N/A + public override void SetLength(long value) + { + throw new NotSupportedException(); + } + + + void IDisposable.Dispose() + { + Close(); + } + + /// + /// Closes the stream. + /// + public override void Close() + { + base.Close(); + if (!_leaveOpen) + _innerStream.Close(); + } + + } + + + public class CRC32Hash : HashAlgorithm + { + private CRC32 _Crc32=new CRC32(); + + public override void Initialize() + { + _Crc32.Reset(); + } + protected override void HashCore(byte[] buffer, int start, int length) + { + _Crc32.SlurpBlock(buffer, start, length); + } + protected override byte[] HashFinal() + { + uint crcValue =(uint) _Crc32.Crc32Result; + HashValue = new[] + { + (byte) ((crcValue >> 24) & 0xff), + (byte) ((crcValue >> 16) & 0xff), + (byte) ((crcValue >> 8) & 0xff), + (byte) (crcValue & 0xff) + }; + return HashValue; + } + + public override int HashSize + { + get { return 32; } + } + } +} \ No newline at end of file diff --git a/ROMVault2/SupportedFiles/Zip/ZLib/Deflate.cs b/ROMVault2/SupportedFiles/Zip/ZLib/Deflate.cs new file mode 100644 index 0000000..84c6b83 --- /dev/null +++ b/ROMVault2/SupportedFiles/Zip/ZLib/Deflate.cs @@ -0,0 +1,1890 @@ +// Deflate.cs +// ------------------------------------------------------------------ +// +// Copyright (c) 2009 Dino Chiesa and Microsoft Corporation. +// All rights reserved. +// +// This code module is part of DotNetZip, a zipfile class library. +// +// ------------------------------------------------------------------ +// +// This code is licensed under the Microsoft Public License. +// See the file License.txt for the license details. +// More info on: http://dotnetzip.codeplex.com +// +// ------------------------------------------------------------------ +// +// last saved (in emacs): +// Time-stamp: <2011-August-03 19:52:15> +// +// ------------------------------------------------------------------ +// +// This module defines logic for handling the Deflate or compression. +// +// This code is based on multiple sources: +// - the original zlib v1.2.3 source, which is Copyright (C) 1995-2005 Jean-loup Gailly. +// - the original jzlib, which is Copyright (c) 2000-2003 ymnk, JCraft,Inc. +// +// However, this code is significantly different from both. +// The object model is not the same, and many of the behaviors are different. +// +// In keeping with the license for these other works, the copyrights for +// jzlib and zlib are here. +// +// ----------------------------------------------------------------------- +// Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// 2. 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. +// +// 3. The names of the authors may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 JCRAFT, +// INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE 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. +// +// ----------------------------------------------------------------------- +// +// This program is based on zlib-1.1.3; credit to authors +// Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) +// and contributors of zlib. +// +// ----------------------------------------------------------------------- + + +using System; + +namespace ROMVault2.SupportedFiles.Zip.ZLib +{ + + internal enum BlockState + { + NeedMore = 0, // block not completed, need more input or more output + BlockDone, // block flush performed + FinishStarted, // finish started, need only more output at next deflate + FinishDone // finish done, accept no more input or output + } + + internal enum DeflateFlavor + { + Store, + Fast, + Slow + } + + internal sealed class DeflateManager + { + private static readonly int MEM_LEVEL_MAX = 9; + private static readonly int MEM_LEVEL_DEFAULT = 8; + + internal delegate BlockState CompressFunc(FlushType flush); + + internal class Config + { + // Use a faster search when the previous match is longer than this + internal int GoodLength; // reduce lazy search above this match length + + // Attempt to find a better match only when the current match is + // strictly smaller than this value. This mechanism is used only for + // compression levels >= 4. For levels 1,2,3: MaxLazy is actually + // MaxInsertLength. (See DeflateFast) + + internal int MaxLazy; // do not perform lazy search above this match length + + internal int NiceLength; // quit search above this match length + + // To speed up deflation, hash chains are never searched beyond this + // length. A higher limit improves compression ratio but degrades the speed. + + internal int MaxChainLength; + + internal DeflateFlavor Flavor; + + private Config(int goodLength, int maxLazy, int niceLength, int maxChainLength, DeflateFlavor flavor) + { + this.GoodLength = goodLength; + this.MaxLazy = maxLazy; + this.NiceLength = niceLength; + this.MaxChainLength = maxChainLength; + this.Flavor = flavor; + } + + public static Config Lookup(CompressionLevel level) + { + return Table[(int)level]; + } + + + static Config() + { + Table = new Config[] { + new Config(0, 0, 0, 0, DeflateFlavor.Store), + new Config(4, 4, 8, 4, DeflateFlavor.Fast), + new Config(4, 5, 16, 8, DeflateFlavor.Fast), + new Config(4, 6, 32, 32, DeflateFlavor.Fast), + + new Config(4, 4, 16, 16, DeflateFlavor.Slow), + new Config(8, 16, 32, 32, DeflateFlavor.Slow), + new Config(8, 16, 128, 128, DeflateFlavor.Slow), + new Config(8, 32, 128, 256, DeflateFlavor.Slow), + new Config(32, 128, 258, 1024, DeflateFlavor.Slow), + new Config(32, 258, 258, 4096, DeflateFlavor.Slow), + }; + } + + private static readonly Config[] Table; + } + + + private CompressFunc DeflateFunction; + + private static readonly System.String[] _ErrorMessage = new System.String[] + { + "need dictionary", + "stream end", + "", + "file error", + "stream error", + "data error", + "insufficient memory", + "buffer error", + "incompatible version", + "" + }; + + // preset dictionary flag in zlib header + private static readonly int PRESET_DICT = 0x20; + + private static readonly int INIT_STATE = 42; + private static readonly int BUSY_STATE = 113; + private static readonly int FINISH_STATE = 666; + + // The deflate compression method + private static readonly int Z_DEFLATED = 8; + + private static readonly int STORED_BLOCK = 0; + private static readonly int STATIC_TREES = 1; + private static readonly int DYN_TREES = 2; + + // The three kinds of block type + private static readonly int Z_BINARY = 0; + private static readonly int Z_ASCII = 1; + private static readonly int Z_UNKNOWN = 2; + + private static readonly int Buf_size = 8 * 2; + + private static readonly int MIN_MATCH = 3; + private static readonly int MAX_MATCH = 258; + + private static readonly int MIN_LOOKAHEAD = (MAX_MATCH + MIN_MATCH + 1); + + private static readonly int HEAP_SIZE = (2 * InternalConstants.L_CODES + 1); + + private static readonly int END_BLOCK = 256; + + internal ZlibCodec _codec; // the zlib encoder/decoder + internal int status; // as the name implies + internal byte[] pending; // output still pending - waiting to be compressed + internal int nextPending; // index of next pending byte to output to the stream + internal int pendingCount; // number of bytes in the pending buffer + + internal sbyte data_type; // UNKNOWN, BINARY or ASCII + internal int last_flush; // value of flush param for previous deflate call + + internal int w_size; // LZ77 window size (32K by default) + internal int w_bits; // log2(w_size) (8..16) + internal int w_mask; // w_size - 1 + + //internal byte[] dictionary; + internal byte[] window; + + // Sliding window. Input bytes are read into the second half of the window, + // and move to the first half later to keep a dictionary of at least wSize + // bytes. With this organization, matches are limited to a distance of + // wSize-MAX_MATCH bytes, but this ensures that IO is always + // performed with a length multiple of the block size. + // + // To do: use the user input buffer as sliding window. + + internal int window_size; + // Actual size of window: 2*wSize, except when the user input buffer + // is directly used as sliding window. + + internal short[] prev; + // Link to older string with same hash index. To limit the size of this + // array to 64K, this link is maintained only for the last 32K strings. + // An index in this array is thus a window index modulo 32K. + + internal short[] head; // Heads of the hash chains or NIL. + + internal int ins_h; // hash index of string to be inserted + internal int hash_size; // number of elements in hash table + internal int hash_bits; // log2(hash_size) + internal int hash_mask; // hash_size-1 + + // Number of bits by which ins_h must be shifted at each input + // step. It must be such that after MIN_MATCH steps, the oldest + // byte no longer takes part in the hash key, that is: + // hash_shift * MIN_MATCH >= hash_bits + internal int hash_shift; + + // Window position at the beginning of the current output block. Gets + // negative when the window is moved backwards. + + internal int block_start; + + Config config; + internal int match_length; // length of best match + internal int prev_match; // previous match + internal int match_available; // set if previous match exists + internal int strstart; // start of string to insert into.....???? + internal int match_start; // start of matching string + internal int lookahead; // number of valid bytes ahead in window + + // Length of the best match at previous step. Matches not greater than this + // are discarded. This is used in the lazy match evaluation. + internal int prev_length; + + // Insert new strings in the hash table only if the match length is not + // greater than this length. This saves time but degrades compression. + // max_insert_length is used only for compression levels <= 3. + + internal CompressionLevel compressionLevel; // compression level (1..9) + internal CompressionStrategy compressionStrategy; // favor or force Huffman coding + + + internal short[] dyn_ltree; // literal and length tree + internal short[] dyn_dtree; // distance tree + internal short[] bl_tree; // Huffman tree for bit lengths + + internal Tree treeLiterals = new Tree(); // desc for literal tree + internal Tree treeDistances = new Tree(); // desc for distance tree + internal Tree treeBitLengths = new Tree(); // desc for bit length tree + + // number of codes at each bit length for an optimal tree + internal short[] bl_count = new short[InternalConstants.MAX_BITS + 1]; + + // heap used to build the Huffman trees + internal int[] heap = new int[2 * InternalConstants.L_CODES + 1]; + + internal int heap_len; // number of elements in the heap + internal int heap_max; // element of largest frequency + + // The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. + // The same heap array is used to build all trees. + + // Depth of each subtree used as tie breaker for trees of equal frequency + internal sbyte[] depth = new sbyte[2 * InternalConstants.L_CODES + 1]; + + internal int _lengthOffset; // index for literals or lengths + + + // Size of match buffer for literals/lengths. There are 4 reasons for + // limiting lit_bufsize to 64K: + // - frequencies can be kept in 16 bit counters + // - if compression is not successful for the first block, all input + // data is still in the window so we can still emit a stored block even + // when input comes from standard input. (This can also be done for + // all blocks if lit_bufsize is not greater than 32K.) + // - if compression is not successful for a file smaller than 64K, we can + // even emit a stored file instead of a stored block (saving 5 bytes). + // This is applicable only for zip (not gzip or zlib). + // - creating new Huffman trees less frequently may not provide fast + // adaptation to changes in the input data statistics. (Take for + // example a binary file with poorly compressible code followed by + // a highly compressible string table.) Smaller buffer sizes give + // fast adaptation but have of course the overhead of transmitting + // trees more frequently. + + internal int lit_bufsize; + + internal int last_lit; // running index in l_buf + + // Buffer for distances. To simplify the code, d_buf and l_buf have + // the same number of elements. To use different lengths, an extra flag + // array would be necessary. + + internal int _distanceOffset; // index into pending; points to distance data?? + + internal int opt_len; // bit length of current block with optimal trees + internal int static_len; // bit length of current block with static trees + internal int matches; // number of string matches in current block + internal int last_eob_len; // bit length of EOB code for last block + + // Output buffer. bits are inserted starting at the bottom (least + // significant bits). + internal short bi_buf; + + // Number of valid bits in bi_buf. All bits above the last valid bit + // are always zero. + internal int bi_valid; + + + internal DeflateManager() + { + dyn_ltree = new short[HEAP_SIZE * 2]; + dyn_dtree = new short[(2 * InternalConstants.D_CODES + 1) * 2]; // distance tree + bl_tree = new short[(2 * InternalConstants.BL_CODES + 1) * 2]; // Huffman tree for bit lengths + } + + + // lm_init + private void _InitializeLazyMatch() + { + window_size = 2 * w_size; + + // clear the hash - workitem 9063 + Array.Clear(head, 0, hash_size); + //for (int i = 0; i < hash_size; i++) head[i] = 0; + + config = Config.Lookup(compressionLevel); + SetDeflater(); + + strstart = 0; + block_start = 0; + lookahead = 0; + match_length = prev_length = MIN_MATCH - 1; + match_available = 0; + ins_h = 0; + } + + // Initialize the tree data structures for a new zlib stream. + private void _InitializeTreeData() + { + treeLiterals.dyn_tree = dyn_ltree; + treeLiterals.staticTree = StaticTree.Literals; + + treeDistances.dyn_tree = dyn_dtree; + treeDistances.staticTree = StaticTree.Distances; + + treeBitLengths.dyn_tree = bl_tree; + treeBitLengths.staticTree = StaticTree.BitLengths; + + bi_buf = 0; + bi_valid = 0; + last_eob_len = 8; // enough lookahead for inflate + + // Initialize the first block of the first file: + _InitializeBlocks(); + } + + internal void _InitializeBlocks() + { + // Initialize the trees. + for (int i = 0; i < InternalConstants.L_CODES; i++) + dyn_ltree[i * 2] = 0; + for (int i = 0; i < InternalConstants.D_CODES; i++) + dyn_dtree[i * 2] = 0; + for (int i = 0; i < InternalConstants.BL_CODES; i++) + bl_tree[i * 2] = 0; + + dyn_ltree[END_BLOCK * 2] = 1; + opt_len = static_len = 0; + last_lit = matches = 0; + } + + // Restore the heap property by moving down the tree starting at node k, + // exchanging a node with the smallest of its two sons if necessary, stopping + // when the heap property is re-established (each father smaller than its + // two sons). + internal void pqdownheap(short[] tree, int k) + { + int v = heap[k]; + int j = k << 1; // left son of k + while (j <= heap_len) + { + // Set j to the smallest of the two sons: + if (j < heap_len && _IsSmaller(tree, heap[j + 1], heap[j], depth)) + { + j++; + } + // Exit if v is smaller than both sons + if (_IsSmaller(tree, v, heap[j], depth)) + break; + + // Exchange v with the smallest son + heap[k] = heap[j]; k = j; + // And continue down the tree, setting j to the left son of k + j <<= 1; + } + heap[k] = v; + } + + internal static bool _IsSmaller(short[] tree, int n, int m, sbyte[] depth) + { + short tn2 = tree[n * 2]; + short tm2 = tree[m * 2]; + return (tn2 < tm2 || (tn2 == tm2 && depth[n] <= depth[m])); + } + + + // Scan a literal or distance tree to determine the frequencies of the codes + // in the bit length tree. + internal void scan_tree(short[] tree, int max_code) + { + int n; // iterates over all tree elements + int prevlen = -1; // last emitted length + int curlen; // length of current code + int nextlen = (int)tree[0 * 2 + 1]; // length of next code + int count = 0; // repeat count of the current code + int max_count = 7; // max repeat count + int min_count = 4; // min repeat count + + if (nextlen == 0) + { + max_count = 138; min_count = 3; + } + tree[(max_code + 1) * 2 + 1] = (short)0x7fff; // guard //?? + + for (n = 0; n <= max_code; n++) + { + curlen = nextlen; nextlen = (int)tree[(n + 1) * 2 + 1]; + if (++count < max_count && curlen == nextlen) + { + continue; + } + else if (count < min_count) + { + bl_tree[curlen * 2] = (short)(bl_tree[curlen * 2] + count); + } + else if (curlen != 0) + { + if (curlen != prevlen) + bl_tree[curlen * 2]++; + bl_tree[InternalConstants.REP_3_6 * 2]++; + } + else if (count <= 10) + { + bl_tree[InternalConstants.REPZ_3_10 * 2]++; + } + else + { + bl_tree[InternalConstants.REPZ_11_138 * 2]++; + } + count = 0; prevlen = curlen; + if (nextlen == 0) + { + max_count = 138; min_count = 3; + } + else if (curlen == nextlen) + { + max_count = 6; min_count = 3; + } + else + { + max_count = 7; min_count = 4; + } + } + } + + // Construct the Huffman tree for the bit lengths and return the index in + // bl_order of the last bit length code to send. + internal int build_bl_tree() + { + int max_blindex; // index of last bit length code of non zero freq + + // Determine the bit length frequencies for literal and distance trees + scan_tree(dyn_ltree, treeLiterals.max_code); + scan_tree(dyn_dtree, treeDistances.max_code); + + // Build the bit length tree: + treeBitLengths.build_tree(this); + // opt_len now includes the length of the tree representations, except + // the lengths of the bit lengths codes and the 5+5+4 bits for the counts. + + // Determine the number of bit length codes to send. The pkzip format + // requires that at least 4 bit length codes be sent. (appnote.txt says + // 3 but the actual value used is 4.) + for (max_blindex = InternalConstants.BL_CODES - 1; max_blindex >= 3; max_blindex--) + { + if (bl_tree[Tree.bl_order[max_blindex] * 2 + 1] != 0) + break; + } + // Update opt_len to include the bit length tree and counts + opt_len += 3 * (max_blindex + 1) + 5 + 5 + 4; + + return max_blindex; + } + + + // Send the header for a block using dynamic Huffman trees: the counts, the + // lengths of the bit length codes, the literal tree and the distance tree. + // IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. + internal void send_all_trees(int lcodes, int dcodes, int blcodes) + { + int rank; // index in bl_order + + send_bits(lcodes - 257, 5); // not +255 as stated in appnote.txt + send_bits(dcodes - 1, 5); + send_bits(blcodes - 4, 4); // not -3 as stated in appnote.txt + for (rank = 0; rank < blcodes; rank++) + { + send_bits(bl_tree[Tree.bl_order[rank] * 2 + 1], 3); + } + send_tree(dyn_ltree, lcodes - 1); // literal tree + send_tree(dyn_dtree, dcodes - 1); // distance tree + } + + // Send a literal or distance tree in compressed form, using the codes in + // bl_tree. + internal void send_tree(short[] tree, int max_code) + { + int n; // iterates over all tree elements + int prevlen = -1; // last emitted length + int curlen; // length of current code + int nextlen = tree[0 * 2 + 1]; // length of next code + int count = 0; // repeat count of the current code + int max_count = 7; // max repeat count + int min_count = 4; // min repeat count + + if (nextlen == 0) + { + max_count = 138; min_count = 3; + } + + for (n = 0; n <= max_code; n++) + { + curlen = nextlen; nextlen = tree[(n + 1) * 2 + 1]; + if (++count < max_count && curlen == nextlen) + { + continue; + } + else if (count < min_count) + { + do + { + send_code(curlen, bl_tree); + } + while (--count != 0); + } + else if (curlen != 0) + { + if (curlen != prevlen) + { + send_code(curlen, bl_tree); count--; + } + send_code(InternalConstants.REP_3_6, bl_tree); + send_bits(count - 3, 2); + } + else if (count <= 10) + { + send_code(InternalConstants.REPZ_3_10, bl_tree); + send_bits(count - 3, 3); + } + else + { + send_code(InternalConstants.REPZ_11_138, bl_tree); + send_bits(count - 11, 7); + } + count = 0; prevlen = curlen; + if (nextlen == 0) + { + max_count = 138; min_count = 3; + } + else if (curlen == nextlen) + { + max_count = 6; min_count = 3; + } + else + { + max_count = 7; min_count = 4; + } + } + } + + // Output a block of bytes on the stream. + // IN assertion: there is enough room in pending_buf. + private void put_bytes(byte[] p, int start, int len) + { + Array.Copy(p, start, pending, pendingCount, len); + pendingCount += len; + } + +#if NOTNEEDED + private void put_byte(byte c) + { + pending[pendingCount++] = c; + } + internal void put_short(int b) + { + unchecked + { + pending[pendingCount++] = (byte)b; + pending[pendingCount++] = (byte)(b >> 8); + } + } + internal void putShortMSB(int b) + { + unchecked + { + pending[pendingCount++] = (byte)(b >> 8); + pending[pendingCount++] = (byte)b; + } + } +#endif + + internal void send_code(int c, short[] tree) + { + int c2 = c * 2; + send_bits((tree[c2] & 0xffff), (tree[c2 + 1] & 0xffff)); + } + + internal void send_bits(int value, int length) + { + int len = length; + unchecked + { + if (bi_valid > (int)Buf_size - len) + { + //int val = value; + // bi_buf |= (val << bi_valid); + + bi_buf |= (short)((value << bi_valid) & 0xffff); + //put_short(bi_buf); + pending[pendingCount++] = (byte)bi_buf; + pending[pendingCount++] = (byte)(bi_buf >> 8); + + + bi_buf = (short)((uint)value >> (Buf_size - bi_valid)); + bi_valid += len - Buf_size; + } + else + { + // bi_buf |= (value) << bi_valid; + bi_buf |= (short)((value << bi_valid) & 0xffff); + bi_valid += len; + } + } + } + + // Send one empty static block to give enough lookahead for inflate. + // This takes 10 bits, of which 7 may remain in the bit buffer. + // The current inflate code requires 9 bits of lookahead. If the + // last two codes for the previous block (real code plus EOB) were coded + // on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode + // the last real code. In this case we send two empty static blocks instead + // of one. (There are no problems if the previous block is stored or fixed.) + // To simplify the code, we assume the worst case of last real code encoded + // on one bit only. + internal void _tr_align() + { + send_bits(STATIC_TREES << 1, 3); + send_code(END_BLOCK, StaticTree.lengthAndLiteralsTreeCodes); + + bi_flush(); + + // Of the 10 bits for the empty block, we have already sent + // (10 - bi_valid) bits. The lookahead for the last real code (before + // the EOB of the previous block) was thus at least one plus the length + // of the EOB plus what we have just sent of the empty static block. + if (1 + last_eob_len + 10 - bi_valid < 9) + { + send_bits(STATIC_TREES << 1, 3); + send_code(END_BLOCK, StaticTree.lengthAndLiteralsTreeCodes); + bi_flush(); + } + last_eob_len = 7; + } + + + // Save the match info and tally the frequency counts. Return true if + // the current block must be flushed. + internal bool _tr_tally(int dist, int lc) + { + pending[_distanceOffset + last_lit * 2] = unchecked((byte)((uint)dist >> 8)); + pending[_distanceOffset + last_lit * 2 + 1] = unchecked((byte)dist); + pending[_lengthOffset + last_lit] = unchecked((byte)lc); + last_lit++; + + if (dist == 0) + { + // lc is the unmatched char + dyn_ltree[lc * 2]++; + } + else + { + matches++; + // Here, lc is the match length - MIN_MATCH + dist--; // dist = match distance - 1 + dyn_ltree[(Tree.LengthCode[lc] + InternalConstants.LITERALS + 1) * 2]++; + dyn_dtree[Tree.DistanceCode(dist) * 2]++; + } + + /* ************************************************************ + * * + * this code is not turned on by default in ZLIB Trrntzip code * + * * + * ************************************************************* + */ + /* + if (false) //CompSettings + { + if ((last_lit & 0x1fff) == 0 && (int)compressionLevel > 2) + { + // Compute an upper bound for the compressed length + int out_length = last_lit << 3; + int in_length = strstart - block_start; + int dcode; + for (dcode = 0; dcode < InternalConstants.D_CODES; dcode++) + { + out_length = (int)(out_length + (int)dyn_dtree[dcode * 2] * (5L + Tree.ExtraDistanceBits[dcode])); + } + out_length >>= 3; + if ((matches < (last_lit / 2)) && out_length < in_length / 2) + return true; + } + } + */ + + return (last_lit == lit_bufsize - 1) || (last_lit == lit_bufsize); + // dinoch - wraparound? + // We avoid equality with lit_bufsize because of wraparound at 64K + // on 16 bit machines and because stored blocks are restricted to + // 64K-1 bytes. + } + + + + // Send the block data compressed using the given Huffman trees + internal void send_compressed_block(short[] ltree, short[] dtree) + { + int distance; // distance of matched string + int lc; // match length or unmatched char (if dist == 0) + int lx = 0; // running index in l_buf + int code; // the code to send + int extra; // number of extra bits to send + + if (last_lit != 0) + { + do + { + int ix = _distanceOffset + lx * 2; + distance = ((pending[ix] << 8) & 0xff00) | + (pending[ix + 1] & 0xff); + lc = (pending[_lengthOffset + lx]) & 0xff; + lx++; + + if (distance == 0) + { + send_code(lc, ltree); // send a literal byte + } + else + { + // literal or match pair + // Here, lc is the match length - MIN_MATCH + code = Tree.LengthCode[lc]; + + // send the length code + send_code(code + InternalConstants.LITERALS + 1, ltree); + extra = Tree.ExtraLengthBits[code]; + if (extra != 0) + { + // send the extra length bits + lc -= Tree.LengthBase[code]; + send_bits(lc, extra); + } + distance--; // dist is now the match distance - 1 + code = Tree.DistanceCode(distance); + + // send the distance code + send_code(code, dtree); + + extra = Tree.ExtraDistanceBits[code]; + if (extra != 0) + { + // send the extra distance bits + distance -= Tree.DistanceBase[code]; + send_bits(distance, extra); + } + } + + // Check that the overlay between pending and d_buf+l_buf is ok: + } + while (lx < last_lit); + } + + send_code(END_BLOCK, ltree); + last_eob_len = ltree[END_BLOCK * 2 + 1]; + } + + + + // Set the data type to ASCII or BINARY, using a crude approximation: + // binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise. + // IN assertion: the fields freq of dyn_ltree are set and the total of all + // frequencies does not exceed 64K (to fit in an int on 16 bit machines). + internal void set_data_type() + { + int n = 0; + int ascii_freq = 0; + int bin_freq = 0; + while (n < 7) + { + bin_freq += dyn_ltree[n * 2]; n++; + } + while (n < 128) + { + ascii_freq += dyn_ltree[n * 2]; n++; + } + while (n < InternalConstants.LITERALS) + { + bin_freq += dyn_ltree[n * 2]; n++; + } + data_type = (sbyte)(bin_freq > (ascii_freq >> 2) ? Z_BINARY : Z_ASCII); + } + + + + // Flush the bit buffer, keeping at most 7 bits in it. + internal void bi_flush() + { + if (bi_valid == 16) + { + pending[pendingCount++] = (byte)bi_buf; + pending[pendingCount++] = (byte)(bi_buf >> 8); + bi_buf = 0; + bi_valid = 0; + } + else if (bi_valid >= 8) + { + //put_byte((byte)bi_buf); + pending[pendingCount++] = (byte)bi_buf; + bi_buf >>= 8; + bi_valid -= 8; + } + } + + // Flush the bit buffer and align the output on a byte boundary + internal void bi_windup() + { + if (bi_valid > 8) + { + pending[pendingCount++] = (byte)bi_buf; + pending[pendingCount++] = (byte)(bi_buf >> 8); + } + else if (bi_valid > 0) + { + //put_byte((byte)bi_buf); + pending[pendingCount++] = (byte)bi_buf; + } + bi_buf = 0; + bi_valid = 0; + } + + // Copy a stored block, storing first the length and its + // one's complement if requested. + internal void copy_block(int buf, int len, bool header) + { + bi_windup(); // align on byte boundary + last_eob_len = 8; // enough lookahead for inflate + + if (header) + unchecked + { + //put_short((short)len); + pending[pendingCount++] = (byte)len; + pending[pendingCount++] = (byte)(len >> 8); + //put_short((short)~len); + pending[pendingCount++] = (byte)~len; + pending[pendingCount++] = (byte)(~len >> 8); + } + + put_bytes(window, buf, len); + } + + internal void flush_block_only(bool eof) + { + _tr_flush_block(block_start >= 0 ? block_start : -1, strstart - block_start, eof); + block_start = strstart; + _codec.flush_pending(); + } + + // Copy without compression as much as possible from the input stream, return + // the current block state. + // This function does not insert new strings in the dictionary since + // uncompressible data is probably not useful. This function is used + // only for the level=0 compression option. + // NOTE: this function should be optimized to avoid extra copying from + // window to pending_buf. + internal BlockState DeflateNone(FlushType flush) + { + // Stored blocks are limited to 0xffff bytes, pending is limited + // to pending_buf_size, and each stored block has a 5 byte header: + + int max_block_size = 0xffff; + int max_start; + + if (max_block_size > pending.Length - 5) + { + max_block_size = pending.Length - 5; + } + + // Copy as much as possible from input to output: + while (true) + { + // Fill the window as much as possible: + if (lookahead <= 1) + { + _fillWindow(); + if (lookahead == 0 && flush == FlushType.None) + return BlockState.NeedMore; + if (lookahead == 0) + break; // flush the current block + } + + strstart += lookahead; + lookahead = 0; + + // Emit a stored block if pending will be full: + max_start = block_start + max_block_size; + if (strstart == 0 || strstart >= max_start) + { + // strstart == 0 is possible when wraparound on 16-bit machine + lookahead = (int)(strstart - max_start); + strstart = (int)max_start; + + flush_block_only(false); + if (_codec.AvailableBytesOut == 0) + return BlockState.NeedMore; + } + + // Flush if we may have to slide, otherwise block_start may become + // negative and the data will be gone: + if (strstart - block_start >= w_size - MIN_LOOKAHEAD) + { + flush_block_only(false); + if (_codec.AvailableBytesOut == 0) + return BlockState.NeedMore; + } + } + + flush_block_only(flush == FlushType.Finish); + if (_codec.AvailableBytesOut == 0) + return (flush == FlushType.Finish) ? BlockState.FinishStarted : BlockState.NeedMore; + + return flush == FlushType.Finish ? BlockState.FinishDone : BlockState.BlockDone; + } + + + // Send a stored block + internal void _tr_stored_block(int buf, int stored_len, bool eof) + { + send_bits((STORED_BLOCK << 1) + (eof ? 1 : 0), 3); // send block type + copy_block(buf, stored_len, true); // with header + } + + // Determine the best encoding for the current block: dynamic trees, static + // trees or store, and output the encoded block to the zip file. + internal void _tr_flush_block(int buf, int stored_len, bool eof) + { + int opt_lenb, static_lenb; // opt_len and static_len in bytes + int max_blindex = 0; // index of last bit length code of non zero freq + + // Build the Huffman trees unless a stored block is forced + if (compressionLevel > 0) + { + // Check if the file is ascii or binary + if (data_type == Z_UNKNOWN) + set_data_type(); + + // Construct the literal and distance trees + treeLiterals.build_tree(this); + + treeDistances.build_tree(this); + + // At this point, opt_len and static_len are the total bit lengths of + // the compressed block data, excluding the tree representations. + + // Build the bit length tree for the above two trees, and get the index + // in bl_order of the last bit length code to send. + max_blindex = build_bl_tree(); + + // Determine the best encoding. Compute first the block length in bytes + opt_lenb = (opt_len + 3 + 7) >> 3; + static_lenb = (static_len + 3 + 7) >> 3; + + if (static_lenb <= opt_lenb) + opt_lenb = static_lenb; + } + else + { + opt_lenb = static_lenb = stored_len + 5; // force a stored block + } + + if (stored_len + 4 <= opt_lenb && buf != -1) + { + // 4: two words for the lengths + // The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. + // Otherwise we can't have processed more than WSIZE input bytes since + // the last block flush, because compression would have been + // successful. If LIT_BUFSIZE <= WSIZE, it is never too late to + // transform a block into a stored block. + _tr_stored_block(buf, stored_len, eof); + } + else if (static_lenb == opt_lenb) + { + send_bits((STATIC_TREES << 1) + (eof ? 1 : 0), 3); + send_compressed_block(StaticTree.lengthAndLiteralsTreeCodes, StaticTree.distTreeCodes); + } + else + { + send_bits((DYN_TREES << 1) + (eof ? 1 : 0), 3); + send_all_trees(treeLiterals.max_code + 1, treeDistances.max_code + 1, max_blindex + 1); + send_compressed_block(dyn_ltree, dyn_dtree); + } + + // The above check is made mod 2^32, for files larger than 512 MB + // and uLong implemented on 32 bits. + + _InitializeBlocks(); + + if (eof) + { + bi_windup(); + } + } + + // Fill the window when the lookahead becomes insufficient. + // Updates strstart and lookahead. + // + // IN assertion: lookahead < MIN_LOOKAHEAD + // OUT assertions: strstart <= window_size-MIN_LOOKAHEAD + // At least one byte has been read, or avail_in == 0; reads are + // performed for at least two bytes (required for the zip translate_eol + // option -- not supported here). + private void _fillWindow() + { + int n, m; + int p; + int more; // Amount of free space at the end of the window. + + do + { + more = (window_size - lookahead - strstart); + + // Deal with !@#$% 64K limit: + if (more == 0 && strstart == 0 && lookahead == 0) + { + more = w_size; + } + else if (more == -1) + { + // Very unlikely, but possible on 16 bit machine if strstart == 0 + // and lookahead == 1 (input done one byte at time) + more--; + + // If the window is almost full and there is insufficient lookahead, + // move the upper half to the lower one to make room in the upper half. + } + else if (strstart >= w_size + w_size - MIN_LOOKAHEAD) + { + Array.Copy(window, w_size, window, 0, w_size); + match_start -= w_size; + strstart -= w_size; // we now have strstart >= MAX_DIST + block_start -= w_size; + + // Slide the hash table (could be avoided with 32 bit values + // at the expense of memory usage). We slide even when level == 0 + // to keep the hash table consistent if we switch back to level > 0 + // later. (Using level 0 permanently is not an optimal usage of + // zlib, so we don't care about this pathological case.) + + n = hash_size; + p = n; + do + { + m = (head[--p] & 0xffff); + head[p] = (short)((m >= w_size) ? (m - w_size) : 0); + } + while (--n != 0); + + n = w_size; + p = n; + do + { + m = (prev[--p] & 0xffff); + prev[p] = (short)((m >= w_size) ? (m - w_size) : 0); + // If n is not on any hash chain, prev[n] is garbage but + // its value will never be used. + } + while (--n != 0); + more += w_size; + } + + if (_codec.AvailableBytesIn == 0) + return; + + // If there was no sliding: + // strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && + // more == window_size - lookahead - strstart + // => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) + // => more >= window_size - 2*WSIZE + 2 + // In the BIG_MEM or MMAP case (not yet supported), + // window_size == input_size + MIN_LOOKAHEAD && + // strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. + // Otherwise, window_size == 2*WSIZE so more >= 2. + // If there was sliding, more >= WSIZE. So in all cases, more >= 2. + + n = _codec.read_buf(window, strstart + lookahead, more); + lookahead += n; + + // Initialize the hash value now that we have some input: + if (lookahead >= MIN_MATCH) + { + ins_h = window[strstart] & 0xff; + ins_h = (((ins_h) << hash_shift) ^ (window[strstart + 1] & 0xff)) & hash_mask; + } + // If the whole input has less than MIN_MATCH bytes, ins_h is garbage, + // but this is not important since only literal bytes will be emitted. + } + while (lookahead < MIN_LOOKAHEAD && _codec.AvailableBytesIn != 0); + } + + // Compress as much as possible from the input stream, return the current + // block state. + // This function does not perform lazy evaluation of matches and inserts + // new strings in the dictionary only for unmatched strings or for short + // matches. It is used only for the fast compression options. + internal BlockState DeflateFast(FlushType flush) + { + // short hash_head = 0; // head of the hash chain + int hash_head = 0; // head of the hash chain + bool bflush; // set if current block must be flushed + + while (true) + { + // Make sure that we always have enough lookahead, except + // at the end of the input file. We need MAX_MATCH bytes + // for the next match, plus MIN_MATCH bytes to insert the + // string following the next match. + if (lookahead < MIN_LOOKAHEAD) + { + _fillWindow(); + if (lookahead < MIN_LOOKAHEAD && flush == FlushType.None) + { + return BlockState.NeedMore; + } + if (lookahead == 0) + break; // flush the current block + } + + // Insert the string window[strstart .. strstart+2] in the + // dictionary, and set hash_head to the head of the hash chain: + if (lookahead >= MIN_MATCH) + { + ins_h = (((ins_h) << hash_shift) ^ (window[(strstart) + (MIN_MATCH - 1)] & 0xff)) & hash_mask; + + // prev[strstart&w_mask]=hash_head=head[ins_h]; + hash_head = (head[ins_h] & 0xffff); + prev[strstart & w_mask] = head[ins_h]; + head[ins_h] = unchecked((short)strstart); + } + + // Find the longest match, discarding those <= prev_length. + // At this point we have always match_length < MIN_MATCH + + if (hash_head != 0L && ((strstart - hash_head) & 0xffff) <= w_size - MIN_LOOKAHEAD) + { + // To simplify the code, we prevent matches with the string + // of window index 0 (in particular we have to avoid a match + // of the string with itself at the start of the input file). + if (compressionStrategy != CompressionStrategy.HuffmanOnly) + { + match_length = longest_match(hash_head); + } + // longest_match() sets match_start + } + if (match_length >= MIN_MATCH) + { + // check_match(strstart, match_start, match_length); + + bflush = _tr_tally(strstart - match_start, match_length - MIN_MATCH); + + lookahead -= match_length; + + // Insert new strings in the hash table only if the match length + // is not too large. This saves time but degrades compression. + if (match_length <= config.MaxLazy && lookahead >= MIN_MATCH) + { + match_length--; // string at strstart already in hash table + do + { + strstart++; + + ins_h = ((ins_h << hash_shift) ^ (window[(strstart) + (MIN_MATCH - 1)] & 0xff)) & hash_mask; + // prev[strstart&w_mask]=hash_head=head[ins_h]; + hash_head = (head[ins_h] & 0xffff); + prev[strstart & w_mask] = head[ins_h]; + head[ins_h] = unchecked((short)strstart); + + // strstart never exceeds WSIZE-MAX_MATCH, so there are + // always MIN_MATCH bytes ahead. + } + while (--match_length != 0); + strstart++; + } + else + { + strstart += match_length; + match_length = 0; + ins_h = window[strstart] & 0xff; + + ins_h = (((ins_h) << hash_shift) ^ (window[strstart + 1] & 0xff)) & hash_mask; + // If lookahead < MIN_MATCH, ins_h is garbage, but it does not + // matter since it will be recomputed at next deflate call. + } + } + else + { + // No match, output a literal byte + + bflush = _tr_tally(0, window[strstart] & 0xff); + lookahead--; + strstart++; + } + if (bflush) + { + flush_block_only(false); + if (_codec.AvailableBytesOut == 0) + return BlockState.NeedMore; + } + } + + flush_block_only(flush == FlushType.Finish); + if (_codec.AvailableBytesOut == 0) + { + if (flush == FlushType.Finish) + return BlockState.FinishStarted; + else + return BlockState.NeedMore; + } + return flush == FlushType.Finish ? BlockState.FinishDone : BlockState.BlockDone; + } + + // Same as above, but achieves better compression. We use a lazy + // evaluation for matches: a match is finally adopted only if there is + // no better match at the next window position. + internal BlockState DeflateSlow(FlushType flush) + { + // short hash_head = 0; // head of hash chain + int hash_head = 0; // head of hash chain + bool bflush; // set if current block must be flushed + + // Process the input block. + while (true) + { + // Make sure that we always have enough lookahead, except + // at the end of the input file. We need MAX_MATCH bytes + // for the next match, plus MIN_MATCH bytes to insert the + // string following the next match. + + if (lookahead < MIN_LOOKAHEAD) + { + _fillWindow(); + if (lookahead < MIN_LOOKAHEAD && flush == FlushType.None) + return BlockState.NeedMore; + + if (lookahead == 0) + break; // flush the current block + } + + // Insert the string window[strstart .. strstart+2] in the + // dictionary, and set hash_head to the head of the hash chain: + + if (lookahead >= MIN_MATCH) + { + ins_h = (((ins_h) << hash_shift) ^ (window[(strstart) + (MIN_MATCH - 1)] & 0xff)) & hash_mask; + // prev[strstart&w_mask]=hash_head=head[ins_h]; + hash_head = (head[ins_h] & 0xffff); + prev[strstart & w_mask] = head[ins_h]; + head[ins_h] = unchecked((short)strstart); + } + + // Find the longest match, discarding those <= prev_length. + prev_length = match_length; + prev_match = match_start; + match_length = MIN_MATCH - 1; + + if (hash_head != 0 && prev_length < config.MaxLazy && + ((strstart - hash_head) & 0xffff) <= w_size - MIN_LOOKAHEAD) + { + // To simplify the code, we prevent matches with the string + // of window index 0 (in particular we have to avoid a match + // of the string with itself at the start of the input file). + + if (compressionStrategy != CompressionStrategy.HuffmanOnly) + { + match_length = longest_match(hash_head); + } + // longest_match() sets match_start + + if (match_length <= 5 && (compressionStrategy == CompressionStrategy.Filtered || + (match_length == MIN_MATCH && strstart - match_start > 4096))) + { + + // If prev_match is also MIN_MATCH, match_start is garbage + // but we will ignore the current match anyway. + match_length = MIN_MATCH - 1; + } + } + + // If there was a match at the previous step and the current + // match is not better, output the previous match: + if (prev_length >= MIN_MATCH && match_length <= prev_length) + { + int max_insert = strstart + lookahead - MIN_MATCH; + // Do not insert strings in hash table beyond this. + + // check_match(strstart-1, prev_match, prev_length); + + bflush = _tr_tally(strstart - 1 - prev_match, prev_length - MIN_MATCH); + + // Insert in hash table all strings up to the end of the match. + // strstart-1 and strstart are already inserted. If there is not + // enough lookahead, the last two strings are not inserted in + // the hash table. + lookahead -= (prev_length - 1); + prev_length -= 2; + do + { + if (++strstart <= max_insert) + { + ins_h = (((ins_h) << hash_shift) ^ (window[(strstart) + (MIN_MATCH - 1)] & 0xff)) & hash_mask; + //prev[strstart&w_mask]=hash_head=head[ins_h]; + hash_head = (head[ins_h] & 0xffff); + prev[strstart & w_mask] = head[ins_h]; + head[ins_h] = unchecked((short)strstart); + } + } + while (--prev_length != 0); + match_available = 0; + match_length = MIN_MATCH - 1; + strstart++; + + if (bflush) + { + flush_block_only(false); + if (_codec.AvailableBytesOut == 0) + return BlockState.NeedMore; + } + } + else if (match_available != 0) + { + + // If there was no match at the previous position, output a + // single literal. If there was a match but the current match + // is longer, truncate the previous match to a single literal. + + bflush = _tr_tally(0, window[strstart - 1] & 0xff); + + if (bflush) + { + flush_block_only(false); + } + strstart++; + lookahead--; + if (_codec.AvailableBytesOut == 0) + return BlockState.NeedMore; + } + else + { + // There is no previous match to compare with, wait for + // the next step to decide. + + match_available = 1; + strstart++; + lookahead--; + } + } + + if (match_available != 0) + { + bflush = _tr_tally(0, window[strstart - 1] & 0xff); + match_available = 0; + } + flush_block_only(flush == FlushType.Finish); + + if (_codec.AvailableBytesOut == 0) + { + if (flush == FlushType.Finish) + return BlockState.FinishStarted; + else + return BlockState.NeedMore; + } + + return flush == FlushType.Finish ? BlockState.FinishDone : BlockState.BlockDone; + } + + + internal int longest_match(int cur_match) + { + int chain_length = config.MaxChainLength; // max hash chain length + int scan = strstart; // current string + int match; // matched string + int len; // length of current match + int best_len = prev_length; // best match length so far + int limit = strstart > (w_size - MIN_LOOKAHEAD) ? strstart - (w_size - MIN_LOOKAHEAD) : 0; + + int niceLength = config.NiceLength; + + // Stop when cur_match becomes <= limit. To simplify the code, + // we prevent matches with the string of window index 0. + + int wmask = w_mask; + + int strend = strstart + MAX_MATCH; + byte scan_end1 = window[scan + best_len - 1]; + byte scan_end = window[scan + best_len]; + + // The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + // It is easy to get rid of this optimization if necessary. + + // Do not waste too much time if we already have a good match: + if (prev_length >= config.GoodLength) + { + chain_length >>= 2; + } + + // Do not look for matches beyond the end of the input. This is necessary + // to make deflate deterministic. + if (niceLength > lookahead) + niceLength = lookahead; + + do + { + match = cur_match; + + // Skip to next match if the match length cannot increase + // or if the match length is less than 2: + if (window[match + best_len] != scan_end || + window[match + best_len - 1] != scan_end1 || + window[match] != window[scan] || + window[++match] != window[scan + 1]) + continue; + + // The check at best_len-1 can be removed because it will be made + // again later. (This heuristic is not always a win.) + // It is not necessary to compare scan[2] and match[2] since they + // are always equal when the other bytes match, given that + // the hash keys are equal and that HASH_BITS >= 8. + scan += 2; match++; + + // We check for insufficient lookahead only every 8th comparison; + // the 256th check will be made at strstart+258. + do + { + } + while (window[++scan] == window[++match] && + window[++scan] == window[++match] && + window[++scan] == window[++match] && + window[++scan] == window[++match] && + window[++scan] == window[++match] && + window[++scan] == window[++match] && + window[++scan] == window[++match] && + window[++scan] == window[++match] && scan < strend); + + len = MAX_MATCH - (int)(strend - scan); + scan = strend - MAX_MATCH; + + if (len > best_len) + { + match_start = cur_match; + best_len = len; + if (len >= niceLength) + break; + scan_end1 = window[scan + best_len - 1]; + scan_end = window[scan + best_len]; + } + } + while ((cur_match = (prev[cur_match & wmask] & 0xffff)) > limit && --chain_length != 0); + + if (best_len <= lookahead) + return best_len; + return lookahead; + } + + + private bool Rfc1950BytesEmitted = false; + private bool _WantRfc1950HeaderBytes = true; + internal bool WantRfc1950HeaderBytes + { + get { return _WantRfc1950HeaderBytes; } + set { _WantRfc1950HeaderBytes = value; } + } + + + internal int Initialize(ZlibCodec codec, CompressionLevel level) + { + return Initialize(codec, level, ZlibConstants.WindowBitsMax); + } + + internal int Initialize(ZlibCodec codec, CompressionLevel level, int bits) + { + return Initialize(codec, level, bits, MEM_LEVEL_DEFAULT, CompressionStrategy.Default); + } + + internal int Initialize(ZlibCodec codec, CompressionLevel level, int bits, CompressionStrategy compressionStrategy) + { + return Initialize(codec, level, bits, MEM_LEVEL_DEFAULT, compressionStrategy); + } + + internal int Initialize(ZlibCodec codec, CompressionLevel level, int windowBits, int memLevel, CompressionStrategy strategy) + { + _codec = codec; + _codec.Message = null; + + // validation + if (windowBits < 9 || windowBits > 15) + throw new ZlibException("windowBits must be in the range 9..15."); + + if (memLevel < 1 || memLevel > MEM_LEVEL_MAX) + throw new ZlibException(String.Format("memLevel must be in the range 1.. {0}", MEM_LEVEL_MAX)); + + _codec.dstate = this; + + w_bits = windowBits; + w_size = 1 << w_bits; + w_mask = w_size - 1; + + hash_bits = memLevel + 7; + hash_size = 1 << hash_bits; + hash_mask = hash_size - 1; + hash_shift = ((hash_bits + MIN_MATCH - 1) / MIN_MATCH); + + window = new byte[w_size * 2]; + prev = new short[w_size]; + head = new short[hash_size]; + + // for memLevel==8, this will be 16384, 16k + lit_bufsize = 1 << (memLevel + 6); + + // Use a single array as the buffer for data pending compression, + // the output distance codes, and the output length codes (aka tree). + // orig comment: This works just fine since the average + // output size for (length,distance) codes is <= 24 bits. + pending = new byte[lit_bufsize * 4]; + _distanceOffset = lit_bufsize; + _lengthOffset = (1 + 2) * lit_bufsize; + + // So, for memLevel 8, the length of the pending buffer is 65536. 64k. + // The first 16k are pending bytes. + // The middle slice, of 32k, is used for distance codes. + // The final 16k are length codes. + + this.compressionLevel = level; + this.compressionStrategy = strategy; + + Reset(); + return ZlibConstants.Z_OK; + } + + + internal void Reset() + { + _codec.TotalBytesIn = _codec.TotalBytesOut = 0; + _codec.Message = null; + //strm.data_type = Z_UNKNOWN; + + pendingCount = 0; + nextPending = 0; + + Rfc1950BytesEmitted = false; + + status = (WantRfc1950HeaderBytes) ? INIT_STATE : BUSY_STATE; + _codec._Adler32 = Adler.Adler32(0, null, 0, 0); + + last_flush = (int)FlushType.None; + + _InitializeTreeData(); + _InitializeLazyMatch(); + } + + + internal int End() + { + if (status != INIT_STATE && status != BUSY_STATE && status != FINISH_STATE) + { + return ZlibConstants.Z_STREAM_ERROR; + } + // Deallocate in reverse order of allocations: + pending = null; + head = null; + prev = null; + window = null; + // free + // dstate=null; + return status == BUSY_STATE ? ZlibConstants.Z_DATA_ERROR : ZlibConstants.Z_OK; + } + + + private void SetDeflater() + { + switch (config.Flavor) + { + case DeflateFlavor.Store: + DeflateFunction = DeflateNone; + break; + case DeflateFlavor.Fast: + DeflateFunction = DeflateFast; + break; + case DeflateFlavor.Slow: + DeflateFunction = DeflateSlow; + break; + } + } + + + internal int SetParams(CompressionLevel level, CompressionStrategy strategy) + { + int result = ZlibConstants.Z_OK; + + if (compressionLevel != level) + { + Config newConfig = Config.Lookup(level); + + // change in the deflate flavor (Fast vs slow vs none)? + if (newConfig.Flavor != config.Flavor && _codec.TotalBytesIn != 0) + { + // Flush the last buffer: + result = _codec.Deflate(FlushType.Partial); + } + + compressionLevel = level; + config = newConfig; + SetDeflater(); + } + + // no need to flush with change in strategy? Really? + compressionStrategy = strategy; + + return result; + } + + + internal int SetDictionary(byte[] dictionary) + { + int length = dictionary.Length; + int index = 0; + + if (dictionary == null || status != INIT_STATE) + throw new ZlibException("Stream error."); + + _codec._Adler32 = Adler.Adler32(_codec._Adler32, dictionary, 0, dictionary.Length); + + if (length < MIN_MATCH) + return ZlibConstants.Z_OK; + if (length > w_size - MIN_LOOKAHEAD) + { + length = w_size - MIN_LOOKAHEAD; + index = dictionary.Length - length; // use the tail of the dictionary + } + Array.Copy(dictionary, index, window, 0, length); + strstart = length; + block_start = length; + + // Insert all strings in the hash table (except for the last two bytes). + // s->lookahead stays null, so s->ins_h will be recomputed at the next + // call of fill_window. + + ins_h = window[0] & 0xff; + ins_h = (((ins_h) << hash_shift) ^ (window[1] & 0xff)) & hash_mask; + + for (int n = 0; n <= length - MIN_MATCH; n++) + { + ins_h = (((ins_h) << hash_shift) ^ (window[(n) + (MIN_MATCH - 1)] & 0xff)) & hash_mask; + prev[n & w_mask] = head[ins_h]; + head[ins_h] = (short)n; + } + return ZlibConstants.Z_OK; + } + + + + internal int Deflate(FlushType flush) + { + int old_flush; + + if (_codec.OutputBuffer == null || + (_codec.InputBuffer == null && _codec.AvailableBytesIn != 0) || + (status == FINISH_STATE && flush != FlushType.Finish)) + { + _codec.Message = _ErrorMessage[ZlibConstants.Z_NEED_DICT - (ZlibConstants.Z_STREAM_ERROR)]; + throw new ZlibException(String.Format("Something is fishy. [{0}]", _codec.Message)); + } + if (_codec.AvailableBytesOut == 0) + { + _codec.Message = _ErrorMessage[ZlibConstants.Z_NEED_DICT - (ZlibConstants.Z_BUF_ERROR)]; + throw new ZlibException("OutputBuffer is full (AvailableBytesOut == 0)"); + } + + old_flush = last_flush; + last_flush = (int)flush; + + // Write the zlib (rfc1950) header bytes + if (status == INIT_STATE) + { + int header = (Z_DEFLATED + ((w_bits - 8) << 4)) << 8; + int level_flags = (((int)compressionLevel - 1) & 0xff) >> 1; + + if (level_flags > 3) + level_flags = 3; + header |= (level_flags << 6); + if (strstart != 0) + header |= PRESET_DICT; + header += 31 - (header % 31); + + status = BUSY_STATE; + //putShortMSB(header); + unchecked + { + pending[pendingCount++] = (byte)(header >> 8); + pending[pendingCount++] = (byte)header; + } + // Save the adler32 of the preset dictionary: + if (strstart != 0) + { + pending[pendingCount++] = (byte)((_codec._Adler32 & 0xFF000000) >> 24); + pending[pendingCount++] = (byte)((_codec._Adler32 & 0x00FF0000) >> 16); + pending[pendingCount++] = (byte)((_codec._Adler32 & 0x0000FF00) >> 8); + pending[pendingCount++] = (byte)(_codec._Adler32 & 0x000000FF); + } + _codec._Adler32 = Adler.Adler32(0, null, 0, 0); + } + + // Flush as much pending output as possible + if (pendingCount != 0) + { + _codec.flush_pending(); + if (_codec.AvailableBytesOut == 0) + { + //System.out.println(" avail_out==0"); + // Since avail_out is 0, deflate will be called again with + // more output space, but possibly with both pending and + // avail_in equal to zero. There won't be anything to do, + // but this is not an error situation so make sure we + // return OK instead of BUF_ERROR at next call of deflate: + last_flush = -1; + return ZlibConstants.Z_OK; + } + + // Make sure there is something to do and avoid duplicate consecutive + // flushes. For repeated and useless calls with Z_FINISH, we keep + // returning Z_STREAM_END instead of Z_BUFF_ERROR. + } + else if (_codec.AvailableBytesIn == 0 && + (int)flush <= old_flush && + flush != FlushType.Finish) + { + // workitem 8557 + // + // Not sure why this needs to be an error. pendingCount == 0, which + // means there's nothing to deflate. And the caller has not asked + // for a FlushType.Finish, but... that seems very non-fatal. We + // can just say "OK" and do nothing. + + // _codec.Message = z_errmsg[ZlibConstants.Z_NEED_DICT - (ZlibConstants.Z_BUF_ERROR)]; + // throw new ZlibException("AvailableBytesIn == 0 && flush<=old_flush && flush != FlushType.Finish"); + + return ZlibConstants.Z_OK; + } + + // User must not provide more input after the first FINISH: + if (status == FINISH_STATE && _codec.AvailableBytesIn != 0) + { + _codec.Message = _ErrorMessage[ZlibConstants.Z_NEED_DICT - (ZlibConstants.Z_BUF_ERROR)]; + throw new ZlibException("status == FINISH_STATE && _codec.AvailableBytesIn != 0"); + } + + // Start a new block or continue the current one. + if (_codec.AvailableBytesIn != 0 || lookahead != 0 || (flush != FlushType.None && status != FINISH_STATE)) + { + BlockState bstate = DeflateFunction(flush); + + if (bstate == BlockState.FinishStarted || bstate == BlockState.FinishDone) + { + status = FINISH_STATE; + } + if (bstate == BlockState.NeedMore || bstate == BlockState.FinishStarted) + { + if (_codec.AvailableBytesOut == 0) + { + last_flush = -1; // avoid BUF_ERROR next call, see above + } + return ZlibConstants.Z_OK; + // If flush != Z_NO_FLUSH && avail_out == 0, the next call + // of deflate should use the same flush parameter to make sure + // that the flush is complete. So we don't have to output an + // empty block here, this will be done at next call. This also + // ensures that for a very small output buffer, we emit at most + // one empty block. + } + + if (bstate == BlockState.BlockDone) + { + if (flush == FlushType.Partial) + { + _tr_align(); + } + else + { + // FlushType.Full or FlushType.Sync + _tr_stored_block(0, 0, false); + // For a full flush, this empty block will be recognized + // as a special marker by inflate_sync(). + if (flush == FlushType.Full) + { + // clear hash (forget the history) + for (int i = 0; i < hash_size; i++) + head[i] = 0; + } + } + _codec.flush_pending(); + if (_codec.AvailableBytesOut == 0) + { + last_flush = -1; // avoid BUF_ERROR at next call, see above + return ZlibConstants.Z_OK; + } + } + } + + if (flush != FlushType.Finish) + return ZlibConstants.Z_OK; + + if (!WantRfc1950HeaderBytes || Rfc1950BytesEmitted) + return ZlibConstants.Z_STREAM_END; + + // Write the zlib trailer (adler32) + pending[pendingCount++] = (byte)((_codec._Adler32 & 0xFF000000) >> 24); + pending[pendingCount++] = (byte)((_codec._Adler32 & 0x00FF0000) >> 16); + pending[pendingCount++] = (byte)((_codec._Adler32 & 0x0000FF00) >> 8); + pending[pendingCount++] = (byte)(_codec._Adler32 & 0x000000FF); + //putShortMSB((int)(SharedUtils.URShift(_codec._Adler32, 16))); + //putShortMSB((int)(_codec._Adler32 & 0xffff)); + + _codec.flush_pending(); + + // If avail_out is zero, the application will call deflate again + // to flush the rest. + + Rfc1950BytesEmitted = true; // write the trailer only once! + + return pendingCount != 0 ? ZlibConstants.Z_OK : ZlibConstants.Z_STREAM_END; + } + + } +} \ No newline at end of file diff --git a/ROMVault2/SupportedFiles/Zip/ZLib/DeflateStream.cs b/ROMVault2/SupportedFiles/Zip/ZLib/DeflateStream.cs new file mode 100644 index 0000000..4e5557c --- /dev/null +++ b/ROMVault2/SupportedFiles/Zip/ZLib/DeflateStream.cs @@ -0,0 +1,740 @@ +// DeflateStream.cs +// ------------------------------------------------------------------ +// +// Copyright (c) 2009-2010 Dino Chiesa. +// All rights reserved. +// +// This code module is part of DotNetZip, a zipfile class library. +// +// ------------------------------------------------------------------ +// +// This code is licensed under the Microsoft Public License. +// See the file License.txt for the license details. +// More info on: http://dotnetzip.codeplex.com +// +// ------------------------------------------------------------------ +// +// last saved (in emacs): +// Time-stamp: <2011-July-31 14:48:11> +// +// ------------------------------------------------------------------ +// +// This module defines the DeflateStream class, which can be used as a replacement for +// the System.IO.Compression.DeflateStream class in the .NET BCL. +// +// ------------------------------------------------------------------ + + +using System; + +namespace ROMVault2.SupportedFiles.Zip.ZLib +{ + /// + /// A class for compressing and decompressing streams using the Deflate algorithm. + /// + /// + /// + /// + /// + /// The DeflateStream is a Decorator on a . It adds DEFLATE compression or decompression to any + /// stream. + /// + /// + /// + /// Using this stream, applications can compress or decompress data via stream + /// Read and Write operations. Either compresssion or decompression + /// can occur through either reading or writing. The compression format used is + /// DEFLATE, which is documented in IETF RFC 1951, "DEFLATE + /// Compressed Data Format Specification version 1.3.". + /// + /// + /// + /// This class is similar to , except that + /// ZlibStream adds the RFC + /// 1950 - ZLIB framing bytes to a compressed stream when compressing, or + /// expects the RFC1950 framing bytes when decompressing. The DeflateStream + /// does not. + /// + /// + /// + /// + /// + /// + public class DeflateStream : System.IO.Stream + { + internal ZlibBaseStream _baseStream; + internal System.IO.Stream _innerStream; + bool _disposed; + + /// + /// Create a DeflateStream using the specified CompressionMode. + /// + /// + /// + /// When mode is CompressionMode.Compress, the DeflateStream will use + /// the default compression level. The "captive" stream will be closed when + /// the DeflateStream is closed. + /// + /// + /// + /// This example uses a DeflateStream to compress data from a file, and writes + /// the compressed data to another file. + /// + /// using (System.IO.Stream input = System.IO.File.OpenRead(fileToCompress)) + /// { + /// using (var raw = System.IO.File.Create(fileToCompress + ".deflated")) + /// { + /// using (Stream compressor = new DeflateStream(raw, CompressionMode.Compress)) + /// { + /// byte[] buffer = new byte[WORKING_BUFFER_SIZE]; + /// int n; + /// while ((n= input.Read(buffer, 0, buffer.Length)) != 0) + /// { + /// compressor.Write(buffer, 0, n); + /// } + /// } + /// } + /// } + /// + /// + /// + /// Using input As Stream = File.OpenRead(fileToCompress) + /// Using raw As FileStream = File.Create(fileToCompress & ".deflated") + /// Using compressor As Stream = New DeflateStream(raw, CompressionMode.Compress) + /// Dim buffer As Byte() = New Byte(4096) {} + /// Dim n As Integer = -1 + /// Do While (n <> 0) + /// If (n > 0) Then + /// compressor.Write(buffer, 0, n) + /// End If + /// n = input.Read(buffer, 0, buffer.Length) + /// Loop + /// End Using + /// End Using + /// End Using + /// + /// + /// The stream which will be read or written. + /// Indicates whether the DeflateStream will compress or decompress. + public DeflateStream(System.IO.Stream stream, CompressionMode mode) + : this(stream, mode, CompressionLevel.Default, false) + { + } + + /// + /// Create a DeflateStream using the specified CompressionMode and the specified CompressionLevel. + /// + /// + /// + /// + /// + /// When mode is CompressionMode.Decompress, the level parameter is + /// ignored. The "captive" stream will be closed when the DeflateStream is + /// closed. + /// + /// + /// + /// + /// + /// + /// This example uses a DeflateStream to compress data from a file, and writes + /// the compressed data to another file. + /// + /// + /// using (System.IO.Stream input = System.IO.File.OpenRead(fileToCompress)) + /// { + /// using (var raw = System.IO.File.Create(fileToCompress + ".deflated")) + /// { + /// using (Stream compressor = new DeflateStream(raw, + /// CompressionMode.Compress, + /// CompressionLevel.BestCompression)) + /// { + /// byte[] buffer = new byte[WORKING_BUFFER_SIZE]; + /// int n= -1; + /// while (n != 0) + /// { + /// if (n > 0) + /// compressor.Write(buffer, 0, n); + /// n= input.Read(buffer, 0, buffer.Length); + /// } + /// } + /// } + /// } + /// + /// + /// + /// Using input As Stream = File.OpenRead(fileToCompress) + /// Using raw As FileStream = File.Create(fileToCompress & ".deflated") + /// Using compressor As Stream = New DeflateStream(raw, CompressionMode.Compress, CompressionLevel.BestCompression) + /// Dim buffer As Byte() = New Byte(4096) {} + /// Dim n As Integer = -1 + /// Do While (n <> 0) + /// If (n > 0) Then + /// compressor.Write(buffer, 0, n) + /// End If + /// n = input.Read(buffer, 0, buffer.Length) + /// Loop + /// End Using + /// End Using + /// End Using + /// + /// + /// The stream to be read or written while deflating or inflating. + /// Indicates whether the DeflateStream will compress or decompress. + /// A tuning knob to trade speed for effectiveness. + public DeflateStream(System.IO.Stream stream, CompressionMode mode, CompressionLevel level) + : this(stream, mode, level, false) + { + } + + /// + /// Create a DeflateStream using the specified + /// CompressionMode, and explicitly specify whether the + /// stream should be left open after Deflation or Inflation. + /// + /// + /// + /// + /// + /// This constructor allows the application to request that the captive stream + /// remain open after the deflation or inflation occurs. By default, after + /// Close() is called on the stream, the captive stream is also + /// closed. In some cases this is not desired, for example if the stream is a + /// memory stream that will be re-read after compression. Specify true for + /// the parameter to leave the stream open. + /// + /// + /// + /// The DeflateStream will use the default compression level. + /// + /// + /// + /// See the other overloads of this constructor for example code. + /// + /// + /// + /// + /// The stream which will be read or written. This is called the + /// "captive" stream in other places in this documentation. + /// + /// + /// + /// Indicates whether the DeflateStream will compress or decompress. + /// + /// + /// true if the application would like the stream to + /// remain open after inflation/deflation. + public DeflateStream(System.IO.Stream stream, CompressionMode mode, bool leaveOpen) + : this(stream, mode, CompressionLevel.Default, leaveOpen) + { + } + + /// + /// Create a DeflateStream using the specified CompressionMode + /// and the specified CompressionLevel, and explicitly specify whether + /// the stream should be left open after Deflation or Inflation. + /// + /// + /// + /// + /// + /// When mode is CompressionMode.Decompress, the level parameter is ignored. + /// + /// + /// + /// This constructor allows the application to request that the captive stream + /// remain open after the deflation or inflation occurs. By default, after + /// Close() is called on the stream, the captive stream is also + /// closed. In some cases this is not desired, for example if the stream is a + /// that will be re-read after + /// compression. Specify true for the parameter + /// to leave the stream open. + /// + /// + /// + /// + /// + /// + /// This example shows how to use a DeflateStream to compress data from + /// a file, and store the compressed data into another file. + /// + /// + /// using (var output = System.IO.File.Create(fileToCompress + ".deflated")) + /// { + /// using (System.IO.Stream input = System.IO.File.OpenRead(fileToCompress)) + /// { + /// using (Stream compressor = new DeflateStream(output, CompressionMode.Compress, CompressionLevel.BestCompression, true)) + /// { + /// byte[] buffer = new byte[WORKING_BUFFER_SIZE]; + /// int n= -1; + /// while (n != 0) + /// { + /// if (n > 0) + /// compressor.Write(buffer, 0, n); + /// n= input.Read(buffer, 0, buffer.Length); + /// } + /// } + /// } + /// // can write additional data to the output stream here + /// } + /// + /// + /// + /// Using output As FileStream = File.Create(fileToCompress & ".deflated") + /// Using input As Stream = File.OpenRead(fileToCompress) + /// Using compressor As Stream = New DeflateStream(output, CompressionMode.Compress, CompressionLevel.BestCompression, True) + /// Dim buffer As Byte() = New Byte(4096) {} + /// Dim n As Integer = -1 + /// Do While (n <> 0) + /// If (n > 0) Then + /// compressor.Write(buffer, 0, n) + /// End If + /// n = input.Read(buffer, 0, buffer.Length) + /// Loop + /// End Using + /// End Using + /// ' can write additional data to the output stream here. + /// End Using + /// + /// + /// The stream which will be read or written. + /// Indicates whether the DeflateStream will compress or decompress. + /// true if the application would like the stream to remain open after inflation/deflation. + /// A tuning knob to trade speed for effectiveness. + public DeflateStream(System.IO.Stream stream, CompressionMode mode, CompressionLevel level, bool leaveOpen) + { + _innerStream = stream; + _baseStream = new ZlibBaseStream(stream, mode, level, ZlibStreamFlavor.DEFLATE, leaveOpen); + } + + #region Zlib properties + + /// + /// This property sets the flush behavior on the stream. + /// + /// See the ZLIB documentation for the meaning of the flush behavior. + /// + virtual public FlushType FlushMode + { + get { return (this._baseStream._flushMode); } + set + { + if (_disposed) throw new ObjectDisposedException("DeflateStream"); + this._baseStream._flushMode = value; + } + } + + /// + /// The size of the working buffer for the compression codec. + /// + /// + /// + /// + /// The working buffer is used for all stream operations. The default size is + /// 1024 bytes. The minimum size is 128 bytes. You may get better performance + /// with a larger buffer. Then again, you might not. You would have to test + /// it. + /// + /// + /// + /// Set this before the first call to Read() or Write() on the + /// stream. If you try to set it afterwards, it will throw. + /// + /// + public int BufferSize + { + get + { + return this._baseStream._bufferSize; + } + set + { + if (_disposed) throw new ObjectDisposedException("DeflateStream"); + if (this._baseStream._workingBuffer != null) + throw new ZlibException("The working buffer is already set."); + if (value < ZlibConstants.WorkingBufferSizeMin) + throw new ZlibException(String.Format("Don't be silly. {0} bytes?? Use a bigger buffer, at least {1}.", value, ZlibConstants.WorkingBufferSizeMin)); + this._baseStream._bufferSize = value; + } + } + + /// + /// The ZLIB strategy to be used during compression. + /// + /// + /// + /// By tweaking this parameter, you may be able to optimize the compression for + /// data with particular characteristics. + /// + public CompressionStrategy Strategy + { + get + { + return this._baseStream.Strategy; + } + set + { + if (_disposed) throw new ObjectDisposedException("DeflateStream"); + this._baseStream.Strategy = value; + } + } + + /// Returns the total number of bytes input so far. + virtual public long TotalIn + { + get + { + return this._baseStream._z.TotalBytesIn; + } + } + + /// Returns the total number of bytes output so far. + virtual public long TotalOut + { + get + { + return this._baseStream._z.TotalBytesOut; + } + } + + #endregion + + #region System.IO.Stream methods + /// + /// Dispose the stream. + /// + /// + /// + /// This may or may not result in a Close() call on the captive + /// stream. See the constructors that have a leaveOpen parameter + /// for more information. + /// + /// + /// Application code won't call this code directly. This method may be + /// invoked in two distinct scenarios. If disposing == true, the method + /// has been called directly or indirectly by a user's code, for example + /// via the public Dispose() method. In this case, both managed and + /// unmanaged resources can be referenced and disposed. If disposing == + /// false, the method has been called by the runtime from inside the + /// object finalizer and this method should not reference other objects; + /// in that case only unmanaged resources must be referenced or + /// disposed. + /// + /// + /// + /// true if the Dispose method was invoked by user code. + /// + protected override void Dispose(bool disposing) + { + try + { + if (!_disposed) + { + if (disposing && (this._baseStream != null)) + this._baseStream.Close(); + _disposed = true; + } + } + finally + { + base.Dispose(disposing); + } + } + + + + /// + /// Indicates whether the stream can be read. + /// + /// + /// The return value depends on whether the captive stream supports reading. + /// + public override bool CanRead + { + get + { + if (_disposed) throw new ObjectDisposedException("DeflateStream"); + return _baseStream._stream.CanRead; + } + } + + /// + /// Indicates whether the stream supports Seek operations. + /// + /// + /// Always returns false. + /// + public override bool CanSeek + { + get { return false; } + } + + + /// + /// Indicates whether the stream can be written. + /// + /// + /// The return value depends on whether the captive stream supports writing. + /// + public override bool CanWrite + { + get + { + if (_disposed) throw new ObjectDisposedException("DeflateStream"); + return _baseStream._stream.CanWrite; + } + } + + /// + /// Flush the stream. + /// + public override void Flush() + { + if (_disposed) throw new ObjectDisposedException("DeflateStream"); + _baseStream.Flush(); + } + + /// + /// Reading this property always throws a . + /// + public override long Length + { + get { throw new NotImplementedException(); } + } + + /// + /// The position of the stream pointer. + /// + /// + /// + /// Setting this property always throws a . Reading will return the total bytes + /// written out, if used in writing, or the total bytes read in, if used in + /// reading. The count may refer to compressed bytes or uncompressed bytes, + /// depending on how you've used the stream. + /// + public override long Position + { + get + { + if (this._baseStream._streamMode == ZlibBaseStream.StreamMode.Writer) + return this._baseStream._z.TotalBytesOut; + if (this._baseStream._streamMode == ZlibBaseStream.StreamMode.Reader) + return this._baseStream._z.TotalBytesIn; + return 0; + } + set { throw new NotImplementedException(); } + } + + /// + /// Read data from the stream. + /// + /// + /// + /// + /// If you wish to use the DeflateStream to compress data while + /// reading, you can create a DeflateStream with + /// CompressionMode.Compress, providing an uncompressed data stream. + /// Then call Read() on that DeflateStream, and the data read will be + /// compressed as you read. If you wish to use the DeflateStream to + /// decompress data while reading, you can create a DeflateStream with + /// CompressionMode.Decompress, providing a readable compressed data + /// stream. Then call Read() on that DeflateStream, and the data read + /// will be decompressed as you read. + /// + /// + /// + /// A DeflateStream can be used for Read() or Write(), but not both. + /// + /// + /// + /// The buffer into which the read data should be placed. + /// the offset within that data array to put the first byte read. + /// the number of bytes to read. + /// the number of bytes actually read + public override int Read(byte[] buffer, int offset, int count) + { + if (_disposed) throw new ObjectDisposedException("DeflateStream"); + return _baseStream.Read(buffer, offset, count); + } + + + /// + /// Calling this method always throws a . + /// + /// this is irrelevant, since it will always throw! + /// this is irrelevant, since it will always throw! + /// irrelevant! + public override long Seek(long offset, System.IO.SeekOrigin origin) + { + throw new NotImplementedException(); + } + + /// + /// Calling this method always throws a . + /// + /// this is irrelevant, since it will always throw! + public override void SetLength(long value) + { + throw new NotImplementedException(); + } + + /// + /// Write data to the stream. + /// + /// + /// + /// + /// If you wish to use the DeflateStream to compress data while + /// writing, you can create a DeflateStream with + /// CompressionMode.Compress, and a writable output stream. Then call + /// Write() on that DeflateStream, providing uncompressed data + /// as input. The data sent to the output stream will be the compressed form + /// of the data written. If you wish to use the DeflateStream to + /// decompress data while writing, you can create a DeflateStream with + /// CompressionMode.Decompress, and a writable output stream. Then + /// call Write() on that stream, providing previously compressed + /// data. The data sent to the output stream will be the decompressed form of + /// the data written. + /// + /// + /// + /// A DeflateStream can be used for Read() or Write(), + /// but not both. + /// + /// + /// + /// + /// The buffer holding data to write to the stream. + /// the offset within that data array to find the first byte to write. + /// the number of bytes to write. + public override void Write(byte[] buffer, int offset, int count) + { + if (_disposed) throw new ObjectDisposedException("DeflateStream"); + _baseStream.Write(buffer, offset, count); + } + #endregion + + + + + /// + /// Compress a string into a byte array using DEFLATE (RFC 1951). + /// + /// + /// + /// Uncompress it with . + /// + /// + /// DeflateStream.UncompressString(byte[]) + /// DeflateStream.CompressBuffer(byte[]) + /// GZipStream.CompressString(string) + /// ZlibStream.CompressString(string) + /// + /// + /// A string to compress. The string will first be encoded + /// using UTF8, then compressed. + /// + /// + /// The string in compressed form + public static byte[] CompressString(String s) + { + using (var ms = new System.IO.MemoryStream()) + { + System.IO.Stream compressor = + new DeflateStream(ms, CompressionMode.Compress, CompressionLevel.BestCompression); + ZlibBaseStream.CompressString(s, compressor); + return ms.ToArray(); + } + } + + + /// + /// Compress a byte array into a new byte array using DEFLATE. + /// + /// + /// + /// Uncompress it with . + /// + /// + /// DeflateStream.CompressString(string) + /// DeflateStream.UncompressBuffer(byte[]) + /// GZipStream.CompressBuffer(byte[]) + /// ZlibStream.CompressBuffer(byte[]) + /// + /// + /// A buffer to compress. + /// + /// + /// The data in compressed form + public static byte[] CompressBuffer(byte[] b) + { + using (var ms = new System.IO.MemoryStream()) + { + System.IO.Stream compressor = + new DeflateStream( ms, CompressionMode.Compress, CompressionLevel.BestCompression ); + + ZlibBaseStream.CompressBuffer(b, compressor); + return ms.ToArray(); + } + } + + + /// + /// Uncompress a DEFLATE'd byte array into a single string. + /// + /// + /// DeflateStream.CompressString(String) + /// DeflateStream.UncompressBuffer(byte[]) + /// GZipStream.UncompressString(byte[]) + /// ZlibStream.UncompressString(byte[]) + /// + /// + /// A buffer containing DEFLATE-compressed data. + /// + /// + /// The uncompressed string + public static String UncompressString(byte[] compressed) + { + using (var input = new System.IO.MemoryStream(compressed)) + { + System.IO.Stream decompressor = + new DeflateStream(input, CompressionMode.Decompress); + + return ZlibBaseStream.UncompressString(compressed, decompressor); + } + } + + + /// + /// Uncompress a DEFLATE'd byte array into a byte array. + /// + /// + /// DeflateStream.CompressBuffer(byte[]) + /// DeflateStream.UncompressString(byte[]) + /// GZipStream.UncompressBuffer(byte[]) + /// ZlibStream.UncompressBuffer(byte[]) + /// + /// + /// A buffer containing data that has been compressed with DEFLATE. + /// + /// + /// The data in uncompressed form + public static byte[] UncompressBuffer(byte[] compressed) + { + using (var input = new System.IO.MemoryStream(compressed)) + { + System.IO.Stream decompressor = + new DeflateStream( input, CompressionMode.Decompress ); + + return ZlibBaseStream.UncompressBuffer(compressed, decompressor); + } + } + + } + +} + diff --git a/ROMVault2/SupportedFiles/Zip/ZLib/GZipStream.cs b/ROMVault2/SupportedFiles/Zip/ZLib/GZipStream.cs new file mode 100644 index 0000000..9ed7d5e --- /dev/null +++ b/ROMVault2/SupportedFiles/Zip/ZLib/GZipStream.cs @@ -0,0 +1,1033 @@ +// GZipStream.cs +// ------------------------------------------------------------------ +// +// Copyright (c) 2009 Dino Chiesa and Microsoft Corporation. +// All rights reserved. +// +// This code module is part of DotNetZip, a zipfile class library. +// +// ------------------------------------------------------------------ +// +// This code is licensed under the Microsoft Public License. +// See the file License.txt for the license details. +// More info on: http://dotnetzip.codeplex.com +// +// ------------------------------------------------------------------ +// +// last saved (in emacs): +// Time-stamp: <2011-August-08 18:14:39> +// +// ------------------------------------------------------------------ +// +// This module defines the GZipStream class, which can be used as a replacement for +// the System.IO.Compression.GZipStream class in the .NET BCL. NB: The design is not +// completely OO clean: there is some intelligence in the ZlibBaseStream that reads the +// GZip header. +// +// ------------------------------------------------------------------ + + +using System; +using System.IO; + +namespace ROMVault2.SupportedFiles.Zip.ZLib +{ + /// + /// A class for compressing and decompressing GZIP streams. + /// + /// + /// + /// + /// The GZipStream is a Decorator on a + /// . It adds GZIP compression or decompression to any + /// stream. + /// + /// + /// + /// Like the System.IO.Compression.GZipStream in the .NET Base Class Library, the + /// Ionic.Zlib.GZipStream can compress while writing, or decompress while + /// reading, but not vice versa. The compression method used is GZIP, which is + /// documented in IETF RFC + /// 1952, "GZIP file format specification version 4.3". + /// + /// + /// A GZipStream can be used to decompress data (through Read()) or + /// to compress data (through Write()), but not both. + /// + /// + /// + /// If you wish to use the GZipStream to compress data, you must wrap it + /// around a write-able stream. As you call Write() on the GZipStream, the + /// data will be compressed into the GZIP format. If you want to decompress data, + /// you must wrap the GZipStream around a readable stream that contains an + /// IETF RFC 1952-compliant stream. The data will be decompressed as you call + /// Read() on the GZipStream. + /// + /// + /// + /// Though the GZIP format allows data from multiple files to be concatenated + /// together, this stream handles only a single segment of GZIP format, typically + /// representing a single file. + /// + /// + /// + /// This class is similar to and . + /// ZlibStream handles RFC1950-compliant streams. + /// handles RFC1951-compliant streams. This class handles RFC1952-compliant streams. + /// + /// + /// + /// + /// + /// + public class GZipStream : System.IO.Stream + { + // GZip format + // source: http://tools.ietf.org/html/rfc1952 + // + // header id: 2 bytes 1F 8B + // compress method 1 byte 8= DEFLATE (none other supported) + // flag 1 byte bitfield (See below) + // mtime 4 bytes time_t (seconds since jan 1, 1970 UTC of the file. + // xflg 1 byte 2 = max compress used , 4 = max speed (can be ignored) + // OS 1 byte OS for originating archive. set to 0xFF in compression. + // extra field length 2 bytes optional - only if FEXTRA is set. + // extra field varies + // filename varies optional - if FNAME is set. zero terminated. ISO-8859-1. + // file comment varies optional - if FCOMMENT is set. zero terminated. ISO-8859-1. + // crc16 1 byte optional - present only if FHCRC bit is set + // compressed data varies + // CRC32 4 bytes + // isize 4 bytes data size modulo 2^32 + // + // FLG (FLaGs) + // bit 0 FTEXT - indicates file is ASCII text (can be safely ignored) + // bit 1 FHCRC - there is a CRC16 for the header immediately following the header + // bit 2 FEXTRA - extra fields are present + // bit 3 FNAME - the zero-terminated filename is present. encoding; ISO-8859-1. + // bit 4 FCOMMENT - a zero-terminated file comment is present. encoding: ISO-8859-1 + // bit 5 reserved + // bit 6 reserved + // bit 7 reserved + // + // On consumption: + // Extra field is a bunch of nonsense and can be safely ignored. + // Header CRC and OS, likewise. + // + // on generation: + // all optional fields get 0, except for the OS, which gets 255. + // + + + + /// + /// The comment on the GZIP stream. + /// + /// + /// + /// + /// The GZIP format allows for each file to optionally have an associated + /// comment stored with the file. The comment is encoded with the ISO-8859-1 + /// code page. To include a comment in a GZIP stream you create, set this + /// property before calling Write() for the first time on the + /// GZipStream. + /// + /// + /// + /// When using GZipStream to decompress, you can retrieve this property + /// after the first call to Read(). If no comment has been set in the + /// GZIP bytestream, the Comment property will return null + /// (Nothing in VB). + /// + /// + public String Comment + { + get + { + return _Comment; + } + set + { + if (_disposed) throw new ObjectDisposedException("GZipStream"); + _Comment = value; + } + } + + /// + /// The FileName for the GZIP stream. + /// + /// + /// + /// + /// + /// The GZIP format optionally allows each file to have an associated + /// filename. When compressing data (through Write()), set this + /// FileName before calling Write() the first time on the GZipStream. + /// The actual filename is encoded into the GZIP bytestream with the + /// ISO-8859-1 code page, according to RFC 1952. It is the application's + /// responsibility to insure that the FileName can be encoded and decoded + /// correctly with this code page. + /// + /// + /// + /// When decompressing (through Read()), you can retrieve this value + /// any time after the first Read(). In the case where there was no filename + /// encoded into the GZIP bytestream, the property will return null (Nothing + /// in VB). + /// + /// + public String FileName + { + get { return _FileName; } + set + { + if (_disposed) throw new ObjectDisposedException("GZipStream"); + _FileName = value; + if (_FileName == null) return; + if (_FileName.IndexOf("/") != -1) + { + _FileName = _FileName.Replace("/", "\\"); + } + if (_FileName.EndsWith("\\")) + throw new Exception("Illegal filename"); + if (_FileName.IndexOf("\\") != -1) + { + // trim any leading path + _FileName = Path.GetFileName(_FileName); + } + } + } + + /// + /// The last modified time for the GZIP stream. + /// + /// + /// + /// GZIP allows the storage of a last modified time with each GZIP entry. + /// When compressing data, you can set this before the first call to + /// Write(). When decompressing, you can retrieve this value any time + /// after the first call to Read(). + /// + public DateTime? LastModified; + + /// + /// The CRC on the GZIP stream. + /// + /// + /// This is used for internal error checking. You probably don't need to look at this property. + /// + public int Crc32 { get { return _Crc32; } } + + private int _headerByteCount; + internal ZlibBaseStream _baseStream; + bool _disposed; + bool _firstReadDone; + string _FileName; + string _Comment; + int _Crc32; + + + /// + /// Create a GZipStream using the specified CompressionMode. + /// + /// + /// + /// + /// When mode is CompressionMode.Compress, the GZipStream will use the + /// default compression level. + /// + /// + /// + /// As noted in the class documentation, the CompressionMode (Compress + /// or Decompress) also establishes the "direction" of the stream. A + /// GZipStream with CompressionMode.Compress works only through + /// Write(). A GZipStream with + /// CompressionMode.Decompress works only through Read(). + /// + /// + /// + /// + /// + /// This example shows how to use a GZipStream to compress data. + /// + /// using (System.IO.Stream input = System.IO.File.OpenRead(fileToCompress)) + /// { + /// using (var raw = System.IO.File.Create(outputFile)) + /// { + /// using (Stream compressor = new GZipStream(raw, CompressionMode.Compress)) + /// { + /// byte[] buffer = new byte[WORKING_BUFFER_SIZE]; + /// int n; + /// while ((n= input.Read(buffer, 0, buffer.Length)) != 0) + /// { + /// compressor.Write(buffer, 0, n); + /// } + /// } + /// } + /// } + /// + /// + /// Dim outputFile As String = (fileToCompress & ".compressed") + /// Using input As Stream = File.OpenRead(fileToCompress) + /// Using raw As FileStream = File.Create(outputFile) + /// Using compressor As Stream = New GZipStream(raw, CompressionMode.Compress) + /// Dim buffer As Byte() = New Byte(4096) {} + /// Dim n As Integer = -1 + /// Do While (n <> 0) + /// If (n > 0) Then + /// compressor.Write(buffer, 0, n) + /// End If + /// n = input.Read(buffer, 0, buffer.Length) + /// Loop + /// End Using + /// End Using + /// End Using + /// + /// + /// + /// + /// This example shows how to use a GZipStream to uncompress a file. + /// + /// private void GunZipFile(string filename) + /// { + /// if (!filename.EndsWith(".gz)) + /// throw new ArgumentException("filename"); + /// var DecompressedFile = filename.Substring(0,filename.Length-3); + /// byte[] working = new byte[WORKING_BUFFER_SIZE]; + /// int n= 1; + /// using (System.IO.Stream input = System.IO.File.OpenRead(filename)) + /// { + /// using (Stream decompressor= new Ionic.Zlib.GZipStream(input, CompressionMode.Decompress, true)) + /// { + /// using (var output = System.IO.File.Create(DecompressedFile)) + /// { + /// while (n !=0) + /// { + /// n= decompressor.Read(working, 0, working.Length); + /// if (n > 0) + /// { + /// output.Write(working, 0, n); + /// } + /// } + /// } + /// } + /// } + /// } + /// + /// + /// + /// Private Sub GunZipFile(ByVal filename as String) + /// If Not (filename.EndsWith(".gz)) Then + /// Throw New ArgumentException("filename") + /// End If + /// Dim DecompressedFile as String = filename.Substring(0,filename.Length-3) + /// Dim working(WORKING_BUFFER_SIZE) as Byte + /// Dim n As Integer = 1 + /// Using input As Stream = File.OpenRead(filename) + /// Using decompressor As Stream = new Ionic.Zlib.GZipStream(input, CompressionMode.Decompress, True) + /// Using output As Stream = File.Create(UncompressedFile) + /// Do + /// n= decompressor.Read(working, 0, working.Length) + /// If n > 0 Then + /// output.Write(working, 0, n) + /// End IF + /// Loop While (n > 0) + /// End Using + /// End Using + /// End Using + /// End Sub + /// + /// + /// + /// The stream which will be read or written. + /// Indicates whether the GZipStream will compress or decompress. + public GZipStream(Stream stream, CompressionMode mode) + : this(stream, mode, CompressionLevel.Default, false) + { + } + + /// + /// Create a GZipStream using the specified CompressionMode and + /// the specified CompressionLevel. + /// + /// + /// + /// + /// The CompressionMode (Compress or Decompress) also establishes the + /// "direction" of the stream. A GZipStream with + /// CompressionMode.Compress works only through Write(). A + /// GZipStream with CompressionMode.Decompress works only + /// through Read(). + /// + /// + /// + /// + /// + /// + /// This example shows how to use a GZipStream to compress a file into a .gz file. + /// + /// + /// using (System.IO.Stream input = System.IO.File.OpenRead(fileToCompress)) + /// { + /// using (var raw = System.IO.File.Create(fileToCompress + ".gz")) + /// { + /// using (Stream compressor = new GZipStream(raw, + /// CompressionMode.Compress, + /// CompressionLevel.BestCompression)) + /// { + /// byte[] buffer = new byte[WORKING_BUFFER_SIZE]; + /// int n; + /// while ((n= input.Read(buffer, 0, buffer.Length)) != 0) + /// { + /// compressor.Write(buffer, 0, n); + /// } + /// } + /// } + /// } + /// + /// + /// + /// Using input As Stream = File.OpenRead(fileToCompress) + /// Using raw As FileStream = File.Create(fileToCompress & ".gz") + /// Using compressor As Stream = New GZipStream(raw, CompressionMode.Compress, CompressionLevel.BestCompression) + /// Dim buffer As Byte() = New Byte(4096) {} + /// Dim n As Integer = -1 + /// Do While (n <> 0) + /// If (n > 0) Then + /// compressor.Write(buffer, 0, n) + /// End If + /// n = input.Read(buffer, 0, buffer.Length) + /// Loop + /// End Using + /// End Using + /// End Using + /// + /// + /// The stream to be read or written while deflating or inflating. + /// Indicates whether the GZipStream will compress or decompress. + /// A tuning knob to trade speed for effectiveness. + public GZipStream(Stream stream, CompressionMode mode, CompressionLevel level) + : this(stream, mode, level, false) + { + } + + /// + /// Create a GZipStream using the specified CompressionMode, and + /// explicitly specify whether the stream should be left open after Deflation + /// or Inflation. + /// + /// + /// + /// + /// This constructor allows the application to request that the captive stream + /// remain open after the deflation or inflation occurs. By default, after + /// Close() is called on the stream, the captive stream is also + /// closed. In some cases this is not desired, for example if the stream is a + /// memory stream that will be re-read after compressed data has been written + /// to it. Specify true for the parameter to leave + /// the stream open. + /// + /// + /// + /// The (Compress or Decompress) also + /// establishes the "direction" of the stream. A GZipStream with + /// CompressionMode.Compress works only through Write(). A GZipStream + /// with CompressionMode.Decompress works only through Read(). + /// + /// + /// + /// The GZipStream will use the default compression level. If you want + /// to specify the compression level, see . + /// + /// + /// + /// See the other overloads of this constructor for example code. + /// + /// + /// + /// + /// + /// The stream which will be read or written. This is called the "captive" + /// stream in other places in this documentation. + /// + /// + /// Indicates whether the GZipStream will compress or decompress. + /// + /// + /// + /// true if the application would like the base stream to remain open after + /// inflation/deflation. + /// + public GZipStream(Stream stream, CompressionMode mode, bool leaveOpen) + : this(stream, mode, CompressionLevel.Default, leaveOpen) + { + } + + /// + /// Create a GZipStream using the specified CompressionMode and the + /// specified CompressionLevel, and explicitly specify whether the + /// stream should be left open after Deflation or Inflation. + /// + /// + /// + /// + /// + /// This constructor allows the application to request that the captive stream + /// remain open after the deflation or inflation occurs. By default, after + /// Close() is called on the stream, the captive stream is also + /// closed. In some cases this is not desired, for example if the stream is a + /// memory stream that will be re-read after compressed data has been written + /// to it. Specify true for the parameter to + /// leave the stream open. + /// + /// + /// + /// As noted in the class documentation, the CompressionMode (Compress + /// or Decompress) also establishes the "direction" of the stream. A + /// GZipStream with CompressionMode.Compress works only through + /// Write(). A GZipStream with CompressionMode.Decompress works only + /// through Read(). + /// + /// + /// + /// + /// + /// This example shows how to use a GZipStream to compress data. + /// + /// using (System.IO.Stream input = System.IO.File.OpenRead(fileToCompress)) + /// { + /// using (var raw = System.IO.File.Create(outputFile)) + /// { + /// using (Stream compressor = new GZipStream(raw, CompressionMode.Compress, CompressionLevel.BestCompression, true)) + /// { + /// byte[] buffer = new byte[WORKING_BUFFER_SIZE]; + /// int n; + /// while ((n= input.Read(buffer, 0, buffer.Length)) != 0) + /// { + /// compressor.Write(buffer, 0, n); + /// } + /// } + /// } + /// } + /// + /// + /// Dim outputFile As String = (fileToCompress & ".compressed") + /// Using input As Stream = File.OpenRead(fileToCompress) + /// Using raw As FileStream = File.Create(outputFile) + /// Using compressor As Stream = New GZipStream(raw, CompressionMode.Compress, CompressionLevel.BestCompression, True) + /// Dim buffer As Byte() = New Byte(4096) {} + /// Dim n As Integer = -1 + /// Do While (n <> 0) + /// If (n > 0) Then + /// compressor.Write(buffer, 0, n) + /// End If + /// n = input.Read(buffer, 0, buffer.Length) + /// Loop + /// End Using + /// End Using + /// End Using + /// + /// + /// The stream which will be read or written. + /// Indicates whether the GZipStream will compress or decompress. + /// true if the application would like the stream to remain open after inflation/deflation. + /// A tuning knob to trade speed for effectiveness. + public GZipStream(Stream stream, CompressionMode mode, CompressionLevel level, bool leaveOpen) + { + _baseStream = new ZlibBaseStream(stream, mode, level, ZlibStreamFlavor.GZIP, leaveOpen); + } + + #region Zlib properties + + /// + /// This property sets the flush behavior on the stream. + /// + virtual public FlushType FlushMode + { + get { return (this._baseStream._flushMode); } + set { + if (_disposed) throw new ObjectDisposedException("GZipStream"); + this._baseStream._flushMode = value; + } + } + + /// + /// The size of the working buffer for the compression codec. + /// + /// + /// + /// + /// The working buffer is used for all stream operations. The default size is + /// 1024 bytes. The minimum size is 128 bytes. You may get better performance + /// with a larger buffer. Then again, you might not. You would have to test + /// it. + /// + /// + /// + /// Set this before the first call to Read() or Write() on the + /// stream. If you try to set it afterwards, it will throw. + /// + /// + public int BufferSize + { + get + { + return this._baseStream._bufferSize; + } + set + { + if (_disposed) throw new ObjectDisposedException("GZipStream"); + if (this._baseStream._workingBuffer != null) + throw new ZlibException("The working buffer is already set."); + if (value < ZlibConstants.WorkingBufferSizeMin) + throw new ZlibException(String.Format("Don't be silly. {0} bytes?? Use a bigger buffer, at least {1}.", value, ZlibConstants.WorkingBufferSizeMin)); + this._baseStream._bufferSize = value; + } + } + + + /// Returns the total number of bytes input so far. + virtual public long TotalIn + { + get + { + return this._baseStream._z.TotalBytesIn; + } + } + + /// Returns the total number of bytes output so far. + virtual public long TotalOut + { + get + { + return this._baseStream._z.TotalBytesOut; + } + } + + #endregion + + #region Stream methods + + /// + /// Dispose the stream. + /// + /// + /// + /// This may or may not result in a Close() call on the captive + /// stream. See the constructors that have a leaveOpen parameter + /// for more information. + /// + /// + /// This method may be invoked in two distinct scenarios. If disposing + /// == true, the method has been called directly or indirectly by a + /// user's code, for example via the public Dispose() method. In this + /// case, both managed and unmanaged resources can be referenced and + /// disposed. If disposing == false, the method has been called by the + /// runtime from inside the object finalizer and this method should not + /// reference other objects; in that case only unmanaged resources must + /// be referenced or disposed. + /// + /// + /// + /// indicates whether the Dispose method was invoked by user code. + /// + protected override void Dispose(bool disposing) + { + try + { + if (!_disposed) + { + if (disposing && (this._baseStream != null)) + { + this._baseStream.Close(); + this._Crc32 = _baseStream.Crc32; + } + _disposed = true; + } + } + finally + { + base.Dispose(disposing); + } + } + + + /// + /// Indicates whether the stream can be read. + /// + /// + /// The return value depends on whether the captive stream supports reading. + /// + public override bool CanRead + { + get + { + if (_disposed) throw new ObjectDisposedException("GZipStream"); + return _baseStream._stream.CanRead; + } + } + + /// + /// Indicates whether the stream supports Seek operations. + /// + /// + /// Always returns false. + /// + public override bool CanSeek + { + get { return false; } + } + + + /// + /// Indicates whether the stream can be written. + /// + /// + /// The return value depends on whether the captive stream supports writing. + /// + public override bool CanWrite + { + get + { + if (_disposed) throw new ObjectDisposedException("GZipStream"); + return _baseStream._stream.CanWrite; + } + } + + /// + /// Flush the stream. + /// + public override void Flush() + { + if (_disposed) throw new ObjectDisposedException("GZipStream"); + _baseStream.Flush(); + } + + /// + /// Reading this property always throws a . + /// + public override long Length + { + get { throw new NotImplementedException(); } + } + + /// + /// The position of the stream pointer. + /// + /// + /// + /// Setting this property always throws a . Reading will return the total bytes + /// written out, if used in writing, or the total bytes read in, if used in + /// reading. The count may refer to compressed bytes or uncompressed bytes, + /// depending on how you've used the stream. + /// + public override long Position + { + get + { + if (this._baseStream._streamMode == ZlibBaseStream.StreamMode.Writer) + return this._baseStream._z.TotalBytesOut + _headerByteCount; + if (this._baseStream._streamMode == ZlibBaseStream.StreamMode.Reader) + return this._baseStream._z.TotalBytesIn + this._baseStream._gzipHeaderByteCount; + return 0; + } + + set { throw new NotImplementedException(); } + } + + /// + /// Read and decompress data from the source stream. + /// + /// + /// + /// With a GZipStream, decompression is done through reading. + /// + /// + /// + /// + /// byte[] working = new byte[WORKING_BUFFER_SIZE]; + /// using (System.IO.Stream input = System.IO.File.OpenRead(_CompressedFile)) + /// { + /// using (Stream decompressor= new Ionic.Zlib.GZipStream(input, CompressionMode.Decompress, true)) + /// { + /// using (var output = System.IO.File.Create(_DecompressedFile)) + /// { + /// int n; + /// while ((n= decompressor.Read(working, 0, working.Length)) !=0) + /// { + /// output.Write(working, 0, n); + /// } + /// } + /// } + /// } + /// + /// + /// The buffer into which the decompressed data should be placed. + /// the offset within that data array to put the first byte read. + /// the number of bytes to read. + /// the number of bytes actually read + public override int Read(byte[] buffer, int offset, int count) + { + if (_disposed) throw new ObjectDisposedException("GZipStream"); + int n = _baseStream.Read(buffer, offset, count); + + // Console.WriteLine("GZipStream::Read(buffer, off({0}), c({1}) = {2}", offset, count, n); + // Console.WriteLine( Util.FormatByteArray(buffer, offset, n) ); + + if (!_firstReadDone) + { + _firstReadDone = true; + FileName = _baseStream._GzipFileName; + Comment = _baseStream._GzipComment; + } + return n; + } + + + + /// + /// Calling this method always throws a . + /// + /// irrelevant; it will always throw! + /// irrelevant; it will always throw! + /// irrelevant! + public override long Seek(long offset, SeekOrigin origin) + { + throw new NotImplementedException(); + } + + /// + /// Calling this method always throws a . + /// + /// irrelevant; this method will always throw! + public override void SetLength(long value) + { + throw new NotImplementedException(); + } + + /// + /// Write data to the stream. + /// + /// + /// + /// + /// If you wish to use the GZipStream to compress data while writing, + /// you can create a GZipStream with CompressionMode.Compress, and a + /// writable output stream. Then call Write() on that GZipStream, + /// providing uncompressed data as input. The data sent to the output stream + /// will be the compressed form of the data written. + /// + /// + /// + /// A GZipStream can be used for Read() or Write(), but not + /// both. Writing implies compression. Reading implies decompression. + /// + /// + /// + /// The buffer holding data to write to the stream. + /// the offset within that data array to find the first byte to write. + /// the number of bytes to write. + public override void Write(byte[] buffer, int offset, int count) + { + if (_disposed) throw new ObjectDisposedException("GZipStream"); + if (_baseStream._streamMode == ZlibBaseStream.StreamMode.Undefined) + { + //Console.WriteLine("GZipStream: First write"); + if (_baseStream._wantCompress) + { + // first write in compression, therefore, emit the GZIP header + _headerByteCount = EmitHeader(); + } + else + { + throw new InvalidOperationException(); + } + } + + _baseStream.Write(buffer, offset, count); + } + #endregion + + + internal static readonly System.DateTime _unixEpoch = new System.DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); +#if SILVERLIGHT || NETCF + internal static readonly System.Text.Encoding iso8859dash1 = new Ionic.Encoding.Iso8859Dash1Encoding(); +#else + internal static readonly System.Text.Encoding iso8859dash1 = System.Text.Encoding.GetEncoding("iso-8859-1"); +#endif + + + private int EmitHeader() + { + byte[] commentBytes = (Comment == null) ? null : iso8859dash1.GetBytes(Comment); + byte[] filenameBytes = (FileName == null) ? null : iso8859dash1.GetBytes(FileName); + + int cbLength = (Comment == null) ? 0 : commentBytes.Length + 1; + int fnLength = (FileName == null) ? 0 : filenameBytes.Length + 1; + + int bufferLength = 10 + cbLength + fnLength; + byte[] header = new byte[bufferLength]; + int i = 0; + // ID + header[i++] = 0x1F; + header[i++] = 0x8B; + + // compression method + header[i++] = 8; + byte flag = 0; + if (Comment != null) + flag ^= 0x10; + if (FileName != null) + flag ^= 0x8; + + // flag + header[i++] = flag; + + // mtime + if (!LastModified.HasValue) LastModified = DateTime.Now; + System.TimeSpan delta = LastModified.Value - _unixEpoch; + Int32 timet = (Int32)delta.TotalSeconds; + Array.Copy(BitConverter.GetBytes(timet), 0, header, i, 4); + i += 4; + + // xflg + header[i++] = 0; // this field is totally useless + // OS + header[i++] = 0xFF; // 0xFF == unspecified + + // extra field length - only if FEXTRA is set, which it is not. + //header[i++]= 0; + //header[i++]= 0; + + // filename + if (fnLength != 0) + { + Array.Copy(filenameBytes, 0, header, i, fnLength - 1); + i += fnLength - 1; + header[i++] = 0; // terminate + } + + // comment + if (cbLength != 0) + { + Array.Copy(commentBytes, 0, header, i, cbLength - 1); + i += cbLength - 1; + header[i++] = 0; // terminate + } + + _baseStream._stream.Write(header, 0, header.Length); + + return header.Length; // bytes written + } + + + + /// + /// Compress a string into a byte array using GZip. + /// + /// + /// + /// Uncompress it with . + /// + /// + /// + /// + /// + /// + /// A string to compress. The string will first be encoded + /// using UTF8, then compressed. + /// + /// + /// The string in compressed form + public static byte[] CompressString(String s) + { + using (var ms = new MemoryStream()) + { + System.IO.Stream compressor = + new GZipStream(ms, CompressionMode.Compress, CompressionLevel.BestCompression); + ZlibBaseStream.CompressString(s, compressor); + return ms.ToArray(); + } + } + + + /// + /// Compress a byte array into a new byte array using GZip. + /// + /// + /// + /// Uncompress it with . + /// + /// + /// + /// + /// + /// + /// A buffer to compress. + /// + /// + /// The data in compressed form + public static byte[] CompressBuffer(byte[] b) + { + using (var ms = new MemoryStream()) + { + System.IO.Stream compressor = + new GZipStream( ms, CompressionMode.Compress, CompressionLevel.BestCompression ); + + ZlibBaseStream.CompressBuffer(b, compressor); + return ms.ToArray(); + } + } + + + /// + /// Uncompress a GZip'ed byte array into a single string. + /// + /// + /// + /// + /// + /// + /// A buffer containing GZIP-compressed data. + /// + /// + /// The uncompressed string + public static String UncompressString(byte[] compressed) + { + using (var input = new MemoryStream(compressed)) + { + Stream decompressor = new GZipStream(input, CompressionMode.Decompress); + return ZlibBaseStream.UncompressString(compressed, decompressor); + } + } + + + /// + /// Uncompress a GZip'ed byte array into a byte array. + /// + /// + /// + /// + /// + /// + /// A buffer containing data that has been compressed with GZip. + /// + /// + /// The data in uncompressed form + public static byte[] UncompressBuffer(byte[] compressed) + { + using (var input = new System.IO.MemoryStream(compressed)) + { + System.IO.Stream decompressor = + new GZipStream( input, CompressionMode.Decompress ); + + return ZlibBaseStream.UncompressBuffer(compressed, decompressor); + } + } + + + } +} diff --git a/ROMVault2/SupportedFiles/Zip/ZLib/InfTree.cs b/ROMVault2/SupportedFiles/Zip/ZLib/InfTree.cs new file mode 100644 index 0000000..7d8faf7 --- /dev/null +++ b/ROMVault2/SupportedFiles/Zip/ZLib/InfTree.cs @@ -0,0 +1,436 @@ +// Inftree.cs +// ------------------------------------------------------------------ +// +// Copyright (c) 2009 Dino Chiesa and Microsoft Corporation. +// All rights reserved. +// +// This code module is part of DotNetZip, a zipfile class library. +// +// ------------------------------------------------------------------ +// +// This code is licensed under the Microsoft Public License. +// See the file License.txt for the license details. +// More info on: http://dotnetzip.codeplex.com +// +// ------------------------------------------------------------------ +// +// last saved (in emacs): +// Time-stamp: <2009-October-28 12:43:54> +// +// ------------------------------------------------------------------ +// +// This module defines classes used in decompression. This code is derived +// from the jzlib implementation of zlib. In keeping with the license for jzlib, +// the copyright to that code is below. +// +// ------------------------------------------------------------------ +// +// Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// 2. 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. +// +// 3. The names of the authors may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 JCRAFT, +// INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE 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. +// +// ----------------------------------------------------------------------- +// +// This program is based on zlib-1.1.3; credit to authors +// Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) +// and contributors of zlib. +// +// ----------------------------------------------------------------------- + + +using System; + +namespace ROMVault2.SupportedFiles.Zip.ZLib +{ + + sealed class InfTree + { + + private const int MANY = 1440; + + private const int Z_OK = 0; + private const int Z_STREAM_END = 1; + private const int Z_NEED_DICT = 2; + private const int Z_ERRNO = - 1; + private const int Z_STREAM_ERROR = - 2; + private const int Z_DATA_ERROR = - 3; + private const int Z_MEM_ERROR = - 4; + private const int Z_BUF_ERROR = - 5; + private const int Z_VERSION_ERROR = - 6; + + internal const int fixed_bl = 9; + internal const int fixed_bd = 5; + + //UPGRADE_NOTE: Final was removed from the declaration of 'fixed_tl'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" + internal static readonly int[] fixed_tl = new int[]{96, 7, 256, 0, 8, 80, 0, 8, 16, 84, 8, 115, 82, 7, 31, 0, 8, 112, 0, 8, 48, 0, 9, 192, 80, 7, 10, 0, 8, 96, 0, 8, 32, 0, 9, 160, 0, 8, 0, 0, 8, 128, 0, 8, 64, 0, 9, 224, 80, 7, 6, 0, 8, 88, 0, 8, 24, 0, 9, 144, 83, 7, 59, 0, 8, 120, 0, 8, 56, 0, 9, 208, 81, 7, 17, 0, 8, 104, 0, 8, 40, 0, 9, 176, 0, 8, 8, 0, 8, 136, 0, 8, 72, 0, 9, 240, 80, 7, 4, 0, 8, 84, 0, 8, 20, 85, 8, 227, 83, 7, 43, 0, 8, 116, 0, 8, 52, 0, 9, 200, 81, 7, 13, 0, 8, 100, 0, 8, 36, 0, 9, 168, 0, 8, 4, 0, 8, 132, 0, 8, 68, 0, 9, 232, 80, 7, 8, 0, 8, 92, 0, 8, 28, 0, 9, 152, 84, 7, 83, 0, 8, 124, 0, 8, 60, 0, 9, 216, 82, 7, 23, 0, 8, 108, 0, 8, 44, 0, 9, 184, 0, 8, 12, 0, 8, 140, 0, 8, 76, 0, 9, 248, 80, 7, 3, 0, 8, 82, 0, 8, 18, 85, 8, 163, 83, 7, 35, 0, 8, 114, 0, 8, 50, 0, 9, 196, 81, 7, 11, 0, 8, 98, 0, 8, 34, 0, 9, 164, 0, 8, 2, 0, 8, 130, 0, 8, 66, 0, 9, 228, 80, 7, 7, 0, 8, 90, 0, 8, 26, 0, 9, 148, 84, 7, 67, 0, 8, 122, 0, 8, 58, 0, 9, 212, 82, 7, 19, 0, 8, 106, 0, 8, 42, 0, 9, 180, 0, 8, 10, 0, 8, 138, 0, 8, 74, 0, 9, 244, 80, 7, 5, 0, 8, 86, 0, 8, 22, 192, 8, 0, 83, 7, 51, 0, 8, 118, 0, 8, 54, 0, 9, 204, 81, 7, 15, 0, 8, 102, 0, 8, 38, 0, 9, 172, 0, 8, 6, 0, 8, 134, 0, 8, 70, 0, 9, 236, 80, 7, 9, 0, 8, 94, 0, 8, 30, 0, 9, 156, 84, 7, 99, 0, 8, 126, 0, 8, 62, 0, 9, 220, 82, 7, 27, 0, 8, 110, 0, 8, 46, 0, 9, 188, 0, 8, 14, 0, 8, 142, 0, 8, 78, 0, 9, 252, 96, 7, 256, 0, 8, 81, 0, 8, 17, 85, 8, 131, 82, 7, 31, 0, 8, 113, 0, 8, 49, 0, 9, 194, 80, 7, 10, 0, 8, 97, 0, 8, 33, 0, 9, 162, 0, 8, 1, 0, 8, 129, 0, 8, 65, 0, 9, 226, 80, 7, 6, 0, 8, 89, 0, 8, 25, 0, 9, 146, 83, 7, 59, 0, 8, 121, 0, 8, 57, 0, 9, 210, 81, 7, 17, 0, 8, 105, 0, 8, 41, 0, 9, 178, 0, 8, 9, 0, 8, 137, 0, 8, 73, 0, 9, 242, 80, 7, 4, 0, 8, 85, 0, 8, 21, 80, 8, 258, 83, 7, 43, 0, 8, 117, 0, 8, 53, 0, 9, 202, 81, 7, 13, 0, 8, 101, 0, 8, 37, 0, 9, 170, 0, 8, 5, 0, 8, 133, 0, 8, 69, 0, 9, 234, 80, 7, 8, 0, 8, 93, 0, 8, 29, 0, 9, 154, 84, 7, 83, 0, 8, 125, 0, 8, 61, 0, 9, 218, 82, 7, 23, 0, 8, 109, 0, 8, 45, 0, 9, 186, + 0, 8, 13, 0, 8, 141, 0, 8, 77, 0, 9, 250, 80, 7, 3, 0, 8, 83, 0, 8, 19, 85, 8, 195, 83, 7, 35, 0, 8, 115, 0, 8, 51, 0, 9, 198, 81, 7, 11, 0, 8, 99, 0, 8, 35, 0, 9, 166, 0, 8, 3, 0, 8, 131, 0, 8, 67, 0, 9, 230, 80, 7, 7, 0, 8, 91, 0, 8, 27, 0, 9, 150, 84, 7, 67, 0, 8, 123, 0, 8, 59, 0, 9, 214, 82, 7, 19, 0, 8, 107, 0, 8, 43, 0, 9, 182, 0, 8, 11, 0, 8, 139, 0, 8, 75, 0, 9, 246, 80, 7, 5, 0, 8, 87, 0, 8, 23, 192, 8, 0, 83, 7, 51, 0, 8, 119, 0, 8, 55, 0, 9, 206, 81, 7, 15, 0, 8, 103, 0, 8, 39, 0, 9, 174, 0, 8, 7, 0, 8, 135, 0, 8, 71, 0, 9, 238, 80, 7, 9, 0, 8, 95, 0, 8, 31, 0, 9, 158, 84, 7, 99, 0, 8, 127, 0, 8, 63, 0, 9, 222, 82, 7, 27, 0, 8, 111, 0, 8, 47, 0, 9, 190, 0, 8, 15, 0, 8, 143, 0, 8, 79, 0, 9, 254, 96, 7, 256, 0, 8, 80, 0, 8, 16, 84, 8, 115, 82, 7, 31, 0, 8, 112, 0, 8, 48, 0, 9, 193, 80, 7, 10, 0, 8, 96, 0, 8, 32, 0, 9, 161, 0, 8, 0, 0, 8, 128, 0, 8, 64, 0, 9, 225, 80, 7, 6, 0, 8, 88, 0, 8, 24, 0, 9, 145, 83, 7, 59, 0, 8, 120, 0, 8, 56, 0, 9, 209, 81, 7, 17, 0, 8, 104, 0, 8, 40, 0, 9, 177, 0, 8, 8, 0, 8, 136, 0, 8, 72, 0, 9, 241, 80, 7, 4, 0, 8, 84, 0, 8, 20, 85, 8, 227, 83, 7, 43, 0, 8, 116, 0, 8, 52, 0, 9, 201, 81, 7, 13, 0, 8, 100, 0, 8, 36, 0, 9, 169, 0, 8, 4, 0, 8, 132, 0, 8, 68, 0, 9, 233, 80, 7, 8, 0, 8, 92, 0, 8, 28, 0, 9, 153, 84, 7, 83, 0, 8, 124, 0, 8, 60, 0, 9, 217, 82, 7, 23, 0, 8, 108, 0, 8, 44, 0, 9, 185, 0, 8, 12, 0, 8, 140, 0, 8, 76, 0, 9, 249, 80, 7, 3, 0, 8, 82, 0, 8, 18, 85, 8, 163, 83, 7, 35, 0, 8, 114, 0, 8, 50, 0, 9, 197, 81, 7, 11, 0, 8, 98, 0, 8, 34, 0, 9, 165, 0, 8, 2, 0, 8, 130, 0, 8, 66, 0, 9, 229, 80, 7, 7, 0, 8, 90, 0, 8, 26, 0, 9, 149, 84, 7, 67, 0, 8, 122, 0, 8, 58, 0, 9, 213, 82, 7, 19, 0, 8, 106, 0, 8, 42, 0, 9, 181, 0, 8, 10, 0, 8, 138, 0, 8, 74, 0, 9, 245, 80, 7, 5, 0, 8, 86, 0, 8, 22, 192, 8, 0, 83, 7, 51, 0, 8, 118, 0, 8, 54, 0, 9, 205, 81, 7, 15, 0, 8, 102, 0, 8, 38, 0, 9, 173, 0, 8, 6, 0, 8, 134, 0, 8, 70, 0, 9, 237, 80, 7, 9, 0, 8, 94, 0, 8, 30, 0, 9, 157, 84, 7, 99, 0, 8, 126, 0, 8, 62, 0, 9, 221, 82, 7, 27, 0, 8, 110, 0, 8, 46, 0, 9, 189, 0, 8, + 14, 0, 8, 142, 0, 8, 78, 0, 9, 253, 96, 7, 256, 0, 8, 81, 0, 8, 17, 85, 8, 131, 82, 7, 31, 0, 8, 113, 0, 8, 49, 0, 9, 195, 80, 7, 10, 0, 8, 97, 0, 8, 33, 0, 9, 163, 0, 8, 1, 0, 8, 129, 0, 8, 65, 0, 9, 227, 80, 7, 6, 0, 8, 89, 0, 8, 25, 0, 9, 147, 83, 7, 59, 0, 8, 121, 0, 8, 57, 0, 9, 211, 81, 7, 17, 0, 8, 105, 0, 8, 41, 0, 9, 179, 0, 8, 9, 0, 8, 137, 0, 8, 73, 0, 9, 243, 80, 7, 4, 0, 8, 85, 0, 8, 21, 80, 8, 258, 83, 7, 43, 0, 8, 117, 0, 8, 53, 0, 9, 203, 81, 7, 13, 0, 8, 101, 0, 8, 37, 0, 9, 171, 0, 8, 5, 0, 8, 133, 0, 8, 69, 0, 9, 235, 80, 7, 8, 0, 8, 93, 0, 8, 29, 0, 9, 155, 84, 7, 83, 0, 8, 125, 0, 8, 61, 0, 9, 219, 82, 7, 23, 0, 8, 109, 0, 8, 45, 0, 9, 187, 0, 8, 13, 0, 8, 141, 0, 8, 77, 0, 9, 251, 80, 7, 3, 0, 8, 83, 0, 8, 19, 85, 8, 195, 83, 7, 35, 0, 8, 115, 0, 8, 51, 0, 9, 199, 81, 7, 11, 0, 8, 99, 0, 8, 35, 0, 9, 167, 0, 8, 3, 0, 8, 131, 0, 8, 67, 0, 9, 231, 80, 7, 7, 0, 8, 91, 0, 8, 27, 0, 9, 151, 84, 7, 67, 0, 8, 123, 0, 8, 59, 0, 9, 215, 82, 7, 19, 0, 8, 107, 0, 8, 43, 0, 9, 183, 0, 8, 11, 0, 8, 139, 0, 8, 75, 0, 9, 247, 80, 7, 5, 0, 8, 87, 0, 8, 23, 192, 8, 0, 83, 7, 51, 0, 8, 119, 0, 8, 55, 0, 9, 207, 81, 7, 15, 0, 8, 103, 0, 8, 39, 0, 9, 175, 0, 8, 7, 0, 8, 135, 0, 8, 71, 0, 9, 239, 80, 7, 9, 0, 8, 95, 0, 8, 31, 0, 9, 159, 84, 7, 99, 0, 8, 127, 0, 8, 63, 0, 9, 223, 82, 7, 27, 0, 8, 111, 0, 8, 47, 0, 9, 191, 0, 8, 15, 0, 8, 143, 0, 8, 79, 0, 9, 255}; + //UPGRADE_NOTE: Final was removed from the declaration of 'fixed_td'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" + internal static readonly int[] fixed_td = new int[]{80, 5, 1, 87, 5, 257, 83, 5, 17, 91, 5, 4097, 81, 5, 5, 89, 5, 1025, 85, 5, 65, 93, 5, 16385, 80, 5, 3, 88, 5, 513, 84, 5, 33, 92, 5, 8193, 82, 5, 9, 90, 5, 2049, 86, 5, 129, 192, 5, 24577, 80, 5, 2, 87, 5, 385, 83, 5, 25, 91, 5, 6145, 81, 5, 7, 89, 5, 1537, 85, 5, 97, 93, 5, 24577, 80, 5, 4, 88, 5, 769, 84, 5, 49, 92, 5, 12289, 82, 5, 13, 90, 5, 3073, 86, 5, 193, 192, 5, 24577}; + + // Tables for deflate from PKZIP's appnote.txt. + //UPGRADE_NOTE: Final was removed from the declaration of 'cplens'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" + internal static readonly int[] cplens = new int[]{3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; + + // see note #13 above about 258 + //UPGRADE_NOTE: Final was removed from the declaration of 'cplext'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" + internal static readonly int[] cplext = new int[]{0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112}; + + //UPGRADE_NOTE: Final was removed from the declaration of 'cpdist'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" + internal static readonly int[] cpdist = new int[]{1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577}; + + //UPGRADE_NOTE: Final was removed from the declaration of 'cpdext'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" + internal static readonly int[] cpdext = new int[]{0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13}; + + // If BMAX needs to be larger than 16, then h and x[] should be uLong. + internal const int BMAX = 15; // maximum bit length of any code + + internal int[] hn = null; // hufts used in space + internal int[] v = null; // work area for huft_build + internal int[] c = null; // bit length count table + internal int[] r = null; // table entry for structure assignment + internal int[] u = null; // table stack + internal int[] x = null; // bit offsets, then code stack + + private int huft_build(int[] b, int bindex, int n, int s, int[] d, int[] e, int[] t, int[] m, int[] hp, int[] hn, int[] v) + { + // Given a list of code lengths and a maximum table size, make a set of + // tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR + // if the given code set is incomplete (the tables are still built in this + // case), Z_DATA_ERROR if the input is invalid (an over-subscribed set of + // lengths), or Z_MEM_ERROR if not enough memory. + + int a; // counter for codes of length k + int f; // i repeats in table every f entries + int g; // maximum code length + int h; // table level + int i; // counter, current code + int j; // counter + int k; // number of bits in current code + int l; // bits per table (returned in m) + int mask; // (1 << w) - 1, to avoid cc -O bug on HP + int p; // pointer into c[], b[], or v[] + int q; // points to current table + int w; // bits before this table == (l * h) + int xp; // pointer into x + int y; // number of dummy codes added + int z; // number of entries in current table + + // Generate counts for each bit length + + p = 0; i = n; + do + { + c[b[bindex + p]]++; p++; i--; // assume all entries <= BMAX + } + while (i != 0); + + if (c[0] == n) + { + // null input--all zero length codes + t[0] = - 1; + m[0] = 0; + return Z_OK; + } + + // Find minimum and maximum length, bound *m by those + l = m[0]; + for (j = 1; j <= BMAX; j++) + if (c[j] != 0) + break; + k = j; // minimum code length + if (l < j) + { + l = j; + } + for (i = BMAX; i != 0; i--) + { + if (c[i] != 0) + break; + } + g = i; // maximum code length + if (l > i) + { + l = i; + } + m[0] = l; + + // Adjust last length count to fill out codes, if needed + for (y = 1 << j; j < i; j++, y <<= 1) + { + if ((y -= c[j]) < 0) + { + return Z_DATA_ERROR; + } + } + if ((y -= c[i]) < 0) + { + return Z_DATA_ERROR; + } + c[i] += y; + + // Generate starting offsets into the value table for each length + x[1] = j = 0; + p = 1; xp = 2; + while (--i != 0) + { + // note that i == g from above + x[xp] = (j += c[p]); + xp++; + p++; + } + + // Make a table of values in order of bit lengths + i = 0; p = 0; + do + { + if ((j = b[bindex + p]) != 0) + { + v[x[j]++] = i; + } + p++; + } + while (++i < n); + n = x[g]; // set n to length of v + + // Generate the Huffman codes and for each, make the table entries + x[0] = i = 0; // first Huffman code is zero + p = 0; // grab values in bit order + h = - 1; // no tables yet--level -1 + w = - l; // bits decoded == (l * h) + u[0] = 0; // just to keep compilers happy + q = 0; // ditto + z = 0; // ditto + + // go through the bit lengths (k already is bits in shortest code) + for (; k <= g; k++) + { + a = c[k]; + while (a-- != 0) + { + // here i is the Huffman code of length k bits for value *p + // make tables up to required level + while (k > w + l) + { + h++; + w += l; // previous table always l bits + // compute minimum size table less than or equal to l bits + z = g - w; + z = (z > l)?l:z; // table size upper limit + if ((f = 1 << (j = k - w)) > a + 1) + { + // try a k-w bit table + // too few codes for k-w bit table + f -= (a + 1); // deduct codes from patterns left + xp = k; + if (j < z) + { + while (++j < z) + { + // try smaller tables up to z bits + if ((f <<= 1) <= c[++xp]) + break; // enough codes to use up j bits + f -= c[xp]; // else deduct codes from patterns + } + } + } + z = 1 << j; // table entries for j-bit table + + // allocate new table + if (hn[0] + z > MANY) + { + // (note: doesn't matter for fixed) + return Z_DATA_ERROR; // overflow of MANY + } + u[h] = q = hn[0]; // DEBUG + hn[0] += z; + + // connect to last table, if there is one + if (h != 0) + { + x[h] = i; // save pattern for backing up + r[0] = (sbyte) j; // bits in this table + r[1] = (sbyte) l; // bits to dump before this table + j = SharedUtils.URShift(i, (w - l)); + r[2] = (int) (q - u[h - 1] - j); // offset to this table + Array.Copy(r, 0, hp, (u[h - 1] + j) * 3, 3); // connect to last table + } + else + { + t[0] = q; // first table is returned result + } + } + + // set up table entry in r + r[1] = (sbyte) (k - w); + if (p >= n) + { + r[0] = 128 + 64; // out of values--invalid code + } + else if (v[p] < s) + { + r[0] = (sbyte) (v[p] < 256?0:32 + 64); // 256 is end-of-block + r[2] = v[p++]; // simple code is just the value + } + else + { + r[0] = (sbyte) (e[v[p] - s] + 16 + 64); // non-simple--look up in lists + r[2] = d[v[p++] - s]; + } + + // fill code-like entries with r + f = 1 << (k - w); + for (j = SharedUtils.URShift(i, w); j < z; j += f) + { + Array.Copy(r, 0, hp, (q + j) * 3, 3); + } + + // backwards increment the k-bit code i + for (j = 1 << (k - 1); (i & j) != 0; j = SharedUtils.URShift(j, 1)) + { + i ^= j; + } + i ^= j; + + // backup over finished tables + mask = (1 << w) - 1; // needed on HP, cc -O bug + while ((i & mask) != x[h]) + { + h--; // don't need to update q + w -= l; + mask = (1 << w) - 1; + } + } + } + // Return Z_BUF_ERROR if we were given an incomplete table + return y != 0 && g != 1?Z_BUF_ERROR:Z_OK; + } + + internal int inflate_trees_bits(int[] c, int[] bb, int[] tb, int[] hp, ZlibCodec z) + { + int result; + initWorkArea(19); + hn[0] = 0; + result = huft_build(c, 0, 19, 19, null, null, tb, bb, hp, hn, v); + + if (result == Z_DATA_ERROR) + { + z.Message = "oversubscribed dynamic bit lengths tree"; + } + else if (result == Z_BUF_ERROR || bb[0] == 0) + { + z.Message = "incomplete dynamic bit lengths tree"; + result = Z_DATA_ERROR; + } + return result; + } + + internal int inflate_trees_dynamic(int nl, int nd, int[] c, int[] bl, int[] bd, int[] tl, int[] td, int[] hp, ZlibCodec z) + { + int result; + + // build literal/length tree + initWorkArea(288); + hn[0] = 0; + result = huft_build(c, 0, nl, 257, cplens, cplext, tl, bl, hp, hn, v); + if (result != Z_OK || bl[0] == 0) + { + if (result == Z_DATA_ERROR) + { + z.Message = "oversubscribed literal/length tree"; + } + else if (result != Z_MEM_ERROR) + { + z.Message = "incomplete literal/length tree"; + result = Z_DATA_ERROR; + } + return result; + } + + // build distance tree + initWorkArea(288); + result = huft_build(c, nl, nd, 0, cpdist, cpdext, td, bd, hp, hn, v); + + if (result != Z_OK || (bd[0] == 0 && nl > 257)) + { + if (result == Z_DATA_ERROR) + { + z.Message = "oversubscribed distance tree"; + } + else if (result == Z_BUF_ERROR) + { + z.Message = "incomplete distance tree"; + result = Z_DATA_ERROR; + } + else if (result != Z_MEM_ERROR) + { + z.Message = "empty distance tree with lengths"; + result = Z_DATA_ERROR; + } + return result; + } + + return Z_OK; + } + + internal static int inflate_trees_fixed(int[] bl, int[] bd, int[][] tl, int[][] td, ZlibCodec z) + { + bl[0] = fixed_bl; + bd[0] = fixed_bd; + tl[0] = fixed_tl; + td[0] = fixed_td; + return Z_OK; + } + + private void initWorkArea(int vsize) + { + if (hn == null) + { + hn = new int[1]; + v = new int[vsize]; + c = new int[BMAX + 1]; + r = new int[3]; + u = new int[BMAX]; + x = new int[BMAX + 1]; + } + else + { + if (v.Length < vsize) + { + v = new int[vsize]; + } + Array.Clear(v,0,vsize); + Array.Clear(c,0,BMAX+1); + r[0]=0; r[1]=0; r[2]=0; + // for(int i=0; i +// +// ------------------------------------------------------------------ +// +// This module defines classes for decompression. This code is derived +// from the jzlib implementation of zlib, but significantly modified. +// The object model is not the same, and many of the behaviors are +// different. Nonetheless, in keeping with the license for jzlib, I am +// reproducing the copyright to that code here. +// +// ------------------------------------------------------------------ +// +// Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// 2. 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. +// +// 3. The names of the authors may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 JCRAFT, +// INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE 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. +// +// ----------------------------------------------------------------------- +// +// This program is based on zlib-1.1.3; credit to authors +// Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) +// and contributors of zlib. +// +// ----------------------------------------------------------------------- + + +using System; + +namespace ROMVault2.SupportedFiles.Zip.ZLib +{ + sealed class InflateBlocks + { + private const int MANY = 1440; + + // Table for deflate from PKZIP's appnote.txt. + internal static readonly int[] border = new int[] + { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 }; + + private enum InflateBlockMode + { + TYPE = 0, // get type bits (3, including end bit) + LENS = 1, // get lengths for stored + STORED = 2, // processing stored block + TABLE = 3, // get table lengths + BTREE = 4, // get bit lengths tree for a dynamic block + DTREE = 5, // get length, distance trees for a dynamic block + CODES = 6, // processing fixed or dynamic block + DRY = 7, // output remaining window bytes + DONE = 8, // finished last block, done + BAD = 9, // ot a data error--stuck here + } + + private InflateBlockMode mode; // current inflate_block mode + + internal int left; // if STORED, bytes left to copy + + internal int table; // table lengths (14 bits) + internal int index; // index into blens (or border) + internal int[] blens; // bit lengths of codes + internal int[] bb = new int[1]; // bit length tree depth + internal int[] tb = new int[1]; // bit length decoding tree + + internal InflateCodes codes = new InflateCodes(); // if CODES, current state + + internal int last; // true if this block is the last block + + internal ZlibCodec _codec; // pointer back to this zlib stream + + // mode independent information + internal int bitk; // bits in bit buffer + internal int bitb; // bit buffer + internal int[] hufts; // single malloc for tree space + internal byte[] window; // sliding window + internal int end; // one byte after sliding window + internal int readAt; // window read pointer + internal int writeAt; // window write pointer + internal System.Object checkfn; // check function + internal uint check; // check on output + + internal InfTree inftree = new InfTree(); + + internal InflateBlocks(ZlibCodec codec, System.Object checkfn, int w) + { + _codec = codec; + hufts = new int[MANY * 3]; + window = new byte[w]; + end = w; + this.checkfn = checkfn; + mode = InflateBlockMode.TYPE; + Reset(); + } + + internal uint Reset() + { + uint oldCheck = check; + mode = InflateBlockMode.TYPE; + bitk = 0; + bitb = 0; + readAt = writeAt = 0; + + if (checkfn != null) + _codec._Adler32 = check = Adler.Adler32(0, null, 0, 0); + return oldCheck; + } + + + internal int Process(int r) + { + int t; // temporary storage + int b; // bit buffer + int k; // bits in bit buffer + int p; // input data pointer + int n; // bytes available there + int q; // output window write pointer + int m; // bytes to end of window or read pointer + + // copy input/output information to locals (UPDATE macro restores) + + p = _codec.NextIn; + n = _codec.AvailableBytesIn; + b = bitb; + k = bitk; + + q = writeAt; + m = (int)(q < readAt ? readAt - q - 1 : end - q); + + + // process input based on current state + while (true) + { + switch (mode) + { + case InflateBlockMode.TYPE: + + while (k < (3)) + { + if (n != 0) + { + r = ZlibConstants.Z_OK; + } + else + { + bitb = b; bitk = k; + _codec.AvailableBytesIn = n; + _codec.TotalBytesIn += p - _codec.NextIn; + _codec.NextIn = p; + writeAt = q; + return Flush(r); + } + + n--; + b |= (_codec.InputBuffer[p++] & 0xff) << k; + k += 8; + } + t = (int)(b & 7); + last = t & 1; + + switch ((uint)t >> 1) + { + case 0: // stored + b >>= 3; k -= (3); + t = k & 7; // go to byte boundary + b >>= t; k -= t; + mode = InflateBlockMode.LENS; // get length of stored block + break; + + case 1: // fixed + int[] bl = new int[1]; + int[] bd = new int[1]; + int[][] tl = new int[1][]; + int[][] td = new int[1][]; + InfTree.inflate_trees_fixed(bl, bd, tl, td, _codec); + codes.Init(bl[0], bd[0], tl[0], 0, td[0], 0); + b >>= 3; k -= 3; + mode = InflateBlockMode.CODES; + break; + + case 2: // dynamic + b >>= 3; k -= 3; + mode = InflateBlockMode.TABLE; + break; + + case 3: // illegal + b >>= 3; k -= 3; + mode = InflateBlockMode.BAD; + _codec.Message = "invalid block type"; + r = ZlibConstants.Z_DATA_ERROR; + bitb = b; bitk = k; + _codec.AvailableBytesIn = n; + _codec.TotalBytesIn += p - _codec.NextIn; + _codec.NextIn = p; + writeAt = q; + return Flush(r); + } + break; + + case InflateBlockMode.LENS: + + while (k < (32)) + { + if (n != 0) + { + r = ZlibConstants.Z_OK; + } + else + { + bitb = b; bitk = k; + _codec.AvailableBytesIn = n; + _codec.TotalBytesIn += p - _codec.NextIn; + _codec.NextIn = p; + writeAt = q; + return Flush(r); + } + ; + n--; + b |= (_codec.InputBuffer[p++] & 0xff) << k; + k += 8; + } + + if ( ( ((~b)>>16) & 0xffff) != (b & 0xffff)) + { + mode = InflateBlockMode.BAD; + _codec.Message = "invalid stored block lengths"; + r = ZlibConstants.Z_DATA_ERROR; + + bitb = b; bitk = k; + _codec.AvailableBytesIn = n; + _codec.TotalBytesIn += p - _codec.NextIn; + _codec.NextIn = p; + writeAt = q; + return Flush(r); + } + left = (b & 0xffff); + b = k = 0; // dump bits + mode = left != 0 ? InflateBlockMode.STORED : (last != 0 ? InflateBlockMode.DRY : InflateBlockMode.TYPE); + break; + + case InflateBlockMode.STORED: + if (n == 0) + { + bitb = b; bitk = k; + _codec.AvailableBytesIn = n; + _codec.TotalBytesIn += p - _codec.NextIn; + _codec.NextIn = p; + writeAt = q; + return Flush(r); + } + + if (m == 0) + { + if (q == end && readAt != 0) + { + q = 0; m = (int)(q < readAt ? readAt - q - 1 : end - q); + } + if (m == 0) + { + writeAt = q; + r = Flush(r); + q = writeAt; m = (int)(q < readAt ? readAt - q - 1 : end - q); + if (q == end && readAt != 0) + { + q = 0; m = (int)(q < readAt ? readAt - q - 1 : end - q); + } + if (m == 0) + { + bitb = b; bitk = k; + _codec.AvailableBytesIn = n; + _codec.TotalBytesIn += p - _codec.NextIn; + _codec.NextIn = p; + writeAt = q; + return Flush(r); + } + } + } + r = ZlibConstants.Z_OK; + + t = left; + if (t > n) + t = n; + if (t > m) + t = m; + Array.Copy(_codec.InputBuffer, p, window, q, t); + p += t; n -= t; + q += t; m -= t; + if ((left -= t) != 0) + break; + mode = last != 0 ? InflateBlockMode.DRY : InflateBlockMode.TYPE; + break; + + case InflateBlockMode.TABLE: + + while (k < (14)) + { + if (n != 0) + { + r = ZlibConstants.Z_OK; + } + else + { + bitb = b; bitk = k; + _codec.AvailableBytesIn = n; + _codec.TotalBytesIn += p - _codec.NextIn; + _codec.NextIn = p; + writeAt = q; + return Flush(r); + } + + n--; + b |= (_codec.InputBuffer[p++] & 0xff) << k; + k += 8; + } + + table = t = (b & 0x3fff); + if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29) + { + mode = InflateBlockMode.BAD; + _codec.Message = "too many length or distance symbols"; + r = ZlibConstants.Z_DATA_ERROR; + + bitb = b; bitk = k; + _codec.AvailableBytesIn = n; + _codec.TotalBytesIn += p - _codec.NextIn; + _codec.NextIn = p; + writeAt = q; + return Flush(r); + } + t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f); + if (blens == null || blens.Length < t) + { + blens = new int[t]; + } + else + { + Array.Clear(blens, 0, t); + // for (int i = 0; i < t; i++) + // { + // blens[i] = 0; + // } + } + + b >>= 14; + k -= 14; + + + index = 0; + mode = InflateBlockMode.BTREE; + goto case InflateBlockMode.BTREE; + + case InflateBlockMode.BTREE: + while (index < 4 + (table >> 10)) + { + while (k < (3)) + { + if (n != 0) + { + r = ZlibConstants.Z_OK; + } + else + { + bitb = b; bitk = k; + _codec.AvailableBytesIn = n; + _codec.TotalBytesIn += p - _codec.NextIn; + _codec.NextIn = p; + writeAt = q; + return Flush(r); + } + + n--; + b |= (_codec.InputBuffer[p++] & 0xff) << k; + k += 8; + } + + blens[border[index++]] = b & 7; + + b >>= 3; k -= 3; + } + + while (index < 19) + { + blens[border[index++]] = 0; + } + + bb[0] = 7; + t = inftree.inflate_trees_bits(blens, bb, tb, hufts, _codec); + if (t != ZlibConstants.Z_OK) + { + r = t; + if (r == ZlibConstants.Z_DATA_ERROR) + { + blens = null; + mode = InflateBlockMode.BAD; + } + + bitb = b; bitk = k; + _codec.AvailableBytesIn = n; + _codec.TotalBytesIn += p - _codec.NextIn; + _codec.NextIn = p; + writeAt = q; + return Flush(r); + } + + index = 0; + mode = InflateBlockMode.DTREE; + goto case InflateBlockMode.DTREE; + + case InflateBlockMode.DTREE: + while (true) + { + t = table; + if (!(index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))) + { + break; + } + + int i, j, c; + + t = bb[0]; + + while (k < t) + { + if (n != 0) + { + r = ZlibConstants.Z_OK; + } + else + { + bitb = b; bitk = k; + _codec.AvailableBytesIn = n; + _codec.TotalBytesIn += p - _codec.NextIn; + _codec.NextIn = p; + writeAt = q; + return Flush(r); + } + + n--; + b |= (_codec.InputBuffer[p++] & 0xff) << k; + k += 8; + } + + t = hufts[(tb[0] + (b & InternalInflateConstants.InflateMask[t])) * 3 + 1]; + c = hufts[(tb[0] + (b & InternalInflateConstants.InflateMask[t])) * 3 + 2]; + + if (c < 16) + { + b >>= t; k -= t; + blens[index++] = c; + } + else + { + // c == 16..18 + i = c == 18 ? 7 : c - 14; + j = c == 18 ? 11 : 3; + + while (k < (t + i)) + { + if (n != 0) + { + r = ZlibConstants.Z_OK; + } + else + { + bitb = b; bitk = k; + _codec.AvailableBytesIn = n; + _codec.TotalBytesIn += p - _codec.NextIn; + _codec.NextIn = p; + writeAt = q; + return Flush(r); + } + + n--; + b |= (_codec.InputBuffer[p++] & 0xff) << k; + k += 8; + } + + b >>= t; k -= t; + + j += (b & InternalInflateConstants.InflateMask[i]); + + b >>= i; k -= i; + + i = index; + t = table; + if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || (c == 16 && i < 1)) + { + blens = null; + mode = InflateBlockMode.BAD; + _codec.Message = "invalid bit length repeat"; + r = ZlibConstants.Z_DATA_ERROR; + + bitb = b; bitk = k; + _codec.AvailableBytesIn = n; + _codec.TotalBytesIn += p - _codec.NextIn; + _codec.NextIn = p; + writeAt = q; + return Flush(r); + } + + c = (c == 16) ? blens[i-1] : 0; + do + { + blens[i++] = c; + } + while (--j != 0); + index = i; + } + } + + tb[0] = -1; + { + int[] bl = new int[] { 9 }; // must be <= 9 for lookahead assumptions + int[] bd = new int[] { 6 }; // must be <= 9 for lookahead assumptions + int[] tl = new int[1]; + int[] td = new int[1]; + + t = table; + t = inftree.inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f), blens, bl, bd, tl, td, hufts, _codec); + + if (t != ZlibConstants.Z_OK) + { + if (t == ZlibConstants.Z_DATA_ERROR) + { + blens = null; + mode = InflateBlockMode.BAD; + } + r = t; + + bitb = b; bitk = k; + _codec.AvailableBytesIn = n; + _codec.TotalBytesIn += p - _codec.NextIn; + _codec.NextIn = p; + writeAt = q; + return Flush(r); + } + codes.Init(bl[0], bd[0], hufts, tl[0], hufts, td[0]); + } + mode = InflateBlockMode.CODES; + goto case InflateBlockMode.CODES; + + case InflateBlockMode.CODES: + bitb = b; bitk = k; + _codec.AvailableBytesIn = n; + _codec.TotalBytesIn += p - _codec.NextIn; + _codec.NextIn = p; + writeAt = q; + + r = codes.Process(this, r); + if (r != ZlibConstants.Z_STREAM_END) + { + return Flush(r); + } + + r = ZlibConstants.Z_OK; + p = _codec.NextIn; + n = _codec.AvailableBytesIn; + b = bitb; + k = bitk; + q = writeAt; + m = (int)(q < readAt ? readAt - q - 1 : end - q); + + if (last == 0) + { + mode = InflateBlockMode.TYPE; + break; + } + mode = InflateBlockMode.DRY; + goto case InflateBlockMode.DRY; + + case InflateBlockMode.DRY: + writeAt = q; + r = Flush(r); + q = writeAt; m = (int)(q < readAt ? readAt - q - 1 : end - q); + if (readAt != writeAt) + { + bitb = b; bitk = k; + _codec.AvailableBytesIn = n; + _codec.TotalBytesIn += p - _codec.NextIn; + _codec.NextIn = p; + writeAt = q; + return Flush(r); + } + mode = InflateBlockMode.DONE; + goto case InflateBlockMode.DONE; + + case InflateBlockMode.DONE: + r = ZlibConstants.Z_STREAM_END; + bitb = b; + bitk = k; + _codec.AvailableBytesIn = n; + _codec.TotalBytesIn += p - _codec.NextIn; + _codec.NextIn = p; + writeAt = q; + return Flush(r); + + case InflateBlockMode.BAD: + r = ZlibConstants.Z_DATA_ERROR; + + bitb = b; bitk = k; + _codec.AvailableBytesIn = n; + _codec.TotalBytesIn += p - _codec.NextIn; + _codec.NextIn = p; + writeAt = q; + return Flush(r); + + + default: + r = ZlibConstants.Z_STREAM_ERROR; + + bitb = b; bitk = k; + _codec.AvailableBytesIn = n; + _codec.TotalBytesIn += p - _codec.NextIn; + _codec.NextIn = p; + writeAt = q; + return Flush(r); + } + } + } + + + internal void Free() + { + Reset(); + window = null; + hufts = null; + } + + internal void SetDictionary(byte[] d, int start, int n) + { + Array.Copy(d, start, window, 0, n); + readAt = writeAt = n; + } + + // Returns true if inflate is currently at the end of a block generated + // by Z_SYNC_FLUSH or Z_FULL_FLUSH. + internal int SyncPoint() + { + return mode == InflateBlockMode.LENS ? 1 : 0; + } + + // copy as much as possible from the sliding window to the output area + internal int Flush(int r) + { + int nBytes; + + for (int pass=0; pass < 2; pass++) + { + if (pass==0) + { + // compute number of bytes to copy as far as end of window + nBytes = (int)((readAt <= writeAt ? writeAt : end) - readAt); + } + else + { + // compute bytes to copy + nBytes = writeAt - readAt; + } + + // workitem 8870 + if (nBytes == 0) + { + if (r == ZlibConstants.Z_BUF_ERROR) + r = ZlibConstants.Z_OK; + return r; + } + + if (nBytes > _codec.AvailableBytesOut) + nBytes = _codec.AvailableBytesOut; + + if (nBytes != 0 && r == ZlibConstants.Z_BUF_ERROR) + r = ZlibConstants.Z_OK; + + // update counters + _codec.AvailableBytesOut -= nBytes; + _codec.TotalBytesOut += nBytes; + + // update check information + if (checkfn != null) + _codec._Adler32 = check = Adler.Adler32(check, window, readAt, nBytes); + + // copy as far as end of window + Array.Copy(window, readAt, _codec.OutputBuffer, _codec.NextOut, nBytes); + _codec.NextOut += nBytes; + readAt += nBytes; + + // see if more to copy at beginning of window + if (readAt == end && pass == 0) + { + // wrap pointers + readAt = 0; + if (writeAt == end) + writeAt = 0; + } + else pass++; + } + + // done + return r; + } + } + + + internal static class InternalInflateConstants + { + // And'ing with mask[n] masks the lower n bits + internal static readonly int[] InflateMask = new int[] { + 0x00000000, 0x00000001, 0x00000003, 0x00000007, + 0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f, + 0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff, + 0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff }; + } + + + sealed class InflateCodes + { + // waiting for "i:"=input, + // "o:"=output, + // "x:"=nothing + private const int START = 0; // x: set up for LEN + private const int LEN = 1; // i: get length/literal/eob next + private const int LENEXT = 2; // i: getting length extra (have base) + private const int DIST = 3; // i: get distance next + private const int DISTEXT = 4; // i: getting distance extra + private const int COPY = 5; // o: copying bytes in window, waiting for space + private const int LIT = 6; // o: got literal, waiting for output space + private const int WASH = 7; // o: got eob, possibly still output waiting + private const int END = 8; // x: got eob and all data flushed + private const int BADCODE = 9; // x: got error + + internal int mode; // current inflate_codes mode + + // mode dependent information + internal int len; + + internal int[] tree; // pointer into tree + internal int tree_index = 0; + internal int need; // bits needed + + internal int lit; + + // if EXT or COPY, where and how much + internal int bitsToGet; // bits to get for extra + internal int dist; // distance back to copy from + + internal byte lbits; // ltree bits decoded per branch + internal byte dbits; // dtree bits decoder per branch + internal int[] ltree; // literal/length/eob tree + internal int ltree_index; // literal/length/eob tree + internal int[] dtree; // distance tree + internal int dtree_index; // distance tree + + internal InflateCodes() + { + } + + internal void Init(int bl, int bd, int[] tl, int tl_index, int[] td, int td_index) + { + mode = START; + lbits = (byte)bl; + dbits = (byte)bd; + ltree = tl; + ltree_index = tl_index; + dtree = td; + dtree_index = td_index; + tree = null; + } + + internal int Process(InflateBlocks blocks, int r) + { + int j; // temporary storage + int tindex; // temporary pointer + int e; // extra bits or operation + int b = 0; // bit buffer + int k = 0; // bits in bit buffer + int p = 0; // input data pointer + int n; // bytes available there + int q; // output window write pointer + int m; // bytes to end of window or read pointer + int f; // pointer to copy strings from + + ZlibCodec z = blocks._codec; + + // copy input/output information to locals (UPDATE macro restores) + p = z.NextIn; + n = z.AvailableBytesIn; + b = blocks.bitb; + k = blocks.bitk; + q = blocks.writeAt; m = q < blocks.readAt ? blocks.readAt - q - 1 : blocks.end - q; + + // process input and output based on current state + while (true) + { + switch (mode) + { + // waiting for "i:"=input, "o:"=output, "x:"=nothing + case START: // x: set up for LEN + if (m >= 258 && n >= 10) + { + blocks.bitb = b; blocks.bitk = k; + z.AvailableBytesIn = n; + z.TotalBytesIn += p - z.NextIn; + z.NextIn = p; + blocks.writeAt = q; + r = InflateFast(lbits, dbits, ltree, ltree_index, dtree, dtree_index, blocks, z); + + p = z.NextIn; + n = z.AvailableBytesIn; + b = blocks.bitb; + k = blocks.bitk; + q = blocks.writeAt; m = q < blocks.readAt ? blocks.readAt - q - 1 : blocks.end - q; + + if (r != ZlibConstants.Z_OK) + { + mode = (r == ZlibConstants.Z_STREAM_END) ? WASH : BADCODE; + break; + } + } + need = lbits; + tree = ltree; + tree_index = ltree_index; + + mode = LEN; + goto case LEN; + + case LEN: // i: get length/literal/eob next + j = need; + + while (k < j) + { + if (n != 0) + r = ZlibConstants.Z_OK; + else + { + blocks.bitb = b; blocks.bitk = k; + z.AvailableBytesIn = n; + z.TotalBytesIn += p - z.NextIn; + z.NextIn = p; + blocks.writeAt = q; + return blocks.Flush(r); + } + n--; + b |= (z.InputBuffer[p++] & 0xff) << k; + k += 8; + } + + tindex = (tree_index + (b & InternalInflateConstants.InflateMask[j])) * 3; + + b >>= (tree[tindex + 1]); + k -= (tree[tindex + 1]); + + e = tree[tindex]; + + if (e == 0) + { + // literal + lit = tree[tindex + 2]; + mode = LIT; + break; + } + if ((e & 16) != 0) + { + // length + bitsToGet = e & 15; + len = tree[tindex + 2]; + mode = LENEXT; + break; + } + if ((e & 64) == 0) + { + // next table + need = e; + tree_index = tindex / 3 + tree[tindex + 2]; + break; + } + if ((e & 32) != 0) + { + // end of block + mode = WASH; + break; + } + mode = BADCODE; // invalid code + z.Message = "invalid literal/length code"; + r = ZlibConstants.Z_DATA_ERROR; + + blocks.bitb = b; blocks.bitk = k; + z.AvailableBytesIn = n; + z.TotalBytesIn += p - z.NextIn; + z.NextIn = p; + blocks.writeAt = q; + return blocks.Flush(r); + + + case LENEXT: // i: getting length extra (have base) + j = bitsToGet; + + while (k < j) + { + if (n != 0) + r = ZlibConstants.Z_OK; + else + { + blocks.bitb = b; blocks.bitk = k; + z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p; + blocks.writeAt = q; + return blocks.Flush(r); + } + n--; b |= (z.InputBuffer[p++] & 0xff) << k; + k += 8; + } + + len += (b & InternalInflateConstants.InflateMask[j]); + + b >>= j; + k -= j; + + need = dbits; + tree = dtree; + tree_index = dtree_index; + mode = DIST; + goto case DIST; + + case DIST: // i: get distance next + j = need; + + while (k < j) + { + if (n != 0) + r = ZlibConstants.Z_OK; + else + { + blocks.bitb = b; blocks.bitk = k; + z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p; + blocks.writeAt = q; + return blocks.Flush(r); + } + n--; b |= (z.InputBuffer[p++] & 0xff) << k; + k += 8; + } + + tindex = (tree_index + (b & InternalInflateConstants.InflateMask[j])) * 3; + + b >>= tree[tindex + 1]; + k -= tree[tindex + 1]; + + e = (tree[tindex]); + if ((e & 0x10) != 0) + { + // distance + bitsToGet = e & 15; + dist = tree[tindex + 2]; + mode = DISTEXT; + break; + } + if ((e & 64) == 0) + { + // next table + need = e; + tree_index = tindex / 3 + tree[tindex + 2]; + break; + } + mode = BADCODE; // invalid code + z.Message = "invalid distance code"; + r = ZlibConstants.Z_DATA_ERROR; + + blocks.bitb = b; blocks.bitk = k; + z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p; + blocks.writeAt = q; + return blocks.Flush(r); + + + case DISTEXT: // i: getting distance extra + j = bitsToGet; + + while (k < j) + { + if (n != 0) + r = ZlibConstants.Z_OK; + else + { + blocks.bitb = b; blocks.bitk = k; + z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p; + blocks.writeAt = q; + return blocks.Flush(r); + } + n--; b |= (z.InputBuffer[p++] & 0xff) << k; + k += 8; + } + + dist += (b & InternalInflateConstants.InflateMask[j]); + + b >>= j; + k -= j; + + mode = COPY; + goto case COPY; + + case COPY: // o: copying bytes in window, waiting for space + f = q - dist; + while (f < 0) + { + // modulo window size-"while" instead + f += blocks.end; // of "if" handles invalid distances + } + while (len != 0) + { + if (m == 0) + { + if (q == blocks.end && blocks.readAt != 0) + { + q = 0; m = q < blocks.readAt ? blocks.readAt - q - 1 : blocks.end - q; + } + if (m == 0) + { + blocks.writeAt = q; r = blocks.Flush(r); + q = blocks.writeAt; m = q < blocks.readAt ? blocks.readAt - q - 1 : blocks.end - q; + + if (q == blocks.end && blocks.readAt != 0) + { + q = 0; m = q < blocks.readAt ? blocks.readAt - q - 1 : blocks.end - q; + } + + if (m == 0) + { + blocks.bitb = b; blocks.bitk = k; + z.AvailableBytesIn = n; + z.TotalBytesIn += p - z.NextIn; + z.NextIn = p; + blocks.writeAt = q; + return blocks.Flush(r); + } + } + } + + blocks.window[q++] = blocks.window[f++]; m--; + + if (f == blocks.end) + f = 0; + len--; + } + mode = START; + break; + + case LIT: // o: got literal, waiting for output space + if (m == 0) + { + if (q == blocks.end && blocks.readAt != 0) + { + q = 0; m = q < blocks.readAt ? blocks.readAt - q - 1 : blocks.end - q; + } + if (m == 0) + { + blocks.writeAt = q; r = blocks.Flush(r); + q = blocks.writeAt; m = q < blocks.readAt ? blocks.readAt - q - 1 : blocks.end - q; + + if (q == blocks.end && blocks.readAt != 0) + { + q = 0; m = q < blocks.readAt ? blocks.readAt - q - 1 : blocks.end - q; + } + if (m == 0) + { + blocks.bitb = b; blocks.bitk = k; + z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p; + blocks.writeAt = q; + return blocks.Flush(r); + } + } + } + r = ZlibConstants.Z_OK; + + blocks.window[q++] = (byte)lit; m--; + + mode = START; + break; + + case WASH: // o: got eob, possibly more output + if (k > 7) + { + // return unused byte, if any + k -= 8; + n++; + p--; // can always return one + } + + blocks.writeAt = q; r = blocks.Flush(r); + q = blocks.writeAt; m = q < blocks.readAt ? blocks.readAt - q - 1 : blocks.end - q; + + if (blocks.readAt != blocks.writeAt) + { + blocks.bitb = b; blocks.bitk = k; + z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p; + blocks.writeAt = q; + return blocks.Flush(r); + } + mode = END; + goto case END; + + case END: + r = ZlibConstants.Z_STREAM_END; + blocks.bitb = b; blocks.bitk = k; + z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p; + blocks.writeAt = q; + return blocks.Flush(r); + + case BADCODE: // x: got error + + r = ZlibConstants.Z_DATA_ERROR; + + blocks.bitb = b; blocks.bitk = k; + z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p; + blocks.writeAt = q; + return blocks.Flush(r); + + default: + r = ZlibConstants.Z_STREAM_ERROR; + + blocks.bitb = b; blocks.bitk = k; + z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p; + blocks.writeAt = q; + return blocks.Flush(r); + } + } + } + + + // Called with number of bytes left to write in window at least 258 + // (the maximum string length) and number of input bytes available + // at least ten. The ten bytes are six bytes for the longest length/ + // distance pair plus four bytes for overloading the bit buffer. + + internal int InflateFast(int bl, int bd, int[] tl, int tl_index, int[] td, int td_index, InflateBlocks s, ZlibCodec z) + { + int t; // temporary pointer + int[] tp; // temporary pointer + int tp_index; // temporary pointer + int e; // extra bits or operation + int b; // bit buffer + int k; // bits in bit buffer + int p; // input data pointer + int n; // bytes available there + int q; // output window write pointer + int m; // bytes to end of window or read pointer + int ml; // mask for literal/length tree + int md; // mask for distance tree + int c; // bytes to copy + int d; // distance back to copy from + int r; // copy source pointer + + int tp_index_t_3; // (tp_index+t)*3 + + // load input, output, bit values + p = z.NextIn; n = z.AvailableBytesIn; b = s.bitb; k = s.bitk; + q = s.writeAt; m = q < s.readAt ? s.readAt - q - 1 : s.end - q; + + // initialize masks + ml = InternalInflateConstants.InflateMask[bl]; + md = InternalInflateConstants.InflateMask[bd]; + + // do until not enough input or output space for fast loop + do + { + // assume called with m >= 258 && n >= 10 + // get literal/length code + while (k < (20)) + { + // max bits for literal/length code + n--; + b |= (z.InputBuffer[p++] & 0xff) << k; k += 8; + } + + t = b & ml; + tp = tl; + tp_index = tl_index; + tp_index_t_3 = (tp_index + t) * 3; + if ((e = tp[tp_index_t_3]) == 0) + { + b >>= (tp[tp_index_t_3 + 1]); k -= (tp[tp_index_t_3 + 1]); + + s.window[q++] = (byte)tp[tp_index_t_3 + 2]; + m--; + continue; + } + do + { + + b >>= (tp[tp_index_t_3 + 1]); k -= (tp[tp_index_t_3 + 1]); + + if ((e & 16) != 0) + { + e &= 15; + c = tp[tp_index_t_3 + 2] + ((int)b & InternalInflateConstants.InflateMask[e]); + + b >>= e; k -= e; + + // decode distance base of block to copy + while (k < 15) + { + // max bits for distance code + n--; + b |= (z.InputBuffer[p++] & 0xff) << k; k += 8; + } + + t = b & md; + tp = td; + tp_index = td_index; + tp_index_t_3 = (tp_index + t) * 3; + e = tp[tp_index_t_3]; + + do + { + + b >>= (tp[tp_index_t_3 + 1]); k -= (tp[tp_index_t_3 + 1]); + + if ((e & 16) != 0) + { + // get extra bits to add to distance base + e &= 15; + while (k < e) + { + // get extra bits (up to 13) + n--; + b |= (z.InputBuffer[p++] & 0xff) << k; k += 8; + } + + d = tp[tp_index_t_3 + 2] + (b & InternalInflateConstants.InflateMask[e]); + + b >>= e; k -= e; + + // do the copy + m -= c; + if (q >= d) + { + // offset before dest + // just copy + r = q - d; + if (q - r > 0 && 2 > (q - r)) + { + s.window[q++] = s.window[r++]; // minimum count is three, + s.window[q++] = s.window[r++]; // so unroll loop a little + c -= 2; + } + else + { + Array.Copy(s.window, r, s.window, q, 2); + q += 2; r += 2; c -= 2; + } + } + else + { + // else offset after destination + r = q - d; + do + { + r += s.end; // force pointer in window + } + while (r < 0); // covers invalid distances + e = s.end - r; + if (c > e) + { + // if source crosses, + c -= e; // wrapped copy + if (q - r > 0 && e > (q - r)) + { + do + { + s.window[q++] = s.window[r++]; + } + while (--e != 0); + } + else + { + Array.Copy(s.window, r, s.window, q, e); + q += e; r += e; e = 0; + } + r = 0; // copy rest from start of window + } + } + + // copy all or what's left + if (q - r > 0 && c > (q - r)) + { + do + { + s.window[q++] = s.window[r++]; + } + while (--c != 0); + } + else + { + Array.Copy(s.window, r, s.window, q, c); + q += c; r += c; c = 0; + } + break; + } + else if ((e & 64) == 0) + { + t += tp[tp_index_t_3 + 2]; + t += (b & InternalInflateConstants.InflateMask[e]); + tp_index_t_3 = (tp_index + t) * 3; + e = tp[tp_index_t_3]; + } + else + { + z.Message = "invalid distance code"; + + c = z.AvailableBytesIn - n; c = (k >> 3) < c ? k >> 3 : c; n += c; p -= c; k -= (c << 3); + + s.bitb = b; s.bitk = k; + z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p; + s.writeAt = q; + + return ZlibConstants.Z_DATA_ERROR; + } + } + while (true); + break; + } + + if ((e & 64) == 0) + { + t += tp[tp_index_t_3 + 2]; + t += (b & InternalInflateConstants.InflateMask[e]); + tp_index_t_3 = (tp_index + t) * 3; + if ((e = tp[tp_index_t_3]) == 0) + { + b >>= (tp[tp_index_t_3 + 1]); k -= (tp[tp_index_t_3 + 1]); + s.window[q++] = (byte)tp[tp_index_t_3 + 2]; + m--; + break; + } + } + else if ((e & 32) != 0) + { + c = z.AvailableBytesIn - n; c = (k >> 3) < c ? k >> 3 : c; n += c; p -= c; k -= (c << 3); + + s.bitb = b; s.bitk = k; + z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p; + s.writeAt = q; + + return ZlibConstants.Z_STREAM_END; + } + else + { + z.Message = "invalid literal/length code"; + + c = z.AvailableBytesIn - n; c = (k >> 3) < c ? k >> 3 : c; n += c; p -= c; k -= (c << 3); + + s.bitb = b; s.bitk = k; + z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p; + s.writeAt = q; + + return ZlibConstants.Z_DATA_ERROR; + } + } + while (true); + } + while (m >= 258 && n >= 10); + + // not enough input or output--restore pointers and return + c = z.AvailableBytesIn - n; c = (k >> 3) < c ? k >> 3 : c; n += c; p -= c; k -= (c << 3); + + s.bitb = b; s.bitk = k; + z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p; + s.writeAt = q; + + return ZlibConstants.Z_OK; + } + } + + + internal sealed class InflateManager + { + // preset dictionary flag in zlib header + private const int PRESET_DICT = 0x20; + + private const int Z_DEFLATED = 8; + + private enum InflateManagerMode + { + METHOD = 0, // waiting for method byte + FLAG = 1, // waiting for flag byte + DICT4 = 2, // four dictionary check bytes to go + DICT3 = 3, // three dictionary check bytes to go + DICT2 = 4, // two dictionary check bytes to go + DICT1 = 5, // one dictionary check byte to go + DICT0 = 6, // waiting for inflateSetDictionary + BLOCKS = 7, // decompressing blocks + CHECK4 = 8, // four check bytes to go + CHECK3 = 9, // three check bytes to go + CHECK2 = 10, // two check bytes to go + CHECK1 = 11, // one check byte to go + DONE = 12, // finished check, done + BAD = 13, // got an error--stay here + } + + private InflateManagerMode mode; // current inflate mode + internal ZlibCodec _codec; // pointer back to this zlib stream + + // mode dependent information + internal int method; // if FLAGS, method byte + + // if CHECK, check values to compare + internal uint computedCheck; // computed check value + internal uint expectedCheck; // stream check value + + // if BAD, inflateSync's marker bytes count + internal int marker; + + // mode independent information + //internal int nowrap; // flag for no wrapper + private bool _handleRfc1950HeaderBytes = true; + internal bool HandleRfc1950HeaderBytes + { + get { return _handleRfc1950HeaderBytes; } + set { _handleRfc1950HeaderBytes = value; } + } + internal int wbits; // log2(window size) (8..15, defaults to 15) + + internal InflateBlocks blocks; // current inflate_blocks state + + public InflateManager() { } + + public InflateManager(bool expectRfc1950HeaderBytes) + { + _handleRfc1950HeaderBytes = expectRfc1950HeaderBytes; + } + + internal int Reset() + { + _codec.TotalBytesIn = _codec.TotalBytesOut = 0; + _codec.Message = null; + mode = HandleRfc1950HeaderBytes ? InflateManagerMode.METHOD : InflateManagerMode.BLOCKS; + blocks.Reset(); + return ZlibConstants.Z_OK; + } + + internal int End() + { + if (blocks != null) + blocks.Free(); + blocks = null; + return ZlibConstants.Z_OK; + } + + internal int Initialize(ZlibCodec codec, int w) + { + _codec = codec; + _codec.Message = null; + blocks = null; + + // handle undocumented nowrap option (no zlib header or check) + //nowrap = 0; + //if (w < 0) + //{ + // w = - w; + // nowrap = 1; + //} + + // set window size + if (w < 8 || w > 15) + { + End(); + throw new ZlibException("Bad window size."); + + //return ZlibConstants.Z_STREAM_ERROR; + } + wbits = w; + + blocks = new InflateBlocks(codec, + HandleRfc1950HeaderBytes ? this : null, + 1 << w); + + // reset state + Reset(); + return ZlibConstants.Z_OK; + } + + + internal int Inflate(FlushType flush) + { + int b; + + if (_codec.InputBuffer == null) + throw new ZlibException("InputBuffer is null. "); + +// int f = (flush == FlushType.Finish) +// ? ZlibConstants.Z_BUF_ERROR +// : ZlibConstants.Z_OK; + + // workitem 8870 + int f = ZlibConstants.Z_OK; + int r = ZlibConstants.Z_BUF_ERROR; + + while (true) + { + switch (mode) + { + case InflateManagerMode.METHOD: + if (_codec.AvailableBytesIn == 0) return r; + r = f; + _codec.AvailableBytesIn--; + _codec.TotalBytesIn++; + if (((method = _codec.InputBuffer[_codec.NextIn++]) & 0xf) != Z_DEFLATED) + { + mode = InflateManagerMode.BAD; + _codec.Message = String.Format("unknown compression method (0x{0:X2})", method); + marker = 5; // can't try inflateSync + break; + } + if ((method >> 4) + 8 > wbits) + { + mode = InflateManagerMode.BAD; + _codec.Message = String.Format("invalid window size ({0})", (method >> 4) + 8); + marker = 5; // can't try inflateSync + break; + } + mode = InflateManagerMode.FLAG; + break; + + + case InflateManagerMode.FLAG: + if (_codec.AvailableBytesIn == 0) return r; + r = f; + _codec.AvailableBytesIn--; + _codec.TotalBytesIn++; + b = (_codec.InputBuffer[_codec.NextIn++]) & 0xff; + + if ((((method << 8) + b) % 31) != 0) + { + mode = InflateManagerMode.BAD; + _codec.Message = "incorrect header check"; + marker = 5; // can't try inflateSync + break; + } + + mode = ((b & PRESET_DICT) == 0) + ? InflateManagerMode.BLOCKS + : InflateManagerMode.DICT4; + break; + + case InflateManagerMode.DICT4: + if (_codec.AvailableBytesIn == 0) return r; + r = f; + _codec.AvailableBytesIn--; + _codec.TotalBytesIn++; + expectedCheck = (uint)((_codec.InputBuffer[_codec.NextIn++] << 24) & 0xff000000); + mode = InflateManagerMode.DICT3; + break; + + case InflateManagerMode.DICT3: + if (_codec.AvailableBytesIn == 0) return r; + r = f; + _codec.AvailableBytesIn--; + _codec.TotalBytesIn++; + expectedCheck += (uint)((_codec.InputBuffer[_codec.NextIn++] << 16) & 0x00ff0000); + mode = InflateManagerMode.DICT2; + break; + + case InflateManagerMode.DICT2: + + if (_codec.AvailableBytesIn == 0) return r; + r = f; + _codec.AvailableBytesIn--; + _codec.TotalBytesIn++; + expectedCheck += (uint)((_codec.InputBuffer[_codec.NextIn++] << 8) & 0x0000ff00); + mode = InflateManagerMode.DICT1; + break; + + + case InflateManagerMode.DICT1: + if (_codec.AvailableBytesIn == 0) return r; + r = f; + _codec.AvailableBytesIn--; _codec.TotalBytesIn++; + expectedCheck += (uint)(_codec.InputBuffer[_codec.NextIn++] & 0x000000ff); + _codec._Adler32 = expectedCheck; + mode = InflateManagerMode.DICT0; + return ZlibConstants.Z_NEED_DICT; + + + case InflateManagerMode.DICT0: + mode = InflateManagerMode.BAD; + _codec.Message = "need dictionary"; + marker = 0; // can try inflateSync + return ZlibConstants.Z_STREAM_ERROR; + + + case InflateManagerMode.BLOCKS: + r = blocks.Process(r); + if (r == ZlibConstants.Z_DATA_ERROR) + { + mode = InflateManagerMode.BAD; + marker = 0; // can try inflateSync + break; + } + + if (r == ZlibConstants.Z_OK) r = f; + + if (r != ZlibConstants.Z_STREAM_END) + return r; + + r = f; + computedCheck = blocks.Reset(); + if (!HandleRfc1950HeaderBytes) + { + mode = InflateManagerMode.DONE; + return ZlibConstants.Z_STREAM_END; + } + mode = InflateManagerMode.CHECK4; + break; + + case InflateManagerMode.CHECK4: + if (_codec.AvailableBytesIn == 0) return r; + r = f; + _codec.AvailableBytesIn--; + _codec.TotalBytesIn++; + expectedCheck = (uint)((_codec.InputBuffer[_codec.NextIn++] << 24) & 0xff000000); + mode = InflateManagerMode.CHECK3; + break; + + case InflateManagerMode.CHECK3: + if (_codec.AvailableBytesIn == 0) return r; + r = f; + _codec.AvailableBytesIn--; _codec.TotalBytesIn++; + expectedCheck += (uint)((_codec.InputBuffer[_codec.NextIn++] << 16) & 0x00ff0000); + mode = InflateManagerMode.CHECK2; + break; + + case InflateManagerMode.CHECK2: + if (_codec.AvailableBytesIn == 0) return r; + r = f; + _codec.AvailableBytesIn--; + _codec.TotalBytesIn++; + expectedCheck += (uint)((_codec.InputBuffer[_codec.NextIn++] << 8) & 0x0000ff00); + mode = InflateManagerMode.CHECK1; + break; + + case InflateManagerMode.CHECK1: + if (_codec.AvailableBytesIn == 0) return r; + r = f; + _codec.AvailableBytesIn--; _codec.TotalBytesIn++; + expectedCheck += (uint)(_codec.InputBuffer[_codec.NextIn++] & 0x000000ff); + if (computedCheck != expectedCheck) + { + mode = InflateManagerMode.BAD; + _codec.Message = "incorrect data check"; + marker = 5; // can't try inflateSync + break; + } + mode = InflateManagerMode.DONE; + return ZlibConstants.Z_STREAM_END; + + case InflateManagerMode.DONE: + return ZlibConstants.Z_STREAM_END; + + case InflateManagerMode.BAD: + throw new ZlibException(String.Format("Bad state ({0})", _codec.Message)); + + default: + throw new ZlibException("Stream error."); + + } + } + } + + + + internal int SetDictionary(byte[] dictionary) + { + int index = 0; + int length = dictionary.Length; + if (mode != InflateManagerMode.DICT0) + throw new ZlibException("Stream error."); + + if (Adler.Adler32(1, dictionary, 0, dictionary.Length) != _codec._Adler32) + { + return ZlibConstants.Z_DATA_ERROR; + } + + _codec._Adler32 = Adler.Adler32(0, null, 0, 0); + + if (length >= (1 << wbits)) + { + length = (1 << wbits) - 1; + index = dictionary.Length - length; + } + blocks.SetDictionary(dictionary, index, length); + mode = InflateManagerMode.BLOCKS; + return ZlibConstants.Z_OK; + } + + + private static readonly byte[] mark = new byte[] { 0, 0, 0xff, 0xff }; + + internal int Sync() + { + int n; // number of bytes to look at + int p; // pointer to bytes + int m; // number of marker bytes found in a row + long r, w; // temporaries to save total_in and total_out + + // set up + if (mode != InflateManagerMode.BAD) + { + mode = InflateManagerMode.BAD; + marker = 0; + } + if ((n = _codec.AvailableBytesIn) == 0) + return ZlibConstants.Z_BUF_ERROR; + p = _codec.NextIn; + m = marker; + + // search + while (n != 0 && m < 4) + { + if (_codec.InputBuffer[p] == mark[m]) + { + m++; + } + else if (_codec.InputBuffer[p] != 0) + { + m = 0; + } + else + { + m = 4 - m; + } + p++; n--; + } + + // restore + _codec.TotalBytesIn += p - _codec.NextIn; + _codec.NextIn = p; + _codec.AvailableBytesIn = n; + marker = m; + + // return no joy or set up to restart on a new block + if (m != 4) + { + return ZlibConstants.Z_DATA_ERROR; + } + r = _codec.TotalBytesIn; + w = _codec.TotalBytesOut; + Reset(); + _codec.TotalBytesIn = r; + _codec.TotalBytesOut = w; + mode = InflateManagerMode.BLOCKS; + return ZlibConstants.Z_OK; + } + + + // Returns true if inflate is currently at the end of a block generated + // by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP + // implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH + // but removes the length bytes of the resulting empty stored block. When + // decompressing, PPP checks that at the end of input packet, inflate is + // waiting for these length bytes. + internal int SyncPoint(ZlibCodec z) + { + return blocks.SyncPoint(); + } + } +} \ No newline at end of file diff --git a/ROMVault2/SupportedFiles/Zip/ZLib/Tree.cs b/ROMVault2/SupportedFiles/Zip/ZLib/Tree.cs new file mode 100644 index 0000000..0059796 --- /dev/null +++ b/ROMVault2/SupportedFiles/Zip/ZLib/Tree.cs @@ -0,0 +1,421 @@ +// Tree.cs +// ------------------------------------------------------------------ +// +// Copyright (c) 2009 Dino Chiesa and Microsoft Corporation. +// All rights reserved. +// +// This code module is part of DotNetZip, a zipfile class library. +// +// ------------------------------------------------------------------ +// +// This code is licensed under the Microsoft Public License. +// See the file License.txt for the license details. +// More info on: http://dotnetzip.codeplex.com +// +// ------------------------------------------------------------------ +// +// last saved (in emacs): +// Time-stamp: <2009-October-28 13:29:50> +// +// ------------------------------------------------------------------ +// +// This module defines classes for zlib compression and +// decompression. This code is derived from the jzlib implementation of +// zlib. In keeping with the license for jzlib, the copyright to that +// code is below. +// +// ------------------------------------------------------------------ +// +// Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// 2. 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. +// +// 3. The names of the authors may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 JCRAFT, +// INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE 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. +// +// ----------------------------------------------------------------------- +// +// This program is based on zlib-1.1.3; credit to authors +// Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) +// and contributors of zlib. +// +// ----------------------------------------------------------------------- + + +namespace ROMVault2.SupportedFiles.Zip.ZLib +{ + sealed class Tree + { + private static readonly int HEAP_SIZE = (2 * InternalConstants.L_CODES + 1); + + // extra bits for each length code + internal static readonly int[] ExtraLengthBits = new int[] + { + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, + 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0 + }; + + // extra bits for each distance code + internal static readonly int[] ExtraDistanceBits = new int[] + { + 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, + 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13 + }; + + // extra bits for each bit length code + internal static readonly int[] extra_blbits = new int[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7}; + + internal static readonly sbyte[] bl_order = new sbyte[]{16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + + + // The lengths of the bit length codes are sent in order of decreasing + // probability, to avoid transmitting the lengths for unused bit + // length codes. + + internal const int Buf_size = 8 * 2; + + // see definition of array dist_code below + //internal const int DIST_CODE_LEN = 512; + + private static readonly sbyte[] _dist_code = new sbyte[] + { + 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, + 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 0, 0, 16, 17, 18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, + 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 + }; + + internal static readonly sbyte[] LengthCode = new sbyte[] + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, + 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, + 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, + 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 + }; + + + internal static readonly int[] LengthBase = new int[] + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, + 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 0 + }; + + + internal static readonly int[] DistanceBase = new int[] + { + 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96, 128, 192, + 256, 384, 512, 768, 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 + }; + + + /// + /// Map from a distance to a distance code. + /// + /// + /// No side effects. _dist_code[256] and _dist_code[257] are never used. + /// + internal static int DistanceCode(int dist) + { + return (dist < 256) + ? _dist_code[dist] + : _dist_code[256 + SharedUtils.URShift(dist, 7)]; + } + + internal short[] dyn_tree; // the dynamic tree + internal int max_code; // largest code with non zero frequency + internal StaticTree staticTree; // the corresponding static tree + + // Compute the optimal bit lengths for a tree and update the total bit length + // for the current block. + // IN assertion: the fields freq and dad are set, heap[heap_max] and + // above are the tree nodes sorted by increasing frequency. + // OUT assertions: the field len is set to the optimal bit length, the + // array bl_count contains the frequencies for each bit length. + // The length opt_len is updated; static_len is also updated if stree is + // not null. + internal void gen_bitlen(DeflateManager s) + { + short[] tree = dyn_tree; + short[] stree = staticTree.treeCodes; + int[] extra = staticTree.extraBits; + int base_Renamed = staticTree.extraBase; + int max_length = staticTree.maxLength; + int h; // heap index + int n, m; // iterate over the tree elements + int bits; // bit length + int xbits; // extra bits + short f; // frequency + int overflow = 0; // number of elements with bit length too large + + for (bits = 0; bits <= InternalConstants.MAX_BITS; bits++) + s.bl_count[bits] = 0; + + // In a first pass, compute the optimal bit lengths (which may + // overflow in the case of the bit length tree). + tree[s.heap[s.heap_max] * 2 + 1] = 0; // root of the heap + + for (h = s.heap_max + 1; h < HEAP_SIZE; h++) + { + n = s.heap[h]; + bits = tree[tree[n * 2 + 1] * 2 + 1] + 1; + if (bits > max_length) + { + bits = max_length; overflow++; + } + tree[n * 2 + 1] = (short) bits; + // We overwrite tree[n*2+1] which is no longer needed + + if (n > max_code) + continue; // not a leaf node + + s.bl_count[bits]++; + xbits = 0; + if (n >= base_Renamed) + xbits = extra[n - base_Renamed]; + f = tree[n * 2]; + s.opt_len += f * (bits + xbits); + if (stree != null) + s.static_len += f * (stree[n * 2 + 1] + xbits); + } + if (overflow == 0) + return ; + + // This happens for example on obj2 and pic of the Calgary corpus + // Find the first bit length which could increase: + do + { + bits = max_length - 1; + while (s.bl_count[bits] == 0) + bits--; + s.bl_count[bits]--; // move one leaf down the tree + s.bl_count[bits + 1] = (short) (s.bl_count[bits + 1] + 2); // move one overflow item as its brother + s.bl_count[max_length]--; + // The brother of the overflow item also moves one step up, + // but this does not affect bl_count[max_length] + overflow -= 2; + } + while (overflow > 0); + + for (bits = max_length; bits != 0; bits--) + { + n = s.bl_count[bits]; + while (n != 0) + { + m = s.heap[--h]; + if (m > max_code) + continue; + if (tree[m * 2 + 1] != bits) + { + s.opt_len = (int) (s.opt_len + ((long) bits - (long) tree[m * 2 + 1]) * (long) tree[m * 2]); + tree[m * 2 + 1] = (short) bits; + } + n--; + } + } + } + + // Construct one Huffman tree and assigns the code bit strings and lengths. + // Update the total bit length for the current block. + // IN assertion: the field freq is set for all tree elements. + // OUT assertions: the fields len and code are set to the optimal bit length + // and corresponding code. The length opt_len is updated; static_len is + // also updated if stree is not null. The field max_code is set. + internal void build_tree(DeflateManager s) + { + short[] tree = dyn_tree; + short[] stree = staticTree.treeCodes; + int elems = staticTree.elems; + int n, m; // iterate over heap elements + int max_code = -1; // largest code with non zero frequency + int node; // new node being created + + // Construct the initial heap, with least frequent element in + // heap[1]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. + // heap[0] is not used. + s.heap_len = 0; + s.heap_max = HEAP_SIZE; + + for (n = 0; n < elems; n++) + { + if (tree[n * 2] != 0) + { + s.heap[++s.heap_len] = max_code = n; + s.depth[n] = 0; + } + else + { + tree[n * 2 + 1] = 0; + } + } + + // The pkzip format requires that at least one distance code exists, + // and that at least one bit should be sent even if there is only one + // possible code. So to avoid special checks later on we force at least + // two codes of non zero frequency. + while (s.heap_len < 2) + { + node = s.heap[++s.heap_len] = (max_code < 2?++max_code:0); + tree[node * 2] = 1; + s.depth[node] = 0; + s.opt_len--; + if (stree != null) + s.static_len -= stree[node * 2 + 1]; + // node is 0 or 1 so it does not have extra bits + } + this.max_code = max_code; + + // The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, + // establish sub-heaps of increasing lengths: + + for (n = s.heap_len / 2; n >= 1; n--) + s.pqdownheap(tree, n); + + // Construct the Huffman tree by repeatedly combining the least two + // frequent nodes. + + node = elems; // next internal node of the tree + do + { + // n = node of least frequency + n = s.heap[1]; + s.heap[1] = s.heap[s.heap_len--]; + s.pqdownheap(tree, 1); + m = s.heap[1]; // m = node of next least frequency + + s.heap[--s.heap_max] = n; // keep the nodes sorted by frequency + s.heap[--s.heap_max] = m; + + // Create a new node father of n and m + tree[node * 2] = unchecked((short) (tree[n * 2] + tree[m * 2])); + s.depth[node] = (sbyte) (System.Math.Max((byte) s.depth[n], (byte) s.depth[m]) + 1); + tree[n * 2 + 1] = tree[m * 2 + 1] = (short) node; + + // and insert the new node in the heap + s.heap[1] = node++; + s.pqdownheap(tree, 1); + } + while (s.heap_len >= 2); + + s.heap[--s.heap_max] = s.heap[1]; + + // At this point, the fields freq and dad are set. We can now + // generate the bit lengths. + + gen_bitlen(s); + + // The field len is now set, we can generate the bit codes + gen_codes(tree, max_code, s.bl_count); + } + + // Generate the codes for a given tree and bit counts (which need not be + // optimal). + // IN assertion: the array bl_count contains the bit length statistics for + // the given tree and the field len is set for all tree elements. + // OUT assertion: the field code is set for all tree elements of non + // zero code length. + internal static void gen_codes(short[] tree, int max_code, short[] bl_count) + { + short[] next_code = new short[InternalConstants.MAX_BITS + 1]; // next code value for each bit length + short code = 0; // running code value + int bits; // bit index + int n; // code index + + // The distribution counts are first used to generate the code values + // without bit reversal. + for (bits = 1; bits <= InternalConstants.MAX_BITS; bits++) + unchecked { + next_code[bits] = code = (short) ((code + bl_count[bits - 1]) << 1); + } + + // Check that the bit counts in bl_count are consistent. The last code + // must be all ones. + //Assert (code + bl_count[MAX_BITS]-1 == (1<>= 1; //SharedUtils.URShift(code, 1); + res <<= 1; + } + while (--len > 0); + return res >> 1; + } + } +} \ No newline at end of file diff --git a/ROMVault2/SupportedFiles/Zip/ZLib/Zlib.cs b/ROMVault2/SupportedFiles/Zip/ZLib/Zlib.cs new file mode 100644 index 0000000..9a5fd5e --- /dev/null +++ b/ROMVault2/SupportedFiles/Zip/ZLib/Zlib.cs @@ -0,0 +1,544 @@ +// Zlib.cs +// ------------------------------------------------------------------ +// +// Copyright (c) 2009-2011 Dino Chiesa and Microsoft Corporation. +// All rights reserved. +// +// This code module is part of DotNetZip, a zipfile class library. +// +// ------------------------------------------------------------------ +// +// This code is licensed under the Microsoft Public License. +// See the file License.txt for the license details. +// More info on: http://dotnetzip.codeplex.com +// +// ------------------------------------------------------------------ +// +// Last Saved: <2011-August-03 19:52:28> +// +// ------------------------------------------------------------------ +// +// This module defines classes for ZLIB compression and +// decompression. This code is derived from the jzlib implementation of +// zlib, but significantly modified. The object model is not the same, +// and many of the behaviors are new or different. Nonetheless, in +// keeping with the license for jzlib, the copyright to that code is +// included below. +// +// ------------------------------------------------------------------ +// +// The following notice applies to jzlib: +// +// Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// 2. 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. +// +// 3. The names of the authors may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 JCRAFT, +// INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE 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. +// +// ----------------------------------------------------------------------- +// +// jzlib is based on zlib-1.1.3. +// +// The following notice applies to zlib: +// +// ----------------------------------------------------------------------- +// +// Copyright (C) 1995-2004 Jean-loup Gailly and Mark Adler +// +// The ZLIB 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. +// +// Jean-loup Gailly jloup@gzip.org +// Mark Adler madler@alumni.caltech.edu +// +// ----------------------------------------------------------------------- + + +using System.Runtime.InteropServices; + +namespace ROMVault2.SupportedFiles.Zip.ZLib +{ + + /// + /// Describes how to flush the current deflate operation. + /// + /// + /// The different FlushType values are useful when using a Deflate in a streaming application. + /// + public enum FlushType + { + /// No flush at all. + None = 0, + + /// Closes the current block, but doesn't flush it to + /// the output. Used internally only in hypothetical + /// scenarios. This was supposed to be removed by Zlib, but it is + /// still in use in some edge cases. + /// + Partial, + + /// + /// Use this during compression to specify that all pending output should be + /// flushed to the output buffer and the output should be aligned on a byte + /// boundary. You might use this in a streaming communication scenario, so that + /// the decompressor can get all input data available so far. When using this + /// with a ZlibCodec, AvailableBytesIn will be zero after the call if + /// enough output space has been provided before the call. Flushing will + /// degrade compression and so it should be used only when necessary. + /// + Sync, + + /// + /// Use this during compression to specify that all output should be flushed, as + /// with FlushType.Sync, but also, the compression state should be reset + /// so that decompression can restart from this point if previous compressed + /// data has been damaged or if random access is desired. Using + /// FlushType.Full too often can significantly degrade the compression. + /// + Full, + + /// Signals the end of the compression/decompression stream. + Finish, + } + + + /// + /// The compression level to be used when using a DeflateStream or ZlibStream with CompressionMode.Compress. + /// + public enum CompressionLevel + { + /// + /// None means that the data will be simply stored, with no change at all. + /// If you are producing ZIPs for use on Mac OSX, be aware that archives produced with CompressionLevel.None + /// cannot be opened with the default zip reader. Use a different CompressionLevel. + /// + None= 0, + /// + /// Same as None. + /// + Level0 = 0, + + /// + /// The fastest but least effective compression. + /// + BestSpeed = 1, + + /// + /// A synonym for BestSpeed. + /// + Level1 = 1, + + /// + /// A little slower, but better, than level 1. + /// + Level2 = 2, + + /// + /// A little slower, but better, than level 2. + /// + Level3 = 3, + + /// + /// A little slower, but better, than level 3. + /// + Level4 = 4, + + /// + /// A little slower than level 4, but with better compression. + /// + Level5 = 5, + + /// + /// The default compression level, with a good balance of speed and compression efficiency. + /// + Default = 6, + /// + /// A synonym for Default. + /// + Level6 = 6, + + /// + /// Pretty good compression! + /// + Level7 = 7, + + /// + /// Better compression than Level7! + /// + Level8 = 8, + + /// + /// The "best" compression, where best means greatest reduction in size of the input data stream. + /// This is also the slowest compression. + /// + BestCompression = 9, + + /// + /// A synonym for BestCompression. + /// + Level9 = 9, + } + + /// + /// Describes options for how the compression algorithm is executed. Different strategies + /// work better on different sorts of data. The strategy parameter can affect the compression + /// ratio and the speed of compression but not the correctness of the compresssion. + /// + public enum CompressionStrategy + { + /// + /// The default strategy is probably the best for normal data. + /// + Default = 0, + + /// + /// The Filtered strategy is intended to be used most effectively with data produced by a + /// filter or predictor. By this definition, filtered data consists mostly of small + /// values with a somewhat random distribution. In this case, the compression algorithm + /// is tuned to compress them better. The effect of Filtered is to force more Huffman + /// coding and less string matching; it is a half-step between Default and HuffmanOnly. + /// + Filtered = 1, + + /// + /// Using HuffmanOnly will force the compressor to do Huffman encoding only, with no + /// string matching. + /// + HuffmanOnly = 2, + } + + + /// + /// An enum to specify the direction of transcoding - whether to compress or decompress. + /// + public enum CompressionMode + { + /// + /// Used to specify that the stream should compress the data. + /// + Compress= 0, + /// + /// Used to specify that the stream should decompress the data. + /// + Decompress = 1, + } + + + /// + /// A general purpose exception class for exceptions in the Zlib library. + /// + [Guid("ebc25cf6-9120-4283-b972-0e5520d0000E")] + public class ZlibException : System.Exception + { + /// + /// The ZlibException class captures exception information generated + /// by the Zlib library. + /// + public ZlibException() + : base() + { + } + + /// + /// This ctor collects a message attached to the exception. + /// + /// the message for the exception. + public ZlibException(System.String s) + : base(s) + { + } + } + + + internal class SharedUtils + { + /// + /// Performs an unsigned bitwise right shift with the specified number + /// + /// Number to operate on + /// Ammount of bits to shift + /// The resulting number from the shift operation + public static int URShift(int number, int bits) + { + return (int)((uint)number >> bits); + } + +#if NOT + /// + /// Performs an unsigned bitwise right shift with the specified number + /// + /// Number to operate on + /// Ammount of bits to shift + /// The resulting number from the shift operation + public static long URShift(long number, int bits) + { + return (long) ((UInt64)number >> bits); + } +#endif + + /// + /// Reads a number of characters from the current source TextReader and writes + /// the data to the target array at the specified index. + /// + /// + /// The source TextReader to read from + /// Contains the array of characteres read from the source TextReader. + /// The starting index of the target array. + /// The maximum number of characters to read from the source TextReader. + /// + /// + /// The number of characters read. The number will be less than or equal to + /// count depending on the data available in the source TextReader. Returns -1 + /// if the end of the stream is reached. + /// + public static System.Int32 ReadInput(System.IO.TextReader sourceTextReader, byte[] target, int start, int count) + { + // Returns 0 bytes if not enough space in target + if (target.Length == 0) return 0; + + char[] charArray = new char[target.Length]; + int bytesRead = sourceTextReader.Read(charArray, start, count); + + // Returns -1 if EOF + if (bytesRead == 0) return -1; + + for (int index = start; index < start + bytesRead; index++) + target[index] = (byte)charArray[index]; + + return bytesRead; + } + + + internal static byte[] ToByteArray(System.String sourceString) + { + return System.Text.UTF8Encoding.UTF8.GetBytes(sourceString); + } + + + internal static char[] ToCharArray(byte[] byteArray) + { + return System.Text.UTF8Encoding.UTF8.GetChars(byteArray); + } + } + + internal static class InternalConstants + { + internal static readonly int MAX_BITS = 15; + internal static readonly int BL_CODES = 19; + internal static readonly int D_CODES = 30; + internal static readonly int LITERALS = 256; + internal static readonly int LENGTH_CODES = 29; + internal static readonly int L_CODES = (LITERALS + 1 + LENGTH_CODES); + + // Bit length codes must not exceed MAX_BL_BITS bits + internal static readonly int MAX_BL_BITS = 7; + + // repeat previous bit length 3-6 times (2 bits of repeat count) + internal static readonly int REP_3_6 = 16; + + // repeat a zero length 3-10 times (3 bits of repeat count) + internal static readonly int REPZ_3_10 = 17; + + // repeat a zero length 11-138 times (7 bits of repeat count) + internal static readonly int REPZ_11_138 = 18; + + } + + internal sealed class StaticTree + { + internal static readonly short[] lengthAndLiteralsTreeCodes = new short[] { + 12, 8, 140, 8, 76, 8, 204, 8, 44, 8, 172, 8, 108, 8, 236, 8, + 28, 8, 156, 8, 92, 8, 220, 8, 60, 8, 188, 8, 124, 8, 252, 8, + 2, 8, 130, 8, 66, 8, 194, 8, 34, 8, 162, 8, 98, 8, 226, 8, + 18, 8, 146, 8, 82, 8, 210, 8, 50, 8, 178, 8, 114, 8, 242, 8, + 10, 8, 138, 8, 74, 8, 202, 8, 42, 8, 170, 8, 106, 8, 234, 8, + 26, 8, 154, 8, 90, 8, 218, 8, 58, 8, 186, 8, 122, 8, 250, 8, + 6, 8, 134, 8, 70, 8, 198, 8, 38, 8, 166, 8, 102, 8, 230, 8, + 22, 8, 150, 8, 86, 8, 214, 8, 54, 8, 182, 8, 118, 8, 246, 8, + 14, 8, 142, 8, 78, 8, 206, 8, 46, 8, 174, 8, 110, 8, 238, 8, + 30, 8, 158, 8, 94, 8, 222, 8, 62, 8, 190, 8, 126, 8, 254, 8, + 1, 8, 129, 8, 65, 8, 193, 8, 33, 8, 161, 8, 97, 8, 225, 8, + 17, 8, 145, 8, 81, 8, 209, 8, 49, 8, 177, 8, 113, 8, 241, 8, + 9, 8, 137, 8, 73, 8, 201, 8, 41, 8, 169, 8, 105, 8, 233, 8, + 25, 8, 153, 8, 89, 8, 217, 8, 57, 8, 185, 8, 121, 8, 249, 8, + 5, 8, 133, 8, 69, 8, 197, 8, 37, 8, 165, 8, 101, 8, 229, 8, + 21, 8, 149, 8, 85, 8, 213, 8, 53, 8, 181, 8, 117, 8, 245, 8, + 13, 8, 141, 8, 77, 8, 205, 8, 45, 8, 173, 8, 109, 8, 237, 8, + 29, 8, 157, 8, 93, 8, 221, 8, 61, 8, 189, 8, 125, 8, 253, 8, + 19, 9, 275, 9, 147, 9, 403, 9, 83, 9, 339, 9, 211, 9, 467, 9, + 51, 9, 307, 9, 179, 9, 435, 9, 115, 9, 371, 9, 243, 9, 499, 9, + 11, 9, 267, 9, 139, 9, 395, 9, 75, 9, 331, 9, 203, 9, 459, 9, + 43, 9, 299, 9, 171, 9, 427, 9, 107, 9, 363, 9, 235, 9, 491, 9, + 27, 9, 283, 9, 155, 9, 411, 9, 91, 9, 347, 9, 219, 9, 475, 9, + 59, 9, 315, 9, 187, 9, 443, 9, 123, 9, 379, 9, 251, 9, 507, 9, + 7, 9, 263, 9, 135, 9, 391, 9, 71, 9, 327, 9, 199, 9, 455, 9, + 39, 9, 295, 9, 167, 9, 423, 9, 103, 9, 359, 9, 231, 9, 487, 9, + 23, 9, 279, 9, 151, 9, 407, 9, 87, 9, 343, 9, 215, 9, 471, 9, + 55, 9, 311, 9, 183, 9, 439, 9, 119, 9, 375, 9, 247, 9, 503, 9, + 15, 9, 271, 9, 143, 9, 399, 9, 79, 9, 335, 9, 207, 9, 463, 9, + 47, 9, 303, 9, 175, 9, 431, 9, 111, 9, 367, 9, 239, 9, 495, 9, + 31, 9, 287, 9, 159, 9, 415, 9, 95, 9, 351, 9, 223, 9, 479, 9, + 63, 9, 319, 9, 191, 9, 447, 9, 127, 9, 383, 9, 255, 9, 511, 9, + 0, 7, 64, 7, 32, 7, 96, 7, 16, 7, 80, 7, 48, 7, 112, 7, + 8, 7, 72, 7, 40, 7, 104, 7, 24, 7, 88, 7, 56, 7, 120, 7, + 4, 7, 68, 7, 36, 7, 100, 7, 20, 7, 84, 7, 52, 7, 116, 7, + 3, 8, 131, 8, 67, 8, 195, 8, 35, 8, 163, 8, 99, 8, 227, 8 + }; + + internal static readonly short[] distTreeCodes = new short[] { + 0, 5, 16, 5, 8, 5, 24, 5, 4, 5, 20, 5, 12, 5, 28, 5, + 2, 5, 18, 5, 10, 5, 26, 5, 6, 5, 22, 5, 14, 5, 30, 5, + 1, 5, 17, 5, 9, 5, 25, 5, 5, 5, 21, 5, 13, 5, 29, 5, + 3, 5, 19, 5, 11, 5, 27, 5, 7, 5, 23, 5 }; + + internal static readonly StaticTree Literals; + internal static readonly StaticTree Distances; + internal static readonly StaticTree BitLengths; + + internal short[] treeCodes; // static tree or null + internal int[] extraBits; // extra bits for each code or null + internal int extraBase; // base index for extra_bits + internal int elems; // max number of elements in the tree + internal int maxLength; // max bit length for the codes + + private StaticTree(short[] treeCodes, int[] extraBits, int extraBase, int elems, int maxLength) + { + this.treeCodes = treeCodes; + this.extraBits = extraBits; + this.extraBase = extraBase; + this.elems = elems; + this.maxLength = maxLength; + } + static StaticTree() + { + Literals = new StaticTree(lengthAndLiteralsTreeCodes, Tree.ExtraLengthBits, InternalConstants.LITERALS + 1, InternalConstants.L_CODES, InternalConstants.MAX_BITS); + Distances = new StaticTree(distTreeCodes, Tree.ExtraDistanceBits, 0, InternalConstants.D_CODES, InternalConstants.MAX_BITS); + BitLengths = new StaticTree(null, Tree.extra_blbits, 0, InternalConstants.BL_CODES, InternalConstants.MAX_BL_BITS); + } + } + + + + /// + /// Computes an Adler-32 checksum. + /// + /// + /// The Adler checksum is similar to a CRC checksum, but faster to compute, though less + /// reliable. It is used in producing RFC1950 compressed streams. The Adler checksum + /// is a required part of the "ZLIB" standard. Applications will almost never need to + /// use this class directly. + /// + /// + /// + public sealed class Adler + { + // largest prime smaller than 65536 + private static readonly uint BASE = 65521; + // NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 + private static readonly int NMAX = 5552; + + +#pragma warning disable 3001 +#pragma warning disable 3002 + + /// + /// Calculates the Adler32 checksum. + /// + /// + /// + /// This is used within ZLIB. You probably don't need to use this directly. + /// + /// + /// + /// To compute an Adler32 checksum on a byte array: + /// + /// var adler = Adler.Adler32(0, null, 0, 0); + /// adler = Adler.Adler32(adler, buffer, index, length); + /// + /// + public static uint Adler32(uint adler, byte[] buf, int index, int len) + { + if (buf == null) + return 1; + + uint s1 = (uint) (adler & 0xffff); + uint s2 = (uint) ((adler >> 16) & 0xffff); + + while (len > 0) + { + int k = len < NMAX ? len : NMAX; + len -= k; + while (k >= 16) + { + //s1 += (buf[index++] & 0xff); s2 += s1; + s1 += buf[index++]; s2 += s1; + s1 += buf[index++]; s2 += s1; + s1 += buf[index++]; s2 += s1; + s1 += buf[index++]; s2 += s1; + s1 += buf[index++]; s2 += s1; + s1 += buf[index++]; s2 += s1; + s1 += buf[index++]; s2 += s1; + s1 += buf[index++]; s2 += s1; + s1 += buf[index++]; s2 += s1; + s1 += buf[index++]; s2 += s1; + s1 += buf[index++]; s2 += s1; + s1 += buf[index++]; s2 += s1; + s1 += buf[index++]; s2 += s1; + s1 += buf[index++]; s2 += s1; + s1 += buf[index++]; s2 += s1; + s1 += buf[index++]; s2 += s1; + k -= 16; + } + if (k != 0) + { + do + { + s1 += buf[index++]; + s2 += s1; + } + while (--k != 0); + } + s1 %= BASE; + s2 %= BASE; + } + return (uint)((s2 << 16) | s1); + } +#pragma warning restore 3001 +#pragma warning restore 3002 + + } + +} \ No newline at end of file diff --git a/ROMVault2/SupportedFiles/Zip/ZLib/ZlibBaseStream.cs b/ROMVault2/SupportedFiles/Zip/ZLib/ZlibBaseStream.cs new file mode 100644 index 0000000..83d72f5 --- /dev/null +++ b/ROMVault2/SupportedFiles/Zip/ZLib/ZlibBaseStream.cs @@ -0,0 +1,627 @@ +// ZlibBaseStream.cs +// ------------------------------------------------------------------ +// +// Copyright (c) 2009 Dino Chiesa and Microsoft Corporation. +// All rights reserved. +// +// This code module is part of DotNetZip, a zipfile class library. +// +// ------------------------------------------------------------------ +// +// This code is licensed under the Microsoft Public License. +// See the file License.txt for the license details. +// More info on: http://dotnetzip.codeplex.com +// +// ------------------------------------------------------------------ +// +// last saved (in emacs): +// Time-stamp: <2011-August-06 21:22:38> +// +// ------------------------------------------------------------------ +// +// This module defines the ZlibBaseStream class, which is an intnernal +// base class for DeflateStream, ZlibStream and GZipStream. +// +// ------------------------------------------------------------------ + +using System; +using System.IO; + +namespace ROMVault2.SupportedFiles.Zip.ZLib +{ + + internal enum ZlibStreamFlavor { ZLIB = 1950, DEFLATE = 1951, GZIP = 1952 } + + internal class ZlibBaseStream : System.IO.Stream + { + protected internal ZlibCodec _z = null; // deferred init... new ZlibCodec(); + + protected internal StreamMode _streamMode = StreamMode.Undefined; + protected internal FlushType _flushMode; + protected internal ZlibStreamFlavor _flavor; + protected internal CompressionMode _compressionMode; + protected internal CompressionLevel _level; + protected internal bool _leaveOpen; + protected internal byte[] _workingBuffer; + protected internal int _bufferSize = ZlibConstants.WorkingBufferSizeDefault; + protected internal byte[] _buf1 = new byte[1]; + + protected internal System.IO.Stream _stream; + protected internal CompressionStrategy Strategy = CompressionStrategy.Default; + + // workitem 7159 + CRC32 crc; + protected internal string _GzipFileName; + protected internal string _GzipComment; + protected internal DateTime _GzipMtime; + protected internal int _gzipHeaderByteCount; + + internal int Crc32 { get { if (crc == null) return 0; return crc.Crc32Result; } } + + public ZlibBaseStream(System.IO.Stream stream, + CompressionMode compressionMode, + CompressionLevel level, + ZlibStreamFlavor flavor, + bool leaveOpen) + : base() + { + this._flushMode = FlushType.None; + //this._workingBuffer = new byte[WORKING_BUFFER_SIZE_DEFAULT]; + this._stream = stream; + this._leaveOpen = leaveOpen; + this._compressionMode = compressionMode; + this._flavor = flavor; + this._level = level; + // workitem 7159 + if (flavor == ZlibStreamFlavor.GZIP) + { + this.crc = new CRC32(); + } + } + + + protected internal bool _wantCompress + { + get + { + return (this._compressionMode == CompressionMode.Compress); + } + } + + private ZlibCodec z + { + get + { + if (_z == null) + { + bool wantRfc1950Header = (this._flavor == ZlibStreamFlavor.ZLIB); + _z = new ZlibCodec(); + if (this._compressionMode == CompressionMode.Decompress) + { + _z.InitializeInflate(wantRfc1950Header); + } + else + { + _z.Strategy = Strategy; + _z.InitializeDeflate(this._level, wantRfc1950Header); + } + } + return _z; + } + } + + + + private byte[] workingBuffer + { + get + { + if (_workingBuffer == null) + _workingBuffer = new byte[_bufferSize]; + return _workingBuffer; + } + } + + + + public override void Write(System.Byte[] buffer, int offset, int count) + { + // workitem 7159 + // calculate the CRC on the unccompressed data (before writing) + if (crc != null) + crc.SlurpBlock(buffer, offset, count); + + if (_streamMode == StreamMode.Undefined) + _streamMode = StreamMode.Writer; + else if (_streamMode != StreamMode.Writer) + throw new ZlibException("Cannot Write after Reading."); + + if (count == 0) + return; + + // first reference of z property will initialize the private var _z + z.InputBuffer = buffer; + _z.NextIn = offset; + _z.AvailableBytesIn = count; + bool done = false; + do + { + _z.OutputBuffer = workingBuffer; + _z.NextOut = 0; + _z.AvailableBytesOut = _workingBuffer.Length; + int rc = (_wantCompress) + ? _z.Deflate(_flushMode) + : _z.Inflate(_flushMode); + if (rc != ZlibConstants.Z_OK && rc != ZlibConstants.Z_STREAM_END) + throw new ZlibException((_wantCompress ? "de" : "in") + "flating: " + _z.Message); + + //if (_workingBuffer.Length - _z.AvailableBytesOut > 0) + _stream.Write(_workingBuffer, 0, _workingBuffer.Length - _z.AvailableBytesOut); + + done = _z.AvailableBytesIn == 0 && _z.AvailableBytesOut != 0; + + // If GZIP and de-compress, we're done when 8 bytes remain. + if (_flavor == ZlibStreamFlavor.GZIP && !_wantCompress) + done = (_z.AvailableBytesIn == 8 && _z.AvailableBytesOut != 0); + + } + while (!done); + } + + + + private void finish() + { + if (_z == null) return; + + if (_streamMode == StreamMode.Writer) + { + bool done = false; + do + { + _z.OutputBuffer = workingBuffer; + _z.NextOut = 0; + _z.AvailableBytesOut = _workingBuffer.Length; + int rc = (_wantCompress) + ? _z.Deflate(FlushType.Finish) + : _z.Inflate(FlushType.Finish); + + if (rc != ZlibConstants.Z_STREAM_END && rc != ZlibConstants.Z_OK) + { + string verb = (_wantCompress ? "de" : "in") + "flating"; + if (_z.Message == null) + throw new ZlibException(String.Format("{0}: (rc = {1})", verb, rc)); + else + throw new ZlibException(verb + ": " + _z.Message); + } + + if (_workingBuffer.Length - _z.AvailableBytesOut > 0) + { + _stream.Write(_workingBuffer, 0, _workingBuffer.Length - _z.AvailableBytesOut); + } + + done = _z.AvailableBytesIn == 0 && _z.AvailableBytesOut != 0; + // If GZIP and de-compress, we're done when 8 bytes remain. + if (_flavor == ZlibStreamFlavor.GZIP && !_wantCompress) + done = (_z.AvailableBytesIn == 8 && _z.AvailableBytesOut != 0); + + } + while (!done); + + Flush(); + + // workitem 7159 + if (_flavor == ZlibStreamFlavor.GZIP) + { + if (_wantCompress) + { + // Emit the GZIP trailer: CRC32 and size mod 2^32 + int c1 = crc.Crc32Result; + _stream.Write(BitConverter.GetBytes(c1), 0, 4); + int c2 = (Int32)(crc.TotalBytesRead & 0x00000000FFFFFFFF); + _stream.Write(BitConverter.GetBytes(c2), 0, 4); + } + else + { + throw new ZlibException("Writing with decompression is not supported."); + } + } + } + // workitem 7159 + else if (_streamMode == StreamMode.Reader) + { + if (_flavor == ZlibStreamFlavor.GZIP) + { + if (!_wantCompress) + { + // workitem 8501: handle edge case (decompress empty stream) + if (_z.TotalBytesOut == 0L) + return; + + // Read and potentially verify the GZIP trailer: + // CRC32 and size mod 2^32 + byte[] trailer = new byte[8]; + + // workitems 8679 & 12554 + if (_z.AvailableBytesIn < 8) + { + // Make sure we have read to the end of the stream + Array.Copy(_z.InputBuffer, _z.NextIn, trailer, 0, _z.AvailableBytesIn); + int bytesNeeded = 8 - _z.AvailableBytesIn; + int bytesRead = _stream.Read(trailer, + _z.AvailableBytesIn, + bytesNeeded); + if (bytesNeeded != bytesRead) + { + throw new ZlibException(String.Format("Missing or incomplete GZIP trailer. Expected 8 bytes, got {0}.", + _z.AvailableBytesIn + bytesRead)); + } + } + else + { + Array.Copy(_z.InputBuffer, _z.NextIn, trailer, 0, trailer.Length); + } + + Int32 crc32_expected = BitConverter.ToInt32(trailer, 0); + Int32 crc32_actual = crc.Crc32Result; + Int32 isize_expected = BitConverter.ToInt32(trailer, 4); + Int32 isize_actual = (Int32)(_z.TotalBytesOut & 0x00000000FFFFFFFF); + + if (crc32_actual != crc32_expected) + throw new ZlibException(String.Format("Bad CRC32 in GZIP trailer. (actual({0:X8})!=expected({1:X8}))", crc32_actual, crc32_expected)); + + if (isize_actual != isize_expected) + throw new ZlibException(String.Format("Bad size in GZIP trailer. (actual({0})!=expected({1}))", isize_actual, isize_expected)); + + } + else + { + throw new ZlibException("Reading with compression is not supported."); + } + } + } + } + + + private void end() + { + if (z == null) + return; + if (_wantCompress) + { + _z.EndDeflate(); + } + else + { + _z.EndInflate(); + } + _z = null; + } + + + public override void Close() + { + if (_stream == null) return; + try + { + finish(); + } + finally + { + end(); + if (!_leaveOpen) _stream.Close(); + _stream = null; + } + } + + public override void Flush() + { + _stream.Flush(); + } + + public override System.Int64 Seek(System.Int64 offset, System.IO.SeekOrigin origin) + { + throw new NotImplementedException(); + //_outStream.Seek(offset, origin); + } + public override void SetLength(System.Int64 value) + { + _stream.SetLength(value); + } + + +#if NOT + public int Read() + { + if (Read(_buf1, 0, 1) == 0) + return 0; + // calculate CRC after reading + if (crc!=null) + crc.SlurpBlock(_buf1,0,1); + return (_buf1[0] & 0xFF); + } +#endif + + private bool nomoreinput = false; + + + + private string ReadZeroTerminatedString() + { + var list = new System.Collections.Generic.List(); + bool done = false; + do + { + // workitem 7740 + int n = _stream.Read(_buf1, 0, 1); + if (n != 1) + throw new ZlibException("Unexpected EOF reading GZIP header."); + else + { + if (_buf1[0] == 0) + done = true; + else + list.Add(_buf1[0]); + } + } while (!done); + byte[] a = list.ToArray(); + return GZipStream.iso8859dash1.GetString(a, 0, a.Length); + } + + + private int _ReadAndValidateGzipHeader() + { + int totalBytesRead = 0; + // read the header on the first read + byte[] header = new byte[10]; + int n = _stream.Read(header, 0, header.Length); + + // workitem 8501: handle edge case (decompress empty stream) + if (n == 0) + return 0; + + if (n != 10) + throw new ZlibException("Not a valid GZIP stream."); + + if (header[0] != 0x1F || header[1] != 0x8B || header[2] != 8) + throw new ZlibException("Bad GZIP header."); + + Int32 timet = BitConverter.ToInt32(header, 4); + _GzipMtime = GZipStream._unixEpoch.AddSeconds(timet); + totalBytesRead += n; + if ((header[3] & 0x04) == 0x04) + { + // read and discard extra field + n = _stream.Read(header, 0, 2); // 2-byte length field + totalBytesRead += n; + + Int16 extraLength = (Int16)(header[0] + header[1] * 256); + byte[] extra = new byte[extraLength]; + n = _stream.Read(extra, 0, extra.Length); + if (n != extraLength) + throw new ZlibException("Unexpected end-of-file reading GZIP header."); + totalBytesRead += n; + } + if ((header[3] & 0x08) == 0x08) + _GzipFileName = ReadZeroTerminatedString(); + if ((header[3] & 0x10) == 0x010) + _GzipComment = ReadZeroTerminatedString(); + if ((header[3] & 0x02) == 0x02) + Read(_buf1, 0, 1); // CRC16, ignore + + return totalBytesRead; + } + + + + public override System.Int32 Read(System.Byte[] buffer, System.Int32 offset, System.Int32 count) + { + // According to MS documentation, any implementation of the IO.Stream.Read function must: + // (a) throw an exception if offset & count reference an invalid part of the buffer, + // or if count < 0, or if buffer is null + // (b) return 0 only upon EOF, or if count = 0 + // (c) if not EOF, then return at least 1 byte, up to bytes + + if (_streamMode == StreamMode.Undefined) + { + if (!this._stream.CanRead) throw new ZlibException("The stream is not readable."); + // for the first read, set up some controls. + _streamMode = StreamMode.Reader; + // (The first reference to _z goes through the private accessor which + // may initialize it.) + z.AvailableBytesIn = 0; + if (_flavor == ZlibStreamFlavor.GZIP) + { + _gzipHeaderByteCount = _ReadAndValidateGzipHeader(); + // workitem 8501: handle edge case (decompress empty stream) + if (_gzipHeaderByteCount == 0) + return 0; + } + } + + if (_streamMode != StreamMode.Reader) + throw new ZlibException("Cannot Read after Writing."); + + if (count == 0) return 0; + if (nomoreinput && _wantCompress) return 0; // workitem 8557 + if (buffer == null) throw new ArgumentNullException("buffer"); + if (count < 0) throw new ArgumentOutOfRangeException("count"); + if (offset < buffer.GetLowerBound(0)) throw new ArgumentOutOfRangeException("offset"); + if ((offset + count) > buffer.GetLength(0)) throw new ArgumentOutOfRangeException("count"); + + int rc = 0; + + // set up the output of the deflate/inflate codec: + _z.OutputBuffer = buffer; + _z.NextOut = offset; + _z.AvailableBytesOut = count; + + // This is necessary in case _workingBuffer has been resized. (new byte[]) + // (The first reference to _workingBuffer goes through the private accessor which + // may initialize it.) + _z.InputBuffer = workingBuffer; + + do + { + // need data in _workingBuffer in order to deflate/inflate. Here, we check if we have any. + if ((_z.AvailableBytesIn == 0) && (!nomoreinput)) + { + // No data available, so try to Read data from the captive stream. + _z.NextIn = 0; + _z.AvailableBytesIn = _stream.Read(_workingBuffer, 0, _workingBuffer.Length); + if (_z.AvailableBytesIn == 0) + nomoreinput = true; + + } + // we have data in InputBuffer; now compress or decompress as appropriate + rc = (_wantCompress) + ? _z.Deflate(_flushMode) + : _z.Inflate(_flushMode); + + if (nomoreinput && (rc == ZlibConstants.Z_BUF_ERROR)) + return 0; + + if (rc != ZlibConstants.Z_OK && rc != ZlibConstants.Z_STREAM_END) + throw new ZlibException(String.Format("{0}flating: rc={1} msg={2}", (_wantCompress ? "de" : "in"), rc, _z.Message)); + + if ((nomoreinput || rc == ZlibConstants.Z_STREAM_END) && (_z.AvailableBytesOut == count)) + break; // nothing more to read + } + //while (_z.AvailableBytesOut == count && rc == ZlibConstants.Z_OK); + while (_z.AvailableBytesOut > 0 && !nomoreinput && rc == ZlibConstants.Z_OK); + + + // workitem 8557 + // is there more room in output? + if (_z.AvailableBytesOut > 0) + { + if (rc == ZlibConstants.Z_OK && _z.AvailableBytesIn == 0) + { + // deferred + } + + // are we completely done reading? + if (nomoreinput) + { + // and in compression? + if (_wantCompress) + { + // no more input data available; therefore we flush to + // try to complete the read + rc = _z.Deflate(FlushType.Finish); + + if (rc != ZlibConstants.Z_OK && rc != ZlibConstants.Z_STREAM_END) + throw new ZlibException(String.Format("Deflating: rc={0} msg={1}", rc, _z.Message)); + } + } + } + + + rc = (count - _z.AvailableBytesOut); + + // calculate CRC after reading + if (crc != null) + crc.SlurpBlock(buffer, offset, rc); + + return rc; + } + + + + public override System.Boolean CanRead + { + get { return this._stream.CanRead; } + } + + public override System.Boolean CanSeek + { + get { return this._stream.CanSeek; } + } + + public override System.Boolean CanWrite + { + get { return this._stream.CanWrite; } + } + + public override System.Int64 Length + { + get { return _stream.Length; } + } + + public override long Position + { + get { throw new NotImplementedException(); } + set { throw new NotImplementedException(); } + } + + internal enum StreamMode + { + Writer, + Reader, + Undefined, + } + + + public static void CompressString(String s, Stream compressor) + { + byte[] uncompressed = System.Text.Encoding.UTF8.GetBytes(s); + using (compressor) + { + compressor.Write(uncompressed, 0, uncompressed.Length); + } + } + + public static void CompressBuffer(byte[] b, Stream compressor) + { + // workitem 8460 + using (compressor) + { + compressor.Write(b, 0, b.Length); + } + } + + public static String UncompressString(byte[] compressed, Stream decompressor) + { + // workitem 8460 + byte[] working = new byte[1024]; + var encoding = System.Text.Encoding.UTF8; + using (var output = new MemoryStream()) + { + using (decompressor) + { + int n; + while ((n = decompressor.Read(working, 0, working.Length)) != 0) + { + output.Write(working, 0, n); + } + } + + // reset to allow read from start + output.Seek(0, SeekOrigin.Begin); + var sr = new StreamReader(output, encoding); + return sr.ReadToEnd(); + } + } + + public static byte[] UncompressBuffer(byte[] compressed, Stream decompressor) + { + // workitem 8460 + byte[] working = new byte[1024]; + using (var output = new MemoryStream()) + { + using (decompressor) + { + int n; + while ((n = decompressor.Read(working, 0, working.Length)) != 0) + { + output.Write(working, 0, n); + } + } + return output.ToArray(); + } + } + + } + + +} diff --git a/ROMVault2/SupportedFiles/Zip/ZLib/ZlibCodec.cs b/ROMVault2/SupportedFiles/Zip/ZLib/ZlibCodec.cs new file mode 100644 index 0000000..f11bcca --- /dev/null +++ b/ROMVault2/SupportedFiles/Zip/ZLib/ZlibCodec.cs @@ -0,0 +1,717 @@ +// ZlibCodec.cs +// ------------------------------------------------------------------ +// +// Copyright (c) 2009 Dino Chiesa and Microsoft Corporation. +// All rights reserved. +// +// This code module is part of DotNetZip, a zipfile class library. +// +// ------------------------------------------------------------------ +// +// This code is licensed under the Microsoft Public License. +// See the file License.txt for the license details. +// More info on: http://dotnetzip.codeplex.com +// +// ------------------------------------------------------------------ +// +// last saved (in emacs): +// Time-stamp: <2009-November-03 15:40:51> +// +// ------------------------------------------------------------------ +// +// This module defines a Codec for ZLIB compression and +// decompression. This code extends code that was based the jzlib +// implementation of zlib, but this code is completely novel. The codec +// class is new, and encapsulates some behaviors that are new, and some +// that were present in other classes in the jzlib code base. In +// keeping with the license for jzlib, the copyright to the jzlib code +// is included below. +// +// ------------------------------------------------------------------ +// +// Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// 2. 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. +// +// 3. The names of the authors may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 JCRAFT, +// INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE 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. +// +// ----------------------------------------------------------------------- +// +// This program is based on zlib-1.1.3; credit to authors +// Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) +// and contributors of zlib. +// +// ----------------------------------------------------------------------- + + +using System; +using System.Runtime.InteropServices; + +namespace ROMVault2.SupportedFiles.Zip.ZLib +{ + /// + /// Encoder and Decoder for ZLIB and DEFLATE (IETF RFC1950 and RFC1951). + /// + /// + /// + /// This class compresses and decompresses data according to the Deflate algorithm + /// and optionally, the ZLIB format, as documented in RFC 1950 - ZLIB and RFC 1951 - DEFLATE. + /// + [Guid("ebc25cf6-9120-4283-b972-0e5520d0000D")] + [System.Runtime.InteropServices.ComVisible(true)] +#if !NETCF + [System.Runtime.InteropServices.ClassInterface(System.Runtime.InteropServices.ClassInterfaceType.AutoDispatch)] +#endif + sealed public class ZlibCodec + { + /// + /// The buffer from which data is taken. + /// + public byte[] InputBuffer; + + /// + /// An index into the InputBuffer array, indicating where to start reading. + /// + public int NextIn; + + /// + /// The number of bytes available in the InputBuffer, starting at NextIn. + /// + /// + /// Generally you should set this to InputBuffer.Length before the first Inflate() or Deflate() call. + /// The class will update this number as calls to Inflate/Deflate are made. + /// + public int AvailableBytesIn; + + /// + /// Total number of bytes read so far, through all calls to Inflate()/Deflate(). + /// + public long TotalBytesIn; + + /// + /// Buffer to store output data. + /// + public byte[] OutputBuffer; + + /// + /// An index into the OutputBuffer array, indicating where to start writing. + /// + public int NextOut; + + /// + /// The number of bytes available in the OutputBuffer, starting at NextOut. + /// + /// + /// Generally you should set this to OutputBuffer.Length before the first Inflate() or Deflate() call. + /// The class will update this number as calls to Inflate/Deflate are made. + /// + public int AvailableBytesOut; + + /// + /// Total number of bytes written to the output so far, through all calls to Inflate()/Deflate(). + /// + public long TotalBytesOut; + + /// + /// used for diagnostics, when something goes wrong! + /// + public System.String Message; + + internal DeflateManager dstate; + internal InflateManager istate; + + internal uint _Adler32; + + /// + /// The compression level to use in this codec. Useful only in compression mode. + /// + public CompressionLevel CompressLevel = CompressionLevel.Default; + + /// + /// The number of Window Bits to use. + /// + /// + /// This gauges the size of the sliding window, and hence the + /// compression effectiveness as well as memory consumption. It's best to just leave this + /// setting alone if you don't know what it is. The maximum value is 15 bits, which implies + /// a 32k window. + /// + public int WindowBits = ZlibConstants.WindowBitsDefault; + + /// + /// The compression strategy to use. + /// + /// + /// This is only effective in compression. The theory offered by ZLIB is that different + /// strategies could potentially produce significant differences in compression behavior + /// for different data sets. Unfortunately I don't have any good recommendations for how + /// to set it differently. When I tested changing the strategy I got minimally different + /// compression performance. It's best to leave this property alone if you don't have a + /// good feel for it. Or, you may want to produce a test harness that runs through the + /// different strategy options and evaluates them on different file types. If you do that, + /// let me know your results. + /// + public CompressionStrategy Strategy = CompressionStrategy.Default; + + + /// + /// The Adler32 checksum on the data transferred through the codec so far. You probably don't need to look at this. + /// + public int Adler32 { get { return (int)_Adler32; } } + + + /// + /// Create a ZlibCodec. + /// + /// + /// If you use this default constructor, you will later have to explicitly call + /// InitializeInflate() or InitializeDeflate() before using the ZlibCodec to compress + /// or decompress. + /// + public ZlibCodec() { } + + /// + /// Create a ZlibCodec that either compresses or decompresses. + /// + /// + /// Indicates whether the codec should compress (deflate) or decompress (inflate). + /// + public ZlibCodec(CompressionMode mode) + { + if (mode == CompressionMode.Compress) + { + int rc = InitializeDeflate(); + if (rc != ZlibConstants.Z_OK) throw new ZlibException("Cannot initialize for deflate."); + } + else if (mode == CompressionMode.Decompress) + { + int rc = InitializeInflate(); + if (rc != ZlibConstants.Z_OK) throw new ZlibException("Cannot initialize for inflate."); + } + else throw new ZlibException("Invalid ZlibStreamFlavor."); + } + + /// + /// Initialize the inflation state. + /// + /// + /// It is not necessary to call this before using the ZlibCodec to inflate data; + /// It is implicitly called when you call the constructor. + /// + /// Z_OK if everything goes well. + public int InitializeInflate() + { + return InitializeInflate(this.WindowBits); + } + + /// + /// Initialize the inflation state with an explicit flag to + /// govern the handling of RFC1950 header bytes. + /// + /// + /// + /// By default, the ZLIB header defined in RFC 1950 is expected. If + /// you want to read a zlib stream you should specify true for + /// expectRfc1950Header. If you have a deflate stream, you will want to specify + /// false. It is only necessary to invoke this initializer explicitly if you + /// want to specify false. + /// + /// + /// whether to expect an RFC1950 header byte + /// pair when reading the stream of data to be inflated. + /// + /// Z_OK if everything goes well. + public int InitializeInflate(bool expectRfc1950Header) + { + return InitializeInflate(this.WindowBits, expectRfc1950Header); + } + + /// + /// Initialize the ZlibCodec for inflation, with the specified number of window bits. + /// + /// The number of window bits to use. If you need to ask what that is, + /// then you shouldn't be calling this initializer. + /// Z_OK if all goes well. + public int InitializeInflate(int windowBits) + { + this.WindowBits = windowBits; + return InitializeInflate(windowBits, true); + } + + /// + /// Initialize the inflation state with an explicit flag to govern the handling of + /// RFC1950 header bytes. + /// + /// + /// + /// If you want to read a zlib stream you should specify true for + /// expectRfc1950Header. In this case, the library will expect to find a ZLIB + /// header, as defined in RFC + /// 1950, in the compressed stream. If you will be reading a DEFLATE or + /// GZIP stream, which does not have such a header, you will want to specify + /// false. + /// + /// + /// whether to expect an RFC1950 header byte pair when reading + /// the stream of data to be inflated. + /// The number of window bits to use. If you need to ask what that is, + /// then you shouldn't be calling this initializer. + /// Z_OK if everything goes well. + public int InitializeInflate(int windowBits, bool expectRfc1950Header) + { + this.WindowBits = windowBits; + if (dstate != null) throw new ZlibException("You may not call InitializeInflate() after calling InitializeDeflate()."); + istate = new InflateManager(expectRfc1950Header); + return istate.Initialize(this, windowBits); + } + + /// + /// Inflate the data in the InputBuffer, placing the result in the OutputBuffer. + /// + /// + /// You must have set InputBuffer and OutputBuffer, NextIn and NextOut, and AvailableBytesIn and + /// AvailableBytesOut before calling this method. + /// + /// + /// + /// private void InflateBuffer() + /// { + /// int bufferSize = 1024; + /// byte[] buffer = new byte[bufferSize]; + /// ZlibCodec decompressor = new ZlibCodec(); + /// + /// Console.WriteLine("\n============================================"); + /// Console.WriteLine("Size of Buffer to Inflate: {0} bytes.", CompressedBytes.Length); + /// MemoryStream ms = new MemoryStream(DecompressedBytes); + /// + /// int rc = decompressor.InitializeInflate(); + /// + /// decompressor.InputBuffer = CompressedBytes; + /// decompressor.NextIn = 0; + /// decompressor.AvailableBytesIn = CompressedBytes.Length; + /// + /// decompressor.OutputBuffer = buffer; + /// + /// // pass 1: inflate + /// do + /// { + /// decompressor.NextOut = 0; + /// decompressor.AvailableBytesOut = buffer.Length; + /// rc = decompressor.Inflate(FlushType.None); + /// + /// if (rc != ZlibConstants.Z_OK && rc != ZlibConstants.Z_STREAM_END) + /// throw new Exception("inflating: " + decompressor.Message); + /// + /// ms.Write(decompressor.OutputBuffer, 0, buffer.Length - decompressor.AvailableBytesOut); + /// } + /// while (decompressor.AvailableBytesIn > 0 || decompressor.AvailableBytesOut == 0); + /// + /// // pass 2: finish and flush + /// do + /// { + /// decompressor.NextOut = 0; + /// decompressor.AvailableBytesOut = buffer.Length; + /// rc = decompressor.Inflate(FlushType.Finish); + /// + /// if (rc != ZlibConstants.Z_STREAM_END && rc != ZlibConstants.Z_OK) + /// throw new Exception("inflating: " + decompressor.Message); + /// + /// if (buffer.Length - decompressor.AvailableBytesOut > 0) + /// ms.Write(buffer, 0, buffer.Length - decompressor.AvailableBytesOut); + /// } + /// while (decompressor.AvailableBytesIn > 0 || decompressor.AvailableBytesOut == 0); + /// + /// decompressor.EndInflate(); + /// } + /// + /// + /// + /// The flush to use when inflating. + /// Z_OK if everything goes well. + public int Inflate(FlushType flush) + { + if (istate == null) + throw new ZlibException("No Inflate State!"); + return istate.Inflate(flush); + } + + + /// + /// Ends an inflation session. + /// + /// + /// Call this after successively calling Inflate(). This will cause all buffers to be flushed. + /// After calling this you cannot call Inflate() without a intervening call to one of the + /// InitializeInflate() overloads. + /// + /// Z_OK if everything goes well. + public int EndInflate() + { + if (istate == null) + throw new ZlibException("No Inflate State!"); + int ret = istate.End(); + istate = null; + return ret; + } + + /// + /// I don't know what this does! + /// + /// Z_OK if everything goes well. + public int SyncInflate() + { + if (istate == null) + throw new ZlibException("No Inflate State!"); + return istate.Sync(); + } + + /// + /// Initialize the ZlibCodec for deflation operation. + /// + /// + /// The codec will use the MAX window bits and the default level of compression. + /// + /// + /// + /// int bufferSize = 40000; + /// byte[] CompressedBytes = new byte[bufferSize]; + /// byte[] DecompressedBytes = new byte[bufferSize]; + /// + /// ZlibCodec compressor = new ZlibCodec(); + /// + /// compressor.InitializeDeflate(CompressionLevel.Default); + /// + /// compressor.InputBuffer = System.Text.ASCIIEncoding.ASCII.GetBytes(TextToCompress); + /// compressor.NextIn = 0; + /// compressor.AvailableBytesIn = compressor.InputBuffer.Length; + /// + /// compressor.OutputBuffer = CompressedBytes; + /// compressor.NextOut = 0; + /// compressor.AvailableBytesOut = CompressedBytes.Length; + /// + /// while (compressor.TotalBytesIn != TextToCompress.Length && compressor.TotalBytesOut < bufferSize) + /// { + /// compressor.Deflate(FlushType.None); + /// } + /// + /// while (true) + /// { + /// int rc= compressor.Deflate(FlushType.Finish); + /// if (rc == ZlibConstants.Z_STREAM_END) break; + /// } + /// + /// compressor.EndDeflate(); + /// + /// + /// + /// Z_OK if all goes well. You generally don't need to check the return code. + public int InitializeDeflate() + { + return _InternalInitializeDeflate(true); + } + + /// + /// Initialize the ZlibCodec for deflation operation, using the specified CompressionLevel. + /// + /// + /// The codec will use the maximum window bits (15) and the specified + /// CompressionLevel. It will emit a ZLIB stream as it compresses. + /// + /// The compression level for the codec. + /// Z_OK if all goes well. + public int InitializeDeflate(CompressionLevel level) + { + this.CompressLevel = level; + return _InternalInitializeDeflate(true); + } + + + /// + /// Initialize the ZlibCodec for deflation operation, using the specified CompressionLevel, + /// and the explicit flag governing whether to emit an RFC1950 header byte pair. + /// + /// + /// The codec will use the maximum window bits (15) and the specified CompressionLevel. + /// If you want to generate a zlib stream, you should specify true for + /// wantRfc1950Header. In this case, the library will emit a ZLIB + /// header, as defined in RFC + /// 1950, in the compressed stream. + /// + /// The compression level for the codec. + /// whether to emit an initial RFC1950 byte pair in the compressed stream. + /// Z_OK if all goes well. + public int InitializeDeflate(CompressionLevel level, bool wantRfc1950Header) + { + this.CompressLevel = level; + return _InternalInitializeDeflate(wantRfc1950Header); + } + + + /// + /// Initialize the ZlibCodec for deflation operation, using the specified CompressionLevel, + /// and the specified number of window bits. + /// + /// + /// The codec will use the specified number of window bits and the specified CompressionLevel. + /// + /// The compression level for the codec. + /// the number of window bits to use. If you don't know what this means, don't use this method. + /// Z_OK if all goes well. + public int InitializeDeflate(CompressionLevel level, int bits) + { + this.CompressLevel = level; + this.WindowBits = bits; + return _InternalInitializeDeflate(true); + } + + /// + /// Initialize the ZlibCodec for deflation operation, using the specified + /// CompressionLevel, the specified number of window bits, and the explicit flag + /// governing whether to emit an RFC1950 header byte pair. + /// + /// + /// The compression level for the codec. + /// whether to emit an initial RFC1950 byte pair in the compressed stream. + /// the number of window bits to use. If you don't know what this means, don't use this method. + /// Z_OK if all goes well. + public int InitializeDeflate(CompressionLevel level, int bits, bool wantRfc1950Header) + { + this.CompressLevel = level; + this.WindowBits = bits; + return _InternalInitializeDeflate(wantRfc1950Header); + } + + private int _InternalInitializeDeflate(bool wantRfc1950Header) + { + if (istate != null) throw new ZlibException("You may not call InitializeDeflate() after calling InitializeInflate()."); + dstate = new DeflateManager(); + dstate.WantRfc1950HeaderBytes = wantRfc1950Header; + + return dstate.Initialize(this, this.CompressLevel, this.WindowBits, this.Strategy); + } + + /// + /// Deflate one batch of data. + /// + /// + /// You must have set InputBuffer and OutputBuffer before calling this method. + /// + /// + /// + /// private void DeflateBuffer(CompressionLevel level) + /// { + /// int bufferSize = 1024; + /// byte[] buffer = new byte[bufferSize]; + /// ZlibCodec compressor = new ZlibCodec(); + /// + /// Console.WriteLine("\n============================================"); + /// Console.WriteLine("Size of Buffer to Deflate: {0} bytes.", UncompressedBytes.Length); + /// MemoryStream ms = new MemoryStream(); + /// + /// int rc = compressor.InitializeDeflate(level); + /// + /// compressor.InputBuffer = UncompressedBytes; + /// compressor.NextIn = 0; + /// compressor.AvailableBytesIn = UncompressedBytes.Length; + /// + /// compressor.OutputBuffer = buffer; + /// + /// // pass 1: deflate + /// do + /// { + /// compressor.NextOut = 0; + /// compressor.AvailableBytesOut = buffer.Length; + /// rc = compressor.Deflate(FlushType.None); + /// + /// if (rc != ZlibConstants.Z_OK && rc != ZlibConstants.Z_STREAM_END) + /// throw new Exception("deflating: " + compressor.Message); + /// + /// ms.Write(compressor.OutputBuffer, 0, buffer.Length - compressor.AvailableBytesOut); + /// } + /// while (compressor.AvailableBytesIn > 0 || compressor.AvailableBytesOut == 0); + /// + /// // pass 2: finish and flush + /// do + /// { + /// compressor.NextOut = 0; + /// compressor.AvailableBytesOut = buffer.Length; + /// rc = compressor.Deflate(FlushType.Finish); + /// + /// if (rc != ZlibConstants.Z_STREAM_END && rc != ZlibConstants.Z_OK) + /// throw new Exception("deflating: " + compressor.Message); + /// + /// if (buffer.Length - compressor.AvailableBytesOut > 0) + /// ms.Write(buffer, 0, buffer.Length - compressor.AvailableBytesOut); + /// } + /// while (compressor.AvailableBytesIn > 0 || compressor.AvailableBytesOut == 0); + /// + /// compressor.EndDeflate(); + /// + /// ms.Seek(0, SeekOrigin.Begin); + /// CompressedBytes = new byte[compressor.TotalBytesOut]; + /// ms.Read(CompressedBytes, 0, CompressedBytes.Length); + /// } + /// + /// + /// whether to flush all data as you deflate. Generally you will want to + /// use Z_NO_FLUSH here, in a series of calls to Deflate(), and then call EndDeflate() to + /// flush everything. + /// + /// Z_OK if all goes well. + public int Deflate(FlushType flush) + { + if (dstate == null) + throw new ZlibException("No Deflate State!"); + return dstate.Deflate(flush); + } + + /// + /// End a deflation session. + /// + /// + /// Call this after making a series of one or more calls to Deflate(). All buffers are flushed. + /// + /// Z_OK if all goes well. + public int EndDeflate() + { + if (dstate == null) + throw new ZlibException("No Deflate State!"); + // TODO: dinoch Tue, 03 Nov 2009 15:39 (test this) + //int ret = dstate.End(); + dstate = null; + return ZlibConstants.Z_OK; //ret; + } + + /// + /// Reset a codec for another deflation session. + /// + /// + /// Call this to reset the deflation state. For example if a thread is deflating + /// non-consecutive blocks, you can call Reset() after the Deflate(Sync) of the first + /// block and before the next Deflate(None) of the second block. + /// + /// Z_OK if all goes well. + public void ResetDeflate() + { + if (dstate == null) + throw new ZlibException("No Deflate State!"); + dstate.Reset(); + } + + + /// + /// Set the CompressionStrategy and CompressionLevel for a deflation session. + /// + /// the level of compression to use. + /// the strategy to use for compression. + /// Z_OK if all goes well. + public int SetDeflateParams(CompressionLevel level, CompressionStrategy strategy) + { + if (dstate == null) + throw new ZlibException("No Deflate State!"); + return dstate.SetParams(level, strategy); + } + + + /// + /// Set the dictionary to be used for either Inflation or Deflation. + /// + /// The dictionary bytes to use. + /// Z_OK if all goes well. + public int SetDictionary(byte[] dictionary) + { + if (istate != null) + return istate.SetDictionary(dictionary); + + if (dstate != null) + return dstate.SetDictionary(dictionary); + + throw new ZlibException("No Inflate or Deflate state!"); + } + + // Flush as much pending output as possible. All deflate() output goes + // through this function so some applications may wish to modify it + // to avoid allocating a large strm->next_out buffer and copying into it. + // (See also read_buf()). + internal void flush_pending() + { + int len = dstate.pendingCount; + + if (len > AvailableBytesOut) + len = AvailableBytesOut; + if (len == 0) + return; + + if (dstate.pending.Length <= dstate.nextPending || + OutputBuffer.Length <= NextOut || + dstate.pending.Length < (dstate.nextPending + len) || + OutputBuffer.Length < (NextOut + len)) + { + throw new ZlibException(String.Format("Invalid State. (pending.Length={0}, pendingCount={1})", + dstate.pending.Length, dstate.pendingCount)); + } + + Array.Copy(dstate.pending, dstate.nextPending, OutputBuffer, NextOut, len); + + NextOut += len; + dstate.nextPending += len; + TotalBytesOut += len; + AvailableBytesOut -= len; + dstate.pendingCount -= len; + if (dstate.pendingCount == 0) + { + dstate.nextPending = 0; + } + } + + // Read a new buffer from the current input stream, update the adler32 + // and total number of bytes read. All deflate() input goes through + // this function so some applications may wish to modify it to avoid + // allocating a large strm->next_in buffer and copying from it. + // (See also flush_pending()). + internal int read_buf(byte[] buf, int start, int size) + { + int len = AvailableBytesIn; + + if (len > size) + len = size; + if (len == 0) + return 0; + + AvailableBytesIn -= len; + + if (dstate.WantRfc1950HeaderBytes) + { + _Adler32 = Adler.Adler32(_Adler32, InputBuffer, NextIn, len); + } + Array.Copy(InputBuffer, NextIn, buf, start, len); + NextIn += len; + TotalBytesIn += len; + return len; + } + + } +} \ No newline at end of file diff --git a/ROMVault2/SupportedFiles/Zip/ZLib/ZlibConstants.cs b/ROMVault2/SupportedFiles/Zip/ZLib/ZlibConstants.cs new file mode 100644 index 0000000..964f977 --- /dev/null +++ b/ROMVault2/SupportedFiles/Zip/ZLib/ZlibConstants.cs @@ -0,0 +1,126 @@ +// ZlibConstants.cs +// ------------------------------------------------------------------ +// +// Copyright (c) 2009 Dino Chiesa and Microsoft Corporation. +// All rights reserved. +// +// This code module is part of DotNetZip, a zipfile class library. +// +// ------------------------------------------------------------------ +// +// This code is licensed under the Microsoft Public License. +// See the file License.txt for the license details. +// More info on: http://dotnetzip.codeplex.com +// +// ------------------------------------------------------------------ +// +// last saved (in emacs): +// Time-stamp: <2009-November-03 18:50:19> +// +// ------------------------------------------------------------------ +// +// This module defines constants used by the zlib class library. This +// code is derived from the jzlib implementation of zlib, but +// significantly modified. In keeping with the license for jzlib, the +// copyright to that code is included here. +// +// ------------------------------------------------------------------ +// +// Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// 2. 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. +// +// 3. The names of the authors may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 JCRAFT, +// INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE 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. +// +// ----------------------------------------------------------------------- +// +// This program is based on zlib-1.1.3; credit to authors +// Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) +// and contributors of zlib. +// +// ----------------------------------------------------------------------- + + +namespace ROMVault2.SupportedFiles.Zip.ZLib +{ + /// + /// A bunch of constants used in the Zlib interface. + /// + public static class ZlibConstants + { + /// + /// The maximum number of window bits for the Deflate algorithm. + /// + public const int WindowBitsMax = 15; // 32K LZ77 window + + /// + /// The default number of window bits for the Deflate algorithm. + /// + public const int WindowBitsDefault = WindowBitsMax; + + /// + /// indicates everything is A-OK + /// + public const int Z_OK = 0; + + /// + /// Indicates that the last operation reached the end of the stream. + /// + public const int Z_STREAM_END = 1; + + /// + /// The operation ended in need of a dictionary. + /// + public const int Z_NEED_DICT = 2; + + /// + /// There was an error with the stream - not enough data, not open and readable, etc. + /// + public const int Z_STREAM_ERROR = -2; + + /// + /// There was an error with the data - not enough data, bad data, etc. + /// + public const int Z_DATA_ERROR = -3; + + /// + /// There was an error with the working buffer. + /// + public const int Z_BUF_ERROR = -5; + + /// + /// The size of the working buffer used in the ZlibCodec class. Defaults to 8192 bytes. + /// +#if NETCF + public const int WorkingBufferSizeDefault = 8192; +#else + public const int WorkingBufferSizeDefault = 16384; +#endif + /// + /// The minimum size of the working buffer used in the ZlibCodec class. Currently it is 128 bytes. + /// + public const int WorkingBufferSizeMin = 1024; + } + +} + diff --git a/ROMVault2/SupportedFiles/Zip/ZLib/ZlibStream.cs b/ROMVault2/SupportedFiles/Zip/ZLib/ZlibStream.cs new file mode 100644 index 0000000..1ce03e5 --- /dev/null +++ b/ROMVault2/SupportedFiles/Zip/ZLib/ZlibStream.cs @@ -0,0 +1,725 @@ +// ZlibStream.cs +// ------------------------------------------------------------------ +// +// Copyright (c) 2009 Dino Chiesa and Microsoft Corporation. +// All rights reserved. +// +// This code module is part of DotNetZip, a zipfile class library. +// +// ------------------------------------------------------------------ +// +// This code is licensed under the Microsoft Public License. +// See the file License.txt for the license details. +// More info on: http://dotnetzip.codeplex.com +// +// ------------------------------------------------------------------ +// +// last saved (in emacs): +// Time-stamp: <2011-July-31 14:53:33> +// +// ------------------------------------------------------------------ +// +// This module defines the ZlibStream class, which is similar in idea to +// the System.IO.Compression.DeflateStream and +// System.IO.Compression.GZipStream classes in the .NET BCL. +// +// ------------------------------------------------------------------ + +using System; +using System.IO; + +namespace ROMVault2.SupportedFiles.Zip.ZLib +{ + + /// + /// Represents a Zlib stream for compression or decompression. + /// + /// + /// + /// + /// The ZlibStream is a Decorator on a . It adds ZLIB compression or decompression to any + /// stream. + /// + /// + /// Using this stream, applications can compress or decompress data via + /// stream Read() and Write() operations. Either compresssion or + /// decompression can occur through either reading or writing. The compression + /// format used is ZLIB, which is documented in IETF RFC 1950, "ZLIB Compressed + /// Data Format Specification version 3.3". This implementation of ZLIB always uses + /// DEFLATE as the compression method. (see IETF RFC 1951, "DEFLATE + /// Compressed Data Format Specification version 1.3.") + /// + /// + /// The ZLIB format allows for varying compression methods, window sizes, and dictionaries. + /// This implementation always uses the DEFLATE compression method, a preset dictionary, + /// and 15 window bits by default. + /// + /// + /// + /// This class is similar to , except that it adds the + /// RFC1950 header and trailer bytes to a compressed stream when compressing, or expects + /// the RFC1950 header and trailer bytes when decompressing. It is also similar to the + /// . + /// + /// + /// + /// + public class ZlibStream : System.IO.Stream + { + internal ZlibBaseStream _baseStream; + bool _disposed; + + /// + /// Create a ZlibStream using the specified CompressionMode. + /// + /// + /// + /// + /// When mode is CompressionMode.Compress, the ZlibStream + /// will use the default compression level. The "captive" stream will be + /// closed when the ZlibStream is closed. + /// + /// + /// + /// + /// + /// This example uses a ZlibStream to compress a file, and writes the + /// compressed data to another file. + /// + /// using (System.IO.Stream input = System.IO.File.OpenRead(fileToCompress)) + /// { + /// using (var raw = System.IO.File.Create(fileToCompress + ".zlib")) + /// { + /// using (Stream compressor = new ZlibStream(raw, CompressionMode.Compress)) + /// { + /// byte[] buffer = new byte[WORKING_BUFFER_SIZE]; + /// int n; + /// while ((n= input.Read(buffer, 0, buffer.Length)) != 0) + /// { + /// compressor.Write(buffer, 0, n); + /// } + /// } + /// } + /// } + /// + /// + /// Using input As Stream = File.OpenRead(fileToCompress) + /// Using raw As FileStream = File.Create(fileToCompress & ".zlib") + /// Using compressor As Stream = New ZlibStream(raw, CompressionMode.Compress) + /// Dim buffer As Byte() = New Byte(4096) {} + /// Dim n As Integer = -1 + /// Do While (n <> 0) + /// If (n > 0) Then + /// compressor.Write(buffer, 0, n) + /// End If + /// n = input.Read(buffer, 0, buffer.Length) + /// Loop + /// End Using + /// End Using + /// End Using + /// + /// + /// + /// The stream which will be read or written. + /// Indicates whether the ZlibStream will compress or decompress. + public ZlibStream(System.IO.Stream stream, CompressionMode mode) + : this(stream, mode, CompressionLevel.Default, false) + { + } + + /// + /// Create a ZlibStream using the specified CompressionMode and + /// the specified CompressionLevel. + /// + /// + /// + /// + /// + /// When mode is CompressionMode.Decompress, the level parameter is ignored. + /// The "captive" stream will be closed when the ZlibStream is closed. + /// + /// + /// + /// + /// + /// This example uses a ZlibStream to compress data from a file, and writes the + /// compressed data to another file. + /// + /// + /// using (System.IO.Stream input = System.IO.File.OpenRead(fileToCompress)) + /// { + /// using (var raw = System.IO.File.Create(fileToCompress + ".zlib")) + /// { + /// using (Stream compressor = new ZlibStream(raw, + /// CompressionMode.Compress, + /// CompressionLevel.BestCompression)) + /// { + /// byte[] buffer = new byte[WORKING_BUFFER_SIZE]; + /// int n; + /// while ((n= input.Read(buffer, 0, buffer.Length)) != 0) + /// { + /// compressor.Write(buffer, 0, n); + /// } + /// } + /// } + /// } + /// + /// + /// + /// Using input As Stream = File.OpenRead(fileToCompress) + /// Using raw As FileStream = File.Create(fileToCompress & ".zlib") + /// Using compressor As Stream = New ZlibStream(raw, CompressionMode.Compress, CompressionLevel.BestCompression) + /// Dim buffer As Byte() = New Byte(4096) {} + /// Dim n As Integer = -1 + /// Do While (n <> 0) + /// If (n > 0) Then + /// compressor.Write(buffer, 0, n) + /// End If + /// n = input.Read(buffer, 0, buffer.Length) + /// Loop + /// End Using + /// End Using + /// End Using + /// + /// + /// + /// The stream to be read or written while deflating or inflating. + /// Indicates whether the ZlibStream will compress or decompress. + /// A tuning knob to trade speed for effectiveness. + public ZlibStream(System.IO.Stream stream, CompressionMode mode, CompressionLevel level) + : this(stream, mode, level, false) + { + } + + /// + /// Create a ZlibStream using the specified CompressionMode, and + /// explicitly specify whether the captive stream should be left open after + /// Deflation or Inflation. + /// + /// + /// + /// + /// + /// When mode is CompressionMode.Compress, the ZlibStream will use + /// the default compression level. + /// + /// + /// + /// This constructor allows the application to request that the captive stream + /// remain open after the deflation or inflation occurs. By default, after + /// Close() is called on the stream, the captive stream is also + /// closed. In some cases this is not desired, for example if the stream is a + /// that will be re-read after + /// compression. Specify true for the parameter to leave the stream + /// open. + /// + /// + /// + /// See the other overloads of this constructor for example code. + /// + /// + /// + /// + /// The stream which will be read or written. This is called the + /// "captive" stream in other places in this documentation. + /// Indicates whether the ZlibStream will compress or decompress. + /// true if the application would like the stream to remain + /// open after inflation/deflation. + public ZlibStream(System.IO.Stream stream, CompressionMode mode, bool leaveOpen) + : this(stream, mode, CompressionLevel.Default, leaveOpen) + { + } + + /// + /// Create a ZlibStream using the specified CompressionMode + /// and the specified CompressionLevel, and explicitly specify + /// whether the stream should be left open after Deflation or Inflation. + /// + /// + /// + /// + /// + /// This constructor allows the application to request that the captive + /// stream remain open after the deflation or inflation occurs. By + /// default, after Close() is called on the stream, the captive + /// stream is also closed. In some cases this is not desired, for example + /// if the stream is a that will be + /// re-read after compression. Specify true for the parameter to leave the stream open. + /// + /// + /// + /// When mode is CompressionMode.Decompress, the level parameter is + /// ignored. + /// + /// + /// + /// + /// + /// + /// This example shows how to use a ZlibStream to compress the data from a file, + /// and store the result into another file. The filestream remains open to allow + /// additional data to be written to it. + /// + /// + /// using (var output = System.IO.File.Create(fileToCompress + ".zlib")) + /// { + /// using (System.IO.Stream input = System.IO.File.OpenRead(fileToCompress)) + /// { + /// using (Stream compressor = new ZlibStream(output, CompressionMode.Compress, CompressionLevel.BestCompression, true)) + /// { + /// byte[] buffer = new byte[WORKING_BUFFER_SIZE]; + /// int n; + /// while ((n= input.Read(buffer, 0, buffer.Length)) != 0) + /// { + /// compressor.Write(buffer, 0, n); + /// } + /// } + /// } + /// // can write additional data to the output stream here + /// } + /// + /// + /// Using output As FileStream = File.Create(fileToCompress & ".zlib") + /// Using input As Stream = File.OpenRead(fileToCompress) + /// Using compressor As Stream = New ZlibStream(output, CompressionMode.Compress, CompressionLevel.BestCompression, True) + /// Dim buffer As Byte() = New Byte(4096) {} + /// Dim n As Integer = -1 + /// Do While (n <> 0) + /// If (n > 0) Then + /// compressor.Write(buffer, 0, n) + /// End If + /// n = input.Read(buffer, 0, buffer.Length) + /// Loop + /// End Using + /// End Using + /// ' can write additional data to the output stream here. + /// End Using + /// + /// + /// + /// The stream which will be read or written. + /// + /// Indicates whether the ZlibStream will compress or decompress. + /// + /// + /// true if the application would like the stream to remain open after + /// inflation/deflation. + /// + /// + /// + /// A tuning knob to trade speed for effectiveness. This parameter is + /// effective only when mode is CompressionMode.Compress. + /// + public ZlibStream(System.IO.Stream stream, CompressionMode mode, CompressionLevel level, bool leaveOpen) + { + _baseStream = new ZlibBaseStream(stream, mode, level, ZlibStreamFlavor.ZLIB, leaveOpen); + } + + #region Zlib properties + + /// + /// This property sets the flush behavior on the stream. + /// Sorry, though, not sure exactly how to describe all the various settings. + /// + virtual public FlushType FlushMode + { + get { return (this._baseStream._flushMode); } + set + { + if (_disposed) throw new ObjectDisposedException("ZlibStream"); + this._baseStream._flushMode = value; + } + } + + /// + /// The size of the working buffer for the compression codec. + /// + /// + /// + /// + /// The working buffer is used for all stream operations. The default size is + /// 1024 bytes. The minimum size is 128 bytes. You may get better performance + /// with a larger buffer. Then again, you might not. You would have to test + /// it. + /// + /// + /// + /// Set this before the first call to Read() or Write() on the + /// stream. If you try to set it afterwards, it will throw. + /// + /// + public int BufferSize + { + get + { + return this._baseStream._bufferSize; + } + set + { + if (_disposed) throw new ObjectDisposedException("ZlibStream"); + if (this._baseStream._workingBuffer != null) + throw new ZlibException("The working buffer is already set."); + if (value < ZlibConstants.WorkingBufferSizeMin) + throw new ZlibException(String.Format("Don't be silly. {0} bytes?? Use a bigger buffer, at least {1}.", value, ZlibConstants.WorkingBufferSizeMin)); + this._baseStream._bufferSize = value; + } + } + + /// Returns the total number of bytes input so far. + virtual public long TotalIn + { + get { return this._baseStream._z.TotalBytesIn; } + } + + /// Returns the total number of bytes output so far. + virtual public long TotalOut + { + get { return this._baseStream._z.TotalBytesOut; } + } + + #endregion + + #region System.IO.Stream methods + + /// + /// Dispose the stream. + /// + /// + /// + /// This may or may not result in a Close() call on the captive + /// stream. See the constructors that have a leaveOpen parameter + /// for more information. + /// + /// + /// This method may be invoked in two distinct scenarios. If disposing + /// == true, the method has been called directly or indirectly by a + /// user's code, for example via the public Dispose() method. In this + /// case, both managed and unmanaged resources can be referenced and + /// disposed. If disposing == false, the method has been called by the + /// runtime from inside the object finalizer and this method should not + /// reference other objects; in that case only unmanaged resources must + /// be referenced or disposed. + /// + /// + /// + /// indicates whether the Dispose method was invoked by user code. + /// + protected override void Dispose(bool disposing) + { + try + { + if (!_disposed) + { + if (disposing && (this._baseStream != null)) + this._baseStream.Close(); + _disposed = true; + } + } + finally + { + base.Dispose(disposing); + } + } + + + /// + /// Indicates whether the stream can be read. + /// + /// + /// The return value depends on whether the captive stream supports reading. + /// + public override bool CanRead + { + get + { + if (_disposed) throw new ObjectDisposedException("ZlibStream"); + return _baseStream._stream.CanRead; + } + } + + /// + /// Indicates whether the stream supports Seek operations. + /// + /// + /// Always returns false. + /// + public override bool CanSeek + { + get { return false; } + } + + /// + /// Indicates whether the stream can be written. + /// + /// + /// The return value depends on whether the captive stream supports writing. + /// + public override bool CanWrite + { + get + { + if (_disposed) throw new ObjectDisposedException("ZlibStream"); + return _baseStream._stream.CanWrite; + } + } + + /// + /// Flush the stream. + /// + public override void Flush() + { + if (_disposed) throw new ObjectDisposedException("ZlibStream"); + _baseStream.Flush(); + } + + /// + /// Reading this property always throws a . + /// + public override long Length + { + get { throw new NotSupportedException(); } + } + + /// + /// The position of the stream pointer. + /// + /// + /// + /// Setting this property always throws a . Reading will return the total bytes + /// written out, if used in writing, or the total bytes read in, if used in + /// reading. The count may refer to compressed bytes or uncompressed bytes, + /// depending on how you've used the stream. + /// + public override long Position + { + get + { + if (this._baseStream._streamMode == ZlibBaseStream.StreamMode.Writer) + return this._baseStream._z.TotalBytesOut; + if (this._baseStream._streamMode == ZlibBaseStream.StreamMode.Reader) + return this._baseStream._z.TotalBytesIn; + return 0; + } + + set { throw new NotSupportedException(); } + } + + /// + /// Read data from the stream. + /// + /// + /// + /// + /// + /// If you wish to use the ZlibStream to compress data while reading, + /// you can create a ZlibStream with CompressionMode.Compress, + /// providing an uncompressed data stream. Then call Read() on that + /// ZlibStream, and the data read will be compressed. If you wish to + /// use the ZlibStream to decompress data while reading, you can create + /// a ZlibStream with CompressionMode.Decompress, providing a + /// readable compressed data stream. Then call Read() on that + /// ZlibStream, and the data will be decompressed as it is read. + /// + /// + /// + /// A ZlibStream can be used for Read() or Write(), but + /// not both. + /// + /// + /// + /// + /// + /// The buffer into which the read data should be placed. + /// + /// + /// the offset within that data array to put the first byte read. + /// + /// the number of bytes to read. + /// + /// the number of bytes read + public override int Read(byte[] buffer, int offset, int count) + { + if (_disposed) throw new ObjectDisposedException("ZlibStream"); + return _baseStream.Read(buffer, offset, count); + } + + /// + /// Calling this method always throws a . + /// + /// + /// The offset to seek to.... + /// IF THIS METHOD ACTUALLY DID ANYTHING. + /// + /// + /// The reference specifying how to apply the offset.... IF + /// THIS METHOD ACTUALLY DID ANYTHING. + /// + /// + /// nothing. This method always throws. + public override long Seek(long offset, System.IO.SeekOrigin origin) + { + throw new NotSupportedException(); + } + + /// + /// Calling this method always throws a . + /// + /// + /// The new value for the stream length.... IF + /// THIS METHOD ACTUALLY DID ANYTHING. + /// + public override void SetLength(long value) + { + throw new NotSupportedException(); + } + + /// + /// Write data to the stream. + /// + /// + /// + /// + /// + /// If you wish to use the ZlibStream to compress data while writing, + /// you can create a ZlibStream with CompressionMode.Compress, + /// and a writable output stream. Then call Write() on that + /// ZlibStream, providing uncompressed data as input. The data sent to + /// the output stream will be the compressed form of the data written. If you + /// wish to use the ZlibStream to decompress data while writing, you + /// can create a ZlibStream with CompressionMode.Decompress, and a + /// writable output stream. Then call Write() on that stream, + /// providing previously compressed data. The data sent to the output stream + /// will be the decompressed form of the data written. + /// + /// + /// + /// A ZlibStream can be used for Read() or Write(), but not both. + /// + /// + /// The buffer holding data to write to the stream. + /// the offset within that data array to find the first byte to write. + /// the number of bytes to write. + public override void Write(byte[] buffer, int offset, int count) + { + if (_disposed) throw new ObjectDisposedException("ZlibStream"); + _baseStream.Write(buffer, offset, count); + } + #endregion + + + /// + /// Compress a string into a byte array using ZLIB. + /// + /// + /// + /// Uncompress it with . + /// + /// + /// + /// + /// + /// + /// + /// A string to compress. The string will first be encoded + /// using UTF8, then compressed. + /// + /// + /// The string in compressed form + public static byte[] CompressString(String s) + { + using (var ms = new MemoryStream()) + { + Stream compressor = + new ZlibStream(ms, CompressionMode.Compress, CompressionLevel.BestCompression); + ZlibBaseStream.CompressString(s, compressor); + return ms.ToArray(); + } + } + + + /// + /// Compress a byte array into a new byte array using ZLIB. + /// + /// + /// + /// Uncompress it with . + /// + /// + /// + /// + /// + /// + /// A buffer to compress. + /// + /// + /// The data in compressed form + public static byte[] CompressBuffer(byte[] b) + { + using (var ms = new MemoryStream()) + { + Stream compressor = + new ZlibStream( ms, CompressionMode.Compress, CompressionLevel.BestCompression ); + + ZlibBaseStream.CompressBuffer(b, compressor); + return ms.ToArray(); + } + } + + + /// + /// Uncompress a ZLIB-compressed byte array into a single string. + /// + /// + /// + /// + /// + /// + /// A buffer containing ZLIB-compressed data. + /// + /// + /// The uncompressed string + public static String UncompressString(byte[] compressed) + { + using (var input = new MemoryStream(compressed)) + { + Stream decompressor = + new ZlibStream(input, CompressionMode.Decompress); + + return ZlibBaseStream.UncompressString(compressed, decompressor); + } + } + + + /// + /// Uncompress a ZLIB-compressed byte array into a byte array. + /// + /// + /// + /// + /// + /// + /// A buffer containing ZLIB-compressed data. + /// + /// + /// The data in uncompressed form + public static byte[] UncompressBuffer(byte[] compressed) + { + using (var input = new MemoryStream(compressed)) + { + Stream decompressor = + new ZlibStream( input, CompressionMode.Decompress ); + + return ZlibBaseStream.UncompressBuffer(compressed, decompressor); + } + } + + } + + +} \ No newline at end of file diff --git a/ROMVault2/SupportedFiles/Zip/zipFile.cs b/ROMVault2/SupportedFiles/Zip/zipFile.cs new file mode 100644 index 0000000..a31b24d --- /dev/null +++ b/ROMVault2/SupportedFiles/Zip/zipFile.cs @@ -0,0 +1,1549 @@ +/****************************************************** + * ROMVault2 is written by Gordon J. * + * Contact gordon@romvault.com * + * Copyright 2014 * + ******************************************************/ + +using System; +using System.Collections.Generic; +using System.IO; +using System.Security.Cryptography; +using System.Text; +using ROMVault2.SupportedFiles.Zip.ZLib; + +// UInt16 = ushort +// UInt32 = uint +// ULong = ulong + +namespace ROMVault2.SupportedFiles.Zip +{ + + public class ZipFile + { + const int Buffersize = 4096 * 128; + private static byte[] _buffer; + + private const uint LocalFileHeaderSignature = 0x04034b50; + private const uint CentralDirectoryHeaderSigniature = 0x02014b50; + private const uint EndOfCentralDirSignature = 0x06054b50; + private const uint Zip64EndOfCentralDirSignatue = 0x06064b50; + private const uint Zip64EndOfCentralDirectoryLocator = 0x07064b50; + + class LocalFile + { + private readonly Stream _zipFs; + public string FileName { get; private set; } + public ushort _generalPurposeBitFlag { get; private set; } + private ushort _compressionMethod; + private ushort _lastModFileTime; + private ushort _lastModFileDate; + public byte[] CRC { get; private set; } + private ulong _compressedSize; + public ulong UncompressedSize { get; private set; } + public ulong RelativeOffsetOfLocalHeader; // only in centeral directory + + private ulong _crc32Location; + private ulong _extraLocation; + private ulong _dataLocation; + + public bool Zip64 { get; private set; } + public bool TrrntZip { get; private set; } + + public byte[] sha1 { get; private set; } + public byte[] md5 { get; private set; } + + public ZipReturn FileStatus = ZipReturn.ZipUntested; + public LocalFile(Stream zipFs) + { + _zipFs = zipFs; + } + public LocalFile(Stream zipFs, string filename) + { + Zip64 = false; + _zipFs = zipFs; + _generalPurposeBitFlag = 2; // Maximum Compression Deflating + _compressionMethod = 8; // Compression Method Deflate + _lastModFileTime = 48128; + _lastModFileDate = 8600; + + FileName = filename; + } + + + public ZipReturn CenteralDirectoryRead() + { + try + { + BinaryReader br = new BinaryReader(_zipFs); + + uint thisSignature = br.ReadUInt32(); + if (thisSignature != CentralDirectoryHeaderSigniature) + return ZipReturn.ZipCenteralDirError; + + br.ReadUInt16(); // Version Made By + + br.ReadUInt16(); // Version Needed To Extract + + + _generalPurposeBitFlag = br.ReadUInt16(); + _compressionMethod = br.ReadUInt16(); + if (_compressionMethod != 8 && _compressionMethod != 0) + return ZipReturn.ZipUnsupportedCompression; + + _lastModFileTime = br.ReadUInt16(); + _lastModFileDate = br.ReadUInt16(); + CRC = ReadCRC(br); + + _compressedSize = br.ReadUInt32(); + UncompressedSize = br.ReadUInt32(); + + ushort fileNameLength = br.ReadUInt16(); + ushort extraFieldLength = br.ReadUInt16(); + ushort fileCommentLength = br.ReadUInt16(); + + br.ReadUInt16(); // diskNumberStart + br.ReadUInt16(); // internalFileAttributes + br.ReadUInt32(); // externalFileAttributes + + RelativeOffsetOfLocalHeader = br.ReadUInt32(); + + byte[] bFileName = br.ReadBytes(fileNameLength); + FileName = (_generalPurposeBitFlag & (1 << 11)) == 0 ? + GetString(bFileName) : + Encoding.UTF8.GetString(bFileName, 0, fileNameLength); + + Byte[] extraField = br.ReadBytes(extraFieldLength); + br.ReadBytes(fileCommentLength); // File Comments + + int pos = 0; + while (extraFieldLength > pos) + { + ushort type = BitConverter.ToUInt16(extraField, pos); + pos += 2; + ushort blockLength = BitConverter.ToUInt16(extraField, pos); + pos += 2; + switch (type) + { + case 0x0001: + Zip64 = true; + if (UncompressedSize == 0xffffffff) + { + UncompressedSize = BitConverter.ToUInt64(extraField, pos); + pos += 8; + } + if (_compressedSize == 0xffffffff) + { + _compressedSize = BitConverter.ToUInt64(extraField, pos); + pos += 8; + } + if (RelativeOffsetOfLocalHeader == 0xffffffff) + { + RelativeOffsetOfLocalHeader = BitConverter.ToUInt64(extraField, pos); + pos += 8; + } + break; + case 0x7075: + //byte version = extraField[pos]; + pos += 1; + uint nameCRC32 = BitConverter.ToUInt32(extraField, pos); + pos += 4; + + CRC32 crcTest = new CRC32(); + crcTest.SlurpBlock(bFileName, 0, fileNameLength); + uint fCRC = crcTest.Crc32ResultU; + + if (nameCRC32 != fCRC) return ZipReturn.ZipCenteralDirError; + + int charLen = blockLength - 5; + + FileName = Encoding.UTF8.GetString(extraField, pos, charLen); + pos += charLen; + + break; + default: + pos += blockLength; + break; + } + } + + return ZipReturn.ZipGood; + } + catch + { + return ZipReturn.ZipCenteralDirError; + } + + } + public void CenteralDirectoryWrite(Stream crcStream) + { + BinaryWriter bw = new BinaryWriter(crcStream); + + const uint header = 0x2014B50; + + List extraField = new List(); + + uint cdUncompressedSize; + if (UncompressedSize >= 0xffffffff) + { + Zip64 = true; + cdUncompressedSize = 0xffffffff; + extraField.AddRange(BitConverter.GetBytes(UncompressedSize)); + } + else + cdUncompressedSize = (uint)UncompressedSize; + + uint cdCompressedSize; + if (_compressedSize >= 0xffffffff) + { + Zip64 = true; + cdCompressedSize = 0xffffffff; + extraField.AddRange(BitConverter.GetBytes(_compressedSize)); + } + else + cdCompressedSize = (uint)_compressedSize; + + uint cdRelativeOffsetOfLocalHeader; + if (RelativeOffsetOfLocalHeader >= 0xffffffff) + { + Zip64 = true; + cdRelativeOffsetOfLocalHeader = 0xffffffff; + extraField.AddRange(BitConverter.GetBytes(RelativeOffsetOfLocalHeader)); + } + else + cdRelativeOffsetOfLocalHeader = (uint)RelativeOffsetOfLocalHeader; + + + if (extraField.Count > 0) + { + ushort exfl = (ushort)extraField.Count; + extraField.InsertRange(0, BitConverter.GetBytes((ushort)0x0001)); + extraField.InsertRange(2, BitConverter.GetBytes(exfl)); + } + ushort extraFieldLength = (ushort)extraField.Count; + + byte[] bFileName; + if (IsUnicode(FileName)) + { + _generalPurposeBitFlag |= 1 << 11; + bFileName = Encoding.UTF8.GetBytes(FileName); + } + else + bFileName = GetBytes(FileName); + ushort fileNameLength = (ushort)bFileName.Length; + + ushort versionNeededToExtract = (ushort)(Zip64 ? 45 : 20); + + bw.Write(header); + bw.Write((ushort)0); + bw.Write(versionNeededToExtract); + bw.Write(_generalPurposeBitFlag); + bw.Write(_compressionMethod); + bw.Write(_lastModFileTime); + bw.Write(_lastModFileDate); + bw.Write(CRC[3]); + bw.Write(CRC[2]); + bw.Write(CRC[1]); + bw.Write(CRC[0]); + bw.Write(cdCompressedSize); + bw.Write(cdUncompressedSize); + bw.Write(fileNameLength); + bw.Write(extraFieldLength); + bw.Write((ushort)0); // file comment length + bw.Write((ushort)0); // disk number start + bw.Write((ushort)0); // internal file attributes + bw.Write((uint)0); // external file attributes + bw.Write(cdRelativeOffsetOfLocalHeader); + + bw.Write(bFileName, 0, fileNameLength); + bw.Write(extraField.ToArray(), 0, extraFieldLength); + // No File Comment + } + + + public ZipReturn LocalFileHeaderRead() + { + try + { + TrrntZip = true; + + BinaryReader br = new BinaryReader(_zipFs); + + _zipFs.Position = (long)RelativeOffsetOfLocalHeader; + uint thisSignature = br.ReadUInt32(); + if (thisSignature != LocalFileHeaderSignature) + return ZipReturn.ZipLocalFileHeaderError; + + br.ReadUInt16(); // version needed to extract + ushort generalPurposeBitFlagLocal = br.ReadUInt16(); + if (generalPurposeBitFlagLocal != _generalPurposeBitFlag) TrrntZip = false; + + ushort tshort = br.ReadUInt16(); + if (tshort != _compressionMethod) return ZipReturn.ZipLocalFileHeaderError; + + tshort = br.ReadUInt16(); + if (tshort != _lastModFileTime) return ZipReturn.ZipLocalFileHeaderError; + + tshort = br.ReadUInt16(); + if (tshort != _lastModFileDate) return ZipReturn.ZipLocalFileHeaderError; + + byte[] tCRC = ReadCRC(br); + if (((_generalPurposeBitFlag & 8) == 0) && !ByteArrCompare(tCRC, CRC)) return ZipReturn.ZipLocalFileHeaderError; + + uint tCompressedSize = br.ReadUInt32(); + if (Zip64 && tCompressedSize != 0xffffffff && tCompressedSize != _compressedSize) // if Zip64 File then the compressedSize should be 0xffffffff + return ZipReturn.ZipLocalFileHeaderError; + if ((_generalPurposeBitFlag & 8) == 8 && tCompressedSize != 0) // if bit 4 set then no compressedSize is set yet + return ZipReturn.ZipLocalFileHeaderError; + if (!Zip64 && (_generalPurposeBitFlag & 8) != 8 && tCompressedSize != _compressedSize) // check the compressedSize + return ZipReturn.ZipLocalFileHeaderError; + + + + uint tUnCompressedSize = br.ReadUInt32(); + if (Zip64 && tUnCompressedSize != 0xffffffff && tUnCompressedSize != UncompressedSize) // if Zip64 File then the unCompressedSize should be 0xffffffff + return ZipReturn.ZipLocalFileHeaderError; + if ((_generalPurposeBitFlag & 8) == 8 && tUnCompressedSize != 0) // if bit 4 set then no unCompressedSize is set yet + return ZipReturn.ZipLocalFileHeaderError; + if (!Zip64 && (_generalPurposeBitFlag & 8) != 8 && tUnCompressedSize != UncompressedSize) // check the unCompressedSize + return ZipReturn.ZipLocalFileHeaderError; + + ushort fileNameLength = br.ReadUInt16(); + ushort extraFieldLength = br.ReadUInt16(); + + + byte[] bFileName = br.ReadBytes(fileNameLength); + string tFileName = (generalPurposeBitFlagLocal & (1 << 11)) == 0 ? + GetString(bFileName) : + Encoding.UTF8.GetString(bFileName, 0, fileNameLength); + + byte[] extraField = br.ReadBytes(extraFieldLength); + + + Zip64 = false; + int pos = 0; + while (extraFieldLength > pos) + { + ushort type = BitConverter.ToUInt16(extraField, pos); + pos += 2; + ushort blockLength = BitConverter.ToUInt16(extraField, pos); + pos += 2; + switch (type) + { + case 0x0001: + Zip64 = true; + if (tUnCompressedSize == 0xffffffff) + { + ulong tLong = BitConverter.ToUInt64(extraField, pos); + if (tLong != UncompressedSize) return ZipReturn.ZipLocalFileHeaderError; + pos += 8; + } + if (tCompressedSize == 0xffffffff) + { + ulong tLong = BitConverter.ToUInt64(extraField, pos); + if (tLong != _compressedSize) return ZipReturn.ZipLocalFileHeaderError; + pos += 8; + } + break; + case 0x7075: + //byte version = extraField[pos]; + pos += 1; + uint nameCRC32 = BitConverter.ToUInt32(extraField, pos); + pos += 4; + + CRC32 crcTest = new CRC32(); + crcTest.SlurpBlock(bFileName, 0, fileNameLength); + uint fCRC = crcTest.Crc32ResultU; + + if (nameCRC32 != fCRC) return ZipReturn.ZipLocalFileHeaderError; + + int charLen = blockLength - 5; + + tFileName = Encoding.UTF8.GetString(extraField, pos, charLen); + pos += charLen; + + break; + default: + pos += blockLength; + break; + } + } + + if (!CompareString(FileName, tFileName)) return ZipReturn.ZipLocalFileHeaderError; + + _dataLocation = (ulong)_zipFs.Position; + + if ((_generalPurposeBitFlag & 8) == 0) return ZipReturn.ZipGood; + + _zipFs.Position += (long)_compressedSize; + + tCRC = ReadCRC(br); + if (!ByteArrCompare(tCRC, new byte[] { 0x50, 0x4b, 0x07, 0x08 })) + tCRC = ReadCRC(br); + + if (!ByteArrCompare(tCRC, CRC)) return ZipReturn.ZipLocalFileHeaderError; + + uint tint = br.ReadUInt32(); + if (tint != _compressedSize) return ZipReturn.ZipLocalFileHeaderError; + + tint = br.ReadUInt32(); + if (tint != UncompressedSize) return ZipReturn.ZipLocalFileHeaderError; + + return ZipReturn.ZipGood; + } + catch + { + return ZipReturn.ZipLocalFileHeaderError; + } + + + } + public ZipReturn LocalFileHeaderReadQuick() + { + try + { + TrrntZip = true; + + BinaryReader br = new BinaryReader(_zipFs); + + _zipFs.Position = (long)RelativeOffsetOfLocalHeader; + uint thisSignature = br.ReadUInt32(); + if (thisSignature != LocalFileHeaderSignature) + return ZipReturn.ZipLocalFileHeaderError; + + br.ReadUInt16(); // version needed to extract + _generalPurposeBitFlag = br.ReadUInt16(); + if ((_generalPurposeBitFlag & 8) == 8) + return ZipReturn.ZipCannotFastOpen; + + _compressionMethod = br.ReadUInt16(); + _lastModFileTime = br.ReadUInt16(); + _lastModFileDate = br.ReadUInt16(); + CRC = ReadCRC(br); + _compressedSize = br.ReadUInt32(); + UncompressedSize = br.ReadUInt32(); + + ushort fileNameLength = br.ReadUInt16(); + ushort extraFieldLength = br.ReadUInt16(); + + byte[] bFileName = br.ReadBytes(fileNameLength); + + FileName = (_generalPurposeBitFlag & (1 << 11)) == 0 ? + GetString(bFileName) : + Encoding.UTF8.GetString(bFileName, 0, fileNameLength); + + byte[] extraField = br.ReadBytes(extraFieldLength); + + Zip64 = false; + int pos = 0; + while (extraFieldLength > pos) + { + ushort type = BitConverter.ToUInt16(extraField, pos); + pos += 2; + ushort blockLength = BitConverter.ToUInt16(extraField, pos); + pos += 2; + switch (type) + { + case 0x0001: + Zip64 = true; + if (UncompressedSize == 0xffffffff) + { + UncompressedSize = BitConverter.ToUInt64(extraField, pos); + pos += 8; + } + if (_compressedSize == 0xffffffff) + { + _compressedSize = BitConverter.ToUInt64(extraField, pos); + pos += 8; + } + break; + case 0x7075: + pos += 1; + uint nameCRC32 = BitConverter.ToUInt32(extraField, pos); + pos += 4; + + CRC32 crcTest = new CRC32(); + crcTest.SlurpBlock(bFileName, 0, fileNameLength); + uint fCRC = crcTest.Crc32ResultU; + + if (nameCRC32 != fCRC) return ZipReturn.ZipLocalFileHeaderError; + + int charLen = blockLength - 5; + + FileName = Encoding.UTF8.GetString(extraField, pos, charLen); + + pos += charLen; + + break; + default: + pos += blockLength; + break; + } + } + + _dataLocation = (ulong)_zipFs.Position; + return ZipReturn.ZipGood; + + } + catch + { + return ZipReturn.ZipLocalFileHeaderError; + } + + + } + + + + private void LocalFileHeaderWrite() + { + BinaryWriter bw = new BinaryWriter(_zipFs); + + List extraField = new List(); + Zip64 = UncompressedSize >= 0xffffffff; + + byte[] bFileName; + if (IsUnicode(FileName)) + { + _generalPurposeBitFlag |= 1 << 11; + bFileName = Encoding.UTF8.GetBytes(FileName); + } + else + bFileName = GetBytes(FileName); + + ushort versionNeededToExtract = (ushort)(Zip64 ? 45 : 20); + + RelativeOffsetOfLocalHeader = (ulong)_zipFs.Position; + const uint header = 0x4034B50; + bw.Write(header); + bw.Write(versionNeededToExtract); + bw.Write(_generalPurposeBitFlag); + bw.Write(_compressionMethod); + bw.Write(_lastModFileTime); + bw.Write(_lastModFileDate); + + _crc32Location = (ulong)_zipFs.Position; + + // these 3 values will be set correctly after the file data has been written + bw.Write(0xffffffff); + bw.Write(0xffffffff); + bw.Write(0xffffffff); + + + + if (Zip64) + { + for (int i = 0; i < 20; i++) + extraField.Add(0); + } + + ushort fileNameLength = (ushort)bFileName.Length; + bw.Write(fileNameLength); + + ushort extraFieldLength = (ushort)extraField.Count; + bw.Write(extraFieldLength); + + bw.Write(bFileName, 0, fileNameLength); + + _extraLocation = (ulong)_zipFs.Position; + bw.Write(extraField.ToArray(), 0, extraFieldLength); + + } + + + private Stream _readStream; + public ZipReturn LocalFileOpenReadStream(bool raw, out Stream stream, out ulong streamSize, out ushort compressionMethod) + { + streamSize = 0; + compressionMethod = _compressionMethod; + + _readStream = null; + _zipFs.Seek((long)_dataLocation, SeekOrigin.Begin); + + switch (_compressionMethod) + { + case 8: + if (raw) + { + _readStream = _zipFs; + streamSize = _compressedSize; + } + else + { + _readStream = new DeflateStream(_zipFs, CompressionMode.Decompress, true); + streamSize = UncompressedSize; + + } + break; + case 0: + _readStream = _zipFs; + streamSize = _compressedSize; // same as UncompressedSize + break; + } + stream = _readStream; + return stream == null ? ZipReturn.ZipErrorGettingDataStream : ZipReturn.ZipGood; + } + public ZipReturn LocalFileCloseReadStream() + { + DeflateStream dfStream = _readStream as DeflateStream; + if (dfStream != null) + { + dfStream.Close(); + dfStream.Dispose(); + } + return ZipReturn.ZipGood; + } + + private Stream _writeStream; + public ZipReturn LocalFileOpenWriteStream(bool raw, bool trrntZip, ulong uncompressedSize, ushort compressionMethod, out Stream stream) + { + UncompressedSize = uncompressedSize; + _compressionMethod = compressionMethod; + + LocalFileHeaderWrite(); + _dataLocation = (ulong)_zipFs.Position; + + if (raw) + { + _writeStream = _zipFs; + TrrntZip = trrntZip; + } + else + { + if (compressionMethod == 0) + { + _writeStream = _zipFs; + TrrntZip = false; + } + else + { + _writeStream = new DeflateStream(_zipFs, CompressionMode.Compress, CompressionLevel.BestCompression, true); + TrrntZip = true; + } + } + + stream = _writeStream; + return stream == null ? ZipReturn.ZipErrorGettingDataStream : ZipReturn.ZipGood; + } + public ZipReturn LocalFileCloseWriteStream(byte[] crc32) + { + DeflateStream dfStream = _writeStream as DeflateStream; + if (dfStream != null) + { + dfStream.Flush(); + dfStream.Close(); + dfStream.Dispose(); + } + + _compressedSize = (ulong)_zipFs.Position - _dataLocation; + + if (_compressedSize == 0 && UncompressedSize == 0) + { + LocalFileAddDirectory(); + _compressedSize = (ulong)_zipFs.Position - _dataLocation; + } + + CRC = crc32; + WriteCompressedSize(); + + return ZipReturn.ZipGood; + } + private void WriteCompressedSize() + { + long posNow = _zipFs.Position; + _zipFs.Seek((long)_crc32Location, SeekOrigin.Begin); + BinaryWriter bw = new BinaryWriter(_zipFs); + + uint tCompressedSize; + uint tUncompressedSize; + if (Zip64) + { + tCompressedSize = 0xffffffff; + tUncompressedSize = 0xffffffff; + } + else + { + tCompressedSize = (uint)_compressedSize; + tUncompressedSize = (uint)UncompressedSize; + } + + bw.Write(CRC[3]); + bw.Write(CRC[2]); + bw.Write(CRC[1]); + bw.Write(CRC[0]); + bw.Write(tCompressedSize); + bw.Write(tUncompressedSize); + + // also need to write extradata + if (Zip64) + { + _zipFs.Seek((long)_extraLocation, SeekOrigin.Begin); + bw.Write((ushort)0x0001); // id + bw.Write((ushort)16); // data length + bw.Write(UncompressedSize); + bw.Write(_compressedSize); + } + + _zipFs.Seek(posNow, SeekOrigin.Begin); + + } + + + public void LocalFileCheck() + { + if (FileStatus != ZipReturn.ZipUntested) return; + + try + { + Stream sInput = null; + _zipFs.Seek((long)_dataLocation, SeekOrigin.Begin); + + switch (_compressionMethod) + { + case 8: + sInput = new DeflateStream(_zipFs, CompressionMode.Decompress, true); + break; + case 0: + sInput = _zipFs; + break; + } + + if (sInput == null) + { + FileStatus = ZipReturn.ZipErrorGettingDataStream; + return; + } + + CRC32Hash crc32 = new CRC32Hash(); + MD5 lmd5 = System.Security.Cryptography.MD5.Create(); + SHA1 lsha1 = System.Security.Cryptography.SHA1.Create(); + + ulong sizetogo = UncompressedSize; + if (_buffer == null) + _buffer = new byte[Buffersize]; + + while (sizetogo > 0) + { + int sizenow = sizetogo > Buffersize ? Buffersize : (int)sizetogo; + sInput.Read(_buffer, 0, sizenow); + + crc32.TransformBlock(_buffer, 0, sizenow, null, 0); + lmd5.TransformBlock(_buffer, 0, sizenow, null, 0); + lsha1.TransformBlock(_buffer, 0, sizenow, null, 0); + + sizetogo = sizetogo - (ulong)sizenow; + } + + crc32.TransformFinalBlock(_buffer, 0, 0); + lmd5.TransformFinalBlock(_buffer, 0, 0); + lsha1.TransformFinalBlock(_buffer, 0, 0); + + byte[] testcrc = crc32.Hash; + md5 = lmd5.Hash; + sha1 = lsha1.Hash; + + if (_compressionMethod == 8) + { + sInput.Close(); + sInput.Dispose(); + } + + FileStatus = ByteArrCompare(CRC, testcrc) ? ZipReturn.ZipGood : ZipReturn.ZipCRCDecodeError; + } + catch + { + FileStatus = ZipReturn.ZipDecodeError; + } + } + + + public void LocalFileAddDirectory() + { + Stream ds = _zipFs; + ds.WriteByte(03); + ds.WriteByte(00); + } + + + + public ulong LocalFilePos + { + get { return RelativeOffsetOfLocalHeader; } + set { RelativeOffsetOfLocalHeader = value; } + } + private static byte[] ReadCRC(BinaryReader br) + { + byte[] tCRC = new byte[4]; + tCRC[3] = br.ReadByte(); + tCRC[2] = br.ReadByte(); + tCRC[1] = br.ReadByte(); + tCRC[0] = br.ReadByte(); + return tCRC; + } + + + } + + + private IO.FileInfo _zipFileInfo; + + public string ZipFilename + { + get { return _zipFileInfo != null ? _zipFileInfo.FullName : ""; } + } + public long TimeStamp + { + get { return _zipFileInfo != null ? _zipFileInfo.LastWriteTime : 0; } + } + + private ulong _centerDirStart; + private ulong _centerDirSize; + private ulong _endOfCenterDir64; + + byte[] _fileComment; + private Stream _zipFs; + + private uint _localFilesCount; + private readonly List _localFiles = new List(); + + private ZipStatus _pZipStatus; + private bool _zip64; + public ZipOpenType ZipOpen; + + public ZipStatus ZipStatus { get { return _pZipStatus; } } + + public int LocalFilesCount() { return _localFiles.Count; } + + public string Filename(int i) { return _localFiles[i].FileName; } + public ulong UncompressedSize(int i) { return _localFiles[i].UncompressedSize; } + public ulong? LocalHeader(int i) + { + return ((_localFiles[i]._generalPurposeBitFlag & 8) == 0) ? (ulong?)_localFiles[i].RelativeOffsetOfLocalHeader : null; + } + public ZipReturn FileStatus(int i) { return _localFiles[i].FileStatus; } + public byte[] CRC32(int i) { return _localFiles[i].CRC; } + public byte[] MD5(int i) { return _localFiles[i].md5; } + public byte[] SHA1(int i) { return _localFiles[i].sha1; } + + + ~ZipFile() + { + if (_zipFs != null) + { + _zipFs.Close(); + _zipFs.Dispose(); + } + } + + + private ZipReturn FindEndOfCentralDirSignature() + { + long fileSize = _zipFs.Length; + long maxBackSearch = 0xffff; + + if (_zipFs.Length < maxBackSearch) + maxBackSearch = fileSize; + + const long buffSize = 0x400; + + byte[] buffer = new byte[buffSize + 4]; + + long backPosition = 4; + while (backPosition < maxBackSearch) + { + backPosition += buffSize; + if (backPosition > maxBackSearch) backPosition = maxBackSearch; + + long readSize = backPosition > (buffSize + 4) ? (buffSize + 4) : backPosition; + + _zipFs.Position = fileSize - backPosition; + + _zipFs.Read(buffer, 0, (int)readSize); + + + for (long i = readSize - 4; i >= 0; i--) + { + if ((buffer[i] != 0x50) || (buffer[i + 1] != 0x4b) || (buffer[i + 2] != 0x05) || (buffer[i + 3] != 0x06)) continue; + + _zipFs.Position = (fileSize - backPosition) + i; + return ZipReturn.ZipGood; + } + } + return ZipReturn.ZipCenteralDirError; + } + + + private ZipReturn EndOfCentralDirRead() + { + BinaryReader zipBr = new BinaryReader(_zipFs); + + uint thisSignature = zipBr.ReadUInt32(); + if (thisSignature != EndOfCentralDirSignature) + return ZipReturn.ZipEndOfCentralDirectoryError; + + ushort tushort = zipBr.ReadUInt16(); // NumberOfThisDisk + if (tushort != 0) return ZipReturn.ZipEndOfCentralDirectoryError; + + tushort = zipBr.ReadUInt16(); // NumberOfThisDiskCenterDir + if (tushort != 0) return ZipReturn.ZipEndOfCentralDirectoryError; + + _localFilesCount = zipBr.ReadUInt16(); // TotalNumberOfEnteriesDisk + + tushort = zipBr.ReadUInt16(); // TotalNumber of enteries in the central directory + if (tushort != _localFilesCount) return ZipReturn.ZipEndOfCentralDirectoryError; + + _centerDirSize = zipBr.ReadUInt32(); // SizeOfCenteralDir + _centerDirStart = zipBr.ReadUInt32(); // Offset + + ushort zipFileCommentLength = zipBr.ReadUInt16(); + + _fileComment = zipBr.ReadBytes(zipFileCommentLength); + + if (_zipFs.Position != _zipFs.Length) _pZipStatus |= ZipStatus.ExtraData; + + return ZipReturn.ZipGood; + } + private void EndOfCentralDirWrite() + { + + BinaryWriter bw = new BinaryWriter(_zipFs); + bw.Write(EndOfCentralDirSignature); + bw.Write((ushort)0); // NumberOfThisDisk + bw.Write((ushort)0); // NumberOfThisDiskCenterDir + bw.Write((ushort)(_localFiles.Count >= 0xffff ? 0xffff : _localFiles.Count)); // TotalNumberOfEnteriesDisk + bw.Write((ushort)(_localFiles.Count >= 0xffff ? 0xffff : _localFiles.Count)); // TotalNumber of enteries in the central directory + bw.Write((uint)(_centerDirSize >= 0xffffffff ? 0xffffffff : _centerDirSize)); + bw.Write((uint)(_centerDirStart >= 0xffffffff ? 0xffffffff : _centerDirStart)); + bw.Write((ushort)_fileComment.Length); + bw.Write(_fileComment, 0, _fileComment.Length); + } + + private ZipReturn Zip64EndOfCentralDirRead() + { + _zip64 = true; + BinaryReader zipBr = new BinaryReader(_zipFs); + + uint thisSignature = zipBr.ReadUInt32(); + if (thisSignature != Zip64EndOfCentralDirSignatue) + return ZipReturn.ZipEndOfCentralDirectoryError; + + ulong tulong = zipBr.ReadUInt64(); // Size of zip64 end of central directory record + if (tulong != 44) return ZipReturn.Zip64EndOfCentralDirError; + + zipBr.ReadUInt16(); // version made by + + ushort tushort = zipBr.ReadUInt16(); // version needed to extract + if (tushort != 45) return ZipReturn.Zip64EndOfCentralDirError; + + uint tuint = zipBr.ReadUInt32(); // number of this disk + if (tuint != 0) return ZipReturn.Zip64EndOfCentralDirError; + + tuint = zipBr.ReadUInt32(); // number of the disk with the start of the central directory + if (tuint != 0) return ZipReturn.Zip64EndOfCentralDirError; + + _localFilesCount = (uint)zipBr.ReadUInt64(); // total number of entries in the central directory on this disk + + tulong = zipBr.ReadUInt64(); // total number of entries in the central directory + if (tulong != _localFilesCount) return ZipReturn.Zip64EndOfCentralDirError; + + _centerDirSize = zipBr.ReadUInt64(); // size of central directory + + _centerDirStart = zipBr.ReadUInt64(); // offset of start of central directory with respect to the starting disk number + + return ZipReturn.ZipGood; + } + + private void Zip64EndOfCentralDirWrite() + { + BinaryWriter bw = new BinaryWriter(_zipFs); + bw.Write(Zip64EndOfCentralDirSignatue); + bw.Write((ulong)44); // Size of zip64 end of central directory record + bw.Write((ushort)45); // version made by + bw.Write((ushort)45); // version needed to extract + bw.Write((uint)0); // number of this disk + bw.Write((uint)0); // number of the disk with the start of the central directroy + bw.Write((ulong)_localFiles.Count); // total number of entries in the central directory on this disk + bw.Write((ulong)_localFiles.Count); // total number of entries in the central directory + bw.Write(_centerDirSize); // size of central directory + bw.Write(_centerDirStart); // offset of start of central directory with respect to the starting disk number + } + + private ZipReturn Zip64EndOfCentralDirectoryLocatorRead() + { + _zip64 = true; + BinaryReader zipBr = new BinaryReader(_zipFs); + + uint thisSignature = zipBr.ReadUInt32(); + if (thisSignature != Zip64EndOfCentralDirectoryLocator) + return ZipReturn.ZipEndOfCentralDirectoryError; + + uint tuint = zipBr.ReadUInt32(); // number of the disk with the start of the zip64 end of centeral directory + if (tuint != 0) return ZipReturn.Zip64EndOfCentralDirectoryLocatorError; + + _endOfCenterDir64 = zipBr.ReadUInt64(); // relative offset of the zip64 end of central directroy record + + tuint = zipBr.ReadUInt32(); // total number of disks + if (tuint != 1) return ZipReturn.Zip64EndOfCentralDirectoryLocatorError; + + return ZipReturn.ZipGood; + } + private void Zip64EndOfCentralDirectoryLocatorWrite() + { + BinaryWriter bw = new BinaryWriter(_zipFs); + bw.Write(Zip64EndOfCentralDirectoryLocator); + bw.Write((uint)0); // number of the disk with the start of the zip64 end of centeral directory + bw.Write(_endOfCenterDir64); // relative offset of the zip64 end of central directroy record + bw.Write((uint)1); // total number of disks + } + + + + public ZipReturn ZipFileOpen(string newFilename, long timestamp, bool readHeaders) + { + ZipFileClose(); + _pZipStatus = ZipStatus.None; + _zip64 = false; + _centerDirStart = 0; + _centerDirSize = 0; + _zipFileInfo = null; + + try + { + if (!IO.File.Exists(newFilename)) + { + ZipFileClose(); + return ZipReturn.ZipErrorFileNotFound; + } + _zipFileInfo = new IO.FileInfo(newFilename); + if (_zipFileInfo.LastWriteTime != timestamp) + { + ZipFileClose(); + return ZipReturn.ZipErrorTimeStamp; + } + int errorCode = IO.FileStream.OpenFileRead(newFilename, out _zipFs); + if (errorCode != 0) + { + ZipFileClose(); + if (errorCode == 32) + return ZipReturn.ZipFileLocked; + return ZipReturn.ZipErrorOpeningFile; + } + } + catch (PathTooLongException) + { + ZipFileClose(); + return ZipReturn.ZipFileNameToLong; + } + catch (IOException) + { + ZipFileClose(); + return ZipReturn.ZipErrorOpeningFile; + } + ZipOpen = ZipOpenType.OpenRead; + + if (!readHeaders) + return ZipReturn.ZipGood; + + + try + { + ZipReturn zRet = FindEndOfCentralDirSignature(); + if (zRet != ZipReturn.ZipGood) + { + ZipFileClose(); + return zRet; + } + + long endOfCentralDir = _zipFs.Position; + zRet = EndOfCentralDirRead(); + if (zRet != ZipReturn.ZipGood) + { + ZipFileClose(); + return zRet; + } + + // check if this is a ZIP64 zip and if it is read the Zip64 End Of Central Dir Info + if (_centerDirStart == 0xffffffff || _centerDirSize == 0xffffffff || _localFilesCount == 0xffff) + { + _zip64 = true; + _zipFs.Position = endOfCentralDir - 20; + zRet = Zip64EndOfCentralDirectoryLocatorRead(); + if (zRet != ZipReturn.ZipGood) + { + ZipFileClose(); + return zRet; + } + _zipFs.Position = (long)_endOfCenterDir64; + zRet = Zip64EndOfCentralDirRead(); + if (zRet != ZipReturn.ZipGood) + { + ZipFileClose(); + return zRet; + } + } + + bool trrntzip = false; + + // check if the ZIP has a valid TorrentZip file comment + if (_fileComment.Length == 22) + { + if (GetString(_fileComment).Substring(0, 14) == "TORRENTZIPPED-") + { + CrcCalculatorStream crcCs = new CrcCalculatorStream(_zipFs, true); + byte[] buffer = new byte[_centerDirSize]; + _zipFs.Position = (long)_centerDirStart; + crcCs.Read(buffer, 0, (int)_centerDirSize); + crcCs.Flush(); + crcCs.Close(); + + uint r = (uint)crcCs.Crc; + crcCs.Dispose(); + + string tcrc = GetString(_fileComment).Substring(14, 8); + string zcrc = r.ToString("X8"); + if (String.Compare(tcrc, zcrc, StringComparison.Ordinal) == 0) + trrntzip = true; + + } + } + + + // now read the central directory + _zipFs.Position = (long)_centerDirStart; + + _localFiles.Clear(); + _localFiles.Capacity = (int)_localFilesCount; + for (int i = 0; i < _localFilesCount; i++) + { + LocalFile lc = new LocalFile(_zipFs); + zRet = lc.CenteralDirectoryRead(); + if (zRet != ZipReturn.ZipGood) + { + ZipFileClose(); + return zRet; + } + _zip64 |= lc.Zip64; + _localFiles.Add(lc); + } + + for (int i = 0; i < _localFilesCount; i++) + { + zRet = _localFiles[i].LocalFileHeaderRead(); + if (zRet != ZipReturn.ZipGood) + { + ZipFileClose(); + return zRet; + } + trrntzip &= _localFiles[i].TrrntZip; + } + + // check trrntzip file order + if (trrntzip) + for (int i = 0; i < _localFilesCount - 1; i++) + { + if (TrrntZipStringCompare(_localFiles[i].FileName, _localFiles[i + 1].FileName) < 0) continue; + trrntzip = false; + break; + } + + // check trrntzip directories + if (trrntzip) + for (int i = 0; i < _localFilesCount - 1; i++) + { + // see if we found a directory + string filename0 = _localFiles[i].FileName; + if (filename0.Substring(filename0.Length - 1, 1) != "/") continue; + + // see if the next file is in that directory + string filename1 = _localFiles[i + 1].FileName; + if (filename1.Length <= filename0.Length) continue; + if (TrrntZipStringCompare(filename0, filename1.Substring(0, filename0.Length)) != 0) continue; + + // if we found a file in the directory then we do not need the directory entry + trrntzip = false; + break; + } + + if (trrntzip) + _pZipStatus |= ZipStatus.TrrntZip; + + return ZipReturn.ZipGood; + } + catch + { + ZipFileClose(); + return ZipReturn.ZipErrorReadingFile; + } + + } + + public ZipReturn ZipFileCreate(string newFilename) + { + if (ZipOpen != ZipOpenType.Closed) + return ZipReturn.ZipFileAlreadyOpen; + + CreateDirForFile(newFilename); + _zipFileInfo = new IO.FileInfo(newFilename); + + int errorCode = IO.FileStream.OpenFileWrite(newFilename, out _zipFs); + if (errorCode != 0) + { + ZipFileClose(); + return ZipReturn.ZipErrorOpeningFile; + } + ZipOpen = ZipOpenType.OpenWrite; + return ZipReturn.ZipGood; + } + + public void ZipFileClose() + { + if (ZipOpen == ZipOpenType.Closed) + { + return; + } + + if (ZipOpen == ZipOpenType.OpenRead) + { + if (_zipFs != null) + { + _zipFs.Close(); + _zipFs.Dispose(); + } + ZipOpen = ZipOpenType.Closed; + return; + } + + _zip64 = false; + bool lTrrntzip = true; + + _centerDirStart = (ulong)_zipFs.Position; + if (_centerDirStart >= 0xffffffff) + _zip64 = true; + + CrcCalculatorStream crcCs = new CrcCalculatorStream(_zipFs, true); + + foreach (LocalFile t in _localFiles) + { + t.CenteralDirectoryWrite(crcCs); + _zip64 |= t.Zip64; + lTrrntzip &= t.TrrntZip; + } + + crcCs.Flush(); + crcCs.Close(); + + _centerDirSize = (ulong)_zipFs.Position - _centerDirStart; + + _fileComment = lTrrntzip ? GetBytes("TORRENTZIPPED-" + crcCs.Crc.ToString("X8")) : new byte[0]; + _pZipStatus = lTrrntzip ? ZipStatus.TrrntZip : ZipStatus.None; + + crcCs.Dispose(); + + if (_zip64) + { + _endOfCenterDir64 = (ulong)_zipFs.Position; + Zip64EndOfCentralDirWrite(); + Zip64EndOfCentralDirectoryLocatorWrite(); + } + EndOfCentralDirWrite(); + + _zipFs.SetLength(_zipFs.Position); + _zipFs.Flush(); + _zipFs.Close(); + _zipFs.Dispose(); + _zipFileInfo = new IO.FileInfo(_zipFileInfo.FullName); + ZipOpen = ZipOpenType.Closed; + + } + + public void ZipFileCloseFailed() + { + if (ZipOpen == ZipOpenType.Closed) + { + return; + } + + if (ZipOpen == ZipOpenType.OpenRead) + { + if (_zipFs != null) + { + _zipFs.Close(); + _zipFs.Dispose(); + } + ZipOpen = ZipOpenType.Closed; + return; + } + + _zipFs.Flush(); + _zipFs.Close(); + _zipFs.Dispose(); + IO.File.Delete(_zipFileInfo.FullName); + _zipFileInfo = null; + ZipOpen = ZipOpenType.Closed; + } + + + private int _readIndex; + public ZipReturn ZipFileOpenReadStream(int index, bool raw, out Stream stream, out ulong streamSize, out ushort compressionMethod) + { + streamSize = 0; + compressionMethod = 0; + _readIndex = index; + stream = null; + if (ZipOpen != ZipOpenType.OpenRead) + return ZipReturn.ZipReadingFromOutputFile; + + ZipReturn zRet = _localFiles[index].LocalFileHeaderRead(); + if (zRet != ZipReturn.ZipGood) + { + ZipFileClose(); + return zRet; + } + + return _localFiles[index].LocalFileOpenReadStream(raw, out stream, out streamSize, out compressionMethod); + } + + public ZipReturn ZipFileOpenReadStreamQuick(ulong pos, bool raw, out Stream stream, out ulong streamSize, out ushort compressionMethod) + { + LocalFile tmpFile = new LocalFile(_zipFs) { LocalFilePos = pos }; + _localFiles.Clear(); + _localFiles.Add(tmpFile); + ZipReturn zr = tmpFile.LocalFileHeaderReadQuick(); + if (zr != ZipReturn.ZipGood) + { + stream = null; + streamSize = 0; + compressionMethod = 0; + return zr; + } + _readIndex = 0; + + return tmpFile.LocalFileOpenReadStream(raw, out stream, out streamSize, out compressionMethod); + } + + public ZipReturn ZipFileCloseReadStream() + { + return _localFiles[_readIndex].LocalFileCloseReadStream(); + } + + public ZipReturn ZipFileOpenWriteStream(bool raw, bool trrntzip, string filename, ulong uncompressedSize, ushort compressionMethod, out Stream stream) + { + stream = null; + if (ZipOpen != ZipOpenType.OpenWrite) + return ZipReturn.ZipWritingToInputFile; + + LocalFile lf = new LocalFile(_zipFs, filename); + + ZipReturn retVal = lf.LocalFileOpenWriteStream(raw, trrntzip, uncompressedSize, compressionMethod, out stream); + + _localFiles.Add(lf); + + return retVal; + } + public ZipReturn ZipFileCloseWriteStream(byte[] crc32) + { + return _localFiles[_localFiles.Count - 1].LocalFileCloseWriteStream(crc32); + } + + public ZipReturn ZipFileRollBack() + { + if (ZipOpen != ZipOpenType.OpenWrite) + return ZipReturn.ZipWritingToInputFile; + + int fileCount = _localFiles.Count; + if (fileCount == 0) + return ZipReturn.ZipErrorRollBackFile; + + LocalFile lf = _localFiles[fileCount - 1]; + + _localFiles.RemoveAt(fileCount - 1); + _zipFs.Position = (long)lf.LocalFilePos; + return ZipReturn.ZipGood; + } + + public void ZipFileAddDirectory() + { + _localFiles[_localFiles.Count - 1].LocalFileAddDirectory(); + } + + + /* + public void BreakTrrntZip(string filename) + { + _zipFs = new FileStream(filename, FileMode.Open, FileAccess.ReadWrite); + BinaryReader zipBr = new BinaryReader(_zipFs); + _zipFs.Position = _zipFs.Length - 22; + byte[] fileComment = zipBr.ReadBytes(22); + if (GetString(fileComment).Substring(0, 14) == "TORRENTZIPPED-") + { + _zipFs.Position = _zipFs.Length - 8; + _zipFs.WriteByte(48); _zipFs.WriteByte(48); _zipFs.WriteByte(48); _zipFs.WriteByte(48); + _zipFs.WriteByte(48); _zipFs.WriteByte(48); _zipFs.WriteByte(48); _zipFs.WriteByte(48); + } + + zipBr.Close(); + _zipFs.Flush(); + _zipFs.Close(); + } + */ + + public void DeepScan() + { + foreach (LocalFile lfile in _localFiles) + lfile.LocalFileCheck(); + } + + private static void CreateDirForFile(string sFilename) + { + string strTemp = IO.Path.GetDirectoryName(sFilename); + + if (String.IsNullOrEmpty(strTemp)) return; + + if (IO.Directory.Exists(strTemp)) return; + + + while (strTemp.Length > 0 && !IO.Directory.Exists(strTemp)) + { + int pos = strTemp.LastIndexOf(IO.Path.DirectorySeparatorChar); + if (pos < 0) pos = 0; + strTemp = strTemp.Substring(0, pos); + } + + while (sFilename.IndexOf(IO.Path.DirectorySeparatorChar, strTemp.Length + 1) > 0) + { + strTemp = sFilename.Substring(0, sFilename.IndexOf(IO.Path.DirectorySeparatorChar, strTemp.Length + 1)); + IO.Directory.CreateDirectory(strTemp); + } + } + + + public static string ZipErrorMessageText(ZipReturn zS) + { + string ret = "Unknown"; + switch (zS) + { + case ZipReturn.ZipGood: + ret = ""; + break; + case ZipReturn.ZipFileCountError: + ret = "The number of file in the Zip does not mach the number of files in the Zips Centeral Directory"; + break; + case ZipReturn.ZipSignatureError: + ret = "An unknown Signature Block was found in the Zip"; + break; + case ZipReturn.ZipExtraDataOnEndOfZip: + ret = "Extra Data was found on the end of the Zip"; + break; + case ZipReturn.ZipUnsupportedCompression: + ret = "An unsupported Compression method was found in the Zip, if you recompress this zip it will be usable"; + break; + case ZipReturn.ZipLocalFileHeaderError: + ret = "Error reading a zipped file header information"; + break; + case ZipReturn.ZipCenteralDirError: + ret = "There is an error in the Zip Centeral Directory"; + break; + case ZipReturn.ZipReadingFromOutputFile: + ret = "Trying to write to a Zip file open for output only"; + break; + case ZipReturn.ZipWritingToInputFile: + ret = "Tring to read from a Zip file open for input only"; + break; + case ZipReturn.ZipErrorGettingDataStream: + ret = "Error creating Data Stream"; + break; + case ZipReturn.ZipCRCDecodeError: + ret = "CRC error"; + break; + case ZipReturn.ZipDecodeError: + ret = "Error unzipping a file"; + break; + } + + return ret; + } + + private static byte[] GetBytes(String s) + { + char[] c = s.ToCharArray(); + byte[] b = new byte[c.Length]; + for (int i = 0; i < c.Length; i++) + { + char t = c[i]; + b[i] = t > 255 ? (byte)'?' : (byte)c[i]; + } + return b; + } + private static bool IsUnicode(string s) + { + char[] c = s.ToCharArray(); + for (int i = 0; i < c.Length; i++) + if (c[i] > 255) return true; + return false; + } + + private static string GetString(byte[] b) + { + string s = ""; + for (int i = 0; i < b.Length; i++) + s += (char)b[i]; + return s; + } + private static bool CompareString(string s1, string s2) + { + char[] c1 = s1.ToCharArray(); + char[] c2 = s2.ToCharArray(); + + if (c1.Length != c2.Length) + return false; + + for (int i = 0; i < c1.Length; i++) + if (c1[i] != c2[i]) return false; + return true; + } + + + private static bool ByteArrCompare(byte[] b0, byte[] b1) + { + if (b0 == null || b1 == null) + return false; + if (b0.Length != b1.Length) + return false; + + for (int i = 0; i < b0.Length; i++) + { + if (b0[i] != b1[i]) + return false; + } + return true; + } + + private static int TrrntZipStringCompare(string string1, string string2) + { + char[] bytes1 = string1.ToCharArray(); + char[] bytes2 = string2.ToCharArray(); + + int pos1 = 0; + int pos2 = 0; + + for (; ; ) + { + if (pos1 == bytes1.Length) + return ((pos2 == bytes2.Length) ? 0 : -1); + if (pos2 == bytes2.Length) + return 1; + + int byte1 = bytes1[pos1++]; + int byte2 = bytes2[pos2++]; + + if (byte1 >= 65 && byte1 <= 90) byte1 += 0x20; + if (byte2 >= 65 && byte2 <= 90) byte2 += 0x20; + + if (byte1 < byte2) + return -1; + if (byte1 > byte2) + return 1; + } + } + } + +} diff --git a/ROMVault2/SupportedFiles/ZipEnums.cs b/ROMVault2/SupportedFiles/ZipEnums.cs new file mode 100644 index 0000000..d80d9fc --- /dev/null +++ b/ROMVault2/SupportedFiles/ZipEnums.cs @@ -0,0 +1,57 @@ +/****************************************************** + * ROMVault2 is written by Gordon J. * + * Contact gordon@romvault.com * + * Copyright 2014 * + ******************************************************/ + +using System; + +namespace ROMVault2.SupportedFiles +{ + public enum ZipReturn + { + ZipGood, + ZipFileLocked, + ZipFileCountError, + ZipSignatureError, + ZipExtraDataOnEndOfZip, + ZipUnsupportedCompression, + ZipLocalFileHeaderError, + ZipCenteralDirError, + ZipEndOfCentralDirectoryError, + Zip64EndOfCentralDirError, + Zip64EndOfCentralDirectoryLocatorError, + ZipReadingFromOutputFile, + ZipWritingToInputFile, + ZipErrorGettingDataStream, + ZipCRCDecodeError, + ZipDecodeError, + ZipFileNameToLong, + ZipFileAlreadyOpen, + ZipCannotFastOpen, + ZipErrorOpeningFile, + ZipErrorFileNotFound, + ZipErrorReadingFile, + ZipErrorTimeStamp, + ZipErrorRollBackFile, + ZipUntested + + } + + public enum ZipOpenType + { + Closed, + OpenRead, + OpenWrite + } + + [Flags] + public enum ZipStatus + { + None = 0x0, + TrrntZip = 0x1, + ExtraData = 0x2 + } + + +} diff --git a/ROMVault2/Utils/ArrByte.cs b/ROMVault2/Utils/ArrByte.cs new file mode 100644 index 0000000..eb5cebe --- /dev/null +++ b/ROMVault2/Utils/ArrByte.cs @@ -0,0 +1,72 @@ +/****************************************************** + * ROMVault2 is written by Gordon J. * + * Contact gordon@romvault.com * + * Copyright 2014 * + ******************************************************/ + +using System; +using System.IO; + +namespace ROMVault2.Utils +{ + public static class ArrByte + { + public static void Write(BinaryWriter bw, byte[] b) + { + bw.Write((byte)b.Length); + bw.Write(b); + } + + public static byte[] Read(BinaryReader br) + { + byte len = br.ReadByte(); + return br.ReadBytes(len); + } + + public static byte[] Copy(byte[] b) + { + if (b == null) return null; + byte[] retB = new byte[b.Length]; + for (int i = 0; i < b.Length; i++) + retB[i] = b[i]; + return retB; + } + + public static bool bCompare(byte[] b1, byte[] b2) + { + if (b1 == null || b2 == null) return false; + + if (b1.Length != b2.Length) return false; + + for (int i = 0; i < b1.Length; i++) + if (b1[i] != b2[i]) return false; + + return true; + } + + public static int iCompare(byte[] b1, byte[] b2) + { + int b1Len = (b1 == null) ? 0 : b1.Length; + int b2Len = (b2 == null) ? 0 : b2.Length; + + int p = 0; + for (; ; ) + { + if (b1Len == p) + return (b2Len == p) ? 0 : -1; + if (b2Len == p) + return 1; + if (b1[p] < b2[p]) + return -1; + if (b1[p] > b2[p]) + return 1; + p++; + } + } + + public static string ToString(byte[] b) + { + return b == null ? "" : BitConverter.ToString(b).ToLower().Replace("-", ""); + } + } +} diff --git a/ROMVault2/Utils/DBTypeGet.cs b/ROMVault2/Utils/DBTypeGet.cs new file mode 100644 index 0000000..25daa43 --- /dev/null +++ b/ROMVault2/Utils/DBTypeGet.cs @@ -0,0 +1,58 @@ +/****************************************************** + * ROMVault2 is written by Gordon J. * + * Contact gordon@romvault.com * + * Copyright 2014 * + ******************************************************/ + +using System; +using ROMVault2.RvDB; + +namespace ROMVault2.Utils +{ + public class DBTypeGet + { + public static FileType DirFromFile(FileType ft) + { + switch (ft) + { + case FileType.File: + return FileType.Dir; + case FileType.ZipFile: + return FileType.Zip; + } + return FileType.Zip; + } + + public static FileType FileFromDir(FileType ft) + { + switch (ft) + { + case FileType.Dir: + return FileType.File; + case FileType.Zip: + return FileType.ZipFile; + } + return FileType.Zip; + } + + public static bool isCompressedDir(FileType fileType) + { + return (fileType == FileType.Zip); + } + + public static RvBase GetRvType(FileType fileType) + { + switch (fileType) + { + case FileType.Dir: + case FileType.Zip: + return new RvDir(fileType); + case FileType.File: + case FileType.ZipFile: + return new RvFile(fileType); + default: + throw new Exception("Unknown file type"); + } + } + } +} diff --git a/ROMVault2/Utils/RelativePath.cs b/ROMVault2/Utils/RelativePath.cs new file mode 100644 index 0000000..c474c5e --- /dev/null +++ b/ROMVault2/Utils/RelativePath.cs @@ -0,0 +1,95 @@ +/****************************************************** + * ROMVault2 is written by Gordon J. * + * Contact gordon@romvault.com * + * Copyright 2014 * + ******************************************************/ + +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; + +namespace ROMVault2.Utils +{ + public static class RelativePath + { + /// + /// Creates a relative path from one file + /// or folder to another. + /// + /// + /// Contains the directory that defines the + /// start of the relative path. + /// + /// + /// Contains the path that defines the + /// endpoint of the relative path. + /// + /// + /// The relative path from the start + /// directory to the end path. + /// + /// + public static string MakeRelative(string fromDirectory, string toPath) + { + if (fromDirectory == null) + throw new ArgumentNullException("fromDirectory"); + + if (toPath == null) + throw new ArgumentNullException("toPath"); + + bool isRooted = (Path.IsPathRooted(fromDirectory) && Path.IsPathRooted(toPath)); + + if (isRooted) + { + bool isDifferentRoot = (String.Compare(Path.GetPathRoot(fromDirectory), Path.GetPathRoot(toPath), StringComparison.OrdinalIgnoreCase) != 0); + + if (isDifferentRoot) + return toPath; + } + + List relativePath = new List(); + string[] fromDirectories = fromDirectory.Split(Path.DirectorySeparatorChar); + + string[] toDirectories = toPath.Split(Path.DirectorySeparatorChar); + + int length = Math.Min(fromDirectories.Length, toDirectories.Length); + + int lastCommonRoot = -1; + + // find common root + for (int x = 0; x < length; x++) + { + if (String.Compare(fromDirectories[x], toDirectories[x], StringComparison.OrdinalIgnoreCase) != 0) + break; + + lastCommonRoot = x; + } + + if (lastCommonRoot == -1) + return toPath; + + // add relative folders in from path + for (int x = lastCommonRoot + 1; x < fromDirectories.Length; x++) + { + if (fromDirectories[x].Length > 0) + relativePath.Add(".."); + } + + // add to folders to path + for (int x = lastCommonRoot + 1; x < toDirectories.Length; x++) + { + relativePath.Add(toDirectories[x]); + } + + // create relative path + string[] relativeParts = new string[relativePath.Count]; + relativePath.CopyTo(relativeParts, 0); + + string newPath = string.Join(Path.DirectorySeparatorChar.ToString(CultureInfo.InvariantCulture), relativeParts); + + return newPath; + } + + } +} diff --git a/ROMVault2/Utils/ULong.cs b/ROMVault2/Utils/ULong.cs new file mode 100644 index 0000000..019f24c --- /dev/null +++ b/ROMVault2/Utils/ULong.cs @@ -0,0 +1,23 @@ +/****************************************************** + * ROMVault2 is written by Gordon J. * + * Contact gordon@romvault.com * + * Copyright 2014 * + ******************************************************/ + +using System; + +namespace ROMVault2.Utils +{ + public static class ULong + { + public static int iCompare(ulong? a, ulong? b) + { + if ((a == null) || (b == null)) + { + ReportError.SendAndShow("comparing null ulong? "); + return -1; + } + return Math.Sign(((ulong) a).CompareTo((ulong) b)); + } + } +} diff --git a/ROMVault2/Utils/VarFix.cs b/ROMVault2/Utils/VarFix.cs new file mode 100644 index 0000000..cd74fae --- /dev/null +++ b/ROMVault2/Utils/VarFix.cs @@ -0,0 +1,183 @@ +/****************************************************** + * ROMVault2 is written by Gordon J. * + * Contact gordon@romvault.com * + * Copyright 2014 * + ******************************************************/ + +using System; +using System.Xml; + +namespace ROMVault2.Utils +{ + public static class VarFix + { + public static bool StringYesNo(string b) + { + return b != null && ((b.ToLower() == "yes") || (b.ToLower() == "true")); + } + + public static ulong? ULong(XmlNode n) + { + return ULong(n == null ? "" : n.InnerText); + } + + public static ulong? ULong(string n) + { + if (string.IsNullOrEmpty(n)) + return null; + + if (n == "-") + return null; + + try + { + if (n.Length >= 2 && n.Substring(0, 2).ToLower() == "0x") + { + return Convert.ToUInt64(n.Substring(2), 16); + } + + return Convert.ToUInt64(n); + } + catch + { + return null; + } + } + + public static string String(XmlNode n) + { + return String(n == null ? "" : n.InnerText); + } + public static string String(string n) + { + return n ?? ""; + } + + + private const string ValidHexChar = "0123456789abcdef"; + private static string CleanCheck(string crc, int length) + { + string retcrc = crc ?? ""; + retcrc = retcrc.ToLower().Trim(); + + if (retcrc.Length >= 2 && retcrc.Substring(0, 2).ToLower() == "0x") + retcrc = retcrc.Substring(2); + + if (retcrc == "-") retcrc="00000000"; + + for (int i = 0; i < retcrc.Length; i++) + if (ValidHexChar.IndexOf(retcrc.Substring(i, 1), StringComparison.Ordinal) < 0) + return ""; + + + retcrc = (new String('0', length)) + retcrc; + retcrc = retcrc.Substring(retcrc.Length - length); + + return retcrc; + } + + + //CleanMD5SHA1 with a null or empty string will return null + public static byte[] CleanMD5SHA1(XmlNode n, int length) + { + return CleanMD5SHA1(n == null ? null : n.InnerText, length); + } + public static byte[] CleanMD5SHA1(string checksum, int length) + { + if (string.IsNullOrEmpty(checksum)) return null; + + checksum = checksum.ToLower().Trim(); + + if (checksum.Length >= 2) + if (checksum.Substring(0, 2) == "0x") + checksum = checksum.Substring(2); + + + if (string.IsNullOrEmpty(checksum)) return null; + + if (checksum == "-") return null; + + //if (checksum.Length % 2 == 1) + // checksum = "0" + checksum; + + //if (checksum.Length != length) + // return null; + + while (checksum.Length < length) + checksum = "0" + checksum; + + int retL = checksum.Length / 2; + byte[] retB = new byte[retL]; + + for (int i = 0; i < retL; i++) + retB[i] = Convert.ToByte(checksum.Substring(i * 2, 2), 16); + + return retB; + } + + + public static string CleanFullFileName(XmlNode n) + { + return CleanFullFileName(n == null ? "" : n.InnerText); + } + public static string CleanFullFileName(string name) + { + if (System.String.IsNullOrEmpty(name)) return ""; + + string retName = name; + retName = retName.TrimStart(); + retName = retName.TrimEnd(new []{ '.', ' ' }); + + char[] charName = retName.ToCharArray(); + for (int i = 0; i < charName.Length; i++) + { + int c = charName[i]; + if (c == ':' || c == '*' || c == '?' || c == '<' || c == '>' || c == '|' || c < 32) + charName[i] = '-'; + else if (c == '\\') + charName[i] = '/'; + } + return new string(charName); + } + + public static string CleanFileName(XmlNode n) + { + return CleanFileName(n == null ? "" : n.InnerText); + } + public static string CleanFileName(string name,char crep='-') + { + if (System.String.IsNullOrEmpty(name)) return ""; + string retName = name; + retName = retName.TrimStart(); + retName = retName.TrimEnd(new[] { '.', ' ' }); + + char[] charName = retName.ToCharArray(); + for (int i = 0; i < charName.Length; i++) + { + int c = charName[i]; + if (c == ':' || c == '*' || c == '?' || c == '<' || c == '>' || c == '|' || c == '\\' || c == '/' || c < 32) + charName[i] = crep; + } + return new string(charName); + } + + public static string ToLower(XmlNode n) + { + return ToLower(n == null ? "" : n.InnerText); + } + public static string ToLower(string name) + { + return name == null ? "" : name.ToLower(); + } + + + public static string PCombine(string path1, string path2) + { + if (System.String.IsNullOrEmpty(path1)) return path2; + if (System.String.IsNullOrEmpty(path2)) return path1; + + return path1 + "/" + path2; + } + + } +} diff --git a/ROMVault2/chdman.exe b/ROMVault2/chdman.exe new file mode 100644 index 0000000..7918172 Binary files /dev/null and b/ROMVault2/chdman.exe differ diff --git a/ROMVault2/chip.ico b/ROMVault2/chip.ico new file mode 100644 index 0000000..c001ad9 Binary files /dev/null and b/ROMVault2/chip.ico differ diff --git a/ROMVault2/frmHelpAbout.Designer.cs b/ROMVault2/frmHelpAbout.Designer.cs new file mode 100644 index 0000000..0d5280d --- /dev/null +++ b/ROMVault2/frmHelpAbout.Designer.cs @@ -0,0 +1,97 @@ +namespace ROMVault2 +{ + partial class frmHelpAbout + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.lblVersion = new System.Windows.Forms.Label(); + this.label1 = new System.Windows.Forms.Label(); + this.label2 = new System.Windows.Forms.Label(); + this.SuspendLayout(); + // + // lblVersion + // + this.lblVersion.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.lblVersion.Location = new System.Drawing.Point(12, 115); + this.lblVersion.Name = "lblVersion"; + this.lblVersion.Size = new System.Drawing.Size(445, 15); + this.lblVersion.TabIndex = 6; + this.lblVersion.Text = "label1"; + this.lblVersion.TextAlign = System.Drawing.ContentAlignment.TopCenter; + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, ((System.Drawing.FontStyle)((System.Drawing.FontStyle.Bold | System.Drawing.FontStyle.Underline))), System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.label1.ForeColor = System.Drawing.Color.Blue; + this.label1.Location = new System.Drawing.Point(279, 142); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(178, 16); + this.label1.TabIndex = 7; + this.label1.Text = "http://www.romvault.com/"; + this.label1.Click += new System.EventHandler(this.label1_Click); + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, ((System.Drawing.FontStyle)((System.Drawing.FontStyle.Bold | System.Drawing.FontStyle.Underline))), System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.label2.ForeColor = System.Drawing.Color.Blue; + this.label2.Location = new System.Drawing.Point(12, 142); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(167, 16); + this.label2.TabIndex = 8; + this.label2.Text = "support@romvault.com"; + this.label2.Click += new System.EventHandler(this.label2_Click); + // + // frmHelpAbout + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.BackgroundImage = global::ROMVault2.rvImages.romvaultTZ; + this.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None; + this.ClientSize = new System.Drawing.Size(471, 172); + this.Controls.Add(this.label2); + this.Controls.Add(this.label1); + this.Controls.Add(this.lblVersion); + this.DoubleBuffered = true; + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow; + this.Name = "frmHelpAbout"; + this.ShowInTaskbar = false; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "frmHelpAbout"; + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Label lblVersion; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Label label2; + } +} \ No newline at end of file diff --git a/ROMVault2/frmHelpAbout.cs b/ROMVault2/frmHelpAbout.cs new file mode 100644 index 0000000..d03e933 --- /dev/null +++ b/ROMVault2/frmHelpAbout.cs @@ -0,0 +1,40 @@ +/****************************************************** + * ROMVault2 is written by Gordon J. * + * Contact gordon@romvault.com * + * Copyright 2014 * + ******************************************************/ + +using System; +using System.Windows.Forms; + +namespace ROMVault2 +{ + public partial class frmHelpAbout : Form + { + public frmHelpAbout() + { + + InitializeComponent(); + Text = "Version "+Program.Version+"." + Program.SubVersion + " : " + Application.StartupPath; + lblVersion.Text = "Version "+Program.Version+"." + Program.SubVersion; + } + + private void label1_Click(object sender, EventArgs e) + { + string url = "http://www.romvault.com/"; + System.Diagnostics.Process.Start(url); + } + + private void label2_Click(object sender, EventArgs e) + { + try + { + string url = "mailto:support@romvault.com?subject=Support " + Program.Version + "." + Program.SubVersion; + System.Diagnostics.Process.Start(url); + } + catch + { } + } + + } +} diff --git a/ROMVault2/frmHelpAbout.resx b/ROMVault2/frmHelpAbout.resx new file mode 100644 index 0000000..5ea0895 --- /dev/null +++ b/ROMVault2/frmHelpAbout.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/ROMVault2/frmKey.Designer.cs b/ROMVault2/frmKey.Designer.cs new file mode 100644 index 0000000..b2f0c2c --- /dev/null +++ b/ROMVault2/frmKey.Designer.cs @@ -0,0 +1,55 @@ +namespace ROMVault2 +{ + partial class frmKey + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(frmKey)); + this.SuspendLayout(); + // + // frmKey + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.BackColor = System.Drawing.SystemColors.ControlDark; + this.ClientSize = new System.Drawing.Size(600, 532); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow; + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Name = "frmKey"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "Color Key to ROM Status"; + this.Load += new System.EventHandler(this.frmKey_Load); + this.ResumeLayout(false); + + } + + #endregion + + + + } +} \ No newline at end of file diff --git a/ROMVault2/frmKey.cs b/ROMVault2/frmKey.cs new file mode 100644 index 0000000..55e5b06 --- /dev/null +++ b/ROMVault2/frmKey.cs @@ -0,0 +1,117 @@ +/****************************************************** + * ROMVault2 is written by Gordon J. * + * Contact gordon@romvault.com * + * Copyright 2014 * + ******************************************************/ + +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Windows.Forms; + +namespace ROMVault2 +{ + public partial class frmKey : Form + { + public frmKey() + { + InitializeComponent(); + } + + private void frmKey_Load(object sender, EventArgs e) + { + List displayList= new List + { + RepStatus.Missing, + RepStatus.Correct, + RepStatus.NotCollected, + RepStatus.UnNeeded, + RepStatus.Unknown, + RepStatus.InToSort, + RepStatus.Corrupt, + RepStatus.UnScanned, + RepStatus.Ignore, + RepStatus.CanBeFixed, + RepStatus.MoveToSort, + RepStatus.Delete, + RepStatus.NeededForFix, + }; + Height = displayList.Count * 44 + 32; + for (int i = 0; i < displayList.Count; i++) + { + PictureBox pictureBox = new PictureBox(); + pictureBox.BorderStyle = BorderStyle.FixedSingle; + pictureBox.Location = new Point(4, 4 + i * 44); + pictureBox.Name = "pictureBox" + i; + pictureBox.Size = new Size(48, 42); + pictureBox.TabIndex = 0; + pictureBox.TabStop = false; + + Controls.Add(pictureBox); + + Bitmap bm = rvImages.GetBitmap("G_" + displayList[i]); + pictureBox.Image = bm; + + Label label = new Label(); + label.BackColor = SystemColors.Control; + label.BorderStyle = BorderStyle.FixedSingle; + label.Location = new Point(54, 4 + i * 44); + label.TextAlign = ContentAlignment.MiddleLeft; + label.Name = "label" + i; + label.Size = new Size(542, 42); + label.TabIndex = 0; + + String text; + switch (displayList[i]) + { + case RepStatus.Missing: + text = "Red - This ROM is missing."; + break; + case RepStatus.Correct: + text = "Green - This ROM is Correct."; + break; + case RepStatus.NotCollected: + text = "Gray - This ROM is not collected. Either it is in the parent set, or it is a 'BadDump ROM'"; + break; + case RepStatus.UnNeeded: + text = "Light Cyan - This ROM is unneeded here, as this ROM is collected in the parent set."; + break; + case RepStatus.Unknown: + text = "Cyan - This ROM is not needed here. (Find Fixes to see what should be done with this ROM)"; + break; + case RepStatus.InToSort: + text = "Magenta - This ROM is in the ToSort directory, after Finding Fixes this ROM is not needed in any sets."; + break; + case RepStatus.Corrupt: + text = "Red - This ROM is Corrupt in the Zip File."; + break; + case RepStatus.UnScanned: + text = "Blue - This file could not be scanned as it is locked by another process."; + break; + case RepStatus.Ignore: + text = "GreyBlue - This file is found in the Ignore file list."; + break; + case RepStatus.CanBeFixed: + text = "Yellow - This ROM is missing here but has been found somewhere else, and so can be fixed."; + break; + case RepStatus.MoveToSort: + text = "Purple - This ROM is not found in any DAT set, and so will be moved out to ToSort."; + break; + case RepStatus.Delete: + text = "Brown - This ROM should be deleted, as a copy of it is correctly located somewhere else."; + break; + case RepStatus.NeededForFix: + text = "Orange - This Rom in not needed here, but is required in another set somewhere else."; + break; + + default: + text = ""; + break; + } + + label.Text = text; + Controls.Add(label); + } + } + } +} diff --git a/ROMVault2/frmKey.resx b/ROMVault2/frmKey.resx new file mode 100644 index 0000000..1e12950 --- /dev/null +++ b/ROMVault2/frmKey.resx @@ -0,0 +1,1787 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + AAABAAUAEBAAAAAAIABoBAAAVgAAACAgAAAAACAAqBAAAL4EAAAwMAAAAAAgAKglAABmFQAAQEAAAAAA + IAAoQgAADjsAAICAAAAAACAAKAgBADZ9AAAoAAAAEAAAACAAAAABACAAAAAAAEAEAAAAAAAAAAAAAAAA + AAAAAAAA7e3tvevr6//m5ub/4ODg/9nZ2f/Q0ND/wsLC/66urv+ampr/nJyc/6Kiov+tra3/ubm5/8XF + xf/R0dH/2trapenp6b3l5eX/3t7e/9bW1v/Kysr/ubm5/5+fn/92dnb/ampq/21tbf97e3v/jIyM/56e + nv+wsLD/wsLC/8/Pz6Xl5eW939/f/9bW1v/Jycn/uLi4/5ycnP9ubm7/YWFh/2pqav8tLS3/RERE/2lp + af+AgID/mJiY/7Kysv/FxcWl39/fvdjY2P/Ly8v/ubm5/56env9ycnL/VlZW/2RkZP92dnb/IyMj/yAg + IP8qKir/VlZW/319ff+ioqL/v7+/pdnZ2b3Nzc3/u7u7/6Kiov94eHj/U1NT/15eXv99fX3/IiIi/yYm + Jv8lJSX/IyMj/yAgIP8+Pj7/hoaG/76+vqXQ0NC9wMDA/6ampv+AgID/U1NT/1tbW/+BgYH/ISEh/yUl + Jf8lJSX/JiYm/yYmJv8lJSX/IiIi/2BgYP/Dw8OlxsbGva6urv+Hh4f/VlZW/1paWv+BgYH/JCQk/yUl + Jf8kJCT/JSUl/yUlJf8mJib/JiYm/yQkJP91dXX/zc3Npby8vL2Wlpb/XV1d/1tbW/+AgID/JiYm/zs7 + O/9ubm7/YWFh/ykpKf8kJCT/JSUl/yUlJf9ZWVn/xcXF/9XV1aW4uLi9dXV1/2JiYv9/f3//Kysr/0BA + QP/FxcX/zMzM/8vLy/+hoaH/JCQk/yQkJP9NTU3/v7+//9LS0v/c3NylvLy8vXJycv9/f3//NjY2/yMj + I/9lZWX/zc3N/83Nzf/MzMz/ycnJ/ykpKf9DQ0P/uLi4/9DQ0P/c3Nz/4+PjpcDAwL1/f3//QkJC/yQi + Iv8jIyP/Li4u/6ioqP/MzMz/ysrK/3h4eP88PDz/s7Oz/8/Pz//b29v/4+Pj/+jo6KXR0dG9bm5u/yQi + Iv9hJRr/SCQd/0QkHv8yJCH/Ozs7/zExMf82Njb/r6+v/9HR0f/b29v/4+Pj/+jo6P/s7Oyl29vbvX9/ + f/8lJSX/PiMe/1okGv9dJBr/VSQc/zokIP8yMjL/rq6u/9XV1f/e3t7/5OTk/+np6f/t7e3/8PDwpeXl + 5b3f39//t7e3/2tra/8lJSX/RyMd/1QlHP8vLi7/ra2t/93d3f/j4+P/6Ojo/+vr6//u7u7/8fHx//Pz + 86Xs7Oy96enp/+bm5v/i4uL/n5+f/zY2Nv9JSUn/q6ur/+bm5v/p6en/7Ozs/+7u7v/w8PD/8vLy//T0 + 9P/19fWl8fHxvfDw8P/u7u7/7Ozs/+rq6v/g4OD/39/f/+zs7P/u7u7/7+/v//Hx8f/y8vL/9PT0//X1 + 9f/29vb/9/f3pQAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA + //8AAP//AAD//wAA//8oAAAAIAAAAEAAAAABACAAAAAAAIAQAAAAAAAAAAAAAAAAAAAAAAAA7+/vee7u + 7v/t7e3/6+vr/+np6f/n5+f/5OTk/+Hh4f/e3t7/29vb/9fX1//T09P/zc3N/8XFxf++vr7/uLi4/7Cw + sP+rq6v/qKio/6ioqP+rq6v/rq6u/7Kysv+4uLj/vb29/8LCwv/Hx8f/zMzM/9HR0f/X19f/3Nzc/9/f + 303t7e157Ozs/+rq6v/o6Oj/5ubm/+Pj4//g4OD/3Nzc/9jY2P/U1NT/z8/P/8jIyP/AwMD/tra2/6qq + qv+YmJj/goKC/42Njf+NjY3/kZGR/5aWlv+bm5v/oqKi/6qqqv+wsLD/tra2/729vf/Dw8P/ysrK/9HR + 0f/X19f/29vbTevr63nq6ur/6Ojo/+Xl5f/i4uL/3t7e/9vb2//W1tb/0tLS/8zMzP/ExMT/u7u7/7Gx + sf+jo6P/kJCQ/3Z2dv9mZmb/c3Nz/3R0dP96enr/gICA/4iIiP+RkZH/mZmZ/6Ghof+pqan/sbGx/7m5 + uf/CwsL/ysrK/9HR0f/W1tZN6enpeefn5//l5eX/4uLi/97e3v/a2tr/1dXV/9DQ0P/Kysr/wsLC/7m5 + uf+tra3/n5+f/4mJif9ra2v/aWlp/29vb/9hYWH/YWFh/2dnZ/9tbW3/dXV1/35+fv+IiIj/kpKS/5yc + nP+lpaX/r6+v/7m5uf/CwsL/y8vL/9HR0U3n5+d55eXl/+Li4v/f39//29vb/9bW1v/Q0ND/ycnJ/8LC + wv+4uLj/ra2t/52dnf+IiIj/a2tr/0tLS/9oaGj/enp6/1hYWP9ERET/Ly8v/1NTU/9kZGT/bW1t/3d3 + d/+CgoL/jY2N/5iYmP+kpKT/sLCw/7u7u//Gxsb/zMzMTeXl5Xnj4+P/39/f/9vb2//X19f/0dHR/8rK + yv/BwcH/uLi4/62trf+enp7/iYmJ/2tra/9bW1v/WFhY/3h4eP91dXX/X19f/yAgIP8iIiL/Hx8f/zk5 + Of9aWlr/Z2dn/3Jycv9+fn7/i4uL/5mZmf+np6f/tbW1/8HBwf/JyclN4uLieeDg4P/c3Nz/2NjY/9LS + 0v/Kysr/wsLC/7i4uP+tra3/n5+f/4uLi/9tbW3/Q0ND/11dXf9dXV3/aWlp/5WVlf+QkJD/IiIi/yEh + If8eHh7/Hh4e/yQkJP9HR0f/YmJi/29vb/99fX3/jIyM/52dnf+vr6//vr6+/8fHx03g4OB53d3d/9jY + 2P/T09P/zMzM/8PDw/+5ubn/rq6u/6CgoP+MjIz/cnJy/19fX/9NTU3/ampq/3d3d/9TU1P/jo6O/yYm + Jv8jIyP/JiYm/yQkJP8hISH/Hh4e/x4eHv8wMDD/WFhY/21tbf99fX3/kpKS/6mpqf+8vLz/xsbGTd7e + 3nna2tr/1NTU/83Nzf/ExMT/u7u7/6+vr/+hoaH/j4+P/3V1df9HR0f/Wlpa/1ZWVv9paWn/fn5+/5ub + m/8dHR3/IyMj/yYmJv8mJib/JiYm/yUlJf8jIyP/Hx8f/x4eHv8hISH/QEBA/2xsbP+IiIj/o6Oj/7u7 + u//Hx8dN2traedXV1f/Ozs7/xsbG/7y8vP+xsbH/pKSk/5KSkv97e3v/ZGRk/0pKSv9gYGD/dXV1/0JC + Qv+qqqr/MjIy/yMjI/8mJib/JiYm/yYmJv8mJib/JiYm/yUlJf8lJSX/ISEh/x8fH/8fHx//LS0t/1JS + Uv+cnJz/u7u7/8fHx03W1tZ50dHR/8nJyf+/v7//s7Oz/6ampv+UlJT/fX19/01NTf9ZWVn/WFhY/2ho + aP9ubm7/mJiY/xsbG/8hISH/JSUl/yUlJf8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8lJSX/JCQk/yEh + If8gICD/KSkp/5ycnP++vr7/ycnJTdLS0nnMzMz/wsLC/7a2tv+pqan/l5eX/4KCgv9sbGz/SkpK/1tb + W/91dXX/Nzc3/7W1tf9HR0f/IiIi/yQkJP8lJSX/JSUl/yUlJf8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JSUl/yMjI/8jIyP/mJiY/8XFxf/MzMxNzs7OecfHx/+7u7v/ra2t/5ubm/+Ghob/WVlZ/1lZ + Wf9dXV3/ZWVl/2hoaP+Kior/KSkp/yEhIf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JSUl/zIyMv+goKD/ysrK/9DQ0E3Kysp5wcHB/7Kysv+goKD/ioqK/3Jy + cv9PT0//V1dX/3V1df8zMzP/q6ur/2ZmZv8gICD/JCQk/yUlJf8lJSX/JCQk/yQkJP8kJCT/JSUl/yUl + Jf8lJSX/JiYm/yYmJv8mJib/JiYm/yYmJv8hISH/Q0ND/76+vv/Nzc3/09PTTcXFxXm7u7v/qKio/5GR + kf9mZmb/Xl5e/2JiYv9eXl7/bGxs/3d3d/82Njb/Hx8f/yQkJP8kJCT/JSUl/ycnJ/8lJSX/JCQk/yQk + JP8kJCT/JSUl/yUlJf8lJSX/JSUl/yYmJv8mJib/Kioq/1hYWP+3t7f/ycnJ/9HR0f/X19dNwsLCebW1 + tf+enp7/gYGB/1hYWP9WVlb/dXV1/zg4OP+UlJT/ioqK/x8fH/8kJCT/LCws/3l5ef+tra3/v7+//7S0 + tP+IiIj/OTk5/yQkJP8kJCT/JCQk/yUlJf8lJSX/JSUl/yQkJP8xMTH/sbGx/8bGxv/Ozs7/1tbW/9ra + 2k3BwcF5srKy/4iIiP9xcXH/bGxs/1tbW/92dnb/YWFh/05OTv8eHh7/IyMj/zMzM/+wsLD/zMzM/8vL + y//Ly8v/zMzM/8vLy//BwcH/SkpK/yMjI/8kJCT/JCQk/yUlJf8oKCj/QkJC/6qqqv/ExMT/zMzM/9PT + 0//Z2dn/3d3dTcLCwnm0tLT/enp6/2FhYf97e3v/SEhI/319ff+np6f/ISEh/yEhIf8jIyP/iIiI/8zM + zP/MzMz/zc3N/83Nzf/MzMz/y8vL/8rKyv+vr6//JSUl/yQkJP8kJCT/IyMj/yUlJf+lpaX/w8PD/8vL + y//R0dH/19fX/93d3f/g4OBNw8PDebm5uf+JiYn/Y2Nj/4GBgf9WVlb/Y2Nj/ykpKf8hISH/IyMj/yQk + JP+wsLD/zc3N/83Nzf/Nzc3/zc3N/8zMzP/Ly8v/y8vL/8zMzP8zMzP/JCQk/yUlJf8zMzP/lpaW/8HB + wf/Kysr/0dHR/9fX1//c3Nz/4ODg/+Pj403FxcV5tra2/4aGhv9WVlb/bm5u/7i4uP8rKyv/ISEh/yQk + JP8kJCT/JCQk/52dnf/Nzc3/zc3N/83Nzf/Nzc3/zMzM/8zMzP/Ly8v/wcHB/yoqKv8jIyP/ICAg/5aW + lv/AwMD/ycnJ/9DQ0P/X19f/3Nzc/+Dg4P/k5OT/5ubmTcnJyXm2trb/jY2N/1JSUv9zc3P/PDw8/yEh + If8jIyP/IyMj/yMjI/8kJCT/T09P/8nJyf/Nzc3/zc3N/83Nzf/Nzc3/zMzM/8vLy/95eXn/JCQk/ygo + KP+Dg4P/wMDA/8jIyP/Q0ND/1tbW/9vb2//g4OD/4+Pj/+bm5v/o6OhNzc3NecDAwP9nZ2f/tLS0/zw8 + PP8eHh7/IiIi/ysiIf8iIiL/IyMj/yMjI/8jIyP/VlZW/7e3t//MzMz/zc3N/8zMzP/ExMT/d3d3/yYm + Jv8dHR3/h4eH/8HBwf/Jycn/0NDQ/9bW1v/b29v/39/f/+Pj4//m5ub/6enp/+vr603S0tJ5zMzM/6mp + qf9VVVX/ICAg/yMjI/84Ix//ayYa/yIiIf8qIiH/NCMg/zQjIP8jIyP/JiYm/0hISP9dXV3/UVFR/y0t + Lf8jIyP/IiIi/2tra//BwcH/ysrK/9HR0f/W1tb/29vb/9/f3//j4+P/5ubm/+np6f/r6+v/7e3tTdfX + 13nS0tL/kpKS/ygoKP8jIyP/KyIg/3omF/9mJRn/cyYY/14lGv9TJRz/UyUc/1ckG/8oIyH/IyMj/yMj + I/8jIyP/IyMj/x0dHf93d3f/xMTE/8vLy//S0tL/19fX/9vb2//f39//4+Pj/+bm5v/o6Oj/6+vr/+3t + 7f/u7u5N29vbedfX1/+FhYX/IyMj/yMjI/8jISH/TyQc/2QkGP9yJhj/WyQa/2slGf86Ix7/XCUb/2Ml + G/8+Ix//JSMi/yMjI/8hISH/VVVV/8bGxv/Ozs7/1NTU/9nZ2f/d3d3/4ODg/+Pj4//m5ub/6Ojo/+vr + 6//t7e3/7+/v//Dw8E3g4OB53d3d/9PT0/9/f3//LCws/yIiIv8hISH/ISEh/0UjHf9XIxr/bCUY/2El + Gv8/Ix7/VSQc/10mG/8nIyL/Hx8f/2VlZf/Kysr/09PT/9fX1//b29v/39/f/+Li4v/l5eX/5+fn/+np + 6f/r6+v/7e3t/+/v7//w8PD/8fHxTeTk5Hni4uL/3t7e/9vb2//Dw8P/YGBg/yQkJP8iIiL/ISEh/yEh + If9fJRr/ZSUZ/1IkHP9eJRv/JSMi/yIiIv9AQED/ysrK/9jY2P/b29v/39/f/+Li4v/l5eX/5+fn/+np + 6f/q6ur/7Ozs/+7u7v/v7+//8fHx//Ly8v/z8/NN6Ojoeebm5v/k5OT/4eHh/9/f3//c3Nz/v7+//6io + qP8vLy//IiIi/yEhIf81IyD/ZiYa/zskIP8gICD/VFRU/83Nzf/d3d3/4ODg/+Pj4//l5eX/5+fn/+np + 6f/r6+v/7Ozs/+3t7f/v7+//8PDw//Hx8f/y8vL/8/Pz//T09E3s7Ox56+vr/+np6f/n5+f/5OTk/+Li + 4v/h4eH/39/f/5aWlv8wMDD/IiIi/yIiIv8jIyP/IiIi/ywsLP/Gxsb/4uLi/+Tk5P/m5ub/6Ojo/+np + 6f/r6+v/7Ozs/+7u7v/v7+//8PDw//Hx8f/y8vL/8/Pz//Pz8//09PT/9fX1Te7u7nnt7e3/7Ozs/+vr + 6//p6en/6Ojo/+bm5v/k5OT/4+Pj/9PT0/9vb2//JiYm/y0tLf+ysrL/1NTU/+bm5v/n5+f/6enp/+rq + 6v/s7Oz/7e3t/+7u7v/v7+//8PDw//Hx8f/y8vL/8vLy//Pz8//09PT/9fX1//X19f/29vZN8fHxefDw + 8P/v7+//7u7u/+3t7f/s7Oz/6urq/+np6f/o6Oj/6Ojo/+jo6P++vr7/urq6/+np6f/q6ur/6+vr/+vr + 6//t7e3/7u7u/+/v7//v7+//8PDw//Hx8f/y8vL/8/Pz//Pz8//09PT/9PT0//X19f/29vb/9vb2//f3 + 903z8/N58vLy//Hx8f/w8PD/8PDw/+/v7//u7u7/7e3t/+3t7f/s7Oz/7e3t/+3t7f/t7e3/7e3t/+3t + 7f/u7u7/7+/v//Dw8P/w8PD/8fHx//Ly8v/y8vL/8/Pz//T09P/09PT/9fX1//X19f/29vb/9vb2//f3 + 9//39/f/9/f3TQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAKAAAADAAAABgAAAAAQAgAAAAAACAJQAAAAAAAAAAAAAAAAAAAAAAAPDw + 8Dfv7+//7u7u/+3t7f/s7Oz/6+vr/+rq6v/p6en/5+fn/+Xl5f/j4+P/4eHh/9/f3//d3d3/29vb/9nZ + 2f/X19f/1NTU/9DQ0P/Ly8v/x8fH/8LCwv++vr7/urq6/7a2tv+xsbH/rq6u/62trf+srKz/rKys/62t + rf+vr6//sbGx/7S0tP+3t7f/u7u7/76+vv/BwcH/xcXF/8jIyP/Ly8v/z8/P/9LS0v/V1dX/2NjY/9zc + 3P/f39/x////Ae7u7jfu7u7/7e3t/+zs7P/r6+v/6enp/+jo6P/m5ub/5eXl/+Pj4//g4OD/3t7e/9zc + 3P/Z2dn/19fX/9TU1P/R0dH/zc3N/8jIyP/CwsL/vLy8/7e3t/+xsbH/qqqq/6Ojo/+enp7/nJyc/5ub + m/+cnJz/np6e/6CgoP+jo6P/pqam/6qqqv+urq7/srKy/7a2tv+6urr/vr6+/8HBwf/FxcX/ycnJ/83N + zf/R0dH/1dXV/9nZ2f/c3Nzx////Ae3t7Tfs7Oz/6+vr/+rq6v/p6en/6Ojo/+bm5v/k5OT/4uLi/+Dg + 4P/d3d3/29vb/9jY2P/V1dX/0tLS/87Ozv/Kysr/xMTE/7+/v/+5ubn/sbGx/6ioqP+fn5//ioqK/21t + bf+Ghob/iIiI/4iIiP+Li4v/jo6O/5GRkf+VlZX/mZmZ/56env+kpKT/qKio/62trf+xsbH/tbW1/7q6 + uv++vr7/w8PD/8jIyP/MzMz/0dHR/9XV1f/Z2dnx////Aezs7Dfr6+v/6urq/+jo6P/n5+f/5eXl/+Pj + 4//h4eH/39/f/9zc3P/Z2dn/19fX/9TU1P/Q0ND/zMzM/8fHx//CwsL/vLy8/7a2tv+urq7/pKSk/5iY + mP+MjIz/cHBw/2JiYv9zc3P/dnZ2/3d3d/96enr/fn5+/4ODg/+Hh4f/jIyM/5KSkv+YmJj/nZ2d/6Oj + o/+oqKj/ra2t/7Kysv+3t7f/vb29/8LCwv/Hx8f/zMzM/9HR0f/W1tbx////Aerq6jfp6en/6Ojo/+fn + 5//l5eX/4+Pj/+Hh4f/e3t7/3Nzc/9nZ2f/W1tb/09PT/8/Pz//Ly8v/xsbG/8DAwP+6urr/s7Oz/6ur + q/+hoaH/lJSU/4WFhf94eHj/ampq/2hoaP9oaGj/ZmZm/2hoaP9tbW3/cXFx/3V1df96enr/f39//4aG + hv+MjIz/kpKS/5iYmP+enp7/pKSk/6qqqv+wsLD/tra2/7y8vP/CwsL/x8fH/83Nzf/S0tLx////Aenp + 6Tfo6Oj/5ubm/+Xl5f/j4+P/4eHh/9/f3//c3Nz/2dnZ/9bW1v/S0tL/zs7O/8rKyv/FxcX/v7+//7i4 + uP+xsbH/qamp/5+fn/+RkZH/f39//2BgYP9nZ2f/aGho/29vb/9vb2//W1tb/11dXf9hYWH/ZWVl/2lp + af9ubm7/c3Nz/3p6ev+AgID/h4eH/42Njf+UlJT/m5ub/6Ghof+oqKj/r6+v/7W1tf+8vLz/wsLC/8nJ + yf/Ozs7x////Aejo6Dfn5+f/5eXl/+Pj4//h4eH/39/f/9zc3P/Z2dn/1tbW/9LS0v/Ozs7/ycnJ/8TE + xP+/v7//uLi4/7Gxsf+oqKj/nZ2d/5CQkP+AgID/ZmZm/0pKSv9XV1f/a2tr/3R0dP9xcXH/UlJS/1NT + U/84ODj/PT09/1tbW/9jY2P/aGho/25ubv91dXX/fHx8/4ODg/+Kior/kZGR/5mZmf+goKD/qKio/6+v + r/+3t7f/vr6+/8XFxf/Ly8vx////Aefn5zfm5ub/4+Pj/+Hh4f/f39//3Nzc/9ra2v/W1tb/09PT/87O + zv/Jycn/xMTE/76+vv+4uLj/sLCw/6ioqP+enp7/kJCQ/4GBgf9vb2//Xl5e/01NTf9VVVX/cXFx/42N + jf9xcXH/S0tL/zExMf8gICD/Hh4e/ygoKP9JSUn/XV1d/2NjY/9paWn/cXFx/3h4eP+AgID/iIiI/5CQ + kP+YmJj/oKCg/6mpqf+ysrL/urq6/8LCwv/Jycnx////AeXl5Tfk5OT/4uLi/9/f3//d3d3/2tra/9fX + 1//T09P/z8/P/8rKyv/FxcX/v7+//7i4uP+xsbH/qKio/5+fn/+RkZH/gYGB/2ZmZv9eXl7/WVlZ/2Nj + Y/9aWlr/i4uL/2tra/93d3f/VFRU/x0dHf8kJCT/Hh4e/x4eHv8eHh7/MjIy/1JSUv9eXl7/ZmZm/25u + bv91dXX/fn5+/4eHh/+QkJD/mZmZ/6Ojo/+tra3/tra2/7+/v//Gxsbx////AePj4zfi4uL/4ODg/93d + 3f/b29v/2NjY/9TU1P/Pz8//ysrK/8XFxf+/v7//uLi4/7Gxsf+pqan/n5+f/5OTk/+CgoL/ampq/0ZG + Rv9ISEj/YWFh/2VlZf9dXV3/cHBw/3Jycv/CwsL/jIyM/yQkJP8fHx//Hx8f/x4eHv8eHh7/HR0d/yEh + If8+Pj7/Wlpa/2NjY/9ra2v/dHR0/319ff+Hh4f/kZGR/5ycnP+np6f/s7Oz/7y8vP/FxcXx////AeLi + 4jfg4OD/3t7e/9vb2//Y2Nj/1dXV/9HR0f/Ly8v/xsbG/8DAwP+5ubn/srKy/6mpqf+fn5//kpKS/4SE + hP9zc3P/YWFh/0RERP9FRUX/ampq/3x8fP9WVlb/Xl5e/7e3t/+zs7P/KCgo/yIiIv8kJCT/JiYm/yIi + Iv8fHx//Hh4e/x4eHv8eHh7/KSkp/0xMTP9hYWH/ampq/3Nzc/99fX3/iIiI/5SUlP+ioqL/r6+v/7u7 + u//ExMTx////AeDg4Dff39//3Nzc/9nZ2f/V1dX/0dHR/8zMzP/Hx8f/wcHB/7q6uv+ysrL/qqqq/6Gh + of+Tk5P/hISE/3BwcP9lZWX/W1tb/15eXv9GRkb/fHx8/39/f/9hYWH/RERE/4iIiP8uLi7/IiIi/yMj + I/8lJSX/JiYm/yUlJf8kJCT/ISEh/x8fH/8eHh7/Hh4e/x8fH/83Nzf/Wlpa/2dnZ/9xcXH/fX19/42N + jf+cnJz/q6ur/7m5uf/ExMTx////Ad/f3zfd3d3/2tra/9bW1v/R0dH/zc3N/8fHx//BwcH/u7u7/7Oz + s/+rq6v/oaGh/5aWlv+Hh4f/c3Nz/0pKSv9LS0v/XFxc/2ZmZv9GRkb/hISE/2JiYv+dnZ3/mpqa/xwc + HP8cHBz/IyMj/yYmJv8mJib/JSUl/yYmJv8mJib/JSUl/yMjI/8fHx//Hx8f/x4eHv8eHh7/JSUl/0VF + Rf9jY2P/dHR0/4aGhv+YmJj/qamp/7i4uP/ExMTx////Ad3d3Tfb29v/19fX/9LS0v/Ozs7/yMjI/8LC + wv+8vLz/tLS0/6ysrP+jo6P/l5eX/4mJif94eHj/ZmZm/0hISP9DQ0P/ZWVl/3Jycv89PT3/V1dX/5aW + lv/a2tr/Pj4+/yIiIv8kJCT/JiYm/yYmJv8lJSX/JSUl/yYmJv8lJSX/JiYm/yUlJf8kJCT/ISEh/x8f + H/8fHx//Hx8f/x8fH/8xMTH/YWFh/3BwcP+Li4v/paWl/7e3t//ExMTx////Advb2zfY2Nj/1NTU/8/P + z//Jycn/xMTE/729vf+1tbX/ra2t/6SkpP+ZmZn/jIyM/3t7e/9ra2v/X19f/1ZWVv9CQkL/cHBw/42N + jf9OTk7/ODg4/7S0tP9JSUn/IyMj/yIiIv8mJib/JiYm/yYmJv8lJSX/JiYm/yYmJv8mJib/JiYm/yYm + Jv8lJSX/JSUl/yMjI/8gICD/Hx8f/yAgIP8gICD/IiIi/zk5Of91dXX/paWl/7e3t//FxcXx////AdjY + 2DfV1dX/0NDQ/8vLy//FxcX/v7+//7e3t/+vr6//paWl/5ubm/+NjY3/fX19/1RUVP9OTk7/W1tb/2Rk + ZP8/Pz//i4uL/1xcXP+FhYX/h4eH/xsbG/8eHh7/ISEh/yUlJf8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8lJSX/IiIi/yAgIP8gICD/ICAg/yAgIP9jY2P/pqam/7q6 + uv/Gxsbx////AdXV1TfT09P/zc3N/8fHx//AwMD/ubm5/7CwsP+np6f/nJyc/4+Pj/+AgID/b29v/01N + Tf9AQED/YWFh/2xsbP83Nzf/VlZW/319ff/Y2Nj/aWlp/yEhIf8fHx//JCQk/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yYmJv8lJSX/JiYm/yUlJf8lJSX/JiYm/yUlJf8lJSX/JSUl/yUlJf8gICD/ICAg/yAg + IP9YWFj/paWl/7+/v//IyMjx////AdPT0zfQ0ND/ysrK/8PDw/+7u7v/srKy/6mpqf+enp7/kZGR/4SE + hP90dHT/ZWVl/1RUVP8/Pz//aWlp/4qKiv9LS0v/NjY2/7u7u/+BgYH/JCQk/yEhIf8kJCT/JSUl/yQk + JP8lJSX/JSUl/yUlJf8lJSX/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8lJSX/JCQk/yAgIP9TU1P/paWl/8PDw//Ly8vx////AdDQ0DfNzc3/xsbG/76+vv+2trb/rKys/6Gh + of+UlJT/hoaG/2VlZf9VVVX/XV1d/2NjY/89PT3/hISE/2tra/9ubm7/YmJi/zY2Nv8jIyP/IiIi/yYm + Jv8lJSX/JCQk/yUlJf8lJSX/JCQk/yUlJf8lJSX/JSUl/yUlJf8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8lJSX/JiYm/yYmJv8lJSX/JiYm/yYmJv9sbGz/qKio/8fHx//Ozs7x////Ac3NzTfJycn/wsLC/7m5 + uf+vr6//pKSk/5eXl/+IiIj/dnZ2/1RUVP9BQUH/Xl5e/2pqav83Nzf/YWFh/2pqav+5ubn/pqam/yAg + IP8bGxv/IyMj/yQkJP8kJCT/JSUl/yUlJf8kJCT/JCQk/yQkJP8lJSX/JSUl/yUlJf8lJSX/JiYm/yUl + Jf8mJib/JiYm/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/xoaGv9iYmL/u7u7/8rKyv/Q0NDx////AcvL + yzfGxsb/vr6+/7Ozs/+np6f/mpqa/4uLi/96enr/bGxs/1hYWP8+Pj7/ZGRk/35+fv9UVFT/NjY2/6en + p/+4uLj/Jycn/yEhIf8iIiL/JCQk/yUlJf8lJSX/JSUl/yQkJP8kJCT/JCQk/yQkJP8lJSX/JSUl/yUl + Jf8lJSX/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8lJSX/HBwc/zU1Nf+vr6//xsbG/83N + zf/S0tLx////AcjIyDfDw8P/ubm5/62trf+goKD/kJCQ/3Z2dv9cXFz/Y2Nj/2NjY/9GRkb/cHBw/4GB + gf9dXV3/R0dH/0FBQf8wMDD/ICAg/yMjI/8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8jIyP/JCQk/yQk + JP8kJCT/JCQk/yUlJf8lJSX/JSUl/yUlJf8lJSX/JiYm/yYmJv8lJSX/JiYm/yUlJf81NTX/Pz8//6mp + qf/ExMT/ysrK/8/Pz//V1dXx////AcbGxjfAwMD/tbW1/6ampv+Xl5f/g4OD/2JiYv9FRUX/X19f/2pq + av9BQUH/bm5u/1xcXP+VlZX/zc3N/yIiIv8YGBj/IyMj/yQkJP8kJCT/KCgo/0VFRf9jY2P/a2tr/11d + Xf89PT3/JiYm/yMjI/8jIyP/JCQk/yQkJP8lJSX/JCQk/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yAg + IP9HR0f/q6ur/8HBwf/Hx8f/zc3N/9LS0v/X19fx////AcTExDe+vr7/sbGx/6Kiov+Pj4//enp6/2Nj + Y/9AQED/Y2Nj/3Z2dv9eXl7/MTEx/4qKiv/Z2dn/Ozs7/yEhIf8kJCT/JCQk/yQkJP9kZGT/srKy/8rK + yv/Ly8v/zMzM/8zMzP/Kysr/qKio/1NTU/8kJCT/JCQk/yQkJP8kJCT/JSUl/yQkJP8lJSX/JSUl/yUl + Jf8lJSX/IyMj/x0dHf+YmJj/wMDA/8bGxv/Ly8v/0NDQ/9XV1f/a2trx////AcTExDe9vb3/rq6u/5ub + m/92dnb/eXl5/2xsbP9VVVX/Y2Nj/5GRkf9XV1f/Nzc3/09PT/9OTk7/ICAg/yIiIv8kJCT/KSkp/4+P + j//MzMz/zMzM/8vLy//Ly8v/zMzM/8zMzP/MzMz/y8vL/8nJyf9/f3//JCQk/yMjI/8kJCT/JCQk/yQk + JP8kJCT/JSUl/yUlJf8rKyv/ISEh/5GRkf+/v7//xcXF/8rKyv/Pz8//09PT/9jY2P/c3Nzx////AcTE + xDe9vb3/rq6u/4qKiv9SUlL/cHBw/3Jycv9UVFT/b29v/1paWv9+fn7/y8vL/y4uLv8bGxv/Hx8f/yMj + I/8kJCT/d3d3/8rKyv/Ly8v/zMzM/8zMzP/MzMz/zMzM/8zMzP/Ly8v/ysrK/8rKyv/Jycn/Y2Nj/yMj + I/8jIyP/JCQk/yQkJP8kJCT/JCQk/yQkJP8/Pz//mpqa/729vf/Dw8P/ycnJ/83Nzf/S0tL/1tbW/9ra + 2v/e3t7x////AcTExDe/v7//sbGx/42Njf9MTEz/cHBw/3p6ev9qamr/OTk5/3V1df/Q0ND/bW1t/yAg + IP8fHx//IyMj/yQkJP8xMTH/wMDA/8zMzP/MzMz/zc3N/83Nzf/Nzc3/zc3N/8zMzP/Ly8v/y8vL/8rK + yv/Ly8v/srKy/ygoKP8kJCT/JCQk/yQkJP8kJCT/IiIi/xMTE/95eXn/u7u7/8PDw//IyMj/zc3N/9HR + 0f/W1tb/2dnZ/9zc3P/g4ODx////AcXFxTfAwMD/tbW1/5KSkv9qamr/ZWVl/5KSkv9lZWX/Ojo6/2ho + aP98fHz/ICAg/x8fH/8jIyP/JCQk/yQkJP9NTU3/zc3N/83Nzf/MzMz/zc3N/83Nzf/Nzc3/zc3N/83N + zf/MzMz/y8vL/8vLy//MzMz/y8vL/zg4OP8kJCT/JCQk/yQkJP8mJib/FRUV/29vb/+4uLj/wcHB/8fH + x//Nzc3/0dHR/9XV1f/Z2dn/3Nzc/9/f3//i4uLx////AcbGxjfBwcH/t7e3/4uLi/9vb2//aGho/29v + b/9paWn/srKy/zw8PP8jIyP/ICAg/yQkJP8jIyP/JCQk/yMjI/9MTEz/zMzM/8zMzP/MzMz/zMzM/83N + zf/Nzc3/zc3N/8zMzP/MzMz/zMzM/8zMzP/MzMz/y8vL/zs7O/8jIyP/JCQk/yQkJP85OTn/gICA/7m5 + uf/AwMD/xsbG/8zMzP/R0dH/1dXV/9jY2P/b29v/39/f/+Hh4f/k5OTx////AcfHxzfDw8P/r6+v/4WF + hf99fX3/Pj4+/2VlZf+xsbH/qamp/yAgIP8fHx//JCQk/yQkJP8jIyP/JCQk/yQkJP8xMTH/wMDA/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/MzMz/zMzM/8vLy//Ly8v/tra2/ykpKf8jIyP/IyMj/xIS + Ev9dXV3/tbW1/8DAwP/Gxsb/zMzM/9DQ0P/V1dX/2NjY/9zc3P/f39//4eHh/+Tk5P/m5ubx////AcnJ + yTfGxsb/rq6u/5CQkP+AgID/ODg4/3p6ev+tra3/JSUl/yAgIP8jIyP/IyMj/yMjI/8jIyP/IyMj/yQk + JP8kJCT/fn5+/83Nzf/MzMz/zc3N/83Nzf/MzMz/zc3N/83Nzf/MzMz/zMzM/8vLy//Kysr/bm5u/yQk + JP8kJCT/FhYW/01NTf+ysrL/wMDA/8bGxv/Ly8v/0NDQ/9TU1P/Y2Nj/29vb/9/f3//h4eH/4+Pj/+Xl + 5f/n5+fx////AczMzDfJycn/tLS0/4mJif9ZWVn/kZGR/05OTv8uLi7/Hx8f/yEhIf8iIiL/IiIi/yIi + Iv8iIiL/IyMj/yMjI/8jIyP/Kysr/5iYmP/MzMz/zMzM/83Nzf/MzMz/zMzM/8zMzP/MzMz/zMzM/8vL + y/+QkJD/Jycn/yMjI/81NTX/ZGRk/7S0tP/BwcH/xsbG/8vLy//Q0ND/1NTU/9jY2P/b29v/3t7e/+Hh + 4f/j4+P/5eXl/+fn5//p6enx////Ac/PzzfMzMz/vb29/11dXf+Ojo7/zs7O/zExMf8cHBz/ISEh/yIi + Iv8iIiL/NSIf/yIiIv8jIyP/IyMj/yMjI/8jIyP/IyMj/ygoKP9xcXH/vb29/8zMzP/Nzc3/zc3N/83N + zf/MzMz/ubm5/2pqav8nJyf/IyMj/xkZGf88PDz/ra2t/8HBwf/Gxsb/y8vL/9DQ0P/U1NT/2NjY/9vb + 2//e3t7/4ODg/+Pj4//l5eX/5+fn/+np6f/q6urx////AdLS0jfPz8//ysrK/62trf/Nzc3/OTk5/x8f + H/8hISH/IyMj/yIiIv9ZJBv/dCcZ/yIiIf8iIiL/IyMj/yMjI/8oIiH/IyIi/yMjI/8jIyP/Kysr/1NT + U/9vb2//fHx8/29vb/9OTk7/Kioq/yMjI/8jIyP/Gxsb/yoqKv+oqKj/wsLC/8fHx//MzMz/0NDQ/9TU + 1P/Y2Nj/29vb/97e3v/g4OD/4uLi/+Xl5f/n5+f/6enp/+rq6v/s7Ozx////AdXV1TfT09P/zs7O/7e3 + t/9CQkL/IiIi/yIiIv8kJCT/IiIi/00jHP+oKhP/SiMc/0MiHP9xJhj/WiQa/1wlG/9+KBj/LSMh/zEj + IP8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/JCQk/yMjI/8vLy//TExM/6mpqf/Dw8P/yMjI/83N + zf/R0dH/1dXV/9jY2P/b29v/3t7e/+Dg4P/j4+P/5eXl/+fn5//o6Oj/6urq/+zs7P/t7e3x////AdnZ + 2TfW1tb/0tLS/7y8vP8zMzP/IyMj/yMjI/8iIiL/NyIe/50pFP8tIR//bSYZ/4knFv85Ix//TyQc/y4i + If9gJhv/XiUb/3ImGP9BIx7/KCMh/yMjI/8jIyP/IyMj/yMjI/8kJCT/IyMj/x4eHv8lJSX/o6Oj/8XF + xf/Kysr/zs7O/9LS0v/W1tb/2dnZ/9zc3P/e3t7/4ODg/+Pj4//l5eX/5+fn/+jo6P/q6ur/6+vr/+3t + 7f/u7u7x////Adzc3DfZ2dn/1dXV/7Gxsf8lJSX/IyMj/yMjI/8iIiL/JCEh/1gkG/97Jhb/aCQX/34n + F/95Jhf/aiUZ/3wmF/88Ix7/UCQc/20mGf9oJhr/bSYZ/zIjIP8iIiL/IyMj/yMjI/8jIyP/ISEh/xkZ + Gf+YmJj/yMjI/8zMzP/Q0ND/1NTU/9fX1//a2tr/3d3d/9/f3//h4eH/4+Pj/+Xl5f/n5+f/6Ojo/+rq + 6v/r6+v/7e3t/+7u7v/v7+/x////Ad/f3zfd3d3/2dnZ/8fHx/9OTk7/JCQk/yMjI/8iIiL/IiIi/yEh + If8pISD/QSMd/0QjHf9pJRn/ISAg/3QlF/9DIx3/WCQb/ywiIP84Ix//aiYa/2UmGv9TJRz/IiIi/yIi + Iv8rKyv/Pj4+/5WVlf/Ly8v/z8/P/9LS0v/V1dX/2dnZ/9zc3P/e3t7/4ODg/+Li4v/k5OT/5eXl/+fn + 5//p6en/6urq/+vr6//t7e3/7u7u/+/v7//w8PDx////AeHh4Tfg4OD/3d3d/9ra2v/V1dX/k5OT/zc3 + N/8iIiL/IiIi/yIiIv8hISH/ISEh/yQhIP9oJRn/cSQX/2glGf+EJxb/PiMe/0kjHP9BIx7/YiUa/28m + Gf8kIyL/IyMj/yIiIv8cHBz/kJCQ/87Ozv/S0tL/1dXV/9jY2P/b29v/3d3d/+Dg4P/i4uL/5OTk/+Xl + 5f/n5+f/6Ojo/+np6f/r6+v/7Ozs/+3t7f/u7u7/7+/v//Dw8P/x8fHx////AeTk5Dfj4+P/4ODg/97e + 3v/b29v/2dnZ/8vLy/91dXX/Kioq/yIiIv8iIiL/IiIi/yEhIf8hISH/ISEg/1wkGv90Jhj/QyIc/4An + F/8mIiH/ZyYa/ygjIv8jIyP/JCQk/xQUFP99fX3/0dHR/9bW1v/Y2Nj/2tra/93d3f/f39//4uLi/+Tk + 5P/l5eX/5+fn/+jo6P/p6en/6urq/+vr6//s7Oz/7u7u/+/v7//w8PD/8PDw//Hx8f/y8vLx////Aefn + 5zfm5ub/4+Pj/+Hh4f/g4OD/3t7e/9zc3P/Z2dn/t7e3/1paWv9PT0//NTU1/yIiIv8hISH/ISEh/yEh + If9UJBz/iSgW/0QjHf9yJhj/VCYd/yMjIv8nJyf/Nzc3/3Z2dv/S0tL/2dnZ/9vb2//e3t7/4ODg/+Li + 4v/k5OT/5eXl/+fn5//o6Oj/6enp/+rq6v/r6+v/7Ozs/+3t7f/u7u7/7+/v//Dw8P/x8fH/8vLy//Ly + 8v/z8/Px////Aenp6Tfp6en/5+fn/+Xl5f/j4+P/4uLi/+Dg4P/e3t7/3d3d/9vb2//a2tr/ysrK/0BA + QP8iIiL/IiIi/yIiIv8iIiL/KCIh/2snGv9RJR7/IyMi/yIiIv8bGxv/eXl5/9bW1v/d3d3/39/f/+Dg + 4P/i4uL/5OTk/+bm5v/n5+f/6Ojo/+np6f/q6ur/6+vr/+zs7P/t7e3/7u7u/+/v7//w8PD/8PDw//Hx + 8f/y8vL/8/Pz//Pz8//09PTx////Aezs7Dfr6+v/6urq/+jo6P/n5+f/5eXl/+Tk5P/j4+P/4eHh/+Dg + 4P/f39//3t7e/5SUlP8rKyv/IiIi/yIiIv8iIiL/IiIi/yMjI/8iIiL/IyMj/xYWFv9SUlL/1dXV/+Hh + 4f/i4uL/4+Pj/+Xl5f/m5ub/5+fn/+np6f/q6ur/6+vr/+zs7P/t7e3/7e3t/+7u7v/v7+//7+/v//Dw + 8P/x8fH/8vLy//Ly8v/z8/P/8/Pz//T09P/19fXx////Ae3t7Tft7e3/7Ozs/+vr6//q6ur/6enp/+fn + 5//m5ub/5eXl/+Tk5P/j4+P/4uLi/+Hh4f/IyMj/YmJi/yQkJP8jIyP/IyMj/yMjI/8kJCT/WFhY/11d + Xf/U1NT/5OTk/+Xl5f/m5ub/5+fn/+jo6P/p6en/6urq/+vr6//s7Oz/7e3t/+7u7v/u7u7/7+/v//Dw + 8P/w8PD/8fHx//Hx8f/y8vL/8/Pz//Pz8//09PT/9PT0//X19f/19fXx////Ae/v7zfu7u7/7u7u/+3t + 7f/s7Oz/6+vr/+rq6v/p6en/6Ojo/+fn5//m5ub/5eXl/+Xl5f/k5OT/4+Pj/7CwsP9HR0f/IyMj/yMj + I/+Dg4P/5OTk/+Xl5f/m5ub/5+fn/+jo6P/p6en/6urq/+vr6//s7Oz/7Ozs/+3t7f/u7u7/7+/v/+/v + 7//w8PD/8fHx//Hx8f/y8vL/8vLy//Ly8v/z8/P/8/Pz//T09P/09PT/9fX1//X19f/29vbx////AfHx + 8Tfw8PD/7+/v/+/v7//u7u7/7e3t/+zs7P/s7Oz/6+vr/+rq6v/p6en/6Ojo/+jo6P/n5+f/6Ojo/+jo + 6P/f39//kZGR/4GBgf/m5ub/6enp/+np6f/p6en/6urq/+vr6//s7Oz/7Ozs/+3t7f/u7u7/7u7u/+/v + 7//v7+//8PDw//Hx8f/x8fH/8vLy//Ly8v/z8/P/8/Pz//Pz8//09PT/9PT0//X19f/19fX/9vb2//b2 + 9v/29vbx////AfLy8jfy8vL/8fHx//Dw8P/w8PD/7+/v/+7u7v/u7u7/7e3t/+zs7P/s7Oz/6+vr/+vr + 6//q6ur/6urq/+rq6v/r6+v/6+vr/+vr6//r6+v/6+vr/+zs7P/s7Oz/7e3t/+3t7f/u7u7/7u7u/+/v + 7//v7+//8PDw//Dw8P/x8fH/8fHx//Ly8v/y8vL/8/Pz//Pz8//09PT/9PT0//T09P/19fX/9fX1//X1 + 9f/29vb/9vb2//f39//39/fx////AfPz8zfz8/P/8vLy//Ly8v/x8fH/8fHx//Dw8P/w8PD/7+/v/+/v + 7//u7u7/7u7u/+3t7f/t7e3/7e3t/+3t7f/t7e3/7e3t/+3t7f/t7e3/7u7u/+7u7v/u7u7/7+/v/+/v + 7//w8PD/8PDw//Dw8P/x8fH/8fHx//Ly8v/y8vL/8/Pz//Pz8//z8/P/9PT0//T09P/19fX/9fX1//X1 + 9f/29vb/9vb2//b29v/29vb/9/f3//f39//39/fx////AQAAAAAAAP//AAAAAAAA//8AAAAAAAD//wAA + AAAAAP//AAAAAAAA//8AAAAAAAD//wAAAAAAAP//AAAAAAAA//8AAAAAAAD//wAAAAAAAP//AAAAAAAA + //8AAAAAAAD//wAAAAAAAP//AAAAAAAA//8AAAAAAAD//wAAAAAAAP//AAAAAAAA//8AAAAAAAD//wAA + AAAAAP//AAAAAAAA//8AAAAAAAD//wAAAAAAAP//AAAAAAAA//8AAAAAAAD//wAAAAAAAP//AAAAAAAA + //8AAAAAAAD//wAAAAAAAP//AAAAAAAA//8AAAAAAAD//wAAAAAAAP//AAAAAAAA//8AAAAAAAD//wAA + AAAAAP//AAAAAAAA//8AAAAAAAD//wAAAAAAAP//AAAAAAAA//8AAAAAAAD//wAAAAAAAP//AAAAAAAA + //8AAAAAAAD//wAAAAAAAP//AAAAAAAA//8AAAAAAAD//wAAAAAAAP//AAAAAAAA//8AAAAAAAD//ygA + AABAAAAAgAAAAAEAIAAAAAAAAEIAAAAAAAAAAAAAAAAAAAAAAAD///8B7+/v8e/v7//u7u7/7u7u/+3t + 7f/s7Oz/6+vr/+rq6v/p6en/6Ojo/+fn5//m5ub/5OTk/+Pj4//h4eH/4ODg/97e3v/d3d3/29vb/9ra + 2v/Y2Nj/19fX/9XV1f/R0dH/zs7O/8vLy//Hx8f/xMTE/8HBwf++vr7/u7u7/7i4uP+1tbX/srKy/7Cw + sP+vr6//rq6u/62trf+urq7/r6+v/7CwsP+xsbH/s7Oz/7W1tf+3t7f/urq6/7y8vP+/v7//wcHB/8TE + xP/Gxsb/yMjI/8vLy//Nzc3/0NDQ/9LS0v/V1dX/19fX/9nZ2f/c3Nz/3t7e/+Dg4Jf///8B////Ae/v + 7/Hu7u7/7e3t/+3t7f/s7Oz/6+vr/+rq6v/p6en/6Ojo/+fn5//l5eX/5OTk/+Li4v/h4eH/39/f/93d + 3f/c3Nz/2tra/9jY2P/W1tb/1dXV/9LS0v/Q0ND/zMzM/8jIyP/ExMT/wMDA/7y8vP+4uLj/tLS0/7Cw + sP+srKz/qKio/6Wlpf+kpKT/o6Oj/6Kiov+ioqL/o6Oj/6Wlpf+np6f/qKio/6qqqv+tra3/sLCw/7Oz + s/+2trb/uLi4/7u7u/++vr7/wcHB/8PDw//Gxsb/ycnJ/8vLy//Ozs7/0dHR/9TU1P/W1tb/2dnZ/9zc + 3P/e3t6X////Af///wHu7u7x7e3t/+zs7P/s7Oz/6+vr/+rq6v/p6en/5+fn/+bm5v/l5eX/5OTk/+Li + 4v/g4OD/3t7e/93d3f/b29v/2dnZ/9fX1//U1NT/0tLS/9DQ0P/Nzc3/ycnJ/8bGxv/BwcH/vLy8/7e3 + t/+ysrL/rq6u/6ioqP+hoaH/k5OT/5iYmP+VlZX/lJSU/5SUlP+VlZX/lpaW/5iYmP+ampr/nJyc/5+f + n/+hoaH/paWl/6mpqf+srKz/r6+v/7Kysv+1tbX/uLi4/7u7u/++vr7/wcHB/8TExP/Hx8f/ysrK/87O + zv/R0dH/1NTU/9fX1//a2tr/3Nzcl////wH///8B7e3t8ezs7P/r6+v/6urq/+np6f/o6Oj/5+fn/+bm + 5v/k5OT/4+Pj/+Hh4f/f39//3t7e/9zc3P/a2tr/2NjY/9XV1f/T09P/0NDQ/87Ozv/Kysr/x8fH/8PD + w/+/v7//urq6/7W1tf+urq7/qKio/6Ghof+ZmZn/fX19/2RkZP94eHj/hoaG/4WFhf+Ghob/h4eH/4qK + iv+MjIz/jo6O/5GRkf+VlZX/mJiY/5ycnP+goKD/pKSk/6enp/+rq6v/rq6u/7Kysv+1tbX/uLi4/7u7 + u/+/v7//w8PD/8bGxv/Kysr/zs7O/9HR0f/U1NT/19fX/9ra2pf///8B////Aezs7PHr6+v/6urq/+np + 6f/o6Oj/5+fn/+Xl5f/k5OT/4uLi/+Hh4f/f39//3d3d/9vb2//Z2dn/19fX/9XV1f/S0tL/z8/P/8zM + zP/IyMj/xcXF/8HBwf+8vLz/uLi4/7Ozs/+tra3/pKSk/5ycnP+Tk5P/ioqK/2pqav9jY2P/ampq/3l5 + ef94eHj/eHh4/3p6ev99fX3/gYGB/4SEhP+Hh4f/i4uL/4+Pj/+Tk5P/l5eX/5ubm/+fn5//o6Oj/6en + p/+rq6v/r6+v/7Kysv+2trb/urq6/76+vv/CwsL/xsbG/8rKyv/Nzc3/0dHR/9XV1f/X19eX////Af// + /wHq6urx6enp/+jo6P/n5+f/5ubm/+Xl5f/k5OT/4uLi/+Dg4P/e3t7/3Nzc/9ra2v/Y2Nj/1tbW/9TU + 1P/R0dH/zs7O/8vLy//Hx8f/w8PD/7+/v/+6urr/tbW1/7CwsP+qqqr/oqKi/5iYmP+Ojo7/g4OD/3p6 + ev9oaGj/ZWVl/2dnZ/9tbW3/bGxs/21tbf9wcHD/c3Nz/3Z2dv96enr/fX19/4GBgf+FhYX/ioqK/46O + jv+Tk5P/l5eX/5ubm/+goKD/pKSk/6ioqP+srKz/sLCw/7W1tf+5ubn/vr6+/8LCwv/Gxsb/ysrK/87O + zv/S0tL/1dXVl////wH///8B6enp8ejo6P/n5+f/5ubm/+Xl5f/k5OT/4uLi/+Dg4P/e3t7/3Nzc/9ra + 2v/Y2Nj/1tbW/9PT0//R0dH/zs7O/8rKyv/Hx8f/w8PD/76+vv+5ubn/s7Oz/66urv+oqKj/oKCg/5aW + lv+MjIz/gICA/3Z2dv9ubm7/Z2dn/2tra/9tbW3/Y2Nj/2JiYv9jY2P/Z2dn/2pqav9tbW3/cHBw/3Nz + c/93d3f/fHx8/4CAgP+FhYX/ioqK/46Ojv+Tk5P/mJiY/52dnf+hoaH/pqam/6urq/+vr6//tLS0/7m5 + uf+9vb3/wsLC/8bGxv/Ly8v/z8/P/9LS0pf///8B////Aejo6PHn5+f/5ubm/+Xl5f/j4+P/4uLi/+Dg + 4P/f39//3d3d/9ra2v/Y2Nj/1tbW/9PT0//Q0ND/zc3N/8rKyv/Hx8f/w8PD/76+vv+4uLj/s7Oz/62t + rf+mpqb/n5+f/5SUlP+Kior/eHh4/1dXV/9fX1//Z2dn/2lpaf9vb2//dHR0/2VlZf9aWlr/W1tb/15e + Xv9hYWH/ZGRk/2dnZ/9qamr/bm5u/3Nzc/93d3f/fHx8/4GBgf+Ghob/i4uL/5CQkP+VlZX/mpqa/5+f + n/+kpKT/qqqq/6+vr/+0tLT/ubm5/76+vv/Dw8P/yMjI/8zMzP/Pz8+X////Af///wHo6Ojx5ubm/+Xl + 5f/k5OT/4uLi/+Dg4P/f39//3d3d/9vb2//Y2Nj/1tbW/9PT0//Q0ND/zc3N/8nJyf/Gxsb/wsLC/729 + vf+4uLj/s7Oz/62trf+mpqb/nZ2d/5SUlP+IiIj/fHx8/2JiYv9MTEz/TExM/2JiYv9sbGz/cXFx/3Z2 + dv9jY2P/UlJS/1RUVP9PT0//NDQ0/0xMTP9eXl7/YmJi/2ZmZv9qamr/b29v/3Nzc/95eXn/fn5+/4OD + g/+JiYn/jo6O/5SUlP+ZmZn/np6e/6SkpP+qqqr/r6+v/7W1tf+6urr/v7+//8XFxf/Jycn/zc3Nl/// + /wH///8B5+fn8eXl5f/k5OT/4uLi/+Hh4f/f39//3d3d/9vb2//Z2dn/1tbW/9PT0//Q0ND/zc3N/8nJ + yf/FxcX/wcHB/729vf+4uLj/s7Oz/62trf+mpqb/np6e/5SUlP+IiIj/fHx8/3BwcP9dXV3/TExM/0dH + R/9kZGT/b29v/319ff+CgoL/YWFh/0xMTP9JSUn/JCQk/xwcHP8gICD/NjY2/1RUVP9eXl7/YmJi/2Zm + Zv9ra2v/cHBw/3Z2dv97e3v/gYGB/4eHh/+MjIz/kpKS/5iYmP+enp7/pKSk/6urq/+xsbH/t7e3/7y8 + vP/CwsL/x8fH/8vLy5f///8B////Aebm5vHk5OT/4uLi/+Hh4f/f39//3d3d/9vb2//Z2dn/19fX/9TU + 1P/R0dH/zc3N/8rKyv/Gxsb/wcHB/729vf+4uLj/s7Oz/6ysrP+mpqb/np6e/5WVlf+JiYn/fn5+/3Bw + cP9iYmL/W1tb/1dXV/9NTU3/ZWVl/3l5ef+Xl5f/ampq/2xsbP9GRkb/JSUl/xsbG/8vLy//Hh4e/x4e + Hv8kJCT/QkJC/1hYWP9eXl7/Y2Nj/2hoaP9ubm7/c3Nz/3l5ef9/f3//hYWF/4yMjP+SkpL/mJiY/5+f + n/+mpqb/ra2t/7Ozs/+6urr/v7+//8XFxf/JycmX////Af///wHk5OTx4+Pj/+Hh4f/f39//3t7e/9zc + 3P/Z2dn/19fX/9TU1P/R0dH/zs7O/8rKyv/Gxsb/wsLC/729vf+4uLj/s7Oz/62trf+mpqb/n5+f/5WV + lf+Kior/fX19/2FhYf9eXl7/VlZW/1paWv9mZmb/VlZW/21tbf+Wlpb/Z2dn/2xsbP+Ghob/RERE/xsb + G/8mJib/HBwc/x4eHv8eHh7/Hh4e/x4eHv8sLCz/TExM/1paWv9gYGD/ZmZm/2xsbP9xcXH/d3d3/35+ + fv+EhIT/i4uL/5KSkv+ampr/oaGh/6ioqP+wsLD/t7e3/729vf/Dw8P/yMjIl////wH///8B4+Pj8eHh + 4f/g4OD/3t7e/9zc3P/a2tr/2NjY/9XV1f/S0tL/zs7O/8rKyv/Hx8f/wsLC/729vf+4uLj/s7Oz/66u + rv+np6f/n5+f/5eXl/+Kior/fn5+/2dnZ/9ISEj/QUFB/1FRUf9jY2P/ampq/01NTf+EhIT/bm5u/2Vl + Zf+IiIj/5eXl/39/f/8jIyP/Hx8f/x8fH/8eHh7/Hh4e/x4eHv8eHh7/HR0d/x8fH/83Nzf/VFRU/15e + Xv9kZGT/aWlp/3BwcP92dnb/fX19/4SEhP+MjIz/k5OT/5ycnP+kpKT/rKys/7S0tP+8vLz/wsLC/8fH + x5f///8B////AeLi4vHg4OD/3t7e/9zc3P/a2tr/2NjY/9bW1v/T09P/z8/P/8vLy//Hx8f/w8PD/76+ + vv+5ubn/s7Oz/62trf+np6f/n5+f/5aWlv+MjIz/f39//3Jycv9fX1//SUlJ/zo6Ov9XV1f/aWlp/3Bw + cP9PT0//V1dX/11dXf+IiIj/39/f/7S0tP8nJyf/Jycn/yEhIf8lJSX/JCQk/x8fH/8fHx//Hh4e/x4e + Hv8eHh7/Hh4e/yUlJf9ERET/W1tb/2JiYv9oaGj/b29v/3Z2dv99fX3/hYWF/42Njf+Wlpb/n5+f/6mp + qf+ysrL/urq6/8HBwf/GxsaX////Af///wHh4eHx39/f/93d3f/b29v/2NjY/9bW1v/T09P/0NDQ/8zM + zP/IyMj/w8PD/76+vv+5ubn/tLS0/66urv+np6f/oKCg/5aWlv+Li4v/gICA/3R0dP9nZ2f/XV1d/01N + Tf86Ojr/WVlZ/25ubv+Li4v/c3Nz/05OTv9dXV3/0dHR/8bGxv8uLi7/JiYm/yAgIP8kJCT/JSUl/yYm + Jv8lJSX/IiIi/x8fH/8eHh7/Hh4e/x4eHv8eHh7/Hh4e/zAwMP9RUVH/YWFh/2dnZ/9ubm7/dXV1/319 + ff+Ghob/kJCQ/5qamv+lpaX/r6+v/7m5uf/BwcH/xsbGl////wH///8B4ODg8d7e3v/b29v/2dnZ/9bW + 1v/T09P/0NDQ/8zMzP/IyMj/xMTE/7+/v/+6urr/tLS0/66urv+oqKj/oaGh/5iYmP+MjIz/gYGB/25u + bv9mZmb/Xl5e/1paWv9iYmL/SkpK/1lZWf+Ghob/hYWF/1hYWP9paWn/Ozs7/2xsbP81NTX/JiYm/yAg + IP8kJCT/JSUl/yYmJv8mJib/JiYm/yUlJf8kJCT/ISEh/x8fH/8eHh7/Hh4e/x4eHv8eHh7/IiIi/z4+ + Pv9bW1v/ZGRk/2tra/90dHT/fn5+/4qKiv+Wlpb/oaGh/62trf+3t7f/wcHB/8bGxpf///8B////Ad7e + 3vHc3Nz/2tra/9fX1//U1NT/0NDQ/8zMzP/IyMj/xMTE/8DAwP+7u7v/tbW1/6+vr/+oqKj/oaGh/5mZ + mf+Ojo7/goKC/3Jycv9OTk7/RUVF/1RUVP9dXV3/ZmZm/0ZGRv9qamr/ioqK/1RUVP99fX3/tLS0/4CA + gP8bGxv/HR0d/x4eHv8jIyP/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yUlJf8jIyP/Hx8f/x8f + H/8fHx//Hh4e/x4eHv8eHh7/KSkp/0pKSv9fX1//ampq/3d3d/+EhIT/kpKS/5+fn/+rq6v/tra2/8DA + wP/Hx8eX////Af///wHd3d3x2tra/9fX1//U1NT/0dHR/83Nzf/Jycn/xcXF/8DAwP+7u7v/tra2/7Cw + sP+qqqr/oqKi/5qamv+QkJD/hISE/3d3d/9nZ2f/TExM/zw8PP9SUlL/ZGRk/2pqav9BQUH/Wlpa/1RU + VP97e3v/ra2t/+rq6v9OTk7/IiIi/xsbG/8kJCT/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JSUl/yMjI/8hISH/Hx8f/x8fH/8fHx//Hx8f/x8fH/8gICD/NjY2/11dXf9ycnL/f39//4yM + jP+cnJz/qamp/7W1tf/AwMD/x8fHl////wH///8B29vb8djY2P/V1dX/0tLS/87Ozv/Kysr/xsbG/8HB + wf+8vLz/t7e3/7Gxsf+qqqr/pKSk/5ycnP+SkpL/h4eH/3p6ev9tbW3/YWFh/05OTv82Njb/VFRU/2lp + af94eHj/bGxs/zMzM/9fX1//pKSk/+/v7/9gYGD/JCQk/yAgIP8kJCT/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8lJSX/JCQk/yMjI/8fHx//Hx8f/x8fH/8fHx//Hx8f/x8f + H/8mJib/Tk5O/1xcXP9oaGj/k5OT/6enp/+0tLT/wMDA/8fHx5f///8B////AdnZ2fHW1tb/09PT/8/P + z//Ly8v/x8fH/8LCwv+9vb3/t7e3/7Kysv+rq6v/pKSk/52dnf+Tk5P/iIiI/3t7e/9vb2//ZWVl/1xc + XP9cXFz/SkpK/09PT/92dnb/l5eX/1lZWf9GRkb/MTEx/6enp/9tbW3/IiIi/yAgIP8iIiL/JSUl/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yUlJf8lJSX/JCQk/yIi + Iv8fHx//Hx8f/yAgIP8gICD/ICAg/yAgIP8pKSn/Wlpa/46Ojv+np6f/tbW1/8HBwf/Hx8eX////Af// + /wHX19fx1NTU/9DQ0P/MzMz/yMjI/8PDw/++vr7/ubm5/7Ozs/+srKz/paWl/52dnf+UlJT/iYmJ/319 + ff9cXFz/SkpK/1lZWf9aWlr/Y2Nj/0xMTP9TU1P/k5OT/2BgYP9sbGz/i4uL/2BgYP8YGBj/Hh4e/yEh + If8hISH/JSUl/yUlJf8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8lJSX/JCQk/yEhIf8gICD/ICAg/yAgIP8gICD/ICAg/zQ0NP+QkJD/qKio/7e3 + t//Dw8P/yMjIl////wH///8B1dXV8dLS0v/Ozs7/ycnJ/8XFxf/AwMD/urq6/7S0tP+urq7/p6en/5+f + n/+VlZX/i4uL/39/f/9xcXH/UVFR/zw8PP9OTk7/YWFh/2dnZ/9ISEj/UVFR/2lpaf9kZGT/ioqK/+fn + 5/+NjY3/Hh4e/xgYGP8fHx//JCQk/yUlJf8lJSX/JSUl/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yUlJf8lJSX/IyMj/yAgIP8gICD/ICAg/yEh + If8uLi7/jo6O/6urq/+7u7v/xcXF/8nJyZf///8B////AdPT0/HPz8//y8vL/8bGxv/BwcH/u7u7/7W1 + tf+vr6//qKio/6CgoP+Wlpb/jY2N/4GBgf91dXX/aWlp/1NTU/82Njb/TU1N/2dnZ/9vb2//Y2Nj/yoq + Kv9SUlL/hoaG/9/f3/+pqan/JSUl/yQkJP8gICD/JCQk/yUlJf8lJSX/JSUl/yUlJf8lJSX/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8kJCT/ISEh/yAgIP8gICD/Jycn/4ODg/+qqqr/wMDA/8fHx//Ly8uX////Af///wHR0dHxzc3N/8jI + yP/Dw8P/vb29/7e3t/+wsLD/qqqq/6Kiov+YmJj/jo6O/4SEhP93d3f/bW1t/2NjY/9aWlr/R0dH/0hI + SP9tbW3/jIyM/3R0dP8vLy//MjIy/6+vr//AwMD/Jycn/yYmJv8gICD/JCQk/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JSUl/yYmJv8kJCT/ICAg/yUlJf+EhIT/ra2t/8PDw//Jycn/zc3Nl/// + /wH///8Bz8/P8cvLy//Gxsb/wMDA/7q6uv+zs7P/rKys/6SkpP+bm5v/kZGR/4aGhv9xcXH/VVVV/19f + X/9dXV3/YmJi/1ZWVv8/Pz//h4eH/4GBgf9TU1P/cHBw/zc3N/8nJyf/R0dH/yQkJP8hISH/JiYm/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yUlJf81NTX/i4uL/6+v + r//Gxsb/y8vL/8/Pz5f///8B////Ac3NzfHIyMj/w8PD/7y8vP+1tbX/rq6u/6ampv+dnZ3/kpKS/4eH + h/96enr/WVlZ/0RERP9NTU3/Xl5e/2dnZ/9UVFT/QUFB/4uLi/9PT0//fHx8/7y8vP/Gxsb/Hh4e/xgY + GP8dHR3/JCQk/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yUl + Jf8lJSX/SUlJ/4+Pj/+4uLj/ycnJ/83Nzf/R0dGX////Af///wHLy8vxxcXF/7+/v/+4uLj/sLCw/6io + qP+fn5//lZWV/4mJif98fHz/b29v/1paWv8/Pz//SEhI/2VlZf9ra2v/YmJi/yQkJP9JSUn/enp6/7Gx + sf/k5OT/QEBA/yMjI/8dHR3/ISEh/yQkJP8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yUlJf8kJCT/ERER/y8vL/+rq6v/xcXF/8rKyv/Pz8//0tLSl////wH///8BycnJ8cPD + w/+8vLz/tLS0/6urq/+ioqL/l5eX/4yMjP9/f3//c3Nz/2lpaf9eXl7/RERE/0VFRf9paWn/fHx8/4uL + i/8nJyf/Ojo6/5ycnP/o6Oj/UlJS/yIiIv8gICD/IiIi/yQkJP8lJSX/JSUl/yUlJf8lJSX/JSUl/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8kJCT/FhYW/ywsLP+fn5//wsLC/8jIyP/MzMz/0NDQ/9TU + 1Jf///8B////AcbGxvHAwMD/ubm5/7CwsP+mpqb/m5ub/4+Pj/+AgID/YmJi/2ZmZv9kZGT/YWFh/2Bg + YP84ODj/d3d3/5SUlP9WVlb/W1tb/ygoKP87Ozv/XV1d/yEhIf8fHx//IiIi/yQkJP8lJSX/JSUl/yUl + Jf8lJSX/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8nJyf/Kysr/ygoKP+ZmZn/wMDA/8bG + xv/Kysr/zs7O/9LS0v/W1taX////Af///wHFxcXxvr6+/7W1tf+rq6v/oKCg/5OTk/+Ghob/a2tr/0tL + S/9MTEz/YWFh/2ZmZv9hYWH/NjY2/5KSkv9dXV3/aWlp/5KSkv/FxcX/ISEh/yEhIf8bGxv/IiIi/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JiYm/ysrK/8rKyv/KCgo/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JiYm/yYmJv8mJib/JiYm/yYmJv8lJSX/NTU1/2tr + a/+jo6P/v7+//8TExP/IyMj/zMzM/9HR0f/V1dX/2NjYl////wH///8Bw8PD8bu7u/+xsbH/pqam/5qa + mv+MjIz/fHx8/2ZmZv9JSUn/RkZG/2RkZP9sbGz/Z2dn/ycnJ/9UVFT/YmJi/4uLi//p6en/hoaG/x8f + H/8bGxv/ICAg/yUlJf8kJCT/IyMj/ygoKP9OTk7/f39//6Ghof+ysrL/s7Oz/6ioqP+Pj4//YmJi/zMz + M/8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8mJib/JiYm/yUl + Jf8lJSX/HBwc/xkZGf+Li4v/vLy8/8LCwv/Gxsb/y8vL/8/Pz//T09P/19fX/9nZ2Zf///8B////AcLC + wvG5ubn/r6+v/6Ojo/+Wlpb/hoaG/3d3d/9nZ2f/SkpK/0VFRf9qamr/dHR0/5CQkP8uLi7/Nzc3/4CA + gP/j4+P/m5ub/x0dHf8hISH/IiIi/yYmJv8kJCT/IyMj/0hISP+lpaX/ycnJ/8vLy//Ly8v/y8vL/8zM + zP/MzMz/zc3N/83Nzf++vr7/cnJy/yoqKv8kJCT/JCQk/yQkJP8kJCT/JCQk/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yYmJv8lJSX/IiIi/xEREf9/f3//u7u7/8LCwv/Gxsb/ycnJ/83Nzf/R0dH/1dXV/9jY + 2P/b29uX////Af///wHBwcHxuLi4/62trf+hoaH/h4eH/35+fv94eHj/bGxs/2hoaP9BQUH/bGxs/5OT + k/92dnb/RkZG/yQkJP9LS0v/lZWV/yAgIP8iIiL/ICAg/yUlJf8kJCT/JCQk/2lpaf/Gxsb/zc3N/8zM + zP/Ly8v/y8vL/8vLy//MzMz/zMzM/8zMzP/MzMz/y8vL/8rKyv+np6f/Nzc3/yMjI/8kJCT/JCQk/yQk + JP8kJCT/JCQk/yUlJf8lJSX/JSUl/yUlJf8lJSX/IyMj/wwMDP93d3f/uLi4/8HBwf/FxcX/ycnJ/8zM + zP/Q0ND/1NTU/9fX1//a2tr/3Nzcl////wH///8BwcHB8be3t/+srKz/mJiY/2FhYf9VVVX/eXl5/3Bw + cP9ubm7/Ojo6/4WFhf9+fn7/UFBQ/35+fv+bm5v/Jycn/zAwMP8bGxv/HR0d/yMjI/8kJCT/IyMj/19f + X//Gxsb/y8vL/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/Ly8v/y8vL/8rKyv/Kysr/ycnJ/6Oj + o/8rKyv/IyMj/yQkJP8kJCT/JCQk/yQkJP8lJSX/JSUl/yUlJf8lJSX/MjIy/1lZWf+AgID/t7e3/8DA + wP/ExMT/yMjI/8vLy//Pz8//0tLS/9bW1v/Z2dn/29vb/97e3pf///8B////AcLCwvG5ubn/ra2t/5WV + lf9fX1//SkpK/3l5ef90dHT/c3Nz/zIyMv9qamr/TU1N/3x8fP/CwsL/ycnJ/ywsLP8aGhr/Gxsb/yIi + Iv8jIyP/JCQk/zU1Nf+2trb/y8vL/8vLy//MzMz/zMzM/83Nzf/Nzc3/zc3N/8zMzP/MzMz/y8vL/8vL + y//Kysr/ysrK/8rKyv/Kysr/c3Nz/yQkJP8kJCT/JCQk/yQkJP8kJCT/JSUl/yUlJf8kJCT/ISEh/xUV + Ff9zc3P/s7Oz/7+/v//Dw8P/x8fH/8vLy//Ozs7/0tLS/9XV1f/Y2Nj/2tra/93d3f/f39+X////Af// + /wHDw8Pxu7u7/6+vr/+Wlpb/X19f/0dHR/96enr/enp6/4mJif9DQ0P/Pj4+/3Z2dv+0tLT/2dnZ/zk5 + Of8hISH/Hh4e/yIiIv8jIyP/JCQk/yQkJP9paWn/zMzM/83Nzf/MzMz/zMzM/83Nzf/Nzc3/zs7O/83N + zf/Nzc3/zMzM/8zMzP/Ly8v/y8vL/8vLy//Ly8v/zMzM/7Ozs/8rKyv/JCQk/yQkJP8kJCT/JCQk/yUl + Jf8kJCT/ISEh/w0NDf9RUVH/r6+v/76+vv/CwsL/x8fH/8rKyv/Ozs7/0dHR/9TU1P/X19f/2tra/9zc + 3P/f39//4eHhl////wH///8Bw8PD8b29vf+zs7P/mZmZ/3V1df9VVVX/c3Nz/4qKiv+Tk5P/RERE/zAw + MP9qamr/09PT/0NDQ/8hISH/Hh4e/yIiIv8jIyP/JCQk/yQkJP8kJCT/kJCQ/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/87Ozv/Ozs7/zs7O/83Nzf/MzMz/zMzM/8vLy//Ly8v/zMzM/83Nzf/Jycn/PDw8/yQk + JP8kJCT/JCQk/yQkJP8kJCT/IyMj/w4ODv9KSkr/qamp/729vf/BwcH/xsbG/8rKyv/Ozs7/0dHR/9TU + 1P/X19f/2tra/9zc3P/e3t7/4eHh/+Li4pf///8B////AcPDw/G9vb3/tra2/5aWlv9/f3//UFBQ/3R0 + dP+Xl5f/UlJS/29vb/92dnb/ISEh/y8vL/8fHx//Hx8f/yIiIv8jIyP/JCQk/yQkJP8kJCT/JCQk/5iY + mP/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zMzM/8zMzP/MzMz/zMzM/8zM + zP/MzMz/zMzM/0dHR/8kJCT/JCQk/yQkJP8kJCT/KSkp/0RERP9WVlb/q6ur/7y8vP/AwMD/xcXF/8rK + yv/Nzc3/0dHR/9TU1P/X19f/2dnZ/9zc3P/e3t7/4ODg/+Li4v/k5OSX////Af///wHFxcXxvr6+/7Oz + s/+Hh4f/goKC/0xMTP9wcHD/V1dX/2pqav+Tk5P/7u7u/1NTU/8eHh7/GRkZ/yQkJP8lJSX/JCQk/yQk + JP8kJCT/JCQk/yQkJP+Ghob/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/8zM + zP/MzMz/zMzM/8zMzP/MzMz/zMzM/8bGxv87Ozv/JCQk/yQkJP8kJCT/IyMj/xoaGv9ZWVn/pKSk/7y8 + vP/AwMD/xMTE/8nJyf/Nzc3/0NDQ/9TU1P/X19f/2dnZ/9zc3P/e3t7/4ODg/+Li4v/k5OT/5eXll/// + /wH///8BxsbG8cDAwP+oqKj/hYWF/4qKiv9fX1//Pj4+/2hoaP+Ojo7/6enp/3V1df8dHR3/ICAg/yMj + I/8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/VlZW/8vLy//Nzc3/zc3N/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/MzMz/zMzM/8zMzP/Ly8v/y8vL/8vLy/+pqan/KCgo/yQkJP8kJCT/IiIi/xIS + Ev8vLy//oqKi/7u7u//AwMD/xMTE/8nJyf/Nzc3/0NDQ/9TU1P/X19f/2dnZ/9zc3P/e3t7/4ODg/+Li + 4v/k5OT/5eXl/+bm5pf///8B////AcjIyPHDw8P/qKio/4qKiv+cnJz/X19f/zMzM/+CgoL/1tbW/4eH + h/8eHh7/ICAg/yEhIf8jIyP/IyMj/yMjI/8jIyP/IyMj/yQkJP8kJCT/JCQk/ysrK/+np6f/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/8zMzP/MzMz/y8vL/8vLy//Jycn/YWFh/yQk + JP8kJCT/IyMj/xUVFf8mJib/lZWV/7u7u//AwMD/xMTE/8nJyf/MzMz/0NDQ/9PT0//W1tb/2dnZ/9vb + 2//e3t7/4ODg/+Li4v/j4+P/5eXl/+fn5//o6OiX////Af///wHKysrxxcXF/6qqqv+bm5v/cnJy/1ZW + Vv9iYmL/MzMz/0NDQ/8qKir/ISEh/yAgIP8iIiL/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/JCQk/yQk + JP8kJCT/R0dH/729vf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zMzM/8vL + y//Kysr/kZGR/ycnJ/8kJCT/JSUl/zY2Nv8zMzP/lpaW/7u7u//AwMD/xMTE/8jIyP/MzMz/0NDQ/9PT + 0//W1tb/2dnZ/9vb2//d3d3/4ODg/+Li4v/j4+P/5eXl/+bm5v/o6Oj/6enpl////wH///8By8vL8cfH + x/+1tbX/e3t7/1BQUP9/f3//0dHR/4WFhf8mJib/GRkZ/x8fH/8iIiL/IyMj/yMjI/8jIyP/IyMj/yMj + I/8jIyP/IyMj/yMjI/8jIyP/JCQk/yQkJP9LS0v/tbW1/8zMzP/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/8zMzP/IyMj/j4+P/y4uLv8kJCT/IyMj/yIiIv9LS0v/lJSU/729vf/BwcH/xcXF/8jI + yP/MzMz/0NDQ/9PT0//W1tb/2dnZ/9vb2//d3d3/39/f/+Hh4f/j4+P/5eXl/+bm5v/o6Oj/6enp/+rq + 6pf///8B////Ac7OzvHKysr/urq6/1lZWf96enr/xcXF/7y8vP8kJCT/Hx8f/x0dHf8iIiL/IiIi/yIi + Iv8oIiH/PiId/yMiIv8iIiL/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/zMzM/+Dg4P/v7+//8vL + y//Nzc3/zc3N/83Nzf/Nzc3/zMzM/8rKyv+srKz/XV1d/yYmJv8kJCT/IyMj/xsbG/8UFBT/goKC/7u7 + u//CwsL/xcXF/8nJyf/Nzc3/0NDQ/9PT0//W1tb/2dnZ/9vb2//d3d3/39/f/+Hh4f/j4+P/5OTk/+bm + 5v/o6Oj/6enp/+rq6v/r6+uX////Af///wHQ0NDxzc3N/8nJyf+wsLD/t7e3/9LS0v8oKCj/ICAg/x0d + Hf8jIyP/IyMj/yIiIv8jISH/gicW/3UnGf8jIiH/IiIi/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMj + I/8jIyP/JCQk/zAwMP9dXV3/fX19/5OTk/+ZmZn/jo6O/29vb/9HR0f/Jycn/yQkJP8kJCT/IyMj/x0d + Hf8NDQ3/dXV1/7q6uv/CwsL/xsbG/8rKyv/Nzc3/0NDQ/9PT0//W1tb/2dnZ/9vb2//d3d3/39/f/+Hh + 4f/i4uL/5OTk/+bm5v/n5+f/6enp/+rq6v/r6+v/7Ozsl////wH///8B09PT8dDQ0P/MzMz/xcXF/3Z2 + dv88PDz/Hx8f/x8fH/8lJSX/IyMj/yIiIv8iISH/dyYX/44oFv8lIiH/IiIi/yQhIf88Ih7/KCIh/y0i + IP9gJRr/aCYa/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/IyMj/y0tLf8bGxv/cnJy/7i4uP/Dw8P/xsbG/8rKyv/Ozs7/0dHR/9TU1P/W1tb/2dnZ/9vb + 2//d3d3/39/f/+Hh4f/i4uL/5OTk/+bm5v/n5+f/6enp/+rq6v/r6+v/7Ozs/+3t7Zf///8B////AdXV + 1fHS0tL/z8/P/8jIyP9kZGT/NDQ0/yMjI/8kJCT/IyMj/yIiIv8iISH/aCQY/5cpFf+RKBX/fSYW/3kl + Fv+WKBT/jykW/3slFv9uJhn/UyUd/1omHf9GJB3/WSQa/ygiIf8jIyL/IyMj/yMjI/8jIyP/IyMj/yMj + I/8jIyP/JCQk/yQkJP8kJCT/IyMj/yIiIv9FRUX/gICA/729vf/ExMT/x8fH/8vLy//Ozs7/0dHR/9TU + 1P/X19f/2dnZ/9vb2//d3d3/39/f/+Hh4f/j4+P/5OTk/+bm5v/n5+f/6Ojo/+rq6v/r6+v/7Ozs/+3t + 7f/u7u6X////Af///wHY2Njx1dXV/9LS0v/Ly8v/UlJS/ycnJ/8iIiL/IyMj/yIiIv8iIiL/RiMd/7Yr + Ev8zIR7/JiAg/2QlGv+SKBX/LSIg/ykhIP9GIx3/KCIh/2ImG/9EJB7/aSYZ/2IkGf94Jhj/NiMf/yci + Iv8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8kJCT/IyMj/yAgIP8MDAz/Xl5e/7e3t//FxcX/ycnJ/8zM + zP/Pz8//0tLS/9XV1f/X19f/2tra/9zc3P/e3t7/39/f/+Hh4f/j4+P/5OTk/+bm5v/n5+f/6Ojo/+np + 6f/r6+v/7Ozs/+3t7f/u7u7/7+/vl////wH///8B2tra8dfX1//U1NT/ysrK/z4+Pv8iIiL/IyMj/yMj + I/8iIiL/IiIi/yUhIP9dJRv/kicU/1QiGf9QIhn/oyoU/0QiHP+TKBT/fScX/4YmFf9eJRr/LiIg/2ol + Gf+DJxf/bCYZ/2UmG/9yJhj/LCIh/yMiIv8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8NDQ3/TExM/7i4 + uP/IyMj/y8vL/83Nzf/Q0ND/09PT/9bW1v/Z2dn/29vb/93d3f/e3t7/4ODg/+Hh4f/j4+P/5OTk/+bm + 5v/n5+f/6Ojo/+rq6v/r6+v/7Ozs/+3t7f/u7u7/7+/v/+/v75f///8B////Ad3d3fHa2tr/19fX/83N + zf8/Pz//IyMj/yQkJP8jIyP/IyMj/yIiIv8hISH/ISEh/y4hH/9tJhn/gScX/0cjHf+aKRT/OiIe/yEh + If9LIxz/fScX/yUhIf8tIiD/KiIg/1clHP9HIx3/bSca/2smGv88Ix7/LCMh/yMjI/8jIyP/IyMj/ycn + J/8WFhb/RkZG/7S0tP/Kysr/zc3N/8/Pz//S0tL/1NTU/9fX1//a2tr/3Nzc/97e3v/f39//4eHh/+Li + 4v/j4+P/5eXl/+bm5v/n5+f/6Ojo/+rq6v/r6+v/7Ozs/+3t7f/u7u7/7+/v/+/v7//w8PCX////Af// + /wHf39/x3d3d/9ra2v/Y2Nj/vr6+/1xcXP8lJSX/IyMj/yMjI/8iIiL/IiIi/yIiIv8hISH/ISEh/yEh + If8nISD/likV/zAhHv8nIB//iSYU/1skG/92JRf/aCUZ/yIiIf8iIiH/RyMd/3QmGP9dJRv/ayca/zUk + IP8jIyP/IiIi/yMjI/9GRkb/a2tr/7m5uf/Nzc3/z8/P/9HR0f/U1NT/1tbW/9jY2P/b29v/3d3d/9/f + 3//g4OD/4uLi/+Pj4//k5OT/5eXl/+fn5//o6Oj/6enp/+rq6v/r6+v/7Ozs/+3t7f/u7u7/7+/v/+/v + 7//w8PD/8fHxl////wH///8B4eHh8d/f3//d3d3/29vb/9nZ2f/W1tb/paWl/0dHR/8jIyP/IyMj/yIi + Iv8iIiL/IiIi/yIiIv8hISH/ISEh/zkiHv99Jhb/hyYV/14kGv9tJBf/gicX/yQhIP8+Ih3/fCYX/0Ij + Hv9YJRz/hSgX/ykjIv8jIyP/IyMj/yMjI/8TExP/NjY2/62trf/Q0ND/0tLS/9TU1P/W1tb/2NjY/9ra + 2v/c3Nz/3t7e/+Dg4P/i4uL/4+Pj/+Tk5P/l5eX/5+fn/+jo6P/o6Oj/6enp/+rq6v/r6+v/7Ozs/+3t + 7f/u7u7/7+/v//Dw8P/w8PD/8fHx//Ly8pf///8B////AePj4/Hh4eH/39/f/93d3f/c3Nz/2tra/9jY + 2P/Pz8//ioqK/zU1Nf8iIiL/IyMj/yIiIv8iIiL/IiIi/yEhIf8hISH/ISEg/yIhIP9QIxv/qioT/y0h + H/82IR3/nCkU/zojH/8mIiH/YiUa/ysjIf8jIyL/IyMj/yQkJP8YGBj/KCgo/6urq//S0tL/1dXV/9fX + 1//Y2Nj/2tra/9zc3P/e3t7/4ODg/+Li4v/j4+P/5OTk/+Xl5f/n5+f/6Ojo/+jo6P/p6en/6urq/+vr + 6//s7Oz/7e3t/+7u7v/u7u7/7+/v//Dw8P/w8PD/8fHx//Ly8v/y8vKX////Af///wHl5eXx5OTk/+Li + 4v/g4OD/39/f/93d3f/c3Nz/2tra/9jY2P/BwcH/aWlp/ygoKP8iIiL/IiIi/yIiIv8iIiL/ISEh/yEh + If8hISH/KSEg/1kkG/+LJxT/pykT/00kHf8kIiH/fCcX/3QoGv8kIyL/IyMj/yQkJP8cHBz/ICAg/6Cg + oP/U1NT/19fX/9nZ2f/b29v/3Nzc/97e3v/g4OD/4eHh/+Pj4//k5OT/5ubm/+fn5//o6Oj/6Ojo/+np + 6f/q6ur/6+vr/+zs7P/s7Oz/7e3t/+7u7v/v7+//7+/v//Dw8P/x8fH/8fHx//Ly8v/z8/P/8/Pzl/// + /wH///8B5+fn8ebm5v/l5eX/4+Pj/+Li4v/g4OD/39/f/97e3v/c3Nz/29vb/9jY2P+tra3/lpaW/5eX + l/9aWlr/JCQk/yIiIv8iIiL/ISEh/yEhIf8iISH/MiIg/10mG/91Jhj/fSYX/30oGf8mIyL/IyMj/yMj + I/9BQUH/WVlZ/6ampv/X19f/2tra/9zc3P/d3d3/39/f/+Dg4P/i4uL/4+Pj/+Tk5P/m5ub/5+fn/+jo + 6P/o6Oj/6enp/+rq6v/r6+v/7Ozs/+zs7P/t7e3/7u7u/+7u7v/v7+//8PDw//Dw8P/x8fH/8fHx//Ly + 8v/z8/P/8/Pz//T09Jf///8B////Aenp6fHo6Oj/5+fn/+bm5v/k5OT/4+Pj/+Li4v/h4eH/39/f/97e + 3v/d3d3/3Nzc/9vb2//b29v/1NTU/1VVVf8iIiL/IiIi/yIiIv8iIiL/IiIi/yIiIv8kIiL/UCUd/1cm + Hf8mIyL/IyMj/yIiIv8aGhr/ICAg/5WVlf/Z2dn/3d3d/97e3v/f39//4eHh/+Li4v/j4+P/5eXl/+bm + 5v/n5+f/6Ojo/+np6f/q6ur/6urq/+vr6//s7Oz/7Ozs/+3t7f/u7u7/7u7u/+/v7//v7+//8PDw//Hx + 8f/x8fH/8vLy//Ly8v/z8/P/8/Pz//T09P/09PSX////Af///wHr6+vx6urq/+np6f/o6Oj/5+fn/+bm + 5v/l5eX/5OTk/+Pj4//i4uL/4eHh/9/f3//f39//3t7e/93d3f+Xl5f/KSkp/yMjI/8iIiL/IiIi/yIi + Iv8iIiL/IyMj/yMjI/8jIyP/IyMj/yIiIv8eHh7/DQ0N/4ODg//Z2dn/4ODg/+Hh4f/i4uL/4+Pj/+Tk + 5P/l5eX/5ubm/+fn5//o6Oj/6enp/+rq6v/r6+v/6+vr/+zs7P/t7e3/7e3t/+7u7v/u7u7/7+/v/+/v + 7//w8PD/8PDw//Hx8f/x8fH/8vLy//Pz8//z8/P/8/Pz//T09P/09PT/9fX1l////wH///8B7e3t8ezs + 7P/r6+v/6urq/+np6f/o6Oj/5+fn/+bm5v/l5eX/5OTk/+Pj4//j4+P/4uLi/+Hh4f/g4OD/39/f/7m5 + uf9YWFj/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yIiIv8gICD/DQ0N/3p6ev/Z2dn/4+Pj/+Pj + 4//k5OT/5eXl/+bm5v/n5+f/6Ojo/+np6f/p6en/6urq/+vr6//s7Oz/7Ozs/+3t7f/t7e3/7u7u/+/v + 7//v7+//8PDw//Dw8P/w8PD/8fHx//Hx8f/y8vL/8vLy//Pz8//z8/P/9PT0//T09P/19fX/9fX1//b2 + 9pf///8B////Ae7u7vHt7e3/7Ozs/+zs7P/r6+v/6urq/+rq6v/p6en/6Ojo/+fn5//m5ub/5eXl/+Tk + 5P/j4+P/4+Pj/+Li4v/i4uL/39/f/6Kiov8+Pj7/IyMj/yMjI/8jIyP/IyMj/yIiIv9ZWVn/tLS0/6en + p//c3Nz/5OTk/+Xl5f/m5ub/5+fn/+fn5//o6Oj/6enp/+rq6v/r6+v/6+vr/+zs7P/s7Oz/7e3t/+7u + 7v/u7u7/7+/v/+/v7//w8PD/8PDw//Hx8f/x8fH/8fHx//Ly8v/y8vL/8/Pz//Pz8//z8/P/9PT0//T0 + 9P/09PT/9fX1//X19f/29vaX////Af///wHv7+/x7u7u/+7u7v/t7e3/7Ozs/+zs7P/r6+v/6+vr/+rq + 6v/p6en/6Ojo/+fn5//n5+f/5ubm/+Xl5f/l5eX/5OTk/+Tk5P/l5eX/2NjY/4ODg/8xMTH/IiIi/yIi + Iv9NTU3/19fX/+bm5v/m5ub/5ubm/+fn5//o6Oj/6Ojo/+np6f/q6ur/6urq/+vr6//s7Oz/7Ozs/+3t + 7f/t7e3/7u7u/+7u7v/v7+//7+/v//Dw8P/w8PD/8fHx//Hx8f/y8vL/8vLy//Ly8v/y8vL/8/Pz//Pz + 8//09PT/9PT0//T09P/19fX/9fX1//X19f/29vb/9vb2l////wH///8B8PDw8fDw8P/v7+//7u7u/+7u + 7v/t7e3/7e3t/+zs7P/s7Oz/6+vr/+rq6v/q6ur/6enp/+jo6P/o6Oj/5+fn/+fn5//n5+f/5+fn/+fn + 5//m5ub/xMTE/2VlZf9LS0v/0tLS/+jo6P/p6en/6enp/+np6f/p6en/6urq/+rq6v/r6+v/7Ozs/+zs + 7P/t7e3/7e3t/+7u7v/u7u7/7+/v/+/v7//v7+//8PDw//Dw8P/x8fH/8fHx//Ly8v/y8vL/8vLy//Pz + 8//z8/P/8/Pz//T09P/09PT/9PT0//X19f/19fX/9fX1//b29v/29vb/9vb2//f395f///8B////AfHx + 8fHx8fH/8PDw//Dw8P/v7+//7+/v/+7u7v/u7u7/7e3t/+3t7f/s7Oz/7Ozs/+vr6//q6ur/6urq/+rq + 6v/p6en/6enp/+np6f/p6en/6enp/+rq6v/n5+f/4eHh/+rq6v/q6ur/6urq/+vr6//r6+v/6+vr/+zs + 7P/s7Oz/7e3t/+3t7f/u7u7/7u7u/+/v7//v7+//7+/v//Dw8P/w8PD/8PDw//Hx8f/x8fH/8vLy//Ly + 8v/y8vL/8/Pz//Pz8//z8/P/9PT0//T09P/09PT/9fX1//X19f/19fX/9vb2//b29v/29vb/9vb2//f3 + 9//39/eX////Af///wHy8vLx8vLy//Hx8f/x8fH/8PDw//Dw8P/w8PD/7+/v/+/v7//u7u7/7u7u/+3t + 7f/t7e3/7Ozs/+zs7P/s7Oz/7Ozs/+zs7P/r6+v/7Ozs/+zs7P/s7Oz/7Ozs/+zs7P/s7Oz/7Ozs/+zs + 7P/s7Oz/7e3t/+3t7f/t7e3/7u7u/+7u7v/v7+//7+/v/+/v7//w8PD/8PDw//Hx8f/x8fH/8fHx//Hx + 8f/y8vL/8vLy//Pz8//z8/P/8/Pz//T09P/09PT/9PT0//T09P/19fX/9fX1//X19f/29vb/9vb2//b2 + 9v/29vb/9/f3//f39//39/f/9/f3l////wH///8B8/Pz8fPz8//y8vL/8vLy//Ly8v/x8fH/8fHx//Dw + 8P/w8PD/8PDw/+/v7//v7+//7+/v/+7u7v/u7u7/7u7u/+7u7v/t7e3/7u7u/+7u7v/u7u7/7u7u/+7u + 7v/u7u7/7u7u/+7u7v/u7u7/7u7u/+7u7v/u7u7/7+/v/+/v7//w8PD/8PDw//Dw8P/x8fH/8fHx//Hx + 8f/y8vL/8vLy//Ly8v/y8vL/8/Pz//Pz8//z8/P/9PT0//T09P/09PT/9fX1//X19f/19fX/9fX1//b2 + 9v/29vb/9vb2//b29v/39/f/9/f3//f39//39/f/+Pj4//j4+Jf///8BAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAoAAAAgAAAAAABAAABACAAAAAAAAAIAQAAAAAAAAAAAAAAAAAAAAAA////Af// + /wHw8PDj8PDw/+/v7//v7+//7+/v/+7u7v/u7u7/7u7u/+3t7f/t7e3/7e3t/+zs7P/s7Oz/6+vr/+vr + 6//q6ur/6urq/+np6f/p6en/6Ojo/+jo6P/n5+f/5ubm/+bm5v/l5eX/5OTk/+Tk5P/j4+P/4uLi/+Hh + 4f/h4eH/4ODg/9/f3//e3t7/3t7e/93d3f/c3Nz/3Nzc/9vb2//a2tr/2dnZ/9nZ2f/Y2Nj/19fX/9bW + 1v/V1dX/09PT/9LS0v/Q0ND/zs7O/83Nzf/Ly8v/ysrK/8jIyP/Hx8f/xcXF/8TExP/CwsL/wcHB/8DA + wP++vr7/vb29/7u7u/+6urr/uLi4/7e3t/+1tbX/tLS0/7Ozs/+ysrL/sbGx/7Gxsf+wsLD/sLCw/7Cw + sP+wsLD/sLCw/7Gxsf+xsbH/sbGx/7Kysv+ysrL/srKy/7S0tP+0tLT/tbW1/7a2tv+3t7f/uLi4/7m5 + uf+7u7v/u7u7/729vf++vr7/wMDA/8HBwf/BwcH/w8PD/8TExP/FxcX/xsbG/8jIyP/Jycn/ysrK/8vL + y//MzMz/zs7O/8/Pz//Q0ND/0dHR/9PT0//T09P/1dXV/9bW1v/X19f/2NjY/9nZ2f/b29v/3Nzc/97e + 3v/e3t7/39/f/+Hh4f/h4eEx////Af///wH///8B////AfDw8OPv7+//7+/v/+/v7//v7+//7u7u/+7u + 7v/t7e3/7e3t/+zs7P/s7Oz/7Ozs/+vr6//r6+v/6urq/+rq6v/p6en/6enp/+jo6P/o6Oj/5+fn/+fn + 5//m5ub/5eXl/+Tk5P/k5OT/4+Pj/+Li4v/h4eH/4eHh/+Dg4P/f39//3t7e/93d3f/c3Nz/3Nzc/9vb + 2//a2tr/2tra/9nZ2f/Y2Nj/19fX/9bW1v/V1dX/1NTU/9PT0//R0dH/z8/P/83Nzf/MzMz/ysrK/8jI + yP/Hx8f/xcXF/8PDw//BwcH/wMDA/7+/v/+9vb3/vLy8/7q6uv+4uLj/t7e3/7W1tf+zs7P/srKy/7Cw + sP+vr6//rq6u/62trf+tra3/rKys/6urq/+rq6v/q6ur/6urq/+rq6v/rKys/62trf+tra3/ra2t/66u + rv+urq7/sLCw/7CwsP+ysrL/srKy/7Ozs/+1tbX/tra2/7e3t/+5ubn/urq6/7y8vP+9vb3/vr6+/7+/ + v//AwMD/wsLC/8PDw//ExMT/xcXF/8bGxv/IyMj/ycnJ/8vLy//MzMz/zc3N/87Ozv/Pz8//0dHR/9LS + 0v/T09P/1dXV/9bW1v/X19f/2NjY/9nZ2f/b29v/3Nzc/97e3v/f39//39/f/+Dg4DH///8B////Af// + /wH///8B7+/v4+/v7//u7u7/7u7u/+7u7v/t7e3/7e3t/+3t7f/s7Oz/7Ozs/+vr6//r6+v/6urq/+rq + 6v/p6en/6enp/+jo6P/o6Oj/5+fn/+fn5//m5ub/5eXl/+Xl5f/k5OT/4+Pj/+Pj4//i4uL/4eHh/+Dg + 4P/f39//3t7e/93d3f/d3d3/3Nzc/9vb2//a2tr/2dnZ/9nZ2f/Y2Nj/19fX/9bW1v/V1dX/1NTU/9PT + 0//S0tL/0NDQ/87Ozv/MzMz/ysrK/8nJyf/Gxsb/xcXF/8LCwv/BwcH/v7+//729vf+8vLz/urq6/7i4 + uP+2trb/tLS0/7Kysv+wsLD/rq6u/6ysrP+rq6v/qamp/6ioqP+np6f/p6en/6ampv+lpaX/paWl/6Wl + pf+lpaX/paWl/6ampv+mpqb/p6en/6ioqP+oqKj/qamp/6qqqv+rq6v/rKys/62trf+vr6//sLCw/7Gx + sf+ysrL/tLS0/7a2tv+2trb/uLi4/7m5uf+7u7v/vLy8/729vf+/v7//wMDA/8LCwv/CwsL/w8PD/8XF + xf/Gxsb/yMjI/8nJyf/Ly8v/zMzM/83Nzf/Pz8//0NDQ/9HR0f/S0tL/1NTU/9XV1f/W1tb/2NjY/9nZ + 2f/b29v/3Nzc/97e3v/e3t7/39/fMf///wH///8B////Af///wHv7+/j7+/v/+7u7v/u7u7/7u7u/+3t + 7f/t7e3/7Ozs/+zs7P/r6+v/6+vr/+rq6v/q6ur/6enp/+np6f/o6Oj/6Ojo/+fn5//m5ub/5ubm/+Xl + 5f/l5eX/5OTk/+Pj4//i4uL/4eHh/+Hh4f/g4OD/39/f/97e3v/d3d3/3Nzc/9vb2//a2tr/2tra/9nZ + 2f/Y2Nj/19fX/9bW1v/V1dX/1NTU/9PT0//S0tL/0NDQ/8/Pz//Nzc3/y8vL/8rKyv/Hx8f/xsbG/8PD + w//BwcH/v7+//729vf+7u7v/ubm5/7e3t/+1tbX/s7Oz/7Gxsf+urq7/rKys/6mpqf+np6f/paWl/6Oj + o/+ioqL/oaGh/6CgoP+goKD/n5+f/5+fn/+fn5//n5+f/5+fn/+goKD/oaGh/6Ghof+ioqL/o6Oj/6Sk + pP+lpaX/pqam/6enp/+oqKj/qamp/6qqqv+srKz/ra2t/6+vr/+xsbH/srKy/7Ozs/+1tbX/tra2/7i4 + uP+5ubn/u7u7/7y8vP+9vb3/v7+//8DAwP/BwcH/w8PD/8TExP/FxcX/x8fH/8jIyP/Kysr/y8vL/8zM + zP/Ozs7/z8/P/9HR0f/S0tL/1NTU/9XV1f/W1tb/2NjY/9nZ2f/b29v/3Nzc/97e3v/e3t4x////Af// + /wH///8B////Ae7u7uPu7u7/7u7u/+3t7f/t7e3/7Ozs/+zs7P/s7Oz/6+vr/+vr6//q6ur/6urq/+np + 6f/p6en/6Ojo/+jo6P/n5+f/5ubm/+bm5v/l5eX/5eXl/+Tk5P/j4+P/4uLi/+Hh4f/h4eH/4ODg/9/f + 3//e3t7/3d3d/9zc3P/b29v/2tra/9nZ2f/Y2Nj/19fX/9bW1v/V1dX/1NTU/9PT0//S0tL/0NDQ/8/P + z//Ozs7/zMzM/8rKyv/IyMj/x8fH/8TExP/CwsL/v7+//729vf+7u7v/uLi4/7e3t/+0tLT/srKy/7Cw + sP+tra3/qqqq/6enp/+lpaX/oaGh/6CgoP+dnZ3/m5ub/5qamv+ZmZn/mJiY/5iYmP+YmJj/mJiY/5iY + mP+YmJj/mZmZ/5qamv+bm5v/nJyc/52dnf+dnZ3/n5+f/6CgoP+hoaH/oqKi/6Ojo/+lpaX/pqam/6io + qP+qqqr/q6ur/62trf+urq7/sLCw/7Kysv+zs7P/tbW1/7a2tv+4uLj/ubm5/7u7u/+8vLz/vb29/7+/ + v//AwMD/wsLC/8PDw//ExMT/xsbG/8fHx//Jycn/y8vL/8zMzP/Ozs7/z8/P/9HR0f/S0tL/1NTU/9XV + 1f/X19f/2dnZ/9nZ2f/b29v/3Nzc/93d3TH///8B////Af///wH///8B7u7u4+3t7f/t7e3/7e3t/+zs + 7P/s7Oz/7Ozs/+vr6//r6+v/6urq/+np6f/p6en/6Ojo/+jo6P/n5+f/5+fn/+bm5v/l5eX/5eXl/+Tk + 5P/j4+P/4+Pj/+Li4v/h4eH/4ODg/9/f3//e3t7/3d3d/9zc3P/c3Nz/2tra/9nZ2f/Z2dn/19fX/9bW + 1v/V1dX/1NTU/9PT0//S0tL/0dHR/8/Pz//Nzc3/zMzM/8rKyv/IyMj/x8fH/8XFxf/Dw8P/wcHB/76+ + vv+7u7v/ubm5/7a2tv+0tLT/sbGx/66urv+srKz/qamp/6ampv+jo6P/n5+f/5mZmf+BgYH/ioqK/5SU + lP+Tk5P/kZGR/5CQkP+QkJD/kJCQ/5CQkP+QkJD/kZGR/5GRkf+SkpL/k5OT/5WVlf+Wlpb/lpaW/5eX + l/+ZmZn/mpqa/5ycnP+dnZ3/np6e/6CgoP+ioqL/o6Oj/6ampv+np6f/qamp/6urq/+srKz/rq6u/6+v + r/+xsbH/s7Oz/7S0tP+2trb/t7e3/7m5uf+6urr/vLy8/729vf+/v7//wMDA/8HBwf/ExMT/xcXF/8fH + x//Jycn/ysrK/8zMzP/Ozs7/z8/P/9HR0f/S0tL/1NTU/9bW1v/X19f/2dnZ/9ra2v/b29v/3NzcMf// + /wH///8B////Af///wHt7e3j7e3t/+zs7P/s7Oz/7Ozs/+vr6//r6+v/6urq/+rq6v/q6ur/6enp/+np + 6f/o6Oj/5+fn/+bm5v/m5ub/5eXl/+Xl5f/k5OT/4+Pj/+Li4v/i4uL/4ODg/+Dg4P/f39//3t7e/93d + 3f/c3Nz/29vb/9ra2v/Z2dn/2NjY/9fX1//W1tb/1NTU/9PT0//S0tL/0dHR/9DQ0P/Pz8//zc3N/8vL + y//Jycn/yMjI/8bGxv/Dw8P/wsLC/8DAwP++vr7/u7u7/7m5uf+2trb/s7Oz/6+vr/+srKz/qamp/6en + p/+jo6P/n5+f/5ycnP+VlZX/fX19/2RkZP9paWn/enp6/4qKiv+Li4v/iYmJ/4mJif+JiYn/iYmJ/4qK + iv+Kior/i4uL/4yMjP+Ojo7/j4+P/5CQkP+RkZH/kpKS/5SUlP+VlZX/l5eX/5mZmf+ampr/m5ub/56e + nv+fn5//oqKi/6SkpP+mpqb/p6en/6ioqP+rq6v/rKys/66urv+wsLD/sbGx/7Ozs/+0tLT/tra2/7i4 + uP+5ubn/u7u7/7y8vP++vr7/wMDA/8HBwf/Dw8P/xcXF/8fHx//Jycn/ysrK/8zMzP/Ozs7/z8/P/9HR + 0f/S0tL/1NTU/9bW1v/X19f/2dnZ/9ra2v/b29sx////Af///wH///8B////Ae3t7ePs7Oz/7Ozs/+vr + 6//r6+v/6urq/+rq6v/q6ur/6enp/+np6f/o6Oj/5+fn/+fn5//m5ub/5ubm/+Xl5f/k5OT/4+Pj/+Pj + 4//i4uL/4eHh/+Dg4P/f39//3t7e/93d3f/d3d3/29vb/9vb2//Z2dn/2NjY/9jY2P/W1tb/1dXV/9PT + 0//T09P/0tLS/9DQ0P/Pz8//zc3N/8zMzP/Kysr/yMjI/8bGxv/ExMT/wsLC/8DAwP++vr7/vLy8/7m5 + uf+3t7f/tLS0/7Kysv+urq7/qqqq/6enp/+jo6P/n5+f/5ubm/+Xl5f/k5OT/4CAgP9jY2P/YmJi/2Fh + Yf9iYmL/enp6/4ODg/+CgoL/gYGB/4GBgf+CgoL/goKC/4ODg/+EhIT/hoaG/4eHh/+IiIj/iYmJ/4uL + i/+MjIz/jo6O/4+Pj/+RkZH/k5OT/5WVlf+Xl5f/mZmZ/5qamv+dnZ3/n5+f/6Ghof+ioqL/pKSk/6am + pv+oqKj/qqqq/6urq/+tra3/r6+v/7Gxsf+ysrL/tLS0/7a2tv+4uLj/ubm5/7u7u/+9vb3/v7+//8HB + wf/CwsL/xMTE/8bGxv/IyMj/ysrK/8zMzP/Ozs7/z8/P/9HR0f/S0tL/1NTU/9bW1v/X19f/2dnZ/9nZ + 2TH///8B////Af///wH///8B7Ozs4+zs7P/r6+v/6+vr/+vr6//q6ur/6urq/+np6f/p6en/6Ojo/+fn + 5//n5+f/5ubm/+bm5v/l5eX/5OTk/+Pj4//i4uL/4uLi/+Hh4f/g4OD/39/f/97e3v/d3d3/3Nzc/9vb + 2//a2tr/2dnZ/9jY2P/X19f/1tbW/9XV1f/T09P/0tLS/9HR0f/Q0ND/zs7O/8zMzP/Kysr/ycnJ/8fH + x//FxcX/xMTE/8HBwf+/v7//vb29/7u7u/+5ubn/tra2/7S0tP+wsLD/ra2t/6qqqv+lpaX/oqKi/52d + nf+ZmZn/lJSU/5CQkP+MjIz/dnZ2/2FhYf9jY2P/YmJi/2FhYf92dnb/fX19/3x8fP98fHz/e3t7/3x8 + fP98fHz/fX19/35+fv+AgID/gYGB/4ODg/+EhIT/hYWF/4eHh/+JiYn/i4uL/4yMjP+Ojo7/kJCQ/5KS + kv+UlJT/lpaW/5mZmf+bm5v/nZ2d/56env+goKD/oqKi/6SkpP+mpqb/qKio/6qqqv+srKz/ra2t/7Cw + sP+xsbH/s7Oz/7W1tf+2trb/ubm5/7q6uv+9vb3/vr6+/8DAwP/CwsL/xMTE/8bGxv/IyMj/ysrK/8vL + y//Nzc3/z8/P/9HR0f/T09P/1dXV/9bW1v/X19f/2NjYMf///wH///8B////Af///wHr6+vj6+vr/+vr + 6//q6ur/6urq/+np6f/p6en/6Ojo/+jo6P/n5+f/5+fn/+bm5v/l5eX/5eXl/+Tk5P/j4+P/4uLi/+Hh + 4f/h4eH/39/f/9/f3//e3t7/3Nzc/9zc3P/b29v/2tra/9jY2P/X19f/19fX/9XV1f/V1dX/09PT/9LS + 0v/R0dH/z8/P/87Ozv/MzMz/ysrK/8jIyP/Gxsb/xMTE/8LCwv/AwMD/vr6+/7y8vP+5ubn/t7e3/7W1 + tf+ysrL/r6+v/6ysrP+pqan/pKSk/5+fn/+bm5v/lpaW/5GRkf+MjIz/iIiI/4SEhP9ycnL/YWFh/2Rk + ZP9iYmL/YWFh/3Fxcf92dnb/dnZ2/3V1df91dXX/dXV1/3V1df92dnb/eHh4/3p6ev97e3v/fX19/39/ + f/+AgID/goKC/4ODg/+Ghob/h4eH/4mJif+Li4v/jY2N/5CQkP+SkpL/lJSU/5aWlv+YmJj/mpqa/5yc + nP+enp7/oKCg/6Kiov+kpKT/pqam/6ioqP+qqqr/rKys/66urv+wsLD/srKy/7Ozs/+2trb/uLi4/7q6 + uv+8vLz/vr6+/8DAwP/CwsL/xMTE/8bGxv/IyMj/ysrK/8vLy//Nzc3/z8/P/9HR0f/T09P/1dXV/9bW + 1v/X19cx////Af///wH///8B////Aevr6+Pr6+v/6urq/+np6f/p6en/6Ojo/+jo6P/o6Oj/5+fn/+bm + 5v/m5ub/5eXl/+Tk5P/k5OT/4+Pj/+Li4v/h4eH/4ODg/9/f3//e3t7/3t7e/9zc3P/b29v/2tra/9nZ + 2f/Y2Nj/19fX/9bW1v/V1dX/1NTU/9PT0//R0dH/0NDQ/8/Pz//Nzc3/zMzM/8rKyv/IyMj/xsbG/8TE + xP/CwsL/v7+//729vf+7u7v/uLi4/7a2tv+zs7P/sLCw/62trf+rq6v/p6en/6Ojo/+enp7/mZmZ/5SU + lP+Ojo7/iYmJ/4SEhP9/f3//fHx8/21tbf9iYmL/ZWVl/2NjY/9iYmL/bW1t/3BwcP9wcHD/b29v/29v + b/9vb2//b29v/3Fxcf9zc3P/dHR0/3Z2dv94eHj/enp6/3t7e/99fX3/fn5+/4CAgP+CgoL/hISE/4aG + hv+JiYn/i4uL/42Njf+Pj4//kZGR/5SUlP+Wlpb/mJiY/5qamv+cnJz/np6e/6CgoP+jo6P/paWl/6am + pv+pqan/qqqq/62trf+vr6//sbGx/7Ozs/+1tbX/t7e3/7m5uf+8vLz/vr6+/7+/v//CwsL/xMTE/8bG + xv/IyMj/ysrK/8zMzP/Ozs7/z8/P/9HR0f/T09P/1dXV/9bW1jH///8B////Af///wH///8B6urq4+rq + 6v/p6en/6enp/+jo6P/o6Oj/5+fn/+fn5//m5ub/5ubm/+Xl5f/l5eX/5OTk/+Pj4//i4uL/4eHh/+Hh + 4f/f39//3t7e/93d3f/c3Nz/29vb/9ra2v/Z2dn/2NjY/9fX1//W1tb/1dXV/9TU1P/S0tL/0dHR/9DQ + 0P/Ozs7/zc3N/8vLy//Jycn/x8fH/8XFxf/Dw8P/wcHB/7+/v/+9vb3/urq6/7e3t/+1tbX/s7Oz/7Cw + sP+tra3/qamp/6ampv+ioqL/nZ2d/5iYmP+Tk5P/jY2N/4eHh/+CgoL/fX19/3h4eP91dXX/a2tr/2Rk + ZP9mZmb/ZWVl/2NjY/9paWn/ampq/2lpaf9paWn/aWlp/2pqav9ra2v/bW1t/25ubv9wcHD/cnJy/3Nz + c/91dXX/d3d3/3l5ef96enr/fHx8/319ff9/f3//gYGB/4SEhP+Hh4f/iYmJ/4uLi/+NjY3/kJCQ/5KS + kv+UlJT/lpaW/5iYmP+bm5v/nZ2d/5+fn/+hoaH/o6Oj/6ampv+oqKj/qqqq/6ysrP+urq7/sLCw/7Ky + sv+1tbX/t7e3/7m5uf+7u7v/vb29/8DAwP/CwsL/xMTE/8bGxv/IyMj/ysrK/8zMzP/Ozs7/0NDQ/9LS + 0v/U1NT/1dXVMf///wH///8B////Af///wHq6urj6enp/+np6f/o6Oj/6Ojo/+fn5//n5+f/5ubm/+Xl + 5f/l5eX/5OTk/+Tk5P/j4+P/4uLi/+Hh4f/g4OD/39/f/97e3v/d3d3/3Nzc/9vb2//a2tr/2dnZ/9fX + 1//X19f/1tbW/9TU1P/T09P/0tLS/9HR0f/Q0ND/zs7O/8zMzP/Kysr/ycnJ/8fHx//FxcX/w8PD/8HB + wf++vr7/vLy8/7m5uf+2trb/s7Oz/7Gxsf+urq7/rKys/6mpqf+lpaX/oaGh/5ubm/+Xl5f/kZGR/4uL + i/+Ghob/gYGB/3x8fP92dnb/cnJy/29vb/9oaGj/ZWVl/2lpaf9qamr/ampq/2hoaP9kZGT/Y2Nj/2Nj + Y/9kZGT/ZWVl/2ZmZv9oaGj/aWlp/2tra/9tbW3/bm5u/3BwcP9xcXH/c3Nz/3V1df92dnb/eHh4/3p6 + ev98fHz/fn5+/4GBgf+EhIT/hoaG/4mJif+Li4v/jY2N/4+Pj/+RkZH/lJSU/5aWlv+ZmZn/m5ub/56e + nv+fn5//oqKi/6SkpP+mpqb/qKio/6urq/+tra3/r6+v/7Kysv+0tLT/tra2/7m5uf+7u7v/vb29/7+/ + v//CwsL/xMTE/8bGxv/IyMj/ysrK/83Nzf/Pz8//0dHR/9PT0//T09Mx////Af///wH///8B////Aenp + 6ePp6en/6Ojo/+jo6P/n5+f/5+fn/+bm5v/l5eX/5eXl/+Tk5P/k5OT/4+Pj/+Li4v/h4eH/4ODg/9/f + 3//f39//3d3d/9zc3P/b29v/2tra/9nZ2f/Y2Nj/19fX/9bW1v/U1NT/09PT/9LS0v/R0dH/z8/P/87O + zv/MzMz/ysrK/8nJyf/Hx8f/xcXF/8PDw//BwcH/vr6+/7y8vP+5ubn/tra2/7Ozs/+wsLD/rq6u/6ur + q/+oqKj/pKSk/6CgoP+cnJz/lZWV/5CQkP+Li4v/hoaG/39/f/96enr/dnZ2/3Fxcf9ubm7/a2tr/2dn + Z/9nZ2f/a2tr/25ubv9ycnL/cHBw/2dnZ/9fX1//X19f/2BgYP9hYWH/YmJi/2RkZP9lZWX/Z2dn/2ho + aP9qamr/a2tr/21tbf9vb2//cHBw/3Jycv90dHT/dnZ2/3l5ef97e3v/fX19/4CAgP+CgoL/hYWF/4eH + h/+JiYn/i4uL/46Ojv+QkJD/k5OT/5WVlf+YmJj/mpqa/5ycnP+fn5//oaGh/6Ojo/+lpaX/qKio/6qq + qv+tra3/r6+v/7Gxsf+0tLT/tra2/7m5uf+7u7v/vb29/8DAwP/CwsL/xMTE/8fHx//Jycn/y8vL/83N + zf/Pz8//0dHR/9LS0jH///8B////Af///wH///8B6enp4+jo6P/o6Oj/5+fn/+fn5//m5ub/5eXl/+Xl + 5f/k5OT/4+Pj/+Pj4//i4uL/4eHh/+Dg4P/g4OD/3t7e/97e3v/c3Nz/29vb/9ra2v/Z2dn/2NjY/9fX + 1//W1tb/1NTU/9PT0//R0dH/0NDQ/8/Pz//Nzc3/zMzM/8rKyv/Jycn/x8fH/8XFxf/Dw8P/wMDA/76+ + vv+7u7v/uLi4/7W1tf+zs7P/sLCw/62trf+qqqr/p6en/6Ojo/+fn5//mpqa/5WVlf+Pj4//ioqK/4WF + hf97e3v/Y2Nj/11dXf9nZ2f/ampq/2pqav9nZ2f/Z2dn/2lpaf9sbGz/b29v/3Nzc/90dHT/b29v/1xc + XP9bW1v/XFxc/11dXf9eXl7/X19f/2FhYf9iYmL/ZGRk/2VlZf9nZ2f/aWlp/2pqav9sbGz/bW1t/29v + b/9xcXH/dHR0/3Z2dv94eHj/enp6/35+fv+AgID/goKC/4SEhP+Hh4f/ioqK/4yMjP+Ojo7/kZGR/5SU + lP+Wlpb/mJiY/5ubm/+dnZ3/oKCg/6Kiov+kpKT/p6en/6qqqv+tra3/r6+v/7Gxsf+0tLT/tra2/7m5 + uf+7u7v/vr6+/8DAwP/CwsL/xcXF/8fHx//Kysr/zMzM/87Ozv/Q0ND/0NDQMf///wH///8B////Af// + /wHp6enj6Ojo/+fn5//n5+f/5ubm/+Xl5f/l5eX/5OTk/+Pj4//j4+P/4uLi/+Hh4f/g4OD/4ODg/9/f + 3//e3t7/3d3d/9zc3P/a2tr/2dnZ/9jY2P/X19f/1tbW/9TU1P/T09P/0dHR/9DQ0P/Pz8//zc3N/8vL + y//Kysr/yMjI/8fHx//FxcX/w8PD/8DAwP++vr7/u7u7/7i4uP+1tbX/s7Oz/7CwsP+tra3/qamp/6am + pv+ioqL/np6e/5qamv+UlJT/j4+P/4mJif+EhIT/fX19/2NjY/9QUFD/S0tL/01NTf9dXV3/ZWVl/2Vl + Zf9oaGj/a2tr/25ubv9wcHD/c3Nz/3R0dP9wcHD/Wlpa/1dXV/9YWFj/WVlZ/1paWv9bW1v/XV1d/15e + Xv9gYGD/YWFh/2JiYv9kZGT/ZmZm/2dnZ/9paWn/a2tr/21tbf9vb2//cnJy/3R0dP92dnb/eXl5/3t7 + e/9+fn7/gICA/4ODg/+Ghob/iIiI/4uLi/+NjY3/kJCQ/5OTk/+VlZX/mJiY/5qamv+dnZ3/n5+f/6Gh + of+kpKT/p6en/6qqqv+tra3/r6+v/7Gxsf+0tLT/t7e3/7m5uf+7u7v/vr6+/8HBwf/Dw8P/xsbG/8jI + yP/Kysr/zMzM/8/Pz//Q0NAx////Af///wH///8B////Aejo6OPo6Oj/5+fn/+bm5v/m5ub/5eXl/+Tk + 5P/j4+P/4+Pj/+Li4v/h4eH/4ODg/+Dg4P/f39//3t7e/93d3f/c3Nz/2tra/9nZ2f/Y2Nj/19fX/9bW + 1v/U1NT/09PT/9HR0f/Q0ND/z8/P/83Nzf/Ly8v/ycnJ/8jIyP/Gxsb/xMTE/8LCwv/AwMD/vr6+/7u7 + u/+4uLj/tbW1/7Ozs/+wsLD/ra2t/6qqqv+mpqb/oqKi/56env+ZmZn/lJSU/42Njf+IiIj/goKC/319 + ff9ycnL/VFRU/09PT/9JSUn/RUVF/1VVVf9hYWH/ZGRk/2pqav9tbW3/cHBw/3Jycv90dHT/dXV1/3Bw + cP9XV1f/VFRU/1VVVf9WVlb/V1dX/1hYWP9XV1f/S0tL/0lJSf9YWFj/Xl5e/2BgYP9hYWH/Y2Nj/2Vl + Zf9nZ2f/aWlp/2tra/9tbW3/cHBw/3Jycv91dXX/d3d3/3p6ev98fHz/fn5+/4GBgf+EhIT/h4eH/4qK + iv+MjIz/j4+P/5GRkf+UlJT/l5eX/5mZmf+cnJz/np6e/6Ghof+kpKT/p6en/6qqqv+srKz/r6+v/7Ky + sv+0tLT/t7e3/7q6uv+9vb3/v7+//8HBwf/ExMT/xsbG/8nJyf/Ly8v/zs7O/8/PzzH///8B////Af// + /wH///8B6Ojo4+fn5//m5ub/5ubm/+Xl5f/k5OT/5OTk/+Pj4//i4uL/4eHh/+Dg4P/g4OD/39/f/97e + 3v/d3d3/3Nzc/9vb2//Z2dn/2NjY/9fX1//W1tb/1NTU/9PT0//R0dH/0NDQ/8/Pz//Nzc3/y8vL/8nJ + yf/IyMj/xsbG/8TExP/CwsL/wMDA/729vf+7u7v/uLi4/7W1tf+ysrL/sLCw/62trf+qqqr/pqam/6Gh + of+enp7/mZmZ/5OTk/+Ojo7/h4eH/4KCgv98fHz/dnZ2/2xsbP9VVVX/UVFR/0dHR/9DQ0P/UlJS/15e + Xv9nZ2f/bGxs/25ubv9xcXH/dHR0/3d3d/93d3f/cXFx/1NTU/9QUFD/UVFR/1JSUv9TU1P/UlJS/z4+ + Pv8fHx//Hh4e/zExMf9KSkr/Wlpa/15eXv9fX1//YmJi/2NjY/9lZWX/Z2dn/2lpaf9ra2v/bm5u/3Bw + cP9ycnL/dXV1/3h4eP96enr/fX19/4CAgP+Dg4P/hYWF/4iIiP+Li4v/jo6O/5CQkP+Tk5P/lpaW/5mZ + mf+bm5v/np6e/6Ghof+kpKT/p6en/6qqqv+tra3/r6+v/7Kysv+1tbX/uLi4/7q6uv+9vb3/wMDA/8PD + w//FxcX/x8fH/8rKyv/MzMz/zc3NMf///wH///8B////Af///wHn5+fj5+fn/+bm5v/l5eX/5eXl/+Tk + 5P/j4+P/4uLi/+Li4v/h4eH/4ODg/9/f3//e3t7/3d3d/9zc3P/b29v/2tra/9jY2P/X19f/1tbW/9TU + 1P/T09P/0dHR/9DQ0P/Pz8//zc3N/8vLy//Jycn/x8fH/8bGxv/ExMT/wcHB/8DAwP+9vb3/u7u7/7m5 + uf+1tbX/s7Oz/7CwsP+tra3/qqqq/6ampv+jo6P/np6e/5mZmf+UlJT/j4+P/4iIiP+CgoL/fHx8/3Z2 + dv9wcHD/ZmZm/1ZWVv9TU1P/RkZG/0JCQv9PT0//X19f/2lpaf9tbW3/b29v/3Jycv96enr/fn5+/3h4 + eP9xcXH/UVFR/01NTf9OTk7/T09P/09PT/9AQED/ISEh/xoaGv8bGxv/Hh4e/yYmJv88PDz/VFRU/1xc + XP9eXl7/YGBg/2FhYf9jY2P/ZWVl/2dnZ/9qamr/bGxs/25ubv9xcXH/dHR0/3d3d/96enr/fHx8/39/ + f/+BgYH/hISE/4eHh/+Kior/jY2N/5CQkP+Tk5P/lZWV/5mZmf+cnJz/np6e/6Kiov+kpKT/p6en/6qq + qv+tra3/sLCw/7Ozs/+2trb/ubm5/7y8vP+/v7//wcHB/8TExP/Gxsb/ycnJ/8zMzP/MzMwx////Af// + /wH///8B////Aefn5+Pm5ub/5ubm/+Tk5P/k5OT/4+Pj/+Li4v/i4uL/4eHh/+Dg4P/f39//3t7e/93d + 3f/c3Nz/29vb/9ra2v/Z2dn/19fX/9fX1//V1dX/1NTU/9LS0v/Q0ND/z8/P/83Nzf/Ly8v/ycnJ/8fH + x//Gxsb/w8PD/8HBwf+/v7//vb29/7u7u/+4uLj/tbW1/7Kysv+wsLD/ra2t/6mpqf+mpqb/oqKi/5+f + n/+ZmZn/lJSU/46Ojv+IiIj/goKC/3t7e/92dnb/b29v/2lpaf9gYGD/WFhY/1VVVf9ERET/QUFB/0tL + S/9eXl7/a2tr/25ubv9xcXH/enp6/46Ojv+VlZX/fHx8/3Nzc/9PT0//SUlJ/0pKSv9LS0v/PDw8/xsb + G/8TExP/HBwc/x4eHv8dHR3/Hh4e/x4eHv8oKCj/QEBA/1VVVf9bW1v/XV1d/19fX/9hYWH/Y2Nj/2Vl + Zf9oaGj/ampq/21tbf9wcHD/cnJy/3V1df94eHj/e3t7/319ff+AgID/g4OD/4aGhv+JiYn/jIyM/4+P + j/+SkpL/lZWV/5iYmP+bm5v/np6e/6Ghof+kpKT/qKio/6urq/+urq7/sbGx/7W1tf+3t7f/urq6/729 + vf/AwMD/w8PD/8XFxf/IyMj/y8vL/8vLyzH///8B////Af///wH///8B5ubm4+bm5v/l5eX/5OTk/+Pj + 4//i4uL/4uLi/+Hh4f/g4OD/39/f/97e3v/d3d3/3Nzc/9vb2//a2tr/2dnZ/9jY2P/X19f/1dXV/9TU + 1P/S0tL/0dHR/8/Pz//Nzc3/y8vL/8nJyf/IyMj/xcXF/8TExP/BwcH/v7+//729vf+7u7v/uLi4/7W1 + tf+zs7P/r6+v/6ysrP+pqan/pqam/6Ojo/+fn5//mpqa/5SUlP+Pj4//iYmJ/4SEhP99fX3/dnZ2/3Bw + cP9paWn/YmJi/1xcXP9bW1v/V1dX/0ZGRv9FRUX/SkpK/11dXf9sbGz/cHBw/3Z2dv+MjIz/oKCg/4+P + j/9vb2//dnZ2/1dXV/9GRkb/R0dH/z4+Pv8dHR3/EhIS/xgYGP8uLi7/LCws/x4eHv8eHh7/Hh4e/x4e + Hv8hISH/NDQ0/0xMTP9ZWVn/W1tb/11dXf9fX1//YWFh/2RkZP9mZmb/aWlp/2xsbP9ubm7/cXFx/3R0 + dP93d3f/enp6/319ff+AgID/goKC/4aGhv+JiYn/jIyM/4+Pj/+SkpL/lZWV/5iYmP+cnJz/np6e/6Ki + ov+mpqb/qamp/6ysrP+vr6//s7Oz/7a2tv+5ubn/vLy8/76+vv/CwsL/xMTE/8fHx//Kysr/y8vLMf// + /wH///8B////Af///wHm5ubj5eXl/+Tk5P/j4+P/4+Pj/+Li4v/h4eH/4ODg/9/f3//e3t7/3d3d/9zc + 3P/b29v/2tra/9nZ2f/Y2Nj/19fX/9XV1f/U1NT/0tLS/9HR0f/Pz8//zc3N/8zMzP/Kysr/yMjI/8bG + xv/Dw8P/wcHB/7+/v/+9vb3/u7u7/7i4uP+2trb/s7Oz/7CwsP+srKz/qamp/6ampv+jo6P/np6e/5mZ + mf+VlZX/j4+P/4qKiv+EhIT/fn5+/3h4eP9wcHD/ampq/2JiYv9bW1v/WFhY/11dXf9fX1//X19f/1lZ + Wf9MTEz/Xl5e/25ubv92dnb/h4eH/5+fn/+SkpL/VVVV/1ZWVv93d3f/bGxs/05OTv89PT3/JCQk/xMT + E/8YGBj/KCgo/zY2Nv8rKyv/Hh4e/x4eHv8eHh7/Hh4e/x4eHv8eHh7/JSUl/z09Pf9QUFD/WFhY/1tb + W/9dXV3/X19f/2FhYf9kZGT/Z2dn/2pqav9tbW3/cHBw/3Nzc/91dXX/eHh4/3t7e/9+fn7/goKC/4WF + hf+IiIj/i4uL/46Ojv+SkpL/lZWV/5mZmf+cnJz/n5+f/6Ojo/+mpqb/qqqq/62trf+xsbH/tLS0/7e3 + t/+6urr/vb29/8DAwP/Dw8P/xsbG/8nJyf/Kysox////Af///wH///8B////AeXl5ePk5OT/5OTk/+Pj + 4//i4uL/4eHh/+Dg4P/f39//39/f/97e3v/c3Nz/29vb/9ra2v/Z2dn/2NjY/9fX1//W1tb/1NTU/9LS + 0v/R0dH/0NDQ/83Nzf/MzMz/ysrK/8jIyP/Gxsb/xMTE/8HBwf+/v7//vb29/7u7u/+4uLj/tra2/7S0 + tP+wsLD/ra2t/6qqqv+mpqb/o6Oj/6CgoP+ampr/lZWV/5CQkP+JiYn/hISE/35+fv9zc3P/aWlp/2lp + af9kZGT/XFxc/1VVVf9UVFT/YGBg/2NjY/9mZmb/XFxc/09PT/9dXV3/c3Nz/4WFhf+bm5v/lpaW/11d + Xf9MTEz/cHBw/4aGhv92dnb/Y2Nj/ykpKf8WFhb/GBgY/ycnJ/8rKyv/Hx8f/xwcHP8eHh7/Hh4e/x4e + Hv8eHh7/Hh4e/x4eHv8eHh7/Hx8f/ywsLP9DQ0P/VVVV/1lZWf9bW1v/XV1d/2BgYP9jY2P/ZmZm/2lp + af9sbGz/b29v/3Jycv91dXX/eHh4/3t7e/9+fn7/gYGB/4SEhP+IiIj/i4uL/4+Pj/+SkpL/lpaW/5mZ + mf+dnZ3/oaGh/6SkpP+oqKj/q6ur/6+vr/+ysrL/tra2/7m5uf+8vLz/v7+//8LCwv/FxcX/yMjI/8rK + yjH///8B////Af///wH///8B5OTk4+Tk5P/j4+P/4uLi/+Hh4f/g4OD/4ODg/9/f3//e3t7/3d3d/9zc + 3P/b29v/2dnZ/9jY2P/X19f/1tbW/9XV1f/S0tL/0dHR/9DQ0P/Ozs7/zMzM/8rKyv/IyMj/xsbG/8TE + xP/CwsL/wMDA/729vf+7u7v/uLi4/7W1tf+zs7P/sbGx/62trf+qqqr/pqam/6Ojo/+fn5//m5ub/5aW + lv+Pj4//ioqK/4ODg/9+fn7/dHR0/1paWv9NTU3/U1NT/1lZWf9XV1f/UVFR/1RUVP9iYmL/ZWVl/2ho + aP9dXV3/UFBQ/2FhYf+BgYH/mpqa/56env9hYWH/SEhI/2pqav+MjIz/fHx8/5+fn/9nZ2f/HBwc/xcX + F/8lJSX/Kysr/xwcHP8aGhr/HBwc/x4eHv8eHh7/Hh4e/x4eHv8eHh7/Hh4e/x4eHv8eHh7/Hh4e/yMj + I/81NTX/S0tL/1ZWVv9aWlr/XFxc/19fX/9iYmL/ZmZm/2hoaP9ra2v/bm5u/3Fxcf90dHT/d3d3/3t7 + e/9+fn7/gYGB/4WFhf+IiIj/jIyM/4+Pj/+Tk5P/lpaW/5qamv+enp7/oaGh/6ampv+pqan/ra2t/7Gx + sf+0tLT/uLi4/7u7u/++vr7/wcHB/8XFxf/IyMj/ycnJMf///wH///8B////Af///wHj4+Pj4+Pj/+Li + 4v/h4eH/4ODg/9/f3//f39//3t7e/93d3f/c3Nz/29vb/9ra2v/Y2Nj/2NjY/9bW1v/V1dX/09PT/9LS + 0v/Q0ND/zs7O/8zMzP/Kysr/yMjI/8bGxv/ExMT/wsLC/8DAwP+9vb3/u7u7/7i4uP+1tbX/s7Oz/7Cw + sP+urq7/qqqq/6enp/+jo6P/n5+f/5ubm/+Wlpb/kJCQ/4qKiv+EhIT/fX19/3d3d/9eXl7/SkpK/0VF + Rf9BQUH/RUVF/1JSUv9PT0//XFxc/2VlZf9oaGj/ampq/1JSUv9OTk7/bW1t/5eXl/+cnJz/ampq/0dH + R/9mZmb/iYmJ/35+fv+vr6//+vr6/9HR0f84ODj/HR0d/ykpKf8hISH/GRkZ/xsbG/8dHR3/Hh4e/x8f + H/8fHx//Hh4e/x4eHv8eHh7/Hh4e/x4eHv8eHh7/HR0d/x0dHf8lJSX/PT09/09PT/9YWFj/W1tb/15e + Xv9hYWH/ZGRk/2dnZ/9paWn/bGxs/3BwcP9zc3P/dnZ2/3p6ev9+fn7/gYGB/4SEhP+IiIj/i4uL/4+P + j/+Tk5P/l5eX/5ubm/+enp7/o6Oj/6enp/+rq6v/r6+v/7Ozs/+3t7f/urq6/76+vv/BwcH/xMTE/8fH + x//IyMgx////Af///wH///8B////AePj4+Pi4uL/4uLi/+Hh4f/g4OD/39/f/97e3v/d3d3/3Nzc/9vb + 2//a2tr/2dnZ/9jY2P/W1tb/1dXV/9PT0//S0tL/0NDQ/87Ozv/MzMz/ysrK/8nJyf/Hx8f/xcXF/8LC + wv/AwMD/vr6+/7u7u/+5ubn/tbW1/7Ozs/+wsLD/rq6u/6urq/+np6f/pKSk/6CgoP+cnJz/l5eX/5KS + kv+Li4v/hISE/39/f/93d3f/cHBw/1VVVf9MTEz/Q0ND/z4+Pv9BQUH/T09P/1NTU/9jY2P/Z2dn/2pq + av9ra2v/S0tL/0hISP9xcXH/m5ub/2tra/9GRkb/YWFh/4eHh/98fHz/nZ2d//Hx8f/8/Pz/wsLC/zAw + MP8gICD/JSUl/yIiIv8hISH/IiIi/yEhIf8fHx//Hh4e/x4eHv8fHx//Hh4e/x4eHv8eHh7/Hh4e/x4e + Hv8eHh7/Hh4e/x0dHf8hISH/Ly8v/0hISP9XV1f/Wlpa/11dXf9gYGD/ZGRk/2ZmZv9paWn/bGxs/29v + b/9zc3P/dnZ2/3p6ev99fX3/gICA/4WFhf+IiIj/jY2N/5CQkP+UlJT/mZmZ/5ycnP+hoaH/paWl/6mp + qf+tra3/srKy/7a2tv+5ubn/vb29/8DAwP/ExMT/x8fH/8jIyDH///8B////Af///wH///8B4uLi4+Hh + 4f/h4eH/4ODg/9/f3//e3t7/3d3d/9zc3P/b29v/2tra/9nZ2f/Y2Nj/19fX/9bW1v/U1NT/0tLS/9HR + 0f/Ozs7/zc3N/8rKyv/Jycn/x8fH/8XFxf/Dw8P/wMDA/76+vv+7u7v/uLi4/7a2tv+zs7P/sLCw/62t + rf+qqqr/p6en/6Ojo/+fn5//m5ub/5eXl/+RkZH/i4uL/4aGhv9+fn7/eHh4/3BwcP9qamr/VlZW/1BQ + UP9BQUH/Ojo6/z09Pf9NTU3/XFxc/2dnZ/9qamr/bGxs/25ubv9LS0v/R0dH/19fX/9mZmb/RERE/1tb + W/+IiIj/goKC/6CgoP/09PT//Pz8/7y8vP8+Pj7/HBwc/ygoKP8oKCj/ICAg/yIiIv8kJCT/JSUl/yQk + JP8gICD/Hh4e/x8fH/8fHx//Hh4e/x4eHv8eHh7/Hh4e/x4eHv8eHh7/Hh4e/x4eHv8eHh7/IiIi/zY2 + Nv9MTEz/WFhY/1xcXP9fX1//YmJi/2VlZf9oaGj/a2tr/29vb/9ycnL/dnZ2/3l5ef98fHz/gYGB/4SE + hP+JiYn/jY2N/5GRkf+VlZX/mpqa/56env+ioqL/p6en/6ysrP+wsLD/tbW1/7m5uf+9vb3/wMDA/8PD + w//Gxsb/yMjIMf///wH///8B////Af///wHi4uLj4eHh/+Dg4P/f39//3t7e/93d3f/c3Nz/29vb/9ra + 2v/Z2dn/2NjY/9fX1//W1tb/1NTU/9PT0//R0dH/z8/P/83Nzf/Ly8v/ycnJ/8fHx//FxcX/w8PD/8HB + wf++vr7/vLy8/7m5uf+2trb/tLS0/7Gxsf+urq7/qqqq/6enp/+jo6P/n5+f/5ubm/+Wlpb/kZGR/4yM + jP+Ghob/gICA/3l5ef9zc3P/bGxs/2ZmZv9YWFj/UlJS/z8/P/83Nzf/Ozs7/09PT/9kZGT/aWlp/2tr + a/9tbW3/eHh4/2FhYf9LS0v/U1NT/0RERP9XV1f/f39//4aGhv+QkJD/6Ojo///////S0tL/R0dH/xwc + HP8nJyf/KSkp/yIiIv8fHx//IyMj/yQkJP8lJSX/JiYm/yUlJf8iIiL/Hx8f/x8fH/8fHx//Hx8f/x4e + Hv8eHh7/Hh4e/x4eHv8eHh7/Hh4e/x4eHv8eHh7/Hx8f/yoqKv9CQkL/VFRU/1xcXP9fX1//YmJi/2Vl + Zf9oaGj/bGxs/29vb/9ycnL/dnZ2/3l5ef9+fn7/gYGB/4aGhv+Kior/jo6O/5KSkv+Xl5f/nJyc/6Cg + oP+mpqb/qqqq/6+vr/+zs7P/t7e3/7y8vP/AwMD/w8PD/8bGxv/IyMgx////Af///wH///8B////AeHh + 4ePg4OD/4ODg/9/f3//e3t7/3d3d/9zc3P/a2tr/2dnZ/9jY2P/X19f/1tbW/9TU1P/T09P/0tLS/9DQ + 0P/Ozs7/y8vL/8nJyf/Hx8f/xcXF/8PDw//BwcH/vr6+/7y8vP+5ubn/tra2/7S0tP+xsbH/rq6u/6ur + q/+np6f/pKSk/6CgoP+bm5v/lpaW/5CQkP+MjIz/hoaG/4CAgP96enr/c3Nz/25ubv9nZ2f/YWFh/1lZ + Wf9VVVX/PT09/zQ0NP85OTn/TU1N/2ZmZv9ra2v/bW1t/3Z2dv+NjY3/kZGR/15eXv9VVVX/QEBA/15e + Xv+Dg4P/jo6O/+Hh4f/8/Pz/1dXV/1dXV/8cHBz/JiYm/ykpKf8hISH/Hx8f/yIiIv8kJCT/JSUl/yYm + Jv8mJib/Jycn/yYmJv8jIyP/ISEh/x8fH/8fHx//Hx8f/x8fH/8eHh7/Hh4e/x4eHv8eHh7/Hh4e/x4e + Hv8eHh7/Hh4e/yEhIf8wMDD/TExM/1hYWP9eXl7/YWFh/2RkZP9oaGj/a2tr/25ubv9xcXH/dXV1/3p6 + ev99fX3/goKC/4WFhf+Kior/j4+P/5SUlP+ZmZn/np6e/6Ojo/+oqKj/ra2t/7Kysv+3t7f/u7u7/7+/ + v//Dw8P/xsbG/8jIyDH///8B////Af///wH///8B4eHh4+Dg4P/f39//3t7e/93d3f/c3Nz/29vb/9ra + 2v/Z2dn/19fX/9bW1v/U1NT/09PT/9LS0v/Q0ND/zs7O/8zMzP/Kysr/yMjI/8bGxv/Dw8P/wcHB/76+ + vv+8vLz/ubm5/7e3t/+0tLT/sbGx/66urv+rq6v/qKio/6SkpP+goKD/m5ub/5aWlv+RkZH/i4uL/4aG + hv+AgID/enp6/3R0dP9ubm7/aGho/2JiYv9dXV3/W1tb/1paWv9ISEj/QkJC/zo6Ov9KSkr/Z2dn/2xs + bP91dXX/iYmJ/6CgoP+Kior/U1NT/1hYWP9JSUn/PT09/1dXV//X19f//////93d3f9oaGj/Hh4e/yYm + Jv8qKir/Hx8f/x4eHv8hISH/JCQk/yUlJf8mJib/JiYm/yYmJv8mJib/JiYm/yUlJf8kJCT/IiIi/yAg + IP8fHx//Hx8f/x8fH/8fHx//Hh4e/x4eHv8eHh7/Hh4e/x4eHv8eHh7/Hh4e/x4eHv8mJib/Ozs7/1JS + Uv9dXV3/YGBg/2RkZP9nZ2f/ampq/21tbf9xcXH/dXV1/3h4eP99fX3/gYGB/4aGhv+Li4v/kZGR/5eX + l/+bm5v/oaGh/6ampv+srKz/sbGx/7a2tv+7u7v/v7+//8PDw//Gxsb/yMjIMf///wH///8B////Af// + /wHg4ODj4ODg/9/f3//d3d3/3d3d/9vb2//a2tr/2dnZ/9fX1//W1tb/1NTU/9PT0//S0tL/0NDQ/87O + zv/MzMz/ysrK/8jIyP/Gxsb/xMTE/8LCwv+/v7//vb29/7q6uv+2trb/tLS0/7Kysv+urq7/q6ur/6io + qP+lpaX/oaGh/5ycnP+Xl5f/kZGR/4yMjP+Ghob/gYGB/3t7e/90dHT/b29v/2lpaf9jY2P/Xl5e/1lZ + Wf9cXFz/YGBg/2BgYP9YWFj/PT09/0dHR/9oaGj/cnJy/4aGhv+cnJz/kZGR/1dXV/9NTU3/YWFh/1hY + WP9AQED/NTU1/4uLi//W1tb/cHBw/yEhIf8iIiL/Kioq/yEhIf8eHh7/ISEh/yQkJP8lJSX/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yUlJf8mJib/JCQk/yIiIv8gICD/Hx8f/x8fH/8fHx//Hh4e/x4e + Hv8eHh7/Hh4e/x4eHv8eHh7/Hh4e/x4eHv8gICD/Li4u/0pKSv9aWlr/YGBg/2JiYv9lZWX/aGho/2xs + bP9wcHD/dHR0/3l5ef99fX3/goKC/4iIiP+Ojo7/lJSU/5mZmf+fn5//paWl/6urq/+wsLD/tbW1/7q6 + uv++vr7/w8PD/8bGxv/IyMgx////Af///wH///8B////AeDg4OPf39//3t7e/93d3f/b29v/2tra/9nZ + 2f/X19f/1tbW/9TU1P/T09P/0tLS/9DQ0P/Ozs7/zMzM/8rKyv/IyMj/xsbG/8TExP/CwsL/v7+//729 + vf+6urr/t7e3/7S0tP+ysrL/rq6u/6urq/+oqKj/pKSk/6Ghof+dnZ3/mJiY/5KSkv+MjIz/h4eH/4GB + gf97e3v/b29v/1tbW/9dXV3/YmJi/19fX/9ZWVn/VlZW/15eXv9jY2P/ZWVl/1lZWf87Ozv/R0dH/29v + b/+EhIT/nJyc/5WVlf9QUFD/SkpK/3Jycv+CgoL/aWlp/1FRUf8jIyP/GRkZ/zY2Nv8jIyP/ISEh/yoq + Kv8hISH/HR0d/yIiIv8lJSX/JSUl/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JSUl/yQkJP8hISH/Hx8f/x8fH/8fHx//Hx8f/x8fH/8fHx//Hh4e/x4eHv8eHh7/Hh4e/x4e + Hv8eHh7/ISEh/zMzM/9PT0//W1tb/19fX/9jY2P/ZmZm/2pqav9ubm7/dHR0/3l5ef9/f3//hYWF/4uL + i/+SkpL/l5eX/52dnf+jo6P/qamp/7CwsP+0tLT/urq6/76+vv/Dw8P/xsbG/8jIyDH///8B////Af// + /wH///8B39/f497e3v/d3d3/3Nzc/9vb2//a2tr/2NjY/9fX1//V1dX/09PT/9LS0v/Q0ND/zs7O/8zM + zP/Kysr/yMjI/8fHx//ExMT/wsLC/8DAwP+9vb3/u7u7/7i4uP+1tbX/srKy/6+vr/+rq6v/qKio/6Wl + pf+hoaH/nZ2d/5mZmf+UlJT/jo6O/4iIiP+Dg4P/fHx8/3Nzc/9ZWVn/SkpK/0dHR/9OTk7/WFhY/1ZW + Vv9VVVX/YGBg/2RkZP9nZ2f/Wlpa/zo6Ov9KSkr/fX19/5mZmf+YmJj/YGBg/0ZGRv9oaGj/iYmJ/3t7 + e/+wsLD/hISE/x4eHv8RERH/IiIi/yYmJv8eHh7/IiIi/xwcHP8fHx//IyMj/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yUlJf8iIiL/ISEh/x8f + H/8fHx//Hx8f/x8fH/8fHx//Hx8f/x4eHv8eHh7/Hh4e/x4eHv8eHh7/Hh4e/ykpKf8/Pz//VVVV/11d + Xf9hYWH/ZWVl/2pqav9wcHD/dXV1/3x8fP+CgoL/iYmJ/5CQkP+VlZX/nJyc/6Kiov+pqan/r6+v/7Oz + s/+5ubn/vr6+/8PDw//Hx8f/yMjIMf///wH///8B////Af///wHe3t7j3t7e/9zc3P/b29v/2tra/9jY + 2P/X19f/1dXV/9TU1P/S0tL/0NDQ/8/Pz//MzMz/y8vL/8jIyP/Gxsb/xMTE/8LCwv/AwMD/vb29/7u7 + u/+4uLj/tbW1/7Ozs/+vr6//rKys/6ioqP+lpaX/oaGh/52dnf+ZmZn/lJSU/4+Pj/+JiYn/goKC/319 + ff92dnb/ZWVl/05OTv9ISEj/QEBA/0BAQP9QUFD/U1NT/1paWv9jY2P/Z2dn/2hoaP9VVVX/MDAw/09P + T/+Tk5P/mZmZ/2BgYP9FRUX/aGho/4mJif97e3v/r6+v//f39//q6ur/dHR0/xgYGP8fHx//GBgY/xYW + Fv8ZGRn/Hx8f/yQkJP8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yUlJf8kJCT/ISEh/x4eHv8fHx//Hx8f/x8fH/8fHx//Hx8f/x8f + H/8fHx//Hh4e/x4eHv8eHh7/Hh4e/x8fH/8tLS3/RkZG/1hYWP9gYGD/ZWVl/2xsbP9ycnL/eXl5/4CA + gP+Hh4f/jo6O/5SUlP+bm5v/oaGh/6enp/+tra3/s7Oz/7m5uf++vr7/w8PD/8fHx//IyMgx////Af// + /wH///8B////Ad7e3uPd3d3/3Nzc/9ra2v/Z2dn/19fX/9XV1f/U1NT/09PT/9HR0f/Pz8//zc3N/8vL + y//Jycn/x8fH/8XFxf/Dw8P/wMDA/76+vv+7u7v/uLi4/7a2tv+zs7P/sLCw/62trf+pqan/pqam/6Ki + ov+enp7/mZmZ/5WVlf+QkJD/ioqK/4SEhP99fX3/d3d3/3BwcP9hYWH/UFBQ/0dHR/89PT3/PT09/01N + Tf9UVFT/YGBg/2VlZf9oaGj/ampq/1FRUf8rKyv/SkpK/5CQkP9paWn/RUVF/15eXv+IiIj/f39//6mp + qf/z8/P/+vr6/62trf83Nzf/HR0d/yAgIP8YGBj/Ghoa/x8fH/8lJSX/Jycn/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JSUl/yUl + Jf8kJCT/IiIi/yEhIf8fHx//Hx8f/x8fH/8fHx//Hx8f/x8fH/8fHx//Hx8f/x8fH/8fHx//Hx8f/x8f + H/8kJCT/Nzc3/1RUVP9iYmL/ampq/3BwcP93d3f/fn5+/4WFhf+MjIz/kpKS/5mZmf+goKD/pqam/62t + rf+ysrL/uLi4/76+vv/Dw8P/x8fH/8jIyDH///8B////Af///wH///8B3d3d49zc3P/b29v/2dnZ/9jY + 2P/W1tb/1NTU/9PT0//R0dH/0NDQ/83Nzf/Ly8v/ycnJ/8fHx//FxcX/w8PD/8HBwf++vr7/u7u7/7m5 + uf+2trb/s7Oz/7CwsP+tra3/qqqq/6ampv+ioqL/np6e/5qamv+VlZX/kZGR/4uLi/+FhYX/f39//3d3 + d/9xcXH/a2tr/19fX/9TU1P/RkZG/zo6Ov86Ojr/SkpK/1xcXP9lZWX/Z2dn/2lpaf9sbGz/WVlZ/y8v + L/87Ozv/UlJS/0ZGRv9dXV3/g4OD/4KCgv+ZmZn/8fHx//z8/P+/v7//ODg4/xwcHP8oKCj/JCQk/xwc + HP8fHx//JSUl/ycnJ/8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JSUl/yUlJf8kJCT/IyMj/yEhIf8fHx//Hx8f/x8f + H/8fHx//Hx8f/x8fH/8fHx//Hx8f/x8fH/8fHx//Hx8f/x8fH/8gICD/LCws/0RERP9iYmL/bW1t/3V1 + df97e3v/fHx8/4ODg/+Pj4//mJiY/56env+lpaX/q6ur/7Gxsf+4uLj/vr6+/8PDw//Hx8f/yMjIMf// + /wH///8B////Af///wHc3Nzj29vb/9ra2v/Y2Nj/1tbW/9XV1f/U1NT/0dHR/9DQ0P/Ozs7/zMzM/8rK + yv/IyMj/xcXF/8PDw//AwMD/vr6+/7y8vP+5ubn/tra2/7S0tP+xsbH/ra2t/6qqqv+np6f/o6Oj/5+f + n/+bm5v/lpaW/5GRkf+MjIz/hoaG/4CAgP95eXn/cnJy/2xsbP9mZmb/Xl5e/1VVVf9FRUX/Nzc3/zg4 + OP9ISEj/YWFh/2dnZ/9paWn/bGxs/3Z2dv97e3v/QUFB/zY2Nv8wMDD/SkpK/4KCgv+Ghob/mJiY/+rq + 6v/8/Pz/xsbG/0tLS/8aGhr/JiYm/yYmJv8dHR3/ISEh/yYmJv8nJyf/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JSUl/yUlJf8kJCT/JCQk/yQkJP8hISH/Hx8f/x8fH/8fHx//Hx8f/x8fH/8fHx//Hx8f/x8f + H/8fHx//Hx8f/x8fH/8fHx//ICAg/zg4OP9XV1f/b29v/3Fxcf9dXV3/Y2Nj/3l5ef+RkZH/nZ2d/6Oj + o/+qqqr/sbGx/7i4uP+9vb3/w8PD/8fHx//IyMgx////Af///wH///8B////Adzc3OPa2tr/2dnZ/9fX + 1//V1dX/1NTU/9LS0v/Q0ND/zs7O/8zMzP/Kysr/yMjI/8bGxv/ExMT/wcHB/7+/v/+8vLz/ubm5/7e3 + t/+0tLT/sbGx/66urv+rq6v/qKio/6SkpP+goKD/nJyc/5iYmP+Tk5P/jY2N/4iIiP+BgYH/e3t7/3R0 + dP9ubm7/aGho/2NjY/9dXV3/WFhY/0RERP81NTX/NTU1/0VFRf9iYmL/aWlp/2tra/90dHT/i4uL/5mZ + mf9cXFz/ODg4/y8vL/88PDz/dHR0/4eHh//q6ur//v7+/9jY2P9WVlb/Gxsb/yUlJf8pKSn/Hh4e/x8f + H/8kJCT/Jycn/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JSUl/yUlJf8lJSX/JSUl/yMj + I/8hISH/Hx8f/x8fH/8fHx//Hx8f/x8fH/8fHx//Hx8f/x8fH/8fHx//Hx8f/x8fH/8fHx//ISEh/ykp + Kf9ISEj/VVVV/01NTf9fX1//ZWVl/4ODg/+cnJz/o6Oj/6qqqv+wsLD/uLi4/76+vv/Dw8P/x8fH/8jI + yDH///8B////Af///wH///8B2tra49nZ2f/X19f/1tbW/9TU1P/S0tL/0dHR/8/Pz//Nzc3/y8vL/8nJ + yf/Hx8f/xMTE/8LCwv+/v7//vLy8/7q6uv+3t7f/tbW1/7Gxsf+urq7/q6ur/6enp/+lpaX/oKCg/5yc + nP+Xl5f/kpKS/42Njf+IiIj/goKC/3x8fP92dnb/b29v/2lpaf9kZGT/X19f/1xcXP9bW1v/VFRU/09P + T/88PDz/QEBA/2RkZP9ra2v/dHR0/4yMjP+fn5//g4OD/0xMTP8+Pj7/NjY2/ysrK/89PT3/tra2//z8 + /P/c3Nz/UVFR/xkZGf8lJSX/KCgo/x4eHv8fHx//IyMj/yUlJf8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yUlJf8lJSX/JSUl/yQkJP8iIiL/ISEh/yAgIP8fHx//Hh4e/x8f + H/8gICD/ICAg/yAgIP8gICD/ICAg/yAgIP8gICD/ICAg/yAgIP8oKCj/Ojo6/2BgYP9oaGj/f39//5ub + m/+jo6P/q6ur/7Gxsf+5ubn/vr6+/8TExP/Hx8f/yMjIMf///wH///8B////Af///wHa2trj2NjY/9bW + 1v/V1dX/09PT/9HR0f/Pz8//zs7O/8vLy//Jycn/x8fH/8XFxf/Dw8P/wMDA/729vf+6urr/uLi4/7W1 + tf+ysrL/r6+v/6urq/+oqKj/paWl/6Ghof+dnZ3/mZmZ/5OTk/+Ojo7/iYmJ/4ODg/99fX3/c3Nz/2tr + a/9qamr/ZWVl/2BgYP9cXFz/W1tb/15eXv9hYWH/YWFh/zs7O/8zMzP/ZGRk/3Fxcf+Ghob/n5+f/5GR + kf9NTU3/SkpK/2BgYP9DQ0P/NDQ0/ykpKf9LS0v/n5+f/2pqav8cHBz/IiIi/ykpKf8fHx//Gxsb/yEh + If8kJCT/JSUl/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/IyMj/yAgIP8eHh7/Hh4e/yAgIP8gICD/ICAg/yAgIP8gICD/ICAg/yAg + IP8gICD/ICAg/yAgIP8kJCT/Pj4+/2JiYv+BgYH/nJyc/6Ojo/+rq6v/srKy/7m5uf+/v7//xMTE/8fH + x//IyMgx////Af///wH///8B////AdjY2OPX19f/1dXV/9PT0//S0tL/0NDQ/87Ozv/MzMz/ysrK/8jI + yP/Gxsb/w8PD/8HBwf++vr7/u7u7/7i4uP+2trb/srKy/6+vr/+srKz/qKio/6Wlpf+hoaH/np6e/5mZ + mf+UlJT/jo6O/4mJif+EhIT/fX19/3Nzc/9WVlb/TU1N/1ZWVv9fX1//XFxc/1hYWP9bW1v/YWFh/2Rk + ZP9iYmL/OTk5/zIyMv9sbGz/hISE/5ycnP+QkJD/U1NT/0pKSv9ubm7/hoaG/21tbf9SUlL/GRkZ/xIS + Ev8gICD/IyMj/yEhIf8pKSn/IiIi/x8fH/8gICD/IyMj/yUlJf8lJSX/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8lJSX/IyMj/yEh + If8fHx//ICAg/yAgIP8gICD/ICAg/yAgIP8gICD/ICAg/yAgIP8gICD/ICAg/yAgIP8iIiL/R0dH/4KC + gv+cnJz/pKSk/6ysrP+ysrL/urq6/8DAwP/FxcX/yMjI/8jIyDH///8B////Af///wH///8B19fX49bW + 1v/U1NT/0tLS/9DQ0P/Pz8//zc3N/8vLy//IyMj/xsbG/8PDw//CwsL/v7+//7y8vP+5ubn/tra2/7Oz + s/+wsLD/ra2t/6mpqf+mpqb/oqKi/56env+ZmZn/lJSU/5CQkP+Kior/hISE/35+fv91dXX/XFxc/0tL + S/9ERET/QEBA/09PT/9ZWVn/WFhY/15eXv9jY2P/ZWVl/2JiYv8zMzP/MDAw/319ff+ampr/kpKS/1dX + V/9GRkb/a2tr/4uLi/9+fn7/vb29/8rKyv9NTU3/FRUV/xwcHP8dHR3/GBgY/x0dHf8dHR3/ISEh/yMj + I/8kJCT/JSUl/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yUlJf8lJSX/JSUl/yMjI/8iIiL/ISEh/yAgIP8gICD/ICAg/yAg + IP8gICD/ICAg/yAgIP8gICD/ICAg/yEhIf9ERET/hYWF/52dnf+lpaX/rKys/7Ozs/+7u7v/wcHB/8XF + xf/IyMj/ycnJMf///wH///8B////Af///wHW1tbj1dXV/9TU1P/R0dH/z8/P/83Nzf/Ly8v/ycnJ/8fH + x//FxcX/wsLC/7+/v/+8vLz/urq6/7e3t/+0tLT/sbGx/62trf+qqqr/pqam/6Kiov+enp7/mpqa/5aW + lv+QkJD/i4uL/4WFhf9+fn7/eXl5/25ubv9UVFT/TExM/0BAQP88PDz/SUlJ/1ZWVv9bW1v/YmJi/2Vl + Zf9nZ2f/YmJi/ywsLP8sLCz/ioqK/5ycnP9eXl7/RERE/2NjY/+IiIj/enp6/7S0tP/4+Pj/8fHx/39/ + f/8gICD/GRkZ/xUVFf8VFRX/Ghoa/yAgIP8jIyP/JCQk/yUlJf8lJSX/JSUl/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8lJSX/JSUl/yQkJP8jIyP/ISEh/yAgIP8gICD/ICAg/yAgIP8hISH/ISEh/yEhIf8hISH/ISEh/0BA + QP+FhYX/np6e/6enp/+vr6//tra2/76+vv/CwsL/xsbG/8nJyf/Kysox////Af///wH///8B////AdbW + 1uPU1NT/0tLS/9DQ0P/Ozs7/zMzM/8rKyv/Hx8f/xcXF/8PDw//AwMD/vb29/7q6uv+3t7f/tLS0/7Gx + sf+urq7/qqqq/6enp/+jo6P/n5+f/5ubm/+VlZX/kZGR/4uLi/+FhYX/f39//3l5ef90dHT/aWlp/1VV + Vf9NTU3/PT09/zg4OP9GRkb/VVVV/2FhYf9lZWX/aGho/2lpaf9mZmb/LS0t/yUlJf9oaGj/ZmZm/0RE + RP9iYmL/hoaG/319ff+pqan/+vr6//f39/+cnJz/Jycn/xwcHP8kJCT/Ghoa/xsbG/8gICD/IyMj/yQk + JP8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JSUl/yUlJf8kJCT/IiIi/yAg + IP8fHx//Hx8f/yAgIP8hISH/ISEh/yEhIf8hISH/Nzc3/319ff+Xl5f/pqam/7Ozs/+6urr/wMDA/8TE + xP/Hx8f/ysrK/8vLyzH///8B////Af///wH///8B1dXV49PT0//R0dH/z8/P/8zMzP/Kysr/yMjI/8bG + xv/Dw8P/wcHB/76+vv+8vLz/uLi4/7W1tf+ysrL/r6+v/6ysrP+oqKj/pKSk/6CgoP+bm5v/l5eX/5KS + kv+NjY3/hoaG/4GBgf96enr/dXV1/3BwcP9nZ2f/V1dX/05OTv85OTn/NTU1/0NDQ/9XV1f/ZWVl/2dn + Z/9paWn/bGxs/29vb/8zMzP/JSUl/zQ0NP9AQED/Wlpa/4ODg/98fHz/nZ2d/+/v7//7+/v/t7e3/zc3 + N/8cHBz/KCgo/yUlJf8eHh7/ICAg/yMjI/8kJCT/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8kJCT/IiIi/yAgIP8fHx//ICAg/yEhIf8hISH/ISEh/yEh + If8vLy//enp6/42Njf+cnJz/tra2/729vf/BwcH/xMTE/8fHx//Kysr/y8vLMf///wH///8B////Af// + /wHU1NTj0tLS/9DQ0P/Nzc3/y8vL/8nJyf/Gxsb/xMTE/8HBwf+/v7//vLy8/7m5uf+1tbX/srKy/6+v + r/+srKz/qKio/6Wlpf+goKD/m5ub/5aWlv+SkpL/jY2N/4iIiP+BgYH/e3t7/3Z2dv9wcHD/a2tr/2Rk + ZP9ZWVn/UFBQ/zc3N/8yMjL/QUFB/1paWv9oaGj/aWlp/21tbf94eHj/jo6O/11dXf8oKCj/Jycn/zg4 + OP93d3f/gICA/5qamv/19fX//v7+/7m5uf86Ojr/Ghoa/ygoKP8mJib/HR0d/yAgIP8jIyP/JCQk/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yUl + Jf8kJCT/IyMj/yMjI/8hISH/ICAg/x8fH/8gICD/ISEh/ysrK/95eXn/jY2N/5ubm/+6urr/v7+//8PD + w//Gxsb/ycnJ/8zMzP/MzMwx////Af///wH///8B////AdPT0+PR0dH/z8/P/8zMzP/Kysr/x8fH/8XF + xf/Dw8P/wMDA/729vf+6urr/tra2/7Ozs/+wsLD/ra2t/6mpqf+mpqb/oaGh/52dnf+Xl5f/k5OT/46O + jv+JiYn/hISE/319ff93d3f/cnJy/2xsbP9nZ2f/YWFh/1tbW/9RUVH/Pj4+/zc3N/89PT3/W1tb/2lp + af9ra2v/d3d3/42Njf+goKD/bGxs/y4uLv8mJib/KSkp/01NTf+Li4v/5ubm//7+/v/a2tr/RUVF/xoa + Gv8lJSX/KCgo/x8fH/8fHx//IiIi/yQkJP8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yUlJf8lJSX/JiYm/yUlJf8hISH/Hh4e/x8f + H/8hISH/LCws/3p6ev+Ojo7/nZ2d/729vf/BwcH/xMTE/8bGxv/Jycn/zMzM/83NzTH///8B////Af// + /wH///8B0tLS49DQ0P/Ozs7/y8vL/8nJyf/Gxsb/xMTE/8HBwf++vr7/u7u7/7i4uP+0tLT/sbGx/62t + rf+qqqr/pqam/6Kiov+dnZ3/mZmZ/5SUlP+Pj4//ioqK/4WFhf9/f3//dnZ2/3Jycv9tbW3/aGho/2Rk + ZP9eXl7/XV1d/15eXv9eXl7/R0dH/zQ0NP9WVlb/bGxs/3R0dP+NjY3/oKCg/4CAgP9GRkb/Pj4+/ysr + K/8mJib/LCws/3Fxcf/b29v/0dHR/1hYWP8bGxv/JCQk/ykpKf8hISH/Hx8f/yMjI/8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yQkJP8iIiL/Hx8f/x8fH/8pKSn/d3d3/5CQkP+dnZ3/vr6+/8LC + wv/FxcX/yMjI/8vLy//Nzc3/zs7OMf///wH///8B////Af///wHR0dHjz8/P/8zMzP/Kysr/yMjI/8bG + xv/Dw8P/v7+//7y8vP+5ubn/tra2/7Kysv+vr6//q6ur/6enp/+jo6P/n5+f/5mZmf+VlZX/kJCQ/4qK + iv+FhYX/gICA/3Nzc/9cXFz/YmJi/2dnZ/9kZGT/YGBg/1xcXP9fX1//YmJi/2VlZf9ISEj/Kysr/1JS + Uv9zc3P/h4eH/56env+FhYX/S0tL/0xMTP9wcHD/VVVV/yoqKv8gICD/Ghoa/09PT/9nZ2f/ISEh/yMj + I/8oKCj/ICAg/yEhIf8kJCT/Jycn/yYmJv8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8kJCT/IiIi/y0tLf97e3v/kZGR/56env+/v7//xMTE/8fHx//Jycn/zMzM/87Ozv/Pz88x////Af// + /wH///8B////Ac/Pz+POzs7/y8vL/8nJyf/Gxsb/xMTE/8HBwf++vr7/urq6/7e3t/+0tLT/sLCw/6ys + rP+oqKj/pKSk/6CgoP+cnJz/lpaW/5GRkf+MjIz/hoaG/4GBgf91dXX/W1tb/0tLS/9KSkr/UlJS/15e + Xv9cXFz/XFxc/2FhYf9lZWX/Z2dn/0VFRf8pKSn/VlZW/4aGhv+dnZ3/kJCQ/1BQUP9GRkb/bm5u/4iI + iP91dXX/dHR0/yAgIP8LCwv/KSkp/2tra/8pKSn/JSUl/yAgIP8fHx//JCQk/ycnJ/8mJib/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yUlJf8rKyv/WVlZ/42Njf+SkpL/np6e/8DA + wP/FxcX/yMjI/8vLy//Nzc3/z8/P/9DQ0DH///8B////Af///wH///8Bzs7O48zMzP/Kysr/x8fH/8XF + xf/CwsL/v7+//7u7u/+4uLj/tbW1/7Gxsf+urq7/qamp/6Wlpf+hoaH/nJyc/5iYmP+RkZH/jY2N/4aG + hv+AgID/enp6/2RkZP9PT0//SEhI/0NDQ/9ERET/V1dX/1lZWf9gYGD/ZWVl/2dnZ/9paWn/QUFB/yYm + Jv9jY2P/np6e/5OTk/9TU1P/RUVF/2tra/+IiIj/dnZ2/87Ozv/4+Pj/nJyc/x8fH/8eHh7/IiIi/xMT + E/8YGBj/Hh4e/yMjI/8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8lJSX/JiYm/0lJSf+EhIT/k5OT/5OTk/+kpKT/w8PD/8bGxv/Kysr/y8vL/87Ozv/Q0ND/0dHRMf// + /wH///8B////Af///wHNzc3jy8vL/8nJyf/Gxsb/xMTE/8DAwP+9vb3/urq6/7a2tv+zs7P/rq6u/6ur + q/+np6f/oqKi/56env+ZmZn/lJSU/42Njf+IiIj/gICA/3p6ev90dHT/YGBg/1FRUf9GRkb/Pz8//0JC + Qv9VVVX/Wlpa/2RkZP9mZmb/aWlp/2tra/89PT3/Hx8f/1tbW/+ampr/Xl5e/0JCQv9jY2P/hoaG/3p6 + ev+zs7P//Pz8//b29v+NjY3/Hx8f/x0dHf8VFRX/FBQU/x0dHf8gICD/IyMj/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JSUl/yQkJP8kJCT/Hx8f/zg4OP9+fn7/mZmZ/7W1 + tf/Gxsb/yMjI/8vLy//Nzc3/z8/P/9HR0f/S0tIx////Af///wH///8B////AczMzOPKysr/yMjI/8XF + xf/CwsL/vr6+/7u7u/+3t7f/s7Oz/7CwsP+srKz/qKio/6Ojo/+enp7/mZmZ/5SUlP+Pj4//iIiI/4KC + gv96enr/dHR0/25ubv9dXV3/VVVV/0RERP88PDz/Pj4+/1RUVP9gYGD/Z2dn/2lpaf9ra2v/bm5u/0FB + Qf8eHh7/MzMz/1VVVf9BQUH/Y2Nj/4WFhf95eXn/s7Oz//f39//z8/P/lJSU/yIiIv8cHBz/Jycn/x4e + Hv8bGxv/ICAg/yEhIf8kJCT/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yUl + Jf8jIyP/ISEh/w8PD/8CAgL/JSUl/4mJif+xsbH/w8PD/8fHx//Jycn/y8vL/83Nzf/Q0ND/0tLS/9LS + 0jH///8B////Af///wH///8BzMzM48nJyf/Gxsb/w8PD/8DAwP+8vLz/ubm5/7W1tf+xsbH/ra2t/6mp + qf+lpaX/oKCg/5ubm/+VlZX/kJCQ/4qKiv+Dg4P/fX19/3Z2dv9wcHD/a2tr/15eXv9YWFj/Q0ND/zg4 + OP88PDz/VFRU/2RkZP9paWn/a2tr/25ubv97e3v/Xl5e/x8fH/8hISH/NjY2/1hYWP+Dg4P/fHx8/6Gh + of/19fX//v7+/6enp/8wMDD/Ghoa/yYmJv8jIyP/Gxsb/x0dHf8hISH/IyMj/yQkJP8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8lJSX/JCQk/yMjI/8RERH/AwMD/yUlJf9vb2//r6+v/8HB + wf/FxcX/x8fH/8rKyv/MzMz/zs7O/9DQ0P/S0tL/09PTMf///wH///8B////Af///wHLy8vjyMjI/8bG + xv/CwsL/v7+//7u7u/+3t7f/s7Oz/66urv+qqqr/pqam/6Kiov+cnJz/lpaW/5GRkf+Li4v/hYWF/35+ + fv94eHj/cnJy/21tbf9paWn/X19f/1tbW/9CQkL/Nzc3/zk5Of9TU1P/ZmZm/2tra/9ubm7/e3t7/5OT + k/+Hh4f/LCws/x8fH/8wMDD/YWFh/4GBgf+cnJz/7e3t//r6+v++vr7/MTEx/xoaGv8mJib/JSUl/x4e + Hv8fHx//ISEh/yQkJP8kJCT/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8kJCT/JCQk/yQkJP8kJCT/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JSUl/yQk + JP8nJyf/FxcX/wMDA/8eHh7/e3t7/6Ghof+/v7//xMTE/8bGxv/IyMj/ysrK/83Nzf/Pz8//0dHR/9PT + 0//U1NQx////Af///wH///8B////AcrKyuPHx8f/xMTE/8DAwP+9vb3/ubm5/7W1tf+xsbH/rKys/6io + qP+ioqL/np6e/5iYmP+SkpL/jIyM/4aGhv+AgID/eHh4/3Nzc/9ubm7/ampq/2VlZf9fX1//Xl5e/1BQ + UP9JSUn/Nzc3/1BQUP9oaGj/bW1t/3h4eP+SkpL/oKCg/3R0dP8xMTH/Hx8f/yIiIv8zMzP/bGxs/+Xl + 5f/8/Pz/vLy8/0FBQf8ZGRn/JSUl/yQkJP8fHx//ICAg/yIiIv8kJCT/JCQk/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8lJSX/IyMj/xcXF/8DAwP/Hh4e/29vb/+kpKT/vb29/8LC + wv/ExMT/x8fH/8nJyf/Ly8v/zs7O/9DQ0P/S0tL/1NTU/9XV1TH///8B////Af///wH///8ByMjI48bG + xv/Dw8P/v7+//7y8vP+3t7f/s7Oz/6+vr/+qqqr/pqam/6CgoP+bm5v/lJSU/46Ojv+IiIj/goKC/3V1 + df9ubm7/b29v/2xsbP9nZ2f/YmJi/19fX/9hYWH/Y2Nj/1lZWf8yMjL/Q0ND/2hoaP92dnb/jIyM/5+f + n/+AgID/RkZG/0RERP84ODj/HR0d/yEhIf83Nzf/kJCQ/8XFxf9MTEz/GRkZ/yQkJP8lJSX/HR0d/x8f + H/8iIiL/JCQk/yQkJP8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8lJSX/JSUl/ycn + J/8XFxf/BAQE/xEREf9mZmb/np6e/7u7u//CwsL/xMTE/8bGxv/IyMj/y8vL/83Nzf/Pz8//0dHR/9PT + 0//V1dX/1tbWMf///wH///8B////Af///wHIyMjjxMTE/8HBwf+9vb3/urq6/7W1tf+xsbH/rKys/6en + p/+ioqL/m5ub/5aWlv+QkJD/ioqK/4ODg/90dHT/WFhY/09PT/9ZWVn/ZGRk/2RkZP9hYWH/YWFh/2Rk + ZP9nZ2f/W1tb/y4uLv88PDz/b29v/42Njf+hoaH/g4OD/0ZGRv9MTEz/dnZ2/3t7e/9BQUH/ISEh/w8P + D/8UFBT/QEBA/yEhIf8gICD/JiYm/x0dHf8fHx//IiIi/yQkJP8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yUlJf8uLi7/QUFB/y0tLf8hISH/aWlp/6SkpP+7u7v/wcHB/8PD + w//FxcX/x8fH/8rKyv/MzMz/zs7O/9DQ0P/S0tL/1NTU/9bW1v/X19cx////Af///wH///8B////AcbG + xuPExMT/wMDA/729vf+4uLj/s7Oz/6+vr/+pqan/pKSk/5+fn/+ZmZn/kpKS/4uLi/+FhYX/fHx8/2Fh + Yf9PT0//SEhI/0ZGRv9WVlb/YmJi/2BgYP9kZGT/ZmZm/2lpaf9aWlr/Kioq/0NDQ/+CgoL/oKCg/5GR + kf9KSkr/RkZG/29vb/+Ghob/e3t7/8DAwP95eXn/ExMT/xQUFP84ODj/ISEh/xwcHP8eHh7/Hh4e/yIi + Iv8kJCT/JSUl/yUlJf8lJSX/JSUl/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8lJSX/Kioq/0RE + RP9WVlb/e3t7/4KCgv+vr6//u7u7/8DAwP/CwsL/xMTE/8bGxv/IyMj/y8vL/83Nzf/Pz8//0dHR/9PT + 0//V1dX/19fX/9jY2DH///8B////Af///wH///8BxsbG48PDw/+/v7//u7u7/7e3t/+xsbH/rKys/6am + pv+hoaH/nJyc/5WVlf+Ojo7/hoaG/4CAgP92dnb/WVlZ/1FRUf9FRUX/QkJC/1JSUv9gYGD/YmJi/2dn + Z/9paWn/a2tr/1ZWVv8lJSX/RkZG/5WVlf+RkZH/UlJS/0ZGRv9qamr/hYWF/319ff/Kysr//f39/9/f + 3/9CQkL/HBwc/xsbG/8SEhL/FhYW/xwcHP8iIiL/JSUl/yUlJf8lJSX/JSUl/yQkJP8kJCT/JCQk/yQk + JP8jIyP/IyMj/yQkJP8nJyf/Kysr/zAwMP80NDT/NDQ0/zIyMv8uLi7/KSkp/yYmJv8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JSUl/yUlJf8qKir/PT09/1JSUv+IiIj/np6e/7u7u/+/v7//wcHB/8PD + w//FxcX/yMjI/8rKyv/MzMz/zs7O/9DQ0P/S0tL/1NTU/9bW1v/Y2Nj/2dnZMf///wH///8B////Af// + /wHFxcXjwsLC/729vf+5ubn/tbW1/6+vr/+qqqr/pKSk/5+fn/+ZmZn/kZGR/4qKiv+CgoL/e3t7/3Nz + c/9bW1v/U1NT/0FBQf8/Pz//UVFR/2BgYP9mZmb/aWlp/2tra/9tbW3/WFhY/yMjI/81NTX/f39//1ZW + Vv9BQUH/ZmZm/4aGhv96enr/u7u7//n5+f/s7Oz/gICA/xwcHP8fHx//Gxsb/xQUFP8aGhr/ISEh/yYm + Jv8lJSX/JCQk/yQkJP8kJCT/JCQk/yMjI/8jIyP/IyMj/ygoKP85OTn/WVlZ/3Fxcf+EhIT/lZWV/52d + nf+dnZ3/mJiY/46Ojv9+fn7/ampq/09PT/85OTn/JiYm/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yUlJf8jIyP/Hh4e/wsL + C/8UFBT/WVlZ/5aWlv+zs7P/vr6+/8DAwP/Dw8P/xcXF/8fHx//Jycn/y8vL/83Nzf/Pz8//0dHR/9PT + 0//V1dX/19fX/9nZ2f/a2tox////Af///wH///8B////AcTExOPBwcH/vb29/7i4uP+0tLT/rq6u/6io + qP+ioqL/nJyc/5aWlv+Ojo7/hoaG/319ff93d3f/b29v/1xcXP9UVFT/PT09/zs7O/9PT0//Y2Nj/2lp + af9sbGz/bm5u/3Jycv9kZGT/JCQk/yEhIf86Ojr/QEBA/11dXf+FhYX/fn5+/7CwsP/5+fn/9vb2/4eH + h/8kJCT/HBwc/yYmJv8hISH/HR0d/yEhIf8mJib/JiYm/yUlJf8kJCT/IyMj/yMjI/8jIyP/JiYm/zIy + Mv9fX1//jY2N/6ysrP++vr7/xcXF/8nJyf/Ly8v/y8vL/8vLy//Ly8v/y8vL/8nJyf/FxcX/vb29/6ur + q/99fX3/VFRU/zExMf8mJib/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yUlJf8lJSX/IyMj/yMjI/8LCwv/BgYG/0FBQf+Li4v/srKy/729vf/AwMD/wsLC/8TE + xP/Gxsb/yMjI/8vLy//Nzc3/zs7O/9DQ0P/S0tL/1dXV/9bW1v/Y2Nj/2tra/9ra2jH///8B////Af// + /wH///8BxMTE48DAwP+8vLz/t7e3/7Kysv+srKz/p6en/6Ghof+ampr/k5OT/4uLi/+Dg4P/enp6/3R0 + dP9tbW3/X19f/1VVVf86Ojr/ODg4/09PT/9lZWX/bGxs/25ubv9ycnL/goKC/4eHh/8yMjL/Hh4e/ysr + K/9OTk7/gICA/39/f/+qqqr/9vb2//Pz8/+ampr/Hh4e/xoaGv8lJSX/IiIi/x4eHv8iIiL/JiYm/yYm + Jv8lJSX/JCQk/yMjI/8jIyP/IyMj/zAwMP9nZ2f/o6Oj/8XFxf/Ly8v/y8vL/8vLy//Ly8v/y8vL/8vL + y//Ly8v/zMzM/8zMzP/MzMz/zc3N/83Nzf/Nzc3/zc3N/83Nzf/FxcX/m5ub/11dXf8uLi7/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yYmJv8mJib/JiYm/yYmJv8mJib/JSUl/yYmJv8jIyP/CwsL/wYG + Bv85OTn/kJCQ/7Kysv+9vb3/wMDA/8LCwv/ExMT/xsbG/8jIyP/Kysr/zMzM/87Ozv/Q0ND/0tLS/9TU + 1P/V1dX/19fX/9nZ2f/a2tr/29vbMf///wH///8B////Af///wHExMTjwMDA/7u7u/+2trb/sbGx/6ur + q/+mpqb/oKCg/5mZmf+SkpL/iYmJ/4GBgf95eXn/dHR0/25ubv9iYmL/VlZW/0JCQv88PDz/T09P/2dn + Z/9vb2//cXFx/319ff+Xl5f/oaGh/0tLS/8dHR3/IyMj/0BAQP9lZWX/nJyc//Dw8P/6+vr/rKys/zMz + M/8YGBj/JSUl/yEhIf8cHBz/ISEh/yYmJv8mJib/JSUl/yQkJP8jIyP/IyMj/yMjI/9AQED/jY2N/8DA + wP/MzMz/zMzM/8vLy//Ly8v/y8vL/8vLy//Ly8v/y8vL/8vLy//MzMz/zMzM/8zMzP/MzMz/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Ly8v/vLy8/4GBgf89PT3/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8mJib/JiYm/yUlJf8kJCT/Kysr/xISEv8CAgL/Ly8v/4WFhf+tra3/vLy8/7+/v//BwcH/w8PD/8bG + xv/Hx8f/ysrK/8vLy//Nzc3/z8/P/9HR0f/T09P/1dXV/9fX1//Y2Nj/2tra/9vb2//c3Nwx////Af// + /wH///8B////AcPDw+O/v7//u7u7/7W1tf+wsLD/qqqq/6Wlpf+enp7/l5eX/4yMjP+Hh4f/gYGB/3l5 + ef91dXX/b29v/2ZmZv9nZ2f/Z2dn/0lJSf9BQUH/ZWVl/3Jycv9/f3//lZWV/6Kiov91dXX/Ozs7/yws + LP8dHR3/JSUl/zg4OP+rq6v/7+/v/66urv8uLi7/GBgY/yUlJf8jIyP/HBwc/yAgIP8lJSX/JiYm/yUl + Jf8kJCT/IyMj/yMjI/8qKir/XV1d/7W1tf/Nzc3/zc3N/83Nzf/MzMz/zMzM/8vLy//Ly8v/y8vL/8vL + y//Ly8v/y8vL/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/Ly8v/ysrK/7Cw + sP9nZ2f/KSkp/yMjI/8jIyP/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/ycnJ/8PDw//AQEB/zIy + Mv+Hh4f/rKys/729vf+/v7//wcHB/8PDw//FxcX/x8fH/8nJyf/Ly8v/zMzM/8/Pz//Q0ND/0tLS/9TU + 1P/W1tb/19fX/9nZ2f/b29v/3Nzc/93d3TH///8B////Af///wH///8Bw8PD48DAwP+7u7v/tbW1/7Cw + sP+pqan/pKSk/52dnf+Li4v/bW1t/3Nzc/99fX3/e3t7/3h4eP9xcXH/aGho/2pqav9paWn/RUVF/zU1 + Nf9gYGD/e3t7/5OTk/+jo6P/fn5+/0VFRf9MTEz/ZGRk/zY2Nv8aGhr/HBwc/y4uLv9ycnL/Q0ND/xYW + Fv8iIiL/IyMj/xwcHP8fHx//IyMj/yUlJf8lJSX/JCQk/yQkJP8jIyP/KCgo/2lpaf+1tbX/zMzM/8zM + zP/Nzc3/zMzM/8zMzP/MzMz/zMzM/8vLy//Ly8v/y8vL/8vLy//Ly8v/zMzM/8zMzP/MzMz/zMzM/8zM + zP/MzMz/zMzM/8zMzP/Ly8v/y8vL/8vLy//Kysr/ysrK/7u7u/9mZmb/Kioq/yMjI/8jIyP/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yQkJP8pKSn/FxcX/wEBAf8dHR3/fX19/6ioqP+6urr/vr6+/8DAwP/Dw8P/xcXF/8bG + xv/Jycn/y8vL/8zMzP/Ozs7/0NDQ/9LS0v/T09P/1dXV/9fX1//Y2Nj/2tra/9vb2//d3d3/3d3dMf// + /wH///8B////Af///wHDw8Pjv7+//7q6uv+0tLT/r6+v/6mpqf+jo6P/lJSU/21tbf9aWlr/VVVV/19f + X/94eHj/eXl5/3Jycv9sbGz/bm5u/2xsbP9ERET/MzMz/2pqav+Pj4//oqKi/4aGhv9BQUH/SUlJ/3R0 + dP+BgYH/b29v/1BQUP8VFRX/DQ0N/zs7O/9DQ0P/HR0d/yQkJP8bGxv/HR0d/yIiIv8kJCT/JCQk/yQk + JP8kJCT/IyMj/yUlJf9kZGT/u7u7/8rKyv/Ly8v/y8vL/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zM + zP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/Ly8v/y8vL/8vLy//Kysr/ysrK/8rK + yv/Kysr/ycnJ/7W1tf9dXV3/JSUl/yMjI/8jIyP/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yQkJP8lJSX/MzMz/0tLS/9TU1P/SUlJ/4GB + gf+rq6v/urq6/76+vv/AwMD/wsLC/8TExP/Gxsb/yMjI/8rKyv/MzMz/zs7O/8/Pz//R0dH/09PT/9XV + 1f/W1tb/19fX/9nZ2f/a2tr/3Nzc/93d3f/e3t4x////Af///wH///8B////AcPDw+O/v7//urq6/7W1 + tf+vr6//qamp/6Ojo/+Hh4f/Y2Nj/1dXV/9NTU3/UlJS/3h4eP96enr/cXFx/3BwcP9xcXH/bm5u/z8/ + P/8xMTH/eXl5/6Ghof+Hh4f/SkpK/0ZGRv9ubm7/g4OD/4KCgv/R0dH/3d3d/2hoaP8SEhL/IyMj/x0d + Hf8UFBT/GBgY/xwcHP8gICD/IiIi/yQkJP8kJCT/JCQk/yQkJP8jIyP/Q0ND/6+vr//Kysr/ysrK/8vL + y//Ly8v/y8vL/8zMzP/MzMz/zMzM/8zMzP/Nzc3/zc3N/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zM + zP/MzMz/y8vL/8vLy//Ly8v/y8vL/8rKyv/Kysr/ysrK/8rKyv/Kysr/ycnJ/7Gxsf9DQ0P/IyMj/yMj + I/8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/y0tLf9ERET/U1NT/3Nzc/+Kior/rq6u/7u7u/+9vb3/v7+//8LCwv/ExMT/xsbG/8jI + yP/Kysr/y8vL/83Nzf/Pz8//0dHR/9LS0v/U1NT/1dXV/9fX1//Y2Nj/2tra/9vb2//d3d3/3t7e/9/f + 3zH///8B////Af///wH///8BxMTE48DAwP+7u7v/tra2/7CwsP+pqan/o6Oj/4WFhf9nZ2f/VVVV/0hI + SP9PT0//enp6/3l5ef9zc3P/c3Nz/3R0dP9ubm7/Ozs7/ywsLP95eXn/k5OT/01NTf9CQkL/bGxs/4eH + h/97e3v/ycnJ//v7+//d3d3/X19f/xcXF/8YGBj/EhIS/xYWFv8bGxv/ICAg/yIiIv8jIyP/JCQk/yQk + JP8kJCT/JCQk/zAwMP+Hh4f/yMjI/8vLy//Ly8v/y8vL/8vLy//Ly8v/zMzM/8zMzP/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zMzM/8zMzP/MzMz/zMzM/8zMzP/Ly8v/y8vL/8vLy//Ly8v/ysrK/8rK + yv/Kysr/ysrK/8rKyv/Kysr/ycnJ/4qKiv8uLi7/IyMj/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yUlJf8lJSX/JSUl/yUlJf8lJSX/JCQk/yMjI/8mJib/HR0d/x8fH/9FRUX/enp6/56e + nv+3t7f/vb29/7+/v//BwcH/w8PD/8XFxf/Hx8f/ycnJ/8vLy//Nzc3/zs7O/9DQ0P/S0tL/1NTU/9XV + 1f/W1tb/2NjY/9nZ2f/b29v/3Nzc/93d3f/f39//39/fMf///wH///8B////Af///wHExMTjwcHB/7y8 + vP+2trb/sbGx/6mpqf+jo6P/iIiI/2tra/9TU1P/RERE/0xMTP95eXn/d3d3/3V1df92dnb/d3d3/3Nz + c/8+Pj7/JCQk/0xMTP9RUVH/QUFB/2VlZf+Hh4f/eXl5/8fHx//+/v7/6Ojo/2RkZP8aGhr/Hh4e/yQk + JP8bGxv/HBwc/yEhIf8jIyP/IyMj/yQkJP8kJCT/JCQk/yQkJP8kJCT/XFxc/76+vv/MzMz/zMzM/8zM + zP/MzMz/zMzM/8zMzP/MzMz/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/8zM + zP/MzMz/zMzM/8vLy//Ly8v/y8vL/8vLy//Kysr/ysrK/8rKyv/Kysr/ysrK/8vLy//Ly8v/vLy8/1dX + V/8lJSX/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JSUl/yUlJf8lJSX/JSUl/yQk + JP8jIyP/IiIi/xkZGf8EBAT/ExMT/21tbf+goKD/uLi4/7y8vP++vr7/wcHB/8PDw//FxcX/x8fH/8nJ + yf/Kysr/zc3N/87Ozv/Q0ND/0dHR/9PT0//V1dX/1tbW/9jY2P/Z2dn/2tra/9vb2//d3d3/3t7e/9/f + 3//g4OAx////Af///wH///8B////AcTExOPBwcH/vb29/7i4uP+ysrL/q6ur/6SkpP+Hh4f/bm5u/1BQ + UP9CQkL/TU1N/3t7e/93d3f/eHh4/3h4eP97e3v/g4OD/01NTf8iIiL/MDAw/0RERP9gYGD/hYWF/3V1 + df+vr6//+Pj4//Hx8f+IiIj/Hh4e/xwcHP8lJSX/Hx8f/x0dHf8gICD/IiIi/yMjI/8kJCT/JCQk/yQk + JP8kJCT/JCQk/yUlJf+SkpL/zMzM/83Nzf/Nzc3/zc3N/8zMzP/MzMz/zMzM/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zs7O/87Ozv/Ozs7/zc3N/83Nzf/Nzc3/zc3N/8zMzP/MzMz/zMzM/8vLy//Ly8v/y8vL/8vL + y//Ly8v/y8vL/8vLy//Ly8v/y8vL/8zMzP/Jycn/hoaG/ywsLP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8lJSX/JSUl/yUlJf8lJSX/JCQk/yMjI/8bGxv/BAQE/wcHB/9RUVH/mZmZ/7S0 + tP+8vLz/vr6+/8DAwP/Dw8P/xcXF/8fHx//IyMj/ysrK/8zMzP/Ozs7/0NDQ/9HR0f/T09P/1NTU/9bW + 1v/X19f/2NjY/9ra2v/b29v/3d3d/97e3v/f39//4ODg/+Hh4TH///8B////Af///wH///8BxMTE48LC + wv++vr7/uLi4/7Ozs/+tra3/pqam/4iIiP9xcXH/T09P/0JCQv9LS0v/e3t7/3p6ev96enr/fX19/4iI + iP+enp7/eXl5/yUlJf8sLCz/Wlpa/3x8fP92dnb/srKy//j4+P/w8PD/ioqK/yIiIv8bGxv/JSUl/x8f + H/8cHBz/ICAg/yIiIv8jIyP/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/MjIy/7q6uv/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/87Ozv/Ozs7/zs7O/87Ozv/Ozs7/zc3N/83N + zf/Nzc3/zc3N/8zMzP/MzMz/y8vL/8vLy//Ly8v/y8vL/8vLy//Ly8v/y8vL/8zMzP/MzMz/zMzM/83N + zf+urq7/OTk5/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JSUl/yUlJf8lJSX/JSUl/yQk + JP8iIiL/Gxsb/wYGBv8ODg7/UVFR/5mZmf+1tbX/u7u7/76+vv/AwMD/wsLC/8TExP/Hx8f/ycnJ/8rK + yv/MzMz/zs7O/9DQ0P/R0dH/09PT/9TU1P/V1dX/2NjY/9nZ2f/a2tr/29vb/9zc3P/e3t7/39/f/+Dg + 4P/h4eH/4eHhMf///wH///8B////Af///wHExMTjwsLC/76+vv+6urr/tbW1/66urv+oqKj/ioqK/3d3 + d/9oaGj/Xl5e/05OTv94eHj/fX19/35+fv+IiIj/mpqa/5+fn/9kZGT/KCgo/yAgIP9KSkr/aWlp/5WV + lf/29vb/+vr6/56env8oKCj/GRkZ/yUlJf8hISH/HBwc/yAgIP8iIiL/IyMj/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP9LS0v/ysrK/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83N + zf/Ozs7/zs7O/87Ozv/Ozs7/zs7O/87Ozv/Ozs7/zs7O/83Nzf/Nzc3/zMzM/8zMzP/MzMz/zMzM/8zM + zP/Ly8v/y8vL/8vLy//MzMz/zMzM/83Nzf/Nzc3/zc3N/8HBwf9OTk7/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8lJSX/JSUl/yUlJf8kJCT/JSUl/x8fH/8HBwf/BgYG/05OTv+Pj4//r6+v/7u7 + u/+9vb3/wMDA/8LCwv/ExMT/xsbG/8jIyP/Kysr/zMzM/87Ozv/Pz8//0dHR/9PT0//U1NT/1dXV/9fX + 1//Y2Nj/2tra/9vb2//d3d3/3d3d/97e3v/g4OD/4eHh/+Li4v/i4uIx////Af///wH///8B////AcTE + xOPCwsL/v7+//7u7u/+3t7f/sbGx/6qqqv+Kior/e3t7/3x8fP9sbGz/Pj4+/1lZWf9+fn7/iIiI/5ub + m/+jo6P/bm5u/z8/P/9GRkb/MTEx/yYmJv9JSUn/YGBg/7Gxsf+qqqr/Ly8v/xgYGP8kJCT/IiIi/x0d + Hf8fHx//IiIi/yMjI/8jIyP/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/2BgYP/MzMz/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Ozs7/zs7O/87Ozv/Ozs7/zs7O/87O + zv/Ozs7/zc3N/83Nzf/Nzc3/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zc3N/83N + zf/Nzc3/ysrK/11dXf8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yUlJf8lJSX/JCQk/yQk + JP8fHx//CQkJ/wcHB/9FRUX/kJCQ/62trf+6urr/vLy8/7+/v//BwcH/xMTE/8bGxv/IyMj/ysrK/8zM + zP/Ozs7/0NDQ/9HR0f/T09P/1NTU/9XV1f/X19f/2NjY/9ra2v/b29v/3Nzc/93d3f/e3t7/4ODg/+Hh + 4f/i4uL/4+Pj/+Pj4zH///8B////Af///wH///8BxcXF48LCwv+/v7//vLy8/7i4uP+zs7P/qqqq/4iI + iP9+fn7/fn5+/2lpaf83Nzf/VlZW/4aGhv+YmJj/oaGh/3x8fP8+Pj7/TU1N/3h4eP9oaGj/NjY2/xkZ + Gf8TExP/IyMj/z4+Pv8eHh7/IiIi/yQkJP8cHBz/Hh4e/yIiIv8jIyP/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/aGho/8zMzP/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Ozs7/zs7O/87Ozv/Ozs7/zs7O/83Nzf/Nzc3/zc3N/83Nzf/MzMz/zMzM/8zM + zP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/Nzc3/zc3N/83Nzf/Nzc3/a2tr/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8lJSX/JSUl/yQkJP8mJib/NjY2/y0tLf8aGhr/Q0ND/5GRkf+urq7/ubm5/7y8 + vP+/v7//wcHB/8PDw//FxcX/yMjI/8rKyv/MzMz/zc3N/8/Pz//R0dH/09PT/9TU1P/V1dX/19fX/9jY + 2P/Z2dn/29vb/9zc3P/d3d3/3t7e/9/f3//g4OD/4eHh/+Li4v/j4+P/5OTkMf///wH///8B////Af// + /wHFxcXjwsLC/7+/v/+8vLz/uLi4/7S0tP+jo6P/hISE/4CAgP+AgID/aWlp/zY2Nv9cXFz/l5eX/6Oj + o/+AgID/RUVF/0lJSf9ycnL/g4OD/4ODg/+1tbX/S0tL/w4ODv8iIiL/Ozs7/x8fH/8eHh7/Hh4e/x4e + Hv8jIyP/JSUl/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP9hYWH/zMzM/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zM + zP/MzMz/zc3N/8vLy/9qamr/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yUlJf8kJCT/JCQk/zQ0 + NP9MTEz/X19f/2pqav+SkpL/s7Oz/7m5uf+7u7v/vr6+/8DAwP/Dw8P/xcXF/8fHx//Kysr/zMzM/83N + zf/Pz8//0dHR/9PT0//U1NT/1dXV/9fX1//Y2Nj/2dnZ/9ra2v/c3Nz/3d3d/97e3v/f39//4ODg/+Hh + 4f/i4uL/4+Pj/+Tk5P/k5OQx////Af///wH///8B////AcbGxuPDw8P/wMDA/7y8vP+5ubn/sbGx/5KS + kv+CgoL/goKC/4GBgf9lZWX/NDQ0/1xcXP+ioqL/iIiI/0VFRf9ERET/dHR0/4SEhP+BgYH/3t7e//z8 + /P+wsLD/Li4u/ycnJ/8bGxv/FBQU/xoaGv8gICD/JSUl/yYmJv8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/1FRUf/Ly8v/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zMzM/8zM + zP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/x8fH/1xcXP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yMjI/8jIyP/LS0t/0RERP9oaGj/hoaG/6+vr/+5ubn/vLy8/76+ + vv/AwMD/wsLC/8TExP/Hx8f/ycnJ/8vLy//Nzc3/z8/P/9DQ0P/S0tL/1NTU/9XV1f/X19f/2NjY/9nZ + 2f/a2tr/3Nzc/93d3f/e3t7/39/f/+Dg4P/h4eH/4uLi/+Pj4//k5OT/5eXl/+Xl5TH///8B////Af// + /wH///8BxsbG48TExP/BwcH/vb29/7q6uv+np6f/h4eH/4ODg/+Dg4P/g4OD/2VlZf8zMzP/Q0ND/4CA + gP9MTEz/QkJC/2hoaP+Hh4f/enp6/9DQ0P/9/f3/4ODg/1VVVf8ZGRn/Hx8f/xkZGf8WFhb/Hh4e/yUl + Jf8mJib/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/Ojo6/8HB + wf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zM + zP/MzMz/zMzM/8zMzP+8vLz/R0dH/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8iIiL/IiIi/xAQ + EP8GBgb/NjY2/4GBgf+hoaH/ubm5/7u7u/++vr7/wMDA/8LCwv/ExMT/xsbG/8nJyf/Ly8v/zc3N/8/P + z//Q0ND/0tLS/9TU1P/V1dX/19fX/9jY2P/Z2dn/2tra/9zc3P/d3d3/3t7e/9/f3//g4OD/4eHh/+Li + 4v/j4+P/5OTk/+Xl5f/l5eX/5ubmMf///wH///8B////Af///wHHx8fjxMTE/8HBwf++vr7/u7u7/5iY + mP+EhIT/hYWF/4WFhf+IiIj/dnZ2/zc3N/8sLCz/RUVF/0NDQ/9paWn/hYWF/319ff/IyMj/+/v7/+Dg + 4P9lZWX/FhYW/x0dHf8kJCT/Hh4e/x8fH/8jIyP/JSUl/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8mJib/n5+f/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/8zM + zP/MzMz/zMzM/8zMzP/MzMz/zMzM/8vLy//Ly8v/y8vL/8vLy//Ly8v/ysrK/5ycnP8yMjL/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/IiIi/yEhIf8TExP/AwMD/yoqKv+BgYH/qamp/7i4uP+8vLz/vr6+/8DA + wP/CwsL/xMTE/8fHx//Jycn/y8vL/83Nzf/Pz8//0dHR/9PT0//U1NT/1dXV/9fX1//Y2Nj/2dnZ/9vb + 2//c3Nz/3d3d/97e3v/f39//4ODg/+Hh4f/i4uL/4+Pj/+Tk5P/l5eX/5eXl/+bm5v/m5uYx////Af// + /wH///8B////AcjIyOPFxcX/wsLC/7+/v/+8vLz/k5OT/4WFhf+Ghob/iIiI/5KSkv+Ojo7/QkJC/yoq + Kv9eXl7/cHBw/4ODg/93d3f/vr6+//n5+f/n5+f/dHR0/xwcHP8cHBz/JSUl/x4eHv8fHx//JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP9wcHD/xsbG/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/8zMzP/MzMz/zMzM/8zMzP/Ly8v/y8vL/8vL + y//Ly8v/y8vL/8vLy//FxcX/eHh4/ykpKf8kJCT/JCQk/yQkJP8kJCT/JCQk/yMjI/8hISH/ExMT/wMD + A/8bGxv/dHR0/6Wlpf+4uLj/vLy8/76+vv/AwMD/wsLC/8TExP/Gxsb/ycnJ/8vLy//Nzc3/z8/P/9DQ + 0P/S0tL/09PT/9XV1f/X19f/2NjY/9nZ2f/a2tr/3Nzc/93d3f/e3t7/39/f/+Dg4P/h4eH/4uLi/+Pj + 4//j4+P/5OTk/+Xl5f/m5ub/5+fn/+fn5zH///8B////Af///wH///8ByMjI48bGxv/ExMT/wcHB/729 + vf+SkpL/hoaG/4iIiP+RkZH/oKCg/5eXl/9HR0f/JSUl/1JSUv+Li4v/gICA/66urv/6+vr/8fHx/3x8 + fP8eHh7/Gxsb/yUlJf8fHx//Hh4e/yIiIv8kJCT/JCQk/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/z4+Pv+np6f/zMzM/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zMzM/8zMzP/MzMz/zMzM/8vLy//Ly8v/y8vL/8vLy//Ly8v/y8vL/7CwsP9JSUn/JCQk/yQk + JP8kJCT/JCQk/yQkJP8jIyP/IyMj/xgYGP8EBAT/ExMT/2dnZ/+ampr/tra2/7y8vP++vr7/wMDA/8LC + wv/ExMT/xsbG/8nJyf/Ly8v/zMzM/8/Pz//Q0ND/0tLS/9PT0//U1NT/1tbW/9fX1//Z2dn/2tra/9zc + 3P/d3d3/3t7e/9/f3//g4OD/4eHh/+Li4v/j4+P/4+Pj/+Tk5P/l5eX/5ubm/+fn5//n5+f/5+fnMf// + /wH///8B////Af///wHJycnjx8fH/8XFxf/CwsL/vr6+/5KSkv+JiYn/kZGR/6CgoP+fn5//Y2Nj/zo6 + Ov8sLCz/Kioq/21tbf+QkJD/w8PD/+zs7P+RkZH/Hh4e/xoaGv8kJCT/ICAg/x0dHf8gICD/IyMj/yMj + I/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/KCgo/2dnZ//CwsL/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zMzM/8zMzP/MzMz/zMzM/8vL + y//Ly8v/y8vL/8vLy//Gxsb/ZmZm/ycnJ/8kJCT/JCQk/yQkJP8kJCT/IyMj/yIiIv8XFxf/BAQE/xkZ + Gf9oaGj/np6e/7S0tP+8vLz/vr6+/8DAwP/CwsL/xMTE/8fHx//IyMj/y8vL/8zMzP/Ozs7/0NDQ/9LS + 0v/T09P/1NTU/9bW1v/X19f/2dnZ/9ra2v/c3Nz/3d3d/97e3v/f39//4ODg/+Hh4f/i4uL/4+Pj/+Pj + 4//k5OT/5eXl/+bm5v/n5+f/5+fn/+jo6P/o6Ogx////Af///wH///8B////AcrKyuPIyMj/xsbG/8PD + w/+/v7//kpKS/5CQkP+dnZ3/o6Oj/3R0dP88PDz/Tk5O/2FhYf8vLy//LCws/z4+Pv8+Pj7/cHBw/zAw + MP8ZGRn/IyMj/yEhIf8dHR3/ICAg/yIiIv8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMj + I/8jIyP/IyMj/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/Li4u/5OTk//MzMz/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zMzM/8zMzP/MzMz/y8vL/8vLy//Ly8v/ycnJ/56env8xMTH/JCQk/yQk + JP8kJCT/IyMj/yMjI/8mJib/ISEh/wcHB/8KCgr/YWFh/5mZmf+2trb/vLy8/76+vv/AwMD/wsLC/8TE + xP/Gxsb/yMjI/8rKyv/MzMz/zs7O/9DQ0P/S0tL/09PT/9TU1P/W1tb/19fX/9nZ2f/a2tr/29vb/9zc + 3P/e3t7/39/f/+Dg4P/h4eH/4eHh/+Pj4//j4+P/5OTk/+Xl5f/l5eX/5ubm/+fn5//o6Oj/6Ojo/+np + 6TH///8B////Af///wH///8By8vL48nJyf/Hx8f/xcXF/7+/v/+YmJj/np6e/6Ojo/9ycnL/PT09/1JS + Uv96enr/fX19/3p6ev9RUVH/ERER/xISEv9MTEz/Pz8//yEhIf8iIiL/Hx8f/x8fH/8iIiL/IyMj/yMj + I/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/Nzc3/5WVlf/IyMj/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/MzMz/zMzM/8zM + zP/MzMz/y8vL/8rKyv+dnZ3/QEBA/yQkJP8kJCT/JCQk/yQkJP8jIyP/KSkp/0FBQf9RUVH/U1NT/2lp + af+qqqr/tra2/729vf+/v7//wcHB/8PDw//ExMT/x8fH/8jIyP/Kysr/zMzM/87Ozv/Q0ND/0tLS/9PT + 0//U1NT/1tbW/9fX1//Z2dn/2tra/9vb2//d3d3/3d3d/9/f3//g4OD/4eHh/+Li4v/i4uL/5OTk/+Tk + 5P/l5eX/5ubm/+bm5v/n5+f/6Ojo/+np6f/p6en/6enpMf///wH///8B////Af///wHMzMzjysrK/8jI + yP/Gxsb/wcHB/6Ojo/+mpqb/fX19/0FBQf9HR0f/dnZ2/4GBgf+Ghob/4eHh/9PT0/9MTEz/KSkp/zMz + M/8gICD/Ghoa/xwcHP8gICD/ISEh/yIiIv8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMj + I/8jIyP/IyMj/yMjI/8jIyP/IyMj/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8lJSX/QEBA/5aW + lv/Ly8v/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/MzMz/zMzM/8zMzP/Kysr/qamp/0lJSf8mJib/JCQk/yQk + JP8kJCT/IyMj/yQkJP8zMzP/SkpK/1tbW/94eHj/mJiY/7q6uv+8vLz/v7+//8HBwf/Dw8P/xcXF/8bG + xv/IyMj/ysrK/8zMzP/Ozs7/0NDQ/9LS0v/T09P/1NTU/9bW1v/X19f/2dnZ/9ra2v/c3Nz/3Nzc/93d + 3f/e3t7/39/f/+Dg4P/h4eH/4uLi/+Pj4//k5OT/5eXl/+bm5v/m5ub/5+fn/+jo6P/o6Oj/6enp/+rq + 6v/q6uox////Af///wH///8B////Ac3NzePLy8v/ycnJ/8fHx//ExMT/rKys/4SEhP9ERET/R0dH/29v + b/+CgoL/hYWF/+Li4v/7+/v/wMDA/zY2Nv8eHh7/HR0d/xISEv8ZGRn/Hh4e/yEhIf8iIiL/IyMj/yMj + I/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMj + I/8jIyP/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/MzMz/4KCgv+6urr/zMzM/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/8zM + zP/MzMz/v7+//4qKiv9AQED/JSUl/yQkJP8kJCT/JCQk/yMjI/8iIiL/ICAg/xISEv8nJyf/YWFh/42N + jf+ysrL/vb29/7+/v//BwcH/w8PD/8XFxf/Hx8f/ycnJ/8rKyv/MzMz/zs7O/9DQ0P/S0tL/09PT/9TU + 1P/W1tb/19fX/9nZ2f/a2tr/29vb/93d3f/d3d3/3t7e/9/f3//g4OD/4eHh/+Li4v/j4+P/5OTk/+Xl + 5f/m5ub/5ubm/+fn5//o6Oj/6Ojo/+np6f/q6ur/6urq/+vr6zH///8B////Af///wH///8Bz8/P483N + zf/Kysr/yMjI/8bGxv+jo6P/SkpK/0NDQ/9sbGz/goKC/35+fv/R0dH/+/v7/8zMzP9KSkr/ExMT/x0d + Hf8hISH/GRkZ/x4eHv8hISH/IiIi/yMjI/8jIyP/IyMj/yMjI/8iIiL/IiIi/yQiIf8iIiL/IiIi/yMj + I/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8kJCT/JCQk/yQk + JP8kJCT/LCws/1dXV/+jo6P/xsbG/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/x8fH/6mpqf9kZGT/Ly8v/yQkJP8kJCT/JCQk/yQk + JP8jIyP/IiIi/x4eHv8LCwv/BwcH/0BAQP+QkJD/sbGx/729vf/AwMD/wcHB/8PDw//FxcX/x8fH/8nJ + yf/Ly8v/zMzM/87Ozv/Q0ND/0tLS/9PT0//U1NT/1tbW/9fX1//Z2dn/2tra/9vb2//c3Nz/3d3d/97e + 3v/f39//4ODg/+Hh4f/i4uL/4+Pj/+Tk5P/k5OT/5ubm/+bm5v/n5+f/6Ojo/+jo6P/p6en/6urq/+rq + 6v/r6+v/6+vrMf///wH///8B////Af///wHPz8/jzs7O/8zMzP/Kysr/yMjI/7e3t/9vb2//aGho/4OD + g/94eHj/y8vL//v7+//T09P/VFRU/xcXF/8dHR3/IyMj/xwcHP8dHR3/ISEh/yMjI/8jIyP/IyMj/yIi + Iv8iIiL/IiIi/yIiIv86Ih7/ciQW/0AhHP8jISH/IiIi/yIiIv8jIyP/IyMj/yMjI/8jIyP/IyMj/yMj + I/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yQkJP8kJCT/JiYm/zo6Ov9oaGj/o6Oj/8HB + wf/Jycn/zMzM/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/8zMzP/Jycn/xMTE/62t + rf9wcHD/Pz8//ycnJ/8kJCT/JCQk/yQkJP8kJCT/IyMj/yIiIv8gICD/DAwM/wMDA/89PT3/h4eH/7Cw + sP+9vb3/v7+//8LCwv/ExMT/xsbG/8fHx//Jycn/y8vL/83Nzf/Pz8//0NDQ/9LS0v/T09P/1NTU/9bW + 1v/X19f/2dnZ/9ra2v/b29v/3Nzc/93d3f/e3t7/39/f/+Dg4P/h4eH/4uLi/+Li4v/j4+P/5OTk/+Xl + 5f/m5ub/5+fn/+jo6P/o6Oj/6enp/+rq6v/q6ur/6+vr/+vr6//s7Owx////Af///wH///8B////AdHR + 0ePPz8//zc3N/8vLy//Jycn/x8fH/7W1tf+SkpL/e3t7/76+vv/+/v7/5OTk/1paWv8UFBT/HBwc/yQk + JP8bGxv/HBwc/yEhIf8kJCT/IyMj/yMjI/8iIiL/IiIi/yIiIv8iIiL/NSIe/5EnFP/CLBH/ZCUa/yYi + If8iIiL/IiIi/yIiIv8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMj + I/8jIyP/IyMj/yQkJP8kJCT/JCQk/yQkJP8tLS3/TU1N/3Z2dv+goKD/rq6u/7q6uv/BwcH/yMjI/8nJ + yf/Hx8f/xcXF/729vf+urq7/m5ub/3p6ev9VVVX/MzMz/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yMj + I/8iIiL/ICAg/w4ODv8CAgL/Kioq/42Njf+tra3/vb29/8DAwP/CwsL/xMTE/8bGxv/IyMj/ysrK/8vL + y//Nzc3/z8/P/9DQ0P/S0tL/09PT/9TU1P/W1tb/19fX/9nZ2f/a2tr/3Nzc/93d3f/d3d3/3t7e/9/f + 3//g4OD/4eHh/+Li4v/i4uL/4+Pj/+Tk5P/l5eX/5ubm/+fn5//n5+f/6Ojo/+np6f/p6en/6urq/+vr + 6//r6+v/7Ozs/+zs7DH///8B////Af///wH///8B0tLS49DQ0P/Ozs7/zMzM/8vLy//Jycn/xsbG/7Ky + sv+xsbH/9PT0/+np6f98fHz/GRkZ/xkZGf8jIyP/Hx8f/xwcHP8hISH/JSUl/yQkJP8jIyP/IiIi/yIi + Iv8iIiL/IiIi/ykhIP9/JRX/xCwR/4UoGP8qIiH/IiIi/yIiIv8iIiL/IiIi/yMjI/8jIyP/IyMj/yMj + I/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8kJCT/JCQk/yQk + JP8kJCT/KCgo/zY2Nv9AQED/TExM/1lZWf9qamr/bW1t/2hoaP9iYmL/UVFR/0FBQf8zMzP/KCgo/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/IyMj/yEhIf8QEBD/AgIC/yAgIP90dHT/qqqq/7y8 + vP/AwMD/wsLC/8TExP/Gxsb/yMjI/8rKyv/MzMz/zc3N/8/Pz//R0dH/0tLS/9PT0//U1NT/1tbW/9fX + 1//Z2dn/2tra/9zc3P/c3Nz/3d3d/97e3v/f39//4ODg/+Hh4f/i4uL/4uLi/+Pj4//k5OT/5eXl/+bm + 5v/m5ub/5+fn/+jo6P/p6en/6enp/+rq6v/r6+v/6+vr/+zs7P/s7Oz/7OzsMf///wH///8B////Af// + /wHU1NTj0tLS/9DQ0P/Ozs7/zMzM/8rKyv/IyMj/wsLC/5GRkf+kpKT/cHBw/xsbG/8ZGRn/IiIi/x8f + H/8eHh7/IyMj/yYmJv8lJSX/IyMj/yIiIv8iIiL/IiIi/yIiIv8sIR//eSYX/8UtEf+CKBj/LiIg/yIi + Iv8iIiL/IiIi/yIiIv8iIiL/IiIi/yQiIv8jIyP/IyMj/yMjI/8jIiL/LCIh/0sjHP9vJRj/NSIf/yMj + I/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/IyMj/yQk + JP8nJyf/ERER/wICAv8lJSX/fX19/6ampv++vr7/wcHB/8PDw//ExMT/xsbG/8jIyP/Kysr/zMzM/83N + zf/Pz8//0dHR/9PT0//U1NT/1dXV/9bW1v/X19f/2dnZ/9ra2v/b29v/3d3d/93d3f/e3t7/39/f/+Dg + 4P/h4eH/4uLi/+Pj4//j4+P/5OTk/+Xl5f/m5ub/5+fn/+fn5//o6Oj/6enp/+np6f/q6ur/6urq/+vr + 6//r6+v/7Ozs/+3t7f/t7e0x////Af///wH///8B////AdXV1ePT09P/0dHR/8/Pz//Nzc3/zMzM/8rK + yv/BwcH/aGho/zs7O/9DQ0P/ISEh/yIiIv8eHh7/HR0d/yIiIv8mJib/JSUl/yMjI/8iIiL/IiIi/yIi + Iv8hISH/JCEh/3QlF//DLBD/tSsS/z4iHf8iISH/IiIi/yIiIv8iIiL/IiEh/yohH/9JIhz/YiIX/zch + Hf8kIiL/JiIh/0ciG/9+Jhb/jCgW/7csE/9GJB7/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMj + I/8jIyP/IyMj/yMjI/8kJCT/JCQk/yQkJP8kJCT/IyMj/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8jIyP/Li4u/z4+Pv8sLCz/Kysr/35+fv+qqqr/vLy8/8HB + wf/Dw8P/xcXF/8bGxv/IyMj/ysrK/8zMzP/Nzc3/z8/P/9HR0f/T09P/1NTU/9XV1f/X19f/2NjY/9nZ + 2f/a2tr/3Nzc/9zc3P/d3d3/3t7e/9/f3//g4OD/4eHh/+Li4v/i4uL/4+Pj/+Tk5P/l5eX/5ubm/+bm + 5v/n5+f/6Ojo/+jo6P/p6en/6urq/+rq6v/r6+v/7Ozs/+zs7P/t7e3/7e3t/+7u7jH///8B////Af// + /wH///8B1dXV49TU1P/T09P/0dHR/8/Pz//Nzc3/y8vL/8LCwv9vb2//U1NT/0dHR/8tLS3/JiYm/x4e + Hv8iIiL/JSUl/yUlJf8jIyP/IyMj/yIiIv8hISH/ISEh/yYgIP9fIxj/xSwR/7QsE/+7KxL/lycT/1Ui + GP80IR7/OSEc/0ohGv9tIxb/nygT/7wrEv+6LBL/hiYV/1MiGf98Jhb/kSgV/2QmG/9YJhz/nisW/ywj + If8jIiL/MyIf/z8iHf8vIiD/IyIi/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMj + I/8jIyP/IyMj/yMjI/8jIyP/IyMj/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8jIyP/IyMj/yYm + Jv9DQ0P/UVFR/2xsbP9/f3//s7Oz/7+/v//BwcH/xMTE/8XFxf/Hx8f/ycnJ/8rKyv/MzMz/zs7O/9DQ + 0P/R0dH/09PT/9TU1P/V1dX/19fX/9jY2P/Z2dn/2tra/9vb2//c3Nz/3d3d/97e3v/f39//4ODg/+Hh + 4f/i4uL/4+Pj/+Pj4//k5OT/5eXl/+bm5v/n5+f/5+fn/+jo6P/o6Oj/6enp/+rq6v/q6ur/6+vr/+vr + 6//s7Oz/7Ozs/+3t7f/u7u7/7u7uMf///wH///8B////Af///wHX19fj1dXV/9TU1P/S0tL/0NDQ/8/P + z//Nzc3/xcXF/35+fv9PT0//MDAw/ywsLP8mJib/ISEh/yQkJP8lJSX/IyMj/yMjI/8iIiL/IiIi/yEh + If8jICD/YiMZ/7srEf+fKhX/QSMd/1QkHP+eKhX/vCoQ/64pEf+sKBH/tioR/7ErE/+ZKhb/dCca/1Ml + HP98JRb/mCgU/3EnGv85JCD/JiMi/2smGv95KBn/IyMi/zQjIP+PJxT/hicW/3AkFv84Ix//IyIi/yMj + Iv8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yMjI/8jIyP/Hh4e/zIyMv9PT0//e3t7/5ycnP+9vb3/w8PD/8TE + xP/Gxsb/yMjI/8nJyf/Ly8v/zc3N/87Ozv/Q0ND/0dHR/9PT0//U1NT/1dXV/9fX1//Y2Nj/2dnZ/9ra + 2v/c3Nz/3Nzc/93d3f/e3t7/39/f/+Dg4P/h4eH/4uLi/+Pj4//k5OT/5OTk/+Xl5f/m5ub/5+fn/+fn + 5//o6Oj/6Ojo/+np6f/q6ur/6urq/+vr6//r6+v/7Ozs/+3t7f/t7e3/7e3t/+7u7v/u7u4x////Af// + /wH///8B////AdjY2OPX19f/1dXV/9PT0//S0tL/0NDQ/8/Pz//IyMj/gYGB/zc3N/8sLCz/KCgo/yEh + If8hISH/IyMj/yQkJP8jIyP/IiIi/yIiIv8hISH/ISEh/1EjG/+7KxH/tisS/0QjHf8iISD/IiEg/zUi + Hv9rJhn/tysS/7YqEf9eJBr/PiMe/y8iIP8lIiH/JCIh/0wkHf9DJB7/KCMi/yIiIv8qIiH/hSgX/1Ym + Hf8nIiH/QyQe/5YpFf9IIxz/TyUd/4gnFv9aJBn/JSIi/yMiIv8jIiL/IyMj/yMjI/8jIyP/IyMj/yMj + I/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/JCQk/yQkJP8kJCT/JCQk/yMjI/8jIyP/IyMj/xoa + Gv8GBgb/FxcX/2RkZP+enp7/u7u7/8PDw//FxcX/x8fH/8jIyP/Kysr/zMzM/87Ozv/Pz8//0NDQ/9LS + 0v/T09P/1dXV/9bW1v/X19f/2NjY/9ra2v/a2tr/3Nzc/9zc3P/d3d3/3t7e/9/f3//g4OD/4eHh/+Li + 4v/j4+P/5OTk/+Tk5P/l5eX/5ubm/+bm5v/n5+f/6Ojo/+jo6P/p6en/6enp/+rq6v/r6+v/6+vr/+zs + 7P/s7Oz/7e3t/+3t7f/u7u7/7u7u/+7u7jH///8B////Af///wH///8B2tra49jY2P/W1tb/1NTU/9PT + 0//S0tL/0NDQ/8XFxf9kZGT/LS0t/ygoKP8iIiL/IiIi/yMjI/8kJCT/IyMj/yMjI/8iIiL/IiIi/yEh + If8oISD/gCcX/8ctEf+gKBP/QSEb/yYgH/8gICD/ICAg/yAgH/9MIxz/tisS/34mFv8mISD/ISEh/yYh + IP83IR3/RSIb/0MiHP8zIR7/IyEh/0IkHv+ZKRX/OyMf/1ckG/9zJRf/WSUc/4MmFf9uJBf/pSoU/1Yl + HP9EIx3/SyMc/zMiH/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMj + I/8kJCT/JCQk/yQkJP8kJCT/IyMj/yIiIv8ZGRn/BQUF/wwMDP9bW1v/oaGh/7+/v//FxcX/xsbG/8jI + yP/Jycn/y8vL/8zMzP/Ozs7/0NDQ/9HR0f/T09P/1NTU/9XV1f/X19f/2NjY/9nZ2f/a2tr/29vb/9zc + 3P/d3d3/3t7e/9/f3//g4OD/4ODg/+Hh4f/i4uL/4+Pj/+Tk5P/k5OT/5eXl/+bm5v/n5+f/5+fn/+jo + 6P/o6Oj/6enp/+rq6v/q6ur/6+vr/+vr6//s7Oz/7e3t/+3t7f/u7u7/7u7u/+7u7v/v7+//7+/vMf// + /wH///8B////Af///wHa2trj2dnZ/9fX1//W1tb/1NTU/9PT0//S0tL/w8PD/1dXV/8sLCz/IyMj/yEh + If8jIyP/JCQk/yQkJP8jIyP/IyMj/yIiIv8iIiL/IiIi/yEhIf8zIh//aiYa/64qE/+uKRH/bSMW/y0f + Hf8gICD/ICAg/zshHf+tKhL/oioU/y0hH/8rIB7/bCMW/6QpEv+0KhH/rykR/5onEv9aIhj/WiQa/3cn + Gf8pIiH/SSQd/40nFP9YIhn/fiYW/6YqFP9dJRv/WSQa/5goFf+JKBb/gCYW/zUiHv8kIiL/IyMj/yMj + I/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yQkJP8kJCT/JCQk/yMjI/8iIiL/HBwc/wcH + B/8GBgb/SkpK/5ycnP+9vb3/xcXF/8fHx//Jycn/ysrK/8zMzP/Nzc3/zs7O/9DQ0P/S0tL/09PT/9XV + 1f/W1tb/19fX/9nZ2f/Z2dn/2tra/9vb2//d3d3/3d3d/97e3v/f39//4ODg/+Dg4P/h4eH/4uLi/+Pj + 4//k5OT/5OTk/+Xl5f/m5ub/5ubm/+fn5//o6Oj/6Ojo/+np6f/p6en/6urq/+vr6//r6+v/7Ozs/+zs + 7P/t7e3/7e3t/+7u7v/u7u7/7+/v/+/v7//w8PAx////Af///wH///8B////Advb2+Pa2tr/2dnZ/9fX + 1//W1tb/1NTU/9PT0//CwsL/UFBQ/yQkJP8hISH/IyMj/yQkJP8kJCT/JCQk/yMjI/8jIyP/IiIi/yIi + Iv8iIiL/ISEh/yEhIf8iISD/OSIe/3wnGP+zKhL/nycR/2YiFv9WIRf/kCUS/8UsEf93Jxn/MSEe/4Ul + FP+5KxL/gygX/0wkHf9FIx3/dicY/68qEv98JRb/KiIg/yIiIf8kIiH/QyMe/38nGP+NKRb/XCYb/1wk + Gv+dKRT/SyUe/ykjIv98KBn/licU/z0iHv8tIiD/JSIi/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMj + I/8jIyP/JCQk/yMjI/8jIyP/JCQk/yEhIf8JCQn/CQkJ/0hISP+YmJj/wMDA/8fHx//IyMj/ycnJ/8vL + y//MzMz/zs7O/8/Pz//R0dH/0tLS/9TU1P/V1dX/19fX/9jY2P/Z2dn/2tra/9vb2//c3Nz/3d3d/97e + 3v/e3t7/39/f/+Dg4P/h4eH/4uLi/+Li4v/j4+P/5OTk/+Tk5P/l5eX/5ubm/+fn5//n5+f/6Ojo/+jo + 6P/p6en/6urq/+rq6v/r6+v/6+vr/+zs7P/s7Oz/7e3t/+3t7f/u7u7/7u7u/+/v7//v7+//8PDw//Dw + 8DH///8B////Af///wH///8B3d3d49zc3P/a2tr/2dnZ/9fX1//W1tb/1NTU/8DAwP9GRkb/IiIi/yMj + I/8kJCT/JCQk/yQkJP8kJCT/IyMj/yMjI/8jIyP/IiIi/yIiIv8iIiL/ISEh/yEhIf8hISH/JyEg/04j + HP+QKBX/tioR/70rEP+3KxL/gygX/zsiHv9tJRj/viwR/3AmGf8rISD/ISEh/yEhIf8nISD/dicY/7Eq + Ev88Ih7/IiIi/yIiIv8iIiL/JiIh/ykiIf82Ih7/likV/10mHP8kIiL/OCIe/5UpFv9pJxv/RCMe/3Ym + F/8xIyD/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8kJCT/IyMj/yMjI/8jIyP/CgoK/wQE + BP9AQED/kpKS/7u7u//IyMj/ycnJ/8vLy//MzMz/zs7O/8/Pz//Q0ND/0dHR/9PT0//U1NT/1tbW/9fX + 1//Y2Nj/2tra/9vb2//c3Nz/3Nzc/97e3v/e3t7/39/f/+Dg4P/g4OD/4eHh/+Li4v/i4uL/4+Pj/+Tk + 5P/l5eX/5eXl/+bm5v/m5ub/5+fn/+jo6P/o6Oj/6enp/+rq6v/q6ur/6+vr/+vr6//s7Oz/7Ozs/+3t + 7f/t7e3/7u7u/+7u7v/v7+//7+/v/+/v7//w8PD/8PDwMf///wH///8B////Af///wHe3t7j3d3d/9zc + 3P/a2tr/2dnZ/9fX1//W1tb/y8vL/2hoaP8sLCz/IyMj/yMjI/8kJCT/JCQk/yMjI/8jIyP/IyMj/yMj + I/8iIiL/IiIi/yIiIv8hISH/ISEh/yEhIf8hISH/ISEg/ywhH/9BIx3/TyQc/0AjHv8pISD/NCIe/6Iq + FP+cKRX/KyEf/yEhIf8hISH/ISEh/yQhIP9sJRj/vSsR/0sjHf8hISH/MCEf/0QiHP8oISD/IiIi/yci + If9CJB7/JyIh/zciH/+IJxX/cica/0YkHf+RKBX/YiYc/zoiHv9kJBn/RyMd/yUiIv8jIyP/IyMj/yMj + I/8jIyP/IyMj/yMjI/8lJSX/MTEx/x8fH/8NDQ3/Pz8//5WVlf+5ubn/ycnJ/8vLy//MzMz/zc3N/8/P + z//Q0ND/0dHR/9LS0v/U1NT/1dXV/9bW1v/X19f/2dnZ/9ra2v/b29v/3Nzc/93d3f/e3t7/39/f/+Dg + 4P/g4OD/4eHh/+Li4v/i4uL/4+Pj/+Tk5P/k5OT/5eXl/+bm5v/m5ub/5+fn/+fn5//o6Oj/6enp/+np + 6f/q6ur/6urq/+vr6//r6+v/7Ozs/+zs7P/t7e3/7e3t/+7u7v/u7u7/7u7u/+/v7//v7+//8PDw//Dw + 8P/x8fEx////Af///wH///8B////Ad/f3+Pe3t7/3d3d/9zc3P/a2tr/2dnZ/9jY2P/X19f/xMTE/4yM + jP89PT3/JiYm/yMjI/8kJCT/IyMj/yMjI/8jIyP/IyMj/yMjI/8iIiL/IiIi/yIiIv8iIiL/IiIi/yEh + If8hISH/ISEh/yEhIf8hISH/ISEh/yEhIf8zIh//oioU/5AoFf8jICD/ISEh/yEhIf8gICD/OiEc/6Ao + Ev+rKhP/MiIf/ysgHv+EJhX/rikR/0QjHf8iIiL/IiIi/yIiIv8iIiL/TiMc/24nGv9CIx7/kikW/3co + Gf89Ix7/hicX/4EpGf9iJhv/KiMi/yMjI/8jIyP/IyMj/yMjI/8iIiL/JCQk/zg4OP9SUlL/XV1d/2Ji + Yv+ZmZn/xMTE/8zMzP/MzMz/zs7O/8/Pz//Q0ND/0dHR/9LS0v/U1NT/1dXV/9bW1v/X19f/2NjY/9nZ + 2f/b29v/3Nzc/93d3f/e3t7/39/f/9/f3//g4OD/4eHh/+Li4v/i4uL/4+Pj/+Pj4//k5OT/5eXl/+Xl + 5f/m5ub/5ubm/+fn5//o6Oj/6Ojo/+np6f/p6en/6urq/+rq6v/r6+v/7Ozs/+zs7P/t7e3/7e3t/+3t + 7f/u7u7/7u7u/+/v7//v7+//8PDw//Dw8P/w8PD/8fHx//Hx8TH///8B////Af///wH///8B4ODg49/f + 3//e3t7/3d3d/9zc3P/a2tr/2dnZ/9jY2P/X19f/0tLS/6qqqv9kZGT/Kysr/yMjI/8jIyP/IyMj/yMj + I/8jIyP/IyMj/yIiIv8iIiL/IiIi/yIiIv8iIiL/ISEh/yEhIf8hISH/ISEh/yEhIf8hISH/ISEh/yYh + IP9zJxn/sCoS/1QhGP8oIB7/IyAf/zcgG/+MJRP/visR/2YlGf8oIB//aSMX/78rEf+CKBj/LCIg/yIi + Iv8iIiH/IyIh/yIhIf8oIiH/NyIe/4AmFv99KBj/PSId/4EnFv95KBn/LSMi/yYjIv8jIyL/IyMj/yMj + I/8jIyP/IiIi/yIiIv8lJSX/OTk5/1NTU/9nZ2f/hYWF/7m5uf/Nzc3/zs7O/8/Pz//Q0ND/0dHR/9LS + 0v/T09P/1NTU/9bW1v/X19f/2NjY/9nZ2f/a2tr/29vb/9zc3P/d3d3/3t7e/9/f3//g4OD/4ODg/+Hh + 4f/i4uL/4+Pj/+Pj4//k5OT/5OTk/+Xl5f/m5ub/5ubm/+fn5//n5+f/6Ojo/+jo6P/p6en/6enp/+rq + 6v/r6+v/6+vr/+vr6//s7Oz/7Ozs/+3t7f/t7e3/7u7u/+7u7v/v7+//7+/v/+/v7//w8PD/8PDw//Hx + 8f/x8fH/8fHxMf///wH///8B////Af///wHh4eHj4ODg/9/f3//e3t7/3d3d/9zc3P/b29v/2tra/9nZ + 2f/Y2Nj/19fX/9TU1P+goKD/XFxc/y8vL/8iIiL/IyMj/yMjI/8jIyP/IyMj/yMjI/8iIiL/IiIi/yIi + Iv8iIiL/IiIi/yIiIv8iIiL/ISEh/yEhIf8hISH/ISEh/ykhIP9yJhj/qikS/54mEf+WJRH/rSgR/6sq + E/9kJRr/LyEe/3EkFv+/KxD/gygX/zAiH/8hISH/IiEh/zIiH/97JRX/VCMa/ysiIP9zJRf/eygZ/1Ek + HP+fKBP/likV/zMjIP8jIyP/IyMj/yMjI/8jIyP/IyMj/yIiIv8jIyP/JCQk/xEREf8HBwf/PT09/4GB + gf+0tLT/zs7O/8/Pz//R0dH/0tLS/9LS0v/T09P/1NTU/9XV1f/X19f/2NjY/9nZ2f/a2tr/29vb/9zc + 3P/d3d3/3t7e/9/f3//g4OD/4eHh/+Hh4f/i4uL/4+Pj/+Tk5P/k5OT/5eXl/+Xl5f/m5ub/5ubm/+fn + 5//n5+f/6Ojo/+jo6P/p6en/6enp/+rq6v/q6ur/6+vr/+vr6//s7Oz/7Ozs/+3t7f/t7e3/7u7u/+7u + 7v/u7u7/7+/v/+/v7//w8PD/8PDw//Hx8f/x8fH/8fHx//Ly8v/x8fEx////Af///wH///8B////AeLi + 4uPh4eH/4ODg/9/f3//e3t7/3d3d/9zc3P/b29v/2tra/9nZ2f/Y2Nj/19fX/9XV1f/ExMT/ioqK/0FB + Qf8kJCT/IyMj/yMjI/8jIyP/IyMj/yMjI/8iIiL/IiIi/yIiIv8iIiL/IiIi/yIiIv8iIiL/IiIi/yEh + If8hISH/ISEh/yghIP9FIx3/aCUZ/3UmGP9lJRn/QiMd/ychH/9YIhj/vSsR/5YpFf8wIh//ISEh/yEh + If8tIR//eSUW/7wsEf9lJhv/JyIh/0QkHv81IyD/YCUa/4spF/9UJR3/KyMh/yMjI/8jIyP/IyMj/yMj + I/8jIyP/IiIi/yQkJP8XFxf/AgIC/xwcHP95eXn/sbGx/87Ozv/Q0ND/0tLS/9PT0//U1NT/1NTU/9XV + 1f/W1tb/19fX/9nZ2f/a2tr/29vb/9vb2//d3d3/3d3d/9/f3//g4OD/4eHh/+Hh4f/i4uL/4+Pj/+Pj + 4//k5OT/5OTk/+Xl5f/m5ub/5ubm/+fn5//n5+f/6Ojo/+jo6P/p6en/6enp/+np6f/q6ur/6urq/+vr + 6//r6+v/7Ozs/+zs7P/t7e3/7e3t/+7u7v/u7u7/7+/v/+/v7//v7+//8PDw//Dw8P/w8PD/8fHx//Hx + 8f/y8vL/8vLy//Ly8jH///8B////Af///wH///8B4+Pj4+Li4v/h4eH/4ODg/9/f3//e3t7/3d3d/9zc + 3P/b29v/29vb/9ra2v/Z2dn/2NjY/9fX1//T09P/urq6/3t7e/81NTX/JSUl/yIiIv8jIyP/IyMj/yMj + I/8jIyP/IiIi/yIiIv8iIiL/IiIi/yIiIv8iIiL/IiIi/yEhIf8hISH/ISEh/yEhIP8iISD/JCEg/yIh + IP8lICD/WCIZ/7QqEf+sKxP/PiMe/yEhIP8hISH/KyAf/3klFv+7KxH/byca/yoiIf8iIiL/IyIi/y8i + IP9CIx3/MSMh/yQjIv8jIyL/IyMj/yMjI/8jIyP/IiIi/yMjI/8mJib/GBgY/wUFBf8eHh7/d3d3/7W1 + tf/Ozs7/0tLS/9PT0//U1NT/1dXV/9bW1v/X19f/19fX/9nZ2f/Z2dn/29vb/9zc3P/c3Nz/3t7e/97e + 3v/g4OD/4ODg/+Hh4f/i4uL/4+Pj/+Tk5P/k5OT/5eXl/+Xl5f/m5ub/5ubm/+fn5//n5+f/6Ojo/+jo + 6P/p6en/6enp/+rq6v/q6ur/6urq/+vr6//r6+v/7Ozs/+zs7P/t7e3/7e3t/+3t7f/u7u7/7u7u/+/v + 7//v7+//7+/v//Dw8P/w8PD/8PDw//Hx8f/x8fH/8vLy//Ly8v/y8vL/8/PzMf///wH///8B////Af// + /wHk5OTj5OTk/+Li4v/i4uL/4ODg/+Dg4P/e3t7/3t7e/93d3f/c3Nz/29vb/9ra2v/a2tr/2dnZ/9jY + 2P/X19f/09PT/6SkpP9gYGD/Kioq/yIiIv8jIyP/IyMj/yMjI/8jIyP/IyMj/yIiIv8iIiL/IiIi/yIi + Iv8iIiL/IiIi/yEhIf8hISH/ISEh/yEhIf8hISH/ISEh/zIhHv+TKBT/qCoT/6EpFP82IR3/ISAg/yYg + H/9nIxf/uysR/4MoF/8uIiD/IiIi/yIiIv8xIiD/iSgW/48oFf81IyD/IyMj/yMjI/8jIyP/IyMj/yMj + I/8iIiL/KSkp/x8fH/8FBQX/FRUV/2lpaf+urq7/0NDQ/9TU1P/V1dX/1dXV/9bW1v/X19f/2NjY/9nZ + 2f/Z2dn/29vb/9vb2//c3Nz/3d3d/97e3v/f39//4ODg/+Hh4f/i4uL/4+Pj/+Pj4//k5OT/5eXl/+Xl + 5f/m5ub/5ubm/+fn5//n5+f/6Ojo/+jo6P/p6en/6enp/+rq6v/q6ur/6urq/+vr6//r6+v/7Ozs/+zs + 7P/s7Oz/7e3t/+3t7f/u7u7/7u7u/+/v7//v7+//7+/v//Dw8P/w8PD/8PDw//Hx8f/x8fH/8fHx//Ly + 8v/y8vL/8vLy//Pz8//z8/Mx////Af///wH///8B////AeXl5ePl5eX/5OTk/+Pj4//i4uL/4eHh/+Dg + 4P/f39//3t7e/97e3v/c3Nz/3Nzc/9vb2//a2tr/2tra/9nZ2f/Y2Nj/1tbW/8nJyf+MjIz/RUVF/yYm + Jv8iIiL/IyMj/yMjI/8jIyP/IiIi/yIiIv8iIiL/IiIi/yIiIv8iIiL/IiIi/yEhIf8hISH/ISEh/yEh + If8hISH/JCEg/z0iHv9HIx3/pyoT/4gmE/9QIRj/dCQW/7orEf+OKRf/NCMf/yIiIv8iIiL/MCIf/4Em + Fv/ALRL/cCga/yojIv8jIyP/IyMj/yMjI/8jIyP/IiIi/yQkJP8eHh7/BQUF/wwMDP9hYWH/qamp/83N + zf/V1dX/1tbW/9fX1//X19f/2NjY/9nZ2f/a2tr/29vb/9zc3P/d3d3/3d3d/97e3v/f39//4ODg/+Hh + 4f/i4uL/4+Pj/+Pj4//k5OT/5eXl/+Xl5f/m5ub/5ubm/+fn5//n5+f/6Ojo/+jo6P/p6en/6enp/+rq + 6v/q6ur/6urq/+vr6//r6+v/6+vr/+zs7P/s7Oz/7e3t/+3t7f/t7e3/7u7u/+7u7v/v7+//7+/v/+/v + 7//w8PD/8PDw//Dw8P/x8fH/8fHx//Hx8f/y8vL/8vLy//Ly8v/z8/P/8/Pz//Pz8zH///8B////Af// + /wH///8B5ubm4+bm5v/l5eX/5OTk/+Pj4//i4uL/4eHh/+Hh4f/g4OD/39/f/9/f3//e3t7/3d3d/9zc + 3P/c3Nz/29vb/9ra2v/Z2dn/2dnZ/9fX1/+8vLz/fHx8/zg4OP8kJCT/IiIi/yMjI/8jIyP/IyMj/yIi + Iv8iIiL/IiIi/yIiIv8iIiL/IiIi/yIiIv8hISH/ISEh/yEhIf8hISH/ISEh/yMhIP9TJBz/nSkV/7gr + Ef+2KxL/uiwS/08kHP8iIiL/IiIi/yoiIP+AJhX/vywS/3YoGv8pIyL/IyMj/yMjI/8jIyP/IyMj/yIi + Iv8qKir/JSUl/wkJCf8RERH/Xl5e/6enp//Pz8//19fX/9jY2P/Y2Nj/2dnZ/9ra2v/a2tr/3Nzc/9zc + 3P/d3d3/3t7e/97e3v/f39//4ODg/+Hh4f/i4uL/4+Pj/+Tk5P/k5OT/5eXl/+Xl5f/m5ub/5+fn/+fn + 5//n5+f/6Ojo/+jo6P/p6en/6enp/+rq6v/q6ur/6+vr/+vr6//r6+v/7Ozs/+zs7P/s7Oz/7e3t/+3t + 7f/t7e3/7u7u/+7u7v/u7u7/7+/v/+/v7//w8PD/8PDw//Dw8P/x8fH/8fHx//Hx8f/y8vL/8vLy//Ly + 8v/z8/P/8/Pz//Pz8//z8/P/8/PzMf///wH///8B////Af///wHn5+fj5+fn/+bm5v/l5eX/5OTk/+Pj + 4//j4+P/4uLi/+Hh4f/g4OD/4ODg/9/f3//e3t7/3t7e/93d3f/c3Nz/29vb/9vb2//a2tr/2dnZ/9nZ + 2f/R0dH/pKSk/19fX/9LS0v/YmJi/2FhYf9PT0//LS0t/yIiIv8iIiL/IiIi/yIiIv8iIiL/IiIi/yIi + Iv8iIiL/ISEh/yEhIf8hISH/ISEh/yMhIP82Ix//TiQd/0okHf+iKhT/YCQZ/yQhIf8oISD/aCQY/8As + Ef+BKRn/MCMh/yMjI/8jIyP/IyMj/yMjI/8iIiL/Kysr/0xMTP9MTEz/QkJC/2RkZP+ysrL/zs7O/9jY + 2P/Z2dn/2dnZ/9ra2v/b29v/3Nzc/9zc3P/e3t7/3t7e/9/f3//g4OD/4ODg/+Hh4f/i4uL/4+Pj/+Pj + 4//k5OT/5eXl/+Xl5f/m5ub/5ubm/+fn5//n5+f/6Ojo/+jo6P/p6en/6enp/+np6f/q6ur/6urq/+vr + 6//r6+v/6+vr/+zs7P/s7Oz/7e3t/+3t7f/t7e3/7u7u/+7u7v/u7u7/7+/v/+/v7//v7+//8PDw//Dw + 8P/w8PD/8fHx//Hx8f/x8fH/8vLy//Ly8v/y8vL/8/Pz//Pz8//z8/P/8/Pz//T09P/z8/Mx////Af// + /wH///8B////Aejo6OPo6Oj/5+fn/+bm5v/m5ub/5eXl/+Tk5P/k5OT/4+Pj/+Li4v/h4eH/4eHh/+Dg + 4P/g4OD/39/f/97e3v/e3t7/3d3d/9zc3P/c3Nz/29vb/9ra2v/a2tr/1tbW/9TU1P/Y2Nj/19fX/9TU + 1P+1tbX/ZWVl/ysrK/8iIiL/IiIi/yIiIv8iIiL/IiIi/yIiIv8iIiL/ISEh/yEhIf8hISH/ISEh/yEh + If8iIiH/IiIh/2YnG/+zKxL/nCgT/6MoEv/BLBH/gSkZ/zAkIf8jIyL/IyMj/yMjI/8jIyP/IiIi/ycn + J/84ODj/VFRU/2JiYv92dnb/q6ur/9fX1//a2tr/2tra/9vb2//c3Nz/3d3d/93d3f/e3t7/39/f/9/f + 3//g4OD/4eHh/+Li4v/i4uL/4+Pj/+Tk5P/k5OT/5eXl/+bm5v/m5ub/5+fn/+fn5//o6Oj/6Ojo/+jo + 6P/p6en/6enp/+rq6v/q6ur/6+vr/+vr6//r6+v/7Ozs/+zs7P/s7Oz/7e3t/+3t7f/t7e3/7u7u/+7u + 7v/u7u7/7+/v/+/v7//v7+//7+/v//Dw8P/w8PD/8PDw//Hx8f/x8fH/8fHx//Hx8f/y8vL/8vLy//Pz + 8//z8/P/8/Pz//Pz8//09PT/9PT0//Pz8zH///8B////Af///wH///8B6enp4+np6f/o6Oj/5+fn/+fn + 5//m5ub/5eXl/+Xl5f/k5OT/4+Pj/+Pj4//i4uL/4eHh/+Hh4f/g4OD/4ODg/9/f3//e3t7/3t7e/93d + 3f/d3d3/3Nzc/9vb2//b29v/29vb/9ra2v/a2tr/2dnZ/9nZ2f/Dw8P/YmJi/yQkJP8jIyP/IiIi/yIi + Iv8iIiL/IiIi/yIiIv8iIiL/IiIi/yIiIv8iIiL/IiIi/yIiIv8iIiL/KiIh/10mHP+UKhb/nSsW/28o + G/8uIyH/IyMj/yMjI/8jIyP/IyMj/yIiIv8iIiL/ISEh/xQUFP8uLi7/Z2dn/4+Pj//Ozs7/29vb/9zc + 3P/c3Nz/3d3d/97e3v/e3t7/39/f/9/f3//g4OD/4eHh/+Li4v/i4uL/4+Pj/+Tk5P/k5OT/5eXl/+bm + 5v/m5ub/5ubm/+fn5//o6Oj/6Ojo/+jo6P/p6en/6enp/+rq6v/q6ur/6urq/+vr6//r6+v/7Ozs/+zs + 7P/s7Oz/7e3t/+3t7f/t7e3/7u7u/+7u7v/u7u7/7+/v/+/v7//v7+//8PDw//Dw8P/w8PD/8PDw//Hx + 8f/x8fH/8fHx//Ly8v/y8vL/8vLy//Ly8v/z8/P/8/Pz//Pz8//09PT/9PT0//T09P/09PT/9PT0Mf// + /wH///8B////Af///wHq6urj6urq/+np6f/o6Oj/6Ojo/+fn5//n5+f/5ubm/+bm5v/l5eX/5OTk/+Tk + 5P/j4+P/4+Pj/+Li4v/h4eH/4eHh/+Dg4P/g4OD/39/f/97e3v/e3t7/3d3d/93d3f/d3d3/3Nzc/9zc + 3P/b29v/29vb/9ra2v+mpqb/Kioq/yMjI/8iIiL/IiIi/yIiIv8iIiL/IiIi/yIiIv8iIiL/IiIi/yIi + Iv8iIiL/IiIi/yIiIv8iIiL/JCMi/ysjIv8sIyH/JiMi/yMjIv8jIyP/IyMj/yMjI/8iIiL/IiIi/x0d + Hf8ICAj/BQUF/zs7O/+Wlpb/x8fH/9zc3P/d3d3/3t7e/97e3v/f39//4ODg/+Dg4P/h4eH/4uLi/+Li + 4v/j4+P/4+Pj/+Tk5P/l5eX/5eXl/+bm5v/m5ub/5+fn/+jo6P/o6Oj/6Ojo/+np6f/p6en/6urq/+rq + 6v/q6ur/6+vr/+vr6//r6+v/7Ozs/+zs7P/s7Oz/7e3t/+3t7f/t7e3/7u7u/+7u7v/u7u7/7+/v/+/v + 7//v7+//7+/v/+/v7//w8PD/8PDw//Dw8P/x8fH/8fHx//Hx8f/y8vL/8vLy//Ly8v/y8vL/8/Pz//Pz + 8//z8/P/9PT0//T09P/09PT/9PT0//X19f/19fUx////Af///wH///8B////Aevr6+Pr6+v/6urq/+rq + 6v/p6en/6Ojo/+jo6P/n5+f/5+fn/+bm5v/m5ub/5eXl/+Tk5P/k5OT/4+Pj/+Pj4//i4uL/4uLi/+Hh + 4f/h4eH/4ODg/+Dg4P/f39//3t7e/97e3v/e3t7/3d3d/93d3f/c3Nz/3Nzc/8HBwf83Nzf/IiIi/yIi + Iv8jIyP/IyMj/yIiIv8iIiL/IiIi/yIiIv8iIiL/IiIi/yIiIv8iIiL/IyMj/yMjI/8jIyP/IyMj/yMj + I/8jIyP/IyMj/yMjI/8jIyP/IiIi/yIiIv8hISH/DQ0N/wMDA/80NDT/kJCQ/8nJyf/d3d3/39/f/9/f + 3//g4OD/4ODg/+Hh4f/h4eH/4uLi/+Li4v/j4+P/5OTk/+Tk5P/l5eX/5eXl/+bm5v/n5+f/5+fn/+fn + 5//o6Oj/6Ojo/+np6f/p6en/6urq/+rq6v/q6ur/6+vr/+vr6//r6+v/7Ozs/+zs7P/t7e3/7e3t/+3t + 7f/u7u7/7u7u/+7u7v/u7u7/7+/v/+/v7//v7+//7+/v//Dw8P/w8PD/8PDw//Hx8f/x8fH/8fHx//Hx + 8f/y8vL/8vLy//Ly8v/z8/P/8/Pz//Pz8//z8/P/8/Pz//T09P/09PT/9PT0//T09P/19fX/9fX1//X1 + 9TH///8B////Af///wH///8B7Ozs4+vr6//r6+v/6urq/+rq6v/p6en/6enp/+jo6P/o6Oj/5+fn/+bm + 5v/m5ub/5eXl/+Xl5f/k5OT/5OTk/+Pj4//j4+P/4uLi/+Li4v/h4eH/4eHh/+Dg4P/g4OD/39/f/9/f + 3//f39//3t7e/97e3v/d3d3/19fX/4uLi/89PT3/JCQk/yMjI/8jIyP/IyMj/yMjI/8iIiL/IiIi/yIi + Iv8iIiL/IiIi/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yIiIv8jIyP/JSUl/w4O + Dv8CAgL/IyMj/4KCgv/FxcX/39/f/+Dg4P/g4OD/4eHh/+Hh4f/i4uL/4uLi/+Pj4//j4+P/5OTk/+Tk + 5P/l5eX/5eXl/+bm5v/m5ub/5+fn/+fn5//o6Oj/6Ojo/+np6f/p6en/6urq/+rq6v/q6ur/6+vr/+vr + 6//r6+v/7Ozs/+zs7P/s7Oz/7e3t/+3t7f/t7e3/7u7u/+7u7v/u7u7/7+/v/+/v7//v7+//7+/v//Dw + 8P/w8PD/8PDw//Dw8P/x8fH/8fHx//Hx8f/x8fH/8vLy//Ly8v/y8vL/8vLy//Pz8//z8/P/8/Pz//Pz + 8//09PT/9PT0//T09P/19fX/9fX1//X19f/19fX/9fX1Mf///wH///8B////Af///wHt7e3j7Ozs/+zs + 7P/r6+v/6+vr/+rq6v/q6ur/6enp/+np6f/p6en/6Ojo/+jo6P/n5+f/5ubm/+bm5v/l5eX/5eXl/+Xl + 5f/k5OT/5OTk/+Pj4//j4+P/4uLi/+Li4v/h4eH/4eHh/+Hh4f/g4OD/4ODg/9/f3//f39//3d3d/76+ + vv9ycnL/ODg4/yQkJP8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMj + I/8jIyP/IyMj/yMjI/8jIyP/IiIi/yMjI/8RERH/AgIC/yYmJv+IiIj/xcXF/9/f3//i4uL/4uLi/+Li + 4v/j4+P/4+Pj/+Tk5P/k5OT/5eXl/+Xl5f/m5ub/5ubm/+bm5v/n5+f/5+fn/+jo6P/o6Oj/6enp/+np + 6f/p6en/6urq/+rq6v/r6+v/6+vr/+zs7P/s7Oz/7Ozs/+3t7f/t7e3/7e3t/+7u7v/u7u7/7u7u/+7u + 7v/v7+//7+/v/+/v7//v7+//8PDw//Dw8P/w8PD/8PDw//Hx8f/x8fH/8fHx//Hx8f/y8vL/8vLy//Ly + 8v/y8vL/8vLy//Pz8//z8/P/8/Pz//Pz8//09PT/9PT0//T09P/09PT/9fX1//X19f/19fX/9fX1//b2 + 9v/29vYx////Af///wH///8B////Ae3t7ePt7e3/7Ozs/+zs7P/s7Oz/6+vr/+vr6//q6ur/6urq/+np + 6f/p6en/6enp/+jo6P/o6Oj/5+fn/+fn5//m5ub/5ubm/+Xl5f/l5eX/5OTk/+Tk5P/j4+P/4+Pj/+Li + 4v/i4uL/4uLi/+Hh4f/h4eH/4eHh/+Dg4P/g4OD/4ODg/9TU1P+np6f/XFxc/yQkJP8iIiL/IyMj/yMj + I/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yIiIv8nJyf/FBQU/wIC + Av8cHBz/dnZ2/8TExP/f39//4uLi/+Pj4//j4+P/4+Pj/+Tk5P/k5OT/5eXl/+Xl5f/m5ub/5ubm/+fn + 5//n5+f/5+fn/+jo6P/o6Oj/6enp/+np6f/q6ur/6urq/+rq6v/r6+v/6+vr/+vr6//s7Oz/7Ozs/+3t + 7f/t7e3/7e3t/+7u7v/u7u7/7u7u/+7u7v/v7+//7+/v/+/v7//v7+//7+/v//Dw8P/w8PD/8PDw//Dw + 8P/x8fH/8fHx//Hx8f/x8fH/8vLy//Ly8v/y8vL/8vLy//Pz8//z8/P/8/Pz//Pz8//z8/P/9PT0//T0 + 9P/09PT/9PT0//X19f/19fX/9fX1//X19f/19fX/9vb2//b29jH///8B////Af///wH///8B7u7u4+3t + 7f/t7e3/7e3t/+zs7P/s7Oz/7Ozs/+vr6//r6+v/6+vr/+rq6v/q6ur/6enp/+np6f/p6en/6Ojo/+jo + 6P/n5+f/5+fn/+bm5v/m5ub/5eXl/+Xl5f/l5eX/5OTk/+Tk5P/j4+P/4+Pj/+Pj4//i4uL/4uLi/+Li + 4v/i4uL/4eHh/+Hh4f/X19f/l5eX/05OTv8oKCj/IiIi/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMj + I/8jIyP/IyMj/yMjI/8lJSX/Tk5O/5iYmP9zc3P/UVFR/5OTk//Gxsb/4uLi/+Tk5P/k5OT/5eXl/+Xl + 5f/l5eX/5ubm/+bm5v/n5+f/5+fn/+fn5//o6Oj/6Ojo/+np6f/p6en/6enp/+rq6v/q6ur/6urq/+vr + 6//r6+v/6+vr/+zs7P/s7Oz/7Ozs/+3t7f/t7e3/7e3t/+7u7v/u7u7/7u7u/+7u7v/u7u7/7+/v/+/v + 7//v7+//8PDw//Dw8P/w8PD/8PDw//Dw8P/x8fH/8fHx//Hx8f/x8fH/8fHx//Ly8v/y8vL/8vLy//Ly + 8v/y8vL/8/Pz//Pz8//z8/P/8/Pz//T09P/09PT/9PT0//T09P/09PT/9fX1//X19f/19fX/9fX1//b2 + 9v/29vb/9vb2Mf///wH///8B////Af///wHu7u7j7u7u/+7u7v/t7e3/7e3t/+3t7f/s7Oz/7Ozs/+zs + 7P/r6+v/6+vr/+vr6//q6ur/6urq/+rq6v/p6en/6enp/+jo6P/o6Oj/5+fn/+fn5//m5ub/5ubm/+Xl + 5f/l5eX/5eXl/+Tk5P/k5OT/5OTk/+Pj4//j4+P/4+Pj/+Pj4//i4uL/4uLi/+Pj4//g4OD/xMTE/3d3 + d/82Njb/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IiIi/0RERP+urq7/4uLi/+Li + 4v/a2tr/4ODg/+Tk5P/l5eX/5eXl/+Xl5f/l5eX/5ubm/+bm5v/n5+f/5+fn/+fn5//o6Oj/6Ojo/+jo + 6P/p6en/6enp/+rq6v/q6ur/6urq/+vr6//r6+v/6+vr/+zs7P/s7Oz/7Ozs/+3t7f/t7e3/7e3t/+7u + 7v/u7u7/7u7u/+/v7//v7+//7+/v/+/v7//v7+//8PDw//Dw8P/w8PD/8PDw//Hx8f/x8fH/8fHx//Hx + 8f/x8fH/8vLy//Ly8v/y8vL/8vLy//Ly8v/z8/P/8/Pz//Pz8//z8/P/8/Pz//T09P/09PT/9PT0//T0 + 9P/09PT/9fX1//X19f/19fX/9fX1//b29v/29vb/9vb2//b29v/29vYx////Af///wH///8B////Ae/v + 7+Pu7u7/7u7u/+7u7v/u7u7/7e3t/+3t7f/t7e3/7Ozs/+zs7P/s7Oz/6+vr/+vr6//r6+v/6urq/+rq + 6v/q6ur/6enp/+np6f/o6Oj/6Ojo/+fn5//n5+f/5+fn/+bm5v/m5ub/5eXl/+Xl5f/l5eX/5OTk/+Tk + 5P/k5OT/5OTk/+Pj4//j4+P/5OTk/+Tk5P/k5OT/29vb/7i4uP9ra2v/LS0t/yQkJP8iIiL/IyMj/yMj + I/8jIyP/IiIi/yMjI/84ODj/ra2t/+Li4v/l5eX/5eXl/+Xl5f/l5eX/5eXl/+bm5v/m5ub/5ubm/+fn + 5//n5+f/5+fn/+jo6P/o6Oj/6Ojo/+np6f/p6en/6enp/+rq6v/q6ur/6+vr/+vr6//r6+v/7Ozs/+zs + 7P/s7Oz/7e3t/+3t7f/t7e3/7e3t/+7u7v/u7u7/7u7u/+7u7v/v7+//7+/v/+/v7//v7+//8PDw//Dw + 8P/w8PD/8PDw//Hx8f/x8fH/8fHx//Hx8f/x8fH/8vLy//Ly8v/y8vL/8vLy//Ly8v/z8/P/8/Pz//Pz + 8//z8/P/8/Pz//T09P/09PT/9PT0//T09P/09PT/9PT0//X19f/19fX/9fX1//X19f/19fX/9vb2//b2 + 9v/29vb/9vb2//b29jH///8B////Af///wH///8B8PDw4+/v7//v7+//7+/v/+7u7v/u7u7/7u7u/+3t + 7f/t7e3/7e3t/+zs7P/s7Oz/7Ozs/+zs7P/r6+v/6+vr/+vr6//q6ur/6urq/+np6f/p6en/6enp/+jo + 6P/o6Oj/5+fn/+fn5//n5+f/5ubm/+bm5v/m5ub/5ubm/+bm5v/l5eX/5eXl/+Xl5f/l5eX/5eXl/+bm + 5v/m5ub/5ubm/9jY2P+dnZ3/V1dX/yYmJv8iIiL/IyMj/yMjI/8iIiL/PDw8/6CgoP/l5eX/5+fn/+fn + 5//n5+f/5+fn/+fn5//n5+f/5+fn/+jo6P/o6Oj/6Ojo/+jo6P/p6en/6enp/+np6f/q6ur/6urq/+rq + 6v/r6+v/6+vr/+vr6//s7Oz/7Ozs/+zs7P/t7e3/7e3t/+3t7f/t7e3/7u7u/+7u7v/u7u7/7u7u/+/v + 7//v7+//7+/v/+/v7//w8PD/8PDw//Dw8P/w8PD/8fHx//Hx8f/x8fH/8fHx//Ly8v/y8vL/8vLy//Ly + 8v/y8vL/8vLy//Pz8//z8/P/8/Pz//Pz8//z8/P/8/Pz//T09P/09PT/9PT0//T09P/09PT/9PT0//X1 + 9f/19fX/9fX1//X19f/19fX/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2Mf///wH///8B////Af// + /wHw8PDj8PDw//Dw8P/v7+//7+/v/+/v7//u7u7/7u7u/+7u7v/t7e3/7e3t/+3t7f/s7Oz/7Ozs/+zs + 7P/s7Oz/6+vr/+vr6//r6+v/6urq/+rq6v/p6en/6enp/+np6f/o6Oj/6Ojo/+jo6P/n5+f/5+fn/+fn + 5//n5+f/5ubm/+bm5v/m5ub/5ubm/+bm5v/m5ub/5ubm/+fn5//n5+f/5+fn/+Tk5P/MzMz/eHh4/zY2 + Nv8kJCT/IiIi/y0tLf+ampr/4ODg/+fn5//o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6enp/+np + 6f/p6en/6enp/+rq6v/q6ur/6urq/+rq6v/r6+v/6+vr/+vr6//s7Oz/7Ozs/+zs7P/t7e3/7e3t/+3t + 7f/t7e3/7u7u/+7u7v/u7u7/7+/v/+/v7//v7+//7+/v/+/v7//w8PD/8PDw//Dw8P/w8PD/8fHx//Hx + 8f/x8fH/8fHx//Hx8f/y8vL/8vLy//Ly8v/y8vL/8vLy//Pz8//z8/P/8/Pz//Pz8//z8/P/8/Pz//Pz + 8//09PT/9PT0//T09P/09PT/9PT0//X19f/19fX/9fX1//X19f/19fX/9fX1//b29v/29vb/9vb2//b2 + 9v/29vb/9vb2//f39//29vYx////Af///wH///8B////AfHx8ePx8fH/8PDw//Dw8P/w8PD/7+/v/+/v + 7//v7+//7+/v/+7u7v/u7u7/7u7u/+3t7f/t7e3/7e3t/+3t7f/s7Oz/7Ozs/+zs7P/r6+v/6+vr/+vr + 6//q6ur/6urq/+rq6v/p6en/6enp/+np6f/p6en/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo + 6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/k5OT/xcXF/3R0dP9MTEz/kZGR/+bm5v/p6en/6enp/+np + 6f/p6en/6enp/+np6f/q6ur/6urq/+rq6v/q6ur/6urq/+vr6//r6+v/6+vr/+vr6//r6+v/7Ozs/+zs + 7P/s7Oz/7e3t/+3t7f/t7e3/7u7u/+7u7v/u7u7/7u7u/+7u7v/v7+//7+/v/+/v7//v7+//8PDw//Dw + 8P/w8PD/8PDw//Dw8P/x8fH/8fHx//Hx8f/x8fH/8vLy//Ly8v/y8vL/8vLy//Ly8v/z8/P/8/Pz//Pz + 8//z8/P/8/Pz//Pz8//z8/P/9PT0//T09P/09PT/9PT0//T09P/09PT/9PT0//X19f/19fX/9fX1//X1 + 9f/19fX/9fX1//b29v/29vb/9vb2//b29v/29vb/9vb2//f39//39/f/9/f3//b29jH///8B////Af// + /wH///8B8fHx4/Hx8f/x8fH/8fHx//Dw8P/w8PD/8PDw/+/v7//v7+//7+/v/+/v7//u7u7/7u7u/+7u + 7v/t7e3/7e3t/+3t7f/t7e3/7e3t/+zs7P/s7Oz/6+vr/+vr6//r6+v/6urq/+rq6v/q6ur/6urq/+np + 6f/p6en/6enp/+np6f/p6en/6enp/+np6f/p6en/6enp/+np6f/p6en/6enp/+np6f/p6en/6enp/+np + 6f/p6en/3d3d/83Nzf/h4eH/6urq/+rq6v/q6ur/6urq/+rq6v/q6ur/6urq/+rq6v/q6ur/6urq/+vr + 6//r6+v/6+vr/+vr6//s7Oz/7Ozs/+zs7P/s7Oz/7e3t/+3t7f/t7e3/7u7u/+7u7v/u7u7/7u7u/+7u + 7v/v7+//7+/v/+/v7//v7+//8PDw//Dw8P/w8PD/8PDw//Dw8P/w8PD/8fHx//Hx8f/x8fH/8fHx//Ly + 8v/y8vL/8vLy//Ly8v/y8vL/8/Pz//Pz8//z8/P/8/Pz//Pz8//z8/P/9PT0//T09P/09PT/9PT0//T0 + 9P/09PT/9PT0//X19f/19fX/9fX1//X19f/19fX/9fX1//b29v/29vb/9vb2//b29v/29vb/9vb2//b2 + 9v/39/f/9/f3//f39//39/f/9vb2Mf///wH///8B////Af///wHy8vLj8fHx//Hx8f/x8fH/8fHx//Dw + 8P/w8PD/8PDw//Dw8P/v7+//7+/v/+/v7//v7+//7u7u/+7u7v/u7u7/7u7u/+3t7f/t7e3/7e3t/+3t + 7f/t7e3/7Ozs/+zs7P/s7Oz/7Ozs/+vr6//r6+v/6+vr/+vr6//r6+v/6urq/+rq6v/q6ur/6urq/+rq + 6v/q6ur/6urq/+rq6v/q6ur/6urq/+rq6v/q6ur/6urq/+rq6v/q6ur/6urq/+rq6v/r6+v/6+vr/+vr + 6//r6+v/6+vr/+vr6//r6+v/6+vr/+vr6//r6+v/7Ozs/+zs7P/s7Oz/7Ozs/+zs7P/t7e3/7e3t/+3t + 7f/u7u7/7u7u/+7u7v/u7u7/7u7u/+/v7//v7+//7+/v/+/v7//v7+//8PDw//Dw8P/w8PD/8PDw//Dw + 8P/x8fH/8fHx//Hx8f/x8fH/8fHx//Ly8v/y8vL/8vLy//Ly8v/y8vL/8/Pz//Pz8//z8/P/8/Pz//Pz + 8//z8/P/9PT0//T09P/09PT/9PT0//T09P/09PT/9PT0//T09P/19fX/9fX1//X19f/19fX/9fX1//X1 + 9f/19fX/9vb2//b29v/29vb/9vb2//b29v/29vb/9/f3//f39//39/f/9/f3//f39//39/cx////Af// + /wH///8B////AfLy8uPy8vL/8vLy//Ly8v/y8vL/8fHx//Hx8f/x8fH/8PDw//Dw8P/w8PD/8PDw/+/v + 7//v7+//7+/v/+/v7//u7u7/7u7u/+7u7v/u7u7/7u7u/+3t7f/t7e3/7e3t/+3t7f/s7Oz/7Ozs/+zs + 7P/s7Oz/7Ozs/+vr6//r6+v/6+vr/+vr6//r6+v/6+vr/+vr6//r6+v/6+vr/+vr6//r6+v/6+vr/+vr + 6//r6+v/6+vr/+vr6//r6+v/6+vr/+zs7P/s7Oz/7Ozs/+zs7P/s7Oz/7Ozs/+zs7P/s7Oz/7Ozs/+zs + 7P/t7e3/7e3t/+3t7f/t7e3/7e3t/+7u7v/u7u7/7u7u/+7u7v/v7+//7+/v/+/v7//v7+//7+/v//Dw + 8P/w8PD/8PDw//Dw8P/w8PD/8fHx//Hx8f/x8fH/8fHx//Hx8f/x8fH/8vLy//Ly8v/y8vL/8vLy//Ly + 8v/z8/P/8/Pz//Pz8//z8/P/8/Pz//Pz8//09PT/9PT0//T09P/09PT/9PT0//T09P/09PT/9fX1//X1 + 9f/19fX/9fX1//X19f/19fX/9fX1//b29v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9/f3//f3 + 9//39/f/9/f3//f39//39/f/9/f3//j4+DH///8B////Af///wH///8B8/Pz4/Pz8//y8vL/8vLy//Ly + 8v/y8vL/8fHx//Hx8f/x8fH/8fHx//Dw8P/w8PD/8PDw//Dw8P/w8PD/7+/v/+/v7//v7+//7+/v/+/v + 7//u7u7/7u7u/+7u7v/u7u7/7e3t/+3t7f/t7e3/7e3t/+3t7f/s7Oz/7Ozs/+zs7P/s7Oz/7Ozs/+zs + 7P/s7Oz/7Ozs/+zs7P/s7Oz/7Ozs/+zs7P/s7Oz/7Ozs/+zs7P/s7Oz/7Ozs/+zs7P/s7Oz/7Ozs/+zs + 7P/s7Oz/7e3t/+3t7f/t7e3/7e3t/+3t7f/t7e3/7e3t/+3t7f/t7e3/7u7u/+7u7v/u7u7/7u7u/+/v + 7//v7+//7+/v/+/v7//v7+//8PDw//Dw8P/w8PD/8PDw//Dw8P/x8fH/8fHx//Hx8f/x8fH/8fHx//Hx + 8f/x8fH/8vLy//Ly8v/y8vL/8vLy//Ly8v/z8/P/8/Pz//Pz8//z8/P/8/Pz//Pz8//09PT/9PT0//T0 + 9P/09PT/9PT0//T09P/09PT/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/29vb/9vb2//b2 + 9v/29vb/9vb2//b29v/29vb/9vb2//f39//39/f/9/f3//f39//39/f/9/f3//f39//4+Pj/+Pj4Mf// + /wH///8B////Af///wHz8/Pj8/Pz//Pz8//z8/P/8/Pz//Ly8v/y8vL/8vLy//Ly8v/x8fH/8fHx//Hx + 8f/x8fH/8fHx//Dw8P/w8PD/8PDw//Dw8P/w8PD/8PDw/+/v7//v7+//7+/v/+/v7//v7+//7u7u/+7u + 7v/u7u7/7u7u/+7u7v/u7u7/7e3t/+3t7f/t7e3/7e3t/+3t7f/t7e3/7e3t/+3t7f/t7e3/7e3t/+3t + 7f/t7e3/7e3t/+3t7f/t7e3/7e3t/+3t7f/t7e3/7e3t/+3t7f/u7u7/7u7u/+7u7v/u7u7/7u7u/+7u + 7v/u7u7/7u7u/+7u7v/v7+//7+/v/+/v7//v7+//7+/v//Dw8P/w8PD/8PDw//Dw8P/w8PD/8fHx//Hx + 8f/x8fH/8fHx//Hx8f/x8fH/8vLy//Ly8v/y8vL/8vLy//Ly8v/y8vL/8vLy//Pz8//z8/P/8/Pz//Pz + 8//z8/P/8/Pz//T09P/09PT/9PT0//T09P/09PT/9PT0//T09P/19fX/9fX1//X19f/19fX/9fX1//X1 + 9f/19fX/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b29v/39/f/9/f3//f39//39/f/9/f3//f3 + 9//39/f/9/f3//j4+P/4+Pj/+Pj4//j4+P/4+Pgx////Af///wH///8B////AfT09OP09PT/8/Pz//Pz + 8//z8/P/8/Pz//Pz8//y8vL/8vLy//Ly8v/y8vL/8vLy//Hx8f/x8fH/8fHx//Hx8f/w8PD/8PDw//Dw + 8P/w8PD/8PDw//Dw8P/w8PD/8PDw/+/v7//v7+//7+/v/+/v7//u7u7/7u7u/+7u7v/u7u7/7u7u/+7u + 7v/u7u7/7u7u/+7u7v/u7u7/7u7u/+7u7v/u7u7/7u7u/+7u7v/u7u7/7u7u/+7u7v/u7u7/7u7u/+7u + 7v/u7u7/7u7u/+7u7v/u7u7/7u7u/+7u7v/u7u7/7+/v/+/v7//v7+//7+/v/+/v7//v7+//8PDw//Dw + 8P/w8PD/8PDw//Dw8P/x8fH/8fHx//Hx8f/x8fH/8fHx//Hx8f/x8fH/8vLy//Ly8v/y8vL/8vLy//Ly + 8v/y8vL/8vLy//Pz8//z8/P/8/Pz//Pz8//z8/P/8/Pz//T09P/09PT/9PT0//T09P/09PT/9PT0//X1 + 9f/19fX/9fX1//X19f/19fX/9fX1//X19f/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b2 + 9v/29vb/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//j4+P/4+Pj/+Pj4//j4+P/4+Pj/+Pj4//j4 + +DH///8B////AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA + + + \ No newline at end of file diff --git a/ROMVault2/frmMain.Designer.cs b/ROMVault2/frmMain.Designer.cs new file mode 100644 index 0000000..2bbf160 --- /dev/null +++ b/ROMVault2/frmMain.Designer.cs @@ -0,0 +1,1104 @@ +namespace ROMVault2 +{ + partial class FrmMain + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FrmMain)); + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle1 = new System.Windows.Forms.DataGridViewCellStyle(); + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle2 = new System.Windows.Forms.DataGridViewCellStyle(); + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle3 = new System.Windows.Forms.DataGridViewCellStyle(); + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle4 = new System.Windows.Forms.DataGridViewCellStyle(); + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle5 = new System.Windows.Forms.DataGridViewCellStyle(); + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle6 = new System.Windows.Forms.DataGridViewCellStyle(); + this.splitContainer1 = new System.Windows.Forms.SplitContainer(); + this.btnReport = new System.Windows.Forms.Button(); + this.btnFixFiles = new System.Windows.Forms.Button(); + this.btnFindFixes = new System.Windows.Forms.Button(); + this.btnScanRoms = new System.Windows.Forms.Button(); + this.btnUpdateDats = new System.Windows.Forms.Button(); + this.splitContainer2 = new System.Windows.Forms.SplitContainer(); + this.splitContainer3 = new System.Windows.Forms.SplitContainer(); + this.gbDatInfo = new System.Windows.Forms.GroupBox(); + this.lblDIRomsUnknown = new System.Windows.Forms.Label(); + this.label9 = new System.Windows.Forms.Label(); + this.lblDITRomsUnknown = new System.Windows.Forms.Label(); + this.lblDITRomsFixable = new System.Windows.Forms.Label(); + this.lblDITRomsMissing = new System.Windows.Forms.Label(); + this.lblDITRomsGot = new System.Windows.Forms.Label(); + this.lblDITRomPath = new System.Windows.Forms.Label(); + this.lblDITPath = new System.Windows.Forms.Label(); + this.lblDIDate = new System.Windows.Forms.Label(); + this.lblDIAuthor = new System.Windows.Forms.Label(); + this.lblDITDate = new System.Windows.Forms.Label(); + this.lblDITAuthor = new System.Windows.Forms.Label(); + this.lblDIVersion = new System.Windows.Forms.Label(); + this.lblDICategory = new System.Windows.Forms.Label(); + this.lblDITVersion = new System.Windows.Forms.Label(); + this.lblDITCategory = new System.Windows.Forms.Label(); + this.lblDIDescription = new System.Windows.Forms.Label(); + this.lblDIName = new System.Windows.Forms.Label(); + this.lblDITDescription = new System.Windows.Forms.Label(); + this.lblDITName = new System.Windows.Forms.Label(); + this.lblDIRomsFixable = new System.Windows.Forms.Label(); + this.label8 = new System.Windows.Forms.Label(); + this.DirTree = new ROMVault2.RvTree(); + this.splitContainer4 = new System.Windows.Forms.SplitContainer(); + this.btnColorKey = new System.Windows.Forms.Button(); + this.chkBoxShowMerged = new System.Windows.Forms.CheckBox(); + this.chkBoxShowFixed = new System.Windows.Forms.CheckBox(); + this.chkBoxShowMissing = new System.Windows.Forms.CheckBox(); + this.chkBoxShowCorrect = new System.Windows.Forms.CheckBox(); + this.gbSetInfo = new System.Windows.Forms.GroupBox(); + this.splitContainer5 = new System.Windows.Forms.SplitContainer(); + this.GameGrid = new System.Windows.Forms.DataGridView(); + this.Type = new System.Windows.Forms.DataGridViewImageColumn(); + this.CGame = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.CDescription = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.CCorrect = new System.Windows.Forms.DataGridViewImageColumn(); + this.RomGrid = new System.Windows.Forms.DataGridView(); + this.CGot = new System.Windows.Forms.DataGridViewImageColumn(); + this.CRom = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.CSize = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.CMerge = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.CCRC32 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.CSHA1 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.CMD5 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.CStatus = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.ZipIndex = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.ZipHeader = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.menuStrip1 = new System.Windows.Forms.MenuStrip(); + this.tsmUpdateDATs = new System.Windows.Forms.ToolStripMenuItem(); + this.tsmScanROMs = new System.Windows.Forms.ToolStripMenuItem(); + this.tsmScanLevel1 = new System.Windows.Forms.ToolStripMenuItem(); + this.tsmScanLevel2 = new System.Windows.Forms.ToolStripMenuItem(); + this.tsmScanLevel3 = new System.Windows.Forms.ToolStripMenuItem(); + this.tsmFindFixes = new System.Windows.Forms.ToolStripMenuItem(); + this.FixROMsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.settingsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.reportsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.fixDatReportToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.fullReportToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.fixReportToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.helpToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.aboutRomVaultToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.checkForUpdateToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.registratioToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.dataGridViewImageColumn1 = new System.Windows.Forms.DataGridViewImageColumn(); + this.dataGridViewImageColumn2 = new System.Windows.Forms.DataGridViewImageColumn(); + this.dataGridViewImageColumn3 = new System.Windows.Forms.DataGridViewImageColumn(); + this.splitContainer1.Panel1.SuspendLayout(); + this.splitContainer1.Panel2.SuspendLayout(); + this.splitContainer1.SuspendLayout(); + this.splitContainer2.Panel1.SuspendLayout(); + this.splitContainer2.Panel2.SuspendLayout(); + this.splitContainer2.SuspendLayout(); + this.splitContainer3.Panel1.SuspendLayout(); + this.splitContainer3.Panel2.SuspendLayout(); + this.splitContainer3.SuspendLayout(); + this.gbDatInfo.SuspendLayout(); + this.splitContainer4.Panel1.SuspendLayout(); + this.splitContainer4.Panel2.SuspendLayout(); + this.splitContainer4.SuspendLayout(); + this.splitContainer5.Panel1.SuspendLayout(); + this.splitContainer5.Panel2.SuspendLayout(); + this.splitContainer5.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.GameGrid)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.RomGrid)).BeginInit(); + this.menuStrip1.SuspendLayout(); + this.SuspendLayout(); + // + // splitContainer1 + // + this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill; + this.splitContainer1.FixedPanel = System.Windows.Forms.FixedPanel.Panel1; + this.splitContainer1.IsSplitterFixed = true; + this.splitContainer1.Location = new System.Drawing.Point(0, 24); + this.splitContainer1.Name = "splitContainer1"; + // + // splitContainer1.Panel1 + // + this.splitContainer1.Panel1.BackColor = System.Drawing.Color.White; + this.splitContainer1.Panel1.Controls.Add(this.btnReport); + this.splitContainer1.Panel1.Controls.Add(this.btnFixFiles); + this.splitContainer1.Panel1.Controls.Add(this.btnFindFixes); + this.splitContainer1.Panel1.Controls.Add(this.btnScanRoms); + this.splitContainer1.Panel1.Controls.Add(this.btnUpdateDats); + // + // splitContainer1.Panel2 + // + this.splitContainer1.Panel2.Controls.Add(this.splitContainer2); + this.splitContainer1.Size = new System.Drawing.Size(1264, 738); + this.splitContainer1.SplitterDistance = 80; + this.splitContainer1.TabIndex = 5; + // + // btnReport + // + this.btnReport.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("btnReport.BackgroundImage"))); + this.btnReport.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch; + this.btnReport.Location = new System.Drawing.Point(0, 320); + this.btnReport.Name = "btnReport"; + this.btnReport.Size = new System.Drawing.Size(80, 80); + this.btnReport.TabIndex = 13; + this.btnReport.Text = "Generate Reports"; + this.btnReport.TextAlign = System.Drawing.ContentAlignment.BottomCenter; + this.btnReport.UseVisualStyleBackColor = true; + this.btnReport.Click += new System.EventHandler(this.BtnReportClick); + // + // btnFixFiles + // + this.btnFixFiles.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("btnFixFiles.BackgroundImage"))); + this.btnFixFiles.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch; + this.btnFixFiles.Location = new System.Drawing.Point(0, 240); + this.btnFixFiles.Name = "btnFixFiles"; + this.btnFixFiles.Size = new System.Drawing.Size(80, 80); + this.btnFixFiles.TabIndex = 10; + this.btnFixFiles.Text = "Fix ROMs"; + this.btnFixFiles.TextAlign = System.Drawing.ContentAlignment.BottomCenter; + this.btnFixFiles.UseVisualStyleBackColor = true; + this.btnFixFiles.Click += new System.EventHandler(this.BtnFixFilesClick); + // + // btnFindFixes + // + this.btnFindFixes.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("btnFindFixes.BackgroundImage"))); + this.btnFindFixes.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch; + this.btnFindFixes.Location = new System.Drawing.Point(0, 160); + this.btnFindFixes.Name = "btnFindFixes"; + this.btnFindFixes.Size = new System.Drawing.Size(80, 80); + this.btnFindFixes.TabIndex = 9; + this.btnFindFixes.Text = "Find Fixes"; + this.btnFindFixes.TextAlign = System.Drawing.ContentAlignment.BottomCenter; + this.btnFindFixes.UseVisualStyleBackColor = true; + this.btnFindFixes.Click += new System.EventHandler(this.BtnFindFixesClick); + // + // btnScanRoms + // + this.btnScanRoms.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("btnScanRoms.BackgroundImage"))); + this.btnScanRoms.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch; + this.btnScanRoms.Location = new System.Drawing.Point(0, 80); + this.btnScanRoms.Name = "btnScanRoms"; + this.btnScanRoms.Size = new System.Drawing.Size(80, 80); + this.btnScanRoms.TabIndex = 8; + this.btnScanRoms.Text = "Scan ROMs"; + this.btnScanRoms.TextAlign = System.Drawing.ContentAlignment.BottomCenter; + this.btnScanRoms.UseVisualStyleBackColor = true; + this.btnScanRoms.Click += new System.EventHandler(this.BtnScanRomsClick); + // + // btnUpdateDats + // + this.btnUpdateDats.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("btnUpdateDats.BackgroundImage"))); + this.btnUpdateDats.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch; + this.btnUpdateDats.Location = new System.Drawing.Point(0, 0); + this.btnUpdateDats.Name = "btnUpdateDats"; + this.btnUpdateDats.Size = new System.Drawing.Size(80, 80); + this.btnUpdateDats.TabIndex = 0; + this.btnUpdateDats.Text = "Update DATs"; + this.btnUpdateDats.TextAlign = System.Drawing.ContentAlignment.BottomCenter; + this.btnUpdateDats.UseVisualStyleBackColor = true; + this.btnUpdateDats.Click += new System.EventHandler(this.BtnUpdateDatsClick); + // + // splitContainer2 + // + this.splitContainer2.Dock = System.Windows.Forms.DockStyle.Fill; + this.splitContainer2.Location = new System.Drawing.Point(0, 0); + this.splitContainer2.Name = "splitContainer2"; + // + // splitContainer2.Panel1 + // + this.splitContainer2.Panel1.Controls.Add(this.splitContainer3); + this.splitContainer2.Panel1MinSize = 450; + // + // splitContainer2.Panel2 + // + this.splitContainer2.Panel2.Controls.Add(this.splitContainer4); + this.splitContainer2.Size = new System.Drawing.Size(1180, 738); + this.splitContainer2.SplitterDistance = 479; + this.splitContainer2.TabIndex = 0; + // + // splitContainer3 + // + this.splitContainer3.Dock = System.Windows.Forms.DockStyle.Fill; + this.splitContainer3.FixedPanel = System.Windows.Forms.FixedPanel.Panel1; + this.splitContainer3.IsSplitterFixed = true; + this.splitContainer3.Location = new System.Drawing.Point(0, 0); + this.splitContainer3.Name = "splitContainer3"; + this.splitContainer3.Orientation = System.Windows.Forms.Orientation.Horizontal; + // + // splitContainer3.Panel1 + // + this.splitContainer3.Panel1.Controls.Add(this.gbDatInfo); + this.splitContainer3.Panel1.Resize += new System.EventHandler(this.splitContainer3_Panel1_Resize); + // + // splitContainer3.Panel2 + // + this.splitContainer3.Panel2.Controls.Add(this.DirTree); + this.splitContainer3.Size = new System.Drawing.Size(479, 738); + this.splitContainer3.SplitterDistance = 148; + this.splitContainer3.TabIndex = 0; + // + // gbDatInfo + // + this.gbDatInfo.Controls.Add(this.lblDIRomsUnknown); + this.gbDatInfo.Controls.Add(this.label9); + this.gbDatInfo.Controls.Add(this.lblDITRomsUnknown); + this.gbDatInfo.Controls.Add(this.lblDITRomsFixable); + this.gbDatInfo.Controls.Add(this.lblDITRomsMissing); + this.gbDatInfo.Controls.Add(this.lblDITRomsGot); + this.gbDatInfo.Controls.Add(this.lblDITRomPath); + this.gbDatInfo.Controls.Add(this.lblDITPath); + this.gbDatInfo.Controls.Add(this.lblDIDate); + this.gbDatInfo.Controls.Add(this.lblDIAuthor); + this.gbDatInfo.Controls.Add(this.lblDITDate); + this.gbDatInfo.Controls.Add(this.lblDITAuthor); + this.gbDatInfo.Controls.Add(this.lblDIVersion); + this.gbDatInfo.Controls.Add(this.lblDICategory); + this.gbDatInfo.Controls.Add(this.lblDITVersion); + this.gbDatInfo.Controls.Add(this.lblDITCategory); + this.gbDatInfo.Controls.Add(this.lblDIDescription); + this.gbDatInfo.Controls.Add(this.lblDIName); + this.gbDatInfo.Controls.Add(this.lblDITDescription); + this.gbDatInfo.Controls.Add(this.lblDITName); + this.gbDatInfo.Controls.Add(this.lblDIRomsFixable); + this.gbDatInfo.Controls.Add(this.label8); + this.gbDatInfo.Location = new System.Drawing.Point(5, 0); + this.gbDatInfo.Name = "gbDatInfo"; + this.gbDatInfo.Size = new System.Drawing.Size(440, 147); + this.gbDatInfo.TabIndex = 3; + this.gbDatInfo.TabStop = false; + this.gbDatInfo.Text = "Dat Info :"; + this.gbDatInfo.Resize += new System.EventHandler(this.gbDatInfo_Resize); + // + // lblDIRomsUnknown + // + this.lblDIRomsUnknown.Location = new System.Drawing.Point(214, 121); + this.lblDIRomsUnknown.Name = "lblDIRomsUnknown"; + this.lblDIRomsUnknown.Size = new System.Drawing.Size(92, 13); + this.lblDIRomsUnknown.TabIndex = 26; + this.lblDIRomsUnknown.Text = "ROMs Unknown :"; + this.lblDIRomsUnknown.TextAlign = System.Drawing.ContentAlignment.TopRight; + // + // label9 + // + this.label9.Location = new System.Drawing.Point(10, 105); + this.label9.Name = "label9"; + this.label9.Size = new System.Drawing.Size(75, 13); + this.label9.TabIndex = 23; + this.label9.Text = "ROMs Got :"; + this.label9.TextAlign = System.Drawing.ContentAlignment.TopRight; + // + // lblDITRomsUnknown + // + this.lblDITRomsUnknown.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.lblDITRomsUnknown.Location = new System.Drawing.Point(311, 120); + this.lblDITRomsUnknown.Name = "lblDITRomsUnknown"; + this.lblDITRomsUnknown.Size = new System.Drawing.Size(120, 17); + this.lblDITRomsUnknown.TabIndex = 21; + // + // lblDITRomsFixable + // + this.lblDITRomsFixable.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.lblDITRomsFixable.Location = new System.Drawing.Point(311, 104); + this.lblDITRomsFixable.Name = "lblDITRomsFixable"; + this.lblDITRomsFixable.Size = new System.Drawing.Size(120, 17); + this.lblDITRomsFixable.TabIndex = 20; + // + // lblDITRomsMissing + // + this.lblDITRomsMissing.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.lblDITRomsMissing.Location = new System.Drawing.Point(89, 120); + this.lblDITRomsMissing.Name = "lblDITRomsMissing"; + this.lblDITRomsMissing.Size = new System.Drawing.Size(120, 17); + this.lblDITRomsMissing.TabIndex = 19; + // + // lblDITRomsGot + // + this.lblDITRomsGot.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.lblDITRomsGot.Location = new System.Drawing.Point(89, 104); + this.lblDITRomsGot.Name = "lblDITRomsGot"; + this.lblDITRomsGot.Size = new System.Drawing.Size(120, 17); + this.lblDITRomsGot.TabIndex = 18; + // + // lblDITRomPath + // + this.lblDITRomPath.Location = new System.Drawing.Point(10, 79); + this.lblDITRomPath.Name = "lblDITRomPath"; + this.lblDITRomPath.Size = new System.Drawing.Size(75, 13); + this.lblDITRomPath.TabIndex = 15; + this.lblDITRomPath.Text = "ROM Path:"; + this.lblDITRomPath.TextAlign = System.Drawing.ContentAlignment.TopRight; + // + // lblDITPath + // + this.lblDITPath.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.lblDITPath.Location = new System.Drawing.Point(89, 78); + this.lblDITPath.Name = "lblDITPath"; + this.lblDITPath.Size = new System.Drawing.Size(342, 17); + this.lblDITPath.TabIndex = 13; + // + // lblDIDate + // + this.lblDIDate.Location = new System.Drawing.Point(214, 63); + this.lblDIDate.Name = "lblDIDate"; + this.lblDIDate.Size = new System.Drawing.Size(92, 13); + this.lblDIDate.TabIndex = 12; + this.lblDIDate.Text = "Date :"; + this.lblDIDate.TextAlign = System.Drawing.ContentAlignment.TopRight; + // + // lblDIAuthor + // + this.lblDIAuthor.Location = new System.Drawing.Point(10, 63); + this.lblDIAuthor.Name = "lblDIAuthor"; + this.lblDIAuthor.Size = new System.Drawing.Size(75, 13); + this.lblDIAuthor.TabIndex = 11; + this.lblDIAuthor.Text = "Author :"; + this.lblDIAuthor.TextAlign = System.Drawing.ContentAlignment.TopRight; + // + // lblDITDate + // + this.lblDITDate.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.lblDITDate.Location = new System.Drawing.Point(311, 62); + this.lblDITDate.Name = "lblDITDate"; + this.lblDITDate.Size = new System.Drawing.Size(120, 17); + this.lblDITDate.TabIndex = 10; + // + // lblDITAuthor + // + this.lblDITAuthor.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.lblDITAuthor.Location = new System.Drawing.Point(89, 62); + this.lblDITAuthor.Name = "lblDITAuthor"; + this.lblDITAuthor.Size = new System.Drawing.Size(120, 17); + this.lblDITAuthor.TabIndex = 9; + // + // lblDIVersion + // + this.lblDIVersion.Location = new System.Drawing.Point(214, 47); + this.lblDIVersion.Name = "lblDIVersion"; + this.lblDIVersion.Size = new System.Drawing.Size(92, 13); + this.lblDIVersion.TabIndex = 8; + this.lblDIVersion.Text = "Version :"; + this.lblDIVersion.TextAlign = System.Drawing.ContentAlignment.TopRight; + // + // lblDICategory + // + this.lblDICategory.Location = new System.Drawing.Point(10, 47); + this.lblDICategory.Name = "lblDICategory"; + this.lblDICategory.Size = new System.Drawing.Size(75, 13); + this.lblDICategory.TabIndex = 7; + this.lblDICategory.Text = "Category :"; + this.lblDICategory.TextAlign = System.Drawing.ContentAlignment.TopRight; + // + // lblDITVersion + // + this.lblDITVersion.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.lblDITVersion.Location = new System.Drawing.Point(311, 46); + this.lblDITVersion.Name = "lblDITVersion"; + this.lblDITVersion.Size = new System.Drawing.Size(120, 17); + this.lblDITVersion.TabIndex = 6; + // + // lblDITCategory + // + this.lblDITCategory.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.lblDITCategory.Location = new System.Drawing.Point(89, 46); + this.lblDITCategory.Name = "lblDITCategory"; + this.lblDITCategory.Size = new System.Drawing.Size(120, 17); + this.lblDITCategory.TabIndex = 5; + // + // lblDIDescription + // + this.lblDIDescription.Location = new System.Drawing.Point(10, 31); + this.lblDIDescription.Name = "lblDIDescription"; + this.lblDIDescription.Size = new System.Drawing.Size(75, 13); + this.lblDIDescription.TabIndex = 4; + this.lblDIDescription.Text = "Description :"; + this.lblDIDescription.TextAlign = System.Drawing.ContentAlignment.TopRight; + // + // lblDIName + // + this.lblDIName.Location = new System.Drawing.Point(10, 15); + this.lblDIName.Name = "lblDIName"; + this.lblDIName.Size = new System.Drawing.Size(75, 13); + this.lblDIName.TabIndex = 3; + this.lblDIName.Text = "Name :"; + this.lblDIName.TextAlign = System.Drawing.ContentAlignment.TopRight; + // + // lblDITDescription + // + this.lblDITDescription.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.lblDITDescription.Location = new System.Drawing.Point(89, 30); + this.lblDITDescription.Name = "lblDITDescription"; + this.lblDITDescription.Size = new System.Drawing.Size(342, 17); + this.lblDITDescription.TabIndex = 2; + // + // lblDITName + // + this.lblDITName.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.lblDITName.Location = new System.Drawing.Point(89, 14); + this.lblDITName.Name = "lblDITName"; + this.lblDITName.Size = new System.Drawing.Size(342, 17); + this.lblDITName.TabIndex = 1; + // + // lblDIRomsFixable + // + this.lblDIRomsFixable.Location = new System.Drawing.Point(214, 105); + this.lblDIRomsFixable.Name = "lblDIRomsFixable"; + this.lblDIRomsFixable.Size = new System.Drawing.Size(92, 13); + this.lblDIRomsFixable.TabIndex = 25; + this.lblDIRomsFixable.Text = "ROMs Fixable :"; + this.lblDIRomsFixable.TextAlign = System.Drawing.ContentAlignment.TopRight; + // + // label8 + // + this.label8.Location = new System.Drawing.Point(2, 121); + this.label8.Name = "label8"; + this.label8.Size = new System.Drawing.Size(83, 13); + this.label8.TabIndex = 24; + this.label8.Text = "ROMs Missing :"; + this.label8.TextAlign = System.Drawing.ContentAlignment.TopRight; + // + // DirTree + // + this.DirTree.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.DirTree.Dock = System.Windows.Forms.DockStyle.Fill; + this.DirTree.Location = new System.Drawing.Point(0, 0); + this.DirTree.Name = "DirTree"; + this.DirTree.Size = new System.Drawing.Size(479, 586); + this.DirTree.TabIndex = 2; + this.DirTree.RvSelected += new System.Windows.Forms.MouseEventHandler(this.DirTreeRvSelected); + // + // splitContainer4 + // + this.splitContainer4.Dock = System.Windows.Forms.DockStyle.Fill; + this.splitContainer4.FixedPanel = System.Windows.Forms.FixedPanel.Panel1; + this.splitContainer4.IsSplitterFixed = true; + this.splitContainer4.Location = new System.Drawing.Point(0, 0); + this.splitContainer4.Name = "splitContainer4"; + this.splitContainer4.Orientation = System.Windows.Forms.Orientation.Horizontal; + // + // splitContainer4.Panel1 + // + this.splitContainer4.Panel1.Controls.Add(this.btnColorKey); + this.splitContainer4.Panel1.Controls.Add(this.chkBoxShowMerged); + this.splitContainer4.Panel1.Controls.Add(this.chkBoxShowFixed); + this.splitContainer4.Panel1.Controls.Add(this.chkBoxShowMissing); + this.splitContainer4.Panel1.Controls.Add(this.chkBoxShowCorrect); + this.splitContainer4.Panel1.Controls.Add(this.gbSetInfo); + this.splitContainer4.Panel1.Resize += new System.EventHandler(this.splitContainer4_Panel1_Resize); + // + // splitContainer4.Panel2 + // + this.splitContainer4.Panel2.Controls.Add(this.splitContainer5); + this.splitContainer4.Size = new System.Drawing.Size(697, 738); + this.splitContainer4.SplitterDistance = 148; + this.splitContainer4.TabIndex = 0; + // + // btnColorKey + // + this.btnColorKey.Location = new System.Drawing.Point(568, 85); + this.btnColorKey.Name = "btnColorKey"; + this.btnColorKey.Size = new System.Drawing.Size(89, 23); + this.btnColorKey.TabIndex = 9; + this.btnColorKey.Text = "Color Key"; + this.btnColorKey.UseVisualStyleBackColor = true; + this.btnColorKey.Click += new System.EventHandler(this.BtnColorKeyClick); + // + // chkBoxShowMerged + // + this.chkBoxShowMerged.AutoSize = true; + this.chkBoxShowMerged.Location = new System.Drawing.Point(568, 68); + this.chkBoxShowMerged.Name = "chkBoxShowMerged"; + this.chkBoxShowMerged.Size = new System.Drawing.Size(125, 17); + this.chkBoxShowMerged.TabIndex = 8; + this.chkBoxShowMerged.Text = "Show Merged ROMs"; + this.chkBoxShowMerged.UseVisualStyleBackColor = true; + this.chkBoxShowMerged.CheckedChanged += new System.EventHandler(this.ChkBoxShowMergedCheckedChanged); + // + // chkBoxShowFixed + // + this.chkBoxShowFixed.AutoSize = true; + this.chkBoxShowFixed.Checked = true; + this.chkBoxShowFixed.CheckState = System.Windows.Forms.CheckState.Checked; + this.chkBoxShowFixed.Location = new System.Drawing.Point(568, 52); + this.chkBoxShowFixed.Name = "chkBoxShowFixed"; + this.chkBoxShowFixed.Size = new System.Drawing.Size(102, 17); + this.chkBoxShowFixed.TabIndex = 7; + this.chkBoxShowFixed.Text = "Show Fix ROMs"; + this.chkBoxShowFixed.UseVisualStyleBackColor = true; + this.chkBoxShowFixed.CheckedChanged += new System.EventHandler(this.ChkBoxShowFixedCheckedChanged); + // + // chkBoxShowMissing + // + this.chkBoxShowMissing.AutoSize = true; + this.chkBoxShowMissing.Checked = true; + this.chkBoxShowMissing.CheckState = System.Windows.Forms.CheckState.Checked; + this.chkBoxShowMissing.Location = new System.Drawing.Point(568, 36); + this.chkBoxShowMissing.Name = "chkBoxShowMissing"; + this.chkBoxShowMissing.Size = new System.Drawing.Size(124, 17); + this.chkBoxShowMissing.TabIndex = 6; + this.chkBoxShowMissing.Text = "Show Missing ROMs"; + this.chkBoxShowMissing.UseVisualStyleBackColor = true; + this.chkBoxShowMissing.CheckedChanged += new System.EventHandler(this.ChkBoxShowMissingCheckedChanged); + // + // chkBoxShowCorrect + // + this.chkBoxShowCorrect.AutoSize = true; + this.chkBoxShowCorrect.Checked = true; + this.chkBoxShowCorrect.CheckState = System.Windows.Forms.CheckState.Checked; + this.chkBoxShowCorrect.Location = new System.Drawing.Point(568, 20); + this.chkBoxShowCorrect.Name = "chkBoxShowCorrect"; + this.chkBoxShowCorrect.Size = new System.Drawing.Size(123, 17); + this.chkBoxShowCorrect.TabIndex = 5; + this.chkBoxShowCorrect.Text = "Show Correct ROMs"; + this.chkBoxShowCorrect.UseVisualStyleBackColor = true; + this.chkBoxShowCorrect.CheckedChanged += new System.EventHandler(this.ChkBoxShowCorrectCheckedChanged); + // + // gbSetInfo + // + this.gbSetInfo.Location = new System.Drawing.Point(5, 0); + this.gbSetInfo.Name = "gbSetInfo"; + this.gbSetInfo.Size = new System.Drawing.Size(416, 147); + this.gbSetInfo.TabIndex = 4; + this.gbSetInfo.TabStop = false; + this.gbSetInfo.Text = "Game Info :"; + this.gbSetInfo.Resize += new System.EventHandler(this.gbSetInfo_Resize); + // + // splitContainer5 + // + this.splitContainer5.Dock = System.Windows.Forms.DockStyle.Fill; + this.splitContainer5.Location = new System.Drawing.Point(0, 0); + this.splitContainer5.Name = "splitContainer5"; + this.splitContainer5.Orientation = System.Windows.Forms.Orientation.Horizontal; + // + // splitContainer5.Panel1 + // + this.splitContainer5.Panel1.Controls.Add(this.GameGrid); + // + // splitContainer5.Panel2 + // + this.splitContainer5.Panel2.Controls.Add(this.RomGrid); + this.splitContainer5.Size = new System.Drawing.Size(697, 586); + this.splitContainer5.SplitterDistance = 267; + this.splitContainer5.TabIndex = 0; + // + // GameGrid + // + this.GameGrid.AllowUserToAddRows = false; + this.GameGrid.AllowUserToDeleteRows = false; + this.GameGrid.AllowUserToResizeRows = false; + this.GameGrid.BackgroundColor = System.Drawing.Color.White; + dataGridViewCellStyle1.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; + dataGridViewCellStyle1.BackColor = System.Drawing.SystemColors.Control; + dataGridViewCellStyle1.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + dataGridViewCellStyle1.ForeColor = System.Drawing.SystemColors.WindowText; + dataGridViewCellStyle1.SelectionBackColor = System.Drawing.SystemColors.Highlight; + dataGridViewCellStyle1.SelectionForeColor = System.Drawing.SystemColors.HighlightText; + dataGridViewCellStyle1.WrapMode = System.Windows.Forms.DataGridViewTriState.True; + this.GameGrid.ColumnHeadersDefaultCellStyle = dataGridViewCellStyle1; + this.GameGrid.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; + this.GameGrid.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { + this.Type, + this.CGame, + this.CDescription, + this.CCorrect}); + dataGridViewCellStyle2.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; + dataGridViewCellStyle2.BackColor = System.Drawing.SystemColors.Window; + dataGridViewCellStyle2.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + dataGridViewCellStyle2.ForeColor = System.Drawing.SystemColors.ControlText; + dataGridViewCellStyle2.SelectionBackColor = System.Drawing.SystemColors.Highlight; + dataGridViewCellStyle2.SelectionForeColor = System.Drawing.SystemColors.HighlightText; + dataGridViewCellStyle2.WrapMode = System.Windows.Forms.DataGridViewTriState.False; + this.GameGrid.DefaultCellStyle = dataGridViewCellStyle2; + this.GameGrid.Dock = System.Windows.Forms.DockStyle.Fill; + this.GameGrid.GridColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224))))); + this.GameGrid.Location = new System.Drawing.Point(0, 0); + this.GameGrid.MultiSelect = false; + this.GameGrid.Name = "GameGrid"; + this.GameGrid.ReadOnly = true; + dataGridViewCellStyle3.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; + dataGridViewCellStyle3.BackColor = System.Drawing.SystemColors.Control; + dataGridViewCellStyle3.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + dataGridViewCellStyle3.ForeColor = System.Drawing.SystemColors.WindowText; + dataGridViewCellStyle3.SelectionBackColor = System.Drawing.SystemColors.Highlight; + dataGridViewCellStyle3.SelectionForeColor = System.Drawing.SystemColors.HighlightText; + dataGridViewCellStyle3.WrapMode = System.Windows.Forms.DataGridViewTriState.True; + this.GameGrid.RowHeadersDefaultCellStyle = dataGridViewCellStyle3; + this.GameGrid.RowHeadersVisible = false; + this.GameGrid.RowTemplate.Height = 17; + this.GameGrid.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect; + this.GameGrid.ShowCellErrors = false; + this.GameGrid.ShowCellToolTips = false; + this.GameGrid.ShowEditingIcon = false; + this.GameGrid.ShowRowErrors = false; + this.GameGrid.Size = new System.Drawing.Size(697, 267); + this.GameGrid.TabIndex = 4; + this.GameGrid.SelectionChanged += new System.EventHandler(this.GameGridSelectionChanged); + this.GameGrid.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.GameGridMouseDoubleClick); + this.GameGrid.MouseUp += new System.Windows.Forms.MouseEventHandler(this.GameGrid_MouseUp); + // + // Type + // + this.Type.FillWeight = 40F; + this.Type.HeaderText = "Type"; + this.Type.Name = "Type"; + this.Type.ReadOnly = true; + this.Type.Resizable = System.Windows.Forms.DataGridViewTriState.True; + this.Type.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Automatic; + this.Type.Width = 40; + // + // CGame + // + this.CGame.HeaderText = "Game (Directory / Zip)"; + this.CGame.Name = "CGame"; + this.CGame.ReadOnly = true; + this.CGame.Width = 220; + // + // CDescription + // + this.CDescription.HeaderText = "Description"; + this.CDescription.Name = "CDescription"; + this.CDescription.ReadOnly = true; + this.CDescription.Width = 220; + // + // CCorrect + // + this.CCorrect.HeaderText = "ROM Status"; + this.CCorrect.Name = "CCorrect"; + this.CCorrect.ReadOnly = true; + this.CCorrect.Resizable = System.Windows.Forms.DataGridViewTriState.False; + this.CCorrect.Width = 500; + // + // RomGrid + // + this.RomGrid.AllowUserToAddRows = false; + this.RomGrid.AllowUserToDeleteRows = false; + this.RomGrid.AllowUserToResizeRows = false; + this.RomGrid.BackgroundColor = System.Drawing.Color.White; + dataGridViewCellStyle4.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; + dataGridViewCellStyle4.BackColor = System.Drawing.SystemColors.Control; + dataGridViewCellStyle4.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + dataGridViewCellStyle4.ForeColor = System.Drawing.SystemColors.WindowText; + dataGridViewCellStyle4.SelectionBackColor = System.Drawing.SystemColors.Highlight; + dataGridViewCellStyle4.SelectionForeColor = System.Drawing.SystemColors.HighlightText; + dataGridViewCellStyle4.WrapMode = System.Windows.Forms.DataGridViewTriState.True; + this.RomGrid.ColumnHeadersDefaultCellStyle = dataGridViewCellStyle4; + this.RomGrid.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; + this.RomGrid.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { + this.CGot, + this.CRom, + this.CSize, + this.CMerge, + this.CCRC32, + this.CSHA1, + this.CMD5, + this.CStatus, + this.ZipIndex, + this.ZipHeader}); + dataGridViewCellStyle5.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; + dataGridViewCellStyle5.BackColor = System.Drawing.SystemColors.Window; + dataGridViewCellStyle5.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + dataGridViewCellStyle5.ForeColor = System.Drawing.SystemColors.ControlText; + dataGridViewCellStyle5.SelectionBackColor = System.Drawing.SystemColors.Highlight; + dataGridViewCellStyle5.SelectionForeColor = System.Drawing.SystemColors.HighlightText; + dataGridViewCellStyle5.WrapMode = System.Windows.Forms.DataGridViewTriState.False; + this.RomGrid.DefaultCellStyle = dataGridViewCellStyle5; + this.RomGrid.Dock = System.Windows.Forms.DockStyle.Fill; + this.RomGrid.GridColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224))))); + this.RomGrid.Location = new System.Drawing.Point(0, 0); + this.RomGrid.MultiSelect = false; + this.RomGrid.Name = "RomGrid"; + this.RomGrid.ReadOnly = true; + dataGridViewCellStyle6.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; + dataGridViewCellStyle6.BackColor = System.Drawing.SystemColors.Control; + dataGridViewCellStyle6.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + dataGridViewCellStyle6.ForeColor = System.Drawing.SystemColors.WindowText; + dataGridViewCellStyle6.SelectionBackColor = System.Drawing.SystemColors.Highlight; + dataGridViewCellStyle6.SelectionForeColor = System.Drawing.SystemColors.HighlightText; + dataGridViewCellStyle6.WrapMode = System.Windows.Forms.DataGridViewTriState.True; + this.RomGrid.RowHeadersDefaultCellStyle = dataGridViewCellStyle6; + this.RomGrid.RowHeadersVisible = false; + this.RomGrid.RowTemplate.Height = 19; + this.RomGrid.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect; + this.RomGrid.ShowCellErrors = false; + this.RomGrid.ShowEditingIcon = false; + this.RomGrid.ShowRowErrors = false; + this.RomGrid.Size = new System.Drawing.Size(697, 315); + this.RomGrid.TabIndex = 21; + this.RomGrid.SelectionChanged += new System.EventHandler(this.RomGridSelectionChanged); + this.RomGrid.MouseUp += new System.Windows.Forms.MouseEventHandler(this.RomGridMouseUp); + // + // CGot + // + this.CGot.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.None; + this.CGot.HeaderText = "Got"; + this.CGot.Name = "CGot"; + this.CGot.ReadOnly = true; + this.CGot.Resizable = System.Windows.Forms.DataGridViewTriState.True; + this.CGot.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Automatic; + this.CGot.Width = 65; + // + // CRom + // + this.CRom.HeaderText = "ROM (File)"; + this.CRom.Name = "CRom"; + this.CRom.ReadOnly = true; + this.CRom.Width = 150; + // + // CSize + // + this.CSize.HeaderText = "Size"; + this.CSize.Name = "CSize"; + this.CSize.ReadOnly = true; + this.CSize.Width = 60; + // + // CMerge + // + this.CMerge.HeaderText = "Merge"; + this.CMerge.Name = "CMerge"; + this.CMerge.ReadOnly = true; + this.CMerge.Width = 60; + // + // CCRC32 + // + this.CCRC32.HeaderText = "CRC32"; + this.CCRC32.Name = "CCRC32"; + this.CCRC32.ReadOnly = true; + // + // CSHA1 + // + this.CSHA1.HeaderText = "SHA1"; + this.CSHA1.Name = "CSHA1"; + this.CSHA1.ReadOnly = true; + this.CSHA1.Width = 150; + // + // CMD5 + // + this.CMD5.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.None; + this.CMD5.HeaderText = "MD5"; + this.CMD5.Name = "CMD5"; + this.CMD5.ReadOnly = true; + this.CMD5.Width = 150; + // + // CStatus + // + this.CStatus.HeaderText = "Status"; + this.CStatus.Name = "CStatus"; + this.CStatus.ReadOnly = true; + // + // ZipIndex + // + this.ZipIndex.HeaderText = "ZipIndex"; + this.ZipIndex.Name = "ZipIndex"; + this.ZipIndex.ReadOnly = true; + // + // ZipHeader + // + this.ZipHeader.HeaderText = "ZipHeader"; + this.ZipHeader.Name = "ZipHeader"; + this.ZipHeader.ReadOnly = true; + // + // menuStrip1 + // + this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.tsmUpdateDATs, + this.tsmScanROMs, + this.tsmFindFixes, + this.FixROMsToolStripMenuItem, + this.settingsToolStripMenuItem, + this.reportsToolStripMenuItem, + this.helpToolStripMenuItem}); + this.menuStrip1.Location = new System.Drawing.Point(0, 0); + this.menuStrip1.Name = "menuStrip1"; + this.menuStrip1.Size = new System.Drawing.Size(1264, 24); + this.menuStrip1.TabIndex = 6; + this.menuStrip1.Text = "menuStrip1"; + // + // tsmUpdateDATs + // + this.tsmUpdateDATs.Name = "tsmUpdateDATs"; + this.tsmUpdateDATs.Size = new System.Drawing.Size(88, 20); + this.tsmUpdateDATs.Text = "Update DATs"; + this.tsmUpdateDATs.Click += new System.EventHandler(this.TsmUpdateDaTsClick); + // + // tsmScanROMs + // + this.tsmScanROMs.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.tsmScanLevel1, + this.tsmScanLevel2, + this.tsmScanLevel3}); + this.tsmScanROMs.Name = "tsmScanROMs"; + this.tsmScanROMs.Size = new System.Drawing.Size(79, 20); + this.tsmScanROMs.Text = "Scan ROMs"; + // + // tsmScanLevel1 + // + this.tsmScanLevel1.Name = "tsmScanLevel1"; + this.tsmScanLevel1.Size = new System.Drawing.Size(300, 22); + this.tsmScanLevel1.Text = "Level 1: Scan ROMs"; + this.tsmScanLevel1.Click += new System.EventHandler(this.TsmScanLevel1Click); + // + // tsmScanLevel2 + // + this.tsmScanLevel2.Name = "tsmScanLevel2"; + this.tsmScanLevel2.Size = new System.Drawing.Size(300, 22); + this.tsmScanLevel2.Text = "Level 2: ReScan New ROMs"; + this.tsmScanLevel2.Click += new System.EventHandler(this.TsmScanLevel2Click); + // + // tsmScanLevel3 + // + this.tsmScanLevel3.Name = "tsmScanLevel3"; + this.tsmScanLevel3.Size = new System.Drawing.Size(300, 22); + this.tsmScanLevel3.Text = "Level 3: ReScan All ROMs (CRC,MD5,SHA1)"; + this.tsmScanLevel3.Click += new System.EventHandler(this.TsmScanLevel3Click); + // + // tsmFindFixes + // + this.tsmFindFixes.Name = "tsmFindFixes"; + this.tsmFindFixes.Size = new System.Drawing.Size(70, 20); + this.tsmFindFixes.Text = "Find Fixes"; + this.tsmFindFixes.Click += new System.EventHandler(this.TsmFindFixesClick); + // + // FixROMsToolStripMenuItem + // + this.FixROMsToolStripMenuItem.Name = "FixROMsToolStripMenuItem"; + this.FixROMsToolStripMenuItem.Size = new System.Drawing.Size(68, 20); + this.FixROMsToolStripMenuItem.Text = "Fix ROMs"; + this.FixROMsToolStripMenuItem.Click += new System.EventHandler(this.FixFilesToolStripMenuItemClick); + // + // settingsToolStripMenuItem + // + this.settingsToolStripMenuItem.Name = "settingsToolStripMenuItem"; + this.settingsToolStripMenuItem.Size = new System.Drawing.Size(61, 20); + this.settingsToolStripMenuItem.Text = "Settings"; + this.settingsToolStripMenuItem.Click += new System.EventHandler(this.SettingsToolStripMenuItemClick); + // + // reportsToolStripMenuItem + // + this.reportsToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.fixDatReportToolStripMenuItem, + this.fullReportToolStripMenuItem, + this.fixReportToolStripMenuItem}); + this.reportsToolStripMenuItem.Name = "reportsToolStripMenuItem"; + this.reportsToolStripMenuItem.Size = new System.Drawing.Size(59, 20); + this.reportsToolStripMenuItem.Text = "Reports"; + // + // fixDatReportToolStripMenuItem + // + this.fixDatReportToolStripMenuItem.Name = "fixDatReportToolStripMenuItem"; + this.fixDatReportToolStripMenuItem.Size = new System.Drawing.Size(147, 22); + this.fixDatReportToolStripMenuItem.Text = "Fix Dat Report"; + this.fixDatReportToolStripMenuItem.Click += new System.EventHandler(this.fixDatReportToolStripMenuItem_Click); + // + // fullReportToolStripMenuItem + // + this.fullReportToolStripMenuItem.Name = "fullReportToolStripMenuItem"; + this.fullReportToolStripMenuItem.Size = new System.Drawing.Size(147, 22); + this.fullReportToolStripMenuItem.Text = "Full Report"; + this.fullReportToolStripMenuItem.Click += new System.EventHandler(this.fullReportToolStripMenuItem_Click); + // + // fixReportToolStripMenuItem + // + this.fixReportToolStripMenuItem.Name = "fixReportToolStripMenuItem"; + this.fixReportToolStripMenuItem.Size = new System.Drawing.Size(147, 22); + this.fixReportToolStripMenuItem.Text = "Fix Report"; + this.fixReportToolStripMenuItem.Click += new System.EventHandler(this.fixReportToolStripMenuItem_Click); + // + // helpToolStripMenuItem + // + this.helpToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.aboutRomVaultToolStripMenuItem, + this.checkForUpdateToolStripMenuItem, + this.registratioToolStripMenuItem}); + this.helpToolStripMenuItem.Name = "helpToolStripMenuItem"; + this.helpToolStripMenuItem.Size = new System.Drawing.Size(44, 20); + this.helpToolStripMenuItem.Text = "Help"; + // + // aboutRomVaultToolStripMenuItem + // + this.aboutRomVaultToolStripMenuItem.Name = "aboutRomVaultToolStripMenuItem"; + this.aboutRomVaultToolStripMenuItem.Size = new System.Drawing.Size(168, 22); + this.aboutRomVaultToolStripMenuItem.Text = "About RomVault"; + this.aboutRomVaultToolStripMenuItem.Click += new System.EventHandler(this.AboutRomVaultToolStripMenuItemClick); + // + // checkForUpdateToolStripMenuItem + // + this.checkForUpdateToolStripMenuItem.Name = "checkForUpdateToolStripMenuItem"; + this.checkForUpdateToolStripMenuItem.Size = new System.Drawing.Size(168, 22); + this.checkForUpdateToolStripMenuItem.Text = "Check For Update"; + this.checkForUpdateToolStripMenuItem.Click += new System.EventHandler(this.checkForUpdateToolStripMenuItem_Click); + // + // registratioToolStripMenuItem + // + this.registratioToolStripMenuItem.Name = "registratioToolStripMenuItem"; + this.registratioToolStripMenuItem.Size = new System.Drawing.Size(168, 22); + this.registratioToolStripMenuItem.Text = "Registration"; + this.registratioToolStripMenuItem.Click += new System.EventHandler(this.RegistratioToolStripMenuItemClick); + // + // dataGridViewImageColumn1 + // + this.dataGridViewImageColumn1.FillWeight = 40F; + this.dataGridViewImageColumn1.HeaderText = "Type"; + this.dataGridViewImageColumn1.Name = "dataGridViewImageColumn1"; + this.dataGridViewImageColumn1.ReadOnly = true; + this.dataGridViewImageColumn1.Resizable = System.Windows.Forms.DataGridViewTriState.True; + this.dataGridViewImageColumn1.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Automatic; + this.dataGridViewImageColumn1.Width = 40; + // + // dataGridViewImageColumn2 + // + this.dataGridViewImageColumn2.HeaderText = "ROM Status"; + this.dataGridViewImageColumn2.Name = "dataGridViewImageColumn2"; + this.dataGridViewImageColumn2.ReadOnly = true; + this.dataGridViewImageColumn2.Resizable = System.Windows.Forms.DataGridViewTriState.False; + this.dataGridViewImageColumn2.Width = 300; + // + // dataGridViewImageColumn3 + // + this.dataGridViewImageColumn3.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.None; + this.dataGridViewImageColumn3.HeaderText = "Got"; + this.dataGridViewImageColumn3.Name = "dataGridViewImageColumn3"; + this.dataGridViewImageColumn3.ReadOnly = true; + this.dataGridViewImageColumn3.Resizable = System.Windows.Forms.DataGridViewTriState.True; + this.dataGridViewImageColumn3.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Automatic; + this.dataGridViewImageColumn3.Width = 65; + // + // FrmMain + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(1264, 762); + this.Controls.Add(this.splitContainer1); + this.Controls.Add(this.menuStrip1); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Name = "FrmMain"; + this.Text = "RomVault (V2.0)"; + this.splitContainer1.Panel1.ResumeLayout(false); + this.splitContainer1.Panel2.ResumeLayout(false); + this.splitContainer1.ResumeLayout(false); + this.splitContainer2.Panel1.ResumeLayout(false); + this.splitContainer2.Panel2.ResumeLayout(false); + this.splitContainer2.ResumeLayout(false); + this.splitContainer3.Panel1.ResumeLayout(false); + this.splitContainer3.Panel2.ResumeLayout(false); + this.splitContainer3.ResumeLayout(false); + this.gbDatInfo.ResumeLayout(false); + this.splitContainer4.Panel1.ResumeLayout(false); + this.splitContainer4.Panel1.PerformLayout(); + this.splitContainer4.Panel2.ResumeLayout(false); + this.splitContainer4.ResumeLayout(false); + this.splitContainer5.Panel1.ResumeLayout(false); + this.splitContainer5.Panel2.ResumeLayout(false); + this.splitContainer5.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.GameGrid)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.RomGrid)).EndInit(); + this.menuStrip1.ResumeLayout(false); + this.menuStrip1.PerformLayout(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.SplitContainer splitContainer1; + private System.Windows.Forms.Button btnReport; + private System.Windows.Forms.Button btnFixFiles; + private System.Windows.Forms.Button btnFindFixes; + private System.Windows.Forms.Button btnScanRoms; + private System.Windows.Forms.Button btnUpdateDats; + private System.Windows.Forms.SplitContainer splitContainer2; + private System.Windows.Forms.SplitContainer splitContainer3; + private System.Windows.Forms.GroupBox gbDatInfo; + private System.Windows.Forms.Label lblDIRomsUnknown; + private System.Windows.Forms.Label label8; + private System.Windows.Forms.Label label9; + private System.Windows.Forms.Label lblDITRomsUnknown; + private System.Windows.Forms.Label lblDITRomsMissing; + private System.Windows.Forms.Label lblDITRomsGot; + private System.Windows.Forms.Label lblDITRomPath; + private System.Windows.Forms.Label lblDITPath; + private System.Windows.Forms.Label lblDIDate; + private System.Windows.Forms.Label lblDIAuthor; + private System.Windows.Forms.Label lblDITDate; + private System.Windows.Forms.Label lblDITAuthor; + private System.Windows.Forms.Label lblDIVersion; + private System.Windows.Forms.Label lblDICategory; + private System.Windows.Forms.Label lblDITVersion; + private System.Windows.Forms.Label lblDITCategory; + private System.Windows.Forms.Label lblDIDescription; + private System.Windows.Forms.Label lblDIName; + private System.Windows.Forms.Label lblDITDescription; + private System.Windows.Forms.Label lblDITName; + private System.Windows.Forms.SplitContainer splitContainer4; + private System.Windows.Forms.Button btnColorKey; + private System.Windows.Forms.CheckBox chkBoxShowMerged; + private System.Windows.Forms.CheckBox chkBoxShowFixed; + private System.Windows.Forms.CheckBox chkBoxShowMissing; + private System.Windows.Forms.CheckBox chkBoxShowCorrect; + private System.Windows.Forms.GroupBox gbSetInfo; + + private System.Windows.Forms.SplitContainer splitContainer5; + private System.Windows.Forms.DataGridView GameGrid; + private System.Windows.Forms.DataGridView RomGrid; + private RvTree DirTree; + private System.Windows.Forms.DataGridViewImageColumn dataGridViewImageColumn1; + private System.Windows.Forms.DataGridViewImageColumn dataGridViewImageColumn2; + private System.Windows.Forms.DataGridViewImageColumn dataGridViewImageColumn3; + private System.Windows.Forms.MenuStrip menuStrip1; + private System.Windows.Forms.ToolStripMenuItem tsmUpdateDATs; + private System.Windows.Forms.ToolStripMenuItem tsmScanROMs; + private System.Windows.Forms.ToolStripMenuItem tsmScanLevel1; + private System.Windows.Forms.ToolStripMenuItem tsmScanLevel3; + private System.Windows.Forms.ToolStripMenuItem tsmFindFixes; + private System.Windows.Forms.ToolStripMenuItem settingsToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem helpToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem aboutRomVaultToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem checkForUpdateToolStripMenuItem; + private System.Windows.Forms.DataGridViewImageColumn Type; + private System.Windows.Forms.DataGridViewTextBoxColumn CGame; + private System.Windows.Forms.DataGridViewTextBoxColumn CDescription; + private System.Windows.Forms.DataGridViewImageColumn CCorrect; + private System.Windows.Forms.ToolStripMenuItem FixROMsToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem tsmScanLevel2; + private System.Windows.Forms.DataGridViewImageColumn CGot; + private System.Windows.Forms.DataGridViewTextBoxColumn CRom; + private System.Windows.Forms.DataGridViewTextBoxColumn CSize; + private System.Windows.Forms.DataGridViewTextBoxColumn CMerge; + private System.Windows.Forms.DataGridViewTextBoxColumn CCRC32; + private System.Windows.Forms.DataGridViewTextBoxColumn CSHA1; + private System.Windows.Forms.DataGridViewTextBoxColumn CMD5; + private System.Windows.Forms.DataGridViewTextBoxColumn CStatus; + private System.Windows.Forms.DataGridViewTextBoxColumn ZipIndex; + private System.Windows.Forms.DataGridViewTextBoxColumn ZipHeader; + private System.Windows.Forms.ToolStripMenuItem registratioToolStripMenuItem; + private System.Windows.Forms.Label lblDITRomsFixable; + private System.Windows.Forms.Label lblDIRomsFixable; + private System.Windows.Forms.ToolStripMenuItem reportsToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem fixDatReportToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem fullReportToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem fixReportToolStripMenuItem; + } +} + diff --git a/ROMVault2/frmMain.cs b/ROMVault2/frmMain.cs new file mode 100644 index 0000000..c55d983 --- /dev/null +++ b/ROMVault2/frmMain.cs @@ -0,0 +1,1339 @@ +/****************************************************** + * ROMVault2 is written by Gordon J. * + * Contact gordon@romvault.com * + * Copyright 2010 * + ******************************************************/ +using System; +using System.Diagnostics; +using System.Drawing; +using System.Globalization; +using System.ServiceModel; +using System.Windows.Forms; +using ROMVault2.Properties; +using ROMVault2.RVRef; +using ROMVault2.RvDB; +using ROMVault2.Utils; + +namespace ROMVault2 +{ + public partial class FrmMain : Form + { + + private static readonly Color CBlue = Color.FromArgb(214, 214, 255); + private static readonly Color CGreyBlue = Color.FromArgb(214, 224, 255); + private static readonly Color CRed = Color.FromArgb(255, 214, 214); + private static readonly Color CBrightRed = Color.FromArgb(255, 0, 0); + private static readonly Color CGreen = Color.FromArgb(214, 255, 214); + private static readonly Color CGrey = Color.FromArgb(214, 214, 214); + private static readonly Color CCyan = Color.FromArgb(214, 255, 255); + private static readonly Color CCyanGrey = Color.FromArgb(214, 225, 225); + private static readonly Color CMagenta = Color.FromArgb(255, 214, 255); + private static readonly Color CBrown = Color.FromArgb(140, 80, 80); + private static readonly Color CPurple = Color.FromArgb(214, 140, 214); + private static readonly Color CYellow = Color.FromArgb(255, 255, 214); + private static readonly Color COrange = Color.FromArgb(255, 214, 140); + private static readonly Color CWhite = Color.FromArgb(255, 255, 255); + + private readonly Color[] _displayColor; + + private bool _updatingGameGrid; + + public static int[] GameGridColumnXPositions; + + private frmKey _fk; + + private Single _scaleFactorX = 1; + private Single _scaleFactorY = 1; + + protected override void ScaleControl(SizeF factor, BoundsSpecified specified) + { + base.ScaleControl(factor, specified); + splitContainer1.SplitterDistance = (int)(splitContainer1.SplitterDistance * factor.Width); + splitContainer2.SplitterDistance = (int)(splitContainer2.SplitterDistance * factor.Width); + splitContainer2.Panel1MinSize = (int)(splitContainer2.Panel1MinSize * factor.Width); + + splitContainer3.SplitterDistance = (int)(splitContainer3.SplitterDistance * factor.Height); + splitContainer4.SplitterDistance = (int)(splitContainer4.SplitterDistance * factor.Height); + + _scaleFactorX *= factor.Width; + _scaleFactorY *= factor.Height; + } + + public FrmMain() + { + + InitializeComponent(); + addGameGrid(); + Text = string.Format("RomVault ({0}.{1}) {2}", Program.Version, Program.SubVersion, Application.StartupPath); + + + + + _displayColor = new Color[(int)RepStatus.EndValue]; + + // RepStatus.UnSet + + _displayColor[(int)RepStatus.UnScanned] = CBlue; + + _displayColor[(int)RepStatus.DirCorrect] = CGreen; + _displayColor[(int)RepStatus.DirMissing] = CRed; + _displayColor[(int)RepStatus.DirCorrupt] = CBrightRed; //BrightRed + + _displayColor[(int)RepStatus.Missing] = CRed; + _displayColor[(int)RepStatus.Correct] = CGreen; + _displayColor[(int)RepStatus.NotCollected] = CGrey; + _displayColor[(int)RepStatus.UnNeeded] = CCyanGrey; + _displayColor[(int)RepStatus.Unknown] = CCyan; + _displayColor[(int)RepStatus.InToSort] = CMagenta; + + _displayColor[(int)RepStatus.Corrupt] = CBrightRed; //BrightRed + _displayColor[(int)RepStatus.Ignore] = CGreyBlue; + + _displayColor[(int)RepStatus.CanBeFixed] = CYellow; + _displayColor[(int)RepStatus.MoveToSort] = CPurple; + _displayColor[(int)RepStatus.Delete] = CBrown; + _displayColor[(int)RepStatus.NeededForFix] = COrange; + _displayColor[(int)RepStatus.Rename] = COrange; + + _displayColor[(int)RepStatus.CorruptCanBeFixed] = CYellow; + _displayColor[(int)RepStatus.MoveToCorrupt] = CPurple; //Missing + + + _displayColor[(int)RepStatus.Deleted] = CWhite; + + GameGridColumnXPositions = new int[(int)RepStatus.EndValue]; + + DirTree.Setup(ref DB.DirTree); + + splitContainer3_Panel1_Resize(new object(), new EventArgs()); + splitContainer4_Panel1_Resize(new object(), new EventArgs()); + } + + private Label lblSIName; + private Label lblSITName; + + private Label lblSIDescription; + private Label lblSITDescription; + + private Label lblSIManufacturer; + private Label lblSITManufacturer; + + private Label lblSICloneOf; + private Label lblSITCloneOf; + + private Label lblSIRomOf; + private Label lblSITRomOf; + + private Label lblSIYear; + private Label lblSITYear; + + private Label lblSITotalRoms; + private Label lblSITTotalRoms; + + //Trurip Extra Data + private Label lblSIPublisher; + private Label lblSITPublisher; + + private Label lblSIDeveloper; + private Label lblSITDeveloper; + + private Label lblSIEdition; + private Label lblSITEdition; + + private Label lblSIVersion; + private Label lblSITVersion; + + private Label lblSIType; + private Label lblSITType; + + private Label lblSIMedia; + private Label lblSITMedia; + + private Label lblSILanguage; + private Label lblSITLanguage; + + private Label lblSIPlayers; + private Label lblSITPlayers; + + private Label lblSIRatings; + private Label lblSITRatings; + + private Label lblSIGenre; + private Label lblSITGenre; + + private Label lblSIPeripheral; + private Label lblSITPeripheral; + + private Label lblSIBarCode; + private Label lblSITBarCode; + + private Label lblSIMediaCatalogNumber; + private Label lblSITMediaCatalogNumber; + + private void addGameGrid() + { + lblSIName = new Label { Location = SPoint(6, 15), Size = SSize(76, 13), Text = "Name :", TextAlign = ContentAlignment.TopRight }; + lblSITName = new Label { Location = SPoint(84, 14), Size = SSize(320, 17), BorderStyle = BorderStyle.FixedSingle }; + gbSetInfo.Controls.Add(lblSIName); + gbSetInfo.Controls.Add(lblSITName); + + lblSIDescription = new Label { Location = SPoint(6, 31), Size = SSize(76, 13), Text = "Description :", TextAlign = ContentAlignment.TopRight, Visible = false }; + lblSITDescription = new Label { Location = SPoint(84, 30), Size = SSize(320, 17), BorderStyle = BorderStyle.FixedSingle, Visible = false }; + gbSetInfo.Controls.Add(lblSIDescription); + gbSetInfo.Controls.Add(lblSITDescription); + + lblSIManufacturer = new Label { Location = SPoint(6, 47), Size = SSize(76, 13), Text = "Manufacturer :", TextAlign = ContentAlignment.TopRight, Visible = false }; + lblSITManufacturer = new Label { Location = SPoint(84, 46), Size = SSize(320, 17), BorderStyle = BorderStyle.FixedSingle, Visible = false }; + gbSetInfo.Controls.Add(lblSIManufacturer); + gbSetInfo.Controls.Add(lblSITManufacturer); + + lblSICloneOf = new Label { Location = SPoint(6, 63), Size = SSize(76, 13), Text = "Clone of :", TextAlign = ContentAlignment.TopRight, Visible = false }; + lblSITCloneOf = new Label { Location = SPoint(84, 62), Size = SSize(120, 17), BorderStyle = BorderStyle.FixedSingle, Visible = false }; + gbSetInfo.Controls.Add(lblSICloneOf); + gbSetInfo.Controls.Add(lblSITCloneOf); + + lblSIYear = new Label { Location = SPoint(206, 63), Size = SSize(76, 13), Text = "Year :", TextAlign = ContentAlignment.TopRight, Visible = false }; + lblSITYear = new Label { Location = SPoint(284, 62), Size = SSize(120, 17), BorderStyle = BorderStyle.FixedSingle, Visible = false }; + gbSetInfo.Controls.Add(lblSIYear); + gbSetInfo.Controls.Add(lblSITYear); + + + lblSIRomOf = new Label { Location = SPoint(6, 79), Size = SSize(76, 13), Text = "ROM of :", TextAlign = ContentAlignment.TopRight, Visible = false }; + lblSITRomOf = new Label { Location = SPoint(84, 78), Size = SSize(120, 17), BorderStyle = BorderStyle.FixedSingle, Visible = false }; + gbSetInfo.Controls.Add(lblSIRomOf); + gbSetInfo.Controls.Add(lblSITRomOf); + + lblSITotalRoms = new Label { Location = SPoint(206, 79), Size = SSize(76, 13), Text = "Total ROMs :", TextAlign = ContentAlignment.TopRight, Visible = false }; + lblSITTotalRoms = new Label { Location = SPoint(284, 78), Size = SSize(120, 17), BorderStyle = BorderStyle.FixedSingle, Visible = false }; + gbSetInfo.Controls.Add(lblSITotalRoms); + gbSetInfo.Controls.Add(lblSITTotalRoms); + + //Trurip + + lblSIPublisher = new Label { Location = SPoint(6, 47), Size = SSize(76, 13), Text = "Publisher :", TextAlign = ContentAlignment.TopRight, Visible = false }; + lblSITPublisher = new Label { Location = SPoint(84, 46), Size = SSize(320, 17), BorderStyle = BorderStyle.FixedSingle, Visible = false }; + gbSetInfo.Controls.Add(lblSIPublisher); + gbSetInfo.Controls.Add(lblSITPublisher); + + lblSIDeveloper = new Label { Location = SPoint(6, 63), Size = SSize(76, 13), Text = "Developer :", TextAlign = ContentAlignment.TopRight, Visible = false }; + lblSITDeveloper = new Label { Location = SPoint(84, 62), Size = SSize(320, 17), BorderStyle = BorderStyle.FixedSingle, Visible = false }; + gbSetInfo.Controls.Add(lblSIDeveloper); + gbSetInfo.Controls.Add(lblSITDeveloper); + + + + lblSIEdition = new Label { Location = SPoint(6, 79), Size = SSize(76, 13), Text = "Edition :", TextAlign = ContentAlignment.TopRight, Visible = false }; + lblSITEdition = new Label { Location = SPoint(84, 78), Size = SSize(120, 17), BorderStyle = BorderStyle.FixedSingle, Visible = false }; + gbSetInfo.Controls.Add(lblSIEdition); + gbSetInfo.Controls.Add(lblSITEdition); + + lblSIVersion = new Label { Location = SPoint(206, 79), Size = SSize(76, 13), Text = "Version :", TextAlign = ContentAlignment.TopRight, Visible = false }; + lblSITVersion = new Label { Location = SPoint(284, 78), Size = SSize(120, 17), BorderStyle = BorderStyle.FixedSingle, Visible = false }; + gbSetInfo.Controls.Add(lblSIVersion); + gbSetInfo.Controls.Add(lblSITVersion); + + lblSIType = new Label { Location = SPoint(406, 79), Size = SSize(76, 13), Text = "Type :", TextAlign = ContentAlignment.TopRight, Visible = false }; + lblSITType = new Label { Location = SPoint(484, 78), Size = SSize(120, 17), BorderStyle = BorderStyle.FixedSingle, Visible = false }; + gbSetInfo.Controls.Add(lblSIType); + gbSetInfo.Controls.Add(lblSITType); + + + lblSIMedia = new Label { Location = SPoint(6, 95), Size = SSize(76, 13), Text = "Media :", TextAlign = ContentAlignment.TopRight, Visible = false }; + lblSITMedia = new Label { Location = SPoint(84, 94), Size = SSize(120, 17), BorderStyle = BorderStyle.FixedSingle, Visible = false }; + gbSetInfo.Controls.Add(lblSIMedia); + gbSetInfo.Controls.Add(lblSITMedia); + + lblSILanguage = new Label { Location = SPoint(206, 95), Size = SSize(76, 13), Text = "Language :", TextAlign = ContentAlignment.TopRight, Visible = false }; + lblSITLanguage = new Label { Location = SPoint(284, 94), Size = SSize(120, 17), BorderStyle = BorderStyle.FixedSingle, Visible = false }; + gbSetInfo.Controls.Add(lblSILanguage); + gbSetInfo.Controls.Add(lblSITLanguage); + + lblSIPlayers = new Label { Location = SPoint(406, 95), Size = SSize(76, 13), Text = "Players :", TextAlign = ContentAlignment.TopRight, Visible = false }; + lblSITPlayers = new Label { Location = SPoint(484, 94), Size = SSize(120, 17), BorderStyle = BorderStyle.FixedSingle, Visible = false }; + gbSetInfo.Controls.Add(lblSIPlayers); + gbSetInfo.Controls.Add(lblSITPlayers); + + + + lblSIRatings = new Label { Location = SPoint(6, 111), Size = SSize(76, 13), Text = "Ratings :", TextAlign = ContentAlignment.TopRight, Visible = false }; + lblSITRatings = new Label { Location = SPoint(84, 110), Size = SSize(120, 17), BorderStyle = BorderStyle.FixedSingle, Visible = false }; + gbSetInfo.Controls.Add(lblSIRatings); + gbSetInfo.Controls.Add(lblSITRatings); + + lblSIGenre = new Label { Location = SPoint(206, 111), Size = SSize(76, 13), Text = "Genre :", TextAlign = ContentAlignment.TopRight, Visible = false }; + lblSITGenre = new Label { Location = SPoint(284, 110), Size = SSize(120, 17), BorderStyle = BorderStyle.FixedSingle, Visible = false }; + gbSetInfo.Controls.Add(lblSIGenre); + gbSetInfo.Controls.Add(lblSITGenre); + + lblSIPeripheral = new Label { Location = SPoint(406, 111), Size = SSize(76, 13), Text = "Peripheral :", TextAlign = ContentAlignment.TopRight, Visible = false }; + lblSITPeripheral = new Label { Location = SPoint(484, 110), Size = SSize(120, 17), BorderStyle = BorderStyle.FixedSingle, Visible = false }; + gbSetInfo.Controls.Add(lblSIPeripheral); + gbSetInfo.Controls.Add(lblSITPeripheral); + + + lblSIBarCode = new Label { Location = SPoint(6, 127), Size = SSize(76, 13), Text = "Barcode :", TextAlign = ContentAlignment.TopRight, Visible = false }; + lblSITBarCode = new Label { Location = SPoint(84, 126), Size = SSize(120, 17), BorderStyle = BorderStyle.FixedSingle, Visible = false }; + gbSetInfo.Controls.Add(lblSIBarCode); + gbSetInfo.Controls.Add(lblSITBarCode); + + lblSIMediaCatalogNumber = new Label { Location = SPoint(406, 127), Size = SSize(76, 13), Text = "Cat. No. :", TextAlign = ContentAlignment.TopRight, Visible = false }; + lblSITMediaCatalogNumber = new Label { Location = SPoint(484, 126), Size = SSize(120, 17), BorderStyle = BorderStyle.FixedSingle, Visible = false }; + gbSetInfo.Controls.Add(lblSIMediaCatalogNumber); + gbSetInfo.Controls.Add(lblSITMediaCatalogNumber); + + } + + private Point SPoint(int x, int y) + { + return new Point((int)(x*_scaleFactorX),(int)(y*_scaleFactorY)); + } + private Size SSize(int x, int y) + { + return new Size((int)(x * _scaleFactorX), (int)(y * _scaleFactorY)); + } + + + public override sealed string Text + { + get { return base.Text; } + set { base.Text = value; } + } + + #region "Main Buttons" + + private void TsmUpdateDaTsClick(object sender, EventArgs e) + { + UpdateDats(); + } + private void BtnUpdateDatsClick(object sender, EventArgs e) + { + UpdateDats(); + } + + private void UpdateDats() + { + + FrmProgressWindow progress = new FrmProgressWindow(this, "Scanning Dats", DatUpdate.UpdateDat); + progress.ShowDialog(this); + progress.Dispose(); + + DirTree.Setup(ref DB.DirTree); + DatSetSelected(DirTree.Selected); + } + + + + + private void TsmScanLevel1Click(object sender, EventArgs e) + { + ScanRoms(eScanLevel.Level1); + } + private void TsmScanLevel2Click(object sender, EventArgs e) + { + ScanRoms(eScanLevel.Level2); + } + private void TsmScanLevel3Click(object sender, EventArgs e) + { + ScanRoms(eScanLevel.Level3); + } + private void BtnScanRomsClick(object sender, EventArgs e) + { + ScanRoms(Settings.ScanLevel); + } + + private void ScanRoms(eScanLevel sd) + { + FileScanning.EScanLevel = sd; + FrmProgressWindow progress = new FrmProgressWindow(this, "Scanning Dirs", FileScanning.ScanFiles); + progress.ShowDialog(this); + progress.Dispose(); + + DatSetSelected(DirTree.Selected); + } + + + private void TsmFindFixesClick(object sender, EventArgs e) + { + FindFix(); + } + private void BtnFindFixesClick(object sender, EventArgs e) + { + FindFix(); + } + + private void FindFix() + { +#if NEWFINDFIX + FrmProgressWindow progress = new FrmProgressWindow(this, "Finding Fixes", FindFixesNew.ScanFiles); + progress.ShowDialog(this); + progress.Dispose(); + + DatSetSelected(DirTree.Selected); +#else + FrmProgressWindow progress = new FrmProgressWindow(this, "Finding Fixes", FindFixes.ScanFiles); + progress.ShowDialog(this); + progress.Dispose(); + + DatSetSelected(DirTree.Selected); +#endif + } + + + + + private void BtnFixFilesClick(object sender, EventArgs e) + { + FixFiles(); + } + private void FixFilesToolStripMenuItemClick(object sender, EventArgs e) + { + FixFiles(); + } + + + private void FixFiles() + { + FrmProgressWindowFix progress = new FrmProgressWindowFix(this); + progress.ShowDialog(this); + progress.Dispose(); + + DatSetSelected(DirTree.Selected); + } + + + + #endregion + + private void DirTreeRvSelected(object sender, MouseEventArgs e) + { + RvDir cf = (RvDir)sender; + if (cf != DirTree.GetSelected()) + DatSetSelected(cf); + + if (e.Button == MouseButtons.Right) + { + RvDir tn = (RvDir)sender; + + ContextMenu mnuContext = new ContextMenu(); + + MenuItem mnuFile = new MenuItem + { + Index = 0, + Text = Resources.FrmMain_DirTreeRvSelected_Set_ROM_DIR, + Tag = tn.TreeFullName + }; + mnuFile.Click += MnuFileClick; + mnuContext.MenuItems.Add(mnuFile); + + MenuItem mnuMakeDat = new MenuItem + { + Index = 1, + Text = @"Make Dat", + Tag = tn + }; + mnuMakeDat.Click += MnuMakeDatClick; + mnuContext.MenuItems.Add(mnuMakeDat); + + + mnuContext.Show(DirTree, e.Location); + } + } + + #region "DAT display code" + + private void DatSetSelected(RvBase cf) + { + DirTree.Refresh(); + GameGrid.Rows.Clear(); + RomGrid.Rows.Clear(); + + if (cf == null) + return; + + UpdateGameGrid((RvDir)cf); + + + } + + + private static void MnuFileClick(object sender, EventArgs e) + { + FrmSetDir sd = new FrmSetDir(); + + MenuItem mi = (MenuItem)sender; + string tDir = (string)mi.Tag; + Debug.WriteLine("Opening Dir Options for " + tDir); + + sd.SetLocation(tDir); + sd.ShowDialog(); + + sd.Dispose(); + } + + private static void MnuMakeDatClick(object sender, EventArgs e) + { + MenuItem mi = (MenuItem)sender; + RvDir thisDir = (RvDir) mi.Tag; + DatMaker.MakeDatFromDir(thisDir); + } + + private void splitContainer3_Panel1_Resize(object sender, EventArgs e) + { + gbDatInfo.Width = splitContainer3.Panel1.Width - (gbDatInfo.Left * 2); + } + + private void gbDatInfo_Resize(object sender, EventArgs e) + { + const int leftPos = 89; + int rightPos = (int)(gbDatInfo.Width / _scaleFactorX) - 15; + if (rightPos > 600) rightPos = 600; + int width = rightPos - leftPos; + int widthB1 = (int)((double)width * 120 / 340); + int leftB2 = rightPos - widthB1; + + + int backD = 97; + + width = (int)(width * _scaleFactorX); + widthB1 = (int)(widthB1 * _scaleFactorX); + leftB2 = (int)(leftB2 * _scaleFactorX); + backD = (int)(backD * _scaleFactorX); + + + lblDITName.Width = width; + lblDITDescription.Width = width; + + lblDITCategory.Width = widthB1; + lblDITAuthor.Width = widthB1; + + lblDIVersion.Left = leftB2 - backD; + lblDIDate.Left = leftB2 - backD; + + lblDITVersion.Left = leftB2; + lblDITVersion.Width = widthB1; + lblDITDate.Left = leftB2; + lblDITDate.Width = widthB1; + + lblDITPath.Width = width; + + lblDITRomsGot.Width = widthB1; + lblDITRomsMissing.Width = widthB1; + + lblDIRomsFixable.Left = leftB2 - backD; + lblDIRomsUnknown.Left = leftB2 - backD; + + lblDITRomsFixable.Left = leftB2; + lblDITRomsFixable.Width = widthB1; + lblDITRomsUnknown.Left = leftB2; + lblDITRomsUnknown.Width = widthB1; + } + + + #endregion + + #region "Game Grid Code" + + private void UpdateGameGrid(RvDir tDir) + { + + + lblDITName.Text = tDir.Name; + if (tDir.Dat != null) + { + RvDat tDat = tDir.Dat; + lblDITDescription.Text = tDat.GetData(RvDat.DatData.Description); + lblDITCategory.Text = tDat.GetData(RvDat.DatData.Category); + lblDITVersion.Text = tDat.GetData(RvDat.DatData.Version); + lblDITAuthor.Text = tDat.GetData(RvDat.DatData.Author); + lblDITDate.Text = tDat.GetData(RvDat.DatData.Date); + } + else if (tDir.DirDatCount == 1) + { + RvDat tDat = tDir.DirDat(0); + lblDITDescription.Text = tDat.GetData(RvDat.DatData.Description); + lblDITCategory.Text = tDat.GetData(RvDat.DatData.Category); + lblDITVersion.Text = tDat.GetData(RvDat.DatData.Version); + lblDITAuthor.Text = tDat.GetData(RvDat.DatData.Author); + lblDITDate.Text = tDat.GetData(RvDat.DatData.Date); + } + else + { + lblDITDescription.Text = ""; + lblDITCategory.Text = ""; + lblDITVersion.Text = ""; + lblDITAuthor.Text = ""; + lblDITDate.Text = ""; + } + + + + lblDITPath.Text = tDir.FullName; + + + lblDITRomsGot.Text = tDir.DirStatus.CountCorrect().ToString(CultureInfo.InvariantCulture); + lblDITRomsMissing.Text = tDir.DirStatus.CountMissing().ToString(CultureInfo.InvariantCulture); + lblDITRomsFixable.Text = tDir.DirStatus.CountFixesNeeded().ToString(CultureInfo.InvariantCulture); + lblDITRomsUnknown.Text = (tDir.DirStatus.CountUnknown() + tDir.DirStatus.CountInToSort()).ToString(CultureInfo.InvariantCulture); + + _updatingGameGrid = true; + GameGrid.Rows.Clear(); + RomGrid.Rows.Clear(); + + ReportStatus tDirStat; + + GameGridColumnXPositions = new int[(int)RepStatus.EndValue]; + + for (int j = 0; j < tDir.ChildCount; j++) + { + + RvDir tChildDir = tDir.Child(j) as RvDir; + if (tChildDir == null) continue; + + tDirStat = tChildDir.DirStatus; + + bool gCorrect = tDirStat.HasCorrect(); + bool gMissing = tDirStat.HasMissing(); + bool gUnknown = tDirStat.HasUnknown(); + bool gInToSort = tDirStat.HasInToSort(); + bool gFixes = tDirStat.HasFixesNeeded(); + + bool show = (chkBoxShowCorrect.Checked && gCorrect && !gMissing && !gFixes); + show = show || (chkBoxShowMissing.Checked && gMissing); + show = show || (chkBoxShowFixed.Checked && gFixes); + show = show || (gUnknown); + show = show || (gInToSort); + show = show || (tChildDir.GotStatus == GotStatus.Corrupt); + show = show || !(gCorrect || gMissing || gUnknown || gInToSort || gFixes); + + if (!show) continue; + + int columnIndex = 0; + for (int l = 0; l < RepairStatus.DisplayOrder.Length; l++) + { + if (l >= 13) columnIndex = l; + + if (tDirStat.Get(RepairStatus.DisplayOrder[l]) <= 0) continue; + + int len = DigitLength(tDirStat.Get(RepairStatus.DisplayOrder[l])) * 7 + 26; + if (len > GameGridColumnXPositions[columnIndex]) + GameGridColumnXPositions[columnIndex] = len; + columnIndex++; + } + } + + int t = 0; + for (int l = 0; l < (int)RepStatus.EndValue; l++) + { + int colWidth = GameGridColumnXPositions[l]; + GameGridColumnXPositions[l] = t; + t += colWidth; + } + + for (int j = 0; j < tDir.ChildCount; j++) + { + RvDir tChildDir = tDir.Child(j) as RvDir; + if (tChildDir == null) continue; + + tDirStat = tChildDir.DirStatus; + + bool gCorrect = tDirStat.HasCorrect(); + bool gMissing = tDirStat.HasMissing(); + bool gUnknown = tDirStat.HasUnknown(); + bool gFixes = tDirStat.HasFixesNeeded(); + bool gInToSort = tDirStat.HasInToSort(); + + bool show = (chkBoxShowCorrect.Checked && gCorrect && !gMissing && !gFixes); + show = show || (chkBoxShowMissing.Checked && gMissing); + show = show || (chkBoxShowFixed.Checked && gFixes); + show = show || (gUnknown); + show = show || (gInToSort); + show = show || (tChildDir.GotStatus == GotStatus.Corrupt); + show = show || !(gCorrect || gMissing || gUnknown || gInToSort || gFixes); + + if (!show) continue; + + Color bgCol = Color.FromArgb(255, 255, 255); + + + foreach (RepStatus t1 in RepairStatus.DisplayOrder) + { + if (tDirStat.Get(t1) <= 0) continue; + + bgCol = _displayColor[(int)t1]; + break; + } + + + GameGrid.Rows.Add(); + int iRow = GameGrid.Rows.Count - 1; + + GameGrid.Rows[iRow].Selected = false; + GameGrid.Rows[iRow].Tag = tChildDir; + + GameGrid.Rows[iRow].Cells[0].Style.BackColor = bgCol; + GameGrid.Rows[iRow].Cells[1].Style.BackColor = bgCol; + GameGrid.Rows[iRow].Cells[2].Style.BackColor = bgCol; + + if (String.IsNullOrEmpty(tChildDir.FileName)) + GameGrid.Rows[iRow].Cells[1].Value = tChildDir.Name; + else + GameGrid.Rows[iRow].Cells[1].Value = tChildDir.Name + " (Found: " + tChildDir.FileName + ")"; + + if (tChildDir.Game != null) + GameGrid.Rows[iRow].Cells[2].Value = tChildDir.Game.GetData(RvGame.GameData.Description); + + DirCellDraw tDirCellDraw = new DirCellDraw(tChildDir, bgCol); + GameGrid.Rows[iRow].Cells[0] = tDirCellDraw; + + DirCellStatusDraw tCellStatusDraw = new DirCellStatusDraw(tChildDir); + GameGrid.Rows[iRow].Cells[3] = tCellStatusDraw; + } + + _updatingGameGrid = false; + + UpdateRomGrid(tDir); + } + + private static int DigitLength(int number) + { + + int textNumber = number; + int len = 0; + + while (textNumber > 0) + { + textNumber = textNumber / 10; + len++; + } + + return len; + } + + private void GameGridSelectionChanged(object sender, EventArgs e) + { + UpdateSelectedGame(); + } + + private void GameGridMouseDoubleClick(object sender, MouseEventArgs e) + { + if (_updatingGameGrid) + return; + + if (GameGrid.SelectedRows.Count != 1) + return; + + RvDir tGame = (RvDir)GameGrid.SelectedRows[0].Tag; + if (tGame.Game == null) + { + UpdateGameGrid(tGame); + DirTree.SetSelected(tGame); + } + } + + + #endregion + + #region "Rom Grid Code" + + private void splitContainer4_Panel1_Resize(object sender, EventArgs e) + { + int chkLeft = splitContainer4.Panel1.Width - 150; + if (chkLeft < 430) chkLeft = 430; + + chkBoxShowCorrect.Left = chkLeft; + chkBoxShowMissing.Left = chkLeft; + chkBoxShowFixed.Left = chkLeft; + chkBoxShowMerged.Left = chkLeft; + btnColorKey.Left = chkLeft; + + gbSetInfo.Width = chkLeft - gbSetInfo.Left - 10; + } + + + private void gbSetInfo_Resize(object sender, EventArgs e) + { + int leftPos = 84; + int rightPos = gbSetInfo.Width - 15; + if (rightPos > 750) rightPos = 750; + int width = rightPos - leftPos; + + int widthB1 = (int)((double)width * 120 / 340); + int leftB2 = leftPos + width - widthB1; + + if (lblSITName == null) return; + + lblSITName.Width = width; + lblSITDescription.Width = width; + lblSITManufacturer.Width = width; + + lblSITCloneOf.Width = widthB1; + + lblSIYear.Left = leftB2 - 78; + lblSITYear.Left = leftB2; + lblSITYear.Width = widthB1; + + lblSITRomOf.Width = widthB1; + + lblSITotalRoms.Left = leftB2 - 78; + lblSITTotalRoms.Left = leftB2; + lblSITTotalRoms.Width = widthB1; + + lblSITPublisher.Width = width; + lblSITDeveloper.Width = width; + + int width3 = (int)((double)width * 0.24); + int P2 = (int)((double)width * 0.38); + + int width4 = (int) ((double) width*0.24); + + lblSITEdition.Width = width3; + + lblSIVersion.Left = leftPos + P2 - 78; + lblSITVersion.Left = leftPos + P2; + lblSITVersion.Width = width3; + + lblSIType.Left = leftPos + width - width3 - 78; + lblSITType.Left = leftPos + width - width3; + lblSITType.Width = width3; + + + lblSITMedia.Width = width3; + + lblSILanguage.Left = leftPos + P2 - 78; + lblSITLanguage.Left = leftPos + P2; + lblSITLanguage.Width = width3; + + lblSIPlayers.Left = leftPos + width - width3 - 78; + lblSITPlayers.Left = leftPos + width - width3; + lblSITPlayers.Width = width3; + + lblSITRatings.Width = width3; + + lblSIGenre.Left = leftPos + P2 - 78; + lblSITGenre.Left = leftPos + P2; + lblSITGenre.Width = width3; + + lblSIPeripheral.Left = leftPos + width - width3 - 78; + lblSITPeripheral.Left = leftPos + width - width3; + lblSITPeripheral.Width = width3; + + + lblSITBarCode.Width = width4; + + lblSIMediaCatalogNumber.Left = leftPos + width - width4 - 78; + lblSITMediaCatalogNumber.Left = leftPos + width - width4; + lblSITMediaCatalogNumber.Width = width4; + + + } + + + private void UpdateSelectedGame() + { + if (_updatingGameGrid) + return; + + if (GameGrid.SelectedRows.Count != 1) + return; + + RvDir tGame = (RvDir)GameGrid.SelectedRows[0].Tag; + UpdateRomGrid(tGame); + } + + private void UpdateRomGrid(RvDir tGame) + { + lblSITName.Text = tGame.Name; + if (tGame.Game == null) + { + lblSIDescription.Visible = false; + lblSITDescription.Visible = false; + + lblSIManufacturer.Visible = false; + lblSITManufacturer.Visible = false; + + lblSICloneOf.Visible = false; + lblSITCloneOf.Visible = false; + + lblSIRomOf.Visible = false; + lblSITRomOf.Visible = false; + + lblSIYear.Visible = false; + lblSITYear.Visible = false; + + lblSITotalRoms.Visible = false; + lblSITTotalRoms.Visible = false; + + // Trurip + + lblSIPublisher.Visible = false; + lblSITPublisher.Visible = false; + + lblSIDeveloper.Visible = false; + lblSITDeveloper.Visible = false; + + lblSIEdition.Visible = false; + lblSITEdition.Visible = false; + + lblSIVersion.Visible = false; + lblSITVersion.Visible = false; + + lblSIType.Visible = false; + lblSITType.Visible = false; + + lblSIMedia.Visible = false; + lblSITMedia.Visible = false; + + lblSILanguage.Visible = false; + lblSITLanguage.Visible = false; + + lblSIPlayers.Visible = false; + lblSITPlayers.Visible = false; + + lblSIRatings.Visible = false; + lblSITRatings.Visible = false; + + lblSIGenre.Visible = false; + lblSITGenre.Visible = false; + + lblSIPeripheral.Visible = false; + lblSITPeripheral.Visible = false; + + lblSIBarCode.Visible = false; + lblSITBarCode.Visible = false; + + lblSIMediaCatalogNumber.Visible = false; + lblSITMediaCatalogNumber.Visible = false; + } + else + { + + if (tGame.Game.GetData(RvGame.GameData.Trurip) == "yes") + { + lblSIDescription.Visible = true; + lblSITDescription.Visible = true; + lblSITDescription.Text = tGame.Game.GetData(RvGame.GameData.Description); + + lblSIManufacturer.Visible = false; + lblSITManufacturer.Visible = false; + + lblSICloneOf.Visible = false; + lblSITCloneOf.Visible = false; + + lblSIRomOf.Visible = false; + lblSITRomOf.Visible = false; + + lblSIYear.Visible = false; + lblSITYear.Visible = false; + + lblSITotalRoms.Visible = false; + lblSITTotalRoms.Visible = false; + + + lblSIPublisher.Visible = true; + lblSITPublisher.Visible = true; + lblSITPublisher.Text = tGame.Game.GetData(RvGame.GameData.Publisher); + + lblSIDeveloper.Visible = true; + lblSITDeveloper.Visible = true; + lblSITDeveloper.Text = tGame.Game.GetData(RvGame.GameData.Developer); + + lblSIEdition.Visible = true; + lblSITEdition.Visible = true; + lblSITEdition.Text = tGame.Game.GetData(RvGame.GameData.Edition); + + lblSIVersion.Visible = true; + lblSITVersion.Visible = true; + lblSITVersion.Text = tGame.Game.GetData(RvGame.GameData.Version); + + lblSIType.Visible = true; + lblSITType.Visible = true; + lblSITType.Text = tGame.Game.GetData(RvGame.GameData.Type); + + lblSIMedia.Visible = true; + lblSITMedia.Visible = true; + lblSITMedia.Text = tGame.Game.GetData(RvGame.GameData.Media); + + lblSILanguage.Visible = true; + lblSITLanguage.Visible = true; + lblSITLanguage.Text = tGame.Game.GetData(RvGame.GameData.Language); + + lblSIPlayers.Visible = true; + lblSITPlayers.Visible = true; + lblSITPlayers.Text = tGame.Game.GetData(RvGame.GameData.Players); + + lblSIRatings.Visible = true; + lblSITRatings.Visible = true; + lblSITRatings.Text = tGame.Game.GetData(RvGame.GameData.Ratings); + + lblSIGenre.Visible = true; + lblSITGenre.Visible = true; + lblSITGenre.Text = tGame.Game.GetData(RvGame.GameData.Genre); + + lblSIPeripheral.Visible = true; + lblSITPeripheral.Visible = true; + lblSITPeripheral.Text = tGame.Game.GetData(RvGame.GameData.Peripheral); + + lblSIBarCode.Visible = true; + lblSITBarCode.Visible = true; + lblSITBarCode.Text = tGame.Game.GetData(RvGame.GameData.BarCode); + + lblSIMediaCatalogNumber.Visible = true; + lblSITMediaCatalogNumber.Visible = true; + lblSITMediaCatalogNumber.Text = tGame.Game.GetData(RvGame.GameData.MediaCatalogNumber); + + } + else + { + lblSIDescription.Visible = true; + lblSITDescription.Visible = true; + lblSITDescription.Text = tGame.Game.GetData(RvGame.GameData.Description); + + lblSIManufacturer.Visible = true; + lblSITManufacturer.Visible = true; + lblSITManufacturer.Text = tGame.Game.GetData(RvGame.GameData.Manufacturer); + + lblSICloneOf.Visible = true; + lblSITCloneOf.Visible = true; + lblSITCloneOf.Text = tGame.Game.GetData(RvGame.GameData.CloneOf); + + lblSIRomOf.Visible = true; + lblSITRomOf.Visible = true; + lblSITRomOf.Text = tGame.Game.GetData(RvGame.GameData.RomOf); + + lblSIYear.Visible = true; + lblSITYear.Visible = true; + lblSITYear.Text = tGame.Game.GetData(RvGame.GameData.Year); + + lblSITotalRoms.Visible = true; + lblSITTotalRoms.Visible = true; + + + + + lblSIPublisher.Visible = false; + lblSITPublisher.Visible = false; + + lblSIDeveloper.Visible = false; + lblSITDeveloper.Visible = false; + + lblSIEdition.Visible = false; + lblSITEdition.Visible = false; + + lblSIVersion.Visible = false; + lblSITVersion.Visible = false; + + lblSIType.Visible = false; + lblSITType.Visible = false; + + lblSIMedia.Visible = false; + lblSITMedia.Visible = false; + + lblSILanguage.Visible = false; + lblSITLanguage.Visible = false; + + lblSIPlayers.Visible = false; + lblSITPlayers.Visible = false; + + lblSIRatings.Visible = false; + lblSITRatings.Visible = false; + + lblSIGenre.Visible = false; + lblSITGenre.Visible = false; + + lblSIPeripheral.Visible = false; + lblSITPeripheral.Visible = false; + + lblSIBarCode.Visible = false; + lblSITBarCode.Visible = false; + + lblSIMediaCatalogNumber.Visible = false; + lblSITMediaCatalogNumber.Visible = false; + + } + } + + RomGrid.Rows.Clear(); + AddDir(tGame, ""); + GC.Collect(); + } + + + private void AddDir(RvDir tGame, string pathAdd) + { + for (int l = 0; l < tGame.ChildCount; l++) + { + RvBase tBase = tGame.Child(l); + + RvFile tFile = tBase as RvFile; + if (tFile != null) + AddRom((RvFile)tBase, pathAdd); + + if (tGame.Dat == null) + continue; + + RvDir tDir = tBase as RvDir; + if (tDir == null) continue; + if (tDir.Game == null) + AddDir(tDir, pathAdd + tGame.Name + "/"); + } + } + + private void AddRom(RvFile tRomTable, string pathAdd) + { + + if (tRomTable.DatStatus != DatStatus.InDatMerged || tRomTable.RepStatus != RepStatus.NotCollected || chkBoxShowMerged.Checked) + { + RomGrid.Rows.Add(); + int row = RomGrid.Rows.Count - 1; + + string imageName = "R_" + tRomTable.DatStatus + "_" + tRomTable.RepStatus; + + RomCellDraw tDirCellDraw = new RomCellDraw(imageName, _displayColor[(int)tRomTable.RepStatus]); + RomGrid.Rows[row].Cells[0] = tDirCellDraw; + + for (int i = 0; i < RomGrid.Rows[row].Cells.Count; i++) + RomGrid.Rows[row].Cells[i].Style.BackColor = _displayColor[(int)tRomTable.RepStatus]; + + string fname = pathAdd + tRomTable.Name; + if (!string.IsNullOrEmpty(tRomTable.FileName)) + fname += " (Found: " + tRomTable.FileName + ")"; + if (tRomTable.CHDVersion != null) + fname += " (V" + tRomTable.CHDVersion + ")"; + + RomGrid.Rows[row].Cells["CRom"].Value = fname; + + RomGrid.Rows[row].Cells["CMerge"].Value = tRomTable.Merge; + RomGrid.Rows[row].Cells["CStatus"].Value = tRomTable.Status; + + string strSize = tRomTable.Size.ToString(); + string flags = ""; + if (tRomTable.FileStatusIs(FileStatus.SizeFromDAT)) flags += "D"; + if (tRomTable.FileStatusIs(FileStatus.SizeFromHeader)) flags += "H"; + if (tRomTable.FileStatusIs(FileStatus.SizeVerified)) flags += "V"; + if (!String.IsNullOrEmpty(flags)) strSize += " (" + flags + ")"; + RomGrid.Rows[row].Cells["CSize"].Value = strSize; + + string strCRC = ArrByte.ToString(tRomTable.CRC); + flags = ""; + if (tRomTable.FileStatusIs(FileStatus.CRCFromDAT)) flags += "D"; + if (tRomTable.FileStatusIs(FileStatus.CRCFromHeader)) flags += "H"; + if (tRomTable.FileStatusIs(FileStatus.CRCVerified)) flags += "V"; + if (!String.IsNullOrEmpty(flags)) strCRC += " (" + flags + ")"; + RomGrid.Rows[row].Cells["CCRC32"].Value = strCRC; + + if (tRomTable.SHA1CHD == null) + { + string strSHA1 = ArrByte.ToString(tRomTable.SHA1); + flags = ""; + if (tRomTable.FileStatusIs(FileStatus.SHA1FromDAT)) flags += "D"; + if (tRomTable.FileStatusIs(FileStatus.SHA1FromHeader)) flags += "H"; + if (tRomTable.FileStatusIs(FileStatus.SHA1Verified)) flags += "V"; + if (!String.IsNullOrEmpty(flags)) strSHA1 += " (" + flags + ")"; + RomGrid.Rows[row].Cells["CSHA1"].Value = strSHA1; + } + else + { + string strSHA1CHD = "CHD: " + ArrByte.ToString(tRomTable.SHA1CHD); + flags = ""; + if (tRomTable.FileStatusIs(FileStatus.SHA1CHDFromDAT)) flags += "D"; + if (tRomTable.FileStatusIs(FileStatus.SHA1CHDFromHeader)) flags += "H"; + if (tRomTable.FileStatusIs(FileStatus.SHA1CHDVerified)) flags += "V"; + if (!String.IsNullOrEmpty(flags)) strSHA1CHD += " (" + flags + ")"; + RomGrid.Rows[row].Cells["CSHA1"].Value = strSHA1CHD; + } + + if (tRomTable.MD5CHD == null) + { + string strMD5 = ArrByte.ToString(tRomTable.MD5); + flags = ""; + if (tRomTable.FileStatusIs(FileStatus.MD5FromDAT)) flags += "D"; + if (tRomTable.FileStatusIs(FileStatus.MD5FromHeader)) flags += "H"; + if (tRomTable.FileStatusIs(FileStatus.MD5Verified)) flags += "V"; + if (!String.IsNullOrEmpty(flags)) strMD5 += " (" + flags + ")"; + RomGrid.Rows[row].Cells["CMD5"].Value = strMD5; + } + else + { + string strMD5CHD = "CHD: " + ArrByte.ToString(tRomTable.MD5CHD); + flags = ""; + if (tRomTable.FileStatusIs(FileStatus.MD5CHDFromDAT)) flags += "D"; + if (tRomTable.FileStatusIs(FileStatus.MD5CHDFromHeader)) flags += "H"; + if (tRomTable.FileStatusIs(FileStatus.MD5CHDVerified)) flags += "V"; + if (!String.IsNullOrEmpty(flags)) strMD5CHD += " (" + flags + ")"; + RomGrid.Rows[row].Cells["CMD5"].Value = strMD5CHD; + } + + if (tRomTable.FileType == FileType.ZipFile) + { + RomGrid.Rows[row].Cells["ZipIndex"].Value = tRomTable.ZipFileIndex == -1 ? "" : tRomTable.ZipFileIndex.ToString(CultureInfo.InvariantCulture); + RomGrid.Rows[row].Cells["ZipHeader"].Value = tRomTable.ZipFileHeaderPosition == null ? "" : tRomTable.ZipFileHeaderPosition.ToString(); + } + } + } + #endregion + + private void RomGridSelectionChanged(object sender, EventArgs e) + { + RomGrid.ClearSelection(); + } + + private void ChkBoxShowCorrectCheckedChanged(object sender, EventArgs e) + { + DatSetSelected(DirTree.Selected); + } + + private void ChkBoxShowMissingCheckedChanged(object sender, EventArgs e) + { + DatSetSelected(DirTree.Selected); + } + + private void ChkBoxShowFixedCheckedChanged(object sender, EventArgs e) + { + DatSetSelected(DirTree.Selected); + } + + private void ChkBoxShowMergedCheckedChanged(object sender, EventArgs e) + { + UpdateSelectedGame(); + } + + private void BtnColorKeyClick(object sender, EventArgs e) + { + + if (_fk == null || _fk.IsDisposed) + _fk = new frmKey(); + _fk.Show(); + } + + private void SettingsToolStripMenuItemClick(object sender, EventArgs e) + { + FrmSettings fcfg = new FrmSettings(); + fcfg.ShowDialog(this); + fcfg.Dispose(); + } + + private void BtnReportClick(object sender, EventArgs e) + { + Report.MakeFixFiles(); + //frmReport newreporter = new frmReport(); + //newreporter.ShowDialog(); + //newreporter.Dispose(); + } + private void fixDatReportToolStripMenuItem_Click(object sender, EventArgs e) + { + Report.MakeFixFiles(); + } + + private void fullReportToolStripMenuItem_Click(object sender, EventArgs e) + { + Report.GenerateReport(); + } + private void fixReportToolStripMenuItem_Click(object sender, EventArgs e) + { + Report.GenerateFixReport(); + } + + + private void AboutRomVaultToolStripMenuItemClick(object sender, EventArgs e) + { + frmHelpAbout fha = new frmHelpAbout(); + fha.ShowDialog(this); + fha.Dispose(); + } + + private void RomGridMouseUp(object sender, MouseEventArgs e) + { + if (e.Button == MouseButtons.Right) + { + int currentMouseOverRow = RomGrid.HitTest(e.X, e.Y).RowIndex; + if (currentMouseOverRow >= 0) + { + string name = RomGrid.Rows[currentMouseOverRow].Cells[1].Value.ToString(); + string size = RomGrid.Rows[currentMouseOverRow].Cells[2].Value.ToString(); + string crc = RomGrid.Rows[currentMouseOverRow].Cells[4].Value.ToString(); + if (crc.Length > 8) crc = crc.Substring(0, 8); + string sha1 = RomGrid.Rows[currentMouseOverRow].Cells[5].Value.ToString(); + if (sha1.Length > 40) sha1 = sha1.Substring(0, 40); + string md5 = RomGrid.Rows[currentMouseOverRow].Cells[6].Value.ToString(); + if (md5.Length > 32) md5 = md5.Substring(0, 32); + + string clipText = "Name : " + name + Environment.NewLine; + clipText += "Size : " + size + Environment.NewLine; + clipText += "CRC32: " + crc + Environment.NewLine; + if (sha1.Length > 0) clipText += "SHA1 : " + sha1 + Environment.NewLine; + if (md5.Length > 0) clipText += "MD5 : " + md5 + Environment.NewLine; + + try + { + Clipboard.Clear(); + Clipboard.SetText(clipText); + } + catch + { + } + } + } + } + + private void GameGrid_MouseUp(object sender, MouseEventArgs e) + { + if (e.Button == MouseButtons.Right) + { + int currentMouseOverRow = GameGrid.HitTest(e.X, e.Y).RowIndex; + if (currentMouseOverRow >= 0) + { + object r1 = GameGrid.Rows[currentMouseOverRow].Cells[1].Value; + string filename = r1 != null ? r1.ToString() : ""; + object r2 = GameGrid.Rows[currentMouseOverRow].Cells[2].Value; + string description = r2 != null ? r2.ToString() : ""; + + try + { + Clipboard.Clear(); + Clipboard.SetText("Name : " + filename + Environment.NewLine + "Desc : " + description + Environment.NewLine); + } + catch + { + } + } + } + + } + + private void RegistratioToolStripMenuItemClick(object sender, EventArgs e) + { + FrmRegistration freg = new FrmRegistration(); + freg.ShowDialog(this); + freg.Dispose(); + } + + private void checkForUpdateToolStripMenuItem_Click(object sender, EventArgs e) + { + BasicHttpBinding b = new BasicHttpBinding(); + EndpointAddress ep = new EndpointAddress(@"http://services.romvault.com/Service1.svc"); + + Service1Client s = new Service1Client(b, ep); + + string v = s.GetLatestVersion1(Program.Version, Program.SubVersion); + + string thisV = Program.Version + "." + Program.SubVersion.ToString("0000"); + + int res = String.Compare(v, thisV, StringComparison.Ordinal); + + if (res > 0) + { + string url = s.GetUpdateLink1(Program.Version, Program.SubVersion); + MessageBox.Show(Resources.Program_Main_There_is_a_new_release_download_now_from + url); + Process.Start(url); + } + else + { + MessageBox.Show(@"You are running the latest version " + Program.Version + "." + Program.SubVersion); + } + + + } + + + } +} diff --git a/ROMVault2/frmMain.resx b/ROMVault2/frmMain.resx new file mode 100644 index 0000000..b1dc996 --- /dev/null +++ b/ROMVault2/frmMain.resx @@ -0,0 +1,2236 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + 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 + YII= + + + + + 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 + RU5ErkJggg== + + + + + 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 + + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + 17, 17 + + + + AAABAAUAEBAAAAAAIABoBAAAVgAAACAgAAAAACAAqBAAAL4EAAAwMAAAAAAgAKglAABmFQAAQEAAAAAA + IAAoQgAADjsAAICAAAAAACAAKAgBADZ9AAAoAAAAEAAAACAAAAABACAAAAAAAEAEAAAAAAAAAAAAAAAA + AAAAAAAA7e3tvevr6//m5ub/4ODg/9nZ2f/Q0ND/wsLC/66urv+ampr/nJyc/6Kiov+tra3/ubm5/8XF + xf/R0dH/2trapenp6b3l5eX/3t7e/9bW1v/Kysr/ubm5/5+fn/92dnb/ampq/21tbf97e3v/jIyM/56e + nv+wsLD/wsLC/8/Pz6Xl5eW939/f/9bW1v/Jycn/uLi4/5ycnP9ubm7/YWFh/2pqav8tLS3/RERE/2lp + af+AgID/mJiY/7Kysv/FxcWl39/fvdjY2P/Ly8v/ubm5/56env9ycnL/VlZW/2RkZP92dnb/IyMj/yAg + IP8qKir/VlZW/319ff+ioqL/v7+/pdnZ2b3Nzc3/u7u7/6Kiov94eHj/U1NT/15eXv99fX3/IiIi/yYm + Jv8lJSX/IyMj/yAgIP8+Pj7/hoaG/76+vqXQ0NC9wMDA/6ampv+AgID/U1NT/1tbW/+BgYH/ISEh/yUl + Jf8lJSX/JiYm/yYmJv8lJSX/IiIi/2BgYP/Dw8OlxsbGva6urv+Hh4f/VlZW/1paWv+BgYH/JCQk/yUl + Jf8kJCT/JSUl/yUlJf8mJib/JiYm/yQkJP91dXX/zc3Npby8vL2Wlpb/XV1d/1tbW/+AgID/JiYm/zs7 + O/9ubm7/YWFh/ykpKf8kJCT/JSUl/yUlJf9ZWVn/xcXF/9XV1aW4uLi9dXV1/2JiYv9/f3//Kysr/0BA + QP/FxcX/zMzM/8vLy/+hoaH/JCQk/yQkJP9NTU3/v7+//9LS0v/c3NylvLy8vXJycv9/f3//NjY2/yMj + I/9lZWX/zc3N/83Nzf/MzMz/ycnJ/ykpKf9DQ0P/uLi4/9DQ0P/c3Nz/4+PjpcDAwL1/f3//QkJC/yQi + Iv8jIyP/Li4u/6ioqP/MzMz/ysrK/3h4eP88PDz/s7Oz/8/Pz//b29v/4+Pj/+jo6KXR0dG9bm5u/yQi + Iv9hJRr/SCQd/0QkHv8yJCH/Ozs7/zExMf82Njb/r6+v/9HR0f/b29v/4+Pj/+jo6P/s7Oyl29vbvX9/ + f/8lJSX/PiMe/1okGv9dJBr/VSQc/zokIP8yMjL/rq6u/9XV1f/e3t7/5OTk/+np6f/t7e3/8PDwpeXl + 5b3f39//t7e3/2tra/8lJSX/RyMd/1QlHP8vLi7/ra2t/93d3f/j4+P/6Ojo/+vr6//u7u7/8fHx//Pz + 86Xs7Oy96enp/+bm5v/i4uL/n5+f/zY2Nv9JSUn/q6ur/+bm5v/p6en/7Ozs/+7u7v/w8PD/8vLy//T0 + 9P/19fWl8fHxvfDw8P/u7u7/7Ozs/+rq6v/g4OD/39/f/+zs7P/u7u7/7+/v//Hx8f/y8vL/9PT0//X1 + 9f/29vb/9/f3pQAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA + //8AAP//AAD//wAA//8oAAAAIAAAAEAAAAABACAAAAAAAIAQAAAAAAAAAAAAAAAAAAAAAAAA7+/vee7u + 7v/t7e3/6+vr/+np6f/n5+f/5OTk/+Hh4f/e3t7/29vb/9fX1//T09P/zc3N/8XFxf++vr7/uLi4/7Cw + sP+rq6v/qKio/6ioqP+rq6v/rq6u/7Kysv+4uLj/vb29/8LCwv/Hx8f/zMzM/9HR0f/X19f/3Nzc/9/f + 303t7e157Ozs/+rq6v/o6Oj/5ubm/+Pj4//g4OD/3Nzc/9jY2P/U1NT/z8/P/8jIyP/AwMD/tra2/6qq + qv+YmJj/goKC/42Njf+NjY3/kZGR/5aWlv+bm5v/oqKi/6qqqv+wsLD/tra2/729vf/Dw8P/ysrK/9HR + 0f/X19f/29vbTevr63nq6ur/6Ojo/+Xl5f/i4uL/3t7e/9vb2//W1tb/0tLS/8zMzP/ExMT/u7u7/7Gx + sf+jo6P/kJCQ/3Z2dv9mZmb/c3Nz/3R0dP96enr/gICA/4iIiP+RkZH/mZmZ/6Ghof+pqan/sbGx/7m5 + uf/CwsL/ysrK/9HR0f/W1tZN6enpeefn5//l5eX/4uLi/97e3v/a2tr/1dXV/9DQ0P/Kysr/wsLC/7m5 + uf+tra3/n5+f/4mJif9ra2v/aWlp/29vb/9hYWH/YWFh/2dnZ/9tbW3/dXV1/35+fv+IiIj/kpKS/5yc + nP+lpaX/r6+v/7m5uf/CwsL/y8vL/9HR0U3n5+d55eXl/+Li4v/f39//29vb/9bW1v/Q0ND/ycnJ/8LC + wv+4uLj/ra2t/52dnf+IiIj/a2tr/0tLS/9oaGj/enp6/1hYWP9ERET/Ly8v/1NTU/9kZGT/bW1t/3d3 + d/+CgoL/jY2N/5iYmP+kpKT/sLCw/7u7u//Gxsb/zMzMTeXl5Xnj4+P/39/f/9vb2//X19f/0dHR/8rK + yv/BwcH/uLi4/62trf+enp7/iYmJ/2tra/9bW1v/WFhY/3h4eP91dXX/X19f/yAgIP8iIiL/Hx8f/zk5 + Of9aWlr/Z2dn/3Jycv9+fn7/i4uL/5mZmf+np6f/tbW1/8HBwf/JyclN4uLieeDg4P/c3Nz/2NjY/9LS + 0v/Kysr/wsLC/7i4uP+tra3/n5+f/4uLi/9tbW3/Q0ND/11dXf9dXV3/aWlp/5WVlf+QkJD/IiIi/yEh + If8eHh7/Hh4e/yQkJP9HR0f/YmJi/29vb/99fX3/jIyM/52dnf+vr6//vr6+/8fHx03g4OB53d3d/9jY + 2P/T09P/zMzM/8PDw/+5ubn/rq6u/6CgoP+MjIz/cnJy/19fX/9NTU3/ampq/3d3d/9TU1P/jo6O/yYm + Jv8jIyP/JiYm/yQkJP8hISH/Hh4e/x4eHv8wMDD/WFhY/21tbf99fX3/kpKS/6mpqf+8vLz/xsbGTd7e + 3nna2tr/1NTU/83Nzf/ExMT/u7u7/6+vr/+hoaH/j4+P/3V1df9HR0f/Wlpa/1ZWVv9paWn/fn5+/5ub + m/8dHR3/IyMj/yYmJv8mJib/JiYm/yUlJf8jIyP/Hx8f/x4eHv8hISH/QEBA/2xsbP+IiIj/o6Oj/7u7 + u//Hx8dN2traedXV1f/Ozs7/xsbG/7y8vP+xsbH/pKSk/5KSkv97e3v/ZGRk/0pKSv9gYGD/dXV1/0JC + Qv+qqqr/MjIy/yMjI/8mJib/JiYm/yYmJv8mJib/JiYm/yUlJf8lJSX/ISEh/x8fH/8fHx//LS0t/1JS + Uv+cnJz/u7u7/8fHx03W1tZ50dHR/8nJyf+/v7//s7Oz/6ampv+UlJT/fX19/01NTf9ZWVn/WFhY/2ho + aP9ubm7/mJiY/xsbG/8hISH/JSUl/yUlJf8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8lJSX/JCQk/yEh + If8gICD/KSkp/5ycnP++vr7/ycnJTdLS0nnMzMz/wsLC/7a2tv+pqan/l5eX/4KCgv9sbGz/SkpK/1tb + W/91dXX/Nzc3/7W1tf9HR0f/IiIi/yQkJP8lJSX/JSUl/yUlJf8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JSUl/yMjI/8jIyP/mJiY/8XFxf/MzMxNzs7OecfHx/+7u7v/ra2t/5ubm/+Ghob/WVlZ/1lZ + Wf9dXV3/ZWVl/2hoaP+Kior/KSkp/yEhIf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JSUl/zIyMv+goKD/ysrK/9DQ0E3Kysp5wcHB/7Kysv+goKD/ioqK/3Jy + cv9PT0//V1dX/3V1df8zMzP/q6ur/2ZmZv8gICD/JCQk/yUlJf8lJSX/JCQk/yQkJP8kJCT/JSUl/yUl + Jf8lJSX/JiYm/yYmJv8mJib/JiYm/yYmJv8hISH/Q0ND/76+vv/Nzc3/09PTTcXFxXm7u7v/qKio/5GR + kf9mZmb/Xl5e/2JiYv9eXl7/bGxs/3d3d/82Njb/Hx8f/yQkJP8kJCT/JSUl/ycnJ/8lJSX/JCQk/yQk + JP8kJCT/JSUl/yUlJf8lJSX/JSUl/yYmJv8mJib/Kioq/1hYWP+3t7f/ycnJ/9HR0f/X19dNwsLCebW1 + tf+enp7/gYGB/1hYWP9WVlb/dXV1/zg4OP+UlJT/ioqK/x8fH/8kJCT/LCws/3l5ef+tra3/v7+//7S0 + tP+IiIj/OTk5/yQkJP8kJCT/JCQk/yUlJf8lJSX/JSUl/yQkJP8xMTH/sbGx/8bGxv/Ozs7/1tbW/9ra + 2k3BwcF5srKy/4iIiP9xcXH/bGxs/1tbW/92dnb/YWFh/05OTv8eHh7/IyMj/zMzM/+wsLD/zMzM/8vL + y//Ly8v/zMzM/8vLy//BwcH/SkpK/yMjI/8kJCT/JCQk/yUlJf8oKCj/QkJC/6qqqv/ExMT/zMzM/9PT + 0//Z2dn/3d3dTcLCwnm0tLT/enp6/2FhYf97e3v/SEhI/319ff+np6f/ISEh/yEhIf8jIyP/iIiI/8zM + zP/MzMz/zc3N/83Nzf/MzMz/y8vL/8rKyv+vr6//JSUl/yQkJP8kJCT/IyMj/yUlJf+lpaX/w8PD/8vL + y//R0dH/19fX/93d3f/g4OBNw8PDebm5uf+JiYn/Y2Nj/4GBgf9WVlb/Y2Nj/ykpKf8hISH/IyMj/yQk + JP+wsLD/zc3N/83Nzf/Nzc3/zc3N/8zMzP/Ly8v/y8vL/8zMzP8zMzP/JCQk/yUlJf8zMzP/lpaW/8HB + wf/Kysr/0dHR/9fX1//c3Nz/4ODg/+Pj403FxcV5tra2/4aGhv9WVlb/bm5u/7i4uP8rKyv/ISEh/yQk + JP8kJCT/JCQk/52dnf/Nzc3/zc3N/83Nzf/Nzc3/zMzM/8zMzP/Ly8v/wcHB/yoqKv8jIyP/ICAg/5aW + lv/AwMD/ycnJ/9DQ0P/X19f/3Nzc/+Dg4P/k5OT/5ubmTcnJyXm2trb/jY2N/1JSUv9zc3P/PDw8/yEh + If8jIyP/IyMj/yMjI/8kJCT/T09P/8nJyf/Nzc3/zc3N/83Nzf/Nzc3/zMzM/8vLy/95eXn/JCQk/ygo + KP+Dg4P/wMDA/8jIyP/Q0ND/1tbW/9vb2//g4OD/4+Pj/+bm5v/o6OhNzc3NecDAwP9nZ2f/tLS0/zw8 + PP8eHh7/IiIi/ysiIf8iIiL/IyMj/yMjI/8jIyP/VlZW/7e3t//MzMz/zc3N/8zMzP/ExMT/d3d3/yYm + Jv8dHR3/h4eH/8HBwf/Jycn/0NDQ/9bW1v/b29v/39/f/+Pj4//m5ub/6enp/+vr603S0tJ5zMzM/6mp + qf9VVVX/ICAg/yMjI/84Ix//ayYa/yIiIf8qIiH/NCMg/zQjIP8jIyP/JiYm/0hISP9dXV3/UVFR/y0t + Lf8jIyP/IiIi/2tra//BwcH/ysrK/9HR0f/W1tb/29vb/9/f3//j4+P/5ubm/+np6f/r6+v/7e3tTdfX + 13nS0tL/kpKS/ygoKP8jIyP/KyIg/3omF/9mJRn/cyYY/14lGv9TJRz/UyUc/1ckG/8oIyH/IyMj/yMj + I/8jIyP/IyMj/x0dHf93d3f/xMTE/8vLy//S0tL/19fX/9vb2//f39//4+Pj/+bm5v/o6Oj/6+vr/+3t + 7f/u7u5N29vbedfX1/+FhYX/IyMj/yMjI/8jISH/TyQc/2QkGP9yJhj/WyQa/2slGf86Ix7/XCUb/2Ml + G/8+Ix//JSMi/yMjI/8hISH/VVVV/8bGxv/Ozs7/1NTU/9nZ2f/d3d3/4ODg/+Pj4//m5ub/6Ojo/+vr + 6//t7e3/7+/v//Dw8E3g4OB53d3d/9PT0/9/f3//LCws/yIiIv8hISH/ISEh/0UjHf9XIxr/bCUY/2El + Gv8/Ix7/VSQc/10mG/8nIyL/Hx8f/2VlZf/Kysr/09PT/9fX1//b29v/39/f/+Li4v/l5eX/5+fn/+np + 6f/r6+v/7e3t/+/v7//w8PD/8fHxTeTk5Hni4uL/3t7e/9vb2//Dw8P/YGBg/yQkJP8iIiL/ISEh/yEh + If9fJRr/ZSUZ/1IkHP9eJRv/JSMi/yIiIv9AQED/ysrK/9jY2P/b29v/39/f/+Li4v/l5eX/5+fn/+np + 6f/q6ur/7Ozs/+7u7v/v7+//8fHx//Ly8v/z8/NN6Ojoeebm5v/k5OT/4eHh/9/f3//c3Nz/v7+//6io + qP8vLy//IiIi/yEhIf81IyD/ZiYa/zskIP8gICD/VFRU/83Nzf/d3d3/4ODg/+Pj4//l5eX/5+fn/+np + 6f/r6+v/7Ozs/+3t7f/v7+//8PDw//Hx8f/y8vL/8/Pz//T09E3s7Ox56+vr/+np6f/n5+f/5OTk/+Li + 4v/h4eH/39/f/5aWlv8wMDD/IiIi/yIiIv8jIyP/IiIi/ywsLP/Gxsb/4uLi/+Tk5P/m5ub/6Ojo/+np + 6f/r6+v/7Ozs/+7u7v/v7+//8PDw//Hx8f/y8vL/8/Pz//Pz8//09PT/9fX1Te7u7nnt7e3/7Ozs/+vr + 6//p6en/6Ojo/+bm5v/k5OT/4+Pj/9PT0/9vb2//JiYm/y0tLf+ysrL/1NTU/+bm5v/n5+f/6enp/+rq + 6v/s7Oz/7e3t/+7u7v/v7+//8PDw//Hx8f/y8vL/8vLy//Pz8//09PT/9fX1//X19f/29vZN8fHxefDw + 8P/v7+//7u7u/+3t7f/s7Oz/6urq/+np6f/o6Oj/6Ojo/+jo6P++vr7/urq6/+np6f/q6ur/6+vr/+vr + 6//t7e3/7u7u/+/v7//v7+//8PDw//Hx8f/y8vL/8/Pz//Pz8//09PT/9PT0//X19f/29vb/9vb2//f3 + 903z8/N58vLy//Hx8f/w8PD/8PDw/+/v7//u7u7/7e3t/+3t7f/s7Oz/7e3t/+3t7f/t7e3/7e3t/+3t + 7f/u7u7/7+/v//Dw8P/w8PD/8fHx//Ly8v/y8vL/8/Pz//T09P/09PT/9fX1//X19f/29vb/9vb2//f3 + 9//39/f/9/f3TQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAKAAAADAAAABgAAAAAQAgAAAAAACAJQAAAAAAAAAAAAAAAAAAAAAAAPDw + 8Dfv7+//7u7u/+3t7f/s7Oz/6+vr/+rq6v/p6en/5+fn/+Xl5f/j4+P/4eHh/9/f3//d3d3/29vb/9nZ + 2f/X19f/1NTU/9DQ0P/Ly8v/x8fH/8LCwv++vr7/urq6/7a2tv+xsbH/rq6u/62trf+srKz/rKys/62t + rf+vr6//sbGx/7S0tP+3t7f/u7u7/76+vv/BwcH/xcXF/8jIyP/Ly8v/z8/P/9LS0v/V1dX/2NjY/9zc + 3P/f39/x////Ae7u7jfu7u7/7e3t/+zs7P/r6+v/6enp/+jo6P/m5ub/5eXl/+Pj4//g4OD/3t7e/9zc + 3P/Z2dn/19fX/9TU1P/R0dH/zc3N/8jIyP/CwsL/vLy8/7e3t/+xsbH/qqqq/6Ojo/+enp7/nJyc/5ub + m/+cnJz/np6e/6CgoP+jo6P/pqam/6qqqv+urq7/srKy/7a2tv+6urr/vr6+/8HBwf/FxcX/ycnJ/83N + zf/R0dH/1dXV/9nZ2f/c3Nzx////Ae3t7Tfs7Oz/6+vr/+rq6v/p6en/6Ojo/+bm5v/k5OT/4uLi/+Dg + 4P/d3d3/29vb/9jY2P/V1dX/0tLS/87Ozv/Kysr/xMTE/7+/v/+5ubn/sbGx/6ioqP+fn5//ioqK/21t + bf+Ghob/iIiI/4iIiP+Li4v/jo6O/5GRkf+VlZX/mZmZ/56env+kpKT/qKio/62trf+xsbH/tbW1/7q6 + uv++vr7/w8PD/8jIyP/MzMz/0dHR/9XV1f/Z2dnx////Aezs7Dfr6+v/6urq/+jo6P/n5+f/5eXl/+Pj + 4//h4eH/39/f/9zc3P/Z2dn/19fX/9TU1P/Q0ND/zMzM/8fHx//CwsL/vLy8/7a2tv+urq7/pKSk/5iY + mP+MjIz/cHBw/2JiYv9zc3P/dnZ2/3d3d/96enr/fn5+/4ODg/+Hh4f/jIyM/5KSkv+YmJj/nZ2d/6Oj + o/+oqKj/ra2t/7Kysv+3t7f/vb29/8LCwv/Hx8f/zMzM/9HR0f/W1tbx////Aerq6jfp6en/6Ojo/+fn + 5//l5eX/4+Pj/+Hh4f/e3t7/3Nzc/9nZ2f/W1tb/09PT/8/Pz//Ly8v/xsbG/8DAwP+6urr/s7Oz/6ur + q/+hoaH/lJSU/4WFhf94eHj/ampq/2hoaP9oaGj/ZmZm/2hoaP9tbW3/cXFx/3V1df96enr/f39//4aG + hv+MjIz/kpKS/5iYmP+enp7/pKSk/6qqqv+wsLD/tra2/7y8vP/CwsL/x8fH/83Nzf/S0tLx////Aenp + 6Tfo6Oj/5ubm/+Xl5f/j4+P/4eHh/9/f3//c3Nz/2dnZ/9bW1v/S0tL/zs7O/8rKyv/FxcX/v7+//7i4 + uP+xsbH/qamp/5+fn/+RkZH/f39//2BgYP9nZ2f/aGho/29vb/9vb2//W1tb/11dXf9hYWH/ZWVl/2lp + af9ubm7/c3Nz/3p6ev+AgID/h4eH/42Njf+UlJT/m5ub/6Ghof+oqKj/r6+v/7W1tf+8vLz/wsLC/8nJ + yf/Ozs7x////Aejo6Dfn5+f/5eXl/+Pj4//h4eH/39/f/9zc3P/Z2dn/1tbW/9LS0v/Ozs7/ycnJ/8TE + xP+/v7//uLi4/7Gxsf+oqKj/nZ2d/5CQkP+AgID/ZmZm/0pKSv9XV1f/a2tr/3R0dP9xcXH/UlJS/1NT + U/84ODj/PT09/1tbW/9jY2P/aGho/25ubv91dXX/fHx8/4ODg/+Kior/kZGR/5mZmf+goKD/qKio/6+v + r/+3t7f/vr6+/8XFxf/Ly8vx////Aefn5zfm5ub/4+Pj/+Hh4f/f39//3Nzc/9ra2v/W1tb/09PT/87O + zv/Jycn/xMTE/76+vv+4uLj/sLCw/6ioqP+enp7/kJCQ/4GBgf9vb2//Xl5e/01NTf9VVVX/cXFx/42N + jf9xcXH/S0tL/zExMf8gICD/Hh4e/ygoKP9JSUn/XV1d/2NjY/9paWn/cXFx/3h4eP+AgID/iIiI/5CQ + kP+YmJj/oKCg/6mpqf+ysrL/urq6/8LCwv/Jycnx////AeXl5Tfk5OT/4uLi/9/f3//d3d3/2tra/9fX + 1//T09P/z8/P/8rKyv/FxcX/v7+//7i4uP+xsbH/qKio/5+fn/+RkZH/gYGB/2ZmZv9eXl7/WVlZ/2Nj + Y/9aWlr/i4uL/2tra/93d3f/VFRU/x0dHf8kJCT/Hh4e/x4eHv8eHh7/MjIy/1JSUv9eXl7/ZmZm/25u + bv91dXX/fn5+/4eHh/+QkJD/mZmZ/6Ojo/+tra3/tra2/7+/v//Gxsbx////AePj4zfi4uL/4ODg/93d + 3f/b29v/2NjY/9TU1P/Pz8//ysrK/8XFxf+/v7//uLi4/7Gxsf+pqan/n5+f/5OTk/+CgoL/ampq/0ZG + Rv9ISEj/YWFh/2VlZf9dXV3/cHBw/3Jycv/CwsL/jIyM/yQkJP8fHx//Hx8f/x4eHv8eHh7/HR0d/yEh + If8+Pj7/Wlpa/2NjY/9ra2v/dHR0/319ff+Hh4f/kZGR/5ycnP+np6f/s7Oz/7y8vP/FxcXx////AeLi + 4jfg4OD/3t7e/9vb2//Y2Nj/1dXV/9HR0f/Ly8v/xsbG/8DAwP+5ubn/srKy/6mpqf+fn5//kpKS/4SE + hP9zc3P/YWFh/0RERP9FRUX/ampq/3x8fP9WVlb/Xl5e/7e3t/+zs7P/KCgo/yIiIv8kJCT/JiYm/yIi + Iv8fHx//Hh4e/x4eHv8eHh7/KSkp/0xMTP9hYWH/ampq/3Nzc/99fX3/iIiI/5SUlP+ioqL/r6+v/7u7 + u//ExMTx////AeDg4Dff39//3Nzc/9nZ2f/V1dX/0dHR/8zMzP/Hx8f/wcHB/7q6uv+ysrL/qqqq/6Gh + of+Tk5P/hISE/3BwcP9lZWX/W1tb/15eXv9GRkb/fHx8/39/f/9hYWH/RERE/4iIiP8uLi7/IiIi/yMj + I/8lJSX/JiYm/yUlJf8kJCT/ISEh/x8fH/8eHh7/Hh4e/x8fH/83Nzf/Wlpa/2dnZ/9xcXH/fX19/42N + jf+cnJz/q6ur/7m5uf/ExMTx////Ad/f3zfd3d3/2tra/9bW1v/R0dH/zc3N/8fHx//BwcH/u7u7/7Oz + s/+rq6v/oaGh/5aWlv+Hh4f/c3Nz/0pKSv9LS0v/XFxc/2ZmZv9GRkb/hISE/2JiYv+dnZ3/mpqa/xwc + HP8cHBz/IyMj/yYmJv8mJib/JSUl/yYmJv8mJib/JSUl/yMjI/8fHx//Hx8f/x4eHv8eHh7/JSUl/0VF + Rf9jY2P/dHR0/4aGhv+YmJj/qamp/7i4uP/ExMTx////Ad3d3Tfb29v/19fX/9LS0v/Ozs7/yMjI/8LC + wv+8vLz/tLS0/6ysrP+jo6P/l5eX/4mJif94eHj/ZmZm/0hISP9DQ0P/ZWVl/3Jycv89PT3/V1dX/5aW + lv/a2tr/Pj4+/yIiIv8kJCT/JiYm/yYmJv8lJSX/JSUl/yYmJv8lJSX/JiYm/yUlJf8kJCT/ISEh/x8f + H/8fHx//Hx8f/x8fH/8xMTH/YWFh/3BwcP+Li4v/paWl/7e3t//ExMTx////Advb2zfY2Nj/1NTU/8/P + z//Jycn/xMTE/729vf+1tbX/ra2t/6SkpP+ZmZn/jIyM/3t7e/9ra2v/X19f/1ZWVv9CQkL/cHBw/42N + jf9OTk7/ODg4/7S0tP9JSUn/IyMj/yIiIv8mJib/JiYm/yYmJv8lJSX/JiYm/yYmJv8mJib/JiYm/yYm + Jv8lJSX/JSUl/yMjI/8gICD/Hx8f/yAgIP8gICD/IiIi/zk5Of91dXX/paWl/7e3t//FxcXx////AdjY + 2DfV1dX/0NDQ/8vLy//FxcX/v7+//7e3t/+vr6//paWl/5ubm/+NjY3/fX19/1RUVP9OTk7/W1tb/2Rk + ZP8/Pz//i4uL/1xcXP+FhYX/h4eH/xsbG/8eHh7/ISEh/yUlJf8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8lJSX/IiIi/yAgIP8gICD/ICAg/yAgIP9jY2P/pqam/7q6 + uv/Gxsbx////AdXV1TfT09P/zc3N/8fHx//AwMD/ubm5/7CwsP+np6f/nJyc/4+Pj/+AgID/b29v/01N + Tf9AQED/YWFh/2xsbP83Nzf/VlZW/319ff/Y2Nj/aWlp/yEhIf8fHx//JCQk/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yYmJv8lJSX/JiYm/yUlJf8lJSX/JiYm/yUlJf8lJSX/JSUl/yUlJf8gICD/ICAg/yAg + IP9YWFj/paWl/7+/v//IyMjx////AdPT0zfQ0ND/ysrK/8PDw/+7u7v/srKy/6mpqf+enp7/kZGR/4SE + hP90dHT/ZWVl/1RUVP8/Pz//aWlp/4qKiv9LS0v/NjY2/7u7u/+BgYH/JCQk/yEhIf8kJCT/JSUl/yQk + JP8lJSX/JSUl/yUlJf8lJSX/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8lJSX/JCQk/yAgIP9TU1P/paWl/8PDw//Ly8vx////AdDQ0DfNzc3/xsbG/76+vv+2trb/rKys/6Gh + of+UlJT/hoaG/2VlZf9VVVX/XV1d/2NjY/89PT3/hISE/2tra/9ubm7/YmJi/zY2Nv8jIyP/IiIi/yYm + Jv8lJSX/JCQk/yUlJf8lJSX/JCQk/yUlJf8lJSX/JSUl/yUlJf8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8lJSX/JiYm/yYmJv8lJSX/JiYm/yYmJv9sbGz/qKio/8fHx//Ozs7x////Ac3NzTfJycn/wsLC/7m5 + uf+vr6//pKSk/5eXl/+IiIj/dnZ2/1RUVP9BQUH/Xl5e/2pqav83Nzf/YWFh/2pqav+5ubn/pqam/yAg + IP8bGxv/IyMj/yQkJP8kJCT/JSUl/yUlJf8kJCT/JCQk/yQkJP8lJSX/JSUl/yUlJf8lJSX/JiYm/yUl + Jf8mJib/JiYm/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/xoaGv9iYmL/u7u7/8rKyv/Q0NDx////AcvL + yzfGxsb/vr6+/7Ozs/+np6f/mpqa/4uLi/96enr/bGxs/1hYWP8+Pj7/ZGRk/35+fv9UVFT/NjY2/6en + p/+4uLj/Jycn/yEhIf8iIiL/JCQk/yUlJf8lJSX/JSUl/yQkJP8kJCT/JCQk/yQkJP8lJSX/JSUl/yUl + Jf8lJSX/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8lJSX/HBwc/zU1Nf+vr6//xsbG/83N + zf/S0tLx////AcjIyDfDw8P/ubm5/62trf+goKD/kJCQ/3Z2dv9cXFz/Y2Nj/2NjY/9GRkb/cHBw/4GB + gf9dXV3/R0dH/0FBQf8wMDD/ICAg/yMjI/8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8jIyP/JCQk/yQk + JP8kJCT/JCQk/yUlJf8lJSX/JSUl/yUlJf8lJSX/JiYm/yYmJv8lJSX/JiYm/yUlJf81NTX/Pz8//6mp + qf/ExMT/ysrK/8/Pz//V1dXx////AcbGxjfAwMD/tbW1/6ampv+Xl5f/g4OD/2JiYv9FRUX/X19f/2pq + av9BQUH/bm5u/1xcXP+VlZX/zc3N/yIiIv8YGBj/IyMj/yQkJP8kJCT/KCgo/0VFRf9jY2P/a2tr/11d + Xf89PT3/JiYm/yMjI/8jIyP/JCQk/yQkJP8lJSX/JCQk/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yAg + IP9HR0f/q6ur/8HBwf/Hx8f/zc3N/9LS0v/X19fx////AcTExDe+vr7/sbGx/6Kiov+Pj4//enp6/2Nj + Y/9AQED/Y2Nj/3Z2dv9eXl7/MTEx/4qKiv/Z2dn/Ozs7/yEhIf8kJCT/JCQk/yQkJP9kZGT/srKy/8rK + yv/Ly8v/zMzM/8zMzP/Kysr/qKio/1NTU/8kJCT/JCQk/yQkJP8kJCT/JSUl/yQkJP8lJSX/JSUl/yUl + Jf8lJSX/IyMj/x0dHf+YmJj/wMDA/8bGxv/Ly8v/0NDQ/9XV1f/a2trx////AcTExDe9vb3/rq6u/5ub + m/92dnb/eXl5/2xsbP9VVVX/Y2Nj/5GRkf9XV1f/Nzc3/09PT/9OTk7/ICAg/yIiIv8kJCT/KSkp/4+P + j//MzMz/zMzM/8vLy//Ly8v/zMzM/8zMzP/MzMz/y8vL/8nJyf9/f3//JCQk/yMjI/8kJCT/JCQk/yQk + JP8kJCT/JSUl/yUlJf8rKyv/ISEh/5GRkf+/v7//xcXF/8rKyv/Pz8//09PT/9jY2P/c3Nzx////AcTE + xDe9vb3/rq6u/4qKiv9SUlL/cHBw/3Jycv9UVFT/b29v/1paWv9+fn7/y8vL/y4uLv8bGxv/Hx8f/yMj + I/8kJCT/d3d3/8rKyv/Ly8v/zMzM/8zMzP/MzMz/zMzM/8zMzP/Ly8v/ysrK/8rKyv/Jycn/Y2Nj/yMj + I/8jIyP/JCQk/yQkJP8kJCT/JCQk/yQkJP8/Pz//mpqa/729vf/Dw8P/ycnJ/83Nzf/S0tL/1tbW/9ra + 2v/e3t7x////AcTExDe/v7//sbGx/42Njf9MTEz/cHBw/3p6ev9qamr/OTk5/3V1df/Q0ND/bW1t/yAg + IP8fHx//IyMj/yQkJP8xMTH/wMDA/8zMzP/MzMz/zc3N/83Nzf/Nzc3/zc3N/8zMzP/Ly8v/y8vL/8rK + yv/Ly8v/srKy/ygoKP8kJCT/JCQk/yQkJP8kJCT/IiIi/xMTE/95eXn/u7u7/8PDw//IyMj/zc3N/9HR + 0f/W1tb/2dnZ/9zc3P/g4ODx////AcXFxTfAwMD/tbW1/5KSkv9qamr/ZWVl/5KSkv9lZWX/Ojo6/2ho + aP98fHz/ICAg/x8fH/8jIyP/JCQk/yQkJP9NTU3/zc3N/83Nzf/MzMz/zc3N/83Nzf/Nzc3/zc3N/83N + zf/MzMz/y8vL/8vLy//MzMz/y8vL/zg4OP8kJCT/JCQk/yQkJP8mJib/FRUV/29vb/+4uLj/wcHB/8fH + x//Nzc3/0dHR/9XV1f/Z2dn/3Nzc/9/f3//i4uLx////AcbGxjfBwcH/t7e3/4uLi/9vb2//aGho/29v + b/9paWn/srKy/zw8PP8jIyP/ICAg/yQkJP8jIyP/JCQk/yMjI/9MTEz/zMzM/8zMzP/MzMz/zMzM/83N + zf/Nzc3/zc3N/8zMzP/MzMz/zMzM/8zMzP/MzMz/y8vL/zs7O/8jIyP/JCQk/yQkJP85OTn/gICA/7m5 + uf/AwMD/xsbG/8zMzP/R0dH/1dXV/9jY2P/b29v/39/f/+Hh4f/k5OTx////AcfHxzfDw8P/r6+v/4WF + hf99fX3/Pj4+/2VlZf+xsbH/qamp/yAgIP8fHx//JCQk/yQkJP8jIyP/JCQk/yQkJP8xMTH/wMDA/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/MzMz/zMzM/8vLy//Ly8v/tra2/ykpKf8jIyP/IyMj/xIS + Ev9dXV3/tbW1/8DAwP/Gxsb/zMzM/9DQ0P/V1dX/2NjY/9zc3P/f39//4eHh/+Tk5P/m5ubx////AcnJ + yTfGxsb/rq6u/5CQkP+AgID/ODg4/3p6ev+tra3/JSUl/yAgIP8jIyP/IyMj/yMjI/8jIyP/IyMj/yQk + JP8kJCT/fn5+/83Nzf/MzMz/zc3N/83Nzf/MzMz/zc3N/83Nzf/MzMz/zMzM/8vLy//Kysr/bm5u/yQk + JP8kJCT/FhYW/01NTf+ysrL/wMDA/8bGxv/Ly8v/0NDQ/9TU1P/Y2Nj/29vb/9/f3//h4eH/4+Pj/+Xl + 5f/n5+fx////AczMzDfJycn/tLS0/4mJif9ZWVn/kZGR/05OTv8uLi7/Hx8f/yEhIf8iIiL/IiIi/yIi + Iv8iIiL/IyMj/yMjI/8jIyP/Kysr/5iYmP/MzMz/zMzM/83Nzf/MzMz/zMzM/8zMzP/MzMz/zMzM/8vL + y/+QkJD/Jycn/yMjI/81NTX/ZGRk/7S0tP/BwcH/xsbG/8vLy//Q0ND/1NTU/9jY2P/b29v/3t7e/+Hh + 4f/j4+P/5eXl/+fn5//p6enx////Ac/PzzfMzMz/vb29/11dXf+Ojo7/zs7O/zExMf8cHBz/ISEh/yIi + Iv8iIiL/NSIf/yIiIv8jIyP/IyMj/yMjI/8jIyP/IyMj/ygoKP9xcXH/vb29/8zMzP/Nzc3/zc3N/83N + zf/MzMz/ubm5/2pqav8nJyf/IyMj/xkZGf88PDz/ra2t/8HBwf/Gxsb/y8vL/9DQ0P/U1NT/2NjY/9vb + 2//e3t7/4ODg/+Pj4//l5eX/5+fn/+np6f/q6urx////AdLS0jfPz8//ysrK/62trf/Nzc3/OTk5/x8f + H/8hISH/IyMj/yIiIv9ZJBv/dCcZ/yIiIf8iIiL/IyMj/yMjI/8oIiH/IyIi/yMjI/8jIyP/Kysr/1NT + U/9vb2//fHx8/29vb/9OTk7/Kioq/yMjI/8jIyP/Gxsb/yoqKv+oqKj/wsLC/8fHx//MzMz/0NDQ/9TU + 1P/Y2Nj/29vb/97e3v/g4OD/4uLi/+Xl5f/n5+f/6enp/+rq6v/s7Ozx////AdXV1TfT09P/zs7O/7e3 + t/9CQkL/IiIi/yIiIv8kJCT/IiIi/00jHP+oKhP/SiMc/0MiHP9xJhj/WiQa/1wlG/9+KBj/LSMh/zEj + IP8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/JCQk/yMjI/8vLy//TExM/6mpqf/Dw8P/yMjI/83N + zf/R0dH/1dXV/9jY2P/b29v/3t7e/+Dg4P/j4+P/5eXl/+fn5//o6Oj/6urq/+zs7P/t7e3x////AdnZ + 2TfW1tb/0tLS/7y8vP8zMzP/IyMj/yMjI/8iIiL/NyIe/50pFP8tIR//bSYZ/4knFv85Ix//TyQc/y4i + If9gJhv/XiUb/3ImGP9BIx7/KCMh/yMjI/8jIyP/IyMj/yMjI/8kJCT/IyMj/x4eHv8lJSX/o6Oj/8XF + xf/Kysr/zs7O/9LS0v/W1tb/2dnZ/9zc3P/e3t7/4ODg/+Pj4//l5eX/5+fn/+jo6P/q6ur/6+vr/+3t + 7f/u7u7x////Adzc3DfZ2dn/1dXV/7Gxsf8lJSX/IyMj/yMjI/8iIiL/JCEh/1gkG/97Jhb/aCQX/34n + F/95Jhf/aiUZ/3wmF/88Ix7/UCQc/20mGf9oJhr/bSYZ/zIjIP8iIiL/IyMj/yMjI/8jIyP/ISEh/xkZ + Gf+YmJj/yMjI/8zMzP/Q0ND/1NTU/9fX1//a2tr/3d3d/9/f3//h4eH/4+Pj/+Xl5f/n5+f/6Ojo/+rq + 6v/r6+v/7e3t/+7u7v/v7+/x////Ad/f3zfd3d3/2dnZ/8fHx/9OTk7/JCQk/yMjI/8iIiL/IiIi/yEh + If8pISD/QSMd/0QjHf9pJRn/ISAg/3QlF/9DIx3/WCQb/ywiIP84Ix//aiYa/2UmGv9TJRz/IiIi/yIi + Iv8rKyv/Pj4+/5WVlf/Ly8v/z8/P/9LS0v/V1dX/2dnZ/9zc3P/e3t7/4ODg/+Li4v/k5OT/5eXl/+fn + 5//p6en/6urq/+vr6//t7e3/7u7u/+/v7//w8PDx////AeHh4Tfg4OD/3d3d/9ra2v/V1dX/k5OT/zc3 + N/8iIiL/IiIi/yIiIv8hISH/ISEh/yQhIP9oJRn/cSQX/2glGf+EJxb/PiMe/0kjHP9BIx7/YiUa/28m + Gf8kIyL/IyMj/yIiIv8cHBz/kJCQ/87Ozv/S0tL/1dXV/9jY2P/b29v/3d3d/+Dg4P/i4uL/5OTk/+Xl + 5f/n5+f/6Ojo/+np6f/r6+v/7Ozs/+3t7f/u7u7/7+/v//Dw8P/x8fHx////AeTk5Dfj4+P/4ODg/97e + 3v/b29v/2dnZ/8vLy/91dXX/Kioq/yIiIv8iIiL/IiIi/yEhIf8hISH/ISEg/1wkGv90Jhj/QyIc/4An + F/8mIiH/ZyYa/ygjIv8jIyP/JCQk/xQUFP99fX3/0dHR/9bW1v/Y2Nj/2tra/93d3f/f39//4uLi/+Tk + 5P/l5eX/5+fn/+jo6P/p6en/6urq/+vr6//s7Oz/7u7u/+/v7//w8PD/8PDw//Hx8f/y8vLx////Aefn + 5zfm5ub/4+Pj/+Hh4f/g4OD/3t7e/9zc3P/Z2dn/t7e3/1paWv9PT0//NTU1/yIiIv8hISH/ISEh/yEh + If9UJBz/iSgW/0QjHf9yJhj/VCYd/yMjIv8nJyf/Nzc3/3Z2dv/S0tL/2dnZ/9vb2//e3t7/4ODg/+Li + 4v/k5OT/5eXl/+fn5//o6Oj/6enp/+rq6v/r6+v/7Ozs/+3t7f/u7u7/7+/v//Dw8P/x8fH/8vLy//Ly + 8v/z8/Px////Aenp6Tfp6en/5+fn/+Xl5f/j4+P/4uLi/+Dg4P/e3t7/3d3d/9vb2//a2tr/ysrK/0BA + QP8iIiL/IiIi/yIiIv8iIiL/KCIh/2snGv9RJR7/IyMi/yIiIv8bGxv/eXl5/9bW1v/d3d3/39/f/+Dg + 4P/i4uL/5OTk/+bm5v/n5+f/6Ojo/+np6f/q6ur/6+vr/+zs7P/t7e3/7u7u/+/v7//w8PD/8PDw//Hx + 8f/y8vL/8/Pz//Pz8//09PTx////Aezs7Dfr6+v/6urq/+jo6P/n5+f/5eXl/+Tk5P/j4+P/4eHh/+Dg + 4P/f39//3t7e/5SUlP8rKyv/IiIi/yIiIv8iIiL/IiIi/yMjI/8iIiL/IyMj/xYWFv9SUlL/1dXV/+Hh + 4f/i4uL/4+Pj/+Xl5f/m5ub/5+fn/+np6f/q6ur/6+vr/+zs7P/t7e3/7e3t/+7u7v/v7+//7+/v//Dw + 8P/x8fH/8vLy//Ly8v/z8/P/8/Pz//T09P/19fXx////Ae3t7Tft7e3/7Ozs/+vr6//q6ur/6enp/+fn + 5//m5ub/5eXl/+Tk5P/j4+P/4uLi/+Hh4f/IyMj/YmJi/yQkJP8jIyP/IyMj/yMjI/8kJCT/WFhY/11d + Xf/U1NT/5OTk/+Xl5f/m5ub/5+fn/+jo6P/p6en/6urq/+vr6//s7Oz/7e3t/+7u7v/u7u7/7+/v//Dw + 8P/w8PD/8fHx//Hx8f/y8vL/8/Pz//Pz8//09PT/9PT0//X19f/19fXx////Ae/v7zfu7u7/7u7u/+3t + 7f/s7Oz/6+vr/+rq6v/p6en/6Ojo/+fn5//m5ub/5eXl/+Xl5f/k5OT/4+Pj/7CwsP9HR0f/IyMj/yMj + I/+Dg4P/5OTk/+Xl5f/m5ub/5+fn/+jo6P/p6en/6urq/+vr6//s7Oz/7Ozs/+3t7f/u7u7/7+/v/+/v + 7//w8PD/8fHx//Hx8f/y8vL/8vLy//Ly8v/z8/P/8/Pz//T09P/09PT/9fX1//X19f/29vbx////AfHx + 8Tfw8PD/7+/v/+/v7//u7u7/7e3t/+zs7P/s7Oz/6+vr/+rq6v/p6en/6Ojo/+jo6P/n5+f/6Ojo/+jo + 6P/f39//kZGR/4GBgf/m5ub/6enp/+np6f/p6en/6urq/+vr6//s7Oz/7Ozs/+3t7f/u7u7/7u7u/+/v + 7//v7+//8PDw//Hx8f/x8fH/8vLy//Ly8v/z8/P/8/Pz//Pz8//09PT/9PT0//X19f/19fX/9vb2//b2 + 9v/29vbx////AfLy8jfy8vL/8fHx//Dw8P/w8PD/7+/v/+7u7v/u7u7/7e3t/+zs7P/s7Oz/6+vr/+vr + 6//q6ur/6urq/+rq6v/r6+v/6+vr/+vr6//r6+v/6+vr/+zs7P/s7Oz/7e3t/+3t7f/u7u7/7u7u/+/v + 7//v7+//8PDw//Dw8P/x8fH/8fHx//Ly8v/y8vL/8/Pz//Pz8//09PT/9PT0//T09P/19fX/9fX1//X1 + 9f/29vb/9vb2//f39//39/fx////AfPz8zfz8/P/8vLy//Ly8v/x8fH/8fHx//Dw8P/w8PD/7+/v/+/v + 7//u7u7/7u7u/+3t7f/t7e3/7e3t/+3t7f/t7e3/7e3t/+3t7f/t7e3/7u7u/+7u7v/u7u7/7+/v/+/v + 7//w8PD/8PDw//Dw8P/x8fH/8fHx//Ly8v/y8vL/8/Pz//Pz8//z8/P/9PT0//T09P/19fX/9fX1//X1 + 9f/29vb/9vb2//b29v/29vb/9/f3//f39//39/fx////AQAAAAAAAP//AAAAAAAA//8AAAAAAAD//wAA + AAAAAP//AAAAAAAA//8AAAAAAAD//wAAAAAAAP//AAAAAAAA//8AAAAAAAD//wAAAAAAAP//AAAAAAAA + //8AAAAAAAD//wAAAAAAAP//AAAAAAAA//8AAAAAAAD//wAAAAAAAP//AAAAAAAA//8AAAAAAAD//wAA + AAAAAP//AAAAAAAA//8AAAAAAAD//wAAAAAAAP//AAAAAAAA//8AAAAAAAD//wAAAAAAAP//AAAAAAAA + //8AAAAAAAD//wAAAAAAAP//AAAAAAAA//8AAAAAAAD//wAAAAAAAP//AAAAAAAA//8AAAAAAAD//wAA + AAAAAP//AAAAAAAA//8AAAAAAAD//wAAAAAAAP//AAAAAAAA//8AAAAAAAD//wAAAAAAAP//AAAAAAAA + //8AAAAAAAD//wAAAAAAAP//AAAAAAAA//8AAAAAAAD//wAAAAAAAP//AAAAAAAA//8AAAAAAAD//ygA + AABAAAAAgAAAAAEAIAAAAAAAAEIAAAAAAAAAAAAAAAAAAAAAAAD///8B7+/v8e/v7//u7u7/7u7u/+3t + 7f/s7Oz/6+vr/+rq6v/p6en/6Ojo/+fn5//m5ub/5OTk/+Pj4//h4eH/4ODg/97e3v/d3d3/29vb/9ra + 2v/Y2Nj/19fX/9XV1f/R0dH/zs7O/8vLy//Hx8f/xMTE/8HBwf++vr7/u7u7/7i4uP+1tbX/srKy/7Cw + sP+vr6//rq6u/62trf+urq7/r6+v/7CwsP+xsbH/s7Oz/7W1tf+3t7f/urq6/7y8vP+/v7//wcHB/8TE + xP/Gxsb/yMjI/8vLy//Nzc3/0NDQ/9LS0v/V1dX/19fX/9nZ2f/c3Nz/3t7e/+Dg4Jf///8B////Ae/v + 7/Hu7u7/7e3t/+3t7f/s7Oz/6+vr/+rq6v/p6en/6Ojo/+fn5//l5eX/5OTk/+Li4v/h4eH/39/f/93d + 3f/c3Nz/2tra/9jY2P/W1tb/1dXV/9LS0v/Q0ND/zMzM/8jIyP/ExMT/wMDA/7y8vP+4uLj/tLS0/7Cw + sP+srKz/qKio/6Wlpf+kpKT/o6Oj/6Kiov+ioqL/o6Oj/6Wlpf+np6f/qKio/6qqqv+tra3/sLCw/7Oz + s/+2trb/uLi4/7u7u/++vr7/wcHB/8PDw//Gxsb/ycnJ/8vLy//Ozs7/0dHR/9TU1P/W1tb/2dnZ/9zc + 3P/e3t6X////Af///wHu7u7x7e3t/+zs7P/s7Oz/6+vr/+rq6v/p6en/5+fn/+bm5v/l5eX/5OTk/+Li + 4v/g4OD/3t7e/93d3f/b29v/2dnZ/9fX1//U1NT/0tLS/9DQ0P/Nzc3/ycnJ/8bGxv/BwcH/vLy8/7e3 + t/+ysrL/rq6u/6ioqP+hoaH/k5OT/5iYmP+VlZX/lJSU/5SUlP+VlZX/lpaW/5iYmP+ampr/nJyc/5+f + n/+hoaH/paWl/6mpqf+srKz/r6+v/7Kysv+1tbX/uLi4/7u7u/++vr7/wcHB/8TExP/Hx8f/ysrK/87O + zv/R0dH/1NTU/9fX1//a2tr/3Nzcl////wH///8B7e3t8ezs7P/r6+v/6urq/+np6f/o6Oj/5+fn/+bm + 5v/k5OT/4+Pj/+Hh4f/f39//3t7e/9zc3P/a2tr/2NjY/9XV1f/T09P/0NDQ/87Ozv/Kysr/x8fH/8PD + w/+/v7//urq6/7W1tf+urq7/qKio/6Ghof+ZmZn/fX19/2RkZP94eHj/hoaG/4WFhf+Ghob/h4eH/4qK + iv+MjIz/jo6O/5GRkf+VlZX/mJiY/5ycnP+goKD/pKSk/6enp/+rq6v/rq6u/7Kysv+1tbX/uLi4/7u7 + u/+/v7//w8PD/8bGxv/Kysr/zs7O/9HR0f/U1NT/19fX/9ra2pf///8B////Aezs7PHr6+v/6urq/+np + 6f/o6Oj/5+fn/+Xl5f/k5OT/4uLi/+Hh4f/f39//3d3d/9vb2//Z2dn/19fX/9XV1f/S0tL/z8/P/8zM + zP/IyMj/xcXF/8HBwf+8vLz/uLi4/7Ozs/+tra3/pKSk/5ycnP+Tk5P/ioqK/2pqav9jY2P/ampq/3l5 + ef94eHj/eHh4/3p6ev99fX3/gYGB/4SEhP+Hh4f/i4uL/4+Pj/+Tk5P/l5eX/5ubm/+fn5//o6Oj/6en + p/+rq6v/r6+v/7Kysv+2trb/urq6/76+vv/CwsL/xsbG/8rKyv/Nzc3/0dHR/9XV1f/X19eX////Af// + /wHq6urx6enp/+jo6P/n5+f/5ubm/+Xl5f/k5OT/4uLi/+Dg4P/e3t7/3Nzc/9ra2v/Y2Nj/1tbW/9TU + 1P/R0dH/zs7O/8vLy//Hx8f/w8PD/7+/v/+6urr/tbW1/7CwsP+qqqr/oqKi/5iYmP+Ojo7/g4OD/3p6 + ev9oaGj/ZWVl/2dnZ/9tbW3/bGxs/21tbf9wcHD/c3Nz/3Z2dv96enr/fX19/4GBgf+FhYX/ioqK/46O + jv+Tk5P/l5eX/5ubm/+goKD/pKSk/6ioqP+srKz/sLCw/7W1tf+5ubn/vr6+/8LCwv/Gxsb/ysrK/87O + zv/S0tL/1dXVl////wH///8B6enp8ejo6P/n5+f/5ubm/+Xl5f/k5OT/4uLi/+Dg4P/e3t7/3Nzc/9ra + 2v/Y2Nj/1tbW/9PT0//R0dH/zs7O/8rKyv/Hx8f/w8PD/76+vv+5ubn/s7Oz/66urv+oqKj/oKCg/5aW + lv+MjIz/gICA/3Z2dv9ubm7/Z2dn/2tra/9tbW3/Y2Nj/2JiYv9jY2P/Z2dn/2pqav9tbW3/cHBw/3Nz + c/93d3f/fHx8/4CAgP+FhYX/ioqK/46Ojv+Tk5P/mJiY/52dnf+hoaH/pqam/6urq/+vr6//tLS0/7m5 + uf+9vb3/wsLC/8bGxv/Ly8v/z8/P/9LS0pf///8B////Aejo6PHn5+f/5ubm/+Xl5f/j4+P/4uLi/+Dg + 4P/f39//3d3d/9ra2v/Y2Nj/1tbW/9PT0//Q0ND/zc3N/8rKyv/Hx8f/w8PD/76+vv+4uLj/s7Oz/62t + rf+mpqb/n5+f/5SUlP+Kior/eHh4/1dXV/9fX1//Z2dn/2lpaf9vb2//dHR0/2VlZf9aWlr/W1tb/15e + Xv9hYWH/ZGRk/2dnZ/9qamr/bm5u/3Nzc/93d3f/fHx8/4GBgf+Ghob/i4uL/5CQkP+VlZX/mpqa/5+f + n/+kpKT/qqqq/6+vr/+0tLT/ubm5/76+vv/Dw8P/yMjI/8zMzP/Pz8+X////Af///wHo6Ojx5ubm/+Xl + 5f/k5OT/4uLi/+Dg4P/f39//3d3d/9vb2//Y2Nj/1tbW/9PT0//Q0ND/zc3N/8nJyf/Gxsb/wsLC/729 + vf+4uLj/s7Oz/62trf+mpqb/nZ2d/5SUlP+IiIj/fHx8/2JiYv9MTEz/TExM/2JiYv9sbGz/cXFx/3Z2 + dv9jY2P/UlJS/1RUVP9PT0//NDQ0/0xMTP9eXl7/YmJi/2ZmZv9qamr/b29v/3Nzc/95eXn/fn5+/4OD + g/+JiYn/jo6O/5SUlP+ZmZn/np6e/6SkpP+qqqr/r6+v/7W1tf+6urr/v7+//8XFxf/Jycn/zc3Nl/// + /wH///8B5+fn8eXl5f/k5OT/4uLi/+Hh4f/f39//3d3d/9vb2//Z2dn/1tbW/9PT0//Q0ND/zc3N/8nJ + yf/FxcX/wcHB/729vf+4uLj/s7Oz/62trf+mpqb/np6e/5SUlP+IiIj/fHx8/3BwcP9dXV3/TExM/0dH + R/9kZGT/b29v/319ff+CgoL/YWFh/0xMTP9JSUn/JCQk/xwcHP8gICD/NjY2/1RUVP9eXl7/YmJi/2Zm + Zv9ra2v/cHBw/3Z2dv97e3v/gYGB/4eHh/+MjIz/kpKS/5iYmP+enp7/pKSk/6urq/+xsbH/t7e3/7y8 + vP/CwsL/x8fH/8vLy5f///8B////Aebm5vHk5OT/4uLi/+Hh4f/f39//3d3d/9vb2//Z2dn/19fX/9TU + 1P/R0dH/zc3N/8rKyv/Gxsb/wcHB/729vf+4uLj/s7Oz/6ysrP+mpqb/np6e/5WVlf+JiYn/fn5+/3Bw + cP9iYmL/W1tb/1dXV/9NTU3/ZWVl/3l5ef+Xl5f/ampq/2xsbP9GRkb/JSUl/xsbG/8vLy//Hh4e/x4e + Hv8kJCT/QkJC/1hYWP9eXl7/Y2Nj/2hoaP9ubm7/c3Nz/3l5ef9/f3//hYWF/4yMjP+SkpL/mJiY/5+f + n/+mpqb/ra2t/7Ozs/+6urr/v7+//8XFxf/JycmX////Af///wHk5OTx4+Pj/+Hh4f/f39//3t7e/9zc + 3P/Z2dn/19fX/9TU1P/R0dH/zs7O/8rKyv/Gxsb/wsLC/729vf+4uLj/s7Oz/62trf+mpqb/n5+f/5WV + lf+Kior/fX19/2FhYf9eXl7/VlZW/1paWv9mZmb/VlZW/21tbf+Wlpb/Z2dn/2xsbP+Ghob/RERE/xsb + G/8mJib/HBwc/x4eHv8eHh7/Hh4e/x4eHv8sLCz/TExM/1paWv9gYGD/ZmZm/2xsbP9xcXH/d3d3/35+ + fv+EhIT/i4uL/5KSkv+ampr/oaGh/6ioqP+wsLD/t7e3/729vf/Dw8P/yMjIl////wH///8B4+Pj8eHh + 4f/g4OD/3t7e/9zc3P/a2tr/2NjY/9XV1f/S0tL/zs7O/8rKyv/Hx8f/wsLC/729vf+4uLj/s7Oz/66u + rv+np6f/n5+f/5eXl/+Kior/fn5+/2dnZ/9ISEj/QUFB/1FRUf9jY2P/ampq/01NTf+EhIT/bm5u/2Vl + Zf+IiIj/5eXl/39/f/8jIyP/Hx8f/x8fH/8eHh7/Hh4e/x4eHv8eHh7/HR0d/x8fH/83Nzf/VFRU/15e + Xv9kZGT/aWlp/3BwcP92dnb/fX19/4SEhP+MjIz/k5OT/5ycnP+kpKT/rKys/7S0tP+8vLz/wsLC/8fH + x5f///8B////AeLi4vHg4OD/3t7e/9zc3P/a2tr/2NjY/9bW1v/T09P/z8/P/8vLy//Hx8f/w8PD/76+ + vv+5ubn/s7Oz/62trf+np6f/n5+f/5aWlv+MjIz/f39//3Jycv9fX1//SUlJ/zo6Ov9XV1f/aWlp/3Bw + cP9PT0//V1dX/11dXf+IiIj/39/f/7S0tP8nJyf/Jycn/yEhIf8lJSX/JCQk/x8fH/8fHx//Hh4e/x4e + Hv8eHh7/Hh4e/yUlJf9ERET/W1tb/2JiYv9oaGj/b29v/3Z2dv99fX3/hYWF/42Njf+Wlpb/n5+f/6mp + qf+ysrL/urq6/8HBwf/GxsaX////Af///wHh4eHx39/f/93d3f/b29v/2NjY/9bW1v/T09P/0NDQ/8zM + zP/IyMj/w8PD/76+vv+5ubn/tLS0/66urv+np6f/oKCg/5aWlv+Li4v/gICA/3R0dP9nZ2f/XV1d/01N + Tf86Ojr/WVlZ/25ubv+Li4v/c3Nz/05OTv9dXV3/0dHR/8bGxv8uLi7/JiYm/yAgIP8kJCT/JSUl/yYm + Jv8lJSX/IiIi/x8fH/8eHh7/Hh4e/x4eHv8eHh7/Hh4e/zAwMP9RUVH/YWFh/2dnZ/9ubm7/dXV1/319 + ff+Ghob/kJCQ/5qamv+lpaX/r6+v/7m5uf/BwcH/xsbGl////wH///8B4ODg8d7e3v/b29v/2dnZ/9bW + 1v/T09P/0NDQ/8zMzP/IyMj/xMTE/7+/v/+6urr/tLS0/66urv+oqKj/oaGh/5iYmP+MjIz/gYGB/25u + bv9mZmb/Xl5e/1paWv9iYmL/SkpK/1lZWf+Ghob/hYWF/1hYWP9paWn/Ozs7/2xsbP81NTX/JiYm/yAg + IP8kJCT/JSUl/yYmJv8mJib/JiYm/yUlJf8kJCT/ISEh/x8fH/8eHh7/Hh4e/x4eHv8eHh7/IiIi/z4+ + Pv9bW1v/ZGRk/2tra/90dHT/fn5+/4qKiv+Wlpb/oaGh/62trf+3t7f/wcHB/8bGxpf///8B////Ad7e + 3vHc3Nz/2tra/9fX1//U1NT/0NDQ/8zMzP/IyMj/xMTE/8DAwP+7u7v/tbW1/6+vr/+oqKj/oaGh/5mZ + mf+Ojo7/goKC/3Jycv9OTk7/RUVF/1RUVP9dXV3/ZmZm/0ZGRv9qamr/ioqK/1RUVP99fX3/tLS0/4CA + gP8bGxv/HR0d/x4eHv8jIyP/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yUlJf8jIyP/Hx8f/x8f + H/8fHx//Hh4e/x4eHv8eHh7/KSkp/0pKSv9fX1//ampq/3d3d/+EhIT/kpKS/5+fn/+rq6v/tra2/8DA + wP/Hx8eX////Af///wHd3d3x2tra/9fX1//U1NT/0dHR/83Nzf/Jycn/xcXF/8DAwP+7u7v/tra2/7Cw + sP+qqqr/oqKi/5qamv+QkJD/hISE/3d3d/9nZ2f/TExM/zw8PP9SUlL/ZGRk/2pqav9BQUH/Wlpa/1RU + VP97e3v/ra2t/+rq6v9OTk7/IiIi/xsbG/8kJCT/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JSUl/yMjI/8hISH/Hx8f/x8fH/8fHx//Hx8f/x8fH/8gICD/NjY2/11dXf9ycnL/f39//4yM + jP+cnJz/qamp/7W1tf/AwMD/x8fHl////wH///8B29vb8djY2P/V1dX/0tLS/87Ozv/Kysr/xsbG/8HB + wf+8vLz/t7e3/7Gxsf+qqqr/pKSk/5ycnP+SkpL/h4eH/3p6ev9tbW3/YWFh/05OTv82Njb/VFRU/2lp + af94eHj/bGxs/zMzM/9fX1//pKSk/+/v7/9gYGD/JCQk/yAgIP8kJCT/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8lJSX/JCQk/yMjI/8fHx//Hx8f/x8fH/8fHx//Hx8f/x8f + H/8mJib/Tk5O/1xcXP9oaGj/k5OT/6enp/+0tLT/wMDA/8fHx5f///8B////AdnZ2fHW1tb/09PT/8/P + z//Ly8v/x8fH/8LCwv+9vb3/t7e3/7Kysv+rq6v/pKSk/52dnf+Tk5P/iIiI/3t7e/9vb2//ZWVl/1xc + XP9cXFz/SkpK/09PT/92dnb/l5eX/1lZWf9GRkb/MTEx/6enp/9tbW3/IiIi/yAgIP8iIiL/JSUl/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yUlJf8lJSX/JCQk/yIi + Iv8fHx//Hx8f/yAgIP8gICD/ICAg/yAgIP8pKSn/Wlpa/46Ojv+np6f/tbW1/8HBwf/Hx8eX////Af// + /wHX19fx1NTU/9DQ0P/MzMz/yMjI/8PDw/++vr7/ubm5/7Ozs/+srKz/paWl/52dnf+UlJT/iYmJ/319 + ff9cXFz/SkpK/1lZWf9aWlr/Y2Nj/0xMTP9TU1P/k5OT/2BgYP9sbGz/i4uL/2BgYP8YGBj/Hh4e/yEh + If8hISH/JSUl/yUlJf8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8lJSX/JCQk/yEhIf8gICD/ICAg/yAgIP8gICD/ICAg/zQ0NP+QkJD/qKio/7e3 + t//Dw8P/yMjIl////wH///8B1dXV8dLS0v/Ozs7/ycnJ/8XFxf/AwMD/urq6/7S0tP+urq7/p6en/5+f + n/+VlZX/i4uL/39/f/9xcXH/UVFR/zw8PP9OTk7/YWFh/2dnZ/9ISEj/UVFR/2lpaf9kZGT/ioqK/+fn + 5/+NjY3/Hh4e/xgYGP8fHx//JCQk/yUlJf8lJSX/JSUl/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yUlJf8lJSX/IyMj/yAgIP8gICD/ICAg/yEh + If8uLi7/jo6O/6urq/+7u7v/xcXF/8nJyZf///8B////AdPT0/HPz8//y8vL/8bGxv/BwcH/u7u7/7W1 + tf+vr6//qKio/6CgoP+Wlpb/jY2N/4GBgf91dXX/aWlp/1NTU/82Njb/TU1N/2dnZ/9vb2//Y2Nj/yoq + Kv9SUlL/hoaG/9/f3/+pqan/JSUl/yQkJP8gICD/JCQk/yUlJf8lJSX/JSUl/yUlJf8lJSX/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8kJCT/ISEh/yAgIP8gICD/Jycn/4ODg/+qqqr/wMDA/8fHx//Ly8uX////Af///wHR0dHxzc3N/8jI + yP/Dw8P/vb29/7e3t/+wsLD/qqqq/6Kiov+YmJj/jo6O/4SEhP93d3f/bW1t/2NjY/9aWlr/R0dH/0hI + SP9tbW3/jIyM/3R0dP8vLy//MjIy/6+vr//AwMD/Jycn/yYmJv8gICD/JCQk/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JSUl/yYmJv8kJCT/ICAg/yUlJf+EhIT/ra2t/8PDw//Jycn/zc3Nl/// + /wH///8Bz8/P8cvLy//Gxsb/wMDA/7q6uv+zs7P/rKys/6SkpP+bm5v/kZGR/4aGhv9xcXH/VVVV/19f + X/9dXV3/YmJi/1ZWVv8/Pz//h4eH/4GBgf9TU1P/cHBw/zc3N/8nJyf/R0dH/yQkJP8hISH/JiYm/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yUlJf81NTX/i4uL/6+v + r//Gxsb/y8vL/8/Pz5f///8B////Ac3NzfHIyMj/w8PD/7y8vP+1tbX/rq6u/6ampv+dnZ3/kpKS/4eH + h/96enr/WVlZ/0RERP9NTU3/Xl5e/2dnZ/9UVFT/QUFB/4uLi/9PT0//fHx8/7y8vP/Gxsb/Hh4e/xgY + GP8dHR3/JCQk/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yUl + Jf8lJSX/SUlJ/4+Pj/+4uLj/ycnJ/83Nzf/R0dGX////Af///wHLy8vxxcXF/7+/v/+4uLj/sLCw/6io + qP+fn5//lZWV/4mJif98fHz/b29v/1paWv8/Pz//SEhI/2VlZf9ra2v/YmJi/yQkJP9JSUn/enp6/7Gx + sf/k5OT/QEBA/yMjI/8dHR3/ISEh/yQkJP8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yUlJf8kJCT/ERER/y8vL/+rq6v/xcXF/8rKyv/Pz8//0tLSl////wH///8BycnJ8cPD + w/+8vLz/tLS0/6urq/+ioqL/l5eX/4yMjP9/f3//c3Nz/2lpaf9eXl7/RERE/0VFRf9paWn/fHx8/4uL + i/8nJyf/Ojo6/5ycnP/o6Oj/UlJS/yIiIv8gICD/IiIi/yQkJP8lJSX/JSUl/yUlJf8lJSX/JSUl/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8kJCT/FhYW/ywsLP+fn5//wsLC/8jIyP/MzMz/0NDQ/9TU + 1Jf///8B////AcbGxvHAwMD/ubm5/7CwsP+mpqb/m5ub/4+Pj/+AgID/YmJi/2ZmZv9kZGT/YWFh/2Bg + YP84ODj/d3d3/5SUlP9WVlb/W1tb/ygoKP87Ozv/XV1d/yEhIf8fHx//IiIi/yQkJP8lJSX/JSUl/yUl + Jf8lJSX/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8nJyf/Kysr/ygoKP+ZmZn/wMDA/8bG + xv/Kysr/zs7O/9LS0v/W1taX////Af///wHFxcXxvr6+/7W1tf+rq6v/oKCg/5OTk/+Ghob/a2tr/0tL + S/9MTEz/YWFh/2ZmZv9hYWH/NjY2/5KSkv9dXV3/aWlp/5KSkv/FxcX/ISEh/yEhIf8bGxv/IiIi/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JiYm/ysrK/8rKyv/KCgo/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JiYm/yYmJv8mJib/JiYm/yYmJv8lJSX/NTU1/2tr + a/+jo6P/v7+//8TExP/IyMj/zMzM/9HR0f/V1dX/2NjYl////wH///8Bw8PD8bu7u/+xsbH/pqam/5qa + mv+MjIz/fHx8/2ZmZv9JSUn/RkZG/2RkZP9sbGz/Z2dn/ycnJ/9UVFT/YmJi/4uLi//p6en/hoaG/x8f + H/8bGxv/ICAg/yUlJf8kJCT/IyMj/ygoKP9OTk7/f39//6Ghof+ysrL/s7Oz/6ioqP+Pj4//YmJi/zMz + M/8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8mJib/JiYm/yUl + Jf8lJSX/HBwc/xkZGf+Li4v/vLy8/8LCwv/Gxsb/y8vL/8/Pz//T09P/19fX/9nZ2Zf///8B////AcLC + wvG5ubn/r6+v/6Ojo/+Wlpb/hoaG/3d3d/9nZ2f/SkpK/0VFRf9qamr/dHR0/5CQkP8uLi7/Nzc3/4CA + gP/j4+P/m5ub/x0dHf8hISH/IiIi/yYmJv8kJCT/IyMj/0hISP+lpaX/ycnJ/8vLy//Ly8v/y8vL/8zM + zP/MzMz/zc3N/83Nzf++vr7/cnJy/yoqKv8kJCT/JCQk/yQkJP8kJCT/JCQk/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yYmJv8lJSX/IiIi/xEREf9/f3//u7u7/8LCwv/Gxsb/ycnJ/83Nzf/R0dH/1dXV/9jY + 2P/b29uX////Af///wHBwcHxuLi4/62trf+hoaH/h4eH/35+fv94eHj/bGxs/2hoaP9BQUH/bGxs/5OT + k/92dnb/RkZG/yQkJP9LS0v/lZWV/yAgIP8iIiL/ICAg/yUlJf8kJCT/JCQk/2lpaf/Gxsb/zc3N/8zM + zP/Ly8v/y8vL/8vLy//MzMz/zMzM/8zMzP/MzMz/y8vL/8rKyv+np6f/Nzc3/yMjI/8kJCT/JCQk/yQk + JP8kJCT/JCQk/yUlJf8lJSX/JSUl/yUlJf8lJSX/IyMj/wwMDP93d3f/uLi4/8HBwf/FxcX/ycnJ/8zM + zP/Q0ND/1NTU/9fX1//a2tr/3Nzcl////wH///8BwcHB8be3t/+srKz/mJiY/2FhYf9VVVX/eXl5/3Bw + cP9ubm7/Ojo6/4WFhf9+fn7/UFBQ/35+fv+bm5v/Jycn/zAwMP8bGxv/HR0d/yMjI/8kJCT/IyMj/19f + X//Gxsb/y8vL/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/Ly8v/y8vL/8rKyv/Kysr/ycnJ/6Oj + o/8rKyv/IyMj/yQkJP8kJCT/JCQk/yQkJP8lJSX/JSUl/yUlJf8lJSX/MjIy/1lZWf+AgID/t7e3/8DA + wP/ExMT/yMjI/8vLy//Pz8//0tLS/9bW1v/Z2dn/29vb/97e3pf///8B////AcLCwvG5ubn/ra2t/5WV + lf9fX1//SkpK/3l5ef90dHT/c3Nz/zIyMv9qamr/TU1N/3x8fP/CwsL/ycnJ/ywsLP8aGhr/Gxsb/yIi + Iv8jIyP/JCQk/zU1Nf+2trb/y8vL/8vLy//MzMz/zMzM/83Nzf/Nzc3/zc3N/8zMzP/MzMz/y8vL/8vL + y//Kysr/ysrK/8rKyv/Kysr/c3Nz/yQkJP8kJCT/JCQk/yQkJP8kJCT/JSUl/yUlJf8kJCT/ISEh/xUV + Ff9zc3P/s7Oz/7+/v//Dw8P/x8fH/8vLy//Ozs7/0tLS/9XV1f/Y2Nj/2tra/93d3f/f39+X////Af// + /wHDw8Pxu7u7/6+vr/+Wlpb/X19f/0dHR/96enr/enp6/4mJif9DQ0P/Pj4+/3Z2dv+0tLT/2dnZ/zk5 + Of8hISH/Hh4e/yIiIv8jIyP/JCQk/yQkJP9paWn/zMzM/83Nzf/MzMz/zMzM/83Nzf/Nzc3/zs7O/83N + zf/Nzc3/zMzM/8zMzP/Ly8v/y8vL/8vLy//Ly8v/zMzM/7Ozs/8rKyv/JCQk/yQkJP8kJCT/JCQk/yUl + Jf8kJCT/ISEh/w0NDf9RUVH/r6+v/76+vv/CwsL/x8fH/8rKyv/Ozs7/0dHR/9TU1P/X19f/2tra/9zc + 3P/f39//4eHhl////wH///8Bw8PD8b29vf+zs7P/mZmZ/3V1df9VVVX/c3Nz/4qKiv+Tk5P/RERE/zAw + MP9qamr/09PT/0NDQ/8hISH/Hh4e/yIiIv8jIyP/JCQk/yQkJP8kJCT/kJCQ/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/87Ozv/Ozs7/zs7O/83Nzf/MzMz/zMzM/8vLy//Ly8v/zMzM/83Nzf/Jycn/PDw8/yQk + JP8kJCT/JCQk/yQkJP8kJCT/IyMj/w4ODv9KSkr/qamp/729vf/BwcH/xsbG/8rKyv/Ozs7/0dHR/9TU + 1P/X19f/2tra/9zc3P/e3t7/4eHh/+Li4pf///8B////AcPDw/G9vb3/tra2/5aWlv9/f3//UFBQ/3R0 + dP+Xl5f/UlJS/29vb/92dnb/ISEh/y8vL/8fHx//Hx8f/yIiIv8jIyP/JCQk/yQkJP8kJCT/JCQk/5iY + mP/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zMzM/8zMzP/MzMz/zMzM/8zM + zP/MzMz/zMzM/0dHR/8kJCT/JCQk/yQkJP8kJCT/KSkp/0RERP9WVlb/q6ur/7y8vP/AwMD/xcXF/8rK + yv/Nzc3/0dHR/9TU1P/X19f/2dnZ/9zc3P/e3t7/4ODg/+Li4v/k5OSX////Af///wHFxcXxvr6+/7Oz + s/+Hh4f/goKC/0xMTP9wcHD/V1dX/2pqav+Tk5P/7u7u/1NTU/8eHh7/GRkZ/yQkJP8lJSX/JCQk/yQk + JP8kJCT/JCQk/yQkJP+Ghob/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/8zM + zP/MzMz/zMzM/8zMzP/MzMz/zMzM/8bGxv87Ozv/JCQk/yQkJP8kJCT/IyMj/xoaGv9ZWVn/pKSk/7y8 + vP/AwMD/xMTE/8nJyf/Nzc3/0NDQ/9TU1P/X19f/2dnZ/9zc3P/e3t7/4ODg/+Li4v/k5OT/5eXll/// + /wH///8BxsbG8cDAwP+oqKj/hYWF/4qKiv9fX1//Pj4+/2hoaP+Ojo7/6enp/3V1df8dHR3/ICAg/yMj + I/8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/VlZW/8vLy//Nzc3/zc3N/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/MzMz/zMzM/8zMzP/Ly8v/y8vL/8vLy/+pqan/KCgo/yQkJP8kJCT/IiIi/xIS + Ev8vLy//oqKi/7u7u//AwMD/xMTE/8nJyf/Nzc3/0NDQ/9TU1P/X19f/2dnZ/9zc3P/e3t7/4ODg/+Li + 4v/k5OT/5eXl/+bm5pf///8B////AcjIyPHDw8P/qKio/4qKiv+cnJz/X19f/zMzM/+CgoL/1tbW/4eH + h/8eHh7/ICAg/yEhIf8jIyP/IyMj/yMjI/8jIyP/IyMj/yQkJP8kJCT/JCQk/ysrK/+np6f/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/8zMzP/MzMz/y8vL/8vLy//Jycn/YWFh/yQk + JP8kJCT/IyMj/xUVFf8mJib/lZWV/7u7u//AwMD/xMTE/8nJyf/MzMz/0NDQ/9PT0//W1tb/2dnZ/9vb + 2//e3t7/4ODg/+Li4v/j4+P/5eXl/+fn5//o6OiX////Af///wHKysrxxcXF/6qqqv+bm5v/cnJy/1ZW + Vv9iYmL/MzMz/0NDQ/8qKir/ISEh/yAgIP8iIiL/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/JCQk/yQk + JP8kJCT/R0dH/729vf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zMzM/8vL + y//Kysr/kZGR/ycnJ/8kJCT/JSUl/zY2Nv8zMzP/lpaW/7u7u//AwMD/xMTE/8jIyP/MzMz/0NDQ/9PT + 0//W1tb/2dnZ/9vb2//d3d3/4ODg/+Li4v/j4+P/5eXl/+bm5v/o6Oj/6enpl////wH///8By8vL8cfH + x/+1tbX/e3t7/1BQUP9/f3//0dHR/4WFhf8mJib/GRkZ/x8fH/8iIiL/IyMj/yMjI/8jIyP/IyMj/yMj + I/8jIyP/IyMj/yMjI/8jIyP/JCQk/yQkJP9LS0v/tbW1/8zMzP/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/8zMzP/IyMj/j4+P/y4uLv8kJCT/IyMj/yIiIv9LS0v/lJSU/729vf/BwcH/xcXF/8jI + yP/MzMz/0NDQ/9PT0//W1tb/2dnZ/9vb2//d3d3/39/f/+Hh4f/j4+P/5eXl/+bm5v/o6Oj/6enp/+rq + 6pf///8B////Ac7OzvHKysr/urq6/1lZWf96enr/xcXF/7y8vP8kJCT/Hx8f/x0dHf8iIiL/IiIi/yIi + Iv8oIiH/PiId/yMiIv8iIiL/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/zMzM/+Dg4P/v7+//8vL + y//Nzc3/zc3N/83Nzf/Nzc3/zMzM/8rKyv+srKz/XV1d/yYmJv8kJCT/IyMj/xsbG/8UFBT/goKC/7u7 + u//CwsL/xcXF/8nJyf/Nzc3/0NDQ/9PT0//W1tb/2dnZ/9vb2//d3d3/39/f/+Hh4f/j4+P/5OTk/+bm + 5v/o6Oj/6enp/+rq6v/r6+uX////Af///wHQ0NDxzc3N/8nJyf+wsLD/t7e3/9LS0v8oKCj/ICAg/x0d + Hf8jIyP/IyMj/yIiIv8jISH/gicW/3UnGf8jIiH/IiIi/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMj + I/8jIyP/JCQk/zAwMP9dXV3/fX19/5OTk/+ZmZn/jo6O/29vb/9HR0f/Jycn/yQkJP8kJCT/IyMj/x0d + Hf8NDQ3/dXV1/7q6uv/CwsL/xsbG/8rKyv/Nzc3/0NDQ/9PT0//W1tb/2dnZ/9vb2//d3d3/39/f/+Hh + 4f/i4uL/5OTk/+bm5v/n5+f/6enp/+rq6v/r6+v/7Ozsl////wH///8B09PT8dDQ0P/MzMz/xcXF/3Z2 + dv88PDz/Hx8f/x8fH/8lJSX/IyMj/yIiIv8iISH/dyYX/44oFv8lIiH/IiIi/yQhIf88Ih7/KCIh/y0i + IP9gJRr/aCYa/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/IyMj/y0tLf8bGxv/cnJy/7i4uP/Dw8P/xsbG/8rKyv/Ozs7/0dHR/9TU1P/W1tb/2dnZ/9vb + 2//d3d3/39/f/+Hh4f/i4uL/5OTk/+bm5v/n5+f/6enp/+rq6v/r6+v/7Ozs/+3t7Zf///8B////AdXV + 1fHS0tL/z8/P/8jIyP9kZGT/NDQ0/yMjI/8kJCT/IyMj/yIiIv8iISH/aCQY/5cpFf+RKBX/fSYW/3kl + Fv+WKBT/jykW/3slFv9uJhn/UyUd/1omHf9GJB3/WSQa/ygiIf8jIyL/IyMj/yMjI/8jIyP/IyMj/yMj + I/8jIyP/JCQk/yQkJP8kJCT/IyMj/yIiIv9FRUX/gICA/729vf/ExMT/x8fH/8vLy//Ozs7/0dHR/9TU + 1P/X19f/2dnZ/9vb2//d3d3/39/f/+Hh4f/j4+P/5OTk/+bm5v/n5+f/6Ojo/+rq6v/r6+v/7Ozs/+3t + 7f/u7u6X////Af///wHY2Njx1dXV/9LS0v/Ly8v/UlJS/ycnJ/8iIiL/IyMj/yIiIv8iIiL/RiMd/7Yr + Ev8zIR7/JiAg/2QlGv+SKBX/LSIg/ykhIP9GIx3/KCIh/2ImG/9EJB7/aSYZ/2IkGf94Jhj/NiMf/yci + Iv8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8kJCT/IyMj/yAgIP8MDAz/Xl5e/7e3t//FxcX/ycnJ/8zM + zP/Pz8//0tLS/9XV1f/X19f/2tra/9zc3P/e3t7/39/f/+Hh4f/j4+P/5OTk/+bm5v/n5+f/6Ojo/+np + 6f/r6+v/7Ozs/+3t7f/u7u7/7+/vl////wH///8B2tra8dfX1//U1NT/ysrK/z4+Pv8iIiL/IyMj/yMj + I/8iIiL/IiIi/yUhIP9dJRv/kicU/1QiGf9QIhn/oyoU/0QiHP+TKBT/fScX/4YmFf9eJRr/LiIg/2ol + Gf+DJxf/bCYZ/2UmG/9yJhj/LCIh/yMiIv8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8NDQ3/TExM/7i4 + uP/IyMj/y8vL/83Nzf/Q0ND/09PT/9bW1v/Z2dn/29vb/93d3f/e3t7/4ODg/+Hh4f/j4+P/5OTk/+bm + 5v/n5+f/6Ojo/+rq6v/r6+v/7Ozs/+3t7f/u7u7/7+/v/+/v75f///8B////Ad3d3fHa2tr/19fX/83N + zf8/Pz//IyMj/yQkJP8jIyP/IyMj/yIiIv8hISH/ISEh/y4hH/9tJhn/gScX/0cjHf+aKRT/OiIe/yEh + If9LIxz/fScX/yUhIf8tIiD/KiIg/1clHP9HIx3/bSca/2smGv88Ix7/LCMh/yMjI/8jIyP/IyMj/ycn + J/8WFhb/RkZG/7S0tP/Kysr/zc3N/8/Pz//S0tL/1NTU/9fX1//a2tr/3Nzc/97e3v/f39//4eHh/+Li + 4v/j4+P/5eXl/+bm5v/n5+f/6Ojo/+rq6v/r6+v/7Ozs/+3t7f/u7u7/7+/v/+/v7//w8PCX////Af// + /wHf39/x3d3d/9ra2v/Y2Nj/vr6+/1xcXP8lJSX/IyMj/yMjI/8iIiL/IiIi/yIiIv8hISH/ISEh/yEh + If8nISD/likV/zAhHv8nIB//iSYU/1skG/92JRf/aCUZ/yIiIf8iIiH/RyMd/3QmGP9dJRv/ayca/zUk + IP8jIyP/IiIi/yMjI/9GRkb/a2tr/7m5uf/Nzc3/z8/P/9HR0f/U1NT/1tbW/9jY2P/b29v/3d3d/9/f + 3//g4OD/4uLi/+Pj4//k5OT/5eXl/+fn5//o6Oj/6enp/+rq6v/r6+v/7Ozs/+3t7f/u7u7/7+/v/+/v + 7//w8PD/8fHxl////wH///8B4eHh8d/f3//d3d3/29vb/9nZ2f/W1tb/paWl/0dHR/8jIyP/IyMj/yIi + Iv8iIiL/IiIi/yIiIv8hISH/ISEh/zkiHv99Jhb/hyYV/14kGv9tJBf/gicX/yQhIP8+Ih3/fCYX/0Ij + Hv9YJRz/hSgX/ykjIv8jIyP/IyMj/yMjI/8TExP/NjY2/62trf/Q0ND/0tLS/9TU1P/W1tb/2NjY/9ra + 2v/c3Nz/3t7e/+Dg4P/i4uL/4+Pj/+Tk5P/l5eX/5+fn/+jo6P/o6Oj/6enp/+rq6v/r6+v/7Ozs/+3t + 7f/u7u7/7+/v//Dw8P/w8PD/8fHx//Ly8pf///8B////AePj4/Hh4eH/39/f/93d3f/c3Nz/2tra/9jY + 2P/Pz8//ioqK/zU1Nf8iIiL/IyMj/yIiIv8iIiL/IiIi/yEhIf8hISH/ISEg/yIhIP9QIxv/qioT/y0h + H/82IR3/nCkU/zojH/8mIiH/YiUa/ysjIf8jIyL/IyMj/yQkJP8YGBj/KCgo/6urq//S0tL/1dXV/9fX + 1//Y2Nj/2tra/9zc3P/e3t7/4ODg/+Li4v/j4+P/5OTk/+Xl5f/n5+f/6Ojo/+jo6P/p6en/6urq/+vr + 6//s7Oz/7e3t/+7u7v/u7u7/7+/v//Dw8P/w8PD/8fHx//Ly8v/y8vKX////Af///wHl5eXx5OTk/+Li + 4v/g4OD/39/f/93d3f/c3Nz/2tra/9jY2P/BwcH/aWlp/ygoKP8iIiL/IiIi/yIiIv8iIiL/ISEh/yEh + If8hISH/KSEg/1kkG/+LJxT/pykT/00kHf8kIiH/fCcX/3QoGv8kIyL/IyMj/yQkJP8cHBz/ICAg/6Cg + oP/U1NT/19fX/9nZ2f/b29v/3Nzc/97e3v/g4OD/4eHh/+Pj4//k5OT/5ubm/+fn5//o6Oj/6Ojo/+np + 6f/q6ur/6+vr/+zs7P/s7Oz/7e3t/+7u7v/v7+//7+/v//Dw8P/x8fH/8fHx//Ly8v/z8/P/8/Pzl/// + /wH///8B5+fn8ebm5v/l5eX/4+Pj/+Li4v/g4OD/39/f/97e3v/c3Nz/29vb/9jY2P+tra3/lpaW/5eX + l/9aWlr/JCQk/yIiIv8iIiL/ISEh/yEhIf8iISH/MiIg/10mG/91Jhj/fSYX/30oGf8mIyL/IyMj/yMj + I/9BQUH/WVlZ/6ampv/X19f/2tra/9zc3P/d3d3/39/f/+Dg4P/i4uL/4+Pj/+Tk5P/m5ub/5+fn/+jo + 6P/o6Oj/6enp/+rq6v/r6+v/7Ozs/+zs7P/t7e3/7u7u/+7u7v/v7+//8PDw//Dw8P/x8fH/8fHx//Ly + 8v/z8/P/8/Pz//T09Jf///8B////Aenp6fHo6Oj/5+fn/+bm5v/k5OT/4+Pj/+Li4v/h4eH/39/f/97e + 3v/d3d3/3Nzc/9vb2//b29v/1NTU/1VVVf8iIiL/IiIi/yIiIv8iIiL/IiIi/yIiIv8kIiL/UCUd/1cm + Hf8mIyL/IyMj/yIiIv8aGhr/ICAg/5WVlf/Z2dn/3d3d/97e3v/f39//4eHh/+Li4v/j4+P/5eXl/+bm + 5v/n5+f/6Ojo/+np6f/q6ur/6urq/+vr6//s7Oz/7Ozs/+3t7f/u7u7/7u7u/+/v7//v7+//8PDw//Hx + 8f/x8fH/8vLy//Ly8v/z8/P/8/Pz//T09P/09PSX////Af///wHr6+vx6urq/+np6f/o6Oj/5+fn/+bm + 5v/l5eX/5OTk/+Pj4//i4uL/4eHh/9/f3//f39//3t7e/93d3f+Xl5f/KSkp/yMjI/8iIiL/IiIi/yIi + Iv8iIiL/IyMj/yMjI/8jIyP/IyMj/yIiIv8eHh7/DQ0N/4ODg//Z2dn/4ODg/+Hh4f/i4uL/4+Pj/+Tk + 5P/l5eX/5ubm/+fn5//o6Oj/6enp/+rq6v/r6+v/6+vr/+zs7P/t7e3/7e3t/+7u7v/u7u7/7+/v/+/v + 7//w8PD/8PDw//Hx8f/x8fH/8vLy//Pz8//z8/P/8/Pz//T09P/09PT/9fX1l////wH///8B7e3t8ezs + 7P/r6+v/6urq/+np6f/o6Oj/5+fn/+bm5v/l5eX/5OTk/+Pj4//j4+P/4uLi/+Hh4f/g4OD/39/f/7m5 + uf9YWFj/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yIiIv8gICD/DQ0N/3p6ev/Z2dn/4+Pj/+Pj + 4//k5OT/5eXl/+bm5v/n5+f/6Ojo/+np6f/p6en/6urq/+vr6//s7Oz/7Ozs/+3t7f/t7e3/7u7u/+/v + 7//v7+//8PDw//Dw8P/w8PD/8fHx//Hx8f/y8vL/8vLy//Pz8//z8/P/9PT0//T09P/19fX/9fX1//b2 + 9pf///8B////Ae7u7vHt7e3/7Ozs/+zs7P/r6+v/6urq/+rq6v/p6en/6Ojo/+fn5//m5ub/5eXl/+Tk + 5P/j4+P/4+Pj/+Li4v/i4uL/39/f/6Kiov8+Pj7/IyMj/yMjI/8jIyP/IyMj/yIiIv9ZWVn/tLS0/6en + p//c3Nz/5OTk/+Xl5f/m5ub/5+fn/+fn5//o6Oj/6enp/+rq6v/r6+v/6+vr/+zs7P/s7Oz/7e3t/+7u + 7v/u7u7/7+/v/+/v7//w8PD/8PDw//Hx8f/x8fH/8fHx//Ly8v/y8vL/8/Pz//Pz8//z8/P/9PT0//T0 + 9P/09PT/9fX1//X19f/29vaX////Af///wHv7+/x7u7u/+7u7v/t7e3/7Ozs/+zs7P/r6+v/6+vr/+rq + 6v/p6en/6Ojo/+fn5//n5+f/5ubm/+Xl5f/l5eX/5OTk/+Tk5P/l5eX/2NjY/4ODg/8xMTH/IiIi/yIi + Iv9NTU3/19fX/+bm5v/m5ub/5ubm/+fn5//o6Oj/6Ojo/+np6f/q6ur/6urq/+vr6//s7Oz/7Ozs/+3t + 7f/t7e3/7u7u/+7u7v/v7+//7+/v//Dw8P/w8PD/8fHx//Hx8f/y8vL/8vLy//Ly8v/y8vL/8/Pz//Pz + 8//09PT/9PT0//T09P/19fX/9fX1//X19f/29vb/9vb2l////wH///8B8PDw8fDw8P/v7+//7u7u/+7u + 7v/t7e3/7e3t/+zs7P/s7Oz/6+vr/+rq6v/q6ur/6enp/+jo6P/o6Oj/5+fn/+fn5//n5+f/5+fn/+fn + 5//m5ub/xMTE/2VlZf9LS0v/0tLS/+jo6P/p6en/6enp/+np6f/p6en/6urq/+rq6v/r6+v/7Ozs/+zs + 7P/t7e3/7e3t/+7u7v/u7u7/7+/v/+/v7//v7+//8PDw//Dw8P/x8fH/8fHx//Ly8v/y8vL/8vLy//Pz + 8//z8/P/8/Pz//T09P/09PT/9PT0//X19f/19fX/9fX1//b29v/29vb/9vb2//f395f///8B////AfHx + 8fHx8fH/8PDw//Dw8P/v7+//7+/v/+7u7v/u7u7/7e3t/+3t7f/s7Oz/7Ozs/+vr6//q6ur/6urq/+rq + 6v/p6en/6enp/+np6f/p6en/6enp/+rq6v/n5+f/4eHh/+rq6v/q6ur/6urq/+vr6//r6+v/6+vr/+zs + 7P/s7Oz/7e3t/+3t7f/u7u7/7u7u/+/v7//v7+//7+/v//Dw8P/w8PD/8PDw//Hx8f/x8fH/8vLy//Ly + 8v/y8vL/8/Pz//Pz8//z8/P/9PT0//T09P/09PT/9fX1//X19f/19fX/9vb2//b29v/29vb/9vb2//f3 + 9//39/eX////Af///wHy8vLx8vLy//Hx8f/x8fH/8PDw//Dw8P/w8PD/7+/v/+/v7//u7u7/7u7u/+3t + 7f/t7e3/7Ozs/+zs7P/s7Oz/7Ozs/+zs7P/r6+v/7Ozs/+zs7P/s7Oz/7Ozs/+zs7P/s7Oz/7Ozs/+zs + 7P/s7Oz/7e3t/+3t7f/t7e3/7u7u/+7u7v/v7+//7+/v/+/v7//w8PD/8PDw//Hx8f/x8fH/8fHx//Hx + 8f/y8vL/8vLy//Pz8//z8/P/8/Pz//T09P/09PT/9PT0//T09P/19fX/9fX1//X19f/29vb/9vb2//b2 + 9v/29vb/9/f3//f39//39/f/9/f3l////wH///8B8/Pz8fPz8//y8vL/8vLy//Ly8v/x8fH/8fHx//Dw + 8P/w8PD/8PDw/+/v7//v7+//7+/v/+7u7v/u7u7/7u7u/+7u7v/t7e3/7u7u/+7u7v/u7u7/7u7u/+7u + 7v/u7u7/7u7u/+7u7v/u7u7/7u7u/+7u7v/u7u7/7+/v/+/v7//w8PD/8PDw//Dw8P/x8fH/8fHx//Hx + 8f/y8vL/8vLy//Ly8v/y8vL/8/Pz//Pz8//z8/P/9PT0//T09P/09PT/9fX1//X19f/19fX/9fX1//b2 + 9v/29vb/9vb2//b29v/39/f/9/f3//f39//39/f/+Pj4//j4+Jf///8BAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAoAAAAgAAAAAABAAABACAAAAAAAAAIAQAAAAAAAAAAAAAAAAAAAAAA////Af// + /wHw8PDj8PDw/+/v7//v7+//7+/v/+7u7v/u7u7/7u7u/+3t7f/t7e3/7e3t/+zs7P/s7Oz/6+vr/+vr + 6//q6ur/6urq/+np6f/p6en/6Ojo/+jo6P/n5+f/5ubm/+bm5v/l5eX/5OTk/+Tk5P/j4+P/4uLi/+Hh + 4f/h4eH/4ODg/9/f3//e3t7/3t7e/93d3f/c3Nz/3Nzc/9vb2//a2tr/2dnZ/9nZ2f/Y2Nj/19fX/9bW + 1v/V1dX/09PT/9LS0v/Q0ND/zs7O/83Nzf/Ly8v/ysrK/8jIyP/Hx8f/xcXF/8TExP/CwsL/wcHB/8DA + wP++vr7/vb29/7u7u/+6urr/uLi4/7e3t/+1tbX/tLS0/7Ozs/+ysrL/sbGx/7Gxsf+wsLD/sLCw/7Cw + sP+wsLD/sLCw/7Gxsf+xsbH/sbGx/7Kysv+ysrL/srKy/7S0tP+0tLT/tbW1/7a2tv+3t7f/uLi4/7m5 + uf+7u7v/u7u7/729vf++vr7/wMDA/8HBwf/BwcH/w8PD/8TExP/FxcX/xsbG/8jIyP/Jycn/ysrK/8vL + y//MzMz/zs7O/8/Pz//Q0ND/0dHR/9PT0//T09P/1dXV/9bW1v/X19f/2NjY/9nZ2f/b29v/3Nzc/97e + 3v/e3t7/39/f/+Hh4f/h4eEx////Af///wH///8B////AfDw8OPv7+//7+/v/+/v7//v7+//7u7u/+7u + 7v/t7e3/7e3t/+zs7P/s7Oz/7Ozs/+vr6//r6+v/6urq/+rq6v/p6en/6enp/+jo6P/o6Oj/5+fn/+fn + 5//m5ub/5eXl/+Tk5P/k5OT/4+Pj/+Li4v/h4eH/4eHh/+Dg4P/f39//3t7e/93d3f/c3Nz/3Nzc/9vb + 2//a2tr/2tra/9nZ2f/Y2Nj/19fX/9bW1v/V1dX/1NTU/9PT0//R0dH/z8/P/83Nzf/MzMz/ysrK/8jI + yP/Hx8f/xcXF/8PDw//BwcH/wMDA/7+/v/+9vb3/vLy8/7q6uv+4uLj/t7e3/7W1tf+zs7P/srKy/7Cw + sP+vr6//rq6u/62trf+tra3/rKys/6urq/+rq6v/q6ur/6urq/+rq6v/rKys/62trf+tra3/ra2t/66u + rv+urq7/sLCw/7CwsP+ysrL/srKy/7Ozs/+1tbX/tra2/7e3t/+5ubn/urq6/7y8vP+9vb3/vr6+/7+/ + v//AwMD/wsLC/8PDw//ExMT/xcXF/8bGxv/IyMj/ycnJ/8vLy//MzMz/zc3N/87Ozv/Pz8//0dHR/9LS + 0v/T09P/1dXV/9bW1v/X19f/2NjY/9nZ2f/b29v/3Nzc/97e3v/f39//39/f/+Dg4DH///8B////Af// + /wH///8B7+/v4+/v7//u7u7/7u7u/+7u7v/t7e3/7e3t/+3t7f/s7Oz/7Ozs/+vr6//r6+v/6urq/+rq + 6v/p6en/6enp/+jo6P/o6Oj/5+fn/+fn5//m5ub/5eXl/+Xl5f/k5OT/4+Pj/+Pj4//i4uL/4eHh/+Dg + 4P/f39//3t7e/93d3f/d3d3/3Nzc/9vb2//a2tr/2dnZ/9nZ2f/Y2Nj/19fX/9bW1v/V1dX/1NTU/9PT + 0//S0tL/0NDQ/87Ozv/MzMz/ysrK/8nJyf/Gxsb/xcXF/8LCwv/BwcH/v7+//729vf+8vLz/urq6/7i4 + uP+2trb/tLS0/7Kysv+wsLD/rq6u/6ysrP+rq6v/qamp/6ioqP+np6f/p6en/6ampv+lpaX/paWl/6Wl + pf+lpaX/paWl/6ampv+mpqb/p6en/6ioqP+oqKj/qamp/6qqqv+rq6v/rKys/62trf+vr6//sLCw/7Gx + sf+ysrL/tLS0/7a2tv+2trb/uLi4/7m5uf+7u7v/vLy8/729vf+/v7//wMDA/8LCwv/CwsL/w8PD/8XF + xf/Gxsb/yMjI/8nJyf/Ly8v/zMzM/83Nzf/Pz8//0NDQ/9HR0f/S0tL/1NTU/9XV1f/W1tb/2NjY/9nZ + 2f/b29v/3Nzc/97e3v/e3t7/39/fMf///wH///8B////Af///wHv7+/j7+/v/+7u7v/u7u7/7u7u/+3t + 7f/t7e3/7Ozs/+zs7P/r6+v/6+vr/+rq6v/q6ur/6enp/+np6f/o6Oj/6Ojo/+fn5//m5ub/5ubm/+Xl + 5f/l5eX/5OTk/+Pj4//i4uL/4eHh/+Hh4f/g4OD/39/f/97e3v/d3d3/3Nzc/9vb2//a2tr/2tra/9nZ + 2f/Y2Nj/19fX/9bW1v/V1dX/1NTU/9PT0//S0tL/0NDQ/8/Pz//Nzc3/y8vL/8rKyv/Hx8f/xsbG/8PD + w//BwcH/v7+//729vf+7u7v/ubm5/7e3t/+1tbX/s7Oz/7Gxsf+urq7/rKys/6mpqf+np6f/paWl/6Oj + o/+ioqL/oaGh/6CgoP+goKD/n5+f/5+fn/+fn5//n5+f/5+fn/+goKD/oaGh/6Ghof+ioqL/o6Oj/6Sk + pP+lpaX/pqam/6enp/+oqKj/qamp/6qqqv+srKz/ra2t/6+vr/+xsbH/srKy/7Ozs/+1tbX/tra2/7i4 + uP+5ubn/u7u7/7y8vP+9vb3/v7+//8DAwP/BwcH/w8PD/8TExP/FxcX/x8fH/8jIyP/Kysr/y8vL/8zM + zP/Ozs7/z8/P/9HR0f/S0tL/1NTU/9XV1f/W1tb/2NjY/9nZ2f/b29v/3Nzc/97e3v/e3t4x////Af// + /wH///8B////Ae7u7uPu7u7/7u7u/+3t7f/t7e3/7Ozs/+zs7P/s7Oz/6+vr/+vr6//q6ur/6urq/+np + 6f/p6en/6Ojo/+jo6P/n5+f/5ubm/+bm5v/l5eX/5eXl/+Tk5P/j4+P/4uLi/+Hh4f/h4eH/4ODg/9/f + 3//e3t7/3d3d/9zc3P/b29v/2tra/9nZ2f/Y2Nj/19fX/9bW1v/V1dX/1NTU/9PT0//S0tL/0NDQ/8/P + z//Ozs7/zMzM/8rKyv/IyMj/x8fH/8TExP/CwsL/v7+//729vf+7u7v/uLi4/7e3t/+0tLT/srKy/7Cw + sP+tra3/qqqq/6enp/+lpaX/oaGh/6CgoP+dnZ3/m5ub/5qamv+ZmZn/mJiY/5iYmP+YmJj/mJiY/5iY + mP+YmJj/mZmZ/5qamv+bm5v/nJyc/52dnf+dnZ3/n5+f/6CgoP+hoaH/oqKi/6Ojo/+lpaX/pqam/6io + qP+qqqr/q6ur/62trf+urq7/sLCw/7Kysv+zs7P/tbW1/7a2tv+4uLj/ubm5/7u7u/+8vLz/vb29/7+/ + v//AwMD/wsLC/8PDw//ExMT/xsbG/8fHx//Jycn/y8vL/8zMzP/Ozs7/z8/P/9HR0f/S0tL/1NTU/9XV + 1f/X19f/2dnZ/9nZ2f/b29v/3Nzc/93d3TH///8B////Af///wH///8B7u7u4+3t7f/t7e3/7e3t/+zs + 7P/s7Oz/7Ozs/+vr6//r6+v/6urq/+np6f/p6en/6Ojo/+jo6P/n5+f/5+fn/+bm5v/l5eX/5eXl/+Tk + 5P/j4+P/4+Pj/+Li4v/h4eH/4ODg/9/f3//e3t7/3d3d/9zc3P/c3Nz/2tra/9nZ2f/Z2dn/19fX/9bW + 1v/V1dX/1NTU/9PT0//S0tL/0dHR/8/Pz//Nzc3/zMzM/8rKyv/IyMj/x8fH/8XFxf/Dw8P/wcHB/76+ + vv+7u7v/ubm5/7a2tv+0tLT/sbGx/66urv+srKz/qamp/6ampv+jo6P/n5+f/5mZmf+BgYH/ioqK/5SU + lP+Tk5P/kZGR/5CQkP+QkJD/kJCQ/5CQkP+QkJD/kZGR/5GRkf+SkpL/k5OT/5WVlf+Wlpb/lpaW/5eX + l/+ZmZn/mpqa/5ycnP+dnZ3/np6e/6CgoP+ioqL/o6Oj/6ampv+np6f/qamp/6urq/+srKz/rq6u/6+v + r/+xsbH/s7Oz/7S0tP+2trb/t7e3/7m5uf+6urr/vLy8/729vf+/v7//wMDA/8HBwf/ExMT/xcXF/8fH + x//Jycn/ysrK/8zMzP/Ozs7/z8/P/9HR0f/S0tL/1NTU/9bW1v/X19f/2dnZ/9ra2v/b29v/3NzcMf// + /wH///8B////Af///wHt7e3j7e3t/+zs7P/s7Oz/7Ozs/+vr6//r6+v/6urq/+rq6v/q6ur/6enp/+np + 6f/o6Oj/5+fn/+bm5v/m5ub/5eXl/+Xl5f/k5OT/4+Pj/+Li4v/i4uL/4ODg/+Dg4P/f39//3t7e/93d + 3f/c3Nz/29vb/9ra2v/Z2dn/2NjY/9fX1//W1tb/1NTU/9PT0//S0tL/0dHR/9DQ0P/Pz8//zc3N/8vL + y//Jycn/yMjI/8bGxv/Dw8P/wsLC/8DAwP++vr7/u7u7/7m5uf+2trb/s7Oz/6+vr/+srKz/qamp/6en + p/+jo6P/n5+f/5ycnP+VlZX/fX19/2RkZP9paWn/enp6/4qKiv+Li4v/iYmJ/4mJif+JiYn/iYmJ/4qK + iv+Kior/i4uL/4yMjP+Ojo7/j4+P/5CQkP+RkZH/kpKS/5SUlP+VlZX/l5eX/5mZmf+ampr/m5ub/56e + nv+fn5//oqKi/6SkpP+mpqb/p6en/6ioqP+rq6v/rKys/66urv+wsLD/sbGx/7Ozs/+0tLT/tra2/7i4 + uP+5ubn/u7u7/7y8vP++vr7/wMDA/8HBwf/Dw8P/xcXF/8fHx//Jycn/ysrK/8zMzP/Ozs7/z8/P/9HR + 0f/S0tL/1NTU/9bW1v/X19f/2dnZ/9ra2v/b29sx////Af///wH///8B////Ae3t7ePs7Oz/7Ozs/+vr + 6//r6+v/6urq/+rq6v/q6ur/6enp/+np6f/o6Oj/5+fn/+fn5//m5ub/5ubm/+Xl5f/k5OT/4+Pj/+Pj + 4//i4uL/4eHh/+Dg4P/f39//3t7e/93d3f/d3d3/29vb/9vb2//Z2dn/2NjY/9jY2P/W1tb/1dXV/9PT + 0//T09P/0tLS/9DQ0P/Pz8//zc3N/8zMzP/Kysr/yMjI/8bGxv/ExMT/wsLC/8DAwP++vr7/vLy8/7m5 + uf+3t7f/tLS0/7Kysv+urq7/qqqq/6enp/+jo6P/n5+f/5ubm/+Xl5f/k5OT/4CAgP9jY2P/YmJi/2Fh + Yf9iYmL/enp6/4ODg/+CgoL/gYGB/4GBgf+CgoL/goKC/4ODg/+EhIT/hoaG/4eHh/+IiIj/iYmJ/4uL + i/+MjIz/jo6O/4+Pj/+RkZH/k5OT/5WVlf+Xl5f/mZmZ/5qamv+dnZ3/n5+f/6Ghof+ioqL/pKSk/6am + pv+oqKj/qqqq/6urq/+tra3/r6+v/7Gxsf+ysrL/tLS0/7a2tv+4uLj/ubm5/7u7u/+9vb3/v7+//8HB + wf/CwsL/xMTE/8bGxv/IyMj/ysrK/8zMzP/Ozs7/z8/P/9HR0f/S0tL/1NTU/9bW1v/X19f/2dnZ/9nZ + 2TH///8B////Af///wH///8B7Ozs4+zs7P/r6+v/6+vr/+vr6//q6ur/6urq/+np6f/p6en/6Ojo/+fn + 5//n5+f/5ubm/+bm5v/l5eX/5OTk/+Pj4//i4uL/4uLi/+Hh4f/g4OD/39/f/97e3v/d3d3/3Nzc/9vb + 2//a2tr/2dnZ/9jY2P/X19f/1tbW/9XV1f/T09P/0tLS/9HR0f/Q0ND/zs7O/8zMzP/Kysr/ycnJ/8fH + x//FxcX/xMTE/8HBwf+/v7//vb29/7u7u/+5ubn/tra2/7S0tP+wsLD/ra2t/6qqqv+lpaX/oqKi/52d + nf+ZmZn/lJSU/5CQkP+MjIz/dnZ2/2FhYf9jY2P/YmJi/2FhYf92dnb/fX19/3x8fP98fHz/e3t7/3x8 + fP98fHz/fX19/35+fv+AgID/gYGB/4ODg/+EhIT/hYWF/4eHh/+JiYn/i4uL/4yMjP+Ojo7/kJCQ/5KS + kv+UlJT/lpaW/5mZmf+bm5v/nZ2d/56env+goKD/oqKi/6SkpP+mpqb/qKio/6qqqv+srKz/ra2t/7Cw + sP+xsbH/s7Oz/7W1tf+2trb/ubm5/7q6uv+9vb3/vr6+/8DAwP/CwsL/xMTE/8bGxv/IyMj/ysrK/8vL + y//Nzc3/z8/P/9HR0f/T09P/1dXV/9bW1v/X19f/2NjYMf///wH///8B////Af///wHr6+vj6+vr/+vr + 6//q6ur/6urq/+np6f/p6en/6Ojo/+jo6P/n5+f/5+fn/+bm5v/l5eX/5eXl/+Tk5P/j4+P/4uLi/+Hh + 4f/h4eH/39/f/9/f3//e3t7/3Nzc/9zc3P/b29v/2tra/9jY2P/X19f/19fX/9XV1f/V1dX/09PT/9LS + 0v/R0dH/z8/P/87Ozv/MzMz/ysrK/8jIyP/Gxsb/xMTE/8LCwv/AwMD/vr6+/7y8vP+5ubn/t7e3/7W1 + tf+ysrL/r6+v/6ysrP+pqan/pKSk/5+fn/+bm5v/lpaW/5GRkf+MjIz/iIiI/4SEhP9ycnL/YWFh/2Rk + ZP9iYmL/YWFh/3Fxcf92dnb/dnZ2/3V1df91dXX/dXV1/3V1df92dnb/eHh4/3p6ev97e3v/fX19/39/ + f/+AgID/goKC/4ODg/+Ghob/h4eH/4mJif+Li4v/jY2N/5CQkP+SkpL/lJSU/5aWlv+YmJj/mpqa/5yc + nP+enp7/oKCg/6Kiov+kpKT/pqam/6ioqP+qqqr/rKys/66urv+wsLD/srKy/7Ozs/+2trb/uLi4/7q6 + uv+8vLz/vr6+/8DAwP/CwsL/xMTE/8bGxv/IyMj/ysrK/8vLy//Nzc3/z8/P/9HR0f/T09P/1dXV/9bW + 1v/X19cx////Af///wH///8B////Aevr6+Pr6+v/6urq/+np6f/p6en/6Ojo/+jo6P/o6Oj/5+fn/+bm + 5v/m5ub/5eXl/+Tk5P/k5OT/4+Pj/+Li4v/h4eH/4ODg/9/f3//e3t7/3t7e/9zc3P/b29v/2tra/9nZ + 2f/Y2Nj/19fX/9bW1v/V1dX/1NTU/9PT0//R0dH/0NDQ/8/Pz//Nzc3/zMzM/8rKyv/IyMj/xsbG/8TE + xP/CwsL/v7+//729vf+7u7v/uLi4/7a2tv+zs7P/sLCw/62trf+rq6v/p6en/6Ojo/+enp7/mZmZ/5SU + lP+Ojo7/iYmJ/4SEhP9/f3//fHx8/21tbf9iYmL/ZWVl/2NjY/9iYmL/bW1t/3BwcP9wcHD/b29v/29v + b/9vb2//b29v/3Fxcf9zc3P/dHR0/3Z2dv94eHj/enp6/3t7e/99fX3/fn5+/4CAgP+CgoL/hISE/4aG + hv+JiYn/i4uL/42Njf+Pj4//kZGR/5SUlP+Wlpb/mJiY/5qamv+cnJz/np6e/6CgoP+jo6P/paWl/6am + pv+pqan/qqqq/62trf+vr6//sbGx/7Ozs/+1tbX/t7e3/7m5uf+8vLz/vr6+/7+/v//CwsL/xMTE/8bG + xv/IyMj/ysrK/8zMzP/Ozs7/z8/P/9HR0f/T09P/1dXV/9bW1jH///8B////Af///wH///8B6urq4+rq + 6v/p6en/6enp/+jo6P/o6Oj/5+fn/+fn5//m5ub/5ubm/+Xl5f/l5eX/5OTk/+Pj4//i4uL/4eHh/+Hh + 4f/f39//3t7e/93d3f/c3Nz/29vb/9ra2v/Z2dn/2NjY/9fX1//W1tb/1dXV/9TU1P/S0tL/0dHR/9DQ + 0P/Ozs7/zc3N/8vLy//Jycn/x8fH/8XFxf/Dw8P/wcHB/7+/v/+9vb3/urq6/7e3t/+1tbX/s7Oz/7Cw + sP+tra3/qamp/6ampv+ioqL/nZ2d/5iYmP+Tk5P/jY2N/4eHh/+CgoL/fX19/3h4eP91dXX/a2tr/2Rk + ZP9mZmb/ZWVl/2NjY/9paWn/ampq/2lpaf9paWn/aWlp/2pqav9ra2v/bW1t/25ubv9wcHD/cnJy/3Nz + c/91dXX/d3d3/3l5ef96enr/fHx8/319ff9/f3//gYGB/4SEhP+Hh4f/iYmJ/4uLi/+NjY3/kJCQ/5KS + kv+UlJT/lpaW/5iYmP+bm5v/nZ2d/5+fn/+hoaH/o6Oj/6ampv+oqKj/qqqq/6ysrP+urq7/sLCw/7Ky + sv+1tbX/t7e3/7m5uf+7u7v/vb29/8DAwP/CwsL/xMTE/8bGxv/IyMj/ysrK/8zMzP/Ozs7/0NDQ/9LS + 0v/U1NT/1dXVMf///wH///8B////Af///wHq6urj6enp/+np6f/o6Oj/6Ojo/+fn5//n5+f/5ubm/+Xl + 5f/l5eX/5OTk/+Tk5P/j4+P/4uLi/+Hh4f/g4OD/39/f/97e3v/d3d3/3Nzc/9vb2//a2tr/2dnZ/9fX + 1//X19f/1tbW/9TU1P/T09P/0tLS/9HR0f/Q0ND/zs7O/8zMzP/Kysr/ycnJ/8fHx//FxcX/w8PD/8HB + wf++vr7/vLy8/7m5uf+2trb/s7Oz/7Gxsf+urq7/rKys/6mpqf+lpaX/oaGh/5ubm/+Xl5f/kZGR/4uL + i/+Ghob/gYGB/3x8fP92dnb/cnJy/29vb/9oaGj/ZWVl/2lpaf9qamr/ampq/2hoaP9kZGT/Y2Nj/2Nj + Y/9kZGT/ZWVl/2ZmZv9oaGj/aWlp/2tra/9tbW3/bm5u/3BwcP9xcXH/c3Nz/3V1df92dnb/eHh4/3p6 + ev98fHz/fn5+/4GBgf+EhIT/hoaG/4mJif+Li4v/jY2N/4+Pj/+RkZH/lJSU/5aWlv+ZmZn/m5ub/56e + nv+fn5//oqKi/6SkpP+mpqb/qKio/6urq/+tra3/r6+v/7Kysv+0tLT/tra2/7m5uf+7u7v/vb29/7+/ + v//CwsL/xMTE/8bGxv/IyMj/ysrK/83Nzf/Pz8//0dHR/9PT0//T09Mx////Af///wH///8B////Aenp + 6ePp6en/6Ojo/+jo6P/n5+f/5+fn/+bm5v/l5eX/5eXl/+Tk5P/k5OT/4+Pj/+Li4v/h4eH/4ODg/9/f + 3//f39//3d3d/9zc3P/b29v/2tra/9nZ2f/Y2Nj/19fX/9bW1v/U1NT/09PT/9LS0v/R0dH/z8/P/87O + zv/MzMz/ysrK/8nJyf/Hx8f/xcXF/8PDw//BwcH/vr6+/7y8vP+5ubn/tra2/7Ozs/+wsLD/rq6u/6ur + q/+oqKj/pKSk/6CgoP+cnJz/lZWV/5CQkP+Li4v/hoaG/39/f/96enr/dnZ2/3Fxcf9ubm7/a2tr/2dn + Z/9nZ2f/a2tr/25ubv9ycnL/cHBw/2dnZ/9fX1//X19f/2BgYP9hYWH/YmJi/2RkZP9lZWX/Z2dn/2ho + aP9qamr/a2tr/21tbf9vb2//cHBw/3Jycv90dHT/dnZ2/3l5ef97e3v/fX19/4CAgP+CgoL/hYWF/4eH + h/+JiYn/i4uL/46Ojv+QkJD/k5OT/5WVlf+YmJj/mpqa/5ycnP+fn5//oaGh/6Ojo/+lpaX/qKio/6qq + qv+tra3/r6+v/7Gxsf+0tLT/tra2/7m5uf+7u7v/vb29/8DAwP/CwsL/xMTE/8fHx//Jycn/y8vL/83N + zf/Pz8//0dHR/9LS0jH///8B////Af///wH///8B6enp4+jo6P/o6Oj/5+fn/+fn5//m5ub/5eXl/+Xl + 5f/k5OT/4+Pj/+Pj4//i4uL/4eHh/+Dg4P/g4OD/3t7e/97e3v/c3Nz/29vb/9ra2v/Z2dn/2NjY/9fX + 1//W1tb/1NTU/9PT0//R0dH/0NDQ/8/Pz//Nzc3/zMzM/8rKyv/Jycn/x8fH/8XFxf/Dw8P/wMDA/76+ + vv+7u7v/uLi4/7W1tf+zs7P/sLCw/62trf+qqqr/p6en/6Ojo/+fn5//mpqa/5WVlf+Pj4//ioqK/4WF + hf97e3v/Y2Nj/11dXf9nZ2f/ampq/2pqav9nZ2f/Z2dn/2lpaf9sbGz/b29v/3Nzc/90dHT/b29v/1xc + XP9bW1v/XFxc/11dXf9eXl7/X19f/2FhYf9iYmL/ZGRk/2VlZf9nZ2f/aWlp/2pqav9sbGz/bW1t/29v + b/9xcXH/dHR0/3Z2dv94eHj/enp6/35+fv+AgID/goKC/4SEhP+Hh4f/ioqK/4yMjP+Ojo7/kZGR/5SU + lP+Wlpb/mJiY/5ubm/+dnZ3/oKCg/6Kiov+kpKT/p6en/6qqqv+tra3/r6+v/7Gxsf+0tLT/tra2/7m5 + uf+7u7v/vr6+/8DAwP/CwsL/xcXF/8fHx//Kysr/zMzM/87Ozv/Q0ND/0NDQMf///wH///8B////Af// + /wHp6enj6Ojo/+fn5//n5+f/5ubm/+Xl5f/l5eX/5OTk/+Pj4//j4+P/4uLi/+Hh4f/g4OD/4ODg/9/f + 3//e3t7/3d3d/9zc3P/a2tr/2dnZ/9jY2P/X19f/1tbW/9TU1P/T09P/0dHR/9DQ0P/Pz8//zc3N/8vL + y//Kysr/yMjI/8fHx//FxcX/w8PD/8DAwP++vr7/u7u7/7i4uP+1tbX/s7Oz/7CwsP+tra3/qamp/6am + pv+ioqL/np6e/5qamv+UlJT/j4+P/4mJif+EhIT/fX19/2NjY/9QUFD/S0tL/01NTf9dXV3/ZWVl/2Vl + Zf9oaGj/a2tr/25ubv9wcHD/c3Nz/3R0dP9wcHD/Wlpa/1dXV/9YWFj/WVlZ/1paWv9bW1v/XV1d/15e + Xv9gYGD/YWFh/2JiYv9kZGT/ZmZm/2dnZ/9paWn/a2tr/21tbf9vb2//cnJy/3R0dP92dnb/eXl5/3t7 + e/9+fn7/gICA/4ODg/+Ghob/iIiI/4uLi/+NjY3/kJCQ/5OTk/+VlZX/mJiY/5qamv+dnZ3/n5+f/6Gh + of+kpKT/p6en/6qqqv+tra3/r6+v/7Gxsf+0tLT/t7e3/7m5uf+7u7v/vr6+/8HBwf/Dw8P/xsbG/8jI + yP/Kysr/zMzM/8/Pz//Q0NAx////Af///wH///8B////Aejo6OPo6Oj/5+fn/+bm5v/m5ub/5eXl/+Tk + 5P/j4+P/4+Pj/+Li4v/h4eH/4ODg/+Dg4P/f39//3t7e/93d3f/c3Nz/2tra/9nZ2f/Y2Nj/19fX/9bW + 1v/U1NT/09PT/9HR0f/Q0ND/z8/P/83Nzf/Ly8v/ycnJ/8jIyP/Gxsb/xMTE/8LCwv/AwMD/vr6+/7u7 + u/+4uLj/tbW1/7Ozs/+wsLD/ra2t/6qqqv+mpqb/oqKi/56env+ZmZn/lJSU/42Njf+IiIj/goKC/319 + ff9ycnL/VFRU/09PT/9JSUn/RUVF/1VVVf9hYWH/ZGRk/2pqav9tbW3/cHBw/3Jycv90dHT/dXV1/3Bw + cP9XV1f/VFRU/1VVVf9WVlb/V1dX/1hYWP9XV1f/S0tL/0lJSf9YWFj/Xl5e/2BgYP9hYWH/Y2Nj/2Vl + Zf9nZ2f/aWlp/2tra/9tbW3/cHBw/3Jycv91dXX/d3d3/3p6ev98fHz/fn5+/4GBgf+EhIT/h4eH/4qK + iv+MjIz/j4+P/5GRkf+UlJT/l5eX/5mZmf+cnJz/np6e/6Ghof+kpKT/p6en/6qqqv+srKz/r6+v/7Ky + sv+0tLT/t7e3/7q6uv+9vb3/v7+//8HBwf/ExMT/xsbG/8nJyf/Ly8v/zs7O/8/PzzH///8B////Af// + /wH///8B6Ojo4+fn5//m5ub/5ubm/+Xl5f/k5OT/5OTk/+Pj4//i4uL/4eHh/+Dg4P/g4OD/39/f/97e + 3v/d3d3/3Nzc/9vb2//Z2dn/2NjY/9fX1//W1tb/1NTU/9PT0//R0dH/0NDQ/8/Pz//Nzc3/y8vL/8nJ + yf/IyMj/xsbG/8TExP/CwsL/wMDA/729vf+7u7v/uLi4/7W1tf+ysrL/sLCw/62trf+qqqr/pqam/6Gh + of+enp7/mZmZ/5OTk/+Ojo7/h4eH/4KCgv98fHz/dnZ2/2xsbP9VVVX/UVFR/0dHR/9DQ0P/UlJS/15e + Xv9nZ2f/bGxs/25ubv9xcXH/dHR0/3d3d/93d3f/cXFx/1NTU/9QUFD/UVFR/1JSUv9TU1P/UlJS/z4+ + Pv8fHx//Hh4e/zExMf9KSkr/Wlpa/15eXv9fX1//YmJi/2NjY/9lZWX/Z2dn/2lpaf9ra2v/bm5u/3Bw + cP9ycnL/dXV1/3h4eP96enr/fX19/4CAgP+Dg4P/hYWF/4iIiP+Li4v/jo6O/5CQkP+Tk5P/lpaW/5mZ + mf+bm5v/np6e/6Ghof+kpKT/p6en/6qqqv+tra3/r6+v/7Kysv+1tbX/uLi4/7q6uv+9vb3/wMDA/8PD + w//FxcX/x8fH/8rKyv/MzMz/zc3NMf///wH///8B////Af///wHn5+fj5+fn/+bm5v/l5eX/5eXl/+Tk + 5P/j4+P/4uLi/+Li4v/h4eH/4ODg/9/f3//e3t7/3d3d/9zc3P/b29v/2tra/9jY2P/X19f/1tbW/9TU + 1P/T09P/0dHR/9DQ0P/Pz8//zc3N/8vLy//Jycn/x8fH/8bGxv/ExMT/wcHB/8DAwP+9vb3/u7u7/7m5 + uf+1tbX/s7Oz/7CwsP+tra3/qqqq/6ampv+jo6P/np6e/5mZmf+UlJT/j4+P/4iIiP+CgoL/fHx8/3Z2 + dv9wcHD/ZmZm/1ZWVv9TU1P/RkZG/0JCQv9PT0//X19f/2lpaf9tbW3/b29v/3Jycv96enr/fn5+/3h4 + eP9xcXH/UVFR/01NTf9OTk7/T09P/09PT/9AQED/ISEh/xoaGv8bGxv/Hh4e/yYmJv88PDz/VFRU/1xc + XP9eXl7/YGBg/2FhYf9jY2P/ZWVl/2dnZ/9qamr/bGxs/25ubv9xcXH/dHR0/3d3d/96enr/fHx8/39/ + f/+BgYH/hISE/4eHh/+Kior/jY2N/5CQkP+Tk5P/lZWV/5mZmf+cnJz/np6e/6Kiov+kpKT/p6en/6qq + qv+tra3/sLCw/7Ozs/+2trb/ubm5/7y8vP+/v7//wcHB/8TExP/Gxsb/ycnJ/8zMzP/MzMwx////Af// + /wH///8B////Aefn5+Pm5ub/5ubm/+Tk5P/k5OT/4+Pj/+Li4v/i4uL/4eHh/+Dg4P/f39//3t7e/93d + 3f/c3Nz/29vb/9ra2v/Z2dn/19fX/9fX1//V1dX/1NTU/9LS0v/Q0ND/z8/P/83Nzf/Ly8v/ycnJ/8fH + x//Gxsb/w8PD/8HBwf+/v7//vb29/7u7u/+4uLj/tbW1/7Kysv+wsLD/ra2t/6mpqf+mpqb/oqKi/5+f + n/+ZmZn/lJSU/46Ojv+IiIj/goKC/3t7e/92dnb/b29v/2lpaf9gYGD/WFhY/1VVVf9ERET/QUFB/0tL + S/9eXl7/a2tr/25ubv9xcXH/enp6/46Ojv+VlZX/fHx8/3Nzc/9PT0//SUlJ/0pKSv9LS0v/PDw8/xsb + G/8TExP/HBwc/x4eHv8dHR3/Hh4e/x4eHv8oKCj/QEBA/1VVVf9bW1v/XV1d/19fX/9hYWH/Y2Nj/2Vl + Zf9oaGj/ampq/21tbf9wcHD/cnJy/3V1df94eHj/e3t7/319ff+AgID/g4OD/4aGhv+JiYn/jIyM/4+P + j/+SkpL/lZWV/5iYmP+bm5v/np6e/6Ghof+kpKT/qKio/6urq/+urq7/sbGx/7W1tf+3t7f/urq6/729 + vf/AwMD/w8PD/8XFxf/IyMj/y8vL/8vLyzH///8B////Af///wH///8B5ubm4+bm5v/l5eX/5OTk/+Pj + 4//i4uL/4uLi/+Hh4f/g4OD/39/f/97e3v/d3d3/3Nzc/9vb2//a2tr/2dnZ/9jY2P/X19f/1dXV/9TU + 1P/S0tL/0dHR/8/Pz//Nzc3/y8vL/8nJyf/IyMj/xcXF/8TExP/BwcH/v7+//729vf+7u7v/uLi4/7W1 + tf+zs7P/r6+v/6ysrP+pqan/pqam/6Ojo/+fn5//mpqa/5SUlP+Pj4//iYmJ/4SEhP99fX3/dnZ2/3Bw + cP9paWn/YmJi/1xcXP9bW1v/V1dX/0ZGRv9FRUX/SkpK/11dXf9sbGz/cHBw/3Z2dv+MjIz/oKCg/4+P + j/9vb2//dnZ2/1dXV/9GRkb/R0dH/z4+Pv8dHR3/EhIS/xgYGP8uLi7/LCws/x4eHv8eHh7/Hh4e/x4e + Hv8hISH/NDQ0/0xMTP9ZWVn/W1tb/11dXf9fX1//YWFh/2RkZP9mZmb/aWlp/2xsbP9ubm7/cXFx/3R0 + dP93d3f/enp6/319ff+AgID/goKC/4aGhv+JiYn/jIyM/4+Pj/+SkpL/lZWV/5iYmP+cnJz/np6e/6Ki + ov+mpqb/qamp/6ysrP+vr6//s7Oz/7a2tv+5ubn/vLy8/76+vv/CwsL/xMTE/8fHx//Kysr/y8vLMf// + /wH///8B////Af///wHm5ubj5eXl/+Tk5P/j4+P/4+Pj/+Li4v/h4eH/4ODg/9/f3//e3t7/3d3d/9zc + 3P/b29v/2tra/9nZ2f/Y2Nj/19fX/9XV1f/U1NT/0tLS/9HR0f/Pz8//zc3N/8zMzP/Kysr/yMjI/8bG + xv/Dw8P/wcHB/7+/v/+9vb3/u7u7/7i4uP+2trb/s7Oz/7CwsP+srKz/qamp/6ampv+jo6P/np6e/5mZ + mf+VlZX/j4+P/4qKiv+EhIT/fn5+/3h4eP9wcHD/ampq/2JiYv9bW1v/WFhY/11dXf9fX1//X19f/1lZ + Wf9MTEz/Xl5e/25ubv92dnb/h4eH/5+fn/+SkpL/VVVV/1ZWVv93d3f/bGxs/05OTv89PT3/JCQk/xMT + E/8YGBj/KCgo/zY2Nv8rKyv/Hh4e/x4eHv8eHh7/Hh4e/x4eHv8eHh7/JSUl/z09Pf9QUFD/WFhY/1tb + W/9dXV3/X19f/2FhYf9kZGT/Z2dn/2pqav9tbW3/cHBw/3Nzc/91dXX/eHh4/3t7e/9+fn7/goKC/4WF + hf+IiIj/i4uL/46Ojv+SkpL/lZWV/5mZmf+cnJz/n5+f/6Ojo/+mpqb/qqqq/62trf+xsbH/tLS0/7e3 + t/+6urr/vb29/8DAwP/Dw8P/xsbG/8nJyf/Kysox////Af///wH///8B////AeXl5ePk5OT/5OTk/+Pj + 4//i4uL/4eHh/+Dg4P/f39//39/f/97e3v/c3Nz/29vb/9ra2v/Z2dn/2NjY/9fX1//W1tb/1NTU/9LS + 0v/R0dH/0NDQ/83Nzf/MzMz/ysrK/8jIyP/Gxsb/xMTE/8HBwf+/v7//vb29/7u7u/+4uLj/tra2/7S0 + tP+wsLD/ra2t/6qqqv+mpqb/o6Oj/6CgoP+ampr/lZWV/5CQkP+JiYn/hISE/35+fv9zc3P/aWlp/2lp + af9kZGT/XFxc/1VVVf9UVFT/YGBg/2NjY/9mZmb/XFxc/09PT/9dXV3/c3Nz/4WFhf+bm5v/lpaW/11d + Xf9MTEz/cHBw/4aGhv92dnb/Y2Nj/ykpKf8WFhb/GBgY/ycnJ/8rKyv/Hx8f/xwcHP8eHh7/Hh4e/x4e + Hv8eHh7/Hh4e/x4eHv8eHh7/Hx8f/ywsLP9DQ0P/VVVV/1lZWf9bW1v/XV1d/2BgYP9jY2P/ZmZm/2lp + af9sbGz/b29v/3Jycv91dXX/eHh4/3t7e/9+fn7/gYGB/4SEhP+IiIj/i4uL/4+Pj/+SkpL/lpaW/5mZ + mf+dnZ3/oaGh/6SkpP+oqKj/q6ur/6+vr/+ysrL/tra2/7m5uf+8vLz/v7+//8LCwv/FxcX/yMjI/8rK + yjH///8B////Af///wH///8B5OTk4+Tk5P/j4+P/4uLi/+Hh4f/g4OD/4ODg/9/f3//e3t7/3d3d/9zc + 3P/b29v/2dnZ/9jY2P/X19f/1tbW/9XV1f/S0tL/0dHR/9DQ0P/Ozs7/zMzM/8rKyv/IyMj/xsbG/8TE + xP/CwsL/wMDA/729vf+7u7v/uLi4/7W1tf+zs7P/sbGx/62trf+qqqr/pqam/6Ojo/+fn5//m5ub/5aW + lv+Pj4//ioqK/4ODg/9+fn7/dHR0/1paWv9NTU3/U1NT/1lZWf9XV1f/UVFR/1RUVP9iYmL/ZWVl/2ho + aP9dXV3/UFBQ/2FhYf+BgYH/mpqa/56env9hYWH/SEhI/2pqav+MjIz/fHx8/5+fn/9nZ2f/HBwc/xcX + F/8lJSX/Kysr/xwcHP8aGhr/HBwc/x4eHv8eHh7/Hh4e/x4eHv8eHh7/Hh4e/x4eHv8eHh7/Hh4e/yMj + I/81NTX/S0tL/1ZWVv9aWlr/XFxc/19fX/9iYmL/ZmZm/2hoaP9ra2v/bm5u/3Fxcf90dHT/d3d3/3t7 + e/9+fn7/gYGB/4WFhf+IiIj/jIyM/4+Pj/+Tk5P/lpaW/5qamv+enp7/oaGh/6ampv+pqan/ra2t/7Gx + sf+0tLT/uLi4/7u7u/++vr7/wcHB/8XFxf/IyMj/ycnJMf///wH///8B////Af///wHj4+Pj4+Pj/+Li + 4v/h4eH/4ODg/9/f3//f39//3t7e/93d3f/c3Nz/29vb/9ra2v/Y2Nj/2NjY/9bW1v/V1dX/09PT/9LS + 0v/Q0ND/zs7O/8zMzP/Kysr/yMjI/8bGxv/ExMT/wsLC/8DAwP+9vb3/u7u7/7i4uP+1tbX/s7Oz/7Cw + sP+urq7/qqqq/6enp/+jo6P/n5+f/5ubm/+Wlpb/kJCQ/4qKiv+EhIT/fX19/3d3d/9eXl7/SkpK/0VF + Rf9BQUH/RUVF/1JSUv9PT0//XFxc/2VlZf9oaGj/ampq/1JSUv9OTk7/bW1t/5eXl/+cnJz/ampq/0dH + R/9mZmb/iYmJ/35+fv+vr6//+vr6/9HR0f84ODj/HR0d/ykpKf8hISH/GRkZ/xsbG/8dHR3/Hh4e/x8f + H/8fHx//Hh4e/x4eHv8eHh7/Hh4e/x4eHv8eHh7/HR0d/x0dHf8lJSX/PT09/09PT/9YWFj/W1tb/15e + Xv9hYWH/ZGRk/2dnZ/9paWn/bGxs/3BwcP9zc3P/dnZ2/3p6ev9+fn7/gYGB/4SEhP+IiIj/i4uL/4+P + j/+Tk5P/l5eX/5ubm/+enp7/o6Oj/6enp/+rq6v/r6+v/7Ozs/+3t7f/urq6/76+vv/BwcH/xMTE/8fH + x//IyMgx////Af///wH///8B////AePj4+Pi4uL/4uLi/+Hh4f/g4OD/39/f/97e3v/d3d3/3Nzc/9vb + 2//a2tr/2dnZ/9jY2P/W1tb/1dXV/9PT0//S0tL/0NDQ/87Ozv/MzMz/ysrK/8nJyf/Hx8f/xcXF/8LC + wv/AwMD/vr6+/7u7u/+5ubn/tbW1/7Ozs/+wsLD/rq6u/6urq/+np6f/pKSk/6CgoP+cnJz/l5eX/5KS + kv+Li4v/hISE/39/f/93d3f/cHBw/1VVVf9MTEz/Q0ND/z4+Pv9BQUH/T09P/1NTU/9jY2P/Z2dn/2pq + av9ra2v/S0tL/0hISP9xcXH/m5ub/2tra/9GRkb/YWFh/4eHh/98fHz/nZ2d//Hx8f/8/Pz/wsLC/zAw + MP8gICD/JSUl/yIiIv8hISH/IiIi/yEhIf8fHx//Hh4e/x4eHv8fHx//Hh4e/x4eHv8eHh7/Hh4e/x4e + Hv8eHh7/Hh4e/x0dHf8hISH/Ly8v/0hISP9XV1f/Wlpa/11dXf9gYGD/ZGRk/2ZmZv9paWn/bGxs/29v + b/9zc3P/dnZ2/3p6ev99fX3/gICA/4WFhf+IiIj/jY2N/5CQkP+UlJT/mZmZ/5ycnP+hoaH/paWl/6mp + qf+tra3/srKy/7a2tv+5ubn/vb29/8DAwP/ExMT/x8fH/8jIyDH///8B////Af///wH///8B4uLi4+Hh + 4f/h4eH/4ODg/9/f3//e3t7/3d3d/9zc3P/b29v/2tra/9nZ2f/Y2Nj/19fX/9bW1v/U1NT/0tLS/9HR + 0f/Ozs7/zc3N/8rKyv/Jycn/x8fH/8XFxf/Dw8P/wMDA/76+vv+7u7v/uLi4/7a2tv+zs7P/sLCw/62t + rf+qqqr/p6en/6Ojo/+fn5//m5ub/5eXl/+RkZH/i4uL/4aGhv9+fn7/eHh4/3BwcP9qamr/VlZW/1BQ + UP9BQUH/Ojo6/z09Pf9NTU3/XFxc/2dnZ/9qamr/bGxs/25ubv9LS0v/R0dH/19fX/9mZmb/RERE/1tb + W/+IiIj/goKC/6CgoP/09PT//Pz8/7y8vP8+Pj7/HBwc/ygoKP8oKCj/ICAg/yIiIv8kJCT/JSUl/yQk + JP8gICD/Hh4e/x8fH/8fHx//Hh4e/x4eHv8eHh7/Hh4e/x4eHv8eHh7/Hh4e/x4eHv8eHh7/IiIi/zY2 + Nv9MTEz/WFhY/1xcXP9fX1//YmJi/2VlZf9oaGj/a2tr/29vb/9ycnL/dnZ2/3l5ef98fHz/gYGB/4SE + hP+JiYn/jY2N/5GRkf+VlZX/mpqa/56env+ioqL/p6en/6ysrP+wsLD/tbW1/7m5uf+9vb3/wMDA/8PD + w//Gxsb/yMjIMf///wH///8B////Af///wHi4uLj4eHh/+Dg4P/f39//3t7e/93d3f/c3Nz/29vb/9ra + 2v/Z2dn/2NjY/9fX1//W1tb/1NTU/9PT0//R0dH/z8/P/83Nzf/Ly8v/ycnJ/8fHx//FxcX/w8PD/8HB + wf++vr7/vLy8/7m5uf+2trb/tLS0/7Gxsf+urq7/qqqq/6enp/+jo6P/n5+f/5ubm/+Wlpb/kZGR/4yM + jP+Ghob/gICA/3l5ef9zc3P/bGxs/2ZmZv9YWFj/UlJS/z8/P/83Nzf/Ozs7/09PT/9kZGT/aWlp/2tr + a/9tbW3/eHh4/2FhYf9LS0v/U1NT/0RERP9XV1f/f39//4aGhv+QkJD/6Ojo///////S0tL/R0dH/xwc + HP8nJyf/KSkp/yIiIv8fHx//IyMj/yQkJP8lJSX/JiYm/yUlJf8iIiL/Hx8f/x8fH/8fHx//Hx8f/x4e + Hv8eHh7/Hh4e/x4eHv8eHh7/Hh4e/x4eHv8eHh7/Hx8f/yoqKv9CQkL/VFRU/1xcXP9fX1//YmJi/2Vl + Zf9oaGj/bGxs/29vb/9ycnL/dnZ2/3l5ef9+fn7/gYGB/4aGhv+Kior/jo6O/5KSkv+Xl5f/nJyc/6Cg + oP+mpqb/qqqq/6+vr/+zs7P/t7e3/7y8vP/AwMD/w8PD/8bGxv/IyMgx////Af///wH///8B////AeHh + 4ePg4OD/4ODg/9/f3//e3t7/3d3d/9zc3P/a2tr/2dnZ/9jY2P/X19f/1tbW/9TU1P/T09P/0tLS/9DQ + 0P/Ozs7/y8vL/8nJyf/Hx8f/xcXF/8PDw//BwcH/vr6+/7y8vP+5ubn/tra2/7S0tP+xsbH/rq6u/6ur + q/+np6f/pKSk/6CgoP+bm5v/lpaW/5CQkP+MjIz/hoaG/4CAgP96enr/c3Nz/25ubv9nZ2f/YWFh/1lZ + Wf9VVVX/PT09/zQ0NP85OTn/TU1N/2ZmZv9ra2v/bW1t/3Z2dv+NjY3/kZGR/15eXv9VVVX/QEBA/15e + Xv+Dg4P/jo6O/+Hh4f/8/Pz/1dXV/1dXV/8cHBz/JiYm/ykpKf8hISH/Hx8f/yIiIv8kJCT/JSUl/yYm + Jv8mJib/Jycn/yYmJv8jIyP/ISEh/x8fH/8fHx//Hx8f/x8fH/8eHh7/Hh4e/x4eHv8eHh7/Hh4e/x4e + Hv8eHh7/Hh4e/yEhIf8wMDD/TExM/1hYWP9eXl7/YWFh/2RkZP9oaGj/a2tr/25ubv9xcXH/dXV1/3p6 + ev99fX3/goKC/4WFhf+Kior/j4+P/5SUlP+ZmZn/np6e/6Ojo/+oqKj/ra2t/7Kysv+3t7f/u7u7/7+/ + v//Dw8P/xsbG/8jIyDH///8B////Af///wH///8B4eHh4+Dg4P/f39//3t7e/93d3f/c3Nz/29vb/9ra + 2v/Z2dn/19fX/9bW1v/U1NT/09PT/9LS0v/Q0ND/zs7O/8zMzP/Kysr/yMjI/8bGxv/Dw8P/wcHB/76+ + vv+8vLz/ubm5/7e3t/+0tLT/sbGx/66urv+rq6v/qKio/6SkpP+goKD/m5ub/5aWlv+RkZH/i4uL/4aG + hv+AgID/enp6/3R0dP9ubm7/aGho/2JiYv9dXV3/W1tb/1paWv9ISEj/QkJC/zo6Ov9KSkr/Z2dn/2xs + bP91dXX/iYmJ/6CgoP+Kior/U1NT/1hYWP9JSUn/PT09/1dXV//X19f//////93d3f9oaGj/Hh4e/yYm + Jv8qKir/Hx8f/x4eHv8hISH/JCQk/yUlJf8mJib/JiYm/yYmJv8mJib/JiYm/yUlJf8kJCT/IiIi/yAg + IP8fHx//Hx8f/x8fH/8fHx//Hh4e/x4eHv8eHh7/Hh4e/x4eHv8eHh7/Hh4e/x4eHv8mJib/Ozs7/1JS + Uv9dXV3/YGBg/2RkZP9nZ2f/ampq/21tbf9xcXH/dXV1/3h4eP99fX3/gYGB/4aGhv+Li4v/kZGR/5eX + l/+bm5v/oaGh/6ampv+srKz/sbGx/7a2tv+7u7v/v7+//8PDw//Gxsb/yMjIMf///wH///8B////Af// + /wHg4ODj4ODg/9/f3//d3d3/3d3d/9vb2//a2tr/2dnZ/9fX1//W1tb/1NTU/9PT0//S0tL/0NDQ/87O + zv/MzMz/ysrK/8jIyP/Gxsb/xMTE/8LCwv+/v7//vb29/7q6uv+2trb/tLS0/7Kysv+urq7/q6ur/6io + qP+lpaX/oaGh/5ycnP+Xl5f/kZGR/4yMjP+Ghob/gYGB/3t7e/90dHT/b29v/2lpaf9jY2P/Xl5e/1lZ + Wf9cXFz/YGBg/2BgYP9YWFj/PT09/0dHR/9oaGj/cnJy/4aGhv+cnJz/kZGR/1dXV/9NTU3/YWFh/1hY + WP9AQED/NTU1/4uLi//W1tb/cHBw/yEhIf8iIiL/Kioq/yEhIf8eHh7/ISEh/yQkJP8lJSX/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yUlJf8mJib/JCQk/yIiIv8gICD/Hx8f/x8fH/8fHx//Hh4e/x4e + Hv8eHh7/Hh4e/x4eHv8eHh7/Hh4e/x4eHv8gICD/Li4u/0pKSv9aWlr/YGBg/2JiYv9lZWX/aGho/2xs + bP9wcHD/dHR0/3l5ef99fX3/goKC/4iIiP+Ojo7/lJSU/5mZmf+fn5//paWl/6urq/+wsLD/tbW1/7q6 + uv++vr7/w8PD/8bGxv/IyMgx////Af///wH///8B////AeDg4OPf39//3t7e/93d3f/b29v/2tra/9nZ + 2f/X19f/1tbW/9TU1P/T09P/0tLS/9DQ0P/Ozs7/zMzM/8rKyv/IyMj/xsbG/8TExP/CwsL/v7+//729 + vf+6urr/t7e3/7S0tP+ysrL/rq6u/6urq/+oqKj/pKSk/6Ghof+dnZ3/mJiY/5KSkv+MjIz/h4eH/4GB + gf97e3v/b29v/1tbW/9dXV3/YmJi/19fX/9ZWVn/VlZW/15eXv9jY2P/ZWVl/1lZWf87Ozv/R0dH/29v + b/+EhIT/nJyc/5WVlf9QUFD/SkpK/3Jycv+CgoL/aWlp/1FRUf8jIyP/GRkZ/zY2Nv8jIyP/ISEh/yoq + Kv8hISH/HR0d/yIiIv8lJSX/JSUl/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JSUl/yQkJP8hISH/Hx8f/x8fH/8fHx//Hx8f/x8fH/8fHx//Hh4e/x4eHv8eHh7/Hh4e/x4e + Hv8eHh7/ISEh/zMzM/9PT0//W1tb/19fX/9jY2P/ZmZm/2pqav9ubm7/dHR0/3l5ef9/f3//hYWF/4uL + i/+SkpL/l5eX/52dnf+jo6P/qamp/7CwsP+0tLT/urq6/76+vv/Dw8P/xsbG/8jIyDH///8B////Af// + /wH///8B39/f497e3v/d3d3/3Nzc/9vb2//a2tr/2NjY/9fX1//V1dX/09PT/9LS0v/Q0ND/zs7O/8zM + zP/Kysr/yMjI/8fHx//ExMT/wsLC/8DAwP+9vb3/u7u7/7i4uP+1tbX/srKy/6+vr/+rq6v/qKio/6Wl + pf+hoaH/nZ2d/5mZmf+UlJT/jo6O/4iIiP+Dg4P/fHx8/3Nzc/9ZWVn/SkpK/0dHR/9OTk7/WFhY/1ZW + Vv9VVVX/YGBg/2RkZP9nZ2f/Wlpa/zo6Ov9KSkr/fX19/5mZmf+YmJj/YGBg/0ZGRv9oaGj/iYmJ/3t7 + e/+wsLD/hISE/x4eHv8RERH/IiIi/yYmJv8eHh7/IiIi/xwcHP8fHx//IyMj/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yUlJf8iIiL/ISEh/x8f + H/8fHx//Hx8f/x8fH/8fHx//Hx8f/x4eHv8eHh7/Hh4e/x4eHv8eHh7/Hh4e/ykpKf8/Pz//VVVV/11d + Xf9hYWH/ZWVl/2pqav9wcHD/dXV1/3x8fP+CgoL/iYmJ/5CQkP+VlZX/nJyc/6Kiov+pqan/r6+v/7Oz + s/+5ubn/vr6+/8PDw//Hx8f/yMjIMf///wH///8B////Af///wHe3t7j3t7e/9zc3P/b29v/2tra/9jY + 2P/X19f/1dXV/9TU1P/S0tL/0NDQ/8/Pz//MzMz/y8vL/8jIyP/Gxsb/xMTE/8LCwv/AwMD/vb29/7u7 + u/+4uLj/tbW1/7Ozs/+vr6//rKys/6ioqP+lpaX/oaGh/52dnf+ZmZn/lJSU/4+Pj/+JiYn/goKC/319 + ff92dnb/ZWVl/05OTv9ISEj/QEBA/0BAQP9QUFD/U1NT/1paWv9jY2P/Z2dn/2hoaP9VVVX/MDAw/09P + T/+Tk5P/mZmZ/2BgYP9FRUX/aGho/4mJif97e3v/r6+v//f39//q6ur/dHR0/xgYGP8fHx//GBgY/xYW + Fv8ZGRn/Hx8f/yQkJP8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yUlJf8kJCT/ISEh/x4eHv8fHx//Hx8f/x8fH/8fHx//Hx8f/x8f + H/8fHx//Hh4e/x4eHv8eHh7/Hh4e/x8fH/8tLS3/RkZG/1hYWP9gYGD/ZWVl/2xsbP9ycnL/eXl5/4CA + gP+Hh4f/jo6O/5SUlP+bm5v/oaGh/6enp/+tra3/s7Oz/7m5uf++vr7/w8PD/8fHx//IyMgx////Af// + /wH///8B////Ad7e3uPd3d3/3Nzc/9ra2v/Z2dn/19fX/9XV1f/U1NT/09PT/9HR0f/Pz8//zc3N/8vL + y//Jycn/x8fH/8XFxf/Dw8P/wMDA/76+vv+7u7v/uLi4/7a2tv+zs7P/sLCw/62trf+pqan/pqam/6Ki + ov+enp7/mZmZ/5WVlf+QkJD/ioqK/4SEhP99fX3/d3d3/3BwcP9hYWH/UFBQ/0dHR/89PT3/PT09/01N + Tf9UVFT/YGBg/2VlZf9oaGj/ampq/1FRUf8rKyv/SkpK/5CQkP9paWn/RUVF/15eXv+IiIj/f39//6mp + qf/z8/P/+vr6/62trf83Nzf/HR0d/yAgIP8YGBj/Ghoa/x8fH/8lJSX/Jycn/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JSUl/yUl + Jf8kJCT/IiIi/yEhIf8fHx//Hx8f/x8fH/8fHx//Hx8f/x8fH/8fHx//Hx8f/x8fH/8fHx//Hx8f/x8f + H/8kJCT/Nzc3/1RUVP9iYmL/ampq/3BwcP93d3f/fn5+/4WFhf+MjIz/kpKS/5mZmf+goKD/pqam/62t + rf+ysrL/uLi4/76+vv/Dw8P/x8fH/8jIyDH///8B////Af///wH///8B3d3d49zc3P/b29v/2dnZ/9jY + 2P/W1tb/1NTU/9PT0//R0dH/0NDQ/83Nzf/Ly8v/ycnJ/8fHx//FxcX/w8PD/8HBwf++vr7/u7u7/7m5 + uf+2trb/s7Oz/7CwsP+tra3/qqqq/6ampv+ioqL/np6e/5qamv+VlZX/kZGR/4uLi/+FhYX/f39//3d3 + d/9xcXH/a2tr/19fX/9TU1P/RkZG/zo6Ov86Ojr/SkpK/1xcXP9lZWX/Z2dn/2lpaf9sbGz/WVlZ/y8v + L/87Ozv/UlJS/0ZGRv9dXV3/g4OD/4KCgv+ZmZn/8fHx//z8/P+/v7//ODg4/xwcHP8oKCj/JCQk/xwc + HP8fHx//JSUl/ycnJ/8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JSUl/yUlJf8kJCT/IyMj/yEhIf8fHx//Hx8f/x8f + H/8fHx//Hx8f/x8fH/8fHx//Hx8f/x8fH/8fHx//Hx8f/x8fH/8gICD/LCws/0RERP9iYmL/bW1t/3V1 + df97e3v/fHx8/4ODg/+Pj4//mJiY/56env+lpaX/q6ur/7Gxsf+4uLj/vr6+/8PDw//Hx8f/yMjIMf// + /wH///8B////Af///wHc3Nzj29vb/9ra2v/Y2Nj/1tbW/9XV1f/U1NT/0dHR/9DQ0P/Ozs7/zMzM/8rK + yv/IyMj/xcXF/8PDw//AwMD/vr6+/7y8vP+5ubn/tra2/7S0tP+xsbH/ra2t/6qqqv+np6f/o6Oj/5+f + n/+bm5v/lpaW/5GRkf+MjIz/hoaG/4CAgP95eXn/cnJy/2xsbP9mZmb/Xl5e/1VVVf9FRUX/Nzc3/zg4 + OP9ISEj/YWFh/2dnZ/9paWn/bGxs/3Z2dv97e3v/QUFB/zY2Nv8wMDD/SkpK/4KCgv+Ghob/mJiY/+rq + 6v/8/Pz/xsbG/0tLS/8aGhr/JiYm/yYmJv8dHR3/ISEh/yYmJv8nJyf/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JSUl/yUlJf8kJCT/JCQk/yQkJP8hISH/Hx8f/x8fH/8fHx//Hx8f/x8fH/8fHx//Hx8f/x8f + H/8fHx//Hx8f/x8fH/8fHx//ICAg/zg4OP9XV1f/b29v/3Fxcf9dXV3/Y2Nj/3l5ef+RkZH/nZ2d/6Oj + o/+qqqr/sbGx/7i4uP+9vb3/w8PD/8fHx//IyMgx////Af///wH///8B////Adzc3OPa2tr/2dnZ/9fX + 1//V1dX/1NTU/9LS0v/Q0ND/zs7O/8zMzP/Kysr/yMjI/8bGxv/ExMT/wcHB/7+/v/+8vLz/ubm5/7e3 + t/+0tLT/sbGx/66urv+rq6v/qKio/6SkpP+goKD/nJyc/5iYmP+Tk5P/jY2N/4iIiP+BgYH/e3t7/3R0 + dP9ubm7/aGho/2NjY/9dXV3/WFhY/0RERP81NTX/NTU1/0VFRf9iYmL/aWlp/2tra/90dHT/i4uL/5mZ + mf9cXFz/ODg4/y8vL/88PDz/dHR0/4eHh//q6ur//v7+/9jY2P9WVlb/Gxsb/yUlJf8pKSn/Hh4e/x8f + H/8kJCT/Jycn/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JSUl/yUlJf8lJSX/JSUl/yMj + I/8hISH/Hx8f/x8fH/8fHx//Hx8f/x8fH/8fHx//Hx8f/x8fH/8fHx//Hx8f/x8fH/8fHx//ISEh/ykp + Kf9ISEj/VVVV/01NTf9fX1//ZWVl/4ODg/+cnJz/o6Oj/6qqqv+wsLD/uLi4/76+vv/Dw8P/x8fH/8jI + yDH///8B////Af///wH///8B2tra49nZ2f/X19f/1tbW/9TU1P/S0tL/0dHR/8/Pz//Nzc3/y8vL/8nJ + yf/Hx8f/xMTE/8LCwv+/v7//vLy8/7q6uv+3t7f/tbW1/7Gxsf+urq7/q6ur/6enp/+lpaX/oKCg/5yc + nP+Xl5f/kpKS/42Njf+IiIj/goKC/3x8fP92dnb/b29v/2lpaf9kZGT/X19f/1xcXP9bW1v/VFRU/09P + T/88PDz/QEBA/2RkZP9ra2v/dHR0/4yMjP+fn5//g4OD/0xMTP8+Pj7/NjY2/ysrK/89PT3/tra2//z8 + /P/c3Nz/UVFR/xkZGf8lJSX/KCgo/x4eHv8fHx//IyMj/yUlJf8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yUlJf8lJSX/JSUl/yQkJP8iIiL/ISEh/yAgIP8fHx//Hh4e/x8f + H/8gICD/ICAg/yAgIP8gICD/ICAg/yAgIP8gICD/ICAg/yAgIP8oKCj/Ojo6/2BgYP9oaGj/f39//5ub + m/+jo6P/q6ur/7Gxsf+5ubn/vr6+/8TExP/Hx8f/yMjIMf///wH///8B////Af///wHa2trj2NjY/9bW + 1v/V1dX/09PT/9HR0f/Pz8//zs7O/8vLy//Jycn/x8fH/8XFxf/Dw8P/wMDA/729vf+6urr/uLi4/7W1 + tf+ysrL/r6+v/6urq/+oqKj/paWl/6Ghof+dnZ3/mZmZ/5OTk/+Ojo7/iYmJ/4ODg/99fX3/c3Nz/2tr + a/9qamr/ZWVl/2BgYP9cXFz/W1tb/15eXv9hYWH/YWFh/zs7O/8zMzP/ZGRk/3Fxcf+Ghob/n5+f/5GR + kf9NTU3/SkpK/2BgYP9DQ0P/NDQ0/ykpKf9LS0v/n5+f/2pqav8cHBz/IiIi/ykpKf8fHx//Gxsb/yEh + If8kJCT/JSUl/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/IyMj/yAgIP8eHh7/Hh4e/yAgIP8gICD/ICAg/yAgIP8gICD/ICAg/yAg + IP8gICD/ICAg/yAgIP8kJCT/Pj4+/2JiYv+BgYH/nJyc/6Ojo/+rq6v/srKy/7m5uf+/v7//xMTE/8fH + x//IyMgx////Af///wH///8B////AdjY2OPX19f/1dXV/9PT0//S0tL/0NDQ/87Ozv/MzMz/ysrK/8jI + yP/Gxsb/w8PD/8HBwf++vr7/u7u7/7i4uP+2trb/srKy/6+vr/+srKz/qKio/6Wlpf+hoaH/np6e/5mZ + mf+UlJT/jo6O/4mJif+EhIT/fX19/3Nzc/9WVlb/TU1N/1ZWVv9fX1//XFxc/1hYWP9bW1v/YWFh/2Rk + ZP9iYmL/OTk5/zIyMv9sbGz/hISE/5ycnP+QkJD/U1NT/0pKSv9ubm7/hoaG/21tbf9SUlL/GRkZ/xIS + Ev8gICD/IyMj/yEhIf8pKSn/IiIi/x8fH/8gICD/IyMj/yUlJf8lJSX/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8lJSX/IyMj/yEh + If8fHx//ICAg/yAgIP8gICD/ICAg/yAgIP8gICD/ICAg/yAgIP8gICD/ICAg/yAgIP8iIiL/R0dH/4KC + gv+cnJz/pKSk/6ysrP+ysrL/urq6/8DAwP/FxcX/yMjI/8jIyDH///8B////Af///wH///8B19fX49bW + 1v/U1NT/0tLS/9DQ0P/Pz8//zc3N/8vLy//IyMj/xsbG/8PDw//CwsL/v7+//7y8vP+5ubn/tra2/7Oz + s/+wsLD/ra2t/6mpqf+mpqb/oqKi/56env+ZmZn/lJSU/5CQkP+Kior/hISE/35+fv91dXX/XFxc/0tL + S/9ERET/QEBA/09PT/9ZWVn/WFhY/15eXv9jY2P/ZWVl/2JiYv8zMzP/MDAw/319ff+ampr/kpKS/1dX + V/9GRkb/a2tr/4uLi/9+fn7/vb29/8rKyv9NTU3/FRUV/xwcHP8dHR3/GBgY/x0dHf8dHR3/ISEh/yMj + I/8kJCT/JSUl/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yUlJf8lJSX/JSUl/yMjI/8iIiL/ISEh/yAgIP8gICD/ICAg/yAg + IP8gICD/ICAg/yAgIP8gICD/ICAg/yEhIf9ERET/hYWF/52dnf+lpaX/rKys/7Ozs/+7u7v/wcHB/8XF + xf/IyMj/ycnJMf///wH///8B////Af///wHW1tbj1dXV/9TU1P/R0dH/z8/P/83Nzf/Ly8v/ycnJ/8fH + x//FxcX/wsLC/7+/v/+8vLz/urq6/7e3t/+0tLT/sbGx/62trf+qqqr/pqam/6Kiov+enp7/mpqa/5aW + lv+QkJD/i4uL/4WFhf9+fn7/eXl5/25ubv9UVFT/TExM/0BAQP88PDz/SUlJ/1ZWVv9bW1v/YmJi/2Vl + Zf9nZ2f/YmJi/ywsLP8sLCz/ioqK/5ycnP9eXl7/RERE/2NjY/+IiIj/enp6/7S0tP/4+Pj/8fHx/39/ + f/8gICD/GRkZ/xUVFf8VFRX/Ghoa/yAgIP8jIyP/JCQk/yUlJf8lJSX/JSUl/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8lJSX/JSUl/yQkJP8jIyP/ISEh/yAgIP8gICD/ICAg/yAgIP8hISH/ISEh/yEhIf8hISH/ISEh/0BA + QP+FhYX/np6e/6enp/+vr6//tra2/76+vv/CwsL/xsbG/8nJyf/Kysox////Af///wH///8B////AdbW + 1uPU1NT/0tLS/9DQ0P/Ozs7/zMzM/8rKyv/Hx8f/xcXF/8PDw//AwMD/vb29/7q6uv+3t7f/tLS0/7Gx + sf+urq7/qqqq/6enp/+jo6P/n5+f/5ubm/+VlZX/kZGR/4uLi/+FhYX/f39//3l5ef90dHT/aWlp/1VV + Vf9NTU3/PT09/zg4OP9GRkb/VVVV/2FhYf9lZWX/aGho/2lpaf9mZmb/LS0t/yUlJf9oaGj/ZmZm/0RE + RP9iYmL/hoaG/319ff+pqan/+vr6//f39/+cnJz/Jycn/xwcHP8kJCT/Ghoa/xsbG/8gICD/IyMj/yQk + JP8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JSUl/yUlJf8kJCT/IiIi/yAg + IP8fHx//Hx8f/yAgIP8hISH/ISEh/yEhIf8hISH/Nzc3/319ff+Xl5f/pqam/7Ozs/+6urr/wMDA/8TE + xP/Hx8f/ysrK/8vLyzH///8B////Af///wH///8B1dXV49PT0//R0dH/z8/P/8zMzP/Kysr/yMjI/8bG + xv/Dw8P/wcHB/76+vv+8vLz/uLi4/7W1tf+ysrL/r6+v/6ysrP+oqKj/pKSk/6CgoP+bm5v/l5eX/5KS + kv+NjY3/hoaG/4GBgf96enr/dXV1/3BwcP9nZ2f/V1dX/05OTv85OTn/NTU1/0NDQ/9XV1f/ZWVl/2dn + Z/9paWn/bGxs/29vb/8zMzP/JSUl/zQ0NP9AQED/Wlpa/4ODg/98fHz/nZ2d/+/v7//7+/v/t7e3/zc3 + N/8cHBz/KCgo/yUlJf8eHh7/ICAg/yMjI/8kJCT/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8kJCT/IiIi/yAgIP8fHx//ICAg/yEhIf8hISH/ISEh/yEh + If8vLy//enp6/42Njf+cnJz/tra2/729vf/BwcH/xMTE/8fHx//Kysr/y8vLMf///wH///8B////Af// + /wHU1NTj0tLS/9DQ0P/Nzc3/y8vL/8nJyf/Gxsb/xMTE/8HBwf+/v7//vLy8/7m5uf+1tbX/srKy/6+v + r/+srKz/qKio/6Wlpf+goKD/m5ub/5aWlv+SkpL/jY2N/4iIiP+BgYH/e3t7/3Z2dv9wcHD/a2tr/2Rk + ZP9ZWVn/UFBQ/zc3N/8yMjL/QUFB/1paWv9oaGj/aWlp/21tbf94eHj/jo6O/11dXf8oKCj/Jycn/zg4 + OP93d3f/gICA/5qamv/19fX//v7+/7m5uf86Ojr/Ghoa/ygoKP8mJib/HR0d/yAgIP8jIyP/JCQk/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yUl + Jf8kJCT/IyMj/yMjI/8hISH/ICAg/x8fH/8gICD/ISEh/ysrK/95eXn/jY2N/5ubm/+6urr/v7+//8PD + w//Gxsb/ycnJ/8zMzP/MzMwx////Af///wH///8B////AdPT0+PR0dH/z8/P/8zMzP/Kysr/x8fH/8XF + xf/Dw8P/wMDA/729vf+6urr/tra2/7Ozs/+wsLD/ra2t/6mpqf+mpqb/oaGh/52dnf+Xl5f/k5OT/46O + jv+JiYn/hISE/319ff93d3f/cnJy/2xsbP9nZ2f/YWFh/1tbW/9RUVH/Pj4+/zc3N/89PT3/W1tb/2lp + af9ra2v/d3d3/42Njf+goKD/bGxs/y4uLv8mJib/KSkp/01NTf+Li4v/5ubm//7+/v/a2tr/RUVF/xoa + Gv8lJSX/KCgo/x8fH/8fHx//IiIi/yQkJP8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yUlJf8lJSX/JiYm/yUlJf8hISH/Hh4e/x8f + H/8hISH/LCws/3p6ev+Ojo7/nZ2d/729vf/BwcH/xMTE/8bGxv/Jycn/zMzM/83NzTH///8B////Af// + /wH///8B0tLS49DQ0P/Ozs7/y8vL/8nJyf/Gxsb/xMTE/8HBwf++vr7/u7u7/7i4uP+0tLT/sbGx/62t + rf+qqqr/pqam/6Kiov+dnZ3/mZmZ/5SUlP+Pj4//ioqK/4WFhf9/f3//dnZ2/3Jycv9tbW3/aGho/2Rk + ZP9eXl7/XV1d/15eXv9eXl7/R0dH/zQ0NP9WVlb/bGxs/3R0dP+NjY3/oKCg/4CAgP9GRkb/Pj4+/ysr + K/8mJib/LCws/3Fxcf/b29v/0dHR/1hYWP8bGxv/JCQk/ykpKf8hISH/Hx8f/yMjI/8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yQkJP8iIiL/Hx8f/x8fH/8pKSn/d3d3/5CQkP+dnZ3/vr6+/8LC + wv/FxcX/yMjI/8vLy//Nzc3/zs7OMf///wH///8B////Af///wHR0dHjz8/P/8zMzP/Kysr/yMjI/8bG + xv/Dw8P/v7+//7y8vP+5ubn/tra2/7Kysv+vr6//q6ur/6enp/+jo6P/n5+f/5mZmf+VlZX/kJCQ/4qK + iv+FhYX/gICA/3Nzc/9cXFz/YmJi/2dnZ/9kZGT/YGBg/1xcXP9fX1//YmJi/2VlZf9ISEj/Kysr/1JS + Uv9zc3P/h4eH/56env+FhYX/S0tL/0xMTP9wcHD/VVVV/yoqKv8gICD/Ghoa/09PT/9nZ2f/ISEh/yMj + I/8oKCj/ICAg/yEhIf8kJCT/Jycn/yYmJv8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8kJCT/IiIi/y0tLf97e3v/kZGR/56env+/v7//xMTE/8fHx//Jycn/zMzM/87Ozv/Pz88x////Af// + /wH///8B////Ac/Pz+POzs7/y8vL/8nJyf/Gxsb/xMTE/8HBwf++vr7/urq6/7e3t/+0tLT/sLCw/6ys + rP+oqKj/pKSk/6CgoP+cnJz/lpaW/5GRkf+MjIz/hoaG/4GBgf91dXX/W1tb/0tLS/9KSkr/UlJS/15e + Xv9cXFz/XFxc/2FhYf9lZWX/Z2dn/0VFRf8pKSn/VlZW/4aGhv+dnZ3/kJCQ/1BQUP9GRkb/bm5u/4iI + iP91dXX/dHR0/yAgIP8LCwv/KSkp/2tra/8pKSn/JSUl/yAgIP8fHx//JCQk/ycnJ/8mJib/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yUlJf8rKyv/WVlZ/42Njf+SkpL/np6e/8DA + wP/FxcX/yMjI/8vLy//Nzc3/z8/P/9DQ0DH///8B////Af///wH///8Bzs7O48zMzP/Kysr/x8fH/8XF + xf/CwsL/v7+//7u7u/+4uLj/tbW1/7Gxsf+urq7/qamp/6Wlpf+hoaH/nJyc/5iYmP+RkZH/jY2N/4aG + hv+AgID/enp6/2RkZP9PT0//SEhI/0NDQ/9ERET/V1dX/1lZWf9gYGD/ZWVl/2dnZ/9paWn/QUFB/yYm + Jv9jY2P/np6e/5OTk/9TU1P/RUVF/2tra/+IiIj/dnZ2/87Ozv/4+Pj/nJyc/x8fH/8eHh7/IiIi/xMT + E/8YGBj/Hh4e/yMjI/8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8lJSX/JiYm/0lJSf+EhIT/k5OT/5OTk/+kpKT/w8PD/8bGxv/Kysr/y8vL/87Ozv/Q0ND/0dHRMf// + /wH///8B////Af///wHNzc3jy8vL/8nJyf/Gxsb/xMTE/8DAwP+9vb3/urq6/7a2tv+zs7P/rq6u/6ur + q/+np6f/oqKi/56env+ZmZn/lJSU/42Njf+IiIj/gICA/3p6ev90dHT/YGBg/1FRUf9GRkb/Pz8//0JC + Qv9VVVX/Wlpa/2RkZP9mZmb/aWlp/2tra/89PT3/Hx8f/1tbW/+ampr/Xl5e/0JCQv9jY2P/hoaG/3p6 + ev+zs7P//Pz8//b29v+NjY3/Hx8f/x0dHf8VFRX/FBQU/x0dHf8gICD/IyMj/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JSUl/yQkJP8kJCT/Hx8f/zg4OP9+fn7/mZmZ/7W1 + tf/Gxsb/yMjI/8vLy//Nzc3/z8/P/9HR0f/S0tIx////Af///wH///8B////AczMzOPKysr/yMjI/8XF + xf/CwsL/vr6+/7u7u/+3t7f/s7Oz/7CwsP+srKz/qKio/6Ojo/+enp7/mZmZ/5SUlP+Pj4//iIiI/4KC + gv96enr/dHR0/25ubv9dXV3/VVVV/0RERP88PDz/Pj4+/1RUVP9gYGD/Z2dn/2lpaf9ra2v/bm5u/0FB + Qf8eHh7/MzMz/1VVVf9BQUH/Y2Nj/4WFhf95eXn/s7Oz//f39//z8/P/lJSU/yIiIv8cHBz/Jycn/x4e + Hv8bGxv/ICAg/yEhIf8kJCT/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yUl + Jf8jIyP/ISEh/w8PD/8CAgL/JSUl/4mJif+xsbH/w8PD/8fHx//Jycn/y8vL/83Nzf/Q0ND/0tLS/9LS + 0jH///8B////Af///wH///8BzMzM48nJyf/Gxsb/w8PD/8DAwP+8vLz/ubm5/7W1tf+xsbH/ra2t/6mp + qf+lpaX/oKCg/5ubm/+VlZX/kJCQ/4qKiv+Dg4P/fX19/3Z2dv9wcHD/a2tr/15eXv9YWFj/Q0ND/zg4 + OP88PDz/VFRU/2RkZP9paWn/a2tr/25ubv97e3v/Xl5e/x8fH/8hISH/NjY2/1hYWP+Dg4P/fHx8/6Gh + of/19fX//v7+/6enp/8wMDD/Ghoa/yYmJv8jIyP/Gxsb/x0dHf8hISH/IyMj/yQkJP8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8lJSX/JCQk/yMjI/8RERH/AwMD/yUlJf9vb2//r6+v/8HB + wf/FxcX/x8fH/8rKyv/MzMz/zs7O/9DQ0P/S0tL/09PTMf///wH///8B////Af///wHLy8vjyMjI/8bG + xv/CwsL/v7+//7u7u/+3t7f/s7Oz/66urv+qqqr/pqam/6Kiov+cnJz/lpaW/5GRkf+Li4v/hYWF/35+ + fv94eHj/cnJy/21tbf9paWn/X19f/1tbW/9CQkL/Nzc3/zk5Of9TU1P/ZmZm/2tra/9ubm7/e3t7/5OT + k/+Hh4f/LCws/x8fH/8wMDD/YWFh/4GBgf+cnJz/7e3t//r6+v++vr7/MTEx/xoaGv8mJib/JSUl/x4e + Hv8fHx//ISEh/yQkJP8kJCT/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8kJCT/JCQk/yQkJP8kJCT/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JSUl/yQk + JP8nJyf/FxcX/wMDA/8eHh7/e3t7/6Ghof+/v7//xMTE/8bGxv/IyMj/ysrK/83Nzf/Pz8//0dHR/9PT + 0//U1NQx////Af///wH///8B////AcrKyuPHx8f/xMTE/8DAwP+9vb3/ubm5/7W1tf+xsbH/rKys/6io + qP+ioqL/np6e/5iYmP+SkpL/jIyM/4aGhv+AgID/eHh4/3Nzc/9ubm7/ampq/2VlZf9fX1//Xl5e/1BQ + UP9JSUn/Nzc3/1BQUP9oaGj/bW1t/3h4eP+SkpL/oKCg/3R0dP8xMTH/Hx8f/yIiIv8zMzP/bGxs/+Xl + 5f/8/Pz/vLy8/0FBQf8ZGRn/JSUl/yQkJP8fHx//ICAg/yIiIv8kJCT/JCQk/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8lJSX/IyMj/xcXF/8DAwP/Hh4e/29vb/+kpKT/vb29/8LC + wv/ExMT/x8fH/8nJyf/Ly8v/zs7O/9DQ0P/S0tL/1NTU/9XV1TH///8B////Af///wH///8ByMjI48bG + xv/Dw8P/v7+//7y8vP+3t7f/s7Oz/6+vr/+qqqr/pqam/6CgoP+bm5v/lJSU/46Ojv+IiIj/goKC/3V1 + df9ubm7/b29v/2xsbP9nZ2f/YmJi/19fX/9hYWH/Y2Nj/1lZWf8yMjL/Q0ND/2hoaP92dnb/jIyM/5+f + n/+AgID/RkZG/0RERP84ODj/HR0d/yEhIf83Nzf/kJCQ/8XFxf9MTEz/GRkZ/yQkJP8lJSX/HR0d/x8f + H/8iIiL/JCQk/yQkJP8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8lJSX/JSUl/ycn + J/8XFxf/BAQE/xEREf9mZmb/np6e/7u7u//CwsL/xMTE/8bGxv/IyMj/y8vL/83Nzf/Pz8//0dHR/9PT + 0//V1dX/1tbWMf///wH///8B////Af///wHIyMjjxMTE/8HBwf+9vb3/urq6/7W1tf+xsbH/rKys/6en + p/+ioqL/m5ub/5aWlv+QkJD/ioqK/4ODg/90dHT/WFhY/09PT/9ZWVn/ZGRk/2RkZP9hYWH/YWFh/2Rk + ZP9nZ2f/W1tb/y4uLv88PDz/b29v/42Njf+hoaH/g4OD/0ZGRv9MTEz/dnZ2/3t7e/9BQUH/ISEh/w8P + D/8UFBT/QEBA/yEhIf8gICD/JiYm/x0dHf8fHx//IiIi/yQkJP8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yUlJf8uLi7/QUFB/y0tLf8hISH/aWlp/6SkpP+7u7v/wcHB/8PD + w//FxcX/x8fH/8rKyv/MzMz/zs7O/9DQ0P/S0tL/1NTU/9bW1v/X19cx////Af///wH///8B////AcbG + xuPExMT/wMDA/729vf+4uLj/s7Oz/6+vr/+pqan/pKSk/5+fn/+ZmZn/kpKS/4uLi/+FhYX/fHx8/2Fh + Yf9PT0//SEhI/0ZGRv9WVlb/YmJi/2BgYP9kZGT/ZmZm/2lpaf9aWlr/Kioq/0NDQ/+CgoL/oKCg/5GR + kf9KSkr/RkZG/29vb/+Ghob/e3t7/8DAwP95eXn/ExMT/xQUFP84ODj/ISEh/xwcHP8eHh7/Hh4e/yIi + Iv8kJCT/JSUl/yUlJf8lJSX/JSUl/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8lJSX/Kioq/0RE + RP9WVlb/e3t7/4KCgv+vr6//u7u7/8DAwP/CwsL/xMTE/8bGxv/IyMj/y8vL/83Nzf/Pz8//0dHR/9PT + 0//V1dX/19fX/9jY2DH///8B////Af///wH///8BxsbG48PDw/+/v7//u7u7/7e3t/+xsbH/rKys/6am + pv+hoaH/nJyc/5WVlf+Ojo7/hoaG/4CAgP92dnb/WVlZ/1FRUf9FRUX/QkJC/1JSUv9gYGD/YmJi/2dn + Z/9paWn/a2tr/1ZWVv8lJSX/RkZG/5WVlf+RkZH/UlJS/0ZGRv9qamr/hYWF/319ff/Kysr//f39/9/f + 3/9CQkL/HBwc/xsbG/8SEhL/FhYW/xwcHP8iIiL/JSUl/yUlJf8lJSX/JSUl/yQkJP8kJCT/JCQk/yQk + JP8jIyP/IyMj/yQkJP8nJyf/Kysr/zAwMP80NDT/NDQ0/zIyMv8uLi7/KSkp/yYmJv8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JSUl/yUlJf8qKir/PT09/1JSUv+IiIj/np6e/7u7u/+/v7//wcHB/8PD + w//FxcX/yMjI/8rKyv/MzMz/zs7O/9DQ0P/S0tL/1NTU/9bW1v/Y2Nj/2dnZMf///wH///8B////Af// + /wHFxcXjwsLC/729vf+5ubn/tbW1/6+vr/+qqqr/pKSk/5+fn/+ZmZn/kZGR/4qKiv+CgoL/e3t7/3Nz + c/9bW1v/U1NT/0FBQf8/Pz//UVFR/2BgYP9mZmb/aWlp/2tra/9tbW3/WFhY/yMjI/81NTX/f39//1ZW + Vv9BQUH/ZmZm/4aGhv96enr/u7u7//n5+f/s7Oz/gICA/xwcHP8fHx//Gxsb/xQUFP8aGhr/ISEh/yYm + Jv8lJSX/JCQk/yQkJP8kJCT/JCQk/yMjI/8jIyP/IyMj/ygoKP85OTn/WVlZ/3Fxcf+EhIT/lZWV/52d + nf+dnZ3/mJiY/46Ojv9+fn7/ampq/09PT/85OTn/JiYm/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yUlJf8jIyP/Hh4e/wsL + C/8UFBT/WVlZ/5aWlv+zs7P/vr6+/8DAwP/Dw8P/xcXF/8fHx//Jycn/y8vL/83Nzf/Pz8//0dHR/9PT + 0//V1dX/19fX/9nZ2f/a2tox////Af///wH///8B////AcTExOPBwcH/vb29/7i4uP+0tLT/rq6u/6io + qP+ioqL/nJyc/5aWlv+Ojo7/hoaG/319ff93d3f/b29v/1xcXP9UVFT/PT09/zs7O/9PT0//Y2Nj/2lp + af9sbGz/bm5u/3Jycv9kZGT/JCQk/yEhIf86Ojr/QEBA/11dXf+FhYX/fn5+/7CwsP/5+fn/9vb2/4eH + h/8kJCT/HBwc/yYmJv8hISH/HR0d/yEhIf8mJib/JiYm/yUlJf8kJCT/IyMj/yMjI/8jIyP/JiYm/zIy + Mv9fX1//jY2N/6ysrP++vr7/xcXF/8nJyf/Ly8v/y8vL/8vLy//Ly8v/y8vL/8nJyf/FxcX/vb29/6ur + q/99fX3/VFRU/zExMf8mJib/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yUlJf8lJSX/IyMj/yMjI/8LCwv/BgYG/0FBQf+Li4v/srKy/729vf/AwMD/wsLC/8TE + xP/Gxsb/yMjI/8vLy//Nzc3/zs7O/9DQ0P/S0tL/1dXV/9bW1v/Y2Nj/2tra/9ra2jH///8B////Af// + /wH///8BxMTE48DAwP+8vLz/t7e3/7Kysv+srKz/p6en/6Ghof+ampr/k5OT/4uLi/+Dg4P/enp6/3R0 + dP9tbW3/X19f/1VVVf86Ojr/ODg4/09PT/9lZWX/bGxs/25ubv9ycnL/goKC/4eHh/8yMjL/Hh4e/ysr + K/9OTk7/gICA/39/f/+qqqr/9vb2//Pz8/+ampr/Hh4e/xoaGv8lJSX/IiIi/x4eHv8iIiL/JiYm/yYm + Jv8lJSX/JCQk/yMjI/8jIyP/IyMj/zAwMP9nZ2f/o6Oj/8XFxf/Ly8v/y8vL/8vLy//Ly8v/y8vL/8vL + y//Ly8v/zMzM/8zMzP/MzMz/zc3N/83Nzf/Nzc3/zc3N/83Nzf/FxcX/m5ub/11dXf8uLi7/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yYmJv8mJib/JiYm/yYmJv8mJib/JSUl/yYmJv8jIyP/CwsL/wYG + Bv85OTn/kJCQ/7Kysv+9vb3/wMDA/8LCwv/ExMT/xsbG/8jIyP/Kysr/zMzM/87Ozv/Q0ND/0tLS/9TU + 1P/V1dX/19fX/9nZ2f/a2tr/29vbMf///wH///8B////Af///wHExMTjwMDA/7u7u/+2trb/sbGx/6ur + q/+mpqb/oKCg/5mZmf+SkpL/iYmJ/4GBgf95eXn/dHR0/25ubv9iYmL/VlZW/0JCQv88PDz/T09P/2dn + Z/9vb2//cXFx/319ff+Xl5f/oaGh/0tLS/8dHR3/IyMj/0BAQP9lZWX/nJyc//Dw8P/6+vr/rKys/zMz + M/8YGBj/JSUl/yEhIf8cHBz/ISEh/yYmJv8mJib/JSUl/yQkJP8jIyP/IyMj/yMjI/9AQED/jY2N/8DA + wP/MzMz/zMzM/8vLy//Ly8v/y8vL/8vLy//Ly8v/y8vL/8vLy//MzMz/zMzM/8zMzP/MzMz/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Ly8v/vLy8/4GBgf89PT3/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8mJib/JiYm/yUlJf8kJCT/Kysr/xISEv8CAgL/Ly8v/4WFhf+tra3/vLy8/7+/v//BwcH/w8PD/8bG + xv/Hx8f/ysrK/8vLy//Nzc3/z8/P/9HR0f/T09P/1dXV/9fX1//Y2Nj/2tra/9vb2//c3Nwx////Af// + /wH///8B////AcPDw+O/v7//u7u7/7W1tf+wsLD/qqqq/6Wlpf+enp7/l5eX/4yMjP+Hh4f/gYGB/3l5 + ef91dXX/b29v/2ZmZv9nZ2f/Z2dn/0lJSf9BQUH/ZWVl/3Jycv9/f3//lZWV/6Kiov91dXX/Ozs7/yws + LP8dHR3/JSUl/zg4OP+rq6v/7+/v/66urv8uLi7/GBgY/yUlJf8jIyP/HBwc/yAgIP8lJSX/JiYm/yUl + Jf8kJCT/IyMj/yMjI/8qKir/XV1d/7W1tf/Nzc3/zc3N/83Nzf/MzMz/zMzM/8vLy//Ly8v/y8vL/8vL + y//Ly8v/y8vL/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/Ly8v/ysrK/7Cw + sP9nZ2f/KSkp/yMjI/8jIyP/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/ycnJ/8PDw//AQEB/zIy + Mv+Hh4f/rKys/729vf+/v7//wcHB/8PDw//FxcX/x8fH/8nJyf/Ly8v/zMzM/8/Pz//Q0ND/0tLS/9TU + 1P/W1tb/19fX/9nZ2f/b29v/3Nzc/93d3TH///8B////Af///wH///8Bw8PD48DAwP+7u7v/tbW1/7Cw + sP+pqan/pKSk/52dnf+Li4v/bW1t/3Nzc/99fX3/e3t7/3h4eP9xcXH/aGho/2pqav9paWn/RUVF/zU1 + Nf9gYGD/e3t7/5OTk/+jo6P/fn5+/0VFRf9MTEz/ZGRk/zY2Nv8aGhr/HBwc/y4uLv9ycnL/Q0ND/xYW + Fv8iIiL/IyMj/xwcHP8fHx//IyMj/yUlJf8lJSX/JCQk/yQkJP8jIyP/KCgo/2lpaf+1tbX/zMzM/8zM + zP/Nzc3/zMzM/8zMzP/MzMz/zMzM/8vLy//Ly8v/y8vL/8vLy//Ly8v/zMzM/8zMzP/MzMz/zMzM/8zM + zP/MzMz/zMzM/8zMzP/Ly8v/y8vL/8vLy//Kysr/ysrK/7u7u/9mZmb/Kioq/yMjI/8jIyP/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yQkJP8pKSn/FxcX/wEBAf8dHR3/fX19/6ioqP+6urr/vr6+/8DAwP/Dw8P/xcXF/8bG + xv/Jycn/y8vL/8zMzP/Ozs7/0NDQ/9LS0v/T09P/1dXV/9fX1//Y2Nj/2tra/9vb2//d3d3/3d3dMf// + /wH///8B////Af///wHDw8Pjv7+//7q6uv+0tLT/r6+v/6mpqf+jo6P/lJSU/21tbf9aWlr/VVVV/19f + X/94eHj/eXl5/3Jycv9sbGz/bm5u/2xsbP9ERET/MzMz/2pqav+Pj4//oqKi/4aGhv9BQUH/SUlJ/3R0 + dP+BgYH/b29v/1BQUP8VFRX/DQ0N/zs7O/9DQ0P/HR0d/yQkJP8bGxv/HR0d/yIiIv8kJCT/JCQk/yQk + JP8kJCT/IyMj/yUlJf9kZGT/u7u7/8rKyv/Ly8v/y8vL/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zM + zP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/Ly8v/y8vL/8vLy//Kysr/ysrK/8rK + yv/Kysr/ycnJ/7W1tf9dXV3/JSUl/yMjI/8jIyP/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yQkJP8lJSX/MzMz/0tLS/9TU1P/SUlJ/4GB + gf+rq6v/urq6/76+vv/AwMD/wsLC/8TExP/Gxsb/yMjI/8rKyv/MzMz/zs7O/8/Pz//R0dH/09PT/9XV + 1f/W1tb/19fX/9nZ2f/a2tr/3Nzc/93d3f/e3t4x////Af///wH///8B////AcPDw+O/v7//urq6/7W1 + tf+vr6//qamp/6Ojo/+Hh4f/Y2Nj/1dXV/9NTU3/UlJS/3h4eP96enr/cXFx/3BwcP9xcXH/bm5u/z8/ + P/8xMTH/eXl5/6Ghof+Hh4f/SkpK/0ZGRv9ubm7/g4OD/4KCgv/R0dH/3d3d/2hoaP8SEhL/IyMj/x0d + Hf8UFBT/GBgY/xwcHP8gICD/IiIi/yQkJP8kJCT/JCQk/yQkJP8jIyP/Q0ND/6+vr//Kysr/ysrK/8vL + y//Ly8v/y8vL/8zMzP/MzMz/zMzM/8zMzP/Nzc3/zc3N/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zM + zP/MzMz/y8vL/8vLy//Ly8v/y8vL/8rKyv/Kysr/ysrK/8rKyv/Kysr/ycnJ/7Gxsf9DQ0P/IyMj/yMj + I/8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/y0tLf9ERET/U1NT/3Nzc/+Kior/rq6u/7u7u/+9vb3/v7+//8LCwv/ExMT/xsbG/8jI + yP/Kysr/y8vL/83Nzf/Pz8//0dHR/9LS0v/U1NT/1dXV/9fX1//Y2Nj/2tra/9vb2//d3d3/3t7e/9/f + 3zH///8B////Af///wH///8BxMTE48DAwP+7u7v/tra2/7CwsP+pqan/o6Oj/4WFhf9nZ2f/VVVV/0hI + SP9PT0//enp6/3l5ef9zc3P/c3Nz/3R0dP9ubm7/Ozs7/ywsLP95eXn/k5OT/01NTf9CQkL/bGxs/4eH + h/97e3v/ycnJ//v7+//d3d3/X19f/xcXF/8YGBj/EhIS/xYWFv8bGxv/ICAg/yIiIv8jIyP/JCQk/yQk + JP8kJCT/JCQk/zAwMP+Hh4f/yMjI/8vLy//Ly8v/y8vL/8vLy//Ly8v/zMzM/8zMzP/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zMzM/8zMzP/MzMz/zMzM/8zMzP/Ly8v/y8vL/8vLy//Ly8v/ysrK/8rK + yv/Kysr/ysrK/8rKyv/Kysr/ycnJ/4qKiv8uLi7/IyMj/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yUlJf8lJSX/JSUl/yUlJf8lJSX/JCQk/yMjI/8mJib/HR0d/x8fH/9FRUX/enp6/56e + nv+3t7f/vb29/7+/v//BwcH/w8PD/8XFxf/Hx8f/ycnJ/8vLy//Nzc3/zs7O/9DQ0P/S0tL/1NTU/9XV + 1f/W1tb/2NjY/9nZ2f/b29v/3Nzc/93d3f/f39//39/fMf///wH///8B////Af///wHExMTjwcHB/7y8 + vP+2trb/sbGx/6mpqf+jo6P/iIiI/2tra/9TU1P/RERE/0xMTP95eXn/d3d3/3V1df92dnb/d3d3/3Nz + c/8+Pj7/JCQk/0xMTP9RUVH/QUFB/2VlZf+Hh4f/eXl5/8fHx//+/v7/6Ojo/2RkZP8aGhr/Hh4e/yQk + JP8bGxv/HBwc/yEhIf8jIyP/IyMj/yQkJP8kJCT/JCQk/yQkJP8kJCT/XFxc/76+vv/MzMz/zMzM/8zM + zP/MzMz/zMzM/8zMzP/MzMz/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/8zM + zP/MzMz/zMzM/8vLy//Ly8v/y8vL/8vLy//Kysr/ysrK/8rKyv/Kysr/ysrK/8vLy//Ly8v/vLy8/1dX + V/8lJSX/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JSUl/yUlJf8lJSX/JSUl/yQk + JP8jIyP/IiIi/xkZGf8EBAT/ExMT/21tbf+goKD/uLi4/7y8vP++vr7/wcHB/8PDw//FxcX/x8fH/8nJ + yf/Kysr/zc3N/87Ozv/Q0ND/0dHR/9PT0//V1dX/1tbW/9jY2P/Z2dn/2tra/9vb2//d3d3/3t7e/9/f + 3//g4OAx////Af///wH///8B////AcTExOPBwcH/vb29/7i4uP+ysrL/q6ur/6SkpP+Hh4f/bm5u/1BQ + UP9CQkL/TU1N/3t7e/93d3f/eHh4/3h4eP97e3v/g4OD/01NTf8iIiL/MDAw/0RERP9gYGD/hYWF/3V1 + df+vr6//+Pj4//Hx8f+IiIj/Hh4e/xwcHP8lJSX/Hx8f/x0dHf8gICD/IiIi/yMjI/8kJCT/JCQk/yQk + JP8kJCT/JCQk/yUlJf+SkpL/zMzM/83Nzf/Nzc3/zc3N/8zMzP/MzMz/zMzM/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zs7O/87Ozv/Ozs7/zc3N/83Nzf/Nzc3/zc3N/8zMzP/MzMz/zMzM/8vLy//Ly8v/y8vL/8vL + y//Ly8v/y8vL/8vLy//Ly8v/y8vL/8zMzP/Jycn/hoaG/ywsLP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8lJSX/JSUl/yUlJf8lJSX/JCQk/yMjI/8bGxv/BAQE/wcHB/9RUVH/mZmZ/7S0 + tP+8vLz/vr6+/8DAwP/Dw8P/xcXF/8fHx//IyMj/ysrK/8zMzP/Ozs7/0NDQ/9HR0f/T09P/1NTU/9bW + 1v/X19f/2NjY/9ra2v/b29v/3d3d/97e3v/f39//4ODg/+Hh4TH///8B////Af///wH///8BxMTE48LC + wv++vr7/uLi4/7Ozs/+tra3/pqam/4iIiP9xcXH/T09P/0JCQv9LS0v/e3t7/3p6ev96enr/fX19/4iI + iP+enp7/eXl5/yUlJf8sLCz/Wlpa/3x8fP92dnb/srKy//j4+P/w8PD/ioqK/yIiIv8bGxv/JSUl/x8f + H/8cHBz/ICAg/yIiIv8jIyP/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/MjIy/7q6uv/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/87Ozv/Ozs7/zs7O/87Ozv/Ozs7/zc3N/83N + zf/Nzc3/zc3N/8zMzP/MzMz/y8vL/8vLy//Ly8v/y8vL/8vLy//Ly8v/y8vL/8zMzP/MzMz/zMzM/83N + zf+urq7/OTk5/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JSUl/yUlJf8lJSX/JSUl/yQk + JP8iIiL/Gxsb/wYGBv8ODg7/UVFR/5mZmf+1tbX/u7u7/76+vv/AwMD/wsLC/8TExP/Hx8f/ycnJ/8rK + yv/MzMz/zs7O/9DQ0P/R0dH/09PT/9TU1P/V1dX/2NjY/9nZ2f/a2tr/29vb/9zc3P/e3t7/39/f/+Dg + 4P/h4eH/4eHhMf///wH///8B////Af///wHExMTjwsLC/76+vv+6urr/tbW1/66urv+oqKj/ioqK/3d3 + d/9oaGj/Xl5e/05OTv94eHj/fX19/35+fv+IiIj/mpqa/5+fn/9kZGT/KCgo/yAgIP9KSkr/aWlp/5WV + lf/29vb/+vr6/56env8oKCj/GRkZ/yUlJf8hISH/HBwc/yAgIP8iIiL/IyMj/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP9LS0v/ysrK/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83N + zf/Ozs7/zs7O/87Ozv/Ozs7/zs7O/87Ozv/Ozs7/zs7O/83Nzf/Nzc3/zMzM/8zMzP/MzMz/zMzM/8zM + zP/Ly8v/y8vL/8vLy//MzMz/zMzM/83Nzf/Nzc3/zc3N/8HBwf9OTk7/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8lJSX/JSUl/yUlJf8kJCT/JSUl/x8fH/8HBwf/BgYG/05OTv+Pj4//r6+v/7u7 + u/+9vb3/wMDA/8LCwv/ExMT/xsbG/8jIyP/Kysr/zMzM/87Ozv/Pz8//0dHR/9PT0//U1NT/1dXV/9fX + 1//Y2Nj/2tra/9vb2//d3d3/3d3d/97e3v/g4OD/4eHh/+Li4v/i4uIx////Af///wH///8B////AcTE + xOPCwsL/v7+//7u7u/+3t7f/sbGx/6qqqv+Kior/e3t7/3x8fP9sbGz/Pj4+/1lZWf9+fn7/iIiI/5ub + m/+jo6P/bm5u/z8/P/9GRkb/MTEx/yYmJv9JSUn/YGBg/7Gxsf+qqqr/Ly8v/xgYGP8kJCT/IiIi/x0d + Hf8fHx//IiIi/yMjI/8jIyP/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/2BgYP/MzMz/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Ozs7/zs7O/87Ozv/Ozs7/zs7O/87O + zv/Ozs7/zc3N/83Nzf/Nzc3/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zc3N/83N + zf/Nzc3/ysrK/11dXf8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yUlJf8lJSX/JCQk/yQk + JP8fHx//CQkJ/wcHB/9FRUX/kJCQ/62trf+6urr/vLy8/7+/v//BwcH/xMTE/8bGxv/IyMj/ysrK/8zM + zP/Ozs7/0NDQ/9HR0f/T09P/1NTU/9XV1f/X19f/2NjY/9ra2v/b29v/3Nzc/93d3f/e3t7/4ODg/+Hh + 4f/i4uL/4+Pj/+Pj4zH///8B////Af///wH///8BxcXF48LCwv+/v7//vLy8/7i4uP+zs7P/qqqq/4iI + iP9+fn7/fn5+/2lpaf83Nzf/VlZW/4aGhv+YmJj/oaGh/3x8fP8+Pj7/TU1N/3h4eP9oaGj/NjY2/xkZ + Gf8TExP/IyMj/z4+Pv8eHh7/IiIi/yQkJP8cHBz/Hh4e/yIiIv8jIyP/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/aGho/8zMzP/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Ozs7/zs7O/87Ozv/Ozs7/zs7O/83Nzf/Nzc3/zc3N/83Nzf/MzMz/zMzM/8zM + zP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/Nzc3/zc3N/83Nzf/Nzc3/a2tr/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8lJSX/JSUl/yQkJP8mJib/NjY2/y0tLf8aGhr/Q0ND/5GRkf+urq7/ubm5/7y8 + vP+/v7//wcHB/8PDw//FxcX/yMjI/8rKyv/MzMz/zc3N/8/Pz//R0dH/09PT/9TU1P/V1dX/19fX/9jY + 2P/Z2dn/29vb/9zc3P/d3d3/3t7e/9/f3//g4OD/4eHh/+Li4v/j4+P/5OTkMf///wH///8B////Af// + /wHFxcXjwsLC/7+/v/+8vLz/uLi4/7S0tP+jo6P/hISE/4CAgP+AgID/aWlp/zY2Nv9cXFz/l5eX/6Oj + o/+AgID/RUVF/0lJSf9ycnL/g4OD/4ODg/+1tbX/S0tL/w4ODv8iIiL/Ozs7/x8fH/8eHh7/Hh4e/x4e + Hv8jIyP/JSUl/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP9hYWH/zMzM/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zM + zP/MzMz/zc3N/8vLy/9qamr/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yUlJf8kJCT/JCQk/zQ0 + NP9MTEz/X19f/2pqav+SkpL/s7Oz/7m5uf+7u7v/vr6+/8DAwP/Dw8P/xcXF/8fHx//Kysr/zMzM/83N + zf/Pz8//0dHR/9PT0//U1NT/1dXV/9fX1//Y2Nj/2dnZ/9ra2v/c3Nz/3d3d/97e3v/f39//4ODg/+Hh + 4f/i4uL/4+Pj/+Tk5P/k5OQx////Af///wH///8B////AcbGxuPDw8P/wMDA/7y8vP+5ubn/sbGx/5KS + kv+CgoL/goKC/4GBgf9lZWX/NDQ0/1xcXP+ioqL/iIiI/0VFRf9ERET/dHR0/4SEhP+BgYH/3t7e//z8 + /P+wsLD/Li4u/ycnJ/8bGxv/FBQU/xoaGv8gICD/JSUl/yYmJv8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/1FRUf/Ly8v/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zMzM/8zM + zP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/x8fH/1xcXP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yMjI/8jIyP/LS0t/0RERP9oaGj/hoaG/6+vr/+5ubn/vLy8/76+ + vv/AwMD/wsLC/8TExP/Hx8f/ycnJ/8vLy//Nzc3/z8/P/9DQ0P/S0tL/1NTU/9XV1f/X19f/2NjY/9nZ + 2f/a2tr/3Nzc/93d3f/e3t7/39/f/+Dg4P/h4eH/4uLi/+Pj4//k5OT/5eXl/+Xl5TH///8B////Af// + /wH///8BxsbG48TExP/BwcH/vb29/7q6uv+np6f/h4eH/4ODg/+Dg4P/g4OD/2VlZf8zMzP/Q0ND/4CA + gP9MTEz/QkJC/2hoaP+Hh4f/enp6/9DQ0P/9/f3/4ODg/1VVVf8ZGRn/Hx8f/xkZGf8WFhb/Hh4e/yUl + Jf8mJib/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/Ojo6/8HB + wf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zM + zP/MzMz/zMzM/8zMzP+8vLz/R0dH/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8iIiL/IiIi/xAQ + EP8GBgb/NjY2/4GBgf+hoaH/ubm5/7u7u/++vr7/wMDA/8LCwv/ExMT/xsbG/8nJyf/Ly8v/zc3N/8/P + z//Q0ND/0tLS/9TU1P/V1dX/19fX/9jY2P/Z2dn/2tra/9zc3P/d3d3/3t7e/9/f3//g4OD/4eHh/+Li + 4v/j4+P/5OTk/+Xl5f/l5eX/5ubmMf///wH///8B////Af///wHHx8fjxMTE/8HBwf++vr7/u7u7/5iY + mP+EhIT/hYWF/4WFhf+IiIj/dnZ2/zc3N/8sLCz/RUVF/0NDQ/9paWn/hYWF/319ff/IyMj/+/v7/+Dg + 4P9lZWX/FhYW/x0dHf8kJCT/Hh4e/x8fH/8jIyP/JSUl/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8mJib/n5+f/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/8zM + zP/MzMz/zMzM/8zMzP/MzMz/zMzM/8vLy//Ly8v/y8vL/8vLy//Ly8v/ysrK/5ycnP8yMjL/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/IiIi/yEhIf8TExP/AwMD/yoqKv+BgYH/qamp/7i4uP+8vLz/vr6+/8DA + wP/CwsL/xMTE/8fHx//Jycn/y8vL/83Nzf/Pz8//0dHR/9PT0//U1NT/1dXV/9fX1//Y2Nj/2dnZ/9vb + 2//c3Nz/3d3d/97e3v/f39//4ODg/+Hh4f/i4uL/4+Pj/+Tk5P/l5eX/5eXl/+bm5v/m5uYx////Af// + /wH///8B////AcjIyOPFxcX/wsLC/7+/v/+8vLz/k5OT/4WFhf+Ghob/iIiI/5KSkv+Ojo7/QkJC/yoq + Kv9eXl7/cHBw/4ODg/93d3f/vr6+//n5+f/n5+f/dHR0/xwcHP8cHBz/JSUl/x4eHv8fHx//JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP9wcHD/xsbG/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/8zMzP/MzMz/zMzM/8zMzP/Ly8v/y8vL/8vL + y//Ly8v/y8vL/8vLy//FxcX/eHh4/ykpKf8kJCT/JCQk/yQkJP8kJCT/JCQk/yMjI/8hISH/ExMT/wMD + A/8bGxv/dHR0/6Wlpf+4uLj/vLy8/76+vv/AwMD/wsLC/8TExP/Gxsb/ycnJ/8vLy//Nzc3/z8/P/9DQ + 0P/S0tL/09PT/9XV1f/X19f/2NjY/9nZ2f/a2tr/3Nzc/93d3f/e3t7/39/f/+Dg4P/h4eH/4uLi/+Pj + 4//j4+P/5OTk/+Xl5f/m5ub/5+fn/+fn5zH///8B////Af///wH///8ByMjI48bGxv/ExMT/wcHB/729 + vf+SkpL/hoaG/4iIiP+RkZH/oKCg/5eXl/9HR0f/JSUl/1JSUv+Li4v/gICA/66urv/6+vr/8fHx/3x8 + fP8eHh7/Gxsb/yUlJf8fHx//Hh4e/yIiIv8kJCT/JCQk/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/z4+Pv+np6f/zMzM/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zMzM/8zMzP/MzMz/zMzM/8vLy//Ly8v/y8vL/8vLy//Ly8v/y8vL/7CwsP9JSUn/JCQk/yQk + JP8kJCT/JCQk/yQkJP8jIyP/IyMj/xgYGP8EBAT/ExMT/2dnZ/+ampr/tra2/7y8vP++vr7/wMDA/8LC + wv/ExMT/xsbG/8nJyf/Ly8v/zMzM/8/Pz//Q0ND/0tLS/9PT0//U1NT/1tbW/9fX1//Z2dn/2tra/9zc + 3P/d3d3/3t7e/9/f3//g4OD/4eHh/+Li4v/j4+P/4+Pj/+Tk5P/l5eX/5ubm/+fn5//n5+f/5+fnMf// + /wH///8B////Af///wHJycnjx8fH/8XFxf/CwsL/vr6+/5KSkv+JiYn/kZGR/6CgoP+fn5//Y2Nj/zo6 + Ov8sLCz/Kioq/21tbf+QkJD/w8PD/+zs7P+RkZH/Hh4e/xoaGv8kJCT/ICAg/x0dHf8gICD/IyMj/yMj + I/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/KCgo/2dnZ//CwsL/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zMzM/8zMzP/MzMz/zMzM/8vL + y//Ly8v/y8vL/8vLy//Gxsb/ZmZm/ycnJ/8kJCT/JCQk/yQkJP8kJCT/IyMj/yIiIv8XFxf/BAQE/xkZ + Gf9oaGj/np6e/7S0tP+8vLz/vr6+/8DAwP/CwsL/xMTE/8fHx//IyMj/y8vL/8zMzP/Ozs7/0NDQ/9LS + 0v/T09P/1NTU/9bW1v/X19f/2dnZ/9ra2v/c3Nz/3d3d/97e3v/f39//4ODg/+Hh4f/i4uL/4+Pj/+Pj + 4//k5OT/5eXl/+bm5v/n5+f/5+fn/+jo6P/o6Ogx////Af///wH///8B////AcrKyuPIyMj/xsbG/8PD + w/+/v7//kpKS/5CQkP+dnZ3/o6Oj/3R0dP88PDz/Tk5O/2FhYf8vLy//LCws/z4+Pv8+Pj7/cHBw/zAw + MP8ZGRn/IyMj/yEhIf8dHR3/ICAg/yIiIv8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMj + I/8jIyP/IyMj/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/Li4u/5OTk//MzMz/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zMzM/8zMzP/MzMz/y8vL/8vLy//Ly8v/ycnJ/56env8xMTH/JCQk/yQk + JP8kJCT/IyMj/yMjI/8mJib/ISEh/wcHB/8KCgr/YWFh/5mZmf+2trb/vLy8/76+vv/AwMD/wsLC/8TE + xP/Gxsb/yMjI/8rKyv/MzMz/zs7O/9DQ0P/S0tL/09PT/9TU1P/W1tb/19fX/9nZ2f/a2tr/29vb/9zc + 3P/e3t7/39/f/+Dg4P/h4eH/4eHh/+Pj4//j4+P/5OTk/+Xl5f/l5eX/5ubm/+fn5//o6Oj/6Ojo/+np + 6TH///8B////Af///wH///8By8vL48nJyf/Hx8f/xcXF/7+/v/+YmJj/np6e/6Ojo/9ycnL/PT09/1JS + Uv96enr/fX19/3p6ev9RUVH/ERER/xISEv9MTEz/Pz8//yEhIf8iIiL/Hx8f/x8fH/8iIiL/IyMj/yMj + I/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/Nzc3/5WVlf/IyMj/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/MzMz/zMzM/8zM + zP/MzMz/y8vL/8rKyv+dnZ3/QEBA/yQkJP8kJCT/JCQk/yQkJP8jIyP/KSkp/0FBQf9RUVH/U1NT/2lp + af+qqqr/tra2/729vf+/v7//wcHB/8PDw//ExMT/x8fH/8jIyP/Kysr/zMzM/87Ozv/Q0ND/0tLS/9PT + 0//U1NT/1tbW/9fX1//Z2dn/2tra/9vb2//d3d3/3d3d/9/f3//g4OD/4eHh/+Li4v/i4uL/5OTk/+Tk + 5P/l5eX/5ubm/+bm5v/n5+f/6Ojo/+np6f/p6en/6enpMf///wH///8B////Af///wHMzMzjysrK/8jI + yP/Gxsb/wcHB/6Ojo/+mpqb/fX19/0FBQf9HR0f/dnZ2/4GBgf+Ghob/4eHh/9PT0/9MTEz/KSkp/zMz + M/8gICD/Ghoa/xwcHP8gICD/ISEh/yIiIv8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMj + I/8jIyP/IyMj/yMjI/8jIyP/IyMj/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8lJSX/QEBA/5aW + lv/Ly8v/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/MzMz/zMzM/8zMzP/Kysr/qamp/0lJSf8mJib/JCQk/yQk + JP8kJCT/IyMj/yQkJP8zMzP/SkpK/1tbW/94eHj/mJiY/7q6uv+8vLz/v7+//8HBwf/Dw8P/xcXF/8bG + xv/IyMj/ysrK/8zMzP/Ozs7/0NDQ/9LS0v/T09P/1NTU/9bW1v/X19f/2dnZ/9ra2v/c3Nz/3Nzc/93d + 3f/e3t7/39/f/+Dg4P/h4eH/4uLi/+Pj4//k5OT/5eXl/+bm5v/m5ub/5+fn/+jo6P/o6Oj/6enp/+rq + 6v/q6uox////Af///wH///8B////Ac3NzePLy8v/ycnJ/8fHx//ExMT/rKys/4SEhP9ERET/R0dH/29v + b/+CgoL/hYWF/+Li4v/7+/v/wMDA/zY2Nv8eHh7/HR0d/xISEv8ZGRn/Hh4e/yEhIf8iIiL/IyMj/yMj + I/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMj + I/8jIyP/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/MzMz/4KCgv+6urr/zMzM/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/8zM + zP/MzMz/v7+//4qKiv9AQED/JSUl/yQkJP8kJCT/JCQk/yMjI/8iIiL/ICAg/xISEv8nJyf/YWFh/42N + jf+ysrL/vb29/7+/v//BwcH/w8PD/8XFxf/Hx8f/ycnJ/8rKyv/MzMz/zs7O/9DQ0P/S0tL/09PT/9TU + 1P/W1tb/19fX/9nZ2f/a2tr/29vb/93d3f/d3d3/3t7e/9/f3//g4OD/4eHh/+Li4v/j4+P/5OTk/+Xl + 5f/m5ub/5ubm/+fn5//o6Oj/6Ojo/+np6f/q6ur/6urq/+vr6zH///8B////Af///wH///8Bz8/P483N + zf/Kysr/yMjI/8bGxv+jo6P/SkpK/0NDQ/9sbGz/goKC/35+fv/R0dH/+/v7/8zMzP9KSkr/ExMT/x0d + Hf8hISH/GRkZ/x4eHv8hISH/IiIi/yMjI/8jIyP/IyMj/yMjI/8iIiL/IiIi/yQiIf8iIiL/IiIi/yMj + I/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8kJCT/JCQk/yQk + JP8kJCT/LCws/1dXV/+jo6P/xsbG/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/x8fH/6mpqf9kZGT/Ly8v/yQkJP8kJCT/JCQk/yQk + JP8jIyP/IiIi/x4eHv8LCwv/BwcH/0BAQP+QkJD/sbGx/729vf/AwMD/wcHB/8PDw//FxcX/x8fH/8nJ + yf/Ly8v/zMzM/87Ozv/Q0ND/0tLS/9PT0//U1NT/1tbW/9fX1//Z2dn/2tra/9vb2//c3Nz/3d3d/97e + 3v/f39//4ODg/+Hh4f/i4uL/4+Pj/+Tk5P/k5OT/5ubm/+bm5v/n5+f/6Ojo/+jo6P/p6en/6urq/+rq + 6v/r6+v/6+vrMf///wH///8B////Af///wHPz8/jzs7O/8zMzP/Kysr/yMjI/7e3t/9vb2//aGho/4OD + g/94eHj/y8vL//v7+//T09P/VFRU/xcXF/8dHR3/IyMj/xwcHP8dHR3/ISEh/yMjI/8jIyP/IyMj/yIi + Iv8iIiL/IiIi/yIiIv86Ih7/ciQW/0AhHP8jISH/IiIi/yIiIv8jIyP/IyMj/yMjI/8jIyP/IyMj/yMj + I/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yQkJP8kJCT/JiYm/zo6Ov9oaGj/o6Oj/8HB + wf/Jycn/zMzM/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/8zMzP/Jycn/xMTE/62t + rf9wcHD/Pz8//ycnJ/8kJCT/JCQk/yQkJP8kJCT/IyMj/yIiIv8gICD/DAwM/wMDA/89PT3/h4eH/7Cw + sP+9vb3/v7+//8LCwv/ExMT/xsbG/8fHx//Jycn/y8vL/83Nzf/Pz8//0NDQ/9LS0v/T09P/1NTU/9bW + 1v/X19f/2dnZ/9ra2v/b29v/3Nzc/93d3f/e3t7/39/f/+Dg4P/h4eH/4uLi/+Li4v/j4+P/5OTk/+Xl + 5f/m5ub/5+fn/+jo6P/o6Oj/6enp/+rq6v/q6ur/6+vr/+vr6//s7Owx////Af///wH///8B////AdHR + 0ePPz8//zc3N/8vLy//Jycn/x8fH/7W1tf+SkpL/e3t7/76+vv/+/v7/5OTk/1paWv8UFBT/HBwc/yQk + JP8bGxv/HBwc/yEhIf8kJCT/IyMj/yMjI/8iIiL/IiIi/yIiIv8iIiL/NSIe/5EnFP/CLBH/ZCUa/yYi + If8iIiL/IiIi/yIiIv8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMj + I/8jIyP/IyMj/yQkJP8kJCT/JCQk/yQkJP8tLS3/TU1N/3Z2dv+goKD/rq6u/7q6uv/BwcH/yMjI/8nJ + yf/Hx8f/xcXF/729vf+urq7/m5ub/3p6ev9VVVX/MzMz/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yMj + I/8iIiL/ICAg/w4ODv8CAgL/Kioq/42Njf+tra3/vb29/8DAwP/CwsL/xMTE/8bGxv/IyMj/ysrK/8vL + y//Nzc3/z8/P/9DQ0P/S0tL/09PT/9TU1P/W1tb/19fX/9nZ2f/a2tr/3Nzc/93d3f/d3d3/3t7e/9/f + 3//g4OD/4eHh/+Li4v/i4uL/4+Pj/+Tk5P/l5eX/5ubm/+fn5//n5+f/6Ojo/+np6f/p6en/6urq/+vr + 6//r6+v/7Ozs/+zs7DH///8B////Af///wH///8B0tLS49DQ0P/Ozs7/zMzM/8vLy//Jycn/xsbG/7Ky + sv+xsbH/9PT0/+np6f98fHz/GRkZ/xkZGf8jIyP/Hx8f/xwcHP8hISH/JSUl/yQkJP8jIyP/IiIi/yIi + Iv8iIiL/IiIi/ykhIP9/JRX/xCwR/4UoGP8qIiH/IiIi/yIiIv8iIiL/IiIi/yMjI/8jIyP/IyMj/yMj + I/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8kJCT/JCQk/yQk + JP8kJCT/KCgo/zY2Nv9AQED/TExM/1lZWf9qamr/bW1t/2hoaP9iYmL/UVFR/0FBQf8zMzP/KCgo/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/IyMj/yEhIf8QEBD/AgIC/yAgIP90dHT/qqqq/7y8 + vP/AwMD/wsLC/8TExP/Gxsb/yMjI/8rKyv/MzMz/zc3N/8/Pz//R0dH/0tLS/9PT0//U1NT/1tbW/9fX + 1//Z2dn/2tra/9zc3P/c3Nz/3d3d/97e3v/f39//4ODg/+Hh4f/i4uL/4uLi/+Pj4//k5OT/5eXl/+bm + 5v/m5ub/5+fn/+jo6P/p6en/6enp/+rq6v/r6+v/6+vr/+zs7P/s7Oz/7OzsMf///wH///8B////Af// + /wHU1NTj0tLS/9DQ0P/Ozs7/zMzM/8rKyv/IyMj/wsLC/5GRkf+kpKT/cHBw/xsbG/8ZGRn/IiIi/x8f + H/8eHh7/IyMj/yYmJv8lJSX/IyMj/yIiIv8iIiL/IiIi/yIiIv8sIR//eSYX/8UtEf+CKBj/LiIg/yIi + Iv8iIiL/IiIi/yIiIv8iIiL/IiIi/yQiIv8jIyP/IyMj/yMjI/8jIiL/LCIh/0sjHP9vJRj/NSIf/yMj + I/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/IyMj/yQk + JP8nJyf/ERER/wICAv8lJSX/fX19/6ampv++vr7/wcHB/8PDw//ExMT/xsbG/8jIyP/Kysr/zMzM/83N + zf/Pz8//0dHR/9PT0//U1NT/1dXV/9bW1v/X19f/2dnZ/9ra2v/b29v/3d3d/93d3f/e3t7/39/f/+Dg + 4P/h4eH/4uLi/+Pj4//j4+P/5OTk/+Xl5f/m5ub/5+fn/+fn5//o6Oj/6enp/+np6f/q6ur/6urq/+vr + 6//r6+v/7Ozs/+3t7f/t7e0x////Af///wH///8B////AdXV1ePT09P/0dHR/8/Pz//Nzc3/zMzM/8rK + yv/BwcH/aGho/zs7O/9DQ0P/ISEh/yIiIv8eHh7/HR0d/yIiIv8mJib/JSUl/yMjI/8iIiL/IiIi/yIi + Iv8hISH/JCEh/3QlF//DLBD/tSsS/z4iHf8iISH/IiIi/yIiIv8iIiL/IiEh/yohH/9JIhz/YiIX/zch + Hf8kIiL/JiIh/0ciG/9+Jhb/jCgW/7csE/9GJB7/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMj + I/8jIyP/IyMj/yMjI/8kJCT/JCQk/yQkJP8kJCT/IyMj/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8jIyP/Li4u/z4+Pv8sLCz/Kysr/35+fv+qqqr/vLy8/8HB + wf/Dw8P/xcXF/8bGxv/IyMj/ysrK/8zMzP/Nzc3/z8/P/9HR0f/T09P/1NTU/9XV1f/X19f/2NjY/9nZ + 2f/a2tr/3Nzc/9zc3P/d3d3/3t7e/9/f3//g4OD/4eHh/+Li4v/i4uL/4+Pj/+Tk5P/l5eX/5ubm/+bm + 5v/n5+f/6Ojo/+jo6P/p6en/6urq/+rq6v/r6+v/7Ozs/+zs7P/t7e3/7e3t/+7u7jH///8B////Af// + /wH///8B1dXV49TU1P/T09P/0dHR/8/Pz//Nzc3/y8vL/8LCwv9vb2//U1NT/0dHR/8tLS3/JiYm/x4e + Hv8iIiL/JSUl/yUlJf8jIyP/IyMj/yIiIv8hISH/ISEh/yYgIP9fIxj/xSwR/7QsE/+7KxL/lycT/1Ui + GP80IR7/OSEc/0ohGv9tIxb/nygT/7wrEv+6LBL/hiYV/1MiGf98Jhb/kSgV/2QmG/9YJhz/nisW/ywj + If8jIiL/MyIf/z8iHf8vIiD/IyIi/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMj + I/8jIyP/IyMj/yMjI/8jIyP/IyMj/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8jIyP/IyMj/yYm + Jv9DQ0P/UVFR/2xsbP9/f3//s7Oz/7+/v//BwcH/xMTE/8XFxf/Hx8f/ycnJ/8rKyv/MzMz/zs7O/9DQ + 0P/R0dH/09PT/9TU1P/V1dX/19fX/9jY2P/Z2dn/2tra/9vb2//c3Nz/3d3d/97e3v/f39//4ODg/+Hh + 4f/i4uL/4+Pj/+Pj4//k5OT/5eXl/+bm5v/n5+f/5+fn/+jo6P/o6Oj/6enp/+rq6v/q6ur/6+vr/+vr + 6//s7Oz/7Ozs/+3t7f/u7u7/7u7uMf///wH///8B////Af///wHX19fj1dXV/9TU1P/S0tL/0NDQ/8/P + z//Nzc3/xcXF/35+fv9PT0//MDAw/ywsLP8mJib/ISEh/yQkJP8lJSX/IyMj/yMjI/8iIiL/IiIi/yEh + If8jICD/YiMZ/7srEf+fKhX/QSMd/1QkHP+eKhX/vCoQ/64pEf+sKBH/tioR/7ErE/+ZKhb/dCca/1Ml + HP98JRb/mCgU/3EnGv85JCD/JiMi/2smGv95KBn/IyMi/zQjIP+PJxT/hicW/3AkFv84Ix//IyIi/yMj + Iv8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yMjI/8jIyP/Hh4e/zIyMv9PT0//e3t7/5ycnP+9vb3/w8PD/8TE + xP/Gxsb/yMjI/8nJyf/Ly8v/zc3N/87Ozv/Q0ND/0dHR/9PT0//U1NT/1dXV/9fX1//Y2Nj/2dnZ/9ra + 2v/c3Nz/3Nzc/93d3f/e3t7/39/f/+Dg4P/h4eH/4uLi/+Pj4//k5OT/5OTk/+Xl5f/m5ub/5+fn/+fn + 5//o6Oj/6Ojo/+np6f/q6ur/6urq/+vr6//r6+v/7Ozs/+3t7f/t7e3/7e3t/+7u7v/u7u4x////Af// + /wH///8B////AdjY2OPX19f/1dXV/9PT0//S0tL/0NDQ/8/Pz//IyMj/gYGB/zc3N/8sLCz/KCgo/yEh + If8hISH/IyMj/yQkJP8jIyP/IiIi/yIiIv8hISH/ISEh/1EjG/+7KxH/tisS/0QjHf8iISD/IiEg/zUi + Hv9rJhn/tysS/7YqEf9eJBr/PiMe/y8iIP8lIiH/JCIh/0wkHf9DJB7/KCMi/yIiIv8qIiH/hSgX/1Ym + Hf8nIiH/QyQe/5YpFf9IIxz/TyUd/4gnFv9aJBn/JSIi/yMiIv8jIiL/IyMj/yMjI/8jIyP/IyMj/yMj + I/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/JCQk/yQkJP8kJCT/JCQk/yMjI/8jIyP/IyMj/xoa + Gv8GBgb/FxcX/2RkZP+enp7/u7u7/8PDw//FxcX/x8fH/8jIyP/Kysr/zMzM/87Ozv/Pz8//0NDQ/9LS + 0v/T09P/1dXV/9bW1v/X19f/2NjY/9ra2v/a2tr/3Nzc/9zc3P/d3d3/3t7e/9/f3//g4OD/4eHh/+Li + 4v/j4+P/5OTk/+Tk5P/l5eX/5ubm/+bm5v/n5+f/6Ojo/+jo6P/p6en/6enp/+rq6v/r6+v/6+vr/+zs + 7P/s7Oz/7e3t/+3t7f/u7u7/7u7u/+7u7jH///8B////Af///wH///8B2tra49jY2P/W1tb/1NTU/9PT + 0//S0tL/0NDQ/8XFxf9kZGT/LS0t/ygoKP8iIiL/IiIi/yMjI/8kJCT/IyMj/yMjI/8iIiL/IiIi/yEh + If8oISD/gCcX/8ctEf+gKBP/QSEb/yYgH/8gICD/ICAg/yAgH/9MIxz/tisS/34mFv8mISD/ISEh/yYh + IP83IR3/RSIb/0MiHP8zIR7/IyEh/0IkHv+ZKRX/OyMf/1ckG/9zJRf/WSUc/4MmFf9uJBf/pSoU/1Yl + HP9EIx3/SyMc/zMiH/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMj + I/8kJCT/JCQk/yQkJP8kJCT/IyMj/yIiIv8ZGRn/BQUF/wwMDP9bW1v/oaGh/7+/v//FxcX/xsbG/8jI + yP/Jycn/y8vL/8zMzP/Ozs7/0NDQ/9HR0f/T09P/1NTU/9XV1f/X19f/2NjY/9nZ2f/a2tr/29vb/9zc + 3P/d3d3/3t7e/9/f3//g4OD/4ODg/+Hh4f/i4uL/4+Pj/+Tk5P/k5OT/5eXl/+bm5v/n5+f/5+fn/+jo + 6P/o6Oj/6enp/+rq6v/q6ur/6+vr/+vr6//s7Oz/7e3t/+3t7f/u7u7/7u7u/+7u7v/v7+//7+/vMf// + /wH///8B////Af///wHa2trj2dnZ/9fX1//W1tb/1NTU/9PT0//S0tL/w8PD/1dXV/8sLCz/IyMj/yEh + If8jIyP/JCQk/yQkJP8jIyP/IyMj/yIiIv8iIiL/IiIi/yEhIf8zIh//aiYa/64qE/+uKRH/bSMW/y0f + Hf8gICD/ICAg/zshHf+tKhL/oioU/y0hH/8rIB7/bCMW/6QpEv+0KhH/rykR/5onEv9aIhj/WiQa/3cn + Gf8pIiH/SSQd/40nFP9YIhn/fiYW/6YqFP9dJRv/WSQa/5goFf+JKBb/gCYW/zUiHv8kIiL/IyMj/yMj + I/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yQkJP8kJCT/JCQk/yMjI/8iIiL/HBwc/wcH + B/8GBgb/SkpK/5ycnP+9vb3/xcXF/8fHx//Jycn/ysrK/8zMzP/Nzc3/zs7O/9DQ0P/S0tL/09PT/9XV + 1f/W1tb/19fX/9nZ2f/Z2dn/2tra/9vb2//d3d3/3d3d/97e3v/f39//4ODg/+Dg4P/h4eH/4uLi/+Pj + 4//k5OT/5OTk/+Xl5f/m5ub/5ubm/+fn5//o6Oj/6Ojo/+np6f/p6en/6urq/+vr6//r6+v/7Ozs/+zs + 7P/t7e3/7e3t/+7u7v/u7u7/7+/v/+/v7//w8PAx////Af///wH///8B////Advb2+Pa2tr/2dnZ/9fX + 1//W1tb/1NTU/9PT0//CwsL/UFBQ/yQkJP8hISH/IyMj/yQkJP8kJCT/JCQk/yMjI/8jIyP/IiIi/yIi + Iv8iIiL/ISEh/yEhIf8iISD/OSIe/3wnGP+zKhL/nycR/2YiFv9WIRf/kCUS/8UsEf93Jxn/MSEe/4Ul + FP+5KxL/gygX/0wkHf9FIx3/dicY/68qEv98JRb/KiIg/yIiIf8kIiH/QyMe/38nGP+NKRb/XCYb/1wk + Gv+dKRT/SyUe/ykjIv98KBn/licU/z0iHv8tIiD/JSIi/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMj + I/8jIyP/JCQk/yMjI/8jIyP/JCQk/yEhIf8JCQn/CQkJ/0hISP+YmJj/wMDA/8fHx//IyMj/ycnJ/8vL + y//MzMz/zs7O/8/Pz//R0dH/0tLS/9TU1P/V1dX/19fX/9jY2P/Z2dn/2tra/9vb2//c3Nz/3d3d/97e + 3v/e3t7/39/f/+Dg4P/h4eH/4uLi/+Li4v/j4+P/5OTk/+Tk5P/l5eX/5ubm/+fn5//n5+f/6Ojo/+jo + 6P/p6en/6urq/+rq6v/r6+v/6+vr/+zs7P/s7Oz/7e3t/+3t7f/u7u7/7u7u/+/v7//v7+//8PDw//Dw + 8DH///8B////Af///wH///8B3d3d49zc3P/a2tr/2dnZ/9fX1//W1tb/1NTU/8DAwP9GRkb/IiIi/yMj + I/8kJCT/JCQk/yQkJP8kJCT/IyMj/yMjI/8jIyP/IiIi/yIiIv8iIiL/ISEh/yEhIf8hISH/JyEg/04j + HP+QKBX/tioR/70rEP+3KxL/gygX/zsiHv9tJRj/viwR/3AmGf8rISD/ISEh/yEhIf8nISD/dicY/7Eq + Ev88Ih7/IiIi/yIiIv8iIiL/JiIh/ykiIf82Ih7/likV/10mHP8kIiL/OCIe/5UpFv9pJxv/RCMe/3Ym + F/8xIyD/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8kJCT/IyMj/yMjI/8jIyP/CgoK/wQE + BP9AQED/kpKS/7u7u//IyMj/ycnJ/8vLy//MzMz/zs7O/8/Pz//Q0ND/0dHR/9PT0//U1NT/1tbW/9fX + 1//Y2Nj/2tra/9vb2//c3Nz/3Nzc/97e3v/e3t7/39/f/+Dg4P/g4OD/4eHh/+Li4v/i4uL/4+Pj/+Tk + 5P/l5eX/5eXl/+bm5v/m5ub/5+fn/+jo6P/o6Oj/6enp/+rq6v/q6ur/6+vr/+vr6//s7Oz/7Ozs/+3t + 7f/t7e3/7u7u/+7u7v/v7+//7+/v/+/v7//w8PD/8PDwMf///wH///8B////Af///wHe3t7j3d3d/9zc + 3P/a2tr/2dnZ/9fX1//W1tb/y8vL/2hoaP8sLCz/IyMj/yMjI/8kJCT/JCQk/yMjI/8jIyP/IyMj/yMj + I/8iIiL/IiIi/yIiIv8hISH/ISEh/yEhIf8hISH/ISEg/ywhH/9BIx3/TyQc/0AjHv8pISD/NCIe/6Iq + FP+cKRX/KyEf/yEhIf8hISH/ISEh/yQhIP9sJRj/vSsR/0sjHf8hISH/MCEf/0QiHP8oISD/IiIi/yci + If9CJB7/JyIh/zciH/+IJxX/cica/0YkHf+RKBX/YiYc/zoiHv9kJBn/RyMd/yUiIv8jIyP/IyMj/yMj + I/8jIyP/IyMj/yMjI/8lJSX/MTEx/x8fH/8NDQ3/Pz8//5WVlf+5ubn/ycnJ/8vLy//MzMz/zc3N/8/P + z//Q0ND/0dHR/9LS0v/U1NT/1dXV/9bW1v/X19f/2dnZ/9ra2v/b29v/3Nzc/93d3f/e3t7/39/f/+Dg + 4P/g4OD/4eHh/+Li4v/i4uL/4+Pj/+Tk5P/k5OT/5eXl/+bm5v/m5ub/5+fn/+fn5//o6Oj/6enp/+np + 6f/q6ur/6urq/+vr6//r6+v/7Ozs/+zs7P/t7e3/7e3t/+7u7v/u7u7/7u7u/+/v7//v7+//8PDw//Dw + 8P/x8fEx////Af///wH///8B////Ad/f3+Pe3t7/3d3d/9zc3P/a2tr/2dnZ/9jY2P/X19f/xMTE/4yM + jP89PT3/JiYm/yMjI/8kJCT/IyMj/yMjI/8jIyP/IyMj/yMjI/8iIiL/IiIi/yIiIv8iIiL/IiIi/yEh + If8hISH/ISEh/yEhIf8hISH/ISEh/yEhIf8zIh//oioU/5AoFf8jICD/ISEh/yEhIf8gICD/OiEc/6Ao + Ev+rKhP/MiIf/ysgHv+EJhX/rikR/0QjHf8iIiL/IiIi/yIiIv8iIiL/TiMc/24nGv9CIx7/kikW/3co + Gf89Ix7/hicX/4EpGf9iJhv/KiMi/yMjI/8jIyP/IyMj/yMjI/8iIiL/JCQk/zg4OP9SUlL/XV1d/2Ji + Yv+ZmZn/xMTE/8zMzP/MzMz/zs7O/8/Pz//Q0ND/0dHR/9LS0v/U1NT/1dXV/9bW1v/X19f/2NjY/9nZ + 2f/b29v/3Nzc/93d3f/e3t7/39/f/9/f3//g4OD/4eHh/+Li4v/i4uL/4+Pj/+Pj4//k5OT/5eXl/+Xl + 5f/m5ub/5ubm/+fn5//o6Oj/6Ojo/+np6f/p6en/6urq/+rq6v/r6+v/7Ozs/+zs7P/t7e3/7e3t/+3t + 7f/u7u7/7u7u/+/v7//v7+//8PDw//Dw8P/w8PD/8fHx//Hx8TH///8B////Af///wH///8B4ODg49/f + 3//e3t7/3d3d/9zc3P/a2tr/2dnZ/9jY2P/X19f/0tLS/6qqqv9kZGT/Kysr/yMjI/8jIyP/IyMj/yMj + I/8jIyP/IyMj/yIiIv8iIiL/IiIi/yIiIv8iIiL/ISEh/yEhIf8hISH/ISEh/yEhIf8hISH/ISEh/yYh + IP9zJxn/sCoS/1QhGP8oIB7/IyAf/zcgG/+MJRP/visR/2YlGf8oIB//aSMX/78rEf+CKBj/LCIg/yIi + Iv8iIiH/IyIh/yIhIf8oIiH/NyIe/4AmFv99KBj/PSId/4EnFv95KBn/LSMi/yYjIv8jIyL/IyMj/yMj + I/8jIyP/IiIi/yIiIv8lJSX/OTk5/1NTU/9nZ2f/hYWF/7m5uf/Nzc3/zs7O/8/Pz//Q0ND/0dHR/9LS + 0v/T09P/1NTU/9bW1v/X19f/2NjY/9nZ2f/a2tr/29vb/9zc3P/d3d3/3t7e/9/f3//g4OD/4ODg/+Hh + 4f/i4uL/4+Pj/+Pj4//k5OT/5OTk/+Xl5f/m5ub/5ubm/+fn5//n5+f/6Ojo/+jo6P/p6en/6enp/+rq + 6v/r6+v/6+vr/+vr6//s7Oz/7Ozs/+3t7f/t7e3/7u7u/+7u7v/v7+//7+/v/+/v7//w8PD/8PDw//Hx + 8f/x8fH/8fHxMf///wH///8B////Af///wHh4eHj4ODg/9/f3//e3t7/3d3d/9zc3P/b29v/2tra/9nZ + 2f/Y2Nj/19fX/9TU1P+goKD/XFxc/y8vL/8iIiL/IyMj/yMjI/8jIyP/IyMj/yMjI/8iIiL/IiIi/yIi + Iv8iIiL/IiIi/yIiIv8iIiL/ISEh/yEhIf8hISH/ISEh/ykhIP9yJhj/qikS/54mEf+WJRH/rSgR/6sq + E/9kJRr/LyEe/3EkFv+/KxD/gygX/zAiH/8hISH/IiEh/zIiH/97JRX/VCMa/ysiIP9zJRf/eygZ/1Ek + HP+fKBP/likV/zMjIP8jIyP/IyMj/yMjI/8jIyP/IyMj/yIiIv8jIyP/JCQk/xEREf8HBwf/PT09/4GB + gf+0tLT/zs7O/8/Pz//R0dH/0tLS/9LS0v/T09P/1NTU/9XV1f/X19f/2NjY/9nZ2f/a2tr/29vb/9zc + 3P/d3d3/3t7e/9/f3//g4OD/4eHh/+Hh4f/i4uL/4+Pj/+Tk5P/k5OT/5eXl/+Xl5f/m5ub/5ubm/+fn + 5//n5+f/6Ojo/+jo6P/p6en/6enp/+rq6v/q6ur/6+vr/+vr6//s7Oz/7Ozs/+3t7f/t7e3/7u7u/+7u + 7v/u7u7/7+/v/+/v7//w8PD/8PDw//Hx8f/x8fH/8fHx//Ly8v/x8fEx////Af///wH///8B////AeLi + 4uPh4eH/4ODg/9/f3//e3t7/3d3d/9zc3P/b29v/2tra/9nZ2f/Y2Nj/19fX/9XV1f/ExMT/ioqK/0FB + Qf8kJCT/IyMj/yMjI/8jIyP/IyMj/yMjI/8iIiL/IiIi/yIiIv8iIiL/IiIi/yIiIv8iIiL/IiIi/yEh + If8hISH/ISEh/yghIP9FIx3/aCUZ/3UmGP9lJRn/QiMd/ychH/9YIhj/vSsR/5YpFf8wIh//ISEh/yEh + If8tIR//eSUW/7wsEf9lJhv/JyIh/0QkHv81IyD/YCUa/4spF/9UJR3/KyMh/yMjI/8jIyP/IyMj/yMj + I/8jIyP/IiIi/yQkJP8XFxf/AgIC/xwcHP95eXn/sbGx/87Ozv/Q0ND/0tLS/9PT0//U1NT/1NTU/9XV + 1f/W1tb/19fX/9nZ2f/a2tr/29vb/9vb2//d3d3/3d3d/9/f3//g4OD/4eHh/+Hh4f/i4uL/4+Pj/+Pj + 4//k5OT/5OTk/+Xl5f/m5ub/5ubm/+fn5//n5+f/6Ojo/+jo6P/p6en/6enp/+np6f/q6ur/6urq/+vr + 6//r6+v/7Ozs/+zs7P/t7e3/7e3t/+7u7v/u7u7/7+/v/+/v7//v7+//8PDw//Dw8P/w8PD/8fHx//Hx + 8f/y8vL/8vLy//Ly8jH///8B////Af///wH///8B4+Pj4+Li4v/h4eH/4ODg/9/f3//e3t7/3d3d/9zc + 3P/b29v/29vb/9ra2v/Z2dn/2NjY/9fX1//T09P/urq6/3t7e/81NTX/JSUl/yIiIv8jIyP/IyMj/yMj + I/8jIyP/IiIi/yIiIv8iIiL/IiIi/yIiIv8iIiL/IiIi/yEhIf8hISH/ISEh/yEhIP8iISD/JCEg/yIh + IP8lICD/WCIZ/7QqEf+sKxP/PiMe/yEhIP8hISH/KyAf/3klFv+7KxH/byca/yoiIf8iIiL/IyIi/y8i + IP9CIx3/MSMh/yQjIv8jIyL/IyMj/yMjI/8jIyP/IiIi/yMjI/8mJib/GBgY/wUFBf8eHh7/d3d3/7W1 + tf/Ozs7/0tLS/9PT0//U1NT/1dXV/9bW1v/X19f/19fX/9nZ2f/Z2dn/29vb/9zc3P/c3Nz/3t7e/97e + 3v/g4OD/4ODg/+Hh4f/i4uL/4+Pj/+Tk5P/k5OT/5eXl/+Xl5f/m5ub/5ubm/+fn5//n5+f/6Ojo/+jo + 6P/p6en/6enp/+rq6v/q6ur/6urq/+vr6//r6+v/7Ozs/+zs7P/t7e3/7e3t/+3t7f/u7u7/7u7u/+/v + 7//v7+//7+/v//Dw8P/w8PD/8PDw//Hx8f/x8fH/8vLy//Ly8v/y8vL/8/PzMf///wH///8B////Af// + /wHk5OTj5OTk/+Li4v/i4uL/4ODg/+Dg4P/e3t7/3t7e/93d3f/c3Nz/29vb/9ra2v/a2tr/2dnZ/9jY + 2P/X19f/09PT/6SkpP9gYGD/Kioq/yIiIv8jIyP/IyMj/yMjI/8jIyP/IyMj/yIiIv8iIiL/IiIi/yIi + Iv8iIiL/IiIi/yEhIf8hISH/ISEh/yEhIf8hISH/ISEh/zIhHv+TKBT/qCoT/6EpFP82IR3/ISAg/yYg + H/9nIxf/uysR/4MoF/8uIiD/IiIi/yIiIv8xIiD/iSgW/48oFf81IyD/IyMj/yMjI/8jIyP/IyMj/yMj + I/8iIiL/KSkp/x8fH/8FBQX/FRUV/2lpaf+urq7/0NDQ/9TU1P/V1dX/1dXV/9bW1v/X19f/2NjY/9nZ + 2f/Z2dn/29vb/9vb2//c3Nz/3d3d/97e3v/f39//4ODg/+Hh4f/i4uL/4+Pj/+Pj4//k5OT/5eXl/+Xl + 5f/m5ub/5ubm/+fn5//n5+f/6Ojo/+jo6P/p6en/6enp/+rq6v/q6ur/6urq/+vr6//r6+v/7Ozs/+zs + 7P/s7Oz/7e3t/+3t7f/u7u7/7u7u/+/v7//v7+//7+/v//Dw8P/w8PD/8PDw//Hx8f/x8fH/8fHx//Ly + 8v/y8vL/8vLy//Pz8//z8/Mx////Af///wH///8B////AeXl5ePl5eX/5OTk/+Pj4//i4uL/4eHh/+Dg + 4P/f39//3t7e/97e3v/c3Nz/3Nzc/9vb2//a2tr/2tra/9nZ2f/Y2Nj/1tbW/8nJyf+MjIz/RUVF/yYm + Jv8iIiL/IyMj/yMjI/8jIyP/IiIi/yIiIv8iIiL/IiIi/yIiIv8iIiL/IiIi/yEhIf8hISH/ISEh/yEh + If8hISH/JCEg/z0iHv9HIx3/pyoT/4gmE/9QIRj/dCQW/7orEf+OKRf/NCMf/yIiIv8iIiL/MCIf/4Em + Fv/ALRL/cCga/yojIv8jIyP/IyMj/yMjI/8jIyP/IiIi/yQkJP8eHh7/BQUF/wwMDP9hYWH/qamp/83N + zf/V1dX/1tbW/9fX1//X19f/2NjY/9nZ2f/a2tr/29vb/9zc3P/d3d3/3d3d/97e3v/f39//4ODg/+Hh + 4f/i4uL/4+Pj/+Pj4//k5OT/5eXl/+Xl5f/m5ub/5ubm/+fn5//n5+f/6Ojo/+jo6P/p6en/6enp/+rq + 6v/q6ur/6urq/+vr6//r6+v/6+vr/+zs7P/s7Oz/7e3t/+3t7f/t7e3/7u7u/+7u7v/v7+//7+/v/+/v + 7//w8PD/8PDw//Dw8P/x8fH/8fHx//Hx8f/y8vL/8vLy//Ly8v/z8/P/8/Pz//Pz8zH///8B////Af// + /wH///8B5ubm4+bm5v/l5eX/5OTk/+Pj4//i4uL/4eHh/+Hh4f/g4OD/39/f/9/f3//e3t7/3d3d/9zc + 3P/c3Nz/29vb/9ra2v/Z2dn/2dnZ/9fX1/+8vLz/fHx8/zg4OP8kJCT/IiIi/yMjI/8jIyP/IyMj/yIi + Iv8iIiL/IiIi/yIiIv8iIiL/IiIi/yIiIv8hISH/ISEh/yEhIf8hISH/ISEh/yMhIP9TJBz/nSkV/7gr + Ef+2KxL/uiwS/08kHP8iIiL/IiIi/yoiIP+AJhX/vywS/3YoGv8pIyL/IyMj/yMjI/8jIyP/IyMj/yIi + Iv8qKir/JSUl/wkJCf8RERH/Xl5e/6enp//Pz8//19fX/9jY2P/Y2Nj/2dnZ/9ra2v/a2tr/3Nzc/9zc + 3P/d3d3/3t7e/97e3v/f39//4ODg/+Hh4f/i4uL/4+Pj/+Tk5P/k5OT/5eXl/+Xl5f/m5ub/5+fn/+fn + 5//n5+f/6Ojo/+jo6P/p6en/6enp/+rq6v/q6ur/6+vr/+vr6//r6+v/7Ozs/+zs7P/s7Oz/7e3t/+3t + 7f/t7e3/7u7u/+7u7v/u7u7/7+/v/+/v7//w8PD/8PDw//Dw8P/x8fH/8fHx//Hx8f/y8vL/8vLy//Ly + 8v/z8/P/8/Pz//Pz8//z8/P/8/PzMf///wH///8B////Af///wHn5+fj5+fn/+bm5v/l5eX/5OTk/+Pj + 4//j4+P/4uLi/+Hh4f/g4OD/4ODg/9/f3//e3t7/3t7e/93d3f/c3Nz/29vb/9vb2//a2tr/2dnZ/9nZ + 2f/R0dH/pKSk/19fX/9LS0v/YmJi/2FhYf9PT0//LS0t/yIiIv8iIiL/IiIi/yIiIv8iIiL/IiIi/yIi + Iv8iIiL/ISEh/yEhIf8hISH/ISEh/yMhIP82Ix//TiQd/0okHf+iKhT/YCQZ/yQhIf8oISD/aCQY/8As + Ef+BKRn/MCMh/yMjI/8jIyP/IyMj/yMjI/8iIiL/Kysr/0xMTP9MTEz/QkJC/2RkZP+ysrL/zs7O/9jY + 2P/Z2dn/2dnZ/9ra2v/b29v/3Nzc/9zc3P/e3t7/3t7e/9/f3//g4OD/4ODg/+Hh4f/i4uL/4+Pj/+Pj + 4//k5OT/5eXl/+Xl5f/m5ub/5ubm/+fn5//n5+f/6Ojo/+jo6P/p6en/6enp/+np6f/q6ur/6urq/+vr + 6//r6+v/6+vr/+zs7P/s7Oz/7e3t/+3t7f/t7e3/7u7u/+7u7v/u7u7/7+/v/+/v7//v7+//8PDw//Dw + 8P/w8PD/8fHx//Hx8f/x8fH/8vLy//Ly8v/y8vL/8/Pz//Pz8//z8/P/8/Pz//T09P/z8/Mx////Af// + /wH///8B////Aejo6OPo6Oj/5+fn/+bm5v/m5ub/5eXl/+Tk5P/k5OT/4+Pj/+Li4v/h4eH/4eHh/+Dg + 4P/g4OD/39/f/97e3v/e3t7/3d3d/9zc3P/c3Nz/29vb/9ra2v/a2tr/1tbW/9TU1P/Y2Nj/19fX/9TU + 1P+1tbX/ZWVl/ysrK/8iIiL/IiIi/yIiIv8iIiL/IiIi/yIiIv8iIiL/ISEh/yEhIf8hISH/ISEh/yEh + If8iIiH/IiIh/2YnG/+zKxL/nCgT/6MoEv/BLBH/gSkZ/zAkIf8jIyL/IyMj/yMjI/8jIyP/IiIi/ycn + J/84ODj/VFRU/2JiYv92dnb/q6ur/9fX1//a2tr/2tra/9vb2//c3Nz/3d3d/93d3f/e3t7/39/f/9/f + 3//g4OD/4eHh/+Li4v/i4uL/4+Pj/+Tk5P/k5OT/5eXl/+bm5v/m5ub/5+fn/+fn5//o6Oj/6Ojo/+jo + 6P/p6en/6enp/+rq6v/q6ur/6+vr/+vr6//r6+v/7Ozs/+zs7P/s7Oz/7e3t/+3t7f/t7e3/7u7u/+7u + 7v/u7u7/7+/v/+/v7//v7+//7+/v//Dw8P/w8PD/8PDw//Hx8f/x8fH/8fHx//Hx8f/y8vL/8vLy//Pz + 8//z8/P/8/Pz//Pz8//09PT/9PT0//Pz8zH///8B////Af///wH///8B6enp4+np6f/o6Oj/5+fn/+fn + 5//m5ub/5eXl/+Xl5f/k5OT/4+Pj/+Pj4//i4uL/4eHh/+Hh4f/g4OD/4ODg/9/f3//e3t7/3t7e/93d + 3f/d3d3/3Nzc/9vb2//b29v/29vb/9ra2v/a2tr/2dnZ/9nZ2f/Dw8P/YmJi/yQkJP8jIyP/IiIi/yIi + Iv8iIiL/IiIi/yIiIv8iIiL/IiIi/yIiIv8iIiL/IiIi/yIiIv8iIiL/KiIh/10mHP+UKhb/nSsW/28o + G/8uIyH/IyMj/yMjI/8jIyP/IyMj/yIiIv8iIiL/ISEh/xQUFP8uLi7/Z2dn/4+Pj//Ozs7/29vb/9zc + 3P/c3Nz/3d3d/97e3v/e3t7/39/f/9/f3//g4OD/4eHh/+Li4v/i4uL/4+Pj/+Tk5P/k5OT/5eXl/+bm + 5v/m5ub/5ubm/+fn5//o6Oj/6Ojo/+jo6P/p6en/6enp/+rq6v/q6ur/6urq/+vr6//r6+v/7Ozs/+zs + 7P/s7Oz/7e3t/+3t7f/t7e3/7u7u/+7u7v/u7u7/7+/v/+/v7//v7+//8PDw//Dw8P/w8PD/8PDw//Hx + 8f/x8fH/8fHx//Ly8v/y8vL/8vLy//Ly8v/z8/P/8/Pz//Pz8//09PT/9PT0//T09P/09PT/9PT0Mf// + /wH///8B////Af///wHq6urj6urq/+np6f/o6Oj/6Ojo/+fn5//n5+f/5ubm/+bm5v/l5eX/5OTk/+Tk + 5P/j4+P/4+Pj/+Li4v/h4eH/4eHh/+Dg4P/g4OD/39/f/97e3v/e3t7/3d3d/93d3f/d3d3/3Nzc/9zc + 3P/b29v/29vb/9ra2v+mpqb/Kioq/yMjI/8iIiL/IiIi/yIiIv8iIiL/IiIi/yIiIv8iIiL/IiIi/yIi + Iv8iIiL/IiIi/yIiIv8iIiL/JCMi/ysjIv8sIyH/JiMi/yMjIv8jIyP/IyMj/yMjI/8iIiL/IiIi/x0d + Hf8ICAj/BQUF/zs7O/+Wlpb/x8fH/9zc3P/d3d3/3t7e/97e3v/f39//4ODg/+Dg4P/h4eH/4uLi/+Li + 4v/j4+P/4+Pj/+Tk5P/l5eX/5eXl/+bm5v/m5ub/5+fn/+jo6P/o6Oj/6Ojo/+np6f/p6en/6urq/+rq + 6v/q6ur/6+vr/+vr6//r6+v/7Ozs/+zs7P/s7Oz/7e3t/+3t7f/t7e3/7u7u/+7u7v/u7u7/7+/v/+/v + 7//v7+//7+/v/+/v7//w8PD/8PDw//Dw8P/x8fH/8fHx//Hx8f/y8vL/8vLy//Ly8v/y8vL/8/Pz//Pz + 8//z8/P/9PT0//T09P/09PT/9PT0//X19f/19fUx////Af///wH///8B////Aevr6+Pr6+v/6urq/+rq + 6v/p6en/6Ojo/+jo6P/n5+f/5+fn/+bm5v/m5ub/5eXl/+Tk5P/k5OT/4+Pj/+Pj4//i4uL/4uLi/+Hh + 4f/h4eH/4ODg/+Dg4P/f39//3t7e/97e3v/e3t7/3d3d/93d3f/c3Nz/3Nzc/8HBwf83Nzf/IiIi/yIi + Iv8jIyP/IyMj/yIiIv8iIiL/IiIi/yIiIv8iIiL/IiIi/yIiIv8iIiL/IyMj/yMjI/8jIyP/IyMj/yMj + I/8jIyP/IyMj/yMjI/8jIyP/IiIi/yIiIv8hISH/DQ0N/wMDA/80NDT/kJCQ/8nJyf/d3d3/39/f/9/f + 3//g4OD/4ODg/+Hh4f/h4eH/4uLi/+Li4v/j4+P/5OTk/+Tk5P/l5eX/5eXl/+bm5v/n5+f/5+fn/+fn + 5//o6Oj/6Ojo/+np6f/p6en/6urq/+rq6v/q6ur/6+vr/+vr6//r6+v/7Ozs/+zs7P/t7e3/7e3t/+3t + 7f/u7u7/7u7u/+7u7v/u7u7/7+/v/+/v7//v7+//7+/v//Dw8P/w8PD/8PDw//Hx8f/x8fH/8fHx//Hx + 8f/y8vL/8vLy//Ly8v/z8/P/8/Pz//Pz8//z8/P/8/Pz//T09P/09PT/9PT0//T09P/19fX/9fX1//X1 + 9TH///8B////Af///wH///8B7Ozs4+vr6//r6+v/6urq/+rq6v/p6en/6enp/+jo6P/o6Oj/5+fn/+bm + 5v/m5ub/5eXl/+Xl5f/k5OT/5OTk/+Pj4//j4+P/4uLi/+Li4v/h4eH/4eHh/+Dg4P/g4OD/39/f/9/f + 3//f39//3t7e/97e3v/d3d3/19fX/4uLi/89PT3/JCQk/yMjI/8jIyP/IyMj/yMjI/8iIiL/IiIi/yIi + Iv8iIiL/IiIi/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yIiIv8jIyP/JSUl/w4O + Dv8CAgL/IyMj/4KCgv/FxcX/39/f/+Dg4P/g4OD/4eHh/+Hh4f/i4uL/4uLi/+Pj4//j4+P/5OTk/+Tk + 5P/l5eX/5eXl/+bm5v/m5ub/5+fn/+fn5//o6Oj/6Ojo/+np6f/p6en/6urq/+rq6v/q6ur/6+vr/+vr + 6//r6+v/7Ozs/+zs7P/s7Oz/7e3t/+3t7f/t7e3/7u7u/+7u7v/u7u7/7+/v/+/v7//v7+//7+/v//Dw + 8P/w8PD/8PDw//Dw8P/x8fH/8fHx//Hx8f/x8fH/8vLy//Ly8v/y8vL/8vLy//Pz8//z8/P/8/Pz//Pz + 8//09PT/9PT0//T09P/19fX/9fX1//X19f/19fX/9fX1Mf///wH///8B////Af///wHt7e3j7Ozs/+zs + 7P/r6+v/6+vr/+rq6v/q6ur/6enp/+np6f/p6en/6Ojo/+jo6P/n5+f/5ubm/+bm5v/l5eX/5eXl/+Xl + 5f/k5OT/5OTk/+Pj4//j4+P/4uLi/+Li4v/h4eH/4eHh/+Hh4f/g4OD/4ODg/9/f3//f39//3d3d/76+ + vv9ycnL/ODg4/yQkJP8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMj + I/8jIyP/IyMj/yMjI/8jIyP/IiIi/yMjI/8RERH/AgIC/yYmJv+IiIj/xcXF/9/f3//i4uL/4uLi/+Li + 4v/j4+P/4+Pj/+Tk5P/k5OT/5eXl/+Xl5f/m5ub/5ubm/+bm5v/n5+f/5+fn/+jo6P/o6Oj/6enp/+np + 6f/p6en/6urq/+rq6v/r6+v/6+vr/+zs7P/s7Oz/7Ozs/+3t7f/t7e3/7e3t/+7u7v/u7u7/7u7u/+7u + 7v/v7+//7+/v/+/v7//v7+//8PDw//Dw8P/w8PD/8PDw//Hx8f/x8fH/8fHx//Hx8f/y8vL/8vLy//Ly + 8v/y8vL/8vLy//Pz8//z8/P/8/Pz//Pz8//09PT/9PT0//T09P/09PT/9fX1//X19f/19fX/9fX1//b2 + 9v/29vYx////Af///wH///8B////Ae3t7ePt7e3/7Ozs/+zs7P/s7Oz/6+vr/+vr6//q6ur/6urq/+np + 6f/p6en/6enp/+jo6P/o6Oj/5+fn/+fn5//m5ub/5ubm/+Xl5f/l5eX/5OTk/+Tk5P/j4+P/4+Pj/+Li + 4v/i4uL/4uLi/+Hh4f/h4eH/4eHh/+Dg4P/g4OD/4ODg/9TU1P+np6f/XFxc/yQkJP8iIiL/IyMj/yMj + I/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yIiIv8nJyf/FBQU/wIC + Av8cHBz/dnZ2/8TExP/f39//4uLi/+Pj4//j4+P/4+Pj/+Tk5P/k5OT/5eXl/+Xl5f/m5ub/5ubm/+fn + 5//n5+f/5+fn/+jo6P/o6Oj/6enp/+np6f/q6ur/6urq/+rq6v/r6+v/6+vr/+vr6//s7Oz/7Ozs/+3t + 7f/t7e3/7e3t/+7u7v/u7u7/7u7u/+7u7v/v7+//7+/v/+/v7//v7+//7+/v//Dw8P/w8PD/8PDw//Dw + 8P/x8fH/8fHx//Hx8f/x8fH/8vLy//Ly8v/y8vL/8vLy//Pz8//z8/P/8/Pz//Pz8//z8/P/9PT0//T0 + 9P/09PT/9PT0//X19f/19fX/9fX1//X19f/19fX/9vb2//b29jH///8B////Af///wH///8B7u7u4+3t + 7f/t7e3/7e3t/+zs7P/s7Oz/7Ozs/+vr6//r6+v/6+vr/+rq6v/q6ur/6enp/+np6f/p6en/6Ojo/+jo + 6P/n5+f/5+fn/+bm5v/m5ub/5eXl/+Xl5f/l5eX/5OTk/+Tk5P/j4+P/4+Pj/+Pj4//i4uL/4uLi/+Li + 4v/i4uL/4eHh/+Hh4f/X19f/l5eX/05OTv8oKCj/IiIi/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMj + I/8jIyP/IyMj/yMjI/8lJSX/Tk5O/5iYmP9zc3P/UVFR/5OTk//Gxsb/4uLi/+Tk5P/k5OT/5eXl/+Xl + 5f/l5eX/5ubm/+bm5v/n5+f/5+fn/+fn5//o6Oj/6Ojo/+np6f/p6en/6enp/+rq6v/q6ur/6urq/+vr + 6//r6+v/6+vr/+zs7P/s7Oz/7Ozs/+3t7f/t7e3/7e3t/+7u7v/u7u7/7u7u/+7u7v/u7u7/7+/v/+/v + 7//v7+//8PDw//Dw8P/w8PD/8PDw//Dw8P/x8fH/8fHx//Hx8f/x8fH/8fHx//Ly8v/y8vL/8vLy//Ly + 8v/y8vL/8/Pz//Pz8//z8/P/8/Pz//T09P/09PT/9PT0//T09P/09PT/9fX1//X19f/19fX/9fX1//b2 + 9v/29vb/9vb2Mf///wH///8B////Af///wHu7u7j7u7u/+7u7v/t7e3/7e3t/+3t7f/s7Oz/7Ozs/+zs + 7P/r6+v/6+vr/+vr6//q6ur/6urq/+rq6v/p6en/6enp/+jo6P/o6Oj/5+fn/+fn5//m5ub/5ubm/+Xl + 5f/l5eX/5eXl/+Tk5P/k5OT/5OTk/+Pj4//j4+P/4+Pj/+Pj4//i4uL/4uLi/+Pj4//g4OD/xMTE/3d3 + d/82Njb/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IiIi/0RERP+urq7/4uLi/+Li + 4v/a2tr/4ODg/+Tk5P/l5eX/5eXl/+Xl5f/l5eX/5ubm/+bm5v/n5+f/5+fn/+fn5//o6Oj/6Ojo/+jo + 6P/p6en/6enp/+rq6v/q6ur/6urq/+vr6//r6+v/6+vr/+zs7P/s7Oz/7Ozs/+3t7f/t7e3/7e3t/+7u + 7v/u7u7/7u7u/+/v7//v7+//7+/v/+/v7//v7+//8PDw//Dw8P/w8PD/8PDw//Hx8f/x8fH/8fHx//Hx + 8f/x8fH/8vLy//Ly8v/y8vL/8vLy//Ly8v/z8/P/8/Pz//Pz8//z8/P/8/Pz//T09P/09PT/9PT0//T0 + 9P/09PT/9fX1//X19f/19fX/9fX1//b29v/29vb/9vb2//b29v/29vYx////Af///wH///8B////Ae/v + 7+Pu7u7/7u7u/+7u7v/u7u7/7e3t/+3t7f/t7e3/7Ozs/+zs7P/s7Oz/6+vr/+vr6//r6+v/6urq/+rq + 6v/q6ur/6enp/+np6f/o6Oj/6Ojo/+fn5//n5+f/5+fn/+bm5v/m5ub/5eXl/+Xl5f/l5eX/5OTk/+Tk + 5P/k5OT/5OTk/+Pj4//j4+P/5OTk/+Tk5P/k5OT/29vb/7i4uP9ra2v/LS0t/yQkJP8iIiL/IyMj/yMj + I/8jIyP/IiIi/yMjI/84ODj/ra2t/+Li4v/l5eX/5eXl/+Xl5f/l5eX/5eXl/+bm5v/m5ub/5ubm/+fn + 5//n5+f/5+fn/+jo6P/o6Oj/6Ojo/+np6f/p6en/6enp/+rq6v/q6ur/6+vr/+vr6//r6+v/7Ozs/+zs + 7P/s7Oz/7e3t/+3t7f/t7e3/7e3t/+7u7v/u7u7/7u7u/+7u7v/v7+//7+/v/+/v7//v7+//8PDw//Dw + 8P/w8PD/8PDw//Hx8f/x8fH/8fHx//Hx8f/x8fH/8vLy//Ly8v/y8vL/8vLy//Ly8v/z8/P/8/Pz//Pz + 8//z8/P/8/Pz//T09P/09PT/9PT0//T09P/09PT/9PT0//X19f/19fX/9fX1//X19f/19fX/9vb2//b2 + 9v/29vb/9vb2//b29jH///8B////Af///wH///8B8PDw4+/v7//v7+//7+/v/+7u7v/u7u7/7u7u/+3t + 7f/t7e3/7e3t/+zs7P/s7Oz/7Ozs/+zs7P/r6+v/6+vr/+vr6//q6ur/6urq/+np6f/p6en/6enp/+jo + 6P/o6Oj/5+fn/+fn5//n5+f/5ubm/+bm5v/m5ub/5ubm/+bm5v/l5eX/5eXl/+Xl5f/l5eX/5eXl/+bm + 5v/m5ub/5ubm/9jY2P+dnZ3/V1dX/yYmJv8iIiL/IyMj/yMjI/8iIiL/PDw8/6CgoP/l5eX/5+fn/+fn + 5//n5+f/5+fn/+fn5//n5+f/5+fn/+jo6P/o6Oj/6Ojo/+jo6P/p6en/6enp/+np6f/q6ur/6urq/+rq + 6v/r6+v/6+vr/+vr6//s7Oz/7Ozs/+zs7P/t7e3/7e3t/+3t7f/t7e3/7u7u/+7u7v/u7u7/7u7u/+/v + 7//v7+//7+/v/+/v7//w8PD/8PDw//Dw8P/w8PD/8fHx//Hx8f/x8fH/8fHx//Ly8v/y8vL/8vLy//Ly + 8v/y8vL/8vLy//Pz8//z8/P/8/Pz//Pz8//z8/P/8/Pz//T09P/09PT/9PT0//T09P/09PT/9PT0//X1 + 9f/19fX/9fX1//X19f/19fX/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2Mf///wH///8B////Af// + /wHw8PDj8PDw//Dw8P/v7+//7+/v/+/v7//u7u7/7u7u/+7u7v/t7e3/7e3t/+3t7f/s7Oz/7Ozs/+zs + 7P/s7Oz/6+vr/+vr6//r6+v/6urq/+rq6v/p6en/6enp/+np6f/o6Oj/6Ojo/+jo6P/n5+f/5+fn/+fn + 5//n5+f/5ubm/+bm5v/m5ub/5ubm/+bm5v/m5ub/5ubm/+fn5//n5+f/5+fn/+Tk5P/MzMz/eHh4/zY2 + Nv8kJCT/IiIi/y0tLf+ampr/4ODg/+fn5//o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6enp/+np + 6f/p6en/6enp/+rq6v/q6ur/6urq/+rq6v/r6+v/6+vr/+vr6//s7Oz/7Ozs/+zs7P/t7e3/7e3t/+3t + 7f/t7e3/7u7u/+7u7v/u7u7/7+/v/+/v7//v7+//7+/v/+/v7//w8PD/8PDw//Dw8P/w8PD/8fHx//Hx + 8f/x8fH/8fHx//Hx8f/y8vL/8vLy//Ly8v/y8vL/8vLy//Pz8//z8/P/8/Pz//Pz8//z8/P/8/Pz//Pz + 8//09PT/9PT0//T09P/09PT/9PT0//X19f/19fX/9fX1//X19f/19fX/9fX1//b29v/29vb/9vb2//b2 + 9v/29vb/9vb2//f39//29vYx////Af///wH///8B////AfHx8ePx8fH/8PDw//Dw8P/w8PD/7+/v/+/v + 7//v7+//7+/v/+7u7v/u7u7/7u7u/+3t7f/t7e3/7e3t/+3t7f/s7Oz/7Ozs/+zs7P/r6+v/6+vr/+vr + 6//q6ur/6urq/+rq6v/p6en/6enp/+np6f/p6en/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo + 6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/k5OT/xcXF/3R0dP9MTEz/kZGR/+bm5v/p6en/6enp/+np + 6f/p6en/6enp/+np6f/q6ur/6urq/+rq6v/q6ur/6urq/+vr6//r6+v/6+vr/+vr6//r6+v/7Ozs/+zs + 7P/s7Oz/7e3t/+3t7f/t7e3/7u7u/+7u7v/u7u7/7u7u/+7u7v/v7+//7+/v/+/v7//v7+//8PDw//Dw + 8P/w8PD/8PDw//Dw8P/x8fH/8fHx//Hx8f/x8fH/8vLy//Ly8v/y8vL/8vLy//Ly8v/z8/P/8/Pz//Pz + 8//z8/P/8/Pz//Pz8//z8/P/9PT0//T09P/09PT/9PT0//T09P/09PT/9PT0//X19f/19fX/9fX1//X1 + 9f/19fX/9fX1//b29v/29vb/9vb2//b29v/29vb/9vb2//f39//39/f/9/f3//b29jH///8B////Af// + /wH///8B8fHx4/Hx8f/x8fH/8fHx//Dw8P/w8PD/8PDw/+/v7//v7+//7+/v/+/v7//u7u7/7u7u/+7u + 7v/t7e3/7e3t/+3t7f/t7e3/7e3t/+zs7P/s7Oz/6+vr/+vr6//r6+v/6urq/+rq6v/q6ur/6urq/+np + 6f/p6en/6enp/+np6f/p6en/6enp/+np6f/p6en/6enp/+np6f/p6en/6enp/+np6f/p6en/6enp/+np + 6f/p6en/3d3d/83Nzf/h4eH/6urq/+rq6v/q6ur/6urq/+rq6v/q6ur/6urq/+rq6v/q6ur/6urq/+vr + 6//r6+v/6+vr/+vr6//s7Oz/7Ozs/+zs7P/s7Oz/7e3t/+3t7f/t7e3/7u7u/+7u7v/u7u7/7u7u/+7u + 7v/v7+//7+/v/+/v7//v7+//8PDw//Dw8P/w8PD/8PDw//Dw8P/w8PD/8fHx//Hx8f/x8fH/8fHx//Ly + 8v/y8vL/8vLy//Ly8v/y8vL/8/Pz//Pz8//z8/P/8/Pz//Pz8//z8/P/9PT0//T09P/09PT/9PT0//T0 + 9P/09PT/9PT0//X19f/19fX/9fX1//X19f/19fX/9fX1//b29v/29vb/9vb2//b29v/29vb/9vb2//b2 + 9v/39/f/9/f3//f39//39/f/9vb2Mf///wH///8B////Af///wHy8vLj8fHx//Hx8f/x8fH/8fHx//Dw + 8P/w8PD/8PDw//Dw8P/v7+//7+/v/+/v7//v7+//7u7u/+7u7v/u7u7/7u7u/+3t7f/t7e3/7e3t/+3t + 7f/t7e3/7Ozs/+zs7P/s7Oz/7Ozs/+vr6//r6+v/6+vr/+vr6//r6+v/6urq/+rq6v/q6ur/6urq/+rq + 6v/q6ur/6urq/+rq6v/q6ur/6urq/+rq6v/q6ur/6urq/+rq6v/q6ur/6urq/+rq6v/r6+v/6+vr/+vr + 6//r6+v/6+vr/+vr6//r6+v/6+vr/+vr6//r6+v/7Ozs/+zs7P/s7Oz/7Ozs/+zs7P/t7e3/7e3t/+3t + 7f/u7u7/7u7u/+7u7v/u7u7/7u7u/+/v7//v7+//7+/v/+/v7//v7+//8PDw//Dw8P/w8PD/8PDw//Dw + 8P/x8fH/8fHx//Hx8f/x8fH/8fHx//Ly8v/y8vL/8vLy//Ly8v/y8vL/8/Pz//Pz8//z8/P/8/Pz//Pz + 8//z8/P/9PT0//T09P/09PT/9PT0//T09P/09PT/9PT0//T09P/19fX/9fX1//X19f/19fX/9fX1//X1 + 9f/19fX/9vb2//b29v/29vb/9vb2//b29v/29vb/9/f3//f39//39/f/9/f3//f39//39/cx////Af// + /wH///8B////AfLy8uPy8vL/8vLy//Ly8v/y8vL/8fHx//Hx8f/x8fH/8PDw//Dw8P/w8PD/8PDw/+/v + 7//v7+//7+/v/+/v7//u7u7/7u7u/+7u7v/u7u7/7u7u/+3t7f/t7e3/7e3t/+3t7f/s7Oz/7Ozs/+zs + 7P/s7Oz/7Ozs/+vr6//r6+v/6+vr/+vr6//r6+v/6+vr/+vr6//r6+v/6+vr/+vr6//r6+v/6+vr/+vr + 6//r6+v/6+vr/+vr6//r6+v/6+vr/+zs7P/s7Oz/7Ozs/+zs7P/s7Oz/7Ozs/+zs7P/s7Oz/7Ozs/+zs + 7P/t7e3/7e3t/+3t7f/t7e3/7e3t/+7u7v/u7u7/7u7u/+7u7v/v7+//7+/v/+/v7//v7+//7+/v//Dw + 8P/w8PD/8PDw//Dw8P/w8PD/8fHx//Hx8f/x8fH/8fHx//Hx8f/x8fH/8vLy//Ly8v/y8vL/8vLy//Ly + 8v/z8/P/8/Pz//Pz8//z8/P/8/Pz//Pz8//09PT/9PT0//T09P/09PT/9PT0//T09P/09PT/9fX1//X1 + 9f/19fX/9fX1//X19f/19fX/9fX1//b29v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9/f3//f3 + 9//39/f/9/f3//f39//39/f/9/f3//j4+DH///8B////Af///wH///8B8/Pz4/Pz8//y8vL/8vLy//Ly + 8v/y8vL/8fHx//Hx8f/x8fH/8fHx//Dw8P/w8PD/8PDw//Dw8P/w8PD/7+/v/+/v7//v7+//7+/v/+/v + 7//u7u7/7u7u/+7u7v/u7u7/7e3t/+3t7f/t7e3/7e3t/+3t7f/s7Oz/7Ozs/+zs7P/s7Oz/7Ozs/+zs + 7P/s7Oz/7Ozs/+zs7P/s7Oz/7Ozs/+zs7P/s7Oz/7Ozs/+zs7P/s7Oz/7Ozs/+zs7P/s7Oz/7Ozs/+zs + 7P/s7Oz/7e3t/+3t7f/t7e3/7e3t/+3t7f/t7e3/7e3t/+3t7f/t7e3/7u7u/+7u7v/u7u7/7u7u/+/v + 7//v7+//7+/v/+/v7//v7+//8PDw//Dw8P/w8PD/8PDw//Dw8P/x8fH/8fHx//Hx8f/x8fH/8fHx//Hx + 8f/x8fH/8vLy//Ly8v/y8vL/8vLy//Ly8v/z8/P/8/Pz//Pz8//z8/P/8/Pz//Pz8//09PT/9PT0//T0 + 9P/09PT/9PT0//T09P/09PT/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/29vb/9vb2//b2 + 9v/29vb/9vb2//b29v/29vb/9vb2//f39//39/f/9/f3//f39//39/f/9/f3//f39//4+Pj/+Pj4Mf// + /wH///8B////Af///wHz8/Pj8/Pz//Pz8//z8/P/8/Pz//Ly8v/y8vL/8vLy//Ly8v/x8fH/8fHx//Hx + 8f/x8fH/8fHx//Dw8P/w8PD/8PDw//Dw8P/w8PD/8PDw/+/v7//v7+//7+/v/+/v7//v7+//7u7u/+7u + 7v/u7u7/7u7u/+7u7v/u7u7/7e3t/+3t7f/t7e3/7e3t/+3t7f/t7e3/7e3t/+3t7f/t7e3/7e3t/+3t + 7f/t7e3/7e3t/+3t7f/t7e3/7e3t/+3t7f/t7e3/7e3t/+3t7f/u7u7/7u7u/+7u7v/u7u7/7u7u/+7u + 7v/u7u7/7u7u/+7u7v/v7+//7+/v/+/v7//v7+//7+/v//Dw8P/w8PD/8PDw//Dw8P/w8PD/8fHx//Hx + 8f/x8fH/8fHx//Hx8f/x8fH/8vLy//Ly8v/y8vL/8vLy//Ly8v/y8vL/8vLy//Pz8//z8/P/8/Pz//Pz + 8//z8/P/8/Pz//T09P/09PT/9PT0//T09P/09PT/9PT0//T09P/19fX/9fX1//X19f/19fX/9fX1//X1 + 9f/19fX/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b29v/39/f/9/f3//f39//39/f/9/f3//f3 + 9//39/f/9/f3//j4+P/4+Pj/+Pj4//j4+P/4+Pgx////Af///wH///8B////AfT09OP09PT/8/Pz//Pz + 8//z8/P/8/Pz//Pz8//y8vL/8vLy//Ly8v/y8vL/8vLy//Hx8f/x8fH/8fHx//Hx8f/w8PD/8PDw//Dw + 8P/w8PD/8PDw//Dw8P/w8PD/8PDw/+/v7//v7+//7+/v/+/v7//u7u7/7u7u/+7u7v/u7u7/7u7u/+7u + 7v/u7u7/7u7u/+7u7v/u7u7/7u7u/+7u7v/u7u7/7u7u/+7u7v/u7u7/7u7u/+7u7v/u7u7/7u7u/+7u + 7v/u7u7/7u7u/+7u7v/u7u7/7u7u/+7u7v/u7u7/7+/v/+/v7//v7+//7+/v/+/v7//v7+//8PDw//Dw + 8P/w8PD/8PDw//Dw8P/x8fH/8fHx//Hx8f/x8fH/8fHx//Hx8f/x8fH/8vLy//Ly8v/y8vL/8vLy//Ly + 8v/y8vL/8vLy//Pz8//z8/P/8/Pz//Pz8//z8/P/8/Pz//T09P/09PT/9PT0//T09P/09PT/9PT0//X1 + 9f/19fX/9fX1//X19f/19fX/9fX1//X19f/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b2 + 9v/29vb/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//j4+P/4+Pj/+Pj4//j4+P/4+Pj/+Pj4//j4 + +DH///8B////AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA + + + \ No newline at end of file diff --git a/ROMVault2/frmSetDir.Designer.cs b/ROMVault2/frmSetDir.Designer.cs new file mode 100644 index 0000000..202169f --- /dev/null +++ b/ROMVault2/frmSetDir.Designer.cs @@ -0,0 +1,241 @@ +namespace ROMVault2 +{ + partial class FrmSetDir + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FrmSetDir)); + this.DataGridGames = new System.Windows.Forms.DataGridView(); + this.CDAT = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.CROM = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.btnDeleteSelected = new System.Windows.Forms.Button(); + this.grpBoxAddNew = new System.Windows.Forms.GroupBox(); + this.btnSetRomLocation = new System.Windows.Forms.Button(); + this.txtROMLocation = new System.Windows.Forms.Label(); + this.lblROMLocation = new System.Windows.Forms.Label(); + this.txtDATLocation = new System.Windows.Forms.Label(); + this.lblDATLocation = new System.Windows.Forms.Label(); + this.lblDelete = new System.Windows.Forms.Label(); + this.btnClose = new System.Windows.Forms.Button(); + this.btnResetAll = new System.Windows.Forms.Button(); + ((System.ComponentModel.ISupportInitialize)(this.DataGridGames)).BeginInit(); + this.grpBoxAddNew.SuspendLayout(); + this.SuspendLayout(); + // + // DataGridGames + // + this.DataGridGames.AllowUserToAddRows = false; + this.DataGridGames.AllowUserToDeleteRows = false; + this.DataGridGames.AllowUserToResizeRows = false; + this.DataGridGames.BackgroundColor = System.Drawing.Color.White; + this.DataGridGames.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; + this.DataGridGames.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { + this.CDAT, + this.CROM}); + this.DataGridGames.GridColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224))))); + this.DataGridGames.Location = new System.Drawing.Point(12, 135); + this.DataGridGames.Name = "DataGridGames"; + this.DataGridGames.ReadOnly = true; + this.DataGridGames.RowHeadersVisible = false; + this.DataGridGames.RowTemplate.Height = 17; + this.DataGridGames.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect; + this.DataGridGames.ShowCellErrors = false; + this.DataGridGames.ShowCellToolTips = false; + this.DataGridGames.ShowEditingIcon = false; + this.DataGridGames.ShowRowErrors = false; + this.DataGridGames.Size = new System.Drawing.Size(670, 214); + this.DataGridGames.TabIndex = 10; + this.DataGridGames.DoubleClick += new System.EventHandler(this.DataGridGamesDoubleClick); + // + // CDAT + // + this.CDAT.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill; + this.CDAT.HeaderText = "DAT Location"; + this.CDAT.Name = "CDAT"; + this.CDAT.ReadOnly = true; + // + // CROM + // + this.CROM.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill; + this.CROM.HeaderText = "ROM Location"; + this.CROM.Name = "CROM"; + this.CROM.ReadOnly = true; + // + // btnDeleteSelected + // + this.btnDeleteSelected.Location = new System.Drawing.Point(12, 355); + this.btnDeleteSelected.Name = "btnDeleteSelected"; + this.btnDeleteSelected.Size = new System.Drawing.Size(96, 25); + this.btnDeleteSelected.TabIndex = 11; + this.btnDeleteSelected.Text = "Delete Selected"; + this.btnDeleteSelected.UseVisualStyleBackColor = true; + this.btnDeleteSelected.Click += new System.EventHandler(this.BtnDeleteSelectedClick); + // + // grpBoxAddNew + // + this.grpBoxAddNew.Controls.Add(this.btnSetRomLocation); + this.grpBoxAddNew.Controls.Add(this.txtROMLocation); + this.grpBoxAddNew.Controls.Add(this.lblROMLocation); + this.grpBoxAddNew.Controls.Add(this.txtDATLocation); + this.grpBoxAddNew.Controls.Add(this.lblDATLocation); + this.grpBoxAddNew.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.grpBoxAddNew.Location = new System.Drawing.Point(12, 12); + this.grpBoxAddNew.Name = "grpBoxAddNew"; + this.grpBoxAddNew.Size = new System.Drawing.Size(670, 91); + this.grpBoxAddNew.TabIndex = 14; + this.grpBoxAddNew.TabStop = false; + this.grpBoxAddNew.Text = "Add New Directory Mapping"; + // + // btnSetRomLocation + // + this.btnSetRomLocation.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.btnSetRomLocation.Location = new System.Drawing.Point(617, 53); + this.btnSetRomLocation.Name = "btnSetRomLocation"; + this.btnSetRomLocation.Size = new System.Drawing.Size(47, 24); + this.btnSetRomLocation.TabIndex = 14; + this.btnSetRomLocation.Text = "Set"; + this.btnSetRomLocation.UseVisualStyleBackColor = true; + this.btnSetRomLocation.Click += new System.EventHandler(this.BtnSetRomLocationClick); + // + // txtROMLocation + // + this.txtROMLocation.BackColor = System.Drawing.Color.White; + this.txtROMLocation.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.txtROMLocation.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.txtROMLocation.Location = new System.Drawing.Point(89, 55); + this.txtROMLocation.Name = "txtROMLocation"; + this.txtROMLocation.Size = new System.Drawing.Size(515, 22); + this.txtROMLocation.TabIndex = 13; + this.txtROMLocation.Text = "label2"; + this.txtROMLocation.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + // + // lblROMLocation + // + this.lblROMLocation.AutoSize = true; + this.lblROMLocation.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.lblROMLocation.Location = new System.Drawing.Point(12, 60); + this.lblROMLocation.Name = "lblROMLocation"; + this.lblROMLocation.Size = new System.Drawing.Size(79, 13); + this.lblROMLocation.TabIndex = 12; + this.lblROMLocation.Text = "ROM Location:"; + // + // txtDATLocation + // + this.txtDATLocation.BackColor = System.Drawing.Color.White; + this.txtDATLocation.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.txtDATLocation.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.txtDATLocation.Location = new System.Drawing.Point(89, 25); + this.txtDATLocation.Name = "txtDATLocation"; + this.txtDATLocation.Size = new System.Drawing.Size(515, 22); + this.txtDATLocation.TabIndex = 11; + this.txtDATLocation.Text = "label2"; + this.txtDATLocation.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + // + // lblDATLocation + // + this.lblDATLocation.AutoSize = true; + this.lblDATLocation.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.lblDATLocation.Location = new System.Drawing.Point(12, 30); + this.lblDATLocation.Name = "lblDATLocation"; + this.lblDATLocation.Size = new System.Drawing.Size(76, 13); + this.lblDATLocation.TabIndex = 10; + this.lblDATLocation.Text = "DAT Location:"; + // + // lblDelete + // + this.lblDelete.AutoSize = true; + this.lblDelete.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.lblDelete.Location = new System.Drawing.Point(20, 111); + this.lblDelete.Name = "lblDelete"; + this.lblDelete.Size = new System.Drawing.Size(144, 13); + this.lblDelete.TabIndex = 15; + this.lblDelete.Text = "Delete Existing Mapping"; + // + // btnClose + // + this.btnClose.Location = new System.Drawing.Point(586, 355); + this.btnClose.Name = "btnClose"; + this.btnClose.Size = new System.Drawing.Size(96, 25); + this.btnClose.TabIndex = 16; + this.btnClose.Text = "Done"; + this.btnClose.UseVisualStyleBackColor = true; + this.btnClose.Click += new System.EventHandler(this.BtnCloseClick); + // + // btnResetAll + // + this.btnResetAll.Location = new System.Drawing.Point(138, 355); + this.btnResetAll.Name = "btnResetAll"; + this.btnResetAll.Size = new System.Drawing.Size(96, 25); + this.btnResetAll.TabIndex = 17; + this.btnResetAll.Text = "Reset All"; + this.btnResetAll.UseVisualStyleBackColor = true; + this.btnResetAll.Click += new System.EventHandler(this.BtnResetAllClick); + // + // FrmSetDir + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(694, 391); + this.Controls.Add(this.btnResetAll); + this.Controls.Add(this.btnClose); + this.Controls.Add(this.lblDelete); + this.Controls.Add(this.grpBoxAddNew); + this.Controls.Add(this.btnDeleteSelected); + this.Controls.Add(this.DataGridGames); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "FrmSetDir"; + this.ShowInTaskbar = false; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "Set ROM Directories"; + this.Activated += new System.EventHandler(this.FrmSetDirActivated); + ((System.ComponentModel.ISupportInitialize)(this.DataGridGames)).EndInit(); + this.grpBoxAddNew.ResumeLayout(false); + this.grpBoxAddNew.PerformLayout(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.DataGridView DataGridGames; + private System.Windows.Forms.DataGridViewTextBoxColumn CDAT; + private System.Windows.Forms.DataGridViewTextBoxColumn CROM; + private System.Windows.Forms.Button btnDeleteSelected; + private System.Windows.Forms.GroupBox grpBoxAddNew; + private System.Windows.Forms.Button btnSetRomLocation; + private System.Windows.Forms.Label txtROMLocation; + private System.Windows.Forms.Label lblROMLocation; + private System.Windows.Forms.Label txtDATLocation; + private System.Windows.Forms.Label lblDATLocation; + private System.Windows.Forms.Label lblDelete; + private System.Windows.Forms.Button btnClose; + private System.Windows.Forms.Button btnResetAll; + } +} \ No newline at end of file diff --git a/ROMVault2/frmSetDir.cs b/ROMVault2/frmSetDir.cs new file mode 100644 index 0000000..fa07d0f --- /dev/null +++ b/ROMVault2/frmSetDir.cs @@ -0,0 +1,167 @@ +/****************************************************** + * ROMVault2 is written by Gordon J. * + * Contact gordon@romvault.com * + * Copyright 2014 * + ******************************************************/ + +using System; +using System.Drawing; +using System.Windows.Forms; +using ROMVault2.Properties; +using ROMVault2.Utils; + +namespace ROMVault2 +{ + public partial class FrmSetDir : Form + { + private string _datLocation; + + private readonly Color _cMagenta = Color.FromArgb(255, 214, 255); + private readonly Color _cGreen = Color.FromArgb(214, 255, 214); + private readonly Color _cYellow = Color.FromArgb(255, 255, 214); + + public FrmSetDir() + { + InitializeComponent(); + } + + public void SetLocation(string dLocation) + { + _datLocation = dLocation; + txtDATLocation.Text = _datLocation; + txtROMLocation.Text = DBHelper.GetRealPath(_datLocation); + UpdateGrid(); + } + + private void UpdateGrid() + { + DataGridGames.Rows.Clear(); + foreach (DirMap t in Settings.DirPathMap) + { + DataGridGames.Rows.Add(); + int row = DataGridGames.Rows.Count - 1; + string key = t.DirKey; + DataGridGames.Rows[row].Cells["CDAT"].Value = t.DirKey; + DataGridGames.Rows[row].Cells["CROM"].Value = t.DirPath; + + if (key == "ToSort") + { + DataGridGames.Rows[row].Cells["CDAT"].Style.BackColor = _cMagenta; + DataGridGames.Rows[row].Cells["CROM"].Style.BackColor = _cMagenta; + } + else if (key == _datLocation) + { + DataGridGames.Rows[row].Cells["CDAT"].Style.BackColor = _cGreen; + DataGridGames.Rows[row].Cells["CROM"].Style.BackColor = _cGreen; + } + else if (key.Length >= _datLocation.Length) + { + if (key.Substring(0, _datLocation.Length) == _datLocation) + { + DataGridGames.Rows[row].Cells["CDAT"].Style.BackColor = _cYellow; + DataGridGames.Rows[row].Cells["CROM"].Style.BackColor = _cYellow; + } + } + } + + for (int j = 0; j < DataGridGames.Rows.Count; j++) + { + DataGridGames.Rows[j].Selected = false; + } + } + + + private void BtnSetRomLocationClick(object sender, EventArgs e) + { + FolderBrowserDialog browse = new FolderBrowserDialog + { + ShowNewFolderButton = true, + Description = Resources.FrmSetDir_BtnSetRomLocationClick_Please_select_a_folder_for_This_Rom_Set, + RootFolder = Environment.SpecialFolder.DesktopDirectory, + SelectedPath = DBHelper.GetRealPath(_datLocation) + }; + if (browse.ShowDialog() == DialogResult.OK) + { + for (int i = 0; i < Settings.DirPathMap.Count; i++) + { + if (Settings.DirPathMap[i].DirKey == _datLocation) + { + Settings.DirPathMap.RemoveAt(i); + i--; + } + } + + + string relPath = RelativePath.MakeRelative(AppDomain.CurrentDomain.BaseDirectory, browse.SelectedPath); + + Settings.DirPathMap.Add(new DirMap(_datLocation, relPath)); + Settings.DirPathMap.Sort(); + SetLocation(_datLocation); + Settings.WriteConfig(); + + //db.CheckNamesToLong(); + } + } + + private void BtnDeleteSelectedClick(object sender, EventArgs e) + { + for (int j = 0; j < DataGridGames.SelectedRows.Count; j++) + { + string datLocation = DataGridGames.SelectedRows[j].Cells["CDAT"].Value.ToString(); + + if (datLocation == "ToSort" || datLocation == "RomVault") + { + ReportError.Show(Resources.FrmSetDir_BtnDeleteSelectedClick_You_cannot_delete_the + datLocation + Resources.FrmSetDir_BtnDeleteSelectedClick_Directory_Settings, + Resources.FrmSetDir_BtnDeleteSelectedClick_RomVault_Rom_Location); + } + else + { + for (int i = 0; i < Settings.DirPathMap.Count; i++) + { + if (Settings.DirPathMap[i].DirKey == datLocation) + { + Settings.DirPathMap.RemoveAt(i); + i--; + } + } + } + } + Settings.WriteConfig(); + UpdateGrid(); + //db.CheckNamesToLong(); + } + + private void BtnCloseClick(object sender, EventArgs e) + { + //db.CheckNamesToLong(); + Close(); + } + + private void DataGridGamesDoubleClick(object sender, EventArgs e) + { + if (DataGridGames.SelectedRows.Count <= 0) return; + + grpBoxAddNew.Text = Resources.FrmSetDir_DataGridGamesDoubleClick_Edit_Existing_Directory_Mapping; + SetLocation(DataGridGames.SelectedRows[0].Cells["CDAT"].Value.ToString()); + } + + private void FrmSetDirActivated(object sender, EventArgs e) + { + + for (int j = 0; j < DataGridGames.Rows.Count; j++) + { + DataGridGames.Rows[j].Selected = false; + } + } + + private void BtnResetAllClick(object sender, EventArgs e) + { + Settings.ResetDirectories(); + Settings.WriteConfig(); + UpdateGrid(); + } + + + + } +} diff --git a/ROMVault2/frmSettings.Designer.cs b/ROMVault2/frmSettings.Designer.cs new file mode 100644 index 0000000..742994e --- /dev/null +++ b/ROMVault2/frmSettings.Designer.cs @@ -0,0 +1,271 @@ +namespace ROMVault2 +{ + partial class FrmSettings + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.label1 = new System.Windows.Forms.Label(); + this.lblDATRoot = new System.Windows.Forms.Label(); + this.btnDAT = new System.Windows.Forms.Button(); + this.btnOK = new System.Windows.Forms.Button(); + this.btnCancel = new System.Windows.Forms.Button(); + this.textBox1 = new System.Windows.Forms.TextBox(); + this.label4 = new System.Windows.Forms.Label(); + this.cboFixLevel = new System.Windows.Forms.ComboBox(); + this.cboScanLevel = new System.Windows.Forms.ComboBox(); + this.label2 = new System.Windows.Forms.Label(); + this.label3 = new System.Windows.Forms.Label(); + this.chkDebugLogs = new System.Windows.Forms.CheckBox(); + this.chkCacheSaveTimer = new System.Windows.Forms.CheckBox(); + this.upTime = new System.Windows.Forms.NumericUpDown(); + this.label5 = new System.Windows.Forms.Label(); + this.chkDoubleCheckDelete = new System.Windows.Forms.CheckBox(); + ((System.ComponentModel.ISupportInitialize)(this.upTime)).BeginInit(); + this.SuspendLayout(); + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(8, 19); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(103, 13); + this.label1.TabIndex = 0; + this.label1.Text = "DAT Root Directory:"; + // + // lblDATRoot + // + this.lblDATRoot.BackColor = System.Drawing.Color.White; + this.lblDATRoot.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.lblDATRoot.Location = new System.Drawing.Point(123, 14); + this.lblDATRoot.Name = "lblDATRoot"; + this.lblDATRoot.Size = new System.Drawing.Size(357, 22); + this.lblDATRoot.TabIndex = 3; + this.lblDATRoot.Text = "label4"; + this.lblDATRoot.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + // + // btnDAT + // + this.btnDAT.Location = new System.Drawing.Point(486, 12); + this.btnDAT.Name = "btnDAT"; + this.btnDAT.Size = new System.Drawing.Size(47, 24); + this.btnDAT.TabIndex = 6; + this.btnDAT.Text = "Set"; + this.btnDAT.UseVisualStyleBackColor = true; + this.btnDAT.Click += new System.EventHandler(this.BtnDatClick); + // + // btnOK + // + this.btnOK.Location = new System.Drawing.Point(167, 314); + this.btnOK.Name = "btnOK"; + this.btnOK.Size = new System.Drawing.Size(89, 23); + this.btnOK.TabIndex = 9; + this.btnOK.Text = "OK"; + this.btnOK.UseVisualStyleBackColor = true; + this.btnOK.Click += new System.EventHandler(this.BtnOkClick); + // + // btnCancel + // + this.btnCancel.Location = new System.Drawing.Point(280, 314); + this.btnCancel.Name = "btnCancel"; + this.btnCancel.Size = new System.Drawing.Size(89, 23); + this.btnCancel.TabIndex = 10; + this.btnCancel.Text = "Cancel"; + this.btnCancel.UseVisualStyleBackColor = true; + this.btnCancel.Click += new System.EventHandler(this.BtnCancelClick); + // + // textBox1 + // + this.textBox1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.textBox1.Location = new System.Drawing.Point(123, 111); + this.textBox1.Multiline = true; + this.textBox1.Name = "textBox1"; + this.textBox1.Size = new System.Drawing.Size(357, 136); + this.textBox1.TabIndex = 12; + // + // label4 + // + this.label4.Location = new System.Drawing.Point(8, 113); + this.label4.Name = "label4"; + this.label4.Size = new System.Drawing.Size(106, 72); + this.label4.TabIndex = 13; + this.label4.Text = "Filenames not to remove from RomDir\'s : (Put each file on its ow" + + "n line)"; + // + // cboFixLevel + // + this.cboFixLevel.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.cboFixLevel.FormattingEnabled = true; + this.cboFixLevel.Location = new System.Drawing.Point(123, 75); + this.cboFixLevel.Name = "cboFixLevel"; + this.cboFixLevel.Size = new System.Drawing.Size(357, 21); + this.cboFixLevel.TabIndex = 14; + // + // cboScanLevel + // + this.cboScanLevel.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.cboScanLevel.FormattingEnabled = true; + this.cboScanLevel.Location = new System.Drawing.Point(123, 48); + this.cboScanLevel.Name = "cboScanLevel"; + this.cboScanLevel.Size = new System.Drawing.Size(357, 21); + this.cboScanLevel.TabIndex = 15; + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(8, 51); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(84, 13); + this.label2.TabIndex = 16; + this.label2.Text = "Scanning Level:"; + // + // label3 + // + this.label3.AutoSize = true; + this.label3.Location = new System.Drawing.Point(8, 79); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(66, 13); + this.label3.TabIndex = 17; + this.label3.Text = "Fixing Level:"; + // + // chkDebugLogs + // + this.chkDebugLogs.AutoSize = true; + this.chkDebugLogs.Location = new System.Drawing.Point(279, 261); + this.chkDebugLogs.Name = "chkDebugLogs"; + this.chkDebugLogs.Size = new System.Drawing.Size(126, 17); + this.chkDebugLogs.TabIndex = 18; + this.chkDebugLogs.Text = "Debug Logs Enabled"; + this.chkDebugLogs.UseVisualStyleBackColor = true; + // + // chkCacheSaveTimer + // + this.chkCacheSaveTimer.AutoSize = true; + this.chkCacheSaveTimer.Location = new System.Drawing.Point(125, 285); + this.chkCacheSaveTimer.Name = "chkCacheSaveTimer"; + this.chkCacheSaveTimer.Size = new System.Drawing.Size(156, 17); + this.chkCacheSaveTimer.TabIndex = 19; + this.chkCacheSaveTimer.Text = "Save Cache On Timer Ever"; + this.chkCacheSaveTimer.UseVisualStyleBackColor = true; + // + // upTime + // + this.upTime.Increment = new decimal(new int[] { + 5, + 0, + 0, + 0}); + this.upTime.Location = new System.Drawing.Point(279, 283); + this.upTime.Maximum = new decimal(new int[] { + 60, + 0, + 0, + 0}); + this.upTime.Minimum = new decimal(new int[] { + 5, + 0, + 0, + 0}); + this.upTime.Name = "upTime"; + this.upTime.Size = new System.Drawing.Size(47, 20); + this.upTime.TabIndex = 20; + this.upTime.Value = new decimal(new int[] { + 10, + 0, + 0, + 0}); + // + // label5 + // + this.label5.AutoSize = true; + this.label5.Location = new System.Drawing.Point(329, 286); + this.label5.Name = "label5"; + this.label5.Size = new System.Drawing.Size(44, 13); + this.label5.TabIndex = 21; + this.label5.Text = "Minutes"; + // + // chkDoubleCheckDelete + // + this.chkDoubleCheckDelete.AutoSize = true; + this.chkDoubleCheckDelete.Location = new System.Drawing.Point(125, 261); + this.chkDoubleCheckDelete.Name = "chkDoubleCheckDelete"; + this.chkDoubleCheckDelete.Size = new System.Drawing.Size(128, 17); + this.chkDoubleCheckDelete.TabIndex = 22; + this.chkDoubleCheckDelete.Text = "Double Check Delete"; + this.chkDoubleCheckDelete.UseVisualStyleBackColor = true; + // + // FrmSettings + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(545, 346); + this.Controls.Add(this.chkDoubleCheckDelete); + this.Controls.Add(this.label5); + this.Controls.Add(this.upTime); + this.Controls.Add(this.chkCacheSaveTimer); + this.Controls.Add(this.chkDebugLogs); + this.Controls.Add(this.label3); + this.Controls.Add(this.label2); + this.Controls.Add(this.cboScanLevel); + this.Controls.Add(this.cboFixLevel); + this.Controls.Add(this.label4); + this.Controls.Add(this.textBox1); + this.Controls.Add(this.btnCancel); + this.Controls.Add(this.btnOK); + this.Controls.Add(this.btnDAT); + this.Controls.Add(this.lblDATRoot); + this.Controls.Add(this.label1); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow; + this.Name = "FrmSettings"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "RomVault Settings"; + this.Load += new System.EventHandler(this.FrmConfigLoad); + ((System.ComponentModel.ISupportInitialize)(this.upTime)).EndInit(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Label lblDATRoot; + private System.Windows.Forms.Button btnDAT; + private System.Windows.Forms.Button btnOK; + private System.Windows.Forms.Button btnCancel; + private System.Windows.Forms.TextBox textBox1; + private System.Windows.Forms.Label label4; + private System.Windows.Forms.ComboBox cboFixLevel; + private System.Windows.Forms.ComboBox cboScanLevel; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.CheckBox chkDebugLogs; + private System.Windows.Forms.CheckBox chkCacheSaveTimer; + private System.Windows.Forms.NumericUpDown upTime; + private System.Windows.Forms.Label label5; + private System.Windows.Forms.CheckBox chkDoubleCheckDelete; + } +} \ No newline at end of file diff --git a/ROMVault2/frmSettings.cs b/ROMVault2/frmSettings.cs new file mode 100644 index 0000000..dc98973 --- /dev/null +++ b/ROMVault2/frmSettings.cs @@ -0,0 +1,101 @@ +/****************************************************** + * ROMVault2 is written by Gordon J. * + * Contact gordon@romvault.com * + * Copyright 2014 * + ******************************************************/ + +using System; +using System.Collections.Generic; +using System.Windows.Forms; +using ROMVault2.Properties; + +namespace ROMVault2 +{ + public partial class FrmSettings : Form + { + public FrmSettings() + { + InitializeComponent(); + + cboScanLevel.Items.Clear(); + cboScanLevel.Items.Add("Level1"); + cboScanLevel.Items.Add("Level2"); + cboScanLevel.Items.Add("Level3"); + + cboFixLevel.Items.Clear(); + cboFixLevel.Items.Add("TorrentZip Level 1"); + cboFixLevel.Items.Add("TorrentZip Level 2"); + cboFixLevel.Items.Add("TorrentZip Level 3"); + cboFixLevel.Items.Add("Level1"); + cboFixLevel.Items.Add("Level2"); + cboFixLevel.Items.Add("Level3"); + } + + private void FrmConfigLoad(object sender, EventArgs e) + { + lblDATRoot.Text = Settings.DatRoot; + cboScanLevel.SelectedIndex = (int)Settings.ScanLevel; + cboFixLevel.SelectedIndex = (int)Settings.FixLevel; + + textBox1.Text = ""; + for (int i = 0; i < Settings.IgnoreFiles.Count; i++) + textBox1.Text += Settings.IgnoreFiles[i] + Environment.NewLine; + + chkDoubleCheckDelete.Checked = Settings.DoubleCheckDelete; + chkCacheSaveTimer.Checked = Settings.CacheSaveTimerEnabled; + upTime.Value = Settings.CacheSaveTimePeriod; + chkDebugLogs.Checked = Settings.DebugLogsEnabled; + } + + private void BtnCancelClick(object sender, EventArgs e) + { + Close(); + } + + private void BtnOkClick(object sender, EventArgs e) + { + Settings.DatRoot = lblDATRoot.Text; + Settings.ScanLevel = (eScanLevel)cboScanLevel.SelectedIndex; + Settings.FixLevel = (eFixLevel)cboFixLevel.SelectedIndex; + + string strtxt = textBox1.Text; + strtxt = strtxt.Replace("\r", ""); + string[] strsplit = strtxt.Split('\n'); + + Settings.IgnoreFiles = new List(strsplit); + for (int i = 0; i < Settings.IgnoreFiles.Count; i++) + { + Settings.IgnoreFiles[i] = Settings.IgnoreFiles[i].Trim(); + if (string.IsNullOrEmpty(Settings.IgnoreFiles[i])) + { + Settings.IgnoreFiles.RemoveAt(i); + i--; + } + } + + Settings.DoubleCheckDelete = chkDoubleCheckDelete.Checked; + Settings.DebugLogsEnabled = chkDebugLogs.Checked; + Settings.CacheSaveTimerEnabled = chkCacheSaveTimer.Checked; + Settings.CacheSaveTimePeriod = (int)upTime.Value; + + Settings.WriteConfig(); + Close(); + } + + private void BtnDatClick(object sender, EventArgs e) + { + FolderBrowserDialog browse = new FolderBrowserDialog + { + ShowNewFolderButton = true, + Description = Resources.FrmSettings_BtnDatClick_Please_select_a_folder_for_DAT_Root, + RootFolder = Environment.SpecialFolder.DesktopDirectory, + SelectedPath = Settings.DatRoot + }; + + if (browse.ShowDialog() != DialogResult.OK) return; + + lblDATRoot.Text = Utils.RelativePath.MakeRelative(AppDomain.CurrentDomain.BaseDirectory, browse.SelectedPath); + } + + } +} diff --git a/ROMVault2/frmSettings.resx b/ROMVault2/frmSettings.resx new file mode 100644 index 0000000..5ea0895 --- /dev/null +++ b/ROMVault2/frmSettings.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/ROMVault2/frmShowError.Designer.cs b/ROMVault2/frmShowError.Designer.cs new file mode 100644 index 0000000..71d830b --- /dev/null +++ b/ROMVault2/frmShowError.Designer.cs @@ -0,0 +1,89 @@ +namespace ROMVault2 +{ + partial class frmShowError + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(frmShowError)); + this.textBox1 = new System.Windows.Forms.TextBox(); + this.button1 = new System.Windows.Forms.Button(); + this.label1 = new System.Windows.Forms.Label(); + this.SuspendLayout(); + // + // textBox1 + // + this.textBox1.Location = new System.Drawing.Point(12, 12); + this.textBox1.Multiline = true; + this.textBox1.Name = "textBox1"; + this.textBox1.ScrollBars = System.Windows.Forms.ScrollBars.Both; + this.textBox1.Size = new System.Drawing.Size(565, 525); + this.textBox1.TabIndex = 0; + // + // button1 + // + this.button1.Location = new System.Drawing.Point(460, 543); + this.button1.Name = "button1"; + this.button1.Size = new System.Drawing.Size(117, 28); + this.button1.TabIndex = 1; + this.button1.Text = "Exit"; + this.button1.UseVisualStyleBackColor = true; + this.button1.Click += new System.EventHandler(this.button1_Click); + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(20, 551); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(202, 13); + this.label1.TabIndex = 2; + this.label1.Text = "Sending Error Message to RomVault.Com"; + // + // frmShowError + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(589, 583); + this.Controls.Add(this.label1); + this.Controls.Add(this.button1); + this.Controls.Add(this.textBox1); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.Fixed3D; + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Name = "frmShowError"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "RomVault Error report"; + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.TextBox textBox1; + private System.Windows.Forms.Button button1; + private System.Windows.Forms.Label label1; + } +} \ No newline at end of file diff --git a/ROMVault2/frmShowError.cs b/ROMVault2/frmShowError.cs new file mode 100644 index 0000000..6e12bec --- /dev/null +++ b/ROMVault2/frmShowError.cs @@ -0,0 +1,29 @@ +/****************************************************** + * ROMVault2 is written by Gordon J. * + * Contact gordon@romvault.com * + * Copyright 2014 * + ******************************************************/ + +using System; +using System.Windows.Forms; + +namespace ROMVault2 +{ + public partial class frmShowError : Form + { + public frmShowError() + { + InitializeComponent(); + } + + public void settype(string s) + { + textBox1.Text = s; + } + + private void button1_Click(object sender, EventArgs e) + { + Environment.Exit(0); + } + } +} diff --git a/ROMVault2/frmShowError.resx b/ROMVault2/frmShowError.resx new file mode 100644 index 0000000..1e12950 --- /dev/null +++ b/ROMVault2/frmShowError.resx @@ -0,0 +1,1787 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + AAABAAUAEBAAAAAAIABoBAAAVgAAACAgAAAAACAAqBAAAL4EAAAwMAAAAAAgAKglAABmFQAAQEAAAAAA + IAAoQgAADjsAAICAAAAAACAAKAgBADZ9AAAoAAAAEAAAACAAAAABACAAAAAAAEAEAAAAAAAAAAAAAAAA + AAAAAAAA7e3tvevr6//m5ub/4ODg/9nZ2f/Q0ND/wsLC/66urv+ampr/nJyc/6Kiov+tra3/ubm5/8XF + xf/R0dH/2trapenp6b3l5eX/3t7e/9bW1v/Kysr/ubm5/5+fn/92dnb/ampq/21tbf97e3v/jIyM/56e + nv+wsLD/wsLC/8/Pz6Xl5eW939/f/9bW1v/Jycn/uLi4/5ycnP9ubm7/YWFh/2pqav8tLS3/RERE/2lp + af+AgID/mJiY/7Kysv/FxcWl39/fvdjY2P/Ly8v/ubm5/56env9ycnL/VlZW/2RkZP92dnb/IyMj/yAg + IP8qKir/VlZW/319ff+ioqL/v7+/pdnZ2b3Nzc3/u7u7/6Kiov94eHj/U1NT/15eXv99fX3/IiIi/yYm + Jv8lJSX/IyMj/yAgIP8+Pj7/hoaG/76+vqXQ0NC9wMDA/6ampv+AgID/U1NT/1tbW/+BgYH/ISEh/yUl + Jf8lJSX/JiYm/yYmJv8lJSX/IiIi/2BgYP/Dw8OlxsbGva6urv+Hh4f/VlZW/1paWv+BgYH/JCQk/yUl + Jf8kJCT/JSUl/yUlJf8mJib/JiYm/yQkJP91dXX/zc3Npby8vL2Wlpb/XV1d/1tbW/+AgID/JiYm/zs7 + O/9ubm7/YWFh/ykpKf8kJCT/JSUl/yUlJf9ZWVn/xcXF/9XV1aW4uLi9dXV1/2JiYv9/f3//Kysr/0BA + QP/FxcX/zMzM/8vLy/+hoaH/JCQk/yQkJP9NTU3/v7+//9LS0v/c3NylvLy8vXJycv9/f3//NjY2/yMj + I/9lZWX/zc3N/83Nzf/MzMz/ycnJ/ykpKf9DQ0P/uLi4/9DQ0P/c3Nz/4+PjpcDAwL1/f3//QkJC/yQi + Iv8jIyP/Li4u/6ioqP/MzMz/ysrK/3h4eP88PDz/s7Oz/8/Pz//b29v/4+Pj/+jo6KXR0dG9bm5u/yQi + Iv9hJRr/SCQd/0QkHv8yJCH/Ozs7/zExMf82Njb/r6+v/9HR0f/b29v/4+Pj/+jo6P/s7Oyl29vbvX9/ + f/8lJSX/PiMe/1okGv9dJBr/VSQc/zokIP8yMjL/rq6u/9XV1f/e3t7/5OTk/+np6f/t7e3/8PDwpeXl + 5b3f39//t7e3/2tra/8lJSX/RyMd/1QlHP8vLi7/ra2t/93d3f/j4+P/6Ojo/+vr6//u7u7/8fHx//Pz + 86Xs7Oy96enp/+bm5v/i4uL/n5+f/zY2Nv9JSUn/q6ur/+bm5v/p6en/7Ozs/+7u7v/w8PD/8vLy//T0 + 9P/19fWl8fHxvfDw8P/u7u7/7Ozs/+rq6v/g4OD/39/f/+zs7P/u7u7/7+/v//Hx8f/y8vL/9PT0//X1 + 9f/29vb/9/f3pQAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA + //8AAP//AAD//wAA//8oAAAAIAAAAEAAAAABACAAAAAAAIAQAAAAAAAAAAAAAAAAAAAAAAAA7+/vee7u + 7v/t7e3/6+vr/+np6f/n5+f/5OTk/+Hh4f/e3t7/29vb/9fX1//T09P/zc3N/8XFxf++vr7/uLi4/7Cw + sP+rq6v/qKio/6ioqP+rq6v/rq6u/7Kysv+4uLj/vb29/8LCwv/Hx8f/zMzM/9HR0f/X19f/3Nzc/9/f + 303t7e157Ozs/+rq6v/o6Oj/5ubm/+Pj4//g4OD/3Nzc/9jY2P/U1NT/z8/P/8jIyP/AwMD/tra2/6qq + qv+YmJj/goKC/42Njf+NjY3/kZGR/5aWlv+bm5v/oqKi/6qqqv+wsLD/tra2/729vf/Dw8P/ysrK/9HR + 0f/X19f/29vbTevr63nq6ur/6Ojo/+Xl5f/i4uL/3t7e/9vb2//W1tb/0tLS/8zMzP/ExMT/u7u7/7Gx + sf+jo6P/kJCQ/3Z2dv9mZmb/c3Nz/3R0dP96enr/gICA/4iIiP+RkZH/mZmZ/6Ghof+pqan/sbGx/7m5 + uf/CwsL/ysrK/9HR0f/W1tZN6enpeefn5//l5eX/4uLi/97e3v/a2tr/1dXV/9DQ0P/Kysr/wsLC/7m5 + uf+tra3/n5+f/4mJif9ra2v/aWlp/29vb/9hYWH/YWFh/2dnZ/9tbW3/dXV1/35+fv+IiIj/kpKS/5yc + nP+lpaX/r6+v/7m5uf/CwsL/y8vL/9HR0U3n5+d55eXl/+Li4v/f39//29vb/9bW1v/Q0ND/ycnJ/8LC + wv+4uLj/ra2t/52dnf+IiIj/a2tr/0tLS/9oaGj/enp6/1hYWP9ERET/Ly8v/1NTU/9kZGT/bW1t/3d3 + d/+CgoL/jY2N/5iYmP+kpKT/sLCw/7u7u//Gxsb/zMzMTeXl5Xnj4+P/39/f/9vb2//X19f/0dHR/8rK + yv/BwcH/uLi4/62trf+enp7/iYmJ/2tra/9bW1v/WFhY/3h4eP91dXX/X19f/yAgIP8iIiL/Hx8f/zk5 + Of9aWlr/Z2dn/3Jycv9+fn7/i4uL/5mZmf+np6f/tbW1/8HBwf/JyclN4uLieeDg4P/c3Nz/2NjY/9LS + 0v/Kysr/wsLC/7i4uP+tra3/n5+f/4uLi/9tbW3/Q0ND/11dXf9dXV3/aWlp/5WVlf+QkJD/IiIi/yEh + If8eHh7/Hh4e/yQkJP9HR0f/YmJi/29vb/99fX3/jIyM/52dnf+vr6//vr6+/8fHx03g4OB53d3d/9jY + 2P/T09P/zMzM/8PDw/+5ubn/rq6u/6CgoP+MjIz/cnJy/19fX/9NTU3/ampq/3d3d/9TU1P/jo6O/yYm + Jv8jIyP/JiYm/yQkJP8hISH/Hh4e/x4eHv8wMDD/WFhY/21tbf99fX3/kpKS/6mpqf+8vLz/xsbGTd7e + 3nna2tr/1NTU/83Nzf/ExMT/u7u7/6+vr/+hoaH/j4+P/3V1df9HR0f/Wlpa/1ZWVv9paWn/fn5+/5ub + m/8dHR3/IyMj/yYmJv8mJib/JiYm/yUlJf8jIyP/Hx8f/x4eHv8hISH/QEBA/2xsbP+IiIj/o6Oj/7u7 + u//Hx8dN2traedXV1f/Ozs7/xsbG/7y8vP+xsbH/pKSk/5KSkv97e3v/ZGRk/0pKSv9gYGD/dXV1/0JC + Qv+qqqr/MjIy/yMjI/8mJib/JiYm/yYmJv8mJib/JiYm/yUlJf8lJSX/ISEh/x8fH/8fHx//LS0t/1JS + Uv+cnJz/u7u7/8fHx03W1tZ50dHR/8nJyf+/v7//s7Oz/6ampv+UlJT/fX19/01NTf9ZWVn/WFhY/2ho + aP9ubm7/mJiY/xsbG/8hISH/JSUl/yUlJf8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8lJSX/JCQk/yEh + If8gICD/KSkp/5ycnP++vr7/ycnJTdLS0nnMzMz/wsLC/7a2tv+pqan/l5eX/4KCgv9sbGz/SkpK/1tb + W/91dXX/Nzc3/7W1tf9HR0f/IiIi/yQkJP8lJSX/JSUl/yUlJf8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JSUl/yMjI/8jIyP/mJiY/8XFxf/MzMxNzs7OecfHx/+7u7v/ra2t/5ubm/+Ghob/WVlZ/1lZ + Wf9dXV3/ZWVl/2hoaP+Kior/KSkp/yEhIf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JSUl/zIyMv+goKD/ysrK/9DQ0E3Kysp5wcHB/7Kysv+goKD/ioqK/3Jy + cv9PT0//V1dX/3V1df8zMzP/q6ur/2ZmZv8gICD/JCQk/yUlJf8lJSX/JCQk/yQkJP8kJCT/JSUl/yUl + Jf8lJSX/JiYm/yYmJv8mJib/JiYm/yYmJv8hISH/Q0ND/76+vv/Nzc3/09PTTcXFxXm7u7v/qKio/5GR + kf9mZmb/Xl5e/2JiYv9eXl7/bGxs/3d3d/82Njb/Hx8f/yQkJP8kJCT/JSUl/ycnJ/8lJSX/JCQk/yQk + JP8kJCT/JSUl/yUlJf8lJSX/JSUl/yYmJv8mJib/Kioq/1hYWP+3t7f/ycnJ/9HR0f/X19dNwsLCebW1 + tf+enp7/gYGB/1hYWP9WVlb/dXV1/zg4OP+UlJT/ioqK/x8fH/8kJCT/LCws/3l5ef+tra3/v7+//7S0 + tP+IiIj/OTk5/yQkJP8kJCT/JCQk/yUlJf8lJSX/JSUl/yQkJP8xMTH/sbGx/8bGxv/Ozs7/1tbW/9ra + 2k3BwcF5srKy/4iIiP9xcXH/bGxs/1tbW/92dnb/YWFh/05OTv8eHh7/IyMj/zMzM/+wsLD/zMzM/8vL + y//Ly8v/zMzM/8vLy//BwcH/SkpK/yMjI/8kJCT/JCQk/yUlJf8oKCj/QkJC/6qqqv/ExMT/zMzM/9PT + 0//Z2dn/3d3dTcLCwnm0tLT/enp6/2FhYf97e3v/SEhI/319ff+np6f/ISEh/yEhIf8jIyP/iIiI/8zM + zP/MzMz/zc3N/83Nzf/MzMz/y8vL/8rKyv+vr6//JSUl/yQkJP8kJCT/IyMj/yUlJf+lpaX/w8PD/8vL + y//R0dH/19fX/93d3f/g4OBNw8PDebm5uf+JiYn/Y2Nj/4GBgf9WVlb/Y2Nj/ykpKf8hISH/IyMj/yQk + JP+wsLD/zc3N/83Nzf/Nzc3/zc3N/8zMzP/Ly8v/y8vL/8zMzP8zMzP/JCQk/yUlJf8zMzP/lpaW/8HB + wf/Kysr/0dHR/9fX1//c3Nz/4ODg/+Pj403FxcV5tra2/4aGhv9WVlb/bm5u/7i4uP8rKyv/ISEh/yQk + JP8kJCT/JCQk/52dnf/Nzc3/zc3N/83Nzf/Nzc3/zMzM/8zMzP/Ly8v/wcHB/yoqKv8jIyP/ICAg/5aW + lv/AwMD/ycnJ/9DQ0P/X19f/3Nzc/+Dg4P/k5OT/5ubmTcnJyXm2trb/jY2N/1JSUv9zc3P/PDw8/yEh + If8jIyP/IyMj/yMjI/8kJCT/T09P/8nJyf/Nzc3/zc3N/83Nzf/Nzc3/zMzM/8vLy/95eXn/JCQk/ygo + KP+Dg4P/wMDA/8jIyP/Q0ND/1tbW/9vb2//g4OD/4+Pj/+bm5v/o6OhNzc3NecDAwP9nZ2f/tLS0/zw8 + PP8eHh7/IiIi/ysiIf8iIiL/IyMj/yMjI/8jIyP/VlZW/7e3t//MzMz/zc3N/8zMzP/ExMT/d3d3/yYm + Jv8dHR3/h4eH/8HBwf/Jycn/0NDQ/9bW1v/b29v/39/f/+Pj4//m5ub/6enp/+vr603S0tJ5zMzM/6mp + qf9VVVX/ICAg/yMjI/84Ix//ayYa/yIiIf8qIiH/NCMg/zQjIP8jIyP/JiYm/0hISP9dXV3/UVFR/y0t + Lf8jIyP/IiIi/2tra//BwcH/ysrK/9HR0f/W1tb/29vb/9/f3//j4+P/5ubm/+np6f/r6+v/7e3tTdfX + 13nS0tL/kpKS/ygoKP8jIyP/KyIg/3omF/9mJRn/cyYY/14lGv9TJRz/UyUc/1ckG/8oIyH/IyMj/yMj + I/8jIyP/IyMj/x0dHf93d3f/xMTE/8vLy//S0tL/19fX/9vb2//f39//4+Pj/+bm5v/o6Oj/6+vr/+3t + 7f/u7u5N29vbedfX1/+FhYX/IyMj/yMjI/8jISH/TyQc/2QkGP9yJhj/WyQa/2slGf86Ix7/XCUb/2Ml + G/8+Ix//JSMi/yMjI/8hISH/VVVV/8bGxv/Ozs7/1NTU/9nZ2f/d3d3/4ODg/+Pj4//m5ub/6Ojo/+vr + 6//t7e3/7+/v//Dw8E3g4OB53d3d/9PT0/9/f3//LCws/yIiIv8hISH/ISEh/0UjHf9XIxr/bCUY/2El + Gv8/Ix7/VSQc/10mG/8nIyL/Hx8f/2VlZf/Kysr/09PT/9fX1//b29v/39/f/+Li4v/l5eX/5+fn/+np + 6f/r6+v/7e3t/+/v7//w8PD/8fHxTeTk5Hni4uL/3t7e/9vb2//Dw8P/YGBg/yQkJP8iIiL/ISEh/yEh + If9fJRr/ZSUZ/1IkHP9eJRv/JSMi/yIiIv9AQED/ysrK/9jY2P/b29v/39/f/+Li4v/l5eX/5+fn/+np + 6f/q6ur/7Ozs/+7u7v/v7+//8fHx//Ly8v/z8/NN6Ojoeebm5v/k5OT/4eHh/9/f3//c3Nz/v7+//6io + qP8vLy//IiIi/yEhIf81IyD/ZiYa/zskIP8gICD/VFRU/83Nzf/d3d3/4ODg/+Pj4//l5eX/5+fn/+np + 6f/r6+v/7Ozs/+3t7f/v7+//8PDw//Hx8f/y8vL/8/Pz//T09E3s7Ox56+vr/+np6f/n5+f/5OTk/+Li + 4v/h4eH/39/f/5aWlv8wMDD/IiIi/yIiIv8jIyP/IiIi/ywsLP/Gxsb/4uLi/+Tk5P/m5ub/6Ojo/+np + 6f/r6+v/7Ozs/+7u7v/v7+//8PDw//Hx8f/y8vL/8/Pz//Pz8//09PT/9fX1Te7u7nnt7e3/7Ozs/+vr + 6//p6en/6Ojo/+bm5v/k5OT/4+Pj/9PT0/9vb2//JiYm/y0tLf+ysrL/1NTU/+bm5v/n5+f/6enp/+rq + 6v/s7Oz/7e3t/+7u7v/v7+//8PDw//Hx8f/y8vL/8vLy//Pz8//09PT/9fX1//X19f/29vZN8fHxefDw + 8P/v7+//7u7u/+3t7f/s7Oz/6urq/+np6f/o6Oj/6Ojo/+jo6P++vr7/urq6/+np6f/q6ur/6+vr/+vr + 6//t7e3/7u7u/+/v7//v7+//8PDw//Hx8f/y8vL/8/Pz//Pz8//09PT/9PT0//X19f/29vb/9vb2//f3 + 903z8/N58vLy//Hx8f/w8PD/8PDw/+/v7//u7u7/7e3t/+3t7f/s7Oz/7e3t/+3t7f/t7e3/7e3t/+3t + 7f/u7u7/7+/v//Dw8P/w8PD/8fHx//Ly8v/y8vL/8/Pz//T09P/09PT/9fX1//X19f/29vb/9vb2//f3 + 9//39/f/9/f3TQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAKAAAADAAAABgAAAAAQAgAAAAAACAJQAAAAAAAAAAAAAAAAAAAAAAAPDw + 8Dfv7+//7u7u/+3t7f/s7Oz/6+vr/+rq6v/p6en/5+fn/+Xl5f/j4+P/4eHh/9/f3//d3d3/29vb/9nZ + 2f/X19f/1NTU/9DQ0P/Ly8v/x8fH/8LCwv++vr7/urq6/7a2tv+xsbH/rq6u/62trf+srKz/rKys/62t + rf+vr6//sbGx/7S0tP+3t7f/u7u7/76+vv/BwcH/xcXF/8jIyP/Ly8v/z8/P/9LS0v/V1dX/2NjY/9zc + 3P/f39/x////Ae7u7jfu7u7/7e3t/+zs7P/r6+v/6enp/+jo6P/m5ub/5eXl/+Pj4//g4OD/3t7e/9zc + 3P/Z2dn/19fX/9TU1P/R0dH/zc3N/8jIyP/CwsL/vLy8/7e3t/+xsbH/qqqq/6Ojo/+enp7/nJyc/5ub + m/+cnJz/np6e/6CgoP+jo6P/pqam/6qqqv+urq7/srKy/7a2tv+6urr/vr6+/8HBwf/FxcX/ycnJ/83N + zf/R0dH/1dXV/9nZ2f/c3Nzx////Ae3t7Tfs7Oz/6+vr/+rq6v/p6en/6Ojo/+bm5v/k5OT/4uLi/+Dg + 4P/d3d3/29vb/9jY2P/V1dX/0tLS/87Ozv/Kysr/xMTE/7+/v/+5ubn/sbGx/6ioqP+fn5//ioqK/21t + bf+Ghob/iIiI/4iIiP+Li4v/jo6O/5GRkf+VlZX/mZmZ/56env+kpKT/qKio/62trf+xsbH/tbW1/7q6 + uv++vr7/w8PD/8jIyP/MzMz/0dHR/9XV1f/Z2dnx////Aezs7Dfr6+v/6urq/+jo6P/n5+f/5eXl/+Pj + 4//h4eH/39/f/9zc3P/Z2dn/19fX/9TU1P/Q0ND/zMzM/8fHx//CwsL/vLy8/7a2tv+urq7/pKSk/5iY + mP+MjIz/cHBw/2JiYv9zc3P/dnZ2/3d3d/96enr/fn5+/4ODg/+Hh4f/jIyM/5KSkv+YmJj/nZ2d/6Oj + o/+oqKj/ra2t/7Kysv+3t7f/vb29/8LCwv/Hx8f/zMzM/9HR0f/W1tbx////Aerq6jfp6en/6Ojo/+fn + 5//l5eX/4+Pj/+Hh4f/e3t7/3Nzc/9nZ2f/W1tb/09PT/8/Pz//Ly8v/xsbG/8DAwP+6urr/s7Oz/6ur + q/+hoaH/lJSU/4WFhf94eHj/ampq/2hoaP9oaGj/ZmZm/2hoaP9tbW3/cXFx/3V1df96enr/f39//4aG + hv+MjIz/kpKS/5iYmP+enp7/pKSk/6qqqv+wsLD/tra2/7y8vP/CwsL/x8fH/83Nzf/S0tLx////Aenp + 6Tfo6Oj/5ubm/+Xl5f/j4+P/4eHh/9/f3//c3Nz/2dnZ/9bW1v/S0tL/zs7O/8rKyv/FxcX/v7+//7i4 + uP+xsbH/qamp/5+fn/+RkZH/f39//2BgYP9nZ2f/aGho/29vb/9vb2//W1tb/11dXf9hYWH/ZWVl/2lp + af9ubm7/c3Nz/3p6ev+AgID/h4eH/42Njf+UlJT/m5ub/6Ghof+oqKj/r6+v/7W1tf+8vLz/wsLC/8nJ + yf/Ozs7x////Aejo6Dfn5+f/5eXl/+Pj4//h4eH/39/f/9zc3P/Z2dn/1tbW/9LS0v/Ozs7/ycnJ/8TE + xP+/v7//uLi4/7Gxsf+oqKj/nZ2d/5CQkP+AgID/ZmZm/0pKSv9XV1f/a2tr/3R0dP9xcXH/UlJS/1NT + U/84ODj/PT09/1tbW/9jY2P/aGho/25ubv91dXX/fHx8/4ODg/+Kior/kZGR/5mZmf+goKD/qKio/6+v + r/+3t7f/vr6+/8XFxf/Ly8vx////Aefn5zfm5ub/4+Pj/+Hh4f/f39//3Nzc/9ra2v/W1tb/09PT/87O + zv/Jycn/xMTE/76+vv+4uLj/sLCw/6ioqP+enp7/kJCQ/4GBgf9vb2//Xl5e/01NTf9VVVX/cXFx/42N + jf9xcXH/S0tL/zExMf8gICD/Hh4e/ygoKP9JSUn/XV1d/2NjY/9paWn/cXFx/3h4eP+AgID/iIiI/5CQ + kP+YmJj/oKCg/6mpqf+ysrL/urq6/8LCwv/Jycnx////AeXl5Tfk5OT/4uLi/9/f3//d3d3/2tra/9fX + 1//T09P/z8/P/8rKyv/FxcX/v7+//7i4uP+xsbH/qKio/5+fn/+RkZH/gYGB/2ZmZv9eXl7/WVlZ/2Nj + Y/9aWlr/i4uL/2tra/93d3f/VFRU/x0dHf8kJCT/Hh4e/x4eHv8eHh7/MjIy/1JSUv9eXl7/ZmZm/25u + bv91dXX/fn5+/4eHh/+QkJD/mZmZ/6Ojo/+tra3/tra2/7+/v//Gxsbx////AePj4zfi4uL/4ODg/93d + 3f/b29v/2NjY/9TU1P/Pz8//ysrK/8XFxf+/v7//uLi4/7Gxsf+pqan/n5+f/5OTk/+CgoL/ampq/0ZG + Rv9ISEj/YWFh/2VlZf9dXV3/cHBw/3Jycv/CwsL/jIyM/yQkJP8fHx//Hx8f/x4eHv8eHh7/HR0d/yEh + If8+Pj7/Wlpa/2NjY/9ra2v/dHR0/319ff+Hh4f/kZGR/5ycnP+np6f/s7Oz/7y8vP/FxcXx////AeLi + 4jfg4OD/3t7e/9vb2//Y2Nj/1dXV/9HR0f/Ly8v/xsbG/8DAwP+5ubn/srKy/6mpqf+fn5//kpKS/4SE + hP9zc3P/YWFh/0RERP9FRUX/ampq/3x8fP9WVlb/Xl5e/7e3t/+zs7P/KCgo/yIiIv8kJCT/JiYm/yIi + Iv8fHx//Hh4e/x4eHv8eHh7/KSkp/0xMTP9hYWH/ampq/3Nzc/99fX3/iIiI/5SUlP+ioqL/r6+v/7u7 + u//ExMTx////AeDg4Dff39//3Nzc/9nZ2f/V1dX/0dHR/8zMzP/Hx8f/wcHB/7q6uv+ysrL/qqqq/6Gh + of+Tk5P/hISE/3BwcP9lZWX/W1tb/15eXv9GRkb/fHx8/39/f/9hYWH/RERE/4iIiP8uLi7/IiIi/yMj + I/8lJSX/JiYm/yUlJf8kJCT/ISEh/x8fH/8eHh7/Hh4e/x8fH/83Nzf/Wlpa/2dnZ/9xcXH/fX19/42N + jf+cnJz/q6ur/7m5uf/ExMTx////Ad/f3zfd3d3/2tra/9bW1v/R0dH/zc3N/8fHx//BwcH/u7u7/7Oz + s/+rq6v/oaGh/5aWlv+Hh4f/c3Nz/0pKSv9LS0v/XFxc/2ZmZv9GRkb/hISE/2JiYv+dnZ3/mpqa/xwc + HP8cHBz/IyMj/yYmJv8mJib/JSUl/yYmJv8mJib/JSUl/yMjI/8fHx//Hx8f/x4eHv8eHh7/JSUl/0VF + Rf9jY2P/dHR0/4aGhv+YmJj/qamp/7i4uP/ExMTx////Ad3d3Tfb29v/19fX/9LS0v/Ozs7/yMjI/8LC + wv+8vLz/tLS0/6ysrP+jo6P/l5eX/4mJif94eHj/ZmZm/0hISP9DQ0P/ZWVl/3Jycv89PT3/V1dX/5aW + lv/a2tr/Pj4+/yIiIv8kJCT/JiYm/yYmJv8lJSX/JSUl/yYmJv8lJSX/JiYm/yUlJf8kJCT/ISEh/x8f + H/8fHx//Hx8f/x8fH/8xMTH/YWFh/3BwcP+Li4v/paWl/7e3t//ExMTx////Advb2zfY2Nj/1NTU/8/P + z//Jycn/xMTE/729vf+1tbX/ra2t/6SkpP+ZmZn/jIyM/3t7e/9ra2v/X19f/1ZWVv9CQkL/cHBw/42N + jf9OTk7/ODg4/7S0tP9JSUn/IyMj/yIiIv8mJib/JiYm/yYmJv8lJSX/JiYm/yYmJv8mJib/JiYm/yYm + Jv8lJSX/JSUl/yMjI/8gICD/Hx8f/yAgIP8gICD/IiIi/zk5Of91dXX/paWl/7e3t//FxcXx////AdjY + 2DfV1dX/0NDQ/8vLy//FxcX/v7+//7e3t/+vr6//paWl/5ubm/+NjY3/fX19/1RUVP9OTk7/W1tb/2Rk + ZP8/Pz//i4uL/1xcXP+FhYX/h4eH/xsbG/8eHh7/ISEh/yUlJf8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8lJSX/IiIi/yAgIP8gICD/ICAg/yAgIP9jY2P/pqam/7q6 + uv/Gxsbx////AdXV1TfT09P/zc3N/8fHx//AwMD/ubm5/7CwsP+np6f/nJyc/4+Pj/+AgID/b29v/01N + Tf9AQED/YWFh/2xsbP83Nzf/VlZW/319ff/Y2Nj/aWlp/yEhIf8fHx//JCQk/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yYmJv8lJSX/JiYm/yUlJf8lJSX/JiYm/yUlJf8lJSX/JSUl/yUlJf8gICD/ICAg/yAg + IP9YWFj/paWl/7+/v//IyMjx////AdPT0zfQ0ND/ysrK/8PDw/+7u7v/srKy/6mpqf+enp7/kZGR/4SE + hP90dHT/ZWVl/1RUVP8/Pz//aWlp/4qKiv9LS0v/NjY2/7u7u/+BgYH/JCQk/yEhIf8kJCT/JSUl/yQk + JP8lJSX/JSUl/yUlJf8lJSX/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8lJSX/JCQk/yAgIP9TU1P/paWl/8PDw//Ly8vx////AdDQ0DfNzc3/xsbG/76+vv+2trb/rKys/6Gh + of+UlJT/hoaG/2VlZf9VVVX/XV1d/2NjY/89PT3/hISE/2tra/9ubm7/YmJi/zY2Nv8jIyP/IiIi/yYm + Jv8lJSX/JCQk/yUlJf8lJSX/JCQk/yUlJf8lJSX/JSUl/yUlJf8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8lJSX/JiYm/yYmJv8lJSX/JiYm/yYmJv9sbGz/qKio/8fHx//Ozs7x////Ac3NzTfJycn/wsLC/7m5 + uf+vr6//pKSk/5eXl/+IiIj/dnZ2/1RUVP9BQUH/Xl5e/2pqav83Nzf/YWFh/2pqav+5ubn/pqam/yAg + IP8bGxv/IyMj/yQkJP8kJCT/JSUl/yUlJf8kJCT/JCQk/yQkJP8lJSX/JSUl/yUlJf8lJSX/JiYm/yUl + Jf8mJib/JiYm/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/xoaGv9iYmL/u7u7/8rKyv/Q0NDx////AcvL + yzfGxsb/vr6+/7Ozs/+np6f/mpqa/4uLi/96enr/bGxs/1hYWP8+Pj7/ZGRk/35+fv9UVFT/NjY2/6en + p/+4uLj/Jycn/yEhIf8iIiL/JCQk/yUlJf8lJSX/JSUl/yQkJP8kJCT/JCQk/yQkJP8lJSX/JSUl/yUl + Jf8lJSX/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8lJSX/HBwc/zU1Nf+vr6//xsbG/83N + zf/S0tLx////AcjIyDfDw8P/ubm5/62trf+goKD/kJCQ/3Z2dv9cXFz/Y2Nj/2NjY/9GRkb/cHBw/4GB + gf9dXV3/R0dH/0FBQf8wMDD/ICAg/yMjI/8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8jIyP/JCQk/yQk + JP8kJCT/JCQk/yUlJf8lJSX/JSUl/yUlJf8lJSX/JiYm/yYmJv8lJSX/JiYm/yUlJf81NTX/Pz8//6mp + qf/ExMT/ysrK/8/Pz//V1dXx////AcbGxjfAwMD/tbW1/6ampv+Xl5f/g4OD/2JiYv9FRUX/X19f/2pq + av9BQUH/bm5u/1xcXP+VlZX/zc3N/yIiIv8YGBj/IyMj/yQkJP8kJCT/KCgo/0VFRf9jY2P/a2tr/11d + Xf89PT3/JiYm/yMjI/8jIyP/JCQk/yQkJP8lJSX/JCQk/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yAg + IP9HR0f/q6ur/8HBwf/Hx8f/zc3N/9LS0v/X19fx////AcTExDe+vr7/sbGx/6Kiov+Pj4//enp6/2Nj + Y/9AQED/Y2Nj/3Z2dv9eXl7/MTEx/4qKiv/Z2dn/Ozs7/yEhIf8kJCT/JCQk/yQkJP9kZGT/srKy/8rK + yv/Ly8v/zMzM/8zMzP/Kysr/qKio/1NTU/8kJCT/JCQk/yQkJP8kJCT/JSUl/yQkJP8lJSX/JSUl/yUl + Jf8lJSX/IyMj/x0dHf+YmJj/wMDA/8bGxv/Ly8v/0NDQ/9XV1f/a2trx////AcTExDe9vb3/rq6u/5ub + m/92dnb/eXl5/2xsbP9VVVX/Y2Nj/5GRkf9XV1f/Nzc3/09PT/9OTk7/ICAg/yIiIv8kJCT/KSkp/4+P + j//MzMz/zMzM/8vLy//Ly8v/zMzM/8zMzP/MzMz/y8vL/8nJyf9/f3//JCQk/yMjI/8kJCT/JCQk/yQk + JP8kJCT/JSUl/yUlJf8rKyv/ISEh/5GRkf+/v7//xcXF/8rKyv/Pz8//09PT/9jY2P/c3Nzx////AcTE + xDe9vb3/rq6u/4qKiv9SUlL/cHBw/3Jycv9UVFT/b29v/1paWv9+fn7/y8vL/y4uLv8bGxv/Hx8f/yMj + I/8kJCT/d3d3/8rKyv/Ly8v/zMzM/8zMzP/MzMz/zMzM/8zMzP/Ly8v/ysrK/8rKyv/Jycn/Y2Nj/yMj + I/8jIyP/JCQk/yQkJP8kJCT/JCQk/yQkJP8/Pz//mpqa/729vf/Dw8P/ycnJ/83Nzf/S0tL/1tbW/9ra + 2v/e3t7x////AcTExDe/v7//sbGx/42Njf9MTEz/cHBw/3p6ev9qamr/OTk5/3V1df/Q0ND/bW1t/yAg + IP8fHx//IyMj/yQkJP8xMTH/wMDA/8zMzP/MzMz/zc3N/83Nzf/Nzc3/zc3N/8zMzP/Ly8v/y8vL/8rK + yv/Ly8v/srKy/ygoKP8kJCT/JCQk/yQkJP8kJCT/IiIi/xMTE/95eXn/u7u7/8PDw//IyMj/zc3N/9HR + 0f/W1tb/2dnZ/9zc3P/g4ODx////AcXFxTfAwMD/tbW1/5KSkv9qamr/ZWVl/5KSkv9lZWX/Ojo6/2ho + aP98fHz/ICAg/x8fH/8jIyP/JCQk/yQkJP9NTU3/zc3N/83Nzf/MzMz/zc3N/83Nzf/Nzc3/zc3N/83N + zf/MzMz/y8vL/8vLy//MzMz/y8vL/zg4OP8kJCT/JCQk/yQkJP8mJib/FRUV/29vb/+4uLj/wcHB/8fH + x//Nzc3/0dHR/9XV1f/Z2dn/3Nzc/9/f3//i4uLx////AcbGxjfBwcH/t7e3/4uLi/9vb2//aGho/29v + b/9paWn/srKy/zw8PP8jIyP/ICAg/yQkJP8jIyP/JCQk/yMjI/9MTEz/zMzM/8zMzP/MzMz/zMzM/83N + zf/Nzc3/zc3N/8zMzP/MzMz/zMzM/8zMzP/MzMz/y8vL/zs7O/8jIyP/JCQk/yQkJP85OTn/gICA/7m5 + uf/AwMD/xsbG/8zMzP/R0dH/1dXV/9jY2P/b29v/39/f/+Hh4f/k5OTx////AcfHxzfDw8P/r6+v/4WF + hf99fX3/Pj4+/2VlZf+xsbH/qamp/yAgIP8fHx//JCQk/yQkJP8jIyP/JCQk/yQkJP8xMTH/wMDA/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/MzMz/zMzM/8vLy//Ly8v/tra2/ykpKf8jIyP/IyMj/xIS + Ev9dXV3/tbW1/8DAwP/Gxsb/zMzM/9DQ0P/V1dX/2NjY/9zc3P/f39//4eHh/+Tk5P/m5ubx////AcnJ + yTfGxsb/rq6u/5CQkP+AgID/ODg4/3p6ev+tra3/JSUl/yAgIP8jIyP/IyMj/yMjI/8jIyP/IyMj/yQk + JP8kJCT/fn5+/83Nzf/MzMz/zc3N/83Nzf/MzMz/zc3N/83Nzf/MzMz/zMzM/8vLy//Kysr/bm5u/yQk + JP8kJCT/FhYW/01NTf+ysrL/wMDA/8bGxv/Ly8v/0NDQ/9TU1P/Y2Nj/29vb/9/f3//h4eH/4+Pj/+Xl + 5f/n5+fx////AczMzDfJycn/tLS0/4mJif9ZWVn/kZGR/05OTv8uLi7/Hx8f/yEhIf8iIiL/IiIi/yIi + Iv8iIiL/IyMj/yMjI/8jIyP/Kysr/5iYmP/MzMz/zMzM/83Nzf/MzMz/zMzM/8zMzP/MzMz/zMzM/8vL + y/+QkJD/Jycn/yMjI/81NTX/ZGRk/7S0tP/BwcH/xsbG/8vLy//Q0ND/1NTU/9jY2P/b29v/3t7e/+Hh + 4f/j4+P/5eXl/+fn5//p6enx////Ac/PzzfMzMz/vb29/11dXf+Ojo7/zs7O/zExMf8cHBz/ISEh/yIi + Iv8iIiL/NSIf/yIiIv8jIyP/IyMj/yMjI/8jIyP/IyMj/ygoKP9xcXH/vb29/8zMzP/Nzc3/zc3N/83N + zf/MzMz/ubm5/2pqav8nJyf/IyMj/xkZGf88PDz/ra2t/8HBwf/Gxsb/y8vL/9DQ0P/U1NT/2NjY/9vb + 2//e3t7/4ODg/+Pj4//l5eX/5+fn/+np6f/q6urx////AdLS0jfPz8//ysrK/62trf/Nzc3/OTk5/x8f + H/8hISH/IyMj/yIiIv9ZJBv/dCcZ/yIiIf8iIiL/IyMj/yMjI/8oIiH/IyIi/yMjI/8jIyP/Kysr/1NT + U/9vb2//fHx8/29vb/9OTk7/Kioq/yMjI/8jIyP/Gxsb/yoqKv+oqKj/wsLC/8fHx//MzMz/0NDQ/9TU + 1P/Y2Nj/29vb/97e3v/g4OD/4uLi/+Xl5f/n5+f/6enp/+rq6v/s7Ozx////AdXV1TfT09P/zs7O/7e3 + t/9CQkL/IiIi/yIiIv8kJCT/IiIi/00jHP+oKhP/SiMc/0MiHP9xJhj/WiQa/1wlG/9+KBj/LSMh/zEj + IP8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/JCQk/yMjI/8vLy//TExM/6mpqf/Dw8P/yMjI/83N + zf/R0dH/1dXV/9jY2P/b29v/3t7e/+Dg4P/j4+P/5eXl/+fn5//o6Oj/6urq/+zs7P/t7e3x////AdnZ + 2TfW1tb/0tLS/7y8vP8zMzP/IyMj/yMjI/8iIiL/NyIe/50pFP8tIR//bSYZ/4knFv85Ix//TyQc/y4i + If9gJhv/XiUb/3ImGP9BIx7/KCMh/yMjI/8jIyP/IyMj/yMjI/8kJCT/IyMj/x4eHv8lJSX/o6Oj/8XF + xf/Kysr/zs7O/9LS0v/W1tb/2dnZ/9zc3P/e3t7/4ODg/+Pj4//l5eX/5+fn/+jo6P/q6ur/6+vr/+3t + 7f/u7u7x////Adzc3DfZ2dn/1dXV/7Gxsf8lJSX/IyMj/yMjI/8iIiL/JCEh/1gkG/97Jhb/aCQX/34n + F/95Jhf/aiUZ/3wmF/88Ix7/UCQc/20mGf9oJhr/bSYZ/zIjIP8iIiL/IyMj/yMjI/8jIyP/ISEh/xkZ + Gf+YmJj/yMjI/8zMzP/Q0ND/1NTU/9fX1//a2tr/3d3d/9/f3//h4eH/4+Pj/+Xl5f/n5+f/6Ojo/+rq + 6v/r6+v/7e3t/+7u7v/v7+/x////Ad/f3zfd3d3/2dnZ/8fHx/9OTk7/JCQk/yMjI/8iIiL/IiIi/yEh + If8pISD/QSMd/0QjHf9pJRn/ISAg/3QlF/9DIx3/WCQb/ywiIP84Ix//aiYa/2UmGv9TJRz/IiIi/yIi + Iv8rKyv/Pj4+/5WVlf/Ly8v/z8/P/9LS0v/V1dX/2dnZ/9zc3P/e3t7/4ODg/+Li4v/k5OT/5eXl/+fn + 5//p6en/6urq/+vr6//t7e3/7u7u/+/v7//w8PDx////AeHh4Tfg4OD/3d3d/9ra2v/V1dX/k5OT/zc3 + N/8iIiL/IiIi/yIiIv8hISH/ISEh/yQhIP9oJRn/cSQX/2glGf+EJxb/PiMe/0kjHP9BIx7/YiUa/28m + Gf8kIyL/IyMj/yIiIv8cHBz/kJCQ/87Ozv/S0tL/1dXV/9jY2P/b29v/3d3d/+Dg4P/i4uL/5OTk/+Xl + 5f/n5+f/6Ojo/+np6f/r6+v/7Ozs/+3t7f/u7u7/7+/v//Dw8P/x8fHx////AeTk5Dfj4+P/4ODg/97e + 3v/b29v/2dnZ/8vLy/91dXX/Kioq/yIiIv8iIiL/IiIi/yEhIf8hISH/ISEg/1wkGv90Jhj/QyIc/4An + F/8mIiH/ZyYa/ygjIv8jIyP/JCQk/xQUFP99fX3/0dHR/9bW1v/Y2Nj/2tra/93d3f/f39//4uLi/+Tk + 5P/l5eX/5+fn/+jo6P/p6en/6urq/+vr6//s7Oz/7u7u/+/v7//w8PD/8PDw//Hx8f/y8vLx////Aefn + 5zfm5ub/4+Pj/+Hh4f/g4OD/3t7e/9zc3P/Z2dn/t7e3/1paWv9PT0//NTU1/yIiIv8hISH/ISEh/yEh + If9UJBz/iSgW/0QjHf9yJhj/VCYd/yMjIv8nJyf/Nzc3/3Z2dv/S0tL/2dnZ/9vb2//e3t7/4ODg/+Li + 4v/k5OT/5eXl/+fn5//o6Oj/6enp/+rq6v/r6+v/7Ozs/+3t7f/u7u7/7+/v//Dw8P/x8fH/8vLy//Ly + 8v/z8/Px////Aenp6Tfp6en/5+fn/+Xl5f/j4+P/4uLi/+Dg4P/e3t7/3d3d/9vb2//a2tr/ysrK/0BA + QP8iIiL/IiIi/yIiIv8iIiL/KCIh/2snGv9RJR7/IyMi/yIiIv8bGxv/eXl5/9bW1v/d3d3/39/f/+Dg + 4P/i4uL/5OTk/+bm5v/n5+f/6Ojo/+np6f/q6ur/6+vr/+zs7P/t7e3/7u7u/+/v7//w8PD/8PDw//Hx + 8f/y8vL/8/Pz//Pz8//09PTx////Aezs7Dfr6+v/6urq/+jo6P/n5+f/5eXl/+Tk5P/j4+P/4eHh/+Dg + 4P/f39//3t7e/5SUlP8rKyv/IiIi/yIiIv8iIiL/IiIi/yMjI/8iIiL/IyMj/xYWFv9SUlL/1dXV/+Hh + 4f/i4uL/4+Pj/+Xl5f/m5ub/5+fn/+np6f/q6ur/6+vr/+zs7P/t7e3/7e3t/+7u7v/v7+//7+/v//Dw + 8P/x8fH/8vLy//Ly8v/z8/P/8/Pz//T09P/19fXx////Ae3t7Tft7e3/7Ozs/+vr6//q6ur/6enp/+fn + 5//m5ub/5eXl/+Tk5P/j4+P/4uLi/+Hh4f/IyMj/YmJi/yQkJP8jIyP/IyMj/yMjI/8kJCT/WFhY/11d + Xf/U1NT/5OTk/+Xl5f/m5ub/5+fn/+jo6P/p6en/6urq/+vr6//s7Oz/7e3t/+7u7v/u7u7/7+/v//Dw + 8P/w8PD/8fHx//Hx8f/y8vL/8/Pz//Pz8//09PT/9PT0//X19f/19fXx////Ae/v7zfu7u7/7u7u/+3t + 7f/s7Oz/6+vr/+rq6v/p6en/6Ojo/+fn5//m5ub/5eXl/+Xl5f/k5OT/4+Pj/7CwsP9HR0f/IyMj/yMj + I/+Dg4P/5OTk/+Xl5f/m5ub/5+fn/+jo6P/p6en/6urq/+vr6//s7Oz/7Ozs/+3t7f/u7u7/7+/v/+/v + 7//w8PD/8fHx//Hx8f/y8vL/8vLy//Ly8v/z8/P/8/Pz//T09P/09PT/9fX1//X19f/29vbx////AfHx + 8Tfw8PD/7+/v/+/v7//u7u7/7e3t/+zs7P/s7Oz/6+vr/+rq6v/p6en/6Ojo/+jo6P/n5+f/6Ojo/+jo + 6P/f39//kZGR/4GBgf/m5ub/6enp/+np6f/p6en/6urq/+vr6//s7Oz/7Ozs/+3t7f/u7u7/7u7u/+/v + 7//v7+//8PDw//Hx8f/x8fH/8vLy//Ly8v/z8/P/8/Pz//Pz8//09PT/9PT0//X19f/19fX/9vb2//b2 + 9v/29vbx////AfLy8jfy8vL/8fHx//Dw8P/w8PD/7+/v/+7u7v/u7u7/7e3t/+zs7P/s7Oz/6+vr/+vr + 6//q6ur/6urq/+rq6v/r6+v/6+vr/+vr6//r6+v/6+vr/+zs7P/s7Oz/7e3t/+3t7f/u7u7/7u7u/+/v + 7//v7+//8PDw//Dw8P/x8fH/8fHx//Ly8v/y8vL/8/Pz//Pz8//09PT/9PT0//T09P/19fX/9fX1//X1 + 9f/29vb/9vb2//f39//39/fx////AfPz8zfz8/P/8vLy//Ly8v/x8fH/8fHx//Dw8P/w8PD/7+/v/+/v + 7//u7u7/7u7u/+3t7f/t7e3/7e3t/+3t7f/t7e3/7e3t/+3t7f/t7e3/7u7u/+7u7v/u7u7/7+/v/+/v + 7//w8PD/8PDw//Dw8P/x8fH/8fHx//Ly8v/y8vL/8/Pz//Pz8//z8/P/9PT0//T09P/19fX/9fX1//X1 + 9f/29vb/9vb2//b29v/29vb/9/f3//f39//39/fx////AQAAAAAAAP//AAAAAAAA//8AAAAAAAD//wAA + AAAAAP//AAAAAAAA//8AAAAAAAD//wAAAAAAAP//AAAAAAAA//8AAAAAAAD//wAAAAAAAP//AAAAAAAA + //8AAAAAAAD//wAAAAAAAP//AAAAAAAA//8AAAAAAAD//wAAAAAAAP//AAAAAAAA//8AAAAAAAD//wAA + AAAAAP//AAAAAAAA//8AAAAAAAD//wAAAAAAAP//AAAAAAAA//8AAAAAAAD//wAAAAAAAP//AAAAAAAA + //8AAAAAAAD//wAAAAAAAP//AAAAAAAA//8AAAAAAAD//wAAAAAAAP//AAAAAAAA//8AAAAAAAD//wAA + AAAAAP//AAAAAAAA//8AAAAAAAD//wAAAAAAAP//AAAAAAAA//8AAAAAAAD//wAAAAAAAP//AAAAAAAA + //8AAAAAAAD//wAAAAAAAP//AAAAAAAA//8AAAAAAAD//wAAAAAAAP//AAAAAAAA//8AAAAAAAD//ygA + AABAAAAAgAAAAAEAIAAAAAAAAEIAAAAAAAAAAAAAAAAAAAAAAAD///8B7+/v8e/v7//u7u7/7u7u/+3t + 7f/s7Oz/6+vr/+rq6v/p6en/6Ojo/+fn5//m5ub/5OTk/+Pj4//h4eH/4ODg/97e3v/d3d3/29vb/9ra + 2v/Y2Nj/19fX/9XV1f/R0dH/zs7O/8vLy//Hx8f/xMTE/8HBwf++vr7/u7u7/7i4uP+1tbX/srKy/7Cw + sP+vr6//rq6u/62trf+urq7/r6+v/7CwsP+xsbH/s7Oz/7W1tf+3t7f/urq6/7y8vP+/v7//wcHB/8TE + xP/Gxsb/yMjI/8vLy//Nzc3/0NDQ/9LS0v/V1dX/19fX/9nZ2f/c3Nz/3t7e/+Dg4Jf///8B////Ae/v + 7/Hu7u7/7e3t/+3t7f/s7Oz/6+vr/+rq6v/p6en/6Ojo/+fn5//l5eX/5OTk/+Li4v/h4eH/39/f/93d + 3f/c3Nz/2tra/9jY2P/W1tb/1dXV/9LS0v/Q0ND/zMzM/8jIyP/ExMT/wMDA/7y8vP+4uLj/tLS0/7Cw + sP+srKz/qKio/6Wlpf+kpKT/o6Oj/6Kiov+ioqL/o6Oj/6Wlpf+np6f/qKio/6qqqv+tra3/sLCw/7Oz + s/+2trb/uLi4/7u7u/++vr7/wcHB/8PDw//Gxsb/ycnJ/8vLy//Ozs7/0dHR/9TU1P/W1tb/2dnZ/9zc + 3P/e3t6X////Af///wHu7u7x7e3t/+zs7P/s7Oz/6+vr/+rq6v/p6en/5+fn/+bm5v/l5eX/5OTk/+Li + 4v/g4OD/3t7e/93d3f/b29v/2dnZ/9fX1//U1NT/0tLS/9DQ0P/Nzc3/ycnJ/8bGxv/BwcH/vLy8/7e3 + t/+ysrL/rq6u/6ioqP+hoaH/k5OT/5iYmP+VlZX/lJSU/5SUlP+VlZX/lpaW/5iYmP+ampr/nJyc/5+f + n/+hoaH/paWl/6mpqf+srKz/r6+v/7Kysv+1tbX/uLi4/7u7u/++vr7/wcHB/8TExP/Hx8f/ysrK/87O + zv/R0dH/1NTU/9fX1//a2tr/3Nzcl////wH///8B7e3t8ezs7P/r6+v/6urq/+np6f/o6Oj/5+fn/+bm + 5v/k5OT/4+Pj/+Hh4f/f39//3t7e/9zc3P/a2tr/2NjY/9XV1f/T09P/0NDQ/87Ozv/Kysr/x8fH/8PD + w/+/v7//urq6/7W1tf+urq7/qKio/6Ghof+ZmZn/fX19/2RkZP94eHj/hoaG/4WFhf+Ghob/h4eH/4qK + iv+MjIz/jo6O/5GRkf+VlZX/mJiY/5ycnP+goKD/pKSk/6enp/+rq6v/rq6u/7Kysv+1tbX/uLi4/7u7 + u/+/v7//w8PD/8bGxv/Kysr/zs7O/9HR0f/U1NT/19fX/9ra2pf///8B////Aezs7PHr6+v/6urq/+np + 6f/o6Oj/5+fn/+Xl5f/k5OT/4uLi/+Hh4f/f39//3d3d/9vb2//Z2dn/19fX/9XV1f/S0tL/z8/P/8zM + zP/IyMj/xcXF/8HBwf+8vLz/uLi4/7Ozs/+tra3/pKSk/5ycnP+Tk5P/ioqK/2pqav9jY2P/ampq/3l5 + ef94eHj/eHh4/3p6ev99fX3/gYGB/4SEhP+Hh4f/i4uL/4+Pj/+Tk5P/l5eX/5ubm/+fn5//o6Oj/6en + p/+rq6v/r6+v/7Kysv+2trb/urq6/76+vv/CwsL/xsbG/8rKyv/Nzc3/0dHR/9XV1f/X19eX////Af// + /wHq6urx6enp/+jo6P/n5+f/5ubm/+Xl5f/k5OT/4uLi/+Dg4P/e3t7/3Nzc/9ra2v/Y2Nj/1tbW/9TU + 1P/R0dH/zs7O/8vLy//Hx8f/w8PD/7+/v/+6urr/tbW1/7CwsP+qqqr/oqKi/5iYmP+Ojo7/g4OD/3p6 + ev9oaGj/ZWVl/2dnZ/9tbW3/bGxs/21tbf9wcHD/c3Nz/3Z2dv96enr/fX19/4GBgf+FhYX/ioqK/46O + jv+Tk5P/l5eX/5ubm/+goKD/pKSk/6ioqP+srKz/sLCw/7W1tf+5ubn/vr6+/8LCwv/Gxsb/ysrK/87O + zv/S0tL/1dXVl////wH///8B6enp8ejo6P/n5+f/5ubm/+Xl5f/k5OT/4uLi/+Dg4P/e3t7/3Nzc/9ra + 2v/Y2Nj/1tbW/9PT0//R0dH/zs7O/8rKyv/Hx8f/w8PD/76+vv+5ubn/s7Oz/66urv+oqKj/oKCg/5aW + lv+MjIz/gICA/3Z2dv9ubm7/Z2dn/2tra/9tbW3/Y2Nj/2JiYv9jY2P/Z2dn/2pqav9tbW3/cHBw/3Nz + c/93d3f/fHx8/4CAgP+FhYX/ioqK/46Ojv+Tk5P/mJiY/52dnf+hoaH/pqam/6urq/+vr6//tLS0/7m5 + uf+9vb3/wsLC/8bGxv/Ly8v/z8/P/9LS0pf///8B////Aejo6PHn5+f/5ubm/+Xl5f/j4+P/4uLi/+Dg + 4P/f39//3d3d/9ra2v/Y2Nj/1tbW/9PT0//Q0ND/zc3N/8rKyv/Hx8f/w8PD/76+vv+4uLj/s7Oz/62t + rf+mpqb/n5+f/5SUlP+Kior/eHh4/1dXV/9fX1//Z2dn/2lpaf9vb2//dHR0/2VlZf9aWlr/W1tb/15e + Xv9hYWH/ZGRk/2dnZ/9qamr/bm5u/3Nzc/93d3f/fHx8/4GBgf+Ghob/i4uL/5CQkP+VlZX/mpqa/5+f + n/+kpKT/qqqq/6+vr/+0tLT/ubm5/76+vv/Dw8P/yMjI/8zMzP/Pz8+X////Af///wHo6Ojx5ubm/+Xl + 5f/k5OT/4uLi/+Dg4P/f39//3d3d/9vb2//Y2Nj/1tbW/9PT0//Q0ND/zc3N/8nJyf/Gxsb/wsLC/729 + vf+4uLj/s7Oz/62trf+mpqb/nZ2d/5SUlP+IiIj/fHx8/2JiYv9MTEz/TExM/2JiYv9sbGz/cXFx/3Z2 + dv9jY2P/UlJS/1RUVP9PT0//NDQ0/0xMTP9eXl7/YmJi/2ZmZv9qamr/b29v/3Nzc/95eXn/fn5+/4OD + g/+JiYn/jo6O/5SUlP+ZmZn/np6e/6SkpP+qqqr/r6+v/7W1tf+6urr/v7+//8XFxf/Jycn/zc3Nl/// + /wH///8B5+fn8eXl5f/k5OT/4uLi/+Hh4f/f39//3d3d/9vb2//Z2dn/1tbW/9PT0//Q0ND/zc3N/8nJ + yf/FxcX/wcHB/729vf+4uLj/s7Oz/62trf+mpqb/np6e/5SUlP+IiIj/fHx8/3BwcP9dXV3/TExM/0dH + R/9kZGT/b29v/319ff+CgoL/YWFh/0xMTP9JSUn/JCQk/xwcHP8gICD/NjY2/1RUVP9eXl7/YmJi/2Zm + Zv9ra2v/cHBw/3Z2dv97e3v/gYGB/4eHh/+MjIz/kpKS/5iYmP+enp7/pKSk/6urq/+xsbH/t7e3/7y8 + vP/CwsL/x8fH/8vLy5f///8B////Aebm5vHk5OT/4uLi/+Hh4f/f39//3d3d/9vb2//Z2dn/19fX/9TU + 1P/R0dH/zc3N/8rKyv/Gxsb/wcHB/729vf+4uLj/s7Oz/6ysrP+mpqb/np6e/5WVlf+JiYn/fn5+/3Bw + cP9iYmL/W1tb/1dXV/9NTU3/ZWVl/3l5ef+Xl5f/ampq/2xsbP9GRkb/JSUl/xsbG/8vLy//Hh4e/x4e + Hv8kJCT/QkJC/1hYWP9eXl7/Y2Nj/2hoaP9ubm7/c3Nz/3l5ef9/f3//hYWF/4yMjP+SkpL/mJiY/5+f + n/+mpqb/ra2t/7Ozs/+6urr/v7+//8XFxf/JycmX////Af///wHk5OTx4+Pj/+Hh4f/f39//3t7e/9zc + 3P/Z2dn/19fX/9TU1P/R0dH/zs7O/8rKyv/Gxsb/wsLC/729vf+4uLj/s7Oz/62trf+mpqb/n5+f/5WV + lf+Kior/fX19/2FhYf9eXl7/VlZW/1paWv9mZmb/VlZW/21tbf+Wlpb/Z2dn/2xsbP+Ghob/RERE/xsb + G/8mJib/HBwc/x4eHv8eHh7/Hh4e/x4eHv8sLCz/TExM/1paWv9gYGD/ZmZm/2xsbP9xcXH/d3d3/35+ + fv+EhIT/i4uL/5KSkv+ampr/oaGh/6ioqP+wsLD/t7e3/729vf/Dw8P/yMjIl////wH///8B4+Pj8eHh + 4f/g4OD/3t7e/9zc3P/a2tr/2NjY/9XV1f/S0tL/zs7O/8rKyv/Hx8f/wsLC/729vf+4uLj/s7Oz/66u + rv+np6f/n5+f/5eXl/+Kior/fn5+/2dnZ/9ISEj/QUFB/1FRUf9jY2P/ampq/01NTf+EhIT/bm5u/2Vl + Zf+IiIj/5eXl/39/f/8jIyP/Hx8f/x8fH/8eHh7/Hh4e/x4eHv8eHh7/HR0d/x8fH/83Nzf/VFRU/15e + Xv9kZGT/aWlp/3BwcP92dnb/fX19/4SEhP+MjIz/k5OT/5ycnP+kpKT/rKys/7S0tP+8vLz/wsLC/8fH + x5f///8B////AeLi4vHg4OD/3t7e/9zc3P/a2tr/2NjY/9bW1v/T09P/z8/P/8vLy//Hx8f/w8PD/76+ + vv+5ubn/s7Oz/62trf+np6f/n5+f/5aWlv+MjIz/f39//3Jycv9fX1//SUlJ/zo6Ov9XV1f/aWlp/3Bw + cP9PT0//V1dX/11dXf+IiIj/39/f/7S0tP8nJyf/Jycn/yEhIf8lJSX/JCQk/x8fH/8fHx//Hh4e/x4e + Hv8eHh7/Hh4e/yUlJf9ERET/W1tb/2JiYv9oaGj/b29v/3Z2dv99fX3/hYWF/42Njf+Wlpb/n5+f/6mp + qf+ysrL/urq6/8HBwf/GxsaX////Af///wHh4eHx39/f/93d3f/b29v/2NjY/9bW1v/T09P/0NDQ/8zM + zP/IyMj/w8PD/76+vv+5ubn/tLS0/66urv+np6f/oKCg/5aWlv+Li4v/gICA/3R0dP9nZ2f/XV1d/01N + Tf86Ojr/WVlZ/25ubv+Li4v/c3Nz/05OTv9dXV3/0dHR/8bGxv8uLi7/JiYm/yAgIP8kJCT/JSUl/yYm + Jv8lJSX/IiIi/x8fH/8eHh7/Hh4e/x4eHv8eHh7/Hh4e/zAwMP9RUVH/YWFh/2dnZ/9ubm7/dXV1/319 + ff+Ghob/kJCQ/5qamv+lpaX/r6+v/7m5uf/BwcH/xsbGl////wH///8B4ODg8d7e3v/b29v/2dnZ/9bW + 1v/T09P/0NDQ/8zMzP/IyMj/xMTE/7+/v/+6urr/tLS0/66urv+oqKj/oaGh/5iYmP+MjIz/gYGB/25u + bv9mZmb/Xl5e/1paWv9iYmL/SkpK/1lZWf+Ghob/hYWF/1hYWP9paWn/Ozs7/2xsbP81NTX/JiYm/yAg + IP8kJCT/JSUl/yYmJv8mJib/JiYm/yUlJf8kJCT/ISEh/x8fH/8eHh7/Hh4e/x4eHv8eHh7/IiIi/z4+ + Pv9bW1v/ZGRk/2tra/90dHT/fn5+/4qKiv+Wlpb/oaGh/62trf+3t7f/wcHB/8bGxpf///8B////Ad7e + 3vHc3Nz/2tra/9fX1//U1NT/0NDQ/8zMzP/IyMj/xMTE/8DAwP+7u7v/tbW1/6+vr/+oqKj/oaGh/5mZ + mf+Ojo7/goKC/3Jycv9OTk7/RUVF/1RUVP9dXV3/ZmZm/0ZGRv9qamr/ioqK/1RUVP99fX3/tLS0/4CA + gP8bGxv/HR0d/x4eHv8jIyP/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yUlJf8jIyP/Hx8f/x8f + H/8fHx//Hh4e/x4eHv8eHh7/KSkp/0pKSv9fX1//ampq/3d3d/+EhIT/kpKS/5+fn/+rq6v/tra2/8DA + wP/Hx8eX////Af///wHd3d3x2tra/9fX1//U1NT/0dHR/83Nzf/Jycn/xcXF/8DAwP+7u7v/tra2/7Cw + sP+qqqr/oqKi/5qamv+QkJD/hISE/3d3d/9nZ2f/TExM/zw8PP9SUlL/ZGRk/2pqav9BQUH/Wlpa/1RU + VP97e3v/ra2t/+rq6v9OTk7/IiIi/xsbG/8kJCT/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JSUl/yMjI/8hISH/Hx8f/x8fH/8fHx//Hx8f/x8fH/8gICD/NjY2/11dXf9ycnL/f39//4yM + jP+cnJz/qamp/7W1tf/AwMD/x8fHl////wH///8B29vb8djY2P/V1dX/0tLS/87Ozv/Kysr/xsbG/8HB + wf+8vLz/t7e3/7Gxsf+qqqr/pKSk/5ycnP+SkpL/h4eH/3p6ev9tbW3/YWFh/05OTv82Njb/VFRU/2lp + af94eHj/bGxs/zMzM/9fX1//pKSk/+/v7/9gYGD/JCQk/yAgIP8kJCT/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8lJSX/JCQk/yMjI/8fHx//Hx8f/x8fH/8fHx//Hx8f/x8f + H/8mJib/Tk5O/1xcXP9oaGj/k5OT/6enp/+0tLT/wMDA/8fHx5f///8B////AdnZ2fHW1tb/09PT/8/P + z//Ly8v/x8fH/8LCwv+9vb3/t7e3/7Kysv+rq6v/pKSk/52dnf+Tk5P/iIiI/3t7e/9vb2//ZWVl/1xc + XP9cXFz/SkpK/09PT/92dnb/l5eX/1lZWf9GRkb/MTEx/6enp/9tbW3/IiIi/yAgIP8iIiL/JSUl/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yUlJf8lJSX/JCQk/yIi + Iv8fHx//Hx8f/yAgIP8gICD/ICAg/yAgIP8pKSn/Wlpa/46Ojv+np6f/tbW1/8HBwf/Hx8eX////Af// + /wHX19fx1NTU/9DQ0P/MzMz/yMjI/8PDw/++vr7/ubm5/7Ozs/+srKz/paWl/52dnf+UlJT/iYmJ/319 + ff9cXFz/SkpK/1lZWf9aWlr/Y2Nj/0xMTP9TU1P/k5OT/2BgYP9sbGz/i4uL/2BgYP8YGBj/Hh4e/yEh + If8hISH/JSUl/yUlJf8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8lJSX/JCQk/yEhIf8gICD/ICAg/yAgIP8gICD/ICAg/zQ0NP+QkJD/qKio/7e3 + t//Dw8P/yMjIl////wH///8B1dXV8dLS0v/Ozs7/ycnJ/8XFxf/AwMD/urq6/7S0tP+urq7/p6en/5+f + n/+VlZX/i4uL/39/f/9xcXH/UVFR/zw8PP9OTk7/YWFh/2dnZ/9ISEj/UVFR/2lpaf9kZGT/ioqK/+fn + 5/+NjY3/Hh4e/xgYGP8fHx//JCQk/yUlJf8lJSX/JSUl/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yUlJf8lJSX/IyMj/yAgIP8gICD/ICAg/yEh + If8uLi7/jo6O/6urq/+7u7v/xcXF/8nJyZf///8B////AdPT0/HPz8//y8vL/8bGxv/BwcH/u7u7/7W1 + tf+vr6//qKio/6CgoP+Wlpb/jY2N/4GBgf91dXX/aWlp/1NTU/82Njb/TU1N/2dnZ/9vb2//Y2Nj/yoq + Kv9SUlL/hoaG/9/f3/+pqan/JSUl/yQkJP8gICD/JCQk/yUlJf8lJSX/JSUl/yUlJf8lJSX/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8kJCT/ISEh/yAgIP8gICD/Jycn/4ODg/+qqqr/wMDA/8fHx//Ly8uX////Af///wHR0dHxzc3N/8jI + yP/Dw8P/vb29/7e3t/+wsLD/qqqq/6Kiov+YmJj/jo6O/4SEhP93d3f/bW1t/2NjY/9aWlr/R0dH/0hI + SP9tbW3/jIyM/3R0dP8vLy//MjIy/6+vr//AwMD/Jycn/yYmJv8gICD/JCQk/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JSUl/yYmJv8kJCT/ICAg/yUlJf+EhIT/ra2t/8PDw//Jycn/zc3Nl/// + /wH///8Bz8/P8cvLy//Gxsb/wMDA/7q6uv+zs7P/rKys/6SkpP+bm5v/kZGR/4aGhv9xcXH/VVVV/19f + X/9dXV3/YmJi/1ZWVv8/Pz//h4eH/4GBgf9TU1P/cHBw/zc3N/8nJyf/R0dH/yQkJP8hISH/JiYm/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yUlJf81NTX/i4uL/6+v + r//Gxsb/y8vL/8/Pz5f///8B////Ac3NzfHIyMj/w8PD/7y8vP+1tbX/rq6u/6ampv+dnZ3/kpKS/4eH + h/96enr/WVlZ/0RERP9NTU3/Xl5e/2dnZ/9UVFT/QUFB/4uLi/9PT0//fHx8/7y8vP/Gxsb/Hh4e/xgY + GP8dHR3/JCQk/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yUl + Jf8lJSX/SUlJ/4+Pj/+4uLj/ycnJ/83Nzf/R0dGX////Af///wHLy8vxxcXF/7+/v/+4uLj/sLCw/6io + qP+fn5//lZWV/4mJif98fHz/b29v/1paWv8/Pz//SEhI/2VlZf9ra2v/YmJi/yQkJP9JSUn/enp6/7Gx + sf/k5OT/QEBA/yMjI/8dHR3/ISEh/yQkJP8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yUlJf8kJCT/ERER/y8vL/+rq6v/xcXF/8rKyv/Pz8//0tLSl////wH///8BycnJ8cPD + w/+8vLz/tLS0/6urq/+ioqL/l5eX/4yMjP9/f3//c3Nz/2lpaf9eXl7/RERE/0VFRf9paWn/fHx8/4uL + i/8nJyf/Ojo6/5ycnP/o6Oj/UlJS/yIiIv8gICD/IiIi/yQkJP8lJSX/JSUl/yUlJf8lJSX/JSUl/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8kJCT/FhYW/ywsLP+fn5//wsLC/8jIyP/MzMz/0NDQ/9TU + 1Jf///8B////AcbGxvHAwMD/ubm5/7CwsP+mpqb/m5ub/4+Pj/+AgID/YmJi/2ZmZv9kZGT/YWFh/2Bg + YP84ODj/d3d3/5SUlP9WVlb/W1tb/ygoKP87Ozv/XV1d/yEhIf8fHx//IiIi/yQkJP8lJSX/JSUl/yUl + Jf8lJSX/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8nJyf/Kysr/ygoKP+ZmZn/wMDA/8bG + xv/Kysr/zs7O/9LS0v/W1taX////Af///wHFxcXxvr6+/7W1tf+rq6v/oKCg/5OTk/+Ghob/a2tr/0tL + S/9MTEz/YWFh/2ZmZv9hYWH/NjY2/5KSkv9dXV3/aWlp/5KSkv/FxcX/ISEh/yEhIf8bGxv/IiIi/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JiYm/ysrK/8rKyv/KCgo/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JiYm/yYmJv8mJib/JiYm/yYmJv8lJSX/NTU1/2tr + a/+jo6P/v7+//8TExP/IyMj/zMzM/9HR0f/V1dX/2NjYl////wH///8Bw8PD8bu7u/+xsbH/pqam/5qa + mv+MjIz/fHx8/2ZmZv9JSUn/RkZG/2RkZP9sbGz/Z2dn/ycnJ/9UVFT/YmJi/4uLi//p6en/hoaG/x8f + H/8bGxv/ICAg/yUlJf8kJCT/IyMj/ygoKP9OTk7/f39//6Ghof+ysrL/s7Oz/6ioqP+Pj4//YmJi/zMz + M/8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8mJib/JiYm/yUl + Jf8lJSX/HBwc/xkZGf+Li4v/vLy8/8LCwv/Gxsb/y8vL/8/Pz//T09P/19fX/9nZ2Zf///8B////AcLC + wvG5ubn/r6+v/6Ojo/+Wlpb/hoaG/3d3d/9nZ2f/SkpK/0VFRf9qamr/dHR0/5CQkP8uLi7/Nzc3/4CA + gP/j4+P/m5ub/x0dHf8hISH/IiIi/yYmJv8kJCT/IyMj/0hISP+lpaX/ycnJ/8vLy//Ly8v/y8vL/8zM + zP/MzMz/zc3N/83Nzf++vr7/cnJy/yoqKv8kJCT/JCQk/yQkJP8kJCT/JCQk/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yYmJv8lJSX/IiIi/xEREf9/f3//u7u7/8LCwv/Gxsb/ycnJ/83Nzf/R0dH/1dXV/9jY + 2P/b29uX////Af///wHBwcHxuLi4/62trf+hoaH/h4eH/35+fv94eHj/bGxs/2hoaP9BQUH/bGxs/5OT + k/92dnb/RkZG/yQkJP9LS0v/lZWV/yAgIP8iIiL/ICAg/yUlJf8kJCT/JCQk/2lpaf/Gxsb/zc3N/8zM + zP/Ly8v/y8vL/8vLy//MzMz/zMzM/8zMzP/MzMz/y8vL/8rKyv+np6f/Nzc3/yMjI/8kJCT/JCQk/yQk + JP8kJCT/JCQk/yUlJf8lJSX/JSUl/yUlJf8lJSX/IyMj/wwMDP93d3f/uLi4/8HBwf/FxcX/ycnJ/8zM + zP/Q0ND/1NTU/9fX1//a2tr/3Nzcl////wH///8BwcHB8be3t/+srKz/mJiY/2FhYf9VVVX/eXl5/3Bw + cP9ubm7/Ojo6/4WFhf9+fn7/UFBQ/35+fv+bm5v/Jycn/zAwMP8bGxv/HR0d/yMjI/8kJCT/IyMj/19f + X//Gxsb/y8vL/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/Ly8v/y8vL/8rKyv/Kysr/ycnJ/6Oj + o/8rKyv/IyMj/yQkJP8kJCT/JCQk/yQkJP8lJSX/JSUl/yUlJf8lJSX/MjIy/1lZWf+AgID/t7e3/8DA + wP/ExMT/yMjI/8vLy//Pz8//0tLS/9bW1v/Z2dn/29vb/97e3pf///8B////AcLCwvG5ubn/ra2t/5WV + lf9fX1//SkpK/3l5ef90dHT/c3Nz/zIyMv9qamr/TU1N/3x8fP/CwsL/ycnJ/ywsLP8aGhr/Gxsb/yIi + Iv8jIyP/JCQk/zU1Nf+2trb/y8vL/8vLy//MzMz/zMzM/83Nzf/Nzc3/zc3N/8zMzP/MzMz/y8vL/8vL + y//Kysr/ysrK/8rKyv/Kysr/c3Nz/yQkJP8kJCT/JCQk/yQkJP8kJCT/JSUl/yUlJf8kJCT/ISEh/xUV + Ff9zc3P/s7Oz/7+/v//Dw8P/x8fH/8vLy//Ozs7/0tLS/9XV1f/Y2Nj/2tra/93d3f/f39+X////Af// + /wHDw8Pxu7u7/6+vr/+Wlpb/X19f/0dHR/96enr/enp6/4mJif9DQ0P/Pj4+/3Z2dv+0tLT/2dnZ/zk5 + Of8hISH/Hh4e/yIiIv8jIyP/JCQk/yQkJP9paWn/zMzM/83Nzf/MzMz/zMzM/83Nzf/Nzc3/zs7O/83N + zf/Nzc3/zMzM/8zMzP/Ly8v/y8vL/8vLy//Ly8v/zMzM/7Ozs/8rKyv/JCQk/yQkJP8kJCT/JCQk/yUl + Jf8kJCT/ISEh/w0NDf9RUVH/r6+v/76+vv/CwsL/x8fH/8rKyv/Ozs7/0dHR/9TU1P/X19f/2tra/9zc + 3P/f39//4eHhl////wH///8Bw8PD8b29vf+zs7P/mZmZ/3V1df9VVVX/c3Nz/4qKiv+Tk5P/RERE/zAw + MP9qamr/09PT/0NDQ/8hISH/Hh4e/yIiIv8jIyP/JCQk/yQkJP8kJCT/kJCQ/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/87Ozv/Ozs7/zs7O/83Nzf/MzMz/zMzM/8vLy//Ly8v/zMzM/83Nzf/Jycn/PDw8/yQk + JP8kJCT/JCQk/yQkJP8kJCT/IyMj/w4ODv9KSkr/qamp/729vf/BwcH/xsbG/8rKyv/Ozs7/0dHR/9TU + 1P/X19f/2tra/9zc3P/e3t7/4eHh/+Li4pf///8B////AcPDw/G9vb3/tra2/5aWlv9/f3//UFBQ/3R0 + dP+Xl5f/UlJS/29vb/92dnb/ISEh/y8vL/8fHx//Hx8f/yIiIv8jIyP/JCQk/yQkJP8kJCT/JCQk/5iY + mP/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zMzM/8zMzP/MzMz/zMzM/8zM + zP/MzMz/zMzM/0dHR/8kJCT/JCQk/yQkJP8kJCT/KSkp/0RERP9WVlb/q6ur/7y8vP/AwMD/xcXF/8rK + yv/Nzc3/0dHR/9TU1P/X19f/2dnZ/9zc3P/e3t7/4ODg/+Li4v/k5OSX////Af///wHFxcXxvr6+/7Oz + s/+Hh4f/goKC/0xMTP9wcHD/V1dX/2pqav+Tk5P/7u7u/1NTU/8eHh7/GRkZ/yQkJP8lJSX/JCQk/yQk + JP8kJCT/JCQk/yQkJP+Ghob/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/8zM + zP/MzMz/zMzM/8zMzP/MzMz/zMzM/8bGxv87Ozv/JCQk/yQkJP8kJCT/IyMj/xoaGv9ZWVn/pKSk/7y8 + vP/AwMD/xMTE/8nJyf/Nzc3/0NDQ/9TU1P/X19f/2dnZ/9zc3P/e3t7/4ODg/+Li4v/k5OT/5eXll/// + /wH///8BxsbG8cDAwP+oqKj/hYWF/4qKiv9fX1//Pj4+/2hoaP+Ojo7/6enp/3V1df8dHR3/ICAg/yMj + I/8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/VlZW/8vLy//Nzc3/zc3N/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/MzMz/zMzM/8zMzP/Ly8v/y8vL/8vLy/+pqan/KCgo/yQkJP8kJCT/IiIi/xIS + Ev8vLy//oqKi/7u7u//AwMD/xMTE/8nJyf/Nzc3/0NDQ/9TU1P/X19f/2dnZ/9zc3P/e3t7/4ODg/+Li + 4v/k5OT/5eXl/+bm5pf///8B////AcjIyPHDw8P/qKio/4qKiv+cnJz/X19f/zMzM/+CgoL/1tbW/4eH + h/8eHh7/ICAg/yEhIf8jIyP/IyMj/yMjI/8jIyP/IyMj/yQkJP8kJCT/JCQk/ysrK/+np6f/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/8zMzP/MzMz/y8vL/8vLy//Jycn/YWFh/yQk + JP8kJCT/IyMj/xUVFf8mJib/lZWV/7u7u//AwMD/xMTE/8nJyf/MzMz/0NDQ/9PT0//W1tb/2dnZ/9vb + 2//e3t7/4ODg/+Li4v/j4+P/5eXl/+fn5//o6OiX////Af///wHKysrxxcXF/6qqqv+bm5v/cnJy/1ZW + Vv9iYmL/MzMz/0NDQ/8qKir/ISEh/yAgIP8iIiL/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/JCQk/yQk + JP8kJCT/R0dH/729vf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zMzM/8vL + y//Kysr/kZGR/ycnJ/8kJCT/JSUl/zY2Nv8zMzP/lpaW/7u7u//AwMD/xMTE/8jIyP/MzMz/0NDQ/9PT + 0//W1tb/2dnZ/9vb2//d3d3/4ODg/+Li4v/j4+P/5eXl/+bm5v/o6Oj/6enpl////wH///8By8vL8cfH + x/+1tbX/e3t7/1BQUP9/f3//0dHR/4WFhf8mJib/GRkZ/x8fH/8iIiL/IyMj/yMjI/8jIyP/IyMj/yMj + I/8jIyP/IyMj/yMjI/8jIyP/JCQk/yQkJP9LS0v/tbW1/8zMzP/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/8zMzP/IyMj/j4+P/y4uLv8kJCT/IyMj/yIiIv9LS0v/lJSU/729vf/BwcH/xcXF/8jI + yP/MzMz/0NDQ/9PT0//W1tb/2dnZ/9vb2//d3d3/39/f/+Hh4f/j4+P/5eXl/+bm5v/o6Oj/6enp/+rq + 6pf///8B////Ac7OzvHKysr/urq6/1lZWf96enr/xcXF/7y8vP8kJCT/Hx8f/x0dHf8iIiL/IiIi/yIi + Iv8oIiH/PiId/yMiIv8iIiL/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/zMzM/+Dg4P/v7+//8vL + y//Nzc3/zc3N/83Nzf/Nzc3/zMzM/8rKyv+srKz/XV1d/yYmJv8kJCT/IyMj/xsbG/8UFBT/goKC/7u7 + u//CwsL/xcXF/8nJyf/Nzc3/0NDQ/9PT0//W1tb/2dnZ/9vb2//d3d3/39/f/+Hh4f/j4+P/5OTk/+bm + 5v/o6Oj/6enp/+rq6v/r6+uX////Af///wHQ0NDxzc3N/8nJyf+wsLD/t7e3/9LS0v8oKCj/ICAg/x0d + Hf8jIyP/IyMj/yIiIv8jISH/gicW/3UnGf8jIiH/IiIi/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMj + I/8jIyP/JCQk/zAwMP9dXV3/fX19/5OTk/+ZmZn/jo6O/29vb/9HR0f/Jycn/yQkJP8kJCT/IyMj/x0d + Hf8NDQ3/dXV1/7q6uv/CwsL/xsbG/8rKyv/Nzc3/0NDQ/9PT0//W1tb/2dnZ/9vb2//d3d3/39/f/+Hh + 4f/i4uL/5OTk/+bm5v/n5+f/6enp/+rq6v/r6+v/7Ozsl////wH///8B09PT8dDQ0P/MzMz/xcXF/3Z2 + dv88PDz/Hx8f/x8fH/8lJSX/IyMj/yIiIv8iISH/dyYX/44oFv8lIiH/IiIi/yQhIf88Ih7/KCIh/y0i + IP9gJRr/aCYa/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/IyMj/y0tLf8bGxv/cnJy/7i4uP/Dw8P/xsbG/8rKyv/Ozs7/0dHR/9TU1P/W1tb/2dnZ/9vb + 2//d3d3/39/f/+Hh4f/i4uL/5OTk/+bm5v/n5+f/6enp/+rq6v/r6+v/7Ozs/+3t7Zf///8B////AdXV + 1fHS0tL/z8/P/8jIyP9kZGT/NDQ0/yMjI/8kJCT/IyMj/yIiIv8iISH/aCQY/5cpFf+RKBX/fSYW/3kl + Fv+WKBT/jykW/3slFv9uJhn/UyUd/1omHf9GJB3/WSQa/ygiIf8jIyL/IyMj/yMjI/8jIyP/IyMj/yMj + I/8jIyP/JCQk/yQkJP8kJCT/IyMj/yIiIv9FRUX/gICA/729vf/ExMT/x8fH/8vLy//Ozs7/0dHR/9TU + 1P/X19f/2dnZ/9vb2//d3d3/39/f/+Hh4f/j4+P/5OTk/+bm5v/n5+f/6Ojo/+rq6v/r6+v/7Ozs/+3t + 7f/u7u6X////Af///wHY2Njx1dXV/9LS0v/Ly8v/UlJS/ycnJ/8iIiL/IyMj/yIiIv8iIiL/RiMd/7Yr + Ev8zIR7/JiAg/2QlGv+SKBX/LSIg/ykhIP9GIx3/KCIh/2ImG/9EJB7/aSYZ/2IkGf94Jhj/NiMf/yci + Iv8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8kJCT/IyMj/yAgIP8MDAz/Xl5e/7e3t//FxcX/ycnJ/8zM + zP/Pz8//0tLS/9XV1f/X19f/2tra/9zc3P/e3t7/39/f/+Hh4f/j4+P/5OTk/+bm5v/n5+f/6Ojo/+np + 6f/r6+v/7Ozs/+3t7f/u7u7/7+/vl////wH///8B2tra8dfX1//U1NT/ysrK/z4+Pv8iIiL/IyMj/yMj + I/8iIiL/IiIi/yUhIP9dJRv/kicU/1QiGf9QIhn/oyoU/0QiHP+TKBT/fScX/4YmFf9eJRr/LiIg/2ol + Gf+DJxf/bCYZ/2UmG/9yJhj/LCIh/yMiIv8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8NDQ3/TExM/7i4 + uP/IyMj/y8vL/83Nzf/Q0ND/09PT/9bW1v/Z2dn/29vb/93d3f/e3t7/4ODg/+Hh4f/j4+P/5OTk/+bm + 5v/n5+f/6Ojo/+rq6v/r6+v/7Ozs/+3t7f/u7u7/7+/v/+/v75f///8B////Ad3d3fHa2tr/19fX/83N + zf8/Pz//IyMj/yQkJP8jIyP/IyMj/yIiIv8hISH/ISEh/y4hH/9tJhn/gScX/0cjHf+aKRT/OiIe/yEh + If9LIxz/fScX/yUhIf8tIiD/KiIg/1clHP9HIx3/bSca/2smGv88Ix7/LCMh/yMjI/8jIyP/IyMj/ycn + J/8WFhb/RkZG/7S0tP/Kysr/zc3N/8/Pz//S0tL/1NTU/9fX1//a2tr/3Nzc/97e3v/f39//4eHh/+Li + 4v/j4+P/5eXl/+bm5v/n5+f/6Ojo/+rq6v/r6+v/7Ozs/+3t7f/u7u7/7+/v/+/v7//w8PCX////Af// + /wHf39/x3d3d/9ra2v/Y2Nj/vr6+/1xcXP8lJSX/IyMj/yMjI/8iIiL/IiIi/yIiIv8hISH/ISEh/yEh + If8nISD/likV/zAhHv8nIB//iSYU/1skG/92JRf/aCUZ/yIiIf8iIiH/RyMd/3QmGP9dJRv/ayca/zUk + IP8jIyP/IiIi/yMjI/9GRkb/a2tr/7m5uf/Nzc3/z8/P/9HR0f/U1NT/1tbW/9jY2P/b29v/3d3d/9/f + 3//g4OD/4uLi/+Pj4//k5OT/5eXl/+fn5//o6Oj/6enp/+rq6v/r6+v/7Ozs/+3t7f/u7u7/7+/v/+/v + 7//w8PD/8fHxl////wH///8B4eHh8d/f3//d3d3/29vb/9nZ2f/W1tb/paWl/0dHR/8jIyP/IyMj/yIi + Iv8iIiL/IiIi/yIiIv8hISH/ISEh/zkiHv99Jhb/hyYV/14kGv9tJBf/gicX/yQhIP8+Ih3/fCYX/0Ij + Hv9YJRz/hSgX/ykjIv8jIyP/IyMj/yMjI/8TExP/NjY2/62trf/Q0ND/0tLS/9TU1P/W1tb/2NjY/9ra + 2v/c3Nz/3t7e/+Dg4P/i4uL/4+Pj/+Tk5P/l5eX/5+fn/+jo6P/o6Oj/6enp/+rq6v/r6+v/7Ozs/+3t + 7f/u7u7/7+/v//Dw8P/w8PD/8fHx//Ly8pf///8B////AePj4/Hh4eH/39/f/93d3f/c3Nz/2tra/9jY + 2P/Pz8//ioqK/zU1Nf8iIiL/IyMj/yIiIv8iIiL/IiIi/yEhIf8hISH/ISEg/yIhIP9QIxv/qioT/y0h + H/82IR3/nCkU/zojH/8mIiH/YiUa/ysjIf8jIyL/IyMj/yQkJP8YGBj/KCgo/6urq//S0tL/1dXV/9fX + 1//Y2Nj/2tra/9zc3P/e3t7/4ODg/+Li4v/j4+P/5OTk/+Xl5f/n5+f/6Ojo/+jo6P/p6en/6urq/+vr + 6//s7Oz/7e3t/+7u7v/u7u7/7+/v//Dw8P/w8PD/8fHx//Ly8v/y8vKX////Af///wHl5eXx5OTk/+Li + 4v/g4OD/39/f/93d3f/c3Nz/2tra/9jY2P/BwcH/aWlp/ygoKP8iIiL/IiIi/yIiIv8iIiL/ISEh/yEh + If8hISH/KSEg/1kkG/+LJxT/pykT/00kHf8kIiH/fCcX/3QoGv8kIyL/IyMj/yQkJP8cHBz/ICAg/6Cg + oP/U1NT/19fX/9nZ2f/b29v/3Nzc/97e3v/g4OD/4eHh/+Pj4//k5OT/5ubm/+fn5//o6Oj/6Ojo/+np + 6f/q6ur/6+vr/+zs7P/s7Oz/7e3t/+7u7v/v7+//7+/v//Dw8P/x8fH/8fHx//Ly8v/z8/P/8/Pzl/// + /wH///8B5+fn8ebm5v/l5eX/4+Pj/+Li4v/g4OD/39/f/97e3v/c3Nz/29vb/9jY2P+tra3/lpaW/5eX + l/9aWlr/JCQk/yIiIv8iIiL/ISEh/yEhIf8iISH/MiIg/10mG/91Jhj/fSYX/30oGf8mIyL/IyMj/yMj + I/9BQUH/WVlZ/6ampv/X19f/2tra/9zc3P/d3d3/39/f/+Dg4P/i4uL/4+Pj/+Tk5P/m5ub/5+fn/+jo + 6P/o6Oj/6enp/+rq6v/r6+v/7Ozs/+zs7P/t7e3/7u7u/+7u7v/v7+//8PDw//Dw8P/x8fH/8fHx//Ly + 8v/z8/P/8/Pz//T09Jf///8B////Aenp6fHo6Oj/5+fn/+bm5v/k5OT/4+Pj/+Li4v/h4eH/39/f/97e + 3v/d3d3/3Nzc/9vb2//b29v/1NTU/1VVVf8iIiL/IiIi/yIiIv8iIiL/IiIi/yIiIv8kIiL/UCUd/1cm + Hf8mIyL/IyMj/yIiIv8aGhr/ICAg/5WVlf/Z2dn/3d3d/97e3v/f39//4eHh/+Li4v/j4+P/5eXl/+bm + 5v/n5+f/6Ojo/+np6f/q6ur/6urq/+vr6//s7Oz/7Ozs/+3t7f/u7u7/7u7u/+/v7//v7+//8PDw//Hx + 8f/x8fH/8vLy//Ly8v/z8/P/8/Pz//T09P/09PSX////Af///wHr6+vx6urq/+np6f/o6Oj/5+fn/+bm + 5v/l5eX/5OTk/+Pj4//i4uL/4eHh/9/f3//f39//3t7e/93d3f+Xl5f/KSkp/yMjI/8iIiL/IiIi/yIi + Iv8iIiL/IyMj/yMjI/8jIyP/IyMj/yIiIv8eHh7/DQ0N/4ODg//Z2dn/4ODg/+Hh4f/i4uL/4+Pj/+Tk + 5P/l5eX/5ubm/+fn5//o6Oj/6enp/+rq6v/r6+v/6+vr/+zs7P/t7e3/7e3t/+7u7v/u7u7/7+/v/+/v + 7//w8PD/8PDw//Hx8f/x8fH/8vLy//Pz8//z8/P/8/Pz//T09P/09PT/9fX1l////wH///8B7e3t8ezs + 7P/r6+v/6urq/+np6f/o6Oj/5+fn/+bm5v/l5eX/5OTk/+Pj4//j4+P/4uLi/+Hh4f/g4OD/39/f/7m5 + uf9YWFj/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yIiIv8gICD/DQ0N/3p6ev/Z2dn/4+Pj/+Pj + 4//k5OT/5eXl/+bm5v/n5+f/6Ojo/+np6f/p6en/6urq/+vr6//s7Oz/7Ozs/+3t7f/t7e3/7u7u/+/v + 7//v7+//8PDw//Dw8P/w8PD/8fHx//Hx8f/y8vL/8vLy//Pz8//z8/P/9PT0//T09P/19fX/9fX1//b2 + 9pf///8B////Ae7u7vHt7e3/7Ozs/+zs7P/r6+v/6urq/+rq6v/p6en/6Ojo/+fn5//m5ub/5eXl/+Tk + 5P/j4+P/4+Pj/+Li4v/i4uL/39/f/6Kiov8+Pj7/IyMj/yMjI/8jIyP/IyMj/yIiIv9ZWVn/tLS0/6en + p//c3Nz/5OTk/+Xl5f/m5ub/5+fn/+fn5//o6Oj/6enp/+rq6v/r6+v/6+vr/+zs7P/s7Oz/7e3t/+7u + 7v/u7u7/7+/v/+/v7//w8PD/8PDw//Hx8f/x8fH/8fHx//Ly8v/y8vL/8/Pz//Pz8//z8/P/9PT0//T0 + 9P/09PT/9fX1//X19f/29vaX////Af///wHv7+/x7u7u/+7u7v/t7e3/7Ozs/+zs7P/r6+v/6+vr/+rq + 6v/p6en/6Ojo/+fn5//n5+f/5ubm/+Xl5f/l5eX/5OTk/+Tk5P/l5eX/2NjY/4ODg/8xMTH/IiIi/yIi + Iv9NTU3/19fX/+bm5v/m5ub/5ubm/+fn5//o6Oj/6Ojo/+np6f/q6ur/6urq/+vr6//s7Oz/7Ozs/+3t + 7f/t7e3/7u7u/+7u7v/v7+//7+/v//Dw8P/w8PD/8fHx//Hx8f/y8vL/8vLy//Ly8v/y8vL/8/Pz//Pz + 8//09PT/9PT0//T09P/19fX/9fX1//X19f/29vb/9vb2l////wH///8B8PDw8fDw8P/v7+//7u7u/+7u + 7v/t7e3/7e3t/+zs7P/s7Oz/6+vr/+rq6v/q6ur/6enp/+jo6P/o6Oj/5+fn/+fn5//n5+f/5+fn/+fn + 5//m5ub/xMTE/2VlZf9LS0v/0tLS/+jo6P/p6en/6enp/+np6f/p6en/6urq/+rq6v/r6+v/7Ozs/+zs + 7P/t7e3/7e3t/+7u7v/u7u7/7+/v/+/v7//v7+//8PDw//Dw8P/x8fH/8fHx//Ly8v/y8vL/8vLy//Pz + 8//z8/P/8/Pz//T09P/09PT/9PT0//X19f/19fX/9fX1//b29v/29vb/9vb2//f395f///8B////AfHx + 8fHx8fH/8PDw//Dw8P/v7+//7+/v/+7u7v/u7u7/7e3t/+3t7f/s7Oz/7Ozs/+vr6//q6ur/6urq/+rq + 6v/p6en/6enp/+np6f/p6en/6enp/+rq6v/n5+f/4eHh/+rq6v/q6ur/6urq/+vr6//r6+v/6+vr/+zs + 7P/s7Oz/7e3t/+3t7f/u7u7/7u7u/+/v7//v7+//7+/v//Dw8P/w8PD/8PDw//Hx8f/x8fH/8vLy//Ly + 8v/y8vL/8/Pz//Pz8//z8/P/9PT0//T09P/09PT/9fX1//X19f/19fX/9vb2//b29v/29vb/9vb2//f3 + 9//39/eX////Af///wHy8vLx8vLy//Hx8f/x8fH/8PDw//Dw8P/w8PD/7+/v/+/v7//u7u7/7u7u/+3t + 7f/t7e3/7Ozs/+zs7P/s7Oz/7Ozs/+zs7P/r6+v/7Ozs/+zs7P/s7Oz/7Ozs/+zs7P/s7Oz/7Ozs/+zs + 7P/s7Oz/7e3t/+3t7f/t7e3/7u7u/+7u7v/v7+//7+/v/+/v7//w8PD/8PDw//Hx8f/x8fH/8fHx//Hx + 8f/y8vL/8vLy//Pz8//z8/P/8/Pz//T09P/09PT/9PT0//T09P/19fX/9fX1//X19f/29vb/9vb2//b2 + 9v/29vb/9/f3//f39//39/f/9/f3l////wH///8B8/Pz8fPz8//y8vL/8vLy//Ly8v/x8fH/8fHx//Dw + 8P/w8PD/8PDw/+/v7//v7+//7+/v/+7u7v/u7u7/7u7u/+7u7v/t7e3/7u7u/+7u7v/u7u7/7u7u/+7u + 7v/u7u7/7u7u/+7u7v/u7u7/7u7u/+7u7v/u7u7/7+/v/+/v7//w8PD/8PDw//Dw8P/x8fH/8fHx//Hx + 8f/y8vL/8vLy//Ly8v/y8vL/8/Pz//Pz8//z8/P/9PT0//T09P/09PT/9fX1//X19f/19fX/9fX1//b2 + 9v/29vb/9vb2//b29v/39/f/9/f3//f39//39/f/+Pj4//j4+Jf///8BAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAoAAAAgAAAAAABAAABACAAAAAAAAAIAQAAAAAAAAAAAAAAAAAAAAAA////Af// + /wHw8PDj8PDw/+/v7//v7+//7+/v/+7u7v/u7u7/7u7u/+3t7f/t7e3/7e3t/+zs7P/s7Oz/6+vr/+vr + 6//q6ur/6urq/+np6f/p6en/6Ojo/+jo6P/n5+f/5ubm/+bm5v/l5eX/5OTk/+Tk5P/j4+P/4uLi/+Hh + 4f/h4eH/4ODg/9/f3//e3t7/3t7e/93d3f/c3Nz/3Nzc/9vb2//a2tr/2dnZ/9nZ2f/Y2Nj/19fX/9bW + 1v/V1dX/09PT/9LS0v/Q0ND/zs7O/83Nzf/Ly8v/ysrK/8jIyP/Hx8f/xcXF/8TExP/CwsL/wcHB/8DA + wP++vr7/vb29/7u7u/+6urr/uLi4/7e3t/+1tbX/tLS0/7Ozs/+ysrL/sbGx/7Gxsf+wsLD/sLCw/7Cw + sP+wsLD/sLCw/7Gxsf+xsbH/sbGx/7Kysv+ysrL/srKy/7S0tP+0tLT/tbW1/7a2tv+3t7f/uLi4/7m5 + uf+7u7v/u7u7/729vf++vr7/wMDA/8HBwf/BwcH/w8PD/8TExP/FxcX/xsbG/8jIyP/Jycn/ysrK/8vL + y//MzMz/zs7O/8/Pz//Q0ND/0dHR/9PT0//T09P/1dXV/9bW1v/X19f/2NjY/9nZ2f/b29v/3Nzc/97e + 3v/e3t7/39/f/+Hh4f/h4eEx////Af///wH///8B////AfDw8OPv7+//7+/v/+/v7//v7+//7u7u/+7u + 7v/t7e3/7e3t/+zs7P/s7Oz/7Ozs/+vr6//r6+v/6urq/+rq6v/p6en/6enp/+jo6P/o6Oj/5+fn/+fn + 5//m5ub/5eXl/+Tk5P/k5OT/4+Pj/+Li4v/h4eH/4eHh/+Dg4P/f39//3t7e/93d3f/c3Nz/3Nzc/9vb + 2//a2tr/2tra/9nZ2f/Y2Nj/19fX/9bW1v/V1dX/1NTU/9PT0//R0dH/z8/P/83Nzf/MzMz/ysrK/8jI + yP/Hx8f/xcXF/8PDw//BwcH/wMDA/7+/v/+9vb3/vLy8/7q6uv+4uLj/t7e3/7W1tf+zs7P/srKy/7Cw + sP+vr6//rq6u/62trf+tra3/rKys/6urq/+rq6v/q6ur/6urq/+rq6v/rKys/62trf+tra3/ra2t/66u + rv+urq7/sLCw/7CwsP+ysrL/srKy/7Ozs/+1tbX/tra2/7e3t/+5ubn/urq6/7y8vP+9vb3/vr6+/7+/ + v//AwMD/wsLC/8PDw//ExMT/xcXF/8bGxv/IyMj/ycnJ/8vLy//MzMz/zc3N/87Ozv/Pz8//0dHR/9LS + 0v/T09P/1dXV/9bW1v/X19f/2NjY/9nZ2f/b29v/3Nzc/97e3v/f39//39/f/+Dg4DH///8B////Af// + /wH///8B7+/v4+/v7//u7u7/7u7u/+7u7v/t7e3/7e3t/+3t7f/s7Oz/7Ozs/+vr6//r6+v/6urq/+rq + 6v/p6en/6enp/+jo6P/o6Oj/5+fn/+fn5//m5ub/5eXl/+Xl5f/k5OT/4+Pj/+Pj4//i4uL/4eHh/+Dg + 4P/f39//3t7e/93d3f/d3d3/3Nzc/9vb2//a2tr/2dnZ/9nZ2f/Y2Nj/19fX/9bW1v/V1dX/1NTU/9PT + 0//S0tL/0NDQ/87Ozv/MzMz/ysrK/8nJyf/Gxsb/xcXF/8LCwv/BwcH/v7+//729vf+8vLz/urq6/7i4 + uP+2trb/tLS0/7Kysv+wsLD/rq6u/6ysrP+rq6v/qamp/6ioqP+np6f/p6en/6ampv+lpaX/paWl/6Wl + pf+lpaX/paWl/6ampv+mpqb/p6en/6ioqP+oqKj/qamp/6qqqv+rq6v/rKys/62trf+vr6//sLCw/7Gx + sf+ysrL/tLS0/7a2tv+2trb/uLi4/7m5uf+7u7v/vLy8/729vf+/v7//wMDA/8LCwv/CwsL/w8PD/8XF + xf/Gxsb/yMjI/8nJyf/Ly8v/zMzM/83Nzf/Pz8//0NDQ/9HR0f/S0tL/1NTU/9XV1f/W1tb/2NjY/9nZ + 2f/b29v/3Nzc/97e3v/e3t7/39/fMf///wH///8B////Af///wHv7+/j7+/v/+7u7v/u7u7/7u7u/+3t + 7f/t7e3/7Ozs/+zs7P/r6+v/6+vr/+rq6v/q6ur/6enp/+np6f/o6Oj/6Ojo/+fn5//m5ub/5ubm/+Xl + 5f/l5eX/5OTk/+Pj4//i4uL/4eHh/+Hh4f/g4OD/39/f/97e3v/d3d3/3Nzc/9vb2//a2tr/2tra/9nZ + 2f/Y2Nj/19fX/9bW1v/V1dX/1NTU/9PT0//S0tL/0NDQ/8/Pz//Nzc3/y8vL/8rKyv/Hx8f/xsbG/8PD + w//BwcH/v7+//729vf+7u7v/ubm5/7e3t/+1tbX/s7Oz/7Gxsf+urq7/rKys/6mpqf+np6f/paWl/6Oj + o/+ioqL/oaGh/6CgoP+goKD/n5+f/5+fn/+fn5//n5+f/5+fn/+goKD/oaGh/6Ghof+ioqL/o6Oj/6Sk + pP+lpaX/pqam/6enp/+oqKj/qamp/6qqqv+srKz/ra2t/6+vr/+xsbH/srKy/7Ozs/+1tbX/tra2/7i4 + uP+5ubn/u7u7/7y8vP+9vb3/v7+//8DAwP/BwcH/w8PD/8TExP/FxcX/x8fH/8jIyP/Kysr/y8vL/8zM + zP/Ozs7/z8/P/9HR0f/S0tL/1NTU/9XV1f/W1tb/2NjY/9nZ2f/b29v/3Nzc/97e3v/e3t4x////Af// + /wH///8B////Ae7u7uPu7u7/7u7u/+3t7f/t7e3/7Ozs/+zs7P/s7Oz/6+vr/+vr6//q6ur/6urq/+np + 6f/p6en/6Ojo/+jo6P/n5+f/5ubm/+bm5v/l5eX/5eXl/+Tk5P/j4+P/4uLi/+Hh4f/h4eH/4ODg/9/f + 3//e3t7/3d3d/9zc3P/b29v/2tra/9nZ2f/Y2Nj/19fX/9bW1v/V1dX/1NTU/9PT0//S0tL/0NDQ/8/P + z//Ozs7/zMzM/8rKyv/IyMj/x8fH/8TExP/CwsL/v7+//729vf+7u7v/uLi4/7e3t/+0tLT/srKy/7Cw + sP+tra3/qqqq/6enp/+lpaX/oaGh/6CgoP+dnZ3/m5ub/5qamv+ZmZn/mJiY/5iYmP+YmJj/mJiY/5iY + mP+YmJj/mZmZ/5qamv+bm5v/nJyc/52dnf+dnZ3/n5+f/6CgoP+hoaH/oqKi/6Ojo/+lpaX/pqam/6io + qP+qqqr/q6ur/62trf+urq7/sLCw/7Kysv+zs7P/tbW1/7a2tv+4uLj/ubm5/7u7u/+8vLz/vb29/7+/ + v//AwMD/wsLC/8PDw//ExMT/xsbG/8fHx//Jycn/y8vL/8zMzP/Ozs7/z8/P/9HR0f/S0tL/1NTU/9XV + 1f/X19f/2dnZ/9nZ2f/b29v/3Nzc/93d3TH///8B////Af///wH///8B7u7u4+3t7f/t7e3/7e3t/+zs + 7P/s7Oz/7Ozs/+vr6//r6+v/6urq/+np6f/p6en/6Ojo/+jo6P/n5+f/5+fn/+bm5v/l5eX/5eXl/+Tk + 5P/j4+P/4+Pj/+Li4v/h4eH/4ODg/9/f3//e3t7/3d3d/9zc3P/c3Nz/2tra/9nZ2f/Z2dn/19fX/9bW + 1v/V1dX/1NTU/9PT0//S0tL/0dHR/8/Pz//Nzc3/zMzM/8rKyv/IyMj/x8fH/8XFxf/Dw8P/wcHB/76+ + vv+7u7v/ubm5/7a2tv+0tLT/sbGx/66urv+srKz/qamp/6ampv+jo6P/n5+f/5mZmf+BgYH/ioqK/5SU + lP+Tk5P/kZGR/5CQkP+QkJD/kJCQ/5CQkP+QkJD/kZGR/5GRkf+SkpL/k5OT/5WVlf+Wlpb/lpaW/5eX + l/+ZmZn/mpqa/5ycnP+dnZ3/np6e/6CgoP+ioqL/o6Oj/6ampv+np6f/qamp/6urq/+srKz/rq6u/6+v + r/+xsbH/s7Oz/7S0tP+2trb/t7e3/7m5uf+6urr/vLy8/729vf+/v7//wMDA/8HBwf/ExMT/xcXF/8fH + x//Jycn/ysrK/8zMzP/Ozs7/z8/P/9HR0f/S0tL/1NTU/9bW1v/X19f/2dnZ/9ra2v/b29v/3NzcMf// + /wH///8B////Af///wHt7e3j7e3t/+zs7P/s7Oz/7Ozs/+vr6//r6+v/6urq/+rq6v/q6ur/6enp/+np + 6f/o6Oj/5+fn/+bm5v/m5ub/5eXl/+Xl5f/k5OT/4+Pj/+Li4v/i4uL/4ODg/+Dg4P/f39//3t7e/93d + 3f/c3Nz/29vb/9ra2v/Z2dn/2NjY/9fX1//W1tb/1NTU/9PT0//S0tL/0dHR/9DQ0P/Pz8//zc3N/8vL + y//Jycn/yMjI/8bGxv/Dw8P/wsLC/8DAwP++vr7/u7u7/7m5uf+2trb/s7Oz/6+vr/+srKz/qamp/6en + p/+jo6P/n5+f/5ycnP+VlZX/fX19/2RkZP9paWn/enp6/4qKiv+Li4v/iYmJ/4mJif+JiYn/iYmJ/4qK + iv+Kior/i4uL/4yMjP+Ojo7/j4+P/5CQkP+RkZH/kpKS/5SUlP+VlZX/l5eX/5mZmf+ampr/m5ub/56e + nv+fn5//oqKi/6SkpP+mpqb/p6en/6ioqP+rq6v/rKys/66urv+wsLD/sbGx/7Ozs/+0tLT/tra2/7i4 + uP+5ubn/u7u7/7y8vP++vr7/wMDA/8HBwf/Dw8P/xcXF/8fHx//Jycn/ysrK/8zMzP/Ozs7/z8/P/9HR + 0f/S0tL/1NTU/9bW1v/X19f/2dnZ/9ra2v/b29sx////Af///wH///8B////Ae3t7ePs7Oz/7Ozs/+vr + 6//r6+v/6urq/+rq6v/q6ur/6enp/+np6f/o6Oj/5+fn/+fn5//m5ub/5ubm/+Xl5f/k5OT/4+Pj/+Pj + 4//i4uL/4eHh/+Dg4P/f39//3t7e/93d3f/d3d3/29vb/9vb2//Z2dn/2NjY/9jY2P/W1tb/1dXV/9PT + 0//T09P/0tLS/9DQ0P/Pz8//zc3N/8zMzP/Kysr/yMjI/8bGxv/ExMT/wsLC/8DAwP++vr7/vLy8/7m5 + uf+3t7f/tLS0/7Kysv+urq7/qqqq/6enp/+jo6P/n5+f/5ubm/+Xl5f/k5OT/4CAgP9jY2P/YmJi/2Fh + Yf9iYmL/enp6/4ODg/+CgoL/gYGB/4GBgf+CgoL/goKC/4ODg/+EhIT/hoaG/4eHh/+IiIj/iYmJ/4uL + i/+MjIz/jo6O/4+Pj/+RkZH/k5OT/5WVlf+Xl5f/mZmZ/5qamv+dnZ3/n5+f/6Ghof+ioqL/pKSk/6am + pv+oqKj/qqqq/6urq/+tra3/r6+v/7Gxsf+ysrL/tLS0/7a2tv+4uLj/ubm5/7u7u/+9vb3/v7+//8HB + wf/CwsL/xMTE/8bGxv/IyMj/ysrK/8zMzP/Ozs7/z8/P/9HR0f/S0tL/1NTU/9bW1v/X19f/2dnZ/9nZ + 2TH///8B////Af///wH///8B7Ozs4+zs7P/r6+v/6+vr/+vr6//q6ur/6urq/+np6f/p6en/6Ojo/+fn + 5//n5+f/5ubm/+bm5v/l5eX/5OTk/+Pj4//i4uL/4uLi/+Hh4f/g4OD/39/f/97e3v/d3d3/3Nzc/9vb + 2//a2tr/2dnZ/9jY2P/X19f/1tbW/9XV1f/T09P/0tLS/9HR0f/Q0ND/zs7O/8zMzP/Kysr/ycnJ/8fH + x//FxcX/xMTE/8HBwf+/v7//vb29/7u7u/+5ubn/tra2/7S0tP+wsLD/ra2t/6qqqv+lpaX/oqKi/52d + nf+ZmZn/lJSU/5CQkP+MjIz/dnZ2/2FhYf9jY2P/YmJi/2FhYf92dnb/fX19/3x8fP98fHz/e3t7/3x8 + fP98fHz/fX19/35+fv+AgID/gYGB/4ODg/+EhIT/hYWF/4eHh/+JiYn/i4uL/4yMjP+Ojo7/kJCQ/5KS + kv+UlJT/lpaW/5mZmf+bm5v/nZ2d/56env+goKD/oqKi/6SkpP+mpqb/qKio/6qqqv+srKz/ra2t/7Cw + sP+xsbH/s7Oz/7W1tf+2trb/ubm5/7q6uv+9vb3/vr6+/8DAwP/CwsL/xMTE/8bGxv/IyMj/ysrK/8vL + y//Nzc3/z8/P/9HR0f/T09P/1dXV/9bW1v/X19f/2NjYMf///wH///8B////Af///wHr6+vj6+vr/+vr + 6//q6ur/6urq/+np6f/p6en/6Ojo/+jo6P/n5+f/5+fn/+bm5v/l5eX/5eXl/+Tk5P/j4+P/4uLi/+Hh + 4f/h4eH/39/f/9/f3//e3t7/3Nzc/9zc3P/b29v/2tra/9jY2P/X19f/19fX/9XV1f/V1dX/09PT/9LS + 0v/R0dH/z8/P/87Ozv/MzMz/ysrK/8jIyP/Gxsb/xMTE/8LCwv/AwMD/vr6+/7y8vP+5ubn/t7e3/7W1 + tf+ysrL/r6+v/6ysrP+pqan/pKSk/5+fn/+bm5v/lpaW/5GRkf+MjIz/iIiI/4SEhP9ycnL/YWFh/2Rk + ZP9iYmL/YWFh/3Fxcf92dnb/dnZ2/3V1df91dXX/dXV1/3V1df92dnb/eHh4/3p6ev97e3v/fX19/39/ + f/+AgID/goKC/4ODg/+Ghob/h4eH/4mJif+Li4v/jY2N/5CQkP+SkpL/lJSU/5aWlv+YmJj/mpqa/5yc + nP+enp7/oKCg/6Kiov+kpKT/pqam/6ioqP+qqqr/rKys/66urv+wsLD/srKy/7Ozs/+2trb/uLi4/7q6 + uv+8vLz/vr6+/8DAwP/CwsL/xMTE/8bGxv/IyMj/ysrK/8vLy//Nzc3/z8/P/9HR0f/T09P/1dXV/9bW + 1v/X19cx////Af///wH///8B////Aevr6+Pr6+v/6urq/+np6f/p6en/6Ojo/+jo6P/o6Oj/5+fn/+bm + 5v/m5ub/5eXl/+Tk5P/k5OT/4+Pj/+Li4v/h4eH/4ODg/9/f3//e3t7/3t7e/9zc3P/b29v/2tra/9nZ + 2f/Y2Nj/19fX/9bW1v/V1dX/1NTU/9PT0//R0dH/0NDQ/8/Pz//Nzc3/zMzM/8rKyv/IyMj/xsbG/8TE + xP/CwsL/v7+//729vf+7u7v/uLi4/7a2tv+zs7P/sLCw/62trf+rq6v/p6en/6Ojo/+enp7/mZmZ/5SU + lP+Ojo7/iYmJ/4SEhP9/f3//fHx8/21tbf9iYmL/ZWVl/2NjY/9iYmL/bW1t/3BwcP9wcHD/b29v/29v + b/9vb2//b29v/3Fxcf9zc3P/dHR0/3Z2dv94eHj/enp6/3t7e/99fX3/fn5+/4CAgP+CgoL/hISE/4aG + hv+JiYn/i4uL/42Njf+Pj4//kZGR/5SUlP+Wlpb/mJiY/5qamv+cnJz/np6e/6CgoP+jo6P/paWl/6am + pv+pqan/qqqq/62trf+vr6//sbGx/7Ozs/+1tbX/t7e3/7m5uf+8vLz/vr6+/7+/v//CwsL/xMTE/8bG + xv/IyMj/ysrK/8zMzP/Ozs7/z8/P/9HR0f/T09P/1dXV/9bW1jH///8B////Af///wH///8B6urq4+rq + 6v/p6en/6enp/+jo6P/o6Oj/5+fn/+fn5//m5ub/5ubm/+Xl5f/l5eX/5OTk/+Pj4//i4uL/4eHh/+Hh + 4f/f39//3t7e/93d3f/c3Nz/29vb/9ra2v/Z2dn/2NjY/9fX1//W1tb/1dXV/9TU1P/S0tL/0dHR/9DQ + 0P/Ozs7/zc3N/8vLy//Jycn/x8fH/8XFxf/Dw8P/wcHB/7+/v/+9vb3/urq6/7e3t/+1tbX/s7Oz/7Cw + sP+tra3/qamp/6ampv+ioqL/nZ2d/5iYmP+Tk5P/jY2N/4eHh/+CgoL/fX19/3h4eP91dXX/a2tr/2Rk + ZP9mZmb/ZWVl/2NjY/9paWn/ampq/2lpaf9paWn/aWlp/2pqav9ra2v/bW1t/25ubv9wcHD/cnJy/3Nz + c/91dXX/d3d3/3l5ef96enr/fHx8/319ff9/f3//gYGB/4SEhP+Hh4f/iYmJ/4uLi/+NjY3/kJCQ/5KS + kv+UlJT/lpaW/5iYmP+bm5v/nZ2d/5+fn/+hoaH/o6Oj/6ampv+oqKj/qqqq/6ysrP+urq7/sLCw/7Ky + sv+1tbX/t7e3/7m5uf+7u7v/vb29/8DAwP/CwsL/xMTE/8bGxv/IyMj/ysrK/8zMzP/Ozs7/0NDQ/9LS + 0v/U1NT/1dXVMf///wH///8B////Af///wHq6urj6enp/+np6f/o6Oj/6Ojo/+fn5//n5+f/5ubm/+Xl + 5f/l5eX/5OTk/+Tk5P/j4+P/4uLi/+Hh4f/g4OD/39/f/97e3v/d3d3/3Nzc/9vb2//a2tr/2dnZ/9fX + 1//X19f/1tbW/9TU1P/T09P/0tLS/9HR0f/Q0ND/zs7O/8zMzP/Kysr/ycnJ/8fHx//FxcX/w8PD/8HB + wf++vr7/vLy8/7m5uf+2trb/s7Oz/7Gxsf+urq7/rKys/6mpqf+lpaX/oaGh/5ubm/+Xl5f/kZGR/4uL + i/+Ghob/gYGB/3x8fP92dnb/cnJy/29vb/9oaGj/ZWVl/2lpaf9qamr/ampq/2hoaP9kZGT/Y2Nj/2Nj + Y/9kZGT/ZWVl/2ZmZv9oaGj/aWlp/2tra/9tbW3/bm5u/3BwcP9xcXH/c3Nz/3V1df92dnb/eHh4/3p6 + ev98fHz/fn5+/4GBgf+EhIT/hoaG/4mJif+Li4v/jY2N/4+Pj/+RkZH/lJSU/5aWlv+ZmZn/m5ub/56e + nv+fn5//oqKi/6SkpP+mpqb/qKio/6urq/+tra3/r6+v/7Kysv+0tLT/tra2/7m5uf+7u7v/vb29/7+/ + v//CwsL/xMTE/8bGxv/IyMj/ysrK/83Nzf/Pz8//0dHR/9PT0//T09Mx////Af///wH///8B////Aenp + 6ePp6en/6Ojo/+jo6P/n5+f/5+fn/+bm5v/l5eX/5eXl/+Tk5P/k5OT/4+Pj/+Li4v/h4eH/4ODg/9/f + 3//f39//3d3d/9zc3P/b29v/2tra/9nZ2f/Y2Nj/19fX/9bW1v/U1NT/09PT/9LS0v/R0dH/z8/P/87O + zv/MzMz/ysrK/8nJyf/Hx8f/xcXF/8PDw//BwcH/vr6+/7y8vP+5ubn/tra2/7Ozs/+wsLD/rq6u/6ur + q/+oqKj/pKSk/6CgoP+cnJz/lZWV/5CQkP+Li4v/hoaG/39/f/96enr/dnZ2/3Fxcf9ubm7/a2tr/2dn + Z/9nZ2f/a2tr/25ubv9ycnL/cHBw/2dnZ/9fX1//X19f/2BgYP9hYWH/YmJi/2RkZP9lZWX/Z2dn/2ho + aP9qamr/a2tr/21tbf9vb2//cHBw/3Jycv90dHT/dnZ2/3l5ef97e3v/fX19/4CAgP+CgoL/hYWF/4eH + h/+JiYn/i4uL/46Ojv+QkJD/k5OT/5WVlf+YmJj/mpqa/5ycnP+fn5//oaGh/6Ojo/+lpaX/qKio/6qq + qv+tra3/r6+v/7Gxsf+0tLT/tra2/7m5uf+7u7v/vb29/8DAwP/CwsL/xMTE/8fHx//Jycn/y8vL/83N + zf/Pz8//0dHR/9LS0jH///8B////Af///wH///8B6enp4+jo6P/o6Oj/5+fn/+fn5//m5ub/5eXl/+Xl + 5f/k5OT/4+Pj/+Pj4//i4uL/4eHh/+Dg4P/g4OD/3t7e/97e3v/c3Nz/29vb/9ra2v/Z2dn/2NjY/9fX + 1//W1tb/1NTU/9PT0//R0dH/0NDQ/8/Pz//Nzc3/zMzM/8rKyv/Jycn/x8fH/8XFxf/Dw8P/wMDA/76+ + vv+7u7v/uLi4/7W1tf+zs7P/sLCw/62trf+qqqr/p6en/6Ojo/+fn5//mpqa/5WVlf+Pj4//ioqK/4WF + hf97e3v/Y2Nj/11dXf9nZ2f/ampq/2pqav9nZ2f/Z2dn/2lpaf9sbGz/b29v/3Nzc/90dHT/b29v/1xc + XP9bW1v/XFxc/11dXf9eXl7/X19f/2FhYf9iYmL/ZGRk/2VlZf9nZ2f/aWlp/2pqav9sbGz/bW1t/29v + b/9xcXH/dHR0/3Z2dv94eHj/enp6/35+fv+AgID/goKC/4SEhP+Hh4f/ioqK/4yMjP+Ojo7/kZGR/5SU + lP+Wlpb/mJiY/5ubm/+dnZ3/oKCg/6Kiov+kpKT/p6en/6qqqv+tra3/r6+v/7Gxsf+0tLT/tra2/7m5 + uf+7u7v/vr6+/8DAwP/CwsL/xcXF/8fHx//Kysr/zMzM/87Ozv/Q0ND/0NDQMf///wH///8B////Af// + /wHp6enj6Ojo/+fn5//n5+f/5ubm/+Xl5f/l5eX/5OTk/+Pj4//j4+P/4uLi/+Hh4f/g4OD/4ODg/9/f + 3//e3t7/3d3d/9zc3P/a2tr/2dnZ/9jY2P/X19f/1tbW/9TU1P/T09P/0dHR/9DQ0P/Pz8//zc3N/8vL + y//Kysr/yMjI/8fHx//FxcX/w8PD/8DAwP++vr7/u7u7/7i4uP+1tbX/s7Oz/7CwsP+tra3/qamp/6am + pv+ioqL/np6e/5qamv+UlJT/j4+P/4mJif+EhIT/fX19/2NjY/9QUFD/S0tL/01NTf9dXV3/ZWVl/2Vl + Zf9oaGj/a2tr/25ubv9wcHD/c3Nz/3R0dP9wcHD/Wlpa/1dXV/9YWFj/WVlZ/1paWv9bW1v/XV1d/15e + Xv9gYGD/YWFh/2JiYv9kZGT/ZmZm/2dnZ/9paWn/a2tr/21tbf9vb2//cnJy/3R0dP92dnb/eXl5/3t7 + e/9+fn7/gICA/4ODg/+Ghob/iIiI/4uLi/+NjY3/kJCQ/5OTk/+VlZX/mJiY/5qamv+dnZ3/n5+f/6Gh + of+kpKT/p6en/6qqqv+tra3/r6+v/7Gxsf+0tLT/t7e3/7m5uf+7u7v/vr6+/8HBwf/Dw8P/xsbG/8jI + yP/Kysr/zMzM/8/Pz//Q0NAx////Af///wH///8B////Aejo6OPo6Oj/5+fn/+bm5v/m5ub/5eXl/+Tk + 5P/j4+P/4+Pj/+Li4v/h4eH/4ODg/+Dg4P/f39//3t7e/93d3f/c3Nz/2tra/9nZ2f/Y2Nj/19fX/9bW + 1v/U1NT/09PT/9HR0f/Q0ND/z8/P/83Nzf/Ly8v/ycnJ/8jIyP/Gxsb/xMTE/8LCwv/AwMD/vr6+/7u7 + u/+4uLj/tbW1/7Ozs/+wsLD/ra2t/6qqqv+mpqb/oqKi/56env+ZmZn/lJSU/42Njf+IiIj/goKC/319 + ff9ycnL/VFRU/09PT/9JSUn/RUVF/1VVVf9hYWH/ZGRk/2pqav9tbW3/cHBw/3Jycv90dHT/dXV1/3Bw + cP9XV1f/VFRU/1VVVf9WVlb/V1dX/1hYWP9XV1f/S0tL/0lJSf9YWFj/Xl5e/2BgYP9hYWH/Y2Nj/2Vl + Zf9nZ2f/aWlp/2tra/9tbW3/cHBw/3Jycv91dXX/d3d3/3p6ev98fHz/fn5+/4GBgf+EhIT/h4eH/4qK + iv+MjIz/j4+P/5GRkf+UlJT/l5eX/5mZmf+cnJz/np6e/6Ghof+kpKT/p6en/6qqqv+srKz/r6+v/7Ky + sv+0tLT/t7e3/7q6uv+9vb3/v7+//8HBwf/ExMT/xsbG/8nJyf/Ly8v/zs7O/8/PzzH///8B////Af// + /wH///8B6Ojo4+fn5//m5ub/5ubm/+Xl5f/k5OT/5OTk/+Pj4//i4uL/4eHh/+Dg4P/g4OD/39/f/97e + 3v/d3d3/3Nzc/9vb2//Z2dn/2NjY/9fX1//W1tb/1NTU/9PT0//R0dH/0NDQ/8/Pz//Nzc3/y8vL/8nJ + yf/IyMj/xsbG/8TExP/CwsL/wMDA/729vf+7u7v/uLi4/7W1tf+ysrL/sLCw/62trf+qqqr/pqam/6Gh + of+enp7/mZmZ/5OTk/+Ojo7/h4eH/4KCgv98fHz/dnZ2/2xsbP9VVVX/UVFR/0dHR/9DQ0P/UlJS/15e + Xv9nZ2f/bGxs/25ubv9xcXH/dHR0/3d3d/93d3f/cXFx/1NTU/9QUFD/UVFR/1JSUv9TU1P/UlJS/z4+ + Pv8fHx//Hh4e/zExMf9KSkr/Wlpa/15eXv9fX1//YmJi/2NjY/9lZWX/Z2dn/2lpaf9ra2v/bm5u/3Bw + cP9ycnL/dXV1/3h4eP96enr/fX19/4CAgP+Dg4P/hYWF/4iIiP+Li4v/jo6O/5CQkP+Tk5P/lpaW/5mZ + mf+bm5v/np6e/6Ghof+kpKT/p6en/6qqqv+tra3/r6+v/7Kysv+1tbX/uLi4/7q6uv+9vb3/wMDA/8PD + w//FxcX/x8fH/8rKyv/MzMz/zc3NMf///wH///8B////Af///wHn5+fj5+fn/+bm5v/l5eX/5eXl/+Tk + 5P/j4+P/4uLi/+Li4v/h4eH/4ODg/9/f3//e3t7/3d3d/9zc3P/b29v/2tra/9jY2P/X19f/1tbW/9TU + 1P/T09P/0dHR/9DQ0P/Pz8//zc3N/8vLy//Jycn/x8fH/8bGxv/ExMT/wcHB/8DAwP+9vb3/u7u7/7m5 + uf+1tbX/s7Oz/7CwsP+tra3/qqqq/6ampv+jo6P/np6e/5mZmf+UlJT/j4+P/4iIiP+CgoL/fHx8/3Z2 + dv9wcHD/ZmZm/1ZWVv9TU1P/RkZG/0JCQv9PT0//X19f/2lpaf9tbW3/b29v/3Jycv96enr/fn5+/3h4 + eP9xcXH/UVFR/01NTf9OTk7/T09P/09PT/9AQED/ISEh/xoaGv8bGxv/Hh4e/yYmJv88PDz/VFRU/1xc + XP9eXl7/YGBg/2FhYf9jY2P/ZWVl/2dnZ/9qamr/bGxs/25ubv9xcXH/dHR0/3d3d/96enr/fHx8/39/ + f/+BgYH/hISE/4eHh/+Kior/jY2N/5CQkP+Tk5P/lZWV/5mZmf+cnJz/np6e/6Kiov+kpKT/p6en/6qq + qv+tra3/sLCw/7Ozs/+2trb/ubm5/7y8vP+/v7//wcHB/8TExP/Gxsb/ycnJ/8zMzP/MzMwx////Af// + /wH///8B////Aefn5+Pm5ub/5ubm/+Tk5P/k5OT/4+Pj/+Li4v/i4uL/4eHh/+Dg4P/f39//3t7e/93d + 3f/c3Nz/29vb/9ra2v/Z2dn/19fX/9fX1//V1dX/1NTU/9LS0v/Q0ND/z8/P/83Nzf/Ly8v/ycnJ/8fH + x//Gxsb/w8PD/8HBwf+/v7//vb29/7u7u/+4uLj/tbW1/7Kysv+wsLD/ra2t/6mpqf+mpqb/oqKi/5+f + n/+ZmZn/lJSU/46Ojv+IiIj/goKC/3t7e/92dnb/b29v/2lpaf9gYGD/WFhY/1VVVf9ERET/QUFB/0tL + S/9eXl7/a2tr/25ubv9xcXH/enp6/46Ojv+VlZX/fHx8/3Nzc/9PT0//SUlJ/0pKSv9LS0v/PDw8/xsb + G/8TExP/HBwc/x4eHv8dHR3/Hh4e/x4eHv8oKCj/QEBA/1VVVf9bW1v/XV1d/19fX/9hYWH/Y2Nj/2Vl + Zf9oaGj/ampq/21tbf9wcHD/cnJy/3V1df94eHj/e3t7/319ff+AgID/g4OD/4aGhv+JiYn/jIyM/4+P + j/+SkpL/lZWV/5iYmP+bm5v/np6e/6Ghof+kpKT/qKio/6urq/+urq7/sbGx/7W1tf+3t7f/urq6/729 + vf/AwMD/w8PD/8XFxf/IyMj/y8vL/8vLyzH///8B////Af///wH///8B5ubm4+bm5v/l5eX/5OTk/+Pj + 4//i4uL/4uLi/+Hh4f/g4OD/39/f/97e3v/d3d3/3Nzc/9vb2//a2tr/2dnZ/9jY2P/X19f/1dXV/9TU + 1P/S0tL/0dHR/8/Pz//Nzc3/y8vL/8nJyf/IyMj/xcXF/8TExP/BwcH/v7+//729vf+7u7v/uLi4/7W1 + tf+zs7P/r6+v/6ysrP+pqan/pqam/6Ojo/+fn5//mpqa/5SUlP+Pj4//iYmJ/4SEhP99fX3/dnZ2/3Bw + cP9paWn/YmJi/1xcXP9bW1v/V1dX/0ZGRv9FRUX/SkpK/11dXf9sbGz/cHBw/3Z2dv+MjIz/oKCg/4+P + j/9vb2//dnZ2/1dXV/9GRkb/R0dH/z4+Pv8dHR3/EhIS/xgYGP8uLi7/LCws/x4eHv8eHh7/Hh4e/x4e + Hv8hISH/NDQ0/0xMTP9ZWVn/W1tb/11dXf9fX1//YWFh/2RkZP9mZmb/aWlp/2xsbP9ubm7/cXFx/3R0 + dP93d3f/enp6/319ff+AgID/goKC/4aGhv+JiYn/jIyM/4+Pj/+SkpL/lZWV/5iYmP+cnJz/np6e/6Ki + ov+mpqb/qamp/6ysrP+vr6//s7Oz/7a2tv+5ubn/vLy8/76+vv/CwsL/xMTE/8fHx//Kysr/y8vLMf// + /wH///8B////Af///wHm5ubj5eXl/+Tk5P/j4+P/4+Pj/+Li4v/h4eH/4ODg/9/f3//e3t7/3d3d/9zc + 3P/b29v/2tra/9nZ2f/Y2Nj/19fX/9XV1f/U1NT/0tLS/9HR0f/Pz8//zc3N/8zMzP/Kysr/yMjI/8bG + xv/Dw8P/wcHB/7+/v/+9vb3/u7u7/7i4uP+2trb/s7Oz/7CwsP+srKz/qamp/6ampv+jo6P/np6e/5mZ + mf+VlZX/j4+P/4qKiv+EhIT/fn5+/3h4eP9wcHD/ampq/2JiYv9bW1v/WFhY/11dXf9fX1//X19f/1lZ + Wf9MTEz/Xl5e/25ubv92dnb/h4eH/5+fn/+SkpL/VVVV/1ZWVv93d3f/bGxs/05OTv89PT3/JCQk/xMT + E/8YGBj/KCgo/zY2Nv8rKyv/Hh4e/x4eHv8eHh7/Hh4e/x4eHv8eHh7/JSUl/z09Pf9QUFD/WFhY/1tb + W/9dXV3/X19f/2FhYf9kZGT/Z2dn/2pqav9tbW3/cHBw/3Nzc/91dXX/eHh4/3t7e/9+fn7/goKC/4WF + hf+IiIj/i4uL/46Ojv+SkpL/lZWV/5mZmf+cnJz/n5+f/6Ojo/+mpqb/qqqq/62trf+xsbH/tLS0/7e3 + t/+6urr/vb29/8DAwP/Dw8P/xsbG/8nJyf/Kysox////Af///wH///8B////AeXl5ePk5OT/5OTk/+Pj + 4//i4uL/4eHh/+Dg4P/f39//39/f/97e3v/c3Nz/29vb/9ra2v/Z2dn/2NjY/9fX1//W1tb/1NTU/9LS + 0v/R0dH/0NDQ/83Nzf/MzMz/ysrK/8jIyP/Gxsb/xMTE/8HBwf+/v7//vb29/7u7u/+4uLj/tra2/7S0 + tP+wsLD/ra2t/6qqqv+mpqb/o6Oj/6CgoP+ampr/lZWV/5CQkP+JiYn/hISE/35+fv9zc3P/aWlp/2lp + af9kZGT/XFxc/1VVVf9UVFT/YGBg/2NjY/9mZmb/XFxc/09PT/9dXV3/c3Nz/4WFhf+bm5v/lpaW/11d + Xf9MTEz/cHBw/4aGhv92dnb/Y2Nj/ykpKf8WFhb/GBgY/ycnJ/8rKyv/Hx8f/xwcHP8eHh7/Hh4e/x4e + Hv8eHh7/Hh4e/x4eHv8eHh7/Hx8f/ywsLP9DQ0P/VVVV/1lZWf9bW1v/XV1d/2BgYP9jY2P/ZmZm/2lp + af9sbGz/b29v/3Jycv91dXX/eHh4/3t7e/9+fn7/gYGB/4SEhP+IiIj/i4uL/4+Pj/+SkpL/lpaW/5mZ + mf+dnZ3/oaGh/6SkpP+oqKj/q6ur/6+vr/+ysrL/tra2/7m5uf+8vLz/v7+//8LCwv/FxcX/yMjI/8rK + yjH///8B////Af///wH///8B5OTk4+Tk5P/j4+P/4uLi/+Hh4f/g4OD/4ODg/9/f3//e3t7/3d3d/9zc + 3P/b29v/2dnZ/9jY2P/X19f/1tbW/9XV1f/S0tL/0dHR/9DQ0P/Ozs7/zMzM/8rKyv/IyMj/xsbG/8TE + xP/CwsL/wMDA/729vf+7u7v/uLi4/7W1tf+zs7P/sbGx/62trf+qqqr/pqam/6Ojo/+fn5//m5ub/5aW + lv+Pj4//ioqK/4ODg/9+fn7/dHR0/1paWv9NTU3/U1NT/1lZWf9XV1f/UVFR/1RUVP9iYmL/ZWVl/2ho + aP9dXV3/UFBQ/2FhYf+BgYH/mpqa/56env9hYWH/SEhI/2pqav+MjIz/fHx8/5+fn/9nZ2f/HBwc/xcX + F/8lJSX/Kysr/xwcHP8aGhr/HBwc/x4eHv8eHh7/Hh4e/x4eHv8eHh7/Hh4e/x4eHv8eHh7/Hh4e/yMj + I/81NTX/S0tL/1ZWVv9aWlr/XFxc/19fX/9iYmL/ZmZm/2hoaP9ra2v/bm5u/3Fxcf90dHT/d3d3/3t7 + e/9+fn7/gYGB/4WFhf+IiIj/jIyM/4+Pj/+Tk5P/lpaW/5qamv+enp7/oaGh/6ampv+pqan/ra2t/7Gx + sf+0tLT/uLi4/7u7u/++vr7/wcHB/8XFxf/IyMj/ycnJMf///wH///8B////Af///wHj4+Pj4+Pj/+Li + 4v/h4eH/4ODg/9/f3//f39//3t7e/93d3f/c3Nz/29vb/9ra2v/Y2Nj/2NjY/9bW1v/V1dX/09PT/9LS + 0v/Q0ND/zs7O/8zMzP/Kysr/yMjI/8bGxv/ExMT/wsLC/8DAwP+9vb3/u7u7/7i4uP+1tbX/s7Oz/7Cw + sP+urq7/qqqq/6enp/+jo6P/n5+f/5ubm/+Wlpb/kJCQ/4qKiv+EhIT/fX19/3d3d/9eXl7/SkpK/0VF + Rf9BQUH/RUVF/1JSUv9PT0//XFxc/2VlZf9oaGj/ampq/1JSUv9OTk7/bW1t/5eXl/+cnJz/ampq/0dH + R/9mZmb/iYmJ/35+fv+vr6//+vr6/9HR0f84ODj/HR0d/ykpKf8hISH/GRkZ/xsbG/8dHR3/Hh4e/x8f + H/8fHx//Hh4e/x4eHv8eHh7/Hh4e/x4eHv8eHh7/HR0d/x0dHf8lJSX/PT09/09PT/9YWFj/W1tb/15e + Xv9hYWH/ZGRk/2dnZ/9paWn/bGxs/3BwcP9zc3P/dnZ2/3p6ev9+fn7/gYGB/4SEhP+IiIj/i4uL/4+P + j/+Tk5P/l5eX/5ubm/+enp7/o6Oj/6enp/+rq6v/r6+v/7Ozs/+3t7f/urq6/76+vv/BwcH/xMTE/8fH + x//IyMgx////Af///wH///8B////AePj4+Pi4uL/4uLi/+Hh4f/g4OD/39/f/97e3v/d3d3/3Nzc/9vb + 2//a2tr/2dnZ/9jY2P/W1tb/1dXV/9PT0//S0tL/0NDQ/87Ozv/MzMz/ysrK/8nJyf/Hx8f/xcXF/8LC + wv/AwMD/vr6+/7u7u/+5ubn/tbW1/7Ozs/+wsLD/rq6u/6urq/+np6f/pKSk/6CgoP+cnJz/l5eX/5KS + kv+Li4v/hISE/39/f/93d3f/cHBw/1VVVf9MTEz/Q0ND/z4+Pv9BQUH/T09P/1NTU/9jY2P/Z2dn/2pq + av9ra2v/S0tL/0hISP9xcXH/m5ub/2tra/9GRkb/YWFh/4eHh/98fHz/nZ2d//Hx8f/8/Pz/wsLC/zAw + MP8gICD/JSUl/yIiIv8hISH/IiIi/yEhIf8fHx//Hh4e/x4eHv8fHx//Hh4e/x4eHv8eHh7/Hh4e/x4e + Hv8eHh7/Hh4e/x0dHf8hISH/Ly8v/0hISP9XV1f/Wlpa/11dXf9gYGD/ZGRk/2ZmZv9paWn/bGxs/29v + b/9zc3P/dnZ2/3p6ev99fX3/gICA/4WFhf+IiIj/jY2N/5CQkP+UlJT/mZmZ/5ycnP+hoaH/paWl/6mp + qf+tra3/srKy/7a2tv+5ubn/vb29/8DAwP/ExMT/x8fH/8jIyDH///8B////Af///wH///8B4uLi4+Hh + 4f/h4eH/4ODg/9/f3//e3t7/3d3d/9zc3P/b29v/2tra/9nZ2f/Y2Nj/19fX/9bW1v/U1NT/0tLS/9HR + 0f/Ozs7/zc3N/8rKyv/Jycn/x8fH/8XFxf/Dw8P/wMDA/76+vv+7u7v/uLi4/7a2tv+zs7P/sLCw/62t + rf+qqqr/p6en/6Ojo/+fn5//m5ub/5eXl/+RkZH/i4uL/4aGhv9+fn7/eHh4/3BwcP9qamr/VlZW/1BQ + UP9BQUH/Ojo6/z09Pf9NTU3/XFxc/2dnZ/9qamr/bGxs/25ubv9LS0v/R0dH/19fX/9mZmb/RERE/1tb + W/+IiIj/goKC/6CgoP/09PT//Pz8/7y8vP8+Pj7/HBwc/ygoKP8oKCj/ICAg/yIiIv8kJCT/JSUl/yQk + JP8gICD/Hh4e/x8fH/8fHx//Hh4e/x4eHv8eHh7/Hh4e/x4eHv8eHh7/Hh4e/x4eHv8eHh7/IiIi/zY2 + Nv9MTEz/WFhY/1xcXP9fX1//YmJi/2VlZf9oaGj/a2tr/29vb/9ycnL/dnZ2/3l5ef98fHz/gYGB/4SE + hP+JiYn/jY2N/5GRkf+VlZX/mpqa/56env+ioqL/p6en/6ysrP+wsLD/tbW1/7m5uf+9vb3/wMDA/8PD + w//Gxsb/yMjIMf///wH///8B////Af///wHi4uLj4eHh/+Dg4P/f39//3t7e/93d3f/c3Nz/29vb/9ra + 2v/Z2dn/2NjY/9fX1//W1tb/1NTU/9PT0//R0dH/z8/P/83Nzf/Ly8v/ycnJ/8fHx//FxcX/w8PD/8HB + wf++vr7/vLy8/7m5uf+2trb/tLS0/7Gxsf+urq7/qqqq/6enp/+jo6P/n5+f/5ubm/+Wlpb/kZGR/4yM + jP+Ghob/gICA/3l5ef9zc3P/bGxs/2ZmZv9YWFj/UlJS/z8/P/83Nzf/Ozs7/09PT/9kZGT/aWlp/2tr + a/9tbW3/eHh4/2FhYf9LS0v/U1NT/0RERP9XV1f/f39//4aGhv+QkJD/6Ojo///////S0tL/R0dH/xwc + HP8nJyf/KSkp/yIiIv8fHx//IyMj/yQkJP8lJSX/JiYm/yUlJf8iIiL/Hx8f/x8fH/8fHx//Hx8f/x4e + Hv8eHh7/Hh4e/x4eHv8eHh7/Hh4e/x4eHv8eHh7/Hx8f/yoqKv9CQkL/VFRU/1xcXP9fX1//YmJi/2Vl + Zf9oaGj/bGxs/29vb/9ycnL/dnZ2/3l5ef9+fn7/gYGB/4aGhv+Kior/jo6O/5KSkv+Xl5f/nJyc/6Cg + oP+mpqb/qqqq/6+vr/+zs7P/t7e3/7y8vP/AwMD/w8PD/8bGxv/IyMgx////Af///wH///8B////AeHh + 4ePg4OD/4ODg/9/f3//e3t7/3d3d/9zc3P/a2tr/2dnZ/9jY2P/X19f/1tbW/9TU1P/T09P/0tLS/9DQ + 0P/Ozs7/y8vL/8nJyf/Hx8f/xcXF/8PDw//BwcH/vr6+/7y8vP+5ubn/tra2/7S0tP+xsbH/rq6u/6ur + q/+np6f/pKSk/6CgoP+bm5v/lpaW/5CQkP+MjIz/hoaG/4CAgP96enr/c3Nz/25ubv9nZ2f/YWFh/1lZ + Wf9VVVX/PT09/zQ0NP85OTn/TU1N/2ZmZv9ra2v/bW1t/3Z2dv+NjY3/kZGR/15eXv9VVVX/QEBA/15e + Xv+Dg4P/jo6O/+Hh4f/8/Pz/1dXV/1dXV/8cHBz/JiYm/ykpKf8hISH/Hx8f/yIiIv8kJCT/JSUl/yYm + Jv8mJib/Jycn/yYmJv8jIyP/ISEh/x8fH/8fHx//Hx8f/x8fH/8eHh7/Hh4e/x4eHv8eHh7/Hh4e/x4e + Hv8eHh7/Hh4e/yEhIf8wMDD/TExM/1hYWP9eXl7/YWFh/2RkZP9oaGj/a2tr/25ubv9xcXH/dXV1/3p6 + ev99fX3/goKC/4WFhf+Kior/j4+P/5SUlP+ZmZn/np6e/6Ojo/+oqKj/ra2t/7Kysv+3t7f/u7u7/7+/ + v//Dw8P/xsbG/8jIyDH///8B////Af///wH///8B4eHh4+Dg4P/f39//3t7e/93d3f/c3Nz/29vb/9ra + 2v/Z2dn/19fX/9bW1v/U1NT/09PT/9LS0v/Q0ND/zs7O/8zMzP/Kysr/yMjI/8bGxv/Dw8P/wcHB/76+ + vv+8vLz/ubm5/7e3t/+0tLT/sbGx/66urv+rq6v/qKio/6SkpP+goKD/m5ub/5aWlv+RkZH/i4uL/4aG + hv+AgID/enp6/3R0dP9ubm7/aGho/2JiYv9dXV3/W1tb/1paWv9ISEj/QkJC/zo6Ov9KSkr/Z2dn/2xs + bP91dXX/iYmJ/6CgoP+Kior/U1NT/1hYWP9JSUn/PT09/1dXV//X19f//////93d3f9oaGj/Hh4e/yYm + Jv8qKir/Hx8f/x4eHv8hISH/JCQk/yUlJf8mJib/JiYm/yYmJv8mJib/JiYm/yUlJf8kJCT/IiIi/yAg + IP8fHx//Hx8f/x8fH/8fHx//Hh4e/x4eHv8eHh7/Hh4e/x4eHv8eHh7/Hh4e/x4eHv8mJib/Ozs7/1JS + Uv9dXV3/YGBg/2RkZP9nZ2f/ampq/21tbf9xcXH/dXV1/3h4eP99fX3/gYGB/4aGhv+Li4v/kZGR/5eX + l/+bm5v/oaGh/6ampv+srKz/sbGx/7a2tv+7u7v/v7+//8PDw//Gxsb/yMjIMf///wH///8B////Af// + /wHg4ODj4ODg/9/f3//d3d3/3d3d/9vb2//a2tr/2dnZ/9fX1//W1tb/1NTU/9PT0//S0tL/0NDQ/87O + zv/MzMz/ysrK/8jIyP/Gxsb/xMTE/8LCwv+/v7//vb29/7q6uv+2trb/tLS0/7Kysv+urq7/q6ur/6io + qP+lpaX/oaGh/5ycnP+Xl5f/kZGR/4yMjP+Ghob/gYGB/3t7e/90dHT/b29v/2lpaf9jY2P/Xl5e/1lZ + Wf9cXFz/YGBg/2BgYP9YWFj/PT09/0dHR/9oaGj/cnJy/4aGhv+cnJz/kZGR/1dXV/9NTU3/YWFh/1hY + WP9AQED/NTU1/4uLi//W1tb/cHBw/yEhIf8iIiL/Kioq/yEhIf8eHh7/ISEh/yQkJP8lJSX/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yUlJf8mJib/JCQk/yIiIv8gICD/Hx8f/x8fH/8fHx//Hh4e/x4e + Hv8eHh7/Hh4e/x4eHv8eHh7/Hh4e/x4eHv8gICD/Li4u/0pKSv9aWlr/YGBg/2JiYv9lZWX/aGho/2xs + bP9wcHD/dHR0/3l5ef99fX3/goKC/4iIiP+Ojo7/lJSU/5mZmf+fn5//paWl/6urq/+wsLD/tbW1/7q6 + uv++vr7/w8PD/8bGxv/IyMgx////Af///wH///8B////AeDg4OPf39//3t7e/93d3f/b29v/2tra/9nZ + 2f/X19f/1tbW/9TU1P/T09P/0tLS/9DQ0P/Ozs7/zMzM/8rKyv/IyMj/xsbG/8TExP/CwsL/v7+//729 + vf+6urr/t7e3/7S0tP+ysrL/rq6u/6urq/+oqKj/pKSk/6Ghof+dnZ3/mJiY/5KSkv+MjIz/h4eH/4GB + gf97e3v/b29v/1tbW/9dXV3/YmJi/19fX/9ZWVn/VlZW/15eXv9jY2P/ZWVl/1lZWf87Ozv/R0dH/29v + b/+EhIT/nJyc/5WVlf9QUFD/SkpK/3Jycv+CgoL/aWlp/1FRUf8jIyP/GRkZ/zY2Nv8jIyP/ISEh/yoq + Kv8hISH/HR0d/yIiIv8lJSX/JSUl/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JSUl/yQkJP8hISH/Hx8f/x8fH/8fHx//Hx8f/x8fH/8fHx//Hh4e/x4eHv8eHh7/Hh4e/x4e + Hv8eHh7/ISEh/zMzM/9PT0//W1tb/19fX/9jY2P/ZmZm/2pqav9ubm7/dHR0/3l5ef9/f3//hYWF/4uL + i/+SkpL/l5eX/52dnf+jo6P/qamp/7CwsP+0tLT/urq6/76+vv/Dw8P/xsbG/8jIyDH///8B////Af// + /wH///8B39/f497e3v/d3d3/3Nzc/9vb2//a2tr/2NjY/9fX1//V1dX/09PT/9LS0v/Q0ND/zs7O/8zM + zP/Kysr/yMjI/8fHx//ExMT/wsLC/8DAwP+9vb3/u7u7/7i4uP+1tbX/srKy/6+vr/+rq6v/qKio/6Wl + pf+hoaH/nZ2d/5mZmf+UlJT/jo6O/4iIiP+Dg4P/fHx8/3Nzc/9ZWVn/SkpK/0dHR/9OTk7/WFhY/1ZW + Vv9VVVX/YGBg/2RkZP9nZ2f/Wlpa/zo6Ov9KSkr/fX19/5mZmf+YmJj/YGBg/0ZGRv9oaGj/iYmJ/3t7 + e/+wsLD/hISE/x4eHv8RERH/IiIi/yYmJv8eHh7/IiIi/xwcHP8fHx//IyMj/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yUlJf8iIiL/ISEh/x8f + H/8fHx//Hx8f/x8fH/8fHx//Hx8f/x4eHv8eHh7/Hh4e/x4eHv8eHh7/Hh4e/ykpKf8/Pz//VVVV/11d + Xf9hYWH/ZWVl/2pqav9wcHD/dXV1/3x8fP+CgoL/iYmJ/5CQkP+VlZX/nJyc/6Kiov+pqan/r6+v/7Oz + s/+5ubn/vr6+/8PDw//Hx8f/yMjIMf///wH///8B////Af///wHe3t7j3t7e/9zc3P/b29v/2tra/9jY + 2P/X19f/1dXV/9TU1P/S0tL/0NDQ/8/Pz//MzMz/y8vL/8jIyP/Gxsb/xMTE/8LCwv/AwMD/vb29/7u7 + u/+4uLj/tbW1/7Ozs/+vr6//rKys/6ioqP+lpaX/oaGh/52dnf+ZmZn/lJSU/4+Pj/+JiYn/goKC/319 + ff92dnb/ZWVl/05OTv9ISEj/QEBA/0BAQP9QUFD/U1NT/1paWv9jY2P/Z2dn/2hoaP9VVVX/MDAw/09P + T/+Tk5P/mZmZ/2BgYP9FRUX/aGho/4mJif97e3v/r6+v//f39//q6ur/dHR0/xgYGP8fHx//GBgY/xYW + Fv8ZGRn/Hx8f/yQkJP8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yUlJf8kJCT/ISEh/x4eHv8fHx//Hx8f/x8fH/8fHx//Hx8f/x8f + H/8fHx//Hh4e/x4eHv8eHh7/Hh4e/x8fH/8tLS3/RkZG/1hYWP9gYGD/ZWVl/2xsbP9ycnL/eXl5/4CA + gP+Hh4f/jo6O/5SUlP+bm5v/oaGh/6enp/+tra3/s7Oz/7m5uf++vr7/w8PD/8fHx//IyMgx////Af// + /wH///8B////Ad7e3uPd3d3/3Nzc/9ra2v/Z2dn/19fX/9XV1f/U1NT/09PT/9HR0f/Pz8//zc3N/8vL + y//Jycn/x8fH/8XFxf/Dw8P/wMDA/76+vv+7u7v/uLi4/7a2tv+zs7P/sLCw/62trf+pqan/pqam/6Ki + ov+enp7/mZmZ/5WVlf+QkJD/ioqK/4SEhP99fX3/d3d3/3BwcP9hYWH/UFBQ/0dHR/89PT3/PT09/01N + Tf9UVFT/YGBg/2VlZf9oaGj/ampq/1FRUf8rKyv/SkpK/5CQkP9paWn/RUVF/15eXv+IiIj/f39//6mp + qf/z8/P/+vr6/62trf83Nzf/HR0d/yAgIP8YGBj/Ghoa/x8fH/8lJSX/Jycn/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JSUl/yUl + Jf8kJCT/IiIi/yEhIf8fHx//Hx8f/x8fH/8fHx//Hx8f/x8fH/8fHx//Hx8f/x8fH/8fHx//Hx8f/x8f + H/8kJCT/Nzc3/1RUVP9iYmL/ampq/3BwcP93d3f/fn5+/4WFhf+MjIz/kpKS/5mZmf+goKD/pqam/62t + rf+ysrL/uLi4/76+vv/Dw8P/x8fH/8jIyDH///8B////Af///wH///8B3d3d49zc3P/b29v/2dnZ/9jY + 2P/W1tb/1NTU/9PT0//R0dH/0NDQ/83Nzf/Ly8v/ycnJ/8fHx//FxcX/w8PD/8HBwf++vr7/u7u7/7m5 + uf+2trb/s7Oz/7CwsP+tra3/qqqq/6ampv+ioqL/np6e/5qamv+VlZX/kZGR/4uLi/+FhYX/f39//3d3 + d/9xcXH/a2tr/19fX/9TU1P/RkZG/zo6Ov86Ojr/SkpK/1xcXP9lZWX/Z2dn/2lpaf9sbGz/WVlZ/y8v + L/87Ozv/UlJS/0ZGRv9dXV3/g4OD/4KCgv+ZmZn/8fHx//z8/P+/v7//ODg4/xwcHP8oKCj/JCQk/xwc + HP8fHx//JSUl/ycnJ/8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JSUl/yUlJf8kJCT/IyMj/yEhIf8fHx//Hx8f/x8f + H/8fHx//Hx8f/x8fH/8fHx//Hx8f/x8fH/8fHx//Hx8f/x8fH/8gICD/LCws/0RERP9iYmL/bW1t/3V1 + df97e3v/fHx8/4ODg/+Pj4//mJiY/56env+lpaX/q6ur/7Gxsf+4uLj/vr6+/8PDw//Hx8f/yMjIMf// + /wH///8B////Af///wHc3Nzj29vb/9ra2v/Y2Nj/1tbW/9XV1f/U1NT/0dHR/9DQ0P/Ozs7/zMzM/8rK + yv/IyMj/xcXF/8PDw//AwMD/vr6+/7y8vP+5ubn/tra2/7S0tP+xsbH/ra2t/6qqqv+np6f/o6Oj/5+f + n/+bm5v/lpaW/5GRkf+MjIz/hoaG/4CAgP95eXn/cnJy/2xsbP9mZmb/Xl5e/1VVVf9FRUX/Nzc3/zg4 + OP9ISEj/YWFh/2dnZ/9paWn/bGxs/3Z2dv97e3v/QUFB/zY2Nv8wMDD/SkpK/4KCgv+Ghob/mJiY/+rq + 6v/8/Pz/xsbG/0tLS/8aGhr/JiYm/yYmJv8dHR3/ISEh/yYmJv8nJyf/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JSUl/yUlJf8kJCT/JCQk/yQkJP8hISH/Hx8f/x8fH/8fHx//Hx8f/x8fH/8fHx//Hx8f/x8f + H/8fHx//Hx8f/x8fH/8fHx//ICAg/zg4OP9XV1f/b29v/3Fxcf9dXV3/Y2Nj/3l5ef+RkZH/nZ2d/6Oj + o/+qqqr/sbGx/7i4uP+9vb3/w8PD/8fHx//IyMgx////Af///wH///8B////Adzc3OPa2tr/2dnZ/9fX + 1//V1dX/1NTU/9LS0v/Q0ND/zs7O/8zMzP/Kysr/yMjI/8bGxv/ExMT/wcHB/7+/v/+8vLz/ubm5/7e3 + t/+0tLT/sbGx/66urv+rq6v/qKio/6SkpP+goKD/nJyc/5iYmP+Tk5P/jY2N/4iIiP+BgYH/e3t7/3R0 + dP9ubm7/aGho/2NjY/9dXV3/WFhY/0RERP81NTX/NTU1/0VFRf9iYmL/aWlp/2tra/90dHT/i4uL/5mZ + mf9cXFz/ODg4/y8vL/88PDz/dHR0/4eHh//q6ur//v7+/9jY2P9WVlb/Gxsb/yUlJf8pKSn/Hh4e/x8f + H/8kJCT/Jycn/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JSUl/yUlJf8lJSX/JSUl/yMj + I/8hISH/Hx8f/x8fH/8fHx//Hx8f/x8fH/8fHx//Hx8f/x8fH/8fHx//Hx8f/x8fH/8fHx//ISEh/ykp + Kf9ISEj/VVVV/01NTf9fX1//ZWVl/4ODg/+cnJz/o6Oj/6qqqv+wsLD/uLi4/76+vv/Dw8P/x8fH/8jI + yDH///8B////Af///wH///8B2tra49nZ2f/X19f/1tbW/9TU1P/S0tL/0dHR/8/Pz//Nzc3/y8vL/8nJ + yf/Hx8f/xMTE/8LCwv+/v7//vLy8/7q6uv+3t7f/tbW1/7Gxsf+urq7/q6ur/6enp/+lpaX/oKCg/5yc + nP+Xl5f/kpKS/42Njf+IiIj/goKC/3x8fP92dnb/b29v/2lpaf9kZGT/X19f/1xcXP9bW1v/VFRU/09P + T/88PDz/QEBA/2RkZP9ra2v/dHR0/4yMjP+fn5//g4OD/0xMTP8+Pj7/NjY2/ysrK/89PT3/tra2//z8 + /P/c3Nz/UVFR/xkZGf8lJSX/KCgo/x4eHv8fHx//IyMj/yUlJf8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yUlJf8lJSX/JSUl/yQkJP8iIiL/ISEh/yAgIP8fHx//Hh4e/x8f + H/8gICD/ICAg/yAgIP8gICD/ICAg/yAgIP8gICD/ICAg/yAgIP8oKCj/Ojo6/2BgYP9oaGj/f39//5ub + m/+jo6P/q6ur/7Gxsf+5ubn/vr6+/8TExP/Hx8f/yMjIMf///wH///8B////Af///wHa2trj2NjY/9bW + 1v/V1dX/09PT/9HR0f/Pz8//zs7O/8vLy//Jycn/x8fH/8XFxf/Dw8P/wMDA/729vf+6urr/uLi4/7W1 + tf+ysrL/r6+v/6urq/+oqKj/paWl/6Ghof+dnZ3/mZmZ/5OTk/+Ojo7/iYmJ/4ODg/99fX3/c3Nz/2tr + a/9qamr/ZWVl/2BgYP9cXFz/W1tb/15eXv9hYWH/YWFh/zs7O/8zMzP/ZGRk/3Fxcf+Ghob/n5+f/5GR + kf9NTU3/SkpK/2BgYP9DQ0P/NDQ0/ykpKf9LS0v/n5+f/2pqav8cHBz/IiIi/ykpKf8fHx//Gxsb/yEh + If8kJCT/JSUl/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/IyMj/yAgIP8eHh7/Hh4e/yAgIP8gICD/ICAg/yAgIP8gICD/ICAg/yAg + IP8gICD/ICAg/yAgIP8kJCT/Pj4+/2JiYv+BgYH/nJyc/6Ojo/+rq6v/srKy/7m5uf+/v7//xMTE/8fH + x//IyMgx////Af///wH///8B////AdjY2OPX19f/1dXV/9PT0//S0tL/0NDQ/87Ozv/MzMz/ysrK/8jI + yP/Gxsb/w8PD/8HBwf++vr7/u7u7/7i4uP+2trb/srKy/6+vr/+srKz/qKio/6Wlpf+hoaH/np6e/5mZ + mf+UlJT/jo6O/4mJif+EhIT/fX19/3Nzc/9WVlb/TU1N/1ZWVv9fX1//XFxc/1hYWP9bW1v/YWFh/2Rk + ZP9iYmL/OTk5/zIyMv9sbGz/hISE/5ycnP+QkJD/U1NT/0pKSv9ubm7/hoaG/21tbf9SUlL/GRkZ/xIS + Ev8gICD/IyMj/yEhIf8pKSn/IiIi/x8fH/8gICD/IyMj/yUlJf8lJSX/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8lJSX/IyMj/yEh + If8fHx//ICAg/yAgIP8gICD/ICAg/yAgIP8gICD/ICAg/yAgIP8gICD/ICAg/yAgIP8iIiL/R0dH/4KC + gv+cnJz/pKSk/6ysrP+ysrL/urq6/8DAwP/FxcX/yMjI/8jIyDH///8B////Af///wH///8B19fX49bW + 1v/U1NT/0tLS/9DQ0P/Pz8//zc3N/8vLy//IyMj/xsbG/8PDw//CwsL/v7+//7y8vP+5ubn/tra2/7Oz + s/+wsLD/ra2t/6mpqf+mpqb/oqKi/56env+ZmZn/lJSU/5CQkP+Kior/hISE/35+fv91dXX/XFxc/0tL + S/9ERET/QEBA/09PT/9ZWVn/WFhY/15eXv9jY2P/ZWVl/2JiYv8zMzP/MDAw/319ff+ampr/kpKS/1dX + V/9GRkb/a2tr/4uLi/9+fn7/vb29/8rKyv9NTU3/FRUV/xwcHP8dHR3/GBgY/x0dHf8dHR3/ISEh/yMj + I/8kJCT/JSUl/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yUlJf8lJSX/JSUl/yMjI/8iIiL/ISEh/yAgIP8gICD/ICAg/yAg + IP8gICD/ICAg/yAgIP8gICD/ICAg/yEhIf9ERET/hYWF/52dnf+lpaX/rKys/7Ozs/+7u7v/wcHB/8XF + xf/IyMj/ycnJMf///wH///8B////Af///wHW1tbj1dXV/9TU1P/R0dH/z8/P/83Nzf/Ly8v/ycnJ/8fH + x//FxcX/wsLC/7+/v/+8vLz/urq6/7e3t/+0tLT/sbGx/62trf+qqqr/pqam/6Kiov+enp7/mpqa/5aW + lv+QkJD/i4uL/4WFhf9+fn7/eXl5/25ubv9UVFT/TExM/0BAQP88PDz/SUlJ/1ZWVv9bW1v/YmJi/2Vl + Zf9nZ2f/YmJi/ywsLP8sLCz/ioqK/5ycnP9eXl7/RERE/2NjY/+IiIj/enp6/7S0tP/4+Pj/8fHx/39/ + f/8gICD/GRkZ/xUVFf8VFRX/Ghoa/yAgIP8jIyP/JCQk/yUlJf8lJSX/JSUl/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8lJSX/JSUl/yQkJP8jIyP/ISEh/yAgIP8gICD/ICAg/yAgIP8hISH/ISEh/yEhIf8hISH/ISEh/0BA + QP+FhYX/np6e/6enp/+vr6//tra2/76+vv/CwsL/xsbG/8nJyf/Kysox////Af///wH///8B////AdbW + 1uPU1NT/0tLS/9DQ0P/Ozs7/zMzM/8rKyv/Hx8f/xcXF/8PDw//AwMD/vb29/7q6uv+3t7f/tLS0/7Gx + sf+urq7/qqqq/6enp/+jo6P/n5+f/5ubm/+VlZX/kZGR/4uLi/+FhYX/f39//3l5ef90dHT/aWlp/1VV + Vf9NTU3/PT09/zg4OP9GRkb/VVVV/2FhYf9lZWX/aGho/2lpaf9mZmb/LS0t/yUlJf9oaGj/ZmZm/0RE + RP9iYmL/hoaG/319ff+pqan/+vr6//f39/+cnJz/Jycn/xwcHP8kJCT/Ghoa/xsbG/8gICD/IyMj/yQk + JP8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JSUl/yUlJf8kJCT/IiIi/yAg + IP8fHx//Hx8f/yAgIP8hISH/ISEh/yEhIf8hISH/Nzc3/319ff+Xl5f/pqam/7Ozs/+6urr/wMDA/8TE + xP/Hx8f/ysrK/8vLyzH///8B////Af///wH///8B1dXV49PT0//R0dH/z8/P/8zMzP/Kysr/yMjI/8bG + xv/Dw8P/wcHB/76+vv+8vLz/uLi4/7W1tf+ysrL/r6+v/6ysrP+oqKj/pKSk/6CgoP+bm5v/l5eX/5KS + kv+NjY3/hoaG/4GBgf96enr/dXV1/3BwcP9nZ2f/V1dX/05OTv85OTn/NTU1/0NDQ/9XV1f/ZWVl/2dn + Z/9paWn/bGxs/29vb/8zMzP/JSUl/zQ0NP9AQED/Wlpa/4ODg/98fHz/nZ2d/+/v7//7+/v/t7e3/zc3 + N/8cHBz/KCgo/yUlJf8eHh7/ICAg/yMjI/8kJCT/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8kJCT/IiIi/yAgIP8fHx//ICAg/yEhIf8hISH/ISEh/yEh + If8vLy//enp6/42Njf+cnJz/tra2/729vf/BwcH/xMTE/8fHx//Kysr/y8vLMf///wH///8B////Af// + /wHU1NTj0tLS/9DQ0P/Nzc3/y8vL/8nJyf/Gxsb/xMTE/8HBwf+/v7//vLy8/7m5uf+1tbX/srKy/6+v + r/+srKz/qKio/6Wlpf+goKD/m5ub/5aWlv+SkpL/jY2N/4iIiP+BgYH/e3t7/3Z2dv9wcHD/a2tr/2Rk + ZP9ZWVn/UFBQ/zc3N/8yMjL/QUFB/1paWv9oaGj/aWlp/21tbf94eHj/jo6O/11dXf8oKCj/Jycn/zg4 + OP93d3f/gICA/5qamv/19fX//v7+/7m5uf86Ojr/Ghoa/ygoKP8mJib/HR0d/yAgIP8jIyP/JCQk/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yUl + Jf8kJCT/IyMj/yMjI/8hISH/ICAg/x8fH/8gICD/ISEh/ysrK/95eXn/jY2N/5ubm/+6urr/v7+//8PD + w//Gxsb/ycnJ/8zMzP/MzMwx////Af///wH///8B////AdPT0+PR0dH/z8/P/8zMzP/Kysr/x8fH/8XF + xf/Dw8P/wMDA/729vf+6urr/tra2/7Ozs/+wsLD/ra2t/6mpqf+mpqb/oaGh/52dnf+Xl5f/k5OT/46O + jv+JiYn/hISE/319ff93d3f/cnJy/2xsbP9nZ2f/YWFh/1tbW/9RUVH/Pj4+/zc3N/89PT3/W1tb/2lp + af9ra2v/d3d3/42Njf+goKD/bGxs/y4uLv8mJib/KSkp/01NTf+Li4v/5ubm//7+/v/a2tr/RUVF/xoa + Gv8lJSX/KCgo/x8fH/8fHx//IiIi/yQkJP8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yUlJf8lJSX/JiYm/yUlJf8hISH/Hh4e/x8f + H/8hISH/LCws/3p6ev+Ojo7/nZ2d/729vf/BwcH/xMTE/8bGxv/Jycn/zMzM/83NzTH///8B////Af// + /wH///8B0tLS49DQ0P/Ozs7/y8vL/8nJyf/Gxsb/xMTE/8HBwf++vr7/u7u7/7i4uP+0tLT/sbGx/62t + rf+qqqr/pqam/6Kiov+dnZ3/mZmZ/5SUlP+Pj4//ioqK/4WFhf9/f3//dnZ2/3Jycv9tbW3/aGho/2Rk + ZP9eXl7/XV1d/15eXv9eXl7/R0dH/zQ0NP9WVlb/bGxs/3R0dP+NjY3/oKCg/4CAgP9GRkb/Pj4+/ysr + K/8mJib/LCws/3Fxcf/b29v/0dHR/1hYWP8bGxv/JCQk/ykpKf8hISH/Hx8f/yMjI/8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yQkJP8iIiL/Hx8f/x8fH/8pKSn/d3d3/5CQkP+dnZ3/vr6+/8LC + wv/FxcX/yMjI/8vLy//Nzc3/zs7OMf///wH///8B////Af///wHR0dHjz8/P/8zMzP/Kysr/yMjI/8bG + xv/Dw8P/v7+//7y8vP+5ubn/tra2/7Kysv+vr6//q6ur/6enp/+jo6P/n5+f/5mZmf+VlZX/kJCQ/4qK + iv+FhYX/gICA/3Nzc/9cXFz/YmJi/2dnZ/9kZGT/YGBg/1xcXP9fX1//YmJi/2VlZf9ISEj/Kysr/1JS + Uv9zc3P/h4eH/56env+FhYX/S0tL/0xMTP9wcHD/VVVV/yoqKv8gICD/Ghoa/09PT/9nZ2f/ISEh/yMj + I/8oKCj/ICAg/yEhIf8kJCT/Jycn/yYmJv8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8kJCT/IiIi/y0tLf97e3v/kZGR/56env+/v7//xMTE/8fHx//Jycn/zMzM/87Ozv/Pz88x////Af// + /wH///8B////Ac/Pz+POzs7/y8vL/8nJyf/Gxsb/xMTE/8HBwf++vr7/urq6/7e3t/+0tLT/sLCw/6ys + rP+oqKj/pKSk/6CgoP+cnJz/lpaW/5GRkf+MjIz/hoaG/4GBgf91dXX/W1tb/0tLS/9KSkr/UlJS/15e + Xv9cXFz/XFxc/2FhYf9lZWX/Z2dn/0VFRf8pKSn/VlZW/4aGhv+dnZ3/kJCQ/1BQUP9GRkb/bm5u/4iI + iP91dXX/dHR0/yAgIP8LCwv/KSkp/2tra/8pKSn/JSUl/yAgIP8fHx//JCQk/ycnJ/8mJib/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yUlJf8rKyv/WVlZ/42Njf+SkpL/np6e/8DA + wP/FxcX/yMjI/8vLy//Nzc3/z8/P/9DQ0DH///8B////Af///wH///8Bzs7O48zMzP/Kysr/x8fH/8XF + xf/CwsL/v7+//7u7u/+4uLj/tbW1/7Gxsf+urq7/qamp/6Wlpf+hoaH/nJyc/5iYmP+RkZH/jY2N/4aG + hv+AgID/enp6/2RkZP9PT0//SEhI/0NDQ/9ERET/V1dX/1lZWf9gYGD/ZWVl/2dnZ/9paWn/QUFB/yYm + Jv9jY2P/np6e/5OTk/9TU1P/RUVF/2tra/+IiIj/dnZ2/87Ozv/4+Pj/nJyc/x8fH/8eHh7/IiIi/xMT + E/8YGBj/Hh4e/yMjI/8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8lJSX/JiYm/0lJSf+EhIT/k5OT/5OTk/+kpKT/w8PD/8bGxv/Kysr/y8vL/87Ozv/Q0ND/0dHRMf// + /wH///8B////Af///wHNzc3jy8vL/8nJyf/Gxsb/xMTE/8DAwP+9vb3/urq6/7a2tv+zs7P/rq6u/6ur + q/+np6f/oqKi/56env+ZmZn/lJSU/42Njf+IiIj/gICA/3p6ev90dHT/YGBg/1FRUf9GRkb/Pz8//0JC + Qv9VVVX/Wlpa/2RkZP9mZmb/aWlp/2tra/89PT3/Hx8f/1tbW/+ampr/Xl5e/0JCQv9jY2P/hoaG/3p6 + ev+zs7P//Pz8//b29v+NjY3/Hx8f/x0dHf8VFRX/FBQU/x0dHf8gICD/IyMj/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JSUl/yQkJP8kJCT/Hx8f/zg4OP9+fn7/mZmZ/7W1 + tf/Gxsb/yMjI/8vLy//Nzc3/z8/P/9HR0f/S0tIx////Af///wH///8B////AczMzOPKysr/yMjI/8XF + xf/CwsL/vr6+/7u7u/+3t7f/s7Oz/7CwsP+srKz/qKio/6Ojo/+enp7/mZmZ/5SUlP+Pj4//iIiI/4KC + gv96enr/dHR0/25ubv9dXV3/VVVV/0RERP88PDz/Pj4+/1RUVP9gYGD/Z2dn/2lpaf9ra2v/bm5u/0FB + Qf8eHh7/MzMz/1VVVf9BQUH/Y2Nj/4WFhf95eXn/s7Oz//f39//z8/P/lJSU/yIiIv8cHBz/Jycn/x4e + Hv8bGxv/ICAg/yEhIf8kJCT/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yUl + Jf8jIyP/ISEh/w8PD/8CAgL/JSUl/4mJif+xsbH/w8PD/8fHx//Jycn/y8vL/83Nzf/Q0ND/0tLS/9LS + 0jH///8B////Af///wH///8BzMzM48nJyf/Gxsb/w8PD/8DAwP+8vLz/ubm5/7W1tf+xsbH/ra2t/6mp + qf+lpaX/oKCg/5ubm/+VlZX/kJCQ/4qKiv+Dg4P/fX19/3Z2dv9wcHD/a2tr/15eXv9YWFj/Q0ND/zg4 + OP88PDz/VFRU/2RkZP9paWn/a2tr/25ubv97e3v/Xl5e/x8fH/8hISH/NjY2/1hYWP+Dg4P/fHx8/6Gh + of/19fX//v7+/6enp/8wMDD/Ghoa/yYmJv8jIyP/Gxsb/x0dHf8hISH/IyMj/yQkJP8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8lJSX/JCQk/yMjI/8RERH/AwMD/yUlJf9vb2//r6+v/8HB + wf/FxcX/x8fH/8rKyv/MzMz/zs7O/9DQ0P/S0tL/09PTMf///wH///8B////Af///wHLy8vjyMjI/8bG + xv/CwsL/v7+//7u7u/+3t7f/s7Oz/66urv+qqqr/pqam/6Kiov+cnJz/lpaW/5GRkf+Li4v/hYWF/35+ + fv94eHj/cnJy/21tbf9paWn/X19f/1tbW/9CQkL/Nzc3/zk5Of9TU1P/ZmZm/2tra/9ubm7/e3t7/5OT + k/+Hh4f/LCws/x8fH/8wMDD/YWFh/4GBgf+cnJz/7e3t//r6+v++vr7/MTEx/xoaGv8mJib/JSUl/x4e + Hv8fHx//ISEh/yQkJP8kJCT/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8kJCT/JCQk/yQkJP8kJCT/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JSUl/yQk + JP8nJyf/FxcX/wMDA/8eHh7/e3t7/6Ghof+/v7//xMTE/8bGxv/IyMj/ysrK/83Nzf/Pz8//0dHR/9PT + 0//U1NQx////Af///wH///8B////AcrKyuPHx8f/xMTE/8DAwP+9vb3/ubm5/7W1tf+xsbH/rKys/6io + qP+ioqL/np6e/5iYmP+SkpL/jIyM/4aGhv+AgID/eHh4/3Nzc/9ubm7/ampq/2VlZf9fX1//Xl5e/1BQ + UP9JSUn/Nzc3/1BQUP9oaGj/bW1t/3h4eP+SkpL/oKCg/3R0dP8xMTH/Hx8f/yIiIv8zMzP/bGxs/+Xl + 5f/8/Pz/vLy8/0FBQf8ZGRn/JSUl/yQkJP8fHx//ICAg/yIiIv8kJCT/JCQk/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8lJSX/IyMj/xcXF/8DAwP/Hh4e/29vb/+kpKT/vb29/8LC + wv/ExMT/x8fH/8nJyf/Ly8v/zs7O/9DQ0P/S0tL/1NTU/9XV1TH///8B////Af///wH///8ByMjI48bG + xv/Dw8P/v7+//7y8vP+3t7f/s7Oz/6+vr/+qqqr/pqam/6CgoP+bm5v/lJSU/46Ojv+IiIj/goKC/3V1 + df9ubm7/b29v/2xsbP9nZ2f/YmJi/19fX/9hYWH/Y2Nj/1lZWf8yMjL/Q0ND/2hoaP92dnb/jIyM/5+f + n/+AgID/RkZG/0RERP84ODj/HR0d/yEhIf83Nzf/kJCQ/8XFxf9MTEz/GRkZ/yQkJP8lJSX/HR0d/x8f + H/8iIiL/JCQk/yQkJP8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8lJSX/JSUl/ycn + J/8XFxf/BAQE/xEREf9mZmb/np6e/7u7u//CwsL/xMTE/8bGxv/IyMj/y8vL/83Nzf/Pz8//0dHR/9PT + 0//V1dX/1tbWMf///wH///8B////Af///wHIyMjjxMTE/8HBwf+9vb3/urq6/7W1tf+xsbH/rKys/6en + p/+ioqL/m5ub/5aWlv+QkJD/ioqK/4ODg/90dHT/WFhY/09PT/9ZWVn/ZGRk/2RkZP9hYWH/YWFh/2Rk + ZP9nZ2f/W1tb/y4uLv88PDz/b29v/42Njf+hoaH/g4OD/0ZGRv9MTEz/dnZ2/3t7e/9BQUH/ISEh/w8P + D/8UFBT/QEBA/yEhIf8gICD/JiYm/x0dHf8fHx//IiIi/yQkJP8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yUlJf8uLi7/QUFB/y0tLf8hISH/aWlp/6SkpP+7u7v/wcHB/8PD + w//FxcX/x8fH/8rKyv/MzMz/zs7O/9DQ0P/S0tL/1NTU/9bW1v/X19cx////Af///wH///8B////AcbG + xuPExMT/wMDA/729vf+4uLj/s7Oz/6+vr/+pqan/pKSk/5+fn/+ZmZn/kpKS/4uLi/+FhYX/fHx8/2Fh + Yf9PT0//SEhI/0ZGRv9WVlb/YmJi/2BgYP9kZGT/ZmZm/2lpaf9aWlr/Kioq/0NDQ/+CgoL/oKCg/5GR + kf9KSkr/RkZG/29vb/+Ghob/e3t7/8DAwP95eXn/ExMT/xQUFP84ODj/ISEh/xwcHP8eHh7/Hh4e/yIi + Iv8kJCT/JSUl/yUlJf8lJSX/JSUl/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8lJSX/Kioq/0RE + RP9WVlb/e3t7/4KCgv+vr6//u7u7/8DAwP/CwsL/xMTE/8bGxv/IyMj/y8vL/83Nzf/Pz8//0dHR/9PT + 0//V1dX/19fX/9jY2DH///8B////Af///wH///8BxsbG48PDw/+/v7//u7u7/7e3t/+xsbH/rKys/6am + pv+hoaH/nJyc/5WVlf+Ojo7/hoaG/4CAgP92dnb/WVlZ/1FRUf9FRUX/QkJC/1JSUv9gYGD/YmJi/2dn + Z/9paWn/a2tr/1ZWVv8lJSX/RkZG/5WVlf+RkZH/UlJS/0ZGRv9qamr/hYWF/319ff/Kysr//f39/9/f + 3/9CQkL/HBwc/xsbG/8SEhL/FhYW/xwcHP8iIiL/JSUl/yUlJf8lJSX/JSUl/yQkJP8kJCT/JCQk/yQk + JP8jIyP/IyMj/yQkJP8nJyf/Kysr/zAwMP80NDT/NDQ0/zIyMv8uLi7/KSkp/yYmJv8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yYmJv8mJib/JSUl/yUlJf8qKir/PT09/1JSUv+IiIj/np6e/7u7u/+/v7//wcHB/8PD + w//FxcX/yMjI/8rKyv/MzMz/zs7O/9DQ0P/S0tL/1NTU/9bW1v/Y2Nj/2dnZMf///wH///8B////Af// + /wHFxcXjwsLC/729vf+5ubn/tbW1/6+vr/+qqqr/pKSk/5+fn/+ZmZn/kZGR/4qKiv+CgoL/e3t7/3Nz + c/9bW1v/U1NT/0FBQf8/Pz//UVFR/2BgYP9mZmb/aWlp/2tra/9tbW3/WFhY/yMjI/81NTX/f39//1ZW + Vv9BQUH/ZmZm/4aGhv96enr/u7u7//n5+f/s7Oz/gICA/xwcHP8fHx//Gxsb/xQUFP8aGhr/ISEh/yYm + Jv8lJSX/JCQk/yQkJP8kJCT/JCQk/yMjI/8jIyP/IyMj/ygoKP85OTn/WVlZ/3Fxcf+EhIT/lZWV/52d + nf+dnZ3/mJiY/46Ojv9+fn7/ampq/09PT/85OTn/JiYm/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8mJib/JiYm/yUlJf8jIyP/Hh4e/wsL + C/8UFBT/WVlZ/5aWlv+zs7P/vr6+/8DAwP/Dw8P/xcXF/8fHx//Jycn/y8vL/83Nzf/Pz8//0dHR/9PT + 0//V1dX/19fX/9nZ2f/a2tox////Af///wH///8B////AcTExOPBwcH/vb29/7i4uP+0tLT/rq6u/6io + qP+ioqL/nJyc/5aWlv+Ojo7/hoaG/319ff93d3f/b29v/1xcXP9UVFT/PT09/zs7O/9PT0//Y2Nj/2lp + af9sbGz/bm5u/3Jycv9kZGT/JCQk/yEhIf86Ojr/QEBA/11dXf+FhYX/fn5+/7CwsP/5+fn/9vb2/4eH + h/8kJCT/HBwc/yYmJv8hISH/HR0d/yEhIf8mJib/JiYm/yUlJf8kJCT/IyMj/yMjI/8jIyP/JiYm/zIy + Mv9fX1//jY2N/6ysrP++vr7/xcXF/8nJyf/Ly8v/y8vL/8vLy//Ly8v/y8vL/8nJyf/FxcX/vb29/6ur + q/99fX3/VFRU/zExMf8mJib/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yYmJv8mJib/JiYm/yYm + Jv8mJib/JiYm/yUlJf8lJSX/IyMj/yMjI/8LCwv/BgYG/0FBQf+Li4v/srKy/729vf/AwMD/wsLC/8TE + xP/Gxsb/yMjI/8vLy//Nzc3/zs7O/9DQ0P/S0tL/1dXV/9bW1v/Y2Nj/2tra/9ra2jH///8B////Af// + /wH///8BxMTE48DAwP+8vLz/t7e3/7Kysv+srKz/p6en/6Ghof+ampr/k5OT/4uLi/+Dg4P/enp6/3R0 + dP9tbW3/X19f/1VVVf86Ojr/ODg4/09PT/9lZWX/bGxs/25ubv9ycnL/goKC/4eHh/8yMjL/Hh4e/ysr + K/9OTk7/gICA/39/f/+qqqr/9vb2//Pz8/+ampr/Hh4e/xoaGv8lJSX/IiIi/x4eHv8iIiL/JiYm/yYm + Jv8lJSX/JCQk/yMjI/8jIyP/IyMj/zAwMP9nZ2f/o6Oj/8XFxf/Ly8v/y8vL/8vLy//Ly8v/y8vL/8vL + y//Ly8v/zMzM/8zMzP/MzMz/zc3N/83Nzf/Nzc3/zc3N/83Nzf/FxcX/m5ub/11dXf8uLi7/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yYmJv8mJib/JiYm/yYmJv8mJib/JSUl/yYmJv8jIyP/CwsL/wYG + Bv85OTn/kJCQ/7Kysv+9vb3/wMDA/8LCwv/ExMT/xsbG/8jIyP/Kysr/zMzM/87Ozv/Q0ND/0tLS/9TU + 1P/V1dX/19fX/9nZ2f/a2tr/29vbMf///wH///8B////Af///wHExMTjwMDA/7u7u/+2trb/sbGx/6ur + q/+mpqb/oKCg/5mZmf+SkpL/iYmJ/4GBgf95eXn/dHR0/25ubv9iYmL/VlZW/0JCQv88PDz/T09P/2dn + Z/9vb2//cXFx/319ff+Xl5f/oaGh/0tLS/8dHR3/IyMj/0BAQP9lZWX/nJyc//Dw8P/6+vr/rKys/zMz + M/8YGBj/JSUl/yEhIf8cHBz/ISEh/yYmJv8mJib/JSUl/yQkJP8jIyP/IyMj/yMjI/9AQED/jY2N/8DA + wP/MzMz/zMzM/8vLy//Ly8v/y8vL/8vLy//Ly8v/y8vL/8vLy//MzMz/zMzM/8zMzP/MzMz/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Ly8v/vLy8/4GBgf89PT3/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8mJib/JiYm/yUlJf8kJCT/Kysr/xISEv8CAgL/Ly8v/4WFhf+tra3/vLy8/7+/v//BwcH/w8PD/8bG + xv/Hx8f/ysrK/8vLy//Nzc3/z8/P/9HR0f/T09P/1dXV/9fX1//Y2Nj/2tra/9vb2//c3Nwx////Af// + /wH///8B////AcPDw+O/v7//u7u7/7W1tf+wsLD/qqqq/6Wlpf+enp7/l5eX/4yMjP+Hh4f/gYGB/3l5 + ef91dXX/b29v/2ZmZv9nZ2f/Z2dn/0lJSf9BQUH/ZWVl/3Jycv9/f3//lZWV/6Kiov91dXX/Ozs7/yws + LP8dHR3/JSUl/zg4OP+rq6v/7+/v/66urv8uLi7/GBgY/yUlJf8jIyP/HBwc/yAgIP8lJSX/JiYm/yUl + Jf8kJCT/IyMj/yMjI/8qKir/XV1d/7W1tf/Nzc3/zc3N/83Nzf/MzMz/zMzM/8vLy//Ly8v/y8vL/8vL + y//Ly8v/y8vL/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/Ly8v/ysrK/7Cw + sP9nZ2f/KSkp/yMjI/8jIyP/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JSUl/yUl + Jf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/ycnJ/8PDw//AQEB/zIy + Mv+Hh4f/rKys/729vf+/v7//wcHB/8PDw//FxcX/x8fH/8nJyf/Ly8v/zMzM/8/Pz//Q0ND/0tLS/9TU + 1P/W1tb/19fX/9nZ2f/b29v/3Nzc/93d3TH///8B////Af///wH///8Bw8PD48DAwP+7u7v/tbW1/7Cw + sP+pqan/pKSk/52dnf+Li4v/bW1t/3Nzc/99fX3/e3t7/3h4eP9xcXH/aGho/2pqav9paWn/RUVF/zU1 + Nf9gYGD/e3t7/5OTk/+jo6P/fn5+/0VFRf9MTEz/ZGRk/zY2Nv8aGhr/HBwc/y4uLv9ycnL/Q0ND/xYW + Fv8iIiL/IyMj/xwcHP8fHx//IyMj/yUlJf8lJSX/JCQk/yQkJP8jIyP/KCgo/2lpaf+1tbX/zMzM/8zM + zP/Nzc3/zMzM/8zMzP/MzMz/zMzM/8vLy//Ly8v/y8vL/8vLy//Ly8v/zMzM/8zMzP/MzMz/zMzM/8zM + zP/MzMz/zMzM/8zMzP/Ly8v/y8vL/8vLy//Kysr/ysrK/7u7u/9mZmb/Kioq/yMjI/8jIyP/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/yQkJP8pKSn/FxcX/wEBAf8dHR3/fX19/6ioqP+6urr/vr6+/8DAwP/Dw8P/xcXF/8bG + xv/Jycn/y8vL/8zMzP/Ozs7/0NDQ/9LS0v/T09P/1dXV/9fX1//Y2Nj/2tra/9vb2//d3d3/3d3dMf// + /wH///8B////Af///wHDw8Pjv7+//7q6uv+0tLT/r6+v/6mpqf+jo6P/lJSU/21tbf9aWlr/VVVV/19f + X/94eHj/eXl5/3Jycv9sbGz/bm5u/2xsbP9ERET/MzMz/2pqav+Pj4//oqKi/4aGhv9BQUH/SUlJ/3R0 + dP+BgYH/b29v/1BQUP8VFRX/DQ0N/zs7O/9DQ0P/HR0d/yQkJP8bGxv/HR0d/yIiIv8kJCT/JCQk/yQk + JP8kJCT/IyMj/yUlJf9kZGT/u7u7/8rKyv/Ly8v/y8vL/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zM + zP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/Ly8v/y8vL/8vLy//Kysr/ysrK/8rK + yv/Kysr/ycnJ/7W1tf9dXV3/JSUl/yMjI/8jIyP/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yQkJP8lJSX/MzMz/0tLS/9TU1P/SUlJ/4GB + gf+rq6v/urq6/76+vv/AwMD/wsLC/8TExP/Gxsb/yMjI/8rKyv/MzMz/zs7O/8/Pz//R0dH/09PT/9XV + 1f/W1tb/19fX/9nZ2f/a2tr/3Nzc/93d3f/e3t4x////Af///wH///8B////AcPDw+O/v7//urq6/7W1 + tf+vr6//qamp/6Ojo/+Hh4f/Y2Nj/1dXV/9NTU3/UlJS/3h4eP96enr/cXFx/3BwcP9xcXH/bm5u/z8/ + P/8xMTH/eXl5/6Ghof+Hh4f/SkpK/0ZGRv9ubm7/g4OD/4KCgv/R0dH/3d3d/2hoaP8SEhL/IyMj/x0d + Hf8UFBT/GBgY/xwcHP8gICD/IiIi/yQkJP8kJCT/JCQk/yQkJP8jIyP/Q0ND/6+vr//Kysr/ysrK/8vL + y//Ly8v/y8vL/8zMzP/MzMz/zMzM/8zMzP/Nzc3/zc3N/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zM + zP/MzMz/y8vL/8vLy//Ly8v/y8vL/8rKyv/Kysr/ysrK/8rKyv/Kysr/ycnJ/7Gxsf9DQ0P/IyMj/yMj + I/8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8lJSX/JSUl/yUlJf8lJSX/JSUl/yUl + Jf8lJSX/JSUl/y0tLf9ERET/U1NT/3Nzc/+Kior/rq6u/7u7u/+9vb3/v7+//8LCwv/ExMT/xsbG/8jI + yP/Kysr/y8vL/83Nzf/Pz8//0dHR/9LS0v/U1NT/1dXV/9fX1//Y2Nj/2tra/9vb2//d3d3/3t7e/9/f + 3zH///8B////Af///wH///8BxMTE48DAwP+7u7v/tra2/7CwsP+pqan/o6Oj/4WFhf9nZ2f/VVVV/0hI + SP9PT0//enp6/3l5ef9zc3P/c3Nz/3R0dP9ubm7/Ozs7/ywsLP95eXn/k5OT/01NTf9CQkL/bGxs/4eH + h/97e3v/ycnJ//v7+//d3d3/X19f/xcXF/8YGBj/EhIS/xYWFv8bGxv/ICAg/yIiIv8jIyP/JCQk/yQk + JP8kJCT/JCQk/zAwMP+Hh4f/yMjI/8vLy//Ly8v/y8vL/8vLy//Ly8v/zMzM/8zMzP/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zMzM/8zMzP/MzMz/zMzM/8zMzP/Ly8v/y8vL/8vLy//Ly8v/ysrK/8rK + yv/Kysr/ysrK/8rKyv/Kysr/ycnJ/4qKiv8uLi7/IyMj/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yUlJf8lJSX/JSUl/yUlJf8lJSX/JCQk/yMjI/8mJib/HR0d/x8fH/9FRUX/enp6/56e + nv+3t7f/vb29/7+/v//BwcH/w8PD/8XFxf/Hx8f/ycnJ/8vLy//Nzc3/zs7O/9DQ0P/S0tL/1NTU/9XV + 1f/W1tb/2NjY/9nZ2f/b29v/3Nzc/93d3f/f39//39/fMf///wH///8B////Af///wHExMTjwcHB/7y8 + vP+2trb/sbGx/6mpqf+jo6P/iIiI/2tra/9TU1P/RERE/0xMTP95eXn/d3d3/3V1df92dnb/d3d3/3Nz + c/8+Pj7/JCQk/0xMTP9RUVH/QUFB/2VlZf+Hh4f/eXl5/8fHx//+/v7/6Ojo/2RkZP8aGhr/Hh4e/yQk + JP8bGxv/HBwc/yEhIf8jIyP/IyMj/yQkJP8kJCT/JCQk/yQkJP8kJCT/XFxc/76+vv/MzMz/zMzM/8zM + zP/MzMz/zMzM/8zMzP/MzMz/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/8zM + zP/MzMz/zMzM/8vLy//Ly8v/y8vL/8vLy//Kysr/ysrK/8rKyv/Kysr/ysrK/8vLy//Ly8v/vLy8/1dX + V/8lJSX/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JSUl/yUlJf8lJSX/JSUl/yQk + JP8jIyP/IiIi/xkZGf8EBAT/ExMT/21tbf+goKD/uLi4/7y8vP++vr7/wcHB/8PDw//FxcX/x8fH/8nJ + yf/Kysr/zc3N/87Ozv/Q0ND/0dHR/9PT0//V1dX/1tbW/9jY2P/Z2dn/2tra/9vb2//d3d3/3t7e/9/f + 3//g4OAx////Af///wH///8B////AcTExOPBwcH/vb29/7i4uP+ysrL/q6ur/6SkpP+Hh4f/bm5u/1BQ + UP9CQkL/TU1N/3t7e/93d3f/eHh4/3h4eP97e3v/g4OD/01NTf8iIiL/MDAw/0RERP9gYGD/hYWF/3V1 + df+vr6//+Pj4//Hx8f+IiIj/Hh4e/xwcHP8lJSX/Hx8f/x0dHf8gICD/IiIi/yMjI/8kJCT/JCQk/yQk + JP8kJCT/JCQk/yUlJf+SkpL/zMzM/83Nzf/Nzc3/zc3N/8zMzP/MzMz/zMzM/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zs7O/87Ozv/Ozs7/zc3N/83Nzf/Nzc3/zc3N/8zMzP/MzMz/zMzM/8vLy//Ly8v/y8vL/8vL + y//Ly8v/y8vL/8vLy//Ly8v/y8vL/8zMzP/Jycn/hoaG/ywsLP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8lJSX/JSUl/yUlJf8lJSX/JCQk/yMjI/8bGxv/BAQE/wcHB/9RUVH/mZmZ/7S0 + tP+8vLz/vr6+/8DAwP/Dw8P/xcXF/8fHx//IyMj/ysrK/8zMzP/Ozs7/0NDQ/9HR0f/T09P/1NTU/9bW + 1v/X19f/2NjY/9ra2v/b29v/3d3d/97e3v/f39//4ODg/+Hh4TH///8B////Af///wH///8BxMTE48LC + wv++vr7/uLi4/7Ozs/+tra3/pqam/4iIiP9xcXH/T09P/0JCQv9LS0v/e3t7/3p6ev96enr/fX19/4iI + iP+enp7/eXl5/yUlJf8sLCz/Wlpa/3x8fP92dnb/srKy//j4+P/w8PD/ioqK/yIiIv8bGxv/JSUl/x8f + H/8cHBz/ICAg/yIiIv8jIyP/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/MjIy/7q6uv/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/87Ozv/Ozs7/zs7O/87Ozv/Ozs7/zc3N/83N + zf/Nzc3/zc3N/8zMzP/MzMz/y8vL/8vLy//Ly8v/y8vL/8vLy//Ly8v/y8vL/8zMzP/MzMz/zMzM/83N + zf+urq7/OTk5/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JSUl/yUlJf8lJSX/JSUl/yQk + JP8iIiL/Gxsb/wYGBv8ODg7/UVFR/5mZmf+1tbX/u7u7/76+vv/AwMD/wsLC/8TExP/Hx8f/ycnJ/8rK + yv/MzMz/zs7O/9DQ0P/R0dH/09PT/9TU1P/V1dX/2NjY/9nZ2f/a2tr/29vb/9zc3P/e3t7/39/f/+Dg + 4P/h4eH/4eHhMf///wH///8B////Af///wHExMTjwsLC/76+vv+6urr/tbW1/66urv+oqKj/ioqK/3d3 + d/9oaGj/Xl5e/05OTv94eHj/fX19/35+fv+IiIj/mpqa/5+fn/9kZGT/KCgo/yAgIP9KSkr/aWlp/5WV + lf/29vb/+vr6/56env8oKCj/GRkZ/yUlJf8hISH/HBwc/yAgIP8iIiL/IyMj/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP9LS0v/ysrK/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83N + zf/Ozs7/zs7O/87Ozv/Ozs7/zs7O/87Ozv/Ozs7/zs7O/83Nzf/Nzc3/zMzM/8zMzP/MzMz/zMzM/8zM + zP/Ly8v/y8vL/8vLy//MzMz/zMzM/83Nzf/Nzc3/zc3N/8HBwf9OTk7/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8lJSX/JSUl/yUlJf8kJCT/JSUl/x8fH/8HBwf/BgYG/05OTv+Pj4//r6+v/7u7 + u/+9vb3/wMDA/8LCwv/ExMT/xsbG/8jIyP/Kysr/zMzM/87Ozv/Pz8//0dHR/9PT0//U1NT/1dXV/9fX + 1//Y2Nj/2tra/9vb2//d3d3/3d3d/97e3v/g4OD/4eHh/+Li4v/i4uIx////Af///wH///8B////AcTE + xOPCwsL/v7+//7u7u/+3t7f/sbGx/6qqqv+Kior/e3t7/3x8fP9sbGz/Pj4+/1lZWf9+fn7/iIiI/5ub + m/+jo6P/bm5u/z8/P/9GRkb/MTEx/yYmJv9JSUn/YGBg/7Gxsf+qqqr/Ly8v/xgYGP8kJCT/IiIi/x0d + Hf8fHx//IiIi/yMjI/8jIyP/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/2BgYP/MzMz/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Ozs7/zs7O/87Ozv/Ozs7/zs7O/87O + zv/Ozs7/zc3N/83Nzf/Nzc3/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zc3N/83N + zf/Nzc3/ysrK/11dXf8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yUlJf8lJSX/JCQk/yQk + JP8fHx//CQkJ/wcHB/9FRUX/kJCQ/62trf+6urr/vLy8/7+/v//BwcH/xMTE/8bGxv/IyMj/ysrK/8zM + zP/Ozs7/0NDQ/9HR0f/T09P/1NTU/9XV1f/X19f/2NjY/9ra2v/b29v/3Nzc/93d3f/e3t7/4ODg/+Hh + 4f/i4uL/4+Pj/+Pj4zH///8B////Af///wH///8BxcXF48LCwv+/v7//vLy8/7i4uP+zs7P/qqqq/4iI + iP9+fn7/fn5+/2lpaf83Nzf/VlZW/4aGhv+YmJj/oaGh/3x8fP8+Pj7/TU1N/3h4eP9oaGj/NjY2/xkZ + Gf8TExP/IyMj/z4+Pv8eHh7/IiIi/yQkJP8cHBz/Hh4e/yIiIv8jIyP/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/aGho/8zMzP/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Ozs7/zs7O/87Ozv/Ozs7/zs7O/83Nzf/Nzc3/zc3N/83Nzf/MzMz/zMzM/8zM + zP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/Nzc3/zc3N/83Nzf/Nzc3/a2tr/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8lJSX/JSUl/yQkJP8mJib/NjY2/y0tLf8aGhr/Q0ND/5GRkf+urq7/ubm5/7y8 + vP+/v7//wcHB/8PDw//FxcX/yMjI/8rKyv/MzMz/zc3N/8/Pz//R0dH/09PT/9TU1P/V1dX/19fX/9jY + 2P/Z2dn/29vb/9zc3P/d3d3/3t7e/9/f3//g4OD/4eHh/+Li4v/j4+P/5OTkMf///wH///8B////Af// + /wHFxcXjwsLC/7+/v/+8vLz/uLi4/7S0tP+jo6P/hISE/4CAgP+AgID/aWlp/zY2Nv9cXFz/l5eX/6Oj + o/+AgID/RUVF/0lJSf9ycnL/g4OD/4ODg/+1tbX/S0tL/w4ODv8iIiL/Ozs7/x8fH/8eHh7/Hh4e/x4e + Hv8jIyP/JSUl/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP9hYWH/zMzM/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zM + zP/MzMz/zc3N/8vLy/9qamr/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yUlJf8kJCT/JCQk/zQ0 + NP9MTEz/X19f/2pqav+SkpL/s7Oz/7m5uf+7u7v/vr6+/8DAwP/Dw8P/xcXF/8fHx//Kysr/zMzM/83N + zf/Pz8//0dHR/9PT0//U1NT/1dXV/9fX1//Y2Nj/2dnZ/9ra2v/c3Nz/3d3d/97e3v/f39//4ODg/+Hh + 4f/i4uL/4+Pj/+Tk5P/k5OQx////Af///wH///8B////AcbGxuPDw8P/wMDA/7y8vP+5ubn/sbGx/5KS + kv+CgoL/goKC/4GBgf9lZWX/NDQ0/1xcXP+ioqL/iIiI/0VFRf9ERET/dHR0/4SEhP+BgYH/3t7e//z8 + /P+wsLD/Li4u/ycnJ/8bGxv/FBQU/xoaGv8gICD/JSUl/yYmJv8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/1FRUf/Ly8v/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zMzM/8zM + zP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/x8fH/1xcXP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yMjI/8jIyP/LS0t/0RERP9oaGj/hoaG/6+vr/+5ubn/vLy8/76+ + vv/AwMD/wsLC/8TExP/Hx8f/ycnJ/8vLy//Nzc3/z8/P/9DQ0P/S0tL/1NTU/9XV1f/X19f/2NjY/9nZ + 2f/a2tr/3Nzc/93d3f/e3t7/39/f/+Dg4P/h4eH/4uLi/+Pj4//k5OT/5eXl/+Xl5TH///8B////Af// + /wH///8BxsbG48TExP/BwcH/vb29/7q6uv+np6f/h4eH/4ODg/+Dg4P/g4OD/2VlZf8zMzP/Q0ND/4CA + gP9MTEz/QkJC/2hoaP+Hh4f/enp6/9DQ0P/9/f3/4ODg/1VVVf8ZGRn/Hx8f/xkZGf8WFhb/Hh4e/yUl + Jf8mJib/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/Ojo6/8HB + wf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zM + zP/MzMz/zMzM/8zMzP+8vLz/R0dH/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8iIiL/IiIi/xAQ + EP8GBgb/NjY2/4GBgf+hoaH/ubm5/7u7u/++vr7/wMDA/8LCwv/ExMT/xsbG/8nJyf/Ly8v/zc3N/8/P + z//Q0ND/0tLS/9TU1P/V1dX/19fX/9jY2P/Z2dn/2tra/9zc3P/d3d3/3t7e/9/f3//g4OD/4eHh/+Li + 4v/j4+P/5OTk/+Xl5f/l5eX/5ubmMf///wH///8B////Af///wHHx8fjxMTE/8HBwf++vr7/u7u7/5iY + mP+EhIT/hYWF/4WFhf+IiIj/dnZ2/zc3N/8sLCz/RUVF/0NDQ/9paWn/hYWF/319ff/IyMj/+/v7/+Dg + 4P9lZWX/FhYW/x0dHf8kJCT/Hh4e/x8fH/8jIyP/JSUl/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8mJib/n5+f/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/8zM + zP/MzMz/zMzM/8zMzP/MzMz/zMzM/8vLy//Ly8v/y8vL/8vLy//Ly8v/ysrK/5ycnP8yMjL/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/IiIi/yEhIf8TExP/AwMD/yoqKv+BgYH/qamp/7i4uP+8vLz/vr6+/8DA + wP/CwsL/xMTE/8fHx//Jycn/y8vL/83Nzf/Pz8//0dHR/9PT0//U1NT/1dXV/9fX1//Y2Nj/2dnZ/9vb + 2//c3Nz/3d3d/97e3v/f39//4ODg/+Hh4f/i4uL/4+Pj/+Tk5P/l5eX/5eXl/+bm5v/m5uYx////Af// + /wH///8B////AcjIyOPFxcX/wsLC/7+/v/+8vLz/k5OT/4WFhf+Ghob/iIiI/5KSkv+Ojo7/QkJC/yoq + Kv9eXl7/cHBw/4ODg/93d3f/vr6+//n5+f/n5+f/dHR0/xwcHP8cHBz/JSUl/x4eHv8fHx//JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP9wcHD/xsbG/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/8zMzP/MzMz/zMzM/8zMzP/Ly8v/y8vL/8vL + y//Ly8v/y8vL/8vLy//FxcX/eHh4/ykpKf8kJCT/JCQk/yQkJP8kJCT/JCQk/yMjI/8hISH/ExMT/wMD + A/8bGxv/dHR0/6Wlpf+4uLj/vLy8/76+vv/AwMD/wsLC/8TExP/Gxsb/ycnJ/8vLy//Nzc3/z8/P/9DQ + 0P/S0tL/09PT/9XV1f/X19f/2NjY/9nZ2f/a2tr/3Nzc/93d3f/e3t7/39/f/+Dg4P/h4eH/4uLi/+Pj + 4//j4+P/5OTk/+Xl5f/m5ub/5+fn/+fn5zH///8B////Af///wH///8ByMjI48bGxv/ExMT/wcHB/729 + vf+SkpL/hoaG/4iIiP+RkZH/oKCg/5eXl/9HR0f/JSUl/1JSUv+Li4v/gICA/66urv/6+vr/8fHx/3x8 + fP8eHh7/Gxsb/yUlJf8fHx//Hh4e/yIiIv8kJCT/JCQk/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/z4+Pv+np6f/zMzM/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zMzM/8zMzP/MzMz/zMzM/8vLy//Ly8v/y8vL/8vLy//Ly8v/y8vL/7CwsP9JSUn/JCQk/yQk + JP8kJCT/JCQk/yQkJP8jIyP/IyMj/xgYGP8EBAT/ExMT/2dnZ/+ampr/tra2/7y8vP++vr7/wMDA/8LC + wv/ExMT/xsbG/8nJyf/Ly8v/zMzM/8/Pz//Q0ND/0tLS/9PT0//U1NT/1tbW/9fX1//Z2dn/2tra/9zc + 3P/d3d3/3t7e/9/f3//g4OD/4eHh/+Li4v/j4+P/4+Pj/+Tk5P/l5eX/5ubm/+fn5//n5+f/5+fnMf// + /wH///8B////Af///wHJycnjx8fH/8XFxf/CwsL/vr6+/5KSkv+JiYn/kZGR/6CgoP+fn5//Y2Nj/zo6 + Ov8sLCz/Kioq/21tbf+QkJD/w8PD/+zs7P+RkZH/Hh4e/xoaGv8kJCT/ICAg/x0dHf8gICD/IyMj/yMj + I/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/KCgo/2dnZ//CwsL/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zMzM/8zMzP/MzMz/zMzM/8vL + y//Ly8v/y8vL/8vLy//Gxsb/ZmZm/ycnJ/8kJCT/JCQk/yQkJP8kJCT/IyMj/yIiIv8XFxf/BAQE/xkZ + Gf9oaGj/np6e/7S0tP+8vLz/vr6+/8DAwP/CwsL/xMTE/8fHx//IyMj/y8vL/8zMzP/Ozs7/0NDQ/9LS + 0v/T09P/1NTU/9bW1v/X19f/2dnZ/9ra2v/c3Nz/3d3d/97e3v/f39//4ODg/+Hh4f/i4uL/4+Pj/+Pj + 4//k5OT/5eXl/+bm5v/n5+f/5+fn/+jo6P/o6Ogx////Af///wH///8B////AcrKyuPIyMj/xsbG/8PD + w/+/v7//kpKS/5CQkP+dnZ3/o6Oj/3R0dP88PDz/Tk5O/2FhYf8vLy//LCws/z4+Pv8+Pj7/cHBw/zAw + MP8ZGRn/IyMj/yEhIf8dHR3/ICAg/yIiIv8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMj + I/8jIyP/IyMj/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/Li4u/5OTk//MzMz/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zMzM/8zMzP/MzMz/y8vL/8vLy//Ly8v/ycnJ/56env8xMTH/JCQk/yQk + JP8kJCT/IyMj/yMjI/8mJib/ISEh/wcHB/8KCgr/YWFh/5mZmf+2trb/vLy8/76+vv/AwMD/wsLC/8TE + xP/Gxsb/yMjI/8rKyv/MzMz/zs7O/9DQ0P/S0tL/09PT/9TU1P/W1tb/19fX/9nZ2f/a2tr/29vb/9zc + 3P/e3t7/39/f/+Dg4P/h4eH/4eHh/+Pj4//j4+P/5OTk/+Xl5f/l5eX/5ubm/+fn5//o6Oj/6Ojo/+np + 6TH///8B////Af///wH///8By8vL48nJyf/Hx8f/xcXF/7+/v/+YmJj/np6e/6Ojo/9ycnL/PT09/1JS + Uv96enr/fX19/3p6ev9RUVH/ERER/xISEv9MTEz/Pz8//yEhIf8iIiL/Hx8f/x8fH/8iIiL/IyMj/yMj + I/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/Nzc3/5WVlf/IyMj/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/MzMz/zMzM/8zM + zP/MzMz/y8vL/8rKyv+dnZ3/QEBA/yQkJP8kJCT/JCQk/yQkJP8jIyP/KSkp/0FBQf9RUVH/U1NT/2lp + af+qqqr/tra2/729vf+/v7//wcHB/8PDw//ExMT/x8fH/8jIyP/Kysr/zMzM/87Ozv/Q0ND/0tLS/9PT + 0//U1NT/1tbW/9fX1//Z2dn/2tra/9vb2//d3d3/3d3d/9/f3//g4OD/4eHh/+Li4v/i4uL/5OTk/+Tk + 5P/l5eX/5ubm/+bm5v/n5+f/6Ojo/+np6f/p6en/6enpMf///wH///8B////Af///wHMzMzjysrK/8jI + yP/Gxsb/wcHB/6Ojo/+mpqb/fX19/0FBQf9HR0f/dnZ2/4GBgf+Ghob/4eHh/9PT0/9MTEz/KSkp/zMz + M/8gICD/Ghoa/xwcHP8gICD/ISEh/yIiIv8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMj + I/8jIyP/IyMj/yMjI/8jIyP/IyMj/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8lJSX/QEBA/5aW + lv/Ly8v/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/MzMz/zMzM/8zMzP/Kysr/qamp/0lJSf8mJib/JCQk/yQk + JP8kJCT/IyMj/yQkJP8zMzP/SkpK/1tbW/94eHj/mJiY/7q6uv+8vLz/v7+//8HBwf/Dw8P/xcXF/8bG + xv/IyMj/ysrK/8zMzP/Ozs7/0NDQ/9LS0v/T09P/1NTU/9bW1v/X19f/2dnZ/9ra2v/c3Nz/3Nzc/93d + 3f/e3t7/39/f/+Dg4P/h4eH/4uLi/+Pj4//k5OT/5eXl/+bm5v/m5ub/5+fn/+jo6P/o6Oj/6enp/+rq + 6v/q6uox////Af///wH///8B////Ac3NzePLy8v/ycnJ/8fHx//ExMT/rKys/4SEhP9ERET/R0dH/29v + b/+CgoL/hYWF/+Li4v/7+/v/wMDA/zY2Nv8eHh7/HR0d/xISEv8ZGRn/Hh4e/yEhIf8iIiL/IyMj/yMj + I/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMj + I/8jIyP/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/MzMz/4KCgv+6urr/zMzM/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/8zM + zP/MzMz/v7+//4qKiv9AQED/JSUl/yQkJP8kJCT/JCQk/yMjI/8iIiL/ICAg/xISEv8nJyf/YWFh/42N + jf+ysrL/vb29/7+/v//BwcH/w8PD/8XFxf/Hx8f/ycnJ/8rKyv/MzMz/zs7O/9DQ0P/S0tL/09PT/9TU + 1P/W1tb/19fX/9nZ2f/a2tr/29vb/93d3f/d3d3/3t7e/9/f3//g4OD/4eHh/+Li4v/j4+P/5OTk/+Xl + 5f/m5ub/5ubm/+fn5//o6Oj/6Ojo/+np6f/q6ur/6urq/+vr6zH///8B////Af///wH///8Bz8/P483N + zf/Kysr/yMjI/8bGxv+jo6P/SkpK/0NDQ/9sbGz/goKC/35+fv/R0dH/+/v7/8zMzP9KSkr/ExMT/x0d + Hf8hISH/GRkZ/x4eHv8hISH/IiIi/yMjI/8jIyP/IyMj/yMjI/8iIiL/IiIi/yQiIf8iIiL/IiIi/yMj + I/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8kJCT/JCQk/yQk + JP8kJCT/LCws/1dXV/+jo6P/xsbG/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83N + zf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/x8fH/6mpqf9kZGT/Ly8v/yQkJP8kJCT/JCQk/yQk + JP8jIyP/IiIi/x4eHv8LCwv/BwcH/0BAQP+QkJD/sbGx/729vf/AwMD/wcHB/8PDw//FxcX/x8fH/8nJ + yf/Ly8v/zMzM/87Ozv/Q0ND/0tLS/9PT0//U1NT/1tbW/9fX1//Z2dn/2tra/9vb2//c3Nz/3d3d/97e + 3v/f39//4ODg/+Hh4f/i4uL/4+Pj/+Tk5P/k5OT/5ubm/+bm5v/n5+f/6Ojo/+jo6P/p6en/6urq/+rq + 6v/r6+v/6+vrMf///wH///8B////Af///wHPz8/jzs7O/8zMzP/Kysr/yMjI/7e3t/9vb2//aGho/4OD + g/94eHj/y8vL//v7+//T09P/VFRU/xcXF/8dHR3/IyMj/xwcHP8dHR3/ISEh/yMjI/8jIyP/IyMj/yIi + Iv8iIiL/IiIi/yIiIv86Ih7/ciQW/0AhHP8jISH/IiIi/yIiIv8jIyP/IyMj/yMjI/8jIyP/IyMj/yMj + I/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yQkJP8kJCT/JiYm/zo6Ov9oaGj/o6Oj/8HB + wf/Jycn/zMzM/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/8zMzP/Jycn/xMTE/62t + rf9wcHD/Pz8//ycnJ/8kJCT/JCQk/yQkJP8kJCT/IyMj/yIiIv8gICD/DAwM/wMDA/89PT3/h4eH/7Cw + sP+9vb3/v7+//8LCwv/ExMT/xsbG/8fHx//Jycn/y8vL/83Nzf/Pz8//0NDQ/9LS0v/T09P/1NTU/9bW + 1v/X19f/2dnZ/9ra2v/b29v/3Nzc/93d3f/e3t7/39/f/+Dg4P/h4eH/4uLi/+Li4v/j4+P/5OTk/+Xl + 5f/m5ub/5+fn/+jo6P/o6Oj/6enp/+rq6v/q6ur/6+vr/+vr6//s7Owx////Af///wH///8B////AdHR + 0ePPz8//zc3N/8vLy//Jycn/x8fH/7W1tf+SkpL/e3t7/76+vv/+/v7/5OTk/1paWv8UFBT/HBwc/yQk + JP8bGxv/HBwc/yEhIf8kJCT/IyMj/yMjI/8iIiL/IiIi/yIiIv8iIiL/NSIe/5EnFP/CLBH/ZCUa/yYi + If8iIiL/IiIi/yIiIv8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMj + I/8jIyP/IyMj/yQkJP8kJCT/JCQk/yQkJP8tLS3/TU1N/3Z2dv+goKD/rq6u/7q6uv/BwcH/yMjI/8nJ + yf/Hx8f/xcXF/729vf+urq7/m5ub/3p6ev9VVVX/MzMz/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yMj + I/8iIiL/ICAg/w4ODv8CAgL/Kioq/42Njf+tra3/vb29/8DAwP/CwsL/xMTE/8bGxv/IyMj/ysrK/8vL + y//Nzc3/z8/P/9DQ0P/S0tL/09PT/9TU1P/W1tb/19fX/9nZ2f/a2tr/3Nzc/93d3f/d3d3/3t7e/9/f + 3//g4OD/4eHh/+Li4v/i4uL/4+Pj/+Tk5P/l5eX/5ubm/+fn5//n5+f/6Ojo/+np6f/p6en/6urq/+vr + 6//r6+v/7Ozs/+zs7DH///8B////Af///wH///8B0tLS49DQ0P/Ozs7/zMzM/8vLy//Jycn/xsbG/7Ky + sv+xsbH/9PT0/+np6f98fHz/GRkZ/xkZGf8jIyP/Hx8f/xwcHP8hISH/JSUl/yQkJP8jIyP/IiIi/yIi + Iv8iIiL/IiIi/ykhIP9/JRX/xCwR/4UoGP8qIiH/IiIi/yIiIv8iIiL/IiIi/yMjI/8jIyP/IyMj/yMj + I/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8kJCT/JCQk/yQk + JP8kJCT/KCgo/zY2Nv9AQED/TExM/1lZWf9qamr/bW1t/2hoaP9iYmL/UVFR/0FBQf8zMzP/KCgo/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/IyMj/yEhIf8QEBD/AgIC/yAgIP90dHT/qqqq/7y8 + vP/AwMD/wsLC/8TExP/Gxsb/yMjI/8rKyv/MzMz/zc3N/8/Pz//R0dH/0tLS/9PT0//U1NT/1tbW/9fX + 1//Z2dn/2tra/9zc3P/c3Nz/3d3d/97e3v/f39//4ODg/+Hh4f/i4uL/4uLi/+Pj4//k5OT/5eXl/+bm + 5v/m5ub/5+fn/+jo6P/p6en/6enp/+rq6v/r6+v/6+vr/+zs7P/s7Oz/7OzsMf///wH///8B////Af// + /wHU1NTj0tLS/9DQ0P/Ozs7/zMzM/8rKyv/IyMj/wsLC/5GRkf+kpKT/cHBw/xsbG/8ZGRn/IiIi/x8f + H/8eHh7/IyMj/yYmJv8lJSX/IyMj/yIiIv8iIiL/IiIi/yIiIv8sIR//eSYX/8UtEf+CKBj/LiIg/yIi + Iv8iIiL/IiIi/yIiIv8iIiL/IiIi/yQiIv8jIyP/IyMj/yMjI/8jIiL/LCIh/0sjHP9vJRj/NSIf/yMj + I/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/IyMj/yQk + JP8nJyf/ERER/wICAv8lJSX/fX19/6ampv++vr7/wcHB/8PDw//ExMT/xsbG/8jIyP/Kysr/zMzM/83N + zf/Pz8//0dHR/9PT0//U1NT/1dXV/9bW1v/X19f/2dnZ/9ra2v/b29v/3d3d/93d3f/e3t7/39/f/+Dg + 4P/h4eH/4uLi/+Pj4//j4+P/5OTk/+Xl5f/m5ub/5+fn/+fn5//o6Oj/6enp/+np6f/q6ur/6urq/+vr + 6//r6+v/7Ozs/+3t7f/t7e0x////Af///wH///8B////AdXV1ePT09P/0dHR/8/Pz//Nzc3/zMzM/8rK + yv/BwcH/aGho/zs7O/9DQ0P/ISEh/yIiIv8eHh7/HR0d/yIiIv8mJib/JSUl/yMjI/8iIiL/IiIi/yIi + Iv8hISH/JCEh/3QlF//DLBD/tSsS/z4iHf8iISH/IiIi/yIiIv8iIiL/IiEh/yohH/9JIhz/YiIX/zch + Hf8kIiL/JiIh/0ciG/9+Jhb/jCgW/7csE/9GJB7/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMj + I/8jIyP/IyMj/yMjI/8kJCT/JCQk/yQkJP8kJCT/IyMj/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8jIyP/Li4u/z4+Pv8sLCz/Kysr/35+fv+qqqr/vLy8/8HB + wf/Dw8P/xcXF/8bGxv/IyMj/ysrK/8zMzP/Nzc3/z8/P/9HR0f/T09P/1NTU/9XV1f/X19f/2NjY/9nZ + 2f/a2tr/3Nzc/9zc3P/d3d3/3t7e/9/f3//g4OD/4eHh/+Li4v/i4uL/4+Pj/+Tk5P/l5eX/5ubm/+bm + 5v/n5+f/6Ojo/+jo6P/p6en/6urq/+rq6v/r6+v/7Ozs/+zs7P/t7e3/7e3t/+7u7jH///8B////Af// + /wH///8B1dXV49TU1P/T09P/0dHR/8/Pz//Nzc3/y8vL/8LCwv9vb2//U1NT/0dHR/8tLS3/JiYm/x4e + Hv8iIiL/JSUl/yUlJf8jIyP/IyMj/yIiIv8hISH/ISEh/yYgIP9fIxj/xSwR/7QsE/+7KxL/lycT/1Ui + GP80IR7/OSEc/0ohGv9tIxb/nygT/7wrEv+6LBL/hiYV/1MiGf98Jhb/kSgV/2QmG/9YJhz/nisW/ywj + If8jIiL/MyIf/z8iHf8vIiD/IyIi/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMj + I/8jIyP/IyMj/yMjI/8jIyP/IyMj/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8jIyP/IyMj/yYm + Jv9DQ0P/UVFR/2xsbP9/f3//s7Oz/7+/v//BwcH/xMTE/8XFxf/Hx8f/ycnJ/8rKyv/MzMz/zs7O/9DQ + 0P/R0dH/09PT/9TU1P/V1dX/19fX/9jY2P/Z2dn/2tra/9vb2//c3Nz/3d3d/97e3v/f39//4ODg/+Hh + 4f/i4uL/4+Pj/+Pj4//k5OT/5eXl/+bm5v/n5+f/5+fn/+jo6P/o6Oj/6enp/+rq6v/q6ur/6+vr/+vr + 6//s7Oz/7Ozs/+3t7f/u7u7/7u7uMf///wH///8B////Af///wHX19fj1dXV/9TU1P/S0tL/0NDQ/8/P + z//Nzc3/xcXF/35+fv9PT0//MDAw/ywsLP8mJib/ISEh/yQkJP8lJSX/IyMj/yMjI/8iIiL/IiIi/yEh + If8jICD/YiMZ/7srEf+fKhX/QSMd/1QkHP+eKhX/vCoQ/64pEf+sKBH/tioR/7ErE/+ZKhb/dCca/1Ml + HP98JRb/mCgU/3EnGv85JCD/JiMi/2smGv95KBn/IyMi/zQjIP+PJxT/hicW/3AkFv84Ix//IyIi/yMj + Iv8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/JCQk/yQk + JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yMjI/8jIyP/Hh4e/zIyMv9PT0//e3t7/5ycnP+9vb3/w8PD/8TE + xP/Gxsb/yMjI/8nJyf/Ly8v/zc3N/87Ozv/Q0ND/0dHR/9PT0//U1NT/1dXV/9fX1//Y2Nj/2dnZ/9ra + 2v/c3Nz/3Nzc/93d3f/e3t7/39/f/+Dg4P/h4eH/4uLi/+Pj4//k5OT/5OTk/+Xl5f/m5ub/5+fn/+fn + 5//o6Oj/6Ojo/+np6f/q6ur/6urq/+vr6//r6+v/7Ozs/+3t7f/t7e3/7e3t/+7u7v/u7u4x////Af// + /wH///8B////AdjY2OPX19f/1dXV/9PT0//S0tL/0NDQ/8/Pz//IyMj/gYGB/zc3N/8sLCz/KCgo/yEh + If8hISH/IyMj/yQkJP8jIyP/IiIi/yIiIv8hISH/ISEh/1EjG/+7KxH/tisS/0QjHf8iISD/IiEg/zUi + Hv9rJhn/tysS/7YqEf9eJBr/PiMe/y8iIP8lIiH/JCIh/0wkHf9DJB7/KCMi/yIiIv8qIiH/hSgX/1Ym + Hf8nIiH/QyQe/5YpFf9IIxz/TyUd/4gnFv9aJBn/JSIi/yMiIv8jIiL/IyMj/yMjI/8jIyP/IyMj/yMj + I/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/JCQk/yQkJP8kJCT/JCQk/yMjI/8jIyP/IyMj/xoa + Gv8GBgb/FxcX/2RkZP+enp7/u7u7/8PDw//FxcX/x8fH/8jIyP/Kysr/zMzM/87Ozv/Pz8//0NDQ/9LS + 0v/T09P/1dXV/9bW1v/X19f/2NjY/9ra2v/a2tr/3Nzc/9zc3P/d3d3/3t7e/9/f3//g4OD/4eHh/+Li + 4v/j4+P/5OTk/+Tk5P/l5eX/5ubm/+bm5v/n5+f/6Ojo/+jo6P/p6en/6enp/+rq6v/r6+v/6+vr/+zs + 7P/s7Oz/7e3t/+3t7f/u7u7/7u7u/+7u7jH///8B////Af///wH///8B2tra49jY2P/W1tb/1NTU/9PT + 0//S0tL/0NDQ/8XFxf9kZGT/LS0t/ygoKP8iIiL/IiIi/yMjI/8kJCT/IyMj/yMjI/8iIiL/IiIi/yEh + If8oISD/gCcX/8ctEf+gKBP/QSEb/yYgH/8gICD/ICAg/yAgH/9MIxz/tisS/34mFv8mISD/ISEh/yYh + IP83IR3/RSIb/0MiHP8zIR7/IyEh/0IkHv+ZKRX/OyMf/1ckG/9zJRf/WSUc/4MmFf9uJBf/pSoU/1Yl + HP9EIx3/SyMc/zMiH/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMj + I/8kJCT/JCQk/yQkJP8kJCT/IyMj/yIiIv8ZGRn/BQUF/wwMDP9bW1v/oaGh/7+/v//FxcX/xsbG/8jI + yP/Jycn/y8vL/8zMzP/Ozs7/0NDQ/9HR0f/T09P/1NTU/9XV1f/X19f/2NjY/9nZ2f/a2tr/29vb/9zc + 3P/d3d3/3t7e/9/f3//g4OD/4ODg/+Hh4f/i4uL/4+Pj/+Tk5P/k5OT/5eXl/+bm5v/n5+f/5+fn/+jo + 6P/o6Oj/6enp/+rq6v/q6ur/6+vr/+vr6//s7Oz/7e3t/+3t7f/u7u7/7u7u/+7u7v/v7+//7+/vMf// + /wH///8B////Af///wHa2trj2dnZ/9fX1//W1tb/1NTU/9PT0//S0tL/w8PD/1dXV/8sLCz/IyMj/yEh + If8jIyP/JCQk/yQkJP8jIyP/IyMj/yIiIv8iIiL/IiIi/yEhIf8zIh//aiYa/64qE/+uKRH/bSMW/y0f + Hf8gICD/ICAg/zshHf+tKhL/oioU/y0hH/8rIB7/bCMW/6QpEv+0KhH/rykR/5onEv9aIhj/WiQa/3cn + Gf8pIiH/SSQd/40nFP9YIhn/fiYW/6YqFP9dJRv/WSQa/5goFf+JKBb/gCYW/zUiHv8kIiL/IyMj/yMj + I/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yQkJP8kJCT/JCQk/yMjI/8iIiL/HBwc/wcH + B/8GBgb/SkpK/5ycnP+9vb3/xcXF/8fHx//Jycn/ysrK/8zMzP/Nzc3/zs7O/9DQ0P/S0tL/09PT/9XV + 1f/W1tb/19fX/9nZ2f/Z2dn/2tra/9vb2//d3d3/3d3d/97e3v/f39//4ODg/+Dg4P/h4eH/4uLi/+Pj + 4//k5OT/5OTk/+Xl5f/m5ub/5ubm/+fn5//o6Oj/6Ojo/+np6f/p6en/6urq/+vr6//r6+v/7Ozs/+zs + 7P/t7e3/7e3t/+7u7v/u7u7/7+/v/+/v7//w8PAx////Af///wH///8B////Advb2+Pa2tr/2dnZ/9fX + 1//W1tb/1NTU/9PT0//CwsL/UFBQ/yQkJP8hISH/IyMj/yQkJP8kJCT/JCQk/yMjI/8jIyP/IiIi/yIi + Iv8iIiL/ISEh/yEhIf8iISD/OSIe/3wnGP+zKhL/nycR/2YiFv9WIRf/kCUS/8UsEf93Jxn/MSEe/4Ul + FP+5KxL/gygX/0wkHf9FIx3/dicY/68qEv98JRb/KiIg/yIiIf8kIiH/QyMe/38nGP+NKRb/XCYb/1wk + Gv+dKRT/SyUe/ykjIv98KBn/licU/z0iHv8tIiD/JSIi/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMj + I/8jIyP/JCQk/yMjI/8jIyP/JCQk/yEhIf8JCQn/CQkJ/0hISP+YmJj/wMDA/8fHx//IyMj/ycnJ/8vL + y//MzMz/zs7O/8/Pz//R0dH/0tLS/9TU1P/V1dX/19fX/9jY2P/Z2dn/2tra/9vb2//c3Nz/3d3d/97e + 3v/e3t7/39/f/+Dg4P/h4eH/4uLi/+Li4v/j4+P/5OTk/+Tk5P/l5eX/5ubm/+fn5//n5+f/6Ojo/+jo + 6P/p6en/6urq/+rq6v/r6+v/6+vr/+zs7P/s7Oz/7e3t/+3t7f/u7u7/7u7u/+/v7//v7+//8PDw//Dw + 8DH///8B////Af///wH///8B3d3d49zc3P/a2tr/2dnZ/9fX1//W1tb/1NTU/8DAwP9GRkb/IiIi/yMj + I/8kJCT/JCQk/yQkJP8kJCT/IyMj/yMjI/8jIyP/IiIi/yIiIv8iIiL/ISEh/yEhIf8hISH/JyEg/04j + HP+QKBX/tioR/70rEP+3KxL/gygX/zsiHv9tJRj/viwR/3AmGf8rISD/ISEh/yEhIf8nISD/dicY/7Eq + Ev88Ih7/IiIi/yIiIv8iIiL/JiIh/ykiIf82Ih7/likV/10mHP8kIiL/OCIe/5UpFv9pJxv/RCMe/3Ym + F/8xIyD/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8kJCT/IyMj/yMjI/8jIyP/CgoK/wQE + BP9AQED/kpKS/7u7u//IyMj/ycnJ/8vLy//MzMz/zs7O/8/Pz//Q0ND/0dHR/9PT0//U1NT/1tbW/9fX + 1//Y2Nj/2tra/9vb2//c3Nz/3Nzc/97e3v/e3t7/39/f/+Dg4P/g4OD/4eHh/+Li4v/i4uL/4+Pj/+Tk + 5P/l5eX/5eXl/+bm5v/m5ub/5+fn/+jo6P/o6Oj/6enp/+rq6v/q6ur/6+vr/+vr6//s7Oz/7Ozs/+3t + 7f/t7e3/7u7u/+7u7v/v7+//7+/v/+/v7//w8PD/8PDwMf///wH///8B////Af///wHe3t7j3d3d/9zc + 3P/a2tr/2dnZ/9fX1//W1tb/y8vL/2hoaP8sLCz/IyMj/yMjI/8kJCT/JCQk/yMjI/8jIyP/IyMj/yMj + I/8iIiL/IiIi/yIiIv8hISH/ISEh/yEhIf8hISH/ISEg/ywhH/9BIx3/TyQc/0AjHv8pISD/NCIe/6Iq + FP+cKRX/KyEf/yEhIf8hISH/ISEh/yQhIP9sJRj/vSsR/0sjHf8hISH/MCEf/0QiHP8oISD/IiIi/yci + If9CJB7/JyIh/zciH/+IJxX/cica/0YkHf+RKBX/YiYc/zoiHv9kJBn/RyMd/yUiIv8jIyP/IyMj/yMj + I/8jIyP/IyMj/yMjI/8lJSX/MTEx/x8fH/8NDQ3/Pz8//5WVlf+5ubn/ycnJ/8vLy//MzMz/zc3N/8/P + z//Q0ND/0dHR/9LS0v/U1NT/1dXV/9bW1v/X19f/2dnZ/9ra2v/b29v/3Nzc/93d3f/e3t7/39/f/+Dg + 4P/g4OD/4eHh/+Li4v/i4uL/4+Pj/+Tk5P/k5OT/5eXl/+bm5v/m5ub/5+fn/+fn5//o6Oj/6enp/+np + 6f/q6ur/6urq/+vr6//r6+v/7Ozs/+zs7P/t7e3/7e3t/+7u7v/u7u7/7u7u/+/v7//v7+//8PDw//Dw + 8P/x8fEx////Af///wH///8B////Ad/f3+Pe3t7/3d3d/9zc3P/a2tr/2dnZ/9jY2P/X19f/xMTE/4yM + jP89PT3/JiYm/yMjI/8kJCT/IyMj/yMjI/8jIyP/IyMj/yMjI/8iIiL/IiIi/yIiIv8iIiL/IiIi/yEh + If8hISH/ISEh/yEhIf8hISH/ISEh/yEhIf8zIh//oioU/5AoFf8jICD/ISEh/yEhIf8gICD/OiEc/6Ao + Ev+rKhP/MiIf/ysgHv+EJhX/rikR/0QjHf8iIiL/IiIi/yIiIv8iIiL/TiMc/24nGv9CIx7/kikW/3co + Gf89Ix7/hicX/4EpGf9iJhv/KiMi/yMjI/8jIyP/IyMj/yMjI/8iIiL/JCQk/zg4OP9SUlL/XV1d/2Ji + Yv+ZmZn/xMTE/8zMzP/MzMz/zs7O/8/Pz//Q0ND/0dHR/9LS0v/U1NT/1dXV/9bW1v/X19f/2NjY/9nZ + 2f/b29v/3Nzc/93d3f/e3t7/39/f/9/f3//g4OD/4eHh/+Li4v/i4uL/4+Pj/+Pj4//k5OT/5eXl/+Xl + 5f/m5ub/5ubm/+fn5//o6Oj/6Ojo/+np6f/p6en/6urq/+rq6v/r6+v/7Ozs/+zs7P/t7e3/7e3t/+3t + 7f/u7u7/7u7u/+/v7//v7+//8PDw//Dw8P/w8PD/8fHx//Hx8TH///8B////Af///wH///8B4ODg49/f + 3//e3t7/3d3d/9zc3P/a2tr/2dnZ/9jY2P/X19f/0tLS/6qqqv9kZGT/Kysr/yMjI/8jIyP/IyMj/yMj + I/8jIyP/IyMj/yIiIv8iIiL/IiIi/yIiIv8iIiL/ISEh/yEhIf8hISH/ISEh/yEhIf8hISH/ISEh/yYh + IP9zJxn/sCoS/1QhGP8oIB7/IyAf/zcgG/+MJRP/visR/2YlGf8oIB//aSMX/78rEf+CKBj/LCIg/yIi + Iv8iIiH/IyIh/yIhIf8oIiH/NyIe/4AmFv99KBj/PSId/4EnFv95KBn/LSMi/yYjIv8jIyL/IyMj/yMj + I/8jIyP/IiIi/yIiIv8lJSX/OTk5/1NTU/9nZ2f/hYWF/7m5uf/Nzc3/zs7O/8/Pz//Q0ND/0dHR/9LS + 0v/T09P/1NTU/9bW1v/X19f/2NjY/9nZ2f/a2tr/29vb/9zc3P/d3d3/3t7e/9/f3//g4OD/4ODg/+Hh + 4f/i4uL/4+Pj/+Pj4//k5OT/5OTk/+Xl5f/m5ub/5ubm/+fn5//n5+f/6Ojo/+jo6P/p6en/6enp/+rq + 6v/r6+v/6+vr/+vr6//s7Oz/7Ozs/+3t7f/t7e3/7u7u/+7u7v/v7+//7+/v/+/v7//w8PD/8PDw//Hx + 8f/x8fH/8fHxMf///wH///8B////Af///wHh4eHj4ODg/9/f3//e3t7/3d3d/9zc3P/b29v/2tra/9nZ + 2f/Y2Nj/19fX/9TU1P+goKD/XFxc/y8vL/8iIiL/IyMj/yMjI/8jIyP/IyMj/yMjI/8iIiL/IiIi/yIi + Iv8iIiL/IiIi/yIiIv8iIiL/ISEh/yEhIf8hISH/ISEh/ykhIP9yJhj/qikS/54mEf+WJRH/rSgR/6sq + E/9kJRr/LyEe/3EkFv+/KxD/gygX/zAiH/8hISH/IiEh/zIiH/97JRX/VCMa/ysiIP9zJRf/eygZ/1Ek + HP+fKBP/likV/zMjIP8jIyP/IyMj/yMjI/8jIyP/IyMj/yIiIv8jIyP/JCQk/xEREf8HBwf/PT09/4GB + gf+0tLT/zs7O/8/Pz//R0dH/0tLS/9LS0v/T09P/1NTU/9XV1f/X19f/2NjY/9nZ2f/a2tr/29vb/9zc + 3P/d3d3/3t7e/9/f3//g4OD/4eHh/+Hh4f/i4uL/4+Pj/+Tk5P/k5OT/5eXl/+Xl5f/m5ub/5ubm/+fn + 5//n5+f/6Ojo/+jo6P/p6en/6enp/+rq6v/q6ur/6+vr/+vr6//s7Oz/7Ozs/+3t7f/t7e3/7u7u/+7u + 7v/u7u7/7+/v/+/v7//w8PD/8PDw//Hx8f/x8fH/8fHx//Ly8v/x8fEx////Af///wH///8B////AeLi + 4uPh4eH/4ODg/9/f3//e3t7/3d3d/9zc3P/b29v/2tra/9nZ2f/Y2Nj/19fX/9XV1f/ExMT/ioqK/0FB + Qf8kJCT/IyMj/yMjI/8jIyP/IyMj/yMjI/8iIiL/IiIi/yIiIv8iIiL/IiIi/yIiIv8iIiL/IiIi/yEh + If8hISH/ISEh/yghIP9FIx3/aCUZ/3UmGP9lJRn/QiMd/ychH/9YIhj/vSsR/5YpFf8wIh//ISEh/yEh + If8tIR//eSUW/7wsEf9lJhv/JyIh/0QkHv81IyD/YCUa/4spF/9UJR3/KyMh/yMjI/8jIyP/IyMj/yMj + I/8jIyP/IiIi/yQkJP8XFxf/AgIC/xwcHP95eXn/sbGx/87Ozv/Q0ND/0tLS/9PT0//U1NT/1NTU/9XV + 1f/W1tb/19fX/9nZ2f/a2tr/29vb/9vb2//d3d3/3d3d/9/f3//g4OD/4eHh/+Hh4f/i4uL/4+Pj/+Pj + 4//k5OT/5OTk/+Xl5f/m5ub/5ubm/+fn5//n5+f/6Ojo/+jo6P/p6en/6enp/+np6f/q6ur/6urq/+vr + 6//r6+v/7Ozs/+zs7P/t7e3/7e3t/+7u7v/u7u7/7+/v/+/v7//v7+//8PDw//Dw8P/w8PD/8fHx//Hx + 8f/y8vL/8vLy//Ly8jH///8B////Af///wH///8B4+Pj4+Li4v/h4eH/4ODg/9/f3//e3t7/3d3d/9zc + 3P/b29v/29vb/9ra2v/Z2dn/2NjY/9fX1//T09P/urq6/3t7e/81NTX/JSUl/yIiIv8jIyP/IyMj/yMj + I/8jIyP/IiIi/yIiIv8iIiL/IiIi/yIiIv8iIiL/IiIi/yEhIf8hISH/ISEh/yEhIP8iISD/JCEg/yIh + IP8lICD/WCIZ/7QqEf+sKxP/PiMe/yEhIP8hISH/KyAf/3klFv+7KxH/byca/yoiIf8iIiL/IyIi/y8i + IP9CIx3/MSMh/yQjIv8jIyL/IyMj/yMjI/8jIyP/IiIi/yMjI/8mJib/GBgY/wUFBf8eHh7/d3d3/7W1 + tf/Ozs7/0tLS/9PT0//U1NT/1dXV/9bW1v/X19f/19fX/9nZ2f/Z2dn/29vb/9zc3P/c3Nz/3t7e/97e + 3v/g4OD/4ODg/+Hh4f/i4uL/4+Pj/+Tk5P/k5OT/5eXl/+Xl5f/m5ub/5ubm/+fn5//n5+f/6Ojo/+jo + 6P/p6en/6enp/+rq6v/q6ur/6urq/+vr6//r6+v/7Ozs/+zs7P/t7e3/7e3t/+3t7f/u7u7/7u7u/+/v + 7//v7+//7+/v//Dw8P/w8PD/8PDw//Hx8f/x8fH/8vLy//Ly8v/y8vL/8/PzMf///wH///8B////Af// + /wHk5OTj5OTk/+Li4v/i4uL/4ODg/+Dg4P/e3t7/3t7e/93d3f/c3Nz/29vb/9ra2v/a2tr/2dnZ/9jY + 2P/X19f/09PT/6SkpP9gYGD/Kioq/yIiIv8jIyP/IyMj/yMjI/8jIyP/IyMj/yIiIv8iIiL/IiIi/yIi + Iv8iIiL/IiIi/yEhIf8hISH/ISEh/yEhIf8hISH/ISEh/zIhHv+TKBT/qCoT/6EpFP82IR3/ISAg/yYg + H/9nIxf/uysR/4MoF/8uIiD/IiIi/yIiIv8xIiD/iSgW/48oFf81IyD/IyMj/yMjI/8jIyP/IyMj/yMj + I/8iIiL/KSkp/x8fH/8FBQX/FRUV/2lpaf+urq7/0NDQ/9TU1P/V1dX/1dXV/9bW1v/X19f/2NjY/9nZ + 2f/Z2dn/29vb/9vb2//c3Nz/3d3d/97e3v/f39//4ODg/+Hh4f/i4uL/4+Pj/+Pj4//k5OT/5eXl/+Xl + 5f/m5ub/5ubm/+fn5//n5+f/6Ojo/+jo6P/p6en/6enp/+rq6v/q6ur/6urq/+vr6//r6+v/7Ozs/+zs + 7P/s7Oz/7e3t/+3t7f/u7u7/7u7u/+/v7//v7+//7+/v//Dw8P/w8PD/8PDw//Hx8f/x8fH/8fHx//Ly + 8v/y8vL/8vLy//Pz8//z8/Mx////Af///wH///8B////AeXl5ePl5eX/5OTk/+Pj4//i4uL/4eHh/+Dg + 4P/f39//3t7e/97e3v/c3Nz/3Nzc/9vb2//a2tr/2tra/9nZ2f/Y2Nj/1tbW/8nJyf+MjIz/RUVF/yYm + Jv8iIiL/IyMj/yMjI/8jIyP/IiIi/yIiIv8iIiL/IiIi/yIiIv8iIiL/IiIi/yEhIf8hISH/ISEh/yEh + If8hISH/JCEg/z0iHv9HIx3/pyoT/4gmE/9QIRj/dCQW/7orEf+OKRf/NCMf/yIiIv8iIiL/MCIf/4Em + Fv/ALRL/cCga/yojIv8jIyP/IyMj/yMjI/8jIyP/IiIi/yQkJP8eHh7/BQUF/wwMDP9hYWH/qamp/83N + zf/V1dX/1tbW/9fX1//X19f/2NjY/9nZ2f/a2tr/29vb/9zc3P/d3d3/3d3d/97e3v/f39//4ODg/+Hh + 4f/i4uL/4+Pj/+Pj4//k5OT/5eXl/+Xl5f/m5ub/5ubm/+fn5//n5+f/6Ojo/+jo6P/p6en/6enp/+rq + 6v/q6ur/6urq/+vr6//r6+v/6+vr/+zs7P/s7Oz/7e3t/+3t7f/t7e3/7u7u/+7u7v/v7+//7+/v/+/v + 7//w8PD/8PDw//Dw8P/x8fH/8fHx//Hx8f/y8vL/8vLy//Ly8v/z8/P/8/Pz//Pz8zH///8B////Af// + /wH///8B5ubm4+bm5v/l5eX/5OTk/+Pj4//i4uL/4eHh/+Hh4f/g4OD/39/f/9/f3//e3t7/3d3d/9zc + 3P/c3Nz/29vb/9ra2v/Z2dn/2dnZ/9fX1/+8vLz/fHx8/zg4OP8kJCT/IiIi/yMjI/8jIyP/IyMj/yIi + Iv8iIiL/IiIi/yIiIv8iIiL/IiIi/yIiIv8hISH/ISEh/yEhIf8hISH/ISEh/yMhIP9TJBz/nSkV/7gr + Ef+2KxL/uiwS/08kHP8iIiL/IiIi/yoiIP+AJhX/vywS/3YoGv8pIyL/IyMj/yMjI/8jIyP/IyMj/yIi + Iv8qKir/JSUl/wkJCf8RERH/Xl5e/6enp//Pz8//19fX/9jY2P/Y2Nj/2dnZ/9ra2v/a2tr/3Nzc/9zc + 3P/d3d3/3t7e/97e3v/f39//4ODg/+Hh4f/i4uL/4+Pj/+Tk5P/k5OT/5eXl/+Xl5f/m5ub/5+fn/+fn + 5//n5+f/6Ojo/+jo6P/p6en/6enp/+rq6v/q6ur/6+vr/+vr6//r6+v/7Ozs/+zs7P/s7Oz/7e3t/+3t + 7f/t7e3/7u7u/+7u7v/u7u7/7+/v/+/v7//w8PD/8PDw//Dw8P/x8fH/8fHx//Hx8f/y8vL/8vLy//Ly + 8v/z8/P/8/Pz//Pz8//z8/P/8/PzMf///wH///8B////Af///wHn5+fj5+fn/+bm5v/l5eX/5OTk/+Pj + 4//j4+P/4uLi/+Hh4f/g4OD/4ODg/9/f3//e3t7/3t7e/93d3f/c3Nz/29vb/9vb2//a2tr/2dnZ/9nZ + 2f/R0dH/pKSk/19fX/9LS0v/YmJi/2FhYf9PT0//LS0t/yIiIv8iIiL/IiIi/yIiIv8iIiL/IiIi/yIi + Iv8iIiL/ISEh/yEhIf8hISH/ISEh/yMhIP82Ix//TiQd/0okHf+iKhT/YCQZ/yQhIf8oISD/aCQY/8As + Ef+BKRn/MCMh/yMjI/8jIyP/IyMj/yMjI/8iIiL/Kysr/0xMTP9MTEz/QkJC/2RkZP+ysrL/zs7O/9jY + 2P/Z2dn/2dnZ/9ra2v/b29v/3Nzc/9zc3P/e3t7/3t7e/9/f3//g4OD/4ODg/+Hh4f/i4uL/4+Pj/+Pj + 4//k5OT/5eXl/+Xl5f/m5ub/5ubm/+fn5//n5+f/6Ojo/+jo6P/p6en/6enp/+np6f/q6ur/6urq/+vr + 6//r6+v/6+vr/+zs7P/s7Oz/7e3t/+3t7f/t7e3/7u7u/+7u7v/u7u7/7+/v/+/v7//v7+//8PDw//Dw + 8P/w8PD/8fHx//Hx8f/x8fH/8vLy//Ly8v/y8vL/8/Pz//Pz8//z8/P/8/Pz//T09P/z8/Mx////Af// + /wH///8B////Aejo6OPo6Oj/5+fn/+bm5v/m5ub/5eXl/+Tk5P/k5OT/4+Pj/+Li4v/h4eH/4eHh/+Dg + 4P/g4OD/39/f/97e3v/e3t7/3d3d/9zc3P/c3Nz/29vb/9ra2v/a2tr/1tbW/9TU1P/Y2Nj/19fX/9TU + 1P+1tbX/ZWVl/ysrK/8iIiL/IiIi/yIiIv8iIiL/IiIi/yIiIv8iIiL/ISEh/yEhIf8hISH/ISEh/yEh + If8iIiH/IiIh/2YnG/+zKxL/nCgT/6MoEv/BLBH/gSkZ/zAkIf8jIyL/IyMj/yMjI/8jIyP/IiIi/ycn + J/84ODj/VFRU/2JiYv92dnb/q6ur/9fX1//a2tr/2tra/9vb2//c3Nz/3d3d/93d3f/e3t7/39/f/9/f + 3//g4OD/4eHh/+Li4v/i4uL/4+Pj/+Tk5P/k5OT/5eXl/+bm5v/m5ub/5+fn/+fn5//o6Oj/6Ojo/+jo + 6P/p6en/6enp/+rq6v/q6ur/6+vr/+vr6//r6+v/7Ozs/+zs7P/s7Oz/7e3t/+3t7f/t7e3/7u7u/+7u + 7v/u7u7/7+/v/+/v7//v7+//7+/v//Dw8P/w8PD/8PDw//Hx8f/x8fH/8fHx//Hx8f/y8vL/8vLy//Pz + 8//z8/P/8/Pz//Pz8//09PT/9PT0//Pz8zH///8B////Af///wH///8B6enp4+np6f/o6Oj/5+fn/+fn + 5//m5ub/5eXl/+Xl5f/k5OT/4+Pj/+Pj4//i4uL/4eHh/+Hh4f/g4OD/4ODg/9/f3//e3t7/3t7e/93d + 3f/d3d3/3Nzc/9vb2//b29v/29vb/9ra2v/a2tr/2dnZ/9nZ2f/Dw8P/YmJi/yQkJP8jIyP/IiIi/yIi + Iv8iIiL/IiIi/yIiIv8iIiL/IiIi/yIiIv8iIiL/IiIi/yIiIv8iIiL/KiIh/10mHP+UKhb/nSsW/28o + G/8uIyH/IyMj/yMjI/8jIyP/IyMj/yIiIv8iIiL/ISEh/xQUFP8uLi7/Z2dn/4+Pj//Ozs7/29vb/9zc + 3P/c3Nz/3d3d/97e3v/e3t7/39/f/9/f3//g4OD/4eHh/+Li4v/i4uL/4+Pj/+Tk5P/k5OT/5eXl/+bm + 5v/m5ub/5ubm/+fn5//o6Oj/6Ojo/+jo6P/p6en/6enp/+rq6v/q6ur/6urq/+vr6//r6+v/7Ozs/+zs + 7P/s7Oz/7e3t/+3t7f/t7e3/7u7u/+7u7v/u7u7/7+/v/+/v7//v7+//8PDw//Dw8P/w8PD/8PDw//Hx + 8f/x8fH/8fHx//Ly8v/y8vL/8vLy//Ly8v/z8/P/8/Pz//Pz8//09PT/9PT0//T09P/09PT/9PT0Mf// + /wH///8B////Af///wHq6urj6urq/+np6f/o6Oj/6Ojo/+fn5//n5+f/5ubm/+bm5v/l5eX/5OTk/+Tk + 5P/j4+P/4+Pj/+Li4v/h4eH/4eHh/+Dg4P/g4OD/39/f/97e3v/e3t7/3d3d/93d3f/d3d3/3Nzc/9zc + 3P/b29v/29vb/9ra2v+mpqb/Kioq/yMjI/8iIiL/IiIi/yIiIv8iIiL/IiIi/yIiIv8iIiL/IiIi/yIi + Iv8iIiL/IiIi/yIiIv8iIiL/JCMi/ysjIv8sIyH/JiMi/yMjIv8jIyP/IyMj/yMjI/8iIiL/IiIi/x0d + Hf8ICAj/BQUF/zs7O/+Wlpb/x8fH/9zc3P/d3d3/3t7e/97e3v/f39//4ODg/+Dg4P/h4eH/4uLi/+Li + 4v/j4+P/4+Pj/+Tk5P/l5eX/5eXl/+bm5v/m5ub/5+fn/+jo6P/o6Oj/6Ojo/+np6f/p6en/6urq/+rq + 6v/q6ur/6+vr/+vr6//r6+v/7Ozs/+zs7P/s7Oz/7e3t/+3t7f/t7e3/7u7u/+7u7v/u7u7/7+/v/+/v + 7//v7+//7+/v/+/v7//w8PD/8PDw//Dw8P/x8fH/8fHx//Hx8f/y8vL/8vLy//Ly8v/y8vL/8/Pz//Pz + 8//z8/P/9PT0//T09P/09PT/9PT0//X19f/19fUx////Af///wH///8B////Aevr6+Pr6+v/6urq/+rq + 6v/p6en/6Ojo/+jo6P/n5+f/5+fn/+bm5v/m5ub/5eXl/+Tk5P/k5OT/4+Pj/+Pj4//i4uL/4uLi/+Hh + 4f/h4eH/4ODg/+Dg4P/f39//3t7e/97e3v/e3t7/3d3d/93d3f/c3Nz/3Nzc/8HBwf83Nzf/IiIi/yIi + Iv8jIyP/IyMj/yIiIv8iIiL/IiIi/yIiIv8iIiL/IiIi/yIiIv8iIiL/IyMj/yMjI/8jIyP/IyMj/yMj + I/8jIyP/IyMj/yMjI/8jIyP/IiIi/yIiIv8hISH/DQ0N/wMDA/80NDT/kJCQ/8nJyf/d3d3/39/f/9/f + 3//g4OD/4ODg/+Hh4f/h4eH/4uLi/+Li4v/j4+P/5OTk/+Tk5P/l5eX/5eXl/+bm5v/n5+f/5+fn/+fn + 5//o6Oj/6Ojo/+np6f/p6en/6urq/+rq6v/q6ur/6+vr/+vr6//r6+v/7Ozs/+zs7P/t7e3/7e3t/+3t + 7f/u7u7/7u7u/+7u7v/u7u7/7+/v/+/v7//v7+//7+/v//Dw8P/w8PD/8PDw//Hx8f/x8fH/8fHx//Hx + 8f/y8vL/8vLy//Ly8v/z8/P/8/Pz//Pz8//z8/P/8/Pz//T09P/09PT/9PT0//T09P/19fX/9fX1//X1 + 9TH///8B////Af///wH///8B7Ozs4+vr6//r6+v/6urq/+rq6v/p6en/6enp/+jo6P/o6Oj/5+fn/+bm + 5v/m5ub/5eXl/+Xl5f/k5OT/5OTk/+Pj4//j4+P/4uLi/+Li4v/h4eH/4eHh/+Dg4P/g4OD/39/f/9/f + 3//f39//3t7e/97e3v/d3d3/19fX/4uLi/89PT3/JCQk/yMjI/8jIyP/IyMj/yMjI/8iIiL/IiIi/yIi + Iv8iIiL/IiIi/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yIiIv8jIyP/JSUl/w4O + Dv8CAgL/IyMj/4KCgv/FxcX/39/f/+Dg4P/g4OD/4eHh/+Hh4f/i4uL/4uLi/+Pj4//j4+P/5OTk/+Tk + 5P/l5eX/5eXl/+bm5v/m5ub/5+fn/+fn5//o6Oj/6Ojo/+np6f/p6en/6urq/+rq6v/q6ur/6+vr/+vr + 6//r6+v/7Ozs/+zs7P/s7Oz/7e3t/+3t7f/t7e3/7u7u/+7u7v/u7u7/7+/v/+/v7//v7+//7+/v//Dw + 8P/w8PD/8PDw//Dw8P/x8fH/8fHx//Hx8f/x8fH/8vLy//Ly8v/y8vL/8vLy//Pz8//z8/P/8/Pz//Pz + 8//09PT/9PT0//T09P/19fX/9fX1//X19f/19fX/9fX1Mf///wH///8B////Af///wHt7e3j7Ozs/+zs + 7P/r6+v/6+vr/+rq6v/q6ur/6enp/+np6f/p6en/6Ojo/+jo6P/n5+f/5ubm/+bm5v/l5eX/5eXl/+Xl + 5f/k5OT/5OTk/+Pj4//j4+P/4uLi/+Li4v/h4eH/4eHh/+Hh4f/g4OD/4ODg/9/f3//f39//3d3d/76+ + vv9ycnL/ODg4/yQkJP8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMj + I/8jIyP/IyMj/yMjI/8jIyP/IiIi/yMjI/8RERH/AgIC/yYmJv+IiIj/xcXF/9/f3//i4uL/4uLi/+Li + 4v/j4+P/4+Pj/+Tk5P/k5OT/5eXl/+Xl5f/m5ub/5ubm/+bm5v/n5+f/5+fn/+jo6P/o6Oj/6enp/+np + 6f/p6en/6urq/+rq6v/r6+v/6+vr/+zs7P/s7Oz/7Ozs/+3t7f/t7e3/7e3t/+7u7v/u7u7/7u7u/+7u + 7v/v7+//7+/v/+/v7//v7+//8PDw//Dw8P/w8PD/8PDw//Hx8f/x8fH/8fHx//Hx8f/y8vL/8vLy//Ly + 8v/y8vL/8vLy//Pz8//z8/P/8/Pz//Pz8//09PT/9PT0//T09P/09PT/9fX1//X19f/19fX/9fX1//b2 + 9v/29vYx////Af///wH///8B////Ae3t7ePt7e3/7Ozs/+zs7P/s7Oz/6+vr/+vr6//q6ur/6urq/+np + 6f/p6en/6enp/+jo6P/o6Oj/5+fn/+fn5//m5ub/5ubm/+Xl5f/l5eX/5OTk/+Tk5P/j4+P/4+Pj/+Li + 4v/i4uL/4uLi/+Hh4f/h4eH/4eHh/+Dg4P/g4OD/4ODg/9TU1P+np6f/XFxc/yQkJP8iIiL/IyMj/yMj + I/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yIiIv8nJyf/FBQU/wIC + Av8cHBz/dnZ2/8TExP/f39//4uLi/+Pj4//j4+P/4+Pj/+Tk5P/k5OT/5eXl/+Xl5f/m5ub/5ubm/+fn + 5//n5+f/5+fn/+jo6P/o6Oj/6enp/+np6f/q6ur/6urq/+rq6v/r6+v/6+vr/+vr6//s7Oz/7Ozs/+3t + 7f/t7e3/7e3t/+7u7v/u7u7/7u7u/+7u7v/v7+//7+/v/+/v7//v7+//7+/v//Dw8P/w8PD/8PDw//Dw + 8P/x8fH/8fHx//Hx8f/x8fH/8vLy//Ly8v/y8vL/8vLy//Pz8//z8/P/8/Pz//Pz8//z8/P/9PT0//T0 + 9P/09PT/9PT0//X19f/19fX/9fX1//X19f/19fX/9vb2//b29jH///8B////Af///wH///8B7u7u4+3t + 7f/t7e3/7e3t/+zs7P/s7Oz/7Ozs/+vr6//r6+v/6+vr/+rq6v/q6ur/6enp/+np6f/p6en/6Ojo/+jo + 6P/n5+f/5+fn/+bm5v/m5ub/5eXl/+Xl5f/l5eX/5OTk/+Tk5P/j4+P/4+Pj/+Pj4//i4uL/4uLi/+Li + 4v/i4uL/4eHh/+Hh4f/X19f/l5eX/05OTv8oKCj/IiIi/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMj + I/8jIyP/IyMj/yMjI/8lJSX/Tk5O/5iYmP9zc3P/UVFR/5OTk//Gxsb/4uLi/+Tk5P/k5OT/5eXl/+Xl + 5f/l5eX/5ubm/+bm5v/n5+f/5+fn/+fn5//o6Oj/6Ojo/+np6f/p6en/6enp/+rq6v/q6ur/6urq/+vr + 6//r6+v/6+vr/+zs7P/s7Oz/7Ozs/+3t7f/t7e3/7e3t/+7u7v/u7u7/7u7u/+7u7v/u7u7/7+/v/+/v + 7//v7+//8PDw//Dw8P/w8PD/8PDw//Dw8P/x8fH/8fHx//Hx8f/x8fH/8fHx//Ly8v/y8vL/8vLy//Ly + 8v/y8vL/8/Pz//Pz8//z8/P/8/Pz//T09P/09PT/9PT0//T09P/09PT/9fX1//X19f/19fX/9fX1//b2 + 9v/29vb/9vb2Mf///wH///8B////Af///wHu7u7j7u7u/+7u7v/t7e3/7e3t/+3t7f/s7Oz/7Ozs/+zs + 7P/r6+v/6+vr/+vr6//q6ur/6urq/+rq6v/p6en/6enp/+jo6P/o6Oj/5+fn/+fn5//m5ub/5ubm/+Xl + 5f/l5eX/5eXl/+Tk5P/k5OT/5OTk/+Pj4//j4+P/4+Pj/+Pj4//i4uL/4uLi/+Pj4//g4OD/xMTE/3d3 + d/82Njb/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IiIi/0RERP+urq7/4uLi/+Li + 4v/a2tr/4ODg/+Tk5P/l5eX/5eXl/+Xl5f/l5eX/5ubm/+bm5v/n5+f/5+fn/+fn5//o6Oj/6Ojo/+jo + 6P/p6en/6enp/+rq6v/q6ur/6urq/+vr6//r6+v/6+vr/+zs7P/s7Oz/7Ozs/+3t7f/t7e3/7e3t/+7u + 7v/u7u7/7u7u/+/v7//v7+//7+/v/+/v7//v7+//8PDw//Dw8P/w8PD/8PDw//Hx8f/x8fH/8fHx//Hx + 8f/x8fH/8vLy//Ly8v/y8vL/8vLy//Ly8v/z8/P/8/Pz//Pz8//z8/P/8/Pz//T09P/09PT/9PT0//T0 + 9P/09PT/9fX1//X19f/19fX/9fX1//b29v/29vb/9vb2//b29v/29vYx////Af///wH///8B////Ae/v + 7+Pu7u7/7u7u/+7u7v/u7u7/7e3t/+3t7f/t7e3/7Ozs/+zs7P/s7Oz/6+vr/+vr6//r6+v/6urq/+rq + 6v/q6ur/6enp/+np6f/o6Oj/6Ojo/+fn5//n5+f/5+fn/+bm5v/m5ub/5eXl/+Xl5f/l5eX/5OTk/+Tk + 5P/k5OT/5OTk/+Pj4//j4+P/5OTk/+Tk5P/k5OT/29vb/7i4uP9ra2v/LS0t/yQkJP8iIiL/IyMj/yMj + I/8jIyP/IiIi/yMjI/84ODj/ra2t/+Li4v/l5eX/5eXl/+Xl5f/l5eX/5eXl/+bm5v/m5ub/5ubm/+fn + 5//n5+f/5+fn/+jo6P/o6Oj/6Ojo/+np6f/p6en/6enp/+rq6v/q6ur/6+vr/+vr6//r6+v/7Ozs/+zs + 7P/s7Oz/7e3t/+3t7f/t7e3/7e3t/+7u7v/u7u7/7u7u/+7u7v/v7+//7+/v/+/v7//v7+//8PDw//Dw + 8P/w8PD/8PDw//Hx8f/x8fH/8fHx//Hx8f/x8fH/8vLy//Ly8v/y8vL/8vLy//Ly8v/z8/P/8/Pz//Pz + 8//z8/P/8/Pz//T09P/09PT/9PT0//T09P/09PT/9PT0//X19f/19fX/9fX1//X19f/19fX/9vb2//b2 + 9v/29vb/9vb2//b29jH///8B////Af///wH///8B8PDw4+/v7//v7+//7+/v/+7u7v/u7u7/7u7u/+3t + 7f/t7e3/7e3t/+zs7P/s7Oz/7Ozs/+zs7P/r6+v/6+vr/+vr6//q6ur/6urq/+np6f/p6en/6enp/+jo + 6P/o6Oj/5+fn/+fn5//n5+f/5ubm/+bm5v/m5ub/5ubm/+bm5v/l5eX/5eXl/+Xl5f/l5eX/5eXl/+bm + 5v/m5ub/5ubm/9jY2P+dnZ3/V1dX/yYmJv8iIiL/IyMj/yMjI/8iIiL/PDw8/6CgoP/l5eX/5+fn/+fn + 5//n5+f/5+fn/+fn5//n5+f/5+fn/+jo6P/o6Oj/6Ojo/+jo6P/p6en/6enp/+np6f/q6ur/6urq/+rq + 6v/r6+v/6+vr/+vr6//s7Oz/7Ozs/+zs7P/t7e3/7e3t/+3t7f/t7e3/7u7u/+7u7v/u7u7/7u7u/+/v + 7//v7+//7+/v/+/v7//w8PD/8PDw//Dw8P/w8PD/8fHx//Hx8f/x8fH/8fHx//Ly8v/y8vL/8vLy//Ly + 8v/y8vL/8vLy//Pz8//z8/P/8/Pz//Pz8//z8/P/8/Pz//T09P/09PT/9PT0//T09P/09PT/9PT0//X1 + 9f/19fX/9fX1//X19f/19fX/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2Mf///wH///8B////Af// + /wHw8PDj8PDw//Dw8P/v7+//7+/v/+/v7//u7u7/7u7u/+7u7v/t7e3/7e3t/+3t7f/s7Oz/7Ozs/+zs + 7P/s7Oz/6+vr/+vr6//r6+v/6urq/+rq6v/p6en/6enp/+np6f/o6Oj/6Ojo/+jo6P/n5+f/5+fn/+fn + 5//n5+f/5ubm/+bm5v/m5ub/5ubm/+bm5v/m5ub/5ubm/+fn5//n5+f/5+fn/+Tk5P/MzMz/eHh4/zY2 + Nv8kJCT/IiIi/y0tLf+ampr/4ODg/+fn5//o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6enp/+np + 6f/p6en/6enp/+rq6v/q6ur/6urq/+rq6v/r6+v/6+vr/+vr6//s7Oz/7Ozs/+zs7P/t7e3/7e3t/+3t + 7f/t7e3/7u7u/+7u7v/u7u7/7+/v/+/v7//v7+//7+/v/+/v7//w8PD/8PDw//Dw8P/w8PD/8fHx//Hx + 8f/x8fH/8fHx//Hx8f/y8vL/8vLy//Ly8v/y8vL/8vLy//Pz8//z8/P/8/Pz//Pz8//z8/P/8/Pz//Pz + 8//09PT/9PT0//T09P/09PT/9PT0//X19f/19fX/9fX1//X19f/19fX/9fX1//b29v/29vb/9vb2//b2 + 9v/29vb/9vb2//f39//29vYx////Af///wH///8B////AfHx8ePx8fH/8PDw//Dw8P/w8PD/7+/v/+/v + 7//v7+//7+/v/+7u7v/u7u7/7u7u/+3t7f/t7e3/7e3t/+3t7f/s7Oz/7Ozs/+zs7P/r6+v/6+vr/+vr + 6//q6ur/6urq/+rq6v/p6en/6enp/+np6f/p6en/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo + 6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/k5OT/xcXF/3R0dP9MTEz/kZGR/+bm5v/p6en/6enp/+np + 6f/p6en/6enp/+np6f/q6ur/6urq/+rq6v/q6ur/6urq/+vr6//r6+v/6+vr/+vr6//r6+v/7Ozs/+zs + 7P/s7Oz/7e3t/+3t7f/t7e3/7u7u/+7u7v/u7u7/7u7u/+7u7v/v7+//7+/v/+/v7//v7+//8PDw//Dw + 8P/w8PD/8PDw//Dw8P/x8fH/8fHx//Hx8f/x8fH/8vLy//Ly8v/y8vL/8vLy//Ly8v/z8/P/8/Pz//Pz + 8//z8/P/8/Pz//Pz8//z8/P/9PT0//T09P/09PT/9PT0//T09P/09PT/9PT0//X19f/19fX/9fX1//X1 + 9f/19fX/9fX1//b29v/29vb/9vb2//b29v/29vb/9vb2//f39//39/f/9/f3//b29jH///8B////Af// + /wH///8B8fHx4/Hx8f/x8fH/8fHx//Dw8P/w8PD/8PDw/+/v7//v7+//7+/v/+/v7//u7u7/7u7u/+7u + 7v/t7e3/7e3t/+3t7f/t7e3/7e3t/+zs7P/s7Oz/6+vr/+vr6//r6+v/6urq/+rq6v/q6ur/6urq/+np + 6f/p6en/6enp/+np6f/p6en/6enp/+np6f/p6en/6enp/+np6f/p6en/6enp/+np6f/p6en/6enp/+np + 6f/p6en/3d3d/83Nzf/h4eH/6urq/+rq6v/q6ur/6urq/+rq6v/q6ur/6urq/+rq6v/q6ur/6urq/+vr + 6//r6+v/6+vr/+vr6//s7Oz/7Ozs/+zs7P/s7Oz/7e3t/+3t7f/t7e3/7u7u/+7u7v/u7u7/7u7u/+7u + 7v/v7+//7+/v/+/v7//v7+//8PDw//Dw8P/w8PD/8PDw//Dw8P/w8PD/8fHx//Hx8f/x8fH/8fHx//Ly + 8v/y8vL/8vLy//Ly8v/y8vL/8/Pz//Pz8//z8/P/8/Pz//Pz8//z8/P/9PT0//T09P/09PT/9PT0//T0 + 9P/09PT/9PT0//X19f/19fX/9fX1//X19f/19fX/9fX1//b29v/29vb/9vb2//b29v/29vb/9vb2//b2 + 9v/39/f/9/f3//f39//39/f/9vb2Mf///wH///8B////Af///wHy8vLj8fHx//Hx8f/x8fH/8fHx//Dw + 8P/w8PD/8PDw//Dw8P/v7+//7+/v/+/v7//v7+//7u7u/+7u7v/u7u7/7u7u/+3t7f/t7e3/7e3t/+3t + 7f/t7e3/7Ozs/+zs7P/s7Oz/7Ozs/+vr6//r6+v/6+vr/+vr6//r6+v/6urq/+rq6v/q6ur/6urq/+rq + 6v/q6ur/6urq/+rq6v/q6ur/6urq/+rq6v/q6ur/6urq/+rq6v/q6ur/6urq/+rq6v/r6+v/6+vr/+vr + 6//r6+v/6+vr/+vr6//r6+v/6+vr/+vr6//r6+v/7Ozs/+zs7P/s7Oz/7Ozs/+zs7P/t7e3/7e3t/+3t + 7f/u7u7/7u7u/+7u7v/u7u7/7u7u/+/v7//v7+//7+/v/+/v7//v7+//8PDw//Dw8P/w8PD/8PDw//Dw + 8P/x8fH/8fHx//Hx8f/x8fH/8fHx//Ly8v/y8vL/8vLy//Ly8v/y8vL/8/Pz//Pz8//z8/P/8/Pz//Pz + 8//z8/P/9PT0//T09P/09PT/9PT0//T09P/09PT/9PT0//T09P/19fX/9fX1//X19f/19fX/9fX1//X1 + 9f/19fX/9vb2//b29v/29vb/9vb2//b29v/29vb/9/f3//f39//39/f/9/f3//f39//39/cx////Af// + /wH///8B////AfLy8uPy8vL/8vLy//Ly8v/y8vL/8fHx//Hx8f/x8fH/8PDw//Dw8P/w8PD/8PDw/+/v + 7//v7+//7+/v/+/v7//u7u7/7u7u/+7u7v/u7u7/7u7u/+3t7f/t7e3/7e3t/+3t7f/s7Oz/7Ozs/+zs + 7P/s7Oz/7Ozs/+vr6//r6+v/6+vr/+vr6//r6+v/6+vr/+vr6//r6+v/6+vr/+vr6//r6+v/6+vr/+vr + 6//r6+v/6+vr/+vr6//r6+v/6+vr/+zs7P/s7Oz/7Ozs/+zs7P/s7Oz/7Ozs/+zs7P/s7Oz/7Ozs/+zs + 7P/t7e3/7e3t/+3t7f/t7e3/7e3t/+7u7v/u7u7/7u7u/+7u7v/v7+//7+/v/+/v7//v7+//7+/v//Dw + 8P/w8PD/8PDw//Dw8P/w8PD/8fHx//Hx8f/x8fH/8fHx//Hx8f/x8fH/8vLy//Ly8v/y8vL/8vLy//Ly + 8v/z8/P/8/Pz//Pz8//z8/P/8/Pz//Pz8//09PT/9PT0//T09P/09PT/9PT0//T09P/09PT/9fX1//X1 + 9f/19fX/9fX1//X19f/19fX/9fX1//b29v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9/f3//f3 + 9//39/f/9/f3//f39//39/f/9/f3//j4+DH///8B////Af///wH///8B8/Pz4/Pz8//y8vL/8vLy//Ly + 8v/y8vL/8fHx//Hx8f/x8fH/8fHx//Dw8P/w8PD/8PDw//Dw8P/w8PD/7+/v/+/v7//v7+//7+/v/+/v + 7//u7u7/7u7u/+7u7v/u7u7/7e3t/+3t7f/t7e3/7e3t/+3t7f/s7Oz/7Ozs/+zs7P/s7Oz/7Ozs/+zs + 7P/s7Oz/7Ozs/+zs7P/s7Oz/7Ozs/+zs7P/s7Oz/7Ozs/+zs7P/s7Oz/7Ozs/+zs7P/s7Oz/7Ozs/+zs + 7P/s7Oz/7e3t/+3t7f/t7e3/7e3t/+3t7f/t7e3/7e3t/+3t7f/t7e3/7u7u/+7u7v/u7u7/7u7u/+/v + 7//v7+//7+/v/+/v7//v7+//8PDw//Dw8P/w8PD/8PDw//Dw8P/x8fH/8fHx//Hx8f/x8fH/8fHx//Hx + 8f/x8fH/8vLy//Ly8v/y8vL/8vLy//Ly8v/z8/P/8/Pz//Pz8//z8/P/8/Pz//Pz8//09PT/9PT0//T0 + 9P/09PT/9PT0//T09P/09PT/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/29vb/9vb2//b2 + 9v/29vb/9vb2//b29v/29vb/9vb2//f39//39/f/9/f3//f39//39/f/9/f3//f39//4+Pj/+Pj4Mf// + /wH///8B////Af///wHz8/Pj8/Pz//Pz8//z8/P/8/Pz//Ly8v/y8vL/8vLy//Ly8v/x8fH/8fHx//Hx + 8f/x8fH/8fHx//Dw8P/w8PD/8PDw//Dw8P/w8PD/8PDw/+/v7//v7+//7+/v/+/v7//v7+//7u7u/+7u + 7v/u7u7/7u7u/+7u7v/u7u7/7e3t/+3t7f/t7e3/7e3t/+3t7f/t7e3/7e3t/+3t7f/t7e3/7e3t/+3t + 7f/t7e3/7e3t/+3t7f/t7e3/7e3t/+3t7f/t7e3/7e3t/+3t7f/u7u7/7u7u/+7u7v/u7u7/7u7u/+7u + 7v/u7u7/7u7u/+7u7v/v7+//7+/v/+/v7//v7+//7+/v//Dw8P/w8PD/8PDw//Dw8P/w8PD/8fHx//Hx + 8f/x8fH/8fHx//Hx8f/x8fH/8vLy//Ly8v/y8vL/8vLy//Ly8v/y8vL/8vLy//Pz8//z8/P/8/Pz//Pz + 8//z8/P/8/Pz//T09P/09PT/9PT0//T09P/09PT/9PT0//T09P/19fX/9fX1//X19f/19fX/9fX1//X1 + 9f/19fX/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b29v/39/f/9/f3//f39//39/f/9/f3//f3 + 9//39/f/9/f3//j4+P/4+Pj/+Pj4//j4+P/4+Pgx////Af///wH///8B////AfT09OP09PT/8/Pz//Pz + 8//z8/P/8/Pz//Pz8//y8vL/8vLy//Ly8v/y8vL/8vLy//Hx8f/x8fH/8fHx//Hx8f/w8PD/8PDw//Dw + 8P/w8PD/8PDw//Dw8P/w8PD/8PDw/+/v7//v7+//7+/v/+/v7//u7u7/7u7u/+7u7v/u7u7/7u7u/+7u + 7v/u7u7/7u7u/+7u7v/u7u7/7u7u/+7u7v/u7u7/7u7u/+7u7v/u7u7/7u7u/+7u7v/u7u7/7u7u/+7u + 7v/u7u7/7u7u/+7u7v/u7u7/7u7u/+7u7v/u7u7/7+/v/+/v7//v7+//7+/v/+/v7//v7+//8PDw//Dw + 8P/w8PD/8PDw//Dw8P/x8fH/8fHx//Hx8f/x8fH/8fHx//Hx8f/x8fH/8vLy//Ly8v/y8vL/8vLy//Ly + 8v/y8vL/8vLy//Pz8//z8/P/8/Pz//Pz8//z8/P/8/Pz//T09P/09PT/9PT0//T09P/09PT/9PT0//X1 + 9f/19fX/9fX1//X19f/19fX/9fX1//X19f/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b2 + 9v/29vb/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//j4+P/4+Pj/+Pj4//j4+P/4+Pj/+Pj4//j4 + +DH///8B////AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA + + + \ No newline at end of file diff --git a/ROMVault2/frmSplashScreen.Designer.cs b/ROMVault2/frmSplashScreen.Designer.cs new file mode 100644 index 0000000..9003df2 --- /dev/null +++ b/ROMVault2/frmSplashScreen.Designer.cs @@ -0,0 +1,119 @@ +namespace ROMVault2 +{ + partial class FrmSplashScreen + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FrmSplashScreen)); + this.lblStatus = new System.Windows.Forms.Label(); + this.timer1 = new System.Windows.Forms.Timer(this.components); + this.progressBar = new System.Windows.Forms.ProgressBar(); + this.lblVersion = new System.Windows.Forms.Label(); + this.bgWork = new System.ComponentModel.BackgroundWorker(); + this.label1 = new System.Windows.Forms.Label(); + this.SuspendLayout(); + // + // lblStatus + // + this.lblStatus.BackColor = System.Drawing.Color.White; + this.lblStatus.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.lblStatus.ImageAlign = System.Drawing.ContentAlignment.TopLeft; + this.lblStatus.Location = new System.Drawing.Point(7, 135); + this.lblStatus.Name = "lblStatus"; + this.lblStatus.Padding = new System.Windows.Forms.Padding(2, 2, 0, 0); + this.lblStatus.Size = new System.Drawing.Size(450, 20); + this.lblStatus.TabIndex = 0; + // + // timer1 + // + this.timer1.Tick += new System.EventHandler(this.Timer1Tick); + // + // progressBar + // + this.progressBar.Location = new System.Drawing.Point(7, 159); + this.progressBar.Name = "progressBar"; + this.progressBar.Size = new System.Drawing.Size(450, 19); + this.progressBar.TabIndex = 4; + // + // lblVersion + // + this.lblVersion.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.lblVersion.Location = new System.Drawing.Point(10, 113); + this.lblVersion.Name = "lblVersion"; + this.lblVersion.Size = new System.Drawing.Size(445, 15); + this.lblVersion.TabIndex = 5; + this.lblVersion.Text = "label1"; + this.lblVersion.TextAlign = System.Drawing.ContentAlignment.TopCenter; + // + // bgWork + // + this.bgWork.WorkerReportsProgress = true; + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(12, 185); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(35, 13); + this.label1.TabIndex = 6; + this.label1.Text = "label1"; + // + // FrmSplashScreen + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("$this.BackgroundImage"))); + this.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None; + this.ClientSize = new System.Drawing.Size(465, 207); + this.ControlBox = false; + this.Controls.Add(this.label1); + this.Controls.Add(this.lblVersion); + this.Controls.Add(this.progressBar); + this.Controls.Add(this.lblStatus); + this.DoubleBuffered = true; + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; + this.Name = "FrmSplashScreen"; + this.ShowInTaskbar = false; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Text = "frmSplashScreen"; + this.Shown += new System.EventHandler(this.FrmSplashScreenShown); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Label lblStatus; + private System.Windows.Forms.Timer timer1; + private System.Windows.Forms.ProgressBar progressBar; + private System.Windows.Forms.Label lblVersion; + private System.ComponentModel.BackgroundWorker bgWork; + private System.Windows.Forms.Label label1; + } +} \ No newline at end of file diff --git a/ROMVault2/frmSplashScreen.cs b/ROMVault2/frmSplashScreen.cs new file mode 100644 index 0000000..39c0c1a --- /dev/null +++ b/ROMVault2/frmSplashScreen.cs @@ -0,0 +1,159 @@ +/****************************************************** + * ROMVault2 is written by Gordon J. * + * Contact gordon@romvault.com * + * Copyright 2014 * + ******************************************************/ + +using System; +using System.ComponentModel; +using System.ServiceModel; +using System.Threading; +using System.Windows.Forms; +using ROMVault2.Properties; +using ROMVault2.RVRef; +using ROMVault2.RvDB; + +namespace ROMVault2 +{ + public partial class FrmSplashScreen : Form + { + private double _opacityIncrement = 0.05; + + public FrmSplashScreen() + { + InitializeComponent(); + lblVersion.Text = @"Version " + Program.Version + @"." + Program.SubVersion + Resources.FixFiles_FixZip_Colon + Application.StartupPath; + Opacity = 0; + timer1.Interval = 50; + + label1.Text = @"Registered to : " + Settings.Username + @" Contact Email (" + Settings.EMail + @")"; + + bgWork.DoWork += StartUpCode; + bgWork.ProgressChanged += BgwProgressChanged; + bgWork.RunWorkerCompleted += BgwRunWorkerCompleted; + } + + private void FrmSplashScreenShown(object sender, EventArgs e) + { + bgWork.RunWorkerAsync(SynchronizationContext.Current); + timer1.Start(); + } + + + private void StartUpCode(object sender, DoWorkEventArgs e) + { + + BasicHttpBinding b = new BasicHttpBinding { SendTimeout = new TimeSpan(0, 0, 20), ReceiveTimeout = new TimeSpan(0, 0, 20) }; + EndpointAddress ep = new EndpointAddress(@"http://services.romvault.com/Service1.svc"); + Service1Client s = new Service1Client(b, ep); + + if (string.IsNullOrEmpty(Settings.Username) || string.IsNullOrEmpty(Settings.EMail)) + { + FrmRegistration freg = new FrmRegistration(); + freg.ShowDialog(); + freg.Dispose(); + } + + bool isNetworkAvailable = System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable(); + + string r = "OK"; + try + { + if (isNetworkAvailable) + r = s.SendUser1(Settings.Username, Settings.EMail, Program.Version, Program.SubVersion); + } + catch (Exception) + { + r = "OK"; + } + + if (r != "OK") + { + Program.ErrorMessage=Resources.Program_Main_You_are_not_Authorised_to_use_this_program; + return; + } + // normal check ends + + string thisV = Program.Version + "." + Program.SubVersion.ToString("0000"); + string v = thisV; + try + { + if (isNetworkAvailable) + v = s.GetLatestVersion1(Program.Version, Program.SubVersion); + } + catch (Exception) + { + v = thisV; + } + if (String.Compare(v, thisV, StringComparison.Ordinal) > 0) + { + Program.URL = s.GetUpdateLink1(Program.Version, Program.SubVersion); + Program.ErrorMessage=Resources.Program_Main_There_is_a_new_release_download_now_from + Program.URL; + return; + } + + s.Close(); + + RepairStatus.InitStatusCheck(); + + Settings.SetDefaults(); + + DB.Read(sender,e); + + } + + + private void BgwProgressChanged(object sender, ProgressChangedEventArgs e) + { + if (e.UserState == null) + { + if (e.ProgressPercentage >= progressBar.Minimum && e.ProgressPercentage <= progressBar.Maximum) + progressBar.Value = e.ProgressPercentage; + return; + } + bgwSetRange bgwSr = e.UserState as bgwSetRange; + if (bgwSr != null) + { + progressBar.Minimum = 0; + progressBar.Maximum = bgwSr.MaxVal; + progressBar.Value = 0; + return; + } + + bgwText bgwT = e.UserState as bgwText; + if (bgwT != null) + { + lblStatus.Text = bgwT.Text; + } + } + + private void BgwRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) + { + _opacityIncrement = -0.1; + timer1.Start(); + } + + private void Timer1Tick(object sender, EventArgs e) + { + + if (_opacityIncrement > 0) + { + if (Opacity < 1) + Opacity += _opacityIncrement; + else + timer1.Stop(); + } + else + { + if (Opacity > 0) + Opacity += _opacityIncrement; + else + { + timer1.Stop(); + Close(); + } + } + } + + } +} diff --git a/ROMVault2/frmSplashScreen.resx b/ROMVault2/frmSplashScreen.resx new file mode 100644 index 0000000..488f942 --- /dev/null +++ b/ROMVault2/frmSplashScreen.resx @@ -0,0 +1,587 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + + 104, 17 + + + + + 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 + + + \ No newline at end of file diff --git a/ROMVault2/rvImages.cs b/ROMVault2/rvImages.cs new file mode 100644 index 0000000..c867a9b --- /dev/null +++ b/ROMVault2/rvImages.cs @@ -0,0 +1,56 @@ +/****************************************************** + * ROMVault2 is written by Gordon J. * + * Contact gordon@romvault.com * + * Copyright 2014 * + ******************************************************/ + +using System.Collections.Generic; +using System.Drawing; + +namespace ROMVault2 +{ + public static class rvImages + { + private static List names; + private static List images; + + + public static Bitmap GetBitmap(string bitmapName) + { + object bmObj = rvImages1.ResourceManager.GetObject(bitmapName); + + Bitmap bm = null; + if (bmObj != null) + bm = (Bitmap)bmObj; + + return bm; + } + + public static Bitmap TickBoxDisabled + { + get { return GetBitmap("TickBoxDisabled"); } + } + public static Bitmap TickBoxTicked + { + get { return GetBitmap("TickBoxTicked"); } + } + public static Bitmap TickBoxUnTicked + { + get { return GetBitmap("TickBoxUnTicked"); } + } + + public static Bitmap ExpandBoxMinus + { + get { return GetBitmap("ExpandBoxMinus"); } + } + public static Bitmap ExpandBoxPlus + { + get { return GetBitmap("ExpandBoxPlus"); } + } + + public static Bitmap romvaultTZ + { + get { return GetBitmap("romvaultTZ"); } + } + } +} diff --git a/ROMVault2/rvImages1.Designer.cs b/ROMVault2/rvImages1.Designer.cs new file mode 100644 index 0000000..341dc40 --- /dev/null +++ b/ROMVault2/rvImages1.Designer.cs @@ -0,0 +1,743 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.34011 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace ROMVault2 { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class rvImages1 { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal rvImages1() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ROMVault2.rvImages1", typeof(rvImages1).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap DirDirCorrect { + get { + object obj = ResourceManager.GetObject("DirDirCorrect", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap DirDirCorrectBadCase { + get { + object obj = ResourceManager.GetObject("DirDirCorrectBadCase", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap DirDirMissing { + get { + object obj = ResourceManager.GetObject("DirDirMissing", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap DirDirUnknown { + get { + object obj = ResourceManager.GetObject("DirDirUnknown", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap DirectoryTree1 { + get { + object obj = ResourceManager.GetObject("DirectoryTree1", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap DirectoryTree2 { + get { + object obj = ResourceManager.GetObject("DirectoryTree2", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap DirectoryTree3 { + get { + object obj = ResourceManager.GetObject("DirectoryTree3", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap DirectoryTree4 { + get { + object obj = ResourceManager.GetObject("DirectoryTree4", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap ExpandBoxMinus { + get { + object obj = ResourceManager.GetObject("ExpandBoxMinus", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap ExpandBoxPlus { + get { + object obj = ResourceManager.GetObject("ExpandBoxPlus", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap G_CanBeFixed { + get { + object obj = ResourceManager.GetObject("G_CanBeFixed", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap G_Correct { + get { + object obj = ResourceManager.GetObject("G_Correct", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap G_Corrupt { + get { + object obj = ResourceManager.GetObject("G_Corrupt", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap G_CorruptCanBeFixed { + get { + object obj = ResourceManager.GetObject("G_CorruptCanBeFixed", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap G_Delete { + get { + object obj = ResourceManager.GetObject("G_Delete", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap G_DirCorrupt { + get { + object obj = ResourceManager.GetObject("G_DirCorrupt", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap G_Ignore { + get { + object obj = ResourceManager.GetObject("G_Ignore", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap G_InToSort { + get { + object obj = ResourceManager.GetObject("G_InToSort", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap G_Missing { + get { + object obj = ResourceManager.GetObject("G_Missing", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap G_MoveToSort { + get { + object obj = ResourceManager.GetObject("G_MoveToSort", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap G_NeededForFix { + get { + object obj = ResourceManager.GetObject("G_NeededForFix", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap G_NotCollected { + get { + object obj = ResourceManager.GetObject("G_NotCollected", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap G_Rename { + get { + object obj = ResourceManager.GetObject("G_Rename", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap G_Unknown { + get { + object obj = ResourceManager.GetObject("G_Unknown", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap G_UnNeeded { + get { + object obj = ResourceManager.GetObject("G_UnNeeded", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap G_UnScanned { + get { + object obj = ResourceManager.GetObject("G_UnScanned", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap R_InDatBad_NotCollected { + get { + object obj = ResourceManager.GetObject("R_InDatBad_NotCollected", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap R_InDatCollect_CanBeFixed { + get { + object obj = ResourceManager.GetObject("R_InDatCollect_CanBeFixed", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap R_InDatCollect_Correct { + get { + object obj = ResourceManager.GetObject("R_InDatCollect_Correct", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap R_InDatCollect_Corrupt { + get { + object obj = ResourceManager.GetObject("R_InDatCollect_Corrupt", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap R_InDatCollect_CorruptCanBeFixed { + get { + object obj = ResourceManager.GetObject("R_InDatCollect_CorruptCanBeFixed", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap R_InDatCollect_Missing { + get { + object obj = ResourceManager.GetObject("R_InDatCollect_Missing", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap R_InDatCollect_MoveToCorrupt { + get { + object obj = ResourceManager.GetObject("R_InDatCollect_MoveToCorrupt", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap R_InDatCollect_UnScanned { + get { + object obj = ResourceManager.GetObject("R_InDatCollect_UnScanned", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap R_InDatMerged_Deleted { + get { + object obj = ResourceManager.GetObject("R_InDatMerged_Deleted", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap R_InDatMerged_NeededForFix { + get { + object obj = ResourceManager.GetObject("R_InDatMerged_NeededForFix", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap R_InDatMerged_NotCollected { + get { + object obj = ResourceManager.GetObject("R_InDatMerged_NotCollected", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap R_InDatMerged_UnNeeded { + get { + object obj = ResourceManager.GetObject("R_InDatMerged_UnNeeded", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap R_InToSort_Corrupt { + get { + object obj = ResourceManager.GetObject("R_InToSort_Corrupt", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap R_InToSort_Delete { + get { + object obj = ResourceManager.GetObject("R_InToSort_Delete", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap R_InToSort_Deleted { + get { + object obj = ResourceManager.GetObject("R_InToSort_Deleted", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap R_InToSort_InToSort { + get { + object obj = ResourceManager.GetObject("R_InToSort_InToSort", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap R_InToSort_MoveToCorrupt { + get { + object obj = ResourceManager.GetObject("R_InToSort_MoveToCorrupt", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap R_InToSort_NeededForFix { + get { + object obj = ResourceManager.GetObject("R_InToSort_NeededForFix", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap R_NotInDat_Corrupt { + get { + object obj = ResourceManager.GetObject("R_NotInDat_Corrupt", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap R_NotInDat_Delete { + get { + object obj = ResourceManager.GetObject("R_NotInDat_Delete", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap R_NotInDat_Deleted { + get { + object obj = ResourceManager.GetObject("R_NotInDat_Deleted", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap R_NotInDat_Ignore { + get { + object obj = ResourceManager.GetObject("R_NotInDat_Ignore", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap R_NotInDat_MoveToCorrupt { + get { + object obj = ResourceManager.GetObject("R_NotInDat_MoveToCorrupt", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap R_NotInDat_MoveToSort { + get { + object obj = ResourceManager.GetObject("R_NotInDat_MoveToSort", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap R_NotInDat_NeededForFix { + get { + object obj = ResourceManager.GetObject("R_NotInDat_NeededForFix", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap R_NotInDat_Rename { + get { + object obj = ResourceManager.GetObject("R_NotInDat_Rename", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap R_NotInDat_Unknown { + get { + object obj = ResourceManager.GetObject("R_NotInDat_Unknown", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap R_NotInDat_UnScanned { + get { + object obj = ResourceManager.GetObject("R_NotInDat_UnScanned", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap romvaultTZ { + get { + object obj = ResourceManager.GetObject("romvaultTZ", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap TickBoxDisabled { + get { + object obj = ResourceManager.GetObject("TickBoxDisabled", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap TickBoxTicked { + get { + object obj = ResourceManager.GetObject("TickBoxTicked", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap TickBoxUnTicked { + get { + object obj = ResourceManager.GetObject("TickBoxUnTicked", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap Tree1 { + get { + object obj = ResourceManager.GetObject("Tree1", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap Tree2 { + get { + object obj = ResourceManager.GetObject("Tree2", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap Tree3 { + get { + object obj = ResourceManager.GetObject("Tree3", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap Tree4 { + get { + object obj = ResourceManager.GetObject("Tree4", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap ZipDirCorrect { + get { + object obj = ResourceManager.GetObject("ZipDirCorrect", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap ZipDirCorrupt { + get { + object obj = ResourceManager.GetObject("ZipDirCorrupt", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap ZipDirInToSort { + get { + object obj = ResourceManager.GetObject("ZipDirInToSort", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap ZipDirMissing { + get { + object obj = ResourceManager.GetObject("ZipDirMissing", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap ZipDirUnknown { + get { + object obj = ResourceManager.GetObject("ZipDirUnknown", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap ZipTZ { + get { + object obj = ResourceManager.GetObject("ZipTZ", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + } +} diff --git a/ROMVault2/rvImages1.resx b/ROMVault2/rvImages1.resx new file mode 100644 index 0000000..75a2f72 --- /dev/null +++ b/ROMVault2/rvImages1.resx @@ -0,0 +1,3922 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + 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 + y6WsttrvAQMfgh5KTfoXAAAAAElFTkSuQmCC + + + + + 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 + 1xe7R6QZxv8DiyxXTC5xLO8AAAAASUVORK5CYII= + + + + + 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 + Y/eRFMP4//ZFmX/edOjbAAAAAElFTkSuQmCC + + + + + iVBORw0KGgoAAAANSUhEUgAAAG4AAABuCAYAAADGWyb7AAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO + vAAADrwBlbxySQAAABl0RVh0U29mdHdhcmUAUGFpbnQuTkVUIHYzLjUuODc7gF0AACILSURBVHhe7Z0J + cBRXmuefMCCVDNjc5jCnQQZzm8PGCIS4hECgA4EQCMQhDgMCzA0GY+OjfTQ+sDHiEAiEECBV6ShVqbQT + u7Ex0TvRu7M93onZ3p3o6ZiZnt3Y3pmYnu3p2d3p2XZ/+/+/zJdKFYVcOgCB9SL+kVVZVVlZ3y+/733f + y5eVqrN1ts7W2TpbZ+tsD6Z9peL7f6E808+p+E3nlOcIlpegP/hUec4cUHGj+6qYOLytKxSjP9DZHk4D + mO7Qy4CRCUC7bDABQPoJ1v8Okub0uYr/L3NV1xewqZ5QN6gTYHs1GHgiQCyGtkOfAswtgvlSxf86HES4 + znd7Rop69pfLg4dL8fAxUpIwQa5PnCKX+g7Wr/E9HyvPN0NVl8n4qv4QPbATXksajDgAQI5DFwHlP0K/ + cEOIpPMxPaSoV3+5NGCoXBk2WkoA5ebMV+RWUpJUZKZLxepM8a5eJd6cbKmEvNlZUpGRLneWpUrZa4ly + wdNHb+eM8vzYo2KmYzcGQZ3wom0wXiwUgr6lId0q6tFPLvYZLFeGjpKScROldOp0KZ8HMGnLpTI70wKS + u0Z863KkKm+dVG3Kk+otG6V6a75Ub9ssNdT2LVKzYwueb9KvedfnSGVmhtyamyRfxz6rv+eUivtD7MrL + 0EAoFuqE11yD0fpBAej/0oCXnhumvaY8OVl7R+XqLO0xPhjbl5crvvz1UrUZcAhmuw1l51ap3VUg/t3b + pXbfTvHve13q9u8S/xu7xX+wUAIHCqWO4nO8VoP3Vm/ZoLd7CwfB+a49NLzDKrYWuzQVGgB1hzrh3a/B + YEEajbo8aLj2JO+aVRpSFT2nAF6iwWzTYPyFO7Tx/QBDEHUEc3ivpaP7oDckeOKApZOHJHjqkNRjWf8m + Hp84KEG8HsBn/IU7pQbb9q1dI2VzEh0PL1SxN7Bbk6B+UGfCEqnBUONpLIYrGq8ifSWArdUhrpaQ6DkH + 9kjdYcA5QijUfgkeIxhAgDSUU4e1Qm8dldBp6O1jlt45LqEzJxrF104d0RC5vbq9r2uv9eXmSOmMWQ68 + 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 + 7iNpSv1/UMkKCmeMXs0AAAAASUVORK5CYII= + + + + + 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 + KUYaLl4iYdYepObrZMaXc88d2rf4Prehfl6N3RZaTmrfXvvVyKHaE+s+03IT1mpR1E9lo4driTdep32J + z9sauy24cJ1yAQBygsBew8kDp+Wc8bU1dltwYSNzUsBJAnsOw+H2E6fmj0I/78ZuCy+cHHD9w9kdexG3 + nzg1b2vsHpeiaf8PHu0G+LJznRQAAAAASUVORK5CYII= + + + + + iVBORw0KGgoAAAANSUhEUgAAAG4AAABuCAYAAADGWyb7AAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO + vAAADrwBlbxySQAAABl0RVh0U29mdHdhcmUAUGFpbnQuTkVUIHYzLjUuODc7gF0AACJfSURBVHhe7Z0L + cFRXmt8vGAzCAqHuNtg8DRiwARkD5mGMQMhgC5mHEIg3QgIE4qEX74d5mIdtDAaDECAEwgIhJNBbrZZa + u5XU1tbs1iSb3cnWZpKtyVR2J0llktTOZnYmycxmZr78/+ee091q2qAXILBO1b/u7dvdt29/v/t95/vO + PX3b6mpdrat1ta7W1braE2p5rletS673rFxnqpXr2o9lAfTH1gXnSWt3xCjL2b03XtUD6qZe39WeUstz + vQxNAYxEANqhwXgA6S+x/XeQPFIXnf/emh32JvbUF+oJdQHssJbnigKIj6Ct0AWAuafAXHb98iEQQep5 + 5XXpmz9CBt14R4YXTpGxRbMk6nasOAvGqufU6846fmQN6TERn/QqRA/sgteqlucaACCHoOuA8m+gnwVC + CKVuV16VfvkjZUDBOBl2c7JEFcXKtLvxEnNvmSSUp0liebosr0yXpMrtklSxTZZhPaF8s8Tf3yAflCyR + sGvD7H2ddPzQCuv2Ho7idagLXotbnqsX5IV+rwwZoPD84eK4PkaG3HxX3i6KlknF82VO6TJZWJ4iiRWA + UrFdVlbukFVVGbK2OlPWV++SDTW7JaVmr2ys2Scba/fJptr9Sql4zOdWVWbI0oo0mX0vUXpdHWR/1tHI + P8WRTIEGQr2gLniPbHkuF+SB/i8N+FpBlPKa2NIVyjuWEQ48ZlVVpqypypJ1VTmAQzB7FBgC2Vx7QNLq + DstW92HZVndUtruPyo7647LTfVwy3Sck0wPVn5Cd2LbdfUzSag9LMgByv3PgnT2uvGbD29e/Dkc0CRoA + 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 + +CcA9CPrrOMX6J/+1lrxyp9YY3oW4/muYrcTN/YprwEgEwR6DZMHpuXM+LqK3U7caGQmBUwS6DmEw/qJ + qXkc9D0vdjt3Y3LA/ofZHb2I9RNT865i95k0y/r/EU4Y1WW4l4EAAAAASUVORK5CYII= + + + + + iVBORw0KGgoAAAANSUhEUgAAAAkAAAAJCAMAAADXT/YiAAAABGdBTUEAALGPC/xhBQAAAwBQTFRFS2On + kZGRuru84+Pj7e3s+vv7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlMgENQAAAAlwSFlzAAAO + vQAADr0BR/uQrQAAABl0RVh0U29mdHdhcmUAUGFpbnQuTkVUIHYzLjUuND6NzHYAAAAnSURBVBhXY2Bi + hAAmBkZWCGDEzmJhAAEWEAsCgCxmCEBmQc1jZAIAKdsA3KpMtoEAAAAASUVORK5CYII= + + + + + iVBORw0KGgoAAAANSUhEUgAAAAkAAAAJCAMAAADXT/YiAAAABGdBTUEAALGPC/xhBQAAAwBQTFRFKUJy + S2OnkZGRuru84+Pj7e3s+vv7/Pz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMVj7mgAAAAlwSFlzAAAO + vQAADr0BR/uQrQAAABl0RVh0U29mdHdhcmUAUGFpbnQuTkVUIHYzLjUuND6NzHYAAAAySURBVBhXNcxZ + CgAxFAJBx7fk/jcejaRBqC9RTAWexCtEuwvN+pw1M9Ck7oYWOb4/1g84IgEnGNR0wgAAAABJRU5ErkJg + gg== + + + + + iVBORw0KGgoAAAANSUhEUgAAADAAAAApCAMAAABEBVrmAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6 + JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAADAFBMVEU9AAdPAAlUAApfAAtoAAxvAA18 + AA6BAA+MABCRABGeABKhABOlAxaoBhmrCButCh2wDSC2FCe6GCu7Gi2+HTDCJTfGKz3ILkDLNEbNN0nS + RFTUR1fVSVnXT1/ZUmLcW2rdXWzgaXbicH3mfIjohpLpjJfrkZvun6juoarwqbLytbz1xMr2x8330NT5 + 3eD64+b87O798vP+9fb++fn//Pz///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAq2/ciAAAACXBIWXMAAA68AAAOvAGVvHJJAAAAGXRF + WHRTb2Z0d2FyZQBQYWludC5ORVQgdjMuNS40Po3MdgAAA65JREFUSEt9lYuWsjoMhasgtQgKghQEESgC + Fu0PFN//1U6Kl9G5nO2sJbPI1yQ7AdHtL8nulF0f12/6E+g5dRwvqh//vvQH0LcHz0555nk0/0zzKyDF + cWM6p2sPZVHPi9/T/Ab07Y6svJr34zjKsU2pT1l3v/Ur0DXEXEV13UH8pI5RSjN+v/sDGMVhYZrpCQp6 + SUqeUbqfmvkBdOWK2IwxLj51ZVGq7n8Dhma3Ih7Lc8bbp66TxJDuVcQHAO4sMaF5lmWM85q/qZUy/gEo + d/Bqn8bwyetT/aZW9HL/HRhKYhh2HMeR+rDTm1RDx/Ab0DULw/Cjl1Lo/CGoqF0vrY2AsBfQlUTHwbvS + /KGa1yeyHkRFxfgEumZj6KvAf1eQpim0r7phMyLlIJKLvAPKHd1wHoEvxSl0n9bsxGbrm+wvIoGaFNC3 + m4WOHfcu//HtuqqTjOWMmWSUfXUWST8BXbPEBvadSZHvOtH9UgExg6LWBC2PRXG+JHA6Uu4sS0K63LVt + J8C6rptwBfKhbxBd7iwN4QQAOgHXXMPUIOMoMjfCCogcE2T7fppGsYfCrjtjjb4AfgB8Di6I9mSaBGN3 + ijcdN4aavFkJ9QsLJUV1KegZgCZEuJiTvr/yk+/YdmwSJdPJYBYmKuGks7A0q6gqyHFBXYg0APDYtXWd + RwEL7oATg7HBbC3lBfyhyCqK6gwp0AFpiQWAFLxmNfz5gW9ibKdgMFkvwB9oV9CZBTUlNOnRGmlLy5o7 + qiKWxfkVynL9NABbF5udtURWojIQzaIQ30oUzpCmafOVaOtTnsZqDtBxC7aqcv4l2t3QkMCxSdPfUL4l + SNvqc7yvWZ5Gge/aYFVmmrN1B+tTLDQFFDQJdzs+gK08P4TlYWvM5zjI4ihwHQXEZOb1sofhLhVQXS60 + LDlsxg0NV94KoBRiqAQOuIQjY8alAB+TDaLKn4R2/+B8NTg5DGN/be4IcVQCADDSdmpWyQ66LipKq35U + 8QDcpZBwKmyadkTwDLZBAcofSovnG/YJwNK25YTokEAPiG9ALQAcQ3g46bGVj7Av4Db2CjEBgQyuYcBw + q0uVALI7XJ/x7wAgHS8PgOi6beimAlTbx6bppn4nfQDqZ4erLLDjYai2oYD1qYZHv5O+AfB2EirLtmwO + C0wTtT7q5fKlHwC0InjDRZtv4cGiNJnG9aWfACBDL+HJPWyX2Er466fkrt+ASaOAWYY73r3Vr/QnALMU + TdN+1gP6HwC66Ydv599u/wFxKBe9ZCaNnAAAAABJRU5ErkJggg== + + + + + iVBORw0KGgoAAAANSUhEUgAAADAAAAApCAMAAABEBVrmAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6 + JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAADAFBMVEUAMQAAPwAAQwAATAAAUwAAWQAA + YwACZwICaAIGcAYJdAkQgBARgRETgxMWhxYZihkbjRsdjx0gkiAnmCcrnCstnS0woDA3pTc9qT0/qz9F + r0VJsUlUuFRYulhau1pfvl9jwGNrxGttxW13ynd9zX2J0omS1pKX2Jec2pyo36ir4Kuy47K9573K7MrN + 7c3V8NXg9ODm9ubu+e7z+/P2/Pb5/fn8/vz///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB6Ra9RAAAAGHRFWHRTb2Z0d2FyZQBQYWludC5ORVQg + djMuMzap5+IlAAADs0lEQVRIS32VDbt6TBDGt0haRRFZImGFVu0fq+//zZ5ZvZw6L8/dua6cy/x2Zu4Z + Qre/JNpTen1cv+lPoGPEtt2wevz70h9A1xxcK2Gp65LsM82vgODHzdI+XTsoi7hu9J7mN6BrdnjlVqwb + hkEMTUI8QtvHvd+AtsbLVVhVLcSPaikhJGX3uz+AgR9mSyM5QUEvCcFSQvZjMz+Atlhhi1LK+KeuNEzk + /W9AX+9W2KVZRlnz1HUU75O9jPgAwJ2FjkmWpillrGJvaoSIfgDSHX21TyL4ZNWpelPDO7H/DvQF1jQr + iqJQfujpTbKhY/ANaOuZpnnhSwl0/hBU1KwX5oZD2AtoC6zq/ruS7KGKVSe87nlJ+PAE2nqjqSvfe5ef + JAm0L7uhEyxEz+OLuAPSHVWzH4EvRQl0n1T0RCfrm+guPIaaJNA1m5mq285d3uPbcWQnKc0oXeJBdOWZ + x90ItPVirumePSr0HDu8X0ogolDUGqPFMc/PlxhOR9KdRYFxmzmWZfu6qqoGXIE86BtEFjtTQfMYADIC + 10yZEw0PA0+dUJdAaBsgy/OSJIxcFLTtea6QF8AOgE/BBd6cDAPrujPGG7YTQU3upID6uYnivLzk5AxA + HaB5PsVdd2Unz7asyMBShp3CLJaogJPO3FTMvCwhxwW1AVIA0Ie2qaos9Kl/B+wIjPUnayEu4A9BZp6X + Z0iBDkiJTQAEZxWt4M/zPUPXrQQMxusZ+APtcjIxoaaYxB1aI2VhmlNbVkTTKLtCWY6X+GDrbLMzF8iM + ZQasmATiG4GCCVIUZbriTXXKkkjOATpuwFZZzr9YuRsaYDg2rrsbyrYYKVt1qu8rmiWh7zkWWJUaxmTd + wvrkM0UCOYmD3Y71YCvLDkFx2GrTqe6nUeg7tgQiPHE70cFwFxIoLxdSFAw244b6K2s4UBLRZAIbXNJD + bcIEBx/jDSLSn5i0/+B8OTjR90N3re8ItmUCAHSk7OSs4h10nZeElN0g4wG4SyLBWNg47RDrE9gGCUh/ + CMmfb9gnAEvbFCOiQgLVx54GtQBwDODhJMdGPMK+gNvQSWQJCGRwNA2GW17KGJDd4fqMfwcAaVlxAERV + LU1dSkC2fazrdux31Acgf3aYzAI7HgRyG3JYn7J/9DvqGwBvJy6zbIv6MJuTWK6PfLl86QcArXBWM95k + W3iwCInHcX3pJwBI3wl4cg/bxdyM2eun5K7fgFEDh1kGO9a+1S/1JwCz5HXdfNYD+h8Auun6b+ffbv8B + CV4lp0vtr3kAAAAASUVORK5CYII= + + + + + iVBORw0KGgoAAAANSUhEUgAAADAAAAApCAMAAABEBVrmAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6 + JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAADAFBMVEU4ADhIAEhNAE1XAFdfAF9mAGZy + AHJ2AHZ3AHeAAICEAISRAJGSAJKUAJSYAJibAZueA56gBaCjCKOpD6mtE62uFa6xGLG1ILW5Jrm7KLu/ + L7/AM8DHP8fJQ8nJRsnMS8zOT87RWNHSWtLWZdbZbNndet3ghODiieLjj+PnnOfooOjqqOrttO3xw/Hy + xvL0z/T33Pf44/j77Pv88fz99f3++P7+/P7///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABn1z/qAAAACXBIWXMAAA69AAAOvQFH+5CtAAAAGXRF + WHRTb2Z0d2FyZQBQYWludC5ORVQgdjMuNS40Po3MdgAAA7NJREFUSEt9lQ27ekwQxrdIWkURWSJhhVbt + H6vv/82eWb2cOi/P3bmunMv8dmbuGUK3vyTaU3p9XL/pT6BjxLbdsHr8+9IfQNccXCthqeuS7DPNr4Dg + x83SPl07KIu4bvSe5jega3Z45VasG4ZBDE1CPELbx73fgLbGy1VYVS3Ej2opISRl97s/gIEfZksjOUFB + LwnBUkL2YzM/gLZYYYtSyvinrjRM5P1vQF/vVtilWUZZ89R1FO+TvYz4AMCdhY5JlqYpZaxib2qEiH4A + 0h19tU8i+GTVqXpTwzux/w70BdY0K4qiUH7o6U2yoWPwDWjrmaZ54UsJdP4QVNSsF+aGQ9gLaAus6v67 + kuyhilUnvO55SfjwBNp6o6kr33uXnyQJtC+7oRMsRM/ji7gD0h1Vsx+BL0UJdJ9U9EQn65voLjyGmiTQ + NZuZqtvOXd7j23FkJynNKF3iQXTlmcfdCLT1Yq7pnj0q9Bw7vF9KIKJQ1BqjxTHPz5cYTkfSnUWBcZs5 + lmX7uqqqBlyBPOgbRBY7U0HzGAAyAtdMmRMNDwNPnVCXQGgbIMvzkiSMXBS07XmukBfADoBPwQXenAwD + 67ozxhu2E0FN7qSA+rmJ4ry85OQMQB2geT7FXXdlJ8+2rMjAUoadwiyWqICTztxUzLwsIccFtQFSANCH + tqmqLPSpfwfsCIz1J2shLuAPQWael2dIgQ5IiU0ABGcVreDP8z1D160EDMbrGfgD7XIyMaGmmMQdWiNl + YZpTW1ZE0yi7QlmOl/hg62yzMxfIjGUGrJgE4huBgglSFGW64k11ypJIzgE6bsBWWc6/WLkbGmA4Nq67 + G8q2GClbdarvK5oloe85FliVGsZk3cL65DNFAjmJg92O9WAryw5Bcdhq06nup1HoO7YEIjxxO9HBcBcS + KC8XUhQMNuOG+itrOFAS0WQCG1zSQ23CBAcf4w0i0p+YtP/gfDk40fdDd63vCLZlAgB0pOzkrOIddJ2X + hJTdIOMBuEsiwVjYOO0Q6xPYBglIfwjJn2/YJwBL2xQjokIC1ceeBrUAcAzg4STHRjzCvoDb0ElkCQhk + cDQNhlteyhiQ3eH6jH8HAGlZcQBEVS1NXUpAtn2s63bsd9QHIH92mMwCOx4EchtyWJ+yf/Q76hsAbycu + s2yL+jCbk1iuj3y5fOkHAK1wVjPeZFt4sAiJx3F96ScASN8JeHIP28XcjNnrp+Su34BRA4dZBjvWvtUv + 9ScAs+R13XzWA/ofALrp+m/n327/AQleJadL7a95AAAAAElFTkSuQmCC + + + + + iVBORw0KGgoAAAANSUhEUgAAADAAAAApCAMAAABEBVrmAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6 + JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAADAFBMVEUlEg8wFxMzGRQ5HBc/HhlDIBpL + JB1NJR5OJh5UKCFXKiJfLiVgLiVhLyZjMCdmMShoNCpqNixtOS90PzZ4Qzp5RTx8SD+BT0aFVEuHVk2M + XFSOX1eXamKabWWbb2efdGyhd2+mfneogHmuiIGzjoe6mJPAoJvDpJ/FqaTNs6/PtrLTvLjZxsLh0c7j + 1NHn2tjt5OPx6ej28fD49PT69/f8+vn9/fz///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + 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 + H6YwJdAl+mOdAAAAAElFTkSuQmCC + + + + + iVBORw0KGgoAAAANSUhEUgAAADAAAAApCAMAAABEBVrmAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6 + JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAADAFBMVEVMGwBhIgBoJAB2KQCALQCKMACZ + NgCfOAChOACtPACyPgDAQwDERADJRgDPSADRSQDUSgDZTwXdUwneVQvhWA7kXhbnYxzpZiDsaybtbinx + eDfzezrzfDz1gUP2hEb4ik/4jFH6lF37mmX9onL9qn3+roP+son/vJf/vZr/w6P/y7D/1sD/2MP/3sz/ + 59r/7OH/8er/9vH/+PX/+vj//fz///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD1zQOUAAAACXBIWXMAAA69AAAOvQFH+5CtAAAAGXRF + WHRTb2Z0d2FyZQBQYWludC5ORVQgdjMuNS40Po3MdgAAA65JREFUSEt9lY2WqjoMhasgYrEKghQGRKAI + WLSHUnz/V7spOo7Oz93OWjKLfE2yExDd/pLqT/n1cf2iPwHJqev6cfP496k/ANkdfJLx3Pdp8Z7mV0CJ + 49ZxT1cJZVHfT17T/AbIbo/XfsPlOI5q7DIaUNY/7v0G9C121nHT9BA/qWeU0pzf7/4ARnFYOE52goKe + UornlH5MzfwA+mqNCWOMi3ddWZzp+9+Aod2vsc+KgvHuU9dJYsg+dMQbAO6sbEyLPM8Z5w1/UadU8gPQ + 7tjrjyyBT9Gcmhd1QqqP78BQYcsiSZLE+sNOL9INHaNvQN8uLCuIn8qg84egom6zIlsBYU+gr7Bph6/K + ioca3pzwZhA1FeMn0Ldby1yHwavCLMugfd0Nm2GlBpFe1B3Q7piW+wh8Ksmg+6xhJzbb3JS8iBRq0oDs + tgvTdr27gse35+lOclYw5uBRyfosUjkBfbtaWnbgTooDz43vlxpIGBS1wWh1LMvzJYXTkXZnVWHcFx4h + bmibpunAFSiAvkF0tScGWqYA0Am4FsaSWngcRe7FtgZi1wGRIMiyOPFR1PfnpUGfAD8APgcXRHdyHGzb + 3hTvuF4CNfmzCuoXBKVlfSnpGYA2QstyjqW88lPgEpI4WMtxc5iFgyo46SyIQcq6hhwX1EfIAMAe+65p + ijhk4R1wEzA2nG2UuoA/FJGyrM+QAh2QkRIAlOANa+AvCAPHtkkGBuPNAvyBdgWdEagppalEG2SsCJm7 + uiKWJ8UVyvKCLARbF9s9WSGS6gzYIBTiO4WiGTIMY74WXXMqskTPATruwFZdzr/UuBsaYTg2beUNFTuM + jJ05tz8aVmRxGHgErModZ7bpYX3KhaGBkqbRfs8HsJUXh6g67Kz53A7zJA49VwMJnvlSSRjuSgP15UKr + isNm3NBw5Z0ASiOWTuCCS3ZszbgS4GO6RVT7k9L+H5yvB6eGYZTX9o5gVycAwEbGXs8q3UPXZU1pLUcd + D8BdGommwqZpx9iewTZoQPtDafn5hv0EYGm7akJMSGCGOLCgFgCOETyc9NipR9gXcBulRhxAIINnWTDc + +lKngOwP18/4VwCQnlcHQEyTWKajAd32sW37qd9Jb4D+2eE6C+x4FOltKGF96uHR76RvALydhM6yq9rD + YklTvT765fKlHwC0InjLRVfs4MGiNJ3G9aWfACCDVPDkHnarJUn586fkrt+ASaOAWUZ73r/Ur/UnALMU + bdu91wP6HwC6kcO382+3/wCaQBhXpUSmlgAAAABJRU5ErkJggg== + + + + + iVBORw0KGgoAAAANSUhEUgAAAA0AAAANCAMAAABFNRROAAAABGdBTUEAALGPC/xhBQAAAwBQTFRF/w8n + /RMq/RMr/hQr9yI3+SM5+iU7/Sc89jBFznJ//EJV/ENW9VBh9mNy92p4+Wx64XuJjo+PvJihrrO5sre8 + uLu/vL/CxYOOyqesy6it17W84o6a7pCZ75Ca5Kat6ayz77i/97m/xsfIzsPKzM3Ny8/VzdHX08XL1NXW + 1djc2tzf3N3e3d/h8s3R9c3R4OHh4eLi5ebm5ufn6Ojo6enq7e3t9OLk8vLy9PT09vb2AAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJD5aTwAAAAlwSFlzAAAO + vgAADr4B6kKxwAAAABl0RVh0U29mdHdhcmUAUGFpbnQuTkVUIHYzLjUuND6NzHYAAAB0SURBVBhXTcnZ + GoFQGEbhzw4JYduRoQEJDWgu939j1d/Bts7eZ4H/B97IegkNphDb0bgieWzmnxg7DM/f4DyFexv0eDLA + zu8kIwiXWJXli7SLLWBe1xFp70Jd49okpKOivD9Y/NJe1QTON9NxKejJOsk4bwGhyBMzrrTmTgAAAABJ + RU5ErkJggg== + + + + + iVBORw0KGgoAAAANSUhEUgAAAA0AAAANCAMAAABFNRROAAAABGdBTUEAALGPC/xhBQAAAwBQTFRFRFqS + R1yUSF2VSV6WSl+XS2CXTGGYV2qdXnGhYXOkZHalZ3inbn+qd4arjo+Pi5m7jJm6kJ29rrO5nafAo67I + r7jPsLnRt7/Vub/QusHVvMPWxsjKxcnNysvMyczQy8/Vzc/Ryc/dzNDW1dXW1djc1dnd2trb29zc3N3e + z9Ti3N/k3uDh3+Ll3uHp3+Lp4eLi4OLm5ubm5+fo6enq6+vs7O3t7e7u6uzw7e7x8vP08vP29PT09fX1 + 9vb2+Pj4+fn5+Pn6AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARbOMIgAAAAlwSFlzAAAO + vgAADr4B6kKxwAAAABl0RVh0U29mdHdhcmUAUGFpbnQuTkVUIHYzLjUuND6NzHYAAAB/SURBVBhXY+BD + Bgx81hBgZ29rDeIJgYCcMK+WDZgnLy+vZMHOIGEL5SkZiDJwGUFUquqoWHIwSqmDeTKKImaSzFx2ymCe + Ng+jJjeruK0GmKegy8TMyulgrQ/mSZvzs7CJ2dsagnmyanoCglamJsZgnrW1jb2dDcg9QB4C8PEBAFWP + FTAV/UJaAAAAAElFTkSuQmCC + + + + + iVBORw0KGgoAAAANSUhEUgAAAA0AAAANCAMAAABFNRROAAAABGdBTUEAALGPC/xhBQAAAwBQTFRFjo+P + rrO5r7S6sre8tLm9uLu/u77BvL/CwcPFwsTGxsfIysvMzM3Ny8/VzdHWzdHX1NTV1NXW0NPY0NTZ0tXa + 1Nfb1djc29vc2Nve2tzf3N3e3d/h4OHh4OHj4eLi4eLj4uPk4+Tl5OXl5ebm5ufn6Ojo6enp6enq6urq + 6uvr6+vs6+zs7Ozs7e3t7+/v8PDw8vLy9PT09fX19vb2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkW0KowAAAAlwSFlzAAAO + vgAADr4B6kKxwAAAABl0RVh0U29mdHdhcmUAUGFpbnQuTkVUIHYzLjUuND6NzHYAAABrSURBVBhXXcdt + F4EwFADgRaSIUmJ6w1rycnVn//+/mbvj7BzPt4f9Uc53Hpn4c7vY2BZ88ds6P5SnyG6T7Xgr5Io2LXgt + nwApbVZehhciHmnBuQdUb9XQwh5GpbUWtGWyr7rb436lOWYOYx8cDA/QsvGKEgAAAABJRU5ErkJggg== + + + + + iVBORw0KGgoAAAANSUhEUgAAADAAAAApCAMAAABEBVrmAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6 + JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAADAFBMVEU9AAdPAAlUAApfAAtoAAxvAA18 + AA6BAA+MABCRABGeABKhABOlAxaoBhmrCButCh2wDSC2FCe6GCu7Gi2+HTDCJTfGKz3ILkDLNEbNN0nS + RFTUR1fVSVnXT1/ZUmLcW2rdXWzgaXbicH3mfIjohpLpjJfrkZvun6juoarwqbLytbz1xMr2x8330NT5 + 3eD64+b87O798vP+9fb++fn//Pz///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + 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 + H6YwJdAl+mOdAAAAAElFTkSuQmCC + + + + + iVBORw0KGgoAAAANSUhEUgAAADAAAAApCAMAAABEBVrmAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6 + JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAADAFBMVEUAMQAAPwAAQwAATAAAUwAAWQAA + YwACZwICaAIGcAYJdAkQgBARgRETgxMWhxYZihkbjRsdjx0gkiAnmCcrnCstnS0woDA3pTc9qT0/qz9F + r0VJsUlUuFRYulhau1pfvl9jwGNrxGttxW13ynd9zX2J0omS1pKX2Jec2pyo36ir4Kuy47K9573K7MrN + 7c3V8NXg9ODm9ubu+e7z+/P2/Pb5/fn8/vz///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB6Ra9RAAAAGHRFWHRTb2Z0d2FyZQBQYWludC5ORVQg + djMuMzap5+IlAAADs0lEQVRIS32VDbt6TBDGt0haRRFZImGFVu0fq+//zZ5ZvZw6L8/dua6cy/x2Zu4Z + Qre/JNpTen1cv+lPoGPEtt2wevz70h9A1xxcK2Gp65LsM82vgODHzdI+XTsoi7hu9J7mN6BrdnjlVqwb + hkEMTUI8QtvHvd+AtsbLVVhVLcSPaikhJGX3uz+AgR9mSyM5QUEvCcFSQvZjMz+Atlhhi1LK+KeuNEzk + /W9AX+9W2KVZRlnz1HUU75O9jPgAwJ2FjkmWpillrGJvaoSIfgDSHX21TyL4ZNWpelPDO7H/DvQF1jQr + iqJQfujpTbKhY/ANaOuZpnnhSwl0/hBU1KwX5oZD2AtoC6zq/ruS7KGKVSe87nlJ+PAE2nqjqSvfe5ef + JAm0L7uhEyxEz+OLuAPSHVWzH4EvRQl0n1T0RCfrm+guPIaaJNA1m5mq285d3uPbcWQnKc0oXeJBdOWZ + x90ItPVirumePSr0HDu8X0ogolDUGqPFMc/PlxhOR9KdRYFxmzmWZfu6qqoGXIE86BtEFjtTQfMYADIC + 10yZEw0PA0+dUJdAaBsgy/OSJIxcFLTtea6QF8AOgE/BBd6cDAPrujPGG7YTQU3upID6uYnivLzk5AxA + HaB5PsVdd2Unz7asyMBShp3CLJaogJPO3FTMvCwhxwW1AVIA0Ie2qaos9Kl/B+wIjPUnayEu4A9BZp6X + Z0iBDkiJTQAEZxWt4M/zPUPXrQQMxusZ+APtcjIxoaaYxB1aI2VhmlNbVkTTKLtCWY6X+GDrbLMzF8iM + ZQasmATiG4GCCVIUZbriTXXKkkjOATpuwFZZzr9YuRsaYDg2rrsbyrYYKVt1qu8rmiWh7zkWWJUaxmTd + wvrkM0UCOYmD3Y71YCvLDkFx2GrTqe6nUeg7tgQiPHE70cFwFxIoLxdSFAw244b6K2s4UBLRZAIbXNJD + bcIEBx/jDSLSn5i0/+B8OTjR90N3re8ItmUCAHSk7OSs4h10nZeElN0g4wG4SyLBWNg47RDrE9gGCUh/ + CMmfb9gnAEvbFCOiQgLVx54GtQBwDODhJMdGPMK+gNvQSWQJCGRwNA2GW17KGJDd4fqMfwcAaVlxAERV + LU1dSkC2fazrdux31Acgf3aYzAI7HgRyG3JYn7J/9DvqGwBvJy6zbIv6MJuTWK6PfLl86QcArXBWM95k + W3iwCInHcX3pJwBI3wl4cg/bxdyM2eun5K7fgFEDh1kGO9a+1S/1JwCz5HXdfNYD+h8Auun6b+ffbv8B + CV4lp0vtr3kAAAAASUVORK5CYII= + + + + + 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 + SUwPzmIlAAAAAElFTkSuQmCC + + + + + iVBORw0KGgoAAAANSUhEUgAAADAAAAApCAMAAABEBVrmAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6 + JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAADAFBMVEUAE1MAGWsAGnEAHoEAIYwAI5cA + J6cAKK0AKa4AK7kALL8ALcAGNc0HNs4JONAMO9UPPtgRQNwTQt4WReEdTOYiUekjUuomVe0tW/EzYPQ2 + Y/U9aPhAa/lLdf1PeP5Rev5Xfv9bgf9jh/9lif9wkf93l/+DoP+Mp/+Rq/+Wr/+juf+mu/+vwf+5yv/H + 1P/K1v/T3f/e5v/l6//t8f/y9f/1+P/5+v/8/f////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABcxoJWAAAACXBIWXMAAA69AAAOvQFH+5CtAAAAGXRF + WHRTb2Z0d2FyZQBQYWludC5ORVQgdjMuNS40Po3MdgAAA7dJREFUSEt9lYuWsjoMhasgIqCgIEhBELkJ + WLQ/pfj+T3ZSvIwzzpztrCWzyNckOwHR7S/x7pReH9dv+hNgBNu2G9aPf1/6A2DtwbUSkrouzr6n+RXg + 9LhZ2qcrg7Kw60bvaX4DWLvTV25N2DAMfGgT7OGie9z7DegafbkK67qD+FFdgTFOyf3uBzDQw2xpJCco + 6CXOSYrxfmzmA+jKlWYVRUHod12LMBH3fwB9s1tpbpFlBWmfuo6ifbIXEd8AcGehajhL07QgpCZvajmP + PgDhjrraJxF8svpUv6mljO9/An2pK4oVRVEoPsXpTaKhY/AD6JqZonjhSwl0/hBU1K4X5oZC2AvoSk1W + /Xcl2UM1qU/6uqcVpsMT6JqNIq98711+kiTQvuimmOic9zS+8Dsg3JEV+xH4UpRA90ldnIrJ+sbZhcZQ + kwBYu5nJqu3c5T2+HUd0khZZUSz1gbPqTGM2Al2zmCuqZ48KPccO75cCiAooaq2jxTHPz5cYTkfCnUWp + aV3mWJbtq7IsG3AF8qBvEF7sTAnNYwDwCFwzaY4VbRho6oSqAELbAFmelyRh5KKg685zCb8AcgB8qnFO + 25NhaKrqjPGG7URQkzspoX5qojivLjk+A9AEaJ5PNcau5OTZlhUZmpBhpzCLJSrhpDM1JTOvKshxQV2A + JADUoWvrOgv9wr8DdgTG+pM15xfwByMzz6szpEAHJMUmAJySuqjhz/M9Q1WtBAzW1zPwB9qleGJCTTGO + GVojaWGaU1tUVKRRdoWyHC/xwdbZZmcukBmLDLpkYohvOQomSJKk6Yq29SlLIjEH6LgFW0U5/2Lpbmig + w7Fxw24o2+pI2spTdV8XWRL6nmOBValhTNYdrE8+kwSQ4zjY7UgPtpLsEJSHrTKdqn4ahb5jCyDSJi7j + DIa7EEB1ueCyJLAZN9RfSUuBEogiEtjgkhoqE8Ip+BhvEBb+xLj7B+eLwfG+H9i1uSOaLRIAoCJpJ2YV + 76DrvMK4YoOIB+AugQRjYeO0Q02dwDYIQPiDcf58wz4BWNq2HBEZEsi+5ilQCwDHAB5OfGz5I+wLuA1M + IEtAIIOjKDDc6lLFgOwO12f8OwBIR8oDILJsKfJSAKLtY9N0Y7+jvgHiZ4eILLDjQSC2IYf1qfpHv6N+ + APB2oiLLtmwOszmOxfqIl8uXPgBohZKG0DbbwoOFcTyO60ufACA94/DkHraLuRmT10/JXb8BowYKswx2 + pHurX+hPAGZJm6b9Xg/ofwDohvU/zr/d/gOjFSyLIyVhmAAAAABJRU5ErkJggg== + + + + + iVBORw0KGgoAAAANSUhEUgAAADAAAAApCAMAAABEBVrmAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6 + JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAADAFBMVEVDQwBVVQBbWwBmZgBvbwB3dwCD + gwCHhwCJiQCSkgCWlgCYmACkpAWnpwerqwqurg2xsQ+zsxG2thS8vBu/vyDAwCHDwyXHxyvLyzHMzDTP + zzrR0T3W1knY2E3Y2E/a2lXc3Fne3mHf32Pi4m7k5HTn54Dp6Yrq6o/s7JXu7qLv76Xw8K3z87j19cb2 + 9sn399L5+d76+uT8/O39/fP9/fb+/vn+/vz///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACyxEXdAAAAGHRFWHRTb2Z0d2FyZQBQYWludC5ORVQg + djMuMzap5+IlAAADtElEQVRIS32VD7tyTBDGt0hCFJHlkLBCq/axVt//m72z6nTq/HnvznXlXOa3M3PP + ELr9JdGf8uvj+kV/Apxi1/Xj5vHvU38AvDv4TkZz38fFe5pfAcGOW8s9XTmUhX0/eU3zG8C7vbn2G8rH + cRRjl+EAk/5x7zegb01rHTdND/GTeoIxzun97g9gZIeFZWUnKOgpIWiO8cfUzA+gr9aGQwih7F1XEmfy + /jdgaPdrwydFQWj3qeskNmQfMuINAHdWuoGLPM8JpQ19USdE8gOQ7ujrjyyBT9Gcmhd1jIuP78BQmZrm + JEkSyw85vUg2dIy+AX270LQgfiqDzh+CirrNyt4yCHsCfWWoeviqrHiooc3J3Aysxmz8BPp2q6nrMHhV + mGUZtC+7ITNTiIGlF3EHpDuq5j4Cn0oy6D5ryInMNjfBLyyFmiTAu+1C1V3vruDx7Xmyk5wUhFjmKHh9 + ZimfgL5dLTU9cCfFgefG90sJJASK2phodSzL8yWF05F0Z1UZRl94juOGuqqqFlyBAugbhFd7W0HLFAA8 + AddCWWLNGEeWe7Eugdi1QE4QZFmc+Cjq+/NSwU+AHgCfG0Kw7mRZhq57U7zlegnU5M8qqJ/ZKC3rS4nP + ALQRWpZzg/MrPQWu4ySWIWW5OczCQhWcdGa2Ypd1DTkuqI+QAoA+9l3TFHFIwjvgJmBsONsIcQF/MLLL + sj5DCnRASmoDIBhtSAN/QRhYuu5kYLC5WYA/0C7DMxtqSnHK0QYpK9ueu7IikifFFcrygiwEWxfbvb1C + diozmIqNIb4TKJohRVHma9Y1pyJL5Byg4w5sleX8S5W7oZEJx6Ytv6FiZyJlp871j4YUWRwGngNW5ZY1 + 2/SwPuVCkUCJ02i/pwPYSotDVB122nyuh3kSh54rgcSY+VxwGO5KAvXlgquKwmbc0HClHQNKIppM4IJL + eqzNqGDgY7pFWPqT4v4fnC8HJ4Zh5Nf2jhiuTACAjpS9nFW6h67LGuOajzIegLskEk2FTdOODX0G2yAB + 6Q/G5ecb9hOApe2qCVEhgRoagQa1AHCM4OHEx048wr6A28glYgECGTxNg+HWlzoFZH+4fsa/AoD0tDoA + oqqOploSkG0f27af+p30BsifHSqzwI5HkdyGEtanHh79TvoGwNuJySy7qj0sljiV6yNfLl/6AUArjLaU + dcUOHiyM02lcX/oJADJwAU/uYbda2il9/pTc9RswaWQwy2hP+5f6pf4EYJasbbv3ekD/A0A3fPh2/u32 + H6YwJdAl+mOdAAAAAElFTkSuQmCC + + + + + iVBORw0KGgoAAAANSUhEUgAAADAAAAApCAMAAABEBVrmAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6 + JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAADAFBMVEVgBgB9CACECQCXCgCkCwCwDADE + DQDMDgDeDwDlDwD/AAD/AAL/AAX/BAD/AA3/CwD/DgD/AxP/BRX/DB35EQD+EAD/ESL/Hy3/IzL/JTT/ + LDv/Lj7/OUj/PUv/SVX/U2D/YGv/bXn/c37/eYL/i5T/jJX/lqD/pav/t73/u8L/xsn/1tn/3eD/5+n/ + 7/D/9PT/+Pj//Pz///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADRANgHAAAACXBIWXMAAA68AAAOvAGVvHJJAAAAGnRF + WHRTb2Z0d2FyZQBQYWludC5ORVQgdjMuNS4xMDD0cqEAAAOkSURBVEhLfZWNlqo6DIWrILUCIoUiiEAR + sGgPpfj+D3dT/BlnnLnbWUtmka9JdgKi21/Sw6m4Pq7f9CegBA0CN2kf/770B6D6g8tyUbguLb+n+RXQ + 8riLg9NVQVnUddP3NL8Bqt8S5rZCTdOkpz6nHuXD495vwNCRmCVtO0D8rIFTSgtxv/sBTPKwiuP8BAW9 + pLUoKN3PzXwAQ80I45wL+V1XnuTm/g9g7LaMuLwsueifus6SY743Ed8AcGeNCS2LouBCtOJNvdbpB2Dc + wWyfp/Ap21P7pl4qvf8JjDVxHJamaWI+/PQm09Ax+gEM3cpxvOSlHDp/CCrq2ZrtJIS9gKEmNg7flZcP + taI9ETbKhsrpCQzdzrFZ6L0rzPMc2jfd8AXRepTZRd8B447tBI/Al9Icus9bfuILdtPqIjOoyQCq361s + HPh3eY9v3zedFLzkPCaTVs1ZZmoGhm6NHewFsxLPD5L7pQFSDkUxgtbHqjpfMjgdGXfWNSFD6TMWhNi2 + 7RiuQB70DaLrLbMQzgCgM3AtLUwdMk2y8BNsgCSIQczz8jxJXRQNwxlb9AWIA+BLcEH2pzgmGPtzfBz4 + KdTkLmqoXzKUVc2lomcAugjhakmUuoqTFzCWxsQoDgqYRYxqOOksmcWqpoEcFzREyAIAT0PftmUS8vAO + BCkYGy6Y1hfwhyJWVc0ZUqADsjIGgJai5S38eaEXY8xyMJiwFfgD7Uq6YFBTRjOFGLLWjC0DUxEv0vIK + ZfleHoKtq92WrRHLTAZiMQrxvUbRAlmWtWSyb09lnpo5QMc92GrK+ZdZd0MjAsdmnbqhckOQtbGXeN/y + Mk9Cz2dgVRHHCzbA+lQrywAVzaLtVoxgqygPUX3YOMslDos0Cf3AAClZuEorGO7aAM3lQutawGbc0HgV + vQTKII5JEIBLOHEWQkvwMdshavzJ6PAPzjeD0+M4qWt3R0hgEgCAkbU1s8q20HXVUNqoycQDcJdBormw + edoJwQvYBgMYfyitnm/YJwBL29czYkMCOySeA7UAcIzg4aTHXj/CvoDbpAwSAwIZfMeB4TaXJgNke7g+ + 498BQAZRHwCxbebYsQFM28euG+Z+Z30DzM+OMFlgx6PIbEMF69OMj35n/QDg7SRNlk3dHVaYZmZ9zMvl + Sx8AtCJFJ2RfbuDBojSbx/WlTwCQUWl4cg+bNWaZeP2U3PUbMGuSMMtoK4a3+o3+BGCWsuv67/WA/geA + btT44/zb7T/qbgW9TfW/8QAAAABJRU5ErkJggg== + + + + + iVBORw0KGgoAAAANSUhEUgAAAD0AAAAUCAMAAAAJH8UlAAAABGdBTUEAALGPC/xhBQAAAwBQTFRFTExM + WFhYW1tbYGBgY2NjZGRkZWVlZmZmZ2dnaWlpampqa2trbW1tbm5ucHBwcXFxcnJydHR0dXV1dnZ2d3d3 + eXl5e3t7fX19f39/gICAgYGBgoKCg4ODhISEhYWFhoaGh4eHiIiIiYmJioqKi4uLjIyMjo6Oj4+PkJCQ + kZGRkpKSk5OTlJSUlZWVlpaWl5eXmJiYmZmZmpqam5ubnJycnp6en5+foKCgo6OjpKSkpqamp6enqKio + qampqqqqq6urrq6usLCwsbGxsrKys7OztLS0tbW1tra2t7e3uLi4ubm5u7u7vLy8vb29vr6+wMDAwcHB + wsLCw8PDxMTExcXFxsbGx8fHyMjIycnJy8vLzMzMzc3Nzs7Oz8/P0NDQ0dHR0tLS09PT1NTU1dXV1tbW + 19fX2NjY2dnZ2tra29vb3Nzc3t7e39/f4ODg5eXl5ubm5+fn6Ojo6enp6urq6+vr7e3t7+/v8PDw8vLy + 8/Pz9PT09vb29/f3+vr6+/v7/v7+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/DPJbQAAAAlwSFlzAAAO + vAAADrwBlbxySQAAABp0RVh0U29mdHdhcmUAUGFpbnQuTkVUIHYzLjUuMTAw9HKhAAABlUlEQVQ4T52T + 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 + AABJRU5ErkJggg== + + + + + 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 + /wH43mXDvz/ONMu59lrKAAAAAElFTkSuQmCC + + + + + iVBORw0KGgoAAAANSUhEUgAAAD0AAAAUCAMAAAAJH8UlAAAABGdBTUEAALGPC/xhBQAAAwBQTFRF//// + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACyO34QAAAAlwSFlzAAAO + vAAADrwBlbxySQAAABp0RVh0U29mdHdhcmUAUGFpbnQuTkVUIHYzLjUuMTAw9HKhAAAAE0lEQVQ4T2MY + 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 + WFhYW1tbYGBgY2NjZGRkZWVlZmZmZ2dnaWlpampqa2trbW1tbm5ucHBwcXFxcnJydHR0dXV1dnZ2d3d3 + eXl5e3t7fX19f39/gICAgYGBgoKCg4ODhISEhYWFhoaGh4eHiIiIiYmJioqKi4uLjIyMjo6Oj4+PkJCQ + kZGRkpKSk5OTlJSUlZWVlpaWl5eXmJiYmZmZmpqam5ubnJycnp6en5+foKCgo6OjpKSkpqamp6enqKio + qampqqqqq6urrq6usLCwsbGxsrKys7OztLS0tbW1tra2t7e3uLi4ubm5u7u7vLy8vb29vr6+wMDAwcHB + wsLCw8PDxMTExcXFxsbGx8fHyMjIycnJy8vLzMzMzc3Nzs7Oz8/P0NDQ0dHR0tLS09PT1NTU1dXV1tbW + 19fX2NjY2dnZ2tra29vb3Nzc3t7e39/f4ODg5eXl5ubm5+fn6Ojo6enp6urq6+vr7e3t7+/v8PDw8vLy + 8/Pz9PT09vb29/f3+vr6+/v7/v7+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/DPJbQAAAAlwSFlzAAAO + vAAADrwBlbxySQAAABp0RVh0U29mdHdhcmUAUGFpbnQuTkVUIHYzLjUuMTAw9HKhAAABlUlEQVQ4T52T + 6zcCQRTAFxEljzxC2UjYapXXrrdED1t6SFa02tqdDSVKQp7/ui1z6NtOfp/u3Ht+M3PuuRcDTWR8IRGG + aDTZvGcjXwgFUi1c8GeztvXbz6+vJy6YkGBKkV/7ZGIPPL/JvNduImmYVALa6fUpLyvel8rlh0rlNX/2 + k1Xkxz4xTXoZJgauZW4equFEI6tMw44OWrZ3ZXzJ8wuuIKxxsUZNGdlOrejmaYqmKIo+DMezafyuhto2 + DCQtGtpBuqxOh510+9mwU5u8zsKqElhumhh5SSzr2mfMJsId3HTkF8akS0QdEzpJ7UfZZ1s0DI9S7iXL + c/VUwxdYtL9jY1pX71sxk/IS4yQ9a+wOXWVUQTaMaE9iqh4xF/dRuGtVv18icCCQxAGsKoHx3qhFbfZs + 2g3jQzu1x51hvhjj0HsuSWIE79TjQ4b+nqMi0+WJoM5K3a7DB00dar21beX2bMvewpbCOZeEgFGl65vL + Fo7BfzY0J0TP9wb8DAfPSPza8vtA3LWlkHe7TpMtI+VggAQA31EYtvsm5zkIAAAAAElFTkSuQmCC + + + + + iVBORw0KGgoAAAANSUhEUgAAAD0AAAAUCAMAAAAJH8UlAAAABGdBTUEAALGPC/xhBQAAAwBQTFRFmdXV + mdramdvbmdzcmd3dmd7emd/fnt/fmeDgm+HhmeLimePjmeTkmeXlmebmmefnnuPjn+fnmejomenpmerq + mevrmezsme3tme7ume/vnejonO3tnO/vmfDwmfHxmfLymfPzmfT0mfX1mfb2mff3nvPznfT0nPb2n/f3 + mfj4mfn5mfr6m/v7nPj4nPn5nfv7od3dod7eot/fpt7eoOLiouXlpubmp+fnoenpo+rqo+vroe7uoO/v + purqqO3toPHxofLyofPzo/T0oPX1o/b2p/LypPT0pfb2p/f3ofj4ovn5ofr6oPv7ofz8pfj4pvn5p/v7 + qvT0q/f3rPDwrfPzrfT0rPX1qvj4qvn5qfv7qvz8rfj4r/v7rfz8serqsu3ts+/vuezsuu/vvunpve7u + sfPzsfn5sfz8sv39tvn5tv39ufLyuvb2vPHxvPPzvvT0uvr6uP39vfr6vPv7vv39wurqxejoxuvrxezs + xe3txu7uzOXlzObmzefny+rqyezsz+rqzezswfHxw/LywPPzwvj4wfv7wf39xfz8zvDwyfr6yPz8yP39 + z/z8zf7+0uPj0+Tk0ubm1eHh1eLi1ePj1OTk1OXl0urq0/f30f7+1f7+2Pv72/7+3/7+4vz84/7+5/39 + 5f7+5v//6fv76v7+6///7P//9f//+////P//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFkrd1wAAAAlwSFlzAAAO + vAAADrwBlbxySQAAABp0RVh0U29mdHdhcmUAUGFpbnQuTkVUIHYzLjUuMTAw9HKhAAABpUlEQVQ4T2OY + hACT693i66Bs4gCS7uoQ1e7ecNeUfiifCIDQXWHj2LN85Yr5RZ4JDVAhggCme0qisHP63GUgsKjDqwwq + SghAdE+usRNV0Y/t65sJBLMWdSeCRQkDsO7JpRaiKlpa3ulZQFA4c344KbonJAuIKYOApo+vr29JUfCM + VIgkQQDUXWPLLaEIAZra2rExZosXtkFlCQGGSeVWnA6ycnLicrKyciqa+noyxplZxVBZQoBhmqC06ZJM + OW4mMTFRSWUtBdvZcXwZBbVQaQKAoYpZ2mj5THdJWWF+IXllOfMFc1o5okrSpkLl8QMGEw4Zo6XtsZHu + ksKSChIihkFZbay6kX5E6hZiYGXvytLRVRWztudtmmcpnFEsKenSCJUmABjyQlNFWKWUlWSFhXmSlsxy + 5Ilqj8gmUjMwzKdNqQwUZuUV4xfiNvBr92RT9w+DyhEG4LQ2rcVDiIWDV5xRpj1AUdJtOliGGABJ55Mm + trgLsXJxicWWeDeTk0MntkTnO3Fr6OVC+UQBuG5gXpncpCaRMwXKIwog6QaCiZ2kaJ40CQBLsmMl+qL9 + EAAAAABJRU5ErkJggg== + + + + + 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 + QmCC + + + + + iVBORw0KGgoAAAANSUhEUgAAAD0AAAAUCAMAAAAJH8UlAAAABGdBTUEAALGPC/xhBQAAAwBQTFRF//// + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACyO34QAAAAlwSFlzAAAO + vAAADrwBlbxySQAAABp0RVh0U29mdHdhcmUAUGFpbnQuTkVUIHYzLjUuMTAw9HKhAAAAE0lEQVQ4T2MY + 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 + 2Zu+iiHUgUsAAAAASUVORK5CYII= + + + + + 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 + YII= + + + + + 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 + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACyO34QAAAAlwSFlzAAAO + vAAADrwBlbxySQAAABp0RVh0U29mdHdhcmUAUGFpbnQuTkVUIHYzLjUuMTAw9HKhAAAAE0lEQVQ4T2MY + BaNgFIyCYQUYGAAE2AABE91XygAAAABJRU5ErkJggg== + + + + + iVBORw0KGgoAAAANSUhEUgAAAD0AAAAUCAYAAAA+wTUXAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6 + JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAACXBIWXMAAA68AAAOvAGVvHJJAAAAGnRF + WHRTb2Z0d2FyZQBQYWludC5ORVQgdjMuNS4xMDD0cqEAAAZfSURBVFhHxZd9TNR1HMeRhSvJNUoNrDRL + K521Rbm55R+NWjMrN0trs1mjJ+csszlXM2czNdRUJoqaZ6YkiIj4gKIgoiDi8SxHhxwPwnEgTyooDwJ3 + 3Lvf+3P+rjvud0g+1B/v/bjjft/f9/V9f55+PiXrjBioynUmXI84CLwegpszPodleZLm7+6bIoyoTKp2 + ++7SwWqY02pRcdKCkq2lbv/zpgFDX9GdgX3mTFifHQXrxkjYduwAJoXA9tqbuDovHKawfM377pkU4JQM + AzLzylBsrER5eY2osKIe54wWHL9Qi2M5VfK3qrQLNSiKMXmsdVtoU8RfaN++B12jg2AbNw7YtB32llbY + u7sdysqBfd4i9E54BZ2fLYFlTZrmOncjy2Ej2lszkXQgFLs2jYBuvb+HDiR8haMFFlG83izak1WLE3ty + PNbrF5rA1pXr0BDwIKyTJgscIXHJ7K76BtiNpfJbut+4NFZzvTtV4+UsNNWmwlKhQ92f03Bthi9qp/qi + dKUvilJ9oE/0RVr8A0g9sw0xqSWIiM0SbTvXjMSIsx7raUITtmFDChqnvIGmIX7ioi3kPQd0zH432eKO + ipCYLOC9azejafZKjzXvRgSmmmsS0PZrKGx+fqIb3/qgLs8hgvNQqmuvYPOpGiyJTEZaah70+wwoDS9x + W88DmsB1q3UwjxkpDvc+/RJsT453SMlfCeUlqzwk8Hm5cjgDhTZuyNX83lXcMJ3u7rgoaglf5oSu/NQH + PWYfNBoGOaGbrrbht4IuLN2ZhfxE7TXdoAlMp3JGDHc4/NAwDxG+950PncKsULmHod0RMlkKXG/ofNRF + uz9IS8bFX6Pmg9ko+TlR8/+qVGhes8O/d0IXfzMIHZWe0Lvyb9we2hRZisaIZNRPfQvZ/o4F+xXBlZBn + /orzCmRO8ERxWkJccX4g0GWhc2S9zqAgr/B0uqI4FtkZq0SFcXOd+yhf5AhrNa9doZftzvEOTeDW3/eh + /vmxyAnwk5bkhFNEx10/U66OE7zrqRE4MWEc7IuWCjCv7OluD/slHVUL4tzEQ5a1bq3rDZ4u9/aY5Wo1 + xTh/b01whDfd7gsdFq33Dt28Nx/nJ05EfWAgSscGOpxSnLMNe0xcT/b3dYJ3BgyWq4S6kuvcpOHFl6Wg + GaZPQ84jAQJM96uWpbg9yPjdYudmVVBv19axo6SuqPeq4c221WmORs/0IPS8PQhthQ5grfDu1+mWsL2I + 8R+MS+PHI2VMoLQfFiW2KEK2Bz4uG2FR42cBVw6EG9S/GiyH1JWcLbA8IB4Yc9z2/hxYtub98zDFver5 + 0W5ydZpXit8JsDKMiJR7zWUJAt3TUSBOW398AtYffHD9qDY0C1m/0AzLlOFDJbwJLf1Wmbi4efvHX+Dm + BKV6K5ui2+oB8G8qfvRImdLE3VvQPCwpclOmueV137bBz8Z5jvajwlat/kOKqevvqJryQxLedLw4fIXc + Q+k/8azebFnsz2xZnOCKdBc91vNhpY4c4iMbThw93AHMFqS0J+at6m7bC89Ivhc/7IvmBXNhT09HcXAw + TIrrKjRTRCCUIte685THw/qK0IRltJVvKtT8DcVCRhlytyB3xUdOaFZv9mjTWUdOn8k+AP3Fehk/j2WV + I+58tfZERsCW6bPEWQIQnlcpVLdCj9CmR4eKWHEZDRxGGAU8KDWk6S5bV9fBdI8HaUopbv3BqmowFYjL + 5aYkCfWm5LUymZn07zp15PRWmcYIqsrrGMowk4FECcVuXbzkogpPVwnNfObfLGwMacJxBqejEtLPBTte + PpR7B9Kq/q3YYdgNzmZWCkxsZpXbjK3O2dSWRAPW7i+S6q075JjI+q7nMZxw0zfXR8lkpcITVu3fLHrM + f3FWyV1GBL/nQVyOPOeRu/dUSmE7lVwsucoRk1dX8e2Lb2HqGCouK/fw9dN1X15nb8JLFVZym2GtglPM + XXy50BnSPKT74bCm1KrOd2flygg4WXBVXjCyyq5JEduQ4bgy3JPijdif2+D24qEJ7ZSyKPu4hLLiKvOV + LyEEZ0hL3ivgWhX3vxKhT5e1Y+GKQwLPdkXtMNgkvAnOA9j+0xHnPf1Du4hO8gE9G3dLAWPLGui4eV+l + OM4wjlmVJPm7ZsthLA+PF62PiIMhqgRRUSdwPCzDec+AoVURnMMI9b8D35GM+BtD6z86AGwUowAAAABJ + RU5ErkJggg== + + + + + iVBORw0KGgoAAAANSUhEUgAAAD0AAAAUCAYAAAA+wTUXAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6 + JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAACXBIWXMAAA68AAAOvAGVvHJJAAAAGnRF + WHRTb2Z0d2FyZQBQYWludC5ORVQgdjMuNS4xMDD0cqEAAAYmSURBVFhHzZhtTJVlHMYPmLWVzvme+sFc + 2Votqzk33WzrU+baWivrQ2Wbm7WWlWaTXG/rRZckExPQbL4SKMIA5QhyjqACwRF558ABDmdHzjm8I2CA + hChe3dcfnuN5eXjRafXh2nN4zvPcz/O7r+t/3/+DoTrChjvRwQw3Hq934fW6ZiSkunSvuV+yH3fAYboM + ++F6v/M1v9fBbnLDnuL0Oz+aJgydrAZdUePEFLsdYf392HHtGp5ubxeFFTShKKZW9757pl9tyM4rFZWW + VaGquha2WieKbS7kWT0wl7pxutgtnzXxnDWuLmiscaGtUbXYaXJgusWCGVYrwgYH0XHrFq6P6KTSu3/1 + YE5HB97LdSMtRbmvXlBvrLuVK7UKfd0WXMjcgOTDC5F4YDri9s70U2rK+0gvcQh4UqFHFJfvwZmMStTG + lPuNNyY03dtY0QiD0YiZ9fV4UQETshwIUt7QEDaqBBA+6lyT7nh3q9bGPLQ3Z8NVvxeu0k24nPs2atOX + o/JsqFfZSZNw7sJuJJisiEm04Jcj5+QzoQNNGBWacX42rxiGrCyENjfjoZ4eLB0YwE8Kjtrpo31qMiiC + M/qbshp0x7xbOe1p6GrNRVdJLHpfXYHr8+aL+lfOQHvyA6jLDYElLQTOmmi4W7pwoKAd3xzMg+l4ES7t + 8XeZ0oXedroOc00mL7CmWX194vYrOiL82Zs3pcYnDB2er38+QK56Iwb7azC09VPcnDoH7pnzYZ0+Wz4P + vDwHTZYQ5KSEShJarvTiaPk1fBdbiIKEKt3x/KAZ56/TbAiJjw8C9hXhfbX+xg2p6xfKyrBbfb9KgZem + uP0epKstn8D95juw/WjU/35EdLq3sxRd+79F19rVyP/ieRQsmybQdDsQOrasF9uOFY0PzTg/k5krwCEX + L8KgVunRRHDGXYv8MnV8IiUFhVevSsQ5CflpjUEPC5R93Vpg8lSJ6ljwdNphO4GqkijY8r9H25rnhl1+ + 8lF4oh/0xvuOoCNH4hwSEyMrtEBXVIj42Vc8pzlOaB4fttmwKDJSHGbU6Xrggxjly58l+ql19SqB1jQa + PKOtach+Qq4j8ODJyRhsMKDPYQiGTrYNQ+vsJAazuXkYWAEtSExEkapLvrwAq0kwhIffBlaR51EDpuuP + mc2yiK3MzJSUEPqt7h6ciQt42OYtfoBjiUCuiN+897Z4zLJldbako6swUuq4b800iXVbhUG3psd0misd + wQg0NzoazWr74aK0oLHRH3akzjWneWSkGed4tY191Noqk/SUalrWqngv77jiF3G617Ah3k+BTjOyPOfc + ccjPIcZ7aLBBnB74M1auo9uOxEniNMG5ZU043nMPxMnLEo7Q3HNZk6xVAixqahoGV3u1HJW72kTM3rVL + 4OjuB729Mg4nhPctbusct0vTatoXtmZPWdB1GjT364xDO2B5YzGyXnsER7eH+kFrW1aCxS17NfdpPXCD + OLh58zC40lfd3QLhW6+EnFVYOFzv6vr1lZU4o/Zj2dbUZGh1zOsopiQuc/yFrPrjdWPCatIWMarowpco + NL8kNUxpzcn5tCVIPZ8tHZkmwgeVmZLhQ89VLHU6h+uYMVbgU06dEmBKXFVg4rQCXqPgWfesY3ZpPEdn + mQ7u0RwvKcMT9CBdqcVtLFiRinmD0Yb6tEuorLGIyqxGlJTuE2d5pP7IzpG2U2tBj19UE6/+ZoMSOKaB + vXXxQYfEILy6C0uUSwJI57U69oFmpOkkIdlyapFmnLl1cbzAh9wTKfjyEtVP5zqDpeAorQVlY/J5xCnE + Hjk/sR8chN9qvSK1LLBcvUcmQFwfWc0JTYe1Gl/Y2QnuBIHj3UtxQkuMtfKOvmJ/bcqxSj0z1lycuZDl + mqvlZyevqdx/exzdNpRiR0V4uuoHTylIuspVmh3Zz5YWFOy3647zb4iTzV77tLUL+4r/9orOU5yEYxHZ + 3utHhdbEAcNa+2SV5go9z+EQ17WaZw3ft0hPRCr2sSdKsF3FOb/II02Jph+ijOI2XT+8Ld17z7jQFKG4 + /fDICeA/Eug29+b/FHhEVUl1Ik5AekyeVzlHiuUcv/Ot7QlBB4rux+a3/S+A71w2/ANexKXfwolaxQAA + AABJRU5ErkJggg== + + + + + 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 + RK5CYII= + + + + + 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 + fhwAAAAASUVORK5CYII= + + + + + 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 + v93+A6MVLIsjJWGYAAAAAElFTkSuQmCC + + + + + iVBORw0KGgoAAAANSUhEUgAAADAAAAApCAMAAABEBVrmAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6 + JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAADAFBMVEVMGwBhIgBoJAB2KQCALQCKMACZ + NgCfOAChOACtPACyPgDAQwDERADJRgDPSADRSQDUSgDZTwXdUwneVQvhWA7kXhbnYxzpZiDsaybtbinx + eDfzezrzfDz1gUP2hEb4ik/4jFH6lF37mmX9onL9qn3+roP+son/vJf/vZr/w6P/y7D/1sD/2MP/3sz/ + 59r/7OH/8er/9vH/+PX/+vj//fz///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD1zQOUAAAACXBIWXMAAA68AAAOvAGVvHJJAAAAGXRF + WHRTb2Z0d2FyZQBQYWludC5ORVQgdjMuNS40Po3MdgAAA65JREFUSEt9lY2WqjoMhasgYrEKghQGRKAI + WLSHUnz/V7spOo7Oz93OWjKLfE2yExDd/pLqT/n1cf2iPwHJqev6cfP496k/ANkdfJLx3Pdp8Z7mV0CJ + 49ZxT1cJZVHfT17T/AbIbo/XfsPlOI5q7DIaUNY/7v0G9C121nHT9BA/qWeU0pzf7/4ARnFYOE52goKe + UornlH5MzfwA+mqNCWOMi3ddWZzp+9+Aod2vsc+KgvHuU9dJYsg+dMQbAO6sbEyLPM8Z5w1/UadU8gPQ + 7tjrjyyBT9Gcmhd1QqqP78BQYcsiSZLE+sNOL9INHaNvQN8uLCuIn8qg84egom6zIlsBYU+gr7Bph6/K + ioca3pzwZhA1FeMn0Ldby1yHwavCLMugfd0Nm2GlBpFe1B3Q7piW+wh8Ksmg+6xhJzbb3JS8iBRq0oDs + tgvTdr27gse35+lOclYw5uBRyfosUjkBfbtaWnbgTooDz43vlxpIGBS1wWh1LMvzJYXTkXZnVWHcFx4h + bmibpunAFSiAvkF0tScGWqYA0Am4FsaSWngcRe7FtgZi1wGRIMiyOPFR1PfnpUGfAD8APgcXRHdyHGzb + 3hTvuF4CNfmzCuoXBKVlfSnpGYA2QstyjqW88lPgEpI4WMtxc5iFgyo46SyIQcq6hhwX1EfIAMAe+65p + ijhk4R1wEzA2nG2UuoA/FJGyrM+QAh2QkRIAlOANa+AvCAPHtkkGBuPNAvyBdgWdEagppalEG2SsCJm7 + uiKWJ8UVyvKCLARbF9s9WSGS6gzYIBTiO4WiGTIMY74WXXMqskTPATruwFZdzr/UuBsaYTg2beUNFTuM + jJ05tz8aVmRxGHgErModZ7bpYX3KhaGBkqbRfs8HsJUXh6g67Kz53A7zJA49VwMJnvlSSRjuSgP15UKr + isNm3NBw5Z0ASiOWTuCCS3ZszbgS4GO6RVT7k9L+H5yvB6eGYZTX9o5gVycAwEbGXs8q3UPXZU1pLUcd + D8BdGommwqZpx9iewTZoQPtDafn5hv0EYGm7akJMSGCGOLCgFgCOETyc9NipR9gXcBulRhxAIINnWTDc + +lKngOwP18/4VwCQnlcHQEyTWKajAd32sW37qd9Jb4D+2eE6C+x4FOltKGF96uHR76RvALydhM6yq9rD + YklTvT765fKlHwC0InjLRVfs4MGiNJ3G9aWfACCDVPDkHnarJUn586fkrt+ASaOAWUZ73r/Ur/UnALMU + bdu91wP6HwC6kcO382+3/wCaQBhXpUSmlgAAAABJRU5ErkJggg== + + + + + iVBORw0KGgoAAAANSUhEUgAAADAAAAApCAMAAABEBVrmAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6 + JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAADAFBMVEUASUkAXl4AZGQAcXEAfHwAhYUA + lJQAmpoAm5sAp6cAra0Arq4Au7sAvLwAvr4Aw8MAxsYAyckAy8sAzs4A1NQA19cA2NgA29sA398A4uIA + 5OQA5+cA6OgA7e0A7u4A7+8A8PAA8fEA8/MA9PQK9vYU9/co+fk5+vpB+/tK+/tg/Pxj/f1x/f2E/v6c + /v6i/v6x/v7F///P///f///q///v///0///6//////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + 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 + 1xe7R6QZxv8DiyxXTC5xLO8AAAAASUVORK5CYII= + + + + + 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 + 1xe7R6QZxv8DiyxXTC5xLO8AAAAASUVORK5CYII= + + + + + iVBORw0KGgoAAAANSUhEUgAAADAAAAApCAMAAABEBVrmAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6 + JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAADAFBMVEWZysqZ0NCZ0dGZ1dWZ2NiZ29uZ + 39+Z4eGZ5eWZ5uaZ5+eZ6uqZ6+uZ7e2Z7u6Z7++Z8PCZ8vKZ8/OZ9PSZ9fWZ9vaZ9/eZ+PiZ+fmZ+vqZ + +/ud/Pyh/Pyp/Pyw/Pyz/f23/f2//f3A/v7G/v7O/v7X/v7Z/v7f/v7n///r///y///2///5///+//8A + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC5XfXWAAAACXBIWXMAAA68AAAOvAGVvHJJAAAAGnRF + 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 + SUwPzmIlAAAAAElFTkSuQmCC + + + + + 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 + SUwPzmIlAAAAAElFTkSuQmCC + + + + + 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 + dxRklOT2WyEJAAAAAElFTkSuQmCC + + + + + iVBORw0KGgoAAAANSUhEUgAAAD0AAAAUCAIAAACxo6JAAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6 + JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAACXBIWXMAAA6+AAAOvgHqQrHAAAAAGnRF + WHRTb2Z0d2FyZQBQYWludC5ORVQgdjMuNS4xMDD0cqEAAATXSURBVEhLzZZpUFNXFICjo9ixFKZKC2gr + lQE0ZcAVQRBaOoQEKYtlKVoRFGzVDkYo2whtQRAYtSPIotSFgIigrIqySANFIGwiSSCAQC3rpMCUJYQl + yXunF5+jzmu0paS2M9+8H+/ce+ab984991AEAng1ra1w9z7mFjoRFDdd24i3tJIX/Cf8hXdlA+4Z9ruR + hzC9RJZTLv0iTLwvTHz9DtbMI698zbzUu60drhWKdBw6jD0Hs37CRFMglc3B74ao1Fmn4zMxKbKGJvIu + hdDSAnWNWG3DHA1NWOufFiDke/NbIfHm1ArzWhvm8JnrwOuG/qGnDAzD4Ah09QPrLrY3XHqbTd67cIrY + Eh3HvndpPQjaIWFTM05agJDjXV6L2R3tVvuYa+snOnwGTmfA3VoorYeyxjnYD6DiIVRyoXsA0kshIVNO + 0gUyb++2NriSM65tw1H76AGNOWMbIEN4nsTQJ0/Ke05yAZQ3AbcT8zopjrsmezGDQnjRm35E+JD7Sm9e + K34xZ1TdrGAVjbvZQ2R0QPwMhu/MsTjwT4CARDieDKnF8GOeyPJg1+W8kaD46WcZFAW7SmrgOkB4uwUN + k6IET73ZHIm9D19pw21N60d6ziM6TiO6T54E6I2tv9QlFN8fBdFXISJFauRc/EAg6uyb+/bPcikKdCi3 + ewwS3n6nRklRAkp7B2SXjus7NiwzzNmyt1+D3qvJ6NV26NWwatGy61G3Rvyqyegz8RbTfaVf/wDu4TO6 + jl3aFpcir0xeyIezWYqvb34LTjssJLxPXRaRogQUfjuYuN6j7uJrmBf/MoAHJ06ud+pbali4WPe8Jo33 + pin/DePmd6y6Tbwn7QNlOw4OWXpy8iumHY5UrqWVxd6AmKvS6jrFq6PyILxZOVOkEAHlVgWmYZS0bQ9X + wyRtTDTXMXYFjr1n00V1eqy0pW6RYeWSTRyqq9DYa5Lq3GO+p6SzT9rYDicujaluzjiRAqlFEHJeQkq6 + cPxOjyLpVYzewjL5ySnGzoVq2zI2fN6+2iwdteeMexCZCiHJmJ3/hDqtS9Wsbq1d9zqXIXWrtpUW9erb + Ln0ZNZaUC2czJUofslxCpo/GYl/FSElJF87lm1P2zKHdwcP3a+X3K8q6nRWUNd8v02et3JrKKhTHZ8OB + KKD7zlBdhKhIDF07DN16lLcWM2M6OXyJuXuNtk3N2SyIzZLpOXauond+FjhRr+hbs5mLp+VOJ2eKETlF + s6QoASX9NsaM+e3bxAm9T+tUNrL07SvozImN7uPoOC7dUqdmwVmxvehQOO/xIF7NB7rP4BrLWxEsyCwD + 72hJ0k0MTVqkjAunkiPbtPtpH3T65pV9EA195TUQfG5Sm1Gz3ID1llGJsilvseHPb5tVqWy9pbXj4v6I + SVRCu4JnlhukMo6N7YuYDUpQ/I1DMA9vAmSfXYp7R05oWVct0kuhrM9SNS7RsBIs0T1n6tGWXgLMONzU + a+T9nV37IyRN3OcbFcu8vQm4fLhRjLt/N7b6k+ol1DTlzXkrjXOpDk1RaZBWDF7RWAUHf/ivSSPQiF9T + L0MnEoHuIFKUQI43Ae+JfWi8KK1gam+IUMXojn2A2D5QwspXfEH/A17q/SLsamD4DH1g++jCDancafj1 + 87e8EWiWR3/gfyItEMAfGSFv/tw5mZ0AAAAASUVORK5CYII= + + + \ No newline at end of file diff --git a/ROMVault2/rvTree.Designer.cs b/ROMVault2/rvTree.Designer.cs new file mode 100644 index 0000000..5dff86c --- /dev/null +++ b/ROMVault2/rvTree.Designer.cs @@ -0,0 +1,47 @@ +namespace ROMVault2 +{ + partial class RvTree + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.SuspendLayout(); + // + // rvTree + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.DoubleBuffered = true; + this.Name = "RvTree"; + this.Size = new System.Drawing.Size(455, 416); + this.ResumeLayout(false); + + } + + #endregion + } +} diff --git a/ROMVault2/rvTree.cs b/ROMVault2/rvTree.cs new file mode 100644 index 0000000..28e0a57 --- /dev/null +++ b/ROMVault2/rvTree.cs @@ -0,0 +1,452 @@ +/****************************************************** + * ROMVault2 is written by Gordon J. * + * Contact gordon@romvault.com * + * Copyright 2014 * + ******************************************************/ + +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Windows.Forms; +using ROMVault2.RvDB; + +namespace ROMVault2 +{ + + public partial class RvTree : UserControl + { + + + public event MouseEventHandler RvSelected; + + private RvDir _lTree; + + private RvDir _lSelected; + + public RvTree() + { + InitializeComponent(); + } + + #region "Setup" + private int _yPos; + + public void Setup(ref RvDir dirTree) + { + _lSelected = null; + _lTree = dirTree; + SetupInt(); + } + + private void SetupInt() + { + _yPos = 0; + + int treeCount = _lTree.ChildCount; + + if (treeCount >= 1) + { + for (int i = 0; i < treeCount - 1; i++) + SetupTree((RvDir)_lTree.Child(i), "├"); + + SetupTree((RvDir)_lTree.Child(treeCount - 1), "└"); + } + AutoScrollMinSize = new Size(500, _yPos); + Refresh(); + } + + private void SetupTree(RvDir pTree, string pTreeBranches) + { + int nodeDepth = pTreeBranches.Length - 1; + + pTree.Tree.TreeBranches = pTreeBranches; + + pTree.Tree.RTree = new Rectangle(0, _yPos - 8, nodeDepth * 18, 16); + pTree.Tree.RExpand = new Rectangle(5 + nodeDepth * 18, _yPos + 4, 9, 9); + pTree.Tree.RChecked = new Rectangle(20 + nodeDepth * 18, _yPos + 2, 13, 13); + pTree.Tree.RIcon = new Rectangle(35 + nodeDepth * 18, _yPos, 16, 16); + pTree.Tree.RText = new Rectangle(51 + nodeDepth * 18, _yPos, 500, 16); + + pTreeBranches = pTreeBranches.Replace("├", "│"); + pTreeBranches = pTreeBranches.Replace("└", " "); + + _yPos = _yPos + 16; + + bool found = false; + int last = 0; + for (int i = 0; i < pTree.ChildCount; i++) + { + RvBase t = pTree.Child(i); + if (t is RvDir) + if (((RvDir)t).Tree != null) + { + found = true; + if (pTree.Tree.TreeExpanded) + last = i; + } + } + if (!found) + pTree.Tree.RExpand = new Rectangle(0, 0, 0, 0); + + + + for (int i = 0; i < pTree.ChildCount; i++) + { + RvBase t = pTree.Child(i); + if (t is RvDir) + if (((RvDir)t).Tree != null) + { + if (pTree.Tree.TreeExpanded) + { + if (i != last) + SetupTree((RvDir)pTree.Child(i), pTreeBranches + "├"); + else + SetupTree((RvDir)pTree.Child(i), pTreeBranches + "└"); + } + } + } + + + } + #endregion + + #region "Paint" + private int _hScroll; + private int _vScroll; + protected override void OnPaint(PaintEventArgs e) + { + + Graphics g = e.Graphics; + + _hScroll = HorizontalScroll.Value; + _vScroll = VerticalScroll.Value; + + Rectangle t = new Rectangle(e.ClipRectangle.Left + _hScroll, e.ClipRectangle.Top + _vScroll, e.ClipRectangle.Width, e.ClipRectangle.Height); + + g.FillRectangle(Brushes.White, e.ClipRectangle); + + if (_lTree != null) + for (int i = 0; i < _lTree.ChildCount; i++) + { + RvBase tBase = _lTree.Child(i); + if (tBase is RvDir) + { + RvDir tDir = (RvDir)tBase; + if (tDir.Tree != null) + PaintTree(tDir, g, t); + } + } + + + } + + private void PaintTree(RvDir pTree, Graphics g, Rectangle t) + { + int y = pTree.Tree.RTree.Top - _vScroll; + + if (pTree.Tree.RTree.IntersectsWith(t)) + { + Pen p = new Pen(Brushes.Gray, 1) { DashStyle = DashStyle.Dot }; + + string lTree = pTree.Tree.TreeBranches; + for (int j = 0; j < lTree.Length; j++) + { + int x = j * 18 - _hScroll; + string cTree = lTree.Substring(j, 1); + switch (cTree) + { + case "│": + g.DrawLine(p, x + 9, y, x + 9, y + 16); + break; + + case "├": + case "└": + g.DrawLine(p, x + 9, y, x + 9, y + 16); + g.DrawLine(p, x + 9, y + 16, x + 27, y + 16); + break; + } + } + } + + if (!pTree.Tree.RExpand.IsEmpty) + if (pTree.Tree.RExpand.IntersectsWith(t)) + { + g.DrawImage(pTree.Tree.TreeExpanded ? rvImages.ExpandBoxMinus : rvImages.ExpandBoxPlus, RSub(pTree.Tree.RExpand, _hScroll, _vScroll)); + } + + + if (pTree.Tree.RChecked.IntersectsWith(t)) + { + switch (pTree.Tree.Checked) + { + case RvTreeRow.TreeSelect.Disabled: + g.DrawImage(rvImages.TickBoxDisabled, RSub(pTree.Tree.RChecked, _hScroll, _vScroll)); + break; + case RvTreeRow.TreeSelect.UnSelected: + g.DrawImage(rvImages.TickBoxUnTicked, RSub(pTree.Tree.RChecked, _hScroll, _vScroll)); + break; + case RvTreeRow.TreeSelect.Selected: + g.DrawImage(rvImages.TickBoxTicked, RSub(pTree.Tree.RChecked, _hScroll, _vScroll)); + break; + } + } + + if (pTree.Tree.RIcon.IntersectsWith(t)) + { + int icon = 2; + if (pTree.DirStatus.HasInToSort()) + { + icon = 4; + } + else if (!pTree.DirStatus.HasCorrect()) + { + icon = 1; + } + else if (!pTree.DirStatus.HasMissing()) + { + icon = 3; + } + + + + Bitmap bm; + if (pTree.Dat == null && pTree.DirDatCount != 1) // Directory above DAT's in Tree + bm = rvImages.GetBitmap("DirectoryTree" + icon); + else if (pTree.Dat == null && pTree.DirDatCount == 1) // Directory that contains DAT's + bm = rvImages.GetBitmap("Tree" + icon); + else if (pTree.Dat != null && pTree.DirDatCount == 0) // Directories made by a DAT + bm = rvImages.GetBitmap("Tree" + icon); + else + { + ReportError.SendAndShow("Unknown Tree settings in DisplayTree."); + bm = null; + } + + if (bm != null) + { + g.DrawImage(bm, RSub(pTree.Tree.RIcon, _hScroll, _vScroll)); + } + } + + + + Rectangle recBackGround = new Rectangle(pTree.Tree.RText.X, pTree.Tree.RText.Y, Width - pTree.Tree.RText.X + _hScroll, pTree.Tree.RText.Height); + + if (recBackGround.IntersectsWith(t)) + { + string thistxt; + + if (pTree.Dat == null && pTree.DirDatCount != 1) // Directory above DAT's in Tree + thistxt = pTree.Name; + else if (pTree.Dat == null && pTree.DirDatCount == 1) // Directory that contains DAT's + thistxt = pTree.Name + ": " + pTree.DirDat(0).GetData(RvDat.DatData.Description) + " ( Have:" + pTree.DirStatus.CountCorrect() + " \\ Missing: " + pTree.DirStatus.CountMissing() + " )"; + + // pTree.Parent.DirDatCount>1: This should probably be a test like parent contains Dat + else if (pTree.Dat != null && pTree.Dat.AutoAddDirectory && pTree.Parent.DirDatCount > 1) + thistxt = pTree.Name + ": " + pTree.Dat.GetData(RvDat.DatData.Description) + " ( Have:" + pTree.DirStatus.CountCorrect() + " \\ Missing: " + pTree.DirStatus.CountMissing() + " )"; + else if (pTree.Dat != null && pTree.DirDatCount == 0) // Directories made by a DAT + thistxt = pTree.Name + " ( Have:" + pTree.DirStatus.CountCorrect() + " \\ Missing: " + pTree.DirStatus.CountMissing() + " )"; + else + { + ReportError.SendAndShow("Unknown Tree settings in DisplayTree."); + thistxt = ""; + } + + + if (_lSelected != null && pTree.TreeFullName == _lSelected.TreeFullName) + { + g.FillRectangle(new SolidBrush(Color.FromArgb(51, 153, 255)), RSub(recBackGround, _hScroll, _vScroll)); + g.DrawString(thistxt, new Font("Microsoft Sans Serif", 8), Brushes.White, pTree.Tree.RText.Left - _hScroll, pTree.Tree.RText.Top + 1 - _vScroll); + } + else + { + g.DrawString(thistxt, new Font("Microsoft Sans Serif", 8), Brushes.Black, pTree.Tree.RText.Left - _hScroll, pTree.Tree.RText.Top + 1 - _vScroll); + } + } + + if (pTree.Tree.TreeExpanded) + for (int i = 0; i < pTree.ChildCount; i++) + { + RvBase tBase = pTree.Child(i); + if (tBase is RvDir) + { + RvDir tDir = (RvDir)tBase; + if (tDir.Tree != null) + PaintTree(tDir, g, t); + } + } + + } + + + private static Rectangle RSub(Rectangle r, int h, int v) + { + Rectangle ret = new Rectangle(r.Left - h, r.Top - v, r.Width, r.Height); + return ret; + } + #endregion + + #region"Mouse Events" + private bool _mousehit; + protected override void OnMouseDown(MouseEventArgs mevent) + { + int x = mevent.X + HorizontalScroll.Value; + int y = mevent.Y + VerticalScroll.Value; + + if (_lTree != null) + for (int i = 0; i < _lTree.ChildCount; i++) + { + RvDir tDir = (RvDir)_lTree.Child(i); + if (tDir.Tree != null) + if (CheckMouseDown(tDir, x, y, mevent)) + break; + } + + if (!_mousehit) return; + + SetupInt(); + base.OnMouseDown(mevent); + } + + public void SetSelected(RvDir selected) + { + bool found = false; + + RvDir t = selected; + while (t != null) + { + if (t.Tree != null) + { + if (!found) + { + _lSelected = t; + found = true; + } + else + t.Tree.TreeExpanded = true; + } + t = t.Parent; + } + SetupInt(); + } + + public RvDir GetSelected() + { + return _lSelected; + } + + private bool CheckMouseDown(RvDir pTree, int x, int y, MouseEventArgs mevent) + { + if (pTree.Tree.RChecked.Contains(x, y)) + { + if (pTree.Tree.Checked == RvTreeRow.TreeSelect.Disabled) + return true; + + _mousehit = true; + SetChecked(pTree, pTree.Tree.Checked == RvTreeRow.TreeSelect.Selected ? RvTreeRow.TreeSelect.UnSelected : RvTreeRow.TreeSelect.Selected); + return true; + } + + if (pTree.Tree.RExpand.Contains(x, y)) + { + _mousehit = true; + SetExpanded(pTree, mevent.Button == MouseButtons.Right); + return true; + } + + if (pTree.Tree.RText.Contains(x, y)) + { + _mousehit = true; + + if (RvSelected != null) + RvSelected(pTree, mevent); + + _lSelected = pTree; + return true; + } + + if (pTree.Tree.TreeExpanded) + for (int i = 0; i < pTree.ChildCount; i++) + { + RvBase rBase = pTree.Child(i); + if (rBase is RvDir) + { + RvDir rDir = (RvDir)rBase; + if (rDir.Tree != null) + if (CheckMouseDown(rDir, x, y, mevent)) + return true; + } + } + + return false; + } + + private static void SetChecked(RvDir pTree, RvTreeRow.TreeSelect nSelection) + { + pTree.Tree.Checked = nSelection; + for (int i = 0; i < pTree.ChildCount; i++) + { + RvBase b = pTree.Child(i); + if (b is RvDir) + { + RvDir d = (RvDir)b; + if (d.Tree != null) + { + SetChecked(d, nSelection); + } + } + } + } + + private static void SetExpanded(RvDir pTree, bool rightClick) + { + if (!rightClick) + { + pTree.Tree.TreeExpanded = !pTree.Tree.TreeExpanded; + return; + } + + // Find the value of the first child node. + for (int i = 0; i < pTree.ChildCount; i++) + { + RvBase b = pTree.Child(i); + if (b is RvDir) + { + RvDir d = (RvDir)b; + if (d.Tree != null) + { + //Recusivly Set All Child Nodes to this value + SetExpandedRecurse(pTree, !d.Tree.TreeExpanded); + break; + } + } + } + } + + private static void SetExpandedRecurse(RvDir pTree, bool expanded) + { + for (int i = 0; i < pTree.ChildCount; i++) + { + RvBase b = pTree.Child(i); + if (b is RvDir) + { + RvDir d = (RvDir)b; + if (d.Tree != null) + { + d.Tree.TreeExpanded = expanded; + SetExpandedRecurse(d, expanded); + } + } + } + } + #endregion + + public RvBase Selected + { + get + { + return _lSelected; + } + } + } + +} diff --git a/ROMVault2/rvTree.resx b/ROMVault2/rvTree.resx new file mode 100644 index 0000000..5ea0895 --- /dev/null +++ b/ROMVault2/rvTree.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/ROMVault2/rvTreeRow.cs b/ROMVault2/rvTreeRow.cs new file mode 100644 index 0000000..d1f3c9a --- /dev/null +++ b/ROMVault2/rvTreeRow.cs @@ -0,0 +1,99 @@ +/****************************************************** + * ROMVault2 is written by Gordon J. * + * Contact gordon@romvault.com * + * Copyright 2014 * + ******************************************************/ + +using System.Drawing; +using System.IO; + +namespace ROMVault2 +{ + public class RvTreeRow + { + public enum TreeSelect { UnSelected, Selected, Disabled } + + + public string TreeBranches; + private long _filePointer = -1; + private bool _pTreeExpanded; + private TreeSelect _pChecked; + + public Rectangle RTree; + public Rectangle RExpand; + public Rectangle RChecked; + public Rectangle RIcon; + public Rectangle RText; + + public RvTreeRow() + { + _pTreeExpanded = true; + _pChecked = TreeSelect.Selected; + } + + public void Write(BinaryWriter bw) + { + _filePointer = bw.BaseStream.Position; + bw.Write(_pTreeExpanded); + bw.Write((byte)_pChecked); + } + + public void Read(BinaryReader br) + { + _filePointer = br.BaseStream.Position; + _pTreeExpanded = br.ReadBoolean(); + _pChecked = (TreeSelect)br.ReadByte(); + } + + public bool TreeExpanded + { + get + { + return _pTreeExpanded; + } + set + { + if (_pTreeExpanded != value) + { + _pTreeExpanded = value; + CacheUpdate(); + } + } + } + + public TreeSelect Checked + { + get + { + return _pChecked; + } + set + { + if (_pChecked != value) + { + _pChecked = value; + CacheUpdate(); + } + } + } + + private void CacheUpdate() + { + if (_filePointer >= 0) + { + FileStream fs = new FileStream(Settings.CacheFile, FileMode.Open, FileAccess.Write); + BinaryWriter bw = new BinaryWriter(fs); + fs.Position = _filePointer; + bw.Write(_pTreeExpanded); + bw.Write((byte)_pChecked); + + bw.Flush(); + bw.Close(); + + fs.Close(); + fs.Dispose(); + } + } + } + +}