diff --git a/MyCBZ/App.config b/MyCBZ/App.config index 9a2f4d16..6d7f5d65 100644 --- a/MyCBZ/App.config +++ b/MyCBZ/App.config @@ -114,6 +114,12 @@ 0 + + False + + + False + diff --git a/MyCBZ/Data/AddImagesThreadParams.cs b/MyCBZ/Data/AddImagesThreadParams.cs index bffc73f3..c6ccb5d5 100644 --- a/MyCBZ/Data/AddImagesThreadParams.cs +++ b/MyCBZ/Data/AddImagesThreadParams.cs @@ -20,5 +20,7 @@ internal class AddImagesThreadParams : ThreadParam public string[] FilterExtensions { get; set; } = new string[0]; public int MaxCountPages { get; set; } = 0; + + public bool HashFiles { get; set; } = false; } } diff --git a/MyCBZ/Data/ParseFilesThreadParams.cs b/MyCBZ/Data/ParseFilesThreadParams.cs index 9fcf6d5e..c93d2569 100644 --- a/MyCBZ/Data/ParseFilesThreadParams.cs +++ b/MyCBZ/Data/ParseFilesThreadParams.cs @@ -22,6 +22,8 @@ internal class ParseFilesThreadParams : ThreadParam public MetaData.PageIndexVersion PageIndexVerToWrite { get; set; } = MetaData.PageIndexVersion.VERSION_1; + public bool HashFiles { get; set; } = false; + public bool ContinuePipeline { get; set; } } } diff --git a/MyCBZ/Forms/MainForm.cs b/MyCBZ/Forms/MainForm.cs index bf5f74c7..0cdbc245 100644 --- a/MyCBZ/Forms/MainForm.cs +++ b/MyCBZ/Forms/MainForm.cs @@ -4898,6 +4898,7 @@ private void SettingsToolStripMenuItem_Click(object sender, EventArgs e) Win_CBZSettings.Default.OmitEmptyXMLTags = settingsDialog.OmitEmptyXMLTags; Win_CBZSettings.Default.AutoDeleteTempFiles = settingsDialog.DeleteTempFilesImediately; Win_CBZSettings.Default.SkipIndexCheck = settingsDialog.SkipIndexCheck; + Win_CBZSettings.Default.CalculateHash = settingsDialog.CalculateCrc32; Win_CBZSettings.Default.CustomMetadataFields.Clear(); foreach (String line in settingsDialog.CustomFieldTypesCollection) diff --git a/MyCBZ/Forms/PageSettingsForm.cs b/MyCBZ/Forms/PageSettingsForm.cs index 99342fac..8109e92e 100644 --- a/MyCBZ/Forms/PageSettingsForm.cs +++ b/MyCBZ/Forms/PageSettingsForm.cs @@ -16,6 +16,7 @@ using System.Drawing.Imaging; using System.Runtime.Versioning; using System.Threading; +using Win_CBZ.Hash; namespace Win_CBZ.Forms { @@ -345,6 +346,11 @@ private void ButtonReloadImage_Click(object sender, EventArgs e) { Invoke(new Action(() => { + if (Win_CBZ.Win_CBZSettings.Default.CalculateHash) + { + HashCrc32.Calculate(ref FirstPage); + } + ImagePreviewButton.BackgroundImage = Image.FromHbitmap(t.Result.GetHbitmap()); LabelDimensions.Text = FirstPage.Format.W.ToString() + " x " + FirstPage.Format.H.ToString() + " px"; diff --git a/MyCBZ/Forms/SettingsDialog.Designer.cs b/MyCBZ/Forms/SettingsDialog.Designer.cs index cd0176fc..b150bdaa 100644 --- a/MyCBZ/Forms/SettingsDialog.Designer.cs +++ b/MyCBZ/Forms/SettingsDialog.Designer.cs @@ -49,10 +49,14 @@ private void InitializeComponent() RestoreFieldTypesButton = new System.Windows.Forms.Button(); tabPage5 = new System.Windows.Forms.TabPage(); tableLayoutPanel4 = new System.Windows.Forms.TableLayoutPanel(); + pictureBox3 = new System.Windows.Forms.PictureBox(); CheckBoxSkipIndexCheck = new System.Windows.Forms.CheckBox(); label9 = new System.Windows.Forms.Label(); label7 = new System.Windows.Forms.Label(); CheckBoxDeleteTempFiles = new System.Windows.Forms.CheckBox(); + label8 = new System.Windows.Forms.Label(); + CheckBoxCalculateCrc = new System.Windows.Forms.CheckBox(); + pictureBox4 = new System.Windows.Forms.PictureBox(); CBZSettingsTabControl = new System.Windows.Forms.TabControl(); tabPage2 = new System.Windows.Forms.TabPage(); tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel(); @@ -104,6 +108,8 @@ private void InitializeComponent() ((System.ComponentModel.ISupportInitialize)CustomFieldsDataGrid).BeginInit(); tabPage5.SuspendLayout(); tableLayoutPanel4.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)pictureBox3).BeginInit(); + ((System.ComponentModel.ISupportInitialize)pictureBox4).BeginInit(); CBZSettingsTabControl.SuspendLayout(); tabPage2.SuspendLayout(); tableLayoutPanel2.SuspendLayout(); @@ -238,11 +244,11 @@ private void InitializeComponent() // AppSettingsTabControl.Controls.Add(TabPageAppSettings); AppSettingsTabControl.Controls.Add(tabPage5); - AppSettingsTabControl.Location = new System.Drawing.Point(271, 2); + AppSettingsTabControl.Location = new System.Drawing.Point(275, 2); AppSettingsTabControl.Margin = new System.Windows.Forms.Padding(3, 5, 3, 5); AppSettingsTabControl.Name = "AppSettingsTabControl"; AppSettingsTabControl.SelectedIndex = 0; - AppSettingsTabControl.Size = new System.Drawing.Size(147, 460); + AppSettingsTabControl.Size = new System.Drawing.Size(144, 460); AppSettingsTabControl.TabIndex = 3; // // TabPageAppSettings @@ -252,7 +258,7 @@ private void InitializeComponent() TabPageAppSettings.Margin = new System.Windows.Forms.Padding(3, 5, 3, 5); TabPageAppSettings.Name = "TabPageAppSettings"; TabPageAppSettings.Padding = new System.Windows.Forms.Padding(3, 5, 3, 5); - TabPageAppSettings.Size = new System.Drawing.Size(139, 427); + TabPageAppSettings.Size = new System.Drawing.Size(136, 427); TabPageAppSettings.TabIndex = 0; TabPageAppSettings.Text = "Metadata Editor"; TabPageAppSettings.UseVisualStyleBackColor = true; @@ -275,7 +281,7 @@ private void InitializeComponent() CustomFieldTypesTablePanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 49F)); CustomFieldTypesTablePanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); CustomFieldTypesTablePanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 54F)); - CustomFieldTypesTablePanel.Size = new System.Drawing.Size(133, 417); + CustomFieldTypesTablePanel.Size = new System.Drawing.Size(130, 417); CustomFieldTypesTablePanel.TabIndex = 1; // // CustomFieldsDataGrid @@ -299,7 +305,7 @@ private void InitializeComponent() CustomFieldsDataGrid.Name = "CustomFieldsDataGrid"; CustomFieldsDataGrid.RowHeadersWidth = 51; CustomFieldsDataGrid.RowTemplate.Height = 24; - CustomFieldsDataGrid.Size = new System.Drawing.Size(127, 304); + CustomFieldsDataGrid.Size = new System.Drawing.Size(124, 304); CustomFieldsDataGrid.TabIndex = 0; CustomFieldsDataGrid.CellContentClick += CustomFieldsDataGrid_CellContentClick; CustomFieldsDataGrid.CellValueChanged += CustomFieldsDataGrid_CellValueChanged; @@ -315,7 +321,7 @@ private void InitializeComponent() AddFieldTypeButton.Location = new System.Drawing.Point(3, 371); AddFieldTypeButton.Margin = new System.Windows.Forms.Padding(3, 8, 3, 4); AddFieldTypeButton.Name = "AddFieldTypeButton"; - AddFieldTypeButton.Size = new System.Drawing.Size(32, 42); + AddFieldTypeButton.Size = new System.Drawing.Size(31, 42); AddFieldTypeButton.TabIndex = 1; AddFieldTypeButton.Text = "Add"; AddFieldTypeButton.UseVisualStyleBackColor = true; @@ -336,10 +342,10 @@ private void InitializeComponent() RemoveFieldTypeButton.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft; RemoveFieldTypeButton.ImageIndex = 1; RemoveFieldTypeButton.ImageList = DialogImages; - RemoveFieldTypeButton.Location = new System.Drawing.Point(41, 371); + RemoveFieldTypeButton.Location = new System.Drawing.Point(40, 371); RemoveFieldTypeButton.Margin = new System.Windows.Forms.Padding(3, 8, 3, 4); RemoveFieldTypeButton.Name = "RemoveFieldTypeButton"; - RemoveFieldTypeButton.Size = new System.Drawing.Size(32, 42); + RemoveFieldTypeButton.Size = new System.Drawing.Size(31, 42); RemoveFieldTypeButton.TabIndex = 2; RemoveFieldTypeButton.Text = "Remove"; RemoveFieldTypeButton.UseVisualStyleBackColor = true; @@ -348,7 +354,7 @@ private void InitializeComponent() // RestoreFieldTypesButton // RestoreFieldTypesButton.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right; - RestoreFieldTypesButton.Location = new System.Drawing.Point(96, 371); + RestoreFieldTypesButton.Location = new System.Drawing.Point(93, 371); RestoreFieldTypesButton.Margin = new System.Windows.Forms.Padding(3, 8, 3, 4); RestoreFieldTypesButton.Name = "RestoreFieldTypesButton"; RestoreFieldTypesButton.Size = new System.Drawing.Size(34, 42); @@ -364,7 +370,7 @@ private void InitializeComponent() tabPage5.Margin = new System.Windows.Forms.Padding(2); tabPage5.Name = "tabPage5"; tabPage5.Padding = new System.Windows.Forms.Padding(2); - tabPage5.Size = new System.Drawing.Size(139, 427); + tabPage5.Size = new System.Drawing.Size(136, 427); tabPage5.TabIndex = 2; tabPage5.Text = "Behaviour"; tabPage5.UseVisualStyleBackColor = true; @@ -373,24 +379,44 @@ private void InitializeComponent() // tableLayoutPanel4.ColumnCount = 3; tableLayoutPanel4.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 153F)); - tableLayoutPanel4.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); - tableLayoutPanel4.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 7F)); + tableLayoutPanel4.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 85.7816849F)); + tableLayoutPanel4.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 14.2183151F)); + tableLayoutPanel4.Controls.Add(pictureBox3, 2, 0); tableLayoutPanel4.Controls.Add(CheckBoxSkipIndexCheck, 1, 0); tableLayoutPanel4.Controls.Add(label9, 0, 0); tableLayoutPanel4.Controls.Add(label7, 0, 1); tableLayoutPanel4.Controls.Add(CheckBoxDeleteTempFiles, 1, 1); + tableLayoutPanel4.Controls.Add(label8, 0, 2); + tableLayoutPanel4.Controls.Add(CheckBoxCalculateCrc, 1, 2); + tableLayoutPanel4.Controls.Add(pictureBox4, 2, 2); tableLayoutPanel4.Dock = System.Windows.Forms.DockStyle.Fill; tableLayoutPanel4.Location = new System.Drawing.Point(2, 2); tableLayoutPanel4.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); tableLayoutPanel4.Name = "tableLayoutPanel4"; - tableLayoutPanel4.RowCount = 4; - tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 60.60606F)); + tableLayoutPanel4.RowCount = 6; tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 59F)); tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 59F)); - tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 248F)); - tableLayoutPanel4.Size = new System.Drawing.Size(135, 423); + tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 59F)); + tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 59F)); + tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 59F)); + tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F)); + tableLayoutPanel4.Size = new System.Drawing.Size(132, 423); tableLayoutPanel4.TabIndex = 2; // + // pictureBox3 + // + pictureBox3.Image = Properties.Resources.information; + pictureBox3.InitialImage = Properties.Resources.information; + pictureBox3.Location = new System.Drawing.Point(135, 0); + pictureBox3.Margin = new System.Windows.Forms.Padding(0); + pictureBox3.Name = "pictureBox3"; + pictureBox3.Padding = new System.Windows.Forms.Padding(7, 20, 7, 8); + pictureBox3.Size = new System.Drawing.Size(1, 52); + pictureBox3.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize; + pictureBox3.TabIndex = 14; + pictureBox3.TabStop = false; + TagValidationTooltip.SetToolTip(pictureBox3, "By default, when opening a cbz-archive, all files and info from the\r\nComicInfo.xml -Pageindex is verified with actual image data.\r\nBy enabling this, opening archives will be significatly faster."); + // // CheckBoxSkipIndexCheck // CheckBoxSkipIndexCheck.AutoSize = true; @@ -408,14 +434,14 @@ private void InitializeComponent() label9.Location = new System.Drawing.Point(18, 20); label9.Margin = new System.Windows.Forms.Padding(18, 20, 18, 20); label9.Name = "label9"; - label9.Size = new System.Drawing.Size(45, 17); + label9.Size = new System.Drawing.Size(45, 19); label9.TabIndex = 9; label9.Text = "Index"; // // label7 // label7.AutoSize = true; - label7.Location = new System.Drawing.Point(18, 77); + label7.Location = new System.Drawing.Point(18, 79); label7.Margin = new System.Windows.Forms.Padding(18, 20, 3, 0); label7.Name = "label7"; label7.Size = new System.Drawing.Size(113, 20); @@ -425,7 +451,7 @@ private void InitializeComponent() // CheckBoxDeleteTempFiles // CheckBoxDeleteTempFiles.AutoSize = true; - CheckBoxDeleteTempFiles.Location = new System.Drawing.Point(162, 77); + CheckBoxDeleteTempFiles.Location = new System.Drawing.Point(162, 79); CheckBoxDeleteTempFiles.Margin = new System.Windows.Forms.Padding(9, 20, 3, 4); CheckBoxDeleteTempFiles.Name = "CheckBoxDeleteTempFiles"; CheckBoxDeleteTempFiles.Size = new System.Drawing.Size(1, 24); @@ -433,6 +459,41 @@ private void InitializeComponent() CheckBoxDeleteTempFiles.Text = "Delete Immediately"; CheckBoxDeleteTempFiles.UseVisualStyleBackColor = true; // + // label8 + // + label8.AutoSize = true; + label8.Location = new System.Drawing.Point(18, 138); + label8.Margin = new System.Windows.Forms.Padding(18, 20, 3, 0); + label8.Name = "label8"; + label8.Size = new System.Drawing.Size(63, 20); + label8.TabIndex = 12; + label8.Text = "Hashing"; + // + // CheckBoxCalculateCrc + // + CheckBoxCalculateCrc.AutoSize = true; + CheckBoxCalculateCrc.Location = new System.Drawing.Point(162, 138); + CheckBoxCalculateCrc.Margin = new System.Windows.Forms.Padding(9, 20, 3, 3); + CheckBoxCalculateCrc.Name = "CheckBoxCalculateCrc"; + CheckBoxCalculateCrc.Size = new System.Drawing.Size(1, 24); + CheckBoxCalculateCrc.TabIndex = 13; + CheckBoxCalculateCrc.Text = "Calculate crc32 for new pages"; + CheckBoxCalculateCrc.UseVisualStyleBackColor = true; + // + // pictureBox4 + // + pictureBox4.Image = Properties.Resources.information; + pictureBox4.InitialImage = Properties.Resources.information; + pictureBox4.Location = new System.Drawing.Point(135, 118); + pictureBox4.Margin = new System.Windows.Forms.Padding(0); + pictureBox4.Name = "pictureBox4"; + pictureBox4.Padding = new System.Windows.Forms.Padding(7, 20, 7, 8); + pictureBox4.Size = new System.Drawing.Size(1, 52); + pictureBox4.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize; + pictureBox4.TabIndex = 15; + pictureBox4.TabStop = false; + TagValidationTooltip.SetToolTip(pictureBox4, "Caldulates a hash for every newly added page. \r\nThis is helpful when identifying duplicate pages, but slows down\r\nadding new images significantly!"); + // // CBZSettingsTabControl // CBZSettingsTabControl.Controls.Add(tabPage2); @@ -982,6 +1043,8 @@ private void InitializeComponent() tabPage5.ResumeLayout(false); tableLayoutPanel4.ResumeLayout(false); tableLayoutPanel4.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)pictureBox3).EndInit(); + ((System.ComponentModel.ISupportInitialize)pictureBox4).EndInit(); CBZSettingsTabControl.ResumeLayout(false); tabPage2.ResumeLayout(false); tableLayoutPanel2.ResumeLayout(false); @@ -1074,5 +1137,9 @@ private void InitializeComponent() private System.Windows.Forms.Label label7; private System.Windows.Forms.CheckBox CheckBoxDeleteTempFiles; private System.Windows.Forms.ImageList AutocompleteIcons; + private System.Windows.Forms.Label label8; + private System.Windows.Forms.CheckBox CheckBoxCalculateCrc; + private System.Windows.Forms.PictureBox pictureBox3; + private System.Windows.Forms.PictureBox pictureBox4; } } \ No newline at end of file diff --git a/MyCBZ/Forms/SettingsDialog.cs b/MyCBZ/Forms/SettingsDialog.cs index d1323ed3..66437678 100644 --- a/MyCBZ/Forms/SettingsDialog.cs +++ b/MyCBZ/Forms/SettingsDialog.cs @@ -53,6 +53,8 @@ internal partial class SettingsDialog : Form public bool SkipIndexCheck; + public bool CalculateCrc32; + DataValidation validation; public SettingsDialog() @@ -87,6 +89,8 @@ public SettingsDialog() SkipIndexCheck = Win_CBZSettings.Default.SkipIndexCheck; + CalculateCrc32 = Win_CBZSettings.Default.CalculateHash; + //CustomFieldTypesCollection = Win_CBZSettings.Default.CustomMetadataFields.OfType().ToArray(); CustomFieldTypesSettings = MetaDataFieldConfig.GetInstance().GetAllTypes(); @@ -106,6 +110,7 @@ public SettingsDialog() CheckBoxPruneEmplyTags.Checked = OmitEmptyXMLTags; CheckBoxSkipIndexCheck.Checked = SkipIndexCheck; + CheckBoxCalculateCrc.Checked = CalculateCrc32; ComboBoxFileName.Text = MetaDataFilename; @@ -422,6 +427,7 @@ private void SettingsDialog_FormClosing(object sender, FormClosingEventArgs e) OmitEmptyXMLTags = CheckBoxPruneEmplyTags.Checked; DeleteTempFilesImediately = CheckBoxDeleteTempFiles.Checked; SkipIndexCheck = CheckBoxSkipIndexCheck.Checked; + CalculateCrc32 = CheckBoxCalculateCrc.Checked; List fieldConfigItems = new List(); foreach (MetaDataFieldType fieldTypeCnf in CustomFieldTypesSettings) { diff --git a/MyCBZ/Forms/SettingsDialog.resx b/MyCBZ/Forms/SettingsDialog.resx index cbfd5faa..e4e82d30 100644 --- a/MyCBZ/Forms/SettingsDialog.resx +++ b/MyCBZ/Forms/SettingsDialog.resx @@ -125,7 +125,7 @@ AAEAAAD/////AQAAAAAAAAAMAgAAAEZTeXN0ZW0uV2luZG93cy5Gb3JtcywgQ3VsdHVyZT1uZXV0cmFs LCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5BQEAAAAmU3lzdGVtLldpbmRvd3MuRm9ybXMu SW1hZ2VMaXN0U3RyZWFtZXIBAAAABERhdGEHAgIAAAAJAwAAAA8DAAAAoAIAAAJNU0Z0AUkBTAIBAQIB - AAEwAQMBMAEDARABAAEQAQAE/wEZAQAI/wFCAU0BNgcAATYDAAEoAwABQAMAARADAAEBAQABGAYAAQz/ + AAFYAQMBWAEDARABAAEQAQAE/wEZAQAI/wFCAU0BNgcAATYDAAEoAwABQAMAARADAAEBAQABGAYAAQz/ AAwAA+cBUgFUAVUD+g8AA7gBtgK4ewAD9gO+A70D4BgAA+YDUAMlA30D+gYAA/0DtAMrAyUDungAAdEC 0gYlAYoCixUAA+cMJQNGA/oDAAO0DCUBtgK4dQAB0QLSBiUBigKLFQAD6AM1DCUDfQO0AysJJQMrA7h1 AAHRAtIGJQGKAosYAAPzAzUbJQO0bwADlAGKAosBigKLAWYCZwYlA0cBigKLAYoCiwGKAosD4A8AA+AD @@ -338,154 +338,154 @@ VERSION_2 = <Image="[FileName]" Key="[UniqueID]" ...> AAEAAAD/////AQAAAAAAAAAMAgAAAEZTeXN0ZW0uV2luZG93cy5Gb3JtcywgQ3VsdHVyZT1uZXV0cmFs LCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5BQEAAAAmU3lzdGVtLldpbmRvd3MuRm9ybXMu - SW1hZ2VMaXN0U3RyZWFtZXIBAAAABERhdGEHAgIAAAAJAwAAAA8DAAAAYiIAAAJNU0Z0AUkBTAIBAQ0B - AAGgAQEBoAEBARABAAEQAQAE/wEhAQAI/wFCAU0BNgcAATYDAAEoAwABQAMAAUADAAEBAQABIAYAAUD/ + SW1hZ2VMaXN0U3RyZWFtZXIBAAAABERhdGEHAgIAAAAJAwAAAA8DAAAAXCIAAAJNU0Z0AUkBTAIBAQ0B + AAHIAQEByAEBARABAAEQAQAE/wEhAQAI/wFCAU0BNgcAATYDAAEoAwABQAMAAUADAAEBAQABIAYAAUD/ ABsAA0wBkAMlAf8DYgHhCAADJAE0AyUB/wMlAf8DKgE/3AADMgFPAyUB/wMlAf8DGgEkBAAEAgNZAe8D JQH/A0YBgNgAAxABFQMbASYDQAH9AyUB/wNAAW8DEAEVAxABFQNYAboDJQH/A1oBxAMQARUDDwET0AAD XAHZAyUB/wMlAf8DJQH/AyUB/wMlAf8DJQH/AyUB/wMlAf8DJQH/AyUB/wMrAfwDDgESzAADTgGXAyUB /wMlAf8DJQH/AyUB/wMlAf8DJQH/AyUB/wMlAf8DJQH/AyUB/wMlAf8DMwFRzAADFAEbAyoBPwNAAXED - JQH/AyUB/wM7AWQDKgE/AyoBPwNhAesDJQH/A1MBqgMqAT8DFgEe1AADCgENAkoBSwH6AyUB/wM+AWoI - AANUAasDJQH/A1kBxuAAA1kBxgMlAf8DVAGrCAADPgFqAyUB/wJKAUsB+gMKAQ3UAAMWAR4DKgE/A1MB - qgMlAf8DYQHrAyoBPwMqAT8DOwFkAyUB/wMlAf8DQAFxAyoBPwMUARvMAAMzAVEDJQH/AyUB/wMlAf8D - JQH/AyUB/wMlAf8DJQH/AyUB/wMlAf8DJQH/AyUB/wNOAZfMAAMOARIDKwH8AyUB/wMlAf8DJQH/AyUB - /wMlAf8DJQH/AyUB/wMlAf8DJQH/AyUB/wNcAdnQAAMPARMDEAEVA1oBxAMlAf8DWAG6AxABFQMQARUD - QAFvAyUB/wNAAf0DGwEmAxABFdgAA0YBgAMlAf8DWQHvBAIEAAMaASQDJQH/AyUB/wMyAU/cAAMqAT8D - JQH/AyUB/wMkATQIAANiAeEDJQH/A0wBkP8A/wDeAAMYASEDUAGcA1oB8gNQAZwDGAEhOAADOAFdAzAB - SgMEAQUkAAMTARoDSQGIA10B1ANBAfkDQQH5A10B1ANJAYgDEwEaIAADEwEaA0kBiANdAdQDQQH5A0EB - +QNdAdQDSQGIAxMBGhwAAxgBIANPAZkDWgHyA1EBogMlAf8DUQGiA1oB8gNPAZkDGAEgMAADOgFiA00B - +gNdAdwDJAE0HAADNwFaA2IB7gNLAY0DIwEyAwYBBwMGAQcDIwEyA0sBjQNdAeoDNwFaGAADNwFaA2AB - 8wNNAfoDWAG3A0kBhwNJAYcDWAG3A00B+gNgAfMDNwFaEAADFQEcA04BlgNaAfIDUQGeAxoBIwMIAQoD - JQH/AwgBCgMaASMDUQGeA1oB8gNOAZYDFQEcKAADQgF0A1MBqgMzAVEDYAHoAxcBHxQAAzcBWgNbAeQD - XQHOAwMBBBAAAzQBUwM2AVcDYAHgAzcBWhAAAzcBWgNEAf4DWgG/AxgBIRAAAxgBIQNaAb8DRAH+AzcB - WgwAA18B5QNRAaQDGwElCAADCAEKAyUB/wMIAQoIAAMbASUDUQGkA18B5RgAAysBQQNRAaEDXgHdA00B - +gNfAdUDHQEoBAADRgF+A1ABnBAAAxMBGgNdAeoDPQFnAyUB/wNaAb8DBAEFDAADXAHWAyYB+wMoATsD - XQHqAxMBGggAAxMBGgNgAfMDWgG/AwUBBhgAAwUBBgNaAb8DYAHzAxMBGggAAyUB/wMQARUMAAMIAQoD - JQH/AwgBCgwAAxABFQMlAf8QAAMOARIDVgGzA1sB2AM/AW0DHQEoAwUBBgwAAxUBHANhAesDDwETDAAD - SQGIA0IBdANXAcIDJQH/AyUB/wMlATcMAANeAe0DJQH/A0QBeANLAY0DSQGICAADSQGIA00B+gMYASEg - AAMYASEDTQH6A0kBiAgAAyUB/wMQARUMAAMIAQoDJQH/AwgBCgwAAxABFQMlAf8MAAMIAQoDXQHPA0oB - iwMEAQUcAANHAYIDXQHPAwgBCggAA10B1AM6AWIDJQH/A0AB/QNLAYwDBgEHBAADCwEOAyYBOQMlAf8D - JQH/A1oBxwMdASgDXQHUCAADXQHUA1gBtygAA1gBtwNdAdQIAAMlAf8DEAEVBAADFwEfAxEBFgMIAQoD - JQH/AwgBCgwAAxABFQMlAf8MAANHAYIDUgGjCQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8B - AAHSAfoB/wEAAdIB+gH/CAADUwGmA0cBgggAA0EB+QNMAZEDXgHwAzsBZAgAAxYBHgNlAfEDJQH/AyUB - /wMlAf8DJQH/AysEQQH5CAADQQH5A0kBhxEAAdIB+gH/AQAB0gH6Af8QAANJAYcDQQH5CAADJQH/AxAB - FQNYAbgBPgK+Af0DIQEvA0sBjwMlAf8DSwGPAxIBGAgAAxABFQMlAf8MAANdAd8DHgEqKAADHgEqA10B - 3wgAA0EB+QNbAcoDCwEODAADMwFSAyUB/wMlAf8DJQH/AyUB/wMlAf8DPgFrA0EB+QgAA0EB+QNJAYcM - AAMEAQUBSAFrAXIB9gFIAWsBcgH2AVwCYQHZAzMBUggAA0kBhwNBAfkIAAMlAf8DEAEVAVMBaAFrAfQB - AAHSAfoB/wFAAkEBcQNFAXwDLgFIA1IBqANeAfADSgGLAxEBFgMQARUDJQH/DAADQAH9AwIBAwkAAdIB - +gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wgAAwIBAwNAAf0IAANdAdQD - WQHvAxoBIwwAAxYBHQNgAfMDJQH/A1EB9wNbAeQDSAH2A0QB/gNdAdQIAANdAdQDWAG3DAADSwGNAVoC - XAHEAyUBNwNFAXwDYgHuAzUBVQQAA1gBtwNdAdQIAAMlAf8DOgFgAVsCXQHKAQAB0gH6Af8BAAHSAfoB - /wFbAmEB3gM0AVMEAgMgAS4DVAGrA14B8ANOAZcDJQH/DAADXQHfAx4BKigAAx4BKgNdAd8IAANJAYgD - JQH/A10B3wMeASoMAAM3AVoDUQGhAzABSgNLAY0DYgHuAyUB/wNJAYgIAANJAYgDTQH6AxgBIQQAAxEB - FgNiAe4DHAEnCAADCQELAxABFQMYASEDTQH6A0kBiAgAA18B5QNbAcUDGwEmAUoCSwGKAV4CZQHiASAB - kgG5Af4BIAGSAbkB/gFeAmUB3QMzAVAEAQM0AVMDTQH6A18B5QwAA0cBggNSAaUJAAHSAfoB/wEAAdIB - +gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8IAANSAaUDRwGCCAADEwEaA2AB8wMlAf8D - RAH+AzEBTggAAzYBWANaAb8DWgHyAyUB/wMlAf8DYAHzAxMBGggAAxMBGgNgAfMDWgG/AwUBBgFbAl0B - ygNLAY0QAAMFAQYDWgG/A2AB8wMTARoIAAMVARwDRAF4A1oB8gNGAX4DFwEfAzgBWwFgAmUB4wEfAZQB - vAH+AQAB0gH6Af8BYAJkAdsBOgI7AWIDQwF2AxUBHAwAAwgBCgNdAc8DSwGNAwQBBRgAAwQBBQNLAY0D - XQHPAwgBCgwAAzcBWgNEAf4DJQH/AysBQgNTAakDTgGYAycBOgMjATMDXgHSA0oBiwMrAfwDNwFaEAAD - NwFaA0QB/gNaAb8BQAJBAXADDAEPDAADGAEhA1oBvwNEAf4DNwFaFAADGAEgA0QBegNaAfIDRQF8Ax0B - KAFPAlABmwFbAmEB3gNVAawDEAEVGAADDgESA1YBswNeAdcDPgFrAxsBJgMEAQUDBAEFAxsBJgM+AWsD - XgHXA1YBswMOARIUAAM3AVoDYAHzA10B1ANZAe8DJQH/A1cBuQMYASADQAFxA10B6gM3AVoYAAM3AVoD - YAHzA00B+gNYAbcDSQGHA0kBhwNYAbcDTQH6A2AB8wM3AVogAAMYASEDRgF9A1oB8gNLAY0EAigAAysB - QQNRAaEDXgHdA00B+gNNAfoDXgHdA1EBoQMrAUEgAAMTARoDSQGIA10B1ANBAfkDQQH5A10B1ANJAYgD - EwEaIAADEwEaA0kBiANdAdQDQQH5A0EB+QNdAdQDSQGIAxMBGv8A/wAeAAMzAVADWgHpAyUB/wMlAf8D - JQH/AyUB/wMlAf8DXAHIGAADMQFNA1UBtANbAeQDJgH7AyYB+wNbAeQDVQG0AzEBTSQAAzMBUANaAekD - JQH/BQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8B - WQJcAcFUAANaAekDJQH/AyUB/wMlAf8DJQH/AyUB/wMlAf8DJQH/GAADQQH5AyUB/wMlAf8DJQH/AyUB - /wMlAf8DJQH/A0EB+SQAA1oB6QMlAf8DJQH/BQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8B - AAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/zAAAxcBHwNJAYcDXAHWA1oB+ANTAaoQAAMlAf8D - JQH/AyUB/wMlAf8DJQH/AyUB/wMlAf8DJQH/GAADYAHgAyUB/wMlAf8DJQH/AyUB/wMlAf8DJQH/A2AB - 4CQAAyUB/wMlAf8DJQH/BQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB - +gH/AQAB0gH6Af8BAAHSAfoB/yQAAwkEDAEPA00BkwNNAfoDJQH/AyUB/wMlAf8DYAHzEAADJQH/AyUB - /wMlAf8DJQH/AyUB/wMlAf8DJQH/AyUB/wMzAVIBAAHSAfoB/wFcAl8ByAwAAzwBZgNbAcoDRAF6Ay4B - SAMwAUsDRAF6A1sBygM8AWYkAAMlAf8DJQH/AyUB/wUAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB - +gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8cAAE7AjwBZQNVAa8DNgFYA1wB5wNgAeAD - PgFqAzoEYAHoAyUB/wNVAa4QAAMlAf8DJQH/AyUB/wMlAf8DJQH/AyUB/wMlAf8DJQH/AzMBUgEAAdIB - +gH/AQAB0gH6Af8QAAMXAR8DNgFXA1oBxANaAcQDOQFeAxgBIAMbASYBTAJNAZEBIQGHAZAB+wEhAYcB - kAH7AVsCYwHkAVUCVwG0AzEBTQwAAyUB/wMlAf8DJQH/BQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB - 0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/xgAASYCJwE5AVUCVgGuA0QBegNaAfUD - OQFfAz0BZwFgAmkB6AMgAS4DVwG5AyYB+wMhATAQAAMlAf8DJQH/AyUB/wMlAf8DJQH/AyUB/wMlAf8D - JQH/AzMBUgEAAdIB+gH/AQAB0gH6Af8QAAM9AWkDSgH+AyUB/wMlAf8DSgH+Az0BaQMZASIBAAHSAfoB - /wEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AUEBewGEAfkMAAMlAf8DJQH/AyUB/wUAAdIB - +gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8Y - AAMyAU8DQgF1A2AB2wM1AVYBXgJlAeIBAAHSAfoB/wEAAdIB+gH/AVACUQGdA0wBkQNGAYAUAAMlAf8D - JQH/AyUB/wMlAf8DJQH/AyUB/wMlAf8DJQH/AzMBUgEAAdIB+gH/AQAB0gH6Af8QAANhAeYDJQH/AyUB - /wMlAf8DJQH/A2EB5gMeASoBAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AWAC - ZgHgDAADJQH/AyUB/wMlAf8FAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB - 0gH6Af8BAAHSAfoB/wEAAdIB+gH/FAADBwEJA0oBigNdAc8DOgFgATMBfQGMAfoBAAHSAfoB/wEAAdIB - +gH/AQAB0gH6Af8BKwGJAaMB/AMpAT0EAhQAAyUB/wMlAf8DJQH/AyUB/wMlAf8DJQH/AyUB/wNcAcgD - MwFSAQAB0gH6Af8BAAHSAfoB/xAAA1oB9QMlAf8DJQH/AyUB/wMlAf8DWgH1AysBQgNEAXoDLgFIAzAB - SwNEAXoBWwJdAcoDPAFmDAADJQH/AyUB/wMlAf8FAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB - /wEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/EAAEAgNLAY8DYAHgAzUBVgEfAZUBvQH+AQAB - 0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8BKwGJAaMB/AMEAQUYAAMlAf8DJQE3FAADOwFlAzMB - UgEAAdIB+gH/AQAB0gH6Af8QAANRAZ4DJQH/AyUB/wMlAf8DJQH/A1EBngMXAR8DNgFXAVoCXAHEAVoC - XAHEAzkBXgMYASAQAAMlAf8DJQH/AyUB/wUAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB - 0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8QAANBAXMDJQH/AzYBWAFgAmYB4AEAAdIB+gH/AQAB - 0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8BWQJcAcEcAANaAekDJQE3EAADCwEOAyUB/wMzAVIB - AAHSAfoB/wEAAdIB+gH/EAADCAEKA04BmANlAfEDZQHxA04BmAMIAQoDNAFUASUBiQGxAf4BAAHSAfoB - /wEAAdIB+gH/ASUBiQGxAf4BPQI+AWkQAAMlAf8DJQH/AyUB/wUAAdIB+gH/AQAB0gH6Af8BAAHSAfoB - /wEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8MAAMcAScDJgH7A10BzgMbASUB - QQGDAYoB+QEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AUEBgwGKAfkBJgInATkcAAMzAVAD - WgHpAyUB/wMlAf8DJQH/AyUB/wMlAf8DWwHKA0YBfgEAAdIB+gH/AVwCXwHIKAABYQJqAeYBAAHSAfoB - /wEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wFhAmoB5hAAAyUB/wMlAf8DJQH/BAABJAGLAbMB/gEkAYsB - swH+ASQBiwGzAf4BJAGLAbMB/gEkAYsBswH+AQAB0gH6Af8BAAHSAfoB/wFGAkcBgAwAA1UBrgMlAf8D - YAHoAzoBYAMwAUsBWAJaAb0BAAHSAfoB/wEAAdIB+gH/A14B0gMqAT8sAAM8AWYDBQEGFAADRgF+KAAB - WgJuAfUBAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wFaAm4B9RAAAyUB/wMlATc0AANgAfMD - JQH/AyUB/wMlAf8DWgHyAygBPAMRARYDEQEWNAABWgJjAekDJQE3EAADCwEOAQAB0gH6Af8oAANRAZ4B - AAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wNRAZ4QAANaAekDJQE3IAADCwEOAQAB0gH6Af8M - AANTAaoDWgH4A1wB1gNJAYcDFwEfQAADMwFQAVoCYwHpAQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB - 0gH6Af8BAAHSAfoB/wFbAl0ByigAAwgBCgNOAZgBZQJwAfEBZQJwAfEDTgGYAwgBChAAAzMBUANaAekD - JQH/BQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8B - UQJTAaL/AP8AYgADFwEfAyUB/wMlAf8DCAEKJAADHQEpAz8BbgMGAQgQAAMGAQgDPwFuAx0BKRgAAxMB - GQNHAYIDWQHDA1oB6QMrAfwDKwH8A1oB6QNZAcMDRgGBAxMBGWAAAxcBHwMlAf8DPAFmA04BlwMlAf8D - CAEKIAADUgGoAyUB/wNbAdADHQEoCAADHQEoA1sB0AMlAf8DUgGoGAADWwHkAyUB/wMlAf8DJQH/AyUB - /wMlAf8DJQH/AyUB/wMlAf8DWwHkXAADFgEeAyUB/wM7AWUEAAQBA04BlwMlAf8DCAEKHAADPwFsAyUB - /wMlAf8DUwH0AzsBYwM7AWMDUwH0AyUB/wMlAf8DPwFsGAADUQH3AyUB/wMlAf8DJQH/AyUB/wMlAf8D - JQH/AyUB/wMlAf8DUQH3EAABXAJfAcgBAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB - +gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8B - XAJfAcgQAAMWAR4DJQH/AzwBZgwABAEDTgGXAyUB/wMIAQoYAAMUARsDQAH9AyUB/wMlAf8DJQH/AyUB - /wMlAf8DJQH/A0AB/QMUARsYAANbAc0DJQH/AyUB/wMlAf8DJQH/AyUB/wMlAf8DJQH/AyUB/wNbAc0R - AAHSAfoB/zEAAdIB+gH/DAADFgEeAyUB/wM8AWYUAAQBA04BmAMlAf8cAANZAcYDJQH/AyUB/wMlAf8D - JQH/AyUB/wMlAf8DWQHGHAADNQFWA1QB/gMlAf8DYQHmA10BzwNdAc8DYQHmAyUB/wNUAf4DNQFWEQAB - 0gH6Af8EAAMlAf8EAAMlAf8DPAFmAyUB/wMlAf8EAAMlAf8DPAFmAyUB/wUAAdIB+gH/CAADFgEeAyUB - /wM8AWYcAAM2AVkDJQH/BAEUAAQBA1QBqwMlAf8DJQH/AyUB/wMlAf8DJQH/AyUB/wNUAasEARwAAzAB - TAMqAT8DGwElAw0BEQMNAREDHQEpAyoBPwMwAUwVAAHSAfoB/wQAAyUB/wQAAyUB/wM8AWYDJQH/AyUB - /wQAAyUB/wM8AWYDJQH/BQAB0gH6Af8IAAMlAf8DUgGgHAADNgFXAyUB/wMdASkBVgJYAbMQAAMQARUD - VgG1AyUB/wMlAf8DJQH/AyUB/wMlAf8DJQH/AyUB/wMlAf8DVgG1AxABFRwAAxYBHgM5AV8DWgHHA1oB - xwM5AV8DFgEeGQAB0gH6Af8EAAMlAf8EAAMlAf8DPAFmAyUB/wMlAf8EAAMlAf8DPAFmAyUB/wUAAdIB - +gH/CAADJQH/AysB/AM5AV4UAAM2AVcDJQH/Aw8BEwM9AWgBAAHSAfoB/wwAAysBQgNhAeYDJQH/AyUB - /wMlAf8DJQH/AyUB/wMlAf8DJQH/AyUB/wMlAf8DJQH/A2EB5gMrAUIUAAMdASkDXgHwAyUB/wMlAf8D - JQH/AyUB/wNeAfADHQEpFQAB0gH6Af8EAAMlAf8EAAMlAf8DPAFmAyUB/wMlAf8EAAMlAf8DPAFmAyUB - /wUAAdIB+gH/CAADJQH/AyUB/wMrAfwDOQFeDAADNQFWAyUB/wMPARQDPAFmAQAB0gH6Af8DFgEeDAAD - WgHyAyUB/wMlAf8DJQH/AyUB/wMlAf8DJQH/AyUB/wMlAf8DJQH/AyUB/wMlAf8DJQH/A1oB8hQAA1UB - sQMlAf8DJQH/AyUB/wMlAf8DJQH/AyUB/wNVAbEVAAHSAfoB/wQAAyUB/wQAAyUB/wM8AWYDJQH/AyUB - /wQAAyUB/wM8AWYDJQH/BQAB0gH6Af8IAAMlAf8DRgGBA1YBsgMrAfwDOAFdBAADNQFWAyUB/wMPARQD - PAFmAQAB0gH6Af8DFgEeEAADPQFpA1ABnANPAZsDTwGbA1MBpwMlAf8DJQH/AyUB/wMlAf8DUwGnA08B - mwNPAZsDUAGcAz0BaRQAA1MB9AMlAf8DJQH/AyUB/wMlAf8DJQH/AyUB/wNTAfQVAAHSAfoB/wQAAyUB - /wQAAyUB/wM8AWYDJQH/AyUB/wQAAyUB/wM8AWYDJQH/BQAB0gH6Af8IAANZAf4DGgEjA0IBdQMlAf8D - KwH8A04BlgMlAf8DDwEUAzwBZgEAAdIB+gH/AxYBHigAA14B1wMlAf8DJQH/A14B1ygAA1MB9AMlAf8D - JQH/AyUB/wMlAf8DJQH/AyUB/wNTAfQVAAHSAfoB/zEAAdIB+gH/CAADTgGVA00B+gMrAfwDJQH/AyUB - /wMlAf8DCwEOATsCPAFlAQAB0gH6Af8DFgEeLAADSQGFAyUB/wMlAf8DSQGGKAADVQGxAyUB/wMlAf8D - JQH/AyUB/wMlAf8DJQH/A1UBsRQAAVwCXwHIAQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8B - AAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB - +gH/AVwCXwHICAADBQEGA0cBggMNAREDKwFBAyoBQAE7AjwBZQNSAaABAAHSAfoB/wMXAR8wAAMkATQD - JQH/AyUB/wMkATQoAAMdASkDXgHwAyUB/wMlAf8DJQH/AyUB/wNeAfADHQEpVAAEAQNNAZIBNAGAAZMB - /gEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AxcBHzQABAEDXAHIA1wByAQBLAADHQEpA1UB - sQNTAfQDUwH0A1UBsQMdASn/AFUAAUIBTQE+BwABPgMAASgDAAFAAwABQAMAAQEBAAEBBgABAhYAA/8B - AAL/BgABxgEfBgABwgEfBgABgAEHBgABgAEDBgABgAEDBgABgAEDBgAB4QGPBgAB8QGHBgABwAEBBgAB - wAEBBgABwAEBBgAB4AEBBgAB+AFDBgAB+AFjBgAC/wYACP8B+AE/Af8BHwHwAQ8B8AEPAeABDwH/AQ8B - 4AEHAeABBwGAAQMB/wEHBMMBjAFjAfABJwGBAcEBhwHhAZwBcwHAAeMBgQHBAY8B8QGcAXMBhwHxAYEB - AQGfAfkBkAFzAZgBGQGGAQEBngF5AYABMwGfAfkBjgEBAZwBGQGAAQMBmAEZAY4BAQGcAQkBgAEDAZ8B - +QGHAQEBiAHBAYABAwGYARkBgwEBAYEB4QGAAQMBhwHhAcABAwHBAcMB4AEPAcABAwHgAQcB4AEHAfgB - PwHwAQ8B8AEPAfABDxD/AeABHwGAAX8BxAEDAv8B4AEfAYABfwHEAQMB/wHBAeABHwGAAX8BxAEDAf4B - AQHgAQMBgAF/AcQBAwH4AQEB4AEDAcABAQHEAQMB8AEBAeABAwHAAQEBxAEDAfABAwHgAQMBwAEBAcQB - AwHgAQMB4AEDAcABAQHEAQMBwAEHAecBwwHAAQMBxAEDAcABDwHnAYMBwAEDAcQBAwGAAQ8B4AEDAf8B - AwHEAQMBgAEfAfwB+wH/AQMBzwH/AYABfwH8AfMB/wEDAc8B8wGDAf8B/AEDAf8BAwHEAQMS/wH8AT8B - 4wHHAeABBwL/AfgBHwHhAYcB4AEHAv8B8QEPAeABBwHgAQcBgAEBAeMBhwHgAQcB4AEHAb8B/QLHAfAB - DwHgAQcBqAFFAY8B4wHgAQcB8AEPAagBRQGfAcMBwAEDAfgBHwGoAUUBjwGDAYABAQHwAQ8BqAFFAYcB - AwGAAQEB8AEPAagBRQGCAQcBgAEBAfABDwGoAUUBgAEPAfwBPwHwAQ8BvwH9AYABHwH8AT8B8AEPAYAB - AQGAAT8B/AE/AfABDwL/AYABfwH8AT8B+AEfCv8L + JQH/AyUB/wM7AWQDKgE/AyoBPwNhAesDJQH/A1MBqgMqAT8DFgEe1AADCgENA00B+gMlAf8DPgFqCAAD + VAGrAyUB/wNZAcbgAANZAcYDJQH/A1QBqwgAAz4BagMlAf8DTQH6AwoBDdQAAxYBHgMqAT8DUwGqAyUB + /wNhAesDKgE/AyoBPwM7AWQDJQH/AyUB/wNAAXEDKgE/AxQBG8wAAzMBUQMlAf8DJQH/AyUB/wMlAf8D + JQH/AyUB/wMlAf8DJQH/AyUB/wMlAf8DJQH/A04Bl8wAAw4BEgMrAfwDJQH/AyUB/wMlAf8DJQH/AyUB + /wMlAf8DJQH/AyUB/wMlAf8DJQH/A1wB2dAAAw8BEwMQARUDWgHEAyUB/wNYAboDEAEVAxABFQNAAW8D + JQH/A0AB/QMbASYDEAEV2AADRgGAAyUB/wNZAe8EAgQAAxoBJAMlAf8DJQH/AzIBT9wAAyoBPwMlAf8D + JQH/AyQBNAgAA2IB4QMlAf8DTAGQ/wD/AN4AAxgBIQNQAZwDWgHyA1ABnAMYASE4AAM4AV0DMAFKAwQB + BSQAAxMBGgNJAYgDXQHUA0EB+QNBAfkDXQHUA0kBiAMTARogAAMTARoDSQGIA10B1ANBAfkDQQH5A10B + 1ANJAYgDEwEaHAADGAEgA08BmQNaAfIDUQGiAyUB/wNRAaIDWgHyA08BmQMYASAwAAM6AWIDTQH6A10B + 3AMkATQcAAM3AVoDYgHuA0sBjQMjATIDBgEHAwYBBwMjATIDSwGNA10B6gM3AVoYAAM3AVoDYAHzA00B + +gNYAbcDSQGHA0kBhwNYAbcDTQH6A2AB8wM3AVoQAAMVARwDTgGWA1oB8gNRAZ4DGgEjAwgBCgMlAf8D + CAEKAxoBIwNRAZ4DWgHyA04BlgMVARwoAANCAXQDUwGqAzMBUQNgAegDFwEfFAADNwFaA1sB5ANdAc4D + AwEEEAADNAFTAzYBVwNgAeADNwFaEAADNwFaA0kB/gNaAb8DGAEhEAADGAEhA1oBvwNJAf4DNwFaDAAD + XwHlA1EBpAMbASUIAAMIAQoDJQH/AwgBCggAAxsBJQNRAaQDXwHlGAADKwFBA1EBoQNeAd0DTQH6A18B + 1QMdASgEAANGAX4DUAGcEAADEwEaA10B6gM9AWcDJQH/A1oBvwMEAQUMAANcAdYDJgH7AygBOwNdAeoD + EwEaCAADEwEaA2AB8wNaAb8DBQEGGAADBQEGA1oBvwNgAfMDEwEaCAADJQH/AxABFQwAAwgBCgMlAf8D + CAEKDAADEAEVAyUB/xAAAw4BEgNWAbMDWwHYAz8BbQMdASgDBQEGDAADFQEcA2EB6wMPARMMAANJAYgD + QgF0A1cBwgMlAf8DJQH/AyUBNwwAA14B7QMlAf8DRAF4A0sBjQNJAYgIAANJAYgDTQH6AxgBISAAAxgB + IQNNAfoDSQGICAADJQH/AxABFQwAAwgBCgMlAf8DCAEKDAADEAEVAyUB/wwAAwgBCgNdAc8DSgGLAwQB + BRwAA0cBggNdAc8DCAEKCAADXQHUAzoBYgMlAf8DQAH9A0sBjAMGAQcEAAMLAQ4DJgE5AyUB/wMlAf8D + WgHHAx0BKANdAdQIAANdAdQDWAG3KAADWAG3A10B1AgAAyUB/wMQARUEAAMXAR8DEQEWAwgBCgMlAf8D + CAEKDAADEAEVAyUB/wwAA0cBggNSAaMJAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB + +gH/AQAB0gH6Af8IAANTAaYDRwGCCAADQQH5A0wBkQNeAfADOwFkCAADFgEeA2UB8QMlAf8DJQH/AyUB + /wMlAf8DKwRBAfkIAANBAfkDSQGHEQAB0gH6Af8BAAHSAfoB/xAAA0kBhwNBAfkIAAMlAf8DEAEVA1gB + uAFAAr4B/QMhAS8DSwGPAyUB/wNLAY8DEgEYCAADEAEVAyUB/wwAA10B3wMeASooAAMeASoDXQHfCAAD + QQH5A1sBygMLAQ4MAAMzAVIDJQH/AyUB/wMlAf8DJQH/AyUB/wM+AWsDQQH5CAADQQH5A0kBhwwAAwQB + BQFIAWMBaQH2AUgBYwFpAfYBXAJhAdkDMwFSCAADSQGHA0EB+QgAAyUB/wMQARUBUwJoAfQBAAHSAfoB + /wFAAkEBcQNFAXwDLgFIA1IBqANeAfADSgGLAxEBFgMQARUDJQH/DAADQAH9AwIBAwkAAdIB+gH/AQAB + 0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wgAAwIBAwNAAf0IAANdAdQDWQHvAxoB + IwwAAxYBHQNgAfMDJQH/A1EB9wNbAeQDSAH2A0kB/gNdAdQIAANdAdQDWAG3DAADSwGNAVoCXAHEAyUB + NwNFAXwDYgHuAzUBVQQAA1gBtwNdAdQIAAMlAf8DOgFgAVsCXQHKAQAB0gH6Af8BAAHSAfoB/wFbAmEB + 3gM0AVMEAgMgAS4DVAGrA14B8ANOAZcDJQH/DAADXQHfAx4BKigAAx4BKgNdAd8IAANJAYgDJQH/A10B + 3wMeASoMAAM3AVoDUQGhAzABSgNLAY0DYgHuAyUB/wNJAYgIAANJAYgDTQH6AxgBIQQAAxEBFgNiAe4D + HAEnCAADCQELAxABFQMYASEDTQH6A0kBiAgAA18B5QNbAcUDGwEmAUoCSwGKAV4CZQHiASUBiAGvAf4B + JQGIAa8B/gFeAmUB3QMzAVAEAQM0AVMDTQH6A18B5QwAA0cBggNSAaUJAAHSAfoB/wEAAdIB+gH/AQAB + 0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8IAANSAaUDRwGCCAADEwEaA2AB8wMlAf8DSQH+AzEB + TggAAzYBWANaAb8DWgHyAyUB/wMlAf8DYAHzAxMBGggAAxMBGgNgAfMDWgG/AwUBBgFbAl0BygNLAY0Q + AAMFAQYDWgG/A2AB8wMTARoIAAMVARwDRAF4A1oB8gNGAX4DFwEfAzgBWwFgAmUB4wEkAYoBsgH+AQAB + 0gH6Af8BYAJkAdsBOgI7AWIDQwF2AxUBHAwAAwgBCgNdAc8DSwGNAwQBBRgAAwQBBQNLAY0DXQHPAwgB + CgwAAzcBWgNJAf4DJQH/AysBQgNTAakDTgGYAycBOgMjATMDXgHSA0oBiwMrAfwDNwFaEAADNwFaA0kB + /gNaAb8BQAJBAXADDAEPDAADGAEhA1oBvwNJAf4DNwFaFAADGAEgA0QBegNaAfIDRQF8Ax0BKAFPAlAB + mwFbAmEB3gNVAawDEAEVGAADDgESA1YBswNeAdcDPgFrAxsBJgMEAQUDBAEFAxsBJgM+AWsDXgHXA1YB + swMOARIUAAM3AVoDYAHzA10B1ANZAe8DJQH/A1cBuQMYASADQAFxA10B6gM3AVoYAAM3AVoDYAHzA00B + +gNYAbcDSQGHA0kBhwNYAbcDTQH6A2AB8wM3AVogAAMYASEDRgF9A1oB8gNLAY0EAigAAysBQQNRAaED + XgHdA00B+gNNAfoDXgHdA1EBoQMrAUEgAAMTARoDSQGIA10B1ANBAfkDQQH5A10B1ANJAYgDEwEaIAAD + EwEaA0kBiANdAdQDQQH5A0EB+QNdAdQDSQGIAxMBGv8A/wAeAAMzAVADWgHpAyUB/wMlAf8DJQH/AyUB + /wMlAf8DXAHIGAADMQFNA1UBtANbAeQDJgH7AyYB+wNbAeQDVQG0AzEBTSQAAzMBUANaAekDJQH/BQAB + 0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8BWQJcAcFU + AANaAekDJQH/AyUB/wMlAf8DJQH/AyUB/wMlAf8DJQH/GAADQQH5AyUB/wMlAf8DJQH/AyUB/wMlAf8D + JQH/A0EB+SQAA1oB6QMlAf8DJQH/BQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB + /wEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/zAAAxcBHwNJAYcDXAHWA1wB+ANTAaoQAAMlAf8DJQH/AyUB + /wMlAf8DJQH/AyUB/wMlAf8DJQH/GAADYAHgAyUB/wMlAf8DJQH/AyUB/wMlAf8DJQH/A2AB4CQAAyUB + /wMlAf8DJQH/BQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB + 0gH6Af8BAAHSAfoB/yQAAwkEDAEPA00BkwNNAfoDJQH/AyUB/wMlAf8DYAHzEAADJQH/AyUB/wMlAf8D + JQH/AyUB/wMlAf8DJQH/AyUB/wMzAVIBAAHSAfoB/wFcAl8ByAwAAzwBZgNbAcoDRAF6Ay4BSAMwAUsD + RAF6A1sBygM8AWYkAAMlAf8DJQH/AyUB/wUAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB + 0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8cAAE7AjwBZQNVAa8DNgFYA1wB5wNgAeADPgFqAzoE + YAHoAyUB/wNVAa4QAAMlAf8DJQH/AyUB/wMlAf8DJQH/AyUB/wMlAf8DJQH/AzMBUgEAAdIB+gH/AQAB + 0gH6Af8QAAMXAR8DNgFXA1oBxANaAcQDOQFeAxgBIAMbASYBTAJNAZEBIQGCAYsB+wEhAYIBiwH7AVsC + YwHkAVUCVwG0AzEBTQwAAyUB/wMlAf8DJQH/BQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8B + AAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/xgAASYCJwE5AVUCVgGuA0QBegNaAfUDOQFfAz0B + ZwFgAmkB6AMgAS4DVwG5AyYB+wMhATAQAAMlAf8DJQH/AyUB/wMlAf8DJQH/AyUB/wMlAf8DJQH/AzMB + UgEAAdIB+gH/AQAB0gH6Af8QAAM9AWkDTwH+AyUB/wMlAf8DTwH+Az0BaQMZASIBAAHSAfoB/wEAAdIB + +gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AUEBcQF/AfkMAAMlAf8DJQH/AyUB/wUAAdIB+gH/AQAB + 0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8YAAMyAU8D + QgF1A2AB2wM1AVYBXgJlAeIBAAHSAfoB/wEAAdIB+gH/AVACUQGdA0wBkQNGAYAUAAMlAf8DJQH/AyUB + /wMlAf8DJQH/AyUB/wMlAf8DJQH/AzMBUgEAAdIB+gH/AQAB0gH6Af8QAANhAeYDJQH/AyUB/wMlAf8D + JQH/A2EB5gMeASoBAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AWACZgHgDAAD + JQH/AyUB/wMlAf8FAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8B + AAHSAfoB/wEAAdIB+gH/FAADBwEJA0oBigNdAc8DOgFgATwBfQF+AfoBAAHSAfoB/wEAAdIB+gH/AQAB + 0gH6Af8BKwF+AZQB/AMpAT0EAhQAAyUB/wMlAf8DJQH/AyUB/wMlAf8DJQH/AyUB/wNcAcgDMwFSAQAB + 0gH6Af8BAAHSAfoB/xAAA1oB9QMlAf8DJQH/AyUB/wMlAf8DWgH1AysBQgNEAXoDLgFIAzABSwNEAXoB + WwJdAcoDPAFmDAADJQH/AyUB/wMlAf8FAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB + +gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/EAAEAgNLAY8DYAHgAzUBVgEkAYsBswH+AQAB0gH6Af8B + AAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8BKwF+AZQB/AMEAQUYAAMlAf8DJQE3FAADOwFlAzMBUgEAAdIB + +gH/AQAB0gH6Af8QAANRAZ4DJQH/AyUB/wMlAf8DJQH/A1EBngMXAR8DNgFXAVoCXAHEAVoCXAHEAzkB + XgMYASAQAAMlAf8DJQH/AyUB/wUAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8B + AAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8QAANBAXMDJQH/AzYBWAFgAmYB4AEAAdIB+gH/AQAB0gH6Af8B + AAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8BWQJcAcEcAANaAekDJQE3EAADCwEOAyUB/wMzAVIBAAHSAfoB + /wEAAdIB+gH/EAADCAEKA04BmANlAfEDZQHxA04BmAMIAQoDNAFUASoBgAGnAf4BAAHSAfoB/wEAAdIB + +gH/ASoBgAGnAf4BPQI+AWkQAAMlAf8DJQH/AyUB/wUAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB + +gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8MAAMcAScDJgH7A10BzgMbASUBQQF9AYUB + +QEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AUEBfQGFAfkBJgInATkcAAMzAVADWgHpAyUB + /wMlAf8DJQH/AyUB/wMlAf8DWwHKA0YBfgEAAdIB+gH/AVwCXwHIKAABYQJqAeYBAAHSAfoB/wEAAdIB + +gH/AQAB0gH6Af8BAAHSAfoB/wFhAmoB5hAAAyUB/wMlAf8DJQH/BAABKQGBAakB/gEpAYEBqQH+ASkB + gQGpAf4BKQGBAakB/gEpAYEBqQH+AQAB0gH6Af8BAAHSAfoB/wFGAkcBgAwAA1UBrgMlAf8DYAHoAzoB + YAMwAUsBWAJaAb0BAAHSAfoB/wEAAdIB+gH/A14B0gMqAT8sAAM8AWYDBQEGFAADRgF+KAABWgJuAfUB + AAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wFaAm4B9RAAAyUB/wMlATc0AANgAfMDJQH/AyUB + /wMlAf8DWgHyAygBPAMRARYDEQEWNAABWgJjAekDJQE3EAADCwEOAQAB0gH6Af8oAANRAZ4BAAHSAfoB + /wEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wNRAZ4QAANaAekDJQE3IAADCwEOAQAB0gH6Af8MAANTAaoD + XAH4A1wB1gNJAYcDFwEfQAADMwFQAVoCYwHpAQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8B + AAHSAfoB/wFbAl0ByigAAwgBCgNOAZgBZQJwAfEBZQJwAfEDTgGYAwgBChAAAzMBUANaAekDJQH/BQAB + 0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8BUQJTAaL/ + AP8AYgADFwEfAyUB/wMlAf8DCAEKJAADHQEpAz8BbgMGAQgQAAMGAQgDPwFuAx0BKRgAAxMBGQNHAYID + WQHDA1oB6QMrAfwDKwH8A1oB6QNZAcMDRgGBAxMBGWAAAxcBHwMlAf8DPAFmA04BlwMlAf8DCAEKIAAD + UgGoAyUB/wNbAdADHQEoCAADHQEoA1sB0AMlAf8DUgGoGAADWwHkAyUB/wMlAf8DJQH/AyUB/wMlAf8D + JQH/AyUB/wMlAf8DWwHkXAADFgEeAyUB/wM7AWUEAAQBA04BlwMlAf8DCAEKHAADPwFsAyUB/wMlAf8D + UwH0AzsBYwM7AWMDUwH0AyUB/wMlAf8DPwFsGAADUQH3AyUB/wMlAf8DJQH/AyUB/wMlAf8DJQH/AyUB + /wMlAf8DUQH3EAABXAJfAcgBAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB + 0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8BXAJfAcgQ + AAMWAR4DJQH/AzwBZgwABAEDTgGXAyUB/wMIAQoYAAMUARsDQAH9AyUB/wMlAf8DJQH/AyUB/wMlAf8D + JQH/A0AB/QMUARsYAANbAc0DJQH/AyUB/wMlAf8DJQH/AyUB/wMlAf8DJQH/AyUB/wNbAc0RAAHSAfoB + /zEAAdIB+gH/DAADFgEeAyUB/wM8AWYUAAQBA04BmAMlAf8cAANZAcYDJQH/AyUB/wMlAf8DJQH/AyUB + /wMlAf8DWQHGHAADNQFWA1kB/gMlAf8DYQHmA10BzwNdAc8DYQHmAyUB/wNZAf4DNQFWEQAB0gH6Af8E + AAMlAf8EAAMlAf8DPAFmAyUB/wMlAf8EAAMlAf8DPAFmAyUB/wUAAdIB+gH/CAADFgEeAyUB/wM8AWYc + AAM2AVkDJQH/BAEUAAQBA1QBqwMlAf8DJQH/AyUB/wMlAf8DJQH/AyUB/wNUAasEARwAAzABTAMqAT8D + GwElAw0BEQMNAREDHQEpAyoBPwMwAUwVAAHSAfoB/wQAAyUB/wQAAyUB/wM8AWYDJQH/AyUB/wQAAyUB + /wM8AWYDJQH/BQAB0gH6Af8IAAMlAf8DUgGgHAADNgFXAyUB/wMdASkBVgJYAbMQAAMQARUDVgG1AyUB + /wMlAf8DJQH/AyUB/wMlAf8DJQH/AyUB/wMlAf8DVgG1AxABFRwAAxYBHgM5AV8DWgHHA1oBxwM5AV8D + FgEeGQAB0gH6Af8EAAMlAf8EAAMlAf8DPAFmAyUB/wMlAf8EAAMlAf8DPAFmAyUB/wUAAdIB+gH/CAAD + JQH/AysB/AM5AV4UAAM2AVcDJQH/Aw8BEwM9AWgBAAHSAfoB/wwAAysBQgNhAeYDJQH/AyUB/wMlAf8D + JQH/AyUB/wMlAf8DJQH/AyUB/wMlAf8DJQH/A2EB5gMrAUIUAAMdASkDXgHwAyUB/wMlAf8DJQH/AyUB + /wNeAfADHQEpFQAB0gH6Af8EAAMlAf8EAAMlAf8DPAFmAyUB/wMlAf8EAAMlAf8DPAFmAyUB/wUAAdIB + +gH/CAADJQH/AyUB/wMrAfwDOQFeDAADNQFWAyUB/wMPARQDPAFmAQAB0gH6Af8DFgEeDAADWgHyAyUB + /wMlAf8DJQH/AyUB/wMlAf8DJQH/AyUB/wMlAf8DJQH/AyUB/wMlAf8DJQH/A1oB8hQAA1UBsQMlAf8D + JQH/AyUB/wMlAf8DJQH/AyUB/wNVAbEVAAHSAfoB/wQAAyUB/wQAAyUB/wM8AWYDJQH/AyUB/wQAAyUB + /wM8AWYDJQH/BQAB0gH6Af8IAAMlAf8DRgGBA1YBsgMrAfwDOAFdBAADNQFWAyUB/wMPARQDPAFmAQAB + 0gH6Af8DFgEeEAADPQFpA1ABnANPAZsDTwGbA1MBpwMlAf8DJQH/AyUB/wMlAf8DUwGnA08BmwNPAZsD + UAGcAz0BaRQAA1MB9AMlAf8DJQH/AyUB/wMlAf8DJQH/AyUB/wNTAfQVAAHSAfoB/wQAAyUB/wQAAyUB + /wM8AWYDJQH/AyUB/wQAAyUB/wM8AWYDJQH/BQAB0gH6Af8IAANeAf4DGgEjA0IBdQMlAf8DKwH8A04B + lgMlAf8DDwEUAzwBZgEAAdIB+gH/AxYBHigAA14B1wMlAf8DJQH/A14B1ygAA1MB9AMlAf8DJQH/AyUB + /wMlAf8DJQH/AyUB/wNTAfQVAAHSAfoB/zEAAdIB+gH/CAADTgGVA00B+gMrAfwDJQH/AyUB/wMlAf8D + CwEOATsCPAFlAQAB0gH6Af8DFgEeLAADSQGFAyUB/wMlAf8DSQGGKAADVQGxAyUB/wMlAf8DJQH/AyUB + /wMlAf8DJQH/A1UBsRQAAVwCXwHIAQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB + /wEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AVwC + XwHICAADBQEGA0cBggMNAREDKwFBAyoBQAE7AjwBZQNSAaABAAHSAfoB/wMXAR8wAAMkATQDJQH/AyUB + /wMkATQoAAMdASkDXgHwAyUB/wMlAf8DJQH/AyUB/wNeAfADHQEpVAAEAQNNAZIBOQGAAYkB/gEAAdIB + +gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AxcBHzQABAEDXAHIA1wByAQBLAADHQEpA1UBsQNTAfQD + UwH0A1UBsQMdASn/AFUAAUIBTQE+BwABPgMAASgDAAFAAwABQAMAAQEBAAEBBgABAhYAA/8BAAL/BgAB + xgEfBgABwgEfBgABgAEHBgABgAEDBgABgAEDBgABgAEDBgAB4QGPBgAB8QGHBgABwAEBBgABwAEBBgAB + wAEBBgAB4AEBBgAB+AFDBgAB+AFjBgAC/wYACP8B+AE/Af8BHwHwAQ8B8AEPAeABDwH/AQ8B4AEHAeAB + BwGAAQMB/wEHBMMBjAFjAfABJwGBAcEBhwHhAZwBcwHAAeMBgQHBAY8B8QGcAXMBhwHxAYEBAQGfAfkB + kAFzAZgBGQGGAQEBngF5AYABMwGfAfkBjgEBAZwBGQGAAQMBmAEZAY4BAQGcAQkBgAEDAZ8B+QGHAQEB + iAHBAYABAwGYARkBgwEBAYEB4QGAAQMBhwHhAcABAwHBAcMB4AEPAcABAwHgAQcB4AEHAfgBPwHwAQ8B + 8AEPAfABDxD/AeABHwGAAX8BxAEDAv8B4AEfAYABfwHEAQMB/wHBAeABHwGAAX8BxAEDAf4BAQHgAQMB + gAF/AcQBAwH4AQEB4AEDAcABAQHEAQMB8AEBAeABAwHAAQEBxAEDAfABAwHgAQMBwAEBAcQBAwHgAQMB + 4AEDAcABAQHEAQMBwAEHAecBwwHAAQMBxAEDAcABDwHnAYMBwAEDAcQBAwGAAQ8B4AEDAf8BAwHEAQMB + gAEfAfwB+wH/AQMBzwH/AYABfwH8AfMB/wEDAc8B8wGDAf8B/AEDAf8BAwHEAQMS/wH8AT8B4wHHAeAB + BwL/AfgBHwHhAYcB4AEHAv8B8QEPAeABBwHgAQcBgAEBAeMBhwHgAQcB4AEHAb8B/QLHAfABDwHgAQcB + qAFFAY8B4wHgAQcB8AEPAagBRQGfAcMBwAEDAfgBHwGoAUUBjwGDAYABAQHwAQ8BqAFFAYcBAwGAAQEB + 8AEPAagBRQGCAQcBgAEBAfABDwGoAUUBgAEPAfwBPwHwAQ8BvwH9AYABHwH8AT8B8AEPAYABAQGAAT8B + /AE/AfABDwL/AYABfwH8AT8B+AEfCv8L \ No newline at end of file diff --git a/MyCBZ/Hash/CRC32.cs b/MyCBZ/Hash/CRC32.cs index 029b80c6..a4e22fde 100644 --- a/MyCBZ/Hash/CRC32.cs +++ b/MyCBZ/Hash/CRC32.cs @@ -9,14 +9,48 @@ using SharpCompress.Common; using SharpCompress.Readers; using System.IO; +using System.Runtime.Versioning; +using System.Numerics; namespace Win_CBZ.Hash { internal class HashCrc32 { - public HashCrc32(LocalFile input) + [SupportedOSPlatform("windows")] + public static void Calculate(ref Page page) { + if (page == null) + { + throw new ArgumentNullException("page"); + } + if (page.LocalFile == null) + { + throw new ArgumentNullException("page.LocalFile"); + } + + if (!page.LocalFile.Exists()) + { + throw new FileNotFoundException("File not found", page.LocalFile.FullPath); + } + + LocalFile localFile = page.LocalFile; + if (page.Compressed || page.Changed) + { + localFile = page.TemporaryFile; + } + + using (var stream = localFile.LocalFileInfo.Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) + { + var crc32 = new Crc32(); + crc32.Append(stream); + + var hash = crc32.GetHashAndReset(); + + page.Hash = BitConverter.ToString(hash).Replace("-", "").ToUpper(); + + crc32 = null; + } } } } diff --git a/MyCBZ/Models/MetaData.cs b/MyCBZ/Models/MetaData.cs index 4edd2c39..ef5507e3 100644 --- a/MyCBZ/Models/MetaData.cs +++ b/MyCBZ/Models/MetaData.cs @@ -254,7 +254,6 @@ public void Save(String path) } } - public MemoryStream BuildComicInfoXMLStream(bool withoutXMLHeaderTag = false) { MemoryStream ms = new MemoryStream(); diff --git a/MyCBZ/Models/MetaDataEntryPage.cs b/MyCBZ/Models/MetaDataEntryPage.cs index 683ff150..b8bd755a 100644 --- a/MyCBZ/Models/MetaDataEntryPage.cs +++ b/MyCBZ/Models/MetaDataEntryPage.cs @@ -28,10 +28,13 @@ internal class MetaDataEntryPage public const String COMIC_PAGE_TYPE_OTHER = "Other"; public const String COMIC_PAGE_TYPE_DELETED = "Deleted"; - public static String [] PageTypes = {COMIC_PAGE_TYPE_STORY, COMIC_PAGE_TYPE_FRONT_COVER, - COMIC_PAGE_TYPE_INNER_COVER, COMIC_PAGE_TYPE_BACK_COVER, COMIC_PAGE_TYPE_ROUNDUP, COMIC_PAGE_TYPE_ADVERTICEMENT, - COMIC_PAGE_TYPE_EDITORIAL,COMIC_PAGE_TYPE_LETTERS, COMIC_PAGE_TYPE_PREVIEW, COMIC_PAGE_TYPE_OTHER, - COMIC_PAGE_TYPE_DELETED}; + public static String [] PageTypes = { + COMIC_PAGE_TYPE_STORY, COMIC_PAGE_TYPE_FRONT_COVER, + COMIC_PAGE_TYPE_INNER_COVER, COMIC_PAGE_TYPE_BACK_COVER, COMIC_PAGE_TYPE_ROUNDUP, + COMIC_PAGE_TYPE_ADVERTICEMENT, + COMIC_PAGE_TYPE_EDITORIAL,COMIC_PAGE_TYPE_LETTERS, COMIC_PAGE_TYPE_PREVIEW, + COMIC_PAGE_TYPE_OTHER, COMIC_PAGE_TYPE_DELETED + }; /* diff --git a/MyCBZ/Models/Page.cs b/MyCBZ/Models/Page.cs index ed012ced..9427b2cb 100644 --- a/MyCBZ/Models/Page.cs +++ b/MyCBZ/Models/Page.cs @@ -273,7 +273,6 @@ public Page(ZipArchiveEntry entry, String workingDir, String randomId = null) Format = new PageImageFormat(FileExtension); } - public Page(Stream fileInputStream, String name) { @@ -1286,8 +1285,6 @@ public void UpdateImageExtension(string newExtension) FileExtension = ExtractFileExtension(Filename); } - - public string SizeFormat() { double size = Size; @@ -1308,7 +1305,6 @@ public string SizeFormat() return size.ToString("n2") + " " + selectedUnit; } - /// /// Serialize the page to XML- Fragment /// @@ -1843,25 +1839,35 @@ public void LoadImageInfo(bool force = false) } } - public Image GetThumbnail() + public Image GetThumbnail(int w = 0, int h = 0) { if (!Closed) { LoadImage(); } + if (w == 0) + { + w = ThumbW; + } + + if (h == 0) + { + h = ThumbH; + } + if (Image != null) { try { - var newBitmap = new Bitmap(ThumbW, ThumbH); + var newBitmap = new Bitmap(w, h); using (Graphics g = Graphics.FromImage(newBitmap)) { g.PixelOffsetMode = PixelOffsetMode.HighQuality; g.CompositingQuality = CompositingQuality.HighQuality; g.SmoothingMode = SmoothingMode.HighQuality; g.InterpolationMode = InterpolationMode.HighQualityBicubic; - g.DrawImage(Image, new Rectangle(0, 0, ThumbW, ThumbH)); + g.DrawImage(Image, new Rectangle(0, 0, w, h)); } Thumbnail = Image.FromHbitmap(newBitmap.GetHbitmap()); //openBitmap.Dispose(); //Clear The Old Large Bitmap From Memory @@ -1879,25 +1885,34 @@ public Image GetThumbnail() return Thumbnail; } - public Bitmap GetThumbnailBitmap() + public Bitmap GetThumbnailBitmap(int w = 0, int h = 0) { if (!Closed) { LoadImage(); } + if (w == 0) { + w = ThumbW; + } + + if (h == 0) + { + h = ThumbH; + } + if (Image != null) { try { - var newBitmap = new Bitmap(ThumbW, ThumbH); + var newBitmap = new Bitmap(w, h); using (Graphics g = Graphics.FromImage(newBitmap)) { g.PixelOffsetMode = PixelOffsetMode.HighQuality; g.CompositingQuality = CompositingQuality.HighQuality; g.SmoothingMode = SmoothingMode.HighQuality; g.InterpolationMode = InterpolationMode.HighQualityBicubic; - g.DrawImage(Image, new Rectangle(0, 0, ThumbW, ThumbH)); + g.DrawImage(Image, new Rectangle(0, 0, w, h)); } return newBitmap; @@ -1920,7 +1935,7 @@ public Bitmap GetThumbnailBitmap() /* * This will use Windows api fetching cached explorer thumbs */ - public Image GetWindowsThumbnail(Image.GetThumbnailImageAbort callback, IntPtr data) + public Image GetWindowsThumbnail(Image.GetThumbnailImageAbort callback, IntPtr callbackData) { if (!Closed) { @@ -1931,7 +1946,7 @@ public Image GetWindowsThumbnail(Image.GetThumbnailImageAbort callback, IntPtr d { try { - Thumbnail = Image.GetThumbnailImage(ThumbW, ThumbH, callback, data); + Thumbnail = Image.GetThumbnailImage(ThumbW, ThumbH, callback, callbackData); Image?.Dispose(); Image = null; diff --git a/MyCBZ/Models/ProjectModel.cs b/MyCBZ/Models/ProjectModel.cs index 4aea3674..7d14553a 100644 --- a/MyCBZ/Models/ProjectModel.cs +++ b/MyCBZ/Models/ProjectModel.cs @@ -41,6 +41,7 @@ using System.Windows.Interop; using Win_CBZ.Events; using System.Text.RegularExpressions; +using Win_CBZ.Hash; namespace Win_CBZ { @@ -276,6 +277,7 @@ private void HandlePipeline(object sender, PipelineEvent e) InvalidFileNames = FilteredFileNames.ToArray(), CancelToken = TokenStore.GetInstance().CancellationTokenSourceForName(TokenStore.TOKEN_SOURCE_PROCESS_FILES).Token, MaxCountPages = p.MaxCountPages, + HashFiles = p.HashFiles, }); currentPerformed = e.Task; @@ -1861,6 +1863,129 @@ public void CancelAllThreads() */ } + + public Page AddPageFromFile(LocalFile localFile, PageIndexVersion version, int insertAt = -1) + { + int pageStatus = 0; + bool pageError = false; + FileInfo targetPath; + FileInfo localPath; + int realNewIndex = Pages.Count; + Page page; + Page insertPage = null; + + if (insertAt >= 0 && insertAt < Pages.Count) + { + realNewIndex = insertAt; + insertPage = GetPageByIndex(realNewIndex); + } + + targetPath = MakeNewTempFileName(); + + //CopyFile(fileObject.FullPath, targetPath.FullName); + + page = GetPageByName(localFile.Name); + + if (page == null) + { + page = new Page(localFile, targetPath.Directory.FullName, FileAccess.ReadWrite) + { + Number = realNewIndex + 1, + Index = realNewIndex, + OriginalIndex = realNewIndex, + Key = version == PageIndexVersion.VERSION_1 ? localFile.Name : RandomId.GetInstance().Make(), + }; + pageStatus = PageChangedEvent.IMAGE_STATUS_NEW; + } + else + { + throw new PageException(page, "Page already exists!", true); + } + + try + { + page.LoadImage(true); // dont load full image here! + } + catch (PageException pe) + { + pageStatus = PageChangedEvent.IMAGE_STATUS_ERROR; + + MessageLogger.Instance.Log(LogMessageEvent.LOGMESSAGE_TYPE_WARNING, "Failed to load image metadata for page ['" + page.Name + "']! [" + pe.Message + "]"); + } + finally + { + page.FreeImage(); + } + + if (insertAt > -1 && insertAt < Pages.Count) + { + Pages.Insert(realNewIndex, page); + + } else + { + Pages.Add(page); + } + + AppEventHandler.OnPageChanged(this, new PageChangedEvent(page, insertPage, pageStatus)); + + return page; + } + + public Page AddPage(Page page, int insertAt = -1) + { + int pageStatus = 0; + int realNewIndex = Pages.Count; + Page insertPage = null; + + if (insertAt >= 0 && insertAt < Pages.Count) + { + realNewIndex = insertAt; + insertPage = GetPageByIndex(realNewIndex); + } + + if (page != null) + { + pageStatus = PageChangedEvent.IMAGE_STATUS_NEW; + + try + { + page.LoadImage(true); // dont load full image here! + } + catch (PageException pe) + { + pageStatus = PageChangedEvent.IMAGE_STATUS_ERROR; + + MessageLogger.Instance.Log(LogMessageEvent.LOGMESSAGE_TYPE_WARNING, "Failed to load image metadata for page ['" + page.Name + "']! [" + pe.Message + "]"); + } + finally + { + page.FreeImage(); + } + + page.Index = realNewIndex; + page.Number = realNewIndex + 1; + + if (insertAt > -1 && insertAt < Pages.Count) + { + Pages.Insert(realNewIndex, page); + + } + else + { + Pages.Add(page); + } + + AppEventHandler.OnPageChanged(this, new PageChangedEvent(page, insertPage, pageStatus)); + } + else + { + throw new PageException(page, "Page already exists!", true); + } + + + return page; + } + public void AddImagesProc(object threadParams) { AddImagesThreadParams tParams = threadParams as AddImagesThreadParams; @@ -1928,6 +2053,21 @@ public void AddImagesProc(object threadParams) page.Changed = true; } + try { + if (tParams.HashFiles) + { + HashCrc32.Calculate(ref page); + } + } catch (Exception pe) + { + pageStatus = PageChangedEvent.IMAGE_STATUS_ERROR; + + MessageLogger.Instance.Log(LogMessageEvent.LOGMESSAGE_TYPE_WARNING, "Failed calculate crc32 for page ['" + page.Name + "']! [" + pe.Message + "]"); + } finally + { + // + } + try { page.LoadImage(true); // dont load full image here! @@ -2028,6 +2168,7 @@ public void ParseFiles(List files) CancelToken = TokenStore.GetInstance().CancellationTokenSourceForName(TokenStore.TOKEN_SOURCE_PARSE_FILES).Token, Pages = Pages, MaxCountPages = Pages.Count, + HashFiles = Win_CBZSettings.Default.CalculateHash, }); } @@ -2085,6 +2226,8 @@ public void ParseFilesProc(object threadParams) LocalFiles = files.ToList(), PageIndexVerToWrite = tParams.PageIndexVerToWrite, MaxCountPages = tParams.MaxCountPages, + CancelToken = tParams.CancelToken, + HashFiles = tParams.HashFiles, } }, new StackItem @@ -2557,7 +2700,6 @@ public void RestoreOriginalNamesProc(object threadParams) AppEventHandler.OnOperationFinished(this, new OperationFinishedEvent(0, Pages.Count)); AppEventHandler.OnApplicationStateChanged(this, new ApplicationStatusEvent(this, ApplicationStatusEvent.STATE_READY)); } - public void RenamePage(Page page, String name, bool ignoreDuplicates = false, bool showErrors = false) { diff --git a/MyCBZ/Win_CBZSettings.Designer.cs b/MyCBZ/Win_CBZSettings.Designer.cs index b56d6488..dc2546c8 100644 --- a/MyCBZ/Win_CBZSettings.Designer.cs +++ b/MyCBZ/Win_CBZSettings.Designer.cs @@ -497,5 +497,29 @@ public int WhatsNewVersion { this["WhatsNewVersion"] = value; } } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("False")] + public bool CalculateHash { + get { + return ((bool)(this["CalculateHash"])); + } + set { + this["CalculateHash"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("False")] + public bool CheckDuplicatePages { + get { + return ((bool)(this["CheckDuplicatePages"])); + } + set { + this["CheckDuplicatePages"] = value; + } + } } } diff --git a/MyCBZ/Win_CBZSettings.settings b/MyCBZ/Win_CBZSettings.settings index 884c13c0..0cea6997 100644 --- a/MyCBZ/Win_CBZSettings.settings +++ b/MyCBZ/Win_CBZSettings.settings @@ -141,5 +141,11 @@ 0 + + False + + + False + \ No newline at end of file